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();