]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/9/pc/mp.c
kernel: cleanup makefile for $CONF.$O target
[plan9front.git] / sys / src / 9 / pc / mp.c
index c53d2b089c3e01ec864ed6c265e4c5ecbe733869..382e247f7a1b592c62a82e22a0ea2c712b7643eb 100644 (file)
@@ -7,7 +7,7 @@
 #include "ureg.h"
 
 #include "mp.h"
-#include "apbootstrap.h"
+#include "apbootstrap.i"
 
 /* filled in by pcmpinit or acpiinit */
 Bus* mpbus;
@@ -90,58 +90,6 @@ mpintrinit(Bus* bus, PCMPintr* intr, int vno, int /*irq*/)
        return v;
 }
 
-static void
-checkmtrr(void)
-{
-       int i, vcnt;
-       Mach *mach0;
-
-       /*
-        * If there are MTRR registers, snarf them for validation.
-        */
-       if(!(m->cpuiddx & Mtrr))
-               return;
-
-       rdmsr(0x0FE, &m->mtrrcap);
-       rdmsr(0x2FF, &m->mtrrdef);
-       if(m->mtrrcap & 0x0100){
-               rdmsr(0x250, &m->mtrrfix[0]);
-               rdmsr(0x258, &m->mtrrfix[1]);
-               rdmsr(0x259, &m->mtrrfix[2]);
-               for(i = 0; i < 8; i++)
-                       rdmsr(0x268+i, &m->mtrrfix[(i+3)]);
-       }
-       vcnt = m->mtrrcap & 0x00FF;
-       if(vcnt > nelem(m->mtrrvar))
-               vcnt = nelem(m->mtrrvar);
-       for(i = 0; i < vcnt; i++)
-               rdmsr(0x200+i, &m->mtrrvar[i]);
-
-       /*
-        * If not the bootstrap processor, compare.
-        */
-       if(m->machno == 0)
-               return;
-
-       mach0 = MACHP(0);
-       if(mach0->mtrrcap != m->mtrrcap)
-               print("mtrrcap%d: %lluX %lluX\n",
-                       m->machno, mach0->mtrrcap, m->mtrrcap);
-       if(mach0->mtrrdef != m->mtrrdef)
-               print("mtrrdef%d: %lluX %lluX\n",
-                       m->machno, mach0->mtrrdef, m->mtrrdef);
-       for(i = 0; i < 11; i++){
-               if(mach0->mtrrfix[i] != m->mtrrfix[i])
-                       print("mtrrfix%d: i%d: %lluX %lluX\n",
-                               m->machno, i, mach0->mtrrfix[i], m->mtrrfix[i]);
-       }
-       for(i = 0; i < vcnt; i++){
-               if(mach0->mtrrvar[i] != m->mtrrvar[i])
-                       print("mtrrvar%d: i%d: %lluX %lluX\n",
-                               m->machno, i, mach0->mtrrvar[i], m->mtrrvar[i]);
-       }
-}
-
 uvlong
 tscticks(uvlong *hz)
 {
@@ -172,112 +120,6 @@ syncclock(void)
        }
 }
 
-static void
-squidboy(Apic* apic)
-{
-//     iprint("Hello Squidboy\n");
-
-       machinit();
-       mmuinit();
-
-       cpuidentify();
-       cpuidprint();
-       checkmtrr();
-
-       apic->online = 1;
-
-       lapicinit(apic);
-       lapiconline();
-       syncclock();
-       timersinit();
-
-       fpoff();
-
-       lock(&active);
-       active.machs |= 1<<m->machno;
-       unlock(&active);
-
-       while(!active.thunderbirdsarego)
-               microdelay(100);
-
-       schedinit();
-}
-
-static void
-mpstartap(Apic* apic)
-{
-       ulong *apbootp, *pdb, *pte;
-       Mach *mach, *mach0;
-       int i, machno;
-       uchar *p;
-
-       mach0 = MACHP(0);
-
-       /*
-        * Initialise the AP page-tables and Mach structure. The page-tables
-        * are the same as for the bootstrap processor with the exception of
-        * the PTE for the Mach structure.
-        * Xspanalloc will panic if an allocation can't be made.
-        */
-       p = xspanalloc(4*BY2PG, BY2PG, 0);
-       pdb = (ulong*)p;
-       memmove(pdb, mach0->pdb, BY2PG);
-       p += BY2PG;
-
-       if((pte = mmuwalk(pdb, MACHADDR, 1, 0)) == nil)
-               return;
-       memmove(p, KADDR(PPN(*pte)), BY2PG);
-       *pte = PADDR(p)|PTEWRITE|PTEVALID;
-       if(mach0->havepge)
-               *pte |= PTEGLOBAL;
-       p += BY2PG;
-
-       mach = (Mach*)p;
-       if((pte = mmuwalk(pdb, MACHADDR, 2, 0)) == nil)
-               return;
-       *pte = PADDR(mach)|PTEWRITE|PTEVALID;
-       if(mach0->havepge)
-               *pte |= PTEGLOBAL;
-       p += BY2PG;
-
-       machno = apic->machno;
-       MACHP(machno) = mach;
-       mach->machno = machno;
-       mach->pdb = pdb;
-       mach->gdt = (Segdesc*)p;        /* filled by mmuinit */
-
-       /*
-        * Tell the AP where its kernel vector and pdb are.
-        * The offsets are known in the AP bootstrap code.
-        */
-       apbootp = (ulong*)(APBOOTSTRAP+0x08);
-       *apbootp++ = (ulong)squidboy;
-       *apbootp++ = PADDR(pdb);
-       *apbootp = (ulong)apic;
-
-       /*
-        * Universal Startup Algorithm.
-        */
-       p = KADDR(0x467);
-       *p++ = PADDR(APBOOTSTRAP);
-       *p++ = PADDR(APBOOTSTRAP)>>8;
-       i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
-       /* code assumes i==0 */
-       if(i != 0)
-               print("mp: bad APBOOTSTRAP\n");
-       *p++ = i;
-       *p = i>>8;
-
-       nvramwrite(0x0F, 0x0A);
-       lapicstartap(apic, PADDR(APBOOTSTRAP));
-       for(i = 0; i < 1000; i++){
-               if(apic->online)
-                       break;
-               delay(10);
-       }
-       nvramwrite(0x0F, 0x00);
-}
-
 void
 mpinit(void)
 {
@@ -295,11 +137,11 @@ mpinit(void)
 
                for(i=0; i<=MaxAPICNO; i++){
                        if(apic = mpapic[i])
-                               print("LAPIC%d: pa=%lux va=%lux flags=%x\n",
-                                       i, apic->paddr, (ulong)apic->addr, apic->flags);
+                               print("LAPIC%d: pa=%lux va=%#p flags=%x\n",
+                                       i, apic->paddr, apic->addr, apic->flags);
                        if(apic = mpioapic[i])
-                               print("IOAPIC%d: pa=%lux va=%lux flags=%x gsibase=%d mre=%d\n",
-                                       i, apic->paddr, (ulong)apic->addr, apic->flags, apic->gsibase, apic->mre);
+                               print("IOAPIC%d: pa=%lux va=%#p flags=%x gsibase=%d mre=%d\n",
+                                       i, apic->paddr, apic->addr, apic->flags, apic->gsibase, apic->mre);
                }
                for(b = mpbus; b; b = b->next){
                        print("BUS%d type=%d flags=%x\n", b->busno, b->type, b->po|b->el);
@@ -327,6 +169,7 @@ mpinit(void)
                return;
        }
        apic->online = 1;
+
        lapicinit(apic);
 
        /*
@@ -339,8 +182,6 @@ mpinit(void)
        intrenable(IrqSPURIOUS, lapicspurious, 0, BUSUNKNOWN, "lapicspurious");
        lapiconline();
 
-       checkmtrr();
-
        /*
         * Initialise the application processors.
         */
@@ -357,6 +198,8 @@ mpinit(void)
        for(i=0; i<nelem(mpapic); i++){
                if((apic = mpapic[i]) == nil)
                        continue;
+               if(apic->machno >= MAXMACH)
+                       continue;
                if(ncpu <= 1)
                        break;
                if((apic->flags & (PcmpBP|PcmpEN)) == PcmpEN){
@@ -373,7 +216,7 @@ mpinit(void)
         *  set conf.copymode here if nmach > 1.
         *  Should look for an ExtINT line and enable it.
         */
-       if(X86FAMILY(m->cpuidax) == 3 || conf.nmach > 1)
+       if(m->cpuidfamily == 3 || conf.nmach > 1)
                conf.copymode = 1;
 }
 
@@ -573,6 +416,65 @@ enum {
        MSIData64 = 0x0C, /* message data register for 64 bit MSI (16 bit) */
 };
 
+enum {
+       HTMSIMapping    = 0xA8,
+       HTMSIFlags      = 0x02,
+       HTMSIFlagsEn    = 0x01,
+};
+
+static int
+htmsicapenable(Pcidev *p)
+{
+       int cap, flags;
+
+       if((cap = pcihtcap(p, HTMSIMapping)) <= 0)
+               return -1;
+       flags = pcicfgr8(p, cap + HTMSIFlags);
+       if((flags & HTMSIFlagsEn) == 0)
+               pcicfgw8(p, cap + HTMSIFlags, flags | HTMSIFlagsEn);
+       return 0;
+}
+
+static int
+htmsienable(Pcidev *pdev)
+{
+       Pcidev *p;
+
+       p = nil;
+       while((p = pcimatch(p, 0x1022, 0)) != nil)
+               if(p->did == 0x1103 || p->did == 0x1203)
+                       break;
+
+       if(p == nil)
+               return 0;       /* not hypertransport platform */
+
+       p = nil;
+       while((p = pcimatch(p, 0x10de, 0)) != nil){
+               switch(p->did){
+               case 0x02f0:    /* NVIDIA NFORCE C51 MEMC0 */
+               case 0x02f1:    /* NVIDIA NFORCE C51 MEMC1 */
+               case 0x02f2:    /* NVIDIA NFORCE C51 MEMC2 */
+               case 0x02f3:    /* NVIDIA NFORCE C51 MEMC3 */
+               case 0x02f4:    /* NVIDIA NFORCE C51 MEMC4 */
+               case 0x02f5:    /* NVIDIA NFORCE C51 MEMC5 */
+               case 0x02f6:    /* NVIDIA NFORCE C51 MEMC6 */
+               case 0x02f7:    /* NVIDIA NFORCE C51 MEMC7 */
+               case 0x0369:    /* NVIDIA NFORCE MCP55 MEMC */
+                       htmsicapenable(p);
+                       break;
+               }
+       }
+
+       if(htmsicapenable(pdev) == 0)
+               return 0;
+
+       for(p = pdev->parent; p != nil; p = p->parent)
+               if(htmsicapenable(p) == 0)
+                       return 0;
+
+       return -1;
+}
+
 static int
 msiintrenable(Vctl *v)
 {
@@ -589,6 +491,8 @@ msiintrenable(Vctl *v)
                print("msiintrenable: could not find Pcidev for tbdf %uX\n", tbdf);
                return -1;
        }
+       if(htmsienable(pci) < 0)
+               return -1;
        cap = pcicap(pci, PciCapMSI);
        if(cap < 0)
                return -1;
@@ -660,29 +564,17 @@ mpintrenable(Vctl* v)
        return -1;
 }
 
-
 void
 mpshutdown(void)
 {
-       static Lock shutdownlock;
-
        /*
-        * To be done...
+        * Park application processors.
         */
-       if(!canlock(&shutdownlock)){
-               /*
-                * If this processor received the CTRL-ALT-DEL from
-                * the keyboard, acknowledge it. Send an INIT to self.
-                */
-#ifdef FIXTHIS
-               if(lapicisr(VectorKBD))
-                       lapiceoi(VectorKBD);
-#endif /* FIX THIS */
+       if(m->machno != 0){
+               splhi();
                arch->introff();
-               idle();
+               for(;;) idle();
        }
-
-       print("apshutdown: active = %#8.8ux\n", active.machs);
        delay(1000);
        splhi();
 
@@ -692,24 +584,4 @@ mpshutdown(void)
        lapicicrw(0, 0x000C0000|ApicINIT);
 
        pcireset();
-       i8042reset();
-
-       /*
-        * Often the BIOS hangs during restart if a conventional 8042
-        * warm-boot sequence is tried. The following is Intel specific and
-        * seems to perform a cold-boot, but at least it comes back.
-        * And sometimes there is no keyboard...
-        *
-        * The reset register (0xcf9) is usually in one of the bridge
-        * chips. The actual location and sequence could be extracted from
-        * ACPI but why bother, this is the end of the line anyway.
-        */
-       print("no kbd; trying bios warm boot...");
-       *(ushort*)KADDR(0x472) = 0x1234;        /* BIOS warm-boot flag */
-       outb(0xCF9, 0x02);
-       outb(0xCF9, 0x06);
-
-       print("can't reset\n");
-       for(;;)
-               idle();
 }