UefiCpuPkg: Update PiSmmCpuDxeSmm pass XCODE5 tool chain
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.nasm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016 - 2018, 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 ; SmiEntry.nasm
14 ;
15 ; Abstract:
16 ;
17 ; Code template of the SMI handler for a particular processor
18 ;
19 ;-------------------------------------------------------------------------------
20
21 ;
22 ; Variables referrenced by C code
23 ;
24
25 %define MSR_IA32_MISC_ENABLE 0x1A0
26 %define MSR_EFER 0xc0000080
27 %define MSR_EFER_XD 0x800
28
29 ;
30 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
31 ;
32 %define DSC_OFFSET 0xfb00
33 %define DSC_GDTPTR 0x30
34 %define DSC_GDTSIZ 0x38
35 %define DSC_CS 14
36 %define DSC_DS 16
37 %define DSC_SS 18
38 %define DSC_OTHERSEG 20
39 ;
40 ; Constants relating to CPU State Save Area
41 ;
42 %define SSM_DR6 0xffd0
43 %define SSM_DR7 0xffc8
44
45 %define PROTECT_MODE_CS 0x8
46 %define PROTECT_MODE_DS 0x20
47 %define LONG_MODE_CS 0x38
48 %define TSS_SEGMENT 0x40
49 %define GDT_SIZE 0x50
50
51 extern ASM_PFX(SmiRendezvous)
52 extern ASM_PFX(gSmiHandlerIdtr)
53 extern ASM_PFX(CpuSmmDebugEntry)
54 extern ASM_PFX(CpuSmmDebugExit)
55
56 global ASM_PFX(gSmbase)
57 global ASM_PFX(mXdSupported)
58 global ASM_PFX(gSmiStack)
59 global ASM_PFX(gSmiCr3)
60 global ASM_PFX(gcSmiHandlerTemplate)
61 global ASM_PFX(gcSmiHandlerSize)
62
63 DEFAULT REL
64 SECTION .text
65
66 BITS 16
67 ASM_PFX(gcSmiHandlerTemplate):
68 _SmiEntryPoint:
69 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
70 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
71 dec ax
72 mov [cs:bx], ax
73 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
74 mov [cs:bx + 2], eax
75 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
76 mov ax, PROTECT_MODE_CS
77 mov [cs:bx-0x2],ax
78 DB 0x66, 0xbf ; mov edi, SMBASE
79 ASM_PFX(gSmbase): DD 0
80 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]
81 mov [cs:bx-0x6],eax
82 mov ebx, cr0
83 and ebx, 0x9ffafff3
84 or ebx, 0x23
85 mov cr0, ebx
86 jmp dword 0x0:0x0
87 _GdtDesc:
88 DW 0
89 DD 0
90
91 BITS 32
92 @ProtectedMode:
93 mov ax, PROTECT_MODE_DS
94 o16 mov ds, ax
95 o16 mov es, ax
96 o16 mov fs, ax
97 o16 mov gs, ax
98 o16 mov ss, ax
99 DB 0xbc ; mov esp, imm32
100 ASM_PFX(gSmiStack): DD 0
101 jmp ProtFlatMode
102
103 BITS 64
104 ProtFlatMode:
105 DB 0xb8 ; mov eax, offset gSmiCr3
106 ASM_PFX(gSmiCr3): DD 0
107 mov cr3, rax
108 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
109 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
110 ; Load TSS
111 sub esp, 8 ; reserve room in stack
112 sgdt [rsp]
113 mov eax, [rsp + 2] ; eax = GDT base
114 add esp, 8
115 mov dl, 0x89
116 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
117 mov eax, TSS_SEGMENT
118 ltr ax
119
120 ; enable NXE if supported
121 DB 0xb0 ; mov al, imm8
122 ASM_PFX(mXdSupported): DB 1
123 cmp al, 0
124 jz @SkipXd
125 ;
126 ; Check XD disable bit
127 ;
128 mov ecx, MSR_IA32_MISC_ENABLE
129 rdmsr
130 sub esp, 4
131 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]
132 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
133 jz .0
134 and dx, 0xFFFB ; clear XD Disable bit if it is set
135 wrmsr
136 .0:
137 mov ecx, MSR_EFER
138 rdmsr
139 or ax, MSR_EFER_XD ; enable NXE
140 wrmsr
141 jmp @XdDone
142 @SkipXd:
143 sub esp, 8
144 @XdDone:
145
146 ; Switch into @LongMode
147 push LONG_MODE_CS ; push cs hardcore here
148 call Base ; push return address for retf later
149 Base:
150 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
151
152 mov ecx, MSR_EFER
153 rdmsr
154 or ah, 1 ; enable LME
155 wrmsr
156 mov rbx, cr0
157 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
158 mov cr0, rbx
159 retf
160 @LongMode: ; long mode (64-bit code) starts here
161 mov rax, strict qword 0 ; mov rax, ASM_PFX(gSmiHandlerIdtr)
162 SmiHandlerIdtrAbsAddr:
163 lidt [rax]
164 lea ebx, [rdi + DSC_OFFSET]
165 mov ax, [rbx + DSC_DS]
166 mov ds, eax
167 mov ax, [rbx + DSC_OTHERSEG]
168 mov es, eax
169 mov fs, eax
170 mov gs, eax
171 mov ax, [rbx + DSC_SS]
172 mov ss, eax
173 mov rax, strict qword 0 ; mov rax, _SmiHandler
174 _SmiHandlerAbsAddr:
175 jmp rax
176
177 _SmiHandler:
178 mov rbx, [rsp + 0x8] ; rcx <- CpuIndex
179
180 ;
181 ; Save FP registers
182 ;
183 sub rsp, 0x200
184 DB 0x48 ; FXSAVE64
185 fxsave [rsp]
186
187 add rsp, -0x20
188
189 mov rcx, rbx
190 call ASM_PFX(CpuSmmDebugEntry)
191
192 mov rcx, rbx
193 call ASM_PFX(SmiRendezvous)
194
195 mov rcx, rbx
196 call ASM_PFX(CpuSmmDebugExit)
197
198 add rsp, 0x20
199
200 ;
201 ; Restore FP registers
202 ;
203 DB 0x48 ; FXRSTOR64
204 fxrstor [rsp]
205
206 add rsp, 0x200
207
208 lea rax, [ASM_PFX(mXdSupported)]
209 mov al, [rax]
210 cmp al, 0
211 jz .1
212 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]
213 test edx, BIT2
214 jz .1
215 mov ecx, MSR_IA32_MISC_ENABLE
216 rdmsr
217 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
218 wrmsr
219
220 .1:
221 rsm
222
223 ASM_PFX(gcSmiHandlerSize) DW $ - _SmiEntryPoint
224
225 global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)
226 ASM_PFX(PiSmmCpuSmiEntryFixupAddress):
227 lea rax, [ASM_PFX(gSmiHandlerIdtr)]
228 lea rcx, [SmiHandlerIdtrAbsAddr]
229 mov qword [rcx - 8], rax
230
231 lea rax, [_SmiHandler]
232 lea rcx, [_SmiHandlerAbsAddr]
233 mov qword [rcx - 8], rax
234 ret