Mercurial > flash_v2
comparison packages/redboot/current/src/flash.c @ 195:67850532eebb
Merge from eCos master repository on 2001-11-02-06:43:03-GMT
| author | jlarmour |
|---|---|
| date | Fri, 02 Nov 2001 16:12:33 +0000 |
| parents | 678094f34118 |
| children | 9b55e9c69693 |
comparison
equal
deleted
inserted
replaced
| 194:feb0fcf83327 | 195:67850532eebb |
|---|---|
| 44 //========================================================================== | 44 //========================================================================== |
| 45 | 45 |
| 46 #include <redboot.h> | 46 #include <redboot.h> |
| 47 #include <cyg/io/flash.h> | 47 #include <cyg/io/flash.h> |
| 48 #include <fis.h> | 48 #include <fis.h> |
| 49 #include <sib.h> | |
| 49 | 50 |
| 50 // CLI function | 51 // CLI function |
| 51 static cmd_fun do_fis; | 52 static cmd_fun do_fis; |
| 52 RedBoot_cmd("fis", | 53 RedBoot_cmd("fis", |
| 53 "Manage FLASH images", | 54 "Manage FLASH images", |
| 214 #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE | 215 #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE |
| 215 redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE; | 216 redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE; |
| 216 | 217 |
| 217 // Create a pseudo image for RedBoot | 218 // Create a pseudo image for RedBoot |
| 218 img = (struct fis_image_desc *)fis_work_block; | 219 img = (struct fis_image_desc *)fis_work_block; |
| 220 memset(img, 0xFF, block_size); // Start with erased data | |
| 219 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | 221 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE |
| 220 memset(img, 0, sizeof(*img)); | 222 memset(img, 0, sizeof(*img)); |
| 221 strcpy(img->name, "(reserved)"); | 223 strcpy(img->name, "(reserved)"); |
| 222 img->flash_base = (CYG_ADDRESS)flash_start; | 224 img->flash_base = (CYG_ADDRESS)flash_start; |
| 223 img->mem_base = (CYG_ADDRESS)flash_start; | 225 img->mem_base = (CYG_ADDRESS)flash_start; |
| 271 strcpy(img->name, "FIS directory"); | 273 strcpy(img->name, "FIS directory"); |
| 272 img->flash_base = (CYG_ADDRESS)fis_addr; | 274 img->flash_base = (CYG_ADDRESS)fis_addr; |
| 273 img->mem_base = (CYG_ADDRESS)fis_addr; | 275 img->mem_base = (CYG_ADDRESS)fis_addr; |
| 274 img->size = block_size; | 276 img->size = block_size; |
| 275 img++; | 277 img++; |
| 278 | |
| 279 #ifdef CYGOPT_REDBOOT_FIS_DIRECTORY_ARM_SIB_ID | |
| 280 // FIS gets the size of a full block - note, this should be changed | |
| 281 // if support is added for multi-block FIS structures. | |
| 282 img = (struct fis_image_desc *)((CYG_ADDRESS)fis_work_block + block_size); | |
| 283 // Add a footer so the FIS will be recognized by the ARM Boot | |
| 284 // Monitor as a reserved area. | |
| 285 { | |
| 286 tFooter* footer_p = (tFooter*)((CYG_ADDRESS)img - sizeof(tFooter)); | |
| 287 cyg_uint32 check = 0; | |
| 288 cyg_uint32 *check_ptr = (cyg_uint32 *)footer_p; | |
| 289 cyg_int32 count = (sizeof(tFooter) - 4) >> 2; | |
| 290 | |
| 291 // Prepare footer. Try to protect all but the reserved space | |
| 292 // and the first RedBoot image (which is expected to be | |
| 293 // bootable), but fall back to just protecting the FIS if it's | |
| 294 // not at the default position in the flash. | |
| 295 #if defined(CYGOPT_REDBOOT_FIS_RESERVED_BASE) && (-1 == CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK) | |
| 296 footer_p->blockBase = (char*)_ADDR_REDBOOT_TO_ARM(flash_start); | |
| 297 footer_p->blockBase += CYGNUM_REDBOOT_FLASH_RESERVED_BASE + redboot_image_size; | |
| 298 #else | |
| 299 footer_p->blockBase = _ADDR_REDBOOT_TO_ARM(fis_work_block); | |
| 300 #endif | |
| 301 footer_p->infoBase = NULL; | |
| 302 footer_p->signature = FLASH_FOOTER_SIGNATURE; | |
| 303 footer_p->type = TYPE_REDHAT_REDBOOT; | |
| 304 | |
| 305 // and compute its checksum | |
| 306 for ( ; count > 0; count--) { | |
| 307 if (*check_ptr > ~check) | |
| 308 check++; | |
| 309 check += *check_ptr++; | |
| 310 } | |
| 311 footer_p->checksum = ~check; | |
| 312 } | |
| 313 #endif | |
| 276 | 314 |
| 277 // Do this after creating the initialized table because that inherently | 315 // Do this after creating the initialized table because that inherently |
| 278 // calculates where the high water mark of default RedBoot images is. | 316 // calculates where the high water mark of default RedBoot images is. |
| 279 | 317 |
| 280 if (full_init) { | 318 if (full_init) { |
| 368 struct fis_image_desc *img; | 406 struct fis_image_desc *img; |
| 369 int i; | 407 int i; |
| 370 bool show_cksums = false; | 408 bool show_cksums = false; |
| 371 bool show_datalen = false; | 409 bool show_datalen = false; |
| 372 struct option_info opts[2]; | 410 struct option_info opts[2]; |
| 411 | |
| 412 #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB | |
| 413 // FIXME: this is somewhat half-baked | |
| 414 extern void arm_fis_list(void); | |
| 415 arm_fis_list(); | |
| 416 return; | |
| 417 #endif | |
| 373 | 418 |
| 374 init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, | 419 init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, |
| 375 (void **)&show_datalen, (bool *)0, "display data length"); | 420 (void **)&show_datalen, (bool *)0, "display data length"); |
| 376 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK | 421 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK |
| 377 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, | 422 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, |
| 686 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); | 731 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); |
| 687 #endif | 732 #endif |
| 688 } | 733 } |
| 689 } | 734 } |
| 690 | 735 |
| 736 extern void arm_fis_delete(char *); | |
| 691 static void | 737 static void |
| 692 fis_delete(int argc, char *argv[]) | 738 fis_delete(int argc, char *argv[]) |
| 693 { | 739 { |
| 694 char *name; | 740 char *name; |
| 695 int num_reserved, i, stat; | 741 int num_reserved, i, stat; |
| 700 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | 746 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) |
| 701 { | 747 { |
| 702 fis_usage("invalid arguments"); | 748 fis_usage("invalid arguments"); |
| 703 return; | 749 return; |
| 704 } | 750 } |
| 751 #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB | |
| 752 // FIXME: this is somewhat half-baked | |
| 753 arm_fis_delete(name); | |
| 754 return; | |
| 755 #endif | |
| 705 slot_found = false; | 756 slot_found = false; |
| 706 img = (struct fis_image_desc *)fis_work_block; | 757 img = (struct fis_image_desc *)fis_work_block; |
| 707 num_reserved = 0; | 758 num_reserved = 0; |
| 708 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | 759 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE |
| 709 num_reserved++; | 760 num_reserved++; |
| 1236 static void config_init(void); | 1287 static void config_init(void); |
| 1237 | 1288 |
| 1238 static int | 1289 static int |
| 1239 get_config(unsigned char *dp, char *title, int list_opt, char *newvalue ) | 1290 get_config(unsigned char *dp, char *title, int list_opt, char *newvalue ) |
| 1240 { | 1291 { |
| 1241 char line[256], *sp, *lp; | 1292 char line[256], hold_line[256], *sp, *lp; |
| 1242 int ret; | 1293 int ret; |
| 1243 bool hold_bool_val, new_bool_val, enable; | 1294 bool hold_bool_val, new_bool_val, enable; |
| 1244 unsigned long hold_int_val, new_int_val; | 1295 unsigned long hold_int_val, new_int_val; |
| 1245 #ifdef CYGPKG_REDBOOT_NETWORKING | 1296 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 1246 in_addr_t hold_ip_val, new_ip_val; | 1297 in_addr_t hold_ip_val, new_ip_val; |
| 1256 if (((bool)CONFIG_OBJECT_ENABLE_SENSE(dp) && !enable) || | 1307 if (((bool)CONFIG_OBJECT_ENABLE_SENSE(dp) && !enable) || |
| 1257 (!(bool)CONFIG_OBJECT_ENABLE_SENSE(dp) && enable)) { | 1308 (!(bool)CONFIG_OBJECT_ENABLE_SENSE(dp) && enable)) { |
| 1258 return CONFIG_OK; // Disabled field | 1309 return CONFIG_OK; // Disabled field |
| 1259 } | 1310 } |
| 1260 } | 1311 } |
| 1312 lp = line; *lp = '\0'; | |
| 1261 val_ptr = (void *)CONFIG_OBJECT_VALUE(dp); | 1313 val_ptr = (void *)CONFIG_OBJECT_VALUE(dp); |
| 1262 if (LIST_OPT_NICKNAMES & list_opt) | 1314 if (LIST_OPT_NICKNAMES & list_opt) |
| 1263 diag_printf("%s: ", CONFIG_OBJECT_KEY(dp)); | 1315 diag_printf("%s: ", CONFIG_OBJECT_KEY(dp)); |
| 1264 if (LIST_OPT_FULLNAMES & list_opt) { | 1316 if (LIST_OPT_FULLNAMES & list_opt) { |
| 1265 if (title != (char *)NULL) { | 1317 if (title != (char *)NULL) { |
| 1269 } | 1321 } |
| 1270 } | 1322 } |
| 1271 switch (type = CONFIG_OBJECT_TYPE(dp)) { | 1323 switch (type = CONFIG_OBJECT_TYPE(dp)) { |
| 1272 case CONFIG_BOOL: | 1324 case CONFIG_BOOL: |
| 1273 memcpy(&hold_bool_val, val_ptr, sizeof(bool)); | 1325 memcpy(&hold_bool_val, val_ptr, sizeof(bool)); |
| 1274 diag_printf("%s ", hold_bool_val ? "true" : "false"); | 1326 lp += diag_sprintf(lp, "%s", hold_bool_val ? "true" : "false"); |
| 1275 break; | 1327 break; |
| 1276 case CONFIG_INT: | 1328 case CONFIG_INT: |
| 1277 memcpy(&hold_int_val, val_ptr, sizeof(unsigned long)); | 1329 memcpy(&hold_int_val, val_ptr, sizeof(unsigned long)); |
| 1278 diag_printf("%ld ", hold_int_val); | 1330 lp += diag_sprintf(lp, "%ld", hold_int_val); |
| 1279 break; | 1331 break; |
| 1280 #ifdef CYGPKG_REDBOOT_NETWORKING | 1332 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 1281 case CONFIG_IP: | 1333 case CONFIG_IP: |
| 1282 diag_printf("%s ", inet_ntoa((in_addr_t *)val_ptr)); | 1334 lp += diag_sprintf(lp, "%s", inet_ntoa((in_addr_t *)val_ptr)); |
| 1283 break; | 1335 break; |
| 1284 case CONFIG_ESA: | 1336 case CONFIG_ESA: |
| 1285 for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { | 1337 for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { |
| 1286 diag_printf("0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); | 1338 lp += diag_sprintf(lp, "0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); |
| 1287 if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":"); | 1339 if (esa_ptr < (sizeof(enet_addr_t)-1)) lp += diag_sprintf(lp, ":"); |
| 1288 } | 1340 } |
| 1289 diag_printf(" "); | |
| 1290 break; | 1341 break; |
| 1291 #endif | 1342 #endif |
| 1292 case CONFIG_STRING: | 1343 case CONFIG_STRING: |
| 1293 diag_printf("%s ", (unsigned char *)val_ptr); | 1344 lp += diag_sprintf(lp, "%s", (unsigned char *)val_ptr); |
| 1294 break; | 1345 break; |
| 1295 case CONFIG_SCRIPT: | 1346 case CONFIG_SCRIPT: |
| 1296 diag_printf("\n"); | 1347 diag_printf("\n"); |
| 1297 sp = lp = (unsigned char *)val_ptr; | 1348 sp = lp = (unsigned char *)val_ptr; |
| 1298 while (*sp) { | 1349 while (*sp) { |
| 1303 sp = lp; | 1354 sp = lp; |
| 1304 } | 1355 } |
| 1305 break; | 1356 break; |
| 1306 } | 1357 } |
| 1307 if (LIST_OPT_LIST_ONLY & list_opt) { | 1358 if (LIST_OPT_LIST_ONLY & list_opt) { |
| 1308 diag_printf("\n"); | 1359 diag_printf("%s\n", line); |
| 1309 return CONFIG_OK; | 1360 return CONFIG_OK; |
| 1310 } | 1361 } |
| 1311 if (type != CONFIG_SCRIPT) { | 1362 if (type != CONFIG_SCRIPT) { |
| 1312 if (NULL != newvalue) { | 1363 if (NULL != newvalue) { |
| 1313 ret = strlen(newvalue); | 1364 ret = strlen(newvalue); |
| 1314 if (ret > sizeof(line)) | 1365 if (ret > sizeof(line)) |
| 1315 return CONFIG_BAD; | 1366 return CONFIG_BAD; |
| 1316 strcpy(line, newvalue); | 1367 strcpy(line, newvalue); |
| 1368 strcpy(hold_line, newvalue); | |
| 1317 diag_printf("Setting to %s\n", newvalue); | 1369 diag_printf("Setting to %s\n", newvalue); |
| 1318 } | 1370 } else { |
| 1319 else // read from terminal | 1371 // read from terminal |
| 1320 ret = _rb_gets(line, sizeof(line), 0); | 1372 strcpy(hold_line, line); |
| 1373 ret = _rb_gets_preloaded(line, sizeof(line), 0); | |
| 1374 } | |
| 1321 if (ret < 0) return CONFIG_ABORT; | 1375 if (ret < 0) return CONFIG_ABORT; |
| 1322 if (strlen(line) == 0) return CONFIG_OK; // Just a CR - leave value untouched | 1376 if (strcmp(line, hold_line) == 0) return CONFIG_OK; // Just a CR - leave value untouched |
| 1323 if (line[0] == '.') return CONFIG_DONE; | 1377 lp = &line[strlen(line)-1]; |
| 1324 if (line[0] == '^') return CONFIG_BACK; | 1378 if (*lp == '.') return CONFIG_DONE; |
| 1379 if (*lp == '^') return CONFIG_BACK; | |
| 1325 } | 1380 } |
| 1326 switch (type) { | 1381 switch (type) { |
| 1327 case CONFIG_BOOL: | 1382 case CONFIG_BOOL: |
| 1328 memcpy(&hold_bool_val, val_ptr, sizeof(bool)); | 1383 memcpy(&hold_bool_val, val_ptr, sizeof(bool)); |
| 1329 if (!parse_bool(line, &new_bool_val)) { | 1384 if (!parse_bool(line, &new_bool_val)) { |
| 1659 } | 1714 } |
| 1660 | 1715 |
| 1661 // Expand aliases, this is recursive. ie if one alias contains other | 1716 // Expand aliases, this is recursive. ie if one alias contains other |
| 1662 // aliases, these will also be expanded from the insertion point | 1717 // aliases, these will also be expanded from the insertion point |
| 1663 // onwards. | 1718 // onwards. |
| 1719 // | |
| 1720 // If 'iter' is zero, then quoted strings are not expanded | |
| 1721 // | |
| 1664 bool | 1722 bool |
| 1665 _expand_aliases(char *line, int len) | 1723 _expand_aliases(char *line, int len, int iter) |
| 1666 { | 1724 { |
| 1667 char *lp = line; | 1725 char *lp = line; |
| 1668 char *ms, *me, *ep; | 1726 char *ms, *me, *ep; |
| 1669 char *alias; | 1727 char *alias; |
| 1670 char c; | 1728 char c; |
| 1725 } | 1783 } |
| 1726 } else { | 1784 } else { |
| 1727 diag_printf("Alias '%s' not defined\n", ms); | 1785 diag_printf("Alias '%s' not defined\n", ms); |
| 1728 *me = '|'; | 1786 *me = '|'; |
| 1729 } | 1787 } |
| 1730 } else if (c == '"') { | 1788 } else if ((c == '"') && (iter == 0)) { |
| 1731 // Skip quoted strings | 1789 // Skip quoted strings |
| 1732 while (*lp && (*lp != '"')) lp++; | 1790 while (*lp && (*lp != '"')) lp++; |
| 1733 } | 1791 } |
| 1734 } | 1792 } |
| 1735 } | 1793 } |
| 1737 } | 1795 } |
| 1738 | 1796 |
| 1739 void | 1797 void |
| 1740 expand_aliases(char *line, int len) | 1798 expand_aliases(char *line, int len) |
| 1741 { | 1799 { |
| 1742 while (_expand_aliases(line, len)) ; | 1800 int iter = 0; |
| 1801 | |
| 1802 while (_expand_aliases(line, len, iter++)) { | |
| 1803 } | |
| 1743 } | 1804 } |
| 1744 #endif // CYGSEM_REDBOOT_FLASH_ALIASES | 1805 #endif // CYGSEM_REDBOOT_FLASH_ALIASES |
| 1745 | 1806 |
| 1746 // | 1807 // |
| 1747 // Write the in-memory copy of the configuration data to the flash device. | 1808 // Write the in-memory copy of the configuration data to the flash device. |
