summaryrefslogtreecommitdiff
path: root/sys/arch
diff options
context:
space:
mode:
authorMike Larkin <mlarkin@cvs.openbsd.org>2011-09-21 02:51:24 +0000
committerMike Larkin <mlarkin@cvs.openbsd.org>2011-09-21 02:51:24 +0000
commit4a14692e9a9a2f1c4f6bd5ab052054670250cd46 (patch)
tree7184ae179fcac3ebf8dd25c417c40cc92b2477b2 /sys/arch
parentea3a7478277273383b202cb5291a7be915000f31 (diff)
Perform most of the remaining refactoring of hibernate code into
MI/MD parts. This also introduces a chunk placement routine that was originally developed at c2k11 with help from drahn and ariane. There are still a few more things to do for hibernate, but those can be worked on in-tree. This code is disabled by default, and not yet called. ok deraadt@ (and deraadt@ said kettenis@ also ok'ed it :) )
Diffstat (limited to 'sys/arch')
-rw-r--r--sys/arch/i386/i386/acpi_wakecode.S27
-rw-r--r--sys/arch/i386/i386/hibernate_machdep.c492
-rw-r--r--sys/arch/i386/include/hibernate.h8
-rw-r--r--sys/arch/i386/include/hibernate_var.h19
4 files changed, 108 insertions, 438 deletions
diff --git a/sys/arch/i386/i386/acpi_wakecode.S b/sys/arch/i386/i386/acpi_wakecode.S
index fd4261c5a0a..63e71928bd5 100644
--- a/sys/arch/i386/i386/acpi_wakecode.S
+++ b/sys/arch/i386/i386/acpi_wakecode.S
@@ -53,7 +53,10 @@
#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)
+
+#ifdef HIBERNATE
#define HIBERNATE_STACK_OFFSET 0x0F00
+#endif
/*
* On wakeup, we'll start executing at acpi_real_mode_resume.
@@ -320,12 +323,13 @@ _C_LABEL(acpi_protected_mode_resume):
xorl %eax, %eax
jmp *acpi_saved_ret
+#ifdef HIBERNATE
/*
- * hibernate_resume_machine drops to real mode and
+ * hibernate_resume_machdep drops to real mode and
* restarts the OS using the saved S3 resume vector
*/
.code32
-NENTRY(hibernate_resume_machine)
+NENTRY(hibernate_resume_machdep)
cli
/* Jump to the identity mapped version of ourself */
mov $hibernate_resume_vector_2, %eax
@@ -363,32 +367,37 @@ _ACPI_TRMP_LABEL(hibernate_resume_vector_3)
.code32
/* Switch to hibernate resume pagetable */
-NENTRY(hibernate_activate_resume_pt)
+NENTRY(hibernate_activate_resume_pt_machdep)
/* Enable large pages */
movl %eax, %cr4
orl $(CR4_PSE), %eax
movl %eax, %cr4
- movl $HIBERNATE_PT_PAGE, %eax
+ movl $HIBERNATE_PD_PAGE, %eax
movl %eax, %cr3
jmp 1f
1: nop
ret
-NENTRY(hibernate_switch_stack)
+ /*
+ * Switch to the private resume-time hibernate stack
+ */
+NENTRY(hibernate_switch_stack_machdep)
movl (%esp), %eax
- movl %eax, HIBERNATE_STACK_PAGE + HIBERNATE_STACK_OFFSET
- movl $(HIBERNATE_STACK_PAGE + HIBERNATE_STACK_OFFSET), %eax
- movl %eax, %esp
+ 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
NENTRY(hibernate_flush)
wbinvd
- invlpg HIBERNATE_TEMP_PAGE
+ movl $hibernate_inflate_page, %eax
+ invlpg (%eax)
ret
+#endif /* HIBERNATE */
.code16
.align 8
diff --git a/sys/arch/i386/i386/hibernate_machdep.c b/sys/arch/i386/i386/hibernate_machdep.c
index f9b4ba73c5d..21af80dde9b 100644
--- a/sys/arch/i386/i386/hibernate_machdep.c
+++ b/sys/arch/i386/i386/hibernate_machdep.c
@@ -44,23 +44,15 @@
#include "acpi.h"
#include "wd.h"
-#ifndef SMALL_KERNEL
/* Hibernate support */
-int hibernate_write_image(void);
-int hibernate_read_image(void);
-void hibernate_unpack_image(void);
void hibernate_enter_resume_4k_pte(vaddr_t, paddr_t);
void hibernate_enter_resume_4k_pde(vaddr_t);
void hibernate_enter_resume_4m_pde(vaddr_t, paddr_t);
-void hibernate_populate_resume_pt(paddr_t, paddr_t);
-int get_hibernate_info_md(union hibernate_info *);
+int hibernate_read_chunks(union hibernate_info *, paddr_t, paddr_t, size_t);
-union hibernate_info *global_hiber_info;
-paddr_t global_image_start;
+extern vaddr_t hibernate_inflate_page;
-extern void hibernate_resume_machine(void);
-extern void hibernate_activate_resume_pt(void);
-extern void hibernate_switch_stack(void);
+extern void hibernate_resume_machdep(void);
extern void hibernate_flush(void);
extern char *disk_readlabel(struct disklabel *, dev_t, char *, size_t);
extern caddr_t start, end;
@@ -73,41 +65,6 @@ extern struct hibernate_state *hibernate_state;
*/
/*
- * hibernate_zlib_reset
- *
- * Reset the zlib stream state and allocate a new hiballoc area for either
- * inflate or deflate. This function is called once for each hibernate chunk
- * Calling hiballoc_init multiple times is acceptable since the memory it is
- * provided is unmanaged memory (stolen).
- *
- */
-int
-hibernate_zlib_reset(int deflate)
-{
- hibernate_state = (struct hibernate_state *)HIBERNATE_ZLIB_SCRATCH;
-
- bzero((caddr_t)HIBERNATE_ZLIB_START, HIBERNATE_ZLIB_SIZE);
- bzero((caddr_t)HIBERNATE_ZLIB_SCRATCH, PAGE_SIZE);
-
- /* Set up stream structure */
- hibernate_state->hib_stream.zalloc = (alloc_func)hibernate_zlib_alloc;
- hibernate_state->hib_stream.zfree = (free_func)hibernate_zlib_free;
-
- /* Initialize the hiballoc arena for zlib allocs/frees */
- hiballoc_init(&hibernate_state->hiballoc_arena,
- (caddr_t)HIBERNATE_ZLIB_START, HIBERNATE_ZLIB_SIZE);
-
- if (deflate) {
- return deflateInit(&hibernate_state->hib_stream,
- Z_DEFAULT_COMPRESSION);
- }
- else
- return inflateInit(&hibernate_state->hib_stream);
-}
-
-/*
- * get_hibernate_io_function
- *
* Returns the hibernate write I/O function to use on this machine
*
*/
@@ -126,8 +83,6 @@ get_hibernate_io_function()
}
/*
- * get_hibernate_info_md
- *
* Gather MD-specific data and store into hiber_info
*/
int
@@ -165,18 +120,17 @@ get_hibernate_info_md(union hibernate_info *hiber_info)
/*
* Enter a mapping for va->pa in the resume pagetable, using
- * the specified size hint.
+ * the specified size.
*
- * hint : 0 if a 4KB mapping is desired
+ * size : 0 if a 4KB mapping is desired
* 1 if a 4MB mapping is desired
*/
void
-hibernate_enter_resume_mapping(vaddr_t va, paddr_t pa, int hint)
+hibernate_enter_resume_mapping(vaddr_t va, paddr_t pa, int size)
{
- if (hint)
+ if (size)
return hibernate_enter_resume_4m_pde(va, pa);
else {
- hibernate_enter_resume_4k_pde(va);
return hibernate_enter_resume_4k_pte(va, pa);
}
}
@@ -222,19 +176,32 @@ hibernate_enter_resume_4k_pde(vaddr_t va)
/*
* 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 during inflate and expect things to work properly.
+ * the kernel text area, and various utility pages for use during resume,
+ * since we cannot overwrite the resuming kernel's page table during inflate
+ * and expect things to work properly.
*/
void
-hibernate_populate_resume_pt(paddr_t image_start, paddr_t image_end)
+hibernate_populate_resume_pt(union hibernate_info *hib_info,
+ paddr_t image_start, paddr_t image_end)
{
int phys_page_number, i;
- paddr_t pa;
+ paddr_t pa, piglet_start, piglet_end;
vaddr_t kern_start_4m_va, kern_end_4m_va, page;
+ /* Identity map PD, PT, and stack pages */
+ pmap_kenter_pa(HIBERNATE_PT_PAGE, HIBERNATE_PT_PAGE, VM_PROT_ALL);
+ pmap_kenter_pa(HIBERNATE_PD_PAGE, HIBERNATE_PD_PAGE, VM_PROT_ALL);
+ pmap_kenter_pa(HIBERNATE_STACK_PAGE, HIBERNATE_STACK_PAGE, VM_PROT_ALL);
+ pmap_activate(curproc);
+
+ hibernate_inflate_page = HIBERNATE_INFLATE_PAGE;
+
bzero((caddr_t)HIBERNATE_PT_PAGE, PAGE_SIZE);
bzero((caddr_t)HIBERNATE_PD_PAGE, PAGE_SIZE);
+ bzero((caddr_t)HIBERNATE_STACK_PAGE, PAGE_SIZE);
+
+ /* PDE for low pages */
+ hibernate_enter_resume_4k_pde(0);
/*
* Identity map first 640KB physical for tramps and special utility
@@ -245,15 +212,6 @@ hibernate_populate_resume_pt(paddr_t image_start, paddr_t image_end)
}
/*
- * Identity map chunk table
- */
- for (i=0; i < HIBERNATE_CHUNK_TABLE_SIZE/PAGE_SIZE; i ++) {
- hibernate_enter_resume_mapping(
- (vaddr_t)HIBERNATE_CHUNK_TABLE_START + (i*PAGE_SIZE),
- HIBERNATE_CHUNK_TABLE_START + (i*PAGE_SIZE), 0);
- }
-
- /*
* Map current kernel VA range using 4M pages
*/
kern_start_4m_va = (paddr_t)&start & ~(PAGE_MASK_4M);
@@ -279,353 +237,76 @@ hibernate_populate_resume_pt(paddr_t image_start, paddr_t image_end)
pa = (paddr_t)(phys_page_number * NBPD);
hibernate_enter_resume_mapping(page, pa, 1);
}
-}
-
-/*
- * hibernate_write_image
- *
- * Write a compressed version of this machine's memory to disk, at the
- * precalculated swap offset:
- *
- * end of swap - signature block size - chunk table size - memory size
- *
- * The function begins by mapping various pages into the suspending
- * kernel's pmap, then loops through each phys mem range, cutting each
- * one into 4MB chunks. These chunks are then compressed individually
- * and written out to disk, in phys mem order. Some chunks might compress
- * more than others, and for this reason, each chunk's size is recorded
- * in the chunk table, which is written to disk after the image has
- * properly been compressed and written.
- *
- * When this function is called, the machine is nearly suspended - most
- * devices are quiesced/suspended, interrupts are off, and cold has
- * been set. This means that there can be no side effects once the
- * write has started, and the write function itself can also have no
- * side effects.
- */
-int
-hibernate_write_image()
-{
- union hibernate_info hiber_info;
- paddr_t range_base, range_end, inaddr, temp_inaddr;
- vaddr_t zlib_range;
- daddr_t blkctr;
- int i;
- size_t nblocks, out_remaining, used, offset;
- struct hibernate_disk_chunk *chunks;
-
- /* Get current running machine's hibernate info */
- bzero(&hiber_info, sizeof(hiber_info));
- if (get_hibernate_info(&hiber_info))
- return (1);
-
- zlib_range = HIBERNATE_ZLIB_START;
-
- /* Map utility pages */
- pmap_kenter_pa(HIBERNATE_ALLOC_PAGE, HIBERNATE_ALLOC_PAGE,
- VM_PROT_ALL);
- pmap_kenter_pa(HIBERNATE_IO_PAGE, HIBERNATE_IO_PAGE, VM_PROT_ALL);
- pmap_kenter_pa(HIBERNATE_TEMP_PAGE, HIBERNATE_TEMP_PAGE,
- VM_PROT_ALL);
- pmap_kenter_pa(HIBERNATE_ZLIB_SCRATCH, HIBERNATE_ZLIB_SCRATCH,
- VM_PROT_ALL);
-
- /* Map the zlib allocation ranges */
- for(zlib_range = HIBERNATE_ZLIB_START; zlib_range < HIBERNATE_ZLIB_END;
- zlib_range += PAGE_SIZE) {
- pmap_kenter_pa((vaddr_t)(zlib_range+i),
- (paddr_t)(zlib_range+i),
- VM_PROT_ALL);
- }
-
- /* Identity map the chunktable */
- for(i=0; i < HIBERNATE_CHUNK_TABLE_SIZE; i += PAGE_SIZE) {
- pmap_kenter_pa((vaddr_t)(HIBERNATE_CHUNK_TABLE_START+i),
- (paddr_t)(HIBERNATE_CHUNK_TABLE_START+i),
- VM_PROT_ALL);
- }
-
- pmap_activate(curproc);
-
- blkctr = hiber_info.image_offset;
- hiber_info.chunk_ctr = 0;
- offset = 0;
- chunks = (struct hibernate_disk_chunk *)HIBERNATE_CHUNK_TABLE_START;
-
- /* Calculate the chunk regions */
- for (i=0; i < hiber_info.nranges; i++) {
- range_base = hiber_info.ranges[i].base;
- range_end = hiber_info.ranges[i].end;
-
- inaddr = range_base;
-
- while (inaddr < range_end) {
- chunks[hiber_info.chunk_ctr].base = inaddr;
- if (inaddr + HIBERNATE_CHUNK_SIZE < range_end)
- chunks[hiber_info.chunk_ctr].end = inaddr +
- HIBERNATE_CHUNK_SIZE;
- else
- chunks[hiber_info.chunk_ctr].end = range_end;
-
- inaddr += HIBERNATE_CHUNK_SIZE;
- hiber_info.chunk_ctr ++;
- }
- }
-
- /* Compress and write the chunks in the chunktable */
- for (i=0; i < hiber_info.chunk_ctr; i++) {
- range_base = chunks[i].base;
- range_end = chunks[i].end;
-
- chunks[i].offset = blkctr;
-
- /* Reset zlib for deflate */
- if (hibernate_zlib_reset(1) != Z_OK)
- return (1);
-
- inaddr = range_base;
-
- /*
- * For each range, loop through its phys mem region
- * and write out 4MB chunks (the last chunk might be
- * smaller than 4MB).
- */
- while (inaddr < range_end) {
- out_remaining = PAGE_SIZE;
- while (out_remaining > 0 && inaddr < range_end) {
- pmap_kenter_pa(HIBERNATE_TEMP_PAGE2,
- inaddr & PMAP_PA_MASK, VM_PROT_ALL);
- pmap_activate(curproc);
- bcopy((caddr_t)HIBERNATE_TEMP_PAGE2,
- (caddr_t)HIBERNATE_TEMP_PAGE, PAGE_SIZE);
-
- /* Adjust for non page-sized regions */
- temp_inaddr = (inaddr & PAGE_MASK) +
- HIBERNATE_TEMP_PAGE;
-
- /* Deflate from temp_inaddr to IO page */
- inaddr += hibernate_deflate(temp_inaddr,
- &out_remaining);
- }
-
- if (out_remaining == 0) {
- /* Filled up the page */
- nblocks = PAGE_SIZE / hiber_info.secsize;
-
- if(hiber_info.io_func(hiber_info.device, blkctr,
- (vaddr_t)HIBERNATE_IO_PAGE, PAGE_SIZE,
- 1, (void *)HIBERNATE_ALLOC_PAGE))
- return (1);
-
- blkctr += nblocks;
- }
-
- }
-
- if (inaddr != range_end)
- return (1);
-
- /*
- * End of range. Round up to next secsize bytes
- * after finishing compress
- */
- if (out_remaining == 0)
- out_remaining = PAGE_SIZE;
-
- /* Finish compress */
- hibernate_state->hib_stream.avail_in = 0;
- hibernate_state->hib_stream.avail_out = out_remaining;
- hibernate_state->hib_stream.next_in = (caddr_t)inaddr;
- hibernate_state->hib_stream.next_out =
- (caddr_t)HIBERNATE_IO_PAGE + (PAGE_SIZE - out_remaining);
-
- if (deflate(&hibernate_state->hib_stream, Z_FINISH) !=
- Z_STREAM_END)
- return (1);
-
- out_remaining = hibernate_state->hib_stream.avail_out;
-
- used = PAGE_SIZE - out_remaining;
- nblocks = used / hiber_info.secsize;
-
- /* Round up to next block if needed */
- if (used % hiber_info.secsize != 0)
- nblocks ++;
-
- /* Write final block(s) for this chunk */
- if( hiber_info.io_func(hiber_info.device, blkctr,
- (vaddr_t)HIBERNATE_IO_PAGE, nblocks*hiber_info.secsize,
- 1, (void *)HIBERNATE_ALLOC_PAGE))
- return (1);
-
- blkctr += nblocks;
-
- offset = blkctr;
- chunks[i].compressed_size=
- (offset-chunks[i].offset)*hiber_info.secsize;
- }
-
- /* Image write complete, write the signature+chunk table and return */
- return hibernate_write_signature(&hiber_info);
-}
-
-int
-hibernate_read_image()
-{
- union 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 (1);
-
- 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);
- 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);
-
- }
- }
-
- /* Read complete, clear the signature and return */
- return hibernate_clear_signature();
-}
-int
-hibernate_suspend()
-{
/*
- * On i386, the only thing to do on hibernate suspend is
- * to zero all the unused pages and write the image.
+ * Map the piglet
*/
-
- uvm_pmr_zero_everything();
-
- return hibernate_write_image();
-}
-
-/* Unpack image from resumed image to real location */
-void
-hibernate_unpack_image()
-{
- union 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_mapping(base, base, 0);
- bcopy((caddr_t)pig_base, (caddr_t)base, NBPD);
- }
+ phys_page_number = hib_info->piglet_pa / NBPD;
+ piglet_start = hib_info->piglet_va;
+ piglet_end = piglet_start + HIBERNATE_CHUNK_SIZE * 3;
+ piglet_start &= ~(PAGE_MASK_4M);
+ piglet_end &= ~(PAGE_MASK_4M);
+ for (page = piglet_start; page <= piglet_end ;
+ page += NBPD, phys_page_number++) {
+ pa = (paddr_t)(phys_page_number * NBPD);
+ hibernate_enter_resume_mapping(page, pa, 1);
}
}
+/*
+ * MD-specific resume preparation (creating resume time pagetables,
+ * stacks, etc).
+ *
+ * On i386, we use the piglet whose address is contained in hib_info
+ * as per the following layout:
+ *
+ * offset from piglet base use
+ * ----------------------- --------------------
+ * 0 i/o allocation area
+ * PAGE_SIZE i/o read area
+ * 2*PAGE_SIZE temp/scratch page
+ * 5*PAGE_SIZE resume stack
+ * 6*PAGE_SIZE hiballoc arena
+ * 7*PAGE_SIZE to 87*PAGE_SIZE zlib inflate area
+ * ...
+ * HIBERNATE_CHUNK_SIZE chunk table
+ * 2*HIBERNATE_CHUNK_SIZE bounce/copy area
+ */
void
-hibernate_resume()
+hibernate_prepare_resume_machdep(union hibernate_info *hib_info)
{
- union hibernate_info hiber_info, disk_hiber_info;
- u_int8_t *io_page;
- int s;
- paddr_t image_start;
-
- /* 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(union hibernate_info)) !=0) {
- return;
- }
+ paddr_t pa, piglet_end;
+ vaddr_t va;
/*
- * On-disk and in-memory hibernate signatures match,
- * this means we should do a resume from hibernate.
+ * At this point, we are sure that the piglet's phys
+ * space is going to have been unused by the suspending
+ * kernel, but the vaddrs used by the suspending kernel
+ * may or may not be available to us here in the
+ * resuming kernel, so we allocate a new range of VAs
+ * for the piglet. Those VAs will be temporary and will
+ * cease to exist as soon as we switch to the resume
+ * PT, so we need to ensure that any VAs required during
+ * inflate are also entered into that map.
*/
- 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);
-
- /*
- * 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;
+ hib_info->piglet_va = (vaddr_t)km_alloc(HIBERNATE_CHUNK_SIZE*3,
+ &kv_any, &kp_none, &kd_nowait);
+ if (!hib_info->piglet_va)
+ panic("Unable to allocate vaddr for hibernate resume piglet\n");
- /* Switch stacks */
- hibernate_switch_stack();
+ piglet_end = hib_info->piglet_pa + HIBERNATE_CHUNK_SIZE*3;
- /* Read the image from disk into the image (pig) area */
- if (hibernate_read_image())
- panic("Failed to restore the hibernate image");
+ for (pa = hib_info->piglet_pa,
+ va = hib_info->piglet_va;
+ pa <= piglet_end;
+ pa += PAGE_SIZE, va += PAGE_SIZE)
+ pmap_kenter_pa(va, pa, VM_PROT_ALL);
- /*
- * 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();
+ pmap_activate(curproc);
}
/*
- * hibernate_inflate_skip
- *
* During inflate, certain pages that contain our bookkeeping information
* (eg, the chunk table, scratch pages, etc) need to be skipped over and
* not inflated into.
@@ -633,23 +314,12 @@ hibernate_resume()
* Returns 1 if the physical page at dest should be skipped, 0 otherwise
*/
int
-hibernate_inflate_skip(paddr_t dest)
+hibernate_inflate_skip(union hibernate_info *hib_info, paddr_t dest)
{
- /* Chunk Table */
- if (dest >= HIBERNATE_CHUNK_TABLE_START &&
- dest <= HIBERNATE_CHUNK_TABLE_END)
- return (1);
-
- /* Contiguous utility pages */
- if (dest >= HIBERNATE_STACK_PAGE &&
- dest <= HIBERNATE_CHUNKS_PAGE)
- return (1);
-
- /* libz hiballoc arena */
- if (dest >= HIBERNATE_ZLIB_SCRATCH &&
- dest <= HIBERNATE_ZLIB_END)
+ if (dest >= hib_info->piglet_pa &&
+ dest <= (hib_info->piglet_pa + 3 * HIBERNATE_CHUNK_SIZE))
return (1);
return (0);
}
-#endif /* !SMALL_KERNEL */
+
diff --git a/sys/arch/i386/include/hibernate.h b/sys/arch/i386/include/hibernate.h
index 5f3b7042eae..19c0b8dd63f 100644
--- a/sys/arch/i386/include/hibernate.h
+++ b/sys/arch/i386/include/hibernate.h
@@ -21,7 +21,9 @@
int get_hibernate_info_md(union hibernate_info *);
void hibernate_flush(void);
void hibernate_enter_resume_mapping(vaddr_t, paddr_t, int);
-int hibernate_zlib_reset(int);
-int hibernate_inflate_skip(paddr_t);
+int hibernate_inflate_skip(union hibernate_info *, paddr_t);
+void hibernate_prepare_resume_machdep(union hibernate_info *);
int hibernate_suspend(void);
-void hibernate_resume(void);
+void hibernate_switch_stack_machdep(void);
+void hibernate_resume_machdep(void);
+void hibernate_activate_resume_pt_machdep(void);
diff --git a/sys/arch/i386/include/hibernate_var.h b/sys/arch/i386/include/hibernate_var.h
index 07a14b9836f..b34fd9395cb 100644
--- a/sys/arch/i386/include/hibernate_var.h
+++ b/sys/arch/i386/include/hibernate_var.h
@@ -20,15 +20,10 @@
#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_TEMP_PAGE2 (PAGE_SIZE * 11)
-#define HIBERNATE_PD_PAGE (PAGE_SIZE * 12)
-#define HIBERNATE_PT_PAGE (PAGE_SIZE * 13)
-#define HIBERNATE_ALLOC_PAGE (PAGE_SIZE * 14)
-
-#define HIBERNATE_CHUNKS_PAGE (PAGE_SIZE * 15)
+#define HIBERNATE_PD_PAGE (PAGE_SIZE * 5)
+#define HIBERNATE_PT_PAGE (PAGE_SIZE * 6)
+#define HIBERNATE_STACK_PAGE (PAGE_SIZE * 7)
+#define HIBERNATE_INFLATE_PAGE (PAGE_SIZE * 8)
/* Use 4MB hibernation chunks */
#define HIBERNATE_CHUNK_SIZE 0x400000
@@ -39,12 +34,6 @@
#define HIBERNATE_CHUNK_TABLE_SIZE (HIBERNATE_CHUNK_TABLE_END - \
HIBERNATE_CHUNK_TABLE_START)
-/* 320KB (80 pages) for gzip allocator */
-#define HIBERNATE_ZLIB_SCRATCH (PAGE_SIZE * 20)
-#define HIBERNATE_ZLIB_START (PAGE_SIZE * 21)
-#define HIBERNATE_ZLIB_END (PAGE_SIZE * (21 + 80))
-#define HIBERNATE_ZLIB_SIZE (HIBERNATE_ZLIB_END - HIBERNATE_ZLIB_START)
-
#define HIBERNATE_STACK_OFFSET 0x0F00
#define atop_4m(x) ((x) >> PAGE_SHIFT_4M)