diff options
-rw-r--r-- | sys/arch/i386/i386/machdep.c | 17 | ||||
-rw-r--r-- | sys/arch/i386/i386/pmap.c | 16 | ||||
-rw-r--r-- | sys/arch/i386/i386/pmap.old.c | 16 | ||||
-rw-r--r-- | sys/arch/i386/isa/isa_machdep.c | 176 | ||||
-rw-r--r-- | sys/arch/i386/isa/isa_machdep.h | 8 | ||||
-rw-r--r-- | sys/dev/isa/isadmavar.h | 5 |
6 files changed, 132 insertions, 106 deletions
diff --git a/sys/arch/i386/i386/machdep.c b/sys/arch/i386/i386/machdep.c index e112ebfb611..97341394fc8 100644 --- a/sys/arch/i386/i386/machdep.c +++ b/sys/arch/i386/i386/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.50 1997/09/22 12:11:19 deraadt Exp $ */ +/* $OpenBSD: machdep.c,v 1.51 1997/09/22 21:03:53 niklas Exp $ */ /* $NetBSD: machdep.c,v 1.202 1996/05/18 15:54:59 christos Exp $ */ /*- @@ -119,6 +119,7 @@ #endif #include "isa.h" +#include "isadma.h" #include "npx.h" #if NNPX > 0 extern struct proc *npxproc; @@ -202,7 +203,7 @@ cpu_startup() struct pcb *pcb; int x; - /* + /* * Initialize error message buffer (at end of core). */ /* avail_end was pre-decremented in pmap_bootstrap to compensate */ @@ -220,6 +221,14 @@ cpu_startup() 1024 * cnvmem, 1024 * extmem); printf("real mem = %d\n", ctob(physmem)); +#if NISA > 0 && NISADMA > 0 + /* + * We need the bounce buffer allocated early so we have a good chance + * of getting a chunk of continuous low memory. + */ + isadma_init(); +#endif + /* * Find out how much space we need, allocate it, * and then give everything true virtual addresses. @@ -284,8 +293,8 @@ cpu_startup() * Finally, allocate mbuf pool. Since mclrefcnt is an off-size * we use the more space efficient malloc in place of kmem_alloc. */ - mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, - M_MBUF, M_NOWAIT); + mclrefcnt = (char *)malloc(NMBCLUSTERS+CLBYTES/MCLBYTES, M_MBUF, + M_NOWAIT); bzero(mclrefcnt, NMBCLUSTERS+CLBYTES/MCLBYTES); mb_map = kmem_suballoc(kernel_map, (vm_offset_t *)&mbutl, &maxaddr, VM_MBUF_SIZE, FALSE); diff --git a/sys/arch/i386/i386/pmap.c b/sys/arch/i386/i386/pmap.c index dace4b52baf..5153e7871ea 100644 --- a/sys/arch/i386/i386/pmap.c +++ b/sys/arch/i386/i386/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.18 1997/08/17 17:31:37 grr Exp $ */ +/* $OpenBSD: pmap.c,v 1.19 1997/09/22 21:03:54 niklas Exp $ */ /* $NetBSD: pmap.c,v 1.36 1996/05/03 19:42:22 christos Exp $ */ /* @@ -284,20 +284,6 @@ pmap_bootstrap(virtual_start) */ virtual_avail = reserve_dumppages(virtual_avail); - /* - * reserve special hunk of memory for use by bus dma as a bounce - * buffer (contiguous virtual *and* physical memory). XXX - */ -#if NISA > 0 && NISADMA > 0 - if (ctob(physmem) >= 0x1000000) { - isaphysmem = pmap_steal_memory(DMA_BOUNCE * NBPG); - isaphysmempgs = DMA_BOUNCE; - } else { - isaphysmem = pmap_steal_memory(DMA_BOUNCE_LOW * NBPG); - isaphysmempgs = DMA_BOUNCE_LOW; - } -#endif - /* flawed, no mappings?? */ if (ctob(physmem) > 31*1024*1024 && MAXKPDE != NKPDE) { vm_offset_t p; diff --git a/sys/arch/i386/i386/pmap.old.c b/sys/arch/i386/i386/pmap.old.c index 28c81c0efc0..814dcfebd8d 100644 --- a/sys/arch/i386/i386/pmap.old.c +++ b/sys/arch/i386/i386/pmap.old.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.old.c,v 1.18 1997/08/17 17:31:37 grr Exp $ */ +/* $OpenBSD: pmap.old.c,v 1.19 1997/09/22 21:03:54 niklas Exp $ */ /* $NetBSD: pmap.c,v 1.36 1996/05/03 19:42:22 christos Exp $ */ /* @@ -284,20 +284,6 @@ pmap_bootstrap(virtual_start) */ virtual_avail = reserve_dumppages(virtual_avail); - /* - * reserve special hunk of memory for use by bus dma as a bounce - * buffer (contiguous virtual *and* physical memory). XXX - */ -#if NISA > 0 && NISADMA > 0 - if (ctob(physmem) >= 0x1000000) { - isaphysmem = pmap_steal_memory(DMA_BOUNCE * NBPG); - isaphysmempgs = DMA_BOUNCE; - } else { - isaphysmem = pmap_steal_memory(DMA_BOUNCE_LOW * NBPG); - isaphysmempgs = DMA_BOUNCE_LOW; - } -#endif - /* flawed, no mappings?? */ if (ctob(physmem) > 31*1024*1024 && MAXKPDE != NKPDE) { vm_offset_t p; diff --git a/sys/arch/i386/isa/isa_machdep.c b/sys/arch/i386/isa/isa_machdep.c index 2fbbc0dc0ce..208b11317d3 100644 --- a/sys/arch/i386/isa/isa_machdep.c +++ b/sys/arch/i386/isa/isa_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: isa_machdep.c,v 1.20 1997/04/17 03:44:52 tholo Exp $ */ +/* $OpenBSD: isa_machdep.c,v 1.21 1997/09/22 21:03:55 niklas Exp $ */ /* $NetBSD: isa_machdep.c,v 1.14 1996/05/12 23:06:18 mycroft Exp $ */ /*- @@ -63,15 +63,13 @@ typedef (*vector) __P((void)); extern vector IDTVEC(intr)[], IDTVEC(fast)[]; extern struct gate_descriptor idt[]; + +extern vm_map_t kernel_map; + void isa_strayintr __P((int)); void intr_calculatemasks __P((void)); int fakeintr __P((void *)); -vm_offset_t bounce_alloc __P((vm_size_t, vm_offset_t, int)); -caddr_t bounce_vaddr __P((vm_offset_t)); -void bounce_free __P((vm_offset_t, vm_size_t)); -void isadma_copyfrombuf __P((caddr_t, vm_size_t, int, struct isadma_seg *)); - /* * Fill in default interrupt table (in case of spuruious interrupt * during configuration of kernel, setup interrupt control unit @@ -359,43 +357,90 @@ static int bit_ptr = -1; /* last segment visited */ static int chunk_size = 0; /* size (bytes) of one low mem segment */ static int chunk_num = 0; /* actual number of low mem segments */ #ifdef DIAGNOSTIC -int bounce_alloc_cur = 0; -int bounce_alloc_max = 0; +int isadma_alloc_cur = 0; +int isadma_alloc_max = 0; #endif -vm_offset_t isaphysmem; /* base address of low mem arena */ -int isaphysmempgs; /* number of pages of low mem arena */ +vm_offset_t isadma_mem; /* base address (virtual) of low mem arena */ +int isadma_pages; /* number of pages of low mem arena */ /* - * if addr is the physical address of an allocated bounce buffer return the - * corresponding virtual address, 0 otherwise + * called from cpu_startup to setup the bounce buffer. */ +void +isadma_init() +{ + struct pglist pglist; + vm_size_t sz; + vm_page_t pg; + vm_offset_t off; + + TAILQ_INIT(&pglist); + + /* + * Get some continuous physical memory situated below 16MB as that is + * the ISA DMA limit. + */ + isadma_pages = + ctob(physmem) >= 0x1000000 ? DMA_BOUNCE : DMA_BOUNCE_LOW; + sz = isadma_pages << PGSHIFT; + if (vm_page_alloc_memory(sz, 0, 0x1000000, 0, 0, &pglist, 1, 0)) + panic("isadma_init: no physical memory for bounce buffer"); + + /* + * Find some space in the kernel virtual memory for our bounce buffer. + */ + isadma_mem = vm_map_min(kernel_map); + if (vm_map_find(kernel_map, NULL, 0, &isadma_mem, sz, TRUE)) + panic("isadma_init: no virtual memory for bounce buffer"); + /* + * Now map the physical bounce buffer into the virtual addresspace. + */ + for (pg = pglist.tqh_first, off = isadma_mem; pg != NULL; + pg = pg->pageq.tqe_next, off += PAGE_SIZE) + pmap_enter(pmap_kernel(), off, VM_PAGE_TO_PHYS(pg), + VM_PROT_DEFAULT, TRUE); + + /* + * Finally, wire it down so it never will be paged out. + * XXX Is this really needed? we have already told pmap_enter. + */ + vm_map_pageable(kernel_map, isadma_mem, isadma_mem + sz, FALSE); + +#if 0 + printf("ISA DMA bounce buffer: pa 0x%08x va 0x%08x sz 0x%08x", + VM_PAGE_TO_PHYS(pglist.tqh_first), isadma_mem, sz); +#endif +} +/* + * if addr is the physical address of an allocated bounce buffer return the + * corresponding virtual address, 0 otherwise + */ caddr_t -bounce_vaddr(addr) +isadma_vaddr(addr) vm_offset_t addr; { int i; - if (addr < vtophys(isaphysmem) || - addr >= vtophys(isaphysmem + chunk_num*chunk_size) || - ((i = (int)(addr-vtophys(isaphysmem))) % chunk_size) != 0 || + if (addr < vtophys(isadma_mem) || + addr >= vtophys(isadma_mem + chunk_num * chunk_size) || + ((i = (int)(addr-vtophys(isadma_mem))) % chunk_size) != 0 || bit(i/chunk_size)) - return(0); + return (0); - return((caddr_t) (isaphysmem + (addr - vtophys(isaphysmem)))); + return ((caddr_t)(isadma_mem + (addr - vtophys(isadma_mem)))); } /* - * alloc a low mem segment of size nbytes. Alignment constraint is: + * Allocate a low mem segment of size nbytes. Alignment constraint is: * (addr & pmask) == ((addr+size-1) & pmask) - * if waitok, call may wait for memory to become available. - * returns 0 on failure + * If waitok, call may wait for memory to become available. + * Returns 0 on failure. */ - vm_offset_t -bounce_alloc(nbytes, pmask, waitok) +isadma_alloc(nbytes, pmask, waitok) vm_size_t nbytes; vm_offset_t pmask; int waitok; @@ -408,25 +453,25 @@ bounce_alloc(nbytes, pmask, waitok) opri = splbio(); if (bit_ptr < 0) { /* initialize low mem arena */ - if ((chunk_size = isaphysmempgs*NBPG/MAX_CHUNK) & 1) + if ((chunk_size = isadma_pages * NBPG / MAX_CHUNK) & 1) chunk_size--; - chunk_num = (isaphysmempgs*NBPG) / chunk_size; + chunk_num = (isadma_pages * NBPG) / chunk_size; for(i = 0; i < chunk_num; i++) set(i); bit_ptr = 0; } - nunits = (nbytes+chunk_size-1)/chunk_size; + nunits = (nbytes + chunk_size - 1) / chunk_size; /* * set a=start, b=start with address constraints, c=end * check if this request may ever succeed. */ - a = isaphysmem; - b = (isaphysmem + ~pmask) & pmask; - c = isaphysmem + chunk_num*chunk_size; - n = nunits*chunk_size; + a = isadma_mem; + b = (isadma_mem + ~pmask) & pmask; + c = isadma_mem + chunk_num * chunk_size; + n = nunits * chunk_size; if (a + n >= c || (pmask != 0 && a + n >= b && b + n >= c)) { splx(opri); return(0); @@ -436,16 +481,19 @@ bounce_alloc(nbytes, pmask, waitok) i = bit_ptr; l = -1; do{ - if (bit(i) && l >= 0 && (i - l + 1) >= nunits){ - r = vtophys(isaphysmem + (i - nunits + 1)*chunk_size); + if (bit(i) && l >= 0 && (i - l + 1) >= nunits) { + r = vtophys(isadma_mem + + (i - nunits + 1) * chunk_size); if (((r ^ (r + nbytes - 1)) & pmask) == 0) { for (l = i - nunits + 1; l <= i; l++) clr(l); bit_ptr = i; #ifdef DIAGNOSTIC - bounce_alloc_cur += nunits*chunk_size; - bounce_alloc_max = max(bounce_alloc_max, - bounce_alloc_cur); + isadma_alloc_cur += + nunits * chunk_size; + isadma_alloc_max = + max(isadma_alloc_max, + isadma_alloc_cur); #endif splx(opri); return(r); @@ -458,10 +506,10 @@ bounce_alloc(nbytes, pmask, waitok) i = 0; l = -1; } - } while(i != bit_ptr); + } while (i != bit_ptr); if (waitok) - tsleep((caddr_t) &bit_ptr, PRIBIO, "physmem", 0); + tsleep((caddr_t)&bit_ptr, PRIBIO, "physmem", 0); else { splx(opri); return(0); @@ -474,7 +522,7 @@ bounce_alloc(nbytes, pmask, waitok) */ void -bounce_free(addr, nbytes) +isadma_free(addr, nbytes) vm_offset_t addr; vm_size_t nbytes; { @@ -483,37 +531,37 @@ bounce_free(addr, nbytes) opri = splbio(); - if ((vaddr = (vm_offset_t) bounce_vaddr(addr)) == 0) - panic("bounce_free: bad address"); + if ((vaddr = (vm_offset_t)isadma_vaddr(addr)) == 0) + panic("isadma_free: bad address"); - i = (int) (vaddr - isaphysmem)/chunk_size; - j = i + (nbytes + chunk_size - 1)/chunk_size; + i = (int)(vaddr - isadma_mem) / chunk_size; + j = i + (nbytes + chunk_size - 1) / chunk_size; #ifdef DIAGNOSTIC - bounce_alloc_cur -= (j - i)*chunk_size; + isadma_alloc_cur -= (j - i) * chunk_size; #endif while (i < j) { if (bit(i)) - panic("bounce_free: already free"); + panic("isadma_free: already free"); set(i); i++; } - wakeup((caddr_t) &bit_ptr); + wakeup((caddr_t)&bit_ptr); splx(opri); } /* * setup (addr, nbytes) for an ISA dma transfer. - * flags&ISADMA_MAP_WAITOK may wait - * flags&ISADMA_MAP_BOUNCE may use a bounce buffer if necessary - * flags&ISADMA_MAP_CONTIG result must be physically contiguous - * flags&ISADMA_MAP_8BIT must not cross 64k boundary - * flags&ISADMA_MAP_16BIT must not cross 128k boundary + * flags & ISADMA_MAP_WAITOK may wait + * flags & ISADMA_MAP_BOUNCE may use a bounce buffer if necessary + * flags & ISADMA_MAP_CONTIG result must be physically contiguous + * flags & ISADMA_MAP_8BIT must not cross 64k boundary + * flags & ISADMA_MAP_16BIT must not cross 128k boundary * * returns the number of used phys entries, 0 on failure. - * if flags&ISADMA_MAP_CONTIG result is 1 on sucess! + * if flags & ISADMA_MAP_CONTIG result is 1 on sucess! */ int @@ -563,14 +611,14 @@ isadma_map(addr, nbytes, phys, flags) if ((flags & ISADMA_MAP_BOUNCE) == 0) phys[seg].addr = 0; else - phys[seg].addr = bounce_alloc(phys[seg].length, - pmask, waitok); + phys[seg].addr = isadma_alloc(phys[seg].length, + pmask, waitok); if (phys[seg].addr == 0) { for (i = 0; i < seg; i++) - if (bounce_vaddr(phys[i].addr)) - bounce_free(phys[i].addr, - phys[i].length); - return 0; + if (isadma_vaddr(phys[i].addr)) + isadma_free(phys[i].addr, + phys[i].length); + return (0); } } @@ -579,11 +627,11 @@ isadma_map(addr, nbytes, phys, flags) /* check all constraints */ if (datalen || - ((phys[0].addr ^ (phys[0].addr + phys[0].length - 1)) & pmask) != 0 || - ((phys[0].addr & 1) && (flags & ISADMA_MAP_16BIT))) { + ((phys[0].addr ^ (phys[0].addr + phys[0].length - 1)) & pmask) != + 0 || ((phys[0].addr & 1) && (flags & ISADMA_MAP_16BIT))) { if ((flags & ISADMA_MAP_BOUNCE) == 0) return 0; - if ((phys[0].addr = bounce_alloc(nbytes, pmask, waitok)) == 0) + if ((phys[0].addr = isadma_alloc(nbytes, pmask, waitok)) == 0) return 0; phys[0].length = nbytes; } @@ -605,8 +653,8 @@ isadma_unmap(addr, nbytes, nphys, phys) int i; for (i = 0; i < nphys; i++) - if (bounce_vaddr(phys[i].addr)) - bounce_free(phys[i].addr, phys[i].length); + if (isadma_vaddr(phys[i].addr)) + isadma_free(phys[i].addr, phys[i].length); } /* @@ -624,7 +672,7 @@ isadma_copyfrombuf(addr, nbytes, nphys, phys) caddr_t vaddr; for (i = 0; i < nphys; i++) { - vaddr = bounce_vaddr(phys[i].addr); + vaddr = isadma_vaddr(phys[i].addr); if (vaddr) bcopy(vaddr, addr, phys[i].length); addr += phys[i].length; @@ -646,7 +694,7 @@ isadma_copytobuf(addr, nbytes, nphys, phys) caddr_t vaddr; for (i = 0; i < nphys; i++) { - vaddr = bounce_vaddr(phys[i].addr); + vaddr = isadma_vaddr(phys[i].addr); if (vaddr) bcopy(addr, vaddr, phys[i].length); addr += phys[i].length; diff --git a/sys/arch/i386/isa/isa_machdep.h b/sys/arch/i386/isa/isa_machdep.h index e62aefdb0d8..8bebed26dfd 100644 --- a/sys/arch/i386/isa/isa_machdep.h +++ b/sys/arch/i386/isa/isa_machdep.h @@ -110,9 +110,6 @@ void isa_intr_disestablish __P((isa_chipset_tag_t ic, void *handler)); * DMA_BOUNCE is the number of pages of low-addressed physical memory * to acquire for ISA bounce buffers. If physical memory below 16 MB * then DMA_BOUNCE_LOW will be used. - * - * isaphysmem is the address of this physical contiguous low memory. - * isaphysmempgs is the number of pages allocated. */ #ifndef DMA_BOUNCE @@ -123,10 +120,6 @@ void isa_intr_disestablish __P((isa_chipset_tag_t ic, void *handler)); #define DMA_BOUNCE_LOW 16 /* number of pages if memory <= 16M */ #endif -extern vm_offset_t isaphysmem; -extern int isaphysmempgs; - - /* * Variables and macros to deal with the ISA I/O hole. * XXX These should be converted to machine- and bus-mapping-independent @@ -152,5 +145,6 @@ extern u_long atdevbase; /* kernel virtual address of "hole" */ * Miscellanous functions. */ void sysbeep __P((int, int)); /* beep with the system speaker */ +void isadma_init __P((void)); #endif /* _I386_ISA_MACHDEP_H_ XXX */ diff --git a/sys/dev/isa/isadmavar.h b/sys/dev/isa/isadmavar.h index 20334013d6e..aa5d1b6bce1 100644 --- a/sys/dev/isa/isadmavar.h +++ b/sys/dev/isa/isadmavar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: isadmavar.h,v 1.5 1996/11/29 22:55:02 niklas Exp $ */ +/* $OpenBSD: isadmavar.h,v 1.6 1997/09/22 21:03:52 niklas Exp $ */ /* $NetBSD: isadmavar.h,v 1.4 1996/03/01 04:08:46 mycroft Exp $ */ #define DMAMODE_WRITE 0 @@ -19,6 +19,9 @@ struct isadma_seg { /* a physical contiguous segment */ vm_size_t length; /* length of this segment (bytes) */ }; +vm_offset_t isadma_alloc __P((vm_size_t, vm_offset_t, int)); +caddr_t isadma_vaddr __P((vm_offset_t)); +void isadma_free __P((vm_offset_t, vm_size_t)); int isadma_map __P((caddr_t, vm_size_t, struct isadma_seg *, int)); void isadma_unmap __P((caddr_t, vm_size_t, int, struct isadma_seg *)); void isadma_copytobuf __P((caddr_t, vm_size_t, int, struct isadma_seg *)); |