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