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