mirror of
https://review.coreboot.org/flashrom.git
synced 2025-04-26 22:52:34 +02:00
tree/: Convert flashchip read func ptr to enumerate
This forges the way for flashchips.c to be pure declarative data and lookup functions for dispatch to be pure. This means that the flashchips data could be extracted out to be agnostic data of the flashrom code and algorithms. TEST='R|W|E && --flash-name' on ARM, AMD & Intel DUT's. Change-Id: I612d46fefedf2b69e7e2064aa857fa0756efb4e7 Signed-off-by: Edward O'Callaghan <quasisec@google.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/66788 Reviewed-by: Nikolai Artemiev <nartemiev@google.com> Reviewed-by: Felix Singer <felixsinger@posteo.net> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
parent
985ad5623f
commit
594d3357b6
1174
flashchips.c
1174
flashchips.c
File diff suppressed because it is too large
Load Diff
51
flashrom.c
51
flashrom.c
@ -411,6 +411,35 @@ static int check_erased_range(struct flashctx *flash, unsigned int start, unsign
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* special unit-test hook */
|
||||
read_func_t *g_test_read_injector;
|
||||
|
||||
static read_func_t *lookup_read_func_ptr(const struct flashchip *chip)
|
||||
{
|
||||
switch (chip->read) {
|
||||
case SPI_CHIP_READ: return &spi_chip_read;
|
||||
case READ_OPAQUE: return &read_opaque;
|
||||
case READ_MEMMAPPED: return &read_memmapped;
|
||||
case EDI_CHIP_READ: return &edi_chip_read;
|
||||
case SPI_READ_AT45DB: return spi_read_at45db;
|
||||
case SPI_READ_AT45DB_E8: return spi_read_at45db_e8;
|
||||
case TEST_READ_INJECTOR: return g_test_read_injector;
|
||||
/* default: total function, 0 indicates no read function set.
|
||||
* We explicitly do not want a default catch-all case in the switch
|
||||
* to ensure unhandled enum's are compiler warnings.
|
||||
*/
|
||||
case NO_READ_FUNC: return NULL;
|
||||
};
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int read_flash(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
|
||||
{
|
||||
read_func_t *read_func = lookup_read_func_ptr(flash->chip);
|
||||
return read_func(flash, buf, start, len);
|
||||
}
|
||||
|
||||
/*
|
||||
* @cmpbuf buffer to compare against, cmpbuf[0] is expected to match the
|
||||
* flash content at location start
|
||||
@ -430,7 +459,7 @@ int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int sta
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!flash->chip->read) {
|
||||
if (!lookup_read_func_ptr(flash->chip)) {
|
||||
msg_cerr("ERROR: flashrom has no read function for this flash chip.\n");
|
||||
return -1;
|
||||
}
|
||||
@ -441,7 +470,7 @@ int verify_range(struct flashctx *flash, const uint8_t *cmpbuf, unsigned int sta
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = flash->chip->read(flash, readbuf, start, len);
|
||||
int ret = read_flash(flash, readbuf, start, len);
|
||||
if (ret) {
|
||||
msg_gerr("Verification impossible because read failed "
|
||||
"at 0x%x (len 0x%x)\n", start, len);
|
||||
@ -930,7 +959,7 @@ static int read_by_layout(struct flashctx *const flashctx, uint8_t *const buffer
|
||||
const chipoff_t region_start = entry->start;
|
||||
const chipsize_t region_len = entry->end - entry->start + 1;
|
||||
|
||||
if (flashctx->chip->read(flashctx, buffer + region_start, region_start, region_len))
|
||||
if (read_flash(flashctx, buffer + region_start, region_start, region_len))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -1159,7 +1188,7 @@ static int erase_block(struct flashctx *const flashctx,
|
||||
if (info->region_start > info->erase_start) {
|
||||
const chipoff_t start = info->erase_start;
|
||||
const chipsize_t len = info->region_start - info->erase_start;
|
||||
if (flashctx->chip->read(flashctx, backup_contents, start, len)) {
|
||||
if (read_flash(flashctx, backup_contents, start, len)) {
|
||||
msg_cerr("Can't read! Aborting.\n");
|
||||
goto _free_ret;
|
||||
}
|
||||
@ -1169,7 +1198,7 @@ static int erase_block(struct flashctx *const flashctx,
|
||||
const chipoff_t start = info->region_end + 1;
|
||||
const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
|
||||
const chipsize_t len = info->erase_end - info->region_end;
|
||||
if (flashctx->chip->read(flashctx, backup_contents + rel_start, start, len)) {
|
||||
if (read_flash(flashctx, backup_contents + rel_start, start, len)) {
|
||||
msg_cerr("Can't read! Aborting.\n");
|
||||
goto _free_ret;
|
||||
}
|
||||
@ -1256,7 +1285,7 @@ static int read_erase_write_block(struct flashctx *const flashctx,
|
||||
if (info->region_start > info->erase_start) {
|
||||
const chipoff_t start = info->erase_start;
|
||||
const chipsize_t len = info->region_start - info->erase_start;
|
||||
if (flashctx->chip->read(flashctx, newc, start, len)) {
|
||||
if (read_flash(flashctx, newc, start, len)) {
|
||||
msg_cerr("Can't read! Aborting.\n");
|
||||
goto _free_ret;
|
||||
}
|
||||
@ -1267,7 +1296,7 @@ static int read_erase_write_block(struct flashctx *const flashctx,
|
||||
const chipoff_t start = info->region_end + 1;
|
||||
const chipoff_t rel_start = start - info->erase_start; /* within this erase block */
|
||||
const chipsize_t len = info->erase_end - info->region_end;
|
||||
if (flashctx->chip->read(flashctx, newc + rel_start, start, len)) {
|
||||
if (read_flash(flashctx, newc + rel_start, start, len)) {
|
||||
msg_cerr("Can't read! Aborting.\n");
|
||||
goto _free_ret;
|
||||
}
|
||||
@ -1367,7 +1396,7 @@ static int verify_by_layout(
|
||||
const chipoff_t region_start = entry->start;
|
||||
const chipsize_t region_len = entry->end - entry->start + 1;
|
||||
|
||||
if (flashctx->chip->read(flashctx, curcontents + region_start, region_start, region_len))
|
||||
if (read_flash(flashctx, curcontents + region_start, region_start, region_len))
|
||||
return 1;
|
||||
if (compare_range(newcontents + region_start, curcontents + region_start,
|
||||
region_start, region_len))
|
||||
@ -1554,7 +1583,7 @@ static int chip_safety_check(const struct flashctx *flash, int force,
|
||||
return 1;
|
||||
msg_cerr("Continuing anyway.\n");
|
||||
}
|
||||
if (!chip->read) {
|
||||
if (!lookup_read_func_ptr(chip)) {
|
||||
msg_cerr("flashrom has no read function for this "
|
||||
"flash chip.\n");
|
||||
return 1;
|
||||
@ -1775,7 +1804,7 @@ int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, co
|
||||
*/
|
||||
msg_cinfo("Reading old flash chip contents... ");
|
||||
if (verify_all) {
|
||||
if (flashctx->chip->read(flashctx, oldcontents, 0, flash_size)) {
|
||||
if (read_flash(flashctx, oldcontents, 0, flash_size)) {
|
||||
msg_cinfo("FAILED.\n");
|
||||
goto _finalize_ret;
|
||||
}
|
||||
@ -1795,7 +1824,7 @@ int flashrom_image_write(struct flashctx *const flashctx, void *const buffer, co
|
||||
if (verify_all) {
|
||||
msg_cerr("Checking if anything has changed.\n");
|
||||
msg_cinfo("Reading current flash chip contents... ");
|
||||
if (!flashctx->chip->read(flashctx, curcontents, 0, flash_size)) {
|
||||
if (!read_flash(flashctx, curcontents, 0, flash_size)) {
|
||||
msg_cinfo("done.\n");
|
||||
if (!memcmp(oldcontents, curcontents, flash_size)) {
|
||||
nonfatal_help_message();
|
||||
|
8
fmap.c
8
fmap.c
@ -167,7 +167,7 @@ static int fmap_lsearch_rom(struct fmap **fmap_out,
|
||||
goto _finalize_ret;
|
||||
}
|
||||
|
||||
ret = flashctx->chip->read(flashctx, buf + rom_offset, rom_offset, len);
|
||||
ret = read_flash(flashctx, buf + rom_offset, rom_offset, len);
|
||||
if (ret) {
|
||||
msg_pdbg("Cannot read ROM contents.\n");
|
||||
goto _free_ret;
|
||||
@ -232,7 +232,7 @@ static int fmap_bsearch_rom(struct fmap **fmap_out, struct flashctx *const flash
|
||||
|
||||
/* Read errors are considered non-fatal since we may
|
||||
* encounter locked regions and want to continue. */
|
||||
if (flashctx->chip->read(flashctx, (uint8_t *)fmap, offset, sig_len)) {
|
||||
if (read_flash(flashctx, (uint8_t *)fmap, offset, sig_len)) {
|
||||
/*
|
||||
* Print in verbose mode only to avoid excessive
|
||||
* messages for benign errors. Subsequent error
|
||||
@ -245,7 +245,7 @@ static int fmap_bsearch_rom(struct fmap **fmap_out, struct flashctx *const flash
|
||||
if (memcmp(fmap, FMAP_SIGNATURE, sig_len) != 0)
|
||||
continue;
|
||||
|
||||
if (flashctx->chip->read(flashctx, (uint8_t *)fmap + sig_len,
|
||||
if (read_flash(flashctx, (uint8_t *)fmap + sig_len,
|
||||
offset + sig_len, sizeof(*fmap) - sig_len)) {
|
||||
msg_cerr("Cannot read %zu bytes at offset %06zx\n",
|
||||
sizeof(*fmap) - sig_len, offset + sig_len);
|
||||
@ -277,7 +277,7 @@ static int fmap_bsearch_rom(struct fmap **fmap_out, struct flashctx *const flash
|
||||
goto _free_ret;
|
||||
}
|
||||
|
||||
if (flashctx->chip->read(flashctx, (uint8_t *)fmap + sizeof(*fmap),
|
||||
if (read_flash(flashctx, (uint8_t *)fmap + sizeof(*fmap),
|
||||
offset + sizeof(*fmap), fmap_len - sizeof(*fmap))) {
|
||||
msg_cerr("Cannot read %zu bytes at offset %06zx\n",
|
||||
fmap_len - sizeof(*fmap), offset + sizeof(*fmap));
|
||||
|
@ -255,6 +255,19 @@ enum write_func {
|
||||
};
|
||||
typedef int (write_func_t)(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len);
|
||||
|
||||
enum read_func {
|
||||
NO_READ_FUNC = 0, /* 0 indicates no read function set. */
|
||||
SPI_CHIP_READ = 1,
|
||||
READ_OPAQUE,
|
||||
READ_MEMMAPPED,
|
||||
EDI_CHIP_READ,
|
||||
SPI_READ_AT45DB,
|
||||
SPI_READ_AT45DB_E8,
|
||||
TEST_READ_INJECTOR, /* special case must come last. */
|
||||
};
|
||||
typedef int (read_func_t)(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
|
||||
int read_flash(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
|
||||
|
||||
struct flashchip {
|
||||
const char *vendor;
|
||||
const char *name;
|
||||
@ -323,7 +336,7 @@ struct flashchip {
|
||||
int (*printlock) (struct flashctx *flash);
|
||||
int (*unlock) (struct flashctx *flash);
|
||||
enum write_func write;
|
||||
int (*read) (struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len);
|
||||
enum read_func read;
|
||||
struct voltage {
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
|
@ -299,7 +299,7 @@ int flashrom_layout_read_from_ifd(struct flashrom_layout **const layout, struct
|
||||
goto _free_ret;
|
||||
|
||||
msg_cinfo("Reading ich descriptor... ");
|
||||
if (flashctx->chip->read(flashctx, desc, 0, 0x1000)) {
|
||||
if (read_flash(flashctx, desc, 0, 0x1000)) {
|
||||
msg_cerr("Read operation failed!\n");
|
||||
msg_cinfo("FAILED.\n");
|
||||
ret = 2;
|
||||
|
@ -147,12 +147,13 @@ static void teardown(struct flashrom_layout **layout)
|
||||
}
|
||||
|
||||
extern write_func_t *g_test_write_injector;
|
||||
extern read_func_t *g_test_read_injector;
|
||||
|
||||
static const struct flashchip chip_8MiB = {
|
||||
.vendor = "aklm",
|
||||
.total_size = MOCK_CHIP_SIZE / KiB,
|
||||
.tested = TEST_OK_PREW,
|
||||
.read = read_chip,
|
||||
.read = TEST_READ_INJECTOR,
|
||||
.write = TEST_WRITE_INJECTOR,
|
||||
.unlock = unlock_chip,
|
||||
.block_erasers =
|
||||
@ -168,7 +169,7 @@ static const struct flashchip chip_W25Q128_V = {
|
||||
.vendor = "aklm&dummyflasher",
|
||||
.total_size = 16 * 1024,
|
||||
.tested = TEST_OK_PREW,
|
||||
.read = spi_chip_read,
|
||||
.read = SPI_CHIP_READ,
|
||||
.write = SPI_CHIP_WRITE256,
|
||||
.unlock = spi_disable_blockprotect,
|
||||
.page_size = 256,
|
||||
@ -206,6 +207,7 @@ void erase_chip_test_success(void **state)
|
||||
};
|
||||
|
||||
g_test_write_injector = write_chip;
|
||||
g_test_read_injector = read_chip;
|
||||
struct flashrom_flashctx flashctx = { 0 };
|
||||
struct flashrom_layout *layout;
|
||||
struct flashchip mock_chip = chip_8MiB;
|
||||
@ -265,6 +267,7 @@ void read_chip_test_success(void **state)
|
||||
};
|
||||
|
||||
g_test_write_injector = write_chip;
|
||||
g_test_read_injector = read_chip;
|
||||
struct flashrom_flashctx flashctx = { 0 };
|
||||
struct flashrom_layout *layout;
|
||||
struct flashchip mock_chip = chip_8MiB;
|
||||
@ -337,6 +340,7 @@ void write_chip_test_success(void **state)
|
||||
};
|
||||
|
||||
g_test_write_injector = write_chip;
|
||||
g_test_read_injector = read_chip;
|
||||
struct flashrom_flashctx flashctx = { 0 };
|
||||
struct flashrom_layout *layout;
|
||||
struct flashchip mock_chip = chip_8MiB;
|
||||
@ -435,6 +439,7 @@ void verify_chip_test_success(void **state)
|
||||
};
|
||||
|
||||
g_test_write_injector = write_chip;
|
||||
g_test_read_injector = read_chip;
|
||||
struct flashrom_flashctx flashctx = { 0 };
|
||||
struct flashrom_layout *layout;
|
||||
struct flashchip mock_chip = chip_8MiB;
|
||||
|
@ -64,7 +64,7 @@ static const struct flashchip chip_W25Q128_V = {
|
||||
.vendor = "aklm&dummyflasher",
|
||||
.total_size = 16 * 1024,
|
||||
.tested = TEST_OK_PREW,
|
||||
.read = spi_chip_read,
|
||||
.read = SPI_CHIP_READ,
|
||||
.write = SPI_CHIP_WRITE256,
|
||||
.unlock = spi_disable_blockprotect,
|
||||
.feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_WRSR_EXT2 | FEATURE_WRSR2 | FEATURE_WRSR3,
|
||||
|
Loading…
x
Reference in New Issue
Block a user