diff packages/redboot/current/src/flash.c @ 154:e2d866e32dac

Merge from eCos master repository on 2001-02-26-23:18:05-GMT
author jlarmour
date Tue, 27 Feb 2001 01:21:45 +0000
parents 5e8f3b328bb3
children b939e9cada46
line wrap: on
line diff
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -114,8 +114,8 @@ local_cmd_entry("load",
     );
 local_cmd_entry("create",
                 "Create an image",
-                "-b <mem_base> -l <image_length> [-s <data_length>] 
-                [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>",
+                "-b <mem_base> -l <image_length> [-s <data_length>]\n"
+                "      [-f <flash_addr>] [-e <entry_point>] [-r <ram_addr>] [-n] <name>",
                 fis_create,
                 FIS_cmds
     );
@@ -159,7 +159,7 @@ fis_usage(char *why)
 static void
 fis_init(int argc, char *argv[])
 {
-    int stat, img_count = 0;
+    int stat;
     struct fis_image_desc *img;
     void *fis_base, *err_addr;
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
@@ -182,58 +182,52 @@ fis_init(int argc, char *argv[])
     }
     printf("*** Initialize FLASH Image System\n");
 
-    redboot_flash_start = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
 #define MIN_REDBOOT_IMAGE_SIZE CYGBLD_REDBOOT_MIN_IMAGE_SIZE
     redboot_image_size = block_size > MIN_REDBOOT_IMAGE_SIZE ? block_size : MIN_REDBOOT_IMAGE_SIZE;
 
-    if (full_init) {
-	// Erase everything except default RedBoot images, fis block, and config block.
-	// FIXME! This still assumes that fis and config blocks can use top of FLASH.
-	if (CYGBLD_REDBOOT_FLASH_BOOT_OFFSET == 0) {
-	    if ((stat = flash_erase((void *)((unsigned long)flash_start+(2*redboot_image_size)), 
-				    ((blocks-2)*block_size) - (2*redboot_image_size),
-				    (void **)&err_addr)) != 0) {
-		printf("   initialization failed %p: 0x%x(%s)\n",
-		       err_addr, stat, flash_errmsg(stat));
-	    }
-	} else {
-	    if ((stat = flash_erase(flash_start, CYGBLD_REDBOOT_FLASH_BOOT_OFFSET, 
-				    (void **)&err_addr)) != 0) {
-		printf("   initialization failed %p: 0x%x(%s)\n",
-		       err_addr, stat, flash_errmsg(stat));
-	    } else {
-		unsigned long erase_start, erase_size;
-
-		erase_start = redboot_flash_start+(2*redboot_image_size);
-		erase_size = (blocks-2)*block_size;
-		erase_size -= erase_start - (unsigned long)flash_start;
-
-		if (erase_size && (stat = flash_erase((void *)erase_start, erase_size,
-						      (void **)&err_addr)) != 0) {
-		    printf("   initialization failed %p: 0x%x(%s)\n",
-			   err_addr, stat, flash_errmsg(stat));
-		}
-	    }
-	}
-
-    } else {
-        printf("    Warning: device contents not erased, some blocks may not be usable\n");
-    }
     // Create a pseudo image for RedBoot
     img = (struct fis_image_desc *)fis_work_block;
+#ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
+    memset(img, 0, sizeof(*img));
+    strcpy(img->name, "(reserved)");
+    img->flash_base = (unsigned long)flash_start;
+    img->mem_base = (unsigned long)flash_start;
+    img->size = CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+    img++;
+#endif
+    redboot_flash_start = (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
+#ifdef CYGOPT_REDBOOT_FIS_REDBOOT
     memset(img, 0, sizeof(*img));
     strcpy(img->name, "RedBoot");
     img->flash_base = redboot_flash_start;
     img->mem_base = redboot_flash_start;
     img->size = redboot_image_size;
-    img++;  img_count++;
+    img++;
+    redboot_flash_start += redboot_image_size;
+#endif
+#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST
+#ifdef CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET
+    // Take care to place the POST entry at the right offset:
+    redboot_flash_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FIS_REDBOOT_POST_OFFSET;
+#endif
+    memset(img, 0, sizeof(*img));
+    strcpy(img->name, "RedBoot[post]");
+    img->flash_base = redboot_flash_start;
+    img->mem_base = redboot_flash_start;
+    img->size = redboot_image_size;
+    img++;
+    redboot_flash_start += redboot_image_size;
+#endif
+#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP
     // And a backup image
     memset(img, 0, sizeof(*img));
     strcpy(img->name, "RedBoot[backup]");
-    img->flash_base = redboot_flash_start+redboot_image_size;
-    img->mem_base = redboot_flash_start+redboot_image_size;
+    img->flash_base = redboot_flash_start;
+    img->mem_base = redboot_flash_start;
     img->size = redboot_image_size;
-    img++;  img_count++;
+    img++;
+    redboot_flash_start += redboot_image_size;
+#endif
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
     // And a descriptor for the configuration data
     memset(img, 0, sizeof(*img));
@@ -242,7 +236,7 @@ fis_init(int argc, char *argv[])
     img->flash_base = (unsigned long)cfg_base;
     img->mem_base = (unsigned long)cfg_base;
     img->size = block_size;
-    img++;  img_count++;
+    img++;
 #endif
     // And a descriptor for the descriptor table itself
     memset(img, 0, sizeof(*img));
@@ -251,22 +245,59 @@ fis_init(int argc, char *argv[])
     img->flash_base = (unsigned long)fis_base;
     img->mem_base = (unsigned long)fis_base;
     img->size = block_size;
-    img++;  img_count++;
+    img++;
+
+    // Do this after creating the initialized table because that inherently
+    // calculates where the high water mark of default RedBoot images is.
+
+    if (full_init) {
+        unsigned long erase_start, erase_size;
+	// Erase everything except default RedBoot images, fis block, and config block.
+	// FIXME! This still assumes that fis and config blocks can use top of FLASH.
+
+        // first deal with the possible first part, before RedBoot images:
+        erase_start = (unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE;
+        erase_size =  (unsigned long)flash_start + CYGBLD_REDBOOT_FLASH_BOOT_OFFSET;
+        if ( erase_size > erase_start ) {
+            erase_size -= erase_start;
+	    if ((stat = flash_erase((void *)erase_start, erase_size,
+				    (void **)&err_addr)) != 0) {
+		printf("   initialization failed %p: 0x%x(%s)\n",
+		       err_addr, stat, flash_errmsg(stat));
+            }
+        }
+        // second deal with the larger part in the main:
+        erase_start = redboot_flash_start; // high water of created images
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+        erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data
+#else
+        erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data
+#endif
+        if ((stat = flash_erase((void *)erase_start, erase_size,
+                                (void **)&err_addr)) != 0) {
+            printf("   initialization failed %p: 0x%x(%s)\n",
+                   err_addr, stat, flash_errmsg(stat));
+        }
+    } else {
+        printf("    Warning: device contents not erased, some blocks may not be usable\n");
+    }
+
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
-    // Insure [quietly] that the directory is unlocked before trying to update
+    // Ensure [quietly] that the directory is unlocked before trying to update
     flash_unlock((void *)fis_base, block_size, (void **)&err_addr);
 #endif
     if ((stat = flash_erase(fis_base, block_size, (void **)&err_addr)) != 0) {
             printf("   initialization failed %p: 0x%x(%s)\n", err_addr, stat, flash_errmsg(stat));
     } else {
         if ((stat = flash_program(fis_base, fis_work_block, 
-                                  img_count*sizeof(*img), (void **)&err_addr)) != 0) {
+                                  (unsigned long)img - (unsigned long)fis_work_block,
+                                  (void **)&err_addr)) != 0) {
             printf("Error writing image descriptors at %p: 0x%x(%s)\n", 
                    err_addr, stat, flash_errmsg(stat));
         }
     }
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
-    // Insure [quietly] that the directory is locked after the update
+    // Ensure [quietly] that the directory is locked after the update
     flash_lock((void *)fis_base, block_size, (void **)&err_addr);
 #endif
 }
@@ -305,15 +336,15 @@ fis_free(int argc, char *argv[])
     unsigned long *fis_ptr, *fis_end;
     unsigned long *area_start;
 
-    fis_ptr = (unsigned long *)((unsigned long)flash_start + 2*block_size);
-    fis_end = (unsigned long *)((unsigned long)flash_end + block_size);
+    // Do not search the area reserved for pre-RedBoot systems:
+    fis_ptr = (unsigned long *)((unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
     fis_end = (unsigned long *)(unsigned long)flash_end;
     area_start = fis_ptr;
     while (fis_ptr < fis_end) {
         if (*fis_ptr != (unsigned long)0xFFFFFFFF) {
             if (area_start != fis_ptr) {
                 // Assume that this is something
-                printf("  0x%08lX .. 0x%08lX\n", 
+                printf("  0x%08lX .. 0x%08lX\n",
                        (unsigned long)area_start, (unsigned long)fis_ptr);
             }
             // Find next blank block
@@ -335,14 +366,15 @@ fis_free(int argc, char *argv[])
     }
 }
 
-// Find the first unused area of flash which is long enougn
+// Find the first unused area of flash which is long enough
 static bool
 fis_find_free(unsigned long *addr, unsigned long length)
 {
     unsigned long *fis_ptr, *fis_end;
     unsigned long *area_start;
 
-    fis_ptr = (unsigned long *)((unsigned long)flash_start + 2*block_size);
+    // Do not search the area reserved for pre-RedBoot systems:
+    fis_ptr = (unsigned long *)((unsigned long)flash_start + CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
     fis_end = (unsigned long *)(unsigned long)flash_end;
     area_start = fis_ptr;
     while (fis_ptr < fis_end) {
@@ -415,6 +447,27 @@ fis_create(int argc, char *argv[])
         return;
     }
 
+    if ( name ) {
+        // Search existing files to acquire defaults for params not specified:
+        fis_addr = (void *)((unsigned long)flash_end - block_size);
+        memcpy(fis_work_block, fis_addr, block_size);
+        img = (struct fis_image_desc *)fis_work_block;
+        for (i = 0;  i < block_size/sizeof(*img);  i++, img++) {
+            if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
+                // Found it, so get any unset but necessary params from there:
+                if ( !length_set ) {
+                    length_set = true;
+                    length = img->size;
+                }
+                if ( !flash_addr_set ) {
+                    flash_addr_set = true;
+                    flash_addr = img->flash_base;
+                }           
+                break;
+            }
+        }
+    }
+
     if ((!no_copy && !mem_addr_set) || (no_copy && !flash_addr_set) ||
         !length_set || !name) {
         fis_usage("required parameter missing");
@@ -673,8 +726,28 @@ fis_delete(int argc, char *argv[])
     fis_addr = (void *)((unsigned long)flash_end - block_size);
     memcpy(fis_work_block, fis_addr, block_size);
     img = (struct fis_image_desc *)fis_work_block;
-    img += 2;  // Skip reserved files
-    for (i = 2;  i < block_size/sizeof(*img);  i++, img++) {
+    i = 0;
+#ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
+    i++;
+#endif
+#ifdef CYGOPT_REDBOOT_FIS_REDBOOT
+    i++;
+#endif
+#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP
+    i++;
+#endif
+#ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST
+    i++;
+#endif
+#ifdef CYGSEM_REDBOOT_FLASH_CONFIG
+    i++;
+#endif
+#if 1 // And the descriptor for the descriptor table itself
+    i++;
+#endif
+    img += i;  // Skip reserved files
+
+    for ( /* i, img */;  i < block_size/sizeof(*img);  i++, img++) {
         if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
             if (!verify_action("Delete image '%s'", name)) {
                 return;
@@ -746,7 +819,7 @@ fis_load(int argc, char *argv[])
         printf("Not a loadable image\n");
         return;
     }
-    memcpy((void *)mem_addr, (void *)img->flash_base, img->size);
+    memcpy((void *)mem_addr, (void *)img->flash_base, img->data_length);
     entry_address = (unsigned long *)img->entry_point;
     cksum = crc32((unsigned char *)mem_addr, img->data_length);
     if (show_cksum) {
@@ -1057,6 +1130,8 @@ config_length(int type)
         return 0;
     case CONFIG_SCRIPT:
         return MAX_SCRIPT_LENGTH;
+    default:
+        return 0;
     }
 }
 
@@ -1337,4 +1412,6 @@ load_flash_config(void)
 
 RedBoot_init(load_flash_config, RedBoot_INIT_FIRST);
 
-#endif
+#endif // CYGSEM_REDBOOT_FLASH_CONFIG
+
+// EOF flash.c