Add acpi_is_wakeup_early to i82371eb and P2B. Build fix for src/arch/i386/boot/acpi.c if !CONFIG_SMP Also check for acpi_slp_type 2 in acpi_is_wakeup, since S2 uses the same acpi wakeup vector as S3. Other chipsets so far only ever set acpi_slp_type to 0 and 3.
Abuild-tested.
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: coreboot-svn-p2b/src/mainboard/asus/p2b/romstage.c =================================================================== --- coreboot-svn-p2b.orig/src/mainboard/asus/p2b/romstage.c 2010-11-27 11:48:28.000000000 +0100 +++ coreboot-svn-p2b/src/mainboard/asus/p2b/romstage.c 2010-11-27 11:55:12.000000000 +0100 @@ -36,6 +36,8 @@
#define SERIAL_DEV PNP_DEV(0x3f0, W83977TF_SP1)
+void enable_pm(void); +int acpi_is_wakeup_early(void); void enable_smbus(void); int smbus_read_byte(u8 device, u8 address);
@@ -46,14 +48,23 @@
void main(unsigned long bist) { + u16 boot_mode; + w83977tf_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE); uart_init(); console_init(); report_bist_failure(bist);
+ enable_pm(); + boot_mode = acpi_is_wakeup_early(); + enable_smbus(); dump_spd_registers(); - sdram_set_registers(); - sdram_set_spd_registers(); - sdram_enable(); + if (boot_mode == 5 || boot_mode == 0) { + /* should't be needed on warm boot (boot_mode 0), + * but can't hurt... */ + sdram_set_registers(); + sdram_set_spd_registers(); + sdram_enable(); + } } Index: coreboot-svn-p2b/src/arch/i386/boot/acpi.c =================================================================== --- coreboot-svn-p2b.orig/src/arch/i386/boot/acpi.c 2010-11-27 11:48:28.000000000 +0100 +++ coreboot-svn-p2b/src/arch/i386/boot/acpi.c 2010-11-27 11:48:41.000000000 +0100 @@ -481,7 +481,7 @@
static int acpi_is_wakeup(void) { - return (acpi_slp_type == 3); + return (acpi_slp_type == 3 || acpi_slp_type == 2); }
static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) @@ -567,9 +567,11 @@ return wake_vec; }
+#if CONFIG_SMP == 1 extern char *lowmem_backup; extern char *lowmem_backup_ptr; extern int lowmem_backup_size; +#endif
#define WAKEUP_BASE 0x600
@@ -588,12 +590,14 @@ return; }
+#if CONFIG_SMP == 1 // FIXME: This should go into the ACPI backup memory, too. No pork saussages. /* * Just restore the SMP trampoline and continue with wakeup on * assembly level. */ memcpy(lowmem_backup_ptr, lowmem_backup, lowmem_backup_size); +#endif
/* Copy wakeup trampoline in place. */ memcpy((void *)WAKEUP_BASE, &__wakeup, (size_t)&__wakeup_size); Index: coreboot-svn-p2b/src/southbridge/intel/i82371eb/Kconfig =================================================================== --- coreboot-svn-p2b.orig/src/southbridge/intel/i82371eb/Kconfig 2010-11-27 11:48:28.000000000 +0100 +++ coreboot-svn-p2b/src/southbridge/intel/i82371eb/Kconfig 2010-11-27 11:48:41.000000000 +0100 @@ -1,6 +1,7 @@ config SOUTHBRIDGE_INTEL_I82371EB bool select TINY_BOOTBLOCK + select HAVE_ACPI_RESUME if HAVE_ACPI_TABLES
config BOOTBLOCK_SOUTHBRIDGE_INIT string Index: coreboot-svn-p2b/src/southbridge/intel/i82371eb/i82371eb_smbus.c =================================================================== --- coreboot-svn-p2b.orig/src/southbridge/intel/i82371eb/i82371eb_smbus.c 2010-11-27 11:48:28.000000000 +0100 +++ coreboot-svn-p2b/src/southbridge/intel/i82371eb/i82371eb_smbus.c 2010-11-27 11:51:16.000000000 +0100 @@ -31,6 +31,10 @@ #include "i82371eb.h" #include "i82371eb_smbus.h"
+#if CONFIG_HAVE_ACPI_RESUME == 1 +extern u8 acpi_slp_type; +#endif + static void pwrmgt_enable(struct device *dev) { struct southbridge_intel_i82371eb_config *sb = dev->chip_info; @@ -87,6 +91,24 @@ outw(0xffff, DEFAULT_PMBASE + GLBSTS); outl(0xffffffff, DEFAULT_PMBASE + DEVSTS);
+#if CONFIG_HAVE_ACPI_RESUME == 1 + reg = (inw(DEFAULT_PMBASE + PMCNTRL) >> 10) & 7; + switch (reg) { + case 1: + acpi_slp_type = 3; + break; + case 2: + case 3: + acpi_slp_type = 2; + break; + default: + acpi_slp_type = 5; + break; + } + printk(BIOS_INFO, + "%s: acpi_slp_type=%d!\n", __func__, acpi_slp_type); +#endif + /* set pmcntrl default */ outw(SUS_TYP_S0|SCI_EN, DEFAULT_PMBASE + PMCNTRL); } Index: coreboot-svn-p2b/src/southbridge/intel/i82371eb/i82371eb_early_pm.c =================================================================== --- coreboot-svn-p2b.orig/src/southbridge/intel/i82371eb/i82371eb_early_pm.c 2010-11-27 11:48:28.000000000 +0100 +++ coreboot-svn-p2b/src/southbridge/intel/i82371eb/i82371eb_early_pm.c 2010-11-27 11:48:41.000000000 +0100 @@ -51,3 +51,48 @@ reg8 |= PMIOSE; pci_write_config8(dev, PMREGMISC, reg8); } + +int acpi_is_wakeup_early(void); + +/* + * Intel i82371eb (piix4e) datasheet, section 7.2.3, page 142: + * + * 000b / 0x0: soft off/suspend to disk (soff/std) S5 + * 001b / 0x1: suspend to ram (str) S3 + * 010b / 0x2: powered on suspend, context lost (poscl) S2 + * Note: 'context lost' menas the cpu restarts at the reset vector + * 011b / 0x3: powered on suspend, cpu context lost (posccl) S1 + * Note: Looks like 'cpu context lost' does _not_ mean the cpu + * restarts at the reset vector. Most likely only caches + * are lost, so both 0x3 and 0x4 map to acpi S1 + * 100b / 0x4: powered on suspend, context maintained (pos) S1 + * 101b / 0x5: working (clock control) S0 + * 110b / 0x6: reserved + * 111b / 0x7: reserved + */ +static const u8 acpi_sus_to_slp_typ[8] = { + 5, 3, 2, 1, 1, 0, 0, 0 +}; + +int acpi_is_wakeup_early(void) +{ + u16 tmp, result; + + print_debug(__func__); + print_debug("\n"); + + tmp = inw(DEFAULT_PMBASE + PMCNTRL); + print_debug(" pmcntrl="); + print_debug_hex16(tmp); + print_debug("\n"); + + result = 5; /* S5, system came out of power-off */ + tmp = (tmp >> 10) & 7; + result = acpi_sus_to_slp_typ[tmp]; + + print_debug(" boot_mode="); + print_debug_hex8(result); + print_debug("\n"); + + return result; +}