plan 9 kernel history: overview | file list | diff list

1991/1113/pc/main.c (diff list | history)

1991/1113/sys/src/9/pc/main.c:1,5131991/1210/sys/src/9/pc/main.c:1,474 (short | long | prev | next)
1991/0702    
#include	"u.h" 
#include	"lib.h" 
1991/0706    
#include	"mem.h" 
1991/0702    
#include	"dat.h" 
#include	"fns.h" 
1991/0706    
#include	"io.h" 
1991/0716    
#include	"ureg.h" 
#include	"init.h" 
1991/0629    
 
1991/0716    
extern long edata; 
1991/1210    
int machtype; 
1991/0711    
 
1991/0716    
void 
1991/0702    
main(void) 
1991/0625    
{ 
1991/1210    
	ident(); 
1991/0827    
	meminit(); 
1991/0711    
	machinit(); 
1991/1113    
	active.exiting = 0; 
	active.machs = 1; 
1991/0711    
	confinit(); 
1991/0703    
	screeninit(); 
1991/0716    
	printinit(); 
1991/0827    
	print("%ludK bytes of physical memory\n", (conf.base1 + conf.npage1*BY2PG)/1024); 
1991/0711    
	mmuinit(); 
1991/0718    
	trapinit(); 
1991/0906    
	mathinit(); 
1991/0719    
	kbdinit(); 
1991/0718    
	clockinit(); 
	faultinit(); 
1991/0716    
	procinit0(); 
	initseg(); 
	grpinit(); 
	chaninit(); 
1991/0711    
	alarminit(); 
1991/1113    
	bigcursor(); 
1991/0716    
	chandevreset(); 
	streaminit(); 
	swapinit(); 
	pageinit(); 
	userinit(); 
1991/0711    
 
1991/0716    
	schedinit(); 
1991/0712    
} 
1991/0706    
 
1991/0716    
void 
1991/1210    
ident(void) 
{ 
	char *id = (char*)(ROMBIOS + 0xFF40); 
 
	/* check for a safari (tres special) */ 
	if(strncmp(id, "AT&TNSX", 7) == 0) 
		machtype = Attnsx; 
	else 
		machtype = At; 
} 
 
void 
1991/0716    
machinit(void) 
1991/0712    
{ 
1991/0716    
	int n; 
1991/0712    
 
1991/0716    
	n = m->machno; 
	memset(m, 0, sizeof(Mach)); 
	m->machno = n; 
	m->mmask = 1<<m->machno; 
1991/0625    
} 
 
1991/0719    
ulong garbage; 
1991/0718    
 
1991/0716    
void 
init0(void) 
1991/0712    
{ 
1991/0716    
	Chan *c; 
1991/0712    
 
1991/0716    
	u->nerrlab = 0; 
	m->proc = u->p; 
	u->p->state = Running; 
	u->p->mach = m; 
1991/0712    
 
1991/0720    
	spllo(); 
 
1991/0716    
	/* 
	 * These are o.k. because rootinit is null. 
	 * Then early kproc's will have a root and dot. 
	 */ 
	u->slash = (*devtab[0].attach)(0); 
	u->dot = clone(u->slash, 0); 
1991/0712    
 
1991/0716    
	chandevinit(); 
 
1991/0926    
	if(!waserror()){ 
1991/1102    
		ksetterm("at&t %s"); 
1991/0927    
		ksetenv("cputype", "386"); 
1991/0926    
		poperror(); 
	} 
1991/0716    
	touser(); 
1991/0712    
} 
 
1991/0629    
void 
1991/0716    
userinit(void) 
1991/0711    
{ 
1991/0716    
	Proc *p; 
	Segment *s; 
	User *up; 
	KMap *k; 
1991/0905    
 
1991/0716    
	p = newproc(); 
	p->pgrp = newpgrp(); 
	p->egrp = newegrp(); 
	p->fgrp = newfgrp(); 
1991/1112    
	p->procmode = 0640; 
1991/0716    
 
	strcpy(p->text, "*init*"); 
1991/1109    
	strcpy(p->user, eve); 
1991/0716    
	p->fpstate = FPinit; 
1991/0906    
	fpoff(); 
1991/0716    
 
	/* 
	 * Kernel Stack 
1991/0717    
	 * 
1991/0719    
	 * N.B. The -12 for the stack pointer is important. 
	 *	4 bytes for gotolabel's return PC 
1991/0716    
	 */ 
	p->sched.pc = (ulong)init0; 
1991/0720    
	p->sched.sp = USERADDR + BY2PG - 4; 
1991/0716    
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); 
 
	/* 
	 * User 
	 */ 
	k = kmap(p->upage); 
	up = (User*)VA(k); 
	up->p = p; 
	kunmap(k); 
 
	/* 
	 * User Stack 
	 */ 
	s = newseg(SG_STACK, USTKTOP-BY2PG, 1); 
	p->seg[SSEG] = s; 
 
	/* 
	 * Text 
	 */ 
	s = newseg(SG_TEXT, UTZERO, 1); 
	p->seg[TSEG] = s; 
	segpage(s, newpage(1, 0, UTZERO)); 
	k = kmap(s->map[0]->pages[0]); 
	memmove((ulong*)VA(k), initcode, sizeof initcode); 
	kunmap(k); 
 
	ready(p); 
1991/0711    
} 
 
1991/0716    
Conf	conf; 
 
1991/0711    
void 
confinit(void) 
{ 
	long x, i, j, *l; 
	int mul; 
 
	/* 
1991/0823    
	 *  the first 640k is the standard useful memory 
	 *  the next 128K is the display 
	 *  the last 256k belongs to the roms 
1991/0711    
	 */ 
1991/0823    
	conf.npage0 = 640/4; 
	conf.base0 = 0; 
 
	/* 
	 *  size the non-standard memory 
	 */ 
1991/0711    
	x = 0x12345678; 
	for(i=1; i<16; i++){ 
		/* 
		 *  write the word 
		 */ 
		l = (long*)(KZERO|(i*1024L*1024L)); 
		*l = x; 
		/* 
		 *  take care of wraps 
		 */ 
		for(j = 0; j < i; j++){ 
			l = (long*)(KZERO|(j*1024L*1024L)); 
			*l = 0; 
		} 
		/* 
		 *  check 
		 */ 
		l = (long*)(KZERO|(i*1024L*1024L)); 
		if(*l != x) 
			break; 
		x += 0x3141526; 
	} 
1991/0827    
	conf.base1 = 0x100000; 
	conf.npage1 = ((i-1)*1024*1024 - conf.base1)/BY2PG; 
1991/0711    
 
	conf.npage = conf.npage0 + conf.npage1; 
1991/0801    
	conf.maxialloc = 2*1024*1024; 
1991/0711    
 
	mul = 1; 
1991/0829    
	conf.nproc = 30 + 20*mul; 
1991/0711    
	conf.npgrp = conf.nproc/2; 
	conf.nseg = conf.nproc*3; 
	conf.npagetab = (conf.nseg*14)/10; 
	conf.nswap = conf.nproc*80; 
	conf.nimage = 50; 
	conf.nalarm = 1000; 
1991/0828    
	conf.nchan = 6*conf.nproc; 
1991/0711    
	conf.nenv = 4*conf.nproc; 
	conf.nenvchar = 8000*mul; 
	conf.npgenv = 200*mul; 
	conf.nmtab = 50*mul; 
	conf.nmount = 80*mul; 
	conf.nmntdev = 15*mul; 
	conf.nmntbuf = conf.nmntdev+3; 
	conf.nmnthdr = 2*conf.nmntdev; 
	conf.nsrv = 16*mul;			/* was 32 */ 
1991/0828    
	conf.nbitmap = 512*mul; 
1991/0711    
	conf.nbitbyte = conf.nbitmap*1024*screenbits(); 
	conf.nfont = 10*mul; 
	conf.nnoifc = 1; 
	conf.nnoconv = 32; 
	conf.nurp = 32; 
	conf.nasync = 1; 
	conf.nstream = (conf.nproc*3)/2; 
	conf.nqueue = 5 * conf.nstream; 
	conf.nblock = 24 * conf.nstream; 
	conf.npipe = conf.nstream/2; 
	conf.copymode = 0;			/* copy on write */ 
	conf.ipif = 8; 
	conf.ip = 64; 
	conf.arp = 32; 
	conf.frag = 32; 
	conf.cntrlp = 0; 
1991/0809    
	conf.nfloppy = 1; 
	conf.nhard = 1; 
1991/1107    
	conf.dkif = 1; 
1991/0711    
} 
 
1991/0913    
char *mathmsg[] = 
1991/0906    
{ 
1991/0913    
	"invalid", 
	"denormalized", 
	"div-by-zero", 
	"overflow", 
	"underflow", 
	"precision", 
	"stack", 
	"error", 
}; 
1991/0906    
 
/* 
1991/0912    
 *  math coprocessor error 
 */ 
void 
1991/0913    
matherror(Ureg *ur) 
1991/0912    
{ 
1991/0913    
	ulong status; 
	int i; 
	char *msg; 
	char note[ERRLEN]; 
 
	/* 
	 *  a write cycle to port 0xF0 clears the interrupt latch attached 
	 *  to the error# line from the 387 
	 */ 
	outb(0xF0, 0xFF); 
 
	status = fpstatus() & 0xffff; 
	msg = "unknown"; 
	for(i = 0; i < 8; i++) 
		if((1<<i) & status){ 
			msg = mathmsg[i]; 
			break; 
		} 
	sprint(note, "math: %s, status 0x%ux, pc 0x%lux", msg, status, ur->pc); 
	postnote(u->p, 1, note, NDebug); 
1991/0912    
} 
 
/* 
1991/0906    
 *  math coprocessor emulation fault 
 */ 
void 
mathemu(Ureg *ur) 
{ 
	switch(u->p->fpstate){ 
	case FPinit: 
		fpinit(); 
		u->p->fpstate = FPactive; 
		break; 
	case FPinactive: 
		fprestore(&u->fpsave); 
		u->p->fpstate = FPactive; 
		break; 
	case FPactive: 
1991/0907    
		pexit("Math emu", 0); 
1991/0906    
		break; 
	} 
} 
 
/* 
 *  math coprocessor segment overrun 
 */ 
void 
mathover(Ureg *ur) 
{ 
1991/0907    
	pexit("Math overrun", 0); 
1991/0906    
} 
 
void 
mathinit(void) 
{ 
1991/0913    
	setvec(Matherr1vec, matherror); 
	setvec(Matherr2vec, matherror); 
1991/0906    
	setvec(Mathemuvec, mathemu); 
	setvec(Mathovervec, mathover); 
} 
 
/* 
1991/0716    
 *  set up floating point for a new process 
 */ 
1991/0703    
void 
1991/0716    
procsetup(Proc *p) 
1991/0703    
{ 
1991/0716    
	p->fpstate = FPinit; 
1991/0906    
	fpoff(); 
1991/0705    
} 
 
1991/0712    
/* 
1991/0906    
 *  Save the mach dependent part of the process state. 
1991/0712    
 */ 
1991/0705    
void 
1991/0716    
procsave(uchar *state, int len) 
1991/0705    
{ 
1991/0906    
	if(u->p->fpstate == FPactive){ 
		fpsave(&u->fpsave); 
		u->p->fpstate = FPinactive; 
	} 
1991/0712    
} 
 
/* 
1991/0716    
 *  Restore what procsave() saves 
1991/0712    
 */ 
1991/0716    
void 
procrestore(Proc *p, uchar *state) 
1991/0712    
{ 
} 
 
1991/0716    
void 
firmware(void) 
1991/0712    
{ 
1991/0716    
	panic("firmware"); 
1991/0712    
} 
 
1991/0906    
/* 
1991/0803    
 *  special stuff for 80c51 power management and headland system controller 
1991/1210    
 *  the following functions all are slightly different from 
 *  PC to PC. 
1991/0803    
 */ 
enum 
{ 
	/* 
	 *  system control port 
	 */ 
	Head=		0x92,		/* control port */ 
	 Reset=		(1<<0),		/* reset the 386 */ 
	 A20ena=	(1<<1),		/* enable address line 20 */ 
 
	/* 
	 *  power management unit ports 
	 */ 
	Pmudata=	0x198, 
                 
	Pmucsr=		0x199, 
1991/0806    
	 Busy=		0x1, 
                 
	/* 
	 *  configuration port 
	 */ 
	Pconfig=	0x3F3, 
1991/0803    
}; 
                 
/* 
 *  enable address bit 20 
 */ 
1991/1210    
/* enable address bit 20 (extended memory) */ 
1991/0803    
void 
1991/0827    
meminit(void) 
1991/0803    
{ 
1991/0827    
	outb(Head, A20ena);		/* enable memory address bit 20 */ 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		heada20();		/* via headland chip */ 
		break; 
	case At: 
		i8042a20();		/* via keyboard controller */ 
		break; 
	} 
1991/0803    
} 
 
/* 
 *  reset the chip 
1991/1210    
 *  reset the i387 chip 
1991/0803    
 */ 
void 
exit(void) 
{ 
	int i; 
 
	u = 0; 
	print("exiting\n"); 
	outb(Head, Reset); 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		headreset();		/* via headland chip */ 
		break; 
	case At: 
		i8042reset();			/* via keyboard controller */ 
		break; 
	} 
1991/0803    
} 
 
/* 
 *  return when pmu ready 
1991/1210    
 *  set cpu speed 
 *	0 == low speed 
 *	1 == high speed 
1991/0803    
 */ 
static int 
pmuready(void) 
1991/1210    
int 
cpuspeed(int speed) 
1991/0803    
{ 
	int tries; 
                 
	for(tries = 0; (inb(Pmucsr) & Busy); tries++) 
		if(tries > 1000) 
			return -1; 
	return 0; 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		return pmucpuspeed(speed); 
	default: 
		return 0; 
	} 
1991/0803    
} 
 
/* 
 *  return when pmu busy 
1991/1210    
 *  f == frequency (Hz) 
 *  d == duration (ms) 
1991/0803    
 */ 
static int 
pmubusy(void) 
1991/1210    
void 
buzz(int f, int d) 
1991/0803    
{ 
	int tries; 
                 
	for(tries = 0; !(inb(Pmucsr) & Busy); tries++) 
		if(tries > 1000) 
			return -1; 
	return 0; 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		pmubuzz(f, d); 
		break; 
	default: 
		break; 
	} 
1991/0803    
} 
 
/* 
 *  set a bit in the PMU 
1991/1210    
 *  each bit in val stands for a light 
1991/0803    
 */ 
1991/0809    
Lock pmulock; 
1991/0803    
int 
pmuwrbit(int index, int bit, int pos) 
1991/1210    
void 
lights(int val) 
1991/0803    
{ 
1991/0809    
	lock(&pmulock); 
1991/0803    
	outb(Pmucsr, 0x02);		/* next is command request */ 
1991/0809    
	if(pmuready() < 0){ 
		unlock(&pmulock); 
1991/0803    
		return -1; 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		pmulights(val); 
		break; 
	default: 
		break; 
1991/0809    
	} 
1991/0803    
	outb(Pmudata, (2<<4) | index);	/* send write bit command */ 
	outb(Pmucsr, 0x01);		/* send available */ 
1991/0809    
	if(pmubusy() < 0){ 
		unlock(&pmulock); 
1991/0803    
		return -1; 
1991/0809    
	} 
1991/0803    
	outb(Pmucsr, 0x01);		/* next is data */ 
1991/0809    
	if(pmuready() < 0){ 
		unlock(&pmulock); 
1991/0803    
		return -1; 
1991/0809    
	} 
1991/0803    
	outb(Pmudata, (bit<<3) | pos);	/* send bit to write */ 
	outb(Pmucsr, 0x01);		/* send available */ 
1991/0809    
	if(pmubusy() < 0){ 
		unlock(&pmulock); 
1991/0803    
		return -1; 
1991/0809    
	} 
	unlock(&pmulock); 
1991/0810    
	return 0; 
1991/0803    
} 
 
/* 
1991/0913    
 *  power to serial port 
 *	onoff == 0 means on 
1991/0803    
 *	onoff == 1 means off 
1991/1210    
 *	onoff == 1 means on 
 *	onoff == 0 means off 
1991/0803    
 */ 
int 
serial(int onoff) 
{ 
	return pmuwrbit(1, onoff, 6); 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		return pmuserial(onoff); 
	default: 
		return 0; 
	} 
1991/0803    
} 
 
1991/1001    
/* 
 *  power to modem 
 *	onoff == 0 means on 
 *	onoff == 1 means off 
1991/1210    
 *	onoff == 1 means on 
 *	onoff == 0 means off 
1991/1001    
 */ 
int 
modem(int onoff) 
{ 
	if(pmuwrbit(1, onoff, 0)<0) 
		return -1; 
	return pmuwrbit(1, 1^onoff, 5); 
} 
                 
1991/1029    
/* 
 *  CPU speed 
 *	onoff == 0 means 2 MHZ 
 *	onoff == 1 means 20 MHZ 
 */ 
int 
cpuspeed(int speed) 
{ 
	return pmuwrbit(0, speed, 0); 
} 
                 
1991/0913    
void 
buzz(int f, int d) 
1991/0803    
{ 
1991/0913    
	static Rendez br; 
	static QLock bl; 
                 
	qlock(&bl); 
	pmuwrbit(0, 0, 6); 
	tsleep(&br, return0, 0, d); 
	pmuwrbit(0, 1, 6); 
	qunlock(&bl); 
1991/0803    
} 
                 
1991/0913    
void 
lights(int val) 
1991/0803    
{ 
1991/0913    
	pmuwrbit(0, (val&1), 4);		/* owl */ 
	pmuwrbit(0, ((val>>1)&1), 1);		/* mail */ 
1991/1113    
} 
                 
void 
owl(int val) 
{ 
	pmuwrbit(0, (val&1), 4);		/* owl */ 
1991/1210    
	switch(machtype){ 
	case Attnsx: 
		return pmumodem(onoff); 
	default: 
		return 0; 
	} 
1991/0803    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)