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