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