diff options
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c')
-rw-r--r-- | src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c b/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c new file mode 100644 index 00000000..eaf57521 --- /dev/null +++ b/src/VBox/Devices/EFI/Firmware/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/X64/ArchDebugSupport.c @@ -0,0 +1,114 @@ +/** @file + Supporting functions for X64 architecture. + + Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR> + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "DebugAgent.h" + +/** + Initialize IDT entries to support source level debug. + +**/ +VOID +InitializeDebugIdt ( + VOID + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + UINTN InterruptHandler; + IA32_DESCRIPTOR IdtDescriptor; + UINTN Index; + UINT16 CodeSegment; + UINT32 RegEdx; + + AsmReadIdtr (&IdtDescriptor); + + // + // Use current CS as the segment selector of interrupt gate in IDT + // + CodeSegment = AsmReadCs (); + + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; + + for (Index = 0; Index < 20; Index ++) { + if (((PcdGet32 (PcdExceptionsIgnoredByDebugger) & ~(BIT1 | BIT3)) & (1 << Index)) != 0) { + // + // If the exception is masked to be reserved except for INT1 and INT3, skip it + // + continue; + } + InterruptHandler = (UINTN)&Exception0Handle + Index * ExceptionStubHeaderSize; + IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry[Index].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); + IdtEntry[Index].Bits.Selector = CodeSegment; + IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; + } + + InterruptHandler = (UINTN) &TimerInterruptHandle; + IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler; + IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16); + IdtEntry[DEBUG_TIMER_VECTOR].Bits.OffsetUpper = (UINT32)((UINTN)InterruptHandler >> 32); + IdtEntry[DEBUG_TIMER_VECTOR].Bits.Selector = CodeSegment; + IdtEntry[DEBUG_TIMER_VECTOR].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32; + + // + // If the CPU supports Debug Extensions(CPUID:01 EDX:BIT2), then + // Set DE flag in CR4 to enable IO breakpoint + // + AsmCpuid (1, NULL, NULL, NULL, &RegEdx); + if ((RegEdx & BIT2) != 0) { + AsmWriteCr4 (AsmReadCr4 () | BIT3); + } +} + +/** + Retrieve exception handler from IDT table by ExceptionNum. + + @param[in] ExceptionNum Exception number + + @return Exception handler + +**/ +VOID * +GetExceptionHandlerInIdtEntry ( + IN UINTN ExceptionNum + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + IA32_DESCRIPTOR IdtDescriptor; + + AsmReadIdtr (&IdtDescriptor); + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; + + return (VOID *) (IdtEntry[ExceptionNum].Bits.OffsetLow | + (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetHigh) << 16) | + (((UINTN)IdtEntry[ExceptionNum].Bits.OffsetUpper) << 32)); +} + +/** + Set exception handler in IDT table by ExceptionNum. + + @param[in] ExceptionNum Exception number + @param[in] ExceptionHandler Exception Handler to be set + +**/ +VOID +SetExceptionHandlerInIdtEntry ( + IN UINTN ExceptionNum, + IN VOID *ExceptionHandler + ) +{ + IA32_IDT_GATE_DESCRIPTOR *IdtEntry; + IA32_DESCRIPTOR IdtDescriptor; + + AsmReadIdtr (&IdtDescriptor); + IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base; + + IdtEntry[ExceptionNum].Bits.OffsetLow = (UINT16)(UINTN)ExceptionHandler; + IdtEntry[ExceptionNum].Bits.OffsetHigh = (UINT16)((UINTN)ExceptionHandler >> 16); + IdtEntry[ExceptionNum].Bits.OffsetUpper = (UINT32)((UINTN)ExceptionHandler >> 32); +} |