Mercurial > flash_v2
comparison packages/redboot/current/src/flash.c @ 184:022f1e506033
Merge from eCos master repository on 2001-10-02-17:59:22-BST
| author | jlarmour |
|---|---|
| date | Tue, 02 Oct 2001 18:28:24 +0000 |
| parents | 9160a8005d76 |
| children | 678094f34118 |
comparison
equal
deleted
inserted
replaced
| 183:9160a8005d76 | 184:022f1e506033 |
|---|---|
| 143 extern struct cmd __FIS_cmds_TAB__[], __FIS_cmds_TAB_END__; | 143 extern struct cmd __FIS_cmds_TAB__[], __FIS_cmds_TAB_END__; |
| 144 | 144 |
| 145 // Local data used by these routines | 145 // Local data used by these routines |
| 146 static void *flash_start, *flash_end; | 146 static void *flash_start, *flash_end; |
| 147 static int block_size, blocks; | 147 static int block_size, blocks; |
| 148 #ifdef CYGOPT_REDBOOT_FIS | |
| 148 static void *fis_work_block; | 149 static void *fis_work_block; |
| 149 static int fisdir_size; // Size of FIS directory. Note: zero if FIS not enabled | 150 static void *fis_addr; |
| 151 static int fisdir_size; // Size of FIS directory. | |
| 152 #endif | |
| 150 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 153 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 151 static void *cfg_base; // Location in Flash of config data | 154 static void *cfg_base; // Location in Flash of config data |
| 152 static int cfg_size; // Length of config data - rounded to Flash block size | 155 static int cfg_size; // Length of config data - rounded to Flash block size |
| 153 // Prototypes for local functions | 156 // Prototypes for local functions |
| 154 static unsigned char *flash_lookup_config(char *key); | 157 static unsigned char *flash_lookup_config(char *key); |
| 159 { | 162 { |
| 160 diag_printf("*** invalid 'fis' command: %s\n", why); | 163 diag_printf("*** invalid 'fis' command: %s\n", why); |
| 161 cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); | 164 cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); |
| 162 } | 165 } |
| 163 | 166 |
| 167 static void | |
| 168 _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) | |
| 169 { | |
| 170 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); | |
| 171 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | |
| 172 } | |
| 173 | |
| 164 #ifdef CYGOPT_REDBOOT_FIS | 174 #ifdef CYGOPT_REDBOOT_FIS |
| 165 struct fis_image_desc * | 175 struct fis_image_desc * |
| 166 fis_lookup(char *name) | 176 fis_lookup(char *name) |
| 167 { | 177 { |
| 168 int i; | 178 int i; |
| 169 void *fis_addr; | |
| 170 struct fis_image_desc *img; | 179 struct fis_image_desc *img; |
| 171 | 180 |
| 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 } | |
| 179 memcpy(fis_work_block, fis_addr, block_size); | |
| 180 img = (struct fis_image_desc *)fis_work_block; | 181 img = (struct fis_image_desc *)fis_work_block; |
| 181 for (i = 0; i < block_size/sizeof(*img); i++, img++) { | 182 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 182 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 183 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 183 return img; | 184 return img; |
| 184 } | 185 } |
| 189 static void | 190 static void |
| 190 fis_init(int argc, char *argv[]) | 191 fis_init(int argc, char *argv[]) |
| 191 { | 192 { |
| 192 int stat; | 193 int stat; |
| 193 struct fis_image_desc *img; | 194 struct fis_image_desc *img; |
| 194 void *fis_base, *err_addr; | 195 void *err_addr; |
| 195 bool full_init = false; | 196 bool full_init = false; |
| 196 struct option_info opts[1]; | 197 struct option_info opts[1]; |
| 197 unsigned long redboot_image_size, redboot_flash_start; | 198 CYG_ADDRESS redboot_flash_start; |
| 199 unsigned long redboot_image_size; | |
| 198 | 200 |
| 199 init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, | 201 init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, |
| 200 (void **)&full_init, (bool *)0, "full initialization, erases all of flash"); | 202 (void **)&full_init, (bool *)0, "full initialization, erases all of flash"); |
| 201 if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) | 203 if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) |
| 202 { | 204 { |
| 215 // Create a pseudo image for RedBoot | 217 // Create a pseudo image for RedBoot |
| 216 img = (struct fis_image_desc *)fis_work_block; | 218 img = (struct fis_image_desc *)fis_work_block; |
| 217 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | 219 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE |
| 218 memset(img, 0, sizeof(*img)); | 220 memset(img, 0, sizeof(*img)); |
| 219 strcpy(img->name, "(reserved)"); | 221 strcpy(img->name, "(reserved)"); |
| 220 img->flash_base = (unsigned long)flash_start; | 222 img->flash_base = (CYG_ADDRESS)flash_start; |
| 221 img->mem_base = (unsigned long)flash_start; | 223 img->mem_base = (CYG_ADDRESS)flash_start; |
| 222 img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE; | 224 img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE; |
| 223 img++; | 225 img++; |
| 224 #endif | 226 #endif |
| 225 redboot_flash_start = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; | 227 redboot_flash_start = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; |
| 226 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT | 228 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT |
| 227 memset(img, 0, sizeof(*img)); | 229 memset(img, 0, sizeof(*img)); |
| 228 strcpy(img->name, "RedBoot"); | 230 strcpy(img->name, "RedBoot"); |
| 229 img->flash_base = redboot_flash_start; | 231 img->flash_base = redboot_flash_start; |
| 230 img->mem_base = redboot_flash_start; | 232 img->mem_base = redboot_flash_start; |
| 233 redboot_flash_start += redboot_image_size; | 235 redboot_flash_start += redboot_image_size; |
| 234 #endif | 236 #endif |
| 235 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST | 237 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST |
| 236 #ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET | 238 #ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET |
| 237 // Take care to place the POST entry at the right offset: | 239 // Take care to place the POST entry at the right offset: |
| 238 redboot_flash_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; | 240 redboot_flash_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; |
| 239 #endif | 241 #endif |
| 240 memset(img, 0, sizeof(*img)); | 242 memset(img, 0, sizeof(*img)); |
| 241 strcpy(img->name, "RedBoot[post]"); | 243 strcpy(img->name, "RedBoot[post]"); |
| 242 img->flash_base = redboot_flash_start; | 244 img->flash_base = redboot_flash_start; |
| 243 img->mem_base = redboot_flash_start; | 245 img->mem_base = redboot_flash_start; |
| 257 #endif | 259 #endif |
| 258 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 260 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 259 // And a descriptor for the configuration data | 261 // And a descriptor for the configuration data |
| 260 memset(img, 0, sizeof(*img)); | 262 memset(img, 0, sizeof(*img)); |
| 261 strcpy(img->name, "RedBoot config"); | 263 strcpy(img->name, "RedBoot config"); |
| 262 if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { | 264 img->flash_base = (CYG_ADDRESS)cfg_base; |
| 263 cfg_base = (void *)((unsigned long)flash_end + | 265 img->mem_base = (CYG_ADDRESS)cfg_base; |
| 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 } | |
| 269 img->flash_base = (unsigned long)cfg_base; | |
| 270 img->mem_base = (unsigned long)cfg_base; | |
| 271 img->size = cfg_size; | 266 img->size = cfg_size; |
| 272 img++; | 267 img++; |
| 273 #endif | 268 #endif |
| 274 // And a descriptor for the descriptor table itself | 269 // And a descriptor for the descriptor table itself |
| 275 memset(img, 0, sizeof(*img)); | 270 memset(img, 0, sizeof(*img)); |
| 276 strcpy(img->name, "FIS directory"); | 271 strcpy(img->name, "FIS directory"); |
| 277 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { | 272 img->flash_base = (CYG_ADDRESS)fis_addr; |
| 278 fis_base = (void *)((unsigned long)flash_end + | 273 img->mem_base = (CYG_ADDRESS)fis_addr; |
| 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 } | |
| 284 img->flash_base = (unsigned long)fis_base; | |
| 285 img->mem_base = (unsigned long)fis_base; | |
| 286 img->size = block_size; | 274 img->size = block_size; |
| 287 img++; | 275 img++; |
| 288 | 276 |
| 289 // Do this after creating the initialized table because that inherently | 277 // Do this after creating the initialized table because that inherently |
| 290 // calculates where the high water mark of default RedBoot images is. | 278 // calculates where the high water mark of default RedBoot images is. |
| 291 | 279 |
| 292 if (full_init) { | 280 if (full_init) { |
| 293 unsigned long erase_start, erase_size; | 281 unsigned long erase_size; |
| 282 CYG_ADDRESS erase_start; | |
| 294 // Erase everything except default RedBoot images, fis block, | 283 // Erase everything except default RedBoot images, fis block, |
| 295 // and config block. | 284 // and config block. |
| 296 // First deal with the possible first part, before RedBoot images: | 285 // First deal with the possible first part, before RedBoot images: |
| 297 erase_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; | 286 #if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET > CYGNUM_REDBOOT_FLASH_RESERVED_BASE) |
| 298 erase_size = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; | 287 erase_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; |
| 288 erase_size = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; | |
| 299 if ( erase_size > erase_start ) { | 289 if ( erase_size > erase_start ) { |
| 300 erase_size -= erase_start; | 290 erase_size -= erase_start; |
| 301 if ((stat = flash_erase((void *)erase_start, erase_size, | 291 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 302 (void **)&err_addr)) != 0) { | 292 (void **)&err_addr)) != 0) { |
| 303 diag_printf(" initialization failed at %p: %s\n", | 293 diag_printf(" initialization failed at %p: %s\n", |
| 304 err_addr, flash_errmsg(stat)); | 294 err_addr, flash_errmsg(stat)); |
| 305 } | 295 } |
| 306 } | 296 } |
| 297 #endif | |
| 307 // second deal with the larger part in the main: | 298 // second deal with the larger part in the main: |
| 308 erase_start = redboot_flash_start; // high water of created images | 299 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 | 300 // Now the empty bits between the end of Redboot and the cfg and dir |
| 310 // blocks. | 301 // blocks. |
| 311 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG | 302 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG |
| 312 if (fis_base > cfg_base) { | 303 if (fis_addr > cfg_base) { |
| 313 erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data | 304 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data |
| 314 } else { | 305 } else { |
| 315 erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data | 306 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data |
| 316 } | 307 } |
| 317 if ((stat = flash_erase((void *)erase_start, erase_size, | 308 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 318 (void **)&err_addr)) != 0) { | 309 (void **)&err_addr)) != 0) { |
| 319 diag_printf(" initialization failed %p: %s\n", | 310 diag_printf(" initialization failed %p: %s\n", |
| 320 err_addr, flash_errmsg(stat)); | 311 err_addr, flash_errmsg(stat)); |
| 321 } | 312 } |
| 322 erase_start += (erase_size + block_size); | 313 erase_start += (erase_size + block_size); |
| 323 if (fis_base > cfg_base) { | 314 if (fis_addr > cfg_base) { |
| 324 erase_size = (unsigned long)fis_base - erase_start; // the gap between config and fis data | 315 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data |
| 325 } else { | 316 } else { |
| 326 erase_size = (unsigned long)cfg_base - erase_start; // the gap between fis and config data | 317 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data |
| 327 } | 318 } |
| 328 if ((stat = flash_erase((void *)erase_start, erase_size, | 319 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 329 (void **)&err_addr)) != 0) { | 320 (void **)&err_addr)) != 0) { |
| 330 diag_printf(" initialization failed %p: %s\n", | 321 diag_printf(" initialization failed %p: %s\n", |
| 331 err_addr, flash_errmsg(stat)); | 322 err_addr, flash_errmsg(stat)); |
| 332 } | 323 } |
| 333 erase_start += (erase_size + block_size); | 324 erase_start += (erase_size + block_size); |
| 334 #else // !CYGSEM_REDBOOT_FLASH_CONFIG | 325 #else // !CYGSEM_REDBOOT_FLASH_CONFIG |
| 335 erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data | 326 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data |
| 336 if ((stat = flash_erase((void *)erase_start, erase_size, | 327 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 337 (void **)&err_addr)) != 0) { | 328 (void **)&err_addr)) != 0) { |
| 338 diag_printf(" initialization failed %p: %s\n", | 329 diag_printf(" initialization failed %p: %s\n", |
| 339 err_addr, flash_errmsg(stat)); | 330 err_addr, flash_errmsg(stat)); |
| 340 } | 331 } |
| 341 erase_start += (erase_size + block_size); | 332 erase_start += (erase_size + block_size); |
| 342 #endif | 333 #endif |
| 343 // Lastly, anything at the end | 334 // Lastly, anything at the end |
| 344 erase_size = (unsigned long)flash_end - erase_start; | 335 erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1; |
| 345 if ((stat = flash_erase((void *)erase_start, erase_size, | 336 if ((stat = flash_erase((void *)erase_start, erase_size, |
| 346 (void **)&err_addr)) != 0) { | 337 (void **)&err_addr)) != 0) { |
| 347 diag_printf(" initialization failed at %p: %s\n", | 338 diag_printf(" initialization failed at %p: %s\n", |
| 348 err_addr, flash_errmsg(stat)); | 339 err_addr, flash_errmsg(stat)); |
| 349 } | 340 } |
| 351 diag_printf(" Warning: device contents not erased, some blocks may not be usable\n"); | 342 diag_printf(" Warning: device contents not erased, some blocks may not be usable\n"); |
| 352 } | 343 } |
| 353 | 344 |
| 354 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 345 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 355 // Ensure [quietly] that the directory is unlocked before trying to update | 346 // Ensure [quietly] that the directory is unlocked before trying to update |
| 356 flash_unlock((void *)fis_base, block_size, (void **)&err_addr); | 347 flash_unlock((void *)fis_addr, block_size, (void **)&err_addr); |
| 357 #endif | 348 #endif |
| 358 if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) { | 349 if ((stat = flash_erase(fis_addr, block_size, (void **)&err_addr)) != 0) { |
| 359 diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); | 350 diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); |
| 360 } else { | 351 } else { |
| 361 if ((stat = flash_program(fis_base, fis_work_block, | 352 if ((stat = flash_program(fis_addr, fis_work_block, |
| 362 (unsigned long)img - (unsigned long)fis_work_block, | 353 (CYG_ADDRESS)img - (CYG_ADDRESS)fis_work_block, |
| 363 (void **)&err_addr)) != 0) { | 354 (void **)&err_addr)) != 0) { |
| 364 diag_printf("Error writing image descriptors at %p: %s\n", | 355 diag_printf("Error writing image descriptors at %p: %s\n", |
| 365 err_addr, flash_errmsg(stat)); | 356 err_addr, flash_errmsg(stat)); |
| 366 } | 357 } |
| 367 } | 358 } |
| 368 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 359 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 369 // Ensure [quietly] that the directory is locked after the update | 360 // Ensure [quietly] that the directory is locked after the update |
| 370 flash_lock((void *)fis_base, block_size, (void **)&err_addr); | 361 flash_lock((void *)fis_addr, block_size, (void **)&err_addr); |
| 371 #endif | 362 #endif |
| 372 } | 363 } |
| 373 | 364 |
| 374 static void | 365 static void |
| 375 fis_list(int argc, char *argv[]) | 366 fis_list(int argc, char *argv[]) |
| 391 #endif | 382 #endif |
| 392 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) | 383 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) |
| 393 { | 384 { |
| 394 return; | 385 return; |
| 395 } | 386 } |
| 396 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { | 387 img = (struct fis_image_desc *)fis_work_block; |
| 397 img = (void *)((unsigned long)flash_end + | |
| 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 | 388 // Let diag_printf do the formatting in both cases, rather than counting |
| 404 // cols by hand.... | 389 // cols by hand.... |
| 405 diag_printf("%-16s %-10s %-10s %-10s %-s\n", | 390 diag_printf("%-16s %-10s %-10s %-10s %-s\n", |
| 406 "Name","FLASH addr", | 391 "Name","FLASH addr", |
| 407 show_cksums ? "Checksum" : "Mem addr", | 392 show_cksums ? "Checksum" : "Mem addr", |
| 428 { | 413 { |
| 429 unsigned long *fis_ptr, *fis_end; | 414 unsigned long *fis_ptr, *fis_end; |
| 430 unsigned long *area_start; | 415 unsigned long *area_start; |
| 431 | 416 |
| 432 // Do not search the area reserved for pre-RedBoot systems: | 417 // Do not search the area reserved for pre-RedBoot systems: |
| 433 fis_ptr = (unsigned long *)((unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); | 418 fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); |
| 434 fis_end = (unsigned long *)(unsigned long)flash_end; | 419 fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; |
| 435 area_start = fis_ptr; | 420 area_start = fis_ptr; |
| 436 while (fis_ptr < fis_end) { | 421 while (fis_ptr < fis_end) { |
| 437 if (*fis_ptr != (unsigned long)0xFFFFFFFF) { | 422 if (*fis_ptr != (unsigned long)0xFFFFFFFF) { |
| 438 if (area_start != fis_ptr) { | 423 if (area_start != fis_ptr) { |
| 439 // Assume that this is something | 424 // Assume that this is something |
| 440 diag_printf(" 0x%08lX .. 0x%08lX\n", | 425 diag_printf(" 0x%08lX .. 0x%08lX\n", |
| 441 (unsigned long)area_start, (unsigned long)fis_ptr); | 426 (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr); |
| 442 } | 427 } |
| 443 // Find next blank block | 428 // Find next blank block |
| 444 area_start = fis_ptr; | 429 area_start = fis_ptr; |
| 445 while (area_start < fis_end) { | 430 while (area_start < fis_end) { |
| 446 if (*area_start == (unsigned long)0xFFFFFFFF) { | 431 if (*area_start == (unsigned long)0xFFFFFFFF) { |
| 447 break; | 432 break; |
| 448 } | 433 } |
| 449 area_start += block_size / sizeof(unsigned long); | 434 area_start += block_size / sizeof(CYG_ADDRESS); |
| 450 } | 435 } |
| 451 fis_ptr = area_start; | 436 fis_ptr = area_start; |
| 452 } else { | 437 } else { |
| 453 fis_ptr += block_size / sizeof(unsigned long); | 438 fis_ptr += block_size / sizeof(CYG_ADDRESS); |
| 454 } | 439 } |
| 455 } | 440 } |
| 456 if (area_start != fis_ptr) { | 441 if (area_start != fis_ptr) { |
| 457 diag_printf(" 0x%08lX .. 0x%08lX\n", | 442 diag_printf(" 0x%08lX .. 0x%08lX\n", |
| 458 (unsigned long)area_start, (unsigned long)fis_ptr); | 443 (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr); |
| 459 } | 444 } |
| 460 } | 445 } |
| 461 | 446 |
| 462 // Find the first unused area of flash which is long enough | 447 // Find the first unused area of flash which is long enough |
| 463 static bool | 448 static bool |
| 464 fis_find_free(unsigned long *addr, unsigned long length) | 449 fis_find_free(CYG_ADDRESS *addr, unsigned long length) |
| 465 { | 450 { |
| 466 unsigned long *fis_ptr, *fis_end; | 451 unsigned long *fis_ptr, *fis_end; |
| 467 unsigned long *area_start; | 452 unsigned long *area_start; |
| 468 | 453 |
| 469 // Do not search the area reserved for pre-RedBoot systems: | 454 // Do not search the area reserved for pre-RedBoot systems: |
| 470 fis_ptr = (unsigned long *)((unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); | 455 fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE); |
| 471 fis_end = (unsigned long *)(unsigned long)flash_end; | 456 fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; |
| 472 area_start = fis_ptr; | 457 area_start = fis_ptr; |
| 473 while (fis_ptr < fis_end) { | 458 while (fis_ptr < fis_end) { |
| 474 if (*fis_ptr != (unsigned long)0xFFFFFFFF) { | 459 if (*fis_ptr != (unsigned long)0xFFFFFFFF) { |
| 475 if (area_start != fis_ptr) { | 460 if (area_start != fis_ptr) { |
| 476 // Assume that this is something | 461 // Assume that this is something |
| 477 if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { | 462 if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { |
| 478 *addr = (unsigned long)area_start; | 463 *addr = (CYG_ADDRESS)area_start; |
| 479 return true; | 464 return true; |
| 480 } | 465 } |
| 481 } | 466 } |
| 482 // Find next blank block | 467 // Find next blank block |
| 483 area_start = fis_ptr; | 468 area_start = fis_ptr; |
| 484 while (area_start < fis_end) { | 469 while (area_start < fis_end) { |
| 485 if (*area_start == (unsigned long)0xFFFFFFFF) { | 470 if (*area_start == (unsigned long)0xFFFFFFFF) { |
| 486 break; | 471 break; |
| 487 } | 472 } |
| 488 area_start += block_size / sizeof(unsigned long); | 473 area_start += block_size / sizeof(CYG_ADDRESS); |
| 489 } | 474 } |
| 490 fis_ptr = area_start; | 475 fis_ptr = area_start; |
| 491 } else { | 476 } else { |
| 492 fis_ptr += block_size / sizeof(unsigned long); | 477 fis_ptr += block_size / sizeof(CYG_ADDRESS); |
| 493 } | 478 } |
| 494 } | 479 } |
| 495 if (area_start != fis_ptr) { | 480 if (area_start != fis_ptr) { |
| 496 if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { | 481 if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { |
| 497 *addr = (unsigned long)area_start; | 482 *addr = (CYG_ADDRESS)area_start; |
| 498 return true; | 483 return true; |
| 499 } | 484 } |
| 500 } | 485 } |
| 501 return false; | 486 return false; |
| 502 } | 487 } |
| 503 | 488 |
| 504 static void | 489 static void |
| 505 fis_create(int argc, char *argv[]) | 490 fis_create(int argc, char *argv[]) |
| 506 { | 491 { |
| 507 int i, stat; | 492 int i, stat; |
| 508 unsigned long mem_addr, exec_addr, flash_addr, entry_addr, length, img_size; | 493 unsigned long length, img_size; |
| 494 CYG_ADDRESS mem_addr, exec_addr, flash_addr, entry_addr; | |
| 509 char *name; | 495 char *name; |
| 510 bool mem_addr_set = false; | 496 bool mem_addr_set = false; |
| 511 bool exec_addr_set = false; | 497 bool exec_addr_set = false; |
| 512 bool entry_addr_set = false; | 498 bool entry_addr_set = false; |
| 513 bool flash_addr_set = false; | 499 bool flash_addr_set = false; |
| 514 bool length_set = false; | 500 bool length_set = false; |
| 515 bool img_size_set = false; | 501 bool img_size_set = false; |
| 516 bool no_copy = false; | 502 bool no_copy = false; |
| 517 void *fis_addr, *err_addr; | 503 void *err_addr; |
| 518 struct fis_image_desc *img; | 504 struct fis_image_desc *img; |
| 519 bool slot_found, defaults_assumed; | 505 bool slot_found, defaults_assumed; |
| 520 struct option_info opts[7]; | 506 struct option_info opts[7]; |
| 521 bool prog_ok = false; | 507 bool prog_ok = true; |
| 522 | 508 |
| 523 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, | 509 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, |
| 524 (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address"); | 510 (void **)&mem_addr, (bool *)&mem_addr_set, "memory base address"); |
| 525 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, | 511 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, |
| 526 (void **)&exec_addr, (bool *)&exec_addr_set, "ram base address"); | 512 (void **)&exec_addr, (bool *)&exec_addr_set, "ram base address"); |
| 541 } | 527 } |
| 542 | 528 |
| 543 defaults_assumed = false; | 529 defaults_assumed = false; |
| 544 if (name) { | 530 if (name) { |
| 545 // Search existing files to acquire defaults for params not specified: | 531 // Search existing files to acquire defaults for params not specified: |
| 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 } | |
| 553 memcpy(fis_work_block, fis_addr, block_size); | |
| 554 img = (struct fis_image_desc *)fis_work_block; | 532 img = (struct fis_image_desc *)fis_work_block; |
| 555 for (i = 0; i < block_size/sizeof(*img); i++, img++) { | 533 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 556 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 534 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 557 // Found it, so get any unset but necessary params from there: | 535 // Found it, so get any unset but necessary params from there: |
| 558 if (!length_set) { | 536 if (!length_set) { |
| 593 } | 571 } |
| 594 #endif | 572 #endif |
| 595 if (flash_addr_set && | 573 if (flash_addr_set && |
| 596 ((stat = flash_verify_addr((void *)flash_addr)) || | 574 ((stat = flash_verify_addr((void *)flash_addr)) || |
| 597 (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) { | 575 (stat = flash_verify_addr((void *)(flash_addr+img_size-1))))) { |
| 598 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); | 576 _show_invalid_flash_address(flash_addr, stat); |
| 599 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | |
| 600 return; | 577 return; |
| 601 } | 578 } |
| 602 if (flash_addr_set && flash_addr & (block_size-1)) { | 579 if (flash_addr_set && flash_addr & (block_size-1)) { |
| 603 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | 580 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); |
| 604 diag_printf(" must be 0x%x aligned\n", block_size); | 581 diag_printf(" must be 0x%x aligned\n", block_size); |
| 607 if (strlen(name) >= sizeof(img->name)) { | 584 if (strlen(name) >= sizeof(img->name)) { |
| 608 diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); | 585 diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); |
| 609 return; | 586 return; |
| 610 } | 587 } |
| 611 if (!no_copy) { | 588 if (!no_copy) { |
| 612 if ((mem_addr < (unsigned long)ram_start) || | 589 if ((mem_addr < (CYG_ADDRESS)ram_start) || |
| 613 ((mem_addr+img_size) >= (unsigned long)ram_end)) { | 590 ((mem_addr+img_size) >= (CYG_ADDRESS)ram_end)) { |
| 614 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); | 591 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); |
| 615 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); | 592 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); |
| 616 } | 593 } |
| 617 if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { | 594 if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { |
| 618 diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); | 595 diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); |
| 620 } | 597 } |
| 621 } | 598 } |
| 622 // Find a slot in the directory for this entry | 599 // Find a slot in the directory for this entry |
| 623 // First, see if an image by this name is already present | 600 // First, see if an image by this name is already present |
| 624 slot_found = false; | 601 slot_found = false; |
| 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 } | |
| 632 memcpy(fis_work_block, fis_addr, block_size); | |
| 633 img = (struct fis_image_desc *)fis_work_block; | 602 img = (struct fis_image_desc *)fis_work_block; |
| 634 for (i = 0; i < block_size/sizeof(*img); i++, img++) { | 603 for (i = 0; i < block_size/sizeof(*img); i++, img++) { |
| 635 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { | 604 if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) { |
| 636 if (flash_addr_set && (img->flash_base != flash_addr)) { | 605 if (flash_addr_set && (img->flash_base != flash_addr)) { |
| 637 diag_printf("Image found, but FLASH address incorrect\n"); | 606 diag_printf("Image found, but FLASH address incorrect\n"); |
| 670 // Safety check - make sure the address range is not within the code we're running | 639 // Safety check - make sure the address range is not within the code we're running |
| 671 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { | 640 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { |
| 672 diag_printf("Can't program this region - contains code in use!\n"); | 641 diag_printf("Can't program this region - contains code in use!\n"); |
| 673 return; | 642 return; |
| 674 } | 643 } |
| 675 prog_ok = true; | |
| 676 if (prog_ok) { | 644 if (prog_ok) { |
| 677 // Erase area to be programmed | 645 // Erase area to be programmed |
| 678 if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 646 if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { |
| 679 diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); | 647 diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); |
| 680 prog_ok = false; | 648 prog_ok = false; |
| 692 // Update directory | 660 // Update directory |
| 693 memset(img, 0, sizeof(*img)); | 661 memset(img, 0, sizeof(*img)); |
| 694 strcpy(img->name, name); | 662 strcpy(img->name, name); |
| 695 img->flash_base = flash_addr; | 663 img->flash_base = flash_addr; |
| 696 img->mem_base = exec_addr_set ? exec_addr : (flash_addr_set ? flash_addr : mem_addr); | 664 img->mem_base = exec_addr_set ? exec_addr : (flash_addr_set ? flash_addr : mem_addr); |
| 697 img->entry_point = entry_addr_set ? entry_addr : (unsigned long)entry_address; // Hope it's been set | 665 img->entry_point = entry_addr_set ? entry_addr : (CYG_ADDRESS)entry_address; // Hope it's been set |
| 698 img->size = length; | 666 img->size = length; |
| 699 img->data_length = img_size; | 667 img->data_length = img_size; |
| 700 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK | 668 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK |
| 701 img->file_cksum = crc32((unsigned char *)flash_addr, img_size); | 669 img->file_cksum = crc32((unsigned char *)flash_addr, img_size); |
| 702 #endif | 670 #endif |
| 723 static void | 691 static void |
| 724 fis_delete(int argc, char *argv[]) | 692 fis_delete(int argc, char *argv[]) |
| 725 { | 693 { |
| 726 char *name; | 694 char *name; |
| 727 int num_reserved, i, stat; | 695 int num_reserved, i, stat; |
| 728 void *fis_addr, *err_addr; | 696 void *err_addr; |
| 729 struct fis_image_desc *img; | 697 struct fis_image_desc *img; |
| 730 bool slot_found; | 698 bool slot_found; |
| 731 | 699 |
| 732 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) | 700 if (!scan_opts(argc, argv, 2, 0, 0, (void **)&name, OPTION_ARG_TYPE_STR, "image name")) |
| 733 { | 701 { |
| 734 fis_usage("invalid arguments"); | 702 fis_usage("invalid arguments"); |
| 735 return; | 703 return; |
| 736 } | 704 } |
| 737 slot_found = false; | 705 slot_found = false; |
| 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 } | |
| 745 memcpy(fis_work_block, fis_addr, block_size); | |
| 746 img = (struct fis_image_desc *)fis_work_block; | 706 img = (struct fis_image_desc *)fis_work_block; |
| 747 num_reserved = 0; | 707 num_reserved = 0; |
| 748 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE | 708 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE |
| 749 num_reserved++; | 709 num_reserved++; |
| 750 #endif | 710 #endif |
| 811 static void | 771 static void |
| 812 fis_load(int argc, char *argv[]) | 772 fis_load(int argc, char *argv[]) |
| 813 { | 773 { |
| 814 char *name; | 774 char *name; |
| 815 struct fis_image_desc *img; | 775 struct fis_image_desc *img; |
| 816 unsigned long mem_addr; | 776 CYG_ADDRESS mem_addr; |
| 817 bool mem_addr_set = false; | 777 bool mem_addr_set = false; |
| 818 bool show_cksum = false; | 778 bool show_cksum = false; |
| 819 struct option_info opts[3]; | 779 struct option_info opts[3]; |
| 820 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK | 780 #ifdef CYGPKG_REDBOOT_FIS_CRC_CHECK |
| 821 unsigned long cksum; | 781 unsigned long cksum; |
| 847 } | 807 } |
| 848 if (!mem_addr_set) { | 808 if (!mem_addr_set) { |
| 849 mem_addr = img->mem_base; | 809 mem_addr = img->mem_base; |
| 850 } | 810 } |
| 851 // Load image from FLASH into RAM | 811 // Load image from FLASH into RAM |
| 852 if ((mem_addr < (unsigned long)user_ram_start) || | 812 if ((mem_addr < (CYG_ADDRESS)user_ram_start) || |
| 853 ((mem_addr+img->size) >= (unsigned long)user_ram_end)) { | 813 ((mem_addr+img->size) >= (CYG_ADDRESS)user_ram_end)) { |
| 854 diag_printf("Not a loadable image\n"); | 814 diag_printf("Not a loadable image\n"); |
| 855 return; | 815 return; |
| 856 } | 816 } |
| 857 #ifdef CYGPKG_COMPRESS_ZLIB | 817 #ifdef CYGPKG_COMPRESS_ZLIB |
| 858 if (decompress) { | 818 if (decompress) { |
| 903 | 863 |
| 904 static void | 864 static void |
| 905 fis_write(int argc, char *argv[]) | 865 fis_write(int argc, char *argv[]) |
| 906 { | 866 { |
| 907 int stat; | 867 int stat; |
| 908 unsigned long mem_addr, flash_addr, length; | 868 unsigned long length; |
| 869 CYG_ADDRESS mem_addr, flash_addr; | |
| 909 bool mem_addr_set = false; | 870 bool mem_addr_set = false; |
| 910 bool flash_addr_set = false; | 871 bool flash_addr_set = false; |
| 911 bool length_set = false; | 872 bool length_set = false; |
| 912 void *err_addr; | 873 void *err_addr; |
| 913 struct option_info opts[3]; | 874 struct option_info opts[3]; |
| 935 length = ((length + block_size - 1) / block_size) * block_size; | 896 length = ((length + block_size - 1) / block_size) * block_size; |
| 936 #endif | 897 #endif |
| 937 if (flash_addr_set && | 898 if (flash_addr_set && |
| 938 ((stat = flash_verify_addr((void *)flash_addr)) || | 899 ((stat = flash_verify_addr((void *)flash_addr)) || |
| 939 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 900 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { |
| 940 diag_printf("Invalid FLASH address %p: (%s)\n", (void *)flash_addr, flash_errmsg(stat)); | 901 _show_invalid_flash_address(flash_addr, stat); |
| 941 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | |
| 942 return; | 902 return; |
| 943 } | 903 } |
| 944 if (flash_addr_set && flash_addr & (block_size-1)) { | 904 if (flash_addr_set && flash_addr & (block_size-1)) { |
| 945 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | 905 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); |
| 946 diag_printf(" must be 0x%x aligned\n", block_size); | 906 diag_printf(" must be 0x%x aligned\n", block_size); |
| 947 return; | 907 return; |
| 948 } | 908 } |
| 949 if ((mem_addr < (unsigned long)ram_start) || | 909 if ((mem_addr < (CYG_ADDRESS)ram_start) || |
| 950 ((mem_addr+length) >= (unsigned long)ram_end)) { | 910 ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) { |
| 951 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); | 911 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); |
| 952 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); | 912 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); |
| 953 } | 913 } |
| 954 // Safety check - make sure the address range is not within the code we're running | 914 // Safety check - make sure the address range is not within the code we're running |
| 955 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { | 915 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+length-1))) { |
| 980 | 940 |
| 981 static void | 941 static void |
| 982 fis_erase(int argc, char *argv[]) | 942 fis_erase(int argc, char *argv[]) |
| 983 { | 943 { |
| 984 int stat; | 944 int stat; |
| 985 unsigned long flash_addr, length; | 945 unsigned long length; |
| 946 CYG_ADDRESS flash_addr; | |
| 986 bool flash_addr_set = false; | 947 bool flash_addr_set = false; |
| 987 bool length_set = false; | 948 bool length_set = false; |
| 988 void *err_addr; | 949 void *err_addr; |
| 989 struct option_info opts[2]; | 950 struct option_info opts[2]; |
| 990 | 951 |
| 1003 return; | 964 return; |
| 1004 } | 965 } |
| 1005 if (flash_addr_set && | 966 if (flash_addr_set && |
| 1006 ((stat = flash_verify_addr((void *)flash_addr)) || | 967 ((stat = flash_verify_addr((void *)flash_addr)) || |
| 1007 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 968 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { |
| 1008 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); | 969 _show_invalid_flash_address(flash_addr, stat); |
| 1009 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | |
| 1010 return; | 970 return; |
| 1011 } | 971 } |
| 1012 if (flash_addr_set && flash_addr & (block_size-1)) { | 972 if (flash_addr_set && flash_addr & (block_size-1)) { |
| 1013 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); | 973 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); |
| 1014 diag_printf(" must be 0x%x aligned\n", block_size); | 974 diag_printf(" must be 0x%x aligned\n", block_size); |
| 1028 | 988 |
| 1029 static void | 989 static void |
| 1030 fis_lock(int argc, char *argv[]) | 990 fis_lock(int argc, char *argv[]) |
| 1031 { | 991 { |
| 1032 int stat; | 992 int stat; |
| 1033 unsigned long flash_addr, length; | 993 unsigned long length; |
| 994 CYG_ADDRESS flash_addr; | |
| 1034 bool flash_addr_set = false; | 995 bool flash_addr_set = false; |
| 1035 bool length_set = false; | 996 bool length_set = false; |
| 1036 void *err_addr; | 997 void *err_addr; |
| 1037 struct option_info opts[2]; | 998 struct option_info opts[2]; |
| 1038 | 999 |
| 1051 return; | 1012 return; |
| 1052 } | 1013 } |
| 1053 if (flash_addr_set && | 1014 if (flash_addr_set && |
| 1054 ((stat = flash_verify_addr((void *)flash_addr)) || | 1015 ((stat = flash_verify_addr((void *)flash_addr)) || |
| 1055 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 1016 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { |
| 1056 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); | 1017 _show_invalid_flash_address(flash_addr, stat); |
| 1057 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | |
| 1058 return; | 1018 return; |
| 1059 } | 1019 } |
| 1060 if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 1020 if ((stat = flash_lock((void *)flash_addr, length, (void **)&err_addr)) != 0) { |
| 1061 diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); | 1021 diag_printf("Error locking at %p: %s\n", err_addr, flash_errmsg(stat)); |
| 1062 } | 1022 } |
| 1064 | 1024 |
| 1065 static void | 1025 static void |
| 1066 fis_unlock(int argc, char *argv[]) | 1026 fis_unlock(int argc, char *argv[]) |
| 1067 { | 1027 { |
| 1068 int stat; | 1028 int stat; |
| 1069 unsigned long flash_addr, length; | 1029 unsigned long length; |
| 1030 CYG_ADDRESS flash_addr; | |
| 1070 bool flash_addr_set = false; | 1031 bool flash_addr_set = false; |
| 1071 bool length_set = false; | 1032 bool length_set = false; |
| 1072 void *err_addr; | 1033 void *err_addr; |
| 1073 struct option_info opts[2]; | 1034 struct option_info opts[2]; |
| 1074 | 1035 |
| 1087 return; | 1048 return; |
| 1088 } | 1049 } |
| 1089 if (flash_addr_set && | 1050 if (flash_addr_set && |
| 1090 ((stat = flash_verify_addr((void *)flash_addr)) || | 1051 ((stat = flash_verify_addr((void *)flash_addr)) || |
| 1091 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { | 1052 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { |
| 1092 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); | 1053 _show_invalid_flash_address(flash_addr, stat); |
| 1093 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); | |
| 1094 return; | 1054 return; |
| 1095 } | 1055 } |
| 1096 if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { | 1056 if ((stat = flash_unlock((void *)flash_addr, length, (void **)&err_addr)) != 0) { |
| 1097 diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); | 1057 diag_printf("Error unlocking at %p: %s\n", err_addr, flash_errmsg(stat)); |
| 1098 } | 1058 } |
| 1099 } | 1059 } |
| 1100 #endif | 1060 #endif |
| 1101 | 1061 |
| 1062 // This is set non-zero if the FLASH subsystem has successfully been initialized | |
| 1102 static int __flash_init = 0; | 1063 static int __flash_init = 0; |
| 1103 | 1064 |
| 1104 void | 1065 void |
| 1105 _flash_info(void) | 1066 _flash_info(void) |
| 1106 { | 1067 { |
| 1107 if (!__flash_init) return; | 1068 if (!__flash_init) return; |
| 1108 diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", | 1069 diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", |
| 1109 flash_start, flash_end, blocks, (void *)block_size); | 1070 flash_start, (CYG_ADDRWORD)flash_end + 1, blocks, (void *)block_size); |
| 1110 } | 1071 } |
| 1111 | 1072 |
| 1112 static bool | 1073 static bool |
| 1113 do_flash_init(void) | 1074 do_flash_init(void) |
| 1114 { | 1075 { |
| 1120 FLASH_MIN_WORKSPACE, diag_printf)) != 0) { | 1081 FLASH_MIN_WORKSPACE, diag_printf)) != 0) { |
| 1121 diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); | 1082 diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); |
| 1122 return false; | 1083 return false; |
| 1123 } | 1084 } |
| 1124 flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); | 1085 flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); |
| 1086 // Keep 'end' address as last valid location, to avoid wrap around problems | |
| 1087 flash_end = (void *)((CYG_ADDRESS)flash_end - 1); | |
| 1125 flash_get_block_info(&block_size, &blocks); | 1088 flash_get_block_info(&block_size, &blocks); |
| 1126 fis_work_block = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE-block_size); | 1089 workspace_end = (unsigned char *)(workspace_end-FLASH_MIN_WORKSPACE); |
| 1127 workspace_end = fis_work_block; | 1090 #ifdef CYGOPT_REDBOOT_FIS |
| 1091 workspace_end = (unsigned char *)(workspace_end-block_size); | |
| 1092 fis_work_block = workspace_end; | |
| 1128 fisdir_size = block_size; | 1093 fisdir_size = block_size; |
| 1094 #endif | |
| 1129 } | 1095 } |
| 1130 return true; | 1096 return true; |
| 1131 } | 1097 } |
| 1132 | 1098 |
| 1133 #ifndef CYGOPT_REDBOOT_FLASH_CONFIG | 1099 #ifndef CYGOPT_REDBOOT_FLASH_CONFIG |
| 1141 | 1107 |
| 1142 if (argc < 2) { | 1108 if (argc < 2) { |
| 1143 fis_usage("too few arguments"); | 1109 fis_usage("too few arguments"); |
| 1144 return; | 1110 return; |
| 1145 } | 1111 } |
| 1146 if (!do_flash_init()) return; | 1112 if (!do_flash_init()) { |
| 1113 diag_printf("Sorry, no FLASH memory is available\n"); | |
| 1114 return; | |
| 1115 } | |
| 1116 #ifdef CYGOPT_REDBOOT_FIS | |
| 1117 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { | |
| 1118 fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + | |
| 1119 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 1120 } else { | |
| 1121 fis_addr = (void *)((CYG_ADDRESS)flash_start + | |
| 1122 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size)); | |
| 1123 } | |
| 1124 memcpy(fis_work_block, fis_addr, block_size); | |
| 1125 #endif | |
| 1147 if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, | 1126 if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, |
| 1148 argv[1])) != (struct cmd *)0) { | 1127 argv[1])) != (struct cmd *)0) { |
| 1149 (cmd->fun)(argc, argv); | 1128 (cmd->fun)(argc, argv); |
| 1150 return; | 1129 return; |
| 1151 } | 1130 } |
| 1161 unsigned long len; | 1140 unsigned long len; |
| 1162 unsigned long key1; | 1141 unsigned long key1; |
| 1163 unsigned char config_data[MAX_CONFIG_DATA-(4*4)]; | 1142 unsigned char config_data[MAX_CONFIG_DATA-(4*4)]; |
| 1164 unsigned long key2; | 1143 unsigned long key2; |
| 1165 unsigned long cksum; | 1144 unsigned long cksum; |
| 1166 } config; | 1145 } *config, *backup_config; |
| 1167 static bool config_ok; | 1146 static bool config_ok; |
| 1168 | 1147 |
| 1169 #define CONFIG_KEY1 0x0BADFACE | 1148 #define CONFIG_KEY1 0x0BADFACE |
| 1170 #define CONFIG_KEY2 0xDEADDEAD | 1149 #define CONFIG_KEY2 0xDEADDEAD |
| 1171 | 1150 |
| 1363 } | 1342 } |
| 1364 break; | 1343 break; |
| 1365 #ifdef CYGPKG_REDBOOT_NETWORKING | 1344 #ifdef CYGPKG_REDBOOT_NETWORKING |
| 1366 case CONFIG_IP: | 1345 case CONFIG_IP: |
| 1367 memcpy(&hold_ip_val.s_addr, &((in_addr_t *)val_ptr)->s_addr, sizeof(in_addr_t)); | 1346 memcpy(&hold_ip_val.s_addr, &((in_addr_t *)val_ptr)->s_addr, sizeof(in_addr_t)); |
| 1368 if (!inet_aton(line, &new_ip_val)) { | 1347 if (!_gethostbyname(line, &new_ip_val)) { |
| 1369 return CONFIG_BAD; | 1348 return CONFIG_BAD; |
| 1370 } | 1349 } |
| 1371 if (hold_ip_val.s_addr != new_ip_val.s_addr) { | 1350 if (hold_ip_val.s_addr != new_ip_val.s_addr) { |
| 1372 memcpy(val_ptr, &new_ip_val, sizeof(in_addr_t)); | 1351 memcpy(val_ptr, &new_ip_val, sizeof(in_addr_t)); |
| 1373 return CONFIG_CHANGED; | 1352 return CONFIG_CHANGED; |
| 1457 do_flash_config(int argc, char *argv[]) | 1436 do_flash_config(int argc, char *argv[]) |
| 1458 { | 1437 { |
| 1459 bool need_update = false; | 1438 bool need_update = false; |
| 1460 struct config_option *optend = __CONFIG_options_TAB_END__; | 1439 struct config_option *optend = __CONFIG_options_TAB_END__; |
| 1461 struct config_option *opt = __CONFIG_options_TAB__; | 1440 struct config_option *opt = __CONFIG_options_TAB__; |
| 1462 struct _config hold_config; | |
| 1463 struct option_info opts[4]; | 1441 struct option_info opts[4]; |
| 1464 bool list_only; | 1442 bool list_only; |
| 1465 bool nicknames; | 1443 bool nicknames; |
| 1466 bool fullnames; | 1444 bool fullnames; |
| 1467 int list_opt = 0; | 1445 int list_opt = 0; |
| 1471 char *onlyone = NULL; | 1449 char *onlyone = NULL; |
| 1472 char *onevalue = NULL; | 1450 char *onevalue = NULL; |
| 1473 bool doneone = false; | 1451 bool doneone = false; |
| 1474 bool init = false; | 1452 bool init = false; |
| 1475 | 1453 |
| 1476 if (!do_flash_init()) return; | 1454 if (!__flash_init) { |
| 1477 memcpy(&hold_config, &config, sizeof(config)); | 1455 diag_printf("Sorry, no FLASH memory is available\n"); |
| 1456 return; | |
| 1457 } | |
| 1458 memcpy(backup_config, config, sizeof(struct _config)); | |
| 1478 script = (unsigned char *)0; | 1459 script = (unsigned char *)0; |
| 1479 | 1460 |
| 1480 init_opts(&opts[0], 'l', false, OPTION_ARG_TYPE_FLG, | 1461 init_opts(&opts[0], 'l', false, OPTION_ARG_TYPE_FLG, |
| 1481 (void **)&list_only, (bool *)0, "list configuration only"); | 1462 (void **)&list_only, (bool *)0, "list configuration only"); |
| 1482 init_opts(&opts[1], 'n', false, OPTION_ARG_TYPE_FLG, | 1463 init_opts(&opts[1], 'n', false, OPTION_ARG_TYPE_FLG, |
| 1505 | 1486 |
| 1506 if (init && verify_action("Initialize non-volatile configuration")) { | 1487 if (init && verify_action("Initialize non-volatile configuration")) { |
| 1507 config_init(); | 1488 config_init(); |
| 1508 } | 1489 } |
| 1509 | 1490 |
| 1510 dp = &config.config_data[0]; | 1491 dp = &config->config_data[0]; |
| 1511 while (dp < &config.config_data[sizeof(config.config_data)]) { | 1492 while (dp < &config->config_data[sizeof(config->config_data)]) { |
| 1512 if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) { | 1493 if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) { |
| 1513 break; | 1494 break; |
| 1514 } | 1495 } |
| 1515 len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) + | 1496 len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) + |
| 1516 config_length(CONFIG_OBJECT_TYPE(dp)); | 1497 config_length(CONFIG_OBJECT_TYPE(dp)); |
| 1532 } | 1513 } |
| 1533 switch (ret) { | 1514 switch (ret) { |
| 1534 case CONFIG_DONE: | 1515 case CONFIG_DONE: |
| 1535 goto done; | 1516 goto done; |
| 1536 case CONFIG_ABORT: | 1517 case CONFIG_ABORT: |
| 1537 memcpy(&config, &hold_config, sizeof(config)); | 1518 memcpy(config, backup_config, sizeof(struct _config)); |
| 1538 return; | 1519 return; |
| 1539 case CONFIG_CHANGED: | 1520 case CONFIG_CHANGED: |
| 1540 need_update = true; | 1521 need_update = true; |
| 1541 case CONFIG_OK: | 1522 case CONFIG_OK: |
| 1542 dp += len; | 1523 dp += len; |
| 1543 break; | 1524 break; |
| 1544 case CONFIG_BACK: | 1525 case CONFIG_BACK: |
| 1545 dp = &config.config_data[0]; | 1526 dp = &config->config_data[0]; |
| 1546 continue; | 1527 continue; |
| 1547 case CONFIG_BAD: | 1528 case CONFIG_BAD: |
| 1548 // Nothing - make him do it again | 1529 // Nothing - make him do it again |
| 1549 diag_printf ("** invalid entry\n"); | 1530 diag_printf ("** invalid entry\n"); |
| 1550 } | 1531 } |
| 1605 make_alias(name, argv[1]); | 1586 make_alias(name, argv[1]); |
| 1606 opt.type = CONFIG_STRING; | 1587 opt.type = CONFIG_STRING; |
| 1607 opt.enable = (char *)0; | 1588 opt.enable = (char *)0; |
| 1608 opt.enable_sense = 1; | 1589 opt.enable_sense = 1; |
| 1609 opt.key = name; | 1590 opt.key = name; |
| 1610 opt.dflt = (unsigned long)argv[2]; | 1591 opt.dflt = (CYG_ADDRESS)argv[2]; |
| 1611 flash_add_config(&opt, true); | 1592 flash_add_config(&opt, true); |
| 1612 break; | 1593 break; |
| 1613 default: | 1594 default: |
| 1614 diag_printf("usage: alias name [value]\n"); | 1595 diag_printf("usage: alias name [value]\n"); |
| 1615 } | 1596 } |
| 1616 } | 1597 } |
| 1617 | 1598 |
| 1599 // Lookup an alias. First try plain string aliases. If that fails try | |
| 1600 // other types so allowing access to all configured values. This allows | |
| 1601 // for alias (macro) expansion of normal 'fconfig' data, such as the | |
| 1602 // board IP address. | |
| 1618 static char * | 1603 static char * |
| 1619 lookup_alias(char *alias) | 1604 lookup_alias(char *alias, char *alias_buf) |
| 1620 { | 1605 { |
| 1621 char name[80]; | 1606 char name[80]; |
| 1622 char *val; | 1607 char *val; |
| 1608 unsigned char * dp; | |
| 1609 void *val_ptr; | |
| 1610 int type; | |
| 1611 bool hold_bool_val; | |
| 1612 long hold_long_val; | |
| 1613 int esa_ptr; | |
| 1623 | 1614 |
| 1624 make_alias(name, alias); | 1615 make_alias(name, alias); |
| 1625 if (flash_get_config(name, &val, CONFIG_STRING)) { | 1616 if (flash_get_config(name, &val, CONFIG_STRING)) { |
| 1626 return val; | 1617 return val; |
| 1627 } else { | 1618 } else { |
| 1619 dp = flash_lookup_config(alias); | |
| 1620 if (dp) { | |
| 1621 val_ptr = (void *)CONFIG_OBJECT_VALUE(dp); | |
| 1622 switch (type = CONFIG_OBJECT_TYPE(dp)) { | |
| 1623 case CONFIG_BOOL: | |
| 1624 memcpy(&hold_bool_val, val_ptr, sizeof(bool)); | |
| 1625 diag_sprintf(alias_buf, "%s", hold_bool_val ? "true" : "false"); | |
| 1626 break; | |
| 1627 case CONFIG_INT: | |
| 1628 memcpy(&hold_long_val, val_ptr, sizeof(unsigned long)); | |
| 1629 diag_sprintf(alias_buf,"%ld", hold_long_val); | |
| 1630 break; | |
| 1631 #ifdef CYGPKG_REDBOOT_NETWORKING | |
| 1632 case CONFIG_IP: | |
| 1633 diag_sprintf(alias_buf,"%s", inet_ntoa((in_addr_t *)val_ptr)); | |
| 1634 break; | |
| 1635 case CONFIG_ESA: | |
| 1636 for (esa_ptr = 0; esa_ptr < sizeof(enet_addr_t); esa_ptr++) { | |
| 1637 diag_sprintf(alias_buf+(3*esa_ptr), "0x%02X", ((unsigned char *)val_ptr)[esa_ptr]); | |
| 1638 if (esa_ptr < (sizeof(enet_addr_t)-1)) diag_printf(":"); | |
| 1639 } | |
| 1640 break; | |
| 1641 #endif | |
| 1642 case CONFIG_SCRIPT: | |
| 1643 return (char *) val_ptr; | |
| 1644 break; | |
| 1645 default: | |
| 1646 return (char *)NULL; | |
| 1647 } | |
| 1648 return alias_buf; | |
| 1649 } | |
| 1628 return (char *)NULL; | 1650 return (char *)NULL; |
| 1629 } | 1651 } |
| 1630 } | 1652 } |
| 1631 | 1653 |
| 1654 // Expand aliases, this is recursive. ie if one alias contains other | |
| 1655 // aliases, these will also be expanded from the insertion point | |
| 1656 // onwards. | |
| 1632 bool | 1657 bool |
| 1633 _expand_aliases(char *line, int len) | 1658 _expand_aliases(char *line, int len) |
| 1634 { | 1659 { |
| 1635 char *lp = line; | 1660 char *lp = line; |
| 1636 char *ms, *me, *ep; | 1661 char *ms, *me, *ep; |
| 1637 char *alias; | 1662 char *alias; |
| 1638 char c; | 1663 char c; |
| 1639 int offset, line_len, alias_len; | 1664 int offset, line_len, alias_len; |
| 1665 char alias_buf[MAX_STRING_LENGTH]; | |
| 1640 bool macro_found = false; | 1666 bool macro_found = false; |
| 1641 | 1667 |
| 1642 if ((line_len = strlen(line)) != 0) { | 1668 if ((line_len = strlen(line)) != 0) { |
| 1643 while (*lp) { | 1669 while (*lp) { |
| 1644 c = *lp++; | 1670 c = *lp++; |
| 1653 return false; | 1679 return false; |
| 1654 } | 1680 } |
| 1655 me = lp; | 1681 me = lp; |
| 1656 *me = '\0'; | 1682 *me = '\0'; |
| 1657 lp++; | 1683 lp++; |
| 1658 if ((alias = lookup_alias(ms)) != (char *)NULL) { | 1684 if ((alias = lookup_alias(ms,alias_buf)) != (char *)NULL) { |
| 1659 alias_len = strlen(alias); | 1685 alias_len = strlen(alias); |
| 1660 // See if there is room in the line to expand this macro/alias | 1686 // See if there is room in the line to expand this macro/alias |
| 1661 if ((line_len+alias_len) < len) { | 1687 if ((line_len+alias_len) < len) { |
| 1662 // Make a hole by moving data within the line | 1688 // Make a hole by moving data within the line |
| 1663 offset = alias_len-strlen(ms)-2; // Number of bytes being inserted | 1689 offset = alias_len-strlen(ms)-2; // Number of bytes being inserted |
| 1664 ep = &lp[strlen(lp)-1]; | 1690 ep = &lp[strlen(lp)-1]; |
| 1665 me = &ep[offset]; | 1691 if (offset > 1) { |
| 1666 while (ep != (lp-1)) { | 1692 ep[offset] = '\0'; |
| 1667 ep[offset-1] = *ep--; | 1693 while (ep != (lp-1)) { |
| 1668 } | 1694 ep[offset-1] = *ep--; |
| 1669 *me = '\0'; | 1695 } |
| 1696 } else { | |
| 1697 if (offset <=0) { | |
| 1698 while ((lp-1) != ep) { | |
| 1699 lp[offset-1] = *lp++; | |
| 1700 } | |
| 1701 lp[offset-1]='\0'; | |
| 1702 } | |
| 1703 } | |
| 1670 // Insert the macro/alias data | 1704 // Insert the macro/alias data |
| 1671 lp = ms-2; | 1705 lp = ms-2; |
| 1672 while (*alias) { | 1706 while (*alias) { |
| 1673 if ((alias[0] == '%') && (alias[1] == '{')) macro_found = true; | 1707 if ((alias[0] == '%') && (alias[1] == '{')) macro_found = true; |
| 1674 *lp++ = *alias++; | 1708 *lp++ = *alias++; |
| 1675 } | 1709 } |
| 1676 line_len = strlen(line); | 1710 line_len = strlen(line); |
| 1711 lp = lp - alias_len; | |
| 1677 } else { | 1712 } else { |
| 1678 diag_printf("No room to expand '%s'\n", ms); | 1713 diag_printf("No room to expand '%s'\n", ms); |
| 1679 line[0] = '\0'; // Destroy line | 1714 line[0] = '\0'; // Destroy line |
| 1680 return false; | 1715 return false; |
| 1681 } | 1716 } |
| 1706 flash_write_config(void) | 1741 flash_write_config(void) |
| 1707 { | 1742 { |
| 1708 int stat; | 1743 int stat; |
| 1709 void *err_addr; | 1744 void *err_addr; |
| 1710 | 1745 |
| 1711 config.len = sizeof(config); | 1746 config->len = sizeof(struct _config); |
| 1712 config.key1 = CONFIG_KEY1; | 1747 config->key1 = CONFIG_KEY1; |
| 1713 config.key2 = CONFIG_KEY2; | 1748 config->key2 = CONFIG_KEY2; |
| 1714 config.cksum = crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)); | 1749 config->cksum = crc32((unsigned char *)config, sizeof(struct _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 } | |
| 1722 if (verify_action("Update RedBoot non-volatile configuration")) { | 1750 if (verify_action("Update RedBoot non-volatile configuration")) { |
| 1723 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 1751 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 1724 // Insure [quietly] that the config page is unlocked before trying to update | 1752 // Insure [quietly] that the config page is unlocked before trying to update |
| 1725 flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr); | 1753 flash_unlock((void *)cfg_base, cfg_size, (void **)&err_addr); |
| 1726 #endif | 1754 #endif |
| 1727 if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) { | 1755 if ((stat = flash_erase(cfg_base, cfg_size, (void **)&err_addr)) != 0) { |
| 1728 diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); | 1756 diag_printf(" initialization failed at %p: %s\n", err_addr, flash_errmsg(stat)); |
| 1729 } else { | 1757 } else { |
| 1730 if ((stat = flash_program(cfg_base, (void *)&config, | 1758 if ((stat = flash_program(cfg_base, (void *)config, sizeof(struct _config), |
| 1731 sizeof(config), (void **)&err_addr)) != 0) { | 1759 (void **)&err_addr)) != 0) { |
| 1732 diag_printf("Error writing config data at %p: %s\n", | 1760 diag_printf("Error writing config data at %p: %s\n", |
| 1733 err_addr, flash_errmsg(stat)); | 1761 err_addr, flash_errmsg(stat)); |
| 1734 } | 1762 } |
| 1735 } | 1763 } |
| 1736 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL | 1764 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL |
| 1749 unsigned char *dp; | 1777 unsigned char *dp; |
| 1750 int len; | 1778 int len; |
| 1751 | 1779 |
| 1752 if (!config_ok) return (unsigned char *)NULL; | 1780 if (!config_ok) return (unsigned char *)NULL; |
| 1753 | 1781 |
| 1754 dp = &config.config_data[0]; | 1782 dp = &config->config_data[0]; |
| 1755 while (dp < &config.config_data[sizeof(config.config_data)]) { | 1783 while (dp < &config->config_data[sizeof(config->config_data)]) { |
| 1756 len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) + | 1784 len = 4 + CONFIG_OBJECT_KEYLEN(dp) + CONFIG_OBJECT_ENABLE_KEYLEN(dp) + |
| 1757 config_length(CONFIG_OBJECT_TYPE(dp)); | 1785 config_length(CONFIG_OBJECT_TYPE(dp)); |
| 1758 if (strcmp(key, CONFIG_OBJECT_KEY(dp)) == 0) { | 1786 if (strcmp(key, CONFIG_OBJECT_KEY(dp)) == 0) { |
| 1759 return dp; | 1787 return dp; |
| 1760 } | 1788 } |
| 1855 flash_write_config(); | 1883 flash_write_config(); |
| 1856 } | 1884 } |
| 1857 return true; | 1885 return true; |
| 1858 } | 1886 } |
| 1859 // Add the data item | 1887 // Add the data item |
| 1860 dp = &config.config_data[0]; | 1888 dp = &config->config_data[0]; |
| 1861 size = 0; | 1889 size = 0; |
| 1862 while (size < sizeof(config.config_data)) { | 1890 while (size < sizeof(config->config_data)) { |
| 1863 if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) { | 1891 if (CONFIG_OBJECT_TYPE(dp) == CONFIG_EMPTY) { |
| 1864 kp = opt->key; | 1892 kp = opt->key; |
| 1865 len = strlen(kp) + 1; | 1893 len = strlen(kp) + 1; |
| 1866 size += len + 2 + 2 + config_length(opt->type); | 1894 size += len + 2 + 2 + config_length(opt->type); |
| 1867 if (opt->enable) { | 1895 if (opt->enable) { |
| 1868 elen = strlen(opt->enable) + 1; | 1896 elen = strlen(opt->enable) + 1; |
| 1869 size += elen; | 1897 size += elen; |
| 1870 } else { | 1898 } else { |
| 1871 elen = 0; | 1899 elen = 0; |
| 1872 } | 1900 } |
| 1873 if (size > sizeof(config.config_data)) { | 1901 if (size > sizeof(config->config_data)) { |
| 1874 break; | 1902 break; |
| 1875 } | 1903 } |
| 1876 CONFIG_OBJECT_TYPE(dp) = opt->type; | 1904 CONFIG_OBJECT_TYPE(dp) = opt->type; |
| 1877 CONFIG_OBJECT_KEYLEN(dp) = len; | 1905 CONFIG_OBJECT_KEYLEN(dp) = len; |
| 1878 CONFIG_OBJECT_ENABLE_SENSE(dp) = opt->enable_sense; | 1906 CONFIG_OBJECT_ENABLE_SENSE(dp) = opt->enable_sense; |
| 1909 { | 1937 { |
| 1910 // Well known option strings | 1938 // Well known option strings |
| 1911 struct config_option *optend = __CONFIG_options_TAB_END__; | 1939 struct config_option *optend = __CONFIG_options_TAB_END__; |
| 1912 struct config_option *opt = __CONFIG_options_TAB__; | 1940 struct config_option *opt = __CONFIG_options_TAB__; |
| 1913 | 1941 |
| 1914 memset(&config, 0, sizeof(config)); | 1942 memset(config, 0, sizeof(struct _config)); |
| 1915 while (opt != optend) { | 1943 while (opt != optend) { |
| 1916 if (!flash_add_config(opt, false)) { | 1944 if (!flash_add_config(opt, false)) { |
| 1917 return; | 1945 return; |
| 1918 } | 1946 } |
| 1919 opt++; | 1947 opt++; |
| 1932 bool use_boot_script; | 1960 bool use_boot_script; |
| 1933 | 1961 |
| 1934 config_ok = false; | 1962 config_ok = false; |
| 1935 script = (unsigned char *)0; | 1963 script = (unsigned char *)0; |
| 1936 if (!do_flash_init()) return; | 1964 if (!do_flash_init()) return; |
| 1965 config = (struct _config *)(workspace_end-sizeof(struct _config)); | |
| 1966 backup_config = (struct _config *)((CYG_ADDRESS)config-sizeof(struct _config)); | |
| 1967 workspace_end = (unsigned char *)backup_config; | |
| 1937 #define _roundup(n,s) ((((n)+(s-1))/s)*s) | 1968 #define _roundup(n,s) ((((n)+(s-1))/s)*s) |
| 1938 cfg_size = (block_size > sizeof(config)) ? sizeof(config) : | 1969 cfg_size = (block_size > sizeof(struct _config)) ? |
| 1939 _roundup(sizeof(config), block_size); | 1970 sizeof(struct _config) : |
| 1971 _roundup(sizeof(struct _config), block_size); | |
| 1940 if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { | 1972 if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) { |
| 1941 cfg_base = (void *)((unsigned long)flash_end + | 1973 cfg_base = (void *)((CYG_ADDRESS)flash_end + 1 + |
| 1942 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | 1974 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); |
| 1943 } else { | 1975 } else { |
| 1944 cfg_base = (void *)((unsigned long)flash_start + | 1976 cfg_base = (void *)((CYG_ADDRESS)flash_start + |
| 1945 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); | 1977 (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size)); |
| 1946 } | 1978 } |
| 1947 memcpy(&config, cfg_base, sizeof(config)); | 1979 memcpy(config, cfg_base, sizeof(struct _config)); |
| 1948 if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) || | 1980 if ((crc32((unsigned char *)config, |
| 1949 (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) { | 1981 sizeof(struct _config)-sizeof(config->cksum)) != config->cksum) || |
| 1982 (config->key1 != CONFIG_KEY1)|| (config->key2 != CONFIG_KEY2)) { | |
| 1950 diag_printf("FLASH configuration checksum error or invalid key\n"); | 1983 diag_printf("FLASH configuration checksum error or invalid key\n"); |
| 1951 config_init(); | 1984 config_init(); |
| 1952 return; | 1985 return; |
| 1953 } | 1986 } |
| 1954 config_ok = true; | 1987 config_ok = true; |
