]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
MdeModulePkg/NonDiscoverablePciDeviceDxe: add support for non-coherent DMA
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.asm
... / ...
CommitLineData
1;------------------------------------------------------------------------------ ;\r
2; Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
3; This program and the accompanying materials\r
4; are licensed and made available under the terms and conditions of the BSD License\r
5; which accompanies this distribution. The full text of the license may be found at\r
6; http://opensource.org/licenses/bsd-license.php.\r
7;\r
8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10;\r
11; Module Name:\r
12;\r
13; SmiEntry.asm\r
14;\r
15; Abstract:\r
16;\r
17; Code template of the SMI handler for a particular processor\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
21;\r
22; Variables referenced by C code\r
23;\r
24EXTERNDEF SmiRendezvous:PROC\r
25EXTERNDEF CpuSmmDebugEntry:PROC\r
26EXTERNDEF CpuSmmDebugExit:PROC\r
27EXTERNDEF gcSmiHandlerTemplate:BYTE\r
28EXTERNDEF gcSmiHandlerSize:WORD\r
29EXTERNDEF gSmiCr3:DWORD\r
30EXTERNDEF gSmiStack:DWORD\r
31EXTERNDEF gSmbase:DWORD\r
32EXTERNDEF mXdSupported:BYTE\r
33EXTERNDEF gSmiHandlerIdtr:FWORD\r
34\r
35MSR_IA32_MISC_ENABLE EQU 1A0h\r
36MSR_EFER EQU 0c0000080h\r
37MSR_EFER_XD EQU 0800h\r
38\r
39;\r
40; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
41;\r
42DSC_OFFSET EQU 0fb00h\r
43DSC_GDTPTR EQU 30h\r
44DSC_GDTSIZ EQU 38h\r
45DSC_CS EQU 14\r
46DSC_DS EQU 16\r
47DSC_SS EQU 18\r
48DSC_OTHERSEG EQU 20\r
49;\r
50; Constants relating to CPU State Save Area\r
51;\r
52SSM_DR6 EQU 0ffd0h\r
53SSM_DR7 EQU 0ffc8h\r
54\r
55PROTECT_MODE_CS EQU 08h\r
56PROTECT_MODE_DS EQU 20h\r
57LONG_MODE_CS EQU 38h\r
58TSS_SEGMENT EQU 40h\r
59GDT_SIZE EQU 50h\r
60\r
61 .code\r
62\r
63gcSmiHandlerTemplate LABEL BYTE\r
64\r
65_SmiEntryPoint:\r
66 ;\r
67 ; The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-\r
68 ; bit addressing mode. And that coincidence has been used in the following\r
69 ; "64-bit like" 16-bit code. Be aware that once RDI is referenced as a\r
70 ; base address register, it is actually BX that is referenced.\r
71 ;\r
72 DB 0bbh ; mov bx, imm16\r
73 DW offset _GdtDesc - _SmiEntryPoint + 8000h ; bx = GdtDesc offset\r
74; fix GDT descriptor\r
75 DB 2eh, 0a1h ; mov ax, cs:[offset16]\r
76 DW DSC_OFFSET + DSC_GDTSIZ\r
77 DB 48h ; dec ax\r
78 DB 2eh\r
79 mov [rdi], eax ; mov cs:[bx], ax\r
80 DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]\r
81 DW DSC_OFFSET + DSC_GDTPTR\r
82 DB 2eh\r
83 mov [rdi + 2], ax ; mov cs:[bx + 2], eax\r
84 DB 66h, 2eh\r
85 lgdt fword ptr [rdi] ; lgdt fword ptr cs:[bx]\r
86; Patch ProtectedMode Segment\r
87 DB 0b8h ; mov ax, imm16\r
88 DW PROTECT_MODE_CS ; set AX for segment directly\r
89 DB 2eh\r
90 mov [rdi - 2], eax ; mov cs:[bx - 2], ax\r
91; Patch ProtectedMode entry\r
92 DB 66h, 0bfh ; mov edi, SMBASE\r
93gSmbase DD ?\r
94 lea ax, [edi + (@ProtectedMode - _SmiEntryPoint) + 8000h]\r
95 DB 2eh\r
96 mov [rdi - 6], ax ; mov cs:[bx - 6], eax\r
97; Switch into @ProtectedMode\r
98 mov rbx, cr0\r
99 DB 66h\r
100 and ebx, 9ffafff3h\r
101 DB 66h\r
102 or ebx, 00000023h\r
103\r
104 mov cr0, rbx\r
105 DB 66h, 0eah\r
106 DD ?\r
107 DW ?\r
108\r
109_GdtDesc FWORD ?\r
110@ProtectedMode:\r
111 mov ax, PROTECT_MODE_DS\r
112 mov ds, ax\r
113 mov es, ax\r
114 mov fs, ax\r
115 mov gs, ax\r
116 mov ss, ax\r
117 DB 0bch ; mov esp, imm32\r
118gSmiStack DD ?\r
119 jmp ProtFlatMode\r
120\r
121ProtFlatMode:\r
122 DB 0b8h ; mov eax, offset gSmiCr3\r
123gSmiCr3 DD ?\r
124 mov cr3, rax\r
125 mov eax, 668h ; as cr4.PGE is not set here, refresh cr3\r
126 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.\r
127; Load TSS\r
128 sub esp, 8 ; reserve room in stack\r
129 sgdt fword ptr [rsp]\r
130 mov eax, [rsp + 2] ; eax = GDT base\r
131 add esp, 8\r
132 mov dl, 89h\r
133 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
134 mov eax, TSS_SEGMENT\r
135 ltr ax\r
136\r
137; enable NXE if supported\r
138 DB 0b0h ; mov al, imm8\r
139mXdSupported DB 1\r
140 cmp al, 0\r
141 jz @SkipXd\r
142;\r
143; Check XD disable bit\r
144;\r
145 mov ecx, MSR_IA32_MISC_ENABLE\r
146 rdmsr\r
147 sub esp, 4\r
148 push rdx ; save MSR_IA32_MISC_ENABLE[63-32]\r
149 test edx, BIT2 ; MSR_IA32_MISC_ENABLE[34]\r
150 jz @f\r
151 and dx, 0FFFBh ; clear XD Disable bit if it is set\r
152 wrmsr\r
153@@:\r
154 mov ecx, MSR_EFER\r
155 rdmsr\r
156 or ax, MSR_EFER_XD ; enable NXE\r
157 wrmsr\r
158 jmp @XdDone\r
159@SkipXd:\r
160 sub esp, 8\r
161@XdDone:\r
162\r
163; Switch into @LongMode\r
164 push LONG_MODE_CS ; push cs hardcore here\r
165 call Base ; push return address for retf later\r
166Base:\r
167 add dword ptr [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg\r
168\r
169 mov ecx, MSR_EFER\r
170 rdmsr\r
171 or ah, 1 ; enable LME\r
172 wrmsr\r
173 mov rbx, cr0\r
174 or ebx, 080010023h ; enable paging + WP + NE + MP + PE\r
175 mov cr0, rbx\r
176 retf\r
177@LongMode: ; long mode (64-bit code) starts here\r
178 mov rax, offset gSmiHandlerIdtr\r
179 lidt fword ptr [rax]\r
180 lea ebx, [rdi + DSC_OFFSET]\r
181 mov ax, [rbx + DSC_DS]\r
182 mov ds, eax\r
183 mov ax, [rbx + DSC_OTHERSEG]\r
184 mov es, eax\r
185 mov fs, eax\r
186 mov gs, eax\r
187 mov ax, [rbx + DSC_SS]\r
188 mov ss, eax\r
189; jmp _SmiHandler ; instruction is not needed\r
190\r
191_SmiHandler:\r
192 mov rbx, [rsp] ; rbx <- CpuIndex\r
193\r
194 ;\r
195 ; Save FP registers\r
196 ;\r
197 sub rsp, 200h\r
198 DB 48h ; FXSAVE64\r
199 fxsave [rsp]\r
200\r
201 add rsp, -20h\r
202\r
203 mov rcx, rbx\r
204 mov rax, CpuSmmDebugEntry\r
205 call rax\r
206\r
207 mov rcx, rbx\r
208 mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous\r
209 call rax\r
210\r
211 mov rcx, rbx\r
212 mov rax, CpuSmmDebugExit\r
213 call rax\r
214\r
215 add rsp, 20h\r
216\r
217 ;\r
218 ; Restore FP registers\r
219 ;\r
220 DB 48h ; FXRSTOR64\r
221 fxrstor [rsp]\r
222\r
223 add rsp, 200h\r
224\r
225 mov rax, ASM_PFX(mXdSupported)\r
226 mov al, [rax]\r
227 cmp al, 0\r
228 jz @f\r
229 pop rdx ; get saved MSR_IA32_MISC_ENABLE[63-32]\r
230 test edx, BIT2\r
231 jz @f\r
232 mov ecx, MSR_IA32_MISC_ENABLE\r
233 rdmsr\r
234 or dx, BIT2 ; set XD Disable bit if it was set before entering into SMM\r
235 wrmsr\r
236\r
237@@:\r
238 rsm\r
239\r
240gcSmiHandlerSize DW $ - _SmiEntryPoint\r
241\r
242 END\r