1 /* $NetBSD: autoconf.c,v 1.36 1996/10/13 03:47:45 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1994 Gordon W. Ross 5 * Copyright (c) 1993 Adam Glass 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Adam Glass. 19 * 4. The name of the authors may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Setup the system to run on the current machine. 36 * 37 * Configure() is called at boot time. Available 38 * devices are determined (from possibilities mentioned in ioconf.c), 39 * and the drivers are initialized. 40 */ 41 42 #include <sys/param.h> 43 #include <sys/systm.h> 44 #include <sys/device.h> 45 #include <sys/map.h> 46 #include <sys/buf.h> 47 #include <sys/dkstat.h> 48 #include <sys/conf.h> 49 #include <sys/dmap.h> 50 #include <sys/reboot.h> 51 52 #include <vm/vm.h> 53 #include <vm/vm_kern.h> 54 #include <vm/vm_map.h> 55 56 #include <machine/autoconf.h> 57 #include <machine/cpu.h> 58 #include <machine/isr.h> 59 #include <machine/pte.h> 60 #include <machine/pmap.h> 61 62 extern int soft1intr(); 63 64 void swapgeneric(); 65 void swapconf(), dumpconf(); 66 67 int cold; 68 69 void configure() 70 { 71 struct device *mainbus; 72 73 /* General device autoconfiguration. */ 74 mainbus = config_rootfound("mainbus", NULL); 75 if (mainbus == NULL) 76 panic("configure: mainbus not found"); 77 78 /* Choose root and swap devices. */ 79 swapgeneric(); 80 swapconf(); 81 dumpconf(); 82 cold = 0; 83 } 84 85 /* 86 * Configure swap space and related parameters. 87 */ 88 void 89 swapconf() 90 { 91 struct swdevt *swp; 92 u_int maj; 93 int nblks; 94 95 for (swp = swdevt; swp->sw_dev != NODEV; swp++) { 96 97 maj = major(swp->sw_dev); 98 if (maj > nblkdev) /* paranoid? */ 99 break; 100 101 if (bdevsw[maj].d_psize) { 102 nblks = (*bdevsw[maj].d_psize)(swp->sw_dev); 103 if (nblks > 0 && 104 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 105 swp->sw_nblks = nblks; 106 swp->sw_nblks = ctod(dtoc(swp->sw_nblks)); 107 } 108 } 109 } 110 111 /* 112 * Generic "bus" support functions. 113 * 114 * bus_scan: 115 * This function is passed to config_search() by the attach function 116 * for each of the "bus" drivers (obctl, obio, obmem, vmes, vmel). 117 * The purpose of this function is to copy the "locators" into our 118 * confargs structure, so child drivers may use the confargs both 119 * as match parameters and as temporary storage for the defaulted 120 * locator values determined in the child_match and preserved for 121 * the child_attach function. If the bus attach functions just 122 * used config_found, then we would not have an opportunity to 123 * setup the confargs for each child match and attach call. 124 * 125 * bus_print: 126 * Just prints out the final (non-default) locators. 127 */ 128 int bus_scan(parent, child, aux) 129 struct device *parent; 130 void *child, *aux; 131 { 132 struct cfdata *cf = child; 133 struct confargs *ca = aux; 134 cfmatch_t mf; 135 136 #ifdef DIAGNOSTIC 137 if (parent->dv_cfdata->cf_driver->cd_indirect) 138 panic("bus_scan: indirect?"); 139 if (cf->cf_fstate == FSTATE_STAR) 140 panic("bus_scan: FSTATE_STAR"); 141 #endif 142 143 /* ca->ca_bustype set by parent */ 144 ca->ca_paddr = cf->cf_loc[0]; 145 ca->ca_intpri = cf->cf_loc[1]; 146 ca->ca_intvec = -1; 147 148 if ((ca->ca_bustype == BUS_VME16) || 149 (ca->ca_bustype == BUS_VME32)) 150 { 151 ca->ca_intvec = cf->cf_loc[2]; 152 } 153 154 /* 155 * Note that this allows the match function to save 156 * defaulted locators in the confargs that will be 157 * preserved for the related attach call. 158 */ 159 mf = cf->cf_attach->ca_match; 160 if ((*mf)(parent, cf, ca) > 0) { 161 config_attach(parent, cf, ca, bus_print); 162 } 163 return (0); 164 } 165 166 /* 167 * Print out the confargs. The parent name is non-NULL 168 * when there was no match found by config_found(). 169 */ 170 int 171 bus_print(args, name) 172 void *args; 173 const char *name; 174 { 175 struct confargs *ca = args; 176 177 if (name) 178 printf("%s:", name); 179 180 if (ca->ca_paddr != -1) 181 printf(" addr 0x%x", ca->ca_paddr); 182 if (ca->ca_intpri != -1) 183 printf(" level %d", ca->ca_intpri); 184 if (ca->ca_intvec != -1) 185 printf(" vector 0x%x", ca->ca_intvec); 186 187 return(UNCONF); 188 } 189 190 extern vm_offset_t tmp_vpages[]; 191 static const int bustype_to_ptetype[4] = { 192 PGT_OBMEM, 193 PGT_OBIO, 194 PGT_VME_D16, 195 PGT_VME_D32, 196 }; 197 198 /* 199 * Read addr with size len (1,2,4) into val. 200 * If this generates a bus error, return -1 201 * 202 * Create a temporary mapping, 203 * Try the access using peek_* 204 * Clean up temp. mapping 205 */ 206 int bus_peek(bustype, paddr, sz) 207 int bustype, paddr, sz; 208 { 209 int off, pte, rv; 210 vm_offset_t pgva; 211 caddr_t va; 212 213 if (bustype & ~3) 214 return -1; 215 216 off = paddr & PGOFSET; 217 paddr -= off; 218 pte = PA_PGNUM(paddr); 219 pte |= bustype_to_ptetype[bustype]; 220 pte |= (PG_VALID | PG_WRITE | PG_SYSTEM | PG_NC); 221 222 pgva = tmp_vpages[0]; 223 va = (caddr_t)pgva + off; 224 225 /* All mappings in tmp_vpages are non-cached, so no flush. */ 226 set_pte(pgva, pte); 227 228 /* 229 * OK, try the access using one of the assembly routines 230 * that will set pcb_onfault and catch any bus errors. 231 */ 232 switch (sz) { 233 case 1: 234 rv = peek_byte(va); 235 break; 236 case 2: 237 rv = peek_word(va); 238 break; 239 default: 240 printf(" bus_peek: invalid size=%d\n", sz); 241 rv = -1; 242 } 243 244 /* All mappings in tmp_vpages are non-cached, so no flush. */ 245 set_pte(pgva, PG_INVAL); 246 247 return rv; 248 } 249 250 static const int bustype_to_pmaptype[4] = { 251 0, 252 PMAP_OBIO, 253 PMAP_VME16, 254 PMAP_VME32, 255 }; 256 257 char * 258 bus_mapin(bustype, paddr, sz) 259 int bustype, paddr, sz; 260 { 261 int off, pa, pgs, pmt; 262 vm_offset_t va, retval; 263 264 if (bustype & ~3) 265 return (NULL); 266 267 off = paddr & PGOFSET; 268 pa = paddr - off; 269 sz += off; 270 sz = sun3_round_page(sz); 271 272 pmt = bustype_to_pmaptype[bustype]; 273 pmt |= PMAP_NC; /* non-cached */ 274 275 /* Get some kernel virtual address space. */ 276 va = kmem_alloc_wait(kernel_map, sz); 277 if (va == 0) 278 panic("bus_mapin"); 279 retval = va + off; 280 281 /* Map it to the specified bus. */ 282 #if 0 /* XXX */ 283 /* This has a problem with wrap-around... */ 284 pmap_map((int)va, pa | pmt, pa + sz, VM_PROT_ALL); 285 #else 286 do { 287 pmap_enter(pmap_kernel(), va, pa | pmt, VM_PROT_ALL, FALSE); 288 va += NBPG; 289 pa += NBPG; 290 } while ((sz -= NBPG) > 0); 291 #endif 292 293 return ((char*)retval); 294 } 295