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_mman.c 1.3 (2.11BSD) 2000/2/20
7: */
8:
9: #include "param.h"
10: #include "../machine/seg.h"
11:
12: #include "user.h"
13: #include "proc.h"
14: #include "vm.h"
15: #include "text.h"
16: #include "systm.h"
17:
18: sbrk()
19: {
20: struct a {
21: char *nsiz;
22: };
23: register int n, d;
24:
25: /* set n to new data size */
26: n = btoc((int)((struct a *)u.u_ap)->nsiz);
27: if (!u.u_sep)
28: if (u.u_ovdata.uo_ovbase)
29: n -= u.u_ovdata.uo_dbase;
30: else
31: n -= ctos(u.u_tsize) * stoc(1);
32: if (n < 0)
33: n = 0;
34: if (estabur(u.u_tsize, n, u.u_ssize, u.u_sep, RO))
35: return;
36: expand(n, S_DATA);
37: /* set d to (new - old) */
38: d = n - u.u_dsize;
39: if (d > 0)
40: clear(u.u_procp->p_daddr + u.u_dsize, d);
41: u.u_dsize = n;
42: }
43:
44: /*
45: * grow the stack to include the SP
46: * true return if successful.
47: */
48: grow(sp)
49: register unsigned sp;
50: {
51: register int si;
52:
53: if (sp >= -ctob(u.u_ssize))
54: return (0);
55: si = (-sp) / ctob(1) - u.u_ssize + SINCR;
56: /*
57: * Round the increment back to a segment boundary if necessary.
58: */
59: if (ctos(si + u.u_ssize) > ctos(((-sp) + ctob(1) - 1) / ctob(1)))
60: si = stoc(ctos(((-sp) + ctob(1) - 1) / ctob(1))) - u.u_ssize;
61: if (si <= 0)
62: return (0);
63: if (estabur(u.u_tsize, u.u_dsize, u.u_ssize + si, u.u_sep, RO))
64: return (0);
65: /*
66: * expand will put the stack in the right place;
67: * no copy required here.
68: */
69: expand(u.u_ssize + si, S_STACK);
70: u.u_ssize += si;
71: clear(u.u_procp->p_saddr, si);
72: return (1);
73: }
74:
75: /*
76: * Set up software prototype segmentation registers to implement the 3
77: * pseudo text, data, stack segment sizes passed as arguments. The
78: * argument sep specifies if the text and data+stack segments are to be
79: * separated. The last argument determines whether the text segment is
80: * read-write or read-only.
81: */
82: estabur(nt, nd, ns, sep, xrw)
83: u_int nt, nd, ns;
84: int sep, xrw;
85: {
86: register int a;
87: register short *ap, *dp;
88: u_int ts;
89:
90: if (u.u_ovdata.uo_ovbase && nt)
91: ts = u.u_ovdata.uo_dbase;
92: else
93: ts = nt;
94: if (sep) {
95: #ifndef NONSEPARATE
96: if (!sep_id)
97: goto nomem;
98: if (ctos(ts) > 8 || ctos(nd)+ctos(ns) > 8)
99: #endif !NONSEPARATE
100: goto nomem;
101: } else
102: if (ctos(ts) + ctos(nd) + ctos(ns) > 8)
103: goto nomem;
104: if (u.u_ovdata.uo_ovbase && nt)
105: ts = u.u_ovdata.uo_ov_offst[NOVL];
106: if (ts + nd + ns + USIZE > maxmem) {
107: nomem: u.u_error = ENOMEM;
108: return (-1);
109: }
110: a = 0;
111: ap = &u.u_uisa[0];
112: dp = &u.u_uisd[0];
113: while (nt >= 128) {
114: *dp++ = (127 << 8) | xrw | TX;
115: *ap++ = a;
116: a += 128;
117: nt -= 128;
118: }
119: if (nt) {
120: *dp++ = ((nt - 1) << 8) | xrw | TX;
121: *ap++ = a;
122: }
123: #ifdef NONSEPARATE
124: if (u.u_ovdata.uo_ovbase && ts)
125: #else !NONSEPARATE
126: if ((u.u_ovdata.uo_ovbase && ts) && !sep)
127: #endif NONSEPARATE
128: /*
129: * overlay process, adjust accordingly.
130: * The overlay segment's registers will be set by
131: * choverlay() from sureg().
132: */
133: for (a = 0; a < u.u_ovdata.uo_nseg; a++) {
134: *ap++ = 0;
135: *dp++ = 0;
136: }
137: #ifndef NONSEPARATE
138: if (sep)
139: while(ap < &u.u_uisa[8]) {
140: *ap++ = 0;
141: *dp++ = 0;
142: }
143: #endif !NONSEPARATE
144:
145: a = 0;
146: while (nd >= 128) {
147: *dp++ = (127 << 8) | RW;
148: *ap++ = a;
149: a += 128;
150: nd -= 128;
151: }
152: if (nd) {
153: *dp++ = ((nd - 1) << 8) | RW;
154: *ap++ = a;
155: a += nd;
156: }
157: while (ap < &u.u_uisa[8]) {
158: if (*dp & ABS) {
159: dp++;
160: ap++;
161: continue;
162: }
163: *dp++ = 0;
164: *ap++ = 0;
165: }
166: #ifndef NONSEPARATE
167: if (sep)
168: while (ap < &u.u_uisa[16]) {
169: if(*dp & ABS) {
170: dp++;
171: ap++;
172: continue;
173: }
174: *dp++ = 0;
175: *ap++ = 0;
176: }
177: #endif !NONSEPARATE
178: a = ns;
179: while (ns >= 128) {
180: a -= 128;
181: ns -= 128;
182: *--dp = (0 << 8) | RW | ED;
183: *--ap = a;
184: }
185: if (ns) {
186: *--dp = ((128 - ns) << 8) | RW | ED;
187: *--ap = a - 128;
188: }
189: #ifndef NONSEPARATE
190: if (!sep) {
191: ap = &u.u_uisa[0];
192: dp = &u.u_uisa[8];
193: while(ap < &u.u_uisa[8])
194: *dp++ = *ap++;
195: ap = &u.u_uisd[0];
196: dp = &u.u_uisd[8];
197: while(ap < &u.u_uisd[8])
198: *dp++ = *ap++;
199: }
200: #endif !NONSEPARATE
201: sureg();
202: return(0);
203: }
204:
205: /*
206: * Load the user hardware segmentation registers from the software
207: * prototype. The software registers must have been setup prior by
208: * estabur.
209: */
210: sureg()
211: {
212: register int *rdp;
213: register short *uap,
214: *udp;
215: short *limudp;
216: int *rap;
217: int taddr, daddr, saddr;
218: struct text *tp;
219:
220: taddr = daddr = u.u_procp->p_daddr;
221: saddr = u.u_procp->p_saddr;
222: if ((tp = u.u_procp->p_textp) != NULL)
223: taddr = tp->x_caddr;
224: #ifndef NONSEPARATE
225: limudp = &u.u_uisd[16];
226: if (!sep_id)
227: #endif !NONSEPARATE
228: limudp = &u.u_uisd[8];
229: rap = (int *) UISA;
230: rdp = (int *) UISD;
231: uap = &u.u_uisa[0];
232: for (udp = &u.u_uisd[0]; udp < limudp;) {
233: *rap++ = *uap++ + (*udp & TX? taddr:
234: (*udp & ED ? saddr: (*udp & ABS ? 0 : daddr)));
235: *rdp++ = *udp++;
236: }
237: /*
238: * Since software prototypes are not maintained for overlay
239: * segments, force overlay change. The test for TX is because
240: * there is no text if called from core().
241: */
242: if (u.u_ovdata.uo_ovbase && (u.u_uisd[0] & TX))
243: choverlay(u.u_uisd[0] & ACCESS);
244: }
245:
246: /*
247: * Routine to change overlays. Only hardware registers are changed; must be
248: * called from sureg since the software prototypes will be out of date.
249: */
250: choverlay(xrw)
251: int xrw;
252: {
253: register u_short *rap, *rdp;
254: register int nt;
255: int addr;
256: u_short *limrdp;
257:
258: rap = &(UISA[u.u_ovdata.uo_ovbase]);
259: rdp = &(UISD[u.u_ovdata.uo_ovbase]);
260: limrdp = &(UISD[u.u_ovdata.uo_ovbase + u.u_ovdata.uo_nseg]);
261: if (u.u_ovdata.uo_curov) {
262: addr = u.u_ovdata.uo_ov_offst[u.u_ovdata.uo_curov - 1];
263: nt = u.u_ovdata.uo_ov_offst[u.u_ovdata.uo_curov] - addr;
264: addr += u.u_procp->p_textp->x_caddr;
265: while (nt >= 128) {
266: *rap++ = addr;
267: *rdp++ = (127 << 8) | xrw;
268: addr += 128;
269: nt -= 128;
270: }
271: if (nt) {
272: *rap++ = addr;
273: *rdp++ = ((nt-1) << 8) | xrw;
274: }
275: }
276: while (rdp < limrdp) {
277: *rap++ = 0;
278: *rdp++ = 0;
279: }
280: #ifndef NONSEPARATE
281: /*
282: * This section copies the UISA/UISD registers to the
283: * UDSA/UDSD registers. It is only needed for data fetches
284: * on the overlaid segment, which normally don't happen.
285: */
286: if (!u.u_sep && sep_id) {
287: rdp = &(UISD[u.u_ovdata.uo_ovbase]);
288: rap = rdp + 8;
289: /* limrdp is still correct */
290: while (rdp < limrdp)
291: *rap++ = *rdp++;
292: rdp = &(UISA[u.u_ovdata.uo_ovbase]);
293: rap = rdp + 8;
294: limrdp = &(UISA[u.u_ovdata.uo_ovbase + u.u_ovdata.uo_nseg]);
295: while (rdp < limrdp)
296: *rap++ = *rdp++;
297: }
298: #endif !NONSEPARATE
299: }
Defined functions
grow
defined in line
48; used 4 times
sbrk
defined in line
18; used 2 times
Defined struct's
a
defined in line
20; used 2 times