audk/UefiCpuPkg/Library/SmmCpuFeaturesLib/X64/SmiException.S

179 lines
5.3 KiB
ArmAsm

#------------------------------------------------------------------------------
#
# Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
# Module Name:
#
# SmiException.S
#
# Abstract:
#
# Exception handlers used in SM mode
#
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(gcStmPsd)
ASM_GLOBAL ASM_PFX(SmmStmExceptionHandler)
ASM_GLOBAL ASM_PFX(SmmStmSetup)
ASM_GLOBAL ASM_PFX(SmmStmTeardown)
.equ CODE_SEL, 0x38
.equ DATA_SEL, 0x20
.equ TR_SEL, 0x40
.equ MSR_IA32_MISC_ENABLE, 0x1A0
.equ MSR_EFER, 0x0c0000080
.equ MSR_EFER_XD, 0x0800
.data
#
# This structure serves as a template for all processors.
#
ASM_PFX(gcStmPsd):
.ascii "TXTPSSIG"
.word PSD_SIZE
.word 1 # Version
.long 0 # LocalApicId
.byte 0xF # Cr4Pse;Cr4Pae;Intel64Mode;ExecutionDisableOutsideSmrr
.byte 0 # BIOS to STM
.byte 0 # STM to BIOS
.byte 0
.word CODE_SEL
.word DATA_SEL
.word DATA_SEL
.word DATA_SEL
.word TR_SEL
.word 0
.quad 0 # SmmCr3
.quad ASM_PFX(_OnStmSetup)
.quad ASM_PFX(_OnStmTeardown)
.quad 0 # SmmSmiHandlerRip - SMM guest entrypoint
.quad 0 # SmmSmiHandlerRsp
.quad 0
.long 0
.long 0x80010100 # RequiredStmSmmRevId
.quad ASM_PFX(_OnException)
.quad 0 # ExceptionStack
.word DATA_SEL
.word 0x1F # ExceptionFilter
.long 0
.quad 0
.quad 0 # BiosHwResourceRequirementsPtr
.quad 0 # AcpiRsdp
.byte 0 # PhysicalAddressBits
.equ PSD_SIZE, . - ASM_PFX(gcStmPsd)
.text
#------------------------------------------------------------------------------
# SMM Exception handlers
#------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(_OnException)
ASM_PFX(_OnException):
movq %rsp, %rcx
subq $0x28, %rsp
call ASM_PFX(SmmStmExceptionHandler)
addq $0x28, %rsp
movl %eax, %ebx
movl $4, %eax
.byte 0xf, 0x1, 0xc1 # VMCALL
jmp .
ASM_GLOBAL ASM_PFX(_OnStmSetup)
ASM_PFX(_OnStmSetup):
#
# Check XD disable bit
#
xorq %r8, %r8
movabsq $ASM_PFX(gStmXdSupported), %rax
movb (%rax), %al
cmpb $0, %al
jz StmXdDone1
movl $MSR_IA32_MISC_ENABLE, %ecx
rdmsr
movq %rdx, %r8 # save MSR_IA32_MISC_ENABLE[63-32]
testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34]
jz L13
andw $0x0FFFB, %dx # clear XD Disable bit if it is set
wrmsr
L13:
movl $MSR_EFER, %ecx
rdmsr
orw $MSR_EFER_XD,%ax # enable NXE
wrmsr
StmXdDone1:
pushq %r8
subq $0x20, %rsp
call ASM_PFX(SmmStmSetup)
addq 0x20, %rsp
movabsq $ASM_PFX(gStmXdSupported), %rax
movb (%rax), %al
cmpb $0, %al
jz L14
popq %rdx # get saved MSR_IA32_MISC_ENABLE[63-32]
testl $BIT2, %edx
jz L14
movl $MSR_IA32_MISC_ENABLE, %ecx
rdmsr
orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM
wrmsr
L14:
rsm
ASM_GLOBAL ASM_PFX(_OnStmTeardown)
ASM_PFX(_OnStmTeardown):
#
# Check XD disable bit
#
xorq %r8, %r8
movabsq $ASM_PFX(gStmXdSupported), %rax
movb (%rax), %al
cmpb $0, %al
jz StmXdDone2
movl $MSR_IA32_MISC_ENABLE, %ecx
rdmsr
movq %rdx, %r8 # save MSR_IA32_MISC_ENABLE[63-32]
testl $BIT2, %edx # MSR_IA32_MISC_ENABLE[34]
jz L15
andw $0x0FFFB, %dx # clear XD Disable bit if it is set
wrmsr
L15:
movl $MSR_EFER, %ecx
rdmsr
orw $MSR_EFER_XD,%ax # enable NXE
wrmsr
StmXdDone2:
pushq %r8
subq $0x20, %rsp
call ASM_PFX(SmmStmTeardown)
addq $0x20, %rsp
movabsq $ASM_PFX(gStmXdSupported), %rax
movb (%rax), %al
cmpb $0, %al
jz L16
popq %rdx # get saved MSR_IA32_MISC_ENABLE[63-32]
testl $BIT2, %edx
jz L16
movl $MSR_IA32_MISC_ENABLE, %ecx
rdmsr
orw $BIT2, %dx # set XD Disable bit if it was set before entering into SMM
wrmsr
L16:
rsm