summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c140
1 files changed, 140 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c
new file mode 100644
index 00000000..375bdec9
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c
@@ -0,0 +1,140 @@
+/** @file
+ X64 specific functions to support Debug Support protocol.
+
+Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "PlDebugSupport.h"
+
+IA32_IDT_GATE_DESCRIPTOR NullDesc = {{0,0}};
+
+/**
+ Get Interrupt Handle from IDT Gate Descriptor.
+
+ @param IdtGateDecriptor IDT Gate Descriptor.
+
+ @return Interrupt Handle stored in IDT Gate Descriptor.
+
+**/
+UINTN
+GetInterruptHandleFromIdt (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
+ )
+{
+ UINTN InterruptHandle;
+
+ //
+ // InterruptHandle 0-15 : OffsetLow
+ // InterruptHandle 16-31 : OffsetHigh
+ // InterruptHandle 32-63 : OffsetUpper
+ //
+ InterruptHandle = ((UINTN) IdtGateDecriptor->Bits.OffsetLow) |
+ (((UINTN) IdtGateDecriptor->Bits.OffsetHigh) << 16) |
+ (((UINTN) IdtGateDecriptor->Bits.OffsetUpper) << 32) ;
+
+ return InterruptHandle;
+}
+
+/**
+ Allocate pool for a new IDT entry stub.
+
+ Copy the generic stub into the new buffer and fixup the vector number
+ and jump target address.
+
+ @param ExceptionType This is the exception type that the new stub will be created
+ for.
+ @param Stub On successful exit, *Stub contains the newly allocated entry stub.
+
+**/
+VOID
+CreateEntryStub (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ OUT VOID **Stub
+ )
+{
+ UINT8 *StubCopy;
+
+ StubCopy = *Stub;
+
+ //
+ // Fixup the stub code for this vector
+ //
+
+ // The stub code looks like this:
+ //
+ // 00000000 6A 00 push 0 ; push vector number - will be modified before installed
+ // 00000002 E9 db 0e9h ; jump rel32
+ // 00000003 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry
+ //
+
+ //
+ // poke in the exception type so the second push pushes the exception type
+ //
+ StubCopy[0x1] = (UINT8) ExceptionType;
+
+ //
+ // fixup the jump target to point to the common entry
+ //
+ *(UINT32 *) &StubCopy[0x3] = (UINT32)((UINTN) CommonIdtEntry - (UINTN) &StubCopy[StubSize]);
+
+ return;
+}
+
+/**
+ This is the main worker function that manages the state of the interrupt
+ handlers. It both installs and uninstalls interrupt handlers based on the
+ value of NewCallback. If NewCallback is NULL, then uninstall is indicated.
+ If NewCallback is non-NULL, then install is indicated.
+
+ @param NewCallback If non-NULL, NewCallback specifies the new handler to register.
+ If NULL, specifies that the previously registered handler should
+ be uninstalled.
+ @param ExceptionType Indicates which entry to manage.
+
+ @retval EFI_SUCCESS Process is ok.
+ @retval EFI_INVALID_PARAMETER Requested uninstalling a handler from a vector that has
+ no handler registered for it
+ @retval EFI_ALREADY_STARTED Requested install to a vector that already has a handler registered.
+ @retval others Possible return values are passed through from UnHookEntry and HookEntry.
+
+**/
+EFI_STATUS
+ManageIdtEntryTable (
+ CALLBACK_FUNC NewCallback,
+ EFI_EXCEPTION_TYPE ExceptionType
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ if (CompareMem (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc, sizeof (IA32_IDT_GATE_DESCRIPTOR)) != 0) {
+ //
+ // we've already installed to this vector
+ //
+ if (NewCallback != NULL) {
+ //
+ // if the input handler is non-null, error
+ //
+ Status = EFI_ALREADY_STARTED;
+ } else {
+ UnhookEntry (ExceptionType);
+ }
+ } else {
+ //
+ // no user handler installed on this vector
+ //
+ if (NewCallback == NULL) {
+ //
+ // if the input handler is null, error
+ //
+ Status = EFI_INVALID_PARAMETER;
+ } else {
+ HookEntry (ExceptionType, NewCallback);
+ }
+ }
+
+ return Status;
+}