1 #------------------------------------------------------------------------------
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.
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.
18 # Code template of the SMI handler for a particular processor
20 #------------------------------------------------------------------------------
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(FeaturePcdGet (PcdCpuSmmDebug))
28 ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
29 ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)
31 .equ DSC_OFFSET, 0xfb00
39 .equ PROTECT_MODE_CS, 0x08
40 .equ PROTECT_MODE_DS, 0x20
41 .equ TSS_SEGMENT, 0x40
45 ASM_PFX(gcSmiHandlerTemplate):
48 .byte 0xbb # mov bx, imm16
49 .word _GdtDesc - _SmiEntryPoint + 0x8000
50 .byte 0x2e,0xa1 # mov ax, cs:[offset16]
51 .word DSC_OFFSET + DSC_GDTSIZ
53 movl %eax, %cs:(%edi) # mov cs:[bx], ax
54 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
55 .word DSC_OFFSET + DSC_GDTPTR
57 movw %ax, %bp # ebp = GDT base
60 # Patch ProtectedMode Segment
61 .byte 0xb8 # mov ax, imm16
62 .word PROTECT_MODE_CS # set AX for segment directly
63 movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax
64 # Patch ProtectedMode entry
65 .byte 0x66, 0xbf # mov edi, SMBASE
66 ASM_PFX(gSmbase): .space 4
68 lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax
69 movw %ax, %cs:-6(%edi)
72 andl $0x9ffafff3, %ebx
83 movw $PROTECT_MODE_DS, %ax
89 .byte 0xbc # mov esp, imm32
90 ASM_PFX(gSmiStack): .space 4
91 movl $ASM_PFX(gSmiHandlerIdtr), %eax
96 .byte 0xb8 # mov eax, imm32
97 ASM_PFX(gSmiCr3): .space 4
100 # Need to test for CR4 specific bit support
103 cpuid # use CPUID to determine if specific CR4 bits are supported
104 xorl %eax, %eax # Clear EAX
105 testl $BIT2, %edx # Check for DE capabilities
109 testl $BIT6, %edx # Check for PAE capabilities
113 testl $BIT7, %edx # Check for MCE capabilities
117 testl $BIT24, %edx # Check for FXSR capabilities
121 testl $BIT25, %edx # Check for SSE capabilities
124 L12: # as cr4.PGE is not set here, refresh cr3
125 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.
127 orl $0x080000000, %ebx # enable paging
129 leal DSC_OFFSET(%edi),%ebx
130 movw DSC_DS(%ebx),%ax
132 movw DSC_OTHERSEG(%ebx),%ax
136 movw DSC_SS(%ebx),%ax
139 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
143 movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
144 movl $TSS_SEGMENT, %eax
148 # jmp _SmiHandler # instruction is not needed
151 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
158 movl $0x80000001, %eax
160 btl $29, %edx # check cpuid to identify X64 or IA32
161 leal (0x7fc8 - (L1 - _SmiEntryPoint))(%ebp), %edi
170 movl %edx, %dr7 # restore DR6 & DR7 before running C code
175 movl $ASM_PFX(SmiRendezvous), %eax
180 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
191 ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint