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

/* (lgl-
 *	md.c
 *
 *	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) */
/*
 * Coherent 386
 *	IBM PC
 * Machine dependent stuff.
 *
 */
#include <sys/coherent.h>
#include <sys/reg.h>
#include <sys/clist.h>
#include <errno.h>
#include <sys/inode.h>
#include <sys/proc.h>
#include <sys/seg.h>
#include <signal.h>
#include <sys/uproc.h>
#include <sys/buf.h>

/*
 * Set up a new process.
 */
msetusr(ip, sp)
caddr_t sp;
caddr_t ip;
{
	u.u_regl[EIP] = ip;
	u.u_regl[UESP] = sp;
}

/*
 * Given an irq level (1..15) and an irq function pointer, try to hook the
 * function into the desired interrupt.  Do not allow resetting of the
 * clock interrupt, irq 0.
 *
 * On success, return 1.
 * If the level number is invalid or the interrupt is already in use,
 * do nothing but return 0.
 *
 * Make an entry in the "vecs" table, for use by the assist.
 * Make sure that the channel on the 8259 is armed.
 * Interrupt vectors 2 and 9 are mapped into channel 9.
 */
int
setivec(level, fun)
unsigned int	level;
int		(*fun)();
{
	register int	picm;
	extern	 int	(*vecs[])();
	extern	 int	vret();

	if (level >= NUM_IRQ_LEVELS)
		return 0;
	if (level == 2)
		level = 9;
	if (level==0 || vecs[level]!=&vret)
		return 0;

	vecs[level] = fun;

	/*
	 * NIGEL: The original code here (and matching code below in clrivec ())
	 * takes pains to correctly manipulate the slave PIC chain mask bit in
	 * the master PIC. This is redundant, and unnecessarily complex, so I
	 * have removed it to aid the process of adding a more rational system
	 * of interrupt handling for the DDI/DKI.
	 *
	 * Now the slave PIC chain mask bit is enabled (via a modification to
	 * code in "i386/as.s") at startup, and it should never be disabled.
	 *
	 * The rational interrupt scheme requires that the implementations of
	 * the DDI/DKI functions know the base-level mask value so that they
	 * can correctly (and quickly) manipulate masks to raise and lower
	 * priority levels even when deeply nested inside interrupts (see the
	 * implementations of those functions for a deeper discussion of the
	 * issues involved). This function cooperates with the new system via
	 * the DDI_BASE_..._MASK () macro, which either manipulates the mask
	 * register as the old code did or passes responsibility over to the
	 * new DDI/DKI scheme if it has been enabled.
	 *
	 * The new macro-calls are defined in <sys/reg.h>
	 */

	if ( level >= LOWEST_SLAVE_IRQ ) {
		picm = inb(SPICM);
		picm &= ~(0x01 << (level-LOWEST_SLAVE_IRQ));
		DDI_BASE_SLAVE_MASK (picm);
	} else {
		picm = inb(PICM);
		picm &= ~(0x01 << level);
		DDI_BASE_MASTER_MASK (picm);
	}
	return 1;
}

/*
 * Clear an interrupt vector.
 */
clrivec(level)
register int	level;
{
	register int	picm;
	extern	 int	(*vecs[])();
	extern	 int	vret();

	if ((level &= 0x0F) == 2)
		level = 9;
	if (level == 0)
		printf("clrivec: level=%d", level);
	vecs[level] = &vret;

	/*
	 * NIGEL: This code has been modified to match the changes made to the
	 * setivec () routine above. See the comment there for details.
	 */

	if (level >= LOWEST_SLAVE_IRQ) {
		picm = inb(SPICM);
		picm |= (0x01 << (level-LOWEST_SLAVE_IRQ));
		DDI_BASE_SLAVE_MASK (picm);
	} else {
		picm = inb(PICM);
		picm |= (0x01 << level);
		DDI_BASE_SLAVE_MASK (picm);
	}
}


/*
 * Convert an array of filesystem 3 byte
 * numbers to longs. This routine, unlike the old one,
 * is independent of the order of bytes in a long.
 * Bytes have 8 bits, though.
 */
l3tol(lp, cp, nl)
register long *lp;
register unsigned char *cp;
register unsigned nl;
{
	register long l;

	if (nl != 0) {
		do {
			l  = (long)cp[0] << 16;
			l |= (long)cp[1];
			l |= (long)cp[2] << 8;
			cp += 3;
			*lp++ = l;
		} while (--nl);
	}
}
/*
 * Convert an array of longs into an array
 * of filesystem 3 byte numbers. This routine, unlike
 * the old one, is independent of the order of bytes in
 * a long. Bytes have 8 bits.
 */
ltol3(cp, lp, nl)
register char *cp;
register long *lp;
register unsigned nl;
{
	register long l;

	if (nl != 0) {
		do {
			l = *lp++;
			cp[0] = l >> 16;
			cp[1] = l;
			cp[2] = l >> 8;
			cp += 3;
		} while (--nl);
	}
}


/*
 * Given a port number and a bit value, write the bit value into
 * the tss iomap.
 *
 * Bit value of 0 enables user I/O for that port.
 * Bit value of 1 disables user I/O for that port.
 *
 * Return 1 if port number is valid for the bitmap, else 0.
 */
int
kiopriv(port, bit)
unsigned int port, bit;
{
	extern int tssIoMap;
	extern int tssIoEnd;
	int ret = 0;
	int * ip;
	unsigned int offset = port >> 5;
	int shift = port & 0x1f;
	int mask = 1 << shift;
	int val = (bit & 1) << shift;

	if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) {
		ip = (& tssIoMap) + offset;
		*ip &= ~mask;		/* clear old bit value */
		*ip |= val;		/* or in desired new bit value */
		ret = 1;
	}
	return ret;
}

/*
 * Given a 32 bit mask and a word offset into the tss io map,
 * bitwise or the mask into the map.
 * Offset of 0 covers ports 0..31, offset of 1 covers ports 32..63, etc.
 * Current valid range for offset is 0..63, covering ports 0..7ff.
 *
 * Return the new map word.
 */
int
iomapOr(val, offset)
int val, offset;
{
	extern int tssIoMap;
	extern int tssIoEnd;
	int ret;
	int * ip;

	if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) {
		ip = (& tssIoMap) + offset;
		ret = *ip |= val;
	}
	return ret;
}

/*
 * Given a 32 bit mask and a word offset into the tss io map,
 * bitwise and the mask into the map.
 * Offset of 0 covers ports 0..31, offset of 1 covers ports 32..63, etc.
 * Current valid range for offset is 0..63, covering ports 0..7ff.
 *
 * Return the new map word.
 */
int
iomapAnd(val, offset)
int val, offset;
{
	extern int tssIoMap;
	extern int tssIoEnd;
	int ret;
	int * ip;

	if (offset >= 0 && offset < (&tssIoEnd - &tssIoMap)) {
		ip = (& tssIoMap) + offset;
		ret = *ip &= val;
	}
	return ret;
}

unix.superglobalmegacorp.com

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