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

1993/0401/pc/main.c (diff list | history)

pc/main.c on 1991/0702
1991/0702    
#include	"u.h" 
1992/0321    
#include	"../port/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" 
1992/0918    
#include	<ctype.h> 
1991/0629    
 
1992/0904    
 
1992/0903    
uchar *sp;	/* stack pointer for /boot */ 
 
1992/0923    
extern PCArch nsx20, generic, ncr3170; 
 
PCArch *arch; 
PCArch *knownarch[] = 
{ 
	&nsx20, 
	&ncr3170, 
	&generic, 
}; 
 
1993/0330    
/* where b.com leaves configuration info */ 
#define BOOTARGS	((char*)(KZERO|1024)) 
#define	BOOTARGSLEN	1024 
#define	MAXCONF		32 
 
char *confname[MAXCONF]; 
char *confval[MAXCONF]; 
int nconf; 
 
1991/0716    
void 
1991/0702    
main(void) 
1991/0625    
{ 
1991/1210    
	ident(); 
1992/0902    
	i8042a20();		/* enable address lines 20 and up */ 
1991/0711    
	machinit(); 
1991/1113    
	active.exiting = 0; 
	active.machs = 1; 
1991/0711    
	confinit(); 
1992/0625    
	xinit(); 
1991/0703    
	screeninit(); 
1991/0716    
	printinit(); 
1991/0711    
	mmuinit(); 
1992/0625    
	pageinit(); 
1991/0718    
	trapinit(); 
1991/0906    
	mathinit(); 
1991/0718    
	clockinit(); 
	faultinit(); 
1992/0409    
	kbdinit(); 
1991/0716    
	procinit0(); 
	initseg(); 
	chandevreset(); 
	streaminit(); 
	swapinit(); 
	userinit(); 
	schedinit(); 
1991/0712    
} 
1991/0706    
 
1992/0902    
/* 
1992/0903    
 *  This tries to capture architecture dependencies since things 
 *  like power management/reseting/mouse are outside the hardware 
 *  model. 
1992/0902    
 */ 
1991/0716    
void 
1991/1210    
ident(void) 
{ 
	char *id = (char*)(ROMBIOS + 0xFF40); 
1992/0923    
	PCArch **p; 
1991/1210    
 
1992/0923    
	for(p = knownarch; *p != &generic; p++) 
		if(strncmp((*p)->id, id, strlen((*p)->id)) == 0) 
1992/0918    
			break; 
1992/0923    
	arch = *p; 
1991/1210    
} 
 
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    
{ 
1993/0330    
	int i; 
1992/0918    
	char tstr[32]; 
 
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    
 
1992/0516    
	kproc("alarm", alarmkproc, 0); 
1991/0716    
	chandevinit(); 
 
1991/0926    
	if(!waserror()){ 
1993/0330    
		for(i = 0; i < nconf; i++) 
			ksetenv(confname[i], confval[i]); 
1992/0923    
		strcpy(tstr, arch->id); 
1992/0918    
		strcat(tstr, " %s"); 
		ksetterm(tstr); 
1991/0927    
		ksetenv("cputype", "386"); 
1991/0926    
		poperror(); 
	} 
1992/0323    
	touser(sp); 
1991/0712    
} 
 
1991/0629    
void 
1991/0716    
userinit(void) 
1991/0711    
{ 
1991/0716    
	Proc *p; 
	Segment *s; 
	User *up; 
	KMap *k; 
1992/0323    
	Page *pg; 
1991/0905    
 
1991/0716    
	p = newproc(); 
	p->pgrp = newpgrp(); 
1992/0625    
	p->egrp = smalloc(sizeof(Egrp)); 
	p->egrp->ref = 1; 
	p->fgrp = smalloc(sizeof(Fgrp)); 
	p->fgrp->ref = 1; 
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; 
1992/0323    
	pg = newpage(1, 0, USTKTOP-BY2PG); 
	segpage(s, pg); 
	k = kmap(pg); 
	bootargs(VA(k)); 
	kunmap(k); 
1991/0716    
 
	/* 
	 * 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); 
1992/0323    
} 
 
uchar * 
pusharg(char *p) 
{ 
	int n; 
 
	n = strlen(p)+1; 
	sp -= n; 
	memmove(sp, p, n); 
	return sp; 
} 
 
void 
bootargs(ulong base) 
{ 
 	int i, ac; 
	uchar *av[32]; 
	uchar **lsp; 
1992/0903    
	char *cp = BOOTLINE; 
	char buf[64]; 
1992/0323    
 
	sp = (uchar*)base + BY2PG - MAXSYSARG*BY2WD; 
 
	ac = 0; 
	av[ac++] = pusharg("/386/9safari"); 
	av[ac++] = pusharg("-p"); 
1992/0903    
	cp[64] = 0; 
	if(strncmp(cp, "fd!", 3) == 0){ 
		sprint(buf, "local!#f/fd%ddisk", atoi(cp+3)); 
		av[ac++] = pusharg(buf); 
	} else if(strncmp(cp, "hd!", 3) == 0){ 
1993/0114    
		sprint(buf, "local!#h/hd%ddisk", atoi(cp+3)); 
1992/0903    
		av[ac++] = pusharg(buf); 
	} 
1992/0323    
 
	/* 4 byte word align stack */ 
	sp = (uchar*)((ulong)sp & ~3); 
 
	/* build argc, argv on stack */ 
	sp -= (ac+1)*sizeof(sp); 
	lsp = (uchar**)sp; 
	for(i = 0; i < ac; i++) 
		*lsp++ = av[i] + ((USTKTOP - BY2PG) - base); 
	*lsp = 0; 
	sp += (USTKTOP - BY2PG) - base - sizeof(ulong); 
1991/0711    
} 
 
1991/0716    
Conf	conf; 
 
1991/0711    
void 
confinit(void) 
{ 
	long x, i, j, *l; 
1992/1002    
	int pcnt; 
1992/0715    
	ulong ktop; 
1993/0330    
	char *cp; 
	char *line[MAXCONF]; 
1991/0711    
 
	/* 
1991/0823    
	 *  the first 640k is the standard useful memory 
1992/1113    
	 *  the next 128K is the display, I/O mem, and BIOS 
1992/0429    
	 *  the last 256k belongs to the roms and other devices 
1991/0711    
	 */ 
1991/0823    
	conf.npage0 = 640/4; 
	conf.base0 = 0; 
 
	/* 
	 *  size the non-standard memory 
	 */ 
1991/0711    
	x = 0x12345678; 
1992/1019    
	for(i=2; i<17; i++){ 
1991/0711    
		/* 
		 *  write the word 
		 */ 
1992/0625    
		l = (long*)(KZERO|(i*MB)); 
1992/1019    
		l--; 
1991/0711    
		*l = x; 
		/* 
		 *  take care of wraps 
		 */ 
1992/1019    
		for(j = 1; j < i; j++){ 
1992/0625    
			l = (long*)(KZERO|(j*MB)); 
1992/1019    
			l--; 
			*l = ~x; 
1991/0711    
		} 
		/* 
		 *  check 
		 */ 
1992/0625    
		l = (long*)(KZERO|(i*MB)); 
1992/1019    
		l--; 
1991/0711    
		if(*l != x) 
			break; 
1993/0217    
		memset((char*)(KZERO|((i-1)*MB)), 0, MB); 
1991/0711    
		x += 0x3141526; 
	} 
1992/1019    
	i--; 
1992/0625    
	conf.base1 = 1*MB; 
1992/1016    
	conf.npage1 = (i*MB - conf.base1)/BY2PG; 
1991/0711    
	conf.npage = conf.npage0 + conf.npage1; 
1992/1002    
 
1992/1113    
	conf.ldepth = 0; 
	pcnt = (1<<conf.ldepth)-1;		/* Calculate % of memory for page pool */ 
1992/1014    
	pcnt = 70 - (pcnt*10); 
	conf.upages = (conf.npage*pcnt)/100; 
1992/1016    
 
	ktop = PGROUND((ulong)end); 
	ktop = PADDR(ktop); 
	conf.npage0 -= ktop/BY2PG; 
	conf.base0 += ktop; 
1991/0711    
 
1992/0625    
	conf.topofmem = i*MB; 
1993/0401    
	conf.nproc = 30 + i*5; 
	conf.monitor = 1; 
	conf.nswap = conf.nproc*80; 
	conf.nimage = 50; 
	conf.copymode = 0;			/* copy on write */ 
	conf.nfloppy = 2; 
	conf.nhard = 2; 
1993/0330    
 
	/* 
	 *  parse configuration args from dos file p9rc 
	 */ 
	cp = BOOTARGS;	/* where b.com leaves it's config */ 
	cp[BOOTARGSLEN-1] = 0; 
	i = getfields(cp, line, MAXCONF, '\n'); 
	for(j = 0; j < i; j++){ 
		cp = strchr(line[j], '\r'); 
		if(cp) 
			*cp = 0; 
		cp = strchr(line[j], '='); 
		if(cp == 0) 
			continue; 
		*cp++ = 0; 
		if(cp - line[j] >= NAMELEN+1) 
			*(line[j]+NAMELEN-1) = 0; 
		confname[nconf] = line[j]; 
		confval[nconf] = cp; 
		nconf++; 
	} 
1992/0625    
 
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); 
 
1992/0806    
	/* 
	 *  save floating point state to check out error 
	 */ 
	fpenv(&u->fpsave); 
	status = u->fpsave.status; 
 
	msg = 0; 
1991/0913    
	for(i = 0; i < 8; i++) 
		if((1<<i) & status){ 
			msg = mathmsg[i]; 
1992/0806    
			sprint(note, "sys: fp: %s fppc=0x%lux", msg, u->fpsave.pc); 
			postnote(u->p, 1, note, NDebug); 
1991/0913    
			break; 
		} 
1992/0806    
	if(msg == 0){ 
		sprint(note, "sys: fp: unknown fppc=0x%lux", u->fpsave.pc); 
		postnote(u->p, 1, note, NDebug); 
	} 
	if(ur->pc & KZERO) 
		panic("fp: status %lux fppc=0x%lux pc=0x%lux", status, 
			u->fpsave.pc, ur->pc); 
1991/0912    
} 
 
/* 
1991/0906    
 *  math coprocessor emulation fault 
 */ 
void 
mathemu(Ureg *ur) 
{ 
1992/0711    
	USED(ur); 
1991/0906    
	switch(u->p->fpstate){ 
	case FPinit: 
		fpinit(); 
		u->p->fpstate = FPactive; 
		break; 
	case FPinactive: 
		fprestore(&u->fpsave); 
		u->p->fpstate = FPactive; 
		break; 
	case FPactive: 
1992/0805    
		panic("math emu", 0); 
1991/0906    
		break; 
	} 
} 
 
/* 
 *  math coprocessor segment overrun 
 */ 
void 
mathover(Ureg *ur) 
{ 
1992/0711    
	USED(ur); 
1992/0805    
print("sys: fp: math overrun pc 0x%lux pid %d\n", ur->pc, u->p->pid); 
	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 
1992/0122    
procsave(Proc *p) 
1991/0705    
{ 
1992/0805    
	if(p->fpstate == FPactive){ 
		if(p->state == Moribund) 
			fpoff(); 
		else 
			fpsave(&u->fpsave); 
		p->fpstate = FPinactive; 
1991/0906    
	} 
1991/0712    
} 
 
/* 
1991/0716    
 *  Restore what procsave() saves 
1991/0712    
 */ 
1991/0716    
void 
1992/0122    
procrestore(Proc *p) 
1991/0712    
{ 
1992/0711    
	USED(p); 
1991/0712    
} 
 
 
1991/0906    
/* 
1991/1210    
 *  the following functions all are slightly different from 
 *  PC to PC. 
1991/0803    
 */ 
 
/* 
1991/1210    
 *  reset the i387 chip 
1991/0803    
 */ 
void 
1992/0812    
exit(int ispanic) 
1991/0803    
{ 
	u = 0; 
	print("exiting\n"); 
1992/0812    
	if(ispanic) 
		for(;;); 
1992/0903    
 
1992/0923    
	(*arch->reset)(); 
1991/0803    
} 
 
/* 
1991/1210    
 *  set cpu speed 
 *	0 == low speed 
 *	1 == high speed 
1991/0803    
 */ 
1991/1210    
int 
cpuspeed(int speed) 
1991/0803    
{ 
1992/0923    
	if(arch->cpuspeed) 
		return (*arch->cpuspeed)(speed); 
	else 
1991/1210    
		return 0; 
1991/0803    
} 
 
/* 
1991/1210    
 *  f == frequency (Hz) 
 *  d == duration (ms) 
1991/0803    
 */ 
1991/1210    
void 
buzz(int f, int d) 
1991/0803    
{ 
1992/0923    
	if(arch->buzz) 
		(*arch->buzz)(f, d); 
1991/0803    
} 
 
/* 
1991/1210    
 *  each bit in val stands for a light 
1991/0803    
 */ 
1991/1210    
void 
lights(int val) 
1991/0803    
{ 
1992/0923    
	if(arch->lights) 
		(*arch->lights)(val); 
1991/0803    
} 
 
/* 
1991/0913    
 *  power to serial port 
1991/1210    
 *	onoff == 1 means on 
 *	onoff == 0 means off 
1991/0803    
 */ 
int 
serial(int onoff) 
{ 
1992/0923    
	if(arch->serialpower) 
		return (*arch->serialpower)(onoff); 
	else 
1991/1210    
		return 0; 
1991/0803    
} 
 
1991/1001    
/* 
 *  power to modem 
1991/1210    
 *	onoff == 1 means on 
 *	onoff == 0 means off 
1991/1001    
 */ 
int 
modem(int onoff) 
{ 
1992/0923    
	if(arch->modempower) 
		return (*arch->modempower)(onoff); 
	else 
1991/1210    
		return 0; 
1991/0803    
} 


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