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