]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / Ia32 / MpFuncs.asm
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 ; 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 0BEh ; opcode of mov si, mem16
55 dw ModeOffsetLocation ; mov si, ModeOffsetLocation
56 db 66h, 8Bh, 04h ; mov eax, [si]
57 db 0BEh ; opcode of mov si, mem16
58 dw CodeSegmentLocation ; mov si, CodeSegmentLocation
59 db 66h, 8Bh, 14h ; mov edx, [si]
60 db 89h, 0C7h ; mov di, ax
61 db 83h, 0EFh, 02h ; sub di, 02h
62 db 89h, 15h ; mov [di], dx
63 db 83h, 0EFh, 04h ; sub di, 04h
64 db 66h, 01h, 0D8h ; add eax, ebx
65 db 66h, 89h, 05h ; mov [di], eax
66
67 db 0BEh ; opcode of mov si, mem16
68 dw DataSegmentLocation ; mov si, DataSegmentLocation
69 db 66h, 8Bh, 14h ; mov edx, [si]
70
71 db 0BEh ; opcode of mov si, mem16
72 dw GdtrLocation ; mov si, GdtrLocation
73 db 66h ; db 66h
74 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
75
76 db 0BEh
77 dw IdtrLocation ; mov si, IdtrLocation
78 db 66h ; db 66h
79 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
80
81 db 33h, 0C0h ; xor ax, ax
82 db 8Eh, 0D8h ; mov ds, ax
83
84 db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
85 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
86 db 0Fh, 22h, 0C0h ; mov cr0, eax
87
88 db 66h, 67h, 0EAh ; far jump
89 dd 0h ; 32-bit offset
90 dw 0h ; 16-bit selector
91
92 Flat32Start:: ; protected mode entry point
93 mov ds, dx
94 mov es, dx
95 mov fs, dx
96 mov gs, dx
97 mov ss, dx
98
99 mov esi, ebx
100 mov edi, esi
101 add edi, LockLocation
102 mov eax, NotVacantFlag
103
104 TestLock:
105 xchg dword ptr [edi], eax
106 cmp eax, NotVacantFlag
107 jz TestLock
108
109 mov edi, esi
110 add edi, NumApsExecutingLoction
111 inc dword ptr [edi]
112 mov ebx, dword ptr [edi]
113
114 ProgramStack:
115 mov edi, esi
116 add edi, StackSizeLocation
117 mov eax, dword ptr [edi]
118 mov edi, esi
119 add edi, StackStartAddressLocation
120 add eax, dword ptr [edi]
121 mov esp, eax
122 mov dword ptr [edi], eax
123
124 Releaselock:
125 mov eax, VacantFlag
126 mov edi, esi
127 add edi, LockLocation
128 xchg dword ptr [edi], eax
129
130 CProcedureInvoke:
131 push ebp ; push BIST data at top of AP stack
132 xor ebp, ebp ; clear ebp for call stack trace
133 push ebp
134 mov ebp, esp
135
136 mov eax, InitializeFloatingPointUnits
137 call eax ; Call assembly function to initialize FPU per UEFI spec
138
139 push ebx ; Push NumApsExecuting
140 mov eax, esi
141 add eax, LockLocation
142 push eax ; push address of exchange info data buffer
143
144 mov edi, esi
145 add edi, ApProcedureLocation
146 mov eax, dword ptr [edi]
147
148 call eax ; invoke C function
149
150 jmp $ ; never reach here
151
152 RendezvousFunnelProc ENDP
153 RendezvousFunnelProcEnd::
154
155 ;-------------------------------------------------------------------------------------
156 ; AsmGetAddressMap (&AddressMap);
157 ;-------------------------------------------------------------------------------------
158 AsmGetAddressMap PROC near C PUBLIC
159 pushad
160 mov ebp,esp
161
162 mov ebx, dword ptr [ebp+24h]
163 mov dword ptr [ebx], RendezvousFunnelProcStart
164 mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
165 mov dword ptr [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
166
167 popad
168 ret
169 AsmGetAddressMap ENDP
170
171 PAUSE32 MACRO
172 DB 0F3h
173 DB 090h
174 ENDM
175
176 ;-------------------------------------------------------------------------------------
177 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
178 ;about to become an AP. It switches it'stack with the current AP.
179 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
180 ;-------------------------------------------------------------------------------------
181 AsmExchangeRole PROC near C PUBLIC
182 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
183 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
184 pushad
185 mov ebp,esp
186
187 ; esi contains MyInfo pointer
188 mov esi, dword ptr [ebp+24h]
189
190 ; edi contains OthersInfo pointer
191 mov edi, dword ptr [ebp+28h]
192
193 ;Store EFLAGS, GDTR and IDTR register to stack
194 pushfd
195 mov eax, cr4
196 push eax ; push cr4 firstly
197 mov eax, cr0
198 push eax
199
200 sgdt fword ptr [esi+8]
201 sidt fword ptr [esi+14]
202
203 ; Store the its StackPointer
204 mov dword ptr [esi+4],esp
205
206 ; update its switch state to STORED
207 mov byte ptr [esi], CPU_SWITCH_STATE_STORED
208
209 WaitForOtherStored:
210 ; wait until the other CPU finish storing its state
211 cmp byte ptr [edi], CPU_SWITCH_STATE_STORED
212 jz OtherStored
213 PAUSE32
214 jmp WaitForOtherStored
215
216 OtherStored:
217 ; Since another CPU already stored its state, load them
218 ; load GDTR value
219 lgdt fword ptr [edi+8]
220
221 ; load IDTR value
222 lidt fword ptr [edi+14]
223
224 ; load its future StackPointer
225 mov esp, dword ptr [edi+4]
226
227 ; update the other CPU's switch state to LOADED
228 mov byte ptr [edi], CPU_SWITCH_STATE_LOADED
229
230 WaitForOtherLoaded:
231 ; wait until the other CPU finish loading new state,
232 ; otherwise the data in stack may corrupt
233 cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED
234 jz OtherLoaded
235 PAUSE32
236 jmp WaitForOtherLoaded
237
238 OtherLoaded:
239 ; since the other CPU already get the data it want, leave this procedure
240 pop eax
241 mov cr0, eax
242 pop eax
243 mov cr4, eax
244 popfd
245
246 popad
247 ret
248 AsmExchangeRole ENDP
249
250 END