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