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