]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmiEntry.S
UefiCpuPkg/PiSmmCpuDxeSmm: Remove PSD layout assumptions
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / Ia32 / SmiEntry.S
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_EFER, 0xc0000080
32 .equ MSR_EFER_XD, 0x800
33
34 #
35 # Constants relating to PROCESSOR_SMM_DESCRIPTOR
36 #
37 .equ DSC_OFFSET, 0xfb00
38 .equ DSC_GDTPTR, 0x30
39 .equ DSC_GDTSIZ, 0x38
40 .equ DSC_CS, 14
41 .equ DSC_DS, 16
42 .equ DSC_SS, 18
43 .equ DSC_OTHERSEG, 20
44
45 .equ PROTECT_MODE_CS, 0x08
46 .equ PROTECT_MODE_DS, 0x20
47 .equ TSS_SEGMENT, 0x40
48
49 .text
50
51 ASM_PFX(gcSmiHandlerTemplate):
52
53 _SmiEntryPoint:
54 .byte 0xbb # mov bx, imm16
55 .word _GdtDesc - _SmiEntryPoint + 0x8000
56 .byte 0x2e,0xa1 # mov ax, cs:[offset16]
57 .word DSC_OFFSET + DSC_GDTSIZ
58 decl %eax
59 movl %eax, %cs:(%edi) # mov cs:[bx], ax
60 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]
61 .word DSC_OFFSET + DSC_GDTPTR
62 movw %ax, %cs:2(%edi)
63 movw %ax, %bp # ebp = GDT base
64 .byte 0x66
65 lgdt %cs:(%edi)
66 # Patch ProtectedMode Segment
67 .byte 0xb8 # mov ax, imm16
68 .word PROTECT_MODE_CS # set AX for segment directly
69 movl %eax, %cs:-2(%edi) # mov cs:[bx - 2], ax
70 # Patch ProtectedMode entry
71 .byte 0x66, 0xbf # mov edi, SMBASE
72 ASM_PFX(gSmbase): .space 4
73 .byte 0x67
74 lea ((Start32bit - _SmiEntryPoint) + 0x8000)(%edi), %ax
75 movw %ax, %cs:-6(%edi)
76 movl %cr0, %ebx
77 .byte 0x66
78 andl $0x9ffafff3, %ebx
79 .byte 0x66
80 orl $0x23, %ebx
81 movl %ebx, %cr0
82 .byte 0x66,0xea
83 .space 4
84 .space 2
85 _GdtDesc: .space 4
86 .space 2
87
88 Start32bit:
89 movw $PROTECT_MODE_DS, %ax
90 movl %eax,%ds
91 movl %eax,%es
92 movl %eax,%fs
93 movl %eax,%gs
94 movl %eax,%ss
95 .byte 0xbc # mov esp, imm32
96 ASM_PFX(gSmiStack): .space 4
97 movl $ASM_PFX(gSmiHandlerIdtr), %eax
98 lidt (%eax)
99 jmp ProtFlatMode
100
101 ProtFlatMode:
102 .byte 0xb8 # mov eax, imm32
103 ASM_PFX(gSmiCr3): .space 4
104 movl %eax, %cr3
105 #
106 # Need to test for CR4 specific bit support
107 #
108 movl $1, %eax
109 cpuid # use CPUID to determine if specific CR4 bits are supported
110 xorl %eax, %eax # Clear EAX
111 testl $BIT2, %edx # Check for DE capabilities
112 jz L8
113 orl $BIT3, %eax
114 L8:
115 testl $BIT6, %edx # Check for PAE capabilities
116 jz L9
117 orl $BIT5, %eax
118 L9:
119 testl $BIT7, %edx # Check for MCE capabilities
120 jz L10
121 orl $BIT6, %eax
122 L10:
123 testl $BIT24, %edx # Check for FXSR capabilities
124 jz L11
125 orl $BIT9, %eax
126 L11:
127 testl $BIT25, %edx # Check for SSE capabilities
128 jz L12
129 orl $BIT10, %eax
130 L12: # as cr4.PGE is not set here, refresh cr3
131 movl %eax, %cr4 # in PreModifyMtrrs() to flush TLB.
132
133 cmpb $0, ASM_PFX(FeaturePcdGet (PcdCpuSmmStackGuard))
134 jz L5
135 # Load TSS
136 movb $0x89, (TSS_SEGMENT + 5)(%ebp) # clear busy flag
137 movl $TSS_SEGMENT, %eax
138 ltrw %ax
139 L5:
140
141 # enable NXE if supported
142 .byte 0xb0 # mov al, imm8
143 ASM_PFX(mXdSupported): .byte 1
144 cmpb $0, %al
145 jz SkipNxe
146 #
147 # Check XD disable bit
148 #
149 movl $MSR_IA32_MISC_ENABLE, %ecx
150 rdmsr
151 pushl %edx # save MSR_IA32_MISC_ENABLE[63-32]
152 testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34]
153 jz L13
154 andw $0x0FFFB, %dx # clear XD Disable bit if it is set
155 wrmsr
156 L13:
157 movl $MSR_EFER, %ecx
158 rdmsr
159 orw $MSR_EFER_XD,%ax # enable NXE
160 wrmsr
161 SkipNxe:
162 subl $4, %esp
163 NxeDone:
164
165 movl %cr0, %ebx
166 orl $0x080010023, %ebx # enable paging + WP + NE + MP + PE
167 movl %ebx, %cr0
168 leal DSC_OFFSET(%edi),%ebx
169 movw DSC_DS(%ebx),%ax
170 movl %eax, %ds
171 movw DSC_OTHERSEG(%ebx),%ax
172 movl %eax, %es
173 movl %eax, %fs
174 movl %eax, %gs
175 movw DSC_SS(%ebx),%ax
176 movl %eax, %ss
177
178 # jmp _SmiHandler # instruction is not needed
179
180 _SmiHandler:
181 movl 4(%esp), %ebx
182
183 pushl %ebx
184 movl $ASM_PFX(CpuSmmDebugEntry), %eax
185 call *%eax
186 addl $4, %esp
187
188 pushl %ebx
189 movl $ASM_PFX(SmiRendezvous), %eax
190 call *%eax
191 addl $4, %esp
192
193 pushl %ebx
194 movl $ASM_PFX(CpuSmmDebugExit), %eax
195 call *%eax
196 addl $4, %esp
197
198 movl $ASM_PFX(mXdSupported), %eax
199 movb (%eax), %al
200 cmpb $0, %al
201 jz L16
202 popl %edx # get saved MSR_IA32_MISC_ENABLE[63-32]
203 testl $BIT2, %edx
204 jz L16
205 movl $MSR_IA32_MISC_ENABLE, %ecx
206 rdmsr
207 orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM
208 wrmsr
209
210 L16:
211 rsm
212
213 ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint