Mercurial > ecos
comparison packages/redboot/current/src/flash.c @ 183:9160a8005d76
Merge from eCos master repository on 2001-09-12-03:52:30-BST
| author | jlarmour |
|---|---|
| date | Wed, 12 Sep 2001 04:21:13 +0000 |
| parents | f62680ef1804 |
| children | 022f1e506033 |
comparison
equal
deleted
inserted
replaced
| 182:f62680ef1804 | 183:9160a8005d76 |
|---|---|
| 148 static void *fis_work_block; | 148 static void *fis_work_block; |
| 149 static int fisdir_size; // Size of FIS directory. Note: zero if FIS not enabled | 149 static int fisdir_size; // Size of FIS directory. Note: zero if FIS not enabled |
| 150 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 150 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 151 static void *cfg_base; // Location in Flash of config data | 151 static void *cfg_base; // Location in Flash of config data |
| 152 static int cfg_size; // Length of config data - rounded to Flash block size | 152 static int cfg_size; // Length of config data - rounded to Flash block size |
| 153 // Prototypes for local functions | |
| 154 static unsigned char *flash_lookup_config(char *key); | |
| 153 #endif | 155 #endif |
| 154 | 156 |
| 155 static void | 157 static void |
| 156 fis_usage(char *why) | 158 fis_usage(char *why) |
| 157 { | 159 { |
| 165 { | 167 { |
| 166 int i; | 168 int i; |
| 167 void *fis_addr; | 169 void *fis_addr; |
| 168 struct fis_image_desc *img; | 170 struct fis_image_desc *img; |
| 169 | 171 |
| 170 fis_addr = (void *)((unsigned long)flash_end - block_size); | 172 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 173 fis_addr = (void *)((unsigned long)flash_end + | |
| 174 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 175 } else { | |
| 176 fis_addr = (void *)((unsigned long)flash_start + | |
| 177 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 178 } | |
| 171 memcpy(fis_work_block, fis_addr, block_size); | 179 memcpy(fis_work_block, fis_addr, block_size); |
| 172 img = (struct fis_image_desc *)fis_work_block; | 180 img = (struct fis_image_desc *)fis_work_block; |
| 173 for (i = 0; i < block_size/sizeof(*img); i++, img++) { | 181 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 174 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 182 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 175 return img; | 183 return img; |
| 249 #endif | 257 #endif |
| 250 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 258 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 251 // And a descriptor for the configuration data | 259 // And a descriptor for the configuration data |
| 252 memset(img, 0, sizeof(*img)); | 260 memset(img, 0, sizeof(*img)); |
| 253 strcpy(img->name, "RedBoot config"); | 261 strcpy(img->name, "RedBoot config"); |
| 262 if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { | |
| 263 cfg_base = (void *)((unsigned long)flash_end + | |
| 264 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | |
| 265 } else { | |
| 266 cfg_base = (void *)((unsigned long)flash_start + | |
| 267 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | |
| 268 } | |
| 254 img->flash_base = (unsigned long)cfg_base; | 269 img->flash_base = (unsigned long)cfg_base; |
| 255 img->mem_base = (unsigned long)cfg_base; | 270 img->mem_base = (unsigned long)cfg_base; |
| 256 img->size = cfg_size; | 271 img->size = cfg_size; |
| 257 img++; | 272 img++; |
| 258 #endif | 273 #endif |
| 259 // And a descriptor for the descriptor table itself | 274 // And a descriptor for the descriptor table itself |
| 260 memset(img, 0, sizeof(*img)); | 275 memset(img, 0, sizeof(*img)); |
| 261 strcpy(img->name, "FIS directory"); | 276 strcpy(img->name, "FIS directory"); |
| 262 fis_base = (void *)((unsigned long)flash_end - block_size); | 277 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 278 fis_base = (void *)((unsigned long)flash_end + | |
| 279 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 280 } else { | |
| 281 fis_base = (void *)((unsigned long)flash_start + | |
| 282 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 283 } | |
| 263 img->flash_base = (unsigned long)fis_base; | 284 img->flash_base = (unsigned long)fis_base; |
| 264 img->mem_base = (unsigned long)fis_base; | 285 img->mem_base = (unsigned long)fis_base; |
| 265 img->size = block_size; | 286 img->size = block_size; |
| 266 img++; | 287 img++; |
| 267 | 288 |
| 268 // Do this after creating the initialized table because that inherently | 289 // Do this after creating the initialized table because that inherently |
| 269 // calculates where the high water mark of default RedBoot images is. | 290 // calculates where the high water mark of default RedBoot images is. |
| 270 | 291 |
| 271 if (full_init) { | 292 if (full_init) { |
| 272 unsigned long erase_start, erase_size; | 293 unsigned long erase_start, erase_size; |
| 273 // Erase everything except default RedBoot images, fis block, and config block. | 294 // Erase everything except default RedBoot images, fis block, |
| 274 // FIXME! This still assumes that fis and config blocks can use top of FLASH. | 295 // and config block. |
| 275 | 296 // First deal with the possible first part, before RedBoot images: |
| 276 // first deal with the possible first part, before RedBoot images: | |
| 277 erase_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; | 297 erase_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; |
| 278 erase_size = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; | 298 erase_size = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; |
| 279 if ( erase_size > erase_start ) { | 299 if ( erase_size > erase_start ) { |
| 280 erase_size -= erase_start; | 300 erase_size -= erase_start; |
| 281 if ((stat = flash_erase((void *)erase_start, erase_size, | 301 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 284 err_addr, flash_errmsg(stat)); | 304 err_addr, flash_errmsg(stat)); |
| 285 } | 305 } |
| 286 } | 306 } |
| 287 // second deal with the larger part in the main: | 307 // second deal with the larger part in the main: |
| 288 erase_start = redboot_flash_start; // high water of created images | 308 erase_start = redboot_flash_start; // high water of created images |
| 309 // Now the empty bits between the end of Redboot and the cfg and dir | |
| 310 // blocks. | |
| 289 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 311 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 290 erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data | 312 if (fis_base > cfg_base) { |
| 291 #else | 313 erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data |
| 314 } else { | |
| 315 erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data | |
| 316 } | |
| 317 if ((stat = flash_erase((void *)erase_start, erase_size, | |
| 318 (void **)&err_addr)) != 0) { | |
| 319 diag_printf(" initialization failed %p: %s\n", | |
| 320 err_addr, flash_errmsg(stat)); | |
| 321 } | |
| 322 erase_start += (erase_size + block_size); | |
| 323 if (fis_base > cfg_base) { | |
| 324 erase_size = (unsigned long)fis_base - erase_start; // the gap between config and fis data | |
| 325 } else { | |
| 326 erase_size = (unsigned long)cfg_base - erase_start; // the gap between fis and config data | |
| 327 } | |
| 328 if ((stat = flash_erase((void *)erase_start, erase_size, | |
| 329 (void **)&err_addr)) != 0) { | |
| 330 diag_printf(" initialization failed %p: %s\n", | |
| 331 err_addr, flash_errmsg(stat)); | |
| 332 } | |
| 333 erase_start += (erase_size + block_size); | |
| 334 #else // !CYGSEM_REDBOOT_FLASH_CONFIG | |
| 292 erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data | 335 erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data |
| 293 #endif | 336 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 337 (void **)&err_addr)) != 0) { | |
| 338 diag_printf(" initialization failed %p: %s\n", | |
| 339 err_addr, flash_errmsg(stat)); | |
| 340 } | |
| 341 erase_start += (erase_size + block_size); | |
| 342 #endif | |
| 343 // Lastly, anything at the end | |
| 344 erase_size = (unsigned long)flash_end - erase_start; | |
| 294 if ((stat = flash_erase((void *)erase_start, erase_size, | 345 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 295 (void **)&err_addr)) != 0) { | 346 (void **)&err_addr)) != 0) { |
| 296 diag_printf(" initialization failed at %p: %s\n", | 347 diag_printf(" initialization failed at %p: %s\n", |
| 297 err_addr, flash_errmsg(stat)); | 348 err_addr, flash_errmsg(stat)); |
| 298 } | 349 } |
| 340 #endif | 391 #endif |
| 341 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) | 392 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) |
| 342 { | 393 { |
| 343 return; | 394 return; |
| 344 } | 395 } |
| 345 | 396 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 346 img = (struct fis_image_desc *)((unsigned long)flash_end - block_size); | 397 img = (void *)((unsigned long)flash_end + |
| 347 // Let diag_printf do the formatting in both cases, rather than cnouting | 398 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); |
| 399 } else { | |
| 400 img = (void *)((unsigned long)flash_start + | |
| 401 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 402 } | |
| 403 // Let diag_printf do the formatting in both cases, rather than counting | |
| 348 // cols by hand.... | 404 // cols by hand.... |
| 349 diag_printf("%-16s %-10s %-10s %-10s %-s\n", | 405 diag_printf("%-16s %-10s %-10s %-10s %-s\n", |
| 350 "Name","FLASH addr", | 406 "Name","FLASH addr", |
| 351 show_cksums ? "Checksum" : "Mem addr", | 407 show_cksums ? "Checksum" : "Mem addr", |
| 352 show_datalen ? "Datalen" : "Length", | 408 show_datalen ? "Datalen" : "Length", |
| 485 } | 541 } |
| 486 | 542 |
| 487 defaults_assumed = false; | 543 defaults_assumed = false; |
| 488 if (name) { | 544 if (name) { |
| 489 // Search existing files to acquire defaults for params not specified: | 545 // Search existing files to acquire defaults for params not specified: |
| 490 fis_addr = (void *)((unsigned long)flash_end - block_size); | 546 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 547 fis_addr = (void *)((unsigned long)flash_end + | |
| 548 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 549 } else { | |
| 550 fis_addr = (void *)((unsigned long)flash_start + | |
| 551 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 552 } | |
| 491 memcpy(fis_work_block, fis_addr, block_size); | 553 memcpy(fis_work_block, fis_addr, block_size); |
| 492 img = (struct fis_image_desc *)fis_work_block; | 554 img = (struct fis_image_desc *)fis_work_block; |
| 493 for (i = 0; i < block_size/sizeof(*img); i++, img++) { | 555 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 494 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 556 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 495 // Found it, so get any unset but necessary params from there: | 557 // Found it, so get any unset but necessary params from there: |
| 558 } | 620 } |
| 559 } | 621 } |
| 560 // Find a slot in the directory for this entry | 622 // Find a slot in the directory for this entry |
| 561 // First, see if an image by this name is already present | 623 // First, see if an image by this name is already present |
| 562 slot_found = false; | 624 slot_found = false; |
| 563 fis_addr = (void *)((unsigned long)flash_end - block_size); | 625 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 626 fis_addr = (void *)((unsigned long)flash_end + | |
| 627 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 628 } else { | |
| 629 fis_addr = (void *)((unsigned long)flash_start + | |
| 630 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 631 } | |
| 564 memcpy(fis_work_block, fis_addr, block_size); | 632 memcpy(fis_work_block, fis_addr, block_size); |
| 565 img = (struct fis_image_desc *)fis_work_block; | 633 img = (struct fis_image_desc *)fis_work_block; |
| 566 for (i = 0; i < block_size/sizeof(*img); i++, img++) { | 634 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 567 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 635 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 568 if (flash_addr_set && (img->flash_base != flash_addr)) { | 636 if (flash_addr_set && (img->flash_base != flash_addr)) { |
| 654 | 722 |
| 655 static void | 723 static void |
| 656 fis_delete(int argc, char *argv[]) | 724 fis_delete(int argc, char *argv[]) |
| 657 { | 725 { |
| 658 char *name; | 726 char *name; |
| 659 int i, stat; | 727 int num_reserved, i, stat; |
| 660 void *fis_addr, *err_addr; | 728 void *fis_addr, *err_addr; |
| 661 struct fis_image_desc *img; | 729 struct fis_image_desc *img; |
| 662 bool slot_found; | 730 bool slot_found; |
| 663 | 731 |
| 664 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | 732 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) |
| 665 { | 733 { |
| 666 fis_usage("invalid arguments"); | 734 fis_usage("invalid arguments"); |
| 667 return; | 735 return; |
| 668 } | 736 } |
| 669 | |
| 670 slot_found = false; | 737 slot_found = false; |
| 671 fis_addr = (void *)((unsigned long)flash_end - block_size); | 738 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 739 fis_addr = (void *)((unsigned long)flash_end + | |
| 740 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 741 } else { | |
| 742 fis_addr = (void *)((unsigned long)flash_start + | |
| 743 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 744 } | |
| 672 memcpy(fis_work_block, fis_addr, block_size); | 745 memcpy(fis_work_block, fis_addr, block_size); |
| 673 img = (struct fis_image_desc *)fis_work_block; | 746 img = (struct fis_image_desc *)fis_work_block; |
| 674 i = 0; | 747 num_reserved = 0; |
| 675 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | 748 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE |
| 676 i++; | 749 num_reserved++; |
| 677 #endif | 750 #endif |
| 678 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT | 751 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT |
| 679 i++; | 752 num_reserved++; |
| 680 #endif | 753 #endif |
| 681 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP | 754 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP |
| 682 i++; | 755 num_reserved++; |
| 683 #endif | 756 #endif |
| 684 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST | 757 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST |
| 685 i++; | 758 num_reserved++; |
| 686 #endif | 759 #endif |
| 687 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 760 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 688 i++; | 761 num_reserved++; |
| 689 #endif | 762 #endif |
| 690 #if 1 // And the descriptor for the descriptor table itself | 763 #if 1 // And the descriptor for the descriptor table itself |
| 691 i++; | 764 num_reserved++; |
| 692 #endif | 765 #endif |
| 693 img += i; // Skip reserved files | 766 |
| 694 | 767 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 695 for ( /* i, img */; i < block_size/sizeof(*img); i++, img++) { | |
| 696 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 768 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 769 if (i < num_reserved) { | |
| 770 diag_printf("Sorry, '%s' is a reserved image and cannot be deleted\n", img->name); | |
| 771 return; | |
| 772 } | |
| 697 if (!verify_action("Delete image '%s'", name)) { | 773 if (!verify_action("Delete image '%s'", name)) { |
| 698 return; | 774 return; |
| 699 } else { | 775 } else { |
| 700 slot_found = true; | 776 slot_found = true; |
| 701 break; | 777 break; |
| 1634 | 1710 |
| 1635 config.len = sizeof(config); | 1711 config.len = sizeof(config); |
| 1636 config.key1 = CONFIG_KEY1; | 1712 config.key1 = CONFIG_KEY1; |
| 1637 config.key2 = CONFIG_KEY2; | 1713 config.key2 = CONFIG_KEY2; |
| 1638 config.cksum = crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)); | 1714 config.cksum = crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)); |
| 1715 if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { | |
| 1716 cfg_base = (void *)((unsigned long)flash_end + | |
| 1717 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | |
| 1718 } else { | |
| 1719 cfg_base = (void *)((unsigned long)flash_start + | |
| 1720 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | |
| 1721 } | |
| 1639 if (verify_action("Update RedBoot non-volatile configuration")) { | 1722 if (verify_action("Update RedBoot non-volatile configuration")) { |
| 1640 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 1723 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 1641 // Insure [quietly] that the config page is unlocked before trying to update | 1724 // Insure [quietly] that the config page is unlocked before trying to update |
| 1642 flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr); | 1725 flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr); |
| 1643 #endif | 1726 #endif |
| 1852 script = (unsigned char *)0; | 1935 script = (unsigned char *)0; |
| 1853 if (!do_flash_init()) return; | 1936 if (!do_flash_init()) return; |
| 1854 #define _roundup(n,s) ((((n)+(s-1))/s)*s) | 1937 #define _roundup(n,s) ((((n)+(s-1))/s)*s) |
| 1855 cfg_size = (block_size > sizeof(config)) ? sizeof(config) : | 1938 cfg_size = (block_size > sizeof(config)) ? sizeof(config) : |
| 1856 _roundup(sizeof(config), block_size); | 1939 _roundup(sizeof(config), block_size); |
| 1857 cfg_base = (void *)((unsigned long)flash_end - _roundup(cfg_size+fisdir_size, block_size)); | 1940 if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { |
| 1941 cfg_base = (void *)((unsigned long)flash_end + | |
| 1942 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | |
| 1943 } else { | |
| 1944 cfg_base = (void *)((unsigned long)flash_start + | |
| 1945 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | |
| 1946 } | |
| 1858 memcpy(&config, cfg_base, sizeof(config)); | 1947 memcpy(&config, cfg_base, sizeof(config)); |
| 1859 if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) || | 1948 if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) || |
| 1860 (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) { | 1949 (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) { |
| 1861 diag_printf("FLASH configuration checksum error or invalid key\n"); | 1950 diag_printf("FLASH configuration checksum error or invalid key\n"); |
| 1862 config_init(); | 1951 config_init(); |
