]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc64/squidboy.c
pc, pc64: make mtrr() callable from interrupt context and before mpinit
[plan9front.git] / sys / src / 9 / pc64 / squidboy.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "ureg.h"
8
9 #include "mp.h"
10
11 static void
12 squidboy(Apic* apic)
13 {
14         machinit();
15         mmuinit();
16         cpuidentify();
17         cpuidprint();
18         apic->online = 1;
19         coherence();
20
21         lapicinit(apic);
22         lapiconline();
23         syncclock();
24         timersinit();
25
26         lock(&active);
27         active.machs |= 1<<m->machno;
28         unlock(&active);
29
30         while(!active.thunderbirdsarego)
31                 microdelay(100);
32
33         schedinit();
34 }
35
36 void
37 mpstartap(Apic* apic)
38 {
39         uintptr *apbootp, *pml4, *pdp0;
40         Segdesc *gdt;
41         Mach *mach;
42         uchar *p;
43         int i;
44
45         /*
46          * Initialise the AP page-tables and Mach structure.
47          * Xspanalloc will panic if an allocation can't be made.
48          */
49         p = xspanalloc(2*PTSZ + BY2PG + MACHSIZE, BY2PG, 0);
50         pml4 = (uintptr*)p;
51         p += PTSZ;
52         pdp0 = (uintptr*)p;
53         p += PTSZ;
54         gdt = (Segdesc*)p;
55         p += BY2PG;
56         mach = (Mach*)p;
57
58         memset(pml4, 0, PTSZ);
59         memset(pdp0, 0, PTSZ);
60         memset(gdt, 0, BY2PG);
61         memset(mach, 0, MACHSIZE);
62
63         mach->machno = apic->machno;
64         mach->pml4 = pml4;
65         mach->gdt  = gdt;       /* filled by mmuinit */
66         MACHP(mach->machno) = mach;
67
68         /*
69          * map KZERO (note that we share the KZERO (and VMAP)
70          * PDP between processors.
71          */
72         pml4[PTLX(KZERO, 3)] = MACHP(0)->pml4[PTLX(KZERO, 3)];
73         pml4[PTLX(VMAP, 3)] = MACHP(0)->pml4[PTLX(VMAP, 3)];
74
75         /* double map */
76         pml4[0] = PADDR(pdp0) | PTEWRITE|PTEVALID;
77         pdp0[0] = *mmuwalk(pml4, KZERO, 2, 0);
78
79         /*
80          * Tell the AP where its kernel vector and pdb are.
81          * The offsets are known in the AP bootstrap code.
82          */
83         apbootp = (uintptr*)(APBOOTSTRAP+0x08);
84         apbootp[0] = (uintptr)squidboy; /* assembler jumps here eventually */
85         apbootp[1] = (uintptr)PADDR(pml4);
86         apbootp[2] = (uintptr)apic;
87         apbootp[3] = (uintptr)mach;
88
89         /*
90          * Universal Startup Algorithm.
91          */
92         p = KADDR(0x467);               /* warm-reset vector */
93         *p++ = PADDR(APBOOTSTRAP);
94         *p++ = PADDR(APBOOTSTRAP)>>8;
95         i = (PADDR(APBOOTSTRAP) & ~0xFFFF)/16;
96         /* code assumes i==0 */
97         if(i != 0)
98                 print("mp: bad APBOOTSTRAP\n");
99         *p++ = i;
100         *p = i>>8;
101         coherence();
102
103         nvramwrite(0x0F, 0x0A);         /* shutdown code: warm reset upon init ipi */
104         lapicstartap(apic, PADDR(APBOOTSTRAP));
105         for(i = 0; i < 1000; i++){
106                 if(apic->online)
107                         break;
108                 delay(10);
109         }
110         nvramwrite(0x0F, 0x00);
111 }