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

1993/1005/carrera/main.c (diff list | history)

carrera/main.c on 1993/0903
1993/0903    
#include	"u.h" 
#include	"../port/lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
#include	"init.h" 
 
/* 
 *  args passed by boot process 
 */ 
int _argc; char **_argv; char **_env; 
 
/* 
 *  arguments passed to initcode and /boot 
 */ 
char argbuf[128]; 
 
/* 
 *  environment passed to boot -- sysname, consname, diskid 
 */ 
char consname[NAMELEN]; 
char bootdisk[NAMELEN]; 
char screenldepth[NAMELEN]; 
 
/* 
 * software tlb simulation 
 */ 
Softtlb stlb[MAXMACH][STLBSIZE]; 
 
Conf	conf; 
FPsave	initfp; 
 
void 
main(void) 
{ 
	tlbinit();		/* Very early to establish IO mappings */ 
1993/0918    
	ioinit(1); 
1993/0903    
	arginit(); 
	confinit(); 
	savefpregs(&initfp); 
	machinit(); 
	kmapinit(); 
	xinit(); 
1993/0905    
	iomapinit(); 
1993/0903    
	printinit(); 
1993/0905    
	serialinit(); 
1993/0903    
	vecinit(); 
1993/0918    
	screeninit(); 
	print("\n\nBrazil\n"); 
1993/0903    
	pageinit(); 
	procinit0(); 
	initseg(); 
1993/0915    
	links(); 
1993/0903    
	chandevreset(); 
	swapinit(); 
	userinit(); 
	schedinit(); 
} 
 
/* 
 *  copy arguments passed by the boot kernel (or ROM) into a temporary buffer. 
 *  we do this because the arguments are in memory that may be allocated 
 *  to processes or kernel buffers. 
 * 
 *  also grab any environment variables that might be useful 
 */ 
struct 
{ 
	char	*name; 
	char	*val; 
1993/0904    
}bootenv[] = 
{ 
1993/0903    
	{"netaddr=",	sysname}, 
	{"console=",	consname}, 
	{"bootdisk=",	bootdisk}, 
	{"ldepth=",	screenldepth}, 
}; 
char *sp; 
 
char * 
pusharg(char *p) 
{ 
	int n; 
 
	n = strlen(p)+1; 
	sp -= n; 
	memmove(sp, p, n); 
	return sp; 
} 
 
void 
arginit(void) 
{ 
	int i, n; 
	char **av; 
 
	/* 
	 *  get boot env variables 
	 */ 
	if(*sysname == 0) 
		for(av = _env; *av; av++) 
			for(i=0; i < sizeof bootenv/sizeof bootenv[0]; i++){ 
				n = strlen(bootenv[i].name); 
				if(strncmp(*av, bootenv[i].name, n) == 0){ 
					strncpy(bootenv[i].val, (*av)+n, NAMELEN); 
					bootenv[i].val[NAMELEN-1] = '\0'; 
					break; 
				} 
			} 
 
	/* 
	 *  pack args into buffer 
	 */ 
	av = (char**)argbuf; 
	sp = argbuf + sizeof(argbuf); 
	for(i = 0; i < _argc; i++){ 
		if(strchr(_argv[i], '=')) 
			break; 
		av[i] = pusharg(_argv[i]); 
	} 
	av[i] = 0; 
} 
 
/* 
 *  initialize a processor's mach structure.  each processor does this 
 *  for itself. 
 */ 
void 
machinit(void) 
{ 
	int n; 
 
	/* Ensure CU1 is off */ 
	clrfpintr(); 
 
	/* scrub cache */ 
	cleancache(); 
 
	n = m->machno; 
	m->stb = &stlb[n][0]; 
1993/0904    
 
1993/0905    
	m->speed = 50; 
1993/0903    
	clockinit(); 
1993/0905    
 
	active.exiting = 0; 
	active.machs = 1; 
1993/0903    
} 
 
/* 
1993/0905    
 * Set up a console on serial port 2 
 */ 
void 
serialinit(void) 
{ 
	NS16552setup(Uart1, UartFREQ); 
	NS16552special(0, 9600, &kbdq, &printq, kbdcr2nl); 
1993/0907    
 
	kbdinit(); 
1993/0905    
} 
 
/* 
1993/0903    
 * Map IO address space in wired down TLB entry 1 
 */ 
void 
1993/0918    
ioinit(int mapeisa) 
1993/0903    
{ 
1993/0907    
	ulong devphys, isaphys, intphys, isamphys; 
1993/0903    
 
1993/0904    
	/* 
1993/0918    
	 * If you want to segattach the eisa space these 
	 * mappings must be turned off to prevent duplication 
	 * of the tlb entries 
	 */ 
	if(mapeisa) { 
		isaphys = IOPTE|PPN(Eisaphys)|PTEGLOBL; 
		isamphys = 0x04000000|IOPTE|PTEGLOBL; 
	} 
	else { 
		isaphys = PTEGLOBL; 
		isamphys = PTEGLOBL; 
	} 
 
	/* 
1993/0906    
	 * Map devices and the Eisa control space 
1993/0904    
	 */ 
1993/0908    
	devphys = IOPTE|PPN(Devicephys); 
1993/0903    
 
1993/0906    
	puttlbx(1, Devicevirt, devphys, isaphys, PGSZ64K); 
 
1993/0904    
	/* 
1993/0907    
	 * Map Interrupt control & Eisa memory 
1993/0904    
	 */ 
1993/0908    
	intphys  = IOPTE|PPN(Intctlphys); 
1993/0904    
 
1993/0907    
	puttlbx(2, Intctlvirt, intphys, isamphys, PGSZ1M); 
 
1993/0905    
	/* Enable all devce interrupt */ 
	IO(ushort, Intenareg) = 0xffff; 
1993/0908    
 
	/* Look at the first 16M of Eisa memory */ 
/*	IO(uchar, EisaLatch) = 0; /**/ 
1993/0903    
} 
 
1993/0906    
/* 
 * Pull the ethernet address out of NVRAM 
 */ 
1993/0905    
void 
enetaddr(uchar *ea) 
{ 
1993/0906    
	int i; 
	uchar tbuf[8]; 
1993/0905    
 
1993/0906    
	for(i = 0; i < 8; i++) 
		tbuf[i] = ((uchar*)(NvramRO+Enetoffset))[i]; 
 
	print("ether:"); 
	for(i = 0; i < 6; i++) { 
		ea[i] = tbuf[7-i]; 
		print("%2.2ux", ea[i]); 
	} 
	print("\n"); 
1993/0905    
} 
 
1993/0903    
/* 
1993/0905    
 * All DMA and ether IO buffers must reside in the first 16M bytes of 
 * memory to be covered by the translation registers 
 */ 
void 
iomapinit(void) 
{ 
	int i; 
	Tte *t; 
 
	t = xspanalloc(Ntranslation*sizeof(Tte), BY2PG, 0); 
 
	for(i = 0; i < Ntranslation; i++) 
		t[i].lo = i<<PGSHIFT; 
 
	/* Set the translation table */ 
	IO(ulong, Ttbr) = PADDR(t); 
	IO(ulong, Tlrb) = (Ntranslation-1)*sizeof(Tte); 
 
	/* Invalidate the old entries */ 
	IO(ulong, Tir) = 0; 
} 
 
/* 
1993/0903    
 *  setup MIPS trap vectors 
 */ 
void 
vecinit(void) 
{ 
	memmove((ulong*)UTLBMISS, (ulong*)vector0, 0x100); 
	memmove((ulong*)CACHETRAP, (ulong*)vector100, 0x80); 
	memmove((ulong*)EXCEPTION, (ulong*)vector180, 0x80); 
1993/0904    
 
	icflush((ulong*)UTLBMISS, 8*1024); 
1993/0903    
} 
 
void 
init0(void) 
{ 
	char buf[2*NAMELEN]; 
 
	spllo(); 
 
	/* 
	 * These are o.k. because rootinit is null. 
	 * Then early kproc's will have a root and dot. 
	 */ 
	up->slash = namec("#/", Atodir, 0, 0); 
	up->dot = clone(up->slash, 0); 
 
	iallocinit(); 
	chandevinit(); 
 
	if(!waserror()){ 
		ksetenv("cputype", "mips"); 
1993/1005    
		sprint(buf, "carrera %s R4400PC", conffile); 
1993/0903    
		ksetenv("terminal", buf); 
		ksetenv("sysname", sysname); 
		poperror(); 
	} 
 
	kproc("alarm", alarmkproc, 0); 
	touser((uchar*)(USTKTOP-sizeof(argbuf))); 
} 
 
void 
userinit(void) 
{ 
	Proc *p; 
	KMap *k; 
	Page *pg; 
	char **av; 
	Segment *s; 
 
	p = newproc(); 
	p->pgrp = newpgrp(); 
	p->egrp = smalloc(sizeof(Egrp)); 
	p->egrp->ref = 1; 
	p->fgrp = smalloc(sizeof(Fgrp)); 
	p->fgrp->ref = 1; 
	p->procmode = 0640; 
 
	strcpy(p->text, "*init*"); 
	strcpy(p->user, eve); 
 
	p->fpstate = FPinit; 
	p->fpsave.fpstatus = initfp.fpstatus; 
 
	/* 
	 * Kernel Stack 
	 */ 
	p->sched.pc = (ulong)init0; 
	p->sched.sp = (ulong)p->kstack+KSTACK-(1+MAXSYSARG)*BY2WD; 
	/* 
	 * User Stack, pass input arguments to boot process 
	 */ 
	s = newseg(SG_STACK, USTKTOP-USTKSIZE, USTKSIZE/BY2PG); 
	p->seg[SSEG] = s; 
	pg = newpage(1, 0, USTKTOP-BY2PG); 
	segpage(s, pg); 
	k = kmap(pg); 
	for(av = (char**)argbuf; *av; av++) 
		*av += (USTKTOP - sizeof(argbuf)) - (ulong)argbuf; 
 
	memmove((uchar*)VA(k) + BY2PG - sizeof(argbuf), argbuf, sizeof argbuf); 
	kunmap(k); 
 
	/* Text */ 
	s = newseg(SG_TEXT, UTZERO, 1); 
	s->flushme++; 
	p->seg[TSEG] = s; 
	pg = newpage(1, 0, UTZERO); 
	memset(pg->cachectl, PG_TXTFLUSH, sizeof(pg->cachectl)); 
	segpage(s, pg); 
	k = kmap(s->map[0]->pages[0]); 
	memmove((ulong*)VA(k), initcode, sizeof initcode); 
	kunmap(k); 
 
	ready(p); 
} 
 
void 
exit(long type) 
{ 
1993/0905    
	USED(type); 
1993/0903    
 
	spllo(); 
1993/0905    
	print("cpu %d exiting\n", m->machno); 
1993/0904    
	while(consactive()) 
1993/0903    
		delay(10); 
	splhi(); 
	for(;;) 
		; 
} 
 
void 
confinit(void) 
{ 
	ulong ktop, top; 
 
	ktop = PGROUND((ulong)end); 
	ktop = PADDR(ktop); 
	top = (16*1024*1024)/BY2PG; 
 
	conf.base0 = 0; 
	conf.npage0 = top; 
	conf.npage = conf.npage0; 
	conf.npage0 -= ktop/BY2PG; 
	conf.base0 += ktop; 
	conf.npage1 = 0; 
	conf.base1 = 0; 
 
1993/0918    
	conf.upages = (conf.npage*50)/100; 
1993/0903    
 
	conf.nmach = 1; 
 
	/* set up other configuration parameters */ 
	conf.nproc = 100; 
1993/0904    
	conf.nswap = conf.npage*3; 
1993/0903    
	conf.nimage = 200; 
	conf.ipif = 8; 
	conf.ip = 64; 
	conf.arp = 32; 
	conf.frag = 32; 
 
1993/0918    
	conf.monitor = 1; 
1993/0906    
 
1993/0905    
	conf.copymode = 0;		/* copy on write */ 
1993/0903    
} 
 
 
/* 
 *  for the sake of devcons 
 */ 
 
void 
buzz(int f, int d) 
{ 
	USED(f); 
	USED(d); 
} 


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