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