diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h index 5eb50d038c..748d562a59 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h +++ b/SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/DebugAgent.h @@ -89,6 +89,7 @@ typedef struct { #define DEBUG_AGENT_FLAG_MEMORY_READY BIT2 #define DEBUG_AGENT_FLAG_STEPPING BIT3 #define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB BIT4 +#define DEBUG_AGENT_FLAG_INIT_ARCH BIT5|BIT6 #define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI BIT32 #define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL (BIT33|BIT34|BIT35|BIT36) #define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT BIT37 @@ -111,8 +112,8 @@ typedef union { UINT32 MemoryReady : 1; // 1: Memory is ready UINT32 SteppingFlag : 1; // 1: Agent is running stepping command UINT32 CheckMailboxInHob : 1; // 1: Need to check mailbox saved in HOB - UINT32 SendingPacket : 1; // 1: TARGET is sending debug packet to HOST - UINT32 Reserved1 : 26; + UINT32 InitArch : 2; // value of DEBUG_DATA_RESPONSE_ARCH_MODE + UINT32 Reserved1 : 25; // // Higher 32bits to control the behavior of DebugAgent // diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c index 35c6acfd9d..d560b52359 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgent/DxeDebugAgentLib.c @@ -55,6 +55,8 @@ InternalConstructorWorker ( EFI_STATUS Status; EFI_PHYSICAL_ADDRESS Address; BOOLEAN DebugTimerInterruptState; + DEBUG_AGENT_MAILBOX *Mailbox; + DEBUG_AGENT_MAILBOX *NewMailbox; // // Install EFI Serial IO protocol on debug port @@ -65,20 +67,28 @@ InternalConstructorWorker ( Status = gBS->AllocatePages ( AllocateAnyPages, EfiACPIMemoryNVS, - EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)), + EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)), &Address ); ASSERT_EFI_ERROR (Status); DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE); - CopyMem ( - (UINT8 *) (UINTN) Address, - (UINT8 *) (UINTN) GetMailboxPointer (), - sizeof (DEBUG_AGENT_MAILBOX) - ); - DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState); - mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; + NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; + // + // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox + // and Debug Port Handle buffer may be free at runtime, SMM debug agent needs to access them + // + Mailbox = GetMailboxPointer (); + CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX)); + CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize)); + // + // Update Debug Port Handle in new Mailbox + // + UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1)); + mMailboxPointer = NewMailbox; + + DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState); Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer); ASSERT_EFI_ERROR (Status); diff --git a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf index f73385ce71..cc9b48191d 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf +++ b/SourceLevelDebugPkg/Library/DebugAgent/DxeDebugAgentLib.inf @@ -90,4 +90,5 @@ [Pcd] gEfiMdePkgTokenSpaceGuid.PcdFSBClock ## CONSUMES gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdExceptionsIgnoredByDebugger ## CONSUMES + gEfiSourceLevelDebugPkgTokenSpaceGuid.PcdDebugPortHandleBufferSize ## CONSUMES diff --git a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c index 828407304f..0132942dea 100644 --- a/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c +++ b/SourceLevelDebugPkg/Library/DebugAgent/SecPeiDebugAgent/SecPeiDebugAgentLib.c @@ -174,19 +174,22 @@ GetMailboxPointer ( MailboxLocationInIdt = GetLocationSavedMailboxPointerInIdtEntry (); Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInIdt); // - // Check if mailbox was setup in PEI firstly, cannot used GetDebugFlag() to - // get CheckMailboxInHob flag to avoid GetMailboxPointer() nesting. + // Cannot used GetDebugFlag() to get Debug Flag to avoid GetMailboxPointer() nested // - if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1) { - // - // If mailbox in IDT entry has already been the final one + if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1 || + Mailbox->DebugFlag.Bits.InitArch != DEBUG_ARCH_SYMBOL) { // + // If mailbox was setup in SEC or the current CPU arch is different from the init arch + // Debug Agent initialized, return the mailbox from IDT entry directly. + // Otherwise, we need to check the mailbox location saved in GUIDed HOB further. + // return Mailbox; } MailboxLocationInHob = GetMailboxLocationFromHob (); // - // Compare mailbox in IDT enry with mailbox in HOB + // Compare mailbox in IDT enry with mailbox in HOB, + // need to fix mailbox location if HOB moved by PEI CORE // if (MailboxLocationInHob != MailboxLocationInIdt && MailboxLocationInHob != NULL) { Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob); @@ -247,7 +250,7 @@ DebugAgentCallbackMemoryDiscoveredPpi ( EFI_STATUS Status; DEBUG_AGENT_MAILBOX *Mailbox; BOOLEAN InterruptStatus; - EFI_PHYSICAL_ADDRESS Memory; + EFI_PHYSICAL_ADDRESS Address; DEBUG_AGENT_MAILBOX *NewMailbox; UINT64 *MailboxLocationInHob; @@ -262,10 +265,10 @@ DebugAgentCallbackMemoryDiscoveredPpi ( Status = PeiServicesAllocatePages ( EfiACPIMemoryNVS, EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)), - &Memory + &Address ); ASSERT_EFI_ERROR (Status); - NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Memory; + NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address; // // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox // and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core @@ -369,7 +372,14 @@ InitializeDebugAgent ( // Get and save debug port handle and set the length of memory block. // SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation); + // + // Force error message could be printed during the first shakehand between Target/HOST. + // SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR); + // + // Save init arch type when debug agent initialized + // + SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, sizeof (UINTN) / 4); InitializeDebugTimer (); @@ -453,6 +463,10 @@ InitializeDebugAgent ( // SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer); // + // Save init arch type when debug agent initialized + // + SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL); + // // Register for a callback once memory has been initialized. // If memery has been ready, the callback funtion will be invoked immediately // @@ -483,6 +497,9 @@ InitializeDebugAgent ( MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow + (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16)); Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer); + // + // Mailbox should valid and setup before executing thunk code + // VerifyMailboxChecksum (Mailbox); DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL); @@ -508,7 +525,6 @@ InitializeDebugAgent ( DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n")); CpuDeadLoop (); break; - } EnableInterrupts ();