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