FreeCalypso > hg > freecalypso-sw
diff loadtools/flutil.c @ 405:a212b4968b29
fc-loadtool flash: another refactoring: geometry vs. command set
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Tue, 17 Jun 2014 00:33:05 +0000 |
parents | 7602443edf0d |
children | f2cc551e597f |
line wrap: on
line diff
--- a/loadtools/flutil.c Mon Jun 16 01:15:17 2014 +0000 +++ b/loadtools/flutil.c Tue Jun 17 00:33:05 2014 +0000 @@ -9,6 +9,8 @@ #include "flash.h" extern struct flash_bank_info flash_bank_info[2]; +extern struct flash_cmdset flash_cmdset_amd; +extern struct flash_cmdset flash_cmdset_intel; static int cfi_read_byte(bi, off, ret16p) @@ -37,29 +39,17 @@ return(0); } -static int -cfi_id_return_to_read_mode(bi) - struct flash_bank_info *bi; -{ - if (do_w16(bi->base_addr + 0xAAA, 0xF0)) { - fprintf(stderr, - "unexpected response to w16 when resetting flash to read mode!\n"); - return(-1); - } - return(0); -} - flash_get_cfi(bank) { struct flash_bank_info *bi; - struct cfi_info *cfi; + struct flash_geom *geom; struct flash_region_desc *reg; int nr; - uint16_t rdval; + uint16_t rdval, cmdset_id; uint32_t size_check; bi = flash_bank_info + bank; - if (bi->cfi) + if (bi->geom) return(0); printf("Performing CFI query\n"); if (do_w16(bi->base_addr + 0xAA, 0x98)) { @@ -71,7 +61,7 @@ return(-1); if (rdval != 'Q') { noqry: fprintf(stderr, "error: no QRY response from flash\n"); - cfi_id_return_to_read_mode(bi); + amd_reset_cmd(bi); return(-1); } if (cfi_read_byte(bi, 0x11, &rdval) < 0) @@ -82,35 +72,52 @@ return(-1); if (rdval != 'Y') goto noqry; - cfi = malloc(sizeof(struct cfi_info)); - if (!cfi) { + if (cfi_read_twobyte(bi, 0x13, &cmdset_id) < 0) + return(-1); + if (!bi->ops) { + switch (cmdset_id) { + case 2: + bi->ops = &flash_cmdset_amd; + break; +#if 0 + case 3: + bi->ops = &flash_cmdset_intel; + break; +#endif + default: + fprintf(stderr, "error: command set %04X unsupported\n", + cmdset_id); + amd_reset_cmd(bi); + return(-1); + } + } + geom = malloc(sizeof(struct flash_geom)); + if (!geom) { fprintf(stderr, - "unable to malloc buffer for flash bank %d CFI structure\n", + "unable to malloc buffer for flash bank %d CFI geometry structure\n", bank); - cfi_id_return_to_read_mode(bi); - return(-1); - } - if (cfi_read_twobyte(bi, 0x13, &cfi->cmdset_style) < 0) { -free_and_immed_out: - free(cfi); + bi->ops->reset_cmd(bi); return(-1); } /* total device size */ - if (cfi_read_byte(bi, 0x27, &rdval) < 0) - goto free_and_immed_out; + if (cfi_read_byte(bi, 0x27, &rdval) < 0) { +free_and_immed_out: + free(geom); + return(-1); + } if (rdval < 20 || rdval > 24) { fprintf(stderr, "error: CFI reports unreasonable device size\n"); free_and_clean_out: - free(cfi); - cfi_id_return_to_read_mode(bi); + free(geom); + bi->ops->reset_cmd(bi); return(-1); } - cfi->total_size = 1 << rdval; - if (cfi->total_size > bi->bank_desc->align_size) { + geom->total_size = 1 << rdval; + if (geom->total_size > bi->bank_desc->align_size) { fprintf(stderr, "error: CFI device size 0x%lx exceeds configured maximum 0x%lx\n", - (u_long) cfi->total_size, bi->bank_desc->align_size); + (u_long) geom->total_size, bi->bank_desc->align_size); goto free_and_clean_out; } if (cfi_read_byte(bi, 0x2C, &rdval) < 0) @@ -120,11 +127,11 @@ "error: CFI reports unreasonable # of erase regions\n"); goto free_and_clean_out; } - cfi->nregions = rdval; - cfi->total_sectors = 0; + geom->nregions = rdval; + geom->total_sectors = 0; size_check = 0; - for (nr = 0; nr < cfi->nregions; nr++) { - reg = cfi->regions + nr; + for (nr = 0; nr < geom->nregions; nr++) { + reg = geom->regions + nr; if (cfi_read_twobyte(bi, 0x2D + nr*4, &rdval) < 0) goto free_and_immed_out; if (rdval > 255) { @@ -134,7 +141,7 @@ goto free_and_clean_out; } reg->nsectors = rdval + 1; - cfi->total_sectors += reg->nsectors; + geom->total_sectors += reg->nsectors; if (cfi_read_twobyte(bi, 0x2F + nr*4, &rdval) < 0) goto free_and_immed_out; if (rdval < 0x20 || rdval > 0x400) { @@ -146,31 +153,30 @@ reg->sector_size = rdval << 8; size_check += reg->sector_size * reg->nsectors; } - if (cfi_id_return_to_read_mode(bi) < 0) { + if (bi->ops->reset_cmd(bi) < 0) { /* error msg already printed */ - free(cfi); + free(geom); return(-1); } - if (size_check != cfi->total_size) { + if (size_check != geom->total_size) { fprintf(stderr, "CFI error: added size of erase regions (%lx) != reported devive size (%lx)\n", - (u_long) size_check, (u_long) cfi->total_size); - free(cfi); + (u_long) size_check, (u_long) geom->total_size); + free(geom); return(-1); } /* all checks passed */ - bi->cfi = cfi; + bi->geom = geom; printf( -"CFI query successful: total size %lx, %u sectors, command set style %04X\n\n", - (u_long) cfi->total_size, cfi->total_sectors, - cfi->cmdset_style); +"CFI query successful: total size %lx, %u sectors, command set style %04X\n", + (u_long) geom->total_size, geom->total_sectors, cmdset_id); return(1); } get_flash_sector_table(bank) { struct flash_bank_info *bi; - struct cfi_info *cfi; + struct flash_geom *geom; struct flash_region_desc *reg; struct sector_info *sp; uint32_t offset; @@ -182,9 +188,9 @@ i = flash_get_cfi(bank); if (i < 0) return(i); - cfi = bi->cfi; + geom = bi->geom; sp = (struct sector_info *) malloc(sizeof(struct sector_info) - * (cfi->total_sectors + 1)); + * (geom->total_sectors + 1)); if (!sp) { fprintf(stderr, "unable to malloc buffer for flash bank %d sector table\n", @@ -194,8 +200,8 @@ bi->sectors = sp; /* now fill it */ offset = 0; - for (nr = 0; nr < cfi->nregions; nr++) { - reg = cfi->regions + nr; + for (nr = 0; nr < geom->nregions; nr++) { + reg = geom->regions + nr; for (i = 0; i < reg->nsectors; i++) { sp->start = offset; sp->size = reg->sector_size; @@ -204,12 +210,12 @@ } } /* sanity checks */ - if (sp - bi->sectors != cfi->total_sectors) { + if (sp - bi->sectors != geom->total_sectors) { fprintf(stderr, "BUG in get_flash_sector_table(): wrong # of sectors at the end\n"); abort(); } - if (offset != cfi->total_size) { + if (offset != geom->total_size) { fprintf(stderr, "BUG in get_flash_sector_table(): wrong offset at the end\n"); abort(); @@ -233,7 +239,7 @@ if (get_flash_sector_table(bank) < 0) return(-1); bi = flash_bank_info + bank; - printf("%u sectors in flash bank %d:\n", bi->cfi->total_sectors, bank); + printf("%u sectors in flash bank %d:\n", bi->geom->total_sectors, bank); printf("Offset Size\n"); for (sp = bi->sectors; sp->size; sp++) printf("%08lX %lx\n", (u_long) sp->start, (u_long) sp->size);