isa.c (322) | isa.c (593) |
---|---|
1/*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * | 1/*- 2 * Copyright (c) 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to Berkeley by 6 * William Jolitz. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 19 unchanged lines hidden (view full) --- 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34 * SUCH DAMAGE. 35 * |
36 * @(#)isa.c 7.2 (Berkeley) 5/13/91 37 * 38 * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE 39 * -------------------- ----- ---------------------- 40 * CURRENT PATCH LEVEL: 4 00163 41 * -------------------- ----- ---------------------- 42 * 43 * 18 Aug 92 Frank Maclachlan *See comments below 44 * 25 Mar 93 Rodney W. Grimes Added counter for stray interrupt, 45 * turned on logging of stray interrupts, 46 * Now prints maddr, msize, and flags 47 * after finding a device. 48 * 26 Apr 93 Bruce Evans New intr-0.1 code 49 * Rodney W. Grimes Only print io address if id_alive != -1 50 * 17 May 93 Rodney W. Grimes renamed stray interrupt counters to 51 * work with new intr-0.1 code. 52 * Enabled printf for interrupt masks to 53 * aid in bug reports. 54 * 27 May 93 Guido van Rooij New routine add find_isa_dev | 36 * from: @(#)isa.c 7.2 (Berkeley) 5/13/91 37 * $Id$ |
55 */ | 38 */ |
56static char rcsid[] = "$Header: /a/cvs/386BSD/src/sys/i386/isa/isa.c,v 1.2 1993/06/18 22:18:57 rgrimes Exp $"; | |
57 58/* 59 * code to manage AT bus 60 * 61 * 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com): 62 * Fixed uninitialized variable problem and added code to deal 63 * with DMA page boundaries in isa_dmarangecheck(). Fixed word 64 * mode DMA count compution and reorganized DMA setup code in --- 30 unchanged lines hidden (view full) --- 95*/ 96#define DMA2_CHN(c) (IO_DMA1 + 2*(2*(c))) /* addr reg for channel c */ 97#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */ 98#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ 99#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ 100 101int config_isadev __P((struct isa_device *, u_int *)); 102 | 39 40/* 41 * code to manage AT bus 42 * 43 * 92/08/18 Frank P. MacLachlan (fpm@crash.cts.com): 44 * Fixed uninitialized variable problem and added code to deal 45 * with DMA page boundaries in isa_dmarangecheck(). Fixed word 46 * mode DMA count compution and reorganized DMA setup code in --- 30 unchanged lines hidden (view full) --- 77*/ 78#define DMA2_CHN(c) (IO_DMA1 + 2*(2*(c))) /* addr reg for channel c */ 79#define DMA2_SMSK (IO_DMA2 + 2*10) /* single mask register */ 80#define DMA2_MODE (IO_DMA2 + 2*11) /* mode register */ 81#define DMA2_FFC (IO_DMA2 + 2*12) /* clear first/last FF */ 82 83int config_isadev __P((struct isa_device *, u_int *)); 84 |
103#ifdef notyet 104struct rlist *isa_iomem; 105 | |
106/* | 85/* |
107 * Configure all ISA devices | 86 * print a conflict message |
108 */ | 87 */ |
109isa_configure() { 110 struct isa_device *dvp; 111 struct isa_driver *dp; 112 113 splhigh(); 114 INTREN(IRQ_SLAVE); 115 /*rlist_free(&isa_iomem, 0xa0000, 0xfffff);*/ 116 for (dvp = isa_devtab_tty; dvp; dvp++) 117 (void) config_isadev(dvp, &ttymask); 118 for (dvp = isa_devtab_bio; dvp; dvp++) 119 (void) config_isadev(dvp, &biomask); 120 for (dvp = isa_devtab_net; dvp; dvp++) 121 (void) config_isadev(dvp, &netmask); 122 for (dvp = isa_devtab_null; dvp; dvp++) 123 (void) config_isadev(dvp, (u_int *) NULL); 124#include "sl.h" 125#if NSL > 0 126 netmask |= ttymask; 127 ttymask |= netmask; 128#endif 129/* printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask); */ 130 splnone(); | 88void 89conflict(dvp, tmpdvp, item, reason, format) 90 struct isa_device *dvp, *tmpdvp; 91 int item; 92 char *reason; 93 char *format; 94{ 95 printf("%s%d not probed due to %s conflict with %s%d at ", 96 dvp->id_driver->name, dvp->id_unit, reason, 97 tmpdvp->id_driver->name, tmpdvp->id_unit); 98 printf(format, item); 99 printf("\n"); |
131} 132 133/* | 100} 101 102/* |
134 * Configure an ISA device. | 103 * Check to see if things are alread in use, like IRQ's, I/O addresses 104 * and Memory addresses. |
135 */ | 105 */ |
136config_isadev(isdp, mp) 137 struct isa_device *isdp; 138 u_int *mp; | 106int 107haveseen(dvp, tmpdvp) 108 struct isa_device *dvp, *tmpdvp; |
139{ | 109{ |
140 struct isa_driver *dp; 141 static short drqseen, irqseen; 142 143 if (dp = isdp->id_driver) { 144 /* if a device with i/o memory, convert to virtual address */ 145 if (isdp->id_maddr) { 146 extern unsigned int atdevbase; | 110 int status = 0; |
147 | 111 |
148 isdp->id_maddr -= IOM_BEGIN; 149 isdp->id_maddr += atdevbase; | 112 /* 113 * Only check against devices that have already been found 114 */ 115 if (tmpdvp->id_alive) { 116 /* 117 * Check for I/O address conflict. We can only check the 118 * starting address of the device against the range of the 119 * device that has already been probed since we do not 120 * know how many I/O addresses this device uses. 121 */ 122 if (tmpdvp->id_alive != -1) { 123 if ((dvp->id_iobase >= tmpdvp->id_iobase) && 124 (dvp->id_iobase <= 125 (tmpdvp->id_iobase + tmpdvp->id_alive - 1))) { 126 conflict(dvp, tmpdvp, dvp->id_iobase, 127 "I/O address", "0x%x"); 128 status = 1; 129 } |
150 } | 130 } |
151 isdp->id_alive = (*dp->probe)(isdp); 152 if (isdp->id_alive) { 153 154 printf("%s%d at port 0x%x ", dp->name, 155 isdp->id_unit, isdp->id_iobase); 156 157 /* check for conflicts */ 158 if (irqseen & isdp->id_irq) { 159 printf("INTERRUPT CONFLICT - irq%d\n", 160 ffs(isdp->id_irq) - 1); 161 return (0); | 131 /* 132 * Check for Memory address conflict. We can check for 133 * range overlap, but it will not catch all cases since the 134 * driver may adjust the msize paramater during probe, for 135 * now we just check that the starting address does not 136 * fall within any allocated region. 137 * XXX could add a second check after the probe for overlap, 138 * since at that time we would know the full range. 139 * XXX KERNBASE is a hack, we should have vaddr in the table! 140 */ 141 if(tmpdvp->id_maddr) { 142 if((KERNBASE + dvp->id_maddr >= tmpdvp->id_maddr) && 143 (KERNBASE + dvp->id_maddr <= 144 (tmpdvp->id_maddr + tmpdvp->id_msize - 1))) { 145 conflict(dvp, tmpdvp, dvp->id_maddr, "maddr", 146 "0x%x"); 147 status = 1; |
162 } | 148 } |
163 if (isdp->id_drq != -1 164 && (drqseen & (1<<isdp->id_drq))) { 165 printf("DMA CONFLICT - drq%d\n", isdp->id_drq); 166 return (0); | 149 } 150 /* 151 * Check for IRQ conflicts. 152 */ 153 if(tmpdvp->id_irq) { 154 if (tmpdvp->id_irq == dvp->id_irq) { 155 conflict(dvp, tmpdvp, ffs(dvp->id_irq) - 1, 156 "irq", "%d"); 157 status = 1; |
167 } | 158 } |
168 /* NEED TO CHECK IOMEM CONFLICT HERE */ 169 170 /* allocate and wire in device */ 171 if(isdp->id_irq) { 172 int intrno; 173 174 intrno = ffs(isdp->id_irq)-1; 175 printf("irq %d ", intrno); 176 INTREN(isdp->id_irq); 177 if(mp)INTRMASK(*mp,isdp->id_irq); 178 setidt(NRSVIDT + intrno, isdp->id_intr, 179 SDT_SYS386IGT, SEL_KPL); 180 irqseen |= isdp->id_irq; | 159 } 160 /* 161 * Check for DRQ conflicts. 162 */ 163 if(tmpdvp->id_drq != -1) { 164 if (tmpdvp->id_drq == dvp->id_drq) { 165 conflict(dvp, tmpdvp, dvp->id_drq, 166 "drq", "%d"); 167 status = 1; |
181 } | 168 } |
182 if (isdp->id_drq != -1) { 183 printf("drq %d ", isdp->id_drq); 184 drqseen |= 1 << isdp->id_drq; 185 } | 169 } 170 } 171 return (status); 172} |
186 | 173 |
187 (*dp->attach)(isdp); | 174/* 175 * Search through all the isa_devtab_* tables looking for anything that 176 * conflicts with the current device. 177 */ 178int 179haveseen_isadev(dvp) 180 struct isa_device *dvp; 181{ 182 struct isa_device *tmpdvp; 183 int status = 0; |
188 | 184 |
189 printf("on isa\n"); 190 } 191 return (1); 192 } else return(0); | 185 for (tmpdvp = isa_devtab_tty; tmpdvp->id_driver; tmpdvp++) { 186 status |= haveseen(dvp, tmpdvp); 187 } 188 for (tmpdvp = isa_devtab_bio; tmpdvp->id_driver; tmpdvp++) { 189 status |= haveseen(dvp, tmpdvp); 190 } 191 for (tmpdvp = isa_devtab_net; tmpdvp->id_driver; tmpdvp++) { 192 status |= haveseen(dvp, tmpdvp); 193 } 194 for (tmpdvp = isa_devtab_null; tmpdvp->id_driver; tmpdvp++) { 195 status |= haveseen(dvp, tmpdvp); 196 } 197 return(status); |
193} | 198} |
194#else /* notyet */ | 199 |
195/* 196 * Configure all ISA devices 197 */ | 200/* 201 * Configure all ISA devices 202 */ |
203void |
|
198isa_configure() { 199 struct isa_device *dvp; | 204isa_configure() { 205 struct isa_device *dvp; |
200 struct isa_driver *dp; | |
201 202 enable_intr(); 203 splhigh(); 204 INTREN(IRQ_SLAVE); | 206 207 enable_intr(); 208 splhigh(); 209 INTREN(IRQ_SLAVE); |
205 for (dvp = isa_devtab_tty; config_isadev(dvp,&ttymask); dvp++); 206 for (dvp = isa_devtab_bio; config_isadev(dvp,&biomask); dvp++); 207 for (dvp = isa_devtab_net; config_isadev(dvp,&netmask); dvp++); 208 for (dvp = isa_devtab_null; config_isadev(dvp,(u_int *) NULL); dvp++); | 210 printf("Probing for devices on the ISA bus:\n"); 211 for (dvp = isa_devtab_tty; dvp->id_driver; dvp++) { 212 if (!haveseen_isadev(dvp)) 213 config_isadev(dvp,&ttymask); 214 } 215 for (dvp = isa_devtab_bio; dvp->id_driver; dvp++) { 216 if (!haveseen_isadev(dvp)) 217 config_isadev(dvp,&biomask); 218 } 219 for (dvp = isa_devtab_net; dvp->id_driver; dvp++) { 220 if (!haveseen_isadev(dvp)) 221 config_isadev(dvp,&netmask); 222 } 223 for (dvp = isa_devtab_null; dvp->id_driver; dvp++) { 224 if (!haveseen_isadev(dvp)) 225 config_isadev(dvp,(u_int *) NULL); 226 } 227/* 228 * XXX We should really add the tty device to netmask when the line is 229 * switched to SLIPDISC, and then remove it when it is switched away from 230 * SLIPDISC. No need to block out ALL ttys during a splnet when only one 231 * of them is running slip. 232 */ |
209#include "sl.h" 210#if NSL > 0 211 netmask |= ttymask; 212 ttymask |= netmask; 213#endif 214 /* biomask |= ttymask ; can some tty devices use buffers? */ 215 printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask); 216 splnone(); 217} 218 219/* 220 * Configure an ISA device. 221 */ 222config_isadev(isdp, mp) 223 struct isa_device *isdp; 224 u_int *mp; 225{ | 233#include "sl.h" 234#if NSL > 0 235 netmask |= ttymask; 236 ttymask |= netmask; 237#endif 238 /* biomask |= ttymask ; can some tty devices use buffers? */ 239 printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask); 240 splnone(); 241} 242 243/* 244 * Configure an ISA device. 245 */ 246config_isadev(isdp, mp) 247 struct isa_device *isdp; 248 u_int *mp; 249{ |
226 struct isa_driver *dp; | 250 struct isa_driver *dp = isdp->id_driver; |
227 | 251 |
228 if (dp = isdp->id_driver) { 229 if (isdp->id_maddr) { 230 extern u_int atdevbase; | 252 if (isdp->id_maddr) { 253 extern u_int atdevbase; |
231 | 254 |
232 isdp->id_maddr -= 0xa0000; /* XXX should be a define */ 233 isdp->id_maddr += atdevbase; 234 } 235 isdp->id_alive = (*dp->probe)(isdp); 236 if (isdp->id_alive) { 237 printf("%s%d", dp->name, isdp->id_unit); 238 /* 239 * Only print the I/O address range if id_alive != -1 240 * Right now this is a temporary fix just for the new 241 * NPX code so that if it finds a 486 that can use trap 242 * 16 it will not report I/O addresses. 243 * Rod Grimes 04/26/94 244 */ 245 if (isdp->id_alive != -1) { 246 printf(" at 0x%x", isdp->id_iobase); 247 if ((isdp->id_iobase + isdp->id_alive - 1) != 248 isdp->id_iobase) 249 printf("-0x%x", 250 isdp->id_iobase + 251 isdp->id_alive - 1); | 255 isdp->id_maddr -= 0xa0000; /* XXX should be a define */ 256 isdp->id_maddr += atdevbase; 257 } 258 isdp->id_alive = (*dp->probe)(isdp); 259 if (isdp->id_alive) { 260 /* 261 * Only print the I/O address range if id_alive != -1 262 * Right now this is a temporary fix just for the new 263 * NPX code so that if it finds a 486 that can use trap 264 * 16 it will not report I/O addresses. 265 * Rod Grimes 04/26/94 266 */ 267 printf("%s%d", dp->name, isdp->id_unit); 268 if (isdp->id_alive != -1) { 269 printf(" at 0x%x", isdp->id_iobase); 270 if ((isdp->id_iobase + isdp->id_alive - 1) != 271 isdp->id_iobase) { 272 printf("-0x%x", 273 isdp->id_iobase + 274 isdp->id_alive - 1); |
252 } | 275 } |
253 if(isdp->id_irq) 254 printf(" irq %d", ffs(isdp->id_irq)-1); 255 if (isdp->id_drq != -1) 256 printf(" drq %d", isdp->id_drq); 257 if (isdp->id_maddr != 0) 258 printf(" maddr 0x%x", kvtop(isdp->id_maddr)); 259 if (isdp->id_msize != 0) 260 printf(" msize %d", isdp->id_msize); 261 if (isdp->id_flags != 0) 262 printf(" flags 0x%x", isdp->id_flags); | 276 } 277 if(isdp->id_irq) 278 printf(" irq %d", ffs(isdp->id_irq) - 1); 279 if (isdp->id_drq != -1) 280 printf(" drq %d", isdp->id_drq); 281 if (isdp->id_maddr) 282 printf(" maddr 0x%x", kvtop(isdp->id_maddr)); 283 if (isdp->id_msize) 284 printf(" msize %d", isdp->id_msize); 285 if (isdp->id_flags) 286 printf(" flags 0x%x", isdp->id_flags); 287 if (isdp->id_iobase < 0x100) 288 printf(" on motherboard\n"); 289 else |
263 printf(" on isa\n"); 264 | 290 printf(" on isa\n"); 291 |
265 (*dp->attach)(isdp); | 292 (*dp->attach)(isdp); |
266 | 293 |
267 if(isdp->id_irq) { 268 int intrno; | 294 if(isdp->id_irq) { 295 int intrno; |
269 | 296 |
270 intrno = ffs(isdp->id_irq)-1; 271 setidt(ICU_OFFSET+intrno, isdp->id_intr, 272 SDT_SYS386IGT, SEL_KPL); 273 if(mp) 274 INTRMASK(*mp,isdp->id_irq); 275 INTREN(isdp->id_irq); | 297 intrno = ffs(isdp->id_irq)-1; 298 setidt(ICU_OFFSET+intrno, isdp->id_intr, 299 SDT_SYS386IGT, SEL_KPL); 300 if(mp) { 301 INTRMASK(*mp,isdp->id_irq); |
276 } | 302 } |
303 INTREN(isdp->id_irq); |
|
277 } | 304 } |
278 return (1); 279 } else return(0); | 305 } else { 306 printf("%s%d not found", dp->name, isdp->id_unit); 307 if (isdp->id_iobase) { 308 printf(" at 0x%x", isdp->id_iobase); 309 } 310 printf("\n"); 311 } |
280} | 312} |
281#endif /* (!) notyet */ | |
282 283#define IDTVEC(name) __CONCAT(X,name) 284/* default interrupt vector table entries */ 285extern IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3), 286 IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7), 287 IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11), 288 IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15); 289 --- 471 unchanged lines hidden --- | 313 314#define IDTVEC(name) __CONCAT(X,name) 315/* default interrupt vector table entries */ 316extern IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3), 317 IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7), 318 IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11), 319 IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15); 320 --- 471 unchanged lines hidden --- |