1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <asm/global_data.h>
15#include <asm/msr-index.h>
16#include <asm/processor.h>
17#include <asm/processor-flags.h>
18#include <asm/sipi.h>
19
20#define CODE_SEG (X86_GDT_ENTRY_32BIT_CS * X86_GDT_ENTRY_SIZE)
21#define DATA_SEG (X86_GDT_ENTRY_32BIT_DS * X86_GDT_ENTRY_SIZE)
22
23
24
25
26
27
28
29
30
31
32
33
34.text
35.code16
36.globl ap_start16
37ap_start16:
38 cli
39 xorl %eax, %eax
40 movl %eax, %cr3
41
42
43 movw %cs, %ax
44 movw %ax, %ds
45
46
47 movl $gdtaddr, %ebx
48 subl $ap_start16, %ebx
49
50 data32 lgdt (%ebx)
51
52 movl %cr0, %eax
53 andl $(~(X86_CR0_PG | X86_CR0_AM | X86_CR0_WP | X86_CR0_NE | \
54 X86_CR0_TS | X86_CR0_EM | X86_CR0_MP)), %eax
55 orl $(X86_CR0_NW | X86_CR0_CD | X86_CR0_PE), %eax
56 movl %eax, %cr0
57
58 movl $ap_start_jmp, %eax
59 subl $ap_start16, %eax
60 movw %ax, %bp
61
62
63data32 cs ljmp *(%bp)
64
65 .align 4
66.globl sipi_params_16bit
67sipi_params_16bit:
68
69ap_start_jmp:
70 .long 0
71 .word CODE_SEG
72
73 .word 0
74gdtaddr:
75 .word 0
76 .long 0
77 .word 0
78
79.globl ap_start16_code_end
80ap_start16_code_end:
81
82
83
84
85
86.globl ap_start
87ap_start:
88 .code32
89 movw $DATA_SEG, %ax
90 movw %ax, %ds
91 movw %ax, %es
92 movw %ax, %ss
93 movw %ax, %gs
94
95 movw $(X86_GDT_ENTRY_32BIT_FS * X86_GDT_ENTRY_SIZE), %ax
96 movw %ax, %fs
97
98
99 mov idt_ptr, %ebx
100 lidt (%ebx)
101
102
103 movl ap_count, %eax
1041:
105 movl %eax, %ecx
106 inc %ecx
107 lock cmpxchg %ecx, ap_count
108 jnz 1b
109
110
111 movl stack_size, %eax
112 mul %ecx
113 movl stack_top, %edx
114 subl %eax, %edx
115 mov %edx, %esp
116
117 mov %ecx, %esi
118
119
120 mov microcode_ptr, %edi
121 test %edi, %edi
122 jz microcode_done
123
124
125 mov $1, %eax
126 cpuid
127 mov $MSR_IA32_UCODE_REV, %ecx
128 rdmsr
129
130 test %edx, %edx
131 jnz microcode_done
132
133
134 cmpl $0xffffffff, microcode_lock
135 je load_microcode
136
137
138lock_microcode:
139 lock btsl $0, microcode_lock
140 jc lock_microcode
141
142load_microcode:
143
144 mov $MSR_IA32_UCODE_WRITE, %ecx
145 xor %edx, %edx
146 mov %edi, %eax
147
148
149
150
151 add $UCODE_HEADER_LEN, %eax
152 pusha
153 wrmsr
154 popa
155
156
157 cmpl $0xffffffff, microcode_lock
158 je microcode_done
159
160 xor %eax, %eax
161 mov %eax, microcode_lock
162
163microcode_done:
164
165
166
167
168
169
170
171 mov msr_table_ptr, %edi
172 mov msr_count, %ebx
173 test %ebx, %ebx
174 jz 1f
175load_msr:
176 mov (%edi), %ecx
177 mov 4(%edi), %eax
178 mov 8(%edi), %edx
179 wrmsr
180 add $12, %edi
181 dec %ebx
182 jnz load_msr
183
1841:
185
186 mov %cr0, %eax
187 andl $(~(X86_CR0_CD | X86_CR0_NW)), %eax
188 mov %eax, %cr0
189
190
191 movl %esi, %eax
192 mov c_handler, %esi
193 call *%esi
194
195
196 .align 4
197.globl sipi_params
198sipi_params:
199idt_ptr:
200 .long 0
201stack_top:
202 .long 0
203stack_size:
204 .long 0
205microcode_lock:
206 .long 0
207microcode_ptr:
208 .long 0
209msr_table_ptr:
210 .long 0
211msr_count:
212 .long 0
213c_handler:
214 .long 0
215ap_count:
216 .long 0
217