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.c828
1 files changed, 414 insertions, 414 deletions
diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
index cc5bb957f7..1cbba43b20 100644
--- a/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
+++ b/SourceLevelDebugPkg/Library/DebugAgent/SmmDebugAgent/SmmDebugAgentLib.c
@@ -1,414 +1,414 @@
-/** @file
- Debug Agent library implementation.
-
- Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "SmmDebugAgentLib.h"
-
-DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL;
-DEBUG_AGENT_MAILBOX mLocalMailbox;
-UINTN mSavedDebugRegisters[6];
-IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33];
-BOOLEAN mSkipBreakpoint = FALSE;
-BOOLEAN mSmmDebugIdtInitFlag = FALSE;
-BOOLEAN mApicTimerRestore = FALSE;
-BOOLEAN mPeriodicMode;
-UINT32 mTimerCycle;
-UINTN mApicTimerDivisor;
-UINT8 mVector;
-
-CHAR8 mWarningMsgIgnoreSmmEntryBreak[] = "Ignore smmentrybreak setting for SMI issued during DXE debugging!\r\n";
-
-/**
- Check if debug agent support multi-processor.
-
- @retval TRUE Multi-processor is supported.
- @retval FALSE Multi-processor is not supported.
-
-**/
-BOOLEAN
-MultiProcessorDebugSupport (
- VOID
- )
-{
- return FALSE;
-}
-
-/**
- Read the Attach/Break-in symbols from the debug port.
-
- @param[in] Handle Pointer to Debug Port handle.
- @param[out] BreakSymbol Returned break symbol.
-
- @retval EFI_SUCCESS Read the symbol in BreakSymbol.
- @retval EFI_NOT_FOUND No read the break symbol.
-
-**/
-EFI_STATUS
-DebugReadBreakSymbol (
- IN DEBUG_PORT_HANDLE Handle,
- OUT UINT8 *BreakSymbol
- )
-{
- //
- // Smm instance has no debug timer to poll break symbol.
- //
- return EFI_NOT_FOUND;
-}
-
-/**
- Get the pointer to Mailbox from the GUIDed HOB.
-
- @return Pointer to Mailbox.
-
-**/
-DEBUG_AGENT_MAILBOX *
-GetMailboxFromHob (
- VOID
- )
-{
- EFI_HOB_GUID_TYPE *GuidHob;
- UINT64 *MailboxLocation;
- DEBUG_AGENT_MAILBOX *Mailbox;
-
- GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid);
- if (GuidHob == NULL) {
- return NULL;
- }
-
- MailboxLocation = (UINT64 *)(GET_GUID_HOB_DATA (GuidHob));
- Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
- VerifyMailboxChecksum (Mailbox);
-
- return Mailbox;
-}
-
-/**
- Get Debug Agent Mailbox pointer.
-
- @return Mailbox pointer.
-
-**/
-DEBUG_AGENT_MAILBOX *
-GetMailboxPointer (
- VOID
- )
-{
- VerifyMailboxChecksum (mMailboxPointer);
- return mMailboxPointer;
-}
-
-/**
- Get debug port handle.
-
- @return Debug port handle.
-
-**/
-DEBUG_PORT_HANDLE
-GetDebugPortHandle (
- VOID
- )
-{
- return (DEBUG_PORT_HANDLE)(UINTN)(GetMailboxPointer ()->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 environment for source level debug
- in SMM code.
-
- If InitFlag is DEBUG_AGENT_INIT_SMM, it will override 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 override IDT table entries and initialize debug port. Context must
- point to a BOOLEAN if it's not NULL, which indicates SMM Debug Agent supported
- or not.
- 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;
- IA32_IDT_GATE_DESCRIPTOR IdtEntry[33];
- IA32_DESCRIPTOR IdtDescriptor;
- IA32_DESCRIPTOR *Ia32Idtr;
- IA32_IDT_ENTRY *Ia32IdtEntry;
- IA32_DESCRIPTOR Idtr;
- UINT16 IdtEntryCount;
- DEBUG_AGENT_MAILBOX *Mailbox;
- UINT64 *MailboxLocation;
- UINT32 DebugTimerFrequency;
-
- switch (InitFlag) {
- case DEBUG_AGENT_INIT_SMM:
- //
- // Install configuration table for persisted vector handoff info
- //
- Status = gSmst->SmmInstallConfigurationTable (
- gSmst,
- &gEfiVectorHandoffTableGuid,
- (VOID *)&mVectorHandoffInfoDebugAgent[0],
- sizeof (EFI_VECTOR_HANDOFF_INFO) * mVectorHandoffInfoCount
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
- if (Context != NULL) {
- *(BOOLEAN *)Context = FALSE;
- }
-
- CpuDeadLoop ();
- }
-
- //
- // Check if Debug Agent initialized in DXE phase
- //
- Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **)&Mailbox);
- if ((Status == EFI_SUCCESS) && (Mailbox != NULL)) {
- VerifyMailboxChecksum (Mailbox);
- mMailboxPointer = Mailbox;
- if (Context != NULL) {
- *(BOOLEAN *)Context = TRUE;
- }
-
- break;
- }
-
- //
- // Check if Debug Agent initialized in SEC/PEI phase
- //
- Mailbox = GetMailboxFromHob ();
- if (Mailbox != NULL) {
- mMailboxPointer = Mailbox;
- if (Context != NULL) {
- *(BOOLEAN *)Context = TRUE;
- }
-
- break;
- }
-
- //
- // Debug Agent was not initialized before, use the local mailbox.
- //
- ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
- Mailbox = &mLocalMailbox;
- //
- // Save original IDT entries
- //
- AsmReadIdtr (&IdtDescriptor);
- CopyMem (&IdtEntry, (VOID *)IdtDescriptor.Base, 33 * sizeof (IA32_IDT_GATE_DESCRIPTOR));
- //
- // Initialized Debug Agent
- //
- InitializeDebugIdt ();
- //
- // Initialize Debug Timer hardware and save its frequency
- //
- InitializeDebugTimer (&DebugTimerFrequency, TRUE);
- UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
-
- DebugPortHandle = (UINT64)(UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE)(UINTN)Mailbox->DebugPortHandle, NULL);
- UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
- mMailboxPointer = Mailbox;
- //
- // Trigger one software interrupt to inform HOST
- //
- TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);
-
- SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
- //
- // Memory has been ready
- //
- if (IsHostAttached ()) {
- //
- // Trigger one software interrupt to inform HOST
- //
- TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
- }
-
- //
- // Find and report PE/COFF image info to HOST
- //
- FindAndReportModuleImageInfo (SIZE_4KB);
- //
- // Restore saved IDT entries
- //
- CopyMem ((VOID *)IdtDescriptor.Base, &IdtEntry, 33 * sizeof (IA32_IDT_GATE_DESCRIPTOR));
-
- if (Context != NULL) {
- *(BOOLEAN *)Context = TRUE;
- }
-
- break;
-
- case DEBUG_AGENT_INIT_ENTER_SMI:
- SaveDebugRegister ();
- if (!mSmmDebugIdtInitFlag) {
- //
- // We only need to initialize Debug IDT table at first SMI entry
- // after SMM relocation.
- //
- InitializeDebugIdt ();
- mSmmDebugIdtInitFlag = TRUE;
- }
-
- //
- // Check if CPU APIC Timer is working, otherwise initialize it.
- //
- InitializeLocalApicSoftwareEnable (TRUE);
- GetApicTimerState (&mApicTimerDivisor, &mPeriodicMode, &mVector);
- mTimerCycle = GetApicTimerInitCount ();
- if (!mPeriodicMode || (mTimerCycle == 0)) {
- mApicTimerRestore = TRUE;
- InitializeDebugTimer (NULL, FALSE);
- }
-
- Mailbox = GetMailboxPointer ();
- if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {
- //
- // If Debug Agent has been communication state with HOST, we need skip
- // any break points set in SMM, set Skip Breakpoint flag
- //
- mSkipBreakpoint = TRUE;
- }
-
- if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI) == 1) {
- if (mSkipBreakpoint) {
- //
- // Print warning message if ignore smm entry break
- //
- DebugPortWriteBuffer (
- (DEBUG_PORT_HANDLE)(UINTN)Mailbox->DebugPortHandle,
- (UINT8 *)mWarningMsgIgnoreSmmEntryBreak,
- AsciiStrLen (mWarningMsgIgnoreSmmEntryBreak)
- );
- } else {
- //
- // If SMM entry break is set, SMM code will be break at here.
- //
- CpuBreakpoint ();
- }
- }
-
- break;
-
- case DEBUG_AGENT_INIT_EXIT_SMI:
- Mailbox = GetMailboxPointer ();
- //
- // Clear Skip Breakpoint flag
- //
- mSkipBreakpoint = FALSE;
- RestoreDebugRegister ();
- //
- // Restore APIC Timer
- //
- if (mApicTimerRestore) {
- InitializeApicTimer (mApicTimerDivisor, mTimerCycle, mPeriodicMode, mVector);
- mApicTimerRestore = FALSE;
- }
-
- break;
-
- case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
- if (Context == NULL) {
- DEBUG ((DEBUG_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
- CpuDeadLoop ();
- } else {
- Ia32Idtr = (IA32_DESCRIPTOR *)Context;
- Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
- MailboxLocation = (UINT64 *)((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
- ((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
- mMailboxPointer = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
- VerifyMailboxChecksum (mMailboxPointer);
- //
- // 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;
- ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
- AsmWriteIdtr ((IA32_DESCRIPTOR *)&Idtr);
- }
-
- InitializeDebugIdt ();
- //
- // Initialize Debug Timer hardware and save its frequency
- //
- InitializeDebugTimer (&DebugTimerFrequency, TRUE);
- UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
- //
- // Enable Debug Timer interrupt and CPU interrupt
- //
- SaveAndSetDebugTimerInterrupt (TRUE);
- EnableInterrupts ();
-
- FindAndReportModuleImageInfo (SIZE_4KB);
- }
-
- break;
-
- default:
- //
- // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
- // Debug Agent library instance.
- //
- DEBUG ((DEBUG_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
- CpuDeadLoop ();
- break;
- }
-}
+/** @file
+ Debug Agent library implementation.
+
+ Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SmmDebugAgentLib.h"
+
+DEBUG_AGENT_MAILBOX *mMailboxPointer = NULL;
+DEBUG_AGENT_MAILBOX mLocalMailbox;
+UINTN mSavedDebugRegisters[6];
+IA32_IDT_GATE_DESCRIPTOR mIdtEntryTable[33];
+BOOLEAN mSkipBreakpoint = FALSE;
+BOOLEAN mSmmDebugIdtInitFlag = FALSE;
+BOOLEAN mApicTimerRestore = FALSE;
+BOOLEAN mPeriodicMode;
+UINT32 mTimerCycle;
+UINTN mApicTimerDivisor;
+UINT8 mVector;
+
+CHAR8 mWarningMsgIgnoreSmmEntryBreak[] = "Ignore smmentrybreak setting for SMI issued during DXE debugging!\r\n";
+
+/**
+ Check if debug agent support multi-processor.
+
+ @retval TRUE Multi-processor is supported.
+ @retval FALSE Multi-processor is not supported.
+
+**/
+BOOLEAN
+MultiProcessorDebugSupport (
+ VOID
+ )
+{
+ return FALSE;
+}
+
+/**
+ Read the Attach/Break-in symbols from the debug port.
+
+ @param[in] Handle Pointer to Debug Port handle.
+ @param[out] BreakSymbol Returned break symbol.
+
+ @retval EFI_SUCCESS Read the symbol in BreakSymbol.
+ @retval EFI_NOT_FOUND No read the break symbol.
+
+**/
+EFI_STATUS
+DebugReadBreakSymbol (
+ IN DEBUG_PORT_HANDLE Handle,
+ OUT UINT8 *BreakSymbol
+ )
+{
+ //
+ // Smm instance has no debug timer to poll break symbol.
+ //
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Get the pointer to Mailbox from the GUIDed HOB.
+
+ @return Pointer to Mailbox.
+
+**/
+DEBUG_AGENT_MAILBOX *
+GetMailboxFromHob (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UINT64 *MailboxLocation;
+ DEBUG_AGENT_MAILBOX *Mailbox;
+
+ GuidHob = GetFirstGuidHob (&gEfiDebugAgentGuid);
+ if (GuidHob == NULL) {
+ return NULL;
+ }
+
+ MailboxLocation = (UINT64 *)(GET_GUID_HOB_DATA (GuidHob));
+ Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
+ VerifyMailboxChecksum (Mailbox);
+
+ return Mailbox;
+}
+
+/**
+ Get Debug Agent Mailbox pointer.
+
+ @return Mailbox pointer.
+
+**/
+DEBUG_AGENT_MAILBOX *
+GetMailboxPointer (
+ VOID
+ )
+{
+ VerifyMailboxChecksum (mMailboxPointer);
+ return mMailboxPointer;
+}
+
+/**
+ Get debug port handle.
+
+ @return Debug port handle.
+
+**/
+DEBUG_PORT_HANDLE
+GetDebugPortHandle (
+ VOID
+ )
+{
+ return (DEBUG_PORT_HANDLE)(UINTN)(GetMailboxPointer ()->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 environment for source level debug
+ in SMM code.
+
+ If InitFlag is DEBUG_AGENT_INIT_SMM, it will override 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 override IDT table entries and initialize debug port. Context must
+ point to a BOOLEAN if it's not NULL, which indicates SMM Debug Agent supported
+ or not.
+ 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;
+ IA32_IDT_GATE_DESCRIPTOR IdtEntry[33];
+ IA32_DESCRIPTOR IdtDescriptor;
+ IA32_DESCRIPTOR *Ia32Idtr;
+ IA32_IDT_ENTRY *Ia32IdtEntry;
+ IA32_DESCRIPTOR Idtr;
+ UINT16 IdtEntryCount;
+ DEBUG_AGENT_MAILBOX *Mailbox;
+ UINT64 *MailboxLocation;
+ UINT32 DebugTimerFrequency;
+
+ switch (InitFlag) {
+ case DEBUG_AGENT_INIT_SMM:
+ //
+ // Install configuration table for persisted vector handoff info
+ //
+ Status = gSmst->SmmInstallConfigurationTable (
+ gSmst,
+ &gEfiVectorHandoffTableGuid,
+ (VOID *)&mVectorHandoffInfoDebugAgent[0],
+ sizeof (EFI_VECTOR_HANDOFF_INFO) * mVectorHandoffInfoCount
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "DebugAgent: Cannot install configuration table for persisted vector handoff info!\n"));
+ if (Context != NULL) {
+ *(BOOLEAN *)Context = FALSE;
+ }
+
+ CpuDeadLoop ();
+ }
+
+ //
+ // Check if Debug Agent initialized in DXE phase
+ //
+ Status = EfiGetSystemConfigurationTable (&gEfiDebugAgentGuid, (VOID **)&Mailbox);
+ if ((Status == EFI_SUCCESS) && (Mailbox != NULL)) {
+ VerifyMailboxChecksum (Mailbox);
+ mMailboxPointer = Mailbox;
+ if (Context != NULL) {
+ *(BOOLEAN *)Context = TRUE;
+ }
+
+ break;
+ }
+
+ //
+ // Check if Debug Agent initialized in SEC/PEI phase
+ //
+ Mailbox = GetMailboxFromHob ();
+ if (Mailbox != NULL) {
+ mMailboxPointer = Mailbox;
+ if (Context != NULL) {
+ *(BOOLEAN *)Context = TRUE;
+ }
+
+ break;
+ }
+
+ //
+ // Debug Agent was not initialized before, use the local mailbox.
+ //
+ ZeroMem (&mLocalMailbox, sizeof (DEBUG_AGENT_MAILBOX));
+ Mailbox = &mLocalMailbox;
+ //
+ // Save original IDT entries
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ CopyMem (&IdtEntry, (VOID *)IdtDescriptor.Base, 33 * sizeof (IA32_IDT_GATE_DESCRIPTOR));
+ //
+ // Initialized Debug Agent
+ //
+ InitializeDebugIdt ();
+ //
+ // Initialize Debug Timer hardware and save its frequency
+ //
+ InitializeDebugTimer (&DebugTimerFrequency, TRUE);
+ UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
+
+ DebugPortHandle = (UINT64)(UINTN)DebugPortInitialize ((DEBUG_PORT_HANDLE)(UINTN)Mailbox->DebugPortHandle, NULL);
+ UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, DebugPortHandle);
+ mMailboxPointer = Mailbox;
+ //
+ // Trigger one software interrupt to inform HOST
+ //
+ TriggerSoftInterrupt (SYSTEM_RESET_SIGNATURE);
+
+ SetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY, 1);
+ //
+ // Memory has been ready
+ //
+ if (IsHostAttached ()) {
+ //
+ // Trigger one software interrupt to inform HOST
+ //
+ TriggerSoftInterrupt (MEMORY_READY_SIGNATURE);
+ }
+
+ //
+ // Find and report PE/COFF image info to HOST
+ //
+ FindAndReportModuleImageInfo (SIZE_4KB);
+ //
+ // Restore saved IDT entries
+ //
+ CopyMem ((VOID *)IdtDescriptor.Base, &IdtEntry, 33 * sizeof (IA32_IDT_GATE_DESCRIPTOR));
+
+ if (Context != NULL) {
+ *(BOOLEAN *)Context = TRUE;
+ }
+
+ break;
+
+ case DEBUG_AGENT_INIT_ENTER_SMI:
+ SaveDebugRegister ();
+ if (!mSmmDebugIdtInitFlag) {
+ //
+ // We only need to initialize Debug IDT table at first SMI entry
+ // after SMM relocation.
+ //
+ InitializeDebugIdt ();
+ mSmmDebugIdtInitFlag = TRUE;
+ }
+
+ //
+ // Check if CPU APIC Timer is working, otherwise initialize it.
+ //
+ InitializeLocalApicSoftwareEnable (TRUE);
+ GetApicTimerState (&mApicTimerDivisor, &mPeriodicMode, &mVector);
+ mTimerCycle = GetApicTimerInitCount ();
+ if (!mPeriodicMode || (mTimerCycle == 0)) {
+ mApicTimerRestore = TRUE;
+ InitializeDebugTimer (NULL, FALSE);
+ }
+
+ Mailbox = GetMailboxPointer ();
+ if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {
+ //
+ // If Debug Agent has been communication state with HOST, we need skip
+ // any break points set in SMM, set Skip Breakpoint flag
+ //
+ mSkipBreakpoint = TRUE;
+ }
+
+ if (GetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI) == 1) {
+ if (mSkipBreakpoint) {
+ //
+ // Print warning message if ignore smm entry break
+ //
+ DebugPortWriteBuffer (
+ (DEBUG_PORT_HANDLE)(UINTN)Mailbox->DebugPortHandle,
+ (UINT8 *)mWarningMsgIgnoreSmmEntryBreak,
+ AsciiStrLen (mWarningMsgIgnoreSmmEntryBreak)
+ );
+ } else {
+ //
+ // If SMM entry break is set, SMM code will be break at here.
+ //
+ CpuBreakpoint ();
+ }
+ }
+
+ break;
+
+ case DEBUG_AGENT_INIT_EXIT_SMI:
+ Mailbox = GetMailboxPointer ();
+ //
+ // Clear Skip Breakpoint flag
+ //
+ mSkipBreakpoint = FALSE;
+ RestoreDebugRegister ();
+ //
+ // Restore APIC Timer
+ //
+ if (mApicTimerRestore) {
+ InitializeApicTimer (mApicTimerDivisor, mTimerCycle, mPeriodicMode, mVector);
+ mApicTimerRestore = FALSE;
+ }
+
+ break;
+
+ case DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64:
+ if (Context == NULL) {
+ DEBUG ((DEBUG_ERROR, "DebugAgent: Input parameter Context cannot be NULL!\n"));
+ CpuDeadLoop ();
+ } else {
+ Ia32Idtr = (IA32_DESCRIPTOR *)Context;
+ Ia32IdtEntry = (IA32_IDT_ENTRY *)(Ia32Idtr->Base);
+ MailboxLocation = (UINT64 *)((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +
+ ((UINTN)Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));
+ mMailboxPointer = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocation);
+ VerifyMailboxChecksum (mMailboxPointer);
+ //
+ // 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;
+ ZeroMem (&mIdtEntryTable, Idtr.Limit + 1);
+ AsmWriteIdtr ((IA32_DESCRIPTOR *)&Idtr);
+ }
+
+ InitializeDebugIdt ();
+ //
+ // Initialize Debug Timer hardware and save its frequency
+ //
+ InitializeDebugTimer (&DebugTimerFrequency, TRUE);
+ UpdateMailboxContent (mMailboxPointer, DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY, DebugTimerFrequency);
+ //
+ // Enable Debug Timer interrupt and CPU interrupt
+ //
+ SaveAndSetDebugTimerInterrupt (TRUE);
+ EnableInterrupts ();
+
+ FindAndReportModuleImageInfo (SIZE_4KB);
+ }
+
+ break;
+
+ default:
+ //
+ // Only DEBUG_AGENT_INIT_PREMEM_SEC and DEBUG_AGENT_INIT_POSTMEM_SEC are allowed for this
+ // Debug Agent library instance.
+ //
+ DEBUG ((DEBUG_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));
+ CpuDeadLoop ();
+ break;
+ }
+}