xref: /original-bsd/sys/i386/isa/isa.c (revision 1e29b3fc)
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  * %sccs.include.redist.c%
9  *
10  *	@(#)isa.c	7.3 (Berkeley) 05/11/92
11  */
12 
13 /*
14  * code to manage AT bus
15  */
16 
17 #include "param.h"
18 #include "systm.h"
19 #include "conf.h"
20 #include "file.h"
21 #include "buf.h"
22 #include "uio.h"
23 #include "syslog.h"
24 #include "machine/segments.h"
25 #include "i386/isa/isa_device.h"
26 #include "i386/isa/icu.h"
27 #include "vm/vm.h"
28 
29 /*
30  * Configure all ISA devices
31  */
32 isa_configure() {
33 	struct isa_device *dvp;
34 	struct isa_driver *dp;
35 
36 	splhigh();
37 	INTREN(IRQ_SLAVE);
38 	for (dvp = isa_devtab_bio; config_isadev(dvp,&biomask); dvp++);
39 	for (dvp = isa_devtab_tty; config_isadev(dvp,&ttymask); dvp++);
40 	for (dvp = isa_devtab_net; config_isadev(dvp,&netmask); dvp++);
41 	for (dvp = isa_devtab_null; config_isadev(dvp,0); dvp++);
42 #include "sl.h"
43 #if NSL > 0
44 	netmask |= ttymask;
45 	ttymask |= netmask;
46 #endif
47 	/* biomask |= ttymask ;  can some tty devices use buffers? */
48 	printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask);
49 	splnone();
50 }
51 
52 /*
53  * Configure an ISA device.
54  */
55 config_isadev(isdp, mp)
56 	struct isa_device *isdp;
57 	int *mp;
58 {
59 	struct isa_driver *dp;
60 
61 	if (dp = isdp->id_driver) {
62 		if (isdp->id_maddr) {
63 			extern int atdevbase;
64 
65 			isdp->id_maddr -= 0xa0000;
66 			isdp->id_maddr += atdevbase;
67 		}
68 		isdp->id_alive = (*dp->probe)(isdp);
69 		if (isdp->id_alive) {
70 			printf("%s%d", dp->name, isdp->id_unit);
71 			(*dp->attach)(isdp);
72 			printf(" at 0x%x ", isdp->id_iobase);
73 			if(isdp->id_irq) {
74 				int intrno;
75 
76 				intrno = ffs(isdp->id_irq)-1;
77 				printf("irq %d ", intrno);
78 				INTREN(isdp->id_irq);
79 				if(mp)INTRMASK(*mp,isdp->id_irq);
80 				setidt(ICU_OFFSET+intrno, isdp->id_intr,
81 					 SDT_SYS386IGT, SEL_KPL);
82 			}
83 			if (isdp->id_drq != -1) printf("drq %d ", isdp->id_drq);
84 			printf("on isa\n");
85 		}
86 		return (1);
87 	} else	return(0);
88 }
89 
90 #define	IDTVEC(name)	__CONCAT(X,name)
91 /* default interrupt vector table */
92 extern	IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3),
93 	IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7),
94 	IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11),
95 	IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15);
96 
97 /*
98  * Fill in default interrupt table (in case of spuruious interrupt
99  * during configuration of kernel, setup interrupt control unit
100  */
101 isa_defaultirq() {
102 
103 /* first icu */
104 	setidt(32, &IDTVEC(intr0),  SDT_SYS386IGT, SEL_KPL);
105 	setidt(33, &IDTVEC(intr1),  SDT_SYS386IGT, SEL_KPL);
106 	setidt(34, &IDTVEC(intr2),  SDT_SYS386IGT, SEL_KPL);
107 	setidt(35, &IDTVEC(intr3),  SDT_SYS386IGT, SEL_KPL);
108 	setidt(36, &IDTVEC(intr4),  SDT_SYS386IGT, SEL_KPL);
109 	setidt(37, &IDTVEC(intr5),  SDT_SYS386IGT, SEL_KPL);
110 	setidt(38, &IDTVEC(intr6),  SDT_SYS386IGT, SEL_KPL);
111 	setidt(39, &IDTVEC(intr7),  SDT_SYS386IGT, SEL_KPL);
112 
113 /* second icu */
114 	setidt(40, &IDTVEC(intr8),  SDT_SYS386IGT, SEL_KPL);
115 	setidt(41, &IDTVEC(intr9),  SDT_SYS386IGT, SEL_KPL);
116 	setidt(42, &IDTVEC(intr10),  SDT_SYS386IGT, SEL_KPL);
117 	setidt(43, &IDTVEC(intr11),  SDT_SYS386IGT, SEL_KPL);
118 	setidt(44, &IDTVEC(intr12),  SDT_SYS386IGT, SEL_KPL);
119 	setidt(45, &IDTVEC(intr13),  SDT_SYS386IGT, SEL_KPL);
120 	setidt(46, &IDTVEC(intr14),  SDT_SYS386IGT, SEL_KPL);
121 	setidt(47, &IDTVEC(intr15),  SDT_SYS386IGT, SEL_KPL);
122 
123 	/* initialize 8259's */
124 	outb(0xf1,0);
125 	outb(0x20,0x11);
126 	outb(0x21,32);
127 	outb(0x21,4);
128 	outb(0x21,1);
129 	outb(0x21,0xff);
130 
131 	outb(0xa0,0x11);
132 	outb(0xa1,40);
133 	outb(0xa1,2);
134 	outb(0xa1,1);
135 	outb(0xa1,0xff);
136 }
137 
138 /* stuff needed for virtual to physical calculations */
139 
140 struct buf *dma_bounce[8];
141 #define MAXDMASZ 512
142 
143 /* XXX temporary crud */
144 kernel_space(x)
145 unsigned long x;
146 {
147 	if (x >= KERNBASE) return 1;
148 	else return 0;
149 }
150 
151 
152 /****************************************************************************/
153 /*                                 at_dma                                   */
154 /* set up DMA read/write operation and virtual address addr for nbytes      */
155 /****************************************************************************/
156 at_dma(read,addr,nbytes, chan)
157 int read;
158 unsigned long addr;
159 int nbytes;
160 {
161 	unsigned long phys;
162 	int s,raw;
163 	caddr_t bounce;
164 
165 	if (kernel_space(addr)) raw = 0;
166 	else raw = 1;
167 
168 	if(raw) {
169 		if (dma_bounce[chan] == 0)
170 			dma_bounce[chan] = geteblk(MAXDMASZ);
171 		bounce = dma_bounce[chan]->b_un.b_addr;
172 	}
173 
174 	/* copy bounce buffer on write */
175 	if (raw && !read) bcopy(addr,bounce,nbytes);
176 
177 	/* Set read/write bytes */
178 	if (read) {
179 		outb(0xC,0x46); outb(0xB,0x46);
180 	} else {
181 		outb(0xC,0x4A); outb(0xB,0x4A);
182 	}
183 	/* Send start address */
184 	if (raw) phys = (unsigned long) bounce;
185 	else phys = addr;
186 	/* translate to physical */
187 	phys = pmap_extract(kernel_pmap, (vm_offset_t)phys);
188 	outb(0x4,phys & 0xFF);
189 	outb(0x4,(phys>>8) & 0xFF);
190 	outb(0x81,(phys>>16) & 0xFF);
191 	/* Send count */
192 	nbytes--;
193 	outb(0x5,nbytes & 0xFF);
194 	outb(0x5,(nbytes>>8) & 0xFF);
195 	/* set channel 2 */
196 	outb(0x0A,chan);
197 }
198 
199 /*
200  * Handle a NMI, possibly a machine check.
201  * return true to panic system, false to ignore.
202  */
203 isa_nmi(cd) {
204 
205 	log(LOG_CRIT, "\nNMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70));
206 	return(0);
207 }
208 
209 /*
210  * Caught a stray interrupt, notify
211  */
212 isa_strayintr(d) {
213 
214 	/* for some reason, we get bursts of intr #7, even if not enabled! */
215 	log(LOG_ERR,"ISA strayintr %d", ffs(d)-1);
216 }
217