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; } |