NOR_FLASH_SIGNATURE, // Signature\r
NULL, // Handle ... NEED TO BE FILLED\r
\r
- FALSE, // Initialized\r
- NULL, // Initialize\r
-\r
0, // DeviceBaseAddress ... NEED TO BE FILLED\r
0, // RegionBaseAddress ... NEED TO BE FILLED\r
0, // Size ... NEED TO BE FILLED\r
NorFlashDiskIoWriteDisk // WriteDisk\r
},\r
\r
- FALSE, // SupportFvb ... NEED TO BE FILLED\r
{\r
FvbGetAttributes, // GetAttributes\r
FvbSetAttributes, // SetAttributes\r
}\r
\r
if (SupportFvb) {\r
- Instance->SupportFvb = TRUE;\r
- Instance->Initialize = NorFlashFvbInitialize;\r
+ NorFlashFvbInitialize (Instance);\r
\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Instance->Handle,\r
return Status;\r
}\r
} else {\r
- Instance->Initialized = TRUE;\r
-\r
Status = gBS->InstallMultipleProtocolInterfaces (\r
&Instance->Handle,\r
&gEfiDevicePathProtocolGuid, &Instance->DevicePath,\r
\r
// Write the data to the NOR Flash, advancing each address by 4 bytes\r
for(Count=0; Count < BufferSizeInWords; Count++, Data++, Buffer++) {\r
- *Data = *Buffer;\r
+ MmioWrite32 ((UINTN)Data, *Buffer);\r
}\r
\r
// Issue the Buffered Program Confirm command, to start the programming operation\r
return Status;\r
}\r
\r
+#define BOTH_ALIGNED(a, b, align) ((((UINTN)(a) | (UINTN)(b)) & ((align) - 1)) == 0)\r
+\r
+/**\r
+ Copy Length bytes from Source to Destination, using aligned accesses only.\r
+ Note that this implementation uses memcpy() semantics rather then memmove()\r
+ semantics, i.e., SourceBuffer and DestinationBuffer should not overlap.\r
+\r
+ @param DestinationBuffer The target of the copy request.\r
+ @param SourceBuffer The place to copy from.\r
+ @param Length The number of bytes to copy.\r
+\r
+ @return Destination\r
+\r
+**/\r
+STATIC\r
+VOID *\r
+AlignedCopyMem (\r
+ OUT VOID *DestinationBuffer,\r
+ IN CONST VOID *SourceBuffer,\r
+ IN UINTN Length\r
+ )\r
+{\r
+ UINT8 *Destination8;\r
+ CONST UINT8 *Source8;\r
+ UINT32 *Destination32;\r
+ CONST UINT32 *Source32;\r
+ UINT64 *Destination64;\r
+ CONST UINT64 *Source64;\r
+\r
+ if (BOTH_ALIGNED(DestinationBuffer, SourceBuffer, 8) && Length >= 8) {\r
+ Destination64 = DestinationBuffer;\r
+ Source64 = SourceBuffer;\r
+ while (Length >= 8) {\r
+ *Destination64++ = *Source64++;\r
+ Length -= 8;\r
+ }\r
+\r
+ Destination8 = (UINT8 *)Destination64;\r
+ Source8 = (CONST UINT8 *)Source64;\r
+ } else if (BOTH_ALIGNED(DestinationBuffer, SourceBuffer, 4) && Length >= 4) {\r
+ Destination32 = DestinationBuffer;\r
+ Source32 = SourceBuffer;\r
+ while (Length >= 4) {\r
+ *Destination32++ = *Source32++;\r
+ Length -= 4;\r
+ }\r
+\r
+ Destination8 = (UINT8 *)Destination32;\r
+ Source8 = (CONST UINT8 *)Source32;\r
+ } else {\r
+ Destination8 = DestinationBuffer;\r
+ Source8 = SourceBuffer;\r
+ }\r
+ while (Length-- != 0) {\r
+ *Destination8++ = *Source8++;\r
+ }\r
+ return DestinationBuffer;\r
+}\r
+\r
EFI_STATUS\r
NorFlashReadBlocks (\r
IN NOR_FLASH_INSTANCE *Instance,\r
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
\r
// Readout the data\r
- CopyMem(Buffer, (UINTN *)StartAddress, BufferSizeInBytes);\r
+ AlignedCopyMem (Buffer, (VOID *)StartAddress, BufferSizeInBytes);\r
\r
return EFI_SUCCESS;\r
}\r
OUT VOID *Buffer\r
)\r
{\r
- UINT32 NumBlocks;\r
- UINTN StartAddress;\r
+ UINTN StartAddress;\r
\r
// The buffer must be valid\r
if (Buffer == NULL) {\r
return EFI_SUCCESS;\r
}\r
\r
- // All blocks must be within the device\r
- NumBlocks = ((UINT32)BufferSizeInBytes) / Instance->Media.BlockSize ;\r
-\r
- if ((Lba + NumBlocks) > (Instance->Media.LastBlock + 1)) {\r
- DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed last block\n"));\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (Offset + BufferSizeInBytes >= Instance->Size) {\r
+ if (((Lba * Instance->Media.BlockSize) + Offset + BufferSizeInBytes) > Instance->Size) {\r
DEBUG ((EFI_D_ERROR, "NorFlashRead: ERROR - Read will exceed device size.\n"));\r
return EFI_INVALID_PARAMETER;\r
}\r
SEND_NOR_COMMAND (Instance->DeviceBaseAddress, 0, P30_CMD_READ_ARRAY);\r
\r
// Readout the data\r
- CopyMem (Buffer, (UINTN *)(StartAddress + Offset), BufferSizeInBytes);\r
+ AlignedCopyMem (Buffer, (VOID *)(StartAddress + Offset), BufferSizeInBytes);\r
\r
return EFI_SUCCESS;\r
}\r
\r
PrevBlockAddress = 0;\r
\r
- if (!Instance->Initialized && Instance->Initialize) {\r
- Instance->Initialize(Instance);\r
- }\r
-\r
DEBUG ((DEBUG_BLKIO, "NorFlashWriteSingleBlock(Parameters: Lba=%ld, Offset=0x%x, *NumBytes=0x%x, Buffer @ 0x%08x)\n", Lba, Offset, *NumBytes, Buffer));\r
\r
// Detect WriteDisabled state\r