1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * 5 * bcm63xx board specific routines and commands. 6 * 7 * by: seanl 8 * 9 * April 1, 2002 10 * 11 ********************************************************************* 12 * 13 * Copyright 2000,2001,2002,2003 14 * Broadcom Corporation. All rights reserved. 15 * 16 * This software is furnished under license and may be used and 17 * copied only in accordance with the following terms and 18 * conditions. Subject to these conditions, you may download, 19 * copy, install, use, modify and distribute modified or unmodified 20 * copies of this software in source and/or binary form. No title 21 * or ownership is transferred hereby. 22 * 23 * 1) Any source code used, modified or distributed must reproduce 24 * and retain this copyright notice and list of conditions 25 * as they appear in the source file. 26 * 27 * 2) No right is granted to use any trade name, trademark, or 28 * logo of Broadcom Corporation. The "Broadcom Corporation" 29 * name may not be used to endorse or promote products derived 30 * from this software without the prior written permission of 31 * Broadcom Corporation. 32 * 33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 45 * THE POSSIBILITY OF SUCH DAMAGE. 46 ********************************************************************* */ 47 48 49#include "bcm63xx_util.h" 50 51#define ENTRY_POINT 0x80010470 52#define CODE_ADDRESS 0x80010000 53#define FLASH_STAGING_BUFFER (1024*1024) /* 1MB line */ 54#define FLASH_STAGING_BUFFER_SIZE (4 * 1024 *1024 + TAG_LEN) // 4 MB for now 55 56extern PFILE_TAG kerSysImageTagGet(void); 57extern NVRAM_DATA nvramData; 58 59static int ui_cmd_set_board_param(ui_cmdline_t *cmd,int argc,char *argv[]) 60{ 61 return(setBoardParam()); 62} 63 64 65 66static int ui_cmd_reset(ui_cmdline_t *cmd,int argc,char *argv[]) 67{ 68 kerSysMipsSoftReset(); 69 70 return 0; 71} 72 73 74// return 0 if 'y' 75int yesno(void) 76{ 77 char ans[5]; 78 79 printf(" (y/n):"); 80 console_readline ("", ans, sizeof (ans)); 81 if (ans[0] != 'y') 82 return -1; 83 84 return 0; 85} 86 87 88// erase Persistent sector 89static int ui_cmd_erase_psi(ui_cmdline_t *cmd,int argc,char *argv[]) 90{ 91 printf("Erase persisten storage data?"); 92 if (yesno()) 93 return -1; 94 95 kerSysErasePsi(); 96 97 return 0; 98} 99 100 101 102// erase some sectors 103static int ui_cmd_erase(ui_cmdline_t *cmd,int argc,char *argv[]) 104{ 105 106 //FILE_TAG cfeTag; 107 PFILE_TAG pTag; 108 char *flag; 109 int i, blk_start, blk_end; 110 111 flag = cmd_getarg(cmd,0); 112 113 if (!flag) 114 { 115 printf("Erase [n]vram or [a]ll flash except bootrom; usage: e [n/a]\n"); 116 return 0; 117 } 118 119 switch (*flag) 120 { 121 case 'b': 122 printf("Erase boot loader?"); 123 if (yesno()) 124 return 0; 125 printf("\nNow think carefully. Do you really,\n" 126 "really want to erase the boot loader?"); 127 if (yesno()) 128 return 0; 129 flash_sector_erase_int(0); 130 break; 131 case 'n': 132 printf("Erase nvram?"); 133 if (yesno()) 134 return 0; 135 kerSysEraseNvRam(); 136 break; 137 case 'a': 138 printf("Erase all flash (except bootrom)?"); 139 if (yesno()) 140 return 0; 141 142 if ((pTag = kerSysImageTagGet()) != NULL) 143 blk_start = flash_get_blk( atoi(pTag->rootfsAddress) ); 144 else // just erase all after cfe 145 { 146 blk_start = FLASH45_BLKS_BOOT_ROM; 147 printf("No image tag found. Erase the blocks start at [%d]\n", blk_start); 148 } 149 blk_end = flash_get_numsectors(); 150 if( blk_start > 0 ) 151 { 152 for (i = blk_start; i < blk_end; i++) 153 { 154 printf("."); 155 flash_sector_erase_int(i); 156 } 157 } 158 printf( "\nResetting board...\n" ); 159 kerSysMipsSoftReset(); 160 break; 161 default: 162 printf("Erase [n]vram or [a]ll flash except bootrom; usage: e [n/a]\n"); 163 return 0; 164 } 165 166 flash_reset(); 167 168 return 0; 169} 170 171 172 173// flash the image 174static int ui_cmd_flash_image(ui_cmdline_t *cmd,int argc,char *argv[]) 175{ 176 char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; 177 char *imageName; 178 uint8_t *ptr; 179 cfe_loadargs_t la; 180 int res; 181 182 imageName = cmd_getarg(cmd, 0); 183 184 if (imageName) 185 { 186 if (strchr(imageName, ':')) 187 strcpy(hostImageName, imageName); 188 else 189 { 190 strcpy(hostImageName, bootInfo.hostIp); 191 strcat(hostImageName, ":"); 192 strcat(hostImageName, imageName); 193 } 194 } 195 else // use default flash file name 196 { 197 strcpy(hostImageName, bootInfo.hostIp); 198 strcat(hostImageName, ":"); 199 strcat(hostImageName, bootInfo.flashFileName); 200 } 201 202 printf("Loading %s ...\n", hostImageName); 203 204 ptr = (uint8_t *) PHYS_TO_K0(FLASH_STAGING_BUFFER); 205 206 // tftp only 207 la.la_filesys = "tftp"; 208 la.la_filename = hostImageName; 209 la.la_device = NULL; 210 la.la_address = (intptr_t) ptr; 211 la.la_options = 0; 212 la.la_maxsize = FLASH_STAGING_BUFFER_SIZE; 213 la.la_flags = LOADFLG_SPECADDR; 214 215 res = cfe_load_program("raw", &la); 216 if (res < 0) 217 { 218 ui_showerror(res, "Loading failed."); 219 return res; 220 } 221 printf("Finished loading %d bytes\n", res); 222 223 // check and flash image 224 res = flashImage(ptr); 225 226 if( res == 0 ) 227 { 228 char *p; 229 230 for( p = nvramData.szBootline; p[2] != '\0'; p++ ) 231 if( p[0] == 'r' && p[1] == '=' && p[2] == 'h' ) 232 { 233 /* Change boot source to "boot from flash". */ 234 p[2] = 'f'; 235 writeNvramData(); 236 break; 237 } 238 printf( "Resetting board...\n" ); 239 kerSysMipsSoftReset(); 240 } 241 242 return( res ); 243} 244 245 246// write the whole image 247static int ui_cmd_write_whole_image(ui_cmdline_t *cmd,int argc,char *argv[]) 248{ 249 char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; 250 char *imageName; 251 uint8_t *ptr; 252 cfe_loadargs_t la; 253 int res; 254 255 imageName = cmd_getarg(cmd, 0); 256 if (!imageName) 257 return ui_showusage(cmd); 258 259 if (strchr(imageName, ':')) 260 strcpy(hostImageName, imageName); 261 else 262 { 263 strcpy(hostImageName, bootInfo.hostIp); 264 strcat(hostImageName, ":"); 265 strcat(hostImageName, imageName); 266 } 267 268 printf("Loading %s ...\n", hostImageName); 269 270 ptr = (uint8_t *) PHYS_TO_K0(FLASH_STAGING_BUFFER); 271 272 // tftp only 273 la.la_filesys = "tftp"; 274 la.la_filename = hostImageName; 275 la.la_device = NULL; 276 la.la_address = (intptr_t) ptr; 277 la.la_options = 0; 278 la.la_maxsize = FLASH_STAGING_BUFFER_SIZE; 279 la.la_flags = LOADFLG_SPECADDR; 280 281 res = cfe_load_program("raw", &la); 282 if (res < 0) 283 { 284 ui_showerror(res, "Loading failed."); 285 return res; 286 } 287 printf("Finished loading %d bytes\n", res); 288 289 // check and flash image 290 res = writeWholeImage(ptr, res); 291 292 printf("Finished flashing image. return = %d\n", res); 293 294 if (res == 0) 295 { 296 printf( "Resetting board...\n" ); 297 kerSysMipsSoftReset(); 298 } 299 300 return( res ); 301} 302 303// Used to flash an RTEMS image. Only works on BCM96345 with top boot flash part. 304static int ui_cmd_flash_router_image(ui_cmdline_t *cmd,int argc,char *argv[]) 305{ 306 char hostImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; 307 char *imageName; 308 uint8_t *ptr; 309 cfe_loadargs_t la; 310 int res; 311 312 imageName = cmd_getarg(cmd, 0); 313 if (!imageName) 314 return ui_showusage(cmd); 315 316 if (strchr(imageName, ':')) 317 strcpy(hostImageName, imageName); 318 else 319 { 320 strcpy(hostImageName, bootInfo.hostIp); 321 strcat(hostImageName, ":"); 322 strcat(hostImageName, imageName); 323 } 324 325 printf("Loading %s ...\n", hostImageName); 326 327 ptr = (uint8_t *) PHYS_TO_K0(FLASH_STAGING_BUFFER); 328 329 // tftp only 330 la.la_filesys = "tftp"; 331 la.la_filename = hostImageName; 332 la.la_device = NULL; 333 la.la_address = (intptr_t) ptr; 334 la.la_options = 0; 335 la.la_maxsize = FLASH_STAGING_BUFFER_SIZE; 336 la.la_flags = LOADFLG_SPECADDR; 337 338 res = cfe_load_program("raw", &la); 339 if (res < 0) 340 { 341 ui_showerror(res, "Loading failed."); 342 return res; 343 } 344 printf("Finished loading %d bytes\n", res); 345 346 // check and flash image 347 if ((res = kerSysBcmImageSet(FLASH45_IMAGE_START_ADDR, ptr, res, 1)) != 0) 348 printf("Failed to flash image. Error: %d\n", res); 349 else 350 printf("Finished flashing image.\n"); 351 352 if (res == 0) 353 { 354 char *p; 355 356 for( p = nvramData.szBootline; p[2] != '\0'; p++ ) 357 if( p[0] == 'r' && p[1] == '=' && p[2] == 'h' ) 358 { 359 /* Change boot source to "boot from flash". */ 360 p[2] = 'f'; 361 writeNvramData(); 362 break; 363 } 364 printf( "Resetting board...\n" ); 365 kerSysMipsSoftReset(); 366 } 367 368 return( res ); 369} 370 371static int autoRun(char *imageName) 372{ 373 char runCmd[BOOT_FILENAME_LEN + BOOT_IP_LEN + 20], ipImageName[BOOT_FILENAME_LEN + BOOT_IP_LEN]; 374 int ret; 375 376 377 if (bootInfo.runFrom == 'f' && !imageName) 378 { 379 strcpy(runCmd, "boot -elf -z -rawfs flash1:"); 380 ret = ui_docommand(runCmd); 381 } 382 else // loading from host 383 { 384 if (imageName) 385 { 386 if (strchr(imageName, ':')) 387 strcpy(ipImageName, imageName); 388 else 389 { 390 strcpy(ipImageName, bootInfo.hostIp); 391 strcat(ipImageName, ":"); 392 strcat(ipImageName, imageName); 393 } 394 } 395 else // use default host file name 396 { 397 strcpy(ipImageName, bootInfo.hostIp); 398 strcat(ipImageName, ":"); 399 strcat(ipImageName, bootInfo.hostFileName); 400 } 401 402 // try uncompressed image first 403 strcpy(runCmd, "boot -elf "); 404 strcat(runCmd, ipImageName); 405 406 ret = ui_docommand(runCmd); 407 408 if( ret == CFE_ERR_NOTELF ) 409 { 410 // next try as a compressed image 411 printf("Retry loading it as a compressed image.\n"); 412 strcpy(runCmd, "boot -elf -z "); 413 strcat(runCmd, ipImageName); 414 ret = ui_docommand(runCmd); 415 } 416 } 417 418 return ret; 419} 420 421 422// run program from compressed image in flash or from tftped program from host 423static int ui_cmd_run_program(ui_cmdline_t *cmd,int argc,char *argv[]) 424{ 425 char *imageName; 426 427 imageName = cmd_getarg(cmd, 0); 428 429 return autoRun(imageName); 430} 431 432 433static int ui_cmd_print_system_info(ui_cmdline_t *cmd,int argc,char *argv[]) 434{ 435 return printSysInfo(); 436} 437 438 439static int ui_cmd_change_bootline(ui_cmdline_t *cmd,int argc,char *argv[]) 440{ 441 return changeBootLine(); 442} 443 444 445static int ui_init_bcm6345_cmds(void) 446{ 447 448 // Used to flash an RTEMS image. 449 cmd_addcmd("flashimage", 450 ui_cmd_flash_router_image, 451 NULL, 452 "Flashes a compressed image after the bootloader.", 453 "eg. flashimage [hostip:]compressed_image_file_name", 454 ""); 455 456 cmd_addcmd("reset", 457 ui_cmd_reset, 458 NULL, 459 "Reset the board", 460 "", 461 ""); 462 463 cmd_addcmd("b", 464 ui_cmd_set_board_param, 465 NULL, 466 "Change board parameters", 467 "", 468 ""); 469 470 cmd_addcmd("i", 471 ui_cmd_erase_psi, 472 NULL, 473 "Erase persistent storage data", 474 "", 475 ""); 476 477 cmd_addcmd("f", 478 ui_cmd_flash_image, 479 NULL, 480 "Write image to the flash ", 481 "eg. f [[hostip:]filename]<cr> -- if no filename, tftped from host with file name in 'Default host flash file name'", 482 ""); 483 484 cmd_addcmd("c", 485 ui_cmd_change_bootline, 486 NULL, 487 "Change booline parameters", 488 "", 489 ""); 490 491 cmd_addcmd("p", 492 ui_cmd_print_system_info, 493 NULL, 494 "Print boot line and board parameter info", 495 "", 496 ""); 497 498 cmd_addcmd("r", 499 ui_cmd_run_program, 500 NULL, 501 "Run program from flash image or from host depend on [f/h] flag", 502 "eg. r [[hostip:]filenaem]<cr> if no filename, use the file name in 'Default host run file name'", 503 ""); 504 505 cmd_addcmd("e", 506 ui_cmd_erase, 507 NULL, 508 "Erase [n]vram or [a]ll flash except bootrom", 509 "e [n/a]", 510 ""); 511 512 cmd_addcmd("w", 513 ui_cmd_write_whole_image, 514 NULL, 515 "Write the whole image start from beginning of the flash", 516 "eg. w [hostip:]whole_image_file_name", 517 ""); 518 519 return 0; 520} 521 522 523static int runDelay(int delayCount) 524{ 525 int goAuot = 0; 526 527 if (delayCount == 0) 528 return goAuot; 529 530 printf("*** Press any key to stop auto run (%d seconds) ***\n", delayCount); 531 printf("Auto run second count down: %d", delayCount); 532 533 cfe_sleep(CFE_HZ/8); // about 1/4 second 534 535 while (1) 536 { 537 printf("\b%d", delayCount); 538 cfe_sleep(CFE_HZ/2); // about 1 second 539 if (console_status()) 540 break;; 541 if (--delayCount == 0) 542 { 543 goAuot = 1; 544 break; 545 } 546 } 547 printf("\b%d\n", delayCount); 548 549 return goAuot; 550} 551 552 553void bcm63xx_run(void) 554{ 555 ui_init_bcm6345_cmds(); 556 printSysInfo(); 557 enet_init(); 558 if (runDelay(bootInfo.bootDelay)) 559 autoRun(NULL); // never returns 560} 561