ichspi: Split ICH7 init out
The original, ICH7 init only shared about three lines with the newer,
ever growing ICH9+ init. That's not worth an indentation level in an
endlessly long function, so split it out.
We introduce a kind of "breakpoint" into the `ich_chipset' enum:
SPI_ENGINE_ICH9
This marks all chipset entries below it as supporting this code path
and should help to avoid long `case' lists.
Tested read/erase/write on ThinkPad T60 (ICH7).
Change-Id: I41e46d12e02c1343e636b47b2378db86e76af95e
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/173
Reviewed-by: Arthur Heymans <arthur@aheymans.xyz>
diff --git a/ichspi.c b/ichspi.c
index 65c357d..617eba9 100644
--- a/ichspi.c
+++ b/ichspi.c
@@ -1710,6 +1710,41 @@
.probe_opcode = ich_spi_probe_opcode,
};
+int ich7_init_spi(void *spibar, enum ich_chipset ich_gen)
+{
+ unsigned int i;
+
+ ich_generation = ich_gen;
+ ich_spibar = spibar;
+
+ msg_pdbg("0x00: 0x%04x (SPIS)\n", mmio_readw(ich_spibar + 0));
+ msg_pdbg("0x02: 0x%04x (SPIC)\n", mmio_readw(ich_spibar + 2));
+ msg_pdbg("0x04: 0x%08x (SPIA)\n", mmio_readl(ich_spibar + 4));
+
+ ichspi_bbar = mmio_readl(ich_spibar + 0x50);
+ msg_pdbg("0x50: 0x%08x (BBAR)\n", ichspi_bbar);
+ msg_pdbg("0x54: 0x%04x (PREOP)\n", mmio_readw(ich_spibar + 0x54));
+ msg_pdbg("0x56: 0x%04x (OPTYPE)\n", mmio_readw(ich_spibar + 0x56));
+ msg_pdbg("0x58: 0x%08x (OPMENU)\n", mmio_readl(ich_spibar + 0x58));
+ msg_pdbg("0x5c: 0x%08x (OPMENU+4)\n", mmio_readl(ich_spibar + 0x5c));
+
+ for (i = 0; i < 3; i++) {
+ const int offs = 0x60 + (i * 4);
+ msg_pdbg("0x%02x: 0x%08x (PBR%u)\n", offs,
+ mmio_readl(ich_spibar + offs), i);
+ }
+
+ if (mmio_readw(ich_spibar) & (1 << 15)) {
+ msg_pwarn("WARNING: SPI Configuration Lockdown activated.\n");
+ ichspi_lock = true;
+ }
+
+ ich_init_opcodes();
+ ich_set_bbar(0);
+
+ return register_spi_master(&spi_master_ich7, 0, NULL);
+}
+
static const struct spi_master spi_master_ich9 = {
.max_data_read = 64,
.max_data_write = 64,
@@ -1729,7 +1764,7 @@
.erase = ich_hwseq_block_erase,
};
-int ich_init_spi(void *spibar, enum ich_chipset ich_gen)
+int ich9_init_spi(void *spibar, enum ich_chipset ich_gen)
{
unsigned int i;
uint16_t tmp2;
@@ -1798,90 +1833,130 @@
break;
}
- switch (ich_generation) {
- case CHIPSET_ICH7:
- case CHIPSET_TUNNEL_CREEK:
- case CHIPSET_CENTERTON:
- msg_pdbg("0x00: 0x%04x (SPIS)\n",
- mmio_readw(ich_spibar + 0));
- msg_pdbg("0x02: 0x%04x (SPIC)\n",
- mmio_readw(ich_spibar + 2));
- msg_pdbg("0x04: 0x%08x (SPIA)\n",
- mmio_readl(ich_spibar + 4));
- ichspi_bbar = mmio_readl(ich_spibar + 0x50);
- msg_pdbg("0x50: 0x%08x (BBAR)\n",
- ichspi_bbar);
- msg_pdbg("0x54: 0x%04x (PREOP)\n",
- mmio_readw(ich_spibar + 0x54));
- msg_pdbg("0x56: 0x%04x (OPTYPE)\n",
- mmio_readw(ich_spibar + 0x56));
- msg_pdbg("0x58: 0x%08x (OPMENU)\n",
- mmio_readl(ich_spibar + 0x58));
- msg_pdbg("0x5c: 0x%08x (OPMENU+4)\n",
- mmio_readl(ich_spibar + 0x5c));
- for (i = 0; i < 3; i++) {
- int offs;
- offs = 0x60 + (i * 4);
- msg_pdbg("0x%02x: 0x%08x (PBR%u)\n", offs,
- mmio_readl(ich_spibar + offs), i);
- }
- if (mmio_readw(ich_spibar) & (1 << 15)) {
- msg_pwarn("WARNING: SPI Configuration Lockdown activated.\n");
- ichspi_lock = true;
- }
- ich_init_opcodes();
- ich_set_bbar(0);
- register_spi_master(&spi_master_ich7, 0, NULL);
- break;
- case CHIPSET_ICH8:
- default: /* Future version might behave the same */
- arg = extract_programmer_param("ich_spi_mode");
- if (arg && !strcmp(arg, "hwseq")) {
- ich_spi_mode = ich_hwseq;
- msg_pspew("user selected hwseq\n");
- } else if (arg && !strcmp(arg, "swseq")) {
- ich_spi_mode = ich_swseq;
- msg_pspew("user selected swseq\n");
- } else if (arg && !strcmp(arg, "auto")) {
- msg_pspew("user selected auto\n");
- ich_spi_mode = ich_auto;
- } else if (arg && !strlen(arg)) {
- msg_perr("Missing argument for ich_spi_mode.\n");
- free(arg);
- return ERROR_FATAL;
- } else if (arg) {
- msg_perr("Unknown argument for ich_spi_mode: %s\n",
- arg);
- free(arg);
- return ERROR_FATAL;
- }
+ arg = extract_programmer_param("ich_spi_mode");
+ if (arg && !strcmp(arg, "hwseq")) {
+ ich_spi_mode = ich_hwseq;
+ msg_pspew("user selected hwseq\n");
+ } else if (arg && !strcmp(arg, "swseq")) {
+ ich_spi_mode = ich_swseq;
+ msg_pspew("user selected swseq\n");
+ } else if (arg && !strcmp(arg, "auto")) {
+ msg_pspew("user selected auto\n");
+ ich_spi_mode = ich_auto;
+ } else if (arg && !strlen(arg)) {
+ msg_perr("Missing argument for ich_spi_mode.\n");
free(arg);
+ return ERROR_FATAL;
+ } else if (arg) {
+ msg_perr("Unknown argument for ich_spi_mode: %s\n",
+ arg);
+ free(arg);
+ return ERROR_FATAL;
+ }
+ free(arg);
- tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFS);
- msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2);
- prettyprint_ich9_reg_hsfs(tmp2);
- if (tmp2 & HSFS_FLOCKDN) {
- msg_pinfo("SPI Configuration is locked down.\n");
- ichspi_lock = true;
- }
- if (tmp2 & HSFS_FDV)
- desc_valid = true;
- if (!(tmp2 & HSFS_FDOPSS) && desc_valid)
- msg_pinfo("The Flash Descriptor Override Strap-Pin is set. Restrictions implied by\n"
- "the Master Section of the flash descriptor are NOT in effect. Please note\n"
- "that Protected Range (PR) restrictions still apply.\n");
- ich_init_opcodes();
+ tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFS);
+ msg_pdbg("0x04: 0x%04x (HSFS)\n", tmp2);
+ prettyprint_ich9_reg_hsfs(tmp2);
+ if (tmp2 & HSFS_FLOCKDN) {
+ msg_pinfo("SPI Configuration is locked down.\n");
+ ichspi_lock = true;
+ }
+ if (tmp2 & HSFS_FDV)
+ desc_valid = true;
+ if (!(tmp2 & HSFS_FDOPSS) && desc_valid)
+ msg_pinfo("The Flash Descriptor Override Strap-Pin is set. Restrictions implied by\n"
+ "the Master Section of the flash descriptor are NOT in effect. Please note\n"
+ "that Protected Range (PR) restrictions still apply.\n");
+ ich_init_opcodes();
- if (desc_valid) {
- tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFC);
- msg_pdbg("0x06: 0x%04x (HSFC)\n", tmp2);
- prettyprint_ich9_reg_hsfc(tmp2);
- }
+ if (desc_valid) {
+ tmp2 = mmio_readw(ich_spibar + ICH9_REG_HSFC);
+ msg_pdbg("0x06: 0x%04x (HSFC)\n", tmp2);
+ prettyprint_ich9_reg_hsfc(tmp2);
+ }
- tmp = mmio_readl(ich_spibar + ICH9_REG_FADDR);
- msg_pdbg2("0x08: 0x%08x (FADDR)\n", tmp);
+ tmp = mmio_readl(ich_spibar + ICH9_REG_FADDR);
+ msg_pdbg2("0x08: 0x%08x (FADDR)\n", tmp);
+ switch (ich_gen) {
+ case CHIPSET_100_SERIES_SUNRISE_POINT:
+ case CHIPSET_C620_SERIES_LEWISBURG:
+ case CHIPSET_300_SERIES_CANNON_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
+ tmp = mmio_readl(ich_spibar + PCH100_REG_DLOCK);
+ msg_pdbg("0x0c: 0x%08x (DLOCK)\n", tmp);
+ prettyprint_pch100_reg_dlock(tmp);
+ break;
+ default:
+ break;
+ }
+
+ if (desc_valid) {
+ tmp = mmio_readl(ich_spibar + ICH9_REG_FRAP);
+ msg_pdbg("0x50: 0x%08x (FRAP)\n", tmp);
+ msg_pdbg("BMWAG 0x%02x, ", ICH_BMWAG(tmp));
+ msg_pdbg("BMRAG 0x%02x, ", ICH_BMRAG(tmp));
+ msg_pdbg("BRWA 0x%02x, ", ICH_BRWA(tmp));
+ msg_pdbg("BRRA 0x%02x\n", ICH_BRRA(tmp));
+
+ /* Handle FREGx and FRAP registers */
+ for (i = 0; i < num_freg; i++)
+ ich_spi_rw_restricted |= ich9_handle_frap(tmp, i);
+ if (ich_spi_rw_restricted)
+ msg_pinfo("Not all flash regions are freely accessible by flashprog. This is "
+ "most likely\ndue to an active ME. Please see "
+ "https://flashprog.org/ME for details.\n");
+ }
+
+ /* Handle PR registers */
+ for (i = 0; i < num_pr; i++) {
+ /* if not locked down try to disable PR locks first */
+ if (!ichspi_lock)
+ ich9_set_pr(reg_pr0, i, 0, 0);
+ ich_spi_rw_restricted |= ich9_handle_pr(reg_pr0, i);
+ }
+
+ switch (ich_spi_rw_restricted) {
+ case WRITE_PROT:
+ msg_pwarn("At least some flash regions are write protected. For write operations,\n"
+ "you should use a flash layout and include only writable regions. See\n"
+ "manpage for more details.\n");
+ break;
+ case READ_PROT:
+ case LOCKED:
+ msg_pwarn("At least some flash regions are read protected. You have to use a flash\n"
+ "layout and include only accessible regions. For write operations, you'll\n"
+ "additionally need the --noverify-all switch. See manpage for more details.\n"
+ );
+ break;
+ }
+
+ tmp = mmio_readl(ich_spibar + swseq_data.reg_ssfsc);
+ msg_pdbg("0x%zx: 0x%02x (SSFS)\n", swseq_data.reg_ssfsc, tmp & 0xff);
+ prettyprint_ich9_reg_ssfs(tmp);
+ if (tmp & SSFS_FCERR) {
+ msg_pdbg("Clearing SSFS.FCERR\n");
+ mmio_writeb(SSFS_FCERR, ich_spibar + swseq_data.reg_ssfsc);
+ }
+ msg_pdbg("0x%zx: 0x%06x (SSFC)\n", swseq_data.reg_ssfsc + 1, tmp >> 8);
+ prettyprint_ich9_reg_ssfc(tmp);
+
+ msg_pdbg("0x%zx: 0x%04x (PREOP)\n",
+ swseq_data.reg_preop, mmio_readw(ich_spibar + swseq_data.reg_preop));
+ msg_pdbg("0x%zx: 0x%04x (OPTYPE)\n",
+ swseq_data.reg_optype, mmio_readw(ich_spibar + swseq_data.reg_optype));
+ msg_pdbg("0x%zx: 0x%08x (OPMENU)\n",
+ swseq_data.reg_opmenu, mmio_readl(ich_spibar + swseq_data.reg_opmenu));
+ msg_pdbg("0x%zx: 0x%08x (OPMENU+4)\n",
+ swseq_data.reg_opmenu + 4, mmio_readl(ich_spibar + swseq_data.reg_opmenu + 4));
+
+ if (desc_valid) {
switch (ich_gen) {
+ case CHIPSET_ICH8:
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
@@ -1889,189 +1964,110 @@
case CHIPSET_APOLLO_LAKE:
case CHIPSET_GEMINI_LAKE:
case CHIPSET_ELKHART_LAKE:
- tmp = mmio_readl(ich_spibar + PCH100_REG_DLOCK);
- msg_pdbg("0x0c: 0x%08x (DLOCK)\n", tmp);
- prettyprint_pch100_reg_dlock(tmp);
+ case CHIPSET_BAYTRAIL:
break;
default:
+ ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR);
+ msg_pdbg("0x%x: 0x%08x (BBAR)\n", ICH9_REG_BBAR, ichspi_bbar);
+ ich_set_bbar(0);
break;
}
- if (desc_valid) {
- tmp = mmio_readl(ich_spibar + ICH9_REG_FRAP);
- msg_pdbg("0x50: 0x%08x (FRAP)\n", tmp);
- msg_pdbg("BMWAG 0x%02x, ", ICH_BMWAG(tmp));
- msg_pdbg("BMRAG 0x%02x, ", ICH_BMRAG(tmp));
- msg_pdbg("BRWA 0x%02x, ", ICH_BRWA(tmp));
- msg_pdbg("BRRA 0x%02x\n", ICH_BRRA(tmp));
-
- /* Handle FREGx and FRAP registers */
- for (i = 0; i < num_freg; i++)
- ich_spi_rw_restricted |= ich9_handle_frap(tmp, i);
- if (ich_spi_rw_restricted)
- msg_pinfo("Not all flash regions are freely accessible by flashprog. This is "
- "most likely\ndue to an active ME. Please see "
- "https://flashprog.org/ME for details.\n");
- }
-
- /* Handle PR registers */
- for (i = 0; i < num_pr; i++) {
- /* if not locked down try to disable PR locks first */
- if (!ichspi_lock)
- ich9_set_pr(reg_pr0, i, 0, 0);
- ich_spi_rw_restricted |= ich9_handle_pr(reg_pr0, i);
- }
-
- switch (ich_spi_rw_restricted) {
- case WRITE_PROT:
- msg_pwarn("At least some flash regions are write protected. For write operations,\n"
- "you should use a flash layout and include only writable regions. See\n"
- "manpage for more details.\n");
- break;
- case READ_PROT:
- case LOCKED:
- msg_pwarn("At least some flash regions are read protected. You have to use a flash\n"
- "layout and include only accessible regions. For write operations, you'll\n"
- "additionally need the --noverify-all switch. See manpage for more details.\n"
- );
- break;
- }
-
- tmp = mmio_readl(ich_spibar + swseq_data.reg_ssfsc);
- msg_pdbg("0x%zx: 0x%02x (SSFS)\n", swseq_data.reg_ssfsc, tmp & 0xff);
- prettyprint_ich9_reg_ssfs(tmp);
- if (tmp & SSFS_FCERR) {
- msg_pdbg("Clearing SSFS.FCERR\n");
- mmio_writeb(SSFS_FCERR, ich_spibar + swseq_data.reg_ssfsc);
- }
- msg_pdbg("0x%zx: 0x%06x (SSFC)\n", swseq_data.reg_ssfsc + 1, tmp >> 8);
- prettyprint_ich9_reg_ssfc(tmp);
-
- msg_pdbg("0x%zx: 0x%04x (PREOP)\n",
- swseq_data.reg_preop, mmio_readw(ich_spibar + swseq_data.reg_preop));
- msg_pdbg("0x%zx: 0x%04x (OPTYPE)\n",
- swseq_data.reg_optype, mmio_readw(ich_spibar + swseq_data.reg_optype));
- msg_pdbg("0x%zx: 0x%08x (OPMENU)\n",
- swseq_data.reg_opmenu, mmio_readl(ich_spibar + swseq_data.reg_opmenu));
- msg_pdbg("0x%zx: 0x%08x (OPMENU+4)\n",
- swseq_data.reg_opmenu + 4, mmio_readl(ich_spibar + swseq_data.reg_opmenu + 4));
-
- if (desc_valid) {
- switch (ich_gen) {
- case CHIPSET_ICH8:
- case CHIPSET_100_SERIES_SUNRISE_POINT:
- case CHIPSET_C620_SERIES_LEWISBURG:
- case CHIPSET_300_SERIES_CANNON_POINT:
- case CHIPSET_500_SERIES_TIGER_POINT:
- case CHIPSET_APOLLO_LAKE:
- case CHIPSET_GEMINI_LAKE:
- case CHIPSET_ELKHART_LAKE:
- case CHIPSET_BAYTRAIL:
- break;
- default:
- ichspi_bbar = mmio_readl(ich_spibar + ICH9_REG_BBAR);
- msg_pdbg("0x%x: 0x%08x (BBAR)\n", ICH9_REG_BBAR, ichspi_bbar);
- ich_set_bbar(0);
- break;
- }
-
- if (ich_gen == CHIPSET_ICH8) {
- tmp = mmio_readl(ich_spibar + ICH8_REG_VSCC);
- msg_pdbg("0x%x: 0x%08x (VSCC)\n", ICH8_REG_VSCC, tmp);
- msg_pdbg("VSCC: ");
- prettyprint_ich_reg_vscc(tmp, FLASHPROG_MSG_DEBUG, true);
- } else {
- tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC);
- msg_pdbg("0x%x: 0x%08x (LVSCC)\n", ICH9_REG_LVSCC, tmp);
- msg_pdbg("LVSCC: ");
- prettyprint_ich_reg_vscc(tmp, FLASHPROG_MSG_DEBUG, true);
-
- tmp = mmio_readl(ich_spibar + ICH9_REG_UVSCC);
- msg_pdbg("0x%x: 0x%08x (UVSCC)\n", ICH9_REG_UVSCC, tmp);
- msg_pdbg("UVSCC: ");
- prettyprint_ich_reg_vscc(tmp, FLASHPROG_MSG_DEBUG, false);
- }
-
- switch (ich_gen) {
- case CHIPSET_ICH8:
- case CHIPSET_100_SERIES_SUNRISE_POINT:
- case CHIPSET_C620_SERIES_LEWISBURG:
- case CHIPSET_300_SERIES_CANNON_POINT:
- case CHIPSET_500_SERIES_TIGER_POINT:
- case CHIPSET_APOLLO_LAKE:
- case CHIPSET_GEMINI_LAKE:
- case CHIPSET_ELKHART_LAKE:
- break;
- default:
- tmp = mmio_readl(ich_spibar + ICH9_REG_FPB);
- msg_pdbg("0x%x: 0x%08x (FPB)\n", ICH9_REG_FPB, tmp);
- break;
- }
-
- if (read_ich_descriptors_via_fdo(ich_gen, ich_spibar, &desc) == ICH_RET_OK)
- prettyprint_ich_descriptors(ich_gen, &desc);
-
- /* If the descriptor is valid and indicates multiple
- * flash devices we need to use hwseq to be able to
- * access the second flash device.
- */
- if (ich_spi_mode == ich_auto && desc.content.NC != 0) {
- msg_pinfo("Enabling hardware sequencing due to "
- "multiple flash chips detected.\n");
- ich_spi_mode = ich_hwseq;
- }
- }
-
- if (ich_spi_mode == ich_auto && ichspi_lock &&
- ich_missing_opcodes()) {
- msg_pinfo("Enabling hardware sequencing because "
- "some important opcode is locked.\n");
- ich_spi_mode = ich_hwseq;
- }
-
- if (ich_spi_mode == ich_auto &&
- (ich_gen == CHIPSET_100_SERIES_SUNRISE_POINT ||
- ich_gen == CHIPSET_300_SERIES_CANNON_POINT ||
- ich_gen == CHIPSET_500_SERIES_TIGER_POINT)) {
- msg_pdbg("Enabling hardware sequencing by default for 100+ series PCH.\n");
- ich_spi_mode = ich_hwseq;
- }
-
- if (ich_spi_mode == ich_auto &&
- (ich_gen == CHIPSET_APOLLO_LAKE ||
- ich_gen == CHIPSET_GEMINI_LAKE ||
- ich_gen == CHIPSET_ELKHART_LAKE)) {
- msg_pdbg("Enabling hardware sequencing by default for Apollo/Gemini/Elkhart Lake.\n");
- ich_spi_mode = ich_hwseq;
- }
-
- if (ich_spi_mode == ich_hwseq) {
- if (!desc_valid) {
- msg_perr("Hardware sequencing was requested "
- "but the flash descriptor is not "
- "valid. Aborting.\n");
- return ERROR_FATAL;
- }
-
- int tmpi = getFCBA_component_density(ich_generation, &desc, 0);
- if (tmpi < 0) {
- msg_perr("Could not determine density of flash component %d.\n", 0);
- return ERROR_FATAL;
- }
- hwseq_data.size_comp0 = tmpi;
-
- tmpi = getFCBA_component_density(ich_generation, &desc, 1);
- if (tmpi < 0) {
- msg_perr("Could not determine density of flash component %d.\n", 1);
- return ERROR_FATAL;
- }
- hwseq_data.size_comp1 = tmpi;
-
- register_opaque_master(&opaque_master_ich_hwseq, NULL);
+ if (ich_gen == CHIPSET_ICH8) {
+ tmp = mmio_readl(ich_spibar + ICH8_REG_VSCC);
+ msg_pdbg("0x%x: 0x%08x (VSCC)\n", ICH8_REG_VSCC, tmp);
+ msg_pdbg("VSCC: ");
+ prettyprint_ich_reg_vscc(tmp, FLASHPROG_MSG_DEBUG, true);
} else {
- register_spi_master(&spi_master_ich9, 0, NULL);
+ tmp = mmio_readl(ich_spibar + ICH9_REG_LVSCC);
+ msg_pdbg("0x%x: 0x%08x (LVSCC)\n", ICH9_REG_LVSCC, tmp);
+ msg_pdbg("LVSCC: ");
+ prettyprint_ich_reg_vscc(tmp, FLASHPROG_MSG_DEBUG, true);
+
+ tmp = mmio_readl(ich_spibar + ICH9_REG_UVSCC);
+ msg_pdbg("0x%x: 0x%08x (UVSCC)\n", ICH9_REG_UVSCC, tmp);
+ msg_pdbg("UVSCC: ");
+ prettyprint_ich_reg_vscc(tmp, FLASHPROG_MSG_DEBUG, false);
}
- break;
+
+ switch (ich_gen) {
+ case CHIPSET_ICH8:
+ case CHIPSET_100_SERIES_SUNRISE_POINT:
+ case CHIPSET_C620_SERIES_LEWISBURG:
+ case CHIPSET_300_SERIES_CANNON_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_ELKHART_LAKE:
+ break;
+ default:
+ tmp = mmio_readl(ich_spibar + ICH9_REG_FPB);
+ msg_pdbg("0x%x: 0x%08x (FPB)\n", ICH9_REG_FPB, tmp);
+ break;
+ }
+
+ if (read_ich_descriptors_via_fdo(ich_gen, ich_spibar, &desc) == ICH_RET_OK)
+ prettyprint_ich_descriptors(ich_gen, &desc);
+
+ /* If the descriptor is valid and indicates multiple
+ * flash devices we need to use hwseq to be able to
+ * access the second flash device.
+ */
+ if (ich_spi_mode == ich_auto && desc.content.NC != 0) {
+ msg_pinfo("Enabling hardware sequencing due to "
+ "multiple flash chips detected.\n");
+ ich_spi_mode = ich_hwseq;
+ }
+ }
+
+ if (ich_spi_mode == ich_auto && ichspi_lock &&
+ ich_missing_opcodes()) {
+ msg_pinfo("Enabling hardware sequencing because "
+ "some important opcode is locked.\n");
+ ich_spi_mode = ich_hwseq;
+ }
+
+ if (ich_spi_mode == ich_auto &&
+ (ich_gen == CHIPSET_100_SERIES_SUNRISE_POINT ||
+ ich_gen == CHIPSET_300_SERIES_CANNON_POINT ||
+ ich_gen == CHIPSET_500_SERIES_TIGER_POINT)) {
+ msg_pdbg("Enabling hardware sequencing by default for 100+ series PCH.\n");
+ ich_spi_mode = ich_hwseq;
+ }
+
+ if (ich_spi_mode == ich_auto &&
+ (ich_gen == CHIPSET_APOLLO_LAKE ||
+ ich_gen == CHIPSET_GEMINI_LAKE ||
+ ich_gen == CHIPSET_ELKHART_LAKE)) {
+ msg_pdbg("Enabling hardware sequencing by default for Apollo/Gemini/Elkhart Lake.\n");
+ ich_spi_mode = ich_hwseq;
+ }
+
+ if (ich_spi_mode == ich_hwseq) {
+ if (!desc_valid) {
+ msg_perr("Hardware sequencing was requested "
+ "but the flash descriptor is not "
+ "valid. Aborting.\n");
+ return ERROR_FATAL;
+ }
+
+ int tmpi = getFCBA_component_density(ich_generation, &desc, 0);
+ if (tmpi < 0) {
+ msg_perr("Could not determine density of flash component %d.\n", 0);
+ return ERROR_FATAL;
+ }
+ hwseq_data.size_comp0 = tmpi;
+
+ tmpi = getFCBA_component_density(ich_generation, &desc, 1);
+ if (tmpi < 0) {
+ msg_perr("Could not determine density of flash component %d.\n", 1);
+ return ERROR_FATAL;
+ }
+ hwseq_data.size_comp1 = tmpi;
+
+ register_opaque_master(&opaque_master_ich_hwseq, NULL);
+ } else {
+ register_spi_master(&spi_master_ich9, 0, NULL);
}
return 0;