MdePkg/BaseLib: add PatchInstructionX86()
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / MpFuncs.asm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2006 - 2015, 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.asm
14 ;
15 ; Abstract:
16 ;
17 ; This is the assembly code for Multi-processor S3 support
18 ;
19 ;-------------------------------------------------------------------------------
20
21 EXTERN InitializeFloatingPointUnits:PROC
22
23 VacantFlag Equ 00h
24 NotVacantFlag Equ 0ffh
25
26 LockLocation equ RendezvousFunnelProcEnd - RendezvousFunnelProcStart
27 StackStartAddressLocation equ LockLocation + 08h
28 StackSizeLocation equ LockLocation + 10h
29 CProcedureLocation equ LockLocation + 18h
30 GdtrLocation equ LockLocation + 20h
31 IdtrLocation equ LockLocation + 2Ah
32 BufferStartLocation equ LockLocation + 34h
33 Cr3OffsetLocation equ LockLocation + 38h
34
35 ;-------------------------------------------------------------------------------------
36 ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
37 ;procedure serializes all the AP processors through an Init sequence. It must be
38 ;noted that APs arrive here very raw...ie: real mode, no stack.
39 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
40 ;IS IN MACHINE CODE.
41 ;-------------------------------------------------------------------------------------
42 ;RendezvousFunnelProc (&WakeUpBuffer,MemAddress);
43
44 ;text SEGMENT
45 .code
46
47 RendezvousFunnelProc PROC
48 RendezvousFunnelProcStart::
49
50 ; At this point CS = 0x(vv00) and ip= 0x0.
51
52 db 8ch, 0c8h ; mov ax, cs
53 db 8eh, 0d8h ; mov ds, ax
54 db 8eh, 0c0h ; mov es, ax
55 db 8eh, 0d0h ; mov ss, ax
56 db 33h, 0c0h ; xor ax, ax
57 db 8eh, 0e0h ; mov fs, ax
58 db 8eh, 0e8h ; mov gs, ax
59
60 flat32Start::
61
62 db 0BEh
63 dw BufferStartLocation ; mov si, BufferStartLocation
64 db 66h, 8Bh, 14h ; mov edx,dword ptr [si] ; EDX is keeping the start address of wakeup buffer
65
66 db 0BEh
67 dw Cr3OffsetLocation ; mov si, Cr3Location
68 db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
69
70 db 0BEh
71 dw GdtrLocation ; mov si, GdtrProfile
72 db 66h ; db 66h
73 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
74
75 db 0BEh
76 dw IdtrLocation ; mov si, IdtrProfile
77 db 66h ; db 66h
78 db 2Eh, 0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
79
80 db 33h, 0C0h ; xor ax, ax
81 db 8Eh, 0D8h ; mov ds, ax
82
83 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
84 db 66h, 83h, 0C8h, 01h ; or eax, 000000001h ; Set PE bit (bit #0)
85 db 0Fh, 22h, 0C0h ; mov cr0, eax
86
87 FLAT32_JUMP::
88
89 db 66h, 67h, 0EAh ; far jump
90 dd 0h ; 32-bit offset
91 dw 20h ; 16-bit selector
92
93 PMODE_ENTRY:: ; protected mode entry point
94
95 db 66h, 0B8h, 18h, 00h ; mov ax, 18h
96 db 66h, 8Eh, 0D8h ; mov ds, ax
97 db 66h, 8Eh, 0C0h ; mov es, ax
98 db 66h, 8Eh, 0E0h ; mov fs, ax
99 db 66h, 8Eh, 0E8h ; mov gs, ax
100 db 66h, 8Eh, 0D0h ; mov ss, ax ; Flat mode setup.
101
102 db 0Fh, 20h, 0E0h ; mov eax, cr4
103 db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
104 db 0Fh, 22h, 0E0h ; mov cr4, eax
105
106 db 0Fh, 22h, 0D9h ; mov cr3, ecx
107
108 db 8Bh, 0F2h ; mov esi, edx ; Save wakeup buffer address
109
110 db 0B9h
111 dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
112 db 0Fh, 32h ; rdmsr ; Read EFER.
113 db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.
114 db 0Fh, 30h ; wrmsr ; Write EFER.
115
116 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
117 db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.
118 db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
119
120 LONG_JUMP::
121
122 db 67h, 0EAh ; far jump
123 dd 0h ; 32-bit offset
124 dw 38h ; 16-bit selector
125
126 LongModeStart::
127
128 mov ax, 30h
129 mov ds, ax
130 mov es, ax
131 mov ss, ax
132
133 mov edi, esi
134 add edi, LockLocation
135 mov al, NotVacantFlag
136 TestLock::
137 xchg byte ptr [edi], al
138 cmp al, NotVacantFlag
139 jz TestLock
140
141 ProgramStack::
142
143 mov edi, esi
144 add edi, StackSizeLocation
145 mov rax, qword ptr [edi]
146 mov edi, esi
147 add edi, StackStartAddressLocation
148 add rax, qword ptr [edi]
149 mov rsp, rax
150 mov qword ptr [edi], rax
151
152 Releaselock::
153
154 mov al, VacantFlag
155 mov edi, esi
156 add edi, LockLocation
157 xchg byte ptr [edi], al
158
159 ;
160 ; Call assembly function to initialize FPU.
161 ;
162 mov rax, InitializeFloatingPointUnits
163 sub rsp, 20h
164 call rax
165 add rsp, 20h
166
167 ;
168 ; Call C Function
169 ;
170 mov edi, esi
171 add edi, CProcedureLocation
172 mov rax, qword ptr [edi]
173
174 test rax, rax
175 jz GoToSleep
176
177 sub rsp, 20h
178 call rax
179 add rsp, 20h
180
181 GoToSleep::
182 cli
183 hlt
184 jmp $-2
185
186 RendezvousFunnelProcEnd::
187 RendezvousFunnelProc ENDP
188
189
190 ;-------------------------------------------------------------------------------------
191 ; AsmGetAddressMap (&AddressMap);
192 ;-------------------------------------------------------------------------------------
193 ; comments here for definition of address map
194 AsmGetAddressMap PROC
195 mov rax, offset RendezvousFunnelProcStart
196 mov qword ptr [rcx], rax
197 mov qword ptr [rcx+8h], PMODE_ENTRY - RendezvousFunnelProcStart
198 mov qword ptr [rcx+10h], FLAT32_JUMP - RendezvousFunnelProcStart
199 mov qword ptr [rcx+18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
200 mov qword ptr [rcx+20h], LongModeStart - RendezvousFunnelProcStart
201 mov qword ptr [rcx+28h], LONG_JUMP - RendezvousFunnelProcStart
202 ret
203
204 AsmGetAddressMap ENDP
205
206 END