1 /* $NetBSD: bus_subr.c,v 1.23 2001/09/11 20:37:13 chs 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 vaddr_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 vaddr_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_kenter_pa(pgva, pa, VM_PROT_READ | VM_PROT_WRITE); 111 pmap_update(pmap_kernel()); 112 splx(s); 113 114 return ((void *)(pgva + off)); 115 } 116 117 void bus_tmapout(vp) 118 void *vp; 119 { 120 vaddr_t pgva; 121 int s; 122 123 pgva = m68k_trunc_page(vp); 124 if (pgva != tmp_vpages[1]) 125 return; 126 127 s = splvm(); 128 pmap_kremove(pgva, NBPG); 129 pmap_update(pmap_kernel()); 130 --tmp_vpages_inuse; 131 splx(s); 132 } 133 134 /* 135 * Make a permanent mapping for a device. 136 */ 137 void * 138 bus_mapin(bustype, pa, sz) 139 int bustype, pa, sz; 140 { 141 vaddr_t va; 142 int off; 143 144 if ((bustype < 0) || (bustype >= BUS__NTYPES)) 145 panic("bus_mapin: bustype"); 146 147 off = pa & PGOFSET; 148 pa -= off; 149 sz += off; 150 sz = m68k_round_page(sz); 151 152 /* Borrow PROM mappings if we can. */ 153 if (bustype == BUS_OBIO) { 154 va = (vaddr_t) obio_find_mapping(pa, sz); 155 if (va != 0) 156 goto done; 157 } 158 159 pa &= bus_info[bustype].mask; 160 pa |= bus_info[bustype].base; 161 pa |= PMAP_NC; /* non-cached */ 162 163 /* Get some kernel virtual address space. */ 164 va = uvm_km_valloc_wait(kernel_map, sz); 165 if (va == 0) 166 panic("bus_mapin"); 167 168 /* Map it to the specified bus. */ 169 pmap_map(va, pa, pa + sz, VM_PROT_ALL); 170 171 done: 172 return ((void*)(va + off)); 173 } 174 175 void 176 bus_mapout(ptr, sz) 177 void *ptr; 178 int sz; 179 { 180 vaddr_t va; 181 int off; 182 183 va = (vaddr_t)ptr; 184 185 /* If it was a PROM mapping, do NOT free it! */ 186 if ((va >= SUN3X_MONSTART) && (va < SUN3X_MONEND)) 187 return; 188 189 off = va & PGOFSET; 190 va -= off; 191 sz += off; 192 sz = m68k_round_page(sz); 193 194 uvm_km_free_wakeup(kernel_map, va, sz); 195 } 196