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