]> git.kernelconcepts.de Git - karo-tx-redboot.git/blobdiff - packages/redboot/v2_0/src/flash.c
Starterkit 5 Release 1.5 Bugfix
[karo-tx-redboot.git] / packages / redboot / v2_0 / src / flash.c
index 5517631a8f8b68672c3fd95c74724a5eb2f33c59..b3f0beaa4ab56514e3fbf6ff9ed61ec6deba6338 100644 (file)
@@ -372,7 +372,7 @@ fis_update_directory(int autolock, int error)
 #endif
 #ifdef CYGHWR_IO_FLASH_BLOCK_LOCKING
     if (do_autolock)
-       flash_unlock((void *)fis_addr, blk_size, &err_addr);
+               flash_unlock((void *)fis_addr, blk_size, &err_addr);
 #endif
     if ((stat = flash_erase(fis_addr, flash_block_size, &err_addr)) != 0) {
                diag_printf("Error erasing FIS directory at %p: %s\n", err_addr, flash_errmsg(stat));
@@ -723,33 +723,33 @@ fis_list(int argc, char *argv[])
     last_addr = 0;
     image_indx = 0;
     do {
-       image_found = false;
-       lowest_addr = 0xFFFFFFFF;
-       img = fis_work_block;
-       for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
-           if (img->u.name[0] != 0xFF) {
-               if ((img->flash_base >= last_addr) && (img->flash_base < lowest_addr)) {
-                   lowest_addr = img->flash_base;
-                   image_found = true;
-                   image_indx = i;
+               image_found = false;
+               lowest_addr = 0xFFFFFFFF;
+               img = fis_work_block;
+               for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
+                       if (img->u.name[0] != 0xFF) {
+                               if ((img->flash_base >= last_addr) && (img->flash_base < lowest_addr)) {
+                                       lowest_addr = img->flash_base;
+                                       image_found = true;
+                                       image_indx = i;
+                               }
+                       }
                }
-           }
-       }
-       if (image_found) {
-           img = fis_work_block;
-           img += image_indx;
-           diag_printf("%-16s  0x%08lX  0x%08lX  0x%08lX  0x%08lX\n", img->u.name,
-                       (unsigned long)img->flash_base,
+               if (image_found) {
+                       img = fis_work_block;
+                       img += image_indx;
+                       diag_printf("%-16s  0x%08lX  0x%08lX  0x%08lX  0x%08lX\n", img->u.name,
+                                               (unsigned long)img->flash_base,
 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
-                                               show_cksums ? img->file_cksum : img->mem_base,
+                                               show_cksums ? img->file_cksum : (unsigned long)img->mem_base,
                                                show_datalen ? img->data_length : img->size,
 #else
-                                               img->mem_base,
+                                               (unsigned long)img->mem_base,
                                                img->size,
 #endif
-                       (unsigned long)img->entry_point);
-       }
-       last_addr = lowest_addr + 1;
+                                               (unsigned long)img->entry_point);
+               }
+               last_addr = lowest_addr + 1;
     } while (image_found == true);
 }
 
@@ -825,6 +825,7 @@ fis_free(int argc, char *argv[])
     unsigned long *area_start;
     void *err_addr;
 
+       FLASH_Enable(flash_start, flash_end);
     // Do not search the area reserved for pre-RedBoot systems:
     fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start +
                                                                CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
@@ -856,6 +857,7 @@ fis_free(int argc, char *argv[])
                diag_printf("  0x%08x .. 0x%08x\n",
                                        (CYG_ADDRESS)area_start, (CYG_ADDRESS)fis_ptr);
     }
+       FLASH_Disable(flash_start, flash_end);
 #else
     struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS];
     int idx, num_chunks;
@@ -882,13 +884,14 @@ fis_find_free(CYG_ADDRESS *addr, unsigned long length)
     fis_ptr = (unsigned long *)((CYG_ADDRESS)flash_start +
                                                                CYGNUM_REDBOOT_FLASH_RESERVED_BASE);
     fis_end = (unsigned long *)(CYG_ADDRESS)flash_end;
+       FLASH_Enable(fis_ptr, fis_end);
     area_start = fis_ptr;
     while (fis_ptr < fis_end) {
                flash_read(fis_ptr, &flash_data, sizeof(unsigned long), &err_addr);
                if (flash_data != 0xFFFFFFFF) {
                        if (area_start != fis_ptr) {
                                // Assume that this is something
-                               if ((fis_ptr - area_start) >= (length/sizeof(unsigned))) {
+                               if ((fis_ptr - area_start) >= (length / sizeof(unsigned))) {
                                        *addr = (CYG_ADDRESS)area_start;
                                        return true;
                                }
@@ -907,6 +910,8 @@ fis_find_free(CYG_ADDRESS *addr, unsigned long length)
                        fis_ptr += flash_block_size / sizeof(CYG_ADDRESS);
                }
     }
+       FLASH_Disable((void *)((CYG_ADDRESS)flash_start +
+                                                  CYGNUM_REDBOOT_FLASH_RESERVED_BASE), fis_end);
     if (area_start != fis_ptr) {
                if (fis_ptr - area_start >= length / sizeof(unsigned)) {
                        *addr = (CYG_ADDRESS)area_start;
@@ -1043,8 +1048,9 @@ fis_create(int argc, char *argv[])
                return;
     }
     if (strlen(name) >= sizeof(img->u.name)) {
-       diag_printf("Name is too long, must be less than %d chars\n", sizeof(img->u.name));
-       return;
+               diag_printf("Name is too long, must be less than %d chars\n",
+                                       sizeof(img->u.name));
+               return;
     }
     if (!no_copy) {
                if ((mem_addr < (CYG_ADDRESS)ram_start) ||
@@ -1078,7 +1084,8 @@ fis_create(int argc, char *argv[])
                        if (defaults_assumed) {
                                if (no_copy &&
                                        !verify_action("* CAUTION * about to program '%s'\n                at %p..%p from %p",
-                                                                  name, (void *)flash_addr, (void *)(flash_addr+img_size-1),
+                                                                  name, (void *)flash_addr,
+                                                                  (void *)(flash_addr + img_size - 1),
                                                                   (void *)mem_addr)) {
                                        return;  // The guy gave up
                                }
@@ -1086,67 +1093,75 @@ fis_create(int argc, char *argv[])
                }
     } else {
 #ifdef CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS
-       // Make sure that any FLASH address specified directly is truly free
-       if (flash_addr_set && !no_copy) {
-           struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS];
-           int idx, num_chunks;
-           bool is_free = false;
-
-           num_chunks = find_free(chunks);
-           for (idx = 0;  idx < num_chunks;  idx++) {
-               if ((flash_addr >= chunks[idx].start) &&
-                   ((flash_addr+length-1) <= chunks[idx].end)) {
-                   is_free = true;
+               // Make sure that any FLASH address specified directly is truly free
+               if (flash_addr_set && !no_copy) {
+                       struct free_chunk chunks[CYGDAT_REDBOOT_FIS_MAX_FREE_CHUNKS];
+                       int idx, num_chunks;
+                       bool is_free = false;
+
+                       num_chunks = find_free(chunks);
+                       for (idx = 0;  idx < num_chunks;  idx++) {
+                               if ((flash_addr >= chunks[idx].start) &&
+                                       ((flash_addr + length - 1) <= chunks[idx].end)) {
+                                       is_free = true;
+                               }
+                       }
+                       if (!is_free) {
+                               diag_printf("Invalid FLASH address - not free!\n");
+                               return;
+                       }
                }
-           }
-           if (!is_free) {
-               diag_printf("Invalid FLASH address - not free!\n");
-               return;
-           }
-       }
 #endif
-       // If not image by that name, try and find an empty slot
-       img = fis_work_block;
-       for (i = 0;  i < fisdir_size/sizeof(*img);  i++, img++) {
-           if (img->u.name[0] == 0xFF) {
-               break;
-           }
-       }
-               if (i >= fisdir_size/sizeof(*img)) {
+               // If not image by that name, try and find an empty slot
+               img = fis_work_block;
+               for (i = 0;  i < fisdir_size / sizeof(*img);  i++, img++) {
+                       if (img->u.name[0] == 0xFF) {
+                               break;
+                       }
+               }
+               if (i >= fisdir_size / sizeof(*img)) {
                        diag_printf("Can't find an empty slot in FIS directory!\n");
                        return;
                }
     }
     if (!no_copy) {
                // Safety check - make sure the address range is not within the code we're running
-               if (flash_code_overlaps((void *)flash_addr, (void *)(flash_addr+img_size-1))) {
+               if (flash_code_overlaps((void *)flash_addr,
+                                                               (void *)(flash_addr + img_size - 1))) {
                        diag_printf("Can't program this region - contains code in use!\n");
                        return;
                }
                if (prog_ok) {
+                       FLASH_Enable((void *)flash_addr, (void *)(flash_addr + length));
                        // Erase area to be programmed
-                       if ((stat = flash_erase((void *)flash_addr, length, &err_addr)) != 0) {
+                       stat = flash_erase((void *)flash_addr, length, &err_addr);
+                       FLASH_Disable((void *)flash_addr, (void *)(flash_addr + length));
+                       if (stat != 0) {
                                diag_printf("Can't erase region at %p: %s\n", err_addr, flash_errmsg(stat));
                                prog_ok = false;
                        }
                }
                if (prog_ok) {
                        // Now program it
-                       if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, img_size, &err_addr)) != 0) {
+                       FLASH_Enable((void *)flash_addr, (void *)(flash_addr + length));
+                       stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr,
+                                                                img_size, &err_addr);
+                       FLASH_Disable((void *)flash_addr, (void *)(flash_addr + length));
+                       if (stat != 0) {
                                diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
                                prog_ok = false;
                        }
                }
     }
     if (prog_ok) {
-       // Update directory
-       memset(img, 0, sizeof(*img));
-       strcpy(img->u.name, name);
-       img->flash_base = flash_addr;
-       img->mem_base = exec_addr_set ? exec_addr : (mem_addr_set ? mem_addr : flash_addr);
-       img->entry_point = entry_addr_set ? entry_addr : (CYG_ADDRESS)entry_address;  // Hope it's been set
-       img->size = length;
-       img->data_length = img_size;
+               // Update directory
+               memset(img, 0, sizeof(*img));
+               strcpy(img->u.name, name);
+               img->flash_base = flash_addr;
+               img->mem_base = exec_addr_set ? exec_addr : (mem_addr_set ? mem_addr : flash_addr);
+               img->entry_point = entry_addr_set ? entry_addr : (CYG_ADDRESS)entry_address;  // Hope it's been set
+               img->size = length;
+               img->data_length = img_size;
 #ifdef CYGSEM_REDBOOT_FIS_CRC_CHECK
                if (!no_copy) {
                        img->file_cksum = cyg_crc32((unsigned char *)mem_addr, img_size);
@@ -1155,8 +1170,8 @@ fis_create(int argc, char *argv[])
                        img->file_cksum = 0;
                }
 #endif
-       fis_start_update_directory(0);
-       fis_update_directory(0, 0);
+               fis_start_update_directory(0);
+               fis_update_directory(0, 0);
     }
 }
 
@@ -1333,8 +1348,13 @@ fis_load(int argc, char *argv[])
     } else // dangling block
 #endif
                {
-                       if (flash_read((void *)img->flash_base, (void *)mem_addr,
-                                                  img->data_length, &err_addr) != FLASH_ERR_OK) {
+                       int err;
+
+                       FLASH_Enable((void *)img->flash_base, (void *)(img->flash_base + img->size));
+                       err = flash_read((void *)img->flash_base, (void *)mem_addr,
+                                                        img->data_length, &err_addr);
+                       FLASH_Disable((void *)img->flash_base, (void *)(img->flash_base + img->size));
+                       if (err != FLASH_ERR_OK) {
                                diag_printf("** Error: Failed to load image from flash\n");
                                return;
                        }
@@ -1410,7 +1430,7 @@ fis_write(int argc, char *argv[])
                return;
     }
     if ((mem_addr < (CYG_ADDRESS)ram_start) ||
-               ((mem_addr+length) >= (CYG_ADDRESS)ram_end)) {
+               ((mem_addr + length) >= (CYG_ADDRESS)ram_end)) {
                diag_printf("** WARNING: RAM address: %p may be invalid\n", (void *)mem_addr);
                diag_printf("   valid range is %p-%p\n", (void *)ram_start, (void *)ram_end);
     }
@@ -1434,7 +1454,8 @@ fis_write(int argc, char *argv[])
     }
     if (prog_ok) {
                // Now program it
-               if ((stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, length, &err_addr)) != 0) {
+               stat = FLASH_PROGRAM((void *)flash_addr, (void *)mem_addr, length, &err_addr);
+               if (stat != 0) {
                        diag_printf("Can't program region at %p: %s\n", err_addr, flash_errmsg(stat));
                        prog_ok = false;
                }
@@ -1505,11 +1526,10 @@ fis_lock(int argc, char *argv[])
                          &flash_addr, &flash_addr_set, "FLASH memory base address");
     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM,
                          &length, &length_set, "length");
-    if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name"))
-               {
-                       fis_usage("invalid arguments");
-                       return;
-               }
+    if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) {
+               fis_usage("invalid arguments");
+               return;
+       }
 #ifdef CYGOPT_REDBOOT_FIS
     /* Get parameters from image if specified */
     if (name) {
@@ -1519,8 +1539,8 @@ fis_lock(int argc, char *argv[])
                        return;
                }
 
-       flash_addr = img->flash_base;
-       length = img->size;
+               flash_addr = img->flash_base;
+               length = img->size;
     } else
 #endif
                if (!flash_addr_set || !length_set) {
@@ -1554,11 +1574,10 @@ fis_unlock(int argc, char *argv[])
                          &flash_addr, &flash_addr_set, "FLASH memory base address");
     init_opts(&opts[1], 'l', true, OPTION_ARG_TYPE_NUM,
                          &length, &length_set, "length");
-    if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name"))
-               {
-                       fis_usage("invalid arguments");
-                       return;
-               }
+    if (!scan_opts(argc, argv, 2, opts, 2, &name, OPTION_ARG_TYPE_STR, "image name")) {
+               fis_usage("invalid arguments");
+               return;
+       }
 #ifdef CYGOPT_REDBOOT_FIS
     if (name) {
                struct fis_image_desc *img;
@@ -1567,8 +1586,8 @@ fis_unlock(int argc, char *argv[])
                        return;
                }
 
-       flash_addr = img->flash_base;
-       length = img->size;
+               flash_addr = img->flash_base;
+               length = img->size;
     } else
 #endif
                if (!flash_addr_set || !length_set) {