1: /*
2: * Copyright (c) 1986 Regents of the University of California.
3: * All rights reserved. The Berkeley software License Agreement
4: * specifies the terms and conditions for redistribution.
5: *
6: * @(#)kern_pdp.c 1.4 (2.11BSD) 1998/5/12
7: */
8:
9: #include "param.h"
10: #include "../machine/autoconfig.h"
11: #include "../machine/seg.h"
12:
13: #include "user.h"
14: #include "ioctl.h"
15: #include "proc.h"
16: #include "kernel.h"
17: #include "systm.h"
18: #include "cpu.h"
19: #include "tty.h"
20:
21: /*
22: * used to pass result from int service to probe();
23: * do not declare static!!
24: */
25: int conf_int = CONF_MAGIC;
26:
27: /*
28: * ucall allows user level code to call various kernel functions.
29: * Autoconfig uses it to call the probe and attach routines of the
30: * various device drivers.
31: */
32: ucall()
33: {
34: register struct a {
35: int priority;
36: int (*routine)();
37: int arg1;
38: int arg2;
39: } *uap = (struct a *)u.u_ap;
40: int s;
41:
42: if (!suser())
43: return;
44: switch(uap->priority) {
45: case 0:
46: s = spl0();
47: break;
48: case 1:
49: s = spl1();
50: break;
51: case 2:
52: case 3:
53: case 4:
54: s = spl4();
55: break;
56: case 5:
57: s = spl5();
58: break;
59: case 6:
60: s = spl6();
61: break;
62: case 7:
63: default:
64: s = spl7();
65: break;
66: }
67: u.u_r.r_val1 = (*uap->routine)(uap->arg1,uap->arg2);
68: splx(s);
69: }
70:
71: /*
72: * Lock user into core as much as possible. Swapping may still
73: * occur if core grows.
74: */
75: lock()
76: {
77: struct a {
78: int flag;
79: };
80:
81: if (!suser())
82: return;
83: if (((struct a *)u.u_ap)->flag)
84: u.u_procp->p_flag |= SULOCK;
85: else
86: u.u_procp->p_flag &= ~SULOCK;
87: }
88:
89: /*
90: * fetch the word at iaddr from user I-space. This system call is
91: * required on machines with separate I/D space because the mfpi
92: * instruction reads from D-space if the current and previous modes
93: * in the program status word are both user.
94: */
95: fetchi()
96: {
97: struct a {
98: caddr_t iaddr;
99: };
100: #ifdef NONSEPARATE
101: u.u_error = EINVAL;
102: #else !NONSEPARATE
103: u.u_error = copyiin((struct a *)u.u_ap, u.u_r.r_val1, NBPW);
104: #endif NONSEPARATE
105: }
106:
107: /*
108: * return the floating point error registers as they were following
109: * the last floating point exception generated by the calling process.
110: * Required because the error registers may have been changed so the
111: * system saves them at the time of the exception.
112: */
113: fperr()
114: {
115: u.u_r.r_val1 = (int)u.u_fperr.f_fec;
116: u.u_r.r_val2 = (int)u.u_fperr.f_fea;
117: }
118:
119: /*
120: * set up the process to have no stack segment. The process is
121: * responsible for the management of its own stack, and can thus
122: * use the full 64K byte address space.
123: */
124: nostk()
125: {
126: if (estabur(u.u_tsize, u.u_dsize, 0, u.u_sep, RO))
127: return;
128: expand(0,S_STACK);
129: u.u_ssize = 0;
130: }
131:
132: /*
133: * set up a physical address
134: * into users virtual address space.
135: */
136: phys()
137: {
138: register struct a {
139: int segno;
140: int size;
141: int phys;
142: } *uap = (struct a *)u.u_ap;
143: register int i, s;
144: int d;
145:
146: if (!suser())
147: return;
148:
149: i = uap->segno;
150: if (i < 0 || i >= 8)
151: goto bad;
152: s = uap->size;
153: if (s < 0 || s > 128)
154: goto bad;
155: #ifdef NONSEPARATE
156: d = u.u_uisd[i];
157: #else
158: d = u.u_uisd[i + 8];
159: #endif
160: if (d != 0 && (d & ABS) == 0)
161: goto bad;
162: #ifdef NONSEPARATE
163: u.u_uisd[i] = 0;
164: u.u_uisa[i] = 0;
165: #else
166: u.u_uisd[i + 8] = 0;
167: u.u_uisa[i + 8] = 0;
168: if (!u.u_sep) {
169: u.u_uisd[i] = 0;
170: u.u_uisa[i] = 0;
171: }
172: #endif
173: if (s) {
174: #ifdef NONSEPARATE
175: u.u_uisd[i] = ((s - 1) << 8) | RW | ABS;
176: u.u_uisa[i] = uap->phys;
177: #else
178: u.u_uisd[i + 8] = ((s - 1) << 8) | RW | ABS;
179: u.u_uisa[i + 8] = uap->phys;
180: if (!u.u_sep) {
181: u.u_uisa[i] = u.u_uisa[i + 8];
182: u.u_uisd[i] = u.u_uisd[i + 8];
183: }
184: #endif
185: }
186: sureg();
187: return;
188: bad:
189: u.u_error = EINVAL;
190: }
191:
192: /*
193: * This is ugly but it's either this or always include [T]MSCP code even
194: * for systems without that type of device.
195: */
196: #include "tms.h"
197: #include "ra.h"
198: #if NTMSCP > 0
199: extern int tmscpprintf, tmscpcache; /* see pdpuba/tmscp.c */
200: #endif
201: #if NRAC > 0
202: extern int mscpprintf;
203: #endif
204: extern struct tty cons[];
205:
206: /*
207: * This was moved here when the TMSCP portion was added. At that time it
208: * became (even more) system specific and didn't belong in kern_sysctl.c
209: */
210:
211: int
212: cpu_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
213: int *name;
214: u_int namelen;
215: void *oldp;
216: size_t *oldlenp;
217: void *newp;
218: size_t newlen;
219: {
220:
221: switch (name[0])
222: {
223: case CPU_CONSDEV:
224: if (namelen != 1)
225: return(ENOTDIR);
226: return(sysctl_rdstruct(oldp, oldlenp, newp,
227: &cons[0].t_dev, sizeof &cons[0].t_dev));
228: #if NTMSCP > 0
229: case CPU_TMSCP:
230: /* All sysctl names at this level are terminal */
231: if (namelen != 2)
232: return(ENOTDIR);
233: switch (name[1])
234: {
235: case TMSCP_CACHE:
236: return(sysctl_int(oldp, oldlenp, newp,
237: newlen, &tmscpcache));
238: case TMSCP_PRINTF:
239: return(sysctl_int(oldp, oldlenp, newp,
240: newlen,&tmscpprintf));
241: default:
242: return(EOPNOTSUPP);
243: }
244: #endif
245: #if NRAC > 0
246: case CPU_MSCP:
247: /* All sysctl names at this level are terminal */
248: if (namelen != 2)
249: return(ENOTDIR);
250: switch (name[1])
251: {
252: case MSCP_PRINTF:
253: return(sysctl_int(oldp, oldlenp, newp,
254: newlen,&mscpprintf));
255: default:
256: return(EOPNOTSUPP);
257: }
258: #endif
259: default:
260: return(EOPNOTSUPP);
261: }
262: /* NOTREACHED */
263: }
Defined functions
lock
defined in line
75; used 2 times
phys
defined in line
136; used 5 times
ucall
defined in line
32; used 2 times
Defined variables
Defined struct's
a
defined in line
138; used 8 times