summaryrefslogtreecommitdiffstats
path: root/ich_descriptors.c
diff options
context:
space:
mode:
Diffstat (limited to 'ich_descriptors.c')
-rw-r--r--ich_descriptors.c372
1 files changed, 256 insertions, 116 deletions
diff --git a/ich_descriptors.c b/ich_descriptors.c
index 7374984dc..a2a99bd0b 100644
--- a/ich_descriptors.c
+++ b/ich_descriptors.c
@@ -15,6 +15,7 @@
* GNU General Public License for more details.
*/
+#include "hwaccess_physmap.h"
#include "ich_descriptors.h"
#ifdef ICH_DESCRIPTORS_FROM_DUMP_ONLY
@@ -30,6 +31,7 @@
#define UPPER_MAP_OFFSET (4096 - 256 - 4)
#define getVTBA(flumap) (((flumap)->FLUMAP1 << 4) & 0x00000ff0)
+#include <stdbool.h>
#include <sys/types.h>
#include <string.h>
#include "flash.h" /* for msg_* */
@@ -39,10 +41,16 @@ ssize_t ich_number_of_regions(const enum ich_chipset cs, const struct ich_desc_c
{
switch (cs) {
case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
return 6;
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
+ case CHIPSET_ELKHART_LAKE:
+ case CHIPSET_JASPER_LAKE:
return 16;
case CHIPSET_100_SERIES_SUNRISE_POINT:
return 10;
@@ -68,6 +76,11 @@ ssize_t ich_number_of_masters(const enum ich_chipset cs, const struct ich_desc_c
switch (cs) {
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_JASPER_LAKE:
+ case CHIPSET_ELKHART_LAKE:
if (cont->NM <= MAX_NUM_MASTERS)
return cont->NM;
break;
@@ -81,13 +94,13 @@ ssize_t ich_number_of_masters(const enum ich_chipset cs, const struct ich_desc_c
void prettyprint_ich_reg_vscc(uint32_t reg_val, int verbosity, bool print_vcl)
{
- print(verbosity, "BES=0x%x, ", (reg_val & VSCC_BES) >> VSCC_BES_OFF);
- print(verbosity, "WG=%d, ", (reg_val & VSCC_WG) >> VSCC_WG_OFF);
- print(verbosity, "WSR=%d, ", (reg_val & VSCC_WSR) >> VSCC_WSR_OFF);
- print(verbosity, "WEWS=%d, ", (reg_val & VSCC_WEWS) >> VSCC_WEWS_OFF);
- print(verbosity, "EO=0x%x", (reg_val & VSCC_EO) >> VSCC_EO_OFF);
+ print(verbosity, "BES=0x%"PRIx32", ", (reg_val & VSCC_BES) >> VSCC_BES_OFF);
+ print(verbosity, "WG=%"PRId32", ", (reg_val & VSCC_WG) >> VSCC_WG_OFF);
+ print(verbosity, "WSR=%"PRId32", ", (reg_val & VSCC_WSR) >> VSCC_WSR_OFF);
+ print(verbosity, "WEWS=%"PRId32", ", (reg_val & VSCC_WEWS) >> VSCC_WEWS_OFF);
+ print(verbosity, "EO=0x%"PRIx32"", (reg_val & VSCC_EO) >> VSCC_EO_OFF);
if (print_vcl)
- print(verbosity, ", VCL=%d", (reg_val & VSCC_VCL) >> VSCC_VCL_OFF);
+ print(verbosity, ", VCL=%"PRId32"", (reg_val & VSCC_VCL) >> VSCC_VCL_OFF);
print(verbosity, "\n");
}
@@ -104,7 +117,9 @@ void prettyprint_ich_chipset(enum ich_chipset cs)
"5 series Ibex Peak", "6 series Cougar Point", "7 series Panther Point",
"8 series Lynx Point", "Baytrail", "8 series Lynx Point LP", "8 series Wellsburg",
"9 series Wildcat Point", "9 series Wildcat Point LP", "100 series Sunrise Point",
- "C620 series Lewisburg", "300 series Cannon Point", "Apollo Lake",
+ "C620 series Lewisburg", "300 series Cannon Point", "400 series Comet Point",
+ "500 series Tiger Point", "600 series Alder Point", "Meteor Lake",
+ "Apollo Lake", "Gemini Lake", "Jasper Lake", "Elkhart Lake",
};
if (cs < CHIPSET_ICH8 || cs - CHIPSET_ICH8 + 1 >= ARRAY_SIZE(chipset_names))
cs = 0;
@@ -130,23 +145,23 @@ void prettyprint_ich_descriptors(enum ich_chipset cs, const struct ich_descripto
void prettyprint_ich_descriptor_content(enum ich_chipset cs, const struct ich_desc_content *cont)
{
msg_pdbg2("=== Content Section ===\n");
- msg_pdbg2("FLVALSIG 0x%08x\n", cont->FLVALSIG);
- msg_pdbg2("FLMAP0 0x%08x\n", cont->FLMAP0);
- msg_pdbg2("FLMAP1 0x%08x\n", cont->FLMAP1);
- msg_pdbg2("FLMAP2 0x%08x\n", cont->FLMAP2);
+ msg_pdbg2("FLVALSIG 0x%08"PRIx32"\n", cont->FLVALSIG);
+ msg_pdbg2("FLMAP0 0x%08"PRIx32"\n", cont->FLMAP0);
+ msg_pdbg2("FLMAP1 0x%08"PRIx32"\n", cont->FLMAP1);
+ msg_pdbg2("FLMAP2 0x%08"PRIx32"\n", cont->FLMAP2);
msg_pdbg2("\n");
msg_pdbg2("--- Details ---\n");
msg_pdbg2("NR (Number of Regions): %5zd\n", ich_number_of_regions(cs, cont));
- msg_pdbg2("FRBA (Flash Region Base Address): 0x%03x\n", getFRBA(cont));
+ msg_pdbg2("FRBA (Flash Region Base Address): 0x%03"PRIx32"\n", getFRBA(cont));
msg_pdbg2("NC (Number of Components): %5d\n", cont->NC + 1);
- msg_pdbg2("FCBA (Flash Component Base Address): 0x%03x\n", getFCBA(cont));
+ msg_pdbg2("FCBA (Flash Component Base Address): 0x%03"PRIx32"\n", getFCBA(cont));
msg_pdbg2("ISL (ICH/PCH/SoC Strap Length): %5d\n", cont->ISL);
- msg_pdbg2("FISBA/FPSBA (Flash ICH/PCH/SoC Strap Base Addr): 0x%03x\n", getFISBA(cont));
+ msg_pdbg2("FISBA/FPSBA (Flash ICH/PCH/SoC Strap Base Addr): 0x%03"PRIx32"\n", getFISBA(cont));
msg_pdbg2("NM (Number of Masters): %5zd\n", ich_number_of_masters(cs, cont));
- msg_pdbg2("FMBA (Flash Master Base Address): 0x%03x\n", getFMBA(cont));
+ msg_pdbg2("FMBA (Flash Master Base Address): 0x%03"PRIx32"\n", getFMBA(cont));
msg_pdbg2("MSL/PSL (MCH/PROC Strap Length): %5d\n", cont->MSL);
- msg_pdbg2("FMSBA (Flash MCH/PROC Strap Base Address): 0x%03x\n", getFMSBA(cont));
+ msg_pdbg2("FMSBA (Flash MCH/PROC Strap Base Address): 0x%03"PRIx32"\n", getFMSBA(cont));
msg_pdbg2("\n");
}
@@ -198,7 +213,13 @@ static const char *pprint_density(enum ich_chipset cs, const struct ich_descript
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
- case CHIPSET_APOLLO_LAKE: {
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
+ case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_JASPER_LAKE:
+ case CHIPSET_ELKHART_LAKE: {
uint8_t size_enc;
if (idx == 0) {
size_enc = desc->component.dens_new.comp1_density;
@@ -217,7 +238,7 @@ static const char *pprint_density(enum ich_chipset cs, const struct ich_descript
static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
{
- static const char *const freq_str[3][8] = { {
+ static const char *const freq_str[5][8] = { {
"20 MHz",
"33 MHz",
"reserved",
@@ -244,7 +265,25 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
"reserved",
"14 MHz / 17 MHz",
"reserved"
- } };
+ }, {
+ "100 MHz",
+ "50 MHz",
+ "reserved",
+ "33 MHz",
+ "25 MHz",
+ "reserved",
+ "14 MHz",
+ "reserved"
+ }, {
+ "reserved",
+ "50 MHz",
+ "reserved",
+ "reserved",
+ "33 MHz",
+ "20 MHz",
+ "reserved",
+ "reserved",
+ }};
switch (cs) {
case CHIPSET_ICH8:
@@ -267,15 +306,50 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
+ case CHIPSET_JASPER_LAKE:
return freq_str[1][value];
case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
return freq_str[2][value];
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
+ return freq_str[3][value];
+ case CHIPSET_ELKHART_LAKE:
+ return freq_str[4][value];
case CHIPSET_ICH_UNKNOWN:
default:
return "unknown";
}
}
+static void pprint_read_freq(enum ich_chipset cs, uint8_t value)
+{
+ static const char *const freq_str[1][8] = { {
+ "20 MHz",
+ "24 MHz",
+ "30 MHz",
+ "48 MHz",
+ "60 MHz",
+ "reserved",
+ "reserved",
+ "reserved"
+ }};
+
+ switch (cs) {
+ case CHIPSET_300_SERIES_CANNON_POINT:
+ case CHIPSET_400_SERIES_COMET_POINT:
+ msg_pdbg2("eSPI/EC Bus Clock Frequency: %s\n", freq_str[0][value]);
+ return;
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ msg_pdbg2("Read Clock Frequency: %s\n", "reserved");
+ return;
+ default:
+ msg_pdbg2("Read Clock Frequency: %s\n", pprint_freq(cs, value));
+ return;
+ }
+}
+
void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_descriptors *desc)
{
bool has_flill1;
@@ -285,7 +359,13 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_JASPER_LAKE:
+ case CHIPSET_ELKHART_LAKE:
has_flill1 = true;
break;
default:
@@ -294,10 +374,10 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
}
msg_pdbg2("=== Component Section ===\n");
- msg_pdbg2("FLCOMP 0x%08x\n", desc->component.FLCOMP);
- msg_pdbg2("FLILL 0x%08x\n", desc->component.FLILL );
+ msg_pdbg2("FLCOMP 0x%08"PRIx32"\n", desc->component.FLCOMP);
+ msg_pdbg2("FLILL 0x%08"PRIx32"\n", desc->component.FLILL );
if (has_flill1)
- msg_pdbg2("FLILL1 0x%08x\n", desc->component.FLILL1);
+ msg_pdbg2("FLILL1 0x%08"PRIx32"\n", desc->component.FLILL1);
msg_pdbg2("\n");
msg_pdbg2("--- Details ---\n");
@@ -306,7 +386,9 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
msg_pdbg2("Component 2 density: %s\n", pprint_density(cs, desc, 1));
else
msg_pdbg2("Component 2 is not used.\n");
- msg_pdbg2("Read Clock Frequency: %s\n", pprint_freq(cs, desc->component.modes.freq_read));
+
+ pprint_read_freq(cs, desc->component.modes.freq_read);
+
msg_pdbg2("Read ID and Status Clock Freq.: %s\n", pprint_freq(cs, desc->component.modes.freq_read_id));
msg_pdbg2("Write and Erase Clock Freq.: %s\n", pprint_freq(cs, desc->component.modes.freq_write));
msg_pdbg2("Fast Read is %ssupported.\n", desc->component.modes.fastread ? "" : "not ");
@@ -315,11 +397,11 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
pprint_freq(cs, desc->component.modes.freq_fastread));
if (cs > CHIPSET_6_SERIES_COUGAR_POINT)
msg_pdbg2("Dual Output Fast Read Support: %sabled\n",
- desc->component.modes.dual_output ? "dis" : "en");
+ desc->component.modes.dual_output ? "en" : "dis");
- int has_forbidden_opcode = 0;
+ bool has_forbidden_opcode = false;
if (desc->component.FLILL != 0) {
- has_forbidden_opcode = 1;
+ has_forbidden_opcode = true;
msg_pdbg2("Invalid instruction 0: 0x%02x\n",
desc->component.invalid_instr0);
msg_pdbg2("Invalid instruction 1: 0x%02x\n",
@@ -331,7 +413,7 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
}
if (has_flill1) {
if (desc->component.FLILL1 != 0) {
- has_forbidden_opcode = 1;
+ has_forbidden_opcode = true;
msg_pdbg2("Invalid instruction 4: 0x%02x\n",
desc->component.invalid_instr4);
msg_pdbg2("Invalid instruction 5: 0x%02x\n",
@@ -360,11 +442,11 @@ static void pprint_freg(const struct ich_desc_region *reg, uint32_t i)
}
uint32_t base = ICH_FREG_BASE(reg->FLREGs[i]);
uint32_t limit = ICH_FREG_LIMIT(reg->FLREGs[i]);
- msg_pdbg2("Region %d (%-7s) ", i, region_names[i]);
+ msg_pdbg2("Region %"PRId32" (%-7s) ", i, region_names[i]);
if (base > limit)
msg_pdbg2("is unused.\n");
else
- msg_pdbg2("0x%08x - 0x%08x\n", base, limit);
+ msg_pdbg2("0x%08"PRIx32" - 0x%08"PRIx32"\n", base, limit);
}
void prettyprint_ich_descriptor_region(const enum ich_chipset cs, const struct ich_descriptors *const desc)
@@ -378,7 +460,7 @@ void prettyprint_ich_descriptor_region(const enum ich_chipset cs, const struct i
return;
}
for (i = 0; i < nr; i++)
- msg_pdbg2("FLREG%zd 0x%08x\n", i, desc->region.FLREGs[i]);
+ msg_pdbg2("FLREG%zd 0x%08"PRIx32"\n", i, desc->region.FLREGs[i]);
msg_pdbg2("\n");
msg_pdbg2("--- Details ---\n");
@@ -398,13 +480,16 @@ void prettyprint_ich_descriptor_master(const enum ich_chipset cs, const struct i
return;
}
for (i = 0; i < nm; i++)
- msg_pdbg2("FLMSTR%zd 0x%08x\n", i + 1, desc->master.FLMSTRs[i]);
+ msg_pdbg2("FLMSTR%zd 0x%08"PRIx32"\n", i + 1, desc->master.FLMSTRs[i]);
msg_pdbg2("\n");
msg_pdbg2("--- Details ---\n");
if (cs == CHIPSET_100_SERIES_SUNRISE_POINT ||
cs == CHIPSET_300_SERIES_CANNON_POINT ||
- cs == CHIPSET_400_SERIES_COMET_POINT) {
+ cs == CHIPSET_400_SERIES_COMET_POINT ||
+ cs == CHIPSET_500_SERIES_TIGER_POINT ||
+ cs == CHIPSET_600_SERIES_ALDER_POINT ||
+ cs == CHIPSET_JASPER_LAKE || cs == CHIPSET_METEOR_LAKE) {
const char *const master_names[] = {
"BIOS", "ME", "GbE", "unknown", "EC",
};
@@ -424,16 +509,17 @@ void prettyprint_ich_descriptor_master(const enum ich_chipset cs, const struct i
msg_pdbg2(" RegA RegB RegC RegD RegE RegF\n");
}
for (i = 0; i < nm; i++) {
+ const unsigned int ext_region_start = 12;
size_t j;
msg_pdbg2("%-4s", master_names[i]);
- for (j = 0; j < (size_t)min(num_regions, 12); j++)
+ for (j = 0; j < (size_t)min(num_regions, ext_region_start); j++)
msg_pdbg2(" %c%c ",
desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
- for (; j < num_regions; j++)
+ for (j = ext_region_start; j < num_regions; j++)
msg_pdbg2(" %c%c ",
- desc->master.mstr[i].ext_read & (1 << (j - 12)) ? 'r' : ' ',
- desc->master.mstr[i].ext_write & (1 << (j - 12)) ? 'w' : ' ');
+ desc->master.mstr[i].ext_read & (1 << (j - ext_region_start)) ? 'r' : ' ',
+ desc->master.mstr[i].ext_write & (1 << (j - ext_region_start)) ? 'w' : ' ');
msg_pdbg2("\n");
}
} else if (cs == CHIPSET_C620_SERIES_LEWISBURG) {
@@ -462,7 +548,7 @@ void prettyprint_ich_descriptor_master(const enum ich_chipset cs, const struct i
desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
msg_pdbg2("\n");
}
- } else if (cs == CHIPSET_APOLLO_LAKE) {
+ } else if (cs == CHIPSET_APOLLO_LAKE || cs == CHIPSET_GEMINI_LAKE || cs == CHIPSET_ELKHART_LAKE) {
const char *const master_names[] = { "BIOS", "TXE", };
if (nm > (ssize_t)ARRAY_SIZE(master_names)) {
msg_pdbg2("%s: number of masters too high (%d).\n", __func__, desc->content.NM);
@@ -826,7 +912,7 @@ void prettyprint_ich_descriptor_straps(enum ich_chipset cs, const struct ich_des
msg_pdbg2("--- North/MCH/PROC (%d entries) ---\n", max_count);
for (i = 0; i < max_count; i++)
- msg_pdbg2("STRP%-2d = 0x%08x\n", i, desc->north.STRPs[i]);
+ msg_pdbg2("STRP%-2d = 0x%08"PRIx32"\n", i, desc->north.STRPs[i]);
msg_pdbg2("\n");
max_count = MIN(ARRAY_SIZE(desc->south.STRPs), desc->content.ISL);
@@ -838,7 +924,7 @@ void prettyprint_ich_descriptor_straps(enum ich_chipset cs, const struct ich_des
msg_pdbg2("--- South/ICH/PCH (%d entries) ---\n", max_count);
for (i = 0; i < max_count; i++)
- msg_pdbg2("STRP%-2d = 0x%08x\n", i, desc->south.STRPs[i]);
+ msg_pdbg2("STRP%-2d = 0x%08"PRIx32"\n", i, desc->south.STRPs[i]);
msg_pdbg2("\n");
switch (cs) {
@@ -884,72 +970,103 @@ void prettyprint_ich_descriptor_upper_map(const struct ich_desc_upper_map *umap)
{
int i;
msg_pdbg2("=== Upper Map Section ===\n");
- msg_pdbg2("FLUMAP1 0x%08x\n", umap->FLUMAP1);
+ msg_pdbg2("FLUMAP1 0x%08"PRIx32"\n", umap->FLUMAP1);
msg_pdbg2("\n");
msg_pdbg2("--- Details ---\n");
msg_pdbg2("VTL (length in DWORDS) = %d\n", umap->VTL);
- msg_pdbg2("VTBA (base address) = 0x%6.6x\n", getVTBA(umap));
+ msg_pdbg2("VTBA (base address) = 0x%6.6"PRIx32"\n", getVTBA(umap));
msg_pdbg2("\n");
msg_pdbg2("VSCC Table: %d entries\n", umap->VTL/2);
for (i = 0; i < umap->VTL/2; i++) {
uint32_t jid = umap->vscc_table[i].JID;
uint32_t vscc = umap->vscc_table[i].VSCC;
- msg_pdbg2(" JID%d = 0x%08x\n", i, jid);
- msg_pdbg2(" VSCC%d = 0x%08x\n", i, vscc);
- msg_pdbg2(" "); /* indention */
+ msg_pdbg2(" JID%d = 0x%08"PRIx32"\n", i, jid);
+ msg_pdbg2(" VSCC%d = 0x%08"PRIx32"\n", i, vscc);
+ msg_pdbg2(" "); /* indentation */
prettyprint_rdid(jid);
- msg_pdbg2(" "); /* indention */
+ msg_pdbg2(" "); /* indentation */
prettyprint_ich_reg_vscc(vscc, 0, false);
}
msg_pdbg2("\n");
}
+static inline void warn_peculiar_desc(const char *const name)
+{
+ msg_pwarn("Peculiar flash descriptor, assuming %s compatibility.\n", name);
+}
+
/*
* Guesses a minimum chipset version based on the maximum number of
- * soft straps per generation.
+ * soft straps per generation and presence of the MIP base (MDTBA).
*/
-static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_content *const content)
+static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_content *const content,
+ const struct ich_desc_upper_map *const upper)
{
if (content->ICCRIBA == 0x00) {
if (content->MSL == 0 && content->ISL <= 2)
return CHIPSET_ICH8;
- else if (content->ISL <= 2)
+ if (content->ISL <= 2)
return CHIPSET_ICH9;
- else if (content->ISL <= 10)
+ if (content->ISL <= 10)
return CHIPSET_ICH10;
- else if (content->ISL <= 16)
+ if (content->ISL <= 16)
return CHIPSET_5_SERIES_IBEX_PEAK;
- else if (content->FLMAP2 == 0) {
- if (content->ISL != 19)
- msg_pwarn("Peculiar firmware descriptor, assuming Apollo Lake compatibility.\n");
- return CHIPSET_APOLLO_LAKE;
+ if (content->FLMAP2 == 0) {
+ if (content->ISL == 19)
+ return CHIPSET_APOLLO_LAKE;
+ if (content->ISL == 23)
+ return CHIPSET_GEMINI_LAKE;
+ warn_peculiar_desc("Gemini Lake");
+ return CHIPSET_GEMINI_LAKE;
}
- msg_pwarn("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n");
+ if (content->ISL <= 80)
+ return CHIPSET_C620_SERIES_LEWISBURG;
+ warn_peculiar_desc("Ibex Peak");
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)
+ } else if (upper->MDTBA == 0x00) {
+ if (content->ICCRIBA < 0x31 && content->FMSBA < 0x30) {
+ if (content->MSL == 0 && content->ISL <= 17)
+ return CHIPSET_BAYTRAIL;
+ if (content->MSL <= 1 && content->ISL <= 18)
+ return CHIPSET_6_SERIES_COUGAR_POINT;
+ if (content->MSL <= 1 && content->ISL <= 21)
+ return CHIPSET_8_SERIES_LYNX_POINT;
+ warn_peculiar_desc("Lynx Point");
return CHIPSET_8_SERIES_LYNX_POINT;
- msg_pwarn("Peculiar firmware descriptor, assuming Wildcat Point compatibility.\n");
- return CHIPSET_9_SERIES_WILDCAT_POINT;
- } else if (content->ICCRIBA < 0x34) {
- if (content->NM == 6)
+ }
+ if (content->NM == 6) {
+ if (content->ICCRIBA <= 0x34)
+ return CHIPSET_C620_SERIES_LEWISBURG;
+ warn_peculiar_desc("C620 series");
return CHIPSET_C620_SERIES_LEWISBURG;
- else
+ }
+ if (content->ICCRIBA == 0x31)
return CHIPSET_100_SERIES_SUNRISE_POINT;
- } else if (content->ICCRIBA == 0x34) {
- if (content->NM == 6)
- return CHIPSET_C620_SERIES_LEWISBURG;
- else
- return CHIPSET_300_SERIES_CANNON_POINT;
+ warn_peculiar_desc("100 series");
+ return CHIPSET_100_SERIES_SUNRISE_POINT;
} else {
- msg_pwarn("Unknown firmware descriptor, assuming 300 series compatibility.\n");
- return CHIPSET_300_SERIES_CANNON_POINT;
+ if (content->ICCRIBA == 0x34)
+ return CHIPSET_300_SERIES_CANNON_POINT;
+ if (content->CSSL == 0x11) {
+ if (content->CSSO == 0x68)
+ return CHIPSET_500_SERIES_TIGER_POINT;
+ else if (content->CSSO == 0x5c)
+ return CHIPSET_600_SERIES_ALDER_POINT;
+ }
+ if (content->CSSL == 0x14)
+ return CHIPSET_600_SERIES_ALDER_POINT;
+ if (content->CSSL == 0x03) {
+ if (content->CSSO == 0x58)
+ return CHIPSET_ELKHART_LAKE;
+ else if (content->CSSO == 0x6c)
+ return CHIPSET_JASPER_LAKE;
+ else if (content->CSSO == 0x70)
+ return CHIPSET_METEOR_LAKE;
+ }
+ msg_pwarn("Unknown flash descriptor, assuming 500 series compatibility.\n");
+ return CHIPSET_500_SERIES_TIGER_POINT;
}
}
@@ -960,36 +1077,41 @@ static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_con
* tinction because of the dropped number of regions field (NR).
*/
static enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const content,
- const struct ich_desc_component *const component)
+ const struct ich_desc_component *const component,
+ const struct ich_desc_upper_map *const upper)
{
- const enum ich_chipset guess = guess_ich_chipset_from_content(content);
+ const enum ich_chipset guess = guess_ich_chipset_from_content(content, upper);
switch (guess) {
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_JASPER_LAKE:
+ case CHIPSET_ELKHART_LAKE:
/* `freq_read` was repurposed, so can't check on it any more. */
- return guess;
+ break;
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_APOLLO_LAKE:
if (component->modes.freq_read != 6) {
- msg_pwarn("\nThe firmware descriptor looks like a Skylake/Sunrise Point descriptor.\n"
+ msg_pwarn("\nThe flash 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;
+ break;
default:
if (component->modes.freq_read == 6) {
- msg_pwarn("\nThe firmware descriptor has the read frequency set to 17MHz. However,\n"
+ msg_pwarn("\nThe flash 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;
}
- return guess;
}
+ return guess;
}
/* len is the length of dump in bytes */
@@ -1024,8 +1146,25 @@ int read_ich_descriptors_from_dump(const uint32_t *const dump, const size_t len,
desc->component.FLILL = dump[(getFCBA(&desc->content) >> 2) + 1];
desc->component.FLPB = dump[(getFCBA(&desc->content) >> 2) + 2];
+ /* upper map */
+ desc->upper.FLUMAP1 = dump[(UPPER_MAP_OFFSET >> 2) + 0];
+
+ /* VTL is 8 bits long. Quote from the Ibex Peak SPI programming guide:
+ * "Identifies the 1s based number of DWORDS contained in the VSCC
+ * Table. Each SPI component entry in the table is 2 DWORDS long." So
+ * the maximum of 255 gives us 127.5 SPI components(!?) 8 bytes each. A
+ * check ensures that the maximum offset actually accessed is available.
+ */
+ if (len < getVTBA(&desc->upper) + (desc->upper.VTL / 2 * 8))
+ return ICH_RET_OOB;
+
+ for (i = 0; i < desc->upper.VTL/2; i++) {
+ desc->upper.vscc_table[i].JID = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 0];
+ desc->upper.vscc_table[i].VSCC = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 1];
+ }
+
if (*cs == CHIPSET_ICH_UNKNOWN) {
- *cs = guess_ich_chipset(&desc->content, &desc->component);
+ *cs = guess_ich_chipset(&desc->content, &desc->component, &desc->upper);
prettyprint_ich_chipset(*cs);
}
@@ -1043,23 +1182,6 @@ int read_ich_descriptors_from_dump(const uint32_t *const dump, const size_t len,
for (i = 0; i < nm; i++)
desc->master.FLMSTRs[i] = dump[(getFMBA(&desc->content) >> 2) + i];
- /* upper map */
- desc->upper.FLUMAP1 = dump[(UPPER_MAP_OFFSET >> 2) + 0];
-
- /* VTL is 8 bits long. Quote from the Ibex Peak SPI programming guide:
- * "Identifies the 1s based number of DWORDS contained in the VSCC
- * Table. Each SPI component entry in the table is 2 DWORDS long." So
- * the maximum of 255 gives us 127.5 SPI components(!?) 8 bytes each. A
- * check ensures that the maximum offset actually accessed is available.
- */
- if (len < getVTBA(&desc->upper) + (desc->upper.VTL / 2 * 8))
- return ICH_RET_OOB;
-
- for (i = 0; i < desc->upper.VTL/2; i++) {
- desc->upper.vscc_table[i].JID = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 0];
- desc->upper.vscc_table[i].VSCC = dump[(getVTBA(&desc->upper) >> 2) + i * 2 + 1];
- }
-
/* MCH/PROC (aka. North) straps */
if (len < getFMSBA(&desc->content) + desc->content.MSL * 4)
return ICH_RET_OOB;
@@ -1122,7 +1244,13 @@ int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
case CHIPSET_APOLLO_LAKE:
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_JASPER_LAKE:
+ case CHIPSET_ELKHART_LAKE:
if (idx == 0) {
size_enc = desc->component.dens_new.comp1_density;
} else {
@@ -1151,20 +1279,33 @@ int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors
static uint32_t read_descriptor_reg(enum ich_chipset cs, uint8_t section, uint16_t offset, void *spibar)
{
uint32_t control = 0;
+ uint32_t woffset, roffset;
+
control |= (section << FDOC_FDSS_OFF) & FDOC_FDSS;
control |= (offset << FDOC_FDSI_OFF) & FDOC_FDSI;
+
switch (cs) {
case CHIPSET_100_SERIES_SUNRISE_POINT:
case CHIPSET_C620_SERIES_LEWISBURG:
case CHIPSET_300_SERIES_CANNON_POINT:
case CHIPSET_400_SERIES_COMET_POINT:
+ case CHIPSET_500_SERIES_TIGER_POINT:
+ case CHIPSET_600_SERIES_ALDER_POINT:
+ case CHIPSET_METEOR_LAKE:
case CHIPSET_APOLLO_LAKE:
- mmio_le_writel(control, spibar + PCH100_REG_FDOC);
- return mmio_le_readl(spibar + PCH100_REG_FDOD);
+ case CHIPSET_GEMINI_LAKE:
+ case CHIPSET_JASPER_LAKE:
+ case CHIPSET_ELKHART_LAKE:
+ woffset = PCH100_REG_FDOC;
+ roffset = PCH100_REG_FDOD;
+ break;
default:
- mmio_le_writel(control, spibar + ICH9_REG_FDOC);
- return mmio_le_readl(spibar + ICH9_REG_FDOD);
+ woffset = ICH9_REG_FDOC;
+ roffset = ICH9_REG_FDOD;
}
+
+ mmio_le_writel(control, spibar + woffset);
+ return mmio_le_readl(spibar + roffset);
}
int read_ich_descriptors_via_fdo(enum ich_chipset cs, void *spibar, struct ich_descriptors *desc)
@@ -1246,7 +1387,9 @@ int read_ich_descriptors_via_fdo(enum ich_chipset cs, void *spibar, struct ich_d
* 1 if the descriptor couldn't be parsed,
* 2 when out of memory.
*/
-int layout_from_ich_descriptors(struct ich_layout *const layout, const void *const dump, const size_t len)
+int layout_from_ich_descriptors(
+ struct flashrom_layout **const layout,
+ const void *const dump, const size_t len)
{
static const char *const regions[] = {
"fd", "bios", "me", "gbe", "pd", "reg5", "bios2", "reg7", "ec", "reg9", "ie",
@@ -1262,25 +1405,22 @@ int layout_from_ich_descriptors(struct ich_layout *const layout, const void *con
return 1;
}
- memset(layout, 0x00, sizeof(*layout));
+ if (flashrom_layout_new(layout))
+ return 2;
- ssize_t i, j;
+ ssize_t i;
const ssize_t nr = MIN(ich_number_of_regions(cs, &desc.content), (ssize_t)ARRAY_SIZE(regions));
- for (i = 0, j = 0; i < nr; ++i) {
+ for (i = 0; i < nr; ++i) {
const chipoff_t base = ICH_FREG_BASE(desc.region.FLREGs[i]);
const chipoff_t limit = ICH_FREG_LIMIT(desc.region.FLREGs[i]);
if (limit <= base)
continue;
- layout->entries[j].start = base;
- layout->entries[j].end = limit;
- layout->entries[j].included = false;
- layout->entries[j].name = strdup(regions[i]);
- if (!layout->entries[j].name)
+ if (flashrom_layout_add_region(*layout, base, limit, regions[i])) {
+ flashrom_layout_release(*layout);
+ *layout = NULL;
return 2;
- ++j;
+ }
}
- layout->base.entries = layout->entries;
- layout->base.num_entries = j;
return 0;
}