diff options
author | Mike Larkin <mlarkin@cvs.openbsd.org> | 2011-07-09 00:55:01 +0000 |
---|---|---|
committer | Mike Larkin <mlarkin@cvs.openbsd.org> | 2011-07-09 00:55:01 +0000 |
commit | b39e8c0c98081790ce8599896c6186e353554b93 (patch) | |
tree | 6ff3613b2904919c862983ce8513aaa002068763 /sys/kern | |
parent | f984863a2cc0825432ba8b9536a0eb91e4b339b0 (diff) |
Extract MI pmap function hibernate_enter_resume_mapping, refactor old i386
resume pmap code to match.
Add hibernate deflater and inflater and cache flush routines.
Code is not presently called or automatically built.
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/subr_hibernate.c | 90 |
1 files changed, 83 insertions, 7 deletions
diff --git a/sys/kern/subr_hibernate.c b/sys/kern/subr_hibernate.c index 60db171c1ac..bbb7a9f7de3 100644 --- a/sys/kern/subr_hibernate.c +++ b/sys/kern/subr_hibernate.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_hibernate.c,v 1.9 2011/07/09 00:27:31 mlarkin Exp $ */ +/* $OpenBSD: subr_hibernate.c,v 1.10 2011/07/09 00:55:00 mlarkin Exp $ */ /* * Copyright (c) 2011 Ariane van der Steldt <ariane@stack.nl> @@ -610,14 +610,90 @@ void } /* - * hibernate_zlib_free + * hibernate_inflate + * + * Inflate size bytes from src into dest, skipping any pages in + * [src..dest] that are special (see hibernate_inflate_skip) + * + * For each page of output data, we map HIBERNATE_TEMP_PAGE + * to the current output page, and tell inflate() to inflate + * its data there, resulting in the inflated data being placed + * at the proper paddr. + * + * This function executes while using the resume-time stack + * and pmap, and therefore cannot use ddb/printf/etc. Doing so + * will likely hang or reset the machine. * - * Free the memory pointed to by addr in the hiballoc area presently in - * use - * */ void -hibernate_zlib_free(void *unused, void *addr) +hibernate_inflate(paddr_t dest, paddr_t src, size_t size) +{ + int i; + + hibernate_state->hib_stream.avail_in = size; + hibernate_state->hib_stream.next_in = (char *)src; + + do { + /* Flush cache and TLB */ + hibernate_flush(); + + /* + * Is this a special page? If yes, redirect the + * inflate output to a scratch page (eg, discard it) + */ + if (hibernate_inflate_skip(dest)) + hibernate_enter_resume_mapping(HIBERNATE_TEMP_PAGE, + HIBERNATE_TEMP_PAGE, 0); + else + hibernate_enter_resume_mapping(HIBERNATE_TEMP_PAGE, + dest, 0); + + /* Set up the stream for inflate */ + hibernate_state->hib_stream.avail_out = PAGE_SIZE; + hibernate_state->hib_stream.next_out = + (char *)HIBERNATE_TEMP_PAGE; + + /* Process next block of data */ + i = inflate(&hibernate_state->hib_stream, Z_PARTIAL_FLUSH); + if (i != Z_OK && i != Z_STREAM_END) { + /* + * XXX - this will likely reboot/hang most machines, + * but there's not much else we can do here. + */ + panic("inflate error"); + } + + dest += PAGE_SIZE - hibernate_state->hib_stream.avail_out; + } while (i != Z_STREAM_END); +} + +/* + * hibernate_deflate + * + * deflate from src into the I/O page, up to 'remaining' bytes + * + * Returns number of input bytes consumed, and may reset + * the 'remaining' parameter if not all the output space was consumed + * (this information is needed to know how much to write to disk + * + */ +size_t +hibernate_deflate(paddr_t src, size_t *remaining) { - hib_free(&hibernate_state->hiballoc_arena, addr); + /* Set up the stream for deflate */ + hibernate_state->hib_stream.avail_in = PAGE_SIZE - + (src & PAGE_MASK); + hibernate_state->hib_stream.avail_out = *remaining; + hibernate_state->hib_stream.next_in = (caddr_t)src; + hibernate_state->hib_stream.next_out = (caddr_t)HIBERNATE_IO_PAGE + + (PAGE_SIZE - *remaining); + + /* Process next block of data */ + if (deflate(&hibernate_state->hib_stream, Z_PARTIAL_FLUSH) != Z_OK) + panic("hibernate zlib deflate error\n"); + + /* Update pointers and return number of bytes consumed */ + *remaining = hibernate_state->hib_stream.avail_out; + return (PAGE_SIZE - (src & PAGE_MASK)) - + hibernate_state->hib_stream.avail_in; } |