1 // SPDX-License-Identifier: GPL-2.0+
10 #include <environment.h>
12 #include <ubi_uboot.h>
15 #include "bca_common.h"
16 #include "bcm_bootstate.h"
19 #include "bcm_secure.h"
20 #include "httpd/bcmbca_net.h"
23 #if defined(CONFIG_WDT)
26 #if defined(CONFIG_BCMBCA_PMC)
30 #define SIZE_OVERHEAD 0x100000UL //1M
31 #define BOOTFS_SIZE_BYTES 0x00A00000UL //10M
32 #define ROOTFS_SIZE_BYTES 0x02800000UL //40M
33 #define SQUASHFS_MAGIC 0x73717368
34 #define UBIFS_MAGIC 0x06101831
35 #define MIN_IMG_INDEX 1
36 #define MAX_IMG_INDEX 2
38 #define atoi(s) simple_strtol(s, NULL, 0)
40 DECLARE_GLOBAL_DATA_PTR
;
42 /* Flag indicating whether we want to force an update and disregard any compatibility checks */
43 static int forced_updates
= 0;
44 static char forced_image_media
[256] = {0};
45 static char forced_boot_media
[256] = {0};
46 /* Flag to prevent synching of runtime env to loader bin when flashing a new loader */
47 static int disable_runtime_env_sync
= 0;
49 typedef int (*flash_fn
)( ulong addr
, ulong size
, int img_index
);
52 char name
[20]; /* Name of upgrade bundle component */
53 flash_fn func
; /* Function to flash this upgrade bundle component */
54 } flashfn_table_entry
;
56 /* Enable CLI commands based on included CMD modules */
57 #if defined(CONFIG_CMD_GPT) && defined(CONFIG_CMD_PART) && defined(CONFIG_CMD_MMC) && defined(CONFIG_MMC)
58 #define BCA_SDK_EMMC_CMD 1
61 #if defined(CONFIG_CMD_UBI) && defined(CONFIG_CMD_MTD) && defined(CONFIG_NAND)
62 #define BCA_SDK_NAND_CMD 1
65 #if defined(CONFIG_CMD_SF) && defined(CONFIG_SPI_FLASH) && defined(CONFIG_DM_SPI_FLASH) && defined(CONFIG_CMD_MTD)
66 #define BCA_SDK_SPINOR_CMD 1
69 #if defined(BCA_SDK_SPINOR_CMD)
70 static int spinor_load_bootfs(uint32_t bootfs_load_addr
);
71 static int spinor_restoredefault(void);
72 static int write_spinor_partition( char *const partitionname
, ulong addr
, ulong size
);
73 static int do_flash_spinor_binary(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
74 static int do_flash_spinor_bootfs_rootfs(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
75 static int flash_loader_spinor( ulong addr
, ulong size
);
77 #ifdef BCA_SDK_EMMC_CMD
78 /* EMMC specific routines */
79 static int flash_rootfs_emmc( ulong addr
, ulong size
, int img_index
);
80 static int flash_bootfs_emmc( ulong addr
, ulong size
, int img_index
);
81 static int flash_loader_emmc( ulong addr
, ulong size
, int img_index
);
82 static int set_emmc_metadata( char* metadata
, int size
);
83 static int get_emmc_metadata( char* metadata
, int size
);
84 static int emmc_load_bootfs( int img_index
, uint32_t bootfs_load_addr
);
85 static int emmc_rdwr_userdata_part( char * part_name
, ulong addr
, ulong size
, int write
);
86 static int emmc_rdwr_boot_part( ulong addr
, ulong size
, int img_index
, int write
);
87 static int emmc_restoredefault(void);
88 static int emmc_do_gpt_fixup(void);
89 #endif /* BCA_SDK_EMMC_CMD */
91 #ifdef BCA_SDK_NAND_CMD
92 /* NAND Specific routines */
93 static int flash_rootfs_nand( ulong addr
, ulong size
, int img_index
);
94 static int flash_bootfs_nand( ulong addr
, ulong size
, int img_index
);
95 static int flash_loader_nand( ulong addr
, ulong size
, int img_index
);
96 static int set_nand_metadata( char* metadata
, int size
);
97 static int get_nand_metadata( char* metadata
, int size
);
98 static int nand_load_fit( int img_index
, uint32_t fit_load_addr
);
99 static int nand_load_bootfs( int img_index
, uint32_t bootfs_load_addr
);
100 static int nand_restoredefault(void);
101 #endif /* BCA_SDK_NAND_CMD */
103 /* Generic routines */
104 static unsigned int bcm_handle_mapper(void* fit
, char *flash_device
, char *flash_opts
);
105 static int update_flash_parts_from_loader_bin( ulong loader_addr
, ulong loader_size
);
106 static int get_binary_from_bundle( ulong bundle_addr
, char * conf_name
, char * name
,
107 char ** bin_name
, ulong
* addr
, ulong
* size
);
108 static int sync_update_loader_bin_env(ulong loader_addr
);
109 static int verify_compat_string( const char * compat_str
);
110 static int do_flash_bins(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
111 static int do_boot(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
112 static int do_load(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
113 static int load_linux_img(int flag
, int argc
, char *const argv
[]);
114 static int do_restoredefault(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
115 static int do_metadata(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
116 static int do_force(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
117 static int flash_rootfs( ulong addr
, ulong size
, int img_index
);
118 static int flash_bootfs( ulong addr
, ulong size
, int img_index
);
119 static int flash_loader( ulong addr
, ulong size
, int img_index
);
120 static int do_flash_loader(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
121 static int do_flash_bootfs_rootfs( char * bootfs_filename
, char * rootfs_filename
, int image_index
);
122 static int do_flash_upgrade_img (cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
123 static int set_metadata_val( int * committed
, int * valid
, int * seq
);
124 static int get_metadata_val( int * committed
, int * valid
, int * seq
);
125 static int do_activate(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
126 char * get_loader_media(void);
127 static char * get_image_media(void);
128 static int get_active_img_idx(void);
129 static int set_active_img_idx( int img_idx
);
130 #ifdef CONFIG_BCMBCA_HTTPD
131 static int do_httpd_start(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
133 #ifdef CONFIG_BCMBCA_XRDP_ETH
134 static int do_eth_active_port(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[]);
137 /* Local Variables */
138 static flashfn_table_entry fn_table
[] = {
139 { "bootfs", flash_bootfs
},
140 { "rootfs", flash_rootfs
},
141 { "loader", flash_loader
}
144 #ifdef CONFIG_BCMBCA_BOARD_SPECIFIC_DT
145 #define BCMBCA_BOARDID_MAXSIZE 28
146 #define BCMBCA_VOICEBOARDID_MAXSIZE BCMBCA_BOARDID_MAXSIZE
147 #include "spl_ddrinit.h"
148 static int on_boardid(const char *name
, const char *value
, enum env_op op
, int flags
)
150 char boardid
[BCMBCA_BOARDID_MAXSIZE
+4];
153 long conf
, node
, offset
;
156 if (forced_updates
|| ((flags
& H_INTERACTIVE
) == 0))
161 case env_op_overwrite
:
162 img_index
= get_active_img_idx();
163 if((img_index
< MIN_IMG_INDEX
) || (img_index
> MAX_IMG_INDEX
))
164 img_index
= MIN_IMG_INDEX
;
165 /* Load bootfs to load address */
166 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
167 #ifdef BCA_SDK_NAND_CMD
168 if (nand_load_fit(img_index
, load_addr
))
170 printf("Failed to load bootfs\n");
176 if( ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
177 #ifdef BCA_SDK_EMMC_CMD
178 ret
= emmc_load_bootfs(img_index
, load_addr
);
181 printf("Failed to load bootfs\n");
187 conf
= fdt_path_offset((void*)load_addr
, FIT_IMAGES_PATH
);
189 printf("Cannot find /images node: %ld\n", conf
);
193 if (strlen(value
) > BCMBCA_BOARDID_MAXSIZE
)
195 printf("boardid is too long, max size is %d\n", BCMBCA_BOARDID_MAXSIZE
);
198 sprintf(boardid
,"fdt_%s", value
);
199 for (node
= fdt_first_subnode((const void*)load_addr
, conf
); node
>= 0; node
= fdt_next_subnode((const void*)load_addr
, node
))
201 const char* image_name
= fit_get_name((const char*)load_addr
, node
, NULL
);
203 if (strcmp(image_name
, boardid
) == 0)
205 const uint32_t* memcfg
;
210 ret
= fit_image_get_data_and_size((const void*)load_addr
, node
, &fdt
, &size
);
213 printf("Failed to get FDT\n");
217 offset
= fdt_path_offset(fdt
, "/memory_controller");
219 printf("Not found memory_controller node in FDT\n");
223 memcfg
= fdt_getprop(fdt
, offset
, "memcfg", NULL
);
226 printf("Can't find memcfg parameter in DTB\n");
229 fdt_mcb
= be32_to_cpu(*memcfg
);
230 env_mcb
= env_get_hex("MCB", 0);
231 if (env_mcb
& BP_DDR_CONFIG_OVERRIDE
)
233 printf("MCB sticky bit is set, MCB is not updated\n Current MCB 0x%x, FDT MCB 0x%x\n", env_mcb
, fdt_mcb
);
236 printf("Updating MCB environment from 0x%x to 0x%x\n", env_mcb
, fdt_mcb
);
237 env_set_hex("MCB", fdt_mcb
);
238 env_set("boardid", value
);
239 printf("Memory Configuration Changed -- SAVING ENV AND REBOOT NEEDED\n");
243 printf("Error: boardid %s not supported.\nList of supported boards:\n", value
);
244 for (node
= fdt_first_subnode((const void*)load_addr
, conf
); node
>= 0; node
= fdt_next_subnode((const void*)load_addr
, node
))
246 char* name
= fit_get_name((const char*)load_addr
, node
, NULL
);
247 if ((strncmp("fdt_", name
, 4) == 0) && (strcmp("fdt_uboot", name
)))
248 printf("%s\n", (name
+4));
255 printf("## boardid may not be deleted\n");
261 U_BOOT_ENV_CALLBACK(boardid
, on_boardid
);
263 static int on_voiceBoardid(const char *name
, const char *value
, enum env_op op
, int flags
)
265 char boardid
[BCMBCA_BOARDID_MAXSIZE
+4];
268 long conf
, node
, offset
;
271 if (forced_updates
|| ((flags
& H_INTERACTIVE
) == 0))
274 pboardid
= env_get("boardid");
277 printf("boardId must be set first.\n");
283 case env_op_overwrite
:
284 img_index
= get_active_img_idx();
285 if((img_index
< MIN_IMG_INDEX
) || (img_index
> MAX_IMG_INDEX
))
286 img_index
= MIN_IMG_INDEX
;
287 /* Load bootfs to load address */
288 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
289 #ifdef BCA_SDK_NAND_CMD
290 if (nand_load_fit(img_index
, load_addr
))
292 printf("Failed to load bootfs\n");
298 if( ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
299 #ifdef BCA_SDK_EMMC_CMD
300 ret
= emmc_load_bootfs(img_index
, load_addr
);
303 printf("Failed to load bootfs\n");
309 conf
= fdt_path_offset((void*)load_addr
, FIT_IMAGES_PATH
);
311 printf("Cannot find /images node: %ld\n", conf
);
315 if (strlen(value
) > BCMBCA_VOICEBOARDID_MAXSIZE
)
317 printf("voiceboardid is too long, max size is %d\n", BCMBCA_VOICEBOARDID_MAXSIZE
);
320 sprintf(boardid
,"fdt_%s", pboardid
);
321 for (node
= fdt_first_subnode((const void*)load_addr
, conf
); node
>= 0; node
= fdt_next_subnode((const void*)load_addr
, node
))
323 const char* image_name
= fit_get_name((const char*)load_addr
, node
, NULL
);
325 if (strcmp(image_name
, boardid
) == 0)
329 int i
, len
, idx
, slicCount
;
330 const char *sliclist
;
332 ret
= fit_image_get_data_and_size((const void*)load_addr
, node
, &fdt
, &size
);
335 printf("Failed to get FDT\n");
339 offset
= fdt_path_offset(fdt
, "/bcm_voice");
341 printf("Not found voice node in FDT\n");
344 idx
= fdt_stringlist_search(fdt
, offset
, "sliclist", value
);
345 /* is the string is found, save it and exit */
348 env_set("voiceboardid", value
);
349 printf("-- saving env and reboot needeD\n");
352 printf("%d: %s is not found. idx=%d\n", __LINE__
, value
, idx
);
353 slicCount
= fdt_stringlist_count(fdt
, offset
, "sliclist");
354 printf("slicCount=%d. List of supported daughter cards:\n", slicCount
);
355 for (i
=0; i
< slicCount
; i
++)
357 sliclist
= fdt_stringlist_get(fdt
, offset
, "sliclist", i
, &len
);
359 printf("%s\n", sliclist
);
361 printf("%d: fdt_stringlist_get failed. len=%d\n", __LINE__
, len
);
368 env_set("voiceboardid", "");
369 printf("-- Saving env and reboot needed\n");
375 U_BOOT_ENV_CALLBACK( voiceboardid
, on_voiceBoardid
);
378 static int get_active_img_idx( void )
381 unsigned int active_img_idx
= 0;
382 fdt32_t
* nodep
= NULL
;
383 node
= fdt_path_offset(gd
->fdt_blob
, "/chosen");
385 printf("Can't find /chosen node in uboot DTB\n");
388 nodep
= (fdt32_t
*)fdt_getprop(gd
->fdt_blob
, node
, "active_image", &len
);
389 active_img_idx
= fdt32_to_cpu(*(fdt32_t
*)nodep
);
391 return active_img_idx
;
394 static int set_active_img_idx( int img_idx
)
397 fdt32_t
* nodep
= NULL
;
398 node
= fdt_path_offset(gd
->fdt_blob
, "/chosen");
401 printf("Can't find /chosen node in uboot DTB, device may not boot properly!\n");
403 ret
= fdt_setprop_u32(gd
->fdt_blob
, node
, "active_image", img_idx
);
406 printf("Could not set active image node in the fdt, device may not boot properly!\n");
412 /************************************************************
413 * Flash Specific Functions *
414 ************************************************************/
415 #ifdef BCA_SDK_EMMC_CMD
416 static int emmc_restoredefault(void)
418 ulong part_size_blk
, part_start_blk
;
422 /* Switch to user data partition */
423 if ( run_command("mmc dev 0 0", 0) == 0 ) {
424 env_set("part_start_blk", NULL
);
425 env_set("part_size_blk", NULL
);
426 run_command("part start mmc 0 data part_start_blk", 0);
427 run_command("part size mmc 0 data part_size_blk", 0);
428 part_start_blk
= env_get_hex("part_start_blk", 0);
429 part_size_blk
= env_get_hex("part_size_blk", 0);
431 /* If data exists, delete it */
432 if( part_size_blk
) {
433 sprintf(cmd
, "mmc erase 0x%lx 0x%lx", part_start_blk
, part_size_blk
);
434 ret
= run_command(cmd
, 0);
439 printf("Error: Cannot switch to userdata partition!\n");
445 static int emmc_rdwr_boot_part( ulong addr
, ulong size
, int img_index
, int write
)
448 ulong num_blocks
= 0;
449 ulong block_addr
= 0;
450 ulong part_size_blk
= 0;
451 int boot_part_num
= 1;
453 struct mmc
*mmc
= NULL
;
455 mmc
= find_mmc_device(0);
457 printf("Error: Cannot access mmc device!\n");
458 goto emmc_rdwr_boot_part_exit
;
461 /* Calculate number of blocks */
462 num_blocks
= size
/mmc
->read_bl_len
+ (size
%mmc
->read_bl_len
?1:0);
464 /* Determine size of raw boot partition */
465 part_size_blk
= mmc
->capacity_boot
/mmc
->read_bl_len
;
466 if( num_blocks
> part_size_blk
) {
467 printf("Error: Insufficient space in boot partition %d for 0x%lx blocks. Partition size is 0x%lx\n", boot_part_num
, num_blocks
, part_size_blk
);
468 goto emmc_rdwr_boot_part_exit
;
471 /* Switch to boot partition */
472 sprintf(cmd
, "mmc dev 0 %d", boot_part_num
);
473 if ( run_command(cmd
, 0) ) {
474 printf("Error: Cannot switch to bootpartition %d!\n", boot_part_num
);
475 goto emmc_rdwr_boot_part_exit
;
478 /* Write to raw boot partition */
479 sprintf(cmd
, "mmc %s 0x%lx 0x%lx 0x%lx", (write
?"write":"read"), addr
, block_addr
, num_blocks
);
480 ret
= run_command(cmd
, 0);
481 printf("%s: %s (bootp%d)\n", __FUNCTION__
, cmd
, boot_part_num
);
483 /* Switch back to userdata partition */
484 run_command("mmc dev 0 0", 0);
486 emmc_rdwr_boot_part_exit
:
488 printf("Error: Failed %s 0x%lx blocks from/to boot partition %d!\n", (write
?"writing":"reading"), num_blocks
, boot_part_num
);
493 static int emmc_rdwr_userdata_part( char * part_name
, ulong addr
, ulong size
, int write
)
496 ulong num_blocks
= 0;
497 ulong block_addr
= 0;
498 ulong part_size_blk
= 0;
500 struct mmc
*mmc
= NULL
;
502 mmc
= find_mmc_device(0);
504 printf("Error: Cannot access mmc device!\n");
505 goto emmc_rdwr_usrdata_part_exit
;
508 /* Calculate number of blocks */
509 num_blocks
= size
/mmc
->read_bl_len
+ (size
%mmc
->read_bl_len
?1:0);
511 /* Switch to user data partition */
512 if ( run_command("mmc dev 0 0", 0) ) {
513 printf("Error: Cannot switch to userdata partition!\n");
514 goto emmc_rdwr_usrdata_part_exit
;
517 /* Get GPT partition size in blocks */
518 env_set("part_size_blk", NULL
);
519 sprintf(cmd
, "part size mmc 0 %s part_size_blk", part_name
);
520 if(run_command(cmd
, 0) == 0) {
521 part_size_blk
= env_get_hex("part_size_blk", 0);
522 if( num_blocks
> part_size_blk
) {
523 printf("Error: Insufficient space in partition %s for 0x%lx blocks. Partition size is 0x%lx\n", part_name
, num_blocks
, part_size_blk
);
524 goto emmc_rdwr_usrdata_part_exit
;
527 printf("Error: Cannot determine size of GPT partition %s\n", part_name
);
528 goto emmc_rdwr_usrdata_part_exit
;
531 /* Get start block address of partition */
532 sprintf(cmd
, "part start mmc 0 %s part_start_blk", part_name
);
533 env_set("part_start_blk", NULL
);
534 if(run_command(cmd
, 0) == 0) {
535 block_addr
= env_get_hex("part_start_blk", 0);
536 sprintf(cmd
, "mmc %s 0x%lx 0x%lx 0x%lx", (write
?"write":"read"), addr
, block_addr
, num_blocks
);
537 ret
= run_command(cmd
, 0);
538 printf("%s: %s (%s)\n", __FUNCTION__
, cmd
, part_name
);
540 printf("Error: Cannot determine start block of GPT partition %s\n", part_name
);
541 goto emmc_rdwr_usrdata_part_exit
;
544 emmc_rdwr_usrdata_part_exit
:
546 printf("Error: Failed %s 0x%lx blocks from/to GPT partition %s!\n", (write
?"writing":"reading"), num_blocks
, part_name
);
550 static int flash_rootfs_emmc( ulong addr
, ulong size
, int img_index
)
553 int ret
= CMD_RET_FAILURE
;
555 if( !addr
|| !size
|| img_index
< MIN_IMG_INDEX
|| img_index
> MAX_IMG_INDEX
)
556 return CMD_RET_USAGE
;
558 sprintf(part_name
, "rootfs%d", img_index
);
559 ret
= emmc_rdwr_userdata_part( part_name
, (ulong
)addr
, size
, 1 );
564 static int flash_bootfs_emmc( ulong addr
, ulong size
, int img_index
)
567 int ret
= CMD_RET_FAILURE
;
569 if( !addr
|| !size
|| img_index
< MIN_IMG_INDEX
|| img_index
> MAX_IMG_INDEX
)
570 return CMD_RET_USAGE
;
572 sprintf(part_name
, "bootfs%d", img_index
);
573 ret
= emmc_rdwr_userdata_part( part_name
, (ulong
)addr
, size
, 1 );
577 static int flash_loader_emmc( ulong addr
, ulong size
, int img_index
)
582 return CMD_RET_USAGE
;
584 ret
= emmc_rdwr_boot_part( addr
, size
, img_index
, 1);
589 static int set_emmc_metadata( char* metadata
, int size
)
595 for (i
= 1; i
< 3; i
++) {
596 sprintf(part_name
, "metadata%d", i
);
597 ret
= emmc_rdwr_userdata_part( part_name
, (ulong
)metadata
, size
, 1 );
602 static int get_emmc_metadata( char* metadata
, int size
)
606 int valid
[2] = {0,0};
607 int seq
[2] = {-1,-1};
611 for (i
= 1; i
< 3; i
++) {
612 sprintf(part_name
, "metadata%d", i
);
613 ret
= emmc_rdwr_userdata_part( part_name
, (ulong
)metadata
, size
, 0 );
614 if (0 == validate_metadata(metadata
, valid
, &committed
, seq
)) {
617 printf("metadata parse error\n");
618 ret
= CMD_RET_FAILURE
;
624 static ulong
emmc_get_bootfs_size( char * fit
)
631 ulong bootfs_size
= 0;
634 /* Find images parent node offset */
635 images_noffset
= fdt_path_offset(fit
, FIT_IMAGES_PATH
);
636 if (images_noffset
< 0) {
637 printf("Can't find images parent node '%s' (%s)\n",
638 FIT_IMAGES_PATH
, fdt_strerror(images_noffset
));
642 /* Process all image subnodes */
643 for (ndepth
= 0, count
= 0,
644 noffset
= fdt_next_node(fit
, images_noffset
, &ndepth
);
645 (noffset
>= 0) && (ndepth
> 0);
646 noffset
= fdt_next_node(fit
, noffset
, &ndepth
)) {
649 * Direct child node of the images parent node,
650 * i.e. component image node.
654 if (fit_image_get_data_and_size(fit
, noffset
, &data
, &size
) == 0) {
655 bootfs_size
= ((ulong
)data
+(ulong
)size
) - (ulong
)fit
;
659 printf("Bootfs size is %lu bytes\n", bootfs_size
);
663 static int emmc_add_gpt_part( char * name
, ulong size
)
665 char * current_parts
= NULL
;
666 char * new_parts
= NULL
;
669 /* Read partitions into variable */
670 env_set("current_parts", NULL
);
671 run_command("gpt read mmc 0 current_parts", 0);
672 current_parts
= env_get("current_parts");
674 if( strstr(current_parts
, name
) ) {
675 printf("%s: GPT partition:%s of size:%luMiB exists!\n", __FUNCTION__
, name
, size
);
678 printf("%s: Adding GPT partition %s of size %luMiB\n", __FUNCTION__
, name
, size
);
681 /* Update partitions */
682 new_parts
= malloc(strlen(current_parts
) + 1024 );
684 sprintf(new_parts
, "%sname=%s,size=%luMiB;", current_parts
, name
, size
);
685 ret
= env_set("current_parts", new_parts
);
687 ret
= run_command("gpt write mmc 0 $current_parts", 0);
688 ret
= run_command("gpt verify mmc 0 $current_parts", 0);
690 printf("%s: Error allocating memory for partition string!\n", __FUNCTION__
);
693 //env_set("current_parts", NULL);
698 /* This function will create GPT partitions if it detects partition sizes specfied via
699 * uboot environment variables. The env variable name has to be in the format:
700 * <partition_name>_vol_size=<size in MiB>
701 * The function will then create GPT partition with name <partition_name> of size <size>
703 * NOTE: For NAND, equivalent ubi volumes are also created dynamically based on the same
704 * uboot env variables. However, for NAND the volumes are created in the mount-fs.sh linux
705 * startup script instead of in uboot proper.
707 #define VOL_SIZE_STR "_vol_size="
708 static int emmc_do_gpt_fixup(void)
716 char * token2
= NULL
;
721 config
= env_get("env_boot_magic");
724 printf("env_boot_magic missing in the env\n");
727 elen
= simple_strtoul(config
, NULL
, 0);
728 elen
= max(elen
, CONFIG_ENV_SIZE
);
729 envbuf
= malloc(elen
);
730 memset(envbuf
, 0, elen
);
734 printf("memory allocation failed\n");
737 ep
= (env_t
*) (envbuf
+ 8);
738 ret
= env_export(ep
);
740 /* Search environment for variable names matching <part>_vol_size */
741 token
= (char*)(ep
->data
);
742 while(strlen(token
) && (ret
== 0) && ((ulong
)token
< ((ulong
)envbuf
+elen
)))
744 token_len
= strlen(token
);
745 if( (token2
= strstr(token
, VOL_SIZE_STR
)) )
749 value
= atoi( (char*)((ulong
)token2
+ strlen(VOL_SIZE_STR
)) );
750 printf("%s: Detected env defined partition:%s, of size:%dM\n", __FUNCTION__
, name
, value
);
751 ret
= emmc_add_gpt_part(name
, value
);
754 token
= (char*)((ulong
)token
+ token_len
+ 1);
760 static int do_gpt_fixup(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
763 return emmc_do_gpt_fixup();
766 static int emmc_load_bootfs( int img_index
, uint32_t bootfs_load_addr
)
770 int ret
= CMD_RET_FAILURE
;
773 /* Set rootfs volume id */
774 int rootfs_partid
= (img_index
== 1?IMAGE_PART_ID_1
:IMAGE_PART_ID_2
)+1;
776 /* Switch to userdata partition */
777 if( run_command("mmc dev 0 0", 0) == 0 ) {
778 //FIXME: OR skip loading if FIT is already in memory
779 //FIXME: IF FIT is loaded from flash, reverify RSA of header
780 sprintf(cmd
, "bootfs%d", img_index
);
783 size
= sizeof(struct fdt_header
);
784 ret
= emmc_rdwr_userdata_part( cmd
, (ulong
)bootfs_load_addr
, size
, 0 );
786 /* Retrieve entire FIT header */
787 ret
= emmc_rdwr_userdata_part( cmd
, (ulong
)bootfs_load_addr
,
788 bcm_sec_get_reqd_load_size((ulong
)bootfs_load_addr
), 0 );
791 fit_auth
= bcm_sec_validate_fit((void*)bootfs_load_addr
, 0x10000);
794 /* Determine size of bootfs from fdt_header and load it */
795 size
= emmc_get_bootfs_size((void *)bootfs_load_addr
);
796 ret
= emmc_rdwr_userdata_part( cmd
, (ulong
)bootfs_load_addr
, size
, 0 );
798 /* generate mapper parameters */
799 sprintf(cmd
,"/dev/mmcblk0p%d", rootfs_partid
);
801 /* If device mapper not being used, set rootfs_opts manually */
802 if ( (bcm_handle_mapper((void*)(ulong
)bootfs_load_addr
, cmd
, "")) != 0)
804 /* Set default bootargs */
805 sprintf(cmd
, "env set -f rootfs_opts root=/dev/mmcblk0p%d", rootfs_partid
);
810 bcm_board_boot_fdt_fixup((void*)bootfs_load_addr
);
816 #endif /* BCA_SDK_EMMC_CMD */
818 #ifdef BCA_SDK_NAND_CMD
819 #define EXTRA_SPC_SUFFIX_STR "_extra_space"
820 static uint64_t nand_get_part_extra_bytes(char* partition_prefix
)
823 char * extra_space_str
= NULL
;
824 uint64_t extra_bytes
= 0;
825 unsigned long iargs
[4] = {0};
827 sprintf(var_name
, "%s%s", partition_prefix
, EXTRA_SPC_SUFFIX_STR
);
828 extra_space_str
= env_get(var_name
);
829 if( extra_space_str
) {
830 parse_env_nums(extra_space_str
, 1, iargs
, units
);
831 extra_bytes
= ((long long)iargs
[0]) << suffix2shift(units
[0]);
833 if( extra_bytes
< SIZE_OVERHEAD
)
834 extra_bytes
= SIZE_OVERHEAD
;
839 static uint64_t nand_get_avail_space(char * update_vol_name
)
842 static struct ubi_device
*ubi
;
843 static struct ubi_volume
*vol
;
844 uint64_t vol_size
= 0;
845 uint64_t avail_space
= 0;
848 ret
= run_command("ubi part image", 0);
850 ubi
= ubi_devices
[0];
851 for (i
= 0; i
< (ubi
->vtbl_slots
+ 1); i
++) {
852 if (!ubi
->volumes
[i
])
853 continue; /* Empty record */
854 vol
= ubi
->volumes
[i
];
855 if( strcmp(vol
->name
,update_vol_name
) == 0 ) {
856 vol_size
= vol
->reserved_pebs
* vol
->usable_leb_size
;
860 avail_space
= ubi
->avail_pebs
* ubi
->leb_size
+ vol_size
;
865 static int nand_restoredefault(void)
868 if(run_command("ubi part image", 0) == 0) {
870 /* If data exists, delete it */
871 if(run_command("ubi check data", 0) == 0 ) {
872 ret
= run_command("ubi remove data", 0);
877 printf("Error: Cannot attach ubi!\n");
882 static int flash_rootfs_nand( ulong addr
, ulong size
, int img_index
)
885 int ret
= CMD_RET_FAILURE
;
886 int rootfs_volid
= (img_index
== 1? IMAGE_VOL_ID_1
:IMAGE_VOL_ID_2
) + 1;
887 uint64_t avail_bytes
= 0;
888 uint64_t extra_space_bytes
= nand_get_part_extra_bytes("rootfs");
890 if( !addr
|| !size
|| img_index
< MIN_IMG_INDEX
|| img_index
> MAX_IMG_INDEX
)
891 return CMD_RET_USAGE
;
893 if(run_command("ubi part image", 0) == 0) {
895 /* check if new rootfs will fit in flash */
896 sprintf(cmd
, "rootfs%d", img_index
);
897 avail_bytes
= nand_get_avail_space(cmd
);
898 if( avail_bytes
< size
+extra_space_bytes
) {
899 printf("Error: Insufficient space in NAND for 0x%lx Bytes . Available size is 0x%llx\n", size
+extra_space_bytes
, avail_bytes
);
903 /* If rootfs1 exists, delete it */
904 sprintf(cmd
, "ubi check rootfs%d", img_index
);
905 if(run_command(cmd
, 0) == 0) {
906 sprintf(cmd
, "ubi remove rootfs%d", img_index
);
910 /* Create rootfs volume */
911 sprintf(cmd
, "ubi create rootfs%d %llx dynamic %d", img_index
, size
+extra_space_bytes
,
913 ret
= run_command(cmd
, 0);
915 /* Write rootfs data volume */
917 sprintf(cmd
, "ubi write %lx rootfs%d %lx\n", addr
, img_index
, size
);
918 ret
= run_command(cmd
, 0);
921 run_command("ubi detach", 0);
926 static int flash_bootfs_nand( ulong addr
, ulong size
, int img_index
)
929 int ret
= CMD_RET_FAILURE
;
930 int bootfs_volid
= (img_index
== 1? IMAGE_VOL_ID_1
:IMAGE_VOL_ID_2
);
932 uint64_t avail_bytes
= 0;
933 uint64_t extra_space_bytes
= nand_get_part_extra_bytes("bootfs");
935 if( !addr
|| !size
|| img_index
< MIN_IMG_INDEX
|| img_index
> MAX_IMG_INDEX
)
936 return CMD_RET_USAGE
;
938 ret
= run_command("ubi part image", 0);
940 /* Attach failed, check if we are running bootstrap code */
941 active_img_idx
= get_active_img_idx();
942 if( active_img_idx
== ACTIVE_IMGIDX_BOOTSTRAP
) {
943 /* We are running bootstrap image, wipe Image partition and retry */
944 printf("UBI attach fails for bootstrap image --> erasing IMAGE MTD partition\n");
945 run_command("mtd erase image", 0);
946 ret
= run_command("ubi part image", 0);
951 /* If fit1 exists, delete it */
952 if(run_command("ubi check fit1", 0) == 0)
953 run_command("ubi remove fit1", 0);
955 /* check if new bootfs will fit in flash */
956 sprintf(cmd
, "bootfs%d", img_index
);
957 avail_bytes
= nand_get_avail_space(cmd
);
958 if( avail_bytes
< size
+extra_space_bytes
) {
959 printf("Error: Insufficient space in NAND for 0x%lx Bytes . Available size is 0x%llx\n", size
+extra_space_bytes
, avail_bytes
);
963 /* If bootfs exists, delete it */
964 sprintf(cmd
, "ubi check bootfs%d", img_index
);
965 if(run_command(cmd
, 0) == 0) {
966 sprintf(cmd
, "ubi remove bootfs%d", img_index
);
970 /* Create bootfs volume */
971 sprintf(cmd
, "ubi create bootfs%d %llx static %d", img_index
, size
+extra_space_bytes
,
973 ret
= run_command(cmd
, 0);
977 sprintf(cmd
, "ubi write %lx bootfs%d %lx\n", addr
, img_index
, size
);
978 ret
= run_command(cmd
, 0);
981 run_command("ubi detach", 0);
983 printf("Error! UBI attach failed!\n");
990 static int flash_loader_nand( ulong addr
, ulong size
, int img_index
)
992 struct mtd_info
* mtd
;
993 struct erase_info erase_op
= {};
997 ulong remaining_bytes
= size
;
998 mtd
= get_mtd_device_nm("loader");
1000 if( !addr
|| !size
)
1001 return CMD_RET_USAGE
;
1004 printf("ERROR: Failed to retrieve MTD device for NAND loader!\n");
1008 if( size
> mtd
->size
) {
1009 printf("ERROR: loader size 0x%08llx is greater than mtd partition size 0x%08llx!\n", size
, mtd
->size
);
1010 put_mtd_device(mtd
);
1016 /* Block by block write of loader */
1017 for( off
=0; off
< mtd
->size
; off
+= mtd
->erasesize
)
1019 if( remaining_bytes
) {
1022 erase_op
.addr
= off
;
1023 erase_op
.len
= mtd
->erasesize
;
1025 printf("Erasing next block at 0x%08llx\n", off
);
1026 ret
= mtd_erase(mtd
, &erase_op
);
1028 /* Abort if its not a bad block error */
1029 if ((ret
== -EIO
) && erase_op
.fail_addr
) {
1030 printf("Skipping bad block at 0x%08llx\n", erase_op
.fail_addr
);
1032 /* Truncate image size if we cant fit due to bad block skip */
1033 if( remaining_bytes
> (mtd
->size
- off
- mtd
->erasesize
) )
1034 remaining_bytes
-= (remaining_bytes
< mtd
->erasesize
?remaining_bytes
:mtd
->erasesize
);
1038 printf("ERROR: Failed to erase NAND block 0x%08llx\n", off
);
1043 printf("Writing next block at 0x%08llx\n", off
);
1044 ret
= mtd_write(mtd
, off
,
1045 (remaining_bytes
< mtd
->erasesize
?remaining_bytes
:mtd
->erasesize
),
1046 &retlen
, (const uchar
*)(addr
));
1049 printf("ERROR: Failed to write NAND block 0x%08llx\n", off
);
1053 addr
+= (remaining_bytes
< mtd
->erasesize
?remaining_bytes
:mtd
->erasesize
);
1054 remaining_bytes
-= (remaining_bytes
< mtd
->erasesize
?remaining_bytes
:mtd
->erasesize
);
1061 /* Loader upgrade failed for some reason */
1062 printf("ERROR: Failed to flash NAND loader! re=%d\n", ret
);
1064 /* Loader upgrade worked */
1065 printf("NAND loader flashed successfully!\n");
1068 put_mtd_device(mtd
);
1072 static int set_nand_metadata( char* metadata
, int size
)
1077 int volmap
[] = {-1,METADATA_VOL_ID_1
,METADATA_VOL_ID_2
};
1079 ret
= ubi_part("image", NULL
);
1083 for (i
= 1; i
< 3; i
++) {
1084 sprintf(cmd
, "ubi remove metadata%d", i
);
1085 run_command(cmd
, 0);
1087 "ubi create metadata%d %d static %d", i
,
1088 METADATA_SIZE
+ 1024, volmap
[i
]);
1089 run_command(cmd
, 0);
1090 sprintf(cmd
, "metadata%d", i
);
1091 ubi_volume_write(cmd
, metadata
, size
);
1093 run_command("ubi detach", 0);
1097 static int get_nand_metadata( char* metadata
, int size
)
1101 int valid
[2] = {0,0};
1102 int seq
[2] = {-1,-1};
1106 ret
= ubi_part("image", NULL
);
1110 for (i
= 1; i
< 3; i
++) {
1111 sprintf(name
, "metadata%d", i
);
1112 ret
= ubi_volume_read(name
, metadata
, size
);
1113 printf("read from %s returned %d\n", name
, ret
);
1114 if (0 == validate_metadata(metadata
, valid
, &committed
, seq
)) {
1117 printf("metadata parse error\n");
1118 ret
= CMD_RET_FAILURE
;
1121 run_command("ubi detach", 0);
1125 static int nand_load_fit( int img_index
, uint32_t fit_load_addr
)
1128 int ret
= CMD_RET_FAILURE
;
1131 if(run_command("ubi part image", 0) == 0) {
1132 //FIXME: OR skip loading if FIT is already in memory
1133 //FIXME: IF FIT is loaded from flash, reverify RSA of header
1134 sprintf(cmd
, "ubi read %lx bootfs%d", fit_load_addr
, img_index
);
1135 ret
= run_command(cmd
, 0);
1136 /* may be it is just bootstrap image */
1138 sprintf(cmd
, "ubi read %lx fit1", fit_load_addr
);
1139 ret
= run_command(cmd
, 0);
1146 static unsigned int bcm_handle_mapper(void* fit
, char *flash_device
, char *flash_opts
)
1156 off
= fdt_path_offset(fit
, "/brcm_rootfs_encrypt");
1160 strcpy(dmdev
,"/dev/dm-0");
1161 if (val
= fdt_getprop(fit
, off
, "dev", &len
)) {
1162 strncpy(dmdev
, val
, len
);
1165 val
= fdt_getprop(fit
, off
, "type", &len
);
1169 val
= fdt_getprop(fit
, off
, "mapper", &len
);
1173 strncpy(work
, val
, len
);
1176 while (cp
= strstr(work
,"%DEVICE%")) {
1177 strncpy(cmd
, work
, cp
-work
);
1178 sprintf(&cmd
[cp
-work
], "%s %s", \
1179 flash_device
, cp
+8);
1182 if (cp
= strstr(work
,"%IMAGE_KEY%")) {
1186 off
= fdt_path_offset(gd
->fdt_blob
, "/trust/key_image_aes");
1188 printf("ERROR: Can't find /trust/key_image_aes node in boot DTB!\n");
1190 val
= (char*)(fdt_getprop(gd
->fdt_blob
, off
, "value", &len
));
1191 strncpy(cmd
, work
, cp
-work
);
1192 for (i
= 0 ; i
< len
; i
++) {
1193 sprintf(&cmd
[cp
-work
+2*i
], "%02x", val
[i
]);
1195 sprintf(&cmd
[cp
-work
+2*i
], "%s", cp
+11);
1198 sprintf(cmd
, "root=%s %s dm-mod.create=\"%s\"", dmdev
, flash_opts
, work
);
1199 env_set("rootfs_opts", cmd
);
1203 static int nand_load_bootfs( int img_index
, uint32_t bootfs_load_addr
)
1207 unsigned int magic
= 0;
1208 int ret
= CMD_RET_FAILURE
;
1211 /* Set rootfs volume id */
1212 int rootfs_volid
= (img_index
== 1?IMAGE_VOL_ID_1
:IMAGE_VOL_ID_2
)+1;
1214 if(run_command("ubi part image", 0) == 0) {
1215 /* Set default bootargs */
1216 /* Determine rootfs type */
1217 sprintf(cmd
, "ubi read %lx bootfs%d", bootfs_load_addr
, img_index
);
1218 ret
= run_command(cmd
, 0);
1220 fit_auth
= bcm_sec_validate_fit((void*)bootfs_load_addr
, 0x10000);
1223 sprintf(device
,"/dev/ubiblock0_%d", rootfs_volid
);
1224 sprintf(cmd
,"ubi.mtd=1 ubi.block=0,%d rootfstype=squashfs", rootfs_volid
);
1225 if (bcm_handle_mapper((void*)(ulong
)bootfs_load_addr
, device
, cmd
) == 0)
1227 /* mapper has set up the whole thing */
1229 bcm_board_boot_fdt_fixup((void*)bootfs_load_addr
);
1234 sprintf(cmd
, "ubi read %lx rootfs%d %d", &magic
, img_index
, (int)sizeof(unsigned int));
1235 if (run_command(cmd
, 0) == 0) {
1236 if( magic
== UBIFS_MAGIC
) {
1237 sprintf(cmd
, "env set -f rootfs_opts root=ubi:rootfs%d ubi.mtd=1 rootfstype=ubifs", img_index
);
1238 run_command(cmd
, 0);
1240 else if ( magic
== SQUASHFS_MAGIC
) {
1241 sprintf(cmd
, "env set -f rootfs_opts root=/dev/ubiblock0_%d ubi.mtd=1 ubi.block=0,%d rootfstype=squashfs", rootfs_volid
, rootfs_volid
);
1242 run_command(cmd
, 0);
1244 printf("ERROR: Invalid rootfs detected in volume rootfs1! Boot aborted!\n");
1248 printf("ERROR: Cannot determine rootfs type! Boot aborted!\n");
1252 if (!fit_auth
&& magic
== SQUASHFS_MAGIC
) {
1253 bcm_board_boot_fdt_fixup((void*)bootfs_load_addr
);
1258 #endif /* BCA_SDK_NAND_CMD */
1259 #if defined(BCA_SDK_SPINOR_CMD)
1260 static int spinor_load_bootfs(uint32_t bootfs_load_addr
)
1263 struct mtd_info
*mtd
;
1267 mtd_probe_devices();
1268 mtd
= get_mtd_device_nm(BOOTFS_PART
);
1269 if (IS_ERR_OR_NULL(mtd
)){
1270 debug("%s:MTD device %s not found, ret %ld\n",__func__
, BOOTFS_PART
,
1275 ret
= mtd_read(mtd
,0,mtd
->size
,&retlen
,(u_char
*)bootfs_load_addr
);
1278 fit_auth
= bcm_sec_validate_fit((void*)bootfs_load_addr
, 0x10000);
1281 /* If device mapper not being used, set the rootfs_opts manually */
1282 if (bcm_handle_mapper((void*)(ulong
)bootfs_load_addr
, "/dev/mtdblock3", "rootfstype=squashfs") != 0) {
1283 env_set("rootfs_opts","root=/dev/mtdblock3 rootfstype=squashfs");
1287 bcm_board_boot_fdt_fixup((void*)bootfs_load_addr
);
1290 put_mtd_device(mtd
);
1293 static int spinor_restoredefault(void)
1295 struct mtd_info
*mtd
;
1296 struct erase_info ei
;
1299 mtd_probe_devices();
1300 mtd
= get_mtd_device_nm(DATA_PART
);
1301 if (IS_ERR_OR_NULL(mtd
)){
1302 printf("ERROR!!:failed to get data partition!!\n");
1303 return CMD_RET_FAILURE
;
1306 memset(&ei
, 0, sizeof(ei
));
1310 ret
= mtd_erase(mtd
, &ei
);
1312 printf("ERROR!!: failed to restore to default!!\n");
1313 ret
= CMD_RET_FAILURE
;
1316 printf("Restore to default done.\n");
1318 put_mtd_device(mtd
);
1322 static int flash_loader_spinor( ulong addr
, ulong size
)
1325 struct mtd_info
*mtd
;
1326 struct erase_info ei
;
1329 u_char
*envbuf
= NULL
;
1336 if( !addr
|| !size
)
1337 return CMD_RET_USAGE
;
1338 mtd_probe_devices();
1339 mtd
= get_mtd_device_nm(LOADER_PART
);
1340 if (IS_ERR_OR_NULL(mtd
)){
1341 printf("%s:MTD device %s not found, ret %ld\n",__func__
, LOADER_PART
,
1346 config
= env_get("env_boot_magic");
1347 if (NULL
!= config
){
1348 elen
= simple_strtoul(config
, NULL
, 0);
1349 found
= malloc(strlen(config
) + 1);
1351 strcpy(found
, config
);
1352 envbuf
= malloc(elen
+ 12);
1355 while ((c
= strtok(NULL
, ","))) {
1356 i
= simple_strtoul(c
, NULL
, 0);
1357 debug("read from %x\n", i
);
1359 debug("read len %x\n", wr_len
);
1360 if( mtd_read(mtd
,i
,wr_len
,&retlen
, envbuf
)){
1361 debug("%s:MTD device %s read fail\n",__func__
, LOADER_PART
);
1364 /*assume addr + i will not cause any issue*/
1365 memcpy(addr
+i
, envbuf
, wr_len
);
1367 if( size
< (i
+ wr_len
)){
1368 debug("%s:Change original size from %ld to %d \n",__func__
,size
, i
+ wr_len
);
1378 printf("\nErasing MTD partition %s...\n",LOADER_PART
);
1379 memset(&ei
, 0, sizeof(ei
));
1383 ret
= mtd_erase(mtd
, &ei
);
1385 debug("%s:erase MTD device %s fail, ret %d\n",__func__
, LOADER_PART
,
1390 printf("Writing MTD partition %s...\n",LOADER_PART
);
1391 ret
= mtd_write(mtd
, 0, size
, &retlen
, addr
);
1393 debug("%s:write MTD device %s fail, ret %d\n",__func__
, LOADER_PART
,
1396 debug("%s:Erase/write MTD device %s done, ret %d\n",__func__
, LOADER_PART
,
1399 put_mtd_device(mtd
);
1404 static int write_spinor_partition( char *const partitionname
, ulong addr
, ulong size
)
1407 struct mtd_info
*mtd
;
1408 struct erase_info ei
;
1411 if( !addr
|| !size
)
1412 return CMD_RET_USAGE
;
1414 mtd_probe_devices();
1415 mtd
= get_mtd_device_nm(partitionname
);
1416 if (IS_ERR_OR_NULL(mtd
)){
1417 debug("%s:MTD device %s not found, ret %d\n",__func__
, partitionname
,
1421 printf("\nErasing MTD partition %s...\n",partitionname
);
1422 memset(&ei
, 0, sizeof(ei
));
1426 ret
= mtd_erase(mtd
, &ei
);
1428 debug("%s:erase MTD device %s fail, ret %d\n",__func__
, partitionname
,
1433 printf("Writing MTD partition %s...\n",partitionname
);
1434 ret
= mtd_write(mtd
, 0, size
, &retlen
, (u_char
*)addr
);
1436 debug("%s:write MTD device %s fail, ret %d\n",__func__
, partitionname
,
1440 put_mtd_device(mtd
);
1444 static int do_flash_spinor_binary(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
1451 /* Download binary image */
1452 sprintf(cmd
, "tftp %lx %s", load_addr
, argv
[1]);
1453 if( run_command(cmd
, 0) == 0 ) {
1454 addr
= env_get_hex("fileaddr", 0);
1455 size
= env_get_hex("filesize", 0);
1456 write_spinor_partition(SPIFLASH_MTDNAME
, addr
, size
);
1458 printf("ERROR!!: Failed to tftp spinor binary!!\n");
1463 static int do_flash_spinor_bootfs_rootfs(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
1468 int ret
= CMD_RET_FAILURE
;
1474 /* Parse arguments */
1475 if ( strcmp(argv
[0], "flash_spinor_fit") == 0) {
1477 sprintf(filename
, "brcm_full_linux.itb");
1479 sprintf(filename
, "rootfs.squashfs");
1482 sprintf(cmd
, "tftp %lx %s\n", load_addr
, filename
);
1483 if( run_command(cmd
, 0) == 0 ) {
1484 size
= env_get_hex("filesize", 0);
1485 addr
= env_get_hex("fileaddr", 0);
1487 ret
= write_spinor_partition(BOOTFS_PART
, addr
, size
);
1490 ret
= write_spinor_partition(ROOTFS_PART
, addr
, size
);
1494 printf("ERROR!!: Failed to tftp rootfs binary!!\n");
1498 #endif /*BCA_SDK_SPINOR_CMD*/
1500 /************************************************************
1501 * Generic Functions *
1502 ************************************************************/
1503 static int sync_update_loader_bin_env(ulong loader_addr
)
1507 char *envbuf
= NULL
;
1513 uint32_t magichdr
[3];
1514 int num_env_found
= 0;
1517 /* Search loader in memory for env headers */
1518 for (off
= 0; off
< (loff_t
)env_boot_magic_search_size(); off
+= 4096) {
1520 memcpy((char*)magichdr
, (char*)loader_addr
+ off
, rdlen
);
1521 if (magichdr
[0] != BOOT_MAGIC_MAGIC
) {
1525 rdlen
= magichdr
[1];
1526 ep
= (env_t
*) ((char*)loader_addr
+ off
+ 8);
1527 calc_crc
= the_env_crc32(0, ep
->data
, rdlen
- 4);
1528 if( ep
->crc
== calc_crc
) {
1535 /* Create synced env blob */
1536 if(num_env_found
== 1)
1538 /* Export environment to embed in new loader */
1539 envbuf
= malloc(max(rdlen
+ 12, CONFIG_ENV_SIZE
+ 12));
1541 printf("ERROR: Failed to allocate mem for env!\n");
1545 ep
= (env_t
*) (envbuf
+ 8);
1546 envintp
= (uint32_t *) envbuf
;
1548 /* Delete boot magic string before exporting env */
1549 config
= env_get("env_boot_magic");
1550 env_set("env_boot_magic", NULL
);
1551 ret
= env_export(ep
);
1553 printf("ERROR: Failed to export env!\n");
1554 env_set("env_boot_magic", config
);
1558 for (i
= CONFIG_ENV_SIZE
; i
< rdlen
; i
++) {
1559 envbuf
[12 + i
] = 0xff;
1561 calc_crc
= the_env_crc32(0, ep
->data
, rdlen
- 4);
1562 memcpy(&ep
->crc
, &calc_crc
, sizeof(calc_crc
));
1563 envintp
[0] = BOOT_MAGIC_MAGIC
;
1567 /* Write synched env back to loader binary */
1568 printf("Updating env in loader bin at 0x%lx\n", (long)off
);
1569 memcpy((char*)loader_addr
+ off
, envbuf
, rdlen
+12);
1581 char * get_loader_media(void)
1586 if(forced_updates
&& strlen(forced_boot_media
)) {
1587 media
= forced_boot_media
;
1588 printf("WARNING: forced_updates == 1, forcing boot media to %s!\n", media
);
1590 node
= fdt_path_offset(gd
->fdt_blob
, "/chosen");
1592 printf("ERROR: Can't find /chosen node in cboot DTB! Cannot determine boot media!\n");
1595 media
= (char*)(fdt_getprop(gd
->fdt_blob
, node
, "boot_device", &len
));
1600 static char * get_image_media(void)
1605 if(forced_updates
&& strlen(forced_image_media
)) {
1606 media
= forced_image_media
;
1607 printf("WARNING: forced_updates == 1, forcing image media to %s!\n", media
);
1609 cp
= env_get("IMAGE");
1612 unsigned long iargs
[4];
1614 parse_env_string_plus_nums(cp
, &media
, 4, iargs
, units
);
1617 printf("ERROR: Can't find IMAGE env parameter! Cannot determine image media!\n");
1623 static int flash_rootfs( ulong addr
, ulong size
, int img_index
)
1626 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1627 #ifdef BCA_SDK_NAND_CMD
1628 ret
= flash_rootfs_nand(addr
, size
, img_index
);
1632 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1633 #ifdef BCA_SDK_EMMC_CMD
1634 ret
= flash_rootfs_emmc(addr
, size
, img_index
);
1638 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_SPINOR
) == 0 ) ) {
1639 #ifdef BCA_SDK_SPINOR_CMD
1640 ret
= write_spinor_partition(ROOTFS_PART
, addr
, size
);
1645 printf("ERROR: Failed to flash bootfs binary!\n");
1650 static int flash_bootfs( ulong addr
, ulong size
, int img_index
)
1653 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1654 #ifdef BCA_SDK_NAND_CMD
1655 ret
= flash_bootfs_nand(addr
, size
, img_index
);
1659 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1660 #ifdef BCA_SDK_EMMC_CMD
1661 ret
= flash_bootfs_emmc(addr
, size
, img_index
);
1665 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_SPINOR
) == 0 ) ) {
1666 #ifdef BCA_SDK_SPINOR_CMD
1667 ret
= write_spinor_partition(BOOTFS_PART
, addr
, size
);
1671 printf("ERROR: Failed to flash bootfs binary!\n");
1675 static int flash_loader( ulong addr
, ulong size
, int img_index
)
1680 /* Synch uboot env to loader binary */
1681 if( disable_runtime_env_sync
) {
1682 printf("WARNING: Not synching runtime env to loader board_spl_fit_pre_load!\n");
1684 if( sync_update_loader_bin_env(addr
) ) {
1685 printf("ERROR: Could not sync runtime env to loader bin!\n");
1690 if( strcasecmp(get_loader_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1691 #ifdef BCA_SDK_NAND_CMD
1692 ret
= flash_loader_nand(addr
, size
, img_index
);
1696 if( ret
&& ( strcasecmp(get_loader_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1697 #ifdef BCA_SDK_EMMC_CMD
1698 ret
= flash_loader_emmc(addr
, size
, img_index
);
1702 if( ret
&& ( strcasecmp(get_loader_media(), FLASH_DEV_STR_SPINOR
) == 0 ) ) {
1703 #ifdef BCA_SDK_SPINOR_CMD
1704 ret
= flash_loader_spinor(addr
, size
);
1707 if( disable_runtime_env_sync
) {
1708 printf("WARNING: Not updating runtime env from flashed loader!\n");
1709 disable_runtime_env_sync
= 0;
1711 /* Since sync was successful, we need to scan loader
1712 * for boot magic and update runtime env */
1714 env_set("fileaddr", NULL
);
1719 printf("ERROR: Failed to flash loader binary!\n");
1724 static int set_metadata_val( int * committed
, int * valid
, int * seq
)
1732 b
= malloc(METADATA_SIZE
+ 2048);
1734 ep
= (env_t
*) & d
[2];
1735 d
[0] = METADATA_SIZE
;
1736 d
[1] = METADATA_SIZE
;
1737 i
= sprintf((char*)ep
->data
, "COMMITTED=%d",*committed
) + 1;
1738 i
= i
+ sprintf((char*)&ep
->data
[i
], "VALID=%d,%d",valid
[0],valid
[1]) + 1;
1739 i
= i
+ sprintf((char*)&ep
->data
[i
], "SEQ=%d,%d",seq
[0],seq
[1]) + 1;
1741 crc
= the_env_crc32(0, ep
->data
, (d
[0] - 4) & 0xffff);
1743 * We can't use plain crc32 because someone redefines it??
1744 * crc = crc32(0, ep->data, (d[0] - 4) & 0xffff);
1746 memcpy(&ep
->crc
, &crc
, sizeof(crc
));
1748 /* Flash metadata */
1749 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1750 #ifdef BCA_SDK_NAND_CMD
1751 ret
= set_nand_metadata(b
, METADATA_SIZE
+ 16);
1755 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1756 #ifdef BCA_SDK_EMMC_CMD
1757 ret
= set_emmc_metadata(b
, METADATA_SIZE
+ 16);
1761 printf("Setting committed %d valid %d,%d seq %d,%d\n", *committed
, valid
[0], valid
[1], seq
[0], seq
[1]);
1766 static int get_metadata_val( int * committed
, int * valid
, int * seq
)
1768 char *b
= malloc(MAX_METADATA_SIZE
);
1771 /* Read metadata from flash */
1772 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1773 #ifdef BCA_SDK_NAND_CMD
1774 ret
= get_nand_metadata( b
, MAX_METADATA_SIZE
);
1778 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1779 #ifdef BCA_SDK_EMMC_CMD
1780 ret
= get_emmc_metadata(b
, MAX_METADATA_SIZE
);
1784 /* Validate metadata */
1785 ret
= validate_metadata(b
, valid
, committed
, seq
);
1787 printf("Getting committed %d valid %d,%d seq %d,%d\n", *committed
, valid
[0], valid
[1], seq
[0], seq
[1]);
1791 int commit_image( int img_index
)
1794 int valid
[2] = {0,0};
1795 int seq
[2] = {-1,-1};
1797 /*Return directly for SPI Nor*/
1798 if( strcmp(get_image_media(), FLASH_DEV_STR_SPINOR
) == 0)
1801 /* Get committed image */
1802 get_metadata_val(&committed
, valid
, seq
);
1804 /* update committed image */
1805 committed
= img_index
;
1806 valid
[img_index
-1] = img_index
;
1807 seq
[img_index
-1] = (seq
[(img_index
== 1) ? 1 : 0] + 1) % 1000; // set newly written image sequence number one greater than other image
1809 /* Set committed image */
1810 set_metadata_val(&committed
, valid
, seq
);
1815 int get_img_index_for_upgrade(int flag
)
1818 int valid
[2] = {0,0};
1819 int seq
[2] = {-1,-1};
1821 int img_index
= get_active_img_idx();
1823 /*Return 1 for SPI Nor*/
1824 if( strcmp(get_image_media(), FLASH_DEV_STR_SPINOR
) == 0 )
1827 /* If we know the active image, always write to the inactive image */
1829 return( (img_index
==1)?2:1 );
1832 /* If we cannot determine active image, then get non committed image */
1833 get_metadata_val(&committed
, valid
, seq
);
1835 /* If no commited images then we will flash to the 1st img index */
1838 /* If we have a committed image, then we will upgrade the uncommitted one */
1839 return (committed
== 1? 2: 1);
1843 #ifndef CONFIG_LOAD_FIT_OFFSET
1844 #define CONFIG_LOAD_FIT_OFFSET SZ_16M
1847 static int load_linux_img( int flag
, int argc
, char *const argv
[])
1850 char * board_id
= NULL
;
1852 uint32_t bootfs_load_addr
= load_addr
+ CONFIG_LOAD_FIT_OFFSET
;
1856 img_index
= get_active_img_idx();
1857 } else if( argc
> 1 ) {
1858 if( strlen(argv
[1]) == 1 )
1859 img_index
= *argv
[1] - '0';
1862 img_index
= get_active_img_idx();
1870 if( img_index
< MIN_IMG_INDEX
|| img_index
> MAX_IMG_INDEX
) {
1871 printf("ERROR: Invalid Image Index specified!\n");
1872 return CMD_RET_FAILURE
;
1875 #if defined(CONFIG_BCM_BOOTSTATE)
1876 /* bcmbca_set_boot_reason(BCM_BOOT_REASON_WATCHDOG | BCM_BOOT_PHASE_LINUX_START | (bcmbca_get_boot_reason() & 0xffff0000) ); */
1878 /* Load bootfs to load address */
1879 if( strcasecmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1880 #ifdef BCA_SDK_NAND_CMD
1881 ret
= nand_load_bootfs(img_index
, bootfs_load_addr
);
1885 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1886 #ifdef BCA_SDK_EMMC_CMD
1887 ret
= emmc_load_bootfs(img_index
, bootfs_load_addr
);
1888 ret
= emmc_do_gpt_fixup();
1892 if( ret
&& ( strcasecmp(get_image_media(), FLASH_DEV_STR_SPINOR
) == 0 ) ) {
1893 #ifdef BCA_SDK_SPINOR_CMD
1894 ret
= spinor_load_bootfs(bootfs_load_addr
);
1899 #if defined(CONFIG_WDT)
1900 if (gd
->watchdog_dev
)
1901 wdt_stop(gd
->watchdog_dev
);
1904 board_id
= env_get("boardid");
1907 sprintf(cmd
, "/configurations/conf_lx_%s", board_id
);
1908 if(board_id
&& (fdt_path_offset((void *)bootfs_load_addr
, cmd
) >= 0))
1909 sprintf(cmd
, "bootm start %lx#conf_lx_%s; bootm loados; bootm prep;", bootfs_load_addr
, board_id
);
1911 sprintf(cmd
, "bootm start %lx#conf_linux; bootm loados; bootm prep;", bootfs_load_addr
);
1913 run_command(cmd
, 0);
1915 printf("ERROR: Failed to load bootfs%d!\n", img_index
);
1921 static int do_load(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
1924 if( load_linux_img( flag
, argc
, argv
) == 0 ) {
1925 printf("\nAll Image components have been loaded to DDR:\n");
1926 printf(" - To edit FDT: 'fdt <fdt cmds> ..'\n");
1927 printf(" - To launch Linux: 'bootm go'\n");
1929 printf("Linux image loading Failed!\n");
1934 static int do_boot(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
1937 if( load_linux_img( flag
, argc
, argv
) == 0 )
1938 run_command("bootm go\n", 0);
1940 printf("Linux image booting Failed!\n");
1945 static int do_flash_loader(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
1949 const char *chip_num
;
1953 /* Determine chip number */
1954 chip_num
= strstr(CONFIG_SYS_SOC
, "bcm");
1955 chip_num
+= strlen("bcm");
1957 if( strcasecmp(get_loader_media(), FLASH_DEV_STR_NAND
) == 0 ) {
1958 sprintf(cmd
, "tftp %lx loader_test_nand_%s.bin\n", load_addr
, chip_num
);
1961 if( ( strcasecmp(get_loader_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
1962 sprintf(cmd
, "tftp %lx loader_test_emmc_%s.bin\n", load_addr
, chip_num
);
1965 if( ( strcasecmp(get_loader_media(), FLASH_DEV_STR_SPINOR
) == 0 ) ) {
1966 sprintf(cmd
, "tftp %lx loader_test_spinor_%s.bin\n", load_addr
, chip_num
);
1969 if( run_command(cmd
, 0) == 0 ) {
1970 size
= env_get_hex("filesize", 0);
1971 addr
= env_get_hex("fileaddr", 0);
1972 flash_loader(addr
, size
, 0);
1974 printf("ERROR!!: Failed to tftp loader binary!!\n");
1979 static int do_flash_bootfs_rootfs( char * bootfs_filename
, char * rootfs_filename
, int img_index
)
1984 int ret
= CMD_RET_FAILURE
;
1987 if(bootfs_filename
) {
1988 sprintf(cmd
, "tftp %lx %s", load_addr
, bootfs_filename
);
1989 if( run_command(cmd
, 0) == 0 ) {
1990 size
= env_get_hex("filesize", 0);
1991 addr
= env_get_hex("fileaddr", 0);
1992 ret
= flash_bootfs(addr
, size
, img_index
);
1994 printf("ERROR!!: Failed to tftp FIT image!!\n");
1998 if(rootfs_filename
) {
1999 sprintf(cmd
, "tftp %lx %s\n", load_addr
, rootfs_filename
);
2001 if( run_command(cmd
, 0) == 0 ) {
2002 size
= env_get_hex("filesize", 0);
2003 addr
= env_get_hex("fileaddr", 0);
2004 ret
= flash_rootfs(addr
, size
, img_index
);
2006 printf("ERROR!!: Failed to tftp rootfs binary!!\n");
2012 static int do_flash_bins(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2015 char * rootfs_fname
= NULL
;
2016 char * bootfs_fname
= NULL
;
2018 int ret
= CMD_RET_FAILURE
;
2020 /* Parse arguments */
2021 if ( (strcmp(argv
[0], "flash_bootfs_raw") == 0) ) {
2022 bootfs_fname
= argv
[1];
2024 if( (strcmp(argv
[0], "flash_rootfs_raw") == 0) ) {
2025 rootfs_fname
= argv
[1];
2029 if( (argc
== 3) && (strlen(argv
[2]) == 1) )
2030 img_index
= *argv
[2] - '0';
2032 img_index
= get_img_index_for_upgrade(0);
2034 return CMD_RET_USAGE
;
2037 ret
= do_flash_bootfs_rootfs(bootfs_fname
, rootfs_fname
, img_index
);
2042 static int verify_compat_string( const char * compat_str
)
2044 const char *chip_num
;
2046 char * token
= NULL
;
2047 #ifdef BCA_SDK_NAND_CMD
2048 char flash_type_full
[20];
2049 struct mtd_info
*mtd
= NULL
;
2052 /* Early return if forced updates are enabled */
2053 if( forced_updates
) {
2054 printf("WARNING: Skipping all compatibility checks due to forced updates being enabled!\n");
2058 /* Determine chip number */
2059 chip_num
= strstr(CONFIG_SYS_SOC
, "bcm");
2060 chip_num
+= strlen("bcm");
2062 /* Determine flash type matches*/
2063 flash_type
= get_image_media();
2065 if( strcmp(flash_type
, FLASH_DEV_STR_NAND
) == 0 ) {
2066 #ifdef BCA_SDK_NAND_CMD
2067 mtd
= get_nand_dev_by_index(0);
2069 printf("ERROR: Cannot determine NAND erase block size!\n");
2070 return CMD_RET_FAILURE
;
2072 sprintf(flash_type_full
, "%s%d", flash_type
, mtd
->erasesize
>> 10 );
2076 /* Check compat string */
2077 token
= strtok((char *)compat_str
,";");
2079 if( strstr(token
, "chip=")) {
2080 token
+= strlen("chip=");
2081 if( strcasecmp(token
, chip_num
) ) {
2082 printf("ERROR: Img bundle is for %s, current chip is %s\n", token
, chip_num
);
2085 } else if( strstr(token
, "flash=")) {
2086 token
+= strlen("flash=");
2087 if( strcasecmp(token
, flash_type
) ) {
2088 if( strcmp(flash_type
, FLASH_DEV_STR_NAND
) == 0 ) {
2089 #ifdef BCA_SDK_NAND_CMD
2090 if( strcasecmp(token
, flash_type_full
) )
2092 printf("ERROR: Img bundle is for %s, current flash is %s\n", token
, flash_type_full
);
2097 printf("ERROR: Img bundle is for %s, current flash is %s\n", token
, flash_type
);
2102 token
= strtok(NULL
,";");
2107 static int get_binary_from_bundle( ulong bundle_addr
, char * conf_name
, char * name
,
2108 char ** bin_name
, ulong
* addr
, ulong
* size
)
2111 int conf_nodeoffset
= 0;
2116 if ( !conf_name
|| !name
|| !bin_name
) {
2117 printf("ERROR: Invalid conf_name %p, bin_name %p, name %p\n",
2118 conf_name
, bin_name
, name
);
2122 /* retrieve configuration node */
2123 sprintf(path
, "/configurations");
2124 sprintf(path
, "%s/%s", path
, conf_name
);
2125 conf_nodeoffset
= fdt_path_offset((void *)bundle_addr
, path
);
2126 if( conf_nodeoffset
< 0 ) {
2127 printf("ERROR: %s node not found in bundle!\n", conf_name
);
2131 /* Get actual name of fit node for bundle component */
2132 *bin_name
= fdt_getprop( (void *)bundle_addr
, conf_nodeoffset
, name
, &len
);
2134 printf("INFO: %s not found in configuration %s ...skipping!\n", name
, conf_name
);
2138 /* Retrieve node offset for bundle component */
2139 sprintf(path
, "/images/%s", *bin_name
);
2140 nodeoffset
= fdt_path_offset((void *)bundle_addr
, path
);
2141 if( nodeoffset
< 0 ) {
2142 printf("ERROR: %s node not found in bundle!\n", path
);
2146 /* Get location and size of binary's data */
2147 fit_image_get_data_and_size((void *)bundle_addr
, nodeoffset
, (const void**)addr
, size
);
2149 printf("ERROR: %s data not found in bundle!\n", *bin_name
);
2155 static int update_flash_parts_from_loader_bin( ulong loader_addr
, ulong loader_size
) {
2158 char *envbuf
= NULL
;
2164 uint32_t magichdr
[3];
2167 /* Search loader in memory for env headers */
2168 for (off
= 0; off
< (loff_t
)env_boot_magic_search_size(); off
+= 4096) {
2169 /* Search loader bin for environment */
2171 memcpy((char*)magichdr
, (char*)loader_addr
+ off
, rdlen
);
2172 if (magichdr
[0] != BOOT_MAGIC_MAGIC
) {
2176 rdlen
= magichdr
[1];
2177 ep
= (env_t
*) ((char*)loader_addr
+ off
+ 8);
2178 calc_crc
= the_env_crc32(0, ep
->data
, rdlen
- 4);
2179 if( ep
->crc
== calc_crc
) {
2187 /* Set runtime env variables based on loader's env */
2188 if( off
< (loff_t
)env_boot_magic_search_size() ) {
2190 /* read IMAGE variable */
2191 sprintf(cmd
, "env import %lx - IMAGE", (char*)ep
);
2192 run_command(cmd
, 0);
2195 if( env_get("IMAGE") == NULL
) {
2196 printf("ERROR! Failed to import IMAGE parameter from loader!\n");
2200 /* read default_partitions */
2201 if( ( strcasecmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
2202 sprintf(cmd
, "env import %lx - default_partitions", (char*)ep
);
2203 run_command(cmd
, 0);
2206 if( env_get("default_partitions") == NULL
) {
2207 printf("ERROR! Failed to import default_partitions parameter from loader!\n");
2212 /* Call partition init code */
2213 printf("INFO: flash partition config updated. Repartitioning flash!\n");
2214 ret
= board_init_flash_parts(1);
2216 printf("ERROR!: No environment found in loader binary!\n");
2221 int flash_upgrade_img_bundle( ulong bundle_addr
, int img_index
, const char * conf_name
)
2226 ulong loader_addr
=0;
2227 ulong loader_size
=0;
2230 const char * bin_name
;
2231 const char * loader_bin_name
;
2232 const char * compat_str
;
2235 int conf_nodeoffset
= 0;
2236 int max_entries
= sizeof(fn_table
)/sizeof(flashfn_table_entry
);
2239 /* verify hashes of all upgrade bundle contents */
2240 if( fit_all_image_verify((void *)bundle_addr
) ) {
2242 /* Get offset of config node */
2243 sprintf(path
, "/configurations");
2244 nodeoffset
= fdt_path_offset((void *)bundle_addr
, path
);
2245 if( nodeoffset
< 0 ) {
2246 printf("ERROR: %s node not found in bundle!\n", path
);
2247 return CMD_RET_FAILURE
;
2250 /* If configuration is specifed then use it */
2252 /* Get name of the default configuration */
2253 conf_name
= fdt_getprop((void *)bundle_addr
, nodeoffset
, "default", &len
);
2255 printf("ERROR: Default configuration not found in bundle!\n");
2256 return CMD_RET_FAILURE
;
2260 /* Get offset of selected configurations fit node */
2261 sprintf(path
, "%s/%s", path
, conf_name
);
2262 conf_nodeoffset
= fdt_path_offset((void *)bundle_addr
, path
);
2263 if( conf_nodeoffset
< 0 ) {
2264 printf("ERROR: %s node not found in bundle!\n", conf_name
);
2265 return CMD_RET_FAILURE
;
2268 /* Verify compatibility */
2269 compat_str
= fdt_getprop( (void *)bundle_addr
, conf_nodeoffset
, "compatible", &len
);
2271 printf("Error: 'compatible' node not found in bundle!\n");
2272 return CMD_RET_FAILURE
;
2275 compat_copy
= malloc(strlen(compat_str
)+1);
2278 printf("Error allocating memory for compatibility string!\n");
2279 return CMD_RET_FAILURE
;
2281 strcpy(compat_copy
, compat_str
);
2283 if( verify_compat_string(compat_copy
) ) {
2284 printf("Error: Bundle is not compatible with platform!\n");
2286 return CMD_RET_FAILURE
;
2290 /* Decide whether we want to reformat partitions based on loader
2291 * binaries partition configuration configuration */
2292 if( NULL
== env_get("IMAGE") ) {
2293 printf("WARNING: IMAGE env variable missing! Using IMAGE from loader binary!\n");
2294 if( get_binary_from_bundle(bundle_addr
, conf_name
, "loader",
2295 &loader_bin_name
, &loader_addr
, &loader_size
) == 0 ) {
2296 printf("INFO: Reformatting flash media based on new loader binary\n");
2297 if( update_flash_parts_from_loader_bin( loader_addr
, loader_size
) ) {
2298 printf("ERROR: Failed to reformat flash based loader binary!\n");
2299 return CMD_RET_FAILURE
;
2302 /* Set flag to prevent sync of run-time env to loader bin */
2303 disable_runtime_env_sync
= 1;
2305 printf("ERROR! No loader binary AND IMAGE parameter not set!\n");
2306 return CMD_RET_FAILURE
;
2308 } else if (env_get_hex("reformatOnUpgrade", 0)) {
2309 printf("INFO: Reformatting partitions because reformatOnUpgrade == 1!\n");
2310 err
= board_init_flash_parts(1);
2311 env_set("reformatOnUpgrade", NULL
);
2314 for( i
=0; i
<max_entries
&& !err
; i
++ ) {
2315 /* Parse loader only if it has not been parsed before */
2316 if( (strcmp(fn_table
[i
].name
,"loader") == 0 ) && loader_addr
&& loader_size
) {
2317 bin_name
= loader_bin_name
;
2321 if (get_binary_from_bundle( bundle_addr
, conf_name
, fn_table
[i
].name
,
2322 &bin_name
, &addr
, &size
) ) {
2327 /* Calling flashing function */
2328 printf("Flashing %s (%s: 0x%lx bytes from 0x%lx) to %s%d.....\n",
2329 fn_table
[i
].name
, bin_name
, size
, addr
, fn_table
[i
].name
,
2330 (strcmp(fn_table
[i
].name
,"loader")?img_index
:0));
2331 err
= fn_table
[i
].func(addr
, size
, img_index
);
2335 disable_runtime_env_sync
= 0;
2337 err
= CMD_RET_FAILURE
;
2343 static int do_flash_upgrade_img (cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2347 ulong bundle_addr
=0;
2348 int err
= CMD_RET_FAILURE
;
2349 const char * conf_name
= NULL
;
2351 bool download
= true;
2353 int active_img_idx
= get_active_img_idx();
2355 /* Parse and remove the optional skip argument */
2357 if ( !strcmp(argv
[1], "-s")) {
2361 } else if ( !strcmp(argv
[1], "-i")) {
2369 img_index
= get_img_index_for_upgrade(0);
2370 } else if( argc
> 2 ) {
2371 if( strlen(argv
[2]) == 1 )
2372 img_index
= *argv
[2] - '0';
2374 conf_name
= argv
[2];
2375 img_index
= get_img_index_for_upgrade(0);
2379 conf_name
= argv
[3];
2383 if( img_index
< MIN_IMG_INDEX
|| img_index
> MAX_IMG_INDEX
) {
2384 printf("ERROR: Invalid Image Index specified!\n");
2385 return CMD_RET_USAGE
;
2389 sprintf(cmd
, "tftp %lx %s", load_addr
, argv
[1]);
2391 if( !download
|| run_command(cmd
, 0) == 0 ) {
2392 bundle_addr
= env_get_hex("fileaddr", 0);
2395 /* Call main img flashing function */
2396 err
= flash_upgrade_img_bundle(bundle_addr
, img_index
, conf_name
);
2400 printf("ERROR: Image upgrade failed!!\n");
2402 printf("INFO: Image upgrade successfull!!\n");
2404 printf("INFO: Committing Image!!\n");
2405 commit_image( img_index
);
2407 /* Handle bootstrap condition */
2408 if( active_img_idx
== ACTIVE_IMGIDX_BOOTSTRAP
) {
2409 /* Now that we have a valid image flashed, change active image index */
2410 set_active_img_idx(img_index
);
2413 printf("INFO: Not Committing Image!!\n");
2420 static int do_restoredefault(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2424 if( strcmp(get_image_media(), FLASH_DEV_STR_NAND
) == 0 ) {
2425 #ifdef BCA_SDK_NAND_CMD
2426 ret
= nand_restoredefault();
2430 if( ret
&& ( strcmp(get_image_media(), FLASH_DEV_STR_EMMC
) == 0 ) ) {
2431 #ifdef BCA_SDK_EMMC_CMD
2432 ret
= emmc_restoredefault();
2436 if( ret
&& ( strcmp(get_image_media(), FLASH_DEV_STR_SPINOR
) == 0 ) ) {
2437 #ifdef BCA_SDK_SPINOR_CMD
2438 ret
= spinor_restoredefault();
2445 static int do_metadata(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2450 int valid
[2] = {0,0};
2451 int seq
[2] = {-1,-1};
2452 int status
= get_metadata_val(&committed
, valid
, seq
);
2456 printf("committed-img: %d valid-imgs: ", committed
);
2458 printf("%d", valid
[0]);
2460 printf("%d", valid
[1]);
2461 printf(", seq# img 1: %d, img2: %d\n\n", seq
[0], seq
[1]);
2464 printf("metadata parse error\n");
2466 } else if (argc
== 3) {
2467 committed
= atoi(argv
[1]);
2468 valid
[0] = atoi(strtok(argv
[2],","));
2469 valid
[1] = atoi(strtok(NULL
,","));
2471 if (0 != set_metadata_val(&committed
, valid
, seq
)) {
2472 printf("metadata parse error\n");
2480 #if defined(CONFIG_BCM_BOOTSTATE)
2481 static int do_activate(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[])
2483 bcmbca_set_boot_reason(BCM_BOOT_REASON_ACTIVATE
);
2484 run_command("reset", 0);
2489 static int do_force(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[])
2493 if( atoi(argv
[1]) == 1 ) {
2495 && ( ( strcasecmp(argv
[2], FLASH_DEV_STR_NAND
) == 0 )
2496 || ( strcasecmp(argv
[2], FLASH_DEV_STR_SPINOR
) == 0 )
2497 || ( strcasecmp(argv
[2], FLASH_DEV_STR_EMMC
) == 0 ) )
2498 && ( ( strcasecmp(argv
[3], FLASH_DEV_STR_NAND
) == 0 )
2499 || ( strcasecmp(argv
[3], FLASH_DEV_STR_SPINOR
) == 0 )
2500 || ( strcasecmp(argv
[3], FLASH_DEV_STR_EMMC
) == 0 ) ) ) {
2502 strcpy(forced_boot_media
,argv
[2]);
2503 strcpy(forced_image_media
,argv
[3]);
2504 } else if(argc
== 2) {
2507 ret
= CMD_RET_USAGE
;
2508 printf("Cannot determine boot/image flash type, please specify flash types!\n");
2512 forced_boot_media
[0] = '\0';
2513 forced_image_media
[0] = '\0';
2517 printf("Forced Image Updates: %s, Forced flash types: Boot=%s, Image=%s\n",
2518 (forced_updates
?"Enabled":"Disabled"),
2519 (forced_updates
?forced_boot_media
:"NOT SPECIFIED"),
2520 (forced_updates
?forced_image_media
:"NOT SPECIFIED"));
2525 #ifdef CONFIG_BCMBCA_HTTPD
2526 static int do_httpd_start(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[])
2528 if(!httpd_check_net_env())
2529 register_cli_job_cb(0, http_poll
);
2534 #ifdef CONFIG_BCMBCA_PMC
2535 static int do_bpcm_cmd(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2538 int err
= CMD_RET_USAGE
;
2540 u32 addr
, off
, data
;
2542 if ((argc
!= 5) && (argc
!= 4))
2545 if (!strcmp(argv
[1], "r"))
2547 else if (!strcmp(argv
[1], "w"))
2552 addr
= atoi(argv
[2]);
2553 off
= atoi(argv
[3]);
2555 data
= atoi(argv
[4]);
2556 err
= WriteBPCMRegister(addr
, off
>>2, data
);
2557 printf("bpcm write data 0x%x to addr 0x%x offset 0x%x ret %d\n",
2558 data
, addr
, off
, err
);
2560 err
= ReadBPCMRegister(addr
, off
>>2, &data
);
2561 printf("bpcm read data 0x%x from addr 0x%x offset 0x%x ret %d\n",
2562 data
, addr
, off
, err
);
2569 static int do_cpufreq(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2572 int err
= CMD_RET_USAGE
, freqMHz
;
2577 err
= CMD_RET_SUCCESS
;
2578 freqMHz
= atoi(argv
[1]);
2579 freqMHz
= set_cpu_freq(freqMHz
);
2581 printf("cpu freq set to %dMHz\n", freqMHz
);
2583 err
= CMD_RET_FAILURE
;
2589 static int do_dev_spec_key(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2592 int err
= CMD_RET_USAGE
;
2594 u32 dev_spec_key
[8];
2598 if ( (argc
== 2) && (strcmp(argv
[1], "get") == 0)) {
2599 rc
= bcm_sec_get_dev_spec_key((char*)dev_spec_key
, sizeof(u32
)*8);
2600 } else if ( (argc
>= 10) && (strcmp(argv
[1], "set") == 0)) {
2601 /* Parse and remove the optional FORCE argument */
2603 if ( !strcasecmp(argv
[2], "-f")) {
2610 for(i
=0; i
<8; i
++) {
2611 dev_spec_key
[i
] = simple_strtoul(argv
[i
+2],NULL
, 0);
2614 printf("WARNING: You are attempting to set a new device specific key.\n");
2615 len
= cli_readline("This operation cannot be undone, enter 'Y' to continue: ");
2616 if( !len
|| console_buffer
[0] != 'Y' ) {
2617 printf("Device specific key setting aborted.\n");
2618 return CMD_RET_SUCCESS
;
2621 rc
= bcm_sec_set_dev_spec_key((char*)dev_spec_key
, sizeof(u32
)*8);
2627 printf("Current Device Specific Key:\n");
2628 for( i
=0; i
<8; i
++ ) {
2629 printf(" [%d]0x%08x\n", i
, dev_spec_key
[i
]);
2632 err
= CMD_RET_SUCCESS
;
2634 err
= CMD_RET_FAILURE
;
2640 static int do_sec_ser_num(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2643 int err
= CMD_RET_USAGE
;
2645 u32 sec_ser_num
[8] = {0};
2646 char * sec_ser_num_ptr
= (char*)&sec_ser_num
[0];
2647 char * sec_ser_num_char_array
;
2648 char byte_buf
[3] = {0};
2651 bool is_set
= false;
2652 bool is_odd
= false;
2654 if ( (argc
== 2) && (strcmp(argv
[1], "get") == 0)) {
2655 rc
= bcm_sec_get_sec_ser_num((char*)sec_ser_num
, sizeof(u32
)*8);
2656 } else if ( (argc
>= 3) && (strcmp(argv
[1], "set") == 0)) {
2658 /* Parse and remove the optional FORCE argument */
2660 if ( !strcasecmp(argv
[2], "-f")) {
2667 /* Check if byte array exceeds 32 bytes OR contains an ODD number of characters */
2668 sec_ser_num_char_array
= argv
[2];
2670 /* Skip leading 0x if present */
2671 if( sec_ser_num_char_array
[1] == 'x' || sec_ser_num_char_array
[1] == 'X' )
2672 sec_ser_num_char_array
+= 2;
2674 debug("sernum:%s len:%d\n", sec_ser_num_char_array
, (int)strlen(sec_ser_num_char_array
));
2675 if( ((strlen(sec_ser_num_char_array
)/2) > sizeof(sec_ser_num
)) || (strlen(sec_ser_num_char_array
) % 2)){
2676 return CMD_RET_USAGE
;
2679 /* Check if there is an odd number of digits so that we can insert an extra zero */
2680 if( strlen(sec_ser_num_char_array
) % 2 )
2683 for(i
=0,j
=sizeof(sec_ser_num
)-strlen(sec_ser_num_char_array
)/2;
2684 i
<strlen(sec_ser_num_char_array
),j
<sizeof(sec_ser_num
); j
++){
2685 if( is_odd
&& (i
== 0) ) {
2686 byte_buf
[1] = sec_ser_num_char_array
[i
];
2690 memcpy(byte_buf
,&sec_ser_num_char_array
[i
], 2);
2694 sec_ser_num_ptr
[j
] = simple_strtoul(byte_buf
,NULL
,16);
2695 debug("byte_buf: %s 0x%02x\n", byte_buf
, sec_ser_num_ptr
[j
]);
2699 printf("WARNING: You are attempting to set a new secure serial number.\n");
2700 len
= cli_readline("This operation cannot be undone, enter 'Y' to continue: ");
2701 if( !len
|| console_buffer
[0] != 'Y' ) {
2702 printf("secure serial number setting aborted.\n");
2703 return CMD_RET_SUCCESS
;
2706 rc
= bcm_sec_set_sec_ser_num((char*)sec_ser_num
, sizeof(u32
)*8);
2713 printf("Set Secure Serial Number as:\n");
2715 printf("Current Secure Serial Number:\n");
2718 for( i
=0; i
<sizeof(sec_ser_num
); i
++ ) {
2719 printf("%02x", sec_ser_num_ptr
[i
]);
2723 printf("In memory represenation:\n");
2724 for( i
=0; i
<8; i
++ ) {
2725 printf(" [%d]0x%08x\n", i
, sec_ser_num
[i
]);
2728 err
= CMD_RET_SUCCESS
;
2730 err
= CMD_RET_FAILURE
;
2735 static int do_antirollback(cmd_tbl_t
* cmdtp
, int flag
, int argc
,
2738 int err
= CMD_RET_USAGE
;
2744 if ( (argc
== 2) && (strcmp(argv
[1], "get") == 0)) {
2745 rc
= bcm_sec_get_antirollback_lvl(&lvl
);
2746 } else if ( (argc
>= 3) && (strcmp(argv
[1], "set") == 0)) {
2747 /* Parse and remove the optional FORCE argument */
2749 if ( !strcasecmp(argv
[2], "-f")) {
2757 lvl
= atoi(argv
[2]);
2759 printf("WARNING: You are attempting to set a new anti-rollback level.\n");
2760 len
= cli_readline("This operation cannot be undone, enter 'Y' to continue: ");
2761 if( !len
|| console_buffer
[0] != 'Y' ) {
2762 printf("Anti-rollback level setting aborted.\n");
2763 return CMD_RET_SUCCESS
;
2766 rc
= bcm_sec_set_antirollback_lvl(lvl
);
2772 printf("Current anti-rollback level set to: %d\n", lvl
);
2773 err
= CMD_RET_SUCCESS
;
2775 err
= CMD_RET_FAILURE
;
2781 #ifdef CONFIG_BCMBCA_XRDP_ETH
2782 extern int bcmbca_xrdp_eth_phy_status(void);
2783 extern int bcmbca_xrdp_eth_mac_status(void);
2784 extern int bcmbca_xrdp_eth_active_port_get(void);
2785 extern int bcmbca_xrdp_eth_active_port_set(int port
);
2786 extern int bcmbca_xrdp_eth_env_active_port_set(int port
);
2788 static int do_eth_active_port(cmd_tbl_t
* cmdtp
, int flag
, int argc
, char *const argv
[])
2794 port
= (atoi(argv
[1]));
2795 bcmbca_xrdp_eth_active_port_set(port
);
2798 port
= bcmbca_xrdp_eth_active_port_get();
2799 printf("XRDP Ethernet active port is set to %d\n" ,port
);
2804 static int on_active_port(const char *name
, const char *value
, enum env_op op
, int flags
)
2806 int active_port
= -1;
2808 if ((flags
& H_INTERACTIVE
) == 0)
2813 case env_op_overwrite
:
2814 active_port
= simple_strtoul(value
, NULL
, 10);
2822 return bcmbca_xrdp_eth_env_active_port_set(active_port
);
2824 U_BOOT_ENV_CALLBACK(active_port
, on_active_port
);
2827 static char usage
[] =
2828 #ifdef BCA_SDK_EMMC_CMD
2829 "\n## eMMC Specific Test Commands ##\n"
2831 " - Create GPT partitions if partition sizes are specfied via special uboot\n"
2832 " - environment variables. The env variable name has to be in the format:\n"
2833 " - <partition_name>_vol_size=<size in MiB>\n"
2834 #endif /* BCA_SDK_EMMC_CMD */
2835 #ifdef BCA_SDK_SPINOR_CMD
2836 "\n## SPINOR Specific Test Commands ##\n"
2837 "flash_spinor_fit\n"
2838 " - Download and flash atf+uboot+vmlinux+dtb in brcm_full.itb to SPI NOR flash \n"
2839 "flash_spinor_rootfs\n"
2840 " - Download and flash rootfs in rootfs.squashfs to SPI NOR flash\n"
2841 "flash_spinor_upgrade [-s] <filename> [conf]\n"
2842 "flash_spinor_upgrade <filename> [<img> [<conf>]]\n"
2843 " - Download and flash an image upgrade bundle to SPI NOR flash\n"
2844 "flash_spinor_binary <filename> \n"
2845 " - Erase whole flash,download and flash a binary image to SPI NOR flash start from 0\n"
2846 "boot_spinor [boardid]\n"
2847 " - Boot linux from image in SPI NOR flash.\n"
2849 "\n## Generic Test Commands ##\n"
2851 " - Without arguments, display if forced image updates are enabled\n"
2852 "force [force value] <[Boot Flash Type] [Image Flash Type]>\n"
2853 " - Enable(value=1)/Disable(value=0) forced image updates. All compatibility checks are ignored if enabled\n"
2854 " - If boot and image flash types are not detected, then they need to be specified as 2nd and 3rd args\n"
2855 " - Valid flash type values = [NAND|SPINAND|EMMC|NOR]\n"
2857 " - Delete contents of /data so that it gets populated with default values\n"
2859 " - Download and flash SPL+TPL in loader_test_<flash>_<chip>.bin to boot flash\n"
2860 #if defined(BCA_SDK_NAND_CMD) || defined(BCA_SDK_EMMC_CMD)
2861 "flash_bootfs_raw <bootfs binary> [img]\n"
2862 "flash_rootfs_raw <rootfs binary> [img]\n"
2863 " - Download and flash raw bootfs/rootfs binary to flash \n"
2864 " - WARNING: These are raw writes with no content, security or compatibility checks. Metadata is NOT updated \n"
2866 "metadata [committed] [valid],[valid]\n"
2867 " - without arguments, parse and display metadata\n"
2868 " - set metadata values (example \"metadata 1 1,2\" for both images valid and #1 committed)\n"
2869 " - NOTE: Must do a sw reset for metadata changes to take affect\n"
2871 "flash_img_upgrade [-s] <filename> [conf]\n"
2872 "flash_img_upgrade [-i] <filename> [<img> [<conf>]]\n"
2873 " - Download and flash an image upgrade bundle via TFTP\n"
2874 " - NOTE: Must do a sw reset to use the new image\n"
2875 "load_img [boardid]\n"
2876 "load_img [<img> [<boardid>]]\n"
2877 " - Load image from flash into DDR.\n"
2878 "boot_img [boardid]\n"
2879 "boot_img [<img> [<boardid>]]\n"
2880 " - Boot linux from image in flash.\n"
2881 "[Legend - Optional Parameters]\n"
2882 " -s: Skip downloading the image via tftp. Assume it is already at ${fileaddr}\n"
2883 " -i: Inactive. Do not change activation state of new image i.e do not commit image\n"
2884 " img: Image index for flashing/booting. Valid values: [1|2]. Default index is determined from metadata\n"
2885 " fstype: Filesystem type for flashing. Valid values: [squashfs|ubifs|ext4]. Default is squashfs\n"
2886 " boardid: Boardid to determine boot configuration. If omitted default configuration node is used\n"
2887 " conf: Configuration name used for flashing img bundle. If omitted default configuration node is used\n\n"
2888 #ifdef CONFIG_BCMBCA_HTTPD
2890 " - without arguments, start httpd server\n"
2892 #ifdef CONFIG_BCMBCA_PMC
2893 "bpcm_cmd <r|w> <addr> <offset> [<data>]\n"
2894 " - read/write bpcm register\n"
2895 "cpufreq <freq in MHz>\n"
2896 " - set cpu frequency\n"
2898 "antirollback get\n"
2899 " - get current anti-rollback level\n"
2900 "antirollback set [-f] <new anti-rollback level to set>\n"
2901 " - set new anti-rollback level. [-f] will force the commit and skip warnings\n"
2902 "sec_ser_num get \n"
2903 " - get current secure serial number level ( 64 digits )\n"
2904 "sec_ser_num set [-f] < Hex secure serial number ( Max 64 digits )>\n"
2905 " - set new secure serial number . [-f] will force the commit and skip warnings\n"
2906 "dev_spec_key get \n"
2907 " - get current device specific key ( 32 bytes )\n"
2908 "dev_spec_key set [-f] <32-bit hex word 0>...<32-bit hex word 7> \n"
2909 " - set new device specific key. [-f] will force the commit and skip warnings\n"
2912 static char sdk_usage
[] =
2914 " - Without arguments, display if forced image updates are enabled\n"
2915 "force [force value] <[Boot Flash Type] [Image Flash Type]>\n"
2916 " - Enable(value=1)/Disable(value=0) forced image updates. All compatibility checks are ignored if enabled\n"
2917 " - If boot and image flash types are not detected, then they need to be specified as 2nd and 3rd args\n"
2918 " - Valid flash type values = [NAND|SPINAND|EMMC|NOR]\n"
2920 " - Delete contents of /data so that it gets populated with default values\n"
2921 #if defined(BCA_SDK_NAND_CMD) || defined(BCA_SDK_EMMC_CMD)
2923 "metadata [committed] [valid],[valid]\n"
2924 " - without arguments, parse and display metadata\n"
2925 " - set metadata values (example \"metadata 1 1,2\" for both images valid and #1 committed)\n"
2926 " - NOTE: Must do a sw reset for metadata changes to take affect\n"
2928 "flash_img_upgrade [-s] <filename> [conf]\n"
2929 "flash_img_upgrade [-i] <filename> [<img> [<conf>]]\n"
2930 " - Download and flash an image upgrade bundle via TFTP\n"
2931 " - NOTE: Must do a sw reset to use the new image\n"
2932 "load_img [boardid]\n"
2933 "load_img [<img> [<boardid>]]\n"
2934 " - Load image from flash into DDR.\n"
2935 "boot_img [boardid]\n"
2936 "boot_img [<img> [<boardid>]]\n"
2937 " - Boot linux from image in flash.\n"
2938 "[Legend - Optional Parameters]\n"
2939 " -s: Skip downloading the image via tftp. Assume it is already at ${fileaddr}\n"
2940 " -i: Inactive. Mark new image as inactive i.e do not commit image\n"
2941 " img: Image index for flashing/booting. Valid values: [1|2]. Default index is determined from metadata\n"
2942 " boardid: Boardid to determine boot configuration. If omitted default configuration node is used\n"
2943 " conf: Configuration name used for flashing img bundle. If omitted default configuration node is used\n\n"
2944 #ifdef CONFIG_BCMBCA_HTTPD
2946 " - without arguments, start httpd server\n"
2948 #ifdef CONFIG_BCMBCA_XRDP_ETH
2949 "active_port [port]\n"
2950 " - Set the active network driver's port to send packets from\n"
2951 " - without arguments, display the current active port\n"
2952 "eth_status [type]\n"
2953 " - Print the XRDP Ethernet network driver status tables\n"
2954 " - Argument can be phy or mac. If no argument provided, both tables will be printed\n"
2958 U_BOOT_CMD_WITH_SUBCMDS(bca_test
, "Broadcom test commands", usage
,
2959 U_BOOT_SUBCMD_MKENT(flash_loader
, 1, 0, do_flash_loader
),
2960 #ifdef BCA_SDK_EMMC_CMD
2961 U_BOOT_SUBCMD_MKENT(gpt_fixup
, 1, 0, do_gpt_fixup
),
2962 #endif /* BCA_SDK_EMMC_CMD */
2963 #ifdef BCA_SDK_SPINOR_CMD
2964 U_BOOT_SUBCMD_MKENT(flash_spinor_fit
, 1, 0, do_flash_spinor_bootfs_rootfs
),
2965 U_BOOT_SUBCMD_MKENT(flash_spinor_rootfs
, 1, 0, do_flash_spinor_bootfs_rootfs
),
2966 U_BOOT_SUBCMD_MKENT(flash_spinor_upgrade
, 5, 0, do_flash_upgrade_img
),
2967 U_BOOT_SUBCMD_MKENT(flash_spinor_binary
, 2, 0, do_flash_spinor_binary
),
2968 U_BOOT_SUBCMD_MKENT(boot_spinor
, 3, 0, do_boot
),
2970 #if defined(CONFIG_BCM_BOOTSTATE)
2971 U_BOOT_SUBCMD_MKENT(activate
, 1, 0, do_activate
),
2972 #endif /* CONFIG_BCM_BOOTSTATE */
2973 U_BOOT_SUBCMD_MKENT(force
, 4, 0, do_force
),
2974 U_BOOT_SUBCMD_MKENT(restoredefault
, 1, 0, do_restoredefault
),
2975 #if defined(BCA_SDK_NAND_CMD) || defined(BCA_SDK_EMMC_CMD)
2976 U_BOOT_SUBCMD_MKENT(flash_bootfs_raw
, 3, 0, do_flash_bins
),
2977 U_BOOT_SUBCMD_MKENT(flash_rootfs_raw
, 3, 0, do_flash_bins
),
2978 U_BOOT_SUBCMD_MKENT(metadata
, 5, 0, do_metadata
),
2980 U_BOOT_SUBCMD_MKENT(flash_img_upgrade
, 5, 0, do_flash_upgrade_img
),
2981 U_BOOT_SUBCMD_MKENT(boot_img
, 3, 0, do_boot
)
2982 #ifdef CONFIG_BCMBCA_HTTPD
2983 ,U_BOOT_SUBCMD_MKENT(httpd_start
, 1, 0, do_httpd_start
)
2985 #ifdef CONFIG_BCMBCA_PMC
2986 ,U_BOOT_SUBCMD_MKENT(bpcm_cmd
, 5, 0, do_bpcm_cmd
)
2987 ,U_BOOT_SUBCMD_MKENT(cpufreq
, 2, 0, do_cpufreq
)
2989 ,U_BOOT_SUBCMD_MKENT(antirollback
, 4, 0, do_antirollback
)
2990 ,U_BOOT_SUBCMD_MKENT(sec_ser_num
, 12, 0, do_sec_ser_num
)
2991 ,U_BOOT_SUBCMD_MKENT(dev_spec_key
, 12, 0, do_dev_spec_key
)
2994 U_BOOT_CMD_WITH_SUBCMDS(sdk
, "Broadcom SDK support commands", sdk_usage
,
2995 U_BOOT_SUBCMD_MKENT(force
, 4, 0, do_force
),
2996 U_BOOT_SUBCMD_MKENT(restoredefault
, 1, 0, do_restoredefault
),
2997 #if defined(BCA_SDK_NAND_CMD) || defined(BCA_SDK_EMMC_CMD)
2998 U_BOOT_SUBCMD_MKENT(metadata
, 5, 0, do_metadata
),
3000 U_BOOT_SUBCMD_MKENT(flash_img_upgrade
, 5, 0, do_flash_upgrade_img
),
3001 U_BOOT_SUBCMD_MKENT(boot_img
, 3, 0, do_boot
),
3002 U_BOOT_SUBCMD_MKENT(load_img
, 3, 0, do_load
)
3003 #ifdef CONFIG_BCMBCA_HTTPD
3004 ,U_BOOT_SUBCMD_MKENT(httpd_start
, 1, 0, do_httpd_start
)
3006 #ifdef CONFIG_BCMBCA_XRDP_ETH
3007 ,U_BOOT_SUBCMD_MKENT(active_port
, 2, 0, do_eth_active_port
)