1 // SPDX-License-Identifier: GPL-2.0+
3 * MediaTek BootROM NAND header definitions
5 * Copyright (C) 2022 MediaTek Inc.
6 * Author: Weijie Gao <weijie.gao@mediatek.com>
11 #include "imagetool.h"
12 #include "mtk_image.h"
13 #include "mtk_nand_headers.h"
15 /* NAND header for SPI-NAND with 2KB page + 64B spare */
16 static const union nand_boot_header snand_hdr_2k_64_data = {
18 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
19 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
20 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
21 0x00, 0x00, 0x00, 0x08, 0x03, 0x00, 0x40, 0x00,
22 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
23 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
25 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
26 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
28 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
29 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
30 0x00, 0x00, 0x00, 0x00, 0x7B, 0xC4, 0x17, 0x9D,
31 0xCA, 0x42, 0x90, 0xD0, 0x98, 0xD0, 0xE0, 0xF7,
32 0xDB, 0xCD, 0x16, 0xF6, 0x03, 0x73, 0xD2, 0xB8,
33 0x93, 0xB2, 0x56, 0x5A, 0x84, 0x6E, 0x00, 0x00
37 /* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
38 static const union nand_boot_header snand_hdr_2k_128_data = {
40 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
41 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
42 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
43 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
44 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
45 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
49 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x90, 0x28, 0xED, 0x13,
53 0x7F, 0x12, 0x22, 0xCD, 0x3D, 0x06, 0xF1, 0xB3,
54 0x6F, 0x2E, 0xD9, 0xA0, 0x9D, 0x7A, 0xBD, 0xD7,
55 0xB3, 0x28, 0x3C, 0x13, 0xDB, 0x4E, 0x00, 0x00
59 /* NAND header for SPI-NAND with 4KB page + 256B spare */
60 static const union nand_boot_header snand_hdr_4k_256_data = {
62 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
63 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
64 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
65 0x00, 0x00, 0x00, 0x10, 0x05, 0x00, 0xE0, 0x00,
66 0x40, 0x00, 0x00, 0x08, 0x10, 0x00, 0x16, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
71 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
72 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0x00, 0x00, 0x47, 0xED, 0x0E, 0xC3,
75 0x83, 0xBF, 0x41, 0xD2, 0x85, 0x21, 0x97, 0x57,
76 0xC4, 0x2E, 0x6B, 0x7A, 0x40, 0xE0, 0xCF, 0x8F,
77 0x37, 0xBD, 0x17, 0xB6, 0xC7, 0xFE, 0x00, 0x00
81 /* NAND header for Parallel NAND 1Gb with 2KB page + 64B spare */
82 static const union nand_boot_header nand_hdr_1gb_2k_64_data = {
84 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
85 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
86 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
87 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
88 0x40, 0x00, 0x00, 0x04, 0x0B, 0x00, 0x11, 0x00,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x12, 0x28, 0x1C, 0x12,
97 0x8F, 0xFD, 0xF8, 0x32, 0x6F, 0x6D, 0xCF, 0x6C,
98 0xDA, 0x21, 0x70, 0x8C, 0xDA, 0x0A, 0x22, 0x82,
99 0xAA, 0x59, 0xFA, 0x7C, 0x42, 0x2D, 0x00, 0x00
103 /* NAND header for Parallel NAND 2Gb with 2KB page + 64B spare */
104 static const union nand_boot_header nand_hdr_2gb_2k_64_data = {
106 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
107 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
108 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
109 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
110 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
117 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
118 0x00, 0x00, 0x00, 0x00, 0x20, 0x9C, 0x3D, 0x2D,
119 0x7B, 0x68, 0x63, 0x52, 0x2E, 0x04, 0x63, 0xF1,
120 0x35, 0x4E, 0x44, 0x3E, 0xF8, 0xAC, 0x9B, 0x95,
121 0xAB, 0xFE, 0xE4, 0xE1, 0xD5, 0xF9, 0x00, 0x00
125 /* NAND header for Parallel NAND 4Gb with 2KB page + 64B spare */
126 static const union nand_boot_header nand_hdr_4gb_2k_64_data = {
128 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
129 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
130 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
131 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x40, 0x00,
132 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
133 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
134 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
135 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
136 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
137 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
140 0x00, 0x00, 0x00, 0x00, 0xE3, 0x0F, 0x86, 0x32,
141 0x68, 0x05, 0xD9, 0xC8, 0x13, 0xDF, 0xC5, 0x0B,
142 0x35, 0x3A, 0x68, 0xA5, 0x3C, 0x0C, 0x73, 0x87,
143 0x63, 0xB0, 0xBE, 0xCC, 0x84, 0x47, 0x00, 0x00
147 /* NAND header for Parallel NAND 2Gb with 2KB page + 128B spare */
148 static const union nand_boot_header nand_hdr_2gb_2k_128_data = {
150 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
151 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
152 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
153 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
154 0x40, 0x00, 0x00, 0x08, 0x0B, 0x00, 0x11, 0x00,
155 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
156 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
157 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
158 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
159 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
160 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
161 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
162 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0xE9, 0x5A,
163 0xDF, 0x58, 0x62, 0x41, 0xD6, 0x26, 0x77, 0xBC,
164 0x76, 0x1F, 0x27, 0x4E, 0x4F, 0x6C, 0xC3, 0xF0,
165 0x36, 0xDE, 0xD9, 0xB3, 0xFF, 0x93, 0x00, 0x00
169 /* NAND header for Parallel NAND 4Gb with 2KB page + 128B spare */
170 static const union nand_boot_header nand_hdr_4gb_2k_128_data = {
172 0x42, 0x4F, 0x4F, 0x54, 0x4C, 0x4F, 0x41, 0x44,
173 0x45, 0x52, 0x21, 0x00, 0x56, 0x30, 0x30, 0x36,
174 0x4E, 0x46, 0x49, 0x49, 0x4E, 0x46, 0x4F, 0x00,
175 0x00, 0x00, 0x00, 0x08, 0x05, 0x00, 0x70, 0x00,
176 0x40, 0x00, 0x00, 0x10, 0x0B, 0x00, 0x11, 0x00,
177 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
178 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
179 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
180 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
181 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184 0x00, 0x00, 0x00, 0x00, 0xC2, 0x36, 0x52, 0x45,
185 0xCC, 0x35, 0xD8, 0xDB, 0xEB, 0xFD, 0xD1, 0x46,
186 0x76, 0x6B, 0x0B, 0xD5, 0x8B, 0xCC, 0x2B, 0xE2,
187 0xFE, 0x90, 0x83, 0x9E, 0xAE, 0x2D, 0x00, 0x00
191 static const struct nand_header_type {
193 const union nand_boot_header *data;
197 .data = &snand_hdr_2k_64_data
200 .data = &snand_hdr_2k_128_data
203 .data = &snand_hdr_2k_128_data
206 .data = &snand_hdr_4k_256_data
209 .data = &nand_hdr_1gb_2k_64_data
212 .data = &nand_hdr_2gb_2k_64_data
215 .data = &nand_hdr_4gb_2k_64_data
218 .data = &nand_hdr_2gb_2k_128_data
221 .data = &nand_hdr_4gb_2k_128_data
225 const union nand_boot_header *mtk_nand_header_find(const char *name)
229 for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
230 if (!strcmp(nand_headers[i].name, name))
231 return nand_headers[i].data;
237 uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand)
239 return 2 * le16_to_cpu(hdr_nand->pagesize);
242 static int mtk_nand_header_ap_info(const void *ptr,
243 struct nand_header_info *info)
245 union nand_boot_header *nh = (union nand_boot_header *)ptr;
247 if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
248 strcmp(nh->id, NAND_BOOT_ID))
251 info->page_size = le16_to_cpu(nh->pagesize);
252 info->spare_size = le16_to_cpu(nh->oobsize);
253 info->gfh_offset = 2 * info->page_size;
258 int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
260 if (!strcmp((char *)ptr, NAND_BOOT_NAME))
261 return mtk_nand_header_ap_info(ptr, info);
266 bool is_mtk_nand_header(const void *ptr)
268 struct nand_header_info info;
270 if (mtk_nand_header_info(ptr, &info) >= 0)
276 uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr)
278 union nand_boot_header *nh = (union nand_boot_header *)ptr;
281 /* NAND device header, repeat 4 times */
282 for (i = 0; i < 4; i++)
283 memcpy(nh + i, hdr_nand, sizeof(union nand_boot_header));
285 return le16_to_cpu(hdr_nand->pagesize);