• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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