summaryrefslogtreecommitdiff
path: root/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c')
-rw-r--r--SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c157
1 files changed, 157 insertions, 0 deletions
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
new file mode 100644
index 0000000000..fa42311659
--- /dev/null
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
@@ -0,0 +1,157 @@
+/** @file
+ Debug Agent library implementition.
+
+ 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 "SmmDebugAgentLib.h"
+
+DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL;
+
+GLOBAL_REMOVE_IF_UNREFERENCED DEBUG_AGENT_MAILBOX mLocalMailbox;
+
+GLOBAL_REMOVE_IF_UNREFERENCED UINTN mSavedDebugRegisters[6];
+
+CONST BOOLEAN MultiProcessorDebugSupport = FALSE;
+
+
+/**
+ 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);
+}
+
+/**
+ Store debug register when SMI exit.
+
+**/
+VOID
+SaveDebugRegister (
+ VOID
+ )
+{
+ mSavedDebugRegisters[0] = AsmReadDr0 ();
+ mSavedDebugRegisters[1] = AsmReadDr1 ();
+ mSavedDebugRegisters[2] = AsmReadDr2 ();
+ mSavedDebugRegisters[3] = AsmReadDr3 ();
+ mSavedDebugRegisters[4] = AsmReadDr6 ();
+ mSavedDebugRegisters[5] = AsmReadDr7 ();
+}
+
+/**
+ Restore debug register when SMI exit.
+
+**/
+VOID
+RestoreDebugRegister (
+ VOID
+ )
+{
+ AsmWriteDr7 (0);
+ AsmWriteDr0 (mSavedDebugRegisters[0]);
+ AsmWriteDr1 (mSavedDebugRegisters[1]);
+ AsmWriteDr2 (mSavedDebugRegisters[2]);
+ AsmWriteDr3 (mSavedDebugRegisters[3]);
+ AsmWriteDr6 (mSavedDebugRegisters[4]);
+ AsmWriteDr7 (mSavedDebugRegisters[5]);
+}
+
+/**
+ Initialize debug agent.
+
+ This function is used to set up debug enviroment for source level debug
+ in SMM code.
+
+ If InitFlag is DEBUG_AGENT_INIT_SMM, it will overirde IDT table entries
+ and initialize debug port. It will get debug agent Mailbox from GUIDed HOB,
+ it it exists, debug agent wiil copied it into the local Mailbox in SMM space.
+ it will overirde IDT table entries and initialize debug port. Context will be
+ NULL.
+ If InitFlag is DEBUG_AGENT_INIT_ENTER_SMI, debug agent will save Debug
+ Registers and get local Mailbox in SMM space. Context will be NULL.
+ If InitFlag is DEBUG_AGENT_INIT_EXIT_SMI, debug agent will restore Debug
+ Registers. Context will be NULL.
+
+ @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
+ )
+{
+ EFI_STATUS Status;
+ UINT64 DebugPortHandle;
+
+ switch (InitFlag) {
+ case DEBUG_AGENT_INIT_SMM:
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **) &mMailboxPointer);
+ if (EFI_ERROR (Status) || mMailboxPointer == NULL) {
+ ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ mMailboxPointer = &mLocalMailbox;
+ }
+
+ break;
+
+ case DEBUG_AGENT_INIT_ENTER_SMI:
+ SaveDebugRegister ();
+ InitializeDebugIdt ();
+
+ if (mMailboxPointer != NULL) {
+ //
+ // Initialize debug communication port
+ //
+ DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE) (UINTN)mMailboxPointer->DebugPortHandle, NULL);
+ mMailboxPointer->DebugPortHandle = DebugPortHandle;
+
+ if (mMailboxPointer->DebugFlag.Bits.BreakOnNextSmi == 1) {
+ //
+ // If SMM entry break is set, SMM code will be break at here.
+ //
+ CpuBreakpoint ();
+ }
+ }
+ break;
+
+ case DEBUG_AGENT_INIT_EXIT_SMI:
+ RestoreDebugRegister ();
+ break;
+ }
+}
+