;------------------------------------------------------------------------------ ; ; Copyright (c) 2022, Intel Corporation. All rights reserved.
; 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