X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=ArmPlatformPkg%2FDrivers%2FNorFlashDxe%2FNorFlashDxe.c;h=46e815beb34306eb51d25e7922ed5555a6bcfeec;hb=6281a2ed3bb3ffe57ed54cabd9a31dcf13b415f8;hp=4fac20199ba0b0e929de5a0bfcb85fda1c547788;hpb=36d66acf275135699fea9243e58e25990ab0db7f;p=mirror_edk2.git diff --git a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c index 4fac20199b..46e815beb3 100644 --- a/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c +++ b/ArmPlatformPkg/Drivers/NorFlashDxe/NorFlashDxe.c @@ -32,9 +32,6 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { NOR_FLASH_SIGNATURE, // Signature NULL, // Handle ... NEED TO BE FILLED - FALSE, // Initialized - NULL, // Initialize - 0, // DeviceBaseAddress ... NEED TO BE FILLED 0, // RegionBaseAddress ... NEED TO BE FILLED 0, // Size ... NEED TO BE FILLED @@ -69,7 +66,6 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { NorFlashDiskIoWriteDisk // WriteDisk }, - FALSE, // SupportFvb ... NEED TO BE FILLED { FvbGetAttributes, // GetAttributes FvbSetAttributes, // SetAttributes @@ -86,16 +82,14 @@ NOR_FLASH_INSTANCE mNorFlashInstanceTemplate = { { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, - (UINT8)( sizeof(VENDOR_DEVICE_PATH) ), - (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8), + { (UINT8)sizeof(VENDOR_DEVICE_PATH), (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) } }, - { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }, // GUID ... NEED TO BE FILLED + { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }, // GUID ... NEED TO BE FILLED }, { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, - sizeof (EFI_DEVICE_PATH_PROTOCOL), - 0 + { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } } } // DevicePath }; @@ -139,8 +133,7 @@ NorFlashCreateInstance ( } if (SupportFvb) { - Instance->SupportFvb = TRUE; - Instance->Initialize = NorFlashFvbInitialize; + NorFlashFvbInitialize (Instance); Status = gBS->InstallMultipleProtocolInterfaces ( &Instance->Handle, @@ -154,8 +147,6 @@ NorFlashCreateInstance ( return Status; } } else { - Instance->Initialized = TRUE; - Status = gBS->InstallMultipleProtocolInterfaces ( &Instance->Handle, &gEfiDevicePathProtocolGuid, &Instance->DevicePath, @@ -184,7 +175,7 @@ NorFlashReadStatusRegister ( return MmioRead32 (Instance->DeviceBaseAddress); } - +STATIC BOOLEAN NorFlashBlockIsLocked ( IN NOR_FLASH_INSTANCE *Instance, @@ -192,9 +183,6 @@ NorFlashBlockIsLocked ( ) { UINT32 LockStatus; - BOOLEAN BlockIsLocked; - - BlockIsLocked = TRUE; // Send command for reading device id SEND_NOR_COMMAND (BlockAddress, 2, P30_CMD_READ_DEVICE_ID); @@ -209,23 +197,16 @@ NorFlashBlockIsLocked ( DEBUG((EFI_D_ERROR, "NorFlashBlockIsLocked: WARNING: Block LOCKED DOWN\n")); } - if ((LockStatus & 0x1) == 0) { - // This means the block is unlocked - DEBUG((DEBUG_BLKIO, "UnlockSingleBlock: Block 0x%08x unlocked\n", BlockAddress)); - BlockIsLocked = FALSE; - } - - return BlockIsLocked; + return ((LockStatus & 0x1) != 0); } - +STATIC EFI_STATUS NorFlashUnlockSingleBlock ( IN NOR_FLASH_INSTANCE *Instance, IN UINTN BlockAddress ) { - EFI_STATUS Status = EFI_SUCCESS; UINT32 LockStatus; // Raise the Task Priority Level to TPL_NOTIFY to serialise all its operations @@ -264,19 +245,21 @@ NorFlashUnlockSingleBlock ( // Put device back into Read Array mode 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\n", BlockAddress)); - return Status; + return EFI_SUCCESS; } - +STATIC EFI_STATUS NorFlashUnlockSingleBlockIfNecessary ( IN NOR_FLASH_INSTANCE *Instance, IN UINTN BlockAddress ) { - EFI_STATUS Status = EFI_SUCCESS; + EFI_STATUS Status; + + Status = EFI_SUCCESS; if (NorFlashBlockIsLocked (Instance, BlockAddress) == TRUE) { Status = NorFlashUnlockSingleBlock (Instance, BlockAddress); @@ -289,6 +272,7 @@ NorFlashUnlockSingleBlockIfNecessary ( /** * The following function presumes that the block has already been unlocked. **/ +STATIC EFI_STATUS NorFlashEraseSingleBlock ( IN NOR_FLASH_INSTANCE *Instance, @@ -342,7 +326,7 @@ NorFlashEraseSingleBlock ( } /** - * The following function presumes that the block has already been unlocked. + * This function unlock and erase an entire NOR Flash block. **/ EFI_STATUS NorFlashUnlockAndEraseSingleBlock ( @@ -368,9 +352,10 @@ NorFlashUnlockAndEraseSingleBlock ( do { // Unlock the block if we have to Status = NorFlashUnlockSingleBlockIfNecessary (Instance, BlockAddress); - if (!EFI_ERROR(Status)) { - Status = NorFlashEraseSingleBlock (Instance, BlockAddress); + if (EFI_ERROR (Status)) { + break; } + Status = NorFlashEraseSingleBlock (Instance, BlockAddress); Index++; } while ((Index < NOR_FLASH_ERASE_RETRY) && (Status == EFI_WRITE_PROTECTED)); @@ -533,7 +518,7 @@ NorFlashWriteBuffer ( // Write the data to the NOR Flash, advancing each address by 4 bytes for(Count=0; Count < BufferSizeInWords; Count++, Data++, Buffer++) { - *Data = *Buffer; + MmioWrite32 ((UINTN)Data, *Buffer); } // Issue the Buffered Program Confirm command, to start the programming operation @@ -752,6 +737,65 @@ NorFlashWriteBlocks ( return Status; } +#define BOTH_ALIGNED(a, b, align) ((((UINTN)(a) | (UINTN)(b)) & ((align) - 1)) == 0) + +/** + Copy Length bytes from Source to Destination, using aligned accesses only. + Note that this implementation uses memcpy() semantics rather then memmove() + semantics, i.e., SourceBuffer and DestinationBuffer should not overlap. + + @param DestinationBuffer The target of the copy request. + @param SourceBuffer The place to copy from. + @param Length The number of bytes to copy. + + @return Destination + +**/ +STATIC +VOID * +AlignedCopyMem ( + OUT VOID *DestinationBuffer, + IN CONST VOID *SourceBuffer, + IN UINTN Length + ) +{ + UINT8 *Destination8; + CONST UINT8 *Source8; + UINT32 *Destination32; + CONST UINT32 *Source32; + UINT64 *Destination64; + CONST UINT64 *Source64; + + if (BOTH_ALIGNED(DestinationBuffer, SourceBuffer, 8) && Length >= 8) { + Destination64 = DestinationBuffer; + Source64 = SourceBuffer; + while (Length >= 8) { + *Destination64++ = *Source64++; + Length -= 8; + } + + Destination8 = (UINT8 *)Destination64; + Source8 = (CONST UINT8 *)Source64; + } else if (BOTH_ALIGNED(DestinationBuffer, SourceBuffer, 4) && Length >= 4) { + Destination32 = DestinationBuffer; + Source32 = SourceBuffer; + while (Length >= 4) { + *Destination32++ = *Source32++; + Length -= 4; + } + + Destination8 = (UINT8 *)Destination32; + Source8 = (CONST UINT8 *)Source32; + } else { + Destination8 = DestinationBuffer; + Source8 = SourceBuffer; + } + while (Length-- != 0) { + *Destination8++ = *Source8++; + } + return DestinationBuffer; +} + EFI_STATUS NorFlashReadBlocks ( IN NOR_FLASH_INSTANCE *Instance, @@ -799,7 +843,7 @@ NorFlashReadBlocks ( SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY); // Readout the data - CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes); + AlignedCopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes); return EFI_SUCCESS; } @@ -813,8 +857,7 @@ NorFlashRead ( OUT VOID *Buffer ) { - UINT32 NumBlocks; - UINTN StartAddress; + UINTN StartAddress; // The buffer must be valid if (Buffer == NULL) { @@ -826,15 +869,7 @@ NorFlashRead ( return EFI_SUCCESS; } - // All blocks must be within the device - NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ; - - if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) { - DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed last block\n")); - return EFI_INVALID_PARAMETER; - } - - if (Offset + BufferSizeInBytes >= Instance->Size) { + if (((Lba * Instance->Media.BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) { DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed device size.\n")); return EFI_INVALID_PARAMETER; } @@ -849,7 +884,7 @@ NorFlashRead ( SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY); // Readout the data - CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes); + AlignedCopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes); return EFI_SUCCESS; } @@ -882,10 +917,6 @@ NorFlashWriteSingleBlock ( PrevBlockAddress = 0; - if (!Instance->Initialized && Instance->Initialize) { - Instance->Initialize(Instance); - } - DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer)); // Detect WriteDisabled state