mirror of
https://github.com/acidanthera/audk.git
synced 2025-07-24 06:04:52 +02:00
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
This commit is contained in:
parent
ce9cc403bd
commit
d5e12da4fe
@ -33,6 +33,10 @@
|
|||||||
|
|
||||||
[Guids.common]
|
[Guids.common]
|
||||||
gArmPlatformTokenSpaceGuid = { 0x9c0aaed4, 0x74c5, 0x4043, { 0xb4, 0x17, 0xa3, 0x22, 0x38, 0x14, 0xce, 0x76 } }
|
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]
|
[PcdsFeatureFlag.common]
|
||||||
gArmPlatformTokenSpaceGuid.PcdStandalone|FALSE|BOOLEAN|0x00000001
|
gArmPlatformTokenSpaceGuid.PcdStandalone|FALSE|BOOLEAN|0x00000001
|
||||||
|
@ -101,6 +101,8 @@
|
|||||||
PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf
|
PL301AxiLib|ArmPkg/Drivers/PL301Axi/PL301Axi.inf
|
||||||
# ARM PL011 UART Driver
|
# ARM PL011 UART Driver
|
||||||
PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
|
PL011UartLib|ArmPlatformPkg/Drivers/PL011Uart/PL011Uart.inf
|
||||||
|
|
||||||
|
NorFlashPlatformLib|ArmPlatformPkg/ArmVExpressPkg/Library/NorFlashArmVExpressLib/NorFlashArmVExpressLib.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Assume everything is fixed at build
|
# Assume everything is fixed at build
|
||||||
@ -489,7 +491,7 @@
|
|||||||
EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
|
EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
|
||||||
|
|
||||||
ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
|
ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
|
||||||
ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf
|
ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
|
||||||
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
|
ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -160,7 +160,7 @@ READ_LOCK_STATUS = TRUE
|
|||||||
|
|
||||||
INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
|
INF ArmPkg/Drivers/PL390Gic/PL390GicDxe.inf
|
||||||
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
|
INF ArmPlatformPkg/Drivers/SP804TimerDxe/SP804TimerDxe.inf
|
||||||
INF ArmPlatformPkg/ArmVExpressPkg/NorFlashDxe/NorFlashDxe.inf
|
INF ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.inf
|
||||||
|
|
||||||
#
|
#
|
||||||
# Semi-hosting filesystem
|
# Semi-hosting filesystem
|
||||||
|
@ -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;
|
||||||
|
}
|
@ -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]
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
/** @file NorFlashBlockIoDxe.c
|
/** @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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
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/BaseMemoryLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
|
|
||||||
@ -21,7 +20,8 @@ EFI_STATUS
|
|||||||
EFIAPI
|
EFIAPI
|
||||||
NorFlashBlkIoInitialize (
|
NorFlashBlkIoInitialize (
|
||||||
IN NOR_FLASH_INSTANCE* Instance
|
IN NOR_FLASH_INSTANCE* Instance
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
UINT32 Reply;
|
UINT32 Reply;
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
@ -33,29 +33,23 @@ NorFlashBlkIoInitialize (
|
|||||||
|
|
||||||
// Read a specific CFI query that returns back "QRY"
|
// Read a specific CFI query that returns back "QRY"
|
||||||
// This ensures that there is really a device present there
|
// 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
|
// Read CFI 'QRY' data
|
||||||
Status = NorFlashReadCfiData( Instance->BaseAddress,
|
Status = NorFlashReadCfiData (Instance->BaseAddress, P30_CFI_ADDR_QUERY_UNIQUE_QRY, 3, &Reply);
|
||||||
P30_CFI_ADDR_QUERY_UNIQUE_QRY,
|
|
||||||
3,
|
|
||||||
&Reply
|
|
||||||
);
|
|
||||||
if (EFI_ERROR(Status)) {
|
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));
|
DEBUG((EFI_D_ERROR, "NorFlashBlkIoInitialize: CFI QRY=0x%x (expected 0x595251)\n", Reply));
|
||||||
Status = EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
goto EXIT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXIT:
|
|
||||||
// Reset the device
|
// Reset the device
|
||||||
Status = NorFlashBlockIoReset( &Instance->BlockIoProtocol, FALSE );
|
Status = NorFlashBlockIoReset (&Instance->BlockIoProtocol, FALSE);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
goto EXIT;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
Instance->Initialized = TRUE;
|
Instance->Initialized = TRUE;
|
||||||
@ -73,17 +67,13 @@ NorFlashBlockIoReset (
|
|||||||
IN BOOLEAN ExtendedVerification
|
IN BOOLEAN ExtendedVerification
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
|
||||||
NOR_FLASH_INSTANCE *Instance;
|
NOR_FLASH_INSTANCE *Instance;
|
||||||
|
|
||||||
Instance = INSTANCE_FROM_BLKIO_THIS(This);
|
Instance = INSTANCE_FROM_BLKIO_THIS(This);
|
||||||
|
|
||||||
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
|
DEBUG ((DEBUG_BLKIO, "NorFlashBlockIoReset(MediaId=0x%x)\n", This->Media->MediaId));
|
||||||
|
|
||||||
Status = NorFlashReset(Instance);
|
return NorFlashReset(Instance);
|
||||||
|
|
||||||
return Status;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -99,13 +89,22 @@ NorFlashBlockIoReadBlocks (
|
|||||||
OUT VOID *Buffer
|
OUT VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NOR_FLASH_INSTANCE *Instance;
|
NOR_FLASH_INSTANCE *Instance;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
Instance = INSTANCE_FROM_BLKIO_THIS(This);
|
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));
|
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
|
IN VOID *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
NOR_FLASH_INSTANCE *Instance;
|
NOR_FLASH_INSTANCE *Instance;
|
||||||
|
EFI_STATUS Status;
|
||||||
|
|
||||||
Instance = INSTANCE_FROM_BLKIO_THIS(This);
|
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));
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
@ -12,7 +12,6 @@
|
|||||||
**/
|
**/
|
||||||
|
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/DebugLib.h>
|
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.h>
|
#include <Library/UefiBootServicesTableLib.h>
|
||||||
@ -24,37 +23,7 @@
|
|||||||
//
|
//
|
||||||
// Global variable declarations
|
// Global variable declarations
|
||||||
//
|
//
|
||||||
|
NOR_FLASH_INSTANCE **mNorFlashInstances;
|
||||||
#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 mNorFlashInstanceTemplate = {
|
NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
|
||||||
NOR_FLASH_SIGNATURE, // Signature
|
NOR_FLASH_SIGNATURE, // Signature
|
||||||
@ -65,6 +34,7 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
|
|||||||
|
|
||||||
0, // BaseAddress ... NEED TO BE FILLED
|
0, // BaseAddress ... NEED TO BE FILLED
|
||||||
0, // Size ... NEED TO BE FILLED
|
0, // Size ... NEED TO BE FILLED
|
||||||
|
0, // StartLba
|
||||||
|
|
||||||
{
|
{
|
||||||
EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
|
EFI_BLOCK_IO_PROTOCOL_REVISION2, // Revision
|
||||||
@ -120,15 +90,17 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = {
|
|||||||
} // DevicePath
|
} // DevicePath
|
||||||
};
|
};
|
||||||
|
|
||||||
EFI_STATUS NorFlashCreateInstance(
|
EFI_STATUS
|
||||||
IN UINTN NorFlashBase,
|
NorFlashCreateInstance (
|
||||||
IN UINTN NorFlashSize,
|
IN UINTN NorFlashBase,
|
||||||
IN UINT32 MediaId,
|
IN UINTN NorFlashSize,
|
||||||
IN UINT32 BlockSize,
|
IN UINT32 MediaId,
|
||||||
IN BOOLEAN SupportFvb,
|
IN UINT32 BlockSize,
|
||||||
IN CONST GUID *NorFlashGuid,
|
IN BOOLEAN SupportFvb,
|
||||||
OUT NOR_FLASH_INSTANCE** NorFlashInstance
|
IN CONST GUID *NorFlashGuid,
|
||||||
) {
|
OUT NOR_FLASH_INSTANCE** NorFlashInstance
|
||||||
|
)
|
||||||
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
NOR_FLASH_INSTANCE* Instance;
|
NOR_FLASH_INSTANCE* Instance;
|
||||||
|
|
||||||
@ -156,7 +128,7 @@ EFI_STATUS NorFlashCreateInstance(
|
|||||||
Status = gBS->InstallMultipleProtocolInterfaces (
|
Status = gBS->InstallMultipleProtocolInterfaces (
|
||||||
&Instance->Handle,
|
&Instance->Handle,
|
||||||
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,
|
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,
|
||||||
//&gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol,
|
&gEfiBlockIoProtocolGuid, &Instance->BlockIoProtocol,
|
||||||
&gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
|
&gEfiFirmwareVolumeBlockProtocolGuid, &Instance->FvbProtocol,
|
||||||
NULL
|
NULL
|
||||||
);
|
);
|
||||||
@ -186,13 +158,13 @@ EFI_STATUS NorFlashCreateInstance(
|
|||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashReadCfiData (
|
NorFlashReadCfiData (
|
||||||
IN UINTN BaseAddress,
|
IN UINTN BaseAddress,
|
||||||
IN UINTN CFI_Offset,
|
IN UINTN CfiOffset,
|
||||||
IN UINT32 NumberOfBytes,
|
IN UINT32 NumberOfBytes,
|
||||||
OUT UINT32 *Data
|
OUT UINT32 *Data
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
UINT32 CurrentByte;
|
UINT32 CurrentByte;
|
||||||
volatile UINTN *ReadAddress;
|
UINTN ReadAddress;
|
||||||
UINT32 ReadData;
|
UINT32 ReadData;
|
||||||
UINT32 Byte1;
|
UINT32 Byte1;
|
||||||
UINT32 Byte2;
|
UINT32 Byte2;
|
||||||
@ -200,15 +172,14 @@ NorFlashReadCfiData (
|
|||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
|
|
||||||
if( NumberOfBytes > 4 ) {
|
if (NumberOfBytes > 4) {
|
||||||
// Using 32 bit variable so can only read 4 bytes
|
// Using 32 bit variable so can only read 4 bytes
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
// First combine the base address with the offset address
|
// First combine the base address with the offset address to create an absolute read address.
|
||||||
// to create an absolute read address.
|
|
||||||
// However, because we are in little endian, read from the last address down to the first
|
// 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,
|
// 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.
|
// 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
|
// 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.
|
// 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
|
// Read the bytes from the two chips
|
||||||
ReadData = *ReadAddress;
|
ReadData = MmioRead32(ReadAddress);
|
||||||
|
|
||||||
// Check the data validity:
|
// Check the data validity:
|
||||||
// The 'Dual Data' function means that
|
// The 'Dual Data' function means that
|
||||||
// each chip should return identical data.
|
// each chip should return identical data.
|
||||||
// If that is not the case then we have a problem.
|
// If that is not the case then we have a problem.
|
||||||
Byte1 = GET_LOW_BYTE ( ReadData );
|
Byte1 = GET_LOW_BYTE (ReadData);
|
||||||
Byte2 = GET_HIGH_BYTE( ReadData );
|
Byte2 = GET_HIGH_BYTE(ReadData);
|
||||||
|
|
||||||
if( Byte1 != Byte2 ) {
|
if(Byte1 != Byte2) {
|
||||||
// The two bytes should have been identical
|
// The two bytes should have been identical
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
// Each successive iteration of the 'for' loop reads a lower address.
|
// Each successive iteration of the 'for' loop reads a lower address.
|
||||||
// As we read lower addresses and as we use little endian,
|
// As we read lower addresses and as we use little endian,
|
||||||
// we read lower significance bytes. So combine them in the correct order.
|
// we read lower significance bytes. So combine them in the correct order.
|
||||||
CombinedData = (CombinedData << 8) | Byte1;
|
CombinedData = (CombinedData << 8) | Byte1;
|
||||||
|
|
||||||
// Decrement down to the next address
|
// Decrement down to the next address
|
||||||
ReadAddress--;
|
ReadAddress -= sizeof(UINT32);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -251,7 +220,7 @@ NorFlashReadCfiData (
|
|||||||
}
|
}
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashReadStatusRegister(
|
NorFlashReadStatusRegister (
|
||||||
IN UINTN SR_Address
|
IN UINTN SR_Address
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -265,12 +234,12 @@ NorFlashReadStatusRegister(
|
|||||||
|
|
||||||
do {
|
do {
|
||||||
// Prepare to read the status register
|
// 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
|
// Snapshot the status register
|
||||||
StatusRegister = *pStatusRegister;
|
StatusRegister = *pStatusRegister;
|
||||||
}
|
}
|
||||||
// The chip is busy while the WRITE bit is not asserted
|
// 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:
|
// Perform a full status check:
|
||||||
@ -294,42 +263,38 @@ NorFlashReadStatusRegister(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If an error is detected we must clear the Status Register
|
// 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;
|
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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOLEAN
|
BOOLEAN
|
||||||
NorFlashBlockIsLocked(
|
NorFlashBlockIsLocked (
|
||||||
IN UINTN BlockAddress
|
IN UINTN BlockAddress
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
volatile UINT32 *pReadData;
|
|
||||||
UINT32 LockStatus;
|
UINT32 LockStatus;
|
||||||
BOOLEAN BlockIsLocked = TRUE;
|
BOOLEAN BlockIsLocked = TRUE;
|
||||||
|
|
||||||
// Prepare the read address
|
|
||||||
pReadData = (UINT32 *) CREATE_NOR_ADDRESS( BlockAddress, 2 );
|
|
||||||
|
|
||||||
// Send command for reading device id
|
// 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
|
// Read block lock status
|
||||||
LockStatus = *pReadData;
|
LockStatus = MmioRead32 (CREATE_NOR_ADDRESS( BlockAddress, 2 ));
|
||||||
|
|
||||||
// Decode block lock status
|
// Decode block lock status
|
||||||
LockStatus = FOLD_32BIT_INTO_16BIT(LockStatus);
|
LockStatus = FOLD_32BIT_INTO_16BIT(LockStatus);
|
||||||
|
|
||||||
if( (LockStatus & 0x2) != 0 ) {
|
if((LockStatus & 0x2) != 0) {
|
||||||
DEBUG((EFI_D_ERROR, "UnlockSingleBlock: WARNING: Block LOCKED DOWN\n"));
|
DEBUG((EFI_D_ERROR, "UnlockSingleBlock: WARNING: Block LOCKED DOWN\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if( (LockStatus & 0x1) == 0 ) {
|
if((LockStatus & 0x1) == 0) {
|
||||||
// This means the block is unlocked
|
// This means the block is unlocked
|
||||||
DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: Block 0x%08x unlocked\n", BlockAddress ));
|
DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: Block 0x%08x unlocked\n", BlockAddress ));
|
||||||
BlockIsLocked = FALSE;
|
BlockIsLocked = FALSE;
|
||||||
@ -340,7 +305,7 @@ NorFlashBlockIsLocked(
|
|||||||
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashUnlockSingleBlock(
|
NorFlashUnlockSingleBlock (
|
||||||
IN UINTN BlockAddress
|
IN UINTN BlockAddress
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@ -349,17 +314,14 @@ NorFlashUnlockSingleBlock(
|
|||||||
// Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations
|
// Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations
|
||||||
// and to protect shared data structures.
|
// 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
|
// Request an unlock
|
||||||
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_UNLOCK_BLOCK );
|
SEND_NOR_COMMAND(BlockAddress, 0, P30_CMD_UNLOCK_BLOCK);
|
||||||
}
|
|
||||||
|
|
||||||
// Put device back into Read Array mode
|
// 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));
|
DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: BlockAddress=0x%08x, Exit Status = \"%r\".\n", BlockAddress, Status));
|
||||||
|
|
||||||
@ -368,14 +330,14 @@ NorFlashUnlockSingleBlock(
|
|||||||
|
|
||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashUnlockSingleBlockIfNecessary(
|
NorFlashUnlockSingleBlockIfNecessary (
|
||||||
IN UINTN BlockAddress
|
IN UINTN BlockAddress
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
if ( NorFlashBlockIsLocked( BlockAddress ) == TRUE ) {
|
if ( NorFlashBlockIsLocked(BlockAddress) == TRUE ) {
|
||||||
Status = NorFlashUnlockSingleBlock( BlockAddress );
|
Status = NorFlashUnlockSingleBlock(BlockAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
@ -386,15 +348,15 @@ NorFlashUnlockSingleBlockIfNecessary(
|
|||||||
* The following function presumes that the block has already been unlocked.
|
* The following function presumes that the block has already been unlocked.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashEraseSingleBlock(
|
NorFlashEraseSingleBlock (
|
||||||
IN UINTN BlockAddress
|
IN UINTN BlockAddress
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
|
|
||||||
// Request a block erase and then confirm it
|
// 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_SETUP);
|
||||||
SEND_NOR_COMMAND( BlockAddress, 0, P30_CMD_BLOCK_ERASE_CONFIRM );
|
SEND_NOR_COMMAND (BlockAddress, 0, P30_CMD_BLOCK_ERASE_CONFIRM);
|
||||||
// Wait until the status register gives us the all clear
|
// Wait until the status register gives us the all clear
|
||||||
Status = NorFlashReadStatusRegister( BlockAddress );
|
Status = NorFlashReadStatusRegister( BlockAddress );
|
||||||
|
|
||||||
@ -408,16 +370,16 @@ NorFlashEraseSingleBlock(
|
|||||||
* The following function presumes that the block has already been unlocked.
|
* The following function presumes that the block has already been unlocked.
|
||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashUnlockAndEraseSingleBlock(
|
NorFlashUnlockAndEraseSingleBlock (
|
||||||
IN UINTN BlockAddress
|
IN UINTN BlockAddress
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
|
|
||||||
// Unlock the block if we have to
|
// Unlock the block if we have to
|
||||||
Status = NorFlashUnlockSingleBlockIfNecessary( BlockAddress );
|
Status = NorFlashUnlockSingleBlockIfNecessary (BlockAddress);
|
||||||
if (!EFI_ERROR(Status)) {
|
if (!EFI_ERROR(Status)) {
|
||||||
Status = NorFlashEraseSingleBlock( BlockAddress );
|
Status = NorFlashEraseSingleBlock(BlockAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
@ -426,8 +388,8 @@ NorFlashUnlockAndEraseSingleBlock(
|
|||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashWriteSingleWord (
|
NorFlashWriteSingleWord (
|
||||||
IN UINTN WordAddress,
|
IN UINTN WordAddress,
|
||||||
IN UINT32 WriteData
|
IN UINT32 WriteData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@ -465,9 +427,9 @@ NorFlashWriteSingleWord (
|
|||||||
*/
|
*/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashWriteBuffer (
|
NorFlashWriteBuffer (
|
||||||
IN UINTN TargetAddress,
|
IN UINTN TargetAddress,
|
||||||
IN UINTN BufferSizeInBytes,
|
IN UINTN BufferSizeInBytes,
|
||||||
IN UINT32 *Buffer
|
IN UINT32 *Buffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
@ -546,10 +508,10 @@ NorFlashWriteBuffer (
|
|||||||
|
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
NorFlashWriteSingleBlock (
|
NorFlashWriteSingleBlock (
|
||||||
IN UINTN DeviceBaseAddress,
|
IN UINTN DeviceBaseAddress,
|
||||||
IN EFI_LBA Lba,
|
IN EFI_LBA Lba,
|
||||||
IN UINT32 *DataBuffer,
|
IN UINT32 *DataBuffer,
|
||||||
IN UINT32 BlockSizeInWords
|
IN UINT32 BlockSizeInWords
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status = EFI_SUCCESS;
|
||||||
@ -575,7 +537,7 @@ NorFlashWriteSingleBlock (
|
|||||||
WordAddress = BlockAddress;
|
WordAddress = BlockAddress;
|
||||||
|
|
||||||
// Check that the address starts at a 32-word boundary, i.e. last 7 bits must be zero
|
// 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.
|
// First, break the entire block into buffer-sized chunks.
|
||||||
BuffersInBlock = (UINTN)BlockSizeInWords / P30_MAX_BUFFER_SIZE_IN_BYTES;
|
BuffersInBlock = (UINTN)BlockSizeInWords / P30_MAX_BUFFER_SIZE_IN_BYTES;
|
||||||
@ -635,7 +597,6 @@ NorFlashWriteBlocks (
|
|||||||
UINT32 BlockSizeInWords;
|
UINT32 BlockSizeInWords;
|
||||||
UINT32 NumBlocks;
|
UINT32 NumBlocks;
|
||||||
UINT32 BlockCount;
|
UINT32 BlockCount;
|
||||||
volatile UINT32 *VersatileExpress_SYS_FLASH;
|
|
||||||
|
|
||||||
// The buffer must be valid
|
// The buffer must be valid
|
||||||
if (Buffer == NULL) {
|
if (Buffer == NULL) {
|
||||||
@ -668,15 +629,6 @@ NorFlashWriteBlocks (
|
|||||||
return EFI_INVALID_PARAMETER;
|
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;
|
BlockSizeInWords = Instance->Media.BlockSize / 4;
|
||||||
|
|
||||||
// Because the target *Buffer is a pointer to VOID, we must put all the data into a pointer
|
// 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
|
// Get the address to start reading from
|
||||||
StartAddress = GET_NOR_BLOCK_ADDRESS( Instance->BaseAddress,
|
StartAddress = GET_NOR_BLOCK_ADDRESS (Instance->BaseAddress,
|
||||||
Lba,
|
Lba,
|
||||||
Instance->Media.BlockSize
|
Instance->Media.BlockSize
|
||||||
);
|
);
|
||||||
|
|
||||||
// Put the device into Read Array mode
|
// 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
|
// Readout the data
|
||||||
CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);
|
CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);
|
||||||
@ -760,11 +712,8 @@ NorFlashReset (
|
|||||||
IN NOR_FLASH_INSTANCE *Instance
|
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
|
// 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;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -777,18 +726,39 @@ NorFlashInitialise (
|
|||||||
IN EFI_SYSTEM_TABLE *SystemTable
|
IN EFI_SYSTEM_TABLE *SystemTable
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status = EFI_SUCCESS;
|
EFI_STATUS Status;
|
||||||
UINT32 Index;
|
UINT32 Index;
|
||||||
UINTN NvStorageVariableBase = (UINTN) PcdGet32 (PcdFlashNvStorageVariableBase);
|
NOR_FLASH_DESCRIPTION* NorFlashDevices;
|
||||||
|
UINT32 NorFlashDeviceCount;
|
||||||
|
BOOLEAN ContainVariableStorage;
|
||||||
|
|
||||||
for (Index = 0; Index < NOR_FLASH_LAST_DEVICE; Index++) {
|
Status = NorFlashPlatformInitialization ();
|
||||||
Status = NorFlashCreateInstance(
|
if (EFI_ERROR(Status)) {
|
||||||
mNorFlashDescription[Index].BaseAddress,
|
DEBUG((EFI_D_ERROR,"NorFlashInitialise: Fail to initialize Nor Flash devices\n"));
|
||||||
mNorFlashDescription[Index].Size,
|
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);
|
||||||
|
|
||||||
|
Status = NorFlashCreateInstance (
|
||||||
|
NorFlashDevices[Index].BaseAddress,
|
||||||
|
NorFlashDevices[Index].Size,
|
||||||
Index,
|
Index,
|
||||||
mNorFlashDescription[Index].BlockSize,
|
NorFlashDevices[Index].BlockSize,
|
||||||
(mNorFlashDescription[Index].BaseAddress == NvStorageVariableBase),
|
ContainVariableStorage,
|
||||||
&mNorFlashDescription[Index].Guid,
|
&NorFlashDevices[Index].Guid,
|
||||||
&mNorFlashInstances[Index]
|
&mNorFlashInstances[Index]
|
||||||
);
|
);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
@ -1,6 +1,6 @@
|
|||||||
/** @file NorFlashDxe.h
|
/** @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
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
@ -21,19 +21,17 @@
|
|||||||
#include <Protocol/BlockIo.h>
|
#include <Protocol/BlockIo.h>
|
||||||
#include <Protocol/FirmwareVolumeBlock.h>
|
#include <Protocol/FirmwareVolumeBlock.h>
|
||||||
|
|
||||||
|
#include <Library/DebugLib.h>
|
||||||
|
#include <Library/IoLib.h>
|
||||||
|
#include <Library/NorFlashPlatformLib.h>
|
||||||
|
#include <Library/UefiLib.h>
|
||||||
|
|
||||||
#include <ArmPlatform.h>
|
#include <ArmPlatform.h>
|
||||||
|
|
||||||
#define HIGH_16_BITS 0xFFFF0000
|
#define HIGH_16_BITS 0xFFFF0000
|
||||||
#define LOW_16_BITS 0x0000FFFF
|
#define LOW_16_BITS 0x0000FFFF
|
||||||
#define LOW_8_BITS 0x000000FF
|
#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
|
// Device access macros
|
||||||
// These are necessary because we use 2 x 16bit parts to make up 32bit data
|
// 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,
|
// Each command must be sent simultaneously to both chips,
|
||||||
// i.e. at the lower 16 bits AND at the higher 16 bits
|
// 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 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 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) )
|
#define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)((Lba) * LbaSize) )
|
||||||
|
|
||||||
// Status Register Bits
|
// Status Register Bits
|
||||||
#define P30_SR_BIT_WRITE 0x00800080 /* Bit 7 */
|
#define P30_SR_BIT_WRITE (BIT7 << 16 | BIT7)
|
||||||
#define P30_SR_BIT_ERASE_SUSPEND 0x00400040 /* Bit 6 */
|
#define P30_SR_BIT_ERASE_SUSPEND (BIT6 << 16 | BIT6)
|
||||||
#define P30_SR_BIT_ERASE 0x00200020 /* Bit 5 */
|
#define P30_SR_BIT_ERASE (BIT5 << 16 | BIT5)
|
||||||
#define P30_SR_BIT_PROGRAM 0x00100010 /* Bit 4 */
|
#define P30_SR_BIT_PROGRAM (BIT4 << 16 | BIT4)
|
||||||
#define P30_SR_BIT_VPP 0x00080008 /* Bit 3 */
|
#define P30_SR_BIT_VPP (BIT3 << 16 | BIT3)
|
||||||
#define P30_SR_BIT_PROGRAM_SUSPEND 0x00040004 /* Bit 2 */
|
#define P30_SR_BIT_PROGRAM_SUSPEND (BIT2 << 16 | BIT2)
|
||||||
#define P30_SR_BIT_BLOCK_LOCKED 0x00020002 /* Bit 1 */
|
#define P30_SR_BIT_BLOCK_LOCKED (BIT1 << 16 | BIT1)
|
||||||
#define P30_SR_BIT_BEFP 0x00010001 /* Bit 0 */
|
#define P30_SR_BIT_BEFP (BIT0 << 16 | BIT0)
|
||||||
|
|
||||||
// Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family
|
// Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family
|
||||||
|
|
||||||
@ -120,13 +118,6 @@ typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE;
|
|||||||
|
|
||||||
typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* 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 {
|
typedef struct {
|
||||||
VENDOR_DEVICE_PATH Vendor;
|
VENDOR_DEVICE_PATH Vendor;
|
||||||
EFI_DEVICE_PATH_PROTOCOL End;
|
EFI_DEVICE_PATH_PROTOCOL End;
|
||||||
@ -141,6 +132,7 @@ struct _NOR_FLASH_INSTANCE {
|
|||||||
|
|
||||||
UINTN BaseAddress;
|
UINTN BaseAddress;
|
||||||
UINTN Size;
|
UINTN Size;
|
||||||
|
EFI_LBA StartLba;
|
||||||
|
|
||||||
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
|
EFI_BLOCK_IO_PROTOCOL BlockIoProtocol;
|
||||||
EFI_BLOCK_IO_MEDIA Media;
|
EFI_BLOCK_IO_MEDIA Media;
|
||||||
@ -151,6 +143,24 @@ struct _NOR_FLASH_INSTANCE {
|
|||||||
NOR_FLASH_DEVICE_PATH DevicePath;
|
NOR_FLASH_DEVICE_PATH DevicePath;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
NorFlashBlkIoInitialize (
|
NorFlashBlkIoInitialize (
|
@ -29,13 +29,14 @@
|
|||||||
[Packages]
|
[Packages]
|
||||||
MdePkg/MdePkg.dec
|
MdePkg/MdePkg.dec
|
||||||
MdeModulePkg/MdeModulePkg.dec
|
MdeModulePkg/MdeModulePkg.dec
|
||||||
ArmPlatformPkg/ArmVExpressPkg/ArmVExpressPkg.dec
|
ArmPlatformPkg/ArmPlatformPkg.dec
|
||||||
|
|
||||||
[LibraryClasses]
|
[LibraryClasses]
|
||||||
IoLib
|
IoLib
|
||||||
BaseLib
|
BaseLib
|
||||||
UefiLib
|
|
||||||
DebugLib
|
DebugLib
|
||||||
|
NorFlashPlatformLib
|
||||||
|
UefiLib
|
||||||
UefiDriverEntryPoint
|
UefiDriverEntryPoint
|
||||||
UefiBootServicesTableLib
|
UefiBootServicesTableLib
|
||||||
|
|
||||||
@ -49,9 +50,12 @@
|
|||||||
gEfiFirmwareVolumeBlockProtocolGuid
|
gEfiFirmwareVolumeBlockProtocolGuid
|
||||||
|
|
||||||
[Pcd.common]
|
[Pcd.common]
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
|
||||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingBase
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwWorkingSize
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareBase
|
||||||
|
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageFtwSpareSize
|
||||||
|
|
||||||
[Depex]
|
[Depex]
|
||||||
#
|
#
|
@ -16,7 +16,6 @@
|
|||||||
#include <Library/PcdLib.h>
|
#include <Library/PcdLib.h>
|
||||||
#include <Library/BaseLib.h>
|
#include <Library/BaseLib.h>
|
||||||
#include <Library/UefiLib.h>
|
#include <Library/UefiLib.h>
|
||||||
#include <Library/DebugLib.h>
|
|
||||||
#include <Library/BaseMemoryLib.h>
|
#include <Library/BaseMemoryLib.h>
|
||||||
#include <Library/MemoryAllocationLib.h>
|
#include <Library/MemoryAllocationLib.h>
|
||||||
#include <Library/UefiBootServicesTableLib.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);
|
HeadersLength = sizeof(EFI_FIRMWARE_VOLUME_HEADER) + sizeof(EFI_FV_BLOCK_MAP_ENTRY) + sizeof(VARIABLE_STORE_HEADER);
|
||||||
Headers = AllocateZeroPool(HeadersLength);
|
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
|
// EFI_FIRMWARE_VOLUME_HEADER
|
||||||
//
|
//
|
||||||
FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers;
|
FirmwareVolumeHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Headers;
|
||||||
CopyGuid (&FirmwareVolumeHeader->FileSystemGuid, &gEfiSystemNvDataFvGuid);
|
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->Signature = EFI_FVH_SIGNATURE;
|
||||||
FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
|
FirmwareVolumeHeader->Attributes = (EFI_FVB_ATTRIBUTES_2) (
|
||||||
EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
|
EFI_FVB2_READ_ENABLED_CAP | // Reads may be enabled
|
||||||
@ -96,9 +112,9 @@ InitializeFvAndVariableStoreHeaders (
|
|||||||
VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;
|
VariableStoreHeader->State = VARIABLE_STORE_HEALTHY;
|
||||||
|
|
||||||
// Install the combined super-header in the NorFlash
|
// 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;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,18 +136,23 @@ ValidateFvHeader (
|
|||||||
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
|
||||||
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
VARIABLE_STORE_HEADER *VariableStoreHeader;
|
||||||
UINTN VariableStoreLength;
|
UINTN VariableStoreLength;
|
||||||
|
UINTN FvLength;
|
||||||
|
|
||||||
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Instance->BaseAddress;
|
FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Instance->BaseAddress;
|
||||||
|
|
||||||
|
FvLength = PcdGet32(PcdFlashNvStorageVariableSize) + PcdGet32(PcdFlashNvStorageFtwWorkingSize) +
|
||||||
|
PcdGet32(PcdFlashNvStorageFtwSpareSize);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Verify the header revision, header signature, length
|
// Verify the header revision, header signature, length
|
||||||
// Length of FvBlock cannot be 2**64-1
|
// Length of FvBlock cannot be 2**64-1
|
||||||
// HeaderLength cannot be an odd number
|
// HeaderLength cannot be an odd number
|
||||||
//
|
//
|
||||||
if ( ( FwVolHeader->Revision != EFI_FVH_REVISION )
|
if ( (FwVolHeader->Revision != EFI_FVH_REVISION)
|
||||||
|| ( FwVolHeader->Signature != EFI_FVH_SIGNATURE )
|
|| (FwVolHeader->Signature != EFI_FVH_SIGNATURE)
|
||||||
|| ( FwVolHeader->FvLength != Instance->Media.BlockSize * (Instance->Media.LastBlock + 1) )
|
|| (FwVolHeader->FvLength != FvLength)
|
||||||
) {
|
)
|
||||||
|
{
|
||||||
DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n"));
|
DEBUG ((EFI_D_ERROR, "ValidateFvHeader: No Firmware Volume header present\n"));
|
||||||
return EFI_NOT_FOUND;
|
return EFI_NOT_FOUND;
|
||||||
}
|
}
|
||||||
@ -278,7 +299,7 @@ FvbGetPhysicalAddress(
|
|||||||
|
|
||||||
ASSERT(Address != NULL);
|
ASSERT(Address != NULL);
|
||||||
|
|
||||||
*Address = Instance->BaseAddress;
|
*Address = PcdGet32 (PcdFlashNvStorageVariableBase);
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -310,7 +331,7 @@ FvbGetPhysicalAddress(
|
|||||||
**/
|
**/
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
FvbGetBlockSize(
|
FvbGetBlockSize (
|
||||||
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
|
IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This,
|
||||||
IN EFI_LBA Lba,
|
IN EFI_LBA Lba,
|
||||||
OUT UINTN *BlockSize,
|
OUT UINTN *BlockSize,
|
||||||
@ -399,7 +420,7 @@ FvbRead (
|
|||||||
|
|
||||||
Instance = INSTANCE_FROM_FVB_THIS(This);
|
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) {
|
if (!Instance->Initialized) {
|
||||||
Instance->Initialize(Instance);
|
Instance->Initialize(Instance);
|
||||||
@ -415,9 +436,9 @@ FvbRead (
|
|||||||
|
|
||||||
// The read must not span block boundaries.
|
// The read must not span block boundaries.
|
||||||
// We need to check each variable individually because adding two large values together overflows.
|
// We need to check each variable individually because adding two large values together overflows.
|
||||||
if ( ( Offset >= BlockSize ) ||
|
if ((Offset >= BlockSize) ||
|
||||||
( *NumBytes > BlockSize ) ||
|
(*NumBytes > BlockSize) ||
|
||||||
( (Offset + *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 ));
|
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;
|
return EFI_BAD_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
@ -433,13 +454,13 @@ FvbRead (
|
|||||||
BlockBuffer = AllocateRuntimePool(BlockSize);
|
BlockBuffer = AllocateRuntimePool(BlockSize);
|
||||||
|
|
||||||
// Check if the memory allocation was successful
|
// 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));
|
DEBUG ((EFI_D_ERROR, "FvbRead: ERROR - Could not allocate BlockBuffer @ 0x%08x.\n", BlockBuffer));
|
||||||
return EFI_DEVICE_ERROR;
|
return EFI_DEVICE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read NOR Flash data into shadow buffer
|
// 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)) {
|
if (EFI_ERROR (TempStatus)) {
|
||||||
// Return one of the pre-approved error statuses
|
// Return one of the pre-approved error statuses
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
@ -453,8 +474,6 @@ FvbRead (
|
|||||||
|
|
||||||
FREE_MEMORY:
|
FREE_MEMORY:
|
||||||
FreePool(BlockBuffer);
|
FreePool(BlockBuffer);
|
||||||
|
|
||||||
DEBUG ((DEBUG_BLKIO, "FvbRead - end\n"));
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,7 +553,7 @@ FvbWrite (
|
|||||||
Instance->Initialize(Instance);
|
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;
|
Status = EFI_SUCCESS;
|
||||||
TempStatus = Status;
|
TempStatus = Status;
|
||||||
@ -576,7 +595,7 @@ FvbWrite (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read NOR Flash data into shadow buffer
|
// 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)) {
|
if (EFI_ERROR (TempStatus)) {
|
||||||
// Return one of the pre-approved error statuses
|
// Return one of the pre-approved error statuses
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
@ -587,7 +606,7 @@ FvbWrite (
|
|||||||
CopyMem((BlockBuffer + Offset), Buffer, *NumBytes);
|
CopyMem((BlockBuffer + Offset), Buffer, *NumBytes);
|
||||||
|
|
||||||
// Write the modified buffer back to the NorFlash
|
// 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)) {
|
if (EFI_ERROR (TempStatus)) {
|
||||||
// Return one of the pre-approved error statuses
|
// Return one of the pre-approved error statuses
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
@ -650,7 +669,7 @@ FvbEraseBlocks (
|
|||||||
)
|
)
|
||||||
{
|
{
|
||||||
EFI_STATUS Status;
|
EFI_STATUS Status;
|
||||||
VA_LIST args;
|
VA_LIST Args;
|
||||||
UINTN BlockAddress; // Physical address of Lba to erase
|
UINTN BlockAddress; // Physical address of Lba to erase
|
||||||
EFI_LBA StartingLba; // Lba from which we start erasing
|
EFI_LBA StartingLba; // Lba from which we start erasing
|
||||||
UINTN NumOfLba; // Number of Lba blocks to erase
|
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
|
// Before erasing, check the entire list of parameters to ensure all specified blocks are valid
|
||||||
|
|
||||||
VA_START (args, This);
|
VA_START (Args, This);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
// Get the Lba from which we start erasing
|
// 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?
|
// Have we reached the end of the list?
|
||||||
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
|
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
|
||||||
@ -685,30 +702,27 @@ FvbEraseBlocks (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// How many Lba blocks are we requested to erase?
|
// 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
|
// 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));
|
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", Instance->StartLba + StartingLba, NumOfLba, Instance->Media.LastBlock));
|
||||||
if ((NumOfLba == 0) || ((StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) {
|
if ((NumOfLba == 0) || ((Instance->StartLba + StartingLba + NumOfLba - 1) > Instance->Media.LastBlock)) {
|
||||||
VA_END (args);
|
VA_END (Args);
|
||||||
DEBUG ((DEBUG_BLKIO, "FvbEraseBlocks: Check if: ( StartingLba=%ld + NumOfLba=%d - 1 ) > LastBlock=%ld.\n", StartingLba, NumOfLba, Instance->Media.LastBlock));
|
|
||||||
DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
|
DEBUG ((EFI_D_ERROR, "FvbEraseBlocks: ERROR - Lba range goes past the last Lba.\n"));
|
||||||
Status = EFI_INVALID_PARAMETER;
|
Status = EFI_INVALID_PARAMETER;
|
||||||
goto EXIT;
|
goto EXIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (TRUE);
|
} while (TRUE);
|
||||||
|
VA_END (Args);
|
||||||
|
|
||||||
VA_END (args);
|
|
||||||
|
|
||||||
|
//
|
||||||
// To get here, all must be ok, so start erasing
|
// To get here, all must be ok, so start erasing
|
||||||
|
//
|
||||||
VA_START (args, This);
|
VA_START (Args, This);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|
||||||
// Get the Lba from which we start erasing
|
// 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?
|
// Have we reached the end of the list?
|
||||||
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
|
if (StartingLba == EFI_LBA_LIST_TERMINATOR) {
|
||||||
@ -717,7 +731,7 @@ FvbEraseBlocks (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// How many Lba blocks are we requested to erase?
|
// 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
|
// Go through each one and erase it
|
||||||
while (NumOfLba > 0) {
|
while (NumOfLba > 0) {
|
||||||
@ -725,15 +739,15 @@ FvbEraseBlocks (
|
|||||||
// Get the physical address of Lba to erase
|
// Get the physical address of Lba to erase
|
||||||
BlockAddress = GET_NOR_BLOCK_ADDRESS (
|
BlockAddress = GET_NOR_BLOCK_ADDRESS (
|
||||||
Instance->BaseAddress,
|
Instance->BaseAddress,
|
||||||
StartingLba,
|
Instance->StartLba + StartingLba,
|
||||||
Instance->Media.BlockSize
|
Instance->Media.BlockSize
|
||||||
);
|
);
|
||||||
|
|
||||||
// Erase it
|
// 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);
|
Status = NorFlashUnlockAndEraseSingleBlock (BlockAddress);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
VA_END (args);
|
VA_END (Args);
|
||||||
Status = EFI_DEVICE_ERROR;
|
Status = EFI_DEVICE_ERROR;
|
||||||
goto EXIT;
|
goto EXIT;
|
||||||
}
|
}
|
||||||
@ -742,10 +756,8 @@ FvbEraseBlocks (
|
|||||||
StartingLba++;
|
StartingLba++;
|
||||||
NumOfLba--;
|
NumOfLba--;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (TRUE);
|
} while (TRUE);
|
||||||
|
VA_END (Args);
|
||||||
VA_END (args);
|
|
||||||
|
|
||||||
EXIT:
|
EXIT:
|
||||||
return Status;
|
return Status;
|
||||||
@ -755,18 +767,23 @@ EFI_STATUS
|
|||||||
EFIAPI
|
EFIAPI
|
||||||
NorFlashFvbInitialize (
|
NorFlashFvbInitialize (
|
||||||
IN NOR_FLASH_INSTANCE* Instance
|
IN NOR_FLASH_INSTANCE* Instance
|
||||||
) {
|
)
|
||||||
EFI_STATUS Status;
|
{
|
||||||
|
EFI_STATUS Status;
|
||||||
|
UINT32 FvbNumLba;
|
||||||
|
|
||||||
DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
|
DEBUG((DEBUG_BLKIO,"NorFlashFvbInitialize\n"));
|
||||||
|
|
||||||
Status = NorFlashBlkIoInitialize(Instance);
|
Status = NorFlashBlkIoInitialize (Instance);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - Failed to initialize FVB\n"));
|
DEBUG((EFI_D_ERROR,"NorFlashFvbInitialize: ERROR - Failed to initialize FVB\n"));
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
Instance->Initialized = TRUE;
|
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
|
// Determine if there is a valid header at the beginning of the NorFlash
|
||||||
Status = ValidateFvHeader (Instance);
|
Status = ValidateFvHeader (Instance);
|
||||||
if (EFI_ERROR(Status)) {
|
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"));
|
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
|
// 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)) {
|
if (EFI_ERROR(Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install all appropriate headers
|
// Install all appropriate headers
|
||||||
InitializeFvAndVariableStoreHeaders ( Instance );
|
Status = InitializeFvAndVariableStoreHeaders (Instance);
|
||||||
if (EFI_ERROR(Status)) {
|
if (EFI_ERROR(Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
35
ArmPlatformPkg/Include/Library/NorFlashPlatformLib.h
Normal file
35
ArmPlatformPkg/Include/Library/NorFlashPlatformLib.h
Normal file
@ -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_ */
|
Loading…
x
Reference in New Issue
Block a user