]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.asm
UefiCpuPkg/CpuMpPei: Consume MpInitLib to produce CPU MP PPI services
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / Ia32 / MpFuncs.asm
CommitLineData
ea0f431c 1;------------------------------------------------------------------------------ ;\r
aad5ee48 2; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
ea0f431c
JF
3; This program and the accompanying materials\r
4; are licensed and made available under the terms and conditions of the BSD License\r
5; which accompanies this distribution. The full text of the license may be found at\r
6; http://opensource.org/licenses/bsd-license.php.\r
7;\r
8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10;\r
11; Module Name:\r
12;\r
13; MpFuncs32.asm\r
14;\r
15; Abstract:\r
16;\r
17; This is the assembly code for MP support\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
21.686p\r
22.model flat\r
23\r
24include MpEqu.inc\r
25InitializeFloatingPointUnits PROTO C\r
26\r
27.code\r
28\r
29;-------------------------------------------------------------------------------------\r
30;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
31;procedure serializes all the AP processors through an Init sequence. It must be\r
32;noted that APs arrive here very raw...ie: real mode, no stack.\r
33;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
34;IS IN MACHINE CODE.\r
35;-------------------------------------------------------------------------------------\r
36RendezvousFunnelProc PROC PUBLIC\r
37RendezvousFunnelProcStart::\r
38; At this point CS = 0x(vv00) and ip= 0x0.\r
39; Save BIST information to ebp firstly\r
40 db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information\r
41\r
aad5ee48
JF
42 db 8ch,0c8h ; mov ax, cs\r
43 db 8eh,0d8h ; mov ds, ax\r
44 db 8eh,0c0h ; mov es, ax\r
45 db 8eh,0d0h ; mov ss, ax\r
46 db 33h,0c0h ; xor ax, ax\r
47 db 8eh,0e0h ; mov fs, ax\r
48 db 8eh,0e8h ; mov gs, ax\r
ea0f431c
JF
49\r
50 db 0BEh ; opcode of mov si, mem16\r
51 dw BufferStartLocation ; mov si, BufferStartLocation\r
aad5ee48 52 db 66h, 8Bh, 1Ch ; mov ebx, dword ptr [si]\r
ea0f431c 53\r
aad5ee48 54 db 0BEh ; opcode of mov si, mem16\r
01beffa7 55 dw ModeOffsetLocation ; mov si, ModeOffsetLocation\r
aad5ee48
JF
56 db 66h, 8Bh, 04h ; mov eax, [si]\r
57 db 0BEh ; opcode of mov si, mem16\r
58 dw CodeSegmentLocation ; mov si, CodeSegmentLocation\r
59 db 66h, 8Bh, 14h ; mov edx, [si]\r
60 db 89h, 0C7h ; mov di, ax\r
61 db 83h, 0EFh, 02h ; sub di, 02h\r
62 db 89h, 15h ; mov [di], dx\r
63 db 83h, 0EFh, 04h ; sub di, 04h\r
64 db 66h, 01h, 0D8h ; add eax, ebx\r
65 db 66h, 89h, 05h ; mov [di], eax\r
66\r
67 db 0BEh ; opcode of mov si, mem16\r
68 dw DataSegmentLocation ; mov si, DataSegmentLocation\r
69 db 66h, 8Bh, 14h ; mov edx, [si]\r
ea0f431c
JF
70\r
71 db 0BEh ; opcode of mov si, mem16\r
72 dw GdtrLocation ; mov si, GdtrLocation\r
73 db 66h ; db 66h\r
74 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]\r
75\r
76 db 0BEh\r
77 dw IdtrLocation ; mov si, IdtrLocation\r
78 db 66h ; db 66h\r
79 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]\r
80\r
81 db 33h, 0C0h ; xor ax, ax\r
82 db 8Eh, 0D8h ; mov ds, ax\r
83\r
84 db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0\r
85 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP\r
86 db 0Fh, 22h, 0C0h ; mov cr0, eax\r
87\r
88 db 66h, 67h, 0EAh ; far jump\r
89 dd 0h ; 32-bit offset\r
aad5ee48 90 dw 0h ; 16-bit selector\r
ea0f431c
JF
91\r
92Flat32Start:: ; protected mode entry point\r
aad5ee48
JF
93 mov ds, dx\r
94 mov es, dx\r
95 mov fs, dx\r
96 mov gs, dx\r
97 mov ss, dx\r
ea0f431c
JF
98\r
99 mov esi, ebx\r
100 mov edi, esi\r
101 add edi, LockLocation\r
102 mov eax, NotVacantFlag\r
103\r
104TestLock:\r
105 xchg dword ptr [edi], eax\r
106 cmp eax, NotVacantFlag\r
107 jz TestLock\r
108\r
109 mov edi, esi\r
110 add edi, NumApsExecutingLoction\r
111 inc dword ptr [edi]\r
112 mov ebx, dword ptr [edi]\r
113\r
114ProgramStack:\r
115 mov edi, esi\r
116 add edi, StackSizeLocation\r
117 mov eax, dword ptr [edi]\r
118 mov edi, esi\r
119 add edi, StackStartAddressLocation\r
120 add eax, dword ptr [edi]\r
121 mov esp, eax\r
122 mov dword ptr [edi], eax\r
123\r
124Releaselock:\r
125 mov eax, VacantFlag\r
126 mov edi, esi\r
127 add edi, LockLocation\r
128 xchg dword ptr [edi], eax\r
129\r
130CProcedureInvoke:\r
131 push ebp ; push BIST data at top of AP stack\r
132 xor ebp, ebp ; clear ebp for call stack trace\r
133 push ebp\r
134 mov ebp, esp\r
135\r
136 mov eax, InitializeFloatingPointUnits\r
137 call eax ; Call assembly function to initialize FPU per UEFI spec\r
138\r
139 push ebx ; Push NumApsExecuting\r
140 mov eax, esi\r
141 add eax, LockLocation\r
142 push eax ; push address of exchange info data buffer\r
143\r
144 mov edi, esi\r
145 add edi, ApProcedureLocation\r
146 mov eax, dword ptr [edi]\r
147\r
148 call eax ; invoke C function\r
149\r
150 jmp $ ; never reach here\r
151\r
152RendezvousFunnelProc ENDP\r
153RendezvousFunnelProcEnd::\r
154\r
ea0f431c
JF
155;-------------------------------------------------------------------------------------\r
156; AsmGetAddressMap (&AddressMap);\r
157;-------------------------------------------------------------------------------------\r
158AsmGetAddressMap PROC near C PUBLIC\r
159 pushad\r
160 mov ebp,esp\r
161\r
162 mov ebx, dword ptr [ebp+24h]\r
163 mov dword ptr [ebx], RendezvousFunnelProcStart\r
01beffa7
JF
164 mov dword ptr [ebx + 4h], Flat32Start - RendezvousFunnelProcStart\r
165 mov dword ptr [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
ea0f431c
JF
166\r
167 popad\r
168 ret\r
169AsmGetAddressMap ENDP\r
170\r
171PAUSE32 MACRO\r
172 DB 0F3h\r
173 DB 090h\r
174 ENDM\r
175\r
176;-------------------------------------------------------------------------------------\r
177;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is\r
178;about to become an AP. It switches it'stack with the current AP.\r
179;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);\r
180;-------------------------------------------------------------------------------------\r
181AsmExchangeRole PROC near C PUBLIC\r
182 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack\r
183 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.\r
184 pushad\r
185 mov ebp,esp\r
186\r
187 ; esi contains MyInfo pointer\r
188 mov esi, dword ptr [ebp+24h]\r
189\r
190 ; edi contains OthersInfo pointer\r
191 mov edi, dword ptr [ebp+28h]\r
192\r
193 ;Store EFLAGS, GDTR and IDTR register to stack\r
194 pushfd\r
195 mov eax, cr4\r
196 push eax ; push cr4 firstly\r
197 mov eax, cr0\r
198 push eax\r
199\r
200 sgdt fword ptr [esi+8]\r
201 sidt fword ptr [esi+14]\r
202\r
203 ; Store the its StackPointer\r
204 mov dword ptr [esi+4],esp\r
205\r
206 ; update its switch state to STORED\r
207 mov byte ptr [esi], CPU_SWITCH_STATE_STORED\r
208\r
209WaitForOtherStored:\r
210 ; wait until the other CPU finish storing its state\r
211 cmp byte ptr [edi], CPU_SWITCH_STATE_STORED\r
212 jz OtherStored\r
213 PAUSE32\r
214 jmp WaitForOtherStored\r
215\r
216OtherStored:\r
217 ; Since another CPU already stored its state, load them\r
218 ; load GDTR value\r
219 lgdt fword ptr [edi+8]\r
220\r
221 ; load IDTR value\r
222 lidt fword ptr [edi+14]\r
223\r
224 ; load its future StackPointer\r
225 mov esp, dword ptr [edi+4]\r
226\r
227 ; update the other CPU's switch state to LOADED\r
228 mov byte ptr [edi], CPU_SWITCH_STATE_LOADED\r
229\r
230WaitForOtherLoaded:\r
231 ; wait until the other CPU finish loading new state,\r
232 ; otherwise the data in stack may corrupt\r
233 cmp byte ptr [esi], CPU_SWITCH_STATE_LOADED\r
234 jz OtherLoaded\r
235 PAUSE32\r
236 jmp WaitForOtherLoaded\r
237\r
238OtherLoaded:\r
239 ; since the other CPU already get the data it want, leave this procedure\r
240 pop eax\r
241 mov cr0, eax\r
242 pop eax\r
243 mov cr4, eax\r
244 popfd\r
245\r
246 popad\r
247 ret\r
248AsmExchangeRole ENDP\r
249\r
ea0f431c 250END\r