1 /* $NetBSD: bus_subr.c,v 1.20 2001/04/24 04:31:14 thorpej Exp $ */ 2 3 /*- 4 * Copyright (c) 1996 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Adam Glass and Gordon W. Ross. 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 NetBSD 21 * Foundation, Inc. and its contributors. 22 * 4. Neither the name of The NetBSD Foundation nor the names of its 23 * contributors may be used to endorse or promote products derived 24 * from this software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 36 * POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 /* 40 * bus_xxx support functions, Sun3X-specific part. 41 * The common stuff is in autoconf.c 42 */ 43 44 #include <sys/param.h> 45 #include <sys/systm.h> 46 #include <sys/device.h> 47 48 #include <uvm/uvm_extern.h> 49 50 #include <machine/autoconf.h> 51 #include <machine/cpu.h> 52 #include <machine/mon.h> 53 #include <machine/pmap.h> 54 #include <machine/pte.h> 55 56 #include <sun3/sun3/machdep.h> 57 #include <sun3/sun3x/vme.h> 58 59 label_t *nofault; 60 61 /* These are defined in pmap.c */ 62 extern vm_offset_t tmp_vpages[]; 63 extern int tmp_vpages_inuse; 64 65 static const struct { 66 long base; 67 long mask; 68 } bus_info[BUS__NTYPES] = { 69 { /* OBIO */ 0, ~0 }, 70 { /* OBMEM */ 0, ~0 }, 71 /* VME A16 */ 72 { VME16D16_BASE, VME16_MASK }, 73 { VME16D32_BASE, VME16_MASK }, 74 /* VME A24 */ 75 { VME24D16_BASE, VME24_MASK }, 76 { VME24D32_BASE, VME24_MASK }, 77 /* VME A32 */ 78 { VME32D16_BASE, VME32_MASK }, 79 { VME32D32_BASE, VME32_MASK }, 80 }; 81 82 /* 83 * Create a temporary, one-page mapping for a device. 84 * This is used by some device probe routines that 85 * need to do peek/write/read tricks. 86 */ 87 void * 88 bus_tmapin(bustype, pa) 89 int bustype, pa; 90 { 91 vm_offset_t pgva; 92 int off, s; 93 94 if ((bustype < 0) || (bustype >= BUS__NTYPES)) 95 panic("bus_tmapin: bustype"); 96 97 off = pa & PGOFSET; 98 pa -= off; 99 100 pa &= bus_info[bustype].mask; 101 pa |= bus_info[bustype].base; 102 pa |= PMAP_NC; 103 104 s = splvm(); 105 if (tmp_vpages_inuse) 106 panic("bus_tmapin: tmp_vpages_inuse"); 107 tmp_vpages_inuse++; 108 109 pgva = tmp_vpages[1]; 110 pmap_enter(pmap_kernel(), pgva, pa, 111 (VM_PROT_READ|VM_PROT_WRITE), PMAP_WIRED); 112 pmap_update(); 113 splx(s); 114 115 return ((void *)(pgva + off)); 116 } 117 118 void bus_tmapout(vp) 119 void *vp; 120 { 121 vm_offset_t pgva; 122 int s; 123 124 pgva = m68k_trunc_page(vp); 125 if (pgva != tmp_vpages[1]) 126 return; 127 128 s = splvm(); 129 pmap_remove(pmap_kernel(), pgva, pgva + NBPG); 130 pmap_update(); 131 --tmp_vpages_inuse; 132 splx(s); 133 } 134 135 /* 136 * Make a permanent mapping for a device. 137 */ 138 void * 139 bus_mapin(bustype, pa, sz) 140 int bustype, pa, sz; 141 { 142 vm_offset_t va; 143 int off; 144 145 if ((bustype < 0) || (bustype >= BUS__NTYPES)) 146 panic("bus_mapin: bustype"); 147 148 off = pa & PGOFSET; 149 pa -= off; 150 sz += off; 151 sz = m68k_round_page(sz); 152 153 /* Borrow PROM mappings if we can. */ 154 if (bustype == BUS_OBIO) { 155 va = (vm_offset_t) obio_find_mapping(pa, sz); 156 if (va != 0) 157 goto done; 158 } 159 160 pa &= bus_info[bustype].mask; 161 pa |= bus_info[bustype].base; 162 pa |= PMAP_NC; /* non-cached */ 163 164 /* Get some kernel virtual address space. */ 165 va = uvm_km_valloc_wait(kernel_map, sz); 166 if (va == 0) 167 panic("bus_mapin"); 168 169 /* Map it to the specified bus. */ 170 pmap_map(va, pa, pa + sz, VM_PROT_ALL); 171 172 done: 173 return ((void*)(va + off)); 174 } 175 176 void 177 bus_mapout(ptr, sz) 178 void *ptr; 179 int sz; 180 { 181 vm_offset_t va; 182 int off; 183 184 va = (vm_offset_t)ptr; 185 186 /* If it was a PROM mapping, do NOT free it! */ 187 if ((va >= SUN3X_MONSTART) && (va < SUN3X_MONEND)) 188 return; 189 190 off = va & PGOFSET; 191 va -= off; 192 sz += off; 193 sz = m68k_round_page(sz); 194 195 uvm_km_free_wakeup(kernel_map, va, sz); 196 } 197