summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/i386/i386/acpi_machdep.c34
-rw-r--r--sys/arch/i386/i386/acpi_wakecode.S111
-rw-r--r--sys/arch/i386/i386/autoconf.c8
-rw-r--r--sys/arch/i386/i386/hibernate_machdep.c21
-rw-r--r--sys/arch/i386/i386/machdep.c6
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