2 * Broadcom Common Firmware Environment (CFE)
3 * Board device initialization, File: ui_bcm947xx.c
5 * Copyright (C) 2012, Broadcom Corporation
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
13 * $Id: ui_bcm947xx.c 398971 2013-04-26 22:39:49Z $
16 #include "lib_types.h"
17 #include "lib_string.h"
18 #include "lib_queue.h"
19 #include "lib_malloc.h"
20 #include "lib_printf.h"
23 #include "cfe_devfuncs.h"
24 #include "cfe_ioctl.h"
25 #include "cfe_error.h"
26 #include "cfe_fileops.h"
27 #include "cfe_loader.h"
28 #include "ui_command.h"
29 #include "bsp_config.h"
38 #include <bcmendian.h>
46 unsigned char DETECT(void);
49 extern void LEDON(void);
50 extern void LEDOFF(void);
51 extern void GPIO_INIT(void);
52 extern void FANON(void);
56 #define PWR_LED_GPIO (1 << 0) // GPIO 0
57 #define RST_BTN_GPIO (1 << 7) // GPIO 7
59 #define PWR_LED_GPIO (1 << 3) // GPIO 3
60 #define RST_BTN_GPIO (1 << 11) // GPIO 11
63 #define TURBO_LED_GPIO (1 << 4) // GPIO 4
65 #define USB_LED_GPIO (1 << 0) // GPIO 0
66 #define WL5G_LED_GPIO (1 << 6) // GPIO 6
67 #define USB3_LED_GPIO (1 << 14) // GPIO 14
69 #define WPS_BTN_GPIO (1 << 7) // GPIO 7
72 #define WPS_BTN_GPIO (1 << 11) // GPIO 11
74 #define WPS_BTN_GPIO (1 << 15) // GPIO 15
80 ui_cmd_reboot(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
87 _ui_cmd_nvram(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
89 char *command
, *name
, *value
;
94 if (!(command
= cmd_getarg(cmd
, 0)))
95 return CFE_ERR_INV_PARAM
;
97 if (!strcmp(command
, "get")) {
98 if ((name
= cmd_getarg(cmd
, 1)))
99 if ((value
= nvram_get(name
)))
100 printf("%s\n", value
);
101 } else if (!strcmp(command
, "set")) {
102 if ((name
= cmd_getarg(cmd
, 1))) {
103 if ((value
= strchr(name
, '=')))
105 else if ((value
= cmd_getarg(cmd
, 2))) {
107 value
= cmd_getarg(cmd
, 3);
110 nvram_set(name
, value
);
112 } else if (!strcmp(command
, "unset")) {
113 if ((name
= cmd_getarg(cmd
, 1)))
115 } else if (!strcmp(command
, "commit")) {
117 } else if (!strcmp(command
, "corrupt")) {
119 nvram_commit_internal(TRUE
);
121 } else if (!strcmp(command
, "otpcommit")) {
122 nvram_otpcommit((void *)sih
);
124 } else if (!strcmp(command
, "erase")) {
125 extern char *flashdrv_nvram
;
126 if ((ret
= cfe_open(flashdrv_nvram
)) < 0)
128 if (!(buf
= KMALLOC(MAX_NVRAM_SPACE
, 0))) {
130 return CFE_ERR_NOMEM
;
132 memset(buf
, 0xff, MAX_NVRAM_SPACE
);
133 cfe_writeblk(ret
, 0, (unsigned char *)buf
, MAX_NVRAM_SPACE
);
136 } else if (!strcmp(command
, "show") || !strcmp(command
, "getall")) {
137 if (!(buf
= KMALLOC(MAX_NVRAM_SPACE
, 0)))
138 return CFE_ERR_NOMEM
;
139 nvram_getall(buf
, MAX_NVRAM_SPACE
);
140 for (name
= buf
; *name
; name
+= strlen(name
) + 1)
141 printf("%s\n", name
);
142 size
= sizeof(struct nvram_header
) + ((uintptr
)name
- (uintptr
)buf
);
143 printf("size: %d bytes (%d left)\n", size
, MAX_NVRAM_SPACE
- size
);
151 ui_cmd_nvram(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
153 return _ui_cmd_nvram(cmd
, argc
, argv
);
158 ui_cmd_devinfo(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
163 tmp
= flashdrv_nvram
;
164 flashdrv_nvram
= devinfo_flashdrv_nvram
;
165 _nvram_hash_select(1); /* 1 is devinfo hash table idx */
167 ret
= _ui_cmd_nvram(cmd
, argc
, argv
);
169 /* revert back to default nvram hash table */
170 flashdrv_nvram
= tmp
;
171 _nvram_hash_select(0); /* 0 is nvram hash table idx */
178 check_trx(char *trx_name
)
183 struct trx_header trx
;
186 static uint32 buf
[16*1024];
188 uint32 crc
, buf
[512];
189 #endif /* CFG_NFLASH */
191 unsigned int len
, count
;
194 ret
= fs_init("raw", &fsctx
, trx_name
);
198 ret
= fs_open(fsctx
, &ref
, "", FILE_MODE_READ
);
205 ret
= fs_read(fsctx
, ref
, (unsigned char *) &trx
, sizeof(struct trx_header
));
206 if (ret
!= sizeof(struct trx_header
)) {
211 /* Verify magic number */
212 if (ltoh32(trx
.magic
) != TRX_MAGIC
) {
213 ret
= CFE_ERR_INVBOOTBLOCK
;
217 /* Checksum over header */
218 crc
= hndcrc32((uint8
*) &trx
.flag_version
,
219 sizeof(struct trx_header
) - OFFSETOF(struct trx_header
, flag_version
),
222 for (len
= ltoh32(trx
.len
) - sizeof(struct trx_header
); len
; len
-= count
) {
224 count
= MIN(len
, sizeof(buf
) - sizeof(struct trx_header
));
227 count
= MIN(len
, sizeof(buf
));
230 ret
= fs_read(fsctx
, ref
, (unsigned char *) &buf
, count
);
236 /* Checksum over data */
237 crc
= hndcrc32((uint8
*) &buf
, count
, crc
);
240 /* Verify checksum */
241 if (ltoh32(trx
.crc32
) != crc
) {
242 ret
= CFE_ERR_BOOTPROGCHKSUM
;
249 fs_close(fsctx
, ref
);
252 xprintf("%s\n", cfe_errortext(ret
));
259 unsigned long gpioin
;
261 sih
= si_kattach(SI_OSH
);
263 gpioin
= si_gpioin(sih
);
266 return gpioin
& RST_BTN_GPIO
? FALSE
: TRUE
;
269 bool rmode_set(void) /* reset mode */
271 unsigned long gpioin
;
273 sih
= si_kattach(SI_OSH
);
275 gpioin
= si_gpioin(sih
);
278 return gpioin
& WPS_BTN_GPIO
? FALSE
: TRUE
;
281 extern void LEDON(void)
283 sih
= si_kattach(SI_OSH
);
285 si_gpioouten(sih
, PWR_LED_GPIO
, PWR_LED_GPIO
, GPIO_DRV_PRIORITY
);
287 si_gpioouten(sih
, TURBO_LED_GPIO
, TURBO_LED_GPIO
, GPIO_DRV_PRIORITY
);
290 /* negative logic and hence val==0 */
291 si_gpioout(sih
, PWR_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
293 si_gpioout(sih
, TURBO_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
296 extern void GPIO_INIT(void)
298 sih
= si_kattach(SI_OSH
);
300 si_gpiocontrol(sih
, PWR_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
302 si_gpiocontrol(sih
, TURBO_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
304 si_gpioouten(sih
, PWR_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
306 si_gpioouten(sih
, TURBO_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
310 extern void LEDOFF(void)
312 sih
= si_kattach(SI_OSH
);
314 si_gpioouten(sih
, PWR_LED_GPIO
, PWR_LED_GPIO
, GPIO_DRV_PRIORITY
);
316 si_gpioouten(sih
, TURBO_LED_GPIO
, TURBO_LED_GPIO
, GPIO_DRV_PRIORITY
);
318 si_gpioout(sih
, PWR_LED_GPIO
, PWR_LED_GPIO
, GPIO_DRV_PRIORITY
);
320 si_gpioout(sih
, TURBO_LED_GPIO
, TURBO_LED_GPIO
, GPIO_DRV_PRIORITY
);
325 extern void OTHERLEDOFF(void)
327 sih
= si_kattach(SI_OSH
);
329 si_gpioouten(sih
, WL5G_LED_GPIO
, WL5G_LED_GPIO
, GPIO_DRV_PRIORITY
);
330 si_gpioout(sih
, WL5G_LED_GPIO
, WL5G_LED_GPIO
, GPIO_DRV_PRIORITY
);
331 si_gpioouten(sih
, USB_LED_GPIO
, USB_LED_GPIO
, GPIO_DRV_PRIORITY
);
332 si_gpioout(sih
, USB_LED_GPIO
, USB_LED_GPIO
, GPIO_DRV_PRIORITY
);
333 si_gpioouten(sih
, USB3_LED_GPIO
, USB3_LED_GPIO
, GPIO_DRV_PRIORITY
);
334 si_gpioout(sih
, USB3_LED_GPIO
, USB3_LED_GPIO
, GPIO_DRV_PRIORITY
);
338 unsigned char DETECT(void)
343 if ((rescueflag
= nvram_get("rescueflag")) != NULL
) {
344 if (!nvram_invmatch("rescueflag", "enable")) {
345 xprintf("Rescue Flag enable.\n");
349 xprintf("Rescue Flag disable.\n");
355 nvram_set("rescueflag", "disable");
359 xprintf("Null Rescue Flag.\n");
366 /* Set 1 to be high active and 0 to be low active */
372 #endif // RESCUE_MODE
375 * ui_get_loadbuf(bufptr, bufsize)
377 * Figure out the location and size of the staging buffer.
380 * bufptr - address to return buffer location
381 * bufsize - address to return buffer size
383 static void ui_get_loadbuf(uint8_t **bufptr
, int *bufsize
)
385 int size
= CFG_FLASH_STAGING_BUFFER_SIZE
;
388 * Get the address of the staging buffer. We can't
389 * allocate the space from the heap to store the
390 * new flash image, because the heap may not be big
391 * enough. So, if FLASH_STAGING_BUFFER_SIZE is non-zero
392 * then just use it and FLASH_STAGING_BUFFER; else
393 * use the larger of (mem_bottomofmem - FLASH_STAGING_BUFFER)
394 * and (mem_totalsize - mem_topofmem).
398 *bufptr
= (uint8_t *) KERNADDR(CFG_FLASH_STAGING_BUFFER_ADDR
);
402 int reserved
= CFG_FLASH_STAGING_BUFFER_ADDR
;
404 /* For small memory size (8MB), we tend to use the below region.
405 * The buffer address may conflict with the os running address,
406 * so we reserve 3MB for the os.
408 if ((mem_totalsize
== (8*1024)) && (PHYSADDR(mem_bottomofmem
) > 0x300000))
411 below
= PHYSADDR(mem_bottomofmem
) - reserved
;
412 above
= (mem_totalsize
<< 10) - PHYSADDR(mem_topofmem
);
415 *bufptr
= (uint8_t *) KERNADDR(reserved
);
418 *bufptr
= (uint8_t *) KERNADDR(mem_topofmem
);
424 #if defined(DUAL_IMAGE) || defined(FAILSAFE_UPGRADE)
426 int check_image_prepare_cmd(int the_image
, char *buf
, uint32 osaddr
, int bufsize
)
429 char trx_name
[16], os_name
[16];
430 char trx2_name
[16], os2_name
[16];
433 ui_get_trx_flashdev(trx_name
);
434 ui_get_os_flashdev(os_name
);
436 strcpy(trx_name
, "flash1.trx");
437 strcpy(os_name
, "flash0.os");
440 strncpy(trx2_name
, trx_name
, sizeof(trx2_name
));
441 strncpy(os2_name
, os_name
, sizeof(os2_name
));
442 strcat(trx2_name
, "2");
443 strcat(os2_name
, "2");
445 if (the_image
== 0) {
446 if ((ret
= check_trx(trx_name
)) == 0) {
447 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr
, bufsize
,
450 printf("%s CRC check failed!\n", trx_name
);
452 } else if (the_image
== 1) {
453 if ((ret
= check_trx(trx2_name
)) == 0) {
454 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr
, bufsize
,
457 printf("%s CRC check failed!\n", trx2_name
);
460 printf("Image partition %d does not exist\n", the_image
);
464 #endif /* DUAL_IMAGE || FAILSAFE_UPGRADE */
468 ui_get_boot_flashdev(char *flashdev
)
473 if (soc_boot_dev((void *)sih
) == SOC_BOOTDEV_NANDFLASH
)
474 strcpy(flashdev
, "nflash1.boot");
476 strcpy(flashdev
, "flash1.boot");
482 ui_get_os_flashdev(char *flashdev
)
487 if (soc_knl_dev((void *)sih
) == SOC_KNLDEV_NANDFLASH
)
488 strcpy(flashdev
, "nflash0.os");
490 strcpy(flashdev
, "flash0.os");
496 ui_get_trx_flashdev(char *flashdev
)
501 if (soc_knl_dev((void *)sih
) == SOC_KNLDEV_NANDFLASH
)
502 strcpy(flashdev
, "nflash1.trx");
504 strcpy(flashdev
, "flash1.trx");
508 #endif /* CFG_NFLASH */
511 ui_cmd_go(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
515 struct trx_header
*file_buf
;
533 #ifdef FAILSAFE_UPGRADE
534 char *bootpartition
= nvram_get(BOOTPARTITION
);
535 char *partialboots
= nvram_get(PARTIALBOOTS
);
536 char *maxpartialboots
= nvram_get(MAXPARTIALBOOTS
);
539 char *bootpartition
= nvram_get(IMAGE_BOOT
);
542 char trx_name
[16], os_name
[16];
544 char *trx_name
= "flash1.trx";
545 char *os_name
= "flash0.os";
546 #endif /* CFG_NFLASH */
550 val
= nvram_get("os_ram_addr");
552 osaddr
= bcm_strtoul(val
, NULL
, 16);
562 strcpy(trx_name
, "nflash1.trx");
563 strcpy(os_name
, "nflash0.os");
566 xprintf("Hello!! Enter Rescue Mode: (by Force)\n\n");
567 /* Wait forever for an image */
568 while ((ret
= ui_docommand("flash -noheader : nflash1.trx")) == CFE_ERR_TIMEOUT
) {
580 else if (rmode_set()) {
581 xprintf("Wait until reset button released...\n");
582 while(rmode_set() == 1) {
583 if ((i
%100000) < 50000) {
595 ui_docommand ("nvram erase");
596 ui_docommand ("reboot");
600 xprintf("boot the image...\n"); // tmp test
602 if (check_trx(trx_name
) || nvram_match("asus_trx_test", "1")) {
603 xprintf("Hello!! Enter Rescue Mode: (Check error)\n\n");
604 FW_err_count
= atoi(nvram_get("Ate_FW_err"));
606 sprintf(FW_err
, "%d", FW_err_count
);
607 nvram_set("Ate_FW_err", FW_err
);
609 if(nvram_match("asus_mfg", "1")){ // goto cmd mode if during ATE mode
614 /* wait for cmd input */
615 xprintf("\n1. Wait 10 secs to enter tftp mode\n or push RESCUE-BTN to enter cmd mode\n");
622 /* Wait awhile for an image */
623 xprintf("\n2. enter tftp mode:\n");
625 while ((ret
= ui_docommand("flash -noheader : nflash1.trx")) == CFE_ERR_TIMEOUT
) {
638 /* try reboot if no actions at all */
639 xprintf("\n\n3. rebooting...\n");
640 ui_docommand ("reboot");
642 } else if (!nvram_invmatch("boot_wait", "on")) {
644 xprintf("go load\n"); // tmp test
645 ui_get_loadbuf(&ptr
, &bufsize
);
647 sprintf(buf
, "load -raw -addr=0x%x -max=0x%x :", (unsigned int)ptr
, bufsize
);
648 ret
= ui_docommand(buf
);
650 /* Load was successful. Check for the TRX magic.
651 * If it's a TRX image, then proceed to flash it, else try to boot
652 * Note: To boot a TRX image directly from the memory, address will need to be
653 * load address + trx header length.
656 file_buf
= (struct trx_header
*)ptr
;
657 /* If it's a TRX, then proceed to writing to flash else,
658 * try to boot from memory
660 if (file_buf
->magic
!= TRX_MAGIC
) {
661 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x -fs=memory :0x%x",
662 osaddr
, (unsigned int)bufsize
, (unsigned int)ptr
);
663 return ui_docommand(buf
);
665 /* Flash the image from memory directly */
666 sprintf(buf
, "flash -noheader -mem -size=0x%x 0x%x nflash1.trx",
667 (unsigned int)file_buf
->len
, (unsigned int)ptr
);
668 ret
= ui_docommand(buf
);
675 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
676 if (bootpartition
!= NULL
) {
678 ui_get_trx_flashdev(trx_name
);
680 trx_failed
= check_trx(trx_name
);
682 strcat(trx_name
, "2");
684 trx_failed
&= check_trx(trx_name
);
686 #endif /* FAILSAFE_UPGRADE || DUAL_IMAGE */
689 ui_get_trx_flashdev(trx_name
);
690 ui_get_os_flashdev(os_name
);
692 trx_failed
= check_trx(trx_name
);
696 /* Wait for CFE_ERR_TIMEOUT_LIMIT for an image */
698 sprintf(buf
, "flash -noheader :%s", trx_name
);
699 if ((ret
= ui_docommand(buf
)) != CFE_ERR_TIMEOUT
)
701 if (++retry
== CFE_ERR_TIMEOUT_LIMIT
) {
706 //} else if (!nvram_invmatch("boot_wait", "on")) {
707 } else if (0) { // disable for tmp
708 ui_get_loadbuf(&ptr
, &bufsize
);
710 sprintf(buf
, "load -raw -addr=0x%p -max=0x%x :", ptr
, bufsize
);
711 ret
= ui_docommand(buf
);
713 /* Load was successful. Check for the TRX magic.
714 * If it's a TRX image, then proceed to flash it, else try to boot
715 * Note: To boot a TRX image directly from the memory, address will need to be
716 * load address + trx header length.
719 file_buf
= (struct trx_header
*)ptr
;
720 /* If it's a TRX, then proceed to writing to flash else,
721 * try to boot from memory
723 if (file_buf
->magic
!= TRX_MAGIC
) {
724 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x -fs=memory :0x%p",
725 osaddr
, bufsize
, ptr
);
726 return ui_docommand(buf
);
728 /* Flash the image from memory directly */
729 sprintf(buf
, "flash -noheader -mem -size=0x%x 0x%p %s",
730 file_buf
->len
, ptr
, trx_name
);
731 ret
= ui_docommand(buf
);
734 #endif // RESCUE_MODE
736 if (ret
== CFE_ERR_INTR
)
739 #ifdef __ARM_ARCH_7A__
740 /* Support for loading to ACP base */
741 bufsize
= (PHYSADDR(mem_bottomofmem
) - (PHYSADDR(osaddr
) & ~0x80000000));
743 bufsize
= (PHYSADDR(mem_bottomofmem
) - PHYSADDR(osaddr
));
746 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
747 /* Get linux_boot variable to see what is current image */
748 if (bootpartition
!= NULL
) {
750 int i
= atoi(bootpartition
);
751 #ifdef FAILSAFE_UPGRADE
752 if (maxpartialboots
&& (atoi(maxpartialboots
) > 0)) {
753 if (partialboots
&& (atoi(partialboots
) > atoi(maxpartialboots
))) {
755 printf("Changed to the other image %d"
756 " (maxpartialboots exceeded)\n", i
);
757 /* reset to new image */
758 sprintf(temp
, "%d", i
);
759 nvram_set(PARTIALBOOTS
, "1");
760 nvram_set(BOOTPARTITION
, temp
);
763 /* Increment the counter */
764 sprintf(temp
, "%d", partialboots
? atoi(partialboots
)+1 : 1);
765 nvram_set(PARTIALBOOTS
, temp
);
769 #endif /* FAILSAFE_UPGRADE */
771 /* If we hav eexceeded the max partition # reset it to 0 */
773 nvram_set(BOOTPARTITION
, "0");
776 /* We try the specified one, if it is failed, we try the other one */
777 if (check_image_prepare_cmd(i
, buf
, osaddr
, bufsize
) == 0) {
778 printf("Booting(%d): %s\n", i
, buf
);
779 } else if (check_image_prepare_cmd(1-i
, buf
, osaddr
, bufsize
) == 0) {
780 printf("Changed to the other image %d\n", 1 - i
);
781 sprintf(temp
, "%d", 1-i
);
782 nvram_set(BOOTPARTITION
, temp
);
783 #ifdef FAILSAFE_UPGRADE
784 nvram_set(PARTIALBOOTS
, "1");
788 printf("Both images bad!!!\n");
793 #endif /* FAILSAFE_UPGRADE || DUAL_IMAGE */
794 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr
, bufsize
, os_name
);
796 return ui_docommand(buf
);
800 ui_cmd_clocks(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
802 chipcregs_t
*cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
803 uint32 ccc
= R_REG(NULL
, &cc
->capabilities
);
804 uint32 pll
= ccc
& CC_CAP_PLL_MASK
;
806 if (pll
!= PLL_NONE
) {
807 uint32 n
= R_REG(NULL
, &cc
->clockcontrol_n
);
808 printf("Current clocks for pll=0x%x:\n", pll
);
809 printf(" mips: %d\n", si_clock_rate(pll
, n
, R_REG(NULL
, &cc
->clockcontrol_m3
)));
810 printf(" sb: %d\n", si_clock_rate(pll
, n
, R_REG(NULL
, &cc
->clockcontrol_sb
)));
811 printf(" pci: %d\n", si_clock_rate(pll
, n
, R_REG(NULL
, &cc
->clockcontrol_pci
)));
812 printf(" mipsref: %d\n", si_clock_rate(pll
, n
,
813 R_REG(NULL
, &cc
->clockcontrol_m2
)));
815 printf("Current clocks: %d/%d/%d/%d Mhz.\n",
816 si_cpu_clock(sih
) / 1000000,
817 si_mem_clock(sih
) / 1000000,
818 si_clock(sih
) / 1000000,
819 si_alp_clock(sih
) / 1000000);
825 ui_init_bcm947xxcmds(void)
838 "nvram [command] [args..]\n\n"
840 "get [name];Gets the value of the specified variable|"
841 "set [name=value];Sets the value of the specified variable|"
842 "unset [name];Deletes the specified variable|"
843 "commit;Commit variables to flash|"
844 "corrupt;Corrupt NVRAM -- For testing purposes|"
846 "otpcommit ;Commit otp nvram header to flash"
848 "erase;Erase all nvram|"
849 "show;Shows all variables|");
851 cmd_addcmd("devinfo",
854 "Device Info NVRAM utility.",
855 "devinfo [command] [args..]\n\n"
856 "Access devinfo NVRAM.",
857 "get [name];Gets the value of the specified variable|"
858 "set [name=value];Sets the value of the specified variable|"
859 "unset [name];Deletes the specified variable|"
860 "commit;Commit variables to flash|"
862 "otpcommit ;Commit otp devinfo nvram header to flash"
864 "erase;Erase all devinfo nvram|"
865 "show;Shows all devinfo nvram variables|");
870 "Verify and boot OS image.",
872 "Boots OS image if valid. Waits for a new OS image if image is invalid\n"
873 "or boot_wait is unset or not on.",
875 cmd_addcmd("show clocks",
878 "Show current values of the clocks.",
880 "Shows the current values of the clocks.",