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