diff options
-rw-r--r-- | sys/arch/i386/conf/files.i386 | 3 | ||||
-rw-r--r-- | sys/arch/i386/i386/acpi_wakecode.S | 120 | ||||
-rw-r--r-- | sys/arch/i386/i386/hibernate_machdep.c | 416 | ||||
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 14 | ||||
-rw-r--r-- | sys/arch/i386/include/hibernate.h | 38 | ||||
-rw-r--r-- | sys/arch/i386/include/hibernate_var.h | 31 | ||||
-rw-r--r-- | sys/arch/i386/include/kcore.h | 25 |
7 files changed, 638 insertions, 9 deletions
diff --git a/sys/arch/i386/conf/files.i386 b/sys/arch/i386/conf/files.i386 index cadf84b36fa..b4943512159 100644 --- a/sys/arch/i386/conf/files.i386 +++ b/sys/arch/i386/conf/files.i386 @@ -1,4 +1,4 @@ -# $OpenBSD: files.i386,v 1.201 2011/04/05 12:50:15 guenther Exp $ +# $OpenBSD: files.i386,v 1.202 2011/04/30 15:33:18 mlarkin Exp $ # # new style config file for i386 architecture # @@ -24,6 +24,7 @@ file arch/i386/i386/est.c !small_kernel file arch/i386/i386/gdt.c file arch/i386/i386/in_cksum.s inet file arch/i386/i386/machdep.c +file arch/i386/i386/hibernate_machdep.c file arch/i386/i386/via.c file arch/i386/i386/amd64errata.c !small_kernel file arch/i386/i386/kgdb_machdep.c kgdb diff --git a/sys/arch/i386/i386/acpi_wakecode.S b/sys/arch/i386/i386/acpi_wakecode.S index 6c810cf180a..9940f409303 100644 --- a/sys/arch/i386/i386/acpi_wakecode.S +++ b/sys/arch/i386/i386/acpi_wakecode.S @@ -44,6 +44,7 @@ #include "assym.h" #include <machine/asm.h> +#include <machine/hibernate_var.h> #include <machine/specialreg.h> #include <machine/param.h> #include <machine/segments.h> @@ -52,6 +53,7 @@ #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 HIBERNATE_STACK_OFFSET 0x0F00 /* * On wakeup, we'll start executing at acpi_real_mode_resume. @@ -80,6 +82,7 @@ .global _C_LABEL(acpi_resume_end) .global _C_LABEL(do_real_mode_post) _C_LABEL(acpi_real_mode_resume): +_ACPI_TRMP_OFFSET(acpi_s3_vector_real) nop cli cld @@ -317,6 +320,72 @@ _C_LABEL(acpi_protected_mode_resume): xorl %eax, %eax jmp *acpi_saved_ret + /* + * hibernate_resume_machine drops to real mode and + * restarts the OS using the saved S3 resume vector + */ + .code32 +NENTRY(hibernate_resume_machine) + cli + /* Jump to the identity mapped version of ourself */ + mov $hibernate_resume_vector_2, %eax + jmp *%eax +_ACPI_TRMP_LABEL(hibernate_resume_vector_2) + + /* Get out of 32 bit CS */ + lgdt gdt_16 + ljmp $0x8, $hibernate_resume_vector_3 + +_ACPI_TRMP_LABEL(hibernate_resume_vector_3) + .code16 + movl %cr0, %eax + /* Disable CR0.PG - no paging */ + andl $(~CR0_PG), %eax + /* Disable CR0.PE - real mode */ + andl $(~CR0_PE), %eax + movl %eax, %cr0 + + /* Flush TLB */ + xorl %eax, %eax + movl %eax, %cr3 + + /* Set up real mode segment selectors */ + movw $0x0400, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movl $0x0FFE, %esp + lidtl clean_idt + + /* Jump to the S3 resume vector */ + ljmp $0x0400, $acpi_s3_vector_real + + .code32 + /* Switch to hibernate resume pagetable */ +NENTRY(hibernate_activate_resume_pt) + /* Enable large pages */ + movl %eax, %cr4 + orl $(CR4_PSE), %eax + movl %eax, %cr4 + + movl $HIBERNATE_PT_PAGE, %eax + movl %eax, %cr3 + jmp 1f + +1: nop + ret + +NENTRY(hibernate_switch_stack) + movl (%esp), %eax + movl %eax, HIBERNATE_STACK_PAGE + HIBERNATE_STACK_OFFSET + movl $(HIBERNATE_STACK_PAGE + HIBERNATE_STACK_OFFSET), %eax + movl %eax, %esp + + /* On our own stack from here onward */ + ret + + .code16 .align 8 _ACPI_TRMP_OFFSET(tmp_gdt) .word tmp_gdt_end - tmp_gdtable @@ -368,6 +437,56 @@ _ACPI_TRMP_OFFSET(clean_idt) .long 0 .word 0 + /* + * gdt_16 is the gdt used when returning to real mode for bios + * reads/writes (sets up a 16 bit segment) + */ + .align 8 +_ACPI_TRMP_LABEL(gdt_16) + .word gdt_16_end - gdt_16_table + .long gdt_16_table + + .align 8 +_ACPI_TRMP_LABEL(gdt_16_table) + /* + * 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: False + * + */ + .word 0xffff, 0 + .byte 0, 0x9f, 0x8f, 0 + + /* + * Data + * Limit: 0xffffffff + * Base: 0x00000000 + * Descriptor Type: + * Segment Type: W + * Present: True + * Priv: 0 + * AVL: False + * 64-bit: False + * 32-bit: False + * + */ + .word 0xffff, 0 + .byte 0, 0x93, 0x8f, 0 + +_ACPI_TRMP_LABEL(gdt_16_end) + .align 4 _C_LABEL(do_real_mode_post): _ACPI_TRMP_OFFSET(do_real_mode_post_off) @@ -437,6 +556,7 @@ _C_LABEL(acpi_resume_end): * for use during the ACPI suspend/resume process. */ + .code32 NENTRY(acpi_savecpu) movl (%esp), %eax movl %eax, acpi_saved_ret diff --git a/sys/arch/i386/i386/hibernate_machdep.c b/sys/arch/i386/i386/hibernate_machdep.c new file mode 100644 index 00000000000..6c574ee3b62 --- /dev/null +++ b/sys/arch/i386/i386/hibernate_machdep.c @@ -0,0 +1,416 @@ +/* + * Copyright (c) 2011 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 <sys/param.h> +#include <sys/buf.h> +#include <sys/conf.h> +#include <sys/device.h> +#include <sys/disk.h> +#include <sys/disklabel.h> +#include <sys/timeout.h> +#include <sys/malloc.h> + +#include <uvm/uvm_extern.h> +#include <uvm/uvm_pmemrange.h> + +#include <machine/hibernate.h> +#include <machine/kcore.h> +#include <machine/pmap.h> + +#include <dev/ata/atavar.h> +#include <dev/ata/wdvar.h> + +#ifdef MULTIPROCESSOR +#include <machine/mpbiosvar.h> +#endif /* MULTIPROCESSOR */ + +#include "wd.h" + +#ifndef SMALL_KERNEL +/* Hibernate support */ +int hibernate_write_image(void); +int hibernate_read_image(void); +void hibernate_unpack_image(void); +void *get_hibernate_io_function(void); +int get_hibernate_info(struct hibernate_info *); +void hibernate_enter_resume_pte(vaddr_t, paddr_t); +void hibernate_populate_resume_pt(paddr_t *, paddr_t *); +struct hibernate_info *global_hiber_info; +paddr_t global_image_start; + +extern void hibernate_resume_machine(void); +extern void hibernate_activate_resume_pt(void); +extern void hibernate_switch_stack(void); +extern char *disk_readlabel(struct disklabel *, dev_t, char *, size_t); +extern caddr_t start, end; +extern int ndumpmem; +extern struct dumpmem dumpmem[]; + + +/* + * i386 MD Hibernate functions + */ + +void * +get_hibernate_io_function() +{ + +#if NWD > 0 + /* XXX - Only support wd hibernate presently */ + if (strcmp(findblkname(major(swapdev)), "wd") == 0) + return wd_hibernate_io; + else + return NULL; +#else + return NULL; +#endif +} + +int +get_hibernate_info(struct hibernate_info *hiber_info) +{ + int i; + struct disklabel dl; + char err_string[128], *dl_ret; + + /* Determine I/O function to use */ + hiber_info->io_func = get_hibernate_io_function(); + if (hiber_info->io_func == NULL) + return (0); + + /* Calculate hibernate device */ + hiber_info->device = swdevt[0].sw_dev; + + /* Calculate memory ranges */ + hiber_info->nranges = ndumpmem; + hiber_info->image_size = 0; + + for(i=0; i<ndumpmem; i++) { + hiber_info->ranges[i].base = dumpmem[i].start; + hiber_info->ranges[i].end = + (dumpmem[i].start + dumpmem[i].end * PAGE_SIZE); + hiber_info->image_size += + hiber_info->ranges[i].end - hiber_info->ranges[i].base; + } + +#if NACPI > 0 + hiber_info->ranges[hiber_info->nranges].base = ACPI_TRAMPOLINE; + 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 + hiber_info->ranges[hiber_info->nranges].base = MP_TRAMPOLINE; + hiber_info->ranges[hiber_info->nranges].end = + hiber_info->ranges[hiber_info->nranges].base + PAGE_SIZE; + hiber_info->image_size += PAGE_SIZE; +#endif + + /* Read disklabel (used to calculate signature and image offsets */ + dl_ret = disk_readlabel(&dl, hiber_info->device, err_string, 128); + + if (dl_ret) { + printf("Hibernate error: %s\n", dl_ret); + return (0); + } + + /* Calculate signature block offset in swap */ + hiber_info->sig_offset = DL_BLKTOSEC(&dl, (dl.d_partitions[1].p_size - 1)) * + DL_BLKSPERSEC(&dl); + + /* Calculate memory image offset in swap */ + hiber_info->image_offset = dl.d_partitions[1].p_offset + + dl.d_partitions[1].p_size - + (hiber_info->image_size / 512) -1; + + /* Stash kernel version information */ + bcopy(version, &hiber_info->kernel_version, + min(strlen(version), sizeof(hiber_info->kernel_version))); + + return (1); +} + +/* + * Enter a 4MB PTE mapping for the supplied VA/PA + * into the resume-time page table. + */ +void +hibernate_enter_resume_pte(vaddr_t va, paddr_t pa) +{ + pt_entry_t *pte, npte; + + pte = s4pte_4m(va); + npte = (pa & PMAP_PA_MASK_4M) | PG_RW | PG_V | PG_U | PG_M | PG_PS; + *pte = npte; +} + +/* + * Create the resume-time page table. This table maps the image(pig) area, + * the kernel text area, and various utility pages located in low memory for + * use during resume, since we cannot overwrite the resuming kernel's + * page table and expect things to work properly. + */ +void +hibernate_populate_resume_pt(paddr_t *image_start, paddr_t *image_end) +{ + int phys_page_number; + paddr_t pa, pig_start, pig_end; + psize_t pig_sz; + vaddr_t kern_start_4m_va, kern_end_4m_va, page; + + /* Get the pig (largest contiguous physical range) from uvm */ + if (uvm_pmr_alloc_pig(&pig_start, &pig_sz) == ENOMEM) + panic("Insufficient memory for resume"); + + *image_start = pig_start; + *image_end = pig_end; + + bzero((caddr_t)HIBERNATE_PT_PAGE, PAGE_SIZE); + + /* + * Identity map first 4M physical for tramps and special utility + * pages + */ + hibernate_enter_resume_pte(0, 0); + + /* + * Map current kernel VA range using 4M pages + */ + kern_start_4m_va = (paddr_t)&start & ~(PAGE_MASK_4M); + kern_end_4m_va = (paddr_t)&end & ~(PAGE_MASK_4M); + phys_page_number = 0; + + for (page = kern_start_4m_va ; page <= kern_end_4m_va ; + page += NBPD, phys_page_number++) { + + pa = (paddr_t)(phys_page_number * NBPD); + hibernate_enter_resume_pte(page, pa); + } + + /* + * Identity map the image (pig) area + */ + phys_page_number = pig_start / NBPD; + pig_start &= ~(PAGE_MASK_4M); + pig_end &= ~(PAGE_MASK_4M); + for (page = pig_start; page <= pig_end ; + page += NBPD, phys_page_number++) { + + pa = (paddr_t)(phys_page_number * NBPD); + hibernate_enter_resume_pte(page, pa); + } +} + +int +hibernate_write_image() +{ + struct hibernate_info hiber_info; + int i, j; + paddr_t range_base, range_end, addr; + daddr_t blkctr; + + /* Get current running machine's hibernate info */ + if (!get_hibernate_info(&hiber_info)) + return (0); + + pmap_kenter_pa(HIBERNATE_TEMP_PAGE, HIBERNATE_TEMP_PAGE, VM_PROT_ALL); + pmap_kenter_pa(HIBERNATE_ALLOC_PAGE, HIBERNATE_ALLOC_PAGE, VM_PROT_ALL); + + blkctr = hiber_info.image_offset; + + for (i=0; i < hiber_info.nranges; i++) { + range_base = hiber_info.ranges[i].base; + range_end = hiber_info.ranges[i].end; + + for (j=0; j < (range_end - range_base)/NBPG; + blkctr += (NBPG/512), j += NBPG) { + addr = range_base + j; + pmap_kenter_pa(HIBERNATE_TEMP_PAGE, addr, + VM_PROT_ALL); + bcopy((caddr_t)HIBERNATE_TEMP_PAGE, + (caddr_t)HIBERNATE_IO_PAGE, + NBPG); + hiber_info.io_func(hiber_info.device, blkctr, + (vaddr_t)HIBERNATE_IO_PAGE, NBPG, 1, + (void *)HIBERNATE_ALLOC_PAGE); + } + } + + return (1); +} + +int +hibernate_read_image() +{ + struct hibernate_info hiber_info; + int i, j; + paddr_t range_base, range_end, addr, image_start, image_end; + daddr_t blkctr; + + /* Get current running machine's hibernate info */ + if (!get_hibernate_info(&hiber_info)) + return (0); + + pmap_kenter_pa(HIBERNATE_TEMP_PAGE, HIBERNATE_TEMP_PAGE, VM_PROT_ALL); + pmap_kenter_pa(HIBERNATE_ALLOC_PAGE, HIBERNATE_ALLOC_PAGE, VM_PROT_ALL); + + blkctr = hiber_info.image_offset; + + /* Prepare the resume-time pagetable */ + hibernate_populate_resume_pt(&image_start, &image_end); + + for (i=0; i < hiber_info.nranges; i++) { + range_base = hiber_info.ranges[i].base; + range_end = hiber_info.ranges[i].end; + + for (j=0; j < (range_end - range_base)/NBPG; + blkctr += (NBPG/512), j += NBPG) { + addr = range_base + j; + pmap_kenter_pa(HIBERNATE_TEMP_PAGE, addr, + VM_PROT_ALL); + hiber_info.io_func(hiber_info.device, blkctr, + (vaddr_t)HIBERNATE_IO_PAGE, NBPG, 1, + (void *)HIBERNATE_ALLOC_PAGE); + bcopy((caddr_t)HIBERNATE_IO_PAGE, + (caddr_t)HIBERNATE_TEMP_PAGE, + NBPG); + + } + } + + return (1); +} + +int +hibernate_suspend() +{ + /* + * On i386, the only thing to do on hibernate suspend is + * to write the image. + */ + + return hibernate_write_image(); +} + +/* Unpack image from resumed image to real location */ +void +hibernate_unpack_image() +{ + struct hibernate_info *hiber_info = global_hiber_info; + int i, j; + paddr_t base, end, pig_base; + + hibernate_activate_resume_pt(); + + for (i=0; i<hiber_info->nranges; i++) { + base = hiber_info->ranges[i].base; + end = hiber_info->ranges[i].end; + pig_base = base + global_image_start; + + for (j=base; j< (end - base)/NBPD; j++) { + hibernate_enter_resume_pte(base, base); + bcopy((caddr_t)pig_base, (caddr_t)base, NBPD); + } + } +} + +void +hibernate_resume() +{ + struct hibernate_info hiber_info, disk_hiber_info; + u_int8_t *io_page; + int s; + paddr_t image_start, image_end; + + /* Get current running machine's hibernate info */ + if (!get_hibernate_info(&hiber_info)) + return; + + io_page = malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT); + if (!io_page) + return; + + /* Read hibernate info from disk */ + s = splbio(); + hiber_info.io_func(hiber_info.device, hiber_info.sig_offset, + (vaddr_t)&disk_hiber_info, 512, 0, io_page); + + free(io_page, M_DEVBUF); + + if (memcmp(&hiber_info, &disk_hiber_info, + sizeof(struct hibernate_info)) !=0) { + return; + } + + /* + * On-disk and in-memory hibernate signatures match, + * this means we should do a resume from hibernate. + */ + + disable_intr(); + cold = 1; + + /* + * Add mappings for resume stack and PT page tables + * into the "resuming" kernel. We use these mappings + * during image read and copy + */ + pmap_activate(curproc); + pmap_kenter_pa((vaddr_t)HIBERNATE_STACK_PAGE, + (paddr_t)HIBERNATE_STACK_PAGE, + VM_PROT_ALL); + pmap_kenter_pa((vaddr_t)HIBERNATE_PT_PAGE, + (paddr_t)HIBERNATE_PT_PAGE, + VM_PROT_ALL); + + /* + * Create the resume-time page table (ahead of when we actually + * need it) + */ + hibernate_populate_resume_pt(&image_start, &image_end); + + + /* + * We can't access any of this function's local variables (via + * stack) after we switch stacks, so we stash hiber_info and + * the image start area into temporary global variables first. + */ + global_hiber_info = &hiber_info; + global_image_start = image_start; + + /* Switch stacks */ + hibernate_switch_stack(); + + /* Read the image from disk into the image (pig) area */ + if (!hibernate_read_image()) + panic("Failed to restore the hibernate image"); + + /* + * Image is now in high memory (pig area), copy to "correct" + * location in memory. We'll eventually end up copying on top + * of ourself, but we are assured the kernel code here is + * the same between the hibernated and resuming kernel, + * and we are running on our own stack + */ + hibernate_unpack_image(); + + /* + * Resume the loaded kernel by jumping to the S3 resume vector + */ + hibernate_resume_machine(); +} +#endif /* !SMALL_KERNEL */ diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index f542ed57bae..41d902601ac 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.493 2011/04/19 22:14:54 jsg Exp $ */ +/* $OpenBSD: machdep.c,v 1.494 2011/04/30 15:33:18 mlarkin Exp $ */ /* $NetBSD: machdep.c,v 1.214 1996/11/10 03:16:17 thorpej Exp $ */ /*- @@ -108,6 +108,7 @@ #include <machine/cpufunc.h> #include <machine/cpuvar.h> #include <machine/gdt.h> +#include <machine/kcore.h> #include <machine/pio.h> #include <machine/bus.h> #include <machine/psl.h> @@ -206,10 +207,7 @@ struct uvm_constraint_range *uvm_md_constraints[] = { extern int boothowto; int physmem; -struct dumpmem { - paddr_t start; - paddr_t end; -} dumpmem[VM_PHYSSEG_MAX]; +struct dumpmem dumpmem[VM_PHYSSEG_MAX]; u_int ndumpmem; /* @@ -3070,9 +3068,9 @@ init386(paddr_t first_avail) e = 0xfffff000; } - /* skip first eight pages */ - if (a < 8 * NBPG) - a = 8 * NBPG; + /* skip first 16 pages for tramps and hibernate */ + if (a < 16 * NBPG) + a = 16 * NBPG; /* skip shorter than page regions */ if (a >= e || (e - a) < NBPG) { diff --git a/sys/arch/i386/include/hibernate.h b/sys/arch/i386/include/hibernate.h new file mode 100644 index 00000000000..9a38cb77081 --- /dev/null +++ b/sys/arch/i386/include/hibernate.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011 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 <machine/hibernate_var.h> + +/* i386 hibernate support structures and functions */ + +struct hibernate_memory_range { + paddr_t base; + paddr_t end; +}; + +struct hibernate_info { + u_int nranges; + u_int64_t image_size; + dev_t device; + daddr_t sig_offset; + daddr_t image_offset; + struct hibernate_memory_range ranges[VM_PHYSSEG_MAX]; + char kernel_version[128]; + int (*io_func)(dev_t, daddr_t, vaddr_t, size_t, int, void *); +}; + +int hibernate_suspend(void); +void hibernate_resume(void); diff --git a/sys/arch/i386/include/hibernate_var.h b/sys/arch/i386/include/hibernate_var.h new file mode 100644 index 00000000000..b7aed052c7c --- /dev/null +++ b/sys/arch/i386/include/hibernate_var.h @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2011 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. + */ + +/* i386 hibernate support definitions */ + +#define PAGE_SHIFT_4M 22 +#define PAGE_MASK_4M (NBPD - 1) +#define PMAP_PA_MASK_4M ~((paddr_t)PAGE_MASK_4M) + +#define HIBERNATE_STACK_PAGE (PAGE_SIZE * 5) +#define HIBERNATE_IO_PAGE (PAGE_SIZE * 6) +#define HIBERNATE_TEMP_PAGE (PAGE_SIZE * 10) +#define HIBERNATE_PT_PAGE (PAGE_SIZE * 11) +#define HIBERNATE_ALLOC_PAGE (PAGE_SIZE * 12) +#define HIBERNATE_STACK_OFFSET 0x0F00 + +#define atop_4m(x) ((x) >> PAGE_SHIFT_4M) +#define s4pte_4m(va) ((pt_entry_t *)HIBERNATE_PT_PAGE + atop_4m(va)) diff --git a/sys/arch/i386/include/kcore.h b/sys/arch/i386/include/kcore.h new file mode 100644 index 00000000000..f10f9c31271 --- /dev/null +++ b/sys/arch/i386/include/kcore.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2011 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. + */ + +#ifndef _MACHINE_KCORE_H_ +#define _MACHINE_KCORE_H_ + +struct dumpmem { + paddr_t start; + paddr_t end; +}; + +#endif /* _MACHINE_KCORE_H_ */ |