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