diff options
Diffstat (limited to 'sys/amd64/amd64/vm_machdep.c')
-rw-r--r-- | sys/amd64/amd64/vm_machdep.c | 479 |
1 files changed, 1 insertions, 478 deletions
diff --git a/sys/amd64/amd64/vm_machdep.c b/sys/amd64/amd64/vm_machdep.c index cf16f53..8c0b274 100644 --- a/sys/amd64/amd64/vm_machdep.c +++ b/sys/amd64/amd64/vm_machdep.c @@ -38,11 +38,10 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * $Id: vm_machdep.c,v 1.108 1998/05/19 00:00:10 tegge Exp $ + * $Id: vm_machdep.c,v 1.109 1998/08/18 07:46:58 msmith Exp $ */ #include "npx.h" -#include "opt_bounce.h" #include "opt_user_ldt.h" #include "opt_vm86.h" #ifdef PC98 @@ -94,482 +93,6 @@ static u_int cpu_reset_proxyid; static volatile u_int cpu_reset_proxy_active; #endif -#ifdef BOUNCE_BUFFERS -static vm_offset_t - vm_bounce_kva __P((int size, int waitok)); -static void vm_bounce_kva_free __P((vm_offset_t addr, vm_offset_t size, - int now)); -static vm_offset_t - vm_bounce_page_find __P((int count)); -static void vm_bounce_page_free __P((vm_offset_t pa, int count)); - -static volatile int kvasfreecnt; - -caddr_t bouncememory; -static int bpwait; -static vm_offset_t *bouncepa; -static int bmwait, bmfreeing; - -#define BITS_IN_UNSIGNED (8*sizeof(unsigned)) -static int bounceallocarraysize; -static unsigned *bounceallocarray; -static int bouncefree; - -#if defined(PC98) && defined (EPSON_BOUNCEDMA) -#define SIXTEENMEG (3840*4096) /* 15MB boundary */ -#else -#define SIXTEENMEG (4096*4096) -#endif -#define MAXBKVA 1024 -int maxbkva = MAXBKVA*PAGE_SIZE; - -/* special list that can be used at interrupt time for eventual kva free */ -static struct kvasfree { - vm_offset_t addr; - vm_offset_t size; -} kvaf[MAXBKVA]; - -/* - * get bounce buffer pages (count physically contiguous) - * (only 1 inplemented now) - */ -static vm_offset_t -vm_bounce_page_find(count) - int count; -{ - int bit; - int s,i; - - if (count != 1) - panic("vm_bounce_page_find -- no support for > 1 page yet!!!"); - - s = splbio(); -retry: - for (i = 0; i < bounceallocarraysize; i++) { - if (bounceallocarray[i] != 0xffffffff) { - bit = ffs(~bounceallocarray[i]); - if (bit) { - bounceallocarray[i] |= 1 << (bit - 1) ; - bouncefree -= count; - splx(s); - return bouncepa[(i * BITS_IN_UNSIGNED + (bit - 1))]; - } - } - } - bpwait = 1; - tsleep((caddr_t) &bounceallocarray, PRIBIO, "bncwai", 0); - goto retry; -} - -static void -vm_bounce_kva_free(addr, size, now) - vm_offset_t addr; - vm_offset_t size; - int now; -{ - int s = splbio(); - kvaf[kvasfreecnt].addr = addr; - kvaf[kvasfreecnt].size = size; - ++kvasfreecnt; - if( now) { - /* - * this will do wakeups - */ - vm_bounce_kva(0,0); - } else { - if (bmwait) { - /* - * if anyone is waiting on the bounce-map, then wakeup - */ - wakeup((caddr_t) io_map); - bmwait = 0; - } - } - splx(s); -} - -/* - * free count bounce buffer pages - */ -static void -vm_bounce_page_free(pa, count) - vm_offset_t pa; - int count; -{ - int allocindex; - int index; - int bit; - - if (count != 1) - panic("vm_bounce_page_free -- no support for > 1 page yet!!!"); - - for(index=0;index<bouncepages;index++) { - if( pa == bouncepa[index]) - break; - } - - if( index == bouncepages) - panic("vm_bounce_page_free: invalid bounce buffer"); - - allocindex = index / BITS_IN_UNSIGNED; - bit = index % BITS_IN_UNSIGNED; - - bounceallocarray[allocindex] &= ~(1 << bit); - - bouncefree += count; - if (bpwait) { - bpwait = 0; - wakeup((caddr_t) &bounceallocarray); - } -} - -/* - * allocate count bounce buffer kva pages - */ -static vm_offset_t -vm_bounce_kva(size, waitok) - int size; - int waitok; -{ - int i; - vm_offset_t kva = 0; - vm_offset_t off; - int s = splbio(); -more: - if (!bmfreeing && kvasfreecnt) { - bmfreeing = 1; - for (i = 0; i < kvasfreecnt; i++) { - for(off=0;off<kvaf[i].size;off+=PAGE_SIZE) { - pmap_kremove( kvaf[i].addr + off); - } - kmem_free_wakeup(io_map, kvaf[i].addr, - kvaf[i].size); - } - kvasfreecnt = 0; - bmfreeing = 0; - if( bmwait) { - bmwait = 0; - wakeup( (caddr_t) io_map); - } - } - - if( size == 0) { - splx(s); - return 0; - } - - if ((kva = kmem_alloc_pageable(io_map, size)) == 0) { - if( !waitok) { - splx(s); - return 0; - } - bmwait = 1; - tsleep((caddr_t) io_map, PRIBIO, "bmwait", 0); - goto more; - } - splx(s); - return kva; -} - -/* - * same as vm_bounce_kva -- but really allocate (but takes pages as arg) - */ -vm_offset_t -vm_bounce_kva_alloc(count) -int count; -{ - int i; - vm_offset_t kva; - vm_offset_t pa; - if( bouncepages == 0) { - kva = (vm_offset_t) malloc(count*PAGE_SIZE, M_TEMP, M_WAITOK); - return kva; - } - kva = vm_bounce_kva(count*PAGE_SIZE, 1); - for(i=0;i<count;i++) { - pa = vm_bounce_page_find(1); - pmap_kenter(kva + i * PAGE_SIZE, pa); - } - return kva; -} - -/* - * same as vm_bounce_kva_free -- but really free - */ -void -vm_bounce_kva_alloc_free(kva, count) - vm_offset_t kva; - int count; -{ - int i; - vm_offset_t pa; - if( bouncepages == 0) { - free((caddr_t) kva, M_TEMP); - return; - } - for(i = 0; i < count; i++) { - pa = pmap_kextract(kva + i * PAGE_SIZE); - vm_bounce_page_free(pa, 1); - } - vm_bounce_kva_free(kva, count*PAGE_SIZE, 0); -} - -/* - * do the things necessary to the struct buf to implement - * bounce buffers... inserted before the disk sort - */ -void -vm_bounce_alloc(bp) - struct buf *bp; -{ - int countvmpg; - vm_offset_t vastart, vaend; - vm_offset_t vapstart, vapend; - vm_offset_t va, kva; - vm_offset_t pa; - int dobounceflag = 0; - int i; - - if (bouncepages == 0) - return; - - if (bp->b_flags & B_BOUNCE) { - printf("vm_bounce_alloc: called recursively???\n"); - return; - } - - if (bp->b_bufsize < bp->b_bcount) { - printf( - "vm_bounce_alloc: b_bufsize(0x%lx) < b_bcount(0x%lx) !!\n", - bp->b_bufsize, bp->b_bcount); - panic("vm_bounce_alloc"); - } - -/* - * This is not really necessary - * if( bp->b_bufsize != bp->b_bcount) { - * printf("size: %d, count: %d\n", bp->b_bufsize, bp->b_bcount); - * } - */ - - - vastart = (vm_offset_t) bp->b_data; - vaend = (vm_offset_t) bp->b_data + bp->b_bufsize; - - vapstart = trunc_page(vastart); - vapend = round_page(vaend); - countvmpg = (vapend - vapstart) / PAGE_SIZE; - -/* - * if any page is above 16MB, then go into bounce-buffer mode - */ - va = vapstart; - for (i = 0; i < countvmpg; i++) { - pa = pmap_kextract(va); - if (pa >= SIXTEENMEG) - ++dobounceflag; - if( pa == 0) - panic("vm_bounce_alloc: Unmapped page"); - va += PAGE_SIZE; - } - if (dobounceflag == 0) - return; - - if (bouncepages < dobounceflag) - panic("Not enough bounce buffers!!!"); - -/* - * allocate a replacement kva for b_addr - */ - kva = vm_bounce_kva(countvmpg*PAGE_SIZE, 1); -#if 0 - printf("%s: vapstart: %x, vapend: %x, countvmpg: %d, kva: %x ", - (bp->b_flags & B_READ) ? "read":"write", - vapstart, vapend, countvmpg, kva); -#endif - va = vapstart; - for (i = 0; i < countvmpg; i++) { - pa = pmap_kextract(va); - if (pa >= SIXTEENMEG) { - /* - * allocate a replacement page - */ - vm_offset_t bpa = vm_bounce_page_find(1); - pmap_kenter(kva + (PAGE_SIZE * i), bpa); -#if 0 - printf("r(%d): (%x,%x,%x) ", i, va, pa, bpa); -#endif - /* - * if we are writing, the copy the data into the page - */ - if ((bp->b_flags & B_READ) == 0) { - bcopy((caddr_t) va, (caddr_t) kva + (PAGE_SIZE * i), PAGE_SIZE); - } - } else { - /* - * use original page - */ - pmap_kenter(kva + (PAGE_SIZE * i), pa); - } - va += PAGE_SIZE; - } - -/* - * flag the buffer as being bounced - */ - bp->b_flags |= B_BOUNCE; -/* - * save the original buffer kva - */ - bp->b_savekva = bp->b_data; -/* - * put our new kva into the buffer (offset by original offset) - */ - bp->b_data = (caddr_t) (((vm_offset_t) kva) | - ((vm_offset_t) bp->b_savekva & PAGE_MASK)); -#if 0 - printf("b_savekva: %x, newva: %x\n", bp->b_savekva, bp->b_data); -#endif - return; -} - -/* - * hook into biodone to free bounce buffer - */ -void -vm_bounce_free(bp) - struct buf *bp; -{ - int i; - vm_offset_t origkva, bouncekva, bouncekvaend; - -/* - * if this isn't a bounced buffer, then just return - */ - if ((bp->b_flags & B_BOUNCE) == 0) - return; - -/* - * This check is not necessary - * if (bp->b_bufsize != bp->b_bcount) { - * printf("vm_bounce_free: b_bufsize=%d, b_bcount=%d\n", - * bp->b_bufsize, bp->b_bcount); - * } - */ - - origkva = (vm_offset_t) bp->b_savekva; - bouncekva = (vm_offset_t) bp->b_data; -/* - printf("free: %d ", bp->b_bufsize); -*/ - -/* - * check every page in the kva space for b_addr - */ - for (i = 0; i < bp->b_bufsize; ) { - vm_offset_t mybouncepa; - vm_offset_t copycount; - - copycount = round_page(bouncekva + 1) - bouncekva; - mybouncepa = pmap_kextract(trunc_page(bouncekva)); - -/* - * if this is a bounced pa, then process as one - */ - if ( mybouncepa != pmap_kextract( trunc_page( origkva))) { - vm_offset_t tocopy = copycount; - if (i + tocopy > bp->b_bufsize) - tocopy = bp->b_bufsize - i; -/* - * if this is a read, then copy from bounce buffer into original buffer - */ - if (bp->b_flags & B_READ) - bcopy((caddr_t) bouncekva, (caddr_t) origkva, tocopy); -/* - * free the bounce allocation - */ - -/* - printf("(kva: %x, pa: %x)", bouncekva, mybouncepa); -*/ - vm_bounce_page_free(mybouncepa, 1); - } - - origkva += copycount; - bouncekva += copycount; - i += copycount; - } - -/* - printf("\n"); -*/ -/* - * add the old kva into the "to free" list - */ - - bouncekva= trunc_page((vm_offset_t) bp->b_data); - bouncekvaend= round_page((vm_offset_t)bp->b_data + bp->b_bufsize); - -/* - printf("freeva: %d\n", (bouncekvaend - bouncekva) / PAGE_SIZE); -*/ - vm_bounce_kva_free( bouncekva, (bouncekvaend - bouncekva), 0); - bp->b_data = bp->b_savekva; - bp->b_savekva = 0; - bp->b_flags &= ~B_BOUNCE; - - return; -} - - -/* - * init the bounce buffer system - */ -void -vm_bounce_init() -{ - int i; - - kvasfreecnt = 0; - - if (bouncepages == 0) - return; - - bounceallocarraysize = (bouncepages + BITS_IN_UNSIGNED - 1) / BITS_IN_UNSIGNED; - bounceallocarray = malloc(bounceallocarraysize * sizeof(unsigned), M_TEMP, M_NOWAIT); - - if (!bounceallocarray) - panic("Cannot allocate bounce resource array"); - - bouncepa = malloc(bouncepages * sizeof(vm_offset_t), M_TEMP, M_NOWAIT); - if (!bouncepa) - panic("Cannot allocate physical memory array"); - - for(i=0;i<bounceallocarraysize;i++) { - bounceallocarray[i] = 0xffffffff; - } - - for(i=0;i<bouncepages;i++) { - vm_offset_t pa; - if( (pa = pmap_kextract((vm_offset_t) bouncememory + i * PAGE_SIZE)) >= SIXTEENMEG) { - printf("vm_bounce_init: bounce memory out of range -- bounce disabled\n"); - free(bounceallocarray, M_TEMP); - bounceallocarray = NULL; - free(bouncepa, M_TEMP); - bouncepa = NULL; - bouncepages = 0; - break; - } - if( pa == 0) - panic("bounce memory not resident"); - bouncepa[i] = pa; - bounceallocarray[i/(8*sizeof(int))] &= ~(1<<(i%(8*sizeof(int)))); - } - bouncefree = bouncepages; - -} -#endif /* BOUNCE_BUFFERS */ - /* * quick version of vm_fault */ |