view loadtools/flerase.c @ 737:6d97866bad79

first round of documentation for DUART28C boot control addition
author Mychaela Falconia <falcon@freecalypso.org>
date Wed, 16 Sep 2020 06:10:39 +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);
}