;------------------------------------------------------------------------------ ; ; Copyright (c) 2022, Intel Corporation. All rights reserved.
; SPDX-License-Identifier: BSD-2-Clause-Patent ; ; Module Name: ; ; ArchExceptionHandlerTestAsm.nasm ; ; Abstract: ; ; ia32 CPU Exception Handler Lib Unit test ; ;------------------------------------------------------------------------------ SECTION .text struc GENERAL_REGISTER_IA32 .Edi: resd 1 .Esi: resd 1 .Ebx: resd 1 .Edx: resd 1 .Ecx: resd 1 .Eax: resd 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 ; lea ecx, [ASM_PFX(mFaultInstructionLength)] mov dword[ecx], TriggerGPExceptionAfter - TriggerGPExceptionBefore mov ecx, dword [esp + 0x4] TriggerGPExceptionBefore: mov cr4, ecx TriggerGPExceptionAfter: ret ;------------------------------------------------------------------------------ ; VOID ; EFIAPI ; TriggerPFException ( ; UINTN PfAddress ; ); ;------------------------------------------------------------------------------ global ASM_PFX(TriggerPFException) ASM_PFX(TriggerPFException): lea ecx, [ASM_PFX(mFaultInstructionLength)] mov dword[ecx], TriggerPFExceptionAfter - TriggerPFExceptionBefore mov ecx, dword [esp + 0x4] TriggerPFExceptionBefore: mov dword[ecx], 0x1 TriggerPFExceptionAfter: ret ;------------------------------------------------------------------------------ ; ModifyEcxInGlobalBeforeException; ; This function is writed by assebly code because it's only called in this file. ; It's used to set Ecx in mExpectedContextInHandler for different exception. ;------------------------------------------------------------------------------ global ASM_PFX(ModifyEcxInGlobalBeforeException) ASM_PFX(ModifyEcxInGlobalBeforeException): push eax lea eax, [ASM_PFX(mExpectedContextInHandler)] mov [eax + GENERAL_REGISTER_IA32.Ecx], ecx pop eax ret ;------------------------------------------------------------------------------ ;VOID ;EFIAPI ;AsmTestConsistencyOfCpuContext ( ; IN EFI_EXCEPTION_TYPE ExceptionType ; IN UINTN FaultParameter OPTIONAL ; ); ;------------------------------------------------------------------------------ global ASM_PFX(AsmTestConsistencyOfCpuContext) ASM_PFX(AsmTestConsistencyOfCpuContext): ; ; push 7 general register plus 4 bytes ; pushad ; ; Modify register to mExpectedContextInHandler. Do not handle Esp and Ebp. ; CpuExceptionHandlerLib doesn't set Esp and Esp register to the value in SystemContext. ; lea eax, [ASM_PFX(mExpectedContextInHandler)] mov edi, [eax + GENERAL_REGISTER_IA32.Edi] mov esi, [eax + GENERAL_REGISTER_IA32.Esi] mov ebx, [eax + GENERAL_REGISTER_IA32.Ebx] mov edx, [eax + GENERAL_REGISTER_IA32.Edx] ; ; Set ecx to ExceptionType ; mov ecx, dword [esp + 0x24] mov eax, [eax + GENERAL_REGISTER_IA32.Eax] cmp ecx, 0xd jz GPException cmp ecx, 0xe jz PFException jmp INTnException PFException: mov ecx, dword [esp + 0x28] ; Set ecx to PFAddress. call ASM_PFX(ModifyEcxInGlobalBeforeException) ; Set mExpectedContextInHandler.Ecx to PFAddress. push ecx ; Push PfAddress into stack. call ASM_PFX(TriggerPFException) jmp AfterException GPException: mov ecx, dword [esp + 0x28] ; Set ecx to CR4_RESERVED_BIT. call ASM_PFX(ModifyEcxInGlobalBeforeException) ; Set mExpectedContextInHandler.Ecx to CR4_RESERVED_BIT. push ecx ; Push CR4_RESERVED_BIT into stack. call ASM_PFX(TriggerGPException) jmp AfterException INTnException: call ASM_PFX(ModifyEcxInGlobalBeforeException) ; Set mExpectedContextInHandler.Ecx to ExceptionType. push ecx ; Push ExceptionType into stack. call ASM_PFX(TriggerINTnException) AfterException: ; ; Save register in mActualContextAfterException. ; push eax lea eax, [ASM_PFX(mActualContextAfterException)] mov [eax + GENERAL_REGISTER_IA32.Edi], edi mov [eax + GENERAL_REGISTER_IA32.Esi], esi mov [eax + GENERAL_REGISTER_IA32.Ebx], ebx mov [eax + GENERAL_REGISTER_IA32.Edx], edx mov [eax + GENERAL_REGISTER_IA32.Ecx], ecx pop ecx mov [eax + GENERAL_REGISTER_IA32.Eax], ecx add esp, 4 ; ; restore original register ; popad ret ;------------------------------------------------------------------------------ ; VOID ; EFIAPI ; TriggerStackOverflow ( ; VOID ; ); ;------------------------------------------------------------------------------ global ASM_PFX(TriggerStackOverflow) ASM_PFX(TriggerStackOverflow): lea ecx, [ASM_PFX(mFaultInstructionLength)] mov dword[ecx], TriggerCpuStackGuardAfter - TriggerCpuStackGuardBefore TriggerCpuStackGuardBefore: ; ; Clear CR0.TS since it is set after return from a nested DF ; call TriggerCpuStackGuardBefore clts TriggerCpuStackGuardAfter: ret ;------------------------------------------------------------------------------ ; VOID ; EFIAPI ; TriggerINTnException ( ; IN EFI_EXCEPTION_TYPE ExceptionType ; ); ;------------------------------------------------------------------------------ global ASM_PFX(TriggerINTnException) ASM_PFX(TriggerINTnException): push eax push edx lea eax, [AsmTriggerException1 - AsmTriggerException0] mov ecx, dword [esp + 0xc] push ecx mul ecx mov ecx, AsmTriggerException0 add eax, ecx pop ecx pop edx jmp eax ; ; eax = AsmTriggerException0 + (AsmTriggerException1 - AsmTriggerException0) * ecx ; %assign Vector 0 %rep 22 AsmTriggerException %+ Vector: pop eax INT Vector ret %assign Vector Vector+1 %endrep