Patrick Georgi has submitted this change. ( https://review.coreboot.org/c/em100/+/35947 )
Change subject: em100: Detect emulated flash chip ......................................................................
em100: Detect emulated flash chip
It's not clear why uploads (EM100 to host) generate a 64MiB ROM file. It turns out that the flash chip needs to be specified at the command line, which isn't intentional.
Detect the currently emulated SPI and use the size as defined in flashchips.
Tested on EM100Pro, will now upload ROM files matching the currently emulated target even without specifying the flash chip on the command line.
Signed-off-by: Patrick Rudolph patrick.rudolph@9elements.com Change-Id: Ia3fb3034a195313b8d3bb4ce24dc1779058fd08f Reviewed-on: https://review.coreboot.org/c/em100/+/35947 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Stefan Reinauer stefan.reinauer@coreboot.org Reviewed-by: Simon Glass sjg@chromium.org Reviewed-by: Patrick Georgi pgeorgi@google.com --- M em100.c M em100.h 2 files changed, 82 insertions(+), 2 deletions(-)
Approvals: build bot (Jenkins): Verified Patrick Georgi: Looks good to me, approved Stefan Reinauer: Looks good to me, approved Simon Glass: Looks good to me, but someone else must approve
diff --git a/em100.c b/em100.c index 215b233..3d0de42 100644 --- a/em100.c +++ b/em100.c @@ -567,6 +567,70 @@ return !result; }
+/** + * Searches for a specific FPGA register in the chip initialisation + * sequence and returns the value in out. + * + * @reg1: e.g. FPGA write command (0x23) + * @reg2: e.g. FPGA register + * + * Returns 0 on success. + */ +static int get_chip_init_val(const chipdesc *desc, + const uint8_t reg1, + const uint8_t reg2, + uint16_t *out) +{ + int i; + + for (i = 0; i < desc->init_len; i++) { + if (desc->init[i][0] == reg1 && desc->init[i][1] == reg2) { + *out = (desc->init[i][2] << 8) | desc->init[i][3]; + return 0; + } + } + + return 1; +} + +/** + * Tries to identify the currently emulated SPI flash by looking at + * known registers in the FPGA and matches those bits with the + * chip initialisation sequence. + * + * Returns 0 on success. + */ +static int get_chip_type(struct em100 *em100, const chipdesc **out) +{ + const chipdesc *chip; + uint16_t venid; + uint16_t devid; + + /* Read manufacturer and vendor id from FPGA */ + if (!read_fpga_register(em100, FPGA_REG_VENDID, &venid)) + return 1; + if (!read_fpga_register(em100, FPGA_REG_DEVID, &devid)) + return 1; + + for (chip = chips; chip != NULL; chip++) { + uint16_t comp; + + if (get_chip_init_val(chip, 0x23, FPGA_REG_DEVID, &comp) || devid != comp) + continue; + if (get_chip_init_val(chip, 0x23, FPGA_REG_VENDID, &comp) || venid != comp) + continue; + + break; + } + + if (!chip) + return 1; + + *out = chip; + + return 0; +} + static const struct option longopts[] = { {"set", 1, 0, 'c'}, {"download", 1, 0, 'd'}, @@ -822,8 +886,20 @@ }
if (read_filename) { - /* largest size - 64MB */ - int maxlen = desiredchip ? chip->size : 0x4000000; + int maxlen = 0x4000000; /* largest size - 64MB */ + + if (!desiredchip) { + /* Read configured SPI emulation from EM100 */ + const chipdesc *emulated_chip; + + if (!get_chip_type(&em100, &emulated_chip)) { + printf("Configured to emulate %s\n", emulated_chip->name); + maxlen = emulated_chip->size; + } + } else { + maxlen = chip->size; + } + void *data = malloc(maxlen); if (data == NULL) { printf("FATAL: couldn't allocate memory\n"); diff --git a/em100.h b/em100.h index 6a58e70..a903baa 100644 --- a/em100.h +++ b/em100.h @@ -48,6 +48,10 @@ int fpga_get_voltage(struct em100 *em100, int *voltage_codep); int fpga_reconfigure(struct em100 *em100);
+/* Guessed register names */ +#define FPGA_REG_DEVID 0x40 +#define FPGA_REG_VENDID 0x42 + /* hexdump.c */ void hexdump(const void *memory, size_t length);