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