1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * bcm63xx utility functions
6 * Created on : 04/18/2002 seanl
8 *********************************************************************
12 Copyright (c) 2002 Broadcom Corporation
14 No portions of this material may be reproduced in any form without the
15 written permission of:
18 Irvine, California 92619
19 All information contained in this document is Broadcom Corporation
20 company private, proprietary, and trade secret.
25 #define BCMTAG_EXE_USE
26 #include "bcm63xx_util.h"
28 extern const char *get_system_type(void);
29 extern int readNvramData(void);
31 int changeBootLine(void);
35 static int parseFilename(char *fn
)
37 if (strlen(fn
) < BOOT_FILENAME_LEN
)
43 static int parseChoiceFh(char *choice
)
46 if (*choice
== 'f' || *choice
== 'h')
53 static int parseChoice09(char *choice
)
55 int bChoice
= *choice
- '0';
57 if (bChoice
>= 0 && bChoice
<= 9)
63 static int parseIpAddr(char *ipStr
);
65 static PARAMETER_SETTING gBootParam
[] =
67 // prompt name Error Prompt Boot Define Boot Param Validation function
68 {"Board IP address :", IP_PROMPT
, "e=", "", parseIpAddr
},
69 {"Host IP address :", IP_PROMPT
, "h=", "", parseIpAddr
},
70 {"Gateway IP address :", IP_PROMPT
, "g=", "", parseIpAddr
},
71 {"Run from flash/host (f/h) :", RUN_FROM_PROMPT
, "r=", "", parseChoiceFh
},
72 {"Default host run file name :", HOST_FN_PROMPT
, "f=", "", parseFilename
},
73 {"Default host flash file name :", FLASH_FN_PROMPT
, "i=", "", parseFilename
},
74 {"Boot delay (0-9 seconds) :", BOOT_DELAY_PROMPT
,"d=", "", parseChoice09
},
79 static const char hextable
[16] = "0123456789ABCDEF";
80 void dumpHex(unsigned char *start
, int len
)
82 unsigned char *ptr
= start
,
87 long offset
= ptr
- start
;
88 unsigned char text
[120],
90 while (ptr
< end
&& p
< &text
[16 * 3])
92 *p
++ = hextable
[*ptr
>> 4];
93 *p
++ = hextable
[*ptr
++ & 0xF];
97 printf("%4lX %s\n", offset
, text
);
103 static int parsexdigit(char str
)
107 if ((str
>= '0') && (str
<= '9'))
109 else if ((str
>= 'a') && (str
<= 'f'))
110 digit
= str
- 'a' + 10;
111 else if ((str
>= 'A') && (str
<= 'F'))
112 digit
= str
- 'A' + 10;
120 // convert in = fffffff00 to out=255.255.255.0
121 // return 0 = OK, 1 failed.
122 static int convertMaskStr(char *in
, char *out
)
127 char mask
[BOOT_IP_LEN
];
129 if (strlen(in
) != MASK_LEN
) // mask len has to 8
132 memset(twoHex
, 0, 2);
133 for (i
= 0; i
< 4; i
++)
135 twoHex
[0] = (uint8_t)*in
++;
136 twoHex
[1] = (uint8_t)*in
++;
137 if (parsexdigit(*twoHex
) == -1)
139 dest
[i
] = (uint8_t) xtoi(twoHex
);
141 sprintf(mask
, "%d.%d.%d.%d", dest
[0], dest
[1], dest
[2], dest
[3]);
146 // return 0 - OK, !0 - Bad ip
147 static int parseIpAddr(char *ipStr
)
151 char mask
[BOOT_IP_LEN
];
152 char ipMaskStr
[2*BOOT_IP_LEN
];
154 strcpy(ipMaskStr
, ipStr
);
156 x
= strchr(ipMaskStr
,':');
158 return parseipaddr(ipMaskStr
, dest
);
162 if (parseipaddr(ipMaskStr
, dest
)) // ipStr is not ok
166 return convertMaskStr(x
, mask
); // mask is not used here
171 int parsehwaddr(unsigned char *str
,uint8_t *hwaddr
)
176 if (strlen(str
) != MAX_MAC_STR_LEN
-2)
178 if (*(str
+2) != ':' || *(str
+5) != ':' || *(str
+8) != ':' || *(str
+11) != ':' || *(str
+14) != ':')
181 while (*str
&& (idx
> 0)) {
182 digit1
= parsexdigit(*str
);
194 digit2
= parsexdigit(*str
);
200 *hwaddr
++ = (digit1
<< 4) | digit2
;
210 int parseMacAddr(char * macStr
)
212 unsigned char tmpBuf
[MAX_PROMPT_LEN
];
214 return (parsehwaddr(macStr
, tmpBuf
));
218 int parseBoardIdStr(char *boardIdStr
)
220 if (strlen(boardIdStr
) > 0 && strlen(boardIdStr
) <= NVRAM_BOARD_ID_STRING_LEN
)
227 int parseMacAddrCount(char *ctStr
)
229 int count
= atoi(ctStr
);
231 if (count
>= 1 && count
<= NVRAM_MAC_COUNT_MAX
)
238 //**************************************************************************
239 // Function Name: macNumToStr
240 // Description : convert MAC address from array of 6 bytes to string.
241 // Ex: 0a0b0c0d0e0f -> 0a:0b:0c:0d:0e:0f
243 //**************************************************************************
244 int macNumToStr(unsigned char *macAddr
, unsigned char *str
)
246 if (macAddr
== NULL
|| str
== NULL
)
249 sprintf(str
, "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x",
250 macAddr
[0], macAddr
[1], macAddr
[2],
251 macAddr
[3], macAddr
[4], macAddr
[5]);
260 unsigned char macAddr
[ETH_ALEN
];
261 char macStr
[MAX_MAC_STR_LEN
];
263 strcpy(ethCmd
, "ifconfig eth0 -addr=");
265 if (strlen(bootInfo
.boardIp
) > 0)
266 strcat(ethCmd
, bootInfo
.boardIp
);
268 strcat(ethCmd
, DEFAULT_BOARD_IP
); // provide a default t ip
270 strcat(ethCmd
, " -mask=");
271 if (strlen(bootInfo
.boardMask
) > 0)
272 strcat(ethCmd
, bootInfo
.boardMask
);
274 strcat(ethCmd
, DEFAULT_MASK
);
276 if (strlen(bootInfo
.gatewayIp
) > 0) // optional
278 strcat(ethCmd
, " -gw=");
279 strcat(ethCmd
, bootInfo
.gatewayIp
);
282 memcpy(macAddr
, nvramData
.ucaBaseMacAddr
, ETH_ALEN
);
283 memset(macStr
, 0, MAX_MAC_STR_LEN
);
284 macNumToStr(macAddr
, macStr
);
286 strcat(ethCmd
, " -hwaddr=");
287 strcat(ethCmd
, macStr
);
289 ui_docommand(ethCmd
);
293 /***************************************************************************
294 // Function Name: getCrc32
295 // Description : caculate the CRC 32 of the given data.
296 // Parameters : pdata - array of data.
297 // size - number of input data bytes.
298 // crc - either CRC32_INIT_VALUE or previous return value.
300 ****************************************************************************/
301 UINT32
getCrc32(byte
*pdata
, UINT32 size
, UINT32 crc
)
304 crc
= (crc
>> 8) ^ Crc32_table
[(crc
^ *pdata
++) & 0xff];
313 int flashImage(uint8_t *imagePtr
)
316 FLASH_ADDR_INFO info
;
317 PFILE_TAG pTag
= (PFILE_TAG
) imagePtr
;
318 int totalImageSize
= 0;
319 int cfeSize
, rootfsSize
, kernelSize
;
320 int cfeAddr
, rootfsAddr
, kernelAddr
;
325 kerSysFlashAddrInfoGet( &info
);
327 if( strcmp( pTag
->tagVersion
, BCM_TAG_VER
) )
329 printf("File tag version %s is not supported. Version %s must be used.\n",
330 pTag
->tagVersion
, BCM_TAG_VER
);
334 boardIdLen
= strlen(pTag
->boardId
);
335 if (memcmp(nvramData
.szBoardId
, pTag
->boardId
, boardIdLen
) != 0)
337 printf( "Image with id '" );
338 printf( pTag
->boardId
);
339 printf( "' cannot be flashed onto board '" );
340 printf( nvramData
.szBoardId
);
345 // check tag validate token first
346 crc
= CRC32_INIT_VALUE
;
347 crc
= getCrc32(imagePtr
, (UINT32
)TAG_LEN
-TOKEN_LEN
, crc
);
349 if (crc
!= (UINT32
)(*(UINT32
*)(pTag
->tagValidationToken
)))
351 printf("Illegal image ! Tag crc failed.\n");
356 totalImageSize
= atoi(pTag
->totalImageLen
);
357 crc
= CRC32_INIT_VALUE
;
358 crc
= getCrc32((imagePtr
+TAG_LEN
), (UINT32
) totalImageSize
, crc
);
360 if (crc
!= (UINT32
) (*(UINT32
*)(pTag
->imageValidationToken
)))
362 printf(" Illegal image ! Image crc failed.\n");
366 cfeSize
= rootfsSize
= kernelSize
= cfeAddr
= rootfsAddr
= kernelAddr
= 0;
368 // check cfe's existence
369 cfeAddr
= atoi(pTag
->cfeAddress
);
372 cfeSize
= atoi(pTag
->cfeLen
);
375 printf("Illegal cfe size [%d].\n", cfeSize
);
379 // save the memory type
380 memType
= kerSysMemoryTypeGet();;
382 printf("\nFlashing CFE: ");
383 if ((status
= kerSysBcmImageSet(cfeAddr
, imagePtr
+TAG_LEN
, cfeSize
, 0)) != 0)
385 printf("Failed to flash CFE. Error: %d\n", status
);
389 // restore the memory type
390 kerSysMemoryTypeSet((int) FLASH63XX_ADDR_BOOT_ROM
, (char *) &memType
, sizeof(int));
393 // check root filesystem and kernel existence
394 rootfsAddr
= atoi(pTag
->rootfsAddress
);
395 kernelAddr
= atoi(pTag
->kernelAddress
);
397 #if defined(DEBUG_FLASH)
398 printf("kernelAddr=0x%x, info->flash_nvram_start_blk=%d\n", kernelAddr
, info
.flash_nvram_start_blk
); //~~~
401 if( rootfsAddr
&& kernelAddr
)
403 unsigned int psiAddr
= (unsigned int) flash_get_memptr((byte
)info
.flash_persistent_start_blk
);
405 psiAddr
= psiAddr
+ info
.flash_persistent_blk_offset
;
407 #if defined(DEBUG_FLASH)
408 printf("psiAddr = 0x%x\n", psiAddr
);
411 rootfsSize
= atoi(pTag
->rootfsLen
);
412 kernelSize
= atoi(pTag
->kernelLen
);
413 if((rootfsSize
+ kernelSize
+ TAG_LEN
) > (unsigned int) (psiAddr
- rootfsAddr
))
415 printf("Illegal root file system [%d] and kernel [%d] combined sizes " \
416 " [%d].\nSizes must not be greater than [%d]\n", rootfsSize
,
417 kernelSize
, rootfsSize
+ kernelSize
+ TAG_LEN
, (unsigned int) psiAddr
- rootfsAddr
);
420 printf("\nFlashing root file system: ");
421 if ((status
= kerSysBcmImageSet(rootfsAddr
, imagePtr
+TAG_LEN
+cfeSize
, rootfsSize
, 0)) != 0)
423 printf("Failed to flash root file system. Error: %d\n", status
);
427 printf("\nFlashing kernel: ");
428 // tag is alway at the sector start and followed by kernel
429 memcpy(imagePtr
+cfeSize
+rootfsSize
, imagePtr
, TAG_LEN
);
431 #if defined(DEBUG_FLASH)
432 printf("kernelAddr=0x%x\n", kernelAddr
);
435 if ((status
= kerSysBcmImageSet(kernelAddr
,
436 imagePtr
+cfeSize
+rootfsSize
, kernelSize
+TAG_LEN
, 0)) != 0)
438 printf("Failed to flash kernel. Error: %d\n", status
);
443 printf(".\n*** Image flash done *** !\n");
451 int writeWholeImage(uint8_t *imagePtr
, int wholeImageSize
)
455 int imageSize
= wholeImageSize
- TOKEN_LEN
;
456 unsigned char crcBuf
[CRC_LEN
];
458 // check tag validate token first
459 crc
= CRC32_INIT_VALUE
;
460 crc
= getCrc32(imagePtr
, (UINT32
)imageSize
, crc
);
461 memcpy(crcBuf
, imagePtr
+imageSize
, CRC_LEN
);
462 if (memcmp(&crc
, crcBuf
, CRC_LEN
) != 0)
464 printf("Illegal whole flash image\n");
468 if ((status
= kerSysBcmImageSet((unsigned int)FLASH63XX_ADDR_BOOT_ROM
, imagePtr
, imageSize
, 1)) != 0)
470 printf("Failed to flash whole image. Error: %d\n", status
);
478 int processPrompt(PPARAMETER_SETTING promptPtr
, int promptCt
)
480 unsigned char tmpBuf
[MAX_PROMPT_LEN
];
484 printf("Press: <enter> to use current value\r\n");
485 printf(" '-' to go previous parameter\r\n");
486 printf(" '.' to clear the current value\r\n");
487 printf(" 'x' to exit this command\r\n");
491 if (strlen((promptPtr
+i
)->parameter
) > 0)
492 printf("%s %s ", (promptPtr
+i
)->promptName
, (promptPtr
+i
)->parameter
);
494 printf("%s %s", (promptPtr
+i
)->promptName
, (promptPtr
+i
)->parameter
);
496 memset(tmpBuf
, 0, MAX_PROMPT_LEN
);
497 console_readline ("", tmpBuf
, sizeof (tmpBuf
));
501 case '-': // go back one parameter
505 case '.': // clear the current parameter and advance
506 memset((promptPtr
+i
)->parameter
, 0, MAX_PROMPT_LEN
);
509 case 'x': // get out the b command
512 case 0: // no input; use default
515 default: // new parameter
516 if ((promptPtr
+i
)->func
!= 0) // validate function is supplied, do a check
518 if ((promptPtr
+i
)->func(tmpBuf
))
520 printf("\n%s; Try again!\n", (promptPtr
+i
)->errorPrompt
);
524 memset((promptPtr
+i
)->parameter
, 0, MAX_PROMPT_LEN
);
525 memcpy((promptPtr
+i
)->parameter
, tmpBuf
, strlen(tmpBuf
));
529 } while (i
< promptCt
);
535 // write the nvramData struct to nvram after CRC is calculated
536 void writeNvramData(void)
538 UINT32 crc
= CRC32_INIT_VALUE
;
540 nvramData
.ulCheckSum
= 0;
541 crc
= getCrc32((char *)&nvramData
, (UINT32
) sizeof(NVRAM_DATA
), crc
);
542 nvramData
.ulCheckSum
= crc
;
543 kerSysNvRamSet((char *)&nvramData
, sizeof(NVRAM_DATA
), NVRAM_VERSION_NUMBER_ADDRESS
);
546 // read the nvramData struct from nvram
547 // return -1: crc fail, 0 ok
548 int readNvramData(void)
550 UINT32 crc
= CRC32_INIT_VALUE
, savedCrc
;
552 kerSysNvRamGet((char *)&nvramData
, sizeof(NVRAM_DATA
), NVRAM_VERSION_NUMBER_ADDRESS
);
553 savedCrc
= nvramData
.ulCheckSum
;
554 nvramData
.ulCheckSum
= 0;
555 crc
= getCrc32((char *)&nvramData
, (UINT32
) sizeof(NVRAM_DATA
), crc
);
562 void convertBootInfo(void)
566 memset(&bootInfo
, 0, sizeof(BOOT_INFO
));
567 strcpy(bootInfo
.boardIp
, gBootParam
[0].parameter
);
569 if ((x
= strchr(bootInfo
.boardIp
, ':'))) // has mask
572 convertMaskStr((x
+1), bootInfo
.boardMask
);
574 strcpy(bootInfo
.hostIp
, gBootParam
[1].parameter
);
575 if ((x
= strchr(bootInfo
.hostIp
, ':'))) // ignore host mask
577 strcpy(bootInfo
.gatewayIp
, gBootParam
[2].parameter
);
578 if ((x
= strchr(bootInfo
.gatewayIp
, ':'))) // ignore gw mask
580 bootInfo
.runFrom
= gBootParam
[3].parameter
[0];
581 strcpy(bootInfo
.hostFileName
, gBootParam
[4].parameter
);
582 strcpy(bootInfo
.flashFileName
, gBootParam
[5].parameter
);
583 bootInfo
.bootDelay
= (int) (gBootParam
[6].parameter
[0] - '0');
588 static void getBootLine(int bootCt
)
595 // the struct is filled up in kerSysFlashInit
596 if ((nvramData
.szBootline
[0] == 'b' && nvramData
.szBootline
[1] == 'c' && nvramData
.szBootline
[2] == 'm') ||
597 (nvramData
.szBootline
[0] == (char)0xff))
598 setDefaultBootline();
603 curPtr
= nvramData
.szBootline
;
604 blLen
= NVRAM_BOOTLINE_LEN
;
606 for (i
= 0; i
< bootCt
; i
++)
608 curPtr
= strnchr(curPtr
, '=', blLen
);
609 if (curPtr
) // found '=' and get the param.
611 dPtr
= strnchr(curPtr
, ' ', blLen
); // find param. deliminator ' '
614 setDefaultBootline();
615 break; //break for loop and start over again
617 memset(gBootParam
[i
].parameter
, 0, MAX_PROMPT_LEN
);
618 memcpy(gBootParam
[i
].parameter
, curPtr
+1, dPtr
-curPtr
-1);
622 setDefaultBootline();
623 break; //break for loop and start over again
625 // move to next param.
629 } while (i
!= bootCt
); // do until the all the parameters are accounted for
635 // print the bootline and board parameter info and fill in the struct for later use
637 int printSysInfo(void)
640 PPARAMETER_SETTING tmpPtr
= gBootParam
;
643 if (readNvramData() != 0)
645 while ((nvramData
.szBoardId
[0] == (char)0xff) ||
646 (nvramData
.ulPsiSize
< NVRAM_PSI_MIN_SIZE
&& nvramData
.ulPsiSize
> NVRAM_PSI_MAX_SIZE
) ||
647 (nvramData
.ulNumMacAddrs
< 1 && nvramData
.ulNumMacAddrs
> NVRAM_MAC_COUNT_MAX
))
649 printf("*** Board is not initialized properly ***\n\n");
654 // display the bootline info
655 while (tmpPtr
->promptName
!= NULL
)
662 for (i
= 0; i
< count
; i
++)
663 printf("%s %s \n", gBootParam
[i
].promptName
, gBootParam
[i
].parameter
);
666 // print the board param
673 //**************************************************************************
674 // Function Name: changeBootLine
675 // Description : Use vxWorks bootrom style parameter input method:
676 // Press <enter> to use default, '-' to go to previous parameter
677 // Note: Parameter is set to current value in the menu.
679 //**************************************************************************
680 int changeBootLine(void)
683 PPARAMETER_SETTING tmpPtr
= gBootParam
;
687 while (tmpPtr
->promptName
!= NULL
)
695 bChange
= processPrompt(gBootParam
, count
);
699 char *blPtr
= nvramData
.szBootline
;
702 memset(blPtr
, 0, NVRAM_BOOTLINE_LEN
);
703 for (i
= 0; i
< count
; i
++)
705 memcpy(blPtr
, gBootParam
[i
].promptDefine
, PROMPT_DEFINE_LEN
);
706 blPtr
+= PROMPT_DEFINE_LEN
;
707 paramLen
= strlen(gBootParam
[i
].parameter
);
708 memcpy(blPtr
, gBootParam
[i
].parameter
, paramLen
);
710 if (!(gBootParam
[i
].parameter
[0] == ' '))
712 memcpy(blPtr
, " ", 1);