|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
|
* Exercise the real jedec.c erase routines with a recording bus.
|
|
* No hardware access: the expected wire addresses follow the chip datasheets.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "flash.h"
|
|
#include "parallel.h"
|
|
#include "chipdrivers.h"
|
|
#include "log.h"
|
|
|
|
static struct { chipaddr addr; uint8_t value; } writes[8];
|
|
static unsigned int count;
|
|
|
|
void chip_writeb(const struct flashctx *flash, uint8_t value, chipaddr addr)
|
|
{
|
|
(void)flash;
|
|
if (count >= 8) abort();
|
|
writes[count].addr = addr;
|
|
writes[count++].value = value;
|
|
}
|
|
|
|
uint8_t chip_readb(const struct flashctx *flash, chipaddr addr)
|
|
{
|
|
(void)flash; (void)addr;
|
|
return 0xff; /* Ready; DQ6 does not toggle. */
|
|
}
|
|
|
|
void programmer_delay(const struct flashctx *flash, unsigned int usecs)
|
|
{
|
|
(void)flash; (void)usecs;
|
|
}
|
|
|
|
int print(enum flashrom_log_level level, const char *fmt, ...)
|
|
{
|
|
(void)level; (void)fmt;
|
|
return 0;
|
|
}
|
|
|
|
static int check(const char *name, unsigned int features, unsigned int first,
|
|
unsigned int second, unsigned int target, unsigned int expected,
|
|
unsigned int size, uint8_t command,
|
|
int (*erase)(struct flashctx *, unsigned int, unsigned int))
|
|
{
|
|
struct flashchip chip = {
|
|
.feature_bits = features, .probe_timing = TIMING_ZERO,
|
|
.total_size = 512,
|
|
};
|
|
struct flashctx flash = {.chip = &chip, .virtual_memory = 0x100000};
|
|
const unsigned int offsets[] = {first, second, first, first, second, expected};
|
|
const uint8_t values[] = {0xaa, 0x55, 0x80, 0xaa, 0x55, command};
|
|
count = 0;
|
|
if (erase(&flash, target, size) || count != 6) abort();
|
|
for (unsigned int i = 0; i < count; i++) {
|
|
if (writes[i].addr != flash.virtual_memory + offsets[i] || writes[i].value != values[i]) {
|
|
printf("FAIL %s: cycle %u address=0x%lx expected=0x%x data=0x%x\n",
|
|
name, i + 1, (unsigned long)(writes[i].addr - flash.virtual_memory),
|
|
offsets[i], writes[i].value);
|
|
return 1;
|
|
}
|
|
}
|
|
printf("PASS %s\n", name);
|
|
return 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
int failures = 0;
|
|
failures += check("PMC sector 0", 0, 0x5555, 0x2aaa, 0, 0, 4096, 0x30, erase_sector_jedec);
|
|
failures += check("PMC sector 1", 0, 0x5555, 0x2aaa, 0x1000, 0x1000, 4096, 0x30, erase_sector_jedec);
|
|
failures += check("PMC sector 5", 0, 0x5555, 0x2aaa, 0x5000, 0x5000, 4096, 0x30, erase_sector_jedec);
|
|
failures += check("PMC block 0", 0, 0x5555, 0x2aaa, 0, 0, 65536, 0x50, erase_block_jedec);
|
|
failures += check("PMC block 1", 0, 0x5555, 0x2aaa, 0x10000, 0x10000, 65536, 0x50, erase_block_jedec);
|
|
failures += check("chip erase command address", 0, 0x5555, 0x2aaa, 0, 0x5555, 524288, 0x10, erase_chip_block_jedec);
|
|
failures += check("masked sector 0", FEATURE_ADDR_2AA, 0x555, 0x2aa, 0, 0, 4096, 0x30, erase_sector_jedec);
|
|
failures += check("shifted sector 0", FEATURE_ADDR_SHIFTED, 0x2aaa, 0x5555, 0, 0, 4096, 0x30, erase_sector_jedec);
|
|
failures += check("shifted chip erase", FEATURE_ADDR_SHIFTED, 0x2aaa, 0x5555, 0, 0x2aaa, 524288, 0x10, erase_chip_block_jedec);
|
|
return failures ? 1 : 0;
|
|
}
|