FreeCalypso > hg > freecalypso-sw
diff loadtools/ltflash.c @ 400:f027c6fbe37e
fc-loadtool flash: first round of refactoring for CFI
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 15 Jun 2014 20:05:54 +0000 |
parents | cd12d1049f91 |
children | 7ceeec049be4 |
line wrap: on
line diff
--- a/loadtools/ltflash.c Sun Jun 15 00:47:06 2014 +0000 +++ b/loadtools/ltflash.c Sun Jun 15 20:05:54 2014 +0000 @@ -1,6 +1,6 @@ /* - * In this module we are going to implement the flash operation commands - * of fc-loadtool. + * This module contains the "core" of fc-loadtool flash operations; + * fl*.c modules contain the rest. */ #include <sys/types.h> @@ -13,11 +13,12 @@ /* K5A32xx device description */ -static struct flash_region_desc k5a32xx_topboot_regions[] = { - /* 4 MiB total, 64 KiB sectors except for the boot block of 8x 8 KiB */ - {0x10000, 63}, - {0x2000, 8}, - {0, 0} /* array terminator */ +static struct cfi_info k5a32xx_topboot_hardcfi = { + .cmdset_style = 2, + .total_size = 0x400000, + .nregions = 2, + .regions = {0x10000, 63, 0x2000, 8}, + .total_sectors = 71 }; static struct flash_idcheck k5a32xx_topboot_idcheck[2] = { @@ -26,23 +27,25 @@ }; static struct flash_bank_desc k5a32xx_topboot_bankdesc = { - k5a32xx_topboot_regions, 0xFFF00000, k5a32xx_topboot_idcheck, 2 + 0x400000, &k5a32xx_topboot_hardcfi, k5a32xx_topboot_idcheck, 2 }; /* S{29,71}PL129N device description */ -static struct flash_region_desc pl129n_ce1_regions[] = { - /* 4 sectors of 64 KiB each at the beginning, then 256 KiB sectors */ - {0x10000, 4}, - {0x40000, 31}, - {0, 0} /* array terminator */ +static struct cfi_info pl129n_ce1_hardcfi = { + .cmdset_style = 2, + .total_size = 0x800000, + .nregions = 2, + .regions = {0x10000, 4, 0x40000, 31}, + .total_sectors = 35 }; -static struct flash_region_desc pl129n_ce2_regions[] = { - /* the other way around now */ - {0x40000, 31}, - {0x10000, 4}, - {0, 0} /* array terminator */ +static struct cfi_info pl129n_ce2_hardcfi = { + .cmdset_style = 2, + .total_size = 0x800000, + .nregions = 2, + .regions = {0x40000, 31, 0x10000, 4}, + .total_sectors = 35 }; static struct flash_idcheck pl129n_idcheck[4] = { @@ -53,8 +56,8 @@ }; static struct flash_bank_desc pl129n_banks[2] = { - {pl129n_ce1_regions, 0xFFFC0000, pl129n_idcheck, 4}, - {pl129n_ce2_regions, 0xFFFC0000, pl129n_idcheck, 4} + {0x800000, &pl129n_ce1_hardcfi, pl129n_idcheck, 4}, + {0x800000, &pl129n_ce2_hardcfi, pl129n_idcheck, 4} }; /* list of supported flash devices */ @@ -130,20 +133,14 @@ } /* the rest comes from the flash device type */ bi->bank_desc = selected_flash_device->bank_desc + bank; - compute_flash_totsize_nsecs(bank); - if (count_ones(bi->total_size) != 1) { - fprintf(stderr, -"fc-loadtool internal bug: flash bank %d size for %s is not a power of 2\n", - bank, selected_flash_device->name); - exit(1); - } - if (bi->base_addr & (bi->total_size - 1)) { + if (bi->base_addr & (bi->bank_desc->align_size - 1)) { fprintf(stderr, "%s line %d: flash bank %d base addr is not aligned to the bank size (0x%lx)\n", filename_for_errs, lineno_for_errs, bank, - (u_long) bi->total_size); + (u_long) bi->bank_desc->align_size); exit(1); } + bi->cfi = bi->bank_desc->hard_cfi; } while (isspace(*cp)) cp++; @@ -171,20 +168,22 @@ offset = strtoul(argv[2], &strtoul_endp, 16); if (*strtoul_endp) goto inv; + if (flash_get_cfi(bank) < 0) + return(-1); bi = flash_bank_info + bank; - if (offset >= bi->total_size) { + if (offset >= bi->cfi->total_size) { fprintf(stderr, "error: specified offset exceeds flash bank size (0x%lx)\n", - (u_long) bi->total_size); + (u_long) bi->cfi->total_size); return(-1); } len = strtoul(argv[3], &strtoul_endp, 16); if (*strtoul_endp) goto inv; - if (len > bi->total_size - offset) { + if (len > bi->cfi->total_size - offset) { fprintf(stderr, "error: specified offset+length exceed flash bank size (0x%lx)\n", - (u_long) bi->total_size); + (u_long) bi->cfi->total_size); return(-1); } sprintf(targ_start, "%lx", (u_long) bi->base_addr + offset); @@ -212,20 +211,22 @@ argv[0], argv[1]); return(-1); } + if (flash_get_cfi(bank) < 0) + return(-1); bi = flash_bank_info + bank; if (argc >= 4) { offset = strtoul(argv[3], &strtoul_endp, 16); if (*strtoul_endp) goto inv; - if (offset >= bi->total_size) { + if (offset >= bi->cfi->total_size) { fprintf(stderr, "error: specified offset exceeds flash bank size (0x%lx)\n", - (u_long) bi->total_size); + (u_long) bi->cfi->total_size); return(-1); } } else offset = 0; - maxlen = bi->total_size - offset; + maxlen = bi->cfi->total_size - offset; if (argc >= 5) { dumplen = strtoul(argv[4], &strtoul_endp, 16); if (*strtoul_endp) @@ -233,7 +234,7 @@ if (dumplen > maxlen) { fprintf(stderr, "error: specified offset+length exceed flash bank size (0x%lx)\n", - (u_long) bi->total_size); + (u_long) bi->cfi->total_size); return(-1); } } else @@ -271,8 +272,11 @@ bi = flash_bank_info + bank; printf("Flash device type: %s\n", selected_flash_device->name); printf("Bank %d base address: %08lX\n", bank, (u_long) bi->base_addr); - printf("Bank %d total size: %lx\n", bank, (u_long) bi->total_size); - printf("Sectors in bank %d: %u\n", bank, bi->nsectors); + if (flash_get_cfi(bank) < 0) + return(-1); + printf("Bank %d total size: %lx\n", bank, (u_long) bi->cfi->total_size); + printf("Sectors in bank %d: %u (%u regions)\n", bank, + bi->cfi->total_sectors, bi->cfi->nregions); flash_id_check(bank, 1); if (selected_flash_device->nbanks == 2 && !bank) printf("\nFlash device has 2 banks; flash2 command available\n"); @@ -285,8 +289,15 @@ char *targv[4], targ_base[10]; int stat; + if (flash_get_cfi(bank) < 0) + return(-1); + if (flash_bank_info[bank].cfi->cmdset_style != 2) { + fprintf(stderr, +"error: this command is currently only implemented for AMD-style flash\n"); + return(-1); + } if (argc != 4) { -inv: fprintf(stderr, "usage: %s %s hex-offset hex-data-string\n", + fprintf(stderr, "usage: %s %s hex-offset hex-data-string\n", argv[0], argv[1]); return(-1); }