File:  [MW Coherent from dump] / coherent / d / PS2_KERNEL / i286 / md1.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/* $Header: /var/lib/cvsd/repos/coherent/coherent/d/PS2_KERNEL/i286/md1.c,v 1.1.1.1 2019/05/29 04:56:39 root Exp $ */
/* (lgl-
 *	The information contained herein is a trade secret of Mark Williams
 *	Company, and  is confidential information.  It is provided  under a
 *	license agreement,  and may be  copied or disclosed  only under the
 *	terms of  that agreement.  Any  reproduction or disclosure  of this
 *	material without the express written authorization of Mark Williams
 *	Company or persuant to the license agreement is unlawful.
 *
 *	COHERENT Version 2.3.37
 *	Copyright (c) 1982, 1983, 1984.
 *	An unpublished work by Mark Williams Company, Chicago.
 *	All rights reserved.
 -lgl) */
/*
 * 8086/8088 Coherent.
 * All machines.
 * Machine dependent stuff.
 *
 * $Log: md1.c,v $
 * Revision 1.1.1.1  2019/05/29 04:56:39  root
 * coherent
 *
 * Revision 1.1  92/07/17  15:21:32  bin
 * Initial revision
 * 
 * Revision 1.2	88/08/05  15:34:26	src
 * mproto(), segload(), and msetsys() functions simplified.
 * 
 * Revision 1.1	88/03/24  17:39:43	src
 * Initial revision
 * 
 * 88/03/10	Allan Cornish		/usr/src/sys/coh/proc.c
 * Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
 * These partial fixes will be removed once all CPU's are replaced.
 *
 * 88/02/13	Allan Cornish		/usr/src/sys/i8086/src/md1.c
 * segload() now checks for regl[OIP] being system code segment.
 * iAPX-286 protected mode interrupt gates enable interrupts momentarily.
 *
 * 88/01/21	Allan Cornish		/usr/src/sys/i8086/src/md1.c
 * Segments are now de-associated from processes before freeing the segment.
 *
 * 87/11/05	Allan Cornish		/usr/src/sys/i8086/src/md1.c
 * New seg struct now used to allow extended addressing.
 *
 * 87/09/21	Allan Cornish	/usr/src/sys/i8086/src/md1.c
 * mproto() and setload() modified to support loadable driver processes.
 */
#include <sys/coherent.h>
#include <sys/i8086.h>
#include <sys/clist.h>
#include <errno.h>
#include <sys/inode.h>
#include <sys/proc.h>
#include <sys/seg.h>
#include <signal.h>

/*
 * Calculate segmentation for a
 * new program. If there is a stack segment
 * present merge it into the data segment and
 * relocate the argument list.
 * Make sure that the changes are reflected in the u.u_segl array
 * which sproto sets up.
 */
mproto()
{
	register PROC	*pp;
	register SEG	*dsp;
	register SEG	*ssp;
	register SEG	*csp;
	fsize_t		ds;
	fsize_t		ss;
	unsigned int	so;
	unsigned int	*up;
	unsigned int	v;

	pp = SELF;

	dsp = pp->p_segp[SIPDATA];

	if ( ((pp->p_flags & PFKERN) == 0)
	  && ((ssp=pp->p_segp[SISTACK]) != NULL) ) {
		ds = dsp->s_size;
		ss = ssp->s_size;
		so = ds + ss;
		if (seggrow(dsp, (fsize_t)so) == 0)
			return (0);
		plrcopy( ssp->s_paddr, dsp->s_paddr + ds, ss);
		pp->p_segp[SISTACK] = NULL;
		sfree(ssp);
		u.u_sproto.mp_svb = ds;
		u.u_sproto.mp_svl = so;
		if (u.u_argp != NULL) {
			abase(FP_SEL(dsp->s_faddr));
			up = u.u_argp += so;
			--up;
			while (ageti(--up) != NULL)
				;
			up -= 2+u.u_argc;
			while ((v=ageti(up)) != NULL)
				aputi(up++, v+so);
			while ((v=ageti(++up)) != NULL)
				aputi(up, v+so);
		}
		return (sproto());	/* Recurse to fix u.u_segl */
	}

	/*
	 * Shared code, private code, or kernel code [csp == NULL].
	 * NOTE: Combined code/data no longer supported.
	 */
	if ( (csp = pp->p_segp[SISTEXT]) == NULL )
		csp = pp->p_segp[SIPTEXT];

	/*
	 * Special case if no code/data segment specified.
	 */
	u.u_sproto.mp_cbp = (csp != NULL) ? &FP_SEL(csp->s_faddr) : &scs;
	u.u_sproto.mp_dbp = (dsp != NULL) ? &FP_SEL(dsp->s_faddr) : &sds;
	u.u_sproto.mp_csl = (csp != NULL) ? csp->s_size - 1 : 0;
	u.u_sproto.mp_dsl = (dsp != NULL) ? dsp->s_size - 1 : 0;

	return (1);
}

/*
 * Load up segmentation registers.
 */
segload()
{
	register unsigned *ip;
	register unsigned s;

	ucs = *u.u_sproto.mp_cbp;
	uds = *u.u_sproto.mp_dbp;
	ucl =  u.u_sproto.mp_csl;
	udl =  u.u_sproto.mp_dsl;

	ip = regl;
	ip[OCS] = ucs;
	ip[ODS] = s = uds;
	ip[OES] = s;
	ip[OSS] = s;
}

/*
 * Set up a new process.
 */
msetusr(ip, sp)
vaddr_t sp;
vaddr_t ip;
{
	regl[OIP] = ip;
	regl[OSP] = sp + u.u_sproto.mp_svl;
}

/*
 * Set up initial context for a system process.
 * System processes run at depth 1, just like any
 * user process. This is necessary to make sure that
 * the machine state save is correctly handled, just
 * in case the clock hits a kernel process executing
 * out of the IBM ROM.
 */
msetsys(mp, fn, us)
register MCON *mp;
int (*fn)();
saddr_t us;
{
	mp->mc_sp = (int)(&u) + UPASIZE - 32;
	mp->mc_pc = fn;
	mp->mc_fw = 0;
	mp->mc_depth = 1;
}

/*
 * Set the given address in the user area to the given value if it is
 * okay to do so.
 */
msetuof(a, v)
register int a;
{
	if (a<UPASIZE+OBP*2 || a>UPASIZE+OFW*2)
		return (0);
	if (a == UPASIZE+OCS*2)
		return (0);
	if (a == UPASIZE+ODS*2)
		return (0);
	if (a == UPASIZE+OES*2)
		return (0);
	if (a == UPASIZE+OSS*2)
		return (0);
	if (a == UPASIZE+OID*2)		/* Protect trap id */
		return (0);
	if (a == UPASIZE+ORA*2)
		return (0);		/* Protect trap return link */
	*((int *)((int)&u+a)) = v;
	return (1);
}

/*
 * Cause a signal routine to be executed.
 */
msigint(n, f)
{
	register int *usp;

	usp = regl[OSP];
	putuwd(--usp, regl[OFW]);
	putuwd(--usp, regl[OIP]);
	putuwd(--usp, n);
	regl[OFW] &= ~MFTTB;
	regl[OIP] = f;
	regl[OSP] = usp;
	if (n != SIGTRAP)
		u.u_sfunc[n-1] = SIG_DFL;
}

/*
 * Cause the next instruction to single step.
 */
msigsin()
{
	regl[OFW] |= MFTTB;
}

/*
 * Fix up context.
 */
mfixcon(pp)
PROC *pp;
{
}

/*
 * Idle kernel process.
 */
idle()
{
	for (;;) {
		disflag = 1;
		_idle();
	}
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.