FreeBSD/Linux Kernel Cross Reference
sys/pc/apbootstrap.s
1 /*
2 * Start an Application Processor. This must be placed on a 4KB boundary
3 * somewhere in the 1st MB of conventional memory (APBOOTSTRAP). However,
4 * due to some shortcuts below it's restricted further to within the 1st
5 * 64KB. The AP starts in real-mode, with
6 * CS selector set to the startup memory address/16;
7 * CS base set to startup memory address;
8 * CS limit set to 64KB;
9 * CPL and IP set to 0.
10 */
11 #include "mem.h"
12
13 #define NOP BYTE $0x90 /* NOP */
14 #define LGDT(gdtptr) BYTE $0x0F; /* LGDT */ \
15 BYTE $0x01; BYTE $0x16; \
16 WORD $gdtptr
17 #define FARJUMP16(s, o) BYTE $0xEA; /* far jump to ptr16:16 */ \
18 WORD $o; WORD $s; \
19 NOP; NOP; NOP
20 #define FARJUMP32(s, o) BYTE $0x66; /* far jump to ptr32:16 */ \
21 BYTE $0xEA; LONG $o; WORD $s
22
23 #define DELAY BYTE $0xEB; /* JMP .+2 */ \
24 BYTE $0x00
25 #define INVD BYTE $0x0F; BYTE $0x08
26 #define WBINVD BYTE $0x0F; BYTE $0x09
27
28 /*
29 * Macros for calculating offsets within the page directory base
30 * and page tables. Note that these are assembler-specific hence
31 * the '<<2'.
32 */
33 #define PDO(a) (((((a))>>22) & 0x03FF)<<2)
34 #define PTO(a) (((((a))>>12) & 0x03FF)<<2)
35
36 TEXT apbootstrap(SB), $0
37 FARJUMP16(0, _apbootstrap(SB))
38 TEXT _apvector(SB), $0 /* address APBOOTSTRAP+0x08 */
39 LONG $0
40 TEXT _appdb(SB), $0 /* address APBOOTSTRAP+0x0C */
41 LONG $0
42 TEXT _apapic(SB), $0 /* address APBOOTSTRAP+0x10 */
43 LONG $0
44 TEXT _apbootstrap(SB), $0 /* address APBOOTSTRAP+0x14 */
45 MOVW CS, AX
46 MOVW AX, DS /* initialise DS */
47
48 LGDT(gdtptr(SB)) /* load a basic gdt */
49
50 MOVL CR0, AX
51 ORL $1, AX
52 MOVL AX, CR0 /* turn on protected mode */
53 DELAY /* JMP .+2 */
54
55 BYTE $0xB8; WORD $SELECTOR(1, SELGDT, 0)/* MOVW $SELECTOR(1, SELGDT, 0), AX */
56 MOVW AX, DS
57 MOVW AX, ES
58 MOVW AX, FS
59 MOVW AX, GS
60 MOVW AX, SS
61
62 FARJUMP32(SELECTOR(2, SELGDT, 0), _ap32-KZERO(SB))
63
64 /*
65 * For Pentiums and higher, the code that enables paging must come from
66 * pages that are identity mapped.
67 * To this end double map KZERO at virtual 0 and undo the mapping once virtual
68 * nirvana has been obtained.
69 */
70 TEXT _ap32(SB), $0
71 MOVL _appdb-KZERO(SB), CX /* physical address of PDB */
72 MOVL (PDO(KZERO))(CX), DX /* double-map KZERO at 0 */
73 MOVL DX, (PDO(0))(CX)
74 MOVL CX, CR3 /* load and flush the mmu */
75
76 MOVL CR0, DX
77 ORL $0x80010000, DX /* PG|WP */
78 ANDL $~0x6000000A, DX /* ~(CD|NW|TS|MP) */
79
80 MOVL $_appg(SB), AX
81 MOVL DX, CR0 /* turn on paging */
82 JMP* AX
83
84 TEXT _appg(SB), $0
85 MOVL CX, AX /* physical address of PDB */
86 ORL $KZERO, AX
87 MOVL $0, (PDO(0))(AX) /* undo double-map of KZERO at 0 */
88 MOVL CX, CR3 /* load and flush the mmu */
89
90 MOVL $(MACHADDR+MACHSIZE-4), SP
91
92 MOVL $0, AX
93 PUSHL AX
94 POPFL
95
96 MOVL _apapic(SB), AX
97 MOVL AX, (SP)
98 MOVL _apvector(SB), AX
99 CALL* AX
100 _aphalt:
101 HLT
102 JMP _aphalt
103
104 TEXT gdt(SB), $0
105 LONG $0x0000; LONG $0
106 LONG $0xFFFF; LONG $(SEGG|SEGB|(0xF<<16)|SEGP|SEGPL(0)|SEGDATA|SEGW)
107 LONG $0xFFFF; LONG $(SEGG|SEGD|(0xF<<16)|SEGP|SEGPL(0)|SEGEXEC|SEGR)
108 TEXT gdtptr(SB), $0
109 WORD $(3*8-1)
110 LONG $gdt-KZERO(SB)
Cache object: a73da83ef7133bfc573adfb313e784c1
|