Changeset 12429
- Timestamp:
- 07/03/2009 02:56:55 AM (4 months ago)
- Files:
-
- ar5315_microredboot/microredboot/boot/src/lib/elf.c (added)
- ar5315_microredboot/microredboot/boot/src/lib/elf.h (added)
- ar5315_microredboot/microredboot/boot/src/lib/lib.c (modified) (1 diff)
- ar5315_microredboot/microredboot/boot/src/misc_lzma.c (modified) (4 diffs)
- ar5315_microredboot/microredboot/boot/src/ramconfig.h (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/devs/flash/atheros/spiflash/current/src/spiflash.c (modified) (2 diffs)
- ar5315_microredboot/microredboot/ecos/packages/io/flash/current/src/flash.c (modified) (4 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/flash.c (modified) (10 diffs)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c (modified) (1 diff)
- ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_server.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
ar5315_microredboot/microredboot/boot/src/lib/lib.c
r12320 r12429 25 25 return sc - s; 26 26 } 27 28 void *memmove( void *s1, const void *s2, size_t n ) 29 { 30 char *dst = (char *)s1; 31 const char *src = (const char *)s2; 32 if ((src < dst) && (dst < (src + n))) 33 { 34 // Have to copy backwards 35 src += n; 36 dst += n; 37 while (n--) 38 { 39 *--dst = *--src; 40 } 41 } 42 else 43 { 44 while (n--) 45 { 46 *dst++ = *src++; 47 } 48 } 49 50 51 return s1; 52 } // __memmove() 53 ar5315_microredboot/microredboot/boot/src/misc_lzma.c
r12385 r12429 87 87 88 88 int bootoffset = 0x800004bc; 89 static unsigned int uncompressedSize = 0; 89 90 90 91 /* … … 97 98 98 99 unsigned int i; 99 unsigned int uncompressedSize = 0;100 100 unsigned char *workspace; 101 101 unsigned int lc, lp, pb; … … 222 222 223 223 #include <lib/nvram.c> 224 #include <lib/elf.c> 224 225 225 226 typedef struct { … … 237 238 }; 238 239 240 static int s_memcmp(unsigned char *p1,unsigned char *p2,unsigned int len) 241 { 242 unsigned int i; 243 for (i=0;i<len;i++) 244 if (p1[i]!=p2[i]) 245 return 1; 246 return 0; 247 } 248 239 249 /* initialized commandline and starts linux. we need todo this for Atheros LSDK based firmwares since they have no ramsize detection */ 240 250 static void set_cmdline(void) 241 251 { 252 /* check elf */ 253 if (!s_memcmp(output_data,ELFMAG,SELFMAG)) 254 { 255 unsigned int loadaddr; 256 unsigned int loadaddr_end; 257 fis_load_elf_image(output_data,0,uncompressedSize,&bootoffset,&loadaddr,&loadaddr_end); 258 } 259 260 242 261 char *pcmd; 243 262 struct parmblock *pb; ar5315_microredboot/microredboot/boot/src/ramconfig.h
r12383 r12429 1 1 #define RAM_SIZE 0x2000000 2 #define AR5312 13 2 #define RESETBUTTON 0x06 ar5315_microredboot/microredboot/ecos/packages/devs/flash/atheros/spiflash/current/src/spiflash.c
r12281 r12429 314 314 opcode = (PAGE_PROGRAM_OPCODE) | ((cyg_uint32)offset << 8); 315 315 HAL_WRITE_UINT32(AR2316_SPI_OPCODE, opcode); 316 if (page_programming_supported) 316 317 *(volatile unsigned*)0xB1000090 &= ~(1<<page_gpio);//0xfffffffe;/*set GPIO0 to 0 to dominate spi flash CS to low active*/ 317 318 reg = (reg & ~SPI_CTL_TX_RX_CNT_MASK) | (first_spi_write_data_length + 4) | SPI_CTL_START; … … 327 328 } while (reg & SPI_CTL_BUSY); 328 329 330 if (page_programming_supported) 329 331 *(volatile unsigned*)0xB1000090 |= 1<<page_gpio;/*set GPIO0 to 1 to spi flash CS normal state, this will start programming*/ 330 332 ar5315_microredboot/microredboot/ecos/packages/io/flash/current/src/flash.c
r12281 r12429 159 159 } 160 160 161 void diag_blink(void); 161 162 int 162 163 flash_erase(void *addr, int len, void **err_addr) … … 232 233 #ifdef CYGSEM_IO_FLASH_CHATTER 233 234 (*flash_info.pf)("."); 235 diag_blink(); 234 236 #endif 235 237 } … … 292 294 #ifdef CYGSEM_IO_FLASH_CHATTER 293 295 (*flash_info.pf)("V"); 296 diag_blink(); 294 297 #endif 295 298 } … … 301 304 #ifdef CYGSEM_IO_FLASH_CHATTER 302 305 (*flash_info.pf)("."); 306 diag_blink(); 303 307 #endif 304 308 len -= size; ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/flash.c
r12368 r12429 58 58 #include <fis.h> 59 59 #include <sib.h> 60 #include <cyg/infra/cyg_ass.h> // assertion macros61 60 #include <cyg/infra/cyg_ass.h> // assertion macros 61 #include "ramconfig.h" 62 62 //#define CYGPRI_REDBOOT_7ZIP_FLASH 1; 63 63 … … 89 89 // Image management functions 90 90 local_cmd_entry("init", 91 "Initialize FLASH Image System [FIS]", 92 "[-f]", 93 fis_init_comp, 94 FIS_cmds 95 ); 91 "Initialize FLASH Image System [FIS]", 92 "[-f]", fis_init_comp, FIS_cmds); 96 93 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK 97 94 # define FIS_LIST_OPTS "[-c] [-d]" … … 100 97 #endif 101 98 local_cmd_entry("list", 102 "Display contents of FLASH Image System [FIS]", 103 FIS_LIST_OPTS, 104 fis_list, 105 FIS_cmds 106 ); 99 "Display contents of FLASH Image System [FIS]", 100 FIS_LIST_OPTS, fis_list, FIS_cmds); 107 101 /*local_cmd_entry("free", 108 102 "Display free [available] locations within FLASH Image System [FIS]", … … 120 114 int page_gpio = 0; 121 115 122 static char fis_load_usage[] = 116 static char fis_load_usage[] = 123 117 #ifdef CYGPRI_REDBOOT_ZLIB_FLASH 124 "[-d] "118 "[-d] " 125 119 #endif 126 120 #ifdef CYGPRI_REDBOOT_7ZIP_FLASH 127 "[-l] " 128 #endif 129 130 "[-b <memory_load_address>] [-c] name"; 121 "[-l] " 122 #endif 123 "[-b <memory_load_address>] [-c] name"; 131 124 132 125 local_cmd_entry("load", 133 "Load image from FLASH Image System [FIS] into RAM", 134 fis_load_usage, 135 fis_load, 136 FIS_cmds 137 ); 126 "Load image from FLASH Image System [FIS] into RAM", 127 fis_load_usage, fis_load, FIS_cmds); 138 128 local_cmd_entry("create", 139 "Create an image", 140 "-b <mem_base> -l <image_length> [-s <data_length>]\n" 141 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", 142 fis_create, 143 FIS_cmds 144 ); 129 "Create an image", 130 "-b <mem_base> -l <image_length> [-s <data_length>]\n" 131 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", 132 fis_create, FIS_cmds); 145 133 #if defined(CYGPKG_HAL_MIPS_AR2316) 146 134 local_cmd_entry("create256", 147 "Create an image", 148 "-b <mem_base> -l <image_length> [-s <data_length>]\n" 149 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", 150 fis_create_256, 151 FIS_cmds 152 ); 135 "Create an image", 136 "-b <mem_base> -l <image_length> [-s <data_length>]\n" 137 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", 138 fis_create_256, FIS_cmds); 153 139 local_cmd_entry("createaccton", 154 "Create an image", 155 "-b <mem_base> -l <image_length> [-s <data_length>]\n" 156 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", 157 fis_create_accton, 158 FIS_cmds 159 ); 140 "Create an image", 141 "-b <mem_base> -l <image_length> [-s <data_length>]\n" 142 " [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>", 143 fis_create_accton, FIS_cmds); 160 144 #endif 161 145 #endif … … 170 154 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING 171 155 local_cmd_entry("lock", 172 "LOCK FLASH contents", 173 "[-f <flash_addr> -l <length>] [name]", 174 fis_lock, 175 FIS_cmds 176 ); 156 "LOCK FLASH contents", 157 "[-f <flash_addr> -l <length>] [name]", fis_lock, FIS_cmds); 177 158 local_cmd_entry("unlock", 178 "UNLOCK FLASH contents", 179 "[-f <flash_addr> -l <length>] [name]", 180 fis_unlock, 181 FIS_cmds 182 ); 159 "UNLOCK FLASH contents", 160 "[-f <flash_addr> -l <length>] [name]", fis_unlock, FIS_cmds); 183 161 #endif 184 162 /*local_cmd_entry("write", … … 190 168 191 169 // Define table boundaries 192 CYG_HAL_TABLE_BEGIN( __FIS_cmds_TAB__, FIS_cmds);193 CYG_HAL_TABLE_END( __FIS_cmds_TAB_END__, FIS_cmds);170 CYG_HAL_TABLE_BEGIN(__FIS_cmds_TAB__, FIS_cmds); 171 CYG_HAL_TABLE_END(__FIS_cmds_TAB_END__, FIS_cmds); 194 172 195 173 extern struct cmd __FIS_cmds_TAB__[], __FIS_cmds_TAB_END__; … … 197 175 // CLI function 198 176 static cmd_fun do_fis; 199 RedBoot_nested_cmd("fis", 200 "Manage FLASH images", 201 "{cmds}", 202 do_fis, 203 __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__ 204 ); 177 RedBoot_nested_cmd("fis", 178 "Manage FLASH images", 179 "{cmds}", do_fis, __FIS_cmds_TAB__, &__FIS_cmds_TAB_END__); 205 180 206 181 // Local data used by these routines … … 210 185 void *fis_work_block; 211 186 void *fis_addr; 212 int fisdir_size; // Size of FIS directory.187 int fisdir_size; // Size of FIS directory. 213 188 #endif 214 189 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG 215 extern void *cfg_base; // Location in Flash of config data216 extern int cfg_size;// Length of config data - rounded to Flash block size190 extern void *cfg_base; // Location in Flash of config data 191 extern int cfg_size; // Length of config data - rounded to Flash block size 217 192 extern struct _config *config; 218 193 #endif … … 221 196 #define VXWORKS_BOARD_CFG_DATA 0xbfde0000 222 197 #define VXWORKS_RADIO_CFG_DATA 0xbfdf0000 223 #define CONSOLIDATED_DATA 0xbfdf0000 198 #define CONSOLIDATED_DATA 0xbfdf0000 224 199 #define END_OF_FLASH 0xbffff000 225 200 #elif CYGNUM_FLASH_SIZE == 0x400000 226 201 #define VXWORKS_BOARD_CFG_DATA 0xbffe0000 227 202 #define VXWORKS_RADIO_CFG_DATA 0xbfff0000 228 #define CONSOLIDATED_DATA 0xbfff0000 203 #define CONSOLIDATED_DATA 0xbfff0000 229 204 #define END_OF_FLASH 0xbffff000 230 205 #elif CYGNUM_FLASH_SIZE == 0x800000 231 206 #define VXWORKS_BOARD_CFG_DATA 0xbffe0000 232 207 #define VXWORKS_RADIO_CFG_DATA 0xbfff0000 233 #define CONSOLIDATED_DATA 0xbfff0000 208 #define CONSOLIDATED_DATA 0xbfff0000 234 209 #define END_OF_FLASH 0xbffff000 235 210 #else 236 211 #Warning! Currently works for only 2MB and 4MB 237 #endif // CYGNUM_FLASH_SIZE212 #endif // CYGNUM_FLASH_SIZE 238 213 239 214 #define HEURISTIC_SEARCH_LEN 0x60000 240 215 #define MAGIC_DATA 0x35333131 241 216 242 243 static void 244 fis_usage(char *why) 245 { 246 diag_printf("*** invalid 'fis' command: %s\n", why); 247 cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); 248 } 249 250 static void 251 _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) 252 { 253 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, flash_errmsg(stat)); 254 diag_printf(" valid range is %p-%p\n", (void *)flash_start, (void *)flash_end); 217 static void fis_usage(char *why) 218 { 219 diag_printf("*** invalid 'fis' command: %s\n", why); 220 cmd_usage(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, "fis "); 221 } 222 223 static void _show_invalid_flash_address(CYG_ADDRESS flash_addr, int stat) 224 { 225 diag_printf("Invalid FLASH address %p: %s\n", (void *)flash_addr, 226 flash_errmsg(stat)); 227 diag_printf(" valid range is %p-%p\n", (void *)flash_start, 228 (void *)flash_end); 255 229 } 256 230 … … 262 236 { 263 237 #ifdef REDBOOT_FLASH_REVERSE_BYTEORDER 264 struct fis_image_desc *p = addr; 265 int cnt = fisdir_size / sizeof(struct fis_image_desc); 266 267 while (cnt-- > 0) { 268 p->flash_base = CYG_SWAP32(p->flash_base); 269 p->mem_base = CYG_SWAP32(p->mem_base); 270 p->size = CYG_SWAP32(p->size); 271 p->entry_point = CYG_SWAP32(p->entry_point); 272 p->data_length = CYG_SWAP32(p->data_length); 273 p->desc_cksum = CYG_SWAP32(p->desc_cksum); 274 p->file_cksum = CYG_SWAP32(p->file_cksum); 275 p++; 276 } 277 #endif 278 } 279 280 void 281 fis_read_directory(void) 282 { 283 void *err_addr; 284 285 FLASH_READ(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); 286 fis_endian_fixup(fis_work_block); 287 } 288 289 struct fis_image_desc * 290 fis_lookup(char *name, int *num) 291 { 292 int i; 293 struct fis_image_desc *img; 294 295 fis_read_directory(); 296 297 img = (struct fis_image_desc *)fis_work_block; 298 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { 299 if ((img->name[0] != (unsigned char)0xFF) && 300 (strcasecmp(name, img->name) == 0)) { 301 if (num) *num = i; 302 return img; 303 } 304 } 305 return (struct fis_image_desc *)0; 306 } 307 308 void 309 fis_update_directory(void) 310 { 311 int stat; 312 void *err_addr; 313 314 fis_endian_fixup(fis_work_block); 238 struct fis_image_desc *p = addr; 239 int cnt = fisdir_size / sizeof(struct fis_image_desc); 240 241 while (cnt-- > 0) { 242 p->flash_base = CYG_SWAP32(p->flash_base); 243 p->mem_base = CYG_SWAP32(p->mem_base); 244 p->size = CYG_SWAP32(p->size); 245 p->entry_point = CYG_SWAP32(p->entry_point); 246 p->data_length = CYG_SWAP32(p->data_length); 247 p->desc_cksum = CYG_SWAP32(p->desc_cksum); 248 p->file_cksum = CYG_SWAP32(p->file_cksum); 249 p++; 250 } 251 #endif 252 } 253 254 void fis_read_directory(void) 255 { 256 void *err_addr; 257 258 FLASH_READ(fis_addr, fis_work_block, fisdir_size, (void **)&err_addr); 259 fis_endian_fixup(fis_work_block); 260 } 261 262 struct fis_image_desc *fis_lookup(char *name, int *num) 263 { 264 int i; 265 struct fis_image_desc *img; 266 267 fis_read_directory(); 268 269 img = (struct fis_image_desc *)fis_work_block; 270 for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { 271 if ((img->name[0] != (unsigned char)0xFF) && 272 (strcasecmp(name, img->name) == 0)) { 273 if (num) 274 *num = i; 275 return img; 276 } 277 } 278 return (struct fis_image_desc *)0; 279 } 280 281 void fis_update_directory(void) 282 { 283 int stat; 284 void *err_addr; 285 286 fis_endian_fixup(fis_work_block); 315 287 #ifdef CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG 316 memcpy((char *)fis_work_block+fisdir_size, config, cfg_size);317 conf_endian_fixup((char *)fis_work_block+fisdir_size);288 memcpy((char *)fis_work_block + fisdir_size, config, cfg_size); 289 conf_endian_fixup((char *)fis_work_block + fisdir_size); 318 290 #endif 319 291 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL 320 // Ensure [quietly] that the directory is unlocked before trying to update 321 flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr); 322 #endif 323 if ((stat = flash_erase(fis_addr, flash_block_size, (void **)&err_addr)) != 0) { 324 diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat)); 325 } else { 326 if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block, 327 flash_block_size, (void **)&err_addr)) != 0) { 328 diag_printf("Error writing FIS directory at %p: %s\n", 329 err_addr, flash_errmsg(stat)); 330 } 331 } 292 // Ensure [quietly] that the directory is unlocked before trying to update 293 flash_unlock((void *)fis_addr, flash_block_size, (void **)&err_addr); 294 #endif 295 if ((stat = 296 flash_erase(fis_addr, flash_block_size, 297 (void **)&err_addr)) != 0) { 298 diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, 299 flash_errmsg(stat)); 300 } else { 301 if ((stat = FLASH_PROGRAM(fis_addr, fis_work_block, 302 flash_block_size, 303 (void **)&err_addr)) != 0) { 304 diag_printf("Error writing FIS directory at %p: %s\n", 305 err_addr, flash_errmsg(stat)); 306 } 307 } 332 308 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL 333 // Ensure [quietly] that the directory is locked after the update 334 flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); 335 #endif 336 fis_endian_fixup(fis_work_block); 337 } 338 void fis_init(int argc, char *argv[],int force); 309 // Ensure [quietly] that the directory is locked after the update 310 flash_lock((void *)fis_addr, flash_block_size, (void **)&err_addr); 311 #endif 312 fis_endian_fixup(fis_work_block); 313 } 314 315 void fis_init(int argc, char *argv[], int force); 339 316 340 317 static void fis_init_comp(int argc, char *argv[]) 341 318 { 342 fis_init(argc, argv,0); 343 } 344 void fis_init(int argc, char *argv[],int force) 345 { 346 int stat; 347 struct fis_image_desc *img; 348 void *err_addr; 349 bool full_init = false; 350 struct option_info opts[1]; 351 CYG_ADDRESS redboot_flash_start; 352 unsigned long redboot_image_size; 353 354 init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, 355 (void *)&full_init, (bool *)0, "full initialization, erases all of flash"); 356 if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) 357 { 358 return; 359 } 360 361 if (!force && !verify_action("About to initialize [format] FLASH image system")) { 362 diag_printf("** Aborted\n"); 363 return; 364 } 365 diag_printf("*** Initialize FLASH Image System\n"); 366 319 fis_init(argc, argv, 0); 320 } 321 322 void fis_init(int argc, char *argv[], int force) 323 { 324 int stat; 325 struct fis_image_desc *img; 326 void *err_addr; 327 bool full_init = false; 328 struct option_info opts[1]; 329 CYG_ADDRESS redboot_flash_start; 330 unsigned long redboot_image_size; 331 332 init_opts(&opts[0], 'f', false, OPTION_ARG_TYPE_FLG, 333 (void *)&full_init, (bool *) 0, 334 "full initialization, erases all of flash"); 335 if (!scan_opts(argc, argv, 2, opts, 1, 0, 0, "")) { 336 return; 337 } 338 339 if (!force 340 && 341 !verify_action("About to initialize [format] FLASH image system")) { 342 diag_printf("** Aborted\n"); 343 return; 344 } 345 diag_printf("*** Initialize FLASH Image System\n"); 367 346 368 347 #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE 369 redboot_image_size = flash_block_size > MIN_REDBOOT_IMAGE_SIZE ? 370 flash_block_size : MIN_REDBOOT_IMAGE_SIZE;371 372 // Create a pseudo image for RedBoot373 img = (struct fis_image_desc *)fis_work_block;374 memset(img, 0xFF, fisdir_size);// Start with erased data348 redboot_image_size = flash_block_size > MIN_REDBOOT_IMAGE_SIZE ? 349 flash_block_size : MIN_REDBOOT_IMAGE_SIZE; 350 351 // Create a pseudo image for RedBoot 352 img = (struct fis_image_desc *)fis_work_block; 353 memset(img, 0xFF, fisdir_size); // Start with erased data 375 354 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE 376 memset(img, 0, sizeof(*img)); 377 strcpy(img->name, "(reserved)"); 378 img->flash_base = (CYG_ADDRESS)flash_start; 379 img->mem_base = (CYG_ADDRESS)flash_start; 380 img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE; 381 img++; 382 #endif 383 redboot_flash_start = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; 355 memset(img, 0, sizeof(*img)); 356 strcpy(img->name, "(reserved)"); 357 img->flash_base = (CYG_ADDRESS) flash_start; 358 img->mem_base = (CYG_ADDRESS) flash_start; 359 img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE; 360 img++; 361 #endif 362 redboot_flash_start = 363 (CYG_ADDRESS) flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; 384 364 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT 385 memset(img, 0, sizeof(*img));386 strcpy(img->name, "RedBoot");387 img->flash_base = redboot_flash_start;388 img->mem_base = redboot_flash_start;389 img->size = redboot_image_size;390 img++;391 redboot_flash_start += redboot_image_size;365 memset(img, 0, sizeof(*img)); 366 strcpy(img->name, "RedBoot"); 367 img->flash_base = redboot_flash_start; 368 img->mem_base = redboot_flash_start; 369 img->size = redboot_image_size; 370 img++; 371 redboot_flash_start += redboot_image_size; 392 372 #endif 393 373 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST 394 374 #ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET 395 // Take care to place the POST entry at the right offset: 396 redboot_flash_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; 397 #endif 398 memset(img, 0, sizeof(*img)); 399 strcpy(img->name, "RedBoot[post]"); 400 img->flash_base = redboot_flash_start; 401 img->mem_base = redboot_flash_start; 402 img->size = redboot_image_size; 403 img++; 404 redboot_flash_start += redboot_image_size; 375 // Take care to place the POST entry at the right offset: 376 redboot_flash_start = 377 (CYG_ADDRESS) flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET; 378 #endif 379 memset(img, 0, sizeof(*img)); 380 strcpy(img->name, "RedBoot[post]"); 381 img->flash_base = redboot_flash_start; 382 img->mem_base = redboot_flash_start; 383 img->size = redboot_image_size; 384 img++; 385 redboot_flash_start += redboot_image_size; 405 386 #endif 406 387 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP 407 // And a backup image408 memset(img, 0, sizeof(*img));409 strcpy(img->name, "RedBoot[backup]");410 img->flash_base = redboot_flash_start;411 img->mem_base = redboot_flash_start;412 img->size = redboot_image_size;413 img++;414 redboot_flash_start += redboot_image_size;388 // And a backup image 389 memset(img, 0, sizeof(*img)); 390 strcpy(img->name, "RedBoot[backup]"); 391 img->flash_base = redboot_flash_start; 392 img->mem_base = redboot_flash_start; 393 img->size = redboot_image_size; 394 img++; 395 redboot_flash_start += redboot_image_size; 415 396 #endif 416 397 #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH) 417 // And a descriptor for the configuration data418 memset(img, 0, sizeof(*img));419 strcpy(img->name, "RedBoot config");420 img->flash_base = (CYG_ADDRESS)cfg_base;421 img->mem_base = (CYG_ADDRESS)cfg_base;422 img->size = cfg_size;423 img++;424 #endif 425 // And a descriptor for the descriptor table itself426 memset(img, 0, sizeof(*img));427 strcpy(img->name, "FIS directory");428 img->flash_base = (CYG_ADDRESS)fis_addr;429 img->mem_base = (CYG_ADDRESS)fis_addr;430 img->size = fisdir_size;431 img++;398 // And a descriptor for the configuration data 399 memset(img, 0, sizeof(*img)); 400 strcpy(img->name, "RedBoot config"); 401 img->flash_base = (CYG_ADDRESS) cfg_base; 402 img->mem_base = (CYG_ADDRESS) cfg_base; 403 img->size = cfg_size; 404 img++; 405 #endif 406 // And a descriptor for the descriptor table itself 407 memset(img, 0, sizeof(*img)); 408 strcpy(img->name, "FIS directory"); 409 img->flash_base = (CYG_ADDRESS) fis_addr; 410 img->mem_base = (CYG_ADDRESS) fis_addr; 411 img->size = fisdir_size; 412 img++; 432 413 433 414 #ifdef CYGOPT_REDBOOT_FIS_DIRECTORY_ARM_SIB_ID 434 // FIS gets the size of a full block - note, this should be changed 435 // if support is added for multi-block FIS structures. 436 img = (struct fis_image_desc *)((CYG_ADDRESS)fis_work_block + fisdir_size); 437 // Add a footer so the FIS will be recognized by the ARM Boot 438 // Monitor as a reserved area. 439 { 440 tFooter* footer_p = (tFooter*)((CYG_ADDRESS)img - sizeof(tFooter)); 441 cyg_uint32 check = 0; 442 cyg_uint32 *check_ptr = (cyg_uint32 *)footer_p; 443 cyg_int32 count = (sizeof(tFooter) - 4) >> 2; 444 445 // Prepare footer. Try to protect all but the reserved space 446 // and the first RedBoot image (which is expected to be 447 // bootable), but fall back to just protecting the FIS if it's 448 // not at the default position in the flash. 415 // FIS gets the size of a full block - note, this should be changed 416 // if support is added for multi-block FIS structures. 417 img = 418 (struct fis_image_desc *)((CYG_ADDRESS) fis_work_block + 419 fisdir_size); 420 // Add a footer so the FIS will be recognized by the ARM Boot 421 // Monitor as a reserved area. 422 { 423 tFooter *footer_p = 424 (tFooter *) ((CYG_ADDRESS) img - sizeof(tFooter)); 425 cyg_uint32 check = 0; 426 cyg_uint32 *check_ptr = (cyg_uint32 *) footer_p; 427 cyg_int32 count = (sizeof(tFooter) - 4) >> 2; 428 429 // Prepare footer. Try to protect all but the reserved space 430 // and the first RedBoot image (which is expected to be 431 // bootable), but fall back to just protecting the FIS if it's 432 // not at the default position in the flash. 449 433 #if defined(CYGOPT_REDBOOT_FIS_RESERVED_BASE) && (-1 == CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK) 450 footer_p->blockBase = (char*)_ADDR_REDBOOT_TO_ARM(flash_start); 451 footer_p->blockBase += CYGNUM_REDBOOT_FLASH_RESERVED_BASE + redboot_image_size; 434 footer_p->blockBase = (char *)_ADDR_REDBOOT_TO_ARM(flash_start); 435 footer_p->blockBase += 436 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + redboot_image_size; 452 437 #else 453 footer_p->blockBase = (char*)_ADDR_REDBOOT_TO_ARM(fis_work_block); 454 #endif 455 footer_p->infoBase = NULL; 456 footer_p->signature = FLASH_FOOTER_SIGNATURE; 457 footer_p->type = TYPE_REDHAT_REDBOOT; 458 459 // and compute its checksum 460 for ( ; count > 0; count--) { 461 if (*check_ptr > ~check) 462 check++; 463 check += *check_ptr++; 464 } 465 footer_p->checksum = ~check; 466 } 467 #endif 468 469 // Do this after creating the initialized table because that inherently 470 // calculates where the high water mark of default RedBoot images is. 471 472 if (full_init) { 473 unsigned long erase_size; 474 CYG_ADDRESS erase_start; 475 // Erase everything except default RedBoot images, fis block, 476 // and config block. 477 // First deal with the possible first part, before RedBoot images: 438 footer_p->blockBase = 439 (char *)_ADDR_REDBOOT_TO_ARM(fis_work_block); 440 #endif 441 footer_p->infoBase = NULL; 442 footer_p->signature = FLASH_FOOTER_SIGNATURE; 443 footer_p->type = TYPE_REDHAT_REDBOOT; 444 445 // and compute its checksum 446 for (; count > 0; count--) { 447 if (*check_ptr > ~check) 448 check++; 449 check += *check_ptr++; 450 } 451 footer_p->checksum = ~check; 452 } 453 #endif 454 455 // Do this after creating the initialized table because that inherently 456 // calculates where the high water mark of default RedBoot images is. 457 458 if (full_init) { 459 unsigned long erase_size; 460 CYG_ADDRESS erase_start; 461 // Erase everything except default RedBoot images, fis block, 462 // and config block. 463 // First deal with the possible first part, before RedBoot images: 478 464 #if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET > CYGNUM_REDBOOT_FLASH_RESERVED_BASE) 479 erase_start = (CYG_ADDRESS)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE; 480 erase_size = (CYG_ADDRESS)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; 481 if ( erase_size > erase_start ) { 482 erase_size -= erase_start; 483 if ((stat = flash_erase((void *)erase_start, erase_size, 484 (void **)&err_addr)) != 0) { 485 diag_printf(" initialization failed at %p: %s\n", 486 err_addr, flash_errmsg(stat)); 487 } 488 } 489 #endif 490 // second deal with the larger part in the main: 491 erase_start = redboot_flash_start; // high water of created images 492 // Now the empty bits between the end of Redboot and the cfg and dir 493 // blocks. 465 erase_start = 466 (CYG_ADDRESS) flash_start + 467 CYGNUM_REDBOOT_FLASH_RESERVED_BASE; 468 erase_size = 469 (CYG_ADDRESS) flash_start + 470 CYGBLD_REDBOOT_FLASH_BOOT_OFFSET; 471 if (erase_size > erase_start) { 472 erase_size -= erase_start; 473 if ((stat = flash_erase((void *)erase_start, erase_size, 474 (void **)&err_addr)) != 0) { 475 diag_printf 476 (" initialization failed at %p: %s\n", 477 err_addr, flash_errmsg(stat)); 478 } 479 } 480 #endif 481 // second deal with the larger part in the main: 482 erase_start = redboot_flash_start; // high water of created images 483 // Now the empty bits between the end of Redboot and the cfg and dir 484 // blocks. 494 485 #if defined(CYGSEM_REDBOOT_FLASH_CONFIG) && \ 495 486 defined(CYGHWR_REDBOOT_FLASH_CONFIG_MEDIA_FLASH) && \ 496 487 !defined(CYGSEM_REDBOOT_FLASH_COMBINED_FIS_AND_CONFIG) 497 if (fis_addr > cfg_base) { 498 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between HWM and config data 499 } else { 500 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data 501 } 502 if ((stat = flash_erase((void *)erase_start, erase_size, 503 (void **)&err_addr)) != 0) { 504 diag_printf(" initialization failed %p: %s\n", 505 err_addr, flash_errmsg(stat)); 506 } 507 erase_start += (erase_size + flash_block_size); 508 if (fis_addr > cfg_base) { 509 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between config and fis data 510 } else { 511 erase_size = (CYG_ADDRESS)cfg_base - erase_start; // the gap between fis and config data 512 } 513 if ((stat = flash_erase((void *)erase_start, erase_size, 514 (void **)&err_addr)) != 0) { 515 diag_printf(" initialization failed %p: %s\n", 516 err_addr, flash_errmsg(stat)); 517 } 518 erase_start += (erase_size + flash_block_size); 519 #else // !CYGSEM_REDBOOT_FLASH_CONFIG 520 erase_size = (CYG_ADDRESS)fis_addr - erase_start; // the gap between HWM and fis data 521 if ((stat = flash_erase((void *)erase_start, erase_size, 522 (void **)&err_addr)) != 0) { 523 diag_printf(" initialization failed %p: %s\n", 524 err_addr, flash_errmsg(stat)); 525 } 526 erase_start += (erase_size + flash_block_size); 527 #endif 528 // Lastly, anything at the end, if there is any 529 if ( erase_start < (((CYG_ADDRESS)flash_end)+1) ) { 530 erase_size = ((CYG_ADDRESS)flash_end - erase_start) + 1; 531 if ((stat = flash_erase((void *)erase_start, erase_size, 532 (void **)&err_addr)) != 0) { 533 diag_printf(" initialization failed at %p: %s\n", 534 err_addr, flash_errmsg(stat)); 535 } 536 } 488 if (fis_addr > cfg_base) { 489 erase_size = (CYG_ADDRESS) cfg_base - erase_start; // the gap between HWM and config data 490 } else { 491 erase_size = (CYG_ADDRESS) fis_addr - erase_start; // the gap between HWM and fis data 492 } 493 if ((stat = flash_erase((void *)erase_start, erase_size, 494 (void **)&err_addr)) != 0) { 495 diag_printf(" initialization failed %p: %s\n", 496 err_addr, flash_errmsg(stat)); 497 } 498 erase_start += (erase_size + flash_block_size); 499 if (fis_addr > cfg_base) { 500 erase_size = (CYG_ADDRESS) fis_addr - erase_start; // the gap between config and fis data 501 } else { 502 erase_size = (CYG_ADDRESS) cfg_base - erase_start; // the gap between fis and config data 503 } 504 if ((stat = flash_erase((void *)erase_start, erase_size, 505 (void **)&err_addr)) != 0) { 506 diag_printf(" initialization failed %p: %s\n", 507 err_addr, flash_errmsg(stat)); 508 } 509 erase_start += (erase_size + flash_block_size); 510 #else // !CYGSEM_REDBOOT_FLASH_CONFIG 511 erase_size = (CYG_ADDRESS) fis_addr - erase_start; // the gap between HWM and fis data 512 if ((stat = flash_erase((void *)erase_start, erase_size, 513 (void **)&err_addr)) != 0) { 514 diag_printf(" initialization failed %p: %s\n", 515 err_addr, flash_errmsg(stat)); 516 } 517 erase_start += (erase_size + flash_block_size); 518 #endif 519 // Lastly, anything at the end, if there is any 520 if (erase_start < (((CYG_ADDRESS) flash_end) + 1)) { 521 erase_size = 522 ((CYG_ADDRESS) flash_end - erase_start) + 1; 523 if ((stat = 524 flash_erase((void *)erase_start, erase_size, 525 (void **)&err_addr)) != 0) { 526 diag_printf 527 (" initialization failed at %p: %s\n", 528 err_addr, flash_errmsg(stat)); 529 } 530 } 537 531 #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS 538 // In this case, 'fis free' works by scanning for erased blocks. Since the539 // "-f" option was not supplied, there may be areas which are not used but540 // don't appear to be free since they are not erased - thus the warning541 } else {542 diag_printf(" Warning: device contents not erased, some blocks may not be usable\n"); 543 #endif 544 } 545 fis_update_directory(); 546 } 547 548 static void 549 fis_list(int argc, char *argv[])550 { 551 struct fis_image_desc *img;552 int i, image_indx;553 bool show_cksums = false;554 bool show_datalen = false;555 struct option_info opts[2];556 unsigned long last_addr, lowest_addr;557 bool image_found;532 // In this case, 'fis free' works by scanning for erased blocks. Since the 533 // "-f" option was not supplied, there may be areas which are not used but 534 // don't appear to be free since they are not erased - thus the warning 535 } else { 536 diag_printf 537 (" Warning: device contents not erased, some blocks may not be usable\n"); 538 #endif 539 } 540 fis_update_directory(); 541 } 542 543 static void fis_list(int argc, char *argv[]) 544 { 545 struct fis_image_desc *img; 546 int i, image_indx; 547 bool show_cksums = false; 548 bool show_datalen = false; 549 struct option_info opts[2]; 550 unsigned long last_addr, lowest_addr; 551 bool image_found; 558 552 559 553 #ifdef CYGHWR_REDBOOT_ARM_FLASH_SIB 560 // FIXME: this is somewhat half-baked561 extern void arm_fis_list(void);562 arm_fis_list();563 return;564 #endif 565 566 init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, 567 (void *)&show_datalen, (bool *)0, "display data length");554 // FIXME: this is somewhat half-baked 555 extern void arm_fis_list(void); 556 arm_fis_list(); 557 return; 558 #endif 559 560 init_opts(&opts[0], 'd', false, OPTION_ARG_TYPE_FLG, 561 (void *)&show_datalen, (bool *) 0, "display data length"); 568 562 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK 569 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 570 (void *)&show_cksums, (bool *)0, "display checksums");571 i = 2;563 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 564 (void *)&show_cksums, (bool *) 0, "display checksums"); 565 i = 2; 572 566 #else 573 i = 1; 574 #endif 575 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { 576 return; 577 } 578 fis_read_directory(); 579 580 // Let diag_printf do the formatting in both cases, rather than counting 581 // cols by hand.... 582 diag_printf("%-16s %-10s %-10s %-10s %-s\n", 583 "Name","FLASH addr", 584 show_cksums ? "Checksum" : "Mem addr", 585 show_datalen ? "Datalen" : "Length", 586 "Entry point" ); 587 last_addr = 0; 588 image_indx = 0; 589 do { 590 image_found = false; 591 lowest_addr = 0xFFFFFFFF; 592 img = (struct fis_image_desc *) fis_work_block; 593 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { 594 if (img->name[0] != (unsigned char)0xFF) { 595 if ((img->flash_base > last_addr) && (img->flash_base < lowest_addr)) { 596 lowest_addr = img->flash_base; 597 image_found = true; 598 image_indx = i; 599 } 600 } 601 } 602 if (image_found) { 603 img = (struct fis_image_desc *) fis_work_block; 604 img += image_indx; 605 diag_printf("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", img->name, 606 img->flash_base, 567 i = 1; 568 #endif 569 if (!scan_opts(argc, argv, 2, opts, i, 0, 0, "")) { 570 return; 571 } 572 fis_read_directory(); 573 574 // Let diag_printf do the formatting in both cases, rather than counting 575 // cols by hand.... 576 diag_printf("%-16s %-10s %-10s %-10s %-s\n", 577 "Name", "FLASH addr", 578 show_cksums ? "Checksum" : "Mem addr", 579 show_datalen ? "Datalen" : "Length", "Entry point"); 580 last_addr = 0; 581 image_indx = 0; 582 do { 583 image_found = false; 584 lowest_addr = 0xFFFFFFFF; 585 img = (struct fis_image_desc *)fis_work_block; 586 for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { 587 if (img->name[0] != (unsigned char)0xFF) { 588 if ((img->flash_base > last_addr) 589 && (img->flash_base < lowest_addr)) { 590 lowest_addr = img->flash_base; 591 image_found = true; 592 image_indx = i; 593 } 594 } 595 } 596 if (image_found) { 597 img = (struct fis_image_desc *)fis_work_block; 598 img += image_indx; 599 diag_printf 600 ("%-16s 0x%08lX 0x%08lX 0x%08lX 0x%08lX\n", 601 img->name, img->flash_base, 607 602 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK 608 show_cksums ? img->file_cksum : img->mem_base, 609 show_datalen ? img->data_length : img->size, 603 show_cksums ? img->file_cksum : img->mem_base, 604 show_datalen ? img->data_length : img->size, 610 605 #else 611 img->mem_base, 612 img->size, 613 #endif 614 img->entry_point); 615 } 616 last_addr = lowest_addr; 617 } while (image_found == true); 606 img->mem_base, img->size, 607 #endif 608 img->entry_point); 609 } 610 last_addr = lowest_addr; 611 } while (image_found == true); 618 612 } 619 613 620 614 #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS 621 615 struct free_chunk { 622 CYG_ADDRESS start, end;616 CYG_ADDRESS start, end; 623 617 }; 624 618 625 static int 626 find_free(struct free_chunk *chunks) 627 { 628 CYG_ADDRESS *fis_ptr, *fis_end; 629 struct fis_image_desc *img; 630 int i, idx; 631 int num_chunks = 1; 632 633 // Do not search the area reserved for pre-RedBoot systems: 634 fis_ptr = (CYG_ADDRESS *)((CYG_ADDRESS)flash_start + 635 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + 636 CYGBLD_REDBOOT_MIN_IMAGE_SIZE); 637 fis_end = (CYG_ADDRESS *)flash_end; 638 chunks[num_chunks-1].start = (CYG_ADDRESS)fis_ptr; 639 chunks[num_chunks-1].end = (CYG_ADDRESS)fis_end; 640 fis_read_directory(); 641 img = (struct fis_image_desc *) fis_work_block; 642 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { 643 if (img->name[0] != (unsigned char)0xFF) { 644 // Figure out which chunk this is in and split it 645 for (idx = 0; idx < num_chunks; idx++) { 646 if ((img->flash_base >= chunks[idx].start) && 647 (img->flash_base <= chunks[idx].end)) { 648 if (img->flash_base == chunks[idx].start) { 649 chunks[idx].start += img->size; 650 if (chunks[idx].start >= chunks[idx].end) { 651 // This free chunk has collapsed 652 while (idx < (num_chunks-1)) { 653 chunks[idx] = chunks[idx+1]; 654 idx++; 655 } 656 num_chunks--; 657 } 658 } else if ((img->flash_base+img->size) == chunks[idx].end) { 659 chunks[idx].end = img->flash_base; 660 } else { 661 // Split chunk into two parts 662 if ((img->flash_base+img->size) < (CYG_ADDRESS)fis_end) { 663 chunks[idx+1].start = img->flash_base + img->size; 664 chunks[idx+1].end = chunks[idx].end; 665 if (++num_chunks == CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) { 666 diag_printf("Warning: too many free chunks\n"); 667 return num_chunks; 668 } 669 } 670 chunks[idx].end = img->flash_base; 671 } 672 break; 673 } 674 } 675 } 676 } 677 return num_chunks; 678 } 679 #endif // CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS 680 619 static int find_free(struct free_chunk *chunks) 620 { 621 CYG_ADDRESS *fis_ptr, *fis_end; 622 struct fis_image_desc *img; 623 int i, idx; 624 int num_chunks = 1; 625 626 // Do not search the area reserved for pre-RedBoot systems: 627 fis_ptr = (CYG_ADDRESS *) ((CYG_ADDRESS) flash_start + 628 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + 629 CYGBLD_REDBOOT_MIN_IMAGE_SIZE); 630 fis_end = (CYG_ADDRESS *) flash_end; 631 chunks[num_chunks - 1].start = (CYG_ADDRESS) fis_ptr; 632 chunks[num_chunks - 1].end = (CYG_ADDRESS) fis_end; 633 fis_read_directory(); 634 img = (struct fis_image_desc *)fis_work_block; 635 for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { 636 if (img->name[0] != (unsigned char)0xFF) { 637 // Figure out which chunk this is in and split it 638 for (idx = 0; idx < num_chunks; idx++) { 639 if ((img->flash_base >= chunks[idx].start) && 640 (img->flash_base <= chunks[idx].end)) { 641 if (img->flash_base == 642 chunks[idx].start) { 643 chunks[idx].start += img->size; 644 if (chunks[idx].start >= 645 chunks[idx].end) { 646 // This free chunk has collapsed 647 while (idx < 648 (num_chunks - 649 1)) { 650 chunks[idx] = 651 chunks[idx + 652 1]; 653 idx++; 654 } 655 num_chunks--; 656 } 657 } else if ((img->flash_base + img->size) 658 == chunks[idx].end) { 659 chunks[idx].end = 660 img->flash_base; 661 } else { 662 // Split chunk into two parts 663 if ((img->flash_base + 664 img->size) < 665 (CYG_ADDRESS) fis_end) { 666 chunks[idx + 1].start = 667 img->flash_base + 668 img->size; 669 chunks[idx + 1].end = 670 chunks[idx].end; 671 if (++num_chunks == 672 CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS) 673 { 674 diag_printf 675 ("Warning: too many free chunks\n"); 676 return 677 num_chunks; 678 } 679 } 680 chunks[idx].end = 681 img->flash_base; 682 } 683 break; 684 } 685 } 686 } 687 } 688 return num_chunks; 689 } 690 #endif // CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS 681 691 682 692 // Find the first unused area of flash which is long enough 683 static bool 684 fis_find_free(CYG_ADDRESS *addr, unsigned long length) 693 static bool fis_find_free(CYG_ADDRESS * addr, unsigned long length) 685 694 { 686 695 #ifndef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS 687 unsigned long *fis_ptr, *fis_end, flash_data; 688 unsigned long *area_start; 689 void *err_addr; 690 691 // Do not search the area reserved for pre-RedBoot systems: 692 fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start + 693 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + 694 CYGBLD_REDBOOT_MIN_IMAGE_SIZE); 695 fis_end = (unsigned long *)(CYG_ADDRESS)flash_end; 696 area_start = fis_ptr; 697 while (fis_ptr < fis_end) { 698 flash_read(fis_ptr, &flash_data, sizeof(unsigned long), (void **)&err_addr); 699 if (flash_data != (unsigned long)0xFFFFFFFF) { 700 if (area_start != fis_ptr) { 701 // Assume that this is something 702 if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { 703 *addr = (CYG_ADDRESS)area_start; 704 return true; 705 } 706 } 707 // Find next blank block 708 area_start = fis_ptr; 709 while (area_start < fis_end) { 710 flash_read(area_start, &flash_data, sizeof(unsigned long), (void **)&err_addr); 711 if (flash_data == (unsigned long)0xFFFFFFFF) { 712 break; 713 } 714 area_start += flash_block_size / sizeof(CYG_ADDRESS); 715 } 716 fis_ptr = area_start; 717 } else { 718 fis_ptr += flash_block_size / sizeof(CYG_ADDRESS); 719 } 720 } 721 if (area_start != fis_ptr) { 722 if ((fis_ptr-area_start) >= (length/sizeof(unsigned))) { 723 *addr = (CYG_ADDRESS)area_start; 724 return true; 725 } 726 } 727 return false; 696 unsigned long *fis_ptr, *fis_end, flash_data; 697 unsigned long *area_start; 698 void *err_addr; 699 700 // Do not search the area reserved for pre-RedBoot systems: 701 fis_ptr = (unsigned long *)((CYG_ADDRESS) flash_start + 702 CYGNUM_REDBOOT_FLASH_RESERVED_BASE + 703 CYGBLD_REDBOOT_MIN_IMAGE_SIZE); 704 fis_end = (unsigned long *)(CYG_ADDRESS) flash_end; 705 area_start = fis_ptr; 706 while (fis_ptr < fis_end) { 707 flash_read(fis_ptr, &flash_data, sizeof(unsigned long), 708 (void **)&err_addr); 709 if (flash_data != (unsigned long)0xFFFFFFFF) { 710 if (area_start != fis_ptr) { 711 // Assume that this is something 712 if ((fis_ptr - area_start) >= 713 (length / sizeof(unsigned))) { 714 *addr = (CYG_ADDRESS) area_start; 715 return true; 716 } 717 } 718 // Find next blank block 719 area_start = fis_ptr; 720 while (area_start < fis_end) { 721 flash_read(area_start, &flash_data, 722 sizeof(unsigned long), 723 (void **)&err_addr); 724 if (flash_data == (unsigned long)0xFFFFFFFF) { 725 break; 726 } 727 area_start += 728 flash_block_size / sizeof(CYG_ADDRESS); 729 } 730 fis_ptr = area_start; 731 } else { 732 fis_ptr += flash_block_size / sizeof(CYG_ADDRESS); 733 } 734 } 735 if (area_start != fis_ptr) { 736 if ((fis_ptr - area_start) >= (length / sizeof(unsigned))) { 737 *addr = (CYG_ADDRESS) area_start; 738 return true; 739 } 740 } 741 return false; 728 742 #else 729 struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; 730 int idx, num_chunks; 731 732 num_chunks = find_free(chunks); 733 for (idx = 0; idx < num_chunks; idx++) { 734 if ((chunks[idx].end - chunks[idx].start) >= length) { 735 *addr = (CYG_ADDRESS)chunks[idx].start; 736 return true; 737 } 738 } 739 return false; 740 #endif 741 } 742 743 static void 744 fis_create_old(int argc, char *argv[]) 745 { 746 int i, stat; 747 unsigned long length, img_size; 748 CYG_ADDRESS mem_addr, exec_addr, flash_addr, entry_addr; 749 char *name; 750 bool mem_addr_set = false; 751 bool exec_addr_set = false; 752 bool entry_addr_set = false; 753 bool flash_addr_set = false; 754 bool length_set = false; 755 bool img_size_set = false; 756 bool no_copy = false; 757 void *err_addr; 758 struct fis_image_desc *img = NULL; 759 bool defaults_assumed; 760 struct option_info opts[7]; 761 bool prog_ok = true; 762 763 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 764 (void *)&mem_addr, (bool *)&mem_addr_set, "memory base address"); 765 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, 766 (void *)&exec_addr, (bool *)&exec_addr_set, "ram base address"); 767 init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, 768 (void *)&entry_addr, (bool *)&entry_addr_set, "entry point address"); 769 init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, 770 (void *)&flash_addr, (bool *)&flash_addr_set, "FLASH memory base address"); 771 init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, 772 (void *)&length, (bool *)&length_set, "image length [in FLASH]"); 773 init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, 774 (void *)&img_size, (bool *)&img_size_set, "image size [actual data]"); 775 init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, 776 (void *)&no_copy, (bool *)0, "don't copy from RAM to FLASH, just update directory"); 777 if (!scan_opts(argc, argv, 2, opts, 7, (void *)&name, OPTION_ARG_TYPE_STR, "file name")) 778 { 779 fis_usage("invalid arguments"); 780 return; 781 } 782 783 fis_read_directory(); 784 defaults_assumed = false; 785 if (name) { 786 // Search existing files to acquire defaults for params not specified: 787 img = fis_lookup(name, NULL); 788 if (img) { 789 // Found it, so get image size from there 790 if (!length_set) { 791 length_set = true; 792 length = img->size; 793 defaults_assumed = true; 794 } 795 } 796 } 797 if (!mem_addr_set && (load_address >= (CYG_ADDRESS)ram_start) && 798 (load_address_end) < (CYG_ADDRESS)ram_end) { 799 mem_addr = load_address; 800 mem_addr_set = true; 801 defaults_assumed = true; 802 // Get entry address from loader, unless overridden 803 if (!entry_addr_set) 804 entry_addr = entry_address; 805 if (!length_set) { 806 length = load_address_end - load_address; 807 length_set = true; 808 } else if (defaults_assumed && !img_size_set) { 809 /* We got length from the FIS table, so the size of the 810 actual loaded image becomes img_size */ 811 img_size = load_address_end - load_address; 812 img_size_set = true; 813 } 814 } 815 // Get the remaining fall-back values from the fis 816 if (img) { 817 if (!exec_addr_set) { 818 // Preserve "normal" behaviour 819 exec_addr_set = true; 820 exec_addr = flash_addr_set ? flash_addr : mem_addr; 821 } 822 if (!flash_addr_set) { 823 flash_addr_set = true; 824 flash_addr = img->flash_base; 825 defaults_assumed = true; 826 } 827 } 828 829 if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || 830 !length_set || !name) { 831 fis_usage("required parameter missing"); 832 return; 833 } 834 if (!img_size_set) { 835 img_size = length; 836 } 837 // 'length' is size of FLASH image, 'img_size' is actual data size 838 // Round up length to FLASH block size 839 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken 840 length = ((length + flash_block_size - 1) / flash_block_size) * flash_block_size; 841 if (length < img_size) { 842 diag_printf("Invalid FLASH image size/length combination\n"); 843 return; 844 } 845 #endif 846 if (flash_addr_set && 847 ((stat = flash_verify_addr((void *)flash_addr)) || 848 (stat = flash_verify_addr((void *)(flash_addr+length-1))))) { 849 _show_invalid_flash_address(flash_addr, stat); 850 return; 851 } 852 if (flash_addr_set && ((flash_addr & (flash_block_size-1)) != 0)) { 853 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); 854 diag_printf(" must be 0x%x aligned\n", flash_block_size); 855 return; 856 } 857 if (strlen(name) >= sizeof(img->name)) { 858 diag_printf("Name is too long, must be less than %d chars\n", (int)sizeof(img->name)); 859 return; 860 } 861 if (!no_copy) { 862 if ((mem_addr < (CYG_ADDRESS)ram_start) || 863 ((mem_addr+img_size) >= (CYG_ADDRESS)ram_end)) { 864 diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr); 865 diag_printf(" valid range is %p-%p\n", (void *)ram_start, (void *)ram_end); 866 } 867 if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { 868 diag_printf("Can't locate %lx(%ld) bytes free in FLASH\n", length, length); 869 return; 870 } 871 } 872 // First, see if the image by this name has agreable properties 873 if (img) { 874 if (flash_addr_set && (img->flash_base != flash_addr)) { 875 diag_printf("Image found, but flash address (%p)\n" 876 " is incorrect (present image location %p)\n", 877 flash_addr, img->flash_base); 878 879 return; 880 } 881 if (img->size != length) { 882 diag_printf("Image found, but length (0x%lx, necessitating image size 0x%lx)\n" 883 " is incorrect (present image size 0x%lx)\n", 884 img_size, length, img->size); 885 return; 886 } 887 if (!verify_action("An image named '%s' exists", name)) { 888 return; 889 } else { 890 if (defaults_assumed) { 891 if (no_copy && 892 !verify_action("* CAUTION * about to program '%s'\n at %p..%p from %p", 893 name, (void *)flash_addr, (void *)(flash_addr+img_size-1), 894 (void *)mem_addr)) { 895 return; // The guy gave up 896 } 897 } 898 } 899 } else { 743 struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; 744 int idx, num_chunks; 745 746 num_chunks = find_free(chunks); 747 for (idx = 0; idx < num_chunks; idx++) { 748 if ((chunks[idx].end - chunks[idx].start) >= length) { 749 *addr = (CYG_ADDRESS) chunks[idx].start; 750 return true; 751 } 752 } 753 return false; 754 #endif 755 } 756 757 static void fis_create_old(int argc, char *argv[]) 758 { 759 int i, stat; 760 unsigned long length, img_size; 761 CYG_ADDRESS mem_addr, exec_addr, flash_addr, entry_addr; 762 char *name; 763 bool mem_addr_set = false; 764 bool exec_addr_set = false; 765 bool entry_addr_set = false; 766 bool flash_addr_set = false; 767 bool length_set = false; 768 bool img_size_set = false; 769 bool no_copy = false; 770 void *err_addr; 771 struct fis_image_desc *img = NULL; 772 bool defaults_assumed; 773 struct option_info opts[7]; 774 bool prog_ok = true; 775 776 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 777 (void *)&mem_addr, (bool *) & mem_addr_set, 778 "memory base address"); 779 init_opts(&opts[1], 'r', true, OPTION_ARG_TYPE_NUM, (void *)&exec_addr, 780 (bool *) & exec_addr_set, "ram base address"); 781 init_opts(&opts[2], 'e', true, OPTION_ARG_TYPE_NUM, (void *)&entry_addr, 782 (bool *) & entry_addr_set, "entry point address"); 783 init_opts(&opts[3], 'f', true, OPTION_ARG_TYPE_NUM, (void *)&flash_addr, 784 (bool *) & flash_addr_set, "FLASH memory base address"); 785 init_opts(&opts[4], 'l', true, OPTION_ARG_TYPE_NUM, (void *)&length, 786 (bool *) & length_set, "image length [in FLASH]"); 787 init_opts(&opts[5], 's', true, OPTION_ARG_TYPE_NUM, (void *)&img_size, 788 (bool *) & img_size_set, "image size [actual data]"); 789 init_opts(&opts[6], 'n', false, OPTION_ARG_TYPE_FLG, (void *)&no_copy, 790 (bool *) 0, 791 "don't copy from RAM to FLASH, just update directory"); 792 if (!scan_opts 793 (argc, argv, 2, opts, 7, (void *)&name, OPTION_ARG_TYPE_STR, 794 "file name")) { 795 fis_usage("invalid arguments"); 796 return; 797 } 798 799 fis_read_directory(); 800 defaults_assumed = false; 801 if (name) { 802 // Search existing files to acquire defaults for params not specified: 803 img = fis_lookup(name, NULL); 804 if (img) { 805 // Found it, so get image size from there 806 if (!length_set) { 807 length_set = true; 808 length = img->size; 809 defaults_assumed = true; 810 } 811 } 812 } 813 if (!mem_addr_set && (load_address >= (CYG_ADDRESS) ram_start) && 814 (load_address_end) < (CYG_ADDRESS) ram_end) { 815 mem_addr = load_address; 816 mem_addr_set = true; 817 defaults_assumed = true; 818 // Get entry address from loader, unless overridden 819 if (!entry_addr_set) 820 entry_addr = entry_address; 821 if (!length_set) { 822 length = load_address_end - load_address; 823 length_set = true; 824 } else if (defaults_assumed && !img_size_set) { 825 /* We got length from the FIS table, so the size of the 826 actual loaded image becomes img_size */ 827 img_size = load_address_end - load_address; 828 img_size_set = true; 829 } 830 } 831 // Get the remaining fall-back values from the fis 832 if (img) { 833 if (!exec_addr_set) { 834 // Preserve "normal" behaviour 835 exec_addr_set = true; 836 exec_addr = flash_addr_set ? flash_addr : mem_addr; 837 } 838 if (!flash_addr_set) { 839 flash_addr_set = true; 840 flash_addr = img->flash_base; 841 defaults_assumed = true; 842 } 843 } 844 845 if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) || 846 !length_set || !name) { 847 fis_usage("required parameter missing"); 848 return; 849 } 850 if (!img_size_set) { 851 img_size = length; 852 } 853 // 'length' is size of FLASH image, 'img_size' is actual data size 854 // Round up length to FLASH block size 855 #ifndef CYGPKG_HAL_MIPS // FIXME: compiler is b0rken 856 length = 857 ((length + flash_block_size - 858 1) / flash_block_size) * flash_block_size; 859 if (length < img_size) { 860 diag_printf("Invalid FLASH image size/length combination\n"); 861 return; 862 } 863 #endif 864 if (flash_addr_set && 865 ((stat = flash_verify_addr((void *)flash_addr)) || 866 (stat = flash_verify_addr((void *)(flash_addr + length - 1))))) { 867 _show_invalid_flash_address(flash_addr, stat); 868 return; 869 } 870 if (flash_addr_set && ((flash_addr & (flash_block_size - 1)) != 0)) { 871 diag_printf("Invalid FLASH address: %p\n", (void *)flash_addr); 872 diag_printf(" must be 0x%x aligned\n", flash_block_size); 873 return; 874 } 875 if (strlen(name) >= sizeof(img->name)) { 876 diag_printf("Name is too long, must be less than %d chars\n", 877 (int)sizeof(img->name)); 878 return; 879 } 880 if (!no_copy) { 881 if ((mem_addr < (CYG_ADDRESS) ram_start) || 882 ((mem_addr + img_size) >= (CYG_ADDRESS) ram_end)) { 883 diag_printf 884 ("** WARNING: RAM address: %p may be invalid\n", 885 (void *)mem_addr); 886 diag_printf(" valid range is %p-%p\n", 887 (void *)ram_start, (void *)ram_end); 888 } 889 if (!flash_addr_set && !fis_find_free(&flash_addr, length)) { 890 diag_printf 891 ("Can't locate %lx(%ld) bytes free in FLASH\n", 892 length, length); 893 return; 894 } 895 } 896 // First, see if the image by this name has agreable properties 897 if (img) { 898 if (flash_addr_set && (img->flash_base != flash_addr)) { 899 diag_printf("Image found, but flash address (%p)\n" 900 " is incorrect (present image location %p)\n", 901 flash_addr, img->flash_base); 902 903 return; 904 } 905 if (img->size != length) { 906 diag_printf 907 ("Image found, but length (0x%lx, necessitating image size 0x%lx)\n" 908 " is incorrect (present image size 0x%lx)\n", 909 img_size, length, img->size); 910 return; 911 } 912 if (!verify_action("An image named '%s' exists", name)) { 913 return; 914 } else { 915 if (defaults_assumed) { 916 if (no_copy && 917 !verify_action 918 ("* CAUTION * about to program '%s'\n at %p..%p from %p", 919 name, (void *)flash_addr, 920 (void *)(flash_addr + img_size - 1), 921 (void *)mem_addr)) { 922 return; // The guy gave up 923 } 924 } 925 } 926 } else { 900 927 #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS 901 // Make sure that any FLASH address specified directly is truly free 902 if (flash_addr_set && !no_copy) { 903 struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; 904 int idx, num_chunks; 905 bool is_free = false; 906 907 num_chunks = find_free(chunks); 908 for (idx = 0; idx < num_chunks; idx++) { 909 if ((flash_addr >= chunks[idx].start) && 910 ((flash_addr+length-1) <= chunks[idx].end)) { 911 is_free = true; 912 } 913 } 914 if (!is_free) { 915 diag_printf("Invalid FLASH address - not free!\n"); 916 return; 917 } 918 } 919 #endif 920 // If not image by that name, try and find an empty slot 921 img = (struct fis_image_desc *)fis_work_block; 922 for (i = 0; i < fisdir_size/sizeof(*img); i++, img++) { 923 if (img->name[0] == (unsigned char)0xFF) { 924 break; 925 } 926 } 927 } 928 if (!no_copy) { 929 // Safety check - make sure the address range is not within the code we're running 930 if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) { 931 diag_printf("Can't program this region - contains code in use!\n"); 932 return; 933 } 934 if (prog_ok) { 935 // Erase area to be programmed 936 if ((stat = flash_erase((void *)flash_addr, length, (void **)&err_addr)) != 0) { 937 diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat)); 938 prog_ok = false; 939 } 940 } 941 if (prog_ok) { 942 // Now program it 943 if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, img_size, (void **)&err_addr)) != 0) { 944 diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat)); 945 prog_ok = false; 946 } 947 } 948 } 949 if (prog_ok) { 950 // Update directory 951 memset(img, 0, sizeof(*img)); 952 strcpy(img->name, name); 953 img->flash_base = flash_addr; 954 img->mem_base = exec_addr_set ? exec_addr : (flash_addr_set ? flash_addr : mem_addr); 955 img->entry_point = entry_addr_set ? entry_addr : (CYG_ADDRESS)entry_address; // Hope it's been set 956 img->size = length; 957 img->data_length = img_size; 928 // Make sure that any FLASH address specified directly is truly free 929 if (flash_addr_set && !no_copy) { 930 struct free_chunk 931 chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS]; 932 int idx, num_chunks; 933 bool is_free = false; 934 935 num_chunks = find_free(chunks); 936 for (idx = 0; idx < num_chunks; idx++) { 937 if ((flash_addr >= chunks[idx].start) && 938 ((flash_addr + length - 1) <= 939 chunks[idx].end)) { 940 is_free = true; 941 } 942 } 943 if (!is_free) { 944 diag_printf 945 ("Invalid FLASH address - not free!\n"); 946 return; 947 } 948 } 949 #endif 950 // If not image by that name, try and find an empty slot 951 img = (struct fis_image_desc *)fis_work_block; 952 for (i = 0; i < fisdir_size / sizeof(*img); i++, img++) { 953 if (img->name[0] == (unsigned char)0xFF) { 954 break; 955 } 956 } 957 } 958 if (!no_copy) { 959 // Safety check - make sure the address range is not within the code we're running 960 if (flash_code_overlaps 961 ((void *)flash_addr, (void *)(flash_addr + img_size - 1))) { 962 diag_printf 963 ("Can't program this region - contains code in use!\n"); 964 return; 965 } 966 if (prog_ok) { 967 // Erase area to be programmed 968 if ((stat = 969 flash_erase((void *)flash_addr, length, 970 (void **)&err_addr)) != 0) { 971 diag_printf("Can't erase region at %p: %s\n", 972 err_addr, flash_errmsg(stat)); 973 prog_ok = false; 974 } 975 } 976 if (prog_ok) { 977 // Now program it 978 if ((stat = 979 FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, 980 img_size, 981 (void **)&err_addr)) != 0) { 982 diag_printf("Can't program region at %p: %s\n", 983 err_addr, flash_errmsg(stat)); 984 prog_ok = false; 985 } 986 } 987 } 988 if (prog_ok) { 989 // Update directory 990 memset(img, 0, sizeof(*img)); 991 strcpy(img->name, name); 992 img->flash_base = flash_addr; 993 img->mem_base = 994 exec_addr_set ? exec_addr : (flash_addr_set ? flash_addr : 995 mem_addr); 996 img->entry_point = entry_addr_set ? entry_addr : (CYG_ADDRESS) entry_address; // Hope it's been set 997 img->size = length; 998 img->data_length = img_size; 958 999 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK 959 if (!no_copy) { 960 img->file_cksum = cyg_crc32((unsigned char *)mem_addr, img_size); 961 } else { 962 // No way to compute this, sorry 963 img->file_cksum = 0; 964 } 965 #endif 966 fis_update_directory(); 967 } 1000 if (!no_copy) { 1001 img->file_cksum = 1002 cyg_crc32((unsigned char *)mem_addr, img_size); 1003 } else { 1004 // No way to compute this, sorry 1005 img->file_cksum = 0; 1006 } 1007 #endif 1008 fis_update_directory(); 1009 } 968 1010 } 969 1011 970 1012 #if defined(CYGPKG_HAL_MIPS_AR2316) 971 1013 972 static void 973 fis_create_accton(int argc, char *argv[]) 974 { 975 *(volatile unsigned*)0xB1000090 |= 1;/*set GPIO0 to 1 to spi flash CS normal state*/ 976 *(volatile unsigned*)0xB1000098 |= 1;/*set GPIO0 to be output*/ 977 page_programming_supported = 1; 978 page_gpio = 0; 979 fis_create_old(argc,argv); 980 981 } 982 static void 983 fis_create_256(int argc, char *argv[]) 984 { 985 *(volatile unsigned*)0xB1000090 |= 1<<3;/*set GPIO0 to 1 to spi flash CS normal state*/ 986 *(volatile unsigned*)0xB1000098 |= 1<<3;/*set GPIO0 to be output*/ 987 page_programming_supported = 1; 988 page_gpio = 3; 989 fis_create_old(argc,argv); 990 991 } 992 #endif 993 static void 994 fis_create(int argc, char *argv[]) 995 { 996 page_programming_supported = 0; 997 page_gpio = 0; 998 fis_create_old(argc,argv); 1014 static void fis_create_accton(int argc, char *argv[]) 1015 { 1016 set_gpio(0,1); 1017 page_programming_supported = 1; 1018 page_gpio = 0; 1019 fis_create_old(argc, argv); 1020 1021 } 1022 1023 static void fis_create_256(int argc, char *argv[]) 1024 { 1025 set_gpio(3,1); 1026 page_programming_supported = 1; 1027 page_gpio = 3; 1028 fis_create_old(argc, argv); 1029 1030 } 1031 #endif 1032 static void fis_create(int argc, char *argv[]) 1033 { 1034 page_programming_supported = 0; 1035 page_gpio = 0; 1036 fis_create_old(argc, argv); 999 1037 } 1000 1038 1001 1039 extern void arm_fis_delete(char *); 1002 1040 1003 static void 1004 fis_load(int argc, char *argv[]) 1005 { 1006 char *name; 1007 struct fis_image_desc *img; 1008 CYG_ADDRESS mem_addr; 1009 bool mem_addr_set = false; 1010 bool show_cksum = false; 1011 struct option_info opts[3]; 1041 static void fis_load(int argc, char *argv[]) 1042 { 1043 char *name; 1044 struct fis_image_desc *img; 1045 CYG_ADDRESS mem_addr; 1046 bool mem_addr_set = false; 1047 bool show_cksum = false; 1048 struct option_info opts[3]; 1012 1049 #if defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) 1013 unsigned long cksum;1014 #endif 1015 int num_options;1050 unsigned long cksum; 1051 #endif 1052 int num_options; 1016 1053 #if defined(CYGPRI_REDBOOT_ZLIB_FLASH) || defined(CYGSEM_REDBOOT_FIS_CRC_CHECK) 1017 bool decompress = false;1054 bool decompress = false; 1018 1055 #endif 1019 1056 1020 1057 #if defined(CYGPRI_REDBOOT_7ZIP_FLASH) 1021 bool ldecompress = false; 1022 #endif 1023 void *err_addr; 1024 1025 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 1026 (void *)&mem_addr, (bool *)&mem_addr_set, "memory [load] base address"); 1027 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 1028 (void *)&show_cksum, (bool *)0, "display checksum"); 1029 num_options = 2; 1058 bool ldecompress = false; 1059 #endif 1060 void *err_addr; 1061 1062 init_opts(&opts[0], 'b', true, OPTION_ARG_TYPE_NUM, 1063 (void *)&mem_addr, (bool *) & mem_addr_set, 1064 "memory [load] base address"); 1065 init_opts(&opts[1], 'c', false, OPTION_ARG_TYPE_FLG, 1066 (void *)&show_cksum, (bool *) 0, "display checksum"); 1067 num_options = 2; 1030 1068 #ifdef CYGPRI_REDBOOT_ZLIB_FLASH 1031 init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, 1032 (void *)&decompress, 0, "decompress");1033 num_options++;1069 init_opts(&opts[num_options], 'd', false, OPTION_ARG_TYPE_FLG, 1070 (void *)&decompress, 0, "decompress"); 1071 num_options++; 1034 1072 #endif 1035 1073 1036 1074 #ifdef CYGPRI_REDBOOT_7ZIP_FLASH 1037 init_opts(&opts[num_options], 'l', false, OPTION_ARG_TYPE_FLG, 1038 (void *)&ldecompress, 0, "lzma"); 1039 num_options++; 1040 #endif 1041 1042 CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); 1043 1044 if (!scan_opts(argc, argv, 2, opts, num_options, (void *)&name, OPTION_ARG_TYPE_STR, "image name")) 1045 { 1046 fis_usage("invalid arguments"); 1047 return; 1048 } 1049 if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { 1050 diag_printf("No image '%s' found\n", name); 1051 return; 1052 } 1053 if (!mem_addr_set) { 1054 mem_addr = img->mem_base; 1055 } 1056 // Load image from FLASH into RAM 1075 init_opts(&opts[num_options], 'l', false, OPTION_ARG_TYPE_FLG, 1076 (void *)&ldecompress, 0, "lzma"); 1077 num_options++; 1078 #endif 1079 1080 CYG_ASSERT(num_options <= NUM_ELEMS(opts), "Too many options"); 1081 1082 if (!scan_opts 1083 (argc, argv, 2, opts, num_options, (void *)&name, 1084 OPTION_ARG_TYPE_STR, "image name")) { 1085 fis_usage("invalid arguments"); 1086 return; 1087 } 1088 if ((img = fis_lookup(name, NULL)) == (struct fis_image_desc *)0) { 1089 diag_printf("No image '%s' found\n", name); 1090 return; 1091 } 1092 if (!mem_addr_set) { 1093 mem_addr = img->mem_base; 1094 } 1095 // Load image from FLASH into RAM 1057 1096 #ifdef CYGSEM_REDBOOT_VALIDATE_USER_RAM_LOADS 1058 if (!valid_address((void *)mem_addr)) { 1059 diag_printf("Not a loadable image - try using -b ADDRESS option\n"); 1060 return; 1061 } 1097 if (!valid_address((void *)mem_addr)) { 1098 diag_printf 1099 ("Not a loadable image - try using -b ADDRESS option\n"); 1100 return; 1101 } 1062 1102 #endif 1063 1103 1064 1104 #if defined(CYGPRI_REDBOOT_7ZIP_FLASH) 1065 if (ldecompress) { 1066 unsigned char *in_buf,*out_buf; 1067 unsigned out_buf_len,in_buf_len; 1068 int res; 1069 in_buf = (unsigned char*) img->flash_base; 1070 out_buf = (unsigned char*) mem_addr; 1071 in_buf_len = img->data_length; 1072 res = lzma_decode(in_buf,out_buf,in_buf_len,&out_buf_len); 1073 if ( res!= 0 ) { 1074 diag_printf("lzma_decode failed. res=%d\n",res); 1075 }else { 1076 diag_printf("Image loaded from %p-%p\n", out_buf,out_buf+out_buf_len); 1077 } 1078 load_address = mem_addr; 1079 load_address_end = mem_addr + out_buf_len ; 1080 fis_read_directory(); 1081 } else 1105 if (ldecompress) { 1106 unsigned char *in_buf, *out_buf; 1107 unsigned out_buf_len, in_buf_len; 1108 int res; 1109 in_buf = (unsigned char *)img->flash_base; 1110 out_buf = (unsigned char *)mem_addr; 1111 in_buf_len = img->data_length; 1112 res = lzma_decode(in_buf, out_buf, in_buf_len, &out_buf_len); 1113 if (res != 0) { 1114 diag_printf("lzma_decode failed. res=%d\n", res); 1115 } else { 1116 diag_printf("Image loaded from %p-%p\n", out_buf, 1117 out_buf + out_buf_len); 1118 } 1119 load_address = mem_addr; 1120 load_address_end = mem_addr + out_buf_len; 1121 fis_read_directory(); 1122 } else 1082 1123 #endif 1083 1124 1084 1125 #ifdef CYGPRI_REDBOOT_ZLIB_FLASH 1085 if (decompress) { 1086 int err; 1087 _pipe_t fis_load_pipe; 1088 _pipe_t* p = &fis_load_pipe; 1089 p->out_buf = (unsigned char*) mem_addr; 1090 p->out_max = p->out_size = -1; 1091 p->in_buf = (unsigned char*) img->flash_base; 1092 p->in_avail = img->data_length; 1093 1094 err = (*_dc_init)(p); 1095 1096 if (0 == err) 1097 err = (*_dc_inflate)(p); 1098 1099 // Free used resources, do final translation of 1100 // error value. 1101 err = (*_dc_close)(p, err); 1102 1103 if (0 != err && p->msg) { 1104 diag_printf("decompression error: %s\n", p->msg); 1105 } else { 1106 diag_printf("Image loaded from %p-%p\n", (unsigned char *)mem_addr, p->out_buf); 1107 } 1108 1109 // Set load address/top 1110 load_address = mem_addr; 1111 load_address_end = (unsigned long)p->out_buf; 1112 1113 // Reload fis directory 1114 fis_read_directory(); 1115 } else // dangling block 1116 #endif 1117 { 1118 flash_read((void *)img->flash_base, (void *)mem_addr, img->data_length, (void **)&err_addr); 1119 1120 // Set load address/top 1121 load_address = mem_addr; 1122 load_address_end = mem_addr + img->data_length; 1123 } 1124 entry_address = (unsigned long)img->entry_point; 1126 if (decompress) { 1127 int err; 1128 _pipe_t fis_load_pipe; 1129 _pipe_t *p = &fis_load_pipe; 1130 p->out_buf = (unsigned char *)mem_addr; 1131 p->out_max = p->out_size = -1; 1132 p->in_buf = (unsigned char *)img->flash_base; 1133 p->in_avail = img->data_length; 1134 1135 err = (*_dc_init) (p); 1136 1137 if (0 == err) 1138 err = (*_dc_inflate) (p); 1139 1140 // Free used resources, do final translation of 1141 // error value. 1142 err = (*_dc_close) (p, err); 1143 1144 if (0 != err && p->msg) { 1145 diag_printf("decompression error: %s\n", p->msg); 1146 } else { 1147 diag_printf("Image loaded from %p-%p\n", 1148 (unsigned char *)mem_addr, p->out_buf); 1149 } 1150 1151 // Set load address/top 1152 load_address = mem_addr; 1153 load_address_end = (unsigned long)p->out_buf; 1154 1155 // Reload fis directory 1156 fis_read_directory(); 1157 } else // dangling block 1158 #endif 1159 { 1160 flash_read((void *)img->flash_base, (void *)mem_addr, 1161 img->data_length, (void **)&err_addr); 1162 1163 // Set load address/top 1164 load_address = mem_addr; 1165 load_address_end = mem_addr + img->data_length; 1166 } 1167 entry_address = (unsigned long)img->entry_point; 1125 1168 1126 1169 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK 1127 cksum = cyg_crc32((unsigned char *)mem_addr, img->data_length); 1128 if (show_cksum) { 1129 diag_printf("Checksum: 0x%08lx\n", cksum); 1130 } 1131 // When decompressing, leave CRC checking to decompressor 1132 if (!decompress && !ldecompress && img->file_cksum) { 1133 if (cksum != img->file_cksum) { 1134 diag_printf("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", 1135 img->file_cksum, cksum); 1136 entry_address = (unsigned long)NO_MEMORY; 1137 } 1138 } 1139 #endif 1140 } 1141 #endif // CYGOPT_REDBOOT_FIS 1142 1143 1144 1170 cksum = cyg_crc32((unsigned char *)mem_addr, img->data_length); 1171 if (show_cksum) { 1172 diag_printf("Checksum: 0x%08lx\n", cksum); 1173 } 1174 // When decompressing, leave CRC checking to decompressor 1175 if (!decompress && !ldecompress && img->file_cksum) { 1176 if (cksum != img->file_cksum) { 1177 diag_printf 1178 ("** Warning - checksum failure. stored: 0x%08lx, computed: 0x%08lx\n", 1179 img->file_cksum, cksum); 1180 entry_address = (unsigned long)NO_MEMORY; 1181 } 1182 } 1183 #endif 1184 } 1185 #endif // CYGOPT_REDBOOT_FIS 1145 1186 1146 1187 // This is set non-zero if the FLASH subsystem has successfully been initialized 1147 1188 int __flash_init = 0; 1148 1189 1149 void 1150 _flash_info(void) 1151 { 1152 if (!__flash_init) return; 1153 diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", 1154 flash_start, (CYG_ADDRWORD)flash_end + 1, flash_num_blocks, (void *)flash_block_size); 1155 } 1156 1157 bool 1158 do_flash_init(void) 1159 { 1160 int stat; 1161 1162 if (!__flash_init) { 1163 __flash_init = 1; 1164 if ((stat = flash_init(diag_printf)) != 0) { 1165 diag_printf("FLASH: driver init failed: %s\n", flash_errmsg(stat)); 1166 return false; 1167 } 1168 flash_get_limits((void *)0, (void **)&flash_start, (void **)&flash_end); 1169 // Keep 'end' address as last valid location, to avoid wrap around problems 1170 flash_end = (void *)((CYG_ADDRESS)flash_end - 1); 1171 flash_get_block_info(&flash_block_size, &flash_num_blocks); 1190 void _flash_info(void) 1191 { 1192 if (!__flash_init) 1193 return; 1194 diag_printf("FLASH: %p - %p, %d blocks of %p bytes each.\n", 1195 flash_start, (CYG_ADDRWORD) flash_end + 1, flash_num_blocks, 1196 (void *)flash_block_size); 1197 } 1198 1199 void diag_blink(void) 1200 { 1201 #ifdef LEDCODE 1202 static int counter = 0; 1203 unsigned char leds[] = { 1204 LED1_PIN, 1205 #if LED2_PIN != 0xff 1206 LED2_PIN, 1207 #endif 1208 #if LED3_PIN != 0xff 1209 LED3_PIN, 1210 #endif 1211 #if LED4_PIN != 0xff 1212 LED4_PIN, 1213 #endif 1214 }; 1215 int len = sizeof(leds); 1216 int i; 1217 if (len == 1) { 1218 set_gpio(LED1_PIN, (counter++) % 2); 1219 } else { 1220 for (i = 0; i < len; i++) { 1221 set_gpio(leds[i], 0); 1222 } 1223 set_gpio(leds[counter++], 1); 1224 if (counter == len) 1225 counter = 0; 1226 } 1227 #endif 1228 } 1229 1230 bool do_flash_init(void) 1231 { 1232 int stat; 1233 1234 if (!__flash_init) { 1235 __flash_init = 1; 1236 if ((stat = flash_init(diag_printf)) != 0) { 1237 diag_printf("FLASH: driver init failed: %s\n", 1238 flash_errmsg(stat)); 1239 return false; 1240 } 1241 flash_get_limits((void *)0, (void **)&flash_start, 1242 (void **)&flash_end); 1243 // Keep 'end' address as last valid location, to avoid wrap around problems 1244 flash_end = (void *)((CYG_ADDRESS) flash_end - 1); 1245 flash_get_block_info(&flash_block_size, &flash_num_blocks); 1172 1246 #ifdef CYGOPT_REDBOOT_FIS 1173 fisdir_size = CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; 1174 fisdir_size = ((fisdir_size + flash_block_size - 1) / flash_block_size) * flash_block_size; 1247 fisdir_size = 1248 CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_COUNT * 1249 CYGNUM_REDBOOT_FIS_DIRECTORY_ENTRY_SIZE; 1250 fisdir_size = 1251 ((fisdir_size + flash_block_size - 1252 1) / flash_block_size) * flash_block_size; 1175 1253 # if defined(CYGPRI_REDBOOT_ZLIB_FLASH) && defined(CYGOPT_REDBOOT_FIS_ZLIB_COMMON_BUFFER) 1176 fis_work_block = fis_zlib_common_buffer;1177 if(CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) {1178 diag_printf("FLASH: common buffer too small\n");1179 return false;1180 }1254 fis_work_block = fis_zlib_common_buffer; 1255 if (CYGNUM_REDBOOT_FIS_ZLIB_COMMON_BUFFER_SIZE < fisdir_size) { 1256 diag_printf("FLASH: common buffer too small\n"); 1257 return false; 1258 } 1181 1259 # else 1182 workspace_end = (unsigned char *)(workspace_end-fisdir_size);1183 fis_work_block = workspace_end;1260 workspace_end = (unsigned char *)(workspace_end - fisdir_size); 1261 fis_work_block = workspace_end; 1184 1262 # endif 1185 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { 1186 fis_addr = (void *)((CYG_ADDRESS)flash_end + 1 + 1187 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); 1188 } else { 1189 fis_addr = (void *)((CYG_ADDRESS)flash_start + 1190 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*flash_block_size)); 1191 } 1192 if (((CYG_ADDRESS)fis_addr + fisdir_size - 1) > (CYG_ADDRESS)flash_end) { 1193 diag_printf("FIS directory doesn't fit\n"); 1194 return false; 1195 } 1196 fis_read_directory(); 1197 #endif 1198 } 1199 return true; 1263 if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) { 1264 fis_addr = (void *)((CYG_ADDRESS) flash_end + 1 + 1265 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK 1266 * flash_block_size)); 1267 } else { 1268 fis_addr = (void *)((CYG_ADDRESS) flash_start + 1269 (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK 1270 * flash_block_size)); 1271 } 1272 if (((CYG_ADDRESS) fis_addr + fisdir_size - 1) > 1273 (CYG_ADDRESS) flash_end) { 1274 diag_printf("FIS directory doesn't fit\n"); 1275 return false; 1276 } 1277 fis_read_directory(); 1278 #endif 1279 } 1280 return true; 1200 1281 } 1201 1282 1202 1283 // Wrapper to avoid compiler warnings 1203 static void 1204 _do_flash_init(void) 1205 { 1206 static int init_done = 0; 1207 if (init_done)return;1208 init_done = 1;1209 do_flash_init();1284 static void _do_flash_init(void) 1285 { 1286 static int init_done = 0; 1287 if (init_done) 1288 return; 1289 init_done = 1; 1290 do_flash_init(); 1210 1291 } 1211 1292 1212 1293 RedBoot_init(_do_flash_init, RedBoot_INIT_FIRST); 1213 1294 1214 static void 1215 do_fis(int argc, char *argv[]) 1216 { 1217 struct cmd *cmd; 1218 1219 if (argc < 2) { 1220 fis_usage("too few arguments"); 1221 return; 1222 } 1223 if (!do_flash_init()) { 1224 diag_printf("Sorry, no FLASH memory is available\n"); 1225 return; 1226 } 1227 if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, 1228 argv[1])) != (struct cmd *)0) { 1229 (cmd->fun)(argc, argv); 1230 return; 1231 } 1232 fis_usage("unrecognized command"); 1295 static void do_fis(int argc, char *argv[]) 1296 { 1297 struct cmd *cmd; 1298 1299 if (argc < 2) { 1300 fis_usage("too few arguments"); 1301 return; 1302 } 1303 if (!do_flash_init()) { 1304 diag_printf("Sorry, no FLASH memory is available\n"); 1305 return; 1306 } 1307 if ((cmd = cmd_search(__FIS_cmds_TAB__, &__FIS_cmds_TAB_END__, 1308 argv[1])) != (struct cmd *)0) { 1309 (cmd->fun) (argc, argv); 1310 return; 1311 } 1312 fis_usage("unrecognized command"); 1233 1313 } 1234 1314 ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/main.c
r12409 r12429 159 159 160 160 int in_rescue_mode = 0; 161 162 void set_gpio(int gpio,int state) 163 { 164 #if defined(CYGPKG_HAL_MIPS_AR2316) 165 *(volatile unsigned *)AR2316_GPIO_CR |= 1<<gpio; /*set GPIO0 to be output */ 166 if (state) 167 *(volatile unsigned *)AR2316_GPIO_DO |= 1<<gpio; /*set GPIO0 to 1 to spi flash CS normal state */ 168 else 169 *(volatile unsigned *)AR2316_GPIO_DO &= ~(1<<gpio); /*set GPIO0 to 1 to spi flash CS normal state */ 170 #else 171 *(volatile unsigned *)AR531X_GPIO_CR &= ~(1<<gpio); /*set GPIO0 to be output */ 172 if (state) 173 *(volatile unsigned *)AR531X_GPIO_DO |= 1<<gpio; /*set GPIO0 to 1 to spi flash CS normal state */ 174 else 175 *(volatile unsigned *)AR531X_GPIO_DO &= ~(1<<gpio); /*set GPIO0 to 1 to spi flash CS normal state */ 176 #endif 177 178 } 161 179 162 180 ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/tftp_server.c
r12407 r12429 111 111 #if defined(CYGPKG_HAL_MIPS_AR2316) 112 112 #if FISTYPE == 1 113 *(volatile unsigned *)0xB1000090 |= 1; /*set GPIO0 to 1 to spi flash CS normal state */ 114 *(volatile unsigned *)0xB1000098 |= 1; /*set GPIO0 to be output */ 113 set_gpio(0,1); 115 114 page_programming_supported = 1; 116 115 page_gpio = 0; … … 118 117 119 118 #if FISTYPE == 2 120 *(volatile unsigned *)0xB1000090 |= 1 << 3; /*set GPIO0 to 1 to spi flash CS normal state */ 121 *(volatile unsigned *)0xB1000098 |= 1 << 3; /*set GPIO0 to be output */ 119 set_gpio(3,1); 122 120 page_programming_supported = 1; 123 121 page_gpio = 3;
