sb/intel/*: add option to lockdown chipset on normal boot path

On platforms with a PCH, some registers within host bridge should be
locked down on each normal boot path (done by either coreboot or
payload) and S3 resume (always done by coreboot).

A function to perform such locking is implemented in src/northbridge/
intel/*/finalize.c, and is designed as the handler of an #SMI triggered
with outb(APM_CNT_FINALIZE, APM_CNT), but currently this #SMI is only
triggered during s3 resume, and not on normal boot path. This problem
has beed discussed in
https://mail.coreboot.org/pipermail/coreboot/2017-August/084924.html .

This time, an option "INTEL_CHIPSET_LOCKDOWN" within src/southbridge/
intel/common/Kconfig is added to control the actual locking, which
depends on several compatibility flags, including
"HAVE_INTEL_CHIPSET_LOCKDOWN".

In this commit, "ibexpeak", "bd82x6x", "fsp_bd82x6x", and "lynxpoint"
have the flag "HAVE_INTEL_CHIPSET_LOCKDOWN" selected.

The change is only well tested on Sandy Bridge, my Lenovo x230.

Change-Id: I43d4142291c8737b29738c41e8c484328b297b55
Signed-off-by: Bill XIE <persmule@gmail.com>
Reviewed-on: https://review.coreboot.org/21129
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Nico Huber <nico.h@gmx.de>
This commit is contained in:
Bill XIE 2017-08-22 16:26:22 +08:00 committed by Nico Huber
parent f9267f9bcd
commit d533b16669
9 changed files with 50 additions and 6 deletions

View File

@ -39,6 +39,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
select HAVE_INTEL_FIRMWARE select HAVE_INTEL_FIRMWARE
select SOUTHBRIDGE_INTEL_COMMON_GPIO select SOUTHBRIDGE_INTEL_COMMON_GPIO
select RTC select RTC
select HAVE_INTEL_CHIPSET_LOCKDOWN
config EHCI_BAR config EHCI_BAR
hex hex

View File

@ -829,9 +829,12 @@ static void southbridge_fill_ssdt(device_t device)
static void lpc_final(struct device *dev) static void lpc_final(struct device *dev)
{ {
if (CONFIG_HAVE_SMI_HANDLER && acpi_is_wakeup_s3()) {
/* Call SMM finalize() handlers before resume */ /* Call SMM finalize() handlers before resume */
outb(0xcb, 0xb2); if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
if (IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN) ||
acpi_is_wakeup_s3()) {
outb(APM_CNT_FINALIZE, APM_CNT);
}
} }
} }

View File

@ -4,3 +4,16 @@ config SOUTHBRIDGE_INTEL_COMMON_GPIO
def_bool n def_bool n
config SOUTHBRIDGE_INTEL_COMMON_SMBUS config SOUTHBRIDGE_INTEL_COMMON_SMBUS
def_bool n def_bool n
config HAVE_INTEL_CHIPSET_LOCKDOWN
def_bool n
config INTEL_CHIPSET_LOCKDOWN
depends on HAVE_INTEL_CHIPSET_LOCKDOWN && HAVE_SMI_HANDLER && !CHROMEOS
#ChromeOS's payload seems to handle finalization on its on.
bool "Lock down chipset in coreboot"
default y
help
Some registers within host bridge on particular chipsets should be
locked down on each normal boot path (done by either coreboot or payload)
and S3 resume (always done by coreboot). Select this to let coreboot
to do this on normal boot path.

View File

@ -33,6 +33,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
select HAVE_INTEL_FIRMWARE select HAVE_INTEL_FIRMWARE
select SOUTHBRIDGE_INTEL_COMMON select SOUTHBRIDGE_INTEL_COMMON
select SOUTHBRIDGE_INTEL_COMMON_SMBUS select SOUTHBRIDGE_INTEL_COMMON_SMBUS
select HAVE_INTEL_CHIPSET_LOCKDOWN
config EHCI_BAR config EHCI_BAR
hex hex

View File

@ -739,6 +739,17 @@ void acpi_fill_fadt(acpi_fadt_t *fadt)
fadt->x_gpe1_blk.addrh = 0x0; fadt->x_gpe1_blk.addrh = 0x0;
} }
static void lpc_final(struct device *dev)
{
/* Call SMM finalize() handlers before resume */
if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
if (IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN) ||
acpi_is_wakeup_s3()) {
outb(APM_CNT_FINALIZE, APM_CNT);
}
}
}
static struct pci_operations pci_ops = { static struct pci_operations pci_ops = {
.set_subsystem = set_subsystem, .set_subsystem = set_subsystem,
}; };
@ -750,6 +761,7 @@ static struct device_operations device_ops = {
.write_acpi_tables = acpi_write_hpet, .write_acpi_tables = acpi_write_hpet,
.acpi_inject_dsdt_generator = southbridge_inject_dsdt, .acpi_inject_dsdt_generator = southbridge_inject_dsdt,
.init = lpc_init, .init = lpc_init,
.final = lpc_final,
.enable = pch_lpc_enable, .enable = pch_lpc_enable,
.scan_bus = scan_lpc_bus, .scan_bus = scan_lpc_bus,
.ops_pci = &pci_ops, .ops_pci = &pci_ops,

View File

@ -36,6 +36,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
select ACPI_SATA_GENERATOR select ACPI_SATA_GENERATOR
select HAVE_INTEL_FIRMWARE select HAVE_INTEL_FIRMWARE
select SOUTHBRIDGE_INTEL_COMMON_GPIO select SOUTHBRIDGE_INTEL_COMMON_GPIO
select HAVE_INTEL_CHIPSET_LOCKDOWN
config EHCI_BAR config EHCI_BAR
hex hex

View File

@ -782,6 +782,17 @@ static void southbridge_fill_ssdt(device_t device)
intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8); intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8);
} }
static void lpc_final(struct device *dev)
{
/* Call SMM finalize() handlers before resume */
if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
if (IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN) ||
acpi_is_wakeup_s3()) {
outb(APM_CNT_FINALIZE, APM_CNT);
}
}
}
static struct pci_operations pci_ops = { static struct pci_operations pci_ops = {
.set_subsystem = set_subsystem, .set_subsystem = set_subsystem,
}; };
@ -794,6 +805,7 @@ static struct device_operations device_ops = {
.acpi_fill_ssdt_generator = southbridge_fill_ssdt, .acpi_fill_ssdt_generator = southbridge_fill_ssdt,
.write_acpi_tables = acpi_write_hpet, .write_acpi_tables = acpi_write_hpet,
.init = lpc_init, .init = lpc_init,
.final = lpc_final,
.enable = pch_lpc_enable, .enable = pch_lpc_enable,
.scan_bus = scan_lpc_bus, .scan_bus = scan_lpc_bus,
.ops_pci = &pci_ops, .ops_pci = &pci_ops,

View File

@ -34,6 +34,7 @@ config SOUTH_BRIDGE_OPTIONS # dummy
select HAVE_SPI_CONSOLE_SUPPORT select HAVE_SPI_CONSOLE_SUPPORT
select RTC select RTC
select SOUTHBRIDGE_INTEL_COMMON_GPIO if !INTEL_LYNXPOINT_LP select SOUTHBRIDGE_INTEL_COMMON_GPIO if !INTEL_LYNXPOINT_LP
select HAVE_INTEL_CHIPSET_LOCKDOWN
config INTEL_LYNXPOINT_LP config INTEL_LYNXPOINT_LP
bool bool

View File

@ -121,13 +121,13 @@ void smm_setup_structures(void *gnvs, void *tcg, void *smi1)
} }
/* /*
* Finalize system before payload boot if not in ChromeOS environment. * Finalize system before payload boot if INTEL_CHIPSET_LOCKDOWN=y
*/ */
#if !IS_ENABLED(CONFIG_CHROMEOS) #if IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN)
static void finalize_boot(void *unused) static void finalize_boot(void *unused)
{ {
outb(0xcb, 0xb2); outb(APM_CNT_FINALIZE, APM_CNT);
} }
BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, finalize_boot, NULL); BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, finalize_boot, NULL);