x86: APIC cleanup
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 17 Mar 2014 20:56:30 +0000 (13:56 -0700)
committerBarret Rhoden <brho@cs.berkeley.edu>
Sat, 29 Mar 2014 01:17:04 +0000 (18:17 -0700)
Cleanup of debug info, some dead code removal, better header work, etc.

Things work on qemu, though c89 is unhappy about of a bunch of things.
(bigger apics (nlvt > max), multiple botched buses, and a bus_irq_init
with a 0'd TBDF.

16 files changed:
kern/arch/x86/apic.c
kern/arch/x86/apic.h
kern/arch/x86/apic9.c
kern/arch/x86/ioapic.c
kern/arch/x86/ioapic.h
kern/arch/x86/mp.c
kern/arch/x86/mpacpi.c
kern/arch/x86/mptables.h [new file with mode: 0644]
kern/arch/x86/pci.c
kern/arch/x86/pci.h
kern/arch/x86/rdtsc_test.c
kern/arch/x86/smp_boot.c
kern/arch/x86/trap.c
kern/arch/x86/trap.h
kern/drivers/dev/acpi.c
kern/drivers/net/ether8139.c

index 7250449..f9aa04f 100644 (file)
@@ -25,17 +25,20 @@ bool core_id_ready = FALSE;
 bool lapic_check_spurious(int trap_nr)
 {
        /* FYI: lapic_spurious is 255 on qemu and 15 on the nehalem..  We actually
-        * can set bits 4-7, and P6s have 0-3 hardwired to 0.  YMMV.
+        * can set bits 4-7, and P6s have 0-3 hardwired to 0.  YMMV.  NxM seems to
+        * say the lower 3 bits are usually 1.  We'll see if the assert trips.
         *
         * The SDM recommends not using the spurious vector for any other IRQs (LVT
         * or IOAPIC RTE), since the handlers don't send an EOI.  However, our check
         * here allows us to use the vector since we can tell the diff btw a
         * spurious and a real IRQ. */
-       uint8_t lapic_spurious = read_mmreg32(LAPIC_SPURIOUS) & 0xff;
+       assert(IdtLAPIC_SPURIOUS == (read_mmreg32(LAPIC_SPURIOUS) & 0xff));
        /* Note the lapic's vectors are not shifted by an offset. */
-       if ((trap_nr == lapic_spurious) && !lapic_get_isr_bit(lapic_spurious)) {
+       if ((trap_nr == IdtLAPIC_SPURIOUS) &&
+            !lapic_get_isr_bit(IdtLAPIC_SPURIOUS)) {
                /* i'm still curious about these */
-               printk("Spurious LAPIC irq %d, core %d!\n", lapic_spurious, core_id());
+               printk("Spurious LAPIC irq %d, core %d!\n", IdtLAPIC_SPURIOUS,
+                      core_id());
                lapic_print_isr();
                return TRUE;
        }
index cce9ebe..6fdd924 100644 (file)
@@ -88,6 +88,7 @@ bool ipi_is_pending(uint8_t vector);
 void __lapic_set_timer(uint32_t ticks, uint8_t vec, bool periodic, uint8_t div);
 void lapic_set_timer(uint32_t usec, bool periodic);
 uint32_t lapic_get_default_id(void);
+int apiconline(void);
 
 static inline void lapic_send_eoi(int unused);
 static inline uint32_t lapic_get_version(void);
@@ -109,6 +110,7 @@ static inline void __send_ipi(uint8_t hw_coreid, uint8_t vector);
 static inline void send_group_ipi(uint8_t hw_groupid, uint8_t vector);
 static inline void __send_nmi(uint8_t hw_coreid);
 
+/* XXX: remove these */
 #define mask_lapic_lvt(entry) \
        write_mmreg32(entry, read_mmreg32(entry) | LAPIC_LVT_MASK)
 #define unmask_lapic_lvt(entry) \
@@ -259,21 +261,15 @@ struct ioapic {
        uintptr_t addr;                         /* IOAPIC: register base */
        uintptr_t paddr;                        /* register base */
        int nrdt;                                       /* IOAPIC: size of RDT */
-       int gsib;                                       /* IOAPIC: global RDT index */
        int ibase;                                      /* global interrupt base */
 };
 
 struct lapic {
-       int machno;                                     /* APIC */
+       int machno;                                     /* similar to os_coreid, unused */
 
        uint32_t lvt[6];
        int nlvt;
        int ver;
-
-       int64_t hz;                                     /* APIC Timer frequency */
-       int64_t max;
-       int64_t min;
-       int64_t div;
 };
 
 struct apic {
index 70e1a4e..9eea81b 100644 (file)
@@ -122,8 +122,7 @@ static uint32_t apicrget(int r)
        if (!apicbase)
                panic("apicrget: no apic");
        val = read_mmreg32(apicbase + r);
-       printk("apicrget: %s returns %p\n", apicregnames[r], val);
-       return *((uint32_t *) (apicbase + r));
+       printd("apicrget: %s returns %p\n", apicregnames[r], val);
        return val;
 }
 
@@ -131,26 +130,10 @@ static void apicrput(int r, uint32_t data)
 {
        if (!apicbase)
                panic("apicrput: no apic");
-       printk("apicrput: %s = %p\n", apicregnames[r], data);
+       printd("apicrput: %s = %p\n", apicregnames[r], data);
        write_mmreg32(apicbase + r, data);
 }
 
-int apiceoi(int vecno)
-{
-       apicrput(Eoi, 0);
-
-       return vecno;
-}
-
-int apicisr(int vecno)
-{
-       int isr;
-
-       isr = apicrget(Is + (vecno / 32) * 16);
-
-       return isr & (1 << (vecno % 32));
-}
-
 void apicinit(int apicno, uintptr_t pa, int isbp)
 {
        struct apic *apic;
@@ -163,7 +146,7 @@ void apicinit(int apicno, uintptr_t pa, int isbp)
         * are used for the APIC ID. There is also xAPIC and x2APIC
         * to be dealt with sometime.
         */
-       printk("apicinit: apicno %d pa %#p isbp %d\n", apicno, pa, isbp);
+       printd("apicinit: apicno %d pa %#p isbp %d\n", apicno, pa, isbp);
        if (apicno >= Napic) {
                printd("apicinit%d: out of range\n", apicno);
                return;
@@ -173,24 +156,13 @@ void apicinit(int apicno, uintptr_t pa, int isbp)
                return;
        }
        assert(pa == LAPIC_PBASE);
-       apicbase = LAPIC_BASE;
-       printk("apicinit%d: apicbase %#p -> %#p\n", apicno, pa, apicbase);
+       apicbase = LAPIC_BASE;  /* was the plan to just clobber the global? */
        apic->useable = 1;
-       printk("\t\tapicinit%d: it's useable\n", apicno);
 
-       /*
-        * Assign a machno to the processor associated with this
-        * APIC, it may not be an identity map.
-        * Machno 0 is always the bootstrap processor.
-        */
-
-       if (isbp) {
-               apic->machno = 0;
-#warning "where in pcpui do we put the apicno?"
-               //m->apicno = apicno; // acpino is the hw_coreid
-       } else
-               apic->machno = apmachno++;
-               // ^^ machno is the os_coreid
+       /* plan 9 used to set up a mapping btw apic and pcpui like so:
+               pcpui->apicno = apicno; // acpino is the hw_coreid
+               apic->machno = apmachno++; // machno is the os_coreid
+        * akaros does its own remapping of hw <-> os coreid during smp_boot */
 }
 
 static char *apicdump0(char *start, char *end, struct apic *apic, int i)
@@ -198,8 +170,8 @@ static char *apicdump0(char *start, char *end, struct apic *apic, int i)
        if (!apic->useable || apic->addr != 0)
                return start;
        start =
-               seprintf(start, end, "apic%d: machno %d lint0 %#8.8p lint1 %#8.8p\n", i,
-                                apic->machno, apic->lvt[0], apic->lvt[1]);
+               seprintf(start, end, "apic%d: oscore %d lint0 %#8.8p lint1 %#8.8p\n", i,
+                                get_os_coreid(i), apic->lvt[0], apic->lvt[1]);
        start =
                seprintf(start, end, " tslvt %#8.8p pclvt %#8.8p elvt %#8.8p\n",
                                 apicrget(Tslvt), apicrget(Pclvt), apicrget(Elvt));
@@ -222,20 +194,11 @@ char *apicdump(char *start, char *end)
                seprintf(start, end, "apicbase %#p apmachno %d\n", apicbase, apmachno);
        for (i = 0; i < Napic; i++)
                start = apicdump0(start, end, xlapic + i, i);
-       /* endxioapic?
-          for(i = 0; i < Napic; i++)
-          start = apicdump0(start, endxioapic + i, i);
-        */
+       for (i = 0; i < Napic; i++)
+               start = apicdump0(start, end, xioapic + i, i);
        return start;
 }
 
-#if 0
-static void apictimer(Ureg * ureg, void *)
-{
-       timerintr(ureg, 0);
-}
-
-#endif
 int apiconline(void)
 {
        struct apic *apic;
@@ -243,18 +206,22 @@ int apiconline(void)
        uint32_t dfr, ver;
        int apicno, nlvt;
 
-       if (!apicbase)
+       if (!apicbase) {
+               printk("No apicbase on HW core %d!!\n", hw_core_id());
                return 0;
-       if ((apicno = ((apicrget(Id) >> 24) & 0xff)) >= Napic)
+       }
+       if ((apicno = ((apicrget(Id) >> 24) & 0xff)) >= Napic) {
+               printk("Bad apicno %d on HW core %d!!\n", apicno, hw_core_id());
                return 0;
+       }
        apic = &xlapic[apicno];
-       if (!apic->useable || apic->addr)
+       /* The addr check tells us if it is an IOAPIC or not... */
+       if (!apic->useable || apic->addr) {
+               printk("Unsuitable apicno %d on HW core %d!!\n", apicno, hw_core_id());
                return 0;
-       /*
-        * Things that can only be done when on the processor
-        * owning the APIC, apicinit above runs on the bootstrap
-        * processor.
-        */
+       }
+       /* Things that can only be done when on the processor owning the APIC,
+        * apicinit above runs on the bootstrap processor. */
        ver = apicrget(Ver);
        nlvt = ((ver >> 16) & 0xff) + 1;
        if (nlvt > ARRAY_SIZE(apic->lvt)) {
@@ -264,200 +231,65 @@ int apiconline(void)
        }
        apic->nlvt = nlvt;
        apic->ver = ver & 0xff;
-#warning "fix me for AMD apic"
-       /*
-        * These don't really matter in Physical mode;
-        * set the defaults anyway.
-        if(memcmp(m->cpuinfo, "AuthenticAMD", 12) == 0)
-        dfr = 0xf0000000;
-        else
-        */
-       dfr = 0xffffffff;
+
+       /* These don't really matter in Physical mode; set the defaults anyway.  If
+        * we have problems with logical IPIs on AMD, check this out: */
+       //if (memcmp(m->cpuinfo, "AuthenticAMD", 12) == 0)
+       //      dfr = 0xf0000000;
+       //else
+               dfr = 0xffffffff;
        apicrput(Df, dfr);
        apicrput(Ld, 0x00000000);
 
-       /*
-        * Disable interrupts until ready by setting the Task Priority
-        * register to 0xff.
-        */
+       /* Disable interrupts until ready by setting the Task Priority register to
+        * 0xff. */
        apicrput(Tp, 0xff);
 
-       /*
-        * Software-enable the APIC in the Spurious Interrupt Vector
-        * register and set the vector number. The vector number must have
-        * bits 3-0 0x0f unless the Extended Spurious Vector Enable bit
-        * is set in the HyperTransport Transaction Control register.
-        */
+       /* Software-enable the APIC in the Spurious Interrupt Vector register and
+        * set the vector number. The vector number must have bits 3-0 0x0f unless
+        * the Extended Spurious Vector Enable bit is set in the HyperTransport
+        * Transaction Control register. */
        apicrput(Siv, Swen | IdtLAPIC_SPURIOUS);
 
-       /*
-        * Acknowledge any outstanding interrupts.
-        */
+       /* Acknowledge any outstanding interrupts. */
        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
-        * register instead.
-        */
-       apicrput(Tdc, DivX1);
-       apicrput(Tlvt, Im);
-       // system_timing.tsc_freq? is that valid yet?
-       tsc = read_tsc() + 2 * 1024 * (1048576 / 10) /*m->cpuhz/10 */ ;
-       apicrput(Tic, 0xffffffff);
-
-       while (read_tsc() < tsc) ;
-#define HZ 60
-       apic->hz = (0xffffffff - apicrget(Tcc)) * 10;
-       apic->max = apic->hz / HZ;
-       apic->min = apic->hz / (100 * HZ);
-       apic->div =
-               ((2ULL * 1024 * 1048576 /*m->cpuhz */  / apic->max) + HZ / 2) / HZ;
-
-       if ( /*m->machno == 0 || */ 2) {
-               printk("apic%d: hz %lld max %lld min %lld div %lld\n", apicno,
-                          apic->hz, apic->max, apic->min, apic->div);
-       }
-
-
-
-
-       /*
-        * Mask interrupts on Performance Counter overflow and
-        * Thermal Sensor if implemented, and on Lintr0 (Legacy INTR),
-        * and Lintr1 (Legacy NMI).
-        * Clear any Error Status (write followed by read) and enable
-        * the Error interrupt.
-        */
+       /* Mask interrupts on Performance Counter overflow and Thermal Sensor if
+        * implemented, and on Lintr0 (Legacy INTR), Lintr1 (Legacy NMI), and the
+        * Timer.  Clear any Error Status (write followed by read) and enable the
+        * Error interrupt. */
        switch (apic->nlvt) {
                case 6:
                        apicrput(Tslvt, Im);
-                /*FALLTHROUGH*/ case 5:
+                       /* fall-through */
+               case 5:
                        apicrput(Pclvt, Im);
-                /*FALLTHROUGH*/ default:
+                       /* fall-through */
+               default:
                        break;
        }
+       /* lvt[0] and [1] were set to 0 in the BSS */
        apicrput(Lint1, apic->lvt[1] | Im | IdtLAPIC_LINT1);
        apicrput(Lint0, apic->lvt[0] | Im | IdtLAPIC_LINT0);
+       apicrput(Tlvt, Im);
 
        apicrput(Es, 0);
        apicrget(Es);
        apicrput(Elvt, IdtLAPIC_ERROR);
 
-       /*
+       /* Not sure we need this from plan 9, Akaros never did:
+        *
         * Issue an INIT Level De-Assert to synchronise arbitration ID's.
-        * (Necessary in this implementation? - not if Pentium 4 or Xeon
-        * (APIC Version >= 0x14), or AMD).
-        apicrput(Ichi, 0);
-        apicrput(Iclo, DSallinc|Lassert|MTir);
-        while(apicrget(Iclo) & Ds)
-        ;
-        */
-
-#warning "not reloading the timer"
-       /*
-        * Reload the timer to de-synchronise the processors,
-        * then lower the task priority to allow interrupts to be
-        * accepted by the APIC.
-        microdelay((TK2MS(1)*1000/apmachno) * m->machno);
-        */
-
-#if 0
-       if (apic->machno == 0) {
-               apicrput(Tic, apic->max);
-               intrenable(IdtTIMER, apictimer, 0, -1, "APIC timer");
-               apicrput(Tlvt, Periodic | IrqTIMER);
-       }
-#endif
-       if (node_id() /*m->machno */  == 0)
-               apicrput(Tp, 0);
-
-#warning "map from apicno to cpu info not installed"
-/*
-       maps from apic to per-cpu info
-       xlapicmachptr[apicno] = m;
-*/
-
+        * (Necessary in this implementation? - not if Pentium 4 or Xeon (APIC
+        * Version >= 0x14), or AMD). */
+       //apicrput(Ichi, 0);
+       //apicrput(Iclo, DSallinc | Lassert | MTir);
+       //while (apicrget(Iclo) & Ds)
+       //      cpu_relax();
+
+       /* this is to enable the APIC interrupts.  we did a SW lapic_enable()
+        * earlier.  if we ever have issues where the lapic seems offline, check
+        * here. */
+       apicrput(Tp, 0);
        return 1;
 }
-
-#if 0
-/* To start timers on TCs as part of the boot process. */
-void apictimerenab(void)
-{
-       struct apic *apic;
-
-       apic = &xlapic[(apicrget(Id) >> 24) & 0xff];
-
-       apiceoi(IdtTIMER);
-       apicrput(Tic, apic->max);
-       apicrput(Tlvt, Periodic | IrqTIMER);
-
-}
-
-void apictimerset(uint64_t next)
-{
-       Mpl pl;
-       struct apic *apic;
-       int64_t period;
-
-       apic = &xlapic[(apicrget(Id) >> 24) & 0xff];
-
-       pl = splhi();
-       spin_lock(&(&m->apictimerlock)->lock);
-
-       period = apic->max;
-       if (next != 0) {
-               period = next - fastticks(NULL);        /* fastticks is just rdtsc() */
-               period /= apic->div;
-
-               if (period < apic->min)
-                       period = apic->min;
-               else if (period > apic->max - apic->min)
-                       period = apic->max;
-       }
-       apicrput(Tic, period);
-
-       spin_unlock(&(&m->apictimerlock)->lock);
-       splx(pl);
-}
-
-void apicsipi(int apicno, uintptr_t pa)
-{
-       int i;
-       uint32_t crhi, crlo;
-
-       /*
-        * SIPI - Start-up IPI.
-        * To do: checks on apic validity.
-        */
-       crhi = apicno << 24;
-       apicrput(Ichi, crhi);
-       apicrput(Iclo, DSnone | TMlevel | Lassert | MTir);
-       microdelay(200);
-       apicrput(Iclo, DSnone | TMlevel | MTir);
-       millidelay(10);
-
-       crlo = DSnone | TMedge | MTsipi | ((uint32_t) pa / (4 * KiB));
-       for (i = 0; i < 2; i++) {
-               apicrput(Ichi, crhi);
-               apicrput(Iclo, crlo);
-               microdelay(200);
-       }
-}
-
-void apicipi(int apicno)
-{
-       apicrput(Ichi, apicno << 24);
-       apicrput(Iclo, DSnone | TMedge | Lassert | MTf | IdtIPI);
-       while (apicrget(Iclo) & Ds) ;
-}
-
-void apicpri(int pri)
-{
-       apicrput(Tp, pri);
-}
-#endif
index 15bc2a6..2e3ec52 100644 (file)
@@ -72,10 +72,6 @@ static bool ioapic_exists(void)
        return xioapic[0].useable ? TRUE : FALSE;
 }
 
-/* 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;
@@ -154,7 +150,7 @@ void ioapicintrinit(int busno, int ioapicno, int intin, int devno, int lo)
                rdt->hi = 0;
        } else {
                if (lo != rdt->lo) {
-                       printk("mutiple irq botch bus %d %d/%d/%d lo %d vs %d\n",
+                       printk("multiple irq botch bus %d %d/%d/%d lo %d vs %d\n",
                                   busno, ioapicno, intin, devno, lo, rdt->lo);
                        return;
                }
@@ -283,7 +279,6 @@ 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;
 
        /*
@@ -294,6 +289,9 @@ void ioapicinit(int id, int ibase, uintptr_t pa)
        spin_lock(&apic->lock);
        write_mmreg32(apic->addr + Ioregsel, Ioapicver);
        apic->nrdt = ((read_mmreg32(apic->addr + Iowin) >> 16) & 0xff) + 1;
+       /* the ibase is the global system interrupt base, told to us by ACPI.  if
+        * it's -1, we're called from mpparse, and just guess/make up our own
+        * assignments. */
        if (ibase != -1)
                apic->ibase = ibase;
        else {
@@ -303,6 +301,7 @@ void ioapicinit(int id, int ibase, uintptr_t pa)
        write_mmreg32(apic->addr + Ioregsel, Ioapicid);
        write_mmreg32(apic->addr + Iowin, id << 24);
        spin_unlock(&apic->lock);
+       printk("IOAPIC initialized at %p\n", apic->addr);
 }
 
 char *ioapicdump(char *start, char *end)
@@ -375,7 +374,7 @@ int nextvec(void)
        return vecno;
 }
 
-#warning "no msi mask yet"
+/* TODO: MSI work */
 #if 0
 static int msimask(struct Vkey *v, int mask)
 {
@@ -386,10 +385,7 @@ static int msimask(struct Vkey *v, int mask)
                return -1;
        return pcimsimask(p, mask);
 }
-#endif
 
-#warning "No msi yet"
-#if 0
 static int intrenablemsi(struct vctl *v, Pcidev * p)
 {
        unsigned int vno, lo, hi;
@@ -416,9 +412,7 @@ static int intrenablemsi(struct vctl *v, Pcidev * p)
                   v->name, v->irq, vno);
        return vno;
 }
-#endif
-#warning "no disable msi yet"
-#if 0
+
 int disablemsi(Vctl *, Pcidev * p)
 {
        if (p == NULL)
@@ -567,7 +561,7 @@ int bus_irq_setup(struct irq_handler *irq_h)
                        devno = irq_h->dev_irq << 2;
                        break;
                case BusPCI:
-                       /* we'll assume it's there. */
+                       /* TODO: we'll assume it's there.  (fix when adding MSI) */
 #if 0
                        Pcidev *pcidev;
 
@@ -580,15 +574,11 @@ int bus_irq_setup(struct irq_handler *irq_h)
 #endif
                        explode_tbdf(irq_h->tbdf);
                        devno = pcidev_read8(&pcidev, PciINTP);
-                       printk("INTP is %d\n", devno);
 
                        if (devno == 0)
                                panic("no INTP for tbdf %p", irq_h->tbdf);
                        /* remember, devno is the device shifted with irq pin in bits 0-1 */
                        devno = BUSDNO(irq_h->tbdf) << 2 | (devno - 1);
-                       printk("devno is %08lx\n", devno);
-                       printk("bus_irq_enable: tbdf %p busno %d devno %d\n",
-                                  irq_h->tbdf, busno, devno);
                        break;
                default:
                        panic("Unknown bus type, TBDF %p", irq_h->tbdf);
index 0d5bea6..9f36aef 100644 (file)
@@ -56,6 +56,8 @@ enum {
 
 extern int mpisabusno;
 
+void ioapicintrinit(int busno, int apicno, int intin, int devno, int lo);
+void ioapiconline(void);
 void ioapicinit(int id, int ibase, uintptr_t pa);
 void ioapicrdtr(struct apic*, int unused_int, int*, int*);
 void ioapicrdtw(struct apic*, int unused_int, int, int);
index 71f6b34..6961c29 100644 (file)
@@ -18,6 +18,8 @@
 #include <pmap.h>
 #include <smp.h>
 #include <ip.h>
+#include <arch/mptables.h>
+#include <arch/ioapic.h>
 
 /*
  * MultiProcessor Specification Version 1.[14].
@@ -220,7 +222,7 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                 * CPU and identical for all. Indicate whether this is
                                 * the bootstrap processor (p[3] & 0x02).
                                 */
-                               printk("mpparse: cpu %d pa %p bp %d\n",
+                               printd("mpparse: cpu %d pa %p bp %d\n",
                                           p[1], l32get(pcmp->apicpa), p[3] & 0x02);
                                if ((p[3] & 0x01) != 0 && maxcores > 0) {
                                        maxcores--;
@@ -229,7 +231,7 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                p += 20;
                                break;
                        case 1: /* bus */
-                               printk("mpparse: bus: %d type %6.6s\n", p[1], (char *)p + 2);
+                               printd("mpparse: bus: %d type %6.6s\n", p[1], (char *)p + 2);
                                if (p[1] >= Nbus) {
                                        printd("mpparse: bus %d out of range\n", p[1]);
                                        p += 8;
@@ -304,8 +306,6 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                devno = p[5];
                                if (memcmp(mpbus[p[4]]->type, "PCI   ", 6) != 0)
                                        devno <<= 2;
-                               void ioapicintrinit(int busno, int apicno, int intin, int devno,
-                                                                       int lo);
                                ioapicintrinit(p[4], p[6], p[7], devno, lo);
 
                                p += 8;
@@ -356,19 +356,19 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                printd("\n");
                                break;
                        case 128:
-                               printk("address space mapping\n");
-                               printk(" bus %d type %d base %#llux length %#llux\n",
+                               printd("address space mapping\n");
+                               printd(" bus %d type %d base %#llux length %#llux\n",
                                           p[2], p[3], l64get(p + 4), l64get(p + 12));
                                p += p[1];
                                break;
                        case 129:
-                               printk("bus hierarchy descriptor\n");
-                               printk(" bus %d sd %d parent bus %d\n", p[2], p[3], p[4]);
+                               printd("bus hierarchy descriptor\n");
+                               printd(" bus %d sd %d parent bus %d\n", p[2], p[3], p[4]);
                                p += p[1];
                                break;
                        case 130:
-                               printk("compatibility bus address space modifier\n");
-                               printk(" bus %d pr %d range list %d\n",
+                               printd("compatibility bus address space modifier\n");
+                               printd(" bus %d pr %d range list %d\n",
                                           p[2], p[3], l32get(p + 4));
                                p += p[1];
                                break;
@@ -401,7 +401,7 @@ static void *sigsearch(char *signature)
                return r;
 #endif
        r = sigscan(KADDR(0xe0000), 0x20000, signature);
-       printk("Found mp table at %p\n", r);
+       printk("Found MP table at %p\n", r);
        if (r != NULL)
                return r;
 
@@ -435,7 +435,7 @@ int mpsinit(int maxcores)
                return ncleft;
        if (sigchecksum(mp, mp->length * 16) != 0)
                return ncleft;
-#define vmap(x,y) KADDR((x))
+#define vmap(x,y) ((void*)(x + KERNBASE))
 #define vunmap(x,y)
 
        if ((pcmp = vmap(l32get(mp->addr), sizeof(PCMP))) == NULL)
index 3e7939c..8548a4b 100644 (file)
@@ -5,7 +5,6 @@
  * modified, propagated, or distributed except according to the terms contained
  * in the LICENSE file. */
 
-#define DEBUG
 #include <vfs.h>
 #include <kfs.h>
 #include <slab.h>
@@ -40,7 +39,6 @@ int mpacpi(int ncleft)
        if (mpisabusno == -1)
                mpisabusno = Nbus - 1;
 
-       printk("mpacpi ncleft %d\n", ncleft);
        if (apics == NULL)
                return ncleft;
 
@@ -62,8 +60,6 @@ int mpacpi(int ncleft)
                                        already = "(mp)";
                                } else if (ncleft != 0) {
                                        ncleft--;
-                                       printk("apicinit(%d, %p, %d);\n", st->lapic.id,
-                                                  apics->lapicpa, bp);
                                        apicinit(st->lapic.id, apics->lapicpa, bp);
                                } else
                                        already = "(off)";
@@ -81,8 +77,6 @@ int mpacpi(int ncleft)
                                        already = "(mp)";
                                        goto pr1;
                                }
-                               printk("ioapicinit(%d, %p, %p);\n", st->lapic.id,
-                                          apics->lapicpa, st->ioapic.addr);
                                ioapicinit(st->ioapic.id, st->ioapic.ibase, st->ioapic.addr);
 pr1:
                                printd("ioapic %d ", st->ioapic.id);
diff --git a/kern/arch/x86/mptables.h b/kern/arch/x86/mptables.h
new file mode 100644 (file)
index 0000000..784b1b5
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef ROS_KERN_ARCH_MPTABLES_H
+#define ROS_KERN_ARCH_MPTABLES_H
+
+int mpacpi(int ncleft);
+int mpsinit(int maxcores);
+
+#endif /* ROS_KERN_ARCH_MPTABLES_H */
index 4284bbf..3384b3a 100644 (file)
@@ -110,12 +110,6 @@ void pci_init(void) {
                                pcidev->irqline = pcidev_read8(pcidev, PCI_IRQLINE_STD);
                                /* This is the interrupt pin the device uses (INTA# - INTD#) */
                                pcidev->irqpin = pcidev_read8(pcidev, PCI_IRQPIN_STD);
-                               if (pcidev->irqpin != PCI_NOINT) {
-                                       /* TODO: use a list (check for collisions for now) (massive
-                                        * collisions on a desktop with bridge IRQs. */
-                                       //assert(!irq_pci_map[pcidev->irqline]);
-                                       irq_pci_map[pcidev->irqline] = pcidev;
-                               }
                                /* bottom 7 bits are header type */
                                switch (pcidev_read8(pcidev, PCI_HEADER_REG) & 0x7c) {
                                        case 0x00:
index ee8096e..427854e 100644 (file)
@@ -392,7 +392,7 @@ uint32_t pci_getiobar32(uint32_t bar);
 /* Other common PCI functions */
 void pci_set_bus_master(struct pci_device *pcidev);
 
-/* this is quite the Hacke */
+/* TODO: this is quite the Hacke */
 #define explode_tbdf(tbdf) {pcidev.bus = tbdf >> 16;\
                pcidev.dev = (tbdf>>11)&0x1f;\
                pcidev.func = (tbdf>>8)&3;}
index fe733ac..c22c0b1 100644 (file)
 #include <arch/arch.h>
 #include <stdio.h>
 #include <kmalloc.h>
+#include <time.h>
 
 #define STAT_SIZE_DEF 10000
 #define LOOP_BOUND_DEF 1000
@@ -754,8 +755,7 @@ void test_tsc_cycles(void)
                                      : : : "eax", "cc");
        }
        end = read_tsc_serialized();
-# warning "what happened to system_timing?"
-       end = end - start - 0; //system_timing.timing_overhead;
+       end = end - start - system_timing.timing_overhead;
        printk("%llu (100,000) ticks passed, run twice to load the icache\n", end);
 
        enable_irqsave(&irq_state);
index fcd9ff4..f08b997 100644 (file)
@@ -278,6 +278,9 @@ uintptr_t smp_main(void)
        // Loads the same IDT used by the other cores
        asm volatile("lidt %0" : : "m"(idt_pd));
 
+#ifdef CONFIG_ENABLE_MPTABLES
+       apiconline();
+#else
        // APIC setup
        // set LINT0 to receive ExtINTs (KVM's default).  At reset they are 0x1000.
        write_mmreg32(LAPIC_LVT_LINT0, 0x700);
@@ -286,6 +289,7 @@ uintptr_t smp_main(void)
        mask_lapic_lvt(LAPIC_LVT_LINT0);
        // and then turn it on
        lapic_enable();
+#endif
 
        // set a default logical id for now
        lapic_set_logid(lapic_get_id());
index ab154d6..92b81ee 100644 (file)
@@ -21,6 +21,7 @@
 #include <syscall.h>
 #include <kdebug.h>
 #include <kmalloc.h>
+#include <arch/mptables.h>
 
 taskstate_t RO ts;
 
@@ -33,10 +34,6 @@ pseudodesc_t idt_pd;
 struct irq_handler *irq_handlers[NUM_IRQS];
 spinlock_t irq_handler_wlock = SPINLOCK_INITIALIZER_IRQSAVE;
 
-/* Which pci devices hang off of which irqs */
-/* TODO: make this an array of SLISTs (pain from ioapic.c, etc...) */
-struct pci_device *irq_pci_map[NUM_IRQS] = {0};
-
 const char *x86_trapname(int trapno)
 {
     // zra: excnames is SREADONLY because Ivy doesn't trust const
@@ -170,15 +167,12 @@ void idt_init(void)
 
 #ifdef CONFIG_ENABLE_MPTABLES
        int ncleft = MAX_NUM_CPUS;
-       int mpsinit(int maxcores);
-       void ioapiconline(void);
-       void apiconline(void);
 
        ncleft = mpsinit(ncleft);
        ncleft = mpacpi(ncleft);
-       printk("mpacpi is %d\n", ncleft);
+       printk("MP and ACPI found %d cores\n", MAX_NUM_CPUS - ncleft);
 
-       apiconline(); /* TODO: do this this for all cores*/
+       apiconline();
        ioapiconline();
 #else
        // set LINT0 to receive ExtINTs (KVM's default).  At reset they are 0x1000.
@@ -473,8 +467,8 @@ void handle_irq(struct hw_trapframe *hw_tf)
        abort_halt(hw_tf);
        //if (core_id())
        if (hw_tf->tf_trapno != IdtLAPIC_TIMER) /* timer irq */
-       if (hw_tf->tf_trapno != 255) /* kmsg */
-       if (hw_tf->tf_trapno != 36)     /* serial */
+       if (hw_tf->tf_trapno != I_KERNEL_MSG)
+       if (hw_tf->tf_trapno != 65)     /* qemu serial tends to get this one */
                printd("Incoming IRQ, ISR: %d on core %d\n", hw_tf->tf_trapno,
                       core_id());
        /* TODO: RCU read lock */
@@ -528,7 +522,8 @@ int register_irq(int irq, isr_t handler, void *irq_arg, uint32_t tbdf)
        wmb();  /* make sure irq_h is done before publishing to readers */
        irq_handlers[vector] = irq_h;
        spin_unlock_irqsave(&irq_handler_wlock);
-       /* might need to pass the irq_h, in case unmask needs more info */
+       /* Most IRQs other than the BusIPI should need their irq unmasked.
+        * Might need to pass the irq_h, in case unmask needs more info */
        if (irq_h->unmask)
                irq_h->unmask(vector);
        return 0;
index 78bdb38..683d2d4 100644 (file)
@@ -53,8 +53,7 @@
 #define IdtLAPIC_ERROR                 (IdtLAPIC + 5)
 /* Plan 9 apic note: the spurious vector number must have bits 3-0 0x0f
  * unless the Extended Spurious Vector Enable bit is set in the
- * HyperTransport Transaction Control register.  Plan 9 used 63 (0x3f), but
- * 55 should have worked too (0x37). */
+ * HyperTransport Transaction Control register.  Plan 9 used 63 (0x3f). */
 #define IdtLAPIC_SPURIOUS              (IdtLAPIC + 15) /* Aka 63, 0x3f */
 #define MaxIdtLAPIC                            (IdtLAPIC + 15)
 
@@ -148,8 +147,6 @@ struct irq_handler {
 extern gatedesc_t idt[];
 extern pseudodesc_t idt_pd;
 extern taskstate_t ts;
-/* Mapping of irq -> PCI device (TODO: make this PCI-agnostic) */
-extern struct pci_device *irq_pci_map[NUM_IRQS];
 int bus_irq_setup(struct irq_handler *irq_h);  /* ioapic.c */
 extern const char *x86_trapname(int trapno);
 extern void sysenter_handler(void);
index c5da46e..119dd2b 100644 (file)
 #include <pmap.h>
 #include <smp.h>
 #include <ip.h>
-#include <arch/pci.h>
 #include <acpi.h>
+#ifdef CONFIG_X86
+#include <arch/pci.h>
+#endif
 
 /*
  * ACPI 4.0 Support.
@@ -193,6 +195,8 @@ static void ioset32(uintptr_t p, uint32_t v, void *unused)
        outl(p, v);
 }
 
+/* TODO: these cfgs are hacky. maybe all the struct Reg should have struct
+ * pci_device or something? */
 static uint8_t cfgget8(uintptr_t p, void *r)
 {
        struct Reg *ro = r;
@@ -274,26 +278,27 @@ regcpy(struct Regio *dio, uintptr_t da, struct Regio *sio,
 {
        int n, i;
 
-       printk("regcpy %#p %#p %#p %#p\n", da, sa, len, align);
+       printd("regcpy %#p %#p %#p %#p\n", da, sa, len, align);
        if ((len % align) != 0)
                printd("regcpy: bug: copy not aligned. truncated\n");
        n = len / align;
        for (i = 0; i < n; i++) {
                switch (align) {
                        case 1:
-                               printk("cpy8 %#p %#p\n", da, sa);
+                               printd("cpy8 %#p %#p\n", da, sa);
                                dio->set8(da, sio->get8(sa, sio->arg), dio->arg);
                                break;
                        case 2:
-                               printk("cpy16 %#p %#p\n", da, sa);
+                               printd("cpy16 %#p %#p\n", da, sa);
                                dio->set16(da, sio->get16(sa, sio->arg), dio->arg);
                                break;
                        case 4:
-                               printk("cpy32 %#p %#p\n", da, sa);
+                               printd("cpy32 %#p %#p\n", da, sa);
                                dio->set32(da, sio->get32(sa, sio->arg), dio->arg);
                                break;
                        case 8:
-                               printk("cpy64 %#p %#p\n", da, sa);
+                               printd("cpy64 %#p %#p\n", da, sa);
+                               warn("Not doing set64 for some reason, fix me!");
                                //  dio->set64(da, sio->get64(sa, sio->arg), dio->arg);
                                break;
                        default:
@@ -305,10 +310,10 @@ regcpy(struct Regio *dio, uintptr_t da, struct Regio *sio,
        return n * align;
 }
 
-// until we know.
+// until we know.  TODO: spatch/find_replace this shit, same with mp.c
 //#define vmap(x,y) (void *)vmap_pmem((x),(y))
 //#define vunmap(x,y) vunmap_vmem((uintptr_t)(x),(y))
-#define vmap(x,y) KADDR((x))
+#define vmap(x,y) ((void*)(x + KERNBASE))
 #define vunmap(x,y)
 /*
  * Perform I/O within region in access units of accsz bytes.
@@ -319,7 +324,7 @@ static long regio(struct Reg *r, void *p, uint32_t len, uintptr_t off, int iswr)
        struct Regio rio;
        uintptr_t rp;
 
-       printk("reg%s %s %#p %#p %#lx sz=%d\n",
+       printd("reg%s %s %#p %#p %#lx sz=%d\n",
                   iswr ? "out" : "in", r->name, p, off, len, r->accsz);
        rp = 0;
        if (off + len > r->len) {
@@ -332,9 +337,6 @@ static long regio(struct Reg *r, void *p, uint32_t len, uintptr_t off, int iswr)
        }
        switch (r->spc) {
                case Rsysmem:
-                       // XXX should map only what we are going to use
-                       // A region might be too large.
-                       // we don't have this nonsense in akaros, right? 
                        if (r->p == NULL)
                                r->p = vmap(r->base, len);
                        if (r->p == NULL)
@@ -455,13 +457,13 @@ static int loadfacs(uintptr_t pa)
        }
        /* no unmap */
 
-       printk("acpi: facs: hwsig: %#p\n", facs->hwsig);
-       printk("acpi: facs: wakingv: %#p\n", facs->wakingv);
-       printk("acpi: facs: flags: %#p\n", facs->flags);
-       printk("acpi: facs: glock: %#p\n", facs->glock);
-       printk("acpi: facs: xwakingv: %#p\n", facs->xwakingv);
-       printk("acpi: facs: vers: %#p\n", facs->vers);
-       printk("acpi: facs: ospmflags: %#p\n", facs->ospmflags);
+       printd("acpi: facs: hwsig: %#p\n", facs->hwsig);
+       printd("acpi: facs: wakingv: %#p\n", facs->wakingv);
+       printd("acpi: facs: flags: %#p\n", facs->flags);
+       printd("acpi: facs: glock: %#p\n", facs->glock);
+       printd("acpi: facs: xwakingv: %#p\n", facs->xwakingv);
+       printd("acpi: facs: vers: %#p\n", facs->vers);
+       printd("acpi: facs: ospmflags: %#p\n", facs->ospmflags);
        return 0;
 }
 
@@ -831,37 +833,6 @@ uintptr_t acpimblocksize(uintptr_t addr, int *dom)
        return 0;
 }
 
-/*
- * we use mp->machno (or index in Mach array) as the identifier,
- * but ACPI relies on the apic identifier.
- */
-int corecolor(int core)
-{
-#warning "can't do core colors yet"
-       return -1;
-#if 0
-       struct Srat *sl;
-       static int colors[32];
-
-       if (core < 0 || core >= num_cpus)
-               return -1;
-       m = sys->machptr[core];
-       if (m == NULL)
-               return -1;
-
-       if (core >= 0 && core < ARRAY_SIZE(colors) && colors[core] != 0)
-               return colors[core] - 1;
-
-       for (sl = srat; sl != NULL; sl = sl->next)
-               if (sl->type == SRlapic && sl->lapic.apic == m->apicno) {
-                       if (core >= 0 && core < ARRAY_SIZE(colors))
-                               colors[core] = 1 + sl->lapic.dom;
-                       return sl->lapic.dom;
-               }
-       return -1;
-#endif
-}
-
 int pickcore(int mycolor, int index)
 {
        int color;
@@ -1163,7 +1134,7 @@ static int acpixsdtload(char *sig)
                memmove(tsig, sdt, 4);
                tsig[4] = 0;
                if (sig == NULL || strcmp(sig, tsig) == 0) {
-                       printk("acpi: %s addr %#p\n", tsig, sdt);
+                       printd("acpi: %s addr %#p\n", tsig, sdt);
                        for (t = 0; t < ARRAY_SIZE(ptables); t++)
                                if (strcmp(tsig, ptables[t].sig) == 0) {
                                        //dumptable(table, &table[127], tsig, sdt, l);
@@ -1203,7 +1174,7 @@ static void acpirsdptr(void)
 
        assert(sizeof(struct Sdthdr) == 36);
 
-       printk("acpi: RSD PTR@ %#p, physaddr $%p length %ud %#llux rev %d\n",
+       printd("acpi: RSD PTR@ %#p, physaddr $%p length %ud %#llux rev %d\n",
                   rsd, l32get(rsd->raddr), l32get(rsd->length),
                   l64get(rsd->xaddr), rsd->revision);
 
@@ -1237,7 +1208,7 @@ static void acpirsdptr(void)
        }
        if ((xsdt->p[0] != 'R' && xsdt->p[0] != 'X')
                || memcmp(xsdt->p + 1, "SDT", 3) != 0) {
-               printk("acpi: xsdt sig: %c%c%c%c\n", xsdt->p[0], xsdt->p[1], xsdt->p[2],
+               printd("acpi: xsdt sig: %c%c%c%c\n", xsdt->p[0], xsdt->p[1], xsdt->p[2],
                           xsdt->p[3]);
                kfree(xsdt);
                xsdt = NULL;
@@ -1247,7 +1218,7 @@ static void acpirsdptr(void)
        xsdt->p += sizeof(struct Sdthdr);
        xsdt->len -= sizeof(struct Sdthdr);
        xsdt->asize = asize;
-       printk("acpi: XSDT %#p\n", xsdt);
+       printd("acpi: XSDT %#p\n", xsdt);
        acpixsdtload(NULL);
        /* xsdt is kept and not unmapped */
 
@@ -1384,7 +1355,6 @@ static unsigned int getpm1ctl(void)
 
 static void setpm1sts(unsigned int v)
 {
-       printk("acpi: setpm1sts %#p\n", v);
        setbanked(fadt.pm1aevtblk, fadt.pm1bevtblk, fadt.pm1evtlen / 2, v);
 }
 
@@ -1410,7 +1380,6 @@ static void setgpeen(int n, unsigned int v)
 {
        int old;
 
-       printk("acpi: setgpe %d %d\n", n, v);
        old = inb(gpes[n].enio);
        if (v)
                outb(gpes[n].enio, old | 1 << gpes[n].enbit);
@@ -1503,10 +1472,10 @@ int acpiinit(void)
                //fmtinstall('G', Gfmt);
                acpirsdptr();
                if (fadt.smicmd == 0) {
-                       printk("acpiinit returns -1\n");
                        return -1;
                }
        }
+       printk("ACPI initialized\n");
        return 0;
 }
 
@@ -1514,13 +1483,11 @@ static struct chan *acpiattach(char *spec)
 {
        int i;
 
-       printk("ACPI attach\n");
        /*
         * This was written for the stock kernel.
         * This code must use 64 registers to be acpi ready in nix.
         */
        if (acpiinit() < 0) {
-               printk("ACPIINIT is called\n");
                error("no acpi");
        }
 
@@ -1528,7 +1495,6 @@ static struct chan *acpiattach(char *spec)
         * should use fadt->xpm* and fadt->xgpe* registers for 64 bits.
         * We are not ready in this kernel for that.
         */
-       printk("acpi io alloc\n");
        acpiioalloc(fadt.smicmd, 1);
        acpiioalloc(fadt.pm1aevtblk, fadt.pm1evtlen);
        acpiioalloc(fadt.pm1bevtblk, fadt.pm1evtlen);
@@ -1539,7 +1505,6 @@ static struct chan *acpiattach(char *spec)
        acpiioalloc(fadt.gpe0blk, fadt.gpe0blklen);
        acpiioalloc(fadt.gpe1blk, fadt.gpe1blklen);
 
-       printk("acpi init gpes\n");
        initgpes();
 
        /*
@@ -1604,7 +1569,6 @@ static long acpiread(struct chan *c, void *a, long n, int64_t off)
                        for (t = tfirst; t != NULL; t = t->next) {
                                ns = seprinttable(s, e, t);
                                while (ns == e - 1) {
-                                       printk("acpiread: allocated %d\n", tlen * 2);
                                        ntext = krealloc(ttext, tlen * 2, 0);
                                        if (ntext == NULL)
                                                panic("acpi: no memory\n");
@@ -1663,9 +1627,9 @@ static long acpiwrite(struct chan *c, void *a, long n, int64_t off)
                nexterror();
        }
        ct = lookupcmd(cb, ctls, ARRAY_SIZE(ctls));
-       printk("acpi ctl %s\n", cb->f[0]);
        switch (ct->index) {
                case CMregion:
+                       /* TODO: this block is racy on reg (global) */
                        r = reg;
                        if (r == NULL) {
                                r = kzmalloc(sizeof(struct Reg), 0);
@@ -1683,8 +1647,11 @@ static long acpiwrite(struct chan *c, void *a, long n, int64_t off)
                                fun = r->base >> Rpcifunshift & Rpcifunmask;
                                dev = r->base >> Rpcidevshift & Rpcidevmask;
                                bus = r->base >> Rpcibusshift & Rpcibusmask;
-#define MKBUS(t,b,d,f) (((t)<<24)|(((b)&0xFF)<<16)|(((d)&0x1F)<<11)|(((f)&0x07)<<8))
-                               r->tbdf = MKBUS(0 /*BusPCI */ , bus, dev, fun);
+                               #ifdef CONFIG_X86
+                               r->tbdf = MKBUS(BusPCI, bus, dev, fun);
+                               #else
+                               r->tbdf = 0
+                               #endif
                                r->base = rno;  /* register ~ our base addr */
                        }
                        r->base = strtoul(cb->f[3], NULL, 0);
@@ -1696,7 +1663,7 @@ static long acpiwrite(struct chan *c, void *a, long n, int64_t off)
                                error("bad region access size");
                        }
                        reg = r;
-                       printk("region %s %s %p %p sz%d",
+                       printd("region %s %s %p %p sz%d",
                                   r->name, acpiregstr(r->spc), r->base, r->len, r->accsz);
                        break;
                case CMgpe:
@@ -1704,7 +1671,6 @@ static long acpiwrite(struct chan *c, void *a, long n, int64_t off)
                        if (i >= ngpes)
                                error("gpe out of range");
                        kstrdup(&gpes[i].obj, cb->f[2]);
-                       printk("gpe %d %s\n", i, gpes[i].obj);
                        setgpeen(i, 1);
                        break;
                default:
index 5f337fa..39cd569 100644 (file)
@@ -750,10 +750,8 @@ 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);
+       edev->tbdf = MKBUS(BusPCI, ctlr->pcidev->bus, ctlr->pcidev->dev,
+                          ctlr->pcidev->func);
        edev->attach = rtl8139attach;
        edev->transmit = rtl8139transmit;
        edev->interrupt = rtl8139interrupt;