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