void mpinitcpu(long unit) { cpuinit(unit); /* TODO: initialise HPET; enable [rerouted] interrupts */ #if (HPET) hpetinit(); #endif apicinit(); #if (IOAPIC) ioapicinit(); #endif tssinit(unit); return; }
void mpstart(void) { // volatile static int first = 1; volatile struct m_cpu *cpu; volatile struct m_cpu *lim; uint32_t *mpentrystk = (uint32_t *)MPENTRYSTK; lim = &mpcputab[0] + mpncpu; #if 0 if (first) { kmemcpy((void *)MPENTRY, mpentry, (uint8_t *)&mpend - (uint8_t *)&mpentry); first = 0; } #endif for (cpu = &mpcputab[0] ; cpu < lim ; cpu++) { if (cpu == mpbootcpu) { /* started already */ continue; } kprintf("starting CPU %ld @ 0x%lx\n", cpu->id, MPENTRY); cpuinit((struct m_cpu *)cpu); #if 0 apicinit(cpu->id); ioapicinit(cpu->id); #endif *--mpentrystk = (uint32_t)cpu; *--mpentrystk = MPENTRYSTK - cpu->id * MPSTKSIZE; *--mpentrystk = (uint32_t)&kernpagedir; apicstart(cpu->id, MPENTRY); while (!cpu->started) { ; } } return; }
int mpacpi(int ncleft) { char *already; int np, bp; Apic *apic; Apicst *st; Madt *mt; /* If we don't have an mpisabusno yet, it's because the MP tables failed to * parse. So we'll just take the last one available. I think we're * supposed to parse the ACPI shit with the AML to figure out the buses and * find a clear one, but f**k that. Note this busno is just for our own * RDT/Rbus bookkeeping. */ if (mpisabusno == -1) mpisabusno = Nbus - 1; if (apics == nil) return ncleft; mt = apics->tbl; if (mt == nil) return ncleft; print("APIC lapic paddr %#.8llx, flags %#.8x\n", mt->lapicpa, mt->pcat); np = 0; //print("apics->st %p\n", apics->st); for (int i = 0; i < apics->nchildren; i++) { st = apics->children[i]->tbl; already = ""; switch (st->type) { case ASlapic: print("ASlapic %d\n", st->lapic.id); /* this table is supposed to have all of them if it exists */ if (st->lapic.id > Napic) break; apic = xlapic + st->lapic.id; bp = (np++ == 0); if (apic->useable) { already = "(mp)"; } else if (ncleft != 0) { ncleft--; apicinit(st->lapic.id, mt->lapicpa, bp); } else already = "(off)"; print("apic proc %d/%d apicid %d %s\n", np - 1, apic->Lapic.machno, st->lapic.id, already); break; case ASioapic: print("ASioapic %d\n", st->ioapic.id); if (st->ioapic.id > Napic){ print("ASioapic: %d is > %d, ignoring\n", st->ioapic.id, Napic); break; } apic = xioapic + st->ioapic.id; if (apic->useable) { already = "(mp)"; goto pr1; } ioapicinit(st->ioapic.id, st->ioapic.ibase, st->ioapic.addr); pr1: apic->Ioapic.gsib = st->ioapic.ibase; print("ioapic %d ", st->ioapic.id); print("addr %p ibase %d %s\n", st->ioapic.addr, st->ioapic.ibase, already); break; } } return ncleft; }
int mpacpi(int ncleft) { char *already; int np, bp; struct apic *apic; struct Apicst *st; /* If we don't have an mpisabusno yet, it's because the MP tables failed to * parse. So we'll just take the last one available. I think we're * supposed to parse the ACPI shit with the AML to figure out the buses and * find a clear one, but f**k that. Note this busno is just for our own * RDT/Rbus bookkeeping. */ if (mpisabusno == -1) mpisabusno = Nbus - 1; if (apics == NULL) return ncleft; printd("APIC lapic paddr %#.8llux, flags %#.8ux\n", apics->lapicpa, apics->pcat); np = 0; printd("apics->st %p\n", apics->st); for (st = apics->st; st != NULL; st = st->next) { already = ""; switch (st->type) { case ASlapic: printd("ASlapic %d\n", st->lapic.id); /* this table is supposed to have all of them if it exists */ if (st->lapic.id > MaxAPICNO) break; apic = xlapic + st->lapic.id; bp = (np++ == 0); if (apic->useable) { already = "(mp)"; } else if (ncleft != 0) { ncleft--; apicinit(st->lapic.id, apics->lapicpa, bp); } else already = "(off)"; printd("apic proc %d/%d apicid %d %s\n", np - 1, apic->machno, st->lapic.id, already); break; case ASioapic: printd("ASioapic %d\n", st->ioapic.id); if (st->ioapic.id > Napic) break; apic = xioapic + st->ioapic.id; if (apic->useable) { apic->ibase = st->ioapic.ibase; /* gnarly */ already = "(mp)"; goto pr1; } ioapicinit(st->ioapic.id, st->ioapic.ibase, st->ioapic.addr); pr1: printd("ioapic %d ", st->ioapic.id); printd("addr %p base %d %s\n", apic->paddr, apic->ibase, already); break; } } return ncleft; }