blob: 588c81dcad158c35bb988d3089b73f2e40e05b5d [file] [log] [blame]
Bo Lv72d0e902023-01-02 14:27:34 +00001// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
2/*
3 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
4 */
5
6#include <amlogic/storage.h>
7#include <div64.h>
8#include <linux/math64.h>
9#include <amlogic/cpu_id.h>
10#include <amlogic/store_wrapper.h>
11#include <asm/amlogic/arch/register.h>
12#include <asm/amlogic/arch/bl31_apis.h>
13#include <amlogic/aml_efuse.h>
14#include <asm/amlogic/arch/cpu_config.h>
15#include <asm/amlogic/arch/romboot.h>
16#include <asm/amlogic/arch/secure_apb.h>
17#include <amlogic/blxx2bl33_param.h>
18#include <amlogic/aml_mtd.h>
19#include <mmc.h>
20
21#include <display_options.h>
22
23#ifdef CONFIG_SPI_FLASH_MTD
24extern int spi_nor_pre(void);
25extern int spi_nor_probe(u32 init_flag);
26#endif
27
Bo Lv72d0e902023-01-02 14:27:34 +000028#ifdef CONFIG_MTD_SPI_NAND
29extern int spi_nand_pre(void);
30extern int spi_nand_probe(u32 init_flag);
31#endif
32
Bo Lv72d0e902023-01-02 14:27:34 +000033#ifdef CONFIG_MESON_NFC
34extern int nand_pre(void);
35extern int nand_probe(uint32_t init_flag);
36#endif
37
38#ifdef CONFIG_MMC_MESON_GX
39extern int emmc_pre(void);
40extern int emmc_probe(u32 init_flag);
41#endif
42
43#ifdef CONFIG_MMC_MESON_GX
44extern int sdcard_pre(void);
45extern int sdcard_probe(u32 init_flag);
46#endif
47/* for info protect, fixme later */
48int info_disprotect = 0;
49
50static struct storage_t *current;
51static struct device_node_t device_list[] = {
52#ifdef CONFIG_MESON_NFC
53 {BOOT_NAND_MTD, "mtd", nand_pre, nand_probe},
54#endif
Bo Lv72d0e902023-01-02 14:27:34 +000055#ifdef CONFIG_MTD_SPI_NAND
56 {BOOT_SNAND, "spi-nand", spi_nand_pre, spi_nand_probe},
57#endif
58#ifdef CONFIG_SPI_FLASH_MTD
59 {BOOT_SNOR, "spi-nor", spi_nor_pre, spi_nor_probe},
60#endif
61#if 0
62 {BOOT_SD, "sd", sdcard_pre, sdcard_probe},
63#endif
64
65#ifdef CONFIG_MMC_MESON_GX
66 {BOOT_EMMC, "emmc", emmc_pre, emmc_probe},
67#endif
68
69};
70
71int store_register(struct storage_t *store_dev)
72{
73 if (!store_dev)
74 return 1;
75 if (!current) {
76 INIT_LIST_HEAD(&store_dev->list);
77 current = store_dev;
78 return 0;
79 }
80 /**
81 * the head node will not be a valid node
82 * usually when we use the list, but in storage
83 * interface module, we init the device node as
84 * a head instead a global list_head pointer,
85 * it should be traver scaled.
86 */
87 if (store_dev == current)
88 return 0;
89 struct storage_t *dev;
90
91 if (store_dev->type == current->type)
92 return 1;
93 list_for_each_entry(dev, &current->list, list) {
94 if (dev == store_dev)
95 return 0;
96 else if (dev->type == store_dev->type)
97 return 1;
98 }
99 list_add_tail(&store_dev->list, &current->list);
100 current = store_dev;
101 return 0;
102}
103
104void store_unregister(struct storage_t *store_dev)
105{
106 if (store_dev == current) {
107 if (list_empty_careful(&store_dev->list)) {
108 current = NULL;
109 } else {
110 current = list_entry((current->list).next,
111 struct storage_t, list);
112 list_del_init(&store_dev->list);
113 }
114 } else {
115 list_del_init(&store_dev->list);
116 }
117}
118
119int sheader_need(void)
120{
121 return BOOTLOADER_MODE_ADVANCE_INIT;
122}
123
124unsigned char *ubootdata = NULL;
125void sheader_load(void *addr)
126{
127 ubootdata = addr;
128}
129
130/*
131 * storage header which size is 512B
132 * is bind into the tail of bl2.bin.
133 * @addr: uboot address.
134 */
135static p_payload_info_t parse_uboot_sheader(void *addr)
136{
137 p_payload_info_t pInfo = (p_payload_info_t)(addr + BL2_SIZE);
138
139 if (AML_MAGIC_HDR_L == pInfo->hdr.nMagicL &&
140 AML_MAGIC_HDR_R == pInfo->hdr.nMagicR) {
141 printf("aml log : bootloader blxx mode!\n");
142 return pInfo;
143 }
144 return NULL;
145}
146
147boot_area_entry_t general_boot_part_entry[MAX_BOOT_AREA_ENTRIES] = {
148 {BOOT_BL2, BOOT_AREA_BB1ST, 0, 0},
149 {BOOT_BL2E, BOOT_AREA_BL2E, 0, 0},
150 {BOOT_BL2X, BOOT_AREA_BL2X, 0, 0},
151 {BOOT_DDRFIP, BOOT_AREA_DDRFIP, 0, 0},
152 {BOOT_DEVFIP, BOOT_AREA_DEVFIP, 0, 0},
153};
154
155struct boot_layout general_boot_layout = {.boot_entry = general_boot_part_entry};
156struct storage_startup_parameter g_ssp;
157struct storage_bl *g_storage = NULL;
158
159static void storage_boot_layout_debug_info(
160 struct boot_layout *boot_layout)
161{
162 boot_area_entry_t *boot_entry = boot_layout->boot_entry;
163 int i;
164
165 printf("boot area list: \n");
Bichao Zheng8951e442023-07-13 13:21:29 +0800166 for (i = 0; i <= BOOT_AREA_DEVFIP; i++) {
Bo Lv72d0e902023-01-02 14:27:34 +0000167 printf("%10s ", boot_entry[i].name);
168 printf("%10llx ", boot_entry[i].offset);
169 printf("%10llx\n", boot_entry[i].size);
170 }
171}
172
173/* use STORAGE_ROUND_UP, y must be power of 2 */
174#define STORAGE_ROUND_UP_IF_UNALIGN(x, y) ((x) = (((x) + (y) - 1) & (~(y - 1))))
175#define NAND_RSV_OFFSET 1024
176#define ALIGN_SIZE (4096)
177static int storage_boot_layout_rebuild(struct boot_layout *boot_layout,
178 unsigned int bl2e_size,
179 unsigned int bl2x_size)
180{
181 struct storage_startup_parameter *ssp = &g_ssp;
182 boot_area_entry_t *boot_entry = boot_layout->boot_entry;
183 uint64_t align_size, reserved_size = 0, cal_copy = ssp->boot_backups;
Bichao Zheng8951e442023-07-13 13:21:29 +0800184 cpu_id_t cpu_id = get_cpu_id();
Bo Lv72d0e902023-01-02 14:27:34 +0000185 uint8_t i;
186
187 align_size = ALIGN_SIZE;
188 if ((ssp->boot_device == BOOT_NAND_NFTL) ||
189 (ssp->boot_device == BOOT_NAND_MTD)) {
190 reserved_size = ssp->sip.nsp.layout_reserve_size;
191 align_size = ((NAND_RSV_OFFSET / cal_copy) * ssp->sip.nsp.page_size);
192 printf("reserved_size:0x%llx 0x%llx\n", reserved_size, align_size);
193 } else if (ssp->boot_device == BOOT_SNAND) {
194 reserved_size = ssp->sip.snasp.layout_reserve_size;
195 align_size = ((NAND_RSV_OFFSET / cal_copy) * ssp->sip.snasp.pagesize);
Bichao Zheng8951e442023-07-13 13:21:29 +0800196 } else if (ssp->boot_device == BOOT_EMMC) {
Bo Lv72d0e902023-01-02 14:27:34 +0000197 ssp->boot_entry[0].offset = boot_entry[0].offset +=
198 BL2_CORE_BASE_OFFSET_EMMC;
199 cal_copy = 1;
Bichao Zheng8951e442023-07-13 13:21:29 +0800200 } else if (ssp->boot_device == BOOT_SNOR &&
Bichao Zhengd9e46b22023-07-27 21:26:18 +0800201 ((cpu_id.family_id == MESON_CPU_MAJOR_ID_A4) ||
Feng Chen32c0fb22024-01-12 20:50:41 +0800202 (cpu_id.family_id == MESON_CPU_MAJOR_ID_S1A) ||
zhikui.cui01923c82024-04-20 05:58:16 +0000203 (cpu_id.family_id == MESON_CPU_MAJOR_ID_S7) ||
204 (cpu_id.family_id == MESON_CPU_MAJOR_ID_S7D))) {
205 boot_entry[0].size += 0x200;
Bichao Zheng8951e442023-07-13 13:21:29 +0800206 cal_copy = 1;
Bo Lv72d0e902023-01-02 14:27:34 +0000207 }
Bichao Zheng8951e442023-07-13 13:21:29 +0800208
Bo Lv72d0e902023-01-02 14:27:34 +0000209 STORAGE_ROUND_UP_IF_UNALIGN(boot_entry[0].size, align_size);
210 ssp->boot_entry[0].size = boot_entry[0].size;
211 printf("ssp->boot_entry[0] offset:0x%x, size:0x%x\n",
212 ssp->boot_entry[0].offset, ssp->boot_entry[0].size);
213 printf("cal_copy:0x%llx\n", cal_copy);
214 printf("align_size:0x%llx\n", align_size);
215 printf("reserved_size:0x%llx\n", reserved_size);
216 if ((ssp->boot_device == BOOT_NAND_NFTL) ||
217 (ssp->boot_device == BOOT_NAND_MTD))
218 align_size = ssp->sip.nsp.block_size;
219 else if (ssp->boot_device == BOOT_SNAND)
220 align_size = (uint64_t)ssp->sip.snasp.pagesize *
221 ssp->sip.snasp.pages_per_eraseblock;
222 printf("align_size2:%llu\n", align_size);
223
224 boot_entry[BOOT_AREA_BL2E].size = bl2e_size;
225 boot_entry[BOOT_AREA_BL2X].size = bl2x_size;
226
Bichao Zheng8951e442023-07-13 13:21:29 +0800227 for (i = 1; i <= BOOT_AREA_DEVFIP; i++) {
Bo Lv72d0e902023-01-02 14:27:34 +0000228 STORAGE_ROUND_UP_IF_UNALIGN(boot_entry[i].size, align_size);
229 boot_entry[i].offset = boot_entry[i-1].offset +
230 boot_entry[i-1].size * cal_copy + reserved_size;
231 reserved_size = 0;
232 ssp->boot_entry[i].size = boot_entry[i].size;
233 ssp->boot_entry[i].offset = boot_entry[i].offset;
234 }
235
236 return 0;
237}
238
239/* use STORAGE_ROUND_UP, y must be power of 2 */
240#define STORAGE_ROUND_UP_IF_UNALIGN(x, y) ((x) = (((x) + (y) - 1) & (~(y - 1))))
241#define NAND_RSV_OFFSET 1024
242#define ALIGN_SIZE (4096)
jinbiao9f9847e2023-08-09 09:27:07 +0000243static int storage_boot_layout_general_setting(struct boot_layout *boot_layout, int need_build)
Bo Lv72d0e902023-01-02 14:27:34 +0000244{
245 struct storage_startup_parameter *ssp = &g_ssp;
246 boot_area_entry_t *boot_entry = boot_layout->boot_entry;
247 struct storage_boot_entry *sbentry = ssp->boot_entry;
jinbiao9f9847e2023-08-09 09:27:07 +0000248 p_payload_info_t p_info = parse_uboot_sheader(ubootdata);
249 p_payload_info_hdr_t hdr;
250 p_payload_info_item_t p_item;
251 int off_payload = 0, sz_payload = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000252 unsigned int bl2e_size = 0, bl2x_size = 0;
253 char name[8] = {0};
jinbiao9f9847e2023-08-09 09:27:07 +0000254 int n_index = 0;
Bo Lv72d0e902023-01-02 14:27:34 +0000255
Bo Lv72d0e902023-01-02 14:27:34 +0000256 if (need_build == BOOT_ID_USB) {
jinbiao9f9847e2023-08-09 09:27:07 +0000257 if (!p_info)
258 return -1;
259
260 hdr = &p_info->hdr;
261 p_item = p_info->arrItems;
262
263 for (n_index = 1, p_item += 1; n_index < hdr->byItemNum; ++n_index, ++p_item) {
264 memcpy(name, &p_item->nMagic, sizeof(unsigned int));
265 off_payload = p_item->nOffset;
266 if (n_index == BOOT_AREA_BL2E)
267 bl2e_size = p_item->nPayLoadSize;
268 if (n_index == BOOT_AREA_BL2X)
269 bl2x_size = p_item->nPayLoadSize;
270 sz_payload = p_item->nPayLoadSize;
271 pr_info("Item[%d]%4s offset 0x%08x sz 0x%x\n", n_index, name, off_payload, sz_payload);
Bo Lv72d0e902023-01-02 14:27:34 +0000272 }
273 boot_entry[BOOT_AREA_BB1ST].size = ssp->boot_entry[BOOT_AREA_BB1ST].size;
274 boot_entry[BOOT_AREA_DDRFIP].size = ssp->boot_entry[BOOT_AREA_DDRFIP].size;
275 boot_entry[BOOT_AREA_DEVFIP].size = ssp->boot_entry[BOOT_AREA_DEVFIP].size;
276 storage_boot_layout_rebuild(boot_layout, bl2e_size, bl2x_size);
277 } else {
278 /* may be sdcard boot and also have to rebuild layout */
279 if (need_build == BOOT_ID_SDCARD) {
280 bl2e_size = sbentry[BOOT_AREA_BL2E].size;
281 bl2x_size = sbentry[BOOT_AREA_BL2X].size;
jinbiao9f9847e2023-08-09 09:27:07 +0000282 printf("bl2e_size=%x bl2x_size=%x current->type=%d\n", bl2e_size, bl2x_size, current->type);
283 boot_entry[BOOT_AREA_BB1ST].size = ssp->boot_entry[BOOT_AREA_BB1ST].size;
284 boot_entry[BOOT_AREA_DDRFIP].size = ssp->boot_entry[BOOT_AREA_DDRFIP].size;
285 boot_entry[BOOT_AREA_DEVFIP].size = ssp->boot_entry[BOOT_AREA_DEVFIP].size;
286 storage_boot_layout_rebuild(boot_layout, bl2e_size, bl2x_size);
Bo Lv72d0e902023-01-02 14:27:34 +0000287 return 0;
288 }
289 /* normal boot */
Bichao Zheng5ced7b52023-07-25 15:20:20 +0800290 for (n_index = 0; n_index <= BOOT_AREA_DEVFIP; n_index++, sbentry++) {
jinbiao9f9847e2023-08-09 09:27:07 +0000291 boot_entry[n_index].size = sbentry->size;
292 boot_entry[n_index].offset = sbentry->offset;
Bo Lv72d0e902023-01-02 14:27:34 +0000293 }
294 }
295
296 return 0;
297}
298
299uint8_t emmc_boot_seqs_tbl[8][2] = {
300 {0, 3}, {0, 2}, {0, 3}, {0, 1},
301 {1, 2}, {1, 1}, {2, 1}, {0, 0}
302 };
303
304static int _get_emmc_boot_seqs(void)
305{
306 uint8_t ebcfg = 0;
307 if (IS_FEAT_DIS_EMMC_USER())
308 ebcfg |= (1<<2);
309 if (IS_FEAT_DIS_EMMC_BOOT_0())
310 ebcfg |= (1<<1);
311 if (IS_FEAT_DIS_EMMC_BOOT_1())
312 ebcfg |= (1<<0);
313
314 return ebcfg;
315}
316
317static int storage_get_emmc_boot_seqs(void)
318{
319 return emmc_boot_seqs_tbl[_get_emmc_boot_seqs()][1];;
320}
321
322static int storage_get_emmc_boot_start(void)
323{
324 return emmc_boot_seqs_tbl[_get_emmc_boot_seqs()][0];;
325}
326
Bo Lv72d0e902023-01-02 14:27:34 +0000327#define NSP_PAGE0_DISABLE 1
328extern unsigned char *ubootdata;
329static int storage_get_and_parse_ssp(int *need_build) // boot_device:
330{
331 struct storage_startup_parameter *ssp = &g_ssp;
332 union storage_independent_parameter *sip;
333 static struct param_e *storage_param_e;
334 int usb_boot = *need_build;
335
336 memset(ssp, 0, sizeof(struct storage_startup_parameter));
337 if (!usb_boot) {
338 storage_param_e = param_of(STORAGE_PARAM_TYPE);
339 if (!storage_param_e)
340 return -1;
341 memcpy(ssp, storage_param_e->data,
342 sizeof(struct storage_startup_parameter));
343 /* may be sdcard boot and also have to rebuild layout */
344 if (ssp->boot_device == BOOT_ID_SDCARD ||
345 ssp->boot_device == BOOT_ID_USB) {
346 /* need change the storage base here */
347 *need_build = ssp->boot_device;
348 }
349 }
350
351 if (*need_build) {
352 sip = &ssp->sip;
353 ssp->boot_device = current->type;
354 switch (ssp->boot_device) {
355 case BOOT_EMMC:
356 ssp->boot_backups = storage_get_emmc_boot_seqs();
357 break;
358 case BOOT_SNOR:
359 if (IS_FEAT_EN_4BL2_SNOR())
360 ssp->boot_backups = 4;
361 else if (IS_FEAT_DIS_NBL2_SNOR())
362 ssp->boot_backups = 1;
363 else
Bichao Zheng8951e442023-07-13 13:21:29 +0800364 ssp->boot_backups = 1; /* Default 2 backup, consistent with rom */
Bo Lv72d0e902023-01-02 14:27:34 +0000365 break;
366 case BOOT_SNAND:
Bichao Zheng5ced7b52023-07-25 15:20:20 +0800367 ssp->boot_backups = CONFIG_BL2_COPY_NUM;
Bo Lv72d0e902023-01-02 14:27:34 +0000368 sip->snasp.pagesize = current->info.write_unit;
369 sip->snasp.pages_per_eraseblock =
370 current->info.erase_unit / current->info.write_unit;
371 sip->snasp.eraseblocks_per_lun =
372 (current->info.caps >> 20) / current->info.erase_unit;
373 sip->snasp.planes_per_lun = 1;
374 sip->snasp.luns_per_target = 1;
375 sip->snasp.ntargets = 1;
376 sip->snasp.layout_reserve_size =
Bichao Zheng5ced7b52023-07-25 15:20:20 +0800377 MTD_RSV_BLOCK_CNT * current->info.erase_unit;
Bo Lv72d0e902023-01-02 14:27:34 +0000378 break;
379 case BOOT_NAND_NFTL:
380 case BOOT_NAND_MTD:
Bichao Zheng5ced7b52023-07-25 15:20:20 +0800381 ssp->boot_backups = CONFIG_BL2_COPY_NUM;
Bo Lv72d0e902023-01-02 14:27:34 +0000382 sip->nsp.page_size = current->info.write_unit;
383 sip->nsp.block_size = current->info.erase_unit;
384 sip->nsp.pages_per_block =
385 current->info.erase_unit / current->info.write_unit;
386 sip->nsp.layout_reserve_size =
Bichao Zheng5ced7b52023-07-25 15:20:20 +0800387 MTD_RSV_BLOCK_CNT * sip->nsp.block_size;
Bo Lv72d0e902023-01-02 14:27:34 +0000388 sip->nsp.page0_disable = NSP_PAGE0_DISABLE;
389 break;
390 default:
391 /* do nothing. */
392 break;
393 }
394
395 }
396
397 /* sanity check */
398
399 printf("boot_device:%d\n", ssp->boot_device);
400 printf("boot_seq:%d\n", ssp->boot_seq);
401 printf("boot_backups:%d\n", ssp->boot_backups);
402 printf("rebuild_id :%d\n", *need_build);
403
404 return 0;
405}
406
407int storage_post_init(void)
408{
409 int ret = -1;
410 int need_build = 0;
411
412 ret = storage_get_and_parse_ssp(&need_build);
413 if (ret < 0)
414 return -1;
jinbiao9f9847e2023-08-09 09:27:07 +0000415
416 ret = storage_boot_layout_general_setting(&general_boot_layout, need_build);
417 if (ret < 0)
418 return ret;
419
Bo Lv72d0e902023-01-02 14:27:34 +0000420 storage_boot_layout_debug_info(&general_boot_layout);
421
422 return ret;
423}
424
425int store_init(u32 init_flag)
426{
427 int i, ret = 0;
428 u8 record = 0;
429
430 /*1. pre scan*/
431 for (i = 0; i < ARRAY_SIZE(device_list); i++) {
432 if (!device_list[i].pre()) {
433 record |= BIT(i);
434 }
435 }
436
Bichao Zheng8951e442023-07-13 13:21:29 +0800437 pr_info("record = 0x%x\n", record);
438
Bo Lv72d0e902023-01-02 14:27:34 +0000439 if (!record) {
440 pr_info("No Valid storage device\n");
441 return record;
442 }
443
jinbiao9f9847e2023-08-09 09:27:07 +0000444 if (BOOTLOADER_MODE_ADVANCE_INIT) {
445 ret = storage_post_init();
Ruixuan.li53ff14f2023-10-24 16:34:01 +0800446 if (ret)
447 pr_info("storage_post_init failed\n");
jinbiao9f9847e2023-08-09 09:27:07 +0000448 }
Bo Lv72d0e902023-01-02 14:27:34 +0000449
450 /*2. Enter the probe of the valid device*/
451 for (i = 0; i < ARRAY_SIZE(device_list); i++) {
452 if (record & BIT(i)) {
453 ret = device_list[i].probe(init_flag);
454 if (ret)
455 pr_info("the 0x%x storage device probe failed\n",
456 device_list[i].index);
457 }
458 }
459
460 return record;
461}
462
463static struct storage_t *store_get_current(void)
464{
465 return current;
466}
467
468int store_set_device(enum boot_type_e type)
469{
470 struct list_head *entry;
471 struct storage_t *dev, *store_dev = store_get_current();
472
473 if (!store_dev) {
474 pr_info("%s %d no current device\n", __func__, __LINE__);
475 return 1;
476 }
477 if (store_dev->type == type)
478 return 0;
479 list_for_each(entry, &store_dev->list) {
480 dev = list_entry(entry, struct storage_t, list);
481 if (dev->type == type) {
482 current = dev;
483 return 0;
484 }
485 }
486 pr_info("%s %d please confirm the %d device is valid\n",
487 __func__, __LINE__, type);
488 return 1;
489}
490
491enum boot_type_e store_get_type(void)
492{
493 struct storage_t *store = store_get_current();
494
495 if (!store) {
496 pr_info("%s %d please init storage device first\n",
497 __func__, __LINE__);
498 return BOOT_NONE;
499 }
500
501 return store->type;
502}
503
504int store_get_device_info(struct storage_info_t *info)
505{
506 struct storage_t *store = store_get_current();
507
508 if (!store) {
509 pr_info("%s %d please init storage device first\n",
510 __func__, __LINE__);
511 return 1;
512 }
513
514 memcpy((char *)info, (char *)&store->info,
515 sizeof(struct storage_info_t));
516 return 0;
517}
518
519int store_get_device_bootloader_mode(void)
520{
521 struct storage_t *store = store_get_current();
522
523 if (!store) {
524 pr_info("%s %d please init storage device first\n",
525 __func__, __LINE__);
526 return -1;
527 }
528 return store->info.mode;
529}
530
531int store_read(const char *name, loff_t off, size_t size, void *buf)
532{
533 struct storage_t *store = store_get_current();
534
535 if (!store) {
536 pr_info("%s %d please init storage device first\n",
537 __func__, __LINE__);
538 return 1;
539 }
540 return store->read(name, off, size, buf);
541}
542
543int store_write(const char *name, loff_t off, size_t size, void *buf)
544{
545 struct storage_t *store = store_get_current();
546
547 if (!store) {
548 pr_info("%s %d please init storage device first\n",
549 __func__, __LINE__);
550 return 1;
551 }
552 return store->write(name, off, size, buf);
553}
554
555int store_erase(const char *name, loff_t off, size_t size, int scrub)
556{
557 struct storage_t *store = store_get_current();
558
559 if (!store) {
560 pr_info("%s %d please init storage device first\n",
561 __func__, __LINE__);
562 return 1;
563 }
564 return store->erase(name, off, size, scrub);
565}
566
567u64 store_part_size(const char *name)
568{
569 struct storage_t *store = store_get_current();
570
571 if (!store) {
572 pr_info("%s %d please init storage device first\n",
573 __func__, __LINE__);
574 return 1;
575 }
576 return store->get_part_size(name);
577}
578
579u8 store_boot_copy_num(const char *name)
580{
581 struct storage_t *store = store_get_current();
582
583 if (!store) {
584 pr_info("%s %d please init storage device first\n",
585 __func__, __LINE__);
586 return 1;
587 }
588 return store->get_copies(name);
589}
590
591
592#ifndef SYSCTRL_SEC_STATUS_REG2
593static u32 fake_reg = 0;
594#define SYSCTRL_SEC_STATUS_REG2 (&fake_reg)
595#endif
596u8 store_boot_copy_start(void)
597{
598 struct storage_t *store = store_get_current();
599
600 if (!store) {
601 pr_info("%s %d please init storage device first\n",
602 __func__, __LINE__);
603 return 0;
604 }
605 if (store->type != BOOT_EMMC)
606 return 0;
607 /* new arch since sc2 */
608 if (BOOTLOADER_MODE_ADVANCE_INIT)
609 return storage_get_emmc_boot_start();
610 return 0;
611}
612
613u8 store_bootup_bootidx(const char *name)
614{
615 u8 bl2_idx = 0, fip_idx = 0;
616 u32 val = 0;
617
618 /* new arch since sc2 */
619 if (BOOTLOADER_MODE_ADVANCE_INIT) {
620 bl2_idx = readl(SYSCTRL_SEC_STATUS_REG2) & 0xF;
621 //TODO: fixme after robust devfip is finished.
622 fip_idx = bl2_idx;
623 } else {
624 /* according to the:
625 commit 975b4acbcfa686601999d56843471d98e9c0a2cd
626 storage: robust boot: record bootlog in SEC_AO_SEC_GP_CFG2 [1/2]
627 PD#SWPL-4850
628 ...
629 record the bootup bl2/fip into SEC_AO_SEC_GP_CFG2
630 bit[27-25] bl2
631 bit[24-22] fip
632 */
633 val = readl(SEC_AO_SEC_GP_CFG2);
634 bl2_idx = (val >> 25) & 0x7;
635 fip_idx = (val >> 22) & 0x7;
636 }
637 if (!strncmp(name, "bl2", sizeof("bl2")) ||
638 !strncmp(name, "spl", sizeof("spl")))
639 return bl2_idx;
640 else
641 return fip_idx;
642}
643
644void store_restore_bootidx(void)
645{
646 /* new arch since sc2 */
647 if (BOOTLOADER_MODE_ADVANCE_INIT) {
648 extern void aml_set_bootsequence(uint32_t val);
649 aml_set_bootsequence(0x55);
650 }
651 return;
652}
653
654u64 store_boot_copy_size(const char *name)
655{
656 struct storage_t *store = store_get_current();
657
658 if (!store) {
659 pr_info("%s %d please init storage device first\n",
660 __func__, __LINE__);
661 return 1;
662 }
663 return store->get_copy_size(name);
664}
665
666int store_boot_read(const char *name, u8 copy, size_t size, void *buf)
667{
668 struct storage_t *store = store_get_current();
669
670 if (!store) {
671 pr_info("%s %d please init storage device first\n",
672 __func__, __LINE__);
673 return 1;
674 }
675 return store->boot_read(name, copy, size, buf);
676}
677
678int store_boot_write(const char *name, u8 copy, size_t size, void *buf)
679{
680 struct storage_t *store = store_get_current();
681
682 if (!store) {
683 pr_info("%s %d please init storage device first\n",
684 __func__, __LINE__);
685 return 1;
686 }
687 return store->boot_write(name, copy, size, buf);
688}
689
690int store_boot_erase(const char *name, u8 copy)
691{
692 struct storage_t *store = store_get_current();
693
694 if (!store) {
695 pr_info("%s %d please init storage device first\n",
696 __func__, __LINE__);
697 return 1;
698 }
699 return store->boot_erase(name, copy);
700}
701
702int store_gpt_read(void *buf)
703{
704 struct storage_t *store = store_get_current();
705
706 if (!store) {
707 pr_info("%s %d please init storage device first\n",
708 __func__, __LINE__);
709 return 1;
710 }
711 if (!store->gpt_read)
712 return 1;
713 return store->gpt_read(buf);
714}
715
716int store_gpt_write(void *buf)
717{
718 struct storage_t *store = store_get_current();
719
720 if (!store) {
721 pr_info("%s %d please init storage device first\n",
722 __func__, __LINE__);
723 return 1;
724 }
725 if (!store->gpt_write)
726 return 1;
727 return store->gpt_write(buf);
728}
729
730int store_gpt_erase(void)
731{
732 struct storage_t *store = store_get_current();
733
734 if (!store) {
735 pr_info("%s %d please init storage device first\n",
736 __func__, __LINE__);
737 return 1;
738 }
739 if (!store->gpt_erase)
740 return 1;
741 return store->gpt_erase();
742}
743
jinbiaod6719f12023-12-22 05:34:45 +0000744int store_boot_copy_enable(int index)
745{
746 struct storage_t *store = store_get_current();
747
748 if (!store) {
749 pr_info("%s %d please init storage device first\n",
750 __func__, __LINE__);
751 return -1;
752 }
753 if (!store->boot_copy_enable)
754 return -1;
755 return store->boot_copy_enable(index);
756}
757
Bo Lv72d0e902023-01-02 14:27:34 +0000758u32 store_rsv_size(const char *name)
759{
760 struct storage_t *store = store_get_current();
761
762 if (!store) {
763 pr_info("%s %d please init storage device first\n",
764 __func__, __LINE__);
765 return 1;
766 }
767 return store->get_rsv_size(name);
768}
769
770int store_rsv_read(const char *name, size_t size, void *buf)
771{
772 struct storage_t *store = store_get_current();
773
774 if (!store) {
775 pr_info("%s %d please init storage device first\n",
776 __func__, __LINE__);
777 return 1;
778 }
779 return store->read_rsv(name, size, buf);
780}
781
782int store_rsv_write(const char *name, size_t size, void *buf)
783{
784 struct storage_t *store = store_get_current();
785
786 if (!store) {
787 pr_info("%s %d please init storage device first\n",
788 __func__, __LINE__);
789 return 1;
790 }
791 return store->write_rsv(name, size, buf);
792}
793
794int store_rsv_erase(const char *name)
795{
796 struct storage_t *store = store_get_current();
797
798 if (!store) {
799 pr_info("%s %d please init storage device first\n",
800 __func__, __LINE__);
801 return 1;
802 }
803 return store->erase_rsv(name);
804}
805
806int store_rsv_protect(const char *name, bool ops)
807{
808 struct storage_t *store = store_get_current();
809
810 if (!store) {
811 pr_info("%s %d please init storage device first\n",
812 __func__, __LINE__);
813 return 1;
814 }
815 return store->protect_rsv(name, ops);
816}
817
818static int do_store_init(cmd_tbl_t *cmdtp,
819 int flag, int argc, char * const argv[])
820{
821 u32 init_flag = 1;
822 u8 ret = 0;
823
824 if (unlikely(argc != 2 && argc != 3))
825 return CMD_RET_USAGE;
826
827 if (argc == 3)
828 init_flag = simple_strtoul(argv[2], NULL, 10);
829
830 /*Returns a nonzero value: device index*/
831 if (store_init(init_flag))
832 ret = 0;
833 else ret = 1;
834 return ret;
835}
836
837void store_print_device(struct storage_t *store_dev)
838{
839 int i;
840
841 for (i = 0; i < ARRAY_SIZE(device_list); i++)
842 if (store_dev->type & device_list[i].index)
843 pr_info("device type: [%s]\n", device_list[i].type);
844 pr_info("name %s\n", store_dev->info.name);
845 pr_info("id :");
846 for (i = 0; i < ARRAY_SIZE(store_dev->info.id); i++)
847 pr_info(" 0x%x", store_dev->info.id[i]);
848 pr_info("\n");
849 pr_info("read unit %d\n", store_dev->info.read_unit);
850 pr_info("write unit %d\n", store_dev->info.write_unit);
851 pr_info("erase unit %d\n", store_dev->info.erase_unit);
852 pr_info("total size %lld\n", store_dev->info.caps);
853 if (store_dev->info.mode)
854 pr_info("bootloader in discrete mode : %d\n",
855 store_dev->info.mode);
856 else
857 pr_info("bootloader in compact mode : %d\n",
858 store_dev->info.mode);
859}
860
861static int do_store_device(cmd_tbl_t *cmdtp,
862 int flag, int argc, char * const argv[])
863{
864 if (argc == 2) {
865 struct storage_t *store_dev, *dev;
866 struct list_head *entry;
867
868 store_dev = store_get_current();
869 pr_info("current device:\n");
870 pr_info("----------------------------------\n");
871 store_print_device(store_dev);
872 pr_info("----------------------------------\n");
873 list_for_each(entry, &store_dev->list) {
874 dev = list_entry(entry, struct storage_t, list);
875 pr_info("valid device:\n");
876 pr_info("----------------------------------\n");
877 store_print_device(dev);
878 pr_info("----------------------------------\n");
879 }
880 return 0;
881 } else if (argc == 3) {
882 char *name = NULL;
883 int i = 0, ret = 0;
884 name = argv[2];
885 for (i = 0; i < ARRAY_SIZE(device_list); i++)
886 if (!strcmp(name, device_list[i].type)) {
887
888 ret = store_set_device(device_list[i].index);
889 if (!ret) {
890 pr_info("now current device is: %s\n",
891 name);
892 return 0;
893 }
894 }
895 pr_info("%s %d no such device: %s\n",
896 __func__, __LINE__, name);
897 return ret;
898 }
899 return CMD_RET_USAGE;
900}
901
902static int do_store_partition(cmd_tbl_t *cmdtp,
903 int flag, int argc, char * const argv[])
904{
905 struct storage_t *store_dev;
906 int i = 0, partitions = 0;
907 int ret = 0;
908 char name[16];
909
910 if (argc > 2)
911 return CMD_RET_USAGE;
912 else {
913 store_dev = store_get_current();
914 if (store_dev->get_part_count)
915 partitions = store_dev->get_part_count();
916 pr_info("%d partitions of device %s:\n",
917 partitions, store_dev->info.name);
918
919 if (store_dev->list_part_name)
920 ret = store_dev->list_part_name(i, name);
921
922 return ret;
923 }
924}
925
926#ifdef CONFIG_AML_MTD
927extern int is_mtd_store_boot_area(const char *part_name);
928#endif
929static int do_store_erase(cmd_tbl_t *cmdtp,
930 int flag, int argc, char * const argv[])
931{
932 struct storage_t *store = store_get_current();
933 unsigned long offset;
934 size_t size = 0;
935 char *name = NULL;
936 char *s;
937 int erase_flag = 0, ret;
938 unsigned long time;
939
940 const char *scrub =
941 "Warning: scrub_flag is 1!!!!"
942 "scrub operation!!!\n"
943 "will erase oob area\n"
944 "There is no reliable way to recover them.\n"
945 " "
946 "are sure of what you are doing!\n"
947 "\nReally erase this NAND flash? <y/N>\n";
948
949 if (!store) {
950 pr_info("%s %d please init your storage device first!\n",
951 __func__, __LINE__);
952 return CMD_RET_FAILURE;
953 }
954
955 if (!strncmp(argv[1], "scrub", 5)) {
956 erase_flag |= STORE_SCRUB;
957 puts(scrub);
958 if (!confirm_yesno()) {
959 printf("erase aborted\n");
960 return 1;
961 }
962 }
963
964 /*store erase.chip*/
965 s = strchr(argv[1], '.');
966 if (s != NULL && strcmp(s, ".chip") == 0) {
967 if (argc == 3 && !simple_strtoul(argv[argc - 1], NULL, 16))
968 erase_flag |= STORE_ERASE_DATA;
969 else if ((argc == 3) && (simple_strtoul(argv[argc - 1], NULL, 16) == 1))
970 erase_flag |= STORE_ERASE_RSV;
971 else if (argc == 3)
972 return CMD_RET_USAGE;
973
974 offset = 0;
975 } else {
976 /*store erase normal, partition name can't NULL*/
977 if (unlikely(argc != 5))
978 return CMD_RET_USAGE;
979
980 size = (size_t)simple_strtoul(argv[argc - 1], NULL, 16);
981 offset = simple_strtoul(argv[argc - 2], NULL, 16);
982 name = argv[2];
983#ifdef CONFIG_AML_MTD
984 if (is_mtd_store_boot_area(name)) {
985 pr_info("%s %d please enter normal partition name except tpl area!\n",
986 __func__, __LINE__);
987 return CMD_RET_FAILURE;
988 }
989#endif
990 }
991
992 time = get_timer(0);
993 ret = store->erase(name, offset, size, erase_flag);
994 time = get_timer(time);
995
996 if (size != 0)
997 printf("%lu bytes ", size);
998
999 printf("erased in %lu ms", time);
1000 if ((time > 0) && (size != 0)) {
1001 puts(" (");
1002 print_size(div_u64(size, time) * 1000, "/s");
1003 puts(")");
1004 }
1005 puts("\n");
1006
1007 return ret;
1008}
1009
1010static int do_store_read(cmd_tbl_t *cmdtp,
1011 int flag, int argc, char * const argv[])
1012{
1013 struct storage_t *store = store_get_current();
1014 unsigned long offset, addr, time;
1015 size_t size;
1016 char *name = NULL;
1017 int ret;
1018
1019 if (!store) {
1020 pr_info("%s %d please init your storage device first!\n",
1021 __func__, __LINE__);
1022 return CMD_RET_FAILURE;
1023 }
1024
1025 if (unlikely(argc != 5 && argc != 6))
1026 return CMD_RET_USAGE;
1027
1028 addr = simple_strtoul(argv[2], NULL, 16);
1029 size = (size_t)simple_strtoul(argv[argc - 1], NULL, 16);
1030 offset = simple_strtoul(argv[argc - 2], NULL, 16);
1031 if (argc == 6)
1032 name = argv[3];
1033#ifdef CONFIG_AML_MTD
1034 if (is_mtd_store_boot_area(name)) {
1035 pr_info("%s %d please enter normal partition name except tpl area!\n",
1036 __func__, __LINE__);
1037 return CMD_RET_FAILURE;
1038 }
1039#endif
1040 time = get_timer(0);
1041 ret = store->read(name, offset, size, (u_char *)addr);
1042 time = get_timer(time);
1043
1044 if (size != 0)
1045 pr_info("%lu bytes ", size);
1046
1047 pr_info("read in %lu ms", time);
1048 if ((time > 0) && (size != 0)) {
1049 puts(" (");
1050 print_size(div_u64(size, time) * 1000, "/s");
1051 puts(")");
1052 }
1053 puts("\n");
1054
1055 return ret;
1056}
1057
1058static int name2index(struct boot_layout *boot_layout, const char *img)
1059{
1060 boot_area_entry_t *boot_entry = NULL;
1061 int i;
1062
1063 boot_entry = boot_layout->boot_entry;
Bichao Zheng5ced7b52023-07-25 15:20:20 +08001064 for (i = 1; i <= BOOT_AREA_DEVFIP; i++) {
Bo Lv72d0e902023-01-02 14:27:34 +00001065 if (!strncmp(img, boot_entry[i].name, strlen(boot_entry[i].name)))
1066 return i;
1067 }
1068
1069 return -1;
1070}
1071
1072static int do_store_write_bl2img(cmd_tbl_t *cmdtp,
1073 int flag, int argc, char * const argv[])
1074{
1075 struct storage_t *store = store_get_current();
1076 unsigned long offset, addr;
1077 size_t size, size_src;
1078 char *name = NULL;
1079 int ret = -1, index;
1080 struct boot_layout *boot_layout = &general_boot_layout;
1081
1082 if (!store) {
1083 pr_info("%s %d please init your storage device first!\n",
1084 __func__, __LINE__);
1085 return CMD_RET_FAILURE;
1086 }
1087
1088 addr = simple_strtoul(argv[2], NULL, 16);
1089 name = argv[3];
1090 size = simple_strtoul(argv[4], NULL, 16);
1091
1092 index = name2index(&general_boot_layout, name);
1093 offset = boot_layout->boot_entry[index].offset;
1094 size_src = boot_layout->boot_entry[index].size;
1095 printf("[%s] offset:0x%lx, index:%d\n", name, offset, index);
1096
1097 if (size_src != size)
1098 printf("new img size:0x%lx != img src:0x%lx\n", size, size_src);
1099
1100 ret = store->boot_write(name, offset, size, (u_char *)addr);
1101
1102 return ret;
1103}
1104
1105int store_write_bl2img(void* addr, const char *name, size_t size)
1106{
1107 struct storage_t *store = store_get_current();
1108 unsigned long offset;
1109 size_t size_src;
1110 int ret = -1, index;
1111 struct boot_layout *boot_layout = &general_boot_layout;
1112
1113 if (!store) {
1114 pr_info("%s %d please init your storage device first!\n",
1115 __func__, __LINE__);
1116 return CMD_RET_FAILURE;
1117 }
1118
1119 index = name2index(&general_boot_layout, name);
1120 offset = boot_layout->boot_entry[index].offset;
1121 size_src = boot_layout->boot_entry[index].size;
1122 printf("[%s] offset:0x%lx, index:%d\n", name, offset, index);
1123
1124 if (size_src != size)
1125 printf("new img size:0x%zx != img src:0x%zx\n", size, size_src);
1126
1127 ret = store->boot_write(name, offset, size, (u_char *)addr);
1128 if (size != 0)
1129 printf("[%s][%d]%lx bytes\n", __func__, __LINE__, size);
1130
1131 return ret;
1132}
1133
1134static int do_store_write(cmd_tbl_t *cmdtp,
1135 int flag, int argc, char * const argv[])
1136{
1137 struct storage_t *store = store_get_current();
1138 unsigned long offset, addr, time;
1139 size_t size;
1140 char *name = NULL;
1141 int ret;
1142
1143 if (!store) {
1144 pr_info("%s %d please init your storage device first!\n",
1145 __func__, __LINE__);
1146 return CMD_RET_FAILURE;
1147 }
1148
1149 if (unlikely(argc != 5 && argc != 6))
1150 return CMD_RET_USAGE;
1151
1152 addr = simple_strtoul(argv[2], NULL, 16);
1153 offset = simple_strtoul(argv[argc - 2], NULL, 16);
1154 size = (size_t)simple_strtoul(argv[argc - 1], NULL, 16);
1155 if (argc == 6)
1156 name = argv[3];
1157#ifdef CONFIG_AML_MTD
1158 if (is_mtd_store_boot_area(name)) {
1159 pr_info("%s %d please enter normal partition name except tpl area!\n",
1160 __func__, __LINE__);
1161 return CMD_RET_FAILURE;
1162 }
1163#endif
1164 time = get_timer(0);
1165 ret = store->write(name, offset, size, (u_char *)addr);
1166 time = get_timer(time);
1167
1168 if (size != 0)
1169 printf("%lu bytes ", size);
1170
1171 printf("write in %lu ms", time);
1172 if ((time > 0) && (size != 0)) {
1173 puts(" (");
1174 print_size(div_u64(size, time) * 1000, "/s");
1175 puts(")");
1176 }
1177 puts("\n");
1178
1179 return ret;
1180}
1181
1182static int do_store_boot_read(cmd_tbl_t *cmdtp,
1183 int flag, int argc, char * const argv[])
1184{
1185 struct storage_t *store = store_get_current();
1186 unsigned long addr;
1187 size_t size;
1188 u8 cpy;
1189 char *name;
1190
1191 if (!store) {
1192 pr_info("%s %d please init your storage device first!\n",
1193 __func__, __LINE__);
1194 return CMD_RET_FAILURE;
1195 }
1196
1197 if (unlikely(argc != 6))
1198 return CMD_RET_USAGE;
1199
1200 name = argv[2];
1201 addr = (unsigned long)simple_strtoul(argv[3], NULL, 16);
1202 cpy = (u8)simple_strtoul(argv[4], NULL, 16);
1203 size = (size_t)simple_strtoul(argv[5], NULL, 16);
1204
1205 return store->boot_read(name, cpy, size, (u_char *)addr);
1206}
1207
1208static int bl2x_mode_check_header(p_payload_info_t pInfo)
1209{
1210 p_payload_info_hdr_t hdr = &pInfo->hdr;
1211 const int nItemNum = hdr->byItemNum;
1212 p_payload_info_item_t pItem = pInfo->arrItems;
1213 u8 i = 0;
1214 int sz_payload = 0;
1215 uint64_t align_size = 1;
1216 struct storage_startup_parameter *ssp = &g_ssp;
1217 uint64_t cal_copy = ssp->boot_backups;
1218
1219 printf("\naml log : info parse...\n");
1220 printf("\tsztimes : %s\n",hdr->szTimeStamp);
1221 printf("\tversion : %d\n",hdr->byVersion);
1222 printf("\tItemNum : %d\n",nItemNum);
1223 printf("\tSize : %d(0x%x)\n", hdr->nSize, hdr->nSize);
1224 if (nItemNum > 8 || nItemNum < 3) {
1225 pr_info("illegal nitem num %d\n", nItemNum);
1226 return __LINE__;
1227 }
1228 if (ssp->boot_device == BOOT_NAND_MTD)
1229 align_size = ((NAND_RSV_OFFSET / cal_copy) * ssp->sip.nsp.page_size);
1230 else if (ssp->boot_device == BOOT_SNAND)
1231 align_size = ((NAND_RSV_OFFSET / cal_copy) * ssp->sip.snasp.pagesize);
1232
1233 sz_payload = pItem->nPayLoadSize;
1234 STORAGE_ROUND_UP_IF_UNALIGN(sz_payload, align_size);
1235 if (sz_payload > ssp->boot_entry[0].size)
1236 return __LINE__;
1237 if (ssp->boot_device == BOOT_NAND_MTD)
1238 align_size = ssp->sip.nsp.block_size;
1239 else if (ssp->boot_device == BOOT_SNAND)
1240 align_size = (uint64_t)ssp->sip.snasp.pagesize *
1241 ssp->sip.snasp.pages_per_eraseblock;
1242 ++pItem;
1243
1244 for (i = 1; i < nItemNum; i++, ++pItem) {
1245 sz_payload = pItem->nPayLoadSize;
1246 STORAGE_ROUND_UP_IF_UNALIGN(sz_payload, align_size);
1247 if (sz_payload > ssp->boot_entry[i].size)
1248 return __LINE__;
1249 }
1250
1251 return 0;
1252}
1253
1254static int _store_boot_write(const char *part_name, u8 cpy, size_t size, void *addr)
1255{
1256 enum boot_type_e medium_type = store_get_type();
1257 struct storage_startup_parameter *ssp = &g_ssp;
1258
1259
1260 int ret = 0;
1261 struct storage_t *store = store_get_current();
1262 int bl2_size = BL2_SIZE;
1263 int bl2_cpynum = 0;
1264 int tpl_per_size = CONFIG_TPL_SIZE_PER_COPY;
1265 int tpl_cpynum = 0;
1266 int bootloader_maxsize = 0;
1267
1268 if (store_get_device_bootloader_mode() == COMPACT_BOOTLOADER)
1269 return store->boot_write(part_name, cpy, size, (u_char *)addr);
1270
1271 if (BOOT_NAND_MTD == medium_type || BOOT_SNAND == medium_type)
1272 tpl_cpynum = CONFIG_NAND_TPL_COPY_NUM;
1273 else if (medium_type == BOOT_SNOR)
1274 tpl_cpynum = CONFIG_NOR_TPL_COPY_NUM;
1275
1276 if (store_get_device_bootloader_mode() == ADVANCE_BOOTLOADER) {
1277 bl2_cpynum = ssp->boot_backups;
1278 } else {
1279 bootloader_maxsize = bl2_size + tpl_per_size;
1280 bl2_cpynum = CONFIG_BL2_COPY_NUM;
1281 if (size > bootloader_maxsize) {
1282 pr_info("bootloader sz 0x%lx too large,max sz 0x%x\n",
1283 size, bootloader_maxsize);
1284 return CMD_RET_FAILURE;
1285 }
1286 }
1287
1288 if ((cpy >= tpl_cpynum || cpy >= bl2_cpynum) && (cpy != BOOT_OPS_ALL)) {
1289 pr_info("update copy %d invalid, must < min(%d, %d)\n",
1290 cpy, tpl_cpynum, bl2_cpynum);
1291 return CMD_RET_FAILURE;
1292 }
1293
1294 p_payload_info_t pinfo = parse_uboot_sheader((u8 *)addr);
1295
1296 if (!pinfo) {
1297 ret = store->boot_write("tpl", cpy, size - bl2_size, (u_char *)(addr +bl2_size));
1298 if (ret) {
1299 pr_info("failed update tpl\n");
1300 return CMD_RET_FAILURE;
1301 }
1302 } else {
1303 if (bl2x_mode_check_header(pinfo)) {
1304 pr_info("!!!warning bl2xx size is bigger than bl2x layout size\n");
1305 pr_info("please check bl2x,or erase flash and turn off\n");
1306 pr_info("then turn on, and update uboot again\n");
1307 return CMD_RET_FAILURE;
1308 }
1309
1310 char name[8];
1311 int nindex = 0;
1312 p_payload_info_hdr_t hdr = &pinfo->hdr;
1313 p_payload_info_item_t pitem = pinfo->arrItems;
1314 int off_payload = 0;
1315 int sz_payload = 0;
1316
1317 memset(name, 0, 8);
1318 for (nindex = 1, pitem +=1; nindex < hdr->byItemNum; ++nindex, ++pitem) {
1319 memcpy(name, &pitem->nMagic, sizeof(unsigned int));
1320 off_payload = pitem->nOffset;
1321 sz_payload = pitem->nPayLoadSize;
1322 pr_info("item[%d]%4s offset 0x%08x sz 0x%x\n",
1323 nindex, name, off_payload, sz_payload);
1324 if (!sz_payload)
1325 continue;
1326 ret = store->boot_write(general_boot_part_entry[nindex].name, cpy, sz_payload, (u_char *)(addr + off_payload));
1327 if (ret) {
1328 pr_info("Fail in flash payload %s\n",name);
1329 return CMD_RET_FAILURE;
1330 }
1331 }
1332 }
1333
1334 ret = store->boot_write("bl2", cpy, bl2_size, (u_char *)addr);
1335 if (ret) {
1336 pr_info("Fail in flash payload bl2\n");
1337 return CMD_RET_FAILURE;
1338 }
1339 return ret;
1340
1341}
1342
1343static int do_store_boot_write(cmd_tbl_t *cmdtp,
1344 int flag, int argc, char * const argv[])
1345{
1346 struct storage_t *store = store_get_current();
1347 unsigned long addr;
1348 size_t size;
1349 u8 cpy = BOOT_OPS_ALL;
1350 char *name;
1351
1352 if (!store) {
1353 pr_info("%s %d please init your storage device first!\n",
1354 __func__, __LINE__);
1355 return CMD_RET_FAILURE;
1356 }
1357
1358 if (unlikely(argc != 5 && argc != 6))
1359 return CMD_RET_USAGE;
1360
1361 name = argv[2];
1362 addr = (unsigned long)simple_strtoul(argv[3], NULL, 16);
1363 size = (size_t)simple_strtoul(argv[argc - 1], NULL, 16);
1364 if (argc == 6)
1365 cpy = (u8)simple_strtoul(argv[4], NULL, 16);
1366
1367 if (strcmp(name, "bootloader") == 0) {
1368 return _store_boot_write(name, cpy, size, (u_char *)addr);
1369 }
1370
1371 return store->boot_write(name, cpy, size, (u_char *)addr);
1372}
1373
1374static int do_store_boot_erase(cmd_tbl_t *cmdtp,
1375 int flag, int argc, char * const argv[])
1376{
1377 struct storage_t *store = store_get_current();
1378 u8 cpy = BOOT_OPS_ALL;
1379 char *name;
1380
1381 if (!store) {
1382 pr_info("%s %d please init your storage device first!\n",
1383 __func__, __LINE__);
1384 return CMD_RET_FAILURE;
1385 }
1386
1387 if (unlikely(argc != 3 && argc != 4))
1388 return CMD_RET_USAGE;
1389
1390 name = argv[2];
1391 if (argc == 4)
1392 cpy = (u8)simple_strtoul(argv[3], NULL, 16);
1393
1394 return store->boot_erase(name, cpy);
1395}
1396
1397static int do_store_gpt_read(cmd_tbl_t *cmdtp,
1398 int flag, int argc, char * const argv[])
1399{
1400 struct storage_t *store = store_get_current();
1401 unsigned long addr;
1402 int ret;
1403
1404 if (!store) {
1405 pr_info("%s %d please init your storage device first!\n",
1406 __func__, __LINE__);
1407 return CMD_RET_FAILURE;
1408 }
1409
1410 if (unlikely(argc != 3))
1411 return CMD_RET_USAGE;
1412
1413 addr = simple_strtoul(argv[2], NULL, 16);
1414
1415 if (store->gpt_read) {
1416 ret = store->gpt_read((u_char *)addr);
1417 return ret;
1418 }
1419
1420 printf("read gpt is not prepared\n");
1421 return CMD_RET_USAGE;
1422}
1423
1424static int do_store_gpt_write(cmd_tbl_t *cmdtp,
1425 int flag, int argc, char * const argv[])
1426{
1427 struct storage_t *store = store_get_current();
1428 unsigned long addr;
1429 int ret;
1430
1431 if (!store) {
1432 pr_info("%s %d please init your storage device first!\n",
1433 __func__, __LINE__);
1434 return CMD_RET_FAILURE;
1435 }
1436
1437 if (unlikely(argc != 3))
1438 return CMD_RET_USAGE;
1439
1440 addr = simple_strtoul(argv[2], NULL, 16);
1441
1442 if (store->gpt_write) {
1443 ret = store->gpt_write((u_char *)addr);
1444 return ret;
1445 }
1446
1447 printf("write gpt is not prepared\n");
1448 return CMD_RET_USAGE;
1449}
1450
1451static int do_store_gpt_erase(cmd_tbl_t *cmdtp,
1452 int flag, int argc, char * const argv[])
1453{
1454 struct storage_t *store = store_get_current();
1455 int ret;
1456
1457 if (!store) {
1458 pr_info("%s %d please init your storage device first!\n",
1459 __func__, __LINE__);
1460 return CMD_RET_FAILURE;
1461 }
1462
1463 if (unlikely(argc != 2))
1464 return CMD_RET_USAGE;
1465
1466 if (store->gpt_erase) {
1467 ret = store->gpt_erase();
1468 return ret;
1469 }
1470
1471 printf("erase gpt is not prepared\n");
1472 return CMD_RET_USAGE;
1473}
1474
jinbiaod6719f12023-12-22 05:34:45 +00001475/*
1476 * Check whether the current boot can be written
1477 * ret: 0 disable; 1: enable
1478 */
1479static int do_store_boot_copy_enable(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1480{
1481 enum boot_type_e medium_type = store_get_type();
1482 struct storage_t *store = store_get_current();
jinbiao325839f2024-03-29 09:34:08 +00001483 int ret = CMD_RET_USAGE, index;
jinbiaod6719f12023-12-22 05:34:45 +00001484
1485 if (!store) {
1486 pr_info("%s %d please init your storage device first!\n",
1487 __func__, __LINE__);
jinbiao325839f2024-03-29 09:34:08 +00001488 return ret;
jinbiaod6719f12023-12-22 05:34:45 +00001489 }
1490
1491 if (unlikely(argc != 3))
jinbiao325839f2024-03-29 09:34:08 +00001492 return ret;
jinbiaod6719f12023-12-22 05:34:45 +00001493
1494 if (medium_type != BOOT_EMMC) {
1495 printf("%s %d not eMMC boot\n", __func__, __LINE__);
jinbiao325839f2024-03-29 09:34:08 +00001496 return ret;
jinbiaod6719f12023-12-22 05:34:45 +00001497 }
1498
1499 index = simple_strtoul(argv[2], NULL, 16);
1500 if (store->boot_copy_enable) {
1501 ret = store->boot_copy_enable(index);
jinbiao325839f2024-03-29 09:34:08 +00001502 printf("%s\n", ret ? "enable" : "disable");
1503 } else
1504 printf("boot copy enable is not prepared\n");
jinbiaod6719f12023-12-22 05:34:45 +00001505
jinbiao325839f2024-03-29 09:34:08 +00001506 return ret;
jinbiaod6719f12023-12-22 05:34:45 +00001507}
1508
Bo Lv72d0e902023-01-02 14:27:34 +00001509static int do_store_rsv_ops(cmd_tbl_t *cmdtp,
1510 int flag, int argc, char * const argv[])
1511{
1512 struct storage_t *store = store_get_current();
1513 char *name = NULL;
1514
1515 if (!store) {
1516 pr_info("%s %d please init your storage device first!\n",
1517 __func__, __LINE__);
1518 return CMD_RET_FAILURE;
1519 }
1520
1521 if (!strcmp(argv[2], "erase")) {
1522 if (argc == 3)
1523 ;
1524 else if (argc == 4)
1525 name = argv[3];
1526 else
1527 return CMD_RET_USAGE;
1528 return store->erase_rsv(name);
1529 } else if (!strcmp(argv[2], "read") ||
1530 !strcmp(argv[2], "write")) {
1531 u8 cmd = strcmp(argv[2], "read") ? 0 : 1;
1532 unsigned long addr = simple_strtoul(argv[4], NULL, 16);
1533 size_t size = (size_t)simple_strtoul(argv[5], NULL, 16);
1534
1535 name = argv[3];
1536 if (unlikely(argc != 6))
1537 return CMD_RET_USAGE;
1538 if (cmd)
1539 return store->read_rsv(name, size, (u_char *)addr);
1540 else
1541 return store->write_rsv(name, size, (u_char *)addr);
1542 } else if (!strcmp(argv[2], "protect")) {
1543 char *ops;
1544 flag = false;
1545
1546 if (unlikely(argc != 4 && argc != 5))
1547 return CMD_RET_USAGE;
1548
1549 name = (argc == 4) ? NULL : argv[3];
1550 ops = argv[argc - 1];
1551 if (!strcmp(ops, "on"))
1552 flag = true;
1553 else if (!strcmp(ops, "off"))
1554 flag = false;
1555 return store->protect_rsv(name, flag);
1556 }
1557 return CMD_RET_USAGE;
1558}
1559
1560static int do_store_param_ops(cmd_tbl_t *cmdtp,
1561 int flag, int argc, char * const argv[])
1562{
Bichao Zheng5ced7b52023-07-25 15:20:20 +08001563 struct storage_t *store = store_get_current();
Bo Lv72d0e902023-01-02 14:27:34 +00001564
Bichao Zheng050532c2024-01-09 10:24:31 +08001565 if (!store) {
1566 pr_info("%s %d please init your storage device first!\n",
1567 __func__, __LINE__);
1568 return CMD_RET_FAILURE;
1569 }
1570
Bichao Zheng5ced7b52023-07-25 15:20:20 +08001571 if (store->param_ops)
1572 return store->param_ops();
Bo Lv72d0e902023-01-02 14:27:34 +00001573
1574 return 0;
1575}
1576
1577static cmd_tbl_t cmd_store_sub[] = {
1578 U_BOOT_CMD_MKENT(init, 4, 0, do_store_init, "", ""),
1579 U_BOOT_CMD_MKENT(device, 4, 0, do_store_device, "", ""),
1580 U_BOOT_CMD_MKENT(partition, 3, 0, do_store_partition, "", ""),
1581 U_BOOT_CMD_MKENT(scrub, 5, 0, do_store_erase, "", ""),
1582 U_BOOT_CMD_MKENT(erase, 5, 0, do_store_erase, "", ""),
1583 U_BOOT_CMD_MKENT(read, 6, 0, do_store_read, "", ""),
1584 U_BOOT_CMD_MKENT(write, 7, 0, do_store_write, "", ""),
1585 U_BOOT_CMD_MKENT(write_gpt, 3, 0, do_store_gpt_write, "", ""),
1586 U_BOOT_CMD_MKENT(read_gpt, 3, 0, do_store_gpt_read, "", ""),
1587 U_BOOT_CMD_MKENT(erase_gpt, 2, 0, do_store_gpt_erase, "", ""),
1588 U_BOOT_CMD_MKENT(write_bl2img, 5, 0, do_store_write_bl2img, "", ""),
1589 U_BOOT_CMD_MKENT(boot_read, 6, 0, do_store_boot_read, "", ""),
1590 U_BOOT_CMD_MKENT(boot_write, 6, 0, do_store_boot_write, "", ""),
1591 U_BOOT_CMD_MKENT(boot_erase, 4, 0, do_store_boot_erase, "", ""),
1592 U_BOOT_CMD_MKENT(rsv, 6, 0, do_store_rsv_ops, "", ""),
1593 U_BOOT_CMD_MKENT(param, 2, 0, do_store_param_ops, "", ""),
jinbiaod6719f12023-12-22 05:34:45 +00001594 U_BOOT_CMD_MKENT(boot_copy_enable, 3, 0, do_store_boot_copy_enable, "", ""),
Bo Lv72d0e902023-01-02 14:27:34 +00001595};
1596
1597static int do_store(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1598{
1599 cmd_tbl_t *c;
1600
1601 if (argc < 2)
1602 return CMD_RET_USAGE;
1603
1604 c = find_cmd_tbl(argv[1], cmd_store_sub, ARRAY_SIZE(cmd_store_sub));
1605 if (c)
1606 return c->cmd(cmdtp, flag, argc, argv);
1607
1608 return CMD_RET_USAGE;
1609}
1610
1611U_BOOT_CMD(store, CONFIG_SYS_MAXARGS, 1, do_store,
1612 "STORE sub-system:",
1613 "store init [flag]\n"
1614 " init storage device\n"
1615 "store device [name]\n"
1616 " show or set storage device\n"
1617 " 'store device' command will list\n"
1618 " all valid storage device and print.\n"
1619 " 'store device [name]' will set the\n"
1620 " [name] device to the current device\n"
1621 "store partition\n"
1622 " show partitions of current device\n"
1623 "store read addr [partition name] off size\n"
1624 " read 'size' bytes from offset 'off'\n"
1625 " of device/partition 'partition name' to.\n"
1626 " address 'addr' of memory.\n"
1627 " if partition name not value. read start with\n"
1628 " offset in normal logic area,if tpl area exist\n"
1629 " read offset at end of tpl area\n"
1630 "store write addr [partition name] off size\n"
1631 " write 'size' bytes to offset 'off' of\n"
1632 " device/partition [partition name] from\n"
1633 " address 'addr' of memory.\n"
1634 " if partition name not value. write start with\n"
1635 " offset in normal logic area,if tpl area exist\n"
1636 " write offset at end of tpl area\n"
1637 "store write_gpt addr\n"
1638 " write gpt from address 'addr'\n"
1639 "store read_gpt addr\n"
1640 " read gpt to address 'addr'\n"
1641 "store erase_gpt\n"
1642 " erase primary and secondary gpt\n"
1643 "store erase partition name off size.\n"
1644 " erase 'size' bytes from offset 'off'\n"
1645 " of device/partition [partition name]\n"
1646 " partition name must't NULL\n"
1647 "store scrub partition name off size.\n"
1648 " erase 'size' bytes from offset 'off'\n"
1649 " of device/partition [partition name]\n"
1650 " includes oob area if the device has.\n"
1651 " partition name must't NULL\n"
1652 "store erase.chip [flag]\n"
1653 " erase all nand chip,except bad block\n"
1654 " flag 0 erase all nand chip,except bootloader&rsv\n"
1655 " flag 1 erase rsv\n"
1656 "store scrub.chip\n"
1657 " erase all nand chip,include bad block\n"
1658 "store boot_read name addr copy size\n"
1659 " read 'size' bytes from 'copy'th backup\n"
1660 " in name partition, 'copy' can't be null.\n"
1661 " name:\n"
1662 " in discrete mode: 'bl2'/'tpl'(fip)\n"
1663 " in compact mode: 'bootloader'\n"
1664 "store boot_write name addr [copy] size\n"
1665 " write 'size' bytes to 'copy'th backup\n"
1666 " in [name] partition from address\n"
1667 " 'addr' of memory. when the optional 'copy'\n"
1668 " is null, it will writes to all copies\n"
1669 " name:\n"
1670 " in discrete mode:\n"
1671 " 'bl2/bl2e/bl2x/ddrfip/tpl(fip), only update part\n"
1672 " 'bootloader', update whole uboot.bin, in this case\n"
1673 " @copy:if used, must < min(tplCpyNum, Bl2CpyNum), update only the specified copy\n"
1674 " if not used, update all the copies of bl2 bl2e bl2x ddrfip tpl!\n"
1675 " in compact mode: 'bootloader'\n"
1676 "store boot_erase name [copy]\n"
1677 " erase the name info from 'copy'th backup\n"
1678 " when the optional 'copy' not value, it\n"
1679 " will erase all copies.\n"
1680 " name:\n"
1681 " in discrete mode: \n"
1682 " 'bl2'/'tpl'(fip): erase bl2/tpl partition\n"
1683 " 'bootloader':erase bl2 + tpl partition\n"
1684 " in compact mode: 'bootloader'\n"
1685 "store rsv read name addr size\n"
1686 " read 'size' bytes 'name' rsv info\n"
1687 " to address 'addr' of memory\n"
1688 " 'name' could be key/dtb/env etc...\n"
1689 "store rsv write name addr size\n"
1690 " write 'size' bytes 'name' rsv info\n"
1691 " from address 'addr' of memory\n"
1692 "store rsv erase name\n"
1693 " erase 'name' rsv info\n"
1694 " name must't null\n"
1695 "store rsv protect name on/off\n"
1696 " turn on/off the rsv info protection\n"
1697 " name must't null\n"
1698 "store param\n"
jinbiaod6719f12023-12-22 05:34:45 +00001699 " transfer bl2e/x ddrfip devfip size to kernel in such case like sc2\n"
1700 "store boot_copy_enable [boot_index]\n"
1701 " check bootloader_x whether enable\n"
Bo Lv72d0e902023-01-02 14:27:34 +00001702);