]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/tramp-mp.S
88893a5bd5a63e30301ad012233cd130c05034d4
[l4.git] / kernel / fiasco / src / kern / ia32 / tramp-mp.S
1 /* -*- c -*- */
2 #include "config_gdt.h"
3 #include "tcboffset.h"
4 #include "linking.h"
5
6 #define OFFS(x) ((x)-(_tramp_mp_entry))
7 #define PHYS(x) (x)
8
9 #ifdef CONFIG_AMD64
10 # define CX rcx
11 # define SP rsp
12 #else
13 # define CX ecx
14 # define SP esp
15 #endif
16
17 #define CPU_NR_COUNTER (config_num_ap_cpus)
18
19         .section .mp_tramp , "awx", @progbits
20 #ifndef CONFIG_PF_UX
21         .code16
22         .p2align 12
23 #endif
24         .global _tramp_mp_entry
25 _tramp_mp_entry:
26
27     /* Basic setup of the processor (stack not yet needed) */
28 #ifndef CONFIG_PF_UX
29         cli
30         cld
31         movw    %cs, %ax
32         movw    %ax, %ds
33
34     /* Switch to protected mode (needed to read APIC-ID) */
35         lgdtl   OFFS(_tramp_mp_init_gdt_pdesc)
36         movl    %cr0, %eax
37         orl     $0x00000001, %eax
38         movl    %eax, %cr0
39         ljmpl   $0x08, $PHYS(_tramp_mp_entry32)
40
41         .code32
42 _tramp_mp_entry32:
43         movw    $0x10, %ax
44         movw    %ax, %ds
45
46     /* Initialize paging, needs linear mapping of this page! (first 4MB are linear mapped, due to lucky cirumstances) */
47         movl    PHYS(_tramp_mp_startup_pdbr), %eax
48         movl    %eax, %cr3
49         // Initialize cr4 before, because we may run on a 4MB-page and need the extension enabled before
50         movl    PHYS(_tramp_mp_startup_cr4), %eax
51         movl    %eax, %cr4
52
53 #ifdef CONFIG_AMD64
54         mov %edx, %edi
55         mov $0xc0000080, %ecx
56         rdmsr
57         bts $8,%eax
58         wrmsr
59         mov %edi, %edx
60         
61         movl    PHYS(_tramp_mp_startup_cr0), %eax
62         movl    %eax, %cr0
63
64         ljmpl   $0x18, $PHYS(_tramp_mp_entry64)
65
66         .code64
67 _tramp_mp_entry64:
68         jmp     *PHYS(_ptr_64virt)
69
70         .align 8
71 _ptr_64virt:
72         .quad _entry_64virt
73
74 _entry_64virt:
75 #endif /* AMD64 */
76     /* Reinitialize the gdt, reloads segments with kernel values */
77         lgdt    PHYS(_tramp_mp_startup_gdt_pdesc)
78 #ifndef CONFIG_AMD64
79         movl    PHYS(_tramp_mp_startup_cr0), %eax
80         movl    %eax, %cr0
81         ljmp    $GDT_CODE_KERNEL, $1f
82 1:      movw    $GDT_DATA_KERNEL, %ax
83         movw    %ax, %ds
84         movw    %ax, %es
85         movw    %ax, %ss
86 #endif /* ! AMD64 */
87 #endif /* ! UX */
88
89     /* Increase CPU counter */
90 1:      mov     CPU_NR_COUNTER, %eax
91         mov     %eax, %edi
92         inc     %edi
93         lock    ; cmpxchg %edi, CPU_NR_COUNTER
94         jnz     1b
95
96     /* Acquire spinlock */
97 1:      cmpl $0, _tramp_mp_spinlock
98         je 2f
99         pause
100         jmp 1b
101 2:      mov $2, %CX
102         xchg _tramp_mp_spinlock, %CX
103         cmp $0, %CX
104         jne 1b
105
106         /* we've the lock, can run on the init_stack */
107         mov $_tramp_mp_init_stack_top, %SP
108         mov %edi, %eax /* IA32: cpu-num in %eax, AMD64: %rdi */
109         jmp BOOT_AP_CPU
110
111
112 #ifndef CONFIG_PF_UX
113   /*
114    * Pseudo_descriptor for the initial GDT
115    */
116         .align 4
117 _tramp_mp_init_gdt_pdesc:
118         .word 0x1f
119         .long PHYS(_tramp_mp_init_gdt)
120         .word 0
121
122   /*
123    * Initial GDT, used for switch to protected mode, will be
124    * used only until startup sequence (from this point we use
125    * the OS provided GDT).
126    */
127         .align 8
128 _tramp_mp_init_gdt:
129         .long 0x00000000, 0x00000000 /* dummy                */
130         .long 0x0000FFFF, 0x00CF9A00 /* r-x/0..4GB/PL0/32bit */
131         .long 0x0000FFFF, 0x00CF9200 /* rw-/0..4GB/PL0/32bit */
132         .long 0x0000FFFF, 0x00AF9B00 /* r-x/0..4GB/PL0/64bit */
133
134 .global _tramp_mp_startup_cr0
135 _tramp_mp_startup_cr0:
136         .quad 0x00000000
137
138 .global _tramp_mp_startup_cr4
139 _tramp_mp_startup_cr4:
140         .quad 0x00000000
141
142 .global _tramp_mp_startup_pdbr
143 _tramp_mp_startup_pdbr:
144         .quad 0x00000000
145
146 .global _tramp_mp_startup_gdt_pdesc
147 _tramp_mp_startup_gdt_pdesc:
148         .quad 0
149         .quad 0
150 #endif /* ! UX */
151
152 .global _tramp_mp_spinlock
153 _tramp_mp_spinlock:
154         .quad 0
155
156         .align 16
157 _tramp_mp_init_stack:
158 #ifdef CONFIG_PF_UX
159         /* glibc *printf-functions */
160         .space 4096
161 #else
162         .space 2048
163 #endif
164 _tramp_mp_init_stack_top:
165