Mercurial > flash_v2
comparison packages/redboot/current/src/flash.c @ 1700:bbdd4a302a64
* src/flash.c:
* src/fconfig.c: Make use of the new flash API.
| author | asl |
|---|---|
| date | Thu, 05 Aug 2004 13:18:48 +0000 |
| parents | b548ac5af76c |
| children | faaea4243d52 |
comparison
equal
deleted
inserted
replaced
| 1699:1122a4ee1546 | 1700:bbdd4a302a64 |
|---|---|
| 161 do_fis, | 161 do_fis, |
| 162 __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__ | 162 __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__ |
| 163 ); | 163 ); |
| 164 | 164 |
| 165 // Local data used by these routines | 165 // Local data used by these routines |
| 166 void *flash_start, *flash_end; | 166 cyg_flashaddr_t flash_start, flash_end; |
| 167 int flash_block_size, flash_num_blocks; | 167 size_t flash_block_size; |
| 168 cyg_uint32 flash_num_blocks; | |
| 168 #ifdef CYGOPT_REDBOOT_FIS | 169 #ifdef CYGOPT_REDBOOT_FIS |
| 169 void *fis_work_block; | 170 void *fis_work_block; |
| 170 void *fis_addr; | 171 cyg_flashaddr_t fis_addr; |
| 171 int fisdir_size; // Size of FIS directory. | 172 int fisdir_size; // Size of FIS directory. |
| 172 #endif | 173 #endif |
| 173 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 174 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 174 extern void *cfg_base; // Location in Flash of config data | 175 extern cyg_flashaddr_t cfg_base; // Location in Flash of config data |
| 175 extern int cfg_size; // Length of config data - rounded to Flash block size | 176 extern size_t cfg_size; // Length of config data - rounded to Flash block size |
| 176 extern struct _config *config; | 177 extern struct _config *config; |
| 177 #endif | 178 #endif |
| 178 | 179 |
| 179 static void | 180 static void |
| 180 fis_usage(char *why) | 181 fis_usage(char *why) |
| 184 } | 185 } |
| 185 | 186 |
| 186 static void | 187 static void |
| 187 _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) | 188 _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) |
| 188 { | 189 { |
| 189 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); | 190 cyg_uint32 i=0; |
| 190 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | 191 cyg_flash_info_t info; |
| 192 int ret; | |
| 193 | |
| 194 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, | |
| 195 cyg_flash_errmsg(stat)); | |
| 196 do { | |
| 197 ret = cyg_flash_get_info(i, &info); | |
| 198 if (ret == CYG_FLASH_ERR_OK) { | |
| 199 diag_printf(" valid range is %p - %p\n", info.start, info.end); | |
| 200 } | |
| 201 i++; | |
| 202 } while (ret != CYG_FLASH_ERR_INVALID); | |
| 191 } | 203 } |
| 192 | 204 |
| 193 #ifdef CYGOPT_REDBOOT_FIS | 205 #ifdef CYGOPT_REDBOOT_FIS |
| 194 struct fis_image_desc * | 206 struct fis_image_desc * |
| 195 fis_lookup(char *name, int *num) | 207 fis_lookup(char *name, int *num) |
| 196 { | 208 { |
| 197 int i; | 209 int i; |
| 198 struct fis_image_desc *img; | 210 struct fis_image_desc *img; |
| 199 void *err_addr; | 211 cyg_flashaddr_t err_addr; |
| 200 | 212 |
| 201 flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); | 213 cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); |
| 202 img = (struct fis_image_desc *)fis_work_block; | 214 img = (struct fis_image_desc *)fis_work_block; |
| 203 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { | 215 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { |
| 204 if ((img->name[0] != (unsigned char)0xFF) && | 216 if ((img->name[0] != (unsigned char)0xFF) && |
| 205 (strcasecmp(name, img->name) == 0)) { | 217 (strcasecmp(name, img->name) == 0)) { |
| 206 if (num) *num = i; | 218 if (num) *num = i; |
| 212 | 224 |
| 213 void | 225 void |
| 214 fis_update_directory(void) | 226 fis_update_directory(void) |
| 215 { | 227 { |
| 216 int stat; | 228 int stat; |
| 217 void *err_addr; | 229 cyg_flashaddr_t err_addr; |
| 218 | 230 |
| 219 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG | 231 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG |
| 220 memcpy((char *)fis_work_block+fisdir_size, config, cfg_size); | 232 memcpy((char *)fis_work_block+fisdir_size, config, cfg_size); |
| 221 #endif | 233 #endif |
| 222 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 234 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 223 // Ensure [quietly] that the directory is unlocked before trying to update | 235 // Ensure [quietly] that the directory is unlocked before trying to update |
| 224 flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr); | 236 cyg_flash_unlock((void *)fis_addr, flash_block_size, &err_addr); |
| 225 #endif | 237 #endif |
| 226 if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) { | 238 if ((stat = cyg_flash_erase(fis_addr, flash_block_size, &err_addr)) != 0) { |
| 227 diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); | 239 diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); |
| 228 } else { | 240 } else { |
| 229 if ((stat = flash_program(fis_addr, fis_work_block, flash_block_size, | 241 if ((stat = cyg_flash_program(fis_addr, fis_work_block, flash_block_size, |
| 230 (void **)&err_addr)) != 0) { | 242 &err_addr)) != 0) { |
| 231 diag_printf("Error writing FIS directory at %p: %s\n", | 243 diag_printf("Error writing FIS directory at %p: %s\n", |
| 232 err_addr, flash_errmsg(stat)); | 244 err_addr, cyg_flash_errmsg(stat)); |
| 233 } | 245 } |
| 234 } | 246 } |
| 235 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 247 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 236 // Ensure [quietly] that the directory is locked after the update | 248 // Ensure [quietly] that the directory is locked after the update |
| 237 flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); | 249 cyg_flash_lock((void *)fis_addr, flash_block_size, &err_addr); |
| 238 #endif | 250 #endif |
| 239 } | 251 } |
| 240 | 252 |
| 241 static void | 253 static void |
| 242 fis_init(int argc, char *argv[]) | 254 fis_init(int argc, char *argv[]) |
| 243 { | 255 { |
| 244 int stat; | 256 int stat; |
| 245 struct fis_image_desc *img; | 257 struct fis_image_desc *img; |
| 246 void *err_addr; | 258 cyg_flashaddr_t err_addr; |
| 247 bool full_init = false; | 259 bool full_init = false; |
| 248 struct option_info opts[1]; | 260 struct option_info opts[1]; |
| 249 CYG_ADDRESS redboot_flash_start; | 261 CYG_ADDRESS redboot_flash_start; |
| 250 unsigned long redboot_image_size; | 262 unsigned long redboot_image_size; |
| 251 | 263 |
| 375 #if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET > CYGNUM_REDBOOT_FLASH_RESERVED_BASE) | 387 #if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET > CYGNUM_REDBOOT_FLASH_RESERVED_BASE) |
| 376 erase_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; | 388 erase_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; |
| 377 erase_size = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; | 389 erase_size = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; |
| 378 if ( erase_size > erase_start ) { | 390 if ( erase_size > erase_start ) { |
| 379 erase_size -= erase_start; | 391 erase_size -= erase_start; |
| 380 if ((stat = flash_erase((void *)erase_start, erase_size, | 392 if ((stat = cyg_flash_erase((void *)erase_start, erase_size, |
| 381 (void **)&err_addr)) != 0) { | 393 &err_addr)) != 0) { |
| 382 diag_printf(" initialization failed at %p: %s\n", | 394 diag_printf(" initialization failed at %p: %s\n", |
| 383 err_addr, flash_errmsg(stat)); | 395 err_addr, cyg_flash_errmsg(stat)); |
| 384 } | 396 } |
| 385 } | 397 } |
| 386 #endif | 398 #endif |
| 387 // second deal with the larger part in the main: | 399 // second deal with the larger part in the main: |
| 388 erase_start = redboot_flash_start; // high water of created images | 400 erase_start = redboot_flash_start; // high water of created images |
| 394 if (fis_addr > cfg_base) { | 406 if (fis_addr > cfg_base) { |
| 395 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data | 407 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data |
| 396 } else { | 408 } else { |
| 397 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data | 409 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data |
| 398 } | 410 } |
| 399 if ((stat = flash_erase((void *)erase_start, erase_size, | 411 if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) { |
| 400 (void **)&err_addr)) != 0) { | |
| 401 diag_printf(" initialization failed %p: %s\n", | 412 diag_printf(" initialization failed %p: %s\n", |
| 402 err_addr, flash_errmsg(stat)); | 413 err_addr, cyg_flash_errmsg(stat)); |
| 403 } | 414 } |
| 404 erase_start += (erase_size + flash_block_size); | 415 erase_start += (erase_size + flash_block_size); |
| 405 if (fis_addr > cfg_base) { | 416 if (fis_addr > cfg_base) { |
| 406 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data | 417 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data |
| 407 } else { | 418 } else { |
| 408 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data | 419 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data |
| 409 } | 420 } |
| 410 if ((stat = flash_erase((void *)erase_start, erase_size, | 421 if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) { |
| 411 (void **)&err_addr)) != 0) { | |
| 412 diag_printf(" initialization failed %p: %s\n", | 422 diag_printf(" initialization failed %p: %s\n", |
| 413 err_addr, flash_errmsg(stat)); | 423 err_addr, cyg_flash_errmsg(stat)); |
| 414 } | 424 } |
| 415 erase_start += (erase_size + flash_block_size); | 425 erase_start += (erase_size + flash_block_size); |
| 416 #else // !CYGSEM_REDBOOT_FLASH_CONFIG | 426 #else // !CYGSEM_REDBOOT_FLASH_CONFIG |
| 417 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data | 427 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data |
| 418 if ((stat = flash_erase((void *)erase_start, erase_size, | 428 if ((stat = cyg_flash_erase(erase_start, erase_size,&err_addr)) != 0) { |
| 419 (void **)&err_addr)) != 0) { | |
| 420 diag_printf(" initialization failed %p: %s\n", | 429 diag_printf(" initialization failed %p: %s\n", |
| 421 err_addr, flash_errmsg(stat)); | 430 err_addr, cyg_flash_errmsg(stat)); |
| 422 } | 431 } |
| 423 erase_start += (erase_size + flash_block_size); | 432 erase_start += (erase_size + flash_block_size); |
| 424 #endif | 433 #endif |
| 425 // Lastly, anything at the end | 434 // Lastly, anything at the end |
| 426 erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1; | 435 erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1; |
| 427 if ((stat = flash_erase((void *)erase_start, erase_size, | 436 if ((stat = cyg_flash_erase(erase_start, erase_size, |
| 428 (void **)&err_addr)) != 0) { | 437 &err_addr)) != 0) { |
| 429 diag_printf(" initialization failed at %p: %s\n", | 438 diag_printf(" initialization failed at %p: %s\n", |
| 430 err_addr, flash_errmsg(stat)); | 439 err_addr, cyg_flash_errmsg(stat)); |
| 431 } | 440 } |
| 432 #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS | 441 #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS |
| 433 // In this case, 'fis free' works by scanning for erased blocks. Since the | 442 // In this case, 'fis free' works by scanning for erased blocks. Since the |
| 434 // "-f" option was not supplied, there may be areas which are not used but | 443 // "-f" option was not supplied, there may be areas which are not used but |
| 435 // don't appear to be free since they are not erased - thus the warning | 444 // don't appear to be free since they are not erased - thus the warning |
| 446 struct fis_image_desc *img; | 455 struct fis_image_desc *img; |
| 447 int i, image_indx; | 456 int i, image_indx; |
| 448 bool show_cksums = false; | 457 bool show_cksums = false; |
| 449 bool show_datalen = false; | 458 bool show_datalen = false; |
| 450 struct option_info opts[2]; | 459 struct option_info opts[2]; |
| 451 void *err_addr; | 460 cyg_flashaddr_t err_addr; |
| 452 unsigned long last_addr, lowest_addr; | 461 unsigned long last_addr, lowest_addr; |
| 453 bool image_found; | 462 bool image_found; |
| 454 | 463 |
| 455 #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB | 464 #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB |
| 456 // FIXME: this is somewhat half-baked | 465 // FIXME: this is somewhat half-baked |
| 469 i = 1; | 478 i = 1; |
| 470 #endif | 479 #endif |
| 471 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { | 480 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { |
| 472 return; | 481 return; |
| 473 } | 482 } |
| 474 flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); | 483 cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); |
| 475 // Let diag_printf do the formatting in both cases, rather than counting | 484 // Let diag_printf do the formatting in both cases, rather than counting |
| 476 // cols by hand.... | 485 // cols by hand.... |
| 477 diag_printf("%-16s %-10s %-10s %-10s %-s\n", | 486 diag_printf("%-16s %-10s %-10s %-10s %-s\n", |
| 478 "Name","FLASH addr", | 487 "Name","FLASH addr", |
| 479 show_cksums ? "Checksum" : "Mem addr", | 488 show_cksums ? "Checksum" : "Mem addr", |
| 518 }; | 527 }; |
| 519 | 528 |
| 520 static int | 529 static int |
| 521 find_free(struct free_chunk *chunks) | 530 find_free(struct free_chunk *chunks) |
| 522 { | 531 { |
| 523 CYG_ADDRESS *fis_ptr, *fis_end; | 532 cyg_flashaddr_t err_addr; |
| 524 void *err_addr; | 533 cyg_flash_info_t info; |
| 525 struct fis_image_desc *img; | 534 struct fis_image_desc *img; |
| 526 int i, idx; | 535 int i=0, idx; |
| 527 int num_chunks = 1; | 536 int num_chunks = 0; |
| 528 | 537 int ret; |
| 529 // Do not search the area reserved for pre-RedBoot systems: | 538 |
| 530 fis_ptr = (CYG_ADDRESS *)((CYG_ADDRESS)flash_start + | 539 do { |
| 531 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + | 540 ret = cyg_flash_get_info(i, &info); |
| 532 CYGBLD_REDBOOT_MIN_IMAGE_SIZE); | 541 if (ret == CYG_FLASH_ERR_OK) { |
| 533 fis_end = (CYG_ADDRESS *)flash_end; | 542 if (i == 0 ) { |
| 534 chunks[num_chunks-1].start = (CYG_ADDRESS)fis_ptr; | 543 // Do not search the area reserved for pre-RedBoot systems: |
| 535 chunks[num_chunks-1].end = (CYG_ADDRESS)fis_end; | 544 chunks[num_chunks].start = (info.start + |
| 536 flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); | 545 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + |
| 546 CYGBLD_REDBOOT_MIN_IMAGE_SIZE); | |
| 547 chunks[num_chunks].end = info.end; | |
| 548 num_chunks++; | |
| 549 } else { // Contiguous flash? If so collapse the chunks together. | |
| 550 if (chunks[num_chunks-1].end == (info.start -1)) { | |
| 551 chunks[num_chunks-1].end = info.end; | |
| 552 } else { | |
| 553 chunks[num_chunks].start = info.start; | |
| 554 chunks[num_chunks].end = info.end; | |
| 555 num_chunks++; | |
| 556 } | |
| 557 } | |
| 558 } | |
| 559 i++; | |
| 560 } while (ret != CYG_FLASH_ERR_INVALID); | |
| 561 | |
| 562 cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); | |
| 537 img = (struct fis_image_desc *) fis_work_block; | 563 img = (struct fis_image_desc *) fis_work_block; |
| 538 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { | 564 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { |
| 539 if (img->name[0] != (unsigned char)0xFF) { | 565 if (img->name[0] != (unsigned char)0xFF) { |
| 540 // Figure out which chunk this is in and split it | 566 // Figure out which chunk this is in and split it |
| 541 for (idx = 0; idx < num_chunks; idx++) { | 567 for (idx = 0; idx < num_chunks; idx++) { |
| 553 } | 579 } |
| 554 } else if ((img->flash_base+img->size) == chunks[idx].end) { | 580 } else if ((img->flash_base+img->size) == chunks[idx].end) { |
| 555 chunks[idx].end = img->flash_base; | 581 chunks[idx].end = img->flash_base; |
| 556 } else { | 582 } else { |
| 557 // Split chunk into two parts | 583 // Split chunk into two parts |
| 558 if ((img->flash_base+img->size) < (CYG_ADDRESS)fis_end) { | 584 chunks[idx+1].start = img->flash_base + img->size; |
| 559 chunks[idx+1].start = img->flash_base + img->size; | 585 chunks[idx+1].end = chunks[idx].end; |
| 560 chunks[idx+1].end = chunks[idx].end; | 586 if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) { |
| 561 if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) { | 587 diag_printf("Warning: too many free chunks\n"); |
| 562 diag_printf("Warning: too many free chunks\n"); | 588 return num_chunks; |
| 563 return num_chunks; | |
| 564 } | |
| 565 } | 589 } |
| 566 chunks[idx].end = img->flash_base; | 590 chunks[idx].end = img->flash_base; |
| 567 } | 591 } |
| 568 break; | 592 break; |
| 569 } | 593 } |
| 698 bool entry_addr_set = false; | 722 bool entry_addr_set = false; |
| 699 bool flash_addr_set = false; | 723 bool flash_addr_set = false; |
| 700 bool length_set = false; | 724 bool length_set = false; |
| 701 bool img_size_set = false; | 725 bool img_size_set = false; |
| 702 bool no_copy = false; | 726 bool no_copy = false; |
| 703 void *err_addr; | 727 cyg_flashaddr_t err_addr; |
| 704 struct fis_image_desc *img = NULL; | 728 struct fis_image_desc *img = NULL; |
| 705 bool defaults_assumed; | 729 bool defaults_assumed; |
| 706 struct option_info opts[7]; | 730 struct option_info opts[7]; |
| 707 bool prog_ok = true; | 731 bool prog_ok = true; |
| 708 | 732 size_t block_size; |
| 733 | |
| 709 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | 734 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, |
| 710 (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); | 735 (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); |
| 711 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, | 736 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, |
| 712 (void *)&exec_addr, (bool *)&exec_addr_set, "ram base address"); | 737 (void *)&exec_addr, (bool *)&exec_addr_set, "ram base address"); |
| 713 init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, | 738 init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, |
| 724 { | 749 { |
| 725 fis_usage("invalid arguments"); | 750 fis_usage("invalid arguments"); |
| 726 return; | 751 return; |
| 727 } | 752 } |
| 728 | 753 |
| 729 flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); | 754 cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); |
| 730 defaults_assumed = false; | 755 defaults_assumed = false; |
| 731 if (name) { | 756 if (name) { |
| 732 // Search existing files to acquire defaults for params not specified: | 757 // Search existing files to acquire defaults for params not specified: |
| 733 img = fis_lookup(name, NULL); | 758 img = fis_lookup(name, NULL); |
| 734 if (img) { | 759 if (img) { |
| 779 } | 804 } |
| 780 if (!img_size_set) { | 805 if (!img_size_set) { |
| 781 img_size = length; | 806 img_size = length; |
| 782 } | 807 } |
| 783 // 'length' is size of FLASH image, 'img_size' is actual data size | 808 // 'length' is size of FLASH image, 'img_size' is actual data size |
| 784 // Round up length to FLASH block size | |
| 785 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken | |
| 786 length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; | |
| 787 if (length < img_size) { | |
| 788 diag_printf("Invalid FLASH image size/length combination\n"); | |
| 789 return; | |
| 790 } | |
| 791 #endif | |
| 792 if (flash_addr_set && | |
| 793 ((stat = flash_verify_addr((void *)flash_addr)) || | |
| 794 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | |
| 795 _show_invalid_flash_address(flash_addr, stat); | |
| 796 return; | |
| 797 } | |
| 798 if (flash_addr_set && ((flash_addr & (flash_block_size-1)) != 0)) { | |
| 799 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | |
| 800 diag_printf(" must be 0x%x aligned\n", flash_block_size); | |
| 801 return; | |
| 802 } | |
| 803 if (strlen(name) >= sizeof(img->name)) { | 809 if (strlen(name) >= sizeof(img->name)) { |
| 804 diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); | 810 diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); |
| 805 return; | 811 return; |
| 806 } | 812 } |
| 807 if (!no_copy) { | 813 if (!no_copy) { |
| 812 } | 818 } |
| 813 if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { | 819 if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { |
| 814 diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); | 820 diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); |
| 815 return; | 821 return; |
| 816 } | 822 } |
| 817 } | 823 flash_addr_set = true; |
| 824 } | |
| 825 if (flash_addr_set) { | |
| 826 block_size = cyg_flash_block_size(flash_addr + length); | |
| 827 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken | |
| 828 length = ((length + block_size - 1) / block_size) * block_size; | |
| 829 if (length < img_size) { | |
| 830 diag_printf("Invalid FLASH image size/length combination\n"); | |
| 831 return; | |
| 832 } | |
| 833 #endif | |
| 834 if ((stat = cyg_flash_verify_addr(flash_addr)) || | |
| 835 (stat = cyg_flash_verify_addr((flash_addr+length-1)))) { | |
| 836 _show_invalid_flash_address(flash_addr, stat); | |
| 837 return; | |
| 838 } | |
| 839 block_size = cyg_flash_block_size(flash_addr); | |
| 840 if ((flash_addr & (flash_block_size-1)) != 0) { | |
| 841 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | |
| 842 diag_printf(" must be 0x%x aligned\n", flash_block_size); | |
| 843 return; | |
| 844 } | |
| 845 } | |
| 846 | |
| 818 // First, see if the image by this name has agreable properties | 847 // First, see if the image by this name has agreable properties |
| 819 if (img) { | 848 if (img) { |
| 820 if (flash_addr_set && (img->flash_base != flash_addr)) { | 849 if (flash_addr_set && (img->flash_base != flash_addr)) { |
| 821 diag_printf("Image found, but flash address (%p)\n" | 850 diag_printf("Image found, but flash address (%p)\n" |
| 822 " is incorrect (present image location %p)\n", | 851 " is incorrect (present image location %p)\n", |
| 861 diag_printf("Invalid FLASH address - not free!\n"); | 890 diag_printf("Invalid FLASH address - not free!\n"); |
| 862 return; | 891 return; |
| 863 } | 892 } |
| 864 } | 893 } |
| 865 #endif | 894 #endif |
| 866 // If not image by that name, try and find an empty slot | 895 // If no image by that name, try and find an empty slot |
| 867 img = (struct fis_image_desc *)fis_work_block; | 896 img = (struct fis_image_desc *)fis_work_block; |
| 868 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { | 897 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { |
| 869 if (img->name[0] == (unsigned char)0xFF) { | 898 if (img->name[0] == (unsigned char)0xFF) { |
| 870 break; | 899 break; |
| 871 } | 900 } |
| 872 } | 901 } |
| 873 } | 902 } |
| 874 if (!no_copy) { | 903 if (!no_copy) { |
| 875 // Safety check - make sure the address range is not within the code we're running | 904 // Safety check - make sure the address range is not within the code we're running |
| 876 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { | 905 if (cyg_flash_code_overlaps(flash_addr, (flash_addr+img_size-1))) { |
| 877 diag_printf("Can't program this region - contains code in use!\n"); | 906 diag_printf("Can't program this region - contains code in use!\n"); |
| 878 return; | 907 return; |
| 879 } | 908 } |
| 880 if (prog_ok) { | 909 if (prog_ok) { |
| 881 // Erase area to be programmed | 910 // Erase area to be programmed |
| 882 if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 911 if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) { |
| 883 diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); | 912 diag_printf("Can't erase region at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); |
| 884 prog_ok = false; | 913 prog_ok = false; |
| 885 } | 914 } |
| 886 } | 915 } |
| 887 if (prog_ok) { | 916 if (prog_ok) { |
| 888 // Now program it | 917 // Now program it |
| 889 if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { | 918 if ((stat = cyg_flash_program(flash_addr, (void *)mem_addr, img_size, |
| 890 diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); | 919 &err_addr)) != 0) { |
| 920 diag_printf("Can't program region at %p: %s\n", err_addr, | |
| 921 cyg_flash_errmsg(stat)); | |
| 891 prog_ok = false; | 922 prog_ok = false; |
| 892 } | 923 } |
| 893 } | 924 } |
| 894 } | 925 } |
| 895 if (prog_ok) { | 926 if (prog_ok) { |
| 917 static void | 948 static void |
| 918 fis_delete(int argc, char *argv[]) | 949 fis_delete(int argc, char *argv[]) |
| 919 { | 950 { |
| 920 char *name; | 951 char *name; |
| 921 int num_reserved, i, stat; | 952 int num_reserved, i, stat; |
| 922 void *err_addr; | 953 cyg_flashaddr_t err_addr; |
| 923 struct fis_image_desc *img; | 954 struct fis_image_desc *img; |
| 924 | 955 |
| 925 if (!scan_opts(argc, argv, 2, 0, 0, (void *)&name, OPTION_ARG_TYPE_STR, "image name")) | 956 if (!scan_opts(argc, argv, 2, 0, 0, (void *)&name, OPTION_ARG_TYPE_STR, "image name")) |
| 926 { | 957 { |
| 927 fis_usage("invalid arguments"); | 958 fis_usage("invalid arguments"); |
| 965 } else { | 996 } else { |
| 966 diag_printf("No image '%s' found\n", name); | 997 diag_printf("No image '%s' found\n", name); |
| 967 return; | 998 return; |
| 968 } | 999 } |
| 969 // Erase Data blocks (free space) | 1000 // Erase Data blocks (free space) |
| 970 if ((stat = flash_erase((void *)img->flash_base, img->size, (void **)&err_addr)) != 0) { | 1001 if ((stat = cyg_flash_erase(img->flash_base, img->size, &err_addr)) != 0) { |
| 971 diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); | 1002 diag_printf("Error erasing at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); |
| 972 } else { | 1003 } else { |
| 973 img->name[0] = (unsigned char)0xFF; | 1004 img->name[0] = (unsigned char)0xFF; |
| 974 fis_update_directory(); | 1005 fis_update_directory(); |
| 975 } | 1006 } |
| 976 } | 1007 } |
| 989 #endif | 1020 #endif |
| 990 int num_options; | 1021 int num_options; |
| 991 #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) | 1022 #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) |
| 992 bool decompress = false; | 1023 bool decompress = false; |
| 993 #endif | 1024 #endif |
| 994 void *err_addr; | 1025 cyg_flashaddr_t err_addr; |
| 995 | 1026 |
| 996 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | 1027 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, |
| 997 (void *)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); | 1028 (void *)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); |
| 998 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, | 1029 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, |
| 999 (void *)&show_cksum, (bool *)0, "display checksum"); | 1030 (void *)&show_cksum, (bool *)0, "display checksum"); |
| 1053 // Set load address/top | 1084 // Set load address/top |
| 1054 load_address = mem_addr; | 1085 load_address = mem_addr; |
| 1055 load_address_end = (unsigned long)p->out_buf; | 1086 load_address_end = (unsigned long)p->out_buf; |
| 1056 | 1087 |
| 1057 // Reload fis directory | 1088 // Reload fis directory |
| 1058 flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); | 1089 cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); |
| 1059 } else // dangling block | 1090 } else // dangling block |
| 1060 #endif | 1091 #endif |
| 1061 { | 1092 { |
| 1062 flash_read((void *)img->flash_base, (void *)mem_addr, img->data_length, (void **)&err_addr); | 1093 cyg_flash_read(img->flash_base, (void *)mem_addr, img->data_length, |
| 1094 &err_addr); | |
| 1063 | 1095 |
| 1064 // Set load address/top | 1096 // Set load address/top |
| 1065 load_address = mem_addr; | 1097 load_address = mem_addr; |
| 1066 load_address_end = mem_addr + img->data_length; | 1098 load_address_end = mem_addr + img->data_length; |
| 1067 } | 1099 } |
| 1091 unsigned long length; | 1123 unsigned long length; |
| 1092 CYG_ADDRESS mem_addr, flash_addr; | 1124 CYG_ADDRESS mem_addr, flash_addr; |
| 1093 bool mem_addr_set = false; | 1125 bool mem_addr_set = false; |
| 1094 bool flash_addr_set = false; | 1126 bool flash_addr_set = false; |
| 1095 bool length_set = false; | 1127 bool length_set = false; |
| 1096 void *err_addr; | 1128 cyg_flashaddr_t err_addr; |
| 1097 struct option_info opts[3]; | 1129 struct option_info opts[3]; |
| 1098 bool prog_ok; | 1130 bool prog_ok; |
| 1099 | 1131 size_t block_size; |
| 1132 | |
| 1100 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | 1133 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, |
| 1101 (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); | 1134 (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); |
| 1102 init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM, | 1135 init_opts(&opts[1], 'f', true, OPTION_ARG_TYPE_NUM, |
| 1103 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); | 1136 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); |
| 1104 init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, | 1137 init_opts(&opts[2], 'l', true, OPTION_ARG_TYPE_NUM, |
| 1113 fis_usage("required parameter missing"); | 1146 fis_usage("required parameter missing"); |
| 1114 return; | 1147 return; |
| 1115 } | 1148 } |
| 1116 | 1149 |
| 1117 // Round up length to FLASH block size | 1150 // Round up length to FLASH block size |
| 1151 block_size = cyg_flash_block_size(flash_addr + length); | |
| 1118 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken | 1152 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken |
| 1119 length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; | 1153 length = ((length + block_size - 1) / block_size) * block_size; |
| 1120 #endif | 1154 #endif |
| 1121 if (flash_addr_set && | 1155 if ((stat = cyg_flash_verify_addr(flash_addr)) || |
| 1122 ((stat = flash_verify_addr((void *)flash_addr)) || | 1156 (stat = cyg_flash_verify_addr((flash_addr+length-1)))) { |
| 1123 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | |
| 1124 _show_invalid_flash_address(flash_addr, stat); | 1157 _show_invalid_flash_address(flash_addr, stat); |
| 1125 return; | 1158 return; |
| 1126 } | 1159 } |
| 1127 if (flash_addr_set && flash_addr & (flash_block_size-1)) { | 1160 |
| 1161 block_size = cyg_flash_block_size(flash_addr); | |
| 1162 if (flash_addr & (block_size-1)) { | |
| 1128 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | 1163 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); |
| 1129 diag_printf(" must be 0x%x aligned\n", flash_block_size); | 1164 diag_printf(" must be 0x%x aligned\n", block_size); |
| 1130 return; | 1165 return; |
| 1131 } | 1166 } |
| 1132 if ((mem_addr < (CYG_ADDRESS)ram_start) || | 1167 if ((mem_addr < (CYG_ADDRESS)ram_start) || |
| 1133 ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) { | 1168 ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) { |
| 1134 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); | 1169 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); |
| 1135 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); | 1170 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); |
| 1136 } | 1171 } |
| 1137 // Safety check - make sure the address range is not within the code we're running | 1172 // Safety check - make sure the address range is not within the code we're running |
| 1138 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { | 1173 if (cyg_flash_code_overlaps(flash_addr, (flash_addr+length-1))) { |
| 1139 diag_printf("Can't program this region - contains code in use!\n"); | 1174 diag_printf("Can't program this region - contains code in use!\n"); |
| 1140 return; | 1175 return; |
| 1141 } | 1176 } |
| 1142 if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p", | 1177 if (!verify_action("* CAUTION * about to program FLASH\n at %p..%p from %p", |
| 1143 (void *)flash_addr, (void *)(flash_addr+length-1), | 1178 (void *)flash_addr, (void *)(flash_addr+length-1), |
| 1145 return; // The guy gave up | 1180 return; // The guy gave up |
| 1146 } | 1181 } |
| 1147 prog_ok = true; | 1182 prog_ok = true; |
| 1148 if (prog_ok) { | 1183 if (prog_ok) { |
| 1149 // Erase area to be programmed | 1184 // Erase area to be programmed |
| 1150 if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 1185 if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) { |
| 1151 diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); | 1186 diag_printf("Can't erase region at %p: %s\n", err_addr, |
| 1187 cyg_flash_errmsg(stat)); | |
| 1152 prog_ok = false; | 1188 prog_ok = false; |
| 1153 } | 1189 } |
| 1154 } | 1190 } |
| 1155 if (prog_ok) { | 1191 if (prog_ok) { |
| 1156 // Now program it | 1192 // Now program it |
| 1157 if ((stat = flash_program((void *)flash_addr, (void *)mem_addr, length, (void **)&err_addr)) != 0) { | 1193 if ((stat = cyg_flash_program(flash_addr, (void *)mem_addr, length, |
| 1158 diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); | 1194 &err_addr)) != 0) { |
| 1195 diag_printf("Can't program region at %p: %s\n", err_addr, | |
| 1196 cyg_flash_errmsg(stat)); | |
| 1159 prog_ok = false; | 1197 prog_ok = false; |
| 1160 } | 1198 } |
| 1161 } | 1199 } |
| 1162 } | 1200 } |
| 1163 | 1201 |
| 1167 int stat; | 1205 int stat; |
| 1168 unsigned long length; | 1206 unsigned long length; |
| 1169 CYG_ADDRESS flash_addr; | 1207 CYG_ADDRESS flash_addr; |
| 1170 bool flash_addr_set = false; | 1208 bool flash_addr_set = false; |
| 1171 bool length_set = false; | 1209 bool length_set = false; |
| 1172 void *err_addr; | 1210 cyg_flashaddr_t err_addr; |
| 1173 struct option_info opts[2]; | 1211 struct option_info opts[2]; |
| 1174 | 1212 |
| 1175 init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, | 1213 init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, |
| 1176 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); | 1214 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); |
| 1177 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, | 1215 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, |
| 1185 if (!flash_addr_set || !length_set) { | 1223 if (!flash_addr_set || !length_set) { |
| 1186 fis_usage("missing argument"); | 1224 fis_usage("missing argument"); |
| 1187 return; | 1225 return; |
| 1188 } | 1226 } |
| 1189 if (flash_addr_set && | 1227 if (flash_addr_set && |
| 1190 ((stat = flash_verify_addr((void *)flash_addr)) || | 1228 ((stat = cyg_flash_verify_addr(flash_addr)) || |
| 1191 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 1229 (stat = cyg_flash_verify_addr((flash_addr+length-1))))) { |
| 1192 _show_invalid_flash_address(flash_addr, stat); | 1230 _show_invalid_flash_address(flash_addr, stat); |
| 1193 return; | 1231 return; |
| 1194 } | 1232 } |
| 1195 if (flash_addr_set && flash_addr & (flash_block_size-1)) { | 1233 if (flash_addr_set && flash_addr & (cyg_flash_block_size(flash_addr)-1)) { |
| 1196 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | 1234 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); |
| 1197 diag_printf(" must be 0x%x aligned\n", flash_block_size); | 1235 diag_printf(" must be 0x%x aligned\n", flash_block_size); |
| 1198 return; | 1236 return; |
| 1199 } | 1237 } |
| 1200 // Safety check - make sure the address range is not within the code we're running | 1238 // Safety check - make sure the address range is not within the code we're running |
| 1201 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { | 1239 if (cyg_flash_code_overlaps(flash_addr, (flash_addr+length-1))) { |
| 1202 diag_printf("Can't erase this region - contains code in use!\n"); | 1240 diag_printf("Can't erase this region - contains code in use!\n"); |
| 1203 return; | 1241 return; |
| 1204 } | 1242 } |
| 1205 if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 1243 if ((stat = cyg_flash_erase(flash_addr, length, &err_addr)) != 0) { |
| 1206 diag_printf("Error erasing at %p: %s\n", err_addr, flash_errmsg(stat)); | 1244 diag_printf("Error erasing at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); |
| 1207 } | 1245 } |
| 1208 } | 1246 } |
| 1209 | 1247 |
| 1210 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING | 1248 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING |
| 1211 | 1249 |
| 1216 int stat; | 1254 int stat; |
| 1217 unsigned long length; | 1255 unsigned long length; |
| 1218 CYG_ADDRESS flash_addr; | 1256 CYG_ADDRESS flash_addr; |
| 1219 bool flash_addr_set = false; | 1257 bool flash_addr_set = false; |
| 1220 bool length_set = false; | 1258 bool length_set = false; |
| 1221 void *err_addr; | 1259 cyg_flashaddr_t err_addr; |
| 1222 struct option_info opts[2]; | 1260 struct option_info opts[2]; |
| 1223 | 1261 |
| 1224 init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, | 1262 init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, |
| 1225 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); | 1263 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); |
| 1226 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, | 1264 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, |
| 1244 } else if (!flash_addr_set || !length_set) { | 1282 } else if (!flash_addr_set || !length_set) { |
| 1245 fis_usage("missing argument"); | 1283 fis_usage("missing argument"); |
| 1246 return; | 1284 return; |
| 1247 } | 1285 } |
| 1248 if (flash_addr_set && | 1286 if (flash_addr_set && |
| 1249 ((stat = flash_verify_addr((void *)flash_addr)) || | 1287 ((stat = cyg_flash_verify_addr(flash_addr)) || |
| 1250 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 1288 (stat = cyg_flash_verify_addr((flash_addr+length-1))))) { |
| 1251 _show_invalid_flash_address(flash_addr, stat); | 1289 _show_invalid_flash_address(flash_addr, stat); |
| 1252 return; | 1290 return; |
| 1253 } | 1291 } |
| 1254 if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 1292 if ((stat = cyg_flash_lock(flash_addr, length, &err_addr)) != 0) { |
| 1255 diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); | 1293 diag_printf("Error locking at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); |
| 1256 } | 1294 } |
| 1257 } | 1295 } |
| 1258 | 1296 |
| 1259 static void | 1297 static void |
| 1260 fis_unlock(int argc, char *argv[]) | 1298 fis_unlock(int argc, char *argv[]) |
| 1263 int stat; | 1301 int stat; |
| 1264 unsigned long length; | 1302 unsigned long length; |
| 1265 CYG_ADDRESS flash_addr; | 1303 CYG_ADDRESS flash_addr; |
| 1266 bool flash_addr_set = false; | 1304 bool flash_addr_set = false; |
| 1267 bool length_set = false; | 1305 bool length_set = false; |
| 1268 void *err_addr; | 1306 cyg_flashaddr_t err_addr; |
| 1269 struct option_info opts[2]; | 1307 struct option_info opts[2]; |
| 1270 | 1308 |
| 1271 init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, | 1309 init_opts(&opts[0], 'f', true, OPTION_ARG_TYPE_NUM, |
| 1272 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); | 1310 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); |
| 1273 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, | 1311 init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM, |
| 1290 } else if (!flash_addr_set || !length_set) { | 1328 } else if (!flash_addr_set || !length_set) { |
| 1291 fis_usage("missing argument"); | 1329 fis_usage("missing argument"); |
| 1292 return; | 1330 return; |
| 1293 } | 1331 } |
| 1294 if (flash_addr_set && | 1332 if (flash_addr_set && |
| 1295 ((stat = flash_verify_addr((void *)flash_addr)) || | 1333 ((stat = cyg_flash_verify_addr(flash_addr)) || |
| 1296 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 1334 (stat = cyg_flash_verify_addr((flash_addr+length-1))))) { |
| 1297 _show_invalid_flash_address(flash_addr, stat); | 1335 _show_invalid_flash_address(flash_addr, stat); |
| 1298 return; | 1336 return; |
| 1299 } | 1337 } |
| 1300 | 1338 |
| 1301 if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 1339 if ((stat = cyg_flash_unlock(flash_addr, length, &err_addr)) != 0) { |
| 1302 diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); | 1340 diag_printf("Error unlocking at %p: %s\n", err_addr, cyg_flash_errmsg(stat)); |
| 1303 } | 1341 } |
| 1304 } | 1342 } |
| 1305 #endif | 1343 #endif |
| 1306 | 1344 |
| 1307 // This is set non-zero if the FLASH subsystem has successfully been initialized | 1345 // This is set non-zero if the FLASH subsystem has successfully been initialized |
| 1308 int __flash_init = 0; | 1346 int __flash_init = 0; |
| 1309 | 1347 |
| 1310 void | 1348 void |
| 1311 _flash_info(void) | 1349 _flash_info(void) |
| 1312 { | 1350 { |
| 1351 cyg_uint32 i=0,j; | |
| 1352 cyg_flash_info_t info; | |
| 1353 int ret; | |
| 1354 | |
| 1313 if (!__flash_init) return; | 1355 if (!__flash_init) return; |
| 1314 diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", | 1356 |
| 1315 flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, (void *)flash_block_size); | 1357 do { |
| 1358 ret = cyg_flash_get_info(i, &info); | |
| 1359 if (ret == CYG_FLASH_ERR_OK) { | |
| 1360 diag_printf("FLASH: %p - %p ", info.start, info.end); | |
| 1361 for (j=0;j < info.num_block_infos; j++) { | |
| 1362 diag_printf("%d x 0x%x blocks ", | |
| 1363 info.block_info[j].blocks, | |
| 1364 info.block_info[j].block_size); | |
| 1365 } | |
| 1366 diag_printf("\n"); | |
| 1367 } | |
| 1368 i++; | |
| 1369 } while (ret != CYG_FLASH_ERR_INVALID); | |
| 1316 } | 1370 } |
| 1317 | 1371 |
| 1318 bool | 1372 bool |
| 1319 do_flash_init(void) | 1373 do_flash_init(void) |
| 1320 { | 1374 { |
| 1321 int stat; | 1375 int stat; |
| 1322 void *err_addr; | 1376 cyg_flashaddr_t err_addr; |
| 1323 | 1377 |
| 1324 if (!__flash_init) { | 1378 if (!__flash_init) { |
| 1325 __flash_init = 1; | 1379 __flash_init = 1; |
| 1326 if ((stat = flash_init(diag_printf)) != 0) { | 1380 |
| 1327 diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); | 1381 if ((stat = cyg_flash_init(diag_printf)) != 0) { |
| 1382 diag_printf("FLASH: driver init failed: %s\n", cyg_flash_errmsg(stat)); | |
| 1328 return false; | 1383 return false; |
| 1329 } | 1384 } |
| 1330 flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); | 1385 |
| 1386 if ((stat = cyg_flash_get_limits(&flash_start, &flash_end)) != 0) { | |
| 1387 diag_printf("FLASH: driver init failed: %s\n", | |
| 1388 cyg_flash_errmsg(stat)); | |
| 1389 return false; | |
| 1390 } | |
| 1391 | |
| 1331 // Keep 'end' address as last valid location, to avoid wrap around problems | 1392 // Keep 'end' address as last valid location, to avoid wrap around problems |
| 1332 flash_end = (void *)((CYG_ADDRESS)flash_end - 1); | 1393 flash_end = ((CYG_ADDRESS)flash_end - 1); |
| 1333 flash_get_block_info(&flash_block_size, &flash_num_blocks); | 1394 cyg_flash_get_block_info(&flash_block_size, &flash_num_blocks); |
| 1395 | |
| 1334 #ifdef CYGOPT_REDBOOT_FIS | 1396 #ifdef CYGOPT_REDBOOT_FIS |
| 1335 fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; | 1397 fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; |
| 1398 | |
| 1399 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken | |
| 1336 fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size; | 1400 fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size; |
| 1401 #endif | |
| 1337 # if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER) | 1402 # if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER) |
| 1338 fis_work_block = fis_zlib_common_buffer; | 1403 fis_work_block = fis_zlib_common_buffer; |
| 1339 if(CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) { | 1404 if(CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) { |
| 1340 diag_printf("FLASH: common buffer too small\n"); | 1405 diag_printf("FLASH: common buffer too small\n"); |
| 1341 return false; | 1406 return false; |
| 1342 } | 1407 } |
| 1343 # else | 1408 # else |
| 1344 workspace_end = (unsigned char *)(workspace_end-fisdir_size); | 1409 workspace_end = (unsigned char *)(workspace_end-fisdir_size); |
| 1345 fis_work_block = workspace_end; | 1410 fis_work_block = workspace_end; |
| 1346 # endif | 1411 # endif |
| 1412 | |
| 1347 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { | 1413 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { |
| 1348 fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + | 1414 fis_addr = ((CYG_ADDRESS)flash_end + 1 + |
| 1349 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); | 1415 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); |
| 1350 } else { | 1416 } else { |
| 1351 fis_addr = (void *)((CYG_ADDRESS)flash_start + | 1417 fis_addr = ((CYG_ADDRESS)flash_start + |
| 1352 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); | 1418 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); |
| 1353 } | 1419 } |
| 1420 | |
| 1354 if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) { | 1421 if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) { |
| 1355 diag_printf("FIS directory doesn't fit\n"); | 1422 diag_printf("FIS directory doesn't fit\n"); |
| 1356 return false; | 1423 return false; |
| 1357 } | 1424 } |
| 1358 flash_read(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); | 1425 |
| 1359 #endif | 1426 cyg_flash_read(fis_addr, fis_work_block, fisdir_size, &err_addr); |
| 1360 } | 1427 #endif |
| 1428 } | |
| 1429 | |
| 1361 return true; | 1430 return true; |
| 1362 } | 1431 } |
| 1363 | 1432 |
| 1364 // Wrapper to avoid compiler warnings | 1433 // Wrapper to avoid compiler warnings |
| 1365 static void | 1434 static void |
