diff options
-rw-r--r-- | src/arch/i386/boot/acpi.c | 37 | ||||
-rw-r--r-- | src/arch/i386/include/arch/acpi.h | 39 | ||||
-rw-r--r-- | src/boot/hardwaremain.c | 23 |
3 files changed, 70 insertions, 29 deletions
diff --git a/src/arch/i386/boot/acpi.c b/src/arch/i386/boot/acpi.c index c7046e1b31..b6aa19ff1b 100644 --- a/src/arch/i386/boot/acpi.c +++ b/src/arch/i386/boot/acpi.c @@ -1,8 +1,8 @@ /* * coreboot ACPI Table support * written by Stefan Reinauer <stepan@openbios.org> - * (C) 2004 SUSE LINUX AG - * (C) 2005 Stefan Reinauer + * Copyright (C) 2004 SUSE LINUX AG + * Copyright (C) 2005-2009 coresystems GmbH * * ACPI FADT, FACS, and DSDT table support added by * Nick Barker <nick.barker9@btinternet.com>, and those portions @@ -27,11 +27,6 @@ #include <arch/acpigen.h> #include <device/pci.h> -#if HAVE_ACPI_RESUME == 1 -/* this is to be filled by SB code - startup value what was found */ -u8 acpi_slp_type; -#endif - u8 acpi_checksum(u8 *table, u32 length) { u8 ret=0; @@ -81,7 +76,6 @@ int acpi_create_mcfg_mmconfig(acpi_mcfg_mmconfig_t *mmconfig, u32 base, u16 seg_ return (sizeof(acpi_mcfg_mmconfig_t)); } - int acpi_create_madt_lapic(acpi_madt_lapic_t *lapic, u8 cpu, u8 apic) { lapic->type=0; @@ -378,6 +372,29 @@ void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt) } #if HAVE_ACPI_RESUME == 1 +void suspend_resume(void) +{ + void *wake_vec; + +#if 0 +#if MEM_TRAIN_SEQ != 0 + #error "So far it works on AMD and MEM_TRAIN_SEQ == 0" +#endif + +#if _RAMBASE < 0x1F00000 + #error "For ACPI RESUME you need to have _RAMBASE at least 31MB" + #error "Chipset support (S3_NVRAM_EARLY and ACPI_IS_WAKEUP_EARLY functions and memory ctrl)" + #error "And coreboot memory reserved in mainboard.c" +#endif +#endif + /* if we happen to be resuming find wakeup vector and jump to OS */ + wake_vec = acpi_find_wakeup_vector(); + if (wake_vec) + acpi_jump_to_wakeup(wake_vec); +} + +/* this is to be filled by SB code - startup value what was found */ +u8 acpi_slp_type = 0; int acpi_get_sleep_type(void) { @@ -461,8 +478,10 @@ void *acpi_find_wakeup_vector(void) printk_debug("FADT found at %p\n", fadt); facs = fadt->firmware_ctrl; - if (facs == NULL) + if (facs == NULL) { + printk_debug("No FACS found, wake up from S3 not possible.\n"); return NULL; + } printk_debug("FACS found at %p\n", facs); wake_vec = (void *) facs->firmware_waking_vector; diff --git a/src/arch/i386/include/arch/acpi.h b/src/arch/i386/include/arch/acpi.h index 99bec4b30c..c2ed67971e 100644 --- a/src/arch/i386/include/arch/acpi.h +++ b/src/arch/i386/include/arch/acpi.h @@ -17,8 +17,10 @@ #include <stdint.h> +#if HAVE_ACPI_RESUME /* 0 = S0, 1 = S1 ...*/ extern u8 acpi_slp_type; +#endif #define RSDP_SIG "RSD PTR " /* RSDT Pointer signature */ #define RSDP_NAME "RSDP" @@ -277,6 +279,37 @@ typedef struct acpi_fadt { struct acpi_gen_regaddr x_gpe1_blk; } __attribute__ ((packed)) acpi_fadt_t; +#define ACPI_FADT_WBINVD (1 << 0) +#define ACPI_FADT_WBINVD_FLUSH (1 << 1) +#define ACPI_FADT_C1_SUPPORTED (1 << 2) +#define ACPI_FADT_C2_MP_SUPPORTED (1 << 3) +#define ACPI_FADT_POWER_BUTTON (1 << 4) +#define ACPI_FADT_SLEEP_BUTTON (1 << 5) +#define ACPI_FADT_FIXED_RTC (1 << 6) +#define ACPI_FADT_S4_RTC_WAKE (1 << 7) +#define ACPI_FADT_32BIT_TIMER (1 << 8) +#define ACPI_FADT_DOCKING_SUPPORTED (1 << 9) +#define ACPI_FADT_RESET_REGISTER (1 << 10) +#define ACPI_FADT_SEALED_CASE (1 << 11) +#define ACPI_FADT_HEADLESS (1 << 12) +#define ACPI_FADT_SLEEP_TYPE (1 << 13) +#define ACPI_FADT_PCI_EXPRESS_WAKE (1 << 14) +#define ACPI_FADT_PLATFORM_CLOCK (1 << 15) +#define ACPI_FADT_S4_RTC_VALID (1 << 16) +#define ACPI_FADT_REMOTE_POWER_ON (1 << 17) +#define ACPI_FADT_APIC_CLUSTER (1 << 18) +#define ACPI_FADT_APIC_PHYSICAL (1 << 19) + +enum acpi_preferred_pm_profiles { + PM_UNSPECIFIED = 0, + PM_DESKTOP = 1, + PM_MOBILE = 2, + PM_WORKSTATION = 3, + PM_ENTERPRISE = 4, + PM_SOHO_SERVER = 5, + PM_APPLIANCE_PC = 6 +}; + /* FACS */ typedef struct acpi_facs { char signature[4]; @@ -333,10 +366,14 @@ void acpi_create_facs(acpi_facs_t *facs); void acpi_write_rsdt(acpi_rsdt_t *rsdt); void acpi_write_rsdp(acpi_rsdp_t *rsdp, acpi_rsdt_t *rsdt); + +#if HAVE_ACPI_RESUME +void suspend_resume(void); void *acpi_find_wakeup_vector(void); void *acpi_get_wakeup_rsdp(void); -extern void acpi_jmp_to_realm_wakeup(u32 linear_addr); +void acpi_jmp_to_realm_wakeup(u32 linear_addr); void acpi_jump_to_wakeup(void *wakeup_addr); +#endif unsigned long acpi_add_ssdt_pstates(acpi_rsdt_t *rsdt, unsigned long current); diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c index 99c4d3079c..c22754fe28 100644 --- a/src/boot/hardwaremain.c +++ b/src/boot/hardwaremain.c @@ -28,16 +28,16 @@ it with the version available from LANL. #include <console/console.h> #include <version.h> -#include <boot/tables.h> #include <device/device.h> #include <device/pci.h> #include <delay.h> #include <stdlib.h> #include <part/hard_reset.h> #include <part/init_timer.h> +#include <boot/tables.h> #include <boot/elf.h> #include <cbfs.h> -#if HAVE_ACPI_RESUME == 1 +#if HAVE_ACPI_RESUME #include <arch/acpi.h> #endif @@ -54,9 +54,6 @@ it with the version available from LANL. void hardwaremain(int boot_complete) { struct lb_memory *lb_mem; -#if HAVE_ACPI_RESUME == 1 - void *wake_vec; -#endif post_code(0x80); @@ -92,20 +89,8 @@ void hardwaremain(int boot_complete) post_code(0x89); #if HAVE_ACPI_RESUME == 1 - -#if MEM_TRAIN_SEQ != 0 - #error "So far it works on AMD and MEM_TRAIN_SEQ == 0" -#endif - -#if _RAMBASE < 0x1F00000 - #error "For ACPI RESUME you need to have _RAMBASE at least 31MB" - #error "Chipset support (S3_NVRAM_EARLY and ACPI_IS_WAKEUP_EARLY functions and memory ctrl)" - #error "And coreboot memory reserved in mainboard.c" -#endif - /* if we happen to be resuming find wakeup vector and jump to OS */ - wake_vec = acpi_find_wakeup_vector(); - if (wake_vec) - acpi_jump_to_wakeup(wake_vec); + suspend_resume(); + post_code(0x8a); #endif /* Now that we have collected all of our information |