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 22 ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate) 23 ASM_GLOBAL ASM_PFX(gcSmiHandlerSize) 24 ASM_GLOBAL ASM_PFX(gSmiCr3) 25 ASM_GLOBAL ASM_PFX(gSmiStack) 26 ASM_GLOBAL ASM_PFX(gSmbase) 27 ASM_GLOBAL ASM_PFX(mXdSupported) 28 ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) 29 ASM_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 52 ASM_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 73 ASM_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 89 Start32bit: 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 97 ASM_PFX(gSmiStack): .space 4 98 movl $ASM_PFX(gSmiHandlerIdtr), %eax 99 lidt (%eax) 100 jmp ProtFlatMode 101 102 ProtFlatMode: 103 .byte 0xb8 # mov eax, imm32 104 ASM_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 115 L8: 116 testl $BIT6, %edx # Check for PAE capabilities 117 jz L9 118 orl $BIT5, %eax 119 L9: 120 testl $BIT7, %edx # Check for MCE capabilities 121 jz L10 122 orl $BIT6, %eax 123 L10: 124 testl $BIT24, %edx # Check for FXSR capabilities 125 jz L11 126 orl $BIT9, %eax 127 L11: 128 testl $BIT25, %edx # Check for SSE capabilities 129 jz L12 130 orl $BIT10, %eax 131 L12: # 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 140 L5: 141 142 # enable NXE if supported 143 .byte 0xb0 # mov al, imm8 144 ASM_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 157 L13: 158 movl $MSR_EFER, %ecx 159 rdmsr 160 orw $MSR_EFER_XD,%ax # enable NXE 161 wrmsr 162 SkipNxe: 163 subl $4, %esp 164 NxeDone: 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 211 L16: 212 rsm 213 214 ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint 215