]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.nasm
6bbc339c53b7fafddc0f0662da110d7cd740b857
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / 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 %include "StuffRsb.inc"
22
23 %define MSR_IA32_MISC_ENABLE 0x1A0
24 %define MSR_EFER 0xc0000080
25 %define MSR_EFER_XD 0x800
26
27 ;
28 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
29 ;
30 %define DSC_OFFSET 0xfb00
31 %define DSC_GDTPTR 0x30
32 %define DSC_GDTSIZ 0x38
33 %define DSC_CS 14
34 %define DSC_DS 16
35 %define DSC_SS 18
36 %define DSC_OTHERSEG 20
37
38 %define PROTECT_MODE_CS 0x8
39 %define PROTECT_MODE_DS 0x20
40 %define TSS_SEGMENT 0x40
41
42 extern ASM_PFX(SmiRendezvous)
43 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
44 extern ASM_PFX(CpuSmmDebugEntry)
45 extern ASM_PFX(CpuSmmDebugExit)
46
47 global ASM_PFX(gcSmiHandlerTemplate)
48 global ASM_PFX(gcSmiHandlerSize)
49 global ASM_PFX(gPatchSmiCr3)
50 global ASM_PFX(gPatchSmiStack)
51 global ASM_PFX(gPatchSmbase)
52 extern ASM_PFX(mXdSupported)
53 global ASM_PFX(gPatchXdSupported)
54 extern ASM_PFX(gSmiHandlerIdtr)
55
56 SECTION .text
57
58 BITS 16
59 ASM_PFX(gcSmiHandlerTemplate):
60 _SmiEntryPoint:
61 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
62 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
63 dec ax
64 mov [cs:bx], ax
65 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
66 mov [cs:bx + 2], eax
67 mov ebp, eax ; ebp = GDT base
68 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
69 mov ax, PROTECT_MODE_CS
70 mov [cs:bx-0x2],ax
71 mov edi, strict dword 0 ; source operand will be patched
72 ASM_PFX(gPatchSmbase):
73 lea eax, [edi + (@32bit - _SmiEntryPoint) + 0x8000]
74 mov [cs:bx-0x6],eax
75 mov ebx, cr0
76 and ebx, 0x9ffafff3
77 or ebx, 0x23
78 mov cr0, ebx
79 jmp dword 0x0:0x0
80 _GdtDesc:
81 DW 0
82 DD 0
83
84 BITS 32
85 @32bit:
86 mov ax, PROTECT_MODE_DS
87 o16 mov ds, ax
88 o16 mov es, ax
89 o16 mov fs, ax
90 o16 mov gs, ax
91 o16 mov ss, ax
92 mov esp, strict dword 0 ; source operand will be patched
93 ASM_PFX(gPatchSmiStack):
94 mov eax, ASM_PFX(gSmiHandlerIdtr)
95 lidt [eax]
96 jmp ProtFlatMode
97
98 ProtFlatMode:
99 mov eax, strict dword 0 ; source operand will be patched
100 ASM_PFX(gPatchSmiCr3):
101 mov cr3, eax
102 ;
103 ; Need to test for CR4 specific bit support
104 ;
105 mov eax, 1
106 cpuid ; use CPUID to determine if specific CR4 bits are supported
107 xor eax, eax ; Clear EAX
108 test edx, BIT2 ; Check for DE capabilities
109 jz .0
110 or eax, BIT3
111 .0:
112 test edx, BIT6 ; Check for PAE capabilities
113 jz .1
114 or eax, BIT5
115 .1:
116 test edx, BIT7 ; Check for MCE capabilities
117 jz .2
118 or eax, BIT6
119 .2:
120 test edx, BIT24 ; Check for FXSR capabilities
121 jz .3
122 or eax, BIT9
123 .3:
124 test edx, BIT25 ; Check for SSE capabilities
125 jz .4
126 or eax, BIT10
127 .4: ; as cr4.PGE is not set here, refresh cr3
128 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
129
130 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0
131 jz .6
132 ; Load TSS
133 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag
134 mov eax, TSS_SEGMENT
135 ltr ax
136 .6:
137
138 ; enable NXE if supported
139 mov al, strict byte 1 ; source operand may be patched
140 ASM_PFX(gPatchXdSupported):
141 cmp al, 0
142 jz @SkipXd
143 ;
144 ; Check XD disable bit
145 ;
146 mov ecx, MSR_IA32_MISC_ENABLE
147 rdmsr
148 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
149 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
150 jz .5
151 and dx, 0xFFFB ; clear XD Disable bit if it is set
152 wrmsr
153 .5:
154 mov ecx, MSR_EFER
155 rdmsr
156 or ax, MSR_EFER_XD ; enable NXE
157 wrmsr
158 jmp @XdDone
159 @SkipXd:
160 sub esp, 4
161 @XdDone:
162
163 mov ebx, cr0
164 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE
165 mov cr0, ebx
166 lea ebx, [edi + DSC_OFFSET]
167 mov ax, [ebx + DSC_DS]
168 mov ds, eax
169 mov ax, [ebx + DSC_OTHERSEG]
170 mov es, eax
171 mov fs, eax
172 mov gs, eax
173 mov ax, [ebx + DSC_SS]
174 mov ss, eax
175
176 ; jmp _SmiHandler ; instruction is not needed
177
178 global ASM_PFX(SmiHandler)
179 ASM_PFX(SmiHandler):
180 mov ebx, [esp + 4] ; CPU Index
181 push ebx
182 mov eax, ASM_PFX(CpuSmmDebugEntry)
183 call eax
184 add esp, 4
185
186 push ebx
187 mov eax, ASM_PFX(SmiRendezvous)
188 call eax
189 add esp, 4
190
191 push ebx
192 mov eax, ASM_PFX(CpuSmmDebugExit)
193 call eax
194 add esp, 4
195
196 mov eax, ASM_PFX(mXdSupported)
197 mov al, [eax]
198 cmp al, 0
199 jz .7
200 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
201 test edx, BIT2
202 jz .7
203 mov ecx, MSR_IA32_MISC_ENABLE
204 rdmsr
205 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
206 wrmsr
207
208 .7:
209 StuffRsb32
210 rsm
211
212 ASM_PFX(gcSmiHandlerSize): DW $ - _SmiEntryPoint
213
214 global ASM_PFX(PiSmmCpuSmiEntryFixupAddress)
215 ASM_PFX(PiSmmCpuSmiEntryFixupAddress):
216 ret