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