+ //\r
+ // Find Image Base\r
+ //\r
+ Pe32Data = PeCoffSearchImageBase ((UINTN) mErrorMsgVersionAlert);\r
+ if (Pe32Data != 0) {\r
+ ImageContext.ImageAddress = Pe32Data;\r
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);\r
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);\r
+ }\r
+}\r
+\r
+/**\r
+ Trigger one software interrupt to debug agent to handle it.\r
+\r
+ @param[in] Signature Software interrupt signature.\r
+\r
+**/\r
+VOID\r
+TriggerSoftInterrupt (\r
+ IN UINT32 Signature\r
+ )\r
+{\r
+ UINTN Dr0;\r
+ UINTN Dr1;\r
+\r
+ //\r
+ // Save Debug Register State\r
+ //\r
+ Dr0 = AsmReadDr0 ();\r
+ Dr1 = AsmReadDr1 ();\r
+\r
+ //\r
+ // DR0 = Signature\r
+ //\r
+ AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE);\r
+ AsmWriteDr1 (Signature);\r
+\r
+ //\r
+ // Do INT3 to communicate with HOST side\r
+ //\r
+ CpuBreakpoint ();\r
+\r
+ //\r
+ // Restore Debug Register State only when Host didn't change it inside exception handler.\r
+ // Dr registers can only be changed by setting the HW breakpoint.\r
+ //\r
+ AsmWriteDr0 (Dr0);\r
+ AsmWriteDr1 (Dr1);\r
+\r
+}\r
+\r
+/**\r
+ Calculate Mailbox checksum and update the checksum field.\r
+\r
+ @param[in] Mailbox Debug Agent Mailbox pointer.\r
+\r
+**/\r
+VOID\r
+UpdateMailboxChecksum (\r
+ IN DEBUG_AGENT_MAILBOX *Mailbox\r
+ )\r
+{\r
+ Mailbox->CheckSum = CalculateCheckSum8 ((UINT8 *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2);\r
+}\r
+\r
+/**\r
+ Verify Mailbox checksum.\r
+\r
+ If checksum error, print debug message and run init dead loop.\r
+\r
+ @param[in] Mailbox Debug Agent Mailbox pointer.\r
+\r
+**/\r
+VOID\r
+VerifyMailboxChecksum (\r
+ IN DEBUG_AGENT_MAILBOX *Mailbox\r
+ )\r
+{\r
+ UINT8 CheckSum;\r
+\r
+ CheckSum = CalculateCheckSum8 ((UINT8 *) Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2);\r
+ //\r
+ // The checksum updating process may be disturbed by hardware SMI, we need to check CheckSum field\r
+ // and ToBeCheckSum field to validate the mail box.\r
+ //\r
+ if (CheckSum != Mailbox->CheckSum && CheckSum != Mailbox->ToBeCheckSum) {\r
+ DEBUG ((EFI_D_ERROR, "DebugAgent: Mailbox checksum error, stack or heap crashed!\n"));\r
+ DEBUG ((EFI_D_ERROR, "DebugAgent: CheckSum = %x, Mailbox->CheckSum = %x, Mailbox->ToBeCheckSum = %x\n", CheckSum, Mailbox->CheckSum, Mailbox->ToBeCheckSum));\r
+ CpuDeadLoop ();\r
+ }\r
+}\r
+\r
+/**\r
+ Update Mailbox content by index.\r
+\r
+ @param[in] Mailbox Debug Agent Mailbox pointer.\r
+ @param[in] Index Mailbox content index.\r
+ @param[in] Value Value to be set into Mailbox.\r
+\r
+**/\r
+VOID\r
+UpdateMailboxContent (\r
+ IN DEBUG_AGENT_MAILBOX *Mailbox,\r
+ IN UINTN Index,\r
+ IN UINT64 Value\r
+ )\r
+{\r
+ AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock);\r
+ switch (Index) {\r
+ case DEBUG_MAILBOX_DEBUG_FLAG_INDEX:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugFlag.Uint64, sizeof(UINT64))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT64));\r
+ Mailbox->DebugFlag.Uint64 = Value;\r
+ break;\r
+ case DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugPortHandle, sizeof(UINTN))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINTN));\r
+ Mailbox->DebugPortHandle = (UINTN) Value;\r
+ break;\r
+ case DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->ExceptionBufferPointer, sizeof(UINTN))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINTN));\r
+ Mailbox->ExceptionBufferPointer = (UINTN) Value;\r
+ break;\r
+ case DEBUG_MAILBOX_LAST_ACK:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->LastAck, sizeof(UINT8))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8));\r
+ Mailbox->LastAck = (UINT8) Value;\r
+ break;\r
+ case DEBUG_MAILBOX_SEQUENCE_NO_INDEX:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->SequenceNo, sizeof(UINT8))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8));\r
+ Mailbox->SequenceNo = (UINT8) Value;\r
+ break;\r
+ case DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->HostSequenceNo, sizeof(UINT8))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8));\r
+ Mailbox->HostSequenceNo = (UINT8) Value;\r
+ break;\r
+ case DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugTimerFrequency, sizeof(UINT32))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT32));\r
+ Mailbox->DebugTimerFrequency = (UINT32) Value;\r
+ break;\r
+ }\r
+ UpdateMailboxChecksum (Mailbox);\r
+ ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);\r
+}\r