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