1
0
mirror of https://review.coreboot.org/flashrom.git synced 2025-04-26 22:52:34 +02:00

Add opaque programmer registration infrastructure

An opaque programmer does not allow direct flash access and only offers
abstract probe/read/erase/write methods.
Due to that, opaque programmers need their own infrastructure and
registration framework.

Corresponding to flashrom svn r1459.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Michael Karcher <flashrom@mkarcher.dialup.fu-berlin.de>
This commit is contained in:
Carl-Daniel Hailfinger 2011-11-04 21:35:26 +00:00
parent b992d34339
commit 532c717bcc
8 changed files with 150 additions and 5 deletions

View File

@ -242,7 +242,7 @@ endif
CHIP_OBJS = jedec.o stm50flw0x0x.o w39.o w29ee011.o \
sst28sf040.o m29f400bt.o 82802ab.o pm49fl00x.o \
sst49lfxxxc.o sst_fwhub.o flashchips.o spi.o spi25.o sharplhf00l04.o \
a25.o at25.o
a25.o at25.o opaque.o
LIB_OBJS = layout.o

View File

@ -58,6 +58,12 @@ int spi_read_chunked(struct flashchip *flash, uint8_t *buf, int start, int len,
int spi_write_chunked(struct flashchip *flash, uint8_t *buf, int start, int len, int chunksize);
int spi_aai_write(struct flashchip *flash, uint8_t *buf, int start, int len);
/* opaque.c */
int probe_opaque(struct flashchip *flash);
int read_opaque(struct flashchip *flash, uint8_t *buf, int start, int len);
int write_opaque(struct flashchip *flash, uint8_t *buf, int start, int len);
int erase_opaque(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen);
/* a25.c */
int spi_prettyprint_status_register_amic_a25l05p(struct flashchip *flash);
int spi_prettyprint_status_register_amic_a25l40p(struct flashchip *flash);

View File

@ -62,8 +62,8 @@ enum chipbustype {
BUS_LPC = 1 << 1,
BUS_FWH = 1 << 2,
BUS_SPI = 1 << 3,
BUS_PROG = 1 << 4,
BUS_NONSPI = BUS_PARALLEL | BUS_LPC | BUS_FWH,
BUS_UNKNOWN = BUS_PARALLEL | BUS_LPC | BUS_FWH | BUS_SPI,
};
/*

View File

@ -8873,6 +8873,28 @@ const struct flashchip flashchips[] = {
.voltage = {3000, 3600}, /* Also has 12V fast program */
},
{
.vendor = "Programmer",
.name = "Opaque flash chip",
.bustype = BUS_PROG,
.manufacture_id = PROGMANUF_ID,
.model_id = PROGDEV_ID,
.total_size = 0,
.page_size = 256,
/* probe is assumed to work, rest will be filled in by probe */
.tested = TEST_OK_PROBE,
.probe = probe_opaque,
/* eraseblock sizes will be set by the probing function */
.block_erasers =
{
{
.block_erase = erase_opaque,
}
},
.write = write_opaque,
.read = read_opaque,
},
{
.vendor = "AMIC",
.name = "unknown AMIC SPI chip",

View File

@ -646,4 +646,7 @@
#define WINBOND_W49V002A 0xB0
#define WINBOND_W49V002FA 0x32
#define PROGMANUF_ID 0xFFFE /* dummy ID for opaque chips behind a programmer */
#define PROGDEV_ID 0x01 /* dummy ID for opaque chips behind a programmer */
#endif /* !FLASHCHIPS_H */

99
opaque.c Normal file
View File

@ -0,0 +1,99 @@
/*
* This file is part of the flashrom project.
*
* Copyright (C) 2011 Carl-Daniel Hailfinger
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
/*
* Contains the opaque programmer framework.
* An opaque programmer is a programmer which does not provide direct access
* to the flash chip and which abstracts all flash chip properties into a
* programmer specific interface.
*/
#include <stdint.h>
#include "flash.h"
#include "flashchips.h"
#include "chipdrivers.h"
#include "programmer.h"
const struct opaque_programmer opaque_programmer_none = {
.max_data_read = MAX_DATA_UNSPECIFIED,
.max_data_write = MAX_DATA_UNSPECIFIED,
.probe = NULL,
.read = NULL,
.write = NULL,
.erase = NULL,
};
const struct opaque_programmer *opaque_programmer = &opaque_programmer_none;
int probe_opaque(struct flashchip *flash)
{
if (!opaque_programmer->probe) {
msg_perr("%s called before register_opaque_programmer. "
"Please report a bug at flashrom@flashrom.org\n",
__func__);
return 0;
}
return opaque_programmer->probe(flash);
}
int read_opaque(struct flashchip *flash, uint8_t *buf, int start, int len)
{
if (!opaque_programmer->read) {
msg_perr("%s called before register_opaque_programmer. "
"Please report a bug at flashrom@flashrom.org\n",
__func__);
return 1;
}
return opaque_programmer->read(flash, buf, start, len);
}
int write_opaque(struct flashchip *flash, uint8_t *buf, int start, int len)
{
if (!opaque_programmer->write) {
msg_perr("%s called before register_opaque_programmer. "
"Please report a bug at flashrom@flashrom.org\n",
__func__);
return 1;
}
return opaque_programmer->write(flash, buf, start, len);
}
int erase_opaque(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen)
{
if (!opaque_programmer->erase) {
msg_perr("%s called before register_opaque_programmer. "
"Please report a bug at flashrom@flashrom.org\n",
__func__);
return 1;
}
return opaque_programmer->erase(flash, blockaddr, blocklen);
}
void register_opaque_programmer(const struct opaque_programmer *pgm)
{
if (!pgm->probe || !pgm->read || !pgm->write || !pgm->erase) {
msg_perr("%s called with one of probe/read/write/erase being "
"NULL. Please report a bug at flashrom@flashrom.org\n",
__func__);
return;
}
opaque_programmer = pgm;
buses_supported |= BUS_PROG;
}

View File

@ -32,13 +32,11 @@
char *flashbuses_to_text(enum chipbustype bustype)
{
char *ret = calloc(1, 1);
if (bustype == BUS_UNKNOWN) {
ret = strcat_realloc(ret, "Unknown, ");
/*
* FIXME: Once all chipsets and flash chips have been updated, NONSPI
* will cease to exist and should be eliminated here as well.
*/
} else if (bustype == BUS_NONSPI) {
if (bustype == BUS_NONSPI) {
ret = strcat_realloc(ret, "Non-SPI, ");
} else {
if (bustype & BUS_PARALLEL)
@ -49,6 +47,8 @@ char *flashbuses_to_text(enum chipbustype bustype)
ret = strcat_realloc(ret, "FWH, ");
if (bustype & BUS_SPI)
ret = strcat_realloc(ret, "SPI, ");
if (bustype & BUS_PROG)
ret = strcat_realloc(ret, "Programmer-specific, ");
if (bustype == BUS_NONE)
ret = strcat_realloc(ret, "None, ");
}

View File

@ -24,6 +24,8 @@
#ifndef __PROGRAMMER_H__
#define __PROGRAMMER_H__ 1
#include "flash.h" /* for chipaddr and flashchip */
enum programmer {
#if CONFIG_INTERNAL == 1
PROGRAMMER_INTERNAL,
@ -601,6 +603,19 @@ int sb600_probe_spi(struct pci_dev *dev);
int wbsio_check_for_spi(void);
#endif
/* opaque.c */
struct opaque_programmer {
int max_data_read;
int max_data_write;
/* Specific functions for this programmer */
int (*probe) (struct flashchip *flash);
int (*read) (struct flashchip *flash, uint8_t *buf, int start, int len);
int (*write) (struct flashchip *flash, uint8_t *buf, int start, int len);
int (*erase) (struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen);
};
extern const struct opaque_programmer *opaque_programmer;
void register_opaque_programmer(const struct opaque_programmer *pgm);
/* serprog.c */
#if CONFIG_SERPROG == 1
int serprog_init(void);