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