]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmiEntry.nasm
b717cda2c93ecf23286aa58c369faf80b71ff599
[mirror_edk2.git] / UefiCpuPkg / PiSmmCpuDxeSmm / X64 / SmiEntry.nasm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
7 ;
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 ;
11 ; Module Name:
12 ;
13 ; SmiEntry.nasm
14 ;
15 ; Abstract:
16 ;
17 ; Code template of the SMI handler for a particular processor
18 ;
19 ;-------------------------------------------------------------------------------
20
21 ;
22 ; Variables referrenced by C code
23 ;
24
25 ;
26 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
27 ;
28 %define DSC_OFFSET 0xfb00
29 %define DSC_GDTPTR 0x30
30 %define DSC_GDTSIZ 0x38
31 %define DSC_CS 14
32 %define DSC_DS 16
33 %define DSC_SS 18
34 %define DSC_OTHERSEG 20
35 ;
36 ; Constants relating to CPU State Save Area
37 ;
38 %define SSM_DR6 0xffd0
39 %define SSM_DR7 0xffc8
40
41 %define PROTECT_MODE_CS 0x8
42 %define PROTECT_MODE_DS 0x20
43 %define LONG_MODE_CS 0x38
44 %define TSS_SEGMENT 0x40
45 %define GDT_SIZE 0x50
46
47 extern ASM_PFX(SmiRendezvous)
48 extern ASM_PFX(gSmiHandlerIdtr)
49 extern ASM_PFX(CpuSmmDebugEntry)
50 extern ASM_PFX(CpuSmmDebugExit)
51
52 global ASM_PFX(gSmbase)
53 global ASM_PFX(gSmiStack)
54 global ASM_PFX(gSmiCr3)
55 global ASM_PFX(gcSmiHandlerTemplate)
56 global ASM_PFX(gcSmiHandlerSize)
57
58 DEFAULT REL
59 SECTION .text
60
61 BITS 16
62 ASM_PFX(gcSmiHandlerTemplate):
63 _SmiEntryPoint:
64 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
65 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
66 dec ax
67 mov [cs:bx], ax
68 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
69 mov [cs:bx + 2], eax
70 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
71 mov ax, PROTECT_MODE_CS
72 mov [cs:bx-0x2],ax
73 DB 0x66, 0xbf ; mov edi, SMBASE
74 ASM_PFX(gSmbase): DD 0
75 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]
76 mov [cs:bx-0x6],eax
77 mov ebx, cr0
78 and ebx, 0x9ffafff3
79 or ebx, 0x23
80 mov cr0, ebx
81 jmp dword 0x0:0x0
82 _GdtDesc:
83 DW 0
84 DD 0
85
86 BITS 32
87 @ProtectedMode:
88 mov ax, PROTECT_MODE_DS
89 o16 mov ds, ax
90 o16 mov es, ax
91 o16 mov fs, ax
92 o16 mov gs, ax
93 o16 mov ss, ax
94 DB 0xbc ; mov esp, imm32
95 ASM_PFX(gSmiStack): DD 0
96 jmp ProtFlatMode
97
98 BITS 64
99 ProtFlatMode:
100 DB 0xb8 ; mov eax, offset gSmiCr3
101 ASM_PFX(gSmiCr3): DD 0
102 mov cr3, rax
103 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
104 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
105 ; Load TSS
106 sub esp, 8 ; reserve room in stack
107 sgdt [rsp]
108 mov eax, [rsp + 2] ; eax = GDT base
109 add esp, 8
110 mov dl, 0x89
111 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
112 mov eax, TSS_SEGMENT
113 ltr ax
114
115 ; Switch into @LongMode
116 push LONG_MODE_CS ; push cs hardcore here
117 call Base ; push reture address for retf later
118 Base:
119 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
120 mov ecx, 0xc0000080
121 rdmsr
122 or ah, 1
123 wrmsr
124 mov rbx, cr0
125 or ebx, 080010000h ; enable paging + WP
126 mov cr0, rbx
127 retf
128 @LongMode: ; long mode (64-bit code) starts here
129 mov rax, ASM_PFX(gSmiHandlerIdtr)
130 lidt [rax]
131 lea ebx, [rdi + DSC_OFFSET]
132 mov ax, [rbx + DSC_DS]
133 mov ds, eax
134 mov ax, [rbx + DSC_OTHERSEG]
135 mov es, eax
136 mov fs, eax
137 mov gs, eax
138 mov ax, [rbx + DSC_SS]
139 mov ss, eax
140 ; jmp _SmiHandler ; instruction is not needed
141
142 _SmiHandler:
143 mov rbx, [rsp] ; rbx <- CpuIndex
144
145 ;
146 ; Save FP registers
147 ;
148 sub rsp, 0x208
149 DB 0x48 ; FXSAVE64
150 fxsave [rsp]
151
152 add rsp, -0x20
153
154 mov rcx, rbx
155 mov rax, CpuSmmDebugEntry
156 call rax
157
158 mov rcx, rbx
159 mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
160 call rax
161
162 mov rcx, rbx
163 mov rax, CpuSmmDebugExit
164 call rax
165
166 add rsp, 0x20
167
168 ;
169 ; Restore FP registers
170 ;
171 DB 0x48 ; FXRSTOR64
172 fxrstor [rsp]
173
174 rsm
175
176 gcSmiHandlerSize DW $ - _SmiEntryPoint
177