1 ;------------------------------------------------------------------------------ ; 2 ; Copyright (c) 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.nasm 14 ; 15 ; Abstract: 16 ; 17 ; Code template of the SMI handler for a particular processor 18 ; 19 ;------------------------------------------------------------------------------- 20 21 %define MSR_IA32_MISC_ENABLE 0x1A0 22 %define MSR_EFER 0xc0000080 23 %define MSR_EFER_XD 0x800 24 25 ; 26 ; Constants relating to TXT_PROCESSOR_SMM_DESCRIPTOR 27 ; 28 %define DSC_OFFSET 0xfb00 29 %define DSC_GDTPTR 0x48 30 %define DSC_GDTSIZ 0x50 31 %define DSC_CS 0x14 32 %define DSC_DS 0x16 33 %define DSC_SS 0x18 34 %define DSC_OTHERSEG 0x1a 35 36 %define PROTECT_MODE_CS 0x8 37 %define PROTECT_MODE_DS 0x20 38 %define TSS_SEGMENT 0x40 39 40 extern ASM_PFX(SmiRendezvous) 41 extern ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) 42 extern ASM_PFX(CpuSmmDebugEntry) 43 extern ASM_PFX(CpuSmmDebugExit) 44 45 global ASM_PFX(gcStmSmiHandlerTemplate) 46 global ASM_PFX(gcStmSmiHandlerSize) 47 global ASM_PFX(gcStmSmiHandlerOffset) 48 global ASM_PFX(gStmSmiCr3) 49 global ASM_PFX(gStmSmiStack) 50 global ASM_PFX(gStmSmbase) 51 global ASM_PFX(gStmXdSupported) 52 extern ASM_PFX(gStmSmiHandlerIdtr) 53 54 SECTION .text 55 56 BITS 16 57 ASM_PFX(gcStmSmiHandlerTemplate): 58 _StmSmiEntryPoint: 59 mov bx, _StmGdtDesc - _StmSmiEntryPoint + 0x8000 60 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ] 61 dec ax 62 mov [cs:bx], ax 63 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR] 64 mov [cs:bx + 2], eax 65 mov ebp, eax ; ebp = GDT base 66 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx] 67 mov ax, PROTECT_MODE_CS 68 mov [cs:bx-0x2],ax 69 DB 0x66, 0xbf ; mov edi, SMBASE 70 ASM_PFX(gStmSmbase): DD 0 71 lea eax, [edi + (@32bit - _StmSmiEntryPoint) + 0x8000] 72 mov [cs:bx-0x6],eax 73 mov ebx, cr0 74 and ebx, 0x9ffafff3 75 or ebx, 0x23 76 mov cr0, ebx 77 jmp dword 0x0:0x0 78 _StmGdtDesc: 79 DW 0 80 DD 0 81 82 BITS 32 83 @32bit: 84 mov ax, PROTECT_MODE_DS 85 o16 mov ds, ax 86 o16 mov es, ax 87 o16 mov fs, ax 88 o16 mov gs, ax 89 o16 mov ss, ax 90 DB 0xbc ; mov esp, imm32 91 ASM_PFX(gStmSmiStack): DD 0 92 mov eax, ASM_PFX(gStmSmiHandlerIdtr) 93 lidt [eax] 94 jmp ProtFlatMode 95 96 ProtFlatMode: 97 DB 0xb8 ; mov eax, imm32 98 ASM_PFX(gStmSmiCr3): DD 0 99 mov cr3, eax 100 ; 101 ; Need to test for CR4 specific bit support 102 ; 103 mov eax, 1 104 cpuid ; use CPUID to determine if specific CR4 bits are supported 105 xor eax, eax ; Clear EAX 106 test edx, BIT2 ; Check for DE capabilities 107 jz .0 108 or eax, BIT3 109 .0: 110 test edx, BIT6 ; Check for PAE capabilities 111 jz .1 112 or eax, BIT5 113 .1: 114 test edx, BIT7 ; Check for MCE capabilities 115 jz .2 116 or eax, BIT6 117 .2: 118 test edx, BIT24 ; Check for FXSR capabilities 119 jz .3 120 or eax, BIT9 121 .3: 122 test edx, BIT25 ; Check for SSE capabilities 123 jz .4 124 or eax, BIT10 125 .4: ; as cr4.PGE is not set here, refresh cr3 126 mov cr4, eax ; in PreModifyMtrrs() to flush TLB. 127 128 cmp byte [dword ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))], 0 129 jz .6 130 ; Load TSS 131 mov byte [ebp + TSS_SEGMENT + 5], 0x89 ; clear busy flag 132 mov eax, TSS_SEGMENT 133 ltr ax 134 .6: 135 136 ; enable NXE if supported 137 DB 0b0h ; mov al, imm8 138 ASM_PFX(gStmXdSupported): DB 1 139 cmp al, 0 140 jz @SkipXd 141 ; 142 ; Check XD disable bit 143 ; 144 mov ecx, MSR_IA32_MISC_ENABLE 145 rdmsr 146 push edx ; save MSR_IA32_MISC_ENABLE[63-32] 147 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] 148 jz .5 149 and dx, 0xFFFB ; clear XD Disable bit if it is set 150 wrmsr 151 .5: 152 mov ecx, MSR_EFER 153 rdmsr 154 or ax, MSR_EFER_XD ; enable NXE 155 wrmsr 156 jmp @XdDone 157 @SkipXd: 158 sub esp, 4 159 @XdDone: 160 161 mov ebx, cr0 162 or ebx, 0x80010023 ; enable paging + WP + NE + MP + PE 163 mov cr0, ebx 164 lea ebx, [edi + DSC_OFFSET] 165 mov ax, [ebx + DSC_DS] 166 mov ds, eax 167 mov ax, [ebx + DSC_OTHERSEG] 168 mov es, eax 169 mov fs, eax 170 mov gs, eax 171 mov ax, [ebx + DSC_SS] 172 mov ss, eax 173 174 CommonHandler: 175 mov ebx, [esp + 4] ; CPU Index 176 push ebx 177 mov eax, ASM_PFX(CpuSmmDebugEntry) 178 call eax 179 add esp, 4 180 181 push ebx 182 mov eax, ASM_PFX(SmiRendezvous) 183 call eax 184 add esp, 4 185 186 push ebx 187 mov eax, ASM_PFX(CpuSmmDebugExit) 188 call eax 189 add esp, 4 190 191 mov eax, ASM_PFX(gStmXdSupported) 192 mov al, [eax] 193 cmp al, 0 194 jz .7 195 pop edx ; get saved MSR_IA32_MISC_ENABLE[63-32] 196 test edx, BIT2 197 jz .7 198 mov ecx, MSR_IA32_MISC_ENABLE 199 rdmsr 200 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM 201 wrmsr 202 203 .7: 204 rsm 205 206 207 _StmSmiHandler: 208 ; 209 ; Check XD disable bit 210 ; 211 xor esi, esi 212 mov eax, ASM_PFX(gStmXdSupported) 213 mov al, [eax] 214 cmp al, 0 215 jz @StmXdDone 216 mov ecx, MSR_IA32_MISC_ENABLE 217 rdmsr 218 mov esi, edx ; save MSR_IA32_MISC_ENABLE[63-32] 219 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34] 220 jz .5 221 and dx, 0xFFFB ; clear XD Disable bit if it is set 222 wrmsr 223 .5: 224 mov ecx, MSR_EFER 225 rdmsr 226 or ax, MSR_EFER_XD ; enable NXE 227 wrmsr 228 @StmXdDone: 229 push esi 230 231 ; below step is needed, because STM does not run above code. 232 ; we have to run below code to set IDT/CR0/CR4 233 mov eax, ASM_PFX(gStmSmiHandlerIdtr) 234 lidt [eax] 235 236 mov eax, cr0 237 or eax, 0x80010023 ; enable paging + WP + NE + MP + PE 238 mov cr0, eax 239 ; 240 ; Need to test for CR4 specific bit support 241 ; 242 mov eax, 1 243 cpuid ; use CPUID to determine if specific CR4 bits are supported 244 mov eax, cr4 ; init EAX 245 test edx, BIT2 ; Check for DE capabilities 246 jz .0 247 or eax, BIT3 248 .0: 249 test edx, BIT6 ; Check for PAE capabilities 250 jz .1 251 or eax, BIT5 252 .1: 253 test edx, BIT7 ; Check for MCE capabilities 254 jz .2 255 or eax, BIT6 256 .2: 257 test edx, BIT24 ; Check for FXSR capabilities 258 jz .3 259 or eax, BIT9 260 .3: 261 test edx, BIT25 ; Check for SSE capabilities 262 jz .4 263 or eax, BIT10 264 .4: ; as cr4.PGE is not set here, refresh cr3 265 mov cr4, eax ; in PreModifyMtrrs() to flush TLB. 266 ; STM init finish 267 jmp CommonHandler 268 269 ASM_PFX(gcStmSmiHandlerSize) : DW $ - _StmSmiEntryPoint 270 ASM_PFX(gcStmSmiHandlerOffset) : DW _StmSmiHandler - _StmSmiEntryPoint 271 272