diff packages/redboot/current/src/flash.c @ 183:9160a8005d76

Merge from eCos master repository on 2001-09-12-03:52:30-BST
author jlarmour
date Wed, 12 Sep 2001 04:21:13 +0000
parents f62680ef1804
children 022f1e506033
line wrap: on
line diff
--- a/packages/redboot/current/src/flash.c
+++ b/packages/redboot/current/src/flash.c
@@ -150,6 +150,8 @@ static int fisdir_size;  // Size of FIS 
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
 static void *cfg_base;   // Location in Flash of config data
 static int   cfg_size;   // Length of config data - rounded to Flash block size
+// Prototypes for local functions
+static unsigned char *flash_lookup_config(char *key);
 #endif
 
 static void
@@ -167,7 +169,13 @@ fis_lookup(char *name)
     void *fis_addr;
     struct fis_image_desc *img;
 
-    fis_addr = (void *)((unsigned long)flash_end - block_size);
+    if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
+        fis_addr = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    } else {
+        fis_addr = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*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++) {
@@ -251,6 +259,13 @@ fis_init(int argc, char *argv[])
     // And a descriptor for the configuration data
     memset(img, 0, sizeof(*img));
     strcpy(img->name, "RedBoot config");
+    if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
+        cfg_base = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size));
+    } else {
+        cfg_base = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size));
+    }
     img->flash_base = (unsigned long)cfg_base;
     img->mem_base = (unsigned long)cfg_base;
     img->size = cfg_size;
@@ -259,7 +274,13 @@ fis_init(int argc, char *argv[])
     // And a descriptor for the descriptor table itself
     memset(img, 0, sizeof(*img));
     strcpy(img->name, "FIS directory");
-    fis_base = (void *)((unsigned long)flash_end - block_size);
+    if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
+        fis_base = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    } else {
+        fis_base = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    }
     img->flash_base = (unsigned long)fis_base;
     img->mem_base = (unsigned long)fis_base;
     img->size = block_size;
@@ -270,10 +291,9 @@ fis_init(int argc, char *argv[])
 
     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 everything except default RedBoot images, fis block, 
+        // and config block.
+        // 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 ) {
@@ -286,11 +306,42 @@ fis_init(int argc, char *argv[])
         }
         // second deal with the larger part in the main:
         erase_start = redboot_flash_start; // high water of created images
+        // Now the empty bits between the end of Redboot and the cfg and dir 
+        // blocks. 
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-        erase_size = (unsigned long)cfg_base - erase_start; // the gap between HWM and config data
-#else
+        if (fis_base > cfg_base) {
+          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
+        }
+        if ((stat = flash_erase((void *)erase_start, erase_size,
+                                (void **)&err_addr)) != 0) {
+          diag_printf("   initialization failed %p: %s\n",
+                 err_addr, flash_errmsg(stat));
+        }
+        erase_start += (erase_size + block_size);
+        if (fis_base > cfg_base) {
+          erase_size = (unsigned long)fis_base - erase_start; // the gap between config and fis data
+        } else {
+          erase_size = (unsigned long)cfg_base - erase_start; // the gap between fis and config data
+        }
+        if ((stat = flash_erase((void *)erase_start, erase_size,
+                                (void **)&err_addr)) != 0) {
+          diag_printf("   initialization failed %p: %s\n",
+                 err_addr, flash_errmsg(stat));
+        }
+        erase_start += (erase_size + block_size);
+#else  // !CYGSEM_REDBOOT_FLASH_CONFIG        
         erase_size = (unsigned long)fis_base - erase_start; // the gap between HWM and fis data
+        if ((stat = flash_erase((void *)erase_start, erase_size,
+                                (void **)&err_addr)) != 0) {
+          diag_printf("   initialization failed %p: %s\n",
+                 err_addr, flash_errmsg(stat));
+        }
+        erase_start += (erase_size + block_size);          
 #endif
+        // Lastly, anything at the end
+        erase_size = (unsigned long)flash_end - erase_start;
         if ((stat = flash_erase((void *)erase_start, erase_size,
                                 (void **)&err_addr)) != 0) {
             diag_printf("   initialization failed at %p: %s\n",
@@ -342,9 +393,14 @@ fis_list(int argc, char *argv[])
     {
         return;
     }
-
-    img = (struct fis_image_desc *)((unsigned long)flash_end - block_size);
-    // Let diag_printf do the formatting in both cases, rather than cnouting
+    if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
+        img = (void *)((unsigned long)flash_end + 
+                       (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    } else {
+        img = (void *)((unsigned long)flash_start + 
+                       (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    }
+    // Let diag_printf do the formatting in both cases, rather than counting
     // cols by hand....
     diag_printf("%-16s  %-10s  %-10s  %-10s  %-s\n",
                 "Name","FLASH addr",
@@ -487,7 +543,13 @@ fis_create(int argc, char *argv[])
     defaults_assumed = false;
     if (name) {
         // Search existing files to acquire defaults for params not specified:
-        fis_addr = (void *)((unsigned long)flash_end - block_size);
+        if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
+            fis_addr = (void *)((unsigned long)flash_end + 
+                                (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+        } else {
+            fis_addr = (void *)((unsigned long)flash_start + 
+                                (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*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++) {
@@ -560,7 +622,13 @@ fis_create(int argc, char *argv[])
     // Find a slot in the directory for this entry
     // First, see if an image by this name is already present
     slot_found = false;
-    fis_addr = (void *)((unsigned long)flash_end - block_size);
+    if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
+        fis_addr = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    } else {
+        fis_addr = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*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++) {
@@ -656,7 +724,7 @@ static void
 fis_delete(int argc, char *argv[])
 {
     char *name;
-    int i, stat;
+    int num_reserved, i, stat;
     void *fis_addr, *err_addr;
     struct fis_image_desc *img;
     bool slot_found;
@@ -666,34 +734,42 @@ fis_delete(int argc, char *argv[])
         fis_usage("invalid arguments");
         return;
     }
-
     slot_found = false;
-    fis_addr = (void *)((unsigned long)flash_end - block_size);
+    if (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK < 0) {
+        fis_addr = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    } else {
+        fis_addr = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FIS_DIRECTORY_BLOCK*block_size));
+    }
     memcpy(fis_work_block, fis_addr, block_size);
     img = (struct fis_image_desc *)fis_work_block;
-    i = 0;
+    num_reserved = 0;
 #ifdef CYGOPT_REDBOOT_FIS_RESERVED_BASE
-    i++;
+    num_reserved++;
 #endif
 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT
-    i++;
+    num_reserved++;
 #endif
 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_BACKUP
-    i++;
+    num_reserved++;
 #endif
 #ifdef CYGOPT_REDBOOT_FIS_REDBOOT_POST
-    i++;
+    num_reserved++;
 #endif
 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
-    i++;
+    num_reserved++;
 #endif
 #if 1 // And the descriptor for the descriptor table itself
-    i++;
+    num_reserved++;
 #endif
-    img += i;  // Skip reserved files
 
-    for ( /* i, img */;  i < block_size/sizeof(*img);  i++, img++) {
+    for (i = 0;  i < block_size/sizeof(*img);  i++, img++) {
         if ((img->name[0] != (unsigned char)0xFF) && (strcmp(name, img->name) == 0)) {
+            if (i < num_reserved) {
+                diag_printf("Sorry, '%s' is a reserved image and cannot be deleted\n", img->name);
+                return;
+            }
             if (!verify_action("Delete image '%s'", name)) {
                 return;
             } else {
@@ -1636,6 +1712,13 @@ flash_write_config(void)
     config.key1 = CONFIG_KEY1;  
     config.key2 = CONFIG_KEY2;
     config.cksum = crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum));
+    if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
+        cfg_base = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size));
+    } else {
+        cfg_base = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size));
+    }
     if (verify_action("Update RedBoot non-volatile configuration")) {
 #ifdef CYGSEM_REDBOOT_FLASH_LOCK_SPECIAL
         // Insure [quietly] that the config page is unlocked before trying to update
@@ -1854,7 +1937,13 @@ load_flash_config(void)
 #define _roundup(n,s) ((((n)+(s-1))/s)*s)
     cfg_size = (block_size > sizeof(config)) ? sizeof(config) : 
                                                _roundup(sizeof(config), block_size);
-    cfg_base = (void *)((unsigned long)flash_end - _roundup(cfg_size+fisdir_size, block_size));
+    if (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK < 0) {
+        cfg_base = (void *)((unsigned long)flash_end + 
+                            (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size));
+    } else {
+        cfg_base = (void *)((unsigned long)flash_start + 
+                            (CYGNUM_REDBOOT_FLASH_CONFIG_BLOCK*block_size));
+    }
     memcpy(&config, cfg_base, sizeof(config));
     if ((crc32((unsigned char *)&config, sizeof(config)-sizeof(config.cksum)) != config.cksum) ||
         (config.key1 != CONFIG_KEY1)|| (config.key2 != CONFIG_KEY2)) {