intel/i945: Use romstage_handoff for S3
Don't use scratchpad registers when we have romstage_handoff to pass S3 resume flag. Scratchpad register was read too late in ramstage so acpi_is_wakeup_s3() did not evaluate correctly. This fixes low memory corruption at 0x1000-0x102c and the lack of coreboot tables (util/cbmem not working) after S3 resume. This also fixes console log from reporting early in ramstage "Normal boot" while on "S3 resume" path. Change-Id: I2922a15a90d2f8272c3482579bdd96f8f33e9705 Signed-off-by: Kyösti Mälkki <kyosti.malkki@gmail.com> Reviewed-on: https://review.coreboot.org/17675 Tested-by: build bot (Jenkins) Reviewed-by: Aaron Durbin <adurbin@chromium.org>
This commit is contained in:
parent
a6ac187731
commit
8183025be9
|
@ -17,12 +17,12 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
|
#include <arch/acpi.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <device/pci_ops.h>
|
#include <device/pci_ops.h>
|
||||||
#include <arch/io.h>
|
|
||||||
#include <ec/lenovo/pmh7/pmh7.h>
|
#include <ec/lenovo/pmh7/pmh7.h>
|
||||||
#include <ec/acpi/ec.h>
|
#include <ec/acpi/ec.h>
|
||||||
#include <ec/lenovo/h8/h8.h>
|
#include <ec/lenovo/h8/h8.h>
|
||||||
|
@ -49,13 +49,12 @@ int get_cst_entries(acpi_cstate_t **entries)
|
||||||
static void mainboard_init(device_t dev)
|
static void mainboard_init(device_t dev)
|
||||||
{
|
{
|
||||||
struct southbridge_intel_i82801gx_config *config;
|
struct southbridge_intel_i82801gx_config *config;
|
||||||
device_t dev0, idedev;
|
device_t idedev;
|
||||||
|
|
||||||
install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_DEFAULT, PANEL, 3);
|
install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_DEFAULT, PANEL, 3);
|
||||||
|
|
||||||
/* If we're resuming from suspend, blink suspend LED */
|
/* If we're resuming from suspend, blink suspend LED */
|
||||||
dev0 = dev_find_slot(0, PCI_DEVFN(0,0));
|
if (acpi_is_wakeup_s3())
|
||||||
if (dev0 && pci_read_config32(dev0, SKPAD) == SKPAD_ACPI_S3_MAGIC)
|
|
||||||
ec_write(0x0c, 0xc7);
|
ec_write(0x0c, 0xc7);
|
||||||
|
|
||||||
idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1));
|
idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1));
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
|
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <device/device.h>
|
#include <device/device.h>
|
||||||
|
#include <arch/acpi.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
#include <delay.h>
|
#include <delay.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <device/pci_ops.h>
|
#include <device/pci_ops.h>
|
||||||
#include <device/pci_ids.h>
|
#include <device/pci_ids.h>
|
||||||
#include <arch/io.h>
|
|
||||||
#include <arch/interrupt.h>
|
#include <arch/interrupt.h>
|
||||||
#include <ec/lenovo/pmh7/pmh7.h>
|
#include <ec/lenovo/pmh7/pmh7.h>
|
||||||
#include <ec/acpi/ec.h>
|
#include <ec/acpi/ec.h>
|
||||||
|
@ -79,7 +79,7 @@ int get_cst_entries(acpi_cstate_t **entries)
|
||||||
|
|
||||||
static void mainboard_init(device_t dev)
|
static void mainboard_init(device_t dev)
|
||||||
{
|
{
|
||||||
device_t dev0, idedev, sdhci_dev;
|
device_t idedev, sdhci_dev;
|
||||||
|
|
||||||
ec_clr_bit(0x03, 2);
|
ec_clr_bit(0x03, 2);
|
||||||
|
|
||||||
|
@ -91,8 +91,7 @@ static void mainboard_init(device_t dev)
|
||||||
install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_DEFAULT, PANEL, 3);
|
install_intel_vga_int15_handler(GMA_INT15_ACTIVE_LFP_INT_LVDS, GMA_INT15_PANEL_FIT_DEFAULT, PANEL, 3);
|
||||||
|
|
||||||
/* If we're resuming from suspend, blink suspend LED */
|
/* If we're resuming from suspend, blink suspend LED */
|
||||||
dev0 = dev_find_slot(0, PCI_DEVFN(0,0));
|
if (acpi_is_wakeup_s3())
|
||||||
if (dev0 && pci_read_config32(dev0, SKPAD) == SKPAD_ACPI_S3_MAGIC)
|
|
||||||
ec_write(0x0c, 0xc7);
|
ec_write(0x0c, 0xc7);
|
||||||
|
|
||||||
idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1));
|
idedev = dev_find_slot(0, PCI_DEVFN(0x1f,1));
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <device/pci_def.h>
|
#include <device/pci_def.h>
|
||||||
#include <cbmem.h>
|
#include <cbmem.h>
|
||||||
#include <halt.h>
|
#include <halt.h>
|
||||||
|
#include <romstage_handoff.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "i945.h"
|
#include "i945.h"
|
||||||
#include <pc80/mc146818rtc.h>
|
#include <pc80/mc146818rtc.h>
|
||||||
|
@ -197,7 +198,6 @@ static void i945_setup_bars(void)
|
||||||
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM5, 0x33);
|
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM5, 0x33);
|
||||||
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33);
|
pci_write_config8(PCI_DEV(0, 0x00, 0), PAM6, 0x33);
|
||||||
|
|
||||||
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD, SKPAD_NORMAL_BOOT_MAGIC);
|
|
||||||
printk(BIOS_DEBUG, " done.\n");
|
printk(BIOS_DEBUG, " done.\n");
|
||||||
|
|
||||||
/* Wait for MCH BAR to come up */
|
/* Wait for MCH BAR to come up */
|
||||||
|
@ -901,15 +901,7 @@ static void i945_prepare_resume(int s3resume)
|
||||||
|
|
||||||
cbmem_was_initted = !cbmem_recovery(s3resume);
|
cbmem_was_initted = !cbmem_recovery(s3resume);
|
||||||
|
|
||||||
/* If there is no high memory area, we didn't boot before, so
|
romstage_handoff_init(cbmem_was_initted && s3resume);
|
||||||
* this is not a resume. In that case we just create the cbmem toc.
|
|
||||||
*/
|
|
||||||
if (s3resume && cbmem_was_initted) {
|
|
||||||
|
|
||||||
/* Magic for S3 resume */
|
|
||||||
pci_write_config32(PCI_DEV(0, 0x00, 0), SKPAD,
|
|
||||||
SKPAD_ACPI_S3_MAGIC);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void i945_late_initialization(int s3resume)
|
void i945_late_initialization(int s3resume)
|
||||||
|
|
|
@ -175,26 +175,6 @@ static void intel_set_subsystem(device_t dev, unsigned vendor, unsigned device)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CONFIG_HAVE_ACPI_RESUME
|
|
||||||
static void northbridge_init(struct device *dev)
|
|
||||||
{
|
|
||||||
switch (pci_read_config32(dev, SKPAD)) {
|
|
||||||
case SKPAD_NORMAL_BOOT_MAGIC:
|
|
||||||
printk(BIOS_DEBUG, "Normal boot.\n");
|
|
||||||
acpi_slp_type = 0;
|
|
||||||
break;
|
|
||||||
case SKPAD_ACPI_S3_MAGIC:
|
|
||||||
printk(BIOS_DEBUG, "S3 Resume.\n");
|
|
||||||
acpi_slp_type = 3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printk(BIOS_DEBUG, "Unknown boot method, assuming normal.\n");
|
|
||||||
acpi_slp_type = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static struct pci_operations intel_pci_ops = {
|
static struct pci_operations intel_pci_ops = {
|
||||||
.set_subsystem = intel_set_subsystem,
|
.set_subsystem = intel_set_subsystem,
|
||||||
};
|
};
|
||||||
|
@ -204,9 +184,6 @@ static struct device_operations mc_ops = {
|
||||||
.set_resources = pci_dev_set_resources,
|
.set_resources = pci_dev_set_resources,
|
||||||
.enable_resources = pci_dev_enable_resources,
|
.enable_resources = pci_dev_enable_resources,
|
||||||
.acpi_fill_ssdt_generator = generate_cpu_entries,
|
.acpi_fill_ssdt_generator = generate_cpu_entries,
|
||||||
#if CONFIG_HAVE_ACPI_RESUME
|
|
||||||
.init = northbridge_init,
|
|
||||||
#endif
|
|
||||||
.scan_bus = 0,
|
.scan_bus = 0,
|
||||||
.ops_pci = &intel_pci_ops,
|
.ops_pci = &intel_pci_ops,
|
||||||
};
|
};
|
||||||
|
|
|
@ -375,7 +375,5 @@ int southbridge_detect_s3_resume(void);
|
||||||
#define SS_CNT 0x50
|
#define SS_CNT 0x50
|
||||||
#define C3_RES 0x54
|
#define C3_RES 0x54
|
||||||
|
|
||||||
#define SKPAD_ACPI_S3_MAGIC 0xcafed00d
|
|
||||||
#define SKPAD_NORMAL_BOOT_MAGIC 0xcafebabe
|
|
||||||
#endif /* __ACPI__ */
|
#endif /* __ACPI__ */
|
||||||
#endif /* SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H */
|
#endif /* SOUTHBRIDGE_INTEL_I82801GX_I82801GX_H */
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#include <device/pci.h>
|
#include <device/pci.h>
|
||||||
#include <console/console.h>
|
#include <console/console.h>
|
||||||
#include <arch/io.h>
|
#include <arch/io.h>
|
||||||
|
#include <arch/acpi.h>
|
||||||
#include <cpu/cpu.h>
|
#include <cpu/cpu.h>
|
||||||
#include <cpu/x86/cache.h>
|
#include <cpu/x86/cache.h>
|
||||||
#include <cpu/x86/smm.h>
|
#include <cpu/x86/smm.h>
|
||||||
|
@ -313,16 +314,6 @@ static void smm_relocate(void)
|
||||||
|
|
||||||
static int smm_handler_copied = 0;
|
static int smm_handler_copied = 0;
|
||||||
|
|
||||||
static int is_wakeup(void)
|
|
||||||
{
|
|
||||||
device_t dev0 = dev_find_slot(0, PCI_DEVFN(0,0));
|
|
||||||
|
|
||||||
if (!dev0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return pci_read_config32(dev0, 0xdc) == SKPAD_ACPI_S3_MAGIC;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smm_install(void)
|
static void smm_install(void)
|
||||||
{
|
{
|
||||||
/* The first CPU running this gets to copy the SMM handler. But not all
|
/* The first CPU running this gets to copy the SMM handler. But not all
|
||||||
|
@ -336,7 +327,7 @@ static void smm_install(void)
|
||||||
/* if we're resuming from S3, the SMM code is already in place,
|
/* if we're resuming from S3, the SMM code is already in place,
|
||||||
* so don't copy it again to keep the current SMM state */
|
* so don't copy it again to keep the current SMM state */
|
||||||
|
|
||||||
if (!is_wakeup()) {
|
if (!acpi_is_wakeup_s3()) {
|
||||||
/* enable the SMM memory window */
|
/* enable the SMM memory window */
|
||||||
pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
|
pci_write_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), SMRAM,
|
||||||
D_OPEN | G_SMRAME | C_BASE_SEG);
|
D_OPEN | G_SMRAME | C_BASE_SEG);
|
||||||
|
|
Loading…
Reference in New Issue