summaryrefslogtreecommitdiffstats
path: root/MdeModulePkg/Universal/DebugSupportDxe
diff options
context:
space:
mode:
authorvanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2008-12-11 05:28:12 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2008-12-11 05:28:12 +0000
commit6e8a984eca4c9763038e887b8d813b2110bbaed6 (patch)
treeb418c1c4d5e8981e00c5b27717039758680e6935 /MdeModulePkg/Universal/DebugSupportDxe
parent4ef55dfc766c2206378ab7e5a3101a2a7a32d569 (diff)
downloadedk2-6e8a984eca4c9763038e887b8d813b2110bbaed6.tar.gz
edk2-6e8a984eca4c9763038e887b8d813b2110bbaed6.tar.bz2
edk2-6e8a984eca4c9763038e887b8d813b2110bbaed6.zip
1. Merger generic functions into one file.
2. Use the basic definitions in BaseLib.h, instead of local definitions git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@6986 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Universal/DebugSupportDxe')
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf6
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm15
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h308
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c135
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h215
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c143
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h2
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm34
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c385
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h220
-rw-r--r--MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c143
11 files changed, 637 insertions, 969 deletions
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf
index c36ee518b0..d303847c75 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf
+++ b/MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf
@@ -32,14 +32,18 @@
DebugSupport.c
[Sources.Ia32]
+ Ia32/DebugSupport.h
Ia32/PlDebugSupport.c
Ia32/PlDebugSupport.h
+ Ia32/PlDebugSupportIa32.c
Ia32/AsmFuncs.S
Ia32/AsmFuncs.asm
[Sources.X64]
- X64/PlDebugSupport.c
+ Ia32/DebugSupport.h
+ Ia32/PlDebugSupport.c
X64/PlDebugSupport.h
+ X64/PlDebugSupportX64.c
X64/AsmFuncs.S
X64/AsmFuncs.asm
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm
index 315120ef94..cc776c867e 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm
+++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/AsmFuncs.asm
@@ -132,21 +132,6 @@ FxStorSupport PROC C PUBLIC
FxStorSupport ENDP
-;------------------------------------------------------------------------------
-; DESCRIPTOR *
-; GetIdtr (
-; void
-; )
-;
-; Abstract: Returns physical address of IDTR
-;
-GetIdtr PROC C PUBLIC
- LOCAL IdtrBuf:FWORD
-
- sidt IdtrBuf
- mov eax, DWORD PTR IdtrBuf + 2
- ret
-GetIdtr ENDP
;------------------------------------------------------------------------------
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h
new file mode 100644
index 0000000000..72765507d5
--- /dev/null
+++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/DebugSupport.h
@@ -0,0 +1,308 @@
+/** @file
+ Generic debug support macros, typedefs and prototypes for IA32/x64.
+
+Copyright (c) 2006 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _DEBUG_SUPPORT_H_
+#define _DEBUG_SUPPORT_H_
+
+
+#include <Uefi.h>
+
+#include <Protocol/DebugSupport.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Library/DebugLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseLib.h>
+#include <Library/PcdLib.h>
+
+#define NUM_IDT_ENTRIES 0x78
+#define SYSTEM_TIMER_VECTOR 0x68
+#define VECTOR_ENTRY_PAGES 1
+
+#define FF_FXSR (1 << 24)
+
+typedef
+VOID
+(*DEBUG_PROC) (
+ VOID
+ );
+
+typedef struct {
+ IA32_IDT_GATE_DESCRIPTOR OrigDesc;
+ DEBUG_PROC OrigVector;
+ IA32_IDT_GATE_DESCRIPTOR NewDesc;
+ DEBUG_PROC StubEntry;
+ VOID (*RegisteredCallback) ();
+} IDT_ENTRY;
+
+extern EFI_SYSTEM_CONTEXT SystemContext;
+extern UINT8 InterruptEntryStub[];
+extern UINT32 StubSize;
+extern VOID (*OrigVector) (VOID);
+extern IDT_ENTRY *IdtEntryTable;
+extern IA32_IDT_GATE_DESCRIPTOR NullDesc;
+
+/**
+ Generic IDT entry.
+
+**/
+VOID
+CommonIdtEntry (
+ VOID
+ );
+
+/**
+ Check whether FXSTOR is supported
+
+ @retval TRUE FXSTOR is supported.
+ @retval FALSE FXSTOR is not supported.
+
+**/
+BOOLEAN
+FxStorSupport (
+ VOID
+ );
+
+/**
+ Encodes an IDT descriptor with the given physical address.
+
+ @param DestDesc The IDT descriptor address.
+ @param Vecotr The interrupt vector entry.
+
+**/
+VOID
+Vect2Desc (
+ IA32_IDT_GATE_DESCRIPTOR * DestDesc,
+ VOID (*Vector) (VOID)
+ );
+
+/**
+ Programs interrupt flag to the requested state and returns previous
+ state.
+
+ @param NewState New interrupt status.
+
+ @retval TRUE Old interrupt status is TRUE.
+ @retval FALSE Old interrupt status is FALSE
+
+**/
+BOOLEAN
+WriteInterruptFlag (
+ BOOLEAN NewState
+ );
+
+/**
+ Initializes driver's handler registration databas.
+
+ This code executes in boot services context
+ Must be public because it's referenced from DebugSupport.c
+
+ @retval EFI_UNSUPPORTED If IA32 processor does not support FXSTOR/FXRSTOR instructions,
+ the context save will fail, so these processor's are not supported.
+ @retval EFI_OUT_OF_RESOURCES Fails to allocate memory.
+ @retval EFI_SUCCESS Initializes successfully.
+
+**/
+EFI_STATUS
+PlInitializeDebugSupportDriver (
+ VOID
+ );
+
+/**
+ This is the callback that is written to the LoadedImage protocol instance
+ on the image handle. It uninstalls all registered handlers and frees all entry
+ stub memory.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+
+ @retval EFI_SUCCESS Always.
+
+**/
+EFI_STATUS
+EFIAPI
+PlUnloadDebugSupportDriver (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ This is a DebugSupport protocol member function, hard
+ coded to support only 1 processor for now.
+
+ @param This The DebugSupport instance
+ @param MaxProcessorIndex The maximuim supported processor index
+
+ @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0.
+
+**/
+EFI_STATUS
+EFIAPI
+GetMaximumProcessorIndex (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ OUT UINTN *MaxProcessorIndex
+ );
+
+/**
+ DebugSupport protocol member function.
+
+ @param This The DebugSupport instance
+ @param ProcessorIndex Which processor the callback applies to.
+ @param PeriodicCallback Callback function
+
+ @retval EFI_SUCCESS Indicates the callback was registered.
+ @retval others Callback was not registered.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterPeriodicCallback (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ IN EFI_PERIODIC_CALLBACK PeriodicCallback
+ );
+
+/**
+ DebugSupport protocol member function.
+
+ This code executes in boot services context.
+
+ @param This The DebugSupport instance
+ @param ProcessorIndex Which processor the callback applies to.
+ @param NewCallback Callback function
+ @param ExceptionType Which exception to hook
+
+ @retval EFI_SUCCESS Indicates the callback was registered.
+ @retval others Callback was not registered.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterExceptionCallback (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ IN EFI_EXCEPTION_CALLBACK NewCallback,
+ IN EFI_EXCEPTION_TYPE ExceptionType
+ );
+
+/**
+ DebugSupport protocol member function. Calls assembly routine to flush cache.
+
+ @param This The DebugSupport instance
+ @param ProcessorIndex Which processor the callback applies to.
+ @param Start Physical base of the memory range to be invalidated
+ @param Length mininum number of bytes in instruction cache to invalidate
+
+ @retval EFI_SUCCESS Always returned.
+
+**/
+EFI_STATUS
+EFIAPI
+InvalidateInstructionCache (
+ IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
+ IN UINTN ProcessorIndex,
+ IN VOID *Start,
+ IN UINT64 Length
+ );
+
+/**
+ 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.
+
+ @retval EFI_SUCCESS Always.
+
+**/
+EFI_STATUS
+CreateEntryStub (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ OUT VOID **Stub
+ );
+
+/**
+ Get Procedure Entry Point from IDT Gate Descriptor.
+
+ @param IdtGateDecriptor IDT Gate Descriptor.
+
+ @return Procedure Entry Point located in IDT Gate Descriptor.
+
+**/
+UINTN GetProcedureEntryPoint (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
+ );
+
+/**
+ 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 (
+ VOID (*NewCallback)(),
+ EFI_EXCEPTION_TYPE ExceptionType
+ );
+
+/**
+ Creates a nes entry stub. Then saves the current IDT entry and replaces it
+ with an interrupt gate for the new entry point. The IdtEntryTable is updated
+ with the new registered function.
+
+ This code executes in boot services context. The stub entry executes in interrupt
+ context.
+
+ @param ExceptionType Specifies which vector to hook.
+ @param NewCallback A pointer to the new function to be registered.
+
+ @retval EFI_SUCCESS Always.
+
+**/
+EFI_STATUS
+HookEntry (
+ IN EFI_EXCEPTION_TYPE ExceptionType,
+ IN VOID (*NewCallback) ()
+ );
+
+/**
+ Undoes HookEntry. This code executes in boot services context.
+
+ @param ExceptionType Specifies which entry to unhook
+
+ @retval EFI_SUCCESS Always.
+
+**/
+EFI_STATUS
+UnhookEntry (
+ IN EFI_EXCEPTION_TYPE ExceptionType
+ );
+
+#endif
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c
index c650e6391f..932e923eaa 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c
+++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.c
@@ -15,63 +15,56 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
//
// private header files
//
-#include "PlDebugSupport.h"
+#include "DebugSupport.h"
//
// This the global main table to keep track of the interrupts
//
IDT_ENTRY *IdtEntryTable = NULL;
-DESCRIPTOR NullDesc = 0;
+IA32_IDT_GATE_DESCRIPTOR NullDesc = {0};
/**
- Allocate pool for a new IDT entry stub.
+ Read IDT Gate Descriptor from IDT Table.
- 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.
-
- @retval EFI_SUCCESS Always.
+ @param Vector Specifies vector number.
+ @param IdtGateDecriptor Pointer to IDT Gate Descriptor read from IDT Table.
**/
-EFI_STATUS
-CreateEntryStub (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- OUT VOID **Stub
+VOID ReadIdtGateDecriptor (
+ IN EFI_EXCEPTION_TYPE Vector,
+ OUT IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
)
{
- UINT8 *StubCopy;
+ IA32_DESCRIPTOR IdtrValue;
+ IA32_IDT_GATE_DESCRIPTOR *IdtTable;
- StubCopy = *Stub;
+ AsmReadIdtr (&IdtrValue);
+ IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base;
- //
- // Fixup the stub code for this vector
- //
+ CopyMem ((VOID *) IdtGateDecriptor, (VOID *) &(IdtTable)[Vector], sizeof (IA32_IDT_GATE_DESCRIPTOR));
+}
+/**
+ Write IDT Gate Descriptor into IDT Table.
- // The stub code looks like this:
- //
- // 00000000 89 25 00000004 R mov AppEsp, esp ; save stack top
- // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack
- // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed
- // 0000000D E9 db 0e9h ; jump rel32
- // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry
- //
+ @param Vector Specifies vector number.
+ @param IdtGateDecriptor Pointer to IDT Gate Descriptor written into IDT Table.
- //
- // poke in the exception type so the second push pushes the exception type
- //
- StubCopy[0x0c] = (UINT8) ExceptionType;
+**/
+VOID WriteIdtGateDecriptor (
+ EFI_EXCEPTION_TYPE Vector,
+ IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
+ )
+{
+ IA32_DESCRIPTOR IdtrValue;
+ IA32_IDT_GATE_DESCRIPTOR *IdtTable;
- //
- // fixup the jump target to point to the common entry
- //
- *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize];
+ AsmReadIdtr (&IdtrValue);
+ IdtTable = (IA32_IDT_GATE_DESCRIPTOR *) IdtrValue.Base;
- return EFI_SUCCESS;
+ CopyMem ((VOID *) &(IdtTable)[Vector], (VOID *) IdtGateDecriptor, sizeof (IA32_IDT_GATE_DESCRIPTOR));
}
+
/**
Creates a nes entry stub. Then saves the current IDT entry and replaces it
with an interrupt gate for the new entry point. The IdtEntryTable is updated
@@ -98,14 +91,13 @@ HookEntry (
Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry);
if (Status == EFI_SUCCESS) {
OldIntFlagState = WriteInterruptFlag (0);
- READ_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
+ ReadIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
- ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[0];
- ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc)[3];
+ IdtEntryTable[ExceptionType].OrigVector = (DEBUG_PROC) GetProcedureEntryPoint (&(IdtEntryTable[ExceptionType].OrigDesc));
Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry);
IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback;
- WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc));
+ WriteIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc));
WriteInterruptFlag (OldIntFlagState);
}
@@ -128,72 +120,13 @@ UnhookEntry (
BOOLEAN OldIntFlagState;
OldIntFlagState = WriteInterruptFlag (0);
- WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
+ WriteIdtGateDecriptor (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
WriteInterruptFlag (OldIntFlagState);
return EFI_SUCCESS;
}
/**
- 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 (
- VOID (*NewCallback)(),
- EFI_EXCEPTION_TYPE ExceptionType
- )
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (!FeaturePcdGet (PcdNtEmulatorEnable)) {
- if (COMPARE_DESCRIPTOR (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) {
- //
- // we've already installed to this vector
- //
- if (NewCallback != NULL) {
- //
- // if the input handler is non-null, error
- //
- Status = EFI_ALREADY_STARTED;
- } else {
- Status = 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 {
- Status = HookEntry (ExceptionType, NewCallback);
- }
- }
- }
-
- return Status;
-}
-
-/**
This is a DebugSupport protocol member function, hard
coded to support only 1 processor for now.
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h
index 1566f3e8b7..525ae8b3d7 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h
+++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupport.h
@@ -15,221 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef _PLDEBUG_SUPPORT_H_
#define _PLDEBUG_SUPPORT_H_
+#include "Ia32/DebugSupport.h"
-#include <Uefi.h>
-
-#include <Protocol/DebugSupport.h>
-#include <Protocol/LoadedImage.h>
-
-#include <Library/DebugLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PcdLib.h>
-
-#define NUM_IDT_ENTRIES 0x78
-#define SYSTEM_TIMER_VECTOR 0x68
-#define VECTOR_ENTRY_PAGES 1
-#define COPY_DESCRIPTOR(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR))
-#define READ_IDT(Vector, Dest) COPY_DESCRIPTOR ((Dest), &((GetIdtr ())[(Vector)]))
-#define WRITE_IDT(Vector, Src) COPY_DESCRIPTOR (&((GetIdtr ())[(Vector)]), (Src))
-#define COMPARE_DESCRIPTOR(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR))
#define EFI_ISA IsaIa32
-#define FF_FXSR (1 << 24)
-
-typedef UINT64 DESCRIPTOR;
-
-typedef
-VOID
-(*DEBUG_PROC) (
- VOID
- );
-
-typedef struct {
- DESCRIPTOR OrigDesc;
- DEBUG_PROC OrigVector;
- DESCRIPTOR NewDesc;
- DEBUG_PROC StubEntry;
- VOID (*RegisteredCallback) ();
-} IDT_ENTRY;
-
-extern EFI_SYSTEM_CONTEXT SystemContext;
-extern UINT8 InterruptEntryStub[];
-extern UINT32 StubSize;
-extern VOID (*OrigVector) (VOID);
-
-/**
- Generic IDT entry.
-
-**/
-VOID
-CommonIdtEntry (
- VOID
- );
-
-/**
- Check whether FXSTOR is supported
-
- @retval TRUE FXSTOR is supported.
- @retval FALSE FXSTOR is not supported.
-
-**/
-BOOLEAN
-FxStorSupport (
- VOID
- );
-
-/**
- Return the physical address of IDTR.
-
- @return The physical address of IDTR.
-
-**/
-DESCRIPTOR *
-GetIdtr (
- VOID
- );
-
-/**
- Encodes an IDT descriptor with the given physical address.
-
- @param DestDesc The IDT descriptor address.
- @param Vecotr The interrupt vector entry.
-
-**/
-VOID
-Vect2Desc (
- DESCRIPTOR * DestDesc,
- VOID (*Vector) (VOID)
- );
-
-/**
- Programs interrupt flag to the requested state and returns previous
- state.
-
- @param NewState New interrupt status.
-
- @retval TRUE Old interrupt status is TRUE.
- @retval FALSE Old interrupt status is FALSE
-
-**/
-BOOLEAN
-WriteInterruptFlag (
- BOOLEAN NewState
- );
-
-/**
- Initializes driver's handler registration databas.
-
- This code executes in boot services context
- Must be public because it's referenced from DebugSupport.c
-
- @retval EFI_UNSUPPORTED If IA32 processor does not support FXSTOR/FXRSTOR instructions,
- the context save will fail, so these processor's are not supported.
- @retval EFI_OUT_OF_RESOURCES Fails to allocate memory.
- @retval EFI_SUCCESS Initializes successfully.
-
-**/
-EFI_STATUS
-PlInitializeDebugSupportDriver (
- VOID
- );
-
-/**
- This is the callback that is written to the LoadedImage protocol instance
- on the image handle. It uninstalls all registered handlers and frees all entry
- stub memory.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
-
- @retval EFI_SUCCESS Always.
-
-**/
-EFI_STATUS
-EFIAPI
-PlUnloadDebugSupportDriver (
- IN EFI_HANDLE ImageHandle
- );
-
-/**
- This is a DebugSupport protocol member function, hard
- coded to support only 1 processor for now.
-
- @param This The DebugSupport instance
- @param MaxProcessorIndex The maximuim supported processor index
-
- @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0.
-
-**/
-EFI_STATUS
-EFIAPI
-GetMaximumProcessorIndex (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- OUT UINTN *MaxProcessorIndex
- );
-
-/**
- DebugSupport protocol member function.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param PeriodicCallback Callback function
-
- @retval EFI_SUCCESS Indicates the callback was registered.
- @retval others Callback was not registered.
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterPeriodicCallback (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN EFI_PERIODIC_CALLBACK PeriodicCallback
- );
-
-/**
- DebugSupport protocol member function.
-
- This code executes in boot services context.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param NewCallback Callback function
- @param ExceptionType Which exception to hook
-
- @retval EFI_SUCCESS Indicates the callback was registered.
- @retval others Callback was not registered.
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterExceptionCallback (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN EFI_EXCEPTION_CALLBACK NewCallback,
- IN EFI_EXCEPTION_TYPE ExceptionType
- );
-
-/**
- DebugSupport protocol member function. Calls assembly routine to flush cache.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param Start Physical base of the memory range to be invalidated
- @param Length mininum number of bytes in instruction cache to invalidate
-
- @retval EFI_SUCCESS Always returned.
-
-**/
-EFI_STATUS
-EFIAPI
-InvalidateInstructionCache (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN VOID *Start,
- IN UINT64 Length
- );
#endif
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c
new file mode 100644
index 0000000000..47e4e0e350
--- /dev/null
+++ b/MdeModulePkg/Universal/DebugSupportDxe/Ia32/PlDebugSupportIa32.c
@@ -0,0 +1,143 @@
+/** @file
+ IA32 specific debug support functions
+
+Copyright (c) 2006 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "DebugSupport.h"
+
+/**
+ Get Procedure Entry Point from IDT Gate Descriptor.
+
+ @param IdtGateDecriptor IDT Gate Descriptor.
+
+ @return Procedure Entry Point located in IDT Gate Descriptor.
+
+**/
+UINTN GetProcedureEntryPoint (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
+ )
+{
+ UINTN ProcedureEntryPoint;
+
+ ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow;
+ ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh;
+
+ return ProcedureEntryPoint;
+}
+
+/**
+ 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.
+
+ @retval EFI_SUCCESS Always.
+
+**/
+EFI_STATUS
+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 89 25 00000004 R mov AppEsp, esp ; save stack top
+ // 00000006 BC 00008014 R mov esp, offset DbgStkBot ; switch to debugger stack
+ // 0000000B 6A 00 push 0 ; push vector number - will be modified before installed
+ // 0000000D E9 db 0e9h ; jump rel32
+ // 0000000E 00000000 dd 0 ; fixed up to relative address of CommonIdtEntry
+ //
+
+ //
+ // poke in the exception type so the second push pushes the exception type
+ //
+ StubCopy[0x0c] = (UINT8) ExceptionType;
+
+ //
+ // fixup the jump target to point to the common entry
+ //
+ *(UINT32 *) &StubCopy[0x0e] = (UINT32) CommonIdtEntry - (UINT32) &StubCopy[StubSize];
+
+ return EFI_SUCCESS;
+}
+
+/**
+ 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 (
+ VOID (*NewCallback)(),
+ EFI_EXCEPTION_TYPE ExceptionType
+ )
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ if (!FeaturePcdGet (PcdNtEmulatorEnable)) {
+ 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 {
+ Status = 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 {
+ Status = HookEntry (ExceptionType, NewCallback);
+ }
+ }
+ }
+
+ return Status;
+}
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h
index cd5bb8e038..f8f5532de7 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h
+++ b/MdeModulePkg/Universal/DebugSupportDxe/Ipf/PlDebugSupport.h
@@ -26,8 +26,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PcdLib.h>
#define DISABLE_INTERRUPTS 0UL
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm
index 5cc3e52bfe..f486bd32b5 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm
+++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.asm
@@ -109,19 +109,6 @@ text SEGMENT
externdef InterruptDistrubutionHub:near
;------------------------------------------------------------------------------
-; VOID
-; EfiWbinvd (
-; VOID
-; )
-;
-; Abstract: Writeback and invalidate cache
-;
-EfiWbinvd PROC PUBLIC
- wbinvd
- ret
-EfiWbinvd ENDP
-
-;------------------------------------------------------------------------------
; BOOLEAN
; FxStorSupport (
; void
@@ -145,25 +132,6 @@ FxStorSupport PROC PUBLIC
FxStorSupport ENDP
-;------------------------------------------------------------------------------
-; DESCRIPTOR *
-; GetIdtr (
-; void
-; )
-;
-; Abstract: Returns physical address of IDTR
-;
-GetIdtr PROC PUBLIC
- push rbp
- mov rbp, rsp
-
- sidt QWORD PTR [rbp - 0ah]
- mov rax, QWORD PTR [rbp - 8h]
-
- mov rsp, rbp
- pop rbp
- ret
-GetIdtr ENDP
;------------------------------------------------------------------------------
@@ -196,7 +164,7 @@ WriteInterruptFlag ENDP
;------------------------------------------------------------------------------
; void
; Vect2Desc (
-; DESCRIPTOR * DestDesc, // rcx
+; IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx
; void (*Vector) (void) // rdx
; )
;
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c
deleted file mode 100644
index 24e5acc74a..0000000000
--- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/** @file
- X64 specific debug support functions
-
-Copyright (c) 2006 - 2007, Intel Corporation
-All rights reserved. This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-//
-// private header files
-//
-#include "PlDebugSupport.h"
-
-//
-// This the global main table to keep track of the interrupts
-//
-IDT_ENTRY *IdtEntryTable = NULL;
-DESCRIPTOR NullDesc = {0, 0};
-
-/**
- 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.
-
- @retval EFI_SUCCESS Always.
-
-**/
-EFI_STATUS
-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 EFI_SUCCESS;
-}
-
-/**
- Creates a nes entry stub. Then saves the current IDT entry and replaces it
- with an interrupt gate for the new entry point. The IdtEntryTable is updated
- with the new registered function.
-
- This code executes in boot services context. The stub entry executes in interrupt
- context.
-
- @param ExceptionType Specifies which vector to hook.
- @param NewCallback A pointer to the new function to be registered.
-
- @retval EFI_SUCCESS Always.
-
-**/
-EFI_STATUS
-HookEntry (
- IN EFI_EXCEPTION_TYPE ExceptionType,
- IN VOID (*NewCallback) ()
- )
-{
- BOOLEAN OldIntFlagState;
- EFI_STATUS Status;
-
- Status = CreateEntryStub (ExceptionType, (VOID **) &IdtEntryTable[ExceptionType].StubEntry);
- if (Status == EFI_SUCCESS) {
- OldIntFlagState = WriteInterruptFlag (0);
- READ_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
-
- ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[0] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc.Low)[0];
- ((UINT16 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT16 *) &IdtEntryTable[ExceptionType].OrigDesc.Low)[3];
- ((UINT32 *) &IdtEntryTable[ExceptionType].OrigVector)[1] = ((UINT32 *) &IdtEntryTable[ExceptionType].OrigDesc.High)[0];
-
- Vect2Desc (&IdtEntryTable[ExceptionType].NewDesc, IdtEntryTable[ExceptionType].StubEntry);
- IdtEntryTable[ExceptionType].RegisteredCallback = NewCallback;
- WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].NewDesc));
- WriteInterruptFlag (OldIntFlagState);
- }
-
- return Status;
-}
-
-/**
- Undoes HookEntry. This code executes in boot services context.
-
- @param ExceptionType Specifies which entry to unhook
-
- @retval EFI_SUCCESS Always.
-
-**/
-EFI_STATUS
-UnhookEntry (
- IN EFI_EXCEPTION_TYPE ExceptionType
- )
-{
- BOOLEAN OldIntFlagState;
-
- OldIntFlagState = WriteInterruptFlag (0);
- WRITE_IDT (ExceptionType, &(IdtEntryTable[ExceptionType].OrigDesc));
- WriteInterruptFlag (OldIntFlagState);
-
- return EFI_SUCCESS;
-}
-
-/**
- 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 (
- VOID (*NewCallback)(),
- EFI_EXCEPTION_TYPE ExceptionType
- )
-{
- EFI_STATUS Status;
-
- Status = EFI_SUCCESS;
-
- if (COMPARE_DESCRIPTOR (&IdtEntryTable[ExceptionType].NewDesc, &NullDesc)) {
- //
- // we've already installed to this vector
- //
- if (NewCallback != NULL) {
- //
- // if the input handler is non-null, error
- //
- Status = EFI_ALREADY_STARTED;
- } else {
- Status = 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 {
- Status = HookEntry (ExceptionType, NewCallback);
- }
- }
-
- return Status;
-}
-
-/**
- This is a DebugSupport protocol member function, hard
- coded to support only 1 processor for now.
-
- @param This The DebugSupport instance
- @param MaxProcessorIndex The maximuim supported processor index
-
- @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0.
-
-**/
-EFI_STATUS
-EFIAPI
-GetMaximumProcessorIndex (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- OUT UINTN *MaxProcessorIndex
- )
-{
- *MaxProcessorIndex = 0;
- return (EFI_SUCCESS);
-}
-
-/**
- DebugSupport protocol member function.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param PeriodicCallback Callback function
-
- @retval EFI_SUCCESS Indicates the callback was registered.
- @retval others Callback was not registered.
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterPeriodicCallback (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN EFI_PERIODIC_CALLBACK PeriodicCallback
- )
-{
- return ManageIdtEntryTable (PeriodicCallback, SYSTEM_TIMER_VECTOR);
-}
-
-/**
- DebugSupport protocol member function.
-
- This code executes in boot services context.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param NewCallback Callback function
- @param ExceptionType Which exception to hook
-
- @retval EFI_SUCCESS Indicates the callback was registered.
- @retval others Callback was not registered.
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterExceptionCallback (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN EFI_EXCEPTION_CALLBACK NewCallback,
- IN EFI_EXCEPTION_TYPE ExceptionType
- )
-{
- return ManageIdtEntryTable (NewCallback, ExceptionType);
-}
-
-/**
- DebugSupport protocol member function. Calls assembly routine to flush cache.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param Start Physical base of the memory range to be invalidated
- @param Length mininum number of bytes in instruction cache to invalidate
-
- @retval EFI_SUCCESS Always returned.
-
-**/
-EFI_STATUS
-EFIAPI
-InvalidateInstructionCache (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN VOID *Start,
- IN UINT64 Length
- )
-{
- AsmWbinvd ();
- return EFI_SUCCESS;
-}
-
-/**
- Initializes driver's handler registration databas.
-
- This code executes in boot services context
- Must be public because it's referenced from DebugSupport.c
-
- @retval EFI_UNSUPPORTED If x64 processor does not support FXSTOR/FXRSTOR instructions,
- the context save will fail, so these processor's are not supported.
- @retval EFI_OUT_OF_RESOURCES Fails to allocate memory.
- @retval EFI_SUCCESS Initializes successfully.
-
-**/
-EFI_STATUS
-PlInitializeDebugSupportDriver (
- VOID
- )
-{
- EFI_EXCEPTION_TYPE ExceptionType;
-
- if (!FxStorSupport ()) {
- return EFI_UNSUPPORTED;
- }
-
- IdtEntryTable = AllocateZeroPool (sizeof (IDT_ENTRY) * NUM_IDT_ENTRIES);
- if (IdtEntryTable == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
- IdtEntryTable[ExceptionType].StubEntry = (DEBUG_PROC) (UINTN) AllocatePool (StubSize);
- if (IdtEntryTable[ExceptionType].StubEntry == NULL) {
- goto ErrorCleanup;
- }
-
- CopyMem ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry, InterruptEntryStub, StubSize);
- }
- return EFI_SUCCESS;
-
-ErrorCleanup:
-
- for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
- if (IdtEntryTable[ExceptionType].StubEntry != NULL) {
- FreePool ((VOID *)(UINTN)IdtEntryTable[ExceptionType].StubEntry);
- }
- }
- FreePool (IdtEntryTable);
-
- return EFI_OUT_OF_RESOURCES;
-}
-
-/**
- This is the callback that is written to the LoadedImage protocol instance
- on the image handle. It uninstalls all registered handlers and frees all entry
- stub memory.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
-
- @retval EFI_SUCCESS Always.
-
-**/
-EFI_STATUS
-EFIAPI
-PlUnloadDebugSupportDriver (
- IN EFI_HANDLE ImageHandle
- )
-{
- EFI_EXCEPTION_TYPE ExceptionType;
-
- for (ExceptionType = 0; ExceptionType < NUM_IDT_ENTRIES; ExceptionType++) {
- ManageIdtEntryTable (NULL, ExceptionType);
- }
-
- FreePool (IdtEntryTable);
- return EFI_SUCCESS;
-}
-
-/**
- Common piece of code that invokes the registered handlers.
-
- This code executes in exception context so no efi calls are allowed.
-
- @param ExceptionType Exception type
- @param ContextRecord System context
-
-**/
-VOID
-InterruptDistrubutionHub (
- EFI_EXCEPTION_TYPE ExceptionType,
- EFI_SYSTEM_CONTEXT_IA32 *ContextRecord
- )
-{
- if (IdtEntryTable[ExceptionType].RegisteredCallback != NULL) {
- if (ExceptionType != SYSTEM_TIMER_VECTOR) {
- IdtEntryTable[ExceptionType].RegisteredCallback (ExceptionType, ContextRecord);
- } else {
- OrigVector = IdtEntryTable[ExceptionType].OrigVector;
- IdtEntryTable[ExceptionType].RegisteredCallback (ContextRecord);
- }
- }
-}
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h
index eb04f1a88c..3a9b9030c2 100644
--- a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h
+++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupport.h
@@ -1,5 +1,5 @@
/** @file
- X64 specific debug support macros, typedefs and prototypes.
+ X64 specific debug support macros.
Copyright (c) 2006 - 2008, Intel Corporation
All rights reserved. This program and the accompanying materials
@@ -15,224 +15,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#ifndef _PLDEBUG_SUPPORT_H_
#define _PLDEBUG_SUPPORT_H_
+#include "Ia32/DebugSupport.h"
-#include <Uefi.h>
-
-#include <Protocol/DebugSupport.h>
-#include <Protocol/LoadedImage.h>
-
-#include <Library/DebugLib.h>
-#include <Library/UefiDriverEntryPoint.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseLib.h>
-
-#include <Library/PcdLib.h>
-#define NUM_IDT_ENTRIES 0x78
-#define SYSTEM_TIMER_VECTOR 0x68
-#define VECTOR_ENTRY_PAGES 1
-#define COPY_DESCRIPTOR(Dest, Src) CopyMem ((Dest), (Src), sizeof (DESCRIPTOR))
-#define READ_IDT(Vector, Dest) COPY_DESCRIPTOR ((Dest), &((GetIdtr ())[(Vector)]))
-#define WRITE_IDT(Vector, Src) COPY_DESCRIPTOR (&((GetIdtr ())[(Vector)]), (Src))
-#define COMPARE_DESCRIPTOR(Desc1, Desc2) CompareMem ((Desc1), (Desc2), sizeof (DESCRIPTOR))
#define EFI_ISA IsaX64
-#define FF_FXSR (1 << 24)
-
-typedef struct {
- UINT64 Low;
- UINT64 High;
-} DESCRIPTOR;
-
-typedef
-VOID
-(*DEBUG_PROC) (
- VOID
- );
-
-typedef struct {
- DESCRIPTOR OrigDesc;
- DEBUG_PROC OrigVector;
- DESCRIPTOR NewDesc;
- DEBUG_PROC StubEntry;
- VOID (*RegisteredCallback) ();
-} IDT_ENTRY;
-
-extern EFI_SYSTEM_CONTEXT SystemContext;
-extern UINT8 InterruptEntryStub[];
-extern UINT32 StubSize;
-extern VOID (*OrigVector) (VOID);
-
-/**
- Generic IDT entry.
-
-**/
-VOID
-CommonIdtEntry (
- VOID
- );
-
-/**
- Check whether FXSTOR is supported
-
- @retval TRUE FXSTOR is supported.
- @retval FALSE FXSTOR is not supported.
-
-**/
-BOOLEAN
-FxStorSupport (
- VOID
- );
-
-/**
- Return the physical address of IDTR.
-
- @return The physical address of IDTR.
-
-**/
-DESCRIPTOR *
-GetIdtr (
- VOID
- );
-
-/**
- Encodes an IDT descriptor with the given physical address.
-
- @param DestDesc The IDT descriptor address.
- @param Vecotr The interrupt vector entry.
-
-**/
-VOID
-Vect2Desc (
- DESCRIPTOR * DestDesc,
- VOID (*Vector) (VOID)
- );
-
-/**
- Programs interrupt flag to the requested state and returns previous
- state.
-
- @param NewState New interrupt status.
-
- @retval TRUE Old interrupt status is TRUE.
- @retval FALSE Old interrupt status is FALSE
-
-**/
-BOOLEAN
-WriteInterruptFlag (
- BOOLEAN NewState
- );
-
-/**
- Initializes driver's handler registration databas.
-
- This code executes in boot services context
- Must be public because it's referenced from DebugSupport.c
-
- @retval EFI_UNSUPPORTED If x64 processor does not support FXSTOR/FXRSTOR instructions,
- the context save will fail, so these processor's are not supported.
- @retval EFI_OUT_OF_RESOURCES Fails to allocate memory.
- @retval EFI_SUCCESS Initializes successfully.
-
-**/
-EFI_STATUS
-PlInitializeDebugSupportDriver (
- VOID
- );
-
-/**
- This is the callback that is written to the LoadedImage protocol instance
- on the image handle. It uninstalls all registered handlers and frees all entry
- stub memory.
-
- @param ImageHandle The firmware allocated handle for the EFI image.
-
- @retval EFI_SUCCESS Always.
-
-**/
-EFI_STATUS
-EFIAPI
-PlUnloadDebugSupportDriver (
- IN EFI_HANDLE ImageHandle
- );
-
-/**
- This is a DebugSupport protocol member function, hard
- coded to support only 1 processor for now.
-
- @param This The DebugSupport instance
- @param MaxProcessorIndex The maximuim supported processor index
-
- @retval EFI_SUCCESS Always returned with **MaxProcessorIndex set to 0.
-
-**/
-EFI_STATUS
-EFIAPI
-GetMaximumProcessorIndex (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- OUT UINTN *MaxProcessorIndex
- );
-
-/**
- DebugSupport protocol member function.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param PeriodicCallback Callback function
-
- @retval EFI_SUCCESS Indicates the callback was registered.
- @retval others Callback was not registered.
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterPeriodicCallback (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN EFI_PERIODIC_CALLBACK PeriodicCallback
- );
-
-/**
- DebugSupport protocol member function.
-
- This code executes in boot services context.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param NewCallback Callback function
- @param ExceptionType Which exception to hook
-
- @retval EFI_SUCCESS Indicates the callback was registered.
- @retval others Callback was not registered.
-
-**/
-EFI_STATUS
-EFIAPI
-RegisterExceptionCallback (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN EFI_EXCEPTION_CALLBACK NewCallback,
- IN EFI_EXCEPTION_TYPE ExceptionType
- );
-
-/**
- DebugSupport protocol member function. Calls assembly routine to flush cache.
-
- @param This The DebugSupport instance
- @param ProcessorIndex Which processor the callback applies to.
- @param Start Physical base of the memory range to be invalidated
- @param Length mininum number of bytes in instruction cache to invalidate
-
- @retval EFI_SUCCESS Always returned.
-
-**/
-EFI_STATUS
-EFIAPI
-InvalidateInstructionCache (
- IN EFI_DEBUG_SUPPORT_PROTOCOL *This,
- IN UINTN ProcessorIndex,
- IN VOID *Start,
- IN UINT64 Length
- );
#endif
diff --git a/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c
new file mode 100644
index 0000000000..943d2c6911
--- /dev/null
+++ b/MdeModulePkg/Universal/DebugSupportDxe/X64/PlDebugSupportX64.c
@@ -0,0 +1,143 @@
+/** @file
+ X64 specific debug support functions
+
+Copyright (c) 2006 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//
+// private header files
+//
+#include "DebugSupport.h"
+
+/**
+ Get Procedure Entry Point from IDT Gate Descriptor.
+
+ @param IdtGateDecriptor IDT Gate Descriptor.
+
+ @return Procedure Entry Point located in IDT Gate Descriptor.
+
+**/
+UINTN GetProcedureEntryPoint (
+ IN IA32_IDT_GATE_DESCRIPTOR *IdtGateDecriptor
+ )
+{
+ UINTN ProcedureEntryPoint;
+
+ ((UINT16 *) &ProcedureEntryPoint)[0] = (UINT16) IdtGateDecriptor->Bits.OffsetLow;
+ ((UINT16 *) &ProcedureEntryPoint)[1] = (UINT16) IdtGateDecriptor->Bits.OffsetHigh;
+ ((UINT32 *) &ProcedureEntryPoint)[1] = (UINT32) IdtGateDecriptor->Bits.OffsetUpper;
+
+ return ProcedureEntryPoint;
+}
+
+/**
+ 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.
+
+ @retval EFI_SUCCESS Always.
+
+**/
+EFI_STATUS
+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 EFI_SUCCESS;
+}
+
+/**
+ 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 (
+ VOID (*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 {
+ Status = 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 {
+ Status = HookEntry (ExceptionType, NewCallback);
+ }
+ }
+
+ return Status;
+}