audk/UefiCpuPkg/Library/CpuExceptionHandlerLib/UnitTest/X64/ArchExceptionHandlerTestAsm...

257 lines
7.3 KiB
NASM

;------------------------------------------------------------------------------
;
; Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
; SPDX-License-Identifier: BSD-2-Clause-Patent
;
; Module Name:
;
; ArchExceptionHandlerTestAsm.nasm
;
; Abstract:
;
; x64 CPU Exception Handler Lib Unit test
;
;------------------------------------------------------------------------------
DEFAULT REL
SECTION .text
struc GENERAL_REGISTER
.Rdi: resq 1
.Rsi: resq 1
.Rbx: resq 1
.Rdx: resq 1
.Rcx: resq 1
.Rax: resq 1
.R8: resq 1
.R9: resq 1
.R10: resq 1
.R11: resq 1
.R12: resq 1
.R13: resq 1
.R14: resq 1
.R15: resq 1
endstruc
extern ASM_PFX(mExpectedContextInHandler)
extern ASM_PFX(mActualContextAfterException)
extern ASM_PFX(mFaultInstructionLength)
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; TriggerGPException (
; UINTN Cr4ReservedBit
; );
;------------------------------------------------------------------------------
global ASM_PFX(TriggerGPException)
ASM_PFX(TriggerGPException):
;
; Set reserved bit 15 of cr4 to 1
;
push rcx
lea rcx, [ASM_PFX(mFaultInstructionLength)]
mov qword[rcx], TriggerGPExceptionAfter - TriggerGPExceptionBefore
pop rcx
TriggerGPExceptionBefore:
mov cr4, rcx
TriggerGPExceptionAfter:
ret
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; TriggerPFException (
; UINTN PFAddress
; );
;------------------------------------------------------------------------------
global ASM_PFX(TriggerPFException)
ASM_PFX(TriggerPFException):
push rcx
lea rcx, [ASM_PFX(mFaultInstructionLength)]
mov qword[rcx], TriggerPFExceptionAfter - TriggerPFExceptionBefore
pop rcx
TriggerPFExceptionBefore:
mov qword[rcx], 0x1
TriggerPFExceptionAfter:
ret
;------------------------------------------------------------------------------
; ModifyRcxInGlobalBeforeException;
; This function is writed by assebly code because it's only called in this file.
; It's used to set Rcx in mExpectedContextInHandler for different exception.
;------------------------------------------------------------------------------
global ASM_PFX(ModifyRcxInGlobalBeforeException)
ASM_PFX(ModifyRcxInGlobalBeforeException):
push rax
lea rax, [ASM_PFX(mExpectedContextInHandler)]
mov [rax + GENERAL_REGISTER.Rcx], rcx
pop rax
ret
;------------------------------------------------------------------------------
;VOID
;EFIAPI
;AsmTestConsistencyOfCpuContext (
; IN EFI_EXCEPTION_TYPE ExceptionType
; IN UINTN FaultParameter OPTIONAL
; );
;------------------------------------------------------------------------------
global ASM_PFX(AsmTestConsistencyOfCpuContext)
ASM_PFX(AsmTestConsistencyOfCpuContext):
;
; Push original register
;
push r15
push r14
push r13
push r12
push r11
push r10
push r9
push r8
push rax
push rcx
push rbx
push rsi
push rdi
push rdx
push rdx
;
; Modify registers to mExpectedContextInHandler. Do not handle Rsp and Rbp.
; CpuExceptionHandlerLib doesn't set Rsp and Rsp register to the value in SystemContext.
;
lea r15, [ASM_PFX(mExpectedContextInHandler)]
mov rdi, [r15 + GENERAL_REGISTER.Rdi]
mov rsi, [r15 + GENERAL_REGISTER.Rsi]
mov rbx, [r15 + GENERAL_REGISTER.Rbx]
mov rdx, [r15 + GENERAL_REGISTER.Rdx]
mov rax, [r15 + GENERAL_REGISTER.Rax]
mov r8, [r15 + GENERAL_REGISTER.R8]
mov r9, [r15 + GENERAL_REGISTER.R9]
mov r10, [r15 + GENERAL_REGISTER.R10]
mov r11, [r15 + GENERAL_REGISTER.R11]
mov r12, [r15 + GENERAL_REGISTER.R12]
mov r13, [r15 + GENERAL_REGISTER.R13]
mov r14, [r15 + GENERAL_REGISTER.R14]
mov r15, [r15 + GENERAL_REGISTER.R15]
cmp rcx, 0xd
jz GPException
cmp rcx, 0xe
jz PFException
jmp INTnException
PFException:
pop rcx ; Pop rdx(PFAddress) to rcx.
call ASM_PFX(ModifyRcxInGlobalBeforeException) ; Set mExpectedContextInHandler.Rcx to PFAddress.
call ASM_PFX(TriggerPFException)
jmp AfterException
GPException:
pop rcx ; Pop rdx(Cr4ReservedBit) to rcx.
call ASM_PFX(ModifyRcxInGlobalBeforeException) ; Set mExpectedContextInHandler.Rcx to Cr4ReservedBit.
call ASM_PFX(TriggerGPException)
jmp AfterException
INTnException:
;
; Modify Rcx in mExpectedContextInHandler.
;
add Rsp, 8 ; Discard the extra Rdx in stack. Rcx is ExceptionType now.
call ASM_PFX(ModifyRcxInGlobalBeforeException) ; Set mExpectedContextInHandler.Rcx to ExceptionType.
call ASM_PFX(TriggerINTnException)
AfterException:
;
; Save registers in mActualContextAfterException
;
push rax
lea rax, [ASM_PFX(mActualContextAfterException)]
mov [rax + GENERAL_REGISTER.Rdi], rdi
mov [rax + GENERAL_REGISTER.Rsi], rsi
mov [rax + GENERAL_REGISTER.Rbx], rbx
mov [rax + GENERAL_REGISTER.Rdx], rdx
mov [rax + GENERAL_REGISTER.Rcx], rcx
pop rcx
mov [rax + GENERAL_REGISTER.Rax], rcx
mov [rax + GENERAL_REGISTER.R8], r8
mov [rax + GENERAL_REGISTER.R9], r9
mov [rax + GENERAL_REGISTER.R10], r10
mov [rax + GENERAL_REGISTER.R11], r11
mov [rax + GENERAL_REGISTER.R12], r12
mov [rax + GENERAL_REGISTER.R13], r13
mov [rax + GENERAL_REGISTER.R14], r14
mov [rax + GENERAL_REGISTER.R15], r15
;
; restore original register
;
pop rdx
pop rdi
pop rsi
pop rbx
pop rcx
pop rax
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
ret
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; TriggerStackOverflow (
; VOID
; );
;------------------------------------------------------------------------------
global ASM_PFX(TriggerStackOverflow)
ASM_PFX(TriggerStackOverflow):
push rcx
lea rcx, [ASM_PFX(mFaultInstructionLength)]
mov qword[rcx], TriggerCpuStackGuardAfter - TriggerCpuStackGuardBefore
pop rcx
TriggerCpuStackGuardBefore:
call TriggerCpuStackGuardBefore
TriggerCpuStackGuardAfter:
ret
;------------------------------------------------------------------------------
; VOID
; EFIAPI
; TriggerINTnException (
; IN EFI_EXCEPTION_TYPE ExceptionType
; );
;------------------------------------------------------------------------------
global ASM_PFX(TriggerINTnException)
ASM_PFX(TriggerINTnException):
push rax
push rdx
push rcx
lea rax, [AsmTriggerException1 - AsmTriggerException0]
mul rcx
mov rcx, AsmTriggerException0
add rax, rcx
pop rcx
pop rdx
jmp rax
;
; rax = AsmTriggerException0 + (AsmTriggerException1 - AsmTriggerException0) * rcx
;
%assign Vector 0
%rep 22
AsmTriggerException %+ Vector:
pop rax
INT Vector
ret
%assign Vector Vector+1
%endrep