From 3529f2f42ac9ade06a38b1b9b3d5f94e80d71434 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 08:42:27 +0200 Subject: [PATCH 001/297] create spi driver --- UefiPayloadPkg/SPI/SPI.c | 19 +++++++ UefiPayloadPkg/SPI/SPI.inf | 63 ++++++++++++++++++++++++ UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 1 + UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 1 + 4 files changed, 84 insertions(+) create mode 100644 UefiPayloadPkg/SPI/SPI.c create mode 100644 UefiPayloadPkg/SPI/SPI.inf diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c new file mode 100644 index 000000000000..0cdbfe1b6141 --- /dev/null +++ b/UefiPayloadPkg/SPI/SPI.c @@ -0,0 +1,19 @@ +/** @file BlSMMStoreDxe.c + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +STATIC +EFI_STATUS +InstallSmbusProtocol ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf new file mode 100644 index 000000000000..e11f6f1778f6 --- /dev/null +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -0,0 +1,63 @@ +#/** @file +# +# Component description file for SMMSTORE module +# +# Copyright (c) 2020, 9elements Agency GmbH
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SPI + FILE_GUID = 9f185eec-6795-462d-9663-5bb9a85be9f2 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = SPIInitialize + +[Sources.common] + SPI.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + IoLib + BaseLib + DebugLib + HobLib + SmmStoreLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeLib + DxeServicesTableLib + +[Guids] + gEfiSystemNvDataFvGuid + gEfiVariableGuid + gEfiAuthenticatedVariableGuid + gEfiEventVirtualAddressChangeGuid + gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL + gEfiSMMSTOREInfoHobGuid + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiDiskIoProtocolGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + + [Depex] + gEfiCpuArchProtocolGuid diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 988a59f576b7..80fe3487d138 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -252,6 +252,7 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif +SPI|UefiPayloadPkg/Library/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 4c5bf2613e49..d1ace3fb6d83 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -262,6 +262,7 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif +SPI|UefiPayloadPkg/Library/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf From a06f780dc7d95b6355cdc2c5949fc50ef1fa2698 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 08:51:27 +0200 Subject: [PATCH 002/297] fix spi references --- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 80fe3487d138..e0981bcd13a0 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -252,7 +252,7 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif -SPI|UefiPayloadPkg/Library/SPI/SPI.inf +SPI|UefiPayloadPkg/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index d1ace3fb6d83..ce11b6275714 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -262,7 +262,7 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif -SPI|UefiPayloadPkg/Library/SPI/SPI.inf +SPI|UefiPayloadPkg/Library/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf From b7f26ec730c1d3ebc923ca203f9faf92b7999561 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 08:57:22 +0200 Subject: [PATCH 003/297] fix spi references again --- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index ce11b6275714..a7a5b8f28b7b 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -262,7 +262,7 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif -SPI|UefiPayloadPkg/Library/SPI.inf +SPI|UefiPayloadPkg/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf From 5c6e6b74ec7fd73df58a1a92047cf590f8e07aff Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 09:07:08 +0200 Subject: [PATCH 004/297] comment out libraryClasses --- UefiPayloadPkg/SPI/SPI.inf | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index e11f6f1778f6..aabe2298cb02 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -25,16 +25,16 @@ UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] - IoLib - BaseLib + # IoLib + # BaseLib DebugLib - HobLib - SmmStoreLib - UefiLib - UefiDriverEntryPoint - UefiBootServicesTableLib - UefiRuntimeLib - DxeServicesTableLib + # HobLib + # SmmStoreLib + # UefiLib + # UefiDriverEntryPoint + # UefiBootServicesTableLib + # UefiRuntimeLib + # DxeServicesTableLib [Guids] gEfiSystemNvDataFvGuid From c28e73d9b77825990522a0e3952358c0305397ce Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 09:17:12 +0200 Subject: [PATCH 005/297] comment out Pcd --- UefiPayloadPkg/SPI/SPI.inf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index aabe2298cb02..d9fd1a46d7fb 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -50,14 +50,14 @@ gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES gEfiDiskIoProtocolGuid -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable +# [Pcd] +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +# gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable [Depex] gEfiCpuArchProtocolGuid From a6a607e7ff36243b69c659de04b9ba6665f8da58 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 09:26:50 +0200 Subject: [PATCH 006/297] comment out packages --- UefiPayloadPkg/SPI/SPI.inf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index d9fd1a46d7fb..d6328beb52e7 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,11 +18,11 @@ [Sources.common] SPI.c -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - UefiPayloadPkg/UefiPayloadPkg.dec +# [Packages] +# MdePkg/MdePkg.dec +# MdeModulePkg/MdeModulePkg.dec +# EmbeddedPkg/EmbeddedPkg.dec +# UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] # IoLib From 82dbac443139251410f5ab42639af876975c9ae1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 09:34:22 +0200 Subject: [PATCH 007/297] comment out protocols --- UefiPayloadPkg/SPI/SPI.inf | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index d6328beb52e7..e44b47348d7a 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -45,10 +45,10 @@ gEfiSMMSTOREInfoHobGuid [Protocols] - gEfiBlockIoProtocolGuid - gEfiDevicePathProtocolGuid +# gEfiBlockIoProtocolGuid +# gEfiDevicePathProtocolGuid gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES - gEfiDiskIoProtocolGuid +# gEfiDiskIoProtocolGuid # [Pcd] # gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase From 25cefec3d001dcc79a03632bea267a92fe758574 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 09:41:21 +0200 Subject: [PATCH 008/297] comment out guids --- UefiPayloadPkg/SPI/SPI.inf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index e44b47348d7a..23529b1d0855 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -36,13 +36,13 @@ # UefiRuntimeLib # DxeServicesTableLib -[Guids] - gEfiSystemNvDataFvGuid - gEfiVariableGuid - gEfiAuthenticatedVariableGuid - gEfiEventVirtualAddressChangeGuid - gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL - gEfiSMMSTOREInfoHobGuid +# [Guids] +# gEfiSystemNvDataFvGuid +# gEfiVariableGuid +# gEfiAuthenticatedVariableGuid +# gEfiEventVirtualAddressChangeGuid +# gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL +# gEfiSMMSTOREInfoHobGuid [Protocols] # gEfiBlockIoProtocolGuid From 4be3ab189e27a94b1718c8b66295e83724a8dbbc Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 09:52:20 +0200 Subject: [PATCH 009/297] add debug print --- UefiPayloadPkg/SPI/SPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 0cdbfe1b6141..366f7001c85b 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -7,6 +7,7 @@ **/ #include +#include STATIC EFI_STATUS @@ -15,5 +16,6 @@ InstallSmbusProtocol ( IN EFI_SYSTEM_TABLE *SystemTable ) { + DEBUG((EFI_D_INFO, "SPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPI")); return EFI_SUCCESS; } From 9d22349762dbe9e048ae3cb0e45457fb62c43d29 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 10:03:34 +0200 Subject: [PATCH 010/297] break some code --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 366f7001c85b..f8c2b10e981a 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -16,6 +16,6 @@ InstallSmbusProtocol ( IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG((EFI_D_INFO, "SPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPI")); + DEBUG((EFI_D_INFO, "SPISPISPISPIS return EFI_SUCCESS; } From 34c4b893c04e04595f00275189c5cd879945518f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 10:59:53 +0200 Subject: [PATCH 011/297] try to fix references --- UefiPayloadPkg/UefiPayloadPkg.fdf | 1 + UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 52e72faedce6..668ff886a7d6 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -50,6 +50,7 @@ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei. INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf INF UefiPayloadPkg/BlSupportPei/BlSupportPei.inf INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +INF UefiPayloadPkg/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE INF UefiPayloadPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index e0981bcd13a0..482f6905b29b 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -252,7 +252,6 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif -SPI|UefiPayloadPkg/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf @@ -460,6 +459,7 @@ SPI|UefiPayloadPkg/SPI/SPI.inf MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf UefiPayloadPkg/BlSupportPei/BlSupportPei.inf + UefiPayloadPkg/SPI/SPI.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index a7a5b8f28b7b..ec4de739b6b1 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -262,7 +262,6 @@ !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif -SPI|UefiPayloadPkg/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf @@ -471,6 +470,7 @@ SPI|UefiPayloadPkg/SPI/SPI.inf MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf UefiPayloadPkg/BlSupportPei/BlSupportPei.inf + UefiPayloadPkg/SPI/SPI.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE From 2e0dd17c0e72365697e7abfebae5993c3a5c3b35 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:05:45 +0200 Subject: [PATCH 012/297] fix broken code --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index f8c2b10e981a..366f7001c85b 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -16,6 +16,6 @@ InstallSmbusProtocol ( IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG((EFI_D_INFO, "SPISPISPISPIS + DEBUG((EFI_D_INFO, "SPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPI")); return EFI_SUCCESS; } From b532cc8e3f08ca8253e085f8907ea992b8a0592d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:13:09 +0200 Subject: [PATCH 013/297] restore pcd --- UefiPayloadPkg/SPI/SPI.inf | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 23529b1d0855..572e52f66b0a 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -50,14 +50,14 @@ gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES # gEfiDiskIoProtocolGuid -# [Pcd] -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize -# gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable [Depex] gEfiCpuArchProtocolGuid From cd04c5b6372ec5c68442f6a47a2c9e72d14c322f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:14:46 +0200 Subject: [PATCH 014/297] add guid --- UefiPayloadPkg/SPI/SPI.inf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 572e52f66b0a..3cbea39b854c 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -36,7 +36,8 @@ # UefiRuntimeLib # DxeServicesTableLib -# [Guids] +[Guids] + gEfiMdeModulePkgTokenSpaceGuid # gEfiSystemNvDataFvGuid # gEfiVariableGuid # gEfiAuthenticatedVariableGuid From 0879b3650139a67daca8bf9788b7e37c600cf23b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:15:55 +0200 Subject: [PATCH 015/297] add more guids --- UefiPayloadPkg/SPI/SPI.inf | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 3cbea39b854c..9fe1cc4b0034 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -38,12 +38,12 @@ [Guids] gEfiMdeModulePkgTokenSpaceGuid -# gEfiSystemNvDataFvGuid -# gEfiVariableGuid -# gEfiAuthenticatedVariableGuid -# gEfiEventVirtualAddressChangeGuid -# gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL -# gEfiSMMSTOREInfoHobGuid + gEfiSystemNvDataFvGuid + gEfiVariableGuid + gEfiAuthenticatedVariableGuid + gEfiEventVirtualAddressChangeGuid + gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL + gEfiSMMSTOREInfoHobGuid [Protocols] # gEfiBlockIoProtocolGuid From 026a3c00fd9232f590c5c2d264628e575ae1b1ee Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:25:54 +0200 Subject: [PATCH 016/297] fix inf --- UefiPayloadPkg/SPI/SPI.inf | 59 +++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 9fe1cc4b0034..84b0a410e8a8 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,32 +18,31 @@ [Sources.common] SPI.c -# [Packages] -# MdePkg/MdePkg.dec -# MdeModulePkg/MdeModulePkg.dec -# EmbeddedPkg/EmbeddedPkg.dec -# UefiPayloadPkg/UefiPayloadPkg.dec +[Packages] + MdePkg/MdePkg.dec + # MdeModulePkg/MdeModulePkg.dec + # EmbeddedPkg/EmbeddedPkg.dec + # UefiPayloadPkg/UefiPayloadPkg.dec -[LibraryClasses] - # IoLib - # BaseLib - DebugLib - # HobLib - # SmmStoreLib - # UefiLib - # UefiDriverEntryPoint - # UefiBootServicesTableLib - # UefiRuntimeLib - # DxeServicesTableLib +# [LibraryClasses] +# IoLib +# BaseLib +# DebugLib +# HobLib +# SmmStoreLib +# UefiLib +# UefiDriverEntryPoint +# UefiBootServicesTableLib +# UefiRuntimeLib +# DxeServicesTableLib [Guids] - gEfiMdeModulePkgTokenSpaceGuid - gEfiSystemNvDataFvGuid - gEfiVariableGuid - gEfiAuthenticatedVariableGuid + # gEfiSystemNvDataFvGuid + # gEfiVariableGuid + # gEfiAuthenticatedVariableGuid gEfiEventVirtualAddressChangeGuid - gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL - gEfiSMMSTOREInfoHobGuid + # gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL + # gEfiSMMSTOREInfoHobGuid [Protocols] # gEfiBlockIoProtocolGuid @@ -51,14 +50,14 @@ gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES # gEfiDiskIoProtocolGuid -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable +# [Pcd] +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase +# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize +# gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable [Depex] gEfiCpuArchProtocolGuid From 0dbf925e3ab164fa2874ccba32fdfeff2749bb10 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:27:13 +0200 Subject: [PATCH 017/297] fix ctor name --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 366f7001c85b..6db41f9fc269 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -11,7 +11,7 @@ STATIC EFI_STATUS -InstallSmbusProtocol ( +SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) From 3dc2bfdb4421ebf16adf585b61947d875f3b033f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:31:24 +0200 Subject: [PATCH 018/297] ctor not static anymore --- UefiPayloadPkg/SPI/SPI.c | 1 - 1 file changed, 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 6db41f9fc269..94cba577a925 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -9,7 +9,6 @@ #include #include -STATIC EFI_STATUS SPIInitialize ( IN EFI_HANDLE ImageHandle, From 7698f5530863ace6055bbc772d10265a95524dfc Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:34:02 +0200 Subject: [PATCH 019/297] change driver type --- UefiPayloadPkg/SPI/SPI.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 84b0a410e8a8..ba10bc0cbc9b 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -11,7 +11,7 @@ INF_VERSION = 0x00010005 BASE_NAME = SPI FILE_GUID = 9f185eec-6795-462d-9663-5bb9a85be9f2 - MODULE_TYPE = DXE_RUNTIME_DRIVER + MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = SPIInitialize From 358fb5de1323539c547c1d8e0e8609185da9b3a0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:35:57 +0200 Subject: [PATCH 020/297] ctor definition --- UefiPayloadPkg/SPI/SPI.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 94cba577a925..5edfc80720e1 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -10,7 +10,8 @@ #include EFI_STATUS -SPIInitialize ( +EFIAPI +InstallSmbusProtocol ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) From b58c3014709734ba4741fbf20b35888c5611c802 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:39:32 +0200 Subject: [PATCH 021/297] try to fix --- UefiPayloadPkg/SPI/SPI.inf | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index ba10bc0cbc9b..8b315d10d027 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -20,21 +20,21 @@ [Packages] MdePkg/MdePkg.dec - # MdeModulePkg/MdeModulePkg.dec - # EmbeddedPkg/EmbeddedPkg.dec - # UefiPayloadPkg/UefiPayloadPkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec -# [LibraryClasses] -# IoLib -# BaseLib -# DebugLib -# HobLib -# SmmStoreLib -# UefiLib -# UefiDriverEntryPoint -# UefiBootServicesTableLib -# UefiRuntimeLib -# DxeServicesTableLib +[LibraryClasses] + IoLib + BaseLib + DebugLib + HobLib + SmmStoreLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeLib + DxeServicesTableLib [Guids] # gEfiSystemNvDataFvGuid From a12674ab5c005422d25da910267c4b63341de56f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:43:22 +0200 Subject: [PATCH 022/297] another try --- UefiPayloadPkg/{ => Library}/SPI/SPI.c | 2 +- UefiPayloadPkg/Library/SPI/SPI.inf | 27 ++++++++++ UefiPayloadPkg/SPI/SPI.inf | 63 ------------------------ UefiPayloadPkg/UefiPayloadPkg.fdf | 2 +- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +- 6 files changed, 31 insertions(+), 67 deletions(-) rename UefiPayloadPkg/{ => Library}/SPI/SPI.c (99%) create mode 100644 UefiPayloadPkg/Library/SPI/SPI.inf delete mode 100644 UefiPayloadPkg/SPI/SPI.inf diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/Library/SPI/SPI.c similarity index 99% rename from UefiPayloadPkg/SPI/SPI.c rename to UefiPayloadPkg/Library/SPI/SPI.c index 5edfc80720e1..995783108379 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/Library/SPI/SPI.c @@ -11,7 +11,7 @@ EFI_STATUS EFIAPI -InstallSmbusProtocol ( +SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) diff --git a/UefiPayloadPkg/Library/SPI/SPI.inf b/UefiPayloadPkg/Library/SPI/SPI.inf new file mode 100644 index 000000000000..2ba56852727a --- /dev/null +++ b/UefiPayloadPkg/Library/SPI/SPI.inf @@ -0,0 +1,27 @@ +#/** @file +# +# Component description file for SMMSTORE module +# +# Copyright (c) 2020, 9elements Agency GmbH
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = SPI + FILE_GUID = 9f185eec-6795-462d-9663-5bb9a85be9f2 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = SPIInitialize + +[Sources] + SPI.c + +[LibraryClasses] + DebugLib + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf deleted file mode 100644 index 8b315d10d027..000000000000 --- a/UefiPayloadPkg/SPI/SPI.inf +++ /dev/null @@ -1,63 +0,0 @@ -#/** @file -# -# Component description file for SMMSTORE module -# -# Copyright (c) 2020, 9elements Agency GmbH
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SPI - FILE_GUID = 9f185eec-6795-462d-9663-5bb9a85be9f2 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = SPIInitialize - -[Sources.common] - SPI.c - -[Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec - EmbeddedPkg/EmbeddedPkg.dec - UefiPayloadPkg/UefiPayloadPkg.dec - -[LibraryClasses] - IoLib - BaseLib - DebugLib - HobLib - SmmStoreLib - UefiLib - UefiDriverEntryPoint - UefiBootServicesTableLib - UefiRuntimeLib - DxeServicesTableLib - -[Guids] - # gEfiSystemNvDataFvGuid - # gEfiVariableGuid - # gEfiAuthenticatedVariableGuid - gEfiEventVirtualAddressChangeGuid - # gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL - # gEfiSMMSTOREInfoHobGuid - -[Protocols] -# gEfiBlockIoProtocolGuid -# gEfiDevicePathProtocolGuid - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES -# gEfiDiskIoProtocolGuid - -# [Pcd] -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase -# gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize -# gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable - - [Depex] - gEfiCpuArchProtocolGuid diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 668ff886a7d6..167ccab35fd6 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -50,7 +50,7 @@ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei. INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf INF UefiPayloadPkg/BlSupportPei/BlSupportPei.inf INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf -INF UefiPayloadPkg/SPI/SPI.inf +INF UefiPayloadPkg/Library/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE INF UefiPayloadPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 482f6905b29b..2e7a03bb67d1 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -459,7 +459,7 @@ MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf UefiPayloadPkg/BlSupportPei/BlSupportPei.inf - UefiPayloadPkg/SPI/SPI.inf + UefiPayloadPkg/Library/SPI/SPI.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index ec4de739b6b1..76e7c5ef407e 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -470,7 +470,7 @@ MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf UefiPayloadPkg/BlSupportPei/BlSupportPei.inf - UefiPayloadPkg/SPI/SPI.inf + UefiPayloadPkg/Library/SPI/SPI.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE From a5595a89852df922f166c706928dd5debcc00f16 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:45:29 +0200 Subject: [PATCH 023/297] fix reference al lib --- UefiPayloadPkg/UefiPayloadPkg.fdf | 1 - UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 4 ++-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 167ccab35fd6..52e72faedce6 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -50,7 +50,6 @@ INF MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei. INF MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf INF UefiPayloadPkg/BlSupportPei/BlSupportPei.inf INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf -INF UefiPayloadPkg/Library/SPI/SPI.inf !if $(TPM_ENABLE) == TRUE INF UefiPayloadPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 2e7a03bb67d1..cf86e9ba82ea 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -249,6 +249,7 @@ !if $(BOOTLOADER) == "COREBOOT" SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf + SPI|UefiPayloadPkg/Library/SPI/SPI.inf !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif @@ -459,7 +460,6 @@ MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf UefiPayloadPkg/BlSupportPei/BlSupportPei.inf - UefiPayloadPkg/Library/SPI/SPI.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 76e7c5ef407e..f32799e3ce28 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -259,6 +259,7 @@ !endif !if $(BOOTLOADER) == "COREBOOT" SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf + SPI|UefiPayloadPkg/Library/SPI/SPI.inf !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif @@ -469,8 +470,7 @@ MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf - UefiPayloadPkg/BlSupportPei/BlSupportPei.inf - UefiPayloadPkg/Library/SPI/SPI.inf + UefiPayloadPkg/BlSupportPei/BlSupportPei.inf\ MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE From d0f554287123b916995bb9be5ab874d75de79712 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 11:47:04 +0200 Subject: [PATCH 024/297] fix slash --- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index f32799e3ce28..a0d2adbb1368 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -470,7 +470,7 @@ MdeModulePkg/Universal/ReportStatusCodeRouter/Pei/ReportStatusCodeRouterPei.inf MdeModulePkg/Universal/StatusCodeHandler/Pei/StatusCodeHandlerPei.inf - UefiPayloadPkg/BlSupportPei/BlSupportPei.inf\ + UefiPayloadPkg/BlSupportPei/BlSupportPei.inf MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE From 1a399eab27bc910d934553cf88cf709f2726f0da Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 12:01:28 +0200 Subject: [PATCH 025/297] move from libs --- UefiPayloadPkg/{Library => }/SPI/SPI.c | 0 UefiPayloadPkg/{Library => }/SPI/SPI.inf | 6 +++--- UefiPayloadPkg/UefiPayloadPkg.fdf | 1 + UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 3 ++- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) rename UefiPayloadPkg/{Library => }/SPI/SPI.c (100%) rename UefiPayloadPkg/{Library => }/SPI/SPI.inf (73%) diff --git a/UefiPayloadPkg/Library/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c similarity index 100% rename from UefiPayloadPkg/Library/SPI/SPI.c rename to UefiPayloadPkg/SPI/SPI.c diff --git a/UefiPayloadPkg/Library/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf similarity index 73% rename from UefiPayloadPkg/Library/SPI/SPI.inf rename to UefiPayloadPkg/SPI/SPI.inf index 2ba56852727a..85593080db17 100644 --- a/UefiPayloadPkg/Library/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -10,10 +10,10 @@ [Defines] INF_VERSION = 0x00010005 BASE_NAME = SPI - FILE_GUID = 9f185eec-6795-462d-9663-5bb9a85be9f2 - MODULE_TYPE = BASE + FILE_GUID = e18edc1a-d43d-4e34-8131-088433608076 + MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 - LIBRARY_CLASS = SPIInitialize + ENTRY_POINT = SPIInitialize [Sources] SPI.c diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 52e72faedce6..ec2c12dd468f 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -92,6 +92,7 @@ APRIORI DXE { # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf } +INF UefiPayloadPkg/SPI/SPI.inf # # DXE Phase modules diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index cf86e9ba82ea..505122e91673 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -249,7 +249,6 @@ !if $(BOOTLOADER) == "COREBOOT" SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf - SPI|UefiPayloadPkg/Library/SPI/SPI.inf !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif @@ -439,6 +438,8 @@ # ################################################################################ [Components.IA32] + + UefiPayloadPkg/SPI/SPI.inf # # SEC Core # diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index a0d2adbb1368..0436b1804530 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -259,7 +259,6 @@ !endif !if $(BOOTLOADER) == "COREBOOT" SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf - SPI|UefiPayloadPkg/Library/SPI/SPI.inf !else SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf !endif @@ -488,6 +487,7 @@ !endif [Components.X64] + UefiPayloadPkg/SPI/SPI.inf # # DXE Core # From 42e356e997d73f93a43f6c5ecdbeb4fd0f12adb6 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 12:09:21 +0200 Subject: [PATCH 026/297] try to fix inf --- UefiPayloadPkg/SPI/SPI.inf | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 85593080db17..1207d31019ce 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,10 +18,20 @@ [Sources] SPI.c -[LibraryClasses] - DebugLib - [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + DebugLib + IoLib + UefiLib + TimerLib + PciExpressLib + +[Protocols] + gEfiSmbusHcProtocolGuid ## PRODUCES + +[Depex] + TRUE From 7be86b62e40045d1b9070941551cb1f6f0279756 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 12:16:56 +0200 Subject: [PATCH 027/297] remove libs --- UefiPayloadPkg/SPI/SPI.c | 2 +- UefiPayloadPkg/SPI/SPI.inf | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 995783108379..b7cb095811fa 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -16,6 +16,6 @@ SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG((EFI_D_INFO, "SPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPISPI")); + DEBUG((EFI_D_INFO, "QWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWE")); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 1207d31019ce..17ff501aaedf 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -23,12 +23,12 @@ MdeModulePkg/MdeModulePkg.dec [LibraryClasses] - UefiDriverEntryPoint + # UefiDriverEntryPoint DebugLib - IoLib - UefiLib - TimerLib - PciExpressLib + # IoLib + # UefiLib + # TimerLib + # PciExpressLib [Protocols] gEfiSmbusHcProtocolGuid ## PRODUCES From 810e336644acddcc8740fe6782e6e9e01b8545d9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 12:36:45 +0200 Subject: [PATCH 028/297] restore --- UefiPayloadPkg/SPI/SPI.inf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 17ff501aaedf..1207d31019ce 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -23,12 +23,12 @@ MdeModulePkg/MdeModulePkg.dec [LibraryClasses] - # UefiDriverEntryPoint + UefiDriverEntryPoint DebugLib - # IoLib - # UefiLib - # TimerLib - # PciExpressLib + IoLib + UefiLib + TimerLib + PciExpressLib [Protocols] gEfiSmbusHcProtocolGuid ## PRODUCES From 7caba7694bda5bcaf42911b05176ffb4c0c16df1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 12:39:54 +0200 Subject: [PATCH 029/297] comment some libs --- UefiPayloadPkg/SPI/SPI.inf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 1207d31019ce..afd49c935158 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -25,10 +25,10 @@ [LibraryClasses] UefiDriverEntryPoint DebugLib - IoLib - UefiLib - TimerLib - PciExpressLib + # IoLib + # UefiLib + # TimerLib + # PciExpressLib [Protocols] gEfiSmbusHcProtocolGuid ## PRODUCES From 7f643ef7e89704ff5249585c6aa577f955d0a82e Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 13:26:56 +0200 Subject: [PATCH 030/297] register protocol --- UefiPayloadPkg/SPI/SPI.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index b7cb095811fa..0687889292a9 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -8,6 +8,20 @@ #include #include +#include +#include +#include + +EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL, //ParentHandle + }; EFI_STATUS EFIAPI @@ -16,6 +30,14 @@ SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG((EFI_D_INFO, "QWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWEQWE")); + EFI_STATUS Status; + Status = gBS->InstallProtocolInterface( + ImageHandle, + &gEfiDevicePathProtocolGuid, + EFI_NATIVE_INTERFACE, + &FvbProtocol); + DEBUG((EFI_D_INFO, "SPI\n")); + DEBUG((EFI_D_INFO, "%i\n", Status)); + DEBUG((EFI_D_INFO, "%i\n", EFI_ERROR (Status))); return EFI_SUCCESS; } From 3e5f6def08cebb8a131fc310f57353eb823070c5 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 13:38:56 +0200 Subject: [PATCH 031/297] protocol definition in SPI --- UefiPayloadPkg/SPI/SPI.c | 2 +- UefiPayloadPkg/SPI/SPI.h | 118 +++++++++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/SPI.inf | 1 + 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 UefiPayloadPkg/SPI/SPI.h diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 0687889292a9..277edda6bdee 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -10,7 +10,7 @@ #include #include #include -#include +#include "SPI.h" EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { FvbGetAttributes, // GetAttributes diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h new file mode 100644 index 000000000000..14ac5912e34b --- /dev/null +++ b/UefiPayloadPkg/SPI/SPI.h @@ -0,0 +1,118 @@ +/** @file BlSMMStoreDxe.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SPI_H__ +#define __SPI_H__ + + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) + +typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT8 Index; + EFI_DEVICE_PATH_PROTOCOL End; +} NOR_FLASH_DEVICE_PATH; +#pragma pack () + +struct _SMMSTORE_INSTANCE { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; + + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + + NOR_FLASH_DEVICE_PATH DevicePath; +}; + +// +// BlSMMStoreFvbDxe.c +// + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ); + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbWrite( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + + +#endif /* __SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index afd49c935158..d4fb1c2b8780 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -16,6 +16,7 @@ ENTRY_POINT = SPIInitialize [Sources] + SPI.h SPI.c [Packages] From de47705929ea8947cc4642edf588eac74e3f0b39 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 13:46:44 +0200 Subject: [PATCH 032/297] dummy fill with NULLs --- UefiPayloadPkg/SPI/SPI.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 277edda6bdee..a6d59bea60ab 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,13 +13,13 @@ #include "SPI.h" EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks + NULL, // FvbGetAttributes, // GetAttributes + NULL, // FvbSetAttributes, // SetAttributes + NULL, // FvbGetPhysicalAddress, // GetPhysicalAddress + NULL, // FvbGetBlockSize, // GetBlockSize + NULL, // FvbRead, // Read + NULL, // FvbWrite, // Write + NULL, // FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }; From 84ae43fcd58ed3b9f111493918c9a552e327b39c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 18 Sep 2020 14:00:00 +0200 Subject: [PATCH 033/297] change format --- UefiPayloadPkg/SPI/SPI.c | 4 ++-- UefiPayloadPkg/SPI/SPI.inf | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index a6d59bea60ab..f61aa2cc5b74 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -37,7 +37,7 @@ SPIInitialize ( EFI_NATIVE_INTERFACE, &FvbProtocol); DEBUG((EFI_D_INFO, "SPI\n")); - DEBUG((EFI_D_INFO, "%i\n", Status)); - DEBUG((EFI_D_INFO, "%i\n", EFI_ERROR (Status))); + DEBUG((EFI_D_INFO, "%d\n", Status)); + DEBUG((EFI_D_INFO, "%d\n", EFI_ERROR (Status))); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index d4fb1c2b8780..75e80e9fdb51 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -26,10 +26,6 @@ [LibraryClasses] UefiDriverEntryPoint DebugLib - # IoLib - # UefiLib - # TimerLib - # PciExpressLib [Protocols] gEfiSmbusHcProtocolGuid ## PRODUCES From 19e238ca41decfb0ab7818380f1d1a459392e37d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:12:37 +0200 Subject: [PATCH 034/297] another try to install protocol --- UefiPayloadPkg/SPI/SPI.c | 20 +++++++++++--------- UefiPayloadPkg/SPI/SPI.inf | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index f61aa2cc5b74..ce7486be97d1 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,13 +13,13 @@ #include "SPI.h" EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - NULL, // FvbGetAttributes, // GetAttributes - NULL, // FvbSetAttributes, // SetAttributes - NULL, // FvbGetPhysicalAddress, // GetPhysicalAddress - NULL, // FvbGetBlockSize, // GetBlockSize - NULL, // FvbRead, // Read - NULL, // FvbWrite, // Write - NULL, // FvbEraseBlocks, // EraseBlocks + SPIInitialize, // FvbGetAttributes, // GetAttributes + SPIInitialize, // FvbSetAttributes, // SetAttributes + SPIInitialize, // FvbGetPhysicalAddress, // GetPhysicalAddress + SPIInitialize, // FvbGetBlockSize, // GetBlockSize + SPIInitialize, // FvbRead, // Read + SPIInitialize, // FvbWrite, // Write + SPIInitialize, // FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }; @@ -37,7 +37,9 @@ SPIInitialize ( EFI_NATIVE_INTERFACE, &FvbProtocol); DEBUG((EFI_D_INFO, "SPI\n")); - DEBUG((EFI_D_INFO, "%d\n", Status)); - DEBUG((EFI_D_INFO, "%d\n", EFI_ERROR (Status))); + if(EFI_ERROR (Status)) { + DEBUG(( + EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + } return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 75e80e9fdb51..0b05bc40d5db 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -26,6 +26,7 @@ [LibraryClasses] UefiDriverEntryPoint DebugLib + BaseMemoryLib [Protocols] gEfiSmbusHcProtocolGuid ## PRODUCES From 8b6e0f7faad9aabbfe311b9db2d22e3d1f737e39 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:25:18 +0200 Subject: [PATCH 035/297] change protocoll fill --- UefiPayloadPkg/SPI/SPI.c | 51 ++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index ce7486be97d1..0c731b3234a2 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,16 +13,53 @@ #include "SPI.h" EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - SPIInitialize, // FvbGetAttributes, // GetAttributes - SPIInitialize, // FvbSetAttributes, // SetAttributes - SPIInitialize, // FvbGetPhysicalAddress, // GetPhysicalAddress - SPIInitialize, // FvbGetBlockSize, // GetBlockSize - SPIInitialize, // FvbRead, // Read - SPIInitialize, // FvbWrite, // Write - SPIInitialize, // FvbEraseBlocks, // EraseBlocks + FvbGetAttributes, // FvbGetAttributes, // GetAttributes + FvbGetAttributes, // FvbSetAttributes, // SetAttributes + FvbGetAttributes, // FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetAttributes, // FvbGetBlockSize, // GetBlockSize + FvbGetAttributes, // FvbRead, // Read + FvbGetAttributes, // FvbWrite, // Write + FvbGetAttributes, // FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }; +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( + + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') + + ); + + // Check if it is write protected + if (Instance->Media.ReadOnly != TRUE) { + + FlashFvbAttributes = FlashFvbAttributes | + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled + } + + *Attributes = FlashFvbAttributes; + + DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); + + return EFI_SUCCESS; +} + EFI_STATUS EFIAPI SPIInitialize ( From 93b84225d57b4e87b1d014712275be5fadc0891f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:41:15 +0200 Subject: [PATCH 036/297] add definitions of FVB protocol --- UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c | 813 ++++++++++++++++++++++++++ UefiPayloadPkg/SPI/SPI.inf | 1 + 2 files changed, 814 insertions(+) create mode 100644 UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c diff --git a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c new file mode 100644 index 000000000000..d8dcd5c4f29e --- /dev/null +++ b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c @@ -0,0 +1,813 @@ +/*++ @file BlSMMStoreFvbDxe.c + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + --*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "BlSMMStoreDxe.h" + +STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; +STATIC UINTN mFlashNvStorageVariableBase; + +/// +/// The Firmware Volume Block Protocol is the low-level interface +/// to a firmware volume. File-level access to a firmware volume +/// should not be done using the Firmware Volume Block Protocol. +/// Normal access to a firmware volume must use the Firmware +/// Volume Protocol. Typically, only the file system driver that +/// produces the Firmware Volume Protocol will bind to the +/// Firmware Volume Block Protocol. +/// + +/** + Initialises the FV Header and Variable Store Header + to support variable operations. + + @param[in] Ptr - Location to initialise the headers + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN SMMSTORE_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + VOID* Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); + Headers = AllocateZeroPool(HeadersLength); + + // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + + // Check if the size of the area is at least one block size + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); + + // Ensure the Variable area Base Addresses are aligned on a block size boundaries + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + + // + // EFI_FIRMWARE_VOLUME_HEADER + // + FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; + CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); + FirmwareVolumeHeader->FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; + FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled + ); + FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); + FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; + FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; + FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; + FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; + FirmwareVolumeHeader->BlockMap[1].Length = 0; + FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); + + // + // VARIABLE_STORE_HEADER + // + VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); + CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; + VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; + VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; + + // Install the combined super-header in the store + Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); + + FreePool (Headers); + return Status; +} + +/** + Check the integrity of firmware volume header. + + @param[in] FwVolHeader - A pointer to a firmware volume header + + @retval EFI_SUCCESS - The firmware volume is consistent + @retval EFI_NOT_FOUND - The firmware volume has been corrupted. + +**/ +EFI_STATUS +ValidateFvHeader ( + IN SMMSTORE_INSTANCE *Instance + ) +{ + UINT16 Checksum; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINTN VariableStoreLength; + UINTN FvLength; + EFI_STATUS TempStatus; + UINTN BufferSize; + UINTN BufferSizeReqested; + + BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ( (FwVolHeader->Revision != EFI_FVH_REVISION) + || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength != FvLength) + ) + { + DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", + __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + // Check the Firmware Volume Guid + if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { + DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = FwVolHeader->HeaderLength; + FreePool (FwVolHeader); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + // Verify the header checksum + Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); + if (Checksum != 0) { + DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", + __FUNCTION__, Checksum)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); + VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); + if (!VariableStoreHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = SMMStoreRead (0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (VariableStoreHeader); + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + // Check the Variable Store Guid + if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && + !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; + if (VariableStoreHeader->Size != VariableStoreLength) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + + return EFI_SUCCESS; +} + +/** + The GetAttributes() function retrieves the attributes and + current settings of the block. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and + current settings are returned. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + **/ +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( + + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') + + ); + + // Check if it is write protected + if (Instance->Media.ReadOnly != TRUE) { + + FlashFvbAttributes = FlashFvbAttributes | + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled + } + + *Attributes = FlashFvbAttributes; + + DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); + + return EFI_SUCCESS; +} + +/** + The SetAttributes() function sets configurable firmware volume attributes + and returns the new settings of the firmware volume. + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 + that contains the desired firmware volume settings. + On successful return, it contains the new settings of + the firmware volume. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities + as declared in the firmware volume header. + + **/ +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); + return EFI_UNSUPPORTED; +} + +/** + The GetPhysicalAddress() function retrieves the base address of + a memory-mapped firmware volume. This function should be called + only for memory-mapped firmware volumes. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), contains the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. + + **/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + ASSERT(Address != NULL); + + *Address = mFlashNvStorageVariableBase; + return EFI_SUCCESS; +} + +/** + The GetBlockSize() function retrieves the size of the requested + block. It also returns the number of additional blocks with + the identical size. The GetBlockSize() function is used to + retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba Indicates the block for which to return the size. + + @param BlockSize Pointer to a caller-allocated UINTN in which + the size of the block is returned. + + @param NumberOfBlocks Pointer to a caller-allocated UINTN in + which the number of consecutive blocks, + starting with Lba, is returned. All + blocks in this range have a size of + BlockSize. + + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + + **/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ) +{ + EFI_STATUS Status; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock)); + + if (Lba > Instance->Media.LastBlock) { + DEBUG ((EFI_D_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock)); + Status = EFI_INVALID_PARAMETER; + } else { + *BlockSize = (UINTN) Instance->Media.BlockSize; + *NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1); + + DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks)); + + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + Reads the specified number of bytes into a buffer from the specified block. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + Implementations should be mindful that the firmware volume + might be in the ReadDisabled state. If it is in this state, + the Read() function must return the status code + EFI_ACCESS_DENIED without modifying the contents of the + buffer. The Read() function must also prevent spanning block + boundaries. If a read is requested that would span a block + boundary, the read must read up to the boundary but not + beyond. The output parameter NumBytes must be set to correctly + indicate the number of bytes actually read. The caller must be + aware that a read may be partially completed. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index from which to read. + + @param Offset Offset into the block at which to begin reading. + + @param NumBytes Pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes read. + + @param Buffer Pointer to a caller-allocated buffer that will be used + to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read successfully, and contents are + in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + returned in Buffer. + + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. + + **/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ) +{ + UINTN BlockSize; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return SMMStoreRead (Lba, Offset, NumBytes, Buffer); +} + +/** + Writes the specified number of bytes from the input buffer to the block. + + The Write() function writes the specified number of bytes from + the provided buffer to the specified block and offset. If the + firmware volume is sticky write, the caller must ensure that + all the bits of the specified range to write are in the + EFI_FVB_ERASE_POLARITY state before calling the Write() + function, or else the result will be unpredictable. This + unpredictability arises because, for a sticky-write firmware + volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY + state but cannot flip it back again. Before calling the + Write() function, it is recommended for the caller to first call + the EraseBlocks() function to erase the specified block to + write. A block erase cycle will transition bits from the + (NOT)EFI_FVB_ERASE_POLARITY state back to the + EFI_FVB_ERASE_POLARITY state. Implementations should be + mindful that the firmware volume might be in the WriteDisabled + state. If it is in this state, the Write() function must + return the status code EFI_ACCESS_DENIED without modifying the + contents of the firmware volume. The Write() function must + also prevent spanning block boundaries. If a write is + requested that spans a block boundary, the write must store up + to the boundary but not beyond. The output parameter NumBytes + must be set to correctly indicate the number of bytes actually + written. The caller must be aware that a write may be + partially completed. All writes, partial or otherwise, must be + fully flushed to the hardware before the Write() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index to write to. + + @param Offset Offset into the block at which to begin writing. + + @param NumBytes The pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes actually written. + + @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully. + + @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + actually written. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. + + + **/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINTN BlockSize; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return SMMStoreWrite (Lba, Offset, NumBytes, Buffer); +} + +/** + Erases and initialises a firmware volume block. + + The EraseBlocks() function erases one or more blocks as denoted + by the variable argument list. The entire parameter list of + blocks must be verified before erasing any blocks. If a block is + requested that does not exist within the associated firmware + volume (it has a larger index than the last block of the + firmware volume), the EraseBlocks() function must return the + status code EFI_INVALID_PARAMETER without modifying the contents + of the firmware volume. Implementations should be mindful that + the firmware volume might be in the WriteDisabled state. If it + is in this state, the EraseBlocks() function must return the + status code EFI_ACCESS_DENIED without modifying the contents of + the firmware volume. All calls to EraseBlocks() must be fully + flushed to the hardware before the EraseBlocks() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + instance. + + @param ... The variable argument list is a list of tuples. + Each tuple describes a range of LBAs to erase + and consists of the following: + - An EFI_LBA that indicates the starting LBA + - A UINTN that indicates the number of blocks to erase. + + The list is terminated with an EFI_LBA_LIST_TERMINATOR. + For example, the following indicates that two ranges of blocks + (5-7 and 10-11) are to be erased: + EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); + + @retval EFI_SUCCESS The erase request successfully completed. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. + The firmware device may have been partially erased. + + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do + not exist in the firmware volume. + + **/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Args; + EFI_LBA StartingLba; // Lba from which we start erasing + UINTN NumOfLba; // Number of Lba blocks to erase + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks()\n")); + + Status = EFI_SUCCESS; + + // Detect WriteDisabled state + if (Instance->Media.ReadOnly == TRUE) { + // Firmware volume is in WriteDisabled state + DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n")); + return EFI_ACCESS_DENIED; + } + + // Before erasing, check the entire list of parameters to ensure all specified blocks are valid + + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba = VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + //Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba = VA_ARG (Args, UINTN); + + // All blocks must be within range + DEBUG (( + DEBUG_BLKIO, + "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n", + StartingLba, + (UINT64)NumOfLba, + Instance->Media.LastBlock + )); + if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { + VA_END (Args); + DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n")); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } while (TRUE); + VA_END (Args); + + // + // To get here, all must be ok, so start erasing + // + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba = VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + // Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba = VA_ARG (Args, UINTN); + + // Go through each one and erase it + while (NumOfLba > 0) { + // Erase it + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba)); + Status = SMMStoreEraseBlock (StartingLba); + if (EFI_ERROR(Status)) { + VA_END (Args); + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // Move to the next Lba + StartingLba++; + NumOfLba--; + } + } while (TRUE); + VA_END (Args); + +EXIT: + return Status; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +FvbVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); + return; +} + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ) +{ + EFI_STATUS Status; + UINT32 FvbNumLba; + EFI_BOOT_MODE BootMode; + + DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); + ASSERT((Instance != NULL)); + + mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); + + BootMode = GetBootModeHob (); + if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { + Status = EFI_INVALID_PARAMETER; + } else { + // Determine if there is a valid header at the beginning of the NorFlash + Status = ValidateFvHeader (Instance); + } + + // Install the Default FVB header if required + if (EFI_ERROR(Status)) { + // There is no valid header, so time to install one. + DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); + DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", + __FUNCTION__)); + + // Erase all the NorFlash that is reserved for variable storage + FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; + + Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); + if (EFI_ERROR(Status)) { + return Status; + } + + // Install all appropriate headers + Status = InitializeFvAndVariableStoreHeaders (Instance); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); + } + + // + // The driver implementing the variable read service can now be dispatched; + // the varstore headers are in place. + // + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mFvbVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 0b05bc40d5db..912829f52863 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,6 +18,7 @@ [Sources] SPI.h SPI.c + BlSMMStoreFvbDxe.c [Packages] MdePkg/MdePkg.dec From fdd65fe6809dfc772594638729f5fccd57f65803 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:44:43 +0200 Subject: [PATCH 037/297] only one definition --- UefiPayloadPkg/SPI/SPI.c | 51 ++++++-------------------------------- UefiPayloadPkg/SPI/SPI.inf | 2 +- 2 files changed, 8 insertions(+), 45 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 0c731b3234a2..f8929cdf92a2 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,53 +13,16 @@ #include "SPI.h" EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // FvbGetAttributes, // GetAttributes - FvbGetAttributes, // FvbSetAttributes, // SetAttributes - FvbGetAttributes, // FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetAttributes, // FvbGetBlockSize, // GetBlockSize - FvbGetAttributes, // FvbRead, // Read - FvbGetAttributes, // FvbWrite, // Write - FvbGetAttributes, // FvbEraseBlocks, // EraseBlocks + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }; -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( - - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') - - ); - - // Check if it is write protected - if (Instance->Media.ReadOnly != TRUE) { - - FlashFvbAttributes = FlashFvbAttributes | - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled - } - - *Attributes = FlashFvbAttributes; - - DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); - - return EFI_SUCCESS; -} - EFI_STATUS EFIAPI SPIInitialize ( diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 912829f52863..bb5607f9324d 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,7 +18,7 @@ [Sources] SPI.h SPI.c - BlSMMStoreFvbDxe.c + # BlSMMStoreFvbDxe.c [Packages] MdePkg/MdePkg.dec From 2475829c71c5d9e9966057b0e6153e75a705db20 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:47:11 +0200 Subject: [PATCH 038/297] but it needs to be at least one --- UefiPayloadPkg/SPI/SPI.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index bb5607f9324d..912829f52863 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,7 +18,7 @@ [Sources] SPI.h SPI.c - # BlSMMStoreFvbDxe.c + BlSMMStoreFvbDxe.c [Packages] MdePkg/MdePkg.dec From 4529a3dae3c8d8d65bb74569ebcab3ebbf1ca849 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:51:58 +0200 Subject: [PATCH 039/297] add required files --- UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c | 2 +- UefiPayloadPkg/SPI/SMMStoreLib.h | 98 +++++++++++++++++++++++++ UefiPayloadPkg/SPI/SPI.inf | 1 + UefiPayloadPkg/SPI/SblSMMStore.c | 102 ++++++++++++++++++++++++++ 4 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 UefiPayloadPkg/SPI/SMMStoreLib.h create mode 100644 UefiPayloadPkg/SPI/SblSMMStore.c diff --git a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c index d8dcd5c4f29e..2653f34741b7 100644 --- a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c +++ b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c @@ -16,7 +16,7 @@ #include #include #include -#include +#include #include #include diff --git a/UefiPayloadPkg/SPI/SMMStoreLib.h b/UefiPayloadPkg/SPI/SMMStoreLib.h new file mode 100644 index 000000000000..e6b7f0d9ef24 --- /dev/null +++ b/UefiPayloadPkg/SPI/SMMStoreLib.h @@ -0,0 +1,98 @@ +/** @file SMMStoreLib.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SMM_STORE_LIB_H__ +#define __SMM_STORE_LIB_H__ + +#include +#include +#include + +#define SMMSTORE_COMBUF_SIZE 16 + +/** + Read from SMMStore + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +SMMStoreRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Write to SMMStore + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +SMMStoreWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Erase a block using the SMMStore + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +SMMStoreEraseBlock ( + IN EFI_LBA Lba + ); + + +/** + Notify the SMMStore Library about a VirtualNotify + +**/ + +VOID +EFIAPI +SMMStoreVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Initializes SMMStore support + + @param[in] Ptr A runtime buffer where arguments are stored + for SMM communication + @param[in] SmmStoreInfoHob A runtime buffer with a copy of the + SmmStore Info Hob + + @retval EFI_WRITE_PROTECTED The SMMSTORE is not present. + @retval EFI_SUCCESS The SMMSTORE is supported. + +**/ +EFI_STATUS +SMMStoreInitialize ( + IN VOID *Ptr, + IN SMMSTORE_INFO *SmmStoreInfoHob + ); + +#endif /* __SMM_STORE_LIB_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 912829f52863..7915d0c1e860 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -19,6 +19,7 @@ SPI.h SPI.c BlSMMStoreFvbDxe.c + SblSMMStore.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SblSMMStore.c b/UefiPayloadPkg/SPI/SblSMMStore.c new file mode 100644 index 000000000000..61dfb86117ec --- /dev/null +++ b/UefiPayloadPkg/SPI/SblSMMStore.c @@ -0,0 +1,102 @@ +/** @file CorebootSMMStoreDxe.c + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include + +#include +#include +#include +#include + +/** + Read from SMMStore + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +SMMStoreRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + + +/** + Write to SMMStore + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +SMMStoreWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + return EFI_UNSUPPORTED; +} + + +/** + Erase a SMMStore block + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +SMMStoreEraseBlock ( + IN EFI_LBA Lba + ) +{ + return EFI_UNSUPPORTED; +} + +VOID +EFIAPI +SMMStoreVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + return; +} + +/** + Initializes SMMStore support + + @param[in] Ptr A runtime buffer where arguments are stored + for SMM communication + @param[in] SmmStoreInfoHob A runtime buffer with a copy of the + SmmStore Info Hob + + @retval EFI_WRITE_PROTECTED The SMMSTORE is not present. + @retval EFI_SUCCESS The SMMSTORE is supported. + +**/ +EFI_STATUS +SMMStoreInitialize ( + IN VOID *Ptr, + IN SMMSTORE_INFO *SmmStoreInfoHob + ) +{ + return EFI_UNSUPPORTED; +} From e1142bd99cbfb47dcc989096f8649b005b3f7d6a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:55:48 +0200 Subject: [PATCH 040/297] fix import --- UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h | 27 +++++++++++++++++++++++++++ UefiPayloadPkg/SPI/SMMStoreLib.h | 2 +- 2 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h diff --git a/UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h b/UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h new file mode 100644 index 000000000000..c28d90e00baf --- /dev/null +++ b/UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h @@ -0,0 +1,27 @@ +/** @file + This file defines the hob structure for system tables like ACPI, SMBIOS tables. + + Copyright (c) 2020, 9elements Agency GmbH
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SMMSTORE_GUID_H__ +#define __SMMSTORE_GUID_H__ + +/// +/// System Table Information GUID +/// +extern EFI_GUID gEfiSMMSTOREInfoHobGuid; + +typedef struct { + UINT64 ComBuffer; + UINT32 ComBufferSize; + UINT32 NumBlocks; + UINT32 BlockSize; + UINT64 MmioAddress; + UINT8 ApmCmd; + UINT8 Reserved0[3]; +} SMMSTORE_INFO; + +#endif diff --git a/UefiPayloadPkg/SPI/SMMStoreLib.h b/UefiPayloadPkg/SPI/SMMStoreLib.h index e6b7f0d9ef24..1a56ff238b26 100644 --- a/UefiPayloadPkg/SPI/SMMStoreLib.h +++ b/UefiPayloadPkg/SPI/SMMStoreLib.h @@ -11,7 +11,7 @@ #include #include -#include +#include #define SMMSTORE_COMBUF_SIZE 16 From b80ab5a2645f82526baa085aa93b56378e0868a6 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 08:58:31 +0200 Subject: [PATCH 041/297] fix import 2 --- UefiPayloadPkg/SPI/NvVarStoreFormatted.h | 33 ++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 UefiPayloadPkg/SPI/NvVarStoreFormatted.h diff --git a/UefiPayloadPkg/SPI/NvVarStoreFormatted.h b/UefiPayloadPkg/SPI/NvVarStoreFormatted.h new file mode 100644 index 000000000000..16eb90acc228 --- /dev/null +++ b/UefiPayloadPkg/SPI/NvVarStoreFormatted.h @@ -0,0 +1,33 @@ +/** @file + EDKII NvVarStore Formatted GUID + + A NULL protocol instance with this GUID in the DXE and/or MM protocol + databases, and/or a NULL PPI with this GUID in the PPI database, implies that + a DXE or MM driver, or a PEIM, has verified (or dynamically ensured) that the + non-volatile variable store has valid and consistent headers + (EFI_FIRMWARE_VOLUME_HEADER and VARIABLE_STORE_HEADER). + + Said predicate is required by the read-only variable PEIM, and the read side + of the runtime variable DXE and MM drivers, immediately after they are + dispatched. This GUID presents platforms with one way to coordinate between + their module(s) that format the variable store FVB device and the variable + service drivers. + + Copyright (C) 2018, Red Hat, Inc. + + SPDX-License-Identifier: BSD-2-Clause-Patent +**/ + + +#ifndef __EDKII_NV_VAR_STORE_FORMATTED_H__ +#define __EDKII_NV_VAR_STORE_FORMATTED_H__ + +#define EDKII_NV_VAR_STORE_FORMATTED_GUID \ + { \ + 0xd1a86e3f, 0x0707, 0x4c35, \ + { 0x83, 0xcd, 0xdc, 0x2c, 0x29, 0xc8, 0x91, 0xa3 } \ + } + +extern EFI_GUID gEdkiiNvVarStoreFormattedGuid; + +#endif From aafa81a3179813ee87cb01eee235e325fc6421d3 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 09:01:00 +0200 Subject: [PATCH 042/297] fix import 3 --- UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c index 2653f34741b7..d48fa4a789db 100644 --- a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c +++ b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c @@ -20,7 +20,7 @@ #include #include -#include +#include #include "BlSMMStoreDxe.h" From b77e77b1eb51907980df0b6d5ee21615adceea71 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 09:04:18 +0200 Subject: [PATCH 043/297] fix import 4 --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 118 +++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 UefiPayloadPkg/SPI/BlSMMStoreDxe.h diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h new file mode 100644 index 000000000000..92d937cc0c31 --- /dev/null +++ b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h @@ -0,0 +1,118 @@ +/** @file BlSMMStoreDxe.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __COREBOOT_SMM_STORE_DXE_H__ +#define __COREBOOT_SMM_STORE_DXE_H__ + + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) + +typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT8 Index; + EFI_DEVICE_PATH_PROTOCOL End; +} NOR_FLASH_DEVICE_PATH; +#pragma pack () + +struct _SMMSTORE_INSTANCE { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; + + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + + NOR_FLASH_DEVICE_PATH DevicePath; +}; + +// +// BlSMMStoreFvbDxe.c +// + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ); + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbWrite( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + + +#endif /* __COREBOOT_SMM_STORE_DXE_H__ */ From f7db32567546e5d5f5004b7f61b1fdaa6b117d25 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 09:08:11 +0200 Subject: [PATCH 044/297] Remove protocol definition --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 118 ---- UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c | 813 ----------------------- UefiPayloadPkg/SPI/NvVarStoreFormatted.h | 33 - UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h | 27 - UefiPayloadPkg/SPI/SMMStoreLib.h | 98 --- UefiPayloadPkg/SPI/SPI.c | 14 +- UefiPayloadPkg/SPI/SPI.inf | 2 - UefiPayloadPkg/SPI/SblSMMStore.c | 102 --- 8 files changed, 7 insertions(+), 1200 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/BlSMMStoreDxe.h delete mode 100644 UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c delete mode 100644 UefiPayloadPkg/SPI/NvVarStoreFormatted.h delete mode 100644 UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h delete mode 100644 UefiPayloadPkg/SPI/SMMStoreLib.h delete mode 100644 UefiPayloadPkg/SPI/SblSMMStore.c diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h deleted file mode 100644 index 92d937cc0c31..000000000000 --- a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h +++ /dev/null @@ -1,118 +0,0 @@ -/** @file BlSMMStoreDxe.h - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __COREBOOT_SMM_STORE_DXE_H__ -#define __COREBOOT_SMM_STORE_DXE_H__ - - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') -#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) - -typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; - -#pragma pack (1) -typedef struct { - VENDOR_DEVICE_PATH Vendor; - UINT8 Index; - EFI_DEVICE_PATH_PROTOCOL End; -} NOR_FLASH_DEVICE_PATH; -#pragma pack () - -struct _SMMSTORE_INSTANCE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_BLOCK_IO_MEDIA Media; - - EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; - - NOR_FLASH_DEVICE_PATH DevicePath; -}; - -// -// BlSMMStoreFvbDxe.c -// - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ); - -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbGetBlockSize( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbRead( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbWrite( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbEraseBlocks( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ); - - -#endif /* __COREBOOT_SMM_STORE_DXE_H__ */ diff --git a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c b/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c deleted file mode 100644 index d48fa4a789db..000000000000 --- a/UefiPayloadPkg/SPI/BlSMMStoreFvbDxe.c +++ /dev/null @@ -1,813 +0,0 @@ -/*++ @file BlSMMStoreFvbDxe.c - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - - --*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "BlSMMStoreDxe.h" - -STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; -STATIC UINTN mFlashNvStorageVariableBase; - -/// -/// The Firmware Volume Block Protocol is the low-level interface -/// to a firmware volume. File-level access to a firmware volume -/// should not be done using the Firmware Volume Block Protocol. -/// Normal access to a firmware volume must use the Firmware -/// Volume Protocol. Typically, only the file system driver that -/// produces the Firmware Volume Protocol will bind to the -/// Firmware Volume Block Protocol. -/// - -/** - Initialises the FV Header and Variable Store Header - to support variable operations. - - @param[in] Ptr - Location to initialise the headers - -**/ -EFI_STATUS -InitializeFvAndVariableStoreHeaders ( - IN SMMSTORE_INSTANCE *Instance - ) -{ - EFI_STATUS Status; - VOID* Headers; - UINTN HeadersLength; - EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - - HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); - Headers = AllocateZeroPool(HeadersLength); - - // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); - - // Check if the size of the area is at least one block size - ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); - - // Ensure the Variable area Base Addresses are aligned on a block size boundaries - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); - - // - // EFI_FIRMWARE_VOLUME_HEADER - // - FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; - CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); - FirmwareVolumeHeader->FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); - FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; - FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled - ); - FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); - FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; - FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; - FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; - FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; - FirmwareVolumeHeader->BlockMap[1].Length = 0; - FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); - - // - // VARIABLE_STORE_HEADER - // - VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); - CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); - VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; - VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; - - // Install the combined super-header in the store - Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); - - FreePool (Headers); - return Status; -} - -/** - Check the integrity of firmware volume header. - - @param[in] FwVolHeader - A pointer to a firmware volume header - - @retval EFI_SUCCESS - The firmware volume is consistent - @retval EFI_NOT_FOUND - The firmware volume has been corrupted. - -**/ -EFI_STATUS -ValidateFvHeader ( - IN SMMSTORE_INSTANCE *Instance - ) -{ - UINT16 Checksum; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - UINTN VariableStoreLength; - UINTN FvLength; - EFI_STATUS TempStatus; - UINTN BufferSize; - UINTN BufferSizeReqested; - - BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); - if (!FwVolHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (FwVolHeader); - return EFI_DEVICE_ERROR; - } - - FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); - - // - // Verify the header revision, header signature, length - // Length of FvBlock cannot be 2**64-1 - // HeaderLength cannot be an odd number - // - if ( (FwVolHeader->Revision != EFI_FVH_REVISION) - || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) - || (FwVolHeader->FvLength != FvLength) - ) - { - DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", - __FUNCTION__)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - // Check the Firmware Volume Guid - if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { - DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", - __FUNCTION__)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - BufferSizeReqested = FwVolHeader->HeaderLength; - FreePool (FwVolHeader); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); - if (!FwVolHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (FwVolHeader); - return EFI_DEVICE_ERROR; - } - - // Verify the header checksum - Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); - if (Checksum != 0) { - DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", - __FUNCTION__, Checksum)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); - VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); - if (!VariableStoreHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = SMMStoreRead (0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (VariableStoreHeader); - FreePool (FwVolHeader); - return EFI_DEVICE_ERROR; - } - - // Check the Variable Store Guid - if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && - !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { - DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", - __FUNCTION__)); - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); - return EFI_NOT_FOUND; - } - - VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; - if (VariableStoreHeader->Size != VariableStoreLength) { - DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", - __FUNCTION__)); - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); - return EFI_NOT_FOUND; - } - - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); - - return EFI_SUCCESS; -} - -/** - The GetAttributes() function retrieves the attributes and - current settings of the block. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and - current settings are returned. - Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - - **/ -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( - - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') - - ); - - // Check if it is write protected - if (Instance->Media.ReadOnly != TRUE) { - - FlashFvbAttributes = FlashFvbAttributes | - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled - } - - *Attributes = FlashFvbAttributes; - - DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); - - return EFI_SUCCESS; -} - -/** - The SetAttributes() function sets configurable firmware volume attributes - and returns the new settings of the firmware volume. - - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 - that contains the desired firmware volume settings. - On successful return, it contains the new settings of - the firmware volume. - Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - - @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities - as declared in the firmware volume header. - - **/ -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); - return EFI_UNSUPPORTED; -} - -/** - The GetPhysicalAddress() function retrieves the base address of - a memory-mapped firmware volume. This function should be called - only for memory-mapped firmware volumes. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Address Pointer to a caller-allocated - EFI_PHYSICAL_ADDRESS that, on successful - return from GetPhysicalAddress(), contains the - base address of the firmware volume. - - @retval EFI_SUCCESS The firmware volume base address was returned. - - @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. - - **/ -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - ASSERT(Address != NULL); - - *Address = mFlashNvStorageVariableBase; - return EFI_SUCCESS; -} - -/** - The GetBlockSize() function retrieves the size of the requested - block. It also returns the number of additional blocks with - the identical size. The GetBlockSize() function is used to - retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). - - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba Indicates the block for which to return the size. - - @param BlockSize Pointer to a caller-allocated UINTN in which - the size of the block is returned. - - @param NumberOfBlocks Pointer to a caller-allocated UINTN in - which the number of consecutive blocks, - starting with Lba, is returned. All - blocks in this range have a size of - BlockSize. - - - @retval EFI_SUCCESS The firmware volume base address was returned. - - @retval EFI_INVALID_PARAMETER The requested LBA is out of range. - - **/ -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ) -{ - EFI_STATUS Status; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock)); - - if (Lba > Instance->Media.LastBlock) { - DEBUG ((EFI_D_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock)); - Status = EFI_INVALID_PARAMETER; - } else { - *BlockSize = (UINTN) Instance->Media.BlockSize; - *NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1); - - DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks)); - - Status = EFI_SUCCESS; - } - - return Status; -} - -/** - Reads the specified number of bytes into a buffer from the specified block. - - The Read() function reads the requested number of bytes from the - requested block and stores them in the provided buffer. - Implementations should be mindful that the firmware volume - might be in the ReadDisabled state. If it is in this state, - the Read() function must return the status code - EFI_ACCESS_DENIED without modifying the contents of the - buffer. The Read() function must also prevent spanning block - boundaries. If a read is requested that would span a block - boundary, the read must read up to the boundary but not - beyond. The output parameter NumBytes must be set to correctly - indicate the number of bytes actually read. The caller must be - aware that a read may be partially completed. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba The starting logical block index from which to read. - - @param Offset Offset into the block at which to begin reading. - - @param NumBytes Pointer to a UINTN. - At entry, *NumBytes contains the total size of the buffer. - At exit, *NumBytes contains the total number of bytes read. - - @param Buffer Pointer to a caller-allocated buffer that will be used - to hold the data that is read. - - @retval EFI_SUCCESS The firmware volume was read successfully, and contents are - in Buffer. - - @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. - On output, NumBytes contains the total number of bytes - returned in Buffer. - - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. - - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. - - **/ -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ) -{ - UINTN BlockSize; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); - - // Cache the block size to avoid de-referencing pointers all the time - BlockSize = Instance->Media.BlockSize; - - DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - - // The read must not span block boundaries. - // We need to check each variable individually because adding two large values together overflows. - if ((Offset >= BlockSize) || - (*NumBytes > BlockSize) || - ((Offset + *NumBytes) > BlockSize)) { - DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - return EFI_BAD_BUFFER_SIZE; - } - - // We must have some bytes to read - if (*NumBytes == 0) { - return EFI_BAD_BUFFER_SIZE; - } - - return SMMStoreRead (Lba, Offset, NumBytes, Buffer); -} - -/** - Writes the specified number of bytes from the input buffer to the block. - - The Write() function writes the specified number of bytes from - the provided buffer to the specified block and offset. If the - firmware volume is sticky write, the caller must ensure that - all the bits of the specified range to write are in the - EFI_FVB_ERASE_POLARITY state before calling the Write() - function, or else the result will be unpredictable. This - unpredictability arises because, for a sticky-write firmware - volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY - state but cannot flip it back again. Before calling the - Write() function, it is recommended for the caller to first call - the EraseBlocks() function to erase the specified block to - write. A block erase cycle will transition bits from the - (NOT)EFI_FVB_ERASE_POLARITY state back to the - EFI_FVB_ERASE_POLARITY state. Implementations should be - mindful that the firmware volume might be in the WriteDisabled - state. If it is in this state, the Write() function must - return the status code EFI_ACCESS_DENIED without modifying the - contents of the firmware volume. The Write() function must - also prevent spanning block boundaries. If a write is - requested that spans a block boundary, the write must store up - to the boundary but not beyond. The output parameter NumBytes - must be set to correctly indicate the number of bytes actually - written. The caller must be aware that a write may be - partially completed. All writes, partial or otherwise, must be - fully flushed to the hardware before the Write() service - returns. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba The starting logical block index to write to. - - @param Offset Offset into the block at which to begin writing. - - @param NumBytes The pointer to a UINTN. - At entry, *NumBytes contains the total size of the buffer. - At exit, *NumBytes contains the total number of bytes actually written. - - @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully. - - @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. - On output, NumBytes contains the total number of bytes - actually written. - - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. - - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. - - - **/ -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - UINTN BlockSize; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); - - // Cache the block size to avoid de-referencing pointers all the time - BlockSize = Instance->Media.BlockSize; - - // The read must not span block boundaries. - // We need to check each variable individually because adding two large values together overflows. - if ((Offset >= BlockSize) || - (*NumBytes > BlockSize) || - ((Offset + *NumBytes) > BlockSize)) { - DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - return EFI_BAD_BUFFER_SIZE; - } - - // We must have some bytes to read - if (*NumBytes == 0) { - return EFI_BAD_BUFFER_SIZE; - } - - return SMMStoreWrite (Lba, Offset, NumBytes, Buffer); -} - -/** - Erases and initialises a firmware volume block. - - The EraseBlocks() function erases one or more blocks as denoted - by the variable argument list. The entire parameter list of - blocks must be verified before erasing any blocks. If a block is - requested that does not exist within the associated firmware - volume (it has a larger index than the last block of the - firmware volume), the EraseBlocks() function must return the - status code EFI_INVALID_PARAMETER without modifying the contents - of the firmware volume. Implementations should be mindful that - the firmware volume might be in the WriteDisabled state. If it - is in this state, the EraseBlocks() function must return the - status code EFI_ACCESS_DENIED without modifying the contents of - the firmware volume. All calls to EraseBlocks() must be fully - flushed to the hardware before the EraseBlocks() service - returns. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL - instance. - - @param ... The variable argument list is a list of tuples. - Each tuple describes a range of LBAs to erase - and consists of the following: - - An EFI_LBA that indicates the starting LBA - - A UINTN that indicates the number of blocks to erase. - - The list is terminated with an EFI_LBA_LIST_TERMINATOR. - For example, the following indicates that two ranges of blocks - (5-7 and 10-11) are to be erased: - EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); - - @retval EFI_SUCCESS The erase request successfully completed. - - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. - - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. - The firmware device may have been partially erased. - - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do - not exist in the firmware volume. - - **/ -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ) -{ - EFI_STATUS Status; - VA_LIST Args; - EFI_LBA StartingLba; // Lba from which we start erasing - UINTN NumOfLba; // Number of Lba blocks to erase - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks()\n")); - - Status = EFI_SUCCESS; - - // Detect WriteDisabled state - if (Instance->Media.ReadOnly == TRUE) { - // Firmware volume is in WriteDisabled state - DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n")); - return EFI_ACCESS_DENIED; - } - - // Before erasing, check the entire list of parameters to ensure all specified blocks are valid - - VA_START (Args, This); - do { - // Get the Lba from which we start erasing - StartingLba = VA_ARG (Args, EFI_LBA); - - // Have we reached the end of the list? - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - //Exit the while loop - break; - } - - // How many Lba blocks are we requested to erase? - NumOfLba = VA_ARG (Args, UINTN); - - // All blocks must be within range - DEBUG (( - DEBUG_BLKIO, - "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n", - StartingLba, - (UINT64)NumOfLba, - Instance->Media.LastBlock - )); - if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { - VA_END (Args); - DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n")); - Status = EFI_INVALID_PARAMETER; - goto EXIT; - } - } while (TRUE); - VA_END (Args); - - // - // To get here, all must be ok, so start erasing - // - VA_START (Args, This); - do { - // Get the Lba from which we start erasing - StartingLba = VA_ARG (Args, EFI_LBA); - - // Have we reached the end of the list? - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - // Exit the while loop - break; - } - - // How many Lba blocks are we requested to erase? - NumOfLba = VA_ARG (Args, UINTN); - - // Go through each one and erase it - while (NumOfLba > 0) { - // Erase it - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba)); - Status = SMMStoreEraseBlock (StartingLba); - if (EFI_ERROR(Status)) { - VA_END (Args); - Status = EFI_DEVICE_ERROR; - goto EXIT; - } - - // Move to the next Lba - StartingLba++; - NumOfLba--; - } - } while (TRUE); - VA_END (Args); - -EXIT: - return Status; -} - -/** - Fixup internal data so that EFI can be call in virtual mode. - Call the passed in Child Notify event and convert any pointers in - lib to virtual mode. - - @param[in] Event The Event that is being processed - @param[in] Context Event Context -**/ -VOID -EFIAPI -FvbVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); - return; -} - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ) -{ - EFI_STATUS Status; - UINT32 FvbNumLba; - EFI_BOOT_MODE BootMode; - - DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); - ASSERT((Instance != NULL)); - - mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); - - BootMode = GetBootModeHob (); - if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { - Status = EFI_INVALID_PARAMETER; - } else { - // Determine if there is a valid header at the beginning of the NorFlash - Status = ValidateFvHeader (Instance); - } - - // Install the Default FVB header if required - if (EFI_ERROR(Status)) { - // There is no valid header, so time to install one. - DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); - DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", - __FUNCTION__)); - - // Erase all the NorFlash that is reserved for variable storage - FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; - - Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); - if (EFI_ERROR(Status)) { - return Status; - } - - // Install all appropriate headers - Status = InitializeFvAndVariableStoreHeaders (Instance); - if (EFI_ERROR(Status)) { - return Status; - } - } else { - DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); - } - - // - // The driver implementing the variable read service can now be dispatched; - // the varstore headers are in place. - // - Status = gBS->InstallProtocolInterface ( - &gImageHandle, - &gEdkiiNvVarStoreFormattedGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Register for the virtual address change event - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - FvbVirtualNotifyEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - &mFvbVirtualAddrChangeEvent - ); - ASSERT_EFI_ERROR (Status); - - return Status; -} diff --git a/UefiPayloadPkg/SPI/NvVarStoreFormatted.h b/UefiPayloadPkg/SPI/NvVarStoreFormatted.h deleted file mode 100644 index 16eb90acc228..000000000000 --- a/UefiPayloadPkg/SPI/NvVarStoreFormatted.h +++ /dev/null @@ -1,33 +0,0 @@ -/** @file - EDKII NvVarStore Formatted GUID - - A NULL protocol instance with this GUID in the DXE and/or MM protocol - databases, and/or a NULL PPI with this GUID in the PPI database, implies that - a DXE or MM driver, or a PEIM, has verified (or dynamically ensured) that the - non-volatile variable store has valid and consistent headers - (EFI_FIRMWARE_VOLUME_HEADER and VARIABLE_STORE_HEADER). - - Said predicate is required by the read-only variable PEIM, and the read side - of the runtime variable DXE and MM drivers, immediately after they are - dispatched. This GUID presents platforms with one way to coordinate between - their module(s) that format the variable store FVB device and the variable - service drivers. - - Copyright (C) 2018, Red Hat, Inc. - - SPDX-License-Identifier: BSD-2-Clause-Patent -**/ - - -#ifndef __EDKII_NV_VAR_STORE_FORMATTED_H__ -#define __EDKII_NV_VAR_STORE_FORMATTED_H__ - -#define EDKII_NV_VAR_STORE_FORMATTED_GUID \ - { \ - 0xd1a86e3f, 0x0707, 0x4c35, \ - { 0x83, 0xcd, 0xdc, 0x2c, 0x29, 0xc8, 0x91, 0xa3 } \ - } - -extern EFI_GUID gEdkiiNvVarStoreFormattedGuid; - -#endif diff --git a/UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h b/UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h deleted file mode 100644 index c28d90e00baf..000000000000 --- a/UefiPayloadPkg/SPI/SMMSTOREInfoGuid.h +++ /dev/null @@ -1,27 +0,0 @@ -/** @file - This file defines the hob structure for system tables like ACPI, SMBIOS tables. - - Copyright (c) 2020, 9elements Agency GmbH
- SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __SMMSTORE_GUID_H__ -#define __SMMSTORE_GUID_H__ - -/// -/// System Table Information GUID -/// -extern EFI_GUID gEfiSMMSTOREInfoHobGuid; - -typedef struct { - UINT64 ComBuffer; - UINT32 ComBufferSize; - UINT32 NumBlocks; - UINT32 BlockSize; - UINT64 MmioAddress; - UINT8 ApmCmd; - UINT8 Reserved0[3]; -} SMMSTORE_INFO; - -#endif diff --git a/UefiPayloadPkg/SPI/SMMStoreLib.h b/UefiPayloadPkg/SPI/SMMStoreLib.h deleted file mode 100644 index 1a56ff238b26..000000000000 --- a/UefiPayloadPkg/SPI/SMMStoreLib.h +++ /dev/null @@ -1,98 +0,0 @@ -/** @file SMMStoreLib.h - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __SMM_STORE_LIB_H__ -#define __SMM_STORE_LIB_H__ - -#include -#include -#include - -#define SMMSTORE_COMBUF_SIZE 16 - -/** - Read from SMMStore - - @param[in] Lba The starting logical block index to read from. - @param[in] Offset Offset into the block at which to begin reading. - @param[in] NumBytes On input, indicates the requested read size. On - output, indicates the actual number of bytes read - @param[in] Buffer Pointer to the buffer to read into. - -**/ -EFI_STATUS -SMMStoreRead ( - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN UINT8 *Buffer - ); - - -/** - Write to SMMStore - - @param[in] Lba The starting logical block index to write to. - @param[in] Offset Offset into the block at which to begin writing. - @param[in] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Pointer to the data to write. - -**/ -EFI_STATUS -SMMStoreWrite ( - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN UINT8 *Buffer - ); - - -/** - Erase a block using the SMMStore - - @param Lba The logical block index to erase. - -**/ -EFI_STATUS -SMMStoreEraseBlock ( - IN EFI_LBA Lba - ); - - -/** - Notify the SMMStore Library about a VirtualNotify - -**/ - -VOID -EFIAPI -SMMStoreVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Initializes SMMStore support - - @param[in] Ptr A runtime buffer where arguments are stored - for SMM communication - @param[in] SmmStoreInfoHob A runtime buffer with a copy of the - SmmStore Info Hob - - @retval EFI_WRITE_PROTECTED The SMMSTORE is not present. - @retval EFI_SUCCESS The SMMSTORE is supported. - -**/ -EFI_STATUS -SMMStoreInitialize ( - IN VOID *Ptr, - IN SMMSTORE_INFO *SmmStoreInfoHob - ); - -#endif /* __SMM_STORE_LIB_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index f8929cdf92a2..7308b442ee4b 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,13 +13,13 @@ #include "SPI.h" EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks + NULL, // GetAttributes + NULL, // SetAttributes + NULL, // GetPhysicalAddress + NULL, // GetBlockSize + NULL, // Read + NULL, // Write + NULL, // EraseBlocks NULL, //ParentHandle }; diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 7915d0c1e860..0b05bc40d5db 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,8 +18,6 @@ [Sources] SPI.h SPI.c - BlSMMStoreFvbDxe.c - SblSMMStore.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SblSMMStore.c b/UefiPayloadPkg/SPI/SblSMMStore.c deleted file mode 100644 index 61dfb86117ec..000000000000 --- a/UefiPayloadPkg/SPI/SblSMMStore.c +++ /dev/null @@ -1,102 +0,0 @@ -/** @file CorebootSMMStoreDxe.c - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ -#include - -#include -#include -#include -#include - -/** - Read from SMMStore - - @param[in] Lba The starting logical block index to read from. - @param[in] Offset Offset into the block at which to begin reading. - @param[in] NumBytes On input, indicates the requested read size. On - output, indicates the actual number of bytes read - @param[in] Buffer Pointer to the buffer to read into. - -**/ -EFI_STATUS -SMMStoreRead ( - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - - -/** - Write to SMMStore - - @param[in] Lba The starting logical block index to write to. - @param[in] Offset Offset into the block at which to begin writing. - @param[in] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Pointer to the data to write. - -**/ -EFI_STATUS -SMMStoreWrite ( - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - return EFI_UNSUPPORTED; -} - - -/** - Erase a SMMStore block - - @param Lba The logical block index to erase. - -**/ -EFI_STATUS -SMMStoreEraseBlock ( - IN EFI_LBA Lba - ) -{ - return EFI_UNSUPPORTED; -} - -VOID -EFIAPI -SMMStoreVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - return; -} - -/** - Initializes SMMStore support - - @param[in] Ptr A runtime buffer where arguments are stored - for SMM communication - @param[in] SmmStoreInfoHob A runtime buffer with a copy of the - SmmStore Info Hob - - @retval EFI_WRITE_PROTECTED The SMMSTORE is not present. - @retval EFI_SUCCESS The SMMSTORE is supported. - -**/ -EFI_STATUS -SMMStoreInitialize ( - IN VOID *Ptr, - IN SMMSTORE_INFO *SmmStoreInfoHob - ) -{ - return EFI_UNSUPPORTED; -} From 8307c9d3777e5b60ca4d98ab923e7e66bd7ee0c0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 09:14:15 +0200 Subject: [PATCH 045/297] info if protocol successfull --- UefiPayloadPkg/SPI/SPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 7308b442ee4b..6f47b4c8a41a 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -40,6 +40,8 @@ SPIInitialize ( if(EFI_ERROR (Status)) { DEBUG(( EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + } else { + EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } return EFI_SUCCESS; } From 8b4482fae75c2906c185dc9dc0d7e6a4806dec52 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 09:21:20 +0200 Subject: [PATCH 046/297] typo --- UefiPayloadPkg/SPI/SPI.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 6f47b4c8a41a..10ed64c8284a 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -41,7 +41,8 @@ SPIInitialize ( DEBUG(( EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { - EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); + DEBUG(( + EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } return EFI_SUCCESS; } From a6b02b9795c0f8004540a1dca59d5b4122110b18 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 09:55:25 +0200 Subject: [PATCH 047/297] fix protocol install --- UefiPayloadPkg/SPI/SPI.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 10ed64c8284a..aa3aeedb2fb2 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -15,9 +15,9 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, // GetAttributes NULL, // SetAttributes - NULL, // GetPhysicalAddress - NULL, // GetBlockSize - NULL, // Read + NULL, // GetPhysicalAddress + NULL, // GetBlockSize + NULL, // Read NULL, // Write NULL, // EraseBlocks NULL, //ParentHandle @@ -31,12 +31,17 @@ SPIInitialize ( ) { EFI_STATUS Status; - Status = gBS->InstallProtocolInterface( - ImageHandle, - &gEfiDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - &FvbProtocol); + // Status = gBS->InstallProtocolInterface( + // ImageHandle, + // &gEfiDevicePathProtocolGuid, + // EFI_NATIVE_INTERFACE, + // &FvbProtocol); DEBUG((EFI_D_INFO, "SPI\n")); + Status = gBS->InstallMultipleProtocolInterfaces ( + NULL, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); if(EFI_ERROR (Status)) { DEBUG(( EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); From 2d816fc76c5c0a5ecf1b8c5f0f039ee63310e80c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:01:13 +0200 Subject: [PATCH 048/297] add handle --- UefiPayloadPkg/SPI/SPI.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index aa3aeedb2fb2..9fcf23d87786 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -23,9 +23,9 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; -EFI_STATUS -EFIAPI -SPIInitialize ( +EFI_HANDLE Handle; + +EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) @@ -38,7 +38,7 @@ SPIInitialize ( // &FvbProtocol); DEBUG((EFI_D_INFO, "SPI\n")); Status = gBS->InstallMultipleProtocolInterfaces ( - NULL, + &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, NULL ); From 514fadd1840fae69c74f44a975b348124d658ecc Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:09:13 +0200 Subject: [PATCH 049/297] edd extern guid --- UefiPayloadPkg/SPI/SPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 9fcf23d87786..5a8276a75b5e 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -23,6 +23,8 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; +extern EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid; + EFI_HANDLE Handle; EFI_STATUS EFIAPI SPIInitialize ( From 17a2730f9f6c536e8f5d81d41282c0eaf3a71fdf Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:17:53 +0200 Subject: [PATCH 050/297] Add libraries --- UefiPayloadPkg/SPI/SPI.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 5a8276a75b5e..2b2464dcc5b8 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -6,6 +6,15 @@ **/ +#include +#include +#include +#include +#include +#include +#include +#include + #include #include #include @@ -23,8 +32,6 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; -extern EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid; - EFI_HANDLE Handle; EFI_STATUS EFIAPI SPIInitialize ( From 523c1c260954b97f9ad17ee72a332251d41e3589 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:20:20 +0200 Subject: [PATCH 051/297] fix include --- UefiPayloadPkg/SPI/SPI.c | 1 - 1 file changed, 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 2b2464dcc5b8..d72623068637 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include From 6a20222287252f5a1d210844ea08db7333af6c5c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:22:46 +0200 Subject: [PATCH 052/297] replace guid with NULL --- UefiPayloadPkg/SPI/SPI.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index d72623068637..68d7dd3d40bf 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -6,14 +6,6 @@ **/ -#include -#include -#include -#include -#include -#include -#include - #include #include #include @@ -47,7 +39,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI\n")); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL /*&gEfiFirmwareVolumeBlockProtocolGuid*/, &FvbProtocol, NULL ); if(EFI_ERROR (Status)) { From 3a683ef79a4fc36bec84c646f878481b6be9dbbd Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:24:38 +0200 Subject: [PATCH 053/297] fix guid --- UefiPayloadPkg/SPI/SPI.c | 2 +- UefiPayloadPkg/SPI/SPI.inf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 68d7dd3d40bf..9fcf23d87786 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -39,7 +39,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI\n")); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, - NULL /*&gEfiFirmwareVolumeBlockProtocolGuid*/, &FvbProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, NULL ); if(EFI_ERROR (Status)) { diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 0b05bc40d5db..75b971488bd4 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -29,7 +29,7 @@ BaseMemoryLib [Protocols] - gEfiSmbusHcProtocolGuid ## PRODUCES + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES [Depex] TRUE From 3dd073798aaef871f597a0c7e022d3acc4a79cd4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:40:50 +0200 Subject: [PATCH 054/297] fix not initialized var --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 9fcf23d87786..63f8b6b0919c 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -23,7 +23,7 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; -EFI_HANDLE Handle; +EFI_HANDLE Handle = NULL; EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, From cb953a0d5747bf7de8f9c6d546f90617244247fe Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 10:57:55 +0200 Subject: [PATCH 055/297] change log --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 63f8b6b0919c..8db4ed35663e 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -36,7 +36,7 @@ EFI_STATUS EFIAPI SPIInitialize ( // &gEfiDevicePathProtocolGuid, // EFI_NATIVE_INTERFACE, // &FvbProtocol); - DEBUG((EFI_D_INFO, "SPI\n")); + DEBUG((EFI_D_INFO, "SPI IS HERE\n")); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, From 9f8b4a4d41542827097eab3dfe78c92c2ce43492 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 11:07:56 +0200 Subject: [PATCH 056/297] protocol is null --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 8db4ed35663e..d4fa8006835d 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -39,7 +39,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + &gEfiFirmwareVolumeBlockProtocolGuid, NULL, NULL ); if(EFI_ERROR (Status)) { From 2a824603bce8316724d7727ed18167f7c8a829a5 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 11:44:15 +0200 Subject: [PATCH 057/297] Add Fvb --- UefiPayloadPkg/SPI/SPI.c | 19 +- UefiPayloadPkg/SPI/SPI.inf | 1 + UefiPayloadPkg/SPI/SPIFvb.c | 813 ++++++++++++++++++++++++++++++++++++ 3 files changed, 823 insertions(+), 10 deletions(-) create mode 100644 UefiPayloadPkg/SPI/SPIFvb.c diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index d4fa8006835d..827180c29ad2 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -12,19 +12,18 @@ #include #include "SPI.h" +EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - NULL, // GetAttributes - NULL, // SetAttributes - NULL, // GetPhysicalAddress - NULL, // GetBlockSize - NULL, // Read - NULL, // Write - NULL, // EraseBlocks + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }; -EFI_HANDLE Handle = NULL; - EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -39,7 +38,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, NULL, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, NULL ); if(EFI_ERROR (Status)) { diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 75b971488bd4..210c8c186c4c 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,6 +18,7 @@ [Sources] SPI.h SPI.c + SPIFvb.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c new file mode 100644 index 000000000000..1ed3fc4b754a --- /dev/null +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -0,0 +1,813 @@ +/*++ @file BlSMMStoreFvbDxe.c + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + --*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "SPI.h" + +STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; +STATIC UINTN mFlashNvStorageVariableBase; + +/// +/// The Firmware Volume Block Protocol is the low-level interface +/// to a firmware volume. File-level access to a firmware volume +/// should not be done using the Firmware Volume Block Protocol. +/// Normal access to a firmware volume must use the Firmware +/// Volume Protocol. Typically, only the file system driver that +/// produces the Firmware Volume Protocol will bind to the +/// Firmware Volume Block Protocol. +/// + +/** + Initialises the FV Header and Variable Store Header + to support variable operations. + + @param[in] Ptr - Location to initialise the headers + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN SMMSTORE_INSTANCE *Instance + ) +{ + EFI_STATUS Status; + VOID* Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); + Headers = AllocateZeroPool(HeadersLength); + + // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + + // Check if the size of the area is at least one block size + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); + + // Ensure the Variable area Base Addresses are aligned on a block size boundaries + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + + // + // EFI_FIRMWARE_VOLUME_HEADER + // + FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; + CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); + FirmwareVolumeHeader->FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; + FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled + ); + FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); + FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; + FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; + FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; + FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; + FirmwareVolumeHeader->BlockMap[1].Length = 0; + FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); + + // + // VARIABLE_STORE_HEADER + // + VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); + CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; + VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; + VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; + + // Install the combined super-header in the store + Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); + + FreePool (Headers); + return Status; +} + +/** + Check the integrity of firmware volume header. + + @param[in] FwVolHeader - A pointer to a firmware volume header + + @retval EFI_SUCCESS - The firmware volume is consistent + @retval EFI_NOT_FOUND - The firmware volume has been corrupted. + +**/ +EFI_STATUS +ValidateFvHeader ( + IN SMMSTORE_INSTANCE *Instance + ) +{ + UINT16 Checksum; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINTN VariableStoreLength; + UINTN FvLength; + EFI_STATUS TempStatus; + UINTN BufferSize; + UINTN BufferSizeReqested; + + BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ( (FwVolHeader->Revision != EFI_FVH_REVISION) + || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength != FvLength) + ) + { + DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", + __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + // Check the Firmware Volume Guid + if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { + DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = FwVolHeader->HeaderLength; + FreePool (FwVolHeader); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + // Verify the header checksum + Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); + if (Checksum != 0) { + DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", + __FUNCTION__, Checksum)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); + VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); + if (!VariableStoreHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = SMMStoreRead (0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (VariableStoreHeader); + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + // Check the Variable Store Guid + if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && + !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; + if (VariableStoreHeader->Size != VariableStoreLength) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + + return EFI_SUCCESS; +} + +/** + The GetAttributes() function retrieves the attributes and + current settings of the block. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and + current settings are returned. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + **/ +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( + + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') + + ); + + // Check if it is write protected + if (Instance->Media.ReadOnly != TRUE) { + + FlashFvbAttributes = FlashFvbAttributes | + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled + } + + *Attributes = FlashFvbAttributes; + + DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); + + return EFI_SUCCESS; +} + +/** + The SetAttributes() function sets configurable firmware volume attributes + and returns the new settings of the firmware volume. + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 + that contains the desired firmware volume settings. + On successful return, it contains the new settings of + the firmware volume. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities + as declared in the firmware volume header. + + **/ +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); + return EFI_UNSUPPORTED; +} + +/** + The GetPhysicalAddress() function retrieves the base address of + a memory-mapped firmware volume. This function should be called + only for memory-mapped firmware volumes. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), contains the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. + + **/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + ASSERT(Address != NULL); + + *Address = mFlashNvStorageVariableBase; + return EFI_SUCCESS; +} + +/** + The GetBlockSize() function retrieves the size of the requested + block. It also returns the number of additional blocks with + the identical size. The GetBlockSize() function is used to + retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba Indicates the block for which to return the size. + + @param BlockSize Pointer to a caller-allocated UINTN in which + the size of the block is returned. + + @param NumberOfBlocks Pointer to a caller-allocated UINTN in + which the number of consecutive blocks, + starting with Lba, is returned. All + blocks in this range have a size of + BlockSize. + + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + + **/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ) +{ + EFI_STATUS Status; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock)); + + if (Lba > Instance->Media.LastBlock) { + DEBUG ((EFI_D_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock)); + Status = EFI_INVALID_PARAMETER; + } else { + *BlockSize = (UINTN) Instance->Media.BlockSize; + *NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1); + + DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks)); + + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + Reads the specified number of bytes into a buffer from the specified block. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + Implementations should be mindful that the firmware volume + might be in the ReadDisabled state. If it is in this state, + the Read() function must return the status code + EFI_ACCESS_DENIED without modifying the contents of the + buffer. The Read() function must also prevent spanning block + boundaries. If a read is requested that would span a block + boundary, the read must read up to the boundary but not + beyond. The output parameter NumBytes must be set to correctly + indicate the number of bytes actually read. The caller must be + aware that a read may be partially completed. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index from which to read. + + @param Offset Offset into the block at which to begin reading. + + @param NumBytes Pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes read. + + @param Buffer Pointer to a caller-allocated buffer that will be used + to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read successfully, and contents are + in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + returned in Buffer. + + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. + + **/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ) +{ + UINTN BlockSize; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return SMMStoreRead (Lba, Offset, NumBytes, Buffer); +} + +/** + Writes the specified number of bytes from the input buffer to the block. + + The Write() function writes the specified number of bytes from + the provided buffer to the specified block and offset. If the + firmware volume is sticky write, the caller must ensure that + all the bits of the specified range to write are in the + EFI_FVB_ERASE_POLARITY state before calling the Write() + function, or else the result will be unpredictable. This + unpredictability arises because, for a sticky-write firmware + volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY + state but cannot flip it back again. Before calling the + Write() function, it is recommended for the caller to first call + the EraseBlocks() function to erase the specified block to + write. A block erase cycle will transition bits from the + (NOT)EFI_FVB_ERASE_POLARITY state back to the + EFI_FVB_ERASE_POLARITY state. Implementations should be + mindful that the firmware volume might be in the WriteDisabled + state. If it is in this state, the Write() function must + return the status code EFI_ACCESS_DENIED without modifying the + contents of the firmware volume. The Write() function must + also prevent spanning block boundaries. If a write is + requested that spans a block boundary, the write must store up + to the boundary but not beyond. The output parameter NumBytes + must be set to correctly indicate the number of bytes actually + written. The caller must be aware that a write may be + partially completed. All writes, partial or otherwise, must be + fully flushed to the hardware before the Write() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index to write to. + + @param Offset Offset into the block at which to begin writing. + + @param NumBytes The pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes actually written. + + @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully. + + @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + actually written. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. + + + **/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINTN BlockSize; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return SMMStoreWrite (Lba, Offset, NumBytes, Buffer); +} + +/** + Erases and initialises a firmware volume block. + + The EraseBlocks() function erases one or more blocks as denoted + by the variable argument list. The entire parameter list of + blocks must be verified before erasing any blocks. If a block is + requested that does not exist within the associated firmware + volume (it has a larger index than the last block of the + firmware volume), the EraseBlocks() function must return the + status code EFI_INVALID_PARAMETER without modifying the contents + of the firmware volume. Implementations should be mindful that + the firmware volume might be in the WriteDisabled state. If it + is in this state, the EraseBlocks() function must return the + status code EFI_ACCESS_DENIED without modifying the contents of + the firmware volume. All calls to EraseBlocks() must be fully + flushed to the hardware before the EraseBlocks() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + instance. + + @param ... The variable argument list is a list of tuples. + Each tuple describes a range of LBAs to erase + and consists of the following: + - An EFI_LBA that indicates the starting LBA + - A UINTN that indicates the number of blocks to erase. + + The list is terminated with an EFI_LBA_LIST_TERMINATOR. + For example, the following indicates that two ranges of blocks + (5-7 and 10-11) are to be erased: + EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); + + @retval EFI_SUCCESS The erase request successfully completed. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. + The firmware device may have been partially erased. + + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do + not exist in the firmware volume. + + **/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ) +{ + EFI_STATUS Status; + VA_LIST Args; + EFI_LBA StartingLba; // Lba from which we start erasing + UINTN NumOfLba; // Number of Lba blocks to erase + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks()\n")); + + Status = EFI_SUCCESS; + + // Detect WriteDisabled state + if (Instance->Media.ReadOnly == TRUE) { + // Firmware volume is in WriteDisabled state + DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n")); + return EFI_ACCESS_DENIED; + } + + // Before erasing, check the entire list of parameters to ensure all specified blocks are valid + + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba = VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + //Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba = VA_ARG (Args, UINTN); + + // All blocks must be within range + DEBUG (( + DEBUG_BLKIO, + "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n", + StartingLba, + (UINT64)NumOfLba, + Instance->Media.LastBlock + )); + if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { + VA_END (Args); + DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n")); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } while (TRUE); + VA_END (Args); + + // + // To get here, all must be ok, so start erasing + // + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba = VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + // Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba = VA_ARG (Args, UINTN); + + // Go through each one and erase it + while (NumOfLba > 0) { + // Erase it + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba)); + Status = SMMStoreEraseBlock (StartingLba); + if (EFI_ERROR(Status)) { + VA_END (Args); + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // Move to the next Lba + StartingLba++; + NumOfLba--; + } + } while (TRUE); + VA_END (Args); + +EXIT: + return Status; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +FvbVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); + return; +} + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ) +{ + EFI_STATUS Status; + UINT32 FvbNumLba; + EFI_BOOT_MODE BootMode; + + DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); + ASSERT((Instance != NULL)); + + mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); + + BootMode = GetBootModeHob (); + if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { + Status = EFI_INVALID_PARAMETER; + } else { + // Determine if there is a valid header at the beginning of the NorFlash + Status = ValidateFvHeader (Instance); + } + + // Install the Default FVB header if required + if (EFI_ERROR(Status)) { + // There is no valid header, so time to install one. + DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); + DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", + __FUNCTION__)); + + // Erase all the NorFlash that is reserved for variable storage + FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; + + Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); + if (EFI_ERROR(Status)) { + return Status; + } + + // Install all appropriate headers + Status = InitializeFvAndVariableStoreHeaders (Instance); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); + } + + // + // The driver implementing the variable read service can now be dispatched; + // the varstore headers are in place. + // + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mFvbVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} From 27c3decac7a457e98f9fd03e85b12479b0fd91d0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 11:55:26 +0200 Subject: [PATCH 058/297] add pkg --- UefiPayloadPkg/SPI/SPI.inf | 2 ++ UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 210c8c186c4c..819ca156f2be 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -23,6 +23,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec [LibraryClasses] UefiDriverEntryPoint @@ -31,6 +32,7 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEdkiiNvVarStoreFormattedGuid [Depex] TRUE diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 1ed3fc4b754a..d8906ecbb5fb 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -16,7 +16,7 @@ #include #include #include -#include +// #include #include #include From c1b8b4c18c5cab9f728bcc2c1f45f1eff09a5f66 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:00:45 +0200 Subject: [PATCH 059/297] move to to guids --- UefiPayloadPkg/SPI/SPI.inf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 819ca156f2be..04b75ed5e962 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -30,9 +30,11 @@ DebugLib BaseMemoryLib +[Guids] + gEdkiiNvVarStoreFormattedGuid + [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES - gEdkiiNvVarStoreFormattedGuid [Depex] TRUE From 49fc4e7e71f71e77e317145d01a9a340272c52ef Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:10:56 +0200 Subject: [PATCH 060/297] add libs --- UefiPayloadPkg/SPI/SPI.inf | 9 +++++++++ UefiPayloadPkg/SPI/SPIFvb.c | 9 +++------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 04b75ed5e962..a5a2d4a0b85f 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -36,5 +36,14 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + [Depex] TRUE diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index d8906ecbb5fb..fd1b3db1fa3a 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -16,7 +16,8 @@ #include #include #include -// #include +#include +#include #include #include @@ -59,11 +60,7 @@ InitializeFvAndVariableStoreHeaders ( Headers = AllocateZeroPool(HeadersLength); // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); - - // Check if the size of the area is at least one block size - ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); From 7ac00cd986b2006706df9005a6c4d8b344781c83 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:14:10 +0200 Subject: [PATCH 061/297] add deps --- UefiPayloadPkg/SPI/SPI.inf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index a5a2d4a0b85f..91aecf3f79f4 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -29,9 +29,11 @@ UefiDriverEntryPoint DebugLib BaseMemoryLib + SmmStoreLib [Guids] gEdkiiNvVarStoreFormattedGuid + gEfiSMMSTOREInfoHobGuid [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES From f65497ddb06af165148156c0ccec93b56ca00129 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:16:04 +0200 Subject: [PATCH 062/297] remove guid --- UefiPayloadPkg/SPI/SPI.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 91aecf3f79f4..b6e52f5a90c1 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -33,7 +33,7 @@ [Guids] gEdkiiNvVarStoreFormattedGuid - gEfiSMMSTOREInfoHobGuid + # gEfiSMMSTOREInfoHobGuid [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES From e488cc4d66ba41003d6a617494ac35857f1288f1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:24:13 +0200 Subject: [PATCH 063/297] remove SMMStoreLib --- UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index fd1b3db1fa3a..2a20ab71248c 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -16,7 +16,7 @@ #include #include #include -#include +// #include #include #include From 46db81b800f795ac01540c722bbe9a6b6f74e16d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:28:00 +0200 Subject: [PATCH 064/297] comment out asserts --- UefiPayloadPkg/SPI/SPIFvb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 2a20ab71248c..206f6cfeaeb6 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -60,14 +60,14 @@ InitializeFvAndVariableStoreHeaders ( Headers = AllocateZeroPool(HeadersLength); // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + /*ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); // Ensure the Variable area Base Addresses are aligned on a block size boundaries ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0);*/ // // EFI_FIRMWARE_VOLUME_HEADER From 3c9d0324c193e3070f0b77eb2232e2ae5d1986f2 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:32:04 +0200 Subject: [PATCH 065/297] copy some definitions --- UefiPayloadPkg/SPI/SPI.h | 100 ++++++++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 2 files changed, 101 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 14ac5912e34b..64f31288dc23 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -114,5 +114,105 @@ FvbEraseBlocks( ... ); +/** @file SMMStoreLib.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SMM_STORE_LIB_H__ +#define __SMM_STORE_LIB_H__ + +#include +#include +#include + +#define SMMSTORE_COMBUF_SIZE 16 + +/** + Read from SMMStore + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +SMMStoreRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Write to SMMStore + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +SMMStoreWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Erase a block using the SMMStore + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +SMMStoreEraseBlock ( + IN EFI_LBA Lba + ); + + +/** + Notify the SMMStore Library about a VirtualNotify + +**/ + +VOID +EFIAPI +SMMStoreVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Initializes SMMStore support + + @param[in] Ptr A runtime buffer where arguments are stored + for SMM communication + @param[in] SmmStoreInfoHob A runtime buffer with a copy of the + SmmStore Info Hob + + @retval EFI_WRITE_PROTECTED The SMMSTORE is not present. + @retval EFI_SUCCESS The SMMSTORE is supported. + +**/ +EFI_STATUS +SMMStoreInitialize ( + IN VOID *Ptr, + IN SMMSTORE_INFO *SmmStoreInfoHob + ); + +#endif /* __SMM_STORE_LIB_H__ */ + + #endif /* __SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 206f6cfeaeb6..382cef85f8e6 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -136,7 +136,7 @@ ValidateFvHeader ( UINTN BufferSizeReqested; BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEAD`ER*)AllocatePool(BufferSizeReqested); if (!FwVolHeader) { return EFI_OUT_OF_RESOURCES; } From 179cfe10a746769b54f59dc9fa6b74b6eeadca49 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:38:26 +0200 Subject: [PATCH 066/297] fix --- UefiPayloadPkg/SPI/SPI.h | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 64f31288dc23..8a4a6372ebba 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -114,21 +114,6 @@ FvbEraseBlocks( ... ); -/** @file SMMStoreLib.h - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __SMM_STORE_LIB_H__ -#define __SMM_STORE_LIB_H__ - -#include -#include -#include - #define SMMSTORE_COMBUF_SIZE 16 /** @@ -205,14 +190,22 @@ SMMStoreVirtualNotifyEvent ( @retval EFI_SUCCESS The SMMSTORE is supported. **/ + +typedef struct { + UINT64 ComBuffer; + UINT32 ComBufferSize; + UINT32 NumBlocks; + UINT32 BlockSize; + UINT64 MmioAddress; + UINT8 ApmCmd; + UINT8 Reserved0[3]; +} SMMSTORE_INFO; + EFI_STATUS SMMStoreInitialize ( IN VOID *Ptr, IN SMMSTORE_INFO *SmmStoreInfoHob ); -#endif /* __SMM_STORE_LIB_H__ */ - - #endif /* __SPI_H__ */ From 6abaff5d534860eb5571ff8cedda054fb4c76737 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 12:41:14 +0200 Subject: [PATCH 067/297] fix typo --- UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 382cef85f8e6..206f6cfeaeb6 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -136,7 +136,7 @@ ValidateFvHeader ( UINTN BufferSizeReqested; BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEAD`ER*)AllocatePool(BufferSizeReqested); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); if (!FwVolHeader) { return EFI_OUT_OF_RESOURCES; } From b0816d3678fb86d62f1cda8353305ce0714c5215 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 13:06:49 +0200 Subject: [PATCH 068/297] remove CB --- UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 206f6cfeaeb6..ee0aa6af933c 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -455,7 +455,7 @@ FvbRead ( UINTN BlockSize; SMMSTORE_INSTANCE *Instance; - Instance = INSTANCE_FROM_FVB_THIS(This); + Instance = NULL; //INSTANCE_FROM_FVB_THIS(This); DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); From 1ac013e70037dea5ea55d5f2436e1f8eec814872 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 13:25:38 +0200 Subject: [PATCH 069/297] empty problematic function --- UefiPayloadPkg/SPI/SPIFvb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index ee0aa6af933c..7e8cb6236ddd 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -452,10 +452,11 @@ FvbRead ( IN OUT UINT8 *Buffer ) { - UINTN BlockSize; + return EFI_SUCCESS; + /*UINTN BlockSize; SMMSTORE_INSTANCE *Instance; - Instance = NULL; //INSTANCE_FROM_FVB_THIS(This); + Instance = INSTANCE_FROM_FVB_THIS(This); DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); @@ -478,7 +479,7 @@ FvbRead ( return EFI_BAD_BUFFER_SIZE; } - return SMMStoreRead (Lba, Offset, NumBytes, Buffer); + return SMMStoreRead (Lba, Offset, NumBytes, Buffer);*/ } /** From 438452825fcee36779380658d67cb33c486048af Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 13:39:56 +0200 Subject: [PATCH 070/297] debug --- UefiPayloadPkg/SPI/SPI.inf | 2 +- UefiPayloadPkg/SPI/SPIFvb.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index b6e52f5a90c1..e622c8256ee8 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -10,7 +10,7 @@ [Defines] INF_VERSION = 0x00010005 BASE_NAME = SPI - FILE_GUID = e18edc1a-d43d-4e34-8131-088433608076 + FILE_GUID = c2c2e656-ee66-41e0-bee3-29c6f16f49c0 MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = SPIInitialize diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 7e8cb6236ddd..f1cadd7b2284 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -453,9 +453,11 @@ FvbRead ( ) { return EFI_SUCCESS; - /*UINTN BlockSize; + UINTN BlockSize; SMMSTORE_INSTANCE *Instance; + DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: This=0x%x, Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", This, Lba, Offset, *NumBytes, Buffer)); + Instance = INSTANCE_FROM_FVB_THIS(This); DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); @@ -479,7 +481,7 @@ FvbRead ( return EFI_BAD_BUFFER_SIZE; } - return SMMStoreRead (Lba, Offset, NumBytes, Buffer);*/ + return SMMStoreRead (Lba, Offset, NumBytes, Buffer); } /** From d12ceffae023f53c312d3f640e9c0bf023cbff7c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 13:53:02 +0200 Subject: [PATCH 071/297] debug 2 --- UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index f1cadd7b2284..8557b73e0b8c 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -256,7 +256,7 @@ FvbGetAttributes( { EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; SMMSTORE_INSTANCE *Instance; - + DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(Parameters: This=0x%x, Attributes=0x%x)\n", This, Attributes)); Instance = INSTANCE_FROM_FVB_THIS(This); FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( From e3ea223f45f9f64c5bcded4b8cac6c4599ea216f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 14:01:48 +0200 Subject: [PATCH 072/297] add debug signature to CR() --- MdePkg/Include/Library/DebugLib.h | 1 + UefiPayloadPkg/SPI/SPI.c | 6 ++---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h index f1d55cf62b0e..dc10c1d17f41 100644 --- a/MdePkg/Include/Library/DebugLib.h +++ b/MdePkg/Include/Library/DebugLib.h @@ -562,6 +562,7 @@ DebugPrintLevelEnabled ( **/ #if !defined(MDEPKG_NDEBUG) #define CR(Record, TYPE, Field, TestSignature) \ + DEBUG((EFI_D_INFO, "%a CR(): Signature: 0x%X, TestSignature: 0x%X\n", __FUNCTION__, BASE_CR (Record, TYPE, Field)->Signature, TestSignature)); \ (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ BASE_CR (Record, TYPE, Field) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 827180c29ad2..4028442f2b4d 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -42,11 +42,9 @@ EFI_STATUS EFIAPI SPIInitialize ( NULL ); if(EFI_ERROR (Status)) { - DEBUG(( - EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { - DEBUG(( - EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } return EFI_SUCCESS; } From 8dcde4581fe7466e65460d3d7d26bb126933f14e Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 14:15:17 +0200 Subject: [PATCH 073/297] add debug sigs --- MdePkg/Include/Library/DebugLib.h | 1 - UefiPayloadPkg/SPI/SPIFvb.c | 9 ++++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h index dc10c1d17f41..f1d55cf62b0e 100644 --- a/MdePkg/Include/Library/DebugLib.h +++ b/MdePkg/Include/Library/DebugLib.h @@ -562,7 +562,6 @@ DebugPrintLevelEnabled ( **/ #if !defined(MDEPKG_NDEBUG) #define CR(Record, TYPE, Field, TestSignature) \ - DEBUG((EFI_D_INFO, "%a CR(): Signature: 0x%X, TestSignature: 0x%X\n", __FUNCTION__, BASE_CR (Record, TYPE, Field)->Signature, TestSignature)); \ (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ BASE_CR (Record, TYPE, Field) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 8557b73e0b8c..ba5f8f010fdb 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -256,9 +256,16 @@ FvbGetAttributes( { EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; SMMSTORE_INSTANCE *Instance; - DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(Parameters: This=0x%x, Attributes=0x%x)\n", This, Attributes)); + DEBUG ((EFI_D_INFO, "FvbGetAttributes(Sig: 0x%x, SMMSTORE_SIGNATURE: 0x%x)\n", BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature, SMMSTORE_SIGNATURE)); + Instance = INSTANCE_FROM_FVB_THIS(This); + // CR(Record, TYPE, Field, TestSignature) + // (DebugAssertEnabled () + // && (BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature != SMMSTORE_SIGNATURE)) + // ? (SMMSTORE_INSTANCE *) (_ASSERT (CR has Bad Signature), This) + // : BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol); + FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled From fff59d6ae4403cb6fa4460148618cf953c1c4140 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 14:41:27 +0200 Subject: [PATCH 074/297] remove assert --- UefiPayloadPkg/SPI/SPIFvb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index ba5f8f010fdb..ad30e2b315bb 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -258,7 +258,10 @@ FvbGetAttributes( SMMSTORE_INSTANCE *Instance; DEBUG ((EFI_D_INFO, "FvbGetAttributes(Sig: 0x%x, SMMSTORE_SIGNATURE: 0x%x)\n", BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature, SMMSTORE_SIGNATURE)); - Instance = INSTANCE_FROM_FVB_THIS(This); + //Instance = INSTANCE_FROM_FVB_THIS(This); + Instance = BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol); + + // #define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) // CR(Record, TYPE, Field, TestSignature) // (DebugAssertEnabled () From 0c82b547b18971934dae7819a4e3d23c22c4f32b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 21 Sep 2020 14:51:28 +0200 Subject: [PATCH 075/297] remove assert 2 --- MdePkg/Include/Library/DebugLib.h | 2 +- UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h index f1d55cf62b0e..d025d95f7e5c 100644 --- a/MdePkg/Include/Library/DebugLib.h +++ b/MdePkg/Include/Library/DebugLib.h @@ -562,7 +562,7 @@ DebugPrintLevelEnabled ( **/ #if !defined(MDEPKG_NDEBUG) #define CR(Record, TYPE, Field, TestSignature) \ - (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ + BASE_CR (Record, TYPE, Field); //(DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ BASE_CR (Record, TYPE, Field) #else diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index ad30e2b315bb..ebbd4888e632 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -258,7 +258,7 @@ FvbGetAttributes( SMMSTORE_INSTANCE *Instance; DEBUG ((EFI_D_INFO, "FvbGetAttributes(Sig: 0x%x, SMMSTORE_SIGNATURE: 0x%x)\n", BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature, SMMSTORE_SIGNATURE)); - //Instance = INSTANCE_FROM_FVB_THIS(This); + Instance = INSTANCE_FROM_FVB_THIS(This); Instance = BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol); // #define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) From 87efeeb05d5641c52ef57da58ec0f7badf394609 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 08:23:40 +0200 Subject: [PATCH 076/297] restore asserts --- MdePkg/Include/Library/DebugLib.h | 2 +- UefiPayloadPkg/SPI/SPIFvb.c | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/MdePkg/Include/Library/DebugLib.h b/MdePkg/Include/Library/DebugLib.h index d025d95f7e5c..f1d55cf62b0e 100644 --- a/MdePkg/Include/Library/DebugLib.h +++ b/MdePkg/Include/Library/DebugLib.h @@ -562,7 +562,7 @@ DebugPrintLevelEnabled ( **/ #if !defined(MDEPKG_NDEBUG) #define CR(Record, TYPE, Field, TestSignature) \ - BASE_CR (Record, TYPE, Field); //(DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ + (DebugAssertEnabled () && (BASE_CR (Record, TYPE, Field)->Signature != TestSignature)) ? \ (TYPE *) (_ASSERT (CR has Bad Signature), Record) : \ BASE_CR (Record, TYPE, Field) #else diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index ebbd4888e632..8e4e47b49ecc 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -60,14 +60,14 @@ InitializeFvAndVariableStoreHeaders ( Headers = AllocateZeroPool(HeadersLength); // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - /*ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); // Ensure the Variable area Base Addresses are aligned on a block size boundaries ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0);*/ + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); // // EFI_FIRMWARE_VOLUME_HEADER @@ -259,7 +259,6 @@ FvbGetAttributes( DEBUG ((EFI_D_INFO, "FvbGetAttributes(Sig: 0x%x, SMMSTORE_SIGNATURE: 0x%x)\n", BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature, SMMSTORE_SIGNATURE)); Instance = INSTANCE_FROM_FVB_THIS(This); - Instance = BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol); // #define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) From a26fd1aada2143cb4fdb7786c983e2225db22fe6 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 08:31:21 +0200 Subject: [PATCH 077/297] restore asserts --- UefiPayloadPkg/SPI/SPIFvb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 8e4e47b49ecc..69352fbb05e9 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -60,14 +60,14 @@ InitializeFvAndVariableStoreHeaders ( Headers = AllocateZeroPool(HeadersLength); // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + /*ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); // Ensure the Variable area Base Addresses are aligned on a block size boundaries ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0);*/ // // EFI_FIRMWARE_VOLUME_HEADER From 2df578e487f598a5fd8d4766711510de1856fd47 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 08:50:15 +0200 Subject: [PATCH 078/297] copy inf from another driver --- UefiPayloadPkg/SPI/SPI.inf | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index e622c8256ee8..bc45d6f725ad 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -24,19 +24,33 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] - UefiDriverEntryPoint + IoLib + BaseLib DebugLib - BaseMemoryLib + HobLib SmmStoreLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeLib + DxeServicesTableLib [Guids] - gEdkiiNvVarStoreFormattedGuid - # gEfiSMMSTOREInfoHobGuid + gEfiSystemNvDataFvGuid + gEfiVariableGuid + gEfiAuthenticatedVariableGuid + gEfiEventVirtualAddressChangeGuid + gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL + gEfiSMMSTOREInfoHobGuid [Protocols] - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiDiskIoProtocolGuid [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase @@ -48,4 +62,4 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable [Depex] - TRUE + gEfiCpuArchProtocolGuid From 3c71360fbfd5e8b238247db839f33f56488df5b9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 09:08:46 +0200 Subject: [PATCH 079/297] debug fucntions entry --- UefiPayloadPkg/SPI/SPI.inf | 26 ++++++-------------------- UefiPayloadPkg/SPI/SPIFvb.c | 12 +++++++++++- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index bc45d6f725ad..e622c8256ee8 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -24,33 +24,19 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec - UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] - IoLib - BaseLib + UefiDriverEntryPoint DebugLib - HobLib + BaseMemoryLib SmmStoreLib - UefiLib - UefiDriverEntryPoint - UefiBootServicesTableLib - UefiRuntimeLib - DxeServicesTableLib [Guids] - gEfiSystemNvDataFvGuid - gEfiVariableGuid - gEfiAuthenticatedVariableGuid - gEfiEventVirtualAddressChangeGuid - gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL - gEfiSMMSTOREInfoHobGuid + gEdkiiNvVarStoreFormattedGuid + # gEfiSMMSTOREInfoHobGuid [Protocols] - gEfiBlockIoProtocolGuid - gEfiDevicePathProtocolGuid - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES - gEfiDiskIoProtocolGuid + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase @@ -62,4 +48,4 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable [Depex] - gEfiCpuArchProtocolGuid + TRUE diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 69352fbb05e9..260b174878ce 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -50,6 +50,7 @@ InitializeFvAndVariableStoreHeaders ( IN SMMSTORE_INSTANCE *Instance ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; VOID* Headers; UINTN HeadersLength; @@ -126,6 +127,7 @@ ValidateFvHeader ( IN SMMSTORE_INSTANCE *Instance ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT16 Checksum; EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; VARIABLE_STORE_HEADER *VariableStoreHeader; @@ -254,6 +256,7 @@ FvbGetAttributes( OUT EFI_FVB_ATTRIBUTES_2 *Attributes ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; SMMSTORE_INSTANCE *Instance; DEBUG ((EFI_D_INFO, "FvbGetAttributes(Sig: 0x%x, SMMSTORE_SIGNATURE: 0x%x)\n", BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature, SMMSTORE_SIGNATURE)); @@ -319,6 +322,7 @@ FvbSetAttributes( IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); return EFI_UNSUPPORTED; } @@ -347,6 +351,7 @@ FvbGetPhysicalAddress ( OUT EFI_PHYSICAL_ADDRESS *Address ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); ASSERT(Address != NULL); *Address = mFlashNvStorageVariableBase; @@ -388,6 +393,7 @@ FvbGetBlockSize ( OUT UINTN *NumberOfBlocks ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; SMMSTORE_INSTANCE *Instance; @@ -461,7 +467,7 @@ FvbRead ( IN OUT UINT8 *Buffer ) { - return EFI_SUCCESS; + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINTN BlockSize; SMMSTORE_INSTANCE *Instance; @@ -557,6 +563,7 @@ FvbWrite ( IN UINT8 *Buffer ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINTN BlockSize; SMMSTORE_INSTANCE *Instance; @@ -634,6 +641,7 @@ FvbEraseBlocks ( ... ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; VA_LIST Args; EFI_LBA StartingLba; // Lba from which we start erasing @@ -740,6 +748,7 @@ FvbVirtualNotifyEvent ( IN VOID *Context ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); return; } @@ -750,6 +759,7 @@ SMMStoreFvbInitialize ( IN SMMSTORE_INSTANCE* Instance ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; UINT32 FvbNumLba; EFI_BOOT_MODE BootMode; From fa677aefe34265bf39135257c5c3281a5821b99a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 09:31:09 +0200 Subject: [PATCH 080/297] add more debug --- UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c | 1 + UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreFvbDxe.c | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index 52b133670a35..b66392e04b39 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c @@ -80,6 +80,7 @@ SMMStoreCreateInstance ( OUT SMMSTORE_INSTANCE** SMMStoreInstance ) { + DEBUG((EFI_D_INFO, "STOREDXE ASDF\n", __FUNCTION__)); EFI_STATUS Status; SMMSTORE_INSTANCE* Instance; diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreFvbDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreFvbDxe.c index 9bfaafb72348..c15da69a7d3b 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreFvbDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreFvbDxe.c @@ -49,6 +49,7 @@ InitializeFvAndVariableStoreHeaders ( IN SMMSTORE_INSTANCE *Instance ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; VOID* Headers; UINTN HeadersLength; @@ -129,6 +130,7 @@ ValidateFvHeader ( IN SMMSTORE_INSTANCE *Instance ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT16 Checksum; EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; VARIABLE_STORE_HEADER *VariableStoreHeader; @@ -257,6 +259,7 @@ FvbGetAttributes( OUT EFI_FVB_ATTRIBUTES_2 *Attributes ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; SMMSTORE_INSTANCE *Instance; @@ -313,6 +316,7 @@ FvbSetAttributes( IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); return EFI_UNSUPPORTED; } @@ -341,6 +345,7 @@ FvbGetPhysicalAddress ( OUT EFI_PHYSICAL_ADDRESS *Address ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); ASSERT(Address != NULL); *Address = mFlashNvStorageVariableBase; @@ -382,6 +387,7 @@ FvbGetBlockSize ( OUT UINTN *NumberOfBlocks ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; SMMSTORE_INSTANCE *Instance; @@ -455,6 +461,7 @@ FvbRead ( IN OUT UINT8 *Buffer ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINTN BlockSize; SMMSTORE_INSTANCE *Instance; @@ -548,6 +555,7 @@ FvbWrite ( IN UINT8 *Buffer ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINTN BlockSize; SMMSTORE_INSTANCE *Instance; @@ -625,6 +633,7 @@ FvbEraseBlocks ( ... ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; VA_LIST Args; EFI_LBA StartingLba; // Lba from which we start erasing @@ -731,6 +740,7 @@ FvbVirtualNotifyEvent ( IN VOID *Context ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); return; } @@ -741,6 +751,7 @@ SMMStoreFvbInitialize ( IN SMMSTORE_INSTANCE* Instance ) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); EFI_STATUS Status; UINT32 FvbNumLba; EFI_BOOT_MODE BootMode; From 2dacb59acaa3f00a4bfdd5c4d2082680aaabfd42 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 09:41:09 +0200 Subject: [PATCH 081/297] disable SPI --- UefiPayloadPkg/SPI/SPI.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 4028442f2b4d..e1f597fc9e82 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -36,11 +36,11 @@ EFI_STATUS EFIAPI SPIInitialize ( // EFI_NATIVE_INTERFACE, // &FvbProtocol); DEBUG((EFI_D_INFO, "SPI IS HERE\n")); - Status = gBS->InstallMultipleProtocolInterfaces ( + /*Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, NULL - ); + );*/ if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { From 91a463b4bfb5e08874cce19de00d9198e49aaeb5 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 09:47:53 +0200 Subject: [PATCH 082/297] initialize status --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index e1f597fc9e82..36ec5624c64c 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -29,7 +29,7 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + EFI_STATUS Status = EFI_SUCCESS; // Status = gBS->InstallProtocolInterface( // ImageHandle, // &gEfiDevicePathProtocolGuid, From 13c33125afba168879fbef59f045fc4708ca9edd Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 10:00:48 +0200 Subject: [PATCH 083/297] move some debug --- UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index b66392e04b39..8920371d724f 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c @@ -80,7 +80,6 @@ SMMStoreCreateInstance ( OUT SMMSTORE_INSTANCE** SMMStoreInstance ) { - DEBUG((EFI_D_INFO, "STOREDXE ASDF\n", __FUNCTION__)); EFI_STATUS Status; SMMSTORE_INSTANCE* Instance; @@ -157,6 +156,7 @@ BlSMMSTOREInitialise ( IN EFI_SYSTEM_TABLE *SystemTable ) { + DEBUG((EFI_D_INFO, "STOREDXE ASDF\n", __FUNCTION__)); EFI_STATUS Status; VOID *ComBuf; VOID *GuidHob; From c224848cc6984a18ea7034217bef61757eafff41 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 10:09:49 +0200 Subject: [PATCH 084/297] empty protocol functions --- UefiPayloadPkg/SPI/SPI.c | 4 +- UefiPayloadPkg/SPI/SPIFvb.c | 448 +----------------------------------- 2 files changed, 10 insertions(+), 442 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 36ec5624c64c..38a32c0a7602 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -36,11 +36,11 @@ EFI_STATUS EFIAPI SPIInitialize ( // EFI_NATIVE_INTERFACE, // &FvbProtocol); DEBUG((EFI_D_INFO, "SPI IS HERE\n")); - /*Status = gBS->InstallMultipleProtocolInterfaces ( + Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, NULL - );*/ + ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 260b174878ce..948adbd1baab 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -51,66 +51,7 @@ InitializeFvAndVariableStoreHeaders ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - VOID* Headers; - UINTN HeadersLength; - EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - - HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); - Headers = AllocateZeroPool(HeadersLength); - - // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - /*ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGInitializeFvAndVariableStoreHeaders& (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); - - // Ensure the Variable area Base Addresses are aligned on a block size boundaries - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0);*/ - - // - // EFI_FIRMWARE_VOLUME_HEADER - // - FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; - CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); - FirmwareVolumeHeader->FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); - FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; - FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled - ); - FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); - FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; - FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; - FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; - FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; - FirmwareVolumeHeader->BlockMap[1].Length = 0; - FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); - - // - // VARIABLE_STORE_HEADER - // - VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); - CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); - VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; - VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; - - // Install the combined super-header in the store - Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); - - FreePool (Headers); - return Status; + return EFI_SUCCESS; } /** @@ -128,111 +69,6 @@ ValidateFvHeader ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - UINT16 Checksum; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - UINTN VariableStoreLength; - UINTN FvLength; - EFI_STATUS TempStatus; - UINTN BufferSize; - UINTN BufferSizeReqested; - - BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); - if (!FwVolHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (FwVolHeader); - return EFI_DEVICE_ERROR; - } - - FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); - - // - // Verify the header revision, header signature, length - // Length of FvBlock cannot be 2**64-1 - // HeaderLength cannot be an odd number - // - if ( (FwVolHeader->Revision != EFI_FVH_REVISION) - || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) - || (FwVolHeader->FvLength != FvLength) - ) - { - DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", - __FUNCTION__)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - // Check the Firmware Volume Guid - if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { - DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", - __FUNCTION__)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - BufferSizeReqested = FwVolHeader->HeaderLength; - FreePool (FwVolHeader); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); - if (!FwVolHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = SMMStoreRead (0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (FwVolHeader); - return EFI_DEVICE_ERROR; - } - - // Verify the header checksum - Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); - if (Checksum != 0) { - DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", - __FUNCTION__, Checksum)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); - VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); - if (!VariableStoreHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = SMMStoreRead (0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (VariableStoreHeader); - FreePool (FwVolHeader); - return EFI_DEVICE_ERROR; - } - - // Check the Variable Store Guid - if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && - !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { - DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", - __FUNCTION__)); - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); - return EFI_NOT_FOUND; - } - - VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; - if (VariableStoreHeader->Size != VariableStoreLength) { - DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", - __FUNCTION__)); - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); - return EFI_NOT_FOUND; - } - - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); - return EFI_SUCCESS; } @@ -257,42 +93,6 @@ FvbGetAttributes( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; - SMMSTORE_INSTANCE *Instance; - DEBUG ((EFI_D_INFO, "FvbGetAttributes(Sig: 0x%x, SMMSTORE_SIGNATURE: 0x%x)\n", BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature, SMMSTORE_SIGNATURE)); - - Instance = INSTANCE_FROM_FVB_THIS(This); - - // #define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) - - // CR(Record, TYPE, Field, TestSignature) - // (DebugAssertEnabled () - // && (BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol)->Signature != SMMSTORE_SIGNATURE)) - // ? (SMMSTORE_INSTANCE *) (_ASSERT (CR has Bad Signature), This) - // : BASE_CR (This, SMMSTORE_INSTANCE, FvbProtocol); - - FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( - - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') - - ); - - // Check if it is write protected - if (Instance->Media.ReadOnly != TRUE) { - - FlashFvbAttributes = FlashFvbAttributes | - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled - } - - *Attributes = FlashFvbAttributes; - - DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); - return EFI_SUCCESS; } @@ -323,8 +123,7 @@ FvbSetAttributes( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); - return EFI_UNSUPPORTED; + return EFI_SUCCESS; } /** @@ -352,9 +151,6 @@ FvbGetPhysicalAddress ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - ASSERT(Address != NULL); - - *Address = mFlashNvStorageVariableBase; return EFI_SUCCESS; } @@ -394,26 +190,7 @@ FvbGetBlockSize ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock)); - - if (Lba > Instance->Media.LastBlock) { - DEBUG ((EFI_D_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock)); - Status = EFI_INVALID_PARAMETER; - } else { - *BlockSize = (UINTN) Instance->Media.BlockSize; - *NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1); - - DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks)); - - Status = EFI_SUCCESS; - } - - return Status; + return EFI_SUCCESS; } /** @@ -468,35 +245,7 @@ FvbRead ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - UINTN BlockSize; - SMMSTORE_INSTANCE *Instance; - - DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: This=0x%x, Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", This, Lba, Offset, *NumBytes, Buffer)); - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); - - // Cache the block size to avoid de-referencing pointers all the time - BlockSize = Instance->Media.BlockSize; - - DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - - // The read must not span block boundaries. - // We need to check each variable individually because adding two large values together overflows. - if ((Offset >= BlockSize) || - (*NumBytes > BlockSize) || - ((Offset + *NumBytes) > BlockSize)) { - DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - return EFI_BAD_BUFFER_SIZE; - } - - // We must have some bytes to read - if (*NumBytes == 0) { - return EFI_BAD_BUFFER_SIZE; - } - - return SMMStoreRead (Lba, Offset, NumBytes, Buffer); + return EFI_SUCCESS; } /** @@ -564,31 +313,7 @@ FvbWrite ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - UINTN BlockSize; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); - - // Cache the block size to avoid de-referencing pointers all the time - BlockSize = Instance->Media.BlockSize; - - // The read must not span block boundaries. - // We need to check each variable individually because adding two large values together overflows. - if ((Offset >= BlockSize) || - (*NumBytes > BlockSize) || - ((Offset + *NumBytes) > BlockSize)) { - DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - return EFI_BAD_BUFFER_SIZE; - } - - // We must have some bytes to read - if (*NumBytes == 0) { - return EFI_BAD_BUFFER_SIZE; - } - - return SMMStoreWrite (Lba, Offset, NumBytes, Buffer); + return EFI_SUCCESS; } /** @@ -642,95 +367,7 @@ FvbEraseBlocks ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - VA_LIST Args; - EFI_LBA StartingLba; // Lba from which we start erasing - UINTN NumOfLba; // Number of Lba blocks to erase - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks()\n")); - - Status = EFI_SUCCESS; - - // Detect WriteDisabled state - if (Instance->Media.ReadOnly == TRUE) { - // Firmware volume is in WriteDisabled state - DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n")); - return EFI_ACCESS_DENIED; - } - - // Before erasing, check the entire list of parameters to ensure all specified blocks are valid - - VA_START (Args, This); - do { - // Get the Lba from which we start erasing - StartingLba = VA_ARG (Args, EFI_LBA); - - // Have we reached the end of the list? - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - //Exit the while loop - break; - } - - // How many Lba blocks are we requested to erase? - NumOfLba = VA_ARG (Args, UINTN); - - // All blocks must be within range - DEBUG (( - DEBUG_BLKIO, - "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n", - StartingLba, - (UINT64)NumOfLba, - Instance->Media.LastBlock - )); - if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { - VA_END (Args); - DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n")); - Status = EFI_INVALID_PARAMETER; - goto EXIT; - } - } while (TRUE); - VA_END (Args); - - // - // To get here, all must be ok, so start erasing - // - VA_START (Args, This); - do { - // Get the Lba from which we start erasing - StartingLba = VA_ARG (Args, EFI_LBA); - - // Have we reached the end of the list? - if (StartingLba == EFI_LBA_LIST_TERMINATOR) { - // Exit the while loop - break; - } - - // How many Lba blocks are we requested to erase? - NumOfLba = VA_ARG (Args, UINTN); - - // Go through each one and erase it - while (NumOfLba > 0) { - // Erase it - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba)); - Status = SMMStoreEraseBlock (StartingLba); - if (EFI_ERROR(Status)) { - VA_END (Args); - Status = EFI_DEVICE_ERROR; - goto EXIT; - } - - // Move to the next Lba - StartingLba++; - NumOfLba--; - } - } while (TRUE); - VA_END (Args); - -EXIT: - return Status; + return EFI_SUCCESS; } /** @@ -749,8 +386,7 @@ FvbVirtualNotifyEvent ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); - return; + return EFI_SUCCESS; } EFI_STATUS @@ -760,73 +396,5 @@ SMMStoreFvbInitialize ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - UINT32 FvbNumLba; - EFI_BOOT_MODE BootMode; - - DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); - ASSERT((Instance != NULL)); - - mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); - - BootMode = GetBootModeHob (); - if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { - Status = EFI_INVALID_PARAMETER; - } else { - // Determine if there is a valid header at the beginning of the NorFlash - Status = ValidateFvHeader (Instance); - } - - // Install the Default FVB header if required - if (EFI_ERROR(Status)) { - // There is no valid header, so time to install one. - DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); - DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", - __FUNCTION__)); - - // Erase all the NorFlash that is reserved for variable storage - FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; - - Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); - if (EFI_ERROR(Status)) { - return Status; - } - - // Install all appropriate headers - Status = InitializeFvAndVariableStoreHeaders (Instance); - if (EFI_ERROR(Status)) { - return Status; - } - } else { - DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); - } - - // - // The driver implementing the variable read service can now be dispatched; - // the varstore headers are in place. - // - Status = gBS->InstallProtocolInterface ( - &gImageHandle, - &gEdkiiNvVarStoreFormattedGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Register for the virtual address change event - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - FvbVirtualNotifyEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - &mFvbVirtualAddrChangeEvent - ); - ASSERT_EFI_ERROR (Status); - - return Status; + return EFI_SUCCESS; } From 7937a27e4360ba040da06458f27b0a6f84580d72 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 10:19:29 +0200 Subject: [PATCH 085/297] fix void fucntion --- UefiPayloadPkg/SPI/SPIFvb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 948adbd1baab..99149ad6a6ab 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -386,7 +386,7 @@ FvbVirtualNotifyEvent ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; + return; } EFI_STATUS From 052fdb6a68d67c33fd6e5434c8c084f4508a0822 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 10:23:06 +0200 Subject: [PATCH 086/297] comment out unused code --- UefiPayloadPkg/SPI/SPIFvb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 99149ad6a6ab..c7358a6ce526 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -25,8 +25,8 @@ #include "SPI.h" -STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; -STATIC UINTN mFlashNvStorageVariableBase; +// STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; +// STATIC UINTN mFlashNvStorageVariableBase; /// /// The Firmware Volume Block Protocol is the low-level interface From 4411d860bda33a1dd5f766272b85d499044c76b4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 11:04:16 +0200 Subject: [PATCH 087/297] check guid hob --- UefiPayloadPkg/SPI/SPI.c | 6 ++++++ UefiPayloadPkg/SPI/SPI.inf | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 38a32c0a7602..2736b9f2a6d7 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "SPI.h" EFI_HANDLE Handle = NULL; @@ -30,6 +31,11 @@ EFI_STATUS EFIAPI SPIInitialize ( ) { EFI_STATUS Status = EFI_SUCCESS; + VOID *GuidHob; + GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); + if(GuidHob == NULL) { + DEBUG((EFI_D_INFO, "GUIDHOB IS NULLLLLL!!!!\n")); + } // Status = gBS->InstallProtocolInterface( // ImageHandle, // &gEfiDevicePathProtocolGuid, diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index e622c8256ee8..bdf65c81954c 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -33,7 +33,7 @@ [Guids] gEdkiiNvVarStoreFormattedGuid - # gEfiSMMSTOREInfoHobGuid + gEfiSMMSTOREInfoHobGuid [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES From 30221eb5b1088759082b60bd3db45c621c0b8d12 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 11:23:33 +0200 Subject: [PATCH 088/297] change driver type to DXE --- UefiPayloadPkg/SPI/SPI.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index bdf65c81954c..b9d225dfd1fa 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -11,7 +11,7 @@ INF_VERSION = 0x00010005 BASE_NAME = SPI FILE_GUID = c2c2e656-ee66-41e0-bee3-29c6f16f49c0 - MODULE_TYPE = DXE_DRIVER + MODULE_TYPE = DXE_RUNTIME_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = SPIInitialize From 94ceed448a2b11e1de0f5e08e7db56eab5de2062 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 11:26:20 +0200 Subject: [PATCH 089/297] add uefi pkg --- UefiPayloadPkg/SPI/SPI.inf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index b9d225dfd1fa..3502bfb9cbfb 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -11,7 +11,7 @@ INF_VERSION = 0x00010005 BASE_NAME = SPI FILE_GUID = c2c2e656-ee66-41e0-bee3-29c6f16f49c0 - MODULE_TYPE = DXE_RUNTIME_DRIVER + MODULE_TYPE = DXE_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = SPIInitialize @@ -24,6 +24,7 @@ MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] UefiDriverEntryPoint From 6b7acd6bdd271b7c7f565d1ff7d5466a64584b4b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 11:46:59 +0200 Subject: [PATCH 090/297] remove redefinition --- UefiPayloadPkg/SPI/SPI.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 8a4a6372ebba..4ca0aef7d714 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -191,16 +191,6 @@ SMMStoreVirtualNotifyEvent ( **/ -typedef struct { - UINT64 ComBuffer; - UINT32 ComBufferSize; - UINT32 NumBlocks; - UINT32 BlockSize; - UINT64 MmioAddress; - UINT8 ApmCmd; - UINT8 Reserved0[3]; -} SMMSTORE_INFO; - EFI_STATUS SMMStoreInitialize ( IN VOID *Ptr, From 09807a69d812f472f1d941b7bad9aa818763d964 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 11:51:24 +0200 Subject: [PATCH 091/297] add hob lib --- UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c | 1 - UefiPayloadPkg/SPI/SPI.inf | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index 8920371d724f..52b133670a35 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c @@ -156,7 +156,6 @@ BlSMMSTOREInitialise ( IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG((EFI_D_INFO, "STOREDXE ASDF\n", __FUNCTION__)); EFI_STATUS Status; VOID *ComBuf; VOID *GuidHob; diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 3502bfb9cbfb..dce05f71adc6 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -31,6 +31,7 @@ DebugLib BaseMemoryLib SmmStoreLib + HobLib [Guids] gEdkiiNvVarStoreFormattedGuid From 3e085a622fc0588168f4ed9f8958e56ad35c3a3a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 11:56:24 +0200 Subject: [PATCH 092/297] add hob lib 2 --- UefiPayloadPkg/SPI/SPI.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 2736b9f2a6d7..453489223109 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "SPI.h" EFI_HANDLE Handle = NULL; From ca3a27184f4c8dc0e68171e17e48f510772f117e Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 12:02:26 +0200 Subject: [PATCH 093/297] remove unused definitions --- UefiPayloadPkg/SPI/SPI.h | 84 ---------------------------------------- 1 file changed, 84 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 4ca0aef7d714..6e0d86f205af 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -114,88 +114,4 @@ FvbEraseBlocks( ... ); -#define SMMSTORE_COMBUF_SIZE 16 - -/** - Read from SMMStore - - @param[in] Lba The starting logical block index to read from. - @param[in] Offset Offset into the block at which to begin reading. - @param[in] NumBytes On input, indicates the requested read size. On - output, indicates the actual number of bytes read - @param[in] Buffer Pointer to the buffer to read into. - -**/ -EFI_STATUS -SMMStoreRead ( - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN UINT8 *Buffer - ); - - -/** - Write to SMMStore - - @param[in] Lba The starting logical block index to write to. - @param[in] Offset Offset into the block at which to begin writing. - @param[in] NumBytes On input, indicates the requested write size. On - output, indicates the actual number of bytes written - @param[in] Buffer Pointer to the data to write. - -**/ -EFI_STATUS -SMMStoreWrite ( - IN EFI_LBA Lba, - IN UINTN Offset, - IN UINTN *NumBytes, - IN UINT8 *Buffer - ); - - -/** - Erase a block using the SMMStore - - @param Lba The logical block index to erase. - -**/ -EFI_STATUS -SMMStoreEraseBlock ( - IN EFI_LBA Lba - ); - - -/** - Notify the SMMStore Library about a VirtualNotify - -**/ - -VOID -EFIAPI -SMMStoreVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -/** - Initializes SMMStore support - - @param[in] Ptr A runtime buffer where arguments are stored - for SMM communication - @param[in] SmmStoreInfoHob A runtime buffer with a copy of the - SmmStore Info Hob - - @retval EFI_WRITE_PROTECTED The SMMSTORE is not present. - @retval EFI_SUCCESS The SMMSTORE is supported. - -**/ - -EFI_STATUS -SMMStoreInitialize ( - IN VOID *Ptr, - IN SMMSTORE_INFO *SmmStoreInfoHob - ); - - #endif /* __SPI_H__ */ From 87cdfbaf26fdb393c1fb8dced8bd22ded086daaf Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 12:25:22 +0200 Subject: [PATCH 094/297] install protocol --- UefiPayloadPkg/SPI/SPI.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 453489223109..e7c92d27d163 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -37,11 +37,11 @@ EFI_STATUS EFIAPI SPIInitialize ( if(GuidHob == NULL) { DEBUG((EFI_D_INFO, "GUIDHOB IS NULLLLLL!!!!\n")); } - // Status = gBS->InstallProtocolInterface( - // ImageHandle, - // &gEfiDevicePathProtocolGuid, - // EFI_NATIVE_INTERFACE, - // &FvbProtocol); + Status = gBS->InstallProtocolInterface( + ImageHandle, + &gEfiDevicePathProtocolGuid, + EFI_NATIVE_INTERFACE, + &FvbProtocol); DEBUG((EFI_D_INFO, "SPI IS HERE\n")); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, From ce95917e201635fa42178831d262f54d99bf8c38 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 13:10:06 +0200 Subject: [PATCH 095/297] add fvb initialization --- UefiPayloadPkg/SPI/SPI.c | 61 ++++++++++++++++++++++++++++--- UefiPayloadPkg/SPI/SPIFvb.c | 73 ++++++++++++++++++++++++++++++++++++- 2 files changed, 128 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index e7c92d27d163..85bd725d9213 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -14,6 +14,54 @@ #include #include "SPI.h" +SMMSTORE_INSTANCE mSMMStoreInstanceTemplate = { + SMMSTORE_SIGNATURE, // Signature + NULL, // Handle ... NEED TO BE FILLED + { + 0, // MediaId ... NEED TO BE FILLED + FALSE, // RemovableMedia + TRUE, // MediaPresent + FALSE, // LogicalPartition + FALSE, // ReadOnly + FALSE, // WriteCaching; + 0, // BlockSize ... NEED TO BE FILLED + 4, // IoAlign + 0, // LastBlock ... NEED TO BE FILLED + 0, // LowestAlignedLba + 1, // LogicalBlocksPerPhysicalBlock + }, //Media; + + { + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL, //ParentHandle + }, // FvbProtoccol; + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)), + (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8) + } + }, + { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED + }, + 0, // Index + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } + } + } // DevicePath +}; + EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { FvbGetAttributes, // GetAttributes @@ -31,8 +79,11 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { + SMMSTORE_INSTANCE* Instance; + Instance = AllocateRuntimeCopyPool (sizeof(SMMSTORE_INSTANCE),&mSMMStoreInstanceTemplate); EFI_STATUS Status = EFI_SUCCESS; VOID *GuidHob; + GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); if(GuidHob == NULL) { DEBUG((EFI_D_INFO, "GUIDHOB IS NULLLLLL!!!!\n")); @@ -43,11 +94,11 @@ EFI_STATUS EFIAPI SPIInitialize ( EFI_NATIVE_INTERFACE, &FvbProtocol); DEBUG((EFI_D_INFO, "SPI IS HERE\n")); - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index c7358a6ce526..c1b184d773c4 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -25,6 +25,9 @@ #include "SPI.h" +STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; +STATIC UINTN mFlashNvStorageVariableBase; + // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; // STATIC UINTN mFlashNvStorageVariableBase; @@ -396,5 +399,73 @@ SMMStoreFvbInitialize ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; + EFI_STATUS Status; + UINT32 FvbNumLba; + EFI_BOOT_MODE BootMode; + + DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); + ASSERT((Instance != NULL)); + + mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); + + BootMode = GetBootModeHob (); + if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { + Status = EFI_INVALID_PARAMETER; + } else { + // Determine if there is a valid header at the beginning of the NorFlash + Status = ValidateFvHeader (Instance); + } + + // Install the Default FVB header if required + if (EFI_ERROR(Status)) { + // There is no valid header, so time to install one. + DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); + DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", + __FUNCTION__)); + + // Erase all the NorFlash that is reserved for variable storage + FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; + + Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); + if (EFI_ERROR(Status)) { + return Status; + } + + // Install all appropriate headers + Status = InitializeFvAndVariableStoreHeaders (Instance); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); + } + + // + // The driver implementing the variable read service can now be dispatched; + // the varstore headers are in place. + // + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mFvbVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; } From c43f25e2bbacc51a1f29b3c6d1e9bdc4cf7db67a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 13:17:47 +0200 Subject: [PATCH 096/297] add memoryallocation include --- UefiPayloadPkg/SPI/SPI.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 85bd725d9213..e83f3b55e5b4 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "SPI.h" SMMSTORE_INSTANCE mSMMStoreInstanceTemplate = { From f4ed5a251f34e34e38f9651f867833179e0b7479 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 13:22:40 +0200 Subject: [PATCH 097/297] fix --- UefiPayloadPkg/SPI/SPI.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index e83f3b55e5b4..06f433962b63 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -81,9 +81,15 @@ EFI_STATUS EFIAPI SPIInitialize ( ) { SMMSTORE_INSTANCE* Instance; - Instance = AllocateRuntimeCopyPool (sizeof(SMMSTORE_INSTANCE),&mSMMStoreInstanceTemplate); EFI_STATUS Status = EFI_SUCCESS; VOID *GuidHob; + Instance = AllocateRuntimeCopyPool (sizeof(SMMSTORE_INSTANCE),&mSMMStoreInstanceTemplate); + Status = SMMStoreFvbInitialize (Instance); + if(EFI_ERROR (Status)) { + DEBUG((EFI_D_INFO, "%a Error during FVB init\n", __FUNCTION__)); + } else { + DEBUG((EFI_D_INFO, "%a Successfull FVB init\n", __FUNCTION__)); + } GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); if(GuidHob == NULL) { From b5bad3bf808fa8e2deb43414e9b3d0570d5fe5b5 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 13:25:22 +0200 Subject: [PATCH 098/297] add guid --- UefiPayloadPkg/SPI/SPI.inf | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index dce05f71adc6..c697f740e856 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -36,6 +36,7 @@ [Guids] gEdkiiNvVarStoreFormattedGuid gEfiSMMSTOREInfoHobGuid + gEfiEventVirtualAddressChangeGuid [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES From 78d802045ec0c475bec885104b2ce9c8619fd42d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 13:44:53 +0200 Subject: [PATCH 099/297] cast --- UefiPayloadPkg/SPI/SPI.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 06f433962b63..8cd732d7e07a 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -80,7 +80,7 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - SMMSTORE_INSTANCE* Instance; + SMMSTORE_INSTANCE *Instance; EFI_STATUS Status = EFI_SUCCESS; VOID *GuidHob; Instance = AllocateRuntimeCopyPool (sizeof(SMMSTORE_INSTANCE),&mSMMStoreInstanceTemplate); @@ -95,6 +95,10 @@ EFI_STATUS EFIAPI SPIInitialize ( if(GuidHob == NULL) { DEBUG((EFI_D_INFO, "GUIDHOB IS NULLLLLL!!!!\n")); } + + SMMSTORE_INSTANCE *a; + a = ((VOID *)INSTANCE_FROM_FVB_THIS(FvbProtocol)); + Status = gBS->InstallProtocolInterface( ImageHandle, &gEfiDevicePathProtocolGuid, From a9b3c75d316ae18d7d6451dc0a8fffa1ccd58619 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 14:14:14 +0200 Subject: [PATCH 100/297] empty protocol fuctions --- UefiPayloadPkg/SPI/SPI.c | 3 - UefiPayloadPkg/SPI/SPIFvb.c | 70 +----------------------- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 6 +- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 6 +- 4 files changed, 7 insertions(+), 78 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 8cd732d7e07a..b928b43dccd7 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -96,9 +96,6 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "GUIDHOB IS NULLLLLL!!!!\n")); } - SMMSTORE_INSTANCE *a; - a = ((VOID *)INSTANCE_FROM_FVB_THIS(FvbProtocol)); - Status = gBS->InstallProtocolInterface( ImageHandle, &gEfiDevicePathProtocolGuid, diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index c1b184d773c4..0221ed24b691 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -399,73 +399,5 @@ SMMStoreFvbInitialize ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - UINT32 FvbNumLba; - EFI_BOOT_MODE BootMode; - - DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); - ASSERT((Instance != NULL)); - - mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); - - BootMode = GetBootModeHob (); - if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { - Status = EFI_INVALID_PARAMETER; - } else { - // Determine if there is a valid header at the beginning of the NorFlash - Status = ValidateFvHeader (Instance); - } - - // Install the Default FVB header if required - if (EFI_ERROR(Status)) { - // There is no valid header, so time to install one. - DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); - DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", - __FUNCTION__)); - - // Erase all the NorFlash that is reserved for variable storage - FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; - - Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); - if (EFI_ERROR(Status)) { - return Status; - } - - // Install all appropriate headers - Status = InitializeFvAndVariableStoreHeaders (Instance); - if (EFI_ERROR(Status)) { - return Status; - } - } else { - DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); - } - - // - // The driver implementing the variable read service can now be dispatched; - // the varstore headers are in place. - // - Status = gBS->InstallProtocolInterface ( - &gImageHandle, - &gEdkiiNvVarStoreFormattedGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - ASSERT_EFI_ERROR (Status); - - // - // Register for the virtual address change event - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, - FvbVirtualNotifyEvent, - NULL, - &gEfiEventVirtualAddressChangeGuid, - &mFvbVirtualAddrChangeEvent - ); - ASSERT_EFI_ERROR (Status); - - return Status; + return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 505122e91673..170f6587843d 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -627,9 +627,9 @@ # SMMSTORE # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif +# !if $(BOOTLOADER) == "COREBOOT" +# UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +# !endif # # Network Support diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 0436b1804530..e7422d5de4f5 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -633,9 +633,9 @@ # # SMMSTORE # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif +# !if $(BOOTLOADER) == "COREBOOT" +# UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +# !endif # # Network Support From b91d4d77632641a23bd20cd15e581ab8144a53bb Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 14:22:20 +0200 Subject: [PATCH 101/297] repair reference --- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 170f6587843d..505122e91673 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -627,9 +627,9 @@ # SMMSTORE # -# !if $(BOOTLOADER) == "COREBOOT" -# UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -# !endif +!if $(BOOTLOADER) == "COREBOOT" + UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +!endif # # Network Support From ed69ad84472a2c61cc7e8bdb2b7c2a2189ef3cd5 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 14:23:48 +0200 Subject: [PATCH 102/297] repair reference 2 --- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index e7422d5de4f5..0436b1804530 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -633,9 +633,9 @@ # # SMMSTORE # -# !if $(BOOTLOADER) == "COREBOOT" -# UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -# !endif +!if $(BOOTLOADER) == "COREBOOT" + UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +!endif # # Network Support From db1c33d912baecc1988ae0e8f99cf26180fdd1d0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 14:26:04 +0200 Subject: [PATCH 103/297] remove unused code --- UefiPayloadPkg/SPI/SPIFvb.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index 0221ed24b691..c7358a6ce526 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -25,9 +25,6 @@ #include "SPI.h" -STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; -STATIC UINTN mFlashNvStorageVariableBase; - // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; // STATIC UINTN mFlashNvStorageVariableBase; From cdb0b57b697f5e2c52a37e0bd7284c41c707eef3 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 22 Sep 2020 14:45:03 +0200 Subject: [PATCH 104/297] check unsigned int size --- UefiPayloadPkg/SPI/SPI.c | 1 + UefiPayloadPkg/SPI/SPI.h | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index b928b43dccd7..323b62fab3cf 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -102,6 +102,7 @@ EFI_STATUS EFIAPI SPIInitialize ( EFI_NATIVE_INTERFACE, &FvbProtocol); DEBUG((EFI_D_INFO, "SPI IS HERE\n")); + DEBUG((EFI_D_INFO, "unsigned int 0x%X\n", sizeof(unsigned int))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 6e0d86f205af..8d0c5d09ba13 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -114,4 +114,12 @@ FvbEraseBlocks( ... ); +///////////////////////////////////////////////////////// + +struct spi_slave { + UINT32 bus; + UINT32 cs; + const struct spi_ctrlr *ctrlr; +}; + #endif /* __SPI_H__ */ From dac94305437b8dc0f9dd73301d12b32dcf94779c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 07:15:41 +0200 Subject: [PATCH 105/297] remove SMM --- UefiPayloadPkg/SPI/SPI.c | 70 ++++------------------------------------ UefiPayloadPkg/SPI/SPI.h | 1 + 2 files changed, 7 insertions(+), 64 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 323b62fab3cf..2d6834a3b213 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -15,54 +15,6 @@ #include #include "SPI.h" -SMMSTORE_INSTANCE mSMMStoreInstanceTemplate = { - SMMSTORE_SIGNATURE, // Signature - NULL, // Handle ... NEED TO BE FILLED - { - 0, // MediaId ... NEED TO BE FILLED - FALSE, // RemovableMedia - TRUE, // MediaPresent - FALSE, // LogicalPartition - FALSE, // ReadOnly - FALSE, // WriteCaching; - 0, // BlockSize ... NEED TO BE FILLED - 4, // IoAlign - 0, // LastBlock ... NEED TO BE FILLED - 0, // LowestAlignedLba - 1, // LogicalBlocksPerPhysicalBlock - }, //Media; - - { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks - NULL, //ParentHandle - }, // FvbProtoccol; - { - { - { - HARDWARE_DEVICE_PATH, - HW_VENDOR_DP, - { - (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)), - (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8) - } - }, - { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED - }, - 0, // Index - { - END_DEVICE_PATH_TYPE, - END_ENTIRE_DEVICE_PATH_SUBTYPE, - { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } - } - } // DevicePath -}; - EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { FvbGetAttributes, // GetAttributes @@ -80,27 +32,17 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - SMMSTORE_INSTANCE *Instance; - EFI_STATUS Status = EFI_SUCCESS; - VOID *GuidHob; - Instance = AllocateRuntimeCopyPool (sizeof(SMMSTORE_INSTANCE),&mSMMStoreInstanceTemplate); - Status = SMMStoreFvbInitialize (Instance); - if(EFI_ERROR (Status)) { - DEBUG((EFI_D_INFO, "%a Error during FVB init\n", __FUNCTION__)); - } else { - DEBUG((EFI_D_INFO, "%a Successfull FVB init\n", __FUNCTION__)); - } - - GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); - if(GuidHob == NULL) { - DEBUG((EFI_D_INFO, "GUIDHOB IS NULLLLLL!!!!\n")); - } - + EFI_STATUS Status; Status = gBS->InstallProtocolInterface( ImageHandle, &gEfiDevicePathProtocolGuid, EFI_NATIVE_INTERFACE, &FvbProtocol); + if(EFI_ERROR (Status)) { + DEBUG((EFI_D_INFO, "%a Error during single protocol installation\n", __FUNCTION__)); + } else { + DEBUG((EFI_D_INFO, "%a Successfull signgle protocol installation\n", __FUNCTION__)); + } DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "unsigned int 0x%X\n", sizeof(unsigned int))); Status = gBS->InstallMultipleProtocolInterfaces ( diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 8d0c5d09ba13..3d1d09856303 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -117,6 +117,7 @@ FvbEraseBlocks( ///////////////////////////////////////////////////////// struct spi_slave { + // sizeof(unsigned int) = 4 UINT32 bus; UINT32 cs; const struct spi_ctrlr *ctrlr; From 16fbc09ebe6c9ca6a970a0472f0d0fa8a96e1a5a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 07:53:22 +0200 Subject: [PATCH 106/297] add some spi --- UefiPayloadPkg/SPI/SPI.c | 30 +++- UefiPayloadPkg/SPI/SPI.h | 11 +- UefiPayloadPkg/SPI/SPI.inf | 2 + UefiPayloadPkg/SPI/SPIgeneric.c | 0 UefiPayloadPkg/SPI/SPIgeneric.h | 306 ++++++++++++++++++++++++++++++++ 5 files changed, 339 insertions(+), 10 deletions(-) create mode 100644 UefiPayloadPkg/SPI/SPIgeneric.c create mode 100644 UefiPayloadPkg/SPI/SPIgeneric.h diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 2d6834a3b213..0ecf618ba80f 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,6 +13,7 @@ #include #include #include +#include #include "SPI.h" EFI_HANDLE Handle = NULL; @@ -27,6 +28,32 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +{ + __SIZE_TYPE__ i; + + memset(slave, 0, sizeof(*slave)); + + for (i = 0; i < spi_ctrlr_bus_map_count; i++) { + if ((spi_ctrlr_bus_map[i].bus_start <= bus) && + (spi_ctrlr_bus_map[i].bus_end >= bus)) { + slave->ctrlr = spi_ctrlr_bus_map[i].ctrlr; + break; + } + } + + if (slave->ctrlr == NULL) + return -1; + + slave->bus = bus; + slave->cs = cs; + + if (slave->ctrlr->setup) + return slave->ctrlr->setup(slave); + + return 0; +} + EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -44,7 +71,8 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "%a Successfull signgle protocol installation\n", __FUNCTION__)); } DEBUG((EFI_D_INFO, "SPI IS HERE\n")); - DEBUG((EFI_D_INFO, "unsigned int 0x%X\n", sizeof(unsigned int))); + DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); + DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 3d1d09856303..6c93f01355b1 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -24,6 +24,8 @@ #include #include +#include "spi-generic.h" + #define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') #define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) @@ -114,13 +116,4 @@ FvbEraseBlocks( ... ); -///////////////////////////////////////////////////////// - -struct spi_slave { - // sizeof(unsigned int) = 4 - UINT32 bus; - UINT32 cs; - const struct spi_ctrlr *ctrlr; -}; - #endif /* __SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index c697f740e856..9125c4d85eda 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -19,6 +19,8 @@ SPI.h SPI.c SPIFvb.c + SPIgeneric.h + SPIgeneric.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h new file mode 100644 index 000000000000..0e7817bf46da --- /dev/null +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef _SPI_GENERIC_H_ +#define _SPI_GENERIC_H_ + +/* Common parameters -- kind of high, but they should only occur when there + * is a problem (and well your system already is broken), so err on the side + * of caution in case we're dealing with slower SPI buses and/or processors. + */ +#define SPI_FLASH_PROG_TIMEOUT_MS 200 +#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 500 + +#include +#include + +/* SPI vendor IDs */ +#define VENDOR_ID_ADESTO 0x1f +#define VENDOR_ID_AMIC 0x37 +#define VENDOR_ID_ATMEL 0x1f +#define VENDOR_ID_EON 0x1c +#define VENDOR_ID_GIGADEVICE 0xc8 +#define VENDOR_ID_MACRONIX 0xc2 +#define VENDOR_ID_SPANSION 0x01 +#define VENDOR_ID_SST 0xbf +#define VENDOR_ID_STMICRO 0x20 +#define VENDOR_ID_WINBOND 0xef + +/* Controller-specific definitions: */ + +struct spi_ctrlr; + +/*----------------------------------------------------------------------- + * Representation of a SPI slave, i.e. what we're communicating with. + * + * bus: ID of the bus that the slave is attached to. + * cs: ID of the chip select connected to the slave. + * ctrlr: Pointer to SPI controller structure. + */ +struct spi_slave { + unsigned int bus; + unsigned int cs; + const struct spi_ctrlr *ctrlr; +}; + +/* Representation of SPI operation status. */ +enum spi_op_status { + SPI_OP_NOT_EXECUTED = 0, + SPI_OP_SUCCESS = 1, + SPI_OP_FAILURE = 2, +}; + +/* + * Representation of a SPI operation. + * + * dout: Pointer to data to send. + * bytesout: Count of data in bytes to send. + * din: Pointer to store received data. + * bytesin: Count of data in bytes to receive. + */ +struct spi_op { + const void *dout; + size_t bytesout; + void *din; + size_t bytesin; + enum spi_op_status status; +}; + +enum spi_clock_phase { + SPI_CLOCK_PHASE_FIRST, + SPI_CLOCK_PHASE_SECOND +}; + +enum spi_wire_mode { + SPI_4_WIRE_MODE, + SPI_3_WIRE_MODE +}; + +enum spi_polarity { + SPI_POLARITY_LOW, + SPI_POLARITY_HIGH +}; + +struct spi_cfg { + /* CLK phase - 0: Phase first, 1: Phase second */ + enum spi_clock_phase clk_phase; + /* CLK polarity - 0: Low, 1: High */ + enum spi_polarity clk_polarity; + /* CS polarity - 0: Low, 1: High */ + enum spi_polarity cs_polarity; + /* Wire mode - 0: 4-wire, 1: 3-wire */ + enum spi_wire_mode wire_mode; + /* Data bit length. */ + unsigned int data_bit_length; +}; + +/* + * If there is no limit on the maximum transfer size for the controller, + * max_xfer_size can be set to SPI_CTRLR_DEFAULT_MAX_XFER_SIZE which is equal to + * UINT32_MAX. + */ +#define SPI_CTRLR_DEFAULT_MAX_XFER_SIZE (UINT32_MAX) + +struct spi_flash; + +enum ctrlr_prot_type { + READ_PROTECT = 1, + WRITE_PROTECT = 2, + READ_WRITE_PROTECT = 3, +}; + +enum { + /* Deduct the command length from the spi_crop_chunk() calculation for + sizing a transaction. */ + SPI_CNTRLR_DEDUCT_CMD_LEN = 1 << 0, + /* Remove the opcode size from the command length used in the + spi_crop_chunk() calculation. Controllers which have a dedicated + register for the command byte would set this flag which would + allow the use of the maximum transfer size. */ + SPI_CNTRLR_DEDUCT_OPCODE_LEN = 1 << 1, +}; + +/*----------------------------------------------------------------------- + * Representation of a SPI controller. Note the xfer() and xfer_vector() + * callbacks are meant to process full duplex transactions. If the + * controller cannot handle these transactions then return an error when + * din and dout are both set. See spi_xfer() below for more details. + * + * claim_bus: Claim SPI bus and prepare for communication. + * release_bus: Release SPI bus. + * setup: Setup given SPI device bus. + * xfer: Perform one SPI transfer operation. + * xfer_vector: Vector of SPI transfer operations. + * xfer_dual: (optional) Perform one SPI transfer in Dual SPI mode. + * max_xfer_size: Maximum transfer size supported by the controller + * (0 = invalid, + * SPI_CTRLR_DEFAULT_MAX_XFER_SIZE = unlimited) + * flags: See SPI_CNTRLR_* enums above. + * + * Following member is provided by specialized SPI controllers that are + * actually SPI flash controllers. + * + * flash_probe: Specialized probe function provided by SPI flash + * controllers. + * flash_protect: Protect a region of flash using the SPI flash controller. + */ +struct spi_ctrlr { + int (*claim_bus)(const struct spi_slave *slave); + void (*release_bus)(const struct spi_slave *slave); + int (*setup)(const struct spi_slave *slave); + int (*xfer)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin); + int (*xfer_vector)(const struct spi_slave *slave, + struct spi_op vectors[], size_t count); + int (*xfer_dual)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin); + uint32_t max_xfer_size; + uint32_t flags; + int (*flash_probe)(const struct spi_slave *slave, + struct spi_flash *flash); + int (*flash_protect)(const struct spi_flash *flash, + const struct region *region, + const enum ctrlr_prot_type type); +}; + +/*----------------------------------------------------------------------- + * Structure defining mapping of SPI buses to controller. + * + * ctrlr: Pointer to controller structure managing the given SPI buses. + * bus_start: Start bus number managed by the controller. + * bus_end: End bus number manager by the controller. + */ +struct spi_ctrlr_buses { + const struct spi_ctrlr *ctrlr; + unsigned int bus_start; + unsigned int bus_end; +}; + +/* Mapping of SPI buses to controllers - should be defined by platform. */ +extern const struct spi_ctrlr_buses spi_ctrlr_bus_map[]; +extern const size_t spi_ctrlr_bus_map_count; + +/*----------------------------------------------------------------------- + * Initialization, must be called once on start up. + * + */ +void spi_init(void); + +/* + * Get configuration of SPI bus. + * + * slave: Pointer to slave structure. + * cfg: Pointer to SPI configuration that needs to be filled. + * + * Returns: + * 0 on success, -1 on error + */ +int spi_get_config(const struct spi_slave *slave, struct spi_cfg *cfg); + +/*----------------------------------------------------------------------- + * Set up communications parameters for a SPI slave. + * + * This must be called once for each slave. Note that this function + * usually doesn't touch any actual hardware, it only initializes the + * contents of spi_slave so that the hardware can be easily + * initialized later. + * + * bus: Bus ID of the slave chip. + * cs: Chip select ID of the slave chip on the specified bus. + * slave: Pointer to slave structure that needs to be initialized. + * + * Returns: + * 0 on success, -1 on error + */ +int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * Claim the bus and prepare it for communication with a given slave. + * + * This must be called before doing any transfers with a SPI slave. It + * will enable and initialize any SPI hardware as necessary, and make + * sure that the SCK line is in the correct idle state. It is not + * allowed to claim the same bus for several slaves without releasing + * the bus in between. + * + * slave: The SPI slave + * + * Returns: 0 if the bus was claimed successfully, or a negative value + * if it wasn't. + */ +int spi_claim_bus(const struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * Release the SPI bus + * + * This must be called once for every call to spi_claim_bus() after + * all transfers have finished. It may disable any SPI hardware as + * appropriate. + * + * slave: The SPI slave + */ +void spi_release_bus(const struct spi_slave *slave); + +/*----------------------------------------------------------------------- + * SPI transfer + * + * spi_xfer() interface: + * slave: The SPI slave which will be sending/receiving the data. + * dout: Pointer to a string of bytes to send out. + * bytesout: How many bytes to write. + * din: Pointer to a string of bytes that will be filled in. + * bytesin: How many bytes to read. + * + * Note that din and dout are transferred simultaneously in a full duplex + * transaction. The number of clocks within one transaction is calculated + * as: MAX(bytesout*8, bytesin*8). + * + * Returns: 0 on success, not 0 on failure + */ +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin); + +/*----------------------------------------------------------------------- + * Vector of SPI transfer operations + * + * spi_xfer_vector() interface: + * slave: The SPI slave which will be sending/receiving the data. + * vectors: Array of SPI op structures. + * count: Number of SPI op vectors. + * + * Returns: 0 on success, not 0 on failure + */ +int spi_xfer_vector(const struct spi_slave *slave, + struct spi_op vectors[], size_t count); + +/*----------------------------------------------------------------------- + * Given command length and length of remaining data, return the maximum data + * that can be transferred in next spi_xfer. + * + * Returns: 0 on error, non-zero data size that can be xfered on success. + */ +unsigned int spi_crop_chunk(const struct spi_slave *slave, unsigned int cmd_len, + unsigned int buf_len); + +/*----------------------------------------------------------------------- + * Write 8 bits, then read 8 bits. + * slave: The SPI slave we're communicating with + * byte: Byte to be written + * + * Returns: The value that was read, or a negative value on error. + * + * TODO: This function probably shouldn't be inlined. + */ +static inline int spi_w8r8(const struct spi_slave *slave, unsigned char byte) +{ + unsigned char dout[2]; + unsigned char din[2]; + int ret; + + dout[0] = byte; + dout[1] = 0; + + ret = spi_xfer(slave, dout, 2, din, 2); + return ret < 0 ? ret : din[1]; +} + +#endif /* _SPI_GENERIC_H_ */ From e0a6343fb176f67b17326ee8efd817d95c55249c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 08:09:49 +0200 Subject: [PATCH 107/297] add implementation of memset --- UefiPayloadPkg/SPI/SPI.c | 8 ++++++++ UefiPayloadPkg/SPI/SPI.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 0ecf618ba80f..6dc432a423be 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -28,6 +28,14 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; +void * memset (void *dest, int ch, size_t count) +{ + for(UINT64 offset = 0; offset < count; ++offset) { + dest[offset] = ch; + } + return dest; +} + int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) { __SIZE_TYPE__ i; diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 6c93f01355b1..9e0a448fbe30 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -24,7 +24,7 @@ #include #include -#include "spi-generic.h" +#include "SPIgeneric.h" #define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') #define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) From 254296731581982586c20b9f129c9ccfc76e30b1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 08:12:26 +0200 Subject: [PATCH 108/297] remove string.h --- UefiPayloadPkg/SPI/SPI.c | 1 - 1 file changed, 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 6dc432a423be..7a52f0dee578 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,7 +13,6 @@ #include #include #include -#include #include "SPI.h" EFI_HANDLE Handle = NULL; From 6dee5ae93746f47e6cc72b14bd5a42021b0bffb1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 08:30:04 +0200 Subject: [PATCH 109/297] fix types --- UefiPayloadPkg/SPI/SPIFvb.c | 1 - UefiPayloadPkg/SPI/SPIgeneric.h | 24 +++++++++++------------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c index c7358a6ce526..033ccb66cab6 100644 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ b/UefiPayloadPkg/SPI/SPIFvb.c @@ -16,7 +16,6 @@ #include #include #include -// #include #include #include diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index 0e7817bf46da..702208d877c7 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -10,8 +10,6 @@ #define SPI_FLASH_PROG_TIMEOUT_MS 200 #define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 500 -#include -#include /* SPI vendor IDs */ #define VENDOR_ID_ADESTO 0x1f @@ -58,10 +56,10 @@ enum spi_op_status { * bytesin: Count of data in bytes to receive. */ struct spi_op { - const void *dout; - size_t bytesout; - void *din; - size_t bytesin; + const VOID *dout; + __SIZE_TYPE__ bytesout; + VOID *din; + __SIZE_TYPE__ bytesin; enum spi_op_status status; }; @@ -148,11 +146,11 @@ struct spi_ctrlr { void (*release_bus)(const struct spi_slave *slave); int (*setup)(const struct spi_slave *slave); int (*xfer)(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin); + __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin); int (*xfer_vector)(const struct spi_slave *slave, - struct spi_op vectors[], size_t count); + struct spi_op vectors[], __SIZE_TYPE__ count); int (*xfer_dual)(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin); + __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin); uint32_t max_xfer_size; uint32_t flags; int (*flash_probe)(const struct spi_slave *slave, @@ -177,7 +175,7 @@ struct spi_ctrlr_buses { /* Mapping of SPI buses to controllers - should be defined by platform. */ extern const struct spi_ctrlr_buses spi_ctrlr_bus_map[]; -extern const size_t spi_ctrlr_bus_map_count; +extern const __SIZE_TYPE__ spi_ctrlr_bus_map_count; /*----------------------------------------------------------------------- * Initialization, must be called once on start up. @@ -256,8 +254,8 @@ void spi_release_bus(const struct spi_slave *slave); * * Returns: 0 on success, not 0 on failure */ -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, - void *din, size_t bytesin); +int spi_xfer(const struct spi_slave *slave, const void *dout, __SIZE_TYPE__ bytesout, + void *din, __SIZE_TYPE__ bytesin); /*----------------------------------------------------------------------- * Vector of SPI transfer operations @@ -270,7 +268,7 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, * Returns: 0 on success, not 0 on failure */ int spi_xfer_vector(const struct spi_slave *slave, - struct spi_op vectors[], size_t count); + struct spi_op vectors[], __SIZE_TYPE__ count); /*----------------------------------------------------------------------- * Given command length and length of remaining data, return the maximum data From e09c64449e278ece6cb6f8d135a78f6e51d19d6d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 09:03:31 +0200 Subject: [PATCH 110/297] fix types 2 --- UefiPayloadPkg/SPI/SPIgeneric.h | 56 ++++++++++++++++----------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index 702208d877c7..c7892ef41672 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -142,20 +142,20 @@ enum { * flash_protect: Protect a region of flash using the SPI flash controller. */ struct spi_ctrlr { - int (*claim_bus)(const struct spi_slave *slave); - void (*release_bus)(const struct spi_slave *slave); - int (*setup)(const struct spi_slave *slave); - int (*xfer)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin); - int (*xfer_vector)(const struct spi_slave *slave, + INT32 (*claim_bus)(const struct spi_slave *slave); + VOID (*release_bus)(const struct spi_slave *slave); + INT32 (*setup)(const struct spi_slave *slave); + INT32 (*xfer)(const struct spi_slave *slave, const VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); + INT32 (*xfer_vector)(const struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count); - int (*xfer_dual)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin); - uint32_t max_xfer_size; - uint32_t flags; - int (*flash_probe)(const struct spi_slave *slave, + INT32 (*xfer_dual)(const struct spi_slave *slave, const VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); + UINT32 max_xfer_size; + UINT32 flags; + INT32 (*flash_probe)(const struct spi_slave *slave, struct spi_flash *flash); - int (*flash_protect)(const struct spi_flash *flash, + INT32 (*flash_protect)(const struct spi_flash *flash, const struct region *region, const enum ctrlr_prot_type type); }; @@ -169,8 +169,8 @@ struct spi_ctrlr { */ struct spi_ctrlr_buses { const struct spi_ctrlr *ctrlr; - unsigned int bus_start; - unsigned int bus_end; + UINT32 bus_start; + UINT32 bus_end; }; /* Mapping of SPI buses to controllers - should be defined by platform. */ @@ -181,7 +181,7 @@ extern const __SIZE_TYPE__ spi_ctrlr_bus_map_count; * Initialization, must be called once on start up. * */ -void spi_init(void); +VOID spi_init(VOID); /* * Get configuration of SPI bus. @@ -192,7 +192,7 @@ void spi_init(void); * Returns: * 0 on success, -1 on error */ -int spi_get_config(const struct spi_slave *slave, struct spi_cfg *cfg); +UINT32 spi_get_config(CONST struct spi_slave *slave, struct spi_cfg *cfg); /*----------------------------------------------------------------------- * Set up communications parameters for a SPI slave. @@ -209,7 +209,7 @@ int spi_get_config(const struct spi_slave *slave, struct spi_cfg *cfg); * Returns: * 0 on success, -1 on error */ -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave); +UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave); /*----------------------------------------------------------------------- * Claim the bus and prepare it for communication with a given slave. @@ -225,7 +225,7 @@ int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave); * Returns: 0 if the bus was claimed successfully, or a negative value * if it wasn't. */ -int spi_claim_bus(const struct spi_slave *slave); +UINT32 spi_claim_bus(CONST struct spi_slave *slave); /*----------------------------------------------------------------------- * Release the SPI bus @@ -236,7 +236,7 @@ int spi_claim_bus(const struct spi_slave *slave); * * slave: The SPI slave */ -void spi_release_bus(const struct spi_slave *slave); +VOID spi_release_bus(CONST struct spi_slave *slave); /*----------------------------------------------------------------------- * SPI transfer @@ -254,8 +254,8 @@ void spi_release_bus(const struct spi_slave *slave); * * Returns: 0 on success, not 0 on failure */ -int spi_xfer(const struct spi_slave *slave, const void *dout, __SIZE_TYPE__ bytesout, - void *din, __SIZE_TYPE__ bytesin); +UINT32 spi_xfer(CONST struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ bytesout, + VOID *din, __SIZE_TYPE__ bytesin); /*----------------------------------------------------------------------- * Vector of SPI transfer operations @@ -267,7 +267,7 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, __SIZE_TYPE__ byte * * Returns: 0 on success, not 0 on failure */ -int spi_xfer_vector(const struct spi_slave *slave, +INT32 spi_xfer_vector(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count); /*----------------------------------------------------------------------- @@ -276,8 +276,8 @@ int spi_xfer_vector(const struct spi_slave *slave, * * Returns: 0 on error, non-zero data size that can be xfered on success. */ -unsigned int spi_crop_chunk(const struct spi_slave *slave, unsigned int cmd_len, - unsigned int buf_len); +UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, + UINT32 buf_len); /*----------------------------------------------------------------------- * Write 8 bits, then read 8 bits. @@ -288,11 +288,11 @@ unsigned int spi_crop_chunk(const struct spi_slave *slave, unsigned int cmd_len, * * TODO: This function probably shouldn't be inlined. */ -static inline int spi_w8r8(const struct spi_slave *slave, unsigned char byte) +STATIC inline INT32 spi_w8r8(CONST struct spi_slave *slave, __u_char byte) { - unsigned char dout[2]; - unsigned char din[2]; - int ret; + __u_char dout[2]; + __u_char din[2]; + UINT32 ret; dout[0] = byte; dout[1] = 0; From 8a77a97341c4f5d504cd116c646597bd75041ec0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 09:13:07 +0200 Subject: [PATCH 111/297] fix memset --- UefiPayloadPkg/SPI/SPI.c | 8 ++++---- UefiPayloadPkg/SPI/SPIgeneric.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 7a52f0dee578..11554e08ba85 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -27,15 +27,15 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; -void * memset (void *dest, int ch, size_t count) +void * memset (void *dest, int ch, __SIZE_TYPE__ count) { - for(UINT64 offset = 0; offset < count; ++offset) { - dest[offset] = ch; + for(__SIZE_TYPE__ offset = 0; offset < count; ++offset) { + ((char *)dest)[offset] = ch; } return dest; } -int spi_setup_slave(unsigned int bus, unsigned int cs, struct spi_slave *slave) +UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { __SIZE_TYPE__ i; diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index c7892ef41672..24482e693584 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -288,10 +288,10 @@ UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, * * TODO: This function probably shouldn't be inlined. */ -STATIC inline INT32 spi_w8r8(CONST struct spi_slave *slave, __u_char byte) +STATIC inline INT32 spi_w8r8(CONST struct spi_slave *slave, unsigned char byte) { - __u_char dout[2]; - __u_char din[2]; + unsigned char dout[2]; + unsigned char din[2]; UINT32 ret; dout[0] = byte; From a6df17f44795fb87c7e35fa20c35ea5f1921a287 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 09:35:51 +0200 Subject: [PATCH 112/297] define region struct --- UefiPayloadPkg/SPI/SPIgeneric.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index 24482e693584..c7d38e983ac1 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -27,6 +27,11 @@ struct spi_ctrlr; +struct region { + __SIZE_TYPE__ offset; + __SIZE_TYPE__ size; +}; + /*----------------------------------------------------------------------- * Representation of a SPI slave, i.e. what we're communicating with. * From 73199013dd6963a3ef250179ea0e53b8f33b014a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 09:57:29 +0200 Subject: [PATCH 113/297] fixes --- UefiPayloadPkg/SPI/SPIgeneric.c | 137 ++++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/SPIgeneric.h | 1 + 2 files changed, 138 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index e69de29bb2d1..38e1f5bc165f 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -0,0 +1,137 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +//#include +#include +#include +#include +#include "SPIgeneric.h" + +int spi_claim_bus(const struct spi_slave *slave) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + if (ctrlr && ctrlr->claim_bus) + return ctrlr->claim_bus(slave); + return 0; +} + +void spi_release_bus(const struct spi_slave *slave) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + if (ctrlr && ctrlr->release_bus) + ctrlr->release_bus(slave); +} + +static int spi_xfer_single_op(const struct spi_slave *slave, + struct spi_op *op) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + int ret; + + if (!ctrlr || !ctrlr->xfer) + return -1; + + ret = ctrlr->xfer(slave, op->dout, op->bytesout, op->din, op->bytesin); + if (ret) + op->status = SPI_OP_FAILURE; + else + op->status = SPI_OP_SUCCESS; + + return ret; +} + +static int spi_xfer_vector_default(const struct spi_slave *slave, + struct spi_op vectors[], size_t count) +{ + size_t i; + int ret; + + for (i = 0; i < count; i++) { + ret = spi_xfer_single_op(slave, &vectors[i]); + if (ret) + return ret; + } + + return 0; +} + +int spi_xfer_vector(const struct spi_slave *slave, + struct spi_op vectors[], size_t count) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + + if (ctrlr && ctrlr->xfer_vector) + return ctrlr->xfer_vector(slave, vectors, count); + + return spi_xfer_vector_default(slave, vectors, count); +} + +int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, + void *din, size_t bytesin) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + + if (ctrlr && ctrlr->xfer) + return ctrlr->xfer(slave, dout, bytesout, din, bytesin); + + return -1; +} + +unsigned int spi_crop_chunk(const struct spi_slave *slave, unsigned int cmd_len, + unsigned int buf_len) +{ + const struct spi_ctrlr *ctrlr = slave->ctrlr; + unsigned int ctrlr_max; + BOOLEAN deduct_cmd_len; + BOOLEAN deduct_opcode_len; + + if (!ctrlr) + return 0; + + deduct_cmd_len = !!(ctrlr->flags & SPI_CNTRLR_DEDUCT_CMD_LEN); + deduct_opcode_len = !!(ctrlr->flags & SPI_CNTRLR_DEDUCT_OPCODE_LEN); + ctrlr_max = ctrlr->max_xfer_size; + + assert (ctrlr_max != 0); + + /* Assume opcode is always one byte and deduct it from the cmd_len + as the hardware has a separate register for the opcode. */ + if (deduct_opcode_len) + cmd_len--; + + if (deduct_cmd_len && (ctrlr_max > cmd_len)) + ctrlr_max -= cmd_len; + + return MIN(ctrlr_max, buf_len); +} + +VOID spi_init(VOID) +{ + /* Default weak implementation - do nothing. */ +} + +UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) +{ + size_t i; + + memset(slave, 0, sizeof(*slave)); + + for (i = 0; i < spi_ctrlr_bus_map_count; i++) { + if ((spi_ctrlr_bus_map[i].bus_start <= bus) && + (spi_ctrlr_bus_map[i].bus_end >= bus)) { + slave->ctrlr = spi_ctrlr_bus_map[i].ctrlr; + break; + } + } + + if (slave->ctrlr == NULL) + return -1; + + slave->bus = bus; + slave->cs = cs; + + if (slave->ctrlr->setup) + return slave->ctrlr->setup(slave); + + return 0; +} diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index c7d38e983ac1..01ad15ed9cb4 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -186,6 +186,7 @@ extern const __SIZE_TYPE__ spi_ctrlr_bus_map_count; * Initialization, must be called once on start up. * */ +__attribute__((__weak__, __alias__("__spi_init"))) VOID spi_init(VOID); /* From a83161de30bb2ead08a110f708de0ef029bcd12d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:10:36 +0200 Subject: [PATCH 114/297] fix types --- UefiPayloadPkg/SPI/SPIgeneric.c | 40 ++++++++++++++++----------------- UefiPayloadPkg/SPI/SPIgeneric.h | 2 +- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 38e1f5bc165f..59b01bbfe8ea 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -7,26 +7,26 @@ #include #include "SPIgeneric.h" -int spi_claim_bus(const struct spi_slave *slave) +UINT32 spi_claim_bus(CONST struct spi_slave *slave) { - const struct spi_ctrlr *ctrlr = slave->ctrlr; + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; if (ctrlr && ctrlr->claim_bus) return ctrlr->claim_bus(slave); return 0; } -void spi_release_bus(const struct spi_slave *slave) +VOID spi_release_bus(CONST struct spi_slave *slave) { - const struct spi_ctrlr *ctrlr = slave->ctrlr; + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; if (ctrlr && ctrlr->release_bus) ctrlr->release_bus(slave); } -static int spi_xfer_single_op(const struct spi_slave *slave, +static INT32 spi_xfer_single_op(CONST struct spi_slave *slave, struct spi_op *op) { - const struct spi_ctrlr *ctrlr = slave->ctrlr; - int ret; + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; + INT32 ret; if (!ctrlr || !ctrlr->xfer) return -1; @@ -40,11 +40,11 @@ static int spi_xfer_single_op(const struct spi_slave *slave, return ret; } -static int spi_xfer_vector_default(const struct spi_slave *slave, +static INT32 spi_xfer_vector_default(CONST struct spi_slave *slave, struct spi_op vectors[], size_t count) { - size_t i; - int ret; + __SIZE_TYPE__ i; + INT32 ret; for (i = 0; i < count; i++) { ret = spi_xfer_single_op(slave, &vectors[i]); @@ -56,9 +56,9 @@ static int spi_xfer_vector_default(const struct spi_slave *slave, } int spi_xfer_vector(const struct spi_slave *slave, - struct spi_op vectors[], size_t count) + struct spi_op vectors[], __SIZE_TYPE__ count) { - const struct spi_ctrlr *ctrlr = slave->ctrlr; + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; if (ctrlr && ctrlr->xfer_vector) return ctrlr->xfer_vector(slave, vectors, count); @@ -66,10 +66,10 @@ int spi_xfer_vector(const struct spi_slave *slave, return spi_xfer_vector_default(slave, vectors, count); } -int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, - void *din, size_t bytesin) +UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, size_t bytesout, + VOID *din, size_t bytesin) { - const struct spi_ctrlr *ctrlr = slave->ctrlr; + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; if (ctrlr && ctrlr->xfer) return ctrlr->xfer(slave, dout, bytesout, din, bytesin); @@ -77,11 +77,11 @@ int spi_xfer(const struct spi_slave *slave, const void *dout, size_t bytesout, return -1; } -unsigned int spi_crop_chunk(const struct spi_slave *slave, unsigned int cmd_len, - unsigned int buf_len) +UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, + UINT32 buf_len) { - const struct spi_ctrlr *ctrlr = slave->ctrlr; - unsigned int ctrlr_max; + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; + UINT32 ctrlr_max; BOOLEAN deduct_cmd_len; BOOLEAN deduct_opcode_len; @@ -112,7 +112,7 @@ VOID spi_init(VOID) UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { - size_t i; + __SIZE_TYPE__ i; memset(slave, 0, sizeof(*slave)); diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index 01ad15ed9cb4..8cad692a281e 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -186,7 +186,7 @@ extern const __SIZE_TYPE__ spi_ctrlr_bus_map_count; * Initialization, must be called once on start up. * */ -__attribute__((__weak__, __alias__("__spi_init"))) +__attribute__((__weak__)) VOID spi_init(VOID); /* From 997df4f8f315277450becceaa0fd186095456f75 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:13:07 +0200 Subject: [PATCH 115/297] remove assert.h --- UefiPayloadPkg/SPI/SPIgeneric.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 59b01bbfe8ea..0d1ce1f6466b 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include +//#include //#include #include #include From c6e0d0eb9ac18ac35ed28fa3e882d3bbfa045646 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:15:56 +0200 Subject: [PATCH 116/297] fix includes again --- UefiPayloadPkg/SPI/SPIgeneric.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 0d1ce1f6466b..a49306a9ee4e 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -2,8 +2,8 @@ //#include //#include -#include -#include +//#include +//#include #include #include "SPIgeneric.h" @@ -41,7 +41,7 @@ static INT32 spi_xfer_single_op(CONST struct spi_slave *slave, } static INT32 spi_xfer_vector_default(CONST struct spi_slave *slave, - struct spi_op vectors[], size_t count) + struct spi_op vectors[], __SIZE_TYPE__ count) { __SIZE_TYPE__ i; INT32 ret; @@ -66,8 +66,8 @@ int spi_xfer_vector(const struct spi_slave *slave, return spi_xfer_vector_default(slave, vectors, count); } -UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, size_t bytesout, - VOID *din, size_t bytesin) +UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, __SIZE_TYPE__ bytesout, + VOID *din, __SIZE_TYPE__ bytesin) { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; From 380fd401378b7148fb2d917be72ccc59afc3c941 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:20:51 +0200 Subject: [PATCH 117/297] some fixes --- UefiPayloadPkg/SPI/SPI.c | 8 -------- UefiPayloadPkg/SPI/SPIgeneric.c | 10 +++++++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 11554e08ba85..926020843a41 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -27,14 +27,6 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; -void * memset (void *dest, int ch, __SIZE_TYPE__ count) -{ - for(__SIZE_TYPE__ offset = 0; offset < count; ++offset) { - ((char *)dest)[offset] = ch; - } - return dest; -} - UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { __SIZE_TYPE__ i; diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index a49306a9ee4e..2d6e5dd8f883 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -7,6 +7,14 @@ #include #include "SPIgeneric.h" +void * memset (void *dest, int ch, __SIZE_TYPE__ count) +{ + for(__SIZE_TYPE__ offset = 0; offset < count; ++offset) { + ((CHAR8 *)dest)[offset] = ch; + } + return dest; +} + UINT32 spi_claim_bus(CONST struct spi_slave *slave) { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; @@ -92,7 +100,7 @@ UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, deduct_opcode_len = !!(ctrlr->flags & SPI_CNTRLR_DEDUCT_OPCODE_LEN); ctrlr_max = ctrlr->max_xfer_size; - assert (ctrlr_max != 0); + //assert (ctrlr_max != 0); /* Assume opcode is always one byte and deduct it from the cmd_len as the hardware has a separate register for the opcode. */ From 6d67717cc276d8cb558304f3f90bc3136a9d82f7 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:24:01 +0200 Subject: [PATCH 118/297] fix memset --- UefiPayloadPkg/SPI/SPI.c | 8 ++++++++ UefiPayloadPkg/SPI/SPI.h | 2 ++ UefiPayloadPkg/SPI/SPIgeneric.c | 9 +-------- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 926020843a41..9ece870800d3 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -27,6 +27,14 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL, //ParentHandle }; +void * memset (void *dest, int ch, __SIZE_TYPE__ count) +{ + for(__SIZE_TYPE__ offset = 0; offset < count; ++offset) { + ((CHAR8 *)dest)[offset] = ch; + } + return dest; +} + UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { __SIZE_TYPE__ i; diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 9e0a448fbe30..be726917d163 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -49,6 +49,8 @@ struct _SMMSTORE_INSTANCE { NOR_FLASH_DEVICE_PATH DevicePath; }; +void * memset (void *dest, int ch, __SIZE_TYPE__ count) + // // BlSMMStoreFvbDxe.c // diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 2d6e5dd8f883..b2950d10317e 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -6,14 +6,7 @@ //#include #include #include "SPIgeneric.h" - -void * memset (void *dest, int ch, __SIZE_TYPE__ count) -{ - for(__SIZE_TYPE__ offset = 0; offset < count; ++offset) { - ((CHAR8 *)dest)[offset] = ch; - } - return dest; -} +#include "SPI.h" UINT32 spi_claim_bus(CONST struct spi_slave *slave) { From 246871b03e47f531b298686d6d1beb7894cbb227 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:27:51 +0200 Subject: [PATCH 119/297] fix missing semicolon --- UefiPayloadPkg/SPI/SPI.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index be726917d163..1bc2934a6267 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -49,7 +49,7 @@ struct _SMMSTORE_INSTANCE { NOR_FLASH_DEVICE_PATH DevicePath; }; -void * memset (void *dest, int ch, __SIZE_TYPE__ count) +void * memset (void *dest, int ch, __SIZE_TYPE__ count); // // BlSMMStoreFvbDxe.c From e6dcefac5750280bbd040af0f66ce83d28265405 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:33:29 +0200 Subject: [PATCH 120/297] fix double definition --- UefiPayloadPkg/SPI/SPI.c | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 9ece870800d3..847f58d90a57 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -35,32 +35,6 @@ void * memset (void *dest, int ch, __SIZE_TYPE__ count) return dest; } -UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) -{ - __SIZE_TYPE__ i; - - memset(slave, 0, sizeof(*slave)); - - for (i = 0; i < spi_ctrlr_bus_map_count; i++) { - if ((spi_ctrlr_bus_map[i].bus_start <= bus) && - (spi_ctrlr_bus_map[i].bus_end >= bus)) { - slave->ctrlr = spi_ctrlr_bus_map[i].ctrlr; - break; - } - } - - if (slave->ctrlr == NULL) - return -1; - - slave->bus = bus; - slave->cs = cs; - - if (slave->ctrlr->setup) - return slave->ctrlr->setup(slave); - - return 0; -} - EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable From 76a1241224c3e87b72408e4bf99c83289ab850ab Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:41:33 +0200 Subject: [PATCH 121/297] call spi_setup_slave() --- UefiPayloadPkg/SPI/SPI.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 847f58d90a57..09caeaadc594 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -13,6 +13,7 @@ #include #include #include +#include "SPIgeneric.h" #include "SPI.h" EFI_HANDLE Handle = NULL; @@ -41,6 +42,7 @@ EFI_STATUS EFIAPI SPIInitialize ( ) { EFI_STATUS Status; + struct spi_slave slave; Status = gBS->InstallProtocolInterface( ImageHandle, &gEfiDevicePathProtocolGuid, @@ -54,6 +56,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); + spi_setup_slave(0, 0, &slave); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, From 80f7c87e41ce55a3484c7cf3c4a855aab8a079dd Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:46:40 +0200 Subject: [PATCH 122/297] print result ofcall spi_setup_slave() --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 09caeaadc594..040e33e1bb12 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -56,7 +56,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); - spi_setup_slave(0, 0, &slave); + DEBUG((EFI_D_INFO, "spi_setup_slave() returned %i", spi_setup_slave(0, 0, &slave);)) Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, From 0dbef6ee382183d8eaf706bfad34038dd82b7cd1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 10:52:50 +0200 Subject: [PATCH 123/297] fix semicolon --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 040e33e1bb12..f5ca9234c016 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -56,7 +56,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); - DEBUG((EFI_D_INFO, "spi_setup_slave() returned %i", spi_setup_slave(0, 0, &slave);)) + DEBUG((EFI_D_INFO, "spi_setup_slave() returned %i", spi_setup_slave(0, 0, &slave))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, From 7babc4de1e8be53066afd8932169e4a6d36a94ca Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 13:31:25 +0200 Subject: [PATCH 124/297] add spi controller --- UefiPayloadPkg/SPI/intelSPI.c | 1168 +++++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/intelSPI.h | 27 + 2 files changed, 1195 insertions(+) create mode 100644 UefiPayloadPkg/SPI/intelSPI.c create mode 100644 UefiPayloadPkg/SPI/intelSPI.h diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c new file mode 100644 index 000000000000..2a203298e7e2 --- /dev/null +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -0,0 +1,1168 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define __SIMPLE_DEVICE__ + +/* This file is derived from the flashrom project. */ + +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include +// #include + +#include +#include +#include "SPI.h" +#include "SPIgeneric.h" + +CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); + +/*----------------------------------------------------------------------- + * Representation of a SPI controller. Note the xfer() and xfer_vector() + * callbacks are meant to process full duplex transactions. If the + * controller cannot handle these transactions then return an error when + * din and dout are both set. See spi_xfer() below for more details. + * + * claim_bus: Claim SPI bus and prepare for communication. + * release_bus: Release SPI bus. + * setup: Setup given SPI device bus. + * xfer: Perform one SPI transfer operation. + * xfer_vector: Vector of SPI transfer operations. + * xfer_dual: (optional) Perform one SPI transfer in Dual SPI mode. + * max_xfer_size: Maximum transfer size supported by the controller + * (0 = invalid, + * SPI_CTRLR_DEFAULT_MAX_XFER_SIZE = unlimited) + * flags: See SPI_CNTRLR_* enums above. + * + * Following member is provided by specialized SPI controllers that are + * actually SPI flash controllers. + * + * flash_probe: Specialized probe function provided by SPI flash + * controllers. + * flash_protect: Protect a region of flash using the SPI flash controller. + +struct spi_ctrlr { + int (*claim_bus)(const struct spi_slave *slave); + void (*release_bus)(const struct spi_slave *slave); + int (*setup)(const struct spi_slave *slave); + int (*xfer)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin); + int (*xfer_vector)(const struct spi_slave *slave, + struct spi_op vectors[], size_t count); + int (*xfer_dual)(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin); + uint32_t max_xfer_size; + uint32_t flags; + int (*flash_probe)(const struct spi_slave *slave, + struct spi_flash *flash); + int (*flash_protect)(const struct spi_flash *flash, + const struct region *region, + const enum ctrlr_prot_type type); +}; +*/ + +static CONST struct spi_ctrlr spi_ctrlr = { + .xfer_vector = NULL, + .max_xfer_size = 0, + .flash_probe = NULL, + .flash_protect = NULL, +}; + +CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { + { + .ctrlr = &spi_ctrlr, + .bus_start = 0, + .bus_end = 0, + }, +}; + +// #define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ +// #define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) +// #define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ +// #define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) + +// static int spi_is_multichip(VOID); + +// struct ich7_spi_regs { +// UINT16 spis; +// UINT16 spic; +// UINT32 spia; +// UINT64 spid[8]; +// UINT64 _pad; +// UINT32 bbar; +// UINT16 preop; +// UINT16 optype; +// UINT8 opmenu[8]; +// UINT32 pbr[3]; +// } __packed; + +// struct ich9_spi_regs { +// UINT32 bfpr; +// UINT16 hsfs; +// UINT16 hsfc; +// UINT32 faddr; +// UINT32 _reserved0; +// UINT32 fdata[16]; +// UINT32 frap; +// UINT32 freg[5]; +// UINT32 _reserved1[3]; +// UINT32 pr[5]; +// UINT32 _reserved2[2]; +// UINT8 ssfs; +// UINT8 ssfc[3]; +// UINT16 preop; +// UINT16 optype; +// UINT8 opmenu[8]; +// UINT32 bbar; +// UINT8 _reserved3[12]; +// UINT32 fdoc; +// UINT32 fdod; +// UINT8 _reserved4[8]; +// UINT32 afc; +// UINT32 lvscc; +// UINT32 uvscc; +// UINT8 _reserved5[4]; +// UINT32 fpb; +// UINT8 _reserved6[28]; +// UINT32 srdl; +// UINT32 srdc; +// UINT32 srd; +// } __packed; + +// struct ich_spi_controller { +// INT32 locked; +// UINT32 flmap0; +// UINT32 flcomp; +// UINT32 hsfs; + +// union { +// struct ich9_spi_regs *ich9_spi; +// struct ich7_spi_regs *ich7_spi; +// }; +// UINT8 *opmenu; +// INT32 menubytes; +// UINT16 *preop; +// UINT16 *optype; +// UINT32 *addr; +// UINT8 *data; +// UINT32 databytes; +// UINT8 *status; +// UINT16 *control; +// UINT32 *bbar; +// UINT32 *fpr; +// UINT8 fpr_max; +// }; + +// static struct ich_spi_controller cntlr; + +// enum { +// SPIS_SCIP = 0x0001, +// SPIS_GRANT = 0x0002, +// SPIS_CDS = 0x0004, +// SPIS_FCERR = 0x0008, +// SSFS_AEL = 0x0010, +// SPIS_LOCK = 0x8000, +// SPIS_RESERVED_MASK = 0x7ff0, +// SSFS_RESERVED_MASK = 0x7fe2 +// }; + +// enum { +// SPIC_SCGO = 0x000002, +// SPIC_ACS = 0x000004, +// SPIC_SPOP = 0x000008, +// SPIC_DBC = 0x003f00, +// SPIC_DS = 0x004000, +// SPIC_SME = 0x008000, +// SSFC_SCF_MASK = 0x070000, +// SSFC_RESERVED = 0xf80000 +// }; + +// enum { +// HSFS_FDONE = 0x0001, +// HSFS_FCERR = 0x0002, +// HSFS_AEL = 0x0004, +// HSFS_BERASE_MASK = 0x0018, +// HSFS_BERASE_SHIFT = 3, +// HSFS_SCIP = 0x0020, +// HSFS_FDOPSS = 0x2000, +// HSFS_FDV = 0x4000, +// HSFS_FLOCKDN = 0x8000 +// }; + +// enum { +// HSFC_FGO = 0x0001, +// HSFC_FCYCLE_MASK = 0x0006, +// HSFC_FCYCLE_SHIFT = 1, +// HSFC_FDBC_MASK = 0x3f00, +// HSFC_FDBC_SHIFT = 8, +// HSFC_FSMIE = 0x8000 +// }; + +// enum { +// SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, +// SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, +// SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, +// SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 +// }; + +// #if CONFIG(DEBUG_SPI_FLASH) + +// static u8 readb_(CONST VOID *addr) +// { +// u8 v = read8(addr); + +// printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", +// v, ((unsigned int) addr & 0xffff) - 0xf020); +// return v; +// } + +// static UINT16 readw_(CONST VOID *addr) +// { +// UINT16 v = read16(addr); + +// printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", +// v, ((unsigned int) addr & 0xffff) - 0xf020); +// return v; +// } + +// static UINT32 readl_(CONST VOID *addr) +// { +// UINT32 v = read32(addr); + +// printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", +// v, ((unsigned int) addr & 0xffff) - 0xf020); +// return v; +// } + +// static VOID writeb_(u8 b, VOID *addr) +// { +// write8(addr, b); +// printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", +// b, ((unsigned int) addr & 0xffff) - 0xf020); +// } + +// static VOID writew_(UINT16 b, VOID *addr) +// { +// write16(addr, b); +// printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", +// b, ((unsigned int) addr & 0xffff) - 0xf020); +// } + +// static VOID writel_(UINT32 b, VOID *addr) +// { +// write32(addr, b); +// printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", +// b, ((unsigned int) addr & 0xffff) - 0xf020); +// } + +// #else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ + +// #define readb_(a) read8(a) +// #define readw_(a) read16(a) +// #define readl_(a) read32(a) +// #define writeb_(val, addr) write8(addr, val) +// #define writew_(val, addr) write16(addr, val) +// #define writel_(val, addr) write32(addr, val) + +// #endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ + +// static VOID write_reg(CONST VOID *value, VOID *dest, UINT32 size) +// { +// CONST UINT8 *bvalue = value; +// UINT8 *bdest = dest; + +// while (size >= 4) { +// writel_(*(CONST UINT32 *)bvalue, bdest); +// bdest += 4; bvalue += 4; size -= 4; +// } +// while (size) { +// writeb_(*bvalue, bdest); +// bdest++; bvalue++; size--; +// } +// } + +// static VOID read_reg(CONST VOID *src, VOID *value, UINT32 size) +// { +// CONST UINT8 *bsrc = src; +// UINT8 *bvalue = value; + +// while (size >= 4) { +// *(UINT32 *)bvalue = readl_(bsrc); +// bsrc += 4; bvalue += 4; size -= 4; +// } +// while (size) { +// *bvalue = readb_(bsrc); +// bsrc++; bvalue++; size--; +// } +// } + +// static VOID ich_set_bbar(UINT32 minaddr) +// { +// CONST UINT32 bbar_mask = 0x00ffff00; +// UINT32 ichspi_bbar; + +// minaddr &= bbar_mask; +// ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; +// ichspi_bbar |= minaddr; +// writel_(ichspi_bbar, cntlr.bbar); +// } + +// #if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) +// #define MENU_BYTES member_size(struct ich7_spi_regs, opmenu) +// #else +// #define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) +// #endif + +// #define RCBA 0xf0 +// #define SBASE 0x54 + +// static VOID *get_spi_bar(pci_devfn_t dev) +// { +// uintptr_t rcba; /* Root Complex Register Block */ +// uintptr_t sbase; + +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { +// rcba = pci_read_config32(dev, RCBA); +// return (VOID *)((rcba & 0xffffc000) + 0x3020); +// } +// if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT)) { +// sbase = pci_read_config32(dev, SBASE); +// sbase &= ~0x1ff; +// return (VOID *)sbase; +// } +// if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { +// rcba = pci_read_config32(dev, RCBA); +// return (VOID *)((rcba & 0xffffc000) + 0x3800); +// } +// } + +// VOID spi_init(VOID) +// { +// UINT8 bios_cntl; +// struct ich9_spi_regs *ich9_spi; +// struct ich7_spi_regs *ich7_spi; +// UINT16 hsfs; + +// pci_devfn_t dev = PCI_DEV(0, 31, 0); + +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { +// ich7_spi = get_spi_bar(dev); +// cntlr.ich7_spi = ich7_spi; +// cntlr.opmenu = ich7_spi->opmenu; +// cntlr.menubytes = sizeof(ich7_spi->opmenu); +// cntlr.optype = &ich7_spi->optype; +// cntlr.addr = &ich7_spi->spia; +// cntlr.data = (UINT8 *)ich7_spi->spid; +// cntlr.databytes = sizeof(ich7_spi->spid); +// cntlr.status = (UINT8 *)&ich7_spi->spis; +// cntlr.control = &ich7_spi->spic; +// cntlr.bbar = &ich7_spi->bbar; +// cntlr.preop = &ich7_spi->preop; +// cntlr.fpr = &ich7_spi->pbr[0]; +// cntlr.fpr_max = 3; +// } else { +// ich9_spi = get_spi_bar(dev); +// cntlr.ich9_spi = ich9_spi; +// hsfs = readw_(&ich9_spi->hsfs); +// cntlr.hsfs = hsfs; +// cntlr.opmenu = ich9_spi->opmenu; +// cntlr.menubytes = sizeof(ich9_spi->opmenu); +// cntlr.optype = &ich9_spi->optype; +// cntlr.addr = &ich9_spi->faddr; +// cntlr.data = (UINT8 *)ich9_spi->fdata; +// cntlr.databytes = sizeof(ich9_spi->fdata); +// cntlr.status = &ich9_spi->ssfs; +// cntlr.control = (UINT16 *)ich9_spi->ssfc; +// cntlr.bbar = &ich9_spi->bbar; +// cntlr.preop = &ich9_spi->preop; +// cntlr.fpr = &ich9_spi->pr[0]; +// cntlr.fpr_max = 5; + +// if (cntlr.hsfs & HSFS_FDV) { +// writel_(4, &ich9_spi->fdoc); +// cntlr.flmap0 = readl_(&ich9_spi->fdod); +// writel_(0x1000, &ich9_spi->fdoc); +// cntlr.flcomp = readl_(&ich9_spi->fdod); +// } +// } + +// ich_set_bbar(0); + +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { +// /* Disable the BIOS write protect so write commands are allowed. */ +// bios_cntl = pci_read_config8(dev, 0xdc); +// /* Deassert SMM BIOS Write Protect Disable. */ +// bios_cntl &= ~(1 << 5); +// pci_write_config8(dev, 0xdc, bios_cntl | 0x1); +// } +// } + +// static int spi_locked(VOID) +// { +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { +// return !!(readw_(&cntlr.ich7_spi->spis) & HSFS_FLOCKDN); +// } else { +// return !!(readw_(&cntlr.ich9_spi->hsfs) & HSFS_FLOCKDN); +// } +// } + +// static VOID spi_init_cb(VOID *unused) +// { +// spi_init(); +// } + +// BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); + +// typedef struct spi_transaction { +// CONST UINT8 *out; +// UINT32 bytesout; +// UINT8 *in; +// UINT32 bytesin; +// UINT8 type; +// UINT8 opcode; +// UINT32 offset; +// } spi_transaction; + +// static inline VOID spi_use_out(spi_transaction *trans, unsigned int bytes) +// { +// trans->out += bytes; +// trans->bytesout -= bytes; +// } + +// static inline VOID spi_use_in(spi_transaction *trans, unsigned int bytes) +// { +// trans->in += bytes; +// trans->bytesin -= bytes; +// } + +// static VOID spi_setup_type(spi_transaction *trans) +// { +// trans->type = 0xFF; + +// /* Try to guess spi type from read/write sizes. */ +// if (trans->bytesin == 0) { +// if (trans->bytesout > 4) +// /* +// * If bytesin = 0 and bytesout > 4, we presume this is +// * a write data operation, which is accompanied by an +// * address. +// */ +// trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; +// else +// trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; +// return; +// } + +// if (trans->bytesout == 1) { /* and bytesin is > 0 */ +// trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; +// return; +// } + +// if (trans->bytesout == 4) { /* and bytesin is > 0 */ +// trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; +// } + +// /* Fast read command is called with 5 bytes instead of 4 */ +// if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { +// trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; +// --trans->bytesout; +// } +// } + +// static int spi_setup_opcode(spi_transaction *trans) +// { +// UINT16 optypes; +// UINT8 opmenu[MENU_BYTES]; + +// trans->opcode = trans->out[0]; +// spi_use_out(trans, 1); +// if (!spi_locked()) { +// /* The lock is off, so just use index 0. */ +// writeb_(trans->opcode, cntlr.opmenu); +// optypes = readw_(cntlr.optype); +// optypes = (optypes & 0xfffc) | (trans->type & 0x3); +// writew_(optypes, cntlr.optype); +// return 0; +// } + +// /* The lock is on. See if what we need is on the menu. */ +// UINT8 optype; +// UINT16 opcode_index; + +// /* Write Enable is handled as atomic prefix */ +// if (trans->opcode == SPI_OPCODE_WREN) +// return 0; + +// read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); +// for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { +// if (opmenu[opcode_index] == trans->opcode) +// break; +// } + +// if (opcode_index == ARRAY_SIZE(opmenu)) { +// printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", +// trans->opcode); +// return -1; +// } + +// optypes = readw_(cntlr.optype); +// optype = (optypes >> (opcode_index * 2)) & 0x3; +// if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && +// optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && +// trans->bytesout >= 3) { +// /* We guessed wrong earlier. Fix it up. */ +// trans->type = optype; +// } +// if (optype != trans->type) { +// printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", +// optype); +// return -1; +// } +// return opcode_index; +// } + +// static int spi_setup_offset(spi_transaction *trans) +// { +// /* Separate the SPI address and data. */ +// switch (trans->type) { +// case SPI_OPCODE_TYPE_READ_NO_ADDRESS: +// case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: +// return 0; +// case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: +// case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: +// trans->offset = ((UINT32)trans->out[0] << 16) | +// ((UINT32)trans->out[1] << 8) | +// ((UINT32)trans->out[2] << 0); +// spi_use_out(trans, 3); +// return 1; +// default: +// printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); +// return -1; +// } +// } + +// /* +// * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set +// * below is True) or 0. In case the wait was for the bit(s) to set - write +// * those bits back, which would cause resetting them. +// * +// * Return the last read status value on success or -1 on failure. +// */ +// static int ich_status_poll(UINT16 bitmask, int wait_til_set) +// { +// int timeout = 600000; /* This will result in 6 seconds */ +// UINT16 status = 0; + +// while (timeout--) { +// status = readw_(cntlr.status); +// if (wait_til_set ^ ((status & bitmask) == 0)) { +// if (wait_til_set) +// writew_((status & bitmask), cntlr.status); +// return status; +// } +// udelay(10); +// } + +// printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, bitmask %x\n", +// status, bitmask); +// return -1; +// } + +// static INT32 spi_is_multichip(VOID) +// { +// if (!(cntlr.hsfs & HSFS_FDV)) +// return 0; +// return !!((cntlr.flmap0 >> 8) & 3); +// } + +// static INT32 spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, +// size_t bytesout, VOID *din, size_t bytesin) +// { +// UINT16 control; +// int16_t opcode_index; +// INT32 with_address; +// INT32 status; + +// spi_transaction trans = { +// dout, bytesout, +// din, bytesin, +// 0xff, 0xff, 0 +// }; + +// /* There has to always at least be an opcode. */ +// if (!bytesout || !dout) { +// printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); +// return -1; +// } +// /* Make sure if we read something we have a place to put it. */ +// if (bytesin != 0 && !din) { +// printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); +// return -1; +// } + +// if (ich_status_poll(SPIS_SCIP, 0) == -1) +// return -1; + +// writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); + +// spi_setup_type(&trans); +// if ((opcode_index = spi_setup_opcode(&trans)) < 0) +// return -1; +// if ((with_address = spi_setup_offset(&trans)) < 0) +// return -1; + +// if (trans.opcode == SPI_OPCODE_WREN) { +// /* +// * Treat Write Enable as Atomic Pre-Op if possible +// * in order to prevent the Management Engine from +// * issuing a transaction between WREN and DATA. +// */ +// if (!spi_locked()) +// writew_(trans.opcode, cntlr.preop); +// return 0; +// } + +// /* Preset control fields */ +// control = SPIC_SCGO | ((opcode_index & 0x07) << 4); + +// /* Issue atomic preop cycle if needed */ +// if (readw_(cntlr.preop)) +// control |= SPIC_ACS; + +// if (!trans.bytesout && !trans.bytesin) { +// /* SPI addresses are 24 bit only */ +// if (with_address) +// writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + +// /* +// * This is a 'no data' command (like Write Enable), its +// * bitesout size was 1, decremented to zero while executing +// * spi_setup_opcode() above. Tell the chip to send the +// * command. +// */ +// writew_(control, cntlr.control); + +// /* wait for the result */ +// status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); +// if (status == -1) +// return -1; + +// if (status & SPIS_FCERR) { +// printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); +// return -1; +// } + +// goto spi_xfer_exit; +// } + +// /* +// * Check if this is a write command attempting to transfer more bytes +// * than the controller can handle. Iterations for writes are not +// * supported here because each SPI write command needs to be preceded +// * and followed by other SPI commands, and this sequence is controlled +// * by the SPI chip driver. +// */ +// if (trans.bytesout > cntlr.databytes) { +// printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" +// " spi_crop_chunk()?\n"); +// return -1; +// } + +// /* +// * Read or write up to databytes bytes at a time until everything has +// * been sent. +// */ +// while (trans.bytesout || trans.bytesin) { +// UINT32 data_length; + +// /* SPI addresses are 24 bit only */ +// writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + +// if (trans.bytesout) +// data_length = MIN(trans.bytesout, cntlr.databytes); +// else +// data_length = MIN(trans.bytesin, cntlr.databytes); + +// /* Program data into FDATA0 to N */ +// if (trans.bytesout) { +// write_reg(trans.out, cntlr.data, data_length); +// spi_use_out(&trans, data_length); +// if (with_address) +// trans.offset += data_length; +// } + +// /* Add proper control fields' values */ +// control &= ~((cntlr.databytes - 1) << 8); +// control |= SPIC_DS; +// control |= (data_length - 1) << 8; + +// /* write it */ +// writew_(control, cntlr.control); + +// /* Wait for Cycle Done Status or Flash Cycle Error. */ +// status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); +// if (status == -1) +// return -1; + +// if (status & SPIS_FCERR) { +// printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); +// return -1; +// } + +// if (trans.bytesin) { +// read_reg(cntlr.data, trans.in, data_length); +// spi_use_in(&trans, data_length); +// if (with_address) +// trans.offset += data_length; +// } +// } + +// spi_xfer_exit: +// /* Clear atomic preop now that xfer is done */ +// writew_(0, cntlr.preop); + +// return 0; +// } + +// /* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ +// static VOID ich_hwseq_set_addr(UINT32 addr) +// { +// UINT32 addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; + +// writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); +// } + +// /* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. +// Resets all error flags in HSFS. +// Returns 0 if the cycle completes successfully without errors within +// timeout us, 1 on errors. */ +// static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, +// unsigned int len) +// { +// UINT16 hsfs; +// UINT32 addr; + +// timeout /= 8; /* scale timeout duration to counter */ +// while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & +// (HSFS_FDONE | HSFS_FCERR)) == 0) && +// --timeout) { +// udelay(8); +// } +// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + +// if (!timeout) { +// UINT16 hsfc; +// addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; +// hsfc = readw_(&cntlr.ich9_spi->hsfc); +// printk(BIOS_ERR, "Transaction timeout between offset 0x%08x and " +// "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", +// addr, addr + len - 1, addr, len - 1, +// hsfc, hsfs); +// return 1; +// } + +// if (hsfs & HSFS_FCERR) { +// UINT16 hsfc; +// addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; +// hsfc = readw_(&cntlr.ich9_spi->hsfc); +// printk(BIOS_ERR, "Transaction error between offset 0x%08x and " +// "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", +// addr, addr + len - 1, addr, len - 1, +// hsfc, hsfs); +// return 1; +// } +// return 0; +// } + + +// static int ich_hwseq_erase(CONST struct spi_flash *flash, UINT32 offset, +// size_t len) +// { +// UINT32 start, end, erase_size; +// int ret; +// UINT16 hsfc; +// unsigned int timeout = 1000 * USECS_PER_MSEC; /* 1 second timeout */ + +// erase_size = flash->sector_size; +// if (offset % erase_size || len % erase_size) { +// printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n"); +// return -1; +// } + +// ret = spi_claim_bus(&flash->spi); +// if (ret) { +// printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); +// return ret; +// } + +// start = offset; +// end = start + len; + +// while (offset < end) { +// /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ +// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + +// ich_hwseq_set_addr(offset); + +// offset += erase_size; + +// hsfc = readw_(&cntlr.ich9_spi->hsfc); +// hsfc &= ~HSFC_FCYCLE; /* clear operation */ +// hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ +// hsfc |= HSFC_FGO; /* start */ +// writew_(hsfc, &cntlr.ich9_spi->hsfc); +// if (ich_hwseq_wait_for_cycle_complete(timeout, len)) { +// printk(BIOS_ERR, "SF: Erase failed at %x\n", offset - erase_size); +// ret = -1; +// goto out; +// } +// } + +// printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start); + +// out: +// spi_release_bus(&flash->spi); +// return ret; +// } + +// static VOID ich_read_data(UINT8 *data, INT32 len) +// { +// INT32 i; +// UINT32 temp32 = 0; + +// for (i = 0; i < len; i++) { +// if ((i % 4) == 0) +// temp32 = readl_(cntlr.data + i); + +// data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; +// } +// } + +// static int ich_hwseq_read(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, +// VOID *buf) +// { +// UINT16 hsfc; +// UINT16 timeout = 100 * 60; +// UINT8 block_len; + +// if (addr + len > flash->size) { +// printk(BIOS_ERR, +// "Attempt to read %x-%x which is out of chip\n", +// (unsigned int) addr, +// (unsigned int) addr+(unsigned int) len); +// return -1; +// } + +// /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ +// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + +// while (len > 0) { +// block_len = MIN(len, cntlr.databytes); +// if (block_len > (~addr & 0xff)) +// block_len = (~addr & 0xff) + 1; +// ich_hwseq_set_addr(addr); +// hsfc = readw_(&cntlr.ich9_spi->hsfc); +// hsfc &= ~HSFC_FCYCLE; /* set read operation */ +// hsfc &= ~HSFC_FDBC; /* clear byte count */ +// /* set byte count */ +// hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); +// hsfc |= HSFC_FGO; /* start */ +// writew_(hsfc, &cntlr.ich9_spi->hsfc); + +// if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) +// return 1; +// ich_read_data(buf, block_len); +// addr += block_len; +// buf += block_len; +// len -= block_len; +// } +// return 0; +// } + +// /* Fill len bytes from the data array into the fdata/spid registers. +// * +// * Note that using len > flash->pgm->spi.max_data_write will trash the registers +// * following the data registers. +// */ +// static VOID ich_fill_data(CONST UINT8 *data, INT32 len) +// { +// UINT32 temp32 = 0; +// INT32 i; + +// if (len <= 0) +// return; + +// for (i = 0; i < len; i++) { +// if ((i % 4) == 0) +// temp32 = 0; + +// temp32 |= ((UINT32) data[i]) << ((i % 4) * 8); + +// if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ +// writel_(temp32, cntlr.data + (i - (i % 4))); +// } +// i--; +// if ((i % 4) != 3) /* Write remaining data to regs. */ +// writel_(temp32, cntlr.data + (i - (i % 4))); +// } + +// static int ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, size_t len, +// CONST VOID *buf) +// { +// UINT16 hsfc; +// UINT16 timeout = 100 * 60; +// UINT8 block_len; +// UINT32 start = addr; + +// if (addr + len > flash->size) { +// printk(BIOS_ERR, +// "Attempt to write 0x%x-0x%x which is out of chip\n", +// (unsigned int)addr, (unsigned int) (addr+len)); +// return -1; +// } + +// /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ +// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + +// while (len > 0) { +// block_len = MIN(len, cntlr.databytes); +// if (block_len > (~addr & 0xff)) +// block_len = (~addr & 0xff) + 1; + +// ich_hwseq_set_addr(addr); + +// ich_fill_data(buf, block_len); +// hsfc = readw_(&cntlr.ich9_spi->hsfc); +// hsfc &= ~HSFC_FCYCLE; /* clear operation */ +// hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ +// hsfc &= ~HSFC_FDBC; /* clear byte count */ +// /* set byte count */ +// hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); +// hsfc |= HSFC_FGO; /* start */ +// writew_(hsfc, &cntlr.ich9_spi->hsfc); + +// if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) { +// printk(BIOS_ERR, "SF: write failure at %x\n", +// addr); +// return -1; +// } +// addr += block_len; +// buf += block_len; +// len -= block_len; +// } +// printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", +// (unsigned int) (addr - start), start); +// return 0; +// } + +// static CONST struct spi_flash_ops spi_flash_ops = { +// .read = ich_hwseq_read, +// .write = ich_hwseq_write, +// .erase = ich_hwseq_erase, +// }; + +// static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, +// struct spi_flash *flash) +// { + +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) +// return spi_flash_generic_probe(spi, flash); + +// /* Try generic probing first if spi_is_multichip returns 0. */ +// if (!spi_is_multichip() && !spi_flash_generic_probe(spi, flash)) +// return 0; + +// memcpy(&flash->spi, spi, sizeof(*spi)); + +// ich_hwseq_set_addr(0); +// switch ((cntlr.hsfs >> 3) & 3) { +// case 0: +// flash->sector_size = 256; +// break; +// case 1: +// flash->sector_size = 4096; +// break; +// case 2: +// flash->sector_size = 8192; +// break; +// case 3: +// flash->sector_size = 65536; +// break; +// } + +// flash->size = 1 << (19 + (cntlr.flcomp & 7)); + +// flash->ops = &spi_flash_ops; + +// if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) +// flash->size += 1 << (19 + ((cntlr.flcomp >> 3) & 7)); +// printk(BIOS_DEBUG, "flash size 0x%x bytes\n", flash->size); + +// return 0; +// } + +// static INT32 xfer_vectors(CONST struct spi_slave *slave, +// struct spi_op vectors[], size_t count) +// { +// return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); +// } + +// #define SPI_FPR_SHIFT 12 +// #define ICH7_SPI_FPR_MASK 0xfff +// #define ICH9_SPI_FPR_MASK 0x1fff +// #define SPI_FPR_BASE_SHIFT 0 +// #define ICH7_SPI_FPR_LIMIT_SHIFT 12 +// #define ICH9_SPI_FPR_LIMIT_SHIFT 16 +// #define ICH9_SPI_FPR_RPE (1 << 15) /* Read Protect */ +// #define SPI_FPR_WPE (1 << 31) /* Write Protect */ + +// static UINT32 spi_fpr(UINT32 base, UINT32 limit) +// { +// UINT32 ret; +// UINT32 mask, limit_shift; + +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { +// mask = ICH7_SPI_FPR_MASK; +// limit_shift = ICH7_SPI_FPR_LIMIT_SHIFT; +// } else { +// mask = ICH9_SPI_FPR_MASK; +// limit_shift = ICH9_SPI_FPR_LIMIT_SHIFT; +// } +// ret = ((limit >> SPI_FPR_SHIFT) & mask) << limit_shift; +// ret |= ((base >> SPI_FPR_SHIFT) & mask) << SPI_FPR_BASE_SHIFT; +// return ret; +// } + +// /* +// * Protect range of SPI flash defined by [start, start+size-1] using Flash +// * Protected Range (FPR) register if available. +// * Returns 0 on success, -1 on failure of programming fpr registers. +// */ +// static int spi_flash_protect(CONST struct spi_flash *flash, +// CONST struct region *region, +// CONST enum ctrlr_prot_type type) +// { +// UINT32 start = region_offset(region); +// UINT32 end = start + region_sz(region) - 1; +// UINT32 reg; +// UINT32 protect_mask = 0; +// INT32 fpr; +// UINT32 *fpr_base; + +// fpr_base = cntlr.fpr; + +// /* Find first empty FPR */ +// for (fpr = 0; fpr < cntlr.fpr_max; fpr++) { +// reg = read32(&fpr_base[fpr]); +// if (reg == 0) +// break; +// } + +// if (fpr == cntlr.fpr_max) { +// printk(BIOS_ERR, "ERROR: No SPI FPR free!\n"); +// return -1; +// } + +// switch (type) { +// case WRITE_PROTECT: +// protect_mask |= SPI_FPR_WPE; +// break; +// case READ_PROTECT: +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) +// return -1; +// protect_mask |= ICH9_SPI_FPR_RPE; +// break; +// case READ_WRITE_PROTECT: +// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) +// return -1; +// protect_mask |= (ICH9_SPI_FPR_RPE | SPI_FPR_WPE); +// break; +// default: +// printk(BIOS_ERR, "ERROR: Seeking invalid protection!\n"); +// return -1; +// } + +// /* Set protected range base and limit */ +// reg = spi_fpr(start, end) | protect_mask; + +// /* Set the FPR register and verify it is protected */ +// write32(&fpr_base[fpr], reg); +// if (reg != read32(&fpr_base[fpr])) { +// printk(BIOS_ERR, "ERROR: Unable to set SPI FPR %d\n", fpr); +// return -1; +// } + +// printk(BIOS_INFO, "%s: FPR %d is enabled for range 0x%08x-0x%08x\n", +// __func__, fpr, start, end); +// return 0; +// } + +// VOID spi_finalize_ops(VOID) +// { +// UINT16 spi_opprefix; +// UINT16 optype = 0; +// struct intel_swseq_spi_config spi_config_default = { +// {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ +// { /* OPCODE and OPTYPE */ +// {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ +// {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ +// {0x03, READ_WITH_ADDR}, /* READ: Read Data */ +// {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ +// {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ +// {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ +// {0xd8, WRITE_WITH_ADDR}, /* BED8: Block Erase 0xd8 */ +// {0x0b, READ_WITH_ADDR}, /* FAST: Fast Read */ +// } +// }; +// struct intel_swseq_spi_config spi_config_aai_write = { +// {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ +// { /* OPCODE and OPTYPE */ +// {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ +// {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ +// {0x03, READ_WITH_ADDR}, /* READ: Read Data */ +// {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ +// {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ +// {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ +// {0xad, WRITE_NO_ADDR}, /* Auto Address Increment Word Program */ +// {0x04, WRITE_NO_ADDR} /* Write Disable */ +// } +// }; +// CONST struct spi_flash *flash = boot_device_spi_flash(); +// struct intel_swseq_spi_config *spi_config = &spi_config_default; +// int i; + +// /* +// * Some older SST SPI flashes support AAI write but use 0xaf opcde for +// * that. Flashrom uses the byte program opcode to write those flashes, +// * so this configuration is fine too. SST25VF064C (id = 0x4b) is an +// * exception. +// */ +// if (flash && flash->vendor == VENDOR_ID_SST && (flash->model & 0x00ff) != 0x4b) +// spi_config = &spi_config_aai_write; + +// if (spi_locked()) +// return; + +// intel_southbridge_override_spi(spi_config); + +// spi_opprefix = spi_config->opprefixes[0] +// | (spi_config->opprefixes[1] << 8); +// writew_(spi_opprefix, cntlr.preop); +// for (i = 0; i < ARRAY_SIZE(spi_config->ops); i++) { +// optype |= (spi_config->ops[i].type & 3) << (i * 2); +// writeb_(spi_config->ops[i].op, &cntlr.opmenu[i]); +// } +// writew_(optype, cntlr.optype); +// } + +// __weak VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) +// { +// } diff --git a/UefiPayloadPkg/SPI/intelSPI.h b/UefiPayloadPkg/SPI/intelSPI.h new file mode 100644 index 000000000000..f03e11c312f0 --- /dev/null +++ b/UefiPayloadPkg/SPI/intelSPI.h @@ -0,0 +1,27 @@ + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef SOUTHBRIDGE_INTEL_SPI_H +#define SOUTHBRIDGE_INTEL_SPI_H + +enum optype { + READ_NO_ADDR = 0, + WRITE_NO_ADDR = 1, + READ_WITH_ADDR = 2, + WRITE_WITH_ADDR = 3 +}; + +struct intel_spi_op { + u8 op; + enum optype type; +}; + +struct intel_swseq_spi_config { + u8 opprefixes[2]; + struct intel_spi_op ops[8]; +}; + +void spi_finalize_ops(void); +void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config); + +#endif From e2d7994f47234e9b14937a54df2f2860f390d5df Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 13:39:38 +0200 Subject: [PATCH 125/297] add files to inf --- UefiPayloadPkg/SPI/SPI.inf | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 9125c4d85eda..338686c19031 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -21,6 +21,8 @@ SPIFvb.c SPIgeneric.h SPIgeneric.c + intelSPI.h + intelSPI.c [Packages] MdePkg/MdePkg.dec From bf3ad5fae2847a8639bd119f3edd80c03646e61b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 13:44:48 +0200 Subject: [PATCH 126/297] try fix --- UefiPayloadPkg/SPI/intelSPI.c | 48 ++--------------------------------- 1 file changed, 2 insertions(+), 46 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 2a203298e7e2..91179e002484 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -23,52 +23,6 @@ #include "SPI.h" #include "SPIgeneric.h" -CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); - -/*----------------------------------------------------------------------- - * Representation of a SPI controller. Note the xfer() and xfer_vector() - * callbacks are meant to process full duplex transactions. If the - * controller cannot handle these transactions then return an error when - * din and dout are both set. See spi_xfer() below for more details. - * - * claim_bus: Claim SPI bus and prepare for communication. - * release_bus: Release SPI bus. - * setup: Setup given SPI device bus. - * xfer: Perform one SPI transfer operation. - * xfer_vector: Vector of SPI transfer operations. - * xfer_dual: (optional) Perform one SPI transfer in Dual SPI mode. - * max_xfer_size: Maximum transfer size supported by the controller - * (0 = invalid, - * SPI_CTRLR_DEFAULT_MAX_XFER_SIZE = unlimited) - * flags: See SPI_CNTRLR_* enums above. - * - * Following member is provided by specialized SPI controllers that are - * actually SPI flash controllers. - * - * flash_probe: Specialized probe function provided by SPI flash - * controllers. - * flash_protect: Protect a region of flash using the SPI flash controller. - -struct spi_ctrlr { - int (*claim_bus)(const struct spi_slave *slave); - void (*release_bus)(const struct spi_slave *slave); - int (*setup)(const struct spi_slave *slave); - int (*xfer)(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin); - int (*xfer_vector)(const struct spi_slave *slave, - struct spi_op vectors[], size_t count); - int (*xfer_dual)(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin); - uint32_t max_xfer_size; - uint32_t flags; - int (*flash_probe)(const struct spi_slave *slave, - struct spi_flash *flash); - int (*flash_protect)(const struct spi_flash *flash, - const struct region *region, - const enum ctrlr_prot_type type); -}; -*/ - static CONST struct spi_ctrlr spi_ctrlr = { .xfer_vector = NULL, .max_xfer_size = 0, @@ -84,6 +38,8 @@ CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { }, }; +CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); + // #define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ // #define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) // #define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ From 61aeabdded2e8c3ed9f4cc2347624f85f59febbe Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 13:52:52 +0200 Subject: [PATCH 127/297] change print format --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index f5ca9234c016..51711241e050 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -56,7 +56,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); - DEBUG((EFI_D_INFO, "spi_setup_slave() returned %i", spi_setup_slave(0, 0, &slave))); + DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X", spi_setup_slave(0, 0, &slave))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, From 6211dfe7b77b9b1951d84036b93e7f9f0818e0ae Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 23 Sep 2020 14:51:45 +0200 Subject: [PATCH 128/297] add some functions to ctrl --- UefiPayloadPkg/SPI/SPI.c | 2 +- UefiPayloadPkg/SPI/intelSPI.c | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 51711241e050..305decb98047 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -56,7 +56,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); - DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X", spi_setup_slave(0, 0, &slave))); + DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 91179e002484..332bb627ef2b 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -23,11 +23,42 @@ #include "SPI.h" #include "SPIgeneric.h" +/*----------------------------------------------------------------------- + * Representation of a SPI controller. Note the xfer() and xfer_vector() + * callbacks are meant to process full duplex transactions. If the + * controller cannot handle these transactions then return an error when + * din and dout are both set. See spi_xfer() below for more details. + * + * claim_bus: Claim SPI bus and prepare for communication. + * release_bus: Release SPI bus. + * setup: Setup given SPI device bus. + * xfer: Perform one SPI transfer operation. + * xfer_vector: Vector of SPI transfer operations. + * xfer_dual: (optional) Perform one SPI transfer in Dual SPI mode. + * max_xfer_size: Maximum transfer size supported by the controller + * (0 = invalid, + * SPI_CTRLR_DEFAULT_MAX_XFER_SIZE = unlimited) + * flags: See SPI_CNTRLR_* enums above. + * + * Following member is provided by specialized SPI controllers that are + * actually SPI flash controllers. + * + * flash_probe: Specialized probe function provided by SPI flash + * controllers. + * flash_protect: Protect a region of flash using the SPI flash controller. + */ + static CONST struct spi_ctrlr spi_ctrlr = { + .claim_bus = spi_claim_bus, + .release_bus = spi_release_bus, + .setup = NULL, + .xfer = NULL, .xfer_vector = NULL, + .xfer_dual = NULL, .max_xfer_size = 0, + .flags = 0, .flash_probe = NULL, - .flash_protect = NULL, + .flash_protect = NULL }; CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { From 3da0e4a925e7472032127d39e88af66adf9e8242 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 11:51:58 +0200 Subject: [PATCH 129/297] implement spi controler --- UefiPayloadPkg/SPI/SPI.h | 17 + UefiPayloadPkg/SPI/SPI.inf | 1 + UefiPayloadPkg/SPI/SPIgeneric.h | 24 +- UefiPayloadPkg/SPI/helpers.h | 86 ++ UefiPayloadPkg/SPI/intelSPI.c | 2316 ++++++++++++++++--------------- 5 files changed, 1356 insertions(+), 1088 deletions(-) create mode 100644 UefiPayloadPkg/SPI/helpers.h diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 1bc2934a6267..d8f6db56d393 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -49,6 +49,23 @@ struct _SMMSTORE_INSTANCE { NOR_FLASH_DEVICE_PATH DevicePath; }; +enum optype { + READ_NO_ADDR = 0, + WRITE_NO_ADDR = 1, + READ_WITH_ADDR = 2, + WRITE_WITH_ADDR = 3 +}; + +struct intel_spi_op { + UINT8 op; + enum optype type; +}; + +struct intel_swseq_spi_config { + UINT8 opprefixes[2]; + struct intel_spi_op ops[8]; +}; + void * memset (void *dest, int ch, __SIZE_TYPE__ count); // diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 338686c19031..18cda5cef498 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -23,6 +23,7 @@ SPIgeneric.c intelSPI.h intelSPI.c + helpers.h [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index 8cad692a281e..087d58a06a27 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -103,7 +103,29 @@ struct spi_cfg { */ #define SPI_CTRLR_DEFAULT_MAX_XFER_SIZE (UINT32_MAX) -struct spi_flash; +struct spi_flash { + struct spi_slave spi; + UINT8 vendor; + union { + UINT8 raw; + struct { + UINT8 dual_spi : 1; + UINT8 _reserved : 7; + }; + } flags; + UINT16 model; + UINT32 size; + UINT32 sector_size; + UINT32 page_size; + UINT8 erase_cmd; + UINT8 status_cmd; + UINT8 pp_cmd; /* Page program command. */ + UINT8 wren_cmd; /* Write Enable command. */ + const struct spi_flash_ops *ops; + /* If !NULL all protection callbacks exist. */ + const struct spi_flash_protection_ops *prot_ops; + const struct spi_flash_part_id *part; +}; enum ctrlr_prot_type { READ_PROTECT = 1, diff --git a/UefiPayloadPkg/SPI/helpers.h b/UefiPayloadPkg/SPI/helpers.h new file mode 100644 index 000000000000..692bc48d0467 --- /dev/null +++ b/UefiPayloadPkg/SPI/helpers.h @@ -0,0 +1,86 @@ +/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ + +#ifndef COMMONLIB_BSD_HELPERS_H +#define COMMONLIB_BSD_HELPERS_H + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#endif + +#define ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1UL) +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) +#define ALIGN_UP(x, a) ALIGN((x), (a)) +#define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) +#define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) + +/* Double-evaluation unsafe min/max, for bitfields and outside of functions */ +#define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b)) +#define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <) +#define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >) + +#define __CMP_SAFE(a, b, op, var_a, var_b) ({ \ + __TYPEOF_UNLESS_CONST(a, b) var_a = (a); \ + __TYPEOF_UNLESS_CONST(b, a) var_b = (b); \ + var_a op var_b ? var_a : var_b; \ +}) + +#define __CMP(a, b, op) __builtin_choose_expr( \ + __builtin_constant_p(a) && __builtin_constant_p(b), \ + __CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME)) + +#ifndef MIN +#define MIN(a, b) __CMP(a, b, <) +#endif +#ifndef MAX +#define MAX(a, b) __CMP(a, b, >) +#endif + +#ifndef ABS +#define ABS(a) ({ \ + __typeof__(a) _abs_local_a = (a); \ + (_abs_local_a < 0) ? (-_abs_local_a) : _abs_local_a; \ +}) +#endif + +#define IS_POWER_OF_2(x) ({ \ + __typeof__(x) _power_local_x = (x); \ + (_power_local_x & (_power_local_x - 1)) == 0; \ +}) + +#define POWER_OF_2(x) (1ULL << (x)) + +#define DIV_ROUND_UP(x, y) ({ \ + __typeof__(x) _div_local_x = (x); \ + __typeof__(y) _div_local_y = (y); \ + (_div_local_x + _div_local_y - 1) / _div_local_y; \ +}) + +#define SWAP(a, b) do { \ + __typeof__(&(a)) _swap_local_a = &(a); \ + __typeof__(&(b)) _swap_local_b = &(b); \ + __typeof__(a) _swap_local_tmp = *_swap_local_a; \ + *_swap_local_a = *_swap_local_b; \ + *_swap_local_b = _swap_local_tmp; \ +} while (0) + +/* Standard units. */ +#define KiB (1<<10) +#define MiB (1<<20) +#define GiB (1<<30) + +#define KHz (1000) +#define MHz (1000 * KHz) +#define GHz (1000 * MHz) + +#ifndef offsetof +#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) +#endif + +#define check_member(structure, member, offset) _Static_assert( \ + offsetof(struct structure, member) == offset, \ + "`struct " #structure "` offset for `" #member "` is not " #offset) + +/* Calculate size of structure member. */ +#define member_size(type, member) (sizeof(((type *)0)->member)) + +#endif /* COMMONLIB_BSD_HELPERS_H */ diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 332bb627ef2b..224fd9b41f84 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -22,6 +22,1209 @@ #include #include "SPI.h" #include "SPIgeneric.h" +#include "helpers.h" + +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#define __SIMPLE_DEVICE__ + +#define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ +#define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) +#define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ +#define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) + +/* SPI Flash opcodes */ +#define SPI_OPCODE_WREN 0x06 +#define SPI_OPCODE_FAST_READ 0x0b + +#define NSECS_PER_SEC 1000000000 +#define USECS_PER_SEC 1000000 +#define MSECS_PER_SEC 1000 +#define USECS_PER_MSEC (USECS_PER_SEC / MSECS_PER_SEC) + +#define __ARG_PLACEHOLDER_1 0, +#define config_enabled(cfg) _config_enabled(cfg) +#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) +#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0, 0) +#define ___config_enabled(__ignored, val, ...) val +#define CONFIG(option) config_enabled(CONFIG_##option) + +#if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) +#define MENU_BYTES member_size(struct ich7_spi_regs, opmenu) +#else +#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) +#endif + +typedef enum { + BS_PRE_DEVICE, + BS_DEV_INIT_CHIPS, + BS_DEV_ENUMERATE, + BS_DEV_RESOURCES, + BS_DEV_ENABLE, + BS_DEV_INIT, + BS_POST_DEVICE, + BS_OS_RESUME_CHECK, + BS_OS_RESUME, + BS_WRITE_TABLES, + BS_PAYLOAD_LOAD, + BS_PAYLOAD_BOOT, +} boot_state_t; + +typedef enum { + BS_ON_ENTRY, + BS_ON_EXIT +} boot_state_sequence_t; + +struct boot_state_callback { + void *arg; + void (*callback)(void *arg); + /* For use internal to the boot state machine. */ + struct boot_state_callback *next; +}; + +struct boot_state_init_entry { + boot_state_t state; + boot_state_sequence_t when; + struct boot_state_callback bscb; +}; + +#define BOOT_STATE_CALLBACK_INIT(func_, arg_) \ + { \ + .arg = arg_, \ + .callback = func_, \ + .next = NULL, \ + } + + +#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \ + static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \ + { \ + .state = state_, \ + .when = when_, \ + .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \ + }; \ + static struct boot_state_init_entry * \ + bsie_ ## func_ ##_## state_ ##_## when_; \ + BOOT_STATE_INIT_ATTR = \ + &func_ ##_## state_ ##_## when_; + +static INT32 spi_is_multichip(VOID); + +typedef UINT32 pci_devfn_t; + +/* + * Representation of SPI flash operations: + * read: Flash read operation. + * write: Flash write operation. + * erase: Flash erase operation. + * status: Read flash status register. + */ +struct spi_flash_ops { + int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + VOID *buf); + int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + CONST VOID *buf); + int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + int (*status)(CONST struct spi_flash *flash, UINT8 *reg); +}; + +struct ich7_spi_regs { + UINT16 spis; + UINT16 spic; + UINT32 spia; + UINT64 spid[8]; + UINT64 _pad; + UINT32 bbar; + UINT16 preop; + UINT16 optype; + UINT8 opmenu[8]; + UINT32 pbr[3]; +} __packed; + +struct ich9_spi_regs { + UINT32 bfpr; + UINT16 hsfs; + UINT16 hsfc; + UINT32 faddr; + UINT32 _reserved0; + UINT32 fdata[16]; + UINT32 frap; + UINT32 freg[5]; + UINT32 _reserved1[3]; + UINT32 pr[5]; + UINT32 _reserved2[2]; + UINT8 ssfs; + UINT8 ssfc[3]; + UINT16 preop; + UINT16 optype; + UINT8 opmenu[8]; + UINT32 bbar; + UINT8 _reserved3[12]; + UINT32 fdoc; + UINT32 fdod; + UINT8 _reserved4[8]; + UINT32 afc; + UINT32 lvscc; + UINT32 uvscc; + UINT8 _reserved5[4]; + UINT32 fpb; + UINT8 _reserved6[28]; + UINT32 srdl; + UINT32 srdc; + UINT32 srd; +} __packed; + +struct ich_spi_controller { + INT32 locked; + UINT32 flmap0; + UINT32 flcomp; + UINT32 hsfs; + + union { + struct ich9_spi_regs *ich9_spi; + struct ich7_spi_regs *ich7_spi; + }; + UINT8 *opmenu; + INT32 menubytes; + UINT16 *preop; + UINT16 *optype; + UINT32 *addr; + UINT8 *data; + UINT32 databytes; + UINT8 *status; + UINT16 *control; + UINT32 *bbar; + UINT32 *fpr; + UINT8 fpr_max; +}; + +static struct ich_spi_controller cntlr; + +enum { + SPIS_SCIP = 0x0001, + SPIS_GRANT = 0x0002, + SPIS_CDS = 0x0004, + SPIS_FCERR = 0x0008, + SSFS_AEL = 0x0010, + SPIS_LOCK = 0x8000, + SPIS_RESERVED_MASK = 0x7ff0, + SSFS_RESERVED_MASK = 0x7fe2 +}; + +enum { + SPIC_SCGO = 0x000002, + SPIC_ACS = 0x000004, + SPIC_SPOP = 0x000008, + SPIC_DBC = 0x003f00, + SPIC_DS = 0x004000, + SPIC_SME = 0x008000, + SSFC_SCF_MASK = 0x070000, + SSFC_RESERVED = 0xf80000 +}; + +enum { + HSFS_FDONE = 0x0001, + HSFS_FCERR = 0x0002, + HSFS_AEL = 0x0004, + HSFS_BERASE_MASK = 0x0018, + HSFS_BERASE_SHIFT = 3, + HSFS_SCIP = 0x0020, + HSFS_FDOPSS = 0x2000, + HSFS_FDV = 0x4000, + HSFS_FLOCKDN = 0x8000 +}; + +enum { + HSFC_FGO = 0x0001, + HSFC_FCYCLE_MASK = 0x0006, + HSFC_FCYCLE_SHIFT = 1, + HSFC_FDBC_MASK = 0x3f00, + HSFC_FDBC_SHIFT = 8, + HSFC_FSMIE = 0x8000 +}; + +enum { + SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, + SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, + SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, + SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 +}; + +#define DEBUG_SPI_FLASH + +#ifdef DEBUG_SPI_FLASH + +static UINT8 readb_(CONST VOID *addr) +{ + UINT8 v = read8(addr); + + DEBUG((EFI_D_INFO, "%a read %2.2x from %4.4x\n", + __FUNCTION__, v, ((UINT32) addr & 0xffff) - 0xf020)); + return v; +} + +static UINT16 readw_(CONST VOID *addr) +{ + UINT16 v = read16(addr); + + DEBUG((EFI_D_INFO, "%a read %4.4x from %4.4x\n", + __FUNCTION__, v, ((UINT32) addr & 0xffff) - 0xf020)); + return v; +} + +static UINT32 readl_(CONST VOID *addr) +{ + UINT32 v = read32(addr); + + DEBUG((EFI_D_INFO, "%a read %8.8x from %4.4x\n", + __FUNCTION__, v, ((UINT32) addr & 0xffff) - 0xf020)); + return v; +} + +static VOID writeb_(UINT8 b, VOID *addr) +{ + write8(addr, b); + DEBUG((EFI_D_INFO, "%a wrote %2.2x to %4.4x\n", + __FUNCTION__, b, ((UINT32) addr & 0xffff) - 0xf020)); +} + +static VOID writew_(UINT16 b, VOID *addr) +{ + write16(addr, b); + DEBUG((EFI_D_INFO, "%a wrote %4.4x to %4.4x\n", + __FUNCTION__, b, ((UINT32) addr & 0xffff) - 0xf020)); +} + +static VOID writel_(UINT32 b, VOID *addr) +{ + write32(addr, b); + DEBUG((EFI_D_INFO, "%a wrote %8.8x to %4.4x\n", + __FUNCTION__, b, ((UINT32) addr & 0xffff) - 0xf020)); +} + +#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ + +#define readb_(a) read8(a) +#define readw_(a) read16(a) +#define readl_(a) read32(a) +#define writeb_(val, addr) write8(addr, val) +#define writew_(val, addr) write16(addr, val) +#define writel_(val, addr) write32(addr, val) + +#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ + +static VOID write_reg(CONST VOID *value, VOID *dest, UINT32 size) +{ + CONST UINT8 *bvalue = value; + UINT8 *bdest = dest; + + while (size >= 4) { + writel_(*(CONST UINT32 *)bvalue, bdest); + bdest += 4; bvalue += 4; size -= 4; + } + while (size) { + writeb_(*bvalue, bdest); + bdest++; bvalue++; size--; + } +} + +static VOID read_reg(CONST VOID *src, VOID *value, UINT32 size) +{ + CONST UINT8 *bsrc = src; + UINT8 *bvalue = value; + + while (size >= 4) { + *(UINT32 *)bvalue = readl_(bsrc); + bsrc += 4; bvalue += 4; size -= 4; + } + while (size) { + *bvalue = readb_(bsrc); + bsrc++; bvalue++; size--; + } +} + +static VOID ich_set_bbar(UINT32 minaddr) +{ + CONST UINT32 bbar_mask = 0x00ffff00; + UINT32 ichspi_bbar; + + minaddr &= bbar_mask; + ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; + ichspi_bbar |= minaddr; + writel_(ichspi_bbar, cntlr.bbar); +} + +#if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) +#define MENU_BYTES member_size(struct ich7_spi_regs, opmenu) +#else +#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) +#endif + +#define RCBA 0xf0 +#define SBASE 0x54 + +static VOID *get_spi_bar(pci_devfn_t dev) +{ + uintptr_t rcba; /* Root Complex Register Block */ + uintptr_t sbase; + + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { + rcba = pci_read_config32(dev, RCBA); + return (VOID *)((rcba & 0xffffc000) + 0x3020); + } + if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT)) { + sbase = pci_read_config32(dev, SBASE); + sbase &= ~0x1ff; + return (VOID *)sbase; + } + if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { + rcba = pci_read_config32(dev, RCBA); + return (VOID *)((rcba & 0xffffc000) + 0x3800); + } +} + +VOID spi_init(VOID) +{ + UINT8 bios_cntl; + struct ich9_spi_regs *ich9_spi; + struct ich7_spi_regs *ich7_spi; + UINT16 hsfs; + + pci_devfn_t dev = PCI_DEV(0, 31, 0); + + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { + ich7_spi = get_spi_bar(dev); + cntlr.ich7_spi = ich7_spi; + cntlr.opmenu = ich7_spi->opmenu; + cntlr.menubytes = sizeof(ich7_spi->opmenu); + cntlr.optype = &ich7_spi->optype; + cntlr.addr = &ich7_spi->spia; + cntlr.data = (UINT8 *)ich7_spi->spid; + cntlr.databytes = sizeof(ich7_spi->spid); + cntlr.status = (UINT8 *)&ich7_spi->spis; + cntlr.control = &ich7_spi->spic; + cntlr.bbar = &ich7_spi->bbar; + cntlr.preop = &ich7_spi->preop; + cntlr.fpr = &ich7_spi->pbr[0]; + cntlr.fpr_max = 3; + } else { + ich9_spi = get_spi_bar(dev); + cntlr.ich9_spi = ich9_spi; + hsfs = readw_(&ich9_spi->hsfs); + cntlr.hsfs = hsfs; + cntlr.opmenu = ich9_spi->opmenu; + cntlr.menubytes = sizeof(ich9_spi->opmenu); + cntlr.optype = &ich9_spi->optype; + cntlr.addr = &ich9_spi->faddr; + cntlr.data = (UINT8 *)ich9_spi->fdata; + cntlr.databytes = sizeof(ich9_spi->fdata); + cntlr.status = &ich9_spi->ssfs; + cntlr.control = (UINT16 *)ich9_spi->ssfc; + cntlr.bbar = &ich9_spi->bbar; + cntlr.preop = &ich9_spi->preop; + cntlr.fpr = &ich9_spi->pr[0]; + cntlr.fpr_max = 5; + + if (cntlr.hsfs & HSFS_FDV) { + writel_(4, &ich9_spi->fdoc); + cntlr.flmap0 = readl_(&ich9_spi->fdod); + writel_(0x1000, &ich9_spi->fdoc); + cntlr.flcomp = readl_(&ich9_spi->fdod); + } + } + + ich_set_bbar(0); + + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { + /* Disable the BIOS write protect so write commands are allowed. */ + bios_cntl = pci_read_config8(dev, 0xdc); + /* Deassert SMM BIOS Write Protect Disable. */ + bios_cntl &= ~(1 << 5); + pci_write_config8(dev, 0xdc, bios_cntl | 0x1); + } +} + +static INT32 spi_locked(VOID) +{ + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { + return !!(readw_(&cntlr.ich7_spi->spis) & HSFS_FLOCKDN); + } else { + return !!(readw_(&cntlr.ich9_spi->hsfs) & HSFS_FLOCKDN); + } +} + +static VOID spi_init_cb(VOID *unused) +{ + spi_init(); +} + +BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); + +typedef struct spi_transaction { + CONST UINT8 *out; + UINT32 bytesout; + UINT8 *in; + UINT32 bytesin; + UINT8 type; + UINT8 opcode; + UINT32 offset; +} spi_transaction; + +static inline VOID spi_use_out(spi_transaction *trans, UINT32 bytes) +{ + trans->out += bytes; + trans->bytesout -= bytes; +} + +static inline VOID spi_use_in(spi_transaction *trans, UINT32 bytes) +{ + trans->in += bytes; + trans->bytesin -= bytes; +} + +static VOID spi_setup_type(spi_transaction *trans) +{ + trans->type = 0xFF; + + /* Try to guess spi type from read/write sizes. */ + if (trans->bytesin == 0) { + if (trans->bytesout > 4) + /* + * If bytesin = 0 and bytesout > 4, we presume this is + * a write data operation, which is accompanied by an + * address. + */ + trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; + else + trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; + return; + } + + if (trans->bytesout == 1) { /* and bytesin is > 0 */ + trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; + return; + } + + if (trans->bytesout == 4) { /* and bytesin is > 0 */ + trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; + } + + /* Fast read command is called with 5 bytes instead of 4 */ + if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { + trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; + --trans->bytesout; + } +} + +static INT32 spi_setup_opcode(spi_transaction *trans) +{ + UINT16 optypes; + UINT8 opmenu[MENU_BYTES]; + + trans->opcode = trans->out[0]; + spi_use_out(trans, 1); + if (!spi_locked()) { + /* The lock is off, so just use index 0. */ + writeb_(trans->opcode, cntlr.opmenu); + optypes = readw_(cntlr.optype); + optypes = (optypes & 0xfffc) | (trans->type & 0x3); + writew_(optypes, cntlr.optype); + return 0; + } + + /* The lock is on. See if what we need is on the menu. */ + UINT8 optype; + UINT16 opcode_index; + + /* Write Enable is handled as atomic prefix */ + if (trans->opcode == SPI_OPCODE_WREN) + return 0; + + read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); + for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { + if (opmenu[opcode_index] == trans->opcode) + break; + } + + if (opcode_index == ARRAY_SIZE(opmenu)) { + DEBUG((EFI_D_INFO, "%a ICH SPI: Opcode %x not found\n", + __FUNCTION__, trans->opcode)); + return -1; + } + + optypes = readw_(cntlr.optype); + optype = (optypes >> (opcode_index * 2)) & 0x3; + if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && + optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && + trans->bytesout >= 3) { + /* We guessed wrong earlier. Fix it up. */ + trans->type = optype; + } + if (optype != trans->type) { + DEBUG((EFI_D_INFO, "%a ICH SPI: Transaction doesn't fit type %d\n", + __FUNCTION__, optype)); + return -1; + } + return opcode_index; +} + +static INT32 spi_setup_offset(spi_transaction *trans) +{ + /* Separate the SPI address and data. */ + switch (trans->type) { + case SPI_OPCODE_TYPE_READ_NO_ADDRESS: + case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: + return 0; + case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: + case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: + trans->offset = ((UINT32)trans->out[0] << 16) | + ((UINT32)trans->out[1] << 8) | + ((UINT32)trans->out[2] << 0); + spi_use_out(trans, 3); + return 1; + default: + DEBUG((EFI_D_INFO, "%a Unrecognized SPI transaction type %#x\n", __FUNCTION__, trans->type)); + return -1; + } +} + +/* + * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set + * below is True) or 0. In case the wait was for the bit(s) to set - write + * those bits back, which would cause resetting them. + * + * Return the last read status value on success or -1 on failure. + */ +static INT32 ich_status_poll(UINT16 bitmask, INT32 wait_til_set) +{ + INT32 timeout = 600000; /* This will result in 6 seconds */ + UINT16 status = 0; + + while (timeout--) { + status = readw_(cntlr.status); + if (wait_til_set ^ ((status & bitmask) == 0)) { + if (wait_til_set) + writew_((status & bitmask), cntlr.status); + return status; + } + udelay(10); + } + + DEBUG((EFI_D_INFO, "%a ICH SPI: SCIP timeout, read %x, bitmask %x\n", + __FUNCTION__, status, bitmask)); + return -1; +} + +static INT32 spi_is_multichip(VOID) +{ + if (!(cntlr.hsfs & HSFS_FDV)) + return 0; + return !!((cntlr.flmap0 >> 8) & 3); +} + +static INT32 spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) +{ + UINT16 control; + int16_t opcode_index; + INT32 with_address; + INT32 status; + + spi_transaction trans = { + dout, bytesout, + din, bytesin, + 0xff, 0xff, 0 + }; + + /* There has to always at least be an opcode. */ + if (!bytesout || !dout) { + DEBUG((EFI_D_INFO, "%a ICH SPI: No opcode for transfer\n", __FUNCTION__));; + return -1; + } + /* Make sure if we read something we have a place to put it. */ + if (bytesin != 0 && !din) { + DEBUG((EFI_D_INFO, "%a ICH SPI: Read but no target buffer\n", __FUNCTION__));; + return -1; + } + + if (ich_status_poll(SPIS_SCIP, 0) == -1) + return -1; + + writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); + + spi_setup_type(&trans); + if ((opcode_index = spi_setup_opcode(&trans)) < 0) + return -1; + if ((with_address = spi_setup_offset(&trans)) < 0) + return -1; + + if (trans.opcode == SPI_OPCODE_WREN) { + /* + * Treat Write Enable as Atomic Pre-Op if possible + * in order to prevent the Management Engine from + * issuing a transaction between WREN and DATA. + */ + if (!spi_locked()) + writew_(trans.opcode, cntlr.preop); + return 0; + } + + /* Preset control fields */ + control = SPIC_SCGO | ((opcode_index & 0x07) << 4); + + /* Issue atomic preop cycle if needed */ + if (readw_(cntlr.preop)) + control |= SPIC_ACS; + + if (!trans.bytesout && !trans.bytesin) { + /* SPI addresses are 24 bit only */ + if (with_address) + writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + + /* + * This is a 'no data' command (like Write Enable), its + * bitesout size was 1, decremented to zero while executing + * spi_setup_opcode() above. Tell the chip to send the + * command. + */ + writew_(control, cntlr.control); + + /* wait for the result */ + status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); + if (status == -1) + return -1; + + if (status & SPIS_FCERR) { + DEBUG((EFI_D_INFO, "%a ICH SPI: Command transaction error\n", __FUNCTION__));; + return -1; + } + + goto spi_xfer_exit; + } + + /* + * Check if this is a write command attempting to transfer more bytes + * than the controller can handle. Iterations for writes are not + * supported here because each SPI write command needs to be preceded + * and followed by other SPI commands, and this sequence is controlled + * by the SPI chip driver. + */ + if (trans.bytesout > cntlr.databytes) { + DEBUG((EFI_D_INFO, "%a ICH SPI: Too much to write. Does your SPI chip driver use" + " spi_crop_chunk()?\n", __FUNCTION__)); + return -1; + } + + /* + * Read or write up to databytes bytes at a time until everything has + * been sent. + */ + while (trans.bytesout || trans.bytesin) { + UINT32 data_length; + + /* SPI addresses are 24 bit only */ + writel_(trans.offset & 0x00FFFFFF, cntlr.addr); + + if (trans.bytesout) + data_length = MIN(trans.bytesout, cntlr.databytes); + else + data_length = MIN(trans.bytesin, cntlr.databytes); + + /* Program data into FDATA0 to N */ + if (trans.bytesout) { + write_reg(trans.out, cntlr.data, data_length); + spi_use_out(&trans, data_length); + if (with_address) + trans.offset += data_length; + } + + /* Add proper control fields' values */ + control &= ~((cntlr.databytes - 1) << 8); + control |= SPIC_DS; + control |= (data_length - 1) << 8; + + /* write it */ + writew_(control, cntlr.control); + + /* Wait for Cycle Done Status or Flash Cycle Error. */ + status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); + if (status == -1) + return -1; + + if (status & SPIS_FCERR) { + DEBUG((EFI_D_INFO, "%a ICH SPI: Data transaction error\n", __FUNCTION__));; + return -1; + } + + if (trans.bytesin) { + read_reg(cntlr.data, trans.in, data_length); + spi_use_in(&trans, data_length); + if (with_address) + trans.offset += data_length; + } + } + +spi_xfer_exit: + /* Clear atomic preop now that xfer is done */ + writew_(0, cntlr.preop); + + return 0; +} + +/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ +static VOID ich_hwseq_set_addr(UINT32 addr) +{ + UINT32 addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; + + writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); +} + +/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. + Resets all error flags in HSFS. + Returns 0 if the cycle completes successfully without errors within + timeout us, 1 on errors. */ +static INT32 ich_hwseq_wait_for_cycle_complete(UINT32 timeout, + UINT32 len) +{ + UINT16 hsfs; + UINT32 addr; + + timeout /= 8; /* scale timeout duration to counter */ + while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & + (HSFS_FDONE | HSFS_FCERR)) == 0) && + --timeout) { + udelay(8); + } + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + if (!timeout) { + UINT16 hsfc; + addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; + hsfc = readw_(&cntlr.ich9_spi->hsfc); + DEBUG((EFI_D_INFO, "%a Transaction timeout between offset 0x%08x and " + "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", + __FUNCTION__, + addr, addr + len - 1, addr, len - 1, + hsfc, hsfs)); + return 1; + } + + if (hsfs & HSFS_FCERR) { + UINT16 hsfc; + addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; + hsfc = readw_(&cntlr.ich9_spi->hsfc); + DEBUG((EFI_D_INFO, "%a Transaction error between offset 0x%08x and " + "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", + __FUNCTION__, + addr, addr + len - 1, addr, len - 1, + hsfc, hsfs)); + return 1; + } + return 0; +} + + +static INT32 ich_hwseq_erase(CONST struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len) +{ + UINT32 start, end, erase_size; + INT32 ret; + UINT16 hsfc; + UINT32 timeout = 1000 * USECS_PER_MSEC; /* 1 second timeout */ + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { + DEBUG((EFI_D_INFO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); + return -1; + } + + ret = spi_claim_bus(&flash->spi); + if (ret) { + DEBUG((EFI_D_INFO, "%a SF: Unable to claim SPI bus\n", __FUNCTION__)); + return ret; + } + + start = offset; + end = start + len; + + while (offset < end) { + /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + ich_hwseq_set_addr(offset); + + offset += erase_size; + + hsfc = readw_(&cntlr.ich9_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* clear operation */ + hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.ich9_spi->hsfc); + if (ich_hwseq_wait_for_cycle_complete(timeout, len)) { + DEBUG((EFI_D_INFO, "%a SF: Erase failed at %x\n", __FUNCTION__, offset - erase_size)); + ret = -1; + goto out; + } + } + + DEBUG((EFI_D_INFO, "%a SF: Successfully erased %zu bytes @ %#x\n", __FUNCTION__, len, start)); + +out: + spi_release_bus(&flash->spi); + return ret; +} + +static VOID ich_read_data(UINT8 *data, INT32 len) +{ + INT32 i; + UINT32 temp32 = 0; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + temp32 = readl_(cntlr.data + i); + + data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; + } +} + +static INT32 ich_hwseq_read(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, + VOID *buf) +{ + UINT16 hsfc; + UINT16 timeout = 100 * 60; + UINT8 block_len; + + if (addr + len > flash->size) { + DEBUG((EFI_D_INFO, "%a Attempt to read %x-%x which is out of chip\n", + __FUNCTION__, + (UINT32) addr, + (UINT32) addr+(UINT32) len)); + return -1; + } + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + while (len > 0) { + block_len = MIN(len, cntlr.databytes); + if (block_len > (~addr & 0xff)) + block_len = (~addr & 0xff) + 1; + ich_hwseq_set_addr(addr); + hsfc = readw_(&cntlr.ich9_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* set read operation */ + hsfc &= ~HSFC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.ich9_spi->hsfc); + + if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) + return 1; + ich_read_data(buf, block_len); + addr += block_len; + buf += block_len; + len -= block_len; + } + return 0; +} + +/* Fill len bytes from the data array into the fdata/spid registers. + * + * Note that using len > flash->pgm->spi.max_data_write will trash the registers + * following the data registers. + */ +static VOID ich_fill_data(CONST UINT8 *data, INT32 len) +{ + UINT32 temp32 = 0; + INT32 i; + + if (len <= 0) + return; + + for (i = 0; i < len; i++) { + if ((i % 4) == 0) + temp32 = 0; + + temp32 |= ((UINT32) data[i]) << ((i % 4) * 8); + + if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ + writel_(temp32, cntlr.data + (i - (i % 4))); + } + i--; + if ((i % 4) != 3) /* Write remaining data to regs. */ + writel_(temp32, cntlr.data + (i - (i % 4))); +} + +static INT32 ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, + CONST VOID *buf) +{ + UINT16 hsfc; + UINT16 timeout = 100 * 60; + UINT8 block_len; + UINT32 start = addr; + + if (addr + len > flash->size) { + DEBUG((EFI_D_INFO, "%a Attempt to write 0x%x-0x%x which is out of chip\n", + __FUNCTION__, (UINT32)addr, (UINT32) (addr+len))); + return -1; + } + + /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ + writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); + + while (len > 0) { + block_len = MIN(len, cntlr.databytes); + if (block_len > (~addr & 0xff)) + block_len = (~addr & 0xff) + 1; + + ich_hwseq_set_addr(addr); + + ich_fill_data(buf, block_len); + hsfc = readw_(&cntlr.ich9_spi->hsfc); + hsfc &= ~HSFC_FCYCLE; /* clear operation */ + hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ + hsfc &= ~HSFC_FDBC; /* clear byte count */ + /* set byte count */ + hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); + hsfc |= HSFC_FGO; /* start */ + writew_(hsfc, &cntlr.ich9_spi->hsfc); + + if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) { + DEBUG((EFI_D_INFO, "%a SF: write failure at %x\n", + __FUNCTION__, addr)); + return -1; + } + addr += block_len; + buf += block_len; + len -= block_len; + } + DEBUG((EFI_D_INFO, "%a SF: Successfully written %u bytes @ %#x\n", + __FUNCTION__, (UINT32) (addr - start), start)); + return 0; +} + +static CONST struct spi_flash_ops spi_flash_ops = { + .read = ich_hwseq_read, + .write = ich_hwseq_write, + .erase = ich_hwseq_erase, +}; + +static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, + struct spi_flash *flash) +{ + + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) + return spi_flash_generic_probe(spi, flash); + + /* Try generic probing first if spi_is_multichip returns 0. */ + if (!spi_is_multichip() && !spi_flash_generic_probe(spi, flash)) + return 0; + + memcpy(&flash->spi, spi, sizeof(*spi)); + + ich_hwseq_set_addr(0); + switch ((cntlr.hsfs >> 3) & 3) { + case 0: + flash->sector_size = 256; + break; + case 1: + flash->sector_size = 4096; + break; + case 2: + flash->sector_size = 8192; + break; + case 3: + flash->sector_size = 65536; + break; + } + + flash->size = 1 << (19 + (cntlr.flcomp & 7)); + + flash->ops = &spi_flash_ops; + + if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) + flash->size += 1 << (19 + ((cntlr.flcomp >> 3) & 7)); + DEBUG((EFI_D_INFO, "%a flash size 0x%x bytes\n", __FUNCTION__, flash->size)); + + return 0; +} + +static INT32 xfer_vectors(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count) +{ + return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); +} + +#define SPI_FPR_SHIFT 12 +#define ICH7_SPI_FPR_MASK 0xfff +#define ICH9_SPI_FPR_MASK 0x1fff +#define SPI_FPR_BASE_SHIFT 0 +#define ICH7_SPI_FPR_LIMIT_SHIFT 12 +#define ICH9_SPI_FPR_LIMIT_SHIFT 16 +#define ICH9_SPI_FPR_RPE (1 << 15) /* Read Protect */ +#define SPI_FPR_WPE (1 << 31) /* Write Protect */ + +static UINT32 spi_fpr(UINT32 base, UINT32 limit) +{ + UINT32 ret; + UINT32 mask, limit_shift; + + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { + mask = ICH7_SPI_FPR_MASK; + limit_shift = ICH7_SPI_FPR_LIMIT_SHIFT; + } else { + mask = ICH9_SPI_FPR_MASK; + limit_shift = ICH9_SPI_FPR_LIMIT_SHIFT; + } + ret = ((limit >> SPI_FPR_SHIFT) & mask) << limit_shift; + ret |= ((base >> SPI_FPR_SHIFT) & mask) << SPI_FPR_BASE_SHIFT; + return ret; +} + +/* + * Protect range of SPI flash defined by [start, start+size-1] using Flash + * Protected Range (FPR) register if available. + * Returns 0 on success, -1 on failure of programming fpr registers. + */ +static INT32 spi_flash_protect(CONST struct spi_flash *flash, + CONST struct region *region, + CONST enum ctrlr_prot_type type) +{ + UINT32 start = region_offset(region); + UINT32 end = start + region_sz(region) - 1; + UINT32 reg; + UINT32 protect_mask = 0; + INT32 fpr; + UINT32 *fpr_base; + + fpr_base = cntlr.fpr; + + /* Find first empty FPR */ + for (fpr = 0; fpr < cntlr.fpr_max; fpr++) { + reg = read32(&fpr_base[fpr]); + if (reg == 0) + break; + } + + if (fpr == cntlr.fpr_max) { + DEBUG((EFI_D_INFO, "%a ERROR: No SPI FPR free!\n", __FUNCTION__)); + return -1; + } + + switch (type) { + case WRITE_PROTECT: + protect_mask |= SPI_FPR_WPE; + break; + case READ_PROTECT: + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) + return -1; + protect_mask |= ICH9_SPI_FPR_RPE; + break; + case READ_WRITE_PROTECT: + if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) + return -1; + protect_mask |= (ICH9_SPI_FPR_RPE | SPI_FPR_WPE); + break; + default: + DEBUG((EFI_D_INFO, "%a ERROR: Seeking invalid protection!\n", __FUNCTION__)); + return -1; + } + + /* Set protected range base and limit */ + reg = spi_fpr(start, end) | protect_mask; + + /* Set the FPR register and verify it is protected */ + write32(&fpr_base[fpr], reg); + if (reg != read32(&fpr_base[fpr])) { + DEBUG((EFI_D_INFO, "%a ERROR: Unable to set SPI FPR %d\n", __FUNCTION__, fpr)); + return -1; + } + + DEBUG((EFI_D_INFO, "%a: FPR %d is enabled for range 0x%08x-0x%08x\n", + __FUNCTION__, fpr, start, end)); + return 0; +} + +VOID spi_finalize_ops(VOID) +{ + UINT16 spi_opprefix; + UINT16 optype = 0; + struct intel_swseq_spi_config spi_config_default = { + {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ + { /* OPCODE and OPTYPE */ + {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ + {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ + {0x03, READ_WITH_ADDR}, /* READ: Read Data */ + {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ + {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ + {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ + {0xd8, WRITE_WITH_ADDR}, /* BED8: Block Erase 0xd8 */ + {0x0b, READ_WITH_ADDR}, /* FAST: Fast Read */ + } + }; + struct intel_swseq_spi_config spi_config_aai_write = { + {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ + { /* OPCODE and OPTYPE */ + {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ + {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ + {0x03, READ_WITH_ADDR}, /* READ: Read Data */ + {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ + {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ + {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ + {0xad, WRITE_NO_ADDR}, /* Auto Address Increment Word Program */ + {0x04, WRITE_NO_ADDR} /* Write Disable */ + } + }; + CONST struct spi_flash *flash = boot_device_spi_flash(); + struct intel_swseq_spi_config *spi_config = &spi_config_default; + INT32 i; + + /* + * Some older SST SPI flashes support AAI write but use 0xaf opcde for + * that. Flashrom uses the byte program opcode to write those flashes, + * so this configuration is fine too. SST25VF064C (id = 0x4b) is an + * exception. + */ + if (flash && flash->vendor == VENDOR_ID_SST && (flash->model & 0x00ff) != 0x4b) + spi_config = &spi_config_aai_write; + + if (spi_locked()) + return; + + intel_southbridge_override_spi(spi_config); + + spi_opprefix = spi_config->opprefixes[0] + | (spi_config->opprefixes[1] << 8); + writew_(spi_opprefix, cntlr.preop); + for (i = 0; i < ARRAY_SIZE(spi_config->ops); i++) { + optype |= (spi_config->ops[i].type & 3) << (i * 2); + writeb_(spi_config->ops[i].op, &cntlr.opmenu[i]); + } + writew_(optype, cntlr.optype); +} + +__attribute__((__weak__)) +VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) +{ +} + +static CONST struct spi_ctrlr spi_ctrlr = { + .xfer_vector = xfer_vectors, + .max_xfer_size = member_size(struct ich9_spi_regs, fdata), + .flash_probe = spi_flash_programmer_probe, + .flash_protect = spi_flash_protect, +}; + +CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { + { + .ctrlr = &spi_ctrlr, + .bus_start = 0, + .bus_end = 0, + }, +}; + +CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); + /*----------------------------------------------------------------------- * Representation of a SPI controller. Note the xfer() and xfer_vector() @@ -48,14 +1251,36 @@ * flash_protect: Protect a region of flash using the SPI flash controller. */ +/* +struct spi_ctrlr { + INT32 (*claim_bus)(CONST struct spi_slave *slave); + VOID (*release_bus)(CONST struct spi_slave *slave); + INT32 (*setup)(CONST struct spi_slave *slave); + INT32 (*xfer)(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); + INT32 (*xfer_vector)(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count); + INT32 (*xfer_dual)(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); + UINT32 max_xfer_size; + UINT32 flags; + INT32 (*flash_probe)(CONST struct spi_slave *slave, + struct spi_flash *flash); + INT32 (*flash_protect)(CONST struct spi_flash *flash, + CONST struct region *region, + CONST enum ctrlr_prot_type type); +}; +*/ + + static CONST struct spi_ctrlr spi_ctrlr = { - .claim_bus = spi_claim_bus, - .release_bus = spi_release_bus, + .claim_bus = NULL, + .release_bus = NULL, .setup = NULL, - .xfer = NULL, + .xfer = spi_ctrlr_xfer, .xfer_vector = NULL, .xfer_dual = NULL, - .max_xfer_size = 0, + .max_xfer_size = 0x40, .flags = 0, .flash_probe = NULL, .flash_protect = NULL @@ -70,1086 +1295,3 @@ CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { }; CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); - -// #define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ -// #define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) -// #define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ -// #define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) - -// static int spi_is_multichip(VOID); - -// struct ich7_spi_regs { -// UINT16 spis; -// UINT16 spic; -// UINT32 spia; -// UINT64 spid[8]; -// UINT64 _pad; -// UINT32 bbar; -// UINT16 preop; -// UINT16 optype; -// UINT8 opmenu[8]; -// UINT32 pbr[3]; -// } __packed; - -// struct ich9_spi_regs { -// UINT32 bfpr; -// UINT16 hsfs; -// UINT16 hsfc; -// UINT32 faddr; -// UINT32 _reserved0; -// UINT32 fdata[16]; -// UINT32 frap; -// UINT32 freg[5]; -// UINT32 _reserved1[3]; -// UINT32 pr[5]; -// UINT32 _reserved2[2]; -// UINT8 ssfs; -// UINT8 ssfc[3]; -// UINT16 preop; -// UINT16 optype; -// UINT8 opmenu[8]; -// UINT32 bbar; -// UINT8 _reserved3[12]; -// UINT32 fdoc; -// UINT32 fdod; -// UINT8 _reserved4[8]; -// UINT32 afc; -// UINT32 lvscc; -// UINT32 uvscc; -// UINT8 _reserved5[4]; -// UINT32 fpb; -// UINT8 _reserved6[28]; -// UINT32 srdl; -// UINT32 srdc; -// UINT32 srd; -// } __packed; - -// struct ich_spi_controller { -// INT32 locked; -// UINT32 flmap0; -// UINT32 flcomp; -// UINT32 hsfs; - -// union { -// struct ich9_spi_regs *ich9_spi; -// struct ich7_spi_regs *ich7_spi; -// }; -// UINT8 *opmenu; -// INT32 menubytes; -// UINT16 *preop; -// UINT16 *optype; -// UINT32 *addr; -// UINT8 *data; -// UINT32 databytes; -// UINT8 *status; -// UINT16 *control; -// UINT32 *bbar; -// UINT32 *fpr; -// UINT8 fpr_max; -// }; - -// static struct ich_spi_controller cntlr; - -// enum { -// SPIS_SCIP = 0x0001, -// SPIS_GRANT = 0x0002, -// SPIS_CDS = 0x0004, -// SPIS_FCERR = 0x0008, -// SSFS_AEL = 0x0010, -// SPIS_LOCK = 0x8000, -// SPIS_RESERVED_MASK = 0x7ff0, -// SSFS_RESERVED_MASK = 0x7fe2 -// }; - -// enum { -// SPIC_SCGO = 0x000002, -// SPIC_ACS = 0x000004, -// SPIC_SPOP = 0x000008, -// SPIC_DBC = 0x003f00, -// SPIC_DS = 0x004000, -// SPIC_SME = 0x008000, -// SSFC_SCF_MASK = 0x070000, -// SSFC_RESERVED = 0xf80000 -// }; - -// enum { -// HSFS_FDONE = 0x0001, -// HSFS_FCERR = 0x0002, -// HSFS_AEL = 0x0004, -// HSFS_BERASE_MASK = 0x0018, -// HSFS_BERASE_SHIFT = 3, -// HSFS_SCIP = 0x0020, -// HSFS_FDOPSS = 0x2000, -// HSFS_FDV = 0x4000, -// HSFS_FLOCKDN = 0x8000 -// }; - -// enum { -// HSFC_FGO = 0x0001, -// HSFC_FCYCLE_MASK = 0x0006, -// HSFC_FCYCLE_SHIFT = 1, -// HSFC_FDBC_MASK = 0x3f00, -// HSFC_FDBC_SHIFT = 8, -// HSFC_FSMIE = 0x8000 -// }; - -// enum { -// SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, -// SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, -// SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, -// SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 -// }; - -// #if CONFIG(DEBUG_SPI_FLASH) - -// static u8 readb_(CONST VOID *addr) -// { -// u8 v = read8(addr); - -// printk(BIOS_DEBUG, "read %2.2x from %4.4x\n", -// v, ((unsigned int) addr & 0xffff) - 0xf020); -// return v; -// } - -// static UINT16 readw_(CONST VOID *addr) -// { -// UINT16 v = read16(addr); - -// printk(BIOS_DEBUG, "read %4.4x from %4.4x\n", -// v, ((unsigned int) addr & 0xffff) - 0xf020); -// return v; -// } - -// static UINT32 readl_(CONST VOID *addr) -// { -// UINT32 v = read32(addr); - -// printk(BIOS_DEBUG, "read %8.8x from %4.4x\n", -// v, ((unsigned int) addr & 0xffff) - 0xf020); -// return v; -// } - -// static VOID writeb_(u8 b, VOID *addr) -// { -// write8(addr, b); -// printk(BIOS_DEBUG, "wrote %2.2x to %4.4x\n", -// b, ((unsigned int) addr & 0xffff) - 0xf020); -// } - -// static VOID writew_(UINT16 b, VOID *addr) -// { -// write16(addr, b); -// printk(BIOS_DEBUG, "wrote %4.4x to %4.4x\n", -// b, ((unsigned int) addr & 0xffff) - 0xf020); -// } - -// static VOID writel_(UINT32 b, VOID *addr) -// { -// write32(addr, b); -// printk(BIOS_DEBUG, "wrote %8.8x to %4.4x\n", -// b, ((unsigned int) addr & 0xffff) - 0xf020); -// } - -// #else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -// #define readb_(a) read8(a) -// #define readw_(a) read16(a) -// #define readl_(a) read32(a) -// #define writeb_(val, addr) write8(addr, val) -// #define writew_(val, addr) write16(addr, val) -// #define writel_(val, addr) write32(addr, val) - -// #endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -// static VOID write_reg(CONST VOID *value, VOID *dest, UINT32 size) -// { -// CONST UINT8 *bvalue = value; -// UINT8 *bdest = dest; - -// while (size >= 4) { -// writel_(*(CONST UINT32 *)bvalue, bdest); -// bdest += 4; bvalue += 4; size -= 4; -// } -// while (size) { -// writeb_(*bvalue, bdest); -// bdest++; bvalue++; size--; -// } -// } - -// static VOID read_reg(CONST VOID *src, VOID *value, UINT32 size) -// { -// CONST UINT8 *bsrc = src; -// UINT8 *bvalue = value; - -// while (size >= 4) { -// *(UINT32 *)bvalue = readl_(bsrc); -// bsrc += 4; bvalue += 4; size -= 4; -// } -// while (size) { -// *bvalue = readb_(bsrc); -// bsrc++; bvalue++; size--; -// } -// } - -// static VOID ich_set_bbar(UINT32 minaddr) -// { -// CONST UINT32 bbar_mask = 0x00ffff00; -// UINT32 ichspi_bbar; - -// minaddr &= bbar_mask; -// ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; -// ichspi_bbar |= minaddr; -// writel_(ichspi_bbar, cntlr.bbar); -// } - -// #if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) -// #define MENU_BYTES member_size(struct ich7_spi_regs, opmenu) -// #else -// #define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) -// #endif - -// #define RCBA 0xf0 -// #define SBASE 0x54 - -// static VOID *get_spi_bar(pci_devfn_t dev) -// { -// uintptr_t rcba; /* Root Complex Register Block */ -// uintptr_t sbase; - -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { -// rcba = pci_read_config32(dev, RCBA); -// return (VOID *)((rcba & 0xffffc000) + 0x3020); -// } -// if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT)) { -// sbase = pci_read_config32(dev, SBASE); -// sbase &= ~0x1ff; -// return (VOID *)sbase; -// } -// if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { -// rcba = pci_read_config32(dev, RCBA); -// return (VOID *)((rcba & 0xffffc000) + 0x3800); -// } -// } - -// VOID spi_init(VOID) -// { -// UINT8 bios_cntl; -// struct ich9_spi_regs *ich9_spi; -// struct ich7_spi_regs *ich7_spi; -// UINT16 hsfs; - -// pci_devfn_t dev = PCI_DEV(0, 31, 0); - -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { -// ich7_spi = get_spi_bar(dev); -// cntlr.ich7_spi = ich7_spi; -// cntlr.opmenu = ich7_spi->opmenu; -// cntlr.menubytes = sizeof(ich7_spi->opmenu); -// cntlr.optype = &ich7_spi->optype; -// cntlr.addr = &ich7_spi->spia; -// cntlr.data = (UINT8 *)ich7_spi->spid; -// cntlr.databytes = sizeof(ich7_spi->spid); -// cntlr.status = (UINT8 *)&ich7_spi->spis; -// cntlr.control = &ich7_spi->spic; -// cntlr.bbar = &ich7_spi->bbar; -// cntlr.preop = &ich7_spi->preop; -// cntlr.fpr = &ich7_spi->pbr[0]; -// cntlr.fpr_max = 3; -// } else { -// ich9_spi = get_spi_bar(dev); -// cntlr.ich9_spi = ich9_spi; -// hsfs = readw_(&ich9_spi->hsfs); -// cntlr.hsfs = hsfs; -// cntlr.opmenu = ich9_spi->opmenu; -// cntlr.menubytes = sizeof(ich9_spi->opmenu); -// cntlr.optype = &ich9_spi->optype; -// cntlr.addr = &ich9_spi->faddr; -// cntlr.data = (UINT8 *)ich9_spi->fdata; -// cntlr.databytes = sizeof(ich9_spi->fdata); -// cntlr.status = &ich9_spi->ssfs; -// cntlr.control = (UINT16 *)ich9_spi->ssfc; -// cntlr.bbar = &ich9_spi->bbar; -// cntlr.preop = &ich9_spi->preop; -// cntlr.fpr = &ich9_spi->pr[0]; -// cntlr.fpr_max = 5; - -// if (cntlr.hsfs & HSFS_FDV) { -// writel_(4, &ich9_spi->fdoc); -// cntlr.flmap0 = readl_(&ich9_spi->fdod); -// writel_(0x1000, &ich9_spi->fdoc); -// cntlr.flcomp = readl_(&ich9_spi->fdod); -// } -// } - -// ich_set_bbar(0); - -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { -// /* Disable the BIOS write protect so write commands are allowed. */ -// bios_cntl = pci_read_config8(dev, 0xdc); -// /* Deassert SMM BIOS Write Protect Disable. */ -// bios_cntl &= ~(1 << 5); -// pci_write_config8(dev, 0xdc, bios_cntl | 0x1); -// } -// } - -// static int spi_locked(VOID) -// { -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { -// return !!(readw_(&cntlr.ich7_spi->spis) & HSFS_FLOCKDN); -// } else { -// return !!(readw_(&cntlr.ich9_spi->hsfs) & HSFS_FLOCKDN); -// } -// } - -// static VOID spi_init_cb(VOID *unused) -// { -// spi_init(); -// } - -// BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); - -// typedef struct spi_transaction { -// CONST UINT8 *out; -// UINT32 bytesout; -// UINT8 *in; -// UINT32 bytesin; -// UINT8 type; -// UINT8 opcode; -// UINT32 offset; -// } spi_transaction; - -// static inline VOID spi_use_out(spi_transaction *trans, unsigned int bytes) -// { -// trans->out += bytes; -// trans->bytesout -= bytes; -// } - -// static inline VOID spi_use_in(spi_transaction *trans, unsigned int bytes) -// { -// trans->in += bytes; -// trans->bytesin -= bytes; -// } - -// static VOID spi_setup_type(spi_transaction *trans) -// { -// trans->type = 0xFF; - -// /* Try to guess spi type from read/write sizes. */ -// if (trans->bytesin == 0) { -// if (trans->bytesout > 4) -// /* -// * If bytesin = 0 and bytesout > 4, we presume this is -// * a write data operation, which is accompanied by an -// * address. -// */ -// trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; -// else -// trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; -// return; -// } - -// if (trans->bytesout == 1) { /* and bytesin is > 0 */ -// trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; -// return; -// } - -// if (trans->bytesout == 4) { /* and bytesin is > 0 */ -// trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; -// } - -// /* Fast read command is called with 5 bytes instead of 4 */ -// if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { -// trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; -// --trans->bytesout; -// } -// } - -// static int spi_setup_opcode(spi_transaction *trans) -// { -// UINT16 optypes; -// UINT8 opmenu[MENU_BYTES]; - -// trans->opcode = trans->out[0]; -// spi_use_out(trans, 1); -// if (!spi_locked()) { -// /* The lock is off, so just use index 0. */ -// writeb_(trans->opcode, cntlr.opmenu); -// optypes = readw_(cntlr.optype); -// optypes = (optypes & 0xfffc) | (trans->type & 0x3); -// writew_(optypes, cntlr.optype); -// return 0; -// } - -// /* The lock is on. See if what we need is on the menu. */ -// UINT8 optype; -// UINT16 opcode_index; - -// /* Write Enable is handled as atomic prefix */ -// if (trans->opcode == SPI_OPCODE_WREN) -// return 0; - -// read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); -// for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { -// if (opmenu[opcode_index] == trans->opcode) -// break; -// } - -// if (opcode_index == ARRAY_SIZE(opmenu)) { -// printk(BIOS_DEBUG, "ICH SPI: Opcode %x not found\n", -// trans->opcode); -// return -1; -// } - -// optypes = readw_(cntlr.optype); -// optype = (optypes >> (opcode_index * 2)) & 0x3; -// if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && -// optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && -// trans->bytesout >= 3) { -// /* We guessed wrong earlier. Fix it up. */ -// trans->type = optype; -// } -// if (optype != trans->type) { -// printk(BIOS_DEBUG, "ICH SPI: Transaction doesn't fit type %d\n", -// optype); -// return -1; -// } -// return opcode_index; -// } - -// static int spi_setup_offset(spi_transaction *trans) -// { -// /* Separate the SPI address and data. */ -// switch (trans->type) { -// case SPI_OPCODE_TYPE_READ_NO_ADDRESS: -// case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: -// return 0; -// case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: -// case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: -// trans->offset = ((UINT32)trans->out[0] << 16) | -// ((UINT32)trans->out[1] << 8) | -// ((UINT32)trans->out[2] << 0); -// spi_use_out(trans, 3); -// return 1; -// default: -// printk(BIOS_DEBUG, "Unrecognized SPI transaction type %#x\n", trans->type); -// return -1; -// } -// } - -// /* -// * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set -// * below is True) or 0. In case the wait was for the bit(s) to set - write -// * those bits back, which would cause resetting them. -// * -// * Return the last read status value on success or -1 on failure. -// */ -// static int ich_status_poll(UINT16 bitmask, int wait_til_set) -// { -// int timeout = 600000; /* This will result in 6 seconds */ -// UINT16 status = 0; - -// while (timeout--) { -// status = readw_(cntlr.status); -// if (wait_til_set ^ ((status & bitmask) == 0)) { -// if (wait_til_set) -// writew_((status & bitmask), cntlr.status); -// return status; -// } -// udelay(10); -// } - -// printk(BIOS_DEBUG, "ICH SPI: SCIP timeout, read %x, bitmask %x\n", -// status, bitmask); -// return -1; -// } - -// static INT32 spi_is_multichip(VOID) -// { -// if (!(cntlr.hsfs & HSFS_FDV)) -// return 0; -// return !!((cntlr.flmap0 >> 8) & 3); -// } - -// static INT32 spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, -// size_t bytesout, VOID *din, size_t bytesin) -// { -// UINT16 control; -// int16_t opcode_index; -// INT32 with_address; -// INT32 status; - -// spi_transaction trans = { -// dout, bytesout, -// din, bytesin, -// 0xff, 0xff, 0 -// }; - -// /* There has to always at least be an opcode. */ -// if (!bytesout || !dout) { -// printk(BIOS_DEBUG, "ICH SPI: No opcode for transfer\n"); -// return -1; -// } -// /* Make sure if we read something we have a place to put it. */ -// if (bytesin != 0 && !din) { -// printk(BIOS_DEBUG, "ICH SPI: Read but no target buffer\n"); -// return -1; -// } - -// if (ich_status_poll(SPIS_SCIP, 0) == -1) -// return -1; - -// writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - -// spi_setup_type(&trans); -// if ((opcode_index = spi_setup_opcode(&trans)) < 0) -// return -1; -// if ((with_address = spi_setup_offset(&trans)) < 0) -// return -1; - -// if (trans.opcode == SPI_OPCODE_WREN) { -// /* -// * Treat Write Enable as Atomic Pre-Op if possible -// * in order to prevent the Management Engine from -// * issuing a transaction between WREN and DATA. -// */ -// if (!spi_locked()) -// writew_(trans.opcode, cntlr.preop); -// return 0; -// } - -// /* Preset control fields */ -// control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - -// /* Issue atomic preop cycle if needed */ -// if (readw_(cntlr.preop)) -// control |= SPIC_ACS; - -// if (!trans.bytesout && !trans.bytesin) { -// /* SPI addresses are 24 bit only */ -// if (with_address) -// writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - -// /* -// * This is a 'no data' command (like Write Enable), its -// * bitesout size was 1, decremented to zero while executing -// * spi_setup_opcode() above. Tell the chip to send the -// * command. -// */ -// writew_(control, cntlr.control); - -// /* wait for the result */ -// status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); -// if (status == -1) -// return -1; - -// if (status & SPIS_FCERR) { -// printk(BIOS_DEBUG, "ICH SPI: Command transaction error\n"); -// return -1; -// } - -// goto spi_xfer_exit; -// } - -// /* -// * Check if this is a write command attempting to transfer more bytes -// * than the controller can handle. Iterations for writes are not -// * supported here because each SPI write command needs to be preceded -// * and followed by other SPI commands, and this sequence is controlled -// * by the SPI chip driver. -// */ -// if (trans.bytesout > cntlr.databytes) { -// printk(BIOS_DEBUG, "ICH SPI: Too much to write. Does your SPI chip driver use" -// " spi_crop_chunk()?\n"); -// return -1; -// } - -// /* -// * Read or write up to databytes bytes at a time until everything has -// * been sent. -// */ -// while (trans.bytesout || trans.bytesin) { -// UINT32 data_length; - -// /* SPI addresses are 24 bit only */ -// writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - -// if (trans.bytesout) -// data_length = MIN(trans.bytesout, cntlr.databytes); -// else -// data_length = MIN(trans.bytesin, cntlr.databytes); - -// /* Program data into FDATA0 to N */ -// if (trans.bytesout) { -// write_reg(trans.out, cntlr.data, data_length); -// spi_use_out(&trans, data_length); -// if (with_address) -// trans.offset += data_length; -// } - -// /* Add proper control fields' values */ -// control &= ~((cntlr.databytes - 1) << 8); -// control |= SPIC_DS; -// control |= (data_length - 1) << 8; - -// /* write it */ -// writew_(control, cntlr.control); - -// /* Wait for Cycle Done Status or Flash Cycle Error. */ -// status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); -// if (status == -1) -// return -1; - -// if (status & SPIS_FCERR) { -// printk(BIOS_DEBUG, "ICH SPI: Data transaction error\n"); -// return -1; -// } - -// if (trans.bytesin) { -// read_reg(cntlr.data, trans.in, data_length); -// spi_use_in(&trans, data_length); -// if (with_address) -// trans.offset += data_length; -// } -// } - -// spi_xfer_exit: -// /* Clear atomic preop now that xfer is done */ -// writew_(0, cntlr.preop); - -// return 0; -// } - -// /* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ -// static VOID ich_hwseq_set_addr(UINT32 addr) -// { -// UINT32 addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; - -// writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); -// } - -// /* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. -// Resets all error flags in HSFS. -// Returns 0 if the cycle completes successfully without errors within -// timeout us, 1 on errors. */ -// static int ich_hwseq_wait_for_cycle_complete(unsigned int timeout, -// unsigned int len) -// { -// UINT16 hsfs; -// UINT32 addr; - -// timeout /= 8; /* scale timeout duration to counter */ -// while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & -// (HSFS_FDONE | HSFS_FCERR)) == 0) && -// --timeout) { -// udelay(8); -// } -// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - -// if (!timeout) { -// UINT16 hsfc; -// addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; -// hsfc = readw_(&cntlr.ich9_spi->hsfc); -// printk(BIOS_ERR, "Transaction timeout between offset 0x%08x and " -// "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", -// addr, addr + len - 1, addr, len - 1, -// hsfc, hsfs); -// return 1; -// } - -// if (hsfs & HSFS_FCERR) { -// UINT16 hsfc; -// addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; -// hsfc = readw_(&cntlr.ich9_spi->hsfc); -// printk(BIOS_ERR, "Transaction error between offset 0x%08x and " -// "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", -// addr, addr + len - 1, addr, len - 1, -// hsfc, hsfs); -// return 1; -// } -// return 0; -// } - - -// static int ich_hwseq_erase(CONST struct spi_flash *flash, UINT32 offset, -// size_t len) -// { -// UINT32 start, end, erase_size; -// int ret; -// UINT16 hsfc; -// unsigned int timeout = 1000 * USECS_PER_MSEC; /* 1 second timeout */ - -// erase_size = flash->sector_size; -// if (offset % erase_size || len % erase_size) { -// printk(BIOS_ERR, "SF: Erase offset/length not multiple of erase size\n"); -// return -1; -// } - -// ret = spi_claim_bus(&flash->spi); -// if (ret) { -// printk(BIOS_ERR, "SF: Unable to claim SPI bus\n"); -// return ret; -// } - -// start = offset; -// end = start + len; - -// while (offset < end) { -// /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ -// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - -// ich_hwseq_set_addr(offset); - -// offset += erase_size; - -// hsfc = readw_(&cntlr.ich9_spi->hsfc); -// hsfc &= ~HSFC_FCYCLE; /* clear operation */ -// hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ -// hsfc |= HSFC_FGO; /* start */ -// writew_(hsfc, &cntlr.ich9_spi->hsfc); -// if (ich_hwseq_wait_for_cycle_complete(timeout, len)) { -// printk(BIOS_ERR, "SF: Erase failed at %x\n", offset - erase_size); -// ret = -1; -// goto out; -// } -// } - -// printk(BIOS_DEBUG, "SF: Successfully erased %zu bytes @ %#x\n", len, start); - -// out: -// spi_release_bus(&flash->spi); -// return ret; -// } - -// static VOID ich_read_data(UINT8 *data, INT32 len) -// { -// INT32 i; -// UINT32 temp32 = 0; - -// for (i = 0; i < len; i++) { -// if ((i % 4) == 0) -// temp32 = readl_(cntlr.data + i); - -// data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; -// } -// } - -// static int ich_hwseq_read(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, -// VOID *buf) -// { -// UINT16 hsfc; -// UINT16 timeout = 100 * 60; -// UINT8 block_len; - -// if (addr + len > flash->size) { -// printk(BIOS_ERR, -// "Attempt to read %x-%x which is out of chip\n", -// (unsigned int) addr, -// (unsigned int) addr+(unsigned int) len); -// return -1; -// } - -// /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ -// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - -// while (len > 0) { -// block_len = MIN(len, cntlr.databytes); -// if (block_len > (~addr & 0xff)) -// block_len = (~addr & 0xff) + 1; -// ich_hwseq_set_addr(addr); -// hsfc = readw_(&cntlr.ich9_spi->hsfc); -// hsfc &= ~HSFC_FCYCLE; /* set read operation */ -// hsfc &= ~HSFC_FDBC; /* clear byte count */ -// /* set byte count */ -// hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); -// hsfc |= HSFC_FGO; /* start */ -// writew_(hsfc, &cntlr.ich9_spi->hsfc); - -// if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) -// return 1; -// ich_read_data(buf, block_len); -// addr += block_len; -// buf += block_len; -// len -= block_len; -// } -// return 0; -// } - -// /* Fill len bytes from the data array into the fdata/spid registers. -// * -// * Note that using len > flash->pgm->spi.max_data_write will trash the registers -// * following the data registers. -// */ -// static VOID ich_fill_data(CONST UINT8 *data, INT32 len) -// { -// UINT32 temp32 = 0; -// INT32 i; - -// if (len <= 0) -// return; - -// for (i = 0; i < len; i++) { -// if ((i % 4) == 0) -// temp32 = 0; - -// temp32 |= ((UINT32) data[i]) << ((i % 4) * 8); - -// if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ -// writel_(temp32, cntlr.data + (i - (i % 4))); -// } -// i--; -// if ((i % 4) != 3) /* Write remaining data to regs. */ -// writel_(temp32, cntlr.data + (i - (i % 4))); -// } - -// static int ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, size_t len, -// CONST VOID *buf) -// { -// UINT16 hsfc; -// UINT16 timeout = 100 * 60; -// UINT8 block_len; -// UINT32 start = addr; - -// if (addr + len > flash->size) { -// printk(BIOS_ERR, -// "Attempt to write 0x%x-0x%x which is out of chip\n", -// (unsigned int)addr, (unsigned int) (addr+len)); -// return -1; -// } - -// /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ -// writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - -// while (len > 0) { -// block_len = MIN(len, cntlr.databytes); -// if (block_len > (~addr & 0xff)) -// block_len = (~addr & 0xff) + 1; - -// ich_hwseq_set_addr(addr); - -// ich_fill_data(buf, block_len); -// hsfc = readw_(&cntlr.ich9_spi->hsfc); -// hsfc &= ~HSFC_FCYCLE; /* clear operation */ -// hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ -// hsfc &= ~HSFC_FDBC; /* clear byte count */ -// /* set byte count */ -// hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); -// hsfc |= HSFC_FGO; /* start */ -// writew_(hsfc, &cntlr.ich9_spi->hsfc); - -// if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) { -// printk(BIOS_ERR, "SF: write failure at %x\n", -// addr); -// return -1; -// } -// addr += block_len; -// buf += block_len; -// len -= block_len; -// } -// printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", -// (unsigned int) (addr - start), start); -// return 0; -// } - -// static CONST struct spi_flash_ops spi_flash_ops = { -// .read = ich_hwseq_read, -// .write = ich_hwseq_write, -// .erase = ich_hwseq_erase, -// }; - -// static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, -// struct spi_flash *flash) -// { - -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) -// return spi_flash_generic_probe(spi, flash); - -// /* Try generic probing first if spi_is_multichip returns 0. */ -// if (!spi_is_multichip() && !spi_flash_generic_probe(spi, flash)) -// return 0; - -// memcpy(&flash->spi, spi, sizeof(*spi)); - -// ich_hwseq_set_addr(0); -// switch ((cntlr.hsfs >> 3) & 3) { -// case 0: -// flash->sector_size = 256; -// break; -// case 1: -// flash->sector_size = 4096; -// break; -// case 2: -// flash->sector_size = 8192; -// break; -// case 3: -// flash->sector_size = 65536; -// break; -// } - -// flash->size = 1 << (19 + (cntlr.flcomp & 7)); - -// flash->ops = &spi_flash_ops; - -// if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) -// flash->size += 1 << (19 + ((cntlr.flcomp >> 3) & 7)); -// printk(BIOS_DEBUG, "flash size 0x%x bytes\n", flash->size); - -// return 0; -// } - -// static INT32 xfer_vectors(CONST struct spi_slave *slave, -// struct spi_op vectors[], size_t count) -// { -// return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); -// } - -// #define SPI_FPR_SHIFT 12 -// #define ICH7_SPI_FPR_MASK 0xfff -// #define ICH9_SPI_FPR_MASK 0x1fff -// #define SPI_FPR_BASE_SHIFT 0 -// #define ICH7_SPI_FPR_LIMIT_SHIFT 12 -// #define ICH9_SPI_FPR_LIMIT_SHIFT 16 -// #define ICH9_SPI_FPR_RPE (1 << 15) /* Read Protect */ -// #define SPI_FPR_WPE (1 << 31) /* Write Protect */ - -// static UINT32 spi_fpr(UINT32 base, UINT32 limit) -// { -// UINT32 ret; -// UINT32 mask, limit_shift; - -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { -// mask = ICH7_SPI_FPR_MASK; -// limit_shift = ICH7_SPI_FPR_LIMIT_SHIFT; -// } else { -// mask = ICH9_SPI_FPR_MASK; -// limit_shift = ICH9_SPI_FPR_LIMIT_SHIFT; -// } -// ret = ((limit >> SPI_FPR_SHIFT) & mask) << limit_shift; -// ret |= ((base >> SPI_FPR_SHIFT) & mask) << SPI_FPR_BASE_SHIFT; -// return ret; -// } - -// /* -// * Protect range of SPI flash defined by [start, start+size-1] using Flash -// * Protected Range (FPR) register if available. -// * Returns 0 on success, -1 on failure of programming fpr registers. -// */ -// static int spi_flash_protect(CONST struct spi_flash *flash, -// CONST struct region *region, -// CONST enum ctrlr_prot_type type) -// { -// UINT32 start = region_offset(region); -// UINT32 end = start + region_sz(region) - 1; -// UINT32 reg; -// UINT32 protect_mask = 0; -// INT32 fpr; -// UINT32 *fpr_base; - -// fpr_base = cntlr.fpr; - -// /* Find first empty FPR */ -// for (fpr = 0; fpr < cntlr.fpr_max; fpr++) { -// reg = read32(&fpr_base[fpr]); -// if (reg == 0) -// break; -// } - -// if (fpr == cntlr.fpr_max) { -// printk(BIOS_ERR, "ERROR: No SPI FPR free!\n"); -// return -1; -// } - -// switch (type) { -// case WRITE_PROTECT: -// protect_mask |= SPI_FPR_WPE; -// break; -// case READ_PROTECT: -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) -// return -1; -// protect_mask |= ICH9_SPI_FPR_RPE; -// break; -// case READ_WRITE_PROTECT: -// if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) -// return -1; -// protect_mask |= (ICH9_SPI_FPR_RPE | SPI_FPR_WPE); -// break; -// default: -// printk(BIOS_ERR, "ERROR: Seeking invalid protection!\n"); -// return -1; -// } - -// /* Set protected range base and limit */ -// reg = spi_fpr(start, end) | protect_mask; - -// /* Set the FPR register and verify it is protected */ -// write32(&fpr_base[fpr], reg); -// if (reg != read32(&fpr_base[fpr])) { -// printk(BIOS_ERR, "ERROR: Unable to set SPI FPR %d\n", fpr); -// return -1; -// } - -// printk(BIOS_INFO, "%s: FPR %d is enabled for range 0x%08x-0x%08x\n", -// __func__, fpr, start, end); -// return 0; -// } - -// VOID spi_finalize_ops(VOID) -// { -// UINT16 spi_opprefix; -// UINT16 optype = 0; -// struct intel_swseq_spi_config spi_config_default = { -// {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ -// { /* OPCODE and OPTYPE */ -// {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ -// {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ -// {0x03, READ_WITH_ADDR}, /* READ: Read Data */ -// {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ -// {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ -// {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ -// {0xd8, WRITE_WITH_ADDR}, /* BED8: Block Erase 0xd8 */ -// {0x0b, READ_WITH_ADDR}, /* FAST: Fast Read */ -// } -// }; -// struct intel_swseq_spi_config spi_config_aai_write = { -// {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ -// { /* OPCODE and OPTYPE */ -// {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ -// {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ -// {0x03, READ_WITH_ADDR}, /* READ: Read Data */ -// {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ -// {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ -// {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ -// {0xad, WRITE_NO_ADDR}, /* Auto Address Increment Word Program */ -// {0x04, WRITE_NO_ADDR} /* Write Disable */ -// } -// }; -// CONST struct spi_flash *flash = boot_device_spi_flash(); -// struct intel_swseq_spi_config *spi_config = &spi_config_default; -// int i; - -// /* -// * Some older SST SPI flashes support AAI write but use 0xaf opcde for -// * that. Flashrom uses the byte program opcode to write those flashes, -// * so this configuration is fine too. SST25VF064C (id = 0x4b) is an -// * exception. -// */ -// if (flash && flash->vendor == VENDOR_ID_SST && (flash->model & 0x00ff) != 0x4b) -// spi_config = &spi_config_aai_write; - -// if (spi_locked()) -// return; - -// intel_southbridge_override_spi(spi_config); - -// spi_opprefix = spi_config->opprefixes[0] -// | (spi_config->opprefixes[1] << 8); -// writew_(spi_opprefix, cntlr.preop); -// for (i = 0; i < ARRAY_SIZE(spi_config->ops); i++) { -// optype |= (spi_config->ops[i].type & 3) << (i * 2); -// writeb_(spi_config->ops[i].op, &cntlr.opmenu[i]); -// } -// writew_(optype, cntlr.optype); -// } - -// __weak VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) -// { -// } From fc8933e5d5bfd722ea9d2aca263687ecaaba6ae1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 13:04:05 +0200 Subject: [PATCH 130/297] fix some errors --- UefiPayloadPkg/SPI/intelSPI.c | 154 ++++++++++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 224fd9b41f84..de2200f24f61 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -55,6 +55,13 @@ #define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) #endif +#define pci_read_config8 pci_s_read_config8 +#define pci_read_config16 pci_s_read_config16 +#define pci_read_config32 pci_s_read_config32 +#define pci_write_config8 pci_s_write_config8 +#define pci_write_config16 pci_s_write_config16 +#define pci_write_config32 pci_s_write_config32 + typedef enum { BS_PRE_DEVICE, BS_DEV_INIT_CHIPS, @@ -128,6 +135,107 @@ struct spi_flash_ops { int (*status)(CONST struct spi_flash *flash, UINT8 *reg); }; +/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we + * prevent some sub-optimal constant folding. */ +extern u8 *const pci_mmconf; + +/* Using a unique datatype for MMIO writes makes the pointers to _not_ + * qualify for pointer aliasing with any other objects in memory. + * + * MMIO offset is a value originally derived from 'struct device *' + * in ramstage. For the compiler to not discard this MMIO offset value + * from CPU registers after any MMIO writes, -fstrict-aliasing has to + * be also set for the build. + * + * Bottom 12 bits (4 KiB) are reserved to address the registers of a + * single PCI function. Declare the bank as a union to avoid some casting + * in the functions below. + */ +union pci_bank { + uint8_t reg8[4096]; + uint16_t reg16[4096 / sizeof(uint16_t)]; + uint32_t reg32[4096 / sizeof(uint32_t)]; +}; + +static __always_inline +volatile union pci_bank *pcicfg(pci_devfn_t dev) +{ + return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; +} + +static __always_inline +uint8_t pci_mmio_read_config8(pci_devfn_t dev, uint16_t reg) +{ + return pcicfg(dev)->reg8[reg]; +} + +static __always_inline +uint16_t pci_mmio_read_config16(pci_devfn_t dev, uint16_t reg) +{ + return pcicfg(dev)->reg16[reg / sizeof(uint16_t)]; +} + +static __always_inline +uint32_t pci_mmio_read_config32(pci_devfn_t dev, uint16_t reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(uint32_t)]; +} + +static __always_inline +void pci_mmio_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value) +{ + pcicfg(dev)->reg8[reg] = value; +} + +static __always_inline +void pci_mmio_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value) +{ + pcicfg(dev)->reg16[reg / sizeof(uint16_t)] = value; +} + +static __always_inline +void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) +{ + pcicfg(dev)->reg32[reg / sizeof(uint32_t)] = value; +} + +/* + * The functions pci_mmio_config*_addr provide a way to determine the MMIO address of a PCI + * config register. The address returned is dependent of both the MMCONF base address and the + * assigned PCI bus number of the requested device, which both can change during the boot + * process. Thus, the pointer returned here must not be cached! + */ +static __always_inline +uint8_t *pci_mmio_config8_addr(pci_devfn_t dev, uint16_t reg) +{ + return (uint8_t *)&pcicfg(dev)->reg8[reg]; +} + +static __always_inline +uint16_t *pci_mmio_config16_addr(pci_devfn_t dev, uint16_t reg) +{ + return (uint16_t *)&pcicfg(dev)->reg16[reg / sizeof(uint16_t)]; +} + +static __always_inline +uint32_t *pci_mmio_config32_addr(pci_devfn_t dev, uint16_t reg) +{ + return (uint32_t *)&pcicfg(dev)->reg32[reg / sizeof(uint32_t)]; +} + +typedef UINT32 pci_devfn_t; + +/* Convert pci_devfn_t to offset in MMCONF space. + * As it is one-to-one, nothing needs to be done. */ +#define PCI_DEVFN_OFFSET(x) ((x)) + +#define PCI_DEV(SEGBUS, DEV, FN) ( \ + (((SEGBUS) & 0xFFF) << 20) | \ + (((DEV) & 0x1F) << 15) | \ + (((FN) & 0x07) << 12)) + +#define PCI_DEV_INVALID (0xffffffffU) + struct ich7_spi_regs { UINT16 spis; UINT16 spic; @@ -139,7 +247,7 @@ struct ich7_spi_regs { UINT16 optype; UINT8 opmenu[8]; UINT32 pbr[3]; -} __packed; +} __attribute__((packed)); struct ich9_spi_regs { UINT32 bfpr; @@ -172,7 +280,7 @@ struct ich9_spi_regs { UINT32 srdl; UINT32 srdc; UINT32 srd; -} __packed; +} __attribute__((packed)); struct ich_spi_controller { INT32 locked; @@ -250,6 +358,36 @@ enum { SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 }; +static inline uint8_t read8(const void *addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline uint16_t read16(const void *addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline uint32_t read32(const void *addr) +{ + return *(volatile uint32_t *)addr; +} + +static inline void write8(void *addr, uint8_t val) +{ + *(volatile uint8_t *)addr = val; +} + +static inline void write16(void *addr, uint16_t val) +{ + *(volatile uint16_t *)addr = val; +} + +static inline void write32(void *addr, uint32_t val) +{ + *(volatile uint32_t *)addr = val; +} + #define DEBUG_SPI_FLASH #ifdef DEBUG_SPI_FLASH @@ -259,7 +397,7 @@ static UINT8 readb_(CONST VOID *addr) UINT8 v = read8(addr); DEBUG((EFI_D_INFO, "%a read %2.2x from %4.4x\n", - __FUNCTION__, v, ((UINT32) addr & 0xffff) - 0xf020)); + __FUNCTION__, v, ((UINT64) addr & 0xffff) - 0xf020)); return v; } @@ -268,7 +406,7 @@ static UINT16 readw_(CONST VOID *addr) UINT16 v = read16(addr); DEBUG((EFI_D_INFO, "%a read %4.4x from %4.4x\n", - __FUNCTION__, v, ((UINT32) addr & 0xffff) - 0xf020)); + __FUNCTION__, v, ((UINT64) addr & 0xffff) - 0xf020)); return v; } @@ -277,7 +415,7 @@ static UINT32 readl_(CONST VOID *addr) UINT32 v = read32(addr); DEBUG((EFI_D_INFO, "%a read %8.8x from %4.4x\n", - __FUNCTION__, v, ((UINT32) addr & 0xffff) - 0xf020)); + __FUNCTION__, v, ((UINT64) addr & 0xffff) - 0xf020)); return v; } @@ -285,21 +423,21 @@ static VOID writeb_(UINT8 b, VOID *addr) { write8(addr, b); DEBUG((EFI_D_INFO, "%a wrote %2.2x to %4.4x\n", - __FUNCTION__, b, ((UINT32) addr & 0xffff) - 0xf020)); + __FUNCTION__, b, ((UINT64) addr & 0xffff) - 0xf020)); } static VOID writew_(UINT16 b, VOID *addr) { write16(addr, b); DEBUG((EFI_D_INFO, "%a wrote %4.4x to %4.4x\n", - __FUNCTION__, b, ((UINT32) addr & 0xffff) - 0xf020)); + __FUNCTION__, b, ((UINT64) addr & 0xffff) - 0xf020)); } static VOID writel_(UINT32 b, VOID *addr) { write32(addr, b); DEBUG((EFI_D_INFO, "%a wrote %8.8x to %4.4x\n", - __FUNCTION__, b, ((UINT32) addr & 0xffff) - 0xf020)); + __FUNCTION__, b, ((UINT64) addr & 0xffff) - 0xf020)); } #else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ From e8a2ec30b88a5379b33a86994e5526b4c915450f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 13:20:33 +0200 Subject: [PATCH 131/297] fix some errors 2 --- UefiPayloadPkg/SPI/intelSPI.c | 104 +++++++++++++++++----------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index de2200f24f61..5fa0b7b25487 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -62,6 +62,19 @@ #define pci_write_config16 pci_s_write_config16 #define pci_write_config32 pci_s_write_config32 +typedef UINT32 pci_devfn_t; + +/* Convert pci_devfn_t to offset in MMCONF space. + * As it is one-to-one, nothing needs to be done. */ +#define PCI_DEVFN_OFFSET(x) ((x)) + +#define PCI_DEV(SEGBUS, DEV, FN) ( \ + (((SEGBUS) & 0xFFF) << 20) | \ + (((DEV) & 0x1F) << 15) | \ + (((FN) & 0x07) << 12)) + +#define PCI_DEV_INVALID (0xffffffffU) + typedef enum { BS_PRE_DEVICE, BS_DEV_INIT_CHIPS, @@ -137,7 +150,7 @@ struct spi_flash_ops { /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ -extern u8 *const pci_mmconf; +extern UINT8 *const pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ * qualify for pointer aliasing with any other objects in memory. @@ -152,51 +165,51 @@ extern u8 *const pci_mmconf; * in the functions below. */ union pci_bank { - uint8_t reg8[4096]; - uint16_t reg16[4096 / sizeof(uint16_t)]; - uint32_t reg32[4096 / sizeof(uint32_t)]; + UINT8 reg8[4096]; + UINT16 reg16[4096 / sizeof(UINT16)]; + UINT32 reg32[4096 / sizeof(UINT32)]; }; -static __always_inline +static __attribute__((always_inline)) volatile union pci_bank *pcicfg(pci_devfn_t dev) { return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } -static __always_inline -uint8_t pci_mmio_read_config8(pci_devfn_t dev, uint16_t reg) +static __attribute__((always_inline)) +UINT8 pci_mmio_read_config8(pci_devfn_t dev, UINT16 reg) { return pcicfg(dev)->reg8[reg]; } -static __always_inline -uint16_t pci_mmio_read_config16(pci_devfn_t dev, uint16_t reg) +static __attribute__((always_inline)) +UINT16 pci_mmio_read_config16(pci_devfn_t dev, UINT16 reg) { - return pcicfg(dev)->reg16[reg / sizeof(uint16_t)]; + return pcicfg(dev)->reg16[reg / sizeof(UINT16)]; } -static __always_inline -uint32_t pci_mmio_read_config32(pci_devfn_t dev, uint16_t reg) +static __attribute__((always_inline)) +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) { - return pcicfg(dev)->reg32[reg / sizeof(uint32_t)]; + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; } -static __always_inline -void pci_mmio_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value) +static __attribute__((always_inline)) +void pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) { pcicfg(dev)->reg8[reg] = value; } -static __always_inline -void pci_mmio_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value) +static __attribute__((always_inline)) +void pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) { - pcicfg(dev)->reg16[reg / sizeof(uint16_t)] = value; + pcicfg(dev)->reg16[reg / sizeof(UINT16)] = value; } -static __always_inline -void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) +static __attribute__((always_inline)) +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { - pcicfg(dev)->reg32[reg / sizeof(uint32_t)] = value; + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; } /* @@ -206,36 +219,23 @@ void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) * process. Thus, the pointer returned here must not be cached! */ static __always_inline -uint8_t *pci_mmio_config8_addr(pci_devfn_t dev, uint16_t reg) +UINT8 *pci_mmio_config8_addr(pci_devfn_t dev, UINT16 reg) { - return (uint8_t *)&pcicfg(dev)->reg8[reg]; + return (UINT8 *)&pcicfg(dev)->reg8[reg]; } static __always_inline -uint16_t *pci_mmio_config16_addr(pci_devfn_t dev, uint16_t reg) +UINT16 *pci_mmio_config16_addr(pci_devfn_t dev, UINT16 reg) { - return (uint16_t *)&pcicfg(dev)->reg16[reg / sizeof(uint16_t)]; + return (UINT16 *)&pcicfg(dev)->reg16[reg / sizeof(UINT16)]; } static __always_inline -uint32_t *pci_mmio_config32_addr(pci_devfn_t dev, uint16_t reg) +UINT32 *pci_mmio_config32_addr(pci_devfn_t dev, UINT16 reg) { - return (uint32_t *)&pcicfg(dev)->reg32[reg / sizeof(uint32_t)]; + return (UINT32 *)&pcicfg(dev)->reg32[reg / sizeof(UINT32)]; } -typedef UINT32 pci_devfn_t; - -/* Convert pci_devfn_t to offset in MMCONF space. - * As it is one-to-one, nothing needs to be done. */ -#define PCI_DEVFN_OFFSET(x) ((x)) - -#define PCI_DEV(SEGBUS, DEV, FN) ( \ - (((SEGBUS) & 0xFFF) << 20) | \ - (((DEV) & 0x1F) << 15) | \ - (((FN) & 0x07) << 12)) - -#define PCI_DEV_INVALID (0xffffffffU) - struct ich7_spi_regs { UINT16 spis; UINT16 spic; @@ -358,34 +358,34 @@ enum { SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 }; -static inline uint8_t read8(const void *addr) +static inline UINT8 read8(const void *addr) { - return *(volatile uint8_t *)addr; + return *(volatile UINT8 *)addr; } -static inline uint16_t read16(const void *addr) +static inline UINT16 read16(const void *addr) { - return *(volatile uint16_t *)addr; + return *(volatile UINT16 *)addr; } -static inline uint32_t read32(const void *addr) +static inline UINT32 read32(const void *addr) { - return *(volatile uint32_t *)addr; + return *(volatile UINT32 *)addr; } -static inline void write8(void *addr, uint8_t val) +static inline void write8(void *addr, UINT8 val) { - *(volatile uint8_t *)addr = val; + *(volatile UINT8 *)addr = val; } -static inline void write16(void *addr, uint16_t val) +static inline void write16(void *addr, UINT16 val) { - *(volatile uint16_t *)addr = val; + *(volatile UINT16 *)addr = val; } -static inline void write32(void *addr, uint32_t val) +static inline void write32(void *addr, UINT32 val) { - *(volatile uint32_t *)addr = val; + *(volatile UINT32 *)addr = val; } #define DEBUG_SPI_FLASH From 5dcecd39cd38c2740368b3e42fd5f76719d54297 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 13:33:57 +0200 Subject: [PATCH 132/297] fix some errors 3 --- UefiPayloadPkg/SPI/intelSPI.c | 24 ++++-------------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 5fa0b7b25487..61b7afe4f45b 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -62,6 +62,7 @@ #define pci_write_config16 pci_s_write_config16 #define pci_write_config32 pci_s_write_config32 +typedef unsigned long int uintptr_t; typedef UINT32 pci_devfn_t; /* Convert pci_devfn_t to offset in MMCONF space. @@ -218,19 +219,19 @@ void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) * assigned PCI bus number of the requested device, which both can change during the boot * process. Thus, the pointer returned here must not be cached! */ -static __always_inline +static __attribute__((always_inline)) UINT8 *pci_mmio_config8_addr(pci_devfn_t dev, UINT16 reg) { return (UINT8 *)&pcicfg(dev)->reg8[reg]; } -static __always_inline +static __attribute__((always_inline)) UINT16 *pci_mmio_config16_addr(pci_devfn_t dev, UINT16 reg) { return (UINT16 *)&pcicfg(dev)->reg16[reg / sizeof(UINT16)]; } -static __always_inline +static __attribute__((always_inline)) UINT32 *pci_mmio_config32_addr(pci_devfn_t dev, UINT16 reg) { return (UINT32 *)&pcicfg(dev)->reg32[reg / sizeof(UINT32)]; @@ -1346,23 +1347,6 @@ VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) { } -static CONST struct spi_ctrlr spi_ctrlr = { - .xfer_vector = xfer_vectors, - .max_xfer_size = member_size(struct ich9_spi_regs, fdata), - .flash_probe = spi_flash_programmer_probe, - .flash_protect = spi_flash_protect, -}; - -CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { - { - .ctrlr = &spi_ctrlr, - .bus_start = 0, - .bus_end = 0, - }, -}; - -CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); - /*----------------------------------------------------------------------- * Representation of a SPI controller. Note the xfer() and xfer_vector() From 6c981e5f6ef12a016f9cbdfa39531699dedd5b4b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 13:45:53 +0200 Subject: [PATCH 133/297] fix some errors 4 --- UefiPayloadPkg/SPI/intelSPI.c | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 61b7afe4f45b..1014646a715e 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -62,6 +62,42 @@ #define pci_write_config16 pci_s_write_config16 #define pci_write_config32 pci_s_write_config32 +static __always_inline +uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg) +{ + return pci_mmio_read_config8(dev, reg); +} + +static __always_inline +uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg) +{ + return pci_mmio_read_config16(dev, reg); +} + +static __always_inline +uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +static __always_inline +void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value) +{ + pci_mmio_write_config8(dev, reg, value); +} + +static __always_inline +void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value) +{ + pci_mmio_write_config16(dev, reg, value); +} + +static __always_inline +void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) +{ + pci_mmio_write_config32(dev, reg, value); +} + typedef unsigned long int uintptr_t; typedef UINT32 pci_devfn_t; From 1e9550808f77ea7cf2078a5265d6b358f7ccbdec Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 13:54:11 +0200 Subject: [PATCH 134/297] fix some errors 5 --- UefiPayloadPkg/SPI/intelSPI.c | 56 +++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 1014646a715e..804492a05cf5 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -62,45 +62,45 @@ #define pci_write_config16 pci_s_write_config16 #define pci_write_config32 pci_s_write_config32 -static __always_inline -uint8_t pci_s_read_config8(pci_devfn_t dev, uint16_t reg) +typedef unsigned long int uintptr_t; +typedef UINT32 pci_devfn_t; + +static __attribute__((always_inline)) +UINT8 pci_s_read_config8(pci_devfn_t dev, UINT16 reg) { return pci_mmio_read_config8(dev, reg); } -static __always_inline -uint16_t pci_s_read_config16(pci_devfn_t dev, uint16_t reg) +static __attribute__((always_inline)) +UINT16 pci_s_read_config16(pci_devfn_t dev, UINT16 reg) { return pci_mmio_read_config16(dev, reg); } -static __always_inline -uint32_t pci_s_read_config32(pci_devfn_t dev, uint16_t reg) +static __attribute__((always_inline)) +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) { return pci_mmio_read_config32(dev, reg); } -static __always_inline -void pci_s_write_config8(pci_devfn_t dev, uint16_t reg, uint8_t value) +static __attribute__((always_inline)) +VOID pci_s_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) { pci_mmio_write_config8(dev, reg, value); } -static __always_inline -void pci_s_write_config16(pci_devfn_t dev, uint16_t reg, uint16_t value) +static __attribute__((always_inline)) +VOID pci_s_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) { pci_mmio_write_config16(dev, reg, value); } -static __always_inline -void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) +static __attribute__((always_inline)) +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { pci_mmio_write_config32(dev, reg, value); } -typedef unsigned long int uintptr_t; -typedef UINT32 pci_devfn_t; - /* Convert pci_devfn_t to offset in MMCONF space. * As it is one-to-one, nothing needs to be done. */ #define PCI_DEVFN_OFFSET(x) ((x)) @@ -133,8 +133,8 @@ typedef enum { } boot_state_sequence_t; struct boot_state_callback { - void *arg; - void (*callback)(void *arg); + VOID *arg; + VOID (*callback)(VOID *arg); /* For use internal to the boot state machine. */ struct boot_state_callback *next; }; @@ -198,7 +198,7 @@ extern UINT8 *const pci_mmconf; * be also set for the build. * * Bottom 12 bits (4 KiB) are reserved to address the registers of a - * single PCI function. Declare the bank as a union to avoid some casting + * single PCI function. Declare the bank as a union to aVOID some casting * in the functions below. */ union pci_bank { @@ -210,7 +210,7 @@ union pci_bank { static __attribute__((always_inline)) volatile union pci_bank *pcicfg(pci_devfn_t dev) { - return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; + return (VOID *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } static __attribute__((always_inline)) @@ -232,19 +232,19 @@ UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) } static __attribute__((always_inline)) -void pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) +VOID pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) { pcicfg(dev)->reg8[reg] = value; } static __attribute__((always_inline)) -void pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) +VOID pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) { pcicfg(dev)->reg16[reg / sizeof(UINT16)] = value; } static __attribute__((always_inline)) -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +VOID pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; } @@ -395,32 +395,32 @@ enum { SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 }; -static inline UINT8 read8(const void *addr) +static inline UINT8 read8(const VOID *addr) { return *(volatile UINT8 *)addr; } -static inline UINT16 read16(const void *addr) +static inline UINT16 read16(const VOID *addr) { return *(volatile UINT16 *)addr; } -static inline UINT32 read32(const void *addr) +static inline UINT32 read32(const VOID *addr) { return *(volatile UINT32 *)addr; } -static inline void write8(void *addr, UINT8 val) +static inline VOID write8(VOID *addr, UINT8 val) { *(volatile UINT8 *)addr = val; } -static inline void write16(void *addr, UINT16 val) +static inline VOID write16(VOID *addr, UINT16 val) { *(volatile UINT16 *)addr = val; } -static inline void write32(void *addr, UINT32 val) +static inline VOID write32(VOID *addr, UINT32 val) { *(volatile UINT32 *)addr = val; } From 2db3334dfe683b8345e16a90833b519438564f77 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:00:32 +0200 Subject: [PATCH 135/297] fix some errors 6 --- UefiPayloadPkg/SPI/intelSPI.c | 120 +++++++++++++++++----------------- 1 file changed, 60 insertions(+), 60 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 804492a05cf5..78f19a717cd1 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -62,9 +62,69 @@ #define pci_write_config16 pci_s_write_config16 #define pci_write_config32 pci_s_write_config32 +/* Using a unique datatype for MMIO writes makes the pointers to _not_ + * qualify for pointer aliasing with any other objects in memory. + * + * MMIO offset is a value originally derived from 'struct device *' + * in ramstage. For the compiler to not discard this MMIO offset value + * from CPU registers after any MMIO writes, -fstrict-aliasing has to + * be also set for the build. + * + * Bottom 12 bits (4 KiB) are reserved to address the registers of a + * single PCI function. Declare the bank as a union to aVOID some casting + * in the functions below. + */ +union pci_bank { + UINT8 reg8[4096]; + UINT16 reg16[4096 / sizeof(UINT16)]; + UINT32 reg32[4096 / sizeof(UINT32)]; +}; + typedef unsigned long int uintptr_t; typedef UINT32 pci_devfn_t; +static __attribute__((always_inline)) +volatile union pci_bank *pcicfg(pci_devfn_t dev) +{ + return (VOID *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; +} + +static __attribute__((always_inline)) +UINT8 pci_mmio_read_config8(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg8[reg]; +} + +static __attribute__((always_inline)) +UINT16 pci_mmio_read_config16(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg16[reg / sizeof(UINT16)]; +} + +static __attribute__((always_inline)) +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +static __attribute__((always_inline)) +VOID pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) +{ + pcicfg(dev)->reg8[reg] = value; +} + +static __attribute__((always_inline)) +VOID pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) +{ + pcicfg(dev)->reg16[reg / sizeof(UINT16)] = value; +} + +static __attribute__((always_inline)) +VOID pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; +} + static __attribute__((always_inline)) UINT8 pci_s_read_config8(pci_devfn_t dev, UINT16 reg) { @@ -189,66 +249,6 @@ struct spi_flash_ops { * prevent some sub-optimal constant folding. */ extern UINT8 *const pci_mmconf; -/* Using a unique datatype for MMIO writes makes the pointers to _not_ - * qualify for pointer aliasing with any other objects in memory. - * - * MMIO offset is a value originally derived from 'struct device *' - * in ramstage. For the compiler to not discard this MMIO offset value - * from CPU registers after any MMIO writes, -fstrict-aliasing has to - * be also set for the build. - * - * Bottom 12 bits (4 KiB) are reserved to address the registers of a - * single PCI function. Declare the bank as a union to aVOID some casting - * in the functions below. - */ -union pci_bank { - UINT8 reg8[4096]; - UINT16 reg16[4096 / sizeof(UINT16)]; - UINT32 reg32[4096 / sizeof(UINT32)]; -}; - -static __attribute__((always_inline)) -volatile union pci_bank *pcicfg(pci_devfn_t dev) -{ - return (VOID *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; -} - -static __attribute__((always_inline)) -UINT8 pci_mmio_read_config8(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg8[reg]; -} - -static __attribute__((always_inline)) -UINT16 pci_mmio_read_config16(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg16[reg / sizeof(UINT16)]; -} - -static __attribute__((always_inline)) -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -static __attribute__((always_inline)) -VOID pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) -{ - pcicfg(dev)->reg8[reg] = value; -} - -static __attribute__((always_inline)) -VOID pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) -{ - pcicfg(dev)->reg16[reg / sizeof(UINT16)] = value; -} - -static __attribute__((always_inline)) -VOID pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} - /* * The functions pci_mmio_config*_addr provide a way to determine the MMIO address of a PCI * config register. The address returned is dependent of both the MMCONF base address and the From acf2df2e2520c942510d069faeaa0e49674adfc2 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:11:40 +0200 Subject: [PATCH 136/297] fix some errors 7 --- UefiPayloadPkg/SPI/intelSPI.c | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 78f19a717cd1..29075a076095 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -62,6 +62,21 @@ #define pci_write_config16 pci_s_write_config16 #define pci_write_config32 pci_s_write_config32 +/* Convert pci_devfn_t to offset in MMCONF space. + * As it is one-to-one, nothing needs to be done. */ +#define PCI_DEVFN_OFFSET(x) ((x)) + +#define PCI_DEV(SEGBUS, DEV, FN) ( \ + (((SEGBUS) & 0xFFF) << 20) | \ + (((DEV) & 0x1F) << 15) | \ + (((FN) & 0x07) << 12)) + +#define PCI_DEV_INVALID (0xffffffffU) + +/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we + * prevent some sub-optimal constant folding. */ +extern UINT8 *const pci_mmconf; + /* Using a unique datatype for MMIO writes makes the pointers to _not_ * qualify for pointer aliasing with any other objects in memory. * @@ -161,17 +176,6 @@ VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) pci_mmio_write_config32(dev, reg, value); } -/* Convert pci_devfn_t to offset in MMCONF space. - * As it is one-to-one, nothing needs to be done. */ -#define PCI_DEVFN_OFFSET(x) ((x)) - -#define PCI_DEV(SEGBUS, DEV, FN) ( \ - (((SEGBUS) & 0xFFF) << 20) | \ - (((DEV) & 0x1F) << 15) | \ - (((FN) & 0x07) << 12)) - -#define PCI_DEV_INVALID (0xffffffffU) - typedef enum { BS_PRE_DEVICE, BS_DEV_INIT_CHIPS, @@ -245,10 +249,6 @@ struct spi_flash_ops { int (*status)(CONST struct spi_flash *flash, UINT8 *reg); }; -/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we - * prevent some sub-optimal constant folding. */ -extern UINT8 *const pci_mmconf; - /* * The functions pci_mmio_config*_addr provide a way to determine the MMIO address of a PCI * config register. The address returned is dependent of both the MMCONF base address and the From 241b4575ab9a40f38f581fdeb444f22a1ac3af82 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:22:59 +0200 Subject: [PATCH 137/297] fix some errors 8 --- UefiPayloadPkg/SPI/intelSPI.c | 80 ++++++++++++++++++++++++++++------- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 29075a076095..24b191d9c183 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -98,79 +98,79 @@ union pci_bank { typedef unsigned long int uintptr_t; typedef UINT32 pci_devfn_t; -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline volatile union pci_bank *pcicfg(pci_devfn_t dev) { return (VOID *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT8 pci_mmio_read_config8(pci_devfn_t dev, UINT16 reg) { return pcicfg(dev)->reg8[reg]; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT16 pci_mmio_read_config16(pci_devfn_t dev, UINT16 reg) { return pcicfg(dev)->reg16[reg / sizeof(UINT16)]; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) { return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline VOID pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) { pcicfg(dev)->reg8[reg] = value; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline VOID pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) { pcicfg(dev)->reg16[reg / sizeof(UINT16)] = value; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline VOID pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT8 pci_s_read_config8(pci_devfn_t dev, UINT16 reg) { return pci_mmio_read_config8(dev, reg); } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT16 pci_s_read_config16(pci_devfn_t dev, UINT16 reg) { return pci_mmio_read_config16(dev, reg); } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) { return pci_mmio_read_config32(dev, reg); } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline VOID pci_s_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) { pci_mmio_write_config8(dev, reg, value); } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline VOID pci_s_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) { pci_mmio_write_config16(dev, reg, value); } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { pci_mmio_write_config32(dev, reg, value); @@ -255,19 +255,19 @@ struct spi_flash_ops { * assigned PCI bus number of the requested device, which both can change during the boot * process. Thus, the pointer returned here must not be cached! */ -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT8 *pci_mmio_config8_addr(pci_devfn_t dev, UINT16 reg) { return (UINT8 *)&pcicfg(dev)->reg8[reg]; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT16 *pci_mmio_config16_addr(pci_devfn_t dev, UINT16 reg) { return (UINT16 *)&pcicfg(dev)->reg16[reg / sizeof(UINT16)]; } -static __attribute__((always_inline)) +static __attribute__((always_inline)) inline UINT32 *pci_mmio_config32_addr(pci_devfn_t dev, UINT16 reg) { return (UINT32 *)&pcicfg(dev)->reg32[reg / sizeof(UINT32)]; @@ -1224,6 +1224,54 @@ static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, return 0; } +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + int (*func)(const struct spi_slave *slave, const void *dout, + __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)) +{ + int ret; + void *din; + __SIZE_TYPE__ bytes_in; + + if (count < 1 || count > 2) + return -1; + + /* SPI flash commands always have a command first... */ + if (!vectors[0].dout || !vectors[0].bytesout) + return -1; + /* And not read any data during the command. */ + if (vectors[0].din || vectors[0].bytesin) + return -1; + + if (count == 2) { + /* If response bytes requested ensure the buffer is valid. */ + if (vectors[1].bytesin && !vectors[1].din) + return -1; + /* No sends can accompany a receive. */ + if (vectors[1].dout || vectors[1].bytesout) + return -1; + din = vectors[1].din; + bytes_in = vectors[1].bytesin; + } else { + din = NULL; + bytes_in = 0; + } + + ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); + + if (ret) { + vectors[0].status = SPI_OP_FAILURE; + if (count == 2) + vectors[1].status = SPI_OP_FAILURE; + } else { + vectors[0].status = SPI_OP_SUCCESS; + if (count == 2) + vectors[1].status = SPI_OP_SUCCESS; + } + + return ret; +} + static INT32 xfer_vectors(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count) { From 3ae2006d2edec26671d32b623aa46d6866189dae Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:30:28 +0200 Subject: [PATCH 138/297] fix some errors 9 --- UefiPayloadPkg/SPI/intelSPI.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 24b191d9c183..95839ecffcb3 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -216,6 +216,7 @@ struct boot_state_init_entry { .next = NULL, \ } +#define BOOT_STATE_INIT_ATTR __attribute__((unused)) #define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \ static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \ @@ -225,7 +226,7 @@ struct boot_state_init_entry { .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \ }; \ static struct boot_state_init_entry * \ - bsie_ ## func_ ##_## state_ ##_## when_; \ + bsie_ ## func_ ##_## state_ ##_## when_ \ BOOT_STATE_INIT_ATTR = \ &func_ ##_## state_ ##_## when_; From fa01f26eb08f7dfb5f2e4a3653a4361163ca2902 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:34:33 +0200 Subject: [PATCH 139/297] fix some errors 10 --- UefiPayloadPkg/SPI/intelSPI.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 95839ecffcb3..fc9b60322ef1 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -176,6 +176,34 @@ VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) pci_mmio_write_config32(dev, reg, value); } +/* Function unit addresses. */ +enum { + UP_TAG_BASE = 0x60000000, + TIMER_BASE = 0x60005000, + CLK_RST_BASE = 0x60006000, + FLOW_CTLR_BASE = 0x60007000, + SECURE_BOOT_BASE = 0x6000C200, + TEGRA_EVP_BASE = 0x6000f000, + APB_MISC_BASE = 0x70000000, + PINMUX_BASE = 0x70003000, + PMC_CTLR_BASE = 0x7000e400, + MC_CTLR_BASE = 0x70019000, + FUSE_BASE = 0x7000F800, + TEGRA_SDMMC1_BASE = 0x700b0000, + TEGRA_SDMMC3_BASE = 0x700b0400, + EMC_BASE = 0x7001B000, + I2C5_BASE = 0x7000D000, + I2S_BASE = 0x702d1000 +}; + +static uint32_t *timer_us_ptr = (void *)(TIMER_BASE + 0x10); +static void udelay(unsigned int usecs) +{ + uint32_t start = read32(timer_us_ptr); + while (read32(timer_us_ptr) - start < usecs) + ; +} + typedef enum { BS_PRE_DEVICE, BS_DEV_INIT_CHIPS, From b2dead4a86ec28a9b873d0eaa23f513430d0ea4a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:38:18 +0200 Subject: [PATCH 140/297] fix some errors 11 --- UefiPayloadPkg/SPI/intelSPI.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index fc9b60322ef1..792b8645c985 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -196,8 +196,8 @@ enum { I2S_BASE = 0x702d1000 }; -static uint32_t *timer_us_ptr = (void *)(TIMER_BASE + 0x10); -static void udelay(unsigned int usecs) +static uint32_t *timer_us_ptr = (VOID *)(TIMER_BASE + 0x10); +static VOID udelay(UINT64 usecs) { uint32_t start = read32(timer_us_ptr); while (read32(timer_us_ptr) - start < usecs) @@ -1255,11 +1255,11 @@ static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, int spi_flash_vector_helper(const struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)) + int (*func)(const struct spi_slave *slave, const VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) { int ret; - void *din; + VOID *din; __SIZE_TYPE__ bytes_in; if (count < 1 || count > 2) From 83ba6c0ee718f1f1b7014125ecb47f5f4038a71d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:48:35 +0200 Subject: [PATCH 141/297] fix some errors 12 --- UefiPayloadPkg/SPI/intelSPI.c | 86 +++++++++++++++++++++++++++++------ 1 file changed, 71 insertions(+), 15 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 792b8645c985..1d7579133569 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -37,6 +37,23 @@ #define SPI_OPCODE_WREN 0x06 #define SPI_OPCODE_FAST_READ 0x0b +/* Common commands */ +#define CMD_READ_ID 0x9f + +#define CMD_READ_ARRAY_SLOW 0x03 +#define CMD_READ_ARRAY_FAST 0x0b +#define CMD_READ_ARRAY_LEGACY 0xe8 + +#define CMD_READ_FAST_DUAL_OUTPUT 0x3b + +#define CMD_READ_STATUS 0x05 +#define CMD_WRITE_ENABLE 0x06 + +#define CMD_BLOCK_ERASE 0xD8 + +/* Common status */ +#define STATUS_WIP 0x01 + #define NSECS_PER_SEC 1000000000 #define USECS_PER_SEC 1000000 #define MSECS_PER_SEC 1000 @@ -75,7 +92,7 @@ /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ -extern UINT8 *const pci_mmconf; +extern UINT8 *CONST pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ * qualify for pointer aliasing with any other objects in memory. @@ -95,7 +112,6 @@ union pci_bank { UINT32 reg32[4096 / sizeof(UINT32)]; }; -typedef unsigned long int uintptr_t; typedef UINT32 pci_devfn_t; static __attribute__((always_inline)) inline @@ -196,10 +212,12 @@ enum { I2S_BASE = 0x702d1000 }; -static uint32_t *timer_us_ptr = (VOID *)(TIMER_BASE + 0x10); +#define IDCODE_LEN 5 + +static UINT32 *timer_us_ptr = (VOID *)(TIMER_BASE + 0x10); static VOID udelay(UINT64 usecs) { - uint32_t start = read32(timer_us_ptr); + UINT32 start = read32(timer_us_ptr); while (read32(timer_us_ptr) - start < usecs) ; } @@ -270,12 +288,12 @@ typedef UINT32 pci_devfn_t; * status: Read flash status register. */ struct spi_flash_ops { - int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + INT64 (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); - int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + INT64 (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, CONST VOID *buf); - int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - int (*status)(CONST struct spi_flash *flash, UINT8 *reg); + INT64 (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + INT64 (*status)(CONST struct spi_flash *flash, UINT8 *reg); }; /* @@ -424,17 +442,17 @@ enum { SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 }; -static inline UINT8 read8(const VOID *addr) +static inline UINT8 read8(CONST VOID *addr) { return *(volatile UINT8 *)addr; } -static inline UINT16 read16(const VOID *addr) +static inline UINT16 read16(CONST VOID *addr) { return *(volatile UINT16 *)addr; } -static inline UINT32 read32(const VOID *addr) +static inline UINT32 read32(CONST VOID *addr) { return *(volatile UINT32 *)addr; } @@ -830,7 +848,7 @@ static INT32 spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { UINT16 control; - int16_t opcode_index; + INT16 opcode_index; INT32 with_address; INT32 status; @@ -1213,6 +1231,44 @@ static CONST struct spi_flash_ops spi_flash_ops = { .erase = ich_hwseq_erase, }; +INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, + struct spi_flash *flash) +{ + INT64 ret, i; + UINT8 idcode[IDCODE_LEN]; + UINT8 manuf_id; + UINT16 id[2]; + + /* Read the ID codes */ + ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); + if (ret) + return -1; + + if (CONFIG(DEBUG_SPI_FLASH)) { + DEBUG((EFI_D_INFO, "%a SF: Got idcode: ", __FUNCTION__)); + for (i = 0; i < sizeof(idcode); i++) + DEBUG((EFI_D_INFO, "%a %02x ", __FUNCTION__, idcode[i])); + DEBUG((EFI_D_INFO, "%a \n", __FUNCTION__)); + } + + manuf_id = idcode[0]; + + DEBUG((EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); + + /* If no result from RDID command and STMicro parts are enabled attempt + to wake the part from deep sleep and obtain alternative id info. */ + if (CONFIG(SPI_FLASH_STMICRO) && manuf_id == 0xff) { + if (stmicro_release_deep_sleep_identify(spi, idcode)) + return -1; + manuf_id = idcode[0]; + } + + id[0] = (idcode[1] << 8) | idcode[2]; + id[1] = (idcode[3] << 8) | idcode[4]; + + return find_match(spi, flash, manuf_id, id); +} + static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, struct spi_flash *flash) { @@ -1253,12 +1309,12 @@ static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, return 0; } -int spi_flash_vector_helper(const struct spi_slave *slave, +INT64 spi_flash_vector_helper(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const VOID *dout, + INT64 (*func)(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) { - int ret; + INT64 ret; VOID *din; __SIZE_TYPE__ bytes_in; From 9c5dc40c90ba661af2fa9ad8dd6c648f82d25137 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 24 Sep 2020 14:55:01 +0200 Subject: [PATCH 142/297] fix some errors 13 --- UefiPayloadPkg/SPI/intelSPI.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 1d7579133569..bc7abac66248 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -212,16 +212,6 @@ enum { I2S_BASE = 0x702d1000 }; -#define IDCODE_LEN 5 - -static UINT32 *timer_us_ptr = (VOID *)(TIMER_BASE + 0x10); -static VOID udelay(UINT64 usecs) -{ - UINT32 start = read32(timer_us_ptr); - while (read32(timer_us_ptr) - start < usecs) - ; -} - typedef enum { BS_PRE_DEVICE, BS_DEV_INIT_CHIPS, @@ -472,6 +462,16 @@ static inline VOID write32(VOID *addr, UINT32 val) *(volatile UINT32 *)addr = val; } +#define IDCODE_LEN 5 + +static UINT32 *timer_us_ptr = (VOID *)(TIMER_BASE + 0x10); +static VOID udelay(UINT64 usecs) +{ + UINT32 start = read32(timer_us_ptr); + while (read32(timer_us_ptr) - start < usecs) + ; +} + #define DEBUG_SPI_FLASH #ifdef DEBUG_SPI_FLASH @@ -587,8 +587,8 @@ static VOID ich_set_bbar(UINT32 minaddr) static VOID *get_spi_bar(pci_devfn_t dev) { - uintptr_t rcba; /* Root Complex Register Block */ - uintptr_t sbase; + unsigned long int rcba; /* Root Complex Register Block */ + unsigned long int sbase; if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { rcba = pci_read_config32(dev, RCBA); From a94154a888047ad8f07732e226f2a438de3ea5e1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 07:34:48 +0200 Subject: [PATCH 143/297] fix some errors 14 --- UefiPayloadPkg/SPI/intelSPI.c | 48 ++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index bc7abac66248..62382c89c745 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -278,12 +278,12 @@ typedef UINT32 pci_devfn_t; * status: Read flash status register. */ struct spi_flash_ops { - INT64 (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); - INT64 (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, CONST VOID *buf); - INT64 (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - INT64 (*status)(CONST struct spi_flash *flash, UINT8 *reg); + int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + int (*status)(CONST struct spi_flash *flash, UINT8 *reg); }; /* @@ -1046,13 +1046,13 @@ static INT32 ich_hwseq_wait_for_cycle_complete(UINT32 timeout, } -static INT32 ich_hwseq_erase(CONST struct spi_flash *flash, UINT32 offset, +static int ich_hwseq_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) { UINT32 start, end, erase_size; - INT32 ret; + int ret; UINT16 hsfc; - UINT32 timeout = 1000 * USECS_PER_MSEC; /* 1 second timeout */ + unsigned int timeout = 1000 * USECS_PER_MSEC; /* 1 second timeout */ erase_size = flash->sector_size; if (offset % erase_size || len % erase_size) { @@ -1109,18 +1109,19 @@ static VOID ich_read_data(UINT8 *data, INT32 len) } } -static INT32 ich_hwseq_read(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - VOID *buf) +static int ich_hwseq_read(const struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, + void *buf) { UINT16 hsfc; UINT16 timeout = 100 * 60; - UINT8 block_len; + uint8_t block_len; if (addr + len > flash->size) { - DEBUG((EFI_D_INFO, "%a Attempt to read %x-%x which is out of chip\n", + DEBUG((EFI_D_INFO, + "%a Attempt to read %x-%x which is out of chip\n", __FUNCTION__, - (UINT32) addr, - (UINT32) addr+(UINT32) len)); + (unsigned int) addr, + (unsigned int) addr+(unsigned int) len)); return -1; } @@ -1177,17 +1178,18 @@ static VOID ich_fill_data(CONST UINT8 *data, INT32 len) writel_(temp32, cntlr.data + (i - (i % 4))); } -static INT32 ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - CONST VOID *buf) +static int ich_hwseq_write(const struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, + const void *buf) { UINT16 hsfc; UINT16 timeout = 100 * 60; - UINT8 block_len; - UINT32 start = addr; + uint8_t block_len; + uint32_t start = addr; if (addr + len > flash->size) { - DEBUG((EFI_D_INFO, "%a Attempt to write 0x%x-0x%x which is out of chip\n", - __FUNCTION__, (UINT32)addr, (UINT32) (addr+len))); + printk(BIOS_ERR, + "Attempt to write 0x%x-0x%x which is out of chip\n", + (unsigned int)addr, (unsigned int) (addr+len)); return -1; } @@ -1212,16 +1214,16 @@ static INT32 ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, __SIZE_ writew_(hsfc, &cntlr.ich9_spi->hsfc); if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) { - DEBUG((EFI_D_INFO, "%a SF: write failure at %x\n", - __FUNCTION__, addr)); + printk(BIOS_ERR, "SF: write failure at %x\n", + addr); return -1; } addr += block_len; buf += block_len; len -= block_len; } - DEBUG((EFI_D_INFO, "%a SF: Successfully written %u bytes @ %#x\n", - __FUNCTION__, (UINT32) (addr - start), start)); + printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", + (unsigned int) (addr - start), start); return 0; } From 8e6ee3d2ae28ad4f4331facdd38c3da2f744c6db Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 07:39:33 +0200 Subject: [PATCH 144/297] fix some errors 15 --- UefiPayloadPkg/SPI/intelSPI.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 62382c89c745..c577aff33874 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1114,7 +1114,7 @@ static int ich_hwseq_read(const struct spi_flash *flash, UINT32 addr, __SIZE_TYP { UINT16 hsfc; UINT16 timeout = 100 * 60; - uint8_t block_len; + UINT8 block_len; if (addr + len > flash->size) { DEBUG((EFI_D_INFO, @@ -1183,13 +1183,13 @@ static int ich_hwseq_write(const struct spi_flash *flash, UINT32 addr, __SIZE_TY { UINT16 hsfc; UINT16 timeout = 100 * 60; - uint8_t block_len; - uint32_t start = addr; + UINT8 block_len; + UINT32 start = addr; if (addr + len > flash->size) { - printk(BIOS_ERR, - "Attempt to write 0x%x-0x%x which is out of chip\n", - (unsigned int)addr, (unsigned int) (addr+len)); + DEBUG((EFI_D_INFO, + "%a Attempt to write 0x%x-0x%x which is out of chip\n", + __FUNCTION__, (unsigned int)addr, (unsigned int) (addr+len))); return -1; } @@ -1214,16 +1214,16 @@ static int ich_hwseq_write(const struct spi_flash *flash, UINT32 addr, __SIZE_TY writew_(hsfc, &cntlr.ich9_spi->hsfc); if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) { - printk(BIOS_ERR, "SF: write failure at %x\n", - addr); + DEBUG((EFI_D_INFO, "%a SF: write failure at %x\n", + __FUNCTION__, addr)); return -1; } addr += block_len; buf += block_len; len -= block_len; } - printk(BIOS_DEBUG, "SF: Successfully written %u bytes @ %#x\n", - (unsigned int) (addr - start), start); + DEBUG((EFI_D_INFO, "%a SF: Successfully written %u bytes @ %#x\n", + __FUNCTION__, (unsigned int) (addr - start), start)); return 0; } From 3f5ad574692703fc52643ad25d841e6817ed0c6c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 07:44:58 +0200 Subject: [PATCH 145/297] fix some errors 16 --- UefiPayloadPkg/SPI/intelSPI.c | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index c577aff33874..f3353a944b29 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1233,6 +1233,48 @@ static CONST struct spi_flash_ops spi_flash_ops = { .erase = ich_hwseq_erase, }; +int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len) +{ + int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); + if (ret) + DEBUG((EFI_D_INFO, "%a SF: Failed to send command %02x: %d\n", + __FUNCTION__, cmd, ret)); + + return ret; +} + +/* M25Pxx-specific commands */ +#define CMD_M25PXX_WREN 0x06 /* Write Enable */ +#define CMD_M25PXX_WRDI 0x04 /* Write Disable */ +#define CMD_M25PXX_RDSR 0x05 /* Read Status Register */ +#define CMD_M25PXX_WRSR 0x01 /* Write Status Register */ +#define CMD_M25PXX_READ 0x03 /* Read Data Bytes */ +#define CMD_M25PXX_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ +#define CMD_M25PXX_PP 0x02 /* Page Program */ +#define CMD_M25PXX_SSE 0x20 /* Subsector Erase */ +#define CMD_M25PXX_SE 0xd8 /* Sector Erase */ +#define CMD_M25PXX_BE 0xc7 /* Bulk Erase */ +#define CMD_M25PXX_DP 0xb9 /* Deep Power-down */ +#define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */ + +int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idcode) +{ + if (spi_flash_cmd(spi, CMD_M25PXX_RES, idcode, 4)) + return -1; + + /* Assuming ST parts identify with 0x1X to release from deep + power down and read electronic signature. */ + if ((idcode[3] & 0xf0) != 0x10) + return -1; + + /* Fix up the idcode to mimic rdid jedec instruction. */ + idcode[0] = 0x20; + idcode[1] = 0x20; + idcode[2] = idcode[3] + 1; + + return 0; +} + INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, struct spi_flash *flash) { From 86112adb45d9a2effe53dd9884cfcfecf5041acc Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 07:45:59 +0200 Subject: [PATCH 146/297] fix some errors 17 --- UefiPayloadPkg/SPI/intelSPI.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index f3353a944b29..e7d6f21444eb 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1110,7 +1110,7 @@ static VOID ich_read_data(UINT8 *data, INT32 len) } static int ich_hwseq_read(const struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - void *buf) + VOID *buf) { UINT16 hsfc; UINT16 timeout = 100 * 60; @@ -1179,7 +1179,7 @@ static VOID ich_fill_data(CONST UINT8 *data, INT32 len) } static int ich_hwseq_write(const struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - const void *buf) + const VOID *buf) { UINT16 hsfc; UINT16 timeout = 100 * 60; @@ -1233,7 +1233,7 @@ static CONST struct spi_flash_ops spi_flash_ops = { .erase = ich_hwseq_erase, }; -int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len) +int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) { int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); if (ret) From bb8ff71811cf41aeb563eba05d5b277a225dafaa Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 08:34:31 +0200 Subject: [PATCH 147/297] fix some errors 18 --- UefiPayloadPkg/SPI/SPI.h | 16 + UefiPayloadPkg/SPI/intelSPI.c | 123 ++++- UefiPayloadPkg/SPI/intelSPI.h | 4 +- UefiPayloadPkg/SPI/spi_flash_internal.h | 131 ++++++ UefiPayloadPkg/SPI/spi_winbond.h | 23 + UefiPayloadPkg/SPI/winbond.c | 588 ++++++++++++++++++++++++ 6 files changed, 861 insertions(+), 24 deletions(-) create mode 100644 UefiPayloadPkg/SPI/spi_flash_internal.h create mode 100644 UefiPayloadPkg/SPI/spi_winbond.h create mode 100644 UefiPayloadPkg/SPI/winbond.c diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index d8f6db56d393..2568a3c083ad 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -31,6 +31,22 @@ typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; +/* + * Representation of SPI flash operations: + * read: Flash read operation. + * write: Flash write operation. + * erase: Flash erase operation. + * status: Read flash status register. + */ +struct spi_flash_ops { + int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + VOID *buf); + int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + CONST VOID *buf); + int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + int (*status)(CONST struct spi_flash *flash, UINT8 *reg); +}; + #pragma pack (1) typedef struct { VENDOR_DEVICE_PATH Vendor; diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index e7d6f21444eb..d7aa3377db52 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -270,22 +270,6 @@ static INT32 spi_is_multichip(VOID); typedef UINT32 pci_devfn_t; -/* - * Representation of SPI flash operations: - * read: Flash read operation. - * write: Flash write operation. - * erase: Flash erase operation. - * status: Read flash status register. - */ -struct spi_flash_ops { - int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - VOID *buf); - int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - CONST VOID *buf); - int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - int (*status)(CONST struct spi_flash *flash, UINT8 *reg); -}; - /* * The functions pci_mmio_config*_addr provide a way to determine the MMIO address of a PCI * config register. The address returned is dependent of both the MMCONF base address and the @@ -1046,7 +1030,7 @@ static INT32 ich_hwseq_wait_for_cycle_complete(UINT32 timeout, } -static int ich_hwseq_erase(const struct spi_flash *flash, UINT32 offset, +static int ich_hwseq_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) { UINT32 start, end, erase_size; @@ -1109,7 +1093,7 @@ static VOID ich_read_data(UINT8 *data, INT32 len) } } -static int ich_hwseq_read(const struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, +static int ich_hwseq_read(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, VOID *buf) { UINT16 hsfc; @@ -1178,8 +1162,8 @@ static VOID ich_fill_data(CONST UINT8 *data, INT32 len) writel_(temp32, cntlr.data + (i - (i % 4))); } -static int ich_hwseq_write(const struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - const VOID *buf) +static int ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, + CONST VOID *buf) { UINT16 hsfc; UINT16 timeout = 100 * 60; @@ -1233,7 +1217,38 @@ static CONST struct spi_flash_ops spi_flash_ops = { .erase = ich_hwseq_erase, }; -int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) +static int do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout, + __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) +{ + int ret; + /* + * SPI flash requires command-response kind of behavior. Thus, two + * separate SPI vectors are required -- first to transmit dout and other + * to receive in din. If some specialized SPI flash controllers + * (e.g. x86) can perform both command and response together, it should + * be handled at SPI flash controller driver level. + */ + struct spi_op vectors[] = { + [0] = { .dout = dout, .bytesout = bytes_out, + .din = NULL, .bytesin = 0, }, + [1] = { .dout = NULL, .bytesout = 0, + .din = din, .bytesin = bytes_in }, + }; + __SIZE_TYPE__ count = ARRAY_SIZE(vectors); + if (!bytes_in) + count = 1; + + ret = spi_claim_bus(spi); + if (ret) + return ret; + + ret = spi_xfer_vector(spi, vectors, count); + + spi_release_bus(spi); + return ret; +} + +int spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) { int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); if (ret) @@ -1257,7 +1272,7 @@ int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE #define CMD_M25PXX_DP 0xb9 /* Deep Power-down */ #define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */ -int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idcode) +int stmicro_release_deep_sleep_identify(CONST struct spi_slave *spi, UINT8 *idcode) { if (spi_flash_cmd(spi, CMD_M25PXX_RES, idcode, 4)) return -1; @@ -1275,6 +1290,70 @@ int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idco return 0; } +static const struct spi_flash_vendor_info *spi_flash_vendors[] = { +#if CONFIG(SPI_FLASH_ADESTO) + &spi_flash_adesto_vi, +#endif +#if CONFIG(SPI_FLASH_AMIC) + &spi_flash_amic_vi, +#endif +#if CONFIG(SPI_FLASH_ATMEL) + &spi_flash_atmel_vi, +#endif +#if CONFIG(SPI_FLASH_EON) + &spi_flash_eon_vi, +#endif +#if CONFIG(SPI_FLASH_GIGADEVICE) + &spi_flash_gigadevice_vi, +#endif +#if CONFIG(SPI_FLASH_MACRONIX) + &spi_flash_macronix_vi, +#endif +#if CONFIG(SPI_FLASH_SPANSION) + &spi_flash_spansion_ext1_vi, + &spi_flash_spansion_ext2_vi, + &spi_flash_spansion_vi, +#endif +#if CONFIG(SPI_FLASH_SST) + &spi_flash_sst_ai_vi, + &spi_flash_sst_vi, +#endif +#if CONFIG(SPI_FLASH_STMICRO) + &spi_flash_stmicro1_vi, + &spi_flash_stmicro2_vi, + &spi_flash_stmicro3_vi, + &spi_flash_stmicro4_vi, +#endif +#if CONFIG(SPI_FLASH_WINBOND) + &spi_flash_winbond_vi, +#endif +}; + +static int find_match(CONST struct spi_slave *spi, struct spi_flash *flash, + UINT8 manuf_id, uint16_t id[2]) +{ + int i; + + for (i = 0; i < (int)ARRAY_SIZE(spi_flash_vendors); i++) { + CONST struct spi_flash_vendor_info *vi; + CONST struct spi_flash_part_id *part; + + vi = spi_flash_vendors[i]; + + if (manuf_id != vi->id) + continue; + + part = find_part(vi, id); + + if (part == NULL) + continue; + + return fill_spi_flash(spi, flash, vi, part); + } + + return -1; +} + INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, struct spi_flash *flash) { diff --git a/UefiPayloadPkg/SPI/intelSPI.h b/UefiPayloadPkg/SPI/intelSPI.h index f03e11c312f0..2e6b396d9d5f 100644 --- a/UefiPayloadPkg/SPI/intelSPI.h +++ b/UefiPayloadPkg/SPI/intelSPI.h @@ -12,12 +12,12 @@ enum optype { }; struct intel_spi_op { - u8 op; + UINT8 op; enum optype type; }; struct intel_swseq_spi_config { - u8 opprefixes[2]; + UINT8 opprefixes[2]; struct intel_spi_op ops[8]; }; diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h new file mode 100644 index 000000000000..f04e7b0320ba --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_flash_internal.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include "SPI.h" + +/* + * SPI flash internal definitions + */ + +#ifndef SPI_FLASH_INTERNAL_H +#define SPI_FLASH_INTERNAL_H + +/* Common commands */ +#define CMD_READ_ID 0x9f + +#define CMD_READ_ARRAY_SLOW 0x03 +#define CMD_READ_ARRAY_FAST 0x0b +#define CMD_READ_ARRAY_LEGACY 0xe8 + +#define CMD_READ_FAST_DUAL_OUTPUT 0x3b + +#define CMD_READ_STATUS 0x05 +#define CMD_WRITE_ENABLE 0x06 + +#define CMD_BLOCK_ERASE 0xD8 + +/* Common status */ +#define STATUS_WIP 0x01 + +/* Send a single-byte command to the device and read the response */ +int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); + +/* + * Send a multi-byte command to the device followed by (optional) + * data. Used for programming the flash array, etc. + */ +int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, + __SIZE_TYPE__ cmd_len, const VOID *data, __SIZE_TYPE__ data_len); + +/* Send a command to the device and wait for some bit to clear itself. */ +int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, + UINT8 cmd, UINT8 poll_bit); + +/* + * Send the read status command to the device and wait for the wip + * (write-in-progress) bit to clear itself. + */ +int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout); + +/* Erase sectors. */ +int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + +/* Read status register. */ +int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg); + +/* Write to flash utilizing page program semantics. */ +int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, const VOID *buf); + +/* Read len bytes into buf at offset. */ +int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); + +/* Release from deep sleep an provide alternative rdid information. */ +int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idcode); + +struct spi_flash_part_id { + /* rdid command constructs 2x 16-bit id using the following method + * for matching after reading 5 bytes (1st byte is manuf id): + * id[0] = (id[1] << 8) | id[2] + * id[1] = (id[3] << 8) | id[4] + */ + uint16_t id[2]; + /* Log based 2 total number of sectors. */ + uint16_t nr_sectors_shift: 4; + uint16_t fast_read_dual_output_support : 1; + uint16_t _reserved_for_flags: 3; + /* Block protection. Currently used by Winbond. */ + uint16_t protection_granularity_shift : 5; + uint16_t bp_bits : 3; +}; + +struct spi_flash_ops_descriptor { + uint8_t erase_cmd; /* Sector Erase */ + uint8_t status_cmd; /* Read Status Register */ + uint8_t pp_cmd; /* Page program command, if supported. */ + uint8_t wren_cmd; /* Write Enable command. */ + struct spi_flash_ops ops; +}; + +/* Vendor info represents a common set of organization and commands by a given + * vendor. One can implement multiple sets from a single vendor by having + * separate objects. */ +struct spi_flash_vendor_info { + uint8_t id; + uint8_t page_size_shift : 4; /* if page programming oriented. */ + /* Log based 2 sector size */ + uint8_t sector_size_kib_shift : 4; + uint16_t nr_part_ids; + const struct spi_flash_part_id *ids; + uint16_t match_id_mask[2]; /* matching bytes of the id for this set*/ + const struct spi_flash_ops_descriptor *desc; + const struct spi_flash_protection_ops *prot_ops; + /* Returns 0 on success. !0 otherwise. */ + int (*after_probe)(const struct spi_flash *flash); +}; + +/* Manufacturer-specific probe information */ +extern const struct spi_flash_vendor_info spi_flash_adesto_vi; +extern const struct spi_flash_vendor_info spi_flash_amic_vi; +extern const struct spi_flash_vendor_info spi_flash_atmel_vi; +extern const struct spi_flash_vendor_info spi_flash_eon_vi; +extern const struct spi_flash_vendor_info spi_flash_gigadevice_vi; +extern const struct spi_flash_vendor_info spi_flash_macronix_vi; +/* Probing order matters between the spansion sequence. */ +extern const struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; +extern const struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; +extern const struct spi_flash_vendor_info spi_flash_spansion_vi; +extern const struct spi_flash_vendor_info spi_flash_sst_ai_vi; +extern const struct spi_flash_vendor_info spi_flash_sst_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro1_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro2_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro3_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro4_vi; +extern const struct spi_flash_vendor_info spi_flash_winbond_vi; + +/* Page Programming Command Set with 0x20 Sector Erase command. */ +extern const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; +/* Page Programming Command Set with 0xd8 Sector Erase command. */ +extern const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; + +#endif /* SPI_FLASH_INTERNAL_H */ diff --git a/UefiPayloadPkg/SPI/spi_winbond.h b/UefiPayloadPkg/SPI/spi_winbond.h new file mode 100644 index 000000000000..bdf669430681 --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_winbond.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Winbond specific function */ +/* M25Pxx-specific commands */ +#define CMD_W25_WREN 0x06 /* Write Enable */ +#define CMD_W25_WRDI 0x04 /* Write Disable */ +#define CMD_W25_RDSR 0x05 /* Read Status Register */ +#define CMD_W25_WRSR 0x01 /* Write Status Register */ +#define CMD_W25_RDSR2 0x35 /* Read Status2 Register */ +#define CMD_W25_WRSR2 0x31 /* Write Status2 Register */ +#define CMD_W25_READ 0x03 /* Read Data Bytes */ +#define CMD_W25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ +#define CMD_W25_PP 0x02 /* Page Program */ +#define CMD_W25_SE 0x20 /* Sector (4K) Erase */ +#define CMD_W25_RDID 0x9f /* Read ID */ +#define CMD_W25_BE 0xd8 /* Block (64K) Erase */ +#define CMD_W25_CE 0xc7 /* Chip Erase */ +#define CMD_W25_DP 0xb9 /* Deep Power-down */ +#define CMD_W25_RES 0xab /* Release from DP and Read Signature */ +#define CMD_VOLATILE_SREG_WREN 0x50 /* Write Enable for Volatile SREG */ + +/* tw: Maximum time to write a flash cell in milliseconds */ +#define WINBOND_FLASH_TIMEOUT 30 diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/winbond.c new file mode 100644 index 000000000000..b19a3825be26 --- /dev/null +++ b/UefiPayloadPkg/SPI/winbond.c @@ -0,0 +1,588 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include "spi_winbond.h" +#include "spi_flash_internal.h" + +union status_reg1 { + UINT8 u; + struct { + UINT8 busy : 1; + UINT8 wel : 1; + UINT8 bp : 3; + UINT8 tb : 1; + UINT8 sec : 1; + UINT8 srp0 : 1; + } bp3; + struct { + UINT8 busy : 1; + UINT8 wel : 1; + UINT8 bp : 4; + UINT8 tb : 1; + UINT8 srp0 : 1; + } bp4; +}; + +union status_reg2 { + UINT8 u; + struct { + UINT8 srp1 : 1; + UINT8 qe : 1; + UINT8 res : 1; + UINT8 lb : 3; + UINT8 cmp : 1; + UINT8 sus : 1; + }; +}; + +struct status_regs { + union { + struct { +#if defined(__BIG_ENDIAN) + union status_reg2 reg2; + union status_reg1 reg1; +#else + union status_reg1 reg1; + union status_reg2 reg2; +#endif + }; + UINT16 u; + }; +}; + +static CONST struct spi_flash_part_id flash_table[] = { + { + /* W25P80 */ + .id[0] = 0x2014, + .nr_sectors_shift = 8, + }, + { + /* W25P16 */ + .id[0] = 0x2015, + .nr_sectors_shift = 9, + }, + { + /* W25P32 */ + .id[0] = 0x2016, + .nr_sectors_shift = 10, + }, + { + /* W25X80 */ + .id[0] = 0x3014, + .nr_sectors_shift = 8, + .fast_read_dual_output_support = 1, + }, + { + /* W25X16 */ + .id[0] = 0x3015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + }, + { + /* W25X32 */ + .id[0] = 0x3016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + }, + { + /* W25X64 */ + .id[0] = 0x3017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + }, + { + /* W25Q80_V */ + .id[0] = 0x4014, + .nr_sectors_shift = 8, + .fast_read_dual_output_support = 1, + }, + { + /* W25Q16_V */ + .id[0] = 0x4015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q16DW */ + .id[0] = 0x6015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q32_V */ + .id[0] = 0x4016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q32DW */ + .id[0] = 0x6016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q64_V */ + .id[0] = 0x4017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q64DW */ + .id[0] = 0x6017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q64JW */ + .id[0] = 0x8017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q128_V */ + .id[0] = 0x4018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128FW */ + .id[0] = 0x6018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128J */ + .id[0] = 0x7018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128JW */ + .id[0] = 0x8018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q256_V */ + .id[0] = 0x4019, + .nr_sectors_shift = 13, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 4, + }, + { + /* W25Q256J */ + .id[0] = 0x7019, + .nr_sectors_shift = 13, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 4, + }, +}; + +/* + * Convert BPx, TB and CMP to a region. + * SEC (if available) must be zero. + */ +static void winbond_bpbits_to_region(CONST __SIZE_TYPE__ granularity, + CONST UINT8 bp, + BOOLEAN tb, + CONST BOOLEAN cmp, + CONST __SIZE_TYPE__ flash_size, + struct region *out) +{ + __SIZE_TYPE__ protected_size = + MIN(bp ? granularity << (bp - 1) : 0, flash_size); + + if (cmp) { + protected_size = flash_size - protected_size; + tb = !tb; + } + + out->offset = tb ? 0 : flash_size - protected_size; + out->size = protected_size; +} + +/* + * Available on all devices. + * Read block protect bits from Status/Status2 Reg. + * Converts block protection bits to a region. + * + * Returns: + * -1 on error + * 1 if region is covered by write protection + * 0 if a part of region isn't covered by write protection + */ +static int winbond_get_write_protection(CONST struct spi_flash *flash, + CONST struct region *region) +{ + CONST struct spi_flash_part_id *params; + struct region wp_region; + union status_reg2 reg2; + UINT8 bp, tb; + int ret; + + params = flash->part; + + if (!params) + return -1; + + CONST __SIZE_TYPE__ granularity = (1 << params->protection_granularity_shift); + + union status_reg1 reg1 = { .u = 0 }; + + ret = spi_flash_cmd(&flash->spi, flash->status_cmd, ®1.u, + sizeof(reg1.u)); + if (ret) + return ret; + + if (params->bp_bits == 3) { + if (reg1.bp3.sec) { + // FIXME: not supported + return -1; + } + + bp = reg1.bp3.bp; + tb = reg1.bp3.tb; + } else if (params->bp_bits == 4) { + bp = reg1.bp4.bp; + tb = reg1.bp4.tb; + } else { + // FIXME: not supported + return -1; + } + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®2.u, + sizeof(reg2.u)); + if (ret) + return ret; + + winbond_bpbits_to_region(granularity, bp, tb, reg2.cmp, flash->size, + &wp_region); + + if (!region_sz(&wp_region)) { + DEBUG((EFI_D_INFO, "%a WINBOND: flash isn't protected\n", __FUNCTION__)); + + return 0; + } + + DEBUG((EFI_D_INFO, "%a WINBOND: flash protected range 0x%08zx-0x%08zx\n", + __FUNCTION__, region_offset(&wp_region), region_end(&wp_region))); + + return region_is_subregion(&wp_region, region); +} + +/** + * Common method to write some bit of the status register 1 & 2 at the same + * time. Only change bits that are one in @mask. + * Compare the final result to make sure that the register isn't locked. + * + * @param mask: The bits that are affected by @val + * @param val: The bits to write + * @param non_volatile: Make setting permanent + * + * @return 0 on success + */ +static int winbond_flash_cmd_status(CONST struct spi_flash *flash, + CONST UINT16 mask, + CONST UINT16 val, + CONST BOOLEAN non_volatile) +{ + struct { + UINT8 cmd; + UINT16 sreg; + } __attribute__((packed)) cmdbuf; + UINT8 reg8; + int ret; + + if (!flash) + return -1; + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg = reg8; + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg |= reg8 << 8; + + if ((val & mask) == (cmdbuf.sreg & mask)) + return 0; + + if (non_volatile) { + ret = spi_flash_cmd(&flash->spi, CMD_W25_WREN, NULL, 0); + } else { + ret = spi_flash_cmd(&flash->spi, CMD_VOLATILE_SREG_WREN, NULL, + 0); + } + if (ret) + return ret; + + cmdbuf.sreg &= ~mask; + cmdbuf.sreg |= val & mask; + cmdbuf.cmd = CMD_W25_WRSR; + + /* Legacy method of writing status register 1 & 2 */ + ret = spi_flash_cmd_write(&flash->spi, (UINT8 *)&cmdbuf, sizeof(cmdbuf), + NULL, 0); + if (ret) + return ret; + + if (non_volatile) { + /* Wait tw */ + ret = spi_flash_cmd_wait_ready(flash, WINBOND_FLASH_TIMEOUT); + if (ret) + return ret; + } else { + /* Wait tSHSL */ + udelay(1); + } + + /* Now read the status register to make sure it's not locked */ + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg = reg8; + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg |= reg8 << 8; + + DEBUG((EFI_D_INFO, "%a WINBOND: SREG=%02x SREG2=%02x\n", + __FUNCTION__, + cmdbuf.sreg & 0xff, + cmdbuf.sreg >> 8)); + + /* Compare against expected result */ + if ((val & mask) != (cmdbuf.sreg & mask)) { + DEBUG((EFI_D_INFO, "%a WINBOND: SREG is locked!\n", __FUNCTION__)); + ret = -1; + } + + return ret; +} + +/* + * SPI write protection is enforced by locking the status register. + * The following modes are known. It depends on the flash chip if the + * mode is actually supported. + * + * PRESERVE : Keep the previous status register lock-down setting (noop) + * NONE : Status register isn't locked + * PIN : Status register is locked as long as the ~WP pin is active + * REBOOT : Status register is locked until power failure + * PERMANENT: Status register is permanently locked + */ +enum spi_flash_status_reg_lockdown { + SPI_WRITE_PROTECTION_PRESERVE = -1, + SPI_WRITE_PROTECTION_NONE = 0, + SPI_WRITE_PROTECTION_PIN, + SPI_WRITE_PROTECTION_REBOOT, + SPI_WRITE_PROTECTION_PERMANENT +}; + +/* + * Available on all devices. + * Protect a region starting from start of flash or end of flash. + * The caller must provide a supported protected region size. + * SEC isn't supported and set to zero. + * Write block protect bits to Status/Status2 Reg. + * Optionally lock the status register if lock_sreg is set with the provided + * mode. + * + * @param flash: The flash to operate on + * @param region: The region to write protect + * @param mode: Optional status register lock-down mode + * + * @return 0 on success + */ +static int +winbond_set_write_protection(CONST struct spi_flash *flash, + CONST struct region *region, + CONST enum spi_flash_status_reg_lockdown mode) +{ + CONST struct spi_flash_part_id *params; + struct status_regs mask, val; + struct region wp_region; + UINT8 cmp, bp, tb; + int ret; + + /* Need to touch TOP or BOTTOM */ + if (region_offset(region) != 0 && region_end(region) != flash->size) + return -1; + + params = flash->part; + + if (!params) + return -1; + + if (params->bp_bits != 3 && params->bp_bits != 4) { + /* FIXME: not implemented */ + return -1; + } + + wp_region = *region; + + if (region_offset(&wp_region) == 0) + tb = 1; + else + tb = 0; + + if (region_sz(&wp_region) > flash->size / 2) { + cmp = 1; + wp_region.offset = tb ? 0 : region_sz(&wp_region); + wp_region.size = flash->size - region_sz(&wp_region); + tb = !tb; + } else { + cmp = 0; + } + + if (region_sz(&wp_region) == 0) { + bp = 0; + } else if (IS_POWER_OF_2(region_sz(&wp_region)) && + (region_sz(&wp_region) >= + (1 << params->protection_granularity_shift))) { + bp = log2(region_sz(&wp_region)) - + params->protection_granularity_shift + 1; + } else { + DEBUG((EFI_D_INFO, "%a WINBOND: ERROR: unsupported region size\n")); + return -1; + } + + /* Write block protection bits */ + + if (params->bp_bits == 3) { + val.reg1 = (union status_reg1) { + .bp3 = { .bp = bp, .tb = tb, .sec = 0 } + }; + mask.reg1 = (union status_reg1) { + .bp3 = { .bp = ~0, .tb = 1, .sec = 1 } + }; + } else { + val.reg1 = (union status_reg1) { + .bp4 = { .bp = bp, .tb = tb } + }; + mask.reg1 = (union status_reg1) { + .bp4 = { .bp = ~0, .tb = 1 } + }; + } + + val.reg2 = (union status_reg2) { .cmp = cmp }; + mask.reg2 = (union status_reg2) { .cmp = 1 }; + + if (mode != SPI_WRITE_PROTECTION_PRESERVE) { + UINT8 srp; + switch (mode) { + case SPI_WRITE_PROTECTION_NONE: + srp = 0; + break; + case SPI_WRITE_PROTECTION_PIN: + srp = 1; + break; + case SPI_WRITE_PROTECTION_REBOOT: + srp = 2; + break; + case SPI_WRITE_PROTECTION_PERMANENT: + srp = 3; + break; + default: + return -1; + } + + if (params->bp_bits == 3) { + val.reg1.bp3.srp0 = !!(srp & 1); + mask.reg1.bp3.srp0 = 1; + } else { + val.reg1.bp4.srp0 = !!(srp & 1); + mask.reg1.bp4.srp0 = 1; + } + + val.reg2.srp1 = !!(srp & 2); + mask.reg2.srp1 = 1; + } + + ret = winbond_flash_cmd_status(flash, mask.u, val.u, TRUE); + if (ret) + return ret; + + DEBUG((EFI_D_INFO, "%a WINBOND: write-protection set to range " + "0x%08zx-0x%08zx\n", __FUNCTION__, + region_offset(region), region_end(region))); + + return ret; +} + +/* Current code assumes all callbacks are supplied in this object. */ +struct spi_flash_protection_ops { + /* + * Returns 1 if the whole region is software write protected. + * Hardware write protection mechanism aren't accounted. + * If the write protection could be changed, due to unlocked status + * register for example, 0 should be returned. + * Returns 0 on success. + */ + int (*get_write)(const struct spi_flash *flash, + const struct region *region); + /* + * Enable the status register write protection, if supported on the + * requested region, and optionally enable status register lock-down. + * Returns 0 if the whole region was software write protected. + * Hardware write protection mechanism aren't accounted. + * If the status register is locked and the requested configuration + * doesn't match the selected one, return an error. + * Only a single region is supported ! + * + * @return 0 on success + */ + int + (*set_write)(const struct spi_flash *flash, + const struct region *region, + const enum spi_flash_status_reg_lockdown mode); + +}; + +static CONST struct spi_flash_protection_ops spi_flash_protection_ops = { + .get_write = winbond_get_write_protection, + .set_write = winbond_set_write_protection, +}; + +CONST struct spi_flash_vendor_info spi_flash_winbond_vi = { + .id = VENDOR_ID_WINBOND, + .page_size_shift = 8, + .sector_size_kib_shift = 2, + .match_id_mask[0] = 0xffff, + .ids = flash_table, + .nr_part_ids = ARRAY_SIZE(flash_table), + .desc = &spi_flash_pp_0x20_sector_desc, + .prot_ops = &spi_flash_protection_ops, +}; From aaa50597807bbe2cdc7dd5b5a328cb0017ef1df1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 08:51:28 +0200 Subject: [PATCH 148/297] fix some errors 19 --- UefiPayloadPkg/SPI/intelSPI.c | 11 ++++++++++- UefiPayloadPkg/SPI/spi_winbond.h | 2 ++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index d7aa3377db52..ce4b3f0ba90e 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -23,6 +23,8 @@ #include "SPI.h" #include "SPIgeneric.h" #include "helpers.h" +#include "spi_winbond.h" +#include "spi_flash_internal.h" /* SPDX-License-Identifier: GPL-2.0-or-later */ @@ -1330,7 +1332,7 @@ static const struct spi_flash_vendor_info *spi_flash_vendors[] = { }; static int find_match(CONST struct spi_slave *spi, struct spi_flash *flash, - UINT8 manuf_id, uint16_t id[2]) + UINT8 manuf_id, UINT16 id[2]) { int i; @@ -1392,6 +1394,13 @@ INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, return find_match(spi, flash, manuf_id, id); } +void *memcpy (VOID *destination, CONST VOID *source, __SIZE_TYPE__ num ) { + for(__SIZE_TYPE__ index = 0; index < num; ++index) { + ((char *)destination)[index] = ((char *)source)[index]; + } + return destination; +} + static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, struct spi_flash *flash) { diff --git a/UefiPayloadPkg/SPI/spi_winbond.h b/UefiPayloadPkg/SPI/spi_winbond.h index bdf669430681..cf5e4adbe6c2 100644 --- a/UefiPayloadPkg/SPI/spi_winbond.h +++ b/UefiPayloadPkg/SPI/spi_winbond.h @@ -21,3 +21,5 @@ /* tw: Maximum time to write a flash cell in milliseconds */ #define WINBOND_FLASH_TIMEOUT 30 + +CONST struct spi_flash_vendor_info spi_flash_winbond_vi; From 535c35dee3eedfd1e128663eac62b0db055a8229 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 08:56:39 +0200 Subject: [PATCH 149/297] fix some errors 20 --- UefiPayloadPkg/SPI/intelSPI.c | 70 +++++++++++++++++- UefiPayloadPkg/SPI/spi_flash_internal.h | 96 ++++++++++++------------- 2 files changed, 117 insertions(+), 49 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index ce4b3f0ba90e..01ee64eb385e 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1292,7 +1292,7 @@ int stmicro_release_deep_sleep_identify(CONST struct spi_slave *spi, UINT8 *idco return 0; } -static const struct spi_flash_vendor_info *spi_flash_vendors[] = { +static CONST struct spi_flash_vendor_info *spi_flash_vendors[] = { #if CONFIG(SPI_FLASH_ADESTO) &spi_flash_adesto_vi, #endif @@ -1331,6 +1331,74 @@ static const struct spi_flash_vendor_info *spi_flash_vendors[] = { #endif }; +static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, + uint16_t id[2]) +{ + __SIZE_TYPE__ i; + CONST uint16_t lid[2] = { + [0] = id[0] & vi->match_id_mask[0], + [1] = id[1] & vi->match_id_mask[1], + }; + + + for (i = 0; i < vi->nr_part_ids; i++) { + CONST struct spi_flash_part_id *part = &vi->ids[i]; + + if (part->id[0] == lid[0] && part->id[1] == lid[1]) + return part; + } + + return NULL; +} + +static int fill_spi_flash(CONST struct spi_slave *spi, struct spi_flash *flash, + CONST struct spi_flash_vendor_info *vi, + CONST struct spi_flash_part_id *part) +{ + memcpy(&flash->spi, spi, sizeof(*spi)); + flash->vendor = vi->id; + flash->model = part->id[0]; + + flash->page_size = 1U << vi->page_size_shift; + flash->sector_size = (1U << vi->sector_size_kib_shift) * KiB; + flash->size = flash->sector_size * (1U << part->nr_sectors_shift); + flash->erase_cmd = vi->desc->erase_cmd; + flash->status_cmd = vi->desc->status_cmd; + flash->pp_cmd = vi->desc->pp_cmd; + flash->wren_cmd = vi->desc->wren_cmd; + + flash->flags.dual_spi = part->fast_read_dual_output_support; + + flash->ops = &vi->desc->ops; + flash->prot_ops = vi->prot_ops; + flash->part = part; + + if (vi->after_probe) + return vi->after_probe(flash); + + return 0; +} + +static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, + uint16_t id[2]) +{ + __SIZE_TYPE__ i; + CONST uint16_t lid[2] = { + [0] = id[0] & vi->match_id_mask[0], + [1] = id[1] & vi->match_id_mask[1], + }; + + + for (i = 0; i < vi->nr_part_ids; i++) { + CONST struct spi_flash_part_id *part = &vi->ids[i]; + + if (part->id[0] == lid[0] && part->id[1] == lid[1]) + return part; + } + + return NULL; +} + static int find_match(CONST struct spi_slave *spi, struct spi_flash *flash, UINT8 manuf_id, UINT16 id[2]) { diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h index f04e7b0320ba..4aed3c60fac2 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.h +++ b/UefiPayloadPkg/SPI/spi_flash_internal.h @@ -28,40 +28,40 @@ #define STATUS_WIP 0x01 /* Send a single-byte command to the device and read the response */ -int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); +int spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); /* * Send a multi-byte command to the device followed by (optional) * data. Used for programming the flash array, etc. */ -int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, - __SIZE_TYPE__ cmd_len, const VOID *data, __SIZE_TYPE__ data_len); +int spi_flash_cmd_write(CONST struct spi_slave *spi, CONST UINT8 *cmd, + __SIZE_TYPE__ cmd_len, CONST VOID *data, __SIZE_TYPE__ data_len); /* Send a command to the device and wait for some bit to clear itself. */ -int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, +int spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long timeout, UINT8 cmd, UINT8 poll_bit); /* * Send the read status command to the device and wait for the wip * (write-in-progress) bit to clear itself. */ -int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout); +int spi_flash_cmd_wait_ready(CONST struct spi_flash *flash, unsigned long timeout); /* Erase sectors. */ -int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); +int spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); /* Read status register. */ -int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg); +int spi_flash_cmd_status(CONST struct spi_flash *flash, UINT8 *reg); /* Write to flash utilizing page program semantics. */ -int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, const VOID *buf); +int spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, CONST VOID *buf); /* Read len bytes into buf at offset. */ -int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); +int spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); /* Release from deep sleep an provide alternative rdid information. */ -int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idcode); +int stmicro_release_deep_sleep_identify(CONST struct spi_slave *spi, UINT8 *idcode); struct spi_flash_part_id { /* rdid command constructs 2x 16-bit id using the following method @@ -69,21 +69,21 @@ struct spi_flash_part_id { * id[0] = (id[1] << 8) | id[2] * id[1] = (id[3] << 8) | id[4] */ - uint16_t id[2]; + UINT16 id[2]; /* Log based 2 total number of sectors. */ - uint16_t nr_sectors_shift: 4; - uint16_t fast_read_dual_output_support : 1; - uint16_t _reserved_for_flags: 3; + UINT16 nr_sectors_shift: 4; + UINT16 fast_read_dual_output_support : 1; + UINT16 _reserved_for_flags: 3; /* Block protection. Currently used by Winbond. */ - uint16_t protection_granularity_shift : 5; - uint16_t bp_bits : 3; + UINT16 protection_granularity_shift : 5; + UINT16 bp_bits : 3; }; struct spi_flash_ops_descriptor { - uint8_t erase_cmd; /* Sector Erase */ - uint8_t status_cmd; /* Read Status Register */ - uint8_t pp_cmd; /* Page program command, if supported. */ - uint8_t wren_cmd; /* Write Enable command. */ + UINT8 erase_cmd; /* Sector Erase */ + UINT8 status_cmd; /* Read Status Register */ + UINT8 pp_cmd; /* Page program command, if supported. */ + UINT8 wren_cmd; /* Write Enable command. */ struct spi_flash_ops ops; }; @@ -91,41 +91,41 @@ struct spi_flash_ops_descriptor { * vendor. One can implement multiple sets from a single vendor by having * separate objects. */ struct spi_flash_vendor_info { - uint8_t id; - uint8_t page_size_shift : 4; /* if page programming oriented. */ + UINT8 id; + UINT8 page_size_shift : 4; /* if page programming oriented. */ /* Log based 2 sector size */ - uint8_t sector_size_kib_shift : 4; - uint16_t nr_part_ids; - const struct spi_flash_part_id *ids; - uint16_t match_id_mask[2]; /* matching bytes of the id for this set*/ - const struct spi_flash_ops_descriptor *desc; - const struct spi_flash_protection_ops *prot_ops; + UINT8 sector_size_kib_shift : 4; + UINT16 nr_part_ids; + CONST struct spi_flash_part_id *ids; + UINT16 match_id_mask[2]; /* matching bytes of the id for this set*/ + CONST struct spi_flash_ops_descriptor *desc; + CONST struct spi_flash_protection_ops *prot_ops; /* Returns 0 on success. !0 otherwise. */ - int (*after_probe)(const struct spi_flash *flash); + int (*after_probe)(CONST struct spi_flash *flash); }; /* Manufacturer-specific probe information */ -extern const struct spi_flash_vendor_info spi_flash_adesto_vi; -extern const struct spi_flash_vendor_info spi_flash_amic_vi; -extern const struct spi_flash_vendor_info spi_flash_atmel_vi; -extern const struct spi_flash_vendor_info spi_flash_eon_vi; -extern const struct spi_flash_vendor_info spi_flash_gigadevice_vi; -extern const struct spi_flash_vendor_info spi_flash_macronix_vi; +extern CONST struct spi_flash_vendor_info spi_flash_adesto_vi; +extern CONST struct spi_flash_vendor_info spi_flash_amic_vi; +extern CONST struct spi_flash_vendor_info spi_flash_atmel_vi; +extern CONST struct spi_flash_vendor_info spi_flash_eon_vi; +extern CONST struct spi_flash_vendor_info spi_flash_gigadevice_vi; +extern CONST struct spi_flash_vendor_info spi_flash_macronix_vi; /* Probing order matters between the spansion sequence. */ -extern const struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; -extern const struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; -extern const struct spi_flash_vendor_info spi_flash_spansion_vi; -extern const struct spi_flash_vendor_info spi_flash_sst_ai_vi; -extern const struct spi_flash_vendor_info spi_flash_sst_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro1_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro2_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro3_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro4_vi; -extern const struct spi_flash_vendor_info spi_flash_winbond_vi; +extern CONST struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; +extern CONST struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; +extern CONST struct spi_flash_vendor_info spi_flash_spansion_vi; +extern CONST struct spi_flash_vendor_info spi_flash_sst_ai_vi; +extern CONST struct spi_flash_vendor_info spi_flash_sst_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro1_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro2_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro3_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro4_vi; +extern CONST struct spi_flash_vendor_info spi_flash_winbond_vi; /* Page Programming Command Set with 0x20 Sector Erase command. */ -extern const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; +extern CONST struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; /* Page Programming Command Set with 0xd8 Sector Erase command. */ -extern const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; +extern CONST struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; #endif /* SPI_FLASH_INTERNAL_H */ From a5cde051ed03c245676930f2a16157809acf6572 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 09:04:05 +0200 Subject: [PATCH 150/297] fix some errors 21 --- UefiPayloadPkg/SPI/intelSPI.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 01ee64eb385e..705ed25fc5f4 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1332,10 +1332,10 @@ static CONST struct spi_flash_vendor_info *spi_flash_vendors[] = { }; static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, - uint16_t id[2]) + UINT16 id[2]) { __SIZE_TYPE__ i; - CONST uint16_t lid[2] = { + CONST UINT16 lid[2] = { [0] = id[0] & vi->match_id_mask[0], [1] = id[1] & vi->match_id_mask[1], }; @@ -1351,6 +1351,13 @@ static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_i return NULL; } +void *memcpy (VOID *destination, CONST VOID *source, __SIZE_TYPE__ num ) { + for(__SIZE_TYPE__ index = 0; index < num; ++index) { + ((char *)destination)[index] = ((char *)source)[index]; + } + return destination; +} + static int fill_spi_flash(CONST struct spi_slave *spi, struct spi_flash *flash, CONST struct spi_flash_vendor_info *vi, CONST struct spi_flash_part_id *part) @@ -1380,10 +1387,10 @@ static int fill_spi_flash(CONST struct spi_slave *spi, struct spi_flash *flash, } static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, - uint16_t id[2]) + UINT16 id[2]) { __SIZE_TYPE__ i; - CONST uint16_t lid[2] = { + CONST UINT16 lid[2] = { [0] = id[0] & vi->match_id_mask[0], [1] = id[1] & vi->match_id_mask[1], }; @@ -1462,13 +1469,6 @@ INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, return find_match(spi, flash, manuf_id, id); } -void *memcpy (VOID *destination, CONST VOID *source, __SIZE_TYPE__ num ) { - for(__SIZE_TYPE__ index = 0; index < num; ++index) { - ((char *)destination)[index] = ((char *)source)[index]; - } - return destination; -} - static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, struct spi_flash *flash) { From 53cebdc1f3cd93a253f9cd94fcdd9e4cc636c803 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 09:08:28 +0200 Subject: [PATCH 151/297] fix some errors 22 --- UefiPayloadPkg/SPI/intelSPI.c | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 705ed25fc5f4..38162f331855 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1386,26 +1386,6 @@ static int fill_spi_flash(CONST struct spi_slave *spi, struct spi_flash *flash, return 0; } -static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, - UINT16 id[2]) -{ - __SIZE_TYPE__ i; - CONST UINT16 lid[2] = { - [0] = id[0] & vi->match_id_mask[0], - [1] = id[1] & vi->match_id_mask[1], - }; - - - for (i = 0; i < vi->nr_part_ids; i++) { - CONST struct spi_flash_part_id *part = &vi->ids[i]; - - if (part->id[0] == lid[0] && part->id[1] == lid[1]) - return part; - } - - return NULL; -} - static int find_match(CONST struct spi_slave *spi, struct spi_flash *flash, UINT8 manuf_id, UINT16 id[2]) { From 4a6350adcc0a1e6a7ccecec66fa3936db3d58c52 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 09:44:41 +0200 Subject: [PATCH 152/297] fix some errors 23 --- UefiPayloadPkg/SPI/intelSPI.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 38162f331855..109b366eb208 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -830,7 +830,7 @@ static INT32 spi_is_multichip(VOID) return !!((cntlr.flmap0 >> 8) & 3); } -static INT32 spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, +static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { UINT16 control; @@ -1491,7 +1491,7 @@ static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, INT64 spi_flash_vector_helper(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count, - INT64 (*func)(CONST struct spi_slave *slave, CONST VOID *dout, + int (*func)(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) { INT64 ret; From 245c86d2177c6a69bb392fc0887dfeb9deceff0e Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 09:54:22 +0200 Subject: [PATCH 153/297] fix some errors 24 --- UefiPayloadPkg/SPI/intelSPI.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 109b366eb208..15ee51f106de 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1569,6 +1569,16 @@ static UINT32 spi_fpr(UINT32 base, UINT32 limit) return ret; } +static inline __SIZE_TYPE__ region_offset(const struct region *r) +{ + return r->offset; +} + +static inline __SIZE_TYPE__ region_sz(const struct region *r) +{ + return r->size; +} + /* * Protect range of SPI flash defined by [start, start+size-1] using Flash * Protected Range (FPR) register if available. @@ -1633,6 +1643,19 @@ static INT32 spi_flash_protect(CONST struct spi_flash *flash, return 0; } +static BOOLEAN spi_flash_init_done; +static struct spi_flash spi_flash_info; + +const struct spi_flash *boot_device_spi_flash(void) +{ + boot_device_init(); + + if (spi_flash_init_done != TRUE) + return NULL; + + return &spi_flash_info; +} + VOID spi_finalize_ops(VOID) { UINT16 spi_opprefix; From 445e21cc28259fef91fbcae1ff6e3a7db3e58eec Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 10:12:25 +0200 Subject: [PATCH 154/297] fix some errors 25 --- UefiPayloadPkg/SPI/intelSPI.c | 13 -- UefiPayloadPkg/SPI/spi_flash.h | 225 +++++++++++++++++++++++++++++++++ 2 files changed, 225 insertions(+), 13 deletions(-) create mode 100644 UefiPayloadPkg/SPI/spi_flash.h diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 15ee51f106de..c01d033a1c01 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1643,19 +1643,6 @@ static INT32 spi_flash_protect(CONST struct spi_flash *flash, return 0; } -static BOOLEAN spi_flash_init_done; -static struct spi_flash spi_flash_info; - -const struct spi_flash *boot_device_spi_flash(void) -{ - boot_device_init(); - - if (spi_flash_init_done != TRUE) - return NULL; - - return &spi_flash_info; -} - VOID spi_finalize_ops(VOID) { UINT16 spi_opprefix; diff --git a/UefiPayloadPkg/SPI/spi_flash.h b/UefiPayloadPkg/SPI/spi_flash.h new file mode 100644 index 000000000000..215ec2e1d717 --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_flash.h @@ -0,0 +1,225 @@ +/* Interface to SPI flash */ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef _SPI_FLASH_H_ +#define _SPI_FLASH_H_ + +#include + +/* SPI Flash opcodes */ +#define SPI_OPCODE_WREN 0x06 +#define SPI_OPCODE_FAST_READ 0x0b + +struct spi_flash; + +/* + * SPI write protection is enforced by locking the status register. + * The following modes are known. It depends on the flash chip if the + * mode is actually supported. + * + * PRESERVE : Keep the previous status register lock-down setting (noop) + * NONE : Status register isn't locked + * PIN : Status register is locked as long as the ~WP pin is active + * REBOOT : Status register is locked until power failure + * PERMANENT: Status register is permanently locked + */ +enum spi_flash_status_reg_lockdown { + SPI_WRITE_PROTECTION_PRESERVE = -1, + SPI_WRITE_PROTECTION_NONE = 0, + SPI_WRITE_PROTECTION_PIN, + SPI_WRITE_PROTECTION_REBOOT, + SPI_WRITE_PROTECTION_PERMANENT +}; + +/* + * Representation of SPI flash operations: + * read: Flash read operation. + * write: Flash write operation. + * erase: Flash erase operation. + * status: Read flash status register. + */ +struct spi_flash_ops { + int (*read)(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, + void *buf); + int (*write)(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, + const void *buf); + int (*erase)(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len); + int (*status)(const struct spi_flash *flash, UINT8 *reg); +}; + +/* Current code assumes all callbacks are supplied in this object. */ +struct spi_flash_protection_ops { + /* + * Returns 1 if the whole region is software write protected. + * Hardware write protection mechanism aren't accounted. + * If the write protection could be changed, due to unlocked status + * register for example, 0 should be returned. + * Returns 0 on success. + */ + int (*get_write)(const struct spi_flash *flash, + const struct region *region); + /* + * Enable the status register write protection, if supported on the + * requested region, and optionally enable status register lock-down. + * Returns 0 if the whole region was software write protected. + * Hardware write protection mechanism aren't accounted. + * If the status register is locked and the requested configuration + * doesn't match the selected one, return an error. + * Only a single region is supported ! + * + * @return 0 on success + */ + int + (*set_write)(const struct spi_flash *flash, + const struct region *region, + const enum spi_flash_status_reg_lockdown mode); + +}; + +struct spi_flash_part_id; + +struct spi_flash { + struct spi_slave spi; + UINT8 vendor; + union { + UINT8 raw; + struct { + UINT8 dual_spi : 1; + UINT8 _reserved : 7; + }; + } flags; + u16 model; + UINT32 size; + UINT32 sector_size; + UINT32 page_size; + UINT8 erase_cmd; + UINT8 status_cmd; + UINT8 pp_cmd; /* Page program command. */ + UINT8 wren_cmd; /* Write Enable command. */ + const struct spi_flash_ops *ops; + /* If !NULL all protection callbacks exist. */ + const struct spi_flash_protection_ops *prot_ops; + const struct spi_flash_part_id *part; +}; + +void lb_spi_flash(struct lb_header *header); + +/* SPI Flash Driver Public API */ + +/* + * Probe for SPI flash chip on given SPI bus and chip select and fill info in + * spi_flash structure. + * + * Params: + * bus = SPI Bus # for the flash chip + * cs = Chip select # for the flash chip + * flash = Pointer to spi flash structure that needs to be filled + * + * Return value: + * 0 = success + * non-zero = error + */ +int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash); + +/* + * Generic probing for SPI flash chip based on the different flashes provided. + * + * Params: + * spi = Pointer to spi_slave structure + * flash = Pointer to spi_flash structure that needs to be filled. + * + * Return value: + * 0 = success + * non-zero = error + */ +int spi_flash_generic_probe(const struct spi_slave *slave, + struct spi_flash *flash); + +/* All the following functions return 0 on success and non-zero on error. */ +int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, + void *buf); +int spi_flash_write(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, + const void *buf); +int spi_flash_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len); +int spi_flash_status(const struct spi_flash *flash, UINT8 *reg); + +/* + * Return the vendor dependent SPI flash write protection state. + * @param flash : A SPI flash device + * @param region: A subregion of the device's region + * + * Returns: + * -1 on error + * 0 if the device doesn't support block protection + * 0 if the device doesn't enable block protection + * 0 if given range isn't covered by block protection + * 1 if given range is covered by block protection + */ +int spi_flash_is_write_protected(const struct spi_flash *flash, + const struct region *region); +/* + * Enable the vendor dependent SPI flash write protection. The region not + * covered by write-protection will be set to write-able state. + * Only a single write-protected region is supported. + * Some flash ICs require the region to be aligned in the block size, sector + * size or page size. + * Some flash ICs require the region to start at TOP or BOTTOM. + * + * @param flash : A SPI flash device + * @param region: A subregion of the device's region + * @param mode: Optional lock-down of status register + + * @return 0 on success + */ +int +spi_flash_set_write_protected(const struct spi_flash *flash, + const struct region *region, + const enum spi_flash_status_reg_lockdown mode); + +/* + * Some SPI controllers require exclusive access to SPI flash when volatile + * operations like erase or write are being performed. In such cases, + * volatile_group_begin will gain exclusive access to SPI flash if not already + * acquired and volatile_group_end will end exclusive access if this was the + * last request in the group. spi_flash_{write,erase} operations call + * volatile_group_begin at the start of function and volatile_group_end after + * erase/write operation is performed. These functions can also be used by any + * components that wish to club multiple volatile operations into a single + * group. + */ +int spi_flash_volatile_group_begin(const struct spi_flash *flash); +int spi_flash_volatile_group_end(const struct spi_flash *flash); + +/* + * These are callbacks for marking the start and end of volatile group as + * handled by the chipset. Not every chipset requires this special handling. So, + * these functions are expected to be implemented in Kconfig option for volatile + * group is enabled (SPI_FLASH_HAS_VOLATILE_GROUP). + */ +int chipset_volatile_group_begin(const struct spi_flash *flash); +int chipset_volatile_group_end(const struct spi_flash *flash); + +/* Return spi_flash object reference for the boot device. This is only valid + * if CONFIG(BOOT_DEVICE_SPI_FLASH) is enabled. */ +const struct spi_flash *boot_device_spi_flash(void); + +/* Protect a region of spi flash using its controller, if available. Returns + * < 0 on error, else 0 on success. */ +int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, + const struct region *region, + const enum ctrlr_prot_type type); + +/* + * This function is provided to support spi flash command-response transactions. + * Only 2 vectors are supported and the 'func' is called with appropriate + * write and read buffers together. This can be used for chipsets that + * have specific spi flash controllers that don't conform to the normal + * spi xfer API because they are specialized controllers and not generic. + * + * Returns 0 on success and non-zero on failure. + */ +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE_ count, + int (*func)(const struct spi_slave *slave, const void *dout, + __SIZE_TYPE_ bytesout, void *din, __SIZE_TYPE_ bytesin)); + +#endif /* _SPI_FLASH_H_ */ From eeef2825baaa7330dc85f2f9f793f282ec58dd5c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 11:12:06 +0200 Subject: [PATCH 155/297] fix some errors 26 --- UefiPayloadPkg/SPI/intelSPI.c | 134 +++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index c01d033a1c01..0b296a93ed14 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1351,7 +1351,7 @@ static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_i return NULL; } -void *memcpy (VOID *destination, CONST VOID *source, __SIZE_TYPE__ num ) { +VOID *memcpy (VOID *destination, CONST VOID *source, __SIZE_TYPE__ num ) { for(__SIZE_TYPE__ index = 0; index < num; ++index) { ((char *)destination)[index] = ((char *)source)[index]; } @@ -1569,12 +1569,12 @@ static UINT32 spi_fpr(UINT32 base, UINT32 limit) return ret; } -static inline __SIZE_TYPE__ region_offset(const struct region *r) +static inline __SIZE_TYPE__ region_offset(CONST struct region *r) { return r->offset; } -static inline __SIZE_TYPE__ region_sz(const struct region *r) +static inline __SIZE_TYPE__ region_sz(CONST struct region *r) { return r->size; } @@ -1643,6 +1643,134 @@ static INT32 spi_flash_protect(CONST struct spi_flash *flash, return 0; } +static struct spi_flash spi_flash_info; +static BOOLEAN spi_flash_init_done; + +int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash) +{ + struct spi_slave spi; + int ret = -1; + + if (spi_setup_slave(bus, cs, &spi)) { + DEBUG((EFI_D_INFO, "%a SF: Failed to set up slave\n", __FUNCTION__)); + return -1; + } + + /* Try special programmer probe if any. */ + if (spi.ctrlr->flash_probe) + ret = spi.ctrlr->flash_probe(&spi, flash); + + /* If flash is not found, try generic spi flash probe. */ + if (ret) + ret = spi_flash_generic_probe(&spi, flash); + + /* Give up -- nothing more to try if flash is not found. */ + if (ret) { + DEBUG((EFI_D_INFO, "%a SF: Unsupported manufacturer!\n", __FUNCTION__)); + return -1; + } + + #define CONFIG_BOOT_DEVICE_SPI_FLASH_BUS 0 + #define CONFIG_ROM_SIZE 8196 + + CONST char *mode_string = ""; + if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) + mode_string = " (Dual SPI mode)"; + DEBUG((EFI_D_INFO, + "%a SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", + __FUNCTION__, flash->vendor, flash->model, + flash->sector_size, flash->size, mode_string)); + if (bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS + && flash->size != CONFIG_ROM_SIZE) { + DEBUG((EFI_D_INFO, "%a SF size 0x%x does not correspond to" + " CONFIG_ROM_SIZE 0x%x!!\n", __FUNCTION__, flash->size, + CONFIG_ROM_SIZE)); + } + return 0; +} + +struct mem_pool { + UINT8 *buf; + __SIZE_TYPE__ size; + UINT8 *last_alloc; + __SIZE_TYPE__ free_offset; +}; + +#define MEM_POOL_INIT(buf_, size_) \ + { \ + .buf = (buf_), \ + .size = (size_), \ + .last_alloc = NULL, \ + .free_offset = 0, \ + } + +static inline VOID mem_pool_reset(struct mem_pool *mp) +{ + mp->last_alloc = NULL; + mp->free_offset = 0; +} + +/* Initialize a memory pool. */ +static inline VOID mem_pool_init(struct mem_pool *mp, VOID *buf, __SIZE_TYPE__ sz) +{ + mp->buf = buf; + mp->size = sz; + mem_pool_reset(mp); +} + +/* A region_device operations. */ +struct region_device_ops { + VOID *(*mmap)(CONST struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); + int (*munmap)(CONST struct region_device *, VOID *); + __SIZE_TYPE__ (*readat)(CONST struct region_device *, VOID *, __SIZE_TYPE__, __SIZE_TYPE__); + __SIZE_TYPE__ (*writeat)(CONST struct region_device *, CONST VOID *, __SIZE_TYPE__, + __SIZE_TYPE__); + __SIZE_TYPE__ (*eraseat)(CONST struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); +}; + +struct region_device { + CONST struct region_device *root; + CONST struct region_device_ops *ops; + struct region region; +}; + +struct mmap_helper_region_device { + struct mem_pool pool; + struct region_device rdev; +}; + +VOID mmap_helper_device_init(struct mmap_helper_region_device *mdev, + VOID *cache, __SIZE_TYPE__ cache_size) +{ + mem_pool_init(&mdev->pool, cache, cache_size); +} + +VOID boot_device_init(VOID) +{ + int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; + int cs = 0; + + if (spi_flash_init_done == TRUE) + return; + + if (spi_flash_probe(bus, cs, &spi_flash_info)) + return; + + spi_flash_init_done = TRUE; + + mmap_helper_device_init(&mdev, _cbfs_cache, REGION_SIZE(cbfs_cache)); +} + +CONST struct spi_flash *boot_device_spi_flash(VOID) +{ + boot_device_init(); + + if (spi_flash_init_done != TRUE) + return NULL; + + return &spi_flash_info; +} + VOID spi_finalize_ops(VOID) { UINT16 spi_opprefix; From ed00462825fdd52af6a8f61e053a5e9f1a5ff1fb Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 11:41:36 +0200 Subject: [PATCH 156/297] fix some errors 27 --- UefiPayloadPkg/SPI/intelSPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 0b296a93ed14..ce339633d93e 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -589,6 +589,7 @@ static VOID *get_spi_bar(pci_devfn_t dev) rcba = pci_read_config32(dev, RCBA); return (VOID *)((rcba & 0xffffc000) + 0x3800); } + return NULL; } VOID spi_init(VOID) @@ -1719,6 +1720,7 @@ static inline VOID mem_pool_init(struct mem_pool *mp, VOID *buf, __SIZE_TYPE__ s } /* A region_device operations. */ +struct region_device_ops; struct region_device_ops { VOID *(*mmap)(CONST struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); int (*munmap)(CONST struct region_device *, VOID *); From 66305cf3fb645509f9fb6c2f3fff80514fffd0be Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 11:44:27 +0200 Subject: [PATCH 157/297] fix some errors 28 --- UefiPayloadPkg/SPI/intelSPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index ce339633d93e..583b24c3cc14 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1720,7 +1720,7 @@ static inline VOID mem_pool_init(struct mem_pool *mp, VOID *buf, __SIZE_TYPE__ s } /* A region_device operations. */ -struct region_device_ops; +struct region_device; struct region_device_ops { VOID *(*mmap)(CONST struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); int (*munmap)(CONST struct region_device *, VOID *); From 54a89f4cecaae07c2292b252ff227e7656f5e66b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 11:59:05 +0200 Subject: [PATCH 158/297] fix some errors 29 --- UefiPayloadPkg/SPI/intelSPI.c | 132 ++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 583b24c3cc14..28e689f2a07f 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1741,12 +1741,144 @@ struct mmap_helper_region_device { struct region_device rdev; }; +#define container_of(ptr, type, member) ({ \ + const __typeof__(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); }) + +void mem_pool_free(struct mem_pool *mp, void *p) +{ + /* Determine if p was the most recent allocation. */ + if (p == NULL || mp->last_alloc != p) + return; + + mp->free_offset = mp->last_alloc - mp->buf; + /* No way to track allocation before this one. */ + mp->last_alloc = NULL; +} + VOID mmap_helper_device_init(struct mmap_helper_region_device *mdev, VOID *cache, __SIZE_TYPE__ cache_size) { mem_pool_init(&mdev->pool, cache, cache_size); } +void *mmap_helper_rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + struct mmap_helper_region_device *mdev; + void *mapping; + + mdev = container_of((void *)rd, __typeof__(*mdev), rdev); + + mapping = mem_pool_alloc(&mdev->pool, size); + + if (mapping == NULL) + return NULL; + + if (rd->ops->readat(rd, mapping, offset, size) != size) { + mem_pool_free(&mdev->pool, mapping); + return NULL; + } + + return mapping; +} + +int mmap_helper_rdev_munmap(const struct region_device *rd, void *mapping) +{ + struct mmap_helper_region_device *mdev; + + mdev = container_of((void *)rd, __typeof__(*mdev), rdev); + + mem_pool_free(&mdev->pool, mapping); + + return 0; +} + +static __SIZE_TYPE__ spi_writeat(const struct region_device *rd, const void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + if (spi_flash_write(&sfg, offset, size, b)) + return -1; + + return size; +} + +static struct spi_flash sfg; + +static __SIZE_TYPE__ spi_readat(const struct region_device *rd, void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + if (spi_flash_read(&sfg, offset, size, b)) + return -1; + + return size; +} + +static __SIZE_TYPE__ spi_eraseat(const struct region_device *rd, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + if (spi_flash_erase(&sfg, offset, size)) + return -1; + + return size; +} + +/* Provide all operations on the same device. */ +static const struct region_device_ops spi_ops = { + .mmap = mmap_helper_rdev_mmap, + .munmap = mmap_helper_rdev_munmap, + .readat = spi_readat, + .writeat = spi_writeat, + .eraseat = spi_eraseat, +}; + +#define REGION_DEV_INIT(ops_, offset_, size_) \ + { \ + .root = NULL, \ + .ops = (ops_), \ + .region = { \ + .offset = (offset_), \ + .size = (size_), \ + }, \ + } + +#define MMAP_HELPER_REGION_INIT(ops_, offset_, size_) \ + { \ + .rdev = REGION_DEV_INIT((ops_), (offset_), (size_)), \ + } + +#define REGION_SIZE(name) (_e##name - _##name) + +#define DECLARE_REGION(name) \ + extern UINT8 _##name[]; \ + extern UINT8 _e##name[]; + +/* + * Regions can be declared optional if not all configurations provide them in + * memlayout and you want code to be able to check for their existence at + * runtime. Not every region that is architecture or platform-specific should + * use this -- only declare regions optional if the code *accessing* them runs + * both on configurations that have the region and those that don't. That code + * should then check (REGION_SIZE(name) != 0) before accessing it. + */ +#define DECLARE_OPTIONAL_REGION(name) \ + __attribute__((__weak__)) extern UINT8 _##name[]; \ + __attribute__((__weak__)) extern UINT8 _e##name[]; + +DECLARE_REGION(sram) +DECLARE_OPTIONAL_REGION(timestamp) +DECLARE_REGION(preram_cbmem_console) +DECLARE_REGION(cbmem_init_hooks) +DECLARE_REGION(stack) +DECLARE_REGION(preram_cbfs_cache) +DECLARE_REGION(postram_cbfs_cache) +DECLARE_REGION(cbfs_cache) +DECLARE_REGION(fmap_cache) +DECLARE_REGION(tpm_tcpa_log) + +static struct mmap_helper_region_device mdev = + MMAP_HELPER_REGION_INIT(&spi_ops, 0, CONFIG_ROM_SIZE); + VOID boot_device_init(VOID) { int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; From b9db4aacab717310352df9df351a939d29793bcd Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:06:42 +0200 Subject: [PATCH 159/297] fix some errors 30 --- UefiPayloadPkg/SPI/intelSPI.c | 84 +++++++++++++++++++++++++++++------ 1 file changed, 70 insertions(+), 14 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 28e689f2a07f..1b0c11897e8b 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1742,10 +1742,10 @@ struct mmap_helper_region_device { }; #define container_of(ptr, type, member) ({ \ - const __typeof__(((type *)0)->member) *__mptr = (ptr); \ + CONST __typeof__(((type *)0)->member) *__mptr = (ptr); \ (type *)((char *)__mptr - offsetof(type, member)); }) -void mem_pool_free(struct mem_pool *mp, void *p) +VOID mem_pool_free(struct mem_pool *mp, VOID *p) { /* Determine if p was the most recent allocation. */ if (p == NULL || mp->last_alloc != p) @@ -1762,13 +1762,32 @@ VOID mmap_helper_device_init(struct mmap_helper_region_device *mdev, mem_pool_init(&mdev->pool, cache, cache_size); } -void *mmap_helper_rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, +VOID *mem_pool_alloc(struct mem_pool *mp, __SIZE_TYPE__ sz) +{ + VOID *p; + + /* Make all allocations be at least 8 byte aligned. */ + sz = ALIGN_UP(sz, 8); + + /* Determine if any space available. */ + if ((mp->size - mp->free_offset) < sz) + return NULL; + + p = &mp->buf[mp->free_offset]; + + mp->free_offset += sz; + mp->last_alloc = p; + + return p; +} + +VOID *mmap_helper_rdev_mmap(CONST struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) { struct mmap_helper_region_device *mdev; - void *mapping; + VOID *mapping; - mdev = container_of((void *)rd, __typeof__(*mdev), rdev); + mdev = container_of((VOID *)rd, __typeof__(*mdev), rdev); mapping = mem_pool_alloc(&mdev->pool, size); @@ -1783,18 +1802,57 @@ void *mmap_helper_rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset return mapping; } -int mmap_helper_rdev_munmap(const struct region_device *rd, void *mapping) +int mmap_helper_rdev_munmap(CONST struct region_device *rd, VOID *mapping) { struct mmap_helper_region_device *mdev; - mdev = container_of((void *)rd, __typeof__(*mdev), rdev); + mdev = container_of((VOID *)rd, __typeof__(*mdev), rdev); mem_pool_free(&mdev->pool, mapping); return 0; } -static __SIZE_TYPE__ spi_writeat(const struct region_device *rd, const void *b, +int spi_flash_write(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + CONST VOID *buf) +{ + int ret; + + if (spi_flash_volatile_group_begin(flash)) + return -1; + + ret = flash->ops->write(flash, offset, len, buf); + + if (spi_flash_volatile_group_end(flash)) + return -1; + + return ret; +} + +int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + void *buf) +{ + return flash->ops->read(flash, offset, len, buf); +} + +int spi_flash_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) +{ + int ret; + + if (spi_flash_volatile_group_begin(flash)) + return -1; + + ret = flash->ops->erase(flash, offset, len); + + if (spi_flash_volatile_group_end(flash)) + return -1; + + return ret; +} + +static struct spi_flash sfg; + +static __SIZE_TYPE__ spi_writeat(CONST struct region_device *rd, CONST VOID *b, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) { if (spi_flash_write(&sfg, offset, size, b)) @@ -1803,9 +1861,7 @@ static __SIZE_TYPE__ spi_writeat(const struct region_device *rd, const void *b, return size; } -static struct spi_flash sfg; - -static __SIZE_TYPE__ spi_readat(const struct region_device *rd, void *b, +static __SIZE_TYPE__ spi_readat(CONST struct region_device *rd, VOID *b, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) { if (spi_flash_read(&sfg, offset, size, b)) @@ -1814,17 +1870,17 @@ static __SIZE_TYPE__ spi_readat(const struct region_device *rd, void *b, return size; } -static __SIZE_TYPE__ spi_eraseat(const struct region_device *rd, +static __SIZE_TYPE__ spi_eraseat(CONST struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) { - if (spi_flash_erase(&sfg, offset, size)) + if (__SIZE_TYPE__(&sfg, offset, size)) return -1; return size; } /* Provide all operations on the same device. */ -static const struct region_device_ops spi_ops = { +static CONST struct region_device_ops spi_ops = { .mmap = mmap_helper_rdev_mmap, .munmap = mmap_helper_rdev_munmap, .readat = spi_readat, From e93baa1cfcb90a73edd9cdd5e64c8354dc1b77bf Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:11:10 +0200 Subject: [PATCH 160/297] fix some errors 31 --- UefiPayloadPkg/SPI/intelSPI.c | 40 ++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 1b0c11897e8b..f97392990094 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1813,6 +1813,44 @@ int mmap_helper_rdev_munmap(CONST struct region_device *rd, VOID *mapping) return 0; } +static UINT32 volatile_group_count; + +int spi_flash_volatile_group_begin(const struct spi_flash *flash) +{ + UINT32 count; + int ret = 0; + + if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) + return ret; + + count = volatile_group_count; + if (count == 0) + ret = chipset_volatile_group_begin(flash); + + count++; + volatile_group_count = count; + return ret; +} + +int spi_flash_volatile_group_end(const struct spi_flash *flash) +{ + UINT32 count; + int ret = 0; + + if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) + return ret; + + count = volatile_group_count; + assert(count == 0); + count--; + volatile_group_count = count; + + if (count == 0) + ret = chipset_volatile_group_end(flash); + + return ret; +} + int spi_flash_write(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, CONST VOID *buf) { @@ -1873,7 +1911,7 @@ static __SIZE_TYPE__ spi_readat(CONST struct region_device *rd, VOID *b, static __SIZE_TYPE__ spi_eraseat(CONST struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) { - if (__SIZE_TYPE__(&sfg, offset, size)) + if (spi_flash_erase(&sfg, offset, size)) return -1; return size; From 5909a0d03e9dcd824bd9e8daa939857baed65ff1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:18:51 +0200 Subject: [PATCH 161/297] fix some errors 32 --- UefiPayloadPkg/SPI/intelSPI.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index f97392990094..447b8a6b9526 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1825,7 +1825,7 @@ int spi_flash_volatile_group_begin(const struct spi_flash *flash) count = volatile_group_count; if (count == 0) - ret = chipset_volatile_group_begin(flash); + ret = 0; count++; volatile_group_count = count; @@ -1841,12 +1841,13 @@ int spi_flash_volatile_group_end(const struct spi_flash *flash) return ret; count = volatile_group_count; - assert(count == 0); + //assert(count == 0); count--; volatile_group_count = count; if (count == 0) - ret = chipset_volatile_group_end(flash); + ret = 0; + //ret = chipset_volatile_group_end(flash); return ret; } From 9e6ed2eb2f3530085c32db371491c727014c8b9d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:22:34 +0200 Subject: [PATCH 162/297] fix some errors 33 --- UefiPayloadPkg/SPI/intelSPI.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 447b8a6b9526..2c15a457d489 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -2000,6 +2000,11 @@ CONST struct spi_flash *boot_device_spi_flash(VOID) return &spi_flash_info; } +__attribute__((__weak__)) +VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) +{ +} + VOID spi_finalize_ops(VOID) { UINT16 spi_opprefix; @@ -2058,11 +2063,6 @@ VOID spi_finalize_ops(VOID) writew_(optype, cntlr.optype); } -__attribute__((__weak__)) -VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) -{ -} - /*----------------------------------------------------------------------- * Representation of a SPI controller. Note the xfer() and xfer_vector() From 05acef001898e5e44d315935ff788fd7ba0a1020 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:25:52 +0200 Subject: [PATCH 163/297] fix some errors 34 --- UefiPayloadPkg/SPI/intelSPI.c | 110 ---------------------------------- 1 file changed, 110 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 2c15a457d489..031cd8b8defe 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1450,46 +1450,6 @@ INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, return find_match(spi, flash, manuf_id, id); } -static INT32 spi_flash_programmer_probe(CONST struct spi_slave *spi, - struct spi_flash *flash) -{ - - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) - return spi_flash_generic_probe(spi, flash); - - /* Try generic probing first if spi_is_multichip returns 0. */ - if (!spi_is_multichip() && !spi_flash_generic_probe(spi, flash)) - return 0; - - memcpy(&flash->spi, spi, sizeof(*spi)); - - ich_hwseq_set_addr(0); - switch ((cntlr.hsfs >> 3) & 3) { - case 0: - flash->sector_size = 256; - break; - case 1: - flash->sector_size = 4096; - break; - case 2: - flash->sector_size = 8192; - break; - case 3: - flash->sector_size = 65536; - break; - } - - flash->size = 1 << (19 + (cntlr.flcomp & 7)); - - flash->ops = &spi_flash_ops; - - if ((cntlr.hsfs & HSFS_FDV) && ((cntlr.flmap0 >> 8) & 3)) - flash->size += 1 << (19 + ((cntlr.flcomp >> 3) & 7)); - DEBUG((EFI_D_INFO, "%a flash size 0x%x bytes\n", __FUNCTION__, flash->size)); - - return 0; -} - INT64 spi_flash_vector_helper(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count, int (*func)(CONST struct spi_slave *slave, CONST VOID *dout, @@ -1538,12 +1498,6 @@ INT64 spi_flash_vector_helper(CONST struct spi_slave *slave, return ret; } -static INT32 xfer_vectors(CONST struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count) -{ - return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); -} - #define SPI_FPR_SHIFT 12 #define ICH7_SPI_FPR_MASK 0xfff #define ICH9_SPI_FPR_MASK 0x1fff @@ -1580,70 +1534,6 @@ static inline __SIZE_TYPE__ region_sz(CONST struct region *r) return r->size; } -/* - * Protect range of SPI flash defined by [start, start+size-1] using Flash - * Protected Range (FPR) register if available. - * Returns 0 on success, -1 on failure of programming fpr registers. - */ -static INT32 spi_flash_protect(CONST struct spi_flash *flash, - CONST struct region *region, - CONST enum ctrlr_prot_type type) -{ - UINT32 start = region_offset(region); - UINT32 end = start + region_sz(region) - 1; - UINT32 reg; - UINT32 protect_mask = 0; - INT32 fpr; - UINT32 *fpr_base; - - fpr_base = cntlr.fpr; - - /* Find first empty FPR */ - for (fpr = 0; fpr < cntlr.fpr_max; fpr++) { - reg = read32(&fpr_base[fpr]); - if (reg == 0) - break; - } - - if (fpr == cntlr.fpr_max) { - DEBUG((EFI_D_INFO, "%a ERROR: No SPI FPR free!\n", __FUNCTION__)); - return -1; - } - - switch (type) { - case WRITE_PROTECT: - protect_mask |= SPI_FPR_WPE; - break; - case READ_PROTECT: - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) - return -1; - protect_mask |= ICH9_SPI_FPR_RPE; - break; - case READ_WRITE_PROTECT: - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) - return -1; - protect_mask |= (ICH9_SPI_FPR_RPE | SPI_FPR_WPE); - break; - default: - DEBUG((EFI_D_INFO, "%a ERROR: Seeking invalid protection!\n", __FUNCTION__)); - return -1; - } - - /* Set protected range base and limit */ - reg = spi_fpr(start, end) | protect_mask; - - /* Set the FPR register and verify it is protected */ - write32(&fpr_base[fpr], reg); - if (reg != read32(&fpr_base[fpr])) { - DEBUG((EFI_D_INFO, "%a ERROR: Unable to set SPI FPR %d\n", __FUNCTION__, fpr)); - return -1; - } - - DEBUG((EFI_D_INFO, "%a: FPR %d is enabled for range 0x%08x-0x%08x\n", - __FUNCTION__, fpr, start, end)); - return 0; -} - static struct spi_flash spi_flash_info; static BOOLEAN spi_flash_init_done; From 226a96fc090c4876b92a965bca05d6b967d775dd Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:28:37 +0200 Subject: [PATCH 164/297] fix some errors 35 --- UefiPayloadPkg/SPI/intelSPI.c | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 031cd8b8defe..ab02b0dee84f 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -824,13 +824,6 @@ static INT32 ich_status_poll(UINT16 bitmask, INT32 wait_til_set) return -1; } -static INT32 spi_is_multichip(VOID) -{ - if (!(cntlr.hsfs & HSFS_FDV)) - return 0; - return !!((cntlr.flmap0 >> 8) & 3); -} - static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { @@ -1214,12 +1207,6 @@ static int ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TY return 0; } -static CONST struct spi_flash_ops spi_flash_ops = { - .read = ich_hwseq_read, - .write = ich_hwseq_write, - .erase = ich_hwseq_erase, -}; - static int do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout, __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) { @@ -1507,23 +1494,6 @@ INT64 spi_flash_vector_helper(CONST struct spi_slave *slave, #define ICH9_SPI_FPR_RPE (1 << 15) /* Read Protect */ #define SPI_FPR_WPE (1 << 31) /* Write Protect */ -static UINT32 spi_fpr(UINT32 base, UINT32 limit) -{ - UINT32 ret; - UINT32 mask, limit_shift; - - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { - mask = ICH7_SPI_FPR_MASK; - limit_shift = ICH7_SPI_FPR_LIMIT_SHIFT; - } else { - mask = ICH9_SPI_FPR_MASK; - limit_shift = ICH9_SPI_FPR_LIMIT_SHIFT; - } - ret = ((limit >> SPI_FPR_SHIFT) & mask) << limit_shift; - ret |= ((base >> SPI_FPR_SHIFT) & mask) << SPI_FPR_BASE_SHIFT; - return ret; -} - static inline __SIZE_TYPE__ region_offset(CONST struct region *r) { return r->offset; From 546c76205924f9bc20295823de0d1a9b76588b82 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:32:44 +0200 Subject: [PATCH 165/297] fix some errors 36 --- UefiPayloadPkg/SPI/intelSPI.c | 144 ---------------------------------- 1 file changed, 144 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index ab02b0dee84f..6a7587429f4b 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -268,8 +268,6 @@ struct boot_state_init_entry { BOOT_STATE_INIT_ATTR = \ &func_ ##_## state_ ##_## when_; -static INT32 spi_is_multichip(VOID); - typedef UINT32 pci_devfn_t; /* @@ -1025,57 +1023,6 @@ static INT32 ich_hwseq_wait_for_cycle_complete(UINT32 timeout, return 0; } - -static int ich_hwseq_erase(CONST struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len) -{ - UINT32 start, end, erase_size; - int ret; - UINT16 hsfc; - unsigned int timeout = 1000 * USECS_PER_MSEC; /* 1 second timeout */ - - erase_size = flash->sector_size; - if (offset % erase_size || len % erase_size) { - DEBUG((EFI_D_INFO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); - return -1; - } - - ret = spi_claim_bus(&flash->spi); - if (ret) { - DEBUG((EFI_D_INFO, "%a SF: Unable to claim SPI bus\n", __FUNCTION__)); - return ret; - } - - start = offset; - end = start + len; - - while (offset < end) { - /* make sure FDONE, FCERR, AEL are cleared by writing 1 to them */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - ich_hwseq_set_addr(offset); - - offset += erase_size; - - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* clear operation */ - hsfc |= (0x3 << HSFC_FCYCLE_OFF); /* set erase operation */ - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - if (ich_hwseq_wait_for_cycle_complete(timeout, len)) { - DEBUG((EFI_D_INFO, "%a SF: Erase failed at %x\n", __FUNCTION__, offset - erase_size)); - ret = -1; - goto out; - } - } - - DEBUG((EFI_D_INFO, "%a SF: Successfully erased %zu bytes @ %#x\n", __FUNCTION__, len, start)); - -out: - spi_release_bus(&flash->spi); - return ret; -} - static VOID ich_read_data(UINT8 *data, INT32 len) { INT32 i; @@ -1089,48 +1036,6 @@ static VOID ich_read_data(UINT8 *data, INT32 len) } } -static int ich_hwseq_read(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - VOID *buf) -{ - UINT16 hsfc; - UINT16 timeout = 100 * 60; - UINT8 block_len; - - if (addr + len > flash->size) { - DEBUG((EFI_D_INFO, - "%a Attempt to read %x-%x which is out of chip\n", - __FUNCTION__, - (unsigned int) addr, - (unsigned int) addr+(unsigned int) len)); - return -1; - } - - /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - while (len > 0) { - block_len = MIN(len, cntlr.databytes); - if (block_len > (~addr & 0xff)) - block_len = (~addr & 0xff) + 1; - ich_hwseq_set_addr(addr); - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* set read operation */ - hsfc &= ~HSFC_FDBC; /* clear byte count */ - /* set byte count */ - hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - - if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) - return 1; - ich_read_data(buf, block_len); - addr += block_len; - buf += block_len; - len -= block_len; - } - return 0; -} - /* Fill len bytes from the data array into the fdata/spid registers. * * Note that using len > flash->pgm->spi.max_data_write will trash the registers @@ -1158,55 +1063,6 @@ static VOID ich_fill_data(CONST UINT8 *data, INT32 len) writel_(temp32, cntlr.data + (i - (i % 4))); } -static int ich_hwseq_write(CONST struct spi_flash *flash, UINT32 addr, __SIZE_TYPE__ len, - CONST VOID *buf) -{ - UINT16 hsfc; - UINT16 timeout = 100 * 60; - UINT8 block_len; - UINT32 start = addr; - - if (addr + len > flash->size) { - DEBUG((EFI_D_INFO, - "%a Attempt to write 0x%x-0x%x which is out of chip\n", - __FUNCTION__, (unsigned int)addr, (unsigned int) (addr+len))); - return -1; - } - - /* clear FDONE, FCERR, AEL by writing 1 to them (if they are set) */ - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - while (len > 0) { - block_len = MIN(len, cntlr.databytes); - if (block_len > (~addr & 0xff)) - block_len = (~addr & 0xff) + 1; - - ich_hwseq_set_addr(addr); - - ich_fill_data(buf, block_len); - hsfc = readw_(&cntlr.ich9_spi->hsfc); - hsfc &= ~HSFC_FCYCLE; /* clear operation */ - hsfc |= (0x2 << HSFC_FCYCLE_OFF); /* set write operation */ - hsfc &= ~HSFC_FDBC; /* clear byte count */ - /* set byte count */ - hsfc |= (((block_len - 1) << HSFC_FDBC_OFF) & HSFC_FDBC); - hsfc |= HSFC_FGO; /* start */ - writew_(hsfc, &cntlr.ich9_spi->hsfc); - - if (ich_hwseq_wait_for_cycle_complete(timeout, block_len)) { - DEBUG((EFI_D_INFO, "%a SF: write failure at %x\n", - __FUNCTION__, addr)); - return -1; - } - addr += block_len; - buf += block_len; - len -= block_len; - } - DEBUG((EFI_D_INFO, "%a SF: Successfully written %u bytes @ %#x\n", - __FUNCTION__, (unsigned int) (addr - start), start)); - return 0; -} - static int do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout, __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) { From f1ebf93a18f30b9624aa2991acf30d192105bf74 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:36:15 +0200 Subject: [PATCH 166/297] fix some errors 37 --- UefiPayloadPkg/SPI/intelSPI.c | 92 ----------------------------------- 1 file changed, 92 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 6a7587429f4b..bbc70271a7e3 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -971,98 +971,6 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, return 0; } -/* Sets FLA in FADDR to (addr & 0x01FFFFFF) without touching other bits. */ -static VOID ich_hwseq_set_addr(UINT32 addr) -{ - UINT32 addr_old = readl_(&cntlr.ich9_spi->faddr) & ~0x01FFFFFF; - - writel_((addr & 0x01FFFFFF) | addr_old, &cntlr.ich9_spi->faddr); -} - -/* Polls for Cycle Done Status, Flash Cycle Error or timeout in 8 us intervals. - Resets all error flags in HSFS. - Returns 0 if the cycle completes successfully without errors within - timeout us, 1 on errors. */ -static INT32 ich_hwseq_wait_for_cycle_complete(UINT32 timeout, - UINT32 len) -{ - UINT16 hsfs; - UINT32 addr; - - timeout /= 8; /* scale timeout duration to counter */ - while ((((hsfs = readw_(&cntlr.ich9_spi->hsfs)) & - (HSFS_FDONE | HSFS_FCERR)) == 0) && - --timeout) { - udelay(8); - } - writew_(readw_(&cntlr.ich9_spi->hsfs), &cntlr.ich9_spi->hsfs); - - if (!timeout) { - UINT16 hsfc; - addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; - hsfc = readw_(&cntlr.ich9_spi->hsfc); - DEBUG((EFI_D_INFO, "%a Transaction timeout between offset 0x%08x and " - "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", - __FUNCTION__, - addr, addr + len - 1, addr, len - 1, - hsfc, hsfs)); - return 1; - } - - if (hsfs & HSFS_FCERR) { - UINT16 hsfc; - addr = readl_(&cntlr.ich9_spi->faddr) & 0x01FFFFFF; - hsfc = readw_(&cntlr.ich9_spi->hsfc); - DEBUG((EFI_D_INFO, "%a Transaction error between offset 0x%08x and " - "0x%08x (= 0x%08x + %d) HSFC=%x HSFS=%x!\n", - __FUNCTION__, - addr, addr + len - 1, addr, len - 1, - hsfc, hsfs)); - return 1; - } - return 0; -} - -static VOID ich_read_data(UINT8 *data, INT32 len) -{ - INT32 i; - UINT32 temp32 = 0; - - for (i = 0; i < len; i++) { - if ((i % 4) == 0) - temp32 = readl_(cntlr.data + i); - - data[i] = (temp32 >> ((i % 4) * 8)) & 0xff; - } -} - -/* Fill len bytes from the data array into the fdata/spid registers. - * - * Note that using len > flash->pgm->spi.max_data_write will trash the registers - * following the data registers. - */ -static VOID ich_fill_data(CONST UINT8 *data, INT32 len) -{ - UINT32 temp32 = 0; - INT32 i; - - if (len <= 0) - return; - - for (i = 0; i < len; i++) { - if ((i % 4) == 0) - temp32 = 0; - - temp32 |= ((UINT32) data[i]) << ((i % 4) * 8); - - if ((i % 4) == 3) /* 32 bits are full, write them to regs. */ - writel_(temp32, cntlr.data + (i - (i % 4))); - } - i--; - if ((i % 4) != 3) /* Write remaining data to regs. */ - writel_(temp32, cntlr.data + (i - (i % 4))); -} - static int do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout, __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) { From 368374ce0a8832494fdc6e1ee641ae3f2cf1ec17 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 12:51:39 +0200 Subject: [PATCH 167/297] spi_setup_slave --- UefiPayloadPkg/SPI/SPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 305decb98047..aa34bb8311ff 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -67,5 +67,7 @@ EFI_STATUS EFIAPI SPIInitialize ( } else { DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } + struct spi_slave slave; + spi_setup_slave(0, 0, &slave); return EFI_SUCCESS; } From e0e21bb2f5561b235a502e114cf144ff183548ce Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 13:21:47 +0200 Subject: [PATCH 168/297] spi_xfer --- UefiPayloadPkg/SPI/SPI.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index aa34bb8311ff..043b1f96a529 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -43,20 +43,9 @@ EFI_STATUS EFIAPI SPIInitialize ( { EFI_STATUS Status; struct spi_slave slave; - Status = gBS->InstallProtocolInterface( - ImageHandle, - &gEfiDevicePathProtocolGuid, - EFI_NATIVE_INTERFACE, - &FvbProtocol); - if(EFI_ERROR (Status)) { - DEBUG((EFI_D_INFO, "%a Error during single protocol installation\n", __FUNCTION__)); - } else { - DEBUG((EFI_D_INFO, "%a Successfull signgle protocol installation\n", __FUNCTION__)); - } DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); - DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, @@ -67,7 +56,24 @@ EFI_STATUS EFIAPI SPIInitialize ( } else { DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } - struct spi_slave slave; - spi_setup_slave(0, 0, &slave); + DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); + /*----------------------------------------------------------------------- + * SPI transfer + * + * spi_xfer() interface: + * slave: The SPI slave which will be sending/receiving the data. + * dout: Pointer to a string of bytes to send out. + * bytesout: How many bytes to write. + * din: Pointer to a string of bytes that will be filled in. + * bytesin: How many bytes to read. + * + * Note that din and dout are transferred simultaneously in a full duplex + * transaction. The number of clocks within one transaction is calculated + * as: MAX(bytesout*8, bytesin*8). + * + * Returns: 0 on success, not 0 on failure + */ + char fill[255]; + DEBUG((EFI_D_INFO, "spi_xfer() returned 0x%X\n", spi_xfer(&slave, "asdf", 4, &fill, 0))); return EFI_SUCCESS; } From f16041346b3dc7c0cc38913872b020ffdf55cdea Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 13:45:47 +0200 Subject: [PATCH 169/297] change max xfer size --- UefiPayloadPkg/SPI/intelSPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index bbc70271a7e3..a4d044a3d983 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1742,7 +1742,7 @@ static CONST struct spi_ctrlr spi_ctrlr = { .xfer = spi_ctrlr_xfer, .xfer_vector = NULL, .xfer_dual = NULL, - .max_xfer_size = 0x40, + .max_xfer_size = 0, .flags = 0, .flash_probe = NULL, .flash_protect = NULL From 01af3d522eddc862cde72ab26ff0ae265e0253f1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 14:37:42 +0200 Subject: [PATCH 170/297] change max xfer size 2 --- UefiPayloadPkg/SPI/intelSPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index a4d044a3d983..866dd346b762 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1742,7 +1742,7 @@ static CONST struct spi_ctrlr spi_ctrlr = { .xfer = spi_ctrlr_xfer, .xfer_vector = NULL, .xfer_dual = NULL, - .max_xfer_size = 0, + .max_xfer_size = UINT32_MAX, .flags = 0, .flash_probe = NULL, .flash_protect = NULL From e10f307d4f473c4523b0b300ee4d6866f091d0b0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 25 Sep 2020 14:44:37 +0200 Subject: [PATCH 171/297] change max xfer size 3 --- UefiPayloadPkg/SPI/intelSPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 866dd346b762..83eae2c821f3 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -1742,7 +1742,7 @@ static CONST struct spi_ctrlr spi_ctrlr = { .xfer = spi_ctrlr_xfer, .xfer_vector = NULL, .xfer_dual = NULL, - .max_xfer_size = UINT32_MAX, + .max_xfer_size = 0xFFFFFFFF, .flags = 0, .flash_probe = NULL, .flash_protect = NULL From f6ef8c2fa97a8df361fccb5b40f33c08209294da Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 08:24:51 +0200 Subject: [PATCH 172/297] add debug to spi_init --- UefiPayloadPkg/SPI/intelSPI.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 83eae2c821f3..c07ad06e4338 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -638,6 +638,29 @@ VOID spi_init(VOID) writel_(0x1000, &ich9_spi->fdoc); cntlr.flcomp = readl_(&ich9_spi->fdod); } + DEBUG((EFI_D_INFO, "------\n" + "%a SETTING UP CONTROLLER\n" + "SOUTHBRIDGE_INTEL_I82801GX: 0x%X\n" + "ich7_spi: 0x%X\n" + "ich9_spi: 0x%X\n" + "hsfs: 0x%X\n" + "opmenu: 0x%X\n" + "menubytes: 0x%X\n" + "optype: 0x%X\n" + "addr: 0x%X\n" + "data: 0x%X\n" + "databytes: 0x%X\n" + "status: 0x%X\n" + "control: 0x%X\n" + "bbar: 0x%X\n" + "preop: 0x%X\n" + "fpr: 0x%X\n" + "fpr_max: 0x%X\n" + "------\n", + __FUNCTION__, cntlr.ich7_spi, cntlr.ich9_spi, cntlr.hsfs, cntlr.opmenu, + cntlr.menubytes, cntlr.optype, cntlr.addr, cntlr.data, cntlr.databytes, + cntlr.status, cntlr.control, cntlr.bbar, cntlr.preop, cntlr.fpr, + cntlr.fpr_max)); } ich_set_bbar(0); From 536c68aab4dc3750aaac988a6d406b2cd2a6a5d8 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 09:03:56 +0200 Subject: [PATCH 173/297] add some debug --- UefiPayloadPkg/SPI/intelSPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index c07ad06e4338..338eacd03bcc 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -925,6 +925,8 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, goto spi_xfer_exit; } + DEBUG((EFI_D_INFO, "---\n%a\ntrans.bytesout: 0x%X\ncntlr.bytesout\n---\n", + __FUNCTION__, trans.bytesout, cntlr.databytes)); /* * Check if this is a write command attempting to transfer more bytes * than the controller can handle. Iterations for writes are not From 42199562f44d0c9fde426b26ca56b10e490e79ae Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 09:11:53 +0200 Subject: [PATCH 174/297] add some debug 2 --- UefiPayloadPkg/SPI/intelSPI.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 338eacd03bcc..13b7571d7df2 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -861,12 +861,12 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, /* There has to always at least be an opcode. */ if (!bytesout || !dout) { - DEBUG((EFI_D_INFO, "%a ICH SPI: No opcode for transfer\n", __FUNCTION__));; + DEBUG((EFI_D_INFO, "%a ICH SPI: No opcode for transfer\n", __FUNCTION__)); return -1; } /* Make sure if we read something we have a place to put it. */ if (bytesin != 0 && !din) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Read but no target buffer\n", __FUNCTION__));; + DEBUG((EFI_D_INFO, "%a ICH SPI: Read but no target buffer\n", __FUNCTION__)); return -1; } @@ -918,7 +918,7 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, return -1; if (status & SPIS_FCERR) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Command transaction error\n", __FUNCTION__));; + DEBUG((EFI_D_INFO, "%a ICH SPI: Command transaction error\n", __FUNCTION__)); return -1; } @@ -977,7 +977,7 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, return -1; if (status & SPIS_FCERR) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Data transaction error\n", __FUNCTION__));; + DEBUG((EFI_D_INFO, "%a ICH SPI: Data transaction error\n", __FUNCTION__)); return -1; } From 7959037d53772a7ea70a1e77a984ba09abced5d1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 09:16:17 +0200 Subject: [PATCH 175/297] add some debug 3 --- UefiPayloadPkg/SPI/intelSPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 13b7571d7df2..8e5e93de617f 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -925,7 +925,7 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, goto spi_xfer_exit; } - DEBUG((EFI_D_INFO, "---\n%a\ntrans.bytesout: 0x%X\ncntlr.bytesout\n---\n", + DEBUG((EFI_D_INFO, "---\n%a\ntrans.bytesout: 0x%X\ncntlr.bytesout: 0x%X\n---\n", __FUNCTION__, trans.bytesout, cntlr.databytes)); /* * Check if this is a write command attempting to transfer more bytes From a95c04957686d3341b2769694f44fc48021c97c6 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 09:28:14 +0200 Subject: [PATCH 176/297] call spi_init --- UefiPayloadPkg/SPI/SPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 043b1f96a529..bc97c12afc23 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -56,6 +56,8 @@ EFI_STATUS EFIAPI SPIInitialize ( } else { DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } + spi_init(); + DEBUG((EFI_D_INFO, "spiinit() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); /*----------------------------------------------------------------------- * SPI transfer From 32194005e0fc5287e0f0aeca91bb5700be646e20 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 09:43:28 +0200 Subject: [PATCH 177/297] typo --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index bc97c12afc23..fbd7b58ce47c 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -57,7 +57,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } spi_init(); - DEBUG((EFI_D_INFO, "spiinit() was called\n")); + DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); /*----------------------------------------------------------------------- * SPI transfer From 1900a02c24bdfa7a9a4106cbc9b2e7f96ae7ca0d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 09:56:14 +0200 Subject: [PATCH 178/297] add more debug --- UefiPayloadPkg/SPI/SPI.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index fbd7b58ce47c..b79017358e1b 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -56,6 +56,7 @@ EFI_STATUS EFIAPI SPIInitialize ( } else { DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } + DEBUG((EFI_D_INFO, "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\n")); spi_init(); DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); From 943443c1366f30419036c2e13ca2ce7c2fa44b04 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 10:05:22 +0200 Subject: [PATCH 179/297] debug --- UefiPayloadPkg/SPI/SPI.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index b79017358e1b..5ea7e918f726 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -43,7 +43,7 @@ EFI_STATUS EFIAPI SPIInitialize ( { EFI_STATUS Status; struct spi_slave slave; - DEBUG((EFI_D_INFO, "SPI IS HERE\n")); + DEBUG((EFI_D_INFO, "SPI IS HERE BLAHBLAH\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); Status = gBS->InstallMultipleProtocolInterfaces ( From 0db62d1d796392044583f7ce30142f292d26818c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 10:40:33 +0200 Subject: [PATCH 180/297] fix spi_init() --- UefiPayloadPkg/SPI/SPI.c | 3 ++- UefiPayloadPkg/SPI/SPIgeneric.c | 9 +++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 5ea7e918f726..61f5ba956ad9 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -15,6 +15,7 @@ #include #include "SPIgeneric.h" #include "SPI.h" +#include "intelSPI.h" EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { @@ -56,7 +57,7 @@ EFI_STATUS EFIAPI SPIInitialize ( } else { DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } - DEBUG((EFI_D_INFO, "WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW\n")); + DEBUG((EFI_D_INFO, "calling spi_init()\n")); spi_init(); DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index b2950d10317e..38927a3f9c3b 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -106,10 +106,11 @@ UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, return MIN(ctrlr_max, buf_len); } -VOID spi_init(VOID) -{ - /* Default weak implementation - do nothing. */ -} +// __attribute__((__weak__)) +// VOID spi_init(VOID) +// { +// /* Default weak implementation - do nothing. */ +// } UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { From 74088372dbb33c4a84a0ca547ca6177ac318fb01 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 10:52:34 +0200 Subject: [PATCH 181/297] fix redefinitions --- UefiPayloadPkg/SPI/intelSPI.h | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/UefiPayloadPkg/SPI/intelSPI.h b/UefiPayloadPkg/SPI/intelSPI.h index 2e6b396d9d5f..5a0ce838ac3b 100644 --- a/UefiPayloadPkg/SPI/intelSPI.h +++ b/UefiPayloadPkg/SPI/intelSPI.h @@ -4,23 +4,6 @@ #ifndef SOUTHBRIDGE_INTEL_SPI_H #define SOUTHBRIDGE_INTEL_SPI_H -enum optype { - READ_NO_ADDR = 0, - WRITE_NO_ADDR = 1, - READ_WITH_ADDR = 2, - WRITE_WITH_ADDR = 3 -}; - -struct intel_spi_op { - UINT8 op; - enum optype type; -}; - -struct intel_swseq_spi_config { - UINT8 opprefixes[2]; - struct intel_spi_op ops[8]; -}; - void spi_finalize_ops(void); void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config); From b1e8e40171a1a3e4d1d697ae4ca08f2073cff4bf Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 12:10:20 +0200 Subject: [PATCH 182/297] some debug is not working --- UefiPayloadPkg/SPI/SPI.c | 2 +- UefiPayloadPkg/SPI/intelSPI.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 61f5ba956ad9..723a7b975bbd 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -44,7 +44,7 @@ EFI_STATUS EFIAPI SPIInitialize ( { EFI_STATUS Status; struct spi_slave slave; - DEBUG((EFI_D_INFO, "SPI IS HERE BLAHBLAH\n")); + DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); Status = gBS->InstallMultipleProtocolInterfaces ( diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c index 8e5e93de617f..944847632efe 100644 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ b/UefiPayloadPkg/SPI/intelSPI.c @@ -656,7 +656,7 @@ VOID spi_init(VOID) "preop: 0x%X\n" "fpr: 0x%X\n" "fpr_max: 0x%X\n" - "------\n", + "------\n\n\n\n\n\n\n\n\n********\n", __FUNCTION__, cntlr.ich7_spi, cntlr.ich9_spi, cntlr.hsfs, cntlr.opmenu, cntlr.menubytes, cntlr.optype, cntlr.addr, cntlr.data, cntlr.databytes, cntlr.status, cntlr.control, cntlr.bbar, cntlr.preop, cntlr.fpr, From 85f2bcaee0a276e8028453d804243366a27fa848 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 14:23:56 +0200 Subject: [PATCH 183/297] port amd, not intel --- UefiPayloadPkg/SPI/SPI.c | 2 +- UefiPayloadPkg/SPI/SPIFvb.c | 399 ----- UefiPayloadPkg/SPI/amdSPI.c | 22 + UefiPayloadPkg/SPI/amdSPI.h | 3 + UefiPayloadPkg/SPI/helpers.h | 86 -- UefiPayloadPkg/SPI/intelSPI.c | 1784 ----------------------- UefiPayloadPkg/SPI/intelSPI.h | 10 - UefiPayloadPkg/SPI/lpc.c | 12 + UefiPayloadPkg/SPI/lpc.h | 22 + UefiPayloadPkg/SPI/spi_flash.h | 225 --- UefiPayloadPkg/SPI/spi_flash_internal.h | 131 -- UefiPayloadPkg/SPI/spi_winbond.h | 25 - UefiPayloadPkg/SPI/winbond.c | 588 -------- 13 files changed, 60 insertions(+), 3249 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/SPIFvb.c create mode 100644 UefiPayloadPkg/SPI/amdSPI.c create mode 100644 UefiPayloadPkg/SPI/amdSPI.h delete mode 100644 UefiPayloadPkg/SPI/helpers.h delete mode 100644 UefiPayloadPkg/SPI/intelSPI.c delete mode 100644 UefiPayloadPkg/SPI/intelSPI.h create mode 100644 UefiPayloadPkg/SPI/lpc.c create mode 100644 UefiPayloadPkg/SPI/lpc.h delete mode 100644 UefiPayloadPkg/SPI/spi_flash.h delete mode 100644 UefiPayloadPkg/SPI/spi_flash_internal.h delete mode 100644 UefiPayloadPkg/SPI/spi_winbond.h delete mode 100644 UefiPayloadPkg/SPI/winbond.c diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 723a7b975bbd..2bee5a0dbd02 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -15,7 +15,7 @@ #include #include "SPIgeneric.h" #include "SPI.h" -#include "intelSPI.h" +#include "amdSPI.h" EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { diff --git a/UefiPayloadPkg/SPI/SPIFvb.c b/UefiPayloadPkg/SPI/SPIFvb.c deleted file mode 100644 index 033ccb66cab6..000000000000 --- a/UefiPayloadPkg/SPI/SPIFvb.c +++ /dev/null @@ -1,399 +0,0 @@ -/*++ @file BlSMMStoreFvbDxe.c - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - - --*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include "SPI.h" - -// STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; -// STATIC UINTN mFlashNvStorageVariableBase; - -/// -/// The Firmware Volume Block Protocol is the low-level interface -/// to a firmware volume. File-level access to a firmware volume -/// should not be done using the Firmware Volume Block Protocol. -/// Normal access to a firmware volume must use the Firmware -/// Volume Protocol. Typically, only the file system driver that -/// produces the Firmware Volume Protocol will bind to the -/// Firmware Volume Block Protocol. -/// - -/** - Initialises the FV Header and Variable Store Header - to support variable operations. - - @param[in] Ptr - Location to initialise the headers - -**/ -EFI_STATUS -InitializeFvAndVariableStoreHeaders ( - IN SMMSTORE_INSTANCE *Instance - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - Check the integrity of firmware volume header. - - @param[in] FwVolHeader - A pointer to a firmware volume header - - @retval EFI_SUCCESS - The firmware volume is consistent - @retval EFI_NOT_FOUND - The firmware volume has been corrupted. - -**/ -EFI_STATUS -ValidateFvHeader ( - IN SMMSTORE_INSTANCE *Instance - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - The GetAttributes() function retrieves the attributes and - current settings of the block. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and - current settings are returned. - Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - - **/ -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - The SetAttributes() function sets configurable firmware volume attributes - and returns the new settings of the firmware volume. - - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 - that contains the desired firmware volume settings. - On successful return, it contains the new settings of - the firmware volume. - Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - - @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities - as declared in the firmware volume header. - - **/ -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - The GetPhysicalAddress() function retrieves the base address of - a memory-mapped firmware volume. This function should be called - only for memory-mapped firmware volumes. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Address Pointer to a caller-allocated - EFI_PHYSICAL_ADDRESS that, on successful - return from GetPhysicalAddress(), contains the - base address of the firmware volume. - - @retval EFI_SUCCESS The firmware volume base address was returned. - - @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. - - **/ -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - The GetBlockSize() function retrieves the size of the requested - block. It also returns the number of additional blocks with - the identical size. The GetBlockSize() function is used to - retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). - - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba Indicates the block for which to return the size. - - @param BlockSize Pointer to a caller-allocated UINTN in which - the size of the block is returned. - - @param NumberOfBlocks Pointer to a caller-allocated UINTN in - which the number of consecutive blocks, - starting with Lba, is returned. All - blocks in this range have a size of - BlockSize. - - - @retval EFI_SUCCESS The firmware volume base address was returned. - - @retval EFI_INVALID_PARAMETER The requested LBA is out of range. - - **/ -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - Reads the specified number of bytes into a buffer from the specified block. - - The Read() function reads the requested number of bytes from the - requested block and stores them in the provided buffer. - Implementations should be mindful that the firmware volume - might be in the ReadDisabled state. If it is in this state, - the Read() function must return the status code - EFI_ACCESS_DENIED without modifying the contents of the - buffer. The Read() function must also prevent spanning block - boundaries. If a read is requested that would span a block - boundary, the read must read up to the boundary but not - beyond. The output parameter NumBytes must be set to correctly - indicate the number of bytes actually read. The caller must be - aware that a read may be partially completed. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba The starting logical block index from which to read. - - @param Offset Offset into the block at which to begin reading. - - @param NumBytes Pointer to a UINTN. - At entry, *NumBytes contains the total size of the buffer. - At exit, *NumBytes contains the total number of bytes read. - - @param Buffer Pointer to a caller-allocated buffer that will be used - to hold the data that is read. - - @retval EFI_SUCCESS The firmware volume was read successfully, and contents are - in Buffer. - - @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. - On output, NumBytes contains the total number of bytes - returned in Buffer. - - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. - - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. - - **/ -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - Writes the specified number of bytes from the input buffer to the block. - - The Write() function writes the specified number of bytes from - the provided buffer to the specified block and offset. If the - firmware volume is sticky write, the caller must ensure that - all the bits of the specified range to write are in the - EFI_FVB_ERASE_POLARITY state before calling the Write() - function, or else the result will be unpredictable. This - unpredictability arises because, for a sticky-write firmware - volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY - state but cannot flip it back again. Before calling the - Write() function, it is recommended for the caller to first call - the EraseBlocks() function to erase the specified block to - write. A block erase cycle will transition bits from the - (NOT)EFI_FVB_ERASE_POLARITY state back to the - EFI_FVB_ERASE_POLARITY state. Implementations should be - mindful that the firmware volume might be in the WriteDisabled - state. If it is in this state, the Write() function must - return the status code EFI_ACCESS_DENIED without modifying the - contents of the firmware volume. The Write() function must - also prevent spanning block boundaries. If a write is - requested that spans a block boundary, the write must store up - to the boundary but not beyond. The output parameter NumBytes - must be set to correctly indicate the number of bytes actually - written. The caller must be aware that a write may be - partially completed. All writes, partial or otherwise, must be - fully flushed to the hardware before the Write() service - returns. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba The starting logical block index to write to. - - @param Offset Offset into the block at which to begin writing. - - @param NumBytes The pointer to a UINTN. - At entry, *NumBytes contains the total size of the buffer. - At exit, *NumBytes contains the total number of bytes actually written. - - @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully. - - @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. - On output, NumBytes contains the total number of bytes - actually written. - - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. - - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. - - - **/ -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - Erases and initialises a firmware volume block. - - The EraseBlocks() function erases one or more blocks as denoted - by the variable argument list. The entire parameter list of - blocks must be verified before erasing any blocks. If a block is - requested that does not exist within the associated firmware - volume (it has a larger index than the last block of the - firmware volume), the EraseBlocks() function must return the - status code EFI_INVALID_PARAMETER without modifying the contents - of the firmware volume. Implementations should be mindful that - the firmware volume might be in the WriteDisabled state. If it - is in this state, the EraseBlocks() function must return the - status code EFI_ACCESS_DENIED without modifying the contents of - the firmware volume. All calls to EraseBlocks() must be fully - flushed to the hardware before the EraseBlocks() service - returns. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL - instance. - - @param ... The variable argument list is a list of tuples. - Each tuple describes a range of LBAs to erase - and consists of the following: - - An EFI_LBA that indicates the starting LBA - - A UINTN that indicates the number of blocks to erase. - - The list is terminated with an EFI_LBA_LIST_TERMINATOR. - For example, the following indicates that two ranges of blocks - (5-7 and 10-11) are to be erased: - EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); - - @retval EFI_SUCCESS The erase request successfully completed. - - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. - - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. - The firmware device may have been partially erased. - - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do - not exist in the firmware volume. - - **/ -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - Fixup internal data so that EFI can be call in virtual mode. - Call the passed in Child Notify event and convert any pointers in - lib to virtual mode. - - @param[in] Event The Event that is being processed - @param[in] Context Event Context -**/ -VOID -EFIAPI -FvbVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return; -} - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; -} diff --git a/UefiPayloadPkg/SPI/amdSPI.c b/UefiPayloadPkg/SPI/amdSPI.c new file mode 100644 index 000000000000..ccd9687b8927 --- /dev/null +++ b/UefiPayloadPkg/SPI/amdSPI.c @@ -0,0 +1,22 @@ +#include +#include + +void spi_init(void) +{ + DEBUG((EFI_D_INFO, "%a: SPI BAR at 0x%08lx\n", __FUNCTION__, spi_get_bar())); +} + +static uintptr_t spi_base; + +void spi_set_base(void *base) +{ + spi_base = (uintptr_t)base; +} + +uintptr_t spi_get_bar(void) +{ + if (!spi_base) + spi_set_base((void *)lpc_get_spibase()); + + return spi_base; +} diff --git a/UefiPayloadPkg/SPI/amdSPI.h b/UefiPayloadPkg/SPI/amdSPI.h new file mode 100644 index 000000000000..e49678e0f7af --- /dev/null +++ b/UefiPayloadPkg/SPI/amdSPI.h @@ -0,0 +1,3 @@ +#include + +VOID spi_init(VOID); diff --git a/UefiPayloadPkg/SPI/helpers.h b/UefiPayloadPkg/SPI/helpers.h deleted file mode 100644 index 692bc48d0467..000000000000 --- a/UefiPayloadPkg/SPI/helpers.h +++ /dev/null @@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0-only */ - -#ifndef COMMONLIB_BSD_HELPERS_H -#define COMMONLIB_BSD_HELPERS_H - -#ifndef ARRAY_SIZE -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -#endif - -#define ALIGN(x, a) __ALIGN_MASK(x, (__typeof__(x))(a)-1UL) -#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask)) -#define ALIGN_UP(x, a) ALIGN((x), (a)) -#define ALIGN_DOWN(x, a) ((x) & ~((__typeof__(x))(a)-1UL)) -#define IS_ALIGNED(x, a) (((x) & ((__typeof__(x))(a)-1UL)) == 0) - -/* Double-evaluation unsafe min/max, for bitfields and outside of functions */ -#define __CMP_UNSAFE(a, b, op) ((a) op (b) ? (a) : (b)) -#define MIN_UNSAFE(a, b) __CMP_UNSAFE(a, b, <) -#define MAX_UNSAFE(a, b) __CMP_UNSAFE(a, b, >) - -#define __CMP_SAFE(a, b, op, var_a, var_b) ({ \ - __TYPEOF_UNLESS_CONST(a, b) var_a = (a); \ - __TYPEOF_UNLESS_CONST(b, a) var_b = (b); \ - var_a op var_b ? var_a : var_b; \ -}) - -#define __CMP(a, b, op) __builtin_choose_expr( \ - __builtin_constant_p(a) && __builtin_constant_p(b), \ - __CMP_UNSAFE(a, b, op), __CMP_SAFE(a, b, op, __TMPNAME, __TMPNAME)) - -#ifndef MIN -#define MIN(a, b) __CMP(a, b, <) -#endif -#ifndef MAX -#define MAX(a, b) __CMP(a, b, >) -#endif - -#ifndef ABS -#define ABS(a) ({ \ - __typeof__(a) _abs_local_a = (a); \ - (_abs_local_a < 0) ? (-_abs_local_a) : _abs_local_a; \ -}) -#endif - -#define IS_POWER_OF_2(x) ({ \ - __typeof__(x) _power_local_x = (x); \ - (_power_local_x & (_power_local_x - 1)) == 0; \ -}) - -#define POWER_OF_2(x) (1ULL << (x)) - -#define DIV_ROUND_UP(x, y) ({ \ - __typeof__(x) _div_local_x = (x); \ - __typeof__(y) _div_local_y = (y); \ - (_div_local_x + _div_local_y - 1) / _div_local_y; \ -}) - -#define SWAP(a, b) do { \ - __typeof__(&(a)) _swap_local_a = &(a); \ - __typeof__(&(b)) _swap_local_b = &(b); \ - __typeof__(a) _swap_local_tmp = *_swap_local_a; \ - *_swap_local_a = *_swap_local_b; \ - *_swap_local_b = _swap_local_tmp; \ -} while (0) - -/* Standard units. */ -#define KiB (1<<10) -#define MiB (1<<20) -#define GiB (1<<30) - -#define KHz (1000) -#define MHz (1000 * KHz) -#define GHz (1000 * MHz) - -#ifndef offsetof -#define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER) -#endif - -#define check_member(structure, member, offset) _Static_assert( \ - offsetof(struct structure, member) == offset, \ - "`struct " #structure "` offset for `" #member "` is not " #offset) - -/* Calculate size of structure member. */ -#define member_size(type, member) (sizeof(((type *)0)->member)) - -#endif /* COMMONLIB_BSD_HELPERS_H */ diff --git a/UefiPayloadPkg/SPI/intelSPI.c b/UefiPayloadPkg/SPI/intelSPI.c deleted file mode 100644 index 944847632efe..000000000000 --- a/UefiPayloadPkg/SPI/intelSPI.c +++ /dev/null @@ -1,1784 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#define __SIMPLE_DEVICE__ - -/* This file is derived from the flashrom project. */ - -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include -// #include - -#include -#include -#include "SPI.h" -#include "SPIgeneric.h" -#include "helpers.h" -#include "spi_winbond.h" -#include "spi_flash_internal.h" - -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#define __SIMPLE_DEVICE__ - -#define HSFC_FCYCLE_OFF 1 /* 1-2: FLASH Cycle */ -#define HSFC_FCYCLE (0x3 << HSFC_FCYCLE_OFF) -#define HSFC_FDBC_OFF 8 /* 8-13: Flash Data Byte Count */ -#define HSFC_FDBC (0x3f << HSFC_FDBC_OFF) - -/* SPI Flash opcodes */ -#define SPI_OPCODE_WREN 0x06 -#define SPI_OPCODE_FAST_READ 0x0b - -/* Common commands */ -#define CMD_READ_ID 0x9f - -#define CMD_READ_ARRAY_SLOW 0x03 -#define CMD_READ_ARRAY_FAST 0x0b -#define CMD_READ_ARRAY_LEGACY 0xe8 - -#define CMD_READ_FAST_DUAL_OUTPUT 0x3b - -#define CMD_READ_STATUS 0x05 -#define CMD_WRITE_ENABLE 0x06 - -#define CMD_BLOCK_ERASE 0xD8 - -/* Common status */ -#define STATUS_WIP 0x01 - -#define NSECS_PER_SEC 1000000000 -#define USECS_PER_SEC 1000000 -#define MSECS_PER_SEC 1000 -#define USECS_PER_MSEC (USECS_PER_SEC / MSECS_PER_SEC) - -#define __ARG_PLACEHOLDER_1 0, -#define config_enabled(cfg) _config_enabled(cfg) -#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) -#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0, 0) -#define ___config_enabled(__ignored, val, ...) val -#define CONFIG(option) config_enabled(CONFIG_##option) - -#if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) -#define MENU_BYTES member_size(struct ich7_spi_regs, opmenu) -#else -#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) -#endif - -#define pci_read_config8 pci_s_read_config8 -#define pci_read_config16 pci_s_read_config16 -#define pci_read_config32 pci_s_read_config32 -#define pci_write_config8 pci_s_write_config8 -#define pci_write_config16 pci_s_write_config16 -#define pci_write_config32 pci_s_write_config32 - -/* Convert pci_devfn_t to offset in MMCONF space. - * As it is one-to-one, nothing needs to be done. */ -#define PCI_DEVFN_OFFSET(x) ((x)) - -#define PCI_DEV(SEGBUS, DEV, FN) ( \ - (((SEGBUS) & 0xFFF) << 20) | \ - (((DEV) & 0x1F) << 15) | \ - (((FN) & 0x07) << 12)) - -#define PCI_DEV_INVALID (0xffffffffU) - -/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we - * prevent some sub-optimal constant folding. */ -extern UINT8 *CONST pci_mmconf; - -/* Using a unique datatype for MMIO writes makes the pointers to _not_ - * qualify for pointer aliasing with any other objects in memory. - * - * MMIO offset is a value originally derived from 'struct device *' - * in ramstage. For the compiler to not discard this MMIO offset value - * from CPU registers after any MMIO writes, -fstrict-aliasing has to - * be also set for the build. - * - * Bottom 12 bits (4 KiB) are reserved to address the registers of a - * single PCI function. Declare the bank as a union to aVOID some casting - * in the functions below. - */ -union pci_bank { - UINT8 reg8[4096]; - UINT16 reg16[4096 / sizeof(UINT16)]; - UINT32 reg32[4096 / sizeof(UINT32)]; -}; - -typedef UINT32 pci_devfn_t; - -static __attribute__((always_inline)) inline -volatile union pci_bank *pcicfg(pci_devfn_t dev) -{ - return (VOID *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; -} - -static __attribute__((always_inline)) inline -UINT8 pci_mmio_read_config8(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg8[reg]; -} - -static __attribute__((always_inline)) inline -UINT16 pci_mmio_read_config16(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg16[reg / sizeof(UINT16)]; -} - -static __attribute__((always_inline)) inline -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -static __attribute__((always_inline)) inline -VOID pci_mmio_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) -{ - pcicfg(dev)->reg8[reg] = value; -} - -static __attribute__((always_inline)) inline -VOID pci_mmio_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) -{ - pcicfg(dev)->reg16[reg / sizeof(UINT16)] = value; -} - -static __attribute__((always_inline)) inline -VOID pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} - -static __attribute__((always_inline)) inline -UINT8 pci_s_read_config8(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config8(dev, reg); -} - -static __attribute__((always_inline)) inline -UINT16 pci_s_read_config16(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config16(dev, reg); -} - -static __attribute__((always_inline)) inline -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -static __attribute__((always_inline)) inline -VOID pci_s_write_config8(pci_devfn_t dev, UINT16 reg, UINT8 value) -{ - pci_mmio_write_config8(dev, reg, value); -} - -static __attribute__((always_inline)) inline -VOID pci_s_write_config16(pci_devfn_t dev, UINT16 reg, UINT16 value) -{ - pci_mmio_write_config16(dev, reg, value); -} - -static __attribute__((always_inline)) inline -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pci_mmio_write_config32(dev, reg, value); -} - -/* Function unit addresses. */ -enum { - UP_TAG_BASE = 0x60000000, - TIMER_BASE = 0x60005000, - CLK_RST_BASE = 0x60006000, - FLOW_CTLR_BASE = 0x60007000, - SECURE_BOOT_BASE = 0x6000C200, - TEGRA_EVP_BASE = 0x6000f000, - APB_MISC_BASE = 0x70000000, - PINMUX_BASE = 0x70003000, - PMC_CTLR_BASE = 0x7000e400, - MC_CTLR_BASE = 0x70019000, - FUSE_BASE = 0x7000F800, - TEGRA_SDMMC1_BASE = 0x700b0000, - TEGRA_SDMMC3_BASE = 0x700b0400, - EMC_BASE = 0x7001B000, - I2C5_BASE = 0x7000D000, - I2S_BASE = 0x702d1000 -}; - -typedef enum { - BS_PRE_DEVICE, - BS_DEV_INIT_CHIPS, - BS_DEV_ENUMERATE, - BS_DEV_RESOURCES, - BS_DEV_ENABLE, - BS_DEV_INIT, - BS_POST_DEVICE, - BS_OS_RESUME_CHECK, - BS_OS_RESUME, - BS_WRITE_TABLES, - BS_PAYLOAD_LOAD, - BS_PAYLOAD_BOOT, -} boot_state_t; - -typedef enum { - BS_ON_ENTRY, - BS_ON_EXIT -} boot_state_sequence_t; - -struct boot_state_callback { - VOID *arg; - VOID (*callback)(VOID *arg); - /* For use internal to the boot state machine. */ - struct boot_state_callback *next; -}; - -struct boot_state_init_entry { - boot_state_t state; - boot_state_sequence_t when; - struct boot_state_callback bscb; -}; - -#define BOOT_STATE_CALLBACK_INIT(func_, arg_) \ - { \ - .arg = arg_, \ - .callback = func_, \ - .next = NULL, \ - } - -#define BOOT_STATE_INIT_ATTR __attribute__((unused)) - -#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \ - static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \ - { \ - .state = state_, \ - .when = when_, \ - .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \ - }; \ - static struct boot_state_init_entry * \ - bsie_ ## func_ ##_## state_ ##_## when_ \ - BOOT_STATE_INIT_ATTR = \ - &func_ ##_## state_ ##_## when_; - -typedef UINT32 pci_devfn_t; - -/* - * The functions pci_mmio_config*_addr provide a way to determine the MMIO address of a PCI - * config register. The address returned is dependent of both the MMCONF base address and the - * assigned PCI bus number of the requested device, which both can change during the boot - * process. Thus, the pointer returned here must not be cached! - */ -static __attribute__((always_inline)) inline -UINT8 *pci_mmio_config8_addr(pci_devfn_t dev, UINT16 reg) -{ - return (UINT8 *)&pcicfg(dev)->reg8[reg]; -} - -static __attribute__((always_inline)) inline -UINT16 *pci_mmio_config16_addr(pci_devfn_t dev, UINT16 reg) -{ - return (UINT16 *)&pcicfg(dev)->reg16[reg / sizeof(UINT16)]; -} - -static __attribute__((always_inline)) inline -UINT32 *pci_mmio_config32_addr(pci_devfn_t dev, UINT16 reg) -{ - return (UINT32 *)&pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -struct ich7_spi_regs { - UINT16 spis; - UINT16 spic; - UINT32 spia; - UINT64 spid[8]; - UINT64 _pad; - UINT32 bbar; - UINT16 preop; - UINT16 optype; - UINT8 opmenu[8]; - UINT32 pbr[3]; -} __attribute__((packed)); - -struct ich9_spi_regs { - UINT32 bfpr; - UINT16 hsfs; - UINT16 hsfc; - UINT32 faddr; - UINT32 _reserved0; - UINT32 fdata[16]; - UINT32 frap; - UINT32 freg[5]; - UINT32 _reserved1[3]; - UINT32 pr[5]; - UINT32 _reserved2[2]; - UINT8 ssfs; - UINT8 ssfc[3]; - UINT16 preop; - UINT16 optype; - UINT8 opmenu[8]; - UINT32 bbar; - UINT8 _reserved3[12]; - UINT32 fdoc; - UINT32 fdod; - UINT8 _reserved4[8]; - UINT32 afc; - UINT32 lvscc; - UINT32 uvscc; - UINT8 _reserved5[4]; - UINT32 fpb; - UINT8 _reserved6[28]; - UINT32 srdl; - UINT32 srdc; - UINT32 srd; -} __attribute__((packed)); - -struct ich_spi_controller { - INT32 locked; - UINT32 flmap0; - UINT32 flcomp; - UINT32 hsfs; - - union { - struct ich9_spi_regs *ich9_spi; - struct ich7_spi_regs *ich7_spi; - }; - UINT8 *opmenu; - INT32 menubytes; - UINT16 *preop; - UINT16 *optype; - UINT32 *addr; - UINT8 *data; - UINT32 databytes; - UINT8 *status; - UINT16 *control; - UINT32 *bbar; - UINT32 *fpr; - UINT8 fpr_max; -}; - -static struct ich_spi_controller cntlr; - -enum { - SPIS_SCIP = 0x0001, - SPIS_GRANT = 0x0002, - SPIS_CDS = 0x0004, - SPIS_FCERR = 0x0008, - SSFS_AEL = 0x0010, - SPIS_LOCK = 0x8000, - SPIS_RESERVED_MASK = 0x7ff0, - SSFS_RESERVED_MASK = 0x7fe2 -}; - -enum { - SPIC_SCGO = 0x000002, - SPIC_ACS = 0x000004, - SPIC_SPOP = 0x000008, - SPIC_DBC = 0x003f00, - SPIC_DS = 0x004000, - SPIC_SME = 0x008000, - SSFC_SCF_MASK = 0x070000, - SSFC_RESERVED = 0xf80000 -}; - -enum { - HSFS_FDONE = 0x0001, - HSFS_FCERR = 0x0002, - HSFS_AEL = 0x0004, - HSFS_BERASE_MASK = 0x0018, - HSFS_BERASE_SHIFT = 3, - HSFS_SCIP = 0x0020, - HSFS_FDOPSS = 0x2000, - HSFS_FDV = 0x4000, - HSFS_FLOCKDN = 0x8000 -}; - -enum { - HSFC_FGO = 0x0001, - HSFC_FCYCLE_MASK = 0x0006, - HSFC_FCYCLE_SHIFT = 1, - HSFC_FDBC_MASK = 0x3f00, - HSFC_FDBC_SHIFT = 8, - HSFC_FSMIE = 0x8000 -}; - -enum { - SPI_OPCODE_TYPE_READ_NO_ADDRESS = 0, - SPI_OPCODE_TYPE_WRITE_NO_ADDRESS = 1, - SPI_OPCODE_TYPE_READ_WITH_ADDRESS = 2, - SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS = 3 -}; - -static inline UINT8 read8(CONST VOID *addr) -{ - return *(volatile UINT8 *)addr; -} - -static inline UINT16 read16(CONST VOID *addr) -{ - return *(volatile UINT16 *)addr; -} - -static inline UINT32 read32(CONST VOID *addr) -{ - return *(volatile UINT32 *)addr; -} - -static inline VOID write8(VOID *addr, UINT8 val) -{ - *(volatile UINT8 *)addr = val; -} - -static inline VOID write16(VOID *addr, UINT16 val) -{ - *(volatile UINT16 *)addr = val; -} - -static inline VOID write32(VOID *addr, UINT32 val) -{ - *(volatile UINT32 *)addr = val; -} - -#define IDCODE_LEN 5 - -static UINT32 *timer_us_ptr = (VOID *)(TIMER_BASE + 0x10); -static VOID udelay(UINT64 usecs) -{ - UINT32 start = read32(timer_us_ptr); - while (read32(timer_us_ptr) - start < usecs) - ; -} - -#define DEBUG_SPI_FLASH - -#ifdef DEBUG_SPI_FLASH - -static UINT8 readb_(CONST VOID *addr) -{ - UINT8 v = read8(addr); - - DEBUG((EFI_D_INFO, "%a read %2.2x from %4.4x\n", - __FUNCTION__, v, ((UINT64) addr & 0xffff) - 0xf020)); - return v; -} - -static UINT16 readw_(CONST VOID *addr) -{ - UINT16 v = read16(addr); - - DEBUG((EFI_D_INFO, "%a read %4.4x from %4.4x\n", - __FUNCTION__, v, ((UINT64) addr & 0xffff) - 0xf020)); - return v; -} - -static UINT32 readl_(CONST VOID *addr) -{ - UINT32 v = read32(addr); - - DEBUG((EFI_D_INFO, "%a read %8.8x from %4.4x\n", - __FUNCTION__, v, ((UINT64) addr & 0xffff) - 0xf020)); - return v; -} - -static VOID writeb_(UINT8 b, VOID *addr) -{ - write8(addr, b); - DEBUG((EFI_D_INFO, "%a wrote %2.2x to %4.4x\n", - __FUNCTION__, b, ((UINT64) addr & 0xffff) - 0xf020)); -} - -static VOID writew_(UINT16 b, VOID *addr) -{ - write16(addr, b); - DEBUG((EFI_D_INFO, "%a wrote %4.4x to %4.4x\n", - __FUNCTION__, b, ((UINT64) addr & 0xffff) - 0xf020)); -} - -static VOID writel_(UINT32 b, VOID *addr) -{ - write32(addr, b); - DEBUG((EFI_D_INFO, "%a wrote %8.8x to %4.4x\n", - __FUNCTION__, b, ((UINT64) addr & 0xffff) - 0xf020)); -} - -#else /* CONFIG_DEBUG_SPI_FLASH ^^^ enabled vvv NOT enabled */ - -#define readb_(a) read8(a) -#define readw_(a) read16(a) -#define readl_(a) read32(a) -#define writeb_(val, addr) write8(addr, val) -#define writew_(val, addr) write16(addr, val) -#define writel_(val, addr) write32(addr, val) - -#endif /* CONFIG_DEBUG_SPI_FLASH ^^^ NOT enabled */ - -static VOID write_reg(CONST VOID *value, VOID *dest, UINT32 size) -{ - CONST UINT8 *bvalue = value; - UINT8 *bdest = dest; - - while (size >= 4) { - writel_(*(CONST UINT32 *)bvalue, bdest); - bdest += 4; bvalue += 4; size -= 4; - } - while (size) { - writeb_(*bvalue, bdest); - bdest++; bvalue++; size--; - } -} - -static VOID read_reg(CONST VOID *src, VOID *value, UINT32 size) -{ - CONST UINT8 *bsrc = src; - UINT8 *bvalue = value; - - while (size >= 4) { - *(UINT32 *)bvalue = readl_(bsrc); - bsrc += 4; bvalue += 4; size -= 4; - } - while (size) { - *bvalue = readb_(bsrc); - bsrc++; bvalue++; size--; - } -} - -static VOID ich_set_bbar(UINT32 minaddr) -{ - CONST UINT32 bbar_mask = 0x00ffff00; - UINT32 ichspi_bbar; - - minaddr &= bbar_mask; - ichspi_bbar = readl_(cntlr.bbar) & ~bbar_mask; - ichspi_bbar |= minaddr; - writel_(ichspi_bbar, cntlr.bbar); -} - -#if CONFIG(SOUTHBRIDGE_INTEL_I82801GX) -#define MENU_BYTES member_size(struct ich7_spi_regs, opmenu) -#else -#define MENU_BYTES member_size(struct ich9_spi_regs, opmenu) -#endif - -#define RCBA 0xf0 -#define SBASE 0x54 - -static VOID *get_spi_bar(pci_devfn_t dev) -{ - unsigned long int rcba; /* Root Complex Register Block */ - unsigned long int sbase; - - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { - rcba = pci_read_config32(dev, RCBA); - return (VOID *)((rcba & 0xffffc000) + 0x3020); - } - if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_SILVERMONT)) { - sbase = pci_read_config32(dev, SBASE); - sbase &= ~0x1ff; - return (VOID *)sbase; - } - if (CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { - rcba = pci_read_config32(dev, RCBA); - return (VOID *)((rcba & 0xffffc000) + 0x3800); - } - return NULL; -} - -VOID spi_init(VOID) -{ - UINT8 bios_cntl; - struct ich9_spi_regs *ich9_spi; - struct ich7_spi_regs *ich7_spi; - UINT16 hsfs; - - pci_devfn_t dev = PCI_DEV(0, 31, 0); - - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { - ich7_spi = get_spi_bar(dev); - cntlr.ich7_spi = ich7_spi; - cntlr.opmenu = ich7_spi->opmenu; - cntlr.menubytes = sizeof(ich7_spi->opmenu); - cntlr.optype = &ich7_spi->optype; - cntlr.addr = &ich7_spi->spia; - cntlr.data = (UINT8 *)ich7_spi->spid; - cntlr.databytes = sizeof(ich7_spi->spid); - cntlr.status = (UINT8 *)&ich7_spi->spis; - cntlr.control = &ich7_spi->spic; - cntlr.bbar = &ich7_spi->bbar; - cntlr.preop = &ich7_spi->preop; - cntlr.fpr = &ich7_spi->pbr[0]; - cntlr.fpr_max = 3; - } else { - ich9_spi = get_spi_bar(dev); - cntlr.ich9_spi = ich9_spi; - hsfs = readw_(&ich9_spi->hsfs); - cntlr.hsfs = hsfs; - cntlr.opmenu = ich9_spi->opmenu; - cntlr.menubytes = sizeof(ich9_spi->opmenu); - cntlr.optype = &ich9_spi->optype; - cntlr.addr = &ich9_spi->faddr; - cntlr.data = (UINT8 *)ich9_spi->fdata; - cntlr.databytes = sizeof(ich9_spi->fdata); - cntlr.status = &ich9_spi->ssfs; - cntlr.control = (UINT16 *)ich9_spi->ssfc; - cntlr.bbar = &ich9_spi->bbar; - cntlr.preop = &ich9_spi->preop; - cntlr.fpr = &ich9_spi->pr[0]; - cntlr.fpr_max = 5; - - if (cntlr.hsfs & HSFS_FDV) { - writel_(4, &ich9_spi->fdoc); - cntlr.flmap0 = readl_(&ich9_spi->fdod); - writel_(0x1000, &ich9_spi->fdoc); - cntlr.flcomp = readl_(&ich9_spi->fdod); - } - DEBUG((EFI_D_INFO, "------\n" - "%a SETTING UP CONTROLLER\n" - "SOUTHBRIDGE_INTEL_I82801GX: 0x%X\n" - "ich7_spi: 0x%X\n" - "ich9_spi: 0x%X\n" - "hsfs: 0x%X\n" - "opmenu: 0x%X\n" - "menubytes: 0x%X\n" - "optype: 0x%X\n" - "addr: 0x%X\n" - "data: 0x%X\n" - "databytes: 0x%X\n" - "status: 0x%X\n" - "control: 0x%X\n" - "bbar: 0x%X\n" - "preop: 0x%X\n" - "fpr: 0x%X\n" - "fpr_max: 0x%X\n" - "------\n\n\n\n\n\n\n\n\n********\n", - __FUNCTION__, cntlr.ich7_spi, cntlr.ich9_spi, cntlr.hsfs, cntlr.opmenu, - cntlr.menubytes, cntlr.optype, cntlr.addr, cntlr.data, cntlr.databytes, - cntlr.status, cntlr.control, cntlr.bbar, cntlr.preop, cntlr.fpr, - cntlr.fpr_max)); - } - - ich_set_bbar(0); - - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX) || CONFIG(SOUTHBRIDGE_INTEL_COMMON_SPI_ICH9)) { - /* Disable the BIOS write protect so write commands are allowed. */ - bios_cntl = pci_read_config8(dev, 0xdc); - /* Deassert SMM BIOS Write Protect Disable. */ - bios_cntl &= ~(1 << 5); - pci_write_config8(dev, 0xdc, bios_cntl | 0x1); - } -} - -static INT32 spi_locked(VOID) -{ - if (CONFIG(SOUTHBRIDGE_INTEL_I82801GX)) { - return !!(readw_(&cntlr.ich7_spi->spis) & HSFS_FLOCKDN); - } else { - return !!(readw_(&cntlr.ich9_spi->hsfs) & HSFS_FLOCKDN); - } -} - -static VOID spi_init_cb(VOID *unused) -{ - spi_init(); -} - -BOOT_STATE_INIT_ENTRY(BS_DEV_INIT, BS_ON_ENTRY, spi_init_cb, NULL); - -typedef struct spi_transaction { - CONST UINT8 *out; - UINT32 bytesout; - UINT8 *in; - UINT32 bytesin; - UINT8 type; - UINT8 opcode; - UINT32 offset; -} spi_transaction; - -static inline VOID spi_use_out(spi_transaction *trans, UINT32 bytes) -{ - trans->out += bytes; - trans->bytesout -= bytes; -} - -static inline VOID spi_use_in(spi_transaction *trans, UINT32 bytes) -{ - trans->in += bytes; - trans->bytesin -= bytes; -} - -static VOID spi_setup_type(spi_transaction *trans) -{ - trans->type = 0xFF; - - /* Try to guess spi type from read/write sizes. */ - if (trans->bytesin == 0) { - if (trans->bytesout > 4) - /* - * If bytesin = 0 and bytesout > 4, we presume this is - * a write data operation, which is accompanied by an - * address. - */ - trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS; - else - trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS; - return; - } - - if (trans->bytesout == 1) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS; - return; - } - - if (trans->bytesout == 4) { /* and bytesin is > 0 */ - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - } - - /* Fast read command is called with 5 bytes instead of 4 */ - if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) { - trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS; - --trans->bytesout; - } -} - -static INT32 spi_setup_opcode(spi_transaction *trans) -{ - UINT16 optypes; - UINT8 opmenu[MENU_BYTES]; - - trans->opcode = trans->out[0]; - spi_use_out(trans, 1); - if (!spi_locked()) { - /* The lock is off, so just use index 0. */ - writeb_(trans->opcode, cntlr.opmenu); - optypes = readw_(cntlr.optype); - optypes = (optypes & 0xfffc) | (trans->type & 0x3); - writew_(optypes, cntlr.optype); - return 0; - } - - /* The lock is on. See if what we need is on the menu. */ - UINT8 optype; - UINT16 opcode_index; - - /* Write Enable is handled as atomic prefix */ - if (trans->opcode == SPI_OPCODE_WREN) - return 0; - - read_reg(cntlr.opmenu, opmenu, sizeof(opmenu)); - for (opcode_index = 0; opcode_index < ARRAY_SIZE(opmenu); opcode_index++) { - if (opmenu[opcode_index] == trans->opcode) - break; - } - - if (opcode_index == ARRAY_SIZE(opmenu)) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Opcode %x not found\n", - __FUNCTION__, trans->opcode)); - return -1; - } - - optypes = readw_(cntlr.optype); - optype = (optypes >> (opcode_index * 2)) & 0x3; - if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS && - optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS && - trans->bytesout >= 3) { - /* We guessed wrong earlier. Fix it up. */ - trans->type = optype; - } - if (optype != trans->type) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Transaction doesn't fit type %d\n", - __FUNCTION__, optype)); - return -1; - } - return opcode_index; -} - -static INT32 spi_setup_offset(spi_transaction *trans) -{ - /* Separate the SPI address and data. */ - switch (trans->type) { - case SPI_OPCODE_TYPE_READ_NO_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS: - return 0; - case SPI_OPCODE_TYPE_READ_WITH_ADDRESS: - case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS: - trans->offset = ((UINT32)trans->out[0] << 16) | - ((UINT32)trans->out[1] << 8) | - ((UINT32)trans->out[2] << 0); - spi_use_out(trans, 3); - return 1; - default: - DEBUG((EFI_D_INFO, "%a Unrecognized SPI transaction type %#x\n", __FUNCTION__, trans->type)); - return -1; - } -} - -/* - * Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set - * below is True) or 0. In case the wait was for the bit(s) to set - write - * those bits back, which would cause resetting them. - * - * Return the last read status value on success or -1 on failure. - */ -static INT32 ich_status_poll(UINT16 bitmask, INT32 wait_til_set) -{ - INT32 timeout = 600000; /* This will result in 6 seconds */ - UINT16 status = 0; - - while (timeout--) { - status = readw_(cntlr.status); - if (wait_til_set ^ ((status & bitmask) == 0)) { - if (wait_til_set) - writew_((status & bitmask), cntlr.status); - return status; - } - udelay(10); - } - - DEBUG((EFI_D_INFO, "%a ICH SPI: SCIP timeout, read %x, bitmask %x\n", - __FUNCTION__, status, bitmask)); - return -1; -} - -static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) -{ - UINT16 control; - INT16 opcode_index; - INT32 with_address; - INT32 status; - - spi_transaction trans = { - dout, bytesout, - din, bytesin, - 0xff, 0xff, 0 - }; - - /* There has to always at least be an opcode. */ - if (!bytesout || !dout) { - DEBUG((EFI_D_INFO, "%a ICH SPI: No opcode for transfer\n", __FUNCTION__)); - return -1; - } - /* Make sure if we read something we have a place to put it. */ - if (bytesin != 0 && !din) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Read but no target buffer\n", __FUNCTION__)); - return -1; - } - - if (ich_status_poll(SPIS_SCIP, 0) == -1) - return -1; - - writew_(SPIS_CDS | SPIS_FCERR, cntlr.status); - - spi_setup_type(&trans); - if ((opcode_index = spi_setup_opcode(&trans)) < 0) - return -1; - if ((with_address = spi_setup_offset(&trans)) < 0) - return -1; - - if (trans.opcode == SPI_OPCODE_WREN) { - /* - * Treat Write Enable as Atomic Pre-Op if possible - * in order to prevent the Management Engine from - * issuing a transaction between WREN and DATA. - */ - if (!spi_locked()) - writew_(trans.opcode, cntlr.preop); - return 0; - } - - /* Preset control fields */ - control = SPIC_SCGO | ((opcode_index & 0x07) << 4); - - /* Issue atomic preop cycle if needed */ - if (readw_(cntlr.preop)) - control |= SPIC_ACS; - - if (!trans.bytesout && !trans.bytesin) { - /* SPI addresses are 24 bit only */ - if (with_address) - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - /* - * This is a 'no data' command (like Write Enable), its - * bitesout size was 1, decremented to zero while executing - * spi_setup_opcode() above. Tell the chip to send the - * command. - */ - writew_(control, cntlr.control); - - /* wait for the result */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Command transaction error\n", __FUNCTION__)); - return -1; - } - - goto spi_xfer_exit; - } - - DEBUG((EFI_D_INFO, "---\n%a\ntrans.bytesout: 0x%X\ncntlr.bytesout: 0x%X\n---\n", - __FUNCTION__, trans.bytesout, cntlr.databytes)); - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands, and this sequence is controlled - * by the SPI chip driver. - */ - if (trans.bytesout > cntlr.databytes) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Too much to write. Does your SPI chip driver use" - " spi_crop_chunk()?\n", __FUNCTION__)); - return -1; - } - - /* - * Read or write up to databytes bytes at a time until everything has - * been sent. - */ - while (trans.bytesout || trans.bytesin) { - UINT32 data_length; - - /* SPI addresses are 24 bit only */ - writel_(trans.offset & 0x00FFFFFF, cntlr.addr); - - if (trans.bytesout) - data_length = MIN(trans.bytesout, cntlr.databytes); - else - data_length = MIN(trans.bytesin, cntlr.databytes); - - /* Program data into FDATA0 to N */ - if (trans.bytesout) { - write_reg(trans.out, cntlr.data, data_length); - spi_use_out(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - - /* Add proper control fields' values */ - control &= ~((cntlr.databytes - 1) << 8); - control |= SPIC_DS; - control |= (data_length - 1) << 8; - - /* write it */ - writew_(control, cntlr.control); - - /* Wait for Cycle Done Status or Flash Cycle Error. */ - status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1); - if (status == -1) - return -1; - - if (status & SPIS_FCERR) { - DEBUG((EFI_D_INFO, "%a ICH SPI: Data transaction error\n", __FUNCTION__)); - return -1; - } - - if (trans.bytesin) { - read_reg(cntlr.data, trans.in, data_length); - spi_use_in(&trans, data_length); - if (with_address) - trans.offset += data_length; - } - } - -spi_xfer_exit: - /* Clear atomic preop now that xfer is done */ - writew_(0, cntlr.preop); - - return 0; -} - -static int do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout, - __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) -{ - int ret; - /* - * SPI flash requires command-response kind of behavior. Thus, two - * separate SPI vectors are required -- first to transmit dout and other - * to receive in din. If some specialized SPI flash controllers - * (e.g. x86) can perform both command and response together, it should - * be handled at SPI flash controller driver level. - */ - struct spi_op vectors[] = { - [0] = { .dout = dout, .bytesout = bytes_out, - .din = NULL, .bytesin = 0, }, - [1] = { .dout = NULL, .bytesout = 0, - .din = din, .bytesin = bytes_in }, - }; - __SIZE_TYPE__ count = ARRAY_SIZE(vectors); - if (!bytes_in) - count = 1; - - ret = spi_claim_bus(spi); - if (ret) - return ret; - - ret = spi_xfer_vector(spi, vectors, count); - - spi_release_bus(spi); - return ret; -} - -int spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) -{ - int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); - if (ret) - DEBUG((EFI_D_INFO, "%a SF: Failed to send command %02x: %d\n", - __FUNCTION__, cmd, ret)); - - return ret; -} - -/* M25Pxx-specific commands */ -#define CMD_M25PXX_WREN 0x06 /* Write Enable */ -#define CMD_M25PXX_WRDI 0x04 /* Write Disable */ -#define CMD_M25PXX_RDSR 0x05 /* Read Status Register */ -#define CMD_M25PXX_WRSR 0x01 /* Write Status Register */ -#define CMD_M25PXX_READ 0x03 /* Read Data Bytes */ -#define CMD_M25PXX_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ -#define CMD_M25PXX_PP 0x02 /* Page Program */ -#define CMD_M25PXX_SSE 0x20 /* Subsector Erase */ -#define CMD_M25PXX_SE 0xd8 /* Sector Erase */ -#define CMD_M25PXX_BE 0xc7 /* Bulk Erase */ -#define CMD_M25PXX_DP 0xb9 /* Deep Power-down */ -#define CMD_M25PXX_RES 0xab /* Release from DP, and Read Signature */ - -int stmicro_release_deep_sleep_identify(CONST struct spi_slave *spi, UINT8 *idcode) -{ - if (spi_flash_cmd(spi, CMD_M25PXX_RES, idcode, 4)) - return -1; - - /* Assuming ST parts identify with 0x1X to release from deep - power down and read electronic signature. */ - if ((idcode[3] & 0xf0) != 0x10) - return -1; - - /* Fix up the idcode to mimic rdid jedec instruction. */ - idcode[0] = 0x20; - idcode[1] = 0x20; - idcode[2] = idcode[3] + 1; - - return 0; -} - -static CONST struct spi_flash_vendor_info *spi_flash_vendors[] = { -#if CONFIG(SPI_FLASH_ADESTO) - &spi_flash_adesto_vi, -#endif -#if CONFIG(SPI_FLASH_AMIC) - &spi_flash_amic_vi, -#endif -#if CONFIG(SPI_FLASH_ATMEL) - &spi_flash_atmel_vi, -#endif -#if CONFIG(SPI_FLASH_EON) - &spi_flash_eon_vi, -#endif -#if CONFIG(SPI_FLASH_GIGADEVICE) - &spi_flash_gigadevice_vi, -#endif -#if CONFIG(SPI_FLASH_MACRONIX) - &spi_flash_macronix_vi, -#endif -#if CONFIG(SPI_FLASH_SPANSION) - &spi_flash_spansion_ext1_vi, - &spi_flash_spansion_ext2_vi, - &spi_flash_spansion_vi, -#endif -#if CONFIG(SPI_FLASH_SST) - &spi_flash_sst_ai_vi, - &spi_flash_sst_vi, -#endif -#if CONFIG(SPI_FLASH_STMICRO) - &spi_flash_stmicro1_vi, - &spi_flash_stmicro2_vi, - &spi_flash_stmicro3_vi, - &spi_flash_stmicro4_vi, -#endif -#if CONFIG(SPI_FLASH_WINBOND) - &spi_flash_winbond_vi, -#endif -}; - -static CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, - UINT16 id[2]) -{ - __SIZE_TYPE__ i; - CONST UINT16 lid[2] = { - [0] = id[0] & vi->match_id_mask[0], - [1] = id[1] & vi->match_id_mask[1], - }; - - - for (i = 0; i < vi->nr_part_ids; i++) { - CONST struct spi_flash_part_id *part = &vi->ids[i]; - - if (part->id[0] == lid[0] && part->id[1] == lid[1]) - return part; - } - - return NULL; -} - -VOID *memcpy (VOID *destination, CONST VOID *source, __SIZE_TYPE__ num ) { - for(__SIZE_TYPE__ index = 0; index < num; ++index) { - ((char *)destination)[index] = ((char *)source)[index]; - } - return destination; -} - -static int fill_spi_flash(CONST struct spi_slave *spi, struct spi_flash *flash, - CONST struct spi_flash_vendor_info *vi, - CONST struct spi_flash_part_id *part) -{ - memcpy(&flash->spi, spi, sizeof(*spi)); - flash->vendor = vi->id; - flash->model = part->id[0]; - - flash->page_size = 1U << vi->page_size_shift; - flash->sector_size = (1U << vi->sector_size_kib_shift) * KiB; - flash->size = flash->sector_size * (1U << part->nr_sectors_shift); - flash->erase_cmd = vi->desc->erase_cmd; - flash->status_cmd = vi->desc->status_cmd; - flash->pp_cmd = vi->desc->pp_cmd; - flash->wren_cmd = vi->desc->wren_cmd; - - flash->flags.dual_spi = part->fast_read_dual_output_support; - - flash->ops = &vi->desc->ops; - flash->prot_ops = vi->prot_ops; - flash->part = part; - - if (vi->after_probe) - return vi->after_probe(flash); - - return 0; -} - -static int find_match(CONST struct spi_slave *spi, struct spi_flash *flash, - UINT8 manuf_id, UINT16 id[2]) -{ - int i; - - for (i = 0; i < (int)ARRAY_SIZE(spi_flash_vendors); i++) { - CONST struct spi_flash_vendor_info *vi; - CONST struct spi_flash_part_id *part; - - vi = spi_flash_vendors[i]; - - if (manuf_id != vi->id) - continue; - - part = find_part(vi, id); - - if (part == NULL) - continue; - - return fill_spi_flash(spi, flash, vi, part); - } - - return -1; -} - -INT64 spi_flash_generic_probe(CONST struct spi_slave *spi, - struct spi_flash *flash) -{ - INT64 ret, i; - UINT8 idcode[IDCODE_LEN]; - UINT8 manuf_id; - UINT16 id[2]; - - /* Read the ID codes */ - ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); - if (ret) - return -1; - - if (CONFIG(DEBUG_SPI_FLASH)) { - DEBUG((EFI_D_INFO, "%a SF: Got idcode: ", __FUNCTION__)); - for (i = 0; i < sizeof(idcode); i++) - DEBUG((EFI_D_INFO, "%a %02x ", __FUNCTION__, idcode[i])); - DEBUG((EFI_D_INFO, "%a \n", __FUNCTION__)); - } - - manuf_id = idcode[0]; - - DEBUG((EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); - - /* If no result from RDID command and STMicro parts are enabled attempt - to wake the part from deep sleep and obtain alternative id info. */ - if (CONFIG(SPI_FLASH_STMICRO) && manuf_id == 0xff) { - if (stmicro_release_deep_sleep_identify(spi, idcode)) - return -1; - manuf_id = idcode[0]; - } - - id[0] = (idcode[1] << 8) | idcode[2]; - id[1] = (idcode[3] << 8) | idcode[4]; - - return find_match(spi, flash, manuf_id, id); -} - -INT64 spi_flash_vector_helper(CONST struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(CONST struct spi_slave *slave, CONST VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) -{ - INT64 ret; - VOID *din; - __SIZE_TYPE__ bytes_in; - - if (count < 1 || count > 2) - return -1; - - /* SPI flash commands always have a command first... */ - if (!vectors[0].dout || !vectors[0].bytesout) - return -1; - /* And not read any data during the command. */ - if (vectors[0].din || vectors[0].bytesin) - return -1; - - if (count == 2) { - /* If response bytes requested ensure the buffer is valid. */ - if (vectors[1].bytesin && !vectors[1].din) - return -1; - /* No sends can accompany a receive. */ - if (vectors[1].dout || vectors[1].bytesout) - return -1; - din = vectors[1].din; - bytes_in = vectors[1].bytesin; - } else { - din = NULL; - bytes_in = 0; - } - - ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); - - if (ret) { - vectors[0].status = SPI_OP_FAILURE; - if (count == 2) - vectors[1].status = SPI_OP_FAILURE; - } else { - vectors[0].status = SPI_OP_SUCCESS; - if (count == 2) - vectors[1].status = SPI_OP_SUCCESS; - } - - return ret; -} - -#define SPI_FPR_SHIFT 12 -#define ICH7_SPI_FPR_MASK 0xfff -#define ICH9_SPI_FPR_MASK 0x1fff -#define SPI_FPR_BASE_SHIFT 0 -#define ICH7_SPI_FPR_LIMIT_SHIFT 12 -#define ICH9_SPI_FPR_LIMIT_SHIFT 16 -#define ICH9_SPI_FPR_RPE (1 << 15) /* Read Protect */ -#define SPI_FPR_WPE (1 << 31) /* Write Protect */ - -static inline __SIZE_TYPE__ region_offset(CONST struct region *r) -{ - return r->offset; -} - -static inline __SIZE_TYPE__ region_sz(CONST struct region *r) -{ - return r->size; -} - -static struct spi_flash spi_flash_info; -static BOOLEAN spi_flash_init_done; - -int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash) -{ - struct spi_slave spi; - int ret = -1; - - if (spi_setup_slave(bus, cs, &spi)) { - DEBUG((EFI_D_INFO, "%a SF: Failed to set up slave\n", __FUNCTION__)); - return -1; - } - - /* Try special programmer probe if any. */ - if (spi.ctrlr->flash_probe) - ret = spi.ctrlr->flash_probe(&spi, flash); - - /* If flash is not found, try generic spi flash probe. */ - if (ret) - ret = spi_flash_generic_probe(&spi, flash); - - /* Give up -- nothing more to try if flash is not found. */ - if (ret) { - DEBUG((EFI_D_INFO, "%a SF: Unsupported manufacturer!\n", __FUNCTION__)); - return -1; - } - - #define CONFIG_BOOT_DEVICE_SPI_FLASH_BUS 0 - #define CONFIG_ROM_SIZE 8196 - - CONST char *mode_string = ""; - if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) - mode_string = " (Dual SPI mode)"; - DEBUG((EFI_D_INFO, - "%a SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", - __FUNCTION__, flash->vendor, flash->model, - flash->sector_size, flash->size, mode_string)); - if (bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS - && flash->size != CONFIG_ROM_SIZE) { - DEBUG((EFI_D_INFO, "%a SF size 0x%x does not correspond to" - " CONFIG_ROM_SIZE 0x%x!!\n", __FUNCTION__, flash->size, - CONFIG_ROM_SIZE)); - } - return 0; -} - -struct mem_pool { - UINT8 *buf; - __SIZE_TYPE__ size; - UINT8 *last_alloc; - __SIZE_TYPE__ free_offset; -}; - -#define MEM_POOL_INIT(buf_, size_) \ - { \ - .buf = (buf_), \ - .size = (size_), \ - .last_alloc = NULL, \ - .free_offset = 0, \ - } - -static inline VOID mem_pool_reset(struct mem_pool *mp) -{ - mp->last_alloc = NULL; - mp->free_offset = 0; -} - -/* Initialize a memory pool. */ -static inline VOID mem_pool_init(struct mem_pool *mp, VOID *buf, __SIZE_TYPE__ sz) -{ - mp->buf = buf; - mp->size = sz; - mem_pool_reset(mp); -} - -/* A region_device operations. */ -struct region_device; -struct region_device_ops { - VOID *(*mmap)(CONST struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); - int (*munmap)(CONST struct region_device *, VOID *); - __SIZE_TYPE__ (*readat)(CONST struct region_device *, VOID *, __SIZE_TYPE__, __SIZE_TYPE__); - __SIZE_TYPE__ (*writeat)(CONST struct region_device *, CONST VOID *, __SIZE_TYPE__, - __SIZE_TYPE__); - __SIZE_TYPE__ (*eraseat)(CONST struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); -}; - -struct region_device { - CONST struct region_device *root; - CONST struct region_device_ops *ops; - struct region region; -}; - -struct mmap_helper_region_device { - struct mem_pool pool; - struct region_device rdev; -}; - -#define container_of(ptr, type, member) ({ \ - CONST __typeof__(((type *)0)->member) *__mptr = (ptr); \ - (type *)((char *)__mptr - offsetof(type, member)); }) - -VOID mem_pool_free(struct mem_pool *mp, VOID *p) -{ - /* Determine if p was the most recent allocation. */ - if (p == NULL || mp->last_alloc != p) - return; - - mp->free_offset = mp->last_alloc - mp->buf; - /* No way to track allocation before this one. */ - mp->last_alloc = NULL; -} - -VOID mmap_helper_device_init(struct mmap_helper_region_device *mdev, - VOID *cache, __SIZE_TYPE__ cache_size) -{ - mem_pool_init(&mdev->pool, cache, cache_size); -} - -VOID *mem_pool_alloc(struct mem_pool *mp, __SIZE_TYPE__ sz) -{ - VOID *p; - - /* Make all allocations be at least 8 byte aligned. */ - sz = ALIGN_UP(sz, 8); - - /* Determine if any space available. */ - if ((mp->size - mp->free_offset) < sz) - return NULL; - - p = &mp->buf[mp->free_offset]; - - mp->free_offset += sz; - mp->last_alloc = p; - - return p; -} - -VOID *mmap_helper_rdev_mmap(CONST struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - struct mmap_helper_region_device *mdev; - VOID *mapping; - - mdev = container_of((VOID *)rd, __typeof__(*mdev), rdev); - - mapping = mem_pool_alloc(&mdev->pool, size); - - if (mapping == NULL) - return NULL; - - if (rd->ops->readat(rd, mapping, offset, size) != size) { - mem_pool_free(&mdev->pool, mapping); - return NULL; - } - - return mapping; -} - -int mmap_helper_rdev_munmap(CONST struct region_device *rd, VOID *mapping) -{ - struct mmap_helper_region_device *mdev; - - mdev = container_of((VOID *)rd, __typeof__(*mdev), rdev); - - mem_pool_free(&mdev->pool, mapping); - - return 0; -} - -static UINT32 volatile_group_count; - -int spi_flash_volatile_group_begin(const struct spi_flash *flash) -{ - UINT32 count; - int ret = 0; - - if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) - return ret; - - count = volatile_group_count; - if (count == 0) - ret = 0; - - count++; - volatile_group_count = count; - return ret; -} - -int spi_flash_volatile_group_end(const struct spi_flash *flash) -{ - UINT32 count; - int ret = 0; - - if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) - return ret; - - count = volatile_group_count; - //assert(count == 0); - count--; - volatile_group_count = count; - - if (count == 0) - ret = 0; - //ret = chipset_volatile_group_end(flash); - - return ret; -} - -int spi_flash_write(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - CONST VOID *buf) -{ - int ret; - - if (spi_flash_volatile_group_begin(flash)) - return -1; - - ret = flash->ops->write(flash, offset, len, buf); - - if (spi_flash_volatile_group_end(flash)) - return -1; - - return ret; -} - -int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - void *buf) -{ - return flash->ops->read(flash, offset, len, buf); -} - -int spi_flash_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) -{ - int ret; - - if (spi_flash_volatile_group_begin(flash)) - return -1; - - ret = flash->ops->erase(flash, offset, len); - - if (spi_flash_volatile_group_end(flash)) - return -1; - - return ret; -} - -static struct spi_flash sfg; - -static __SIZE_TYPE__ spi_writeat(CONST struct region_device *rd, CONST VOID *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - if (spi_flash_write(&sfg, offset, size, b)) - return -1; - - return size; -} - -static __SIZE_TYPE__ spi_readat(CONST struct region_device *rd, VOID *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - if (spi_flash_read(&sfg, offset, size, b)) - return -1; - - return size; -} - -static __SIZE_TYPE__ spi_eraseat(CONST struct region_device *rd, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - if (spi_flash_erase(&sfg, offset, size)) - return -1; - - return size; -} - -/* Provide all operations on the same device. */ -static CONST struct region_device_ops spi_ops = { - .mmap = mmap_helper_rdev_mmap, - .munmap = mmap_helper_rdev_munmap, - .readat = spi_readat, - .writeat = spi_writeat, - .eraseat = spi_eraseat, -}; - -#define REGION_DEV_INIT(ops_, offset_, size_) \ - { \ - .root = NULL, \ - .ops = (ops_), \ - .region = { \ - .offset = (offset_), \ - .size = (size_), \ - }, \ - } - -#define MMAP_HELPER_REGION_INIT(ops_, offset_, size_) \ - { \ - .rdev = REGION_DEV_INIT((ops_), (offset_), (size_)), \ - } - -#define REGION_SIZE(name) (_e##name - _##name) - -#define DECLARE_REGION(name) \ - extern UINT8 _##name[]; \ - extern UINT8 _e##name[]; - -/* - * Regions can be declared optional if not all configurations provide them in - * memlayout and you want code to be able to check for their existence at - * runtime. Not every region that is architecture or platform-specific should - * use this -- only declare regions optional if the code *accessing* them runs - * both on configurations that have the region and those that don't. That code - * should then check (REGION_SIZE(name) != 0) before accessing it. - */ -#define DECLARE_OPTIONAL_REGION(name) \ - __attribute__((__weak__)) extern UINT8 _##name[]; \ - __attribute__((__weak__)) extern UINT8 _e##name[]; - -DECLARE_REGION(sram) -DECLARE_OPTIONAL_REGION(timestamp) -DECLARE_REGION(preram_cbmem_console) -DECLARE_REGION(cbmem_init_hooks) -DECLARE_REGION(stack) -DECLARE_REGION(preram_cbfs_cache) -DECLARE_REGION(postram_cbfs_cache) -DECLARE_REGION(cbfs_cache) -DECLARE_REGION(fmap_cache) -DECLARE_REGION(tpm_tcpa_log) - -static struct mmap_helper_region_device mdev = - MMAP_HELPER_REGION_INIT(&spi_ops, 0, CONFIG_ROM_SIZE); - -VOID boot_device_init(VOID) -{ - int bus = CONFIG_BOOT_DEVICE_SPI_FLASH_BUS; - int cs = 0; - - if (spi_flash_init_done == TRUE) - return; - - if (spi_flash_probe(bus, cs, &spi_flash_info)) - return; - - spi_flash_init_done = TRUE; - - mmap_helper_device_init(&mdev, _cbfs_cache, REGION_SIZE(cbfs_cache)); -} - -CONST struct spi_flash *boot_device_spi_flash(VOID) -{ - boot_device_init(); - - if (spi_flash_init_done != TRUE) - return NULL; - - return &spi_flash_info; -} - -__attribute__((__weak__)) -VOID intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config) -{ -} - -VOID spi_finalize_ops(VOID) -{ - UINT16 spi_opprefix; - UINT16 optype = 0; - struct intel_swseq_spi_config spi_config_default = { - {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ - { /* OPCODE and OPTYPE */ - {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ - {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ - {0x03, READ_WITH_ADDR}, /* READ: Read Data */ - {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ - {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ - {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ - {0xd8, WRITE_WITH_ADDR}, /* BED8: Block Erase 0xd8 */ - {0x0b, READ_WITH_ADDR}, /* FAST: Fast Read */ - } - }; - struct intel_swseq_spi_config spi_config_aai_write = { - {0x06, 0x50}, /* OPPREFIXES: EWSR and WREN */ - { /* OPCODE and OPTYPE */ - {0x01, WRITE_NO_ADDR}, /* WRSR: Write Status Register */ - {0x02, WRITE_WITH_ADDR}, /* BYPR: Byte Program */ - {0x03, READ_WITH_ADDR}, /* READ: Read Data */ - {0x05, READ_NO_ADDR}, /* RDSR: Read Status Register */ - {0x20, WRITE_WITH_ADDR}, /* SE20: Sector Erase 0x20 */ - {0x9f, READ_NO_ADDR}, /* RDID: Read ID */ - {0xad, WRITE_NO_ADDR}, /* Auto Address Increment Word Program */ - {0x04, WRITE_NO_ADDR} /* Write Disable */ - } - }; - CONST struct spi_flash *flash = boot_device_spi_flash(); - struct intel_swseq_spi_config *spi_config = &spi_config_default; - INT32 i; - - /* - * Some older SST SPI flashes support AAI write but use 0xaf opcde for - * that. Flashrom uses the byte program opcode to write those flashes, - * so this configuration is fine too. SST25VF064C (id = 0x4b) is an - * exception. - */ - if (flash && flash->vendor == VENDOR_ID_SST && (flash->model & 0x00ff) != 0x4b) - spi_config = &spi_config_aai_write; - - if (spi_locked()) - return; - - intel_southbridge_override_spi(spi_config); - - spi_opprefix = spi_config->opprefixes[0] - | (spi_config->opprefixes[1] << 8); - writew_(spi_opprefix, cntlr.preop); - for (i = 0; i < ARRAY_SIZE(spi_config->ops); i++) { - optype |= (spi_config->ops[i].type & 3) << (i * 2); - writeb_(spi_config->ops[i].op, &cntlr.opmenu[i]); - } - writew_(optype, cntlr.optype); -} - - -/*----------------------------------------------------------------------- - * Representation of a SPI controller. Note the xfer() and xfer_vector() - * callbacks are meant to process full duplex transactions. If the - * controller cannot handle these transactions then return an error when - * din and dout are both set. See spi_xfer() below for more details. - * - * claim_bus: Claim SPI bus and prepare for communication. - * release_bus: Release SPI bus. - * setup: Setup given SPI device bus. - * xfer: Perform one SPI transfer operation. - * xfer_vector: Vector of SPI transfer operations. - * xfer_dual: (optional) Perform one SPI transfer in Dual SPI mode. - * max_xfer_size: Maximum transfer size supported by the controller - * (0 = invalid, - * SPI_CTRLR_DEFAULT_MAX_XFER_SIZE = unlimited) - * flags: See SPI_CNTRLR_* enums above. - * - * Following member is provided by specialized SPI controllers that are - * actually SPI flash controllers. - * - * flash_probe: Specialized probe function provided by SPI flash - * controllers. - * flash_protect: Protect a region of flash using the SPI flash controller. - */ - -/* -struct spi_ctrlr { - INT32 (*claim_bus)(CONST struct spi_slave *slave); - VOID (*release_bus)(CONST struct spi_slave *slave); - INT32 (*setup)(CONST struct spi_slave *slave); - INT32 (*xfer)(CONST struct spi_slave *slave, CONST VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); - INT32 (*xfer_vector)(CONST struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count); - INT32 (*xfer_dual)(CONST struct spi_slave *slave, CONST VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); - UINT32 max_xfer_size; - UINT32 flags; - INT32 (*flash_probe)(CONST struct spi_slave *slave, - struct spi_flash *flash); - INT32 (*flash_protect)(CONST struct spi_flash *flash, - CONST struct region *region, - CONST enum ctrlr_prot_type type); -}; -*/ - - -static CONST struct spi_ctrlr spi_ctrlr = { - .claim_bus = NULL, - .release_bus = NULL, - .setup = NULL, - .xfer = spi_ctrlr_xfer, - .xfer_vector = NULL, - .xfer_dual = NULL, - .max_xfer_size = 0xFFFFFFFF, - .flags = 0, - .flash_probe = NULL, - .flash_protect = NULL -}; - -CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { - { - .ctrlr = &spi_ctrlr, - .bus_start = 0, - .bus_end = 0, - }, -}; - -CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); diff --git a/UefiPayloadPkg/SPI/intelSPI.h b/UefiPayloadPkg/SPI/intelSPI.h deleted file mode 100644 index 5a0ce838ac3b..000000000000 --- a/UefiPayloadPkg/SPI/intelSPI.h +++ /dev/null @@ -1,10 +0,0 @@ - -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef SOUTHBRIDGE_INTEL_SPI_H -#define SOUTHBRIDGE_INTEL_SPI_H - -void spi_finalize_ops(void); -void intel_southbridge_override_spi(struct intel_swseq_spi_config *spi_config); - -#endif diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c new file mode 100644 index 000000000000..1f986f80b642 --- /dev/null +++ b/UefiPayloadPkg/SPI/lpc.c @@ -0,0 +1,12 @@ +#include + +#include "lpc.h" + +UINT32 *lpc_get_spibase(void) +{ + UINT32 base; + + base = pci_read_config32(_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); + base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); + return (UINT32)base; +} diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h new file mode 100644 index 000000000000..7ba304755913 --- /dev/null +++ b/UefiPayloadPkg/SPI/lpc.h @@ -0,0 +1,22 @@ +#include + +#ifndef BIT +#define BIT(x) (1ul << (x)) +#endif + +#define SPIROM_BASE_ADDRESS_REGISTER 0xa0 +#define SPI_BASE_ALIGNMENT BIT(6) +#define SPI_BASE_RESERVED (BIT(4) | BIT(5)) +#define ROUTE_TPM_2_SPI BIT(3) +#define SPI_ABORT_ENABLE BIT(2) +#define SPI_ROM_ENABLE BIT(1) +#define SPI_ROM_ALT_ENABLE BIT(0) +#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +#if !defined(__SIMPLE_DEVICE__) +#define _LPCB_DEV pcidev_on_root(0x14, 0x3) +#else +#define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) +#endif + +UINT32 *lpc_get_spibase(void); diff --git a/UefiPayloadPkg/SPI/spi_flash.h b/UefiPayloadPkg/SPI/spi_flash.h deleted file mode 100644 index 215ec2e1d717..000000000000 --- a/UefiPayloadPkg/SPI/spi_flash.h +++ /dev/null @@ -1,225 +0,0 @@ -/* Interface to SPI flash */ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef _SPI_FLASH_H_ -#define _SPI_FLASH_H_ - -#include - -/* SPI Flash opcodes */ -#define SPI_OPCODE_WREN 0x06 -#define SPI_OPCODE_FAST_READ 0x0b - -struct spi_flash; - -/* - * SPI write protection is enforced by locking the status register. - * The following modes are known. It depends on the flash chip if the - * mode is actually supported. - * - * PRESERVE : Keep the previous status register lock-down setting (noop) - * NONE : Status register isn't locked - * PIN : Status register is locked as long as the ~WP pin is active - * REBOOT : Status register is locked until power failure - * PERMANENT: Status register is permanently locked - */ -enum spi_flash_status_reg_lockdown { - SPI_WRITE_PROTECTION_PRESERVE = -1, - SPI_WRITE_PROTECTION_NONE = 0, - SPI_WRITE_PROTECTION_PIN, - SPI_WRITE_PROTECTION_REBOOT, - SPI_WRITE_PROTECTION_PERMANENT -}; - -/* - * Representation of SPI flash operations: - * read: Flash read operation. - * write: Flash write operation. - * erase: Flash erase operation. - * status: Read flash status register. - */ -struct spi_flash_ops { - int (*read)(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, - void *buf); - int (*write)(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, - const void *buf); - int (*erase)(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len); - int (*status)(const struct spi_flash *flash, UINT8 *reg); -}; - -/* Current code assumes all callbacks are supplied in this object. */ -struct spi_flash_protection_ops { - /* - * Returns 1 if the whole region is software write protected. - * Hardware write protection mechanism aren't accounted. - * If the write protection could be changed, due to unlocked status - * register for example, 0 should be returned. - * Returns 0 on success. - */ - int (*get_write)(const struct spi_flash *flash, - const struct region *region); - /* - * Enable the status register write protection, if supported on the - * requested region, and optionally enable status register lock-down. - * Returns 0 if the whole region was software write protected. - * Hardware write protection mechanism aren't accounted. - * If the status register is locked and the requested configuration - * doesn't match the selected one, return an error. - * Only a single region is supported ! - * - * @return 0 on success - */ - int - (*set_write)(const struct spi_flash *flash, - const struct region *region, - const enum spi_flash_status_reg_lockdown mode); - -}; - -struct spi_flash_part_id; - -struct spi_flash { - struct spi_slave spi; - UINT8 vendor; - union { - UINT8 raw; - struct { - UINT8 dual_spi : 1; - UINT8 _reserved : 7; - }; - } flags; - u16 model; - UINT32 size; - UINT32 sector_size; - UINT32 page_size; - UINT8 erase_cmd; - UINT8 status_cmd; - UINT8 pp_cmd; /* Page program command. */ - UINT8 wren_cmd; /* Write Enable command. */ - const struct spi_flash_ops *ops; - /* If !NULL all protection callbacks exist. */ - const struct spi_flash_protection_ops *prot_ops; - const struct spi_flash_part_id *part; -}; - -void lb_spi_flash(struct lb_header *header); - -/* SPI Flash Driver Public API */ - -/* - * Probe for SPI flash chip on given SPI bus and chip select and fill info in - * spi_flash structure. - * - * Params: - * bus = SPI Bus # for the flash chip - * cs = Chip select # for the flash chip - * flash = Pointer to spi flash structure that needs to be filled - * - * Return value: - * 0 = success - * non-zero = error - */ -int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash); - -/* - * Generic probing for SPI flash chip based on the different flashes provided. - * - * Params: - * spi = Pointer to spi_slave structure - * flash = Pointer to spi_flash structure that needs to be filled. - * - * Return value: - * 0 = success - * non-zero = error - */ -int spi_flash_generic_probe(const struct spi_slave *slave, - struct spi_flash *flash); - -/* All the following functions return 0 on success and non-zero on error. */ -int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, - void *buf); -int spi_flash_write(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len, - const void *buf); -int spi_flash_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE_ len); -int spi_flash_status(const struct spi_flash *flash, UINT8 *reg); - -/* - * Return the vendor dependent SPI flash write protection state. - * @param flash : A SPI flash device - * @param region: A subregion of the device's region - * - * Returns: - * -1 on error - * 0 if the device doesn't support block protection - * 0 if the device doesn't enable block protection - * 0 if given range isn't covered by block protection - * 1 if given range is covered by block protection - */ -int spi_flash_is_write_protected(const struct spi_flash *flash, - const struct region *region); -/* - * Enable the vendor dependent SPI flash write protection. The region not - * covered by write-protection will be set to write-able state. - * Only a single write-protected region is supported. - * Some flash ICs require the region to be aligned in the block size, sector - * size or page size. - * Some flash ICs require the region to start at TOP or BOTTOM. - * - * @param flash : A SPI flash device - * @param region: A subregion of the device's region - * @param mode: Optional lock-down of status register - - * @return 0 on success - */ -int -spi_flash_set_write_protected(const struct spi_flash *flash, - const struct region *region, - const enum spi_flash_status_reg_lockdown mode); - -/* - * Some SPI controllers require exclusive access to SPI flash when volatile - * operations like erase or write are being performed. In such cases, - * volatile_group_begin will gain exclusive access to SPI flash if not already - * acquired and volatile_group_end will end exclusive access if this was the - * last request in the group. spi_flash_{write,erase} operations call - * volatile_group_begin at the start of function and volatile_group_end after - * erase/write operation is performed. These functions can also be used by any - * components that wish to club multiple volatile operations into a single - * group. - */ -int spi_flash_volatile_group_begin(const struct spi_flash *flash); -int spi_flash_volatile_group_end(const struct spi_flash *flash); - -/* - * These are callbacks for marking the start and end of volatile group as - * handled by the chipset. Not every chipset requires this special handling. So, - * these functions are expected to be implemented in Kconfig option for volatile - * group is enabled (SPI_FLASH_HAS_VOLATILE_GROUP). - */ -int chipset_volatile_group_begin(const struct spi_flash *flash); -int chipset_volatile_group_end(const struct spi_flash *flash); - -/* Return spi_flash object reference for the boot device. This is only valid - * if CONFIG(BOOT_DEVICE_SPI_FLASH) is enabled. */ -const struct spi_flash *boot_device_spi_flash(void); - -/* Protect a region of spi flash using its controller, if available. Returns - * < 0 on error, else 0 on success. */ -int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, - const struct region *region, - const enum ctrlr_prot_type type); - -/* - * This function is provided to support spi flash command-response transactions. - * Only 2 vectors are supported and the 'func' is called with appropriate - * write and read buffers together. This can be used for chipsets that - * have specific spi flash controllers that don't conform to the normal - * spi xfer API because they are specialized controllers and not generic. - * - * Returns 0 on success and non-zero on failure. - */ -int spi_flash_vector_helper(const struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE_ count, - int (*func)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE_ bytesout, void *din, __SIZE_TYPE_ bytesin)); - -#endif /* _SPI_FLASH_H_ */ diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h deleted file mode 100644 index 4aed3c60fac2..000000000000 --- a/UefiPayloadPkg/SPI/spi_flash_internal.h +++ /dev/null @@ -1,131 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include "SPI.h" - -/* - * SPI flash internal definitions - */ - -#ifndef SPI_FLASH_INTERNAL_H -#define SPI_FLASH_INTERNAL_H - -/* Common commands */ -#define CMD_READ_ID 0x9f - -#define CMD_READ_ARRAY_SLOW 0x03 -#define CMD_READ_ARRAY_FAST 0x0b -#define CMD_READ_ARRAY_LEGACY 0xe8 - -#define CMD_READ_FAST_DUAL_OUTPUT 0x3b - -#define CMD_READ_STATUS 0x05 -#define CMD_WRITE_ENABLE 0x06 - -#define CMD_BLOCK_ERASE 0xD8 - -/* Common status */ -#define STATUS_WIP 0x01 - -/* Send a single-byte command to the device and read the response */ -int spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); - -/* - * Send a multi-byte command to the device followed by (optional) - * data. Used for programming the flash array, etc. - */ -int spi_flash_cmd_write(CONST struct spi_slave *spi, CONST UINT8 *cmd, - __SIZE_TYPE__ cmd_len, CONST VOID *data, __SIZE_TYPE__ data_len); - -/* Send a command to the device and wait for some bit to clear itself. */ -int spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long timeout, - UINT8 cmd, UINT8 poll_bit); - -/* - * Send the read status command to the device and wait for the wip - * (write-in-progress) bit to clear itself. - */ -int spi_flash_cmd_wait_ready(CONST struct spi_flash *flash, unsigned long timeout); - -/* Erase sectors. */ -int spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - -/* Read status register. */ -int spi_flash_cmd_status(CONST struct spi_flash *flash, UINT8 *reg); - -/* Write to flash utilizing page program semantics. */ -int spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, CONST VOID *buf); - -/* Read len bytes into buf at offset. */ -int spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); - -/* Release from deep sleep an provide alternative rdid information. */ -int stmicro_release_deep_sleep_identify(CONST struct spi_slave *spi, UINT8 *idcode); - -struct spi_flash_part_id { - /* rdid command constructs 2x 16-bit id using the following method - * for matching after reading 5 bytes (1st byte is manuf id): - * id[0] = (id[1] << 8) | id[2] - * id[1] = (id[3] << 8) | id[4] - */ - UINT16 id[2]; - /* Log based 2 total number of sectors. */ - UINT16 nr_sectors_shift: 4; - UINT16 fast_read_dual_output_support : 1; - UINT16 _reserved_for_flags: 3; - /* Block protection. Currently used by Winbond. */ - UINT16 protection_granularity_shift : 5; - UINT16 bp_bits : 3; -}; - -struct spi_flash_ops_descriptor { - UINT8 erase_cmd; /* Sector Erase */ - UINT8 status_cmd; /* Read Status Register */ - UINT8 pp_cmd; /* Page program command, if supported. */ - UINT8 wren_cmd; /* Write Enable command. */ - struct spi_flash_ops ops; -}; - -/* Vendor info represents a common set of organization and commands by a given - * vendor. One can implement multiple sets from a single vendor by having - * separate objects. */ -struct spi_flash_vendor_info { - UINT8 id; - UINT8 page_size_shift : 4; /* if page programming oriented. */ - /* Log based 2 sector size */ - UINT8 sector_size_kib_shift : 4; - UINT16 nr_part_ids; - CONST struct spi_flash_part_id *ids; - UINT16 match_id_mask[2]; /* matching bytes of the id for this set*/ - CONST struct spi_flash_ops_descriptor *desc; - CONST struct spi_flash_protection_ops *prot_ops; - /* Returns 0 on success. !0 otherwise. */ - int (*after_probe)(CONST struct spi_flash *flash); -}; - -/* Manufacturer-specific probe information */ -extern CONST struct spi_flash_vendor_info spi_flash_adesto_vi; -extern CONST struct spi_flash_vendor_info spi_flash_amic_vi; -extern CONST struct spi_flash_vendor_info spi_flash_atmel_vi; -extern CONST struct spi_flash_vendor_info spi_flash_eon_vi; -extern CONST struct spi_flash_vendor_info spi_flash_gigadevice_vi; -extern CONST struct spi_flash_vendor_info spi_flash_macronix_vi; -/* Probing order matters between the spansion sequence. */ -extern CONST struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; -extern CONST struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; -extern CONST struct spi_flash_vendor_info spi_flash_spansion_vi; -extern CONST struct spi_flash_vendor_info spi_flash_sst_ai_vi; -extern CONST struct spi_flash_vendor_info spi_flash_sst_vi; -extern CONST struct spi_flash_vendor_info spi_flash_stmicro1_vi; -extern CONST struct spi_flash_vendor_info spi_flash_stmicro2_vi; -extern CONST struct spi_flash_vendor_info spi_flash_stmicro3_vi; -extern CONST struct spi_flash_vendor_info spi_flash_stmicro4_vi; -extern CONST struct spi_flash_vendor_info spi_flash_winbond_vi; - -/* Page Programming Command Set with 0x20 Sector Erase command. */ -extern CONST struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; -/* Page Programming Command Set with 0xd8 Sector Erase command. */ -extern CONST struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; - -#endif /* SPI_FLASH_INTERNAL_H */ diff --git a/UefiPayloadPkg/SPI/spi_winbond.h b/UefiPayloadPkg/SPI/spi_winbond.h deleted file mode 100644 index cf5e4adbe6c2..000000000000 --- a/UefiPayloadPkg/SPI/spi_winbond.h +++ /dev/null @@ -1,25 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -/* Winbond specific function */ -/* M25Pxx-specific commands */ -#define CMD_W25_WREN 0x06 /* Write Enable */ -#define CMD_W25_WRDI 0x04 /* Write Disable */ -#define CMD_W25_RDSR 0x05 /* Read Status Register */ -#define CMD_W25_WRSR 0x01 /* Write Status Register */ -#define CMD_W25_RDSR2 0x35 /* Read Status2 Register */ -#define CMD_W25_WRSR2 0x31 /* Write Status2 Register */ -#define CMD_W25_READ 0x03 /* Read Data Bytes */ -#define CMD_W25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ -#define CMD_W25_PP 0x02 /* Page Program */ -#define CMD_W25_SE 0x20 /* Sector (4K) Erase */ -#define CMD_W25_RDID 0x9f /* Read ID */ -#define CMD_W25_BE 0xd8 /* Block (64K) Erase */ -#define CMD_W25_CE 0xc7 /* Chip Erase */ -#define CMD_W25_DP 0xb9 /* Deep Power-down */ -#define CMD_W25_RES 0xab /* Release from DP and Read Signature */ -#define CMD_VOLATILE_SREG_WREN 0x50 /* Write Enable for Volatile SREG */ - -/* tw: Maximum time to write a flash cell in milliseconds */ -#define WINBOND_FLASH_TIMEOUT 30 - -CONST struct spi_flash_vendor_info spi_flash_winbond_vi; diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/winbond.c deleted file mode 100644 index b19a3825be26..000000000000 --- a/UefiPayloadPkg/SPI/winbond.c +++ /dev/null @@ -1,588 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include "spi_winbond.h" -#include "spi_flash_internal.h" - -union status_reg1 { - UINT8 u; - struct { - UINT8 busy : 1; - UINT8 wel : 1; - UINT8 bp : 3; - UINT8 tb : 1; - UINT8 sec : 1; - UINT8 srp0 : 1; - } bp3; - struct { - UINT8 busy : 1; - UINT8 wel : 1; - UINT8 bp : 4; - UINT8 tb : 1; - UINT8 srp0 : 1; - } bp4; -}; - -union status_reg2 { - UINT8 u; - struct { - UINT8 srp1 : 1; - UINT8 qe : 1; - UINT8 res : 1; - UINT8 lb : 3; - UINT8 cmp : 1; - UINT8 sus : 1; - }; -}; - -struct status_regs { - union { - struct { -#if defined(__BIG_ENDIAN) - union status_reg2 reg2; - union status_reg1 reg1; -#else - union status_reg1 reg1; - union status_reg2 reg2; -#endif - }; - UINT16 u; - }; -}; - -static CONST struct spi_flash_part_id flash_table[] = { - { - /* W25P80 */ - .id[0] = 0x2014, - .nr_sectors_shift = 8, - }, - { - /* W25P16 */ - .id[0] = 0x2015, - .nr_sectors_shift = 9, - }, - { - /* W25P32 */ - .id[0] = 0x2016, - .nr_sectors_shift = 10, - }, - { - /* W25X80 */ - .id[0] = 0x3014, - .nr_sectors_shift = 8, - .fast_read_dual_output_support = 1, - }, - { - /* W25X16 */ - .id[0] = 0x3015, - .nr_sectors_shift = 9, - .fast_read_dual_output_support = 1, - }, - { - /* W25X32 */ - .id[0] = 0x3016, - .nr_sectors_shift = 10, - .fast_read_dual_output_support = 1, - }, - { - /* W25X64 */ - .id[0] = 0x3017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - }, - { - /* W25Q80_V */ - .id[0] = 0x4014, - .nr_sectors_shift = 8, - .fast_read_dual_output_support = 1, - }, - { - /* W25Q16_V */ - .id[0] = 0x4015, - .nr_sectors_shift = 9, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q16DW */ - .id[0] = 0x6015, - .nr_sectors_shift = 9, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q32_V */ - .id[0] = 0x4016, - .nr_sectors_shift = 10, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q32DW */ - .id[0] = 0x6016, - .nr_sectors_shift = 10, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q64_V */ - .id[0] = 0x4017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 17, - .bp_bits = 3, - }, - { - /* W25Q64DW */ - .id[0] = 0x6017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 17, - .bp_bits = 3, - }, - { - /* W25Q64JW */ - .id[0] = 0x8017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 17, - .bp_bits = 3, - }, - { - /* W25Q128_V */ - .id[0] = 0x4018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q128FW */ - .id[0] = 0x6018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q128J */ - .id[0] = 0x7018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q128JW */ - .id[0] = 0x8018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q256_V */ - .id[0] = 0x4019, - .nr_sectors_shift = 13, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 4, - }, - { - /* W25Q256J */ - .id[0] = 0x7019, - .nr_sectors_shift = 13, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 4, - }, -}; - -/* - * Convert BPx, TB and CMP to a region. - * SEC (if available) must be zero. - */ -static void winbond_bpbits_to_region(CONST __SIZE_TYPE__ granularity, - CONST UINT8 bp, - BOOLEAN tb, - CONST BOOLEAN cmp, - CONST __SIZE_TYPE__ flash_size, - struct region *out) -{ - __SIZE_TYPE__ protected_size = - MIN(bp ? granularity << (bp - 1) : 0, flash_size); - - if (cmp) { - protected_size = flash_size - protected_size; - tb = !tb; - } - - out->offset = tb ? 0 : flash_size - protected_size; - out->size = protected_size; -} - -/* - * Available on all devices. - * Read block protect bits from Status/Status2 Reg. - * Converts block protection bits to a region. - * - * Returns: - * -1 on error - * 1 if region is covered by write protection - * 0 if a part of region isn't covered by write protection - */ -static int winbond_get_write_protection(CONST struct spi_flash *flash, - CONST struct region *region) -{ - CONST struct spi_flash_part_id *params; - struct region wp_region; - union status_reg2 reg2; - UINT8 bp, tb; - int ret; - - params = flash->part; - - if (!params) - return -1; - - CONST __SIZE_TYPE__ granularity = (1 << params->protection_granularity_shift); - - union status_reg1 reg1 = { .u = 0 }; - - ret = spi_flash_cmd(&flash->spi, flash->status_cmd, ®1.u, - sizeof(reg1.u)); - if (ret) - return ret; - - if (params->bp_bits == 3) { - if (reg1.bp3.sec) { - // FIXME: not supported - return -1; - } - - bp = reg1.bp3.bp; - tb = reg1.bp3.tb; - } else if (params->bp_bits == 4) { - bp = reg1.bp4.bp; - tb = reg1.bp4.tb; - } else { - // FIXME: not supported - return -1; - } - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®2.u, - sizeof(reg2.u)); - if (ret) - return ret; - - winbond_bpbits_to_region(granularity, bp, tb, reg2.cmp, flash->size, - &wp_region); - - if (!region_sz(&wp_region)) { - DEBUG((EFI_D_INFO, "%a WINBOND: flash isn't protected\n", __FUNCTION__)); - - return 0; - } - - DEBUG((EFI_D_INFO, "%a WINBOND: flash protected range 0x%08zx-0x%08zx\n", - __FUNCTION__, region_offset(&wp_region), region_end(&wp_region))); - - return region_is_subregion(&wp_region, region); -} - -/** - * Common method to write some bit of the status register 1 & 2 at the same - * time. Only change bits that are one in @mask. - * Compare the final result to make sure that the register isn't locked. - * - * @param mask: The bits that are affected by @val - * @param val: The bits to write - * @param non_volatile: Make setting permanent - * - * @return 0 on success - */ -static int winbond_flash_cmd_status(CONST struct spi_flash *flash, - CONST UINT16 mask, - CONST UINT16 val, - CONST BOOLEAN non_volatile) -{ - struct { - UINT8 cmd; - UINT16 sreg; - } __attribute__((packed)) cmdbuf; - UINT8 reg8; - int ret; - - if (!flash) - return -1; - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg = reg8; - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg |= reg8 << 8; - - if ((val & mask) == (cmdbuf.sreg & mask)) - return 0; - - if (non_volatile) { - ret = spi_flash_cmd(&flash->spi, CMD_W25_WREN, NULL, 0); - } else { - ret = spi_flash_cmd(&flash->spi, CMD_VOLATILE_SREG_WREN, NULL, - 0); - } - if (ret) - return ret; - - cmdbuf.sreg &= ~mask; - cmdbuf.sreg |= val & mask; - cmdbuf.cmd = CMD_W25_WRSR; - - /* Legacy method of writing status register 1 & 2 */ - ret = spi_flash_cmd_write(&flash->spi, (UINT8 *)&cmdbuf, sizeof(cmdbuf), - NULL, 0); - if (ret) - return ret; - - if (non_volatile) { - /* Wait tw */ - ret = spi_flash_cmd_wait_ready(flash, WINBOND_FLASH_TIMEOUT); - if (ret) - return ret; - } else { - /* Wait tSHSL */ - udelay(1); - } - - /* Now read the status register to make sure it's not locked */ - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg = reg8; - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg |= reg8 << 8; - - DEBUG((EFI_D_INFO, "%a WINBOND: SREG=%02x SREG2=%02x\n", - __FUNCTION__, - cmdbuf.sreg & 0xff, - cmdbuf.sreg >> 8)); - - /* Compare against expected result */ - if ((val & mask) != (cmdbuf.sreg & mask)) { - DEBUG((EFI_D_INFO, "%a WINBOND: SREG is locked!\n", __FUNCTION__)); - ret = -1; - } - - return ret; -} - -/* - * SPI write protection is enforced by locking the status register. - * The following modes are known. It depends on the flash chip if the - * mode is actually supported. - * - * PRESERVE : Keep the previous status register lock-down setting (noop) - * NONE : Status register isn't locked - * PIN : Status register is locked as long as the ~WP pin is active - * REBOOT : Status register is locked until power failure - * PERMANENT: Status register is permanently locked - */ -enum spi_flash_status_reg_lockdown { - SPI_WRITE_PROTECTION_PRESERVE = -1, - SPI_WRITE_PROTECTION_NONE = 0, - SPI_WRITE_PROTECTION_PIN, - SPI_WRITE_PROTECTION_REBOOT, - SPI_WRITE_PROTECTION_PERMANENT -}; - -/* - * Available on all devices. - * Protect a region starting from start of flash or end of flash. - * The caller must provide a supported protected region size. - * SEC isn't supported and set to zero. - * Write block protect bits to Status/Status2 Reg. - * Optionally lock the status register if lock_sreg is set with the provided - * mode. - * - * @param flash: The flash to operate on - * @param region: The region to write protect - * @param mode: Optional status register lock-down mode - * - * @return 0 on success - */ -static int -winbond_set_write_protection(CONST struct spi_flash *flash, - CONST struct region *region, - CONST enum spi_flash_status_reg_lockdown mode) -{ - CONST struct spi_flash_part_id *params; - struct status_regs mask, val; - struct region wp_region; - UINT8 cmp, bp, tb; - int ret; - - /* Need to touch TOP or BOTTOM */ - if (region_offset(region) != 0 && region_end(region) != flash->size) - return -1; - - params = flash->part; - - if (!params) - return -1; - - if (params->bp_bits != 3 && params->bp_bits != 4) { - /* FIXME: not implemented */ - return -1; - } - - wp_region = *region; - - if (region_offset(&wp_region) == 0) - tb = 1; - else - tb = 0; - - if (region_sz(&wp_region) > flash->size / 2) { - cmp = 1; - wp_region.offset = tb ? 0 : region_sz(&wp_region); - wp_region.size = flash->size - region_sz(&wp_region); - tb = !tb; - } else { - cmp = 0; - } - - if (region_sz(&wp_region) == 0) { - bp = 0; - } else if (IS_POWER_OF_2(region_sz(&wp_region)) && - (region_sz(&wp_region) >= - (1 << params->protection_granularity_shift))) { - bp = log2(region_sz(&wp_region)) - - params->protection_granularity_shift + 1; - } else { - DEBUG((EFI_D_INFO, "%a WINBOND: ERROR: unsupported region size\n")); - return -1; - } - - /* Write block protection bits */ - - if (params->bp_bits == 3) { - val.reg1 = (union status_reg1) { - .bp3 = { .bp = bp, .tb = tb, .sec = 0 } - }; - mask.reg1 = (union status_reg1) { - .bp3 = { .bp = ~0, .tb = 1, .sec = 1 } - }; - } else { - val.reg1 = (union status_reg1) { - .bp4 = { .bp = bp, .tb = tb } - }; - mask.reg1 = (union status_reg1) { - .bp4 = { .bp = ~0, .tb = 1 } - }; - } - - val.reg2 = (union status_reg2) { .cmp = cmp }; - mask.reg2 = (union status_reg2) { .cmp = 1 }; - - if (mode != SPI_WRITE_PROTECTION_PRESERVE) { - UINT8 srp; - switch (mode) { - case SPI_WRITE_PROTECTION_NONE: - srp = 0; - break; - case SPI_WRITE_PROTECTION_PIN: - srp = 1; - break; - case SPI_WRITE_PROTECTION_REBOOT: - srp = 2; - break; - case SPI_WRITE_PROTECTION_PERMANENT: - srp = 3; - break; - default: - return -1; - } - - if (params->bp_bits == 3) { - val.reg1.bp3.srp0 = !!(srp & 1); - mask.reg1.bp3.srp0 = 1; - } else { - val.reg1.bp4.srp0 = !!(srp & 1); - mask.reg1.bp4.srp0 = 1; - } - - val.reg2.srp1 = !!(srp & 2); - mask.reg2.srp1 = 1; - } - - ret = winbond_flash_cmd_status(flash, mask.u, val.u, TRUE); - if (ret) - return ret; - - DEBUG((EFI_D_INFO, "%a WINBOND: write-protection set to range " - "0x%08zx-0x%08zx\n", __FUNCTION__, - region_offset(region), region_end(region))); - - return ret; -} - -/* Current code assumes all callbacks are supplied in this object. */ -struct spi_flash_protection_ops { - /* - * Returns 1 if the whole region is software write protected. - * Hardware write protection mechanism aren't accounted. - * If the write protection could be changed, due to unlocked status - * register for example, 0 should be returned. - * Returns 0 on success. - */ - int (*get_write)(const struct spi_flash *flash, - const struct region *region); - /* - * Enable the status register write protection, if supported on the - * requested region, and optionally enable status register lock-down. - * Returns 0 if the whole region was software write protected. - * Hardware write protection mechanism aren't accounted. - * If the status register is locked and the requested configuration - * doesn't match the selected one, return an error. - * Only a single region is supported ! - * - * @return 0 on success - */ - int - (*set_write)(const struct spi_flash *flash, - const struct region *region, - const enum spi_flash_status_reg_lockdown mode); - -}; - -static CONST struct spi_flash_protection_ops spi_flash_protection_ops = { - .get_write = winbond_get_write_protection, - .set_write = winbond_set_write_protection, -}; - -CONST struct spi_flash_vendor_info spi_flash_winbond_vi = { - .id = VENDOR_ID_WINBOND, - .page_size_shift = 8, - .sector_size_kib_shift = 2, - .match_id_mask[0] = 0xffff, - .ids = flash_table, - .nr_part_ids = ARRAY_SIZE(flash_table), - .desc = &spi_flash_pp_0x20_sector_desc, - .prot_ops = &spi_flash_protection_ops, -}; From 87dbb903ac23c015774cc573c1b2570565449b52 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 14:29:35 +0200 Subject: [PATCH 184/297] add files to .inf --- UefiPayloadPkg/SPI/SPI.inf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 18cda5cef498..833b2efd412a 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -18,12 +18,12 @@ [Sources] SPI.h SPI.c - SPIFvb.c SPIgeneric.h SPIgeneric.c - intelSPI.h - intelSPI.c - helpers.h + lpc.h + lpc.c + amdSPI.h + amdSPI.c [Packages] MdePkg/MdePkg.dec From f40cf587cf633c00fff158801fa5f2e738453be9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 14:33:22 +0200 Subject: [PATCH 185/297] fix type --- UefiPayloadPkg/SPI/amdSPI.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/amdSPI.c b/UefiPayloadPkg/SPI/amdSPI.c index ccd9687b8927..e5f45a387b04 100644 --- a/UefiPayloadPkg/SPI/amdSPI.c +++ b/UefiPayloadPkg/SPI/amdSPI.c @@ -6,14 +6,14 @@ void spi_init(void) DEBUG((EFI_D_INFO, "%a: SPI BAR at 0x%08lx\n", __FUNCTION__, spi_get_bar())); } -static uintptr_t spi_base; +static UINT32 *spi_base; void spi_set_base(void *base) { - spi_base = (uintptr_t)base; + spi_base = (UINT32 *)base; } -uintptr_t spi_get_bar(void) +UINT32 *spi_get_bar(void) { if (!spi_base) spi_set_base((void *)lpc_get_spibase()); From f950a13f7635f3beb2a255674b2f4199f9f3208d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 14:36:31 +0200 Subject: [PATCH 186/297] missing references --- UefiPayloadPkg/SPI/amdSPI.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/amdSPI.h b/UefiPayloadPkg/SPI/amdSPI.h index e49678e0f7af..30dd96123227 100644 --- a/UefiPayloadPkg/SPI/amdSPI.h +++ b/UefiPayloadPkg/SPI/amdSPI.h @@ -1,3 +1,5 @@ #include VOID spi_init(VOID); +UINT32 *spi_get_bar(void); +void spi_set_base(void *base); From 3cd1b32175ed2345b378151201ffcdcdfd954818 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 14:39:38 +0200 Subject: [PATCH 187/297] add include --- UefiPayloadPkg/SPI/amdSPI.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/amdSPI.c b/UefiPayloadPkg/SPI/amdSPI.c index e5f45a387b04..89e8537e8942 100644 --- a/UefiPayloadPkg/SPI/amdSPI.c +++ b/UefiPayloadPkg/SPI/amdSPI.c @@ -1,6 +1,8 @@ #include #include +#include "amdSPI.h" + void spi_init(void) { DEBUG((EFI_D_INFO, "%a: SPI BAR at 0x%08lx\n", __FUNCTION__, spi_get_bar())); From ea423e481c2714438a613c99471c3388beac94ca Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 28 Sep 2020 14:42:02 +0200 Subject: [PATCH 188/297] add include 2 --- UefiPayloadPkg/SPI/amdSPI.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/amdSPI.c b/UefiPayloadPkg/SPI/amdSPI.c index 89e8537e8942..2fab2b49102b 100644 --- a/UefiPayloadPkg/SPI/amdSPI.c +++ b/UefiPayloadPkg/SPI/amdSPI.c @@ -2,6 +2,7 @@ #include #include "amdSPI.h" +#include "lpc.h" void spi_init(void) { From 012ed356953d8b1265abcd72bd8902aa6451db6d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 09:03:21 +0200 Subject: [PATCH 189/297] add some amdSPI implementation --- UefiPayloadPkg/SPI/SPI.inf | 3 + UefiPayloadPkg/SPI/amdSPI.h | 5 ++ UefiPayloadPkg/SPI/device.h | 91 +++++++++++++++++++ UefiPayloadPkg/SPI/kconfig.h | 20 +++++ UefiPayloadPkg/SPI/lpc.c | 1 + UefiPayloadPkg/SPI/path.h | 145 ++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/pci_mmio_cfg.h | 40 +++++++++ UefiPayloadPkg/SPI/pci_ops.c | 37 ++++++++ UefiPayloadPkg/SPI/pci_ops.h | 13 +++ UefiPayloadPkg/SPI/pci_type.h | 32 +++++++ 10 files changed, 387 insertions(+) create mode 100644 UefiPayloadPkg/SPI/device.h create mode 100644 UefiPayloadPkg/SPI/kconfig.h create mode 100644 UefiPayloadPkg/SPI/path.h create mode 100644 UefiPayloadPkg/SPI/pci_mmio_cfg.h create mode 100644 UefiPayloadPkg/SPI/pci_ops.c create mode 100644 UefiPayloadPkg/SPI/pci_ops.h create mode 100644 UefiPayloadPkg/SPI/pci_type.h diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 833b2efd412a..3f333376f06b 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -24,6 +24,9 @@ lpc.c amdSPI.h amdSPI.c + pci_type.h + device.h + kconfig.h [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/amdSPI.h b/UefiPayloadPkg/SPI/amdSPI.h index 30dd96123227..beaccfe6e5ba 100644 --- a/UefiPayloadPkg/SPI/amdSPI.h +++ b/UefiPayloadPkg/SPI/amdSPI.h @@ -1,5 +1,10 @@ +#ifndef AMD_SPI_H +#define AMD_SPI_H + #include VOID spi_init(VOID); UINT32 *spi_get_bar(void); void spi_set_base(void *base); + +#endif /* AMD_SPI_H */ diff --git a/UefiPayloadPkg/SPI/device.h b/UefiPayloadPkg/SPI/device.h new file mode 100644 index 000000000000..69f24d8294ad --- /dev/null +++ b/UefiPayloadPkg/SPI/device.h @@ -0,0 +1,91 @@ +#ifndef DEVICE_H +#define DEVICE_H + +#include +#include "path.h" +#include "kconfig.h" + +struct bus { + + struct device *dev; /* This bridge device */ + struct device *children; /* devices behind this bridge */ + struct bus *next; /* The next bridge on this device */ + unsigned int bridge_ctrl; /* Bridge control register */ + UINT16 bridge_cmd; /* Bridge command register */ + unsigned char link_num; /* The index of this link */ + UINT16 secondary; /* secondary bus number */ + UINT16 subordinate; /* max subordinate bus number */ + unsigned char cap; /* PCi capability offset */ + UINT32 hcdn_reg; /* For HyperTransport link */ + + unsigned int reset_needed : 1; + unsigned int disable_relaxed_ordering : 1; + unsigned int ht_link_up : 1; + unsigned int no_vga16 : 1; /* No support for 16-bit VGA decoding */ +}; + +/* + * There is one device structure for each slot-number/function-number + * combination: + */ + +struct pci_irq_info { + unsigned int ioapic_irq_pin; + unsigned int ioapic_src_pin; + unsigned int ioapic_dst_id; + unsigned int ioapic_flags; +}; + +struct device { + struct bus *bus; /* bus this device is on, for bridge + * devices, it is the up stream bus */ + + struct device *sibling; /* next device on this bus */ + + struct device *next; /* chain of all devices */ + + struct device_path path; + unsigned int vendor; + unsigned int device; + UINT16 subsystem_vendor; + UINT16 subsystem_device; + unsigned int class; /* 3 bytes: (base, sub, prog-if) */ + unsigned int hdr_type; /* PCI header type */ + unsigned int enabled : 1; /* set if we should enable the device */ + unsigned int initialized : 1; /* 1 if we have initialized the device */ + unsigned int on_mainboard : 1; + unsigned int disable_pcie_aspm : 1; + /* set if we should hide from UI */ + unsigned int hidden : 1; + /* set if this device is used even in minimum PCI cases */ + unsigned int mandatory : 1; + UINT8 command; + UINT16 hotplug_buses; /* Number of hotplug buses to allocate */ + + /* Base registers for this device. I/O, MEM and Expansion ROM */ + struct resource *resource_list; + + /* links are (downstream) buses attached to the device, usually a leaf + * device with no children has 0 buses attached and a bridge has 1 bus + */ + struct bus *link_list; + +#if !DEVTREE_EARLY + struct pci_irq_info pci_irq_info[4]; + struct device_operations *ops; + struct chip_operations *chip_ops; + const char *name; +#if CONFIG(GENERATE_SMBIOS_TABLES) + UINT8 smbios_slot_type; + UINT8 smbios_slot_data_width; + UINT8 smbios_slot_length; + const char *smbios_slot_designation; +#endif +#endif + void *chip_info; + + /* Zero-terminated array of fields and options to probe. */ + struct fw_config *probe_list; +}; + +#endif /* DEVICE_H */ diff --git a/UefiPayloadPkg/SPI/kconfig.h b/UefiPayloadPkg/SPI/kconfig.h new file mode 100644 index 000000000000..a296d5aaaf60 --- /dev/null +++ b/UefiPayloadPkg/SPI/kconfig.h @@ -0,0 +1,20 @@ +#ifndef __KCONFIG_H__ +#define __KCONFIG_H__ + +/* + * Getting something that works in C and CPP for an arg that may or may + * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" + * we match on the placeholder define, insert the "0," for arg1 and generate + * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). + * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when + * the last step cherry picks the 2nd arg, we get a zero. + */ +#define __ARG_PLACEHOLDER_1 0, +#define config_enabled(cfg) _config_enabled(cfg) +#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) +#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0, 0) +#define ___config_enabled(__ignored, val, ...) val + +#define CONFIG(option) config_enabled(CONFIG_##option) + +#endif diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index 1f986f80b642..b65cfcbee291 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -1,6 +1,7 @@ #include #include "lpc.h" +#include "pci_ops.h" UINT32 *lpc_get_spibase(void) { diff --git a/UefiPayloadPkg/SPI/path.h b/UefiPayloadPkg/SPI/path.h new file mode 100644 index 000000000000..8afbfd0820a5 --- /dev/null +++ b/UefiPayloadPkg/SPI/path.h @@ -0,0 +1,145 @@ +#ifndef PATH_H +#define PATH_H + +#include + +enum device_path_type { + DEVICE_PATH_NONE = 0, + DEVICE_PATH_ROOT, + DEVICE_PATH_PCI, + DEVICE_PATH_PNP, + DEVICE_PATH_I2C, + DEVICE_PATH_APIC, + DEVICE_PATH_DOMAIN, + DEVICE_PATH_CPU_CLUSTER, + DEVICE_PATH_CPU, + DEVICE_PATH_CPU_BUS, + DEVICE_PATH_IOAPIC, + DEVICE_PATH_GENERIC, + DEVICE_PATH_SPI, + DEVICE_PATH_USB, + DEVICE_PATH_MMIO, + DEVICE_PATH_ESPI, + DEVICE_PATH_LPC, + + /* + * When adding path types to this table, please also update the + * DEVICE_PATH_NAMES macro below. + */ +}; + +#define DEVICE_PATH_NAMES { \ + "DEVICE_PATH_NONE", \ + "DEVICE_PATH_ROOT", \ + "DEVICE_PATH_PCI", \ + "DEVICE_PATH_PNP", \ + "DEVICE_PATH_I2C", \ + "DEVICE_PATH_APIC", \ + "DEVICE_PATH_DOMAIN", \ + "DEVICE_PATH_CPU_CLUSTER", \ + "DEVICE_PATH_CPU", \ + "DEVICE_PATH_CPU_BUS", \ + "DEVICE_PATH_IOAPIC", \ + "DEVICE_PATH_GENERIC", \ + "DEVICE_PATH_SPI", \ + "DEVICE_PATH_USB", \ + "DEVICE_PATH_MMIO", \ + "DEVICE_PATH_ESPI", \ + "DEVICE_PATH_LPC", \ +} + +struct domain_path { + unsigned int domain; +}; + +struct pci_path { + unsigned int devfn; +}; + +struct pnp_path { + unsigned int port; + unsigned int device; +}; + +struct i2c_path { + unsigned int device; + unsigned int mode_10bit; +}; + +struct spi_path { + unsigned int cs; +}; + +struct apic_path { + unsigned int apic_id; + unsigned int package_id; + unsigned int node_id; + unsigned int core_id; + unsigned int thread_id; +}; + +struct ioapic_path { + unsigned int ioapic_id; +}; + +struct cpu_cluster_path { + unsigned int cluster; +}; + +struct cpu_path { + unsigned int id; +}; + +struct cpu_bus_path { + unsigned int id; +}; + +struct generic_path { + unsigned int id; + unsigned int subid; +}; + +struct usb_path { + unsigned int port_type; + unsigned int port_id; +}; + +struct mmio_path { + UINT32 *addr; +}; + +struct espi_path { + UINT32 *addr; +}; + +struct lpc_path { + UINT32 *addr; +}; + +struct device_path { + enum device_path_type type; + union { + struct pci_path pci; + struct pnp_path pnp; + struct i2c_path i2c; + struct apic_path apic; + struct ioapic_path ioapic; + struct domain_path domain; + struct cpu_cluster_path cpu_cluster; + struct cpu_path cpu; + struct cpu_bus_path cpu_bus; + struct generic_path generic; + struct spi_path spi; + struct usb_path usb; + struct mmio_path mmio; + struct espi_path espi; + struct lpc_path lpc; + }; +}; + +#define DEVICE_PATH_MAX 40 +#define BUS_PATH_MAX (DEVICE_PATH_MAX+10) + +extern const char *dev_path_name(enum device_path_type type); + +#endif /* PATH_H */ diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h new file mode 100644 index 000000000000..8d6778c755e9 --- /dev/null +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -0,0 +1,40 @@ +#ifndef PCI_MMIO_CFG_H +#define PCI_MMIO_CFG_H + +#include +#include "pci_type.h" +/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we + * prevent some sub-optimal constant folding. */ +extern UINT8 *const pci_mmconf; + +/* Using a unique datatype for MMIO writes makes the pointers to _not_ + * qualify for pointer aliasing with any other objects in memory. + * + * MMIO offset is a value originally derived from 'struct device *' + * in ramstage. For the compiler to not discard this MMIO offset value + * from CPU registers after any MMIO writes, -fstrict-aliasing has to + * be also set for the build. + * + * Bottom 12 bits (4 KiB) are reserved to address the registers of a + * single PCI function. Declare the bank as a union to avoid some casting + * in the functions below. + */ +union pci_bank { + UINT8 reg8[4096]; + UINT16 reg16[4096 / sizeof(UINT16)]; + UINT32 reg32[4096 / sizeof(UINT32)]; +}; + +static __attribute__ ((__always_inline__)) inline +volatile union pci_bank *pcicfg(pci_devfn_t dev) +{ + return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; +} + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +#endif PCI_MMIO_CFG_H diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c new file mode 100644 index 000000000000..81901d3f9565 --- /dev/null +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -0,0 +1,37 @@ +#include + +#include "pci_ops.h" +#include "pci_type.h" +#include "device.h" + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +static __attribute__ ((__always_inline__)) inline +pci_devfn_t pcidev_bdf(const struct device *dev) +{ + return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +} + +__attribute__ ((noreturn)) +VOID pcidev_die(VOID) +{ + die("PCI: dev is NULL!\n"); +} + +static __attribute__ ((__always_inline__)) inline +pci_devfn_t pcidev_assert(CONST struct device *dev) +{ + if (!dev) + pcidev_die(); + return pcidev_bdf(dev); +} + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +{ + return pci_s_read_config32(PCI_BDF(dev), reg); +} diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h new file mode 100644 index 000000000000..e37e835abc07 --- /dev/null +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -0,0 +1,13 @@ +#ifndef PCI_OPS_H +#define PCI_OPS_H + +#include +#include "device.h" + +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); +pci_devfn_t pcidev_bdf(const struct device *dev); +VOID pcidev_die(VOID); +pci_devfn_t pcidev_assert(CONST struct device *dev); +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); + +#endif /* PCI_OPS_H */ diff --git a/UefiPayloadPkg/SPI/pci_type.h b/UefiPayloadPkg/SPI/pci_type.h new file mode 100644 index 000000000000..50edd1ba382b --- /dev/null +++ b/UefiPayloadPkg/SPI/pci_type.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef DEVICE_PCI_TYPE_H +#define DEVICE_PCI_TYPE_H + +#include + +typedef UINT32 pci_devfn_t; + +/* Convert pci_devfn_t to offset in MMCONF space. + * As it is one-to-one, nothing needs to be done. */ +#define PCI_DEVFN_OFFSET(x) ((x)) + +#define PCI_DEV(SEGBUS, DEV, FN) ( \ + (((SEGBUS) & 0xFFF) << 20) | \ + (((DEV) & 0x1F) << 15) | \ + (((FN) & 0x07) << 12)) + +#define PCI_DEV_INVALID (0xffffffffU) + +#if 1 +/* FIXME: For most of the time in ramstage, we get valid device pointer + * from calling the driver entry points. The assert should only be used + * with searches like pcidev_behind(), and only if caller does not make + * the check themselves. + */ +#define PCI_BDF(dev) pcidev_assert((dev)) +#else +#define PCI_BDF(dev) pcidev_bdf((dev)) +#endif + +#endif /* DEVICE_PCI_TYPE_H */ From d4877a7f463ccba78fa6a570ef359d9324cc61c7 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 09:09:03 +0200 Subject: [PATCH 190/297] fixes --- UefiPayloadPkg/SPI/pci_ops.h | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index e37e835abc07..625fd288fa81 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -3,6 +3,7 @@ #include #include "device.h" +#include "pci_type.h" UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); pci_devfn_t pcidev_bdf(const struct device *dev); From a43fa746580a60838961ec7107b6845ede83a899 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 09:11:30 +0200 Subject: [PATCH 191/297] fixes 2 --- UefiPayloadPkg/SPI/pci_type.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_type.h b/UefiPayloadPkg/SPI/pci_type.h index 50edd1ba382b..5da76549f782 100644 --- a/UefiPayloadPkg/SPI/pci_type.h +++ b/UefiPayloadPkg/SPI/pci_type.h @@ -3,8 +3,6 @@ #ifndef DEVICE_PCI_TYPE_H #define DEVICE_PCI_TYPE_H -#include - typedef UINT32 pci_devfn_t; /* Convert pci_devfn_t to offset in MMCONF space. From 519d426499e261e662c86189a5309fa4735cfa97 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 09:32:20 +0200 Subject: [PATCH 192/297] fixes 3 --- UefiPayloadPkg/SPI/lpc.c | 1 + UefiPayloadPkg/SPI/lpc.h | 4 ---- UefiPayloadPkg/SPI/pci_ops.c | 1 + UefiPayloadPkg/SPI/utils.h | 10 ++++++++++ 4 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 UefiPayloadPkg/SPI/utils.h diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index b65cfcbee291..5de89ee293dc 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -2,6 +2,7 @@ #include "lpc.h" #include "pci_ops.h" +#include "utils.h" UINT32 *lpc_get_spibase(void) { diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index 7ba304755913..6e60ba865350 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -13,10 +13,6 @@ #define SPI_ROM_ALT_ENABLE BIT(0) #define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) -#if !defined(__SIMPLE_DEVICE__) -#define _LPCB_DEV pcidev_on_root(0x14, 0x3) -#else #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) -#endif UINT32 *lpc_get_spibase(void); diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index 81901d3f9565..744580a16e12 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -3,6 +3,7 @@ #include "pci_ops.h" #include "pci_type.h" #include "device.h" +#include "pci_mmio_cfg.h" static __attribute__ ((__always_inline__)) inline UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) diff --git a/UefiPayloadPkg/SPI/utils.h b/UefiPayloadPkg/SPI/utils.h new file mode 100644 index 000000000000..00b5d2ece31b --- /dev/null +++ b/UefiPayloadPkg/SPI/utils.h @@ -0,0 +1,10 @@ +#ifndef UTILS_H +#define UTILS_H + +#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1UL) +#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) +#define ALIGN_UP(x,a) ALIGN((x),(a)) +#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) +#define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0) + +#endif /* UTILS_H */ From 00add80990067b7ba7d1fc40b44d51ed436cbbb9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 10:08:52 +0200 Subject: [PATCH 193/297] fixes 4 --- UefiPayloadPkg/SPI/lpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index 5de89ee293dc..5fbdfe478406 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -4,11 +4,11 @@ #include "pci_ops.h" #include "utils.h" -UINT32 *lpc_get_spibase(void) +unsigned long int lpc_get_spibase(void) { UINT32 base; base = pci_read_config32(_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); - return (UINT32)base; + return (unsigned long int)base; } From a69468ef93239d0e353b54110f55af6c0e653a55 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 10:11:19 +0200 Subject: [PATCH 194/297] fixes 5 --- UefiPayloadPkg/SPI/lpc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index 6e60ba865350..f96c58c9e40f 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -15,4 +15,4 @@ #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) -UINT32 *lpc_get_spibase(void); +unsigned long int lpc_get_spibase(void) From 1cffff215edefbbe05b03fd703eb73cb62c77898 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 10:15:30 +0200 Subject: [PATCH 195/297] fixes 6 --- UefiPayloadPkg/SPI/lpc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index f96c58c9e40f..d24bd13c4ee2 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -15,4 +15,4 @@ #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) -unsigned long int lpc_get_spibase(void) +unsigned long int lpc_get_spibase(void); From eade64795ce8a1bb95610f6d1a23d44b0363dde9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 10:21:09 +0200 Subject: [PATCH 196/297] fixes 7 --- UefiPayloadPkg/SPI/lpc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index d24bd13c4ee2..83fca594888d 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -1,4 +1,5 @@ #include +#include "pci_type.h" #ifndef BIT #define BIT(x) (1ul << (x)) From 055bd68e160002a885cede604a051ac9adf7d7bc Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 10:25:21 +0200 Subject: [PATCH 197/297] fixes 8 --- UefiPayloadPkg/SPI/lpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index 5fbdfe478406..b47d5659f38c 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -8,7 +8,7 @@ unsigned long int lpc_get_spibase(void) { UINT32 base; - base = pci_read_config32(_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); + base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); return (unsigned long int)base; } From 4ba3542f39f0f47fc5d4a4436145d26ada971bd4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 10:47:15 +0200 Subject: [PATCH 198/297] comment out Fvb --- UefiPayloadPkg/SPI/SPI.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI.c index 2bee5a0dbd02..8de3e0fbdeca 100644 --- a/UefiPayloadPkg/SPI/SPI.c +++ b/UefiPayloadPkg/SPI/SPI.c @@ -19,13 +19,13 @@ EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks + NULL, //FvbGetAttributes, // GetAttributes + NULL, //FvbSetAttributes, // SetAttributes + NULL, //FvbGetPhysicalAddress, // GetPhysicalAddress + NULL, //FvbGetBlockSize, // GetBlockSize + NULL, //FvbRead, // Read + NULL, //FvbWrite, // Write + NULL, //FvbEraseBlocks, // EraseBlocks NULL, //ParentHandle }; From effefc6032d84361494190c05b256baf2704a717 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:06:40 +0200 Subject: [PATCH 199/297] implement more --- UefiPayloadPkg/SPI/SPI.h | 239 +++++++++------------ UefiPayloadPkg/SPI/SPI.inf | 10 +- UefiPayloadPkg/SPI/{SPI.c => SPI_fvb.c} | 0 UefiPayloadPkg/SPI/SPI_fvb.h | 154 ++++++++++++++ UefiPayloadPkg/SPI/fch_spi_ctrl.c | 265 ++++++++++++++++++++++++ UefiPayloadPkg/SPI/fch_spi_ctrl.h | 4 + UefiPayloadPkg/SPI/fch_spi_util.c | 49 +++++ UefiPayloadPkg/SPI/fch_spi_util.h | 15 ++ UefiPayloadPkg/SPI/mmio.c | 37 ++++ UefiPayloadPkg/SPI/mmio.h | 13 ++ UefiPayloadPkg/SPI/pci_mmio_cfg.h | 4 +- 11 files changed, 647 insertions(+), 143 deletions(-) rename UefiPayloadPkg/SPI/{SPI.c => SPI_fvb.c} (100%) create mode 100644 UefiPayloadPkg/SPI/SPI_fvb.h create mode 100644 UefiPayloadPkg/SPI/fch_spi_ctrl.c create mode 100644 UefiPayloadPkg/SPI/fch_spi_ctrl.h create mode 100644 UefiPayloadPkg/SPI/fch_spi_util.c create mode 100644 UefiPayloadPkg/SPI/fch_spi_util.h create mode 100644 UefiPayloadPkg/SPI/mmio.c create mode 100644 UefiPayloadPkg/SPI/mmio.h diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 2568a3c083ad..b0080dae8e4b 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -1,154 +1,111 @@ -/** @file BlSMMStoreDxe.h +/* SPDX-License-Identifier: GPL-2.0-only */ - Copyright (c) 2020, 9elements Agency GmbH
+#ifndef __AMDBLOCKS_SPI_H__ +#define __AMDBLOCKS_SPI_H__ - SPDX-License-Identifier: BSD-2-Clause-Patent +#include -**/ - -#ifndef __SPI_H__ -#define __SPI_H__ - - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include "SPIgeneric.h" - -#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') -#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) - -typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; +#define SPI_CNTRL0 0x00 +#define SPI_BUSY BIT(31) +enum spi_read_mode { + SPI_READ_MODE_NORMAL33M = 0, + /* 1 is reserved. */ + SPI_READ_MODE_DUAL112 = 2, + SPI_READ_MODE_QUAD114 = 3, + SPI_READ_MODE_DUAL122 = 4, + SPI_READ_MODE_QUAD144 = 5, + SPI_READ_MODE_NORMAL66M = 6, + SPI_READ_MODE_FAST_READ = 7, +}; /* - * Representation of SPI flash operations: - * read: Flash read operation. - * write: Flash write operation. - * erase: Flash erase operation. - * status: Read flash status register. + * SPI read mode is split into bits 18, 29, 30 such that [30:29:18] correspond to bits [2:0] for + * SpiReadMode. */ -struct spi_flash_ops { - int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - VOID *buf); - int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - CONST VOID *buf); - int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - int (*status)(CONST struct spi_flash *flash, UINT8 *reg); +#define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18)) +#define SPI_READ_MODE_UPPER_BITS(x) ((((x) >> 1) & 0x3) << 29) +#define SPI_READ_MODE_LOWER_BITS(x) (((x) & 0x1) << 18) +#define SPI_READ_MODE(x) (SPI_READ_MODE_UPPER_BITS(x) | \ + SPI_READ_MODE_LOWER_BITS(x)) +#define SPI_ACCESS_MAC_ROM_EN BIT(22) + +#define SPI100_ENABLE 0x20 +#define SPI_USE_SPI100 BIT(0) + +/* Use SPI_SPEED_16M-SPI_SPEED_66M below for the southbridge */ +#define SPI100_SPEED_CONFIG 0x22 +enum spi100_speed { + SPI_SPEED_66M = 0, + SPI_SPEED_33M = 1, + SPI_SPEED_22M = 2, + SPI_SPEED_16M = 3, + SPI_SPEED_100M = 4, + SPI_SPEED_800K = 5, }; -#pragma pack (1) -typedef struct { - VENDOR_DEVICE_PATH Vendor; - UINT8 Index; - EFI_DEVICE_PATH_PROTOCOL End; -} NOR_FLASH_DEVICE_PATH; -#pragma pack () - -struct _SMMSTORE_INSTANCE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_BLOCK_IO_MEDIA Media; - - EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; - - NOR_FLASH_DEVICE_PATH DevicePath; +#define SPI_SPEED_MASK 0xf +#define SPI_SPEED_MODE(x, shift) (((x) & SPI_SPEED_MASK) << shift) +#define SPI_NORM_SPEED(x) SPI_SPEED_MODE(x, 12) +#define SPI_FAST_SPEED(x) SPI_SPEED_MODE(x, 8) +#define SPI_ALT_SPEED(x) SPI_SPEED_MODE(x, 4) +#define SPI_TPM_SPEED(x) SPI_SPEED_MODE(x, 0) + +#define SPI_SPEED_CFG(n, f, a, t) (SPI_NORM_SPEED(n) | SPI_FAST_SPEED(f) | \ + SPI_ALT_SPEED(a) | SPI_TPM_SPEED(t)) + +#define SPI100_HOST_PREF_CONFIG 0x2c +#define SPI_RD4DW_EN_HOST BIT(15) + +#define SPI_FIFO 0x80 +#define SPI_FIFO_LAST_BYTE 0xc7 +#define SPI_FIFO_DEPTH (SPI_FIFO_LAST_BYTE - SPI_FIFO) + +struct spi_config { + /* + * Default values if not overridden by mainboard: + * Read mode - Normal 33MHz + * Normal speed - 66MHz + * Fast speed - 66MHz + * Alt speed - 66MHz + * TPM speed - 66MHz + */ + enum spi_read_mode read_mode; + enum spi100_speed normal_speed; + enum spi100_speed fast_speed; + enum spi100_speed altio_speed; + enum spi100_speed tpm_speed; }; -enum optype { - READ_NO_ADDR = 0, - WRITE_NO_ADDR = 1, - READ_WITH_ADDR = 2, - WRITE_WITH_ADDR = 3 -}; +/* + * Perform early SPI initialization: + * 1. Sets SPI ROM base and enables SPI ROM + * 2. Enables SPI ROM prefetching + * 3. Disables 4dw burst + * 4. Configures SPI speed and read mode. + * + * This function expects SoC to include soc_amd_common_config in chip SoC config and uses + * settings from mainboard devicetree to configure speed and read mode. + */ +void fch_spi_early_init(void); -struct intel_spi_op { - UINT8 op; - enum optype type; -}; +/* + * Configure SPI speed and read mode. + * + * This function expects SoC to include soc_amd_common_config in chip SoC config and uses + * settings from mainboard devicetree to configure speed and read mode. + */ +void fch_spi_config_modes(void); -struct intel_swseq_spi_config { - UINT8 opprefixes[2]; - struct intel_spi_op ops[8]; -}; +/* Set the SPI base address variable */ +void spi_set_base(void *base); + +/* Get the SPI base address variable's value */ +uintptr_t spi_get_bar(void); +uint8_t spi_read8(uint8_t reg); +uint16_t spi_read16(uint8_t reg); +uint32_t spi_read32(uint8_t reg); +void spi_write8(uint8_t reg, uint8_t val); +void spi_write16(uint8_t reg, uint16_t val); +void spi_write32(uint8_t reg, uint32_t val); -void * memset (void *dest, int ch, __SIZE_TYPE__ count); - -// -// BlSMMStoreFvbDxe.c -// - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ); - -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbGetBlockSize( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbRead( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbWrite( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbEraseBlocks( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ); - -#endif /* __SPI_H__ */ +#endif /* __AMDBLOCKS_SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 3f333376f06b..84bbe0d25404 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -17,7 +17,7 @@ [Sources] SPI.h - SPI.c + # SPI.c SPIgeneric.h SPIgeneric.c lpc.h @@ -27,6 +27,14 @@ pci_type.h device.h kconfig.h + fch_spi_ctrl.h + fch_spi_ctrl.c + SPI_fvb.h + SPI_fvb.c + fch_spi_util.h + fch_spi_util.c + mmio.h + mmio.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SPI.c b/UefiPayloadPkg/SPI/SPI_fvb.c similarity index 100% rename from UefiPayloadPkg/SPI/SPI.c rename to UefiPayloadPkg/SPI/SPI_fvb.c diff --git a/UefiPayloadPkg/SPI/SPI_fvb.h b/UefiPayloadPkg/SPI/SPI_fvb.h new file mode 100644 index 000000000000..2568a3c083ad --- /dev/null +++ b/UefiPayloadPkg/SPI/SPI_fvb.h @@ -0,0 +1,154 @@ +/** @file BlSMMStoreDxe.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __SPI_H__ +#define __SPI_H__ + + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#include "SPIgeneric.h" + +#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) + +typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; + +/* + * Representation of SPI flash operations: + * read: Flash read operation. + * write: Flash write operation. + * erase: Flash erase operation. + * status: Read flash status register. + */ +struct spi_flash_ops { + int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + VOID *buf); + int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + CONST VOID *buf); + int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + int (*status)(CONST struct spi_flash *flash, UINT8 *reg); +}; + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT8 Index; + EFI_DEVICE_PATH_PROTOCOL End; +} NOR_FLASH_DEVICE_PATH; +#pragma pack () + +struct _SMMSTORE_INSTANCE { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; + + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + + NOR_FLASH_DEVICE_PATH DevicePath; +}; + +enum optype { + READ_NO_ADDR = 0, + WRITE_NO_ADDR = 1, + READ_WITH_ADDR = 2, + WRITE_WITH_ADDR = 3 +}; + +struct intel_spi_op { + UINT8 op; + enum optype type; +}; + +struct intel_swseq_spi_config { + UINT8 opprefixes[2]; + struct intel_spi_op ops[8]; +}; + +void * memset (void *dest, int ch, __SIZE_TYPE__ count); + +// +// BlSMMStoreFvbDxe.c +// + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ); + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbWrite( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + +#endif /* __SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c new file mode 100644 index 000000000000..f81078a0d9ba --- /dev/null +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -0,0 +1,265 @@ +#include +#include + +#include "kconfig.h" + +/* SPDX-License-Identifier: GPL-2.0-only */ + +#define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ +#define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) + +/* SPI MMIO registers */ +#define SPI_RESTRICTED_CMD1 0x04 +#define SPI_RESTRICTED_CMD2 0x08 +#define SPI_CNTRL1 0x0c +#define SPI_CMD_CODE 0x45 +#define SPI_CMD_TRIGGER 0x47 +#define SPI_CMD_TRIGGER_EXECUTE BIT(7) +#define SPI_TX_BYTE_COUNT 0x48 +#define SPI_RX_BYTE_COUNT 0x4b +#define SPI_STATUS 0x4c +#define SPI_DONE_BYTE_COUNT_SHIFT 0 +#define SPI_DONE_BYTE_COUNT_MASK 0xff +#define SPI_FIFO_WR_PTR_SHIFT 8 +#define SPI_FIFO_WR_PTR_MASK 0x7f +#define SPI_FIFO_RD_PTR_SHIFT 16 +#define SPI_FIFO_RD_PTR_MASK 0x7f + +static void dump_state(const char *str, UINT8 phase) +{ + UINT8 dump_size; + UINT32 addr; + + if (!CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)) + return; + DEBUG((EFI_D_INFO, "%a: SPI: %s\n", __FUNCTION__, str)); + DEBUG((EFI_D_INFO, "%a: Cntrl0: %x\n", __FUNCTION__, spi_read32(SPI_CNTRL0))); + DEBUG((EFI_D_INFO, "%a: Status: %x\n", __FUNCTION__, spi_read32(SPI_STATUS))); + + addr = spi_get_bar() + SPI_FIFO; + if (phase == 0) { + dump_size = spi_read8(SPI_TX_BYTE_COUNT); + DEBUG((EFI_D_INFO, "%a: TxByteCount: %x\n", __FUNCTION__, dump_size)); + DEBUG((EFI_D_INFO, "%a: CmdCode: %x\n", __FUNCTION__, spi_read8(SPI_CMD_CODE))); + } else { + dump_size = spi_read8(SPI_RX_BYTE_COUNT); + DEBUG((EFI_D_INFO, "%a: RxByteCount: %x\n", __FUNCTION__, dump_size)); + addr += spi_read8(SPI_TX_BYTE_COUNT); + } + + if (dump_size > 0) + hexdump((void *)addr, dump_size); +} + +static int wait_for_ready(void) +{ + const uint32_t timeout_ms = 500; + struct stopwatch sw; + + stopwatch_init_msecs_expire(&sw, timeout_ms); + + do { + if (!(spi_read32(SPI_STATUS) & SPI_BUSY)) + return 0; + } while (!stopwatch_expired(&sw)); + + return -1; +} + +static int execute_command(void) +{ + dump_state("Before execute", 0); + + spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE); + + if (wait_for_ready()) + printk(BIOS_ERR, + "FCH_SC Error: Timeout executing command\n"); + + dump_state("Transaction finished", 1); + + return 0; +} + +void spi_init(void) +{ + DEBUG((EFI_D_INFO, "%a: %s: SPI BAR at 0x%08lx\n", __FUNCTION__, __func__, spi_get_bar())); +} + +static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, + size_t bytesout, void *din, size_t bytesin) +{ + size_t count; + uint8_t cmd; + uint8_t *bufin = din; + const uint8_t *bufout = dout; + + if (CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)) + printk(BIOS_DEBUG, "%s(%zx, %zx)\n", __func__, bytesout, + bytesin); + + /* First byte is cmd which cannot be sent through FIFO */ + cmd = bufout[0]; + bufout++; + bytesout--; + + /* + * Check if this is a write command attempting to transfer more bytes + * than the controller can handle. Iterations for writes are not + * supported here because each SPI write command needs to be preceded + * and followed by other SPI commands. + */ + if (bytesout + bytesin > SPI_FIFO_DEPTH) { + printk(BIOS_WARNING, "FCH_SC: Too much to transfer, code error!\n"); + return -1; + } + + if (wait_for_ready()) + return -1; + + spi_write8(SPI_CMD_CODE, cmd); + spi_write8(SPI_TX_BYTE_COUNT, bytesout); + spi_write8(SPI_RX_BYTE_COUNT, bytesin); + + for (count = 0; count < bytesout; count++) + spi_write8(SPI_FIFO + count, bufout[count]); + + if (execute_command()) + return -1; + + for (count = 0; count < bytesin; count++) + bufin[count] = spi_read8(SPI_FIFO + count + bytesout); + + return 0; +} + +static int xfer_vectors(const struct spi_slave *slave, + struct spi_op vectors[], size_t count) +{ + return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); +} + +static int protect_a_range(UINT32 value) +{ + UINT32 reg32; + UINT8 n; + + /* find a free protection register */ + for (n = 0; n < MAX_ROM_PROTECT_RANGES; n++) { + reg32 = pci_read_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n)); + if (!reg32) + break; + } + if (n == MAX_ROM_PROTECT_RANGES) + return -1; /* no free range */ + + pci_write_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n), value); + return 0; +} + +/* + * Protect range of SPI flash defined by region using the SPI flash controller. + * + * Note: Up to 4 ranges can be protected, though if a particular region requires more than one + * range, total number of regions decreases accordingly. Each range can be programmed to 4KiB or + * 64KiB granularity. + * + * Warning: If more than 1 region needs protection, and they need mixed protections (read/write) + * than start with the region that requires the most protection. After the restricted commands + * have been written, they can't be changed (write once). So if first region is write protection + * and second region is read protection, it's best to define first region as read and write + * protection. + */ +static int fch_spi_flash_protect(const struct spi_flash *flash, const struct region *region, + const enum ctrlr_prot_type type) +{ + int ret; + UINT32 reg32, rom_base, range_base; + size_t addr, len, gran_value, total_ranges, range; + bool granularity_64k = true; /* assume 64k granularity */ + + addr = region->offset; + len = region->size; + + reg32 = pci_read_config32(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_START); + rom_base = WORD_TO_DWORD_UPPER(reg32); + if (addr < rom_base) + return -1; + range_base = addr % rom_base; + + /* Define granularity to be used */ + if (GRANULARITY_TEST_4k & range_base) + granularity_64k = false; /* use 4K granularity */ + if (GRANULARITY_TEST_4k & len) + granularity_64k = false; /* use 4K granularity */ + + /* Define the first range and total number of ranges required */ + if (granularity_64k) { + gran_value = 0x00010000; /* 64 KiB */ + range_base = range_base >> 16; + } else { + gran_value = 0x00001000; /* 4 KiB */ + range_base = range_base >> 12; + } + total_ranges = len / gran_value; + range_base &= RANGE_ADDR_MASK; + + /* Create reg32 to be written into a range register and program required ranges */ + reg32 = rom_base & ROM_BASE_MASK; + reg32 |= range_base; + if (granularity_64k) + reg32 |= RANGE_UNIT; + if (type & WRITE_PROTECT) + reg32 |= ROM_RANGE_WP; + if (type & READ_PROTECT) + reg32 |= ROM_RANGE_RP; + + for (range = 0; range < total_ranges; range++) { + ret = protect_a_range(reg32); + if (ret) + return ret; + /* + * Next range (lower 8 bits). Range points to the start address of a region. + * The range value must be multiplied by the granularity (which is also the + * size of the region) to get the actual offset from the SPI start address. + */ + reg32++; + } + + /* define commands to be blocked if in range */ + reg32 = 0; + if (type & WRITE_PROTECT) { + /* FIXME */ + DEBUG((EFI_D_INFO, "%a: %s: Write Enable and Write Cmd not blocked\n", __FUNCTION__, __func__)); + reg32 |= (flash->erase_cmd << 8); + } + if (type & READ_PROTECT) { + /* FIXME */ + DEBUG((EFI_D_INFO, "%a: %s: READ_PROTECT not supported.\n", __FUNCTION__, __func__)); + } + + /* Final steps to protect region */ + pci_write_config32(SOC_LPC_DEV, SPI_RESTRICTED_CMD1, reg32); + reg32 = spi_read32(SPI_CNTRL0); + reg32 &= ~SPI_ACCESS_MAC_ROM_EN; + spi_write32(SPI_CNTRL0, reg32); + + return 0; +} + +static const struct spi_ctrlr fch_spi_flash_ctrlr = { + .xfer_vector = xfer_vectors, + .max_xfer_size = SPI_FIFO_DEPTH, + .flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN, + .flash_protect = fch_spi_flash_protect, +}; + +const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { + { + .ctrlr = &fch_spi_flash_ctrlr, + .bus_start = 0, + .bus_end = 0, + }, +}; + +const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.h b/UefiPayloadPkg/SPI/fch_spi_ctrl.h new file mode 100644 index 000000000000..87937c0e0c85 --- /dev/null +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.h @@ -0,0 +1,4 @@ +#ifndef FCH_SPI_CTRL_H +#define FCH_SPI_CTRL_H + +#endif /* FCH_SPI_CTRL_H */ diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c new file mode 100644 index 000000000000..3176ae9b2326 --- /dev/null +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include +#include "mmio.h" + +static uintptr_t spi_base; + +VOID spi_set_base(VOID *base) +{ + spi_base = (uintptr_t)base; +} + +uintptr_t spi_get_bar(VOID) +{ + if (!spi_base) + spi_set_base((VOID *)lpc_get_spibase()); + ASSERT(spi_base); + + return spi_base; +} + +UINT8 spi_read8(UINT8 reg) +{ + return read8((VOID *)(spi_get_bar() + reg)); +} + +UINT16 spi_read16(UINT8 reg) +{ + return read8((VOID *)(spi_get_bar() + reg)); +} + +UINT32 spi_read32(UINT8 reg) +{ + return read32((VOID *)(spi_get_bar() + reg)); +} + +VOID spi_write8(UINT8 reg, UINT8 val) +{ + write8((VOID *)(spi_get_bar() + reg), val); +} + +VOID spi_write16(UINT8 reg, UINT16 val) +{ + write16((VOID *)(spi_get_bar() + reg), val); +} + +VOID spi_write32(UINT8 reg, UINT32 val) +{ + write32((VOID *)(spi_get_bar() + reg), val); +} diff --git a/UefiPayloadPkg/SPI/fch_spi_util.h b/UefiPayloadPkg/SPI/fch_spi_util.h new file mode 100644 index 000000000000..829b08ea96a3 --- /dev/null +++ b/UefiPayloadPkg/SPI/fch_spi_util.h @@ -0,0 +1,15 @@ +#ifndef FCH_SPI_UTIL_H +#define FCH_SPI_UTIL_H + +#include + +VOID spi_set_base(VOID *base); +uintptr_t spi_get_bar(VOID); +UINT8 spi_read8(UINT8 reg); +UINT16 spi_read16(UINT8 reg); +UINT32 spi_read32(UINT8 reg); +VOID spi_write8(UINT8 reg, UINT8 val); +VOID spi_write16(UINT8 reg, UINT16 val); +VOID spi_write32(UINT8 reg, UINT32 val); + +#endif /* FCH_SPI_UTIL_H */ diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c new file mode 100644 index 000000000000..acaeac89b75e --- /dev/null +++ b/UefiPayloadPkg/SPI/mmio.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* Originally imported from linux/include/asm-arm/io.h. This file has changed + * substantially since then. + */ + +#include +#include "endian.h" + +static inline uint8_t read8(const void *addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline uint16_t read16(const void *addr) +{ + return *(volatile uint16_t *)addr; +} + +static inline uint32_t read32(const void *addr) +{ + return *(volatile uint32_t *)addr; +} + +static inline void write8(void *addr, uint8_t val) +{ + *(volatile uint8_t *)addr = val; +} + +static inline void write16(void *addr, uint16_t val) +{ + *(volatile uint16_t *)addr = val; +} + +static inline void write32(void *addr, uint32_t val) +{ + *(volatile uint32_t *)addr = val; +} diff --git a/UefiPayloadPkg/SPI/mmio.h b/UefiPayloadPkg/SPI/mmio.h new file mode 100644 index 000000000000..9cba1afe9255 --- /dev/null +++ b/UefiPayloadPkg/SPI/mmio.h @@ -0,0 +1,13 @@ +#ifndef MMIO_H +#define MMIO_H + +#include + +static inline UINT8 read8(const VOID *addr); +static inline UINT16 read16(const VOID *addr); +static inline UINT32 read32(const VOID *addr); +static inline VOID write8(VOID *addr, UINT8 val); +static inline VOID write16(VOID *addr, UINT16 val); +static inline VOID write32(VOID *addr, UINT32 val); + +#endif /* MMIO_H */ diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 8d6778c755e9..4b9e2930a834 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -3,9 +3,11 @@ #include #include "pci_type.h" + /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ -extern UINT8 *const pci_mmconf; +UINT8 *const pci_mmconf = (VOID *)(uintptr_t)CONFIG_MMCONF_BASE_ADDRESS; +//extern UINT8 *const pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ * qualify for pointer aliasing with any other objects in memory. From 2846511b06f02a045457ec25c75896471ff93f31 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:10:44 +0200 Subject: [PATCH 200/297] add includes, fix types --- UefiPayloadPkg/SPI/SPI.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index b0080dae8e4b..293ea610a237 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -3,7 +3,7 @@ #ifndef __AMDBLOCKS_SPI_H__ #define __AMDBLOCKS_SPI_H__ -#include +#include #define SPI_CNTRL0 0x00 #define SPI_BUSY BIT(31) @@ -86,7 +86,7 @@ struct spi_config { * This function expects SoC to include soc_amd_common_config in chip SoC config and uses * settings from mainboard devicetree to configure speed and read mode. */ -void fch_spi_early_init(void); +VOID fch_spi_early_init(VOID); /* * Configure SPI speed and read mode. @@ -94,18 +94,18 @@ void fch_spi_early_init(void); * This function expects SoC to include soc_amd_common_config in chip SoC config and uses * settings from mainboard devicetree to configure speed and read mode. */ -void fch_spi_config_modes(void); +VOID fch_spi_config_modes(VOID); /* Set the SPI base address variable */ -void spi_set_base(void *base); +VOID spi_set_base(VOID *base); /* Get the SPI base address variable's value */ -uintptr_t spi_get_bar(void); -uint8_t spi_read8(uint8_t reg); -uint16_t spi_read16(uint8_t reg); -uint32_t spi_read32(uint8_t reg); -void spi_write8(uint8_t reg, uint8_t val); -void spi_write16(uint8_t reg, uint16_t val); -void spi_write32(uint8_t reg, uint32_t val); +uintptr_t spi_get_bar(VOID); +UINT8 spi_read8(UINT8 reg); +UINT16 spi_read16(UINT8 reg); +UINT32 spi_read32(UINT8 reg); +VOID spi_write8(UINT8 reg, UINT8 val); +VOID spi_write16(UINT8 reg, UINT16 val); +VOID spi_write32(UINT8 reg, UINT32 val); #endif /* __AMDBLOCKS_SPI_H__ */ From 75ab1480dc3f6de42cd2940a20d4dbd2222b6c64 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:23:22 +0200 Subject: [PATCH 201/297] more implementation --- UefiPayloadPkg/SPI/SPI.h | 9 --------- UefiPayloadPkg/SPI/SPI_fvb.c | 3 +-- UefiPayloadPkg/SPI/SPIgeneric.c | 1 - UefiPayloadPkg/SPI/amdSPI.c | 25 ------------------------- UefiPayloadPkg/SPI/amdSPI.h | 10 ---------- UefiPayloadPkg/SPI/fch_spi_util.c | 1 + 6 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/amdSPI.c delete mode 100644 UefiPayloadPkg/SPI/amdSPI.h diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 293ea610a237..b5dc540a19ff 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -99,13 +99,4 @@ VOID fch_spi_config_modes(VOID); /* Set the SPI base address variable */ VOID spi_set_base(VOID *base); -/* Get the SPI base address variable's value */ -uintptr_t spi_get_bar(VOID); -UINT8 spi_read8(UINT8 reg); -UINT16 spi_read16(UINT8 reg); -UINT32 spi_read32(UINT8 reg); -VOID spi_write8(UINT8 reg, UINT8 val); -VOID spi_write16(UINT8 reg, UINT16 val); -VOID spi_write32(UINT8 reg, UINT32 val); - #endif /* __AMDBLOCKS_SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 8de3e0fbdeca..263428ef5a9c 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -14,7 +14,6 @@ #include #include #include "SPIgeneric.h" -#include "SPI.h" #include "amdSPI.h" EFI_HANDLE Handle = NULL; @@ -46,7 +45,7 @@ EFI_STATUS EFIAPI SPIInitialize ( struct spi_slave slave; DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); - DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(void *))); + DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 38927a3f9c3b..d5842f32fa6f 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -6,7 +6,6 @@ //#include #include #include "SPIgeneric.h" -#include "SPI.h" UINT32 spi_claim_bus(CONST struct spi_slave *slave) { diff --git a/UefiPayloadPkg/SPI/amdSPI.c b/UefiPayloadPkg/SPI/amdSPI.c deleted file mode 100644 index 2fab2b49102b..000000000000 --- a/UefiPayloadPkg/SPI/amdSPI.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -#include "amdSPI.h" -#include "lpc.h" - -void spi_init(void) -{ - DEBUG((EFI_D_INFO, "%a: SPI BAR at 0x%08lx\n", __FUNCTION__, spi_get_bar())); -} - -static UINT32 *spi_base; - -void spi_set_base(void *base) -{ - spi_base = (UINT32 *)base; -} - -UINT32 *spi_get_bar(void) -{ - if (!spi_base) - spi_set_base((void *)lpc_get_spibase()); - - return spi_base; -} diff --git a/UefiPayloadPkg/SPI/amdSPI.h b/UefiPayloadPkg/SPI/amdSPI.h deleted file mode 100644 index beaccfe6e5ba..000000000000 --- a/UefiPayloadPkg/SPI/amdSPI.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef AMD_SPI_H -#define AMD_SPI_H - -#include - -VOID spi_init(VOID); -UINT32 *spi_get_bar(void); -void spi_set_base(void *base); - -#endif /* AMD_SPI_H */ diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index 3176ae9b2326..eda4d4366fa4 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include #include "mmio.h" +#include "fch_spi_util.h" static uintptr_t spi_base; From a6eafb771c397cf90184326a1daee592166b0a70 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:25:09 +0200 Subject: [PATCH 202/297] remove reference to nonexisiting file --- UefiPayloadPkg/SPI/SPI.inf | 2 -- 1 file changed, 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 84bbe0d25404..04eb4c68485f 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -22,8 +22,6 @@ SPIgeneric.c lpc.h lpc.c - amdSPI.h - amdSPI.c pci_type.h device.h kconfig.h From 408a5aba9a75eea8f4f4672e95bd67f5826bf54f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:34:26 +0200 Subject: [PATCH 203/297] fixes --- UefiPayloadPkg/SPI/SPI_fvb.c | 1 - UefiPayloadPkg/SPI/fch_spi_ctrl.c | 28 ++++++++++++++-------------- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 263428ef5a9c..b006091a83e7 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -14,7 +14,6 @@ #include #include #include "SPIgeneric.h" -#include "amdSPI.h" EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index f81078a0d9ba..beeeed905269 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -25,7 +25,7 @@ #define SPI_FIFO_RD_PTR_SHIFT 16 #define SPI_FIFO_RD_PTR_MASK 0x7f -static void dump_state(const char *str, UINT8 phase) +static VOID dump_state(const char *str, UINT8 phase) { UINT8 dump_size; UINT32 addr; @@ -48,10 +48,10 @@ static void dump_state(const char *str, UINT8 phase) } if (dump_size > 0) - hexdump((void *)addr, dump_size); + hexdump((VOID *)addr, dump_size); } -static int wait_for_ready(void) +static int wait_for_ready(VOID) { const uint32_t timeout_ms = 500; struct stopwatch sw; @@ -66,7 +66,7 @@ static int wait_for_ready(void) return -1; } -static int execute_command(void) +static int execute_command(VOID) { dump_state("Before execute", 0); @@ -81,15 +81,15 @@ static int execute_command(void) return 0; } -void spi_init(void) +VOID spi_init(VOID) { DEBUG((EFI_D_INFO, "%a: %s: SPI BAR at 0x%08lx\n", __FUNCTION__, __func__, spi_get_bar())); } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, - size_t bytesout, void *din, size_t bytesin) +static int spi_ctrlr_xfer(const struct spi_slave *slave, const VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { - size_t count; + __SIZE_TYPE__ count; uint8_t cmd; uint8_t *bufin = din; const uint8_t *bufout = dout; @@ -134,7 +134,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, } static int xfer_vectors(const struct spi_slave *slave, - struct spi_op vectors[], size_t count) + struct spi_op vectors[], __SIZE_TYPE__ count) { return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); } @@ -175,8 +175,8 @@ static int fch_spi_flash_protect(const struct spi_flash *flash, const struct reg { int ret; UINT32 reg32, rom_base, range_base; - size_t addr, len, gran_value, total_ranges, range; - bool granularity_64k = true; /* assume 64k granularity */ + __SIZE_TYPE__ addr, len, gran_value, total_ranges, range; + BOOLEAN granularity_64k = TRUE; /* assume 64k granularity */ addr = region->offset; len = region->size; @@ -189,9 +189,9 @@ static int fch_spi_flash_protect(const struct spi_flash *flash, const struct reg /* Define granularity to be used */ if (GRANULARITY_TEST_4k & range_base) - granularity_64k = false; /* use 4K granularity */ + granularity_64k = FALSE; /* use 4K granularity */ if (GRANULARITY_TEST_4k & len) - granularity_64k = false; /* use 4K granularity */ + granularity_64k = FALSE; /* use 4K granularity */ /* Define the first range and total number of ranges required */ if (granularity_64k) { @@ -262,4 +262,4 @@ const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { }, }; -const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); +const __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); From 50369667dd18c235e212753f127f34ba81929e0c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:45:20 +0200 Subject: [PATCH 204/297] try to add memset --- UefiPayloadPkg/SPI/SPIgeneric.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index d5842f32fa6f..234097cc6b7a 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -4,6 +4,8 @@ //#include //#include //#include +#include +#include #include #include "SPIgeneric.h" From 22061297a1965a2fa83033262e8df1f629158626 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:54:58 +0200 Subject: [PATCH 205/297] add own memset --- UefiPayloadPkg/SPI/SPIgeneric.c | 6 ------ UefiPayloadPkg/SPI/own.c | 8 ++++++++ UefiPayloadPkg/SPI/own.h | 8 ++++++++ 3 files changed, 16 insertions(+), 6 deletions(-) create mode 100644 UefiPayloadPkg/SPI/own.c create mode 100644 UefiPayloadPkg/SPI/own.h diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 234097cc6b7a..69f6610d9007 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -1,11 +1,5 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -//#include -//#include -//#include -//#include -#include -#include #include #include "SPIgeneric.h" diff --git a/UefiPayloadPkg/SPI/own.c b/UefiPayloadPkg/SPI/own.c new file mode 100644 index 000000000000..c62d5ad95912 --- /dev/null +++ b/UefiPayloadPkg/SPI/own.c @@ -0,0 +1,8 @@ +#include +#include "own.h" + +VOID *memset (VOID *ptr, int value, __SIZE_TYPE__ num ) { + for(__SIZE_TYPE__ offset; offset < num; ++offset) { + ((CHAR8 *)ptr)[offset] = (CHAR8)value; + } +} diff --git a/UefiPayloadPkg/SPI/own.h b/UefiPayloadPkg/SPI/own.h new file mode 100644 index 000000000000..f7d6ddb8ac71 --- /dev/null +++ b/UefiPayloadPkg/SPI/own.h @@ -0,0 +1,8 @@ +#ifndef OWN_H +#define OWN_H + +#include + +VOID *memset (VOID * ptr, int value, __SIZE_TYPE__ num ); + +#endif /* OWN_H */ From 09ec8b9f65166c6d6e18c0699a7d46caa8fd3f01 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 12:57:25 +0200 Subject: [PATCH 206/297] fix include --- UefiPayloadPkg/SPI/SPIgeneric.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 69f6610d9007..53421cee9b83 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -2,6 +2,7 @@ #include #include "SPIgeneric.h" +#include "own.h" UINT32 spi_claim_bus(CONST struct spi_slave *slave) { From 834bd577de58fd2045b43507658d13fc92289e6b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 13:28:03 +0200 Subject: [PATCH 207/297] fixes 0 --- UefiPayloadPkg/SPI/SPI.inf | 1 + UefiPayloadPkg/SPI/fch_spi_ctrl.c | 34 +++--- UefiPayloadPkg/SPI/stopwatch.h | 193 ++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+), 15 deletions(-) create mode 100644 UefiPayloadPkg/SPI/stopwatch.h diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 04eb4c68485f..802dbc07dee6 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -33,6 +33,7 @@ fch_spi_util.c mmio.h mmio.c + stopwatch.h [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index beeeed905269..7bbc413292bd 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -2,6 +2,9 @@ #include #include "kconfig.h" +#include "SPI.h" +#include "utils.h" +#include "stopwatch.h" /* SPDX-License-Identifier: GPL-2.0-only */ @@ -25,7 +28,7 @@ #define SPI_FIFO_RD_PTR_SHIFT 16 #define SPI_FIFO_RD_PTR_MASK 0x7f -static VOID dump_state(const char *str, UINT8 phase) +static VOID dump_state(CONST char *str, UINT8 phase) { UINT8 dump_size; UINT32 addr; @@ -53,7 +56,7 @@ static VOID dump_state(const char *str, UINT8 phase) static int wait_for_ready(VOID) { - const uint32_t timeout_ms = 500; + CONST uint32_t timeout_ms = 500; struct stopwatch sw; stopwatch_init_msecs_expire(&sw, timeout_ms); @@ -73,8 +76,8 @@ static int execute_command(VOID) spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE); if (wait_for_ready()) - printk(BIOS_ERR, - "FCH_SC Error: Timeout executing command\n"); + DEBUG((EFI_D_INFO, + "%a: FCH_SC Error: Timeout executing command\n", __FUNCTION__)); dump_state("Transaction finished", 1); @@ -86,17 +89,17 @@ VOID spi_init(VOID) DEBUG((EFI_D_INFO, "%a: %s: SPI BAR at 0x%08lx\n", __FUNCTION__, __func__, spi_get_bar())); } -static int spi_ctrlr_xfer(const struct spi_slave *slave, const VOID *dout, +static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { __SIZE_TYPE__ count; uint8_t cmd; uint8_t *bufin = din; - const uint8_t *bufout = dout; + CONST uint8_t *bufout = dout; if (CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)) - printk(BIOS_DEBUG, "%s(%zx, %zx)\n", __func__, bytesout, - bytesin); + DEBUG((EFI_D_INFO, "%a(%zx, %zx)\n", __FUNCTION__, bytesout, + bytesin)); /* First byte is cmd which cannot be sent through FIFO */ cmd = bufout[0]; @@ -110,7 +113,8 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const VOID *dout, * and followed by other SPI commands. */ if (bytesout + bytesin > SPI_FIFO_DEPTH) { - printk(BIOS_WARNING, "FCH_SC: Too much to transfer, code error!\n"); + DEBUG((EFI_D_INFO, + "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); return -1; } @@ -133,7 +137,7 @@ static int spi_ctrlr_xfer(const struct spi_slave *slave, const VOID *dout, return 0; } -static int xfer_vectors(const struct spi_slave *slave, +static int xfer_vectors(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count) { return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); @@ -170,8 +174,8 @@ static int protect_a_range(UINT32 value) * and second region is read protection, it's best to define first region as read and write * protection. */ -static int fch_spi_flash_protect(const struct spi_flash *flash, const struct region *region, - const enum ctrlr_prot_type type) +static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, + CONST enum ctrlr_prot_type type) { int ret; UINT32 reg32, rom_base, range_base; @@ -247,14 +251,14 @@ static int fch_spi_flash_protect(const struct spi_flash *flash, const struct reg return 0; } -static const struct spi_ctrlr fch_spi_flash_ctrlr = { +static CONST struct spi_ctrlr fch_spi_flash_ctrlr = { .xfer_vector = xfer_vectors, .max_xfer_size = SPI_FIFO_DEPTH, .flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN, .flash_protect = fch_spi_flash_protect, }; -const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { +CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { { .ctrlr = &fch_spi_flash_ctrlr, .bus_start = 0, @@ -262,4 +266,4 @@ const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { }, }; -const __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); +CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); diff --git a/UefiPayloadPkg/SPI/stopwatch.h b/UefiPayloadPkg/SPI/stopwatch.h new file mode 100644 index 000000000000..81a93a33f523 --- /dev/null +++ b/UefiPayloadPkg/SPI/stopwatch.h @@ -0,0 +1,193 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef STOPWATCH_H +#define STOPWATCH_H + +#include "kconfig.h" +#include "stopwatch.h" + +/* Obtain the current monotonic time. The assumption is that the time counts + * up from the value 0 with value 0 being the point when the timer was + * initialized. Additionally, the timer is assumed to only be valid for the + * duration of the boot. + * + * Note that any implementations of timer_monotonic_get() + * need to ensure its timesource does not roll over within 10 secs. The reason + * is that the time between calls to timer_monotonic_get() may be on order + * of 10 seconds. */ +void timer_monotonic_get(struct mono_time *mt); + +/* Returns 1 if callbacks still present in the queue. 0 if no timers left. */ +int timers_run(void); + +/* Schedule a callback to be ran microseconds from time of invocation. + * 0 returned on success, < 0 on error. */ +int timer_sched_callback(struct timeout_callback *tocb, unsigned long us); + +/* Set an absolute time to a number of microseconds. */ +static inline void mono_time_set_usecs(struct mono_time *mt, long us) +{ + mt->microseconds = us; +} + +/* Set an absolute time to a number of milliseconds. */ +static inline void mono_time_set_msecs(struct mono_time *mt, long ms) +{ + mt->microseconds = ms * USECS_PER_MSEC; +} + +/* Add microseconds to an absolute time. */ +static inline void mono_time_add_usecs(struct mono_time *mt, long us) +{ + mt->microseconds += us; +} + +/* Add milliseconds to an absolute time. */ +static inline void mono_time_add_msecs(struct mono_time *mt, long ms) +{ + mono_time_add_usecs(mt, ms * USECS_PER_MSEC); +} + +/* Compare two absolute times: Return -1, 0, or 1 if t1 is <, =, or > t2, + * respectively. */ +static inline int mono_time_cmp(const struct mono_time *t1, + const struct mono_time *t2) +{ + if (t1->microseconds == t2->microseconds) + return 0; + + if (t1->microseconds < t2->microseconds) + return -1; + + return 1; +} + +/* Return true if t1 after t2 */ +static inline int mono_time_after(const struct mono_time *t1, + const struct mono_time *t2) +{ + return mono_time_cmp(t1, t2) > 0; +} + +/* Return true if t1 before t2. */ +static inline int mono_time_before(const struct mono_time *t1, + const struct mono_time *t2) +{ + return mono_time_cmp(t1, t2) < 0; +} + +/* Return time difference between t1 and t2. i.e. t2 - t1. */ +static inline long mono_time_diff_microseconds(const struct mono_time *t1, + const struct mono_time *t2) +{ + return t2->microseconds - t1->microseconds; +} + +struct stopwatch { + struct mono_time start; + struct mono_time current; + struct mono_time expires; +}; + +static inline void stopwatch_init(struct stopwatch *sw) +{ + if (CONFIG(HAVE_MONOTONIC_TIMER)) + timer_monotonic_get(&sw->start); + else + sw->start.microseconds = 0; + + sw->current = sw->expires = sw->start; +} + +static inline void stopwatch_init_usecs_expire(struct stopwatch *sw, long us) +{ + stopwatch_init(sw); + mono_time_add_usecs(&sw->expires, us); +} + +static inline void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms) +{ + stopwatch_init_usecs_expire(sw, USECS_PER_MSEC * ms); +} + +/* + * Tick the stopwatch to collect the current time. + */ +static inline void stopwatch_tick(struct stopwatch *sw) +{ + if (CONFIG(HAVE_MONOTONIC_TIMER)) + timer_monotonic_get(&sw->current); + else + sw->current.microseconds = 0; +} + +/* + * Tick and check the stopwatch for expiration. Returns non-zero on expiration. + */ +static inline int stopwatch_expired(struct stopwatch *sw) +{ + stopwatch_tick(sw); + return !mono_time_before(&sw->current, &sw->expires); +} + +/* + * Tick and check the stopwatch as long as it has not expired. + */ +static inline void stopwatch_wait_until_expired(struct stopwatch *sw) +{ + while (!stopwatch_expired(sw)) + ; +} + +/* + * Return number of microseconds since starting the stopwatch. + */ +static inline long stopwatch_duration_usecs(struct stopwatch *sw) +{ + /* + * If the stopwatch hasn't been ticked (current == start) tick + * the stopwatch to gather the accumulated time. + */ + if (!mono_time_cmp(&sw->start, &sw->current)) + stopwatch_tick(sw); + + return mono_time_diff_microseconds(&sw->start, &sw->current); +} + +static inline long stopwatch_duration_msecs(struct stopwatch *sw) +{ + return stopwatch_duration_usecs(sw) / USECS_PER_MSEC; +} + +/* + * Helper macro to wait until a condition becomes true or a timeout elapses. + * + * condition: a C expression to wait for + * timeout: timeout, in microseconds + * + * Returns: + * 0 if the condition still evaluates to false after the timeout elapsed, + * >0 if the condition evaluates to true. The return value is the amount of + * microseconds waited (at least 1). + */ +#define wait_us(timeout_us, condition) \ +({ \ + long __ret = 0; \ + struct stopwatch __sw; \ + stopwatch_init_usecs_expire(&__sw, timeout_us); \ + do { \ + if (condition) { \ + stopwatch_tick(&__sw); \ + __ret = stopwatch_duration_usecs(&__sw); \ + if (!__ret) /* make sure it evaluates to true */\ + __ret = 1; \ + break; \ + } \ + } while (!stopwatch_expired(&__sw)); \ + __ret; \ +}) + +#define wait_ms(timeout_ms, condition) \ + DIV_ROUND_UP(wait_us((timeout_ms) * USECS_PER_MSEC, condition), \ + USECS_PER_MSEC) + +#endif /* STOPWATCH_H */ From ecf80b2ece3232e024da0039eebba9e34879a408 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 13:32:12 +0200 Subject: [PATCH 208/297] fixes 1 --- UefiPayloadPkg/SPI/stopwatch.h | 58 ++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 16 deletions(-) diff --git a/UefiPayloadPkg/SPI/stopwatch.h b/UefiPayloadPkg/SPI/stopwatch.h index 81a93a33f523..bbc1a1a95e34 100644 --- a/UefiPayloadPkg/SPI/stopwatch.h +++ b/UefiPayloadPkg/SPI/stopwatch.h @@ -1,9 +1,35 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef STOPWATCH_H -#define STOPWATCH_H +#ifndef TIMER_H +#define TIMER_H -#include "kconfig.h" -#include "stopwatch.h" +#include + +#define NSECS_PER_SEC 1000000000 +#define USECS_PER_SEC 1000000 +#define MSECS_PER_SEC 1000 +#define USECS_PER_MSEC (USECS_PER_SEC / MSECS_PER_SEC) + +/* The time structures are defined to be a representation of the time since + * coreboot started executing one of its stages. The reason for using structures + * is to allow for changes in the future. The structures' details are exposed + * so that the compiler can allocate space on the stack and use in other + * structures. In other words, accessing any field within this structure + * outside of the core timer code is not supported. */ + +struct mono_time { + long microseconds; +}; + +/* A timeout_callback structure is used for the book keeping for scheduling + * work in the future. When a callback is called the structure can be + * re-used for scheduling as it is not being tracked by the core timer + * library any more. */ +struct timeout_callback { + VOID *priv; + VOID (*callback)(struct timeout_callback *tocb); + /* Not for public use. The timer library uses the fields below. */ + struct mono_time expiration; +}; /* Obtain the current monotonic time. The assumption is that the time counts * up from the value 0 with value 0 being the point when the timer was @@ -14,35 +40,35 @@ * need to ensure its timesource does not roll over within 10 secs. The reason * is that the time between calls to timer_monotonic_get() may be on order * of 10 seconds. */ -void timer_monotonic_get(struct mono_time *mt); +VOID timer_monotonic_get(struct mono_time *mt); /* Returns 1 if callbacks still present in the queue. 0 if no timers left. */ -int timers_run(void); +int timers_run(VOID); /* Schedule a callback to be ran microseconds from time of invocation. * 0 returned on success, < 0 on error. */ int timer_sched_callback(struct timeout_callback *tocb, unsigned long us); /* Set an absolute time to a number of microseconds. */ -static inline void mono_time_set_usecs(struct mono_time *mt, long us) +static inline VOID mono_time_set_usecs(struct mono_time *mt, long us) { mt->microseconds = us; } /* Set an absolute time to a number of milliseconds. */ -static inline void mono_time_set_msecs(struct mono_time *mt, long ms) +static inline VOID mono_time_set_msecs(struct mono_time *mt, long ms) { mt->microseconds = ms * USECS_PER_MSEC; } /* Add microseconds to an absolute time. */ -static inline void mono_time_add_usecs(struct mono_time *mt, long us) +static inline VOID mono_time_add_usecs(struct mono_time *mt, long us) { mt->microseconds += us; } /* Add milliseconds to an absolute time. */ -static inline void mono_time_add_msecs(struct mono_time *mt, long ms) +static inline VOID mono_time_add_msecs(struct mono_time *mt, long ms) { mono_time_add_usecs(mt, ms * USECS_PER_MSEC); } @@ -88,7 +114,7 @@ struct stopwatch { struct mono_time expires; }; -static inline void stopwatch_init(struct stopwatch *sw) +static inline VOID stopwatch_init(struct stopwatch *sw) { if (CONFIG(HAVE_MONOTONIC_TIMER)) timer_monotonic_get(&sw->start); @@ -98,13 +124,13 @@ static inline void stopwatch_init(struct stopwatch *sw) sw->current = sw->expires = sw->start; } -static inline void stopwatch_init_usecs_expire(struct stopwatch *sw, long us) +static inline VOID stopwatch_init_usecs_expire(struct stopwatch *sw, long us) { stopwatch_init(sw); mono_time_add_usecs(&sw->expires, us); } -static inline void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms) +static inline VOID stopwatch_init_msecs_expire(struct stopwatch *sw, long ms) { stopwatch_init_usecs_expire(sw, USECS_PER_MSEC * ms); } @@ -112,7 +138,7 @@ static inline void stopwatch_init_msecs_expire(struct stopwatch *sw, long ms) /* * Tick the stopwatch to collect the current time. */ -static inline void stopwatch_tick(struct stopwatch *sw) +static inline VOID stopwatch_tick(struct stopwatch *sw) { if (CONFIG(HAVE_MONOTONIC_TIMER)) timer_monotonic_get(&sw->current); @@ -132,7 +158,7 @@ static inline int stopwatch_expired(struct stopwatch *sw) /* * Tick and check the stopwatch as long as it has not expired. */ -static inline void stopwatch_wait_until_expired(struct stopwatch *sw) +static inline VOID stopwatch_wait_until_expired(struct stopwatch *sw) { while (!stopwatch_expired(sw)) ; @@ -190,4 +216,4 @@ static inline long stopwatch_duration_msecs(struct stopwatch *sw) DIV_ROUND_UP(wait_us((timeout_ms) * USECS_PER_MSEC, condition), \ USECS_PER_MSEC) -#endif /* STOPWATCH_H */ +#endif /* TIMER_H */ From 5a9a78c3ea72ac25283bf66f530605f8ffb20a51 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 13:35:51 +0200 Subject: [PATCH 209/297] fixes 2 --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index 7bbc413292bd..0167ca013265 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -5,6 +5,7 @@ #include "SPI.h" #include "utils.h" #include "stopwatch.h" +#include "fch_spi_util.h" /* SPDX-License-Identifier: GPL-2.0-only */ From 16ac87ca03619d348c662faf22d5112492029f88 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 13:40:39 +0200 Subject: [PATCH 210/297] fixes 3 --- UefiPayloadPkg/SPI/fch_spi_util.h | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/fch_spi_util.h b/UefiPayloadPkg/SPI/fch_spi_util.h index 829b08ea96a3..27aac381923f 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.h +++ b/UefiPayloadPkg/SPI/fch_spi_util.h @@ -2,6 +2,7 @@ #define FCH_SPI_UTIL_H #include +#include "pci_type.h" VOID spi_set_base(VOID *base); uintptr_t spi_get_bar(VOID); From e61146127f2c099675f1d2db660c2c655710ede4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 13:46:02 +0200 Subject: [PATCH 211/297] fixes 4 --- UefiPayloadPkg/SPI/fch_spi_util.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index eda4d4366fa4..aaf94faaa983 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -3,14 +3,14 @@ #include "mmio.h" #include "fch_spi_util.h" -static uintptr_t spi_base; +static unsigned long int spi_base; VOID spi_set_base(VOID *base) { - spi_base = (uintptr_t)base; + spi_base = (unsigned long int)base; } -uintptr_t spi_get_bar(VOID) +unsigned long int spi_get_bar(VOID) { if (!spi_base) spi_set_base((VOID *)lpc_get_spibase()); From 71528a4808922f488a49474e8c15f8bc1f1a3ec0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 13:53:41 +0200 Subject: [PATCH 212/297] fixes 5 --- UefiPayloadPkg/SPI/fch_spi_ctrl.h | 35 +++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/fch_spi_util.h | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.h b/UefiPayloadPkg/SPI/fch_spi_ctrl.h index 87937c0e0c85..37abd89bbf14 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.h +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.h @@ -1,4 +1,39 @@ #ifndef FCH_SPI_CTRL_H #define FCH_SPI_CTRL_H +#include + +#include "kconfig.h" +#include "SPI.h" +#include "utils.h" +#include "stopwatch.h" +#include "fch_spi_util.h" +#include "SPIgeneric.h" + +static VOID dump_state(CONST char *str, UINT8 phase); +static int wait_for_ready(VOID); +static int execute_command(VOID); +VOID spi_init(VOID); +static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); +static int xfer_vectors(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count); +static int protect_a_range(UINT32 value); + +/* + * Protect range of SPI flash defined by region using the SPI flash controller. + * + * Note: Up to 4 ranges can be protected, though if a particular region requires more than one + * range, total number of regions decreases accordingly. Each range can be programmed to 4KiB or + * 64KiB granularity. + * + * Warning: If more than 1 region needs protection, and they need mixed protections (read/write) + * than start with the region that requires the most protection. After the restricted commands + * have been written, they can't be changed (write once). So if first region is write protection + * and second region is read protection, it's best to define first region as read and write + * protection. + */ +static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, + CONST enum ctrlr_prot_type type); + #endif /* FCH_SPI_CTRL_H */ diff --git a/UefiPayloadPkg/SPI/fch_spi_util.h b/UefiPayloadPkg/SPI/fch_spi_util.h index 27aac381923f..1d3521665e08 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.h +++ b/UefiPayloadPkg/SPI/fch_spi_util.h @@ -5,7 +5,7 @@ #include "pci_type.h" VOID spi_set_base(VOID *base); -uintptr_t spi_get_bar(VOID); +unsigned long int spi_get_bar(VOID); UINT8 spi_read8(UINT8 reg); UINT16 spi_read16(UINT8 reg); UINT32 spi_read32(UINT8 reg); From f420cde1d3c343c40be8471af90bf1169d939662 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:07:34 +0200 Subject: [PATCH 213/297] fixes 6 --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 14 ++-- UefiPayloadPkg/SPI/lpc.h | 135 +++++++++++++++++++++++++++--- 2 files changed, 133 insertions(+), 16 deletions(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index 0167ca013265..f2d1a0927eab 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -51,13 +51,15 @@ static VOID dump_state(CONST char *str, UINT8 phase) addr += spi_read8(SPI_TX_BYTE_COUNT); } - if (dump_size > 0) - hexdump((VOID *)addr, dump_size); + if (dump_size > 0) { + //hexdump((VOID *)addr, dump_size); + DEBUG((EFI_D_INFO, "%a: HEXDUMPING NOT IMPLEMENTED: %x\n", __FUNCTION__, dump_size)); + } } static int wait_for_ready(VOID) { - CONST uint32_t timeout_ms = 500; + CONST UINT32 timeout_ms = 500; struct stopwatch sw; stopwatch_init_msecs_expire(&sw, timeout_ms); @@ -94,9 +96,9 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { __SIZE_TYPE__ count; - uint8_t cmd; - uint8_t *bufin = din; - CONST uint8_t *bufout = dout; + UINT8 cmd; + UINT8 *bufin = din; + CONST UINT8 *bufout = dout; if (CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)) DEBUG((EFI_D_INFO, "%a(%zx, %zx)\n", __FUNCTION__, bytesout, diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index 83fca594888d..98088ea49e08 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -1,18 +1,133 @@ #include #include "pci_type.h" -#ifndef BIT -#define BIT(x) (1ul << (x)) -#endif +/* PCI registers for D14F3 */ +#define LPC_PCI_CONTROL 0x40 +#define LEGACY_DMA_EN BIT(2) +#define VW_ROM_SHARING_EN BIT(3) +#define EXT_ROM_SHARING_EN BIT(4) + +#define LPC_IO_PORT_DECODE_ENABLE 0x44 +#define DECODE_ENABLE_PARALLEL_PORT0 BIT(0) +#define DECODE_ENABLE_PARALLEL_PORT1 BIT(1) +#define DECODE_ENABLE_PARALLEL_PORT2 BIT(2) +#define DECODE_ENABLE_PARALLEL_PORT3 BIT(3) +#define DECODE_ENABLE_PARALLEL_PORT4 BIT(4) +#define DECODE_ENABLE_PARALLEL_PORT5 BIT(5) +#define DECODE_ENABLE_SERIAL_PORT0 BIT(6) +#define DECODE_ENABLE_SERIAL_PORT1 BIT(7) +#define DECODE_ENABLE_SERIAL_PORT2 BIT(8) +#define DECODE_ENABLE_SERIAL_PORT3 BIT(9) +#define DECODE_ENABLE_SERIAL_PORT4 BIT(10) +#define DECODE_ENABLE_SERIAL_PORT5 BIT(11) +#define DECODE_ENABLE_SERIAL_PORT6 BIT(12) +#define DECODE_ENABLE_SERIAL_PORT7 BIT(13) +#define DECODE_ENABLE_AUDIO_PORT0 BIT(14) +#define DECODE_ENABLE_AUDIO_PORT1 BIT(15) +#define DECODE_ENABLE_AUDIO_PORT2 BIT(16) +#define DECODE_ENABLE_AUDIO_PORT3 BIT(17) +#define DECODE_ENABLE_MIDI_PORT0 BIT(18) +#define DECODE_ENABLE_MIDI_PORT1 BIT(19) +#define DECODE_ENABLE_MIDI_PORT2 BIT(20) +#define DECODE_ENABLE_MIDI_PORT3 BIT(21) +#define DECODE_ENABLE_MSS_PORT0 BIT(22) +#define DECODE_ENABLE_MSS_PORT1 BIT(23) +#define DECODE_ENABLE_MSS_PORT2 BIT(24) +#define DECODE_ENABLE_MSS_PORT3 BIT(25) +#define DECODE_ENABLE_FDC_PORT0 BIT(26) +#define DECODE_ENABLE_FDC_PORT1 BIT(27) +#define DECODE_ENABLE_GAME_PORT BIT(28) +#define DECODE_ENABLE_KBC_PORT BIT(29) +#define DECODE_ENABLE_ACPIUC_PORT BIT(30) +#define DECODE_ENABLE_ADLIB_PORT BIT(31) + +#define LPC_IO_OR_MEM_DECODE_ENABLE 0x48 +#define LPC_WIDEIO2_ENABLE BIT(25) +#define LPC_WIDEIO1_ENABLE BIT(24) +#define DECODE_IO_PORT_ENABLE6 BIT(23) +#define DECODE_IO_PORT_ENABLE5 BIT(22) +#define DECODE_IO_PORT_ENABLE4 BIT(21) +#define DECODE_MEM_PORT_ENABLE1 BIT(20) +#define DECODE_IO_PORT_ENABLE3 BIT(19) +#define DECODE_IO_PORT_ENABLE2 BIT(18) +#define DECODE_IO_PORT_ENABLE1 BIT(17) +#define DECODE_IO_PORT_ENABLE0 BIT(16) +#define LPC_SYNC_TIMEOUT_COUNT_MASK (0xff << 8) +#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT(7) +#define LPC_DECODE_RTC_IO_ENABLE BIT(6) +#define DECODE_MEM_PORT_ENABLE0 BIT(5) +#define LPC_WIDEIO0_ENABLE BIT(2) +#define DECODE_ALTERNATE_SIO_ENABLE BIT(1) +#define DECODE_SIO_ENABLE BIT(0) +#define LPC_SELECT_SIO_4E4F 1 +#define LPC_SELECT_SIO_2E2F 0 +#define WIDEIO_RANGE_ERROR -1 + +/* Assuming word access to higher word (register 0x4a) */ +#define LPC_IO_OR_MEM_DEC_EN_HIGH 0x4a +#define LPC_WIDEIO2_ENABLE_H BIT(9) +#define LPC_WIDEIO1_ENABLE_H BIT(8) +#define DECODE_IO_PORT_ENABLE6_H BIT(7) +#define DECODE_IO_PORT_ENABLE5_H BIT(6) +#define DECODE_IO_PORT_ENABLE4_H BIT(5) +#define DECODE_IO_PORT_ENABLE3_H BIT(3) +#define DECODE_IO_PORT_ENABLE2_H BIT(2) +#define DECODE_IO_PORT_ENABLE1_H BIT(1) +#define DECODE_IO_PORT_ENABLE0_H BIT(0) + +#define LPC_MEM_PORT1 0x4c +#define ROM_PROTECT_RANGE0 0x50 +#define ROM_BASE_MASK 0xfffff000 /* bits 31-12 */ +#define ROM_RANGE_WP BIT(10) +#define ROM_RANGE_RP BIT(9) +#define RANGE_UNIT BIT(8) +#define RANGE_ADDR_MASK 0x000000ff /* Range defined by bits 7-0 */ +#define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) +#define MAX_ROM_PROTECT_RANGES 4 +#define LPC_MEM_PORT0 0x60 + +/* Register 0x64 is 32-bit, composed by two 16-bit sub-registers. + For ease of access, each sub-register is declared separately. */ +#define LPC_WIDEIO_GENERIC_PORT 0x64 +#define LPC_WIDEIO1_GENERIC_PORT 0x66 +#define ROM_ADDRESS_RANGE1_START 0x68 +#define ROM_ADDRESS_RANGE1_END 0x6a +#define ROM_ADDRESS_RANGE2_START 0x6c +#define ROM_ADDRESS_RANGE2_END 0x6e + +#define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74 +#define LPC_ALT_WIDEIO2_ENABLE BIT(3) +#define LPC_ALT_WIDEIO1_ENABLE BIT(2) +#define LPC_ALT_WIDEIO0_ENABLE BIT(0) + +#define LPC_MISC_CONTROL_BITS 0x78 +#define LPC_NOHOG BIT(0) + +#define LPC_TRUSTED_PLATFORM_MODULE 0x7c +#define TPM_12_EN BIT(0) +#define TPM_LEGACY_EN BIT(2) + +#define LPC_WIDEIO2_GENERIC_PORT 0x90 #define SPIROM_BASE_ADDRESS_REGISTER 0xa0 -#define SPI_BASE_ALIGNMENT BIT(6) -#define SPI_BASE_RESERVED (BIT(4) | BIT(5)) -#define ROUTE_TPM_2_SPI BIT(3) -#define SPI_ABORT_ENABLE BIT(2) -#define SPI_ROM_ENABLE BIT(1) -#define SPI_ROM_ALT_ENABLE BIT(0) -#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define SPI_BASE_ALIGNMENT BIT(6) +#define SPI_BASE_RESERVED (BIT(4) | BIT(5)) +#define ROUTE_TPM_2_SPI BIT(3) +#define SPI_ABORT_ENABLE BIT(2) +#define SPI_ROM_ENABLE BIT(1) +#define SPI_ROM_ALT_ENABLE BIT(0) +#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) + +/* LPC register 0xb8 is DWORD, here there are definitions for byte + access. For example, bits 31-24 are accessed through byte access + at register 0xbb. */ +#define LPC_ROM_DMA_EC_HOST_CONTROL 0xb8 +#define SPI_FROM_HOST_PREFETCH_EN BIT(24) +#define SPI_FROM_USB_PREFETCH_EN BIT(23) + +#define LPC_HOST_CONTROL 0xbb +#define PREFETCH_EN_SPI_FROM_HOST BIT(0) +#define T_START_ENH BIT(3) #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) From bba164975430d393c645e0089e01277684b3db73 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:17:14 +0200 Subject: [PATCH 214/297] fixes 7 --- UefiPayloadPkg/SPI/SPI.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index b5dc540a19ff..6ce5b5b9e116 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -6,7 +6,7 @@ #include #define SPI_CNTRL0 0x00 -#define SPI_BUSY BIT(31) +#define SPI_BUSY BIT31 enum spi_read_mode { SPI_READ_MODE_NORMAL33M = 0, @@ -22,15 +22,15 @@ enum spi_read_mode { * SPI read mode is split into bits 18, 29, 30 such that [30:29:18] correspond to bits [2:0] for * SpiReadMode. */ -#define SPI_READ_MODE_MASK (BIT(30) | BIT(29) | BIT(18)) +#define SPI_READ_MODE_MASK (BIT30 | BIT29 | BIT18) #define SPI_READ_MODE_UPPER_BITS(x) ((((x) >> 1) & 0x3) << 29) #define SPI_READ_MODE_LOWER_BITS(x) (((x) & 0x1) << 18) #define SPI_READ_MODE(x) (SPI_READ_MODE_UPPER_BITS(x) | \ SPI_READ_MODE_LOWER_BITS(x)) -#define SPI_ACCESS_MAC_ROM_EN BIT(22) +#define SPI_ACCESS_MAC_ROM_EN BIT22 #define SPI100_ENABLE 0x20 -#define SPI_USE_SPI100 BIT(0) +#define SPI_USE_SPI100 BIT0 /* Use SPI_SPEED_16M-SPI_SPEED_66M below for the southbridge */ #define SPI100_SPEED_CONFIG 0x22 @@ -54,7 +54,7 @@ enum spi100_speed { SPI_ALT_SPEED(a) | SPI_TPM_SPEED(t)) #define SPI100_HOST_PREF_CONFIG 0x2c -#define SPI_RD4DW_EN_HOST BIT(15) +#define SPI_RD4DW_EN_HOST BIT15 #define SPI_FIFO 0x80 #define SPI_FIFO_LAST_BYTE 0xc7 From dc737d130dfa5e422a23bbcb6e541c7e072fc606 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:25:35 +0200 Subject: [PATCH 215/297] fixes 8 --- UefiPayloadPkg/SPI/SPI.inf | 1 + UefiPayloadPkg/SPI/fch_spi_ctrl.c | 5 +- UefiPayloadPkg/SPI/pci_devs.h | 120 ++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 UefiPayloadPkg/SPI/pci_devs.h diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 802dbc07dee6..daed4872775a 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -34,6 +34,7 @@ mmio.h mmio.c stopwatch.h + pci_devs.h [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index f2d1a0927eab..e1d4e39597ed 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -6,6 +6,9 @@ #include "utils.h" #include "stopwatch.h" #include "fch_spi_util.h" +#include "SPIgeneric.h" +#include "lpc.h" +#include "pci_devs.h" /* SPDX-License-Identifier: GPL-2.0-only */ @@ -18,7 +21,7 @@ #define SPI_CNTRL1 0x0c #define SPI_CMD_CODE 0x45 #define SPI_CMD_TRIGGER 0x47 -#define SPI_CMD_TRIGGER_EXECUTE BIT(7) +#define SPI_CMD_TRIGGER_EXECUTE BIT7 #define SPI_TX_BYTE_COUNT 0x48 #define SPI_RX_BYTE_COUNT 0x4b #define SPI_STATUS 0x4c diff --git a/UefiPayloadPkg/SPI/pci_devs.h b/UefiPayloadPkg/SPI/pci_devs.h new file mode 100644 index 000000000000..75d54c86cd3e --- /dev/null +++ b/UefiPayloadPkg/SPI/pci_devs.h @@ -0,0 +1,120 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef PCI_DEV_H +#define PCI_DEV_H + +#define _SOC_DEV(slot, func) PCI_DEV(0, slot, func) + +/* GNB Root Complex */ +#define GNB_DEV 0x0 +#define GNB_FUNC 0 +#define GNB_DEVFN PCI_DEVFN(GNB_DEV, GNB_FUNC) +#define SOC_GNB_DEV _SOC_DEV(GNB_DEV, GNB_FUNC) + +/* IOMMU */ +#define IOMMU_DEV 0x0 +#define IOMMU_FUNC 2 +#define IOMMU_DEVFN PCI_DEVFN(IOMMU_DEV, IOMMU_FUNC) +#define SOC_IOMMU_DEV _SOC_DEV(IOMMU_DEV, IOMMU_FUNC) + +/* PCIe GPP Bridges 0 - 6 */ +#define PCIE_HOST_BRIDGE_06_DEV 0x1 + +#define PCIE_GPP_0_FUNC 1 +#define PCIE_GPP_0_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_0_FUNC) +#define SOC_GPP_0_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_0_FUNC) + +#define PCIE_GPP_1_FUNC 2 +#define PCIE_GPP_1_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_1_FUNC) +#define SOC_GPP_1_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_1_FUNC) + +#define PCIE_GPP_2_FUNC 3 +#define PCIE_GPP_2_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_2_FUNC) +#define SOC_GPP_2_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_2_FUNC) + +#define PCIE_GPP_3_FUNC 4 +#define PCIE_GPP_3_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_3_FUNC) +#define SOC_GPP_3_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_3_FUNC) + +#define PCIE_GPP_4_FUNC 5 +#define PCIE_GPP_4_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_4_FUNC) +#define SOC_GPP_4_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_4_FUNC) + +#define PCIE_GPP_5_FUNC 6 +#define PCIE_GPP_5_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_5_FUNC) +#define SOC_GPP_5_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_5_FUNC) + +#define PCIE_GPP_6_FUNC 7 +#define PCIE_GPP_6_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_6_FUNC) +#define SOC_GPP_6_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_6_FUNC) + +/* PCIe GPP Bridges to Bus A and Bus B devices */ +#define PCIE_HOST_BRIDGE_AB_DEV 0x8 + +#define PCIE_GPP_A_FUNC 1 +#define PCIE_GPP_A_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_A_FUNC) +#define SOC_PCIE_GPP_A_DEV _SOC_DEV(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_A_FUNC) +#define GFX_DEV 0x0 +#define GFX_FUNC 0 +#define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC) + +#define XHCI0_DEV 0x0 +#define XHCI0_FUNC 3 +#define XHCI0_DEVFN PCI_DEVFN(XHCI0_DEV, XHCI0_FUNC) + +#define XHCI1_DEV 0x0 +#define XHCI1_FUNC 4 +#define XHCI1_DEVFN PCI_DEVFN(XHCI1_DEV, XHCI1_FUNC) + +#define AUDIO_DEV 0x0 +#define AUDIO_FUNC 5 +#define AUDIO_DEVFN PCI_DEVFN(AUDIO_DEV, AUDIO_FUNC) + +#define HD_AUDIO_DEV 0x0 +#define HD_AUDIO_FUNC 6 +#define HD_AUDIO_DEVFN PCI_DEVFN(HD_AUDIO_DEV, HD_AUDIO_FUNC) + +#define PCIE_GPP_B_FUNC 2 +#define PCIE_GPP_B_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_B_FUNC) +#define SOC_PCIE_GPP_B_DEV _SOC_DEV(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_B_FUNC) +#define SATA_DEV 0x0 +#define SATA_FUNC 0 +#define SATA_DEVFN PCI_DEVFN(SATA_DEV, SATA_FUNC) + +/* Data Fabric functions */ +#define DF_DEV 0x18 + +#define DF_F0_DEVFN PCI_DEVFN(DF_DEV, 0) +#define SOC_DF_F0_DEV _SOC_DEV(DF_DEV, 0) + +#define DF_F1_DEVFN PCI_DEVFN(DF_DEV, 1) +#define SOC_DF_F1_DEV _SOC_DEV(DF_DEV, 1) + +#define DF_F2_DEVFN PCI_DEVFN(DF_DEV, 2) +#define SOC_DF_F2_DEV _SOC_DEV(DF_DEV, 2) + +#define DF_F3_DEVFN PCI_DEVFN(DF_DEV, 3) +#define SOC_DF_F3_DEV _SOC_DEV(DF_DEV, 3) + +#define DF_F4_DEVFN PCI_DEVFN(DF_DEV, 4) +#define SOC_DF_F4_DEV _SOC_DEV(DF_DEV, 4) + +#define DF_F5_DEVFN PCI_DEVFN(DF_DEV, 5) +#define SOC_DF_F5_DEV _SOC_DEV(DF_DEV, 5) + +#define DF_F6_DEVFN PCI_DEVFN(DF_DEV, 6) +#define SOC_DF_F6_DEV _SOC_DEV(DF_DEV, 6) + +/* SMBUS */ +#define SMBUS_DEV 0x14 +#define SMBUS_FUNC 0 +#define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC) +#define SOC_SMBUS_DEV _SOC_DEV(SMBUS_DEV, SMBUS_FUNC) + +/* LPC BUS */ +#define PCU_DEV 0x14 +#define LPC_FUNC 3 +#define LPC_DEVFN PCI_DEVFN(PCU_DEV, LPC_FUNC) +#define SOC_LPC_DEV _SOC_DEV(PCU_DEV, LPC_FUNC) + +#endif /* PCI_DEV_H */ From f58ddc258bd8e11665bc68f78fd1a9b6d02feb94 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:34:08 +0200 Subject: [PATCH 216/297] fixes 9 --- UefiPayloadPkg/SPI/spi_flash.c | 50 ++++++++++++++++++++++++++++++++++ UefiPayloadPkg/SPI/spi_flash.h | 13 +++++++++ 2 files changed, 63 insertions(+) create mode 100644 UefiPayloadPkg/SPI/spi_flash.c create mode 100644 UefiPayloadPkg/SPI/spi_flash.h diff --git a/UefiPayloadPkg/SPI/spi_flash.c b/UefiPayloadPkg/SPI/spi_flash.c new file mode 100644 index 000000000000..b2bcbdfe26c5 --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_flash.c @@ -0,0 +1,50 @@ +#include +#include "SPIgeneric.h" + +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + int (*func)(const struct spi_slave *slave, const void *dout, + __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)) +{ + int ret; + void *din; + __SIZE_TYPE__ bytes_in; + + if (count < 1 || count > 2) + return -1; + + /* SPI flash commands always have a command first... */ + if (!vectors[0].dout || !vectors[0].bytesout) + return -1; + /* And not read any data during the command. */ + if (vectors[0].din || vectors[0].bytesin) + return -1; + + if (count == 2) { + /* If response bytes requested ensure the buffer is valid. */ + if (vectors[1].bytesin && !vectors[1].din) + return -1; + /* No sends can accompany a receive. */ + if (vectors[1].dout || vectors[1].bytesout) + return -1; + din = vectors[1].din; + bytes_in = vectors[1].bytesin; + } else { + din = NULL; + bytes_in = 0; + } + + ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); + + if (ret) { + vectors[0].status = SPI_OP_FAILURE; + if (count == 2) + vectors[1].status = SPI_OP_FAILURE; + } else { + vectors[0].status = SPI_OP_SUCCESS; + if (count == 2) + vectors[1].status = SPI_OP_SUCCESS; + } + + return ret; +} diff --git a/UefiPayloadPkg/SPI/spi_flash.h b/UefiPayloadPkg/SPI/spi_flash.h new file mode 100644 index 000000000000..a6f3668cf040 --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_flash.h @@ -0,0 +1,13 @@ +#ifndef SPI_FLASH_H +#define SPI_FLASH_H + +#include +#include "SPIgeneric.h" + +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + int (*func)(const struct spi_slave *slave, const void *dout, + __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)); + + +#endif /* SPI_FLASH_H */ From 1e4016e3b396f4ea3a179c41e4f858d0cfa183e8 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:37:40 +0200 Subject: [PATCH 217/297] fixes 10 --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index e1d4e39597ed..0dbc759984d6 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -9,6 +9,7 @@ #include "SPIgeneric.h" #include "lpc.h" #include "pci_devs.h" +#include "spi_flash.h" /* SPDX-License-Identifier: GPL-2.0-only */ From 8528a9cf0541407e67959a90a4dd8ecd55230873 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:40:49 +0200 Subject: [PATCH 218/297] fixes 11 --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index 0dbc759984d6..b9e967cfc65a 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -10,6 +10,7 @@ #include "lpc.h" #include "pci_devs.h" #include "spi_flash.h" +#include "pci_ops.h" /* SPDX-License-Identifier: GPL-2.0-only */ From 662a043ec9f33fecb18e8d89773769e6fc6cac1e Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:46:30 +0200 Subject: [PATCH 219/297] fixes 12 --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index b9e967cfc65a..aa8c00ab4120 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -158,14 +158,14 @@ static int protect_a_range(UINT32 value) /* find a free protection register */ for (n = 0; n < MAX_ROM_PROTECT_RANGES; n++) { - reg32 = pci_read_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n)); + reg32 = pci_read_config32((struct device *)SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n)); if (!reg32) break; } if (n == MAX_ROM_PROTECT_RANGES) return -1; /* no free range */ - pci_write_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n), value); + pci_write_config32((struct device *)SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n), value); return 0; } From fdf4c5c75f556e150a5677dba97a6eb6d82989c9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 29 Sep 2020 14:52:55 +0200 Subject: [PATCH 220/297] fixes 13 --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 4 +- UefiPayloadPkg/SPI/lpc.h | 160 +++++++++++++++--------------- 2 files changed, 82 insertions(+), 82 deletions(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index aa8c00ab4120..b9e967cfc65a 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -158,14 +158,14 @@ static int protect_a_range(UINT32 value) /* find a free protection register */ for (n = 0; n < MAX_ROM_PROTECT_RANGES; n++) { - reg32 = pci_read_config32((struct device *)SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n)); + reg32 = pci_read_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n)); if (!reg32) break; } if (n == MAX_ROM_PROTECT_RANGES) return -1; /* no free range */ - pci_write_config32((struct device *)SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n), value); + pci_write_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n), value); return 0; } diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index 98088ea49e08..fb8a35f6a832 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -3,84 +3,84 @@ /* PCI registers for D14F3 */ #define LPC_PCI_CONTROL 0x40 -#define LEGACY_DMA_EN BIT(2) -#define VW_ROM_SHARING_EN BIT(3) -#define EXT_ROM_SHARING_EN BIT(4) +#define LEGACY_DMA_EN BIT2 +#define VW_ROM_SHARING_EN BIT3 +#define EXT_ROM_SHARING_EN BIT4 #define LPC_IO_PORT_DECODE_ENABLE 0x44 -#define DECODE_ENABLE_PARALLEL_PORT0 BIT(0) -#define DECODE_ENABLE_PARALLEL_PORT1 BIT(1) -#define DECODE_ENABLE_PARALLEL_PORT2 BIT(2) -#define DECODE_ENABLE_PARALLEL_PORT3 BIT(3) -#define DECODE_ENABLE_PARALLEL_PORT4 BIT(4) -#define DECODE_ENABLE_PARALLEL_PORT5 BIT(5) -#define DECODE_ENABLE_SERIAL_PORT0 BIT(6) -#define DECODE_ENABLE_SERIAL_PORT1 BIT(7) -#define DECODE_ENABLE_SERIAL_PORT2 BIT(8) -#define DECODE_ENABLE_SERIAL_PORT3 BIT(9) -#define DECODE_ENABLE_SERIAL_PORT4 BIT(10) -#define DECODE_ENABLE_SERIAL_PORT5 BIT(11) -#define DECODE_ENABLE_SERIAL_PORT6 BIT(12) -#define DECODE_ENABLE_SERIAL_PORT7 BIT(13) -#define DECODE_ENABLE_AUDIO_PORT0 BIT(14) -#define DECODE_ENABLE_AUDIO_PORT1 BIT(15) -#define DECODE_ENABLE_AUDIO_PORT2 BIT(16) -#define DECODE_ENABLE_AUDIO_PORT3 BIT(17) -#define DECODE_ENABLE_MIDI_PORT0 BIT(18) -#define DECODE_ENABLE_MIDI_PORT1 BIT(19) -#define DECODE_ENABLE_MIDI_PORT2 BIT(20) -#define DECODE_ENABLE_MIDI_PORT3 BIT(21) -#define DECODE_ENABLE_MSS_PORT0 BIT(22) -#define DECODE_ENABLE_MSS_PORT1 BIT(23) -#define DECODE_ENABLE_MSS_PORT2 BIT(24) -#define DECODE_ENABLE_MSS_PORT3 BIT(25) -#define DECODE_ENABLE_FDC_PORT0 BIT(26) -#define DECODE_ENABLE_FDC_PORT1 BIT(27) -#define DECODE_ENABLE_GAME_PORT BIT(28) -#define DECODE_ENABLE_KBC_PORT BIT(29) -#define DECODE_ENABLE_ACPIUC_PORT BIT(30) -#define DECODE_ENABLE_ADLIB_PORT BIT(31) +#define DECODE_ENABLE_PARALLEL_PORT0 BIT0 +#define DECODE_ENABLE_PARALLEL_PORT1 BIT1 +#define DECODE_ENABLE_PARALLEL_PORT2 BIT2 +#define DECODE_ENABLE_PARALLEL_PORT3 BIT3 +#define DECODE_ENABLE_PARALLEL_PORT4 BIT4 +#define DECODE_ENABLE_PARALLEL_PORT5 BIT5 +#define DECODE_ENABLE_SERIAL_PORT0 BIT6 +#define DECODE_ENABLE_SERIAL_PORT1 BIT7 +#define DECODE_ENABLE_SERIAL_PORT2 BIT8 +#define DECODE_ENABLE_SERIAL_PORT3 BIT9 +#define DECODE_ENABLE_SERIAL_PORT4 BIT10 +#define DECODE_ENABLE_SERIAL_PORT5 BIT11 +#define DECODE_ENABLE_SERIAL_PORT6 BIT12 +#define DECODE_ENABLE_SERIAL_PORT7 BIT13 +#define DECODE_ENABLE_AUDIO_PORT0 BIT14 +#define DECODE_ENABLE_AUDIO_PORT1 BIT15 +#define DECODE_ENABLE_AUDIO_PORT2 BIT16 +#define DECODE_ENABLE_AUDIO_PORT3 BIT17 +#define DECODE_ENABLE_MIDI_PORT0 BIT18 +#define DECODE_ENABLE_MIDI_PORT1 BIT19 +#define DECODE_ENABLE_MIDI_PORT2 BIT20 +#define DECODE_ENABLE_MIDI_PORT3 BIT21 +#define DECODE_ENABLE_MSS_PORT0 BIT22 +#define DECODE_ENABLE_MSS_PORT1 BIT23 +#define DECODE_ENABLE_MSS_PORT2 BIT24 +#define DECODE_ENABLE_MSS_PORT3 BIT25 +#define DECODE_ENABLE_FDC_PORT0 BIT26 +#define DECODE_ENABLE_FDC_PORT1 BIT27 +#define DECODE_ENABLE_GAME_PORT BIT28 +#define DECODE_ENABLE_KBC_PORT BIT29 +#define DECODE_ENABLE_ACPIUC_PORT BIT30 +#define DECODE_ENABLE_ADLIB_PORT BIT31 #define LPC_IO_OR_MEM_DECODE_ENABLE 0x48 -#define LPC_WIDEIO2_ENABLE BIT(25) -#define LPC_WIDEIO1_ENABLE BIT(24) -#define DECODE_IO_PORT_ENABLE6 BIT(23) -#define DECODE_IO_PORT_ENABLE5 BIT(22) -#define DECODE_IO_PORT_ENABLE4 BIT(21) -#define DECODE_MEM_PORT_ENABLE1 BIT(20) -#define DECODE_IO_PORT_ENABLE3 BIT(19) -#define DECODE_IO_PORT_ENABLE2 BIT(18) -#define DECODE_IO_PORT_ENABLE1 BIT(17) -#define DECODE_IO_PORT_ENABLE0 BIT(16) +#define LPC_WIDEIO2_ENABLE BIT25 +#define LPC_WIDEIO1_ENABLE BIT24 +#define DECODE_IO_PORT_ENABLE6 BIT23 +#define DECODE_IO_PORT_ENABLE5 BIT22 +#define DECODE_IO_PORT_ENABLE4 BIT21 +#define DECODE_MEM_PORT_ENABLE1 BIT20 +#define DECODE_IO_PORT_ENABLE3 BIT19 +#define DECODE_IO_PORT_ENABLE2 BIT18 +#define DECODE_IO_PORT_ENABLE1 BIT17 +#define DECODE_IO_PORT_ENABLE0 BIT16 #define LPC_SYNC_TIMEOUT_COUNT_MASK (0xff << 8) -#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT(7) -#define LPC_DECODE_RTC_IO_ENABLE BIT(6) -#define DECODE_MEM_PORT_ENABLE0 BIT(5) -#define LPC_WIDEIO0_ENABLE BIT(2) -#define DECODE_ALTERNATE_SIO_ENABLE BIT(1) -#define DECODE_SIO_ENABLE BIT(0) +#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT7 +#define LPC_DECODE_RTC_IO_ENABLE BIT6 +#define DECODE_MEM_PORT_ENABLE0 BIT5 +#define LPC_WIDEIO0_ENABLE BIT2 +#define DECODE_ALTERNATE_SIO_ENABLE BIT1 +#define DECODE_SIO_ENABLE BIT0 #define LPC_SELECT_SIO_4E4F 1 #define LPC_SELECT_SIO_2E2F 0 #define WIDEIO_RANGE_ERROR -1 /* Assuming word access to higher word (register 0x4a) */ #define LPC_IO_OR_MEM_DEC_EN_HIGH 0x4a -#define LPC_WIDEIO2_ENABLE_H BIT(9) -#define LPC_WIDEIO1_ENABLE_H BIT(8) -#define DECODE_IO_PORT_ENABLE6_H BIT(7) -#define DECODE_IO_PORT_ENABLE5_H BIT(6) -#define DECODE_IO_PORT_ENABLE4_H BIT(5) -#define DECODE_IO_PORT_ENABLE3_H BIT(3) -#define DECODE_IO_PORT_ENABLE2_H BIT(2) -#define DECODE_IO_PORT_ENABLE1_H BIT(1) -#define DECODE_IO_PORT_ENABLE0_H BIT(0) +#define LPC_WIDEIO2_ENABLE_H BIT9 +#define LPC_WIDEIO1_ENABLE_H BIT8 +#define DECODE_IO_PORT_ENABLE6_H BIT7 +#define DECODE_IO_PORT_ENABLE5_H BIT6 +#define DECODE_IO_PORT_ENABLE4_H BIT5 +#define DECODE_IO_PORT_ENABLE3_H BIT3 +#define DECODE_IO_PORT_ENABLE2_H BIT2 +#define DECODE_IO_PORT_ENABLE1_H BIT1 +#define DECODE_IO_PORT_ENABLE0_H BIT0 #define LPC_MEM_PORT1 0x4c #define ROM_PROTECT_RANGE0 0x50 #define ROM_BASE_MASK 0xfffff000 /* bits 31-12 */ -#define ROM_RANGE_WP BIT(10) -#define ROM_RANGE_RP BIT(9) -#define RANGE_UNIT BIT(8) +#define ROM_RANGE_WP BIT10 +#define ROM_RANGE_RP BIT9 +#define RANGE_UNIT BIT8 #define RANGE_ADDR_MASK 0x000000ff /* Range defined by bits 7-0 */ #define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) #define MAX_ROM_PROTECT_RANGES 4 @@ -96,38 +96,38 @@ #define ROM_ADDRESS_RANGE2_END 0x6e #define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74 -#define LPC_ALT_WIDEIO2_ENABLE BIT(3) -#define LPC_ALT_WIDEIO1_ENABLE BIT(2) -#define LPC_ALT_WIDEIO0_ENABLE BIT(0) +#define LPC_ALT_WIDEIO2_ENABLE BIT3 +#define LPC_ALT_WIDEIO1_ENABLE BIT2 +#define LPC_ALT_WIDEIO0_ENABLE BIT0 #define LPC_MISC_CONTROL_BITS 0x78 -#define LPC_NOHOG BIT(0) +#define LPC_NOHOG BIT0 #define LPC_TRUSTED_PLATFORM_MODULE 0x7c -#define TPM_12_EN BIT(0) -#define TPM_LEGACY_EN BIT(2) +#define TPM_12_EN BIT0 +#define TPM_LEGACY_EN BIT2 #define LPC_WIDEIO2_GENERIC_PORT 0x90 #define SPIROM_BASE_ADDRESS_REGISTER 0xa0 -#define SPI_BASE_ALIGNMENT BIT(6) -#define SPI_BASE_RESERVED (BIT(4) | BIT(5)) -#define ROUTE_TPM_2_SPI BIT(3) -#define SPI_ABORT_ENABLE BIT(2) -#define SPI_ROM_ENABLE BIT(1) -#define SPI_ROM_ALT_ENABLE BIT(0) -#define SPI_PRESERVE_BITS (BIT(0) | BIT(1) | BIT(2) | BIT(3)) +#define SPI_BASE_ALIGNMENT BIT6 +#define SPI_BASE_RESERVED (BIT4 | BIT5) +#define ROUTE_TPM_2_SPI BIT3 +#define SPI_ABORT_ENABLE BIT2 +#define SPI_ROM_ENABLE BIT1 +#define SPI_ROM_ALT_ENABLE BIT0 +#define SPI_PRESERVE_BITS (BIT0 | BIT1 | BIT2 | BIT3) /* LPC register 0xb8 is DWORD, here there are definitions for byte access. For example, bits 31-24 are accessed through byte access at register 0xbb. */ #define LPC_ROM_DMA_EC_HOST_CONTROL 0xb8 -#define SPI_FROM_HOST_PREFETCH_EN BIT(24) -#define SPI_FROM_USB_PREFETCH_EN BIT(23) +#define SPI_FROM_HOST_PREFETCH_EN BIT24 +#define SPI_FROM_USB_PREFETCH_EN BIT23 #define LPC_HOST_CONTROL 0xbb -#define PREFETCH_EN_SPI_FROM_HOST BIT(0) -#define T_START_ENH BIT(3) +#define PREFETCH_EN_SPI_FROM_HOST BIT0 +#define T_START_ENH BIT3 #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) From 496fe8071e3c4211950a694aad86de0e01b0bde4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 07:38:50 +0200 Subject: [PATCH 221/297] fix errors --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 6 ++++++ UefiPayloadPkg/SPI/pci_ops.c | 12 ++++++++++++ UefiPayloadPkg/SPI/pci_ops.h | 2 ++ 3 files changed, 20 insertions(+) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 4b9e2930a834..d7d8bf3d4f5e 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -39,4 +39,10 @@ UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; } +static __always_inline +void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) +{ + pcicfg(dev)->reg32[reg / sizeof(uint32_t)] = value; +} + #endif PCI_MMIO_CFG_H diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index 744580a16e12..4d3f32711f5d 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -36,3 +36,15 @@ UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) { return pci_s_read_config32(PCI_BDF(dev), reg); } + +static __attribute__ ((__always_inline__)) inline +void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, UINT32 value) +{ + pci_mmio_write_config32(dev, reg, value); +} + +static __attribute__ ((__always_inline__)) inline +void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val) +{ + pci_s_write_config32(PCI_BDF(dev), reg, val); +} diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 625fd288fa81..6a2a0115b584 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -10,5 +10,7 @@ pci_devfn_t pcidev_bdf(const struct device *dev); VOID pcidev_die(VOID); pci_devfn_t pcidev_assert(CONST struct device *dev); UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); +void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, UINT32 value); +void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val); #endif /* PCI_OPS_H */ From 42707801fda1908e422d9dbcffb09b651df74b62 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:11:34 +0200 Subject: [PATCH 222/297] fix pointer type --- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 8 ++++---- UefiPayloadPkg/SPI/pci_ops.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index b9e967cfc65a..186b0948d400 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -158,14 +158,14 @@ static int protect_a_range(UINT32 value) /* find a free protection register */ for (n = 0; n < MAX_ROM_PROTECT_RANGES; n++) { - reg32 = pci_read_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n)); + reg32 = pci_read_config32((struct device *)((VOID *)SOC_LPC_DEV), ROM_PROTECT_RANGE_REG(n)); if (!reg32) break; } if (n == MAX_ROM_PROTECT_RANGES) return -1; /* no free range */ - pci_write_config32(SOC_LPC_DEV, ROM_PROTECT_RANGE_REG(n), value); + pci_write_config32((struct device *)((VOID *)SOC_LPC_DEV), ROM_PROTECT_RANGE_REG(n), value); return 0; } @@ -193,7 +193,7 @@ static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct reg addr = region->offset; len = region->size; - reg32 = pci_read_config32(SOC_LPC_DEV, ROM_ADDRESS_RANGE2_START); + reg32 = pci_read_config32((struct device *)((VOID *)SOC_LPC_DEV), ROM_ADDRESS_RANGE2_START); rom_base = WORD_TO_DWORD_UPPER(reg32); if (addr < rom_base) return -1; @@ -251,7 +251,7 @@ static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct reg } /* Final steps to protect region */ - pci_write_config32(SOC_LPC_DEV, SPI_RESTRICTED_CMD1, reg32); + pci_write_config32((struct device *)((VOID *)SOC_LPC_DEV), SPI_RESTRICTED_CMD1, reg32); reg32 = spi_read32(SPI_CNTRL0); reg32 &= ~SPI_ACCESS_MAC_ROM_EN; spi_write32(SPI_CNTRL0, reg32); diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 6a2a0115b584..429857f24c48 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -10,7 +10,7 @@ pci_devfn_t pcidev_bdf(const struct device *dev); VOID pcidev_die(VOID); pci_devfn_t pcidev_assert(CONST struct device *dev); UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); -void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, UINT32 value); +void pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val); #endif /* PCI_OPS_H */ From 6b8d057325667af51a4035eec0d973de69918072 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:16:28 +0200 Subject: [PATCH 223/297] fix include --- UefiPayloadPkg/SPI/fch_spi_util.c | 1 + 1 file changed, 1 insertion(+) diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index aaf94faaa983..544558c5b1b8 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -2,6 +2,7 @@ #include #include "mmio.h" #include "fch_spi_util.h" +#include "lpc.h" static unsigned long int spi_base; From 8a549446aa14db53bdcfa4a6ed720aa1d644063a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:22:54 +0200 Subject: [PATCH 224/297] fix include --- UefiPayloadPkg/SPI/fch_spi_util.c | 1 - UefiPayloadPkg/SPI/mmio.c | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index 544558c5b1b8..ae2accefcd98 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -15,7 +15,6 @@ unsigned long int spi_get_bar(VOID) { if (!spi_base) spi_set_base((VOID *)lpc_get_spibase()); - ASSERT(spi_base); return spi_base; } diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c index acaeac89b75e..031545f3836a 100644 --- a/UefiPayloadPkg/SPI/mmio.c +++ b/UefiPayloadPkg/SPI/mmio.c @@ -5,6 +5,7 @@ #include #include "endian.h" +#include "mmio.h" static inline uint8_t read8(const void *addr) { From 14d7859fff90d913ccbbad9b63ef86c6212ce59a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:28:29 +0200 Subject: [PATCH 225/297] fix types --- UefiPayloadPkg/SPI/mmio.c | 12 ++++++------ UefiPayloadPkg/SPI/mmio.h | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c index 031545f3836a..9053da5460cf 100644 --- a/UefiPayloadPkg/SPI/mmio.c +++ b/UefiPayloadPkg/SPI/mmio.c @@ -7,32 +7,32 @@ #include "endian.h" #include "mmio.h" -static inline uint8_t read8(const void *addr) +static inline UINT8 read8(CONST VOID *addr) { return *(volatile uint8_t *)addr; } -static inline uint16_t read16(const void *addr) +static inline uint16_t read16(CONST VOID *addr) { return *(volatile uint16_t *)addr; } -static inline uint32_t read32(const void *addr) +static inline uint32_t read32(CONST VOID *addr) { return *(volatile uint32_t *)addr; } -static inline void write8(void *addr, uint8_t val) +static inline VOID write8(VOID *addr, uint8_t val) { *(volatile uint8_t *)addr = val; } -static inline void write16(void *addr, uint16_t val) +static inline VOID write16(VOID *addr, uint16_t val) { *(volatile uint16_t *)addr = val; } -static inline void write32(void *addr, uint32_t val) +static inline VOID write32(VOID *addr, uint32_t val) { *(volatile uint32_t *)addr = val; } diff --git a/UefiPayloadPkg/SPI/mmio.h b/UefiPayloadPkg/SPI/mmio.h index 9cba1afe9255..c90ce9b07b17 100644 --- a/UefiPayloadPkg/SPI/mmio.h +++ b/UefiPayloadPkg/SPI/mmio.h @@ -3,9 +3,9 @@ #include -static inline UINT8 read8(const VOID *addr); -static inline UINT16 read16(const VOID *addr); -static inline UINT32 read32(const VOID *addr); +static inline UINT8 read8(CONST VOID *addr); +static inline UINT16 read16(CONST VOID *addr); +static inline UINT32 read32(CONST VOID *addr); static inline VOID write8(VOID *addr, UINT8 val); static inline VOID write16(VOID *addr, UINT16 val); static inline VOID write32(VOID *addr, UINT32 val); From 0fee4115536f64c2bf1801f8b83741cc0d1ca468 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:32:22 +0200 Subject: [PATCH 226/297] fix types 2 --- UefiPayloadPkg/SPI/mmio.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c index 9053da5460cf..bf9d1131c48e 100644 --- a/UefiPayloadPkg/SPI/mmio.c +++ b/UefiPayloadPkg/SPI/mmio.c @@ -12,14 +12,14 @@ static inline UINT8 read8(CONST VOID *addr) return *(volatile uint8_t *)addr; } -static inline uint16_t read16(CONST VOID *addr) +static inline UINT16 read16(CONST VOID *addr) { - return *(volatile uint16_t *)addr; + return *(volatile UINT16 *)addr; } -static inline uint32_t read32(CONST VOID *addr) +static inline UINT32 read32(CONST VOID *addr) { - return *(volatile uint32_t *)addr; + return *(volatile UINT32 *)addr; } static inline VOID write8(VOID *addr, uint8_t val) @@ -27,12 +27,12 @@ static inline VOID write8(VOID *addr, uint8_t val) *(volatile uint8_t *)addr = val; } -static inline VOID write16(VOID *addr, uint16_t val) +static inline VOID write16(VOID *addr, UINT16 val) { - *(volatile uint16_t *)addr = val; + *(volatile UINT16 *)addr = val; } -static inline VOID write32(VOID *addr, uint32_t val) +static inline VOID write32(VOID *addr, UINT32 val) { - *(volatile uint32_t *)addr = val; + *(volatile UINT32 *)addr = val; } From 9cfce2921126786fb51ed2945a2af9d128181277 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:39:14 +0200 Subject: [PATCH 227/297] fix types 3 --- UefiPayloadPkg/SPI/mmio.c | 1 - 1 file changed, 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c index bf9d1131c48e..362b5ec2d8c2 100644 --- a/UefiPayloadPkg/SPI/mmio.c +++ b/UefiPayloadPkg/SPI/mmio.c @@ -4,7 +4,6 @@ */ #include -#include "endian.h" #include "mmio.h" static inline UINT8 read8(CONST VOID *addr) From bc79abeda99e4a6c6b75e95f1d5b6e5bb39fdad0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:42:26 +0200 Subject: [PATCH 228/297] fix --- UefiPayloadPkg/SPI/mmio.c | 48 +++++++++++++++++++-------------------- UefiPayloadPkg/SPI/mmio.h | 43 ++++++++++++++++++++++++++++++----- 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c index 362b5ec2d8c2..9d415ed449fc 100644 --- a/UefiPayloadPkg/SPI/mmio.c +++ b/UefiPayloadPkg/SPI/mmio.c @@ -6,32 +6,32 @@ #include #include "mmio.h" -static inline UINT8 read8(CONST VOID *addr) -{ - return *(volatile uint8_t *)addr; -} +// static inline UINT8 read8(CONST VOID *addr) +// { +// return *(volatile uint8_t *)addr; +// } -static inline UINT16 read16(CONST VOID *addr) -{ - return *(volatile UINT16 *)addr; -} +// static inline UINT16 read16(CONST VOID *addr) +// { +// return *(volatile UINT16 *)addr; +// } -static inline UINT32 read32(CONST VOID *addr) -{ - return *(volatile UINT32 *)addr; -} +// static inline UINT32 read32(CONST VOID *addr) +// { +// return *(volatile UINT32 *)addr; +// } -static inline VOID write8(VOID *addr, uint8_t val) -{ - *(volatile uint8_t *)addr = val; -} +// static inline VOID write8(VOID *addr, uint8_t val) +// { +// *(volatile uint8_t *)addr = val; +// } -static inline VOID write16(VOID *addr, UINT16 val) -{ - *(volatile UINT16 *)addr = val; -} +// static inline VOID write16(VOID *addr, UINT16 val) +// { +// *(volatile UINT16 *)addr = val; +// } -static inline VOID write32(VOID *addr, UINT32 val) -{ - *(volatile UINT32 *)addr = val; -} +// static inline VOID write32(VOID *addr, UINT32 val) +// { +// *(volatile UINT32 *)addr = val; +// } diff --git a/UefiPayloadPkg/SPI/mmio.h b/UefiPayloadPkg/SPI/mmio.h index c90ce9b07b17..3ede2f8fee77 100644 --- a/UefiPayloadPkg/SPI/mmio.h +++ b/UefiPayloadPkg/SPI/mmio.h @@ -3,11 +3,42 @@ #include -static inline UINT8 read8(CONST VOID *addr); -static inline UINT16 read16(CONST VOID *addr); -static inline UINT32 read32(CONST VOID *addr); -static inline VOID write8(VOID *addr, UINT8 val); -static inline VOID write16(VOID *addr, UINT16 val); -static inline VOID write32(VOID *addr, UINT32 val); +// static inline UINT8 read8(CONST VOID *addr); +// static inline UINT16 read16(CONST VOID *addr); +// static inline UINT32 read32(CONST VOID *addr); +// static inline VOID write8(VOID *addr, UINT8 val); +// static inline VOID write16(VOID *addr, UINT16 val); +// static inline VOID write32(VOID *addr, UINT32 val); + +static inline UINT8 read8(CONST VOID *addr) +{ + return *(volatile uint8_t *)addr; +} + +static inline UINT16 read16(CONST VOID *addr) +{ + return *(volatile UINT16 *)addr; +} + +static inline UINT32 read32(CONST VOID *addr) +{ + return *(volatile UINT32 *)addr; +} + +static inline VOID write8(VOID *addr, uint8_t val) +{ + *(volatile uint8_t *)addr = val; +} + +static inline VOID write16(VOID *addr, UINT16 val) +{ + *(volatile UINT16 *)addr = val; +} + +static inline VOID write32(VOID *addr, UINT32 val) +{ + *(volatile UINT32 *)addr = val; +} + #endif /* MMIO_H */ From 0fb36297b870b5e879fbe97990f8abdee83017e4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 08:44:46 +0200 Subject: [PATCH 229/297] fix type --- UefiPayloadPkg/SPI/mmio.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UefiPayloadPkg/SPI/mmio.h b/UefiPayloadPkg/SPI/mmio.h index 3ede2f8fee77..b74a9ecf24e5 100644 --- a/UefiPayloadPkg/SPI/mmio.h +++ b/UefiPayloadPkg/SPI/mmio.h @@ -12,7 +12,7 @@ static inline UINT8 read8(CONST VOID *addr) { - return *(volatile uint8_t *)addr; + return *(volatile UINT8 *)addr; } static inline UINT16 read16(CONST VOID *addr) @@ -25,9 +25,9 @@ static inline UINT32 read32(CONST VOID *addr) return *(volatile UINT32 *)addr; } -static inline VOID write8(VOID *addr, uint8_t val) +static inline VOID write8(VOID *addr, UINT8 val) { - *(volatile uint8_t *)addr = val; + *(volatile UINT8 *)addr = val; } static inline VOID write16(VOID *addr, UINT16 val) From f5422165c99373ed698c06b312cc330d62696053 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:04:01 +0200 Subject: [PATCH 230/297] fix inf --- UefiPayloadPkg/SPI/SPI.inf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index daed4872775a..49f62ea3a8f9 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -35,6 +35,10 @@ mmio.c stopwatch.h pci_devs.h + spi_flash.h + spi_flash.c + pci_ops.h + pci_ops.c [Packages] MdePkg/MdePkg.dec From 56707319d764a57ec255774de2c7f46e0b701a59 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:10:58 +0200 Subject: [PATCH 231/297] fixes --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 10 +++++----- UefiPayloadPkg/SPI/pci_ops.c | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index d7d8bf3d4f5e..da0ec2a5676d 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -6,7 +6,7 @@ /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ -UINT8 *const pci_mmconf = (VOID *)(uintptr_t)CONFIG_MMCONF_BASE_ADDRESS; +UINT8 *const pci_mmconf = (VOID *)(unsigned long int)CONFIG_MMCONF_BASE_ADDRESS; //extern UINT8 *const pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ @@ -39,10 +39,10 @@ UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; } -static __always_inline -void pci_mmio_write_config32(pci_devfn_t dev, uint16_t reg, uint32_t value) +static __attribute__ ((__always_inline__)) inline +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { - pcicfg(dev)->reg32[reg / sizeof(uint32_t)] = value; + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; } -#endif PCI_MMIO_CFG_H +#endif /* PCI_MMIO_CFG_H */ diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index 4d3f32711f5d..b0be4ef960a0 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -1,4 +1,5 @@ #include +#include #include "pci_ops.h" #include "pci_type.h" @@ -21,6 +22,7 @@ __attribute__ ((noreturn)) VOID pcidev_die(VOID) { die("PCI: dev is NULL!\n"); + while(1); } static __attribute__ ((__always_inline__)) inline @@ -38,7 +40,7 @@ UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) } static __attribute__ ((__always_inline__)) inline -void pci_s_write_config32(pci_devfn_t dev, uint16_t reg, UINT32 value) +void pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { pci_mmio_write_config32(dev, reg, value); } From 399e0accbb66373273bfa50c7a88baee057c142c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:38:47 +0200 Subject: [PATCH 232/297] dummy data to pci_mmconf --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index da0ec2a5676d..0f3ff02afeaa 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -6,7 +6,7 @@ /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ -UINT8 *const pci_mmconf = (VOID *)(unsigned long int)CONFIG_MMCONF_BASE_ADDRESS; +UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; //extern UINT8 *const pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ From 734e5cf9df43a799dcf84cf08ea6155b48de0cf1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:44:20 +0200 Subject: [PATCH 233/297] fix static --- UefiPayloadPkg/SPI/pci_ops.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 429857f24c48..6dde518e6f62 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -5,12 +5,12 @@ #include "device.h" #include "pci_type.h" -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); -pci_devfn_t pcidev_bdf(const struct device *dev); +static UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); +static pci_devfn_t pcidev_bdf(const struct device *dev); VOID pcidev_die(VOID); -pci_devfn_t pcidev_assert(CONST struct device *dev); -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); -void pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); -void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val); +static pci_devfn_t pcidev_assert(CONST struct device *dev); +static UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); +static void pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); +static void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val); #endif /* PCI_OPS_H */ From e2a0d95fad91c203ad5b68c88f865ea076526a3b Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:48:03 +0200 Subject: [PATCH 234/297] fix types --- UefiPayloadPkg/SPI/pci_ops.c | 6 +++--- UefiPayloadPkg/SPI/pci_ops.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index b0be4ef960a0..c8bdd90154ac 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -13,7 +13,7 @@ UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) } static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_bdf(const struct device *dev) +pci_devfn_t pcidev_bdf(CONST struct device *dev) { return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); } @@ -40,13 +40,13 @@ UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) } static __attribute__ ((__always_inline__)) inline -void pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) { pci_mmio_write_config32(dev, reg, value); } static __attribute__ ((__always_inline__)) inline -void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val) +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) { pci_s_write_config32(PCI_BDF(dev), reg, val); } diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 6dde518e6f62..8e03712d2d8a 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -6,11 +6,11 @@ #include "pci_type.h" static UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); -static pci_devfn_t pcidev_bdf(const struct device *dev); +static pci_devfn_t pcidev_bdf(CONST struct device *dev); VOID pcidev_die(VOID); static pci_devfn_t pcidev_assert(CONST struct device *dev); static UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); -static void pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); -static void pci_write_config32(const struct device *dev, UINT16 reg, UINT32 val); +static VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); +static VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val); #endif /* PCI_OPS_H */ From c477d7b7f391bc1222f4cd38139c1d3f45dacda7 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:51:06 +0200 Subject: [PATCH 235/297] fix definitions --- UefiPayloadPkg/SPI/pci_ops.c | 88 ++++++++++++++++++------------------ UefiPayloadPkg/SPI/pci_ops.h | 61 +++++++++++++++++++++---- 2 files changed, 97 insertions(+), 52 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index c8bdd90154ac..ca1d646efbd6 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -6,47 +6,47 @@ #include "device.h" #include "pci_mmio_cfg.h" -static __attribute__ ((__always_inline__)) inline -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_bdf(CONST struct device *dev) -{ - return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -} - -__attribute__ ((noreturn)) -VOID pcidev_die(VOID) -{ - die("PCI: dev is NULL!\n"); - while(1); -} - -static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_assert(CONST struct device *dev) -{ - if (!dev) - pcidev_die(); - return pcidev_bdf(dev); -} - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -{ - return pci_s_read_config32(PCI_BDF(dev), reg); -} - -static __attribute__ ((__always_inline__)) inline -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pci_mmio_write_config32(dev, reg, value); -} - -static __attribute__ ((__always_inline__)) inline -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -{ - pci_s_write_config32(PCI_BDF(dev), reg, val); -} +// static __attribute__ ((__always_inline__)) inline +// UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +// { +// return pci_mmio_read_config32(dev, reg); +// } + +// static __attribute__ ((__always_inline__)) inline +// pci_devfn_t pcidev_bdf(CONST struct device *dev) +// { +// return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +// } + +// __attribute__ ((noreturn)) +// VOID pcidev_die(VOID) +// { +// die("PCI: dev is NULL!\n"); +// while(1); +// } + +// static __attribute__ ((__always_inline__)) inline +// pci_devfn_t pcidev_assert(CONST struct device *dev) +// { +// if (!dev) +// pcidev_die(); +// return pcidev_bdf(dev); +// } + +// static __attribute__ ((__always_inline__)) inline +// UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +// { +// return pci_s_read_config32(PCI_BDF(dev), reg); +// } + +// static __attribute__ ((__always_inline__)) inline +// VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +// { +// pci_mmio_write_config32(dev, reg, value); +// } + +// static __attribute__ ((__always_inline__)) inline +// VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) +// { +// pci_s_write_config32(PCI_BDF(dev), reg, val); +// } diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 8e03712d2d8a..964d9c4698c4 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -1,16 +1,61 @@ #ifndef PCI_OPS_H #define PCI_OPS_H +// #include +// #include "device.h" +// #include "pci_type.h" + #include -#include "device.h" +#include + +#include "pci_ops.h" #include "pci_type.h" +#include "device.h" +#include "pci_mmio_cfg.h" + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +static __attribute__ ((__always_inline__)) inline +pci_devfn_t pcidev_bdf(CONST struct device *dev) +{ + return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +} + +__attribute__ ((noreturn)) +VOID pcidev_die(VOID) +{ + die("PCI: dev is NULL!\n"); + while(1); +} + +static __attribute__ ((__always_inline__)) inline +pci_devfn_t pcidev_assert(CONST struct device *dev) +{ + if (!dev) + pcidev_die(); + return pcidev_bdf(dev); +} + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +{ + return pci_s_read_config32(PCI_BDF(dev), reg); +} + +static __attribute__ ((__always_inline__)) inline +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pci_mmio_write_config32(dev, reg, value); +} -static UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); -static pci_devfn_t pcidev_bdf(CONST struct device *dev); -VOID pcidev_die(VOID); -static pci_devfn_t pcidev_assert(CONST struct device *dev); -static UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); -static VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); -static VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val); +static __attribute__ ((__always_inline__)) inline +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) +{ + pci_s_write_config32(PCI_BDF(dev), reg, val); +} #endif /* PCI_OPS_H */ From bb64d3fae069bd88a0faabd17b86e4b11a764067 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:54:57 +0200 Subject: [PATCH 236/297] fix --- UefiPayloadPkg/SPI/pci_ops.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 964d9c4698c4..ea6a30fc93aa 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -28,7 +28,8 @@ pci_devfn_t pcidev_bdf(CONST struct device *dev) __attribute__ ((noreturn)) VOID pcidev_die(VOID) { - die("PCI: dev is NULL!\n"); + //die("PCI: dev is NULL!\n"); + DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); while(1); } From b8e1438ff5c3846fe202c30f5ea1a7feec19a485 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 09:58:31 +0200 Subject: [PATCH 237/297] fix 1 --- UefiPayloadPkg/SPI/pci_ops.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index ca1d646efbd6..a28d799e39e8 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -1,10 +1,10 @@ -#include -#include +// #include +// #include -#include "pci_ops.h" -#include "pci_type.h" -#include "device.h" -#include "pci_mmio_cfg.h" +// #include "pci_ops.h" +// #include "pci_type.h" +// #include "device.h" +// #include "pci_mmio_cfg.h" // static __attribute__ ((__always_inline__)) inline // UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) From 932dc18a7df86c9a57947686287913d8c4abc845 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 10:03:03 +0200 Subject: [PATCH 238/297] fix 2 --- UefiPayloadPkg/SPI/SPI.inf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 49f62ea3a8f9..e81a33ef9aaf 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -38,7 +38,7 @@ spi_flash.h spi_flash.c pci_ops.h - pci_ops.c + # pci_ops.c [Packages] MdePkg/MdePkg.dec From 4f70b5439b9605d9a3a6529184af409db887dfa4 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 10:05:22 +0200 Subject: [PATCH 239/297] fix 3 --- UefiPayloadPkg/SPI/pci_ops.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index ea6a30fc93aa..1337142b4545 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -25,19 +25,21 @@ pci_devfn_t pcidev_bdf(CONST struct device *dev) return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); } -__attribute__ ((noreturn)) -VOID pcidev_die(VOID) -{ - //die("PCI: dev is NULL!\n"); - DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); - while(1); -} +// __attribute__ ((noreturn)) +// VOID pcidev_die(VOID) +// { +// //die("PCI: dev is NULL!\n"); +// DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); +// while(1); +// } static __attribute__ ((__always_inline__)) inline pci_devfn_t pcidev_assert(CONST struct device *dev) { - if (!dev) - pcidev_die(); + if (!dev) { + DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); + while(1); + } return pcidev_bdf(dev); } From 8a7993306f1159b1de96e31b627070c9e1c4aa67 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 10:08:33 +0200 Subject: [PATCH 240/297] fix 4 --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 0f3ff02afeaa..01d4368c8989 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -6,8 +6,8 @@ /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ -UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; -//extern UINT8 *const pci_mmconf; +//UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; +extern UINT8 *const pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ * qualify for pointer aliasing with any other objects in memory. From 61f3fc88f6cb8da762335a8b77ee9df58adea482 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 10:13:46 +0200 Subject: [PATCH 241/297] fix compilation errors --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 01d4368c8989..4ddff58f0140 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -7,7 +7,7 @@ /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we * prevent some sub-optimal constant folding. */ //UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; -extern UINT8 *const pci_mmconf; +//extern UINT8 *const pci_mmconf; /* Using a unique datatype for MMIO writes makes the pointers to _not_ * qualify for pointer aliasing with any other objects in memory. @@ -30,7 +30,8 @@ union pci_bank { static __attribute__ ((__always_inline__)) inline volatile union pci_bank *pcicfg(pci_devfn_t dev) { - return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; + return ((VOID *)0xBAADF00D)[PCI_DEVFN_OFFSET(dev)]; + //return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } static __attribute__ ((__always_inline__)) inline From 44841aea9e42501bb9c96b6cebeda53922d8e7f7 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 10:19:09 +0200 Subject: [PATCH 242/297] fix compilation errors 2 --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 4ddff58f0140..9d470965ddb8 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -30,8 +30,8 @@ union pci_bank { static __attribute__ ((__always_inline__)) inline volatile union pci_bank *pcicfg(pci_devfn_t dev) { - return ((VOID *)0xBAADF00D)[PCI_DEVFN_OFFSET(dev)]; - //return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; + UINT8 *CONST pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; + return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } static __attribute__ ((__always_inline__)) inline From 70483fa7c345877cf06c3fcc31ddb14b404b8ee3 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 10:48:32 +0200 Subject: [PATCH 243/297] dummy change --- UefiPayloadPkg/SPI/pci_ops.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 1337142b4545..59ab0a7c432c 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -37,7 +37,7 @@ static __attribute__ ((__always_inline__)) inline pci_devfn_t pcidev_assert(CONST struct device *dev) { if (!dev) { - DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!!!", __FUNCTION__)); while(1); } return pcidev_bdf(dev); From fe065b50168509a8f1078cee4f383b62c23b6237 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 11:00:46 +0200 Subject: [PATCH 244/297] debug --- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 2 ++ UefiPayloadPkg/SPI/pci_ops.h | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 9d470965ddb8..75b565dd99b9 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -2,6 +2,7 @@ #define PCI_MMIO_CFG_H #include +#include #include "pci_type.h" /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we @@ -30,6 +31,7 @@ union pci_bank { static __attribute__ ((__always_inline__)) inline volatile union pci_bank *pcicfg(pci_devfn_t dev) { + DEBUG((EFI_D_INFO, "%a: Access to BAADF00D!!!", __FUNCTION__)); UINT8 *CONST pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 59ab0a7c432c..1337142b4545 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -37,7 +37,7 @@ static __attribute__ ((__always_inline__)) inline pci_devfn_t pcidev_assert(CONST struct device *dev) { if (!dev) { - DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!!!", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); while(1); } return pcidev_bdf(dev); From 90a26d76cacf43266196b39047333cbc66bcad8d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 11:15:54 +0200 Subject: [PATCH 245/297] REMOVE PROTOCOL INSTALL --- UefiPayloadPkg/SPI/SPI_fvb.c | 26 +++++++++++++------------- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 5 +++-- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index b006091a83e7..064474250dee 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -17,14 +17,14 @@ EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - NULL, //FvbGetAttributes, // GetAttributes - NULL, //FvbSetAttributes, // SetAttributes - NULL, //FvbGetPhysicalAddress, // GetPhysicalAddress - NULL, //FvbGetBlockSize, // GetBlockSize - NULL, //FvbRead, // Read - NULL, //FvbWrite, // Write - NULL, //FvbEraseBlocks, // EraseBlocks - NULL, //ParentHandle + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL //ParentHandle }; void * memset (void *dest, int ch, __SIZE_TYPE__ count) @@ -45,11 +45,11 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); + // Status = gBS->InstallMultipleProtocolInterfaces ( + // &Handle, + // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + // NULL + // ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 75b565dd99b9..cacc93ebd2c5 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -31,9 +31,10 @@ union pci_bank { static __attribute__ ((__always_inline__)) inline volatile union pci_bank *pcicfg(pci_devfn_t dev) { - DEBUG((EFI_D_INFO, "%a: Access to BAADF00D!!!", __FUNCTION__)); + /*DEBUG((EFI_D_INFO, "%a: Access to BAADF00D!!!", __FUNCTION__)); UINT8 *CONST pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; - return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; + return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)];*/ + return NULL; } static __attribute__ ((__always_inline__)) inline From 40b62f40e17f418857da0212fdeb3c3216603a10 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 30 Sep 2020 15:22:46 +0200 Subject: [PATCH 246/297] UefiPayloadPkg/SPI/*: Port SPI controller, Initialize PcdFlashNvStorage, remove SMMStore from build --- .../Variable/RuntimeDxe/VariableNonVolatile.c | 34 +++++ .../RuntimeDxe/VariableRuntimeDxe.inf | 6 + .../Variable/RuntimeDxe/VariableSmm.inf | 8 ++ .../RuntimeDxe/VariableStandaloneMm.inf | 6 + .../BlSMMStoreDxe/BlSMMStoreDxe.inf | 1 - UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 118 ++++++++++++++++++ UefiPayloadPkg/SPI/SPI.inf | 3 +- UefiPayloadPkg/SPI/SPI_fvb.c | 37 ++++-- UefiPayloadPkg/UefiPayloadPkg.fdf | 8 +- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 14 +-- UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 12 -- 11 files changed, 201 insertions(+), 46 deletions(-) create mode 100644 UefiPayloadPkg/SPI/BlSMMStoreDxe.h diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c index 0637a828b33f..a798370c1bc1 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c @@ -6,6 +6,14 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ +#include +#include +#include +#include +#include +#include +//#include + #include "VariableNonVolatile.h" #include "VariableParsing.h" @@ -117,6 +125,16 @@ InitEmuNonVolatileVariableStore ( return EFI_SUCCESS; } +typedef struct { + UINT64 ComBuffer; + UINT32 ComBufferSize; + UINT32 NumBlocks; + UINT32 BlockSize; + UINT64 MmioAddress; + UINT8 ApmCmd; + UINT8 Reserved0[3]; +} SMMSTORE_INFO; + /** Init real non-volatile variable store. @@ -160,6 +178,22 @@ InitRealNonVolatileVariableStore ( return EFI_OUT_OF_RESOURCES; } + DEBUG((EFI_D_INFO, "Updating HOB\n")); + SMMSTORE_INFO *SMMStoreInfoHob; + SMMStoreInfoHob = AllocateRuntimePool (GET_GUID_HOB_DATA_SIZE(GuidHob)); + // Update PCDs for Variable/RuntimeDxe + CopyMem(SMMStoreInfoHob, GET_GUID_HOB_DATA (GuidHob), GET_GUID_HOB_DATA_SIZE(GuidHob)); + DEBUG((EFI_D_INFO, "PcdGet32 (PcdFlashNvStorageVariableBase) = 0x%X\n", PcdGet32 (PcdFlashNvStorageVariableBase))); + DEBUG((EFI_D_INFO, "PcdGet32 (PcdFlashNvStorageFtwWorkingBase) = 0x%X\n", PcdGet32 (PcdFlashNvStorageFtwWorkingBase))); + DEBUG((EFI_D_INFO, "PcdGet32 (PcdFlashNvStorageFtwSpareBase) = 0x%X\n", PcdGet32 (PcdFlashNvStorageFtwSpareBase))); + DEBUG((EFI_D_INFO, "SMMStoreInfoHob->MmioAddress = 0x%X\n", SMMStoreInfoHob->MmioAddress)); + PcdSet32S (PcdFlashNvStorageVariableBase, + PcdGet32 (PcdFlashNvStorageVariableBase) + SMMStoreInfoHob->MmioAddress); + PcdSet32S (PcdFlashNvStorageFtwWorkingBase, + PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + SMMStoreInfoHob->MmioAddress); + PcdSet32S (PcdFlashNvStorageFtwSpareBase, + PcdGet32 (PcdFlashNvStorageFtwSpareBase) + SMMStoreInfoHob->MmioAddress); + NvStorageBase = NV_STORAGE_VARIABLE_BASE; ASSERT (NvStorageBase != 0); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index ceea5d1ff9ac..3683b4fa7efd 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -135,6 +135,12 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf index bc3033588d40..591dc13b5b83 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf @@ -138,6 +138,14 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## SOMETIMES_CONSUMES + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index 6e17f6cdf588..a0776cecd5cd 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -135,5 +135,11 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + [Depex] TRUE diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf index 49d5f1a3ff39..38be5b9202ba 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf @@ -31,7 +31,6 @@ BaseLib DebugLib HobLib - SmmStoreLib UefiLib UefiDriverEntryPoint UefiBootServicesTableLib diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h new file mode 100644 index 000000000000..92d937cc0c31 --- /dev/null +++ b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h @@ -0,0 +1,118 @@ +/** @file BlSMMStoreDxe.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __COREBOOT_SMM_STORE_DXE_H__ +#define __COREBOOT_SMM_STORE_DXE_H__ + + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) + +typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT8 Index; + EFI_DEVICE_PATH_PROTOCOL End; +} NOR_FLASH_DEVICE_PATH; +#pragma pack () + +struct _SMMSTORE_INSTANCE { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; + + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + + NOR_FLASH_DEVICE_PATH DevicePath; +}; + +// +// BlSMMStoreFvbDxe.c +// + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ); + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbWrite( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + + +#endif /* __COREBOOT_SMM_STORE_DXE_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index e81a33ef9aaf..d579a7127bfd 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -11,7 +11,7 @@ INF_VERSION = 0x00010005 BASE_NAME = SPI FILE_GUID = c2c2e656-ee66-41e0-bee3-29c6f16f49c0 - MODULE_TYPE = DXE_DRIVER + MODULE_TYPE = DXE_RUNTIME_DRIVER VERSION_STRING = 1.0 ENTRY_POINT = SPIInitialize @@ -50,7 +50,6 @@ UefiDriverEntryPoint DebugLib BaseMemoryLib - SmmStoreLib HobLib [Guids] diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 064474250dee..df67864b7c1c 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -15,15 +15,27 @@ #include #include "SPIgeneric.h" + + +#include +#include +#include +#include +#include +#include +#include + +#include "BlSMMStoreDxe.h" + EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks + NULL,// FvbGetAttributes, // GetAttributes + NULL,// FvbSetAttributes, // SetAttributes + NULL,// FvbGetPhysicalAddress, // GetPhysicalAddress + NULL,// FvbGetBlockSize, // GetBlockSize + NULL,// FvbRead, // Read + NULL,// FvbWrite, // Write + NULL,// FvbEraseBlocks, // EraseBlocks NULL //ParentHandle }; @@ -43,13 +55,14 @@ EFI_STATUS EFIAPI SPIInitialize ( EFI_STATUS Status; struct spi_slave slave; DEBUG((EFI_D_INFO, "SPI IS HERE\n")); + DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - // Status = gBS->InstallMultipleProtocolInterfaces ( - // &Handle, - // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - // NULL - // ); + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); } else { diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index ec2c12dd468f..fea6937cd28f 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -83,10 +83,7 @@ APRIORI DXE { INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf -!if $(BOOTLOADER) == "COREBOOT" - # Initialize VariableStore and update PCDs before VariableRuntimeDxe - INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif + # Init Test Driver before Secure Boot # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf @@ -127,9 +124,6 @@ INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf INF MdeModulePkg/Logo/LogoDxe.inf -!if $(BOOTLOADER) == "COREBOOT" -INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif # # PCI Support diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 505122e91673..bf6bf6242a69 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -152,6 +152,8 @@ PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf + SafeIntLib|MdePkg/Library/BaseSafeIntLib/BaseSafeIntLib.inf + BmpSupportLib|MdeModulePkg/Library/BaseBmpSupportLib/BaseBmpSupportLib.inf # # UEFI & PI @@ -247,12 +249,6 @@ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif -!if $(BOOTLOADER) == "COREBOOT" - SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf -!else - SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf -!endif - !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf @@ -625,12 +621,6 @@ UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf - # SMMSTORE - # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif - # # Network Support # diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 0436b1804530..7faf2edf169a 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -257,11 +257,6 @@ !else AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif -!if $(BOOTLOADER) == "COREBOOT" - SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf -!else - SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf -!endif !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf @@ -630,13 +625,6 @@ UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf - # - # SMMSTORE - # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif - # # Network Support # From f41dfe17a82f8800f380c223c95b2e3baf601e08 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 5 Oct 2020 14:38:48 +0200 Subject: [PATCH 247/297] efiPayloadPkg/SPI/fch_spi_ctrl.c: implement SPI xfer and xfer_vector --- .../BlSMMStoreDxe/BlSMMStoreDxe.inf | 1 + UefiPayloadPkg/SPI/SPI_fvb.c | 43 +++++++++++++------ UefiPayloadPkg/SPI/SPIgeneric.c | 7 ++- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 2 + UefiPayloadPkg/SPI/fch_spi_ctrl.h | 14 +++--- UefiPayloadPkg/SPI/fch_spi_util.c | 8 +++- UefiPayloadPkg/SPI/lpc.c | 1 + UefiPayloadPkg/UefiPayloadPkg.fdf | 8 +++- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 11 +++++ UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 12 ++++++ 10 files changed, 83 insertions(+), 24 deletions(-) diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf index 38be5b9202ba..49d5f1a3ff39 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf @@ -31,6 +31,7 @@ BaseLib DebugLib HobLib + SmmStoreLib UefiLib UefiDriverEntryPoint UefiBootServicesTableLib diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index df67864b7c1c..69cdfe322959 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -14,8 +14,7 @@ #include #include #include "SPIgeneric.h" - - +#include "fch_spi_ctrl.h" #include #include @@ -52,26 +51,28 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + // EFI_STATUS Status; struct spi_slave slave; - DEBUG((EFI_D_INFO, "SPI IS HERE\n")); + DEBUG((EFI_D_INFO, "SPI IS HERE 2\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); - if(EFI_ERROR (Status)) { - DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - } else { - DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); - } + // Status = gBS->InstallMultipleProtocolInterfaces ( + // &Handle, + // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + // NULL + // ); + // DEBUG((EFI_D_INFO, "\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.")); + // if(EFI_ERROR (Status)) { + // DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + // } else { + // DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); + // } DEBUG((EFI_D_INFO, "calling spi_init()\n")); spi_init(); DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); + DEBUG((EFI_D_INFO, "0x%X\n", slave.ctrlr->xfer)); /*----------------------------------------------------------------------- * SPI transfer * @@ -88,7 +89,21 @@ EFI_STATUS EFIAPI SPIInitialize ( * * Returns: 0 on success, not 0 on failure */ +// struct spi_op { +// const VOID *dout; +// __SIZE_TYPE__ bytesout; +// VOID *din; +// __SIZE_TYPE__ bytesin; +// enum spi_op_status status; +// }; + struct spi_op vector = { + .dout = "asdf", + .bytesout = 4, + }; char fill[255]; DEBUG((EFI_D_INFO, "spi_xfer() returned 0x%X\n", spi_xfer(&slave, "asdf", 4, &fill, 0))); + DEBUG((EFI_D_INFO, "spi_xfer_vectors() returned 0x%X\n", spi_xfer_vector(&slave, &vector, 1))); + // int spi_xfer_vector(const struct spi_slave *slave, + // struct spi_op vectors[], __SIZE_TYPE__ count) return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 53421cee9b83..f8285adbe77c 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include +#include #include "SPIgeneric.h" #include "own.h" @@ -68,8 +69,12 @@ UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, __SIZE_TYPE__ b { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; - if (ctrlr && ctrlr->xfer) + if (ctrlr && ctrlr->xfer) { + DEBUG((EFI_D_INFO, "xfer available\n")); return ctrlr->xfer(slave, dout, bytesout, din, bytesin); + } else { + DEBUG((EFI_D_INFO, "xfer failed\n")); + } return -1; } diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index 186b0948d400..8aae82644df0 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -94,6 +94,7 @@ static int execute_command(VOID) VOID spi_init(VOID) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); DEBUG((EFI_D_INFO, "%a: %s: SPI BAR at 0x%08lx\n", __FUNCTION__, __func__, spi_get_bar())); } @@ -260,6 +261,7 @@ static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct reg } static CONST struct spi_ctrlr fch_spi_flash_ctrlr = { + .xfer = spi_ctrlr_xfer, .xfer_vector = xfer_vectors, .max_xfer_size = SPI_FIFO_DEPTH, .flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN, diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.h b/UefiPayloadPkg/SPI/fch_spi_ctrl.h index 37abd89bbf14..62a113402c0c 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.h +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.h @@ -10,15 +10,15 @@ #include "fch_spi_util.h" #include "SPIgeneric.h" -static VOID dump_state(CONST char *str, UINT8 phase); -static int wait_for_ready(VOID); -static int execute_command(VOID); +VOID dump_state(CONST char *str, UINT8 phase); +int wait_for_ready(VOID); +int execute_command(VOID); VOID spi_init(VOID); -static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, +int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); -static int xfer_vectors(CONST struct spi_slave *slave, +int xfer_vectors(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count); -static int protect_a_range(UINT32 value); +int protect_a_range(UINT32 value); /* * Protect range of SPI flash defined by region using the SPI flash controller. @@ -33,7 +33,7 @@ static int protect_a_range(UINT32 value); * and second region is read protection, it's best to define first region as read and write * protection. */ -static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, +int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, CONST enum ctrlr_prot_type type); #endif /* FCH_SPI_CTRL_H */ diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index ae2accefcd98..a3dfb3ff8d3b 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -4,15 +4,21 @@ #include "fch_spi_util.h" #include "lpc.h" -static unsigned long int spi_base; +#include +#include +#include "fch_spi_ctrl.h" + +static unsigned long int spi_base = 0xBAADF00D; VOID spi_set_base(VOID *base) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); spi_base = (unsigned long int)base; } unsigned long int spi_get_bar(VOID) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); if (!spi_base) spi_set_base((VOID *)lpc_get_spibase()); diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index b47d5659f38c..dc1e3fe7b156 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -6,6 +6,7 @@ unsigned long int lpc_get_spibase(void) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT32 base; base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index fea6937cd28f..cb7d787f0f25 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -83,7 +83,10 @@ APRIORI DXE { INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf - + !if $(BOOTLOADER) == "COREBOOT" + # Initialize VariableStore and update PCDs before VariableRuntimeDxe + INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf + !endif # Init Test Driver before Secure Boot # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf @@ -124,6 +127,9 @@ INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf INF MdeModulePkg/Logo/LogoDxe.inf +!if $(BOOTLOADER) == "COREBOOT" + INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +!endif # # PCI Support diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index bf6bf6242a69..e9b22230902e 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -249,6 +249,12 @@ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif +!if $(BOOTLOADER) == "COREBOOT" + SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf +!else + SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf +!endif + !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf @@ -620,6 +626,11 @@ !endif UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf + # SMMSTORE + # + !if $(BOOTLOADER) == "COREBOOT" + UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf + !endif # # Network Support diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 7faf2edf169a..0436b1804530 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -257,6 +257,11 @@ !else AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif +!if $(BOOTLOADER) == "COREBOOT" + SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf +!else + SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf +!endif !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf @@ -625,6 +630,13 @@ UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf + # + # SMMSTORE + # +!if $(BOOTLOADER) == "COREBOOT" + UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +!endif + # # Network Support # From cd6c2b57693e20848109ca8479c025ed03f0cacb Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 6 Oct 2020 15:02:07 +0200 Subject: [PATCH 248/297] UefiPayloadPkg/SPI*: Fix missing SPI BAR address and start porting winbond and adesto --- UefiPayloadPkg/SPI/Fvb.c | 403 +++++++++++++ UefiPayloadPkg/SPI/Fvb.h | 87 +++ UefiPayloadPkg/SPI/SPI.inf | 2 + UefiPayloadPkg/SPI/SPI_fvb.c | 57 +- UefiPayloadPkg/SPI/adesto.c | 100 ++++ UefiPayloadPkg/SPI/fch_spi_util.c | 2 +- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 6 +- UefiPayloadPkg/SPI/spi_flash copy.c | 761 ++++++++++++++++++++++++ UefiPayloadPkg/SPI/spi_flash_internal.h | 128 ++++ UefiPayloadPkg/SPI/spi_winbond.h | 23 + UefiPayloadPkg/SPI/winbond.c | 536 +++++++++++++++++ 11 files changed, 2065 insertions(+), 40 deletions(-) create mode 100644 UefiPayloadPkg/SPI/Fvb.c create mode 100644 UefiPayloadPkg/SPI/Fvb.h create mode 100644 UefiPayloadPkg/SPI/adesto.c create mode 100644 UefiPayloadPkg/SPI/spi_flash copy.c create mode 100644 UefiPayloadPkg/SPI/spi_flash_internal.h create mode 100644 UefiPayloadPkg/SPI/spi_winbond.h create mode 100644 UefiPayloadPkg/SPI/winbond.c diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c new file mode 100644 index 000000000000..f09b82d59964 --- /dev/null +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -0,0 +1,403 @@ +#include "BlSMMStoreDxe.h" +#include "Fvb.h" + + +// STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; +// STATIC UINTN mFlashNvStorageVariableBase; + +/// +/// The Firmware Volume Block Protocol is the low-level interface +/// to a firmware volume. File-level access to a firmware volume +/// should not be done using the Firmware Volume Block Protocol. +/// Normal access to a firmware volume must use the Firmware +/// Volume Protocol. Typically, only the file system driver that +/// produces the Firmware Volume Protocol will bind to the +/// Firmware Volume Block Protocol. +/// + +/** + Initialises the FV Header and Variable Store Header + to support variable operations. + + @param[in] Ptr - Location to initialise the headers + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN SMMSTORE_INSTANCE *Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + Check the integrity of firmware volume header. + + @param[in] FwVolHeader - A pointer to a firmware volume header + + @retval EFI_SUCCESS - The firmware volume is consistent + @retval EFI_NOT_FOUND - The firmware volume has been corrupted. + +**/ +EFI_STATUS +ValidateFvHeader ( + IN SMMSTORE_INSTANCE *Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + The GetAttributes() function retrieves the attributes and + current settings of the block. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and + current settings are returned. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + **/ +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + The SetAttributes() function sets configurable firmware volume attributes + and returns the new settings of the firmware volume. + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 + that contains the desired firmware volume settings. + On successful return, it contains the new settings of + the firmware volume. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities + as declared in the firmware volume header. + + **/ +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + The GetPhysicalAddress() function retrieves the base address of + a memory-mapped firmware volume. This function should be called + only for memory-mapped firmware volumes. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), contains the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. + + **/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + The GetBlockSize() function retrieves the size of the requested + block. It also returns the number of additional blocks with + the identical size. The GetBlockSize() function is used to + retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba Indicates the block for which to return the size. + + @param BlockSize Pointer to a caller-allocated UINTN in which + the size of the block is returned. + + @param NumberOfBlocks Pointer to a caller-allocated UINTN in + which the number of consecutive blocks, + starting with Lba, is returned. All + blocks in this range have a size of + BlockSize. + + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + + **/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + Reads the specified number of bytes into a buffer from the specified block. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + Implementations should be mindful that the firmware volume + might be in the ReadDisabled state. If it is in this state, + the Read() function must return the status code + EFI_ACCESS_DENIED without modifying the contents of the + buffer. The Read() function must also prevent spanning block + boundaries. If a read is requested that would span a block + boundary, the read must read up to the boundary but not + beyond. The output parameter NumBytes must be set to correctly + indicate the number of bytes actually read. The caller must be + aware that a read may be partially completed. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index from which to read. + + @param Offset Offset into the block at which to begin reading. + + @param NumBytes Pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes read. + + @param Buffer Pointer to a caller-allocated buffer that will be used + to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read successfully, and contents are + in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + returned in Buffer. + + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. + + **/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINTN BlockSize; + SMMSTORE_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return EFI_DEVICE_ERROR; + //return SMMStoreRead (Lba, Offset, NumBytes, Buffer); +} + +/** + Writes the specified number of bytes from the input buffer to the block. + + The Write() function writes the specified number of bytes from + the provided buffer to the specified block and offset. If the + firmware volume is sticky write, the caller must ensure that + all the bits of the specified range to write are in the + EFI_FVB_ERASE_POLARITY state before calling the Write() + function, or else the result will be unpredictable. This + unpredictability arises because, for a sticky-write firmware + volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY + state but cannot flip it back again. Before calling the + Write() function, it is recommended for the caller to first call + the EraseBlocks() function to erase the specified block to + write. A block erase cycle will transition bits from the + (NOT)EFI_FVB_ERASE_POLARITY state back to the + EFI_FVB_ERASE_POLARITY state. Implementations should be + mindful that the firmware volume might be in the WriteDisabled + state. If it is in this state, the Write() function must + return the status code EFI_ACCESS_DENIED without modifying the + contents of the firmware volume. The Write() function must + also prevent spanning block boundaries. If a write is + requested that spans a block boundary, the write must store up + to the boundary but not beyond. The output parameter NumBytes + must be set to correctly indicate the number of bytes actually + written. The caller must be aware that a write may be + partially completed. All writes, partial or otherwise, must be + fully flushed to the hardware before the Write() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index to write to. + + @param Offset Offset into the block at which to begin writing. + + @param NumBytes The pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes actually written. + + @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully. + + @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + actually written. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. + + + **/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + Erases and initialises a firmware volume block. + + The EraseBlocks() function erases one or more blocks as denoted + by the variable argument list. The entire parameter list of + blocks must be verified before erasing any blocks. If a block is + requested that does not exist within the associated firmware + volume (it has a larger index than the last block of the + firmware volume), the EraseBlocks() function must return the + status code EFI_INVALID_PARAMETER without modifying the contents + of the firmware volume. Implementations should be mindful that + the firmware volume might be in the WriteDisabled state. If it + is in this state, the EraseBlocks() function must return the + status code EFI_ACCESS_DENIED without modifying the contents of + the firmware volume. All calls to EraseBlocks() must be fully + flushed to the hardware before the EraseBlocks() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + instance. + + @param ... The variable argument list is a list of tuples. + Each tuple describes a range of LBAs to erase + and consists of the following: + - An EFI_LBA that indicates the starting LBA + - A UINTN that indicates the number of blocks to erase. + + The list is terminated with an EFI_LBA_LIST_TERMINATOR. + For example, the following indicates that two ranges of blocks + (5-7 and 10-11) are to be erased: + EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); + + @retval EFI_SUCCESS The erase request successfully completed. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. + The firmware device may have been partially erased. + + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do + not exist in the firmware volume. + + **/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +FvbVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); +} + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; +} diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h new file mode 100644 index 000000000000..ea662a93438c --- /dev/null +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -0,0 +1,87 @@ +#ifndef FVB_H +#define FVB_H + +#include "BlSMMStoreDxe.h" + +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN SMMSTORE_INSTANCE *Instance + ); + +EFI_STATUS +ValidateFvHeader ( + IN SMMSTORE_INSTANCE *Instance + ); + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + + +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + +VOID +EFIAPI +FvbVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +EFI_STATUS +EFIAPI +SMMStoreFvbInitialize ( + IN SMMSTORE_INSTANCE* Instance + ); + +#endif /* FVB_H */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index d579a7127bfd..9f487a82424d 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -39,6 +39,8 @@ spi_flash.c pci_ops.h # pci_ops.c + Fvb.h + Fvb.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 69cdfe322959..0a9fecfc171b 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -13,29 +13,26 @@ #include #include #include -#include "SPIgeneric.h" -#include "fch_spi_ctrl.h" - #include #include -#include #include -#include #include #include - +#include "SPIgeneric.h" +#include "fch_spi_ctrl.h" #include "BlSMMStoreDxe.h" +#include "Fvb.h" EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - NULL,// FvbGetAttributes, // GetAttributes - NULL,// FvbSetAttributes, // SetAttributes - NULL,// FvbGetPhysicalAddress, // GetPhysicalAddress - NULL,// FvbGetBlockSize, // GetBlockSize - NULL,// FvbRead, // Read - NULL,// FvbWrite, // Write - NULL,// FvbEraseBlocks, // EraseBlocks - NULL //ParentHandle + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite,// FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL }; void * memset (void *dest, int ch, __SIZE_TYPE__ count) @@ -51,23 +48,22 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - // EFI_STATUS Status; + EFI_STATUS Status; struct spi_slave slave; DEBUG((EFI_D_INFO, "SPI IS HERE 2\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - // Status = gBS->InstallMultipleProtocolInterfaces ( - // &Handle, - // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - // NULL - // ); - // DEBUG((EFI_D_INFO, "\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.\n.")); - // if(EFI_ERROR (Status)) { - // DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - // } else { - // DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); - // } + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); + if(EFI_ERROR (Status)) { + DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + } else { + DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); + } DEBUG((EFI_D_INFO, "calling spi_init()\n")); spi_init(); DEBUG((EFI_D_INFO, "spi_init() was called\n")); @@ -89,13 +85,6 @@ EFI_STATUS EFIAPI SPIInitialize ( * * Returns: 0 on success, not 0 on failure */ -// struct spi_op { -// const VOID *dout; -// __SIZE_TYPE__ bytesout; -// VOID *din; -// __SIZE_TYPE__ bytesin; -// enum spi_op_status status; -// }; struct spi_op vector = { .dout = "asdf", .bytesout = 4, @@ -103,7 +92,5 @@ EFI_STATUS EFIAPI SPIInitialize ( char fill[255]; DEBUG((EFI_D_INFO, "spi_xfer() returned 0x%X\n", spi_xfer(&slave, "asdf", 4, &fill, 0))); DEBUG((EFI_D_INFO, "spi_xfer_vectors() returned 0x%X\n", spi_xfer_vector(&slave, &vector, 1))); - // int spi_xfer_vector(const struct spi_slave *slave, - // struct spi_op vectors[], __SIZE_TYPE__ count) return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/adesto.c b/UefiPayloadPkg/SPI/adesto.c new file mode 100644 index 000000000000..6538905681f8 --- /dev/null +++ b/UefiPayloadPkg/SPI/adesto.c @@ -0,0 +1,100 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * Driver for Adesto Technologies SPI flash + * based on winbond.c + */ + +#include +#include +#include +#include + +#include "spi_flash_internal.h" + +/* at25dfxx-specific commands */ +#define CMD_AT25DF_WREN 0x06 /* Write Enable */ +#define CMD_AT25DF_WRDI 0x04 /* Write Disable */ +#define CMD_AT25DF_RDSR 0x05 /* Read Status Register */ +#define CMD_AT25DF_WRSR 0x01 /* Write Status Register */ +#define CMD_AT25DF_READ 0x03 /* Read Data Bytes */ +#define CMD_AT25DF_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ +#define CMD_AT25DF_PP 0x02 /* Page Program */ +#define CMD_AT25DF_SE 0x20 /* Sector (4K) Erase */ +#define CMD_AT25DF_BE 0xd8 /* Block (64K) Erase */ +#define CMD_AT25DF_CE 0xc7 /* Chip Erase */ +#define CMD_AT25DF_DP 0xb9 /* Deep Power-down */ +#define CMD_AT25DF_RES 0xab /* Release from DP, and Read Signature */ + +static const struct spi_flash_part_id flash_table[] = { + { + /* AT25SL128A */ + .id[0] = 0x4218, + .nr_sectors_shift = 12, + }, + { + /* AT25DF081A Yes, 81A id < 81 */ + .id[0] = 0x4501, + .nr_sectors_shift = 8, + }, + { + /* AT25DF081 */ + .id[0] = 0x4502, + .nr_sectors_shift = 8, + }, + { + /* AT25DF161 */ + .id[0] = 0x4602, + .nr_sectors_shift = 9, + }, + { + /* AT25DL161 */ + .id[0] = 0x4603, + .nr_sectors_shift = 9, + }, + { + /* AT25DF321 */ + .id[0] = 0x4700, + .nr_sectors_shift = 10, + }, + { + /* AT25DF321A */ + .id[0] = 0x4701, + .nr_sectors_shift = 10, + }, + { + /* AT25DF641 */ + .id[0] = 0x4800, + .nr_sectors_shift = 11, + }, + { + /* AT25SF081 */ + .id[0] = 0x8501, + .nr_sectors_shift = 8, + }, + { + /* AT25DQ161 */ + .id[0] = 0x8600, + .nr_sectors_shift = 9, + }, + { + /* AT25SF161 */ + .id[0] = 0x8601, + .nr_sectors_shift = 9, + }, + { + /* AT25DQ321 */ + .id[0] = 0x8700, + .nr_sectors_shift = 10, + }, +}; + +const struct spi_flash_vendor_info spi_flash_adesto_vi = { + .id = VENDOR_ID_ADESTO, + .page_size_shift = 8, + .sector_size_kib_shift = 2, + .match_id_mask[0] = 0xffff, + .ids = flash_table, + .nr_part_ids = ARRAY_SIZE(flash_table), + .desc = &spi_flash_pp_0x20_sector_desc, +}; diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index a3dfb3ff8d3b..646c024feb39 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -8,7 +8,7 @@ #include #include "fch_spi_ctrl.h" -static unsigned long int spi_base = 0xBAADF00D; +static unsigned long int spi_base = 0xF8000000; VOID spi_set_base(VOID *base) { diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index cacc93ebd2c5..90a403c518d7 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -31,10 +31,8 @@ union pci_bank { static __attribute__ ((__always_inline__)) inline volatile union pci_bank *pcicfg(pci_devfn_t dev) { - /*DEBUG((EFI_D_INFO, "%a: Access to BAADF00D!!!", __FUNCTION__)); - UINT8 *CONST pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; - return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)];*/ - return NULL; + UINT8 *const spi_bar = (VOID *)(unsigned long int)0xF8000000; + return (void *)&spi_bar[PCI_DEVFN_OFFSET(dev)]; } static __attribute__ ((__always_inline__)) inline diff --git a/UefiPayloadPkg/SPI/spi_flash copy.c b/UefiPayloadPkg/SPI/spi_flash copy.c new file mode 100644 index 000000000000..7a02e9c84b2c --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_flash copy.c @@ -0,0 +1,761 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include "spi_flash_internal.h" + +static void spi_flash_addr(UINT32 addr, UINT8 *cmd) +{ + /* cmd[0] is actual command */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; +} + +static int do_spi_flash_cmd(const struct spi_slave *spi, const void *dout, + __SIZE_TYPE__ bytes_out, void *din, __SIZE_TYPE__ bytes_in) +{ + int ret; + /* + * SPI flash requires command-response kind of behavior. Thus, two + * separate SPI vectors are required -- first to transmit dout and other + * to receive in din. If some specialized SPI flash controllers + * (e.g. x86) can perform both command and response together, it should + * be handled at SPI flash controller driver level. + */ + struct spi_op vectors[] = { + [0] = { .dout = dout, .bytesout = bytes_out, + .din = NULL, .bytesin = 0, }, + [1] = { .dout = NULL, .bytesout = 0, + .din = din, .bytesin = bytes_in }, + }; + __SIZE_TYPE__ count = ARRAY_SIZE(vectors); + if (!bytes_in) + count = 1; + + ret = spi_claim_bus(spi); + if (ret) + return ret; + + ret = spi_xfer_vector(spi, vectors, count); + + spi_release_bus(spi); + return ret; +} + +static int do_dual_read_cmd(const struct spi_slave *spi, const void *dout, + __SIZE_TYPE__ bytes_out, void *din, __SIZE_TYPE__ bytes_in) +{ + int ret; + + /* + * spi_xfer_vector() will automatically fall back to .xfer() if + * .xfer_vector() is unimplemented. So using vector API here is more + * flexible, even though a controller that implements .xfer_vector() + * and (the non-vector based) .xfer_dual() but not .xfer() would be + * pretty odd. + */ + struct spi_op vector = { .dout = dout, .bytesout = bytes_out, + .din = NULL, .bytesin = 0 }; + + ret = spi_claim_bus(spi); + if (ret) + return ret; + + ret = spi_xfer_vector(spi, &vector, 1); + + if (!ret) + ret = spi->ctrlr->xfer_dual(spi, NULL, 0, din, bytes_in); + + spi_release_bus(spi); + return ret; +} + +int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, void *response, __SIZE_TYPE__ len) +{ + int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); + if (ret) + DEBUG((EFI_D_INFO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, ret)); + + return ret; +} + +/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */ +#pragma GCC diagnostic push +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif +#pragma GCC diagnostic ignored "-Wvla" +int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, + __SIZE_TYPE__ cmd_len, const void *data, __SIZE_TYPE__ data_len) +{ + int ret; + UINT8 buff[cmd_len + data_len]; + memcpy(buff, cmd, cmd_len); + memcpy(buff + cmd_len, data, data_len); + + ret = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0); + if (ret) { + DEBUG((EFI_D_INFO, "%a SF: Failed to send write command (%zu bytes): %d\n", + __FUNCTION__, data_len, ret)); + } + + return ret; +} +#pragma GCC diagnostic pop + +/* Perform the read operation honoring spi controller fifo size, reissuing + * the read command until the full request completed. */ +int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, void *buf) +{ + UINT8 cmd[5]; + int ret, cmd_len; + int (*do_cmd)(const struct spi_slave *spi, const void *din, + __SIZE_TYPE__ in_bytes, void *out, __SIZE_TYPE__ out_bytes); + + if (CONFIG(SPI_FLASH_NO_FAST_READ)) { + cmd_len = 4; + cmd[0] = CMD_READ_ARRAY_SLOW; + do_cmd = do_spi_flash_cmd; + } else if (flash->flags.dual_spi && flash->spi.ctrlr->xfer_dual) { + cmd_len = 5; + cmd[0] = CMD_READ_FAST_DUAL_OUTPUT; + cmd[4] = 0; + do_cmd = do_dual_read_cmd; + } else { + cmd_len = 5; + cmd[0] = CMD_READ_ARRAY_FAST; + cmd[4] = 0; + do_cmd = do_spi_flash_cmd; + } + + uint8_t *data = buf; + while (len) { + __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); + spi_flash_addr(offset, cmd); + ret = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); + if (ret) { + DEBUG((EFI_D_INFO, + "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", + __FUNCTION__, cmd[0], offset, xfer_len, ret)); + return ret; + } + offset += xfer_len; + data += xfer_len; + len -= xfer_len; + } + + return 0; +} + +int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, + UINT8 cmd, UINT8 poll_bit) +{ + const struct spi_slave *spi = &flash->spi; + int ret; + UINT8 status; + struct mono_time current, end; + + timer_monotonic_get(¤t); + end = current; + mono_time_add_msecs(&end, timeout); + + do { + ret = do_spi_flash_cmd(spi, &cmd, 1, &status, 1); + if (ret) + return -1; + if ((status & poll_bit) == 0) + return 0; + timer_monotonic_get(¤t); + } while (!mono_time_after(¤t, &end)); + + DEBUG((EFI_D_INFO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); + return -1; +} + +int spi_flash_cmd_wait_ready(const struct spi_flash *flash, + unsigned long timeout) +{ + return spi_flash_cmd_poll_bit(flash, timeout, + CMD_READ_STATUS, STATUS_WIP); +} + +int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) +{ + UINT32 start, end, erase_size; + int ret = -1; + UINT8 cmd[4]; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { + DEBUG((EFI_D_INFO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); + return -1; + } + if (len == 0) { + DEBUG((EFI_D_INFO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); + return -1; + } + + cmd[0] = flash->erase_cmd; + start = offset; + end = start + len; + + while (offset < end) { + spi_flash_addr(offset, cmd); + offset += erase_size; + +#if CONFIG(DEBUG_SPI_FLASH) + DEBUG((EFI_D_INFO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION, + cmd[0], cmd[1], cmd[2], cmd[3], offset)); +#endif + ret = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0); + if (ret) + goto out; + + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0); + if (ret) + goto out; + + ret = spi_flash_cmd_wait_ready(flash, + SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); + if (ret) + goto out; + } + + DEBUG(EFI_D_INFO, "%a SF: Successfully erased %zu bytes @ %#x\n", __FUNCTION__, len, start)); + +out: + return ret; +} + +int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg) +{ + return spi_flash_cmd(&flash->spi, flash->status_cmd, reg, sizeof(*reg)); +} + +int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, const void *buf) +{ + unsigned long byte_addr; + unsigned long page_size; + __SIZE_TYPE__ chunk_len; + __SIZE_TYPE__ actual; + int ret = 0; + UINT8 cmd[4]; + + page_size = flash->page_size; + cmd[0] = flash->pp_cmd; + + for (actual = 0; actual < len; actual += chunk_len) { + byte_addr = offset % page_size; + chunk_len = MIN(len - actual, page_size - byte_addr); + chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len); + + spi_flash_addr(offset, cmd); + if (CONFIG(DEBUG_SPI_FLASH)) { + DEBUG((EFI_D_INFO, "%a PP: %p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", + __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], + chunk_len)); + } + + ret = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0); + if (ret < 0) { + DEBUG((EFI_D_INFO, "%a SF: Enabling Write failed\n", __FUNCTION__)); + goto out; + } + + ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), + buf + actual, chunk_len); + if (ret < 0) { + DEBUG((EFI_D_INFO, "%a SF: Page Program failed\n", __FUNCTION__)); + goto out; + } + + ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS); + if (ret) + goto out; + + offset += chunk_len; + } + + if (CONFIG(DEBUG_SPI_FLASH)) + DEBUG((EFI_D_INFO, "%a SF: : Successfully programmed %zu bytes @ 0x%lx\n", + __FUNCTION__, len, (unsigned long)(offset - len)); + ret = 0; + +out: + return ret; +} + +static const struct spi_flash_vendor_info *spi_flash_vendors[] = { +#if CONFIG(SPI_FLASH_ADESTO) + &spi_flash_adesto_vi, +#endif +#if CONFIG(SPI_FLASH_AMIC) + &spi_flash_amic_vi, +#endif +#if CONFIG(SPI_FLASH_ATMEL) + &spi_flash_atmel_vi, +#endif +#if CONFIG(SPI_FLASH_EON) + &spi_flash_eon_vi, +#endif +#if CONFIG(SPI_FLASH_GIGADEVICE) + &spi_flash_gigadevice_vi, +#endif +#if CONFIG(SPI_FLASH_MACRONIX) + &spi_flash_macronix_vi, +#endif +#if CONFIG(SPI_FLASH_SPANSION) + &spi_flash_spansion_ext1_vi, + &spi_flash_spansion_ext2_vi, + &spi_flash_spansion_vi, +#endif +#if CONFIG(SPI_FLASH_SST) + &spi_flash_sst_ai_vi, + &spi_flash_sst_vi, +#endif +#if CONFIG(SPI_FLASH_STMICRO) + &spi_flash_stmicro1_vi, + &spi_flash_stmicro2_vi, + &spi_flash_stmicro3_vi, + &spi_flash_stmicro4_vi, +#endif +#if CONFIG(SPI_FLASH_WINBOND) + &spi_flash_winbond_vi, +#endif +}; +#define IDCODE_LEN 5 + +static int fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash, + const struct spi_flash_vendor_info *vi, + const struct spi_flash_part_id *part) +{ + memcpy(&flash->spi, spi, sizeof(*spi)); + flash->vendor = vi->id; + flash->model = part->id[0]; + + flash->page_size = 1U << vi->page_size_shift; + flash->sector_size = (1U << vi->sector_size_kib_shift) * KiB; + flash->size = flash->sector_size * (1U << part->nr_sectors_shift); + flash->erase_cmd = vi->desc->erase_cmd; + flash->status_cmd = vi->desc->status_cmd; + flash->pp_cmd = vi->desc->pp_cmd; + flash->wren_cmd = vi->desc->wren_cmd; + + flash->flags.dual_spi = part->fast_read_dual_output_support; + + flash->ops = &vi->desc->ops; + flash->prot_ops = vi->prot_ops; + flash->part = part; + + if (vi->after_probe) + return vi->after_probe(flash); + + return 0; +} + +static const struct spi_flash_part_id *find_part(const struct spi_flash_vendor_info *vi, + uint16_t id[2]) +{ + __SIZE_TYPE__ i; + const uint16_t lid[2] = { + [0] = id[0] & vi->match_id_mask[0], + [1] = id[1] & vi->match_id_mask[1], + }; + + + for (i = 0; i < vi->nr_part_ids; i++) { + const struct spi_flash_part_id *part = &vi->ids[i]; + + if (part->id[0] == lid[0] && part->id[1] == lid[1]) + return part; + } + + return NULL; +} + +static int find_match(const struct spi_slave *spi, struct spi_flash *flash, + uint8_t manuf_id, uint16_t id[2]) +{ + int i; + + for (i = 0; i < (int)ARRAY_SIZE(spi_flash_vendors); i++) { + const struct spi_flash_vendor_info *vi; + const struct spi_flash_part_id *part; + + vi = spi_flash_vendors[i]; + + if (manuf_id != vi->id) + continue; + + part = find_part(vi, id); + + if (part == NULL) + continue; + + return fill_spi_flash(spi, flash, vi, part); + } + + return -1; +} + +int spi_flash_generic_probe(const struct spi_slave *spi, + struct spi_flash *flash) +{ + int ret, i; + UINT8 idcode[IDCODE_LEN]; + UINT8 manuf_id; + UINT16 id[2]; + + /* Read the ID codes */ + ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); + if (ret) + return -1; + + if (CONFIG(DEBUG_SPI_FLASH)) { + DEBUG((EFI_D_INFO, "SF: Got idcode: ")); + for (i = 0; i < sizeof(idcode); i++) + DEBUG(EFI_D_INFO, "%02x ", idcode[i])); + DEBUG((EFI_D_INFO, "\n"); + } + + manuf_id = idcode[0]; + + DEBUG(EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); + + /* If no result from RDID command and STMicro parts are enabled attempt + to wake the part from deep sleep and obtain alternative id info. */ + if (CONFIG(SPI_FLASH_STMICRO) && manuf_id == 0xff) { + if (stmicro_release_deep_sleep_identify(spi, idcode)) + return -1; + manuf_id = idcode[0]; + } + + id[0] = (idcode[1] << 8) | idcode[2]; + id[1] = (idcode[3] << 8) | idcode[4]; + + return find_match(spi, flash, manuf_id, id); +} + +int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash) +{ + struct spi_slave spi; + int ret = -1; + + if (spi_setup_slave(bus, cs, &spi)) { + DEBUG((EFI_D_INFO, "%a SF: Failed to set up slave\n", __FUNCTION__)); + return -1; + } + + /* Try special programmer probe if any. */ + if (spi.ctrlr->flash_probe) + ret = spi.ctrlr->flash_probe(&spi, flash); + + /* If flash is not found, try generic spi flash probe. */ + if (ret) + ret = spi_flash_generic_probe(&spi, flash); + + /* Give up -- nothing more to try if flash is not found. */ + if (ret) { + DEBUG((EFI_D_INFO, "%a SF: Unsupported manufacturer!\n", __FUNCTION__)); + return -1; + } + + const char *mode_string = ""; + if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) + mode_string = " (Dual SPI mode)"; + DEBUG(EFI_D_INFO, + "%a SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", + __FUNCTION__, flash->vendor, flash->model, + flash->sector_size, flash->size, mode_string)); + if (bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS + && flash->size != CONFIG_ROM_SIZE) { + DEBUG(EFI_D_INFO, "%a SF size 0x%x does not correspond to" + " CONFIG_ROM_SIZE 0x%x!!\n", __FUNCTION__, flash->size, + CONFIG_ROM_SIZE)); + } + return 0; +} + +int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + void *buf) +{ + return flash->ops->read(flash, offset, len, buf); +} + +int spi_flash_write(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + const void *buf) +{ + int ret; + + if (spi_flash_volatile_group_begin(flash)) + return -1; + + ret = flash->ops->write(flash, offset, len, buf); + + if (spi_flash_volatile_group_end(flash)) + return -1; + + return ret; +} + +int spi_flash_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) +{ + int ret; + + if (spi_flash_volatile_group_begin(flash)) + return -1; + + ret = flash->ops->erase(flash, offset, len); + + if (spi_flash_volatile_group_end(flash)) + return -1; + + return ret; +} + +int spi_flash_status(const struct spi_flash *flash, UINT8 *reg) +{ + if (flash->ops->status) + return flash->ops->status(flash, reg); + + return -1; +} + +int spi_flash_is_write_protected(const struct spi_flash *flash, + const struct region *region) +{ + struct region flash_region = { 0 }; + + if (!flash || !region) + return -1; + + flash_region.size = flash->size; + + if (!region_is_subregion(&flash_region, region)) + return -1; + + if (!flash->prot_ops) { + DEBUG(EFI_D_INFO, "%a SPI: Write-protection gathering not " + "implemented for this vendor.\n", __FUNCTION__)); + return -1; + } + + return flash->prot_ops->get_write(flash, region); +} + +int spi_flash_set_write_protected(const struct spi_flash *flash, + const struct region *region, + const enum spi_flash_status_reg_lockdown mode) +{ + struct region flash_region = { 0 }; + int ret; + + if (!flash) + return -1; + + flash_region.size = flash->size; + + if (!region_is_subregion(&flash_region, region)) + return -1; + + if (!flash->prot_ops) { + DEBUG(EFI_D_INFO, "%a SPI: Setting write-protection is not " + "implemented for this vendor.\n", __FUNCTION__)); + return -1; + } + + ret = flash->prot_ops->set_write(flash, region, mode); + + if (ret == 0 && mode != SPI_WRITE_PROTECTION_PRESERVE) { + DEBUG(EFI_D_INFO, "%a SPI: SREG lock-down was set to ", __FUNCTION__)); + switch (mode) { + case SPI_WRITE_PROTECTION_NONE: + DEBUG(EFI_D_INFO, "%a NEVER\n", __FUNCTION__)); + break; + case SPI_WRITE_PROTECTION_PIN: + DEBUG(EFI_D_INFO, "%a WP\n", __FUNCTION__)); + break; + case SPI_WRITE_PROTECTION_REBOOT: + DEBUG(EFI_D_INFO, "%a REBOOT\n", __FUNCTION__)); + break; + case SPI_WRITE_PROTECTION_PERMANENT: + DEBUG(EFI_D_INFO, "%a PERMANENT\n", __FUNCTION__)); + break; + default: + DEBUG(EFI_D_INFO, "%a UNKNOWN\n", __FUNCTION__)); + break; + } + } + + return ret; +} + +static uint32_t volatile_group_count; + +int spi_flash_volatile_group_begin(const struct spi_flash *flash) +{ + uint32_t count; + int ret = 0; + + if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) + return ret; + + count = volatile_group_count; + if (count == 0) + ret = chipset_volatile_group_begin(flash); + + count++; + volatile_group_count = count; + return ret; +} + +int spi_flash_volatile_group_end(const struct spi_flash *flash) +{ + uint32_t count; + int ret = 0; + + if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) + return ret; + + count = volatile_group_count; + assert(count == 0); + count--; + volatile_group_count = count; + + if (count == 0) + ret = chipset_volatile_group_end(flash); + + return ret; +} + +void lb_spi_flash(struct lb_header *header) +{ + struct lb_spi_flash *flash; + const struct spi_flash *spi_flash_dev; + + if (!CONFIG(BOOT_DEVICE_SPI_FLASH)) + return; + + flash = (struct lb_spi_flash *)lb_new_record(header); + + flash->tag = LB_TAG_SPI_FLASH; + flash->size = sizeof(*flash); + + spi_flash_dev = boot_device_spi_flash(); + + if (spi_flash_dev) { + flash->flash_size = spi_flash_dev->size; + flash->sector_size = spi_flash_dev->sector_size; + flash->erase_cmd = spi_flash_dev->erase_cmd; + } else { + flash->flash_size = CONFIG_ROM_SIZE; + /* Default 64k erase command should work on most flash. + * Uniform 4k erase only works on certain devices. */ + flash->sector_size = 64 * KiB; + flash->erase_cmd = CMD_BLOCK_ERASE; + } +} + + +int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, + const struct region *region, + const enum ctrlr_prot_type type) +{ + const struct spi_ctrlr *ctrlr; + struct region flash_region = { 0 }; + + if (!flash) + return -1; + + flash_region.size = flash->size; + + if (!region_is_subregion(&flash_region, region)) + return -1; + + ctrlr = flash->spi.ctrlr; + + if (!ctrlr) + return -1; + + if (ctrlr->flash_protect) + return ctrlr->flash_protect(flash, region, type); + + return -1; +} + +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + int (*func)(const struct spi_slave *slave, const void *dout, + __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)) +{ + int ret; + void *din; + __SIZE_TYPE__ bytes_in; + + if (count < 1 || count > 2) + return -1; + + /* SPI flash commands always have a command first... */ + if (!vectors[0].dout || !vectors[0].bytesout) + return -1; + /* And not read any data during the command. */ + if (vectors[0].din || vectors[0].bytesin) + return -1; + + if (count == 2) { + /* If response bytes requested ensure the buffer is valid. */ + if (vectors[1].bytesin && !vectors[1].din) + return -1; + /* No sends can accompany a receive. */ + if (vectors[1].dout || vectors[1].bytesout) + return -1; + din = vectors[1].din; + bytes_in = vectors[1].bytesin; + } else { + din = NULL; + bytes_in = 0; + } + + ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); + + if (ret) { + vectors[0].status = SPI_OP_FAILURE; + if (count == 2) + vectors[1].status = SPI_OP_FAILURE; + } else { + vectors[0].status = SPI_OP_SUCCESS; + if (count == 2) + vectors[1].status = SPI_OP_SUCCESS; + } + + return ret; +} + +const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc = { + .erase_cmd = 0x20, /* Sector Erase */ + .status_cmd = 0x05, /* Read Status */ + .pp_cmd = 0x02, /* Page Program */ + .wren_cmd = 0x06, /* Write Enable */ + .ops = { + .read = spi_flash_cmd_read, + .write = spi_flash_cmd_write_page_program, + .erase = spi_flash_cmd_erase, + .status = spi_flash_cmd_status, + }, +}; + +const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc = { + .erase_cmd = 0xd8, /* Sector Erase */ + .status_cmd = 0x05, /* Read Status */ + .pp_cmd = 0x02, /* Page Program */ + .wren_cmd = 0x06, /* Write Enable */ + .ops = { + .read = spi_flash_cmd_read, + .write = spi_flash_cmd_write_page_program, + .erase = spi_flash_cmd_erase, + .status = spi_flash_cmd_status, + }, +}; diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h new file mode 100644 index 000000000000..b4d39b3d3120 --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_flash_internal.h @@ -0,0 +1,128 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * SPI flash internal definitions + */ + +#ifndef SPI_FLASH_INTERNAL_H +#define SPI_FLASH_INTERNAL_H + +/* Common commands */ +#define CMD_READ_ID 0x9f + +#define CMD_READ_ARRAY_SLOW 0x03 +#define CMD_READ_ARRAY_FAST 0x0b +#define CMD_READ_ARRAY_LEGACY 0xe8 + +#define CMD_READ_FAST_DUAL_OUTPUT 0x3b + +#define CMD_READ_STATUS 0x05 +#define CMD_WRITE_ENABLE 0x06 + +#define CMD_BLOCK_ERASE 0xD8 + +/* Common status */ +#define STATUS_WIP 0x01 + +/* Send a single-byte command to the device and read the response */ +int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len); + +/* + * Send a multi-byte command to the device followed by (optional) + * data. Used for programming the flash array, etc. + */ +int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd, + size_t cmd_len, const void *data, size_t data_len); + +/* Send a command to the device and wait for some bit to clear itself. */ +int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, + u8 cmd, u8 poll_bit); + +/* + * Send the read status command to the device and wait for the wip + * (write-in-progress) bit to clear itself. + */ +int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout); + +/* Erase sectors. */ +int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len); + +/* Read status register. */ +int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg); + +/* Write to flash utilizing page program semantics. */ +int spi_flash_cmd_write_page_program(const struct spi_flash *flash, u32 offset, + size_t len, const void *buf); + +/* Read len bytes into buf at offset. */ +int spi_flash_cmd_read(const struct spi_flash *flash, u32 offset, size_t len, void *buf); + +/* Release from deep sleep an provide alternative rdid information. */ +int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, u8 *idcode); + +struct spi_flash_part_id { + /* rdid command constructs 2x 16-bit id using the following method + * for matching after reading 5 bytes (1st byte is manuf id): + * id[0] = (id[1] << 8) | id[2] + * id[1] = (id[3] << 8) | id[4] + */ + uint16_t id[2]; + /* Log based 2 total number of sectors. */ + uint16_t nr_sectors_shift: 4; + uint16_t fast_read_dual_output_support : 1; + uint16_t _reserved_for_flags: 3; + /* Block protection. Currently used by Winbond. */ + uint16_t protection_granularity_shift : 5; + uint16_t bp_bits : 3; +}; + +struct spi_flash_ops_descriptor { + uint8_t erase_cmd; /* Sector Erase */ + uint8_t status_cmd; /* Read Status Register */ + uint8_t pp_cmd; /* Page program command, if supported. */ + uint8_t wren_cmd; /* Write Enable command. */ + struct spi_flash_ops ops; +}; + +/* Vendor info represents a common set of organization and commands by a given + * vendor. One can implement multiple sets from a single vendor by having + * separate objects. */ +struct spi_flash_vendor_info { + uint8_t id; + uint8_t page_size_shift : 4; /* if page programming oriented. */ + /* Log based 2 sector size */ + uint8_t sector_size_kib_shift : 4; + uint16_t nr_part_ids; + const struct spi_flash_part_id *ids; + uint16_t match_id_mask[2]; /* matching bytes of the id for this set*/ + const struct spi_flash_ops_descriptor *desc; + const struct spi_flash_protection_ops *prot_ops; + /* Returns 0 on success. !0 otherwise. */ + int (*after_probe)(const struct spi_flash *flash); +}; + +/* Manufacturer-specific probe information */ +extern const struct spi_flash_vendor_info spi_flash_adesto_vi; +extern const struct spi_flash_vendor_info spi_flash_amic_vi; +extern const struct spi_flash_vendor_info spi_flash_atmel_vi; +extern const struct spi_flash_vendor_info spi_flash_eon_vi; +extern const struct spi_flash_vendor_info spi_flash_gigadevice_vi; +extern const struct spi_flash_vendor_info spi_flash_macronix_vi; +/* Probing order matters between the spansion sequence. */ +extern const struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; +extern const struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; +extern const struct spi_flash_vendor_info spi_flash_spansion_vi; +extern const struct spi_flash_vendor_info spi_flash_sst_ai_vi; +extern const struct spi_flash_vendor_info spi_flash_sst_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro1_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro2_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro3_vi; +extern const struct spi_flash_vendor_info spi_flash_stmicro4_vi; +extern const struct spi_flash_vendor_info spi_flash_winbond_vi; + +/* Page Programming Command Set with 0x20 Sector Erase command. */ +extern const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; +/* Page Programming Command Set with 0xd8 Sector Erase command. */ +extern const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; + +#endif /* SPI_FLASH_INTERNAL_H */ diff --git a/UefiPayloadPkg/SPI/spi_winbond.h b/UefiPayloadPkg/SPI/spi_winbond.h new file mode 100644 index 000000000000..bdf669430681 --- /dev/null +++ b/UefiPayloadPkg/SPI/spi_winbond.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* Winbond specific function */ +/* M25Pxx-specific commands */ +#define CMD_W25_WREN 0x06 /* Write Enable */ +#define CMD_W25_WRDI 0x04 /* Write Disable */ +#define CMD_W25_RDSR 0x05 /* Read Status Register */ +#define CMD_W25_WRSR 0x01 /* Write Status Register */ +#define CMD_W25_RDSR2 0x35 /* Read Status2 Register */ +#define CMD_W25_WRSR2 0x31 /* Write Status2 Register */ +#define CMD_W25_READ 0x03 /* Read Data Bytes */ +#define CMD_W25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ +#define CMD_W25_PP 0x02 /* Page Program */ +#define CMD_W25_SE 0x20 /* Sector (4K) Erase */ +#define CMD_W25_RDID 0x9f /* Read ID */ +#define CMD_W25_BE 0xd8 /* Block (64K) Erase */ +#define CMD_W25_CE 0xc7 /* Chip Erase */ +#define CMD_W25_DP 0xb9 /* Deep Power-down */ +#define CMD_W25_RES 0xab /* Release from DP and Read Signature */ +#define CMD_VOLATILE_SREG_WREN 0x50 /* Write Enable for Volatile SREG */ + +/* tw: Maximum time to write a flash cell in milliseconds */ +#define WINBOND_FLASH_TIMEOUT 30 diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/winbond.c new file mode 100644 index 000000000000..e151df5c7a80 --- /dev/null +++ b/UefiPayloadPkg/SPI/winbond.c @@ -0,0 +1,536 @@ +#include +#include +#include + +union status_reg1 { + UINT8 u; + struct { + UINT8 busy : 1; + UINT8 wel : 1; + UINT8 bp : 3; + UINT8 tb : 1; + UINT8 sec : 1; + UINT8 srp0 : 1; + } bp3; + struct { + UINT8 busy : 1; + UINT8 wel : 1; + UINT8 bp : 4; + UINT8 tb : 1; + UINT8 srp0 : 1; + } bp4; +}; + +union status_reg2 { + UINT8 u; + struct { + UINT8 srp1 : 1; + UINT8 qe : 1; + UINT8 res : 1; + UINT8 lb : 3; + UINT8 cmp : 1; + UINT8 sus : 1; + }; +}; + +struct status_regs { + union { + struct { +#if defined(__BIG_ENDIAN) + union status_reg2 reg2; + union status_reg1 reg1; +#else + union status_reg1 reg1; + union status_reg2 reg2; +#endif + }; + UINT16 u; + }; +}; + +static const struct spi_flash_part_id flash_table[] = { + { + /* W25P80 */ + .id[0] = 0x2014, + .nr_sectors_shift = 8, + }, + { + /* W25P16 */ + .id[0] = 0x2015, + .nr_sectors_shift = 9, + }, + { + /* W25P32 */ + .id[0] = 0x2016, + .nr_sectors_shift = 10, + }, + { + /* W25X80 */ + .id[0] = 0x3014, + .nr_sectors_shift = 8, + .fast_read_dual_output_support = 1, + }, + { + /* W25X16 */ + .id[0] = 0x3015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + }, + { + /* W25X32 */ + .id[0] = 0x3016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + }, + { + /* W25X64 */ + .id[0] = 0x3017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + }, + { + /* W25Q80_V */ + .id[0] = 0x4014, + .nr_sectors_shift = 8, + .fast_read_dual_output_support = 1, + }, + { + /* W25Q16_V */ + .id[0] = 0x4015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q16DW */ + .id[0] = 0x6015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q32_V */ + .id[0] = 0x4016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q32DW */ + .id[0] = 0x6016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q64_V */ + .id[0] = 0x4017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q64DW */ + .id[0] = 0x6017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q64JW */ + .id[0] = 0x8017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q128_V */ + .id[0] = 0x4018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128FW */ + .id[0] = 0x6018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128J */ + .id[0] = 0x7018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128JW */ + .id[0] = 0x8018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q256_V */ + .id[0] = 0x4019, + .nr_sectors_shift = 13, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 4, + }, + { + /* W25Q256J */ + .id[0] = 0x7019, + .nr_sectors_shift = 13, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 4, + }, +}; + +/* + * Convert BPx, TB and CMP to a region. + * SEC (if available) must be zero. + */ +static void winbond_bpbits_to_region(const size_t granularity, + const UINT8 bp, + bool tb, + const bool cmp, + const size_t flash_size, + struct region *out) +{ + size_t protected_size = + MIN(bp ? granularity << (bp - 1) : 0, flash_size); + + if (cmp) { + protected_size = flash_size - protected_size; + tb = !tb; + } + + out->offset = tb ? 0 : flash_size - protected_size; + out->size = protected_size; +} + +/* + * Available on all devices. + * Read block protect bits from Status/Status2 Reg. + * Converts block protection bits to a region. + * + * Returns: + * -1 on error + * 1 if region is covered by write protection + * 0 if a part of region isn't covered by write protection + */ +static int winbond_get_write_protection(const struct spi_flash *flash, + const struct region *region) +{ + const struct spi_flash_part_id *params; + struct region wp_region; + union status_reg2 reg2; + UINT8 bp, tb; + int ret; + + params = flash->part; + + if (!params) + return -1; + + const size_t granularity = (1 << params->protection_granularity_shift); + + union status_reg1 reg1 = { .u = 0 }; + + ret = spi_flash_cmd(&flash->spi, flash->status_cmd, ®1.u, + sizeof(reg1.u)); + if (ret) + return ret; + + if (params->bp_bits == 3) { + if (reg1.bp3.sec) { + // FIXME: not supported + return -1; + } + + bp = reg1.bp3.bp; + tb = reg1.bp3.tb; + } else if (params->bp_bits == 4) { + bp = reg1.bp4.bp; + tb = reg1.bp4.tb; + } else { + // FIXME: not supported + return -1; + } + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®2.u, + sizeof(reg2.u)); + if (ret) + return ret; + + winbond_bpbits_to_region(granularity, bp, tb, reg2.cmp, flash->size, + &wp_region); + + if (!region_sz(&wp_region)) { + DEBUG((EFI_D_INFO, "%a WINBOND: flash isn't protected\n", __FUNCTION__)); + + return 0; + } + + printk(BIOS_DEBUG, "WINBOND: flash protected range 0x%08zx-0x%08zx\n", + region_offset(&wp_region), region_end(&wp_region)); + + return region_is_subregion(&wp_region, region); +} + +/** + * Common method to write some bit of the status register 1 & 2 at the same + * time. Only change bits that are one in @mask. + * Compare the final result to make sure that the register isn't locked. + * + * @param mask: The bits that are affected by @val + * @param val: The bits to write + * @param non_volatile: Make setting permanent + * + * @return 0 on success + */ +static int winbond_flash_cmd_status(const struct spi_flash *flash, + const UINT16 mask, + const UINT16 val, + const bool non_volatile) +{ + struct { + UINT8 cmd; + UINT16 sreg; + } __packed cmdbuf; + UINT8 reg8; + int ret; + + if (!flash) + return -1; + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg = reg8; + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg |= reg8 << 8; + + if ((val & mask) == (cmdbuf.sreg & mask)) + return 0; + + if (non_volatile) { + ret = spi_flash_cmd(&flash->spi, CMD_W25_WREN, NULL, 0); + } else { + ret = spi_flash_cmd(&flash->spi, CMD_VOLATILE_SREG_WREN, NULL, + 0); + } + if (ret) + return ret; + + cmdbuf.sreg &= ~mask; + cmdbuf.sreg |= val & mask; + cmdbuf.cmd = CMD_W25_WRSR; + + /* Legacy method of writing status register 1 & 2 */ + ret = spi_flash_cmd_write(&flash->spi, (UINT8 *)&cmdbuf, sizeof(cmdbuf), + NULL, 0); + if (ret) + return ret; + + if (non_volatile) { + /* Wait tw */ + ret = spi_flash_cmd_wait_ready(flash, WINBOND_FLASH_TIMEOUT); + if (ret) + return ret; + } else { + /* Wait tSHSL */ + udelay(1); + } + + /* Now read the status register to make sure it's not locked */ + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg = reg8; + + ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); + if (ret) + return ret; + + cmdbuf.sreg |= reg8 << 8; + + printk(BIOS_DEBUG, "WINBOND: SREG=%02x SREG2=%02x\n", + cmdbuf.sreg & 0xff, + cmdbuf.sreg >> 8); + + /* Compare against expected result */ + if ((val & mask) != (cmdbuf.sreg & mask)) { + DEBUG(((EFI_D_INFO, "%a WINBOND: SREG is locked!\n", __FUNCTION__)); + ret = -1; + } + + return ret; +} + +/* + * Available on all devices. + * Protect a region starting from start of flash or end of flash. + * The caller must provide a supported protected region size. + * SEC isn't supported and set to zero. + * Write block protect bits to Status/Status2 Reg. + * Optionally lock the status register if lock_sreg is set with the provided + * mode. + * + * @param flash: The flash to operate on + * @param region: The region to write protect + * @param mode: Optional status register lock-down mode + * + * @return 0 on success + */ +static int +winbond_set_write_protection(const struct spi_flash *flash, + const struct region *region, + const enum spi_flash_status_reg_lockdown mode) +{ + const struct spi_flash_part_id *params; + struct status_regs mask, val; + struct region wp_region; + UINT8 cmp, bp, tb; + int ret; + + /* Need to touch TOP or BOTTOM */ + if (region_offset(region) != 0 && region_end(region) != flash->size) + return -1; + + params = flash->part; + + if (!params) + return -1; + + if (params->bp_bits != 3 && params->bp_bits != 4) { + /* FIXME: not implemented */ + return -1; + } + + wp_region = *region; + + if (region_offset(&wp_region) == 0) + tb = 1; + else + tb = 0; + + if (region_sz(&wp_region) > flash->size / 2) { + cmp = 1; + wp_region.offset = tb ? 0 : region_sz(&wp_region); + wp_region.size = flash->size - region_sz(&wp_region); + tb = !tb; + } else { + cmp = 0; + } + + if (region_sz(&wp_region) == 0) { + bp = 0; + } else if (IS_POWER_OF_2(region_sz(&wp_region)) && + (region_sz(&wp_region) >= + (1 << params->protection_granularity_shift))) { + bp = log2(region_sz(&wp_region)) - + params->protection_granularity_shift + 1; + } else { + DEBUG((EFI_D_INFO, + "%a WINBOND: ERROR: unsupported region size\n", __FUNCTION__)); + return -1; + } + + /* Write block protection bits */ + + if (params->bp_bits == 3) { + val.reg1 = (union status_reg1) { + .bp3 = { .bp = bp, .tb = tb, .sec = 0 } + }; + mask.reg1 = (union status_reg1) { + .bp3 = { .bp = ~0, .tb = 1, .sec = 1 } + }; + } else { + val.reg1 = (union status_reg1) { + .bp4 = { .bp = bp, .tb = tb } + }; + mask.reg1 = (union status_reg1) { + .bp4 = { .bp = ~0, .tb = 1 } + }; + } + + val.reg2 = (union status_reg2) { .cmp = cmp }; + mask.reg2 = (union status_reg2) { .cmp = 1 }; + + if (mode != SPI_WRITE_PROTECTION_PRESERVE) { + UINT8 srp; + switch (mode) { + case SPI_WRITE_PROTECTION_NONE: + srp = 0; + break; + case SPI_WRITE_PROTECTION_PIN: + srp = 1; + break; + case SPI_WRITE_PROTECTION_REBOOT: + srp = 2; + break; + case SPI_WRITE_PROTECTION_PERMANENT: + srp = 3; + break; + default: + return -1; + } + + if (params->bp_bits == 3) { + val.reg1.bp3.srp0 = !!(srp & 1); + mask.reg1.bp3.srp0 = 1; + } else { + val.reg1.bp4.srp0 = !!(srp & 1); + mask.reg1.bp4.srp0 = 1; + } + + val.reg2.srp1 = !!(srp & 2); + mask.reg2.srp1 = 1; + } + + ret = winbond_flash_cmd_status(flash, mask.u, val.u, true); + if (ret) + return ret; + + printk(BIOS_DEBUG, "WINBOND: write-protection set to range " + "0x%08zx-0x%08zx\n", region_offset(region), region_end(region)); + + return ret; +} + +static const struct spi_flash_protection_ops spi_flash_protection_ops = { + .get_write = winbond_get_write_protection, + .set_write = winbond_set_write_protection, +}; + +const struct spi_flash_vendor_info spi_flash_winbond_vi = { + .id = VENDOR_ID_WINBOND, + .page_size_shift = 8, + .sector_size_kib_shift = 2, + .match_id_mask[0] = 0xffff, + .ids = flash_table, + .nr_part_ids = ARRAY_SIZE(flash_table), + .desc = &spi_flash_pp_0x20_sector_desc, + .prot_ops = &spi_flash_protection_ops, +}; From 4d3d0bbe2c2b03b91349c0e09ba63b795b38e369 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 8 Oct 2020 14:58:45 +0200 Subject: [PATCH 249/297] Port Winbond and Adesto specific code, fix issues with acquisition of spi_base address --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 34 +- UefiPayloadPkg/SPI/Fvb.c | 1 + UefiPayloadPkg/SPI/SPI.inf | 4 +- UefiPayloadPkg/SPI/SPI_fvb.c | 48 +- UefiPayloadPkg/SPI/SPI_fvb.h | 28 + UefiPayloadPkg/SPI/SPIgeneric.h | 19 + UefiPayloadPkg/SPI/adesto.c | 4 - UefiPayloadPkg/SPI/fch_spi_ctrl.c | 2 +- UefiPayloadPkg/SPI/fch_spi_util.c | 52 +- UefiPayloadPkg/SPI/own.c | 6 + UefiPayloadPkg/SPI/own.h | 1 + UefiPayloadPkg/SPI/pci_mmio_cfg.h | 86 +-- UefiPayloadPkg/SPI/pci_ops.h | 1 + UefiPayloadPkg/SPI/region.c | 498 ++++++++++++++++++ UefiPayloadPkg/SPI/region.h | 288 ++++++++++ UefiPayloadPkg/SPI/spi_flash.c | 50 -- UefiPayloadPkg/SPI/spi_flash.h | 13 - ...{spi_flash copy.c => spi_flash_internal.c} | 211 +++++--- UefiPayloadPkg/SPI/spi_flash_internal.h | 66 ++- UefiPayloadPkg/SPI/utils.h | 2 + UefiPayloadPkg/SPI/winbond.c | 41 +- 21 files changed, 1170 insertions(+), 285 deletions(-) create mode 100644 UefiPayloadPkg/SPI/region.c create mode 100644 UefiPayloadPkg/SPI/region.h delete mode 100644 UefiPayloadPkg/SPI/spi_flash.c delete mode 100644 UefiPayloadPkg/SPI/spi_flash.h rename UefiPayloadPkg/SPI/{spi_flash copy.c => spi_flash_internal.c} (79%) diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h index 92d937cc0c31..1dab63240102 100644 --- a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h +++ b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h @@ -29,23 +29,23 @@ typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; -#pragma pack (1) -typedef struct { - VENDOR_DEVICE_PATH Vendor; - UINT8 Index; - EFI_DEVICE_PATH_PROTOCOL End; -} NOR_FLASH_DEVICE_PATH; -#pragma pack () - -struct _SMMSTORE_INSTANCE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_BLOCK_IO_MEDIA Media; - - EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; - - NOR_FLASH_DEVICE_PATH DevicePath; -}; +// #pragma pack (1) +// typedef struct { +// VENDOR_DEVICE_PATH Vendor; +// UINT8 Index; +// EFI_DEVICE_PATH_PROTOCOL End; +// } NOR_FLASH_DEVICE_PATH; +// #pragma pack () + +// struct _SMMSTORE_INSTANCE { +// UINT32 Signature; +// EFI_HANDLE Handle; +// EFI_BLOCK_IO_MEDIA Media; + +// EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + +// NOR_FLASH_DEVICE_PATH DevicePath; +// }; // // BlSMMStoreFvbDxe.c diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index f09b82d59964..1b96b9785216 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -1,5 +1,6 @@ #include "BlSMMStoreDxe.h" #include "Fvb.h" +#include "SPI_fvb.h" // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 9f487a82424d..0987165c3192 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -35,12 +35,12 @@ mmio.c stopwatch.h pci_devs.h - spi_flash.h - spi_flash.c pci_ops.h # pci_ops.c Fvb.h Fvb.c + spi_flash_internal.h + spi_flash_internal.c [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 0a9fecfc171b..f7ab95128d2b 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -20,8 +20,8 @@ #include #include "SPIgeneric.h" #include "fch_spi_ctrl.h" -#include "BlSMMStoreDxe.h" #include "Fvb.h" +#include "spi_flash_internal.h" EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { @@ -48,48 +48,34 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + // EFI_STATUS Status; struct spi_slave slave; DEBUG((EFI_D_INFO, "SPI IS HERE 2\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); - if(EFI_ERROR (Status)) { - DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - } else { - DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); - } + // Status = gBS->InstallMultipleProtocolInterfaces ( + // &Handle, + // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + // NULL + // ); + // if(EFI_ERROR (Status)) { + // DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + // } else { + // DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); + // } DEBUG((EFI_D_INFO, "calling spi_init()\n")); spi_init(); DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); DEBUG((EFI_D_INFO, "0x%X\n", slave.ctrlr->xfer)); - /*----------------------------------------------------------------------- - * SPI transfer - * - * spi_xfer() interface: - * slave: The SPI slave which will be sending/receiving the data. - * dout: Pointer to a string of bytes to send out. - * bytesout: How many bytes to write. - * din: Pointer to a string of bytes that will be filled in. - * bytesin: How many bytes to read. - * - * Note that din and dout are transferred simultaneously in a full duplex - * transaction. The number of clocks within one transaction is calculated - * as: MAX(bytesout*8, bytesin*8). - * - * Returns: 0 on success, not 0 on failure - */ + char fill[255]; + DEBUG((EFI_D_INFO, "spi_flash_cmd() returned 0x%X hihi\n", spi_flash_cmd(&slave, CMD_READ_ID, &fill, 5))); + DEBUG((EFI_D_INFO, "%X %X %X %X %X\n", fill[0], fill[1], fill[2], fill[3], fill[4])); struct spi_op vector = { - .dout = "asdf", - .bytesout = 4, + .dout = "asdf8888", + .bytesout = 8, }; - char fill[255]; DEBUG((EFI_D_INFO, "spi_xfer() returned 0x%X\n", spi_xfer(&slave, "asdf", 4, &fill, 0))); DEBUG((EFI_D_INFO, "spi_xfer_vectors() returned 0x%X\n", spi_xfer_vector(&slave, &vector, 1))); return EFI_SUCCESS; diff --git a/UefiPayloadPkg/SPI/SPI_fvb.h b/UefiPayloadPkg/SPI/SPI_fvb.h index 2568a3c083ad..e1d6a87bff08 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.h +++ b/UefiPayloadPkg/SPI/SPI_fvb.h @@ -82,6 +82,34 @@ struct intel_swseq_spi_config { struct intel_spi_op ops[8]; }; +struct spi_flash_protection_ops { + /* + * Returns 1 if the whole region is software write protected. + * Hardware write protection mechanism aren't accounted. + * If the write protection could be changed, due to unlocked status + * register for example, 0 should be returned. + * Returns 0 on success. + */ + int (*get_write)(const struct spi_flash *flash, + const struct region *region); + /* + * Enable the status register write protection, if supported on the + * requested region, and optionally enable status register lock-down. + * Returns 0 if the whole region was software write protected. + * Hardware write protection mechanism aren't accounted. + * If the status register is locked and the requested configuration + * doesn't match the selected one, return an error. + * Only a single region is supported ! + * + * @return 0 on success + */ + int + (*set_write)(const struct spi_flash *flash, + const struct region *region, + const enum spi_flash_status_reg_lockdown mode); + +}; + void * memset (void *dest, int ch, __SIZE_TYPE__ count); // diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/SPIgeneric.h index 087d58a06a27..0599a8e66add 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.h +++ b/UefiPayloadPkg/SPI/SPIgeneric.h @@ -200,6 +200,25 @@ struct spi_ctrlr_buses { UINT32 bus_end; }; +/* + * SPI write protection is enforced by locking the status register. + * The following modes are known. It depends on the flash chip if the + * mode is actually supported. + * + * PRESERVE : Keep the previous status register lock-down setting (noop) + * NONE : Status register isn't locked + * PIN : Status register is locked as long as the ~WP pin is active + * REBOOT : Status register is locked until power failure + * PERMANENT: Status register is permanently locked + */ +enum spi_flash_status_reg_lockdown { + SPI_WRITE_PROTECTION_PRESERVE = -1, + SPI_WRITE_PROTECTION_NONE = 0, + SPI_WRITE_PROTECTION_PIN, + SPI_WRITE_PROTECTION_REBOOT, + SPI_WRITE_PROTECTION_PERMANENT +}; + /* Mapping of SPI buses to controllers - should be defined by platform. */ extern const struct spi_ctrlr_buses spi_ctrlr_bus_map[]; extern const __SIZE_TYPE__ spi_ctrlr_bus_map_count; diff --git a/UefiPayloadPkg/SPI/adesto.c b/UefiPayloadPkg/SPI/adesto.c index 6538905681f8..978f8539b7e3 100644 --- a/UefiPayloadPkg/SPI/adesto.c +++ b/UefiPayloadPkg/SPI/adesto.c @@ -5,10 +5,6 @@ * based on winbond.c */ -#include -#include -#include -#include #include "spi_flash_internal.h" diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index 8aae82644df0..bd9470ff92c0 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -9,8 +9,8 @@ #include "SPIgeneric.h" #include "lpc.h" #include "pci_devs.h" -#include "spi_flash.h" #include "pci_ops.h" +#include "spi_flash_internal.h" /* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index 646c024feb39..d61d245628e6 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -7,22 +7,66 @@ #include #include #include "fch_spi_ctrl.h" +#include "pci_mmio_cfg.h" +#include "device.h" static unsigned long int spi_base = 0xF8000000; +union pci_bank { + UINT8 reg8[4096]; + UINT16 reg16[4096 / sizeof(UINT16)]; + UINT32 reg32[4096 / sizeof(UINT32)]; +}; + VOID spi_set_base(VOID *base) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); spi_base = (unsigned long int)base; } +static //__attribute__ ((__always_inline__)) +union pci_bank *pcicfg(pci_devfn_t dev) +{ + UINT8 *pci_mmconf = (void *)(unsigned long int)spi_base; + return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; +} + +static //__attribute__ ((__always_inline__)) +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +static //__attribute__ ((__always_inline__)) +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +static //__attribute__ ((__always_inline__)) +pci_devfn_t pcidev_bdf(CONST struct device *dev) +{ + return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +} + +static //__attribute__ ((__always_inline__)) +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +{ + return pci_s_read_config32(pcidev_bdf(dev), reg); +} + unsigned long int spi_get_bar(VOID) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - if (!spi_base) - spi_set_base((VOID *)lpc_get_spibase()); + UINT32 base; + + base = pci_read_config32((VOID *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); + base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); + return (unsigned long int)base; + // DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + // if (!spi_base) + // spi_set_base((VOID *)lpc_get_spibase()); - return spi_base; + // return spi_base; } UINT8 spi_read8(UINT8 reg) diff --git a/UefiPayloadPkg/SPI/own.c b/UefiPayloadPkg/SPI/own.c index c62d5ad95912..26c74a4e8369 100644 --- a/UefiPayloadPkg/SPI/own.c +++ b/UefiPayloadPkg/SPI/own.c @@ -6,3 +6,9 @@ VOID *memset (VOID *ptr, int value, __SIZE_TYPE__ num ) { ((CHAR8 *)ptr)[offset] = (CHAR8)value; } } + +void *memcpy (VOID * destination, CONST void * source, __SIZE_TYPE__ num ) { + for(__SIZE_TYPE__ offset; offset < num; ++offset) { + ((CHAR8 *)destination)[offset] = ((CHAR8 *)source)[offset]; + } +} diff --git a/UefiPayloadPkg/SPI/own.h b/UefiPayloadPkg/SPI/own.h index f7d6ddb8ac71..f3e64697b898 100644 --- a/UefiPayloadPkg/SPI/own.h +++ b/UefiPayloadPkg/SPI/own.h @@ -4,5 +4,6 @@ #include VOID *memset (VOID * ptr, int value, __SIZE_TYPE__ num ); +void *memcpy (VOID * destination, CONST void * source, __SIZE_TYPE__ num ); #endif /* OWN_H */ diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h index 90a403c518d7..cdb34f6d59d6 100644 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ b/UefiPayloadPkg/SPI/pci_mmio_cfg.h @@ -1,50 +1,50 @@ -#ifndef PCI_MMIO_CFG_H -#define PCI_MMIO_CFG_H +// #ifndef PCI_MMIO_CFG_H +// #define PCI_MMIO_CFG_H -#include -#include -#include "pci_type.h" +// #include +// #include +// #include "pci_type.h" -/* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we - * prevent some sub-optimal constant folding. */ -//UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; -//extern UINT8 *const pci_mmconf; +// /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we +// * prevent some sub-optimal constant folding. */ +// //UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; +// //extern UINT8 *const pci_mmconf; -/* Using a unique datatype for MMIO writes makes the pointers to _not_ - * qualify for pointer aliasing with any other objects in memory. - * - * MMIO offset is a value originally derived from 'struct device *' - * in ramstage. For the compiler to not discard this MMIO offset value - * from CPU registers after any MMIO writes, -fstrict-aliasing has to - * be also set for the build. - * - * Bottom 12 bits (4 KiB) are reserved to address the registers of a - * single PCI function. Declare the bank as a union to avoid some casting - * in the functions below. - */ -union pci_bank { - UINT8 reg8[4096]; - UINT16 reg16[4096 / sizeof(UINT16)]; - UINT32 reg32[4096 / sizeof(UINT32)]; -}; +// /* Using a unique datatype for MMIO writes makes the pointers to _not_ +// * qualify for pointer aliasing with any other objects in memory. +// * +// * MMIO offset is a value originally derived from 'struct device *' +// * in ramstage. For the compiler to not discard this MMIO offset value +// * from CPU registers after any MMIO writes, -fstrict-aliasing has to +// * be also set for the build. +// * +// * Bottom 12 bits (4 KiB) are reserved to address the registers of a +// * single PCI function. Declare the bank as a union to avoid some casting +// * in the functions below. +// */ +// union pci_bank { +// UINT8 reg8[4096]; +// UINT16 reg16[4096 / sizeof(UINT16)]; +// UINT32 reg32[4096 / sizeof(UINT32)]; +// }; -static __attribute__ ((__always_inline__)) inline -volatile union pci_bank *pcicfg(pci_devfn_t dev) -{ - UINT8 *const spi_bar = (VOID *)(unsigned long int)0xF8000000; - return (void *)&spi_bar[PCI_DEVFN_OFFSET(dev)]; -} +// static __attribute__ ((__always_inline__)) inline +// volatile union pci_bank *pcicfg(pci_devfn_t dev) +// { +// UINT8 *const spi_bar = (VOID *)(unsigned long int)0xF8000000; +// return (void *)&spi_bar[PCI_DEVFN_OFFSET(dev)]; +// } -static __attribute__ ((__always_inline__)) inline -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} +// static __attribute__ ((__always_inline__)) inline +// UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +// { +// return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +// } -static __attribute__ ((__always_inline__)) inline -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} +// static __attribute__ ((__always_inline__)) inline +// void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +// { +// pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; +// } -#endif /* PCI_MMIO_CFG_H */ +// #endif /* PCI_MMIO_CFG_H */ diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 1337142b4545..383840f981cd 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -12,6 +12,7 @@ #include "pci_type.h" #include "device.h" #include "pci_mmio_cfg.h" +#include "fch_spi_util.h" static __attribute__ ((__always_inline__)) inline UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) diff --git a/UefiPayloadPkg/SPI/region.c b/UefiPayloadPkg/SPI/region.c new file mode 100644 index 000000000000..957d12e6f1a8 --- /dev/null +++ b/UefiPayloadPkg/SPI/region.c @@ -0,0 +1,498 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include "region.h" + +int region_is_subregion(const struct region *p, const struct region *c) +{ + if (region_offset(c) < region_offset(p)) + return 0; + + if (region_end(c) > region_end(p)) + return 0; + + if (region_end(c) < region_offset(c)) + return 0; + + return 1; +} + +static int normalize_and_ok(const struct region *outer, struct region *inner) +{ + inner->offset += region_offset(outer); + return region_is_subregion(outer, inner); +} + +static const struct region_device *rdev_root(const struct region_device *rdev) +{ + if (rdev->root == NULL) + return rdev; + return rdev->root; +} + +__SIZE_TYPE__ rdev_relative_offset(const struct region_device *p, + const struct region_device *c) +{ + if (rdev_root(p) != rdev_root(c)) + return -1; + + if (!region_is_subregion(&p->region, &c->region)) + return -1; + + return region_device_offset(c) - region_device_offset(p); +} + +void *rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + const struct region_device *rdev; + struct region req = { + .offset = offset, + .size = size, + }; + + if (!normalize_and_ok(&rd->region, &req)) + return NULL; + + rdev = rdev_root(rd); + + if (rdev->ops->mmap == NULL) + return NULL; + + return rdev->ops->mmap(rdev, req.offset, req.size); +} + +int rdev_munmap(const struct region_device *rd, void *mapping) +{ + const struct region_device *rdev; + + rdev = rdev_root(rd); + + if (rdev->ops->munmap == NULL) + return -1; + + return rdev->ops->munmap(rdev, mapping); +} + +__SIZE_TYPE__ rdev_readat(const struct region_device *rd, void *b, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + const struct region_device *rdev; + struct region req = { + .offset = offset, + .size = size, + }; + + if (!normalize_and_ok(&rd->region, &req)) + return -1; + + rdev = rdev_root(rd); + + return rdev->ops->readat(rdev, b, req.offset, req.size); +} + +__SIZE_TYPE__ rdev_writeat(const struct region_device *rd, const void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + const struct region_device *rdev; + struct region req = { + .offset = offset, + .size = size, + }; + + if (!normalize_and_ok(&rd->region, &req)) + return -1; + + rdev = rdev_root(rd); + + if (rdev->ops->writeat == NULL) + return -1; + + return rdev->ops->writeat(rdev, b, req.offset, req.size); +} + +__SIZE_TYPE__ rdev_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + const struct region_device *rdev; + struct region req = { + .offset = offset, + .size = size, + }; + + if (!normalize_and_ok(&rd->region, &req)) + return -1; + + rdev = rdev_root(rd); + + /* If the eraseat ptr is NULL we assume that the erase + * function was completed successfully. */ + if (rdev->ops->eraseat == NULL) + return size; + + return rdev->ops->eraseat(rdev, req.offset, req.size); +} + +int rdev_chain(struct region_device *child, const struct region_device *parent, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + struct region req = { + .offset = offset, + .size = size, + }; + + if (!normalize_and_ok(&parent->region, &req)) + return -1; + + /* Keep track of root region device. Note the offsets are relative + * to the root device. */ + child->root = rdev_root(parent); + child->ops = NULL; + child->region.offset = req.offset; + child->region.size = req.size; + + return 0; +} + +static void mem_region_device_init(struct mem_region_device *mdev, + const struct region_device_ops *ops, void *base, __SIZE_TYPE__ size) +{ + memset(mdev, 0, sizeof(*mdev)); + mdev->base = base; + mdev->rdev.ops = ops; + mdev->rdev.region.size = size; +} + +void mem_region_device_ro_init(struct mem_region_device *mdev, void *base, + __SIZE_TYPE__ size) +{ + return mem_region_device_init(mdev, &mem_rdev_ro_ops, base, size); +} + +void mem_region_device_rw_init(struct mem_region_device *mdev, void *base, + __SIZE_TYPE__ size) +{ + return mem_region_device_init(mdev, &mem_rdev_rw_ops, base, size); +} + +void region_device_init(struct region_device *rdev, + const struct region_device_ops *ops, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + memset(rdev, 0, sizeof(*rdev)); + rdev->root = NULL; + rdev->ops = ops; + rdev->region.offset = offset; + rdev->region.size = size; +} + +static void xlate_region_device_init(struct xlate_region_device *xdev, + const struct region_device_ops *ops, + const struct region_device *access_dev, + __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, + __SIZE_TYPE__ parent_size) +{ + memset(xdev, 0, sizeof(*xdev)); + xdev->access_dev = access_dev; + xdev->sub_region.offset = sub_offset; + xdev->sub_region.size = sub_size; + region_device_init(&xdev->rdev, ops, 0, parent_size); +} + +void xlate_region_device_ro_init(struct xlate_region_device *xdev, + const struct region_device *access_dev, + __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, + __SIZE_TYPE__ parent_size) +{ + xlate_region_device_init(xdev, &xlate_rdev_ro_ops, access_dev, + sub_offset, sub_size, parent_size); +} + +void xlate_region_device_rw_init(struct xlate_region_device *xdev, + const struct region_device *access_dev, + __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, + __SIZE_TYPE__ parent_size) +{ + xlate_region_device_init(xdev, &xlate_rdev_rw_ops, access_dev, + sub_offset, sub_size, parent_size); +} + +static void *mdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size __unused) +{ + const struct mem_region_device *mdev; + + mdev = container_of(rd, __typeof__(*mdev), rdev); + + return &mdev->base[offset]; +} + +static int mdev_munmap(const struct region_device *rd __unused, + void *mapping __unused) +{ + return 0; +} + +static __SIZE_TYPE__ mdev_readat(const struct region_device *rd, void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + const struct mem_region_device *mdev; + + mdev = container_of(rd, __typeof__(*mdev), rdev); + + memcpy(b, &mdev->base[offset], size); + + return size; +} + +static __SIZE_TYPE__ mdev_writeat(const struct region_device *rd, const void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + const struct mem_region_device *mdev; + + mdev = container_of(rd, __typeof__(*mdev), rdev); + + memcpy(&mdev->base[offset], b, size); + + return size; +} + +static __SIZE_TYPE__ mdev_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + const struct mem_region_device *mdev; + + mdev = container_of(rd, __typeof__(*mdev), rdev); + + memset(&mdev->base[offset], 0, size); + + return size; +} + +const struct region_device_ops mem_rdev_ro_ops = { + .mmap = mdev_mmap, + .munmap = mdev_munmap, + .readat = mdev_readat, +}; + +const struct region_device_ops mem_rdev_rw_ops = { + .mmap = mdev_mmap, + .munmap = mdev_munmap, + .readat = mdev_readat, + .writeat = mdev_writeat, + .eraseat = mdev_eraseat, +}; + +void mmap_helper_device_init(struct mmap_helper_region_device *mdev, + void *cache, __SIZE_TYPE__ cache_size) +{ + mem_pool_init(&mdev->pool, cache, cache_size); +} + +void *mmap_helper_rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + struct mmap_helper_region_device *mdev; + void *mapping; + + mdev = container_of((void *)rd, __typeof__(*mdev), rdev); + + mapping = mem_pool_alloc(&mdev->pool, size); + + if (mapping == NULL) + return NULL; + + if (rd->ops->readat(rd, mapping, offset, size) != size) { + mem_pool_free(&mdev->pool, mapping); + return NULL; + } + + return mapping; +} + +int mmap_helper_rdev_munmap(const struct region_device *rd, void *mapping) +{ + struct mmap_helper_region_device *mdev; + + mdev = container_of((void *)rd, __typeof__(*mdev), rdev); + + mem_pool_free(&mdev->pool, mapping); + + return 0; +} + +static void *xlate_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + const struct xlate_region_device *xldev; + struct region req = { + .offset = offset, + .size = size, + }; + + xldev = container_of(rd, __typeof__(*xldev), rdev); + + if (!region_is_subregion(&xldev->sub_region, &req)) + return NULL; + + offset -= region_offset(&xldev->sub_region); + + return rdev_mmap(xldev->access_dev, offset, size); +} + +static int xlate_munmap(const struct region_device *rd, void *mapping) +{ + const struct xlate_region_device *xldev; + + xldev = container_of(rd, __typeof__(*xldev), rdev); + + return rdev_munmap(xldev->access_dev, mapping); +} + +static __SIZE_TYPE__ xlate_readat(const struct region_device *rd, void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + struct region req = { + .offset = offset, + .size = size, + }; + const struct xlate_region_device *xldev; + + xldev = container_of(rd, __typeof__(*xldev), rdev); + + if (!region_is_subregion(&xldev->sub_region, &req)) + return -1; + + offset -= region_offset(&xldev->sub_region); + + return rdev_readat(xldev->access_dev, b, offset, size); +} + +static __SIZE_TYPE__ xlate_writeat(const struct region_device *rd, const void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + struct region req = { + .offset = offset, + .size = size, + }; + const struct xlate_region_device *xldev; + + xldev = container_of(rd, __typeof__(*xldev), rdev); + + if (!region_is_subregion(&xldev->sub_region, &req)) + return -1; + + offset -= region_offset(&xldev->sub_region); + + return rdev_writeat(xldev->access_dev, b, offset, size); +} + +static __SIZE_TYPE__ xlate_eraseat(const struct region_device *rd, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + struct region req = { + .offset = offset, + .size = size, + }; + const struct xlate_region_device *xldev; + + xldev = container_of(rd, __typeof__(*xldev), rdev); + + if (!region_is_subregion(&xldev->sub_region, &req)) + return -1; + + offset -= region_offset(&xldev->sub_region); + + return rdev_eraseat(xldev->access_dev, offset, size); +} + +const struct region_device_ops xlate_rdev_ro_ops = { + .mmap = xlate_mmap, + .munmap = xlate_munmap, + .readat = xlate_readat, +}; + +const struct region_device_ops xlate_rdev_rw_ops = { + .mmap = xlate_mmap, + .munmap = xlate_munmap, + .readat = xlate_readat, + .writeat = xlate_writeat, + .eraseat = xlate_eraseat, +}; + + +static void *incoherent_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + const struct incoherent_rdev *irdev; + + irdev = container_of(rd, const struct incoherent_rdev, rdev); + + return rdev_mmap(irdev->read, offset, size); +} + +static int incoherent_munmap(const struct region_device *rd, void *mapping) +{ + const struct incoherent_rdev *irdev; + + irdev = container_of(rd, const struct incoherent_rdev, rdev); + + return rdev_munmap(irdev->read, mapping); +} + +static __SIZE_TYPE__ incoherent_readat(const struct region_device *rd, void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + const struct incoherent_rdev *irdev; + + irdev = container_of(rd, const struct incoherent_rdev, rdev); + + return rdev_readat(irdev->read, b, offset, size); +} + +static __SIZE_TYPE__ incoherent_writeat(const struct region_device *rd, const void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size) +{ + const struct incoherent_rdev *irdev; + + irdev = container_of(rd, const struct incoherent_rdev, rdev); + + return rdev_writeat(irdev->write, b, offset, size); +} + +static __SIZE_TYPE__ incoherent_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size) +{ + const struct incoherent_rdev *irdev; + + irdev = container_of(rd, const struct incoherent_rdev, rdev); + + return rdev_eraseat(irdev->write, offset, size); +} + +static const struct region_device_ops incoherent_rdev_ops = { + .mmap = incoherent_mmap, + .munmap = incoherent_munmap, + .readat = incoherent_readat, + .writeat = incoherent_writeat, + .eraseat = incoherent_eraseat, +}; + +const struct region_device *incoherent_rdev_init(struct incoherent_rdev *irdev, + const struct region *r, + const struct region_device *read, + const struct region_device *write) +{ + const __SIZE_TYPE__ size = region_sz(r); + + if (size != region_device_sz(read) || size != region_device_sz(write)) + return NULL; + + /* The region is represented as offset 0 to size. That way, the generic + * rdev operations can be called on the read or write implementation + * without any unnecessary translation because the offsets all start + * at 0. */ + region_device_init(&irdev->rdev, &incoherent_rdev_ops, 0, size); + irdev->read = read; + irdev->write = write; + + return &irdev->rdev; +} diff --git a/UefiPayloadPkg/SPI/region.h b/UefiPayloadPkg/SPI/region.h new file mode 100644 index 000000000000..7d20ad8ce9c5 --- /dev/null +++ b/UefiPayloadPkg/SPI/region.h @@ -0,0 +1,288 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef _REGION_H_ +#define _REGION_H_ + + +#include + +/* + * Region support. + * + * Regions are intended to abstract away the access mechanisms for blocks of + * data. This could be SPI, eMMC, or a memory region as the backing store. + * They are accessed through a region_device. Subregions can be made by + * chaining together multiple region_devices. + */ + +struct region_device; + +/* + * Returns NULL on error otherwise a buffer is returned with the contents of + * the requested data at offset of size. + */ +void *rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size); + +/* Unmap a previously mapped area. Returns 0 on success, < 0 on error. */ +int rdev_munmap(const struct region_device *rd, void *mapping); + +/* + * Returns < 0 on error otherwise returns size of data read at provided + * offset filling in the buffer passed. + */ +__SIZE_TYPE__ rdev_readat(const struct region_device *rd, void *b, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size); + +/* + * Returns < 0 on error otherwise returns size of data wrote at provided + * offset from the buffer passed. + */ +__SIZE_TYPE__ rdev_writeat(const struct region_device *rd, const void *b, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size); + +/* + * Returns < 0 on error otherwise returns size of data erased. + * If eraseat ops is not defined it returns size which indicates + * that operation was successful. + */ +__SIZE_TYPE__ rdev_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size); + +/**************************************** + * Implementation of a region device * + ****************************************/ + +/* + * Create a child region of the parent provided the sub-region is within + * the parent's region. Returns < 0 on error otherwise 0 on success. Note + * that the child device only calls through the parent's operations. + */ +int rdev_chain(struct region_device *child, const struct region_device *parent, + __SIZE_TYPE__ offset, __SIZE_TYPE__ size); + +/* A region_device operations. */ +struct region_device_ops { + void *(*mmap)(const struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); + int (*munmap)(const struct region_device *, void *); + __SIZE_TYPE__ (*readat)(const struct region_device *, void *, __SIZE_TYPE__, __SIZE_TYPE__); + __SIZE_TYPE__ (*writeat)(const struct region_device *, const void *, __SIZE_TYPE__, + __SIZE_TYPE__); + __SIZE_TYPE__ (*eraseat)(const struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); +}; + +struct region { + __SIZE_TYPE__ offset; + __SIZE_TYPE__ size; +}; + +struct region_device { + const struct region_device *root; + const struct region_device_ops *ops; + struct region region; +}; + +#define REGION_DEV_INIT(ops_, offset_, size_) \ + { \ + .root = NULL, \ + .ops = (ops_), \ + .region = { \ + .offset = (offset_), \ + .size = (size_), \ + }, \ + } + +/* Helper to dynamically initialize region device. */ +void region_device_init(struct region_device *rdev, + const struct region_device_ops *ops, __SIZE_TYPE__ offset, + __SIZE_TYPE__ size); + +/* Return 1 if child is subregion of parent, else 0. */ +int region_is_subregion(const struct region *p, const struct region *c); + +static inline __SIZE_TYPE__ region_offset(const struct region *r) +{ + return r->offset; +} + +static inline __SIZE_TYPE__ region_sz(const struct region *r) +{ + return r->size; +} + +static inline __SIZE_TYPE__ region_end(const struct region *r) +{ + return region_offset(r) + region_sz(r); +} + +static inline BOOLEAN region_overlap(const struct region *r1, const struct region *r2) +{ + return (region_end(r1) > region_offset(r2)) && + (region_offset(r1) < region_end(r2)); +} + +static inline const struct region *region_device_region( + const struct region_device *rdev) +{ + return &rdev->region; +} + +static inline __SIZE_TYPE__ region_device_sz(const struct region_device *rdev) +{ + return region_sz(region_device_region(rdev)); +} + +static inline __SIZE_TYPE__ region_device_offset(const struct region_device *rdev) +{ + return region_offset(region_device_region(rdev)); +} + +static inline __SIZE_TYPE__ region_device_end(const struct region_device *rdev) +{ + return region_end(region_device_region(rdev)); +} + +/* Memory map entire region device. Same semantics as rdev_mmap() above. */ +static inline void *rdev_mmap_full(const struct region_device *rd) +{ + return rdev_mmap(rd, 0, region_device_sz(rd)); +} + +static inline int rdev_chain_full(struct region_device *child, + const struct region_device *parent) +{ + /* Chain full size of parent. */ + return rdev_chain(child, parent, 0, region_device_sz(parent)); +} + +/* + * Compute relative offset of the child (c) w.r.t. the parent (p). Returns < 0 + * when child is not within the parent's region. + */ +__SIZE_TYPE__ rdev_relative_offset(const struct region_device *p, + const struct region_device *c); + +struct mem_region_device { + char *base; + struct region_device rdev; +}; + +/* Initialize at runtime a mem_region_device. This would be used when + * the base and size are dynamic or can't be known during linking. + * There are two variants: read-only and read-write. */ +void mem_region_device_ro_init(struct mem_region_device *mdev, void *base, + __SIZE_TYPE__ size); + +void mem_region_device_rw_init(struct mem_region_device *mdev, void *base, + __SIZE_TYPE__ size); + +extern const struct region_device_ops mem_rdev_ro_ops; + +extern const struct region_device_ops mem_rdev_rw_ops; + +/* Statically initialize mem_region_device. */ +#define MEM_REGION_DEV_INIT(base_, size_, ops_) \ + { \ + .base = (void *)(base_), \ + .rdev = REGION_DEV_INIT((ops_), 0, (size_)), \ + } + +#define MEM_REGION_DEV_RO_INIT(base_, size_) \ + MEM_REGION_DEV_INIT(base_, size_, &mem_rdev_ro_ops) \ + +#define MEM_REGION_DEV_RW_INIT(base_, size_) \ + MEM_REGION_DEV_INIT(base_, size_, &mem_rdev_rw_ops) \ + +struct mem_pool { + UINT8 *buf; + __SIZE_TYPE__ size; + UINT8 *last_alloc; + __SIZE_TYPE__ free_offset; +}; + +struct mmap_helper_region_device { + struct mem_pool pool; + struct region_device rdev; +}; + +#define MMAP_HELPER_REGION_INIT(ops_, offset_, size_) \ + { \ + .rdev = REGION_DEV_INIT((ops_), (offset_), (size_)), \ + } + +void mmap_helper_device_init(struct mmap_helper_region_device *mdev, + void *cache, __SIZE_TYPE__ cache_size); + +void *mmap_helper_rdev_mmap(const struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); +int mmap_helper_rdev_munmap(const struct region_device *, void *); + +/* A translated region device provides the ability to publish a region device + * in one address space and use an access mechanism within another address + * space. The sub region is the window within the 1st address space and + * the request is modified prior to accessing the second address space + * provided by access_dev. */ +struct xlate_region_device { + const struct region_device *access_dev; + struct region sub_region; + struct region_device rdev; +}; + +extern const struct region_device_ops xlate_rdev_ro_ops; + +extern const struct region_device_ops xlate_rdev_rw_ops; + +#define XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, sub_size_, \ + parent_sz_, ops_) \ + { \ + .access_dev = access_dev_, \ + .sub_region = { \ + .offset = (sub_offset_), \ + .size = (sub_size_), \ + }, \ + .rdev = REGION_DEV_INIT((ops_), 0, (parent_sz_)), \ + } + +#define XLATE_REGION_DEV_RO_INIT(access_dev_, sub_offset_, sub_size_, \ + parent_sz_) \ + XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \ + sub_size_, parent_sz_, &xlate_rdev_ro_ops), \ + +#define XLATE_REGION_DEV_RW_INIT(access_dev_, sub_offset_, sub_size_, \ + parent_sz_) \ + XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \ + sub_size_, parent_sz_, &xlate_rdev_rw_ops), \ + +/* Helper to dynamically initialize xlate region device. */ +void xlate_region_device_ro_init(struct xlate_region_device *xdev, + const struct region_device *access_dev, + __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, + __SIZE_TYPE__ parent_size); + +void xlate_region_device_rw_init(struct xlate_region_device *xdev, + const struct region_device *access_dev, + __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, + __SIZE_TYPE__ parent_size); + +/* This type can be used for incoherent access where the read and write + * operations are backed by separate drivers. An example is x86 systems + * with memory mapped media for reading but use a spi flash driver for + * writing. One needs to ensure using this object is appropriate in context. */ +struct incoherent_rdev { + struct region_device rdev; + const struct region_device *read; + const struct region_device *write; +}; + +/* Initialize an incoherent_rdev based on the region as well as the read and + * write rdevs. The read and write rdevs should match in size to the passed + * in region. If not the initialization will fail returning NULL. Otherwise + * the function will return a pointer to the containing region_device to + * be used for region operations. Therefore, the lifetime of the returned + * pointer matches the lifetime of the incoherent_rdev object. Likewise, + * the lifetime of the read and write rdev need to match the lifetime of + * the incoherent_rdev object. */ +const struct region_device *incoherent_rdev_init(struct incoherent_rdev *irdev, + const struct region *r, + const struct region_device *read, + const struct region_device *write); + +#endif /* _REGION_H_ */ diff --git a/UefiPayloadPkg/SPI/spi_flash.c b/UefiPayloadPkg/SPI/spi_flash.c deleted file mode 100644 index b2bcbdfe26c5..000000000000 --- a/UefiPayloadPkg/SPI/spi_flash.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include "SPIgeneric.h" - -int spi_flash_vector_helper(const struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)) -{ - int ret; - void *din; - __SIZE_TYPE__ bytes_in; - - if (count < 1 || count > 2) - return -1; - - /* SPI flash commands always have a command first... */ - if (!vectors[0].dout || !vectors[0].bytesout) - return -1; - /* And not read any data during the command. */ - if (vectors[0].din || vectors[0].bytesin) - return -1; - - if (count == 2) { - /* If response bytes requested ensure the buffer is valid. */ - if (vectors[1].bytesin && !vectors[1].din) - return -1; - /* No sends can accompany a receive. */ - if (vectors[1].dout || vectors[1].bytesout) - return -1; - din = vectors[1].din; - bytes_in = vectors[1].bytesin; - } else { - din = NULL; - bytes_in = 0; - } - - ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); - - if (ret) { - vectors[0].status = SPI_OP_FAILURE; - if (count == 2) - vectors[1].status = SPI_OP_FAILURE; - } else { - vectors[0].status = SPI_OP_SUCCESS; - if (count == 2) - vectors[1].status = SPI_OP_SUCCESS; - } - - return ret; -} diff --git a/UefiPayloadPkg/SPI/spi_flash.h b/UefiPayloadPkg/SPI/spi_flash.h deleted file mode 100644 index a6f3668cf040..000000000000 --- a/UefiPayloadPkg/SPI/spi_flash.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef SPI_FLASH_H -#define SPI_FLASH_H - -#include -#include "SPIgeneric.h" - -int spi_flash_vector_helper(const struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)); - - -#endif /* SPI_FLASH_H */ diff --git a/UefiPayloadPkg/SPI/spi_flash copy.c b/UefiPayloadPkg/SPI/spi_flash_internal.c similarity index 79% rename from UefiPayloadPkg/SPI/spi_flash copy.c rename to UefiPayloadPkg/SPI/spi_flash_internal.c index 7a02e9c84b2c..7194d28eb9c7 100644 --- a/UefiPayloadPkg/SPI/spi_flash copy.c +++ b/UefiPayloadPkg/SPI/spi_flash_internal.c @@ -3,8 +3,14 @@ #include #include #include "spi_flash_internal.h" - -static void spi_flash_addr(UINT32 addr, UINT8 *cmd) +#include "SPIgeneric.h" +#include "kconfig.h" +#include "stopwatch.h" +#include "utils.h" +#include "SPI_fvb.h" +#include "own.h" + +static VOID spi_flash_addr(UINT32 addr, UINT8 *cmd) { /* cmd[0] is actual command */ cmd[1] = addr >> 16; @@ -12,8 +18,8 @@ static void spi_flash_addr(UINT32 addr, UINT8 *cmd) cmd[3] = addr >> 0; } -static int do_spi_flash_cmd(const struct spi_slave *spi, const void *dout, - __SIZE_TYPE__ bytes_out, void *din, __SIZE_TYPE__ bytes_in) +static int do_spi_flash_cmd(const struct spi_slave *spi, const VOID *dout, + __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) { int ret; /* @@ -43,8 +49,8 @@ static int do_spi_flash_cmd(const struct spi_slave *spi, const void *dout, return ret; } -static int do_dual_read_cmd(const struct spi_slave *spi, const void *dout, - __SIZE_TYPE__ bytes_out, void *din, __SIZE_TYPE__ bytes_in) +static int do_dual_read_cmd(const struct spi_slave *spi, const VOID *dout, + __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) { int ret; @@ -71,7 +77,7 @@ static int do_dual_read_cmd(const struct spi_slave *spi, const void *dout, return ret; } -int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, void *response, __SIZE_TYPE__ len) +int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) { int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); if (ret) @@ -87,7 +93,7 @@ int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, void *response, __SIZE #endif #pragma GCC diagnostic ignored "-Wvla" int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, - __SIZE_TYPE__ cmd_len, const void *data, __SIZE_TYPE__ data_len) + __SIZE_TYPE__ cmd_len, const VOID *data, __SIZE_TYPE__ data_len) { int ret; UINT8 buff[cmd_len + data_len]; @@ -107,13 +113,12 @@ int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, /* Perform the read operation honoring spi controller fifo size, reissuing * the read command until the full request completed. */ int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, void *buf) + __SIZE_TYPE__ len, VOID *buf) { UINT8 cmd[5]; int ret, cmd_len; - int (*do_cmd)(const struct spi_slave *spi, const void *din, - __SIZE_TYPE__ in_bytes, void *out, __SIZE_TYPE__ out_bytes); - + int (*do_cmd)(const struct spi_slave *spi, const VOID *din, + __SIZE_TYPE__ in_bytes, VOID *out, __SIZE_TYPE__ out_bytes); if (CONFIG(SPI_FLASH_NO_FAST_READ)) { cmd_len = 4; cmd[0] = CMD_READ_ARRAY_SLOW; @@ -130,7 +135,7 @@ int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, do_cmd = do_spi_flash_cmd; } - uint8_t *data = buf; + UINT8 *data = buf; while (len) { __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); spi_flash_addr(offset, cmd); @@ -223,7 +228,8 @@ int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYP goto out; } - DEBUG(EFI_D_INFO, "%a SF: Successfully erased %zu bytes @ %#x\n", __FUNCTION__, len, start)); + DEBUG((EFI_D_INFO, "%a SF: Successfully erased %zu bytes @ %#x\n", + __FUNCTION__, len, start)); out: return ret; @@ -235,7 +241,7 @@ int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg) } int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, const void *buf) + __SIZE_TYPE__ len, const VOID *buf) { unsigned long byte_addr; unsigned long page_size; @@ -279,9 +285,10 @@ int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offse offset += chunk_len; } - if (CONFIG(DEBUG_SPI_FLASH)) + if (CONFIG(DEBUG_SPI_FLASH)) { DEBUG((EFI_D_INFO, "%a SF: : Successfully programmed %zu bytes @ 0x%lx\n", - __FUNCTION__, len, (unsigned long)(offset - len)); + __FUNCTION__, len, (unsigned long)(offset - len))); + } ret = 0; out: @@ -357,10 +364,10 @@ static int fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash, } static const struct spi_flash_part_id *find_part(const struct spi_flash_vendor_info *vi, - uint16_t id[2]) + UINT16 id[2]) { __SIZE_TYPE__ i; - const uint16_t lid[2] = { + const UINT16 lid[2] = { [0] = id[0] & vi->match_id_mask[0], [1] = id[1] & vi->match_id_mask[1], }; @@ -377,7 +384,7 @@ static const struct spi_flash_part_id *find_part(const struct spi_flash_vendor_i } static int find_match(const struct spi_slave *spi, struct spi_flash *flash, - uint8_t manuf_id, uint16_t id[2]) + UINT8 manuf_id, UINT16 id[2]) { int i; @@ -417,13 +424,13 @@ int spi_flash_generic_probe(const struct spi_slave *spi, if (CONFIG(DEBUG_SPI_FLASH)) { DEBUG((EFI_D_INFO, "SF: Got idcode: ")); for (i = 0; i < sizeof(idcode); i++) - DEBUG(EFI_D_INFO, "%02x ", idcode[i])); - DEBUG((EFI_D_INFO, "\n"); + DEBUG((EFI_D_INFO, "%02x ", idcode[i])); + DEBUG((EFI_D_INFO, "\n")); } manuf_id = idcode[0]; - DEBUG(EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); + DEBUG((EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); /* If no result from RDID command and STMicro parts are enabled attempt to wake the part from deep sleep and obtain alternative id info. */ @@ -466,27 +473,29 @@ int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash) const char *mode_string = ""; if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) mode_string = " (Dual SPI mode)"; - DEBUG(EFI_D_INFO, + DEBUG((EFI_D_INFO, "%a SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", __FUNCTION__, flash->vendor, flash->model, flash->sector_size, flash->size, mode_string)); + /* if (bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS && flash->size != CONFIG_ROM_SIZE) { - DEBUG(EFI_D_INFO, "%a SF size 0x%x does not correspond to" + DEBUG((EFI_D_INFO, "%a SF size 0x%x does not correspond to" " CONFIG_ROM_SIZE 0x%x!!\n", __FUNCTION__, flash->size, CONFIG_ROM_SIZE)); } + */ return 0; } int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - void *buf) + VOID *buf) { return flash->ops->read(flash, offset, len, buf); } int spi_flash_write(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - const void *buf) + const VOID *buf) { int ret; @@ -527,18 +536,18 @@ int spi_flash_status(const struct spi_flash *flash, UINT8 *reg) int spi_flash_is_write_protected(const struct spi_flash *flash, const struct region *region) { - struct region flash_region = { 0 }; + // struct region flash_region = { 0 }; if (!flash || !region) return -1; - flash_region.size = flash->size; + // flash_region.size = flash->size; - if (!region_is_subregion(&flash_region, region)) - return -1; + // if (!region_is_subregion(&flash_region, region)) + // return -1; if (!flash->prot_ops) { - DEBUG(EFI_D_INFO, "%a SPI: Write-protection gathering not " + DEBUG((EFI_D_INFO, "%a SPI: Write-protection gathering not " "implemented for this vendor.\n", __FUNCTION__)); return -1; } @@ -550,19 +559,19 @@ int spi_flash_set_write_protected(const struct spi_flash *flash, const struct region *region, const enum spi_flash_status_reg_lockdown mode) { - struct region flash_region = { 0 }; + // struct region flash_region = { 0 }; int ret; if (!flash) return -1; - flash_region.size = flash->size; + // flash_region.size = flash->size; - if (!region_is_subregion(&flash_region, region)) - return -1; + // if (!region_is_subregion(&flash_region, region)) + // return -1; if (!flash->prot_ops) { - DEBUG(EFI_D_INFO, "%a SPI: Setting write-protection is not " + DEBUG((EFI_D_INFO, "%a SPI: Setting write-protection is not " "implemented for this vendor.\n", __FUNCTION__)); return -1; } @@ -570,22 +579,22 @@ int spi_flash_set_write_protected(const struct spi_flash *flash, ret = flash->prot_ops->set_write(flash, region, mode); if (ret == 0 && mode != SPI_WRITE_PROTECTION_PRESERVE) { - DEBUG(EFI_D_INFO, "%a SPI: SREG lock-down was set to ", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a SPI: SREG lock-down was set to ", __FUNCTION__)); switch (mode) { case SPI_WRITE_PROTECTION_NONE: - DEBUG(EFI_D_INFO, "%a NEVER\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a NEVER\n", __FUNCTION__)); break; case SPI_WRITE_PROTECTION_PIN: - DEBUG(EFI_D_INFO, "%a WP\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a WP\n", __FUNCTION__)); break; case SPI_WRITE_PROTECTION_REBOOT: - DEBUG(EFI_D_INFO, "%a REBOOT\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a REBOOT\n", __FUNCTION__)); break; case SPI_WRITE_PROTECTION_PERMANENT: - DEBUG(EFI_D_INFO, "%a PERMANENT\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a PERMANENT\n", __FUNCTION__)); break; default: - DEBUG(EFI_D_INFO, "%a UNKNOWN\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a UNKNOWN\n", __FUNCTION__)); break; } } @@ -593,11 +602,11 @@ int spi_flash_set_write_protected(const struct spi_flash *flash, return ret; } -static uint32_t volatile_group_count; +static UINT32 volatile_group_count; int spi_flash_volatile_group_begin(const struct spi_flash *flash) { - uint32_t count; + UINT32 count; int ret = 0; if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) @@ -614,14 +623,14 @@ int spi_flash_volatile_group_begin(const struct spi_flash *flash) int spi_flash_volatile_group_end(const struct spi_flash *flash) { - uint32_t count; + UINT32 count; int ret = 0; if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) return ret; count = volatile_group_count; - assert(count == 0); + // assert(count == 0); count--; volatile_group_count = count; @@ -631,33 +640,34 @@ int spi_flash_volatile_group_end(const struct spi_flash *flash) return ret; } -void lb_spi_flash(struct lb_header *header) -{ - struct lb_spi_flash *flash; - const struct spi_flash *spi_flash_dev; +// VOID lb_spi_flash(struct lb_header *header) +// { +// struct lb_spi_flash *flash; +// const struct spi_flash *spi_flash_dev; - if (!CONFIG(BOOT_DEVICE_SPI_FLASH)) - return; +// if (!CONFIG(BOOT_DEVICE_SPI_FLASH)) +// return; - flash = (struct lb_spi_flash *)lb_new_record(header); +// flash = (struct lb_spi_flash *)lb_new_record(header); - flash->tag = LB_TAG_SPI_FLASH; - flash->size = sizeof(*flash); +// flash->tag = LB_TAG_SPI_FLASH; +// flash->size = sizeof(*flash); - spi_flash_dev = boot_device_spi_flash(); +// spi_flash_dev = boot_device_spi_flash(); - if (spi_flash_dev) { - flash->flash_size = spi_flash_dev->size; - flash->sector_size = spi_flash_dev->sector_size; - flash->erase_cmd = spi_flash_dev->erase_cmd; - } else { - flash->flash_size = CONFIG_ROM_SIZE; - /* Default 64k erase command should work on most flash. - * Uniform 4k erase only works on certain devices. */ - flash->sector_size = 64 * KiB; - flash->erase_cmd = CMD_BLOCK_ERASE; - } -} +// if (spi_flash_dev) { +// flash->flash_size = spi_flash_dev->size; +// flash->sector_size = spi_flash_dev->sector_size; +// flash->erase_cmd = spi_flash_dev->erase_cmd; +// } else { +// #define CONFIG_ROM_SIZE 0x400000; +// flash->flash_size = CONFIG_ROM_SIZE; +// /* Default 64k erase command should work on most flash. +// * Uniform 4k erase only works on certain devices. */ +// flash->sector_size = 64 * KiB; +// flash->erase_cmd = CMD_BLOCK_ERASE; +// } +// } int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, @@ -665,15 +675,15 @@ int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, const enum ctrlr_prot_type type) { const struct spi_ctrlr *ctrlr; - struct region flash_region = { 0 }; + // struct region flash_region = { 0 }; if (!flash) return -1; - flash_region.size = flash->size; + // flash_region.size = flash->size; - if (!region_is_subregion(&flash_region, region)) - return -1; + // if (!region_is_subregion(&flash_region, region)) + // return -1; ctrlr = flash->spi.ctrlr; @@ -686,13 +696,62 @@ int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, return -1; } +// int region_is_subregion(const struct region *p, const struct region *c) +// { +// if (region_offset(c) < region_offset(p)) +// return 0; + +// if (region_end(c) > region_end(p)) +// return 0; + +// if (region_end(c) < region_offset(c)) +// return 0; + +// return 1; +// } + +// inline __SIZE_TYPE__ region_offset(const struct region *r) +// { +// return r->offset; +// } + +// inline __SIZE_TYPE__ region_end(const struct region *r) +// { +// return region_offset(r) + region_sz(r); +// } + +// inline __SIZE_TYPE__ region_sz(const struct region *r) +// { +// return r->size; +// } + +int chipset_volatile_group_begin(const struct spi_flash *flash) +{ + return 0; + // if (!CONFIG(HUDSON_IMC_FWM)) + // return 0; + + // ImcSleep(NULL); + // return 0; +} + +int chipset_volatile_group_end(const struct spi_flash *flash) +{ + return 0; + // if (!CONFIG(HUDSON_IMC_FWM)) + // return 0; + + // ImcWakeup(NULL); + // return 0; +} + int spi_flash_vector_helper(const struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const void *dout, - __SIZE_TYPE__ bytesout, void *din, __SIZE_TYPE__ bytesin)) + int (*func)(const struct spi_slave *slave, const VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) { int ret; - void *din; + VOID *din; __SIZE_TYPE__ bytes_in; if (count < 1 || count > 2) diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h index b4d39b3d3120..8c5ba3a89c6a 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.h +++ b/UefiPayloadPkg/SPI/spi_flash_internal.h @@ -7,6 +7,9 @@ #ifndef SPI_FLASH_INTERNAL_H #define SPI_FLASH_INTERNAL_H +#include +#include "SPI_fvb.h" + /* Common commands */ #define CMD_READ_ID 0x9f @@ -25,18 +28,18 @@ #define STATUS_WIP 0x01 /* Send a single-byte command to the device and read the response */ -int spi_flash_cmd(const struct spi_slave *spi, u8 cmd, void *response, size_t len); +int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); /* * Send a multi-byte command to the device followed by (optional) * data. Used for programming the flash array, etc. */ -int spi_flash_cmd_write(const struct spi_slave *spi, const u8 *cmd, - size_t cmd_len, const void *data, size_t data_len); +int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, + __SIZE_TYPE__ cmd_len, const VOID *data, __SIZE_TYPE__ data_len); /* Send a command to the device and wait for some bit to clear itself. */ int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, - u8 cmd, u8 poll_bit); + UINT8 cmd, UINT8 poll_bit); /* * Send the read status command to the device and wait for the wip @@ -45,20 +48,33 @@ int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout); /* Erase sectors. */ -int spi_flash_cmd_erase(const struct spi_flash *flash, u32 offset, size_t len); +int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); /* Read status register. */ -int spi_flash_cmd_status(const struct spi_flash *flash, u8 *reg); +int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg); /* Write to flash utilizing page program semantics. */ -int spi_flash_cmd_write_page_program(const struct spi_flash *flash, u32 offset, - size_t len, const void *buf); +int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, const VOID *buf); /* Read len bytes into buf at offset. */ -int spi_flash_cmd_read(const struct spi_flash *flash, u32 offset, size_t len, void *buf); +int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); /* Release from deep sleep an provide alternative rdid information. */ -int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, u8 *idcode); +int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idcode); + +int spi_flash_volatile_group_begin(const struct spi_flash *flash); +int spi_flash_volatile_group_end(const struct spi_flash *flash); +// int region_is_subregion(const struct region *p, const struct region *c); +int chipset_volatile_group_begin(const struct spi_flash *flash); +int chipset_volatile_group_end(const struct spi_flash *flash); +// inline __SIZE_TYPE__ region_offset(const struct region *r); +// inline __SIZE_TYPE__ region_end(const struct region *r); +// inline __SIZE_TYPE__ region_sz(const struct region *r); +int spi_flash_vector_helper(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + int (*func)(const struct spi_slave *slave, const VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)); struct spi_flash_part_id { /* rdid command constructs 2x 16-bit id using the following method @@ -66,21 +82,21 @@ struct spi_flash_part_id { * id[0] = (id[1] << 8) | id[2] * id[1] = (id[3] << 8) | id[4] */ - uint16_t id[2]; + UINT16 id[2]; /* Log based 2 total number of sectors. */ - uint16_t nr_sectors_shift: 4; - uint16_t fast_read_dual_output_support : 1; - uint16_t _reserved_for_flags: 3; + UINT16 nr_sectors_shift: 4; + UINT16 fast_read_dual_output_support : 1; + UINT16 _reserved_for_flags: 3; /* Block protection. Currently used by Winbond. */ - uint16_t protection_granularity_shift : 5; - uint16_t bp_bits : 3; + UINT16 protection_granularity_shift : 5; + UINT16 bp_bits : 3; }; struct spi_flash_ops_descriptor { - uint8_t erase_cmd; /* Sector Erase */ - uint8_t status_cmd; /* Read Status Register */ - uint8_t pp_cmd; /* Page program command, if supported. */ - uint8_t wren_cmd; /* Write Enable command. */ + UINT8 erase_cmd; /* Sector Erase */ + UINT8 status_cmd; /* Read Status Register */ + UINT8 pp_cmd; /* Page program command, if supported. */ + UINT8 wren_cmd; /* Write Enable command. */ struct spi_flash_ops ops; }; @@ -88,13 +104,13 @@ struct spi_flash_ops_descriptor { * vendor. One can implement multiple sets from a single vendor by having * separate objects. */ struct spi_flash_vendor_info { - uint8_t id; - uint8_t page_size_shift : 4; /* if page programming oriented. */ + UINT8 id; + UINT8 page_size_shift : 4; /* if page programming oriented. */ /* Log based 2 sector size */ - uint8_t sector_size_kib_shift : 4; - uint16_t nr_part_ids; + UINT8 sector_size_kib_shift : 4; + UINT16 nr_part_ids; const struct spi_flash_part_id *ids; - uint16_t match_id_mask[2]; /* matching bytes of the id for this set*/ + UINT16 match_id_mask[2]; /* matching bytes of the id for this set*/ const struct spi_flash_ops_descriptor *desc; const struct spi_flash_protection_ops *prot_ops; /* Returns 0 on success. !0 otherwise. */ diff --git a/UefiPayloadPkg/SPI/utils.h b/UefiPayloadPkg/SPI/utils.h index 00b5d2ece31b..faf3a8f72d4f 100644 --- a/UefiPayloadPkg/SPI/utils.h +++ b/UefiPayloadPkg/SPI/utils.h @@ -7,4 +7,6 @@ #define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) #define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0) +#define KiB (1<<10) + #endif /* UTILS_H */ diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/winbond.c index e151df5c7a80..1d0cf43d147b 100644 --- a/UefiPayloadPkg/SPI/winbond.c +++ b/UefiPayloadPkg/SPI/winbond.c @@ -1,6 +1,9 @@ #include -#include #include +#include "spi_winbond.h" +#include "spi_flash_internal.h" +#include "SPIgeneric.h" +#include "SPI_fvb.h" union status_reg1 { UINT8 u; @@ -204,14 +207,14 @@ static const struct spi_flash_part_id flash_table[] = { * Convert BPx, TB and CMP to a region. * SEC (if available) must be zero. */ -static void winbond_bpbits_to_region(const size_t granularity, +static void winbond_bpbits_to_region(const __SIZE_TYPE__ granularity, const UINT8 bp, - bool tb, - const bool cmp, - const size_t flash_size, + BOOLEAN tb, + const BOOLEAN cmp, + const __SIZE_TYPE__ flash_size, struct region *out) { - size_t protected_size = + __SIZE_TYPE__ protected_size = MIN(bp ? granularity << (bp - 1) : 0, flash_size); if (cmp) { @@ -247,7 +250,7 @@ static int winbond_get_write_protection(const struct spi_flash *flash, if (!params) return -1; - const size_t granularity = (1 << params->protection_granularity_shift); + const __SIZE_TYPE__ granularity = (1 << params->protection_granularity_shift); union status_reg1 reg1 = { .u = 0 }; @@ -285,9 +288,8 @@ static int winbond_get_write_protection(const struct spi_flash *flash, return 0; } - - printk(BIOS_DEBUG, "WINBOND: flash protected range 0x%08zx-0x%08zx\n", - region_offset(&wp_region), region_end(&wp_region)); + DEBUG((EFI_D_INFO, "%a WINBOND: flash protected range 0x%08zx-0x%08zx\n", + __FUNCTION__, region_offset(&wp_region), region_end(&wp_region))); return region_is_subregion(&wp_region, region); } @@ -306,12 +308,12 @@ static int winbond_get_write_protection(const struct spi_flash *flash, static int winbond_flash_cmd_status(const struct spi_flash *flash, const UINT16 mask, const UINT16 val, - const bool non_volatile) + const BOOLEAN non_volatile) { struct { UINT8 cmd; UINT16 sreg; - } __packed cmdbuf; + } __attribute__((packed)) cmdbuf; UINT8 reg8; int ret; @@ -375,13 +377,14 @@ static int winbond_flash_cmd_status(const struct spi_flash *flash, cmdbuf.sreg |= reg8 << 8; - printk(BIOS_DEBUG, "WINBOND: SREG=%02x SREG2=%02x\n", + DEBUG((EFI_D_INFO, "%a WINBOND: SREG=%02x SREG2=%02x\n", + __FUNCTION__, cmdbuf.sreg & 0xff, - cmdbuf.sreg >> 8); + cmdbuf.sreg >> 8)); /* Compare against expected result */ if ((val & mask) != (cmdbuf.sreg & mask)) { - DEBUG(((EFI_D_INFO, "%a WINBOND: SREG is locked!\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "%a WINBOND: SREG is locked!\n", __FUNCTION__)); ret = -1; } @@ -509,12 +512,12 @@ winbond_set_write_protection(const struct spi_flash *flash, mask.reg2.srp1 = 1; } - ret = winbond_flash_cmd_status(flash, mask.u, val.u, true); + ret = winbond_flash_cmd_status(flash, mask.u, val.u, TRUE); if (ret) return ret; - - printk(BIOS_DEBUG, "WINBOND: write-protection set to range " - "0x%08zx-0x%08zx\n", region_offset(region), region_end(region)); + DEBUG((EFI_D_INFO, "%a WINBOND: write-protection set to range " + "0x%08zx-0x%08zx\n", __FUNCTION__, + region_offset(region), region_end(region))); return ret; } From af672bd4ea4bf9b3fe8c25f6d6474de0fa9cd99f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 9 Oct 2020 12:56:13 +0200 Subject: [PATCH 250/297] try to fix invalid SPI response --- UefiPayloadPkg/SPI/SPI_fvb.c | 2 +- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 16 +++++----- UefiPayloadPkg/SPI/fch_spi_ctrl.h | 7 ++++ UefiPayloadPkg/SPI/fch_spi_util.c | 53 ++++++------------------------- UefiPayloadPkg/SPI/lpc.c | 5 ++- UefiPayloadPkg/SPI/pci_ops.h | 18 +++++++++-- 6 files changed, 46 insertions(+), 55 deletions(-) diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index f7ab95128d2b..206120df785d 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -70,7 +70,7 @@ EFI_STATUS EFIAPI SPIInitialize ( DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); DEBUG((EFI_D_INFO, "0x%X\n", slave.ctrlr->xfer)); char fill[255]; - DEBUG((EFI_D_INFO, "spi_flash_cmd() returned 0x%X hihi\n", spi_flash_cmd(&slave, CMD_READ_ID, &fill, 5))); + DEBUG((EFI_D_INFO, "spi_flash_cmd() returned 0x%X\n", spi_flash_cmd(&slave, CMD_READ_ID, &fill, 5))); DEBUG((EFI_D_INFO, "%X %X %X %X %X\n", fill[0], fill[1], fill[2], fill[3], fill[4])); struct spi_op vector = { .dout = "asdf8888", diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index bd9470ff92c0..fbe40a3b8d5a 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -34,7 +34,7 @@ #define SPI_FIFO_RD_PTR_SHIFT 16 #define SPI_FIFO_RD_PTR_MASK 0x7f -static VOID dump_state(CONST char *str, UINT8 phase) +VOID dump_state(CONST char *str, UINT8 phase) { UINT8 dump_size; UINT32 addr; @@ -62,7 +62,7 @@ static VOID dump_state(CONST char *str, UINT8 phase) } } -static int wait_for_ready(VOID) +int wait_for_ready(VOID) { CONST UINT32 timeout_ms = 500; struct stopwatch sw; @@ -77,7 +77,7 @@ static int wait_for_ready(VOID) return -1; } -static int execute_command(VOID) +int execute_command(VOID) { dump_state("Before execute", 0); @@ -98,7 +98,7 @@ VOID spi_init(VOID) DEBUG((EFI_D_INFO, "%a: %s: SPI BAR at 0x%08lx\n", __FUNCTION__, __func__, spi_get_bar())); } -static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, +int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { __SIZE_TYPE__ count; @@ -146,13 +146,13 @@ static int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, return 0; } -static int xfer_vectors(CONST struct spi_slave *slave, +int xfer_vectors(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count) { return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); } -static int protect_a_range(UINT32 value) +int protect_a_range(UINT32 value) { UINT32 reg32; UINT8 n; @@ -183,7 +183,7 @@ static int protect_a_range(UINT32 value) * and second region is read protection, it's best to define first region as read and write * protection. */ -static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, +int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, CONST enum ctrlr_prot_type type) { int ret; @@ -260,7 +260,7 @@ static int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct reg return 0; } -static CONST struct spi_ctrlr fch_spi_flash_ctrlr = { +CONST struct spi_ctrlr fch_spi_flash_ctrlr = { .xfer = spi_ctrlr_xfer, .xfer_vector = xfer_vectors, .max_xfer_size = SPI_FIFO_DEPTH, diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.h b/UefiPayloadPkg/SPI/fch_spi_ctrl.h index 62a113402c0c..7977adc28558 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.h +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.h @@ -10,6 +10,13 @@ #include "fch_spi_util.h" #include "SPIgeneric.h" +union pci_bank { + UINT8 reg8[4096]; + UINT16 reg16[4096 / sizeof(UINT16)]; + UINT32 reg32[4096 / sizeof(UINT32)]; +}; + +union pci_bank *pcicfg(pci_devfn_t dev); VOID dump_state(CONST char *str, UINT8 phase); int wait_for_ready(VOID); int execute_command(VOID); diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index d61d245628e6..0f85f2e231c0 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -10,13 +10,7 @@ #include "pci_mmio_cfg.h" #include "device.h" -static unsigned long int spi_base = 0xF8000000; - -union pci_bank { - UINT8 reg8[4096]; - UINT16 reg16[4096 / sizeof(UINT16)]; - UINT32 reg32[4096 / sizeof(UINT32)]; -}; +static unsigned long int spi_base = 0; VOID spi_set_base(VOID *base) { @@ -24,49 +18,22 @@ VOID spi_set_base(VOID *base) spi_base = (unsigned long int)base; } -static //__attribute__ ((__always_inline__)) +//static //__attribute__ ((__always_inline__)) union pci_bank *pcicfg(pci_devfn_t dev) { - UINT8 *pci_mmconf = (void *)(unsigned long int)spi_base; + UINT8 *pci_mmconf =(void *)((unsigned long int)(0xF8000000)); + DEBUG((EFI_D_INFO, "%a pci_mmconf = 0x%X, dev = 0x%X, PCI_DEVFN_OFFSET(dev) = 0x%X\n", __FUNCTION__, pci_mmconf, dev, PCI_DEVFN_OFFSET(dev))); + DEBUG((EFI_D_INFO, "%a returned address = 0x%X\n", __FUNCTION__, (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)])); return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } -static //__attribute__ ((__always_inline__)) -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -static //__attribute__ ((__always_inline__)) -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -static //__attribute__ ((__always_inline__)) -pci_devfn_t pcidev_bdf(CONST struct device *dev) -{ - return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -} - -static //__attribute__ ((__always_inline__)) -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -{ - return pci_s_read_config32(pcidev_bdf(dev), reg); -} - unsigned long int spi_get_bar(VOID) { - UINT32 base; - - base = pci_read_config32((VOID *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); - base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); - return (unsigned long int)base; - // DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - // if (!spi_base) - // spi_set_base((VOID *)lpc_get_spibase()); - - // return spi_base; + if (spi_base == 0) + DEBUG((EFI_D_INFO, "%a calling lpc_get_spibase()\n", __FUNCTION__)); + spi_set_base((VOID *)lpc_get_spibase()); + DEBUG((EFI_D_INFO, "%a spi_base = 0x%X\n", __FUNCTION__, spi_base)); + return spi_base; } UINT8 spi_read8(UINT8 reg) diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index dc1e3fe7b156..494fc54bdb65 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -8,8 +8,11 @@ unsigned long int lpc_get_spibase(void) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT32 base; - + DEBUG((EFI_D_INFO, "%a _LPCB_DEV = 0x%X\n", __FUNCTION__, _LPCB_DEV)); + DEBUG((EFI_D_INFO, "%a SPIROM_BASE_ADDRESS_REGISTER = 0x%X\n", __FUNCTION__, SPIROM_BASE_ADDRESS_REGISTER)); base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); + DEBUG((EFI_D_INFO, "%a base before align 0x%X\n", __FUNCTION__, base)); base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); + DEBUG((EFI_D_INFO, "%a base after align 0x%X\n", __FUNCTION__, base)); return (unsigned long int)base; } diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 383840f981cd..02b8eefa9f8c 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -13,6 +13,19 @@ #include "device.h" #include "pci_mmio_cfg.h" #include "fch_spi_util.h" +#include "fch_spi_ctrl.h" + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +static __attribute__ ((__always_inline__)) inline +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; +} static __attribute__ ((__always_inline__)) inline UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) @@ -39,7 +52,6 @@ pci_devfn_t pcidev_assert(CONST struct device *dev) { if (!dev) { DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); - while(1); } return pcidev_bdf(dev); } @@ -47,7 +59,9 @@ pci_devfn_t pcidev_assert(CONST struct device *dev) static __attribute__ ((__always_inline__)) inline UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) { - return pci_s_read_config32(PCI_BDF(dev), reg); + DEBUG((EFI_D_INFO, "%a: PCI_BDF = 0x%X\n", __FUNCTION__, PCI_BDF(dev))); + return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); + //return pci_s_read_config32(PCI_BDF(dev), reg); } static __attribute__ ((__always_inline__)) inline From 60371cc4fd78b29ca91f9d51b47c96141520e2eb Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 12 Oct 2020 14:55:26 +0200 Subject: [PATCH 251/297] UefiPayloadPkg/SPI/Fvb.c: Implement reading from SPI flash memory --- UefiPayloadPkg/SPI/Fvb.c | 47 +++++++++++++++---------------- UefiPayloadPkg/SPI/SPI_fvb.c | 31 +++++++++++--------- UefiPayloadPkg/SPI/SPIgeneric.c | 3 -- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 3 +- UefiPayloadPkg/SPI/fch_spi_util.c | 11 +++----- UefiPayloadPkg/SPI/lpc.c | 5 ---- UefiPayloadPkg/SPI/pci_ops.h | 1 - 7 files changed, 46 insertions(+), 55 deletions(-) diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 1b96b9785216..451aa7627209 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -1,6 +1,8 @@ #include "BlSMMStoreDxe.h" #include "Fvb.h" #include "SPI_fvb.h" +#include "SPIgeneric.h" +#include "spi_flash_internal.h" // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; @@ -222,35 +224,32 @@ FvbRead ( IN OUT UINT8 *Buffer ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - UINTN BlockSize; - SMMSTORE_INSTANCE *Instance; - - Instance = INSTANCE_FROM_FVB_THIS(This); - - DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); - - // Cache the block size to avoid de-referencing pointers all the time - BlockSize = Instance->Media.BlockSize; - - DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); - - // The read must not span block boundaries. - // We need to check each variable individually because adding two large values together overflows. - if ((Offset >= BlockSize) || - (*NumBytes > BlockSize) || - ((Offset + *NumBytes) > BlockSize)) { - DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + struct spi_slave slave; + if(Lba != 0) { + DEBUG((EFI_D_INFO, "%a Only block 0 is supported!\n", __FUNCTION__)); + return EFI_ACCESS_DENIED; + } + if(Buffer == NULL || *NumBytes == 0) { + DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; } + spi_setup_slave(0, 0, &slave); + UINT8 command[4] = { + CMD_READ_ARRAY_SLOW, + (UINT8)((Offset & 0xFF0000) >> 16), + (UINT8)((Offset & 0xFF00) >> 8), + (UINT8) (Offset & 0xFF), + }; + if(spi_xfer(&slave, command, 4, Buffer, *NumBytes) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } - // We must have some bytes to read - if (*NumBytes == 0) { - return EFI_BAD_BUFFER_SIZE; + for(int counter = 0; counter < *NumBytes; ++counter) { + DEBUG((EFI_D_INFO, "%DUMP %X\n", Buffer[counter])); } - return EFI_DEVICE_ERROR; - //return SMMStoreRead (Lba, Offset, NumBytes, Buffer); + return EFI_SUCCESS; } /** diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 206120df785d..7e57740c75fd 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -48,30 +48,35 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_SYSTEM_TABLE *SystemTable ) { - // EFI_STATUS Status; + EFI_STATUS Status; struct spi_slave slave; DEBUG((EFI_D_INFO, "SPI IS HERE 2\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - // Status = gBS->InstallMultipleProtocolInterfaces ( - // &Handle, - // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - // NULL - // ); - // if(EFI_ERROR (Status)) { - // DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - // } else { - // DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); - // } + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); + if(EFI_ERROR (Status)) { + DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + } else { + DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); + } DEBUG((EFI_D_INFO, "calling spi_init()\n")); spi_init(); DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); DEBUG((EFI_D_INFO, "0x%X\n", slave.ctrlr->xfer)); - char fill[255]; + unsigned char fill[255]; DEBUG((EFI_D_INFO, "spi_flash_cmd() returned 0x%X\n", spi_flash_cmd(&slave, CMD_READ_ID, &fill, 5))); - DEBUG((EFI_D_INFO, "%X %X %X %X %X\n", fill[0], fill[1], fill[2], fill[3], fill[4])); + DEBUG((EFI_D_INFO, "%X %X %X %X %X\n", + (unsigned int)(unsigned char)fill[0], + (unsigned int)(unsigned char)fill[1], + (unsigned int)(unsigned char)fill[2], + (unsigned int)(unsigned char)fill[3], + (unsigned int)(unsigned char)fill[4])); struct spi_op vector = { .dout = "asdf8888", .bytesout = 8, diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index f8285adbe77c..64dcc6397322 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -70,10 +70,7 @@ UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, __SIZE_TYPE__ b CONST struct spi_ctrlr *ctrlr = slave->ctrlr; if (ctrlr && ctrlr->xfer) { - DEBUG((EFI_D_INFO, "xfer available\n")); return ctrlr->xfer(slave, dout, bytesout, din, bytesin); - } else { - DEBUG((EFI_D_INFO, "xfer failed\n")); } return -1; diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index fbe40a3b8d5a..f71b1f8b76eb 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -94,8 +94,7 @@ int execute_command(VOID) VOID spi_init(VOID) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - DEBUG((EFI_D_INFO, "%a: %s: SPI BAR at 0x%08lx\n", __FUNCTION__, __func__, spi_get_bar())); + spi_get_bar(); } int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index 0f85f2e231c0..bec465b8add2 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -14,25 +14,22 @@ static unsigned long int spi_base = 0; VOID spi_set_base(VOID *base) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); spi_base = (unsigned long int)base; } //static //__attribute__ ((__always_inline__)) union pci_bank *pcicfg(pci_devfn_t dev) { + // FIXME this should not be a magic constant UINT8 *pci_mmconf =(void *)((unsigned long int)(0xF8000000)); - DEBUG((EFI_D_INFO, "%a pci_mmconf = 0x%X, dev = 0x%X, PCI_DEVFN_OFFSET(dev) = 0x%X\n", __FUNCTION__, pci_mmconf, dev, PCI_DEVFN_OFFSET(dev))); - DEBUG((EFI_D_INFO, "%a returned address = 0x%X\n", __FUNCTION__, (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)])); return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } unsigned long int spi_get_bar(VOID) { - if (spi_base == 0) - DEBUG((EFI_D_INFO, "%a calling lpc_get_spibase()\n", __FUNCTION__)); - spi_set_base((VOID *)lpc_get_spibase()); - DEBUG((EFI_D_INFO, "%a spi_base = 0x%X\n", __FUNCTION__, spi_base)); + if (spi_base == 0) { + spi_set_base((VOID *)lpc_get_spibase()); + } return spi_base; } diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c index 494fc54bdb65..6aa21ecbd294 100644 --- a/UefiPayloadPkg/SPI/lpc.c +++ b/UefiPayloadPkg/SPI/lpc.c @@ -6,13 +6,8 @@ unsigned long int lpc_get_spibase(void) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT32 base; - DEBUG((EFI_D_INFO, "%a _LPCB_DEV = 0x%X\n", __FUNCTION__, _LPCB_DEV)); - DEBUG((EFI_D_INFO, "%a SPIROM_BASE_ADDRESS_REGISTER = 0x%X\n", __FUNCTION__, SPIROM_BASE_ADDRESS_REGISTER)); base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); - DEBUG((EFI_D_INFO, "%a base before align 0x%X\n", __FUNCTION__, base)); base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); - DEBUG((EFI_D_INFO, "%a base after align 0x%X\n", __FUNCTION__, base)); return (unsigned long int)base; } diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 02b8eefa9f8c..cd9d896f9f93 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -59,7 +59,6 @@ pci_devfn_t pcidev_assert(CONST struct device *dev) static __attribute__ ((__always_inline__)) inline UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) { - DEBUG((EFI_D_INFO, "%a: PCI_BDF = 0x%X\n", __FUNCTION__, PCI_BDF(dev))); return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); //return pci_s_read_config32(PCI_BDF(dev), reg); } From 9719bd77b3f628b3d125170ef953bc2b3ae6a2db Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 13 Oct 2020 15:05:58 +0200 Subject: [PATCH 252/297] UefiPayloadPkg/SPI/Fvb.h: fix FvbRead, first implement FvbWrite and FvbEraseBlocks --- UefiPayloadPkg/SPI/Fvb.c | 186 +++++++++++++++++++++--- UefiPayloadPkg/SPI/Fvb.h | 4 + UefiPayloadPkg/SPI/SPI_fvb.c | 47 +++--- UefiPayloadPkg/SPI/spi_flash_internal.h | 11 ++ 4 files changed, 204 insertions(+), 44 deletions(-) diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 451aa7627209..20203f5ff212 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -1,10 +1,21 @@ -#include "BlSMMStoreDxe.h" +#include #include "Fvb.h" #include "SPI_fvb.h" #include "SPIgeneric.h" #include "spi_flash_internal.h" +#include "spi_winbond.h" +#define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * (Lba)) + (Offset)) + +static struct spi_slave *getSPISlave() { + static struct spi_slave slave; + if(slave.ctrlr == NULL) { + spi_setup_slave(0, 0, &slave); + } + return &slave; +} + // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; // STATIC UINTN mFlashNvStorageVariableBase; @@ -224,31 +235,39 @@ FvbRead ( IN OUT UINT8 *Buffer ) { - struct spi_slave slave; - if(Lba != 0) { - DEBUG((EFI_D_INFO, "%a Only block 0 is supported!\n", __FUNCTION__)); - return EFI_ACCESS_DENIED; - } - if(Buffer == NULL || *NumBytes == 0) { + // FIXME check if read is not done from outside flash memory + UINTN address = ADDRESS(Lba, Offset); + // Maxumum amount of bytes possible to read. Can't span the block boundary + UINTN numberOfBytesToRead = MIN(*NumBytes, BLOCK_SIZE-Offset); + UINTN numberOfBytesRead = 0; + if(Buffer == NULL || numberOfBytesToRead == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; } - spi_setup_slave(0, 0, &slave); - UINT8 command[4] = { - CMD_READ_ARRAY_SLOW, - (UINT8)((Offset & 0xFF0000) >> 16), - (UINT8)((Offset & 0xFF00) >> 8), - (UINT8) (Offset & 0xFF), - }; - if(spi_xfer(&slave, command, 4, Buffer, *NumBytes) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - for(int counter = 0; counter < *NumBytes; ++counter) { - DEBUG((EFI_D_INFO, "%DUMP %X\n", Buffer[counter])); + while(numberOfBytesRead < numberOfBytesToRead) { + UINTN nextReadAddress = address + numberOfBytesRead; + UINTN numberOfBytesLeft = numberOfBytesToRead - numberOfBytesRead; + UINTN numberOfBytesToReadNext = MIN(numberOfBytesLeft, PAGE_SIZE); + UINT8 command[] = { + CMD_READ_ARRAY_SLOW, + (UINT8)((nextReadAddress & 0xFF0000) >> 16), + (UINT8)((nextReadAddress & 0xFF00) >> 8), + (UINT8) (nextReadAddress & 0xFF) + }; + if(spi_xfer(getSPISlave(), + command, ARRAY_SIZE(command), + Buffer+numberOfBytesRead, numberOfBytesToReadNext) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + numberOfBytesRead += numberOfBytesToReadNext; } + if(numberOfBytesToRead != *NumBytes) { + *NumBytes = numberOfBytesToRead; + return EFI_BAD_BUFFER_SIZE; + } return EFI_SUCCESS; } @@ -316,8 +335,100 @@ FvbWrite ( IN UINT8 *Buffer ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + struct spi_slave slave; + //UINTN bytesToWrite = *NumBytes; + UINTN address = ADDRESS(Lba, Offset); + if(Buffer == NULL || *NumBytes == 0) { + DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); + return EFI_BAD_BUFFER_SIZE; + } + spi_setup_slave(0, 0, &slave); + UINT8 writeEnableCmd[] = { + CMD_WRITE_ENABLE + }; + if(spi_xfer(&slave, writeEnableCmd, ARRAY_SIZE(writeEnableCmd), NULL, 0) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + UINT8 pageProgramCmd[] = { + CMD_W25_PP, // FIXME Winbond specific + (UINT8)((address & 0xFF0000) >> 16), + (UINT8)((address & 0xFF00) >> 8), + (UINT8) (address & 0xFF) + }; + // ALIGN_VALUE - aligns to next nearest address + // MIN - minimum + if(spi_xfer( + &slave, pageProgramCmd, ARRAY_SIZE(pageProgramCmd), Buffer, *NumBytes)) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + return EFI_SUCCESS; +} + + +static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { + UINT8 writeEnableCmd[] = { + CMD_WRITE_ENABLE + }; + if(spi_xfer( + getSPISlave(), + writeEnableCmd, ARRAY_SIZE(writeEnableCmd), + NULL, 0 + ) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + UINT8 blockEraseCmd[] = { + CMD_BLOCK_ERASE, // FIXME Winbond specific + (UINT8)((Address & 0xFF0000) >> 16), + (UINT8)((Address & 0xFF00) >> 8), + (UINT8) (Address & 0xFF) + }; + if(spi_xfer( + getSPISlave(), blockEraseCmd, ARRAY_SIZE(blockEraseCmd), NULL, 0) + ) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount) { + BOOLEAN error = FALSE; + for(UINTN current = 0; current < amount; ++current) { + if(FvbEraseBlockAtAddress(ADDRESS(Lba+current, 0)) != EFI_SUCCESS) { + error = TRUE; + } + } + if(error) { + return EFI_DEVICE_ERROR; + } else { + return EFI_SUCCESS; + } +} + +static EFI_STATUS readStatusReg(UINT8 *Status) { + UINT8 readStatusCmd[] = { + CMD_READ_STATUS + }; + if(spi_xfer( + getSPISlave(), readStatusCmd, ARRAY_SIZE(readStatusCmd), Status, 1) + ) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +EFI_STATUS checkBusyBit(UINT8 *Busy) { + if(readStatusReg(Busy) != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } + *Busy &= REG_BUSY_MASK; + return EFI_SUCCESS; } /** @@ -370,8 +481,35 @@ FvbEraseBlocks ( ... ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + EFI_STATUS status = EFI_SUCCESS; + VA_LIST Args; + VA_START(Args, This); + // Verify and everything + VA_END(Args); + // Erase blocks + VA_START(Args, This); + do { + EFI_LBA Lba = VA_ARG(Args, EFI_LBA); + if(Lba == EFI_LBA_LIST_TERMINATOR) { + break; + } + UINTN NumberOfBlocksToErase = VA_ARG(Args, EFI_LBA); + // To forget an argument is an easy mistake to do. + // Better check for it and try to warn a programmer. + if(NumberOfBlocksToErase == EFI_LBA_LIST_TERMINATOR) { + DEBUG((EFI_D_INFO, + "%a WARNING FvbEraseBlocks with invalid number of parameters!\n", + __FUNCTION__ + )); + status = EFI_INVALID_PARAMETER; + break; + } + if(FvbEraseConsecutiveBlocks(Lba, NumberOfBlocksToErase) != EFI_SUCCESS) { + status = EFI_DEVICE_ERROR; + } + } while (TRUE); + VA_END(Args); + return status; } /** diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index ea662a93438c..41599d53bc27 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -1,8 +1,12 @@ #ifndef FVB_H #define FVB_H +#include #include "BlSMMStoreDxe.h" +#define BLOCK_SIZE 0x10000 +#define PAGE_SIZE 0x100 + EFI_STATUS InitializeFvAndVariableStoreHeaders ( IN SMMSTORE_INSTANCE *Instance diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 7e57740c75fd..2920518ea372 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -43,6 +43,8 @@ void * memset (void *dest, int ch, __SIZE_TYPE__ count) return dest; } +EFI_STATUS checkBusyBit(UINT8 *Busy); + EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable @@ -50,7 +52,7 @@ EFI_STATUS EFIAPI SPIInitialize ( { EFI_STATUS Status; struct spi_slave slave; - DEBUG((EFI_D_INFO, "SPI IS HERE 2\n")); + DEBUG((EFI_D_INFO, "SPI IS HERE\n")); DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); @@ -61,27 +63,32 @@ EFI_STATUS EFIAPI SPIInitialize ( ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - } else { - DEBUG((EFI_D_INFO, "%a Successfull protocol installation\n", __FUNCTION__)); } - DEBUG((EFI_D_INFO, "calling spi_init()\n")); spi_init(); - DEBUG((EFI_D_INFO, "spi_init() was called\n")); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); - DEBUG((EFI_D_INFO, "0x%X\n", slave.ctrlr->xfer)); - unsigned char fill[255]; - DEBUG((EFI_D_INFO, "spi_flash_cmd() returned 0x%X\n", spi_flash_cmd(&slave, CMD_READ_ID, &fill, 5))); - DEBUG((EFI_D_INFO, "%X %X %X %X %X\n", - (unsigned int)(unsigned char)fill[0], - (unsigned int)(unsigned char)fill[1], - (unsigned int)(unsigned char)fill[2], - (unsigned int)(unsigned char)fill[3], - (unsigned int)(unsigned char)fill[4])); - struct spi_op vector = { - .dout = "asdf8888", - .bytesout = 8, - }; - DEBUG((EFI_D_INFO, "spi_xfer() returned 0x%X\n", spi_xfer(&slave, "asdf", 4, &fill, 0))); - DEBUG((EFI_D_INFO, "spi_xfer_vectors() returned 0x%X\n", spi_xfer_vector(&slave, &vector, 1))); + char fill[300] = {}; + UINTN length = 4; + FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); + DEBUG((EFI_D_INFO, "TRIALS\n")); + for(int i = 0; i < 10; i++) { + DEBUG((EFI_D_INFO, "%X %X\n", i, fill[i])); + } + DEBUG((EFI_D_INFO, "ERASING\n")); + EFI_STATUS result = FvbEraseBlocks(&FvbProtocol, 0, 1, EFI_LBA_LIST_TERMINATOR); + if(result == EFI_SUCCESS) + DEBUG((EFI_D_INFO, "EFI_SUCCESS\n")); + if(result == EFI_ACCESS_DENIED) + DEBUG((EFI_D_INFO, "EFI_ACCESS_DENIED\n")); + if(result == EFI_DEVICE_ERROR) + DEBUG((EFI_D_INFO, "EFI_DEVICE_ERROR\n")); + if(result == EFI_INVALID_PARAMETER) + DEBUG((EFI_D_INFO, "EFI_INVALID_PARAMETER\n")); + UINT8 busy = 0xFF; + checkBusyBit(&busy); + DEBUG((EFI_D_INFO, "BUSY: 0x%X\n", busy)); + FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); + for(int i = 0; i < 10; i++) { + DEBUG((EFI_D_INFO, "%X %X\n", i, fill[i])); + } return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h index 8c5ba3a89c6a..e9e29703a8ef 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.h +++ b/UefiPayloadPkg/SPI/spi_flash_internal.h @@ -27,6 +27,17 @@ /* Common status */ #define STATUS_WIP 0x01 +/* Common register masks */ +#define REG_BUSY_MASK 0x01 +#define REG_WRITE_ENABLE_MASK 0x02 +#define REG_BLOCK_PROTECT_0_MASK 0x04 +#define REG_BLOCK_PROTECT_1_MASK 0x08 +#define REG_BLOCK_PROTECT_2_MASK 0x10 +#define REG_TOP_BOTTOM_PROTECTION_MASK 0x20 +#define REG_BLOCK_PROTECTION_MASK 0x40 +#define REG_STATUS_REGISTER_PROTECTION_MASK 0x80 + + /* Send a single-byte command to the device and read the response */ int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); From cfe64eeaf80e789cd58f75643595acb106e5a4a8 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 14 Oct 2020 08:43:30 +0200 Subject: [PATCH 253/297] fixes after code review --- .../Variable/RuntimeDxe/VariableNonVolatile.c | 17 --- .../RuntimeDxe/VariableRuntimeDxe.inf | 6 - .../Variable/RuntimeDxe/VariableSmm.inf | 8 -- .../RuntimeDxe/VariableStandaloneMm.inf | 6 - UefiPayloadPkg/SPI/Fvb.c | 125 +++++++++--------- UefiPayloadPkg/SPI/SPI.h | 20 --- UefiPayloadPkg/SPI/SPI.inf | 1 - UefiPayloadPkg/SPI/SPIgeneric.c | 4 +- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 2 +- UefiPayloadPkg/SPI/fch_spi_ctrl.h | 1 - UefiPayloadPkg/SPI/lpc.h | 1 - UefiPayloadPkg/SPI/own.c | 14 -- UefiPayloadPkg/SPI/own.h | 9 -- UefiPayloadPkg/SPI/spi_flash_internal.c | 8 +- 14 files changed, 69 insertions(+), 153 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/own.c delete mode 100644 UefiPayloadPkg/SPI/own.h diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c index a798370c1bc1..1916c16c785a 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c @@ -6,7 +6,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include #include #include #include @@ -178,22 +177,6 @@ InitRealNonVolatileVariableStore ( return EFI_OUT_OF_RESOURCES; } - DEBUG((EFI_D_INFO, "Updating HOB\n")); - SMMSTORE_INFO *SMMStoreInfoHob; - SMMStoreInfoHob = AllocateRuntimePool (GET_GUID_HOB_DATA_SIZE(GuidHob)); - // Update PCDs for Variable/RuntimeDxe - CopyMem(SMMStoreInfoHob, GET_GUID_HOB_DATA (GuidHob), GET_GUID_HOB_DATA_SIZE(GuidHob)); - DEBUG((EFI_D_INFO, "PcdGet32 (PcdFlashNvStorageVariableBase) = 0x%X\n", PcdGet32 (PcdFlashNvStorageVariableBase))); - DEBUG((EFI_D_INFO, "PcdGet32 (PcdFlashNvStorageFtwWorkingBase) = 0x%X\n", PcdGet32 (PcdFlashNvStorageFtwWorkingBase))); - DEBUG((EFI_D_INFO, "PcdGet32 (PcdFlashNvStorageFtwSpareBase) = 0x%X\n", PcdGet32 (PcdFlashNvStorageFtwSpareBase))); - DEBUG((EFI_D_INFO, "SMMStoreInfoHob->MmioAddress = 0x%X\n", SMMStoreInfoHob->MmioAddress)); - PcdSet32S (PcdFlashNvStorageVariableBase, - PcdGet32 (PcdFlashNvStorageVariableBase) + SMMStoreInfoHob->MmioAddress); - PcdSet32S (PcdFlashNvStorageFtwWorkingBase, - PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + SMMStoreInfoHob->MmioAddress); - PcdSet32S (PcdFlashNvStorageFtwSpareBase, - PcdGet32 (PcdFlashNvStorageFtwSpareBase) + SMMStoreInfoHob->MmioAddress); - NvStorageBase = NV_STORAGE_VARIABLE_BASE; ASSERT (NvStorageBase != 0); diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index 3683b4fa7efd..ceea5d1ff9ac 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -135,12 +135,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable - [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf index 591dc13b5b83..bc3033588d40 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableSmm.inf @@ -138,14 +138,6 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable ## SOMETIMES_CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvStoreReserved ## SOMETIMES_CONSUMES - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable - [FeaturePcd] gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf index a0776cecd5cd..6e17f6cdf588 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableStandaloneMm.inf @@ -135,11 +135,5 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdVariableCollectStatistics ## CONSUMES # statistic the information of variable. gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLangDeprecate ## CONSUMES # Auto update PlatformLang/Lang - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable - [Depex] TRUE diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 20203f5ff212..ffd29d8942b7 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -16,6 +16,68 @@ static struct spi_slave *getSPISlave() { return &slave; } +static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { + UINT8 writeEnableCmd[] = { + CMD_WRITE_ENABLE + }; + if(spi_xfer( + getSPISlave(), + writeEnableCmd, ARRAY_SIZE(writeEnableCmd), + NULL, 0 + ) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + UINT8 blockEraseCmd[] = { + CMD_BLOCK_ERASE, // FIXME Winbond specific + (UINT8)((Address & 0xFF0000) >> 16), + (UINT8)((Address & 0xFF00) >> 8), + (UINT8) (Address & 0xFF) + }; + if(spi_xfer( + getSPISlave(), blockEraseCmd, ARRAY_SIZE(blockEraseCmd), NULL, 0) + ) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount) { + BOOLEAN error = FALSE; + for(UINTN current = 0; current < amount; ++current) { + if(FvbEraseBlockAtAddress(ADDRESS(Lba+current, 0)) != EFI_SUCCESS) { + error = TRUE; + } + } + if(error) { + return EFI_DEVICE_ERROR; + } else { + return EFI_SUCCESS; + } +} + +static EFI_STATUS readStatusReg(UINT8 *Status) { + UINT8 readStatusCmd[] = { + CMD_READ_STATUS + }; + if(spi_xfer( + getSPISlave(), readStatusCmd, ARRAY_SIZE(readStatusCmd), Status, 1) + ) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +EFI_STATUS checkBusyBit(UINT8 *Busy) { + if(readStatusReg(Busy) != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } + *Busy &= REG_BUSY_MASK; + return EFI_SUCCESS; +} + // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; // STATIC UINTN mFlashNvStorageVariableBase; @@ -368,69 +430,6 @@ FvbWrite ( return EFI_SUCCESS; } - -static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { - UINT8 writeEnableCmd[] = { - CMD_WRITE_ENABLE - }; - if(spi_xfer( - getSPISlave(), - writeEnableCmd, ARRAY_SIZE(writeEnableCmd), - NULL, 0 - ) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - UINT8 blockEraseCmd[] = { - CMD_BLOCK_ERASE, // FIXME Winbond specific - (UINT8)((Address & 0xFF0000) >> 16), - (UINT8)((Address & 0xFF00) >> 8), - (UINT8) (Address & 0xFF) - }; - if(spi_xfer( - getSPISlave(), blockEraseCmd, ARRAY_SIZE(blockEraseCmd), NULL, 0) - ) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount) { - BOOLEAN error = FALSE; - for(UINTN current = 0; current < amount; ++current) { - if(FvbEraseBlockAtAddress(ADDRESS(Lba+current, 0)) != EFI_SUCCESS) { - error = TRUE; - } - } - if(error) { - return EFI_DEVICE_ERROR; - } else { - return EFI_SUCCESS; - } -} - -static EFI_STATUS readStatusReg(UINT8 *Status) { - UINT8 readStatusCmd[] = { - CMD_READ_STATUS - }; - if(spi_xfer( - getSPISlave(), readStatusCmd, ARRAY_SIZE(readStatusCmd), Status, 1) - ) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -EFI_STATUS checkBusyBit(UINT8 *Busy) { - if(readStatusReg(Busy) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - *Busy &= REG_BUSY_MASK; - return EFI_SUCCESS; -} - /** Erases and initialises a firmware volume block. diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 6ce5b5b9e116..e58c2f947487 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -76,26 +76,6 @@ struct spi_config { enum spi100_speed tpm_speed; }; -/* - * Perform early SPI initialization: - * 1. Sets SPI ROM base and enables SPI ROM - * 2. Enables SPI ROM prefetching - * 3. Disables 4dw burst - * 4. Configures SPI speed and read mode. - * - * This function expects SoC to include soc_amd_common_config in chip SoC config and uses - * settings from mainboard devicetree to configure speed and read mode. - */ -VOID fch_spi_early_init(VOID); - -/* - * Configure SPI speed and read mode. - * - * This function expects SoC to include soc_amd_common_config in chip SoC config and uses - * settings from mainboard devicetree to configure speed and read mode. - */ -VOID fch_spi_config_modes(VOID); - /* Set the SPI base address variable */ VOID spi_set_base(VOID *base); diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 0987165c3192..689ad89dc220 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -17,7 +17,6 @@ [Sources] SPI.h - # SPI.c SPIgeneric.h SPIgeneric.c lpc.h diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/SPIgeneric.c index 64dcc6397322..9c0373167684 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/SPIgeneric.c @@ -2,8 +2,8 @@ #include #include +#include #include "SPIgeneric.h" -#include "own.h" UINT32 spi_claim_bus(CONST struct spi_slave *slave) { @@ -114,7 +114,7 @@ UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { __SIZE_TYPE__ i; - memset(slave, 0, sizeof(*slave)); + InternalMemZeroMem(slave, sizeof(*slave)); for (i = 0; i < spi_ctrlr_bus_map_count; i++) { if ((spi_ctrlr_bus_map[i].bus_start <= bus) && diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index f71b1f8b76eb..85679479bf75 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -1,8 +1,8 @@ #include #include -#include "kconfig.h" #include "SPI.h" +#include "kconfig.h" #include "utils.h" #include "stopwatch.h" #include "fch_spi_util.h" diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.h b/UefiPayloadPkg/SPI/fch_spi_ctrl.h index 7977adc28558..acfd99dd4559 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.h +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.h @@ -4,7 +4,6 @@ #include #include "kconfig.h" -#include "SPI.h" #include "utils.h" #include "stopwatch.h" #include "fch_spi_util.h" diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h index fb8a35f6a832..772445e4320a 100644 --- a/UefiPayloadPkg/SPI/lpc.h +++ b/UefiPayloadPkg/SPI/lpc.h @@ -1,4 +1,3 @@ -#include #include "pci_type.h" /* PCI registers for D14F3 */ diff --git a/UefiPayloadPkg/SPI/own.c b/UefiPayloadPkg/SPI/own.c deleted file mode 100644 index 26c74a4e8369..000000000000 --- a/UefiPayloadPkg/SPI/own.c +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include "own.h" - -VOID *memset (VOID *ptr, int value, __SIZE_TYPE__ num ) { - for(__SIZE_TYPE__ offset; offset < num; ++offset) { - ((CHAR8 *)ptr)[offset] = (CHAR8)value; - } -} - -void *memcpy (VOID * destination, CONST void * source, __SIZE_TYPE__ num ) { - for(__SIZE_TYPE__ offset; offset < num; ++offset) { - ((CHAR8 *)destination)[offset] = ((CHAR8 *)source)[offset]; - } -} diff --git a/UefiPayloadPkg/SPI/own.h b/UefiPayloadPkg/SPI/own.h deleted file mode 100644 index f3e64697b898..000000000000 --- a/UefiPayloadPkg/SPI/own.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef OWN_H -#define OWN_H - -#include - -VOID *memset (VOID * ptr, int value, __SIZE_TYPE__ num ); -void *memcpy (VOID * destination, CONST void * source, __SIZE_TYPE__ num ); - -#endif /* OWN_H */ diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.c b/UefiPayloadPkg/SPI/spi_flash_internal.c index 7194d28eb9c7..856f02bc6016 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.c +++ b/UefiPayloadPkg/SPI/spi_flash_internal.c @@ -2,13 +2,13 @@ #include #include +#include #include "spi_flash_internal.h" #include "SPIgeneric.h" #include "kconfig.h" #include "stopwatch.h" #include "utils.h" #include "SPI_fvb.h" -#include "own.h" static VOID spi_flash_addr(UINT32 addr, UINT8 *cmd) { @@ -97,8 +97,8 @@ int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, { int ret; UINT8 buff[cmd_len + data_len]; - memcpy(buff, cmd, cmd_len); - memcpy(buff + cmd_len, data, data_len); + InternalMemCopyMem(buff, cmd, cmd_len); + InternalMemCopyMem(buff + cmd_len, data, data_len); ret = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0); if (ret) { @@ -339,7 +339,7 @@ static int fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash, const struct spi_flash_vendor_info *vi, const struct spi_flash_part_id *part) { - memcpy(&flash->spi, spi, sizeof(*spi)); + InternalMemCopyMem(&flash->spi, spi, sizeof(*spi)); flash->vendor = vi->id; flash->model = part->id[0]; From a227e15b3d6dc0ca43bf1239aa00ae9092b94ba9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 14 Oct 2020 15:02:57 +0200 Subject: [PATCH 254/297] UefiPayloadPkg/SPI/Fvb.c: Implement FlashErase. FlashWrite is not working yet --- UefiPayloadPkg/SPI/Fvb.c | 297 ++++++++++++++++++++++++----------- UefiPayloadPkg/SPI/Fvb.h | 1 + UefiPayloadPkg/SPI/SPI_fvb.c | 48 +++--- 3 files changed, 233 insertions(+), 113 deletions(-) diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index ffd29d8942b7..d538ff94db5d 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -7,6 +7,27 @@ #define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * (Lba)) + (Offset)) +#define REMAINING_SPACE_IN_BLOCK(Offset) ((BLOCK_SIZE) - (Offset)) + +static struct spi_slave *getSPISlave(); +static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address); +static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount); +static EFI_STATUS readStatusReg(UINT8 *Status); +static EFI_STATUS checkBusyBit(UINT8 *Busy); +static EFI_STATUS waitForBusyBit(); +static EFI_STATUS FvbNextBlocksFromList( + VA_LIST *Args, + EFI_LBA *Lba, + UINTN *LbaCount); +static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args); +static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba); +static EFI_STATUS FvbVerifyConsecutiveBlocksWritability( + EFI_LBA Lba, + UINTN LbaCount); +static EFI_STATUS FvbVerifyBlocksWritability(VA_LIST *Args); +static UINTN FvbGetTotalNumberOfBlocks(); +static EFI_STATUS WriteEnable(); +static EFI_STATUS PageProgram(UINTN address, UINT8 *Buffer, UINTN NumBytes); static struct spi_slave *getSPISlave() { static struct spi_slave slave; @@ -17,17 +38,7 @@ static struct spi_slave *getSPISlave() { } static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { - UINT8 writeEnableCmd[] = { - CMD_WRITE_ENABLE - }; - if(spi_xfer( - getSPISlave(), - writeEnableCmd, ARRAY_SIZE(writeEnableCmd), - NULL, 0 - ) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } + WriteEnable(); UINT8 blockEraseCmd[] = { CMD_BLOCK_ERASE, // FIXME Winbond specific (UINT8)((Address & 0xFF0000) >> 16), @@ -70,7 +81,7 @@ static EFI_STATUS readStatusReg(UINT8 *Status) { return EFI_SUCCESS; } -EFI_STATUS checkBusyBit(UINT8 *Busy) { +static EFI_STATUS checkBusyBit(UINT8 *Busy) { if(readStatusReg(Busy) != EFI_SUCCESS) { return EFI_DEVICE_ERROR; } @@ -78,6 +89,145 @@ EFI_STATUS checkBusyBit(UINT8 *Busy) { return EFI_SUCCESS; } +static EFI_STATUS waitForBusyBit() { + UINT8 busy = 0xFF; + while(busy != 0) { + if(checkBusyBit(&busy) != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } + } + return EFI_SUCCESS; +} + +static EFI_STATUS FvbNextBlocksFromList( + VA_LIST *Args, + EFI_LBA *Lba, + UINTN *LbaCount +) { + *Lba = VA_ARG(*Args, EFI_LBA); + if(*Lba == EFI_LBA_LIST_TERMINATOR) { + return EFI_SUCCESS; + } + *LbaCount = VA_ARG(*Args, EFI_LBA); + // To forget an argument is an easy mistake to do. + // Better check for it and try to warn a programmer. + if(*LbaCount == EFI_LBA_LIST_TERMINATOR) { + DEBUG(( + EFI_D_INFO, "%a WARNING: invalid number of parameters!\n", __FUNCTION__)); + return EFI_INVALID_PARAMETER; + } + return EFI_SUCCESS; +} + +static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args) { + EFI_STATUS status = EFI_SUCCESS; + while(TRUE) + { + EFI_LBA Lba; + UINTN LbaCount; + if(FvbNextBlocksFromList(Args, &Lba, &LbaCount) != EFI_SUCCESS) { + status = EFI_INVALID_PARAMETER; + break; + } + if(Lba == EFI_LBA_LIST_TERMINATOR) { + break; + } + if(FvbEraseConsecutiveBlocks(Lba, LbaCount) != EFI_SUCCESS) { + status = EFI_DEVICE_ERROR; + } + } + return status; +} + +static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba) { + if(Lba > FvbGetTotalNumberOfBlocks()-1) { + return EFI_ACCESS_DENIED; + } else { + return EFI_SUCCESS; + } +} + +static EFI_STATUS FvbVerifyConsecutiveBlocksWritability( + EFI_LBA Lba, + UINTN LbaCount +) { + for(EFI_LBA currentLba = Lba; currentLba < Lba+LbaCount; ++currentLba) { + if(FvbVerifySingleBlockWritability(Lba) != EFI_SUCCESS) { + return EFI_ACCESS_DENIED; + } + } + return EFI_SUCCESS; +} + +static EFI_STATUS FvbVerifyBlocksWritability(VA_LIST *Args) { + EFI_STATUS status = EFI_SUCCESS; + while(TRUE) { + EFI_LBA Lba; + UINTN LbaCount; + if(FvbNextBlocksFromList(Args, &Lba, &LbaCount) != EFI_SUCCESS) { + status = EFI_INVALID_PARAMETER; + break; + } + if(Lba == EFI_LBA_LIST_TERMINATOR) { + break; + } + if(FvbVerifyConsecutiveBlocksWritability(Lba, LbaCount) != EFI_SUCCESS) { + status = EFI_ACCESS_DENIED; + break; + } + } + return status; +} + +static UINTN FvbGetTotalNumberOfBlocks() { + return FLASH_SIZE / BLOCK_SIZE; +} + +static EFI_STATUS WriteEnable() { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINT8 writeEnableCmd[] = { + CMD_WRITE_ENABLE + }; + if(spi_xfer( + getSPISlave(), writeEnableCmd, ARRAY_SIZE(writeEnableCmd), NULL, 0) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +static EFI_STATUS PageProgram(UINTN address, UINT8 *Buffer, UINTN NumBytes) { + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + DEBUG((EFI_D_INFO, "writing 0x%X 0x%X 0x%X 0x%X\n", (UINTN)Buffer[0], (UINTN)Buffer[1], (UINTN)Buffer[2], (UINTN)Buffer[3])); + DEBUG((EFI_D_INFO, "PageProgram(address = 0x%X, Buffer = 0x%X, NumBytes = 0x%X)\n", address, Buffer, NumBytes)); + UINT8 busy = 0xFF; + checkBusyBit(&busy); + DEBUG((EFI_D_INFO, "BUSY: %X\n", busy)); + UINT8 pageProgramCmd[] = { + CMD_W25_PP, // FIXME Winbond specific + (UINT8)((address & 0xFF0000) >> 16), + (UINT8)((address & 0x00FF00) >> 8), // WRITING DUMMY DATA + (UINT8) (address & 0x0000FF), 0xAA, 0xBB, 0xCC, 0xDD + }; + DEBUG((EFI_D_INFO, "command\n")); + for(UINTN counter = 0; counter < ARRAY_SIZE(pageProgramCmd); ++counter) { + DEBUG((EFI_D_INFO, "0x%X\n", pageProgramCmd[counter])); + } + if(spi_xfer( + getSPISlave(), + pageProgramCmd, ARRAY_SIZE(pageProgramCmd), + NULL, 0) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + checkBusyBit(&busy); + DEBUG((EFI_D_INFO, "BUSY: %X\n", busy)); + waitForBusyBit(); + checkBusyBit(&busy); + DEBUG((EFI_D_INFO, "BUSY: %X\n", busy)); + return EFI_SUCCESS; +} + // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; // STATIC UINTN mFlashNvStorageVariableBase; @@ -104,7 +254,7 @@ InitializeFvAndVariableStoreHeaders ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } /** @@ -122,7 +272,7 @@ ValidateFvHeader ( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + return EFI_SUCCESS; } /** @@ -242,8 +392,13 @@ FvbGetBlockSize ( OUT UINTN *NumberOfBlocks ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + *BlockSize = BLOCK_SIZE; + *NumberOfBlocks = FvbGetTotalNumberOfBlocks(); + if(Lba > *NumberOfBlocks) { + return EFI_INVALID_PARAMETER; + } else { + return EFI_SUCCESS; + } } /** @@ -300,13 +455,13 @@ FvbRead ( // FIXME check if read is not done from outside flash memory UINTN address = ADDRESS(Lba, Offset); // Maxumum amount of bytes possible to read. Can't span the block boundary - UINTN numberOfBytesToRead = MIN(*NumBytes, BLOCK_SIZE-Offset); + UINTN numberOfBytesToRead = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); UINTN numberOfBytesRead = 0; if(Buffer == NULL || numberOfBytesToRead == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; } - + waitForBusyBit(); while(numberOfBytesRead < numberOfBytesToRead) { UINTN nextReadAddress = address + numberOfBytesRead; UINTN numberOfBytesLeft = numberOfBytesToRead - numberOfBytesRead; @@ -387,6 +542,7 @@ FvbRead ( **/ + EFI_STATUS EFIAPI FvbWrite ( @@ -397,35 +553,37 @@ FvbWrite ( IN UINT8 *Buffer ) { - struct spi_slave slave; - //UINTN bytesToWrite = *NumBytes; - UINTN address = ADDRESS(Lba, Offset); - if(Buffer == NULL || *NumBytes == 0) { + DEBUG((EFI_D_INFO, "%a This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); + UINT8 status = 0xFF; + readStatusReg(&status); + DEBUG((EFI_D_INFO, "STATUS: 0x%X\n", status)); + CONST UINTN numberOfBytesToWrite = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); + DEBUG((EFI_D_INFO, "MIN: 0x%X 0x%X\n", *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset))); + DEBUG((EFI_D_INFO, "CALCULATION: 0x%X - 0x%X\n", BLOCK_SIZE, Offset)); + DEBUG((EFI_D_INFO, "numberOfBytesToWrite: 0x%X\n", numberOfBytesToWrite)); + CONST UINTN address = ADDRESS(Lba, Offset); + if(Buffer == NULL || numberOfBytesToWrite == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; } - spi_setup_slave(0, 0, &slave); - UINT8 writeEnableCmd[] = { - CMD_WRITE_ENABLE - }; - if(spi_xfer(&slave, writeEnableCmd, ARRAY_SIZE(writeEnableCmd), NULL, 0) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + if(FvbVerifySingleBlockWritability(Lba) == EFI_ACCESS_DENIED) { + return EFI_ACCESS_DENIED; + } + if(waitForBusyBit() != EFI_SUCCESS) { + DEBUG((EFI_D_INFO, "%a error busy bit\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } - - UINT8 pageProgramCmd[] = { - CMD_W25_PP, // FIXME Winbond specific - (UINT8)((address & 0xFF0000) >> 16), - (UINT8)((address & 0xFF00) >> 8), - (UINT8) (address & 0xFF) - }; - // ALIGN_VALUE - aligns to next nearest address - // MIN - minimum - if(spi_xfer( - &slave, pageProgramCmd, ARRAY_SIZE(pageProgramCmd), Buffer, *NumBytes)) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + if(WriteEnable() != EFI_SUCCESS) { + DEBUG((EFI_D_INFO, "%a error write enable\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } + if(PageProgram(address, Buffer, numberOfBytesToWrite) != EFI_SUCCESS) { + DEBUG((EFI_D_INFO, "%a error page program\n", __FUNCTION__)); + } + if(numberOfBytesToWrite != *NumBytes) { + return EFI_BAD_BUFFER_SIZE; + } + *NumBytes = numberOfBytesToWrite; return EFI_SUCCESS; } @@ -473,6 +631,7 @@ FvbWrite ( not exist in the firmware volume. **/ + EFI_STATUS EFIAPI FvbEraseBlocks ( @@ -483,58 +642,16 @@ FvbEraseBlocks ( EFI_STATUS status = EFI_SUCCESS; VA_LIST Args; VA_START(Args, This); - // Verify and everything + status = FvbVerifyBlocksWritability(&Args); VA_END(Args); - // Erase blocks - VA_START(Args, This); - do { - EFI_LBA Lba = VA_ARG(Args, EFI_LBA); - if(Lba == EFI_LBA_LIST_TERMINATOR) { - break; - } - UINTN NumberOfBlocksToErase = VA_ARG(Args, EFI_LBA); - // To forget an argument is an easy mistake to do. - // Better check for it and try to warn a programmer. - if(NumberOfBlocksToErase == EFI_LBA_LIST_TERMINATOR) { + if(status == EFI_SUCCESS) { + VA_START(Args, This); + status = FvbEraseVerifiedBlocks(&Args); + VA_END(Args); + if(status != EFI_SUCCESS) { DEBUG((EFI_D_INFO, - "%a WARNING FvbEraseBlocks with invalid number of parameters!\n", - __FUNCTION__ - )); - status = EFI_INVALID_PARAMETER; - break; + "%a WARNING: Blocks verified, but erase failed!", __FUNCTION__)); } - if(FvbEraseConsecutiveBlocks(Lba, NumberOfBlocksToErase) != EFI_SUCCESS) { - status = EFI_DEVICE_ERROR; - } - } while (TRUE); - VA_END(Args); + } return status; } - -/** - Fixup internal data so that EFI can be call in virtual mode. - Call the passed in Child Notify event and convert any pointers in - lib to virtual mode. - - @param[in] Event The Event that is being processed - @param[in] Context Event Context -**/ -VOID -EFIAPI -FvbVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); -} - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; -} diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index 41599d53bc27..2a6471376294 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -6,6 +6,7 @@ #define BLOCK_SIZE 0x10000 #define PAGE_SIZE 0x100 +#define FLASH_SIZE 0x800000 EFI_STATUS InitializeFvAndVariableStoreHeaders ( diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 2920518ea372..29ea60e1bdfa 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -35,14 +35,6 @@ EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { NULL }; -void * memset (void *dest, int ch, __SIZE_TYPE__ count) -{ - for(__SIZE_TYPE__ offset = 0; offset < count; ++offset) { - ((CHAR8 *)dest)[offset] = ch; - } - return dest; -} - EFI_STATUS checkBusyBit(UINT8 *Busy); EFI_STATUS EFIAPI SPIInitialize ( @@ -66,29 +58,39 @@ EFI_STATUS EFIAPI SPIInitialize ( } spi_init(); DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); - char fill[300] = {}; - UINTN length = 4; + unsigned char fill[300] = {}; + UINTN length = 30; FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); DEBUG((EFI_D_INFO, "TRIALS\n")); for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, fill[i])); + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); } DEBUG((EFI_D_INFO, "ERASING\n")); - EFI_STATUS result = FvbEraseBlocks(&FvbProtocol, 0, 1, EFI_LBA_LIST_TERMINATOR); - if(result == EFI_SUCCESS) + FvbEraseBlocks(&FvbProtocol, 0, 2, 4, 5, EFI_LBA_LIST_TERMINATOR); + FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); + for(int i = 0; i < 10; i++) { + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); + } + DEBUG((EFI_D_INFO, "WRITING\n")); + UINT8 toWrite[] = {01, 0x01, 0x01, 0x77}; + UINTN writeLen = 4; + EFI_STATUS status = FvbWrite(&FvbProtocol, 0, 1, &writeLen, toWrite); + DEBUG((EFI_D_INFO, "Written: 0x%X\n", writeLen)); + if(status == EFI_SUCCESS) { DEBUG((EFI_D_INFO, "EFI_SUCCESS\n")); - if(result == EFI_ACCESS_DENIED) + } else if(status == EFI_BAD_BUFFER_SIZE) { + DEBUG((EFI_D_INFO, "EFI_BAD_BUFFER_SIZE\n")); + } else if(status == EFI_ACCESS_DENIED) { DEBUG((EFI_D_INFO, "EFI_ACCESS_DENIED\n")); - if(result == EFI_DEVICE_ERROR) - DEBUG((EFI_D_INFO, "EFI_DEVICE_ERROR\n")); - if(result == EFI_INVALID_PARAMETER) - DEBUG((EFI_D_INFO, "EFI_INVALID_PARAMETER\n")); - UINT8 busy = 0xFF; - checkBusyBit(&busy); - DEBUG((EFI_D_INFO, "BUSY: 0x%X\n", busy)); - FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); + } else { + DEBUG((EFI_D_INFO, "It's really bad\n")); + } + unsigned char newFill[300] = {}; + UINTN newLength = 30; + FvbRead(&FvbProtocol, 0, 0, &newLength, (VOID *)newFill); for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, fill[i])); + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); } + while(TRUE); return EFI_SUCCESS; } From 7ce6cf03c442ecd53f3a421113f41a96932ff05a Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 15 Oct 2020 09:36:25 +0200 Subject: [PATCH 255/297] UefiPayloadPkg/SPI/Fvb.c: fix FvbWrite --- UefiPayloadPkg/SPI/Fvb.c | 88 +++++++++++++------------ UefiPayloadPkg/SPI/SPI_fvb.c | 2 +- UefiPayloadPkg/SPI/spi_flash_internal.h | 4 +- 3 files changed, 48 insertions(+), 46 deletions(-) diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index d538ff94db5d..19daf1f89cae 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -14,7 +14,7 @@ static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address); static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount); static EFI_STATUS readStatusReg(UINT8 *Status); static EFI_STATUS checkBusyBit(UINT8 *Busy); -static EFI_STATUS waitForBusyBit(); +static EFI_STATUS WaitForBusyBit(); static EFI_STATUS FvbNextBlocksFromList( VA_LIST *Args, EFI_LBA *Lba, @@ -81,6 +81,20 @@ static EFI_STATUS readStatusReg(UINT8 *Status) { return EFI_SUCCESS; } +static EFI_STATUS writeStatusReg(UINT8 Status) { + UINT8 readStatusCmd[] = { + STATUS_WIP, + Status + }; + if(spi_xfer( + getSPISlave(), readStatusCmd, ARRAY_SIZE(readStatusCmd), NULL, 0) + ) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + static EFI_STATUS checkBusyBit(UINT8 *Busy) { if(readStatusReg(Busy) != EFI_SUCCESS) { return EFI_DEVICE_ERROR; @@ -89,7 +103,7 @@ static EFI_STATUS checkBusyBit(UINT8 *Busy) { return EFI_SUCCESS; } -static EFI_STATUS waitForBusyBit() { +static EFI_STATUS WaitForBusyBit() { UINT8 busy = 0xFF; while(busy != 0) { if(checkBusyBit(&busy) != EFI_SUCCESS) { @@ -184,7 +198,6 @@ static UINTN FvbGetTotalNumberOfBlocks() { } static EFI_STATUS WriteEnable() { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT8 writeEnableCmd[] = { CMD_WRITE_ENABLE }; @@ -196,35 +209,37 @@ static EFI_STATUS WriteEnable() { return EFI_SUCCESS; } -static EFI_STATUS PageProgram(UINTN address, UINT8 *Buffer, UINTN NumBytes) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - DEBUG((EFI_D_INFO, "writing 0x%X 0x%X 0x%X 0x%X\n", (UINTN)Buffer[0], (UINTN)Buffer[1], (UINTN)Buffer[2], (UINTN)Buffer[3])); - DEBUG((EFI_D_INFO, "PageProgram(address = 0x%X, Buffer = 0x%X, NumBytes = 0x%X)\n", address, Buffer, NumBytes)); - UINT8 busy = 0xFF; - checkBusyBit(&busy); - DEBUG((EFI_D_INFO, "BUSY: %X\n", busy)); +static EFI_STATUS PageProgram(UINTN Address, UINT8 *Buffer, UINTN NumBytes) { UINT8 pageProgramCmd[] = { CMD_W25_PP, // FIXME Winbond specific - (UINT8)((address & 0xFF0000) >> 16), - (UINT8)((address & 0x00FF00) >> 8), // WRITING DUMMY DATA - (UINT8) (address & 0x0000FF), 0xAA, 0xBB, 0xCC, 0xDD + (UINT8)((Address & 0xFF0000) >> 16), + (UINT8)((Address & 0x00FF00) >> 8), // WRITING DUMMY DATA + (UINT8) (Address & 0x0000FF), 0xAA, 0xBB, 0xCC, 0xDD }; - DEBUG((EFI_D_INFO, "command\n")); - for(UINTN counter = 0; counter < ARRAY_SIZE(pageProgramCmd); ++counter) { - DEBUG((EFI_D_INFO, "0x%X\n", pageProgramCmd[counter])); - } if(spi_xfer( getSPISlave(), - pageProgramCmd, ARRAY_SIZE(pageProgramCmd), + pageProgramCmd, 8/*ARRAY_SIZE(pageProgramCmd)*/, NULL, 0) != 0) { DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } - checkBusyBit(&busy); - DEBUG((EFI_D_INFO, "BUSY: %X\n", busy)); - waitForBusyBit(); - checkBusyBit(&busy); - DEBUG((EFI_D_INFO, "BUSY: %X\n", busy)); + WaitForBusyBit(); + return EFI_SUCCESS; +} + +static EFI_STATUS RemoveBlockProtection() { + UINT8 status; + if(readStatusReg(&status) != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } + status &= ~( + REG_BLOCK_PROTECT_0_MASK + | REG_BLOCK_PROTECT_1_MASK + | REG_BLOCK_PROTECT_2_MASK + | REG_BLOCK_PROTECT_3_MASK); + if(writeStatusReg(status) != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } return EFI_SUCCESS; } @@ -343,7 +358,7 @@ FvbSetAttributes( @retval EFI_SUCCESS The firmware volume base address was returned. - @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. + @retval EFI_UNSUPPORTED The firmware volume is not memory mapped. **/ EFI_STATUS @@ -353,8 +368,7 @@ FvbGetPhysicalAddress ( OUT EFI_PHYSICAL_ADDRESS *Address ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + return EFI_UNSUPPORTED; } /** @@ -461,7 +475,7 @@ FvbRead ( DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; } - waitForBusyBit(); + WaitForBusyBit(); while(numberOfBytesRead < numberOfBytesToRead) { UINTN nextReadAddress = address + numberOfBytesRead; UINTN numberOfBytesLeft = numberOfBytesToRead - numberOfBytesRead; @@ -553,14 +567,7 @@ FvbWrite ( IN UINT8 *Buffer ) { - DEBUG((EFI_D_INFO, "%a This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); - UINT8 status = 0xFF; - readStatusReg(&status); - DEBUG((EFI_D_INFO, "STATUS: 0x%X\n", status)); CONST UINTN numberOfBytesToWrite = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); - DEBUG((EFI_D_INFO, "MIN: 0x%X 0x%X\n", *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset))); - DEBUG((EFI_D_INFO, "CALCULATION: 0x%X - 0x%X\n", BLOCK_SIZE, Offset)); - DEBUG((EFI_D_INFO, "numberOfBytesToWrite: 0x%X\n", numberOfBytesToWrite)); CONST UINTN address = ADDRESS(Lba, Offset); if(Buffer == NULL || numberOfBytesToWrite == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); @@ -569,17 +576,12 @@ FvbWrite ( if(FvbVerifySingleBlockWritability(Lba) == EFI_ACCESS_DENIED) { return EFI_ACCESS_DENIED; } - if(waitForBusyBit() != EFI_SUCCESS) { - DEBUG((EFI_D_INFO, "%a error busy bit\n", __FUNCTION__)); + if(RemoveBlockProtection() != EFI_SUCCESS + || WaitForBusyBit() != EFI_SUCCESS + || WriteEnable() != EFI_SUCCESS + || PageProgram(address, Buffer, numberOfBytesToWrite) != EFI_SUCCESS) { return EFI_DEVICE_ERROR; } - if(WriteEnable() != EFI_SUCCESS) { - DEBUG((EFI_D_INFO, "%a error write enable\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - if(PageProgram(address, Buffer, numberOfBytesToWrite) != EFI_SUCCESS) { - DEBUG((EFI_D_INFO, "%a error page program\n", __FUNCTION__)); - } if(numberOfBytesToWrite != *NumBytes) { return EFI_BAD_BUFFER_SIZE; } diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 29ea60e1bdfa..8c6cf9419f0d 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -89,7 +89,7 @@ EFI_STATUS EFIAPI SPIInitialize ( UINTN newLength = 30; FvbRead(&FvbProtocol, 0, 0, &newLength, (VOID *)newFill); for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)newFill[i])); } while(TRUE); return EFI_SUCCESS; diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/spi_flash_internal.h index e9e29703a8ef..0c01d887eaa7 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.h +++ b/UefiPayloadPkg/SPI/spi_flash_internal.h @@ -33,8 +33,8 @@ #define REG_BLOCK_PROTECT_0_MASK 0x04 #define REG_BLOCK_PROTECT_1_MASK 0x08 #define REG_BLOCK_PROTECT_2_MASK 0x10 -#define REG_TOP_BOTTOM_PROTECTION_MASK 0x20 -#define REG_BLOCK_PROTECTION_MASK 0x40 +#define REG_BLOCK_PROTECT_3_MASK 0x20 // FIXME this exists only on some winbond chips +#define REG_TOP_BOTTOM_PROTECTION_MASK 0x40 // FIXME on other chips T/B mask should be 0x40 #define REG_STATUS_REGISTER_PROTECTION_MASK 0x80 From 61e718ea47a45ad9e45edd393a9ff8bed73dfbe9 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 15 Oct 2020 12:27:02 +0200 Subject: [PATCH 256/297] UefiPayloadPkg/SPI/Fvb.c: Fix FvbRead() to accept buffers up to BLOCK_SIZE --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 28 ------ UefiPayloadPkg/SPI/Fvb.c | 141 ++++++++++++++++++++++------- UefiPayloadPkg/SPI/Fvb.h | 6 -- UefiPayloadPkg/SPI/SPI_fvb.c | 68 +++----------- UefiPayloadPkg/SPI/SPI_fvb.h | 12 --- 5 files changed, 123 insertions(+), 132 deletions(-) diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h index 1dab63240102..38fb9873be84 100644 --- a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h +++ b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h @@ -29,34 +29,6 @@ typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; -// #pragma pack (1) -// typedef struct { -// VENDOR_DEVICE_PATH Vendor; -// UINT8 Index; -// EFI_DEVICE_PATH_PROTOCOL End; -// } NOR_FLASH_DEVICE_PATH; -// #pragma pack () - -// struct _SMMSTORE_INSTANCE { -// UINT32 Signature; -// EFI_HANDLE Handle; -// EFI_BLOCK_IO_MEDIA Media; - -// EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; - -// NOR_FLASH_DEVICE_PATH DevicePath; -// }; - -// -// BlSMMStoreFvbDxe.c -// - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ); - EFI_STATUS EFIAPI FvbGetAttributes( diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 19daf1f89cae..daed8e0d27f8 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -1,13 +1,18 @@ #include +#include #include "Fvb.h" #include "SPI_fvb.h" #include "SPIgeneric.h" #include "spi_flash_internal.h" #include "spi_winbond.h" +#include "SPI.h" #define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * (Lba)) + (Offset)) -#define REMAINING_SPACE_IN_BLOCK(Offset) ((BLOCK_SIZE) - (Offset)) +#define OFFSET_FROM_PAGE_START(Address) ((Address) % (PAGE_SIZE)) +#define REMAINING_SPACE(Offset, MaxSize) ((MaxSize) - (Offset)) +#define REMAINING_SPACE_IN_BLOCK(Offset) REMAINING_SPACE((Offset), (BLOCK_SIZE)) +#define REMAINING_SPACE_IN_PAGE(Offset) REMAINING_SPACE((Offset), (PAGE_SIZE)) static struct spi_slave *getSPISlave(); static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address); @@ -21,13 +26,22 @@ static EFI_STATUS FvbNextBlocksFromList( UINTN *LbaCount); static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args); static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba); +static EFI_STATUS FvbVerifyBlockReadability(EFI_LBA Lba); static EFI_STATUS FvbVerifyConsecutiveBlocksWritability( EFI_LBA Lba, UINTN LbaCount); static EFI_STATUS FvbVerifyBlocksWritability(VA_LIST *Args); static UINTN FvbGetTotalNumberOfBlocks(); static EFI_STATUS WriteEnable(); -static EFI_STATUS PageProgram(UINTN address, UINT8 *Buffer, UINTN NumBytes); +static EFI_STATUS PageProgram( + CONST UINTN Address, + CONST UINT8 *Buffer, + UINTN *NumBytes); +static BOOLEAN FvbIsBlockValid(EFI_LBA Lba); +static EFI_STATUS ReadArray( + CONST UINTN Address, + UINT8 *Buffer, + UINTN *NumBytes); static struct spi_slave *getSPISlave() { static struct spi_slave slave; @@ -40,7 +54,7 @@ static struct spi_slave *getSPISlave() { static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { WriteEnable(); UINT8 blockEraseCmd[] = { - CMD_BLOCK_ERASE, // FIXME Winbond specific + CMD_BLOCK_ERASE, (UINT8)((Address & 0xFF0000) >> 16), (UINT8)((Address & 0xFF00) >> 8), (UINT8) (Address & 0xFF) @@ -153,8 +167,24 @@ static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args) { return status; } -static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba) { +static BOOLEAN FvbIsBlockValid(EFI_LBA Lba) { if(Lba > FvbGetTotalNumberOfBlocks()-1) { + return FALSE; + } else { + return TRUE; + } +} + +static EFI_STATUS FvbVerifyBlockReadability(EFI_LBA Lba) { + if(FvbIsBlockValid(Lba) == FALSE) { + return EFI_ACCESS_DENIED; + } else { + return EFI_SUCCESS; + } +} + +static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba) { + if(FvbIsBlockValid(Lba) == FALSE) { return EFI_ACCESS_DENIED; } else { return EFI_SUCCESS; @@ -209,20 +239,37 @@ static EFI_STATUS WriteEnable() { return EFI_SUCCESS; } -static EFI_STATUS PageProgram(UINTN Address, UINT8 *Buffer, UINTN NumBytes) { - UINT8 pageProgramCmd[] = { - CMD_W25_PP, // FIXME Winbond specific - (UINT8)((Address & 0xFF0000) >> 16), - (UINT8)((Address & 0x00FF00) >> 8), // WRITING DUMMY DATA - (UINT8) (Address & 0x0000FF), 0xAA, 0xBB, 0xCC, 0xDD - }; +static EFI_STATUS PageProgram( + CONST UINTN Address, + CONST UINT8 *Buffer, + UINTN *NumBytes +) { + CONST UINTN commandHeaderLength = 4; + CONST UINTN maxLengthToWrite = MIN( + SPI_FIFO_DEPTH-commandHeaderLength, + REMAINING_SPACE_IN_PAGE(OFFSET_FROM_PAGE_START(Address)) + ); + CONST UINTN lengthOfDataToWrite = MIN(*NumBytes, maxLengthToWrite); + if(*NumBytes == 0 || Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + UINT8 pageProgramCmd[commandHeaderLength+maxLengthToWrite]; + pageProgramCmd[0] = CMD_W25_PP; // FIXME Winbond specific + pageProgramCmd[1] = (UINT8)((Address & 0xFF0000) >> 16); + pageProgramCmd[2] = (UINT8)((Address & 0x00FF00) >> 8); + pageProgramCmd[3] = (UINT8) (Address & 0x0000FF); + CopyMem(pageProgramCmd+commandHeaderLength, Buffer, lengthOfDataToWrite); if(spi_xfer( getSPISlave(), - pageProgramCmd, 8/*ARRAY_SIZE(pageProgramCmd)*/, + pageProgramCmd, commandHeaderLength+lengthOfDataToWrite, NULL, 0) != 0) { DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } + if(lengthOfDataToWrite != *NumBytes) { + *NumBytes = lengthOfDataToWrite; + return EFI_BAD_BUFFER_SIZE; + } WaitForBusyBit(); return EFI_SUCCESS; } @@ -243,6 +290,31 @@ static EFI_STATUS RemoveBlockProtection() { return EFI_SUCCESS; } +static EFI_STATUS ReadArray(CONST UINTN Address, UINT8 *Buffer, UINTN *NumBytes) { + UINT8 command[] = { + CMD_READ_ARRAY_SLOW, + (UINT8)((Address & 0xFF0000) >> 16), + (UINT8)((Address & 0xFF00) >> 8), + (UINT8) (Address & 0xFF) + }; + UINTN numberOfBytesToRead = MIN(MIN( + *NumBytes, + REMAINING_SPACE_IN_PAGE(OFFSET_FROM_PAGE_START(Address))), + SPI_FIFO_DEPTH-ARRAY_SIZE(command) + ); + if(spi_xfer(getSPISlave(), + command, ARRAY_SIZE(command), + Buffer, numberOfBytesToRead) != 0) { + DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + if(numberOfBytesToRead != *NumBytes) { + *NumBytes = numberOfBytesToRead; + return EFI_BAD_BUFFER_SIZE; + } + return EFI_SUCCESS; +} + // STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; // STATIC UINTN mFlashNvStorageVariableBase; @@ -456,6 +528,7 @@ FvbGetBlockSize ( @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. **/ + EFI_STATUS EFIAPI FvbRead ( @@ -466,33 +539,27 @@ FvbRead ( IN OUT UINT8 *Buffer ) { - // FIXME check if read is not done from outside flash memory UINTN address = ADDRESS(Lba, Offset); - // Maxumum amount of bytes possible to read. Can't span the block boundary UINTN numberOfBytesToRead = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); UINTN numberOfBytesRead = 0; + if(FvbVerifyBlockReadability(Lba) == EFI_ACCESS_DENIED) { + return EFI_ACCESS_DENIED; + } if(Buffer == NULL || numberOfBytesToRead == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; } - WaitForBusyBit(); while(numberOfBytesRead < numberOfBytesToRead) { - UINTN nextReadAddress = address + numberOfBytesRead; - UINTN numberOfBytesLeft = numberOfBytesToRead - numberOfBytesRead; - UINTN numberOfBytesToReadNext = MIN(numberOfBytesLeft, PAGE_SIZE); - UINT8 command[] = { - CMD_READ_ARRAY_SLOW, - (UINT8)((nextReadAddress & 0xFF0000) >> 16), - (UINT8)((nextReadAddress & 0xFF00) >> 8), - (UINT8) (nextReadAddress & 0xFF) - }; - if(spi_xfer(getSPISlave(), - command, ARRAY_SIZE(command), - Buffer+numberOfBytesRead, numberOfBytesToReadNext) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); + UINTN bytesRead = numberOfBytesToRead - numberOfBytesRead; + EFI_STATUS readStatus = ReadArray( + address+numberOfBytesRead, + Buffer+numberOfBytesRead, + &bytesRead + ); + if(readStatus != EFI_SUCCESS && readStatus != EFI_BAD_BUFFER_SIZE) { return EFI_DEVICE_ERROR; } - numberOfBytesRead += numberOfBytesToReadNext; + numberOfBytesRead += bytesRead; } if(numberOfBytesToRead != *NumBytes) { @@ -567,8 +634,11 @@ FvbWrite ( IN UINT8 *Buffer ) { - CONST UINTN numberOfBytesToWrite = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); + CONST UINTN numberOfBytesToWrite = MIN( + *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset) + ); CONST UINTN address = ADDRESS(Lba, Offset); + UINTN numberOfBytesWritten = 0; if(Buffer == NULL || numberOfBytesToWrite == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); return EFI_BAD_BUFFER_SIZE; @@ -578,10 +648,17 @@ FvbWrite ( } if(RemoveBlockProtection() != EFI_SUCCESS || WaitForBusyBit() != EFI_SUCCESS - || WriteEnable() != EFI_SUCCESS - || PageProgram(address, Buffer, numberOfBytesToWrite) != EFI_SUCCESS) { + || WriteEnable() != EFI_SUCCESS) { return EFI_DEVICE_ERROR; } + while(numberOfBytesWritten < numberOfBytesToWrite) { + UINTN writtenAmount = numberOfBytesToWrite; + EFI_STATUS writingStatus = PageProgram(address, Buffer, &writtenAmount); + if(writingStatus != EFI_SUCCESS && writingStatus != EFI_BAD_BUFFER_SIZE) { + return EFI_DEVICE_ERROR; + } + numberOfBytesWritten += writtenAmount; + } if(numberOfBytesToWrite != *NumBytes) { return EFI_BAD_BUFFER_SIZE; } diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index 2a6471376294..7f4b0d3c3af6 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -83,10 +83,4 @@ FvbVirtualNotifyEvent ( IN VOID *Context ); -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ); - #endif /* FVB_H */ diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 8c6cf9419f0d..112b2e4c5e59 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -6,18 +6,18 @@ **/ -#include +// #include #include #include #include -#include +//#include #include #include #include #include #include #include -#include +//#include #include "SPIgeneric.h" #include "fch_spi_ctrl.h" #include "Fvb.h" @@ -25,29 +25,23 @@ EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite,// FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks - NULL - }; + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite,// FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL +}; EFI_STATUS checkBusyBit(UINT8 *Busy); EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable - ) -{ +) { EFI_STATUS Status; - struct spi_slave slave; - DEBUG((EFI_D_INFO, "SPI IS HERE\n")); - - DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); - DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, @@ -55,42 +49,8 @@ EFI_STATUS EFIAPI SPIInitialize ( ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; } spi_init(); - DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); - unsigned char fill[300] = {}; - UINTN length = 30; - FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); - DEBUG((EFI_D_INFO, "TRIALS\n")); - for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); - } - DEBUG((EFI_D_INFO, "ERASING\n")); - FvbEraseBlocks(&FvbProtocol, 0, 2, 4, 5, EFI_LBA_LIST_TERMINATOR); - FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); - for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); - } - DEBUG((EFI_D_INFO, "WRITING\n")); - UINT8 toWrite[] = {01, 0x01, 0x01, 0x77}; - UINTN writeLen = 4; - EFI_STATUS status = FvbWrite(&FvbProtocol, 0, 1, &writeLen, toWrite); - DEBUG((EFI_D_INFO, "Written: 0x%X\n", writeLen)); - if(status == EFI_SUCCESS) { - DEBUG((EFI_D_INFO, "EFI_SUCCESS\n")); - } else if(status == EFI_BAD_BUFFER_SIZE) { - DEBUG((EFI_D_INFO, "EFI_BAD_BUFFER_SIZE\n")); - } else if(status == EFI_ACCESS_DENIED) { - DEBUG((EFI_D_INFO, "EFI_ACCESS_DENIED\n")); - } else { - DEBUG((EFI_D_INFO, "It's really bad\n")); - } - unsigned char newFill[300] = {}; - UINTN newLength = 30; - FvbRead(&FvbProtocol, 0, 0, &newLength, (VOID *)newFill); - for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)newFill[i])); - } - while(TRUE); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI_fvb.h b/UefiPayloadPkg/SPI/SPI_fvb.h index e1d6a87bff08..3699432cd617 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.h +++ b/UefiPayloadPkg/SPI/SPI_fvb.h @@ -110,18 +110,6 @@ struct spi_flash_protection_ops { }; -void * memset (void *dest, int ch, __SIZE_TYPE__ count); - -// -// BlSMMStoreFvbDxe.c -// - -EFI_STATUS -EFIAPI -SMMStoreFvbInitialize ( - IN SMMSTORE_INSTANCE* Instance - ); - EFI_STATUS EFIAPI FvbGetAttributes( From 4308372150b8b46417cac299103187082016fa3c Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 15 Oct 2020 14:03:06 +0200 Subject: [PATCH 257/297] UefiPayloadPkg/SPI/*: Applied review suggestions --- .../Variable/RuntimeDxe/VariableNonVolatile.c | 17 --- UefiPayloadPkg/SPI/SPI.h | 3 - UefiPayloadPkg/SPI/SPI.inf | 4 - UefiPayloadPkg/SPI/SPI_fvb.c | 44 ++---- UefiPayloadPkg/SPI/SPI_fvb.h | 10 -- UefiPayloadPkg/SPI/fch_spi_ctrl.c | 130 +++-------------- UefiPayloadPkg/SPI/fch_spi_util.c | 41 ++++-- UefiPayloadPkg/SPI/fch_spi_util.h | 5 +- UefiPayloadPkg/SPI/lpc.c | 13 -- UefiPayloadPkg/SPI/lpc.h | 133 ------------------ UefiPayloadPkg/SPI/mmio.c | 37 ----- UefiPayloadPkg/SPI/mmio.h | 44 ------ 12 files changed, 66 insertions(+), 415 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/lpc.c delete mode 100644 UefiPayloadPkg/SPI/lpc.h delete mode 100644 UefiPayloadPkg/SPI/mmio.c delete mode 100644 UefiPayloadPkg/SPI/mmio.h diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c index 1916c16c785a..0637a828b33f 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c @@ -6,13 +6,6 @@ SPDX-License-Identifier: BSD-2-Clause-Patent **/ -#include -#include -#include -#include -#include -//#include - #include "VariableNonVolatile.h" #include "VariableParsing.h" @@ -124,16 +117,6 @@ InitEmuNonVolatileVariableStore ( return EFI_SUCCESS; } -typedef struct { - UINT64 ComBuffer; - UINT32 ComBufferSize; - UINT32 NumBlocks; - UINT32 BlockSize; - UINT64 MmioAddress; - UINT8 ApmCmd; - UINT8 Reserved0[3]; -} SMMSTORE_INFO; - /** Init real non-volatile variable store. diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index e58c2f947487..46ac43061815 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -76,7 +76,4 @@ struct spi_config { enum spi100_speed tpm_speed; }; -/* Set the SPI base address variable */ -VOID spi_set_base(VOID *base); - #endif /* __AMDBLOCKS_SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 689ad89dc220..cafba872edef 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -19,8 +19,6 @@ SPI.h SPIgeneric.h SPIgeneric.c - lpc.h - lpc.c pci_type.h device.h kconfig.h @@ -30,8 +28,6 @@ SPI_fvb.c fch_spi_util.h fch_spi_util.c - mmio.h - mmio.c stopwatch.h pci_devs.h pci_ops.h diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 112b2e4c5e59..5f0f062e1e1f 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -6,47 +6,33 @@ **/ -// #include #include #include #include -//#include -#include -#include -#include -#include -#include -#include -//#include -#include "SPIgeneric.h" #include "fch_spi_ctrl.h" #include "Fvb.h" -#include "spi_flash_internal.h" -EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress + NULL, // GetAttributes + NULL, // SetAttributes + NULL, // GetPhysicalAddress FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite,// FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks - NULL + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL // ParentHandle }; -EFI_STATUS checkBusyBit(UINT8 *Busy); - -EFI_STATUS EFIAPI SPIInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable +EFI_STATUS EFIAPI SPIInitialize( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); + Status = gBS->InstallMultipleProtocolInterfaces( + NULL, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); return EFI_DEVICE_ERROR; diff --git a/UefiPayloadPkg/SPI/SPI_fvb.h b/UefiPayloadPkg/SPI/SPI_fvb.h index 3699432cd617..94264dfd94da 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.h +++ b/UefiPayloadPkg/SPI/SPI_fvb.h @@ -72,16 +72,6 @@ enum optype { WRITE_WITH_ADDR = 3 }; -struct intel_spi_op { - UINT8 op; - enum optype type; -}; - -struct intel_swseq_spi_config { - UINT8 opprefixes[2]; - struct intel_spi_op ops[8]; -}; - struct spi_flash_protection_ops { /* * Returns 1 if the whole region is software write protected. diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/fch_spi_ctrl.c index 85679479bf75..d418033ba414 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/fch_spi_ctrl.c @@ -7,32 +7,35 @@ #include "stopwatch.h" #include "fch_spi_util.h" #include "SPIgeneric.h" -#include "lpc.h" #include "pci_devs.h" #include "pci_ops.h" #include "spi_flash_internal.h" /* SPDX-License-Identifier: GPL-2.0-only */ -#define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ -#define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) +#define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ +#define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) /* SPI MMIO registers */ -#define SPI_RESTRICTED_CMD1 0x04 -#define SPI_RESTRICTED_CMD2 0x08 -#define SPI_CNTRL1 0x0c -#define SPI_CMD_CODE 0x45 -#define SPI_CMD_TRIGGER 0x47 -#define SPI_CMD_TRIGGER_EXECUTE BIT7 -#define SPI_TX_BYTE_COUNT 0x48 -#define SPI_RX_BYTE_COUNT 0x4b -#define SPI_STATUS 0x4c -#define SPI_DONE_BYTE_COUNT_SHIFT 0 -#define SPI_DONE_BYTE_COUNT_MASK 0xff -#define SPI_FIFO_WR_PTR_SHIFT 8 -#define SPI_FIFO_WR_PTR_MASK 0x7f -#define SPI_FIFO_RD_PTR_SHIFT 16 -#define SPI_FIFO_RD_PTR_MASK 0x7f +#define SPI_RESTRICTED_CMD1 0x04 +#define SPI_RESTRICTED_CMD2 0x08 +#define SPI_CNTRL1 0x0c +#define SPI_CMD_CODE 0x45 +#define SPI_CMD_TRIGGER 0x47 +#define SPI_CMD_TRIGGER_EXECUTE 0x80 +#define SPI_TX_BYTE_COUNT 0x48 +#define SPI_RX_BYTE_COUNT 0x4b +#define SPI_STATUS 0x4c +#define SPI_DONE_BYTE_COUNT_SHIFT 0 +#define SPI_DONE_BYTE_COUNT_MASK 0xff +#define SPI_FIFO_WR_PTR_SHIFT 8 +#define SPI_FIFO_WR_PTR_MASK 0x7f +#define SPI_FIFO_RD_PTR_SHIFT 16 +#define SPI_FIFO_RD_PTR_MASK 0x7f + +#define MAX_ROM_PROTECT_RANGES 4 +#define ROM_PROTECT_RANGE0 0x50 +#define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) VOID dump_state(CONST char *str, UINT8 phase) { @@ -169,102 +172,11 @@ int protect_a_range(UINT32 value) return 0; } -/* - * Protect range of SPI flash defined by region using the SPI flash controller. - * - * Note: Up to 4 ranges can be protected, though if a particular region requires more than one - * range, total number of regions decreases accordingly. Each range can be programmed to 4KiB or - * 64KiB granularity. - * - * Warning: If more than 1 region needs protection, and they need mixed protections (read/write) - * than start with the region that requires the most protection. After the restricted commands - * have been written, they can't be changed (write once). So if first region is write protection - * and second region is read protection, it's best to define first region as read and write - * protection. - */ -int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, - CONST enum ctrlr_prot_type type) -{ - int ret; - UINT32 reg32, rom_base, range_base; - __SIZE_TYPE__ addr, len, gran_value, total_ranges, range; - BOOLEAN granularity_64k = TRUE; /* assume 64k granularity */ - - addr = region->offset; - len = region->size; - - reg32 = pci_read_config32((struct device *)((VOID *)SOC_LPC_DEV), ROM_ADDRESS_RANGE2_START); - rom_base = WORD_TO_DWORD_UPPER(reg32); - if (addr < rom_base) - return -1; - range_base = addr % rom_base; - - /* Define granularity to be used */ - if (GRANULARITY_TEST_4k & range_base) - granularity_64k = FALSE; /* use 4K granularity */ - if (GRANULARITY_TEST_4k & len) - granularity_64k = FALSE; /* use 4K granularity */ - - /* Define the first range and total number of ranges required */ - if (granularity_64k) { - gran_value = 0x00010000; /* 64 KiB */ - range_base = range_base >> 16; - } else { - gran_value = 0x00001000; /* 4 KiB */ - range_base = range_base >> 12; - } - total_ranges = len / gran_value; - range_base &= RANGE_ADDR_MASK; - - /* Create reg32 to be written into a range register and program required ranges */ - reg32 = rom_base & ROM_BASE_MASK; - reg32 |= range_base; - if (granularity_64k) - reg32 |= RANGE_UNIT; - if (type & WRITE_PROTECT) - reg32 |= ROM_RANGE_WP; - if (type & READ_PROTECT) - reg32 |= ROM_RANGE_RP; - - for (range = 0; range < total_ranges; range++) { - ret = protect_a_range(reg32); - if (ret) - return ret; - /* - * Next range (lower 8 bits). Range points to the start address of a region. - * The range value must be multiplied by the granularity (which is also the - * size of the region) to get the actual offset from the SPI start address. - */ - reg32++; - } - - /* define commands to be blocked if in range */ - reg32 = 0; - if (type & WRITE_PROTECT) { - /* FIXME */ - DEBUG((EFI_D_INFO, "%a: %s: Write Enable and Write Cmd not blocked\n", __FUNCTION__, __func__)); - reg32 |= (flash->erase_cmd << 8); - } - if (type & READ_PROTECT) { - /* FIXME */ - DEBUG((EFI_D_INFO, "%a: %s: READ_PROTECT not supported.\n", __FUNCTION__, __func__)); - } - - /* Final steps to protect region */ - pci_write_config32((struct device *)((VOID *)SOC_LPC_DEV), SPI_RESTRICTED_CMD1, reg32); - reg32 = spi_read32(SPI_CNTRL0); - reg32 &= ~SPI_ACCESS_MAC_ROM_EN; - spi_write32(SPI_CNTRL0, reg32); - - return 0; -} - CONST struct spi_ctrlr fch_spi_flash_ctrlr = { .xfer = spi_ctrlr_xfer, .xfer_vector = xfer_vectors, .max_xfer_size = SPI_FIFO_DEPTH, .flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN, - .flash_protect = fch_spi_flash_protect, }; CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/fch_spi_util.c index bec465b8add2..c637f28983f1 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/fch_spi_util.c @@ -1,64 +1,77 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include "mmio.h" #include "fch_spi_util.h" -#include "lpc.h" +#include "utils.h" #include #include +#include #include "fch_spi_ctrl.h" #include "pci_mmio_cfg.h" #include "device.h" +#include "pci_ops.h" -static unsigned long int spi_base = 0; +#define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) +#define SPIROM_BASE_ADDRESS_REGISTER 0xa0 +#define SPI_BASE_ALIGNMENT 0x00000040 -VOID spi_set_base(VOID *base) +static UINTN spi_base = 0; + +UINTN lpc_get_spibase(VOID) +{ + UINT32 base; + base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); + base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); + return (unsigned long int)base; +} + +VOID spi_set_base(UINTN base) { - spi_base = (unsigned long int)base; + spi_base = base; } //static //__attribute__ ((__always_inline__)) union pci_bank *pcicfg(pci_devfn_t dev) { // FIXME this should not be a magic constant - UINT8 *pci_mmconf =(void *)((unsigned long int)(0xF8000000)); + UINT8 *pci_mmconf =(void *)((UINTN)(0xF8000000)); return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; } -unsigned long int spi_get_bar(VOID) +UINTN spi_get_bar(VOID) { if (spi_base == 0) { - spi_set_base((VOID *)lpc_get_spibase()); + spi_set_base(lpc_get_spibase()); } return spi_base; } UINT8 spi_read8(UINT8 reg) { - return read8((VOID *)(spi_get_bar() + reg)); + return MmioRead8((spi_get_bar() + reg)); } UINT16 spi_read16(UINT8 reg) { - return read8((VOID *)(spi_get_bar() + reg)); + return MmioRead16((spi_get_bar() + reg)); } UINT32 spi_read32(UINT8 reg) { - return read32((VOID *)(spi_get_bar() + reg)); + return MmioRead32((spi_get_bar() + reg)); } VOID spi_write8(UINT8 reg, UINT8 val) { - write8((VOID *)(spi_get_bar() + reg), val); + MmioWrite8((spi_get_bar() + reg), val); } VOID spi_write16(UINT8 reg, UINT16 val) { - write16((VOID *)(spi_get_bar() + reg), val); + MmioWrite16((spi_get_bar() + reg), val); } VOID spi_write32(UINT8 reg, UINT32 val) { - write32((VOID *)(spi_get_bar() + reg), val); + MmioWrite32((spi_get_bar() + reg), val); } diff --git a/UefiPayloadPkg/SPI/fch_spi_util.h b/UefiPayloadPkg/SPI/fch_spi_util.h index 1d3521665e08..ae8ee335c907 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.h +++ b/UefiPayloadPkg/SPI/fch_spi_util.h @@ -4,8 +4,9 @@ #include #include "pci_type.h" -VOID spi_set_base(VOID *base); -unsigned long int spi_get_bar(VOID); +UINTN lpc_get_spibase(VOID); +VOID spi_set_base(UINTN base); +UINTN spi_get_bar(VOID); UINT8 spi_read8(UINT8 reg); UINT16 spi_read16(UINT8 reg); UINT32 spi_read32(UINT8 reg); diff --git a/UefiPayloadPkg/SPI/lpc.c b/UefiPayloadPkg/SPI/lpc.c deleted file mode 100644 index 6aa21ecbd294..000000000000 --- a/UefiPayloadPkg/SPI/lpc.c +++ /dev/null @@ -1,13 +0,0 @@ -#include - -#include "lpc.h" -#include "pci_ops.h" -#include "utils.h" - -unsigned long int lpc_get_spibase(void) -{ - UINT32 base; - base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); - base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); - return (unsigned long int)base; -} diff --git a/UefiPayloadPkg/SPI/lpc.h b/UefiPayloadPkg/SPI/lpc.h deleted file mode 100644 index 772445e4320a..000000000000 --- a/UefiPayloadPkg/SPI/lpc.h +++ /dev/null @@ -1,133 +0,0 @@ -#include "pci_type.h" - -/* PCI registers for D14F3 */ -#define LPC_PCI_CONTROL 0x40 -#define LEGACY_DMA_EN BIT2 -#define VW_ROM_SHARING_EN BIT3 -#define EXT_ROM_SHARING_EN BIT4 - -#define LPC_IO_PORT_DECODE_ENABLE 0x44 -#define DECODE_ENABLE_PARALLEL_PORT0 BIT0 -#define DECODE_ENABLE_PARALLEL_PORT1 BIT1 -#define DECODE_ENABLE_PARALLEL_PORT2 BIT2 -#define DECODE_ENABLE_PARALLEL_PORT3 BIT3 -#define DECODE_ENABLE_PARALLEL_PORT4 BIT4 -#define DECODE_ENABLE_PARALLEL_PORT5 BIT5 -#define DECODE_ENABLE_SERIAL_PORT0 BIT6 -#define DECODE_ENABLE_SERIAL_PORT1 BIT7 -#define DECODE_ENABLE_SERIAL_PORT2 BIT8 -#define DECODE_ENABLE_SERIAL_PORT3 BIT9 -#define DECODE_ENABLE_SERIAL_PORT4 BIT10 -#define DECODE_ENABLE_SERIAL_PORT5 BIT11 -#define DECODE_ENABLE_SERIAL_PORT6 BIT12 -#define DECODE_ENABLE_SERIAL_PORT7 BIT13 -#define DECODE_ENABLE_AUDIO_PORT0 BIT14 -#define DECODE_ENABLE_AUDIO_PORT1 BIT15 -#define DECODE_ENABLE_AUDIO_PORT2 BIT16 -#define DECODE_ENABLE_AUDIO_PORT3 BIT17 -#define DECODE_ENABLE_MIDI_PORT0 BIT18 -#define DECODE_ENABLE_MIDI_PORT1 BIT19 -#define DECODE_ENABLE_MIDI_PORT2 BIT20 -#define DECODE_ENABLE_MIDI_PORT3 BIT21 -#define DECODE_ENABLE_MSS_PORT0 BIT22 -#define DECODE_ENABLE_MSS_PORT1 BIT23 -#define DECODE_ENABLE_MSS_PORT2 BIT24 -#define DECODE_ENABLE_MSS_PORT3 BIT25 -#define DECODE_ENABLE_FDC_PORT0 BIT26 -#define DECODE_ENABLE_FDC_PORT1 BIT27 -#define DECODE_ENABLE_GAME_PORT BIT28 -#define DECODE_ENABLE_KBC_PORT BIT29 -#define DECODE_ENABLE_ACPIUC_PORT BIT30 -#define DECODE_ENABLE_ADLIB_PORT BIT31 - -#define LPC_IO_OR_MEM_DECODE_ENABLE 0x48 -#define LPC_WIDEIO2_ENABLE BIT25 -#define LPC_WIDEIO1_ENABLE BIT24 -#define DECODE_IO_PORT_ENABLE6 BIT23 -#define DECODE_IO_PORT_ENABLE5 BIT22 -#define DECODE_IO_PORT_ENABLE4 BIT21 -#define DECODE_MEM_PORT_ENABLE1 BIT20 -#define DECODE_IO_PORT_ENABLE3 BIT19 -#define DECODE_IO_PORT_ENABLE2 BIT18 -#define DECODE_IO_PORT_ENABLE1 BIT17 -#define DECODE_IO_PORT_ENABLE0 BIT16 -#define LPC_SYNC_TIMEOUT_COUNT_MASK (0xff << 8) -#define LPC_SYNC_TIMEOUT_COUNT_ENABLE BIT7 -#define LPC_DECODE_RTC_IO_ENABLE BIT6 -#define DECODE_MEM_PORT_ENABLE0 BIT5 -#define LPC_WIDEIO0_ENABLE BIT2 -#define DECODE_ALTERNATE_SIO_ENABLE BIT1 -#define DECODE_SIO_ENABLE BIT0 -#define LPC_SELECT_SIO_4E4F 1 -#define LPC_SELECT_SIO_2E2F 0 -#define WIDEIO_RANGE_ERROR -1 - -/* Assuming word access to higher word (register 0x4a) */ -#define LPC_IO_OR_MEM_DEC_EN_HIGH 0x4a -#define LPC_WIDEIO2_ENABLE_H BIT9 -#define LPC_WIDEIO1_ENABLE_H BIT8 -#define DECODE_IO_PORT_ENABLE6_H BIT7 -#define DECODE_IO_PORT_ENABLE5_H BIT6 -#define DECODE_IO_PORT_ENABLE4_H BIT5 -#define DECODE_IO_PORT_ENABLE3_H BIT3 -#define DECODE_IO_PORT_ENABLE2_H BIT2 -#define DECODE_IO_PORT_ENABLE1_H BIT1 -#define DECODE_IO_PORT_ENABLE0_H BIT0 - -#define LPC_MEM_PORT1 0x4c -#define ROM_PROTECT_RANGE0 0x50 -#define ROM_BASE_MASK 0xfffff000 /* bits 31-12 */ -#define ROM_RANGE_WP BIT10 -#define ROM_RANGE_RP BIT9 -#define RANGE_UNIT BIT8 -#define RANGE_ADDR_MASK 0x000000ff /* Range defined by bits 7-0 */ -#define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) -#define MAX_ROM_PROTECT_RANGES 4 -#define LPC_MEM_PORT0 0x60 - -/* Register 0x64 is 32-bit, composed by two 16-bit sub-registers. - For ease of access, each sub-register is declared separately. */ -#define LPC_WIDEIO_GENERIC_PORT 0x64 -#define LPC_WIDEIO1_GENERIC_PORT 0x66 -#define ROM_ADDRESS_RANGE1_START 0x68 -#define ROM_ADDRESS_RANGE1_END 0x6a -#define ROM_ADDRESS_RANGE2_START 0x6c -#define ROM_ADDRESS_RANGE2_END 0x6e - -#define LPC_ALT_WIDEIO_RANGE_ENABLE 0x74 -#define LPC_ALT_WIDEIO2_ENABLE BIT3 -#define LPC_ALT_WIDEIO1_ENABLE BIT2 -#define LPC_ALT_WIDEIO0_ENABLE BIT0 - -#define LPC_MISC_CONTROL_BITS 0x78 -#define LPC_NOHOG BIT0 - -#define LPC_TRUSTED_PLATFORM_MODULE 0x7c -#define TPM_12_EN BIT0 -#define TPM_LEGACY_EN BIT2 - -#define LPC_WIDEIO2_GENERIC_PORT 0x90 - -#define SPIROM_BASE_ADDRESS_REGISTER 0xa0 -#define SPI_BASE_ALIGNMENT BIT6 -#define SPI_BASE_RESERVED (BIT4 | BIT5) -#define ROUTE_TPM_2_SPI BIT3 -#define SPI_ABORT_ENABLE BIT2 -#define SPI_ROM_ENABLE BIT1 -#define SPI_ROM_ALT_ENABLE BIT0 -#define SPI_PRESERVE_BITS (BIT0 | BIT1 | BIT2 | BIT3) - -/* LPC register 0xb8 is DWORD, here there are definitions for byte - access. For example, bits 31-24 are accessed through byte access - at register 0xbb. */ -#define LPC_ROM_DMA_EC_HOST_CONTROL 0xb8 -#define SPI_FROM_HOST_PREFETCH_EN BIT24 -#define SPI_FROM_USB_PREFETCH_EN BIT23 - -#define LPC_HOST_CONTROL 0xbb -#define PREFETCH_EN_SPI_FROM_HOST BIT0 -#define T_START_ENH BIT3 - -#define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) - -unsigned long int lpc_get_spibase(void); diff --git a/UefiPayloadPkg/SPI/mmio.c b/UefiPayloadPkg/SPI/mmio.c deleted file mode 100644 index 9d415ed449fc..000000000000 --- a/UefiPayloadPkg/SPI/mmio.c +++ /dev/null @@ -1,37 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* Originally imported from linux/include/asm-arm/io.h. This file has changed - * substantially since then. - */ - -#include -#include "mmio.h" - -// static inline UINT8 read8(CONST VOID *addr) -// { -// return *(volatile uint8_t *)addr; -// } - -// static inline UINT16 read16(CONST VOID *addr) -// { -// return *(volatile UINT16 *)addr; -// } - -// static inline UINT32 read32(CONST VOID *addr) -// { -// return *(volatile UINT32 *)addr; -// } - -// static inline VOID write8(VOID *addr, uint8_t val) -// { -// *(volatile uint8_t *)addr = val; -// } - -// static inline VOID write16(VOID *addr, UINT16 val) -// { -// *(volatile UINT16 *)addr = val; -// } - -// static inline VOID write32(VOID *addr, UINT32 val) -// { -// *(volatile UINT32 *)addr = val; -// } diff --git a/UefiPayloadPkg/SPI/mmio.h b/UefiPayloadPkg/SPI/mmio.h deleted file mode 100644 index b74a9ecf24e5..000000000000 --- a/UefiPayloadPkg/SPI/mmio.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef MMIO_H -#define MMIO_H - -#include - -// static inline UINT8 read8(CONST VOID *addr); -// static inline UINT16 read16(CONST VOID *addr); -// static inline UINT32 read32(CONST VOID *addr); -// static inline VOID write8(VOID *addr, UINT8 val); -// static inline VOID write16(VOID *addr, UINT16 val); -// static inline VOID write32(VOID *addr, UINT32 val); - -static inline UINT8 read8(CONST VOID *addr) -{ - return *(volatile UINT8 *)addr; -} - -static inline UINT16 read16(CONST VOID *addr) -{ - return *(volatile UINT16 *)addr; -} - -static inline UINT32 read32(CONST VOID *addr) -{ - return *(volatile UINT32 *)addr; -} - -static inline VOID write8(VOID *addr, UINT8 val) -{ - *(volatile UINT8 *)addr = val; -} - -static inline VOID write16(VOID *addr, UINT16 val) -{ - *(volatile UINT16 *)addr = val; -} - -static inline VOID write32(VOID *addr, UINT32 val) -{ - *(volatile UINT32 *)addr = val; -} - - -#endif /* MMIO_H */ From bfe0be8a751d792aa89c2cd08bd77c0c3889c8ca Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 15 Oct 2020 14:53:10 +0200 Subject: [PATCH 258/297] UefiPayloadPkg/SPI/*: clean the unnecessery code --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 90 ----------------------- UefiPayloadPkg/SPI/Fvb.h | 2 +- UefiPayloadPkg/SPI/SPI.inf | 2 +- UefiPayloadPkg/SPI/pci_ops.c | 111 +++++++++++++++-------------- UefiPayloadPkg/SPI/pci_ops.h | 77 ++------------------ 5 files changed, 68 insertions(+), 214 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/BlSMMStoreDxe.h diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h deleted file mode 100644 index 38fb9873be84..000000000000 --- a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h +++ /dev/null @@ -1,90 +0,0 @@ -/** @file BlSMMStoreDxe.h - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __COREBOOT_SMM_STORE_DXE_H__ -#define __COREBOOT_SMM_STORE_DXE_H__ - - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') -#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) - -typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; - -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbGetBlockSize( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbRead( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbWrite( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbEraseBlocks( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ); - - -#endif /* __COREBOOT_SMM_STORE_DXE_H__ */ diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index 7f4b0d3c3af6..b2957478821a 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -2,7 +2,7 @@ #define FVB_H #include -#include "BlSMMStoreDxe.h" +#include "SPI_fvb.h" #define BLOCK_SIZE 0x10000 #define PAGE_SIZE 0x100 diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index cafba872edef..eb1fdcc4a50a 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -31,7 +31,7 @@ stopwatch.h pci_devs.h pci_ops.h - # pci_ops.c + pci_ops.c Fvb.h Fvb.c spi_flash_internal.h diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index a28d799e39e8..b8bc2b5e62d7 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -1,52 +1,59 @@ -// #include -// #include - -// #include "pci_ops.h" -// #include "pci_type.h" -// #include "device.h" -// #include "pci_mmio_cfg.h" - -// static __attribute__ ((__always_inline__)) inline -// UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -// { -// return pci_mmio_read_config32(dev, reg); -// } - -// static __attribute__ ((__always_inline__)) inline -// pci_devfn_t pcidev_bdf(CONST struct device *dev) -// { -// return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -// } - -// __attribute__ ((noreturn)) -// VOID pcidev_die(VOID) -// { -// die("PCI: dev is NULL!\n"); -// while(1); -// } - -// static __attribute__ ((__always_inline__)) inline -// pci_devfn_t pcidev_assert(CONST struct device *dev) -// { -// if (!dev) -// pcidev_die(); -// return pcidev_bdf(dev); -// } - -// static __attribute__ ((__always_inline__)) inline -// UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -// { -// return pci_s_read_config32(PCI_BDF(dev), reg); -// } - -// static __attribute__ ((__always_inline__)) inline -// VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -// { -// pci_mmio_write_config32(dev, reg, value); -// } - -// static __attribute__ ((__always_inline__)) inline -// VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -// { -// pci_s_write_config32(PCI_BDF(dev), reg, val); -// } +#include +#include + +#include "pci_ops.h" +#include "pci_type.h" +#include "device.h" +//#include "pci_mmio_cfg.h" +#include "pci_type.h" +#include "fch_spi_ctrl.h" + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; +} + +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +pci_devfn_t pcidev_bdf(CONST struct device *dev) +{ + return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +} + +static __attribute__ ((noreturn)) +VOID pcidev_die(VOID) +{ + DEBUG((EFI_D_INFO, "PCI: dev is NULL!\n", __FUNCTION__)); + while(1); +} + +pci_devfn_t pcidev_assert(CONST struct device *dev) +{ + if (!dev) + pcidev_die(); + return pcidev_bdf(dev); +} + +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +{ + return pci_s_read_config32(PCI_BDF(dev), reg); +} + +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pci_mmio_write_config32(dev, reg, value); +} + +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) +{ + pci_s_write_config32(PCI_BDF(dev), reg, val); +} diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index cd9d896f9f93..69c8ba7e08cd 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -1,78 +1,15 @@ #ifndef PCI_OPS_H #define PCI_OPS_H -// #include -// #include "device.h" -// #include "pci_type.h" - #include -#include - -#include "pci_ops.h" -#include "pci_type.h" #include "device.h" -#include "pci_mmio_cfg.h" -#include "fch_spi_util.h" -#include "fch_spi_ctrl.h" - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -static __attribute__ ((__always_inline__)) inline -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_bdf(CONST struct device *dev) -{ - return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -} - -// __attribute__ ((noreturn)) -// VOID pcidev_die(VOID) -// { -// //die("PCI: dev is NULL!\n"); -// DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); -// while(1); -// } - -static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_assert(CONST struct device *dev) -{ - if (!dev) { - DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); - } - return pcidev_bdf(dev); -} - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -{ - return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); - //return pci_s_read_config32(PCI_BDF(dev), reg); -} - -static __attribute__ ((__always_inline__)) inline -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pci_mmio_write_config32(dev, reg, value); -} +#include "pci_type.h" -static __attribute__ ((__always_inline__)) inline -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -{ - pci_s_write_config32(PCI_BDF(dev), reg, val); -} +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); +pci_devfn_t pcidev_bdf(CONST struct device *dev); +pci_devfn_t pcidev_assert(CONST struct device *dev); +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val); #endif /* PCI_OPS_H */ From ac174692a0aea352e4aedcbba56295d07c119432 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 16 Oct 2020 09:40:37 +0200 Subject: [PATCH 259/297] Revert "UefiPayloadPkg/SPI/*: clean the unnecessery code" This reverts commit bfe0be8a751d792aa89c2cd08bd77c0c3889c8ca. --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 90 +++++++++++++++++++++++ UefiPayloadPkg/SPI/Fvb.h | 2 +- UefiPayloadPkg/SPI/SPI.inf | 2 +- UefiPayloadPkg/SPI/pci_ops.c | 111 ++++++++++++++--------------- UefiPayloadPkg/SPI/pci_ops.h | 77 ++++++++++++++++++-- 5 files changed, 214 insertions(+), 68 deletions(-) create mode 100644 UefiPayloadPkg/SPI/BlSMMStoreDxe.h diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h new file mode 100644 index 000000000000..38fb9873be84 --- /dev/null +++ b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h @@ -0,0 +1,90 @@ +/** @file BlSMMStoreDxe.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __COREBOOT_SMM_STORE_DXE_H__ +#define __COREBOOT_SMM_STORE_DXE_H__ + + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) + +typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbWrite( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + + +#endif /* __COREBOOT_SMM_STORE_DXE_H__ */ diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index b2957478821a..7f4b0d3c3af6 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -2,7 +2,7 @@ #define FVB_H #include -#include "SPI_fvb.h" +#include "BlSMMStoreDxe.h" #define BLOCK_SIZE 0x10000 #define PAGE_SIZE 0x100 diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index eb1fdcc4a50a..cafba872edef 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -31,7 +31,7 @@ stopwatch.h pci_devs.h pci_ops.h - pci_ops.c + # pci_ops.c Fvb.h Fvb.c spi_flash_internal.h diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index b8bc2b5e62d7..a28d799e39e8 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -1,59 +1,52 @@ -#include -#include - -#include "pci_ops.h" -#include "pci_type.h" -#include "device.h" -//#include "pci_mmio_cfg.h" -#include "pci_type.h" -#include "fch_spi_ctrl.h" - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} - -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -pci_devfn_t pcidev_bdf(CONST struct device *dev) -{ - return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -} - -static __attribute__ ((noreturn)) -VOID pcidev_die(VOID) -{ - DEBUG((EFI_D_INFO, "PCI: dev is NULL!\n", __FUNCTION__)); - while(1); -} - -pci_devfn_t pcidev_assert(CONST struct device *dev) -{ - if (!dev) - pcidev_die(); - return pcidev_bdf(dev); -} - -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -{ - return pci_s_read_config32(PCI_BDF(dev), reg); -} - -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pci_mmio_write_config32(dev, reg, value); -} - -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -{ - pci_s_write_config32(PCI_BDF(dev), reg, val); -} +// #include +// #include + +// #include "pci_ops.h" +// #include "pci_type.h" +// #include "device.h" +// #include "pci_mmio_cfg.h" + +// static __attribute__ ((__always_inline__)) inline +// UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +// { +// return pci_mmio_read_config32(dev, reg); +// } + +// static __attribute__ ((__always_inline__)) inline +// pci_devfn_t pcidev_bdf(CONST struct device *dev) +// { +// return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +// } + +// __attribute__ ((noreturn)) +// VOID pcidev_die(VOID) +// { +// die("PCI: dev is NULL!\n"); +// while(1); +// } + +// static __attribute__ ((__always_inline__)) inline +// pci_devfn_t pcidev_assert(CONST struct device *dev) +// { +// if (!dev) +// pcidev_die(); +// return pcidev_bdf(dev); +// } + +// static __attribute__ ((__always_inline__)) inline +// UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +// { +// return pci_s_read_config32(PCI_BDF(dev), reg); +// } + +// static __attribute__ ((__always_inline__)) inline +// VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +// { +// pci_mmio_write_config32(dev, reg, value); +// } + +// static __attribute__ ((__always_inline__)) inline +// VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) +// { +// pci_s_write_config32(PCI_BDF(dev), reg, val); +// } diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index 69c8ba7e08cd..cd9d896f9f93 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -1,15 +1,78 @@ #ifndef PCI_OPS_H #define PCI_OPS_H +// #include +// #include "device.h" +// #include "pci_type.h" + #include -#include "device.h" +#include + +#include "pci_ops.h" #include "pci_type.h" +#include "device.h" +#include "pci_mmio_cfg.h" +#include "fch_spi_util.h" +#include "fch_spi_ctrl.h" + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +static __attribute__ ((__always_inline__)) inline +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; +} + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +static __attribute__ ((__always_inline__)) inline +pci_devfn_t pcidev_bdf(CONST struct device *dev) +{ + return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +} + +// __attribute__ ((noreturn)) +// VOID pcidev_die(VOID) +// { +// //die("PCI: dev is NULL!\n"); +// DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); +// while(1); +// } + +static __attribute__ ((__always_inline__)) inline +pci_devfn_t pcidev_assert(CONST struct device *dev) +{ + if (!dev) { + DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); + } + return pcidev_bdf(dev); +} + +static __attribute__ ((__always_inline__)) inline +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +{ + return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); + //return pci_s_read_config32(PCI_BDF(dev), reg); +} + +static __attribute__ ((__always_inline__)) inline +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pci_mmio_write_config32(dev, reg, value); +} -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); -pci_devfn_t pcidev_bdf(CONST struct device *dev); -pci_devfn_t pcidev_assert(CONST struct device *dev); -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val); +static __attribute__ ((__always_inline__)) inline +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) +{ + pci_s_write_config32(PCI_BDF(dev), reg, val); +} #endif /* PCI_OPS_H */ From d2715b71adbd8c3e13b716c484837ee4cf8c63df Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 16 Oct 2020 13:07:50 +0200 Subject: [PATCH 260/297] UefiPayloadPkg/SPI*: cleanup the code --- UefiPayloadPkg/SPI/BlSMMStoreDxe.h | 90 ---- .../SPI/{fch_spi_ctrl.c => FchSPICtrl.c} | 68 +-- .../SPI/{fch_spi_ctrl.h => FchSPICtrl.h} | 10 +- .../SPI/{fch_spi_util.c => FchSPIUtil.c} | 8 +- .../SPI/{fch_spi_util.h => FchSPIUtil.h} | 1 - UefiPayloadPkg/SPI/Fvb.c | 16 +- UefiPayloadPkg/SPI/Fvb.h | 2 +- .../SPI/{SPIgeneric.c => GenericSPI.c} | 2 +- .../SPI/{SPIgeneric.h => GenericSPI.h} | 0 UefiPayloadPkg/SPI/SPI.inf | 21 +- UefiPayloadPkg/SPI/SPI_fvb.c | 84 ++- UefiPayloadPkg/SPI/SPI_fvb.h | 66 +-- UefiPayloadPkg/SPI/device.h | 9 - UefiPayloadPkg/SPI/kconfig.h | 20 - UefiPayloadPkg/SPI/pci_devs.h | 120 ----- UefiPayloadPkg/SPI/pci_mmio_cfg.h | 50 -- UefiPayloadPkg/SPI/pci_ops.c | 90 ++-- UefiPayloadPkg/SPI/pci_ops.h | 75 +-- UefiPayloadPkg/SPI/region.c | 498 ------------------ UefiPayloadPkg/SPI/region.h | 288 ---------- UefiPayloadPkg/SPI/spi_flash_internal.c | 130 ++--- UefiPayloadPkg/SPI/stopwatch.h | 14 +- UefiPayloadPkg/SPI/utils.h | 12 - UefiPayloadPkg/SPI/winbond.c | 2 +- 24 files changed, 231 insertions(+), 1445 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/BlSMMStoreDxe.h rename UefiPayloadPkg/SPI/{fch_spi_ctrl.c => FchSPICtrl.c} (70%) rename UefiPayloadPkg/SPI/{fch_spi_ctrl.h => FchSPICtrl.h} (88%) rename UefiPayloadPkg/SPI/{fch_spi_util.c => FchSPIUtil.c} (92%) rename UefiPayloadPkg/SPI/{fch_spi_util.h => FchSPIUtil.h} (94%) rename UefiPayloadPkg/SPI/{SPIgeneric.c => GenericSPI.c} (99%) rename UefiPayloadPkg/SPI/{SPIgeneric.h => GenericSPI.h} (100%) delete mode 100644 UefiPayloadPkg/SPI/kconfig.h delete mode 100644 UefiPayloadPkg/SPI/pci_devs.h delete mode 100644 UefiPayloadPkg/SPI/pci_mmio_cfg.h delete mode 100644 UefiPayloadPkg/SPI/region.c delete mode 100644 UefiPayloadPkg/SPI/region.h delete mode 100644 UefiPayloadPkg/SPI/utils.h diff --git a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h b/UefiPayloadPkg/SPI/BlSMMStoreDxe.h deleted file mode 100644 index 38fb9873be84..000000000000 --- a/UefiPayloadPkg/SPI/BlSMMStoreDxe.h +++ /dev/null @@ -1,90 +0,0 @@ -/** @file BlSMMStoreDxe.h - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __COREBOOT_SMM_STORE_DXE_H__ -#define __COREBOOT_SMM_STORE_DXE_H__ - - -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') -#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) - -typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; - -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbGetBlockSize( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbRead( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbWrite( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbEraseBlocks( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ); - - -#endif /* __COREBOOT_SMM_STORE_DXE_H__ */ diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.c b/UefiPayloadPkg/SPI/FchSPICtrl.c similarity index 70% rename from UefiPayloadPkg/SPI/fch_spi_ctrl.c rename to UefiPayloadPkg/SPI/FchSPICtrl.c index d418033ba414..912807669751 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.c +++ b/UefiPayloadPkg/SPI/FchSPICtrl.c @@ -1,13 +1,10 @@ #include #include +#include #include "SPI.h" -#include "kconfig.h" -#include "utils.h" -#include "stopwatch.h" -#include "fch_spi_util.h" -#include "SPIgeneric.h" -#include "pci_devs.h" +#include "FchSPIUtil.h" +#include "GenericSPI.h" #include "pci_ops.h" #include "spi_flash_internal.h" @@ -37,61 +34,38 @@ #define ROM_PROTECT_RANGE0 0x50 #define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) -VOID dump_state(CONST char *str, UINT8 phase) -{ - UINT8 dump_size; - UINT32 addr; - - if (!CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)) - return; - DEBUG((EFI_D_INFO, "%a: SPI: %s\n", __FUNCTION__, str)); - DEBUG((EFI_D_INFO, "%a: Cntrl0: %x\n", __FUNCTION__, spi_read32(SPI_CNTRL0))); - DEBUG((EFI_D_INFO, "%a: Status: %x\n", __FUNCTION__, spi_read32(SPI_STATUS))); - - addr = spi_get_bar() + SPI_FIFO; - if (phase == 0) { - dump_size = spi_read8(SPI_TX_BYTE_COUNT); - DEBUG((EFI_D_INFO, "%a: TxByteCount: %x\n", __FUNCTION__, dump_size)); - DEBUG((EFI_D_INFO, "%a: CmdCode: %x\n", __FUNCTION__, spi_read8(SPI_CMD_CODE))); - } else { - dump_size = spi_read8(SPI_RX_BYTE_COUNT); - DEBUG((EFI_D_INFO, "%a: RxByteCount: %x\n", __FUNCTION__, dump_size)); - addr += spi_read8(SPI_TX_BYTE_COUNT); - } +#define PCU_DEV 0x14 +#define LPC_FUNC 3 +#define _SOC_DEV(slot, func) PCI_DEV(0, slot, func) +#define SOC_LPC_DEV _SOC_DEV(PCU_DEV, LPC_FUNC) - if (dump_size > 0) { - //hexdump((VOID *)addr, dump_size); - DEBUG((EFI_D_INFO, "%a: HEXDUMPING NOT IMPLEMENTED: %x\n", __FUNCTION__, dump_size)); - } -} - -int wait_for_ready(VOID) +static int wait_for_ready(VOID) { - CONST UINT32 timeout_ms = 500; - struct stopwatch sw; - - stopwatch_init_msecs_expire(&sw, timeout_ms); + CONST UINT64 timeoutMilisecond = 500; + CONST UINT64 nanoToMiliDivider = 1000000; + CONST UINT64 startTimeMilisec = + GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; + CONST UINT64 endTimeMilisec = startTimeMilisec + timeoutMilisecond; + UINT64 timeNow = startTimeMilisec; do { if (!(spi_read32(SPI_STATUS) & SPI_BUSY)) return 0; - } while (!stopwatch_expired(&sw)); + timeNow = GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; + } while ( + timeNowstartTimeMilisec && timeNow>endTimeMilisec)); return -1; } int execute_command(VOID) { - dump_state("Before execute", 0); - spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE); - - if (wait_for_ready()) + if(wait_for_ready()) DEBUG((EFI_D_INFO, "%a: FCH_SC Error: Timeout executing command\n", __FUNCTION__)); - dump_state("Transaction finished", 1); - return 0; } @@ -108,10 +82,6 @@ int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, UINT8 *bufin = din; CONST UINT8 *bufout = dout; - if (CONFIG(SOC_AMD_COMMON_BLOCK_SPI_DEBUG)) - DEBUG((EFI_D_INFO, "%a(%zx, %zx)\n", __FUNCTION__, bytesout, - bytesin)); - /* First byte is cmd which cannot be sent through FIFO */ cmd = bufout[0]; bufout++; diff --git a/UefiPayloadPkg/SPI/fch_spi_ctrl.h b/UefiPayloadPkg/SPI/FchSPICtrl.h similarity index 88% rename from UefiPayloadPkg/SPI/fch_spi_ctrl.h rename to UefiPayloadPkg/SPI/FchSPICtrl.h index acfd99dd4559..db11667deff4 100644 --- a/UefiPayloadPkg/SPI/fch_spi_ctrl.h +++ b/UefiPayloadPkg/SPI/FchSPICtrl.h @@ -2,12 +2,8 @@ #define FCH_SPI_CTRL_H #include - -#include "kconfig.h" -#include "utils.h" -#include "stopwatch.h" -#include "fch_spi_util.h" -#include "SPIgeneric.h" +#include "pci_type.h" +#include "GenericSPI.h" union pci_bank { UINT8 reg8[4096]; @@ -16,8 +12,6 @@ union pci_bank { }; union pci_bank *pcicfg(pci_devfn_t dev); -VOID dump_state(CONST char *str, UINT8 phase); -int wait_for_ready(VOID); int execute_command(VOID); VOID spi_init(VOID); int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, diff --git a/UefiPayloadPkg/SPI/fch_spi_util.c b/UefiPayloadPkg/SPI/FchSPIUtil.c similarity index 92% rename from UefiPayloadPkg/SPI/fch_spi_util.c rename to UefiPayloadPkg/SPI/FchSPIUtil.c index c637f28983f1..cabf89aaf2c1 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.c +++ b/UefiPayloadPkg/SPI/FchSPIUtil.c @@ -1,19 +1,17 @@ /* SPDX-License-Identifier: GPL-2.0-only */ #include -#include "fch_spi_util.h" -#include "utils.h" +#include "FchSPIUtil.h" #include #include #include -#include "fch_spi_ctrl.h" -#include "pci_mmio_cfg.h" -#include "device.h" +#include "FchSPICtrl.h" #include "pci_ops.h" #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) #define SPIROM_BASE_ADDRESS_REGISTER 0xa0 #define SPI_BASE_ALIGNMENT 0x00000040 +#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) static UINTN spi_base = 0; diff --git a/UefiPayloadPkg/SPI/fch_spi_util.h b/UefiPayloadPkg/SPI/FchSPIUtil.h similarity index 94% rename from UefiPayloadPkg/SPI/fch_spi_util.h rename to UefiPayloadPkg/SPI/FchSPIUtil.h index ae8ee335c907..b12408008797 100644 --- a/UefiPayloadPkg/SPI/fch_spi_util.h +++ b/UefiPayloadPkg/SPI/FchSPIUtil.h @@ -2,7 +2,6 @@ #define FCH_SPI_UTIL_H #include -#include "pci_type.h" UINTN lpc_get_spibase(VOID); VOID spi_set_base(UINTN base); diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index daed8e0d27f8..fb5830e9a437 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -2,7 +2,7 @@ #include #include "Fvb.h" #include "SPI_fvb.h" -#include "SPIgeneric.h" +#include "GenericSPI.h" #include "spi_flash_internal.h" #include "spi_winbond.h" #include "SPI.h" @@ -442,6 +442,20 @@ FvbGetPhysicalAddress ( { return EFI_UNSUPPORTED; } +// EFI_STATUS +// EFIAPI +// FvbGetPhysicalAddress ( +// IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, +// OUT EFI_PHYSICAL_ADDRESS *Address +// ) +// { +// DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); +// ASSERT(Address != NULL); + +// *Address = mFlashNvStorageVariableBase; +// return EFI_SUCCESS; +// } + /** The GetBlockSize() function retrieves the size of the requested diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index 7f4b0d3c3af6..b2957478821a 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -2,7 +2,7 @@ #define FVB_H #include -#include "BlSMMStoreDxe.h" +#include "SPI_fvb.h" #define BLOCK_SIZE 0x10000 #define PAGE_SIZE 0x100 diff --git a/UefiPayloadPkg/SPI/SPIgeneric.c b/UefiPayloadPkg/SPI/GenericSPI.c similarity index 99% rename from UefiPayloadPkg/SPI/SPIgeneric.c rename to UefiPayloadPkg/SPI/GenericSPI.c index 9c0373167684..6debdafb2b3b 100644 --- a/UefiPayloadPkg/SPI/SPIgeneric.c +++ b/UefiPayloadPkg/SPI/GenericSPI.c @@ -3,7 +3,7 @@ #include #include #include -#include "SPIgeneric.h" +#include "GenericSPI.h" UINT32 spi_claim_bus(CONST struct spi_slave *slave) { diff --git a/UefiPayloadPkg/SPI/SPIgeneric.h b/UefiPayloadPkg/SPI/GenericSPI.h similarity index 100% rename from UefiPayloadPkg/SPI/SPIgeneric.h rename to UefiPayloadPkg/SPI/GenericSPI.h diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index cafba872edef..1009444b1c38 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -17,21 +17,19 @@ [Sources] SPI.h - SPIgeneric.h - SPIgeneric.c + GenericSPI.h + GenericSPI.c pci_type.h device.h - kconfig.h - fch_spi_ctrl.h - fch_spi_ctrl.c + FchSPICtrl.h + FchSPICtrl.c SPI_fvb.h SPI_fvb.c - fch_spi_util.h - fch_spi_util.c + FchSPIUtil.h + FchSPIUtil.c stopwatch.h - pci_devs.h pci_ops.h - # pci_ops.c + pci_ops.c Fvb.h Fvb.c spi_flash_internal.h @@ -44,9 +42,10 @@ UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] - UefiDriverEntryPoint - DebugLib BaseMemoryLib + DebugLib + TimerLib + UefiDriverEntryPoint HobLib [Guids] diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c index 5f0f062e1e1f..b6d953fbd8b9 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ b/UefiPayloadPkg/SPI/SPI_fvb.c @@ -7,36 +7,86 @@ **/ #include +#include +#include +#include +#include #include +#include +#include #include -#include "fch_spi_ctrl.h" +#include "FchSPICtrl.h" +#include "GenericSPI.h" #include "Fvb.h" +#include "spi_flash_internal.h" +EFI_HANDLE Handle = NULL; EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - NULL, // GetAttributes - NULL, // SetAttributes - NULL, // GetPhysicalAddress + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks - NULL // ParentHandle + FvbRead, // Read + FvbWrite,// FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL }; -EFI_STATUS EFIAPI SPIInitialize( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable +EFI_STATUS checkBusyBit(UINT8 *Busy); + +EFI_STATUS EFIAPI SPIInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; - Status = gBS->InstallMultipleProtocolInterfaces( - NULL, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); + struct spi_slave slave; + DEBUG((EFI_D_INFO, "SPI IS HERE\n")); + + DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); + DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL + ); if(EFI_ERROR (Status)) { DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; } spi_init(); + DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); + unsigned char fill[300] = {}; + UINTN length = 30; + FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); + DEBUG((EFI_D_INFO, "TRIALS\n")); + for(int i = 0; i < 10; i++) { + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); + } + DEBUG((EFI_D_INFO, "ERASING\n")); + FvbEraseBlocks(&FvbProtocol, 0, 2, 4, 5, EFI_LBA_LIST_TERMINATOR); + FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); + for(int i = 0; i < 10; i++) { + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); + } + DEBUG((EFI_D_INFO, "WRITING\n")); + UINT8 toWrite[] = {01, 0x01, 0x01, 0x77}; + UINTN writeLen = 4; + EFI_STATUS status = FvbWrite(&FvbProtocol, 0, 1, &writeLen, toWrite); + DEBUG((EFI_D_INFO, "Written: 0x%X\n", writeLen)); + if(status == EFI_SUCCESS) { + DEBUG((EFI_D_INFO, "EFI_SUCCESS\n")); + } else if(status == EFI_BAD_BUFFER_SIZE) { + DEBUG((EFI_D_INFO, "EFI_BAD_BUFFER_SIZE\n")); + } else if(status == EFI_ACCESS_DENIED) { + DEBUG((EFI_D_INFO, "EFI_ACCESS_DENIED\n")); + } else { + DEBUG((EFI_D_INFO, "It's really bad\n")); + } + unsigned char newFill[300] = {}; + UINTN newLength = 30; + FvbRead(&FvbProtocol, 0, 0, &newLength, (VOID *)newFill); + for(int i = 0; i < 10; i++) { + DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)newFill[i])); + } + while(TRUE); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI_fvb.h b/UefiPayloadPkg/SPI/SPI_fvb.h index 94264dfd94da..77410a9bf10c 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.h +++ b/UefiPayloadPkg/SPI/SPI_fvb.h @@ -12,22 +12,15 @@ #include #include - #include - #include #include #include - #include #include #include #include - -#include "SPIgeneric.h" - -#define SMMSTORE_SIGNATURE SIGNATURE_32('S', 'M', 'M', 'S') -#define INSTANCE_FROM_FVB_THIS(a) CR(a, SMMSTORE_INSTANCE, FvbProtocol, SMMSTORE_SIGNATURE) +#include "GenericSPI.h" typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; @@ -100,61 +93,4 @@ struct spi_flash_protection_ops { }; -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbGetBlockSize( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbRead( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbWrite( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbEraseBlocks( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ); - #endif /* __SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/device.h b/UefiPayloadPkg/SPI/device.h index 69f24d8294ad..168bde6b0d37 100644 --- a/UefiPayloadPkg/SPI/device.h +++ b/UefiPayloadPkg/SPI/device.h @@ -3,7 +3,6 @@ #include #include "path.h" -#include "kconfig.h" struct bus { @@ -70,18 +69,10 @@ struct device { */ struct bus *link_list; -#if !DEVTREE_EARLY struct pci_irq_info pci_irq_info[4]; struct device_operations *ops; struct chip_operations *chip_ops; const char *name; -#if CONFIG(GENERATE_SMBIOS_TABLES) - UINT8 smbios_slot_type; - UINT8 smbios_slot_data_width; - UINT8 smbios_slot_length; - const char *smbios_slot_designation; -#endif -#endif void *chip_info; /* Zero-terminated array of fields and options to probe. */ diff --git a/UefiPayloadPkg/SPI/kconfig.h b/UefiPayloadPkg/SPI/kconfig.h deleted file mode 100644 index a296d5aaaf60..000000000000 --- a/UefiPayloadPkg/SPI/kconfig.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __KCONFIG_H__ -#define __KCONFIG_H__ - -/* - * Getting something that works in C and CPP for an arg that may or may - * not be defined is tricky. Here, if we have "#define CONFIG_BOOGER 1" - * we match on the placeholder define, insert the "0," for arg1 and generate - * the triplet (0, 1, 0). Then the last step cherry picks the 2nd arg (a one). - * When CONFIG_BOOGER is not defined, we generate a (... 1, 0) pair, and when - * the last step cherry picks the 2nd arg, we get a zero. - */ -#define __ARG_PLACEHOLDER_1 0, -#define config_enabled(cfg) _config_enabled(cfg) -#define _config_enabled(value) __config_enabled(__ARG_PLACEHOLDER_##value) -#define __config_enabled(arg1_or_junk) ___config_enabled(arg1_or_junk 1, 0, 0) -#define ___config_enabled(__ignored, val, ...) val - -#define CONFIG(option) config_enabled(CONFIG_##option) - -#endif diff --git a/UefiPayloadPkg/SPI/pci_devs.h b/UefiPayloadPkg/SPI/pci_devs.h deleted file mode 100644 index 75d54c86cd3e..000000000000 --- a/UefiPayloadPkg/SPI/pci_devs.h +++ /dev/null @@ -1,120 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef PCI_DEV_H -#define PCI_DEV_H - -#define _SOC_DEV(slot, func) PCI_DEV(0, slot, func) - -/* GNB Root Complex */ -#define GNB_DEV 0x0 -#define GNB_FUNC 0 -#define GNB_DEVFN PCI_DEVFN(GNB_DEV, GNB_FUNC) -#define SOC_GNB_DEV _SOC_DEV(GNB_DEV, GNB_FUNC) - -/* IOMMU */ -#define IOMMU_DEV 0x0 -#define IOMMU_FUNC 2 -#define IOMMU_DEVFN PCI_DEVFN(IOMMU_DEV, IOMMU_FUNC) -#define SOC_IOMMU_DEV _SOC_DEV(IOMMU_DEV, IOMMU_FUNC) - -/* PCIe GPP Bridges 0 - 6 */ -#define PCIE_HOST_BRIDGE_06_DEV 0x1 - -#define PCIE_GPP_0_FUNC 1 -#define PCIE_GPP_0_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_0_FUNC) -#define SOC_GPP_0_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_0_FUNC) - -#define PCIE_GPP_1_FUNC 2 -#define PCIE_GPP_1_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_1_FUNC) -#define SOC_GPP_1_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_1_FUNC) - -#define PCIE_GPP_2_FUNC 3 -#define PCIE_GPP_2_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_2_FUNC) -#define SOC_GPP_2_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_2_FUNC) - -#define PCIE_GPP_3_FUNC 4 -#define PCIE_GPP_3_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_3_FUNC) -#define SOC_GPP_3_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_3_FUNC) - -#define PCIE_GPP_4_FUNC 5 -#define PCIE_GPP_4_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_4_FUNC) -#define SOC_GPP_4_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_4_FUNC) - -#define PCIE_GPP_5_FUNC 6 -#define PCIE_GPP_5_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_5_FUNC) -#define SOC_GPP_5_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_5_FUNC) - -#define PCIE_GPP_6_FUNC 7 -#define PCIE_GPP_6_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_6_FUNC) -#define SOC_GPP_6_DEV _SOC_DEV(PCIE_HOST_BRIDGE_06_DEV, PCIE_GPP_6_FUNC) - -/* PCIe GPP Bridges to Bus A and Bus B devices */ -#define PCIE_HOST_BRIDGE_AB_DEV 0x8 - -#define PCIE_GPP_A_FUNC 1 -#define PCIE_GPP_A_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_A_FUNC) -#define SOC_PCIE_GPP_A_DEV _SOC_DEV(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_A_FUNC) -#define GFX_DEV 0x0 -#define GFX_FUNC 0 -#define GFX_DEVFN PCI_DEVFN(GFX_DEV, GFX_FUNC) - -#define XHCI0_DEV 0x0 -#define XHCI0_FUNC 3 -#define XHCI0_DEVFN PCI_DEVFN(XHCI0_DEV, XHCI0_FUNC) - -#define XHCI1_DEV 0x0 -#define XHCI1_FUNC 4 -#define XHCI1_DEVFN PCI_DEVFN(XHCI1_DEV, XHCI1_FUNC) - -#define AUDIO_DEV 0x0 -#define AUDIO_FUNC 5 -#define AUDIO_DEVFN PCI_DEVFN(AUDIO_DEV, AUDIO_FUNC) - -#define HD_AUDIO_DEV 0x0 -#define HD_AUDIO_FUNC 6 -#define HD_AUDIO_DEVFN PCI_DEVFN(HD_AUDIO_DEV, HD_AUDIO_FUNC) - -#define PCIE_GPP_B_FUNC 2 -#define PCIE_GPP_B_DEVFN PCI_DEVFN(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_B_FUNC) -#define SOC_PCIE_GPP_B_DEV _SOC_DEV(PCIE_HOST_BRIDGE_AB_DEV, PCIE_GPP_B_FUNC) -#define SATA_DEV 0x0 -#define SATA_FUNC 0 -#define SATA_DEVFN PCI_DEVFN(SATA_DEV, SATA_FUNC) - -/* Data Fabric functions */ -#define DF_DEV 0x18 - -#define DF_F0_DEVFN PCI_DEVFN(DF_DEV, 0) -#define SOC_DF_F0_DEV _SOC_DEV(DF_DEV, 0) - -#define DF_F1_DEVFN PCI_DEVFN(DF_DEV, 1) -#define SOC_DF_F1_DEV _SOC_DEV(DF_DEV, 1) - -#define DF_F2_DEVFN PCI_DEVFN(DF_DEV, 2) -#define SOC_DF_F2_DEV _SOC_DEV(DF_DEV, 2) - -#define DF_F3_DEVFN PCI_DEVFN(DF_DEV, 3) -#define SOC_DF_F3_DEV _SOC_DEV(DF_DEV, 3) - -#define DF_F4_DEVFN PCI_DEVFN(DF_DEV, 4) -#define SOC_DF_F4_DEV _SOC_DEV(DF_DEV, 4) - -#define DF_F5_DEVFN PCI_DEVFN(DF_DEV, 5) -#define SOC_DF_F5_DEV _SOC_DEV(DF_DEV, 5) - -#define DF_F6_DEVFN PCI_DEVFN(DF_DEV, 6) -#define SOC_DF_F6_DEV _SOC_DEV(DF_DEV, 6) - -/* SMBUS */ -#define SMBUS_DEV 0x14 -#define SMBUS_FUNC 0 -#define SMBUS_DEVFN PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC) -#define SOC_SMBUS_DEV _SOC_DEV(SMBUS_DEV, SMBUS_FUNC) - -/* LPC BUS */ -#define PCU_DEV 0x14 -#define LPC_FUNC 3 -#define LPC_DEVFN PCI_DEVFN(PCU_DEV, LPC_FUNC) -#define SOC_LPC_DEV _SOC_DEV(PCU_DEV, LPC_FUNC) - -#endif /* PCI_DEV_H */ diff --git a/UefiPayloadPkg/SPI/pci_mmio_cfg.h b/UefiPayloadPkg/SPI/pci_mmio_cfg.h deleted file mode 100644 index cdb34f6d59d6..000000000000 --- a/UefiPayloadPkg/SPI/pci_mmio_cfg.h +++ /dev/null @@ -1,50 +0,0 @@ -// #ifndef PCI_MMIO_CFG_H -// #define PCI_MMIO_CFG_H - -// #include -// #include -// #include "pci_type.h" - -// /* By not assigning this to CONFIG_MMCONF_BASE_ADDRESS here we -// * prevent some sub-optimal constant folding. */ -// //UINT8 *const pci_mmconf = (VOID *)(unsigned long int)0xBAADF00D; //CONFIG_MMCONF_BASE_ADDRESS; -// //extern UINT8 *const pci_mmconf; - -// /* Using a unique datatype for MMIO writes makes the pointers to _not_ -// * qualify for pointer aliasing with any other objects in memory. -// * -// * MMIO offset is a value originally derived from 'struct device *' -// * in ramstage. For the compiler to not discard this MMIO offset value -// * from CPU registers after any MMIO writes, -fstrict-aliasing has to -// * be also set for the build. -// * -// * Bottom 12 bits (4 KiB) are reserved to address the registers of a -// * single PCI function. Declare the bank as a union to avoid some casting -// * in the functions below. -// */ -// union pci_bank { -// UINT8 reg8[4096]; -// UINT16 reg16[4096 / sizeof(UINT16)]; -// UINT32 reg32[4096 / sizeof(UINT32)]; -// }; - -// static __attribute__ ((__always_inline__)) inline -// volatile union pci_bank *pcicfg(pci_devfn_t dev) -// { -// UINT8 *const spi_bar = (VOID *)(unsigned long int)0xF8000000; -// return (void *)&spi_bar[PCI_DEVFN_OFFSET(dev)]; -// } - -// static __attribute__ ((__always_inline__)) inline -// UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -// { -// return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -// } - -// static __attribute__ ((__always_inline__)) inline -// void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -// { -// pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -// } - -// #endif /* PCI_MMIO_CFG_H */ diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c index a28d799e39e8..8d3b01460ac1 100644 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ b/UefiPayloadPkg/SPI/pci_ops.c @@ -1,52 +1,64 @@ -// #include -// #include +#ifndef PCI_OPS_H +#define PCI_OPS_H -// #include "pci_ops.h" -// #include "pci_type.h" -// #include "device.h" -// #include "pci_mmio_cfg.h" +#include +#include -// static __attribute__ ((__always_inline__)) inline -// UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -// { -// return pci_mmio_read_config32(dev, reg); -// } +#include "pci_type.h" +#include "device.h" +#include "FchSPIUtil.h" +#include "FchSPICtrl.h" -// static __attribute__ ((__always_inline__)) inline -// pci_devfn_t pcidev_bdf(CONST struct device *dev) -// { -// return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -// } +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; +} + +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; +} + +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) +{ + return pci_mmio_read_config32(dev, reg); +} + +pci_devfn_t pcidev_bdf(CONST struct device *dev) +{ + return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); +} // __attribute__ ((noreturn)) // VOID pcidev_die(VOID) // { -// die("PCI: dev is NULL!\n"); +// //die("PCI: dev is NULL!\n"); +// DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); // while(1); // } -// static __attribute__ ((__always_inline__)) inline -// pci_devfn_t pcidev_assert(CONST struct device *dev) -// { -// if (!dev) -// pcidev_die(); -// return pcidev_bdf(dev); -// } +pci_devfn_t pcidev_assert(CONST struct device *dev) +{ + if (!dev) { + DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); + } + return pcidev_bdf(dev); +} -// static __attribute__ ((__always_inline__)) inline -// UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -// { -// return pci_s_read_config32(PCI_BDF(dev), reg); -// } +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) +{ + return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); + //return pci_s_read_config32(PCI_BDF(dev), reg); +} -// static __attribute__ ((__always_inline__)) inline -// VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -// { -// pci_mmio_write_config32(dev, reg, value); -// } +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) +{ + pci_mmio_write_config32(dev, reg, value); +} -// static __attribute__ ((__always_inline__)) inline -// VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -// { -// pci_s_write_config32(PCI_BDF(dev), reg, val); -// } +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) +{ + pci_s_write_config32(PCI_BDF(dev), reg, val); +} + +#endif /* PCI_OPS_H */ diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h index cd9d896f9f93..6a451fa5be10 100644 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ b/UefiPayloadPkg/SPI/pci_ops.h @@ -1,78 +1,19 @@ #ifndef PCI_OPS_H #define PCI_OPS_H -// #include -// #include "device.h" -// #include "pci_type.h" - #include #include -#include "pci_ops.h" #include "pci_type.h" #include "device.h" -#include "pci_mmio_cfg.h" -#include "fch_spi_util.h" -#include "fch_spi_ctrl.h" - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -static __attribute__ ((__always_inline__)) inline -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_bdf(CONST struct device *dev) -{ - return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -} - -// __attribute__ ((noreturn)) -// VOID pcidev_die(VOID) -// { -// //die("PCI: dev is NULL!\n"); -// DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); -// while(1); -// } - -static __attribute__ ((__always_inline__)) inline -pci_devfn_t pcidev_assert(CONST struct device *dev) -{ - if (!dev) { - DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); - } - return pcidev_bdf(dev); -} - -static __attribute__ ((__always_inline__)) inline -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -{ - return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); - //return pci_s_read_config32(PCI_BDF(dev), reg); -} - -static __attribute__ ((__always_inline__)) inline -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pci_mmio_write_config32(dev, reg, value); -} -static __attribute__ ((__always_inline__)) inline -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -{ - pci_s_write_config32(PCI_BDF(dev), reg, val); -} +UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg); +void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); +UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); +pci_devfn_t pcidev_bdf(CONST struct device *dev); +pci_devfn_t pcidev_assert(CONST struct device *dev); +UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); +VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); +VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val); #endif /* PCI_OPS_H */ diff --git a/UefiPayloadPkg/SPI/region.c b/UefiPayloadPkg/SPI/region.c deleted file mode 100644 index 957d12e6f1a8..000000000000 --- a/UefiPayloadPkg/SPI/region.c +++ /dev/null @@ -1,498 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#include "region.h" - -int region_is_subregion(const struct region *p, const struct region *c) -{ - if (region_offset(c) < region_offset(p)) - return 0; - - if (region_end(c) > region_end(p)) - return 0; - - if (region_end(c) < region_offset(c)) - return 0; - - return 1; -} - -static int normalize_and_ok(const struct region *outer, struct region *inner) -{ - inner->offset += region_offset(outer); - return region_is_subregion(outer, inner); -} - -static const struct region_device *rdev_root(const struct region_device *rdev) -{ - if (rdev->root == NULL) - return rdev; - return rdev->root; -} - -__SIZE_TYPE__ rdev_relative_offset(const struct region_device *p, - const struct region_device *c) -{ - if (rdev_root(p) != rdev_root(c)) - return -1; - - if (!region_is_subregion(&p->region, &c->region)) - return -1; - - return region_device_offset(c) - region_device_offset(p); -} - -void *rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - const struct region_device *rdev; - struct region req = { - .offset = offset, - .size = size, - }; - - if (!normalize_and_ok(&rd->region, &req)) - return NULL; - - rdev = rdev_root(rd); - - if (rdev->ops->mmap == NULL) - return NULL; - - return rdev->ops->mmap(rdev, req.offset, req.size); -} - -int rdev_munmap(const struct region_device *rd, void *mapping) -{ - const struct region_device *rdev; - - rdev = rdev_root(rd); - - if (rdev->ops->munmap == NULL) - return -1; - - return rdev->ops->munmap(rdev, mapping); -} - -__SIZE_TYPE__ rdev_readat(const struct region_device *rd, void *b, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - const struct region_device *rdev; - struct region req = { - .offset = offset, - .size = size, - }; - - if (!normalize_and_ok(&rd->region, &req)) - return -1; - - rdev = rdev_root(rd); - - return rdev->ops->readat(rdev, b, req.offset, req.size); -} - -__SIZE_TYPE__ rdev_writeat(const struct region_device *rd, const void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - const struct region_device *rdev; - struct region req = { - .offset = offset, - .size = size, - }; - - if (!normalize_and_ok(&rd->region, &req)) - return -1; - - rdev = rdev_root(rd); - - if (rdev->ops->writeat == NULL) - return -1; - - return rdev->ops->writeat(rdev, b, req.offset, req.size); -} - -__SIZE_TYPE__ rdev_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - const struct region_device *rdev; - struct region req = { - .offset = offset, - .size = size, - }; - - if (!normalize_and_ok(&rd->region, &req)) - return -1; - - rdev = rdev_root(rd); - - /* If the eraseat ptr is NULL we assume that the erase - * function was completed successfully. */ - if (rdev->ops->eraseat == NULL) - return size; - - return rdev->ops->eraseat(rdev, req.offset, req.size); -} - -int rdev_chain(struct region_device *child, const struct region_device *parent, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - struct region req = { - .offset = offset, - .size = size, - }; - - if (!normalize_and_ok(&parent->region, &req)) - return -1; - - /* Keep track of root region device. Note the offsets are relative - * to the root device. */ - child->root = rdev_root(parent); - child->ops = NULL; - child->region.offset = req.offset; - child->region.size = req.size; - - return 0; -} - -static void mem_region_device_init(struct mem_region_device *mdev, - const struct region_device_ops *ops, void *base, __SIZE_TYPE__ size) -{ - memset(mdev, 0, sizeof(*mdev)); - mdev->base = base; - mdev->rdev.ops = ops; - mdev->rdev.region.size = size; -} - -void mem_region_device_ro_init(struct mem_region_device *mdev, void *base, - __SIZE_TYPE__ size) -{ - return mem_region_device_init(mdev, &mem_rdev_ro_ops, base, size); -} - -void mem_region_device_rw_init(struct mem_region_device *mdev, void *base, - __SIZE_TYPE__ size) -{ - return mem_region_device_init(mdev, &mem_rdev_rw_ops, base, size); -} - -void region_device_init(struct region_device *rdev, - const struct region_device_ops *ops, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - memset(rdev, 0, sizeof(*rdev)); - rdev->root = NULL; - rdev->ops = ops; - rdev->region.offset = offset; - rdev->region.size = size; -} - -static void xlate_region_device_init(struct xlate_region_device *xdev, - const struct region_device_ops *ops, - const struct region_device *access_dev, - __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, - __SIZE_TYPE__ parent_size) -{ - memset(xdev, 0, sizeof(*xdev)); - xdev->access_dev = access_dev; - xdev->sub_region.offset = sub_offset; - xdev->sub_region.size = sub_size; - region_device_init(&xdev->rdev, ops, 0, parent_size); -} - -void xlate_region_device_ro_init(struct xlate_region_device *xdev, - const struct region_device *access_dev, - __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, - __SIZE_TYPE__ parent_size) -{ - xlate_region_device_init(xdev, &xlate_rdev_ro_ops, access_dev, - sub_offset, sub_size, parent_size); -} - -void xlate_region_device_rw_init(struct xlate_region_device *xdev, - const struct region_device *access_dev, - __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, - __SIZE_TYPE__ parent_size) -{ - xlate_region_device_init(xdev, &xlate_rdev_rw_ops, access_dev, - sub_offset, sub_size, parent_size); -} - -static void *mdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size __unused) -{ - const struct mem_region_device *mdev; - - mdev = container_of(rd, __typeof__(*mdev), rdev); - - return &mdev->base[offset]; -} - -static int mdev_munmap(const struct region_device *rd __unused, - void *mapping __unused) -{ - return 0; -} - -static __SIZE_TYPE__ mdev_readat(const struct region_device *rd, void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - const struct mem_region_device *mdev; - - mdev = container_of(rd, __typeof__(*mdev), rdev); - - memcpy(b, &mdev->base[offset], size); - - return size; -} - -static __SIZE_TYPE__ mdev_writeat(const struct region_device *rd, const void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - const struct mem_region_device *mdev; - - mdev = container_of(rd, __typeof__(*mdev), rdev); - - memcpy(&mdev->base[offset], b, size); - - return size; -} - -static __SIZE_TYPE__ mdev_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - const struct mem_region_device *mdev; - - mdev = container_of(rd, __typeof__(*mdev), rdev); - - memset(&mdev->base[offset], 0, size); - - return size; -} - -const struct region_device_ops mem_rdev_ro_ops = { - .mmap = mdev_mmap, - .munmap = mdev_munmap, - .readat = mdev_readat, -}; - -const struct region_device_ops mem_rdev_rw_ops = { - .mmap = mdev_mmap, - .munmap = mdev_munmap, - .readat = mdev_readat, - .writeat = mdev_writeat, - .eraseat = mdev_eraseat, -}; - -void mmap_helper_device_init(struct mmap_helper_region_device *mdev, - void *cache, __SIZE_TYPE__ cache_size) -{ - mem_pool_init(&mdev->pool, cache, cache_size); -} - -void *mmap_helper_rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - struct mmap_helper_region_device *mdev; - void *mapping; - - mdev = container_of((void *)rd, __typeof__(*mdev), rdev); - - mapping = mem_pool_alloc(&mdev->pool, size); - - if (mapping == NULL) - return NULL; - - if (rd->ops->readat(rd, mapping, offset, size) != size) { - mem_pool_free(&mdev->pool, mapping); - return NULL; - } - - return mapping; -} - -int mmap_helper_rdev_munmap(const struct region_device *rd, void *mapping) -{ - struct mmap_helper_region_device *mdev; - - mdev = container_of((void *)rd, __typeof__(*mdev), rdev); - - mem_pool_free(&mdev->pool, mapping); - - return 0; -} - -static void *xlate_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - const struct xlate_region_device *xldev; - struct region req = { - .offset = offset, - .size = size, - }; - - xldev = container_of(rd, __typeof__(*xldev), rdev); - - if (!region_is_subregion(&xldev->sub_region, &req)) - return NULL; - - offset -= region_offset(&xldev->sub_region); - - return rdev_mmap(xldev->access_dev, offset, size); -} - -static int xlate_munmap(const struct region_device *rd, void *mapping) -{ - const struct xlate_region_device *xldev; - - xldev = container_of(rd, __typeof__(*xldev), rdev); - - return rdev_munmap(xldev->access_dev, mapping); -} - -static __SIZE_TYPE__ xlate_readat(const struct region_device *rd, void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - struct region req = { - .offset = offset, - .size = size, - }; - const struct xlate_region_device *xldev; - - xldev = container_of(rd, __typeof__(*xldev), rdev); - - if (!region_is_subregion(&xldev->sub_region, &req)) - return -1; - - offset -= region_offset(&xldev->sub_region); - - return rdev_readat(xldev->access_dev, b, offset, size); -} - -static __SIZE_TYPE__ xlate_writeat(const struct region_device *rd, const void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - struct region req = { - .offset = offset, - .size = size, - }; - const struct xlate_region_device *xldev; - - xldev = container_of(rd, __typeof__(*xldev), rdev); - - if (!region_is_subregion(&xldev->sub_region, &req)) - return -1; - - offset -= region_offset(&xldev->sub_region); - - return rdev_writeat(xldev->access_dev, b, offset, size); -} - -static __SIZE_TYPE__ xlate_eraseat(const struct region_device *rd, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - struct region req = { - .offset = offset, - .size = size, - }; - const struct xlate_region_device *xldev; - - xldev = container_of(rd, __typeof__(*xldev), rdev); - - if (!region_is_subregion(&xldev->sub_region, &req)) - return -1; - - offset -= region_offset(&xldev->sub_region); - - return rdev_eraseat(xldev->access_dev, offset, size); -} - -const struct region_device_ops xlate_rdev_ro_ops = { - .mmap = xlate_mmap, - .munmap = xlate_munmap, - .readat = xlate_readat, -}; - -const struct region_device_ops xlate_rdev_rw_ops = { - .mmap = xlate_mmap, - .munmap = xlate_munmap, - .readat = xlate_readat, - .writeat = xlate_writeat, - .eraseat = xlate_eraseat, -}; - - -static void *incoherent_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - const struct incoherent_rdev *irdev; - - irdev = container_of(rd, const struct incoherent_rdev, rdev); - - return rdev_mmap(irdev->read, offset, size); -} - -static int incoherent_munmap(const struct region_device *rd, void *mapping) -{ - const struct incoherent_rdev *irdev; - - irdev = container_of(rd, const struct incoherent_rdev, rdev); - - return rdev_munmap(irdev->read, mapping); -} - -static __SIZE_TYPE__ incoherent_readat(const struct region_device *rd, void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - const struct incoherent_rdev *irdev; - - irdev = container_of(rd, const struct incoherent_rdev, rdev); - - return rdev_readat(irdev->read, b, offset, size); -} - -static __SIZE_TYPE__ incoherent_writeat(const struct region_device *rd, const void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size) -{ - const struct incoherent_rdev *irdev; - - irdev = container_of(rd, const struct incoherent_rdev, rdev); - - return rdev_writeat(irdev->write, b, offset, size); -} - -static __SIZE_TYPE__ incoherent_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size) -{ - const struct incoherent_rdev *irdev; - - irdev = container_of(rd, const struct incoherent_rdev, rdev); - - return rdev_eraseat(irdev->write, offset, size); -} - -static const struct region_device_ops incoherent_rdev_ops = { - .mmap = incoherent_mmap, - .munmap = incoherent_munmap, - .readat = incoherent_readat, - .writeat = incoherent_writeat, - .eraseat = incoherent_eraseat, -}; - -const struct region_device *incoherent_rdev_init(struct incoherent_rdev *irdev, - const struct region *r, - const struct region_device *read, - const struct region_device *write) -{ - const __SIZE_TYPE__ size = region_sz(r); - - if (size != region_device_sz(read) || size != region_device_sz(write)) - return NULL; - - /* The region is represented as offset 0 to size. That way, the generic - * rdev operations can be called on the read or write implementation - * without any unnecessary translation because the offsets all start - * at 0. */ - region_device_init(&irdev->rdev, &incoherent_rdev_ops, 0, size); - irdev->read = read; - irdev->write = write; - - return &irdev->rdev; -} diff --git a/UefiPayloadPkg/SPI/region.h b/UefiPayloadPkg/SPI/region.h deleted file mode 100644 index 7d20ad8ce9c5..000000000000 --- a/UefiPayloadPkg/SPI/region.h +++ /dev/null @@ -1,288 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef _REGION_H_ -#define _REGION_H_ - - -#include - -/* - * Region support. - * - * Regions are intended to abstract away the access mechanisms for blocks of - * data. This could be SPI, eMMC, or a memory region as the backing store. - * They are accessed through a region_device. Subregions can be made by - * chaining together multiple region_devices. - */ - -struct region_device; - -/* - * Returns NULL on error otherwise a buffer is returned with the contents of - * the requested data at offset of size. - */ -void *rdev_mmap(const struct region_device *rd, __SIZE_TYPE__ offset, __SIZE_TYPE__ size); - -/* Unmap a previously mapped area. Returns 0 on success, < 0 on error. */ -int rdev_munmap(const struct region_device *rd, void *mapping); - -/* - * Returns < 0 on error otherwise returns size of data read at provided - * offset filling in the buffer passed. - */ -__SIZE_TYPE__ rdev_readat(const struct region_device *rd, void *b, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size); - -/* - * Returns < 0 on error otherwise returns size of data wrote at provided - * offset from the buffer passed. - */ -__SIZE_TYPE__ rdev_writeat(const struct region_device *rd, const void *b, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size); - -/* - * Returns < 0 on error otherwise returns size of data erased. - * If eraseat ops is not defined it returns size which indicates - * that operation was successful. - */ -__SIZE_TYPE__ rdev_eraseat(const struct region_device *rd, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size); - -/**************************************** - * Implementation of a region device * - ****************************************/ - -/* - * Create a child region of the parent provided the sub-region is within - * the parent's region. Returns < 0 on error otherwise 0 on success. Note - * that the child device only calls through the parent's operations. - */ -int rdev_chain(struct region_device *child, const struct region_device *parent, - __SIZE_TYPE__ offset, __SIZE_TYPE__ size); - -/* A region_device operations. */ -struct region_device_ops { - void *(*mmap)(const struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); - int (*munmap)(const struct region_device *, void *); - __SIZE_TYPE__ (*readat)(const struct region_device *, void *, __SIZE_TYPE__, __SIZE_TYPE__); - __SIZE_TYPE__ (*writeat)(const struct region_device *, const void *, __SIZE_TYPE__, - __SIZE_TYPE__); - __SIZE_TYPE__ (*eraseat)(const struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); -}; - -struct region { - __SIZE_TYPE__ offset; - __SIZE_TYPE__ size; -}; - -struct region_device { - const struct region_device *root; - const struct region_device_ops *ops; - struct region region; -}; - -#define REGION_DEV_INIT(ops_, offset_, size_) \ - { \ - .root = NULL, \ - .ops = (ops_), \ - .region = { \ - .offset = (offset_), \ - .size = (size_), \ - }, \ - } - -/* Helper to dynamically initialize region device. */ -void region_device_init(struct region_device *rdev, - const struct region_device_ops *ops, __SIZE_TYPE__ offset, - __SIZE_TYPE__ size); - -/* Return 1 if child is subregion of parent, else 0. */ -int region_is_subregion(const struct region *p, const struct region *c); - -static inline __SIZE_TYPE__ region_offset(const struct region *r) -{ - return r->offset; -} - -static inline __SIZE_TYPE__ region_sz(const struct region *r) -{ - return r->size; -} - -static inline __SIZE_TYPE__ region_end(const struct region *r) -{ - return region_offset(r) + region_sz(r); -} - -static inline BOOLEAN region_overlap(const struct region *r1, const struct region *r2) -{ - return (region_end(r1) > region_offset(r2)) && - (region_offset(r1) < region_end(r2)); -} - -static inline const struct region *region_device_region( - const struct region_device *rdev) -{ - return &rdev->region; -} - -static inline __SIZE_TYPE__ region_device_sz(const struct region_device *rdev) -{ - return region_sz(region_device_region(rdev)); -} - -static inline __SIZE_TYPE__ region_device_offset(const struct region_device *rdev) -{ - return region_offset(region_device_region(rdev)); -} - -static inline __SIZE_TYPE__ region_device_end(const struct region_device *rdev) -{ - return region_end(region_device_region(rdev)); -} - -/* Memory map entire region device. Same semantics as rdev_mmap() above. */ -static inline void *rdev_mmap_full(const struct region_device *rd) -{ - return rdev_mmap(rd, 0, region_device_sz(rd)); -} - -static inline int rdev_chain_full(struct region_device *child, - const struct region_device *parent) -{ - /* Chain full size of parent. */ - return rdev_chain(child, parent, 0, region_device_sz(parent)); -} - -/* - * Compute relative offset of the child (c) w.r.t. the parent (p). Returns < 0 - * when child is not within the parent's region. - */ -__SIZE_TYPE__ rdev_relative_offset(const struct region_device *p, - const struct region_device *c); - -struct mem_region_device { - char *base; - struct region_device rdev; -}; - -/* Initialize at runtime a mem_region_device. This would be used when - * the base and size are dynamic or can't be known during linking. - * There are two variants: read-only and read-write. */ -void mem_region_device_ro_init(struct mem_region_device *mdev, void *base, - __SIZE_TYPE__ size); - -void mem_region_device_rw_init(struct mem_region_device *mdev, void *base, - __SIZE_TYPE__ size); - -extern const struct region_device_ops mem_rdev_ro_ops; - -extern const struct region_device_ops mem_rdev_rw_ops; - -/* Statically initialize mem_region_device. */ -#define MEM_REGION_DEV_INIT(base_, size_, ops_) \ - { \ - .base = (void *)(base_), \ - .rdev = REGION_DEV_INIT((ops_), 0, (size_)), \ - } - -#define MEM_REGION_DEV_RO_INIT(base_, size_) \ - MEM_REGION_DEV_INIT(base_, size_, &mem_rdev_ro_ops) \ - -#define MEM_REGION_DEV_RW_INIT(base_, size_) \ - MEM_REGION_DEV_INIT(base_, size_, &mem_rdev_rw_ops) \ - -struct mem_pool { - UINT8 *buf; - __SIZE_TYPE__ size; - UINT8 *last_alloc; - __SIZE_TYPE__ free_offset; -}; - -struct mmap_helper_region_device { - struct mem_pool pool; - struct region_device rdev; -}; - -#define MMAP_HELPER_REGION_INIT(ops_, offset_, size_) \ - { \ - .rdev = REGION_DEV_INIT((ops_), (offset_), (size_)), \ - } - -void mmap_helper_device_init(struct mmap_helper_region_device *mdev, - void *cache, __SIZE_TYPE__ cache_size); - -void *mmap_helper_rdev_mmap(const struct region_device *, __SIZE_TYPE__, __SIZE_TYPE__); -int mmap_helper_rdev_munmap(const struct region_device *, void *); - -/* A translated region device provides the ability to publish a region device - * in one address space and use an access mechanism within another address - * space. The sub region is the window within the 1st address space and - * the request is modified prior to accessing the second address space - * provided by access_dev. */ -struct xlate_region_device { - const struct region_device *access_dev; - struct region sub_region; - struct region_device rdev; -}; - -extern const struct region_device_ops xlate_rdev_ro_ops; - -extern const struct region_device_ops xlate_rdev_rw_ops; - -#define XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, sub_size_, \ - parent_sz_, ops_) \ - { \ - .access_dev = access_dev_, \ - .sub_region = { \ - .offset = (sub_offset_), \ - .size = (sub_size_), \ - }, \ - .rdev = REGION_DEV_INIT((ops_), 0, (parent_sz_)), \ - } - -#define XLATE_REGION_DEV_RO_INIT(access_dev_, sub_offset_, sub_size_, \ - parent_sz_) \ - XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \ - sub_size_, parent_sz_, &xlate_rdev_ro_ops), \ - -#define XLATE_REGION_DEV_RW_INIT(access_dev_, sub_offset_, sub_size_, \ - parent_sz_) \ - XLATE_REGION_DEV_INIT(access_dev_, sub_offset_, \ - sub_size_, parent_sz_, &xlate_rdev_rw_ops), \ - -/* Helper to dynamically initialize xlate region device. */ -void xlate_region_device_ro_init(struct xlate_region_device *xdev, - const struct region_device *access_dev, - __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, - __SIZE_TYPE__ parent_size); - -void xlate_region_device_rw_init(struct xlate_region_device *xdev, - const struct region_device *access_dev, - __SIZE_TYPE__ sub_offset, __SIZE_TYPE__ sub_size, - __SIZE_TYPE__ parent_size); - -/* This type can be used for incoherent access where the read and write - * operations are backed by separate drivers. An example is x86 systems - * with memory mapped media for reading but use a spi flash driver for - * writing. One needs to ensure using this object is appropriate in context. */ -struct incoherent_rdev { - struct region_device rdev; - const struct region_device *read; - const struct region_device *write; -}; - -/* Initialize an incoherent_rdev based on the region as well as the read and - * write rdevs. The read and write rdevs should match in size to the passed - * in region. If not the initialization will fail returning NULL. Otherwise - * the function will return a pointer to the containing region_device to - * be used for region operations. Therefore, the lifetime of the returned - * pointer matches the lifetime of the incoherent_rdev object. Likewise, - * the lifetime of the read and write rdev need to match the lifetime of - * the incoherent_rdev object. */ -const struct region_device *incoherent_rdev_init(struct incoherent_rdev *irdev, - const struct region *r, - const struct region_device *read, - const struct region_device *write); - -#endif /* _REGION_H_ */ diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.c b/UefiPayloadPkg/SPI/spi_flash_internal.c index 856f02bc6016..4d2cdf4db3f6 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.c +++ b/UefiPayloadPkg/SPI/spi_flash_internal.c @@ -3,11 +3,9 @@ #include #include #include +#include #include "spi_flash_internal.h" -#include "SPIgeneric.h" -#include "kconfig.h" -#include "stopwatch.h" -#include "utils.h" +#include "GenericSPI.h" #include "SPI_fvb.h" static VOID spi_flash_addr(UINT32 addr, UINT8 *cmd) @@ -119,11 +117,12 @@ int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, int ret, cmd_len; int (*do_cmd)(const struct spi_slave *spi, const VOID *din, __SIZE_TYPE__ in_bytes, VOID *out, __SIZE_TYPE__ out_bytes); - if (CONFIG(SPI_FLASH_NO_FAST_READ)) { +#ifdef SPI_FLASH_NO_FAST_READ cmd_len = 4; cmd[0] = CMD_READ_ARRAY_SLOW; do_cmd = do_spi_flash_cmd; - } else if (flash->flags.dual_spi && flash->spi.ctrlr->xfer_dual) { +#else + if (flash->flags.dual_spi && flash->spi.ctrlr->xfer_dual) { cmd_len = 5; cmd[0] = CMD_READ_FAST_DUAL_OUTPUT; cmd[4] = 0; @@ -134,6 +133,7 @@ int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, cmd[4] = 0; do_cmd = do_spi_flash_cmd; } +#endif UINT8 *data = buf; while (len) { @@ -160,11 +160,12 @@ int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, const struct spi_slave *spi = &flash->spi; int ret; UINT8 status; - struct mono_time current, end; - timer_monotonic_get(¤t); - end = current; - mono_time_add_msecs(&end, timeout); + CONST UINT64 nanoToMiliDivider = 1000000; + CONST UINT64 startTimeMilisec = + GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; + CONST UINT64 endTimeMilisec = startTimeMilisec + timeout; + UINT64 timeNow = startTimeMilisec; do { ret = do_spi_flash_cmd(spi, &cmd, 1, &status, 1); @@ -172,8 +173,10 @@ int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, return -1; if ((status & poll_bit) == 0) return 0; - timer_monotonic_get(¤t); - } while (!mono_time_after(¤t, &end)); + timeNow = GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; + } while ( + timeNowstartTimeMilisec && timeNow>endTimeMilisec)); DEBUG((EFI_D_INFO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); return -1; @@ -210,7 +213,7 @@ int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYP spi_flash_addr(offset, cmd); offset += erase_size; -#if CONFIG(DEBUG_SPI_FLASH) +#ifdef DEBUG_SPI_FLASH DEBUG((EFI_D_INFO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION, cmd[0], cmd[1], cmd[2], cmd[3], offset)); #endif @@ -259,11 +262,11 @@ int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offse chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len); spi_flash_addr(offset, cmd); - if (CONFIG(DEBUG_SPI_FLASH)) { +#ifdef DEBUG_SPI_FLASH DEBUG((EFI_D_INFO, "%a PP: %p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len)); - } +#endif ret = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0); if (ret < 0) { @@ -284,11 +287,6 @@ int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offse offset += chunk_len; } - - if (CONFIG(DEBUG_SPI_FLASH)) { - DEBUG((EFI_D_INFO, "%a SF: : Successfully programmed %zu bytes @ 0x%lx\n", - __FUNCTION__, len, (unsigned long)(offset - len))); - } ret = 0; out: @@ -296,40 +294,40 @@ int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offse } static const struct spi_flash_vendor_info *spi_flash_vendors[] = { -#if CONFIG(SPI_FLASH_ADESTO) +#ifdef SPI_FLASH_ADESTO &spi_flash_adesto_vi, #endif -#if CONFIG(SPI_FLASH_AMIC) +#ifdef SPI_FLASH_AMIC &spi_flash_amic_vi, #endif -#if CONFIG(SPI_FLASH_ATMEL) +#ifdef SPI_FLASH_ATMEL &spi_flash_atmel_vi, #endif -#if CONFIG(SPI_FLASH_EON) +#ifdef SPI_FLASH_EON &spi_flash_eon_vi, #endif -#if CONFIG(SPI_FLASH_GIGADEVICE) +#ifdef SPI_FLASH_GIGADEVICE &spi_flash_gigadevice_vi, #endif -#if CONFIG(SPI_FLASH_MACRONIX) +#ifdef SPI_FLASH_MACRONIX &spi_flash_macronix_vi, #endif -#if CONFIG(SPI_FLASH_SPANSION) +#ifdef SPI_FLASH_SPANSION &spi_flash_spansion_ext1_vi, &spi_flash_spansion_ext2_vi, &spi_flash_spansion_vi, #endif -#if CONFIG(SPI_FLASH_SST) +#ifdef SPI_FLASH_SST &spi_flash_sst_ai_vi, &spi_flash_sst_vi, #endif -#if CONFIG(SPI_FLASH_STMICRO) +#ifdef SPI_FLASH_STMICRO &spi_flash_stmicro1_vi, &spi_flash_stmicro2_vi, &spi_flash_stmicro3_vi, &spi_flash_stmicro4_vi, #endif -#if CONFIG(SPI_FLASH_WINBOND) +#ifdef SPI_FLASH_WINBOND &spi_flash_winbond_vi, #endif }; @@ -344,7 +342,7 @@ static int fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash, flash->model = part->id[0]; flash->page_size = 1U << vi->page_size_shift; - flash->sector_size = (1U << vi->sector_size_kib_shift) * KiB; + flash->sector_size = (1U << vi->sector_size_kib_shift)*1024; flash->size = flash->sector_size * (1U << part->nr_sectors_shift); flash->erase_cmd = vi->desc->erase_cmd; flash->status_cmd = vi->desc->status_cmd; @@ -411,7 +409,7 @@ static int find_match(const struct spi_slave *spi, struct spi_flash *flash, int spi_flash_generic_probe(const struct spi_slave *spi, struct spi_flash *flash) { - int ret, i; + int ret; UINT8 idcode[IDCODE_LEN]; UINT8 manuf_id; UINT16 id[2]; @@ -421,24 +419,19 @@ int spi_flash_generic_probe(const struct spi_slave *spi, if (ret) return -1; - if (CONFIG(DEBUG_SPI_FLASH)) { - DEBUG((EFI_D_INFO, "SF: Got idcode: ")); - for (i = 0; i < sizeof(idcode); i++) - DEBUG((EFI_D_INFO, "%02x ", idcode[i])); - DEBUG((EFI_D_INFO, "\n")); - } - manuf_id = idcode[0]; DEBUG((EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); /* If no result from RDID command and STMicro parts are enabled attempt to wake the part from deep sleep and obtain alternative id info. */ - if (CONFIG(SPI_FLASH_STMICRO) && manuf_id == 0xff) { - if (stmicro_release_deep_sleep_identify(spi, idcode)) +#ifdef SPI_FLASH_STMICRO + if(manuf_id == 0xff) { + if(stmicro_release_deep_sleep_identify(spi, idcode)) return -1; manuf_id = idcode[0]; } +#endif id[0] = (idcode[1] << 8) | idcode[2]; id[1] = (idcode[3] << 8) | idcode[4]; @@ -601,17 +594,13 @@ int spi_flash_set_write_protected(const struct spi_flash *flash, return ret; } - +#ifdef SPI_FLASH_HAS_VOLATILE_GROUP static UINT32 volatile_group_count; int spi_flash_volatile_group_begin(const struct spi_flash *flash) { - UINT32 count; int ret = 0; - - if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) - return ret; - + UINT32 count; count = volatile_group_count; if (count == 0) ret = chipset_volatile_group_begin(flash); @@ -623,14 +612,9 @@ int spi_flash_volatile_group_begin(const struct spi_flash *flash) int spi_flash_volatile_group_end(const struct spi_flash *flash) { - UINT32 count; int ret = 0; - - if (!CONFIG(SPI_FLASH_HAS_VOLATILE_GROUP)) - return ret; - + UINT32 count; count = volatile_group_count; - // assert(count == 0); count--; volatile_group_count = count; @@ -639,36 +623,20 @@ int spi_flash_volatile_group_end(const struct spi_flash *flash) return ret; } +#else -// VOID lb_spi_flash(struct lb_header *header) -// { -// struct lb_spi_flash *flash; -// const struct spi_flash *spi_flash_dev; - -// if (!CONFIG(BOOT_DEVICE_SPI_FLASH)) -// return; - -// flash = (struct lb_spi_flash *)lb_new_record(header); - -// flash->tag = LB_TAG_SPI_FLASH; -// flash->size = sizeof(*flash); - -// spi_flash_dev = boot_device_spi_flash(); - -// if (spi_flash_dev) { -// flash->flash_size = spi_flash_dev->size; -// flash->sector_size = spi_flash_dev->sector_size; -// flash->erase_cmd = spi_flash_dev->erase_cmd; -// } else { -// #define CONFIG_ROM_SIZE 0x400000; -// flash->flash_size = CONFIG_ROM_SIZE; -// /* Default 64k erase command should work on most flash. -// * Uniform 4k erase only works on certain devices. */ -// flash->sector_size = 64 * KiB; -// flash->erase_cmd = CMD_BLOCK_ERASE; -// } -// } +int spi_flash_volatile_group_begin(const struct spi_flash *flash) +{ + int ret = 0; + return ret; +} +int spi_flash_volatile_group_end(const struct spi_flash *flash) +{ + int ret = 0; + return ret; +} +#endif /* SPI_FLASH_HAS_VOLATILE_GROUP */ int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, const struct region *region, diff --git a/UefiPayloadPkg/SPI/stopwatch.h b/UefiPayloadPkg/SPI/stopwatch.h index bbc1a1a95e34..4af0ffbd804e 100644 --- a/UefiPayloadPkg/SPI/stopwatch.h +++ b/UefiPayloadPkg/SPI/stopwatch.h @@ -116,11 +116,7 @@ struct stopwatch { static inline VOID stopwatch_init(struct stopwatch *sw) { - if (CONFIG(HAVE_MONOTONIC_TIMER)) - timer_monotonic_get(&sw->start); - else - sw->start.microseconds = 0; - + sw->start.microseconds = 0; sw->current = sw->expires = sw->start; } @@ -140,10 +136,7 @@ static inline VOID stopwatch_init_msecs_expire(struct stopwatch *sw, long ms) */ static inline VOID stopwatch_tick(struct stopwatch *sw) { - if (CONFIG(HAVE_MONOTONIC_TIMER)) - timer_monotonic_get(&sw->current); - else - sw->current.microseconds = 0; + sw->current.microseconds = 0; } /* @@ -160,8 +153,7 @@ static inline int stopwatch_expired(struct stopwatch *sw) */ static inline VOID stopwatch_wait_until_expired(struct stopwatch *sw) { - while (!stopwatch_expired(sw)) - ; + while (!stopwatch_expired(sw)); } /* diff --git a/UefiPayloadPkg/SPI/utils.h b/UefiPayloadPkg/SPI/utils.h deleted file mode 100644 index faf3a8f72d4f..000000000000 --- a/UefiPayloadPkg/SPI/utils.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef UTILS_H -#define UTILS_H - -#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1UL) -#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) -#define ALIGN_UP(x,a) ALIGN((x),(a)) -#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) -#define IS_ALIGNED(x,a) (((x) & ((typeof(x))(a)-1UL)) == 0) - -#define KiB (1<<10) - -#endif /* UTILS_H */ diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/winbond.c index 1d0cf43d147b..00c36ec82e66 100644 --- a/UefiPayloadPkg/SPI/winbond.c +++ b/UefiPayloadPkg/SPI/winbond.c @@ -2,7 +2,7 @@ #include #include "spi_winbond.h" #include "spi_flash_internal.h" -#include "SPIgeneric.h" +#include "GenericSPI.h" #include "SPI_fvb.h" union status_reg1 { From 6ecb3ec8516359e255c440872e03bac6230ed582 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 16 Oct 2020 14:12:45 +0200 Subject: [PATCH 261/297] UefiPayloadPkg/SPI/pci_ops.c dekete the file and start using PciLib.h --- UefiPayloadPkg/SPI/FchSPICtrl.c | 19 +++++----- UefiPayloadPkg/SPI/FchSPIUtil.c | 10 +++--- UefiPayloadPkg/SPI/Fvb.c | 14 -------- UefiPayloadPkg/SPI/GenericSPI.c | 8 ----- UefiPayloadPkg/SPI/SPI.h | 4 +++ UefiPayloadPkg/SPI/SPI.inf | 3 +- UefiPayloadPkg/SPI/pci_ops.c | 64 --------------------------------- UefiPayloadPkg/SPI/pci_ops.h | 19 ---------- 8 files changed, 18 insertions(+), 123 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/pci_ops.c delete mode 100644 UefiPayloadPkg/SPI/pci_ops.h diff --git a/UefiPayloadPkg/SPI/FchSPICtrl.c b/UefiPayloadPkg/SPI/FchSPICtrl.c index 912807669751..b69614dff017 100644 --- a/UefiPayloadPkg/SPI/FchSPICtrl.c +++ b/UefiPayloadPkg/SPI/FchSPICtrl.c @@ -1,11 +1,10 @@ #include -#include +#include #include - -#include "SPI.h" +#include #include "FchSPIUtil.h" #include "GenericSPI.h" -#include "pci_ops.h" +#include "SPI.h" #include "spi_flash_internal.h" /* SPDX-License-Identifier: GPL-2.0-only */ @@ -34,11 +33,6 @@ #define ROM_PROTECT_RANGE0 0x50 #define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) -#define PCU_DEV 0x14 -#define LPC_FUNC 3 -#define _SOC_DEV(slot, func) PCI_DEV(0, slot, func) -#define SOC_LPC_DEV _SOC_DEV(PCU_DEV, LPC_FUNC) - static int wait_for_ready(VOID) { CONST UINT64 timeoutMilisecond = 500; @@ -131,14 +125,17 @@ int protect_a_range(UINT32 value) /* find a free protection register */ for (n = 0; n < MAX_ROM_PROTECT_RANGES; n++) { - reg32 = pci_read_config32((struct device *)((VOID *)SOC_LPC_DEV), ROM_PROTECT_RANGE_REG(n)); + reg32 = PciRead32( + PCI_LIB_ADDRESS(PCU_BUS, PCU_DEV, LPC_FUNC, ROM_PROTECT_RANGE_REG(n))); if (!reg32) break; } if (n == MAX_ROM_PROTECT_RANGES) return -1; /* no free range */ - pci_write_config32((struct device *)((VOID *)SOC_LPC_DEV), ROM_PROTECT_RANGE_REG(n), value); + PciWrite32( + PCI_LIB_ADDRESS(PCU_BUS, PCU_DEV, LPC_FUNC, ROM_PROTECT_RANGE_REG(n)), + value); return 0; } diff --git a/UefiPayloadPkg/SPI/FchSPIUtil.c b/UefiPayloadPkg/SPI/FchSPIUtil.c index cabf89aaf2c1..1f0dfedf4bd2 100644 --- a/UefiPayloadPkg/SPI/FchSPIUtil.c +++ b/UefiPayloadPkg/SPI/FchSPIUtil.c @@ -1,12 +1,11 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include "FchSPIUtil.h" - #include +#include #include #include #include "FchSPICtrl.h" -#include "pci_ops.h" +#include "FchSPIUtil.h" +#include "SPI.h" #define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) #define SPIROM_BASE_ADDRESS_REGISTER 0xa0 @@ -18,7 +17,8 @@ static UINTN spi_base = 0; UINTN lpc_get_spibase(VOID) { UINT32 base; - base = pci_read_config32((struct device *)_LPCB_DEV, SPIROM_BASE_ADDRESS_REGISTER); + base = PciRead32( + PCI_LIB_ADDRESS(PCU_BUS, PCU_DEV, LPC_FUNC, SPIROM_BASE_ADDRESS_REGISTER)); base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); return (unsigned long int)base; } diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index fb5830e9a437..36edcd494198 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -442,20 +442,6 @@ FvbGetPhysicalAddress ( { return EFI_UNSUPPORTED; } -// EFI_STATUS -// EFIAPI -// FvbGetPhysicalAddress ( -// IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, -// OUT EFI_PHYSICAL_ADDRESS *Address -// ) -// { -// DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); -// ASSERT(Address != NULL); - -// *Address = mFlashNvStorageVariableBase; -// return EFI_SUCCESS; -// } - /** The GetBlockSize() function retrieves the size of the requested diff --git a/UefiPayloadPkg/SPI/GenericSPI.c b/UefiPayloadPkg/SPI/GenericSPI.c index 6debdafb2b3b..e94cb2276584 100644 --- a/UefiPayloadPkg/SPI/GenericSPI.c +++ b/UefiPayloadPkg/SPI/GenericSPI.c @@ -91,8 +91,6 @@ UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, deduct_opcode_len = !!(ctrlr->flags & SPI_CNTRLR_DEDUCT_OPCODE_LEN); ctrlr_max = ctrlr->max_xfer_size; - //assert (ctrlr_max != 0); - /* Assume opcode is always one byte and deduct it from the cmd_len as the hardware has a separate register for the opcode. */ if (deduct_opcode_len) @@ -104,12 +102,6 @@ UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, return MIN(ctrlr_max, buf_len); } -// __attribute__((__weak__)) -// VOID spi_init(VOID) -// { -// /* Default weak implementation - do nothing. */ -// } - UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { __SIZE_TYPE__ i; diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index 46ac43061815..bf5ecb2d8f52 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -5,6 +5,10 @@ #include +#define PCU_BUS 0x00 +#define PCU_DEV 0x14 +#define LPC_FUNC 0x03 + #define SPI_CNTRL0 0x00 #define SPI_BUSY BIT31 diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 1009444b1c38..0a117cfb3e49 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -28,8 +28,6 @@ FchSPIUtil.h FchSPIUtil.c stopwatch.h - pci_ops.h - pci_ops.c Fvb.h Fvb.c spi_flash_internal.h @@ -47,6 +45,7 @@ TimerLib UefiDriverEntryPoint HobLib + PciLib [Guids] gEdkiiNvVarStoreFormattedGuid diff --git a/UefiPayloadPkg/SPI/pci_ops.c b/UefiPayloadPkg/SPI/pci_ops.c deleted file mode 100644 index 8d3b01460ac1..000000000000 --- a/UefiPayloadPkg/SPI/pci_ops.c +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef PCI_OPS_H -#define PCI_OPS_H - -#include -#include - -#include "pci_type.h" -#include "device.h" -#include "FchSPIUtil.h" -#include "FchSPICtrl.h" - -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pcicfg(dev)->reg32[reg / sizeof(UINT32)]; -} - -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pcicfg(dev)->reg32[reg / sizeof(UINT32)] = value; -} - -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg) -{ - return pci_mmio_read_config32(dev, reg); -} - -pci_devfn_t pcidev_bdf(CONST struct device *dev) -{ - return (dev->path.pci.devfn << 12) | (dev->bus->secondary << 20); -} - -// __attribute__ ((noreturn)) -// VOID pcidev_die(VOID) -// { -// //die("PCI: dev is NULL!\n"); -// DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); -// while(1); -// } - -pci_devfn_t pcidev_assert(CONST struct device *dev) -{ - if (!dev) { - DEBUG((EFI_D_INFO, "%a: PCI: dev is NULL!", __FUNCTION__)); - } - return pcidev_bdf(dev); -} - -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg) -{ - return pci_s_read_config32(PCI_DEV(0x00, 0x14, 0x03), reg); - //return pci_s_read_config32(PCI_BDF(dev), reg); -} - -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value) -{ - pci_mmio_write_config32(dev, reg, value); -} - -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val) -{ - pci_s_write_config32(PCI_BDF(dev), reg, val); -} - -#endif /* PCI_OPS_H */ diff --git a/UefiPayloadPkg/SPI/pci_ops.h b/UefiPayloadPkg/SPI/pci_ops.h deleted file mode 100644 index 6a451fa5be10..000000000000 --- a/UefiPayloadPkg/SPI/pci_ops.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef PCI_OPS_H -#define PCI_OPS_H - -#include -#include - -#include "pci_type.h" -#include "device.h" - -UINT32 pci_mmio_read_config32(pci_devfn_t dev, UINT16 reg); -void pci_mmio_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); -UINT32 pci_s_read_config32(pci_devfn_t dev, UINT16 reg); -pci_devfn_t pcidev_bdf(CONST struct device *dev); -pci_devfn_t pcidev_assert(CONST struct device *dev); -UINT32 pci_read_config32(CONST struct device *dev, UINT16 reg); -VOID pci_s_write_config32(pci_devfn_t dev, UINT16 reg, UINT32 value); -VOID pci_write_config32(CONST struct device *dev, UINT16 reg, UINT32 val); - -#endif /* PCI_OPS_H */ From 1f56fc52e599a5bebd473ca50299991617c676b5 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 16 Oct 2020 14:38:02 +0200 Subject: [PATCH 262/297] UefiPayloadPkg/SPI/*: delete stopwatch.h and pci_type.h --- UefiPayloadPkg/SPI/FchSPICtrl.h | 2 - UefiPayloadPkg/SPI/FchSPIUtil.c | 8 -- UefiPayloadPkg/SPI/SPI.inf | 22 ++-- UefiPayloadPkg/SPI/pci_type.h | 30 ----- UefiPayloadPkg/SPI/stopwatch.h | 211 -------------------------------- 5 files changed, 10 insertions(+), 263 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/pci_type.h delete mode 100644 UefiPayloadPkg/SPI/stopwatch.h diff --git a/UefiPayloadPkg/SPI/FchSPICtrl.h b/UefiPayloadPkg/SPI/FchSPICtrl.h index db11667deff4..c4efab3e9562 100644 --- a/UefiPayloadPkg/SPI/FchSPICtrl.h +++ b/UefiPayloadPkg/SPI/FchSPICtrl.h @@ -2,7 +2,6 @@ #define FCH_SPI_CTRL_H #include -#include "pci_type.h" #include "GenericSPI.h" union pci_bank { @@ -11,7 +10,6 @@ union pci_bank { UINT32 reg32[4096 / sizeof(UINT32)]; }; -union pci_bank *pcicfg(pci_devfn_t dev); int execute_command(VOID); VOID spi_init(VOID); int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, diff --git a/UefiPayloadPkg/SPI/FchSPIUtil.c b/UefiPayloadPkg/SPI/FchSPIUtil.c index 1f0dfedf4bd2..c8d282dd9302 100644 --- a/UefiPayloadPkg/SPI/FchSPIUtil.c +++ b/UefiPayloadPkg/SPI/FchSPIUtil.c @@ -28,14 +28,6 @@ VOID spi_set_base(UINTN base) spi_base = base; } -//static //__attribute__ ((__always_inline__)) -union pci_bank *pcicfg(pci_devfn_t dev) -{ - // FIXME this should not be a magic constant - UINT8 *pci_mmconf =(void *)((UINTN)(0xF8000000)); - return (void *)&pci_mmconf[PCI_DEVFN_OFFSET(dev)]; -} - UINTN spi_get_bar(VOID) { if (spi_base == 0) { diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 0a117cfb3e49..f1834a14e7e8 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -16,22 +16,20 @@ ENTRY_POINT = SPIInitialize [Sources] - SPI.h - GenericSPI.h - GenericSPI.c - pci_type.h - device.h - FchSPICtrl.h FchSPICtrl.c - SPI_fvb.h - SPI_fvb.c - FchSPIUtil.h + FchSPICtrl.h FchSPIUtil.c - stopwatch.h - Fvb.h + FchSPIUtil.h Fvb.c - spi_flash_internal.h + Fvb.h + GenericSPI.c + GenericSPI.h + SPI.h + SPI_fvb.c + SPI_fvb.h + device.h spi_flash_internal.c + spi_flash_internal.h [Packages] MdePkg/MdePkg.dec diff --git a/UefiPayloadPkg/SPI/pci_type.h b/UefiPayloadPkg/SPI/pci_type.h deleted file mode 100644 index 5da76549f782..000000000000 --- a/UefiPayloadPkg/SPI/pci_type.h +++ /dev/null @@ -1,30 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef DEVICE_PCI_TYPE_H -#define DEVICE_PCI_TYPE_H - -typedef UINT32 pci_devfn_t; - -/* Convert pci_devfn_t to offset in MMCONF space. - * As it is one-to-one, nothing needs to be done. */ -#define PCI_DEVFN_OFFSET(x) ((x)) - -#define PCI_DEV(SEGBUS, DEV, FN) ( \ - (((SEGBUS) & 0xFFF) << 20) | \ - (((DEV) & 0x1F) << 15) | \ - (((FN) & 0x07) << 12)) - -#define PCI_DEV_INVALID (0xffffffffU) - -#if 1 -/* FIXME: For most of the time in ramstage, we get valid device pointer - * from calling the driver entry points. The assert should only be used - * with searches like pcidev_behind(), and only if caller does not make - * the check themselves. - */ -#define PCI_BDF(dev) pcidev_assert((dev)) -#else -#define PCI_BDF(dev) pcidev_bdf((dev)) -#endif - -#endif /* DEVICE_PCI_TYPE_H */ diff --git a/UefiPayloadPkg/SPI/stopwatch.h b/UefiPayloadPkg/SPI/stopwatch.h deleted file mode 100644 index 4af0ffbd804e..000000000000 --- a/UefiPayloadPkg/SPI/stopwatch.h +++ /dev/null @@ -1,211 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef TIMER_H -#define TIMER_H - -#include - -#define NSECS_PER_SEC 1000000000 -#define USECS_PER_SEC 1000000 -#define MSECS_PER_SEC 1000 -#define USECS_PER_MSEC (USECS_PER_SEC / MSECS_PER_SEC) - -/* The time structures are defined to be a representation of the time since - * coreboot started executing one of its stages. The reason for using structures - * is to allow for changes in the future. The structures' details are exposed - * so that the compiler can allocate space on the stack and use in other - * structures. In other words, accessing any field within this structure - * outside of the core timer code is not supported. */ - -struct mono_time { - long microseconds; -}; - -/* A timeout_callback structure is used for the book keeping for scheduling - * work in the future. When a callback is called the structure can be - * re-used for scheduling as it is not being tracked by the core timer - * library any more. */ -struct timeout_callback { - VOID *priv; - VOID (*callback)(struct timeout_callback *tocb); - /* Not for public use. The timer library uses the fields below. */ - struct mono_time expiration; -}; - -/* Obtain the current monotonic time. The assumption is that the time counts - * up from the value 0 with value 0 being the point when the timer was - * initialized. Additionally, the timer is assumed to only be valid for the - * duration of the boot. - * - * Note that any implementations of timer_monotonic_get() - * need to ensure its timesource does not roll over within 10 secs. The reason - * is that the time between calls to timer_monotonic_get() may be on order - * of 10 seconds. */ -VOID timer_monotonic_get(struct mono_time *mt); - -/* Returns 1 if callbacks still present in the queue. 0 if no timers left. */ -int timers_run(VOID); - -/* Schedule a callback to be ran microseconds from time of invocation. - * 0 returned on success, < 0 on error. */ -int timer_sched_callback(struct timeout_callback *tocb, unsigned long us); - -/* Set an absolute time to a number of microseconds. */ -static inline VOID mono_time_set_usecs(struct mono_time *mt, long us) -{ - mt->microseconds = us; -} - -/* Set an absolute time to a number of milliseconds. */ -static inline VOID mono_time_set_msecs(struct mono_time *mt, long ms) -{ - mt->microseconds = ms * USECS_PER_MSEC; -} - -/* Add microseconds to an absolute time. */ -static inline VOID mono_time_add_usecs(struct mono_time *mt, long us) -{ - mt->microseconds += us; -} - -/* Add milliseconds to an absolute time. */ -static inline VOID mono_time_add_msecs(struct mono_time *mt, long ms) -{ - mono_time_add_usecs(mt, ms * USECS_PER_MSEC); -} - -/* Compare two absolute times: Return -1, 0, or 1 if t1 is <, =, or > t2, - * respectively. */ -static inline int mono_time_cmp(const struct mono_time *t1, - const struct mono_time *t2) -{ - if (t1->microseconds == t2->microseconds) - return 0; - - if (t1->microseconds < t2->microseconds) - return -1; - - return 1; -} - -/* Return true if t1 after t2 */ -static inline int mono_time_after(const struct mono_time *t1, - const struct mono_time *t2) -{ - return mono_time_cmp(t1, t2) > 0; -} - -/* Return true if t1 before t2. */ -static inline int mono_time_before(const struct mono_time *t1, - const struct mono_time *t2) -{ - return mono_time_cmp(t1, t2) < 0; -} - -/* Return time difference between t1 and t2. i.e. t2 - t1. */ -static inline long mono_time_diff_microseconds(const struct mono_time *t1, - const struct mono_time *t2) -{ - return t2->microseconds - t1->microseconds; -} - -struct stopwatch { - struct mono_time start; - struct mono_time current; - struct mono_time expires; -}; - -static inline VOID stopwatch_init(struct stopwatch *sw) -{ - sw->start.microseconds = 0; - sw->current = sw->expires = sw->start; -} - -static inline VOID stopwatch_init_usecs_expire(struct stopwatch *sw, long us) -{ - stopwatch_init(sw); - mono_time_add_usecs(&sw->expires, us); -} - -static inline VOID stopwatch_init_msecs_expire(struct stopwatch *sw, long ms) -{ - stopwatch_init_usecs_expire(sw, USECS_PER_MSEC * ms); -} - -/* - * Tick the stopwatch to collect the current time. - */ -static inline VOID stopwatch_tick(struct stopwatch *sw) -{ - sw->current.microseconds = 0; -} - -/* - * Tick and check the stopwatch for expiration. Returns non-zero on expiration. - */ -static inline int stopwatch_expired(struct stopwatch *sw) -{ - stopwatch_tick(sw); - return !mono_time_before(&sw->current, &sw->expires); -} - -/* - * Tick and check the stopwatch as long as it has not expired. - */ -static inline VOID stopwatch_wait_until_expired(struct stopwatch *sw) -{ - while (!stopwatch_expired(sw)); -} - -/* - * Return number of microseconds since starting the stopwatch. - */ -static inline long stopwatch_duration_usecs(struct stopwatch *sw) -{ - /* - * If the stopwatch hasn't been ticked (current == start) tick - * the stopwatch to gather the accumulated time. - */ - if (!mono_time_cmp(&sw->start, &sw->current)) - stopwatch_tick(sw); - - return mono_time_diff_microseconds(&sw->start, &sw->current); -} - -static inline long stopwatch_duration_msecs(struct stopwatch *sw) -{ - return stopwatch_duration_usecs(sw) / USECS_PER_MSEC; -} - -/* - * Helper macro to wait until a condition becomes true or a timeout elapses. - * - * condition: a C expression to wait for - * timeout: timeout, in microseconds - * - * Returns: - * 0 if the condition still evaluates to false after the timeout elapsed, - * >0 if the condition evaluates to true. The return value is the amount of - * microseconds waited (at least 1). - */ -#define wait_us(timeout_us, condition) \ -({ \ - long __ret = 0; \ - struct stopwatch __sw; \ - stopwatch_init_usecs_expire(&__sw, timeout_us); \ - do { \ - if (condition) { \ - stopwatch_tick(&__sw); \ - __ret = stopwatch_duration_usecs(&__sw); \ - if (!__ret) /* make sure it evaluates to true */\ - __ret = 1; \ - break; \ - } \ - } while (!stopwatch_expired(&__sw)); \ - __ret; \ -}) - -#define wait_ms(timeout_ms, condition) \ - DIV_ROUND_UP(wait_us((timeout_ms) * USECS_PER_MSEC, condition), \ - USECS_PER_MSEC) - -#endif /* TIMER_H */ From a5930e742e726051c26d218ee0faecea7b82125e Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 16 Oct 2020 14:58:50 +0200 Subject: [PATCH 263/297] UefiPayloadPkg/SPI/* delete device.h, path.h --- UefiPayloadPkg/SPI/Fvb.c | 2 +- UefiPayloadPkg/SPI/SPI.inf | 1 - UefiPayloadPkg/SPI/device.h | 82 ---------- UefiPayloadPkg/SPI/path.h | 145 ------------------ UefiPayloadPkg/SPI/winbond.c | 2 +- .../SPI/{spi_winbond.h => winbond.h} | 0 6 files changed, 2 insertions(+), 230 deletions(-) delete mode 100644 UefiPayloadPkg/SPI/device.h delete mode 100644 UefiPayloadPkg/SPI/path.h rename UefiPayloadPkg/SPI/{spi_winbond.h => winbond.h} (100%) diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 36edcd494198..7a80a5ae818e 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -4,7 +4,7 @@ #include "SPI_fvb.h" #include "GenericSPI.h" #include "spi_flash_internal.h" -#include "spi_winbond.h" +#include "winbond.h" #include "SPI.h" diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index f1834a14e7e8..ba3d3d261863 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -27,7 +27,6 @@ SPI.h SPI_fvb.c SPI_fvb.h - device.h spi_flash_internal.c spi_flash_internal.h diff --git a/UefiPayloadPkg/SPI/device.h b/UefiPayloadPkg/SPI/device.h deleted file mode 100644 index 168bde6b0d37..000000000000 --- a/UefiPayloadPkg/SPI/device.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef DEVICE_H -#define DEVICE_H - -#include -#include "path.h" - -struct bus { - - struct device *dev; /* This bridge device */ - struct device *children; /* devices behind this bridge */ - struct bus *next; /* The next bridge on this device */ - unsigned int bridge_ctrl; /* Bridge control register */ - UINT16 bridge_cmd; /* Bridge command register */ - unsigned char link_num; /* The index of this link */ - UINT16 secondary; /* secondary bus number */ - UINT16 subordinate; /* max subordinate bus number */ - unsigned char cap; /* PCi capability offset */ - UINT32 hcdn_reg; /* For HyperTransport link */ - - unsigned int reset_needed : 1; - unsigned int disable_relaxed_ordering : 1; - unsigned int ht_link_up : 1; - unsigned int no_vga16 : 1; /* No support for 16-bit VGA decoding */ -}; - -/* - * There is one device structure for each slot-number/function-number - * combination: - */ - -struct pci_irq_info { - unsigned int ioapic_irq_pin; - unsigned int ioapic_src_pin; - unsigned int ioapic_dst_id; - unsigned int ioapic_flags; -}; - -struct device { - struct bus *bus; /* bus this device is on, for bridge - * devices, it is the up stream bus */ - - struct device *sibling; /* next device on this bus */ - - struct device *next; /* chain of all devices */ - - struct device_path path; - unsigned int vendor; - unsigned int device; - UINT16 subsystem_vendor; - UINT16 subsystem_device; - unsigned int class; /* 3 bytes: (base, sub, prog-if) */ - unsigned int hdr_type; /* PCI header type */ - unsigned int enabled : 1; /* set if we should enable the device */ - unsigned int initialized : 1; /* 1 if we have initialized the device */ - unsigned int on_mainboard : 1; - unsigned int disable_pcie_aspm : 1; - /* set if we should hide from UI */ - unsigned int hidden : 1; - /* set if this device is used even in minimum PCI cases */ - unsigned int mandatory : 1; - UINT8 command; - UINT16 hotplug_buses; /* Number of hotplug buses to allocate */ - - /* Base registers for this device. I/O, MEM and Expansion ROM */ - struct resource *resource_list; - - /* links are (downstream) buses attached to the device, usually a leaf - * device with no children has 0 buses attached and a bridge has 1 bus - */ - struct bus *link_list; - - struct pci_irq_info pci_irq_info[4]; - struct device_operations *ops; - struct chip_operations *chip_ops; - const char *name; - void *chip_info; - - /* Zero-terminated array of fields and options to probe. */ - struct fw_config *probe_list; -}; - -#endif /* DEVICE_H */ diff --git a/UefiPayloadPkg/SPI/path.h b/UefiPayloadPkg/SPI/path.h deleted file mode 100644 index 8afbfd0820a5..000000000000 --- a/UefiPayloadPkg/SPI/path.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef PATH_H -#define PATH_H - -#include - -enum device_path_type { - DEVICE_PATH_NONE = 0, - DEVICE_PATH_ROOT, - DEVICE_PATH_PCI, - DEVICE_PATH_PNP, - DEVICE_PATH_I2C, - DEVICE_PATH_APIC, - DEVICE_PATH_DOMAIN, - DEVICE_PATH_CPU_CLUSTER, - DEVICE_PATH_CPU, - DEVICE_PATH_CPU_BUS, - DEVICE_PATH_IOAPIC, - DEVICE_PATH_GENERIC, - DEVICE_PATH_SPI, - DEVICE_PATH_USB, - DEVICE_PATH_MMIO, - DEVICE_PATH_ESPI, - DEVICE_PATH_LPC, - - /* - * When adding path types to this table, please also update the - * DEVICE_PATH_NAMES macro below. - */ -}; - -#define DEVICE_PATH_NAMES { \ - "DEVICE_PATH_NONE", \ - "DEVICE_PATH_ROOT", \ - "DEVICE_PATH_PCI", \ - "DEVICE_PATH_PNP", \ - "DEVICE_PATH_I2C", \ - "DEVICE_PATH_APIC", \ - "DEVICE_PATH_DOMAIN", \ - "DEVICE_PATH_CPU_CLUSTER", \ - "DEVICE_PATH_CPU", \ - "DEVICE_PATH_CPU_BUS", \ - "DEVICE_PATH_IOAPIC", \ - "DEVICE_PATH_GENERIC", \ - "DEVICE_PATH_SPI", \ - "DEVICE_PATH_USB", \ - "DEVICE_PATH_MMIO", \ - "DEVICE_PATH_ESPI", \ - "DEVICE_PATH_LPC", \ -} - -struct domain_path { - unsigned int domain; -}; - -struct pci_path { - unsigned int devfn; -}; - -struct pnp_path { - unsigned int port; - unsigned int device; -}; - -struct i2c_path { - unsigned int device; - unsigned int mode_10bit; -}; - -struct spi_path { - unsigned int cs; -}; - -struct apic_path { - unsigned int apic_id; - unsigned int package_id; - unsigned int node_id; - unsigned int core_id; - unsigned int thread_id; -}; - -struct ioapic_path { - unsigned int ioapic_id; -}; - -struct cpu_cluster_path { - unsigned int cluster; -}; - -struct cpu_path { - unsigned int id; -}; - -struct cpu_bus_path { - unsigned int id; -}; - -struct generic_path { - unsigned int id; - unsigned int subid; -}; - -struct usb_path { - unsigned int port_type; - unsigned int port_id; -}; - -struct mmio_path { - UINT32 *addr; -}; - -struct espi_path { - UINT32 *addr; -}; - -struct lpc_path { - UINT32 *addr; -}; - -struct device_path { - enum device_path_type type; - union { - struct pci_path pci; - struct pnp_path pnp; - struct i2c_path i2c; - struct apic_path apic; - struct ioapic_path ioapic; - struct domain_path domain; - struct cpu_cluster_path cpu_cluster; - struct cpu_path cpu; - struct cpu_bus_path cpu_bus; - struct generic_path generic; - struct spi_path spi; - struct usb_path usb; - struct mmio_path mmio; - struct espi_path espi; - struct lpc_path lpc; - }; -}; - -#define DEVICE_PATH_MAX 40 -#define BUS_PATH_MAX (DEVICE_PATH_MAX+10) - -extern const char *dev_path_name(enum device_path_type type); - -#endif /* PATH_H */ diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/winbond.c index 00c36ec82e66..8d7309023e8c 100644 --- a/UefiPayloadPkg/SPI/winbond.c +++ b/UefiPayloadPkg/SPI/winbond.c @@ -1,6 +1,6 @@ #include #include -#include "spi_winbond.h" +#include "winbond.h" #include "spi_flash_internal.h" #include "GenericSPI.h" #include "SPI_fvb.h" diff --git a/UefiPayloadPkg/SPI/spi_winbond.h b/UefiPayloadPkg/SPI/winbond.h similarity index 100% rename from UefiPayloadPkg/SPI/spi_winbond.h rename to UefiPayloadPkg/SPI/winbond.h From 5b802f07dbed69c084c8a0138aaf91e2944e4194 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Fri, 16 Oct 2020 16:39:20 +0200 Subject: [PATCH 264/297] UefiPayloadPkg/Library/CbSMMStoreLib/CorebootSMMStore.c: fix compilation error MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/Library/CbSMMStoreLib/CorebootSMMStore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/Library/CbSMMStoreLib/CorebootSMMStore.c b/UefiPayloadPkg/Library/CbSMMStoreLib/CorebootSMMStore.c index 5cbb66b53fb6..b919dbef17fa 100644 --- a/UefiPayloadPkg/Library/CbSMMStoreLib/CorebootSMMStore.c +++ b/UefiPayloadPkg/Library/CbSMMStoreLib/CorebootSMMStore.c @@ -145,7 +145,7 @@ SMMStoreRead ( return EFI_NO_RESPONSE; } - CopyMem (Buffer, (VOID *)(mSmmStoreInfo->ComBuffer + Offset), *NumBytes); + CopyMem (Buffer, (VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), *NumBytes); return EFI_SUCCESS; } @@ -186,7 +186,7 @@ SMMStoreWrite ( mArgComBuf->raw_write.bufoffset = Offset; mArgComBuf->raw_write.block_id = Lba; - CopyMem ((VOID *)(mSmmStoreInfo->ComBuffer + Offset), Buffer, *NumBytes); + CopyMem ((VOID *)(UINTN)(mSmmStoreInfo->ComBuffer + Offset), Buffer, *NumBytes); Result = call_smm(mSmmStoreInfo->ApmCmd, SMMSTORE_CMD_RAW_WRITE, mArgComBufPhys); if (Result == SMMSTORE_RET_FAILURE) { From e97752e8ef4fc2b7a3e8869fae05f0dd5776bbe0 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Mon, 19 Oct 2020 14:52:48 +0200 Subject: [PATCH 265/297] UefiPayloadPkg/UefiPayloadPkgIa32.dsc: remove SMMStore from build --- UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c | 3 +- .../BlSMMStoreDxe/BlSMMStoreDxe.inf | 2 +- UefiPayloadPkg/BlSupportPei/BlSupportPei.c | 18 +- UefiPayloadPkg/BlSupportPei/BlSupportPei.inf | 2 +- .../Include/Guid/SMMSTOREInfoGuid.h | 2 +- UefiPayloadPkg/SPI/{adesto.c => Adesto.c} | 4 +- UefiPayloadPkg/SPI/FchSPICtrl.c | 2 +- UefiPayloadPkg/SPI/Fvb.c | 6 +- UefiPayloadPkg/SPI/Fvb.h | 2 +- UefiPayloadPkg/SPI/FvbSPI.c | 304 ++++++++++++++++++ UefiPayloadPkg/SPI/{SPI_fvb.h => FvbSPI.h} | 20 +- UefiPayloadPkg/SPI/GenericSPI.c | 2 +- UefiPayloadPkg/SPI/SPI.h | 79 +---- UefiPayloadPkg/SPI/SPI.inf | 31 +- ...pi_flash_internal.c => SPIFlashInternal.c} | 196 +---------- ...pi_flash_internal.h => SPIFlashInternal.h} | 4 +- UefiPayloadPkg/SPI/SPI_fvb.c | 92 ------ UefiPayloadPkg/SPI/{winbond.c => Winbond.c} | 8 +- UefiPayloadPkg/SPI/{winbond.h => Winbond.h} | 16 +- UefiPayloadPkg/UefiPayloadPkg.dec | 9 +- UefiPayloadPkg/UefiPayloadPkg.fdf | 10 +- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 11 - UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc | 12 - 23 files changed, 389 insertions(+), 446 deletions(-) rename UefiPayloadPkg/SPI/{adesto.c => Adesto.c} (97%) create mode 100644 UefiPayloadPkg/SPI/FvbSPI.c rename UefiPayloadPkg/SPI/{SPI_fvb.h => FvbSPI.h} (91%) rename UefiPayloadPkg/SPI/{spi_flash_internal.c => SPIFlashInternal.c} (76%) rename UefiPayloadPkg/SPI/{spi_flash_internal.h => SPIFlashInternal.h} (99%) delete mode 100644 UefiPayloadPkg/SPI/SPI_fvb.c rename UefiPayloadPkg/SPI/{winbond.c => Winbond.c} (99%) rename UefiPayloadPkg/SPI/{winbond.h => Winbond.h} (61%) diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index 52b133670a35..cdd0a23bd9cd 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c @@ -170,7 +170,8 @@ BlSMMSTOREInitialise ( // // Find the SMMSTORE information guid hob // - GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); + // GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); + GuidHob = NULL; if (GuidHob == NULL) { DEBUG ((DEBUG_WARN, "SMMSTORE not supported! Skipping driver init.\n")); PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf index 49d5f1a3ff39..cf26a1a20cda 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf @@ -44,7 +44,7 @@ gEfiAuthenticatedVariableGuid gEfiEventVirtualAddressChangeGuid gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL - gEfiSMMSTOREInfoHobGuid + # gEfiSMMSTOREInfoHobGuid [Protocols] gEfiBlockIoProtocolGuid diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c b/UefiPayloadPkg/BlSupportPei/BlSupportPei.c index 4872870ef86d..c5693ffc4fcf 100644 --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.c +++ b/UefiPayloadPkg/BlSupportPei/BlSupportPei.c @@ -433,8 +433,8 @@ BlPeiEntryPoint ( SYSTEM_TABLE_INFO *NewSysTableInfo; ACPI_BOARD_INFO AcpiBoardInfo; ACPI_BOARD_INFO *NewAcpiBoardInfo; - SMMSTORE_INFO SMMSTOREInfo; - SMMSTORE_INFO *NewSMMSTOREInfo; + // SMMSTORE_INFO SMMSTOREInfo; + // SMMSTORE_INFO *NewSMMSTOREInfo; EFI_PEI_GRAPHICS_INFO_HOB GfxInfo; EFI_PEI_GRAPHICS_INFO_HOB *NewGfxInfo; EFI_PEI_GRAPHICS_DEVICE_INFO_HOB GfxDeviceInfo; @@ -588,13 +588,13 @@ BlPeiEntryPoint ( // // Create guid hob for SMMSTORE // - Status = ParseSMMSTOREInfo (&SMMSTOREInfo); - if (!EFI_ERROR (Status)) { - NewSMMSTOREInfo = BuildGuidHob (&gEfiSMMSTOREInfoHobGuid, sizeof (SMMSTOREInfo)); - ASSERT (NewSMMSTOREInfo != NULL); - CopyMem (NewSMMSTOREInfo, &SMMSTOREInfo, sizeof (SMMSTOREInfo)); - DEBUG ((DEBUG_INFO, "Created SMMSTORE info hob\n")); - } + // Status = ParseSMMSTOREInfo (&SMMSTOREInfo); + // if (!EFI_ERROR (Status)) { + // NewSMMSTOREInfo = BuildGuidHob (&gEfiSMMSTOREInfoHobGuid, sizeof (SMMSTOREInfo)); + // ASSERT (NewSMMSTOREInfo != NULL); + // CopyMem (NewSMMSTOREInfo, &SMMSTOREInfo, sizeof (SMMSTOREInfo)); + // DEBUG ((DEBUG_INFO, "Created SMMSTORE info hob\n")); + // } // // Create guid hob for system tables like acpi table and smbios table diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf b/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf index 941c0f419bfa..90216e22f58e 100644 --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf +++ b/UefiPayloadPkg/BlSupportPei/BlSupportPei.inf @@ -56,7 +56,7 @@ gEfiGraphicsInfoHobGuid gEfiGraphicsDeviceInfoHobGuid gUefiAcpiBoardInfoGuid - gEfiSMMSTOREInfoHobGuid + # gEfiSMMSTOREInfoHobGuid [Ppis] gEfiPeiMasterBootModePpiGuid diff --git a/UefiPayloadPkg/Include/Guid/SMMSTOREInfoGuid.h b/UefiPayloadPkg/Include/Guid/SMMSTOREInfoGuid.h index 552f86115b48..075eb14dbf33 100644 --- a/UefiPayloadPkg/Include/Guid/SMMSTOREInfoGuid.h +++ b/UefiPayloadPkg/Include/Guid/SMMSTOREInfoGuid.h @@ -12,7 +12,7 @@ /// /// System Table Information GUID /// -extern EFI_GUID gEfiSMMSTOREInfoHobGuid; +// extern EFI_GUID gEfiSMMSTOREInfoHobGuid; typedef struct { UINT64 ComBuffer; diff --git a/UefiPayloadPkg/SPI/adesto.c b/UefiPayloadPkg/SPI/Adesto.c similarity index 97% rename from UefiPayloadPkg/SPI/adesto.c rename to UefiPayloadPkg/SPI/Adesto.c index 978f8539b7e3..ab6743260b02 100644 --- a/UefiPayloadPkg/SPI/adesto.c +++ b/UefiPayloadPkg/SPI/Adesto.c @@ -2,11 +2,11 @@ /* * Driver for Adesto Technologies SPI flash - * based on winbond.c + * based on Winbond.c */ -#include "spi_flash_internal.h" +#include "SPIFlashInternal.h" /* at25dfxx-specific commands */ #define CMD_AT25DF_WREN 0x06 /* Write Enable */ diff --git a/UefiPayloadPkg/SPI/FchSPICtrl.c b/UefiPayloadPkg/SPI/FchSPICtrl.c index b69614dff017..831fe14bff87 100644 --- a/UefiPayloadPkg/SPI/FchSPICtrl.c +++ b/UefiPayloadPkg/SPI/FchSPICtrl.c @@ -5,7 +5,7 @@ #include "FchSPIUtil.h" #include "GenericSPI.h" #include "SPI.h" -#include "spi_flash_internal.h" +#include "SPIFlashInternal.h" /* SPDX-License-Identifier: GPL-2.0-only */ diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 7a80a5ae818e..907fef05ac07 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -1,11 +1,11 @@ #include #include #include "Fvb.h" -#include "SPI_fvb.h" +#include "FvbSPI.h" #include "GenericSPI.h" -#include "spi_flash_internal.h" -#include "winbond.h" #include "SPI.h" +#include "SPIFlashInternal.h" +#include "Winbond.h" #define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * (Lba)) + (Offset)) diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index b2957478821a..3fe92185154c 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -2,7 +2,7 @@ #define FVB_H #include -#include "SPI_fvb.h" +#include "FvbSPI.h" #define BLOCK_SIZE 0x10000 #define PAGE_SIZE 0x100 diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c new file mode 100644 index 000000000000..7422b61bce16 --- /dev/null +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -0,0 +1,304 @@ +/** @file BlSMMStoreDxe.c + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "FchSPICtrl.h" +#include "Fvb.h" +#include "GenericSPI.h" +#include "SPIFlashInternal.h" + +EFI_HANDLE Handle = NULL; +EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL +}; + +EFI_STATUS checkBusyBit(UINT8 *Busy); + +EFI_STATUS EFIAPI SPIInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + // IN SMMSTORE_INFO *FvbSPIInfoHob +) { EFI_STATUS Status; + VOID *ComBuf; + VOID *GuidHob; + SMMSTORE_INFO *SMMStoreInfoHob; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; + + if (PcdGetBool (PcdEmuVariableNvModeEnable)) { + DEBUG ((DEBUG_WARN, "Variable emulation is active! Skipping driver init.\n")); + while(1); + return EFI_SUCCESS; + } + + // + // Find the SMMSTORE information guid hob + // + GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); + // GuidHob = NULL; + if (GuidHob == NULL) { + DEBUG ((DEBUG_WARN, "SMMSTORE not supported! Skipping driver init.\n")); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + while(1); + return EFI_SUCCESS; + } + + // + // Allocate Communication Buffer for arguments to pass to SMM + // + ComBuf = AllocateRuntimePool (SMMSTORE_COMBUF_SIZE); + if (!ComBuf) { + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + while(1); + return EFI_OUT_OF_RESOURCES; + } + + // + // Place SMMSTORE information hob in a runtime buffer + // + SMMStoreInfoHob = AllocateRuntimePool (GET_GUID_HOB_DATA_SIZE(GuidHob)); + if (!SMMStoreInfoHob) { + FreePool(ComBuf); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + while(1); + return EFI_OUT_OF_RESOURCES; + } + + CopyMem(SMMStoreInfoHob, GET_GUID_HOB_DATA (GuidHob), GET_GUID_HOB_DATA_SIZE(GuidHob)); + + if (!SMMStoreInfoHob->MmioAddress || + !SMMStoreInfoHob->ComBuffer || + !SMMStoreInfoHob->BlockSize || + !SMMStoreInfoHob->NumBlocks) { + DEBUG((EFI_D_ERROR, "%a: Invalid data in SMMStore Info hob\n", __FUNCTION__)); + FreePool(ComBuf); + FreePool(SMMStoreInfoHob); + while(1); + return EFI_WRITE_PROTECTED; + } + + Status = SMMStoreInitialize(ComBuf, SMMStoreInfoHob); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"%a: Failed to initialize SMMStore\n", + __FUNCTION__)); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + FreePool(ComBuf); + FreePool(SMMStoreInfoHob); + while(1); + return Status; + } + + // // Update PCDs for Variable/RuntimeDxe + // PcdSet32S (PcdFlashNvStorageVariableBase, + // PcdGet32 (PcdFlashNvStorageVariableBase) + SMMStoreInfoHob->MmioAddress); + // PcdSet32S (PcdFlashNvStorageFtwWorkingBase, + // PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + SMMStoreInfoHob->MmioAddress); + // PcdSet32S (PcdFlashNvStorageFtwSpareBase, + // PcdGet32 (PcdFlashNvStorageFtwSpareBase) + SMMStoreInfoHob->MmioAddress); + + // mSMMStoreInstance = AllocateRuntimePool (sizeof(SMMSTORE_INSTANCE*)); + // if (!mSMMStoreInstance) { + // DEBUG((EFI_D_ERROR, "%a: Out of resources\n", __FUNCTION__)); + // FreePool(ComBuf); + // FreePool(SMMStoreInfoHob); + // PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + // return EFI_OUT_OF_RESOURCES; + // } + + // Status = SMMStoreCreateInstance ( + // SMMStoreInfoHob->NumBlocks, + // SMMStoreInfoHob->BlockSize, + // &mSMMStoreInstance + // ); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR, "%a: Fail to create instance for SMMStore\n", + __FUNCTION__)); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + FreePool(ComBuf); + FreePool(SMMStoreInfoHob); + while(1); + return Status; + } + + // + // Register for the virtual address change event + // + // Status = gBS->CreateEventEx ( + // EVT_NOTIFY_SIGNAL, + // TPL_NOTIFY, + // BlSMMStoreVirtualNotifyEvent, + // NULL, + // &gEfiEventVirtualAddressChangeGuid, + // &mSMMStoreVirtualAddrChangeEvent + // ); + ASSERT_EFI_ERROR (Status); + + // + // Finally mark the SMM communication buffer provided by CB or SBL as runtime memory + // + Status = gDS->GetMemorySpaceDescriptor (SMMStoreInfoHob->ComBuffer, &GcdDescriptor); + if (EFI_ERROR (Status) || GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) { + DEBUG((EFI_D_INFO, "%a: No memory space descriptor for com buffer found\n", + __FUNCTION__)); + + // + // Add a new entry if not covered by existing mapping + // + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeReserved, + SMMStoreInfoHob->ComBuffer, SMMStoreInfoHob->ComBufferSize, + EFI_MEMORY_WB | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + } + + // + // Mark as runtime service + // + Status = gDS->SetMemorySpaceAttributes ( + SMMStoreInfoHob->ComBuffer, + SMMStoreInfoHob->ComBufferSize, + EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + if (!SMMStoreInfoHob->MmioAddress){ + while(1); + return Status; + } + + // + // Mark the memory mapped store as MMIO memory + // + Status = gDS->GetMemorySpaceDescriptor (SMMStoreInfoHob->MmioAddress, &GcdDescriptor); + if (EFI_ERROR (Status) || GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { + DEBUG((EFI_D_INFO, "%a: No memory space descriptor for com buffer found\n", + __FUNCTION__)); + + // + // Add a new entry if not covered by existing mapping + // + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + SMMStoreInfoHob->MmioAddress, + SMMStoreInfoHob->NumBlocks * SMMStoreInfoHob->BlockSize, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + } + + // + // Mark as runtime service + // + Status = gDS->SetMemorySpaceAttributes ( + SMMStoreInfoHob->MmioAddress, + SMMStoreInfoHob->NumBlocks * SMMStoreInfoHob->BlockSize, + EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + while(1); + return Status; + /////////////////////////////////////////////////////////////////////////////// + // DEBUG((DEBUG_WARN, "SPI IS HERE.\n")); + // SMMSTORE_INFO *FvbSPIInfoHob; + // SMMSTORE_INFO *NewFvbSPIInfoHob; + // VOID *GuidHob; + // if (PcdGetBool(PcdEmuVariableNvModeEnable)) { + // DEBUG (( + // DEBUG_WARN, + // "Variable emulation is active! Skipping driver init.\n")); + // while(1); + // return EFI_SUCCESS; + // } + + // // + // // Create guid hob for SMMSTORE + // // + // // Status = ParseSMMSTOREInfo (&SMMSTOREInfo); + // // if (!EFI_ERROR (Status)) { + // // NewSMMSTOREInfo = BuildGuidHob (&gEfiSMMSTOREInfoHobGuid, sizeof (SMMSTOREInfo)); + // // ASSERT (NewSMMSTOREInfo != NULL); + // // CopyMem (NewSMMSTOREInfo, &SMMSTOREInfo, sizeof (SMMSTOREInfo)); + // // DEBUG ((DEBUG_INFO, "Created SMMSTORE info hob\n")); + // // } + + // FVBSPI_INFO fvbSPIInfo = { + // .ComBuffer = 0, + // .ComBufferSize = 0, + // .NumBlocks = 0, + // .BlockSize = 0, + // .MmioAddress = 0, + // .ApmCmd = 0 + // }; + // DEBUG((DEBUG_WARN, "&gUefiFvbSPIInfoGuid = 0x%X, sizeof(FVBSPI_INFO) = 0x%X\n", &gUefiFvbSPIInfoGuid, sizeof(FVBSPI_INFO))); + // NewFvbSPIInfoHob = BuildGuidHob(&gUefiFvbSPIInfoGuid, sizeof(FVBSPI_INFO)); + // CopyMem(NewFvbSPIInfoHob, &fvbSPIInfo, sizeof(FVBSPI_INFO)); + // DEBUG((DEBUG_INFO, "Created hob\n")); + + // FvbSPIInfoHob = GetFirstGuidHob(&gUefiFvbSPIInfoGuid); + // DEBUG((DEBUG_WARN, "FvbSPIInfoHob = 0x%X\n", FvbSPIInfoHob)); + // if (GuidHob == NULL) { + // DEBUG ((DEBUG_WARN, "FvbSPI not supported! Skipping driver init.\n")); + // PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + // while(1); + // return EFI_SUCCESS; + // } + + // // + // // Place FvbSPI information hob in a runtime buffer + // // + // FvbSPIInfoHob = AllocateRuntimePool(GET_GUID_HOB_DATA_SIZE(GuidHob)); + // if (!FvbSPIInfoHob) { + // DEBUG(( + // EFI_D_INFO, + // "%a Memory allocation failed.\n", __FUNCTION__)); + // PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); + // while(1); + // return EFI_OUT_OF_RESOURCES; + // } + // EFI_STATUS Status; + // Status = gBS->InstallMultipleProtocolInterfaces ( + // &Handle, + // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + // NULL); + // if(EFI_ERROR (Status)) { + // DEBUG(( + // EFI_D_INFO, + // "%a Error during protocol installation.\n", __FUNCTION__)); + // FreePool(FvbSPIInfoHob); + // PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); + // while(1); + // return EFI_PROTOCOL_ERROR; + // } + // // Update PCDs for Variable/RuntimeDxe + // // PcdSet32S (PcdFlashNvStorageVariableBase, + // // PcdGet32 (PcdFlashNvStorageVariableBase) + FvbSPIInfoHob->MmioAddress); + // // PcdSet32S (PcdFlashNvStorageFtwWorkingBase, + // // PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + FvbSPIInfoHob->MmioAddress); + // // PcdSet32S (PcdFlashNvStorageFtwSpareBase, + // // PcdGet32 (PcdFlashNvStorageFtwSpareBase) + FvbSPIInfoHob->MmioAddress); + // spi_init(); + // while(1); + // return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/SPI/SPI_fvb.h b/UefiPayloadPkg/SPI/FvbSPI.h similarity index 91% rename from UefiPayloadPkg/SPI/SPI_fvb.h rename to UefiPayloadPkg/SPI/FvbSPI.h index 77410a9bf10c..d9993b680915 100644 --- a/UefiPayloadPkg/SPI/SPI_fvb.h +++ b/UefiPayloadPkg/SPI/FvbSPI.h @@ -11,17 +11,29 @@ #include -#include #include -#include -#include -#include #include #include #include #include +#include +#include +#include +#include #include "GenericSPI.h" +extern EFI_GUID gUefiFvbSPIInfoGuid; + +typedef struct { + UINT64 ComBuffer; + UINT32 ComBufferSize; + UINT32 NumBlocks; + UINT32 BlockSize; + UINT64 MmioAddress; + UINT8 ApmCmd; + UINT8 Reserved0[3]; +} FVBSPI_INFO; + typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; /* diff --git a/UefiPayloadPkg/SPI/GenericSPI.c b/UefiPayloadPkg/SPI/GenericSPI.c index e94cb2276584..874891664e43 100644 --- a/UefiPayloadPkg/SPI/GenericSPI.c +++ b/UefiPayloadPkg/SPI/GenericSPI.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include #include +#include #include #include "GenericSPI.h" diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h index bf5ecb2d8f52..f975c50139bb 100644 --- a/UefiPayloadPkg/SPI/SPI.h +++ b/UefiPayloadPkg/SPI/SPI.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -#ifndef __AMDBLOCKS_SPI_H__ -#define __AMDBLOCKS_SPI_H__ +#ifndef SPI_H +#define SPI_H #include @@ -9,75 +9,10 @@ #define PCU_DEV 0x14 #define LPC_FUNC 0x03 -#define SPI_CNTRL0 0x00 -#define SPI_BUSY BIT31 +#define SPI_BUSY BIT31 -enum spi_read_mode { - SPI_READ_MODE_NORMAL33M = 0, - /* 1 is reserved. */ - SPI_READ_MODE_DUAL112 = 2, - SPI_READ_MODE_QUAD114 = 3, - SPI_READ_MODE_DUAL122 = 4, - SPI_READ_MODE_QUAD144 = 5, - SPI_READ_MODE_NORMAL66M = 6, - SPI_READ_MODE_FAST_READ = 7, -}; -/* - * SPI read mode is split into bits 18, 29, 30 such that [30:29:18] correspond to bits [2:0] for - * SpiReadMode. - */ -#define SPI_READ_MODE_MASK (BIT30 | BIT29 | BIT18) -#define SPI_READ_MODE_UPPER_BITS(x) ((((x) >> 1) & 0x3) << 29) -#define SPI_READ_MODE_LOWER_BITS(x) (((x) & 0x1) << 18) -#define SPI_READ_MODE(x) (SPI_READ_MODE_UPPER_BITS(x) | \ - SPI_READ_MODE_LOWER_BITS(x)) -#define SPI_ACCESS_MAC_ROM_EN BIT22 +#define SPI_FIFO 0x80 +#define SPI_FIFO_LAST_BYTE 0xc7 +#define SPI_FIFO_DEPTH (SPI_FIFO_LAST_BYTE - SPI_FIFO) -#define SPI100_ENABLE 0x20 -#define SPI_USE_SPI100 BIT0 - -/* Use SPI_SPEED_16M-SPI_SPEED_66M below for the southbridge */ -#define SPI100_SPEED_CONFIG 0x22 -enum spi100_speed { - SPI_SPEED_66M = 0, - SPI_SPEED_33M = 1, - SPI_SPEED_22M = 2, - SPI_SPEED_16M = 3, - SPI_SPEED_100M = 4, - SPI_SPEED_800K = 5, -}; - -#define SPI_SPEED_MASK 0xf -#define SPI_SPEED_MODE(x, shift) (((x) & SPI_SPEED_MASK) << shift) -#define SPI_NORM_SPEED(x) SPI_SPEED_MODE(x, 12) -#define SPI_FAST_SPEED(x) SPI_SPEED_MODE(x, 8) -#define SPI_ALT_SPEED(x) SPI_SPEED_MODE(x, 4) -#define SPI_TPM_SPEED(x) SPI_SPEED_MODE(x, 0) - -#define SPI_SPEED_CFG(n, f, a, t) (SPI_NORM_SPEED(n) | SPI_FAST_SPEED(f) | \ - SPI_ALT_SPEED(a) | SPI_TPM_SPEED(t)) - -#define SPI100_HOST_PREF_CONFIG 0x2c -#define SPI_RD4DW_EN_HOST BIT15 - -#define SPI_FIFO 0x80 -#define SPI_FIFO_LAST_BYTE 0xc7 -#define SPI_FIFO_DEPTH (SPI_FIFO_LAST_BYTE - SPI_FIFO) - -struct spi_config { - /* - * Default values if not overridden by mainboard: - * Read mode - Normal 33MHz - * Normal speed - 66MHz - * Fast speed - 66MHz - * Alt speed - 66MHz - * TPM speed - 66MHz - */ - enum spi_read_mode read_mode; - enum spi100_speed normal_speed; - enum spi100_speed fast_speed; - enum spi100_speed altio_speed; - enum spi100_speed tpm_speed; -}; - -#endif /* __AMDBLOCKS_SPI_H__ */ +#endif /* SPI_H */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index ba3d3d261863..1684cb16bd93 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -22,44 +22,43 @@ FchSPIUtil.h Fvb.c Fvb.h + FvbSPI.c + FvbSPI.h GenericSPI.c GenericSPI.h SPI.h - SPI_fvb.c - SPI_fvb.h - spi_flash_internal.c - spi_flash_internal.h + SPIFlashInternal.c + SPIFlashInternal.h [Packages] - MdePkg/MdePkg.dec - MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] BaseMemoryLib DebugLib - TimerLib - UefiDriverEntryPoint HobLib PciLib + TimerLib + UefiDriverEntryPoint [Guids] - gEdkiiNvVarStoreFormattedGuid + gUefiFvbSPIInfoGuid gEfiSMMSTOREInfoHobGuid - gEfiEventVirtualAddressChangeGuid [Protocols] - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize [Depex] TRUE diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.c b/UefiPayloadPkg/SPI/SPIFlashInternal.c similarity index 76% rename from UefiPayloadPkg/SPI/spi_flash_internal.c rename to UefiPayloadPkg/SPI/SPIFlashInternal.c index 4d2cdf4db3f6..924203307078 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.c +++ b/UefiPayloadPkg/SPI/SPIFlashInternal.c @@ -1,12 +1,12 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include #include -#include #include -#include "spi_flash_internal.h" +#include +#include +#include "FvbSPI.h" #include "GenericSPI.h" -#include "SPI_fvb.h" +#include "SPIFlashInternal.h" static VOID spi_flash_addr(UINT32 addr, UINT8 *cmd) { @@ -293,194 +293,6 @@ int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offse return ret; } -static const struct spi_flash_vendor_info *spi_flash_vendors[] = { -#ifdef SPI_FLASH_ADESTO - &spi_flash_adesto_vi, -#endif -#ifdef SPI_FLASH_AMIC - &spi_flash_amic_vi, -#endif -#ifdef SPI_FLASH_ATMEL - &spi_flash_atmel_vi, -#endif -#ifdef SPI_FLASH_EON - &spi_flash_eon_vi, -#endif -#ifdef SPI_FLASH_GIGADEVICE - &spi_flash_gigadevice_vi, -#endif -#ifdef SPI_FLASH_MACRONIX - &spi_flash_macronix_vi, -#endif -#ifdef SPI_FLASH_SPANSION - &spi_flash_spansion_ext1_vi, - &spi_flash_spansion_ext2_vi, - &spi_flash_spansion_vi, -#endif -#ifdef SPI_FLASH_SST - &spi_flash_sst_ai_vi, - &spi_flash_sst_vi, -#endif -#ifdef SPI_FLASH_STMICRO - &spi_flash_stmicro1_vi, - &spi_flash_stmicro2_vi, - &spi_flash_stmicro3_vi, - &spi_flash_stmicro4_vi, -#endif -#ifdef SPI_FLASH_WINBOND - &spi_flash_winbond_vi, -#endif -}; -#define IDCODE_LEN 5 - -static int fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash, - const struct spi_flash_vendor_info *vi, - const struct spi_flash_part_id *part) -{ - InternalMemCopyMem(&flash->spi, spi, sizeof(*spi)); - flash->vendor = vi->id; - flash->model = part->id[0]; - - flash->page_size = 1U << vi->page_size_shift; - flash->sector_size = (1U << vi->sector_size_kib_shift)*1024; - flash->size = flash->sector_size * (1U << part->nr_sectors_shift); - flash->erase_cmd = vi->desc->erase_cmd; - flash->status_cmd = vi->desc->status_cmd; - flash->pp_cmd = vi->desc->pp_cmd; - flash->wren_cmd = vi->desc->wren_cmd; - - flash->flags.dual_spi = part->fast_read_dual_output_support; - - flash->ops = &vi->desc->ops; - flash->prot_ops = vi->prot_ops; - flash->part = part; - - if (vi->after_probe) - return vi->after_probe(flash); - - return 0; -} - -static const struct spi_flash_part_id *find_part(const struct spi_flash_vendor_info *vi, - UINT16 id[2]) -{ - __SIZE_TYPE__ i; - const UINT16 lid[2] = { - [0] = id[0] & vi->match_id_mask[0], - [1] = id[1] & vi->match_id_mask[1], - }; - - - for (i = 0; i < vi->nr_part_ids; i++) { - const struct spi_flash_part_id *part = &vi->ids[i]; - - if (part->id[0] == lid[0] && part->id[1] == lid[1]) - return part; - } - - return NULL; -} - -static int find_match(const struct spi_slave *spi, struct spi_flash *flash, - UINT8 manuf_id, UINT16 id[2]) -{ - int i; - - for (i = 0; i < (int)ARRAY_SIZE(spi_flash_vendors); i++) { - const struct spi_flash_vendor_info *vi; - const struct spi_flash_part_id *part; - - vi = spi_flash_vendors[i]; - - if (manuf_id != vi->id) - continue; - - part = find_part(vi, id); - - if (part == NULL) - continue; - - return fill_spi_flash(spi, flash, vi, part); - } - - return -1; -} - -int spi_flash_generic_probe(const struct spi_slave *spi, - struct spi_flash *flash) -{ - int ret; - UINT8 idcode[IDCODE_LEN]; - UINT8 manuf_id; - UINT16 id[2]; - - /* Read the ID codes */ - ret = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); - if (ret) - return -1; - - manuf_id = idcode[0]; - - DEBUG((EFI_D_INFO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); - - /* If no result from RDID command and STMicro parts are enabled attempt - to wake the part from deep sleep and obtain alternative id info. */ -#ifdef SPI_FLASH_STMICRO - if(manuf_id == 0xff) { - if(stmicro_release_deep_sleep_identify(spi, idcode)) - return -1; - manuf_id = idcode[0]; - } -#endif - - id[0] = (idcode[1] << 8) | idcode[2]; - id[1] = (idcode[3] << 8) | idcode[4]; - - return find_match(spi, flash, manuf_id, id); -} - -int spi_flash_probe(unsigned int bus, unsigned int cs, struct spi_flash *flash) -{ - struct spi_slave spi; - int ret = -1; - - if (spi_setup_slave(bus, cs, &spi)) { - DEBUG((EFI_D_INFO, "%a SF: Failed to set up slave\n", __FUNCTION__)); - return -1; - } - - /* Try special programmer probe if any. */ - if (spi.ctrlr->flash_probe) - ret = spi.ctrlr->flash_probe(&spi, flash); - - /* If flash is not found, try generic spi flash probe. */ - if (ret) - ret = spi_flash_generic_probe(&spi, flash); - - /* Give up -- nothing more to try if flash is not found. */ - if (ret) { - DEBUG((EFI_D_INFO, "%a SF: Unsupported manufacturer!\n", __FUNCTION__)); - return -1; - } - - const char *mode_string = ""; - if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) - mode_string = " (Dual SPI mode)"; - DEBUG((EFI_D_INFO, - "%a SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", - __FUNCTION__, flash->vendor, flash->model, - flash->sector_size, flash->size, mode_string)); - /* - if (bus == CONFIG_BOOT_DEVICE_SPI_FLASH_BUS - && flash->size != CONFIG_ROM_SIZE) { - DEBUG((EFI_D_INFO, "%a SF size 0x%x does not correspond to" - " CONFIG_ROM_SIZE 0x%x!!\n", __FUNCTION__, flash->size, - CONFIG_ROM_SIZE)); - } - */ - return 0; -} - int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf) { diff --git a/UefiPayloadPkg/SPI/spi_flash_internal.h b/UefiPayloadPkg/SPI/SPIFlashInternal.h similarity index 99% rename from UefiPayloadPkg/SPI/spi_flash_internal.h rename to UefiPayloadPkg/SPI/SPIFlashInternal.h index 0c01d887eaa7..88b110ab6217 100644 --- a/UefiPayloadPkg/SPI/spi_flash_internal.h +++ b/UefiPayloadPkg/SPI/SPIFlashInternal.h @@ -8,7 +8,7 @@ #define SPI_FLASH_INTERNAL_H #include -#include "SPI_fvb.h" +#include "FvbSPI.h" /* Common commands */ #define CMD_READ_ID 0x9f @@ -33,7 +33,7 @@ #define REG_BLOCK_PROTECT_0_MASK 0x04 #define REG_BLOCK_PROTECT_1_MASK 0x08 #define REG_BLOCK_PROTECT_2_MASK 0x10 -#define REG_BLOCK_PROTECT_3_MASK 0x20 // FIXME this exists only on some winbond chips +#define REG_BLOCK_PROTECT_3_MASK 0x20 // FIXME this exists only on some Winbond chips #define REG_TOP_BOTTOM_PROTECTION_MASK 0x40 // FIXME on other chips T/B mask should be 0x40 #define REG_STATUS_REGISTER_PROTECTION_MASK 0x80 diff --git a/UefiPayloadPkg/SPI/SPI_fvb.c b/UefiPayloadPkg/SPI/SPI_fvb.c deleted file mode 100644 index b6d953fbd8b9..000000000000 --- a/UefiPayloadPkg/SPI/SPI_fvb.c +++ /dev/null @@ -1,92 +0,0 @@ -/** @file BlSMMStoreDxe.c - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "FchSPICtrl.h" -#include "GenericSPI.h" -#include "Fvb.h" -#include "spi_flash_internal.h" - -EFI_HANDLE Handle = NULL; -EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite,// FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks - NULL -}; - -EFI_STATUS checkBusyBit(UINT8 *Busy); - -EFI_STATUS EFIAPI SPIInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable -) { - EFI_STATUS Status; - struct spi_slave slave; - DEBUG((EFI_D_INFO, "SPI IS HERE\n")); - - DEBUG((EFI_D_INFO, "sizeof(unsigned int) 0x%X\n", sizeof(unsigned int))); - DEBUG((EFI_D_INFO, "sizeof(void *) 0x%X\n", sizeof(VOID *))); - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL - ); - if(EFI_ERROR (Status)) { - DEBUG((EFI_D_INFO, "%a Error during protocol installation\n", __FUNCTION__)); - } - spi_init(); - DEBUG((EFI_D_INFO, "spi_setup_slave() returned 0x%X\n", spi_setup_slave(0, 0, &slave))); - unsigned char fill[300] = {}; - UINTN length = 30; - FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); - DEBUG((EFI_D_INFO, "TRIALS\n")); - for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); - } - DEBUG((EFI_D_INFO, "ERASING\n")); - FvbEraseBlocks(&FvbProtocol, 0, 2, 4, 5, EFI_LBA_LIST_TERMINATOR); - FvbRead(&FvbProtocol, 0, 0, &length, (VOID *)fill); - for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)fill[i])); - } - DEBUG((EFI_D_INFO, "WRITING\n")); - UINT8 toWrite[] = {01, 0x01, 0x01, 0x77}; - UINTN writeLen = 4; - EFI_STATUS status = FvbWrite(&FvbProtocol, 0, 1, &writeLen, toWrite); - DEBUG((EFI_D_INFO, "Written: 0x%X\n", writeLen)); - if(status == EFI_SUCCESS) { - DEBUG((EFI_D_INFO, "EFI_SUCCESS\n")); - } else if(status == EFI_BAD_BUFFER_SIZE) { - DEBUG((EFI_D_INFO, "EFI_BAD_BUFFER_SIZE\n")); - } else if(status == EFI_ACCESS_DENIED) { - DEBUG((EFI_D_INFO, "EFI_ACCESS_DENIED\n")); - } else { - DEBUG((EFI_D_INFO, "It's really bad\n")); - } - unsigned char newFill[300] = {}; - UINTN newLength = 30; - FvbRead(&FvbProtocol, 0, 0, &newLength, (VOID *)newFill); - for(int i = 0; i < 10; i++) { - DEBUG((EFI_D_INFO, "%X %X\n", i, (UINTN)(UINT8)newFill[i])); - } - while(TRUE); - return EFI_SUCCESS; -} diff --git a/UefiPayloadPkg/SPI/winbond.c b/UefiPayloadPkg/SPI/Winbond.c similarity index 99% rename from UefiPayloadPkg/SPI/winbond.c rename to UefiPayloadPkg/SPI/Winbond.c index 8d7309023e8c..e7a2ac9048af 100644 --- a/UefiPayloadPkg/SPI/winbond.c +++ b/UefiPayloadPkg/SPI/Winbond.c @@ -1,9 +1,9 @@ -#include #include -#include "winbond.h" -#include "spi_flash_internal.h" +#include +#include "FvbSPI.h" #include "GenericSPI.h" -#include "SPI_fvb.h" +#include "SPIFlashInternal.h" +#include "Winbond.h" union status_reg1 { UINT8 u; diff --git a/UefiPayloadPkg/SPI/winbond.h b/UefiPayloadPkg/SPI/Winbond.h similarity index 61% rename from UefiPayloadPkg/SPI/winbond.h rename to UefiPayloadPkg/SPI/Winbond.h index bdf669430681..8ab1dc4122d9 100644 --- a/UefiPayloadPkg/SPI/winbond.h +++ b/UefiPayloadPkg/SPI/Winbond.h @@ -2,17 +2,17 @@ /* Winbond specific function */ /* M25Pxx-specific commands */ -#define CMD_W25_WREN 0x06 /* Write Enable */ -#define CMD_W25_WRDI 0x04 /* Write Disable */ -#define CMD_W25_RDSR 0x05 /* Read Status Register */ -#define CMD_W25_WRSR 0x01 /* Write Status Register */ -#define CMD_W25_RDSR2 0x35 /* Read Status2 Register */ -#define CMD_W25_WRSR2 0x31 /* Write Status2 Register */ -#define CMD_W25_READ 0x03 /* Read Data Bytes */ +#define CMD_W25_WREN 0x06 /* Write Enable */ +#define CMD_W25_WRDI 0x04 /* Write Disable */ +#define CMD_W25_RDSR 0x05 /* Read Status Register */ +#define CMD_W25_WRSR 0x01 /* Write Status Register */ +#define CMD_W25_RDSR2 0x35 /* Read Status2 Register */ +#define CMD_W25_WRSR2 0x31 /* Write Status2 Register */ +#define CMD_W25_READ 0x03 /* Read Data Bytes */ #define CMD_W25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */ #define CMD_W25_PP 0x02 /* Page Program */ #define CMD_W25_SE 0x20 /* Sector (4K) Erase */ -#define CMD_W25_RDID 0x9f /* Read ID */ +#define CMD_W25_RDID 0x9f /* Read ID */ #define CMD_W25_BE 0xd8 /* Block (64K) Erase */ #define CMD_W25_CE 0xc7 /* Chip Erase */ #define CMD_W25_DP 0xb9 /* Deep Power-down */ diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 2613daa52474..bf1d0a3eabb8 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -30,11 +30,12 @@ # gBmpImageGuid = { 0x878AC2CC, 0x5343, 0x46F2, { 0xB5, 0x63, 0x51, 0xF8, 0x9D, 0xAF, 0x56, 0xBA } } - gUefiSystemTableInfoGuid = {0x16c8a6d0, 0xfe8a, 0x4082, {0xa2, 0x8, 0xcf, 0x89, 0xc4, 0x29, 0x4, 0x33}} - gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x6, 0xd9, 0xf}} - gUefiSerialPortInfoGuid = { 0x6c6872fe, 0x56a9, 0x4403, { 0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1 } } - gLoaderMemoryMapInfoGuid = { 0xa1ff7424, 0x7a1a, 0x478e, { 0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32 } } + gUefiSystemTableInfoGuid = {0x16c8a6d0, 0xfe8a, 0x4082, {0xa2, 0x08, 0xcf, 0x89, 0xc4, 0x29, 0x04, 0x33}} + gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x06, 0xd9, 0x0f}} + gUefiSerialPortInfoGuid = {0x6c6872fe, 0x56a9, 0x4403, {0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1}} + gLoaderMemoryMapInfoGuid = {0xa1ff7424, 0x7a1a, 0x478e, {0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32}} gEfiSMMSTOREInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 }} + gUefiFvbSPIInfoGuid = {0x7d3b6dea, 0xd358, 0x440e, {0xb3, 0x5d, 0x36, 0x2f, 0x09, 0xf2, 0x8f, 0xec}} [Ppis] gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} } diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index cb7d787f0f25..001fc738532b 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -83,16 +83,12 @@ APRIORI DXE { INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf - !if $(BOOTLOADER) == "COREBOOT" - # Initialize VariableStore and update PCDs before VariableRuntimeDxe - INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf - !endif + INF UefiPayloadPkg/SPI/SPI.inf # Init Test Driver before Secure Boot # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf } -INF UefiPayloadPkg/SPI/SPI.inf # # DXE Phase modules @@ -127,9 +123,7 @@ INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf INF MdeModulePkg/Logo/LogoDxe.inf -!if $(BOOTLOADER) == "COREBOOT" - INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif +INF UefiPayloadPkg/SPI/SPI.inf # # PCI Support diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index e9b22230902e..bf6bf6242a69 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -249,12 +249,6 @@ AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif -!if $(BOOTLOADER) == "COREBOOT" - SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf -!else - SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf -!endif - !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf @@ -626,11 +620,6 @@ !endif UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf - # SMMSTORE - # - !if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf - !endif # # Network Support diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 0436b1804530..7faf2edf169a 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc @@ -257,11 +257,6 @@ !else AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif -!if $(BOOTLOADER) == "COREBOOT" - SmmStoreLib|UefiPayloadPkg/Library/CbSMMStoreLib/CbSMMStoreLib.inf -!else - SmmStoreLib|UefiPayloadPkg/Library/SblSMMStoreLib/SblSMMStoreLib.inf -!endif !if $(TPM_ENABLE) == TRUE Tpm12CommandLib|SecurityPkg/Library/Tpm12CommandLib/Tpm12CommandLib.inf @@ -630,13 +625,6 @@ UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf - # - # SMMSTORE - # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif - # # Network Support # From 23452e0c404e0107a1d2264c1b4a0648030894f1 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Tue, 20 Oct 2020 14:54:10 +0200 Subject: [PATCH 266/297] UefiPayloadPkg/SPI/Fvb.c: Start implementing VariableStoreHeaders --- .../Variable/RuntimeDxe/VariableDxe.c | 1 + UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c | 16 +- UefiPayloadPkg/BlSupportPei/BlSupportPei.h | 2 +- UefiPayloadPkg/Include/Library/BlParseLib.h | 12 +- .../Library/CbParseLib/CbParseLib.c | 66 ++-- .../Library/SblParseLib/SblParseLib.c | 16 +- UefiPayloadPkg/SPI/Fvb.c | 196 +++++++++++- UefiPayloadPkg/SPI/Fvb.h | 4 +- UefiPayloadPkg/SPI/FvbSPI.c | 297 +++--------------- UefiPayloadPkg/SPI/SPI.inf | 4 +- UefiPayloadPkg/UefiPayloadPkg.dec | 2 +- UefiPayloadPkg/UefiPayloadPkg.fdf | 2 +- 12 files changed, 295 insertions(+), 323 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c index 7d2b6c8e1fad..421bf8ce47cf 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c @@ -490,6 +490,7 @@ VariableServiceInitialize ( EFI_EVENT EndOfDxeEvent; Status = VariableCommonInitialize (); + DEBUG ((DEBUG_WARN, "HIHO\n")); ASSERT_EFI_ERROR (Status); Status = gBS->InstallMultipleProtocolInterfaces ( diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index cdd0a23bd9cd..7decbea0414c 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c @@ -156,6 +156,10 @@ BlSMMSTOREInitialise ( IN EFI_SYSTEM_TABLE *SystemTable ) { + DEBUG ((DEBUG_WARN, "BLAH BlSMMSTOREInitialise.\n")); + while(1); + return EFI_SUCCESS; + ////////////////////////////////////////////// EFI_STATUS Status; VOID *ComBuf; VOID *GuidHob; @@ -220,12 +224,12 @@ BlSMMSTOREInitialise ( } // Update PCDs for Variable/RuntimeDxe - PcdSet32S (PcdFlashNvStorageVariableBase, - PcdGet32 (PcdFlashNvStorageVariableBase) + SMMStoreInfoHob->MmioAddress); - PcdSet32S (PcdFlashNvStorageFtwWorkingBase, - PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + SMMStoreInfoHob->MmioAddress); - PcdSet32S (PcdFlashNvStorageFtwSpareBase, - PcdGet32 (PcdFlashNvStorageFtwSpareBase) + SMMStoreInfoHob->MmioAddress); + PcdSet32S(PcdFlashNvStorageVariableBase, + PcdGet32(PcdFlashNvStorageVariableBase) + SMMStoreInfoHob->MmioAddress); + PcdSet32S(PcdFlashNvStorageFtwWorkingBase, + PcdGet32(PcdFlashNvStorageFtwWorkingBase) + SMMStoreInfoHob->MmioAddress); + PcdSet32S(PcdFlashNvStorageFtwSpareBase, + PcdGet32(PcdFlashNvStorageFtwSpareBase) + SMMStoreInfoHob->MmioAddress); mSMMStoreInstance = AllocateRuntimePool (sizeof(SMMSTORE_INSTANCE*)); if (!mSMMStoreInstance) { diff --git a/UefiPayloadPkg/BlSupportPei/BlSupportPei.h b/UefiPayloadPkg/BlSupportPei/BlSupportPei.h index 705667627d7a..0100af216c98 100644 --- a/UefiPayloadPkg/BlSupportPei/BlSupportPei.h +++ b/UefiPayloadPkg/BlSupportPei/BlSupportPei.h @@ -28,7 +28,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent #include #include #include -#include +// #include #include #include diff --git a/UefiPayloadPkg/Include/Library/BlParseLib.h b/UefiPayloadPkg/Include/Library/BlParseLib.h index 542c714c555b..ffd7e8d48597 100644 --- a/UefiPayloadPkg/Include/Library/BlParseLib.h +++ b/UefiPayloadPkg/Include/Library/BlParseLib.h @@ -12,7 +12,7 @@ #include #include #include -#include +// #include #ifndef __BOOTLOADER_PARSE_LIB__ #define __BOOTLOADER_PARSE_LIB__ @@ -127,10 +127,10 @@ ParseGfxDeviceInfo ( @retval RETURN_NOT_FOUND Failed to find the SMM store buffer information . **/ -RETURN_STATUS -EFIAPI -ParseSMMSTOREInfo ( - OUT SMMSTORE_INFO *SMMSTOREInfo - ); +// RETURN_STATUS +// EFIAPI +// ParseSMMSTOREInfo ( +// OUT SMMSTORE_INFO *SMMSTOREInfo +// ); #endif diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c index 0692e0b8004e..8bb7a581e4e5 100644 --- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -595,36 +595,36 @@ ParseGfxDeviceInfo ( @retval RETURN_NOT_FOUND Failed to find the SMM store buffer information . **/ -RETURN_STATUS -EFIAPI -ParseSMMSTOREInfo ( - OUT SMMSTORE_INFO *SMMSTOREInfo - ) -{ - struct cb_smmstorev2 *CbSSRec; - - if (SMMSTOREInfo == NULL) { - return RETURN_INVALID_PARAMETER; - } - - CbSSRec = FindCbTag (CB_TAG_SMMSTOREV2); - if (CbSSRec == NULL) { - return RETURN_NOT_FOUND; - } - - DEBUG ((DEBUG_INFO, "Found SMM Store information\n")); - DEBUG ((DEBUG_INFO, "block size: 0x%x\n", CbSSRec->block_size)); - DEBUG ((DEBUG_INFO, "number of blocks: 0x%x\n", CbSSRec->num_blocks)); - DEBUG ((DEBUG_INFO, "communication buffer: 0x%x\n", CbSSRec->com_buffer)); - DEBUG ((DEBUG_INFO, "communication buffer size: 0x%x\n", CbSSRec->com_buffer_size)); - DEBUG ((DEBUG_INFO, "MMIO address of store: 0x%x\n", CbSSRec->mmap_addr)); - - SMMSTOREInfo->ComBuffer = CbSSRec->com_buffer; - SMMSTOREInfo->ComBufferSize = CbSSRec->com_buffer_size; - SMMSTOREInfo->BlockSize = CbSSRec->block_size; - SMMSTOREInfo->NumBlocks = CbSSRec->num_blocks; - SMMSTOREInfo->MmioAddress = CbSSRec->mmap_addr; - SMMSTOREInfo->ApmCmd = CbSSRec->apm_cmd; - - return RETURN_SUCCESS; -} +// RETURN_STATUS +// EFIAPI +// ParseSMMSTOREInfo ( +// OUT SMMSTORE_INFO *SMMSTOREInfo +// ) +// { +// struct cb_smmstorev2 *CbSSRec; + +// if (SMMSTOREInfo == NULL) { +// return RETURN_INVALID_PARAMETER; +// } + +// CbSSRec = FindCbTag (CB_TAG_SMMSTOREV2); +// if (CbSSRec == NULL) { +// return RETURN_NOT_FOUND; +// } + +// DEBUG ((DEBUG_INFO, "Found SMM Store information\n")); +// DEBUG ((DEBUG_INFO, "block size: 0x%x\n", CbSSRec->block_size)); +// DEBUG ((DEBUG_INFO, "number of blocks: 0x%x\n", CbSSRec->num_blocks)); +// DEBUG ((DEBUG_INFO, "communication buffer: 0x%x\n", CbSSRec->com_buffer)); +// DEBUG ((DEBUG_INFO, "communication buffer size: 0x%x\n", CbSSRec->com_buffer_size)); +// DEBUG ((DEBUG_INFO, "MMIO address of store: 0x%x\n", CbSSRec->mmap_addr)); + +// SMMSTOREInfo->ComBuffer = CbSSRec->com_buffer; +// SMMSTOREInfo->ComBufferSize = CbSSRec->com_buffer_size; +// SMMSTOREInfo->BlockSize = CbSSRec->block_size; +// SMMSTOREInfo->NumBlocks = CbSSRec->num_blocks; +// SMMSTOREInfo->MmioAddress = CbSSRec->mmap_addr; +// SMMSTOREInfo->ApmCmd = CbSSRec->apm_cmd; + +// return RETURN_SUCCESS; +// } diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c index 6354ef2b030c..61b8245f54ff 100644 --- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c +++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c @@ -247,11 +247,11 @@ ParseGfxDeviceInfo ( @retval RETURN_NOT_FOUND Failed to find the SMM store buffer information . **/ -RETURN_STATUS -EFIAPI -ParseSMMSTOREInfo ( - OUT SMMSTORE_INFO *SMMSTOREInfo - ) -{ - return RETURN_NOT_FOUND; -} +// RETURN_STATUS +// EFIAPI +// ParseSMMSTOREInfo ( +// OUT SMMSTORE_INFO *SMMSTOREInfo +// ) +// { +// return RETURN_NOT_FOUND; +// } diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 907fef05ac07..6fdfd6979302 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -1,5 +1,7 @@ +#include #include #include +#include #include "Fvb.h" #include "FvbSPI.h" #include "GenericSPI.h" @@ -337,11 +339,80 @@ static EFI_STATUS ReadArray(CONST UINTN Address, UINT8 *Buffer, UINTN *NumBytes) **/ EFI_STATUS InitializeFvAndVariableStoreHeaders ( - IN SMMSTORE_INSTANCE *Instance + IN FVBSPI_INFO *Instance ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_SUCCESS; + EFI_STATUS Status; + VOID* Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); + Headers = AllocateZeroPool(HeadersLength); + + // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + + // Check if the size of the area is at least one block size + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->BlockSize > 0)); + + // Ensure the Variable area Base Addresses are aligned on a block size boundaries + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->BlockSize == 0); + + // + // EFI_FIRMWARE_VOLUME_HEADER + // + FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; + CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); + FirmwareVolumeHeader->FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; + FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled + ); + FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); + FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; + FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->NumBlocks; + FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize; + FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; + FirmwareVolumeHeader->BlockMap[1].Length = 0; + FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); + DEBUG((EFI_D_INFO, "%a checksum = 0x%X\n", __FUNCTION__, FirmwareVolumeHeader->Checksum)); + + // + // VARIABLE_STORE_HEADER + // + VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); + CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; + VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; + VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; + + // Install the combined super-header in the store + Status = FvbEraseBlocks(NULL, 0, 1, EFI_LBA_LIST_TERMINATOR); + if(Status != EFI_SUCCESS) { + DEBUG((EFI_D_INFO, "%a Erase failed\n", __FUNCTION__)); + return Status; + } + Status = FvbWrite(NULL, 0, 0, &HeadersLength, Headers); + + FreePool (Headers); + return Status; } /** @@ -354,11 +425,115 @@ InitializeFvAndVariableStoreHeaders ( **/ EFI_STATUS -ValidateFvHeader ( - IN SMMSTORE_INSTANCE *Instance - ) -{ +ValidateFvHeader (IN FVBSPI_INFO *Instance) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINT16 Checksum; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINTN VariableStoreLength; + UINTN FvLength; + EFI_STATUS TempStatus; + UINTN BufferSize; + UINTN BufferSizeReqested; + + BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = FvbRead(NULL, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ( (FwVolHeader->Revision != EFI_FVH_REVISION) + || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength != FvLength) + ) + { + DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", + __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + // Check the Firmware Volume Guid + if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { + DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = FwVolHeader->HeaderLength; + FreePool (FwVolHeader); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = FvbRead(NULL, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + // Verify the header checksum + DEBUG ((EFI_D_INFO, "%a: FwVolHeader->HeaderLength = 0x%X\n", __FUNCTION__, FwVolHeader->HeaderLength)); + Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); + DEBUG((EFI_D_INFO, "%a checksum = 0x%X\n", __FUNCTION__, Checksum)); + if (Checksum != 0) { + DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", + __FUNCTION__, Checksum)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); + VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); + if (!VariableStoreHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = FvbRead(NULL, 0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (VariableStoreHeader); + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + // Check the Variable Store Guid + if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && + !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; + if (VariableStoreHeader->Size != VariableStoreLength) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_SUCCESS; } @@ -539,6 +714,7 @@ FvbRead ( IN OUT UINT8 *Buffer ) { + DEBUG((EFI_D_INFO, "%a(This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X)\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); UINTN address = ADDRESS(Lba, Offset); UINTN numberOfBytesToRead = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); UINTN numberOfBytesRead = 0; @@ -566,6 +742,9 @@ FvbRead ( *NumBytes = numberOfBytesToRead; return EFI_BAD_BUFFER_SIZE; } + for(UINTN counter = 0; counter < *NumBytes; ++counter) { + DEBUG((EFI_D_INFO, "%a 0x%X\n", __FUNCTION__, (UINTN)Buffer[counter])); + } return EFI_SUCCESS; } @@ -634,6 +813,10 @@ FvbWrite ( IN UINT8 *Buffer ) { + DEBUG((EFI_D_INFO, "%a(This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X)\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); + for(UINTN counter = 0; counter < *NumBytes; ++counter) { + DEBUG((EFI_D_INFO, "%a 0x%X\n", __FUNCTION__, (UINTN)Buffer[counter])); + } CONST UINTN numberOfBytesToWrite = MIN( *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset) ); @@ -718,6 +901,7 @@ FvbEraseBlocks ( ... ) { + DEBUG((EFI_D_INFO, "%a(This = 0x%X)\n", __FUNCTION__, This)); EFI_STATUS status = EFI_SUCCESS; VA_LIST Args; VA_START(Args, This); diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index 3fe92185154c..b06803185032 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -10,12 +10,12 @@ EFI_STATUS InitializeFvAndVariableStoreHeaders ( - IN SMMSTORE_INSTANCE *Instance + IN FVBSPI_INFO *Instance ); EFI_STATUS ValidateFvHeader ( - IN SMMSTORE_INSTANCE *Instance + IN FVBSPI_INFO *Instance ); EFI_STATUS diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c index 7422b61bce16..599cbc466979 100644 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -38,267 +38,48 @@ EFI_STATUS checkBusyBit(UINT8 *Busy); EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable - // IN SMMSTORE_INFO *FvbSPIInfoHob -) { EFI_STATUS Status; - VOID *ComBuf; - VOID *GuidHob; - SMMSTORE_INFO *SMMStoreInfoHob; - EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; - - if (PcdGetBool (PcdEmuVariableNvModeEnable)) { - DEBUG ((DEBUG_WARN, "Variable emulation is active! Skipping driver init.\n")); - while(1); - return EFI_SUCCESS; - } - - // - // Find the SMMSTORE information guid hob - // - GuidHob = GetFirstGuidHob (&gEfiSMMSTOREInfoHobGuid); - // GuidHob = NULL; - if (GuidHob == NULL) { - DEBUG ((DEBUG_WARN, "SMMSTORE not supported! Skipping driver init.\n")); - PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); +) { + DEBUG((DEBUG_WARN, "SPI IS HERE.\n")); + FVBSPI_INFO fvbSPIInfo = { + .ComBuffer = 0, + .ComBufferSize = 0, + .NumBlocks = 4, + .BlockSize = BLOCK_SIZE, + .MmioAddress = 0xFF860000, + .ApmCmd = 0 + }; + DEBUG ((DEBUG_WARN, "SPI IS HERE.\n")); + if (PcdGetBool(PcdEmuVariableNvModeEnable)) { + DEBUG (( + DEBUG_WARN, + "Variable emulation is active! Skipping driver init.\n")); while(1); return EFI_SUCCESS; } - - // - // Allocate Communication Buffer for arguments to pass to SMM - // - ComBuf = AllocateRuntimePool (SMMSTORE_COMBUF_SIZE); - if (!ComBuf) { - PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); - while(1); - return EFI_OUT_OF_RESOURCES; - } - - // - // Place SMMSTORE information hob in a runtime buffer - // - SMMStoreInfoHob = AllocateRuntimePool (GET_GUID_HOB_DATA_SIZE(GuidHob)); - if (!SMMStoreInfoHob) { - FreePool(ComBuf); - PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); - while(1); - return EFI_OUT_OF_RESOURCES; - } - - CopyMem(SMMStoreInfoHob, GET_GUID_HOB_DATA (GuidHob), GET_GUID_HOB_DATA_SIZE(GuidHob)); - - if (!SMMStoreInfoHob->MmioAddress || - !SMMStoreInfoHob->ComBuffer || - !SMMStoreInfoHob->BlockSize || - !SMMStoreInfoHob->NumBlocks) { - DEBUG((EFI_D_ERROR, "%a: Invalid data in SMMStore Info hob\n", __FUNCTION__)); - FreePool(ComBuf); - FreePool(SMMStoreInfoHob); - while(1); - return EFI_WRITE_PROTECTED; - } - - Status = SMMStoreInitialize(ComBuf, SMMStoreInfoHob); - if (EFI_ERROR(Status)) { - DEBUG((EFI_D_ERROR,"%a: Failed to initialize SMMStore\n", - __FUNCTION__)); - PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); - FreePool(ComBuf); - FreePool(SMMStoreInfoHob); - while(1); - return Status; - } - - // // Update PCDs for Variable/RuntimeDxe - // PcdSet32S (PcdFlashNvStorageVariableBase, - // PcdGet32 (PcdFlashNvStorageVariableBase) + SMMStoreInfoHob->MmioAddress); - // PcdSet32S (PcdFlashNvStorageFtwWorkingBase, - // PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + SMMStoreInfoHob->MmioAddress); - // PcdSet32S (PcdFlashNvStorageFtwSpareBase, - // PcdGet32 (PcdFlashNvStorageFtwSpareBase) + SMMStoreInfoHob->MmioAddress); - - // mSMMStoreInstance = AllocateRuntimePool (sizeof(SMMSTORE_INSTANCE*)); - // if (!mSMMStoreInstance) { - // DEBUG((EFI_D_ERROR, "%a: Out of resources\n", __FUNCTION__)); - // FreePool(ComBuf); - // FreePool(SMMStoreInfoHob); - // PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); - // return EFI_OUT_OF_RESOURCES; - // } - - // Status = SMMStoreCreateInstance ( - // SMMStoreInfoHob->NumBlocks, - // SMMStoreInfoHob->BlockSize, - // &mSMMStoreInstance - // ); - if (EFI_ERROR(Status)) { - DEBUG((EFI_D_ERROR, "%a: Fail to create instance for SMMStore\n", - __FUNCTION__)); - PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); - FreePool(ComBuf); - FreePool(SMMStoreInfoHob); - while(1); - return Status; - } - - // - // Register for the virtual address change event - // - // Status = gBS->CreateEventEx ( - // EVT_NOTIFY_SIGNAL, - // TPL_NOTIFY, - // BlSMMStoreVirtualNotifyEvent, - // NULL, - // &gEfiEventVirtualAddressChangeGuid, - // &mSMMStoreVirtualAddrChangeEvent - // ); - ASSERT_EFI_ERROR (Status); - - // - // Finally mark the SMM communication buffer provided by CB or SBL as runtime memory - // - Status = gDS->GetMemorySpaceDescriptor (SMMStoreInfoHob->ComBuffer, &GcdDescriptor); - if (EFI_ERROR (Status) || GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeReserved) { - DEBUG((EFI_D_INFO, "%a: No memory space descriptor for com buffer found\n", - __FUNCTION__)); - - // - // Add a new entry if not covered by existing mapping - // - Status = gDS->AddMemorySpace ( - EfiGcdMemoryTypeReserved, - SMMStoreInfoHob->ComBuffer, SMMStoreInfoHob->ComBufferSize, - EFI_MEMORY_WB | EFI_MEMORY_RUNTIME - ); - ASSERT_EFI_ERROR (Status); - } - - // - // Mark as runtime service - // - Status = gDS->SetMemorySpaceAttributes ( - SMMStoreInfoHob->ComBuffer, - SMMStoreInfoHob->ComBufferSize, - EFI_MEMORY_RUNTIME - ); - ASSERT_EFI_ERROR (Status); - - if (!SMMStoreInfoHob->MmioAddress){ + EFI_STATUS Status; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, + NULL); + if(EFI_ERROR (Status)) { + DEBUG(( + EFI_D_INFO, + "%a Error during protocol installation.\n", __FUNCTION__)); + PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); while(1); - return Status; + return EFI_PROTOCOL_ERROR; } - - // - // Mark the memory mapped store as MMIO memory - // - Status = gDS->GetMemorySpaceDescriptor (SMMStoreInfoHob->MmioAddress, &GcdDescriptor); - if (EFI_ERROR (Status) || GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { - DEBUG((EFI_D_INFO, "%a: No memory space descriptor for com buffer found\n", - __FUNCTION__)); - - // - // Add a new entry if not covered by existing mapping - // - Status = gDS->AddMemorySpace ( - EfiGcdMemoryTypeMemoryMappedIo, - SMMStoreInfoHob->MmioAddress, - SMMStoreInfoHob->NumBlocks * SMMStoreInfoHob->BlockSize, - EFI_MEMORY_UC | EFI_MEMORY_RUNTIME - ); - ASSERT_EFI_ERROR (Status); - } - - // - // Mark as runtime service - // - Status = gDS->SetMemorySpaceAttributes ( - SMMStoreInfoHob->MmioAddress, - SMMStoreInfoHob->NumBlocks * SMMStoreInfoHob->BlockSize, - EFI_MEMORY_RUNTIME - ); - ASSERT_EFI_ERROR (Status); - - while(1); - return Status; - /////////////////////////////////////////////////////////////////////////////// - // DEBUG((DEBUG_WARN, "SPI IS HERE.\n")); - // SMMSTORE_INFO *FvbSPIInfoHob; - // SMMSTORE_INFO *NewFvbSPIInfoHob; - // VOID *GuidHob; - // if (PcdGetBool(PcdEmuVariableNvModeEnable)) { - // DEBUG (( - // DEBUG_WARN, - // "Variable emulation is active! Skipping driver init.\n")); - // while(1); - // return EFI_SUCCESS; - // } - - // // - // // Create guid hob for SMMSTORE - // // - // // Status = ParseSMMSTOREInfo (&SMMSTOREInfo); - // // if (!EFI_ERROR (Status)) { - // // NewSMMSTOREInfo = BuildGuidHob (&gEfiSMMSTOREInfoHobGuid, sizeof (SMMSTOREInfo)); - // // ASSERT (NewSMMSTOREInfo != NULL); - // // CopyMem (NewSMMSTOREInfo, &SMMSTOREInfo, sizeof (SMMSTOREInfo)); - // // DEBUG ((DEBUG_INFO, "Created SMMSTORE info hob\n")); - // // } - - // FVBSPI_INFO fvbSPIInfo = { - // .ComBuffer = 0, - // .ComBufferSize = 0, - // .NumBlocks = 0, - // .BlockSize = 0, - // .MmioAddress = 0, - // .ApmCmd = 0 - // }; - // DEBUG((DEBUG_WARN, "&gUefiFvbSPIInfoGuid = 0x%X, sizeof(FVBSPI_INFO) = 0x%X\n", &gUefiFvbSPIInfoGuid, sizeof(FVBSPI_INFO))); - // NewFvbSPIInfoHob = BuildGuidHob(&gUefiFvbSPIInfoGuid, sizeof(FVBSPI_INFO)); - // CopyMem(NewFvbSPIInfoHob, &fvbSPIInfo, sizeof(FVBSPI_INFO)); - // DEBUG((DEBUG_INFO, "Created hob\n")); - - // FvbSPIInfoHob = GetFirstGuidHob(&gUefiFvbSPIInfoGuid); - // DEBUG((DEBUG_WARN, "FvbSPIInfoHob = 0x%X\n", FvbSPIInfoHob)); - // if (GuidHob == NULL) { - // DEBUG ((DEBUG_WARN, "FvbSPI not supported! Skipping driver init.\n")); - // PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); - // while(1); - // return EFI_SUCCESS; - // } - - // // - // // Place FvbSPI information hob in a runtime buffer - // // - // FvbSPIInfoHob = AllocateRuntimePool(GET_GUID_HOB_DATA_SIZE(GuidHob)); - // if (!FvbSPIInfoHob) { - // DEBUG(( - // EFI_D_INFO, - // "%a Memory allocation failed.\n", __FUNCTION__)); - // PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); - // while(1); - // return EFI_OUT_OF_RESOURCES; - // } - // EFI_STATUS Status; - // Status = gBS->InstallMultipleProtocolInterfaces ( - // &Handle, - // &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - // NULL); - // if(EFI_ERROR (Status)) { - // DEBUG(( - // EFI_D_INFO, - // "%a Error during protocol installation.\n", __FUNCTION__)); - // FreePool(FvbSPIInfoHob); - // PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); - // while(1); - // return EFI_PROTOCOL_ERROR; - // } - // // Update PCDs for Variable/RuntimeDxe - // // PcdSet32S (PcdFlashNvStorageVariableBase, - // // PcdGet32 (PcdFlashNvStorageVariableBase) + FvbSPIInfoHob->MmioAddress); - // // PcdSet32S (PcdFlashNvStorageFtwWorkingBase, - // // PcdGet32 (PcdFlashNvStorageFtwWorkingBase) + FvbSPIInfoHob->MmioAddress); - // // PcdSet32S (PcdFlashNvStorageFtwSpareBase, - // // PcdGet32 (PcdFlashNvStorageFtwSpareBase) + FvbSPIInfoHob->MmioAddress); - // spi_init(); - // while(1); - // return EFI_SUCCESS; + // Update PCDs for Variable/RuntimeDxe + PcdSet32S(PcdFlashNvStorageVariableBase, + PcdGet32(PcdFlashNvStorageVariableBase) + fvbSPIInfo.MmioAddress); + PcdSet32S(PcdFlashNvStorageFtwWorkingBase, + PcdGet32(PcdFlashNvStorageFtwWorkingBase) + fvbSPIInfo.MmioAddress); + PcdSet32S(PcdFlashNvStorageFtwSpareBase, + PcdGet32(PcdFlashNvStorageFtwSpareBase) + fvbSPIInfo.MmioAddress); + spi_init(); + Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); + DEBUG((DEBUG_WARN, "InitializeFvAndVariableStoreHeaders(&fvbSPIInfo) = 0x%X\n", Status)); + Status = ValidateFvHeader(&fvbSPIInfo); + DEBUG((DEBUG_WARN, "ValidateFvHeader(&fvbSPIInfo) = 0x%X\n", Status)); + return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 1684cb16bd93..6cb2e1ada3e0 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -45,8 +45,10 @@ UefiDriverEntryPoint [Guids] + gEfiAuthenticatedVariableGuid + gEfiSystemNvDataFvGuid + gEfiVariableGuid gUefiFvbSPIInfoGuid - gEfiSMMSTOREInfoHobGuid [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index bf1d0a3eabb8..2d256a264cd5 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -34,7 +34,7 @@ gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x06, 0xd9, 0x0f}} gUefiSerialPortInfoGuid = {0x6c6872fe, 0x56a9, 0x4403, {0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1}} gLoaderMemoryMapInfoGuid = {0xa1ff7424, 0x7a1a, 0x478e, {0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32}} - gEfiSMMSTOREInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 }} + # gEfiSMMSTOREInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 }} gUefiFvbSPIInfoGuid = {0x7d3b6dea, 0xd358, 0x440e, {0xb3, 0x5d, 0x36, 0x2f, 0x09, 0xf2, 0x8f, 0xec}} [Ppis] diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 001fc738532b..082184c98819 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -320,7 +320,7 @@ INF RuleOverride = BINARY USE = X64 ShellBinPkg/UefiShell/UefiShell.inf # GetNonVolatileMaxVariableSize () < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) DEFINE BLOCK_SIZE = 0x10000 -SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = 0 +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = 0xFF860000 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = $(BLOCK_SIZE) SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize From aa1da81bbaf77b9622a685366b66c997020b932f Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 21 Oct 2020 09:35:57 +0200 Subject: [PATCH 267/297] UefiPayloadPkg/SPI/Fvb.c: style changes --- UefiPayloadPkg/SPI/Fvb.c | 143 +++++++++++++++++++----------------- UefiPayloadPkg/SPI/FvbSPI.c | 15 +++- 2 files changed, 86 insertions(+), 72 deletions(-) diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 6fdfd6979302..f0456ce038e9 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -162,6 +162,7 @@ static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args) { if(Lba == EFI_LBA_LIST_TERMINATOR) { break; } + DEBUG((EFI_D_INFO, "%a ERASING: Lba = 0x%X Count = 0x%X\n", __FUNCTION__, Lba, LbaCount)); if(FvbEraseConsecutiveBlocks(Lba, LbaCount) != EFI_SUCCESS) { status = EFI_DEVICE_ERROR; } @@ -338,33 +339,30 @@ static EFI_STATUS ReadArray(CONST UINTN Address, UINT8 *Buffer, UINTN *NumBytes) **/ EFI_STATUS -InitializeFvAndVariableStoreHeaders ( - IN FVBSPI_INFO *Instance - ) -{ +InitializeFvAndVariableStoreHeaders(IN FVBSPI_INFO *Instance) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - VOID* Headers; - UINTN HeadersLength; - EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; + EFI_STATUS Status; + VOID* Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); Headers = AllocateZeroPool(HeadersLength); // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); // Check if the size of the area is at least one block size - ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->BlockSize > 0)); // Ensure the Variable area Base Addresses are aligned on a block size boundaries - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->BlockSize == 0); // // EFI_FIRMWARE_VOLUME_HEADER @@ -372,18 +370,18 @@ InitializeFvAndVariableStoreHeaders ( FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); FirmwareVolumeHeader->FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled + EFI_FVB2_READ_ENABLED_CAP // Reads may be enabled + | EFI_FVB2_READ_STATUS // Reads are currently enabled + | EFI_FVB2_STICKY_WRITE // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + | EFI_FVB2_MEMORY_MAPPED // It is memory mapped + | EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') + | EFI_FVB2_WRITE_STATUS // Writes are currently enabled + | EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled ); FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; @@ -409,9 +407,16 @@ InitializeFvAndVariableStoreHeaders ( DEBUG((EFI_D_INFO, "%a Erase failed\n", __FUNCTION__)); return Status; } + UINTN len = 0x64; + UINT8 buff[0x64] = {}; + DEBUG((EFI_D_INFO, "%a PAY ATTENTION\n", __FUNCTION__)); + FvbRead(NULL, 0, 0, &len, buff); Status = FvbWrite(NULL, 0, 0, &HeadersLength, Headers); + FvbRead(NULL, 0, 0, &len, buff); FreePool (Headers); + DEBUG((EFI_D_INFO, "%a Initialized. Now checking\n", __FUNCTION__)); + ValidateFvHeader(Instance); return Status; } @@ -425,7 +430,7 @@ InitializeFvAndVariableStoreHeaders ( **/ EFI_STATUS -ValidateFvHeader (IN FVBSPI_INFO *Instance) { +ValidateFvHeader(IN FVBSPI_INFO *Instance) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINT16 Checksum; EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; @@ -437,62 +442,62 @@ ValidateFvHeader (IN FVBSPI_INFO *Instance) { UINTN BufferSizeReqested; BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); - if (!FwVolHeader) { + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested+64); + if(!FwVolHeader) { return EFI_OUT_OF_RESOURCES; } BufferSize = BufferSizeReqested; TempStatus = FvbRead(NULL, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (FwVolHeader); + if(EFI_ERROR(TempStatus) || BufferSizeReqested != BufferSize) { + FreePool(FwVolHeader); return EFI_DEVICE_ERROR; } - FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); + FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); // // Verify the header revision, header signature, length // Length of FvBlock cannot be 2**64-1 // HeaderLength cannot be an odd number // - if ( (FwVolHeader->Revision != EFI_FVH_REVISION) - || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) - || (FwVolHeader->FvLength != FvLength) - ) - { - DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", - __FUNCTION__)); + if( + (FwVolHeader->Revision != EFI_FVH_REVISION) + || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength != FvLength) + ) { + DEBUG((EFI_D_INFO, "%a: No Firmware Volume header present\n", __FUNCTION__)); FreePool (FwVolHeader); return EFI_NOT_FOUND; } // Check the Firmware Volume Guid - if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { - DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", - __FUNCTION__)); - FreePool (FwVolHeader); + if(CompareGuid(&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE) { + DEBUG((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", __FUNCTION__)); + FreePool(FwVolHeader); return EFI_NOT_FOUND; } BufferSizeReqested = FwVolHeader->HeaderLength; - FreePool (FwVolHeader); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); - if (!FwVolHeader) { + FreePool(FwVolHeader); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested+64); + if(!FwVolHeader) { return EFI_OUT_OF_RESOURCES; } BufferSize = BufferSizeReqested; TempStatus = FvbRead(NULL, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (FwVolHeader); + FreePool(FwVolHeader); return EFI_DEVICE_ERROR; } // Verify the header checksum - DEBUG ((EFI_D_INFO, "%a: FwVolHeader->HeaderLength = 0x%X\n", __FUNCTION__, FwVolHeader->HeaderLength)); + DEBUG((EFI_D_INFO, "%a: FwVolHeader->HeaderLength = 0x%X\n", __FUNCTION__, FwVolHeader->HeaderLength)); Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); DEBUG((EFI_D_INFO, "%a checksum = 0x%X\n", __FUNCTION__, Checksum)); - if (Checksum != 0) { + if(Checksum != 0) { DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", __FUNCTION__, Checksum)); FreePool (FwVolHeader); @@ -501,38 +506,40 @@ ValidateFvHeader (IN FVBSPI_INFO *Instance) { BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); - if (!VariableStoreHeader) { + if(!VariableStoreHeader) { return EFI_OUT_OF_RESOURCES; } BufferSize = BufferSizeReqested; TempStatus = FvbRead(NULL, 0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool (VariableStoreHeader); - FreePool (FwVolHeader); + if(EFI_ERROR(TempStatus) || BufferSizeReqested != BufferSize) { + FreePool(VariableStoreHeader); + FreePool(FwVolHeader); return EFI_DEVICE_ERROR; } // Check the Variable Store Guid - if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && - !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { + if ( + !CompareGuid(&VariableStoreHeader->Signature, &gEfiVariableGuid) + && !CompareGuid(&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) + ) { DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", __FUNCTION__)); - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); + FreePool(FwVolHeader); + FreePool(VariableStoreHeader); return EFI_NOT_FOUND; } - VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; + VariableStoreLength = PcdGet32(PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; if (VariableStoreHeader->Size != VariableStoreLength) { DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", __FUNCTION__)); - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); + FreePool(FwVolHeader); + FreePool(VariableStoreHeader); return EFI_NOT_FOUND; } - FreePool (FwVolHeader); - FreePool (VariableStoreHeader); + FreePool(FwVolHeader); + FreePool(VariableStoreHeader); return EFI_SUCCESS; } @@ -742,8 +749,8 @@ FvbRead ( *NumBytes = numberOfBytesToRead; return EFI_BAD_BUFFER_SIZE; } - for(UINTN counter = 0; counter < *NumBytes; ++counter) { - DEBUG((EFI_D_INFO, "%a 0x%X\n", __FUNCTION__, (UINTN)Buffer[counter])); + for(UINTN counter = 0; counter < *NumBytes; counter+=8) { + DEBUG((EFI_D_INFO, "%a 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", __FUNCTION__, (UINTN)Buffer[counter], (UINTN)Buffer[counter+1], (UINTN)Buffer[counter+2], (UINTN)Buffer[counter+3], (UINTN)Buffer[counter+4], (UINTN)Buffer[counter+5], (UINTN)Buffer[counter+6], (UINTN)Buffer[counter+7])); } return EFI_SUCCESS; } @@ -814,8 +821,8 @@ FvbWrite ( ) { DEBUG((EFI_D_INFO, "%a(This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X)\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); - for(UINTN counter = 0; counter < *NumBytes; ++counter) { - DEBUG((EFI_D_INFO, "%a 0x%X\n", __FUNCTION__, (UINTN)Buffer[counter])); + for(UINTN counter = 0; counter < *NumBytes; counter+=8) { + DEBUG((EFI_D_INFO, "%a 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", __FUNCTION__, (UINTN)Buffer[counter], (UINTN)Buffer[counter+1], (UINTN)Buffer[counter+2], (UINTN)Buffer[counter+3], (UINTN)Buffer[counter+4], (UINTN)Buffer[counter+5], (UINTN)Buffer[counter+6], (UINTN)Buffer[counter+7])); } CONST UINTN numberOfBytesToWrite = MIN( *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset) diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c index 599cbc466979..aec1223ea031 100644 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -77,9 +77,16 @@ EFI_STATUS EFIAPI SPIInitialize ( PcdSet32S(PcdFlashNvStorageFtwSpareBase, PcdGet32(PcdFlashNvStorageFtwSpareBase) + fvbSPIInfo.MmioAddress); spi_init(); - Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); - DEBUG((DEBUG_WARN, "InitializeFvAndVariableStoreHeaders(&fvbSPIInfo) = 0x%X\n", Status)); - Status = ValidateFvHeader(&fvbSPIInfo); - DEBUG((DEBUG_WARN, "ValidateFvHeader(&fvbSPIInfo) = 0x%X\n", Status)); + UINTN len = 0x64; + UINT8 buff[0x300] = {}; + FvbRead(NULL, 0, 0, &len, buff); + FvbEraseBlocks(NULL, 0, 1, EFI_LBA_LIST_TERMINATOR); + FvbRead(NULL, 0, 0, &len, buff); + FvbWrite(NULL, 0, 0, &len, buff); + FvbRead(NULL, 0, 0, &len, buff); + // Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); + // DEBUG((DEBUG_WARN, "InitializeFvAndVariableStoreHeaders(&fvbSPIInfo) = 0x%X\n", Status)); + // Status = ValidateFvHeader(&fvbSPIInfo); + // DEBUG((DEBUG_WARN, "ValidateFvHeader(&fvbSPIInfo) = 0x%X\n", Status)); return EFI_SUCCESS; } From e40a530975de1915e196cbced1ea40de23beb306 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Wed, 21 Oct 2020 14:55:31 +0200 Subject: [PATCH 268/297] UefiPayloadPkg/SPI/Fvb.c: fix FvbWrite writing only 0x43 bytes --- .../Variable/RuntimeDxe/VariableDxe.c | 2 +- .../Variable/RuntimeDxe/VariableNonVolatile.c | 2 + UefiPayloadPkg/SPI/Fvb.c | 49 ++++++++++--------- UefiPayloadPkg/SPI/FvbSPI.c | 20 ++++---- UefiPayloadPkg/UefiPayloadPkg.fdf | 2 +- 5 files changed, 39 insertions(+), 36 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c index 421bf8ce47cf..afe03147c96e 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c @@ -490,7 +490,7 @@ VariableServiceInitialize ( EFI_EVENT EndOfDxeEvent; Status = VariableCommonInitialize (); - DEBUG ((DEBUG_WARN, "HIHO\n")); + DEBUG ((DEBUG_WARN, "HIHO, Status = 0x%X\n", Status)); ASSERT_EFI_ERROR (Status); Status = gBS->InstallMultipleProtocolInterfaces ( diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c index 0637a828b33f..405e88498258 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c @@ -207,8 +207,10 @@ InitRealNonVolatileVariableStore ( // Check if the Firmware Volume is not corrupted // if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) { + DEBUG((EFI_D_INFO, "signatures: 0x%X 0x%X\n", FvHeader->Signature, EFI_FVH_SIGNATURE)); FreePool (NvStorageData); DEBUG ((DEBUG_ERROR, "Firmware Volume for Variable Store is corrupted\n")); + DEBUG ((EFI_D_INFO, "%a HERHERHER\n", __FUNCTION__)); return EFI_VOLUME_CORRUPTED; } diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index f0456ce038e9..18a2286da128 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -54,6 +54,7 @@ static struct spi_slave *getSPISlave() { } static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { + WaitForBusyBit(); WriteEnable(); UINT8 blockEraseCmd[] = { CMD_BLOCK_ERASE, @@ -256,6 +257,10 @@ static EFI_STATUS PageProgram( if(*NumBytes == 0 || Buffer == NULL) { return EFI_INVALID_PARAMETER; } + WaitForBusyBit(); + if(WriteEnable() != EFI_SUCCESS) { + return EFI_DEVICE_ERROR; + } UINT8 pageProgramCmd[commandHeaderLength+maxLengthToWrite]; pageProgramCmd[0] = CMD_W25_PP; // FIXME Winbond specific pageProgramCmd[1] = (UINT8)((Address & 0xFF0000) >> 16); @@ -273,7 +278,6 @@ static EFI_STATUS PageProgram( *NumBytes = lengthOfDataToWrite; return EFI_BAD_BUFFER_SIZE; } - WaitForBusyBit(); return EFI_SUCCESS; } @@ -389,30 +393,32 @@ InitializeFvAndVariableStoreHeaders(IN FVBSPI_INFO *Instance) { FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize; FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; FirmwareVolumeHeader->BlockMap[1].Length = 0; - FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); - DEBUG((EFI_D_INFO, "%a checksum = 0x%X\n", __FUNCTION__, FirmwareVolumeHeader->Checksum)); + FirmwareVolumeHeader->Checksum = CalculateCheckSum16((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); // // VARIABLE_STORE_HEADER // VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); - CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + CopyGuid(&VariableStoreHeader->Signature, &gEfiVariableGuid); VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; // Install the combined super-header in the store + static UINT8 blockBackup[BLOCK_SIZE]; + UINTN sizeToRead = BLOCK_SIZE; + FvbRead(NULL, 0, 0, &sizeToRead, blockBackup); + if(sizeToRead != BLOCK_SIZE) { + DEBUG((EFI_D_INFO, "%a Creating block backup failed!\n", __FUNCTION__)); + } Status = FvbEraseBlocks(NULL, 0, 1, EFI_LBA_LIST_TERMINATOR); if(Status != EFI_SUCCESS) { DEBUG((EFI_D_INFO, "%a Erase failed\n", __FUNCTION__)); return Status; } - UINTN len = 0x64; - UINT8 buff[0x64] = {}; - DEBUG((EFI_D_INFO, "%a PAY ATTENTION\n", __FUNCTION__)); - FvbRead(NULL, 0, 0, &len, buff); Status = FvbWrite(NULL, 0, 0, &HeadersLength, Headers); - FvbRead(NULL, 0, 0, &len, buff); + UINTN backupRestoreSize = BLOCK_SIZE-HeadersLength; + Status = FvbWrite(NULL, 0, HeadersLength, &backupRestoreSize, blockBackup+HeadersLength); FreePool (Headers); DEBUG((EFI_D_INFO, "%a Initialized. Now checking\n", __FUNCTION__)); @@ -540,7 +546,7 @@ ValidateFvHeader(IN FVBSPI_INFO *Instance) { FreePool(FwVolHeader); FreePool(VariableStoreHeader); - + DEBUG ((EFI_D_INFO, "%a: Header successfully validated!\n", __FUNCTION__)); return EFI_SUCCESS; } @@ -725,6 +731,7 @@ FvbRead ( UINTN address = ADDRESS(Lba, Offset); UINTN numberOfBytesToRead = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); UINTN numberOfBytesRead = 0; + WaitForBusyBit(); if(FvbVerifyBlockReadability(Lba) == EFI_ACCESS_DENIED) { return EFI_ACCESS_DENIED; } @@ -749,9 +756,6 @@ FvbRead ( *NumBytes = numberOfBytesToRead; return EFI_BAD_BUFFER_SIZE; } - for(UINTN counter = 0; counter < *NumBytes; counter+=8) { - DEBUG((EFI_D_INFO, "%a 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", __FUNCTION__, (UINTN)Buffer[counter], (UINTN)Buffer[counter+1], (UINTN)Buffer[counter+2], (UINTN)Buffer[counter+3], (UINTN)Buffer[counter+4], (UINTN)Buffer[counter+5], (UINTN)Buffer[counter+6], (UINTN)Buffer[counter+7])); - } return EFI_SUCCESS; } @@ -821,13 +825,10 @@ FvbWrite ( ) { DEBUG((EFI_D_INFO, "%a(This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X)\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); - for(UINTN counter = 0; counter < *NumBytes; counter+=8) { - DEBUG((EFI_D_INFO, "%a 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", __FUNCTION__, (UINTN)Buffer[counter], (UINTN)Buffer[counter+1], (UINTN)Buffer[counter+2], (UINTN)Buffer[counter+3], (UINTN)Buffer[counter+4], (UINTN)Buffer[counter+5], (UINTN)Buffer[counter+6], (UINTN)Buffer[counter+7])); - } CONST UINTN numberOfBytesToWrite = MIN( *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset) ); - CONST UINTN address = ADDRESS(Lba, Offset); + UINTN address = ADDRESS(Lba, Offset); UINTN numberOfBytesWritten = 0; if(Buffer == NULL || numberOfBytesToWrite == 0) { DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); @@ -836,18 +837,20 @@ FvbWrite ( if(FvbVerifySingleBlockWritability(Lba) == EFI_ACCESS_DENIED) { return EFI_ACCESS_DENIED; } - if(RemoveBlockProtection() != EFI_SUCCESS - || WaitForBusyBit() != EFI_SUCCESS - || WriteEnable() != EFI_SUCCESS) { + if( + RemoveBlockProtection() != EFI_SUCCESS + || WaitForBusyBit() != EFI_SUCCESS) { return EFI_DEVICE_ERROR; } while(numberOfBytesWritten < numberOfBytesToWrite) { - UINTN writtenAmount = numberOfBytesToWrite; - EFI_STATUS writingStatus = PageProgram(address, Buffer, &writtenAmount); + UINTN writteAmount = numberOfBytesToWrite-numberOfBytesWritten; + EFI_STATUS writingStatus = PageProgram(address, Buffer, &writteAmount); if(writingStatus != EFI_SUCCESS && writingStatus != EFI_BAD_BUFFER_SIZE) { return EFI_DEVICE_ERROR; } - numberOfBytesWritten += writtenAmount; + numberOfBytesWritten += writteAmount; + address += writteAmount; + Buffer += writteAmount; } if(numberOfBytesToWrite != *NumBytes) { return EFI_BAD_BUFFER_SIZE; diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c index aec1223ea031..42270492e731 100644 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -77,16 +77,14 @@ EFI_STATUS EFIAPI SPIInitialize ( PcdSet32S(PcdFlashNvStorageFtwSpareBase, PcdGet32(PcdFlashNvStorageFtwSpareBase) + fvbSPIInfo.MmioAddress); spi_init(); - UINTN len = 0x64; - UINT8 buff[0x300] = {}; - FvbRead(NULL, 0, 0, &len, buff); - FvbEraseBlocks(NULL, 0, 1, EFI_LBA_LIST_TERMINATOR); - FvbRead(NULL, 0, 0, &len, buff); - FvbWrite(NULL, 0, 0, &len, buff); - FvbRead(NULL, 0, 0, &len, buff); - // Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); - // DEBUG((DEBUG_WARN, "InitializeFvAndVariableStoreHeaders(&fvbSPIInfo) = 0x%X\n", Status)); - // Status = ValidateFvHeader(&fvbSPIInfo); - // DEBUG((DEBUG_WARN, "ValidateFvHeader(&fvbSPIInfo) = 0x%X\n", Status)); + + Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); + DEBUG((DEBUG_WARN, "InitializeFvAndVariableStoreHeaders(&fvbSPIInfo) = 0x%X\n", Status)); + Status = ValidateFvHeader(&fvbSPIInfo); + DEBUG((DEBUG_WARN, "ValidateFvHeader(&fvbSPIInfo) = 0x%X\n", Status)); + UINTN len = 5; + FvbWrite(NULL, 0, 0x60000, &len, (UINT8 *)(unsigned char *)"\x00\x01\x02\x03\x04"); + UINT8 *base = (UINT8 *)0xFF860000; + DEBUG((DEBUG_WARN, "0x%X 0x%X 0x%X 0x%X 0x%X \n", base[0], base[1], base[2], base[3], base[4])); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 082184c98819..001fc738532b 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -320,7 +320,7 @@ INF RuleOverride = BINARY USE = X64 ShellBinPkg/UefiShell/UefiShell.inf # GetNonVolatileMaxVariableSize () < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) DEFINE BLOCK_SIZE = 0x10000 -SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = 0xFF860000 +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = 0 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = $(BLOCK_SIZE) SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize From 55b4b9497f670cdabc6cf0b78d02efad5955ffaa Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 22 Oct 2020 13:30:15 +0200 Subject: [PATCH 269/297] UefiPayloadPkg/SPI/Fvb.c: Initialize FirmwareVolumeHeader --- .../Variable/RuntimeDxe/VariableDxe.c | 1 - .../Variable/RuntimeDxe/VariableNonVolatile.c | 3 +- .../RuntimeDxe/VariableRuntimeDxe.inf | 1 + UefiPayloadPkg/SPI/Fvb.c | 18 ++++---- UefiPayloadPkg/SPI/Fvb.h | 1 + UefiPayloadPkg/SPI/FvbSPI.c | 41 ++++++++++--------- UefiPayloadPkg/UefiPayloadPkg.fdf | 2 +- 7 files changed, 32 insertions(+), 35 deletions(-) diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c index afe03147c96e..7d2b6c8e1fad 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableDxe.c @@ -490,7 +490,6 @@ VariableServiceInitialize ( EFI_EVENT EndOfDxeEvent; Status = VariableCommonInitialize (); - DEBUG ((DEBUG_WARN, "HIHO, Status = 0x%X\n", Status)); ASSERT_EFI_ERROR (Status); Status = gBS->InstallMultipleProtocolInterfaces ( diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c index 405e88498258..33e5fb8304e9 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c @@ -127,6 +127,7 @@ InitEmuNonVolatileVariableStore ( @retval EFI_VOLUME_CORRUPTED Variable Store or Firmware Volume for Variable Store is corrupted. **/ + EFI_STATUS InitRealNonVolatileVariableStore ( OUT EFI_PHYSICAL_ADDRESS *VariableStoreBase @@ -207,10 +208,8 @@ InitRealNonVolatileVariableStore ( // Check if the Firmware Volume is not corrupted // if ((FvHeader->Signature != EFI_FVH_SIGNATURE) || (!CompareGuid (&gEfiSystemNvDataFvGuid, &FvHeader->FileSystemGuid))) { - DEBUG((EFI_D_INFO, "signatures: 0x%X 0x%X\n", FvHeader->Signature, EFI_FVH_SIGNATURE)); FreePool (NvStorageData); DEBUG ((DEBUG_ERROR, "Firmware Volume for Variable Store is corrupted\n")); - DEBUG ((EFI_D_INFO, "%a HERHERHER\n", __FUNCTION__)); return EFI_VOLUME_CORRUPTED; } diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf index ceea5d1ff9ac..52b1f5e80c4b 100644 --- a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +++ b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -52,6 +52,7 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec [LibraryClasses] MemoryAllocationLib diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index 18a2286da128..ba9503c120c2 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -10,14 +10,14 @@ #include "Winbond.h" -#define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * (Lba)) + (Offset)) +#define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * ((Lba)+(VARIABLE_STORAGE_BLOCKS_OFFSET))) + (Offset)) #define OFFSET_FROM_PAGE_START(Address) ((Address) % (PAGE_SIZE)) #define REMAINING_SPACE(Offset, MaxSize) ((MaxSize) - (Offset)) #define REMAINING_SPACE_IN_BLOCK(Offset) REMAINING_SPACE((Offset), (BLOCK_SIZE)) #define REMAINING_SPACE_IN_PAGE(Offset) REMAINING_SPACE((Offset), (PAGE_SIZE)) static struct spi_slave *getSPISlave(); -static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address); +static EFI_STATUS FvbEraseBlockAtAddress(UINTN Address); static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount); static EFI_STATUS readStatusReg(UINT8 *Status); static EFI_STATUS checkBusyBit(UINT8 *Busy); @@ -53,7 +53,7 @@ static struct spi_slave *getSPISlave() { return &slave; } -static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { +static EFI_STATUS FvbEraseBlockAtAddress(UINTN Address) { WaitForBusyBit(); WriteEnable(); UINT8 blockEraseCmd[] = { @@ -71,10 +71,10 @@ static EFI_STATUS FvbEraseBlockAtAddress(UINT8 Address) { return EFI_SUCCESS; } -static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount) { +static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN Amount) { BOOLEAN error = FALSE; - for(UINTN current = 0; current < amount; ++current) { - if(FvbEraseBlockAtAddress(ADDRESS(Lba+current, 0)) != EFI_SUCCESS) { + for(UINTN current = 0; current < Amount; ++current) { + if(FvbEraseBlockAtAddress(0x60000/*ADDRESS(Lba+current, 0)*/) != EFI_SUCCESS) { error = TRUE; } } @@ -163,7 +163,6 @@ static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args) { if(Lba == EFI_LBA_LIST_TERMINATOR) { break; } - DEBUG((EFI_D_INFO, "%a ERASING: Lba = 0x%X Count = 0x%X\n", __FUNCTION__, Lba, LbaCount)); if(FvbEraseConsecutiveBlocks(Lba, LbaCount) != EFI_SUCCESS) { status = EFI_DEVICE_ERROR; } @@ -386,7 +385,7 @@ InitializeFvAndVariableStoreHeaders(IN FVBSPI_INFO *Instance) { | EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') | EFI_FVB2_WRITE_STATUS // Writes are currently enabled | EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled - ); + ); FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->NumBlocks; @@ -421,7 +420,6 @@ InitializeFvAndVariableStoreHeaders(IN FVBSPI_INFO *Instance) { Status = FvbWrite(NULL, 0, HeadersLength, &backupRestoreSize, blockBackup+HeadersLength); FreePool (Headers); - DEBUG((EFI_D_INFO, "%a Initialized. Now checking\n", __FUNCTION__)); ValidateFvHeader(Instance); return Status; } @@ -824,7 +822,6 @@ FvbWrite ( IN UINT8 *Buffer ) { - DEBUG((EFI_D_INFO, "%a(This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X)\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); CONST UINTN numberOfBytesToWrite = MIN( *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset) ); @@ -911,7 +908,6 @@ FvbEraseBlocks ( ... ) { - DEBUG((EFI_D_INFO, "%a(This = 0x%X)\n", __FUNCTION__, This)); EFI_STATUS status = EFI_SUCCESS; VA_LIST Args; VA_START(Args, This); diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h index b06803185032..018035112edd 100644 --- a/UefiPayloadPkg/SPI/Fvb.h +++ b/UefiPayloadPkg/SPI/Fvb.h @@ -7,6 +7,7 @@ #define BLOCK_SIZE 0x10000 #define PAGE_SIZE 0x100 #define FLASH_SIZE 0x800000 +#define VARIABLE_STORAGE_BLOCKS_OFFSET 6 EFI_STATUS InitializeFvAndVariableStoreHeaders ( diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c index 42270492e731..7083674fa304 100644 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -39,16 +39,14 @@ EFI_STATUS EFIAPI SPIInitialize ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG((DEBUG_WARN, "SPI IS HERE.\n")); FVBSPI_INFO fvbSPIInfo = { .ComBuffer = 0, .ComBufferSize = 0, .NumBlocks = 4, .BlockSize = BLOCK_SIZE, - .MmioAddress = 0xFF860000, + .MmioAddress = 0, .ApmCmd = 0 }; - DEBUG ((DEBUG_WARN, "SPI IS HERE.\n")); if (PcdGetBool(PcdEmuVariableNvModeEnable)) { DEBUG (( DEBUG_WARN, @@ -57,6 +55,26 @@ EFI_STATUS EFIAPI SPIInitialize ( return EFI_SUCCESS; } EFI_STATUS Status; + // Update PCDs for Variable/RuntimeDxe + PcdSet32S(PcdFlashNvStorageVariableBase, + PcdGet32(PcdFlashNvStorageVariableBase) + fvbSPIInfo.MmioAddress); + PcdSet32S(PcdFlashNvStorageFtwWorkingBase, + PcdGet32(PcdFlashNvStorageFtwWorkingBase) + fvbSPIInfo.MmioAddress); + PcdSet32S(PcdFlashNvStorageFtwSpareBase, + PcdGet32(PcdFlashNvStorageFtwSpareBase) + fvbSPIInfo.MmioAddress); + spi_init(); + + Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); + if(Status != EFI_SUCCESS) { + DEBUG((DEBUG_WARN, "%a InitializeFvAndVariableStoreHeaders() failed\n", __FUNCTION__)); + } + Status = ValidateFvHeader(&fvbSPIInfo); + if(Status != EFI_SUCCESS) { + DEBUG((DEBUG_WARN, "%a ValidateFvHeader() failed\n", __FUNCTION__)); + } + // + // Install the protocol + // Status = gBS->InstallMultipleProtocolInterfaces ( &Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, @@ -69,22 +87,5 @@ EFI_STATUS EFIAPI SPIInitialize ( while(1); return EFI_PROTOCOL_ERROR; } - // Update PCDs for Variable/RuntimeDxe - PcdSet32S(PcdFlashNvStorageVariableBase, - PcdGet32(PcdFlashNvStorageVariableBase) + fvbSPIInfo.MmioAddress); - PcdSet32S(PcdFlashNvStorageFtwWorkingBase, - PcdGet32(PcdFlashNvStorageFtwWorkingBase) + fvbSPIInfo.MmioAddress); - PcdSet32S(PcdFlashNvStorageFtwSpareBase, - PcdGet32(PcdFlashNvStorageFtwSpareBase) + fvbSPIInfo.MmioAddress); - spi_init(); - - Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); - DEBUG((DEBUG_WARN, "InitializeFvAndVariableStoreHeaders(&fvbSPIInfo) = 0x%X\n", Status)); - Status = ValidateFvHeader(&fvbSPIInfo); - DEBUG((DEBUG_WARN, "ValidateFvHeader(&fvbSPIInfo) = 0x%X\n", Status)); - UINTN len = 5; - FvbWrite(NULL, 0, 0x60000, &len, (UINT8 *)(unsigned char *)"\x00\x01\x02\x03\x04"); - UINT8 *base = (UINT8 *)0xFF860000; - DEBUG((DEBUG_WARN, "0x%X 0x%X 0x%X 0x%X 0x%X \n", base[0], base[1], base[2], base[3], base[4])); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 001fc738532b..082184c98819 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -320,7 +320,7 @@ INF RuleOverride = BINARY USE = X64 ShellBinPkg/UefiShell/UefiShell.inf # GetNonVolatileMaxVariableSize () < (VariableStoreLength - sizeof (VARIABLE_STORE_HEADER)) DEFINE BLOCK_SIZE = 0x10000 -SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = 0 +SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase = 0xFF860000 SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize = $(BLOCK_SIZE) SET gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase = gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize From 4910143a9eafa30d0c7079604db7a7831a71bd3d Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Thu, 22 Oct 2020 14:54:19 +0200 Subject: [PATCH 270/297] UefiPayloadPkg/SPI/FvbSPI.c Install gEdkiiNvVarStoreFormattedGuid --- UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c | 4 ---- UefiPayloadPkg/Include/Library/BlParseLib.h | 2 +- UefiPayloadPkg/SPI/FvbSPI.c | 16 ++++++++++++++++ UefiPayloadPkg/SPI/SPI.inf | 3 ++- UefiPayloadPkg/UefiPayloadPkg.dec | 1 - 5 files changed, 19 insertions(+), 7 deletions(-) diff --git a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index 7decbea0414c..b32c2bc4faf4 100644 --- a/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c +++ b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c @@ -156,10 +156,6 @@ BlSMMSTOREInitialise ( IN EFI_SYSTEM_TABLE *SystemTable ) { - DEBUG ((DEBUG_WARN, "BLAH BlSMMSTOREInitialise.\n")); - while(1); - return EFI_SUCCESS; - ////////////////////////////////////////////// EFI_STATUS Status; VOID *ComBuf; VOID *GuidHob; diff --git a/UefiPayloadPkg/Include/Library/BlParseLib.h b/UefiPayloadPkg/Include/Library/BlParseLib.h index ffd7e8d48597..f705057f20da 100644 --- a/UefiPayloadPkg/Include/Library/BlParseLib.h +++ b/UefiPayloadPkg/Include/Library/BlParseLib.h @@ -12,7 +12,7 @@ #include #include #include -// #include +//#include #ifndef __BOOTLOADER_PARSE_LIB__ #define __BOOTLOADER_PARSE_LIB__ diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c index 7083674fa304..21fdbf9e6c66 100644 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -87,5 +87,21 @@ EFI_STATUS EFIAPI SPIInitialize ( while(1); return EFI_PROTOCOL_ERROR; } + // + // The driver implementing the variable read service can now be dispatched; + // the varstore headers are in place. + // + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, EFI_NATIVE_INTERFACE, + NULL); + if(EFI_ERROR (Status)) { + DEBUG(( + EFI_D_INFO, + "%a Error during protocol 2 installation.\n", __FUNCTION__)); + PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); + while(1); + return EFI_PROTOCOL_ERROR; + } return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 6cb2e1ada3e0..982b12c45577 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -45,13 +45,14 @@ UefiDriverEntryPoint [Guids] + gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL gEfiAuthenticatedVariableGuid gEfiSystemNvDataFvGuid gEfiVariableGuid gUefiFvbSPIInfoGuid [Protocols] - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES ## PROTOCOL [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 2d256a264cd5..f6b35b0eab5e 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -34,7 +34,6 @@ gUefiAcpiBoardInfoGuid = {0xad3d31b, 0xb3d8, 0x4506, {0xae, 0x71, 0x2e, 0xf1, 0x10, 0x06, 0xd9, 0x0f}} gUefiSerialPortInfoGuid = {0x6c6872fe, 0x56a9, 0x4403, {0xbb, 0x98, 0x95, 0x8d, 0x62, 0xde, 0x87, 0xf1}} gLoaderMemoryMapInfoGuid = {0xa1ff7424, 0x7a1a, 0x478e, {0xa9, 0xe4, 0x92, 0xf3, 0x57, 0xd1, 0x28, 0x32}} - # gEfiSMMSTOREInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 }} gUefiFvbSPIInfoGuid = {0x7d3b6dea, 0xd358, 0x440e, {0xb3, 0x5d, 0x36, 0x2f, 0x09, 0xf2, 0x8f, 0xec}} [Ppis] From c0744ea225149383624b37338f6a52f423e346f3 Mon Sep 17 00:00:00 2001 From: Igor Bagnucki Date: Fri, 23 Oct 2020 12:44:52 +0200 Subject: [PATCH 271/297] UefiPayloadPkg/SPI/Fvb.c: Add gEfiVariableWriteArchProtocolGuid protocol, and implement FvbGetAttributes --- .../PlatformBootManager.c | 4 +-- UefiPayloadPkg/SPI/Fvb.c | 27 ++++++++++++++++++- UefiPayloadPkg/SPI/FvbSPI.c | 13 +++++---- UefiPayloadPkg/SPI/SPI.inf | 1 + 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c index 9d7bcb35f2c4..7a5e571a86fd 100644 --- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c +++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -319,7 +319,7 @@ SetPrimaryVideoOutput( } // Locate all GOPs - Status = gBS->LocateHandleBuffer(ByProtocol, + Status = gBS->LocateHandleBuffer(ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL, &HandleCount, @@ -456,7 +456,7 @@ SetPrimaryVideoOutput( } } // for loop - + return; } diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c index ba9503c120c2..a8bb82156fcb 100644 --- a/UefiPayloadPkg/SPI/Fvb.c +++ b/UefiPayloadPkg/SPI/Fvb.c @@ -569,7 +569,32 @@ FvbGetAttributes( ) { DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; + EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; + // SMMSTORE_INSTANCE *Instance; + + // Instance = INSTANCE_FROM_FVB_THIS(This); + + FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') + ); + + // // Check if it is write protected + // if (Instance->Media.ReadOnly != TRUE) { + + // FlashFvbAttributes = FlashFvbAttributes | + // EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + // EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled + // } + + *Attributes = FlashFvbAttributes; + + DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); + + return EFI_SUCCESS; } /** diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c index 21fdbf9e6c66..e0ede8327a93 100644 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ b/UefiPayloadPkg/SPI/FvbSPI.c @@ -87,14 +87,13 @@ EFI_STATUS EFIAPI SPIInitialize ( while(1); return EFI_PROTOCOL_ERROR; } - // - // The driver implementing the variable read service can now be dispatched; - // the varstore headers are in place. - // + Status = gBS->InstallProtocolInterface ( - &gImageHandle, - &gEdkiiNvVarStoreFormattedGuid, EFI_NATIVE_INTERFACE, - NULL); + &Handle, + &gEfiVariableWriteArchProtocolGuid, + EFI_NATIVE_INTERFACE, + NULL + ); if(EFI_ERROR (Status)) { DEBUG(( EFI_D_INFO, diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index 982b12c45577..fc7185cf5bea 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -53,6 +53,7 @@ [Protocols] gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES ## PROTOCOL + gEfiVariableWriteArchProtocolGuid [Pcd] gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable From 0319baeeb1ad3e6e54514e17685b662da5f5f6fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 26 Oct 2020 15:47:55 +0100 Subject: [PATCH 272/297] UefiPayloadPkg: fix build under coreboot-sdk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/SPI/FchSPICtrl.c | 13 ++++++------- UefiPayloadPkg/SPI/SPI.inf | 1 + UefiPayloadPkg/UefiPayloadPkg.fdf | 10 +++++----- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 4 ++-- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/UefiPayloadPkg/SPI/FchSPICtrl.c b/UefiPayloadPkg/SPI/FchSPICtrl.c index 831fe14bff87..9fe365f873d2 100644 --- a/UefiPayloadPkg/SPI/FchSPICtrl.c +++ b/UefiPayloadPkg/SPI/FchSPICtrl.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include "FchSPIUtil.h" #include "GenericSPI.h" @@ -35,20 +36,18 @@ static int wait_for_ready(VOID) { - CONST UINT64 timeoutMilisecond = 500; - CONST UINT64 nanoToMiliDivider = 1000000; + CONST UINTN timeoutMilisecond = 500; + CONST UINT32 nanoToMiliDivider = 1000000; CONST UINT64 startTimeMilisec = - GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; + DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); CONST UINT64 endTimeMilisec = startTimeMilisec + timeoutMilisecond; UINT64 timeNow = startTimeMilisec; do { if (!(spi_read32(SPI_STATUS) & SPI_BUSY)) return 0; - timeNow = GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; - } while ( - timeNowstartTimeMilisec && timeNow>endTimeMilisec)); + timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()),nanoToMiliDivider); + } while (timeNowstartTimeMilisec && timeNow>endTimeMilisec)); return -1; } diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf index fc7185cf5bea..07e6de9c458d 100644 --- a/UefiPayloadPkg/SPI/SPI.inf +++ b/UefiPayloadPkg/SPI/SPI.inf @@ -38,6 +38,7 @@ [LibraryClasses] BaseMemoryLib + BaseLib DebugLib HobLib PciLib diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 082184c98819..0d3b6af02556 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -10,16 +10,16 @@ ################################################################################ [FD.UefiPayload] -BaseAddress = 0x800000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase -Size = 0x800000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize +BaseAddress = 0x400000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase +Size = 0x400000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize ErasePolarity = 1 BlockSize = 0x1000 -NumBlocks = 0x800 +NumBlocks = 0x400 -0x00000000|0x040000 +0x00000000|0x020000 FV = PEIFV -0x00040000|0x7C0000 +0x00020000|0x3a0000 FV = DXEFV ################################################################################ diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index bf6bf6242a69..50a9c47b2f1f 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -31,7 +31,7 @@ # SBL: UEFI payload for Slim Bootloader # COREBOOT: UEFI payload for coreboot # - DEFINE BOOTLOADER = SBL + DEFINE BOOTLOADER = COREBOOT # # CPU options @@ -78,7 +78,7 @@ # # Shell options: [BUILD_SHELL, MIN_BIN, NONE, UEFI_BIN] # - DEFINE SHELL_TYPE = BUILD_SHELL + DEFINE SHELL_TYPE = NONE # # Security options: From 8a7bb9a0311ca7d8d31c312e4dbab968006587f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 26 Oct 2020 16:24:35 +0100 Subject: [PATCH 273/297] UefiPayloadPkg: strip unused packages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 38 +++++---------------------- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 30 +++------------------ 2 files changed, 10 insertions(+), 58 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 0d3b6af02556..717c1eb21233 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -83,8 +83,10 @@ APRIORI DXE { INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf INF MdeModulePkg/Universal/ReportStatusCodeRouter/RuntimeDxe/ReportStatusCodeRouterRuntimeDxe.inf INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf - INF UefiPayloadPkg/SPI/SPI.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + INF UefiPayloadPkg/SPI/SPI.inf +!endif # Init Test Driver before Secure Boot # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf @@ -123,7 +125,10 @@ INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf INF MdeModulePkg/Logo/LogoDxe.inf -INF UefiPayloadPkg/SPI/SPI.inf + +!if $(SECURE_BOOT_ENABLE) == TRUE + INF UefiPayloadPkg/SPI/SPI.inf +!endif # # PCI Support @@ -167,36 +172,12 @@ INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf INF FatPkg/EnhancedFatDxe/Fat.inf -# -# Filesystem drivers -# -!if $(ARCH) == IA32 -INF RuleOverride=BINARY USE = IA32 FSDrivers/exfat.inf -INF RuleOverride=BINARY USE = IA32 FSDrivers/ext2.inf -INF RuleOverride=BINARY USE = IA32 FSDrivers/ntfs.inf -INF RuleOverride=BINARY USE = IA32 FSDrivers/ext4.inf -!else -INF RuleOverride=BINARY USE = X64 FSDrivers/exfat.inf -INF RuleOverride=BINARY USE = X64 FSDrivers/ext2.inf -INF RuleOverride=BINARY USE = X64 FSDrivers/ntfs.inf -INF RuleOverride=BINARY USE = X64 FSDrivers/ext4.inf -!endif - -# -# SD/eMMC Support -# -INF MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf -INF MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf -INF MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf - # # Usb Support # -INF MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf -INF MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf # @@ -245,11 +226,6 @@ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf } !endif -# -# Random Number Generator -# -INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf - # # Security # diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 50a9c47b2f1f..325757b6e6df 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -294,7 +294,6 @@ !endif CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf - SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf [LibraryClasses.common.DXE_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -308,7 +307,6 @@ CpuExceptionHandlerLib|UefiCpuPkg/Library/CpuExceptionHandlerLib/DxeCpuExceptionHandlerLib.inf MpInitLib|UefiCpuPkg/Library/MpInitLib/DxeMpInitLib.inf BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf - SmbusLib|MdePkg/Library/DxeSmbusLib/DxeSmbusLib.inf [LibraryClasses.common.DXE_RUNTIME_DRIVER] PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf @@ -435,7 +433,9 @@ ################################################################################ [Components.IA32] +!if $(SECURE_BOOT_ENABLE) == TRUE UefiPayloadPkg/SPI/SPI.inf +!endif # # SEC Core # @@ -497,7 +497,7 @@ } !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf - OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf + UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf !endif UefiCpuPkg/CpuDxe/CpuDxe.inf @@ -573,25 +573,15 @@ MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf - MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf - # - # SD/eMMC Support - # - MdeModulePkg/Bus/Pci/SdMmcPciHcDxe/SdMmcPciHcDxe.inf - MdeModulePkg/Bus/Sd/EmmcDxe/EmmcDxe.inf - MdeModulePkg/Bus/Sd/SdDxe/SdDxe.inf - # # Usb Support # - MdeModulePkg/Bus/Pci/UhciDxe/UhciDxe.inf MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf - MdeModulePkg/Bus/Usb/UsbKbDxe/UsbKbDxe.inf MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf # @@ -603,12 +593,6 @@ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf !endif - # - # SMBUS Support - # - UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf - UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf - # # Console Support # @@ -633,14 +617,6 @@ } !endif - # - # Random Number Generator - # - SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf { - - RngLib|UefiPayloadPkg/Library/BaseRngLib/BaseRngLib.inf - } - !if $(TPM_ENABLE) == TRUE SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { From 9ebbc35381aca9f137c1dd134a651da48646cb04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 26 Oct 2020 16:50:23 +0100 Subject: [PATCH 274/297] UefiPayloadPkg/UefiPayloadPkg.fdf: fix iPXE include MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 717c1eb21233..5201909b73b8 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -166,7 +166,6 @@ INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf INF MdeModulePkg/Bus/Pci/SataControllerDxe/SataControllerDxe.inf INF MdeModulePkg/Bus/Ata/AtaBusDxe/AtaBusDxe.inf INF MdeModulePkg/Bus/Ata/AtaAtapiPassThru/AtaAtapiPassThru.inf -INF MdeModulePkg/Bus/Pci/NvmExpressDxe/NvmExpressDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiBusDxe/ScsiBusDxe.inf INF MdeModulePkg/Bus/Scsi/ScsiDiskDxe/ScsiDiskDxe.inf @@ -220,7 +219,7 @@ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf # # iPXE support # -!if (NETWORK_IPXE) +!if $(NETWORK_IPXE) == TRUE FILE FREEFORM = B68653C7-EEA1-4435-A199-A44F59E4476C { SECTION PE32 = UefiPayloadPkg/NetworkDrivers/ipxe.efi } From 1d082d6c31213cd2516b65f0fa0b3d3f80df0abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 27 Oct 2020 10:25:27 +0100 Subject: [PATCH 275/297] UefiPayloadPkg: use COM2 as output port MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 10 +++++----- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 5201909b73b8..04c6baa7a88e 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -10,16 +10,16 @@ ################################################################################ [FD.UefiPayload] -BaseAddress = 0x400000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase -Size = 0x400000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize +BaseAddress = 0x240000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase +Size = 0x240000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize ErasePolarity = 1 BlockSize = 0x1000 -NumBlocks = 0x400 +NumBlocks = 0x240 -0x00000000|0x020000 +0x00000000|0x040000 FV = PEIFV -0x00020000|0x3a0000 +0x00040000|0x200000 FV = DXEFV ################################################################################ diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 325757b6e6df..f8e756c8db68 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -371,7 +371,7 @@ # The following parameters are set by Library/PlatformHookLib # gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x2f8 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE) gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1 From 38d69b955cd85b99bc40cb822eb5c5a9e9ad9d04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Tue, 27 Oct 2020 11:07:33 +0100 Subject: [PATCH 276/297] UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c: change the menu key to F9 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../Library/PlatformBootManagerLib/PlatformBootManager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c index 7a5e571a86fd..bbab450b9e26 100644 --- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c +++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -485,7 +485,7 @@ PlatformBootManagerBeforeConsole ( // // Map Escape to Boot Manager Menu // - Escape.ScanCode = SCAN_ESC; + Escape.ScanCode = SCAN_F9; Escape.UnicodeChar = CHAR_NULL; EfiBootManagerGetBootManagerMenu (&BootOption); EfiBootManagerAddKeyOptionVariable (NULL, (UINT16) BootOption.OptionNumber, 0, &Escape, NULL); @@ -560,7 +560,7 @@ PlatformBootManagerAfterConsole ( // PlatformRegisterFvBootOption (PcdGetPtr (PcdiPXEFile), L"iPXE Network boot", LOAD_OPTION_ACTIVE); - Print (L"Pess ESC to enter Boot Manager Menu.\n"); + Print (L"Press F9 to enter Boot Manager Menu.\n"); } /** From e55e77b5481a5a89e87337dfa085c4856715b4a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 29 Oct 2020 17:19:19 +0100 Subject: [PATCH 277/297] UefiPayloadPkg/Library/AmdSpiLib: refactor code from SPI module to AmdSpi lib MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../{SPI => Library/AmdSpiLib}/Adesto.c | 6 +- UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c | 82 ++ .../Library/AmdSpiLib/AmdSpiLib.inf | 39 + UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c | 278 +++++ .../{SPI => Library/AmdSpiLib}/GenericSPI.c | 40 +- .../{SPI => Library/AmdSpiLib}/GenericSPI.h | 50 +- .../Library/AmdSpiLib/SPIFlashInternal.c | 482 +++++++++ .../Library/AmdSpiLib/SPIFlashInternal.h | 169 ++++ UefiPayloadPkg/Library/AmdSpiLib/Winbond.c | 211 ++++ .../{SPI => Library/AmdSpiLib}/Winbond.h | 0 UefiPayloadPkg/SPI/FchSPICtrl.c | 156 --- UefiPayloadPkg/SPI/FchSPICtrl.h | 37 - UefiPayloadPkg/SPI/FchSPIUtil.c | 67 -- UefiPayloadPkg/SPI/FchSPIUtil.h | 16 - UefiPayloadPkg/SPI/Fvb.c | 951 ------------------ UefiPayloadPkg/SPI/Fvb.h | 87 -- UefiPayloadPkg/SPI/FvbSPI.c | 106 -- UefiPayloadPkg/SPI/FvbSPI.h | 108 -- UefiPayloadPkg/SPI/SPI.h | 18 - UefiPayloadPkg/SPI/SPI.inf | 69 -- UefiPayloadPkg/SPI/SPIFlashInternal.c | 600 ----------- UefiPayloadPkg/SPI/SPIFlashInternal.h | 155 --- UefiPayloadPkg/SPI/Winbond.c | 539 ---------- 23 files changed, 1298 insertions(+), 2968 deletions(-) rename UefiPayloadPkg/{SPI => Library/AmdSpiLib}/Adesto.c (92%) create mode 100644 UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c create mode 100644 UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.inf create mode 100644 UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c rename UefiPayloadPkg/{SPI => Library/AmdSpiLib}/GenericSPI.c (74%) rename UefiPayloadPkg/{SPI => Library/AmdSpiLib}/GenericSPI.h (85%) create mode 100644 UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c create mode 100644 UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.h create mode 100644 UefiPayloadPkg/Library/AmdSpiLib/Winbond.c rename UefiPayloadPkg/{SPI => Library/AmdSpiLib}/Winbond.h (100%) delete mode 100644 UefiPayloadPkg/SPI/FchSPICtrl.c delete mode 100644 UefiPayloadPkg/SPI/FchSPICtrl.h delete mode 100644 UefiPayloadPkg/SPI/FchSPIUtil.c delete mode 100644 UefiPayloadPkg/SPI/FchSPIUtil.h delete mode 100644 UefiPayloadPkg/SPI/Fvb.c delete mode 100644 UefiPayloadPkg/SPI/Fvb.h delete mode 100644 UefiPayloadPkg/SPI/FvbSPI.c delete mode 100644 UefiPayloadPkg/SPI/FvbSPI.h delete mode 100644 UefiPayloadPkg/SPI/SPI.h delete mode 100644 UefiPayloadPkg/SPI/SPI.inf delete mode 100644 UefiPayloadPkg/SPI/SPIFlashInternal.c delete mode 100644 UefiPayloadPkg/SPI/SPIFlashInternal.h delete mode 100644 UefiPayloadPkg/SPI/Winbond.c diff --git a/UefiPayloadPkg/SPI/Adesto.c b/UefiPayloadPkg/Library/AmdSpiLib/Adesto.c similarity index 92% rename from UefiPayloadPkg/SPI/Adesto.c rename to UefiPayloadPkg/Library/AmdSpiLib/Adesto.c index ab6743260b02..1711fe33e6c3 100644 --- a/UefiPayloadPkg/SPI/Adesto.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/Adesto.c @@ -1,5 +1,3 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - /* * Driver for Adesto Technologies SPI flash * based on Winbond.c @@ -22,7 +20,7 @@ #define CMD_AT25DF_DP 0xb9 /* Deep Power-down */ #define CMD_AT25DF_RES 0xab /* Release from DP, and Read Signature */ -static const struct spi_flash_part_id flash_table[] = { +STATIC CONST struct spi_flash_part_id flash_table[] = { { /* AT25SL128A */ .id[0] = 0x4218, @@ -85,7 +83,7 @@ static const struct spi_flash_part_id flash_table[] = { }, }; -const struct spi_flash_vendor_info spi_flash_adesto_vi = { +CONST struct spi_flash_vendor_info spi_flash_adesto_vi = { .id = VENDOR_ID_ADESTO, .page_size_shift = 8, .sector_size_kib_shift = 2, diff --git a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c new file mode 100644 index 000000000000..9246644091e2 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c @@ -0,0 +1,82 @@ +#include +#include +#include "GenericSPI.h" +#include "SPIFlashInternal.h" +#include "Winbond.h" + +#define BLOCK_SIZE 0x10000 +#define VARIABLE_STORAGE_BLOCKS_OFFSET 6 +#define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * ((Lba)+(VARIABLE_STORAGE_BLOCKS_OFFSET))) + (Offset)) +#define OFFSET_FROM_PAGE_START(Address) ((Address) % (PAGE_SIZE)) +#define REMAINING_SPACE(Offset, MaxSize) ((MaxSize) - (Offset)) +#define REMAINING_SPACE_IN_BLOCK(Offset) REMAINING_SPACE((Offset), (BLOCK_SIZE)) +#define REMAINING_SPACE_IN_PAGE(Offset) REMAINING_SPACE((Offset), (PAGE_SIZE)) + +STATIC struct spi_flash flash; + +EFI_STATUS +AmdSpiRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINTN address = ADDRESS(Lba, Offset); + + if (address + *NumBytes > 0xa0000 || address < 0x60000) + return EFI_ACCESS_DENIED; + + if (*NumBytes == 0 || Buffer == NULL) + return EFI_INVALID_PARAMETER; + + return spi_flash_read(&flash, address, *NumBytes, Buffer); +} + +EFI_STATUS +AmdSpiWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + UINTN address = ADDRESS(Lba, Offset); + + if (address + *NumBytes > 0xa0000 || address < 0x60000) + return EFI_ACCESS_DENIED; + + if (*NumBytes == 0 || Buffer == NULL) + return EFI_INVALID_PARAMETER; + + return spi_flash_write(&flash, address, *NumBytes, Buffer); +} + +/** + Erase a block using the AMD SPI + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +AmdSpiEraseBlock ( + IN EFI_LBA Lba + ) +{ + UINTN address = ADDRESS(Lba, 0); + + if (address > 0xa0000 || address < 0x60000) + return EFI_ACCESS_DENIED; + + return spi_flash_erase(&flash, address, BLOCK_SIZE); +} + +EFI_STATUS +AmdSpiInitialize (VOID) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + + spi_init(); + + return spi_flash_probe(0, 0, &flash); +} diff --git a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.inf b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.inf new file mode 100644 index 000000000000..27d221cb8fb4 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.inf @@ -0,0 +1,39 @@ +## @file +# AMD SPI library +# +# Copyright (c) 2020 3mdeb Embedded Systems Consulting.
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AmdSpi + FILE_GUID = c2c2e656-ee66-41e0-bee3-29c6f16f49c0 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = AmdSpiLib + +[Sources] + Adesto.c + AmdSpiLib.c + FchSPICtrl.c + GenericSPI.c + GenericSPI.h + SPIFlashInternal.c + SPIFlashInternal.h + Winbond.c + Winbond.h + +[Packages] + MdeModulePkg/MdeModulePkg.dec + MdePkg/MdePkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + BaseMemoryLib + BaseLib + DebugLib + PciLib + TimerLib diff --git a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c new file mode 100644 index 000000000000..9174f5c90256 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c @@ -0,0 +1,278 @@ +#include +#include +#include +#include +#include +#include +#include "GenericSPI.h" +#include "SPIFlashInternal.h" + +#define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ +#define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) + +/* SPI MMIO registers */ +#define SPI_REG_OPCODE 0x00 +#define SPI_CNTRL0 0x00 +#define SPI_BUSY BIT31 +#define SPI_REG_CNTRL01 0x01 +#define SPI_REG_CNTRL02 0x02 + #define CNTRL02_FIFO_RESET (1 << 4) + #define CNTRL02_EXEC_OPCODE (1 << 0) +#define SPI_REG_CNTRL03 0x03 + #define CNTRL03_SPIBUSY (1 << 7) +#define SPI_RESTRICTED_CMD1 0x04 +#define SPI_RESTRICTED_CMD2 0x08 +#define SPI_REG_FIFO 0x0c +#define SPI_REG_CNTRL11 0x0d + #define CNTRL11_FIFOPTR_MASK 0x07 +#define SPI_CMD_CODE 0x45 +#define SPI_CMD_TRIGGER 0x47 +#define SPI_CMD_TRIGGER_EXECUTE 0x80 +#define SPI_TX_BYTE_COUNT 0x48 +#define SPI_RX_BYTE_COUNT 0x4b +#define SPI_STATUS 0x4c +#define SPI_DONE_BYTE_COUNT_SHIFT 0 +#define SPI_DONE_BYTE_COUNT_MASK 0xff +#define SPI_FIFO_WR_PTR_SHIFT 8 +#define SPI_FIFO_WR_PTR_MASK 0x7f +#define SPI_FIFO_RD_PTR_SHIFT 16 +#define SPI_FIFO_RD_PTR_MASK 0x7f +#define SPI_BUSY BIT31 +#define SPI_FIFO 0x80 +#define SPI_FIFO_LAST_BYTE 0xc7 +#define SPI_FIFO_DEPTH (SPI_FIFO_LAST_BYTE - SPI_FIFO) + +#define LPC_DEV 0x14 +#define LPC_FUNC 0x03 + +#define SPIROM_BASE_ADDRESS_REGISTER 0xa0 +#define SPI_BASE_ALIGNMENT 0x00000040 +#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) + +static UINTN spi_base = 0; + +STATIC UINTN lpc_get_spibase(VOID) +{ + UINT32 base; + base = PciRead32( + PCI_LIB_ADDRESS(0, LPC_DEV, LPC_FUNC, SPIROM_BASE_ADDRESS_REGISTER)); + base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); + return (UINTN)base; +} + +STATIC VOID spi_set_base(UINTN base) +{ + spi_base = base; +} + +STATIC UINTN spi_get_bar(VOID) +{ + if (spi_base == 0) { + spi_set_base(lpc_get_spibase()); + } + return spi_base; +} + +STATIC UINT8 spi_read8(UINT8 reg) +{ + return MmioRead8((spi_get_bar() + reg)); +} + +STATIC UINT32 spi_read32(UINT8 reg) +{ + return MmioRead32((spi_get_bar() + reg)); +} + +STATIC VOID spi_write8(UINT8 reg, UINT8 val) +{ + MmioWrite8((spi_get_bar() + reg), val); +} + +STATIC VOID reset_internal_fifo_pointer(void) +{ + UINT8 reg8; + + do { + reg8 = spi_read8(SPI_REG_CNTRL02); + reg8 |= CNTRL02_FIFO_RESET; + spi_write8(SPI_REG_CNTRL02, reg8); + } while (spi_read8(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK); +} + +STATIC EFI_STATUS wait_for_ready(VOID) +{ + CONST UINTN timeoutMilisecond = 500; + CONST UINT32 nanoToMiliDivider = 1000000; + CONST UINT64 startTimeMilisec = + DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); + CONST UINT64 endTimeMilisec = startTimeMilisec + timeoutMilisecond; + UINT64 timeNow = startTimeMilisec; + + do { + if (!(spi_read32(SPI_STATUS) & SPI_BUSY)) + return EFI_SUCCESS; + timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()),nanoToMiliDivider); + } while (timeNowstartTimeMilisec && timeNow>endTimeMilisec)); + + return EFI_DEVICE_ERROR; +} + +VOID spi_init(VOID) +{ + spi_get_bar(); +} + +STATIC VOID +InternalDumpData ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + for (Index = 0; Index < Size; Index++) { + DEBUG ((DEBUG_BLKIO, "%02x", (UINTN)Data[Index])); + } +} + +STATIC VOID +InternalDumpHex ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + UINTN Count; + UINTN Left; + +#define COLUME_SIZE (16 * 2) + + Count = Size / COLUME_SIZE; + Left = Size % COLUME_SIZE; + for (Index = 0; Index < Count; Index++) { + DEBUG ((DEBUG_BLKIO, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); + DEBUG ((DEBUG_BLKIO, "\n")); + } + + if (Left != 0) { + DEBUG ((DEBUG_BLKIO, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, Left); + DEBUG ((DEBUG_BLKIO, "\n")); + } +} + +STATIC VOID dump_state(UINT8 phase) +{ + UINT8 dump_size; + UINT32 addr; + + if (phase == 0) + DEBUG ((DEBUG_BLKIO, "SPI: Before execute\n")); + else + DEBUG ((DEBUG_BLKIO, "SPI: After execute\n")); + + DEBUG ((DEBUG_BLKIO, "Cntrl0: %x\n", spi_read32(SPI_CNTRL0))); + DEBUG ((DEBUG_BLKIO, "Status: %x\n", spi_read32(SPI_STATUS))); + + addr = spi_get_bar() + SPI_FIFO; + if (phase == 0) { + dump_size = spi_read8(SPI_TX_BYTE_COUNT); + DEBUG ((DEBUG_BLKIO, "TxByteCount: %x\n", dump_size)); + DEBUG ((DEBUG_BLKIO, "CmdCode: %x\n", spi_read8(SPI_CMD_CODE))); + } else { + dump_size = spi_read8(SPI_RX_BYTE_COUNT); + DEBUG ((DEBUG_BLKIO, "RxByteCount: %x\n", dump_size)); + addr += spi_read8(SPI_TX_BYTE_COUNT); + } + + if (dump_size > 0) + InternalDumpHex((VOID *)addr, dump_size); +} + +STATIC EFI_STATUS execute_command(void) +{ + dump_state(0); + + spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE); + + if (wait_for_ready()) + DEBUG((DEBUG_BLKIO, "%a: FCH_SC Error: Timeout executing command\n", __FUNCTION__)); + + dump_state(1); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) +{ + __SIZE_TYPE__ count; + UINT8 cmd; + UINT8 *bufin = din; + CONST UINT8 *bufout = dout; + + DEBUG((DEBUG_BLKIO, "%s(%x, %x)\n", __FUNCTION__, bytesout, bytesin)); + + /* First byte is cmd which cannot be sent through FIFO */ + cmd = bufout[0]; + bufout++; + bytesout--; + + /* + * Check if this is a write command attempting to transfer more bytes + * than the controller can handle. Iterations for writes are not + * supported here because each SPI write command needs to be preceded + * and followed by other SPI commands. + */ + if (bytesout + bytesin > SPI_FIFO_DEPTH) { + DEBUG((DEBUG_BLKIO, + "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + if (wait_for_ready()) + return EFI_DEVICE_ERROR; + + spi_write8(SPI_CMD_CODE, cmd); + spi_write8(SPI_TX_BYTE_COUNT, bytesout); + spi_write8(SPI_RX_BYTE_COUNT, bytesin); + + reset_internal_fifo_pointer(); + + for (count = 0; count < bytesout; count++) + spi_write8(SPI_FIFO + count, bufout[count]); + + reset_internal_fifo_pointer(); + if (execute_command()) + return EFI_DEVICE_ERROR; + + reset_internal_fifo_pointer(); + + for (count = 0; count < bytesin; count++) + bufin[count] = spi_read8(SPI_FIFO + count + bytesout); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS xfer_vectors(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count) +{ + return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); +} + +CONST struct spi_ctrlr fch_spi_flash_ctrlr = { + .xfer = spi_ctrlr_xfer, + .xfer_vector = xfer_vectors, + .max_xfer_size = SPI_FIFO_DEPTH, + .flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN, +}; + +CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { + { + .ctrlr = &fch_spi_flash_ctrlr, + .bus_start = 0, + .bus_end = 0, + }, +}; + +CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); diff --git a/UefiPayloadPkg/SPI/GenericSPI.c b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.c similarity index 74% rename from UefiPayloadPkg/SPI/GenericSPI.c rename to UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.c index 874891664e43..66f9bfbde983 100644 --- a/UefiPayloadPkg/SPI/GenericSPI.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.c @@ -5,12 +5,12 @@ #include #include "GenericSPI.h" -UINT32 spi_claim_bus(CONST struct spi_slave *slave) +EFI_STATUS spi_claim_bus(CONST struct spi_slave *slave) { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; if (ctrlr && ctrlr->claim_bus) return ctrlr->claim_bus(slave); - return 0; + return EFI_SUCCESS; } VOID spi_release_bus(CONST struct spi_slave *slave) @@ -20,40 +20,40 @@ VOID spi_release_bus(CONST struct spi_slave *slave) ctrlr->release_bus(slave); } -static INT32 spi_xfer_single_op(CONST struct spi_slave *slave, +STATIC EFI_STATUS spi_xfer_single_op(CONST struct spi_slave *slave, struct spi_op *op) { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; - INT32 ret; + EFI_STATUS status; if (!ctrlr || !ctrlr->xfer) - return -1; + return EFI_DEVICE_ERROR; - ret = ctrlr->xfer(slave, op->dout, op->bytesout, op->din, op->bytesin); - if (ret) + status = ctrlr->xfer(slave, op->dout, op->bytesout, op->din, op->bytesin); + if (status) op->status = SPI_OP_FAILURE; else op->status = SPI_OP_SUCCESS; - return ret; + return status; } -static INT32 spi_xfer_vector_default(CONST struct spi_slave *slave, +STATIC EFI_STATUS spi_xfer_vector_default(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count) { __SIZE_TYPE__ i; - INT32 ret; + EFI_STATUS status; for (i = 0; i < count; i++) { - ret = spi_xfer_single_op(slave, &vectors[i]); - if (ret) - return ret; + status = spi_xfer_single_op(slave, &vectors[i]); + if (status) + return status; } - return 0; + return EFI_SUCCESS; } -int spi_xfer_vector(const struct spi_slave *slave, +EFI_STATUS spi_xfer_vector(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count) { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; @@ -64,7 +64,7 @@ int spi_xfer_vector(const struct spi_slave *slave, return spi_xfer_vector_default(slave, vectors, count); } -UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, __SIZE_TYPE__ bytesout, +EFI_STATUS spi_xfer(CONST struct spi_slave *slave, CONST void *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) { CONST struct spi_ctrlr *ctrlr = slave->ctrlr; @@ -73,7 +73,7 @@ UINT32 spi_xfer(CONST struct spi_slave *slave, CONST void *dout, __SIZE_TYPE__ b return ctrlr->xfer(slave, dout, bytesout, din, bytesin); } - return -1; + return EFI_DEVICE_ERROR; } UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, @@ -102,7 +102,7 @@ UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, return MIN(ctrlr_max, buf_len); } -UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) +EFI_STATUS spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) { __SIZE_TYPE__ i; @@ -117,7 +117,7 @@ UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) } if (slave->ctrlr == NULL) - return -1; + return EFI_DEVICE_ERROR; slave->bus = bus; slave->cs = cs; @@ -125,5 +125,5 @@ UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) if (slave->ctrlr->setup) return slave->ctrlr->setup(slave); - return 0; + return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/SPI/GenericSPI.h b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h similarity index 85% rename from UefiPayloadPkg/SPI/GenericSPI.h rename to UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h index 0599a8e66add..7d1bb65fa699 100644 --- a/UefiPayloadPkg/SPI/GenericSPI.h +++ b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h @@ -3,6 +3,9 @@ #ifndef _SPI_GENERIC_H_ #define _SPI_GENERIC_H_ +#include +#include + /* Common parameters -- kind of high, but they should only occur when there * is a problem (and well your system already is broken), so err on the side * of caution in case we're dealing with slower SPI buses and/or processors. @@ -123,7 +126,6 @@ struct spi_flash { UINT8 wren_cmd; /* Write Enable command. */ const struct spi_flash_ops *ops; /* If !NULL all protection callbacks exist. */ - const struct spi_flash_protection_ops *prot_ops; const struct spi_flash_part_id *part; }; @@ -169,22 +171,19 @@ enum { * flash_protect: Protect a region of flash using the SPI flash controller. */ struct spi_ctrlr { - INT32 (*claim_bus)(const struct spi_slave *slave); + EFI_STATUS (*claim_bus)(const struct spi_slave *slave); VOID (*release_bus)(const struct spi_slave *slave); - INT32 (*setup)(const struct spi_slave *slave); - INT32 (*xfer)(const struct spi_slave *slave, const VOID *dout, + EFI_STATUS (*setup)(const struct spi_slave *slave); + EFI_STATUS (*xfer)(const struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); - INT32 (*xfer_vector)(const struct spi_slave *slave, + EFI_STATUS (*xfer_vector)(const struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count); - INT32 (*xfer_dual)(const struct spi_slave *slave, const VOID *dout, + EFI_STATUS (*xfer_dual)(const struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); UINT32 max_xfer_size; UINT32 flags; - INT32 (*flash_probe)(const struct spi_slave *slave, + EFI_STATUS (*flash_probe)(const struct spi_slave *slave, struct spi_flash *flash); - INT32 (*flash_protect)(const struct spi_flash *flash, - const struct region *region, - const enum ctrlr_prot_type type); }; /*----------------------------------------------------------------------- @@ -200,25 +199,6 @@ struct spi_ctrlr_buses { UINT32 bus_end; }; -/* - * SPI write protection is enforced by locking the status register. - * The following modes are known. It depends on the flash chip if the - * mode is actually supported. - * - * PRESERVE : Keep the previous status register lock-down setting (noop) - * NONE : Status register isn't locked - * PIN : Status register is locked as long as the ~WP pin is active - * REBOOT : Status register is locked until power failure - * PERMANENT: Status register is permanently locked - */ -enum spi_flash_status_reg_lockdown { - SPI_WRITE_PROTECTION_PRESERVE = -1, - SPI_WRITE_PROTECTION_NONE = 0, - SPI_WRITE_PROTECTION_PIN, - SPI_WRITE_PROTECTION_REBOOT, - SPI_WRITE_PROTECTION_PERMANENT -}; - /* Mapping of SPI buses to controllers - should be defined by platform. */ extern const struct spi_ctrlr_buses spi_ctrlr_bus_map[]; extern const __SIZE_TYPE__ spi_ctrlr_bus_map_count; @@ -239,7 +219,7 @@ VOID spi_init(VOID); * Returns: * 0 on success, -1 on error */ -UINT32 spi_get_config(CONST struct spi_slave *slave, struct spi_cfg *cfg); +EFI_STATUS spi_get_config(CONST struct spi_slave *slave, struct spi_cfg *cfg); /*----------------------------------------------------------------------- * Set up communications parameters for a SPI slave. @@ -256,7 +236,7 @@ UINT32 spi_get_config(CONST struct spi_slave *slave, struct spi_cfg *cfg); * Returns: * 0 on success, -1 on error */ -UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave); +EFI_STATUS spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave); /*----------------------------------------------------------------------- * Claim the bus and prepare it for communication with a given slave. @@ -272,7 +252,7 @@ UINT32 spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave); * Returns: 0 if the bus was claimed successfully, or a negative value * if it wasn't. */ -UINT32 spi_claim_bus(CONST struct spi_slave *slave); +EFI_STATUS spi_claim_bus(CONST struct spi_slave *slave); /*----------------------------------------------------------------------- * Release the SPI bus @@ -301,7 +281,7 @@ VOID spi_release_bus(CONST struct spi_slave *slave); * * Returns: 0 on success, not 0 on failure */ -UINT32 spi_xfer(CONST struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ bytesout, +EFI_STATUS spi_xfer(CONST struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); /*----------------------------------------------------------------------- @@ -314,7 +294,7 @@ UINT32 spi_xfer(CONST struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ b * * Returns: 0 on success, not 0 on failure */ -INT32 spi_xfer_vector(CONST struct spi_slave *slave, +EFI_STATUS spi_xfer_vector(CONST struct spi_slave *slave, struct spi_op vectors[], __SIZE_TYPE__ count); /*----------------------------------------------------------------------- @@ -344,7 +324,7 @@ STATIC inline INT32 spi_w8r8(CONST struct spi_slave *slave, unsigned char byte) dout[0] = byte; dout[1] = 0; - ret = spi_xfer(slave, dout, 2, din, 2); + ret = (INT32)spi_xfer(slave, dout, 2, din, 2); return ret < 0 ? ret : din[1]; } diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c new file mode 100644 index 000000000000..dbca670113ba --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c @@ -0,0 +1,482 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include "GenericSPI.h" +#include "SPIFlashInternal.h" + +STATIC VOID spi_flash_addr(UINT32 addr, UINT8 *cmd) +{ + /* cmd[0] is actual command */ + cmd[1] = addr >> 16; + cmd[2] = addr >> 8; + cmd[3] = addr >> 0; +} + +STATIC EFI_STATUS do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout, + __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) +{ + EFI_STATUS status; + /* + * SPI flash requires command-response kind of behavior. Thus, two + * separate SPI vectors are required -- first to transmit dout and other + * to receive in din. If some specialized SPI flash controllers + * (e.g. x86) can perform both command and response together, it should + * be handled at SPI flash controller driver level. + */ + struct spi_op vectors[] = { + [0] = { .dout = dout, .bytesout = bytes_out, + .din = NULL, .bytesin = 0, }, + [1] = { .dout = NULL, .bytesout = 0, + .din = din, .bytesin = bytes_in }, + }; + __SIZE_TYPE__ count = ARRAY_SIZE(vectors); + if (!bytes_in) + count = 1; + + status = spi_claim_bus(spi); + if (status) + return status; + + status = spi_xfer_vector(spi, vectors, count); + + spi_release_bus(spi); + return status; +} + +EFI_STATUS spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) +{ + EFI_STATUS status = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); + if (status) + DEBUG((DEBUG_BLKIO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, status)); + + return status; +} + +/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */ +#pragma GCC diagnostic push +#if defined(__GNUC__) && !defined(__clang__) +#pragma GCC diagnostic ignored "-Wstack-usage=" +#endif +#pragma GCC diagnostic ignored "-Wvla" +EFI_STATUS spi_flash_cmd_write(CONST struct spi_slave *spi, CONST UINT8 *cmd, + __SIZE_TYPE__ cmd_len, CONST VOID *data, __SIZE_TYPE__ data_len) +{ + EFI_STATUS status; + UINT8 buff[cmd_len + data_len]; + InternalMemCopyMem(buff, cmd, cmd_len); + InternalMemCopyMem(buff + cmd_len, data, data_len); + + status = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0); + if (status) { + DEBUG((DEBUG_BLKIO, "%a SF: Failed to send write command (%zu bytes): %d\n", + __FUNCTION__, data_len, status)); + } + + return status; +} +#pragma GCC diagnostic pop + +/* Perform the read operation honoring spi controller fifo size, reissuing + * the read command until the full request completed. */ +EFI_STATUS spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, VOID *buf) +{ + UINT8 cmd[5]; + EFI_STATUS status; + int cmd_len; + EFI_STATUS (*do_cmd)(CONST struct spi_slave *spi, CONST VOID *din, + __SIZE_TYPE__ in_bytes, VOID *out, __SIZE_TYPE__ out_bytes); + + cmd_len = 4; + cmd[0] = CMD_READ_ARRAY_SLOW; + do_cmd = do_spi_flash_cmd; + + UINT8 *data = buf; + while (len) { + __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); + spi_flash_addr(offset, cmd); + status = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); + if (status) { + DEBUG((DEBUG_BLKIO, + "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", + __FUNCTION__, cmd[0], offset, xfer_len, status)); + return status; + } + offset += xfer_len; + data += xfer_len; + len -= xfer_len; + } + + return EFI_SUCCESS; +} + +EFI_STATUS spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long timeout, + UINT8 cmd, UINT8 poll_bit) +{ + CONST struct spi_slave *spi = &flash->spi; + EFI_STATUS status; + + CONST UINT32 nanoToMiliDivider = 1000000; + CONST UINT32 startTimeMilisec = + DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); + CONST UINT32 endTimeMilisec = startTimeMilisec + timeout; + UINT32 timeNow = startTimeMilisec; + + do { + status = do_spi_flash_cmd(spi, &cmd, 1, &status, 1); + if (status) + return EFI_DEVICE_ERROR; + if ((status & poll_bit) == 0) + return EFI_SUCCESS; + timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); + } while ( + timeNowstartTimeMilisec && timeNow>endTimeMilisec)); + + DEBUG((DEBUG_BLKIO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); + return EFI_DEVICE_ERROR; +} + +EFI_STATUS spi_flash_cmd_wait_ready(CONST struct spi_flash *flash, + unsigned long timeout) +{ + return spi_flash_cmd_poll_bit(flash, timeout, + CMD_READ_STATUS, STATUS_WIP); +} + +EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) +{ + UINT32 start, end, erase_size; + EFI_STATUS status = EFI_DEVICE_ERROR; + UINT8 cmd[4]; + + erase_size = flash->sector_size; + if (offset % erase_size || len % erase_size) { + DEBUG((DEBUG_BLKIO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + if (len == 0) { + DEBUG((DEBUG_BLKIO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + cmd[0] = flash->erase_cmd; + start = offset; + end = start + len; + + while (offset < end) { + spi_flash_addr(offset, cmd); + offset += erase_size; + + DEBUG((DEBUG_BLKIO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION__, + cmd[0], cmd[1], cmd[2], cmd[3], offset)); + + status = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0); + if (status) + goto out; + + status = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0); + if (status) + goto out; + + status = spi_flash_cmd_wait_ready(flash, + SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); + if (status) + goto out; + } + + DEBUG((DEBUG_BLKIO, "%a SF: Successfully erased %u bytes @ %x\n", + __FUNCTION__, len, start)); + +out: + return status; +} + +EFI_STATUS spi_flash_cmd_status(CONST struct spi_flash *flash, UINT8 *reg) +{ + return spi_flash_cmd(&flash->spi, flash->status_cmd, reg, sizeof(*reg)); +} + +EFI_STATUS spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, CONST VOID *buf) +{ + unsigned long byte_addr; + unsigned long page_size; + __SIZE_TYPE__ chunk_len; + __SIZE_TYPE__ actual; + EFI_STATUS status = EFI_SUCCESS; + UINT8 cmd[4]; + + page_size = flash->page_size; + cmd[0] = flash->pp_cmd; + + for (actual = 0; actual < len; actual += chunk_len) { + byte_addr = offset % page_size; + chunk_len = MIN(len - actual, page_size - byte_addr); + chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len); + + spi_flash_addr(offset, cmd); + DEBUG((DEBUG_BLKIO, "%a PP: %p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %u\n", + __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], + chunk_len)); + + status = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0); + if (status < 0) { + DEBUG((DEBUG_BLKIO, "%a SF: Enabling Write failed\n", __FUNCTION__)); + goto out; + } + + status = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), + buf + actual, chunk_len); + if (status < 0) { + DEBUG((DEBUG_BLKIO, "%a SF: Page Program failed\n", __FUNCTION__)); + goto out; + } + + status = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS); + if (status) + goto out; + + offset += chunk_len; + } + status = EFI_SUCCESS; + +out: + return status; +} + +EFI_STATUS spi_flash_read(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf) +{ + return flash->ops->read(flash, offset, len, buf); +} + +EFI_STATUS spi_flash_write(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, CONST VOID *buf) +{ + return flash->ops->write(flash, offset, len, buf); +} + +EFI_STATUS spi_flash_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) +{ + return flash->ops->erase(flash, offset, len); +} + +EFI_STATUS spi_flash_status(CONST struct spi_flash *flash, UINT8 *reg) +{ + if (flash->ops->status) + return flash->ops->status(flash, reg); + + return EFI_DEVICE_ERROR; +} + +EFI_STATUS spi_flash_vector_helper(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + EFI_STATUS (*func)(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) +{ + EFI_STATUS status; + VOID *din; + __SIZE_TYPE__ bytes_in; + + if (count < 1 || count > 2) + return -1; + + /* SPI flash commands always have a command first... */ + if (!vectors[0].dout || !vectors[0].bytesout) + return EFI_DEVICE_ERROR; + /* And not read any data during the command. */ + if (vectors[0].din || vectors[0].bytesin) + return EFI_DEVICE_ERROR; + + if (count == 2) { + /* If response bytes requested ensure the buffer is valid. */ + if (vectors[1].bytesin && !vectors[1].din) + return EFI_DEVICE_ERROR; + /* No sends can accompany a receive. */ + if (vectors[1].dout || vectors[1].bytesout) + return EFI_DEVICE_ERROR; + din = vectors[1].din; + bytes_in = vectors[1].bytesin; + } else { + din = NULL; + bytes_in = 0; + } + + status = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); + + if (status) { + vectors[0].status = SPI_OP_FAILURE; + if (count == 2) + vectors[1].status = SPI_OP_FAILURE; + } else { + vectors[0].status = SPI_OP_SUCCESS; + if (count == 2) + vectors[1].status = SPI_OP_SUCCESS; + } + + return status; +} + +STATIC CONST struct spi_flash_vendor_info *spi_flash_vendors[] = { + &spi_flash_adesto_vi, + &spi_flash_winbond_vi, +}; + +#define IDCODE_LEN 5 + +STATIC CONST struct spi_flash_part_id *find_part(CONST struct spi_flash_vendor_info *vi, + UINT16 id[2]) +{ + __SIZE_TYPE__ i; + CONST UINT16 lid[2] = { + [0] = id[0] & vi->match_id_mask[0], + [1] = id[1] & vi->match_id_mask[1], + }; + + for (i = 0; i < vi->nr_part_ids; i++) { + CONST struct spi_flash_part_id *part = &vi->ids[i]; + + if (part->id[0] == lid[0] && part->id[1] == lid[1]) + return part; + } + + return NULL; +} + +STATIC EFI_STATUS fill_spi_flash(const struct spi_slave *spi, struct spi_flash *flash, + CONST struct spi_flash_vendor_info *vi, + CONST struct spi_flash_part_id *part) +{ + InternalMemCopyMem(&flash->spi, spi, sizeof(*spi)); + flash->vendor = vi->id; + flash->model = part->id[0]; + + flash->page_size = 1U << vi->page_size_shift; + flash->sector_size = (1U << vi->sector_size_kib_shift) * (1<<10); /* KiB */ + flash->size = flash->sector_size * (1U << part->nr_sectors_shift); + flash->erase_cmd = vi->desc->erase_cmd; + flash->status_cmd = vi->desc->status_cmd; + flash->pp_cmd = vi->desc->pp_cmd; + flash->wren_cmd = vi->desc->wren_cmd; + + flash->flags.dual_spi = part->fast_read_dual_output_support; + + flash->ops = &vi->desc->ops; + flash->part = part; + + if (vi->after_probe) + return vi->after_probe(flash); + + return EFI_SUCCESS; +} + +STATIC EFI_STATUS find_match(CONST struct spi_slave *spi, struct spi_flash *flash, + UINT8 manuf_id, UINT16 id[2]) +{ + UINTN i; + + for (i = 0; i < (UINTN)ARRAY_SIZE(spi_flash_vendors); i++) { + CONST struct spi_flash_vendor_info *vi; + CONST struct spi_flash_part_id *part; + + vi = spi_flash_vendors[i]; + + if (manuf_id != vi->id) + continue; + + part = find_part(vi, id); + + if (part == NULL) + continue; + + return fill_spi_flash(spi, flash, vi, part); + } + + return EFI_NOT_FOUND; +} + +STATIC EFI_STATUS spi_flash_generic_probe(CONST struct spi_slave *spi, + struct spi_flash *flash) +{ + EFI_STATUS status; + UINT8 idcode[IDCODE_LEN]; + UINT8 manuf_id; + UINT16 id[2]; + + /* Read the ID codes */ + status = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); + if (status) + return EFI_DEVICE_ERROR; + + manuf_id = idcode[0]; + + DEBUG((DEBUG_BLKIO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); + + id[0] = (idcode[1] << 8) | idcode[2]; + id[1] = (idcode[3] << 8) | idcode[4]; + + return find_match(spi, flash, manuf_id, id); +} + +EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) +{ + struct spi_slave spi; + EFI_STATUS status = EFI_DEVICE_ERROR; + + if (spi_setup_slave(bus, cs, &spi)) { + DEBUG((DEBUG_BLKIO, "SF: Failed to set up slave\n")); + return EFI_DEVICE_ERROR; + } + + /* Try special programmer probe if any. */ + if (spi.ctrlr->flash_probe) + status = spi.ctrlr->flash_probe(&spi, flash); + + /* If flash is not found, try generic spi flash probe. */ + if (status) + status = spi_flash_generic_probe(&spi, flash); + + /* Give up -- nothing more to try if flash is not found. */ + if (status) { + DEBUG((DEBUG_BLKIO, "SF: Unsupported manufacturer!\n")); + return EFI_DEVICE_ERROR; + } + + CONST char *mode_string = ""; + if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) + mode_string = " (Dual SPI mode)"; + + DEBUG((DEBUG_BLKIO, + "SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", + flash->vendor, flash->model, flash->sector_size, flash->size, mode_string)); + + return EFI_SUCCESS; +} + +CONST struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc = { + .erase_cmd = 0x20, /* Sector Erase */ + .status_cmd = 0x05, /* Read Status */ + .pp_cmd = 0x02, /* Page Program */ + .wren_cmd = 0x06, /* Write Enable */ + .ops = { + .read = spi_flash_cmd_read, + .write = spi_flash_cmd_write_page_program, + .erase = spi_flash_cmd_erase, + .status = spi_flash_cmd_status, + }, +}; + +CONST struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc = { + .erase_cmd = 0xd8, /* Sector Erase */ + .status_cmd = 0x05, /* Read Status */ + .pp_cmd = 0x02, /* Page Program */ + .wren_cmd = 0x06, /* Write Enable */ + .ops = { + .read = spi_flash_cmd_read, + .write = spi_flash_cmd_write_page_program, + .erase = spi_flash_cmd_erase, + .status = spi_flash_cmd_status, + }, +}; diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.h b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.h new file mode 100644 index 000000000000..7a566cf9c1f4 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.h @@ -0,0 +1,169 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +/* + * SPI flash internal definitions + */ + +#ifndef __SPI_FLASH_INTERNAL_H__ +#define __SPI_FLASH_INTERNAL_H__ + +#include +#include +#include "GenericSPI.h" + + +/* Common commands */ +#define CMD_READ_ID 0x9f + +#define CMD_READ_ARRAY_SLOW 0x03 +#define CMD_READ_ARRAY_FAST 0x0b +#define CMD_READ_ARRAY_LEGACY 0xe8 +#define CMD_READ_FAST_DUAL_OUTPUT 0x3b +#define CMD_READ_STATUS 0x05 +#define CMD_WRITE_ENABLE 0x06 +#define CMD_BLOCK_ERASE 0xD8 + +/* Common status */ +#define STATUS_WIP 0x01 + +/* + * Representation of SPI flash operations: + * read: Flash read operation. + * write: Flash write operation. + * erase: Flash erase operation. + * status: Read flash status register. + */ +struct spi_flash_ops { + EFI_STATUS (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + VOID *buf); + EFI_STATUS (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, + CONST VOID *buf); + EFI_STATUS (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + EFI_STATUS (*status)(CONST struct spi_flash *flash, UINT8 *reg); +}; + +enum optype { + READ_NO_ADDR = 0, + WRITE_NO_ADDR = 1, + READ_WITH_ADDR = 2, + WRITE_WITH_ADDR = 3 +}; + +/* Send a single-byte command to the device and read the response */ +EFI_STATUS spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); + +/* + * Send a multi-byte command to the device followed by (optional) + * data. Used for programming the flash array, etc. + */ +EFI_STATUS spi_flash_cmd_write(CONST struct spi_slave *spi, CONST UINT8 *cmd, + __SIZE_TYPE__ cmd_len, CONST VOID *data, __SIZE_TYPE__ data_len); + +/* Send a command to the device and wait for some bit to clear itself. */ +EFI_STATUS spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long timeout, + UINT8 cmd, UINT8 poll_bit); + +/* + * Send the read status command to the device and wait for the wip + * (write-in-progress) bit to clear itself. + */ +EFI_STATUS spi_flash_cmd_wait_ready(CONST struct spi_flash *flash, unsigned long timeout); + +/* Erase sectors. */ +EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); + +/* Read status register. */ +EFI_STATUS spi_flash_cmd_status(CONST struct spi_flash *flash, UINT8 *reg); + +/* Write to flash utilizing page program semantics. */ +EFI_STATUS spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT32 offset, + __SIZE_TYPE__ len, CONST VOID *buf); + +/* Read len bytes into buf at offset. */ +EFI_STATUS spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); + +EFI_STATUS spi_flash_vector_helper(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count, + EFI_STATUS (*func)(CONST struct spi_slave *slave, CONST VOID *dout, + __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)); + +EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash); + +EFI_STATUS spi_flash_read(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); +EFI_STATUS spi_flash_write(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, CONST VOID *buf); +EFI_STATUS spi_flash_erase(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); +EFI_STATUS spi_flash_status(CONST struct spi_flash *flash, UINT8 *reg); + +struct spi_flash_part_id { + /* rdid command CONSTructs 2x 16-bit id using the following method + * for matching after reading 5 bytes (1st byte is manuf id): + * id[0] = (id[1] << 8) | id[2] + * id[1] = (id[3] << 8) | id[4] + */ + UINT16 id[2]; + /* Log based 2 total number of sectors. */ + UINT16 nr_sectors_shift: 4; + UINT16 fast_read_dual_output_support : 1; + UINT16 _reserved_for_flags: 3; + /* Block protection. Currently used by Winbond. */ + UINT16 protection_granularity_shift : 5; + UINT16 bp_bits : 3; +}; + +struct spi_flash_ops_descriptor { + UINT8 erase_cmd; /* Sector Erase */ + UINT8 status_cmd; /* Read Status Register */ + UINT8 pp_cmd; /* Page program command, if supported. */ + UINT8 wren_cmd; /* Write Enable command. */ + struct spi_flash_ops ops; +}; + +/* Vendor info represents a common set of organization and commands by a given + * vendor. One can implement multiple sets from a single vendor by having + * separate objects. */ +struct spi_flash_vendor_info { + UINT8 id; + UINT8 page_size_shift : 4; /* if page programming oriented. */ + /* Log based 2 sector size */ + UINT8 sector_size_kib_shift : 4; + UINT16 nr_part_ids; + CONST struct spi_flash_part_id *ids; + UINT16 match_id_mask[2]; /* matching bytes of the id for this set*/ + CONST struct spi_flash_ops_descriptor *desc; + /* Returns 0 on success. !0 otherwise. */ + int (*after_probe)(CONST struct spi_flash *flash); +}; + +union pci_bank { + UINT8 reg8[4096]; + UINT16 reg16[4096 / sizeof(UINT16)]; + UINT32 reg32[4096 / sizeof(UINT32)]; +}; + +VOID spi_init(VOID); + +/* Manufacturer-specific probe information */ +extern CONST struct spi_flash_vendor_info spi_flash_adesto_vi; +extern CONST struct spi_flash_vendor_info spi_flash_amic_vi; +extern CONST struct spi_flash_vendor_info spi_flash_atmel_vi; +extern CONST struct spi_flash_vendor_info spi_flash_eon_vi; +extern CONST struct spi_flash_vendor_info spi_flash_gigadevice_vi; +extern CONST struct spi_flash_vendor_info spi_flash_macronix_vi; +/* Probing order matters between the spansion sequence. */ +extern CONST struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; +extern CONST struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; +extern CONST struct spi_flash_vendor_info spi_flash_spansion_vi; +extern CONST struct spi_flash_vendor_info spi_flash_sst_ai_vi; +extern CONST struct spi_flash_vendor_info spi_flash_sst_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro1_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro2_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro3_vi; +extern CONST struct spi_flash_vendor_info spi_flash_stmicro4_vi; +extern CONST struct spi_flash_vendor_info spi_flash_winbond_vi; + +/* Page Programming Command Set with 0x20 Sector Erase command. */ +extern CONST struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; +/* Page Programming Command Set with 0xd8 Sector Erase command. */ +extern CONST struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; + +#endif /* __SPI_FLASH_INTERNAL_H__ */ diff --git a/UefiPayloadPkg/Library/AmdSpiLib/Winbond.c b/UefiPayloadPkg/Library/AmdSpiLib/Winbond.c new file mode 100644 index 000000000000..a9a451a5bd64 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/Winbond.c @@ -0,0 +1,211 @@ +#include +#include "SPIFlashInternal.h" +#include "Winbond.h" + +union status_reg1 { + UINT8 u; + struct { + UINT8 busy : 1; + UINT8 wel : 1; + UINT8 bp : 3; + UINT8 tb : 1; + UINT8 sec : 1; + UINT8 srp0 : 1; + } bp3; + struct { + UINT8 busy : 1; + UINT8 wel : 1; + UINT8 bp : 4; + UINT8 tb : 1; + UINT8 srp0 : 1; + } bp4; +}; + +union status_reg2 { + UINT8 u; + struct { + UINT8 srp1 : 1; + UINT8 qe : 1; + UINT8 res : 1; + UINT8 lb : 3; + UINT8 cmp : 1; + UINT8 sus : 1; + }; +}; + +struct status_regs { + union { + struct { +#if defined(__BIG_ENDIAN) + union status_reg2 reg2; + union status_reg1 reg1; +#else + union status_reg1 reg1; + union status_reg2 reg2; +#endif + }; + UINT16 u; + }; +}; + +static const struct spi_flash_part_id flash_table[] = { + { + /* W25P80 */ + .id[0] = 0x2014, + .nr_sectors_shift = 8, + }, + { + /* W25P16 */ + .id[0] = 0x2015, + .nr_sectors_shift = 9, + }, + { + /* W25P32 */ + .id[0] = 0x2016, + .nr_sectors_shift = 10, + }, + { + /* W25X80 */ + .id[0] = 0x3014, + .nr_sectors_shift = 8, + .fast_read_dual_output_support = 1, + }, + { + /* W25X16 */ + .id[0] = 0x3015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + }, + { + /* W25X32 */ + .id[0] = 0x3016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + }, + { + /* W25X64 */ + .id[0] = 0x3017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + }, + { + /* W25Q80_V */ + .id[0] = 0x4014, + .nr_sectors_shift = 8, + .fast_read_dual_output_support = 1, + }, + { + /* W25Q16_V */ + .id[0] = 0x4015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q16DW */ + .id[0] = 0x6015, + .nr_sectors_shift = 9, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q32_V */ + .id[0] = 0x4016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q32DW */ + .id[0] = 0x6016, + .nr_sectors_shift = 10, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 3, + }, + { + /* W25Q64_V */ + .id[0] = 0x4017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q64DW */ + .id[0] = 0x6017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q64JW */ + .id[0] = 0x8017, + .nr_sectors_shift = 11, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 17, + .bp_bits = 3, + }, + { + /* W25Q128_V */ + .id[0] = 0x4018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128FW */ + .id[0] = 0x6018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128J */ + .id[0] = 0x7018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q128JW */ + .id[0] = 0x8018, + .nr_sectors_shift = 12, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 18, + .bp_bits = 3, + }, + { + /* W25Q256_V */ + .id[0] = 0x4019, + .nr_sectors_shift = 13, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 4, + }, + { + /* W25Q256J */ + .id[0] = 0x7019, + .nr_sectors_shift = 13, + .fast_read_dual_output_support = 1, + .protection_granularity_shift = 16, + .bp_bits = 4, + }, +}; + +CONST struct spi_flash_vendor_info spi_flash_winbond_vi = { + .id = VENDOR_ID_WINBOND, + .page_size_shift = 8, + .sector_size_kib_shift = 2, + .match_id_mask[0] = 0xffff, + .ids = flash_table, + .nr_part_ids = ARRAY_SIZE(flash_table), + .desc = &spi_flash_pp_0x20_sector_desc, +}; diff --git a/UefiPayloadPkg/SPI/Winbond.h b/UefiPayloadPkg/Library/AmdSpiLib/Winbond.h similarity index 100% rename from UefiPayloadPkg/SPI/Winbond.h rename to UefiPayloadPkg/Library/AmdSpiLib/Winbond.h diff --git a/UefiPayloadPkg/SPI/FchSPICtrl.c b/UefiPayloadPkg/SPI/FchSPICtrl.c deleted file mode 100644 index 9fe365f873d2..000000000000 --- a/UefiPayloadPkg/SPI/FchSPICtrl.c +++ /dev/null @@ -1,156 +0,0 @@ -#include -#include -#include -#include -#include -#include "FchSPIUtil.h" -#include "GenericSPI.h" -#include "SPI.h" -#include "SPIFlashInternal.h" - -/* SPDX-License-Identifier: GPL-2.0-only */ - -#define GRANULARITY_TEST_4k 0x0000f000 /* bits 15-12 */ -#define WORD_TO_DWORD_UPPER(x) ((x << 16) & 0xffff0000) - -/* SPI MMIO registers */ -#define SPI_RESTRICTED_CMD1 0x04 -#define SPI_RESTRICTED_CMD2 0x08 -#define SPI_CNTRL1 0x0c -#define SPI_CMD_CODE 0x45 -#define SPI_CMD_TRIGGER 0x47 -#define SPI_CMD_TRIGGER_EXECUTE 0x80 -#define SPI_TX_BYTE_COUNT 0x48 -#define SPI_RX_BYTE_COUNT 0x4b -#define SPI_STATUS 0x4c -#define SPI_DONE_BYTE_COUNT_SHIFT 0 -#define SPI_DONE_BYTE_COUNT_MASK 0xff -#define SPI_FIFO_WR_PTR_SHIFT 8 -#define SPI_FIFO_WR_PTR_MASK 0x7f -#define SPI_FIFO_RD_PTR_SHIFT 16 -#define SPI_FIFO_RD_PTR_MASK 0x7f - -#define MAX_ROM_PROTECT_RANGES 4 -#define ROM_PROTECT_RANGE0 0x50 -#define ROM_PROTECT_RANGE_REG(n) (ROM_PROTECT_RANGE0 + (4 * n)) - -static int wait_for_ready(VOID) -{ - CONST UINTN timeoutMilisecond = 500; - CONST UINT32 nanoToMiliDivider = 1000000; - CONST UINT64 startTimeMilisec = - DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); - CONST UINT64 endTimeMilisec = startTimeMilisec + timeoutMilisecond; - UINT64 timeNow = startTimeMilisec; - - do { - if (!(spi_read32(SPI_STATUS) & SPI_BUSY)) - return 0; - timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()),nanoToMiliDivider); - } while (timeNowstartTimeMilisec && timeNow>endTimeMilisec)); - - return -1; -} - -int execute_command(VOID) -{ - spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE); - if(wait_for_ready()) - DEBUG((EFI_D_INFO, - "%a: FCH_SC Error: Timeout executing command\n", __FUNCTION__)); - - return 0; -} - -VOID spi_init(VOID) -{ - spi_get_bar(); -} - -int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin) -{ - __SIZE_TYPE__ count; - UINT8 cmd; - UINT8 *bufin = din; - CONST UINT8 *bufout = dout; - - /* First byte is cmd which cannot be sent through FIFO */ - cmd = bufout[0]; - bufout++; - bytesout--; - - /* - * Check if this is a write command attempting to transfer more bytes - * than the controller can handle. Iterations for writes are not - * supported here because each SPI write command needs to be preceded - * and followed by other SPI commands. - */ - if (bytesout + bytesin > SPI_FIFO_DEPTH) { - DEBUG((EFI_D_INFO, - "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); - return -1; - } - - if (wait_for_ready()) - return -1; - - spi_write8(SPI_CMD_CODE, cmd); - spi_write8(SPI_TX_BYTE_COUNT, bytesout); - spi_write8(SPI_RX_BYTE_COUNT, bytesin); - - for (count = 0; count < bytesout; count++) - spi_write8(SPI_FIFO + count, bufout[count]); - - if (execute_command()) - return -1; - - for (count = 0; count < bytesin; count++) - bufin[count] = spi_read8(SPI_FIFO + count + bytesout); - - return 0; -} - -int xfer_vectors(CONST struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count) -{ - return spi_flash_vector_helper(slave, vectors, count, spi_ctrlr_xfer); -} - -int protect_a_range(UINT32 value) -{ - UINT32 reg32; - UINT8 n; - - /* find a free protection register */ - for (n = 0; n < MAX_ROM_PROTECT_RANGES; n++) { - reg32 = PciRead32( - PCI_LIB_ADDRESS(PCU_BUS, PCU_DEV, LPC_FUNC, ROM_PROTECT_RANGE_REG(n))); - if (!reg32) - break; - } - if (n == MAX_ROM_PROTECT_RANGES) - return -1; /* no free range */ - - PciWrite32( - PCI_LIB_ADDRESS(PCU_BUS, PCU_DEV, LPC_FUNC, ROM_PROTECT_RANGE_REG(n)), - value); - return 0; -} - -CONST struct spi_ctrlr fch_spi_flash_ctrlr = { - .xfer = spi_ctrlr_xfer, - .xfer_vector = xfer_vectors, - .max_xfer_size = SPI_FIFO_DEPTH, - .flags = SPI_CNTRLR_DEDUCT_CMD_LEN | SPI_CNTRLR_DEDUCT_OPCODE_LEN, -}; - -CONST struct spi_ctrlr_buses spi_ctrlr_bus_map[] = { - { - .ctrlr = &fch_spi_flash_ctrlr, - .bus_start = 0, - .bus_end = 0, - }, -}; - -CONST __SIZE_TYPE__ spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map); diff --git a/UefiPayloadPkg/SPI/FchSPICtrl.h b/UefiPayloadPkg/SPI/FchSPICtrl.h deleted file mode 100644 index c4efab3e9562..000000000000 --- a/UefiPayloadPkg/SPI/FchSPICtrl.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef FCH_SPI_CTRL_H -#define FCH_SPI_CTRL_H - -#include -#include "GenericSPI.h" - -union pci_bank { - UINT8 reg8[4096]; - UINT16 reg16[4096 / sizeof(UINT16)]; - UINT32 reg32[4096 / sizeof(UINT32)]; -}; - -int execute_command(VOID); -VOID spi_init(VOID); -int spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin); -int xfer_vectors(CONST struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count); -int protect_a_range(UINT32 value); - -/* - * Protect range of SPI flash defined by region using the SPI flash controller. - * - * Note: Up to 4 ranges can be protected, though if a particular region requires more than one - * range, total number of regions decreases accordingly. Each range can be programmed to 4KiB or - * 64KiB granularity. - * - * Warning: If more than 1 region needs protection, and they need mixed protections (read/write) - * than start with the region that requires the most protection. After the restricted commands - * have been written, they can't be changed (write once). So if first region is write protection - * and second region is read protection, it's best to define first region as read and write - * protection. - */ -int fch_spi_flash_protect(CONST struct spi_flash *flash, CONST struct region *region, - CONST enum ctrlr_prot_type type); - -#endif /* FCH_SPI_CTRL_H */ diff --git a/UefiPayloadPkg/SPI/FchSPIUtil.c b/UefiPayloadPkg/SPI/FchSPIUtil.c deleted file mode 100644 index c8d282dd9302..000000000000 --- a/UefiPayloadPkg/SPI/FchSPIUtil.c +++ /dev/null @@ -1,67 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -#include -#include -#include -#include -#include "FchSPICtrl.h" -#include "FchSPIUtil.h" -#include "SPI.h" - -#define _LPCB_DEV PCI_DEV(0, 0x14, 0x3) -#define SPIROM_BASE_ADDRESS_REGISTER 0xa0 -#define SPI_BASE_ALIGNMENT 0x00000040 -#define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) - -static UINTN spi_base = 0; - -UINTN lpc_get_spibase(VOID) -{ - UINT32 base; - base = PciRead32( - PCI_LIB_ADDRESS(PCU_BUS, PCU_DEV, LPC_FUNC, SPIROM_BASE_ADDRESS_REGISTER)); - base = ALIGN_DOWN(base, SPI_BASE_ALIGNMENT); - return (unsigned long int)base; -} - -VOID spi_set_base(UINTN base) -{ - spi_base = base; -} - -UINTN spi_get_bar(VOID) -{ - if (spi_base == 0) { - spi_set_base(lpc_get_spibase()); - } - return spi_base; -} - -UINT8 spi_read8(UINT8 reg) -{ - return MmioRead8((spi_get_bar() + reg)); -} - -UINT16 spi_read16(UINT8 reg) -{ - return MmioRead16((spi_get_bar() + reg)); -} - -UINT32 spi_read32(UINT8 reg) -{ - return MmioRead32((spi_get_bar() + reg)); -} - -VOID spi_write8(UINT8 reg, UINT8 val) -{ - MmioWrite8((spi_get_bar() + reg), val); -} - -VOID spi_write16(UINT8 reg, UINT16 val) -{ - MmioWrite16((spi_get_bar() + reg), val); -} - -VOID spi_write32(UINT8 reg, UINT32 val) -{ - MmioWrite32((spi_get_bar() + reg), val); -} diff --git a/UefiPayloadPkg/SPI/FchSPIUtil.h b/UefiPayloadPkg/SPI/FchSPIUtil.h deleted file mode 100644 index b12408008797..000000000000 --- a/UefiPayloadPkg/SPI/FchSPIUtil.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef FCH_SPI_UTIL_H -#define FCH_SPI_UTIL_H - -#include - -UINTN lpc_get_spibase(VOID); -VOID spi_set_base(UINTN base); -UINTN spi_get_bar(VOID); -UINT8 spi_read8(UINT8 reg); -UINT16 spi_read16(UINT8 reg); -UINT32 spi_read32(UINT8 reg); -VOID spi_write8(UINT8 reg, UINT8 val); -VOID spi_write16(UINT8 reg, UINT16 val); -VOID spi_write32(UINT8 reg, UINT32 val); - -#endif /* FCH_SPI_UTIL_H */ diff --git a/UefiPayloadPkg/SPI/Fvb.c b/UefiPayloadPkg/SPI/Fvb.c deleted file mode 100644 index a8bb82156fcb..000000000000 --- a/UefiPayloadPkg/SPI/Fvb.c +++ /dev/null @@ -1,951 +0,0 @@ -#include -#include -#include -#include -#include "Fvb.h" -#include "FvbSPI.h" -#include "GenericSPI.h" -#include "SPI.h" -#include "SPIFlashInternal.h" -#include "Winbond.h" - - -#define ADDRESS(Lba, Offset) (((BLOCK_SIZE) * ((Lba)+(VARIABLE_STORAGE_BLOCKS_OFFSET))) + (Offset)) -#define OFFSET_FROM_PAGE_START(Address) ((Address) % (PAGE_SIZE)) -#define REMAINING_SPACE(Offset, MaxSize) ((MaxSize) - (Offset)) -#define REMAINING_SPACE_IN_BLOCK(Offset) REMAINING_SPACE((Offset), (BLOCK_SIZE)) -#define REMAINING_SPACE_IN_PAGE(Offset) REMAINING_SPACE((Offset), (PAGE_SIZE)) - -static struct spi_slave *getSPISlave(); -static EFI_STATUS FvbEraseBlockAtAddress(UINTN Address); -static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN amount); -static EFI_STATUS readStatusReg(UINT8 *Status); -static EFI_STATUS checkBusyBit(UINT8 *Busy); -static EFI_STATUS WaitForBusyBit(); -static EFI_STATUS FvbNextBlocksFromList( - VA_LIST *Args, - EFI_LBA *Lba, - UINTN *LbaCount); -static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args); -static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba); -static EFI_STATUS FvbVerifyBlockReadability(EFI_LBA Lba); -static EFI_STATUS FvbVerifyConsecutiveBlocksWritability( - EFI_LBA Lba, - UINTN LbaCount); -static EFI_STATUS FvbVerifyBlocksWritability(VA_LIST *Args); -static UINTN FvbGetTotalNumberOfBlocks(); -static EFI_STATUS WriteEnable(); -static EFI_STATUS PageProgram( - CONST UINTN Address, - CONST UINT8 *Buffer, - UINTN *NumBytes); -static BOOLEAN FvbIsBlockValid(EFI_LBA Lba); -static EFI_STATUS ReadArray( - CONST UINTN Address, - UINT8 *Buffer, - UINTN *NumBytes); - -static struct spi_slave *getSPISlave() { - static struct spi_slave slave; - if(slave.ctrlr == NULL) { - spi_setup_slave(0, 0, &slave); - } - return &slave; -} - -static EFI_STATUS FvbEraseBlockAtAddress(UINTN Address) { - WaitForBusyBit(); - WriteEnable(); - UINT8 blockEraseCmd[] = { - CMD_BLOCK_ERASE, - (UINT8)((Address & 0xFF0000) >> 16), - (UINT8)((Address & 0xFF00) >> 8), - (UINT8) (Address & 0xFF) - }; - if(spi_xfer( - getSPISlave(), blockEraseCmd, ARRAY_SIZE(blockEraseCmd), NULL, 0) - ) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -static EFI_STATUS FvbEraseConsecutiveBlocks(EFI_LBA Lba, UINTN Amount) { - BOOLEAN error = FALSE; - for(UINTN current = 0; current < Amount; ++current) { - if(FvbEraseBlockAtAddress(0x60000/*ADDRESS(Lba+current, 0)*/) != EFI_SUCCESS) { - error = TRUE; - } - } - if(error) { - return EFI_DEVICE_ERROR; - } else { - return EFI_SUCCESS; - } -} - -static EFI_STATUS readStatusReg(UINT8 *Status) { - UINT8 readStatusCmd[] = { - CMD_READ_STATUS - }; - if(spi_xfer( - getSPISlave(), readStatusCmd, ARRAY_SIZE(readStatusCmd), Status, 1) - ) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -static EFI_STATUS writeStatusReg(UINT8 Status) { - UINT8 readStatusCmd[] = { - STATUS_WIP, - Status - }; - if(spi_xfer( - getSPISlave(), readStatusCmd, ARRAY_SIZE(readStatusCmd), NULL, 0) - ) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -static EFI_STATUS checkBusyBit(UINT8 *Busy) { - if(readStatusReg(Busy) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - *Busy &= REG_BUSY_MASK; - return EFI_SUCCESS; -} - -static EFI_STATUS WaitForBusyBit() { - UINT8 busy = 0xFF; - while(busy != 0) { - if(checkBusyBit(&busy) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - } - return EFI_SUCCESS; -} - -static EFI_STATUS FvbNextBlocksFromList( - VA_LIST *Args, - EFI_LBA *Lba, - UINTN *LbaCount -) { - *Lba = VA_ARG(*Args, EFI_LBA); - if(*Lba == EFI_LBA_LIST_TERMINATOR) { - return EFI_SUCCESS; - } - *LbaCount = VA_ARG(*Args, EFI_LBA); - // To forget an argument is an easy mistake to do. - // Better check for it and try to warn a programmer. - if(*LbaCount == EFI_LBA_LIST_TERMINATOR) { - DEBUG(( - EFI_D_INFO, "%a WARNING: invalid number of parameters!\n", __FUNCTION__)); - return EFI_INVALID_PARAMETER; - } - return EFI_SUCCESS; -} - -static EFI_STATUS FvbEraseVerifiedBlocks(VA_LIST *Args) { - EFI_STATUS status = EFI_SUCCESS; - while(TRUE) - { - EFI_LBA Lba; - UINTN LbaCount; - if(FvbNextBlocksFromList(Args, &Lba, &LbaCount) != EFI_SUCCESS) { - status = EFI_INVALID_PARAMETER; - break; - } - if(Lba == EFI_LBA_LIST_TERMINATOR) { - break; - } - if(FvbEraseConsecutiveBlocks(Lba, LbaCount) != EFI_SUCCESS) { - status = EFI_DEVICE_ERROR; - } - } - return status; -} - -static BOOLEAN FvbIsBlockValid(EFI_LBA Lba) { - if(Lba > FvbGetTotalNumberOfBlocks()-1) { - return FALSE; - } else { - return TRUE; - } -} - -static EFI_STATUS FvbVerifyBlockReadability(EFI_LBA Lba) { - if(FvbIsBlockValid(Lba) == FALSE) { - return EFI_ACCESS_DENIED; - } else { - return EFI_SUCCESS; - } -} - -static EFI_STATUS FvbVerifySingleBlockWritability(EFI_LBA Lba) { - if(FvbIsBlockValid(Lba) == FALSE) { - return EFI_ACCESS_DENIED; - } else { - return EFI_SUCCESS; - } -} - -static EFI_STATUS FvbVerifyConsecutiveBlocksWritability( - EFI_LBA Lba, - UINTN LbaCount -) { - for(EFI_LBA currentLba = Lba; currentLba < Lba+LbaCount; ++currentLba) { - if(FvbVerifySingleBlockWritability(Lba) != EFI_SUCCESS) { - return EFI_ACCESS_DENIED; - } - } - return EFI_SUCCESS; -} - -static EFI_STATUS FvbVerifyBlocksWritability(VA_LIST *Args) { - EFI_STATUS status = EFI_SUCCESS; - while(TRUE) { - EFI_LBA Lba; - UINTN LbaCount; - if(FvbNextBlocksFromList(Args, &Lba, &LbaCount) != EFI_SUCCESS) { - status = EFI_INVALID_PARAMETER; - break; - } - if(Lba == EFI_LBA_LIST_TERMINATOR) { - break; - } - if(FvbVerifyConsecutiveBlocksWritability(Lba, LbaCount) != EFI_SUCCESS) { - status = EFI_ACCESS_DENIED; - break; - } - } - return status; -} - -static UINTN FvbGetTotalNumberOfBlocks() { - return FLASH_SIZE / BLOCK_SIZE; -} - -static EFI_STATUS WriteEnable() { - UINT8 writeEnableCmd[] = { - CMD_WRITE_ENABLE - }; - if(spi_xfer( - getSPISlave(), writeEnableCmd, ARRAY_SIZE(writeEnableCmd), NULL, 0) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -static EFI_STATUS PageProgram( - CONST UINTN Address, - CONST UINT8 *Buffer, - UINTN *NumBytes -) { - CONST UINTN commandHeaderLength = 4; - CONST UINTN maxLengthToWrite = MIN( - SPI_FIFO_DEPTH-commandHeaderLength, - REMAINING_SPACE_IN_PAGE(OFFSET_FROM_PAGE_START(Address)) - ); - CONST UINTN lengthOfDataToWrite = MIN(*NumBytes, maxLengthToWrite); - if(*NumBytes == 0 || Buffer == NULL) { - return EFI_INVALID_PARAMETER; - } - WaitForBusyBit(); - if(WriteEnable() != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - UINT8 pageProgramCmd[commandHeaderLength+maxLengthToWrite]; - pageProgramCmd[0] = CMD_W25_PP; // FIXME Winbond specific - pageProgramCmd[1] = (UINT8)((Address & 0xFF0000) >> 16); - pageProgramCmd[2] = (UINT8)((Address & 0x00FF00) >> 8); - pageProgramCmd[3] = (UINT8) (Address & 0x0000FF); - CopyMem(pageProgramCmd+commandHeaderLength, Buffer, lengthOfDataToWrite); - if(spi_xfer( - getSPISlave(), - pageProgramCmd, commandHeaderLength+lengthOfDataToWrite, - NULL, 0) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - if(lengthOfDataToWrite != *NumBytes) { - *NumBytes = lengthOfDataToWrite; - return EFI_BAD_BUFFER_SIZE; - } - return EFI_SUCCESS; -} - -static EFI_STATUS RemoveBlockProtection() { - UINT8 status; - if(readStatusReg(&status) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - status &= ~( - REG_BLOCK_PROTECT_0_MASK - | REG_BLOCK_PROTECT_1_MASK - | REG_BLOCK_PROTECT_2_MASK - | REG_BLOCK_PROTECT_3_MASK); - if(writeStatusReg(status) != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - return EFI_SUCCESS; -} - -static EFI_STATUS ReadArray(CONST UINTN Address, UINT8 *Buffer, UINTN *NumBytes) { - UINT8 command[] = { - CMD_READ_ARRAY_SLOW, - (UINT8)((Address & 0xFF0000) >> 16), - (UINT8)((Address & 0xFF00) >> 8), - (UINT8) (Address & 0xFF) - }; - UINTN numberOfBytesToRead = MIN(MIN( - *NumBytes, - REMAINING_SPACE_IN_PAGE(OFFSET_FROM_PAGE_START(Address))), - SPI_FIFO_DEPTH-ARRAY_SIZE(command) - ); - if(spi_xfer(getSPISlave(), - command, ARRAY_SIZE(command), - Buffer, numberOfBytesToRead) != 0) { - DEBUG((EFI_D_INFO, "%a Transfer error\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; - } - if(numberOfBytesToRead != *NumBytes) { - *NumBytes = numberOfBytesToRead; - return EFI_BAD_BUFFER_SIZE; - } - return EFI_SUCCESS; -} - -// STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; -// STATIC UINTN mFlashNvStorageVariableBase; - -/// -/// The Firmware Volume Block Protocol is the low-level interface -/// to a firmware volume. File-level access to a firmware volume -/// should not be done using the Firmware Volume Block Protocol. -/// Normal access to a firmware volume must use the Firmware -/// Volume Protocol. Typically, only the file system driver that -/// produces the Firmware Volume Protocol will bind to the -/// Firmware Volume Block Protocol. -/// - -/** - Initialises the FV Header and Variable Store Header - to support variable operations. - - @param[in] Ptr - Location to initialise the headers - -**/ -EFI_STATUS -InitializeFvAndVariableStoreHeaders(IN FVBSPI_INFO *Instance) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - VOID* Headers; - UINTN HeadersLength; - EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - - HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); - Headers = AllocateZeroPool(HeadersLength); - - // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); - - // Check if the size of the area is at least one block size - ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->BlockSize > 0)); - - // Ensure the Variable area Base Addresses are aligned on a block size boundaries - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->BlockSize == 0); - - // - // EFI_FIRMWARE_VOLUME_HEADER - // - FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; - CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); - FirmwareVolumeHeader->FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) - + PcdGet32(PcdFlashNvStorageFtwWorkingSize) - + PcdGet32(PcdFlashNvStorageFtwSpareSize); - FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; - FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP // Reads may be enabled - | EFI_FVB2_READ_STATUS // Reads are currently enabled - | EFI_FVB2_STICKY_WRITE // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - | EFI_FVB2_MEMORY_MAPPED // It is memory mapped - | EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') - | EFI_FVB2_WRITE_STATUS // Writes are currently enabled - | EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled - ); - FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); - FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; - FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->NumBlocks; - FirmwareVolumeHeader->BlockMap[0].Length = Instance->BlockSize; - FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; - FirmwareVolumeHeader->BlockMap[1].Length = 0; - FirmwareVolumeHeader->Checksum = CalculateCheckSum16((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); - - // - // VARIABLE_STORE_HEADER - // - VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); - CopyGuid(&VariableStoreHeader->Signature, &gEfiVariableGuid); - VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; - VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; - - // Install the combined super-header in the store - static UINT8 blockBackup[BLOCK_SIZE]; - UINTN sizeToRead = BLOCK_SIZE; - FvbRead(NULL, 0, 0, &sizeToRead, blockBackup); - if(sizeToRead != BLOCK_SIZE) { - DEBUG((EFI_D_INFO, "%a Creating block backup failed!\n", __FUNCTION__)); - } - Status = FvbEraseBlocks(NULL, 0, 1, EFI_LBA_LIST_TERMINATOR); - if(Status != EFI_SUCCESS) { - DEBUG((EFI_D_INFO, "%a Erase failed\n", __FUNCTION__)); - return Status; - } - Status = FvbWrite(NULL, 0, 0, &HeadersLength, Headers); - UINTN backupRestoreSize = BLOCK_SIZE-HeadersLength; - Status = FvbWrite(NULL, 0, HeadersLength, &backupRestoreSize, blockBackup+HeadersLength); - - FreePool (Headers); - ValidateFvHeader(Instance); - return Status; -} - -/** - Check the integrity of firmware volume header. - - @param[in] FwVolHeader - A pointer to a firmware volume header - - @retval EFI_SUCCESS - The firmware volume is consistent - @retval EFI_NOT_FOUND - The firmware volume has been corrupted. - -**/ -EFI_STATUS -ValidateFvHeader(IN FVBSPI_INFO *Instance) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - UINT16 Checksum; - EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - UINTN VariableStoreLength; - UINTN FvLength; - EFI_STATUS TempStatus; - UINTN BufferSize; - UINTN BufferSizeReqested; - - BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested+64); - if(!FwVolHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = FvbRead(NULL, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if(EFI_ERROR(TempStatus) || BufferSizeReqested != BufferSize) { - FreePool(FwVolHeader); - return EFI_DEVICE_ERROR; - } - - FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) - + PcdGet32(PcdFlashNvStorageFtwWorkingSize) - + PcdGet32(PcdFlashNvStorageFtwSpareSize); - - // - // Verify the header revision, header signature, length - // Length of FvBlock cannot be 2**64-1 - // HeaderLength cannot be an odd number - // - if( - (FwVolHeader->Revision != EFI_FVH_REVISION) - || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) - || (FwVolHeader->FvLength != FvLength) - ) { - DEBUG((EFI_D_INFO, "%a: No Firmware Volume header present\n", __FUNCTION__)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - // Check the Firmware Volume Guid - if(CompareGuid(&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE) { - DEBUG((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", __FUNCTION__)); - FreePool(FwVolHeader); - return EFI_NOT_FOUND; - } - - BufferSizeReqested = FwVolHeader->HeaderLength; - FreePool(FwVolHeader); - FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested+64); - if(!FwVolHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = FvbRead(NULL, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); - if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { - FreePool(FwVolHeader); - return EFI_DEVICE_ERROR; - } - - // Verify the header checksum - DEBUG((EFI_D_INFO, "%a: FwVolHeader->HeaderLength = 0x%X\n", __FUNCTION__, FwVolHeader->HeaderLength)); - Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); - DEBUG((EFI_D_INFO, "%a checksum = 0x%X\n", __FUNCTION__, Checksum)); - if(Checksum != 0) { - DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", - __FUNCTION__, Checksum)); - FreePool (FwVolHeader); - return EFI_NOT_FOUND; - } - - BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); - VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); - if(!VariableStoreHeader) { - return EFI_OUT_OF_RESOURCES; - } - BufferSize = BufferSizeReqested; - TempStatus = FvbRead(NULL, 0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); - if(EFI_ERROR(TempStatus) || BufferSizeReqested != BufferSize) { - FreePool(VariableStoreHeader); - FreePool(FwVolHeader); - return EFI_DEVICE_ERROR; - } - - // Check the Variable Store Guid - if ( - !CompareGuid(&VariableStoreHeader->Signature, &gEfiVariableGuid) - && !CompareGuid(&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid) - ) { - DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", - __FUNCTION__)); - FreePool(FwVolHeader); - FreePool(VariableStoreHeader); - return EFI_NOT_FOUND; - } - - VariableStoreLength = PcdGet32(PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; - if (VariableStoreHeader->Size != VariableStoreLength) { - DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", - __FUNCTION__)); - FreePool(FwVolHeader); - FreePool(VariableStoreHeader); - return EFI_NOT_FOUND; - } - - FreePool(FwVolHeader); - FreePool(VariableStoreHeader); - DEBUG ((EFI_D_INFO, "%a: Header successfully validated!\n", __FUNCTION__)); - return EFI_SUCCESS; -} - -/** - The GetAttributes() function retrieves the attributes and - current settings of the block. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and - current settings are returned. - Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - - **/ -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; - // SMMSTORE_INSTANCE *Instance; - - // Instance = INSTANCE_FROM_FVB_THIS(This); - - FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') - ); - - // // Check if it is write protected - // if (Instance->Media.ReadOnly != TRUE) { - - // FlashFvbAttributes = FlashFvbAttributes | - // EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - // EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled - // } - - *Attributes = FlashFvbAttributes; - - DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); - - return EFI_SUCCESS; -} - -/** - The SetAttributes() function sets configurable firmware volume attributes - and returns the new settings of the firmware volume. - - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 - that contains the desired firmware volume settings. - On successful return, it contains the new settings of - the firmware volume. - Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. - - @retval EFI_SUCCESS The firmware volume attributes were returned. - - @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities - as declared in the firmware volume header. - - **/ -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - return EFI_DEVICE_ERROR; -} - -/** - The GetPhysicalAddress() function retrieves the base address of - a memory-mapped firmware volume. This function should be called - only for memory-mapped firmware volumes. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Address Pointer to a caller-allocated - EFI_PHYSICAL_ADDRESS that, on successful - return from GetPhysicalAddress(), contains the - base address of the firmware volume. - - @retval EFI_SUCCESS The firmware volume base address was returned. - - @retval EFI_UNSUPPORTED The firmware volume is not memory mapped. - - **/ -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ) -{ - return EFI_UNSUPPORTED; -} - -/** - The GetBlockSize() function retrieves the size of the requested - block. It also returns the number of additional blocks with - the identical size. The GetBlockSize() function is used to - retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). - - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba Indicates the block for which to return the size. - - @param BlockSize Pointer to a caller-allocated UINTN in which - the size of the block is returned. - - @param NumberOfBlocks Pointer to a caller-allocated UINTN in - which the number of consecutive blocks, - starting with Lba, is returned. All - blocks in this range have a size of - BlockSize. - - - @retval EFI_SUCCESS The firmware volume base address was returned. - - @retval EFI_INVALID_PARAMETER The requested LBA is out of range. - - **/ -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ) -{ - *BlockSize = BLOCK_SIZE; - *NumberOfBlocks = FvbGetTotalNumberOfBlocks(); - if(Lba > *NumberOfBlocks) { - return EFI_INVALID_PARAMETER; - } else { - return EFI_SUCCESS; - } -} - -/** - Reads the specified number of bytes into a buffer from the specified block. - - The Read() function reads the requested number of bytes from the - requested block and stores them in the provided buffer. - Implementations should be mindful that the firmware volume - might be in the ReadDisabled state. If it is in this state, - the Read() function must return the status code - EFI_ACCESS_DENIED without modifying the contents of the - buffer. The Read() function must also prevent spanning block - boundaries. If a read is requested that would span a block - boundary, the read must read up to the boundary but not - beyond. The output parameter NumBytes must be set to correctly - indicate the number of bytes actually read. The caller must be - aware that a read may be partially completed. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba The starting logical block index from which to read. - - @param Offset Offset into the block at which to begin reading. - - @param NumBytes Pointer to a UINTN. - At entry, *NumBytes contains the total size of the buffer. - At exit, *NumBytes contains the total number of bytes read. - - @param Buffer Pointer to a caller-allocated buffer that will be used - to hold the data that is read. - - @retval EFI_SUCCESS The firmware volume was read successfully, and contents are - in Buffer. - - @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. - On output, NumBytes contains the total number of bytes - returned in Buffer. - - @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. - - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. - - **/ - -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ) -{ - DEBUG((EFI_D_INFO, "%a(This = 0x%X, Lba = 0x%X, Offset = 0x%X, *NumBytes = 0x%X, Buffer = 0x%X)\n", __FUNCTION__, This, Lba, Offset, *NumBytes, Buffer)); - UINTN address = ADDRESS(Lba, Offset); - UINTN numberOfBytesToRead = MIN(*NumBytes, REMAINING_SPACE_IN_BLOCK(Offset)); - UINTN numberOfBytesRead = 0; - WaitForBusyBit(); - if(FvbVerifyBlockReadability(Lba) == EFI_ACCESS_DENIED) { - return EFI_ACCESS_DENIED; - } - if(Buffer == NULL || numberOfBytesToRead == 0) { - DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); - return EFI_BAD_BUFFER_SIZE; - } - while(numberOfBytesRead < numberOfBytesToRead) { - UINTN bytesRead = numberOfBytesToRead - numberOfBytesRead; - EFI_STATUS readStatus = ReadArray( - address+numberOfBytesRead, - Buffer+numberOfBytesRead, - &bytesRead - ); - if(readStatus != EFI_SUCCESS && readStatus != EFI_BAD_BUFFER_SIZE) { - return EFI_DEVICE_ERROR; - } - numberOfBytesRead += bytesRead; - } - - if(numberOfBytesToRead != *NumBytes) { - *NumBytes = numberOfBytesToRead; - return EFI_BAD_BUFFER_SIZE; - } - return EFI_SUCCESS; -} - -/** - Writes the specified number of bytes from the input buffer to the block. - - The Write() function writes the specified number of bytes from - the provided buffer to the specified block and offset. If the - firmware volume is sticky write, the caller must ensure that - all the bits of the specified range to write are in the - EFI_FVB_ERASE_POLARITY state before calling the Write() - function, or else the result will be unpredictable. This - unpredictability arises because, for a sticky-write firmware - volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY - state but cannot flip it back again. Before calling the - Write() function, it is recommended for the caller to first call - the EraseBlocks() function to erase the specified block to - write. A block erase cycle will transition bits from the - (NOT)EFI_FVB_ERASE_POLARITY state back to the - EFI_FVB_ERASE_POLARITY state. Implementations should be - mindful that the firmware volume might be in the WriteDisabled - state. If it is in this state, the Write() function must - return the status code EFI_ACCESS_DENIED without modifying the - contents of the firmware volume. The Write() function must - also prevent spanning block boundaries. If a write is - requested that spans a block boundary, the write must store up - to the boundary but not beyond. The output parameter NumBytes - must be set to correctly indicate the number of bytes actually - written. The caller must be aware that a write may be - partially completed. All writes, partial or otherwise, must be - fully flushed to the hardware before the Write() service - returns. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. - - @param Lba The starting logical block index to write to. - - @param Offset Offset into the block at which to begin writing. - - @param NumBytes The pointer to a UINTN. - At entry, *NumBytes contains the total size of the buffer. - At exit, *NumBytes contains the total number of bytes actually written. - - @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. - - @retval EFI_SUCCESS The firmware volume was written successfully. - - @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. - On output, NumBytes contains the total number of bytes - actually written. - - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. - - @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. - - - **/ - -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ) -{ - CONST UINTN numberOfBytesToWrite = MIN( - *NumBytes, REMAINING_SPACE_IN_BLOCK(Offset) - ); - UINTN address = ADDRESS(Lba, Offset); - UINTN numberOfBytesWritten = 0; - if(Buffer == NULL || numberOfBytesToWrite == 0) { - DEBUG((EFI_D_INFO, "%a Buffer is NULL or too small!\n", __FUNCTION__)); - return EFI_BAD_BUFFER_SIZE; - } - if(FvbVerifySingleBlockWritability(Lba) == EFI_ACCESS_DENIED) { - return EFI_ACCESS_DENIED; - } - if( - RemoveBlockProtection() != EFI_SUCCESS - || WaitForBusyBit() != EFI_SUCCESS) { - return EFI_DEVICE_ERROR; - } - while(numberOfBytesWritten < numberOfBytesToWrite) { - UINTN writteAmount = numberOfBytesToWrite-numberOfBytesWritten; - EFI_STATUS writingStatus = PageProgram(address, Buffer, &writteAmount); - if(writingStatus != EFI_SUCCESS && writingStatus != EFI_BAD_BUFFER_SIZE) { - return EFI_DEVICE_ERROR; - } - numberOfBytesWritten += writteAmount; - address += writteAmount; - Buffer += writteAmount; - } - if(numberOfBytesToWrite != *NumBytes) { - return EFI_BAD_BUFFER_SIZE; - } - *NumBytes = numberOfBytesToWrite; - - return EFI_SUCCESS; -} - -/** - Erases and initialises a firmware volume block. - - The EraseBlocks() function erases one or more blocks as denoted - by the variable argument list. The entire parameter list of - blocks must be verified before erasing any blocks. If a block is - requested that does not exist within the associated firmware - volume (it has a larger index than the last block of the - firmware volume), the EraseBlocks() function must return the - status code EFI_INVALID_PARAMETER without modifying the contents - of the firmware volume. Implementations should be mindful that - the firmware volume might be in the WriteDisabled state. If it - is in this state, the EraseBlocks() function must return the - status code EFI_ACCESS_DENIED without modifying the contents of - the firmware volume. All calls to EraseBlocks() must be fully - flushed to the hardware before the EraseBlocks() service - returns. - - @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL - instance. - - @param ... The variable argument list is a list of tuples. - Each tuple describes a range of LBAs to erase - and consists of the following: - - An EFI_LBA that indicates the starting LBA - - A UINTN that indicates the number of blocks to erase. - - The list is terminated with an EFI_LBA_LIST_TERMINATOR. - For example, the following indicates that two ranges of blocks - (5-7 and 10-11) are to be erased: - EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); - - @retval EFI_SUCCESS The erase request successfully completed. - - @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. - - @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. - The firmware device may have been partially erased. - - @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do - not exist in the firmware volume. - - **/ - -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ) -{ - EFI_STATUS status = EFI_SUCCESS; - VA_LIST Args; - VA_START(Args, This); - status = FvbVerifyBlocksWritability(&Args); - VA_END(Args); - if(status == EFI_SUCCESS) { - VA_START(Args, This); - status = FvbEraseVerifiedBlocks(&Args); - VA_END(Args); - if(status != EFI_SUCCESS) { - DEBUG((EFI_D_INFO, - "%a WARNING: Blocks verified, but erase failed!", __FUNCTION__)); - } - } - return status; -} diff --git a/UefiPayloadPkg/SPI/Fvb.h b/UefiPayloadPkg/SPI/Fvb.h deleted file mode 100644 index 018035112edd..000000000000 --- a/UefiPayloadPkg/SPI/Fvb.h +++ /dev/null @@ -1,87 +0,0 @@ -#ifndef FVB_H -#define FVB_H - -#include -#include "FvbSPI.h" - -#define BLOCK_SIZE 0x10000 -#define PAGE_SIZE 0x100 -#define FLASH_SIZE 0x800000 -#define VARIABLE_STORAGE_BLOCKS_OFFSET 6 - -EFI_STATUS -InitializeFvAndVariableStoreHeaders ( - IN FVBSPI_INFO *Instance - ); - -EFI_STATUS -ValidateFvHeader ( - IN FVBSPI_INFO *Instance - ); - -EFI_STATUS -EFIAPI -FvbGetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbSetAttributes( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes - ); - -EFI_STATUS -EFIAPI -FvbGetPhysicalAddress ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - OUT EFI_PHYSICAL_ADDRESS *Address - ); - -EFI_STATUS -EFIAPI -FvbGetBlockSize ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - OUT UINTN *BlockSize, - OUT UINTN *NumberOfBlocks - ); - -EFI_STATUS -EFIAPI -FvbRead ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN OUT UINT8 *Buffer - ); - - -EFI_STATUS -EFIAPI -FvbWrite ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - IN EFI_LBA Lba, - IN UINTN Offset, - IN OUT UINTN *NumBytes, - IN UINT8 *Buffer - ); - -EFI_STATUS -EFIAPI -FvbEraseBlocks ( - IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, - ... - ); - -VOID -EFIAPI -FvbVirtualNotifyEvent ( - IN EFI_EVENT Event, - IN VOID *Context - ); - -#endif /* FVB_H */ diff --git a/UefiPayloadPkg/SPI/FvbSPI.c b/UefiPayloadPkg/SPI/FvbSPI.c deleted file mode 100644 index e0ede8327a93..000000000000 --- a/UefiPayloadPkg/SPI/FvbSPI.c +++ /dev/null @@ -1,106 +0,0 @@ -/** @file BlSMMStoreDxe.c - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "FchSPICtrl.h" -#include "Fvb.h" -#include "GenericSPI.h" -#include "SPIFlashInternal.h" - -EFI_HANDLE Handle = NULL; -EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol = { - FvbGetAttributes, // GetAttributes - FvbSetAttributes, // SetAttributes - FvbGetPhysicalAddress, // GetPhysicalAddress - FvbGetBlockSize, // GetBlockSize - FvbRead, // Read - FvbWrite, // Write - FvbEraseBlocks, // EraseBlocks - NULL -}; - -EFI_STATUS checkBusyBit(UINT8 *Busy); - -EFI_STATUS EFIAPI SPIInitialize ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable -) { - FVBSPI_INFO fvbSPIInfo = { - .ComBuffer = 0, - .ComBufferSize = 0, - .NumBlocks = 4, - .BlockSize = BLOCK_SIZE, - .MmioAddress = 0, - .ApmCmd = 0 - }; - if (PcdGetBool(PcdEmuVariableNvModeEnable)) { - DEBUG (( - DEBUG_WARN, - "Variable emulation is active! Skipping driver init.\n")); - while(1); - return EFI_SUCCESS; - } - EFI_STATUS Status; - // Update PCDs for Variable/RuntimeDxe - PcdSet32S(PcdFlashNvStorageVariableBase, - PcdGet32(PcdFlashNvStorageVariableBase) + fvbSPIInfo.MmioAddress); - PcdSet32S(PcdFlashNvStorageFtwWorkingBase, - PcdGet32(PcdFlashNvStorageFtwWorkingBase) + fvbSPIInfo.MmioAddress); - PcdSet32S(PcdFlashNvStorageFtwSpareBase, - PcdGet32(PcdFlashNvStorageFtwSpareBase) + fvbSPIInfo.MmioAddress); - spi_init(); - - Status = InitializeFvAndVariableStoreHeaders(&fvbSPIInfo); - if(Status != EFI_SUCCESS) { - DEBUG((DEBUG_WARN, "%a InitializeFvAndVariableStoreHeaders() failed\n", __FUNCTION__)); - } - Status = ValidateFvHeader(&fvbSPIInfo); - if(Status != EFI_SUCCESS) { - DEBUG((DEBUG_WARN, "%a ValidateFvHeader() failed\n", __FUNCTION__)); - } - // - // Install the protocol - // - Status = gBS->InstallMultipleProtocolInterfaces ( - &Handle, - &gEfiFirmwareVolumeBlockProtocolGuid, &FvbProtocol, - NULL); - if(EFI_ERROR (Status)) { - DEBUG(( - EFI_D_INFO, - "%a Error during protocol installation.\n", __FUNCTION__)); - PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); - while(1); - return EFI_PROTOCOL_ERROR; - } - - Status = gBS->InstallProtocolInterface ( - &Handle, - &gEfiVariableWriteArchProtocolGuid, - EFI_NATIVE_INTERFACE, - NULL - ); - if(EFI_ERROR (Status)) { - DEBUG(( - EFI_D_INFO, - "%a Error during protocol 2 installation.\n", __FUNCTION__)); - PcdSetBoolS(PcdEmuVariableNvModeEnable, TRUE); - while(1); - return EFI_PROTOCOL_ERROR; - } - return EFI_SUCCESS; -} diff --git a/UefiPayloadPkg/SPI/FvbSPI.h b/UefiPayloadPkg/SPI/FvbSPI.h deleted file mode 100644 index d9993b680915..000000000000 --- a/UefiPayloadPkg/SPI/FvbSPI.h +++ /dev/null @@ -1,108 +0,0 @@ -/** @file BlSMMStoreDxe.h - - Copyright (c) 2020, 9elements Agency GmbH
- - SPDX-License-Identifier: BSD-2-Clause-Patent - -**/ - -#ifndef __SPI_H__ -#define __SPI_H__ - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "GenericSPI.h" - -extern EFI_GUID gUefiFvbSPIInfoGuid; - -typedef struct { - UINT64 ComBuffer; - UINT32 ComBufferSize; - UINT32 NumBlocks; - UINT32 BlockSize; - UINT64 MmioAddress; - UINT8 ApmCmd; - UINT8 Reserved0[3]; -} FVBSPI_INFO; - -typedef struct _SMMSTORE_INSTANCE SMMSTORE_INSTANCE; - -/* - * Representation of SPI flash operations: - * read: Flash read operation. - * write: Flash write operation. - * erase: Flash erase operation. - * status: Read flash status register. - */ -struct spi_flash_ops { - int (*read)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - VOID *buf); - int (*write)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - CONST VOID *buf); - int (*erase)(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - int (*status)(CONST struct spi_flash *flash, UINT8 *reg); -}; - -#pragma pack (1) -typedef struct { - VENDOR_DEVICE_PATH Vendor; - UINT8 Index; - EFI_DEVICE_PATH_PROTOCOL End; -} NOR_FLASH_DEVICE_PATH; -#pragma pack () - -struct _SMMSTORE_INSTANCE { - UINT32 Signature; - EFI_HANDLE Handle; - EFI_BLOCK_IO_MEDIA Media; - - EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; - - NOR_FLASH_DEVICE_PATH DevicePath; -}; - -enum optype { - READ_NO_ADDR = 0, - WRITE_NO_ADDR = 1, - READ_WITH_ADDR = 2, - WRITE_WITH_ADDR = 3 -}; - -struct spi_flash_protection_ops { - /* - * Returns 1 if the whole region is software write protected. - * Hardware write protection mechanism aren't accounted. - * If the write protection could be changed, due to unlocked status - * register for example, 0 should be returned. - * Returns 0 on success. - */ - int (*get_write)(const struct spi_flash *flash, - const struct region *region); - /* - * Enable the status register write protection, if supported on the - * requested region, and optionally enable status register lock-down. - * Returns 0 if the whole region was software write protected. - * Hardware write protection mechanism aren't accounted. - * If the status register is locked and the requested configuration - * doesn't match the selected one, return an error. - * Only a single region is supported ! - * - * @return 0 on success - */ - int - (*set_write)(const struct spi_flash *flash, - const struct region *region, - const enum spi_flash_status_reg_lockdown mode); - -}; - -#endif /* __SPI_H__ */ diff --git a/UefiPayloadPkg/SPI/SPI.h b/UefiPayloadPkg/SPI/SPI.h deleted file mode 100644 index f975c50139bb..000000000000 --- a/UefiPayloadPkg/SPI/SPI.h +++ /dev/null @@ -1,18 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ - -#ifndef SPI_H -#define SPI_H - -#include - -#define PCU_BUS 0x00 -#define PCU_DEV 0x14 -#define LPC_FUNC 0x03 - -#define SPI_BUSY BIT31 - -#define SPI_FIFO 0x80 -#define SPI_FIFO_LAST_BYTE 0xc7 -#define SPI_FIFO_DEPTH (SPI_FIFO_LAST_BYTE - SPI_FIFO) - -#endif /* SPI_H */ diff --git a/UefiPayloadPkg/SPI/SPI.inf b/UefiPayloadPkg/SPI/SPI.inf deleted file mode 100644 index 07e6de9c458d..000000000000 --- a/UefiPayloadPkg/SPI/SPI.inf +++ /dev/null @@ -1,69 +0,0 @@ -#/** @file -# -# Component description file for SMMSTORE module -# -# Copyright (c) 2020, 9elements Agency GmbH
-# -# SPDX-License-Identifier: BSD-2-Clause-Patent -# -#**/ -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = SPI - FILE_GUID = c2c2e656-ee66-41e0-bee3-29c6f16f49c0 - MODULE_TYPE = DXE_RUNTIME_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = SPIInitialize - -[Sources] - FchSPICtrl.c - FchSPICtrl.h - FchSPIUtil.c - FchSPIUtil.h - Fvb.c - Fvb.h - FvbSPI.c - FvbSPI.h - GenericSPI.c - GenericSPI.h - SPI.h - SPIFlashInternal.c - SPIFlashInternal.h - -[Packages] - EmbeddedPkg/EmbeddedPkg.dec - MdeModulePkg/MdeModulePkg.dec - MdePkg/MdePkg.dec - UefiPayloadPkg/UefiPayloadPkg.dec - -[LibraryClasses] - BaseMemoryLib - BaseLib - DebugLib - HobLib - PciLib - TimerLib - UefiDriverEntryPoint - -[Guids] - gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL - gEfiAuthenticatedVariableGuid - gEfiSystemNvDataFvGuid - gEfiVariableGuid - gUefiFvbSPIInfoGuid - -[Protocols] - gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES ## PROTOCOL - gEfiVariableWriteArchProtocolGuid - -[Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize - -[Depex] - TRUE diff --git a/UefiPayloadPkg/SPI/SPIFlashInternal.c b/UefiPayloadPkg/SPI/SPIFlashInternal.c deleted file mode 100644 index 924203307078..000000000000 --- a/UefiPayloadPkg/SPI/SPIFlashInternal.c +++ /dev/null @@ -1,600 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -#include -#include -#include -#include -#include "FvbSPI.h" -#include "GenericSPI.h" -#include "SPIFlashInternal.h" - -static VOID spi_flash_addr(UINT32 addr, UINT8 *cmd) -{ - /* cmd[0] is actual command */ - cmd[1] = addr >> 16; - cmd[2] = addr >> 8; - cmd[3] = addr >> 0; -} - -static int do_spi_flash_cmd(const struct spi_slave *spi, const VOID *dout, - __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) -{ - int ret; - /* - * SPI flash requires command-response kind of behavior. Thus, two - * separate SPI vectors are required -- first to transmit dout and other - * to receive in din. If some specialized SPI flash controllers - * (e.g. x86) can perform both command and response together, it should - * be handled at SPI flash controller driver level. - */ - struct spi_op vectors[] = { - [0] = { .dout = dout, .bytesout = bytes_out, - .din = NULL, .bytesin = 0, }, - [1] = { .dout = NULL, .bytesout = 0, - .din = din, .bytesin = bytes_in }, - }; - __SIZE_TYPE__ count = ARRAY_SIZE(vectors); - if (!bytes_in) - count = 1; - - ret = spi_claim_bus(spi); - if (ret) - return ret; - - ret = spi_xfer_vector(spi, vectors, count); - - spi_release_bus(spi); - return ret; -} - -static int do_dual_read_cmd(const struct spi_slave *spi, const VOID *dout, - __SIZE_TYPE__ bytes_out, VOID *din, __SIZE_TYPE__ bytes_in) -{ - int ret; - - /* - * spi_xfer_vector() will automatically fall back to .xfer() if - * .xfer_vector() is unimplemented. So using vector API here is more - * flexible, even though a controller that implements .xfer_vector() - * and (the non-vector based) .xfer_dual() but not .xfer() would be - * pretty odd. - */ - struct spi_op vector = { .dout = dout, .bytesout = bytes_out, - .din = NULL, .bytesin = 0 }; - - ret = spi_claim_bus(spi); - if (ret) - return ret; - - ret = spi_xfer_vector(spi, &vector, 1); - - if (!ret) - ret = spi->ctrlr->xfer_dual(spi, NULL, 0, din, bytes_in); - - spi_release_bus(spi); - return ret; -} - -int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) -{ - int ret = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); - if (ret) - DEBUG((EFI_D_INFO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, ret)); - - return ret; -} - -/* TODO: This code is quite possibly broken and overflowing stacks. Fix ASAP! */ -#pragma GCC diagnostic push -#if defined(__GNUC__) && !defined(__clang__) -#pragma GCC diagnostic ignored "-Wstack-usage=" -#endif -#pragma GCC diagnostic ignored "-Wvla" -int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, - __SIZE_TYPE__ cmd_len, const VOID *data, __SIZE_TYPE__ data_len) -{ - int ret; - UINT8 buff[cmd_len + data_len]; - InternalMemCopyMem(buff, cmd, cmd_len); - InternalMemCopyMem(buff + cmd_len, data, data_len); - - ret = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0); - if (ret) { - DEBUG((EFI_D_INFO, "%a SF: Failed to send write command (%zu bytes): %d\n", - __FUNCTION__, data_len, ret)); - } - - return ret; -} -#pragma GCC diagnostic pop - -/* Perform the read operation honoring spi controller fifo size, reissuing - * the read command until the full request completed. */ -int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, VOID *buf) -{ - UINT8 cmd[5]; - int ret, cmd_len; - int (*do_cmd)(const struct spi_slave *spi, const VOID *din, - __SIZE_TYPE__ in_bytes, VOID *out, __SIZE_TYPE__ out_bytes); -#ifdef SPI_FLASH_NO_FAST_READ - cmd_len = 4; - cmd[0] = CMD_READ_ARRAY_SLOW; - do_cmd = do_spi_flash_cmd; -#else - if (flash->flags.dual_spi && flash->spi.ctrlr->xfer_dual) { - cmd_len = 5; - cmd[0] = CMD_READ_FAST_DUAL_OUTPUT; - cmd[4] = 0; - do_cmd = do_dual_read_cmd; - } else { - cmd_len = 5; - cmd[0] = CMD_READ_ARRAY_FAST; - cmd[4] = 0; - do_cmd = do_spi_flash_cmd; - } -#endif - - UINT8 *data = buf; - while (len) { - __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); - spi_flash_addr(offset, cmd); - ret = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); - if (ret) { - DEBUG((EFI_D_INFO, - "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", - __FUNCTION__, cmd[0], offset, xfer_len, ret)); - return ret; - } - offset += xfer_len; - data += xfer_len; - len -= xfer_len; - } - - return 0; -} - -int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, - UINT8 cmd, UINT8 poll_bit) -{ - const struct spi_slave *spi = &flash->spi; - int ret; - UINT8 status; - - CONST UINT64 nanoToMiliDivider = 1000000; - CONST UINT64 startTimeMilisec = - GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; - CONST UINT64 endTimeMilisec = startTimeMilisec + timeout; - UINT64 timeNow = startTimeMilisec; - - do { - ret = do_spi_flash_cmd(spi, &cmd, 1, &status, 1); - if (ret) - return -1; - if ((status & poll_bit) == 0) - return 0; - timeNow = GetTimeInNanoSecond(GetPerformanceCounter()) / nanoToMiliDivider; - } while ( - timeNowstartTimeMilisec && timeNow>endTimeMilisec)); - - DEBUG((EFI_D_INFO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); - return -1; -} - -int spi_flash_cmd_wait_ready(const struct spi_flash *flash, - unsigned long timeout) -{ - return spi_flash_cmd_poll_bit(flash, timeout, - CMD_READ_STATUS, STATUS_WIP); -} - -int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) -{ - UINT32 start, end, erase_size; - int ret = -1; - UINT8 cmd[4]; - - erase_size = flash->sector_size; - if (offset % erase_size || len % erase_size) { - DEBUG((EFI_D_INFO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); - return -1; - } - if (len == 0) { - DEBUG((EFI_D_INFO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); - return -1; - } - - cmd[0] = flash->erase_cmd; - start = offset; - end = start + len; - - while (offset < end) { - spi_flash_addr(offset, cmd); - offset += erase_size; - -#ifdef DEBUG_SPI_FLASH - DEBUG((EFI_D_INFO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION, - cmd[0], cmd[1], cmd[2], cmd[3], offset)); -#endif - ret = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0); - if (ret) - goto out; - - ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0); - if (ret) - goto out; - - ret = spi_flash_cmd_wait_ready(flash, - SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); - if (ret) - goto out; - } - - DEBUG((EFI_D_INFO, "%a SF: Successfully erased %zu bytes @ %#x\n", - __FUNCTION__, len, start)); - -out: - return ret; -} - -int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg) -{ - return spi_flash_cmd(&flash->spi, flash->status_cmd, reg, sizeof(*reg)); -} - -int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, const VOID *buf) -{ - unsigned long byte_addr; - unsigned long page_size; - __SIZE_TYPE__ chunk_len; - __SIZE_TYPE__ actual; - int ret = 0; - UINT8 cmd[4]; - - page_size = flash->page_size; - cmd[0] = flash->pp_cmd; - - for (actual = 0; actual < len; actual += chunk_len) { - byte_addr = offset % page_size; - chunk_len = MIN(len - actual, page_size - byte_addr); - chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len); - - spi_flash_addr(offset, cmd); -#ifdef DEBUG_SPI_FLASH - DEBUG((EFI_D_INFO, "%a PP: %p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n", - __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], - chunk_len)); -#endif - - ret = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0); - if (ret < 0) { - DEBUG((EFI_D_INFO, "%a SF: Enabling Write failed\n", __FUNCTION__)); - goto out; - } - - ret = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), - buf + actual, chunk_len); - if (ret < 0) { - DEBUG((EFI_D_INFO, "%a SF: Page Program failed\n", __FUNCTION__)); - goto out; - } - - ret = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS); - if (ret) - goto out; - - offset += chunk_len; - } - ret = 0; - -out: - return ret; -} - -int spi_flash_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - VOID *buf) -{ - return flash->ops->read(flash, offset, len, buf); -} - -int spi_flash_write(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, - const VOID *buf) -{ - int ret; - - if (spi_flash_volatile_group_begin(flash)) - return -1; - - ret = flash->ops->write(flash, offset, len, buf); - - if (spi_flash_volatile_group_end(flash)) - return -1; - - return ret; -} - -int spi_flash_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len) -{ - int ret; - - if (spi_flash_volatile_group_begin(flash)) - return -1; - - ret = flash->ops->erase(flash, offset, len); - - if (spi_flash_volatile_group_end(flash)) - return -1; - - return ret; -} - -int spi_flash_status(const struct spi_flash *flash, UINT8 *reg) -{ - if (flash->ops->status) - return flash->ops->status(flash, reg); - - return -1; -} - -int spi_flash_is_write_protected(const struct spi_flash *flash, - const struct region *region) -{ - // struct region flash_region = { 0 }; - - if (!flash || !region) - return -1; - - // flash_region.size = flash->size; - - // if (!region_is_subregion(&flash_region, region)) - // return -1; - - if (!flash->prot_ops) { - DEBUG((EFI_D_INFO, "%a SPI: Write-protection gathering not " - "implemented for this vendor.\n", __FUNCTION__)); - return -1; - } - - return flash->prot_ops->get_write(flash, region); -} - -int spi_flash_set_write_protected(const struct spi_flash *flash, - const struct region *region, - const enum spi_flash_status_reg_lockdown mode) -{ - // struct region flash_region = { 0 }; - int ret; - - if (!flash) - return -1; - - // flash_region.size = flash->size; - - // if (!region_is_subregion(&flash_region, region)) - // return -1; - - if (!flash->prot_ops) { - DEBUG((EFI_D_INFO, "%a SPI: Setting write-protection is not " - "implemented for this vendor.\n", __FUNCTION__)); - return -1; - } - - ret = flash->prot_ops->set_write(flash, region, mode); - - if (ret == 0 && mode != SPI_WRITE_PROTECTION_PRESERVE) { - DEBUG((EFI_D_INFO, "%a SPI: SREG lock-down was set to ", __FUNCTION__)); - switch (mode) { - case SPI_WRITE_PROTECTION_NONE: - DEBUG((EFI_D_INFO, "%a NEVER\n", __FUNCTION__)); - break; - case SPI_WRITE_PROTECTION_PIN: - DEBUG((EFI_D_INFO, "%a WP\n", __FUNCTION__)); - break; - case SPI_WRITE_PROTECTION_REBOOT: - DEBUG((EFI_D_INFO, "%a REBOOT\n", __FUNCTION__)); - break; - case SPI_WRITE_PROTECTION_PERMANENT: - DEBUG((EFI_D_INFO, "%a PERMANENT\n", __FUNCTION__)); - break; - default: - DEBUG((EFI_D_INFO, "%a UNKNOWN\n", __FUNCTION__)); - break; - } - } - - return ret; -} -#ifdef SPI_FLASH_HAS_VOLATILE_GROUP -static UINT32 volatile_group_count; - -int spi_flash_volatile_group_begin(const struct spi_flash *flash) -{ - int ret = 0; - UINT32 count; - count = volatile_group_count; - if (count == 0) - ret = chipset_volatile_group_begin(flash); - - count++; - volatile_group_count = count; - return ret; -} - -int spi_flash_volatile_group_end(const struct spi_flash *flash) -{ - int ret = 0; - UINT32 count; - count = volatile_group_count; - count--; - volatile_group_count = count; - - if (count == 0) - ret = chipset_volatile_group_end(flash); - - return ret; -} -#else - -int spi_flash_volatile_group_begin(const struct spi_flash *flash) -{ - int ret = 0; - return ret; -} - -int spi_flash_volatile_group_end(const struct spi_flash *flash) -{ - int ret = 0; - return ret; -} -#endif /* SPI_FLASH_HAS_VOLATILE_GROUP */ - -int spi_flash_ctrlr_protect_region(const struct spi_flash *flash, - const struct region *region, - const enum ctrlr_prot_type type) -{ - const struct spi_ctrlr *ctrlr; - // struct region flash_region = { 0 }; - - if (!flash) - return -1; - - // flash_region.size = flash->size; - - // if (!region_is_subregion(&flash_region, region)) - // return -1; - - ctrlr = flash->spi.ctrlr; - - if (!ctrlr) - return -1; - - if (ctrlr->flash_protect) - return ctrlr->flash_protect(flash, region, type); - - return -1; -} - -// int region_is_subregion(const struct region *p, const struct region *c) -// { -// if (region_offset(c) < region_offset(p)) -// return 0; - -// if (region_end(c) > region_end(p)) -// return 0; - -// if (region_end(c) < region_offset(c)) -// return 0; - -// return 1; -// } - -// inline __SIZE_TYPE__ region_offset(const struct region *r) -// { -// return r->offset; -// } - -// inline __SIZE_TYPE__ region_end(const struct region *r) -// { -// return region_offset(r) + region_sz(r); -// } - -// inline __SIZE_TYPE__ region_sz(const struct region *r) -// { -// return r->size; -// } - -int chipset_volatile_group_begin(const struct spi_flash *flash) -{ - return 0; - // if (!CONFIG(HUDSON_IMC_FWM)) - // return 0; - - // ImcSleep(NULL); - // return 0; -} - -int chipset_volatile_group_end(const struct spi_flash *flash) -{ - return 0; - // if (!CONFIG(HUDSON_IMC_FWM)) - // return 0; - - // ImcWakeup(NULL); - // return 0; -} - -int spi_flash_vector_helper(const struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)) -{ - int ret; - VOID *din; - __SIZE_TYPE__ bytes_in; - - if (count < 1 || count > 2) - return -1; - - /* SPI flash commands always have a command first... */ - if (!vectors[0].dout || !vectors[0].bytesout) - return -1; - /* And not read any data during the command. */ - if (vectors[0].din || vectors[0].bytesin) - return -1; - - if (count == 2) { - /* If response bytes requested ensure the buffer is valid. */ - if (vectors[1].bytesin && !vectors[1].din) - return -1; - /* No sends can accompany a receive. */ - if (vectors[1].dout || vectors[1].bytesout) - return -1; - din = vectors[1].din; - bytes_in = vectors[1].bytesin; - } else { - din = NULL; - bytes_in = 0; - } - - ret = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); - - if (ret) { - vectors[0].status = SPI_OP_FAILURE; - if (count == 2) - vectors[1].status = SPI_OP_FAILURE; - } else { - vectors[0].status = SPI_OP_SUCCESS; - if (count == 2) - vectors[1].status = SPI_OP_SUCCESS; - } - - return ret; -} - -const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc = { - .erase_cmd = 0x20, /* Sector Erase */ - .status_cmd = 0x05, /* Read Status */ - .pp_cmd = 0x02, /* Page Program */ - .wren_cmd = 0x06, /* Write Enable */ - .ops = { - .read = spi_flash_cmd_read, - .write = spi_flash_cmd_write_page_program, - .erase = spi_flash_cmd_erase, - .status = spi_flash_cmd_status, - }, -}; - -const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc = { - .erase_cmd = 0xd8, /* Sector Erase */ - .status_cmd = 0x05, /* Read Status */ - .pp_cmd = 0x02, /* Page Program */ - .wren_cmd = 0x06, /* Write Enable */ - .ops = { - .read = spi_flash_cmd_read, - .write = spi_flash_cmd_write_page_program, - .erase = spi_flash_cmd_erase, - .status = spi_flash_cmd_status, - }, -}; diff --git a/UefiPayloadPkg/SPI/SPIFlashInternal.h b/UefiPayloadPkg/SPI/SPIFlashInternal.h deleted file mode 100644 index 88b110ab6217..000000000000 --- a/UefiPayloadPkg/SPI/SPIFlashInternal.h +++ /dev/null @@ -1,155 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ - -/* - * SPI flash internal definitions - */ - -#ifndef SPI_FLASH_INTERNAL_H -#define SPI_FLASH_INTERNAL_H - -#include -#include "FvbSPI.h" - -/* Common commands */ -#define CMD_READ_ID 0x9f - -#define CMD_READ_ARRAY_SLOW 0x03 -#define CMD_READ_ARRAY_FAST 0x0b -#define CMD_READ_ARRAY_LEGACY 0xe8 - -#define CMD_READ_FAST_DUAL_OUTPUT 0x3b - -#define CMD_READ_STATUS 0x05 -#define CMD_WRITE_ENABLE 0x06 - -#define CMD_BLOCK_ERASE 0xD8 - -/* Common status */ -#define STATUS_WIP 0x01 - -/* Common register masks */ -#define REG_BUSY_MASK 0x01 -#define REG_WRITE_ENABLE_MASK 0x02 -#define REG_BLOCK_PROTECT_0_MASK 0x04 -#define REG_BLOCK_PROTECT_1_MASK 0x08 -#define REG_BLOCK_PROTECT_2_MASK 0x10 -#define REG_BLOCK_PROTECT_3_MASK 0x20 // FIXME this exists only on some Winbond chips -#define REG_TOP_BOTTOM_PROTECTION_MASK 0x40 // FIXME on other chips T/B mask should be 0x40 -#define REG_STATUS_REGISTER_PROTECTION_MASK 0x80 - - -/* Send a single-byte command to the device and read the response */ -int spi_flash_cmd(const struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len); - -/* - * Send a multi-byte command to the device followed by (optional) - * data. Used for programming the flash array, etc. - */ -int spi_flash_cmd_write(const struct spi_slave *spi, const UINT8 *cmd, - __SIZE_TYPE__ cmd_len, const VOID *data, __SIZE_TYPE__ data_len); - -/* Send a command to the device and wait for some bit to clear itself. */ -int spi_flash_cmd_poll_bit(const struct spi_flash *flash, unsigned long timeout, - UINT8 cmd, UINT8 poll_bit); - -/* - * Send the read status command to the device and wait for the wip - * (write-in-progress) bit to clear itself. - */ -int spi_flash_cmd_wait_ready(const struct spi_flash *flash, unsigned long timeout); - -/* Erase sectors. */ -int spi_flash_cmd_erase(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len); - -/* Read status register. */ -int spi_flash_cmd_status(const struct spi_flash *flash, UINT8 *reg); - -/* Write to flash utilizing page program semantics. */ -int spi_flash_cmd_write_page_program(const struct spi_flash *flash, UINT32 offset, - __SIZE_TYPE__ len, const VOID *buf); - -/* Read len bytes into buf at offset. */ -int spi_flash_cmd_read(const struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ len, VOID *buf); - -/* Release from deep sleep an provide alternative rdid information. */ -int stmicro_release_deep_sleep_identify(const struct spi_slave *spi, UINT8 *idcode); - -int spi_flash_volatile_group_begin(const struct spi_flash *flash); -int spi_flash_volatile_group_end(const struct spi_flash *flash); -// int region_is_subregion(const struct region *p, const struct region *c); -int chipset_volatile_group_begin(const struct spi_flash *flash); -int chipset_volatile_group_end(const struct spi_flash *flash); -// inline __SIZE_TYPE__ region_offset(const struct region *r); -// inline __SIZE_TYPE__ region_end(const struct region *r); -// inline __SIZE_TYPE__ region_sz(const struct region *r); -int spi_flash_vector_helper(const struct spi_slave *slave, - struct spi_op vectors[], __SIZE_TYPE__ count, - int (*func)(const struct spi_slave *slave, const VOID *dout, - __SIZE_TYPE__ bytesout, VOID *din, __SIZE_TYPE__ bytesin)); - -struct spi_flash_part_id { - /* rdid command constructs 2x 16-bit id using the following method - * for matching after reading 5 bytes (1st byte is manuf id): - * id[0] = (id[1] << 8) | id[2] - * id[1] = (id[3] << 8) | id[4] - */ - UINT16 id[2]; - /* Log based 2 total number of sectors. */ - UINT16 nr_sectors_shift: 4; - UINT16 fast_read_dual_output_support : 1; - UINT16 _reserved_for_flags: 3; - /* Block protection. Currently used by Winbond. */ - UINT16 protection_granularity_shift : 5; - UINT16 bp_bits : 3; -}; - -struct spi_flash_ops_descriptor { - UINT8 erase_cmd; /* Sector Erase */ - UINT8 status_cmd; /* Read Status Register */ - UINT8 pp_cmd; /* Page program command, if supported. */ - UINT8 wren_cmd; /* Write Enable command. */ - struct spi_flash_ops ops; -}; - -/* Vendor info represents a common set of organization and commands by a given - * vendor. One can implement multiple sets from a single vendor by having - * separate objects. */ -struct spi_flash_vendor_info { - UINT8 id; - UINT8 page_size_shift : 4; /* if page programming oriented. */ - /* Log based 2 sector size */ - UINT8 sector_size_kib_shift : 4; - UINT16 nr_part_ids; - const struct spi_flash_part_id *ids; - UINT16 match_id_mask[2]; /* matching bytes of the id for this set*/ - const struct spi_flash_ops_descriptor *desc; - const struct spi_flash_protection_ops *prot_ops; - /* Returns 0 on success. !0 otherwise. */ - int (*after_probe)(const struct spi_flash *flash); -}; - -/* Manufacturer-specific probe information */ -extern const struct spi_flash_vendor_info spi_flash_adesto_vi; -extern const struct spi_flash_vendor_info spi_flash_amic_vi; -extern const struct spi_flash_vendor_info spi_flash_atmel_vi; -extern const struct spi_flash_vendor_info spi_flash_eon_vi; -extern const struct spi_flash_vendor_info spi_flash_gigadevice_vi; -extern const struct spi_flash_vendor_info spi_flash_macronix_vi; -/* Probing order matters between the spansion sequence. */ -extern const struct spi_flash_vendor_info spi_flash_spansion_ext1_vi; -extern const struct spi_flash_vendor_info spi_flash_spansion_ext2_vi; -extern const struct spi_flash_vendor_info spi_flash_spansion_vi; -extern const struct spi_flash_vendor_info spi_flash_sst_ai_vi; -extern const struct spi_flash_vendor_info spi_flash_sst_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro1_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro2_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro3_vi; -extern const struct spi_flash_vendor_info spi_flash_stmicro4_vi; -extern const struct spi_flash_vendor_info spi_flash_winbond_vi; - -/* Page Programming Command Set with 0x20 Sector Erase command. */ -extern const struct spi_flash_ops_descriptor spi_flash_pp_0x20_sector_desc; -/* Page Programming Command Set with 0xd8 Sector Erase command. */ -extern const struct spi_flash_ops_descriptor spi_flash_pp_0xd8_sector_desc; - -#endif /* SPI_FLASH_INTERNAL_H */ diff --git a/UefiPayloadPkg/SPI/Winbond.c b/UefiPayloadPkg/SPI/Winbond.c deleted file mode 100644 index e7a2ac9048af..000000000000 --- a/UefiPayloadPkg/SPI/Winbond.c +++ /dev/null @@ -1,539 +0,0 @@ -#include -#include -#include "FvbSPI.h" -#include "GenericSPI.h" -#include "SPIFlashInternal.h" -#include "Winbond.h" - -union status_reg1 { - UINT8 u; - struct { - UINT8 busy : 1; - UINT8 wel : 1; - UINT8 bp : 3; - UINT8 tb : 1; - UINT8 sec : 1; - UINT8 srp0 : 1; - } bp3; - struct { - UINT8 busy : 1; - UINT8 wel : 1; - UINT8 bp : 4; - UINT8 tb : 1; - UINT8 srp0 : 1; - } bp4; -}; - -union status_reg2 { - UINT8 u; - struct { - UINT8 srp1 : 1; - UINT8 qe : 1; - UINT8 res : 1; - UINT8 lb : 3; - UINT8 cmp : 1; - UINT8 sus : 1; - }; -}; - -struct status_regs { - union { - struct { -#if defined(__BIG_ENDIAN) - union status_reg2 reg2; - union status_reg1 reg1; -#else - union status_reg1 reg1; - union status_reg2 reg2; -#endif - }; - UINT16 u; - }; -}; - -static const struct spi_flash_part_id flash_table[] = { - { - /* W25P80 */ - .id[0] = 0x2014, - .nr_sectors_shift = 8, - }, - { - /* W25P16 */ - .id[0] = 0x2015, - .nr_sectors_shift = 9, - }, - { - /* W25P32 */ - .id[0] = 0x2016, - .nr_sectors_shift = 10, - }, - { - /* W25X80 */ - .id[0] = 0x3014, - .nr_sectors_shift = 8, - .fast_read_dual_output_support = 1, - }, - { - /* W25X16 */ - .id[0] = 0x3015, - .nr_sectors_shift = 9, - .fast_read_dual_output_support = 1, - }, - { - /* W25X32 */ - .id[0] = 0x3016, - .nr_sectors_shift = 10, - .fast_read_dual_output_support = 1, - }, - { - /* W25X64 */ - .id[0] = 0x3017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - }, - { - /* W25Q80_V */ - .id[0] = 0x4014, - .nr_sectors_shift = 8, - .fast_read_dual_output_support = 1, - }, - { - /* W25Q16_V */ - .id[0] = 0x4015, - .nr_sectors_shift = 9, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q16DW */ - .id[0] = 0x6015, - .nr_sectors_shift = 9, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q32_V */ - .id[0] = 0x4016, - .nr_sectors_shift = 10, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q32DW */ - .id[0] = 0x6016, - .nr_sectors_shift = 10, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 3, - }, - { - /* W25Q64_V */ - .id[0] = 0x4017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 17, - .bp_bits = 3, - }, - { - /* W25Q64DW */ - .id[0] = 0x6017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 17, - .bp_bits = 3, - }, - { - /* W25Q64JW */ - .id[0] = 0x8017, - .nr_sectors_shift = 11, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 17, - .bp_bits = 3, - }, - { - /* W25Q128_V */ - .id[0] = 0x4018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q128FW */ - .id[0] = 0x6018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q128J */ - .id[0] = 0x7018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q128JW */ - .id[0] = 0x8018, - .nr_sectors_shift = 12, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 18, - .bp_bits = 3, - }, - { - /* W25Q256_V */ - .id[0] = 0x4019, - .nr_sectors_shift = 13, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 4, - }, - { - /* W25Q256J */ - .id[0] = 0x7019, - .nr_sectors_shift = 13, - .fast_read_dual_output_support = 1, - .protection_granularity_shift = 16, - .bp_bits = 4, - }, -}; - -/* - * Convert BPx, TB and CMP to a region. - * SEC (if available) must be zero. - */ -static void winbond_bpbits_to_region(const __SIZE_TYPE__ granularity, - const UINT8 bp, - BOOLEAN tb, - const BOOLEAN cmp, - const __SIZE_TYPE__ flash_size, - struct region *out) -{ - __SIZE_TYPE__ protected_size = - MIN(bp ? granularity << (bp - 1) : 0, flash_size); - - if (cmp) { - protected_size = flash_size - protected_size; - tb = !tb; - } - - out->offset = tb ? 0 : flash_size - protected_size; - out->size = protected_size; -} - -/* - * Available on all devices. - * Read block protect bits from Status/Status2 Reg. - * Converts block protection bits to a region. - * - * Returns: - * -1 on error - * 1 if region is covered by write protection - * 0 if a part of region isn't covered by write protection - */ -static int winbond_get_write_protection(const struct spi_flash *flash, - const struct region *region) -{ - const struct spi_flash_part_id *params; - struct region wp_region; - union status_reg2 reg2; - UINT8 bp, tb; - int ret; - - params = flash->part; - - if (!params) - return -1; - - const __SIZE_TYPE__ granularity = (1 << params->protection_granularity_shift); - - union status_reg1 reg1 = { .u = 0 }; - - ret = spi_flash_cmd(&flash->spi, flash->status_cmd, ®1.u, - sizeof(reg1.u)); - if (ret) - return ret; - - if (params->bp_bits == 3) { - if (reg1.bp3.sec) { - // FIXME: not supported - return -1; - } - - bp = reg1.bp3.bp; - tb = reg1.bp3.tb; - } else if (params->bp_bits == 4) { - bp = reg1.bp4.bp; - tb = reg1.bp4.tb; - } else { - // FIXME: not supported - return -1; - } - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®2.u, - sizeof(reg2.u)); - if (ret) - return ret; - - winbond_bpbits_to_region(granularity, bp, tb, reg2.cmp, flash->size, - &wp_region); - - if (!region_sz(&wp_region)) { - DEBUG((EFI_D_INFO, "%a WINBOND: flash isn't protected\n", __FUNCTION__)); - - return 0; - } - DEBUG((EFI_D_INFO, "%a WINBOND: flash protected range 0x%08zx-0x%08zx\n", - __FUNCTION__, region_offset(&wp_region), region_end(&wp_region))); - - return region_is_subregion(&wp_region, region); -} - -/** - * Common method to write some bit of the status register 1 & 2 at the same - * time. Only change bits that are one in @mask. - * Compare the final result to make sure that the register isn't locked. - * - * @param mask: The bits that are affected by @val - * @param val: The bits to write - * @param non_volatile: Make setting permanent - * - * @return 0 on success - */ -static int winbond_flash_cmd_status(const struct spi_flash *flash, - const UINT16 mask, - const UINT16 val, - const BOOLEAN non_volatile) -{ - struct { - UINT8 cmd; - UINT16 sreg; - } __attribute__((packed)) cmdbuf; - UINT8 reg8; - int ret; - - if (!flash) - return -1; - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg = reg8; - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg |= reg8 << 8; - - if ((val & mask) == (cmdbuf.sreg & mask)) - return 0; - - if (non_volatile) { - ret = spi_flash_cmd(&flash->spi, CMD_W25_WREN, NULL, 0); - } else { - ret = spi_flash_cmd(&flash->spi, CMD_VOLATILE_SREG_WREN, NULL, - 0); - } - if (ret) - return ret; - - cmdbuf.sreg &= ~mask; - cmdbuf.sreg |= val & mask; - cmdbuf.cmd = CMD_W25_WRSR; - - /* Legacy method of writing status register 1 & 2 */ - ret = spi_flash_cmd_write(&flash->spi, (UINT8 *)&cmdbuf, sizeof(cmdbuf), - NULL, 0); - if (ret) - return ret; - - if (non_volatile) { - /* Wait tw */ - ret = spi_flash_cmd_wait_ready(flash, WINBOND_FLASH_TIMEOUT); - if (ret) - return ret; - } else { - /* Wait tSHSL */ - udelay(1); - } - - /* Now read the status register to make sure it's not locked */ - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg = reg8; - - ret = spi_flash_cmd(&flash->spi, CMD_W25_RDSR2, ®8, sizeof(reg8)); - if (ret) - return ret; - - cmdbuf.sreg |= reg8 << 8; - - DEBUG((EFI_D_INFO, "%a WINBOND: SREG=%02x SREG2=%02x\n", - __FUNCTION__, - cmdbuf.sreg & 0xff, - cmdbuf.sreg >> 8)); - - /* Compare against expected result */ - if ((val & mask) != (cmdbuf.sreg & mask)) { - DEBUG((EFI_D_INFO, "%a WINBOND: SREG is locked!\n", __FUNCTION__)); - ret = -1; - } - - return ret; -} - -/* - * Available on all devices. - * Protect a region starting from start of flash or end of flash. - * The caller must provide a supported protected region size. - * SEC isn't supported and set to zero. - * Write block protect bits to Status/Status2 Reg. - * Optionally lock the status register if lock_sreg is set with the provided - * mode. - * - * @param flash: The flash to operate on - * @param region: The region to write protect - * @param mode: Optional status register lock-down mode - * - * @return 0 on success - */ -static int -winbond_set_write_protection(const struct spi_flash *flash, - const struct region *region, - const enum spi_flash_status_reg_lockdown mode) -{ - const struct spi_flash_part_id *params; - struct status_regs mask, val; - struct region wp_region; - UINT8 cmp, bp, tb; - int ret; - - /* Need to touch TOP or BOTTOM */ - if (region_offset(region) != 0 && region_end(region) != flash->size) - return -1; - - params = flash->part; - - if (!params) - return -1; - - if (params->bp_bits != 3 && params->bp_bits != 4) { - /* FIXME: not implemented */ - return -1; - } - - wp_region = *region; - - if (region_offset(&wp_region) == 0) - tb = 1; - else - tb = 0; - - if (region_sz(&wp_region) > flash->size / 2) { - cmp = 1; - wp_region.offset = tb ? 0 : region_sz(&wp_region); - wp_region.size = flash->size - region_sz(&wp_region); - tb = !tb; - } else { - cmp = 0; - } - - if (region_sz(&wp_region) == 0) { - bp = 0; - } else if (IS_POWER_OF_2(region_sz(&wp_region)) && - (region_sz(&wp_region) >= - (1 << params->protection_granularity_shift))) { - bp = log2(region_sz(&wp_region)) - - params->protection_granularity_shift + 1; - } else { - DEBUG((EFI_D_INFO, - "%a WINBOND: ERROR: unsupported region size\n", __FUNCTION__)); - return -1; - } - - /* Write block protection bits */ - - if (params->bp_bits == 3) { - val.reg1 = (union status_reg1) { - .bp3 = { .bp = bp, .tb = tb, .sec = 0 } - }; - mask.reg1 = (union status_reg1) { - .bp3 = { .bp = ~0, .tb = 1, .sec = 1 } - }; - } else { - val.reg1 = (union status_reg1) { - .bp4 = { .bp = bp, .tb = tb } - }; - mask.reg1 = (union status_reg1) { - .bp4 = { .bp = ~0, .tb = 1 } - }; - } - - val.reg2 = (union status_reg2) { .cmp = cmp }; - mask.reg2 = (union status_reg2) { .cmp = 1 }; - - if (mode != SPI_WRITE_PROTECTION_PRESERVE) { - UINT8 srp; - switch (mode) { - case SPI_WRITE_PROTECTION_NONE: - srp = 0; - break; - case SPI_WRITE_PROTECTION_PIN: - srp = 1; - break; - case SPI_WRITE_PROTECTION_REBOOT: - srp = 2; - break; - case SPI_WRITE_PROTECTION_PERMANENT: - srp = 3; - break; - default: - return -1; - } - - if (params->bp_bits == 3) { - val.reg1.bp3.srp0 = !!(srp & 1); - mask.reg1.bp3.srp0 = 1; - } else { - val.reg1.bp4.srp0 = !!(srp & 1); - mask.reg1.bp4.srp0 = 1; - } - - val.reg2.srp1 = !!(srp & 2); - mask.reg2.srp1 = 1; - } - - ret = winbond_flash_cmd_status(flash, mask.u, val.u, TRUE); - if (ret) - return ret; - DEBUG((EFI_D_INFO, "%a WINBOND: write-protection set to range " - "0x%08zx-0x%08zx\n", __FUNCTION__, - region_offset(region), region_end(region))); - - return ret; -} - -static const struct spi_flash_protection_ops spi_flash_protection_ops = { - .get_write = winbond_get_write_protection, - .set_write = winbond_set_write_protection, -}; - -const struct spi_flash_vendor_info spi_flash_winbond_vi = { - .id = VENDOR_ID_WINBOND, - .page_size_shift = 8, - .sector_size_kib_shift = 2, - .match_id_mask[0] = 0xffff, - .ids = flash_table, - .nr_part_ids = ARRAY_SIZE(flash_table), - .desc = &spi_flash_pp_0x20_sector_desc, - .prot_ops = &spi_flash_protection_ops, -}; From 337fad733234c83ec1b7f6923f471bec1faa4bfc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 29 Oct 2020 17:20:14 +0100 Subject: [PATCH 278/297] UefiPayloadPkg/AmdSpiDxe: add AmdSpiDxe module to provide FVB protocol MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c | 231 ++++++ UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.h | 118 +++ UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf | 64 ++ UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c | 871 +++++++++++++++++++++ UefiPayloadPkg/Include/Library/AmdSpiLib.h | 88 +++ UefiPayloadPkg/UefiPayloadPkg.fdf | 12 +- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 13 +- 7 files changed, 1387 insertions(+), 10 deletions(-) create mode 100644 UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c create mode 100644 UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.h create mode 100644 UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf create mode 100644 UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c create mode 100644 UefiPayloadPkg/Include/Library/AmdSpiLib.h diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c new file mode 100644 index 000000000000..c60791b77d11 --- /dev/null +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c @@ -0,0 +1,231 @@ +/** @file AmdSpiStoreDxe.c + + Copyright (c) 2020, 3mdeb Embedded Systems Consulting
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AmdSpiDxe.h" + +STATIC EFI_EVENT mAmdSpiVirtualAddrChangeEvent; + +// +// Global variable declarations +// +AMD_SPI_INSTANCE *mAMDSpiInstance; + +AMD_SPI_INSTANCE mAMDSpiInstanceTemplate = { + AMD_SPI_SIGNATURE, // Signature + NULL, // Handle ... NEED TO BE FILLED + { + 0, // MediaId ... NEED TO BE FILLED + FALSE, // RemovableMedia + TRUE, // MediaPresent + FALSE, // LogicalPartition + FALSE, // ReadOnly + FALSE, // WriteCaching; + 0, // BlockSize ... NEED TO BE FILLED + 4, // IoAlign + 0, // LastBlock ... NEED TO BE FILLED + 0, // LowestAlignedLba + 1, // LogicalBlocksPerPhysicalBlock + }, //Media; + + { + FvbGetAttributes, // GetAttributes + FvbSetAttributes, // SetAttributes + FvbGetPhysicalAddress, // GetPhysicalAddress + FvbGetBlockSize, // GetBlockSize + FvbRead, // Read + FvbWrite, // Write + FvbEraseBlocks, // EraseBlocks + NULL, //ParentHandle + }, // FvbProtoccol; + { + { + { + HARDWARE_DEVICE_PATH, + HW_VENDOR_DP, + { + (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End)), + (UINT8)(OFFSET_OF (NOR_FLASH_DEVICE_PATH, End) >> 8) + } + }, + { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED + }, + 0, // Index + { + END_DEVICE_PATH_TYPE, + END_ENTIRE_DEVICE_PATH_SUBTYPE, + { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } + } + } // DevicePath +}; + +STATIC +EFI_STATUS +AmdSpiCreateInstance ( + IN UINTN NumberofBlocks, + IN UINTN BlockSize, + OUT AMD_SPI_INSTANCE** AMDSpiInstance + ) +{ + EFI_STATUS Status; + AMD_SPI_INSTANCE* Instance; + + ASSERT(AMDSpiInstance != NULL); + + Instance = AllocateRuntimeCopyPool (sizeof(AMD_SPI_INSTANCE),&mAMDSpiInstanceTemplate); + if (Instance == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + Instance->Media.MediaId = 0; + Instance->Media.BlockSize = BlockSize; + Instance->Media.LastBlock = NumberofBlocks - 1; + + CopyGuid (&Instance->DevicePath.Vendor.Guid, &gEfiCallerIdGuid); + Instance->DevicePath.Index = (UINT8)0; + + Status = AmdSpiFvbInitialize (Instance); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + + Status = gBS->InstallMultipleProtocolInterfaces ( + &Instance->Handle, + &gEfiDevicePathProtocolGuid, &Instance->DevicePath, + &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol, + NULL + ); + if (EFI_ERROR(Status)) { + FreePool (Instance); + return Status; + } + + DEBUG((DEBUG_INFO, "%a: Created a new instance\n", __FUNCTION__)); + + *AMDSpiInstance = Instance; + return Status; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +BlAMDSpiVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + // Convert Fvb + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.EraseBlocks); + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.GetAttributes); + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.GetBlockSize); + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.GetPhysicalAddress); + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.Read); + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.SetAttributes); + EfiConvertPointer (0x0, (VOID**)&mAMDSpiInstance->FvbProtocol.Write); + + return; +} + +EFI_STATUS +EFIAPI +BlAmdSpiInitialise ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_GCD_MEMORY_SPACE_DESCRIPTOR GcdDescriptor; + + if (PcdGetBool (PcdEmuVariableNvModeEnable)) { + DEBUG ((DEBUG_WARN, "Variable emulation is active! Skipping driver init.\n")); + return EFI_SUCCESS; + } + + Status = AmdSpiInitialize(); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"%a: Failed to initialize AmdSpi\n", __FUNCTION__)); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + return Status; + } + + mAMDSpiInstance = AllocateRuntimePool (sizeof(AMD_SPI_INSTANCE*)); + if (!mAMDSpiInstance) { + DEBUG((EFI_D_ERROR, "%a: Out of resources\n", __FUNCTION__)); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + return EFI_OUT_OF_RESOURCES; + } + + Status = AmdSpiCreateInstance (4, 0x10000, &mAMDSpiInstance); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR, "%a: Fail to create instance for AmdSpi\n", + __FUNCTION__)); + PcdSetBoolS (PcdEmuVariableNvModeEnable, TRUE); + return Status; + } + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + BlAMDSpiVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mAmdSpiVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + // + // Mark the memory mapped store as MMIO memory + // + Status = gDS->GetMemorySpaceDescriptor (PcdGet32(PcdFlashNvStorageVariableBase), &GcdDescriptor); + if (EFI_ERROR (Status) || GcdDescriptor.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { + DEBUG((EFI_D_INFO, "%a: No memory space descriptor for com buffer found\n", + __FUNCTION__)); + + // + // Add a new entry if not covered by existing mapping + // + Status = gDS->AddMemorySpace ( + EfiGcdMemoryTypeMemoryMappedIo, + PcdGet32(PcdFlashNvStorageVariableBase), + 4 * 0x10000, + EFI_MEMORY_UC | EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + } + + // + // Mark as runtime service + // + Status = gDS->SetMemorySpaceAttributes ( + PcdGet32(PcdFlashNvStorageVariableBase), + 4 * 0x10000, + EFI_MEMORY_RUNTIME + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.h b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.h new file mode 100644 index 000000000000..09ca3ea359d2 --- /dev/null +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.h @@ -0,0 +1,118 @@ +/** @file AmdSpiDxe.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __AMD_SPI_DXE_H__ +#define __AMD_SPI_DXE_H__ + + +#include +#include + +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define AMD_SPI_SIGNATURE SIGNATURE_32('A', 'S', 'P', 'I') +#define INSTANCE_FROM_FVB_THIS(a) CR(a, AMD_SPI_INSTANCE, FvbProtocol, AMD_SPI_SIGNATURE) + +typedef struct _AMD_SPI_INSTANCE AMD_SPI_INSTANCE; + +#pragma pack (1) +typedef struct { + VENDOR_DEVICE_PATH Vendor; + UINT8 Index; + EFI_DEVICE_PATH_PROTOCOL End; +} NOR_FLASH_DEVICE_PATH; +#pragma pack () + +struct _AMD_SPI_INSTANCE { + UINT32 Signature; + EFI_HANDLE Handle; + EFI_BLOCK_IO_MEDIA Media; + + EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; + + NOR_FLASH_DEVICE_PATH DevicePath; +}; + +// +// BlAmdSpiFvbDxe.c +// + +EFI_STATUS +EFIAPI +AmdSpiFvbInitialize ( + IN AMD_SPI_INSTANCE* Instance + ); + +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ); + +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ); + +EFI_STATUS +EFIAPI +FvbGetBlockSize( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ); + +EFI_STATUS +EFIAPI +FvbRead( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbWrite( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ); + +EFI_STATUS +EFIAPI +FvbEraseBlocks( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ); + + +#endif /* __AMD_SPI_DXE_H__ */ diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf new file mode 100644 index 000000000000..e27007c9c314 --- /dev/null +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf @@ -0,0 +1,64 @@ +#/** @file +# +# Component description file for SMMSTORE module +# +# Copyright (c) 2020, 9elements Agency GmbH
+# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +#**/ +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UefiPayloadAmdSpiDxe + FILE_GUID = D419A03E-3543-4DE8-8AFD-D6AD124D1D61 + MODULE_TYPE = DXE_RUNTIME_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = BlAmdSpiInitialise + +[Sources.common] + AmdSpiDxe.h + AmdSpiDxe.c + AmdSpiFvbDxe.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + EmbeddedPkg/EmbeddedPkg.dec + UefiPayloadPkg/UefiPayloadPkg.dec + +[LibraryClasses] + IoLib + BaseLib + DebugLib + HobLib + AmdSpiLib + UefiLib + UefiDriverEntryPoint + UefiBootServicesTableLib + UefiRuntimeLib + DxeServicesTableLib + +[Guids] + gEfiSystemNvDataFvGuid + gEfiVariableGuid + gEfiAuthenticatedVariableGuid + gEfiEventVirtualAddressChangeGuid + gEdkiiNvVarStoreFormattedGuid ## PRODUCES ## PROTOCOL + +[Protocols] + gEfiBlockIoProtocolGuid + gEfiDevicePathProtocolGuid + gEfiFirmwareVolumeBlockProtocolGuid ## PRODUCES + gEfiDiskIoProtocolGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize + gEfiMdeModulePkgTokenSpaceGuid.PcdEmuVariableNvModeEnable + +[Depex] + gEfiCpuArchProtocolGuid diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c new file mode 100644 index 000000000000..36bbc66a7281 --- /dev/null +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c @@ -0,0 +1,871 @@ +/*++ @file AmdSpiFvbDxe.c + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + + --*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "AmdSpiDxe.h" + +STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; +STATIC UINTN mFlashNvStorageVariableBase; + +STATIC VOID +InternalDumpData ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + for (Index = 0; Index < Size; Index++) { + DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index])); + } +} + +STATIC VOID +InternalDumpHex ( + IN UINT8 *Data, + IN UINTN Size + ) +{ + UINTN Index; + UINTN Count; + UINTN Left; + +#define COLUME_SIZE (16 * 2) + + Count = Size / COLUME_SIZE; + Left = Size % COLUME_SIZE; + for (Index = 0; Index < Count; Index++) { + DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); + DEBUG ((EFI_D_INFO, "\n")); + } + + if (Left != 0) { + DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); + InternalDumpData (Data + Index * COLUME_SIZE, Left); + DEBUG ((EFI_D_INFO, "\n")); + } +} + +/// +/// The Firmware Volume Block Protocol is the low-level interface +/// to a firmware volume. File-level access to a firmware volume +/// should not be done using the Firmware Volume Block Protocol. +/// Normal access to a firmware volume must use the Firmware +/// Volume Protocol. Typically, only the file system driver that +/// produces the Firmware Volume Protocol will bind to the +/// Firmware Volume Block Protocol. +/// + +/** + Initialises the FV Header and Variable Store Header + to support variable operations. + + @param[in] Ptr - Location to initialise the headers + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN AMD_SPI_INSTANCE *Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_STATUS Status; + VOID* Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); + Headers = AllocateZeroPool(HeadersLength); + + // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + + // Check if the size of the area is at least one block size + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); + + // Ensure the Variable area Base Addresses are aligned on a block size boundaries + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + + // + // EFI_FIRMWARE_VOLUME_HEADER + // + FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; + CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); + FirmwareVolumeHeader->FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; + FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled + ); + FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); + FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; + FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; + FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; + FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; + FirmwareVolumeHeader->BlockMap[1].Length = 0; + FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); + + // + // VARIABLE_STORE_HEADER + // + VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); + CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; + VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; + VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; + + DEBUG ((EFI_D_INFO, "%a: Variable Store header to write:\n", __FUNCTION__)); + InternalDumpHex((UINT8 *)Headers, HeadersLength); + + // Install the combined super-header in the store + Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); + + FreePool (Headers); + return Status; +} + +/** + Check the integrity of firmware volume header. + + @param[in] FwVolHeader - A pointer to a firmware volume header + + @retval EFI_SUCCESS - The firmware volume is consistent + @retval EFI_NOT_FOUND - The firmware volume has been corrupted. + +**/ +EFI_STATUS +ValidateFvHeader ( + IN AMD_SPI_INSTANCE *Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINT16 Checksum; + EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + UINTN VariableStoreLength; + UINTN FvLength; + EFI_STATUS TempStatus; + UINTN BufferSize; + UINTN BufferSizeReqested; + + BufferSizeReqested = sizeof(EFI_FIRMWARE_VOLUME_HEADER); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = FvbRead (&Instance->FvbProtocol, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + DEBUG ((EFI_D_INFO, "%a: FwVol header check:\n", __FUNCTION__)); + InternalDumpHex((UINT8 *)FwVolHeader, BufferSize); + + FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + + // + // Verify the header revision, header signature, length + // Length of FvBlock cannot be 2**64-1 + // HeaderLength cannot be an odd number + // + if ( (FwVolHeader->Revision != EFI_FVH_REVISION) + || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength != FvLength) + ) + { + DEBUG ((EFI_D_INFO, "%a: No Firmware Volume header present\n", __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + // Check the Firmware Volume Guid + if( CompareGuid (&FwVolHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid) == FALSE ) { + DEBUG ((EFI_D_INFO, "%a: Firmware Volume Guid non-compatible\n", __FUNCTION__)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = FwVolHeader->HeaderLength; + FreePool (FwVolHeader); + FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)AllocatePool(BufferSizeReqested); + if (!FwVolHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = FvbRead (&Instance->FvbProtocol, 0, 0, &BufferSize, (UINT8 *)FwVolHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + DEBUG ((EFI_D_INFO, "%a: FwVol header:\n", __FUNCTION__)); + InternalDumpHex((UINT8 *)FwVolHeader, BufferSize); + + // Verify the header checksum + Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); + if (Checksum != 0) { + DEBUG ((EFI_D_INFO, "%a: FV checksum is invalid (Checksum:0x%X)\n", + __FUNCTION__, Checksum)); + FreePool (FwVolHeader); + return EFI_NOT_FOUND; + } + + BufferSizeReqested = sizeof(VARIABLE_STORE_HEADER); + VariableStoreHeader = (VARIABLE_STORE_HEADER*)AllocatePool(BufferSizeReqested); + if (!VariableStoreHeader) { + return EFI_OUT_OF_RESOURCES; + } + BufferSize = BufferSizeReqested; + TempStatus = FvbRead (&Instance->FvbProtocol, 0, FwVolHeader->HeaderLength, &BufferSize, (UINT8 *)VariableStoreHeader); + if (EFI_ERROR (TempStatus) || BufferSizeReqested != BufferSize) { + FreePool (VariableStoreHeader); + FreePool (FwVolHeader); + return EFI_DEVICE_ERROR; + } + + DEBUG ((EFI_D_INFO, "%a: Variable Store header:\n", __FUNCTION__)); + InternalDumpHex((UINT8 *)VariableStoreHeader, BufferSize); + + // Check the Variable Store Guid + if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && + !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Guid non-compatible\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + VariableStoreLength = PcdGet32 (PcdFlashNvStorageVariableSize) - FwVolHeader->HeaderLength; + if (VariableStoreHeader->Size != VariableStoreLength) { + DEBUG ((EFI_D_INFO, "%a: Variable Store Length does not match\n", + __FUNCTION__)); + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + return EFI_NOT_FOUND; + } + + FreePool (FwVolHeader); + FreePool (VariableStoreHeader); + + return EFI_SUCCESS; +} + +/** + The GetAttributes() function retrieves the attributes and + current settings of the block. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes Pointer to EFI_FVB_ATTRIBUTES_2 in which the attributes and + current settings are returned. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + **/ +EFI_STATUS +EFIAPI +FvbGetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_FVB_ATTRIBUTES_2 FlashFvbAttributes; + AMD_SPI_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + FlashFvbAttributes = (EFI_FVB_ATTRIBUTES_2) ( + + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY // After erasure all bits take this value (i.e. '1') + + ); + + // Check if it is write protected + if (Instance->Media.ReadOnly != TRUE) { + + FlashFvbAttributes = FlashFvbAttributes | + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP; // Writes may be enabled + } + + *Attributes = FlashFvbAttributes; + + DEBUG ((DEBUG_BLKIO, "FvbGetAttributes(0x%X)\n", *Attributes)); + + return EFI_SUCCESS; +} + +/** + The SetAttributes() function sets configurable firmware volume attributes + and returns the new settings of the firmware volume. + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Attributes On input, Attributes is a pointer to EFI_FVB_ATTRIBUTES_2 + that contains the desired firmware volume settings. + On successful return, it contains the new settings of + the firmware volume. + Type EFI_FVB_ATTRIBUTES_2 is defined in EFI_FIRMWARE_VOLUME_HEADER. + + @retval EFI_SUCCESS The firmware volume attributes were returned. + + @retval EFI_INVALID_PARAMETER The attributes requested are in conflict with the capabilities + as declared in the firmware volume header. + + **/ +EFI_STATUS +EFIAPI +FvbSetAttributes( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + DEBUG ((DEBUG_BLKIO, "FvbSetAttributes(0x%X) is not supported\n",*Attributes)); + return EFI_UNSUPPORTED; +} + +/** + The GetPhysicalAddress() function retrieves the base address of + a memory-mapped firmware volume. This function should be called + only for memory-mapped firmware volumes. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Address Pointer to a caller-allocated + EFI_PHYSICAL_ADDRESS that, on successful + return from GetPhysicalAddress(), contains the + base address of the firmware volume. + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_NOT_SUPPORTED The firmware volume is not memory mapped. + + **/ +EFI_STATUS +EFIAPI +FvbGetPhysicalAddress ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + OUT EFI_PHYSICAL_ADDRESS *Address + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + ASSERT(Address != NULL); + + *Address = mFlashNvStorageVariableBase; + return EFI_SUCCESS; +} + +/** + The GetBlockSize() function retrieves the size of the requested + block. It also returns the number of additional blocks with + the identical size. The GetBlockSize() function is used to + retrieve the block map (see EFI_FIRMWARE_VOLUME_HEADER). + + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba Indicates the block for which to return the size. + + @param BlockSize Pointer to a caller-allocated UINTN in which + the size of the block is returned. + + @param NumberOfBlocks Pointer to a caller-allocated UINTN in + which the number of consecutive blocks, + starting with Lba, is returned. All + blocks in this range have a size of + BlockSize. + + + @retval EFI_SUCCESS The firmware volume base address was returned. + + @retval EFI_INVALID_PARAMETER The requested LBA is out of range. + + **/ +EFI_STATUS +EFIAPI +FvbGetBlockSize ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + OUT UINTN *BlockSize, + OUT UINTN *NumberOfBlocks + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_STATUS Status; + AMD_SPI_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize(Lba=%ld, BlockSize=0x%x, LastBlock=%ld)\n", Lba, Instance->Media.BlockSize, Instance->Media.LastBlock)); + + if (Lba > Instance->Media.LastBlock) { + DEBUG ((EFI_D_ERROR, "FvbGetBlockSize: ERROR - Parameter LBA %ld is beyond the last Lba (%ld).\n", Lba, Instance->Media.LastBlock)); + Status = EFI_INVALID_PARAMETER; + } else { + *BlockSize = (UINTN) Instance->Media.BlockSize; + *NumberOfBlocks = (UINTN) (Instance->Media.LastBlock - Lba + 1); + + DEBUG ((DEBUG_BLKIO, "FvbGetBlockSize: *BlockSize=0x%x, *NumberOfBlocks=0x%x.\n", *BlockSize, *NumberOfBlocks)); + + Status = EFI_SUCCESS; + } + + return Status; +} + +/** + Reads the specified number of bytes into a buffer from the specified block. + + The Read() function reads the requested number of bytes from the + requested block and stores them in the provided buffer. + Implementations should be mindful that the firmware volume + might be in the ReadDisabled state. If it is in this state, + the Read() function must return the status code + EFI_ACCESS_DENIED without modifying the contents of the + buffer. The Read() function must also prevent spanning block + boundaries. If a read is requested that would span a block + boundary, the read must read up to the boundary but not + beyond. The output parameter NumBytes must be set to correctly + indicate the number of bytes actually read. The caller must be + aware that a read may be partially completed. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index from which to read. + + @param Offset Offset into the block at which to begin reading. + + @param NumBytes Pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes read. + + @param Buffer Pointer to a caller-allocated buffer that will be used + to hold the data that is read. + + @retval EFI_SUCCESS The firmware volume was read successfully, and contents are + in Buffer. + + @retval EFI_BAD_BUFFER_SIZE Read attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + returned in Buffer. + + @retval EFI_ACCESS_DENIED The firmware volume is in the ReadDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be read. + + **/ +EFI_STATUS +EFIAPI +FvbRead ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN OUT UINT8 *Buffer + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINTN BlockSize; + AMD_SPI_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + DEBUG ((DEBUG_BLKIO, "FvbRead: Check if (Offset=0x%x + NumBytes=0x%x) <= BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return AmdSpiRead (Lba, Offset, NumBytes, Buffer); +} + +/** + Writes the specified number of bytes from the input buffer to the block. + + The Write() function writes the specified number of bytes from + the provided buffer to the specified block and offset. If the + firmware volume is sticky write, the caller must ensure that + all the bits of the specified range to write are in the + EFI_FVB_ERASE_POLARITY state before calling the Write() + function, or else the result will be unpredictable. This + unpredictability arises because, for a sticky-write firmware + volume, a write may negate a bit in the EFI_FVB_ERASE_POLARITY + state but cannot flip it back again. Before calling the + Write() function, it is recommended for the caller to first call + the EraseBlocks() function to erase the specified block to + write. A block erase cycle will transition bits from the + (NOT)EFI_FVB_ERASE_POLARITY state back to the + EFI_FVB_ERASE_POLARITY state. Implementations should be + mindful that the firmware volume might be in the WriteDisabled + state. If it is in this state, the Write() function must + return the status code EFI_ACCESS_DENIED without modifying the + contents of the firmware volume. The Write() function must + also prevent spanning block boundaries. If a write is + requested that spans a block boundary, the write must store up + to the boundary but not beyond. The output parameter NumBytes + must be set to correctly indicate the number of bytes actually + written. The caller must be aware that a write may be + partially completed. All writes, partial or otherwise, must be + fully flushed to the hardware before the Write() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL instance. + + @param Lba The starting logical block index to write to. + + @param Offset Offset into the block at which to begin writing. + + @param NumBytes The pointer to a UINTN. + At entry, *NumBytes contains the total size of the buffer. + At exit, *NumBytes contains the total number of bytes actually written. + + @param Buffer The pointer to a caller-allocated buffer that contains the source for the write. + + @retval EFI_SUCCESS The firmware volume was written successfully. + + @retval EFI_BAD_BUFFER_SIZE The write was attempted across an LBA boundary. + On output, NumBytes contains the total number of bytes + actually written. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is malfunctioning and could not be written. + + + **/ +EFI_STATUS +EFIAPI +FvbWrite ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + IN EFI_LBA Lba, + IN UINTN Offset, + IN OUT UINTN *NumBytes, + IN UINT8 *Buffer + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINTN BlockSize; + AMD_SPI_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + + // Cache the block size to avoid de-referencing pointers all the time + BlockSize = Instance->Media.BlockSize; + + // The read must not span block boundaries. + // We need to check each variable individually because adding two large values together overflows. + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { + DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); + return EFI_BAD_BUFFER_SIZE; + } + + // We must have some bytes to read + if (*NumBytes == 0) { + return EFI_BAD_BUFFER_SIZE; + } + + return AmdSpiWrite (Lba, Offset, NumBytes, Buffer); +} + +/** + Erases and initialises a firmware volume block. + + The EraseBlocks() function erases one or more blocks as denoted + by the variable argument list. The entire parameter list of + blocks must be verified before erasing any blocks. If a block is + requested that does not exist within the associated firmware + volume (it has a larger index than the last block of the + firmware volume), the EraseBlocks() function must return the + status code EFI_INVALID_PARAMETER without modifying the contents + of the firmware volume. Implementations should be mindful that + the firmware volume might be in the WriteDisabled state. If it + is in this state, the EraseBlocks() function must return the + status code EFI_ACCESS_DENIED without modifying the contents of + the firmware volume. All calls to EraseBlocks() must be fully + flushed to the hardware before the EraseBlocks() service + returns. + + @param This Indicates the EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL + instance. + + @param ... The variable argument list is a list of tuples. + Each tuple describes a range of LBAs to erase + and consists of the following: + - An EFI_LBA that indicates the starting LBA + - A UINTN that indicates the number of blocks to erase. + + The list is terminated with an EFI_LBA_LIST_TERMINATOR. + For example, the following indicates that two ranges of blocks + (5-7 and 10-11) are to be erased: + EraseBlocks (This, 5, 3, 10, 2, EFI_LBA_LIST_TERMINATOR); + + @retval EFI_SUCCESS The erase request successfully completed. + + @retval EFI_ACCESS_DENIED The firmware volume is in the WriteDisabled state. + + @retval EFI_DEVICE_ERROR The block device is not functioning correctly and could not be written. + The firmware device may have been partially erased. + + @retval EFI_INVALID_PARAMETER One or more of the LBAs listed in the variable argument list do + not exist in the firmware volume. + + **/ +EFI_STATUS +EFIAPI +FvbEraseBlocks ( + IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, + ... + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_STATUS Status; + VA_LIST Args; + EFI_LBA StartingLba; // Lba from which we start erasing + UINTN NumOfLba; // Number of Lba blocks to erase + AMD_SPI_INSTANCE *Instance; + + Instance = INSTANCE_FROM_FVB_THIS(This); + + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks()\n")); + + Status = EFI_SUCCESS; + + // Detect WriteDisabled state + if (Instance->Media.ReadOnly == TRUE) { + // Firmware volume is in WriteDisabled state + DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Device is in WriteDisabled state.\n")); + return EFI_ACCESS_DENIED; + } + + // Before erasing, check the entire list of parameters to ensure all specified blocks are valid + + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba = VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + //Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba = VA_ARG (Args, UINTN); + + // All blocks must be within range + DEBUG (( + DEBUG_BLKIO, + "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%Lu - 1 ) > LastBlock=%ld.\n", + StartingLba, + (UINT64)NumOfLba, + Instance->Media.LastBlock + )); + if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { + VA_END (Args); + DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n")); + Status = EFI_INVALID_PARAMETER; + goto EXIT; + } + } while (TRUE); + VA_END (Args); + + // + // To get here, all must be ok, so start erasing + // + VA_START (Args, This); + do { + // Get the Lba from which we start erasing + StartingLba = VA_ARG (Args, EFI_LBA); + + // Have we reached the end of the list? + if (StartingLba == EFI_LBA_LIST_TERMINATOR) { + // Exit the while loop + break; + } + + // How many Lba blocks are we requested to erase? + NumOfLba = VA_ARG (Args, UINTN); + + // Go through each one and erase it + while (NumOfLba > 0) { + // Erase it + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld\n", StartingLba)); + Status = AmdSpiEraseBlock (StartingLba); + if (EFI_ERROR(Status)) { + VA_END (Args); + Status = EFI_DEVICE_ERROR; + goto EXIT; + } + + // Move to the next Lba + StartingLba++; + NumOfLba--; + } + } while (TRUE); + VA_END (Args); + +EXIT: + return Status; +} + +/** + Fixup internal data so that EFI can be call in virtual mode. + Call the passed in Child Notify event and convert any pointers in + lib to virtual mode. + + @param[in] Event The Event that is being processed + @param[in] Context Event Context +**/ +VOID +EFIAPI +FvbVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EfiConvertPointer (0x0, (VOID**)&mFlashNvStorageVariableBase); + return; +} + +EFI_STATUS +EFIAPI +AmdSpiFvbInitialize ( + IN AMD_SPI_INSTANCE* Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_STATUS Status; + UINT32 FvbNumLba; + EFI_BOOT_MODE BootMode; + + DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); + ASSERT((Instance != NULL)); + + mFlashNvStorageVariableBase = PcdGet32 (PcdFlashNvStorageVariableBase); + + BootMode = GetBootModeHob (); + if (BootMode == BOOT_WITH_DEFAULT_SETTINGS) { + Status = EFI_INVALID_PARAMETER; + } else { + // Determine if there is a valid header at the beginning of the NorFlash + Status = ValidateFvHeader (Instance); + } + + // Install the Default FVB header if required + if (EFI_ERROR(Status)) { + // There is no valid header, so time to install one. + DEBUG ((EFI_D_INFO, "%a: The FVB Header is not valid.\n", __FUNCTION__)); + DEBUG ((EFI_D_INFO, "%a: Installing a correct one for this volume.\n", + __FUNCTION__)); + + // Erase all the NorFlash that is reserved for variable storage + FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; + + Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); + if (EFI_ERROR(Status)) { + return Status; + } + + // Install all appropriate headers + Status = InitializeFvAndVariableStoreHeaders (Instance); + if (EFI_ERROR(Status)) { + return Status; + } + } else { + DEBUG((DEBUG_INFO, "%a: FVB header is valid\n", __FUNCTION__)); + } + + // + // The driver implementing the variable read service can now be dispatched; + // the varstore headers are in place. + // + Status = gBS->InstallProtocolInterface ( + &gImageHandle, + &gEdkiiNvVarStoreFormattedGuid, + EFI_NATIVE_INTERFACE, + NULL + ); + ASSERT_EFI_ERROR (Status); + + // + // Register for the virtual address change event + // + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + FvbVirtualNotifyEvent, + NULL, + &gEfiEventVirtualAddressChangeGuid, + &mFvbVirtualAddrChangeEvent + ); + ASSERT_EFI_ERROR (Status); + + return Status; +} diff --git a/UefiPayloadPkg/Include/Library/AmdSpiLib.h b/UefiPayloadPkg/Include/Library/AmdSpiLib.h new file mode 100644 index 000000000000..010f3ec3cb10 --- /dev/null +++ b/UefiPayloadPkg/Include/Library/AmdSpiLib.h @@ -0,0 +1,88 @@ +/** @file AmdSpiLib.h + + Copyright (c) 2020, 9elements Agency GmbH
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __AMD_SPI_LIB_H__ +#define __AMD_SPI_LIB_H__ + +#include +#include + +/** + Read from AMD SPI + + @param[in] Lba The starting logical block index to read from. + @param[in] Offset Offset into the block at which to begin reading. + @param[in] NumBytes On input, indicates the requested read size. On + output, indicates the actual number of bytes read + @param[in] Buffer Pointer to the buffer to read into. + +**/ +EFI_STATUS +AmdSpiRead ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Write to AMD SPI + + @param[in] Lba The starting logical block index to write to. + @param[in] Offset Offset into the block at which to begin writing. + @param[in] NumBytes On input, indicates the requested write size. On + output, indicates the actual number of bytes written + @param[in] Buffer Pointer to the data to write. + +**/ +EFI_STATUS +AmdSpiWrite ( + IN EFI_LBA Lba, + IN UINTN Offset, + IN UINTN *NumBytes, + IN UINT8 *Buffer + ); + + +/** + Erase a block using the AMD SPI + + @param Lba The logical block index to erase. + +**/ +EFI_STATUS +AmdSpiEraseBlock ( + IN EFI_LBA Lba + ); + + +/** + Notify the AMD SPI Library about a VirtualNotify + +**/ + +VOID +EFIAPI +AmdSpiVirtualNotifyEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ); + +/** + Initializes AMD SPI support + @retval EFI_WRITE_PROTECTED The AMD SPI is not present. + @retval EFI_SUCCESS The AMD SPI is supported. + +**/ +EFI_STATUS +AmdSpiInitialize ( + VOID + ); + +#endif /* __AMD_SPI_LIB_H__ */ diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 04c6baa7a88e..8aa7d89ddd16 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -10,16 +10,16 @@ ################################################################################ [FD.UefiPayload] -BaseAddress = 0x240000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase -Size = 0x240000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize +BaseAddress = 0x440000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase +Size = 0x440000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize ErasePolarity = 1 BlockSize = 0x1000 -NumBlocks = 0x240 +NumBlocks = 0x440 0x00000000|0x040000 FV = PEIFV -0x00040000|0x200000 +0x00040000|0x400000 FV = DXEFV ################################################################################ @@ -85,7 +85,7 @@ APRIORI DXE { INF MdeModulePkg/Universal/StatusCodeHandler/RuntimeDxe/StatusCodeHandlerRuntimeDxe.inf !if $(SECURE_BOOT_ENABLE) == TRUE - INF UefiPayloadPkg/SPI/SPI.inf + INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif # Init Test Driver before Secure Boot # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf @@ -127,7 +127,7 @@ INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf INF MdeModulePkg/Logo/LogoDxe.inf !if $(SECURE_BOOT_ENABLE) == TRUE - INF UefiPayloadPkg/SPI/SPI.inf + INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif # diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index f8e756c8db68..5e4eb16b986d 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -245,6 +245,7 @@ !if $(SECURE_BOOT_ENABLE) == TRUE PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf + AmdSpiLib|UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.inf !else AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf !endif @@ -371,7 +372,7 @@ # The following parameters are set by Library/PlatformHookLib # gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x2f8 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3f8 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE) gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1 @@ -433,9 +434,6 @@ ################################################################################ [Components.IA32] -!if $(SECURE_BOOT_ENABLE) == TRUE - UefiPayloadPkg/SPI/SPI.inf -!endif # # SEC Core # @@ -605,6 +603,13 @@ UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf + # + # AMD SPI + # +!if $(SECURE_BOOT_ENABLE) == TRUE + UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf +!endif + # # Network Support # From 13d8ae73b0f1f6c3e9a45064a015c9e6050c2f81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 29 Oct 2020 17:21:11 +0100 Subject: [PATCH 279/297] UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c: do not add iPXE and UEFI Shell MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../Library/PlatformBootManagerLib/PlatformBootManager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c index bbab450b9e26..e72389a8c602 100644 --- a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c +++ b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c @@ -553,12 +553,12 @@ PlatformBootManagerAfterConsole ( // // Register UEFI Shell // - PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE); + //PlatformRegisterFvBootOption (PcdGetPtr (PcdShellFile), L"UEFI Shell", LOAD_OPTION_ACTIVE); // // Register iPXE // - PlatformRegisterFvBootOption (PcdGetPtr (PcdiPXEFile), L"iPXE Network boot", LOAD_OPTION_ACTIVE); + //PlatformRegisterFvBootOption (PcdGetPtr (PcdiPXEFile), L"iPXE Network boot", LOAD_OPTION_ACTIVE); Print (L"Press F9 to enter Boot Manager Menu.\n"); } From b57cc1da0bea76607491c66ec39db8e16e3d0b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 10:51:27 +0100 Subject: [PATCH 280/297] UefiPayloadPkg/Library/AmdSpiLib: clean up the library from debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c | 6 +- .../Library/AmdSpiLib/SPIFlashInternal.c | 64 +++++++++---------- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c index 9246644091e2..190fd85e9545 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c @@ -1,5 +1,6 @@ #include -#include +#include +#include #include "GenericSPI.h" #include "SPIFlashInternal.h" #include "Winbond.h" @@ -49,6 +50,8 @@ AmdSpiWrite ( if (*NumBytes == 0 || Buffer == NULL) return EFI_INVALID_PARAMETER; + MicroSecondDelay(5000); + return spi_flash_write(&flash, address, *NumBytes, Buffer); } @@ -68,6 +71,7 @@ AmdSpiEraseBlock ( if (address > 0xa0000 || address < 0x60000) return EFI_ACCESS_DENIED; + MicroSecondDelay(5000); return spi_flash_erase(&flash, address, BLOCK_SIZE); } diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c index dbca670113ba..df500441046a 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c @@ -37,7 +37,7 @@ STATIC EFI_STATUS do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout count = 1; status = spi_claim_bus(spi); - if (status) + if (EFI_ERROR(status)) return status; status = spi_xfer_vector(spi, vectors, count); @@ -49,8 +49,8 @@ STATIC EFI_STATUS do_spi_flash_cmd(CONST struct spi_slave *spi, CONST VOID *dout EFI_STATUS spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, __SIZE_TYPE__ len) { EFI_STATUS status = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); - if (status) - DEBUG((DEBUG_BLKIO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, status)); + if (EFI_ERROR(status)) + DEBUG((DEBUG_BLKLIO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, status)); return status; } @@ -70,8 +70,8 @@ EFI_STATUS spi_flash_cmd_write(CONST struct spi_slave *spi, CONST UINT8 *cmd, InternalMemCopyMem(buff + cmd_len, data, data_len); status = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0); - if (status) { - DEBUG((DEBUG_BLKIO, "%a SF: Failed to send write command (%zu bytes): %d\n", + if (EFI_ERROR(status)) { + DEBUG((DEBUG_BLKLIO, "%a SF: Failed to send write command (%zu bytes): %d\n", __FUNCTION__, data_len, status)); } @@ -99,8 +99,8 @@ EFI_STATUS spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); spi_flash_addr(offset, cmd); status = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); - if (status) { - DEBUG((DEBUG_BLKIO, + if (EFI_ERROR(status)) { + DEBUG((DEBUG_BLKLIO, "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", __FUNCTION__, cmd[0], offset, xfer_len, status)); return status; @@ -127,7 +127,7 @@ EFI_STATUS spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long t do { status = do_spi_flash_cmd(spi, &cmd, 1, &status, 1); - if (status) + if (EFI_ERROR(status)) return EFI_DEVICE_ERROR; if ((status & poll_bit) == 0) return EFI_SUCCESS; @@ -136,7 +136,7 @@ EFI_STATUS spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long t timeNowstartTimeMilisec && timeNow>endTimeMilisec)); - DEBUG((DEBUG_BLKIO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); + DEBUG((DEBUG_BLKLIO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); return EFI_DEVICE_ERROR; } @@ -155,11 +155,11 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S erase_size = flash->sector_size; if (offset % erase_size || len % erase_size) { - DEBUG((DEBUG_BLKIO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); + DEBUG((DEBUG_BLKLIO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } if (len == 0) { - DEBUG((DEBUG_BLKIO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); + DEBUG((DEBUG_BLKLIO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } @@ -171,24 +171,24 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S spi_flash_addr(offset, cmd); offset += erase_size; - DEBUG((DEBUG_BLKIO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION__, + DEBUG((DEBUG_BLKLIO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], offset)); status = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0); - if (status) + if (EFI_ERROR(status)) goto out; status = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0); - if (status) + if (EFI_ERROR(status)) goto out; status = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); - if (status) + if (EFI_ERROR(status)) goto out; } - DEBUG((DEBUG_BLKIO, "%a SF: Successfully erased %u bytes @ %x\n", + DEBUG((DEBUG_BLKLIO, "%a SF: Successfully erased %u bytes @ %x\n", __FUNCTION__, len, start)); out: @@ -219,28 +219,28 @@ EFI_STATUS spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT3 chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len); spi_flash_addr(offset, cmd); - DEBUG((DEBUG_BLKIO, "%a PP: %p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %u\n", - __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], - chunk_len)); + DEBUG((DEBUG_BLKLIO, "%a PP: %x => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %u\n", + __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len)); status = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0); - if (status < 0) { - DEBUG((DEBUG_BLKIO, "%a SF: Enabling Write failed\n", __FUNCTION__)); + if (EFI_ERROR(status)) { + DEBUG((DEBUG_BLKLIO, "%a SF: Enabling Write failed\n", __FUNCTION__)); goto out; } status = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); - if (status < 0) { - DEBUG((DEBUG_BLKIO, "%a SF: Page Program failed\n", __FUNCTION__)); + if (EFI_ERROR(status)) { + DEBUG((DEBUG_BLKLIO, "%a SF: Page Program failed\n", __FUNCTION__)); goto out; } status = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS); - if (status) + if (EFI_ERROR(status)) goto out; offset += chunk_len; + MicroSecondDelay(1000); } status = EFI_SUCCESS; @@ -306,7 +306,7 @@ EFI_STATUS spi_flash_vector_helper(CONST struct spi_slave *slave, status = func(slave, vectors[0].dout, vectors[0].bytesout, din, bytes_in); - if (status) { + if (EFI_ERROR(status)) { vectors[0].status = SPI_OP_FAILURE; if (count == 2) vectors[1].status = SPI_OP_FAILURE; @@ -407,12 +407,12 @@ STATIC EFI_STATUS spi_flash_generic_probe(CONST struct spi_slave *spi, /* Read the ID codes */ status = spi_flash_cmd(spi, CMD_READ_ID, idcode, sizeof(idcode)); - if (status) + if (EFI_ERROR(status)) return EFI_DEVICE_ERROR; manuf_id = idcode[0]; - DEBUG((DEBUG_BLKIO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); + DEBUG((DEBUG_BLKLIO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); id[0] = (idcode[1] << 8) | idcode[2]; id[1] = (idcode[3] << 8) | idcode[4]; @@ -426,7 +426,7 @@ EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) EFI_STATUS status = EFI_DEVICE_ERROR; if (spi_setup_slave(bus, cs, &spi)) { - DEBUG((DEBUG_BLKIO, "SF: Failed to set up slave\n")); + DEBUG((DEBUG_BLKLIO, "SF: Failed to set up slave\n")); return EFI_DEVICE_ERROR; } @@ -435,12 +435,12 @@ EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) status = spi.ctrlr->flash_probe(&spi, flash); /* If flash is not found, try generic spi flash probe. */ - if (status) + if (EFI_ERROR(status)) status = spi_flash_generic_probe(&spi, flash); /* Give up -- nothing more to try if flash is not found. */ - if (status) { - DEBUG((DEBUG_BLKIO, "SF: Unsupported manufacturer!\n")); + if (EFI_ERROR(status)) { + DEBUG((DEBUG_BLKLIO, "SF: Unsupported manufacturer!\n")); return EFI_DEVICE_ERROR; } @@ -448,7 +448,7 @@ EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) mode_string = " (Dual SPI mode)"; - DEBUG((DEBUG_BLKIO, + DEBUG((DEBUG_BLKLIO, "SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", flash->vendor, flash->model, flash->sector_size, flash->size, mode_string)); From 783a152b8c32bbad3760aeb6c4b9e6a98188ce1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 10:52:00 +0100 Subject: [PATCH 281/297] UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c: validate header after intializing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c | 210 ++++++++++-------------- 1 file changed, 84 insertions(+), 126 deletions(-) diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c index 36bbc66a7281..8d1eadcf87d1 100644 --- a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c @@ -27,45 +27,6 @@ STATIC EFI_EVENT mFvbVirtualAddrChangeEvent; STATIC UINTN mFlashNvStorageVariableBase; -STATIC VOID -InternalDumpData ( - IN UINT8 *Data, - IN UINTN Size - ) -{ - UINTN Index; - for (Index = 0; Index < Size; Index++) { - DEBUG ((EFI_D_INFO, "%02x", (UINTN)Data[Index])); - } -} - -STATIC VOID -InternalDumpHex ( - IN UINT8 *Data, - IN UINTN Size - ) -{ - UINTN Index; - UINTN Count; - UINTN Left; - -#define COLUME_SIZE (16 * 2) - - Count = Size / COLUME_SIZE; - Left = Size % COLUME_SIZE; - for (Index = 0; Index < Count; Index++) { - DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); - InternalDumpData (Data + Index * COLUME_SIZE, COLUME_SIZE); - DEBUG ((EFI_D_INFO, "\n")); - } - - if (Left != 0) { - DEBUG ((EFI_D_INFO, "%04x: ", Index * COLUME_SIZE)); - InternalDumpData (Data + Index * COLUME_SIZE, Left); - DEBUG ((EFI_D_INFO, "\n")); - } -} - /// /// The Firmware Volume Block Protocol is the low-level interface /// to a firmware volume. File-level access to a firmware volume @@ -76,88 +37,6 @@ InternalDumpHex ( /// Firmware Volume Block Protocol. /// -/** - Initialises the FV Header and Variable Store Header - to support variable operations. - - @param[in] Ptr - Location to initialise the headers - -**/ -EFI_STATUS -InitializeFvAndVariableStoreHeaders ( - IN AMD_SPI_INSTANCE *Instance - ) -{ - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); - EFI_STATUS Status; - VOID* Headers; - UINTN HeadersLength; - EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; - VARIABLE_STORE_HEADER *VariableStoreHeader; - - HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); - Headers = AllocateZeroPool(HeadersLength); - - // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); - - // Check if the size of the area is at least one block size - ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); - ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); - - // Ensure the Variable area Base Addresses are aligned on a block size boundaries - ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); - ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); - - // - // EFI_FIRMWARE_VOLUME_HEADER - // - FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; - CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); - FirmwareVolumeHeader->FvLength = - PcdGet32(PcdFlashNvStorageVariableSize) + - PcdGet32(PcdFlashNvStorageFtwWorkingSize) + - PcdGet32(PcdFlashNvStorageFtwSpareSize); - FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; - FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( - EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled - EFI_FVB2_READ_STATUS | // Reads are currently enabled - EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY - EFI_FVB2_MEMORY_MAPPED | // It is memory mapped - EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') - EFI_FVB2_WRITE_STATUS | // Writes are currently enabled - EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled - ); - FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); - FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; - FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; - FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; - FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; - FirmwareVolumeHeader->BlockMap[1].Length = 0; - FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); - - // - // VARIABLE_STORE_HEADER - // - VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); - CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); - VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; - VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; - VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; - - DEBUG ((EFI_D_INFO, "%a: Variable Store header to write:\n", __FUNCTION__)); - InternalDumpHex((UINT8 *)Headers, HeadersLength); - - // Install the combined super-header in the store - Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); - - FreePool (Headers); - return Status; -} - /** Check the integrity of firmware volume header. @@ -233,8 +112,6 @@ ValidateFvHeader ( FreePool (FwVolHeader); return EFI_DEVICE_ERROR; } - DEBUG ((EFI_D_INFO, "%a: FwVol header:\n", __FUNCTION__)); - InternalDumpHex((UINT8 *)FwVolHeader, BufferSize); // Verify the header checksum Checksum = CalculateSum16((UINT16*)FwVolHeader, FwVolHeader->HeaderLength); @@ -258,9 +135,6 @@ ValidateFvHeader ( return EFI_DEVICE_ERROR; } - DEBUG ((EFI_D_INFO, "%a: Variable Store header:\n", __FUNCTION__)); - InternalDumpHex((UINT8 *)VariableStoreHeader, BufferSize); - // Check the Variable Store Guid if (!CompareGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid) && !CompareGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid)) { @@ -286,6 +160,90 @@ ValidateFvHeader ( return EFI_SUCCESS; } +/** + Initialises the FV Header and Variable Store Header + to support variable operations. + + @param[in] Ptr - Location to initialise the headers + +**/ +EFI_STATUS +InitializeFvAndVariableStoreHeaders ( + IN AMD_SPI_INSTANCE *Instance + ) +{ + DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_STATUS Status; + VOID* Headers; + UINTN HeadersLength; + EFI_FIRMWARE_VOLUME_HEADER *FirmwareVolumeHeader; + VARIABLE_STORE_HEADER *VariableStoreHeader; + + HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); + Headers = AllocateZeroPool(HeadersLength); + + // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + + // Check if the size of the area is at least one block size + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); + + // Ensure the Variable area Base Addresses are aligned on a block size boundaries + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + + // + // EFI_FIRMWARE_VOLUME_HEADER + // + FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; + CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); + FirmwareVolumeHeader->FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; + FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( + EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled + EFI_FVB2_READ_STATUS | // Reads are currently enabled + EFI_FVB2_STICKY_WRITE | // A block erase is required to flip bits into EFI_FVB2_ERASE_POLARITY + EFI_FVB2_MEMORY_MAPPED | // It is memory mapped + EFI_FVB2_ERASE_POLARITY | // After erasure all bits take this value (i.e. '1') + EFI_FVB2_WRITE_STATUS | // Writes are currently enabled + EFI_FVB2_WRITE_ENABLED_CAP // Writes may be enabled + ); + FirmwareVolumeHeader->HeaderLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY); + FirmwareVolumeHeader->Revision = EFI_FVH_REVISION; + FirmwareVolumeHeader->BlockMap[0].NumBlocks = Instance->Media.LastBlock + 1; + FirmwareVolumeHeader->BlockMap[0].Length = Instance->Media.BlockSize; + FirmwareVolumeHeader->BlockMap[1].NumBlocks = 0; + FirmwareVolumeHeader->BlockMap[1].Length = 0; + FirmwareVolumeHeader->Checksum = CalculateCheckSum16 ((UINT16*)FirmwareVolumeHeader,FirmwareVolumeHeader->HeaderLength); + + // + // VARIABLE_STORE_HEADER + // + VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); + CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; + VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; + VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; + + // Install the combined super-header in the store + Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); + FreePool (Headers); + + if (EFI_ERROR(Status)) + return Status; + + Status = ValidateFvHeader (Instance); + + return Status; +} + /** The GetAttributes() function retrieves the attributes and current settings of the block. From 64ef4efbd505aa2dd6c6c1fa9cf6d44a27389f67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 11:18:09 +0100 Subject: [PATCH 282/297] UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c: fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../Library/AmdSpiLib/SPIFlashInternal.c | 34 +++++++++---------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c index df500441046a..14de8b49fde7 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ -#include -#include +#include +#include #include #include #include "GenericSPI.h" @@ -50,7 +50,7 @@ EFI_STATUS spi_flash_cmd(CONST struct spi_slave *spi, UINT8 cmd, VOID *response, { EFI_STATUS status = do_spi_flash_cmd(spi, &cmd, sizeof(cmd), response, len); if (EFI_ERROR(status)) - DEBUG((DEBUG_BLKLIO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, status)); + DEBUG((DEBUG_BLKIO, "%a SF: Failed to send command %02x: %d\n", __FUNCTION__, cmd, status)); return status; } @@ -71,7 +71,7 @@ EFI_STATUS spi_flash_cmd_write(CONST struct spi_slave *spi, CONST UINT8 *cmd, status = do_spi_flash_cmd(spi, buff, cmd_len + data_len, NULL, 0); if (EFI_ERROR(status)) { - DEBUG((DEBUG_BLKLIO, "%a SF: Failed to send write command (%zu bytes): %d\n", + DEBUG((DEBUG_BLKIO, "%a SF: Failed to send write command (%zu bytes): %d\n", __FUNCTION__, data_len, status)); } @@ -100,7 +100,7 @@ EFI_STATUS spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, spi_flash_addr(offset, cmd); status = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); if (EFI_ERROR(status)) { - DEBUG((DEBUG_BLKLIO, + DEBUG((DEBUG_BLKIO, "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", __FUNCTION__, cmd[0], offset, xfer_len, status)); return status; @@ -136,7 +136,7 @@ EFI_STATUS spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long t timeNowstartTimeMilisec && timeNow>endTimeMilisec)); - DEBUG((DEBUG_BLKLIO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); + DEBUG((DEBUG_BLKIO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); return EFI_DEVICE_ERROR; } @@ -155,11 +155,11 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S erase_size = flash->sector_size; if (offset % erase_size || len % erase_size) { - DEBUG((DEBUG_BLKLIO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); + DEBUG((DEBUG_BLKIO, "%a SF: Erase offset/length not multiple of erase size\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } if (len == 0) { - DEBUG((DEBUG_BLKLIO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); + DEBUG((DEBUG_BLKIO, "%a SF: Erase length cannot be 0\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } @@ -171,7 +171,7 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S spi_flash_addr(offset, cmd); offset += erase_size; - DEBUG((DEBUG_BLKLIO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION__, + DEBUG((DEBUG_BLKIO, "%a SF: erase %2x %2x %2x %2x (%x)\n", __FUNCTION__, cmd[0], cmd[1], cmd[2], cmd[3], offset)); status = spi_flash_cmd(&flash->spi, CMD_WRITE_ENABLE, NULL, 0); @@ -188,7 +188,7 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S goto out; } - DEBUG((DEBUG_BLKLIO, "%a SF: Successfully erased %u bytes @ %x\n", + DEBUG((DEBUG_BLKIO, "%a SF: Successfully erased %u bytes @ %x\n", __FUNCTION__, len, start)); out: @@ -219,19 +219,19 @@ EFI_STATUS spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT3 chunk_len = spi_crop_chunk(&flash->spi, sizeof(cmd), chunk_len); spi_flash_addr(offset, cmd); - DEBUG((DEBUG_BLKLIO, "%a PP: %x => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %u\n", + DEBUG((DEBUG_BLKIO, "%a PP: %x => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %u\n", __FUNCTION__, buf + actual, cmd[0], cmd[1], cmd[2], cmd[3], chunk_len)); status = spi_flash_cmd(&flash->spi, flash->wren_cmd, NULL, 0); if (EFI_ERROR(status)) { - DEBUG((DEBUG_BLKLIO, "%a SF: Enabling Write failed\n", __FUNCTION__)); + DEBUG((DEBUG_BLKIO, "%a SF: Enabling Write failed\n", __FUNCTION__)); goto out; } status = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), buf + actual, chunk_len); if (EFI_ERROR(status)) { - DEBUG((DEBUG_BLKLIO, "%a SF: Page Program failed\n", __FUNCTION__)); + DEBUG((DEBUG_BLKIO, "%a SF: Page Program failed\n", __FUNCTION__)); goto out; } @@ -412,7 +412,7 @@ STATIC EFI_STATUS spi_flash_generic_probe(CONST struct spi_slave *spi, manuf_id = idcode[0]; - DEBUG((DEBUG_BLKLIO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); + DEBUG((DEBUG_BLKIO, "%a Manufacturer: %02x\n", __FUNCTION__, manuf_id)); id[0] = (idcode[1] << 8) | idcode[2]; id[1] = (idcode[3] << 8) | idcode[4]; @@ -426,7 +426,7 @@ EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) EFI_STATUS status = EFI_DEVICE_ERROR; if (spi_setup_slave(bus, cs, &spi)) { - DEBUG((DEBUG_BLKLIO, "SF: Failed to set up slave\n")); + DEBUG((DEBUG_BLKIO, "SF: Failed to set up slave\n")); return EFI_DEVICE_ERROR; } @@ -440,7 +440,7 @@ EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) /* Give up -- nothing more to try if flash is not found. */ if (EFI_ERROR(status)) { - DEBUG((DEBUG_BLKLIO, "SF: Unsupported manufacturer!\n")); + DEBUG((DEBUG_BLKIO, "SF: Unsupported manufacturer!\n")); return EFI_DEVICE_ERROR; } @@ -448,7 +448,7 @@ EFI_STATUS spi_flash_probe(UINT32 bus, UINT32 cs, struct spi_flash *flash) if (flash->flags.dual_spi && spi.ctrlr->xfer_dual) mode_string = " (Dual SPI mode)"; - DEBUG((DEBUG_BLKLIO, + DEBUG((DEBUG_BLKIO, "SF: Detected %02x %04x with sector size 0x%x, total 0x%x%s\n", flash->vendor, flash->model, flash->sector_size, flash->size, mode_string)); From 7d3ae3dc28ea4d483bef60ca3ea4b89c98745d4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 11:18:31 +0100 Subject: [PATCH 283/297] UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c: fix build issue MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c index 8d1eadcf87d1..06793932a1ed 100644 --- a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c @@ -72,8 +72,6 @@ ValidateFvHeader ( FreePool (FwVolHeader); return EFI_DEVICE_ERROR; } - DEBUG ((EFI_D_INFO, "%a: FwVol header check:\n", __FUNCTION__)); - InternalDumpHex((UINT8 *)FwVolHeader, BufferSize); FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize); From b948002a8030feddf2d5fe0eea6d96a9f3a2ce8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 12:22:30 +0100 Subject: [PATCH 284/297] UefiPayloadPkg: remove obsolete modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 19 +---------- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 49 +-------------------------- 2 files changed, 2 insertions(+), 66 deletions(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 8aa7d89ddd16..4eceef8674bc 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -53,7 +53,7 @@ INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf !if $(TPM_ENABLE) == TRUE INF UefiPayloadPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf -INF SecurityPkg/Tcg/TcgPei/TcgPei.inf +#INF SecurityPkg/Tcg/TcgPei/TcgPei.inf INF SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf !endif @@ -87,8 +87,6 @@ APRIORI DXE { !if $(SECURE_BOOT_ENABLE) == TRUE INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif - # Init Test Driver before Secure Boot - # INF UefiPayloadPkg/TestDriverDxe/TestDriver.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf } @@ -108,11 +106,9 @@ INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf INF MdeModulePkg/Universal/Metronome/Metronome.inf INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf -INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf -INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf @@ -123,9 +119,6 @@ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf -INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf -INF MdeModulePkg/Logo/LogoDxe.inf - !if $(SECURE_BOOT_ENABLE) == TRUE INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif @@ -150,11 +143,9 @@ INF MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf # INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf -INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf !if $(SERIAL_TERMINAL) == TRUE INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf !endif -INF UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf INF UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf # @@ -174,17 +165,10 @@ INF FatPkg/EnhancedFatDxe/Fat.inf # # Usb Support # -INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf -# -# Network Support -# -!include NetworkPkg/Network.fdf.inc - - # # Network modules (only available on X64) # Available at https://downloadcenter.intel.com/download/29137?v=t @@ -260,7 +244,6 @@ INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf !endif !if $(TPM_ENABLE) == TRUE -INF SecurityPkg/Tcg/TcgDxe/TcgDxe.inf INF SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf INF SecurityPkg/Tcg/Tcg2Config/Tcg2ConfigDxe.inf !endif diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 5e4eb16b986d..831e62041933 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -226,21 +226,9 @@ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf VarCheckLib|MdeModulePkg/Library/VarCheckLib/VarCheckLib.inf - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf ShellCEntryLib|ShellPkg/Library/UefiShellCEntryLib/UefiShellCEntryLib.inf - -# -# Network -# -!include NetworkPkg/NetworkLibs.dsc.inc - -!if $(NETWORK_TLS_ENABLE) == TRUE - OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf - TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf -!else OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLibCrypto.inf -!endif !if $(SECURE_BOOT_ENABLE) == TRUE PlatformSecureLib|OvmfPkg/Library/PlatformSecureLib/PlatformSecureLib.inf @@ -255,7 +243,7 @@ Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf - TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf + #TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf !endif [LibraryClasses.IA32.SEC] @@ -459,7 +447,6 @@ !if $(TPM_ENABLE) == TRUE UefiPayloadPkg/Tcg/Tcg2Config/Tcg2ConfigPei.inf - SecurityPkg/Tcg/TcgPei/TcgPei.inf SecurityPkg/Tcg/Tcg2Pei/Tcg2Pei.inf { HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterPei.inf @@ -489,7 +476,6 @@ NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf !endif !if $(TPM_ENABLE) == TRUE - NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf !endif } @@ -500,7 +486,6 @@ UefiCpuPkg/CpuDxe/CpuDxe.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf - MdeModulePkg/Logo/LogoDxe.inf MdeModulePkg/Application/UiApp/UiApp.inf { NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf @@ -512,11 +497,9 @@ MdeModulePkg/Universal/Metronome/Metronome.inf MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf - MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf - MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf @@ -538,20 +521,9 @@ MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf - MdeModulePkg/Universal/Acpi/BootGraphicsResourceTableDxe/BootGraphicsResourceTableDxe.inf UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf - # - # SMBIOS Support - # - MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf - - # - # ACPI Support - # - MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf - # # PCI Support # @@ -577,7 +549,6 @@ # # Usb Support # - MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf @@ -596,11 +567,9 @@ # MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf - MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf !if $(SERIAL_TERMINAL) == TRUE MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf !endif - UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf # @@ -610,18 +579,6 @@ UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif - # - # Network Support - # -!include NetworkPkg/NetworkComponents.dsc.inc - -!if $(NETWORK_TLS_ENABLE) == TRUE - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { - - NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf - } -!endif - !if $(TPM_ENABLE) == TRUE SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { @@ -638,10 +595,6 @@ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf } - SecurityPkg/Tcg/TcgDxe/TcgDxe.inf { - - Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf - } !endif #------------------------------ From 86c3aac5ff186056bfd6b55b9a0132a9a6b9d97d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 13:25:55 +0100 Subject: [PATCH 285/297] UefiPayloadPkg: bring back FaultTolerantWrite MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c | 2 +- UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c | 6 +++--- UefiPayloadPkg/UefiPayloadPkg.fdf | 1 + UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 1 + 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c index c60791b77d11..67612dc1b8c2 100644 --- a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c @@ -176,7 +176,7 @@ BlAmdSpiInitialise ( return EFI_OUT_OF_RESOURCES; } - Status = AmdSpiCreateInstance (4, 0x10000, &mAMDSpiInstance); + Status = AmdSpiCreateInstance (3, 0x10000, &mAMDSpiInstance); if (EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR, "%a: Fail to create instance for AmdSpi\n", __FUNCTION__)); diff --git a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c index 190fd85e9545..67430a2c501a 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c @@ -25,7 +25,7 @@ AmdSpiRead ( { UINTN address = ADDRESS(Lba, Offset); - if (address + *NumBytes > 0xa0000 || address < 0x60000) + if (address + *NumBytes > 0x90000 || address < 0x60000) return EFI_ACCESS_DENIED; if (*NumBytes == 0 || Buffer == NULL) @@ -44,7 +44,7 @@ AmdSpiWrite ( { UINTN address = ADDRESS(Lba, Offset); - if (address + *NumBytes > 0xa0000 || address < 0x60000) + if (address + *NumBytes > 0x90000 || address < 0x60000) return EFI_ACCESS_DENIED; if (*NumBytes == 0 || Buffer == NULL) @@ -68,7 +68,7 @@ AmdSpiEraseBlock ( { UINTN address = ADDRESS(Lba, 0); - if (address > 0xa0000 || address < 0x60000) + if (address > 0x90000 || address < 0x60000) return EFI_ACCESS_DENIED; MicroSecondDelay(5000); diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 4eceef8674bc..a440371e4b4d 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -109,6 +109,7 @@ INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf +INF MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf INF UefiCpuPkg/CpuIo2Dxe/CpuIo2Dxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 831e62041933..aad0ea009a43 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -500,6 +500,7 @@ MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf + MdeModulePkg/Universal/FaultTolerantWriteDxe/FaultTolerantWriteDxe.inf MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf { NULL|MdeModulePkg/Library/VarCheckUefiLib/VarCheckUefiLib.inf From 21f61e356133be2fded5da1723a6ae6b0ed2ecaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 13:50:42 +0100 Subject: [PATCH 286/297] UefiPayloadPkg: bring back common modules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 3 +++ UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index a440371e4b4d..0bb3c6c5090f 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -120,6 +120,8 @@ INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf +INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + !if $(SECURE_BOOT_ENABLE) == TRUE INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif @@ -166,6 +168,7 @@ INF FatPkg/EnhancedFatDxe/Fat.inf # # Usb Support # +INF MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf INF MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf INF MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf INF MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index aad0ea009a43..06df2c654a7e 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -525,6 +525,16 @@ UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf + # + # SMBIOS Support + # + MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf + + # + # ACPI Support + # + MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf + # # PCI Support # @@ -550,6 +560,7 @@ # # Usb Support # + MdeModulePkg/Bus/Pci/EhciDxe/EhciDxe.inf MdeModulePkg/Bus/Pci/XhciDxe/XhciDxe.inf MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf From e2e3d0dbe3f42a03025a7e8aae7f067ab8294962 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Mon, 2 Nov 2020 14:28:35 +0100 Subject: [PATCH 287/297] UefiPayloadPkg: bring back UEFI capsule for DxeCore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 1 + UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 1 + 2 files changed, 2 insertions(+) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 0bb3c6c5090f..21f77526ddf9 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -106,6 +106,7 @@ INF PcAtChipsetPkg/HpetTimerDxe/HpetTimerDxe.inf INF MdeModulePkg/Universal/Metronome/Metronome.inf INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf +INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf INF MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf INF PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 06df2c654a7e..a3e8ab25d747 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -497,6 +497,7 @@ MdeModulePkg/Universal/Metronome/Metronome.inf MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf + MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcatRealTimeClockRuntimeDxe.inf From 87d974838fb684217d3bbbbbf7197f78a190f385 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 4 Nov 2020 15:52:46 +0100 Subject: [PATCH 288/297] UefiPayloadPkg/Library/AmdSpiLib: make AMD SPI more robust MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c | 3 -- UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c | 38 ++++++++----------- UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h | 2 +- .../Library/AmdSpiLib/SPIFlashInternal.c | 3 +- 4 files changed, 18 insertions(+), 28 deletions(-) diff --git a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c index 67430a2c501a..325f5c7e4c37 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c @@ -50,8 +50,6 @@ AmdSpiWrite ( if (*NumBytes == 0 || Buffer == NULL) return EFI_INVALID_PARAMETER; - MicroSecondDelay(5000); - return spi_flash_write(&flash, address, *NumBytes, Buffer); } @@ -71,7 +69,6 @@ AmdSpiEraseBlock ( if (address > 0x90000 || address < 0x60000) return EFI_ACCESS_DENIED; - MicroSecondDelay(5000); return spi_flash_erase(&flash, address, BLOCK_SIZE); } diff --git a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c index 9174f5c90256..7f384a320152 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c @@ -25,6 +25,10 @@ #define SPI_REG_FIFO 0x0c #define SPI_REG_CNTRL11 0x0d #define CNTRL11_FIFOPTR_MASK 0x07 +#define SPI_EXT_REG_INDX 0x1e +#define SPI_EXT_REG_DATA 0x1f +#define SPI_TX_BYTE_COUNT_IDX 0x05 +#define SPI_RX_BYTE_COUNT_IDX 0x06 #define SPI_CMD_CODE 0x45 #define SPI_CMD_TRIGGER 0x47 #define SPI_CMD_TRIGGER_EXECUTE 0x80 @@ -88,17 +92,6 @@ STATIC VOID spi_write8(UINT8 reg, UINT8 val) MmioWrite8((spi_get_bar() + reg), val); } -STATIC VOID reset_internal_fifo_pointer(void) -{ - UINT8 reg8; - - do { - reg8 = spi_read8(SPI_REG_CNTRL02); - reg8 |= CNTRL02_FIFO_RESET; - spi_write8(SPI_REG_CNTRL02, reg8); - } while (spi_read8(SPI_REG_CNTRL11) & CNTRL11_FIFOPTR_MASK); -} - STATIC EFI_STATUS wait_for_ready(VOID) { CONST UINTN timeoutMilisecond = 500; @@ -109,7 +102,8 @@ STATIC EFI_STATUS wait_for_ready(VOID) UINT64 timeNow = startTimeMilisec; do { - if (!(spi_read32(SPI_STATUS) & SPI_BUSY)) + if (!(spi_read8(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) && + !(spi_read8(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY)) return EFI_SUCCESS; timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()),nanoToMiliDivider); } while (timeNowstartTimeMilisec && timeNow>endTimeMilisec)); @@ -193,7 +187,7 @@ STATIC EFI_STATUS execute_command(void) { dump_state(0); - spi_write8(SPI_CMD_TRIGGER, SPI_CMD_TRIGGER_EXECUTE); + spi_write8(SPI_REG_CNTRL02, spi_read8(SPI_REG_CNTRL02) | CNTRL02_EXEC_OPCODE); if (wait_for_ready()) DEBUG((DEBUG_BLKIO, "%a: FCH_SC Error: Timeout executing command\n", __FUNCTION__)); @@ -225,31 +219,29 @@ STATIC EFI_STATUS spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout * and followed by other SPI commands. */ if (bytesout + bytesin > SPI_FIFO_DEPTH) { - DEBUG((DEBUG_BLKIO, - "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); + DEBUG((DEBUG_BLKIO, "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } if (wait_for_ready()) return EFI_DEVICE_ERROR; - spi_write8(SPI_CMD_CODE, cmd); - spi_write8(SPI_TX_BYTE_COUNT, bytesout); - spi_write8(SPI_RX_BYTE_COUNT, bytesin); + spi_write8(SPI_REG_OPCODE, cmd); + + spi_write8(SPI_EXT_REG_INDX, SPI_TX_BYTE_COUNT_IDX); + spi_write8(SPI_EXT_REG_DATA, bytesout); - reset_internal_fifo_pointer(); + spi_write8(SPI_EXT_REG_INDX, SPI_RX_BYTE_COUNT_IDX); + spi_write8(SPI_EXT_REG_DATA, bytesin); for (count = 0; count < bytesout; count++) spi_write8(SPI_FIFO + count, bufout[count]); - reset_internal_fifo_pointer(); if (execute_command()) return EFI_DEVICE_ERROR; - reset_internal_fifo_pointer(); - for (count = 0; count < bytesin; count++) - bufin[count] = spi_read8(SPI_FIFO + count + bytesout); + bufin[count] = spi_read8(SPI_FIFO + (count + bytesout) % SPI_FIFO_DEPTH); return EFI_SUCCESS; } diff --git a/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h index 7d1bb65fa699..cdb03ea3aa99 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h +++ b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h @@ -11,7 +11,7 @@ * of caution in case we're dealing with slower SPI buses and/or processors. */ #define SPI_FLASH_PROG_TIMEOUT_MS 200 -#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 500 +#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 1000 /* SPI vendor IDs */ diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c index 14de8b49fde7..163249620e15 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c @@ -186,6 +186,7 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); if (EFI_ERROR(status)) goto out; + MicroSecondDelay(10000); } DEBUG((DEBUG_BLKIO, "%a SF: Successfully erased %u bytes @ %x\n", @@ -240,7 +241,7 @@ EFI_STATUS spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT3 goto out; offset += chunk_len; - MicroSecondDelay(1000); + MicroSecondDelay(25000); } status = EFI_SUCCESS; From a43c3dab798d57ef9bac8becb8bd4be6d8668c2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 4 Nov 2020 15:53:29 +0100 Subject: [PATCH 289/297] UefiPayloadPkg/UefiPayloadPkgIa32.dsc: use COM2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkgIa32.dsc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index a3e8ab25d747..28d5045f6526 100644 --- a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc +++ b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc @@ -360,7 +360,7 @@ # The following parameters are set by Library/PlatformHookLib # gEfiMdeModulePkgTokenSpaceGuid.PcdSerialUseMmio|FALSE - gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x3f8 + gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterBase|0x2f8 gEfiMdeModulePkgTokenSpaceGuid.PcdSerialBaudRate|$(BAUD_RATE) gEfiMdeModulePkgTokenSpaceGuid.PcdSerialRegisterStride|1 From 6d83bf493d540ed1b274ab97acfdfd4699739683 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 4 Nov 2020 16:04:29 +0100 Subject: [PATCH 290/297] UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c: remove obsolete function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c index 7f384a320152..16219a6f3a3b 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c @@ -82,11 +82,6 @@ STATIC UINT8 spi_read8(UINT8 reg) return MmioRead8((spi_get_bar() + reg)); } -STATIC UINT32 spi_read32(UINT8 reg) -{ - return MmioRead32((spi_get_bar() + reg)); -} - STATIC VOID spi_write8(UINT8 reg, UINT8 val) { MmioWrite8((spi_get_bar() + reg), val); From 0863dd93a671fa5a153d1ffd4020ab9e2af59880 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Wed, 4 Nov 2020 16:10:36 +0100 Subject: [PATCH 291/297] UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c: replace spi_read32 with direct MMIO read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c index 16219a6f3a3b..83466c430607 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c @@ -160,8 +160,8 @@ STATIC VOID dump_state(UINT8 phase) else DEBUG ((DEBUG_BLKIO, "SPI: After execute\n")); - DEBUG ((DEBUG_BLKIO, "Cntrl0: %x\n", spi_read32(SPI_CNTRL0))); - DEBUG ((DEBUG_BLKIO, "Status: %x\n", spi_read32(SPI_STATUS))); + DEBUG ((DEBUG_BLKIO, "Cntrl0: %x\n", MmioRead8(spi_get_bar() + SPI_CNTRL0))); + DEBUG ((DEBUG_BLKIO, "Status: %x\n", MmioRead8(spi_get_bar() + SPI_STATUS))); addr = spi_get_bar() + SPI_FIFO; if (phase == 0) { From fddb69841da0bc792f6d4ee742cbd17fd83d3ea0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 5 Nov 2020 14:25:36 +0100 Subject: [PATCH 292/297] UefiPayloadPkg/Library/AmdSpiLib: fix bugs in the implementation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf | 1 + UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c | 14 ++-- UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c | 64 ++++++------------- UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h | 2 +- .../Library/AmdSpiLib/SPIFlashInternal.c | 39 ++++------- 5 files changed, 38 insertions(+), 82 deletions(-) diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf index e27007c9c314..5a20877a0a30 100644 --- a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf @@ -33,6 +33,7 @@ HobLib AmdSpiLib UefiLib + TimerLib UefiDriverEntryPoint UefiBootServicesTableLib UefiRuntimeLib diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c index 06793932a1ed..9885072968cd 100644 --- a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -234,11 +235,6 @@ InitializeFvAndVariableStoreHeaders ( Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); FreePool (Headers); - if (EFI_ERROR(Status)) - return Status; - - Status = ValidateFvHeader (Instance); - return Status; } @@ -464,7 +460,6 @@ FvbRead ( IN OUT UINT8 *Buffer ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); UINTN BlockSize; AMD_SPI_INSTANCE *Instance; @@ -558,7 +553,7 @@ FvbWrite ( IN UINT8 *Buffer ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + UINTN BlockSize; AMD_SPI_INSTANCE *Instance; @@ -578,7 +573,7 @@ FvbWrite ( return EFI_BAD_BUFFER_SIZE; } - // We must have some bytes to read + // We must have some bytes to write if (*NumBytes == 0) { return EFI_BAD_BUFFER_SIZE; } @@ -636,7 +631,7 @@ FvbEraseBlocks ( ... ) { - DEBUG((EFI_D_INFO, "%a\n", __FUNCTION__)); + EFI_STATUS Status; VA_LIST Args; EFI_LBA StartingLba; // Lba from which we start erasing @@ -792,6 +787,7 @@ AmdSpiFvbInitialize ( // Install all appropriate headers Status = InitializeFvAndVariableStoreHeaders (Instance); if (EFI_ERROR(Status)) { + DEBUG((DEBUG_INFO, "%a: FVB header init failed\n", __FUNCTION__)); return Status; } } else { diff --git a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c index 83466c430607..257afc2416e6 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c @@ -53,7 +53,7 @@ #define SPI_BASE_ALIGNMENT 0x00000040 #define ALIGN_DOWN(x,a) ((x) & ~((typeof(x))(a)-1UL)) -static UINTN spi_base = 0; +STATIC UINTN spi_base = 0; STATIC UINTN lpc_get_spibase(VOID) { @@ -87,30 +87,6 @@ STATIC VOID spi_write8(UINT8 reg, UINT8 val) MmioWrite8((spi_get_bar() + reg), val); } -STATIC EFI_STATUS wait_for_ready(VOID) -{ - CONST UINTN timeoutMilisecond = 500; - CONST UINT32 nanoToMiliDivider = 1000000; - CONST UINT64 startTimeMilisec = - DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); - CONST UINT64 endTimeMilisec = startTimeMilisec + timeoutMilisecond; - UINT64 timeNow = startTimeMilisec; - - do { - if (!(spi_read8(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) && - !(spi_read8(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY)) - return EFI_SUCCESS; - timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()),nanoToMiliDivider); - } while (timeNowstartTimeMilisec && timeNow>endTimeMilisec)); - - return EFI_DEVICE_ERROR; -} - -VOID spi_init(VOID) -{ - spi_get_bar(); -} - STATIC VOID InternalDumpData ( IN UINT8 *Data, @@ -150,6 +126,11 @@ InternalDumpHex ( } } +VOID spi_init(VOID) +{ + spi_get_bar(); +} + STATIC VOID dump_state(UINT8 phase) { UINT8 dump_size; @@ -160,17 +141,17 @@ STATIC VOID dump_state(UINT8 phase) else DEBUG ((DEBUG_BLKIO, "SPI: After execute\n")); - DEBUG ((DEBUG_BLKIO, "Cntrl0: %x\n", MmioRead8(spi_get_bar() + SPI_CNTRL0))); - DEBUG ((DEBUG_BLKIO, "Status: %x\n", MmioRead8(spi_get_bar() + SPI_STATUS))); + DEBUG ((DEBUG_BLKIO, "Cntrl0: %08x\n", MmioRead32(spi_get_bar() + SPI_CNTRL0))); + DEBUG ((DEBUG_BLKIO, "Status: %08x\n", MmioRead32(spi_get_bar() + SPI_STATUS))); addr = spi_get_bar() + SPI_FIFO; if (phase == 0) { dump_size = spi_read8(SPI_TX_BYTE_COUNT); - DEBUG ((DEBUG_BLKIO, "TxByteCount: %x\n", dump_size)); - DEBUG ((DEBUG_BLKIO, "CmdCode: %x\n", spi_read8(SPI_CMD_CODE))); + DEBUG ((DEBUG_BLKIO, "TxByteCount: %02x\n", dump_size)); + DEBUG ((DEBUG_BLKIO, "CmdCode: %02x\n", spi_read8(SPI_CMD_CODE))); } else { dump_size = spi_read8(SPI_RX_BYTE_COUNT); - DEBUG ((DEBUG_BLKIO, "RxByteCount: %x\n", dump_size)); + DEBUG ((DEBUG_BLKIO, "RxByteCount: %02x\n", dump_size)); addr += spi_read8(SPI_TX_BYTE_COUNT); } @@ -184,8 +165,8 @@ STATIC EFI_STATUS execute_command(void) spi_write8(SPI_REG_CNTRL02, spi_read8(SPI_REG_CNTRL02) | CNTRL02_EXEC_OPCODE); - if (wait_for_ready()) - DEBUG((DEBUG_BLKIO, "%a: FCH_SC Error: Timeout executing command\n", __FUNCTION__)); + while ((spi_read8(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) || + (spi_read8(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY)); dump_state(1); @@ -200,7 +181,7 @@ STATIC EFI_STATUS spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout UINT8 *bufin = din; CONST UINT8 *bufout = dout; - DEBUG((DEBUG_BLKIO, "%s(%x, %x)\n", __FUNCTION__, bytesout, bytesin)); + DEBUG((DEBUG_BLKIO, "%a(%x, %x)\n", __FUNCTION__, bytesout, bytesin)); /* First byte is cmd which cannot be sent through FIFO */ cmd = bufout[0]; @@ -214,26 +195,19 @@ STATIC EFI_STATUS spi_ctrlr_xfer(CONST struct spi_slave *slave, CONST VOID *dout * and followed by other SPI commands. */ if (bytesout + bytesin > SPI_FIFO_DEPTH) { - DEBUG((DEBUG_BLKIO, "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); + DEBUG((EFI_D_ERROR, "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } - if (wait_for_ready()) - return EFI_DEVICE_ERROR; - - spi_write8(SPI_REG_OPCODE, cmd); + spi_write8(SPI_CMD_CODE, cmd); - spi_write8(SPI_EXT_REG_INDX, SPI_TX_BYTE_COUNT_IDX); - spi_write8(SPI_EXT_REG_DATA, bytesout); - - spi_write8(SPI_EXT_REG_INDX, SPI_RX_BYTE_COUNT_IDX); - spi_write8(SPI_EXT_REG_DATA, bytesin); + spi_write8(SPI_TX_BYTE_COUNT, bytesout); + spi_write8(SPI_RX_BYTE_COUNT, bytesin); for (count = 0; count < bytesout; count++) spi_write8(SPI_FIFO + count, bufout[count]); - if (execute_command()) - return EFI_DEVICE_ERROR; + execute_command(); for (count = 0; count < bytesin; count++) bufin[count] = spi_read8(SPI_FIFO + (count + bytesout) % SPI_FIFO_DEPTH); diff --git a/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h index cdb03ea3aa99..7969f6b90f33 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h +++ b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h @@ -11,7 +11,7 @@ * of caution in case we're dealing with slower SPI buses and/or processors. */ #define SPI_FLASH_PROG_TIMEOUT_MS 200 -#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 1000 +#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 2000 /* SPI vendor IDs */ diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c index 163249620e15..22dca86e7b28 100644 --- a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c @@ -86,22 +86,18 @@ EFI_STATUS spi_flash_cmd_read(CONST struct spi_flash *flash, UINT32 offset, { UINT8 cmd[5]; EFI_STATUS status; - int cmd_len; - EFI_STATUS (*do_cmd)(CONST struct spi_slave *spi, CONST VOID *din, - __SIZE_TYPE__ in_bytes, VOID *out, __SIZE_TYPE__ out_bytes); + UINT8 cmd_len; cmd_len = 4; cmd[0] = CMD_READ_ARRAY_SLOW; - do_cmd = do_spi_flash_cmd; UINT8 *data = buf; while (len) { __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); spi_flash_addr(offset, cmd); - status = do_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); + status = do_spi_flash_cmd(&flash->spi, cmd, cmd_len, data, xfer_len); if (EFI_ERROR(status)) { - DEBUG((DEBUG_BLKIO, - "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", + DEBUG((DEBUG_BLKIO, "%a SF: Failed to send read command %#.2x(%#x, %#zx): %d\n", __FUNCTION__, cmd[0], offset, xfer_len, status)); return status; } @@ -117,27 +113,18 @@ EFI_STATUS spi_flash_cmd_poll_bit(CONST struct spi_flash *flash, unsigned long t UINT8 cmd, UINT8 poll_bit) { CONST struct spi_slave *spi = &flash->spi; - EFI_STATUS status; - - CONST UINT32 nanoToMiliDivider = 1000000; - CONST UINT32 startTimeMilisec = - DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); - CONST UINT32 endTimeMilisec = startTimeMilisec + timeout; - UINT32 timeNow = startTimeMilisec; + EFI_STATUS status = EFI_SUCCESS; + UINT8 spi_sr; - do { - status = do_spi_flash_cmd(spi, &cmd, 1, &status, 1); - if (EFI_ERROR(status)) - return EFI_DEVICE_ERROR; - if ((status & poll_bit) == 0) + while (!EFI_ERROR(status)) { + status = do_spi_flash_cmd(spi, &cmd, 1, &spi_sr, 1); + if ((spi_sr & poll_bit) == 0) return EFI_SUCCESS; - timeNow = DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter()), nanoToMiliDivider); - } while ( - timeNowstartTimeMilisec && timeNow>endTimeMilisec)); - DEBUG((DEBUG_BLKIO, "%a SF: timeout at %ld msec\n", __FUNCTION__, timeout)); - return EFI_DEVICE_ERROR; + MicroSecondDelay(10); + } while (TRUE); + + return status; } EFI_STATUS spi_flash_cmd_wait_ready(CONST struct spi_flash *flash, @@ -186,7 +173,6 @@ EFI_STATUS spi_flash_cmd_erase(CONST struct spi_flash *flash, UINT32 offset, __S SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); if (EFI_ERROR(status)) goto out; - MicroSecondDelay(10000); } DEBUG((DEBUG_BLKIO, "%a SF: Successfully erased %u bytes @ %x\n", @@ -241,7 +227,6 @@ EFI_STATUS spi_flash_cmd_write_page_program(CONST struct spi_flash *flash, UINT3 goto out; offset += chunk_len; - MicroSecondDelay(25000); } status = EFI_SUCCESS; From 13e240a1f3818a51cd2af833491f28691f7128fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 5 Nov 2020 14:25:55 +0100 Subject: [PATCH 293/297] UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c: add debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c index 7b6cc4d7668d..ab9f8c7cdafc 100644 --- a/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c +++ b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c @@ -203,7 +203,7 @@ EnrollListOfCerts ( UINT8 *Position; Status = EFI_SUCCESS; - + DEBUG ((DEBUG_INFO, "%a: enrolling for %a\n", __FUNCTION__, VariableName)); // // compute total size first, for UINT32 range check, and allocation // @@ -503,6 +503,8 @@ InstallSecureBootHook ( MicrosoftDbxSize, MicrosoftDbx); ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "SecureBootSetup: enrolling certs.\n")); + Status = EnrollListOfCerts ( EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, @@ -552,6 +554,7 @@ InstallSecureBootHook ( Status = gRT->SetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof Settings.SecureBootEnable, &Settings.SecureBootEnable); + if (EFI_ERROR (Status)) { DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, Status)); From d6c0b602364d0596ba1f1c5666d2892066a878ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 5 Nov 2020 20:18:55 +0100 Subject: [PATCH 294/297] PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe: add debug MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../PcatRealTimeClockRuntimeDxe/PcRtc.c | 20 ++++++++++++++++++- .../PcatRealTimeClockRuntimeDxe/PcRtcEntry.c | 7 ++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c index 8d52bb1fdacf..55c181b7e757 100644 --- a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c +++ b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtc.c @@ -112,6 +112,7 @@ PcRtcInit ( BOOLEAN Enabled; BOOLEAN Pending; + DEBUG((DEBUG_INFO, "%a\n", __FUNCTION__)); // // Acquire RTC Lock to make access to RTC atomic // @@ -148,6 +149,7 @@ PcRtcInit ( // Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout)); if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a: RTC not functional\n", __FUNCTION__)); // // Set the variable with default value if the RTC is functioning incorrectly. // @@ -233,6 +235,7 @@ PcRtcInit ( // Status = PcRtcSetTime (&Time, Global); if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a: failed to set RTC time\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } @@ -272,8 +275,9 @@ PcRtcInit ( Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout)); if (EFI_ERROR (Status)) { if (!EfiAtRuntime ()) { - EfiReleaseLock (&Global->RtcLock); + EfiReleaseLock (&Global->RtcLock); } + DEBUG((DEBUG_INFO, "%a: faield to update RTC\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } @@ -293,6 +297,7 @@ PcRtcInit ( if (!EfiAtRuntime ()) { EfiReleaseLock (&Global->RtcLock); } + DEBUG((DEBUG_INFO, "%a: failed to set variable RTCALARM\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } @@ -366,6 +371,7 @@ PcRtcGetTime ( // Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout)); if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a RTC did not update\n", __FUNCTION__)); if (!EfiAtRuntime ()) { EfiReleaseLock (&Global->RtcLock); } @@ -407,6 +413,7 @@ PcRtcGetTime ( Status = RtcTimeFieldsValid (Time); } if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a time fields invalid after convert to EFI\n", __FUNCTION__)); return EFI_DEVICE_ERROR; } @@ -458,6 +465,7 @@ PcRtcSetTime ( // Status = RtcTimeFieldsValid (Time); if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a time fields invalid\n", __FUNCTION__)); return Status; } @@ -474,6 +482,7 @@ PcRtcSetTime ( // Status = RtcWaitToUpdate (PcdGet32 (PcdRealTimeClockUpdateTimeout)); if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a RTC did not update\n", __FUNCTION__)); if (!EfiAtRuntime ()) { EfiReleaseLock (&Global->RtcLock); } @@ -507,6 +516,7 @@ PcRtcSetTime ( } if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "%a failed to set variables\n", __FUNCTION__)); if (!EfiAtRuntime ()) { EfiReleaseLock (&Global->RtcLock); } @@ -988,6 +998,14 @@ RtcTimeFieldsValid ( Time->Nanosecond > 999999999 || (!(Time->TimeZone == EFI_UNSPECIFIED_TIMEZONE || (Time->TimeZone >= -1440 && Time->TimeZone <= 1440))) || ((Time->Daylight & (~(EFI_TIME_ADJUST_DAYLIGHT | EFI_TIME_IN_DAYLIGHT))) != 0)) { + DEBUG ((DEBUG_INFO, "Year: %04x\n", Time->Year)); + DEBUG ((DEBUG_INFO, "Month: %02x\n", Time->Month)); + DEBUG ((DEBUG_INFO, "Hour: %02x\n", Time->Hour)); + DEBUG ((DEBUG_INFO, "Minute: %02x\n", Time->Minute)); + DEBUG ((DEBUG_INFO, "Second: %02x\n", Time->Second)); + DEBUG ((DEBUG_INFO, "Nanosecond: %08x\n", Time->Nanosecond)); + DEBUG ((DEBUG_INFO, "TimeZone: %d\n", Time->TimeZone)); + DEBUG ((DEBUG_INFO, "Daylight: %02x\n", Time->Daylight)); return EFI_INVALID_PARAMETER; } diff --git a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c index ccda6331373b..aaee51b635c5 100644 --- a/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c +++ b/PcAtChipsetPkg/PcatRealTimeClockRuntimeDxe/PcRtcEntry.c @@ -128,12 +128,15 @@ InitializePcRtc ( EFI_STATUS Status; EFI_EVENT Event; + DEBUG((DEBUG_INFO, "%a\n", __FUNCTION__)); + EfiInitializeLock (&mModuleGlobal.RtcLock, TPL_CALLBACK); mModuleGlobal.CenturyRtcAddress = GetCenturyRtcAddress (); Status = PcRtcInit (&mModuleGlobal); ASSERT_EFI_ERROR (Status); + DEBUG((DEBUG_INFO, "%a: CreateEventEx1\n", __FUNCTION__)); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, @@ -144,6 +147,7 @@ InitializePcRtc ( ); ASSERT_EFI_ERROR (Status); + DEBUG((DEBUG_INFO, "%a: CreateEventEx2\n", __FUNCTION__)); Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, @@ -158,7 +162,8 @@ InitializePcRtc ( gRT->SetTime = PcRtcEfiSetTime; gRT->GetWakeupTime = PcRtcEfiGetWakeupTime; gRT->SetWakeupTime = PcRtcEfiSetWakeupTime; - + + DEBUG((DEBUG_INFO, "%a: Install protocol interfaces\n", __FUNCTION__)); Status = gBS->InstallMultipleProtocolInterfaces ( &mHandle, &gEfiRealTimeClockArchProtocolGuid, From 74aa375db316986c44bf71b3e1d09f674cc1632c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 5 Nov 2020 20:19:39 +0100 Subject: [PATCH 295/297] UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup: let AuthService enable Secure Boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- .../SecureBootSetup.c | 29 ------------------- .../SecureBootSetup.inf | 1 + 2 files changed, 1 insertion(+), 29 deletions(-) diff --git a/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c index ab9f8c7cdafc..b8ee57325878 100644 --- a/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c +++ b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c @@ -461,11 +461,6 @@ InstallSecureBootHook ( return; } - if(Settings.SecureBootEnable != SECURE_BOOT_MODE_ENABLE) { - DEBUG ((EFI_D_ERROR, "SecureBootSetup: SecureBootEnable is disabled.\n")); - return; - } - PrintSettings (&Settings); if (Settings.CustomMode != CUSTOM_SECURE_BOOT_MODE) { @@ -547,30 +542,6 @@ InstallSecureBootHook ( ASSERT_EFI_ERROR (Status); } - // FIXME: Force SecureBoot to ON. The AuthService will do this if authenticated variables - // are supported, which aren't as the SMM handler isn't able to verify them. - - Settings.SecureBootEnable = SECURE_BOOT_ENABLE; - Status = gRT->SetVariable (EFI_SECURE_BOOT_ENABLE_NAME, &gEfiSecureBootEnableDisableGuid, - EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS, - sizeof Settings.SecureBootEnable, &Settings.SecureBootEnable); - - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_SECURE_BOOT_ENABLE_NAME, - &gEfiSecureBootEnableDisableGuid, Status)); - ASSERT_EFI_ERROR (Status); - } - - Settings.SecureBoot = SECURE_BOOT_ENABLE; - Status = gRT->SetVariable (EFI_SECURE_BOOT_MODE_NAME, &gEfiGlobalVariableGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof Settings.SecureBoot, &Settings.SecureBoot); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "SecureBootSetup: SetVariable(\"%s\", %g): %r\n", EFI_SECURE_BOOT_MODE_NAME, - &gEfiGlobalVariableGuid, Status)); - ASSERT_EFI_ERROR (Status); - } - Status = GetSettings (&Settings, FALSE); ASSERT_EFI_ERROR (Status); diff --git a/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf index 153830f74363..a7b8e14a062c 100644 --- a/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf +++ b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf @@ -34,6 +34,7 @@ gEfiCertX509Guid gEfiCustomModeEnableGuid gEfiGlobalVariableGuid + gEfiVendorKeysNvGuid gEfiImageSecurityDatabaseGuid gEfiSecureBootEnableDisableGuid From a019ca18e0a5d54fcc4d7e8f837e6ff34a84ca6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 5 Nov 2020 20:20:04 +0100 Subject: [PATCH 296/297] UefiPayloadPkg/UefiPayloadPkg.fdf: remove obsolete space MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/UefiPayloadPkg.fdf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/UefiPayloadPkg.fdf b/UefiPayloadPkg/UefiPayloadPkg.fdf index 21f77526ddf9..e7573acfe821 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -87,7 +87,7 @@ APRIORI DXE { !if $(SECURE_BOOT_ENABLE) == TRUE INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif - INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf + INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf } # From 95c1d9f3ca8965ffc8994ccd33c655eb05af363b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=C5=BBygowski?= Date: Thu, 5 Nov 2020 20:20:19 +0100 Subject: [PATCH 297/297] UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c: change to AuthFormat MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Michał Żygowski --- UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c index 9885072968cd..be9ffacce6d9 100644 --- a/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c @@ -226,7 +226,7 @@ InitializeFvAndVariableStoreHeaders ( // VARIABLE_STORE_HEADER // VariableStoreHeader = (VARIABLE_STORE_HEADER*)((UINTN)Headers + FirmwareVolumeHeader->HeaderLength); - CopyGuid (&VariableStoreHeader->Signature, &gEfiVariableGuid); + CopyGuid (&VariableStoreHeader->Signature, &gEfiAuthenticatedVariableGuid); VariableStoreHeader->Size = PcdGet32(PcdFlashNvStorageVariableSize) - FirmwareVolumeHeader->HeaderLength; VariableStoreHeader->Format = VARIABLE_STORE_FORMATTED; VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;