1#------------------------------------------------------------------------------ 2# 3# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR> 4# This program and the accompanying materials 5# are licensed and made available under the terms and conditions of the BSD License 6# which accompanies this distribution. The full text of the license may be found at 7# http://opensource.org/licenses/bsd-license.php. 8# 9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 11# 12# Module Name: 13# 14# SmiEntry.S 15# 16# Abstract: 17# 18# Code template of the SMI handler for a particular processor 19# 20#------------------------------------------------------------------------------ 21 22ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate) 23ASM_GLOBAL ASM_PFX(gcSmiHandlerSize) 24ASM_GLOBAL ASM_PFX(gSmiCr3) 25ASM_GLOBAL ASM_PFX(gSmiStack) 26ASM_GLOBAL ASM_PFX(gSmbase) 27ASM_GLOBAL ASM_PFX(mXdSupported) 28ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) 29ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr) 30 31.equ MSR_IA32_MISC_ENABLE, 0x1A0 32.equ MSR_EFER, 0xc0000080 33.equ MSR_EFER_XD, 0x800 34 35# 36# Constants relating to PROCESSOR_SMM_DESCRIPTOR 37# 38.equ DSC_OFFSET, 0xfb00 39.equ DSC_GDTPTR, 0x30 40.equ DSC_GDTSIZ, 0x38 41.equ DSC_CS, 14 42.equ DSC_DS, 16 43.equ DSC_SS, 18 44.equ DSC_OTHERSEG, 20 45 46.equ PROTECT_MODE_CS, 0x08 47.equ PROTECT_MODE_DS, 0x20 48.equ TSS_SEGMENT, 0x40 49 50 .text 51 52ASM_PFX(gcSmiHandlerTemplate): 53 54_SmiEntryPoint: 55 .byte 0xbb # mov bx, imm16 56 .word _GdtDesc - _SmiEntryPoint + 0x8000 57 .byte 0x2e,0xa1 # mov ax, cs:[offset16] 58 .word DSC_OFFSET + DSC_GDTSIZ 59 decl %eax 60 movl %eax, %cs:(%edi) # mov cs:[bx], ax 61 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16] 62 .word DSC_OFFSET + DSC_GDTPTR 63 movw %ax, %cs:2(%edi) 64 movw %ax, %bp # ebp = GDT base 65 .byte 0x66 66 lgdt %cs:(%edi) 67# Patch ProtectedMode Segment 68 .byte 0xb8 # mov ax, imm16 69 .word PROTECT_MODE_CS # set AX for segment directly 70 movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax 71# Patch ProtectedMode entry 72 .byte 0x66, 0xbf # mov edi, SMBASE 73ASM_PFX(gSmbase): .space 4 74 .byte 0x67 75 lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax 76 movw %ax, %cs:-6(%edi) 77 movl %cr0, %ebx 78 .byte 0x66 79 andl $0x9ffafff3, %ebx 80 .byte 0x66 81 orl $0x23, %ebx 82 movl %ebx, %cr0 83 .byte 0x66,0xea 84 .space 4 85 .space 2 86_GdtDesc: .space 4 87 .space 2 88 89Start32bit: 90 movw $PROTECT_MODE_DS, %ax 91 movl %eax,%ds 92 movl %eax,%es 93 movl %eax,%fs 94 movl %eax,%gs 95 movl %eax,%ss 96 .byte 0xbc # mov esp, imm32 97ASM_PFX(gSmiStack): .space 4 98 movl $ASM_PFX(gSmiHandlerIdtr), %eax 99 lidt (%eax) 100 jmp ProtFlatMode 101 102ProtFlatMode: 103 .byte 0xb8 # mov eax, imm32 104ASM_PFX(gSmiCr3): .space 4 105 movl %eax, %cr3 106# 107# Need to test for CR4 specific bit support 108# 109 movl $1, %eax 110 cpuid # use CPUID to determine if specific CR4 bits are supported 111 xorl %eax, %eax # Clear EAX 112 testl $BIT2, %edx # Check for DE capabilities 113 jz L8 114 orl $BIT3, %eax 115L8: 116 testl $BIT6, %edx # Check for PAE capabilities 117 jz L9 118 orl $BIT5, %eax 119L9: 120 testl $BIT7, %edx # Check for MCE capabilities 121 jz L10 122 orl $BIT6, %eax 123L10: 124 testl $BIT24, %edx # Check for FXSR capabilities 125 jz L11 126 orl $BIT9, %eax 127L11: 128 testl $BIT25, %edx # Check for SSE capabilities 129 jz L12 130 orl $BIT10, %eax 131L12: # as cr4.PGE is not set here, refresh cr3 132 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB. 133 134 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) 135 jz L5 136# Load TSS 137 movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag 138 movl $TSS_SEGMENT, %eax 139 ltrw %ax 140L5: 141 142# enable NXE if supported 143 .byte 0xb0 # mov al, imm8 144ASM_PFX(mXdSupported): .byte 1 145 cmpb $0, %al 146 jz SkipNxe 147# 148# Check XD disable bit 149# 150 movl $MSR_IA32_MISC_ENABLE, %ecx 151 rdmsr 152 pushl %edx # save MSR_IA32_MISC_ENABLE[63-32] 153 testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34] 154 jz L13 155 andw $0x0FFFB, %dx # clear XD Disable bit if it is set 156 wrmsr 157L13: 158 movl $MSR_EFER, %ecx 159 rdmsr 160 orw $MSR_EFER_XD,%ax # enable NXE 161 wrmsr 162SkipNxe: 163 subl $4, %esp 164NxeDone: 165 166 movl %cr0, %ebx 167 orl $0x080010023, %ebx # enable paging + WP + NE + MP + PE 168 movl %ebx, %cr0 169 leal DSC_OFFSET(%edi),%ebx 170 movw DSC_DS(%ebx),%ax 171 movl %eax, %ds 172 movw DSC_OTHERSEG(%ebx),%ax 173 movl %eax, %es 174 movl %eax, %fs 175 movl %eax, %gs 176 movw DSC_SS(%ebx),%ax 177 movl %eax, %ss 178 179# jmp _SmiHandler # instruction is not needed 180 181_SmiHandler: 182 movl 4(%esp), %ebx 183 184 pushl %ebx 185 movl $ASM_PFX(CpuSmmDebugEntry), %eax 186 call *%eax 187 addl $4, %esp 188 189 pushl %ebx 190 movl $ASM_PFX(SmiRendezvous), %eax 191 call *%eax 192 addl $4, %esp 193 194 pushl %ebx 195 movl $ASM_PFX(CpuSmmDebugExit), %eax 196 call *%eax 197 addl $4, %esp 198 199 movl $ASM_PFX(mXdSupported), %eax 200 movb (%eax), %al 201 cmpb $0, %al 202 jz L16 203 popl %edx # get saved MSR_IA32_MISC_ENABLE[63-32] 204 testl $BIT2, %edx 205 jz L16 206 movl $MSR_IA32_MISC_ENABLE, %ecx 207 rdmsr 208 orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM 209 wrmsr 210 211L16: 212 rsm 213 214ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint 215