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