from richard, fixes for multiprocessor startup, and shutdown. Reference: /n/atom/patch/applied/pistart Date: Mon Jan 4 16:21:32 CET 2016 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/bcm/main.c Mon Jan 4 16:21:18 2016 +++ /sys/src/9/bcm/main.c Mon Jan 4 16:21:19 2016 @@ -227,20 +227,61 @@ void machinit(void) { - m->machno = 0; - machaddr[m->machno] = m; + Mach *m0; m->ticks = 1; m->perf.period = 1; + m0 = MACHP(0); + if (m->machno != 0) { + /* synchronise with cpu 0 */ + m->ticks = m0->ticks; + m->fastclock = m0->fastclock; + m->delayloop = m0->delayloop; + } - conf.nmach = 1; + //machon(m->machno); +} - active.machs = 1; +void +mach0init(void) +{ + m->machno = 0; + machaddr[m->machno] = m; + + machinit(); active.exiting = 0; up = nil; } +void +launchinit(int ncpus) +{ + int mach; + Mach *mm; + PTE *l1; + + if(ncpus > MAXMACH) + ncpus = MAXMACH; + for(mach = 1; mach < ncpus; mach++){ + machaddr[mach] = mm = mallocalign(MACHSIZE, MACHSIZE, 0, 0); + l1 = mallocalign(L1SIZE, L1SIZE, 0, 0); + if(mm == nil || l1 == nil) + panic("launchinit"); + memset(mm, 0, MACHSIZE); + mm->machno = mach; + + memmove(l1, m->mmul1, L1SIZE); /* clone cpu0's l1 table */ + cachedwbse(l1, L1SIZE); + mm->mmul1 = l1; + cachedwbse(mm, MACHSIZE); + + } + cachedwbse(machaddr, sizeof machaddr); + if((mach = startcpus(ncpus)) < ncpus) + panic("only %d cpu%s started", mach, mach == 1? "" : "s"); +} + static void optionsinit(char* s) { @@ -284,8 +325,9 @@ okay(1); m = (Mach*)MACHADDR; memset(edata, 0, end - edata); /* clear bss */ - machinit(); + mach0init(); mmuinit1((void*)L1); + machon(0); optionsinit("/boot/boot boot"); fmtinit(); @@ -321,6 +363,7 @@ pageinit(); swapinit(); userinit(); + launchinit(getncpus()); schedinit(); assert(0); /* shouldn't have returned */ } @@ -580,9 +623,20 @@ void exit(int code) { + void (*f)(ulong, ulong, ulong); + shutdown(code); splfhi(); - archreboot(); + if(m->machno == 0) + archreboot(); + else{ + f = (void*)REBOOTADDR; + intrcpushutdown(); + cacheuwbinv(); + l2cacheuwbinv(); + (*f)(0, 0, 0); + for(;;){} + } } /* @@ -595,6 +649,14 @@ void (*f)(ulong, ulong, ulong); writeconf(); + + /* + * the boot processor is cpu0. execute this function on it + * so that the new kernel has the same cpu0. + */ + if (m->machno != 0) + procwired(up, 0); + shutdown(0); /* --- /sys/src/9/bcm/fns.h Mon Jan 4 16:21:21 2016 +++ /sys/src/9/bcm/fns.h Mon Jan 4 16:21:22 2016 @@ -62,6 +62,7 @@ extern long i2csend(I2Cdev *, void *, long, ulong); extern u32int ifsrget(void); extern void irqenable(int, void (*)(Ureg*, void*), void*); +extern void intrcpushutdown(void); #define intrenable(i, f, a, b, n) irqenable((i), (f), (a)) extern void intrsoff(void); extern int l2ap(int);