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

1990/0227/power/main.c (diff list | history)

power/main.c on 1990/0227
1990/0227    
#include	"u.h" 
#include	"lib.h" 
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
#include	"io.h" 
#include	"ureg.h" 
#include	"init.h" 
 
void 
main(void) 
{ 
	active.exiting = 0; 
	active.machs = 1; 
	machinit(); 
	confinit(); 
	lockinit(); 
	printinit(); 
	tlbinit(); 
	vecinit(); 
	procinit0(); 
	pgrpinit(); 
	chaninit(); 
	clockinit(); 
	alarminit(); 
	io2init(); 
	chandevreset(); 
	streaminit(); 
	pageinit(); 
	userinit(); 
	launchinit(); 
	schedinit(); 
} 
 
void 
machinit(void) 
{ 
	int n; 
 
	n = m->machno; 
	memset(m, 0, sizeof(Mach)); 
	m->machno = n; 
	m->mmask = 1<<m->machno; 
} 
 
void 
tlbinit(void) 
{ 
	int i; 
 
	for(i=0; i<NTLB; i++) 
		puttlbx(i, KZERO | PTEPID(i), 0); 
} 
 
void 
vecinit(void) 
{ 
	ulong *p, *q; 
	int size; 
 
	p = (ulong*)EXCEPTION; 
	q = (ulong*)vector80; 
	for(size=0; size<4; size++) 
		*p++ = *q++; 
	p = (ulong*)UTLBMISS; 
	q = (ulong*)vector80; 
	for(size=0; size<4; size++) 
		*p++ = *q++; 
} 
 
/* 
 *  We have to program both the IO2 board to generate interrupts 
 *  and the SBCC on CPU 0 to accept them. 
 */ 
void 
io2init(void) 
{ 
	long i; 
 
	/* 
	 *  reset VME bus (MODEREG is on the IO2) 
	 */ 
	MODEREG->resetforce = (1<<1); 
	for(i=0; i<1000000; i++) 
		; 
	MODEREG->resetforce = 0; 
	MODEREG->masterslave = (SLAVE<<4) | MASTER; 
 
	/* 
	 *  all VME interrupts to the error routine 
	 */ 
	for(i=0; i<256; i++) 
		setvmevec(i, novme); 
 
	/* 
	 *  tell IO2 to sent all interrupts to CPU 0's SBCC 
	 */ 
	for(i=0; i<8; i++) 
		INTVECREG->i[i].vec = 0<<8; 
 
	/* 
	 *  Tell CPU 0's SBCC to map all interrupts from the IO2 to MIPS level 5 
	 * 
	 *  Since there are 6 MIPS hardware interrupts and the SBCC can generate 
	 *  only 5, one hardware interrupt can't be generated by the SBCC.  SBCC 
	 *  interrupt 4 maps to MIPS interrupt 5, SBCC interrupt 0 maps to MIPS 
	 *  interrupt 0.  I don't know which interrupt is missing. -- presotto 
	 */ 
	SBCCREG->flevel = 0x10; 
 
	/* 
	 *  Tell CPU 0's SBCC to enable all interrupts from the IO2. 
	 * 
	 *  The SBCC 16 bit registers are read/written as ulong, but only 
	 *  bits 23-16 and 7-0 are meaningful. 
	 */ 
	SBCCREG->fintenable |= 0xff;	  /* allow all interrupts on the IO2 */ 
	SBCCREG->idintenable |= 0x800000; /* allow interrupts from the IO2 */ 
 
	/* 
	 *  enable all interrupts on the IO2 
	 */ 
	*IO2SETMASK = 0xff; 
} 
 
void 
launchinit(void) 
{ 
	int i; 
 
	for(i=1; i<conf.nmach; i++) 
		launch(i); 
	for(i=0; i<1000000; i++) 
		if(active.machs == (1<<conf.nmach) - 1){ 
			print("all launched\n"); 
			return; 
		} 
	print("launch: active = %x\n", active.machs); 
} 
 
 
void 
init0(void) 
{ 
	m->proc = u->p; 
	u->p->state = Running; 
	u->p->mach = m; 
	spllo(); 
	chandevinit(); 
	 
	u->slash = (*devtab[0].attach)(0); 
	u->dot = clone(u->slash, 0); 
 
	touser(); 
} 
 
FPsave	initfp; 
 
void 
userinit(void) 
{ 
	Proc *p; 
	Seg *s; 
	User *up; 
 
	p = newproc(); 
	p->pgrp = newpgrp(); 
	strcpy(p->text, "*init*"); 
	strcpy(p->pgrp->user, "bootes"); 
	savefpregs(&initfp); 
	p->fpstate = FPinit; 
 
	/* 
	 * Kernel Stack 
	 */ 
	p->sched.pc = (ulong)init0; 
	p->sched.sp = USERADDR+BY2PG-20; 
	p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF)); 
 
	/* 
	 * User 
	 */ 
	up = (User*)(p->upage->pa|KZERO); 
	up->p = p; 
 
	/* 
	 * User Stack 
	 */ 
	s = &p->seg[SSEG]; 
	s->proc = p; 
	s->o = neworig(USTKTOP-BY2PG, 1, OWRPERM, 0); 
	s->minva = USTKTOP-BY2PG; 
	s->maxva = USTKTOP; 
 
	/* 
	 * Text 
	 */ 
	s = &p->seg[TSEG]; 
	s->proc = p; 
	s->o = neworig(UTZERO, 1, 0, 0); 
	s->o->pte[0].page = newpage(0, 0, UTZERO); 
	memcpy((ulong*)(s->o->pte[0].page->pa|KZERO), initcode, sizeof initcode); 
	s->minva = 0x1000; 
	s->maxva = 0x2000; 
 
	ready(p); 
} 
 
void 
lights(int v) 
{ 
 
	*LED = ~v; 
} 
 
typedef struct Beef	Beef; 
struct	Beef 
{ 
	long	deadbeef; 
	long	sum; 
	long	cpuid; 
	long	virid; 
	long	erno; 
	void	(*launch)(void); 
	void	(*rend)(void); 
	long	junk1[4]; 
	long	isize; 
	long	dsize; 
	long	nonbss; 
	long	junk2[18]; 
}; 
 
void 
launch(int n) 
{ 
	Beef *p; 
	long i; 
 
	p = (Beef*) 0xb0000500 + n; 
	p->launch = newstart; 
	p->sum -= (long)newstart; 
	for(i=0; i<3000000; i++) 
		if(p->launch == 0) 
			break; 
} 
 
void 
online(void) 
{ 
 
	machinit(); 
	lock(&active); 
	active.machs |= 1<<m->machno; 
	unlock(&active); 
	tlbinit(); 
	clockinit(); 
	schedinit(); 
} 
 
void 
exit(void) 
{ 
	int i; 
 
	u = 0; 
	lock(&active); 
	active.machs &= ~(1<<m->machno); 
	active.exiting = 1; 
	unlock(&active); 
	spllo(); 
	print("cpu %d exiting\n", m->machno); 
	while(active.machs || consactive()) 
		for(i=0; i<1000; i++) 
			; 
	splhi(); 
	for(i=0; i<2000000; i++) 
		; 
	duartreset(); 
	firmware(); 
} 
 
/* 
 * Insert new into list after where 
 */ 
void 
insert(List **head, List *where, List *new) 
{ 
	if(where == 0){ 
		new->next = *head; 
		*head = new; 
	}else{ 
		new->next = where->next; 
		where->next = new; 
	} 
		 
} 
 
/* 
 * Insert new into list at end 
 */ 
void 
append(List **head, List *new) 
{ 
	List *where; 
 
	where = *head; 
	if(where == 0) 
		*head = new; 
	else{ 
		while(where->next) 
			where = where->next; 
		where->next = new; 
	} 
	new->next = 0; 
} 
 
/* 
 * Delete old from list 
 */ 
void 
delete0(List **head, List *old) 
{ 
	List *l; 
 
	l = *head; 
	if(l == old){ 
		*head = old->next; 
		return; 
	} 
	while(l->next != old) 
		l = l->next; 
	l->next = old->next; 
} 
 
/* 
 * Delete old from list.  where->next is known to be old. 
 */ 
void 
delete(List **head, List *where, List *old) 
{ 
	if(where == 0){ 
		*head = old->next; 
		return; 
	} 
	where->next = old->next; 
} 
 
Conf	conf; 
 
void 
confinit(void) 
{ 
	long x, i, j, *l; 
 
	conf.nmach = 4; 
	if(conf.nmach > MAXMACH) 
		panic("confinit"); 
	conf.nproc = 193; 
	conf.npgrp = 100; 
 
	x = 0x12345678; 
	for(i=4; i<64; i+=4){ 
		l = (long*)(KSEG1|(i*1024L*1024L)); 
		*l = x; 
		wbflush(); 
		*(ulong*)KSEG1 = *(ulong*)KSEG1;	/* clear latches */ 
		if(*l != x) 
			break; 
		x += 0x3141526; 
	} 
	conf.npage = i*1024/4; 
 
	conf.npte = 20000; 
	conf.nmod = 500; 
	conf.nalarm = 1000; 
	conf.norig = 500; 
	conf.nchan = 500; 
	conf.nenv = 200; 
	conf.nenvchar = 10000; 
	conf.npgenv = 200; 
	conf.nmtab = 100; 
	conf.nmount = 500; 
	conf.nmntdev = 30; 
	conf.nmntbuf = 60; 
	conf.nmnthdr = 60; 
	conf.nstream = 512; 
	conf.nqueue = 5 * conf.nstream; 
	conf.nblock = 16 * conf.nstream; 
	conf.nsrv = 32; 
} 


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