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