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