Various APIC debugging and IOAPIC IRQ routing
authorBarret Rhoden <brho@cs.berkeley.edu>
Wed, 5 Mar 2014 01:27:06 +0000 (17:27 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Wed, 5 Mar 2014 01:31:24 +0000 (17:31 -0800)
Still busted, but getting a bit closer.  apiconline() needs work, and needs to
be called for all cores.  IOAPIC routing is broken, and the interfaces to IRQ
code are sloppy.  We have a weird mix of plan9 code and Akaros code that do
different things with PCI and IRQ handling.

kern/arch/x86/apic9.c
kern/arch/x86/ioapic.c
kern/arch/x86/mpacpi.c
kern/arch/x86/trap.c
kern/drivers/dev/acpi.c
kern/drivers/net/ether8139.c

index e5282a0..4ce8838 100644 (file)
@@ -171,10 +171,11 @@ void apicinit(int apicno, uintptr_t pa, int isbp)
                printd("apicinit%d: already initialised\n", apicno);
                return;
        }
+       assert(pa == LAPIC_PBASE);
        apicbase = LAPIC_BASE;
        printk("apicinit%d: apicbase %#p -> %#p\n", apicno, pa, apicbase);
        apic->useable = 1;
-       printk("apicinit%d: it's useable\n", apicno);
+       printk("\t\tapicinit%d: it's useable\n", apicno);
 
        /*
         * Assign a machno to the processor associated with this
@@ -185,9 +186,10 @@ void apicinit(int apicno, uintptr_t pa, int isbp)
        if (isbp) {
                apic->machno = 0;
 #warning "where in pcpui do we put the apicno?"
-               //m->apicno = apicno;
+               //m->apicno = apicno; // acpino is the hw_coreid
        } else
                apic->machno = apmachno++;
+               // ^^ machno is the os_coreid
 }
 
 static char *apicdump0(char *start, char *end, struct apic *apic, int i)
@@ -293,6 +295,9 @@ int apiconline(void)
         */
        apicrput(Eoi, 0);
 
+
+
+// TODO: sort this shit out with the system timing stuff
        /*
         * Use the TSC to determine the APIC timer frequency.
         * It might be possible to snarf this from a chipset
@@ -317,6 +322,9 @@ int apiconline(void)
                           apic->hz, apic->max, apic->min, apic->div);
        }
 
+
+
+
        /*
         * Mask interrupts on Performance Counter overflow and
         * Thermal Sensor if implemented, and on Lintr0 (Legacy INTR),
index fb9deb1..c71d925 100644 (file)
@@ -120,6 +120,8 @@ void ioapicintrinit(int busno, int apicno, int intin, int devno, int lo)
        if (!apic->useable || intin >= apic->nrdt) {
                printk("apic->usable %d intin %d apic->nrdt %d OOR\n", apic->useable,
                           intin, apic->nrdt);
+               printk("apicno %d, apic %p\n", apicno, apic);
+               monitor(0);
                return;
        }
 
@@ -189,7 +191,7 @@ int ioapic_route_irq(int irq, int apicno, int devno)
                return -1;
        }
        lo = pol | edge_level;
-       ioapicintrinit(0, 0, 0 /*st->intovr.intr */ , devno, lo);
+       ioapicintrinit(0, 8, 0 /*st->intovr.intr */ , devno, lo);
        printk("FOUND the MADT for %d\n", irq);
        return 0;
 }
@@ -199,6 +201,7 @@ void ioapicinit(int id, int ibase, uintptr_t pa)
        struct apic *apic;
        static int base;
 
+       assert(pa == IOAPIC_PBASE);
        /*
         * Mark the IOAPIC useable if it has a good ID
         * and the registers can be mapped.
@@ -211,6 +214,7 @@ void ioapicinit(int id, int ibase, uintptr_t pa)
        if (apic->useable)
                return;
        apic->useable = 1;
+       printk("\t\tioapicinit %d: it's useable, apic %p\n", id, apic);
        apic->paddr = pa;
 
        /*
@@ -597,7 +601,7 @@ int ioapicintrdisable(int vecno)
 
 spinlock_t vctllock;
 
-void *intrenable(int irq, void (*f) (void *, void *), void *a, int tbdf)
+int intrenable(int irq, void (*f) (void *, void *), void *a, int tbdf)
 {
        int vno;
        Vctl *v;
@@ -647,6 +651,7 @@ void *intrenable(int irq, void (*f) (void *, void *), void *a, int tbdf)
         * the handler; the IRQ is useless in the wonderful world
         * of the IOAPIC.
         */
-       printk("INTRNABLE returns %d\n", v);
-       return v;
+       printk("INTRNABLE returns %p\n", v);
+       printk("INTRNABLE returns %d\n", v->vno);
+       return v->vno;
 }
index a713352..7c72840 100644 (file)
@@ -55,7 +55,6 @@ int mpacpi(int ncleft)
 
                                printd("apic proc %d/%d apicid %d %s\n", np - 1, apic->machno,
                                           st->lapic.id, already);
-                               monitor(NULL);
                                break;
                        case ASioapic:
                                printd("ASioapic %d\n", st->ioapic.id);
@@ -70,7 +69,6 @@ int mpacpi(int ncleft)
                                printk("ioapicinit(%d, %p, %p);\n", st->lapic.id,
                                           apics->lapicpa, st->ioapic.addr);
                                ioapicinit(st->ioapic.id, st->ioapic.ibase, st->ioapic.addr);
-                               monitor(NULL);
 pr1:
                                printd("ioapic %d ", st->ioapic.id);
                                printd("addr %p base %d %s\n", apic->paddr, apic->ibase,
index 91f5e8a..dae2f90 100644 (file)
@@ -538,7 +538,7 @@ void handle_irq(struct hw_trapframe *hw_tf)
        if (hw_tf->tf_trapno != LAPIC_TIMER_DEFAULT_VECTOR)     /* timer irq */
        if (hw_tf->tf_trapno != 255) /* kmsg */
        if (hw_tf->tf_trapno != 36)     /* serial */
-               printd("Incoming IRQ, ISR: %d on core %d\n", hw_tf->tf_trapno,
+               printk("Incoming IRQ, ISR: %d on core %d\n", hw_tf->tf_trapno,
                       core_id());
        if (check_spurious_irq(hw_tf->tf_trapno))
                goto out_no_eoi;
@@ -602,16 +602,18 @@ void unregister_raw_irq(unsigned int vector, isr_t handler, void *data)
  */
 int register_dev_irq(int irq, isr_t handler, void *irq_arg, uint32_t tbdf)
 {
+       /* TODO: remove this - need it to poll serial for now */
        register_raw_irq(KERNEL_IRQ_OFFSET + irq, handler, irq_arg);
-
        /* TODO: whenever we sort out the ACPI/IOAPIC business, we'll probably want
         * a helper to reroute an irq? */
 #ifdef CONFIG_ENABLE_MPTABLES
-       /* TODO: this should be for any IOAPIC EOI, not just MPTABLES */
-       /* Just sending to core 0 for now */
-       printk("ROUTING irq %d to core 0!\n", irq);
-       intrenable(irq, handler, irq_arg, tbdf);
+       /* TODO: dirty hack to get the IOAPIC vector */
+extern int intrenable(int irq, void (*f) (void *, void *), void *a, int tbdf);
+int x =        intrenable(irq, handler, irq_arg, tbdf);
+       if (x > 0)
+               register_raw_irq(x, handler, irq_arg);
 #else
+       register_raw_irq(KERNEL_IRQ_OFFSET + irq, handler, irq_arg);
        pic_unmask_irq(irq);
        unmask_lapic_lvt(LAPIC_LVT_LINT0);
        enable_irq();
index 8252504..c5da46e 100644 (file)
@@ -646,7 +646,7 @@ static struct Atable *acpimsct(uint8_t * p, int len)
        struct Mdom **stl, *st;
        int off;
 
-       msct = kzmalloc(sizeof(struct Msct), KMALLOC_WAIT);
+       msct = kzmalloc(sizeof(struct Msct), 0);
        msct->ndoms = l32get(p + 40) + 1;
        msct->nclkdoms = l32get(p + 44) + 1;
        msct->maxpa = l64get(p + 48);
@@ -655,7 +655,7 @@ static struct Atable *acpimsct(uint8_t * p, int len)
        pe = p + len;
        off = l32get(p + 36);
        for (p += off; p < pe; p += 22) {
-               st = kzmalloc(sizeof(struct Mdom), KMALLOC_WAIT);
+               st = kzmalloc(sizeof(struct Mdom), 0);
                st->next = NULL;
                st->start = l32get(p + 2);
                st->end = l32get(p + 6);
@@ -1588,7 +1588,7 @@ static long acpiread(struct chan *c, void *a, long n, int64_t off)
 
        if (ttext == NULL) {
                tlen = 32768;
-               ttext = kzmalloc(tlen, KMALLOC_WAIT);
+               ttext = kzmalloc(tlen, 0);
        }
        if (ttext == NULL) {
                error("acpiread: no memory");
index f995e6f..5f337fa 100644 (file)
@@ -750,10 +750,10 @@ static int rtl8139pnp(struct ether *edev)
                edev->ea[4] = i;
                edev->ea[5] = i >> 8;
        }
+       /* TODO: sort out this TBDF shit */
        edev->tbdf = MKBUS(BusPCI, ctlr->pcidev->bus, 
                           ctlr->pcidev->dev, ctlr->pcidev->func);
        printk("TBDF is %p\n", edev->tbdf);
-monitor(NULL);
        edev->attach = rtl8139attach;
        edev->transmit = rtl8139transmit;
        edev->interrupt = rtl8139interrupt;