~kris/9p

9hist

596537fc594911e530db6702027251b8301560d2 — David du Colombier 34 years ago 22ffe4f
Plan 9 from Bell Labs 1992-09-23
11 files changed, 242 insertions(+), 173 deletions(-)

A pc/archgeneric.c
A pc/archncr3170.c
R pc/{pmu => archnsx20}.c
M pc/clock.c
M pc/dat.h
M pc/ether509.c
M pc/fns.h
D pc/headland.c
M pc/main.c
M port/sysproc.c
M power/mem.h
A pc/archgeneric.c => pc/archgeneric.c +25 -0
@@ 0,0 1,25 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"

static void
genericreset(void)
{
	print("Reset the machine!\n");
	for(;;);
}

PCArch generic =
{
	"generic",
	genericreset,
	0,
	0,
	0,
	0,
	0,
	0,
};

A pc/archncr3170.c => pc/archncr3170.c +49 -0
@@ 0,0 1,49 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"

enum
{
	Pindex=	0x198,
	Pdata=	0x199,
};

static Lock pmulock;
static int
pmuwrbit(int index, int bit, int pos)
{
	uchar x;

	lock(&pmulock);
	outb(Pindex, index);
	x = inb(Pdata);
	if(bit)
		x |= 1<<pos;
	else
		x &= ~(1<<pos);
	outb(Pindex, index);
	outb(Pdata, x);
	unlock(&pmulock);
	return 0;
}

static int
ncr3170serialpower(int onoff)
{
	return pmuwrbit(0x85, 1^onoff, 4);
}

PCArch ncr3170 =
{
	"NCRD.0",
	i8042reset,
	0,
	0,
	0,
	ncr3170serialpower,
	0,
	0,
};

R pc/pmu.c => pc/archnsx20.c +50 -12
@@ 6,6 6,10 @@
#include	"io.h"

/*
 *  safari nsx20 specific routines
 */

/*
 *  intel power management unit (i80c51)
 */
enum {


@@ 54,8 58,8 @@ pmubusy(void)
/*
 *  set a bit in the PMU
 */
Lock pmulock;
int
static Lock pmulock;
static int
pmuwrbit(int index, int bit, int pos)
{
	lock(&pmulock);


@@ 90,8 94,8 @@ pmuwrbit(int index, int bit, int pos)
 *	onoff == 1 means on
 *	onoff == 0 means off
 */
int
pmuserial(int onoff)
static int
nsx20serialpower(int onoff)
{
	return pmuwrbit(1, 1^onoff, 6);
}


@@ 101,8 105,8 @@ pmuserial(int onoff)
 *	onoff == 1 means on
 *	onoff == 0 means off
 */
int
pmumodem(int onoff)
static int
nsx20modempower(int onoff)
{
	if(pmuwrbit(1, 1^onoff, 0)<0)		/* modem speaker */
		return -1;


@@ 114,8 118,8 @@ pmumodem(int onoff)
 * 	0 == low speed
 *	1 == high speed
 */
int
pmucpuspeed(int speed)
static int
nsx20cpuspeed(int speed)
{
	return pmuwrbit(0, speed, 0);
}


@@ 124,8 128,8 @@ pmucpuspeed(int speed)
 *  f == frequency in Hz
 *  d == duration in ms
 */
void
pmubuzz(int f, int d)
static void
nsx20buzz(int f, int d)
{
	static QLock bl;
	static Rendez br;


@@ 142,9 146,43 @@ pmubuzz(int f, int d)
 *  1 == owl eye
 *  2 == mail icon
 */
void
pmulights(int val)
static void
nsx20lights(int val)
{
	pmuwrbit(0, (val&1), 4);		/* owl */
	pmuwrbit(0, ((val>>1)&1), 1);		/* mail */
}

/*
 *  headland system controller (ht21)
 */
enum
{
	/*
	 *  system control port
	 */
	Head=		0x92,		/* control port */
	 Reset=		(1<<0),		/* reset the 386 */
	 A20ena=	(1<<1),		/* enable address line 20 */
};

/*
 *  reset machine
 */
static void
headreset(void)
{
	outb(Head, Reset);
}

PCArch nsx20 =
{
	"AT&TNSX",
	headreset,
	nsx20cpuspeed,
	nsx20buzz,
	nsx20lights,
	nsx20serialpower,
	nsx20modempower,
	0,
};

M pc/clock.c => pc/clock.c +32 -18
@@ 16,32 16,36 @@ enum
	T2cntr=	0x42,		/* ... */
	Tmode=	0x43,		/* mode port */

	Load0square=	0x36,		/*  load counter 0 with 2 bytes,
					 *  output a square wave whose
					 *  period is the counter period
					 */
	Latch0=		0x06,
	Freq=		1193182,	/* Real clock frequency */
	/* commands */
	Latch0=	0x00,		/* latch counter 0's value */
	Load0=	0x30,		/* load counter 0 with 2 bytes */

	/* modes */
	Square=	0x36,		/* perioic square wave */

	Freq=	1193182,	/* Real clock frequency */
};

static ulong delayloop = 1000;

/*
 *  delay for l milliseconds
 *  delay for l milliseconds more or less.  delayloop is set by
 *  clockinit() to match the actual CPU speed.
 */
void
delay(int l)
{
	int i;
	ulong i;

	while(--l){
		for(i=0; i < 404; i++)
	while(l-- > 0)
		for(i=0; i < delayloop; i++)
			;
	}
}

void
clockinit(void)
{
	ulong dc;	/* change in counter */
	ulong x, y;	/* change in counter */

	/*
	 *  set vector for clock interrupts


@@ 51,18 55,28 @@ clockinit(void)
	/*
	 *  make clock output a square wave with a 1/HZ period
	 */
	outb(Tmode, Load0square);
	outb(Tmode, Load0|Square);
	outb(T0cntr, (Freq/HZ));	/* low byte */
	outb(T0cntr, (Freq/HZ)>>8);	/* high byte */

	/*
	 *  measure cpu speed to make delay() system
	 *  independent
	 *  measure time for delay(10) with current delayloop count
	 */
	delay(100);
	outb(Tmode, Latch0);
	dc = inb(T0cntr);
	dc |= inb(T0cntr)<<8;
	x = inb(T0cntr);
	x |= inb(T0cntr)<<8;
	delay(10);
	outb(Tmode, Latch0);
	y = inb(T0cntr);
	y |= inb(T0cntr)<<8;
	x -= y;

	/*
	 *  fix count, the factor of 2 is a hack
	 */
	delayloop = (delayloop*1193*10)/x;
	if(delayloop == 0)
		delayloop = 1;
}

void

M pc/dat.h => pc/dat.h +18 -5
@@ 4,6 4,7 @@ typedef struct Label	Label;
typedef struct Lock	Lock;
typedef struct MMU	MMU;
typedef struct Mach	Mach;
typedef struct PCArch	PCArch;
typedef struct Page	Page;
typedef struct PMMU	PMMU;
typedef struct Segdesc	Segdesc;


@@ 177,14 178,26 @@ struct
	short	exiting;
}active;

/*
 *  routines for things outside the PC model, like power management
 */
struct PCArch
{
	char	*id;
	void	(*reset)(void);		/* this should be in the model */
	int	(*cpuspeed)(int);	/* 0 = low, 1 = high */
	void	(*buzz)(int, int);	/* make a noise */
	void	(*lights)(int);		/* turn lights or icons on/off */
	int	(*serialpower)(int);	/* 1 == on, 0 == off */
	int	(*modempower)(int);	/* 1 == on, 0 == off */
	int	(*extvga)(int);		/* 1 == external, 0 == internal */
};

extern Mach	*m;
extern User	*u;

extern int	flipD[];	/* for flipping bitblt destination polarity */

/*
 *  bootline passed by boot program
 */
#define BOOTLINE ((char *)0x80000100)
#define BOOTLINE ((char *)0x80000100) /*  bootline passed by boot program */

extern char	machtype[];
extern PCArch *arch;			/* PC architecture */

M pc/ether509.c => pc/ether509.c +37 -25
@@ 78,6 78,30 @@ enum {
#define COMMAND(hw, cmd, a)	outs(hw->addr+Command, ((cmd)<<11)|(a))

/*
 *  Write two 0 bytes to idnetify the IDport and them reset the
 *  ID sequence.  Then send the ID sequenced to the card to get
 *  the card it into command state.
 */
void
idseq(void)
{
	int i;
	uchar al;

	outb(IDport, 0);
	outb(IDport, 0);
	for(al = 0xFF, i = 0; i < 255; i++){
		outb(IDport, al);
		if(al & 0x80){
			al <<= 1;
			al ^= 0xCF;
		}
		else
			al <<= 1;
	}
}

/*
 * get configuration parameters
 */
static int


@@ 85,8 109,7 @@ reset(EtherCtlr *cp)
{
	EtherHw *hw = cp->hw;
	int i, ea;
	ushort acr;
	uchar al;
	ushort x, acr;

	cp->rb = xspanalloc(sizeof(EtherBuf)*Nrb, BY2PG, 0);
	cp->nrb = Nrb;


@@ 98,23 121,12 @@ reset(EtherCtlr *cp)
	 * at the first board that responds, if we ever have more
	 * than one we'll need to modify this sequence.
	 *
	 * 2. Write two 0 bytes then the ID sequence to the IDport.
	 * 2. get to cammand state, reset, then return to command state
	 */
	outb(IDport, 0);
	outb(IDport, 0);
	outb(IDport, 0xc0);
	delay(100)
	outb(IDport, 0);
	outb(IDport, 0);
	for(al = 0xFF, i = 0; i < 255; i++){
		outb(IDport, al);
		if(al & 0x80){
			al <<= 1;
			al ^= 0xCF;
		}
		else
			al <<= 1;
	}
	idseq();
	outb(IDport, 0xC1);
	delay(2);
	idseq();

	/*
	 * 3. Read the Product ID from the EEPROM.


@@ 128,12 140,12 @@ reset(EtherCtlr *cp)
	 * probably isn't there, so barf.
	 */
	outb(IDport, 0x83);
	for(acr = 0, i = 0; i < 16; i++){
	for(x = 0, i = 0; i < 16; i++){
		delay(5);
		acr <<= 1;
		acr |= inb(IDport) & 0x01;
		x <<= 1;
		x |= inb(IDport) & 0x01;
	}
	if((acr & 0xF0FF) != 0x9050)
	if((x & 0xF0FF) != 0x9050)
		return -1;

	/*


@@ 172,9 184,9 @@ reset(EtherCtlr *cp)
		outs(hw->addr+EEPROMcmd, (2<<6)|i);
		while(ins(hw->addr+EEPROMcmd) & 0x8000)
			;
		acr = ins(hw->addr+EEPROMdata);
		cp->ea[ea] = (acr>>8) & 0xFF;
		cp->ea[ea+1] = acr & 0xFF;
		x = ins(hw->addr+EEPROMdata);
		cp->ea[ea] = (x>>8) & 0xFF;
		cp->ea[ea+1] = x & 0xFF;
	}

	/*

M pc/fns.h => pc/fns.h +0 -7
@@ 24,8 24,6 @@ void	fpsave(FPsave*);
ulong	fpstatus(void);
ulong	getcr0(void);
ulong	getcr2(void);
void	heada20(void);
void	headreset(void);
void	i8042a20(void);
void	i8042reset(void);
void	ident(void);


@@ 47,11 45,6 @@ void	outb(int, int);
void	outs(int, ushort);
void	outss(int, void*, int);
void	outsl(int, void*, int);
void	pmubuzz(int, int);
int	pmucpuspeed(int);
void	pmulights(int);
int	pmumodem(int);
int	pmuserial(int);
void	prhex(ulong);
void	procrestore(Proc*);
void	procsave(Proc*);

D pc/headland.c => pc/headland.c +0 -37
@@ 1,37 0,0 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"io.h"

/*
 *  headland system controller (ht21)
 */
enum
{
	/*
	 *  system control port
	 */
	Head=		0x92,		/* control port */
	 Reset=		(1<<0),		/* reset the 386 */
	 A20ena=	(1<<1),		/* enable address line 20 */
};

/*
 *  enable address bit 20
 */
void
heada20(void)
{
	outb(Head, A20ena);
}

/*
 *  reset machine
 */
void
headreset(void)
{
	outb(Head, Reset);
}

M pc/main.c => pc/main.c +29 -68
@@ 8,24 8,19 @@
#include	"init.h"
#include	<ctype.h>

/* configuration parameters */
enum
{
	/* what kind of power management */
	PMUother=	0,
	PMUnsx20=	1,

	/* how to reset the processor */
	Resetother=	0,
	Reset8042=	1,
	Resetheadland=	2,
};
int pmutype;
int resettype;
char machtype[9];

uchar *sp;	/* stack pointer for /boot */

extern PCArch nsx20, generic, ncr3170;

PCArch *arch;
PCArch *knownarch[] =
{
	&nsx20,
	&ncr3170,
	&generic,
};

void
main(void)
{


@@ 51,7 46,6 @@ main(void)
	streaminit();
	swapinit();
	userinit();

	schedinit();
}



@@ 64,21 58,12 @@ void
ident(void)
{
	char *id = (char*)(ROMBIOS + 0xFF40);
	int i;
	PCArch **p;

	for(i = 0; i < 8; i++){
		if(isprint(id[i]) == 0)
	for(p = knownarch; *p != &generic; p++)
		if(strncmp((*p)->id, id, strlen((*p)->id)) == 0)
			break;
		machtype[i] = id[i];
	}
	if(i == 0)
		strcpy(machtype, "generic");
	if(strcmp(machtype, "AT&TNSX") == 0){
		pmutype = PMUnsx20;
		resettype = Resetheadland;
	}else if(strcmp(machtype, "NCRD.0") == 0){
		resettype = Reset8042;
	}
	arch = *p;
}

void


@@ 117,7 102,7 @@ init0(void)
	chandevinit();

	if(!waserror()){
		strcpy(tstr, machtype);
		strcpy(tstr, arch->id);
		strcat(tstr, " %s");
		ksetterm(tstr);
		ksetenv("cputype", "386");


@@ 447,15 432,7 @@ exit(int ispanic)
	if(ispanic)
		for(;;);

	switch(resettype){
	case Resetheadland:
		headreset();
	case Reset8042:
		i8042reset();		/* via keyboard controller */
	default:
		print("Reset the machine!\n");
		for(;;);
	}
	(*arch->reset)();
}

/*


@@ 466,12 443,10 @@ exit(int ispanic)
int
cpuspeed(int speed)
{
	switch(pmutype){
	case PMUnsx20:
		return pmucpuspeed(speed);
	default:
	if(arch->cpuspeed)
		return (*arch->cpuspeed)(speed);
	else
		return 0;
	}
}

/*


@@ 481,13 456,8 @@ cpuspeed(int speed)
void
buzz(int f, int d)
{
	switch(pmutype){
	case PMUnsx20:
		pmubuzz(f, d);
		break;
	default:
		break;
	}
	if(arch->buzz)
		(*arch->buzz)(f, d);
}

/*


@@ 496,13 466,8 @@ buzz(int f, int d)
void
lights(int val)
{
	switch(pmutype){
	case PMUnsx20:
		pmulights(val);
		break;
	default:
		break;
	}
	if(arch->lights)
		(*arch->lights)(val);
}

/*


@@ 513,12 478,10 @@ lights(int val)
int
serial(int onoff)
{
	switch(pmutype){
	case PMUnsx20:
		return pmuserial(onoff);
	default:
	if(arch->serialpower)
		return (*arch->serialpower)(onoff);
	else
		return 0;
	}
}

/*


@@ 529,10 492,8 @@ serial(int onoff)
int
modem(int onoff)
{
	switch(pmutype){
	case PMUnsx20:
		return pmumodem(onoff);
	default:
	if(arch->modempower)
		return (*arch->modempower)(onoff);
	else
		return 0;
	}
}

M port/sysproc.c => port/sysproc.c +1 -0
@@ 308,6 308,7 @@ sysexec(ulong *arg)
		nargs++;
	}
	ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1));

	/*
	 * 8-byte align SP for those (e.g. sparc) that need it.
	 * execregs() will subtract another 4 bytes for argc.

M power/mem.h => power/mem.h +1 -1
@@ 120,7 120,7 @@
#define	UTZERO		(UZERO+BY2PG)		/* first address in user text */
#define	USTKTOP		KZERO			/* byte just beyond user stack */
#define	TSTKTOP		(USERADDR+USTKSIZE)	/* top of temporary stack */
#define TSTKSIZ 	100
#define TSTKSIZ 	500
#define	KZERO		KSEG0			/* base of kernel address space */
#define	KTZERO		(KZERO+0x20000)		/* first address in kernel text */
#define	USTKSIZE	(4*1024*1024)		/* size of user stack */