]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
060f4670e06a9c1eb20b0a5b3da43ff766a76384
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / Ia32 / MpFuncs.asm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2015, 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 ; MpFuncs32.asm
14 ;
15 ; Abstract:
16 ;
17 ; This is the assembly code for MP support
18 ;
19 ;-------------------------------------------------------------------------------
20
21 .686p
22 .model flat
23
24 include MpEqu.inc
25 InitializeFloatingPointUnits PROTO C
26
27 .code
28
29 ;-------------------------------------------------------------------------------------
30 ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
31 ;procedure serializes all the AP processors through an Init sequence. It must be
32 ;noted that APs arrive here very raw...ie: real mode, no stack.
33 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
34 ;IS IN MACHINE CODE.
35 ;-------------------------------------------------------------------------------------
36 RendezvousFunnelProc PROC PUBLIC
37 RendezvousFunnelProcStart::
38 ; At this point CS = 0x(vv00) and ip= 0x0.
39 ; Save BIST information to ebp firstly
40 db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
41
42 db 8ch,0c8h ; mov ax,cs
43 db 8eh,0d8h ; mov ds,ax
44 db 8eh,0c0h ; mov es,ax
45 db 8eh,0d0h ; mov ss,ax
46 db 33h,0c0h ; xor ax,ax
47 db 8eh,0e0h ; mov fs,ax
48 db 8eh,0e8h ; mov gs,ax
49
50 db 0BEh ; opcode of mov si, mem16
51 dw BufferStartLocation ; mov si, BufferStartLocation
52 db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
53
54 db 0BFh ; opcode of mov di, mem16
55 dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
56 db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
57 db 8Bh, 0F8h ; mov di, ax
58 db 83h, 0EFh,06h ; sub di, 06h
59 db 66h, 03h, 0C3h ; add eax, ebx
60 db 66h, 89h, 05h ; mov dword ptr [di],eax
61
62 db 0BEh ; opcode of mov si, mem16
63 dw GdtrLocation ; mov si, GdtrLocation
64 db 66h ; db 66h
65 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
66
67 db 0BEh
68 dw IdtrLocation ; mov si, IdtrLocation
69 db 66h ; db 66h
70 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
71
72 db 33h, 0C0h ; xor ax, ax
73 db 8Eh, 0D8h ; mov ds, ax
74
75 db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
76 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
77 db 0Fh, 22h, 0C0h ; mov cr0, eax
78
79 db 66h, 67h, 0EAh ; far jump
80 dd 0h ; 32-bit offset
81 dw PROTECT_MODE_CS ; 16-bit selector
82
83 Flat32Start:: ; protected mode entry point
84 mov ax, PROTECT_MODE_DS
85 mov ds, ax
86 mov es, ax
87 mov fs, ax
88 mov gs, ax
89 mov ss, ax
90
91 mov esi, ebx
92 mov edi, esi
93 add edi, LockLocation
94 mov eax, NotVacantFlag
95
96 TestLock:
97 xchg dword ptr [edi], eax
98 cmp eax, NotVacantFlag
99 jz TestLock
100
101 mov edi, esi
102 add edi, NumApsExecutingLoction
103 inc dword ptr [edi]
104 mov ebx, dword ptr [edi]
105
106 ProgramStack:
107 mov edi, esi
108 add edi, StackSizeLocation
109 mov eax, dword ptr [edi]
110 mov edi, esi
111 add edi, StackStartAddressLocation
112 add eax, dword ptr [edi]
113 mov esp, eax
114 mov dword ptr [edi], eax
115
116 Releaselock:
117 mov eax, VacantFlag
118 mov edi, esi
119 add edi, LockLocation
120 xchg dword ptr [edi], eax
121
122 CProcedureInvoke:
123 push ebp ; push BIST data at top of AP stack
124 xor ebp, ebp ; clear ebp for call stack trace
125 push ebp
126 mov ebp, esp
127
128 mov eax, InitializeFloatingPointUnits
129 call eax ; Call assembly function to initialize FPU per UEFI spec
130
131 push ebx ; Push NumApsExecuting
132 mov eax, esi
133 add eax, LockLocation
134 push eax ; push address of exchange info data buffer
135
136 mov edi, esi
137 add edi, ApProcedureLocation
138 mov eax, dword ptr [edi]
139
140 call eax ; invoke C function
141
142 jmp $ ; never reach here
143
144 RendezvousFunnelProc ENDP
145 RendezvousFunnelProcEnd::
146
147 AsmCliHltLoop PROC near C PUBLIC
148 cli
149 hlt
150 jmp $-2
151 AsmCliHltLoop ENDP
152
153 ;-------------------------------------------------------------------------------------
154 ; AsmGetAddressMap (&AddressMap);
155 ;-------------------------------------------------------------------------------------
156 AsmGetAddressMap PROC near C PUBLIC
157 pushad
158 mov ebp,esp
159
160 mov ebx, dword ptr [ebp+24h]
161 mov dword ptr [ebx], RendezvousFunnelProcStart
162 mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
163 mov dword ptr [ebx + 8h], 0
164 mov dword ptr [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
165
166 popad
167 ret
168 AsmGetAddressMap ENDP
169
170 PAUSE32 MACRO
171 DB 0F3h
172 DB 090h
173 ENDM
174
175 ;-------------------------------------------------------------------------------------
176 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
177 ;about to become an AP. It switches it'stack with the current AP.
178 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
179 ;-------------------------------------------------------------------------------------
180 AsmExchangeRole PROC near C PUBLIC
181 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
182 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
183 pushad
184 mov ebp,esp
185
186 ; esi contains MyInfo pointer
187 mov esi, dword ptr [ebp+24h]
188
189 ; edi contains OthersInfo pointer
190 mov edi, dword ptr [ebp+28h]
191
192 ;Store EFLAGS, GDTR and IDTR register to stack
193 pushfd
194 mov eax, cr4
195 push eax ; push cr4 firstly
196 mov eax, cr0
197 push eax
198
199 sgdt fword ptr [esi+8]
200 sidt fword ptr [esi+14]
201
202 ; Store the its StackPointer
203 mov dword ptr [esi+4],esp
204
205 ; update its switch state to STORED
206 mov byte ptr [esi], CPU_SWITCH_STATE_STORED
207
208 WaitForOtherStored:
209 ; wait until the other CPU finish storing its state
210 cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
211 jz OtherStored
212 PAUSE32
213 jmp WaitForOtherStored
214
215 OtherStored:
216 ; Since another CPU already stored its state, load them
217 ; load GDTR value
218 lgdt fword ptr [edi+8]
219
220 ; load IDTR value
221 lidt fword ptr [edi+14]
222
223 ; load its future StackPointer
224 mov esp, dword ptr [edi+4]
225
226 ; update the other CPU's switch state to LOADED
227 mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
228
229 WaitForOtherLoaded:
230 ; wait until the other CPU finish loading new state,
231 ; otherwise the data in stack may corrupt
232 cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
233 jz OtherLoaded
234 PAUSE32
235 jmp WaitForOtherLoaded
236
237 OtherLoaded:
238 ; since the other CPU already get the data it want, leave this procedure
239 pop eax
240 mov cr0, eax
241 pop eax
242 mov cr4, eax
243 popfd
244
245 popad
246 ret
247 AsmExchangeRole ENDP
248
249 AsmInitializeGdt PROC near C PUBLIC
250 push ebp
251 mov ebp, esp
252 pushad
253 mov edi, [ebp + 8] ; Load GDT register
254
255 mov ax,cs ; Get the selector data from our code image
256 mov es,ax
257 lgdt FWORD PTR es:[edi] ; and update the GDTR
258
259 push PROTECT_MODE_CS
260 lea eax, SetCodeSelectorFarJump
261 push eax
262 retf
263 SetCodeSelectorFarJump:
264 mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
265 mov ds, ax
266 mov es, ax
267 mov fs, ax
268 mov gs, ax
269 mov ss, ax
270
271 popad
272 pop ebp
273 ret
274 AsmInitializeGdt ENDP
275
276 END