|
|
1.1 root 1: /* (lgl-
2: * md.c
3: *
4: * The information contained herein is a trade secret of Mark Williams
5: * Company, and is confidential information. It is provided under a
6: * license agreement, and may be copied or disclosed only under the
7: * terms of that agreement. Any reproduction or disclosure of this
8: * material without the express written authorization of Mark Williams
9: * Company or persuant to the license agreement is unlawful.
10: *
11: * COHERENT Version 2.3.37
12: * Copyright (c) 1982, 1983, 1984.
13: * An unpublished work by Mark Williams Company, Chicago.
14: * All rights reserved.
15: -lgl) */
16: /*
17: * Coherent 386
18: * IBM PC
19: * Machine dependent stuff.
20: *
21: */
22:
23: #include <kernel/reg.h>
24:
25: #include <sys/coherent.h>
26: #include <sys/clist.h>
27: #include <sys/errno.h>
28: #include <sys/inode.h>
29: #include <sys/proc.h>
30: #include <sys/seg.h>
31: #include <signal.h>
32: #include <sys/uproc.h>
33: #include <sys/buf.h>
34:
35: /*
36: * Given an irq level (1..15) and an irq function pointer, try to hook the
37: * function into the desired interrupt. Do not allow resetting of the
38: * clock interrupt, irq 0.
39: *
40: * On success, return 1.
41: * If the level number is invalid or the interrupt is already in use,
42: * do nothing but return 0.
43: *
44: * Make an entry in the "vecs" table, for use by the assist.
45: * Make sure that the channel on the 8259 is armed.
46: * Interrupt vectors 2 and 9 are mapped into channel 9.
47: */
48: int
49: setivec(level, fun)
50: unsigned int level;
51: int (*fun)();
52: {
53: register int picm;
54: extern int (*vecs[])();
55: extern int vret();
56:
57: if (level >= NUM_IRQ_LEVELS)
58: return 0;
59: if (level == 2)
60: level = 9;
61: if (level==0 || vecs[level]!=&vret)
62: return 0;
63:
64: vecs[level] = fun;
65:
66: /*
67: * NIGEL: The original code here (and matching code below in clrivec ())
68: * takes pains to correctly manipulate the slave PIC chain mask bit in
69: * the master PIC. This is redundant, and unnecessarily complex, so I
70: * have removed it to aid the process of adding a more rational system
71: * of interrupt handling for the DDI/DKI.
72: *
73: * Now the slave PIC chain mask bit is enabled (via a modification to
74: * code in "i386/as.s") at startup, and it should never be disabled.
75: *
76: * The rational interrupt scheme requires that the implementations of
77: * the DDI/DKI functions know the base-level mask value so that they
78: * can correctly (and quickly) manipulate masks to raise and lower
79: * priority levels even when deeply nested inside interrupts (see the
80: * implementations of those functions for a deeper discussion of the
81: * issues involved). This function cooperates with the new system via
82: * the DDI_BASE_..._MASK () macro, which either manipulates the mask
83: * register as the old code did or passes responsibility over to the
84: * new DDI/DKI scheme if it has been enabled.
85: *
86: * The new macro-calls are defined in <kernel/reg.h>
87: */
88:
89: if ( level >= LOWEST_SLAVE_IRQ ) {
90: picm = inb(SPICM);
91: picm &= ~(0x01 << (level-LOWEST_SLAVE_IRQ));
92: DDI_BASE_SLAVE_MASK (picm);
93: } else {
94: picm = inb(PICM);
95: picm &= ~(0x01 << level);
96: DDI_BASE_MASTER_MASK (picm);
97: }
98: return 1;
99: }
100:
101: /*
102: * Clear an interrupt vector.
103: */
104: clrivec(level)
105: register int level;
106: {
107: register int picm;
108: extern int (*vecs[])();
109: extern int vret();
110:
111: if ((level &= 0x0F) == 2)
112: level = 9;
113: if (level == 0)
114: printf("clrivec: level=%d", level);
115: vecs[level] = &vret;
116:
117: /*
118: * NIGEL: This code has been modified to match the changes made to the
119: * setivec () routine above. See the comment there for details.
120: */
121:
122: if (level >= LOWEST_SLAVE_IRQ) {
123: picm = inb(SPICM);
124: picm |= (0x01 << (level-LOWEST_SLAVE_IRQ));
125: DDI_BASE_SLAVE_MASK (picm);
126: } else {
127: picm = inb(PICM);
128: picm |= (0x01 << level);
129: DDI_BASE_SLAVE_MASK (picm);
130: }
131: }
132:
133:
134: /*
135: * Convert an array of filesystem 3 byte
136: * numbers to longs. This routine, unlike the old one,
137: * is independent of the order of bytes in a long.
138: * Bytes have 8 bits, though.
139: */
140: l3tol(lp, cp, nl)
141: register long *lp;
142: register unsigned char *cp;
143: register unsigned nl;
144: {
145: register long l;
146:
147: if (nl != 0) {
148: do {
149: l = (long)cp[0] << 16;
150: l |= (long)cp[1];
151: l |= (long)cp[2] << 8;
152: cp += 3;
153: *lp++ = l;
154: } while (--nl);
155: }
156: }
157: /*
158: * Convert an array of longs into an array
159: * of filesystem 3 byte numbers. This routine, unlike
160: * the old one, is independent of the order of bytes in
161: * a long. Bytes have 8 bits.
162: */
163: ltol3(cp, lp, nl)
164: register char *cp;
165: register long *lp;
166: register unsigned nl;
167: {
168: register long l;
169:
170: if (nl != 0) {
171: do {
172: l = *lp++;
173: cp[0] = l >> 16;
174: cp[1] = l;
175: cp[2] = l >> 8;
176: cp += 3;
177: } while (--nl);
178: }
179: }
180:
181:
182: /*
183: * Given a port number and a bit value, write the bit value into
184: * the tss iomap.
185: *
186: * Bit value of 0 enables user I/O for that port.
187: * Bit value of 1 disables user I/O for that port.
188: *
189: * Return 1 if port number is valid for the bitmap, else 0.
190: */
191: int
192: kiopriv(port, bit)
193: unsigned int port, bit;
194: {
195: extern int tssIoMap;
196: extern int tssIoEnd;
197: int ret = 0;
198: int * ip;
199: unsigned int offset = port >> 5;
200: int shift = port & 0x1f;
201: int mask = 1 << shift;
202: int val = (bit & 1) << shift;
203:
204: if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) {
205: ip = (& tssIoMap) + offset;
206: *ip &= ~mask; /* clear old bit value */
207: *ip |= val; /* or in desired new bit value */
208: ret = 1;
209: }
210: return ret;
211: }
212:
213: /*
214: * Given a 32 bit mask and a word offset into the tss io map,
215: * bitwise or the mask into the map.
216: * Offset of 0 covers ports 0..31, offset of 1 covers ports 32..63, etc.
217: * Current valid range for offset is 0..63, covering ports 0..7ff.
218: *
219: * Return the new map word.
220: */
221: int
222: iomapOr(val, offset)
223: int val, offset;
224: {
225: extern int tssIoMap;
226: extern int tssIoEnd;
227: int ret;
228: int * ip;
229:
230: if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) {
231: ip = (& tssIoMap) + offset;
232: ret = *ip |= val;
233: }
234: return ret;
235: }
236:
237: /*
238: * Given a 32 bit mask and a word offset into the tss io map,
239: * bitwise and the mask into the map.
240: * Offset of 0 covers ports 0..31, offset of 1 covers ports 32..63, etc.
241: * Current valid range for offset is 0..63, covering ports 0..7ff.
242: *
243: * Return the new map word.
244: */
245: int
246: iomapAnd(val, offset)
247: int val, offset;
248: {
249: extern int tssIoMap;
250: extern int tssIoEnd;
251: int ret;
252: int * ip;
253:
254: if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) {
255: ip = (& tssIoMap) + offset;
256: ret = *ip &= val;
257: }
258: return ret;
259: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.