From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) by mx.groups.io with SMTP id smtpd.web10.10811.1635247515609093723 for ; Tue, 26 Oct 2021 04:25:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20210112.gappssmtp.com header.s=20210112 header.b=EIafPF5x; spf=pass (domain: nuviainc.com, ip: 209.85.128.43, mailfrom: leif@nuviainc.com) Received: by mail-wm1-f43.google.com with SMTP id 67-20020a1c1946000000b0030d4c90fa87so1836237wmz.2 for ; Tue, 26 Oct 2021 04:25:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20210112.gappssmtp.com; s=20210112; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=O3pgm9zCMNiUazsso5LeU+rKcLZw9/G7vXplvl+MPZo=; b=EIafPF5xjYlOQ36VS9ij6/gSNLk9dn9yZ6xmT3ML6K95l44yELLv4pi03qXvaai6pM Abo7jmAHcAiZBxjKCJvV6+rZPXdTyh5PBCscfcWIXKh3lAGlaZr/bpYOiUTT34uGZv4u bUsFa/OmhcJ01/ARiElrQDHRwpeQ7Yu19waQHCJQVA38y8HqvIj/OUA4hTLP6Or8pYX2 vCEKHmDfWMIq5vgdNn3DcN6UAsJq1acS2XiC5iI6afv4+Bt9+QJSY6BG7CMO1er9KC6b WUwzrBU9KVnP6ZcFHlLwQIEVyXuIHKxlSGJD0Y90NlNwC15rgwdCJFdF0oiYOmUgjxDC CnJQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=O3pgm9zCMNiUazsso5LeU+rKcLZw9/G7vXplvl+MPZo=; b=aLYQ0qklF5Hb+kOrVmlyyvniYKS+ci9mlcwLHtWo5ZHg748kRgL2dJzFOhc+nsFL9J 39uTg/8f/JfgCLeR0UWDEIG6LsZvs23fJMJT+HcIW4zPi4+XsARjwCdDJP900Yp7GCeC K+7UQcGKi++n9gz/FBTq081Wc6zvPLgyPYuPgOVTZ6yZ+bxWi22OCrpDXBXyroDePbtM zbiQVFalWnMEfAWD5b0aPQ4cE8pOweLsnqmh7/2po6t4+eyJbdhfwqrfUcivvbXp8i2W tWGEl6kxeaMwS94kizZvjoQ49y+uxvz/Y0tWMf7EtYdSNBM+rjxfg2TKOh8Yno7NO+U6 OuyQ== X-Gm-Message-State: AOAM530KZriCeovhg9IcxV1zeVdDrBvvuZJFyZKuztSnhjJRvusn+FlJ wZP1T6qhKmvylXbX8PfCI/bp4w== X-Google-Smtp-Source: ABdhPJyrReIkdS8NAZy5shmZv/mhRxD7/PBCjJFzwsDT95jghQWv4r+7GofpRpBrxX24UVMse4chGw== X-Received: by 2002:a05:600c:1990:: with SMTP id t16mr27609686wmq.124.1635247513960; Tue, 26 Oct 2021 04:25:13 -0700 (PDT) Return-Path: Received: from leviathan (cpc92314-cmbg19-2-0-cust559.5-4.cable.virginm.net. [82.11.186.48]) by smtp.gmail.com with ESMTPSA id a15sm5876648wrt.48.2021.10.26.04.25.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 26 Oct 2021 04:25:13 -0700 (PDT) Date: Tue, 26 Oct 2021 12:25:11 +0100 From: "Leif Lindholm" To: Nhi Pham Cc: devel@edk2.groups.io, patches@amperecomputing.com, vunguyen@os.amperecomputing.com, Thang Nguyen , Chuong Tran , Phong Vo , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: Re: [edk2-platforms][PATCH v4 02/31] AmpereAltraPkg: Add FlashLib library instance Message-ID: <20211026112511.ah35wl6mw7dzyz25@leviathan> References: <20211022061809.31087-1-nhi@os.amperecomputing.com> <20211022061809.31087-3-nhi@os.amperecomputing.com> MIME-Version: 1.0 In-Reply-To: <20211022061809.31087-3-nhi@os.amperecomputing.com> Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Oct 22, 2021 at 13:17:40 +0700, Nhi Pham wrote: > From: Vu Nguyen > > Provides functions to access the NVRAM, NVRAM2 and FailSafe region on the > Flash over MM communication. > > Cc: Thang Nguyen > Cc: Chuong Tran > Cc: Phong Vo > Cc: Leif Lindholm > Cc: Michael D Kinney > Cc: Ard Biesheuvel > Cc: Nate DeSimone > > Signed-off-by: Nhi Pham > --- > 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 | 88 +++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c | 86 +++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.c | 372 ++++++++++++++++++++ > Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.c | 141 ++++++++ > 9 files changed, 882 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 3b33be6280ce..69a6caa56752 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.
> +# > +# 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.
> +# > +# 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.
> + > + 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..36ef9b8ca25d > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLibCommon.h > @@ -0,0 +1,88 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + 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() > + > +/** > + 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..e844a5c73f6c > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/FlashLib.c > @@ -0,0 +1,86 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > + > +#include "FlashLibCommon.h" > + > +extern UINT8 *mTempBufferPhysical; > +extern UINT8 *mTempBufferVirtual; Could you move these declarations to FlashLibCommon.h? I *am* a little bit concerned about globally visible symbols having such generic names. Add FlashLib to name? > + > +/** > + Constructor function of the FlashLib > + > + @retval EFI_SUCCESS The constructor executes successfully. > +**/ > +EFI_STATUS > +EFIAPI > +FlashLibConstructor ( > + VOID > + ) > +{ > + mTempBufferPhysical = AllocateZeroPool (EFI_MM_MAX_TMP_BUF_SIZE); > + mTempBufferVirtual = mTempBufferPhysical; > + ASSERT (mTempBufferPhysical != 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..08aab4ba9f0c > --- /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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > + > +#include "FlashLibCommon.h" > + > +BOOLEAN mIsEfiRuntime = FALSE; > +UINT8 *mTempBufferPhysical; > +UINT8 *mTempBufferVirtual; (Very generic globally visible symbol names.) > + > +/** > + 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 (mIsEfiRuntime) { > + ASSERT (VirtualPtr != NULL); > + CopyMem (mTempBufferVirtual, VirtualPtr, Size); > + return mTempBufferPhysical; > + } > + > + 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)mTempBufferPhysical; // 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 *)mTempBufferVirtual, 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..edea47313501 > --- /dev/null > +++ b/Silicon/Ampere/AmpereAltraPkg/Library/FlashLib/RuntimeFlashLib.c > @@ -0,0 +1,141 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > + > +#include "FlashLibCommon.h" > + > +extern BOOLEAN mIsEfiRuntime; > +extern UINT8 *mTempBufferPhysical; > +extern UINT8 *mTempBufferVirtual; (Have prototypes in FlashLibCommon.h, include "FlashLib" in globally visible symbol names.) / Leif > + > +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 **)&mTempBufferVirtual); > + gRT->ConvertPointer (0x0, (VOID **)&mMmCommunicationProtocol); > + > + mIsEfiRuntime = 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; > + > + mTempBufferPhysical = AllocateRuntimeZeroPool (EFI_MM_MAX_TMP_BUF_SIZE); > + mTempBufferVirtual = mTempBufferPhysical; > + ASSERT (mTempBufferPhysical != 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 >