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.
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.
17 ; Code template of the SMI handler for a particular processor
19 ;-------------------------------------------------------------------------------
22 ; Variables referrenced by C code
26 ; Constants relating to PROCESSOR_SMM_DESCRIPTOR
28 %define DSC_OFFSET 0xfb00
29 %define DSC_GDTPTR 0x30
30 %define DSC_GDTSIZ 0x38
34 %define DSC_OTHERSEG 20
36 ; Constants relating to CPU State Save Area
38 %define SSM_DR6 0xffd0
39 %define SSM_DR7 0xffc8
41 %define PROTECT_MODE_CS 0x8
42 %define PROTECT_MODE_DS 0x20
43 %define LONG_MODE_CS 0x38
44 %define TSS_SEGMENT 0x40
47 extern ASM_PFX(SmiRendezvous)
48 extern ASM_PFX(gSmiHandlerIdtr)
49 extern ASM_PFX(CpuSmmDebugEntry)
50 extern ASM_PFX(CpuSmmDebugExit)
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)
62 ASM_PFX(gcSmiHandlerTemplate):
64 mov bx, _GdtDesc - _SmiEntryPoint + 0x8000
65 mov ax,[cs:DSC_OFFSET + DSC_GDTSIZ]
68 mov eax, [cs:DSC_OFFSET + DSC_GDTPTR]
70 o32 lgdt [cs:bx] ; lgdt fword ptr cs:[bx]
71 mov ax, PROTECT_MODE_CS
73 DB 0x66, 0xbf ; mov edi, SMBASE
74 ASM_PFX(gSmbase): DD 0
75 lea eax, [edi + (@ProtectedMode - _SmiEntryPoint) + 0x8000]
88 mov ax, PROTECT_MODE_DS
94 DB 0xbc ; mov esp, imm32
95 ASM_PFX(gSmiStack): DD 0
100 DB 0xb8 ; mov eax, offset gSmiCr3
101 ASM_PFX(gSmiCr3): DD 0
103 mov eax, 0x668 ; as cr4.PGE is not set here, refresh cr3
104 mov cr4, rax ; in PreModifyMtrrs() to flush TLB.
106 sub esp, 8 ; reserve room in stack
108 mov eax, [rsp + 2] ; eax = GDT base
111 mov [rax + TSS_SEGMENT + 5], dl ; clear busy flag
115 ; Switch into @LongMode
116 push LONG_MODE_CS ; push cs hardcore here
117 call Base ; push reture address for retf later
119 add dword [rsp], @LongMode - Base; offset for far retf, seg is the 1st arg
125 or ebx, 080010000h ; enable paging + WP
128 @LongMode: ; long mode (64-bit code) starts here
129 mov rax, ASM_PFX(gSmiHandlerIdtr)
131 lea ebx, [rdi + DSC_OFFSET]
132 mov ax, [rbx + DSC_DS]
134 mov ax, [rbx + DSC_OTHERSEG]
138 mov ax, [rbx + DSC_SS]
140 ; jmp _SmiHandler ; instruction is not needed
143 mov rbx, [rsp] ; rbx <- CpuIndex
155 mov rax, CpuSmmDebugEntry
159 mov rax, SmiRendezvous ; rax <- absolute addr of SmiRedezvous
163 mov rax, CpuSmmDebugExit
169 ; Restore FP registers
176 gcSmiHandlerSize DW $ - _SmiEntryPoint