From: Vu Nguyen <vunguyen@os.amperecomputing.com>
Provides functions to access the NVRAM, NVRAM2 and FailSafe region on the
Flash over MM communication.
Cc: Thang Nguyen <thang@os.amperecomputing.com>
Cc: Chuong Tran <chuong@os.amperecomputing.com>
Cc: Phong Vo <phong@os.amperecomputing.com>
Cc: Leif Lindholm <leif@nuviainc.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
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 (#83814): https://edk2.groups.io/g/devel/message/83814
Mute This Topic: https://groups.io/mt/87123853/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
On Wed, Nov 17, 2021 at 23:46:59 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen@os.amperecomputing.com>
>
> Provides functions to access the NVRAM, NVRAM2 and FailSafe region on the
> Flash over MM communication.
>
> Cc: Thang Nguyen <thang@os.amperecomputing.com>
> Cc: Chuong Tran <chuong@os.amperecomputing.com>
> Cc: Phong Vo <phong@os.amperecomputing.com>
> Cc: Leif Lindholm <leif@nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
>
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
Reviewed-by: Leif Lindholm <leif@nuviainc.com>
> ---
> 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/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.