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;