APIC MMIO reads/writes use the helper
authorBarret Rhoden <brho@cs.berkeley.edu>
Fri, 7 Mar 2014 02:37:05 +0000 (18:37 -0800)
committerBarret Rhoden <brho@cs.berkeley.edu>
Fri, 7 Mar 2014 02:37:05 +0000 (18:37 -0800)
Some of the operations (like the IOAPIC version read) were getting
optimized such that they didn't work properly.  Like reading a byte
instead of the entire aligned 32 bit IOAPIC version.

kern/arch/x86/apic.h
kern/arch/x86/apic9.c
kern/arch/x86/ioapic.c
kern/arch/x86/mp.c

index 68e2b33..dac3ed3 100644 (file)
@@ -326,7 +326,7 @@ static inline void __send_nmi(uint8_t hw_coreid)
 
 struct ioapic {
        spinlock_t lock;                        /* IOAPIC: register access */
-       uint32_t *addr;                         /* IOAPIC: register base */
+       uintptr_t addr;                         /* IOAPIC: register base */
        uintptr_t paddr;                        /* register base */
        int nrdt;                                       /* IOAPIC: size of RDT */
        int gsib;                                       /* IOAPIC: global RDT index */
index 4ce8838..b9f134d 100644 (file)
@@ -110,7 +110,7 @@ enum {                                                      /* Tdc */
        DivX1 = 0x0000000b,     /* Divide by 1 */
 };
 
-static uint8_t *apicbase;
+static uintptr_t apicbase;
 static int apmachno = 1;
 
 struct apic xlapic[Napic];
@@ -120,7 +120,7 @@ static uint32_t apicrget(int r)
        uint32_t val;
        if (!apicbase)
                panic("apicrget: no apic");
-       val = *((uint32_t *) (apicbase + r));
+       val = read_mmreg32(apicbase + r);
        printk("apicrget: %s returns %p\n", apicregnames[r], val);
        return *((uint32_t *) (apicbase + r));
        return val;
@@ -131,7 +131,7 @@ static void apicrput(int r, uint32_t data)
        if (!apicbase)
                panic("apicrput: no apic");
        printk("apicrput: %s = %p\n", apicregnames[r], data);
-       *((uint32_t *) (apicbase + r)) = data;
+       write_mmreg32(apicbase + r, data);
 }
 
 int apiceoi(int vecno)
@@ -242,14 +242,13 @@ int apiconline(void)
        uint32_t dfr, ver;
        int apicno, nlvt;
 
-       if (apicbase == NULL)
+       if (!apicbase)
                return 0;
        if ((apicno = ((apicrget(Id) >> 24) & 0xff)) >= Napic)
                return 0;
        apic = &xlapic[apicno];
-       if (!apic->useable || apic->addr != NULL)
+       if (!apic->useable || apic->addr)
                return 0;
-
        /*
         * Things that can only be done when on the processor
         * owning the APIC, apicinit above runs on the bootstrap
index c71d925..0974f77 100644 (file)
@@ -40,7 +40,7 @@ struct Rdt {
 
 enum {                                                 /* IOAPIC registers */
        Ioregsel = 0x00,                        /* indirect register address */
-       Iowin = 0x04,   /* indirect register data */
+       Iowin = 0x10,   /* indirect register data */
        Ioipa = 0x08,   /* IRQ Pin Assertion */
        Ioeoi = 0x10,   /* EOI */
 
@@ -60,26 +60,29 @@ static spinlock_t idtnolock;
 static int idtno = IdtIOAPIC;
 
 struct apic xioapic[Napic];
+
+/* TODO: put these in a header */
 int apiceoi(int);
 int apicisr(int);
+
 static void rtblget(struct apic *apic, int sel, uint32_t * hi, uint32_t * lo)
 {
        sel = Ioredtbl + 2 * sel;
 
-       *(apic->addr + Ioregsel) = sel + 1;
-       *hi = *(apic->addr + Iowin);
-       *(apic->addr + Ioregsel) = sel;
-       *lo = *(apic->addr + Iowin);
+       write_mmreg32(apic->addr + Ioregsel, sel + 1);
+       *hi = read_mmreg32(apic->addr + Iowin);
+       write_mmreg32(apic->addr + Ioregsel, sel);
+       *lo = read_mmreg32(apic->addr + Iowin);
 }
 
 static void rtblput(struct apic *apic, int sel, uint32_t hi, uint32_t lo)
 {
        sel = Ioredtbl + 2 * sel;
 
-       *(apic->addr + Ioregsel) = sel + 1;
-       *(apic->addr + Iowin) = hi;
-       *(apic->addr + Ioregsel) = sel;
-       *(apic->addr + Iowin) = lo;
+       write_mmreg32(apic->addr + Ioregsel, sel + 1);
+       write_mmreg32(apic->addr + Iowin, hi);
+       write_mmreg32(apic->addr + Ioregsel, sel);
+       write_mmreg32(apic->addr + Iowin, lo);
 }
 
 struct Rdt *rdtlookup(struct apic *apic, int intin)
@@ -223,16 +226,16 @@ void ioapicinit(int id, int ibase, uintptr_t pa)
         * responsibility of the O/S to set the APIC ID.
         */
        spin_lock(&apic->lock);
-       *(apic->addr + Ioregsel) = Ioapicver;
-       apic->nrdt = ((*(apic->addr + Iowin) >> 16) & 0xff) + 1;
+       write_mmreg32(apic->addr + Ioregsel, Ioapicver);
+       apic->nrdt = ((read_mmreg32(apic->addr + Iowin) >> 16) & 0xff) + 1;
        if (ibase != -1)
                apic->ibase = ibase;
        else {
                apic->ibase = base;
                base += apic->nrdt;
        }
-       *(apic->addr + Ioregsel) = Ioapicid;
-       *(apic->addr + Iowin) = id << 24;
+       write_mmreg32(apic->addr + Ioregsel, Ioapicid);
+       write_mmreg32(apic->addr + Iowin, id << 24);
        spin_unlock(&apic->lock);
 }
 
@@ -274,13 +277,14 @@ char *ioapicdump(char *start, char *end)
        return start;
 }
 
+/* Zeros and masks every redirect entry in every IOAPIC */
 void ioapiconline(void)
 {
        int i;
        struct apic *apic;
 
        for (apic = xioapic; apic < &xioapic[Napic]; apic++) {
-               if (!apic->useable || apic->addr == NULL)
+               if (!apic->useable || !apic->addr)
                        continue;
                for (i = 0; i < apic->nrdt; i++) {
                        spin_lock(&apic->lock);
@@ -609,7 +613,7 @@ int intrenable(int irq, void (*f) (void *, void *), void *a, int tbdf)
 
        if (f == NULL) {
                printk("intrenable: nil handler for %d, tbdf %p\n", irq, tbdf);
-               return NULL;
+               return 0;
        }
 
        v = kzmalloc(sizeof(Vctl), KMALLOC_WAIT);
@@ -627,7 +631,7 @@ int intrenable(int irq, void (*f) (void *, void *), void *a, int tbdf)
                printk("intrenable: couldn't enable irq %d, tbdf %p for %s\n",
                           irq, tbdf, v->name);
                kfree(v);
-               return NULL;
+               return 0;
        }
 #if 0
        if (vctl[vno]) {
index c4d9e03..76d3a77 100644 (file)
@@ -315,7 +315,7 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                 */
                                if (p[6] == 0xff) {
                                        for (i = 0; i < Napic; i++) {
-                                               if (!xlapic[i].useable || xlapic[i].addr != NULL)
+                                               if (!xlapic[i].useable || xlapic[i].addr)
                                                        continue;
                                                xlapic[i].lvt[p[7]] = lo;
                                        }