]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
8f6f0bfd5b935b297fc34a0b73c86c9ffcd39f2e
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / Ia32 / MpFuncs.nasm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
7 ;
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 ;
11 ; Module Name:
12 ;
13 ; MpFuncs.nasm
14 ;
15 ; Abstract:
16 ;
17 ; This is the assembly code for MP support
18 ;
19 ;-------------------------------------------------------------------------------
20
21 %include "MpEqu.inc"
22 extern ASM_PFX(InitializeFloatingPointUnits)
23
24 SECTION .text
25
26 ;-------------------------------------------------------------------------------------
27 ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
28 ;procedure serializes all the AP processors through an Init sequence. It must be
29 ;noted that APs arrive here very raw...ie: real mode, no stack.
30 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
31 ;IS IN MACHINE CODE.
32 ;-------------------------------------------------------------------------------------
33 global ASM_PFX(RendezvousFunnelProc)
34 ASM_PFX(RendezvousFunnelProc):
35 RendezvousFunnelProcStart:
36 ; At this point CS = 0x(vv00) and ip= 0x0.
37 BITS 16
38 mov ebp, eax ; save BIST information
39
40 mov ax, cs
41 mov ds, ax
42 mov es, ax
43 mov ss, ax
44 xor ax, ax
45 mov fs, ax
46 mov gs, ax
47
48 mov si, BufferStartLocation
49 mov ebx, [si]
50
51 mov si, ModeOffsetLocation
52 mov eax, [si]
53 mov si, CodeSegmentLocation
54 mov edx, [si]
55 mov di, ax
56 sub di, 02h
57 mov [di], dx
58 sub di, 04h
59 add eax, ebx
60 mov [di],eax
61
62 mov si, DataSegmentLocation
63 mov edx, [si]
64
65 mov si, GdtrLocation
66 o32 lgdt [cs:si]
67
68 mov si, IdtrLocation
69 o32 lidt [cs:si]
70
71 xor ax, ax
72 mov ds, ax
73
74 mov eax, cr0 ; Get control register 0
75 or eax, 000000003h ; Set PE bit (bit #0) & MP
76 mov cr0, eax
77
78 jmp 0:strict dword 0 ; far jump to protected mode
79 BITS 32
80 Flat32Start: ; protected mode entry point
81 mov ds, dx
82 mov es, dx
83 mov fs, dx
84 mov gs, dx
85 mov ss, dx
86
87 mov esi, ebx
88
89 mov edi, esi
90 add edi, EnableExecuteDisableLocation
91 cmp byte [edi], 0
92 jz SkipEnableExecuteDisable
93
94 ;
95 ; Enable IA32 PAE execute disable
96 ;
97
98 mov ecx, 0xc0000080
99 rdmsr
100 bts eax, 11
101 wrmsr
102
103 mov edi, esi
104 add edi, Cr3Location
105 mov eax, dword [edi]
106 mov cr3, eax
107
108 mov eax, cr4
109 bts eax, 5
110 mov cr4, eax
111
112 mov eax, cr0
113 bts eax, 31
114 mov cr0, eax
115
116 SkipEnableExecuteDisable:
117
118 mov edi, esi
119 add edi, LockLocation
120 mov eax, NotVacantFlag
121
122 TestLock:
123 xchg [edi], eax
124 cmp eax, NotVacantFlag
125 jz TestLock
126
127 mov edi, esi
128 add edi, NumApsExecutingLocation
129 inc dword [edi]
130 mov ebx, [edi]
131
132 ProgramStack:
133 mov edi, esi
134 add edi, StackSizeLocation
135 mov eax, [edi]
136 mov edi, esi
137 add edi, StackStartAddressLocation
138 add eax, [edi]
139 mov esp, eax
140 mov [edi], eax
141
142 Releaselock:
143 mov eax, VacantFlag
144 mov edi, esi
145 add edi, LockLocation
146 xchg [edi], eax
147
148 CProcedureInvoke:
149 push ebp ; push BIST data at top of AP stack
150 xor ebp, ebp ; clear ebp for call stack trace
151 push ebp
152 mov ebp, esp
153
154 mov eax, ASM_PFX(InitializeFloatingPointUnits)
155 call eax ; Call assembly function to initialize FPU per UEFI spec
156
157 push ebx ; Push NumApsExecuting
158 mov eax, esi
159 add eax, LockLocation
160 push eax ; push address of exchange info data buffer
161
162 mov edi, esi
163 add edi, ApProcedureLocation
164 mov eax, [edi]
165
166 call eax ; Invoke C function
167
168 jmp $ ; Never reach here
169 RendezvousFunnelProcEnd:
170
171 ;-------------------------------------------------------------------------------------
172 ; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);
173 ;-------------------------------------------------------------------------------------
174 global ASM_PFX(AsmRelocateApLoop)
175 ASM_PFX(AsmRelocateApLoop):
176 AsmRelocateApLoopStart:
177 cmp byte [esp + 4], 1
178 jnz HltLoop
179 MwaitLoop:
180 mov eax, esp
181 xor ecx, ecx
182 xor edx, edx
183 monitor
184 mov eax, [esp + 8] ; Mwait Cx, Target C-State per eax[7:4]
185 shl eax, 4
186 mwait
187 jmp MwaitLoop
188 HltLoop:
189 cli
190 hlt
191 jmp HltLoop
192 ret
193 AsmRelocateApLoopEnd:
194
195 ;-------------------------------------------------------------------------------------
196 ; AsmGetAddressMap (&AddressMap);
197 ;-------------------------------------------------------------------------------------
198 global ASM_PFX(AsmGetAddressMap)
199 ASM_PFX(AsmGetAddressMap):
200 pushad
201 mov ebp,esp
202
203 mov ebx, [ebp + 24h]
204 mov dword [ebx], RendezvousFunnelProcStart
205 mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
206 mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
207 mov dword [ebx + 0Ch], AsmRelocateApLoopStart
208 mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
209
210 popad
211 ret
212
213 ;-------------------------------------------------------------------------------------
214 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
215 ;about to become an AP. It switches it'stack with the current AP.
216 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
217 ;-------------------------------------------------------------------------------------
218 global ASM_PFX(AsmExchangeRole)
219 ASM_PFX(AsmExchangeRole):
220 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
221 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
222 pushad
223 mov ebp,esp
224
225 ; esi contains MyInfo pointer
226 mov esi, [ebp + 24h]
227
228 ; edi contains OthersInfo pointer
229 mov edi, [ebp + 28h]
230
231 ;Store EFLAGS, GDTR and IDTR register to stack
232 pushfd
233 mov eax, cr4
234 push eax ; push cr4 firstly
235 mov eax, cr0
236 push eax
237
238 sgdt [esi + 8]
239 sidt [esi + 14]
240
241 ; Store the its StackPointer
242 mov [esi + 4],esp
243
244 ; update its switch state to STORED
245 mov byte [esi], CPU_SWITCH_STATE_STORED
246
247 WaitForOtherStored:
248 ; wait until the other CPU finish storing its state
249 cmp byte [edi], CPU_SWITCH_STATE_STORED
250 jz OtherStored
251 pause
252 jmp WaitForOtherStored
253
254 OtherStored:
255 ; Since another CPU already stored its state, load them
256 ; load GDTR value
257 lgdt [edi + 8]
258
259 ; load IDTR value
260 lidt [edi + 14]
261
262 ; load its future StackPointer
263 mov esp, [edi + 4]
264
265 ; update the other CPU's switch state to LOADED
266 mov byte [edi], CPU_SWITCH_STATE_LOADED
267
268 WaitForOtherLoaded:
269 ; wait until the other CPU finish loading new state,
270 ; otherwise the data in stack may corrupt
271 cmp byte [esi], CPU_SWITCH_STATE_LOADED
272 jz OtherLoaded
273 pause
274 jmp WaitForOtherLoaded
275
276 OtherLoaded:
277 ; since the other CPU already get the data it want, leave this procedure
278 pop eax
279 mov cr0, eax
280 pop eax
281 mov cr4, eax
282 popfd
283
284 popad
285 ret