2 * Broadcom Common Firmware Environment (CFE)
3 * Board device initialization, File: ui_bcm947xx.c
5 * Copyright (C) 2011, 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 323091 2012-03-22 23:32:36Z $
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"
39 #include <dmemc_core.h>
40 #include <bcmendian.h>
44 #include "addrspace.h"
50 unsigned char DETECT(void);
53 extern void LEDON(void);
54 extern void LEDOFF(void);
55 extern void GPIO_INIT(void);
56 extern void FANON(void);
59 #define FAN_GPIO (1 << 14) // GPIO 14
60 #define PWR_LED_GPIO (1 << 12) // GPIO 12
61 #define RST_BTN_GPIO (1 << 9) // GPIO 9
62 #define HAVE_FAN_GPIO (1 << 6) // GPIO 6
63 #define EZ_BTN_GPIO (1 << 4) // GPIO 4
67 ui_cmd_reboot(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
75 ui_cmd_nvram(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
77 char *command
, *name
, *value
;
82 if (!(command
= cmd_getarg(cmd
, 0)))
83 return CFE_ERR_INV_PARAM
;
85 if (!strcmp(command
, "get")) {
86 if ((name
= cmd_getarg(cmd
, 1)))
87 if ((value
= nvram_get(name
)))
88 printf("%s\n", value
);
89 } else if (!strcmp(command
, "set")) {
90 if ((name
= cmd_getarg(cmd
, 1))) {
91 if ((value
= strchr(name
, '=')))
93 else if ((value
= cmd_getarg(cmd
, 2))) {
95 value
= cmd_getarg(cmd
, 3);
98 nvram_set(name
, value
);
100 } else if (!strcmp(command
, "unset")) {
101 if ((name
= cmd_getarg(cmd
, 1)))
103 } else if (!strcmp(command
, "commit")) {
105 } else if (!strcmp(command
, "erase")) {
106 extern char *flashdrv_nvram
;
107 if ((ret
= cfe_open(flashdrv_nvram
)) < 0)
109 if (!(buf
= KMALLOC(NVRAM_SPACE
, 0)))
110 return CFE_ERR_NOMEM
;
111 memset(buf
, 0xff, NVRAM_SPACE
);
112 cfe_writeblk(ret
, 0, (unsigned char *)buf
, NVRAM_SPACE
);
115 } else if (!strcmp(command
, "show") || !strcmp(command
, "getall")) {
116 if (!(buf
= KMALLOC(NVRAM_SPACE
, 0)))
117 return CFE_ERR_NOMEM
;
118 nvram_getall(buf
, NVRAM_SPACE
);
119 for (name
= buf
; *name
; name
+= strlen(name
) + 1)
120 printf("%s\n", name
);
121 size
= sizeof(struct nvram_header
) + ((uintptr
)name
- (uintptr
)buf
);
122 printf("size: %d bytes (%d left)\n", size
, NVRAM_SPACE
- size
);
130 check_trx(char *trx_name
)
135 struct trx_header trx
;
138 static uint32 buf
[16*1024];
140 uint32 crc
, buf
[512];
141 #endif /* CFG_NFLASH */
143 unsigned int len
, count
;
146 ret
= fs_init("raw", &fsctx
, trx_name
);
150 ret
= fs_open(fsctx
, &ref
, "", FILE_MODE_READ
);
157 ret
= fs_read(fsctx
, ref
, (unsigned char *) &trx
, sizeof(struct trx_header
));
158 if (ret
!= sizeof(struct trx_header
)) {
163 /* Verify magic number */
164 if (ltoh32(trx
.magic
) != TRX_MAGIC
) {
165 ret
= CFE_ERR_INVBOOTBLOCK
;
169 /* Checksum over header */
170 crc
= hndcrc32((uint8
*) &trx
.flag_version
,
171 sizeof(struct trx_header
) - OFFSETOF(struct trx_header
, flag_version
),
174 for (len
= ltoh32(trx
.len
) - sizeof(struct trx_header
); len
; len
-= count
) {
176 count
= MIN(len
, sizeof(buf
) - sizeof(struct trx_header
));
179 count
= MIN(len
, sizeof(buf
));
182 ret
= fs_read(fsctx
, ref
, (unsigned char *) &buf
, count
);
188 /* Checksum over data */
189 crc
= hndcrc32((uint8
*) &buf
, count
, crc
);
192 /* Verify checksum */
193 if (ltoh32(trx
.crc32
) != crc
) {
194 ret
= CFE_ERR_BOOTPROGCHKSUM
;
201 fs_close(fsctx
, ref
);
204 xprintf("%s\n", cfe_errortext(ret
));
211 unsigned long gpioin
;
213 sih
= si_kattach(SI_OSH
);
215 gpioin
= si_gpioin(sih
);
218 return gpioin
& RST_BTN_GPIO
? FALSE
: TRUE
;
221 bool rmode_set(void) /* reset mode */
223 unsigned long gpioin
;
225 sih
= si_kattach(SI_OSH
);
227 gpioin
= si_gpioin(sih
);
230 return gpioin
& EZ_BTN_GPIO
? FALSE
: TRUE
;
233 extern void LEDON(void)
235 sih
= si_kattach(SI_OSH
);
237 si_gpioouten(sih
, PWR_LED_GPIO
, PWR_LED_GPIO
, GPIO_DRV_PRIORITY
);
240 /* negative logic and hence val==0 */
241 si_gpioout(sih
, PWR_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
243 extern void GPIO_INIT(void)
245 sih
= si_kattach(SI_OSH
);
247 si_gpiocontrol(sih
, PWR_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
248 si_gpioouten(sih
, PWR_LED_GPIO
, 0, GPIO_DRV_PRIORITY
);
249 si_gpiocontrol(sih
, FAN_GPIO
, 0, GPIO_DRV_PRIORITY
);
250 si_gpioouten(sih
, FAN_GPIO
, 0, GPIO_DRV_PRIORITY
);
251 si_gpiocontrol(sih
, HAVE_FAN_GPIO
, 0, GPIO_DRV_PRIORITY
);
252 si_gpioouten(sih
, HAVE_FAN_GPIO
, 0, GPIO_DRV_PRIORITY
);
255 extern void LEDOFF(void)
257 sih
= si_kattach(SI_OSH
);
259 si_gpioouten(sih
, PWR_LED_GPIO
, PWR_LED_GPIO
, GPIO_DRV_PRIORITY
);
260 si_gpioout(sih
, PWR_LED_GPIO
, PWR_LED_GPIO
, GPIO_DRV_PRIORITY
);
263 extern void FANON(void)
265 sih
= si_kattach(SI_OSH
);
267 si_gpioouten(sih
, FAN_GPIO
, FAN_GPIO
, GPIO_DRV_PRIORITY
);
268 si_gpioout(sih
, FAN_GPIO
, 0, GPIO_DRV_PRIORITY
);
269 si_gpioouten(sih
, HAVE_FAN_GPIO
, HAVE_FAN_GPIO
, GPIO_DRV_PRIORITY
);
270 si_gpioout(sih
, HAVE_FAN_GPIO
, 0, GPIO_DRV_PRIORITY
);
272 unsigned char DETECT(void)
277 if ((rescueflag
= nvram_get("rescueflag")) != NULL
) {
278 if (!nvram_invmatch("rescueflag", "enable")) {
279 xprintf("Rescue Flag enable.\n");
283 xprintf("Rescue Flag disable.\n");
289 nvram_set("rescueflag", "disable");
293 xprintf("Null Rescue Flag.\n");
300 /* Set 1 to be high active and 0 to be low active */
306 #endif // RESCUE_MODE
309 * ui_get_loadbuf(bufptr, bufsize)
311 * Figure out the location and size of the staging buffer.
314 * bufptr - address to return buffer location
315 * bufsize - address to return buffer size
317 static void ui_get_loadbuf(uint8_t **bufptr
, int *bufsize
)
319 int size
= CFG_FLASH_STAGING_BUFFER_SIZE
;
322 * Get the address of the staging buffer. We can't
323 * allocate the space from the heap to store the
324 * new flash image, because the heap may not be big
325 * enough. So, if FLASH_STAGING_BUFFER_SIZE is non-zero
326 * then just use it and FLASH_STAGING_BUFFER; else
327 * use the larger of (mem_bottomofmem - FLASH_STAGING_BUFFER)
328 * and (mem_totalsize - mem_topofmem).
332 *bufptr
= (uint8_t *) KERNADDR(CFG_FLASH_STAGING_BUFFER_ADDR
);
336 int reserved
= CFG_FLASH_STAGING_BUFFER_ADDR
;
338 /* For small memory size (8MB), we tend to use the below region.
339 * The buffer address may conflict with the os running address,
340 * so we reserve 3MB for the os.
342 if ((mem_totalsize
== (8*1024)) && (PHYSADDR(mem_bottomofmem
) > 0x300000))
345 below
= PHYSADDR(mem_bottomofmem
) - reserved
;
346 above
= (mem_totalsize
<< 10) - PHYSADDR(mem_topofmem
);
349 *bufptr
= (uint8_t *) KERNADDR(reserved
);
352 *bufptr
= (uint8_t *) KERNADDR(mem_topofmem
);
358 #if defined(DUAL_IMAGE) || defined(FAILSAFE_UPGRADE)
360 int check_image_prepare_cmd(int the_image
, char *buf
, uint32 osaddr
, int bufsize
)
363 char trx_name
[16], os_name
[16];
364 char trx2_name
[16], os2_name
[16];
367 ui_get_trx_flashdev(trx_name
);
368 ui_get_os_flashdev(os_name
);
370 strcpy(trx_name
, "flash1.trx");
371 strcpy(os_name
, "flash0.os");
374 strncpy (trx2_name
,trx_name
,sizeof(trx2_name
));
375 strncpy (os2_name
,os_name
,sizeof(os2_name
));
376 strcat (trx2_name
, "2");
377 strcat (os2_name
, "2");
379 if (the_image
== 0) {
380 if ((ret
= check_trx(trx_name
)) == 0) {
381 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr
, bufsize
,
384 printf("%s CRC check failed!\n", trx_name
);
386 } else if (the_image
== 1) {
387 if ((ret
= check_trx(trx2_name
)) == 0) {
388 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr
, bufsize
,
391 printf("%s CRC check failed!\n", trx2_name
);
394 printf("Image partition %d does not exist\n", the_image
);
398 #endif /* DUAL_IMAGE || FAILSAFE_UPGRADE */
401 static int ui_get_bootflags(void)
406 /* Only support chipcommon revision == 38 and BCM4706 for now */
407 if (((CHIPID(sih
->chip
) == BCM4706_CHIP_ID
) || sih
->ccrev
== 38) &&
408 (sih
->cccaps
& CC_CAP_NFLASH
)) {
409 if ((val
= nvram_get("bootflags")))
410 bootflags
= atoi(val
);
411 else if ((sih
->chipst
& (1 << 4)) != 0) {
412 /* This is NANDBOOT */
413 bootflags
= FLASH_KERNEL_NFLASH
| FLASH_BOOT_NFLASH
;
419 void ui_get_boot_flashdev(char *flashdev
)
423 if ((ui_get_bootflags() & FLASH_BOOT_NFLASH
) == FLASH_BOOT_NFLASH
)
424 strcpy(flashdev
, "nflash1.boot");
426 strcpy(flashdev
, "flash1.boot");
431 void ui_get_os_flashdev(char *flashdev
)
435 if ((ui_get_bootflags() & FLASH_KERNEL_NFLASH
) == FLASH_KERNEL_NFLASH
)
436 strcpy(flashdev
, "nflash0.os");
438 strcpy(flashdev
, "flash0.os");
443 void ui_get_trx_flashdev(char *flashdev
)
447 if ((ui_get_bootflags() & FLASH_KERNEL_NFLASH
) == FLASH_KERNEL_NFLASH
)
448 strcpy(flashdev
, "nflash1.trx");
450 strcpy(flashdev
, "flash1.trx");
453 #endif /* CFG_NFLASH */
456 ui_cmd_go(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
460 struct trx_header
*file_buf
;
473 #ifdef FAILSAFE_UPGRADE
474 char *bootpartition
= nvram_get(BOOTPARTITION
);
475 char *partialboots
= nvram_get(PARTIALBOOTS
);
476 char *maxpartialboots
= nvram_get(MAXPARTIALBOOTS
);
479 char *bootpartition
= nvram_get(IMAGE_BOOT
);
482 char trx_name
[16], os_name
[16];
484 char *trx_name
= "flash1.trx";
485 char *os_name
= "flash0.os";
486 #endif /* CFG_NFLASH */
488 val
= nvram_get("os_ram_addr");
490 osaddr
= bcm_strtoul(val
, NULL
, 16);
495 //trx_name = "nflash1.trx";
496 strcpy(trx_name
, "nflash1.trx");
497 strcpy(os_name
, "nflash0.os");
500 xprintf("Hello!! Enter Rescue Mode: (by Force)\n\n");
501 /* Wait forever for an image */
502 while ((ret
= ui_docommand("flash -noheader : nflash1.trx")) == CFE_ERR_TIMEOUT
) {
513 else if (rmode_set()) {
514 xprintf("Wait until reset button released...\n");
515 while(rmode_set() == 1) {
516 if ((i
%100000) < 50000) {
528 ui_docommand ("nvram erase");
529 ui_docommand ("reboot");
532 xprintf("boot the image...\n"); // tmp test
534 if (check_trx(trx_name
)) {
535 xprintf("Hello!! Enter Rescue Mode: (Check error)\n\n");
536 /* Wait forever for an image */
537 while ((ret
= ui_docommand("flash -noheader : nflash1.trx")) == CFE_ERR_TIMEOUT
) {
546 } else if (!nvram_invmatch("boot_wait", "on")) {
547 xprintf("go load\n"); // tmp test
548 ui_get_loadbuf(&ptr
, &bufsize
);
550 sprintf(buf
, "load -raw -addr=0x%x -max=0x%x :", (unsigned int)ptr
, (unsigned int)TRX_MAX_LEN
);
551 ret
= ui_docommand(buf
);
553 /* Load was successful. Check for the TRX magic.
554 * If it's a TRX image, then proceed to flash it, else try to boot
555 * Note: To boot a TRX image directly from the memory, address will need to be
556 * load address + trx header length.
559 file_buf
= (struct trx_header
*)ptr
;
560 /* If it's a TRX, then proceed to writing to flash else,
561 * try to boot from memory
563 if (file_buf
->magic
!= TRX_MAGIC
) {
564 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x -fs=memory :0x%x",
565 osaddr
, (unsigned int)bufsize
, (unsigned int)ptr
);
566 return ui_docommand(buf
);
568 /* Flash the image from memory directly */
569 sprintf(buf
, "flash -noheader -mem -size=0x%x 0x%x nflash1.trx",
570 (unsigned int)file_buf
->len
, (unsigned int)ptr
);
571 ret
= ui_docommand(buf
);
578 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
579 if (bootpartition
!= NULL
) {
581 ui_get_trx_flashdev(trx_name
);
583 trx_failed
= check_trx(trx_name
);
585 strcat(trx_name
,"2");
587 trx_failed
&= check_trx(trx_name
);
589 #endif /* FAILSAFE_UPGRADE || DUAL_IMAGE*/
592 ui_get_trx_flashdev(trx_name
);
593 ui_get_os_flashdev(os_name
);
595 trx_failed
= check_trx(trx_name
);
599 /* Wait for CFE_ERR_TIMEOUT_LIMIT for an image */
601 sprintf(buf
, "flash -noheader :%s", trx_name
);
602 if ((ret
= ui_docommand(buf
)) != CFE_ERR_TIMEOUT
)
604 if (++retry
== CFE_ERR_TIMEOUT_LIMIT
) {
609 } else if (!nvram_invmatch("boot_wait", "on")) {
610 ui_get_loadbuf(&ptr
, &bufsize
);
612 sprintf(buf
, "load -raw -addr=0x%p -max=0x%x :", ptr
, bufsize
);
613 ret
= ui_docommand(buf
);
615 /* Load was successful. Check for the TRX magic.
616 * If it's a TRX image, then proceed to flash it, else try to boot
617 * Note: To boot a TRX image directly from the memory, address will need to be
618 * load address + trx header length.
621 file_buf
= (struct trx_header
*)ptr
;
622 /* If it's a TRX, then proceed to writing to flash else,
623 * try to boot from memory
625 if (file_buf
->magic
!= TRX_MAGIC
) {
626 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x -fs=memory :0x%p",
627 osaddr
, bufsize
, ptr
);
628 return ui_docommand(buf
);
630 /* Flash the image from memory directly */
631 sprintf(buf
, "flash -noheader -mem -size=0x%x 0x%p %s",
632 file_buf
->len
, ptr
, trx_name
);
633 ret
= ui_docommand(buf
);
636 #endif // RESCUE_MODE
638 if (ret
== CFE_ERR_INTR
)
641 bufsize
= PHYSADDR(mem_bottomofmem
) - PHYSADDR(osaddr
);
643 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
644 /* Get linux_boot variable to see what is current image */
645 if (bootpartition
!= NULL
) {
647 int i
= atoi(bootpartition
);
648 #ifdef FAILSAFE_UPGRADE
649 if (maxpartialboots
&& (atoi(maxpartialboots
) > 0)) {
650 if (partialboots
&& (atoi(partialboots
) > atoi(maxpartialboots
))) {
652 printf("Changed to the other image %d (maxpartialboots exceeded)\n", i
);
653 /* reset to new image */
654 sprintf(temp
, "%d", i
);
655 nvram_set(PARTIALBOOTS
, "1");
656 nvram_set(BOOTPARTITION
, temp
);
659 /* Increment the counter */
660 sprintf(temp
,"%d",partialboots
? atoi(partialboots
)+1:1);
661 nvram_set(PARTIALBOOTS
, temp
);
669 /* We try the specified one, if it is failed, we try the other one */
670 if (check_image_prepare_cmd(i
, buf
, osaddr
, bufsize
) == 0) {
671 printf("Booting(%d): %s\n",i
,buf
);
672 } else if (check_image_prepare_cmd(1-i
, buf
, osaddr
, bufsize
) == 0) {
673 printf("Changed to the other image %d\n", 1 - i
);
674 sprintf(temp
, "%d", 1-i
);
675 nvram_set(BOOTPARTITION
, temp
);
676 #ifdef FAILSAFE_UPGRADE
677 nvram_set(PARTIALBOOTS
, "1");
681 printf ("Both images bad!!!\n");
686 #endif /* FAILSAFE_UPGRADE || DUAL_IMAGE */
687 sprintf(buf
, "boot -raw -z -addr=0x%x -max=0x%x %s:", osaddr
, bufsize
, os_name
);
689 return ui_docommand(buf
);
693 ui_cmd_clocks(ui_cmdline_t
*cmd
, int argc
, char *argv
[])
695 chipcregs_t
*cc
= (chipcregs_t
*)si_setcoreidx(sih
, SI_CC_IDX
);
696 uint32 ccc
= R_REG(NULL
, &cc
->capabilities
);
697 uint32 pll
= ccc
& CC_CAP_PLL_MASK
;
699 if (pll
!= PLL_NONE
) {
700 uint32 n
= R_REG(NULL
, &cc
->clockcontrol_n
);
701 printf("Current clocks for pll=0x%x:\n", pll
);
702 printf(" mips: %d\n", si_clock_rate(pll
, n
, R_REG(NULL
, &cc
->clockcontrol_m3
)));
703 printf(" sb: %d\n", si_clock_rate(pll
, n
, R_REG(NULL
, &cc
->clockcontrol_sb
)));
704 printf(" pci: %d\n", si_clock_rate(pll
, n
, R_REG(NULL
, &cc
->clockcontrol_pci
)));
705 printf(" mipsref: %d\n", si_clock_rate(pll
, n
,
706 R_REG(NULL
, &cc
->clockcontrol_m2
)));
708 printf("Current clocks: %d/%d/%d/%d Mhz.\n",
709 si_cpu_clock(sih
) / 1000000,
710 si_mem_clock(sih
) / 1000000,
711 si_clock(sih
) / 1000000,
712 si_alp_clock(sih
) / 1000000);
718 extern int ui_init_devcmds(void); // J++
721 ui_init_bcm947xxcmds(void)
734 "nvram [command] [args..]\n\n"
736 "get [name];Gets the value of the specified variable|"
737 "set [name=value];Sets the value of the specified variable|"
738 "unset [name];Deletes the specified variable|"
739 "commit;Commit variables to flash|"
740 "erase;Erase all nvram|"
741 "show;Shows all variables|");
745 "Verify and boot OS image.",
747 "Boots OS image if valid. Waits for a new OS image if image is invalid\n"
748 "or boot_wait is unset or not on.",
750 cmd_addcmd("show clocks",
753 "Show current values of the clocks.",
755 "Shows the current values of the clocks.",
758 ui_init_devcmds(); // J++