]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.asm
Install LoadedImage protocol for PiSmmCore.
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.asm
CommitLineData
427e3573
MK
1;------------------------------------------------------------------------------ ;\r
2; Copyright (c) 2009 - 2015, 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 gcSmiHandlerTemplate:BYTE\r
26EXTERNDEF gcSmiHandlerSize:WORD\r
27EXTERNDEF gSmiCr3:DWORD\r
28EXTERNDEF gSmiStack:DWORD\r
29EXTERNDEF gSmbase:DWORD\r
30EXTERNDEF FeaturePcdGet (PcdCpuSmmDebug):BYTE\r
31EXTERNDEF gSmiHandlerIdtr:FWORD\r
32\r
33\r
34;\r
35; Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
36;\r
37DSC_OFFSET EQU 0fb00h\r
38DSC_GDTPTR EQU 30h\r
39DSC_GDTSIZ EQU 38h\r
40DSC_CS EQU 14\r
41DSC_DS EQU 16\r
42DSC_SS EQU 18\r
43DSC_OTHERSEG EQU 20\r
44;\r
45; Constants relating to CPU State Save Area\r
46;\r
47SSM_DR6 EQU 0ffd0h\r
48SSM_DR7 EQU 0ffc8h\r
49\r
50PROTECT_MODE_CS EQU 08h\r
51PROTECT_MODE_DS EQU 20h\r
52LONG_MODE_CS EQU 38h\r
53TSS_SEGMENT EQU 40h\r
54GDT_SIZE EQU 50h\r
55\r
56 .code\r
57\r
58gcSmiHandlerTemplate LABEL BYTE\r
59\r
60_SmiEntryPoint:\r
61 ;\r
62 ; The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-\r
63 ; bit addressing mode. And that coincidence has been used in the following\r
64 ; "64-bit like" 16-bit code. Be aware that once RDI is referenced as a\r
65 ; base address register, it is actually BX that is referenced.\r
66 ;\r
67 DB 0bbh ; mov bx, imm16\r
68 DW offset _GdtDesc - _SmiEntryPoint + 8000h ; bx = GdtDesc offset\r
69; fix GDT descriptor\r
70 DB 2eh, 0a1h ; mov ax, cs:[offset16]\r
71 DW DSC_OFFSET + DSC_GDTSIZ\r
72 DB 48h ; dec ax\r
73 DB 2eh\r
74 mov [rdi], eax ; mov cs:[bx], ax\r
75 DB 66h, 2eh, 0a1h ; mov eax, cs:[offset16]\r
76 DW DSC_OFFSET + DSC_GDTPTR\r
77 DB 2eh\r
78 mov [rdi + 2], ax ; mov cs:[bx + 2], eax\r
79 DB 66h, 2eh\r
80 lgdt fword ptr [rdi] ; lgdt fword ptr cs:[bx]\r
81; Patch ProtectedMode Segment\r
82 DB 0b8h ; mov ax, imm16\r
83 DW PROTECT_MODE_CS ; set AX for segment directly\r
84 DB 2eh\r
85 mov [rdi - 2], eax ; mov cs:[bx - 2], ax\r
86; Patch ProtectedMode entry\r
87 DB 66h, 0bfh ; mov edi, SMBASE\r
88gSmbase DD ?\r
89 lea ax, [edi + (@ProtectedMode - _SmiEntryPoint) + 8000h]\r
90 DB 2eh\r
91 mov [rdi - 6], ax ; mov cs:[bx - 6], eax\r
92; Switch into @ProtectedMode\r
93 mov rbx, cr0\r
94 DB 66h\r
95 and ebx, 9ffafff3h\r
96 DB 66h\r
97 or ebx, 00000023h\r
98\r
99 mov cr0, rbx\r
100 DB 66h, 0eah\r
101 DD ?\r
102 DW ?\r
103\r
104_GdtDesc FWORD ?\r
105@ProtectedMode:\r
106 mov ax, PROTECT_MODE_DS\r
107 mov ds, ax\r
108 mov es, ax\r
109 mov fs, ax\r
110 mov gs, ax\r
111 mov ss, ax\r
112 DB 0bch ; mov esp, imm32\r
113gSmiStack DD ?\r
114 jmp ProtFlatMode\r
115\r
116ProtFlatMode:\r
117 DB 0b8h ; mov eax, offset gSmiCr3\r
118gSmiCr3 DD ?\r
119 mov cr3, rax\r
120 mov eax, 668h ; as cr4.PGE is not set here, refresh cr3\r
121 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.\r
122; Load TSS\r
123 sub esp, 8 ; reserve room in stack\r
124 sgdt fword ptr [rsp]\r
125 mov eax, [rsp + 2] ; eax = GDT base\r
126 add esp, 8\r
427e3573
MK
127 mov dl, 89h\r
128 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag\r
129 mov eax, TSS_SEGMENT\r
130 ltr ax\r
131\r
132; Switch into @LongMode\r
133 push LONG_MODE_CS ; push cs hardcore here\r
134 call Base ; push return address for retf later\r
135Base:\r
136 add dword ptr [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg\r
137 mov ecx, 0c0000080h\r
138 rdmsr\r
139 or ah, 1\r
140 wrmsr\r
141 mov rbx, cr0\r
142 bts ebx, 31\r
143 mov cr0, rbx\r
144 retf\r
145@LongMode: ; long mode (64-bit code) starts here\r
146 mov rax, offset gSmiHandlerIdtr\r
147 lidt fword ptr [rax]\r
148 lea ebx, [rdi + DSC_OFFSET]\r
149 mov ax, [rbx + DSC_DS]\r
150 mov ds, eax\r
151 mov ax, [rbx + DSC_OTHERSEG]\r
152 mov es, eax\r
153 mov fs, eax\r
154 mov gs, eax\r
155 mov ax, [rbx + DSC_SS]\r
156 mov ss, eax\r
157; jmp _SmiHandler ; instruction is not needed\r
158\r
159_SmiHandler:\r
160;\r
161; The following lines restore DR6 & DR7 before running C code. They are useful\r
162; when you want to enable hardware breakpoints in SMM.\r
163;\r
164; NOTE: These lines might not be appreciated in runtime since they might\r
165; conflict with OS debugging facilities. Turn them off in RELEASE.\r
166;\r
167 mov rax, offset FeaturePcdGet (PcdCpuSmmDebug) ;Get absolute address. Avoid RIP relative addressing\r
168 cmp byte ptr [rax], 0\r
169 jz @1\r
170\r
171 DB 48h, 8bh, 0dh ; mov rcx, [rip + disp32]\r
172 DD SSM_DR6 - ($ + 4 - _SmiEntryPoint + 8000h)\r
173 DB 48h, 8bh, 15h ; mov rdx, [rip + disp32]\r
174 DD SSM_DR7 - ($ + 4 - _SmiEntryPoint + 8000h)\r
175 mov dr6, rcx\r
176 mov dr7, rdx\r
177@1:\r
178 mov rcx, [rsp] ; rcx <- CpuIndex\r
179 mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous\r
180\r
181 ;\r
182 ; Save FP registers\r
183 ;\r
184 sub rsp, 208h\r
185 DB 48h ; FXSAVE64\r
186 fxsave [rsp]\r
187\r
188 add rsp, -20h\r
189 call rax\r
190 add rsp, 20h\r
191\r
192 ;\r
193 ; Restore FP registers\r
194 ;\r
195 DB 48h ; FXRSTOR64\r
196 fxrstor [rsp]\r
197\r
198 mov rax, offset FeaturePcdGet (PcdCpuSmmDebug) ;Get absolute address. Avoid RIP relative addressing\r
199 cmp byte ptr [rax], 0\r
200 jz @2\r
201\r
202 mov rdx, dr7\r
203 mov rcx, dr6\r
204 DB 48h, 89h, 15h ; mov [rip + disp32], rdx\r
205 DD SSM_DR7 - ($ + 4 - _SmiEntryPoint + 8000h)\r
206 DB 48h, 89h, 0dh ; mov [rip + disp32], rcx\r
207 DD SSM_DR6 - ($ + 4 - _SmiEntryPoint + 8000h)\r
208@2:\r
209 rsm\r
210\r
211gcSmiHandlerSize DW $ - _SmiEntryPoint\r
212\r
213 END\r