1#------------------------------------------------------------------------------ 2# 3# Copyright (c) 2009 - 2015, 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(FeaturePcdGet (PcdCpuSmmStackGuard)) 28ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr) 29 30.equ DSC_OFFSET, 0xfb00 31.equ DSC_GDTPTR, 0x30 32.equ DSC_GDTSIZ, 0x38 33.equ DSC_CS, 14 34.equ DSC_DS, 16 35.equ DSC_SS, 18 36.equ DSC_OTHERSEG, 20 37 38.equ PROTECT_MODE_CS, 0x08 39.equ PROTECT_MODE_DS, 0x20 40.equ TSS_SEGMENT, 0x40 41 42 .text 43 44ASM_PFX(gcSmiHandlerTemplate): 45 46_SmiEntryPoint: 47 .byte 0xbb # mov bx, imm16 48 .word _GdtDesc - _SmiEntryPoint + 0x8000 49 .byte 0x2e,0xa1 # mov ax, cs:[offset16] 50 .word DSC_OFFSET + DSC_GDTSIZ 51 decl %eax 52 movl %eax, %cs:(%edi) # mov cs:[bx], ax 53 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16] 54 .word DSC_OFFSET + DSC_GDTPTR 55 movw %ax, %cs:2(%edi) 56 movw %ax, %bp # ebp = GDT base 57 .byte 0x66 58 lgdt %cs:(%edi) 59# Patch ProtectedMode Segment 60 .byte 0xb8 # mov ax, imm16 61 .word PROTECT_MODE_CS # set AX for segment directly 62 movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax 63# Patch ProtectedMode entry 64 .byte 0x66, 0xbf # mov edi, SMBASE 65ASM_PFX(gSmbase): .space 4 66 .byte 0x67 67 lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax 68 movw %ax, %cs:-6(%edi) 69 movl %cr0, %ebx 70 .byte 0x66 71 andl $0x9ffafff3, %ebx 72 .byte 0x66 73 orl $0x23, %ebx 74 movl %ebx, %cr0 75 .byte 0x66,0xea 76 .space 4 77 .space 2 78_GdtDesc: .space 4 79 .space 2 80 81Start32bit: 82 movw $PROTECT_MODE_DS, %ax 83 movl %eax,%ds 84 movl %eax,%es 85 movl %eax,%fs 86 movl %eax,%gs 87 movl %eax,%ss 88 .byte 0xbc # mov esp, imm32 89ASM_PFX(gSmiStack): .space 4 90 movl $ASM_PFX(gSmiHandlerIdtr), %eax 91 lidt (%eax) 92 jmp ProtFlatMode 93 94ProtFlatMode: 95 .byte 0xb8 # mov eax, imm32 96ASM_PFX(gSmiCr3): .space 4 97 movl %eax, %cr3 98# 99# Need to test for CR4 specific bit support 100# 101 movl $1, %eax 102 cpuid # use CPUID to determine if specific CR4 bits are supported 103 xorl %eax, %eax # Clear EAX 104 testl $BIT2, %edx # Check for DE capabilities 105 jz L8 106 orl $BIT3, %eax 107L8: 108 testl $BIT6, %edx # Check for PAE capabilities 109 jz L9 110 orl $BIT5, %eax 111L9: 112 testl $BIT7, %edx # Check for MCE capabilities 113 jz L10 114 orl $BIT6, %eax 115L10: 116 testl $BIT24, %edx # Check for FXSR capabilities 117 jz L11 118 orl $BIT9, %eax 119L11: 120 testl $BIT25, %edx # Check for SSE capabilities 121 jz L12 122 orl $BIT10, %eax 123L12: # as cr4.PGE is not set here, refresh cr3 124 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB. 125 movl %cr0, %ebx 126 orl $0x080010000, %ebx # enable paging + WP 127 movl %ebx, %cr0 128 leal DSC_OFFSET(%edi),%ebx 129 movw DSC_DS(%ebx),%ax 130 movl %eax, %ds 131 movw DSC_OTHERSEG(%ebx),%ax 132 movl %eax, %es 133 movl %eax, %fs 134 movl %eax, %gs 135 movw DSC_SS(%ebx),%ax 136 movl %eax, %ss 137 138 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard)) 139 jz L5 140 141# Load TSS 142 movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag 143 movl $TSS_SEGMENT, %eax 144 ltrw %ax 145L5: 146 147# jmp _SmiHandler # instruction is not needed 148 149_SmiHandler: 150 movl (%esp), %ebx 151 152 pushl %ebx 153 movl $ASM_PFX(CpuSmmDebugEntry), %eax 154 call *%eax 155 popl %ecx 156 157 pushl %ebx 158 movl $ASM_PFX(SmiRendezvous), %eax 159 call *%eax 160 popl %ecx 161 162 pushl %ebx 163 movl $ASM_PFX(CpuSmmDebugExit), %eax 164 call *%eax 165 popl %ecx 166 167 rsm 168 169ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint 170