| 1 | /** @file NorFlashDxe.h |
| 2 | |
| 3 | Copyright (c) 2010, ARM Ltd. All rights reserved.<BR> |
| 4 | This program and the accompanying materials |
| 5 | are licensed and made available under the terms and conditions of the BSD License |
| 6 | which accompanies this distribution. The full text of the license may be found at |
| 7 | http://opensource.org/licenses/bsd-license.php |
| 8 | |
| 9 | THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, |
| 10 | WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. |
| 11 | |
| 12 | **/ |
| 13 | |
| 14 | #ifndef __NOR_FLASH_DXE_H__ |
| 15 | #define __NOR_FLASH_DXE_H__ |
| 16 | |
| 17 | |
| 18 | #include <Base.h> |
| 19 | #include <PiDxe.h> |
| 20 | |
| 21 | #include <Protocol/BlockIo.h> |
| 22 | #include <Protocol/FirmwareVolumeBlock.h> |
| 23 | |
| 24 | #include <ArmPlatform.h> |
| 25 | |
| 26 | #define HIGH_16_BITS 0xFFFF0000 |
| 27 | #define LOW_16_BITS 0x0000FFFF |
| 28 | #define LOW_8_BITS 0x000000FF |
| 29 | |
| 30 | // Hardware addresses |
| 31 | |
| 32 | #define VE_SYSTEM_REGISTERS_OFFSET 0x00000000 |
| 33 | #define SYSTEM_REGISTER_SYS_FLASH 0x0000004C |
| 34 | |
| 35 | #define VE_REGISTER_SYS_FLASH_ADDR ( ARM_VE_BOARD_PERIPH_BASE + VE_SYSTEM_REGISTERS_OFFSET + SYSTEM_REGISTER_SYS_FLASH ) |
| 36 | |
| 37 | // Device access macros |
| 38 | // These are necessary because we use 2 x 16bit parts to make up 32bit data |
| 39 | |
| 40 | #define FOLD_32BIT_INTO_16BIT(value) ( ( value >> 16 ) | ( value & LOW_16_BITS ) ) |
| 41 | |
| 42 | #define GET_LOW_BYTE(value) ( value & LOW_8_BITS ) |
| 43 | #define GET_HIGH_BYTE(value) ( GET_LOW_BYTE( value >> 16 ) ) |
| 44 | |
| 45 | // Each command must be sent simultaneously to both chips, |
| 46 | // i.e. at the lower 16 bits AND at the higher 16 bits |
| 47 | #define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ( (volatile UINTN *)((BaseAddr) + ((OffsetAddr) << 2)) ) |
| 48 | #define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) ) |
| 49 | #define SEND_NOR_COMMAND(BaseAddr,OffsetAddr,Cmd) ( *CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) = CREATE_DUAL_CMD(Cmd) ) |
| 50 | #define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)(Lba * LbaSize) ) |
| 51 | |
| 52 | // Status Register Bits |
| 53 | #define P30_SR_BIT_WRITE 0x00800080 /* Bit 7 */ |
| 54 | #define P30_SR_BIT_ERASE_SUSPEND 0x00400040 /* Bit 6 */ |
| 55 | #define P30_SR_BIT_ERASE 0x00200020 /* Bit 5 */ |
| 56 | #define P30_SR_BIT_PROGRAM 0x00100010 /* Bit 4 */ |
| 57 | #define P30_SR_BIT_VPP 0x00080008 /* Bit 3 */ |
| 58 | #define P30_SR_BIT_PROGRAM_SUSPEND 0x00040004 /* Bit 2 */ |
| 59 | #define P30_SR_BIT_BLOCK_LOCKED 0x00020002 /* Bit 1 */ |
| 60 | #define P30_SR_BIT_BEFP 0x00010001 /* Bit 0 */ |
| 61 | |
| 62 | // Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family |
| 63 | |
| 64 | // On chip buffer size for buffered programming operations |
| 65 | // There are 2 chips, each chip can buffer up to 32 (16-bit)words, and each word is 2 bytes. |
| 66 | // Therefore the total size of the buffer is 2 x 32 x 2 = 128 bytes |
| 67 | #define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128) |
| 68 | #define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4)) |
| 69 | #define MAX_BUFFERED_PROG_ITERATIONS 10000000 |
| 70 | #define BOUNDARY_OF_32_WORDS 0x7F |
| 71 | |
| 72 | // CFI Addresses |
| 73 | #define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10 |
| 74 | #define P30_CFI_ADDR_VENDOR_ID 0x13 |
| 75 | |
| 76 | // CFI Data |
| 77 | #define CFI_QRY 0x00595251 |
| 78 | |
| 79 | // READ Commands |
| 80 | #define P30_CMD_READ_DEVICE_ID 0x0090 |
| 81 | #define P30_CMD_READ_STATUS_REGISTER 0x0070 |
| 82 | #define P30_CMD_CLEAR_STATUS_REGISTER 0x0050 |
| 83 | #define P30_CMD_READ_ARRAY 0x00FF |
| 84 | #define P30_CMD_READ_CFI_QUERY 0x0098 |
| 85 | |
| 86 | // WRITE Commands |
| 87 | #define P30_CMD_WORD_PROGRAM_SETUP 0x0040 |
| 88 | #define P30_CMD_ALTERNATE_WORD_PROGRAM_SETUP 0x0010 |
| 89 | #define P30_CMD_BUFFERED_PROGRAM_SETUP 0x00E8 |
| 90 | #define P30_CMD_BUFFERED_PROGRAM_CONFIRM 0x00D0 |
| 91 | #define P30_CMD_BEFP_SETUP 0x0080 |
| 92 | #define P30_CMD_BEFP_CONFIRM 0x00D0 |
| 93 | |
| 94 | // ERASE Commands |
| 95 | #define P30_CMD_BLOCK_ERASE_SETUP 0x0020 |
| 96 | #define P30_CMD_BLOCK_ERASE_CONFIRM 0x00D0 |
| 97 | |
| 98 | // SUSPEND Commands |
| 99 | #define P30_CMD_PROGRAM_OR_ERASE_SUSPEND 0x00B0 |
| 100 | #define P30_CMD_SUSPEND_RESUME 0x00D0 |
| 101 | |
| 102 | // BLOCK LOCKING / UNLOCKING Commands |
| 103 | #define P30_CMD_LOCK_BLOCK_SETUP 0x0060 |
| 104 | #define P30_CMD_LOCK_BLOCK 0x0001 |
| 105 | #define P30_CMD_UNLOCK_BLOCK 0x00D0 |
| 106 | #define P30_CMD_LOCK_DOWN_BLOCK 0x002F |
| 107 | |
| 108 | // PROTECTION Commands |
| 109 | #define P30_CMD_PROGRAM_PROTECTION_REGISTER_SETUP 0x00C0 |
| 110 | |
| 111 | // CONFIGURATION Commands |
| 112 | #define P30_CMD_READ_CONFIGURATION_REGISTER_SETUP 0x0060 |
| 113 | #define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003 |
| 114 | |
| 115 | #define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0') |
| 116 | #define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE) |
| 117 | #define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE) |
| 118 | |
| 119 | typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE; |
| 120 | |
| 121 | typedef EFI_STATUS (*NOR_FLASH_INITIALIZE) (NOR_FLASH_INSTANCE* Instance); |
| 122 | |
| 123 | typedef struct { |
| 124 | UINTN BaseAddress; |
| 125 | UINTN Size; |
| 126 | UINTN BlockSize; |
| 127 | BOOLEAN SupportFvb; |
| 128 | EFI_GUID Guid; |
| 129 | } NOR_FLASH_DESCRIPTION; |
| 130 | |
| 131 | typedef struct { |
| 132 | VENDOR_DEVICE_PATH Vendor; |
| 133 | EFI_DEVICE_PATH_PROTOCOL End; |
| 134 | } NOR_FLASH_DEVICE_PATH; |
| 135 | |
| 136 | struct _NOR_FLASH_INSTANCE { |
| 137 | UINT32 Signature; |
| 138 | EFI_HANDLE Handle; |
| 139 | |
| 140 | BOOLEAN Initialized; |
| 141 | NOR_FLASH_INITIALIZE Initialize; |
| 142 | |
| 143 | UINTN BaseAddress; |
| 144 | UINTN Size; |
| 145 | |
| 146 | EFI_BLOCK_IO_PROTOCOL BlockIoProtocol; |
| 147 | EFI_BLOCK_IO_MEDIA Media; |
| 148 | |
| 149 | BOOLEAN SupportFvb; |
| 150 | EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; |
| 151 | |
| 152 | NOR_FLASH_DEVICE_PATH DevicePath; |
| 153 | }; |
| 154 | |
| 155 | EFI_STATUS |
| 156 | EFIAPI |
| 157 | NorFlashBlkIoInitialize ( |
| 158 | IN NOR_FLASH_INSTANCE* Instance |
| 159 | ); |
| 160 | |
| 161 | EFI_STATUS |
| 162 | NorFlashReadCfiData ( |
| 163 | IN UINTN BaseAddress, |
| 164 | IN UINTN CFI_Offset, |
| 165 | IN UINT32 NumberOfBytes, |
| 166 | OUT UINT32 *Data |
| 167 | ); |
| 168 | |
| 169 | EFI_STATUS |
| 170 | NorFlashWriteBuffer ( |
| 171 | IN UINTN TargetAddress, |
| 172 | IN UINTN BufferSizeInBytes, |
| 173 | IN UINT32 *Buffer |
| 174 | ); |
| 175 | |
| 176 | |
| 177 | // |
| 178 | // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset |
| 179 | // |
| 180 | EFI_STATUS |
| 181 | EFIAPI |
| 182 | NorFlashBlockIoReset ( |
| 183 | IN EFI_BLOCK_IO_PROTOCOL *This, |
| 184 | IN BOOLEAN ExtendedVerification |
| 185 | ); |
| 186 | |
| 187 | // |
| 188 | // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks |
| 189 | // |
| 190 | EFI_STATUS |
| 191 | EFIAPI |
| 192 | NorFlashBlockIoReadBlocks ( |
| 193 | IN EFI_BLOCK_IO_PROTOCOL *This, |
| 194 | IN UINT32 MediaId, |
| 195 | IN EFI_LBA Lba, |
| 196 | IN UINTN BufferSizeInBytes, |
| 197 | OUT VOID *Buffer |
| 198 | ); |
| 199 | |
| 200 | // |
| 201 | // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks |
| 202 | // |
| 203 | EFI_STATUS |
| 204 | EFIAPI |
| 205 | NorFlashBlockIoWriteBlocks ( |
| 206 | IN EFI_BLOCK_IO_PROTOCOL *This, |
| 207 | IN UINT32 MediaId, |
| 208 | IN EFI_LBA Lba, |
| 209 | IN UINTN BufferSizeInBytes, |
| 210 | IN VOID *Buffer |
| 211 | ); |
| 212 | |
| 213 | // |
| 214 | // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks |
| 215 | // |
| 216 | EFI_STATUS |
| 217 | EFIAPI |
| 218 | NorFlashBlockIoFlushBlocks ( |
| 219 | IN EFI_BLOCK_IO_PROTOCOL *This |
| 220 | ); |
| 221 | |
| 222 | |
| 223 | // |
| 224 | // NorFlashFvbDxe.c |
| 225 | // |
| 226 | |
| 227 | EFI_STATUS |
| 228 | EFIAPI |
| 229 | NorFlashFvbInitialize ( |
| 230 | IN NOR_FLASH_INSTANCE* Instance |
| 231 | ); |
| 232 | |
| 233 | EFI_STATUS |
| 234 | EFIAPI |
| 235 | FvbGetAttributes( |
| 236 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 237 | OUT EFI_FVB_ATTRIBUTES_2 *Attributes |
| 238 | ); |
| 239 | |
| 240 | EFI_STATUS |
| 241 | EFIAPI |
| 242 | FvbSetAttributes( |
| 243 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 244 | IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes |
| 245 | ); |
| 246 | |
| 247 | EFI_STATUS |
| 248 | EFIAPI |
| 249 | FvbGetPhysicalAddress( |
| 250 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 251 | OUT EFI_PHYSICAL_ADDRESS *Address |
| 252 | ); |
| 253 | |
| 254 | EFI_STATUS |
| 255 | EFIAPI |
| 256 | FvbGetBlockSize( |
| 257 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 258 | IN EFI_LBA Lba, |
| 259 | OUT UINTN *BlockSize, |
| 260 | OUT UINTN *NumberOfBlocks |
| 261 | ); |
| 262 | |
| 263 | EFI_STATUS |
| 264 | EFIAPI |
| 265 | FvbRead( |
| 266 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 267 | IN EFI_LBA Lba, |
| 268 | IN UINTN Offset, |
| 269 | IN OUT UINTN *NumBytes, |
| 270 | IN OUT UINT8 *Buffer |
| 271 | ); |
| 272 | |
| 273 | EFI_STATUS |
| 274 | EFIAPI |
| 275 | FvbWrite( |
| 276 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 277 | IN EFI_LBA Lba, |
| 278 | IN UINTN Offset, |
| 279 | IN OUT UINTN *NumBytes, |
| 280 | IN UINT8 *Buffer |
| 281 | ); |
| 282 | |
| 283 | EFI_STATUS |
| 284 | EFIAPI |
| 285 | FvbEraseBlocks( |
| 286 | IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, |
| 287 | ... |
| 288 | ); |
| 289 | |
| 290 | // |
| 291 | // NorFlashDxe.c |
| 292 | // |
| 293 | |
| 294 | EFI_STATUS |
| 295 | NorFlashUnlockAndEraseSingleBlock( |
| 296 | IN UINTN BlockAddress |
| 297 | ); |
| 298 | |
| 299 | EFI_STATUS |
| 300 | NorFlashWriteSingleBlock ( |
| 301 | IN UINTN DeviceBaseAddress, |
| 302 | IN EFI_LBA Lba, |
| 303 | IN UINT32 *pDataBuffer, |
| 304 | IN UINT32 BlockSizeInWords |
| 305 | ); |
| 306 | |
| 307 | EFI_STATUS |
| 308 | NorFlashWriteBlocks ( |
| 309 | IN NOR_FLASH_INSTANCE *Instance, |
| 310 | IN EFI_LBA Lba, |
| 311 | IN UINTN BufferSizeInBytes, |
| 312 | IN VOID *Buffer |
| 313 | ); |
| 314 | |
| 315 | EFI_STATUS |
| 316 | NorFlashReadBlocks ( |
| 317 | IN NOR_FLASH_INSTANCE *Instance, |
| 318 | IN EFI_LBA Lba, |
| 319 | IN UINTN BufferSizeInBytes, |
| 320 | OUT VOID *Buffer |
| 321 | ); |
| 322 | |
| 323 | EFI_STATUS |
| 324 | NorFlashReset ( |
| 325 | IN NOR_FLASH_INSTANCE *Instance |
| 326 | ); |
| 327 | |
| 328 | #endif /* __NOR_FLASH_DXE_H__ */ |