#include "../h/param.h" #include "../h/systm.h" #include "../h/dir.h" #include "../h/user.h" #include "../h/proc.h" #include "../h/text.h" #include "../h/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; if(sep) { #ifdef SEP_ID if (!sepid) goto err; if(ctos(nt) > 8 || ctos(nd)+ctos(ns) > 8) #endif SEP_ID goto err; } else if(ctos(nt)+ctos(nd)+ctos(ns) > 8) goto err; if(nt+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; } #ifdef SEP_ID if(sep) while(ap < &u.u_uisa[8]) { *ap++ = 0; *dp++ = 0; } #endif SEP_ID 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; } #ifdef SEP_ID if(sep) while(ap < &u.u_uisa[16]) { if(*dp & ABS) { dp++; ap++; continue; } *dp++ = 0; *ap++ = 0; } #endif SEP_ID 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); }