3 * Copyright (c) 2017 Marvell International Ltd.
5 * SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include <Library/BaseLib.h>
12 #include <Library/BaseMemoryLib.h>
13 #include <Library/DebugLib.h>
14 #include <Library/DxeServicesLib.h>
15 #include <Library/MemoryAllocationLib.h>
16 #include <Library/NorFlashInfoLib.h>
18 STATIC CONST NOR_FLASH_INFO NorFlashIds
[] = {
20 {L
"at45db011d", {0x1f, 0x22, 0x00}, 3, 256, 64 * 1024, 4, NOR_FLASH_ERASE_4K
},
21 {L
"at45db021d", {0x1f, 0x23, 0x00}, 3, 256, 64 * 1024, 8, NOR_FLASH_ERASE_4K
},
22 {L
"at45db041d", {0x1f, 0x24, 0x00}, 3, 256, 64 * 1024, 8, NOR_FLASH_ERASE_4K
},
23 {L
"at45db081d", {0x1f, 0x25, 0x00}, 3, 256, 64 * 1024, 16, NOR_FLASH_ERASE_4K
},
24 {L
"at45db161d", {0x1f, 0x26, 0x00}, 3, 256, 64 * 1024, 32, NOR_FLASH_ERASE_4K
},
25 {L
"at45db321d", {0x1f, 0x27, 0x00}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
26 {L
"at45db641d", {0x1f, 0x28, 0x00}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
27 {L
"at25df321a", {0x1f, 0x47, 0x01}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
28 {L
"at25df321", {0x1f, 0x47, 0x00}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
29 {L
"at26df081a", {0x1f, 0x45, 0x01}, 3, 256, 64 * 1024, 16, NOR_FLASH_ERASE_4K
},
31 {L
"en25q32b", {0x1c, 0x30, 0x16}, 3, 256, 64 * 1024, 64, 0},
32 {L
"en25q64", {0x1c, 0x30, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
33 {L
"en25q128b", {0x1c, 0x30, 0x18}, 3, 256, 64 * 1024, 256, 0},
34 {L
"en25s64", {0x1c, 0x38, 0x17}, 3, 256, 64 * 1024, 128, 0},
36 {L
"gd25q64b", {0xc8, 0x40, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
37 {L
"gd25lq32", {0xc8, 0x60, 0x16}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
39 {L
"is25lp032", {0x9d, 0x60, 0x16}, 3, 256, 64 * 1024, 64, 0},
40 {L
"is25lp064", {0x9d, 0x60, 0x17}, 3, 256, 64 * 1024, 128, 0},
41 {L
"is25lp128", {0x9d, 0x60, 0x18}, 3, 256, 64 * 1024, 256, 0},
43 {L
"mx25l2006e", {0xc2, 0x20, 0x12}, 3, 256, 64 * 1024, 4, 0},
44 {L
"mx25l4005", {0xc2, 0x20, 0x13}, 3, 256, 64 * 1024, 8, 0},
45 {L
"mx25l8005", {0xc2, 0x20, 0x14}, 3, 256, 64 * 1024, 16, 0},
46 {L
"mx25l1605d", {0xc2, 0x20, 0x15}, 3, 256, 64 * 1024, 32, 0},
47 {L
"mx25l3205d", {0xc2, 0x20, 0x16}, 3, 256, 64 * 1024, 64, 0},
48 {L
"mx25l6405d", {0xc2, 0x20, 0x17}, 3, 256, 64 * 1024, 128, 0},
49 {L
"mx25l12805", {0xc2, 0x20, 0x18}, 3, 256, 64 * 1024, 256, 0},
50 {L
"mx25l25635f", {0xc2, 0x20, 0x19}, 3, 256, 64 * 1024, 512, 0},
51 {L
"mx25l51235f", {0xc2, 0x20, 0x1a}, 3, 256, 64 * 1024, 1024, 0},
52 {L
"mx25l12855e", {0xc2, 0x26, 0x18}, 3, 256, 64 * 1024, 256, 0},
53 {L
"mx66u51235f", {0xc2, 0x25, 0x3a}, 3, 256, 64 * 1024, 1024, 0},
54 {L
"mx66u1g45g", {0xc2, 0x25, 0x3b}, 3, 256, 64 * 1024, 2048, 0},
55 {L
"mx66l1g45g", {0xc2, 0x20, 0x1b}, 3, 256, 64 * 1024, 2048, 0},
57 {L
"s25fl008a", {0x01, 0x02, 0x13}, 3, 256, 64 * 1024, 16, 0},
58 {L
"s25fl016a", {0x01, 0x02, 0x14}, 3, 256, 64 * 1024, 32, 0},
59 {L
"s25fl032a", {0x01, 0x02, 0x15}, 3, 256, 64 * 1024, 64, 0},
60 {L
"s25fl064a", {0x01, 0x02, 0x16}, 3, 256, 64 * 1024, 128, 0},
61 {L
"s25fl116k", {0x01, 0x40, 0x15}, 3, 256, 64 * 1024, 128, 0},
62 {L
"s25fl164k", {0x01, 0x40, 0x17, 0x01, 0x40}, 5, 256, 64 * 1024, 128, 0},
63 {L
"s25fl128p_256k", {0x01, 0x20, 0x18, 0x03, 0x00}, 5, 256, 256 * 1024, 64, 0},
64 {L
"s25fl128p_64k", {0x01, 0x20, 0x18, 0x03, 0x01}, 5, 256, 64 * 1024, 256, 0},
65 {L
"s25fl032p", {0x01, 0x02, 0x15, 0x4d, 0x00}, 5, 256, 64 * 1024, 64, 0},
66 {L
"s25fl064p", {0x01, 0x02, 0x16, 0x4d, 0x00}, 5, 256, 64 * 1024, 128, 0},
67 {L
"s25fl128s_256k", {0x01, 0x20, 0x18, 0x4d, 0x00}, 5, 256, 256 * 1024, 64, 0},
68 {L
"s25fl128s_64k", {0x01, 0x20, 0x18, 0x4d, 0x01}, 5, 256, 64 * 1024, 256, 0},
69 {L
"s25fl256s_256k", {0x01, 0x02, 0x19, 0x4d, 0x00}, 5, 256, 256 * 1024, 128, 0},
70 {L
"s25fl256s_64k", {0x01, 0x02, 0x19, 0x4d, 0x01}, 5, 256, 64 * 1024, 512, 0},
71 {L
"s25fl512s_256k", {0x01, 0x02, 0x20, 0x4d, 0x00}, 5, 256, 256 * 1024, 256, 0},
72 {L
"s25fl512s_64k", {0x01, 0x02, 0x20, 0x4d, 0x01}, 5, 256, 64 * 1024, 1024, 0},
73 {L
"s25fl512s_512k", {0x01, 0x02, 0x20, 0x4f, 0x00}, 5, 256, 256 * 1024, 256, 0},
75 {L
"m25p10", {0x20, 0x20, 0x11}, 3, 256, 32 * 1024, 4, 0},
76 {L
"m25p20", {0x20, 0x20, 0x12}, 3, 256, 64 * 1024, 4, 0},
77 {L
"m25p40", {0x20, 0x20, 0x13}, 3, 256, 64 * 1024, 8, 0},
78 {L
"m25p80", {0x20, 0x20, 0x14}, 3, 256, 64 * 1024, 16, 0},
79 {L
"m25p16", {0x20, 0x20, 0x15}, 3, 256, 64 * 1024, 32, 0},
80 {L
"m25pE16", {0x20, 0x80, 0x15, 0x10, 0x00}, 5, 256, 64 * 1024, 32, 0},
81 {L
"m25pX16", {0x20, 0x71, 0x15, 0x10, 0x00}, 5, 256, 64 * 1024, 32, 0},
82 {L
"m25p32", {0x20, 0x20, 0x16}, 3, 256, 64 * 1024, 64, 0},
83 {L
"m25p64", {0x20, 0x20, 0x17}, 3, 256, 64 * 1024, 128, 0},
84 {L
"m25p128", {0x20, 0x20, 0x18}, 3, 256, 256 * 1024, 64, 0},
85 {L
"m25pX64", {0x20, 0x71, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
86 {L
"n25q016a", {0x20, 0xbb, 0x15}, 3, 256, 64 * 1024, 32, NOR_FLASH_ERASE_4K
},
87 {L
"n25q32", {0x20, 0xba, 0x16}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
88 {L
"n25q32a", {0x20, 0xbb, 0x16}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
89 {L
"n25q64", {0x20, 0xba, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
90 {L
"n25q64a", {0x20, 0xbb, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
91 {L
"n25q128", {0x20, 0xba, 0x18}, 3, 256, 64 * 1024, 256, 0},
92 {L
"n25q128a", {0x20, 0xbb, 0x18}, 3, 256, 64 * 1024, 256, 0},
93 {L
"n25q256", {0x20, 0xba, 0x19}, 3, 256, 64 * 1024, 512, NOR_FLASH_ERASE_4K
},
94 {L
"n25q256a", {0x20, 0xbb, 0x19}, 3, 256, 64 * 1024, 512, NOR_FLASH_ERASE_4K
},
95 {L
"n25q512", {0x20, 0xba, 0x20}, 3, 256, 64 * 1024, 1024, NOR_FLASH_WRITE_FSR
| NOR_FLASH_ERASE_4K
},
96 {L
"n25q512a", {0x20, 0xbb, 0x20}, 3, 256, 64 * 1024, 1024, NOR_FLASH_WRITE_FSR
| NOR_FLASH_ERASE_4K
},
97 {L
"n25q1024", {0x20, 0xba, 0x21}, 3, 256, 64 * 1024, 2048, NOR_FLASH_WRITE_FSR
| NOR_FLASH_ERASE_4K
},
98 {L
"n25q1024a", {0x20, 0xbb, 0x21}, 3, 256, 64 * 1024, 2048, NOR_FLASH_WRITE_FSR
| NOR_FLASH_ERASE_4K
},
99 {L
"mt25qu02g", {0x20, 0xbb, 0x22}, 3, 256, 64 * 1024, 4096, NOR_FLASH_WRITE_FSR
| NOR_FLASH_ERASE_4K
},
100 {L
"mt25ql02g", {0x20, 0xba, 0x22}, 3, 256, 64 * 1024, 4096, NOR_FLASH_WRITE_FSR
| NOR_FLASH_ERASE_4K
},
102 {L
"sst25vf040b", {0xbf, 0x25, 0x8d}, 3, 256, 64 * 1024, 8, NOR_FLASH_ERASE_4K
},
103 {L
"sst25vf080b", {0xbf, 0x25, 0x8e}, 3, 256, 64 * 1024, 16, NOR_FLASH_ERASE_4K
},
104 {L
"sst25vf016b", {0xbf, 0x25, 0x41}, 3, 256, 64 * 1024, 32, NOR_FLASH_ERASE_4K
},
105 {L
"sst25vf032b", {0xbf, 0x25, 0x4a}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
106 {L
"sst25vf064c", {0xbf, 0x25, 0x4b}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
107 {L
"sst25wf512", {0xbf, 0x25, 0x01}, 3, 256, 64 * 1024, 1, NOR_FLASH_ERASE_4K
},
108 {L
"sst25wf010", {0xbf, 0x25, 0x02}, 3, 256, 64 * 1024, 2, NOR_FLASH_ERASE_4K
},
109 {L
"sst25wf020", {0xbf, 0x25, 0x03}, 3, 256, 64 * 1024, 4, NOR_FLASH_ERASE_4K
},
110 {L
"sst25wf040", {0xbf, 0x25, 0x04}, 3, 256, 64 * 1024, 8, NOR_FLASH_ERASE_4K
},
111 {L
"sst25wf040b", {0x62, 0x16, 0x13}, 3, 256, 64 * 1024, 8, NOR_FLASH_ERASE_4K
},
112 {L
"sst25wf080", {0xbf, 0x25, 0x05}, 3, 256, 64 * 1024, 16, NOR_FLASH_ERASE_4K
},
114 {L
"w25p80", {0xef, 0x20, 0x14}, 3, 256, 64 * 1024, 16, 0},
115 {L
"w25p16", {0xef, 0x20, 0x15}, 3, 256, 64 * 1024, 32, 0},
116 {L
"w25p32", {0xef, 0x20, 0x16}, 3, 256, 64 * 1024, 64, 0},
117 {L
"w25x40", {0xef, 0x30, 0x13}, 3, 256, 64 * 1024, 8, NOR_FLASH_ERASE_4K
},
118 {L
"w25x16", {0xef, 0x30, 0x15}, 3, 256, 64 * 1024, 32, NOR_FLASH_ERASE_4K
},
119 {L
"w25x32", {0xef, 0x30, 0x16}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
120 {L
"w25x64", {0xef, 0x30, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
121 {L
"w25q80bl", {0xef, 0x40, 0x14}, 3, 256, 64 * 1024, 16, NOR_FLASH_ERASE_4K
},
122 {L
"w25q16cl", {0xef, 0x40, 0x15}, 3, 256, 64 * 1024, 32, NOR_FLASH_ERASE_4K
},
123 {L
"w25q32bv", {0xef, 0x40, 0x16}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
124 {L
"w25q64cv", {0xef, 0x40, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
125 {L
"w25q128bv", {0xef, 0x40, 0x18}, 3, 256, 64 * 1024, 256, NOR_FLASH_ERASE_4K
},
126 {L
"w25q256", {0xef, 0x40, 0x19}, 3, 256, 64 * 1024, 512, NOR_FLASH_ERASE_4K
},
127 {L
"w25q80bw", {0xef, 0x50, 0x14}, 3, 256, 64 * 1024, 16, NOR_FLASH_ERASE_4K
},
128 {L
"w25q16dw", {0xef, 0x60, 0x15}, 3, 256, 64 * 1024, 32, NOR_FLASH_ERASE_4K
},
129 {L
"w25q32dw", {0xef, 0x60, 0x16}, 3, 256, 64 * 1024, 64, NOR_FLASH_ERASE_4K
},
130 {L
"w25q64dw", {0xef, 0x60, 0x17}, 3, 256, 64 * 1024, 128, NOR_FLASH_ERASE_4K
},
131 {L
"w25q128fw", {0xef, 0x60, 0x18}, 3, 256, 64 * 1024, 256, NOR_FLASH_ERASE_4K
},
132 {}, /* Empty entry to terminate the list */
136 Return an allocated copy pool of the NOR flash information structure.
138 @param[in] Id Pointer to an array with JEDEC ID obtained
139 from the NOR flash with READ_ID command
141 @param[in out] FlashInfo Pointer to NOR flash information structure
142 @param[in] AllocateForRuntime A flag specifying a type of a copy pool
143 allocation (TRUE for runtime, FALSE for
146 @retval EFI_SUCCESS Operation completed successfully
147 @retval EFI_NOT_FOUND No matching entry in NOR ID table found
148 @retval EFI_OUT_OF_RESOURCES No pool memory available
155 IN OUT NOR_FLASH_INFO
**FlashInfo
,
156 IN BOOLEAN AllocateForRuntime
159 CONST NOR_FLASH_INFO
*TmpInfo
;
162 * Iterate over NorFlashIds table, in order to find matching entry.
164 TmpInfo
= NorFlashIds
;
165 for (; TmpInfo
->Name
!= NULL
; TmpInfo
++) {
166 if (CompareMem (TmpInfo
->Id
, Id
, TmpInfo
->IdLen
) == 0) {
172 * Matching entry was not found.
174 if (TmpInfo
->Name
== NULL
) {
175 return EFI_NOT_FOUND
;
179 * Allocate and copy NOR flash information structure.
181 if (AllocateForRuntime
) {
182 *FlashInfo
= AllocateRuntimeCopyPool (sizeof (NOR_FLASH_INFO
), TmpInfo
);
184 *FlashInfo
= AllocateCopyPool (sizeof (NOR_FLASH_INFO
), TmpInfo
);
186 if (FlashInfo
== NULL
) {
187 return EFI_OUT_OF_RESOURCES
;
194 Print NOR flash information basing on data stored in
195 the NOR_FLASH_INFO structure.
197 @param[in] FlashInfo Pointer to NOR flash information structure
203 IN NOR_FLASH_INFO
*Info
208 if (Info
->Flags
& NOR_FLASH_ERASE_4K
) {
209 EraseSize
= SIZE_4KB
;
211 EraseSize
= Info
->SectorSize
;
215 "Detected %s SPI NOR flash with page size %d B, erase size %d KB, total %d MB\n",
219 (Info
->SectorSize
* Info
->SectorCount
) / 1024 / 1024));