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