[edk2-devel] [edk2-platforms][PATCH v5 02/30] AmpereAltraPkg: Add FlashLib library instance

Leif Lindholm leif at nuviainc.com
Thu Nov 18 12:50:47 UTC 2021


On Wed, Nov 17, 2021 at 23:46:59 +0700, Nhi Pham wrote:
> From: Vu Nguyen <vunguyen at os.amperecomputing.com>
> 
> Provides functions to access the NVRAM, NVRAM2 and FailSafe region on the
> Flash over MM communication.
> 
> Cc: Thang Nguyen <thang at os.amperecomputing.com>
> Cc: Chuong Tran <chuong at os.amperecomputing.com>
> Cc: Phong Vo <phong at os.amperecomputing.com>
> Cc: Leif Lindholm <leif at nuviainc.com>
> Cc: Michael D Kinney <michael.d.kinney at intel.com>
> Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
> Cc: Nate DeSimone <nathaniel.l.desimone at intel.com>
> 
> Signed-off-by: Nhi Pham <nhi at os.amperecomputing.com>

Reviewed-by: Leif Lindholm <leif at 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/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list