]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuMpPei/Ia32/MpFuncs.nasm
UefiCpuPkg/CpuMpPei: Update files format to DOS
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / Ia32 / MpFuncs.nasm
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; MpFuncs.nasm\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%include "MpEqu.inc"\r
22extern ASM_PFX(InitializeFloatingPointUnits)\r
23\r
24SECTION .text\r
25\r
26;-------------------------------------------------------------------------------------\r
27;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
28;procedure serializes all the AP processors through an Init sequence. It must be\r
29;noted that APs arrive here very raw...ie: real mode, no stack.\r
30;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
31;IS IN MACHINE CODE.\r
32;-------------------------------------------------------------------------------------\r
33global ASM_PFX(RendezvousFunnelProc)\r
34ASM_PFX(RendezvousFunnelProc):\r
35RendezvousFunnelProcStart:\r
36; At this point CS = 0x(vv00) and ip= 0x0.\r
37BITS 16\r
38 mov ebp, eax ; save BIST information\r
39\r
40 mov ax, cs\r
41 mov ds, ax\r
42 mov es, ax\r
43 mov ss, ax\r
44 xor ax, ax\r
45 mov fs, ax\r
46 mov gs, ax\r
47\r
48 mov si, BufferStartLocation\r
49 mov ebx, [si]\r
50\r
51 mov di, PmodeOffsetLocation\r
52 mov eax, [di]\r
53 mov di, ax\r
54 sub di, 06h\r
55 add eax, ebx\r
56 mov [di],eax\r
57\r
58 mov si, GdtrLocation\r
59o32 lgdt [cs:si]\r
60\r
61 mov si, IdtrLocation\r
62o32 lidt [cs:si]\r
63\r
64 xor ax, ax\r
65 mov ds, ax\r
66\r
67 mov eax, cr0 ;Get control register 0\r
68 or eax, 000000003h ;Set PE bit (bit #0) & MP\r
69 mov cr0, eax\r
70\r
71 jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode\r
72BITS 32\r
73Flat32Start: ; protected mode entry point\r
74 mov ax, PROTECT_MODE_DS\r
75 mov ds, ax\r
76 mov es, ax\r
77 mov fs, ax\r
78 mov gs, ax\r
79 mov ss, ax\r
80\r
81 mov esi, ebx\r
82 mov edi, esi\r
83 add edi, LockLocation\r
84 mov eax, NotVacantFlag\r
85\r
86TestLock:\r
87 xchg [edi], eax\r
88 cmp eax, NotVacantFlag\r
89 jz TestLock\r
90\r
91 mov edi, esi\r
92 add edi, NumApsExecutingLoction\r
93 inc dword [edi]\r
94 mov ebx, [edi]\r
95\r
96ProgramStack:\r
97 mov edi, esi\r
98 add edi, StackSizeLocation\r
99 mov eax, [edi]\r
100 mov edi, esi\r
101 add edi, StackStartAddressLocation\r
102 add eax, [edi]\r
103 mov esp, eax\r
104 mov [edi], eax\r
105\r
106Releaselock:\r
107 mov eax, VacantFlag\r
108 mov edi, esi\r
109 add edi, LockLocation\r
110 xchg [edi], eax\r
111\r
112CProcedureInvoke:\r
113 push ebp ; push BIST data at top of AP stack\r
114 xor ebp, ebp ; clear ebp for call stack trace\r
115 push ebp\r
116 mov ebp, esp\r
117\r
118 mov eax, ASM_PFX(InitializeFloatingPointUnits)\r
119 call eax ; Call assembly function to initialize FPU per UEFI spec\r
120\r
121 push ebx ; Push NumApsExecuting\r
122 mov eax, esi\r
123 add eax, LockLocation\r
124 push eax ; push address of exchange info data buffer\r
125\r
126 mov edi, esi\r
127 add edi, ApProcedureLocation\r
128 mov eax, [edi]\r
129\r
130 call eax ; invoke C function\r
131\r
132 jmp $ ; never reach here\r
133RendezvousFunnelProcEnd:\r
134\r
135global ASM_PFX(AsmCliHltLoop)\r
136ASM_PFX(AsmCliHltLoop):\r
137 cli\r
138 hlt\r
139 jmp $-2\r
140\r
141;-------------------------------------------------------------------------------------\r
142; AsmGetAddressMap (&AddressMap);\r
143;-------------------------------------------------------------------------------------\r
144global ASM_PFX(AsmGetAddressMap)\r
145ASM_PFX(AsmGetAddressMap):\r
146 pushad\r
147 mov ebp,esp\r
148\r
149 mov ebx, [ebp + 24h]\r
150 mov dword [ebx], RendezvousFunnelProcStart\r
151 mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart\r
152 mov dword [ebx + 8h], 0\r
153 mov dword [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
154\r
155 popad\r
156 ret\r
157\r
158;-------------------------------------------------------------------------------------\r
159;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is\r
160;about to become an AP. It switches it'stack with the current AP.\r
161;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);\r
162;-------------------------------------------------------------------------------------\r
163global ASM_PFX(AsmExchangeRole)\r
164ASM_PFX(AsmExchangeRole):\r
165 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack\r
166 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.\r
167 pushad\r
168 mov ebp,esp\r
169\r
170 ; esi contains MyInfo pointer\r
171 mov esi, [ebp + 24h]\r
172\r
173 ; edi contains OthersInfo pointer\r
174 mov edi, [ebp + 28h]\r
175\r
176 ;Store EFLAGS, GDTR and IDTR register to stack\r
177 pushfd\r
178 mov eax, cr4\r
179 push eax ; push cr4 firstly\r
180 mov eax, cr0\r
181 push eax\r
182\r
183 sgdt [esi + 8]\r
184 sidt [esi + 14]\r
185\r
186 ; Store the its StackPointer\r
187 mov [esi + 4],esp\r
188\r
189 ; update its switch state to STORED\r
190 mov byte [esi], CPU_SWITCH_STATE_STORED\r
191\r
192WaitForOtherStored:\r
193 ; wait until the other CPU finish storing its state\r
194 cmp byte [edi], CPU_SWITCH_STATE_STORED\r
195 jz OtherStored\r
196 pause\r
197 jmp WaitForOtherStored\r
198\r
199OtherStored:\r
200 ; Since another CPU already stored its state, load them\r
201 ; load GDTR value\r
202 lgdt [edi + 8]\r
203\r
204 ; load IDTR value\r
205 lidt [edi + 14]\r
206\r
207 ; load its future StackPointer\r
208 mov esp, [edi + 4]\r
209\r
210 ; update the other CPU's switch state to LOADED\r
211 mov byte [edi], CPU_SWITCH_STATE_LOADED\r
212\r
213WaitForOtherLoaded:\r
214 ; wait until the other CPU finish loading new state,\r
215 ; otherwise the data in stack may corrupt\r
216 cmp byte [esi], CPU_SWITCH_STATE_LOADED\r
217 jz OtherLoaded\r
218 pause\r
219 jmp WaitForOtherLoaded\r
220\r
221OtherLoaded:\r
222 ; since the other CPU already get the data it want, leave this procedure\r
223 pop eax\r
224 mov cr0, eax\r
225 pop eax\r
226 mov cr4, eax\r
227 popfd\r
228\r
229 popad\r
230 ret\r
231\r
232global ASM_PFX(AsmInitializeGdt)\r
233ASM_PFX(AsmInitializeGdt):\r
234 push ebp\r
235 mov ebp, esp\r
236 pushad\r
237 mov edi, [ebp + 8] ; Load GDT register\r
238\r
239 lgdt [edi] ; and update the GDTR\r
240\r
241 push PROTECT_MODE_CS\r
242 mov eax, ASM_PFX(SetCodeSelectorFarJump)\r
243 push eax\r
244 retf\r
245ASM_PFX(SetCodeSelectorFarJump):\r
246 mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too\r
247 mov ds, ax\r
248 mov es, ax\r
249 mov fs, ax\r
250 mov gs, ax\r
251 mov ss, ax\r
252\r
253 popad\r
254 pop ebp\r
255 ret\r