Project

General

Profile

Bug #671 » test_jedec_address.c

Gianluigi Tiesi, 11/06/2026 08:00 PM

 
/* 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;
}
(2-2/7)