view loadtools/flconf.c @ 994:ad3041e19884

fc-loadtool flash: implement PPB ops for Spansion PL-N
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 03 Dec 2023 06:16:30 +0000
parents 0dd2c87c1b63
children
line wrap: on
line source

/*
 * This module handles flash configuration for fc-loadtool
 */

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

/* the following variables describe our selected flash config */

int flash_global_config;
struct flash_bank_info flash_bank_info[2];

/* global configurations selected via hw parameter files */

static struct global_cfg_kw {
	char *kw;
	int code;
} global_cfg_keywords[] = {
	{"single-4M", FLASH_GLOBAL_CFG_SINGLE_4M},
	{"single-8M", FLASH_GLOBAL_CFG_SINGLE_8M},
	{"dual-8M", FLASH_GLOBAL_CFG_DUAL_8M},
	/* backward compatibility with old hw param files */
	{"cfi-4M", FLASH_GLOBAL_CFG_SINGLE_4M},
	{"cfi-8M", FLASH_GLOBAL_CFG_SINGLE_8M},
	{"k5a32xx_t", FLASH_GLOBAL_CFG_SINGLE_4M},
	{"pl129n", FLASH_GLOBAL_CFG_DUAL_8M},
	{"28f640w30b", FLASH_GLOBAL_CFG_SINGLE_8M},
	{0, 0}		/* array terminator */
};

/* called from hwparam.c config file parser */
void
set_flash_config(arg, filename_for_errs, lineno_for_errs)
	char *arg;
	char *filename_for_errs;
	int lineno_for_errs;
{
	char *cp, *np, *ep;
	struct global_cfg_kw *tp;
	int bank, nbanks;
	struct flash_bank_info *bi;
	uint32_t align_size;

	if (flash_global_config) {
		fprintf(stderr, "%s line %d: duplicate flash setting\n",
			filename_for_errs, lineno_for_errs);
		exit(1);
	}
	for (cp = arg; isspace(*cp); cp++)
		;
	if (!*cp || *cp == '#') {
too_few_arg:	fprintf(stderr,
			"%s line %d: flash setting: too few arguments\n",
			filename_for_errs, lineno_for_errs);
		exit(1);
	}
	for (np = cp; *cp && !isspace(*cp); cp++)
		;
	if (*cp)
		*cp++ = '\0';
	for (tp = global_cfg_keywords; tp->kw; tp++)
		if (!strcmp(tp->kw, np))
			break;
	if (!tp->kw) {
		fprintf(stderr,
			"%s line %d: unknown flash config \"%s\"\n",
			filename_for_errs, lineno_for_errs, np);
		exit(1);
	}
	flash_global_config = tp->code;

	/* now initialize flash_bank_info (base addresses) */
	switch (flash_global_config) {
	case FLASH_GLOBAL_CFG_SINGLE_4M:
		nbanks = 1;
		align_size = 0x400000;
		break;
	case FLASH_GLOBAL_CFG_SINGLE_8M:
		nbanks = 1;
		align_size = 0x800000;
		break;
	case FLASH_GLOBAL_CFG_DUAL_8M:
		nbanks = 2;
		align_size = 0x800000;
		break;
	default:
		fprintf(stderr,
			"BUG in set_flash_config(): invalid global config\n");
		abort();
	}
	for (bank = 0; bank < nbanks; bank++) {
		while (isspace(*cp))
			cp++;
		if (!*cp || *cp == '#')
			goto too_few_arg;
		for (np = cp; *cp && !isspace(*cp); cp++)
			;
		if (*cp)
			*cp++ = '\0';
		bi = flash_bank_info + bank;
		bi->base_addr = strtoul(np, &ep, 16);
		if (*ep) {
			fprintf(stderr,
"%s line %d: syntax error (base addr expected after flash config name)\n",
				filename_for_errs, lineno_for_errs);
			exit(1);
		}
		/* check alignment */
		if (bi->base_addr & (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) align_size);
			exit(1);
		}
	}
	while (isspace(*cp))
		cp++;
	if (*cp && *cp != '#') {
		fprintf(stderr,
			"%s line %d: flash setting: too many arguments\n",
			filename_for_errs, lineno_for_errs);
		exit(1);
	}
}