diff --git a/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c b/MdeModulePkg/Universal/Variable/RuntimeDxe/VariableNonVolatile.c index 0637a828b33f..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 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/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, diff --git a/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.c new file mode 100644 index 000000000000..67612dc1b8c2 --- /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 (3, 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..5a20877a0a30 --- /dev/null +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf @@ -0,0 +1,65 @@ +#/** @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 + TimerLib + 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..be9ffacce6d9 --- /dev/null +++ b/UefiPayloadPkg/AmdSpiDxe/AmdSpiFvbDxe.c @@ -0,0 +1,823 @@ +/*++ @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 + +#include "AmdSpiDxe.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. +/// + +/** + 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; + } + + 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; + } + + // 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; + } + + // 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; +} + +/** + 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, &gEfiAuthenticatedVariableGuid); + 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; +} + +/** + 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 + ) +{ + 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 + ) +{ + + 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 write + 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, + ... + ) +{ + + 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)) { + DEBUG((DEBUG_INFO, "%a: FVB header init failed\n", __FUNCTION__)); + 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/BlSMMStoreDxe/BlSMMStoreDxe.c b/UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.c index 52b133670a35..b32c2bc4faf4 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); @@ -219,12 +220,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/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/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; 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.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/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/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/Include/Library/BlParseLib.h b/UefiPayloadPkg/Include/Library/BlParseLib.h index 542c714c555b..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__ @@ -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/AmdSpiLib/Adesto.c b/UefiPayloadPkg/Library/AmdSpiLib/Adesto.c new file mode 100644 index 000000000000..1711fe33e6c3 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/Adesto.c @@ -0,0 +1,94 @@ +/* + * Driver for Adesto Technologies SPI flash + * based on Winbond.c + */ + + +#include "SPIFlashInternal.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/Library/AmdSpiLib/AmdSpiLib.c b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c new file mode 100644 index 000000000000..325f5c7e4c37 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.c @@ -0,0 +1,83 @@ +#include +#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 > 0x90000 || 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 > 0x90000 || 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 > 0x90000 || 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..257afc2416e6 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/FchSPICtrl.c @@ -0,0 +1,239 @@ +#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_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 +#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 VOID spi_write8(UINT8 reg, UINT8 val) +{ + MmioWrite8((spi_get_bar() + reg), val); +} + +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")); + } +} + +VOID spi_init(VOID) +{ + spi_get_bar(); +} + +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: %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: %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: %02x\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_REG_CNTRL02, spi_read8(SPI_REG_CNTRL02) | CNTRL02_EXEC_OPCODE); + + while ((spi_read8(SPI_REG_CNTRL02) & CNTRL02_EXEC_OPCODE) || + (spi_read8(SPI_REG_CNTRL03) & CNTRL03_SPIBUSY)); + + 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, "%a(%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((EFI_D_ERROR, "%a: FCH_SC: Too much to transfer, code error!\n", __FUNCTION__)); + return EFI_DEVICE_ERROR; + } + + 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]); + + execute_command(); + + for (count = 0; count < bytesin; count++) + bufin[count] = spi_read8(SPI_FIFO + (count + bytesout) % SPI_FIFO_DEPTH); + + 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/Library/AmdSpiLib/GenericSPI.c b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.c new file mode 100644 index 000000000000..66f9bfbde983 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.c @@ -0,0 +1,129 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include "GenericSPI.h" + +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 EFI_SUCCESS; +} + +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 EFI_STATUS spi_xfer_single_op(CONST struct spi_slave *slave, + struct spi_op *op) +{ + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; + EFI_STATUS status; + + if (!ctrlr || !ctrlr->xfer) + return EFI_DEVICE_ERROR; + + 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 status; +} + +STATIC EFI_STATUS spi_xfer_vector_default(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count) +{ + __SIZE_TYPE__ i; + EFI_STATUS status; + + for (i = 0; i < count; i++) { + status = spi_xfer_single_op(slave, &vectors[i]); + if (status) + return status; + } + + return EFI_SUCCESS; +} + +EFI_STATUS spi_xfer_vector(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ 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); +} + +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; + + if (ctrlr && ctrlr->xfer) { + return ctrlr->xfer(slave, dout, bytesout, din, bytesin); + } + + return EFI_DEVICE_ERROR; +} + +UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, + UINT32 buf_len) +{ + CONST struct spi_ctrlr *ctrlr = slave->ctrlr; + UINT32 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; + + /* 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); +} + +EFI_STATUS spi_setup_slave(UINT32 bus, UINT32 cs, struct spi_slave *slave) +{ + __SIZE_TYPE__ i; + + InternalMemZeroMem(slave, 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 EFI_DEVICE_ERROR; + + slave->bus = bus; + slave->cs = cs; + + if (slave->ctrlr->setup) + return slave->ctrlr->setup(slave); + + return EFI_SUCCESS; +} diff --git a/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h new file mode 100644 index 000000000000..7969f6b90f33 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/GenericSPI.h @@ -0,0 +1,331 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#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. + */ +#define SPI_FLASH_PROG_TIMEOUT_MS 200 +#define SPI_FLASH_PAGE_ERASE_TIMEOUT_MS 2000 + + +/* 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; + +struct region { + __SIZE_TYPE__ offset; + __SIZE_TYPE__ size; +}; + +/*----------------------------------------------------------------------- + * 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_TYPE__ bytesout; + VOID *din; + __SIZE_TYPE__ 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 { + 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_part_id *part; +}; + +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 { + EFI_STATUS (*claim_bus)(const struct spi_slave *slave); + VOID (*release_bus)(const struct spi_slave *slave); + 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); + EFI_STATUS (*xfer_vector)(const struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ count); + 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; + EFI_STATUS (*flash_probe)(const struct spi_slave *slave, + struct spi_flash *flash); +}; + +/*----------------------------------------------------------------------- + * 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; + UINT32 bus_start; + UINT32 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_TYPE__ spi_ctrlr_bus_map_count; + +/*----------------------------------------------------------------------- + * Initialization, must be called once on start up. + * + */ +__attribute__((__weak__)) +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 + */ +EFI_STATUS 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 + */ +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. + * + * 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. + */ +EFI_STATUS 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 + */ +EFI_STATUS spi_xfer(CONST struct spi_slave *slave, const VOID *dout, __SIZE_TYPE__ bytesout, + VOID *din, __SIZE_TYPE__ 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 + */ +EFI_STATUS spi_xfer_vector(CONST struct spi_slave *slave, + struct spi_op vectors[], __SIZE_TYPE__ 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. + */ +UINT32 spi_crop_chunk(CONST struct spi_slave *slave, UINT32 cmd_len, + UINT32 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 INT32 spi_w8r8(CONST struct spi_slave *slave, unsigned char byte) +{ + unsigned char dout[2]; + unsigned char din[2]; + UINT32 ret; + + dout[0] = byte; + dout[1] = 0; + + ret = (INT32)spi_xfer(slave, dout, 2, din, 2); + return ret < 0 ? ret : din[1]; +} + +#endif /* _SPI_GENERIC_H_ */ diff --git a/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c new file mode 100644 index 000000000000..22dca86e7b28 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/SPIFlashInternal.c @@ -0,0 +1,468 @@ +/* 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 (EFI_ERROR(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 (EFI_ERROR(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 (EFI_ERROR(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; + UINT8 cmd_len; + + cmd_len = 4; + cmd[0] = CMD_READ_ARRAY_SLOW; + + UINT8 *data = buf; + while (len) { + __SIZE_TYPE__ xfer_len = spi_crop_chunk(&flash->spi, cmd_len, len); + spi_flash_addr(offset, cmd); + 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", + __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 = EFI_SUCCESS; + UINT8 spi_sr; + + while (!EFI_ERROR(status)) { + status = do_spi_flash_cmd(spi, &cmd, 1, &spi_sr, 1); + if ((spi_sr & poll_bit) == 0) + return EFI_SUCCESS; + + MicroSecondDelay(10); + } while (TRUE); + + return status; +} + +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 (EFI_ERROR(status)) + goto out; + + status = spi_flash_cmd_write(&flash->spi, cmd, sizeof(cmd), NULL, 0); + if (EFI_ERROR(status)) + goto out; + + status = spi_flash_cmd_wait_ready(flash, + SPI_FLASH_PAGE_ERASE_TIMEOUT_MS); + if (EFI_ERROR(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: %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_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_BLKIO, "%a SF: Page Program failed\n", __FUNCTION__)); + goto out; + } + + status = spi_flash_cmd_wait_ready(flash, SPI_FLASH_PROG_TIMEOUT_MS); + if (EFI_ERROR(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 (EFI_ERROR(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 (EFI_ERROR(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 (EFI_ERROR(status)) + status = spi_flash_generic_probe(&spi, flash); + + /* Give up -- nothing more to try if flash is not found. */ + if (EFI_ERROR(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/Library/AmdSpiLib/Winbond.h b/UefiPayloadPkg/Library/AmdSpiLib/Winbond.h new file mode 100644 index 000000000000..8ab1dc4122d9 --- /dev/null +++ b/UefiPayloadPkg/Library/AmdSpiLib/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/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/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) { diff --git a/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c b/UefiPayloadPkg/Library/PlatformBootManagerLib/PlatformBootManager.c index 9d7bcb35f2c4..e72389a8c602 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; } @@ -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); @@ -553,14 +553,14 @@ 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"Pess ESC to enter Boot Manager Menu.\n"); + Print (L"Press F9 to enter Boot Manager Menu.\n"); } /** 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/SecureBootEnrollDefaultKeys/SecureBootSetup.c b/UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.c index 7b6cc4d7668d..b8ee57325878 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 // @@ -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) { @@ -503,6 +498,8 @@ InstallSecureBootHook ( MicrosoftDbxSize, MicrosoftDbx); ASSERT_EFI_ERROR (Status); + DEBUG ((DEBUG_INFO, "SecureBootSetup: enrolling certs.\n")); + Status = EnrollListOfCerts ( EFI_IMAGE_SECURITY_DATABASE, &gEfiImageSecurityDatabaseGuid, @@ -545,29 +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 diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec index 2613daa52474..f6b35b0eab5e 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dec +++ b/UefiPayloadPkg/UefiPayloadPkg.dec @@ -30,11 +30,11 @@ # 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 } } - gEfiSMMSTOREInfoHobGuid = { 0xf585ca19, 0x881b, 0x44fb, { 0x3f, 0x3d, 0x81, 0x89, 0x7c, 0x57, 0xbb, 0x01 }} + 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}} + 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 52e72faedce6..e7573acfe821 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.fdf +++ b/UefiPayloadPkg/UefiPayloadPkg.fdf @@ -10,16 +10,16 @@ ################################################################################ [FD.UefiPayload] -BaseAddress = 0x800000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase -Size = 0x800000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize +BaseAddress = 0x440000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemBase +Size = 0x440000|gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize ErasePolarity = 1 BlockSize = 0x1000 -NumBlocks = 0x800 +NumBlocks = 0x440 0x00000000|0x040000 FV = PEIFV -0x00040000|0x7C0000 +0x00040000|0x400000 FV = DXEFV ################################################################################ @@ -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 @@ -83,14 +83,11 @@ 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 - INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf +!if $(SECURE_BOOT_ENABLE) == TRUE + INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf +!endif + INF MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf } # @@ -125,9 +122,9 @@ INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf INF UefiPayloadPkg/BlSupportDxe/BlSupportDxe.inf INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf -INF MdeModulePkg/Logo/LogoDxe.inf -!if $(BOOTLOADER) == "COREBOOT" -INF UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf + +!if $(SECURE_BOOT_ENABLE) == TRUE + INF UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif # @@ -150,11 +147,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 # @@ -166,50 +161,19 @@ 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 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 -# -# Network Support -# -!include NetworkPkg/Network.fdf.inc - - # # Network modules (only available on X64) # Available at https://downloadcenter.intel.com/download/29137?v=t @@ -244,17 +208,12 @@ 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 } !endif -# -# Random Number Generator -# -INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf - # # Security # @@ -290,7 +249,6 @@ INF SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.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 @@ -325,7 +283,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 diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32.dsc index 988a59f576b7..28d5045f6526 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: @@ -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 @@ -224,41 +226,24 @@ 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 AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf + AmdSpiLib|UefiPayloadPkg/Library/AmdSpiLib/AmdSpiLib.inf !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 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] @@ -298,7 +283,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 @@ -312,7 +296,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 @@ -377,7 +360,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 @@ -438,6 +421,7 @@ # ################################################################################ [Components.IA32] + # # SEC Core # @@ -463,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 @@ -493,18 +476,16 @@ NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf !endif !if $(TPM_ENABLE) == TRUE - NULL|SecurityPkg/Library/DxeTpmMeasureBootLib/DxeTpmMeasureBootLib.inf NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf !endif } !if $(SECURE_BOOT_ENABLE) == TRUE SecurityPkg/VariableAuthenticated/SecureBootConfigDxe/SecureBootConfigDxe.inf - OvmfPkg/EnrollDefaultKeys/EnrollDefaultKeys.inf + UefiPayloadPkg/SecureBootEnrollDefaultKeys/SecureBootSetup.inf !endif UefiCpuPkg/CpuDxe/CpuDxe.inf MdeModulePkg/Universal/BdsDxe/BdsDxe.inf - MdeModulePkg/Logo/LogoDxe.inf MdeModulePkg/Application/UiApp/UiApp.inf { NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf @@ -542,7 +523,6 @@ 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 @@ -575,25 +555,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 # @@ -605,50 +575,23 @@ MdeModulePkg/Bus/Isa/Ps2KeyboardDxe/Ps2KeyboardDxe.inf !endif - # - # SMBUS Support - # - UefiPayloadPkg/SmbusDxe/SMBusi801Dxe.inf - UefiPayloadPkg/SmbusConfigLoaderDxe/SMBusConfigLoader.inf - # # Console Support # 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 - # SMMSTORE - # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif - # - # Network Support + # AMD SPI # -!include NetworkPkg/NetworkComponents.dsc.inc - -!if $(NETWORK_TLS_ENABLE) == TRUE - NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf { - - NULL|OvmfPkg/Library/TlsAuthConfigLib/TlsAuthConfigLib.inf - } +!if $(SECURE_BOOT_ENABLE) == TRUE + UefiPayloadPkg/AmdSpiDxe/AmdSpiDxe.inf !endif - # - # Random Number Generator - # - SecurityPkg/RandomNumberGenerator/RngDxe/RngDxe.inf { - - RngLib|UefiPayloadPkg/Library/BaseRngLib/BaseRngLib.inf - } - !if $(TPM_ENABLE) == TRUE SecurityPkg/Tcg/Tcg2Dxe/Tcg2Dxe.inf { @@ -665,10 +608,6 @@ Tpm2DeviceLib|SecurityPkg/Library/Tpm2DeviceLibRouter/Tpm2DeviceLibRouterDxe.inf } - SecurityPkg/Tcg/TcgDxe/TcgDxe.inf { - - Tpm12DeviceLib|SecurityPkg/Library/Tpm12DeviceLibDTpm/Tpm12DeviceLibDTpm.inf - } !endif #------------------------------ diff --git a/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc b/UefiPayloadPkg/UefiPayloadPkgIa32X64.dsc index 4c5bf2613e49..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 @@ -487,6 +482,7 @@ !endif [Components.X64] + UefiPayloadPkg/SPI/SPI.inf # # DXE Core # @@ -629,13 +625,6 @@ UefiPayloadPkg/GraphicsOutputDxe/GraphicsOutputDxe.inf UefiPayloadPkg/PciPlatformDxe/PciPlatformDxe.inf - # - # SMMSTORE - # -!if $(BOOTLOADER) == "COREBOOT" - UefiPayloadPkg/BlSMMStoreDxe/BlSMMStoreDxe.inf -!endif - # # Network Support #