#define DEBUG_AGENT_FLAG_MEMORY_READY BIT2\r
#define DEBUG_AGENT_FLAG_STEPPING BIT3\r
#define DEBUG_AGENT_FLAG_CHECK_MAILBOX_IN_HOB BIT4\r
+#define DEBUG_AGENT_FLAG_INIT_ARCH BIT5|BIT6\r
#define DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI BIT32\r
#define DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL (BIT33|BIT34|BIT35|BIT36)\r
#define DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT BIT37\r
UINT32 MemoryReady : 1; // 1: Memory is ready\r
UINT32 SteppingFlag : 1; // 1: Agent is running stepping command\r
UINT32 CheckMailboxInHob : 1; // 1: Need to check mailbox saved in HOB\r
- UINT32 SendingPacket : 1; // 1: TARGET is sending debug packet to HOST\r
- UINT32 Reserved1 : 26;\r
+ UINT32 InitArch : 2; // value of DEBUG_DATA_RESPONSE_ARCH_MODE\r
+ UINT32 Reserved1 : 25;\r
//\r
// Higher 32bits to control the behavior of DebugAgent\r
//\r
EFI_STATUS Status;\r
EFI_PHYSICAL_ADDRESS Address;\r
BOOLEAN DebugTimerInterruptState;\r
+ DEBUG_AGENT_MAILBOX *Mailbox;\r
+ DEBUG_AGENT_MAILBOX *NewMailbox;\r
\r
//\r
// Install EFI Serial IO protocol on debug port\r
Status = gBS->AllocatePages (\r
AllocateAnyPages,\r
EfiACPIMemoryNVS,\r
- EFI_SIZE_TO_PAGES (sizeof (DEBUG_AGENT_MAILBOX)),\r
+ EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),\r
&Address\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (FALSE);\r
- CopyMem (\r
- (UINT8 *) (UINTN) Address,\r
- (UINT8 *) (UINTN) GetMailboxPointer (),\r
- sizeof (DEBUG_AGENT_MAILBOX)\r
- );\r
- DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);\r
\r
- mMailboxPointer = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;\r
+ NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;\r
+ //\r
+ // Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox\r
+ // and Debug Port Handle buffer may be free at runtime, SMM debug agent needs to access them\r
+ //\r
+ Mailbox = GetMailboxPointer ();\r
+ CopyMem (NewMailbox, Mailbox, sizeof (DEBUG_AGENT_MAILBOX));\r
+ CopyMem (NewMailbox + 1, (VOID *)(UINTN)Mailbox->DebugPortHandle, PcdGet16(PcdDebugPortHandleBufferSize));\r
+ //\r
+ // Update Debug Port Handle in new Mailbox\r
+ //\r
+ UpdateMailboxContent (NewMailbox, DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX, (UINT64)(UINTN)(NewMailbox + 1));\r
+ mMailboxPointer = NewMailbox;\r
+\r
+ DebugTimerInterruptState = SaveAndSetDebugTimerInterrupt (DebugTimerInterruptState);\r
\r
Status = gBS->InstallConfigurationTable (&gEfiDebugAgentGuid, (VOID *) mMailboxPointer);\r
ASSERT_EFI_ERROR (Status);\r
MailboxLocationInIdt = GetLocationSavedMailboxPointerInIdtEntry ();\r
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInIdt);\r
//\r
- // Check if mailbox was setup in PEI firstly, cannot used GetDebugFlag() to \r
- // get CheckMailboxInHob flag to avoid GetMailboxPointer() nesting.\r
+ // Cannot used GetDebugFlag() to get Debug Flag to avoid GetMailboxPointer() nested\r
//\r
- if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1) {\r
- //\r
- // If mailbox in IDT entry has already been the final one\r
+ if (Mailbox->DebugFlag.Bits.CheckMailboxInHob != 1 ||\r
+ Mailbox->DebugFlag.Bits.InitArch != DEBUG_ARCH_SYMBOL) {\r
//\r
+ // If mailbox was setup in SEC or the current CPU arch is different from the init arch\r
+ // Debug Agent initialized, return the mailbox from IDT entry directly.\r
+ // Otherwise, we need to check the mailbox location saved in GUIDed HOB further.\r
+ // \r
return Mailbox;\r
}\r
\r
MailboxLocationInHob = GetMailboxLocationFromHob ();\r
//\r
- // Compare mailbox in IDT enry with mailbox in HOB\r
+ // Compare mailbox in IDT enry with mailbox in HOB,\r
+ // need to fix mailbox location if HOB moved by PEI CORE\r
//\r
if (MailboxLocationInHob != MailboxLocationInIdt && MailboxLocationInHob != NULL) {\r
Mailbox = (DEBUG_AGENT_MAILBOX *)(UINTN)(*MailboxLocationInHob);\r
EFI_STATUS Status;\r
DEBUG_AGENT_MAILBOX *Mailbox;\r
BOOLEAN InterruptStatus;\r
- EFI_PHYSICAL_ADDRESS Memory; \r
+ EFI_PHYSICAL_ADDRESS Address; \r
DEBUG_AGENT_MAILBOX *NewMailbox;\r
UINT64 *MailboxLocationInHob;\r
\r
Status = PeiServicesAllocatePages (\r
EfiACPIMemoryNVS,\r
EFI_SIZE_TO_PAGES (sizeof(DEBUG_AGENT_MAILBOX) + PcdGet16(PcdDebugPortHandleBufferSize)),\r
- &Memory\r
+ &Address\r
);\r
ASSERT_EFI_ERROR (Status);\r
- NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Memory;\r
+ NewMailbox = (DEBUG_AGENT_MAILBOX *) (UINTN) Address;\r
//\r
// Copy Mailbox and Debug Port Handle buffer to new location in ACPI NVS memory, because original Mailbox\r
// and Debug Port Handle buffer in the allocated pool that may be marked as free by DXE Core after DXE Core\r
// Get and save debug port handle and set the length of memory block.\r
//\r
SetLocationSavedMailboxPointerInIdtEntry (&MailboxLocation);\r
+ //\r
+ // Force error message could be printed during the first shakehand between Target/HOST.\r
+ //\r
SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DEBUG_AGENT_ERROR);\r
+ //\r
+ // Save init arch type when debug agent initialized\r
+ //\r
+ SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, sizeof (UINTN) / 4);\r
\r
InitializeDebugTimer ();\r
\r
//\r
SetLocationSavedMailboxPointerInIdtEntry (MailboxLocationPointer);\r
//\r
+ // Save init arch type when debug agent initialized\r
+ //\r
+ SetDebugFlag (DEBUG_AGENT_FLAG_INIT_ARCH, DEBUG_ARCH_SYMBOL);\r
+ //\r
// Register for a callback once memory has been initialized.\r
// If memery has been ready, the callback funtion will be invoked immediately\r
//\r
MailboxLocationPointer = (UINT64 *) (UINTN) (Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetLow +\r
(Ia32IdtEntry[DEBUG_MAILBOX_VECTOR].Bits.OffsetHigh << 16));\r
Mailbox = (DEBUG_AGENT_MAILBOX *) (UINTN)(*MailboxLocationPointer);\r
+ //\r
+ // Mailbox should valid and setup before executing thunk code\r
+ //\r
VerifyMailboxChecksum (Mailbox);\r
\r
DebugPortHandle = (UINT64) (UINTN)DebugPortInitialize ((VOID *)(UINTN)Mailbox->DebugPortHandle, NULL);\r
DEBUG ((EFI_D_ERROR, "Debug Agent: The InitFlag value is not allowed!\n"));\r
CpuDeadLoop ();\r
break;\r
-\r
}\r
\r
EnableInterrupts ();\r