Nikolai Artemiev has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/69195 )
Change subject: ichspi.c: read chip ID and use it to identify chip ......................................................................
ichspi.c: read chip ID and use it to identify chip
BUG=b:253715389,b:253713774 BRANCH=none TEST=builds
Change-Id: Ia408e1e45dc6f53c0934afd6558e301abfa48ee6 Signed-off-by: Nikolai Artemiev nartemiev@google.com --- M ichspi.c 1 file changed, 80 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/95/69195/1
diff --git a/ichspi.c b/ichspi.c index 6d3535c..22fe7cd 100644 --- a/ichspi.c +++ b/ichspi.c @@ -132,6 +132,7 @@ #define HSFC_CYCLE_READ HSFC_FCYCLE_MASK(0) #define HSFC_CYCLE_WRITE HSFC_FCYCLE_MASK(2) #define HSFC_CYCLE_BLOCK_ERASE HSFC_FCYCLE_MASK(3) +#define HSFC_CYCLE_RDID HSFC_FCYCLE_MASK(6) #define HSFC_CYCLE_WR_STATUS HSFC_FCYCLE_MASK(7) #define HSFC_CYCLE_RD_STATUS HSFC_FCYCLE_MASK(8) /* 3-7: reserved */ @@ -1388,6 +1389,19 @@ return ich_hwseq_wait_for_cycle_complete(len, ich_gen, addr_mask); }
+/* Given RDID info, return pointer to entry in flashchips[] */ +static const struct flashchip *flash_id_to_entry(uint32_t mfg_id, uint32_t model_id) +{ + const struct flashchip *chip; + + for (chip = &flashchips[0]; chip->vendor; chip++) { + if ((chip->manufacture_id == mfg_id) && (chip->model_id == model_id)) + return chip; + } + + return NULL; +} + static int ich_hwseq_read_status(const struct flashctx *flash, enum flash_reg reg, uint8_t *value) { const int len = 1; @@ -1431,6 +1445,53 @@ return 0; }
+static int ich_hwseq_get_flash_id(struct flashctx *flash, enum ich_chipset ich_gen) +{ + uint32_t data, mfg_id, model_id; + const struct flashchip *entry; + const int len = sizeof(data); + const struct hwseq_data *hwseq_data = get_hwseq_data_from_context(flash); + + if (ich_exec_sync_hwseq_xfer(HSFC_CYCLE_RDID, 0, len, ich_generation, + hwseq_data->addr_mask)) { + msg_perr("Timed out waiting for RDID to complete.\n"); + return 0; + } + + /* + * Data will appear in reverse order: + * Byte 0: Manufacturer ID + * Byte 1: Model ID (MSB) + * Byte 2: Model ID (LSB) + */ + ich_read_data((uint8_t *)&data, len, ICH9_REG_FDATA0); + mfg_id = data & 0xff; + model_id = (data & 0xff00) | ((data >> 16) & 0xff); + + entry = flash_id_to_entry(mfg_id, model_id); + if (entry == NULL) { + msg_perr("Unable to identify chip, mfg_id: 0x%02x, " + "model_id: 0x%02x\n", mfg_id, model_id); + return 0; + } else { + msg_pdbg("Chip identified: %s\n", entry->name); + /* Update informational flash chip entries only */ + flash->chip->vendor = entry->vendor; + flash->chip->name = entry->name; + flash->chip->manufacture_id = entry->manufacture_id; + flash->chip->model_id = entry->model_id; + /* total_size read from flash descriptor */ + flash->chip->page_size = entry->page_size; + flash->chip->feature_bits = entry->feature_bits; + flash->chip->tested = entry->tested; + /* support writeprotect. */ + flash->chip->reg_bits = entry->reg_bits; + flash->chip->decode_range = entry->decode_range; + } + + return 1; +} + static int ich_hwseq_probe(struct flashctx *flash) { uint32_t total_size, boundary; @@ -1438,6 +1499,11 @@ struct block_eraser *eraser; const struct hwseq_data *hwseq_data = get_hwseq_data_from_context(flash);
+ if (ich_hwseq_get_flash_id(flash, ich_generation) != 1) { + msg_perr("Unable to read flash chip ID\n"); + return 0; + } + total_size = hwseq_data->size_comp0 + hwseq_data->size_comp1; msg_cdbg("Hardware sequencing reports %d attached SPI flash chip", (hwseq_data->size_comp1 != 0) ? 2 : 1);