|
|
1.1 root 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
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
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:
39: /*
40: * code to manage AT bus
41: */
42:
43: #include "param.h"
44: #include "systm.h"
45: #include "conf.h"
46: #include "file.h"
47: #include "buf.h"
48: #include "uio.h"
49: #include "syslog.h"
50: #include "machine/segments.h"
51: #include "i386/isa/isa_device.h"
52: #include "i386/isa/icu.h"
53:
54: /*
55: * Configure all ISA devices
56: */
57: isa_configure() {
58: struct isa_device *dvp;
59: struct isa_driver *dp;
60:
61: splhigh();
62: INTREN(IRQ_SLAVE);
63: for (dvp = isa_devtab_bio; config_isadev(dvp,&biomask); dvp++);
64: for (dvp = isa_devtab_tty; config_isadev(dvp,&ttymask); dvp++);
65: for (dvp = isa_devtab_net; config_isadev(dvp,&netmask); dvp++);
66: for (dvp = isa_devtab_null; config_isadev(dvp,0); dvp++);
67: #include "sl.h"
68: #if NSL > 0
69: netmask |= ttymask;
70: ttymask |= netmask;
71: #endif
72: /* biomask |= ttymask ; can some tty devices use buffers? */
73: printf("biomask %x ttymask %x netmask %x\n", biomask, ttymask, netmask);
74: splnone();
75: }
76:
77: /*
78: * Configure an ISA device.
79: */
80: config_isadev(isdp, mp)
81: struct isa_device *isdp;
82: int *mp;
83: {
84: struct isa_driver *dp;
85:
86: if (dp = isdp->id_driver) {
87: if (isdp->id_maddr) {
88: extern int atdevbase;
89:
90: isdp->id_maddr -= 0xa0000;
91: isdp->id_maddr += atdevbase;
92: }
93: isdp->id_alive = (*dp->probe)(isdp);
94: if (isdp->id_alive) {
95: printf("%s%d", dp->name, isdp->id_unit);
96: (*dp->attach)(isdp);
97: printf(" at 0x%x ", isdp->id_iobase);
98: if(isdp->id_irq) {
99: int intrno;
100:
101: intrno = ffs(isdp->id_irq)-1;
102: printf("irq %d ", intrno);
103: INTREN(isdp->id_irq);
104: if(mp)INTRMASK(*mp,isdp->id_irq);
105: setidt(ICU_OFFSET+intrno, isdp->id_intr,
106: SDT_SYS386IGT, SEL_KPL);
107: }
108: if (isdp->id_drq != -1) printf("drq %d ", isdp->id_drq);
109: printf("on isa\n");
110: }
111: return (1);
112: } else return(0);
113: }
114:
115: #define IDTVEC(name) __CONCAT(X,name)
116: /* default interrupt vector table */
117: extern IDTVEC(intr0), IDTVEC(intr1), IDTVEC(intr2), IDTVEC(intr3),
118: IDTVEC(intr4), IDTVEC(intr5), IDTVEC(intr6), IDTVEC(intr7),
119: IDTVEC(intr8), IDTVEC(intr9), IDTVEC(intr10), IDTVEC(intr11),
120: IDTVEC(intr12), IDTVEC(intr13), IDTVEC(intr14), IDTVEC(intr15);
121:
122: /*
123: * Fill in default interrupt table (in case of spuruious interrupt
124: * during configuration of kernel, setup interrupt control unit
125: */
126: isa_defaultirq() {
127:
128: /* first icu */
129: setidt(32, &IDTVEC(intr0), SDT_SYS386IGT, SEL_KPL);
130: setidt(33, &IDTVEC(intr1), SDT_SYS386IGT, SEL_KPL);
131: setidt(34, &IDTVEC(intr2), SDT_SYS386IGT, SEL_KPL);
132: setidt(35, &IDTVEC(intr3), SDT_SYS386IGT, SEL_KPL);
133: setidt(36, &IDTVEC(intr4), SDT_SYS386IGT, SEL_KPL);
134: setidt(37, &IDTVEC(intr5), SDT_SYS386IGT, SEL_KPL);
135: setidt(38, &IDTVEC(intr6), SDT_SYS386IGT, SEL_KPL);
136: setidt(39, &IDTVEC(intr7), SDT_SYS386IGT, SEL_KPL);
137:
138: /* second icu */
139: setidt(40, &IDTVEC(intr8), SDT_SYS386IGT, SEL_KPL);
140: setidt(41, &IDTVEC(intr9), SDT_SYS386IGT, SEL_KPL);
141: setidt(42, &IDTVEC(intr10), SDT_SYS386IGT, SEL_KPL);
142: setidt(43, &IDTVEC(intr11), SDT_SYS386IGT, SEL_KPL);
143: setidt(44, &IDTVEC(intr12), SDT_SYS386IGT, SEL_KPL);
144: setidt(45, &IDTVEC(intr13), SDT_SYS386IGT, SEL_KPL);
145: setidt(46, &IDTVEC(intr14), SDT_SYS386IGT, SEL_KPL);
146: setidt(47, &IDTVEC(intr15), SDT_SYS386IGT, SEL_KPL);
147:
148: /* initialize 8259's */
149: outb(0xf1,0);
150: outb(0x20,0x11);
151: outb(0x21,32);
152: outb(0x21,4);
153: outb(0x21,1);
154: outb(0x21,0xff);
155:
156: outb(0xa0,0x11);
157: outb(0xa1,40);
158: outb(0xa1,2);
159: outb(0xa1,1);
160: outb(0xa1,0xff);
161: }
162:
163: /* stuff needed for virtual to physical calculations */
164:
165: struct buf *dma_bounce[8];
166: #define MAXDMASZ 512
167:
168: /* XXX temporary crud */
169: kernel_space(x)
170: unsigned long x;
171: {
172: if (x >= KERNBASE) return 1;
173: else return 0;
174: }
175:
176:
177: /****************************************************************************/
178: /* at_dma */
179: /* set up DMA read/write operation and virtual address addr for nbytes */
180: /****************************************************************************/
181: at_dma(read,addr,nbytes, chan)
182: int read;
183: unsigned long addr;
184: int nbytes;
185: {
186: unsigned long phys;
187: int s,raw;
188: caddr_t bounce;
189:
190: if (kernel_space(addr)) raw = 0;
191: else raw = 1;
192:
193: if(raw) {
194: if (dma_bounce[chan] == 0)
195: dma_bounce[chan] = geteblk(MAXDMASZ);
196: bounce = dma_bounce[chan]->b_un.b_addr;
197: }
198:
199: /* copy bounce buffer on write */
200: if (raw && !read) bcopy(addr,bounce,nbytes);
201:
202: /* Set read/write bytes */
203: if (read) {
204: outb(0xC,0x46); outb(0xB,0x46);
205: } else {
206: outb(0xC,0x4A); outb(0xB,0x4A);
207: }
208: /* Send start address */
209: if (raw) phys = (unsigned long) bounce;
210: else phys = addr;
211: /* translate to physical */
212: phys = pmap_extract(pmap_kernel(), (vm_offset_t)phys);
213: outb(0x4,phys & 0xFF);
214: outb(0x4,(phys>>8) & 0xFF);
215: outb(0x81,(phys>>16) & 0xFF);
216: /* Send count */
217: nbytes--;
218: outb(0x5,nbytes & 0xFF);
219: outb(0x5,(nbytes>>8) & 0xFF);
220: /* set channel 2 */
221: outb(0x0A,chan);
222: }
223:
224: /*
225: * Handle a NMI, possibly a machine check.
226: * return true to panic system, false to ignore.
227: */
228: isa_nmi(cd) {
229:
230: log(LOG_CRIT, "\nNMI port 61 %x, port 70 %x\n", inb(0x61), inb(0x70));
231: return(0);
232: }
233:
234: /*
235: * Caught a stray interrupt, notify
236: */
237: isa_strayintr(d) {
238:
239: /* for some reason, we get bursts of intr #7, even if not enabled! */
240: log(LOG_ERR,"ISA strayintr %d", ffs(d)-1);
241: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.