From: "Sami Mujawar" <sami.mujawar@arm.com>
To: Sahil Kaushal <Sahil.Kaushal@arm.com>, devel@edk2.groups.io
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>,
Leif Lindholm <quic_llindhol@quicinc.com>, sahil <sahil@arm.com>,
"nd@arm.com" <nd@arm.com>
Subject: Re: [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 12/14] Platform/ARM: Add CadenceQspiNorFlashDeviceLib for NorFlashDxe
Date: Thu, 16 May 2024 16:24:11 +0100 [thread overview]
Message-ID: <1674c97a-a13e-4ae6-ab79-e174b010140d@arm.com> (raw)
In-Reply-To: <20240423055638.1271531-13-Sahil.Kaushal@arm.com>
[-- Attachment #1: Type: text/plain, Size: 39005 bytes --]
Hi Sahil,
Thank you for this patch.
Please find my response inline marked [SAMI].
With that fixed,
Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
Regards,
Sami Mujawar
On 23/04/2024 06:56 am, Sahil Kaushal wrote:
> From: sahil<sahil@arm.com>
>
> In N1Sdp platform, the SoC is connected to IOFPGA which has a
> Cadence Quad SPI (QSPI) controller. This QSPI controller manages
> the flash chip device via QSPI bus.
>
> This patch adds CadenceQspiNorFlashDeviceLib which is used to
> manage and access the above configuration.
>
> Signed-off-by: sahil<sahil@arm.com>
> ---
> Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.inf | 32 +
> Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.h | 44 +
> Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.c | 1011 ++++++++++++++++++++
> 3 files changed, 1087 insertions(+)
>
> diff --git a/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.inf b/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.inf
> new file mode 100644
> index 000000000000..506876b62285
> --- /dev/null
> +++ b/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.inf
> @@ -0,0 +1,32 @@
> +#/** @file
>
> +#
>
> +# Component description file for CadenceQspiNorFlashDeviceLib Library
>
> +#
>
> +# Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
>
> +#
>
> +# SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +#
>
> +#**/
>
> +
>
> +[Defines]
>
> + INF_VERSION = 0x00010005
>
> + BASE_NAME = CadenceQspiNorFlashDeviceLib
>
> + FILE_GUID = ed172366-066b-4998-9b5e-ca7f385a170b
>
> + MODULE_TYPE = DXE_RUNTIME_DRIVER
>
> + VERSION_STRING = 1.0
>
> + LIBRARY_CLASS = NorFlashDeviceLib
>
> +
>
> +[Sources.common]
>
> + CadenceQspiNorFlashDeviceLib.c
>
> + CadenceQspiNorFlashDeviceLib.h
>
> +
>
> +[Packages]
>
> + MdePkg/MdePkg.dec
>
> + Platform/ARM/ARM.dec
>
> +
>
> +[LibraryClasses]
>
> + BaseLib
>
> + BaseMemoryLib
>
> + DebugLib
>
> + IoLib
>
> + TimerLib
>
> diff --git a/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.h b/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.h
> new file mode 100644
> index 000000000000..d43d27fe5eb4
> --- /dev/null
> +++ b/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.h
> @@ -0,0 +1,44 @@
> +/** @file
>
> +
>
> + Copyright (c) 2024, ARM Limited. All rights reserved.<BR>
>
> +
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#ifndef CADENCE_QSPI_NOR_FLASH_DEVICE_LIB_H_
>
> +#define CADENCE_QSPI_NOR_FLASH_DEVICE_LIB_H_
>
> +
>
> +#define NOR_FLASH_ERASE_RETRY 10
>
> +
>
> +// QSPI Controller defines
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSET 0x90
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_EXECUTE 0x01
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_ENABLE 0x01
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS 19
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS 16
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT 0x02
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS 24
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE 0x01
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_BYTE_3B 0x02
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS 23
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS 20
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C 0x8
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS 7
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES(x) ((x - 1) << CDNS_QSPI_FLASH_CMD_CTRL_REG_READBYTE_BIT_POS)
>
> +#define CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES(x) ((x - 1) << CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BYTE_BIT_POS)
>
> +
>
> +#define CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET 0xA0
>
> +
>
> +#define CDNS_QSPI_FLASH_CMD_ADDR_REG_OFFSET 0x94
>
> +
>
> +#define SPINOR_SR_WIP BIT0 // Write in progress
>
> +
>
> +#define SPINOR_OP_WREN 0x06 // Write enable
>
> +#define SPINOR_OP_BE_4K 0x20 // Erase 4KiB block
>
> +#define SPINOR_OP_RDID 0x9f // Read JEDEC ID
>
> +#define SPINOR_OP_RDSR 0x05 // Read status register
>
> +
>
> +#define SPINOR_SR_WIP_POLL_TIMEOUT_MS 1000u // Status Register read timeout
>
> +
>
> +#endif /* CADENCE_QSPI_NOR_FLASH_DEVICE_LIB_H_ */
>
> diff --git a/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.c b/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.c
> new file mode 100644
> index 000000000000..8a416e07f15e
> --- /dev/null
> +++ b/Platform/ARM/Library/CadenceQspiNorFlashDeviceLib/CadenceQspiNorFlashDeviceLib.c
> @@ -0,0 +1,1011 @@
> +/** @file
>
> +
>
> + Copyright (c) 2024 ARM Limited. All rights reserved.<BR>
>
> +
>
> + SPDX-License-Identifier: BSD-2-Clause-Patent
>
> +
>
> +**/
>
> +
>
> +#include <Library/BaseMemoryLib.h>
>
> +#include <Library/DebugLib.h>
>
> +#include <Library/IoLib.h>
>
> +#include <Library/MemoryAllocationLib.h>
>
> +#include <Library/NorFlashDeviceLib.h>
>
> +#include <Library/TimerLib.h>
>
> +#include <Library/UefiLib.h>
>
> +
>
> +#include "CadenceQspiNorFlashDeviceLib.h"
>
> +
>
> +/**
>
> + Execute Flash cmd ctrl and Read Status.
>
> +
>
> + @param[in] Instance NOR flash Instance.
>
> + @param[in] Val Value to be written to Flash cmd ctrl Register.
>
> +
>
> + @retval EFI_SUCCESS Request is executed successfully.
>
> +
>
> +**/
>
> +STATIC
>
> +EFI_STATUS
>
> +CdnsQspiExecuteCommand (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINT32 Val
>
> + )
>
> +{
>
> + // Set the command
>
> + MmioWrite32 (
>
> + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSET,
>
> + Val
>
> + );
>
> + // Execute the command
>
> + MmioWrite32 (
>
> + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSET,
>
> + Val | CDNS_QSPI_FLASH_CMD_CTRL_REG_EXECUTE
>
> + );
>
> +
>
> + // Wait until command has been executed
>
> + while (
>
> + (MmioRead32 (
>
> + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_CTRL_REG_OFFSET
>
> + ) & CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT) ==
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT
>
> + )
>
> + {
>
> + continue;
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Converts milliseconds into number of ticks of the performance counter.
>
> +
>
> + @param[in] Milliseconds Milliseconds to convert into ticks.
>
> +
>
> + @retval Milliseconds expressed as number of ticks.
>
> +
>
> +**/
>
> +STATIC
>
> +UINT64
>
> +MilliSecondsToTicks (
>
> + IN UINTN Milliseconds
>
> + )
>
> +{
>
> + CONST UINT64 NanoSecondsPerTick = GetTimeInNanoSecond (1);
>
> +
>
> + return (Milliseconds * 1000000) / NanoSecondsPerTick;
>
> +}
>
> +
>
> +/**
>
> + Poll Status register for NOR flash erase/write completion.
>
> +
>
> + @param[in] Instance NOR flash Instance.
>
> +
>
> + @retval EFI_SUCCESS Request is executed successfully.
>
> + @retval EFI_TIMEOUT Operation timed out.
>
> + @retval EFI_DEVICE_ERROR Controller operartion failed.
>
> +
>
> +**/
>
> +STATIC
>
> +EFI_STATUS
>
> +NorFlashPollStatusRegister (
>
> + IN NOR_FLASH_INSTANCE *Instance
>
> + )
>
> +{
>
> + BOOLEAN SRegDone;
>
> + UINT32 val;
>
> +
>
> + val = (SPINOR_OP_RDSR << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS) |
>
> + (CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE <<
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS) |
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES (1) |
>
> + (CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_8C <<
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_DUMMY_BIT_POS);
>
> +
>
> + CONST UINT64 TickOut =
>
> + GetPerformanceCounter () +
>
> + MilliSecondsToTicks (SPINOR_SR_WIP_POLL_TIMEOUT_MS);
>
> +
>
> + do {
>
> + if (GetPerformanceCounter () > TickOut) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashPollStatusRegister: Timeout waiting for erase/write.\n"
>
> + ));
>
> + return EFI_TIMEOUT;
>
> + }
>
> +
>
> + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
>
> + return EFI_DEVICE_ERROR;
[SAMI] CdnsQspiExecuteCommand() always wiats in a loop until the
CDNS_QSPI_FLASH_CMD_CTRL_REG_STATUS_BIT bit is set and returns success.
Should CdnsQspiExecuteCommand() implement a timeout? Can you check,
please? Otherwise these checks do not really make sense.
>
> + }
>
> +
>
> + SRegDone =
>
> + (MmioRead8 (
>
> + Instance->HostRegisterBaseAddress +
>
> + CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET
>
> + )
>
> + & SPINOR_SR_WIP
>
> + ) == 0;
>
> + } while (!SRegDone);
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Check whether NOR flash opertions are Locked.
>
> +
>
> + @param[in] Instance NOR flash Instance.
>
> + @param[in] BlockAddress BlockAddress in NOR flash device.
>
> +
>
> + @retval FALSE If NOR flash is not locked.
>
> +**/
>
> +STATIC
>
> +BOOLEAN
>
> +NorFlashBlockIsLocked (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINTN BlockAddress
>
> + )
>
> +{
>
> + return FALSE;
>
> +}
>
> +
>
> +/**
>
> + Unlock NOR flash operations on given block.
>
> +
>
> + @param[in] Instance NOR flash instance.
>
> + @param[in] BlockAddress BlockAddress in NOR flash device.
>
> +
>
> + @retval EFI_SUCCESS NOR flash operations is unlocked.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashUnlockSingleBlock (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINTN BlockAddress
>
> + )
>
> +{
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Unlock NOR flash operations if it is necessary.
>
> +
>
> + @param[in] Instance NOR flash instance.
>
> + @param[in] BlockAddress BlockAddress in NOR flash device.
>
> +
>
> + @retval EFI_SUCCESS Request is executed successfully.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashUnlockSingleBlockIfNecessary (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINTN BlockAddress
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> +
>
> + Status = EFI_SUCCESS;
>
> +
>
> + if (!NorFlashBlockIsLocked (Instance, BlockAddress)) {
>
> + Status = NorFlashUnlockSingleBlock (Instance, BlockAddress);
>
> + }
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Enable write to NOR flash device.
>
> +
>
> + @param[in] Instance NOR flash instance.
>
> +
>
> + @retval EFI_SUCCESS Request is executed successfully.
>
> + @retval EFI_DEVICE_ERROR The device reported an error.
>
> +**/
>
> +STATIC
>
> +EFI_STATUS
>
> +NorFlashEnableWrite (
>
> + IN NOR_FLASH_INSTANCE *Instance
>
> + )
>
> +{
>
> + UINT32 val;
>
> +
>
> + DEBUG ((DEBUG_INFO, "NorFlashEnableWrite()\n"));
>
> + val = (SPINOR_OP_WREN << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS);
>
> + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + The following function presumes that the block has already been unlocked.
>
> +
>
> + @param[in] Instance NOR flash instance.
>
> + @param[in] BlockAddress Block address within the variable region.
>
> +
>
> + @retval EFI_SUCCESS Request is executed successfully.
>
> + @retval EFI_DEVICE_ERROR The device reported an error.
>
> + **/
>
> +EFI_STATUS
>
> +NorFlashEraseSingleBlock (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINTN BlockAddress
>
> + )
>
> +{
>
> + UINT32 DevConfigVal;
>
> + UINT32 EraseOffset;
>
> +
>
> + EraseOffset = 0x0;
>
> +
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashEraseSingleBlock(BlockAddress=0x%08x)\n",
>
> + BlockAddress
>
> + ));
>
> +
>
> + if (EFI_ERROR (NorFlashEnableWrite (Instance))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + EraseOffset = BlockAddress - Instance->DeviceBaseAddress;
>
> +
>
> + MmioWrite32 (
>
> + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_ADDR_REG_OFFSET,
>
> + EraseOffset
>
> + );
>
> +
>
> + DevConfigVal = (SPINOR_OP_BE_4K << CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS) |
>
> + (CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_ENABLE <<
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_ADDR_BIT_POS) |
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_ADDR_BYTES (3);
>
> +
>
> + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, DevConfigVal))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + This function unlock and erase an entire NOR Flash block.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] BlockAddress Block address within the variable store region.
>
> +
>
> + @retval EFI_SUCCESS The erase and unlock successfully completed.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashUnlockAndEraseSingleBlock (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINTN BlockAddress
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN Index;
>
> + EFI_TPL OriginalTPL;
>
> +
>
> + NorFlashLock (&OriginalTPL);
>
> +
>
> + Index = 0;
>
> + do {
>
> + // Unlock the block if we have to
>
> + Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
>
> + if (EFI_ERROR (Status)) {
>
> + break;
>
> + }
>
> +
>
> + Status = NorFlashEraseSingleBlock (Instance, BlockAddress);
>
> + if (EFI_ERROR (Status)) {
>
> + break;
>
> + }
>
> +
>
> + Index++;
>
> + } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED));
>
> +
>
> + if (Index == NOR_FLASH_ERASE_RETRY) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "EraseSingleBlock(BlockAddress=0x%08x: Block Locked Error "
>
> + "(try to erase %d times)\n",
>
> + BlockAddress,
>
> + Index
>
> + ));
>
> + }
>
> +
>
> + NorFlashUnlock (OriginalTPL);
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Write a single word to given location.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] WordAddress The address in NOR flash to write given word.
>
> + @param[in] WriteData The data to write into NOR flash location.
>
> +
>
> + @retval EFI_SUCCESS The write is completed.
>
> + @retval EFI_DEVICE_ERROR The device reported an error.
[SAMI] any other error code?
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashWriteSingleWord (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN UINTN WordAddress,
>
> + IN UINT32 WriteData
>
> + )
>
> +{
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashWriteSingleWord(WordAddress=0x%08x, WriteData=0x%08x)\n",
>
> + WordAddress,
>
> + WriteData
>
> + ));
>
> +
>
> + if (EFI_ERROR (NorFlashEnableWrite (Instance))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + MmioWrite32 (WordAddress, WriteData);
>
> + if (EFI_ERROR (NorFlashPollStatusRegister (Instance))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Write a full block to given location.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] Lba The logical block address in NOR flash.
>
> + @param[in] DataBuffer The data to write into NOR flash location.
>
> + @param[in] BlockSizeInWords The number of bytes to write.
>
> +
>
> + @retval EFI_SUCCESS The write is completed.
[SAMI] any other error code? I tihink EFI_DEVICE_ERROR can be returned.
Can you check the other functions in the file as well, please?
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashWriteFullBlock (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN EFI_LBA Lba,
>
> + IN UINT32 *DataBuffer,
>
> + IN UINT32 BlockSizeInWords
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINTN WordAddress;
>
> + UINT32 WordIndex;
>
> + UINTN BlockAddress;
>
> + EFI_TPL OriginalTPL;
>
> +
>
> + Status = EFI_SUCCESS;
>
> +
>
> + // Get the physical address of the block
>
> + BlockAddress = GET_NOR_BLOCK_ADDRESS (
>
> + Instance->RegionBaseAddress,
>
> + Lba,
>
> + BlockSizeInWords * 4
>
> + );
>
> +
>
> + // Start writing from the first address at the start of the block
>
> + WordAddress = BlockAddress;
>
> +
>
> + NorFlashLock (&OriginalTPL);
>
> +
>
> + Status = NorFlashUnlockAndEraseSingleBlock (Instance, BlockAddress);
>
> + if (EFI_ERROR (Status)) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "WriteSingleBlock: ERROR - Failed to Unlock and Erase the single "
>
> + "block at 0x%X\n",
>
> + BlockAddress
>
> + ));
>
> + goto EXIT;
[SAMI] According to the edk2 coding guidelines words with all capital
letters are intended for macros. Change EXIT => exit_handler.
I know the P30 device lib has this issue as well. But atleast we
should not repeat this again here.
[/SAMI]
>
> + }
>
> +
>
> + for (WordIndex = 0;
>
> + WordIndex < BlockSizeInWords;
>
> + WordIndex++, DataBuffer++, WordAddress += 4)
>
> + {
>
> + Status = NorFlashWriteSingleWord (Instance, WordAddress, *DataBuffer);
>
> + if (EFI_ERROR (Status)) {
>
> + goto EXIT;
>
> + }
>
> + }
>
> +
>
> +EXIT:
>
> + NorFlashUnlock (OriginalTPL);
>
> +
>
> + if (EFI_ERROR (Status)) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NOR FLASH Programming [WriteSingleBlock] failed at address 0x%08x. "
>
> + "Exit Status = %r.\n",
>
> + WordAddress,
>
> + Status
>
> + ));
>
> + }
>
> +
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Write a full block.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] Lba The starting logical block index.
>
> + @param[in] BufferSizeInBytes The number of bytes to read.
>
> + @param[in] Buffer The pointer to a caller-allocated buffer that
>
> + contains the source for the write.
>
> +
>
> + @retval EFI_SUCCESS The write is completed.
>
> + @retval EFI_INVALID_PARAMETER Invalid parameters passed.
>
> + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size passed.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashWriteBlocks (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN EFI_LBA Lba,
>
> + IN UINTN BufferSizeInBytes,
>
> + IN VOID *Buffer
>
> + )
>
> +{
>
> + UINT32 *pWriteBuffer;
[SAMI] The 'p' prefix does not comply with the edk2 coding standard. Can
you check, please?
>
> + EFI_STATUS Status;
>
> + EFI_LBA CurrentBlock;
>
> + UINT32 BlockSizeInWords;
>
> + UINT32 NumBlocks;
>
> + UINT32 BlockCount;
>
> +
>
> + Status = EFI_SUCCESS;
>
> + // The buffer must be valid
>
> + if (Buffer == NULL) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // We must have some bytes to read
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashWriteBlocks: BufferSizeInBytes=0x%x\n",
>
> + BufferSizeInBytes
>
> + ));
>
> + if (BufferSizeInBytes == 0) {
>
> + return EFI_BAD_BUFFER_SIZE;
>
> + }
>
> +
>
> + // The size of the buffer must be a multiple of the block size
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashWriteBlocks: BlockSize in bytes =0x%x\n",
>
> + Instance->Media.BlockSize
>
> + ));
>
> + if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
>
> + return EFI_BAD_BUFFER_SIZE;
>
> + }
>
> +
>
> + // All blocks must be within the device
>
> + NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize;
>
> +
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashWriteBlocks: NumBlocks=%d, LastBlock=%ld, Lba=%ld.\n",
>
> + NumBlocks,
>
> + Instance->Media.LastBlock,
>
> + Lba
>
> + ));
>
> +
>
> + if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashWriteBlocks: ERROR - Write will exceed last block.\n"
>
> + ));
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + ASSERT (((UINTN)Buffer % sizeof (UINT32)) == 0);
[SAMI] Is this an alignment requirement for the Buffer? what happens in
release build?
>
> +
>
> + BlockSizeInWords = Instance->Media.BlockSize / 4;
>
> +
>
> + // Because the target *Buffer is a pointer to VOID, we must put
>
> + // all the data into a pointer to a proper data type, so use *ReadBuffer
[SAMI] *ReadBuffer => *WriteBuffer ?
>
> + pWriteBuffer = (UINT32 *)Buffer;
>
> +
>
> + CurrentBlock = Lba;
>
> + for (BlockCount = 0;
>
> + BlockCount < NumBlocks;
>
> + BlockCount++, CurrentBlock++, pWriteBuffer += BlockSizeInWords)
>
> + {
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashWriteBlocks: Writing block #%d\n",
>
> + (UINTN)CurrentBlock
>
> + ));
>
> +
>
> + Status = NorFlashWriteFullBlock (
>
> + Instance,
>
> + CurrentBlock,
>
> + pWriteBuffer,
>
> + BlockSizeInWords
>
> + );
>
> +
>
> + if (EFI_ERROR (Status)) {
>
> + break;
>
> + }
>
> + }
>
> +
>
> + DEBUG ((DEBUG_INFO, "NorFlashWriteBlocks: Exit Status = %r.\n", Status));
>
> + return Status;
>
> +}
>
> +
>
> +/**
>
> + Read a full block.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] Lba The starting logical block index to read from.
>
> + @param[in] BufferSizeInBytes The number of bytes to read.
>
> + @param[out] Buffer The pointer to a caller-allocated buffer that
>
> + should be copied with read data.
>
> +
>
> + @retval EFI_SUCCESS The read is completed.
>
> + @retval EFI_INVALID_PARAMETER Invalid parameters passed.
>
> + @retval EFI_BAD_BUFFER_SIZE Invalid buffer size passed.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashReadBlocks (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN EFI_LBA Lba,
>
> + IN UINTN BufferSizeInBytes,
>
> + OUT VOID *Buffer
>
> + )
>
> +{
>
> + UINT32 NumBlocks;
>
> + UINTN StartAddress;
>
> +
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashReadBlocks: BufferSize=0x%xB BlockSize=0x%xB LastBlock=%ld, "
>
> + "Lba=%ld.\n",
>
> + BufferSizeInBytes,
>
> + Instance->Media.BlockSize,
>
> + Instance->Media.LastBlock,
>
> + Lba
>
> + ));
>
> +
>
> + // The buffer must be valid
>
> + if (Buffer == NULL) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // Return if we do not have any byte to read
>
> + if (BufferSizeInBytes == 0) {
>
> + return EFI_SUCCESS;
>
> + }
>
> +
>
> + // The size of the buffer must be a multiple of the block size
>
> + if ((BufferSizeInBytes % Instance->Media.BlockSize) != 0) {
>
> + return EFI_BAD_BUFFER_SIZE;
>
> + }
>
> +
>
> + NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize;
>
> +
>
> + if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashReadBlocks: ERROR - Read will exceed last block\n"
>
> + ));
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // Get the address to start reading from
>
> + StartAddress = GET_NOR_BLOCK_ADDRESS (
>
> + Instance->RegionBaseAddress,
>
> + Lba,
>
> + Instance->Media.BlockSize
>
> + );
>
> +
>
> + // Readout the data
>
> + CopyMem (Buffer, (UINTN *)StartAddress, BufferSizeInBytes);
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Read from nor flash.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] Lba The starting logical block index to read from.
>
> + @param[in] Offset Offset into the block at which to begin reading.
>
> + @param[in] BufferSizeInBytes The number of bytes to read.
>
> + @param[out] Buffer The pointer to a caller-allocated buffer that
>
> + should copied with read data.
>
> +
>
> + @retval EFI_SUCCESS The read is completed.
>
> + @retval EFI_INVALID_PARAMETER Invalid parameters passed.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashRead (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN EFI_LBA Lba,
>
> + IN UINTN Offset,
>
> + IN UINTN BufferSizeInBytes,
>
> + OUT VOID *Buffer
>
> + )
>
> +{
>
> + UINTN StartAddress;
>
> +
>
> + // The buffer must be valid
>
> + if (Buffer == NULL) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // Return if we do not have any byte to read
>
> + if (BufferSizeInBytes == 0) {
>
> + return EFI_SUCCESS;
>
> + }
>
> +
>
> + if (((Lba * Instance->Media.BlockSize) + Offset + BufferSizeInBytes) >
>
> + Instance->Size)
>
> + {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashRead: ERROR - Read will exceed device size.\n"
>
> + ));
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + // Get the address to start reading from
>
> + StartAddress = GET_NOR_BLOCK_ADDRESS (
>
> + Instance->RegionBaseAddress,
>
> + Lba,
>
> + Instance->Media.BlockSize
>
> + );
>
> +
>
> + // Readout the data
>
> + CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes);
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Write a full or portion of a block.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[in] Lba The starting logical block index to write to.
>
> + @param[in] Offset Offset into the block at which to begin writing.
>
> + @param[in, out] NumBytes The total size of the buffer.
>
> + @param[in] Buffer The pointer to a caller-allocated buffer that
>
> + contains the source for the write.
>
> +
>
> + @retval EFI_SUCCESS The write is completed.
>
> + @retval EFI_OUT_OF_RESOURCES Invalid Buffer passed.
>
> + @retval EFI_BAD_BUFFER_SIZE Buffer size not enough.
>
> + @retval EFI_DEVICE_ERROR The device reported an error.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashWriteSingleBlock (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + IN EFI_LBA Lba,
>
> + IN UINTN Offset,
>
> + IN OUT UINTN *NumBytes,
>
> + IN UINT8 *Buffer
>
> + )
>
> +{
>
> + EFI_STATUS Status;
>
> + UINT32 Tmp;
>
> + UINT32 TmpBuf;
>
> + UINT32 WordToWrite;
>
> + UINT32 Mask;
>
> + BOOLEAN DoErase;
>
> + UINTN BytesToWrite;
>
> + UINTN CurOffset;
>
> + UINTN WordAddr;
>
> + UINTN BlockSize;
>
> + UINTN BlockAddress;
>
> + UINTN PrevBlockAddress;
>
> +
>
> + if (Buffer == NULL) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashWriteSingleBlock: ERROR - Buffer is invalid\n"
>
> + ));
>
> + return EFI_OUT_OF_RESOURCES;
>
> + }
>
> +
>
> + PrevBlockAddress = 0;
>
> +
[SAMI] Validate that NumBytes is not NULL.
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, "
>
> + "*NumBytes=0x%x, Buffer @ 0x%08x)\n",
>
> + Lba,
>
> + Offset,
>
> + *NumBytes,
>
> + Buffer
>
> + ));
>
> +
>
> + // Localise the block size to avoid de-referencing pointers all the time
>
> + BlockSize = Instance->Media.BlockSize;
>
> +
>
> + // The write must not span block boundaries.
>
> + // We need to check each variable individually because adding two large
>
> + // values together overflows.
>
> + if ((Offset >= BlockSize) ||
>
> + (*NumBytes > BlockSize) ||
>
> + ((Offset + *NumBytes) > BlockSize))
>
> + {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: "
>
> + "(Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n",
>
> + Offset,
>
> + *NumBytes,
>
> + BlockSize
>
> + ));
>
> + return EFI_BAD_BUFFER_SIZE;
>
> + }
>
> +
>
> + // We must have some bytes to write
>
> + if (*NumBytes == 0) {
>
> + DEBUG ((
>
> + DEBUG_ERROR,
>
> + "NorFlashWriteSingleBlock: ERROR - EFI_BAD_BUFFER_SIZE: "
>
> + "(Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n",
>
> + Offset,
>
> + *NumBytes,
>
> + BlockSize
>
> + ));
>
> + return EFI_BAD_BUFFER_SIZE;
>
> + }
>
> +
>
> + // Pick 128bytes as a good start for word operations as opposed to erasing the
>
> + // block and writing the data regardless if an erase is really needed.
>
> + // It looks like most individual NV variable writes are smaller than 128bytes.
>
> + if (*NumBytes <= 128) {
>
> + // Check to see if we need to erase before programming the data into NOR.
>
> + // If the destination bits are only changing from 1s to 0s we can just write.
>
> + // After a block is erased all bits in the block is set to 1.
>
> + // If any byte requires us to erase we just give up and rewrite all of it.
>
> + DoErase = FALSE;
>
> + BytesToWrite = *NumBytes;
>
> + CurOffset = Offset;
>
> +
>
> + while (BytesToWrite > 0) {
>
> + // Read full word from NOR, splice as required. A word is the smallest
>
> + // unit we can write.
>
> + Status = NorFlashRead (
>
> + Instance,
>
> + Lba,
>
> + CurOffset & ~(0x3),
>
> + sizeof (Tmp),
>
> + &Tmp
>
> + );
>
> + if (EFI_ERROR (Status)) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + // Physical address of word in NOR to write.
>
> + WordAddr = (CurOffset & ~(0x3)) +
>
> + GET_NOR_BLOCK_ADDRESS (
>
> + Instance->RegionBaseAddress,
>
> + Lba,
>
> + BlockSize
>
> + );
>
> +
>
> + // The word of data that is to be written.
>
> + TmpBuf = ReadUnaligned32 (
>
> + (UINT32 *)(Buffer + (*NumBytes - BytesToWrite))
>
> + );
>
> +
>
> + // First do word aligned chunks.
>
> + if ((CurOffset & 0x3) == 0) {
>
> + if (BytesToWrite >= 4) {
>
> + // Is the destination still in 'erased' state?
>
> + if (~Tmp != 0) {
>
> + // Check to see if we are only changing bits to zero.
>
> + if ((Tmp ^ TmpBuf) & TmpBuf) {
>
> + DoErase = TRUE;
>
> + break;
>
> + }
>
> + }
>
> +
>
> + // Write this word to NOR
>
> + WordToWrite = TmpBuf;
>
> + CurOffset += sizeof (TmpBuf);
>
> + BytesToWrite -= sizeof (TmpBuf);
>
> + } else {
>
> + // BytesToWrite < 4. Do small writes and left-overs
>
> + Mask = ~((~0) << (BytesToWrite * 8));
>
> + // Mask out the bytes we want.
>
> + TmpBuf &= Mask;
>
> + // Is the destination still in 'erased' state?
>
> + if ((Tmp & Mask) != Mask) {
>
> + // Check to see if we are only changing bits to zero.
>
> + if ((Tmp ^ TmpBuf) & TmpBuf) {
>
> + DoErase = TRUE;
>
> + break;
>
> + }
>
> + }
>
> +
>
> + // Merge old and new data. Write merged word to NOR
>
> + WordToWrite = (Tmp & ~Mask) | TmpBuf;
>
> + CurOffset += BytesToWrite;
>
> + BytesToWrite = 0;
>
> + }
>
> + } else {
>
> + // Do multiple words, but starting unaligned.
>
> + if (BytesToWrite > (4 - (CurOffset & 0x3))) {
>
> + Mask = ((~0) << ((CurOffset & 0x3) * 8));
>
> + // Mask out the bytes we want.
>
> + TmpBuf &= Mask;
>
> + // Is the destination still in 'erased' state?
>
> + if ((Tmp & Mask) != Mask) {
>
> + // Check to see if we are only changing bits to zero.
>
> + if ((Tmp ^ TmpBuf) & TmpBuf) {
>
> + DoErase = TRUE;
>
> + break;
>
> + }
>
> + }
>
> +
>
> + // Merge old and new data. Write merged word to NOR
>
> + WordToWrite = (Tmp & ~Mask) | TmpBuf;
>
> + BytesToWrite -= (4 - (CurOffset & 0x3));
>
> + CurOffset += (4 - (CurOffset & 0x3));
>
> + } else {
>
> + // Unaligned and fits in one word.
>
> + Mask = (~((~0) << (BytesToWrite * 8))) << ((CurOffset & 0x3) * 8);
>
> + // Mask out the bytes we want.
>
> + TmpBuf = (TmpBuf << ((CurOffset & 0x3) * 8)) & Mask;
>
> + // Is the destination still in 'erased' state?
>
> + if ((Tmp & Mask) != Mask) {
>
> + // Check to see if we are only changing bits to zero.
>
> + if ((Tmp ^ TmpBuf) & TmpBuf) {
>
> + DoErase = TRUE;
>
> + break;
>
> + }
>
> + }
>
> +
>
> + // Merge old and new data. Write merged word to NOR
>
> + WordToWrite = (Tmp & ~Mask) | TmpBuf;
>
> + CurOffset += BytesToWrite;
>
> + BytesToWrite = 0;
>
> + }
>
> + }
>
> +
>
> + BlockAddress = GET_NOR_BLOCK_ADDRESS (
>
> + Instance->RegionBaseAddress,
>
> + Lba,
>
> + BlockSize
>
> + );
>
> + if (BlockAddress != PrevBlockAddress) {
>
> + Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress);
>
> + if (EFI_ERROR (Status)) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + PrevBlockAddress = BlockAddress;
>
> + }
>
> +
>
> + Status = NorFlashWriteSingleWord (Instance, WordAddr, WordToWrite);
>
> + if (EFI_ERROR (Status)) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> + }
>
> +
>
> + // Exit if we got here and could write all the data. Otherwise do the
>
> + // Erase-Write cycle.
>
> + if (!DoErase) {
>
> + return EFI_SUCCESS;
>
> + }
>
> + }
>
> +
>
> + // Check we did get some memory. Buffer is BlockSize.
>
> + if (Instance->ShadowBuffer == NULL) {
>
> + DEBUG ((DEBUG_ERROR, "FvbWrite: ERROR - Buffer not ready\n"));
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + // Read NOR Flash data into shadow buffer
>
> + Status = NorFlashReadBlocks (
>
> + Instance,
>
> + Lba,
>
> + BlockSize,
>
> + Instance->ShadowBuffer
>
> + );
>
> + if (EFI_ERROR (Status)) {
>
> + // Return one of the pre-approved error statuses
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + // Put the data at the appropriate location inside the buffer area
>
> + CopyMem (
>
> + (VOID *)((UINTN)Instance->ShadowBuffer + Offset),
>
> + Buffer,
>
> + *NumBytes
>
> + );
>
> +
>
> + // Write the modified buffer back to the NorFlash
>
> + Status = NorFlashWriteBlocks (
>
> + Instance,
>
> + Lba,
>
> + BlockSize,
>
> + Instance->ShadowBuffer
>
> + );
>
> + if (EFI_ERROR (Status)) {
>
> + // Return one of the pre-approved error statuses
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Read JEDEC ID of NOR flash device.
>
> +
>
> + @param[in] Instance NOR flash Instance of variable store region.
>
> + @param[out] JedecId JEDEC ID of NOR flash device.
>
> + Maximum length of JedecId can be upto 6 bytes
>
> + @retval EFI_SUCCESS The write is completed.
>
> + @retval EFI_UNSUPPORTED JEDEC ID retrievel not implemented.
>
> + @retval EFI_DEVICE_ERROR Failed to fetch JEDEC ID.
>
> + @retval EFI_INVALID_PARAMETER Invalid parameters passed.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashReadID (
>
> + IN NOR_FLASH_INSTANCE *Instance,
>
> + OUT UINT8 *JedecId
>
> + )
>
> +{
>
> + UINT32 val;
>
> +
>
> + if ((Instance == NULL) || (JedecId == NULL)) {
>
> + return EFI_INVALID_PARAMETER;
>
> + }
>
> +
>
> + val = (SPINOR_OP_RDID <<
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_OPCODE_BIT_POS) |
>
> + (CDNS_QSPI_FLASH_CMD_CTRL_REG_READ_ENABLE <<
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_READEN_BIT_POS) |
>
> + CDNS_QSPI_FLASH_CMD_CTRL_REG_NUM_DATA_BYTES (3);
>
> +
>
> + if (EFI_ERROR (CdnsQspiExecuteCommand (Instance, val))) {
>
> + return EFI_DEVICE_ERROR;
>
> + }
>
> +
>
> + val = MmioRead32 (
>
> + Instance->HostRegisterBaseAddress + CDNS_QSPI_FLASH_CMD_READ_DATA_REG_OFFSET
>
> + );
>
> +
>
> + // Manu.ID field
>
> + JedecId[0] = (UINT8)val;
>
> + // Type field
>
> + JedecId[1] = (UINT8)(val >> 8);
>
> + // Capacity field
>
> + JedecId[2] = (UINT8)(val >> 16);
>
> +
>
> + DEBUG ((
>
> + DEBUG_INFO,
>
> + "Nor flash detected, Jedec ID, Manu.Id=%x Type=%x Capacity=%x \n",
>
> + JedecId[0],
>
> + JedecId[1],
>
> + JedecId[2]
>
> + ));
>
> +
>
> + return EFI_SUCCESS;
>
> +}
>
> +
>
> +/**
>
> + Nor Flash Reset
>
> +
>
> + @param[in] Instance NOR flash instance.
>
> +
>
> + @retval EFI_SUCCESS Return success on every call.
>
> +**/
>
> +EFI_STATUS
>
> +NorFlashReset (
>
> + IN NOR_FLASH_INSTANCE *Instance
>
> + )
>
> +{
>
> + return EFI_SUCCESS;
>
> +}
>
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#118968): https://edk2.groups.io/g/devel/message/118968
Mute This Topic: https://groups.io/mt/105690947/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
[-- Attachment #2: Type: text/html, Size: 39097 bytes --]
next prev parent reply other threads:[~2024-05-16 15:24 UTC|newest]
Thread overview: 50+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-04-23 5:56 [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 00/14] Split NorFlashDxe driver and add CadenceQspiNorFlashDeviceLib library Sahil Kaushal
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 01/14] Platform/ARM/NorFlashDxe: Move DiskIo related functions out of NorFlash.c Sahil Kaushal
2024-04-24 9:49 ` levi.yun
2024-05-16 15:17 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 02/14] Platform/ARM/NorFlashDxe: Move NorFlashVirtualNotifyEvent Sahil Kaushal
2024-05-16 15:17 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 03/14] Platform/ARM/NorFlashDxe: Add NorFlashCommon.h header file Sahil Kaushal
2024-04-24 9:49 ` levi.yun
2024-05-16 15:17 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 04/14] Platform/ARM/NorFlashDxe: Move flash specific functions to NorFlash.c Sahil Kaushal
2024-04-24 9:49 ` levi.yun
2024-05-16 15:17 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 05/14] Platform/ARM: Create NorFlashDeviceLib library interface for flash specific functions Sahil Kaushal
2024-04-24 9:50 ` levi.yun
2024-05-16 15:18 ` Sami Mujawar
2024-05-21 8:37 ` sahil
2024-05-21 14:05 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 06/14] Platform/ARM: Add P30NorFlashDeviceLib Library Sahil Kaushal
2024-04-24 9:49 ` levi.yun
2024-05-16 15:18 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 07/14] Platform/ARM/NorFlashDxe: Switch from NorFlash.c to NorFlashDeviceLib Sahil Kaushal
2024-04-24 9:50 ` levi.yun
2024-05-16 15:18 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 08/14] Platform/ARM: Add HostRegisterBaseAddress variable Sahil Kaushal
2024-04-24 9:50 ` levi.yun
2024-05-16 15:22 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 09/14] Platform/ARM: Add optional provision to fetch and print NOR Flash info Sahil Kaushal
2024-04-24 9:51 ` levi.yun
2024-05-16 15:23 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 10/14] Silicon/ARM/NeoverseN1Soc: Enable SCP QSPI flash region Sahil Kaushal
2024-04-24 9:50 ` levi.yun
2024-05-16 15:23 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 11/14] Silicon/ARM/NeoverseN1Soc: NOR flash library for N1Sdp Sahil Kaushal
2024-04-24 9:50 ` levi.yun
2024-05-16 15:23 ` Sami Mujawar
2024-05-21 9:24 ` sahil
2024-05-21 12:59 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 12/14] Platform/ARM: Add CadenceQspiNorFlashDeviceLib for NorFlashDxe Sahil Kaushal
2024-04-24 9:55 ` levi.yun
2024-05-02 13:17 ` PierreGondois
2024-05-09 6:25 ` sahil
2024-05-16 15:25 ` Sami Mujawar
2024-05-16 15:24 ` Sami Mujawar [this message]
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 13/14] Platform/ARM/N1Sdp: Persistent storage for N1Sdp Sahil Kaushal
2024-04-24 9:55 ` levi.yun
2024-05-16 15:24 ` Sami Mujawar
2024-04-23 5:56 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 14/14] Platform/ARM/N1Sdp: Enable FaultTolerantWrite Dxe driver " Sahil Kaushal
2024-04-24 9:51 ` levi.yun
2024-05-16 15:24 ` Sami Mujawar
2024-05-02 13:16 ` [edk2-devel] [PATCH RESEND edk2-platforms][PATCH V2 00/14] Split NorFlashDxe driver and add CadenceQspiNorFlashDeviceLib library PierreGondois
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1674c97a-a13e-4ae6-ab79-e174b010140d@arm.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox