-static PCMP* mppcmp;
-static Bus* mpbus;
-static Bus* mpbuslast;
-static int mpisabus = -1;
-static int mpeisabus = -1;
-extern int i8259elcr; /* mask of level-triggered interrupts */
-static Apic mpapic[MaxAPICNO+1];
-static int machno2apicno[MaxAPICNO+1]; /* inverse map: machno -> APIC ID */
-static int mpapicremap[MaxAPICNO+1];
-static int mpmachno = 1;
-static Lock mpphysidlock;
-static int mpphysid;
-
-static char* buses[] = {
- "CBUSI ",
- "CBUSII",
- "EISA ",
- "FUTURE",
- "INTERN",
- "ISA ",
- "MBI ",
- "MBII ",
- "MCA ",
- "MPI ",
- "MPSA ",
- "NUBUS ",
- "PCI ",
- "PCMCIA",
- "TC ",
- "VL ",
- "VME ",
- "XPRESS",
- 0,
-};
-
-static Apic*
-mkprocessor(PCMPprocessor* p)
-{
- int apicno;
- Apic *apic;
-
- apicno = p->apicno;
- if(!(p->flags & PcmpEN) || apicno > MaxAPICNO)
- return 0;
-
- apic = &mpapic[apicno];
- apic->type = PcmpPROCESSOR;
- apic->apicno = apicno;
- apic->flags = p->flags;
- apic->lintr[0] = ApicIMASK;
- apic->lintr[1] = ApicIMASK;
-
- if(p->flags & PcmpBP){
- machno2apicno[0] = apicno;
- apic->machno = 0;
- }
- else{
- machno2apicno[mpmachno] = apicno;
- apic->machno = mpmachno;
- mpmachno++;
- }
-
- return apic;
-}
-
-static Bus*
-mkbus(PCMPbus* p)
-{
- Bus *bus;
- int i;
-
- for(i = 0; buses[i]; i++){
- if(strncmp(buses[i], p->string, sizeof(p->string)) == 0)
- break;
- }
- if(buses[i] == 0)
- return 0;
-
- bus = xalloc(sizeof(Bus));
- if(mpbus)
- mpbuslast->next = bus;
- else
- mpbus = bus;
- mpbuslast = bus;
-
- bus->type = i;
- bus->busno = p->busno;
- if(bus->type == BusEISA){
- bus->po = PcmpLOW;
- bus->el = PcmpLEVEL;
- if(mpeisabus != -1)
- print("mkbus: more than one EISA bus\n");
- mpeisabus = bus->busno;
- }
- else if(bus->type == BusPCI){
- bus->po = PcmpLOW;
- bus->el = PcmpLEVEL;
- }
- else if(bus->type == BusISA){
- bus->po = PcmpHIGH;
- bus->el = PcmpEDGE;
- if(mpisabus != -1)
- print("mkbus: more than one ISA bus\n");
- mpisabus = bus->busno;
- }
- else{
- bus->po = PcmpHIGH;
- bus->el = PcmpEDGE;
- }
-
- return bus;
-}
-
-static Bus*
-mpgetbus(int busno)
-{
- Bus *bus;
-
- for(bus = mpbus; bus; bus = bus->next){
- if(bus->busno == busno)
- return bus;
- }
- print("mpgetbus: can't find bus %d\n", busno);
-
- return 0;
-}
-
-static int
-freeapicid(void)
-{
- int i;
-
- for(i = 0; i < MaxAPICNO+1; i++)
- if(mpapic[i].flags == 0)
- return i;
- return -1;
-}
-
-static Apic*
-mkioapic(PCMPioapic* p)
-{
- void *va;
- int apicno, new;
- Apic *apic;
-
- apicno = p->apicno;
- if(!(p->flags & PcmpEN) || apicno > MaxAPICNO)
- return 0;
-
- /*
- * Map the I/O APIC.
- */
- if((va = vmap(p->addr, 1024)) == nil)
- return 0;
-
- apic = &mpapic[apicno];
- if(apic->flags != 0) {
- new = freeapicid();
- if(new < 0)
- print("mkioapic: out of APIC IDs\n");
- else {
- mpapicremap[p->apicno] = new;
- print("mkioapic: APIC ID conflict at %d, remapping to %d\n", p->apicno, new);
- p->apicno = apicno = new;
- apic = &mpapic[apicno];
- }
- } else
- mpapicremap[p->apicno] = p->apicno;
- apic->type = PcmpIOAPIC;
- apic->apicno = apicno;
- apic->addr = va;
- apic->paddr = p->addr;
- apic->flags = p->flags;
-
- return apic;
-}
-
-static Aintr*
-mkiointr(PCMPintr* p)
-{
- Bus *bus;
- Aintr *aintr;
- PCMPintr* pcmpintr;
-
- /*
- * According to the MultiProcessor Specification, a destination
- * I/O APIC of 0xFF means the signal is routed to all I/O APICs.
- * It's unclear how that can possibly be correct so treat it as
- * an error for now.
- */
- if(p->apicno > MaxAPICNO)
- return 0;
-
- if(mpapicremap[p->apicno] < 0) {
- print("iointr: non-existing IOAPIC %d\n", p->apicno);
- return 0;
- }
- p->apicno = mpapicremap[p->apicno];
- if((bus = mpgetbus(p->busno)) == 0)
- return 0;
-
- aintr = xalloc(sizeof(Aintr));
- aintr->intr = p;
-
- if(0)
- print("iointr: type %d intr type %d flags %#o "
- "bus %d irq %d apicno %d intin %d\n",
- p->type, p->intr, p->flags,
- p->busno, p->irq, p->apicno, p->intin);
- /*
- * Hack for Intel SR1520ML motherboard, which BIOS describes
- * the i82575 dual ethernet controllers incorrectly.
- */
- if(memcmp(mppcmp->product, "INTEL X38MLST ", 20) == 0){
- if(p->busno == 1 && p->intin == 16 && p->irq == 1){
- pcmpintr = malloc(sizeof(PCMPintr));
- memmove(pcmpintr, p, sizeof(PCMPintr));
- print("mkiointr: %20.20s bus %d intin %d irq %d\n",
- (char*)mppcmp->product,
- pcmpintr->busno, pcmpintr->intin,
- pcmpintr->irq);
- pcmpintr->intin = 17;
- aintr->intr = pcmpintr;
- }
- }
- aintr->apic = &mpapic[p->apicno];
- aintr->next = bus->aintr;
- bus->aintr = aintr;