summaryrefslogtreecommitdiff
path: root/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c')
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
new file mode 100644
index 0000000000..cc49dc0a59
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c
@@ -0,0 +1,247 @@
+/** @file
+ Debug Agent library implementition for Dxe Core and Dxr modules.
+
+ Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
+ 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 "DxeDebugAgentLib.h"
+
+DEBUG_AGENT_MAILBOX mMailbox;
+
+DEBUG_AGENT_MAILBOX *mMailboxPointer;
+
+IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33];
+
+BOOLEAN mConfigurationTableNeeded = FALSE;
+
+CONST BOOLEAN MultiProcessorDebugSupport = TRUE;
+
+/**
+ Constructor allocates the NVS memory to store Mailbox and install configuration table
+ in system table to store its pointer.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval RETURN_SUCCESS Allocate the global memory space to store guid and function tables.
+ @retval RETURN_OUT_OF_RESOURCES No enough memory to allocated.
+
+**/
+RETURN_STATUS
+EFIAPI
+DxeDebugAgentLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ if (!mConfigurationTableNeeded) {
+ return RETURN_SUCCESS;
+ }
+
+ Address = 0;
+ Status = gBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)),
+ &Address
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ CopyMem (
+ (UINT8 *) (UINTN) Address,
+ (UINT8 *) (UINTN) mMailboxPointer,
+ sizeof (DEBUG_AGENT_MAILBOX)
+ );
+
+ mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;
+
+ return gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);
+}
+
+/**
+ Get the pointer to Mailbox from the GUIDed HOB.
+
+ @param[in] HobStart The starting HOB pointer to search from.
+
+ @return Pointer to Mailbox.
+
+**/
+DEBUG_AGENT_MAILBOX *
+GetMailboxFromHob (
+ IN VOID *HobStart
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+
+ GuidHob = GetNextGuidHob (&gEfiDebugAgentGuid, HobStart);
+ if (GuidHob == NULL) {
+ return NULL;
+ }
+
+ return (DEBUG_AGENT_MAILBOX *) (GET_GUID_HOB_DATA(GuidHob));
+}
+
+/**
+ Get Debug Agent Mailbox pointer.
+
+ @return Mailbox pointer.
+
+**/
+DEBUG_AGENT_MAILBOX *
+GetMailboxPointer (
+ VOID
+ )
+{
+ return mMailboxPointer;
+}
+
+/**
+ Get debug port handle.
+
+ @return Debug port handle.
+
+**/
+DEBUG_PORT_HANDLE
+GetDebugPortHandle (
+ VOID
+ )
+{
+ return (DEBUG_PORT_HANDLE) (UINTN)(mMailboxPointer->DebugPortHandle);
+}
+
+
+/**
+ Initialize debug agent.
+
+ This function is used to set up debug enviroment for DXE phase.
+
+ If this function is called by DXE Core, Context must be the pointer
+ to HOB list which will be used to get GUIDed HOB. It will enable
+ interrupt to support break-in feature.
+ If this function is called by DXE module, Context must be NULL. It
+ will enable interrupt to support break-in feature.
+
+ @param[in] InitFlag Init flag is used to decide initialize process.
+ @param[in] Context Context needed according to InitFlag.
+ @param[in] Function Continue function called by debug agent library; it was
+ optional.
+
+**/
+VOID
+EFIAPI
+InitializeDebugAgent (
+ IN UINT32 InitFlag,
+ IN VOID *Context, OPTIONAL
+ IN DEBUG_AGENT_CONTINUE Function OPTIONAL
+ )
+{
+ DEBUG_AGENT_MAILBOX *Mailbox;
+ IA32_DESCRIPTOR Idtr;
+ UINT16 IdtEntryCount;
+ BOOLEAN InterruptStatus;
+
+ if (InitFlag != DEBUG_AGENT_INIT_DXE_CORE &&
+ InitFlag != DEBUG_AGENT_INIT_S3 &&
+ InitFlag != DEBUG_AGENT_INIT_DXE_AP) {
+ return;
+ }
+
+ //
+ // Save and disable original interrupt status
+ //
+ InterruptStatus = SaveAndDisableInterrupts ();
+
+ if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
+ //
+ // Try to get Mailbox from GUIDed HOB.
+ //
+ mConfigurationTableNeeded = TRUE;
+ Mailbox = GetMailboxFromHob (Context);
+
+ } else if (InitFlag == DEBUG_AGENT_INIT_DXE_AP) {
+
+ EnableInterrupts ();
+
+ return;
+
+ } else {
+ //
+ // If it is in S3 path, needn't to install configuration table.
+ //
+ Mailbox = NULL;
+ }
+
+ if (Mailbox != NULL) {
+ //
+ // If Mailbox exists, copy it into one global variable.
+ //
+ CopyMem (&mMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ mMailbox.DebugPortHandle = 0;
+ } else {
+ //
+ // If Mailbox not exists, used the local Mailbox.
+ //
+ ZeroMem (&mMailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ }
+
+ mMailboxPointer = &mMailbox;
+
+ //
+ // Get original IDT address and size.
+ //
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &Idtr);
+ IdtEntryCount = (UINT16) ((Idtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR));
+ if (IdtEntryCount < 33) {
+ Idtr.Limit = (UINT16) (sizeof (IA32_IDT_GATE_DESCRIPTOR) * 33 - 1);
+ Idtr.Base = (UINTN) &mIdtEntryTable;
+ AsmWriteIdtr ((IA32_DESCRIPTOR *) &Idtr);
+ }
+
+ //
+ // Initialize the IDT table entries to support source level debug.
+ //
+ InitializeDebugIdt ();
+
+ //
+ // Initialize debug communication port
+ //
+ mMailboxPointer->DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize (NULL, NULL);
+
+ InitializeSpinLock (&mDebugMpContext.MpContextSpinLock);
+ InitializeSpinLock (&mDebugMpContext.DebugPortSpinLock);
+
+ if (InitFlag == DEBUG_AGENT_INIT_DXE_CORE) {
+ //
+ // Initialize Debug Timer hardware and enable interrupt.
+ //
+ InitializeDebugTimer ();
+ EnableInterrupts ();
+
+ return;
+ } else {
+ //
+ // Disable Debug Timer interrupt in S3 path.
+ //
+ SaveAndSetDebugTimerInterrupt (FALSE);
+
+ //
+ // Restore interrupt state.
+ //
+ SetInterruptState (InterruptStatus);
+ }
+
+}
+