]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.asm
UefiCpuPkg/PiSmmCpuDxeSmm: Add paging protection.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiEntry.asm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2009 - 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 ; SmiEntry.asm
14 ;
15 ; Abstract:
16 ;
17 ; Code template of the SMI handler for a particular processor
18 ;
19 ;-------------------------------------------------------------------------------
20
21 .686p
22 .model flat,C
23 .xmm
24
25 MSR_IA32_MISC_ENABLE EQU 1A0h
26 MSR_EFER EQU 0c0000080h
27 MSR_EFER_XD EQU 0800h
28
29 DSC_OFFSET EQU 0fb00h
30 DSC_GDTPTR EQU 30h
31 DSC_GDTSIZ EQU 38h
32 DSC_CS EQU 14
33 DSC_DS EQU 16
34 DSC_SS EQU 18
35 DSC_OTHERSEG EQU 20
36
37 PROTECT_MODE_CS EQU 08h
38 PROTECT_MODE_DS EQU 20h
39 TSS_SEGMENT EQU 40h
40
41 SmiRendezvous PROTO C
42 CpuSmmDebugEntry PROTO C
43 CpuSmmDebugExit PROTO C
44
45 EXTERNDEF gcSmiHandlerTemplate:BYTE
46 EXTERNDEF gcSmiHandlerSize:WORD
47 EXTERNDEF gSmiCr3:DWORD
48 EXTERNDEF gSmiStack:DWORD
49 EXTERNDEF gSmbase:DWORD
50 EXTERNDEF mXdSupported:BYTE
51 EXTERNDEF FeaturePcdGet (PcdCpuSmmStackGuard):BYTE
52 EXTERNDEF gSmiHandlerIdtr:FWORD
53
54 .code
55
56 gcSmiHandlerTemplate LABEL BYTE
57
58 _SmiEntryPoint:
59 DB 0bbh ; mov bx, imm16
60 DW offset _GdtDesc - _SmiEntryPoint + 8000h
61 DB 2eh, 0a1h ; mov ax, cs:[offset16]
62 DW DSC_OFFSET + DSC_GDTSIZ
63 dec eax
64 mov cs:[edi], eax ; mov cs:[bx], ax
65 DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]
66 DW DSC_OFFSET + DSC_GDTPTR
67 mov cs:[edi + 2], ax ; mov cs:[bx + 2], eax
68 mov bp, ax ; ebp = GDT base
69 DB 66h
70 lgdt fword ptr cs:[edi] ; lgdt fword ptr cs:[bx]
71 ; Patch ProtectedMode Segment
72 DB 0b8h ; mov ax, imm16
73 DW PROTECT_MODE_CS ; set AX for segment directly
74 mov cs:[edi - 2], eax ; mov cs:[bx - 2], ax
75 ; Patch ProtectedMode entry
76 DB 66h, 0bfh ; mov edi, SMBASE
77 gSmbase DD ?
78 DB 67h
79 lea ax, [edi + (@32bit - _SmiEntryPoint) + 8000h]
80 mov cs:[edi - 6], ax ; mov cs:[bx - 6], eax
81 mov ebx, cr0
82 DB 66h
83 and ebx, 9ffafff3h
84 DB 66h
85 or ebx, 23h
86 mov cr0, ebx
87 DB 66h, 0eah
88 DD ?
89 DW ?
90 _GdtDesc FWORD ?
91
92 @32bit:
93 mov ax, PROTECT_MODE_DS
94 mov ds, ax
95 mov es, ax
96 mov fs, ax
97 mov gs, ax
98 mov ss, ax
99 DB 0bch ; mov esp, imm32
100 gSmiStack DD ?
101 mov eax, offset gSmiHandlerIdtr
102 lidt fword ptr [eax]
103 jmp ProtFlatMode
104
105 ProtFlatMode:
106 DB 0b8h ; mov eax, imm32
107 gSmiCr3 DD ?
108 mov cr3, eax
109 ;
110 ; Need to test for CR4 specific bit support
111 ;
112 mov eax, 1
113 cpuid ; use CPUID to determine if specific CR4 bits are supported
114 xor eax, eax ; Clear EAX
115 test edx, BIT2 ; Check for DE capabilities
116 jz @f
117 or eax, BIT3
118 @@:
119 test edx, BIT6 ; Check for PAE capabilities
120 jz @f
121 or eax, BIT5
122 @@:
123 test edx, BIT7 ; Check for MCE capabilities
124 jz @f
125 or eax, BIT6
126 @@:
127 test edx, BIT24 ; Check for FXSR capabilities
128 jz @f
129 or eax, BIT9
130 @@:
131 test edx, BIT25 ; Check for SSE capabilities
132 jz @f
133 or eax, BIT10
134 @@: ; as cr4.PGE is not set here, refresh cr3
135 mov cr4, eax ; in PreModifyMtrrs() to flush TLB.
136
137 cmp FeaturePcdGet (PcdCpuSmmStackGuard), 0
138 jz @F
139 ; Load TSS
140 mov byte ptr [ebp + TSS_SEGMENT + 5], 89h ; clear busy flag
141 mov eax, TSS_SEGMENT
142 ltr ax
143 @@:
144
145 ; enable NXE if supported
146 DB 0b0h ; mov al, imm8
147 mXdSupported DB 1
148 cmp al, 0
149 jz @SkipXd
150 ;
151 ; Check XD disable bit
152 ;
153 mov ecx, MSR_IA32_MISC_ENABLE
154 rdmsr
155 push edx ; save MSR_IA32_MISC_ENABLE[63-32]
156 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]
157 jz @f
158 and dx, 0FFFBh ; clear XD Disable bit if it is set
159 wrmsr
160 @@:
161 mov ecx, MSR_EFER
162 rdmsr
163 or ax, MSR_EFER_XD ; enable NXE
164 wrmsr
165 jmp @XdDone
166 @SkipXd:
167 sub esp, 4
168 @XdDone:
169
170 mov ebx, cr0
171 or ebx, 080010023h ; enable paging + WP + NE + MP + PE
172 mov cr0, ebx
173 lea ebx, [edi + DSC_OFFSET]
174 mov ax, [ebx + DSC_DS]
175 mov ds, eax
176 mov ax, [ebx + DSC_OTHERSEG]
177 mov es, eax
178 mov fs, eax
179 mov gs, eax
180 mov ax, [ebx + DSC_SS]
181 mov ss, eax
182
183 ; jmp _SmiHandler ; instruction is not needed
184
185 _SmiHandler PROC
186 mov ebx, [esp + 4] ; CPU Index
187 push ebx
188 mov eax, CpuSmmDebugEntry
189 call eax
190 add esp, 4
191
192 push ebx
193 mov eax, SmiRendezvous
194 call eax
195 add esp, 4
196
197 push ebx
198 mov eax, CpuSmmDebugExit
199 call eax
200 add esp, 4
201
202 mov eax, mXdSupported
203 mov al, [eax]
204 cmp al, 0
205 jz @f
206 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32]
207 test edx, BIT2
208 jz @f
209 mov ecx, MSR_IA32_MISC_ENABLE
210 rdmsr
211 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM
212 wrmsr
213
214 @@:
215 rsm
216 _SmiHandler ENDP
217
218 gcSmiHandlerSize DW $ - _SmiEntryPoint
219
220 END