Home | History | Annotate | Download | only in NorFlashDxe
      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 
    123 typedef struct _NOR_FLASH_INSTANCE                NOR_FLASH_INSTANCE;
    124 
    125 typedef EFI_STATUS (*NOR_FLASH_INITIALIZE)        (NOR_FLASH_INSTANCE* Instance);
    126 
    127 typedef struct {
    128   VENDOR_DEVICE_PATH                  Vendor;
    129   EFI_DEVICE_PATH_PROTOCOL            End;
    130 } NOR_FLASH_DEVICE_PATH;
    131 
    132 struct _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 
    155 extern CONST EFI_GUID* CONST          mNorFlashVariableGuid;
    156 
    157 EFI_STATUS
    158 NorFlashReadCfiData (
    159   IN  UINTN                   DeviceBaseAddress,
    160   IN  UINTN                   CFI_Offset,
    161   IN  UINT32                  NumberOfBytes,
    162   OUT UINT32                  *Data
    163   );
    164 
    165 EFI_STATUS
    166 NorFlashWriteBuffer (
    167   IN NOR_FLASH_INSTANCE     *Instance,
    168   IN UINTN                  TargetAddress,
    169   IN UINTN                  BufferSizeInBytes,
    170   IN UINT32                 *Buffer
    171   );
    172 
    173 //
    174 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.Reset
    175 //
    176 EFI_STATUS
    177 EFIAPI
    178 NorFlashBlockIoReset (
    179   IN EFI_BLOCK_IO_PROTOCOL    *This,
    180   IN BOOLEAN                  ExtendedVerification
    181   );
    182 
    183 //
    184 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.ReadBlocks
    185 //
    186 EFI_STATUS
    187 EFIAPI
    188 NorFlashBlockIoReadBlocks (
    189   IN  EFI_BLOCK_IO_PROTOCOL   *This,
    190   IN  UINT32                  MediaId,
    191   IN  EFI_LBA                 Lba,
    192   IN  UINTN                   BufferSizeInBytes,
    193   OUT VOID                    *Buffer
    194 );
    195 
    196 //
    197 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.WriteBlocks
    198 //
    199 EFI_STATUS
    200 EFIAPI
    201 NorFlashBlockIoWriteBlocks (
    202   IN  EFI_BLOCK_IO_PROTOCOL   *This,
    203   IN  UINT32                  MediaId,
    204   IN  EFI_LBA                 Lba,
    205   IN  UINTN                   BufferSizeInBytes,
    206   IN  VOID                    *Buffer
    207 );
    208 
    209 //
    210 // BlockIO Protocol function EFI_BLOCK_IO_PROTOCOL.FlushBlocks
    211 //
    212 EFI_STATUS
    213 EFIAPI
    214 NorFlashBlockIoFlushBlocks (
    215   IN EFI_BLOCK_IO_PROTOCOL    *This
    216 );
    217 
    218 //
    219 // DiskIO Protocol function EFI_DISK_IO_PROTOCOL.ReadDisk
    220 //
    221 EFI_STATUS
    222 EFIAPI
    223 NorFlashDiskIoReadDisk (
    224   IN EFI_DISK_IO_PROTOCOL         *This,
    225   IN UINT32                       MediaId,
    226   IN UINT64                       Offset,
    227   IN UINTN                        BufferSize,
    228   OUT VOID                        *Buffer
    229   );
    230 
    231 //
    232 // DiskIO Protocol function EFI_DISK_IO_PROTOCOL.WriteDisk
    233 //
    234 EFI_STATUS
    235 EFIAPI
    236 NorFlashDiskIoWriteDisk (
    237   IN EFI_DISK_IO_PROTOCOL         *This,
    238   IN UINT32                       MediaId,
    239   IN UINT64                       Offset,
    240   IN UINTN                        BufferSize,
    241   IN VOID                         *Buffer
    242   );
    243 
    244 //
    245 // NorFlashFvbDxe.c
    246 //
    247 
    248 EFI_STATUS
    249 EFIAPI
    250 NorFlashFvbInitialize (
    251   IN NOR_FLASH_INSTANCE*                            Instance
    252   );
    253 
    254 EFI_STATUS
    255 EFIAPI
    256 FvbGetAttributes(
    257   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    258   OUT       EFI_FVB_ATTRIBUTES_2                    *Attributes
    259   );
    260 
    261 EFI_STATUS
    262 EFIAPI
    263 FvbSetAttributes(
    264   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    265   IN OUT    EFI_FVB_ATTRIBUTES_2                    *Attributes
    266   );
    267 
    268 EFI_STATUS
    269 EFIAPI
    270 FvbGetPhysicalAddress(
    271   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    272   OUT       EFI_PHYSICAL_ADDRESS                    *Address
    273   );
    274 
    275 EFI_STATUS
    276 EFIAPI
    277 FvbGetBlockSize(
    278   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    279   IN        EFI_LBA                                 Lba,
    280   OUT       UINTN                                   *BlockSize,
    281   OUT       UINTN                                   *NumberOfBlocks
    282   );
    283 
    284 EFI_STATUS
    285 EFIAPI
    286 FvbRead(
    287   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    288   IN        EFI_LBA                                 Lba,
    289   IN        UINTN                                   Offset,
    290   IN OUT    UINTN                                   *NumBytes,
    291   IN OUT    UINT8                                   *Buffer
    292   );
    293 
    294 EFI_STATUS
    295 EFIAPI
    296 FvbWrite(
    297   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    298   IN        EFI_LBA                                 Lba,
    299   IN        UINTN                                   Offset,
    300   IN OUT    UINTN                                   *NumBytes,
    301   IN        UINT8                                   *Buffer
    302   );
    303 
    304 EFI_STATUS
    305 EFIAPI
    306 FvbEraseBlocks(
    307   IN CONST  EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL     *This,
    308   ...
    309   );
    310 
    311 //
    312 // NorFlashDxe.c
    313 //
    314 
    315 EFI_STATUS
    316 NorFlashUnlockAndEraseSingleBlock (
    317   IN NOR_FLASH_INSTANCE     *Instance,
    318   IN UINTN                  BlockAddress
    319   );
    320 
    321 EFI_STATUS
    322 NorFlashWriteSingleBlock (
    323   IN        NOR_FLASH_INSTANCE   *Instance,
    324   IN        EFI_LBA               Lba,
    325   IN        UINTN                 Offset,
    326   IN OUT    UINTN                *NumBytes,
    327   IN        UINT8                *Buffer
    328   );
    329 
    330 EFI_STATUS
    331 NorFlashWriteBlocks (
    332   IN  NOR_FLASH_INSTANCE *Instance,
    333   IN  EFI_LBA           Lba,
    334   IN  UINTN             BufferSizeInBytes,
    335   IN  VOID              *Buffer
    336   );
    337 
    338 EFI_STATUS
    339 NorFlashReadBlocks (
    340   IN NOR_FLASH_INSTANCE   *Instance,
    341   IN EFI_LBA              Lba,
    342   IN UINTN                BufferSizeInBytes,
    343   OUT VOID                *Buffer
    344   );
    345 
    346 EFI_STATUS
    347 NorFlashRead (
    348   IN NOR_FLASH_INSTANCE   *Instance,
    349   IN EFI_LBA              Lba,
    350   IN UINTN                Offset,
    351   IN UINTN                BufferSizeInBytes,
    352   OUT VOID                *Buffer
    353   );
    354 
    355 EFI_STATUS
    356 NorFlashWrite (
    357   IN        NOR_FLASH_INSTANCE   *Instance,
    358   IN        EFI_LBA               Lba,
    359   IN        UINTN                 Offset,
    360   IN OUT    UINTN                *NumBytes,
    361   IN        UINT8                *Buffer
    362   );
    363 
    364 EFI_STATUS
    365 NorFlashReset (
    366   IN  NOR_FLASH_INSTANCE *Instance
    367   );
    368 
    369 #endif /* __NOR_FLASH_DXE_H__ */
    370