Deleted Added
full compact
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 ---