From: Duke Zhai <duke.z...@amd.com> BZ #:4640 In V3: Improve coding style follow edk2 C coding standard. 1.Remove macro definition extra underscores. 2.Putting some AMD copyright in the right place.
In V2: Improve coding style. 1.Remove the leading underscore and use double underscore at trailing in C header files. 2.Remove old tianocore licenses and redundant license description. 3.Improve coding style. For example: remove space between @param. In V1: Initial AMD PlatformFlashAccessLib, It provides flash access protocol for other modules. Signed-off-by: Duke Zhai <duke.z...@amd.com> Cc: Eric Xing <eric.x...@amd.com> Cc: Ken Yao <ken....@amd.com> Cc: Igniculus Fu <igniculus...@amd.com> Cc: Abner Chang <abner.ch...@amd.com> --- .../Include/Library/SpiFlashDeviceLib.h | 59 ++ .../VanGoghCommonPkg/Include/Protocol/Spi.h | 346 ++++++++++++ .../Include/Protocol/SpiCommon.h | 247 ++++++++ .../Include/Protocol/SpiFlashUpdate.h | 152 +++++ .../PlatformFlashAccessLib.c | 528 ++++++++++++++++++ .../PlatformFlashAccessLib.inf | 52 ++ 6 files changed, 1384 insertions(+) create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Library/SpiFlashDeviceLib.h create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/Spi.h create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiCommon.h create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiFlashUpdate.h create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c create mode 100644 Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Library/SpiFlashDeviceLib.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Library/SpiFlashDeviceLib.h new file mode 100644 index 0000000000..391453f512 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Library/SpiFlashDeviceLib.h @@ -0,0 +1,59 @@ +/** @file + Implements SpiFlashDevice.h + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SPI_FLASH_DEVICE_LIB_H_ +#define SPI_FLASH_DEVICE_LIB_H_ + +#include <Protocol/Spi.h> + +// +// Provides mSpiInitTable and the total number of flash part in mSpiInitTable for other modules. +// +extern SPI_INIT_TABLE mSpiInitTable[]; +extern UINT8 mNumSpiFlashMax; + +// +// Flash Device commands +// +// If a supported device uses a command different from the list below, a device specific command +// will be defined just below it's JEDEC id section. +// +#define SPI_COMMAND_WRITE 0x02 +#define SPI_COMMAND_WRITE_AAI 0xAD +#define SPI_COMMAND_READ 0x03 +#define SPI_COMMAND_ERASE 0x20 +#define SPI_COMMAND_WRITE_DISABLE 0x04 +#define SPI_COMMAND_READ_S 0x05 +#define SPI_COMMAND_WRITE_ENABLE 0x06 +#define SPI_COMMAND_READ_ID 0xAB +#define SPI_COMMAND_JEDEC_ID 0x9F +#define SPI_COMMAND_WRITE_S_EN 0x50 +#define SPI_COMMAND_WRITE_S 0x01 +#define SPI_COMMAND_CHIP_ERASE 0xC7 +#define SPI_COMMAND_BLOCK_ERASE 0xD8 +#define SPI_COMMAND_READ_SFDP 0x5A +#define SPI_COMMAND_RPMC_OP1 0x9B +#define SPI_COMMAND_RPMC_OP2 0x96 +#define SPI_COMMAND_Enter_4Byte_Addr 0xB7 +#define SPI_COMMAND_Exit_4Byte_Addr 0xE9 + +// +// Winbond 256Mbit parts +// +#define SF_VENDOR_ID_WINBOND 0xEF +#define SF_DEVICE_ID1_W25Q256JW 0x19 // Capacity 256Mbit +#define SF_DEVICE_ID0_W25Q256JW 0x60 + +// +// index for prefix opcodes +// +#define SPI_WREN_INDEX 0 // Prefix Opcode 0: SPI_COMMAND_WRITE_ENABLE +#define SPI_EWSR_INDEX 1 // Prefix Opcode 1: SPI_COMMAND_WRITE_S_EN +#define BIOS_CTRL 0xDC + +#endif diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/Spi.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/Spi.h new file mode 100644 index 0000000000..9702d34f7c --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/Spi.h @@ -0,0 +1,346 @@ +/** @file + Implements AMD Spi + This file defines the EFI SPI Protocol which implements the + Intel(R) ICH SPI Host Controller Compatibility Interface. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + Copyright (c) 2013-2015 Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SPI_H_ +#define SPI_H_ + +#include <Uefi/UefiBaseType.h> + +// +// Define the SPI protocol GUID +// +// EDK and EDKII have different GUID formats +// +#if !defined (EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#define EFI_SPI_PROTOCOL_GUID \ + { \ + 0x1156efc6, 0xea32, 0x4396, 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \ + } +#define EFI_SMM_SPI_PROTOCOL_GUID \ + { \ + 0xD9072C35, 0xEB8F, 0x43ad, 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \ + } +#else +#define EFI_SPI_PROTOCOL_GUID \ + { \ + 0x1156efc6, 0xea32, 0x4396, \ + { \ + 0xb5, 0xd5, 0x26, 0x93, 0x2e, 0x83, 0xc3, 0x13 \ + } \ + } +#define EFI_SMM_SPI_PROTOCOL_GUID \ + { \ + 0xD9072C35, 0xEB8F, 0x43ad, \ + { \ + 0xA2, 0x20, 0x34, 0xD4, 0x0E, 0x2A, 0x82, 0x85 \ + } \ + } +#endif +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiSpiProtocolGuid; +extern EFI_GUID gEfiSmmSpiProtocolGuid; + +#define FCH_SPI_MMIO_REG00 0x00 // SPI_ +#define FCH_SPI_OPCODE 0x000000FFl // +#define FCH_SPI_TX_COUNT 0x00000F00l // +#define FCH_SPI_RX_COUNT 0x0000F000l // +#define FCH_SPI_EXEC_OPCODE 0x00010000l // +#define FCH_SPI_FIFO_PTR_CRL 0x00100000l // +#define FCH_SPI_FIFO_PTR_INC 0x00200000l // +#define FCH_SPI_BUSY 0x80000000l // +#define FCH_SPI_MMIO_REG0C 0x0C // SPI_Cntrl1 Register +#define FCH_SPI_PARAMETER 0x000000FFl // +#define FCH_SPI_FIFO_PTR 0x00000700l // +#define FCH_SPI_BYTE_PROGRAM 0xFF000000l // +#define FCH_SPI_MMIO_REG1C 0x1C // +#define FCH_SPI_RETRY_TIMES 0x3 // + +// +// Forward reference for ANSI C compatibility +// +typedef struct _EFI_SPI_PROTOCOL EFI_SPI_PROTOCOL; + +// +// SPI protocol data structures and definitions +// +// +// Number of Prefix Opcodes allowed on the SPI interface +// +#define SPI_NUM_PREFIX_OPCODE 2 + +// +// Number of Opcodes in the Opcode Menu +// +#define SPI_NUM_OPCODE 12 + +// +// Opcode Type +// EnumSpiOpcodeCommand: Command without address +// EnumSpiOpcodeRead: Read with address +// EnumSpiOpcodeWrite: Write with address +// +typedef enum { + EnumSpiOpcodeReadNoAddr, + EnumSpiOpcodeWriteNoAddr, + EnumSpiOpcodeRead, + EnumSpiOpcodeWrite, + EnumSpiOpcodeMax +} SPI_OPCODE_TYPE; + +typedef enum { + EnumSpiRegionAll, + EnumSpiRegionBios, + EnumSpiRegionMe, + EnumSpiRegionGbE, + EnumSpiRegionDescriptor, + EnumSpiRegionPlatformData, + EnumSpiRegionMax +} SPI_REGION_TYPE; + +// +// Hardware Sequencing required operations (as listed in CougarPoint EDS Table 5-55: "Hardware +// Sequencing Commands and Opcode Requirements" +// +typedef enum { + EnumSpiOperationWriteStatus, + EnumSpiOperationProgramData_1_Byte, + EnumSpiOperationProgramData_64_Byte, + EnumSpiOperationReadData, + EnumSpiOperationWriteDisable, + EnumSpiOperationReadStatus, + EnumSpiOperationWriteEnable, + EnumSpiOperationFastRead, + EnumSpiOperationEnableWriteStatus, + EnumSpiOperationErase_256_Byte, + EnumSpiOperationErase_4K_Byte = 0x1000, + EnumSpiOperationErase_8K_Byte = 0x2000, + EnumSpiOperationErase_64K_Byte = 0x10000, + EnumSpiOperationFullChipErase, + EnumSpiOperationJedecId, + EnumSpiOperationDualOutputFastRead, + EnumSpiOperationDiscoveryParameters, + EnumSpiOperationOther, + EnumSpiOperationMax +} SPI_OPERATION; + +// +// Opcode menu entries +// Type Operation Type (value to be programmed to the OPTYPE register) +// Code The opcode (value to be programmed to the OPMENU register) +// Operation Which Hardware Sequencing required operation this opcode respoinds to. +// The required operations are listed in EDS Table 5-55: "Hardware +// Sequencing Commands and Opcode Requirements" +// If the opcode does not corresponds to any operation listed, use +// EnumSpiOperationOther +// +typedef struct _SPI_OPCODE_MENU_ENTRY { + SPI_OPCODE_TYPE Type; + UINT8 Code; + SPI_OPERATION Operation; +} SPI_OPCODE_MENU_ENTRY; + +// +// Initialization data table loaded to the SPI host controller +// VendorId Vendor ID of the SPI device +// DeviceId0 Device ID0 of the SPI device +// DeviceId1 Device ID1 of the SPI device +// PrefixOpcode Prefix opcodes which are loaded into the SPI host controller +// OpcodeMenu Opcodes which are loaded into the SPI host controller Opcode Menu +// BiosStartOffset The offset of the start of the BIOS image relative to the flash device. +// Please note this is a Flash Linear Address, NOT a memory space address. +// This value is platform specific and depends on the system flash map. +// This value is only used on non Descriptor mode. +// BiosSize The the BIOS Image size in flash. This value is platform specific +// and depends on the system flash map. Please note BIOS Image size may +// be smaller than BIOS Region size (in Descriptor Mode) or the flash size +// (in Non Descriptor Mode), and in this case, BIOS Image is supposed to be +// placed at the top end of the BIOS Region (in Descriptor Mode) or the flash +// (in Non Descriptor Mode) +// +typedef struct _SPI_INIT_TABLE { + UINT8 VendorId; + UINT8 DeviceId0; + UINT8 DeviceId1; + UINT8 PrefixOpcode[SPI_NUM_PREFIX_OPCODE]; + SPI_OPCODE_MENU_ENTRY OpcodeMenu[SPI_NUM_OPCODE]; + UINTN BiosStartOffset; + UINTN BiosSize; +} SPI_INIT_TABLE; + +// +// Public Info struct to show current initialized state of the spi interface. +// OpcodeIndex must be less then SPI_NUM_OPCODE for operation to be supported. +// +typedef struct _SPI_INIT_INFO { + SPI_INIT_TABLE *InitTable; + UINT8 JedecIdOpcodeIndex; + UINT8 OtherOpcodeIndex; + UINT8 WriteStatusOpcodeIndex; + UINT8 ProgramOpcodeIndex; + UINT8 ReadOpcodeIndex; + UINT8 EraseOpcodeIndex; + UINT8 ReadStatusOpcodeIndex; + UINT8 FullChipEraseOpcodeIndex; +} SPI_INIT_INFO; + +// +// Protocol member functions +// + +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_INIT)( + IN EFI_SPI_PROTOCOL *This + ); + +/*++ + +Routine Description: + + Initializes the host controller to execute SPI commands. + +Arguments: + + This Pointer to the EFI_SPI_PROTOCOL instance. + +Returns: + + EFI_SUCCESS Opcode initialization on the SPI host controller completed. + EFI_ACCESS_DENIED The SPI configuration interface is locked. + EFI_OUT_OF_RESOURCES Not enough resource available to initialize the device. + EFI_DEVICE_ERROR Device error, operation failed. + +--*/ + +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_LOCK)( + IN EFI_SPI_PROTOCOL *This + ); + +/*++ + +Routine Description: + + Lock the SPI Static Configuration Interface. + Once locked, the interface is no longer open for configuration changes. + The lock state automatically clears on next system reset. + +Arguments: + + This Pointer to the EFI_SPI_PROTOCOL instance. + +Returns: + + EFI_SUCCESS Lock operation succeed. + EFI_DEVICE_ERROR Device error, operation failed. + EFI_ACCESS_DENIED The interface has already been locked. + +--*/ + +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_EXECUTE)( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 OpcodeIndex, + IN UINT8 PrefixOpcodeIndex, + IN BOOLEAN DataCycle, + IN BOOLEAN Atomic, + IN BOOLEAN ShiftOut, + IN UINTN Address, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer, + IN SPI_REGION_TYPE SpiRegionType + ); + +/*++ + +Routine Description: + + Execute SPI commands from the host controller. + +Arguments: + + This Pointer to the EFI_SPI_PROTOCOL instance. + OpcodeIndex Index of the command in the OpCode Menu. + PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence. + DataCycle TRUE if the SPI cycle contains data + Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed. + ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in. + Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform + Region, this value specifies the offset from the Region Base; for BIOS Region, + this value specifies the offset from the start of the BIOS Image. In Non + Descriptor Mode, this value specifies the offset from the start of the BIOS Image. + Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor + Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is + supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or + the flash (in Non Descriptor Mode) + DataByteCount Number of bytes in the data portion of the SPI cycle. + Buffer Pointer to caller-allocated buffer containing the dada received or sent during the SPI cycle. + SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe, + EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in + Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode + and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative + to base of the 1st flash device (i.e., it is a Flash Linear Address). + +Returns: + + EFI_SUCCESS Command succeed. + EFI_INVALID_PARAMETER The parameters specified are not valid. + EFI_UNSUPPORTED Command not supported. + EFI_DEVICE_ERROR Device error, command aborts abnormally. + +--*/ + +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_INFO)( + IN EFI_SPI_PROTOCOL *This, + OUT SPI_INIT_INFO **InitInfoPtr + ); + +/*++ + +Routine Description: + + Return info about SPI host controller, to help callers usage of Execute + service. + + If 0xff is returned as an opcode index in init info struct + then device does not support the operation. + +Arguments: + + This Pointer to the EFI_SPI_PROTOCOL instance. + InitInfoPtr Pointer to init info written to this memory location. + +Returns: + + EFI_SUCCESS Information returned. + EFI_INVALID_PARAMETER Invalid parameter. + EFI_NOT_READY Required resources not setup. + Others Unexpected error happened. + +--*/ + +// +// Protocol definition +// +struct _EFI_SPI_PROTOCOL { + EFI_SPI_INIT Init; + EFI_SPI_LOCK Lock; + EFI_SPI_EXECUTE Execute; + EFI_SPI_INFO Info; +}; + +#endif diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiCommon.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiCommon.h new file mode 100644 index 0000000000..1488c9715b --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiCommon.h @@ -0,0 +1,247 @@ +/** @file + Implements AMD SpiCommon + Header file for the PCH SPI Common Driver. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + Copyright (c) 2013-2015 Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SPI_COMMON_H_ +#define SPI_COMMON_H_ + +#include "Protocol/Spi.h" + +#include <Library/PciLib.h> +#include <Library/IoLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/BaseMemoryLib.h> +// #include <Library/SpiFlashDeviceLib.h> + +#include <Uefi/UefiBaseType.h> + +// +// Maximum time allowed while waiting the SPI cycle to complete +// Wait Time = 6 seconds = 6000000 microseconds +// Wait Period = 10 microseconds +// +#define WAIT_TIME 6000000 +#define WAIT_PERIOD 10 + +// +// Private data structure definitions for the driver +// +#define FCH_SPI_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('F', 'S', 'P', 'I') + +// +// SPI default opcode slots +// +#define SPI_OPCODE_JEDEC_ID_INDEX 0 +#define SPI_OPCODE_WRITE_S_INDEX 1 +#define SPI_OPCODE_WRITE_INDEX 2 +#define SPI_OPCODE_READ_INDEX 3 +#define SPI_OPCODE_ERASE_INDEX 4 +#define SPI_OPCODE_READ_S_INDEX 5 +#define SPI_OPCODE_CHIP_ERASE_INDEX 6 +#define SPI_OPCODE_READ_SFDP_INDEX 7 +#define SPI_COMMAND_RPMC_OP1_INDEX 8 +#define SPI_COMMAND_RPMC_OP2_INDEX 9 +#define SPI_COMMAND_Enter_4Byte_Addr_INDEX 10 +#define SPI_COMMAND_Exit_4Byte_Addr_INDEX 11 + +typedef struct { + UINTN Signature; + EFI_HANDLE Handle; + EFI_SPI_PROTOCOL SpiProtocol; + SPI_INIT_TABLE SpiInitTable; + UINTN SpiBar; + BOOLEAN InitDone; // Set to TRUE on SpiProtocolInit SUCCESS. + SPI_INIT_INFO InitInfo; +} SPI_INSTANCE; + +#define SPI_INSTANCE_FROM_SPIPROTOCOL(a) CR (a, SPI_INSTANCE, SpiProtocol, FCH_SPI_PRIVATE_DATA_SIGNATURE) + +/** + + Initialize an SPI protocol instance. + The function will assert in debug if FCH SPI has not been initialized + + @param SpiInstance - Pointer to SpiInstance to initialize + + @retval EFI_SUCCESS The protocol instance was properly initialized + @retval EFI_UNSUPPORTED The FCH is not supported by this module + +**/ +EFI_STATUS +SpiProtocolConstructor ( + SPI_INSTANCE *SpiInstance + ) +; + +/** + + Initialize the host controller to execute SPI command. + + @param This Pointer to the EFI_SPI_PROTOCOL instance. + + @retval EFI_SUCCESS Initialization completed. + @retval EFI_ACCESS_DENIED The SPI static configuration interface has been locked-down. + @retval EFI_INVALID_PARAMETER Bad input parameters. + @retval EFI_UNSUPPORTED Can't get Descriptor mode VSCC values + +**/ +EFI_STATUS +EFIAPI +SpiProtocolInit ( + IN EFI_SPI_PROTOCOL *This + ) +; + +/** + + Lock the SPI Static Configuration Interface. + Once locked, the interface can not be changed and can only be clear by system reset. + + @param This Pointer to the EFI_SPI_PROTOCOL instance. + + @retval EFI_SUCCESS Lock operation succeed. + @retval EFI_DEVICE_ERROR Device error, operation failed. + @retval EFI_ACCESS_DENIED The interface has already been locked. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolLock ( + IN EFI_SPI_PROTOCOL *This + ) +; + +/** + + Execute SPI commands from the host controller. + This function would be called by runtime driver, please do not use any MMIO marco here + + @param This Pointer to the EFI_SPI_PROTOCOL instance. + @param OpcodeIndex Index of the command in the OpCode Menu. + @param PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence. + @param DataCycle TRUE if the SPI cycle contains data + @param Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed. + @param ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in. + @param Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform + Region, this value specifies the offset from the Region Base; for BIOS Region, + this value specifies the offset from the start of the BIOS Image. In Non + Descriptor Mode, this value specifies the offset from the start of the BIOS Image. + Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor + Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is + supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or + the flash (in Non Descriptor Mode) + @param DataByteCount Number of bytes in the data portion of the SPI cycle. This function may break the + data transfer into multiple operations. This function ensures each operation does + not cross 256 byte flash address boundary. + *NOTE: if there is some SPI chip that has a stricter address boundary requirement + (e.g., its write page size is < 256 byte), then the caller cannot rely on this + function to cut the data transfer at proper address boundaries, and it's the + caller's reponsibility to pass in a properly cut DataByteCount parameter. + @param Buffer Pointer to caller-allocated buffer containing the dada received or sent during the + SPI cycle. + @param SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe, + EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in + Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode + and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative + to base of the 1st flash device (i.e., it is a Flash Linear Address). + + @retval EFI_SUCCESS Command succeed. + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + @retval EFI_UNSUPPORTED Command not supported. + @retval EFI_DEVICE_ERROR Device error, command aborts abnormally. + +**/ +EFI_STATUS +EFIAPI +SpiProtocolExecute ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 OpcodeIndex, + IN UINT8 PrefixOpcodeIndex, + IN BOOLEAN DataCycle, + IN BOOLEAN Atomic, + IN BOOLEAN ShiftOut, + IN UINTN Address, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer, + IN SPI_REGION_TYPE SpiRegionType + ) +; + +/** + + This function sends the programmed SPI command to the slave device. + + @param OpcodeIndex Index of the command in the OpCode Menu. + @param PrefixOpcodeIndex Index of the first command to run when in an atomic cycle sequence. + @param DataCycle TRUE if the SPI cycle contains data + @param Atomic TRUE if the SPI cycle is atomic and interleave cycles are not allowed. + @param ShiftOut If DataByteCount is not zero, TRUE to shift data out and FALSE to shift data in. + @param Address In Descriptor Mode, for Descriptor Region, GbE Region, ME Region and Platform + Region, this value specifies the offset from the Region Base; for BIOS Region, + this value specifies the offset from the start of the BIOS Image. In Non + Descriptor Mode, this value specifies the offset from the start of the BIOS Image. + Please note BIOS Image size may be smaller than BIOS Region size (in Descriptor + Mode) or the flash size (in Non Descriptor Mode), and in this case, BIOS Image is + supposed to be placed at the top end of the BIOS Region (in Descriptor Mode) or + the flash (in Non Descriptor Mode) + @param DataByteCount Number of bytes in the data portion of the SPI cycle. This function may break the + data transfer into multiple operations. This function ensures each operation does + not cross 256 byte flash address boundary. + *NOTE: if there is some SPI chip that has a stricter address boundary requirement + (e.g., its write page size is < 256 byte), then the caller cannot rely on this + function to cut the data transfer at proper address boundaries, and it's the + caller's reponsibility to pass in a properly cut DataByteCount parameter. + @param Buffer Data received or sent during the SPI cycle. + @param SpiRegionType SPI Region type. Values EnumSpiRegionBios, EnumSpiRegionGbE, EnumSpiRegionMe, + EnumSpiRegionDescriptor, and EnumSpiRegionPlatformData are only applicable in + Descriptor mode. Value EnumSpiRegionAll is applicable to both Descriptor Mode + and Non Descriptor Mode, which indicates "SpiRegionOffset" is actually relative + to base of the 1st flash device (i.e., it is a Flash Linear Address). + + @retval EFI_SUCCESS SPI command completes successfully. + @retval EFI_DEVICE_ERROR Device error, the command aborts abnormally. + @retval EFI_ACCESS_DENIED Some unrecognized command encountered in hardware sequencing mode + @retval EFI_INVALID_PARAMETER The parameters specified are not valid. + +**/ +EFI_STATUS +SendSpiCmd ( + IN EFI_SPI_PROTOCOL *This, + IN UINT8 OpcodeIndex, + IN UINT8 PrefixOpcodeIndex, + IN BOOLEAN DataCycle, + IN BOOLEAN Atomic, + IN BOOLEAN ShiftOut, + IN UINTN Address, + IN UINT32 DataByteCount, + IN OUT UINT8 *Buffer, + IN SPI_REGION_TYPE SpiRegionType + ) +; + +/** + + Wait execution cycle to complete on the SPI interface. Check both Hardware + and Software Sequencing status registers + + @param This The SPI protocol instance + + @retval TRUE SPI cycle completed on the interface. + @retval FALSE Time out while waiting the SPI cycle to complete. + It's not safe to program the next command on the SPI interface. + +**/ +BOOLEAN +WaitForSpiCycleComplete ( + IN EFI_SPI_PROTOCOL *This + ) +; + +#endif diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiFlashUpdate.h b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiFlashUpdate.h new file mode 100644 index 0000000000..e1271e2244 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Include/Protocol/SpiFlashUpdate.h @@ -0,0 +1,152 @@ +/** @file + Implements AMD PcRtc + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef SPI_FLASH_UPDATE_H_ +#define SPI_FLASH_UPDATE_H_ + +#include <Uefi/UefiBaseType.h> + +// +// Spi Flash Update Protocol GUID +// EDK and EDKII have different GUID formats +// +#if !defined (EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000) +#define EFI_SPI_FLASH_UPDATE_PROTOCOL_GUID \ + { \ + 0x9cf897ac, 0xc8cd, 0x4564, 0x8d, 0x8f, 0x1b, 0x88, 0xd4, 0xcf, 0xde, 0x22 \ + } +#define EFI_SMM_SPI_FLASH_UPDATE_PROTOCOL_GUID \ + { \ + 0xc5922181, 0x7a76, 0x4777, 0x96, 0x85, 0x8a, 0xd3, 0x4e, 0xca, 0x0, 0x8c \ + } +#else +#define EFI_SPI_FLASH_UPDATE_PROTOCOL_GUID \ + { \ + 0x9cf897ac, 0xc8cd, 0x4564, \ + { \ + 0x8d, 0x8f, 0x1b, 0x88, 0xd4, 0xcf, 0xde, 0x22 \ + } \ + } +#define EFI_SMM_SPI_FLASH_UPDATE_PROTOCOL_GUID \ + { \ + 0xc5922181, 0x7a76, 0x4777, \ + { \ + 0x96, 0x85, 0x8a, 0xd3, 0x4e, 0xca, 0x0, 0x8c \ + } \ + } +#endif + +// +// Extern the GUID for protocol users. +// +extern EFI_GUID gEfiSpiFlashUpdateProtocolGuid; +extern EFI_GUID gEfiSmmSpiFlashUpdateProtocolGuid; + +// +// Forward reference for ANSI C compatibility +// +typedef struct _EFI_SPI_FLASH_UPDATE_PROTOCOL EFI_SPI_FLASH_UPDATE_PROTOCOL; + +// +// SMM SPI Flash Update protocol structure is the same as SPI Flash Update +// protocol. The SMM one is intend to run in SMM environment. +// +typedef EFI_SPI_FLASH_UPDATE_PROTOCOL EFI_SMM_SPI_FLASH_UPDATE_PROTOCOL; + +// +// Protocol member functions +// + +/** + Read data from flash device. + + @param[in] FlashAddress Physical flash address. + @param[in] NumBytes Number in Byte. + @param[out] Buffer Buffer contain the read data. + + @retval EFI_SUCCESS Read successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval others Some error occurs when executing this routine. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_FLASH_UPDATE_FD_READ)( + IN UINTN FlashAddress, + IN UINTN NumBytes, + OUT VOID *Buffer + ); + +/** + Erase flash region according to input in a block size. + + @param[in] FlashAddress Physical flash address. + @param[in] NumBytes Number in Byte, a block size in flash device. + + @retval EFI_SUCCESS Erase successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval others Some error occurs when executing this routine. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_FLASH_UPDATE_FD_ERASE)( + IN UINTN FlashAddress, + IN UINTN NumBytes + ); + +/** + Write data to flash device. + + Write Buffer(FlashAddress|NumBytes) to flash device. + + @param[in] FlashAddress Physical flash address. + @param[in] NumBytes Number in Byte. + @param[in] Buffer Buffer contain the write data. + + @retval EFI_SUCCESS Write successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + @retval others Some error occurs when executing this routine. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_FLASH_UPDATE_FD_Write)( + IN UINTN FlashAddress, + IN UINTN NumBytes, + IN UINT8 *Buffer + ); + +/** + Get flash device size and flash block size. + + @param[out] FlashSize Pointer to the size of flash device. + @param[out] BlockSize Pointer to the size of block in flash device. + + @retval EFI_SUCCESS Get successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter. + +**/ +typedef +EFI_STATUS +(EFIAPI *EFI_SPI_FLASH_GET_FLASH_SIZE_BLOCK_SIZE)( + OUT UINTN *FlashSize, + OUT UINTN *BlockSize + ); + +// +// Protocol definition +// +struct _EFI_SPI_FLASH_UPDATE_PROTOCOL { + EFI_SPI_FLASH_UPDATE_FD_READ Read; + EFI_SPI_FLASH_UPDATE_FD_ERASE Erase; + EFI_SPI_FLASH_UPDATE_FD_Write Write; + EFI_SPI_FLASH_GET_FLASH_SIZE_BLOCK_SIZE GetFlashSizeBlockSize; +}; + +#endif diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c new file mode 100644 index 0000000000..61c5983c44 --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.c @@ -0,0 +1,528 @@ +/** @file + Implements PlatformFlashAccessLib.c + Platform Flash Access library. + + Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> + Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include <Uefi.h> + +#include <PiDxe.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/PcdLib.h> +#include <Library/PlatformFlashAccessLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Protocol/Spi.h> +#include <Protocol/SpiCommon.h> +#include <Protocol/FirmwareManagement.h> +#include <Library/CacheMaintenanceLib.h> +#include <Library/IoLib.h> +#include <Library/UefiLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/PrintLib.h> + +#define BLOCK_SIZE 0x1000 + +// +// Prefix Opcode Index on the host SPI controller +// +typedef enum { + SPI_WREN, // Prefix Opcode 0: Write Enable + SPI_EWSR, // Prefix Opcode 1: Enable Write Status Register +} PREFIX_OPCODE_INDEX; + +STATIC EFI_PHYSICAL_ADDRESS mInternalFdAddress; + +EFI_SPI_PROTOCOL *mSpiProtocol; + +/** + Read NumBytes bytes of data from the address specified by + PAddress into Buffer. + + @param[in] Address The starting physical address of the read. + @param[in,out] NumBytes On input, the number of bytes to read. On output, the number + of bytes actually read. + @param[out] Buffer The destination data buffer for the read. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashRead ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + OUT UINT8 *Buffer + ) +{ + CopyMem (Buffer, (VOID *)Address, *NumBytes); + return EFI_SUCCESS; +} + +/** + Write NumBytes bytes of data from Buffer to the address specified by + PAddresss. + + @param[in] Address The starting physical address of the write. + @param[in,out] NumBytes On input, the number of bytes to write. On output, + the actual number of bytes written. + @param[in] Buffer The source data buffer for the write. + + @retval EFI_SUCCESS Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashWrite ( + IN UINTN Address, + IN OUT UINT32 *NumBytes, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + UINTN Offset; + UINT32 Length; + UINT32 RemainingBytes; + + ASSERT ((NumBytes != NULL) && (Buffer != NULL)); + ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashAreaBaseAddress)); + + Offset = Address - (UINTN)PcdGet32 (PcdFlashAreaBaseAddress); + ASSERT ((*NumBytes + Offset) <= (UINTN)(PcdGet32 (PcdFlashAreaSize)*2)); + Status = EFI_SUCCESS; + RemainingBytes = *NumBytes; + + while (RemainingBytes > 0) { + if (RemainingBytes > SIZE_4KB) { + Length = SIZE_4KB; + } else { + Length = RemainingBytes; + } + + Status = mSpiProtocol->Execute ( + mSpiProtocol, + SPI_OPCODE_WRITE_INDEX, + SPI_WREN, + TRUE, + TRUE, + TRUE, + (UINT32)Offset, + Length, + Buffer, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + break; + } + + RemainingBytes -= Length; + Offset += Length; + Buffer += Length; + } + + // + // Actual number of bytes written + // + *NumBytes -= RemainingBytes; + + return Status; +} + +/** + Read the block starting at Address. + + @param[in] BaseAddress The starting physical address of the block to be read. + @param[in,out] ReadBuffer The pointer to a system memory buffer receiving the data read. + + @return The status returned from SpiFlashRead(). + +**/ +EFI_STATUS +InternalReadBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + OUT VOID *ReadBuffer + ) +{ + EFI_STATUS Status; + UINT32 BlockSize; + + BlockSize = BLOCK_SIZE; + + Status = SpiFlashRead ((UINTN)BaseAddress, &BlockSize, ReadBuffer); + + return Status; +} + +/** + Erase the block starting at Address. + + @param[in] Address The starting physical address of the block to be erased. + This library assume that caller garantee that the PAddress + is at the starting address of this block. + @param[in] NumBytes On input, the number of bytes of the logical block to be erased. + On output, the actual number of bytes erased. + + @retval EFI_SUCCESS. Opertion is successful. + @retval EFI_DEVICE_ERROR If there is any device errors. + +**/ +EFI_STATUS +EFIAPI +SpiFlashBlockErase ( + IN UINTN Address, + IN UINTN *NumBytes + ) +{ + EFI_STATUS Status; + UINTN Offset; + UINTN RemainingBytes; + + ASSERT (NumBytes != NULL); + ASSERT (Address >= (UINTN)PcdGet32 (PcdFlashAreaBaseAddress)); + + Offset = Address - (UINTN)PcdGet32 (PcdFlashAreaBaseAddress); + + ASSERT ((*NumBytes % SIZE_4KB) == 0); + // - ASSERT ((*NumBytes + Offset) <= (UINTN)PcdGet32 (PcdFlashAreaSize)); + ASSERT ((*NumBytes + Offset) <= (UINTN)(PcdGet32 (PcdFlashAreaSize)*2)); + Status = EFI_SUCCESS; + RemainingBytes = *NumBytes; + + while (RemainingBytes > 0) { + Status = mSpiProtocol->Execute ( + mSpiProtocol, + SPI_OPCODE_ERASE_INDEX, + SPI_WREN, + FALSE, + TRUE, + TRUE, + (UINT32)Offset, + 0, + NULL, + EnumSpiRegionAll + ); + if (EFI_ERROR (Status)) { + break; + } + + RemainingBytes -= SIZE_4KB; + Offset += SIZE_4KB; + } + + // + // Actual number of bytes erased + // + *NumBytes -= RemainingBytes; + + return Status; +} + +/** + Erase the whole block. + + @param[in] BaseAddress Base address of the block to be erased. + + @retval EFI_SUCCESS The command completed successfully. + @retval Other Device error or wirte-locked, operation failed. + +**/ +EFI_STATUS +InternalEraseBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress + ) +{ + EFI_STATUS Status; + UINTN NumBytes; + + NumBytes = BLOCK_SIZE; + + Status = SpiFlashBlockErase ((UINTN)BaseAddress, &NumBytes); + + return Status; +} + +/** + Compare the block value with buggfer. + + @param[in] BaseAddress Base address of the block to be compare. + @param[in] Buffer The buffer to be compare. + + @retval EFI_SUCCESS The command compare successfully. + @retval EFI_OUT_OF_RESOURCES The resource has run out.. + +**/ +EFI_STATUS +InternalCompareBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT8 *Buffer + ) +{ + EFI_STATUS Status; + VOID *CompareBuffer; + UINT32 NumBytes; + INTN CompareResult; + + NumBytes = BLOCK_SIZE; + CompareBuffer = AllocatePool (NumBytes); + if (CompareBuffer == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Done; + } + + Status = SpiFlashRead ((UINTN)BaseAddress, &NumBytes, CompareBuffer); + if (EFI_ERROR (Status)) { + goto Done; + } + + CompareResult = CompareMem (CompareBuffer, Buffer, BLOCK_SIZE); + if (CompareResult != 0) { + Status = EFI_VOLUME_CORRUPTED; + } + +Done: + if (CompareBuffer != NULL) { + FreePool (CompareBuffer); + } + + return Status; +} + +/** + Write a block of data. + + @param[in] BaseAddress Base address of the block. + @param[in] Buffer Data buffer. + @param[in] BufferSize Size of the buffer. + + @retval EFI_SUCCESS The command completed successfully. + @retval EFI_INVALID_PARAMETER Invalid parameter, can not proceed. + @retval Other Device error or wirte-locked, operation failed. + +**/ +EFI_STATUS +InternalWriteBlock ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT8 *Buffer, + IN UINT32 BufferSize + ) +{ + EFI_STATUS Status; + + Status = SpiFlashWrite ((UINTN)BaseAddress, &BufferSize, Buffer); + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "\nFlash write error.")); + return Status; + } + + WriteBackInvalidateDataCacheRange ((VOID *)(UINTN)BaseAddress, BLOCK_SIZE); + + Status = InternalCompareBlock (BaseAddress, Buffer); + Status = EFI_SUCCESS; + + if (EFI_ERROR (Status)) { + DEBUG ((DEBUG_ERROR, "\nError when writing to BaseAddress %x with different at offset %x.\n", BaseAddress, Status)); + } else { + DEBUG ((DEBUG_INFO, "\nVerified data written to Block at %x is correct.\n", BaseAddress)); + } + + return Status; +} + +/** + Perform flash write operation with progress indicator. The start and end + completion percentage values are passed into this function. If the requested + flash write operation is broken up, then completion percentage between the + start and end values may be passed to the provided Progress function. The + caller of this function is required to call the Progress function for the + start and end completion percentage values. This allows the Progress, + StartPercentage, and EndPercentage parameters to be ignored if the requested + flash write operation can not be broken up + + @param[in] FirmwareType The type of firmware. + @param[in] FlashAddress The address of flash device to be accessed. + @param[in] FlashAddressType The type of flash device address. + @param[in] Buffer The pointer to the data buffer. + @param[in] Length The length of data buffer in bytes. + @param[in] Progress A function used report the progress of the + firmware update. This is an optional parameter + that may be NULL. + @param[in] StartPercentage The start completion percentage value that may + be used to report progress during the flash + write operation. + @param[in] EndPercentage The end completion percentage value that may + be used to report progress during the flash + write operation. + + @retval EFI_SUCCESS The operation returns successfully. + @retval EFI_WRITE_PROTECTED The flash device is read only. + @retval EFI_UNSUPPORTED The flash device access is unsupported. + @retval EFI_INVALID_PARAMETER The input parameter is not valid. +**/ +EFI_STATUS +EFIAPI +PerformFlashWriteWithProgress ( + IN PLATFORM_FIRMWARE_TYPE FirmwareType, + IN EFI_PHYSICAL_ADDRESS FlashAddress, + IN FLASH_ADDRESS_TYPE FlashAddressType, + IN VOID *Buffer, + IN UINTN Length, + IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress, OPTIONAL + IN UINTN StartPercentage, + IN UINTN EndPercentage + ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINTN Index; + EFI_PHYSICAL_ADDRESS Address; + UINTN CountOfBlocks; + EFI_TPL OldTpl; + BOOLEAN FlashError; + UINT8 *Buf; + + Index = 0; + Address = 0; + CountOfBlocks = 0; + FlashError = FALSE; + Buf = Buffer; + + DEBUG ((DEBUG_INFO | DEBUG_ERROR, "PerformFlashWrite - 0x%x(%x) - 0x%x\n", (UINTN)FlashAddress, (UINTN)FlashAddressType, Length)); + if (FlashAddressType == FlashAddressTypeRelativeAddress) { + FlashAddress = FlashAddress + mInternalFdAddress; + } + + CountOfBlocks = (UINTN)(Length / BLOCK_SIZE); + Address = FlashAddress; + + // + // Raise TPL to TPL_NOTIFY to block any event handler, + // while still allowing RaiseTPL(TPL_NOTIFY) within + // output driver during Print() + // + OldTpl = gBS->RaiseTPL (TPL_NOTIFY); + for (Index = 0; Index < CountOfBlocks; Index++) { + if (Progress != NULL) { + Progress (StartPercentage + ((Index * (EndPercentage - StartPercentage)) / CountOfBlocks)); + } + + // + // Handle block based on address and contents. + // + if (!EFI_ERROR (InternalCompareBlock (Address, Buf))) { + DEBUG ((DEBUG_INFO, "Skipping block at 0x%lx (already programmed)\n", Address)); + } else { + // + // Make updating process uninterruptable, + // so that the flash memory area is not accessed by other entities + // which may interfere with the updating process + // + Status = InternalEraseBlock (Address); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + FlashError = TRUE; + goto Done; + } + + Status = InternalWriteBlock ( + Address, + Buf, + (UINT32)(Length > BLOCK_SIZE ? BLOCK_SIZE : Length) + ); + if (EFI_ERROR (Status)) { + gBS->RestoreTPL (OldTpl); + FlashError = TRUE; + goto Done; + } + } + + // + // Move to next block to update. + // + Address += BLOCK_SIZE; + Buf += BLOCK_SIZE; + if (Length > BLOCK_SIZE) { + Length -= BLOCK_SIZE; + } else { + Length = 0; + } + } + + gBS->RestoreTPL (OldTpl); + +Done: + + if (Progress != NULL) { + Progress (EndPercentage); + } + + (VOID)FlashError; + return Status; +} + +/** + Perform flash write operation. + + @param[in] FirmwareType The type of firmware. + @param[in] FlashAddress The address of flash device to be accessed. + @param[in] FlashAddressType The type of flash device address. + @param[in] Buffer The pointer to the data buffer. + @param[in] Length The length of data buffer in bytes. + + @retval EFI_SUCCESS The operation returns successfully. + @retval EFI_WRITE_PROTECTED The flash device is read only. + @retval EFI_UNSUPPORTED The flash device access is unsupported. + @retval EFI_INVALID_PARAMETER The input parameter is not valid. +**/ +EFI_STATUS +EFIAPI +PerformFlashWrite ( + IN PLATFORM_FIRMWARE_TYPE FirmwareType, + IN EFI_PHYSICAL_ADDRESS FlashAddress, + IN FLASH_ADDRESS_TYPE FlashAddressType, + IN VOID *Buffer, + IN UINTN Length + ) +{ + return PerformFlashWriteWithProgress ( + FirmwareType, + FlashAddress, + FlashAddressType, + Buffer, + Length, + NULL, + 0, + 0 + ); +} + +/** + Platform Flash Access Lib Constructor. +**/ +EFI_STATUS +EFIAPI +PerformFlashAccessLibConstructor ( + VOID + ) +{ + EFI_STATUS Status; + + mInternalFdAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PcdGet32 (PcdFlashAreaBaseAddress); + DEBUG ((DEBUG_INFO, "PcdFlashAreaBaseAddress - 0x%x\n", mInternalFdAddress)); + + Status = gBS->LocateProtocol ( + &gEfiSpiProtocolGuid, + NULL, + (VOID **)&mSpiProtocol + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf new file mode 100644 index 0000000000..6dc967efcd --- /dev/null +++ b/Platform/AMD/VanGoghBoard/VanGoghCommonPkg/Library/PlatformFlashAccessLib/PlatformFlashAccessLib.inf @@ -0,0 +1,52 @@ +## @file +# Platform Flash AccessLib +# Platform Flash Access library. +# +# Copyright (C) 2024 Advanced Micro Devices, Inc. All rights reserved.<BR> +# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR> +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PlatformFlashAccessLib + FILE_GUID = 31CF9CEC-DA4E-4505-AA20-33364A291A95 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PlatformFlashAccessLib + CONSTRUCTOR = PerformFlashAccessLibConstructor + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 EBC +# + +[Sources] + PlatformFlashAccessLib.c + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + SignedCapsulePkg/SignedCapsulePkg.dec + VanGoghCommonPkg/AmdCommonPkg.dec + ChachaniBoardPkg/Project.dec + +[LibraryClasses] + BaseMemoryLib + IoLib + PcdLib + DebugLib + MemoryAllocationLib + CacheMaintenanceLib + +[Guids] + gEdkiiSystemFmpCapsuleConfigFileGuid ## SOMETIMES_CONSUMES ## GUID + +[Protocols] + gEfiSpiProtocolGuid ## CONSUMES + +[Pcd] + gPlatformPkgTokenSpaceGuid.PcdFlashAreaBaseAddress ## SOMETIMES_CONSUMES + gPlatformPkgTokenSpaceGuid.PcdFlashAreaSize ## SOMETIMES_CONSUMES -- 2.31.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#114589): https://edk2.groups.io/g/devel/message/114589 Mute This Topic: https://groups.io/mt/103975454/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-