|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1990 University of Utah. ! 3: * Copyright (c) 1991 The Regents of the University of California. ! 4: * All rights reserved. ! 5: * ! 6: * This code is derived from software contributed to Berkeley by ! 7: * the Systems Programming Group of the University of Utah Computer ! 8: * Science Department. ! 9: * ! 10: * Redistribution and use in source and binary forms, with or without ! 11: * modification, are permitted provided that the following conditions ! 12: * are met: ! 13: * 1. Redistributions of source code must retain the above copyright ! 14: * notice, this list of conditions and the following disclaimer. ! 15: * 2. Redistributions in binary form must reproduce the above copyright ! 16: * notice, this list of conditions and the following disclaimer in the ! 17: * documentation and/or other materials provided with the distribution. ! 18: * 3. All advertising materials mentioning features or use of this software ! 19: * must display the following acknowledgement: ! 20: * This product includes software developed by the University of ! 21: * California, Berkeley and its contributors. ! 22: * 4. Neither the name of the University nor the names of its contributors ! 23: * may be used to endorse or promote products derived from this software ! 24: * without specific prior written permission. ! 25: * ! 26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 36: * SUCH DAMAGE. ! 37: * ! 38: * @(#)device_pager.c 7.2 (Berkeley) 4/20/91 ! 39: */ ! 40: ! 41: /* ! 42: * Page to/from special files. ! 43: */ ! 44: ! 45: #include "devpager.h" ! 46: #if NDEVPAGER > 0 ! 47: ! 48: #include "param.h" ! 49: #include "conf.h" ! 50: #include "mman.h" ! 51: #include "malloc.h" ! 52: ! 53: #include "vm.h" ! 54: #include "vm_page.h" ! 55: #include "vm_kern.h" ! 56: #include "device_pager.h" ! 57: ! 58: queue_head_t dev_pager_list; /* list of managed devices */ ! 59: ! 60: #ifdef DEBUG ! 61: int dpagerdebug = 0; ! 62: #define DDB_FOLLOW 0x01 ! 63: #define DDB_INIT 0x02 ! 64: #define DDB_ALLOC 0x04 ! 65: #define DDB_FAIL 0x08 ! 66: #endif ! 67: ! 68: void ! 69: dev_pager_init() ! 70: { ! 71: #ifdef DEBUG ! 72: if (dpagerdebug & DDB_FOLLOW) ! 73: printf("dev_pager_init()\n"); ! 74: #endif ! 75: queue_init(&dev_pager_list); ! 76: } ! 77: ! 78: vm_pager_t ! 79: dev_pager_alloc(handle, size, prot) ! 80: caddr_t handle; ! 81: vm_size_t size; ! 82: vm_prot_t prot; ! 83: { ! 84: dev_t dev; ! 85: vm_pager_t pager; ! 86: int (*mapfunc)(), nprot; ! 87: register vm_object_t object; ! 88: register vm_page_t page; ! 89: register dev_pager_t devp; ! 90: register int npages, off; ! 91: extern int nullop(), enodev(); ! 92: ! 93: ! 94: #ifdef DEBUG ! 95: if (dpagerdebug & DDB_FOLLOW) ! 96: printf("dev_pager_alloc(%x, %x, %x)\n", handle, size, prot); ! 97: #endif ! 98: /* ! 99: * Pageout to device, should never happen. ! 100: */ ! 101: if (handle == NULL) ! 102: panic("dev_pager_alloc called"); ! 103: ! 104: /* ! 105: * Look it up, creating as necessary ! 106: */ ! 107: pager = vm_pager_lookup(&dev_pager_list, handle); ! 108: if (pager == NULL) { ! 109: /* ! 110: * Validation. Make sure this device can be mapped ! 111: * and that range to map is acceptible to device. ! 112: */ ! 113: dev = (dev_t)handle; ! 114: mapfunc = cdevsw[major(dev)].d_mmap; ! 115: if (!mapfunc || mapfunc == enodev || mapfunc == nullop) ! 116: return(NULL); ! 117: nprot = 0; ! 118: if (prot & VM_PROT_READ) ! 119: nprot |= PROT_READ; ! 120: if (prot & VM_PROT_WRITE) ! 121: nprot |= PROT_WRITE; ! 122: if (prot & VM_PROT_EXECUTE) ! 123: nprot |= PROT_EXEC; ! 124: npages = atop(round_page(size)); ! 125: for (off = 0; npages--; off += PAGE_SIZE) ! 126: if ((*mapfunc)(dev, off, nprot) == -1) ! 127: return(NULL); ! 128: /* ! 129: * Allocate and initialize pager structs ! 130: */ ! 131: pager = (vm_pager_t)malloc(sizeof *pager, M_VMPAGER, M_WAITOK); ! 132: if (pager == NULL) ! 133: return(NULL); ! 134: devp = (dev_pager_t)malloc(sizeof *devp, M_VMPGDATA, M_WAITOK); ! 135: if (devp == NULL) { ! 136: free((caddr_t)pager, M_VMPAGER); ! 137: return(NULL); ! 138: } ! 139: devp->devp_dev = dev; ! 140: devp->devp_npages = atop(round_page(size)); ! 141: pager->pg_handle = handle; ! 142: pager->pg_ops = &devicepagerops; ! 143: pager->pg_type = PG_DEVICE; ! 144: pager->pg_data = (caddr_t)devp; ! 145: /* ! 146: * Allocate object and vm_page structures to describe memory ! 147: */ ! 148: npages = devp->devp_npages; ! 149: object = devp->devp_object = vm_object_allocate(ptoa(npages)); ! 150: vm_object_enter(object, pager); ! 151: vm_object_setpager(object, pager, (vm_offset_t)0, FALSE); ! 152: devp->devp_pages = (vm_page_t) ! 153: kmem_alloc(kernel_map, npages*sizeof(struct vm_page)); ! 154: off = 0; ! 155: for (page = devp->devp_pages; ! 156: page < &devp->devp_pages[npages]; page++) { ! 157: vm_object_lock(object); ! 158: vm_page_init(page, object, off); ! 159: page->phys_addr = ! 160: pmap_phys_address((*mapfunc)(dev, off, nprot)); ! 161: page->wire_count = 1; ! 162: page->fictitious = TRUE; ! 163: PAGE_WAKEUP(page); ! 164: vm_object_unlock(object); ! 165: off += PAGE_SIZE; ! 166: } ! 167: /* ! 168: * Finally, put it on the managed list so other can find it. ! 169: */ ! 170: queue_enter(&dev_pager_list, devp, dev_pager_t, devp_list); ! 171: #ifdef DEBUG ! 172: if (dpagerdebug & DDB_ALLOC) ! 173: printf("dev_pager_alloc: pages %d@%x\n", ! 174: devp->devp_npages, devp->devp_pages); ! 175: #endif ! 176: } else { ! 177: /* ! 178: * vm_object_lookup() gains a reference and also ! 179: * removes the object from the cache. ! 180: */ ! 181: devp = (dev_pager_t)pager->pg_data; ! 182: if (vm_object_lookup(pager) != devp->devp_object) ! 183: panic("dev_pager_setup: bad object"); ! 184: } ! 185: #ifdef DEBUG ! 186: if (dpagerdebug & DDB_ALLOC) { ! 187: printf("dev_pager_alloc: pager %x devp %x object %x\n", ! 188: pager, devp, object); ! 189: vm_object_print(object, FALSE); ! 190: } ! 191: #endif ! 192: return(pager); ! 193: ! 194: } ! 195: ! 196: void ! 197: dev_pager_dealloc(pager) ! 198: vm_pager_t pager; ! 199: { ! 200: dev_pager_t devp = (dev_pager_t)pager->pg_data; ! 201: register vm_object_t object; ! 202: ! 203: #ifdef DEBUG ! 204: if (dpagerdebug & DDB_FOLLOW) ! 205: printf("dev_pager_dealloc(%x)\n", pager); ! 206: #endif ! 207: queue_remove(&dev_pager_list, devp, dev_pager_t, devp_list); ! 208: object = devp->devp_object; ! 209: #ifdef DEBUG ! 210: if (dpagerdebug & DDB_ALLOC) ! 211: printf("dev_pager_dealloc: devp %x object %x pages %d@%x\n", ! 212: devp, object, devp->devp_npages, devp->devp_pages); ! 213: #endif ! 214: while (!queue_empty(&object->memq)) ! 215: vm_page_remove((vm_page_t)queue_first(&object->memq)); ! 216: kmem_free(kernel_map, devp->devp_pages, ! 217: devp->devp_npages * sizeof(struct vm_page)); ! 218: free((caddr_t)devp, M_VMPGDATA); ! 219: pager->pg_data = 0; ! 220: } ! 221: ! 222: dev_pager_getpage(pager, m, sync) ! 223: vm_pager_t pager; ! 224: vm_page_t m; ! 225: boolean_t sync; ! 226: { ! 227: #ifdef DEBUG ! 228: if (dpagerdebug & DDB_FOLLOW) ! 229: printf("dev_pager_getpage(%x, %x)\n", pager, m); ! 230: #endif ! 231: return(VM_PAGER_BAD); ! 232: } ! 233: ! 234: dev_pager_putpage(pager, m, sync) ! 235: vm_pager_t pager; ! 236: vm_page_t m; ! 237: boolean_t sync; ! 238: { ! 239: #ifdef DEBUG ! 240: if (dpagerdebug & DDB_FOLLOW) ! 241: printf("dev_pager_putpage(%x, %x)\n", pager, m); ! 242: #endif ! 243: if (pager == NULL) ! 244: return; ! 245: panic("dev_pager_putpage called"); ! 246: } ! 247: ! 248: boolean_t ! 249: dev_pager_haspage(pager, offset) ! 250: vm_pager_t pager; ! 251: vm_offset_t offset; ! 252: { ! 253: #ifdef DEBUG ! 254: if (dpagerdebug & DDB_FOLLOW) ! 255: printf("dev_pager_haspage(%x, %x)\n", pager, offset); ! 256: #endif ! 257: return(TRUE); ! 258: } ! 259: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.