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