]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.S
UefiCpuPkg: Add PiSmmCpuDxeSmm module X64 files
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.S
CommitLineData
427e3573
MK
1#------------------------------------------------------------------------------\r
2#\r
3# Copyright (c) 2009 - 2015, Intel Corporation. All rights reserved.<BR>\r
4# This program and the accompanying materials\r
5# are licensed and made available under the terms and conditions of the BSD License\r
6# which accompanies this distribution. The full text of the license may be found at\r
7# http://opensource.org/licenses/bsd-license.php.\r
8#\r
9# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11#\r
12# Module Name:\r
13#\r
14# SmiEntry.S\r
15#\r
16# Abstract:\r
17#\r
18# Code template of the SMI handler for a particular processor\r
19#\r
20#------------------------------------------------------------------------------\r
21\r
22ASM_GLOBAL ASM_PFX(gcSmiHandlerTemplate)\r
23ASM_GLOBAL ASM_PFX(gcSmiHandlerSize)\r
24ASM_GLOBAL ASM_PFX(gSmiCr3)\r
25ASM_GLOBAL ASM_PFX(gSmiStack)\r
26ASM_GLOBAL ASM_PFX(gSmbase)\r
27ASM_GLOBAL ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug))\r
28ASM_GLOBAL ASM_PFX(gSmiHandlerIdtr)\r
29\r
30#\r
31# Constants relating to PROCESSOR_SMM_DESCRIPTOR\r
32#\r
33.equ DSC_OFFSET, 0xfb00\r
34.equ DSC_GDTPTR, 0x30\r
35.equ DSC_GDTSIZ, 0x38\r
36.equ DSC_CS, 14\r
37.equ DSC_DS, 16\r
38.equ DSC_SS, 18\r
39.equ DSC_OTHERSEG, 20\r
40#\r
41# Constants relating to CPU State Save Area\r
42#\r
43.equ SSM_DR6, 0xffd0\r
44.equ SSM_DR7, 0xffc8\r
45\r
46.equ PROTECT_MODE_CS, 0x08\r
47.equ PROTECT_MODE_DS, 0x20\r
48.equ LONG_MODE_CS, 0x38\r
49.equ TSS_SEGMENT, 0x40\r
50.equ GDT_SIZE, 0x50\r
51\r
52 .text\r
53\r
54ASM_PFX(gcSmiHandlerTemplate):\r
55\r
56_SmiEntryPoint:\r
57 #\r
58 # The encoding of BX in 16-bit addressing mode is the same as of RDI in 64-\r
59 # bit addressing mode. And that coincidence has been used in the following\r
60 # "64-bit like" 16-bit code. Be aware that once RDI is referenced as a\r
61 # base address register, it is actually BX that is referenced.\r
62 #\r
63 .byte 0xbb # mov bx, imm16\r
64 .word _GdtDesc - _SmiEntryPoint + 0x8000\r
65 #\r
66 # fix GDT descriptor\r
67 #\r
68 .byte 0x2e,0xa1 # mov ax, cs:[offset16]\r
69 .word DSC_OFFSET + DSC_GDTSIZ\r
70 .byte 0x48 # dec ax\r
71 .byte 0x2e\r
72 movl %eax, (%rdi) # mov cs:[bx], ax\r
73 .byte 0x66,0x2e,0xa1 # mov eax, cs:[offset16]\r
74 .word DSC_OFFSET + DSC_GDTPTR\r
75 .byte 0x2e\r
76 movw %ax, 2(%rdi)\r
77 .byte 0x66,0x2e\r
78 lgdt (%rdi)\r
79 #\r
80 # Patch ProtectedMode Segment\r
81 #\r
82 .byte 0xb8\r
83 .word PROTECT_MODE_CS\r
84 .byte 0x2e\r
85 movl %eax, -2(%rdi)\r
86 #\r
87 # Patch ProtectedMode entry\r
88 #\r
89 .byte 0x66, 0xbf # mov edi, SMBASE\r
90ASM_PFX(gSmbase): .space 4\r
91 lea ((ProtectedMode - _SmiEntryPoint) + 0x8000)(%edi), %ax\r
92 .byte 0x2e\r
93 movw %ax, -6(%rdi)\r
94 #\r
95 # Switch into ProtectedMode\r
96 #\r
97 movq %cr0, %rbx\r
98 .byte 0x66\r
99 andl $0x9ffafff3, %ebx\r
100 .byte 0x66\r
101 orl $0x00000023, %ebx\r
102\r
103 movq %rbx, %cr0\r
104 .byte 0x66, 0xea\r
105 .space 6\r
106\r
107_GdtDesc: .space 6\r
108\r
109ProtectedMode:\r
110 movw $PROTECT_MODE_DS, %ax\r
111 movl %eax, %ds\r
112 movl %eax, %es\r
113 movl %eax, %fs\r
114 movl %eax, %gs\r
115 movl %eax, %ss\r
116 .byte 0xbc # mov esp, imm32\r
117ASM_PFX(gSmiStack): .space 4\r
118 jmp ProtFlatMode\r
119\r
120ProtFlatMode:\r
121 .byte 0xb8\r
122ASM_PFX(gSmiCr3): .space 4\r
123 movq %rax, %cr3\r
124 movl $0x668,%eax # as cr4.PGE is not set here, refresh cr3\r
125 movq %rax, %cr4 # in PreModifyMtrrs() to flush TLB.\r
126# Load TSS\r
127 subl $8, %esp # reserve room in stack\r
128 sgdt (%rsp)\r
129 movl 2(%rsp), %eax # eax = GDT base\r
130 addl $8, %esp\r
131 movl %eax, %edx\r
132 addl $GDT_SIZE, %edx\r
133 movb %dl, (TSS_SEGMENT + 2)(%rax)\r
134 movb %dh, (TSS_SEGMENT + 3)(%rax)\r
135 .byte 0xc1, 0xea, 0x10 # shr edx, 16\r
136 movb %dl, (TSS_SEGMENT + 4)(%rax)\r
137 movb %dh, (TSS_SEGMENT + 7)(%rax)\r
138 movl %eax, %edx\r
139 movb $0x89, %dl\r
140 movb %dl, (TSS_SEGMENT + 5)(%rax) # clear busy flag\r
141 movl $TSS_SEGMENT, %eax\r
142 ltr %ax\r
143\r
144 #\r
145 # Switch to LongMode\r
146 #\r
147 pushq $LONG_MODE_CS # push cs hardcore here\r
148 call Base # push return address for retf later\r
149Base:\r
150 addl $(LongMode - Base), (%rsp) # offset for far retf, seg is the 1st arg\r
151 movl $0xc0000080, %ecx\r
152 rdmsr\r
153 orb $1,%ah\r
154 wrmsr\r
155 movq %cr0, %rbx\r
156 btsl $31, %ebx\r
157 movq %rbx, %cr0\r
158 retf\r
159LongMode: # long mode (64-bit code) starts here\r
160 movabsq $ASM_PFX(gSmiHandlerIdtr), %rax\r
161 lidt (%rax)\r
162 lea (DSC_OFFSET)(%rdi), %ebx\r
163 movw DSC_DS(%rbx), %ax\r
164 movl %eax,%ds\r
165 movw DSC_OTHERSEG(%rbx), %ax\r
166 movl %eax,%es\r
167 movl %eax,%fs\r
168 movl %eax,%gs\r
169 movw DSC_SS(%rbx), %ax\r
170 movl %eax,%ss\r
171# jmp _SmiHandler ; instruction is not needed\r
172\r
173_SmiHandler:\r
174 movabsq $ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug)), %rax\r
175 cmpb $0, (%rax)\r
176 jz L1\r
177\r
178 .byte 0x48, 0x8b, 0x0d # mov rcx, [rip + disp32]\r
179 .long SSM_DR6 - (. + 4 - _SmiEntryPoint + 0x8000)\r
180 .byte 0x48, 0x8b, 0x15 # mov rdx, [rip + disp32]\r
181 .long SSM_DR7 - (. + 4 - _SmiEntryPoint + 0x8000)\r
182 movq %rcx, %dr6\r
183 movq %rdx, %dr7\r
184L1:\r
185\r
186 movabsq $ASM_PFX(SmiRendezvous), %rax\r
187 movq (%rsp), %rcx\r
188 # Save FP registers\r
189\r
190 subq $0x208, %rsp\r
191 .byte 0x48 # FXSAVE64\r
192 fxsave (%rsp)\r
193\r
194 addq $-0x20, %rsp\r
195 call *%rax\r
196 addq $0x20, %rsp\r
197\r
198 #\r
199 # Restore FP registers\r
200 #\r
201 .byte 0x48 # FXRSTOR64\r
202 fxrstor (%rsp)\r
203\r
204 movabsq $ASM_PFX(FeaturePcdGet (PcdCpuSmmDebug)), %rax\r
205 cmpb $0, (%rax)\r
206 jz L2\r
207\r
208 movq %dr7, %rdx\r
209 movq %dr6, %rcx\r
210 .byte 0x48, 0x89, 0x15 # mov [rip + disp32], rdx\r
211 .long SSM_DR7 - (. + 4 - _SmiEntryPoint + 0x8000)\r
212 .byte 0x48, 0x89, 0x0d # mov [rip + disp32], rcx\r
213 .long SSM_DR6 - (. + 4 - _SmiEntryPoint + 0x8000)\r
214L2:\r
215 rsm\r
216\r
217ASM_PFX(gcSmiHandlerSize): .word . - _SmiEntryPoint\r