/* * Main scheduling loop done by the application core. * Some of functions run will not return. * The system call handler will reset the stack and * call acsched again. * We loop because some functions may return and we should * wait for another call. */ void acsched(void) { acmmuswitch(); for(;;){ acstackok(); mwait(&machp()->icc->fn); if(machp()->icc->flushtlb) acmmuswitch(); DBG("acsched: cpu%d: fn %#p\n", machp()->machno, machp()->icc->fn); machp()->icc->fn(); DBG("acsched: cpu%d: idle\n", machp()->machno); mfence(); machp()->icc->fn = nil; } }
void squidboy(int apicno) { char *n[] = { [NIXAC] "AC", [NIXTC] "TC", [NIXKC] "KC" }; vlong hz; sys->machptr[m->machno] = m; setmachsched(m); /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; m->perf.period = 1; m->nixtype = NIXAC; DBG("Hello Squidboy %d %d\n", apicno, m->machno); vsvminit(MACHSTKSZ, m->nixtype); /* * Beware the Curse of The Non-Interruptable Were-Temporary. */ hz = archhz(); if(hz == 0) ndnr(); m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; mmuinit(); if(!apiconline()) ndnr(); fpuinit(); acmodeset(m->nixtype); m->splpc = 0; m->online = 1; /* * CAUTION: no time sync done, etc. */ DBG("Wait for the thunderbirds!\n"); while(!active.thunderbirdsarego) ; wrmsr(0x10, sys->epoch); m->rdtsc = rdtsc(); print("cpu%d color %d role %s tsc %lld\n", m->machno, corecolor(m->machno), n[m->nixtype], m->rdtsc); switch(m->nixtype){ case NIXAC: acmmuswitch(); acinit(); adec(&active.nbooting); ainc(&active.nonline); /* this was commented out */ acsched(); panic("squidboy"); break; case NIXTC: /* * We only need the idt and syscall entry point actually. * At boot time the boot processor might set our role after * we have decided to become an AC. */ vsvminit(MACHSTKSZ, NIXTC); /* * Enable the timer interrupt. */ apicpri(0); timersinit(); adec(&active.nbooting); ainc(&active.nonline); /* this was commented out */ schedinit(); break; } panic("squidboy returns (type %d)", m->nixtype); }
/* * Entered in AP core context, upon traps (system calls go through acsyscall) * using up->dbgreg means cores MUST be homogeneous. * * BUG: We should setup some trapenable() mechanism for the AC, * so that code like fpu.c could arrange for handlers specific for * the AC, instead of doint that by hand here. * * All interrupts are masked while in the "kernel" */ void actrap(Ureg *u) { panic("actrap"); #if 0 char *n; ACVctl *v; n = nil; _pmcupdate(m); if(m->proc != nil){ m->proc->nactrap++; m->proc->actime1 = fastticks(nil); } if(u->type < nelem(acvctl)){ v = acvctl[u->type]; if(v != nil){ DBG("actrap: cpu%d: %ulld\n", machp()->machno, u->type); n = v->f(u, v->a); if(n != nil) goto Post; return; } } switch(u->type){ case IdtDF: print("AC: double fault\n"); dumpregs(u); ndnr(); case IdtIPI: m->intr++; DBG("actrap: cpu%d: IPI\n", machp()->machno); apiceoi(IdtIPI); break; case IdtTIMER: apiceoi(IdtTIMER); panic("timer interrupt in an AC"); break; case IdtPF: /* this case is here for debug only */ m->pfault++; DBG("actrap: cpu%d: PF cr2 %#ullx\n", machp()->machno, cr2get()); break; default: print("actrap: cpu%d: %ulld\n", machp()->machno, u->type); } Post: m->icc->rc = ICCTRAP; m->cr2 = cr2get(); memmove(m->proc->dbgreg, u, sizeof *u); m->icc->note = n; fpuprocsave(m->proc); _pmcupdate(m); mfence(); m->icc->fn = nil; ready(m->proc); mwait(&m->icc->fn); if(m->icc->flushtlb) acmmuswitch(); if(m->icc->fn != actrapret) acsched(); DBG("actrap: ret\n"); memmove(u, m->proc->dbgreg, sizeof *u); if(m->proc) m->proc->actime += fastticks2us(fastticks(nil) - m->proc->actime1); #endif }
void squidboy(int apicno, Mach *m) { // FIX QEMU. extern int64_t hz; int64_t hz; sys->machptr[m->machno] = m; /* * Need something for initial delays * until a timebase is worked out. */ m->cpuhz = 2000000000ll; m->cpumhz = 2000; m->perf.period = 1; m->nixtype = NIXAC; // no NIXAC for now. m->nixtype = NIXTC; // NOTE: you can't do ANYTHING here before vsvminit. // PRINT WILL PANIC. So wait. vsvminit(MACHSTKSZ, m->nixtype, m); //DBG("Hello squidboy %d %d\n", apicno, m->machno); /* * Beware the Curse of The Non-Interruptable Were-Temporary. */ hz = archhz(); /* Intel cpu's in archk10 must be reviewed */ if(hz == 0) hz = 2000000000ll; m->cpuhz = hz; m->cyclefreq = hz; m->cpumhz = hz/1000000ll; mmuinit(); if(!apiconline()) ndnr(); fpuinit(); acmodeset(m->nixtype); m->splpc = 0; m->online = 1; /* * CAUTION: no time sync done, etc. * Stupid print to avoid up = nil or * last cpu couldn't start in nixquids. */ DBG("Wait for the thunderbirds!\n"); while(!active.thunderbirdsarego) ; wrmsr(0x10, sys->epoch); m->rdtsc = rdtsc(); print("cpu%d color %d role %s tsc %lld\n", m->machno, corecolor(m->machno), rolename[m->nixtype], m->rdtsc); switch(m->nixtype){ case NIXAC: acmmuswitch(); acinit(); adec(&active.nbooting); ainc(&active.nonline); /* this was commented out */ acsched(); panic("squidboy"); break; case NIXTC: /* * We only need the idt and syscall entry point actually. * At boot time the boot processor might set our role after * we have decided to become an AC. */ vsvminit(MACHSTKSZ, NIXTC, m); /* * Enable the timer interrupt. */ apictimerenab(); apicpri(0); timersinit(); adec(&active.nbooting); ainc(&active.nonline); /* Ready? steady? going to timer */ ndnr(); schedinit(); break; } panic("squidboy returns (type %d)", m->nixtype); }