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