#include "DebugAgent.h"\r
#include "Ia32/DebugException.h"\r
\r
+#define INIT_BREAK_ACK_TIMEOUT (200 * 1000)\r
+\r
+CHAR8 mErrorMsgVersionAlert[] = "\rThe SourceLevelDebugPkg you are using requires a newer version of the Intel(R) UDK Debugger Tool.\r\n";\r
+CHAR8 mErrorMsgSendInitPacket[] = "\rSend INIT break packet to HOST ...\r\n";\r
+CHAR8 mErrorMsgConnectOK[] = "HOST connection is successful!\r\n";\r
+CHAR8 mErrorMsgConnectFail[] = "HOST connection is failed!\r\n";\r
+\r
/**\r
- Check if HOST is connected based on Mailbox.\r
+ Send a debug message packet to the debug port.\r
\r
- @retval TRUE HOST is connected.\r
- @retval FALSE HOST is not connected.\r
+ @param[in] Buffer The debug message.\r
+ @param[in] Length The length of debug message.\r
\r
**/\r
-BOOLEAN\r
-IsHostConnected (\r
- VOID\r
+VOID\r
+SendDebugMsgPacket (\r
+ IN CHAR8 *Buffer,\r
+ IN UINTN Length \r
)\r
{\r
- DEBUG_AGENT_MAILBOX *Mailbox;\r
+ DEBUG_PACKET_HEADER DebugHeader;\r
+ DEBUG_PORT_HANDLE Handle;\r
+ \r
+ Handle = GetDebugPortHandle();\r
\r
- Mailbox = GetMailboxPointer ();\r
+ DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
+ DebugHeader.Command = DEBUG_COMMAND_PRINT_MESSAGE;\r
+ DebugHeader.Length = sizeof (DEBUG_PACKET_HEADER) + (UINT8) Length;\r
+ DebugHeader.CheckSum = 0;\r
+ DebugHeader.CheckSum = CalculateCheckSum8 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER));\r
\r
- if (Mailbox->DebugFlag.Bits.HostPresent == 1) {\r
- return TRUE;\r
- } else {\r
- return FALSE;\r
+ DebugPortWriteBuffer (Handle, (UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER));\r
+ DebugPortWriteBuffer (Handle, (UINT8 *)Buffer, Length);\r
+}\r
+\r
+/**\r
+ Prints a debug message to the debug port if the specified error level is enabled.\r
+\r
+ If any bit in ErrorLevel is also set in Mainbox, then print the message specified\r
+ by Format and the associated variable argument list to the debug port.\r
+\r
+ @param[in] ErrorLevel The error level of the debug message.\r
+ @param[in] Format Format string for the debug message to print.\r
+ @param[in] ... Variable argument list whose contents are accessed \r
+ based on the format string specified by Format.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugAgentMsgPrint (\r
+ IN UINT8 ErrorLevel,\r
+ IN CHAR8 *Format,\r
+ ...\r
+ )\r
+{\r
+ DEBUG_AGENT_MAILBOX *Mailbox;\r
+ CHAR8 Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA];\r
+ VA_LIST Marker;\r
+\r
+ Mailbox = GetMailboxPointer ();\r
+ //\r
+ // Check driver debug mask value and global mask\r
+ //\r
+ if ((ErrorLevel & Mailbox->DebugFlag.PrintErrorLevel) == 0) {\r
+ return;\r
}\r
+\r
+ //\r
+ // Convert the DEBUG() message to an ASCII String\r
+ //\r
+ VA_START (Marker, Format);\r
+ AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
+ VA_END (Marker);\r
+\r
+ SendDebugMsgPacket (Buffer, AsciiStrLen (Buffer));\r
}\r
\r
/**\r
- Set HOST connect flag in Mailbox.\r
+ Prints a debug message to the debug output device if the specified error level is enabled.\r
+\r
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function \r
+ GetDebugPrintErrorLevel (), then print the message specified by Format and the \r
+ associated variable argument list to the debug output device.\r
+\r
+ If Format is NULL, then ASSERT().\r
+\r
+ @param[in] ErrorLevel The error level of the debug message.\r
+ @param[in] IsSend Flag of debug message to declare that the data is being sent or being received.\r
+ @param[in] Data Variable argument list whose contents are accessed \r
+ @param[in] Length based on the format string specified by Format.\r
\r
**/\r
VOID\r
-SetHostConnectedFlag (\r
- VOID\r
+EFIAPI\r
+DebugAgentDataMsgPrint (\r
+ IN UINT8 ErrorLevel,\r
+ IN BOOLEAN IsSend,\r
+ IN UINT8 *Data,\r
+ IN UINT8 Length \r
)\r
{\r
- DEBUG_AGENT_MAILBOX *Mailbox;\r
+ DEBUG_AGENT_MAILBOX *Mailbox;\r
+ CHAR8 Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA];\r
+ CHAR8 *DestBuffer;\r
+ UINTN Index;\r
\r
Mailbox = GetMailboxPointer ();\r
+ //\r
+ // Check driver debug mask value and global mask\r
+ //\r
+ if ((ErrorLevel & Mailbox->DebugFlag.PrintErrorLevel) == 0) {\r
+ return;\r
+ }\r
+\r
+ DestBuffer = Buffer;\r
+ if (IsSend) {\r
+ DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Sent data [ ");\r
+ } else {\r
+ DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Received data [ ");\r
+ }\r
\r
- Mailbox->DebugFlag.Bits.HostPresent = 1;\r
+ Index = 0;\r
+ while (TRUE) {\r
+ if (DestBuffer - Buffer > DEBUG_DATA_MAXIMUM_REAL_DATA - 6) {\r
+ //\r
+ // If there was no enough space in buffer, send out the debug message, \r
+ // reserving 6 bytes is for the last data and end characters "]\n".\r
+ //\r
+ SendDebugMsgPacket (Buffer, DestBuffer - Buffer);\r
+ DestBuffer = Buffer;\r
+ }\r
+ DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "%02x ", Data[Index]);\r
+ Index ++;\r
+ if (Index >= Length) {\r
+ //s\r
+ // The last character of debug message has been foramtted in buffer\r
+ //\r
+ DestBuffer += AsciiSPrint(DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "]\n");\r
+ SendDebugMsgPacket (Buffer, DestBuffer - Buffer);\r
+ break;\r
+ }\r
+ }\r
}\r
\r
+\r
/**\r
- Set debug flag of Debug Agent in Mailbox.\r
+ Check if HOST is attached based on Mailbox.\r
\r
- @param DebugFlag Debug Flag defined by transfer protocol.\r
+ @retval TRUE HOST is attached.\r
+ @retval FALSE HOST is not attached.\r
\r
+**/\r
+BOOLEAN\r
+IsHostAttached (\r
+ VOID\r
+ )\r
+{\r
+ return (BOOLEAN) (GetMailboxPointer ()->DebugFlag.HostAttached == 1);\r
+}\r
+\r
+/**\r
+ Set HOST connect flag in Mailbox.\r
+\r
+ @param[in] Attached Attach status.\r
+ \r
**/\r
VOID\r
-SetDebugFlag (\r
- IN UINT32 DebugFlag\r
+SetHostAttached (\r
+ IN BOOLEAN Attached\r
)\r
{\r
+ DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Attach status is %d\n", Attached);\r
+ GetMailboxPointer ()->DebugFlag.HostAttached = Attached;\r
+}\r
+\r
+/**\r
+ Set debug setting of Debug Agent in Mailbox.\r
+\r
+ @param DebugSetting Pointer to Debug Setting defined by transfer protocol.\r
+ \r
+ @retval RETURN_SUCCESS The setting is set successfully.\r
+ @retval RETURN_UNSUPPORTED The Key value is not supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+SetDebugSetting (\r
+ IN DEBUG_DATA_SET_DEBUG_SETTING *DebugSetting \r
+ )\r
+{\r
+ RETURN_STATUS Status;\r
DEBUG_AGENT_MAILBOX *Mailbox;\r
\r
Mailbox = GetMailboxPointer ();\r
\r
- if ((DebugFlag & SOFT_DEBUGGER_SETTING_SMM_ENTRY_BREAK) != 0) {\r
- Mailbox->DebugFlag.Bits.BreakOnNextSmi = 1;\r
- } else {\r
- Mailbox->DebugFlag.Bits.BreakOnNextSmi = 0;\r
+ Status = RETURN_SUCCESS;\r
+ switch (DebugSetting->Key) {\r
+ case DEBUG_AGENT_SETTING_SMM_ENTRY_BREAK:\r
+ Mailbox->DebugFlag.BreakOnNextSmi = DebugSetting->Value;\r
+ break;\r
+ case DEBUG_AGENT_SETTING_PRINT_ERROR_LEVEL:\r
+ Mailbox->DebugFlag.PrintErrorLevel = DebugSetting->Value;\r
+ break;\r
+ default:\r
+ Status = RETURN_UNSUPPORTED;\r
}\r
+ return Status;\r
}\r
\r
/**\r
//\r
// Set RWx and Lenx\r
//\r
- Dr7Value &= ~(0xf0000 << (RegisterIndex * 4));\r
- Dr7Value |= (SetHwBreakpoint->Type.Length | SetHwBreakpoint->Type.Access) << (RegisterIndex * 4);\r
+ Dr7Value &= ~(0xf << (16 + RegisterIndex * 4));\r
+ Dr7Value |= (UINTN) ((SetHwBreakpoint->Type.Length << 2) | SetHwBreakpoint->Type.Access) << (16 + RegisterIndex * 4);\r
//\r
// Enable GE, LE\r
//\r
}\r
}\r
\r
+\r
/**\r
- Send acknowledge packet to HOST.\r
+ Return the offset of FP / MMX / XMM registers in the FPU saved state by register index.\r
\r
- @param[in] AckCommand Type of Acknowledge packet.\r
+ @param[in] Index Register index.\r
+ @param[out] Width Register width returned.\r
+\r
+ @return Offset in the FPU Save State.\r
+\r
+**/\r
+UINT16\r
+ArchReadFxStatOffset (\r
+ IN UINT8 Index,\r
+ OUT UINT8 *Width\r
+ )\r
+{\r
+ if (Index < SOFT_DEBUGGER_REGISTER_ST0) {\r
+ switch (Index) {\r
+ case SOFT_DEBUGGER_REGISTER_FP_FCW:\r
+ *Width = (UINT8) sizeof (UINT16);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Fcw);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_FSW:\r
+ *Width = (UINT8) sizeof (UINT16);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Fsw);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_FTW:\r
+ *Width = (UINT8) sizeof (UINT16);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Ftw);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_OPCODE:\r
+ *Width = (UINT8) sizeof (UINT16);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Opcode);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_EIP:\r
+ *Width = (UINT8) sizeof (UINT32);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Eip);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_CS:\r
+ *Width = (UINT8) sizeof (UINT16);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Cs);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:\r
+ *Width = (UINT8) sizeof (UINT32);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, DataOffset);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_DS:\r
+ *Width = (UINT8) sizeof (UINT16);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Ds);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_MXCSR:\r
+ *Width = (UINT8) sizeof (UINT32);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Mxcsr);\r
+\r
+ case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:\r
+ *Width = (UINT8) sizeof (UINT32);\r
+ return OFFSET_OF(DEBUG_DATA_FX_SAVE_STATE, Mxcsr_Mask);\r
+ }\r
+ }\r
+\r
+ if (Index <= SOFT_DEBUGGER_REGISTER_ST7) {\r
+ *Width = 10;\r
+ } else if (Index <= SOFT_DEBUGGER_REGISTER_XMM15) {\r
+ *Width = 16;\r
+ } else {\r
+ //\r
+ // MMX register\r
+ //\r
+ *Width = 8;\r
+ Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;\r
+ }\r
+\r
+ return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16;\r
+}\r
+\r
+/**\r
+ Return the pointer of the register value in the CPU saved context.\r
+\r
+ @param[in] CpuContext Pointer to saved CPU context.\r
+ @param[in] Index Register index value.\r
+ @param[out] Width Data width to read.\r
+\r
+ @return The pointer in the CPU saved context.\r
+\r
+**/\r
+UINT8 *\r
+ArchReadRegisterBuffer (\r
+ IN DEBUG_CPU_CONTEXT *CpuContext,\r
+ IN UINT8 Index,\r
+ OUT UINT8 *Width\r
+ )\r
+{\r
+ UINT8 *Buffer;\r
+\r
+ if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {\r
+ Buffer = (UINT8 *) CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, Dr0) + Index * sizeof (UINTN);\r
+ *Width = (UINT8) sizeof (UINTN);\r
+ } else {\r
+ //\r
+ // FPU/MMX/XMM registers\r
+ //\r
+ Buffer = (UINT8 *) CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, FxSaveState) + ArchReadFxStatOffset (Index, Width);\r
+ }\r
+\r
+ return Buffer;\r
+}\r
+\r
+/**\r
+ Send the packet without data to HOST.\r
+\r
+ @param[in] CommandType Type of Command.\r
\r
**/\r
VOID\r
-SendAckPacket (\r
- IN UINT8 AckCommand\r
+SendPacketWithoutData (\r
+ IN UINT8 CommandType\r
)\r
{\r
- DEBUG_COMMAND_HEADER DebugCommonHeader;\r
+ DEBUG_PACKET_HEADER DebugHeader;\r
DEBUG_PORT_HANDLE Handle;\r
\r
Handle = GetDebugPortHandle();\r
\r
- DebugCommonHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
- DebugCommonHeader.Command = AckCommand;\r
- DebugCommonHeader.DataLength = 0;\r
+ DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
+ DebugHeader.Command = CommandType;\r
+ DebugHeader.Length = sizeof (DEBUG_PACKET_HEADER);\r
+ DebugHeader.CheckSum = 0;\r
+ DebugHeader.CheckSum = CalculateCheckSum8 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER));\r
\r
- DebugPortWriteBuffer (Handle, (UINT8 *) &DebugCommonHeader, sizeof (DEBUG_COMMAND_HEADER));\r
+ DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *) &DebugHeader, DebugHeader.Length);\r
+ DebugPortWriteBuffer (Handle, (UINT8 *) &DebugHeader, DebugHeader.Length);\r
+}\r
+\r
+/**\r
+ Send acknowledge packet to HOST.\r
+\r
+ @param[in] AckCommand Type of Acknowledge packet.\r
+\r
+**/\r
+VOID\r
+SendAckPacket (\r
+ IN UINT8 AckCommand\r
+ )\r
+{\r
+ if (AckCommand != DEBUG_COMMAND_OK) {\r
+ DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Send ACK(%d)\n", AckCommand);\r
+ }\r
+ SendPacketWithoutData (AckCommand);\r
}\r
\r
/**\r
Receive acknowledge packet from HOST in specified time.\r
\r
- @param[out] Ack Returned acknowlege type from HOST.\r
- @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
- The unit is microsecond.\r
- @param[out] BreakReceived If BreakReceived is not NULL,\r
- TRUE is retured if break-in symbol received.\r
- FALSE is retured if break-in symbol not received.\r
+ @param[out] Ack Returned acknowlege type from HOST.\r
+ @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
+ The unit is microsecond.\r
+ @param[out] BreakReceived If BreakReceived is not NULL,\r
+ TRUE is retured if break-in symbol received.\r
+ FALSE is retured if break-in symbol not received.\r
+ @param[out] CheckSumStatus If CheckSumStatus is not NULL,\r
+ RETURN_SUCCESS CheckSum is OK.\r
+ RETURN_NOT_FOUND Not find the CheckSum field.\r
\r
@retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST,\r
the type of acknowlege packet saved in Ack.\r
ReceiveAckPacket (\r
OUT UINT8 *Ack,\r
IN UINTN Timeout,\r
- OUT BOOLEAN *BreakReceived OPTIONAL\r
+ OUT BOOLEAN *BreakReceived, OPTIONAL\r
+ OUT RETURN_STATUS *CheckSumStatus OPTIONAL\r
)\r
{\r
- DEBUG_COMMAND_HEADER DebugCommonHeader;\r
+ DEBUG_PACKET_HEADER DebugHeader;\r
DEBUG_PORT_HANDLE Handle;\r
\r
Handle = GetDebugPortHandle();\r
\r
while (TRUE) {\r
- if (DebugPortReadBuffer (Handle, (UINT8 *) &DebugCommonHeader.StartSymbol, 1, Timeout) == 0) {\r
+ if (DebugPortReadBuffer (Handle, (UINT8 *) &DebugHeader.StartSymbol, sizeof (DebugHeader.StartSymbol), Timeout) == 0) {\r
return RETURN_TIMEOUT;\r
}\r
- if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_BREAK) {\r
+ if (DebugHeader.StartSymbol == DEBUG_STARTING_SYMBOL_BREAK) {\r
if (BreakReceived != NULL) {\r
SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
*BreakReceived = TRUE;\r
}\r
}\r
- if (DebugCommonHeader.StartSymbol == DEBUG_STARTING_SYMBOL_NORMAL) {\r
+ if (DebugHeader.StartSymbol == DEBUG_STARTING_SYMBOL_NORMAL) {\r
break;\r
}\r
+ DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Invalid start symbol received [%02x]\n", DebugHeader.StartSymbol);\r
}\r
- if (DebugPortReadBuffer (Handle, (UINT8 *)&DebugCommonHeader.Command, sizeof (DEBUG_COMMAND_HEADER) - 1, Timeout) == 0) {\r
+ //\r
+ // Read ACK packet header till field Length (not including StartSymbol and CheckSum)\r
+ //\r
+ DebugHeader.Length = 0;\r
+ if (DebugPortReadBuffer (\r
+ Handle,\r
+ (UINT8 *)&DebugHeader.Command,\r
+ OFFSET_OF (DEBUG_PACKET_HEADER, Length) + sizeof (DebugHeader.Length) - sizeof (DebugHeader.StartSymbol),\r
+ Timeout\r
+ ) == 0) {\r
return RETURN_TIMEOUT;\r
}\r
\r
- *Ack = DebugCommonHeader.Command;\r
+ if (DebugHeader.Length == 0) {\r
+ //\r
+ // The CheckSum field does not exist\r
+ //\r
+ if (CheckSumStatus != NULL) {\r
+ *CheckSumStatus = RETURN_NOT_FOUND;\r
+ }\r
+ } else {\r
+ if (CheckSumStatus != NULL) {\r
+ *CheckSumStatus = RETURN_SUCCESS;\r
+ }\r
+ if (DebugPortReadBuffer (Handle, &DebugHeader.CheckSum, sizeof (DebugHeader.CheckSum), Timeout) == 0) {\r
+ return RETURN_TIMEOUT;\r
+ }\r
+ }\r
+\r
+ DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)&DebugHeader, DebugHeader.Length);\r
+ *Ack = DebugHeader.Command;\r
return RETURN_SUCCESS;\r
}\r
\r
/**\r
Receive acknowledge packet OK from HOST in specified time.\r
\r
- @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
- The unit is microsecond.\r
- @param[out] BreakReceived If BreakReceived is not NULL,\r
- TRUE is retured if break-in symbol received.\r
- FALSE is retured if break-in symbol not received.\r
+ @param[in] Command The command type issued by TARGET.\r
+ @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
+ The unit is microsecond.\r
+ @param[out] BreakReceived If BreakReceived is not NULL,\r
+ TRUE is retured if break-in symbol received.\r
+ FALSE is retured if break-in symbol not received.\r
+ @param[out] CheckSumStatus If CheckSumStatus is not NULL,\r
+ RETURN_SUCCESS CheckSum is OK.\r
+ RETURN_NOT_FOUND Not find the CheckSum field.\r
\r
@retval RETRUEN_SUCCESS Succeed to receive acknowlege packet from HOST,\r
the type of acknowlege packet saved in Ack.\r
\r
**/\r
RETURN_STATUS\r
-WaitForAckPacketOK (\r
- IN UINTN Timeout,\r
- OUT BOOLEAN *BreakReceived OPTIONAL\r
+SendCommandAndWaitForAckOK (\r
+ IN UINT8 Command,\r
+ IN UINTN Timeout,\r
+ OUT BOOLEAN *BreakReceived, OPTIONAL\r
+ OUT RETURN_STATUS *CheckSumStatus OPTIONAL\r
)\r
{\r
- RETURN_STATUS Status;\r
- UINT8 Ack;\r
-\r
+ RETURN_STATUS Status;\r
+ UINT8 Ack;\r
+ \r
while (TRUE) {\r
- Status = ReceiveAckPacket (&Ack, Timeout, BreakReceived);\r
- if ((Status == RETURN_SUCCESS && Ack == DEBUG_COMMAND_OK) ||\r
- Status == RETURN_TIMEOUT) {\r
- break;\r
+ SendPacketWithoutData (Command);\r
+ while (TRUE) {\r
+ Status = ReceiveAckPacket (&Ack, Timeout, BreakReceived, CheckSumStatus);\r
+ if (Status == RETURN_SUCCESS && Ack == DEBUG_COMMAND_RESEND) {\r
+ //\r
+ // Resend the last command\r
+ //\r
+ break;\r
+ } \r
+ if ((Status == RETURN_SUCCESS && Ack == DEBUG_COMMAND_OK) ||\r
+ Status == RETURN_TIMEOUT) {\r
+ //\r
+ // Received Ack OK or timeout\r
+ //\r
+ return Status;\r
+ } \r
}\r
}\r
-\r
- return Status;\r
}\r
\r
/**\r
FALSE means break-in symbol not received.\r
\r
@retval RETURN_SUCCESS A valid package was reveived in InputPacket.\r
- @retval RETURN_NOT_READY No valid start symbol received.\r
@retval RETURN_TIMEOUT Timeout occurs.\r
\r
**/\r
OUT BOOLEAN *BreakReceived\r
)\r
{\r
- DEBUG_COMMAND_HEADER *DebugHeader;\r
+ DEBUG_PACKET_HEADER *DebugHeader;\r
UINTN Received;\r
DEBUG_PORT_HANDLE Handle;\r
+ UINT8 CheckSum;\r
\r
Handle = GetDebugPortHandle();\r
- //\r
- // Find the valid start symbol\r
- //\r
- DebugPortReadBuffer (Handle, InputPacket, 1, 0);\r
-\r
- if (*InputPacket == DEBUG_STARTING_SYMBOL_BREAK) {\r
- *BreakReceived = TRUE;\r
- SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
- }\r
+ \r
+ DebugHeader = (DEBUG_PACKET_HEADER *) InputPacket;\r
+ while (TRUE) {\r
+ //\r
+ // Find the valid start symbol\r
+ //\r
+ DebugPortReadBuffer (Handle, &DebugHeader->StartSymbol, sizeof (DebugHeader->StartSymbol), 0);\r
\r
- if (*InputPacket != DEBUG_STARTING_SYMBOL_NORMAL) {\r
- return RETURN_NOT_READY;\r
- }\r
+ if (DebugHeader->StartSymbol == DEBUG_STARTING_SYMBOL_BREAK) {\r
+ *BreakReceived = TRUE;\r
+ SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);\r
+ }\r
\r
- //\r
- // Read Package header\r
- //\r
- Received = DebugPortReadBuffer (Handle, InputPacket + 1, sizeof(DEBUG_COMMAND_HEADER_NO_START_SYMBOL), 0);\r
- if (Received == 0) {\r
- return RETURN_TIMEOUT;\r
- }\r
+ if (DebugHeader->StartSymbol != DEBUG_STARTING_SYMBOL_NORMAL) {\r
+ DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Invalid start symbol received [%02x]\n", DebugHeader->StartSymbol);\r
+ continue;\r
+ }\r
\r
- DebugHeader = (DEBUG_COMMAND_HEADER *) InputPacket;\r
- //\r
- // Read the payload if has\r
- //\r
- if (DebugHeader->DataLength > 0 && DebugHeader->DataLength < (DEBUG_DATA_MAXIMUM_REAL_DATA - sizeof(DEBUG_COMMAND_HEADER))) {\r
- InputPacket = InputPacket + 1 + Received;\r
- Received = DebugPortReadBuffer (Handle, InputPacket, DebugHeader->DataLength, 0);\r
+ //\r
+ // Read Package header except for checksum\r
+ //\r
+ Received = DebugPortReadBuffer (\r
+ Handle,\r
+ &DebugHeader->Command,\r
+ OFFSET_OF (DEBUG_PACKET_HEADER, Length) + sizeof (DebugHeader->Length) - sizeof (DebugHeader->StartSymbol),\r
+ 0\r
+ );\r
+ if (Received == 0) {\r
+ return RETURN_TIMEOUT;\r
+ }\r
\r
+ //\r
+ // Read the payload data include the checksum\r
+ //\r
+ Received = DebugPortReadBuffer (Handle, &DebugHeader->CheckSum, DebugHeader->Length - OFFSET_OF (DEBUG_PACKET_HEADER, CheckSum), 0);\r
if (Received == 0) {\r
return RETURN_TIMEOUT;\r
}\r
+ //\r
+ // Calculate the checksum of Debug Packet\r
+ //\r
+ CheckSum = CalculateCheckSum8 ((UINT8 *) DebugHeader, DebugHeader->Length);\r
+ if (CheckSum == 0) {\r
+ break;\r
+ }\r
+ DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "CheckSum Error (Caculated checksum is %x, received checksum is %x\n", CheckSum, DebugHeader->CheckSum);\r
+ DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Send DEBUG_COMMAND_RESEND command.\n");\r
+ SendAckPacket (DEBUG_COMMAND_RESEND);\r
}\r
\r
+ DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *) DebugHeader, DebugHeader->Length);\r
+\r
return RETURN_SUCCESS;\r
}\r
\r
\r
default:\r
if (Vector < 20) {\r
- Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION;\r
+ if (GetMailboxPointer()->DebugFlag.SteppingFlag == 1) {\r
+ //\r
+ // If stepping command is executing\r
+ //\r
+ Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;\r
+ } else {\r
+ Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION;\r
+ }\r
}\r
break;\r
}\r
}\r
\r
/**\r
- Send packet with response data to HOST.\r
+ Send command packet with data to HOST.\r
\r
- @param[in] CpuContext Pointer to saved CPU context.\r
+ @param[in] Command Command type.\r
@param[in] Data Pointer to response data buffer.\r
@param[in] DataSize Size of response data in byte.\r
\r
\r
**/\r
RETURN_STATUS\r
-SendDataResponsePacket (\r
- IN DEBUG_CPU_CONTEXT *CpuContext,\r
+SendCommandWithDataPacket (\r
+ IN UINT8 Command,\r
IN UINT8 *Data,\r
IN UINT16 DataSize\r
)\r
{\r
- UINT8 PacketHeader[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS];\r
+ DEBUG_PACKET_HEADER *DebugHeader;\r
BOOLEAN LastPacket;\r
UINT8 Ack;\r
- UINT8 PacketData[DEBUG_DATA_MAXIMUM_REAL_DATA];\r
+ UINT8 DebugPacket[DEBUG_DATA_UPPER_LIMIT];\r
DEBUG_PORT_HANDLE Handle;\r
\r
Handle = GetDebugPortHandle();\r
\r
- ((DEBUG_COMMAND_HEADER *)PacketHeader)->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
+ DebugHeader = (DEBUG_PACKET_HEADER *) &DebugPacket;\r
+ DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;\r
\r
while (TRUE) {\r
if (DataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) {\r
LastPacket = TRUE;\r
- ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command = DEBUG_COMMAND_OK;\r
- ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength = (UINT8) DataSize;\r
- CopyMem (PacketData, Data, DataSize);\r
+ DebugHeader->Command = Command;\r
+ DebugHeader->Length = (UINT8) (DataSize + sizeof (DEBUG_PACKET_HEADER));\r
+ DebugHeader->CheckSum = 0;\r
+ CopyMem (DebugHeader + 1, Data, DataSize);\r
\r
} else {\r
LastPacket = FALSE;\r
- ((DEBUG_COMMAND_HEADER *)PacketHeader)->Command = DEBUG_COMMAND_IN_PROGRESS;\r
- ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength = DEBUG_DATA_MAXIMUM_REAL_DATA;\r
- CopyMem (PacketData, Data, DEBUG_DATA_MAXIMUM_REAL_DATA);\r
+ DebugHeader->Command = DEBUG_COMMAND_IN_PROGRESS;\r
+ DebugHeader->Length = DEBUG_DATA_MAXIMUM_REAL_DATA + sizeof (DEBUG_PACKET_HEADER);\r
+ DebugHeader->CheckSum = 0;\r
+ CopyMem (DebugHeader + 1, Data, DEBUG_DATA_MAXIMUM_REAL_DATA);\r
}\r
\r
- DebugPortWriteBuffer (Handle, PacketHeader, sizeof (DEBUG_COMMAND_HEADER));\r
- DebugPortWriteBuffer (Handle, PacketData, ((DEBUG_COMMAND_HEADER *)PacketHeader)->DataLength);\r
+ //\r
+ // Calculate and fill the checksum\r
+ //\r
+ DebugHeader->CheckSum = CalculateCheckSum8 ((UINT8 *) DebugHeader, DebugHeader->Length);\r
+\r
+ DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *) DebugHeader, DebugHeader->Length);\r
+ \r
+ DebugPortWriteBuffer (Handle, (UINT8 *) DebugHeader, DebugHeader->Length);\r
\r
- ReceiveAckPacket(&Ack, 0, NULL);\r
+ ReceiveAckPacket(&Ack, 0, NULL, NULL);\r
switch (Ack) {\r
case DEBUG_COMMAND_RESEND:\r
//\r
// Send the packet again\r
//\r
+ DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Received DEBUG_COMMAND_RESEND.\n");\r
break;\r
\r
case DEBUG_COMMAND_CONTINUE:\r
}\r
}\r
\r
+/**\r
+ Send packet with response data to HOST.\r
+\r
+ @param[in] Data Pointer to response data buffer.\r
+ @param[in] DataSize Size of response data in byte.\r
+\r
+ @retval RETURN_SUCCESS Response data was sent successfully.\r
+ @retval RETURN_DEVICE_ERROR Cannot receive DEBUG_COMMAND_OK from HOST.\r
+\r
+**/\r
+RETURN_STATUS\r
+SendDataResponsePacket (\r
+ IN UINT8 *Data,\r
+ IN UINT16 DataSize\r
+ )\r
+{\r
+ return SendCommandWithDataPacket (DEBUG_COMMAND_OK, Data, DataSize);\r
+}\r
+\r
/**\r
Send break cause packet to HOST.\r
\r
DebugDataBreakCause.StopAddress = CpuContext->Eip;\r
DebugDataBreakCause.Cause = GetBreakCause (Vector, CpuContext);\r
\r
- return SendDataResponsePacket (CpuContext, (UINT8 *) &DebugDataBreakCause, (UINT16) sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE));\r
+ return SendDataResponsePacket ((UINT8 *) &DebugDataBreakCause, (UINT16) sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE));\r
}\r
\r
+/**\r
+ Try to attach the HOST.\r
+ \r
+ Send init break packet to HOST:\r
+ If no acknowlege received in specified Timeout, return RETURN_TIMEOUT. \r
+ If received acknowlege, check the revision of HOST. \r
+ Set Attach Flag if attach successfully. \r
+ \r
+ @param[in] Timeout Time out value to wait for acknowlege from HOST.\r
+ The unit is microsecond.\r
+ @param[out] BreakReceived If BreakReceived is not NULL,\r
+ TRUE is retured if break-in symbol received.\r
+ FALSE is retured if break-in symbol not received.\r
+**/\r
+RETURN_STATUS\r
+AttachHost (\r
+ IN UINTN Timeout,\r
+ OUT BOOLEAN *BreakReceived\r
+ )\r
+{\r
+ RETURN_STATUS Status;\r
+ DEBUG_PORT_HANDLE Handle;\r
+ RETURN_STATUS CheckSumStatus;\r
+\r
+ Handle = GetDebugPortHandle();\r
+ \r
+ //\r
+ // Send init break and wait ack in Timeout\r
+ //\r
+ DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgSendInitPacket, AsciiStrLen (mErrorMsgSendInitPacket));\r
+ Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_INIT_BREAK, Timeout, BreakReceived, &CheckSumStatus);\r
+ if (RETURN_ERROR (Status)) {\r
+ DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgConnectFail, AsciiStrLen (mErrorMsgConnectFail));\r
+ return Status;\r
+ }\r
+ \r
+ if (CheckSumStatus == RETURN_NOT_FOUND) {\r
+ //\r
+ // If the CheckSum field does not exist in Debug Packet,\r
+ // the HOST should be running with 0.1 transfer protocol.\r
+ // It could be UDK Debugger for Windows v1.1 or for Linux v0.8.\r
+ //\r
+ DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgVersionAlert, AsciiStrLen (mErrorMsgVersionAlert));\r
+ CpuDeadLoop ();\r
+ }\r
+\r
+ DebugPortWriteBuffer (Handle, (UINT8 *) mErrorMsgConnectOK, AsciiStrLen (mErrorMsgConnectOK));\r
+ //\r
+ // Set Attach flag\r
+ //\r
+ SetHostAttached (TRUE);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Send Break point packet to HOST. \r
+ \r
+ Only the first breaking processor could sent BREAK_POINT packet.\r
+ \r
+ @param[in] ProcessorIndex Processor index value.\r
+ @param[out] BreakReceived If BreakReceived is not NULL,\r
+ TRUE is retured if break-in symbol received.\r
+ FALSE is retured if break-in symbol not received.\r
+ \r
+**/\r
+VOID\r
+SendBreakPacketToHost (\r
+ IN UINT32 ProcessorIndex,\r
+ OUT BOOLEAN *BreakReceived\r
+ )\r
+{\r
+ UINT8 InputCharacter;\r
+ DEBUG_PORT_HANDLE Handle;\r
+ \r
+ Handle = GetDebugPortHandle();\r
+ \r
+ if (IsHostAttached ()) {\r
+ DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Send Break Packet to HOST.\n", ProcessorIndex);\r
+ SendCommandAndWaitForAckOK (DEBUG_COMMAND_BREAK_POINT, 0, BreakReceived, NULL);\r
+ } else {\r
+ DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to attach HOST.\n", ProcessorIndex);\r
+ //\r
+ // If HOST is not attached, try to attach it firstly.\r
+ //\r
+ //\r
+ // Poll Attach symbols from HOST and ack OK\r
+ // \r
+ do {\r
+ DebugPortReadBuffer (Handle, &InputCharacter, 1, 0);\r
+ } while (InputCharacter != DEBUG_STARTING_SYMBOL_ATTACH);\r
+ SendAckPacket (DEBUG_COMMAND_OK);\r
+ \r
+ //\r
+ // Try to attach HOST\r
+ //\r
+ while (AttachHost (0, NULL) != RETURN_SUCCESS);\r
+ \r
+ }\r
+}\r
\r
/**\r
The main function to process communication with HOST.\r
IN BOOLEAN BreakReceived\r
)\r
{\r
- RETURN_STATUS Status;\r
- UINT8 InputPacketBuffer[DEBUG_DATA_MAXIMUM_LENGTH_FOR_SMALL_COMMANDS];\r
- DEBUG_COMMAND_HEADER *DebugHeader;\r
- UINT8 Data8;\r
- UINT32 Data32;\r
- UINT64 Data64;\r
- UINTN DataN;\r
- DEBUG_DATA_READ_MEMORY_8 *MemoryRead;\r
- DEBUG_DATA_WRITE_MEMORY_8 *MemoryWrite;\r
- DEBUG_DATA_READ_IO *IoRead;\r
- DEBUG_DATA_WRITE_IO *IoWrite;\r
- DEBUG_DATA_READ_REGISTER *RegisterRead;\r
- DEBUG_DATA_WRITE_REGISTER *RegisterWrite;\r
- UINT8 *RegisterBuffer;\r
- DEBUG_DATA_READ_MSR *MsrRegisterRead;\r
- DEBUG_DATA_WRITE_MSR *MsrRegisterWrite;\r
- DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGLIM RegisterGroupSegLim;\r
- DEBUG_DATA_REPONSE_READ_REGISTER_GROUP_SEGBASE RegisterGroupSegBase;\r
- DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision;\r
- BOOLEAN HaltDeferred;\r
- DEBUG_DATA_RESPONSE_GET_EXCEPTION Exception;\r
- UINT32 ProcessorIndex;\r
- DEBUG_PORT_HANDLE Handle;\r
-\r
- Handle = GetDebugPortHandle();\r
+ RETURN_STATUS Status;\r
+ UINT8 InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT];\r
+ DEBUG_PACKET_HEADER *DebugHeader;\r
+ UINT8 Width;\r
+ UINT8 Data8;\r
+ UINT32 Data32;\r
+ UINT64 Data64;\r
+ DEBUG_DATA_READ_MEMORY *MemoryRead;\r
+ DEBUG_DATA_WRITE_MEMORY *MemoryWrite;\r
+ DEBUG_DATA_READ_IO *IoRead;\r
+ DEBUG_DATA_WRITE_IO *IoWrite;\r
+ DEBUG_DATA_READ_REGISTER *RegisterRead;\r
+ DEBUG_DATA_WRITE_REGISTER *RegisterWrite;\r
+ UINT8 *RegisterBuffer;\r
+ DEBUG_DATA_READ_MSR *MsrRegisterRead;\r
+ DEBUG_DATA_WRITE_MSR *MsrRegisterWrite;\r
+ DEBUG_DATA_CPUID *Cpuid;\r
+ DEBUG_DATA_RESPONSE_CPUID CpuidResponse;\r
+ DEBUG_DATA_SEARCH_SIGNATURE *SearchSignature;\r
+ DEBUG_DATA_RESPONSE_GET_EXCEPTION Exception;\r
+ DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision;\r
+ DEBUG_DATA_SET_VIEWPOINT *SetViewPoint;\r
+ BOOLEAN HaltDeferred;\r
+ UINT32 ProcessorIndex;\r
+ DEBUG_PORT_HANDLE Handle;\r
+ DEBUG_AGENT_EXCEPTION_BUFFER AgentExceptionBuffer;\r
+ UINT32 IssuedViewPoint;\r
\r
ProcessorIndex = 0;\r
- HaltDeferred = BreakReceived;\r
+ IssuedViewPoint = 0;\r
+ HaltDeferred = BreakReceived;\r
\r
if (MultiProcessorDebugSupport) {\r
ProcessorIndex = GetProcessorIndex ();\r
SetCpuStopFlagByIndex (ProcessorIndex, TRUE);\r
+ if (mDebugMpContext.ViewPointIndex == ProcessorIndex) {\r
+ //\r
+ // Only the current view processor could set AgentInProgress Flag. \r
+ //\r
+ IssuedViewPoint = ProcessorIndex;\r
+ }\r
}\r
\r
+ if (IssuedViewPoint == ProcessorIndex) {\r
+ //\r
+ // Set AgentInProgress Flag.\r
+ //\r
+ GetMailboxPointer()->DebugFlag.AgentInProgress = 1;\r
+ } \r
+\r
+ Handle = GetDebugPortHandle();\r
+\r
while (TRUE) {\r
\r
if (MultiProcessorDebugSupport) {\r
+ //\r
+ // Check if the current processor is HOST view point\r
+ //\r
if (mDebugMpContext.ViewPointIndex != ProcessorIndex) {\r
if (mDebugMpContext.RunCommandSet) {\r
+ //\r
+ // If HOST view point sets RUN flag, run GO command to leave\r
+ //\r
SetCpuStopFlagByIndex (ProcessorIndex, FALSE);\r
CommandGo (CpuContext);\r
break;\r
} else {\r
+ //\r
+ // Run into loop again\r
+ //\r
+ CpuPause ();\r
continue;\r
}\r
}\r
\r
Data8 = 1;\r
\r
- DebugHeader =(DEBUG_COMMAND_HEADER *) InputPacketBuffer;\r
+ DebugHeader =(DEBUG_PACKET_HEADER *) InputPacketBuffer;\r
+\r
+ GetMailboxPointer()->ExceptionBufferPointer = (UINT64)(UINTN) &AgentExceptionBuffer.JumpBuffer;\r
+ //\r
+ // Save CPU content before executing HOST commond\r
+ //\r
+ if (SetJump (&AgentExceptionBuffer.JumpBuffer) != 0) {\r
+ //\r
+ // If HOST command failed, continue to wait for HOST's next command\r
+ // If needed, agent could send exception info to HOST.\r
+ //\r
+ SendAckPacket (DEBUG_COMMAND_ABORT);\r
+ ReleaseDebugPortControl ();\r
+ continue;\r
+ }\r
+\r
+ DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Processor[%x]:Received one command(%x)\n", mDebugMpContext.ViewPointIndex, DebugHeader->Command);\r
+ \r
switch (DebugHeader->Command) {\r
\r
case DEBUG_COMMAND_RESET:\r
\r
case DEBUG_COMMAND_GO:\r
CommandGo (CpuContext);\r
+ //\r
+ // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO\r
+ // If HOST changed Dr0 before GO, we will not change Dr0 here\r
+ //\r
+ Data8 = GetBreakCause (Vector, CpuContext);\r
+ if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
+ CpuContext->Dr0 = 0;\r
+ }\r
+ //\r
+ // Clear Stepping Flag\r
+ //\r
+ GetMailboxPointer()->DebugFlag.SteppingFlag = 0;\r
+ \r
if (!HaltDeferred) {\r
//\r
// If no HALT command received when being in-active mode\r
//\r
if (MultiProcessorDebugSupport) {\r
- Data32 = FindCpuNotRunning ();\r
+ Data32 = FindNextPendingBreakCpu ();\r
if (Data32 != -1) {\r
//\r
// If there are still others processors being in break state, \r
mDebugMpContext.BreakAtCpuIndex = mDebugMpContext.ViewPointIndex;\r
SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE);\r
//\r
- // Send break packet to HOST and exit to wait for command packet from HOST.\r
+ // Send break packet to HOST to let HOST break again\r
+ //\r
+ SendBreakPacketToHost (0, &BreakReceived);\r
+ //\r
+ // Continue to run into loop to read command packet from HOST\r
//\r
- SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
- WaitForAckPacketOK (0, &BreakReceived);\r
ReleaseDebugPortControl (); \r
break;\r
}\r
//\r
SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED);\r
HaltDeferred = FALSE;\r
- Data8 = GetBreakCause (Vector, CpuContext);\r
- if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
- CpuContext->Dr0 = 0;\r
- CpuContext->Dr3 = 0;\r
- }\r
\r
Vector = DEBUG_TIMER_VECTOR;\r
}\r
\r
case DEBUG_COMMAND_SINGLE_STEPPING:\r
CommandStepping (CpuContext);\r
+ //\r
+ // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO\r
+ // If HOST changed Dr0 before GO, we will not change Dr0 here\r
+ //\r
+ Data8 = GetBreakCause (Vector, CpuContext);\r
+ if (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
+ CpuContext->Dr0 = 0;\r
+ }\r
\r
mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1);\r
-\r
+ //\r
+ // Set Stepping Flag\r
+ //\r
+ GetMailboxPointer()->DebugFlag.SteppingFlag = 1;\r
ReleaseDebugPortControl ();\r
//\r
- // Executing stepping command directly without sending ACK packet.\r
+ // Executing stepping command directly without sending ACK packet,\r
+ // ACK packet will be sent after stepping done.\r
//\r
return;\r
\r
Data64 = (UINTN) (((DEBUG_DATA_SET_SW_BREAKPOINT *) (DebugHeader + 1))->Address);\r
Data8 = *(UINT8 *) (UINTN) Data64;\r
*(UINT8 *) (UINTN) Data64 = DEBUG_SW_BREAKPOINT_SYMBOL;\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
+ Status = SendDataResponsePacket ((UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
break;\r
\r
- case DEBUG_COMMAND_READ_MEMORY_64:\r
- Data8 *= 2;\r
- case DEBUG_COMMAND_READ_MEMORY_32:\r
- Data8 *= 2;\r
- case DEBUG_COMMAND_READ_MEMORY_16:\r
- Data8 *= 2;\r
- case DEBUG_COMMAND_READ_MEMORY_8:\r
- MemoryRead = (DEBUG_DATA_READ_MEMORY_8 *) (DebugHeader + 1);\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) (UINTN) MemoryRead->Address, (UINT16) (MemoryRead->Count * Data8));\r
+ case DEBUG_COMMAND_READ_MEMORY:\r
+ MemoryRead = (DEBUG_DATA_READ_MEMORY *) (DebugHeader + 1);\r
+ Status = SendDataResponsePacket ((UINT8 *) (UINTN) MemoryRead->Address, (UINT16) (MemoryRead->Count * MemoryRead->Width));\r
break;\r
\r
- case DEBUG_COMMAND_WRITE_MEMORY_64:\r
- Data8 *= 2;\r
- case DEBUG_COMMAND_WRITE_MEMORY_32:\r
- Data8 *= 2;\r
- case DEBUG_COMMAND_WRITE_MEMORY_16:\r
- Data8 *= 2;\r
- case DEBUG_COMMAND_WRITE_MEMORY_8:\r
- MemoryWrite = (DEBUG_DATA_WRITE_MEMORY_8 *) (DebugHeader + 1);\r
- CopyMem ((VOID *) (UINTN) MemoryWrite->Address, &MemoryWrite->Data, MemoryWrite->Count * Data8);\r
+ case DEBUG_COMMAND_WRITE_MEMORY:\r
+ MemoryWrite = (DEBUG_DATA_WRITE_MEMORY *) (DebugHeader + 1);\r
+ CopyMem ((VOID *) (UINTN) MemoryWrite->Address, &MemoryWrite->Data, MemoryWrite->Count * MemoryWrite->Width);\r
SendAckPacket (DEBUG_COMMAND_OK);\r
break;\r
\r
IoRead = (DEBUG_DATA_READ_IO *) (DebugHeader + 1);\r
switch (IoRead->Width) {\r
case 1:\r
- Data64 = IoRead8 (IoRead->Port);\r
+ Data64 = IoRead8 ((UINTN) IoRead->Port);\r
break;\r
case 2:\r
- Data64 = IoRead16 (IoRead->Port);\r
+ Data64 = IoRead16 ((UINTN) IoRead->Port);\r
break;\r
case 4:\r
- Data64 = IoRead32 (IoRead->Port);\r
+ Data64 = IoRead32 ((UINTN) IoRead->Port);\r
break;\r
case 8:\r
- Data64 = IoRead64 (IoRead->Port);\r
+ Data64 = IoRead64 ((UINTN) IoRead->Port);\r
break;\r
default:\r
Data64 = (UINT64) -1;\r
}\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, IoRead->Width);\r
+ Status = SendDataResponsePacket ((UINT8 *) &Data64, IoRead->Width);\r
break;\r
\r
case DEBUG_COMMAND_WRITE_IO:\r
IoWrite = (DEBUG_DATA_WRITE_IO *) (DebugHeader + 1);\r
switch (IoWrite->Width) {\r
case 1:\r
- Data64 = IoWrite8 (IoWrite->Port, *(UINT8 *) &IoWrite->Data);\r
+ Data64 = IoWrite8 ((UINTN) IoWrite->Port, *(UINT8 *) &IoWrite->Data);\r
break;\r
case 2:\r
- Data64 = IoWrite16 (IoWrite->Port, *(UINT16 *) &IoWrite->Data);\r
+ Data64 = IoWrite16 ((UINTN) IoWrite->Port, *(UINT16 *) &IoWrite->Data);\r
break;\r
case 4:\r
- Data64 = IoWrite32 (IoWrite->Port, *(UINT32 *) &IoWrite->Data);\r
+ Data64 = IoWrite32 ((UINTN) IoWrite->Port, *(UINT32 *) &IoWrite->Data);\r
break;\r
case 8:\r
- Data64 = IoWrite64 (IoWrite->Port, *(UINT64 *) &IoWrite->Data);\r
+ Data64 = IoWrite64 ((UINTN) IoWrite->Port, *(UINT64 *) &IoWrite->Data);\r
break;\r
default:\r
Data64 = (UINT64) -1;\r
SendAckPacket (DEBUG_COMMAND_OK);\r
break;\r
\r
+ case DEBUG_COMMAND_READ_ALL_REGISTERS:\r
+ Status = SendDataResponsePacket ((UINT8 *) CpuContext, sizeof (*CpuContext));\r
+ break;\r
+\r
case DEBUG_COMMAND_READ_REGISTER:\r
RegisterRead = (DEBUG_DATA_READ_REGISTER *) (DebugHeader + 1);\r
\r
- if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_OTHERS_BASE) {\r
- Data8 = RegisterRead->Length;\r
- RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, RegisterRead->Offset, &Data8);\r
- Status = SendDataResponsePacket (CpuContext, RegisterBuffer, Data8);\r
- break;\r
- }\r
-\r
- if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_LIM) {\r
- ReadRegisterGroupSegLim (CpuContext, &RegisterGroupSegLim);\r
- DataN = * ((UINTN *) &RegisterGroupSegLim + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_LIM));\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
- } else if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_TSS_BAS) {\r
- ReadRegisterGroupSegBase (CpuContext, &RegisterGroupSegBase);\r
- DataN = * ((UINTN *) &RegisterGroupSegBase + (RegisterRead->Index - SOFT_DEBUGGER_REGISTER_CS_BAS));\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
- } else if (RegisterRead->Index < SOFT_DEBUGGER_REGISTER_IDT_LIM) {\r
- Data64 = ReadRegisterSelectorByIndex (CpuContext, RegisterRead->Index);\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
+ if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_MAX) {\r
+ RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, &Width);\r
+ Status = SendDataResponsePacket (RegisterBuffer, Width);\r
} else {\r
- switch (RegisterRead->Index) {\r
- case SOFT_DEBUGGER_REGISTER_IDT_LIM:\r
- DataN = (UINTN) (CpuContext->Idtr[0] & 0xffff);\r
- SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
- break;\r
- case SOFT_DEBUGGER_REGISTER_GDT_LIM:\r
- DataN = (UINTN) (CpuContext->Gdtr[0] & 0xffff);\r
- SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
- break;\r
- case SOFT_DEBUGGER_REGISTER_IDT_BAS:\r
- DataN = (UINTN) RShiftU64 (CpuContext->Idtr[0], 16);\r
- DataN |= (UINTN) LShiftU64 (CpuContext->Idtr[1], (UINT16) (sizeof (UINTN) * 8 - 16));\r
- SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
- break;\r
- case SOFT_DEBUGGER_REGISTER_GDT_BAS:\r
- DataN = (UINTN) RShiftU64 (CpuContext->Gdtr[0], 16);\r
- DataN |= (UINTN) LShiftU64 (CpuContext->Gdtr[1], (UINT16) (sizeof (UINTN) * 8 - 16));\r
- SendDataResponsePacket (CpuContext, (UINT8 *) &DataN, (UINT16) sizeof (UINTN));\r
- break;\r
- }\r
+ Status = RETURN_UNSUPPORTED;\r
}\r
break;\r
\r
case DEBUG_COMMAND_WRITE_REGISTER:\r
RegisterWrite = (DEBUG_DATA_WRITE_REGISTER *) (DebugHeader + 1);\r
- ArchWriteRegisterBuffer (CpuContext, RegisterWrite->Index, RegisterWrite->Offset, RegisterWrite->Length, (UINT8 *)&RegisterWrite->Value);\r
- SendAckPacket (DEBUG_COMMAND_OK);\r
+ if (RegisterWrite->Index <= SOFT_DEBUGGER_REGISTER_MAX) {\r
+ RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterWrite->Index, &Width);\r
+ ASSERT (Width == RegisterWrite->Length);\r
+ CopyMem (RegisterBuffer, RegisterWrite->Data, Width);\r
+ SendAckPacket (DEBUG_COMMAND_OK);\r
+ } else {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
break;\r
\r
case DEBUG_COMMAND_ARCH_MODE:\r
Data8 = DEBUG_ARCH_SYMBOL;\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
+ Status = SendDataResponsePacket ((UINT8 *) &Data8, (UINT16) sizeof (UINT8));\r
break;\r
\r
case DEBUG_COMMAND_READ_MSR:\r
MsrRegisterRead = (DEBUG_DATA_READ_MSR *) (DebugHeader + 1);\r
Data64 = AsmReadMsr64 (MsrRegisterRead->Index);\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
+ Status = SendDataResponsePacket ((UINT8 *) &Data64, (UINT16) sizeof (UINT64));\r
break;\r
\r
case DEBUG_COMMAND_WRITE_MSR:\r
SendAckPacket (DEBUG_COMMAND_OK);\r
break;\r
\r
- case DEBUG_COMMAND_READ_REGISTER_GROUP:\r
- Data8 = *(UINT8 *) (DebugHeader + 1);\r
- Status = ArchReadRegisterGroup (CpuContext, Data8);\r
- break;\r
-\r
- case DEBUG_COMMAND_SET_DEBUG_FLAG:\r
- Data32 = *(UINT32 *) (DebugHeader + 1);\r
- SetDebugFlag (Data32);\r
- SendAckPacket (DEBUG_COMMAND_OK);\r
+ case DEBUG_COMMAND_SET_DEBUG_SETTING:\r
+ Status = SetDebugSetting ((DEBUG_DATA_SET_DEBUG_SETTING *)(DebugHeader + 1));\r
+ if (Status == RETURN_SUCCESS) {\r
+ SendAckPacket (DEBUG_COMMAND_OK);\r
+ }\r
break;\r
\r
case DEBUG_COMMAND_GET_REVISION:\r
DebugAgentRevision.Revision = DEBUG_AGENT_REVISION;\r
DebugAgentRevision.Capabilities = DEBUG_AGENT_CAPABILITIES;\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &DebugAgentRevision, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_REVISION));\r
+ Status = SendDataResponsePacket ((UINT8 *) &DebugAgentRevision, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_REVISION));\r
break;\r
\r
case DEBUG_COMMAND_GET_EXCEPTION:\r
Exception.ExceptionNum = (UINT8) Vector;\r
- Exception.ExceptionData = 0;\r
- Status = SendDataResponsePacket (CpuContext, (UINT8 *) &Exception, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION));\r
+ Exception.ExceptionData = (UINT32) CpuContext->ExceptionData;\r
+ Status = SendDataResponsePacket ((UINT8 *) &Exception, (UINT16) sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION));\r
break;\r
\r
case DEBUG_COMMAND_SET_VIEWPOINT:\r
- Data32 = *(UINT32 *) (DebugHeader + 1);\r
-\r
+ SetViewPoint = (DEBUG_DATA_SET_VIEWPOINT *) (DebugHeader + 1);\r
if (MultiProcessorDebugSupport) {\r
- if (IsCpuStopped (Data32)) {\r
- SetDebugViewPoint (Data32);\r
+ if (IsCpuStopped (SetViewPoint->ViewPoint)) {\r
+ SetDebugViewPoint (SetViewPoint->ViewPoint);\r
SendAckPacket (DEBUG_COMMAND_OK);\r
} else {\r
//\r
//\r
SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);\r
}\r
- } else if (Data32 == 0) {\r
+ } else if (SetViewPoint->ViewPoint == 0) {\r
SendAckPacket (DEBUG_COMMAND_OK);\r
\r
} else {\r
\r
case DEBUG_COMMAND_GET_VIEWPOINT:\r
Data32 = mDebugMpContext.ViewPointIndex;\r
- SendDataResponsePacket(CpuContext, (UINT8 *) &Data32, (UINT16) sizeof (UINT32));\r
+ SendDataResponsePacket((UINT8 *) &Data32, (UINT16) sizeof (UINT32));\r
+ break;\r
+\r
+ case DEBUG_COMMAND_MEMORY_READY:\r
+ Data8 = (UINT8) GetMailboxPointer ()->DebugFlag.MemoryReady;\r
+ SendDataResponsePacket (&Data8, (UINT16) sizeof (UINT8));\r
+ break;\r
+\r
+ case DEBUG_COMMAND_DETACH:\r
+ SetHostAttached (FALSE);\r
+ SendAckPacket (DEBUG_COMMAND_OK);\r
+ break;\r
+\r
+ case DEBUG_COMMAND_CPUID:\r
+ Cpuid = (DEBUG_DATA_CPUID *) (DebugHeader + 1);\r
+ AsmCpuidEx (\r
+ Cpuid->Eax, Cpuid->Ecx, \r
+ &CpuidResponse.Eax, &CpuidResponse.Ebx,\r
+ &CpuidResponse.Ecx, &CpuidResponse.Edx\r
+ );\r
+ SendDataResponsePacket ((UINT8 *) &CpuidResponse, (UINT16) sizeof (CpuidResponse));\r
+ break;\r
+\r
+ case DEBUG_COMMAND_SEARCH_SIGNATURE:\r
+ SearchSignature = (DEBUG_DATA_SEARCH_SIGNATURE *) (DebugHeader + 1);\r
+ if ((SearchSignature->Alignment != 0) && \r
+ (SearchSignature->Alignment == GetPowerOfTwo32 (SearchSignature->Alignment))\r
+ ) {\r
+ if (SearchSignature->Positive) {\r
+ for (\r
+ Data64 = ALIGN_VALUE ((UINTN) SearchSignature->Start, SearchSignature->Alignment);\r
+ Data64 <= SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength;\r
+ Data64 += SearchSignature->Alignment\r
+ ) {\r
+ if (CompareMem ((VOID *) (UINTN) Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) {\r
+ break;\r
+ }\r
+ }\r
+ if (Data64 > SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength) {\r
+ Data64 = (UINT64) -1;\r
+ }\r
+ } else {\r
+ for (\r
+ Data64 = ALIGN_VALUE ((UINTN) SearchSignature->Start - SearchSignature->Alignment, SearchSignature->Alignment);\r
+ Data64 >= SearchSignature->Start - SearchSignature->Count;\r
+ Data64 -= SearchSignature->Alignment\r
+ ) {\r
+ if (CompareMem ((VOID *) (UINTN) Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) {\r
+ break;\r
+ }\r
+ }\r
+ if (Data64 < SearchSignature->Start - SearchSignature->Count) {\r
+ Data64 = (UINT64) -1;\r
+ }\r
+ }\r
+ SendDataResponsePacket ((UINT8 *) &Data64, (UINT16) sizeof (Data64));\r
+ } else {\r
+ Status = RETURN_UNSUPPORTED;\r
+ }\r
break;\r
\r
default:\r
IN DEBUG_CPU_CONTEXT *CpuContext\r
)\r
{\r
- UINT8 InputCharacter;\r
- UINT8 BreakCause;\r
- UINTN SavedEip;\r
- BOOLEAN BreakReceived;\r
- UINT32 ProcessorIndex;\r
- UINT32 CurrentDebugTimerInitCount;\r
- DEBUG_PORT_HANDLE Handle;\r
- UINT8 Data8;\r
-\r
- Handle = GetDebugPortHandle();\r
+ UINT8 InputCharacter;\r
+ UINT8 BreakCause;\r
+ UINTN SavedEip;\r
+ BOOLEAN BreakReceived;\r
+ UINT32 ProcessorIndex;\r
+ UINT32 CurrentDebugTimerInitCount;\r
+ DEBUG_PORT_HANDLE Handle;\r
+ UINT8 Data8;\r
+ UINT8 *Al;\r
+ UINT32 IssuedViewPoint;\r
+ DEBUG_AGENT_EXCEPTION_BUFFER *ExceptionBuffer;\r
\r
- ProcessorIndex = 0;\r
- BreakReceived = FALSE;\r
+ ProcessorIndex = 0;\r
+ IssuedViewPoint = 0;\r
+ BreakReceived = FALSE;\r
\r
if (MultiProcessorDebugSupport) {\r
ProcessorIndex = GetProcessorIndex ();\r
- while (mDebugMpContext.RunCommandSet);\r
+ //\r
+ // If this processor has alreay halted before, need to check it later\r
+ //\r
+ if (IsCpuStopped (ProcessorIndex)) {\r
+ IssuedViewPoint = ProcessorIndex;\r
+ }\r
}\r
\r
+ if (IssuedViewPoint == ProcessorIndex) {\r
+ //\r
+ // Check if this exception is issued by Debug Agent itself\r
+ // If yes, fill the debug agent exception buffer and LongJump() back to\r
+ // the saved CPU content in CommandCommunication()\r
+ //\r
+ if (GetMailboxPointer()->DebugFlag.AgentInProgress == 1) {\r
+ DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Debug agent meet one Exception, ExceptionNum is %d.\n", Vector);\r
+ ExceptionBuffer = (DEBUG_AGENT_EXCEPTION_BUFFER *) (UINTN) GetMailboxPointer()->ExceptionBufferPointer;\r
+ ExceptionBuffer->ExceptionContent.ExceptionNum = (UINT8) Vector;\r
+ ExceptionBuffer->ExceptionContent.ExceptionData = (UINT32) CpuContext->ExceptionData;\r
+ LongJump ((BASE_LIBRARY_JUMP_BUFFER *)(UINTN)(GetMailboxPointer()->ExceptionBufferPointer), 1);\r
+ }\r
+ }\r
+\r
+ if (MultiProcessorDebugSupport) {\r
+ //\r
+ // If RUN commmand is executing, wait for it done. \r
+ //\r
+ while (mDebugMpContext.RunCommandSet) {\r
+ CpuPause ();\r
+ }\r
+ }\r
+\r
+ Handle = GetDebugPortHandle();\r
+\r
switch (Vector) {\r
case DEBUG_INT1_VECTOR:\r
case DEBUG_INT3_VECTOR:\r
-\r
BreakCause = GetBreakCause (Vector, CpuContext);\r
\r
- if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) {\r
-\r
- //\r
- // Init break, if no ack received after 200ms, return\r
- //\r
- SendAckPacket (DEBUG_COMMAND_INIT_BREAK);\r
- if (WaitForAckPacketOK (200 * 1000, &BreakReceived) != RETURN_SUCCESS) {\r
+ switch (BreakCause) {\r
+ case DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET:\r
+ if (AttachHost (INIT_BREAK_ACK_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) {\r
+ //\r
+ // Try to connect HOST, return if fails\r
+ //\r
break;\r
}\r
-\r
- SetHostConnectedFlag ();\r
CommandCommunication (Vector, CpuContext, BreakReceived);\r
+ break;\r
\r
- } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {\r
-\r
+ case DEBUG_DATA_BREAK_CAUSE_STEPPING:\r
//\r
// Stepping is finished, send Ack package.\r
//\r
}\r
SendAckPacket (DEBUG_COMMAND_OK);\r
CommandCommunication (Vector, CpuContext, BreakReceived);\r
+ break;\r
\r
- } else if (BreakCause == DEBUG_DATA_BREAK_CAUSE_MEMORY_READY) {\r
-\r
+ case DEBUG_DATA_BREAK_CAUSE_MEMORY_READY:\r
//\r
// Memory is ready\r
//\r
- SendAckPacket (DEBUG_COMMAND_MEMORY_READY);\r
- WaitForAckPacketOK (0, &BreakReceived);\r
+ SendCommandAndWaitForAckOK (DEBUG_COMMAND_MEMORY_READY, 0, &BreakReceived, NULL);\r
CommandCommunication (Vector, CpuContext, BreakReceived);\r
+ break;\r
\r
- } else {\r
+ case DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD:\r
+ case DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD:\r
+ //\r
+ // Set AL to DEBUG_AGENT_IMAGE_CONTINUE\r
+ //\r
+ Al = ArchReadRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, &Data8);\r
+ *Al = DEBUG_AGENT_IMAGE_CONTINUE;\r
\r
- if (BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD || BreakCause == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD) {\r
- \r
+ if (!IsHostAttached ()) {\r
//\r
- // Set AL to DEBUG_AGENT_IMAGE_CONTINUE\r
+ // If HOST is not connected for image load/unload, return\r
//\r
- Data8 = DEBUG_AGENT_IMAGE_CONTINUE;\r
- ArchWriteRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, 0, 1, &Data8);\r
-\r
- if (!IsHostConnected ()) {\r
- //\r
- // If HOST is not connected, return\r
- //\r
- break;\r
- }\r
+ break;\r
}\r
-\r
+ //\r
+ // Continue to run the following common code\r
+ //\r
+ \r
+ case DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT:\r
+ case DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT:\r
+ default:\r
+ //\r
+ // Send Break packet to HOST\r
+ //\r
AcquireDebugPortControl ();\r
-\r
- if (MultiProcessorDebugSupport) {\r
- if(!IsAllCpuRunning ()) {\r
- //\r
- // If other processors have been stopped\r
- //\r
- SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
- } else {\r
- //\r
- // If no any processor was stopped, try to halt other processors\r
- //\r
- HaltOtherProcessors (ProcessorIndex);\r
- SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
- WaitForAckPacketOK (0, &BreakReceived);\r
- }\r
- } else {\r
- SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
- WaitForAckPacketOK (0, &BreakReceived);\r
+ //\r
+ // Only the first breaking processor could send BREAK_POINT to HOST\r
+ // \r
+ if (IsFirstBreakProcessor (ProcessorIndex)) {\r
+ SendBreakPacketToHost (ProcessorIndex, &BreakReceived);\r
}\r
-\r
ReleaseDebugPortControl ();\r
-\r
+ \r
if (Vector == DEBUG_INT3_VECTOR) {\r
//\r
// go back address located "0xCC"\r
} else {\r
CommandCommunication (Vector, CpuContext, BreakReceived);\r
}\r
+ break;\r
}\r
\r
break;\r
\r
case DEBUG_TIMER_VECTOR:\r
\r
+ AcquireDebugPortControl ();\r
+\r
if (MultiProcessorDebugSupport) {\r
if (IsBsp (ProcessorIndex)) {\r
//\r
}\r
\r
if (!IsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) {\r
+ ReleaseDebugPortControl ();\r
//\r
// If current processor is not BSP or this is one IPI sent by AP\r
//\r
//\r
// Only BSP could run here\r
//\r
-\r
- AcquireDebugPortControl ();\r
- \r
- while (DebugPortPollBuffer (Handle)) {\r
+ while (TRUE) {\r
//\r
- // If there is data in debug port, will check whether it is break-in symbol,\r
+ // If there is data in debug port, will check whether it is break(attach/break-in) symbol,\r
// If yes, go into communication mode with HOST.\r
// If no, exit interrupt process.\r
//\r
- DebugPortReadBuffer (Handle, &InputCharacter, 1, 0);\r
- if (InputCharacter == DEBUG_STARTING_SYMBOL_BREAK) {\r
+ if (DebugReadBreakSymbol (Handle, &InputCharacter) == EFI_NOT_FOUND) {\r
+ break;\r
+ }\r
+ if ((!IsHostAttached () && (InputCharacter == DEBUG_STARTING_SYMBOL_ATTACH)) ||\r
+ (IsHostAttached () && (InputCharacter == DEBUG_STARTING_SYMBOL_BREAK))\r
+ ) {\r
+ DebugAgentMsgPrint (DEBUG_AGENT_VERBOSE, "Received data [%02x]\n", InputCharacter);\r
+ //\r
+ // Ack OK for break-in symbol\r
+ //\r
SendAckPacket (DEBUG_COMMAND_OK);\r
+\r
+ if (!IsHostAttached ()) {\r
+ //\r
+ // Try to attach HOST, if no ack received after 200ms, return\r
+ //\r
+ if (AttachHost (INIT_BREAK_ACK_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) {\r
+ break;\r
+ }\r
+ }\r
+\r
if (MultiProcessorDebugSupport) {\r
- if(FindCpuNotRunning () != -1) {\r
+ if(FindNextPendingBreakCpu () != -1) {\r
SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
} else {\r
HaltOtherProcessors (ProcessorIndex);\r
default:\r
\r
if (Vector <= DEBUG_EXCEPT_SIMD) {\r
-\r
- AcquireDebugPortControl ();\r
-\r
- if (MultiProcessorDebugSupport) {\r
- if(FindCpuNotRunning () != -1) {\r
- SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);\r
- } else {\r
- HaltOtherProcessors (ProcessorIndex);\r
+ BreakCause = GetBreakCause (Vector, CpuContext);\r
+ if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {\r
+ //\r
+ // Stepping is finished, send Ack package.\r
+ //\r
+ if (MultiProcessorDebugSupport) {\r
+ mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;\r
}\r
+ SendAckPacket (DEBUG_COMMAND_OK);\r
+ } else {\r
+ //\r
+ // Exception occurs, send Break packet to HOST\r
+ //\r
+ AcquireDebugPortControl ();\r
+ //\r
+ // Only the first breaking processor could send BREAK_POINT to HOST\r
+ // \r
+ if (IsFirstBreakProcessor (ProcessorIndex)) {\r
+ SendBreakPacketToHost (ProcessorIndex, &BreakReceived);\r
+ }\r
+ ReleaseDebugPortControl ();\r
}\r
- SendAckPacket (DEBUG_COMMAND_BREAK_POINT);\r
- WaitForAckPacketOK (0, &BreakReceived);\r
- ReleaseDebugPortControl ();\r
+ \r
CommandCommunication (Vector, CpuContext, BreakReceived);\r
}\r
break;\r
// Clear flag and wait for all processors run here\r
//\r
SetIpiSentByApFlag (FALSE);\r
- while (mDebugMpContext.RunCommandSet);\r
+ while (mDebugMpContext.RunCommandSet) {\r
+ CpuPause ();\r
+ }\r
+\r
+ //\r
+ // Only current (view) processor could clean up AgentInProgress flag.\r
+ //\r
+ if (mDebugMpContext.ViewPointIndex == ProcessorIndex) {\r
+ IssuedViewPoint = mDebugMpContext.ViewPointIndex;\r
+ }\r
+ }\r
+\r
+ if (IssuedViewPoint == ProcessorIndex) {\r
+ //\r
+ // Clean up AgentInProgress flag\r
+ //\r
+ GetMailboxPointer()->DebugFlag.AgentInProgress = 0;\r
}\r
\r
return;\r