mirror of
https://review.coreboot.org/flashrom.git
synced 2025-07-02 14:33:18 +02:00
ichspi: Add Apollo Lake support
It's almost identical to 100 series PCHs and later. There are some additional FREGs (12..15). To not clutter the `if` conditions further, make more use of `switch` statements. Tested on Kontron mAL10. Mark it as DEP as usually the last sector is not covered by the descriptor layout and can't be read. Change-Id: I1c464b5b3d151e6d28d5db96495fe874a0a45718 Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: https://review.coreboot.org/c/flashrom/+/30995 Tested-by: build bot (Jenkins) <no-reply@coreboot.org> Reviewed-by: Angel Pons <th3fanbus@gmail.com>
This commit is contained in:
@ -42,6 +42,8 @@
|
||||
ssize_t ich_number_of_regions(const enum ich_chipset cs, const struct ich_desc_content *const cont)
|
||||
{
|
||||
switch (cs) {
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
return 6;
|
||||
case CHIPSET_C620_SERIES_LEWISBURG:
|
||||
return 16;
|
||||
case CHIPSET_100_SERIES_SUNRISE_POINT:
|
||||
@ -67,6 +69,7 @@ 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:
|
||||
if (cont->NM <= MAX_NUM_MASTERS)
|
||||
return cont->NM;
|
||||
break;
|
||||
@ -103,7 +106,7 @@ 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",
|
||||
"C620 series Lewisburg", "Apollo Lake",
|
||||
};
|
||||
if (cs < CHIPSET_ICH8 || cs - CHIPSET_ICH8 + 1 >= ARRAY_SIZE(chipset_names))
|
||||
cs = 0;
|
||||
@ -140,8 +143,8 @@ void prettyprint_ich_descriptor_content(enum ich_chipset cs, const struct ich_de
|
||||
msg_pdbg2("FRBA (Flash Region Base Address): 0x%03x\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("ISL (ICH/PCH Strap Length): %5d\n", cont->ISL);
|
||||
msg_pdbg2("FISBA/FPSBA (Flash ICH/PCH Strap Base Address): 0x%03x\n", getFISBA(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("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("MSL/PSL (MCH/PROC Strap Length): %5d\n", cont->MSL);
|
||||
@ -194,7 +197,8 @@ static const char *pprint_density(enum ich_chipset cs, const struct ich_descript
|
||||
case CHIPSET_9_SERIES_WILDCAT_POINT:
|
||||
case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
|
||||
case CHIPSET_100_SERIES_SUNRISE_POINT:
|
||||
case CHIPSET_C620_SERIES_LEWISBURG: {
|
||||
case CHIPSET_C620_SERIES_LEWISBURG:
|
||||
case CHIPSET_APOLLO_LAKE: {
|
||||
uint8_t size_enc;
|
||||
if (idx == 0) {
|
||||
size_enc = desc->component.dens_new.comp1_density;
|
||||
@ -213,7 +217,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[2][8] = { {
|
||||
static const char *const freq_str[3][8] = { {
|
||||
"20 MHz",
|
||||
"33 MHz",
|
||||
"reserved",
|
||||
@ -231,6 +235,15 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
|
||||
"reserved",
|
||||
"17 MHz",
|
||||
"reserved"
|
||||
}, {
|
||||
"reserved",
|
||||
"50 MHz",
|
||||
"40 MHz",
|
||||
"reserved",
|
||||
"25 MHz",
|
||||
"reserved",
|
||||
"14 MHz / 17 MHz",
|
||||
"reserved"
|
||||
} };
|
||||
|
||||
switch (cs) {
|
||||
@ -253,6 +266,8 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
|
||||
case CHIPSET_100_SERIES_SUNRISE_POINT:
|
||||
case CHIPSET_C620_SERIES_LEWISBURG:
|
||||
return freq_str[1][value];
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
return freq_str[2][value];
|
||||
case CHIPSET_ICH_UNKNOWN:
|
||||
default:
|
||||
return "unknown";
|
||||
@ -261,11 +276,23 @@ static const char *pprint_freq(enum ich_chipset cs, uint8_t value)
|
||||
|
||||
void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_descriptors *desc)
|
||||
{
|
||||
bool has_flill1;
|
||||
|
||||
switch (cs) {
|
||||
case CHIPSET_100_SERIES_SUNRISE_POINT:
|
||||
case CHIPSET_C620_SERIES_LEWISBURG:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
has_flill1 = true;
|
||||
break;
|
||||
default:
|
||||
has_flill1 = false;
|
||||
break;
|
||||
}
|
||||
|
||||
msg_pdbg2("=== Component Section ===\n");
|
||||
msg_pdbg2("FLCOMP 0x%08x\n", desc->component.FLCOMP);
|
||||
msg_pdbg2("FLILL 0x%08x\n", desc->component.FLILL );
|
||||
if (cs == CHIPSET_100_SERIES_SUNRISE_POINT || cs == CHIPSET_C620_SERIES_LEWISBURG)
|
||||
if (has_flill1)
|
||||
msg_pdbg2("FLILL1 0x%08x\n", desc->component.FLILL1);
|
||||
msg_pdbg2("\n");
|
||||
|
||||
@ -298,7 +325,7 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
|
||||
msg_pdbg2("Invalid instruction 3: 0x%02x\n",
|
||||
desc->component.invalid_instr3);
|
||||
}
|
||||
if (cs == CHIPSET_100_SERIES_SUNRISE_POINT || cs == CHIPSET_C620_SERIES_LEWISBURG) {
|
||||
if (has_flill1) {
|
||||
if (desc->component.FLILL1 != 0) {
|
||||
has_forbidden_opcode = 1;
|
||||
msg_pdbg2("Invalid instruction 4: 0x%02x\n",
|
||||
@ -320,7 +347,7 @@ void prettyprint_ich_descriptor_component(enum ich_chipset cs, const struct ich_
|
||||
static void pprint_freg(const struct ich_desc_region *reg, uint32_t i)
|
||||
{
|
||||
static const char *const region_names[] = {
|
||||
"Descr.", "BIOS", "ME", "GbE", "Platf.", "unknown", "BIOS2", "unknown",
|
||||
"Descr.", "BIOS", "ME", "GbE", "Platf.", "DevExp", "BIOS2", "unknown",
|
||||
"EC/BMC", "unknown", "IE", "10GbE", "unknown", "unknown", "unknown", "unknown"
|
||||
};
|
||||
if (i >= ARRAY_SIZE(region_names)) {
|
||||
@ -417,6 +444,23 @@ 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) {
|
||||
const char *const master_names[] = { "BIOS", "TXE", };
|
||||
if (nm > ARRAY_SIZE(master_names)) {
|
||||
msg_pdbg2("%s: number of masters too high (%d).\n", __func__, desc->content.NM);
|
||||
return;
|
||||
}
|
||||
|
||||
msg_pdbg2(" FD IFWI TXE n/a Platf DevExp\n");
|
||||
for (i = 0; i < nm; i++) {
|
||||
size_t j;
|
||||
msg_pdbg2("%-4s", master_names[i]);
|
||||
for (j = 0; j < ich_number_of_regions(cs, &desc->content); j++)
|
||||
msg_pdbg2(" %c%c ",
|
||||
desc->master.mstr[i].read & (1 << j) ? 'r' : ' ',
|
||||
desc->master.mstr[i].write & (1 << j) ? 'w' : ' ');
|
||||
msg_pdbg2("\n");
|
||||
}
|
||||
} else {
|
||||
const struct ich_desc_master *const mstr = &desc->master;
|
||||
msg_pdbg2(" Descr. BIOS ME GbE Platf.\n");
|
||||
@ -859,6 +903,11 @@ static enum ich_chipset guess_ich_chipset_from_content(const struct ich_desc_con
|
||||
return CHIPSET_ICH10;
|
||||
else 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;
|
||||
}
|
||||
msg_pwarn("Peculiar firmware descriptor, assuming Ibex Peak compatibility.\n");
|
||||
return CHIPSET_5_SERIES_IBEX_PEAK;
|
||||
} else if (content->ICCRIBA < 0x31 && content->FMSBA < 0x30) {
|
||||
@ -888,8 +937,20 @@ static enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const c
|
||||
{
|
||||
const enum ich_chipset guess = guess_ich_chipset_from_content(content);
|
||||
|
||||
if (component->modes.freq_read == 6) {
|
||||
if ((guess != CHIPSET_100_SERIES_SUNRISE_POINT) && (guess != CHIPSET_C620_SERIES_LEWISBURG)) {
|
||||
switch (guess) {
|
||||
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"
|
||||
"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;
|
||||
default:
|
||||
if (component->modes.freq_read == 6) {
|
||||
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"
|
||||
@ -897,17 +958,7 @@ static enum ich_chipset guess_ich_chipset(const struct ich_desc_content *const c
|
||||
return CHIPSET_100_SERIES_SUNRISE_POINT;
|
||||
}
|
||||
return guess;
|
||||
} else {
|
||||
if (guess == CHIPSET_100_SERIES_SUNRISE_POINT || guess == CHIPSET_C620_SERIES_LEWISBURG) {
|
||||
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 */
|
||||
@ -1038,6 +1089,7 @@ int getFCBA_component_density(enum ich_chipset cs, const struct ich_descriptors
|
||||
case CHIPSET_9_SERIES_WILDCAT_POINT_LP:
|
||||
case CHIPSET_100_SERIES_SUNRISE_POINT:
|
||||
case CHIPSET_C620_SERIES_LEWISBURG:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
if (idx == 0) {
|
||||
size_enc = desc->component.dens_new.comp1_density;
|
||||
} else {
|
||||
@ -1068,10 +1120,13 @@ static uint32_t read_descriptor_reg(enum ich_chipset cs, uint8_t section, uint16
|
||||
uint32_t control = 0;
|
||||
control |= (section << FDOC_FDSS_OFF) & FDOC_FDSS;
|
||||
control |= (offset << FDOC_FDSI_OFF) & FDOC_FDSI;
|
||||
if (cs == CHIPSET_100_SERIES_SUNRISE_POINT || cs == CHIPSET_C620_SERIES_LEWISBURG) {
|
||||
switch (cs) {
|
||||
case CHIPSET_100_SERIES_SUNRISE_POINT:
|
||||
case CHIPSET_C620_SERIES_LEWISBURG:
|
||||
case CHIPSET_APOLLO_LAKE:
|
||||
mmio_le_writel(control, spibar + PCH100_REG_FDOC);
|
||||
return mmio_le_readl(spibar + PCH100_REG_FDOD);
|
||||
} else {
|
||||
default:
|
||||
mmio_le_writel(control, spibar + ICH9_REG_FDOC);
|
||||
return mmio_le_readl(spibar + ICH9_REG_FDOD);
|
||||
}
|
||||
|
Reference in New Issue
Block a user