1 /** @file NorFlashDxe.h 2 3 Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR> 4 5 SPDX-License-Identifier: BSD-2-Clause-Patent 6 7 **/ 8 9 #ifndef __NOR_FLASH_DXE_H__ 10 #define __NOR_FLASH_DXE_H__ 11 12 13 #include <Base.h> 14 #include <PiDxe.h> 15 16 #include <Guid/EventGroup.h> 17 18 #include <Protocol/BlockIo.h> 19 #include <Protocol/DiskIo.h> 20 #include <Protocol/FirmwareVolumeBlock.h> 21 22 #include <Library/DebugLib.h> 23 #include <Library/IoLib.h> 24 #include <Library/NorFlashPlatformLib.h> 25 #include <Library/UefiLib.h> 26 #include <Library/UefiRuntimeLib.h> 27 28 #define NOR_FLASH_ERASE_RETRY 10 29 30 // Device access macros 31 // These are necessary because we use 2 x 16bit parts to make up 32bit data 32 33 #define HIGH_16_BITS 0xFFFF0000 34 #define LOW_16_BITS 0x0000FFFF 35 #define LOW_8_BITS 0x000000FF 36 37 #define FOLD_32BIT_INTO_16BIT(value) ( ( value >> 16 ) | ( value & LOW_16_BITS ) ) 38 39 #define GET_LOW_BYTE(value) ( value & LOW_8_BITS ) 40 #define GET_HIGH_BYTE(value) ( GET_LOW_BYTE( value >> 16 ) ) 41 42 // Each command must be sent simultaneously to both chips, 43 // i.e. at the lower 16 bits AND at the higher 16 bits 44 #define CREATE_NOR_ADDRESS(BaseAddr,OffsetAddr) ((BaseAddr) + ((OffsetAddr) << 2)) 45 #define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) ) 46 #define SEND_NOR_COMMAND(BaseAddr,Offset,Cmd) MmioWrite32 (CREATE_NOR_ADDRESS(BaseAddr,Offset), CREATE_DUAL_CMD(Cmd)) 47 #define GET_NOR_BLOCK_ADDRESS(BaseAddr,Lba,LbaSize)( BaseAddr + (UINTN)((Lba) * LbaSize) ) 48 49 // Status Register Bits 50 #define P30_SR_BIT_WRITE (BIT7 << 16 | BIT7) 51 #define P30_SR_BIT_ERASE_SUSPEND (BIT6 << 16 | BIT6) 52 #define P30_SR_BIT_ERASE (BIT5 << 16 | BIT5) 53 #define P30_SR_BIT_PROGRAM (BIT4 << 16 | BIT4) 54 #define P30_SR_BIT_VPP (BIT3 << 16 | BIT3) 55 #define P30_SR_BIT_PROGRAM_SUSPEND (BIT2 << 16 | BIT2) 56 #define P30_SR_BIT_BLOCK_LOCKED (BIT1 << 16 | BIT1) 57 #define P30_SR_BIT_BEFP (BIT0 << 16 | BIT0) 58 59 // Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family 60 61 // On chip buffer size for buffered programming operations 62 // There are 2 chips, each chip can buffer up to 32 (16-bit)words, and each word is 2 bytes. 63 // Therefore the total size of the buffer is 2 x 32 x 2 = 128 bytes 64 #define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128) 65 #define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4)) 66 #define MAX_BUFFERED_PROG_ITERATIONS 10000000 67 #define BOUNDARY_OF_32_WORDS 0x7F 68 69 // CFI Addresses 70 #define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10 71 #define P30_CFI_ADDR_VENDOR_ID 0x13 72 73 // CFI Data 74 #define CFI_QRY 0x00595251 75 76 // READ Commands 77 #define P30_CMD_READ_DEVICE_ID 0x0090 78 #define P30_CMD_READ_STATUS_REGISTER 0x0070 79 #define P30_CMD_CLEAR_STATUS_REGISTER 0x0050 80 #define P30_CMD_READ_ARRAY 0x00FF 81 #define P30_CMD_READ_CFI_QUERY 0x0098 82 83 // WRITE Commands 84 #define P30_CMD_WORD_PROGRAM_SETUP 0x0040 85 #define P30_CMD_ALTERNATE_WORD_PROGRAM_SETUP 0x0010 86 #define P30_CMD_BUFFERED_PROGRAM_SETUP 0x00E8 87 #define P30_CMD_BUFFERED_PROGRAM_CONFIRM 0x00D0 88 #define P30_CMD_BEFP_SETUP 0x0080 89 #define P30_CMD_BEFP_CONFIRM 0x00D0 90 91 // ERASE Commands 92 #define P30_CMD_BLOCK_ERASE_SETUP 0x0020 93 #define P30_CMD_BLOCK_ERASE_CONFIRM 0x00D0 94 95 // SUSPEND Commands 96 #define P30_CMD_PROGRAM_OR_ERASE_SUSPEND 0x00B0 97 #define P30_CMD_SUSPEND_RESUME 0x00D0 98 99 // BLOCK LOCKING / UNLOCKING Commands 100 #define P30_CMD_LOCK_BLOCK_SETUP 0x0060 101 #define P30_CMD_LOCK_BLOCK 0x0001 102 #define P30_CMD_UNLOCK_BLOCK 0x00D0 103 #define P30_CMD_LOCK_DOWN_BLOCK 0x002F 104 105 // PROTECTION Commands 106 #define P30_CMD_PROGRAM_PROTECTION_REGISTER_SETUP 0x00C0 107 108 // CONFIGURATION Commands 109 #define P30_CMD_READ_CONFIGURATION_REGISTER_SETUP 0x0060 110 #define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003 111 112 #define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0') 113 #define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE) 114 #define INSTANCE_FROM_BLKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, BlockIoProtocol, NOR_FLASH_SIGNATURE) 115 #define INSTANCE_FROM_DISKIO_THIS(a) CR(a, NOR_FLASH_INSTANCE, DiskIoProtocol, NOR_FLASH_SIGNATURE) 116 117 typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE; 118 119 #pragma pack (1) 120 typedef struct { 121 VENDOR_DEVICE_PATH Vendor; 122 UINT8 Index; 123 EFI_DEVICE_PATH_PROTOCOL End; 124 } NOR_FLASH_DEVICE_PATH; 125 #pragma pack () 126 127 struct _NOR_FLASH_INSTANCE { 128 UINT32 Signature; 129 EFI_HANDLE Handle; 130 131 UINTN DeviceBaseAddress; 132 UINTN RegionBaseAddress; 133 UINTN Size; 134 EFI_LBA StartLba; 135 136 EFI_BLOCK_IO_PROTOCOL BlockIoProtocol; 137 EFI_BLOCK_IO_MEDIA Media; 138 EFI_DISK_IO_PROTOCOL DiskIoProtocol; 139 140 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol; 141 VOID* ShadowBuffer; 142 143 NOR_FLASH_DEVICE_PATH DevicePath; 144 }; 145 146 EFI_STATUS 147 NorFlashReadCfiData ( 148 IN UINTN DeviceBaseAddress, 149 IN UINTN CFI_Offset, 150 IN UINT32 NumberOfBytes, 151 OUT UINT32 *Data 152 ); 153 154 EFI_STATUS 155 NorFlashWriteBuffer ( 156 IN NOR_FLASH_INSTANCE *Instance, 157 IN UINTN TargetAddress, 158 IN UINTN BufferSizeInBytes, 159 IN UINT32 *Buffer 160 ); 161 162 // 163 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset 164 // 165 EFI_STATUS 166 EFIAPI 167 NorFlashBlockIoReset ( 168 IN EFI_BLOCK_IO_PROTOCOL *This, 169 IN BOOLEAN ExtendedVerification 170 ); 171 172 // 173 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks 174 // 175 EFI_STATUS 176 EFIAPI 177 NorFlashBlockIoReadBlocks ( 178 IN EFI_BLOCK_IO_PROTOCOL *This, 179 IN UINT32 MediaId, 180 IN EFI_LBA Lba, 181 IN UINTN BufferSizeInBytes, 182 OUT VOID *Buffer 183 ); 184 185 // 186 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks 187 // 188 EFI_STATUS 189 EFIAPI 190 NorFlashBlockIoWriteBlocks ( 191 IN EFI_BLOCK_IO_PROTOCOL *This, 192 IN UINT32 MediaId, 193 IN EFI_LBA Lba, 194 IN UINTN BufferSizeInBytes, 195 IN VOID *Buffer 196 ); 197 198 // 199 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks 200 // 201 EFI_STATUS 202 EFIAPI 203 NorFlashBlockIoFlushBlocks ( 204 IN EFI_BLOCK_IO_PROTOCOL *This 205 ); 206 207 // 208 // DiskIO Protocol function EFI_DISK_IO_PROTOCOL.ReadDisk 209 // 210 EFI_STATUS 211 EFIAPI 212 NorFlashDiskIoReadDisk ( 213 IN EFI_DISK_IO_PROTOCOL *This, 214 IN UINT32 MediaId, 215 IN UINT64 Offset, 216 IN UINTN BufferSize, 217 OUT VOID *Buffer 218 ); 219 220 // 221 // DiskIO Protocol function EFI_DISK_IO_PROTOCOL.WriteDisk 222 // 223 EFI_STATUS 224 EFIAPI 225 NorFlashDiskIoWriteDisk ( 226 IN EFI_DISK_IO_PROTOCOL *This, 227 IN UINT32 MediaId, 228 IN UINT64 Offset, 229 IN UINTN BufferSize, 230 IN VOID *Buffer 231 ); 232 233 // 234 // NorFlashFvbDxe.c 235 // 236 237 EFI_STATUS 238 EFIAPI 239 NorFlashFvbInitialize ( 240 IN NOR_FLASH_INSTANCE* Instance 241 ); 242 243 EFI_STATUS 244 EFIAPI 245 FvbGetAttributes( 246 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 247 OUT EFI_FVB_ATTRIBUTES_2 *Attributes 248 ); 249 250 EFI_STATUS 251 EFIAPI 252 FvbSetAttributes( 253 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 254 IN OUT EFI_FVB_ATTRIBUTES_2 *Attributes 255 ); 256 257 EFI_STATUS 258 EFIAPI 259 FvbGetPhysicalAddress( 260 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 261 OUT EFI_PHYSICAL_ADDRESS *Address 262 ); 263 264 EFI_STATUS 265 EFIAPI 266 FvbGetBlockSize( 267 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 268 IN EFI_LBA Lba, 269 OUT UINTN *BlockSize, 270 OUT UINTN *NumberOfBlocks 271 ); 272 273 EFI_STATUS 274 EFIAPI 275 FvbRead( 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 OUT UINT8 *Buffer 281 ); 282 283 EFI_STATUS 284 EFIAPI 285 FvbWrite( 286 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 287 IN EFI_LBA Lba, 288 IN UINTN Offset, 289 IN OUT UINTN *NumBytes, 290 IN UINT8 *Buffer 291 ); 292 293 EFI_STATUS 294 EFIAPI 295 FvbEraseBlocks( 296 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL *This, 297 ... 298 ); 299 300 // 301 // NorFlashDxe.c 302 // 303 304 EFI_STATUS 305 NorFlashUnlockAndEraseSingleBlock ( 306 IN NOR_FLASH_INSTANCE *Instance, 307 IN UINTN BlockAddress 308 ); 309 310 EFI_STATUS 311 NorFlashWriteSingleBlock ( 312 IN NOR_FLASH_INSTANCE *Instance, 313 IN EFI_LBA Lba, 314 IN UINTN Offset, 315 IN OUT UINTN *NumBytes, 316 IN UINT8 *Buffer 317 ); 318 319 EFI_STATUS 320 NorFlashWriteBlocks ( 321 IN NOR_FLASH_INSTANCE *Instance, 322 IN EFI_LBA Lba, 323 IN UINTN BufferSizeInBytes, 324 IN VOID *Buffer 325 ); 326 327 EFI_STATUS 328 NorFlashReadBlocks ( 329 IN NOR_FLASH_INSTANCE *Instance, 330 IN EFI_LBA Lba, 331 IN UINTN BufferSizeInBytes, 332 OUT VOID *Buffer 333 ); 334 335 EFI_STATUS 336 NorFlashRead ( 337 IN NOR_FLASH_INSTANCE *Instance, 338 IN EFI_LBA Lba, 339 IN UINTN Offset, 340 IN UINTN BufferSizeInBytes, 341 OUT VOID *Buffer 342 ); 343 344 EFI_STATUS 345 NorFlashWrite ( 346 IN NOR_FLASH_INSTANCE *Instance, 347 IN EFI_LBA Lba, 348 IN UINTN Offset, 349 IN OUT UINTN *NumBytes, 350 IN UINT8 *Buffer 351 ); 352 353 EFI_STATUS 354 NorFlashReset ( 355 IN NOR_FLASH_INSTANCE *Instance 356 ); 357 358 #endif /* __NOR_FLASH_DXE_H__ */ 359