|
|
1.1 root 1: /*
2: * coh.386/syscoh.c
3: *
4: * Functions for the COHERENT-specific system call.
5: *
6: * Revised: Thu Jul 15 14:22:19 1993 CDT
7: */
8:
9: /*
10: * ----------------------------------------------------------------------
11: * Includes.
12: */
13: #include <sys/coherent.h>
14: #include <sys/con.h>
15: #include <sys/errno.h>
16:
17: /*
18: * ----------------------------------------------------------------------
19: * Definitions.
20: * Constants.
21: * Macros with argument lists.
22: * Typedefs.
23: * Enums.
24: */
25:
26: /*
27: * ----------------------------------------------------------------------
28: * Functions.
29: * Import Functions.
30: * Export Functions.
31: * Local Functions.
32: */
33: int ucohcall();
34:
35: static int devload();
36:
37: /*
38: * ----------------------------------------------------------------------
39: * Global Data.
40: * Import Variables.
41: * Export Variables.
42: * Local Variables.
43: */
44:
45: /*
46: * ----------------------------------------------------------------------
47: * Code.
48: */
49:
50: /*
51: * Only allow this if running as superuser.
52: *
53: * a1 call type
54: * ---------- ----------
55: * COH_PRINTF kernel printf
56: * COH_DEVLOAD call load() routine for device with major number a2
57: * COH_SETBP a2=bp#,a3=addr,a4=type,a5=len; set kernel breakpoint
58: * COH_CLRBP a2=bp#; clear kernel breakpoint
59: * COH_REBOOT reboot
60: * COH_GETINT11 returns hardware equipment word saved at boot time
61: */
62: ucohcall(a1,a2,a3,a4,a5)
63: {
64: int ret = 0;
65:
66: if (!super()) {
67: SET_U_ERROR(EPERM, "cohcall, must be root");
68: goto ucc_done;
69: }
70:
71: switch(a1) {
72: case COH_PRINTF:
73: printf(a2);
74: break;
75: case COH_DEVLOAD:
76: ret = devload(a2);
77: break;
78: case COH_SETBP:
79: ret = setbp(a2,a3,a4,a5);
80: break;
81: case COH_CLRBP:
82: ret = clrbp(a2);
83: break;
84: case COH_REBOOT:
85: ret = boot();
86: break;
87: case COH_VIO:
88: ret = vio(a2,a3,a4,a5);
89: break;
90: case COH_SHM:
91: ret = coh_shm(a2,a3,a4,a5);
92: break;
93: case COH_WTEXT:
94: ret = cohWtext(a2,a3,a4);
95: break;
96: case COH_GETINT11:
97: ret = (int11() & 0x0000FFFF);
98: break;
99: default:
100: SET_U_ERROR(EINVAL, "bad COH function");
101: }
102: ucc_done:
103: return ret;
104: }
105:
106: /*
107: * Allow user to write to his own text segment.
108: */
109: int
110: cohWtext(dest,src,numBytes)
111: {
112: if ((accdata(src, numBytes)
113: || accstack(src, numBytes)
114: || acctext(src, numBytes)
115: || accShm(src, numBytes))
116: && acctext(dest, numBytes)) {
117: memcpy(dest, src, numBytes);
118: return 0;
119: } else
120: u.u_error = EINVAL;
121: }
122:
123: /*
124: * Test of shared memory support.
125: */
126: int
127: coh_shm(x1, x2, x3, x4)
128: int x1, x2, x3, x4;
129: {
130: int index, base;
131:
132: switch (x1) {
133: case 0:
134: return shmAlloc(x2);
135: break;
136: case 1:
137: return shmFree(x2);
138: break;
139: case 2:
140: /* Since we are out of args, will use interface
141: * cohcall(COH_SHM, 2, numBytes, base+index, segp)
142: * to call shmAttach, using low bits of base to
143: * carry the index into p_shmsr. */
144:
145: base = x3 & 0xFFFFF000;
146: index = x3 & 0x00000FFF;
147: if (index >= 0 && index < NSHMSEG) {
148: return shmAttach(index, x2, base, x4);
149: } else
150: SET_U_ERROR(EINVAL, "bad COH shm index");
151: break;
152: case 3:
153: return shmDetach(x2);
154: break;
155: default:
156: SET_U_ERROR(EINVAL, "bad COH shm function");
157: break;
158: }
159: return -1;
160: }
161:
162: /*
163: * Test of video io map support.
164: */
165: int
166: vio(x1, x2, x3, x4)
167: int x1, x2, x3;
168: {
169: switch (x1) {
170: case 0:
171: return iomapOr(x2, x3);
172: break;
173: case 1:
174: return iomapAnd(x2, x3);
175: break;
176: case 2:
177: return kiopriv(x2, x3);
178: break;
179: case 3:
180: return mapPhysUser(x2, x3, x4);
181: break;
182: default:
183: SET_U_ERROR(EINVAL, "bad COH vio function");
184: break;
185: }
186: return -1;
187: }
188:
189: /*
190: * Initialize a device.
191: */
192: int
193: devload(maj_num)
194: int maj_num;
195: {
196: int ret = -1;
197: int mask = 1<<maj_num;
198:
199: if (dev_loaded & mask) {
200: SET_U_ERROR(EIO, "already loaded");
201: goto dldone;
202: }
203:
204: if (drvl[maj_num].d_conp == 0) {
205: SET_U_ERROR(EIO, "no driver");
206: goto dldone;
207: }
208:
209: if (drvl[maj_num].d_conp->c_load) {
210: (*drvl[maj_num].d_conp->c_load)();
211: dev_loaded |= mask;
212: ret = 0;
213: }
214: dldone:
215: return ret;
216: }
217:
218: unsigned int DR0,DR1,DR2,DR3,DR7;
219: /*
220: * Set a kernel breakpoint.
221: */
222: int
223: setbp(bp_num, addr, type, len)
224: unsigned int bp_num, addr, type, len;
225: {
226: /* Range check arguments.
227: * Update RAM images of writeable debug registers.
228: * Call routine (while in RING 1) which will cause GP fault.
229: * GP Fault handler (in RING 0) will copy RAM images to DR's.
230: */
231: if (bp_num >= 4 || type >= 4 || len >= 4 || type == 2 || len == 2) {
232: SET_U_ERROR(EINVAL, "bad bp setting");
233: return -1;
234: }
235: switch(bp_num) {
236: case 0:
237: DR0 = addr;
238: write_dr0(DR0);
239: DR7 |= ((type<<16)|(len<<18)|0x303);
240: break;
241: case 1:
242: DR1 = addr;
243: write_dr1(DR1);
244: DR7 |= ((type<<20)|(len<<22)|0x30C);
245: break;
246: case 2:
247: DR2 = addr;
248: write_dr2(DR2);
249: DR7 |= ((type<<24)|(len<<26)|0x330);
250: break;
251: case 3:
252: DR3 = addr;
253: write_dr3(DR3);
254: DR7 |= ((type<<28)|(len<<30)|0x3C0);
255: break;
256: }
257: write_dr7(DR7);
258: return 0;
259: }
260:
261: /*
262: * Clear a kernel breakpoint.
263: */
264: int
265: clrbp(bp_num)
266: unsigned int bp_num;
267: {
268: /* Range check arguments.
269: * Update RAM images of writeable debug registers.
270: * Call routine (while in RING 1) which will cause GP fault.
271: * GP Fault handler (in RING 0) will copy RAM images to DR's.
272: */
273: if (bp_num >= 4) {
274: SET_U_ERROR(EINVAL, "bad bp # to clear");
275: return -1;
276: }
277: switch(bp_num) {
278: case 0:
279: DR7 &= ~0x3;
280: break;
281: case 1:
282: DR7 &= ~0xC;
283: break;
284: case 2:
285: DR7 &= ~0x30;
286: break;
287: case 3:
288: DR7 &= ~0xC0;
289: break;
290: }
291: if ((DR7 & 0xFF) == 0)
292: DR7 &= ~0x300;
293: write_dr7(DR7);
294: return 0;
295: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.