diff options
author | Marco Peereboom <marco@cvs.openbsd.org> | 2009-02-19 21:02:06 +0000 |
---|---|---|
committer | Marco Peereboom <marco@cvs.openbsd.org> | 2009-02-19 21:02:06 +0000 |
commit | 748c385494ee5d641b7e648df28568538e41467c (patch) | |
tree | 9b3648d5d080c29915d0f71b7a8d9c490046223d /sys/arch/amd64 | |
parent | 6fb68817a3957ab44390ea949e41e4b949d653a7 (diff) |
suspend/resume bits so that we can develop this in tree. This is disabled.
code from mlarkin and me
help from art,toby,jordan and several others
ok jordan, go for it deraadt
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/acpi_machdep.c | 71 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/acpi_wakecode.S | 26 |
2 files changed, 77 insertions, 20 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index 24cdfc7b58b..f6a5f98e30f 100644 --- a/sys/arch/amd64/amd64/acpi_machdep.c +++ b/sys/arch/amd64/amd64/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.15 2009/02/15 02:03:40 marco Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.16 2009/02/19 21:02:05 marco Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -30,6 +30,7 @@ #include <dev/isa/isareg.h> #include <dev/acpi/acpireg.h> #include <dev/acpi/acpivar.h> +#include <dev/acpi/acpidev.h> #include "ioapic.h" @@ -171,4 +172,72 @@ acpi_attach_machdep(struct acpi_softc *sc) #endif /* ACPI_SLEEP_ENABLED */ } + +void +acpi_cpu_flush(struct acpi_softc *sc, int state) +{ + /* + * Flush write back caches since we'll lose them. + */ + if (state > ACPI_STATE_S1) + wbinvd(); +} +int +acpi_sleep_machdep(struct acpi_softc *sc, int state) +{ +#ifdef ACPI_SLEEP_ENABLED + + if (sc->sc_facs == NULL) { + printf("%s: acpi_sleep_machdep: no FACS\n", DEVNAME(sc)); + return (ENXIO); + } + + if (rcr3() != pmap_kernel()->pm_pdirpa) { + printf("%s: acpi_sleep_machdep: only kernel may sleep\n", + DEVNAME(sc)); + return (ENXIO); + } + + /* + * + * ACPI defines two wakeup vectors. One is used for ACPI 1.0 + * implementations - it's in the FACS table as wakeup_vector and + * indicates a 32-bit physical address containing real-mode wakeup + * code. + * + * The second wakeup vector is in the FACS table as + * x_wakeup_vector and indicates a 64-bit physical address + * containing protected-mode wakeup code. + * + */ + + sc->sc_facs->wakeup_vector = (u_int32_t)ACPI_TRAMPOLINE; + if (sc->sc_facs->version == 1) + sc->sc_facs->x_wakeup_vector = 0; + + disable_intr(); + + /* Copy the current cpu registers into a safe place for resume. */ + if (acpi_savecpu()) { + wbinvd(); + acpi_enter_sleep_state(sc, state); + panic("%s: acpi_enter_sleep_state failed", DEVNAME(sc)); + } + + /* + * On resume, the execution path will actually occur here. + * This is because we previously saved the stack location + * in acpi_savecpu, and issued a far jmp to the restore + * routine in the wakeup code. This means we are + * returning to the location immediately following the + * last call instruction - after the call to acpi_savecpu. + */ + + initrtclock(); + enable_intr(); +#endif /* ACPI_SLEEP_ENABLED */ + return 0; + } + + #endif /* ! SMALL_KERNEL */ diff --git a/sys/arch/amd64/amd64/acpi_wakecode.S b/sys/arch/amd64/amd64/acpi_wakecode.S index 777a9a13809..7da9a0a4b8a 100644 --- a/sys/arch/amd64/amd64/acpi_wakecode.S +++ b/sys/arch/amd64/amd64/acpi_wakecode.S @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_wakecode.S,v 1.2 2009/02/15 02:06:09 marco Exp $ */ +/* $OpenBSD: acpi_wakecode.S,v 1.3 2009/02/19 21:02:05 marco Exp $ */ /* * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org> * Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org> @@ -128,6 +128,7 @@ _C_LABEL(acpi_real_mode_resume): * laptops), we might not restore the proper VGA mode * on resume. Caveat emptor. */ + jmp nobiosreset /* XXX make this a tunable */ lcall $0xc000,$3 /* @@ -137,6 +138,7 @@ _C_LABEL(acpi_real_mode_resume): movw %cs,%ax movw %ax,%ds movw %ax,%ss +nobiosreset: /* * Set up esi to point to start of current routine's CS. @@ -152,7 +154,6 @@ _C_LABEL(acpi_real_mode_resume): 1: jmp 1f 1: - /* * We're about to enter protected mode, so we need a GDT for that. * Set up a temporary GDT describing 2 segments, one for code @@ -180,11 +181,10 @@ _C_LABEL(acpi_real_mode_resume): */ ljmpl $0x8, $acpi_protected_mode_trampoline -_ACPI_TRMP_LABEL(acpi_protected_mode_trampoline) -_C_LABEL(acpi_protected_mode_resume): .code32 .align 16 - +_ACPI_TRMP_LABEL(acpi_protected_mode_trampoline) +_C_LABEL(acpi_protected_mode_resume): nop /* @@ -257,13 +257,10 @@ _C_LABEL(acpi_protected_mode_resume): /* Enter long mode by making another intersegment jump */ ljmp $0x8, $acpi_long_mode_trampoline -_ACPI_TRMP_LABEL(acpi_long_mode_trampoline) -_C_LABEL(acpi_long_mode_resume): .code64 .align 16 - - - +_ACPI_TRMP_LABEL(acpi_long_mode_trampoline) +_C_LABEL(acpi_long_mode_resume): /* Restore the stashed copy of EFER we set aside earlier */ movl %ebx, %eax movl $MSR_EFER, %ecx @@ -353,8 +350,6 @@ _C_LABEL(acpi_long_mode_resume): xorq %rax, %rax jmp *acpi_saved_ret - - .align 8 _ACPI_TRMP_OFFSET(tmp_gdt) .word tmp_gdt_end - tmp_gdtable @@ -398,7 +393,6 @@ _ACPI_TRMP_LABEL(tmp_gdtable) */ .word 0xffff, 0 .byte 0, 0x93, 0xcf, 0 - _ACPI_TRMP_LABEL(tmp_gdt_end) .align 8 @@ -411,7 +405,6 @@ _ACPI_TRMP_LABEL(tmp_gdtable64) .quad 0x0000000000000000 .quad 0x00af9a000000ffff .quad 0x00cf92000000ffff - _ACPI_TRMP_LABEL(tmp_gdt64_end) .align 8 @@ -447,7 +440,6 @@ _ACPI_TRMP_LABEL(acpi_saved_r14) .quad 0 _ACPI_TRMP_LABEL(acpi_saved_r15) .quad 0 - _ACPI_TRMP_LABEL(acpi_saved_fl) .quad 0 _ACPI_TRMP_LABEL(acpi_saved_cr0) @@ -460,7 +452,6 @@ _ACPI_TRMP_LABEL(acpi_saved_cr4) .quad 0 _ACPI_TRMP_LABEL(acpi_saved_cr8) .quad 0 - _ACPI_TRMP_LABEL(acpi_saved_ret) .quad 0 @@ -563,7 +554,6 @@ NENTRY(acpi_savecpu) popq %rdx popq %rcx - sgdt acpi_saved_gdt sidt acpi_saved_idt sldt acpi_saved_ldt @@ -571,7 +561,5 @@ NENTRY(acpi_savecpu) movl $1, %eax ret - - #endif /* SMALL_KERNEL */ #endif /* NACPI > 0 */ |