1 /* $NetBSD: autoconf.c,v 1.18 1994/12/13 18:37:22 gwr 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 mainbusattach __P((struct device *, struct device *, void *)); 65 void conf_init(), swapgeneric(); 66 void swapconf(), dumpconf(); 67 68 69 struct mainbus_softc { 70 struct device mainbus_dev; 71 }; 72 73 struct cfdriver mainbuscd = 74 { NULL, "mainbus", always_match, mainbusattach, DV_DULL, 75 sizeof(struct mainbus_softc), 0}; 76 77 void mainbusattach(parent, self, args) 78 struct device *parent; 79 struct device *self; 80 void *args; 81 { 82 struct cfdata *new_match; 83 84 printf("\n"); 85 while (1) { 86 new_match = config_search(NULL, self, NULL); 87 if (!new_match) break; 88 config_attach(self, new_match, NULL, NULL); 89 } 90 } 91 92 int nmi_intr(arg) 93 int arg; 94 { 95 printf("nmi interrupt received\n"); 96 return 1; 97 } 98 99 void configure() 100 { 101 int root_found; 102 103 /* General device autoconfiguration. */ 104 root_found = config_rootfound("mainbus", NULL); 105 if (!root_found) 106 panic("configure: mainbus not found"); 107 108 /* Install non-device interrupt handlers. */ 109 isr_add_autovect(nmi_intr, 0, 7); 110 isr_add_autovect(soft1intr, 0, 1); 111 isr_cleanup(); 112 113 /* Build table for CHR-to-BLK translation, etc. */ 114 conf_init(); 115 116 #ifdef GENERIC 117 /* Choose root and swap devices. */ 118 swapgeneric(); 119 #endif 120 swapconf(); 121 dumpconf(); 122 } 123 124 /* 125 * Configure swap space and related parameters. 126 */ 127 void 128 swapconf() 129 { 130 struct swdevt *swp; 131 u_int maj; 132 int nblks; 133 134 for (swp = swdevt; swp->sw_dev != NODEV; swp++) { 135 maj = major(swp->sw_dev); 136 137 if (maj > nblkdev) /* paranoid? */ 138 break; 139 140 if (bdevsw[maj].d_psize) { 141 nblks = (*bdevsw[maj].d_psize)(swp->sw_dev); 142 if (nblks > 0 && 143 (swp->sw_nblks == 0 || swp->sw_nblks > nblks)) 144 swp->sw_nblks = nblks; 145 swp->sw_nblks = ctod(dtoc(swp->sw_nblks)); 146 } 147 } 148 } 149 150 int always_match(parent, cf, args) 151 struct device *parent; 152 void *cf; 153 void *args; 154 { 155 return 1; 156 } 157 158 /* 159 * Generic "bus" support functions. 160 */ 161 void bus_scan(parent, child, bustype) 162 struct device *parent; 163 void *child; 164 int bustype; 165 { 166 struct cfdata *cf = child; 167 struct confargs ca; 168 cfmatch_t match; 169 170 #ifdef DIAGNOSTIC 171 if (parent->dv_cfdata->cf_driver->cd_indirect) 172 panic("bus_scan: indirect?"); 173 if (cf->cf_fstate == FSTATE_STAR) 174 panic("bus_scan: FSTATE_STAR"); 175 #endif 176 177 ca.ca_bustype = bustype; 178 ca.ca_paddr = cf->cf_loc[0]; 179 ca.ca_intpri = cf->cf_loc[1]; 180 181 if ((bustype == BUS_VME16) || (bustype == BUS_VME32)) { 182 ca.ca_intvec = cf->cf_loc[2]; 183 } else { 184 ca.ca_intvec = -1; 185 } 186 187 match = cf->cf_driver->cd_match; 188 if ((*match)(parent, cf, &ca) > 0) { 189 config_attach(parent, cf, &ca, bus_print); 190 } 191 } 192 193 int 194 bus_print(args, name) 195 void *args; 196 char *name; 197 { 198 struct confargs *ca = args; 199 200 if (ca->ca_paddr != -1) 201 printf(" addr 0x%x", ca->ca_paddr); 202 if (ca->ca_intpri != -1) 203 printf(" level %d", ca->ca_intpri); 204 if (ca->ca_intvec != -1) 205 printf(" vector 0x%x", ca->ca_intvec); 206 /* XXXX print flags? */ 207 return(QUIET); 208 } 209 210 /* 211 * Read addr with size len (1,2,4) into val. 212 * If this generates a bus error, return -1 213 * 214 * Create a temporary mapping, 215 * Try the access using fu{byte,sword,word} 216 * Clean up temp. mapping 217 */ 218 extern vm_offset_t tmp_vpages[]; 219 extern int fubyte(), fusword(), fuword(); 220 int bus_peek(bustype, paddr, sz) 221 int bustype, paddr, sz; 222 { 223 int off, pte, rv, s; 224 vm_offset_t pgva; 225 caddr_t va; 226 227 off = paddr & PGOFSET; 228 paddr -= off; 229 pte = PA_PGNUM(paddr); 230 231 /* 232 * The temporary mapping has user-accessibility 233 * because fubyte et. al. do the access using 234 * an explicit switch to user space... 235 * (XXX -Should see if fubyte still needs that.) 236 */ 237 #define PG_PEEK PG_VALID | PG_WRITE | PG_NC 238 switch (bustype) { 239 case BUS_OBMEM: 240 pte |= (PG_PEEK | PGT_OBMEM); 241 break; 242 case BUS_OBIO: 243 pte |= (PG_PEEK | PGT_OBIO); 244 break; 245 case BUS_VME16: 246 pte |= (PG_PEEK | PGT_VME_D16); 247 break; 248 case BUS_VME32: 249 pte |= (PG_PEEK | PGT_VME_D32); 250 break; 251 default: 252 return (-1); 253 } 254 #undef PG_PEEK 255 256 s = splvm(); 257 258 pgva = tmp_vpages[0]; 259 va = (caddr_t)pgva + off; 260 261 set_pte(pgva, pte); 262 263 /* 264 * OK, try the access using one of the assembly routines 265 * that will set pcb_onfault and catch any bus errors. 266 */ 267 switch (sz) { 268 case 1: 269 rv = fubyte(va); 270 break; 271 case 2: 272 rv = fusword(va); 273 break; 274 case 4: 275 rv = fuword(va); 276 break; 277 default: 278 rv = -1; 279 } 280 281 set_pte(pgva, PG_INVAL); 282 splx(s); 283 return rv; 284 } 285