NIX mode.
[akaros.git] / kern / arch / x86 / mp.c
index 1e4a164..32dbbcc 100644 (file)
@@ -1,3 +1,10 @@
+/* This file is part of the UCB release of Plan 9. It is subject to the license
+ * terms in the LICENSE file found in the top-level directory of this
+ * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
+ * part of the UCB release of Plan 9, including this file, may be copied,
+ * modified, propagated, or distributed except according to the terms contained
+ * in the LICENSE file. */
+
 #include <vfs.h>
 #include <kfs.h>
 #include <slab.h>
@@ -11,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].
@@ -54,6 +63,7 @@ static Mpbus mpbusdef[] = {
 
 static Mpbus *mpbus[Nbus];
 int mpisabusno = -1;
+#define MP_VERBOSE_DEBUG 0
 
 static void mpintrprint(char *s, uint8_t * p)
 {
@@ -199,7 +209,7 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                for (i = 0; p < e; i++) {
                                        if (i && ((i & 0x0f) == 0))
                                                printd("\n");
-                                       printd(" %#2.2ux", *p);
+                                       printd(" 0x%#2.2x", *p);
                                        p++;
                                }
                                printd("\n");
@@ -212,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--;
@@ -221,14 +231,14 @@ 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]);
+                                       printk("mpparse: bus %d out of range\n", p[1]);
                                        p += 8;
                                        break;
                                }
                                if (mpbus[p[1]] != NULL) {
-                                       printd("mpparse: bus %d already allocated\n", p[1]);
+                                       printk("mpparse: bus %d already allocated\n", p[1]);
                                        p += 8;
                                        break;
                                }
@@ -237,7 +247,7 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                                continue;
                                        if (memcmp(p + 2, "ISA   ", 6) == 0) {
                                                if (mpisabusno != -1) {
-                                                       printd("mpparse: bus %d already have ISA bus %d\n",
+                                                       printk("mpparse: bus %d already have ISA bus %d\n",
                                                                   p[1], mpisabusno);
                                                        continue;
                                                }
@@ -247,8 +257,8 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                        break;
                                }
                                if (mpbus[p[1]] == NULL)
-                                       printd("mpparse: bus %d type %6.6s unknown\n",
-                                                  p[1], (char *unused_char_p_t)p + 2);
+                                       printk("mpparse: bus %d type %6.6s unknown\n",
+                                                  p[1], (char *)p + 2);
 
                                p += 8;
                                break;
@@ -268,8 +278,8 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                 * p[2-3] contains the polarity and trigger mode;
                                 * p[4] is the source bus;
                                 * p[5] is the IRQ on the source bus;
-                                * p[6] is the destination APIC;
-                                * p[7] is the INITIN pin on the destination APIC.
+                                * p[6] is the destination IOAPIC;
+                                * p[7] is the INITIN pin on the destination IOAPIC.
                                 */
                                if (p[6] == 0xff) {
                                        mpintrprint("routed to all IOAPICs", p);
@@ -277,11 +287,13 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                        break;
                                }
                                if ((lo = mpmkintr(p)) == 0) {
+                                       if (MP_VERBOSE_DEBUG)
+                                               mpintrprint("iointr skipped", p);
                                        p += 8;
                                        break;
                                }
-                               if (2)
-                                       mpintrprint(NULL, p);
+                               if (MP_VERBOSE_DEBUG)
+                                       mpintrprint("iointr", p);
 
                                /*
                                 * Always present the device number in the style
@@ -289,12 +301,13 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                 * bus the IRQ is the device number but unencoded.
                                 * May need to handle other buses here in the future
                                 * (but unlikely).
+                                *
+                                * For PCI devices, this field's lowest two bits are INT#A == 0,
+                                * INT#B == 1, etc.  Bits 2-6 are the PCI device number.
                                 */
                                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;
@@ -307,15 +320,15 @@ static int mpparse(PCMP * pcmp, int maxcores)
                                        p += 8;
                                        break;
                                }
-                               if (2)
-                                       mpintrprint(NULL, p);
+                               if (MP_VERBOSE_DEBUG)
+                                       mpintrprint("LINTR", p);
 
                                /*
                                 * Everything was checked in mpmkintr above.
                                 */
                                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;
                                        }
@@ -345,19 +358,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;
@@ -365,33 +378,6 @@ static int mpparse(PCMP * pcmp, int maxcores)
        return maxcores;
 }
 
-static int sigchecksum(void *address, int length)
-{
-       uint8_t *p, sum;
-
-       sum = 0;
-       for (p = address; length-- > 0; p++)
-               sum += *p;
-
-       return sum;
-}
-
-static void *sigscan(uint8_t * address, int length, char *signature)
-{
-       uint8_t *e, *p;
-       int siglength;
-
-       e = address + length;
-       siglength = strlen(signature);
-       for (p = address; p + siglength < e; p += 16) {
-               if (memcmp(p, signature, siglength))
-                       continue;
-               return p;
-       }
-
-       return NULL;
-}
-
 static void *sigsearch(char *signature)
 {
        uintptr_t p;
@@ -417,7 +403,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;
 
@@ -434,11 +420,13 @@ int mpsinit(int maxcores)
        PCMP *pcmp;
 
        if ((mp = sigsearch("_MP_")) == NULL) {
-               printd("no mp tables\n");
+               printk("No mp tables found, might have issues!\n");
                return ncleft;
        }
+       /* TODO: if an IMCR exists, we should set it to 1, though i've heard that
+        * ACPI-capable HW doesn't have the IMCR anymore. */
 
-       if (2) {
+       if (MP_VERBOSE_DEBUG) {
                printk("_MP_ @ %#p, addr %p length %ud rev %d",
                           mp, l32get(mp->addr), mp->length, mp->revision);
                for (i = 0; i < sizeof(mp->feature); i++)
@@ -449,23 +437,18 @@ int mpsinit(int maxcores)
                return ncleft;
        if (sigchecksum(mp, mp->length * 16) != 0)
                return ncleft;
-#define vmap(x,y) KADDR((x))
-#define vunmap(x,y)
-
-       if ((pcmp = vmap(l32get(mp->addr), sizeof(PCMP))) == NULL)
+       if ((pcmp = KADDR_NOCHECK(l32get(mp->addr))) == NULL)
                return ncleft;
        if (pcmp->revision != 1 && pcmp->revision != 4) {
                return ncleft;
        }
        n = l16get(pcmp->length) + l16get(pcmp->xlength);
-       vunmap(pcmp, sizeof(PCMP));
-       if ((pcmp = vmap(l32get(mp->addr), n)) == NULL)
+       if ((pcmp = KADDR_NOCHECK(l32get(mp->addr))) == NULL)
                return ncleft;
        if (sigchecksum(pcmp, l16get(pcmp->length)) != 0) {
-               vunmap(pcmp, n);
                return ncleft;
        }
-       if (2) {
+       if (MP_VERBOSE_DEBUG) {
                printk("PCMP @ %#p length %p revision %d\n",
                           pcmp, l16get(pcmp->length), pcmp->revision);
                printk(" %20.20s oaddr %p olength %p\n",
@@ -482,7 +465,6 @@ int mpsinit(int maxcores)
                i = sigchecksum(p, l16get(pcmp->xlength));
                if (((i + pcmp->xchecksum) & 0xff) != 0) {
                        printd("extended table checksums to %p\n", i);
-                       vunmap(pcmp, n);
                        return ncleft;
                }
        }