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