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; +}
On Sat, Nov 27, 2010 at 12:02:46PM +0100, Tobias Diedrich wrote:
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
Hm, not sure I feel confident enough to ack this, esp. as it might affect non-P2B boards, but for now here's a quick review below.
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);
Can this have negative effects for other ACPI-enabled chipsets/boards?
static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) @@ -567,9 +567,11 @@ return wake_vec; }
+#if CONFIG_SMP == 1
I think you can write most of the kconfig CONFIG_* variable checks as:
#if CONFIG_SMP
The "== 1" part is _usally_ not needed (there may be exceptions).
+#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);
I'd drop __func__ and make this a bit more userfriendly by wording it something like "ACPI sleep type = %d" or similar.
+/*
- Intel i82371eb (piix4e) datasheet, section 7.2.3, page 142:
Intel 82371EB (PIIX4E)
(cosmetics)
- 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
cpu -> CPU
+int acpi_is_wakeup_early(void) +{
- u16 tmp, result;
- print_debug(__func__);
- print_debug("\n");
Please use printk() in general, unless there's a technical reason to resort to print_debug().
Uwe.
2010/11/28 Uwe Hermann uwe@hermann-uwe.de
On Sat, Nov 27, 2010 at 12:02:46PM +0100, Tobias Diedrich wrote:
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.deranma%2Bcoreboot@tdiedrich.de
Hm, not sure I feel confident enough to ack this, esp. as it might affect non-P2B boards, but for now here's a quick review below.
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);
Can this have negative effects for other ACPI-enabled chipsets/boards?
static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) @@ -567,9 +567,11 @@ return wake_vec; }
+#if CONFIG_SMP == 1
I think you can write most of the kconfig CONFIG_* variable checks as:
#if CONFIG_SMP
The "== 1" part is _usally_ not needed (there may be exceptions).
+#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);
I'd drop __func__ and make this a bit more userfriendly by wording it something like "ACPI sleep type = %d" or similar.
+/*
- Intel i82371eb (piix4e) datasheet, section 7.2.3, page 142:
Intel 82371EB (PIIX4E)
(cosmetics)
- 000b / 0x0: soft off/suspend to disk (soff/std) S5
soff/std --> Soff/STD
- 001b / 0x1: suspend to ram (str) S3
str --> STR
- 010b / 0x2: powered on suspend, context lost (poscl) S2
poscl --> POSCL
- Note: 'context lost' menas the cpu restarts at the reset vector
menas --> means
- 011b / 0x3: powered on suspend, cpu context lost (posccl) S1
posccl --> POSCCL
Should we drop the binary notation and just keep the 0x.. values ?
- Note: Looks like 'cpu context lost' does _not_ mean the cpu
cpu -> CPU
+int acpi_is_wakeup_early(void) +{
u16 tmp, result;
print_debug(__func__);
print_debug("\n");
Please use printk() in general, unless there's a technical reason to resort to print_debug().
Uwe.
http://hermann-uwe.de | http://sigrok.org http://randomprojects.org | http://unmaintained-free-software.org
On 11/28/10 12:47 PM, Idwer Vollering wrote:
2010/11/28 Uwe Hermann <uwe@hermann-uwe.de mailto:uwe@hermann-uwe.de>
On Sat, Nov 27, 2010 at 12:02:46PM +0100, Tobias Diedrich wrote: > 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 <mailto:ranma%2Bcoreboot@tdiedrich.de>> Hm, not sure I feel confident enough to ack this, esp. as it might affect non-P2B boards, but for now here's a quick review below. > 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); Can this have negative effects for other ACPI-enabled chipsets/boards? > static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) > @@ -567,9 +567,11 @@ > return wake_vec; > } > > +#if CONFIG_SMP == 1 I think you can write most of the kconfig CONFIG_* variable checks as: #if CONFIG_SMP The "== 1" part is _usally_ not needed (there may be exceptions). > +#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); I'd drop __func__ and make this a bit more userfriendly by wording it something like "ACPI sleep type = %d" or similar. > +/* > + * Intel i82371eb (piix4e) datasheet, section 7.2.3, page 142: Intel 82371EB (PIIX4E) (cosmetics) > + * > + * 000b / 0x0: soft off/suspend to disk (soff/std) S5
soff/std --> Soff/STD
> + * 001b / 0x1: suspend to ram (str) S3
str --> STR
> + * 010b / 0x2: powered on suspend, context lost (poscl) S2
poscl --> POSCL
> + * Note: 'context lost' menas the cpu restarts at the reset vector
menas --> means
> + * 011b / 0x3: powered on suspend, cpu context lost (posccl) S1
posccl --> POSCCL
Should we drop the binary notation and just keep the 0x.. values ?
Yes, I think so, too. Referring to non-standard names such as POSCCL and POSCL is not useful.
Stefan
Add acpi_get_sleep_type() 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. Add _PTS/_WAK methods to turn off/on the CPU/case fans and blink the power LED while sleeping. acpi_get_sleep_type() is in a seperate file i82371eb_wakeup.c because it is used in both romstage and ramstage after patch 3/3, whereas i82371eb_early_pm.c is used only in romstage. I used the name acpi_get_sleep_type instead of acpi_is_wakeup_early because I think acpi_is_wakeup_early is a bit misleading as a name since it doesn't return a boolean value.
Patch 2/3 and 3/3 follow later.
Other chipsets so far only ever set acpi_slp_type to 0 and 3, so the added check for acpi_slp_type == 2 (resume from S2) should not change behaviour of other boards: northbridge/intel/i945/northbridge.c:256:extern u8 acpi_slp_type; northbridge/intel/i945/northbridge.c:263: acpi_slp_type=0; northbridge/intel/i945/northbridge.c:267: acpi_slp_type=3; northbridge/intel/i945/northbridge.c:271: acpi_slp_type=0; southbridge/intel/i82801gx/i82801gx_lpc.c:171:extern u8 acpi_slp_type; southbridge/via/vt8237r/vt8237r_lpc.c:149:extern u8 acpi_slp_type; southbridge/via/vt8237r/vt8237r_lpc.c:238: acpi_slp_type = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ; southbridge/via/vt8237r/vt8237r_lpc.c:239: printk(BIOS_DEBUG, "SLP_TYP type was %x %x\n", tmp, acpi_slp_type);
Signed-off-by: Tobias Diedrich ranma+coreboot@tdiedrich.de
---
Index: src/arch/i386/boot/acpi.c =================================================================== --- src/arch/i386/boot/acpi.c.orig 2010-11-30 01:15:37.000000000 +0100 +++ src/arch/i386/boot/acpi.c 2010-11-30 01:15:39.000000000 +0100 @@ -481,7 +481,8 @@
static int acpi_is_wakeup(void) { - return (acpi_slp_type == 3); + /* Both resume from S2 and resume from S3 restart at CPU reset */ + return (acpi_slp_type == 3 || acpi_slp_type == 2); }
static acpi_rsdp_t *valid_rsdp(acpi_rsdp_t *rsdp) @@ -567,9 +568,11 @@ return wake_vec; }
+#if CONFIG_SMP extern char *lowmem_backup; extern char *lowmem_backup_ptr; extern int lowmem_backup_size; +#endif
#define WAKEUP_BASE 0x600
@@ -588,12 +591,14 @@ return; }
+#if CONFIG_SMP // 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: src/southbridge/intel/i82371eb/Kconfig =================================================================== --- src/southbridge/intel/i82371eb/Kconfig.orig 2010-11-30 01:15:37.000000000 +0100 +++ src/southbridge/intel/i82371eb/Kconfig 2010-11-30 01:15:39.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: src/southbridge/intel/i82371eb/i82371eb_smbus.c =================================================================== --- src/southbridge/intel/i82371eb/i82371eb_smbus.c.orig 2010-11-30 01:15:37.000000000 +0100 +++ src/southbridge/intel/i82371eb/i82371eb_smbus.c 2010-11-30 01:15:39.000000000 +0100 @@ -31,6 +31,11 @@ #include "i82371eb.h" #include "i82371eb_smbus.h"
+#if CONFIG_HAVE_ACPI_RESUME == 1 +extern u8 acpi_slp_type; +int acpi_get_sleep_type(void); +#endif + static void pwrmgt_enable(struct device *dev) { struct southbridge_intel_i82371eb_config *sb = dev->chip_info; @@ -87,7 +92,13 @@ outw(0xffff, DEFAULT_PMBASE + GLBSTS); outl(0xffffffff, DEFAULT_PMBASE + DEVSTS);
- /* set pmcntrl default */ +#if CONFIG_HAVE_ACPI_RESUME == 1 + /* this reads PMCNTRL, so we have to call it before writing the + * default value */ + acpi_slp_type = acpi_get_sleep_type(); +#endif + + /* set PMCNTRL default */ outw(SUS_TYP_S0|SCI_EN, DEFAULT_PMBASE + PMCNTRL); }
Index: src/lib/cbmem.c =================================================================== --- src/lib/cbmem.c.orig 2010-11-30 01:15:37.000000000 +0100 +++ src/lib/cbmem.c 2010-11-30 01:15:39.000000000 +0100 @@ -198,8 +198,10 @@ void cbmem_initialize(void) { #if CONFIG_HAVE_ACPI_RESUME - if (acpi_slp_type == 3) { + printk(BIOS_DEBUG, "%s: acpi_slp_type=%d\n", __func__, acpi_slp_type); + if (acpi_slp_type == 3 || acpi_slp_type == 2) { if (!cbmem_reinit(high_tables_base)) { + printk(BIOS_DEBUG, "cbmem_reinit failed\n"); /* Something went wrong, our high memory area got wiped */ acpi_slp_type = 0; cbmem_init(high_tables_base, high_tables_size); Index: src/southbridge/intel/i82371eb/i82371eb_wakeup.c =================================================================== --- /dev/null 1970-01-01 00:00:00.000000000 +0000 +++ src/southbridge/intel/i82371eb/i82371eb_wakeup.c 2010-11-30 01:15:39.000000000 +0100 @@ -0,0 +1,59 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2010 Uwe Hermann uwe@hermann-uwe.de + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdint.h> +#include <arch/io.h> +#include <console/console.h> +#include "i82371eb.h" + +int acpi_get_sleep_type(void); + +/* + * Intel 82371EB (PIIX4E) datasheet, section 7.2.3, page 142 + * + * 0: soft off/suspend to disk S5 + * 1: suspend to ram S3 + * 2: powered on suspend, context lost S2 + * Note: 'context lost' means the CPU restarts at the reset + * vector + * 3: powered on suspend, CPU context lost 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 + * 4: powered on suspend, context maintained S1 + * 5: working (clock control) S0 + * 6: reserved + * 7: reserved + */ +static const u8 acpi_sus_to_slp_typ[8] = { + 5, 3, 2, 1, 1, 0, 0, 0 +}; + +int acpi_get_sleep_type(void) +{ + u16 reg, result; + + reg = inw(DEFAULT_PMBASE + PMCNTRL); + result = acpi_sus_to_slp_typ[(reg >> 10) & 7]; + + printk(BIOS_DEBUG, "Wakeup from ACPI sleep type S%d (PMCNTRL=%04x)\n", result, reg); + + return result; +} Index: src/southbridge/intel/i82371eb/Makefile.inc =================================================================== --- src/southbridge/intel/i82371eb/Makefile.inc.orig 2010-11-30 01:15:37.000000000 +0100 +++ src/southbridge/intel/i82371eb/Makefile.inc 2010-11-30 01:15:44.000000000 +0100 @@ -26,6 +26,7 @@ driver-y += i82371eb_reset.c driver-$(CONFIG_HAVE_ACPI_TABLES) += i82371eb_fadt.c driver-$(CONFIG_HAVE_ACPI_TABLES) += acpi_tables.c +driver-$(CONFIG_HAVE_ACPI_RESUME) += i82371eb_wakeup.c
romstage-y += i82371eb_early_pm.c romstage-y += i82371eb_early_smbus.c Index: src/mainboard/asus/p2b/dsdt.asl =================================================================== --- src/mainboard/asus/p2b/dsdt.asl.orig 2010-11-30 01:15:37.000000000 +0100 +++ src/mainboard/asus/p2b/dsdt.asl 2010-11-30 01:15:39.000000000 +0100 @@ -30,27 +30,51 @@ Processor (CPU0, 0x01, Add(DEFAULT_PMBASE, PCNTRL), 0x06) {} }
- /* For now only define 2 power states: - * - S0 which is fully on - * - S5 which is soft off - * Any others would involve declaring the wake up methods. - */ - - /* 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) s1 - 011b / 0x3: powered on suspend, cpu context lost (posccl) s2 - 100b / 0x4: powered on suspend, context maintained (pos) s4 - 101b / 0x5: working (clock control) s0 - 110b / 0x6: reserved - 111b / 0x7: reserved - */ + * Intel 82371EB (PIIX4E) datasheet, section 7.2.3, page 142 + * + * 0: soft off/suspend to disk S5 + * 1: suspend to ram S3 + * 2: powered on suspend, context lost S2 + * Note: 'context lost' means the CPU restarts at the reset + * vector + * 3: powered on suspend, CPU context lost 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 + * 4: powered on suspend, context maintained S1 + * 5: working (clock control) S0 + * 6: reserved + * 7: reserved + */ Name (_S0, Package () { 0x05, 0x05, 0x00, 0x00 }) Name (_S1, Package () { 0x03, 0x03, 0x00, 0x00 }) Name (_S5, Package () { 0x00, 0x00, 0x00, 0x00 })
+ OperationRegion (SIO1, SystemIO, Add(DEFAULT_PMBASE, GPO0), 2) + Field (SIO1, ByteAcc, NoLock, Preserve) + { + FANP, 1, /* CPU/case fan power */ + Offset (0x01), + PLED, 1, + } + + Method (_PTS, 1, NotSerialized) + { + /* Disable fan, blink power led */ + Store (Zero, FANP) + Store (Zero, PLED) + } + + Method (_WAK, 1, NotSerialized) + { + /* Re-enable fan, stop power led blinking */ + Store (One, FANP) + Store (One, PLED) + /* wake OK */ + Return(Package(0x02){0x00, 0x00}) + } + /* Root of the bus hierarchy */ Scope (_SB) {
On 11/28/10 12:36 PM, Uwe Hermann wrote:
On Sat, Nov 27, 2010 at 12:02:46PM +0100, Tobias Diedrich wrote:
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
Hm, not sure I feel confident enough to ack this, esp. as it might affect non-P2B boards, but for now here's a quick review below.
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);
Can this have negative effects for other ACPI-enabled chipsets/boards?
Oh yeah this is not good. acpi_slp_type must be 3 for wakeup.
+#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);
I'd drop __func__ and make this a bit more userfriendly by wording it something like "ACPI sleep type = %d" or similar.
why do you need 2,3 and 5 for sleep types anyways?
Stefan
Stefan Reinauer wrote:
On 11/28/10 12:36 PM, Uwe Hermann wrote:
On Sat, Nov 27, 2010 at 12:02:46PM +0100, Tobias Diedrich wrote:
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);
Can this have negative effects for other ACPI-enabled chipsets/boards?
Oh yeah this is not good. acpi_slp_type must be 3 for wakeup.
Wakeup can also be from S2 though. I assume the '3' is for S3 wakeup. Both are virtually identical though (acpi 4.0a, 15.1.2+15.1.3): S2: The S2 state is defined as a low wake latency sleep state. This state is similar to the S1 sleeping state where any context except for system memory may be lost. Additionally, control starts from the processor’s reset vector after the wake event.
S3: The S3 state is defined as a low wake-latency sleep state. From the software viewpoint, this state is functionally the same as the S2 state. The operational difference is that some Power Resources that may have been left ON in the S2 state may not be available to the S3 state. As such, some devices may be in a lower power state when the system is in S3 state than when the system is in the S2 state. Similarly, some device wake events can function in S2 but not S3.
+#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);
I'd drop __func__ and make this a bit more userfriendly by wording it something like "ACPI sleep type = %d" or similar.
why do you need 2,3 and 5 for sleep types anyways?
5 is wake from soft-off or hardreset, 0 would be boot due to soft-reset or hardreset. Wether hardreset looks like wake from soft-off or looks like soft-reset may depend on hardware, on i82371eb the PMCNTRL bits are default 0 which is equivalent to wake from S5. 2 and 3 are because I'd like to pass on wether the wake was from S2 or S3. E.g. on wake from S2 sio init may not be needed since power was not cut.
Uwe Hermann wrote:
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);
Can this have negative effects for other ACPI-enabled chipsets/boards?
No, I grepped the tree and the other chipsets supporting this only ever use 3 (S3). But since S2 is virtually identically to S3 from a wakeup perspective I thought adding the acpi_slp_type == 2 check would be the right thing to do. The other option would be to set acpi_slp_type to 3 even for S2 wakeup, but then there is not much sense in making it '3' either and it could be changed to be a 'is_wakeup_from_sleep' boolean type.
Tobias Diedrich wrote:
Uwe Hermann wrote:
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);
Can this have negative effects for other ACPI-enabled chipsets/boards?
No, I grepped the tree and the other chipsets supporting this only ever use 3 (S3). But since S2 is virtually identically to S3 from a wakeup perspective I thought adding the acpi_slp_type == 2 check would be the right thing to do. The other option would be to set acpi_slp_type to 3 even for S2 wakeup, but then there is not much sense in making it '3' either and it could be changed to be a 'is_wakeup_from_sleep' boolean type.
The relevant chipset hits are: northbridge/intel/i945/northbridge.c:256:extern u8 acpi_slp_type; northbridge/intel/i945/northbridge.c:263: acpi_slp_type=0; northbridge/intel/i945/northbridge.c:267: acpi_slp_type=3; northbridge/intel/i945/northbridge.c:271: acpi_slp_type=0; southbridge/intel/i82801gx/i82801gx_lpc.c:171:extern u8 acpi_slp_type; southbridge/via/vt8237r/vt8237r_lpc.c:149:extern u8 acpi_slp_type; southbridge/via/vt8237r/vt8237r_lpc.c:238: acpi_slp_type = ((tmp & (7 << 10)) >> 10) == 1 ? 3 : 0 ; southbridge/via/vt8237r/vt8237r_lpc.c:239: printk(BIOS_DEBUG, "SLP_TYP type was %x %x\n", tmp, acpi_slp_type);
Interestingly i82801gx_lpc.c has the extern but doesn't use it.
On Mon, Nov 29, 2010 at 10:02:01PM +0100, Tobias Diedrich wrote:
southbridge/intel/i82801gx/i82801gx_lpc.c:171:extern u8 acpi_slp_type;
Interestingly i82801gx_lpc.c has the extern but doesn't use it.
Probably some left-over. I'd drop it unless somebody objects.
Uwe.