On Wed, Nov 17, 2021 at 23:46:59 +0700, Nhi Pham wrote: > From: Vu Nguyen <[email protected]> > > Provides functions to access the NVRAM, NVRAM2 and FailSafe region on the > Flash over MM communication. > > Cc: Thang Nguyen <[email protected]> > Cc: Chuong Tran <[email protected]> > Cc: Phong Vo <[email protected]> > Cc: Leif Lindholm <[email protected]> > Cc: Michael D Kinney <[email protected]> > Cc: Ard Biesheuvel <[email protected]> > Cc: Nate DeSimone <[email protected]> > > Signed-off-by: Nhi Pham <[email protected]>
Reviewed-by: Leif Lindholm <[email protected]> > --- > Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec | 3 + > Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc | 2 + > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf | 35 ++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.inf | 37 ++ > Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h | 118 > +++++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.h | 92 > +++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c | 83 > +++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.c | 372 > ++++++++++++++++++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.c | 137 > +++++++ > 9 files changed, 879 insertions(+) > > diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > index 0813fc9b4b69..ac778674266d 100644 > --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > @@ -34,6 +34,9 @@ [LibraryClasses] > ## @libraryclass Defines a set of methods to generate random numbers by > using Hardware RNG. > TrngLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/TrngLib.h > > + ## @libraryclass Defines a set of methods to access flash memory. > + FlashLib|Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h > + > [Guids] > ## NVParam MM GUID > gNVParamMmGuid = { 0xE4AC5024, 0x29BE, 0x4ADC, { 0x93, 0x36, > 0x87, 0xB5, 0xA0, 0x76, 0x23, 0x2D } } > diff --git a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc > b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc > index 15f649d97f30..cf1be4df8f27 100644 > --- a/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc > +++ b/Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dsc.inc > @@ -84,6 +84,7 @@ [LibraryClasses.common] > > AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/AmpereCpuLib.inf > TimeBaseLib|EmbeddedPkg/Library/TimeBaseLib/TimeBaseLib.inf > > MmCommunicationLib|Silicon/Ampere/AmpereAltraPkg/Library/MmCommunicationLib/MmCommunicationLib.inf > + FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf > > # > # ARM PL011 UART Driver > @@ -252,6 +253,7 @@ [LibraryClasses.common.DXE_RUNTIME_DRIVER] > ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf > > NVParamLib|Silicon/Ampere/AmpereAltraPkg/Library/NVParamLib/RuntimeNVParamLib.inf > > AmpereCpuLib|Silicon/Ampere/AmpereAltraPkg/Library/AmpereCpuLib/RuntimeAmpereCpuLib.inf > + FlashLib|Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.inf > > [LibraryClasses.ARM,LibraryClasses.AARCH64] > # > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf > b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf > new file mode 100644 > index 000000000000..896d8fd965c8 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.inf > @@ -0,0 +1,35 @@ > +## @file > +# > +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = FlashLib > + FILE_GUID = 9E9D093D-6484-45AE-BA49-0745AA0BB481 > + MODULE_TYPE = BASE > + VERSION_STRING = 0.1 > + LIBRARY_CLASS = FlashLib > + CONSTRUCTOR = FlashLibConstructor > + > +[Sources.common] > + FlashLib.c > + FlashLibCommon.c > + > +[Packages] > + ArmPkg/ArmPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + MdePkg/MdePkg.dec > + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > + > +[LibraryClasses] > + BaseMemoryLib > + DebugLib > + MemoryAllocationLib > + MmCommunicationLib > + > +[Guids] > + gSpiNorMmGuid > diff --git > a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.inf > b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.inf > new file mode 100644 > index 000000000000..e729e29cf450 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.inf > @@ -0,0 +1,37 @@ > +## @file > +# > +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = RuntimeFlashLib > + FILE_GUID = 0FDF1187-A2DA-4876-8B1F-6D1E928AA319 > + MODULE_TYPE = DXE_RUNTIME_DRIVER > + VERSION_STRING = 0.1 > + LIBRARY_CLASS = FlashLib > + CONSTRUCTOR = FlashLibConstructor > + > +[Sources.common] > + FlashLibCommon.c > + RuntimeFlashLib.c > + > +[Packages] > + ArmPkg/ArmPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + MdePkg/MdePkg.dec > + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > + > +[LibraryClasses] > + BaseMemoryLib > + DebugLib > + MemoryAllocationLib > + > +[Guids] > + gSpiNorMmGuid > + > +[Protocols] > + gEfiMmCommunication2ProtocolGuid > diff --git a/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h > b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h > new file mode 100644 > index 000000000000..ce50602f9934 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Include/Library/FlashLib.h > @@ -0,0 +1,118 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef FLASH_LIB_H_ > +#define FLASH_LIB_H_ > + > +/** > + Get the information about the Flash region to store the FailSafe status. > + > + @param[out] FailSafeBase Base address of the FailSafe space. > + @param[out] FailSafeSize Total size of the FailSafe space. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER FailSafeBase or FailSafeSize is NULL. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashGetFailSafeInfo ( > + OUT UINTN *FailSafeBase, > + OUT UINT32 *FailSafeSize > + ); > + > +/** > + Get the information about the Flash region to store the NVRAM variables. > + > + @param[out] NvRamBase Base address of the NVRAM space. > + @param[out] NvRamSize Total size of the NVRAM space. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER NvRamBase or NvRamSize is NULL. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashGetNvRamInfo ( > + OUT UINTN *NvRamBase, > + OUT UINT32 *NvRamSize > + ); > + > +/** > + Get the information about the second Flash region to store the NVRAM > variables. > + > + @param[out] NvRam2Base Base address of the NVRAM space. > + @param[out] NvRam2Size Total size of the NVRAM space. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER NvRam2Base or NvRam2Size is NULL. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashGetNvRam2Info ( > + OUT UINTN *NvRam2Base, > + OUT UINT32 *NvRam2Size > + ); > + > +/** > + Erase a region of the Flash. > + > + @param[in] ByteAddress Start address of the region. > + @param[in] Length Number of bytes to erase. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER Length is Zero. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashEraseCommand ( > + IN UINTN ByteAddress, > + IN UINT32 Length > + ); > + > +/** > + Write data buffer to the Flash. > + > + @param[in] ByteAddress Start address of the region. > + @param[in] Buffer Pointer to the data buffer. > + @param[in] Length Number of bytes to write. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER Buffer is NULL or Length is Zero. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashWriteCommand ( > + IN UINTN ByteAddress, > + IN VOID *Buffer, > + IN UINT32 Length > + ); > + > +/** > + Read data from the Flash into Buffer. > + > + @param[in] ByteAddress Start address of the region. > + @param[out] Buffer Pointer to the data buffer. > + @param[in] Length Number of bytes to read. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER Buffer is NULL or Length is Zero. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashReadCommand ( > + IN UINTN ByteAddress, > + OUT VOID *Buffer, > + IN UINT32 Length > + ); > + > +#endif /* FLASH_LIB_H_ */ > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.h > b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.h > new file mode 100644 > index 000000000000..327429a8f998 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.h > @@ -0,0 +1,92 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef FLASH_LIB_COMMON_H_ > +#define FLASH_LIB_COMMON_H_ > + > +#define EFI_MM_MAX_TMP_BUF_SIZE 0x1000 > +#define EFI_MM_MAX_PAYLOAD_SIZE 0x50 > + > +#define MM_SPINOR_FUNC_GET_INFO 0x00 > +#define MM_SPINOR_FUNC_READ 0x01 > +#define MM_SPINOR_FUNC_WRITE 0x02 > +#define MM_SPINOR_FUNC_ERASE 0x03 > +#define MM_SPINOR_FUNC_GET_NVRAM_INFO 0x04 > +#define MM_SPINOR_FUNC_GET_NVRAM2_INFO 0x05 > +#define MM_SPINOR_FUNC_GET_FAILSAFE_INFO 0x06 > + > +#define MM_SPINOR_RES_SUCCESS 0xAABBCC00 > +#define MM_SPINOR_RES_FAIL 0xAABBCCFF > + > +#pragma pack(1) > + > +typedef struct { > + // > + // Allows for disambiguation of the message format. > + // > + EFI_GUID HeaderGuid; > + > + // > + // Describes the size of Data (in bytes) and does not include the size of > the header. > + // > + UINTN MessageLength; > + > + // > + // Designates an array of bytes that is MessageLength in size. > + // > + UINT8 Data[EFI_MM_MAX_PAYLOAD_SIZE]; > +} EFI_MM_COMMUNICATE_REQUEST; > + > +typedef struct { > + UINT64 Status; > + UINT64 DeviceBase; > + UINT64 PageSize; > + UINT64 SectorSize; > + UINT64 DeviceSize; > +} EFI_MM_COMMUNICATE_SPINOR_RESPONSE; > + > +typedef struct { > + UINT64 Status; > + UINT64 FailSafeBase; > + UINT64 FailSafeSize; > +} EFI_MM_COMMUNICATE_FAILSAFE_INFO_RESPONSE; > + > +typedef struct { > + UINT64 Status; > + UINT64 NvRamBase; > + UINT64 NvRamSize; > +} EFI_MM_COMMUNICATE_NVRAM_INFO_RESPONSE; > + > +#pragma pack() > + > +extern BOOLEAN gFlashLibRuntime; > +extern UINT8 *gFlashLibPhysicalBuffer; > +extern UINT8 *gFlashLibVirtualBuffer; > + > +/** > + Provides an interface to access the Flash services via MM interface. > + > + @param[in] Request Pointer to the request buffer > + @param[in] RequestDataSize Size of the request buffer. > + @param[out] Response Pointer to the response buffer > + @param[in] ResponseDataSize Size of the response buffer. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER An invalid data parameter or an invalid > + combination of data parameters. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +FlashMmCommunicate ( > + IN VOID *Request, > + IN UINT32 RequestDataSize, > + OUT VOID *Response, > + IN UINT32 ResponseDataSize > + ); > + > +#endif /* FLASH_LIB_COMMON_H_ */ > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c > b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c > new file mode 100644 > index 000000000000..6c8a79699cd4 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c > @@ -0,0 +1,83 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/MmCommunicationLib.h> > + > +#include "FlashLibCommon.h" > + > +/** > + Constructor function of the FlashLib > + > + @retval EFI_SUCCESS The constructor executes successfully. > +**/ > +EFI_STATUS > +EFIAPI > +FlashLibConstructor ( > + VOID > + ) > +{ > + gFlashLibPhysicalBuffer = AllocateZeroPool (EFI_MM_MAX_TMP_BUF_SIZE); > + gFlashLibVirtualBuffer = gFlashLibPhysicalBuffer; > + ASSERT (gFlashLibPhysicalBuffer != NULL); > + > + return EFI_SUCCESS; > +} > + > +/** > + Provides an interface to access the Flash services via MM interface. > + > + @param[in] Request Pointer to the request buffer > + @param[in] RequestDataSize Size of the request buffer. > + @param[out] Response Pointer to the response buffer > + @param[in] ResponseDataSize Size of the response buffer. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER An invalid data parameter or an invalid > + combination of data parameters. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +FlashMmCommunicate ( > + IN VOID *Request, > + IN UINT32 RequestDataSize, > + OUT VOID *Response, > + IN UINT32 ResponseDataSize > + ) > +{ > + EFI_MM_COMMUNICATE_REQUEST CommBuffer; > + EFI_STATUS Status; > + > + if (Request == NULL || RequestDataSize == 0 > + || RequestDataSize > EFI_MM_MAX_PAYLOAD_SIZE > + || (ResponseDataSize == 0 && Response == NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + CopyGuid (&CommBuffer.HeaderGuid, &gSpiNorMmGuid); > + CommBuffer.MessageLength = RequestDataSize; > + CopyMem (CommBuffer.Data, Request, RequestDataSize); > + > + Status = MmCommunicationCommunicate ( > + &CommBuffer, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (ResponseDataSize > 0) { > + CopyMem (Response, CommBuffer.Data, ResponseDataSize); > + } > + > + return EFI_SUCCESS; > +} > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.c > b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.c > new file mode 100644 > index 000000000000..83695c857a11 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.c > @@ -0,0 +1,372 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/FlashLib.h> > +#include <Library/MemoryAllocationLib.h> > + > +#include "FlashLibCommon.h" > + > +BOOLEAN gFlashLibRuntime = FALSE; > +UINT8 *gFlashLibPhysicalBuffer; > +UINT8 *gFlashLibVirtualBuffer; > + > +/** > + Convert Virtual Address to Physical Address at Runtime. > + > + @param[in] VirtualPtr Virtual Address Pointer. > + @param[in] Size Total bytes of the buffer. > + > + @retval Pointer to the physical address of the converted buffer. > +**/ > +STATIC > +UINT8 * > +ConvertToPhysicalBuffer ( > + IN UINT8 *VirtualPtr, > + IN UINT32 Size > + ) > +{ > + if (gFlashLibRuntime) { > + ASSERT (VirtualPtr != NULL); > + CopyMem (gFlashLibVirtualBuffer, VirtualPtr, Size); > + return gFlashLibPhysicalBuffer; > + } > + > + return VirtualPtr; > +} > + > +/** > + Get the information about the Flash region to store the FailSafe status. > + > + @param[out] FailSafeBase Base address of the FailSafe space. > + @param[out] FailSafeSize Total size of the FailSafe space. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER FailSafeBase or FailSafeSize is NULL. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashGetFailSafeInfo ( > + OUT UINTN *FailSafeBase, > + OUT UINT32 *FailSafeSize > + ) > +{ > + EFI_MM_COMMUNICATE_FAILSAFE_INFO_RESPONSE FailSafeInfo; > + EFI_STATUS Status; > + UINT64 MmData[5]; > + > + if (FailSafeBase == NULL || FailSafeSize == NULL ) { > + return EFI_INVALID_PARAMETER; > + } > + > + MmData[0] = MM_SPINOR_FUNC_GET_FAILSAFE_INFO; > + > + Status = FlashMmCommunicate ( > + MmData, > + sizeof (MmData), > + &FailSafeInfo, > + sizeof (FailSafeInfo) > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (FailSafeInfo.Status == MM_SPINOR_RES_SUCCESS) { > + *FailSafeBase = FailSafeInfo.FailSafeBase; > + *FailSafeSize = FailSafeInfo.FailSafeSize; > + > + DEBUG (( > + DEBUG_INFO, > + "%a: FailSafe Base 0x%llx, Size 0x%lx\n", > + __FUNCTION__, > + *FailSafeBase, > + *FailSafeSize > + )); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Get the information about the Flash region to store the NVRAM variables. > + > + @param[out] NvRamBase Base address of the NVRAM space. > + @param[out] NvRamSize Total size of the NVRAM space. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER NvRamBase or NvRamSize is NULL. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashGetNvRamInfo ( > + OUT UINTN *NvRamBase, > + OUT UINT32 *NvRamSize > + ) > +{ > + EFI_MM_COMMUNICATE_NVRAM_INFO_RESPONSE NvRamInfo; > + EFI_STATUS Status; > + UINT64 MmData[5]; > + > + if (NvRamBase == NULL || NvRamSize == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + MmData[0] = MM_SPINOR_FUNC_GET_NVRAM_INFO; > + > + Status = FlashMmCommunicate ( > + MmData, > + sizeof (MmData), > + &NvRamInfo, > + sizeof (NvRamInfo) > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (NvRamInfo.Status == MM_SPINOR_RES_SUCCESS) { > + *NvRamBase = NvRamInfo.NvRamBase; > + *NvRamSize = NvRamInfo.NvRamSize; > + DEBUG (( > + DEBUG_INFO, > + "%a: NVRAM Base 0x%llx, Size 0x%lx\n", > + __FUNCTION__, > + *NvRamBase, > + *NvRamSize > + )); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Get the information about the second Flash region to store the NVRAM > variables. > + > + @param[out] NvRam2Base Base address of the NVRAM space. > + @param[out] NvRam2Size Total size of the NVRAM space. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER NvRam2Base or NvRam2Size is NULL. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashGetNvRam2Info ( > + OUT UINTN *NvRam2Base, > + OUT UINT32 *NvRam2Size > + ) > +{ > + EFI_MM_COMMUNICATE_NVRAM_INFO_RESPONSE NvRam2Info; > + EFI_STATUS Status; > + UINT64 MmData[5]; > + > + if (NvRam2Base == NULL || NvRam2Size == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + MmData[0] = MM_SPINOR_FUNC_GET_NVRAM2_INFO; > + > + Status = FlashMmCommunicate ( > + MmData, > + sizeof (MmData), > + &NvRam2Info, > + sizeof (NvRam2Info) > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (NvRam2Info.Status == MM_SPINOR_RES_SUCCESS) { > + *NvRam2Base = NvRam2Info.NvRamBase; > + *NvRam2Size = NvRam2Info.NvRamSize; > + DEBUG (( > + DEBUG_INFO, > + "%a: NVRAM2 Base 0x%llx, Size 0x%lx\n", > + __FUNCTION__, > + *NvRam2Base, > + *NvRam2Size > + )); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Erase a region of the Flash. > + > + @param[in] ByteAddress Start address of the region. > + @param[in] Length Number of bytes to erase. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER Length is Zero. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashEraseCommand ( > + IN UINTN ByteAddress, > + IN UINT32 Length > + ) > +{ > + EFI_MM_COMMUNICATE_SPINOR_RESPONSE MmSpiNorRes; > + EFI_STATUS Status; > + UINT64 MmData[5]; > + > + if (Length == 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + MmData[0] = MM_SPINOR_FUNC_ERASE; > + MmData[1] = ByteAddress; > + MmData[2] = Length; > + > + Status = FlashMmCommunicate ( > + MmData, > + sizeof (MmData), > + &MmSpiNorRes, > + sizeof (MmSpiNorRes) > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (MmSpiNorRes.Status != MM_SPINOR_RES_SUCCESS) { > + DEBUG ((DEBUG_ERROR, "%a: Device error %llx\n", __FUNCTION__, > MmSpiNorRes.Status)); > + return EFI_DEVICE_ERROR; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Write data buffer to the Flash. > + > + @param[in] ByteAddress Start address of the region. > + @param[in] Buffer Pointer to the data buffer. > + @param[in] Length Number of bytes to write. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER Buffer is NULL or Length is Zero. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashWriteCommand ( > + IN UINTN ByteAddress, > + IN VOID *Buffer, > + IN UINT32 Length > + ) > +{ > + EFI_MM_COMMUNICATE_SPINOR_RESPONSE MmSpiNorRes; > + EFI_STATUS Status; > + UINT64 MmData[5]; > + UINTN Remain, NumWrite; > + UINTN Count = 0; > + > + if (Buffer == NULL || Length == 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + Remain = Length; > + while (Remain > 0) { > + NumWrite = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE > : Remain; > + > + MmData[0] = MM_SPINOR_FUNC_WRITE; > + MmData[1] = ByteAddress + Count; > + MmData[2] = NumWrite; > + MmData[3] = (UINT64)ConvertToPhysicalBuffer (Buffer + Count, NumWrite); > + > + Status = FlashMmCommunicate ( > + MmData, > + sizeof (MmData), > + &MmSpiNorRes, > + sizeof (MmSpiNorRes) > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (MmSpiNorRes.Status != MM_SPINOR_RES_SUCCESS) { > + DEBUG ((DEBUG_ERROR, "%a: Device error 0x%llx\n", __FUNCTION__, > MmSpiNorRes.Status)); > + return EFI_DEVICE_ERROR; > + } > + > + Remain -= NumWrite; > + Count += NumWrite; > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Read data from the Flash into Buffer. > + > + @param[in] ByteAddress Start address of the region. > + @param[out] Buffer Pointer to the data buffer. > + @param[in] Length Number of bytes to read. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER Buffer is NULL or Length is Zero. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashReadCommand ( > + IN UINTN ByteAddress, > + OUT VOID *Buffer, > + IN UINT32 Length > + ) > +{ > + EFI_MM_COMMUNICATE_SPINOR_RESPONSE MmSpiNorRes; > + EFI_STATUS Status; > + UINT64 MmData[5]; > + UINTN Remain, NumRead; > + UINTN Count = 0; > + > + if (Buffer == NULL || Length == 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + Remain = Length; > + while (Remain > 0) { > + NumRead = (Remain > EFI_MM_MAX_TMP_BUF_SIZE) ? EFI_MM_MAX_TMP_BUF_SIZE : > Remain; > + > + MmData[0] = MM_SPINOR_FUNC_READ; > + MmData[1] = ByteAddress + Count; > + MmData[2] = NumRead; > + MmData[3] = (UINT64)gFlashLibPhysicalBuffer; // Read data into the temp > buffer with specified virtual address > + > + Status = FlashMmCommunicate ( > + MmData, > + sizeof (MmData), > + &MmSpiNorRes, > + sizeof (MmSpiNorRes) > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (MmSpiNorRes.Status != MM_SPINOR_RES_SUCCESS) { > + DEBUG ((DEBUG_ERROR, "%a: Device error %llx\n", __FUNCTION__, > MmSpiNorRes.Status)); > + return EFI_DEVICE_ERROR; > + } > + > + // > + // Get data from the virtual address of the temp buffer. > + // > + CopyMem ((VOID *)(Buffer + Count), (VOID *)gFlashLibVirtualBuffer, > NumRead); > + Remain -= NumRead; > + Count += NumRead; > + } > + > + return EFI_SUCCESS; > +} > diff --git a/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.c > b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.c > new file mode 100644 > index 000000000000..2dcd13e08146 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.c > @@ -0,0 +1,137 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/MemoryAllocationLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/UefiRuntimeServicesTableLib.h> > +#include <Protocol/MmCommunication2.h> > + > +#include "FlashLibCommon.h" > + > +STATIC EFI_MM_COMMUNICATION2_PROTOCOL *mMmCommunicationProtocol = NULL; > + > +/** > + This is a notification function registered on > EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE > + event. It converts a pointer to a new virtual address. > + > + @param[in] Event Event whose notification function is being invoked. > + @param[in] Context Pointer to the notification function's context > +**/ > +VOID > +EFIAPI > +FlashLibAddressChangeEvent ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + gRT->ConvertPointer (0x0, (VOID **)&gFlashLibVirtualBuffer); > + gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol); > + > + gFlashLibRuntime = TRUE; > +} > + > +/** > + Constructor function of the RuntimeFlashLib. > + > + @param[in] ImageHandle The image handle. > + @param[in] SystemTable The system table. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +EFIAPI > +FlashLibConstructor ( > + IN EFI_HANDLE ImageHandle, > + IN EFI_SYSTEM_TABLE *SystemTable > + ) > +{ > + EFI_EVENT VirtualAddressChangeEvent = NULL; > + EFI_STATUS Status; > + > + gFlashLibPhysicalBuffer = AllocateRuntimeZeroPool > (EFI_MM_MAX_TMP_BUF_SIZE); > + gFlashLibVirtualBuffer = gFlashLibPhysicalBuffer; > + ASSERT (gFlashLibPhysicalBuffer != NULL); > + > + Status = gBS->LocateProtocol ( > + &gEfiMmCommunication2ProtocolGuid, > + NULL, > + (VOID **)&mMmCommunicationProtocol > + ); > + ASSERT_EFI_ERROR (Status); > + > + Status = gBS->CreateEvent ( > + EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, > + TPL_CALLBACK, > + FlashLibAddressChangeEvent, > + NULL, > + &VirtualAddressChangeEvent > + ); > + ASSERT_EFI_ERROR (Status); > + > + return Status; > +} > + > +/** > + Provides an interface to access the Flash services via MM interface. > + > + @param[in] Request Pointer to the request buffer > + @param[in] RequestDataSize Size of the request buffer. > + @param[out] Response Pointer to the response buffer > + @param[in] ResponseDataSize Size of the response buffer. > + > + @retval EFI_SUCCESS Operation succeeded. > + @retval EFI_INVALID_PARAMETER An invalid data parameter or an invalid > + combination of data parameters. > + @retval Others An error has occurred. > +**/ > +EFI_STATUS > +FlashMmCommunicate ( > + IN VOID *Request, > + IN UINT32 RequestDataSize, > + OUT VOID *Response, > + IN UINT32 ResponseDataSize > + ) > +{ > + EFI_MM_COMMUNICATE_REQUEST CommBuffer; > + EFI_STATUS Status; > + > + if (Request == NULL || RequestDataSize == 0 > + || RequestDataSize > EFI_MM_MAX_PAYLOAD_SIZE > + || (ResponseDataSize == 0 && Response == NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + CopyGuid (&CommBuffer.HeaderGuid, &gSpiNorMmGuid); > + CommBuffer.MessageLength = RequestDataSize; > + CopyMem (CommBuffer.Data, Request, RequestDataSize); > + > + if (mMmCommunicationProtocol == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = mMmCommunicationProtocol->Communicate ( > + mMmCommunicationProtocol, > + &CommBuffer, > + &CommBuffer, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + if (ResponseDataSize > 0) { > + CopyMem (Response, CommBuffer.Data, ResponseDataSize); > + } > + > + return EFI_SUCCESS; > +} > -- > 2.17.1 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#83856): https://edk2.groups.io/g/devel/message/83856 Mute This Topic: https://groups.io/mt/87123853/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
