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