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