view loadtools/flutil.c @ 733:bed7981ac8ca

doc/Compal-FFS: update for IMEI found in OTP cells
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 28 Aug 2020 15:58:46 +0000
parents 135de08c5d74
children
line wrap: on
line source

/*
 * Miscellaneous utility functions for flash support
 */

#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "flash.h"

extern struct flash_bank_info flash_bank_info[2];

get_flash_sector_table(bi)
	struct flash_bank_info *bi;
{
	struct flash_geom *geom;
	struct flash_region_desc *reg;
	struct sector_info *sp;
	uint32_t offset;
	int nr, i;

	if (bi->sectors)
		return(0);
	geom = bi->geom;
	sp = (struct sector_info *) malloc(sizeof(struct sector_info)
						* (geom->total_sectors + 1));
	if (!sp) {
		fprintf(stderr,
			"unable to malloc buffer for flash sector table\n");
		return(-1);
	}
	bi->sectors = sp;
	/* now fill it */
	offset = 0;
	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;
			sp++;
			offset += reg->sector_size;
		}
	}
	/* sanity checks */
	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 != geom->total_size) {
		fprintf(stderr,
		"BUG in get_flash_sector_table(): wrong offset at the end\n");
		abort();
	}
	/* finish */
	sp->start = 0;
	sp->size = 0;
	return(0);
}

flashcmd_sectors(argc, argv, bank)
	char **argv;
{
	struct flash_bank_info *bi;
	struct sector_info *sp;

	if (argc > 2) {
		fprintf(stderr, "error: too many arguments\n");
		return(-1);
	}
	if (flash_detect(bank, 0) < 0)
		return(-1);
	bi = flash_bank_info + bank;
	if (get_flash_sector_table(bi) < 0)
		return(-1);
	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);
	return(0);
}

get_flash_sector_range(bi, useroff, userlen, startp, endp)
	struct flash_bank_info *bi;
	u_long useroff, userlen;
	struct sector_info **startp, **endp;
{
	struct sector_info *sp;
	uint32_t remlen;

	for (sp = bi->sectors; sp->size; sp++)
		if (sp->start == useroff)
			break;
	if (!sp->size) {
		fprintf(stderr,
	"error: specified offset not aligned to a flash sector boundary\n");
		return(-1);
	}
	*startp = sp;
	for (remlen = userlen; remlen; ) {
		if (remlen < sp->size) {
			fprintf(stderr,
	"error: specified length not aligned to a flash sector boundary\n");
			return(-1);
		}
		remlen -= sp->size;
		sp++;
	}
	*endp = sp;
	return(0);
}