diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/amd64/amd64/acpi_machdep.c | 26 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/acpi_wakecode.S | 576 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/cpu.c | 17 | ||||
-rw-r--r-- | sys/arch/amd64/amd64/machdep.c | 47 | ||||
-rw-r--r-- | sys/arch/amd64/conf/files.amd64 | 3 |
5 files changed, 650 insertions, 19 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c index 1a51f04b79f..24cdfc7b58b 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.14 2008/12/28 22:27:10 kettenis Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.15 2009/02/15 02:03:40 marco Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -33,6 +33,12 @@ #include "ioapic.h" +extern u_char acpi_real_mode_resume[], acpi_resume_end[]; +extern u_int32_t acpi_pdirpa; +extern paddr_t tramp_pdirpa; + +int acpi_savecpu(void); + #define ACPI_BIOS_RSDP_WINDOW_BASE 0xe0000 #define ACPI_BIOS_RSDP_WINDOW_SIZE 0x20000 @@ -148,5 +154,21 @@ acpi_attach_machdep(struct acpi_softc *sc) sc->sc_interrupt = isa_intr_establish(NULL, sc->sc_fadt->sci_int, IST_LEVEL, IPL_TTY, acpi_interrupt, sc, sc->sc_dev.dv_xname); cpuresetfn = acpi_reset; + +#ifdef ACPI_SLEEP_ENABLED + + /* + * Sanity check before setting up trampoline. + * Ensure the trampoline size is < PAGE_SIZE + */ + KASSERT(acpi_resume_end - acpi_real_mode_resume < PAGE_SIZE); + + bcopy(acpi_real_mode_resume, + (caddr_t)ACPI_TRAMPOLINE, + acpi_resume_end - acpi_real_mode_resume); + + acpi_pdirpa = tramp_pdirpa; + +#endif /* ACPI_SLEEP_ENABLED */ } -#endif /* SMALL_KERNEL */ +#endif /* ! SMALL_KERNEL */ diff --git a/sys/arch/amd64/amd64/acpi_wakecode.S b/sys/arch/amd64/amd64/acpi_wakecode.S new file mode 100644 index 00000000000..1d998447020 --- /dev/null +++ b/sys/arch/amd64/amd64/acpi_wakecode.S @@ -0,0 +1,576 @@ +/* + * Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org> + * Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright (c) 2008, 2009 Mike Larkin <mlarkin@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "acpi.h" + +#if NACPI > 0 +#ifndef SMALL_KERNEL + +#define _ACPI_WAKECODE + +#include "assym.h" +#include <machine/asm.h> +#include <machine/specialreg.h> +#include <machine/param.h> +#include <machine/segments.h> +#include <dev/acpi/acpivar.h> + +#define _ACPI_TRMP_LABEL(a) a = . - _C_LABEL(acpi_real_mode_resume) + ACPI_TRAMPOLINE +#define _ACPI_TRMP_OFFSET(a) a = . - _C_LABEL(acpi_real_mode_resume) + +/* + * On wakeup, we'll start executing at acpi_real_mode_resume. + * This is based on the wakeup vector previously stored with + * ACPI before we went to sleep. ACPI's wakeup vector is a + * physical address - in our case, it's calculated and mapped + * by the kernel and stuffed into a low page early in the boot + * process. + * + * We wakeup in real mode, at some phys addr based on the ACPI + * specification (cs = phys>>8, ip = phys & 0xF). For example, + * if our phys addr is 0x4000, we'd have cs=0x0400,ip=0 + * + * The wakeup code needs to do the following: + * 1. Reenable the video display + * 2. Enter 32 bit protected mode + * 3. Reenable paging + * 4. Enter long mode + * 5. Restore saved CPU registers + */ + + .text + .code16 + .align 4,0 + .global _C_LABEL(acpi_real_mode_resume) + .global _C_LABEL(acpi_protected_mode_resume) + .global _C_LABEL(acpi_long_mode_resume) + .global _C_LABEL(acpi_resume_end) + .global _C_LABEL(acpi_pdirpa) +_C_LABEL(acpi_real_mode_resume): + nop + cli + cld + + /* + * Set up segment registers for real mode. + * We'll only be in real mode for a moment, and we don't have + * ant real dependencies on data or stack, so we'll just use + * the code segment for data and stack (eg, a 64k memory space). + */ + movw %cs,%ax + movw %ax,%ds + movw %ax,%ss + + /* + * Set up stack to grow down from offset 0x0FFE. + * We will only be doing a few push/pops and no calls in real + * mode, so as long as the real mode code in the segment + * plus stack doesn't exceed 0x0FFE (4094) bytes, we'll be ok. + */ + movw $0x0FFE,%sp + + /* + * Clear flags + */ + pushl $0 + popfl + + /* + * Reset the video hardware (as best as we can). + * We call the video bios at c000:0003, similar to + * what the BIOS does on a machine restart. + * Note that this will only reset the video card, + * and may not enable LCDs or other attached displays. + * + * This will also put the hardware in "factory default" + * display mode, which may not match what we had + * when we went to sleep. On many machines (specifically + * laptops), we might not restore the proper VGA mode + * on resume. Caveat emptor. + */ + lcall $0xc000,$3 + + /* + * Restore our segment registers in case the call to + * reset the video hardware clobbered them. + */ + movw %cs,%ax + movw %ax,%ds + movw %ax,%ss + + /* + * Set up esi to point to start of current routine's CS. + */ + xorl %esi,%esi + movw %cs,%si + shll $4,%esi + + /* + * Flush instruction prefetch queue + */ + jmp 1f +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 + * extending from 0x00000000-0xffffffff and one for data + * with the same range. This GDT will only be in use for a short + * time, until we restore the saved GDT that we had when we went + * to sleep (although on i386, the saved GDT will most likely + * represent something similar based on machine/segment.h). + */ + data32 addr32 lgdt tmp_gdt + + /* + * Enable protected mode by setting the PE bit in CR0 + */ + mov %cr0,%eax + orl $(CR0_PE),%eax + mov %eax,%cr0 + + /* + * Force CPU into protected mode + * by making an intersegment jump (to ourselves, just a few lines + * down from here. We rely on the kernel to fixup the jump + * target addres previously. + * + */ + ljmpl $0x8, $acpi_protected_mode_trampoline + +_ACPI_TRMP_LABEL(acpi_protected_mode_trampoline) +_C_LABEL(acpi_protected_mode_resume): + .code32 + .align 16 + + nop + + /* + * We're in protected mode now, without paging enabled. + * + * Set up segment selectors for protected mode. + * We've already set up our cs via the intersegment jump earlier, + * but we need to set ds,es,fs,gs,ss to all point to the + * 4GB flat data segment we defined earlier. + */ + movw $GSEL(GDATA_SEL,SEL_KPL),%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%gs + movw %ax,%ss + movw %ax,%fs + + /* + * Reset ESP based on protected mode. We can do this here + * because we haven't put anything on the stack via a + * call or push that we haven't cleaned up already. + */ + movl %esi, %esp + addl $0x0FFE, %esp + + /* Set CR4 to something sane for entry into long mode */ + mov $(CR4_PAE|CR4_OSFXSR|CR4_OSXMMEXCPT|CR4_PSE),%eax + mov %eax,%cr4 + + /* + * Stash away our previously saved EFER in EBX. + * We have to make sure we don't write to any + * of the EFER reserved bits, so we zero those + * out here. + */ + movl acpi_saved_efer, %ebx + andl $(EFER_LME | EFER_LMA | EFER_NXE | EFER_SCE), %ebx + + /* + * Set up a temporary long mode GDT describing 2 + * segments, one for code and one for data. + */ + lgdt tmp_gdt64 + + /* Prepare to enter long mode by enabling LME in EFER */ + movl $MSR_EFER, %ecx + rdmsr + orl $EFER_LME, %eax + wrmsr + + /* Reenable paging using temporary cr3 */ + movl $acpi_pdirpa, %eax + movl (%eax), %eax + movl %eax, %cr3 + + /* Flush the prefetch queue again */ + jmp 1f +1: jmp 1f +1: + /* Reenable paging by setting the appropriate bits in CR0 */ + movl %cr0,%eax + orl $(CR0_PE|CR0_PG|CR0_NE|CR0_TS|CR0_MP|CR0_WP),%eax + movl %eax,%cr0 + + /* Flush the prefetch queue again */ + jmp 1f +1: jmp 1f +1: + + /* 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 + + + + /* Restore the stashed copy of EFER we set aside earlier */ + movl %ebx, %eax + movl $MSR_EFER, %ecx + wrmsr + + /* Load GDT based on our saved copy */ + lgdt acpi_saved_gdt + + /* Reset segment registers */ + movw $GSEL(GDATA_SEL, SEL_KPL),%ax + movw %ax,%ds + movw %ax,%es + movw %ax,%ss + + xorw %ax, %ax + movw %ax, %fs + movw %ax, %gs + + /* Restore registers - start with the MSRs */ + movl $MSR_FSBASE, %ecx + movl acpi_saved_fsbase, %eax + movl acpi_saved_fsbase+4, %edx + wrmsr + + movl $MSR_GSBASE, %ecx + movl acpi_saved_gsbase, %eax + movl acpi_saved_gsbase+4, %edx + wrmsr + + movl $MSR_KERNELGSBASE, %ecx + movl acpi_saved_kgs, %eax + movl acpi_saved_kgs+4, %edx + wrmsr + + /* Restore control registers */ + movq acpi_saved_cr8, %rax + movq %rax, %cr8 + movq acpi_saved_cr4, %rax + movq %rax, %cr4 + movq acpi_saved_cr3, %rax + movq %rax, %cr3 + + /* Flush the prefetch queue again */ + jmp 1f +1: jmp 1f +1: + movq acpi_saved_cr2, %rax + movq %rax, %cr2 + movq acpi_saved_cr0, %rax + movq %rax, %cr0 + + /* Flush the prefetch queue again */ + jmp 1f +1: jmp 1f +1: + + lldt acpi_saved_ldt + lidt acpi_saved_idt + + /* Restore the saved task register */ + xorq %rcx, %rcx + movw acpi_saved_tr, %cx + movq acpi_saved_gdt+2, %rax + andb $0xF9, 5(%rax,%rcx) + ltr %cx + + pushq acpi_saved_fl + popfq + + movq acpi_saved_rbx, %rbx + movq acpi_saved_rcx, %rcx + movq acpi_saved_rdx, %rdx + movq acpi_saved_rbp, %rbp + movq acpi_saved_rsi, %rsi + movq acpi_saved_rdi, %rdi + movq acpi_saved_rsp, %rsp + + movq acpi_saved_r8, %r8 + movq acpi_saved_r9, %r9 + movq acpi_saved_r10, %r10 + movq acpi_saved_r11, %r11 + movq acpi_saved_r12, %r12 + movq acpi_saved_r13, %r13 + movq acpi_saved_r14, %r14 + movq acpi_saved_r15, %r15 + + xorq %rax, %rax + jmp *acpi_saved_ret + + + + .align 8 +_ACPI_TRMP_OFFSET(tmp_gdt) + .word tmp_gdt_end - tmp_gdtable + .long tmp_gdtable + + .align 8,0 +_ACPI_TRMP_LABEL(tmp_gdtable) + /* + * null + */ + .word 0, 0 + .byte 0, 0, 0, 0 + /* + * Code + * Limit: 0xffffffff + * Base: 0x00000000 + * Descriptor Type: Code + * Segment Type: CRA + * Present: True + * Priv: 0 + * AVL: False + * 64-bit: False + * 32-bit: True + * + */ + .word 0xffff, 0 + .byte 0, 0x9f, 0xcf, 0 + + /* + * Data + * Limit: 0xffffffff + * Base: 0x00000000 + * Descriptor Type: + * Segment Type: W + * Present: True + * Priv: 0 + * AVL: False + * 64-bit: False + * 32-bit: True + * + */ + .word 0xffff, 0 + .byte 0, 0x93, 0xcf, 0 + +_ACPI_TRMP_LABEL(tmp_gdt_end) + + .align 8 +_ACPI_TRMP_LABEL(tmp_gdt64) + .word tmp_gdt64_end - tmp_gdtable64 + .long tmp_gdtable64 + + .align 8,0 +_ACPI_TRMP_LABEL(tmp_gdtable64) + .quad 0x0000000000000000 + .quad 0x00af9a000000ffff + .quad 0x00cf92000000ffff + +_ACPI_TRMP_LABEL(tmp_gdt64_end) + + .align 8 +_ACPI_TRMP_LABEL(acpi_saved_rbx) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rcx) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rdx) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rbp) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rsi) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rdi) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rsp) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_rsp) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_r8) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_r9) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_r10) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_r11) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_r12) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_r13) + .quad 0 +_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) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_cr2) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_cr3) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_cr4) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_cr8) + .quad 0 + +_ACPI_TRMP_LABEL(acpi_saved_ret) + .quad 0 + + .align 8 +_ACPI_TRMP_LABEL(acpi_saved_idt) + .space 10 + + .align 8 +_ACPI_TRMP_LABEL(acpi_saved_gdt) + .space 10 + + .align 8 +_ACPI_TRMP_LABEL(acpi_saved_ldt) + .space 10 + +_ACPI_TRMP_LABEL(acpi_saved_tr) + .short 0 + + .align 4 +_ACPI_TRMP_LABEL(acpi_saved_efer) + .long 0 + + .align 8 +_ACPI_TRMP_LABEL(acpi_saved_fsbase) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_gsbase) + .quad 0 +_ACPI_TRMP_LABEL(acpi_saved_kgs) + .quad 0 + + .align 4 +_ACPI_TRMP_LABEL(acpi_pdirpa) + .long 0 + + /* + * End of resume code (code copied to ACPI_TRAMPOLINE) + */ +_C_LABEL(acpi_resume_end): + + /* + * acpi_savecpu saves the processor's registers and flags + * for use during the ACPI suspend/resume process. + */ + +NENTRY(acpi_savecpu) + movq (%rsp), %rax + movq %rax, acpi_saved_ret + + movq %rbx, acpi_saved_rbx + movq %rcx, acpi_saved_rcx + movq %rdx, acpi_saved_rdx + movq %rbp, acpi_saved_rbp + movq %rsi, acpi_saved_rsi + movq %rdi, acpi_saved_rdi + movq %rsp, acpi_saved_rsp + + movq %r8, acpi_saved_r8 + movq %r9, acpi_saved_r9 + movq %r10, acpi_saved_r10 + movq %r11, acpi_saved_r11 + movq %r12, acpi_saved_r12 + movq %r13, acpi_saved_r13 + movq %r14, acpi_saved_r14 + movq %r15, acpi_saved_r15 + + pushfq + popq acpi_saved_fl + + movq %cr0, %rax + movq %rax, acpi_saved_cr0 + movq %cr2, %rax + movq %rax, acpi_saved_cr2 + movq %cr3, %rax + movq %rax, acpi_saved_cr3 + movq %cr4, %rax + movq %rax, acpi_saved_cr4 + movq %cr8, %rax + movq %rax, acpi_saved_cr8 + + pushq %rcx + pushq %rdx + movl $MSR_FSBASE, %ecx + rdmsr + movl %eax, acpi_saved_fsbase + movl %edx, acpi_saved_fsbase+4 + + movl $MSR_GSBASE, %ecx + rdmsr + movl %eax, acpi_saved_gsbase + movl %edx, acpi_saved_gsbase+4 + + movl $MSR_KERNELGSBASE, %ecx + rdmsr + movl %eax, acpi_saved_kgs + movl %edx, acpi_saved_kgs+4 + + movl $MSR_EFER, %ecx + rdmsr + movl %eax, acpi_saved_efer + popq %rdx + popq %rcx + + + sgdt acpi_saved_gdt + sidt acpi_saved_idt + sldt acpi_saved_ldt + str acpi_saved_tr + + movl $1, %eax + ret + + +#endif /* SMALL_KERNEL */ +#endif /* NACPI > 0 */ diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c index ee47764724e..de241a63372 100644 --- a/sys/arch/amd64/amd64/cpu.c +++ b/sys/arch/amd64/amd64/cpu.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cpu.c,v 1.21 2008/10/15 23:23:46 deraadt Exp $ */ +/* $OpenBSD: cpu.c,v 1.22 2009/02/15 02:03:40 marco Exp $ */ /* $NetBSD: cpu.c,v 1.1 2003/04/26 18:39:26 fvdl Exp $ */ /*- @@ -564,29 +564,18 @@ cpu_copy_trampoline(void) extern u_char cpu_spinup_trampoline[]; extern u_char cpu_spinup_trampoline_end[]; - struct pmap *kmp = pmap_kernel(); extern u_int32_t mp_pdirpa; - extern vaddr_t lo32_vaddr; - extern paddr_t lo32_paddr; + extern paddr_t tramp_pdirpa; - pmap_kenter_pa((vaddr_t)MP_TRAMPOLINE, /* virtual */ - (paddr_t)MP_TRAMPOLINE, /* physical */ - VM_PROT_ALL); /* protection */ memcpy((caddr_t)MP_TRAMPOLINE, cpu_spinup_trampoline, cpu_spinup_trampoline_end-cpu_spinup_trampoline); /* - * The initial PML4 pointer must be below 4G, so if the - * current one isn't, use a "bounce buffer" * We need to patch this after we copy the trampoline, * the symbol points into the copied trampoline. */ - if (kmp->pm_pdirpa > 0xffffffff) { - memcpy((void *)lo32_vaddr, kmp->pm_pdir, PAGE_SIZE); - mp_pdirpa = lo32_paddr; - } else - mp_pdirpa = kmp->pm_pdirpa; + mp_pdirpa = tramp_pdirpa; } diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c index bf7ea133133..28c8d89b540 100644 --- a/sys/arch/amd64/amd64/machdep.c +++ b/sys/arch/amd64/amd64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.87 2009/01/02 05:16:15 miod Exp $ */ +/* $OpenBSD: machdep.c,v 1.88 2009/02/15 02:03:40 marco Exp $ */ /* $NetBSD: machdep.c,v 1.3 2003/05/07 22:58:18 fvdl Exp $ */ /*- @@ -173,6 +173,7 @@ paddr_t idt_paddr; vaddr_t lo32_vaddr; paddr_t lo32_paddr; +paddr_t tramp_pdirpa; int kbd_reset; @@ -253,6 +254,7 @@ int cpu_dumpsize(void); u_long cpu_dump_mempagecnt(void); void dumpsys(void); void cpu_init_extents(void); +void map_tramps(void); void init_x86_64(paddr_t); void (*cpuresetfn)(void); @@ -1194,6 +1196,39 @@ cpu_init_extents(void) already_done = 1; } +#if defined(MULTIPROCESSOR) || \ + (NACPI > 0 && defined(ACPI_SLEEP_ENABLED) && !defined(SMALL_KERNEL)) +void +map_tramps(void) { + struct pmap *kmp = pmap_kernel(); + + pmap_kenter_pa(lo32_vaddr, lo32_paddr, VM_PROT_ALL); + + /* + * The initial PML4 pointer must be below 4G, so if the + * current one isn't, use a "bounce buffer" and save it + * for tramps to use. + */ + if (kmp->pm_pdirpa > 0xffffffff) { + memcpy((void *)lo32_vaddr, kmp->pm_pdir, PAGE_SIZE); + tramp_pdirpa = lo32_paddr; + } else + tramp_pdirpa = kmp->pm_pdirpa; + +#ifdef MULTIPROCESSOR + pmap_kenter_pa((vaddr_t)MP_TRAMPOLINE, /* virtual */ + (paddr_t)MP_TRAMPOLINE, /* physical */ + VM_PROT_ALL); /* protection */ +#endif /* MULTIPROCESSOR */ + + +#ifdef ACPI_SLEEP_ENABLED + pmap_kenter_pa((vaddr_t)ACPI_TRAMPOLINE, /* virtual */ + (paddr_t)ACPI_TRAMPOLINE, /* physical */ + VM_PROT_ALL); /* protection */ +#endif /* ACPI_SLEEP_ENABLED */ +} +#endif #define IDTVEC(name) __CONCAT(X, name) typedef void (vector)(void); @@ -1287,6 +1322,11 @@ init_x86_64(paddr_t first_avail) avail_start = MP_TRAMPOLINE + PAGE_SIZE; #endif +#ifdef ACPI_SLEEP_ENABLED + if (avail_start < ACPI_TRAMPOLINE + PAGE_SIZE) + avail_start = ACPI_TRAMPOLINE + PAGE_SIZE; +#endif /* ACPI_SLEEP_ENABLED */ + /* Let us know if we're supporting > 4GB ram load */ if (bigmem) printf("Bigmem = %d\n", bigmem); @@ -1476,7 +1516,10 @@ init_x86_64(paddr_t first_avail) pmap_kenter_pa(idt_vaddr + PAGE_SIZE, idt_paddr + PAGE_SIZE, VM_PROT_READ|VM_PROT_WRITE); - pmap_kenter_pa(lo32_vaddr, lo32_paddr, VM_PROT_READ|VM_PROT_WRITE); +#if defined(MULTIPROCESSOR) || \ + (NACPI > 0 && defined(ACPI_SLEEP_ENABLED) && !defined(SMALL_KERNEL)) + map_tramps(); +#endif idt = (struct gate_descriptor *)idt_vaddr; gdtstore = (char *)(idt + NIDT); diff --git a/sys/arch/amd64/conf/files.amd64 b/sys/arch/amd64/conf/files.amd64 index fd5516a0bd3..731fa2ca72c 100644 --- a/sys/arch/amd64/conf/files.amd64 +++ b/sys/arch/amd64/conf/files.amd64 @@ -1,4 +1,4 @@ -# $OpenBSD: files.amd64,v 1.43 2009/01/13 13:53:50 kettenis Exp $ +# $OpenBSD: files.amd64,v 1.44 2009/02/15 02:03:40 marco Exp $ maxpartitions 16 maxusers 2 16 128 @@ -206,6 +206,7 @@ include "dev/i2c/files.i2c" # include "../../../dev/acpi/files.acpi" file arch/amd64/amd64/acpi_machdep.c acpi +file arch/amd64/amd64/acpi_wakecode.S acpi # # Machine-independent SD/MMC drivers |