diff options
author | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-06-03 09:35:57 +0000 |
---|---|---|
committer | oliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524> | 2011-06-03 09:35:57 +0000 |
commit | d5e12da4fea90f1293d4731aa8a5da0097f268d5 (patch) | |
tree | de08d65377d30ade6eedf5560d209c73d9b45080 /ArmPlatformPkg | |
parent | ce9cc403bdd8f8d7f8aeebdac40485bf8e0d7be6 (diff) | |
download | edk2-platforms-d5e12da4fea90f1293d4731aa8a5da0097f268d5.tar.xz |
ArmPlatformPkg/NorFlashDxe: Move NorFlash driver from ArmVExpressPkg to ArmPlatformPkg
This NOR Flash driver can be reused for other platform (eg: ARM Realview EB).
To make this driver reusable on other platforms the NorFlashPlatformLib library
has been created to abstract the platform specific bits such as the pre-requirements
steps to the initialization and the geometry of the NOR Flash regions.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11746 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'ArmPlatformPkg')
11 files changed, 407 insertions, 234 deletions
diff --git a/ArmPlatformPkg/ArmPlatformPkg.dec b/ArmPlatformPkg/ArmPlatformPkg.dec index 66ec195054..1f83f43f33 100644 --- a/ArmPlatformPkg/ArmPlatformPkg.dec +++ b/ArmPlatformPkg/ArmPlatformPkg.dec @@ -33,6 +33,10 @@ [Guids.common] gArmPlatformTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } } + # + # Following Guid must match FILE_GUID in MdeModulePkg/Universal/Variable/RuntimeDxe/VariableRuntimeDxe.inf + # + gVariableRuntimeDxeFileGuid = { 0xcbd2e4d5, 0x7068, 0x4ff5, { 0xb4, 0x62, 0x98, 0x22, 0xb4, 0xad, 0x8d, 0x60 } } [PcdsFeatureFlag.common] gArmPlatformTokenSpaceGuid.PcdStandalone|FALSE|BOOLEAN|0x00000001 diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc index 2adbf2dad5..2aeeaf198b 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.dsc @@ -101,6 +101,8 @@ PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf # ARM PL011 UART Driver PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf + + NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf # # Assume everything is fixed at build @@ -489,7 +491,7 @@ EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf - ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf + ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf # diff --git a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf index 12af856e9c..1932df4677 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf +++ b/ArmPlatformPkg/ArmVExpressPkg/ArmVExpress-CTA9x4.fdf @@ -160,7 +160,7 @@ READ_LOCK_STATUS = TRUE INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf - INF ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf + INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf # # Semi-hosting filesystem diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c b/ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c new file mode 100644 index 0000000000..4171aae865 --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpress.c @@ -0,0 +1,79 @@ +/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NorFlashPlatformLib.h>
+#include <ArmPlatform.h>
+
+#define NOR_FLASH_DEVICE_COUNT 4
+
+NOR_FLASH_DESCRIPTION mNorFlashDevices[NOR_FLASH_DEVICE_COUNT] = {
+ { // BootMon
+ ARM_VE_SMB_NOR0_BASE,
+ SIZE_256KB * 255,
+ SIZE_256KB,
+ {0xE7223039, 0x5836, 0x41E1, 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59}
+ },
+ { // BootMon non-volatile storage
+ ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255,
+ SIZE_64KB * 4,
+ SIZE_64KB,
+ {0x02118005, 0x9DA7, 0x443A, 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB}
+ },
+ { // UEFI
+ ARM_VE_SMB_NOR1_BASE,
+ SIZE_256KB * 255,
+ SIZE_256KB,
+ {0x1F15DA3C, 0x37FF, 0x4070, 0xB4, 0x71, 0xBB, 0x4A, 0xF1, 0x2A, 0x72, 0x4A}
+ },
+ { // UEFI Variable Services non-volatile storage
+ ARM_VE_SMB_NOR1_BASE + SIZE_256KB * 255,
+ SIZE_64KB * 3, //FIXME: Set 3 blocks because I did not succeed to copy 4 blocks into the ARM Versatile Express NOR Flash in the last NOR Flash. It should be 4 blocks
+ SIZE_64KB,
+ {0xCC2CBF29, 0x1498, 0x4CDD, 0x81, 0x71, 0xF8, 0xB6, 0xB4, 0x1D, 0x09, 0x09}
+ }
+};
+
+EFI_STATUS
+NorFlashPlatformInitialization (
+ VOID
+ )
+{
+ // Everything seems ok so far, so now we need to disable the platform-specific
+ // flash write protection for Versatile Express
+ if ((MmioRead32 (ARM_VE_SYS_FLASH) & 0x1) == 0) {
+ // Writing to NOR FLASH is disabled, so enable it
+ MmioWrite32 (ARM_VE_SYS_FLASH,1);
+ DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: informational - Had to enable HSYS_FLASH flag.\n" ));
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NorFlashPlatformGetDevices (
+ OUT NOR_FLASH_DESCRIPTION **NorFlashDevices,
+ OUT UINT32 *Count
+ )
+{
+ if ((NorFlashDevices == NULL) || (Count == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *NorFlashDevices = mNorFlashDevices;
+ *Count = NOR_FLASH_DEVICE_COUNT;
+
+ return EFI_SUCCESS;
+}
diff --git a/ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf b/ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf new file mode 100644 index 0000000000..85b17efb39 --- /dev/null +++ b/ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf @@ -0,0 +1,41 @@ +#/** @file +# +# Component discription file for ArmVeGraphicsDxe module +# +# Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = NorFlashArmVExpressLib + FILE_GUID = c0f5dfa0-7599-11e0-9665-0002a5d5c51b + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + LIBRARY_CLASS = NorFlashPlatformLib + +[Sources.common] + NorFlashArmVExpress.c + +[Packages] + MdePkg/MdePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + +[LibraryClasses] + BaseLib + DebugLib + IoLib + +[Guids] + +[Protocols] + +[Pcd] + diff --git a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashBlockIoDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c index ad2c87b6ce..17a5369968 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashBlockIoDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashBlockIoDxe.c @@ -1,6 +1,6 @@ /** @file NorFlashBlockIoDxe.c - Copyright (c) 2010, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -11,7 +11,6 @@ **/ -#include <Library/DebugLib.h> #include <Library/BaseMemoryLib.h> #include <Library/UefiBootServicesTableLib.h> @@ -21,7 +20,8 @@ EFI_STATUS EFIAPI NorFlashBlkIoInitialize ( IN NOR_FLASH_INSTANCE* Instance - ) { + ) +{ UINT32 Reply; EFI_STATUS Status = EFI_SUCCESS; @@ -33,29 +33,23 @@ NorFlashBlkIoInitialize ( // Read a specific CFI query that returns back "QRY" // This ensures that there is really a device present there - SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_CFI_QUERY ); + SEND_NOR_COMMAND (Instance->BaseAddress, 0, P30_CMD_READ_CFI_QUERY); // Read CFI 'QRY' data - Status = NorFlashReadCfiData( Instance->BaseAddress, - P30_CFI_ADDR_QUERY_UNIQUE_QRY, - 3, - &Reply - ); + Status = NorFlashReadCfiData (Instance->BaseAddress, P30_CFI_ADDR_QUERY_UNIQUE_QRY, 3, &Reply); if (EFI_ERROR(Status)) { - goto EXIT; + return Status; } - if ( Reply != CFI_QRY ) { + if (Reply != CFI_QRY) { DEBUG((EFI_D_ERROR, "NorFlashBlkIoInitialize: CFI QRY=0x%x (expected 0x595251)\n", Reply)); - Status = EFI_DEVICE_ERROR; - goto EXIT; + return EFI_DEVICE_ERROR; } -EXIT: // Reset the device - Status = NorFlashBlockIoReset( &Instance->BlockIoProtocol, FALSE ); + Status = NorFlashBlockIoReset (&Instance->BlockIoProtocol, FALSE); if (EFI_ERROR(Status)) { - goto EXIT; + return Status; } Instance->Initialized = TRUE; @@ -73,17 +67,13 @@ NorFlashBlockIoReset ( IN BOOLEAN ExtendedVerification ) { - EFI_STATUS Status; NOR_FLASH_INSTANCE *Instance; Instance = INSTANCE_FROM_BLKIO_THIS(This); DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId)); - Status = NorFlashReset(Instance); - - return Status; - + return NorFlashReset(Instance); } // @@ -99,13 +89,22 @@ NorFlashBlockIoReadBlocks ( OUT VOID *Buffer ) { - NOR_FLASH_INSTANCE *Instance; + NOR_FLASH_INSTANCE *Instance; + EFI_STATUS Status; Instance = INSTANCE_FROM_BLKIO_THIS(This); DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReadBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer)); - return NorFlashReadBlocks(Instance,Lba,BufferSizeInBytes,Buffer); + if( !This->Media->MediaPresent ) { + Status = EFI_NO_MEDIA; + } else if( This->Media->MediaId != MediaId ) { + Status = EFI_MEDIA_CHANGED; + } else { + Status = NorFlashReadBlocks(Instance,Lba,BufferSizeInBytes,Buffer); + } + + return Status; } // @@ -121,13 +120,24 @@ NorFlashBlockIoWriteBlocks ( IN VOID *Buffer ) { - NOR_FLASH_INSTANCE *Instance; + NOR_FLASH_INSTANCE *Instance; + EFI_STATUS Status; Instance = INSTANCE_FROM_BLKIO_THIS(This); DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoWriteBlocks(MediaId=0x%x, Lba=%ld, BufferSize=0x%x bytes (%d kB), BufferPtr @ 0x%08x)\n", MediaId, Lba, BufferSizeInBytes, Buffer)); - return NorFlashWriteBlocks(Instance,Lba,BufferSizeInBytes,Buffer); + if( !This->Media->MediaPresent ) { + Status = EFI_NO_MEDIA; + } else if( This->Media->MediaId != MediaId ) { + Status = EFI_MEDIA_CHANGED; + } else if( This->Media->ReadOnly ) { + Status = EFI_WRITE_PROTECTED; + } else { + Status = NorFlashWriteBlocks(Instance,Lba,BufferSizeInBytes,Buffer); + } + + return Status; } // diff --git a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c index 0fd41cee71..a3d5bf6040 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c @@ -12,7 +12,6 @@ **/ #include <Library/UefiLib.h> -#include <Library/DebugLib.h> #include <Library/BaseMemoryLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/UefiBootServicesTableLib.h> @@ -24,37 +23,7 @@ // // Global variable declarations // - -#define NOR_FLASH_LAST_DEVICE 4 - -NOR_FLASH_DESCRIPTION mNorFlashDescription[NOR_FLASH_LAST_DEVICE] = { - { // BootMon - ARM_VE_SMB_NOR0_BASE, - SIZE_256KB * 255, - SIZE_256KB, - {0xE7223039, 0x5836, 0x41E1, 0xB5, 0x42, 0xD7, 0xEC, 0x73, 0x6C, 0x5E, 0x59} - }, - { // BootMon non-volatile storage - ARM_VE_SMB_NOR0_BASE + SIZE_256KB * 255, - SIZE_64KB * 4, - SIZE_64KB, - {0x02118005, 0x9DA7, 0x443A, 0x92, 0xD5, 0x78, 0x1F, 0x02, 0x2A, 0xED, 0xBB} - }, - { // UEFI - ARM_VE_SMB_NOR1_BASE, - SIZE_256KB * 255, - SIZE_256KB, - {0x1F15DA3C, 0x37FF, 0x4070, 0xB4, 0x71, 0xBB, 0x4A, 0xF1, 0x2A, 0x72, 0x4A} - }, - { // UEFI Variable Services non-volatile storage - ARM_VE_SMB_NOR1_BASE + SIZE_256KB * 255, - SIZE_64KB * 3, //FIXME: Set 3 blocks because I did not succeed to copy 4 blocks into the ARM Versastile Express NOR Falsh in the last NOR Flash. It should be 4 blocks - SIZE_64KB, - {0xCC2CBF29, 0x1498, 0x4CDD, 0x81, 0x71, 0xF8, 0xB6, 0xB4, 0x1D, 0x09, 0x09} - } -}; - -NOR_FLASH_INSTANCE *mNorFlashInstances[ NOR_FLASH_LAST_DEVICE ]; +NOR_FLASH_INSTANCE **mNorFlashInstances; NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { NOR_FLASH_SIGNATURE, // Signature @@ -65,6 +34,7 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { 0, // BaseAddress ... NEED TO BE FILLED 0, // Size ... NEED TO BE FILLED + 0, // StartLba {
EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
@@ -120,15 +90,17 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { } // DevicePath }; -EFI_STATUS NorFlashCreateInstance( - IN UINTN NorFlashBase, - IN UINTN NorFlashSize, - IN UINT32 MediaId, - IN UINT32 BlockSize, - IN BOOLEAN SupportFvb, - IN CONST GUID *NorFlashGuid, - OUT NOR_FLASH_INSTANCE** NorFlashInstance - ) { +EFI_STATUS +NorFlashCreateInstance ( + IN UINTN NorFlashBase, + IN UINTN NorFlashSize, + IN UINT32 MediaId, + IN UINT32 BlockSize, + IN BOOLEAN SupportFvb, + IN CONST GUID *NorFlashGuid, + OUT NOR_FLASH_INSTANCE** NorFlashInstance + ) +{ EFI_STATUS Status; NOR_FLASH_INSTANCE* Instance; @@ -156,7 +128,7 @@ EFI_STATUS NorFlashCreateInstance( Status = gBS->InstallMultipleProtocolInterfaces ( &Instance->Handle, &gEfiDevicePathProtocolGuid, &Instance->DevicePath, - //&gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol, + &gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol, &gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol, NULL ); @@ -186,13 +158,13 @@ EFI_STATUS NorFlashCreateInstance( EFI_STATUS NorFlashReadCfiData ( IN UINTN BaseAddress, - IN UINTN CFI_Offset, + IN UINTN CfiOffset, IN UINT32 NumberOfBytes, OUT UINT32 *Data -) + ) { UINT32 CurrentByte; - volatile UINTN *ReadAddress; + UINTN ReadAddress; UINT32 ReadData; UINT32 Byte1; UINT32 Byte2; @@ -200,15 +172,14 @@ NorFlashReadCfiData ( EFI_STATUS Status = EFI_SUCCESS; - if( NumberOfBytes > 4 ) { + if (NumberOfBytes > 4) { // Using 32 bit variable so can only read 4 bytes return EFI_INVALID_PARAMETER; } - // First combine the base address with the offset address - // to create an absolute read address. + // First combine the base address with the offset address to create an absolute read address. // However, because we are in little endian, read from the last address down to the first - ReadAddress = CREATE_NOR_ADDRESS( BaseAddress, CFI_Offset ) + NumberOfBytes - 1; + ReadAddress = CREATE_NOR_ADDRESS (BaseAddress, CfiOffset) + (NumberOfBytes - 1) * sizeof(UINT32); // Although each read returns 32 bits, because of the NOR Flash structure, // each 16 bits (16 MSB and 16 LSB) come from two different chips. @@ -218,30 +189,28 @@ NorFlashReadCfiData ( // // Also note: As we are in little endian notation and we are reading // bytes from incremental addresses, we should assemble them in little endian order. - for( CurrentByte=0; CurrentByte<NumberOfBytes; CurrentByte++ ) { - + for (CurrentByte=0; CurrentByte<NumberOfBytes; CurrentByte++) { // Read the bytes from the two chips - ReadData = *ReadAddress; + ReadData = MmioRead32(ReadAddress); // Check the data validity: // The 'Dual Data' function means that // each chip should return identical data. // If that is not the case then we have a problem. - Byte1 = GET_LOW_BYTE ( ReadData ); - Byte2 = GET_HIGH_BYTE( ReadData ); + Byte1 = GET_LOW_BYTE (ReadData); + Byte2 = GET_HIGH_BYTE(ReadData); - if( Byte1 != Byte2 ) { + if(Byte1 != Byte2) { // The two bytes should have been identical return EFI_DEVICE_ERROR; } else { - // Each successive iteration of the 'for' loop reads a lower address. // As we read lower addresses and as we use little endian, // we read lower significance bytes. So combine them in the correct order. CombinedData = (CombinedData << 8) | Byte1; // Decrement down to the next address - ReadAddress--; + ReadAddress -= sizeof(UINT32); } } @@ -251,7 +220,7 @@ NorFlashReadCfiData ( } EFI_STATUS -NorFlashReadStatusRegister( +NorFlashReadStatusRegister ( IN UINTN SR_Address ) { @@ -265,12 +234,12 @@ NorFlashReadStatusRegister( do { // Prepare to read the status register - SEND_NOR_COMMAND( SR_Address, 0, P30_CMD_READ_STATUS_REGISTER ); + SEND_NOR_COMMAND (SR_Address, 0, P30_CMD_READ_STATUS_REGISTER); // Snapshot the status register StatusRegister = *pStatusRegister; } // The chip is busy while the WRITE bit is not asserted - while ( (StatusRegister & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE ); + while ((StatusRegister & P30_SR_BIT_WRITE) != P30_SR_BIT_WRITE); // Perform a full status check: @@ -294,42 +263,38 @@ NorFlashReadStatusRegister( } // If an error is detected we must clear the Status Register - SEND_NOR_COMMAND( SR_Address, 0, P30_CMD_CLEAR_STATUS_REGISTER ); + SEND_NOR_COMMAND(SR_Address, 0, P30_CMD_CLEAR_STATUS_REGISTER); Status = EFI_DEVICE_ERROR; } - SEND_NOR_COMMAND( SR_Address, 0, P30_CMD_READ_ARRAY ); + SEND_NOR_COMMAND(SR_Address, 0, P30_CMD_READ_ARRAY); return Status; } BOOLEAN -NorFlashBlockIsLocked( +NorFlashBlockIsLocked ( IN UINTN BlockAddress ) { - volatile UINT32 *pReadData; UINT32 LockStatus; BOOLEAN BlockIsLocked = TRUE; - // Prepare the read address - pReadData = (UINT32 *) CREATE_NOR_ADDRESS( BlockAddress, 2 ); - // Send command for reading device id - SEND_NOR_COMMAND( BlockAddress, 2, P30_CMD_READ_DEVICE_ID ); + SEND_NOR_COMMAND (BlockAddress, 2, P30_CMD_READ_DEVICE_ID); // Read block lock status - LockStatus = *pReadData; + LockStatus = MmioRead32 (CREATE_NOR_ADDRESS( BlockAddress, 2 )); // Decode block lock status LockStatus = FOLD_32BIT_INTO_16BIT(LockStatus); - if( (LockStatus & 0x2) != 0 ) { + if((LockStatus & 0x2) != 0) { DEBUG((EFI_D_ERROR, "UnlockSingleBlock: WARNING: Block LOCKED DOWN\n")); } - if( (LockStatus & 0x1) == 0 ) { + if((LockStatus & 0x1) == 0) { // This means the block is unlocked DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: Block 0x%08x unlocked\n", BlockAddress )); BlockIsLocked = FALSE; @@ -340,7 +305,7 @@ NorFlashBlockIsLocked( EFI_STATUS -NorFlashUnlockSingleBlock( +NorFlashUnlockSingleBlock ( IN UINTN BlockAddress ) { @@ -349,17 +314,14 @@ NorFlashUnlockSingleBlock( // Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations // and to protect shared data structures. - //while( NorFlashBlockIsLocked( BlockAddress ) ) - { - // Request a lock setup - SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP ); + // Request a lock setup + SEND_NOR_COMMAND(BlockAddress, 0, P30_CMD_LOCK_BLOCK_SETUP); - // Request an unlock - SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_UNLOCK_BLOCK ); - } + // Request an unlock + SEND_NOR_COMMAND(BlockAddress, 0, P30_CMD_UNLOCK_BLOCK); // Put device back into Read Array mode - SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_READ_ARRAY ); + SEND_NOR_COMMAND(BlockAddress, 0, P30_CMD_READ_ARRAY); DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: BlockAddress=0x%08x, Exit Status = \"%r\".\n", BlockAddress, Status)); @@ -368,14 +330,14 @@ NorFlashUnlockSingleBlock( EFI_STATUS -NorFlashUnlockSingleBlockIfNecessary( +NorFlashUnlockSingleBlockIfNecessary ( IN UINTN BlockAddress ) { EFI_STATUS Status = EFI_SUCCESS; - if ( NorFlashBlockIsLocked( BlockAddress ) == TRUE ) { - Status = NorFlashUnlockSingleBlock( BlockAddress ); + if ( NorFlashBlockIsLocked(BlockAddress) == TRUE ) { + Status = NorFlashUnlockSingleBlock(BlockAddress); } return Status; @@ -386,15 +348,15 @@ NorFlashUnlockSingleBlockIfNecessary( * The following function presumes that the block has already been unlocked. **/ EFI_STATUS -NorFlashEraseSingleBlock( +NorFlashEraseSingleBlock ( IN UINTN BlockAddress ) { EFI_STATUS Status = EFI_SUCCESS; // Request a block erase and then confirm it - SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_BLOCK_ERASE_SETUP ); - SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_BLOCK_ERASE_CONFIRM ); + SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_BLOCK_ERASE_SETUP); + SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_BLOCK_ERASE_CONFIRM); // Wait until the status register gives us the all clear Status = NorFlashReadStatusRegister( BlockAddress ); @@ -408,16 +370,16 @@ NorFlashEraseSingleBlock( * The following function presumes that the block has already been unlocked. **/ EFI_STATUS -NorFlashUnlockAndEraseSingleBlock( +NorFlashUnlockAndEraseSingleBlock ( IN UINTN BlockAddress ) { EFI_STATUS Status; // Unlock the block if we have to - Status = NorFlashUnlockSingleBlockIfNecessary( BlockAddress ); + Status = NorFlashUnlockSingleBlockIfNecessary (BlockAddress); if (!EFI_ERROR(Status)) { - Status = NorFlashEraseSingleBlock( BlockAddress ); + Status = NorFlashEraseSingleBlock(BlockAddress); } return Status; @@ -426,8 +388,8 @@ NorFlashUnlockAndEraseSingleBlock( EFI_STATUS NorFlashWriteSingleWord ( - IN UINTN WordAddress, - IN UINT32 WriteData + IN UINTN WordAddress, + IN UINT32 WriteData ) { EFI_STATUS Status; @@ -465,9 +427,9 @@ NorFlashWriteSingleWord ( */ EFI_STATUS NorFlashWriteBuffer ( - IN UINTN TargetAddress, - IN UINTN BufferSizeInBytes, - IN UINT32 *Buffer + IN UINTN TargetAddress, + IN UINTN BufferSizeInBytes, + IN UINT32 *Buffer ) { EFI_STATUS Status; @@ -546,10 +508,10 @@ NorFlashWriteBuffer ( EFI_STATUS NorFlashWriteSingleBlock ( - IN UINTN DeviceBaseAddress, - IN EFI_LBA Lba, - IN UINT32 *DataBuffer, - IN UINT32 BlockSizeInWords + IN UINTN DeviceBaseAddress, + IN EFI_LBA Lba, + IN UINT32 *DataBuffer, + IN UINT32 BlockSizeInWords ) { EFI_STATUS Status = EFI_SUCCESS; @@ -575,7 +537,7 @@ NorFlashWriteSingleBlock ( WordAddress = BlockAddress; // Check that the address starts at a 32-word boundary, i.e. last 7 bits must be zero - if ( (WordAddress & BOUNDARY_OF_32_WORDS) == 0x00 ) { + if ((WordAddress & BOUNDARY_OF_32_WORDS) == 0x00) { // First, break the entire block into buffer-sized chunks. BuffersInBlock = (UINTN)BlockSizeInWords / P30_MAX_BUFFER_SIZE_IN_BYTES; @@ -635,7 +597,6 @@ NorFlashWriteBlocks ( UINT32 BlockSizeInWords; UINT32 NumBlocks; UINT32 BlockCount; - volatile UINT32 *VersatileExpress_SYS_FLASH; // The buffer must be valid if (Buffer == NULL) { @@ -668,15 +629,6 @@ NorFlashWriteBlocks ( return EFI_INVALID_PARAMETER; } - // Everything seems ok so far, so now we need to disable the platform-specific - // flash write protection for Versatile Express - VersatileExpress_SYS_FLASH = (UINT32 *)VE_REGISTER_SYS_FLASH_ADDR; - if( (*VersatileExpress_SYS_FLASH & 0x1) == 0 ) { - // Writing to NOR FLASH is disabled, so enable it - *VersatileExpress_SYS_FLASH = 0x1; - DEBUG((DEBUG_BLKIO, "NorFlashWriteBlocks: informational - Had to enable HSYS_FLASH flag.\n" )); - } - BlockSizeInWords = Instance->Media.BlockSize / 4; // Because the target *Buffer is a pointer to VOID, we must put all the data into a pointer @@ -740,13 +692,13 @@ NorFlashReadBlocks ( } // Get the address to start reading from - StartAddress = GET_NOR_BLOCK_ADDRESS( Instance->BaseAddress, + StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->BaseAddress, Lba, Instance->Media.BlockSize - ); + ); // Put the device into Read Array mode - SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_ARRAY ); + SEND_NOR_COMMAND (Instance->BaseAddress, 0, P30_CMD_READ_ARRAY); // Readout the data CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes); @@ -760,11 +712,8 @@ NorFlashReset ( IN NOR_FLASH_INSTANCE *Instance ) { - DEBUG((DEBUG_BLKIO, "NorFlashReset(BaseAddress=0x%08x)\n", Instance->BaseAddress)); - // As there is no specific RESET to perform, ensure that the devices is in the default Read Array mode - SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_ARRAY ); - + SEND_NOR_COMMAND( Instance->BaseAddress, 0, P30_CMD_READ_ARRAY); return EFI_SUCCESS; } @@ -777,18 +726,39 @@ NorFlashInitialise ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status = EFI_SUCCESS; - UINT32 Index; - UINTN NvStorageVariableBase = (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase); + EFI_STATUS Status; + UINT32 Index; + NOR_FLASH_DESCRIPTION* NorFlashDevices; + UINT32 NorFlashDeviceCount; + BOOLEAN ContainVariableStorage; + + Status = NorFlashPlatformInitialization (); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n")); + return Status; + } + + Status = NorFlashPlatformGetDevices (&NorFlashDevices,&NorFlashDeviceCount); + if (EFI_ERROR(Status)) { + DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to get Nor Flash devices\n")); + return Status; + } + + mNorFlashInstances = AllocatePool(sizeof(NOR_FLASH_INSTANCE*) * NorFlashDeviceCount); + + for (Index = 0; Index < NorFlashDeviceCount; Index++) { + // Check if this NOR Flash device contain the variable storage region + ContainVariableStorage = + (NorFlashDevices[Index].BaseAddress <= PcdGet32 (PcdFlashNvStorageVariableBase)) && + (PcdGet32 (PcdFlashNvStorageVariableBase) + PcdGet32 (PcdFlashNvStorageVariableSize) <= NorFlashDevices[Index].BaseAddress + NorFlashDevices[Index].Size); - for (Index = 0; Index < NOR_FLASH_LAST_DEVICE; Index++) { - Status = NorFlashCreateInstance( - mNorFlashDescription[Index].BaseAddress, - mNorFlashDescription[Index].Size, + Status = NorFlashCreateInstance ( + NorFlashDevices[Index].BaseAddress, + NorFlashDevices[Index].Size, Index, - mNorFlashDescription[Index].BlockSize, - (mNorFlashDescription[Index].BaseAddress == NvStorageVariableBase), - &mNorFlashDescription[Index].Guid, + NorFlashDevices[Index].BlockSize, + ContainVariableStorage, + &NorFlashDevices[Index].Guid, &mNorFlashInstances[Index] ); if (EFI_ERROR(Status)) { diff --git a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.h b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h index 7da9942c34..60cdbd5a43 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.h +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.h @@ -1,6 +1,6 @@ /** @file NorFlashDxe.h - Copyright (c) 2010, ARM Ltd. All rights reserved.<BR> + Copyright (c) 2011, ARM Ltd. All rights reserved.<BR> This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -21,19 +21,17 @@ #include <Protocol/BlockIo.h> #include <Protocol/FirmwareVolumeBlock.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/NorFlashPlatformLib.h> +#include <Library/UefiLib.h> + #include <ArmPlatform.h> #define HIGH_16_BITS 0xFFFF0000 #define LOW_16_BITS 0x0000FFFF #define LOW_8_BITS 0x000000FF -// Hardware addresses - -#define VE_SYSTEM_REGISTERS_OFFSET 0x00000000 -#define SYSTEM_REGISTER_SYS_FLASH 0x0000004C - -#define VE_REGISTER_SYS_FLASH_ADDR ( ARM_VE_BOARD_PERIPH_BASE + VE_SYSTEM_REGISTERS_OFFSET + SYSTEM_REGISTER_SYS_FLASH ) - // Device access macros // These are necessary because we use 2 x 16bit parts to make up 32bit data @@ -44,20 +42,20 @@ // Each command must be sent simultaneously to both chips, // i.e. at the lower 16 bits AND at the higher 16 bits -#define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ( (volatile UINTN *)((BaseAddr) + ((OffsetAddr) << 2)) ) +#define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ((BaseAddr) + ((OffsetAddr) << 2)) #define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) ) -#define SEND_NOR_COMMAND(BaseAddr,OffsetAddr,Cmd) ( *CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) = CREATE_DUAL_CMD(Cmd) ) -#define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)(Lba * LbaSize) ) +#define SEND_NOR_COMMAND(BaseAddr,OffsetAddr,Cmd) MmioWrite32 (CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr), CREATE_DUAL_CMD(Cmd)) +#define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)((Lba) * LbaSize) ) // Status Register Bits -#define P30_SR_BIT_WRITE 0x00800080 /* Bit 7 */ -#define P30_SR_BIT_ERASE_SUSPEND 0x00400040 /* Bit 6 */ -#define P30_SR_BIT_ERASE 0x00200020 /* Bit 5 */ -#define P30_SR_BIT_PROGRAM 0x00100010 /* Bit 4 */ -#define P30_SR_BIT_VPP 0x00080008 /* Bit 3 */ -#define P30_SR_BIT_PROGRAM_SUSPEND 0x00040004 /* Bit 2 */ -#define P30_SR_BIT_BLOCK_LOCKED 0x00020002 /* Bit 1 */ -#define P30_SR_BIT_BEFP 0x00010001 /* Bit 0 */ +#define P30_SR_BIT_WRITE (BIT7 << 16 | BIT7) +#define P30_SR_BIT_ERASE_SUSPEND (BIT6 << 16 | BIT6) +#define P30_SR_BIT_ERASE (BIT5 << 16 | BIT5) +#define P30_SR_BIT_PROGRAM (BIT4 << 16 | BIT4) +#define P30_SR_BIT_VPP (BIT3 << 16 | BIT3) +#define P30_SR_BIT_PROGRAM_SUSPEND (BIT2 << 16 | BIT2) +#define P30_SR_BIT_BLOCK_LOCKED (BIT1 << 16 | BIT1) +#define P30_SR_BIT_BEFP (BIT0 << 16 | BIT0) // Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family @@ -121,13 +119,6 @@ typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE; typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* Instance); typedef struct { - UINTN BaseAddress; - UINTN Size; - UINTN BlockSize; - EFI_GUID Guid; -} NOR_FLASH_DESCRIPTION; - -typedef struct { VENDOR_DEVICE_PATH Vendor; EFI_DEVICE_PATH_PROTOCOL End; } NOR_FLASH_DEVICE_PATH; @@ -141,6 +132,7 @@ struct _NOR_FLASH_INSTANCE { UINTN BaseAddress; UINTN Size; + EFI_LBA StartLba; EFI_BLOCK_IO_PROTOCOL BlockIoProtocol; EFI_BLOCK_IO_MEDIA Media; @@ -153,6 +145,24 @@ struct _NOR_FLASH_INSTANCE { EFI_STATUS EFIAPI +NorFlashGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +NorFlashGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +EFI_STATUS +EFIAPI NorFlashBlkIoInitialize ( IN NOR_FLASH_INSTANCE* Instance ); diff --git a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf index 0ea1ded211..43f670e7c6 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf @@ -29,13 +29,14 @@ [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec - ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec [LibraryClasses] IoLib BaseLib - UefiLib DebugLib + NorFlashPlatformLib + UefiLib UefiDriverEntryPoint UefiBootServicesTableLib @@ -49,9 +50,12 @@ gEfiFirmwareVolumeBlockProtocolGuid [Pcd.common] - gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase - + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase + gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize [Depex] # diff --git a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashFvbDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c index ffc2d5db59..c4a61c1763 100644 --- a/ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashFvbDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashFvbDxe.c @@ -16,7 +16,6 @@ #include <Library/PcdLib.h> #include <Library/BaseLib.h> #include <Library/UefiLib.h> -#include <Library/DebugLib.h> #include <Library/BaseMemoryLib.h> #include <Library/MemoryAllocationLib.h> #include <Library/UefiBootServicesTableLib.h> @@ -62,12 +61,29 @@ InitializeFvAndVariableStoreHeaders ( HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER); Headers = AllocateZeroPool(HeadersLength); + // FirmwareVolumeHeader->FvLength is declared to have the Variable area AND the FTW working area AND the FTW Spare contiguous. + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) + PcdGet32(PcdFlashNvStorageVariableSize) == PcdGet32(PcdFlashNvStorageFtwWorkingBase)); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) == PcdGet32(PcdFlashNvStorageFtwSpareBase)); + + // Check if the size of the area is at least one block size + ASSERT((PcdGet32(PcdFlashNvStorageVariableSize) > 0) && (PcdGet32(PcdFlashNvStorageVariableSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwWorkingSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwWorkingSize) / Instance->Media.BlockSize > 0)); + ASSERT((PcdGet32(PcdFlashNvStorageFtwSpareSize) > 0) && (PcdGet32(PcdFlashNvStorageFtwSpareSize) / Instance->Media.BlockSize > 0)); + + // Ensure the Variable area Base Addresses are aligned on a block size boundaries + ASSERT(PcdGet32(PcdFlashNvStorageVariableBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwWorkingBase) % Instance->Media.BlockSize == 0); + ASSERT(PcdGet32(PcdFlashNvStorageFtwSpareBase) % Instance->Media.BlockSize == 0); + // // EFI_FIRMWARE_VOLUME_HEADER // FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers; CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid); - FirmwareVolumeHeader->FvLength = Instance->Media.BlockSize * (Instance->Media.LastBlock + 1); + FirmwareVolumeHeader->FvLength = + PcdGet32(PcdFlashNvStorageVariableSize) + + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); FirmwareVolumeHeader->Signature = EFI_FVH_SIGNATURE; FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) ( EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled @@ -96,9 +112,9 @@ InitializeFvAndVariableStoreHeaders ( VariableStoreHeader->State = VARIABLE_STORE_HEALTHY; // Install the combined super-header in the NorFlash - Status = FvbWrite(&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers ); + Status = FvbWrite (&Instance->FvbProtocol, 0, 0, &HeadersLength, Headers); - FreePool(Headers); + FreePool (Headers); return Status; } @@ -120,18 +136,23 @@ ValidateFvHeader ( EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader; VARIABLE_STORE_HEADER *VariableStoreHeader; UINTN VariableStoreLength; + UINTN FvLength; FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Instance->BaseAddress; + FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + + PcdGet32(PcdFlashNvStorageFtwSpareSize); + // // Verify the header revision, header signature, length // Length of FvBlock cannot be 2**64-1 // HeaderLength cannot be an odd number // - if ( ( FwVolHeader->Revision != EFI_FVH_REVISION ) - || ( FwVolHeader->Signature != EFI_FVH_SIGNATURE ) - || ( FwVolHeader->FvLength != Instance->Media.BlockSize * (Instance->Media.LastBlock + 1) ) - ) { + if ( (FwVolHeader->Revision != EFI_FVH_REVISION) + || (FwVolHeader->Signature != EFI_FVH_SIGNATURE) + || (FwVolHeader->FvLength != FvLength) + ) + { DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n")); return EFI_NOT_FOUND; } @@ -278,7 +299,7 @@ FvbGetPhysicalAddress( ASSERT(Address != NULL); - *Address = Instance->BaseAddress; + *Address = PcdGet32 (PcdFlashNvStorageVariableBase); return EFI_SUCCESS; } @@ -310,7 +331,7 @@ FvbGetPhysicalAddress( **/ EFI_STATUS EFIAPI -FvbGetBlockSize( +FvbGetBlockSize ( IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, IN EFI_LBA Lba, OUT UINTN *BlockSize, @@ -399,7 +420,7 @@ FvbRead ( Instance = INSTANCE_FROM_FVB_THIS(This); - DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + DEBUG ((DEBUG_BLKIO, "FvbRead(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Instance->StartLba + Lba, Offset, *NumBytes, Buffer)); if (!Instance->Initialized) { Instance->Initialize(Instance); @@ -415,9 +436,9 @@ FvbRead ( // The read 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 ) ) { + if ((Offset >= BlockSize) || + (*NumBytes > BlockSize) || + ((Offset + *NumBytes) > BlockSize)) { DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - EFI_BAD_BUFFER_SIZE: (Offset=0x%x + NumBytes=0x%x) > BlockSize=0x%x\n", Offset, *NumBytes, BlockSize )); return EFI_BAD_BUFFER_SIZE; } @@ -433,13 +454,13 @@ FvbRead ( BlockBuffer = AllocateRuntimePool(BlockSize); // Check if the memory allocation was successful - if( BlockBuffer == NULL ) { + if (BlockBuffer == NULL) { DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Could not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer)); return EFI_DEVICE_ERROR; } // Read NOR Flash data into shadow buffer - TempStatus = NorFlashReadBlocks(Instance, Lba, BlockSize, BlockBuffer); + TempStatus = NorFlashReadBlocks (Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer); if (EFI_ERROR (TempStatus)) { // Return one of the pre-approved error statuses Status = EFI_DEVICE_ERROR; @@ -453,8 +474,6 @@ FvbRead ( FREE_MEMORY: FreePool(BlockBuffer); - - DEBUG ((DEBUG_BLKIO, "FvbRead - end\n")); return Status; } @@ -534,7 +553,7 @@ FvbWrite ( Instance->Initialize(Instance); } - DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); + DEBUG ((DEBUG_BLKIO, "FvbWrite(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Instance->StartLba + Lba, Offset, *NumBytes, Buffer)); Status = EFI_SUCCESS; TempStatus = Status; @@ -576,7 +595,7 @@ FvbWrite ( } // Read NOR Flash data into shadow buffer - TempStatus = NorFlashReadBlocks(Instance, Lba, BlockSize, BlockBuffer); + TempStatus = NorFlashReadBlocks(Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer); if (EFI_ERROR (TempStatus)) { // Return one of the pre-approved error statuses Status = EFI_DEVICE_ERROR; @@ -587,7 +606,7 @@ FvbWrite ( CopyMem((BlockBuffer + Offset), Buffer, *NumBytes); // Write the modified buffer back to the NorFlash - Status = NorFlashWriteBlocks(Instance, Lba, BlockSize, BlockBuffer); + Status = NorFlashWriteBlocks(Instance, Instance->StartLba + Lba, BlockSize, BlockBuffer); if (EFI_ERROR (TempStatus)) { // Return one of the pre-approved error statuses Status = EFI_DEVICE_ERROR; @@ -650,7 +669,7 @@ FvbEraseBlocks ( ) { EFI_STATUS Status; - VA_LIST args; + VA_LIST Args; UINTN BlockAddress; // Physical address of Lba to erase EFI_LBA StartingLba; // Lba from which we start erasing UINTN NumOfLba; // Number of Lba blocks to erase @@ -671,12 +690,10 @@ FvbEraseBlocks ( // Before erasing, check the entire list of parameters to ensure all specified blocks are valid - VA_START (args, This); - + VA_START (Args, This); do { - // Get the Lba from which we start erasing - StartingLba = VA_ARG (args, EFI_LBA); + StartingLba = VA_ARG (Args, EFI_LBA); // Have we reached the end of the list? if (StartingLba == EFI_LBA_LIST_TERMINATOR) { @@ -685,30 +702,27 @@ FvbEraseBlocks ( } // How many Lba blocks are we requested to erase? - NumOfLba = VA_ARG (args, UINT32); + NumOfLba = VA_ARG (Args, UINT32); // All blocks must be within range - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", StartingLba, NumOfLba, Instance->Media.LastBlock)); - if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { - VA_END (args); - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", StartingLba, NumOfLba, Instance->Media.LastBlock)); + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", Instance->StartLba + StartingLba, NumOfLba, Instance->Media.LastBlock)); + if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) { + VA_END (Args); DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n")); Status = EFI_INVALID_PARAMETER; goto EXIT; } - } while (TRUE); + VA_END (Args); - VA_END (args); + // // To get here, all must be ok, so start erasing - - VA_START (args, This); - + // + VA_START (Args, This); do { - // Get the Lba from which we start erasing - StartingLba = VA_ARG (args, EFI_LBA); + StartingLba = VA_ARG (Args, EFI_LBA); // Have we reached the end of the list? if (StartingLba == EFI_LBA_LIST_TERMINATOR) { @@ -717,7 +731,7 @@ FvbEraseBlocks ( } // How many Lba blocks are we requested to erase? - NumOfLba = VA_ARG (args, UINT32); + NumOfLba = VA_ARG (Args, UINT32); // Go through each one and erase it while (NumOfLba > 0) { @@ -725,15 +739,15 @@ FvbEraseBlocks ( // Get the physical address of Lba to erase BlockAddress = GET_NOR_BLOCK_ADDRESS ( Instance->BaseAddress, - StartingLba, + Instance->StartLba + StartingLba, Instance->Media.BlockSize ); // Erase it - DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld @ 0x%08x.\n", StartingLba, BlockAddress)); + DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Erasing Lba=%ld @ 0x%08x.\n", Instance->StartLba + StartingLba, BlockAddress)); Status = NorFlashUnlockAndEraseSingleBlock (BlockAddress); if (EFI_ERROR(Status)) { - VA_END (args); + VA_END (Args); Status = EFI_DEVICE_ERROR; goto EXIT; } @@ -742,10 +756,8 @@ FvbEraseBlocks ( StartingLba++; NumOfLba--; } - } while (TRUE); - - VA_END (args); + VA_END (Args); EXIT: return Status; @@ -755,18 +767,23 @@ EFI_STATUS EFIAPI NorFlashFvbInitialize ( IN NOR_FLASH_INSTANCE* Instance - ) { - EFI_STATUS Status; + ) +{ + EFI_STATUS Status; + UINT32 FvbNumLba; DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n")); - Status = NorFlashBlkIoInitialize(Instance); + Status = NorFlashBlkIoInitialize (Instance); if (EFI_ERROR(Status)) { DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - Failed to initialize FVB\n")); return Status; } Instance->Initialized = TRUE; + // Set the index of the first LBA for the FVB + Instance->StartLba = (PcdGet32 (PcdFlashNvStorageVariableBase) - Instance->BaseAddress) / Instance->Media.BlockSize; + // Determine if there is a valid header at the beginning of the NorFlash Status = ValidateFvHeader (Instance); if (EFI_ERROR(Status)) { @@ -774,17 +791,18 @@ NorFlashFvbInitialize ( DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - The FVB Header is not valid. Installing a correct one for this volume.\n")); // Erase all the NorFlash that is reserved for variable storage - Status = FvbEraseBlocks ( &Instance->FvbProtocol, (EFI_LBA)0, (UINT32)(Instance->Media.LastBlock + 1), EFI_LBA_LIST_TERMINATOR ); + FvbNumLba = (PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) + PcdGet32(PcdFlashNvStorageFtwSpareSize)) / Instance->Media.BlockSize; + + Status = FvbEraseBlocks (&Instance->FvbProtocol, (EFI_LBA)0, FvbNumLba, EFI_LBA_LIST_TERMINATOR); if (EFI_ERROR(Status)) { return Status; } // Install all appropriate headers - InitializeFvAndVariableStoreHeaders ( Instance ); + Status = InitializeFvAndVariableStoreHeaders (Instance); if (EFI_ERROR(Status)) { return Status; } } - return Status; } diff --git a/ArmPlatformPkg/Include/Library/NorFlashPlatformLib.h b/ArmPlatformPkg/Include/Library/NorFlashPlatformLib.h new file mode 100644 index 0000000000..d5b427df3a --- /dev/null +++ b/ArmPlatformPkg/Include/Library/NorFlashPlatformLib.h @@ -0,0 +1,35 @@ +/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ **/
+
+#ifndef _NORFLASHPLATFORMLIB_H_
+#define _NORFLASHPLATFORMLIB_H_
+
+typedef struct {
+ UINTN BaseAddress;
+ UINTN Size;
+ UINTN BlockSize;
+ EFI_GUID Guid;
+} NOR_FLASH_DESCRIPTION;
+
+EFI_STATUS
+NorFlashPlatformInitialization (
+ VOID
+ );
+
+EFI_STATUS
+NorFlashPlatformGetDevices (
+ OUT NOR_FLASH_DESCRIPTION **NorFlashDescriptions,
+ OUT UINT32 *Count
+ );
+
+#endif /* _NORFLASHPLATFORMLIB_H_ */
|