Ultrix-3.1/sys/sys/ureg.c
/**********************************************************************
* Copyright (c) Digital Equipment Corporation 1984, 1985, 1986. *
* All Rights Reserved. *
* Reference "/usr/src/COPYRIGHT" for applicable restrictions. *
**********************************************************************/
/*
* SCCSID: @(#)ureg.c 3.2 3/4/87
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/dir.h>
#include <sys/user.h>
#include <sys/proc.h>
#include <sys/text.h>
#include <sys/seg.h>
/*
* Load the user hardware segmentation
* registers from the software prototype.
* The software registers must have
* been setup prior by estabur.
*/
sureg()
{
register *udp, *uap, *rdp;
int *rap, *limudp;
int taddr, daddr;
struct text *tp;
taddr = daddr = u.u_procp->p_addr;
if ((tp=u.u_procp->p_textp) != NULL)
taddr = tp->x_caddr;
limudp = &u.u_uisd[16];
if (!sepid)
limudp = &u.u_uisd[8];
rap = (int *)UISA;
rdp = (int *)UISD;
uap = &u.u_uisa[0];
for (udp = &u.u_uisd[0]; udp < limudp;) {
*rap++ = *uap++ + (*udp&TX? taddr: (*udp&ABS? 0: daddr));
*rdp++ = *udp++;
}
}
/*
* Set up software prototype segmentation
* registers to implement the 3 pseudo
* text,data,stack segment sizes passed
* as arguments.
* The argument sep specifies if the
* text and data+stack segments are to
* be separated.
* The last argument determines whether the text
* segment is read-write or read-only.
*/
estabur(nt, nd, ns, sep, xrw)
unsigned nt, nd, ns;
{
register a, *ap, *dp;
register unsigned ts;
register novlseg;
int last,first;
int *limudp;
char bitm;
if(u.u_ovdata.uo_ovbase && nt)
ts = u.u_ovdata.uo_dbase - 1;
else
ts = nt;
last = 0;
first = 8;
for(bitm=u.u_mbitm; bitm; bitm <<= 1 ) {
--first;
if(bitm < 0 && last == 0)
last = first;
}
if(sep) {
#ifndef NONSEPERATE
if (!sepid)
goto err;
if(ctos(nd) > first || 8-ctos(ns) <= last) {
goto err;
}
if(ctos(ts) > 8 || ctos(nd)+ctos(ns) > 8)
#endif NONSEPERATE
goto err;
} else {
if (ctos(ts) + ctos(nd) > first || 8-ctos(ns) <= last) {
goto err;
}
if(ctos(ts)+ctos(nd)+ctos(ns) > 8)
goto err;
}
if(u.u_ovdata.uo_ovbase && nt)
ts = u.u_ovdata.uo_ov_offst[7];
if(ts+nd+ns+USIZE > maxmem)
goto err;
a = 0;
ap = &u.u_uisa[0];
dp = &u.u_uisd[0];
while(nt >= 128) {
*dp++ = (127<<8) | xrw|TX;
*ap++ = a;
a += 128;
nt -= 128;
}
if(nt) {
*dp++ = ((nt-1)<<8) | xrw|TX;
*ap++ = a;
}
if(u.u_ovdata.uo_ovbase && nt){ /* overlay process adjust accord */
novlseg = 0;
if(u.u_ovdata.uo_curov != 0){ /* map in current overlay */
a = u.u_ovdata.uo_ov_offst[u.u_ovdata.uo_curov-1];
nt = u.u_ovdata.uo_ov_offst[u.u_ovdata.uo_curov] - a;
while(nt >= 128){
*dp++ = (127<<8) | xrw|TX;
*ap++ = a;
a += 128;
nt -= 128;
novlseg++;
}
if(nt){
*dp++ = ((nt-1)<<8)|xrw|TX;
*ap++ = a;
novlseg++;
}
}
#ifndef NONSEPERATE
if(!sep)
#endif NONSEPERATE
for(; novlseg < u.u_ovdata.uo_nseg; novlseg++){
*ap++ = 0;
*dp++ = 0;
}
}
#ifndef NONSEPERATE
if(sep)
while(ap < &u.u_uisa[8]) {
*ap++ = 0;
*dp++ = 0;
}
#endif NONSEPERATE
a = USIZE;
while(nd >= 128) {
*dp++ = (127<<8) | RW;
*ap++ = a;
a += 128;
nd -= 128;
}
if(nd) {
*dp++ = ((nd-1)<<8) | RW;
*ap++ = a;
a += nd;
}
while(ap < &u.u_uisa[8]) {
if(*dp &ABS) {
dp++;
ap++;
continue;
}
*dp++ = 0;
*ap++ = 0;
}
#ifndef NONSEPERATE
if(sep)
while(ap < &u.u_uisa[16]) {
if(*dp & ABS) {
dp++;
ap++;
continue;
}
*dp++ = 0;
*ap++ = 0;
}
#endif NONSEPERATE
a += ns;
while(ns >= 128) {
a -= 128;
ns -= 128;
*--dp = (127<<8) | RW;
*--ap = a;
}
if(ns) {
*--dp = ((128-ns)<<8) | RW | ED;
*--ap = a-128;
}
if(!sep) {
ap = &u.u_uisa[0];
dp = &u.u_uisa[8];
while(ap < &u.u_uisa[8])
*dp++ = *ap++;
ap = &u.u_uisd[0];
dp = &u.u_uisd[8];
while(ap < &u.u_uisd[8])
*dp++ = *ap++;
}
sureg();
return(0);
err:
u.u_error = ENOMEM;
return(-1);
}