ich_descriptors: Add function to guess chipset version
Add guess_ich_chipset() that takes fields from a descriptor dump and
returns the lowest possible chipset version.
Intel did several incompatible changes to the descriptor through the
years. However, they forgot to add a version number. So we have to
apply some heuristics to detect the chipset version in case of exter-
nal flashing.
Change-Id: Ie1736663dc33801b19d3e695c072c61a6c6345a2
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/20246
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Reviewed-by: David Hendricks <david.hendricks@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/ich_descriptors.c b/ich_descriptors.c
index 3e53ec9..4c18dfa 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -702,6 +702,68 @@
msg_pdbg2("\n");
}
+/*
+ * Guesses a minimum chipset version based on the maximum number of
+ * soft straps per generation.
+ */
+static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_content *const content)
+{
+ if (content->ICCRIBA == 0x00) {
+ if (content->MSL == 0 && content->ISL <= 2)
+ return CHIPSET_ICH8;
+ else if (content->ISL <= 2)
+ return CHIPSET_ICH9;
+ else if (content->ISL <= 10)
+ return CHIPSET_ICH10;
+ else if (content->ISL <= 16)
+ return CHIPSET_5_SERIES_IBEX_PEAK;
+ msg_pwarn("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n");
+ return CHIPSET_5_SERIES_IBEX_PEAK;
+ } else if (content->ICCRIBA < 0x31 && content->FMSBA < 0x30) {
+ if (content->MSL == 0 && content->ISL <= 17)
+ return CHIPSET_BAYTRAIL;
+ else if (content->MSL <= 1 && content->ISL <= 18)
+ return CHIPSET_6_SERIES_COUGAR_POINT;
+ else if (content->MSL <= 1 && content->ISL <= 21)
+ return CHIPSET_8_SERIES_LYNX_POINT;
+ msg_pwarn("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n");
+ return CHIPSET_9_SERIES_WILDCAT_POINT;
+ } else {
+ return CHIPSET_100_SERIES_SUNRISE_POINT;
+ }
+}
+
+/*
+ * As an additional measure, we check the read frequency like `ifdtool`.
+ * The frequency value 6 (17MHz) was reserved before Skylake and is the
+ * only valid value since. Skylake is currently the most important dis-
+ * tinction because of the dropped number of regions field (NR).
+ */
+enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const content,
+ const struct ich_desc_component *const component)
+{
+ const enum ich_chipset guess = guess_ich_chipset_from_content(content);
+
+ if (component->modes.freq_read == 6) {
+ if (guess != CHIPSET_100_SERIES_SUNRISE_POINT)
+ msg_pwarn("\nThe firmware descriptor has the read frequency set to 17MHz. However,\n"
+ "it doesn't look like a Skylake/Sunrise Point compatible descriptor.\n"
+ "Please report this message, the output of `ich_descriptors_tool` for\n"
+ "your descriptor and the output of `lspci -nn` to flashrom@flashrom.org\n\n");
+ return CHIPSET_100_SERIES_SUNRISE_POINT;
+ } else {
+ if (guess == CHIPSET_100_SERIES_SUNRISE_POINT) {
+ msg_pwarn("\nThe firmware descriptor looks like a Skylake/Sunrise Point descriptor.\n"
+ "However, the read frequency isn't set to 17MHz (the only valid value).\n"
+ "Please report this message, the output of `ich_descriptors_tool` for\n"
+ "your descriptor and the output of `lspci -nn` to flashrom@flashrom.org\n\n");
+ return CHIPSET_9_SERIES_WILDCAT_POINT;
+ }
+ }
+
+ return guess;
+}
+
/* len is the length of dump in bytes */
int read_ich_descriptors_from_dump(const uint32_t *dump, unsigned int len, struct ich_descriptors *desc)
{
diff --git a/ich_descriptors.h b/ich_descriptors.h
index ec85e0c..920e098 100644
--- a/ich_descriptors.h
+++ b/ich_descriptors.h
@@ -93,9 +93,10 @@
union { /* 0x0c */
uint32_t FLMAP2;
struct {
- uint32_t FMSBA :8, /* Flash (G)MCH Strap Base Addr. */
- MSL :8, /* MCH Strap Length */
- :16;
+ uint32_t FMSBA :8, /* Flash (G)MCH Strap Base Addr. */
+ MSL :8, /* MCH Strap Length */
+ ICCRIBA :8, /* ICC Reg. Init Base Addr. (new since Sandy Bridge) */
+ RIL :8; /* Register Init Length (new since Hawell) */
};
};
};