]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
63c80489f4fb0d7fb744be2e679ca96396ef28f9
[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 ;-------------------------------------------------------------------------------------
148 ; AsmGetAddressMap (&AddressMap);
149 ;-------------------------------------------------------------------------------------
150 AsmGetAddressMap PROC near C PUBLIC
151 pushad
152 mov ebp,esp
153
154 mov ebx, dword ptr [ebp+24h]
155 mov dword ptr [ebx], RendezvousFunnelProcStart
156 mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
157 mov dword ptr [ebx + 8h], 0
158 mov dword ptr [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
159
160 popad
161 ret
162 AsmGetAddressMap ENDP
163
164 PAUSE32 MACRO
165 DB 0F3h
166 DB 090h
167 ENDM
168
169 ;-------------------------------------------------------------------------------------
170 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
171 ;about to become an AP. It switches it'stack with the current AP.
172 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
173 ;-------------------------------------------------------------------------------------
174 AsmExchangeRole PROC near C PUBLIC
175 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
176 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
177 pushad
178 mov ebp,esp
179
180 ; esi contains MyInfo pointer
181 mov esi, dword ptr [ebp+24h]
182
183 ; edi contains OthersInfo pointer
184 mov edi, dword ptr [ebp+28h]
185
186 ;Store EFLAGS, GDTR and IDTR register to stack
187 pushfd
188 mov eax, cr4
189 push eax ; push cr4 firstly
190 mov eax, cr0
191 push eax
192
193 sgdt fword ptr [esi+8]
194 sidt fword ptr [esi+14]
195
196 ; Store the its StackPointer
197 mov dword ptr [esi+4],esp
198
199 ; update its switch state to STORED
200 mov byte ptr [esi], CPU_SWITCH_STATE_STORED
201
202 WaitForOtherStored:
203 ; wait until the other CPU finish storing its state
204 cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
205 jz OtherStored
206 PAUSE32
207 jmp WaitForOtherStored
208
209 OtherStored:
210 ; Since another CPU already stored its state, load them
211 ; load GDTR value
212 lgdt fword ptr [edi+8]
213
214 ; load IDTR value
215 lidt fword ptr [edi+14]
216
217 ; load its future StackPointer
218 mov esp, dword ptr [edi+4]
219
220 ; update the other CPU's switch state to LOADED
221 mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
222
223 WaitForOtherLoaded:
224 ; wait until the other CPU finish loading new state,
225 ; otherwise the data in stack may corrupt
226 cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
227 jz OtherLoaded
228 PAUSE32
229 jmp WaitForOtherLoaded
230
231 OtherLoaded:
232 ; since the other CPU already get the data it want, leave this procedure
233 pop eax
234 mov cr0, eax
235 pop eax
236 mov cr4, eax
237 popfd
238
239 popad
240 ret
241 AsmExchangeRole ENDP
242
243 AsmInitializeGdt PROC near C PUBLIC
244 push ebp
245 mov ebp, esp
246 pushad
247 mov edi, [ebp + 8] ; Load GDT register
248
249 mov ax,cs ; Get the selector data from our code image
250 mov es,ax
251 lgdt FWORD PTR es:[edi] ; and update the GDTR
252
253 push PROTECT_MODE_CS
254 lea eax, SetCodeSelectorFarJump
255 push eax
256 retf
257 SetCodeSelectorFarJump:
258 mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too
259 mov ds, ax
260 mov es, ax
261 mov fs, ax
262 mov gs, ax
263 mov ss, ax
264
265 popad
266 pop ebp
267 ret
268 AsmInitializeGdt ENDP
269
270 END