tools: mtk_image: split the code of generating NAND header into a new file
[platform/kernel/u-boot.git] / tools / mtk_nand_headers.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * MediaTek BootROM NAND header definitions
4  *
5  * Copyright (C) 2022 MediaTek Inc.
6  * Author: Weijie Gao <weijie.gao@mediatek.com>
7  */
8
9 #include <stdint.h>
10 #include <string.h>
11 #include "imagetool.h"
12 #include "mtk_image.h"
13 #include "mtk_nand_headers.h"
14
15 /* NAND header for SPI-NAND with 2KB page + 64B spare */
16 static const union nand_boot_header snand_hdr_2k_64_data = {
17         .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
34         }
35 };
36
37 /* NAND header for SPI-NAND with 2KB page + 120B/128B spare */
38 static const union nand_boot_header snand_hdr_2k_128_data = {
39         .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
56         }
57 };
58
59 /* NAND header for SPI-NAND with 4KB page + 256B spare */
60 static const union nand_boot_header snand_hdr_4k_256_data = {
61         .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
78         }
79 };
80
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 = {
83         .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
100         }
101 };
102
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 = {
105         .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
122         }
123 };
124
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 = {
127         .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
144         }
145 };
146
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 = {
149         .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
166         }
167 };
168
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 = {
171         .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
188         }
189 };
190
191 static const struct nand_header_type {
192         const char *name;
193         const union nand_boot_header *data;
194 } nand_headers[] = {
195         {
196                 .name = "2k+64",
197                 .data = &snand_hdr_2k_64_data
198         }, {
199                 .name = "2k+120",
200                 .data = &snand_hdr_2k_128_data
201         }, {
202                 .name = "2k+128",
203                 .data = &snand_hdr_2k_128_data
204         }, {
205                 .name = "4k+256",
206                 .data = &snand_hdr_4k_256_data
207         }, {
208                 .name = "1g:2k+64",
209                 .data = &nand_hdr_1gb_2k_64_data
210         }, {
211                 .name = "2g:2k+64",
212                 .data = &nand_hdr_2gb_2k_64_data
213         }, {
214                 .name = "4g:2k+64",
215                 .data = &nand_hdr_4gb_2k_64_data
216         }, {
217                 .name = "2g:2k+128",
218                 .data = &nand_hdr_2gb_2k_128_data
219         }, {
220                 .name = "4g:2k+128",
221                 .data = &nand_hdr_4gb_2k_128_data
222         }
223 };
224
225 const union nand_boot_header *mtk_nand_header_find(const char *name)
226 {
227         uint32_t i;
228
229         for (i = 0; i < ARRAY_SIZE(nand_headers); i++) {
230                 if (!strcmp(nand_headers[i].name, name))
231                         return nand_headers[i].data;
232         }
233
234         return NULL;
235 }
236
237 uint32_t mtk_nand_header_size(const union nand_boot_header *hdr_nand)
238 {
239         return 2 * le16_to_cpu(hdr_nand->pagesize);
240 }
241
242 static int mtk_nand_header_ap_info(const void *ptr,
243                                    struct nand_header_info *info)
244 {
245         union nand_boot_header *nh = (union nand_boot_header *)ptr;
246
247         if (strncmp(nh->version, NAND_BOOT_VERSION, sizeof(nh->version)) ||
248             strcmp(nh->id, NAND_BOOT_ID))
249                 return -1;
250
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;
254
255         return 0;
256 }
257
258 int mtk_nand_header_info(const void *ptr, struct nand_header_info *info)
259 {
260         if (!strcmp((char *)ptr, NAND_BOOT_NAME))
261                 return mtk_nand_header_ap_info(ptr, info);
262
263         return -1;
264 }
265
266 bool is_mtk_nand_header(const void *ptr)
267 {
268         struct nand_header_info info;
269
270         if (mtk_nand_header_info(ptr, &info) >= 0)
271                 return true;
272
273         return false;
274 }
275
276 uint32_t mtk_nand_header_put(const union nand_boot_header *hdr_nand, void *ptr)
277 {
278         union nand_boot_header *nh = (union nand_boot_header *)ptr;
279         int i;
280
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));
284
285         return le16_to_cpu(hdr_nand->pagesize);
286 }