diff options
-rw-r--r-- | sys/arch/i386/i386/acpi_machdep.c | 34 | ||||
-rw-r--r-- | sys/arch/i386/i386/acpi_wakecode.S | 111 | ||||
-rw-r--r-- | sys/arch/i386/i386/autoconf.c | 8 | ||||
-rw-r--r-- | sys/arch/i386/i386/hibernate_machdep.c | 21 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 6 |
5 files changed, 115 insertions, 65 deletions
diff --git a/sys/arch/i386/i386/acpi_machdep.c b/sys/arch/i386/i386/acpi_machdep.c index b08ce6fdeb9..6d4025ec6ff 100644 --- a/sys/arch/i386/i386/acpi_machdep.c +++ b/sys/arch/i386/i386/acpi_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acpi_machdep.c,v 1.59 2015/05/30 08:41:30 kettenis Exp $ */ +/* $OpenBSD: acpi_machdep.c,v 1.60 2016/05/20 02:30:41 mlarkin Exp $ */ /* * Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com> * @@ -63,6 +63,7 @@ int haveacpibutusingapm; #endif extern u_char acpi_real_mode_resume[], acpi_resume_end[]; +extern u_char acpi_tramp_data_start[], acpi_tramp_data_end[]; extern int acpi_savecpu(void) __returns_twice; extern void intr_calculatemasks(void); @@ -239,12 +240,31 @@ acpi_attach_machdep(struct acpi_softc *sc) /* * Sanity check before setting up trampoline. - * Ensure the trampoline size is < PAGE_SIZE + * Ensure the trampoline page sizes are < PAGE_SIZE */ KASSERT(acpi_resume_end - acpi_real_mode_resume < PAGE_SIZE); + KASSERT(acpi_tramp_data_end - acpi_tramp_data_start < PAGE_SIZE); - bcopy(acpi_real_mode_resume, (caddr_t)ACPI_TRAMPOLINE, + /* Map ACPI tramp code and data pages RW for copy */ + pmap_kenter_pa(ACPI_TRAMPOLINE, ACPI_TRAMPOLINE, + PROT_READ | PROT_WRITE); + pmap_kenter_pa(ACPI_TRAMP_DATA, ACPI_TRAMP_DATA, + PROT_READ | PROT_WRITE); + + /* Fill the trampoline pages with int3 */ + memset((caddr_t)ACPI_TRAMPOLINE, 0xcc, PAGE_SIZE); + memset((caddr_t)ACPI_TRAMP_DATA, 0xcc, PAGE_SIZE); + + /* Copy over real trampoline pages (code and data) */ + memcpy((caddr_t)ACPI_TRAMPOLINE, acpi_real_mode_resume, acpi_resume_end - acpi_real_mode_resume); + memcpy((caddr_t)ACPI_TRAMP_DATA, acpi_tramp_data_start, + acpi_tramp_data_end - acpi_tramp_data_start); + + /* Unmap, will be remapped in acpi_sleep_cpu */ + pmap_kremove(ACPI_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(ACPI_TRAMP_DATA, PAGE_SIZE); + #endif /* SMALL_KERNEL */ } @@ -318,6 +338,11 @@ acpi_sleep_cpu(struct acpi_softc *sc, int state) if (sc->sc_facs->length > 32 && sc->sc_facs->version >= 1) sc->sc_facs->x_wakeup_vector = 0; + /* Map trampoline and data page */ + pmap_kenter_pa(ACPI_TRAMPOLINE, ACPI_TRAMPOLINE, PROT_READ | PROT_EXEC); + pmap_kenter_pa(ACPI_TRAMP_DATA, ACPI_TRAMP_DATA, + PROT_READ | PROT_WRITE); + /* Copy the current cpu registers into a safe place for resume. * acpi_savecpu actually returns twice - once in the suspend * path and once in the resume path (see setjmp(3)). @@ -357,6 +382,9 @@ acpi_sleep_cpu(struct acpi_softc *sc, int state) if (sc->sc_facs->length > 32 && sc->sc_facs->version >= 1) sc->sc_facs->x_wakeup_vector = 0; + pmap_kremove(ACPI_TRAMPOLINE, PAGE_SIZE); + pmap_kremove(ACPI_TRAMP_DATA, PAGE_SIZE); + return (0); } diff --git a/sys/arch/i386/i386/acpi_wakecode.S b/sys/arch/i386/i386/acpi_wakecode.S index ae21ed92fec..1d722180278 100644 --- a/sys/arch/i386/i386/acpi_wakecode.S +++ b/sys/arch/i386/i386/acpi_wakecode.S @@ -54,7 +54,11 @@ #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) -#define _ACPI_RM_SEGMENT (ACPI_TRAMPOLINE >> 4) +#define _ACPI_TRMP_DATA_LABEL(a) a = . - _C_LABEL(acpi_tramp_data_start) + \ + ACPI_TRAMP_DATA +#define _ACPI_TRMP_DATA_OFFSET(a) a = . - _C_LABEL(acpi_tramp_data_start) +#define _ACPI_RM_CODE_SEG (ACPI_TRAMPOLINE >> 4) +#define _ACPI_RM_DATA_SEG (ACPI_TRAMP_DATA >> 4) #ifdef HIBERNATE #define HIBERNATE_STACK_OFFSET 0x0F00 @@ -85,6 +89,8 @@ .global _C_LABEL(acpi_real_mode_resume) .global _C_LABEL(acpi_protected_mode_resume) .global _C_LABEL(acpi_resume_end) + .global _C_LABEL(acpi_tramp_data_start) + .global _C_LABEL(acpi_tramp_data_end) _C_LABEL(acpi_real_mode_resume): _ACPI_TRMP_OFFSET(acpi_s3_vector_real) nop @@ -97,10 +103,11 @@ _ACPI_TRMP_OFFSET(acpi_s3_vector_real) * want 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,%es - movw %ax,%ss + movw $(_ACPI_RM_DATA_SEG), %ax + movw %ax, %ds + movw %ax, %ss + movw %cs, %ax + movw %ax, %es lidtl clean_idt /* @@ -118,13 +125,6 @@ _ACPI_TRMP_OFFSET(acpi_s3_vector_real) popfl /* - * 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 @@ -184,9 +184,7 @@ _C_LABEL(acpi_protected_mode_resume): * 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 - + addl $(ACPI_TRAMP_DATA), %esp /* * Reset our page size extension (via restoring cr4) to what @@ -337,8 +335,9 @@ _ACPI_TRMP_LABEL(hibernate_resume_vector_3) movl %eax, %cr3 /* Set up real mode segment selectors */ - movw $0x1300, %ax + movw $(_ACPI_RM_DATA_SEG), %ax movw %ax, %ds + movw %ax, %ss movw %ax, %es movw %ax, %fs movw %ax, %gs @@ -346,7 +345,7 @@ _ACPI_TRMP_LABEL(hibernate_resume_vector_3) lidtl clean_idt /* Jump to the S3 resume vector */ - ljmp $0x1300, $acpi_s3_vector_real + ljmp $(_ACPI_RM_CODE_SEG), $acpi_s3_vector_real .code32 /* Switch to hibernate resume pagetable */ @@ -400,14 +399,23 @@ NENTRY(hibernate_flush) ret #endif /* HIBERNATE */ - .code16 - .align 8, 0xcc -_ACPI_TRMP_OFFSET(tmp_gdt) + /* + * End of resume code (code copied to ACPI_TRAMPOLINE) + */ +_C_LABEL(acpi_resume_end): + + /* + * Initial copy of this data gets placed in .rodata, kernel makes + * RW copy of it in the tramp data page. + */ + .section .rodata +_C_LABEL(acpi_tramp_data_start): +_ACPI_TRMP_DATA_OFFSET(tmp_gdt) .word tmp_gdt_end - tmp_gdtable .long tmp_gdtable .align 8, 0xcc -_ACPI_TRMP_LABEL(tmp_gdtable) +_ACPI_TRMP_DATA_LABEL(tmp_gdtable) /* * null */ @@ -444,10 +452,10 @@ _ACPI_TRMP_LABEL(tmp_gdtable) */ .word 0xffff, 0 .byte 0, 0x93, 0xcf, 0 -_ACPI_TRMP_LABEL(tmp_gdt_end) +_ACPI_TRMP_DATA_LABEL(tmp_gdt_end) .align 8, 0xcc -_ACPI_TRMP_OFFSET(clean_idt) +_ACPI_TRMP_DATA_OFFSET(clean_idt) .word 0xffff .long 0 .word 0 @@ -457,12 +465,12 @@ _ACPI_TRMP_OFFSET(clean_idt) * reads/writes (sets up a 16 bit segment) */ .align 8, 0xcc -_ACPI_TRMP_LABEL(gdt_16) +_ACPI_TRMP_DATA_LABEL(gdt_16) .word gdt_16_end - gdt_16_table .long gdt_16_table .align 8, 0xcc -_ACPI_TRMP_LABEL(gdt_16_table) +_ACPI_TRMP_DATA_LABEL(gdt_16_table) /* * null */ @@ -500,66 +508,63 @@ _ACPI_TRMP_LABEL(gdt_16_table) .word 0xffff, 0 .byte 0, 0x93, 0x8f, 0 -_ACPI_TRMP_LABEL(gdt_16_end) +_ACPI_TRMP_DATA_LABEL(gdt_16_end) .align 4, 0xcc -_ACPI_TRMP_LABEL(acpi_saved_ebx) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ebx) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_ecx) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ecx) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_edx) +_ACPI_TRMP_DATA_LABEL(acpi_saved_edx) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_ebp) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ebp) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_esi) +_ACPI_TRMP_DATA_LABEL(acpi_saved_esi) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_edi) +_ACPI_TRMP_DATA_LABEL(acpi_saved_edi) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_esp) +_ACPI_TRMP_DATA_LABEL(acpi_saved_esp) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_fl) +_ACPI_TRMP_DATA_LABEL(acpi_saved_fl) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_cr0) +_ACPI_TRMP_DATA_LABEL(acpi_saved_cr0) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_cr2) +_ACPI_TRMP_DATA_LABEL(acpi_saved_cr2) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_cr3) +_ACPI_TRMP_DATA_LABEL(acpi_saved_cr3) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_cr4) +_ACPI_TRMP_DATA_LABEL(acpi_saved_cr4) .long 0 -_ACPI_TRMP_LABEL(acpi_saved_ret) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ret) .long 0 .align 16, 0xcc -_ACPI_TRMP_LABEL(acpi_saved_idt) +_ACPI_TRMP_DATA_LABEL(acpi_saved_idt) .space 6 .align 16, 0xcc -_ACPI_TRMP_LABEL(acpi_saved_gdt) +_ACPI_TRMP_DATA_LABEL(acpi_saved_gdt) .space 6 .align 16, 0xcc -_ACPI_TRMP_LABEL(acpi_saved_ldt) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ldt) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_cs) +_ACPI_TRMP_DATA_LABEL(acpi_saved_cs) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_ds) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ds) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_es) +_ACPI_TRMP_DATA_LABEL(acpi_saved_es) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_fs) +_ACPI_TRMP_DATA_LABEL(acpi_saved_fs) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_gs) +_ACPI_TRMP_DATA_LABEL(acpi_saved_gs) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_ss) +_ACPI_TRMP_DATA_LABEL(acpi_saved_ss) .short 0 -_ACPI_TRMP_LABEL(acpi_saved_tr) +_ACPI_TRMP_DATA_LABEL(acpi_saved_tr) .short 0 - /* - * End of resume code (code copied to ACPI_TRAMPOLINE) - */ -_C_LABEL(acpi_resume_end): +_C_LABEL(acpi_tramp_data_end): /* * acpi_savecpu saves the processor's registers and flags diff --git a/sys/arch/i386/i386/autoconf.c b/sys/arch/i386/i386/autoconf.c index 2037862de79..72d9499dfe2 100644 --- a/sys/arch/i386/i386/autoconf.c +++ b/sys/arch/i386/i386/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.99 2016/05/18 03:45:11 mlarkin Exp $ */ +/* $OpenBSD: autoconf.c,v 1.100 2016/05/20 02:30:41 mlarkin Exp $ */ /* $NetBSD: autoconf.c,v 1.20 1996/05/03 19:41:56 christos Exp $ */ /*- @@ -145,12 +145,6 @@ cpu_configure(void) PROT_READ | PROT_WRITE); /* protection */ #endif -#if NACPI > 0 && !defined(SMALL_KERNEL) - pmap_kenter_pa((vaddr_t)ACPI_TRAMPOLINE, /* virtual */ - (paddr_t)ACPI_TRAMPOLINE, /* physical */ - PROT_READ | PROT_WRITE | PROT_EXEC); /* protection */ -#endif - if (config_rootfound("mainbus", NULL) == NULL) panic("cpu_configure: mainbus not configured"); diff --git a/sys/arch/i386/i386/hibernate_machdep.c b/sys/arch/i386/i386/hibernate_machdep.c index fbb6f05492d..da0f1251ded 100644 --- a/sys/arch/i386/i386/hibernate_machdep.c +++ b/sys/arch/i386/i386/hibernate_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: hibernate_machdep.c,v 1.48 2016/05/18 03:45:11 mlarkin Exp $ */ +/* $OpenBSD: hibernate_machdep.c,v 1.49 2016/05/20 02:30:41 mlarkin Exp $ */ /* * Copyright (c) 2011 Mike Larkin <mlarkin@openbsd.org> @@ -136,7 +136,17 @@ get_hibernate_info_md(union hibernate_info *hiber_info) hiber_info->ranges[i].base; } + /* Record lowmem PTP page */ + if (hiber_info->nranges >= VM_PHYSSEG_MAX) + return (1); + hiber_info->ranges[hiber_info->nranges].base = PTP0_PA; + hiber_info->ranges[hiber_info->nranges].end = + hiber_info->ranges[hiber_info->nranges].base + PAGE_SIZE; + hiber_info->image_size += PAGE_SIZE; + hiber_info->nranges++; + #if NACPI > 0 + /* Record ACPI trampoline code page */ if (hiber_info->nranges >= VM_PHYSSEG_MAX) return (1); hiber_info->ranges[hiber_info->nranges].base = ACPI_TRAMPOLINE; @@ -144,6 +154,15 @@ get_hibernate_info_md(union hibernate_info *hiber_info) hiber_info->ranges[hiber_info->nranges].base + PAGE_SIZE; hiber_info->image_size += PAGE_SIZE; hiber_info->nranges++; + + /* Record ACPI trampoline data page */ + if (hiber_info->nranges >= VM_PHYSSEG_MAX) + return (1); + hiber_info->ranges[hiber_info->nranges].base = ACPI_TRAMP_DATA; + hiber_info->ranges[hiber_info->nranges].end = + hiber_info->ranges[hiber_info->nranges].base + PAGE_SIZE; + hiber_info->image_size += PAGE_SIZE; + hiber_info->nranges++; #endif #ifdef MULTIPROCESSOR /* Record MP trampoline code page */ diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index 7c737ba5b5b..81d98efa0d2 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.585 2016/05/18 03:45:11 mlarkin Exp $ */ +/* $OpenBSD: machdep.c,v 1.586 2016/05/20 02:30:41 mlarkin Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -3238,6 +3238,10 @@ init386(paddr_t first_avail) /* skip ACPI resume trampoline code page */ if (a < ACPI_TRAMPOLINE + NBPG) a = ACPI_TRAMPOLINE + NBPG; + + /* skip ACPI resume trampoline data page */ + if (a < ACPI_TRAMP_DATA + NBPG) + a = ACPI_TRAMP_DATA + NBPG; #endif /* ACPI */ #ifdef HIBERNATE |