3 Copyright (c) 2011 - 2014, ARM Ltd. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #ifndef __VIRT_NOR_FLASH__
10 #define __VIRT_NOR_FLASH__
15 #include <Guid/EventGroup.h>
17 #include <Protocol/FirmwareVolumeBlock.h>
19 #include <Library/DebugLib.h>
20 #include <Library/IoLib.h>
21 #include <Library/UefiLib.h>
22 #include <Library/UefiRuntimeLib.h>
23 #include <Library/VirtNorFlashPlatformLib.h>
25 #define NOR_FLASH_ERASE_RETRY 10
27 // Device access macros
28 // These are necessary because we use 2 x 16bit parts to make up 32bit data
30 #define HIGH_16_BITS 0xFFFF0000
31 #define LOW_16_BITS 0x0000FFFF
32 #define LOW_8_BITS 0x000000FF
34 #define FOLD_32BIT_INTO_16BIT(value) ( ( value >> 16 ) | ( value & LOW_16_BITS ) )
36 #define GET_LOW_BYTE(value) ( value & LOW_8_BITS )
37 #define GET_HIGH_BYTE(value) ( GET_LOW_BYTE( value >> 16 ) )
39 // Each command must be sent simultaneously to both chips,
40 // i.e. at the lower 16 bits AND at the higher 16 bits
41 #define CREATE_NOR_ADDRESS(BaseAddr, OffsetAddr) ((BaseAddr) + ((OffsetAddr) << 2))
42 #define CREATE_DUAL_CMD(Cmd) ( ( Cmd << 16) | ( Cmd & LOW_16_BITS) )
43 #define SEND_NOR_COMMAND(BaseAddr, Offset, Cmd) MmioWrite32 (CREATE_NOR_ADDRESS(BaseAddr,Offset), CREATE_DUAL_CMD(Cmd))
44 #define GET_NOR_BLOCK_ADDRESS(BaseAddr, Lba, LbaSize) ( BaseAddr + (UINTN)((Lba) * LbaSize) )
46 // Status Register Bits
47 #define P30_SR_BIT_WRITE (BIT7 << 16 | BIT7)
48 #define P30_SR_BIT_ERASE_SUSPEND (BIT6 << 16 | BIT6)
49 #define P30_SR_BIT_ERASE (BIT5 << 16 | BIT5)
50 #define P30_SR_BIT_PROGRAM (BIT4 << 16 | BIT4)
51 #define P30_SR_BIT_VPP (BIT3 << 16 | BIT3)
52 #define P30_SR_BIT_PROGRAM_SUSPEND (BIT2 << 16 | BIT2)
53 #define P30_SR_BIT_BLOCK_LOCKED (BIT1 << 16 | BIT1)
54 #define P30_SR_BIT_BEFP (BIT0 << 16 | BIT0)
56 // Device Commands for Intel StrataFlash(R) Embedded Memory (P30) Family
58 // On chip buffer size for buffered programming operations
59 // There are 2 chips, each chip can buffer up to 32 (16-bit)words, and each word is 2 bytes.
60 // Therefore the total size of the buffer is 2 x 32 x 2 = 128 bytes
61 #define P30_MAX_BUFFER_SIZE_IN_BYTES ((UINTN)128)
62 #define P30_MAX_BUFFER_SIZE_IN_WORDS (P30_MAX_BUFFER_SIZE_IN_BYTES/((UINTN)4))
63 #define MAX_BUFFERED_PROG_ITERATIONS 10000000
64 #define BOUNDARY_OF_32_WORDS 0x7F
67 #define P30_CFI_ADDR_QUERY_UNIQUE_QRY 0x10
68 #define P30_CFI_ADDR_VENDOR_ID 0x13
71 #define CFI_QRY 0x00595251
74 #define P30_CMD_READ_DEVICE_ID 0x0090
75 #define P30_CMD_READ_STATUS_REGISTER 0x0070
76 #define P30_CMD_CLEAR_STATUS_REGISTER 0x0050
77 #define P30_CMD_READ_ARRAY 0x00FF
78 #define P30_CMD_READ_CFI_QUERY 0x0098
81 #define P30_CMD_WORD_PROGRAM_SETUP 0x0040
82 #define P30_CMD_ALTERNATE_WORD_PROGRAM_SETUP 0x0010
83 #define P30_CMD_BUFFERED_PROGRAM_SETUP 0x00E8
84 #define P30_CMD_BUFFERED_PROGRAM_CONFIRM 0x00D0
85 #define P30_CMD_BEFP_SETUP 0x0080
86 #define P30_CMD_BEFP_CONFIRM 0x00D0
89 #define P30_CMD_BLOCK_ERASE_SETUP 0x0020
90 #define P30_CMD_BLOCK_ERASE_CONFIRM 0x00D0
93 #define P30_CMD_PROGRAM_OR_ERASE_SUSPEND 0x00B0
94 #define P30_CMD_SUSPEND_RESUME 0x00D0
96 // BLOCK LOCKING / UNLOCKING Commands
97 #define P30_CMD_LOCK_BLOCK_SETUP 0x0060
98 #define P30_CMD_LOCK_BLOCK 0x0001
99 #define P30_CMD_UNLOCK_BLOCK 0x00D0
100 #define P30_CMD_LOCK_DOWN_BLOCK 0x002F
102 // PROTECTION Commands
103 #define P30_CMD_PROGRAM_PROTECTION_REGISTER_SETUP 0x00C0
105 // CONFIGURATION Commands
106 #define P30_CMD_READ_CONFIGURATION_REGISTER_SETUP 0x0060
107 #define P30_CMD_READ_CONFIGURATION_REGISTER 0x0003
109 #define NOR_FLASH_SIGNATURE SIGNATURE_32('n', 'o', 'r', '0')
110 #define INSTANCE_FROM_FVB_THIS(a) CR(a, NOR_FLASH_INSTANCE, FvbProtocol, NOR_FLASH_SIGNATURE)
112 typedef struct _NOR_FLASH_INSTANCE NOR_FLASH_INSTANCE
;
116 VENDOR_DEVICE_PATH Vendor
;
118 EFI_DEVICE_PATH_PROTOCOL End
;
119 } NOR_FLASH_DEVICE_PATH
;
122 struct _NOR_FLASH_INSTANCE
{
126 UINTN DeviceBaseAddress
;
127 UINTN RegionBaseAddress
;
133 EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL FvbProtocol
;
136 NOR_FLASH_DEVICE_PATH DevicePath
;
140 NorFlashReadCfiData (
141 IN UINTN DeviceBaseAddress
,
143 IN UINT32 NumberOfBytes
,
148 NorFlashWriteBuffer (
149 IN NOR_FLASH_INSTANCE
*Instance
,
150 IN UINTN TargetAddress
,
151 IN UINTN BufferSizeInBytes
,
162 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
163 OUT EFI_FVB_ATTRIBUTES_2
*Attributes
169 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
170 IN OUT EFI_FVB_ATTRIBUTES_2
*Attributes
175 FvbGetPhysicalAddress (
176 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
177 OUT EFI_PHYSICAL_ADDRESS
*Address
183 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
185 OUT UINTN
*BlockSize
,
186 OUT UINTN
*NumberOfBlocks
192 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
195 IN OUT UINTN
*NumBytes
,
202 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
205 IN OUT UINTN
*NumBytes
,
212 IN CONST EFI_FIRMWARE_VOLUME_BLOCK2_PROTOCOL
*This
,
218 IN NOR_FLASH_INSTANCE
*Instance
222 InitializeFvAndVariableStoreHeaders (
223 IN NOR_FLASH_INSTANCE
*Instance
228 FvbVirtualNotifyEvent (
238 NorFlashWriteFullBlock (
239 IN NOR_FLASH_INSTANCE
*Instance
,
241 IN UINT32
*DataBuffer
,
242 IN UINT32 BlockSizeInWords
246 NorFlashUnlockAndEraseSingleBlock (
247 IN NOR_FLASH_INSTANCE
*Instance
,
248 IN UINTN BlockAddress
252 NorFlashCreateInstance (
253 IN UINTN NorFlashDeviceBase
,
254 IN UINTN NorFlashRegionBase
,
255 IN UINTN NorFlashSize
,
258 IN BOOLEAN SupportFvb
,
259 OUT NOR_FLASH_INSTANCE
**NorFlashInstance
264 NorFlashFvbInitialize (
265 IN NOR_FLASH_INSTANCE
*Instance
272 NorFlashWriteSingleBlock (
273 IN NOR_FLASH_INSTANCE
*Instance
,
276 IN OUT UINTN
*NumBytes
,
281 NorFlashWriteBlocks (
282 IN NOR_FLASH_INSTANCE
*Instance
,
284 IN UINTN BufferSizeInBytes
,
290 IN NOR_FLASH_INSTANCE
*Instance
,
292 IN UINTN BufferSizeInBytes
,
298 IN NOR_FLASH_INSTANCE
*Instance
,
301 IN UINTN BufferSizeInBytes
,
307 IN NOR_FLASH_INSTANCE
*Instance
,
310 IN OUT UINTN
*NumBytes
,
316 IN NOR_FLASH_INSTANCE
*Instance
320 NorFlashEraseSingleBlock (
321 IN NOR_FLASH_INSTANCE
*Instance
,
322 IN UINTN BlockAddress
326 NorFlashUnlockSingleBlockIfNecessary (
327 IN NOR_FLASH_INSTANCE
*Instance
,
328 IN UINTN BlockAddress
332 NorFlashWriteSingleWord (
333 IN NOR_FLASH_INSTANCE
*Instance
,
334 IN UINTN WordAddress
,
340 NorFlashVirtualNotifyEvent (
345 #endif /* __VIRT_NOR_FLASH__ */