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