BBN-V6/ken/main.c

Compare this file to the similar file:
Show the results in this format:

#
#include "../h/param.h"
#include "../h/user.h"
#include "../h/systm.h"
#include "../h/proc.h"
#include "../h/text.h"
#include "../h/inode.h"
#include "../h/seg.h"

#define	CLOCK1	0177546
#define	CLOCK2	0172540
/*
 * Icode is the octal bootstrap
 * program executed in user mode
 * to bring up the system.
 */
int	icode[]
{
	0104413,	/* sys exec; init; initp */
	0000014,
	0000010,
	0000777,	/* br . */
	0000014,	/* initp: init; 0 */
	0000000,
	0062457,	/* init: </etc/init\0> */
	0061564,
	0064457,
	0064556,
	0000164,
};

/*
 * Initialization code.
 * Called from m40.s or m45.s as
 * soon as a stack and segmentation
 * have been established.
 * Functions:
 *	clear and free user core
 *	find which clock is configured
 *	hand craft 0th process
 *	call all initialization routines
 *	fork - process 0 to schedule
 *	     - process 1 execute bootstrap
 *
 * panic: no clock -- neither clock responds
 * loop at loc 6 in user mode -- /etc/init
 *	cannot be executed.
 */
main()
{
	extern schar;
	register i, *p;
	register struct proc *cp;

	/*
	 * zero and free all of core
	 */

	printf("BBN-UNIX startup.\n");
	updlock = 0;

	/* BUFMOD code reserves NSBUF*512 bytes of buffers in
	 * non-kernel space (NKS) for use as system buffers. Initially
	 * these NKS system buffers will be used only by
	 * the network software. 4/12/79 S.Y. Chiu BBN
	 */
#ifdef BUFMOD
	i = *ka6 + USIZE + NSBUF*(512>>6);
#endif BUFMOD

#ifndef BUFMOD
	i = *ka6 + USIZE;
#endif BUFMOD

	UISD->r[0] = 077406;
	for(;;) {
		UISA->r[0] = i;
		if(fuibyte(0) < 0)
			break;
		clearseg(i);
		maxmem++;
		mfree(coremap, 1, i);
		i++;
	}
	if(cputype == 70)
	for(i=0; i<62; i=+2) {
		UBMAP->r[i] = i<<12;
		UBMAP->r[i+1] = 0;
	}

	mfree(ubmap, MAPSIZE - MAPLOW, MAPLOW); /* initialize map to be
						  * used in mapalloc */


	printf("mem = %l\n", (maxmem+(maxmem>>2))>>2); /* maxmem*5/16 */
#ifdef  LCBA
	/* lcba_address initially contains UNIXMIN, defined in map_page.c */
	lcba_count = lcba_max = lcba_size = 0;  /* not strictly necessary */
	if (maxmem > lcba_address) lcba_max = maxmem - lcba_address;
#endif
	maxmem = min(maxmem, MAXMEM);
	mfree(swapmap, nswap, swplo);

	/*
	 * determine clock
	 */

	UISA->r[7] = ka6[1]; /* io segment */
	UISD->r[7] = 077406;
	lks = CLOCK1;
	if(fuiword(lks) == -1) {
		lks = CLOCK2;
		if(fuiword(lks) == -1)
			panic("no clock");
	}

	/*
	 * set up system process
	 */

	/* link all processes in the free queue */
	i = 0;
	for( cp = &proc[1]; cp < &proc[ NPROC ]; cp++ )
	{
		cp->p_pid = ++i;
		qenter( &Free_proc.qhead,cp );
	}

	MAXPROC = &proc[1];
	proc[0].p_addr = *ka6;
	proc[0].p_size = USIZE;
	proc[0].p_stat = SRUN;
	proc[0].p_flag =| SLOAD|SSYS;
	u.u_procp = &proc[0];

	/*
	 * set up 'known' i-nodes
	 */

	*lks = 0115;
	cinit();
	binit();

	/* need to also initialize the control blocks of the NKS
	 * system buffers
	 */
#ifdef BUFMOD
	bsinit(*ka6 + USIZE);
#endif BUFMOD

	iinit();
	rootdir = iget(rootdev, ROOTINO);
	rootdir->i_flag =& ~ILOCK;
	u.u_cdir = iget(rootdev, ROOTINO);
	u.u_cdir->i_flag =& ~ILOCK;

	/*
	 * make init process
	 * enter scheduling loop
	 * with system process
	 */

	if(newproc()) {
		expand(USIZE+1);
		estabur(0, 1, 0, 0);
		copyout(icode, 0, sizeof icode);
		/*
		 * Return goes to loc. 0 of user init
		 * code just copied out.
		 */
		return;
	}
	sched();
}

/*
 * Load the user hardware segmentation
 * registers from the software prototype.
 * The software registers must have
 * been setup prior by estabur.
 */
sureg()
{
	register *up, *rp, a;
#ifdef	LCBA
	int b, *ua, *ra;
#endif

	a = u.u_procp->p_addr;
	up = &u.u_uisa[16];
	rp = &UISA->r[16];
	if(cputype == 40) {
		up =- 8;
		rp =- 8;
	}
	while(rp > &UISA->r[0])
		*--rp = *--up + a;
	if((up=u.u_procp->p_textp) != NULL)
		a =- up->x_caddr;
	up = &u.u_uisd[16];
	rp = &UISD->r[16];
	if(cputype == 40) {
		up =- 8;
		rp =- 8;
	}
	while(rp > &UISD->r[0]) {
		*--rp = *--up;
		if((*rp & WO) == 0)
			rp[(UISA-UISD)/2] =- a;
	}
#ifdef LCBA
	if (u.u_lcbflg) {      /* do this only if process has siezed lcba */
		up = &u.u_lcbmd[0];
		rp = &UISD -> r[0];
		ua = &u.u_lcbma[0];
		ra = &UISA -> r[0];
		a = lcba_address;
		b = (cputype == 40)?8:16;
		while (rp < &UISD -> r[b]){
			if (*up && !*rp){
				*rp = *up;
				*ra = *ua + a;
			}
			up++; rp++; ua++; ra++;
		}
	}
/*
 * jsq BBN Tue Jul 25 19:26:08 EDT 1978
 * Note this addition sets a hardware APF only if the software descriptor
 * register is set and the hardware descriptor register is not set.  This should
 * keep the lcba code from interfering with the unix page mapping even if map_page
 * somehow messes up.
 */
#endif
}

/*
 * 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.
 */
estabur(nt, nd, ns, sep)
{
	register a, *ap, *dp;

	if(sep) {
		if(cputype == 40)
			goto err;
		if(nseg(nt) > 8 || nseg(nd)+nseg(ns) > 8)
			goto err;
	} else
		if(nseg(nt)+nseg(nd)+nseg(ns) > 8)
			goto err;
	if(nt+nd+ns+USIZE > maxmem)
		goto err;
#ifdef	LCBA
/* jsq BBN Tue Jul 25 19:23:46 EDT 1978 */
	if (u.u_lcbflg) {
		if (sep) {
			if (u.u_mintlcb && (nseg(nt) >= u.u_mintlcb))
				goto err;
			if (u.u_minlcb && (nseg(nd) >= u.u_minlcb))
				goto err;
		} else {
			if (u.u_minlcb &&
			    ((nseg(nt) + nseg(nd)) >= u.u_minlcb))
				goto err;
		}
		if ((u.u_maxlcb + nseg(ns)) > 8) goto err;
	}
#endif
	a = 0;
	ap = &u.u_uisa[0];
	dp = &u.u_uisd[0];
	while(nt >= 128) {
		*dp++ = (127<<8) | RO;
		*ap++ = a;
		a =+ 128;
		nt =- 128;
	}
	if(nt) {
		*dp++ = ((nt-1)<<8) | RO;
		*ap++ = a;
	}
	if(sep)
	while(ap < &u.u_uisa[8]) {
		*ap++ = 0;
		*dp++ = 0;
	}
	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]) {
		*dp++ = 0;
		*ap++ = 0;
	}
	if(sep)
	while(ap < &u.u_uisa[16]) {
		*dp++ = 0;
		*ap++ = 0;
	}
	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);
}

/*
 * Return the arg/128 rounded up.
 */
nseg(n)
{

	return((n+127)>>7);
}