FreeCalypso > hg > freecalypso-tools
view loadtools/flerase.c @ 973:7c18eac91457
loadtools: round out support for Intel flash families
The three Intel flash families encountered so far in Calypso GSM devices
are C3, W30 and W18, sizes from 2 to 8 MiB. Let's support all Intel
flash chips from these 3 families across this range of sizes.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 28 Nov 2023 18:56:40 +0000 |
parents | 185c9bf208d3 |
children |
line wrap: on
line source
/* * Flash erase operations are implemented here */ #include <sys/types.h> #include <stdio.h> #include <stdint.h> #include <string.h> #include <strings.h> #include <stdlib.h> #include <time.h> #include "flash.h" #include "discontig.h" extern struct flash_bank_info flash_bank_info[2]; flashcmd_erase(argc, argv, bank) char **argv; { struct flash_bank_info *bi; u_long offset, len; char *strtoul_endp; struct sector_info *startsec, *endsec, *sp; int stat; time_t start_time, finish_time; unsigned duration, mm, ss; if (argc != 4) { inv: fprintf(stderr, "usage: %s %s hex-start-offset hex-length\n", argv[0], argv[1]); return(-1); } offset = strtoul(argv[2], &strtoul_endp, 16); if (*strtoul_endp) goto inv; if (flash_detect(bank, 0) < 0) return(-1); bi = flash_bank_info + bank; if (offset >= bi->geom->total_size) { fprintf(stderr, "error: specified offset exceeds flash bank size (0x%lx)\n", (u_long) bi->geom->total_size); return(-1); } len = strtoul(argv[3], &strtoul_endp, 16); if (*strtoul_endp) goto inv; if (len > bi->geom->total_size - offset) { fprintf(stderr, "error: specified offset+length exceed flash bank size (0x%lx)\n", (u_long) bi->geom->total_size); return(-1); } if (!len) { printf("Zero length specified - nothing to do!\n"); return(0); } /* now enforce sector alignment for both offset and length */ if (get_flash_sector_table(bi) < 0) return(-1); if (get_flash_sector_range(bi, offset, len, &startsec, &endsec) < 0) return(-1); printf("Erasing %d sector(s)\n", endsec - startsec); time(&start_time); for (sp = startsec; sp < endsec; sp++) { stat = bi->ops->erase_sector(bi, sp); if (stat) return(stat); putchar('.'); fflush(stdout); } time(&finish_time); putchar('\n'); duration = finish_time - start_time; mm = duration / 60; ss = duration - mm * 60; printf("Operation completed in %um%02us\n", mm, ss); return(0); } erase_sectors_for_prog(bi, regions, nregions) struct flash_bank_info *bi; struct discontig_prog *regions; unsigned nregions; { struct sector_info *seclist[256], **seclp, **secendp, *sp; struct discontig_prog *regp, *regendp; uint32_t endaddr, secendaddr; int flag, stat; time_t start_time, finish_time; unsigned duration, mm, ss; if (get_flash_sector_table(bi) < 0) return(-1); seclp = seclist; endaddr = regions[nregions-1].end; regendp = regions + nregions; for (sp = bi->sectors; sp->size; sp++) { if (sp->start >= endaddr) break; secendaddr = sp->start + sp->size; flag = 0; for (regp = regions; regp < regendp; regp++) { if (regp->start >= secendaddr) break; if (sp->start >= regp->end) continue; flag = 1; break; } if (flag) *seclp++ = sp; } secendp = seclp; printf("Erasing %d sector(s)\n", secendp - seclist); time(&start_time); for (seclp = seclist; seclp < secendp; seclp++) { sp = *seclp; stat = bi->ops->erase_sector(bi, sp); if (stat) return(stat); putchar('.'); fflush(stdout); } time(&finish_time); putchar('\n'); duration = finish_time - start_time; mm = duration / 60; ss = duration - mm * 60; printf("Operation completed in %um%02us\n", mm, ss); return(0); }