]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
UefiCpuPkg: Add PiSmmCpuDxeSmm module IA32 files
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiEntry.S
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
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)
30
31 .equ DSC_OFFSET, 0xfb00
32 .equ DSC_GDTPTR, 0x30
33 .equ DSC_GDTSIZ, 0x38
34 .equ DSC_CS, 14
35 .equ DSC_DS, 16
36 .equ DSC_SS, 18
37 .equ DSC_OTHERSEG, 20
38
39 .equ PROTECT_MODE_CS, 0x08
40 .equ PROTECT_MODE_DS, 0x20
41 .equ TSS_SEGMENT, 0x40
42
43 .text
44
45 ASM_PFX(gcSmiHandlerTemplate):
46
47 _SmiEntryPoint:
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
52 decl %eax
53 movl %eax, %cs:(%edi) # mov cs:[bx], ax
54 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
55 .word DSC_OFFSET + DSC_GDTPTR
56 movw %ax, %cs:2(%edi)
57 movw %ax, %bp # ebp = GDT base
58 .byte 0x66
59 lgdt %cs:(%edi)
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
67 .byte 0x67
68 lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax
69 movw %ax, %cs:-6(%edi)
70 movl %cr0, %ebx
71 .byte 0x66
72 andl $0x9ffafff3, %ebx
73 .byte 0x66
74 orl $0x23, %ebx
75 movl %ebx, %cr0
76 .byte 0x66,0xea
77 .space 4
78 .space 2
79 _GdtDesc: .space 4
80 .space 2
81
82 Start32bit:
83 movw $PROTECT_MODE_DS, %ax
84 movl %eax,%ds
85 movl %eax,%es
86 movl %eax,%fs
87 movl %eax,%gs
88 movl %eax,%ss
89 .byte 0xbc # mov esp, imm32
90 ASM_PFX(gSmiStack): .space 4
91 movl $ASM_PFX(gSmiHandlerIdtr), %eax
92 lidt (%eax)
93 jmp ProtFlatMode
94
95 ProtFlatMode:
96 .byte 0xb8 # mov eax, imm32
97 ASM_PFX(gSmiCr3): .space 4
98 movl %eax, %cr3
99 #
100 # Need to test for CR4 specific bit support
101 #
102 movl $1, %eax
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
106 jz L8
107 orl $BIT3, %eax
108 L8:
109 testl $BIT6, %edx # Check for PAE capabilities
110 jz L9
111 orl $BIT5, %eax
112 L9:
113 testl $BIT7, %edx # Check for MCE capabilities
114 jz L10
115 orl $BIT6, %eax
116 L10:
117 testl $BIT24, %edx # Check for FXSR capabilities
118 jz L11
119 orl $BIT9, %eax
120 L11:
121 testl $BIT25, %edx # Check for SSE capabilities
122 jz L12
123 orl $BIT10, %eax
124 L12: # as cr4.PGE is not set here, refresh cr3
125 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.
126 movl %cr0, %ebx
127 orl $0x080000000, %ebx # enable paging
128 movl %ebx, %cr0
129 leal DSC_OFFSET(%edi),%ebx
130 movw DSC_DS(%ebx),%ax
131 movl %eax, %ds
132 movw DSC_OTHERSEG(%ebx),%ax
133 movl %eax, %es
134 movl %eax, %fs
135 movl %eax, %gs
136 movw DSC_SS(%ebx),%ax
137 movl %eax, %ss
138
139 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
140 jz L5
141
142 # Load TSS
143 movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
144 movl $TSS_SEGMENT, %eax
145 ltrw %ax
146 L5:
147
148 # jmp _SmiHandler # instruction is not needed
149
150 _SmiHandler:
151 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
152 jz L3
153
154 L6:
155 call L1
156 L1:
157 popl %ebp
158 movl $0x80000001, %eax
159 cpuid
160 btl $29, %edx # check cpuid to identify X64 or IA32
161 leal (0x7fc8 - (L1 - _SmiEntryPoint))(%ebp), %edi
162 leal 4(%edi), %esi
163 jnc L2
164 addl $4, %esi
165 L2:
166 movl (%esi), %ecx
167 movl (%edi), %edx
168 L7:
169 movl %ecx, %dr6
170 movl %edx, %dr7 # restore DR6 & DR7 before running C code
171 L3:
172
173 pushl (%esp)
174
175 movl $ASM_PFX(SmiRendezvous), %eax
176 call *%eax
177 popl %ecx
178
179
180 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))
181 jz L4
182
183 movl %dr6, %ecx
184 movl %dr7, %edx
185 movl %ecx, (%esi)
186 movl %edx, (%edi)
187 L4:
188
189 rsm
190
191 ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint