}\r
\r
/**\r
- Caculate Mailbox checksum and update the checksum field.\r
+ Calculate Mailbox checksum and update the checksum field.\r
\r
@param[in] Mailbox Debug Agent Mailbox pointer.\r
\r
- CalculateSum8 ((UINT8 *)&Value, sizeof(UINT8));\r
Mailbox->HostSequenceNo = (UINT8) Value;\r
break;\r
+ case DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY:\r
+ Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugTimerFrequency, sizeof(UINT32))\r
+ - CalculateSum8 ((UINT8 *)&Value, sizeof(UINT32));\r
+ Mailbox->DebugTimerFrequency = (UINT32) Value;\r
+ break;\r
}\r
UpdateMailboxChecksum (Mailbox);\r
ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);\r
}\r
+\r
+/**\r
+ Read data from debug device and save the data in buffer.\r
+\r
+ Reads NumberOfBytes data bytes from a debug device into the buffer\r
+ specified by Buffer. The number of bytes actually read is returned.\r
+ If the return value is less than NumberOfBytes, then the rest operation failed.\r
+ If NumberOfBytes is zero, then return 0.\r
+\r
+ @param Handle Debug port handle.\r
+ @param Buffer Pointer to the data buffer to store the data read from the debug device.\r
+ @param NumberOfBytes Number of bytes which will be read.\r
+ @param Timeout Timeout value for reading from debug device. It unit is Microsecond.\r
+\r
+ @retval 0 Read data failed, no data is to be read.\r
+ @retval >0 Actual number of bytes read from debug device.\r
+\r
+**/\r
+UINTN\r
+DebugAgentReadBuffer (\r
+ IN DEBUG_PORT_HANDLE Handle,\r
+ IN UINT8 *Buffer,\r
+ IN UINTN NumberOfBytes,\r
+ IN UINTN Timeout\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINT32 Begin;\r
+ UINT32 TimeoutTicker;\r
+ UINT32 TimerRound;\r
+ UINT32 TimerFrequency;\r
+ UINT32 TimerCycle;\r
+ \r
+ Begin = 0;\r
+ TimeoutTicker = 0; \r
+ TimerRound = 0;\r
+ TimerFrequency = GetMailboxPointer()->DebugTimerFrequency;\r
+ TimerCycle = GetApicTimerInitCount ();\r
+\r
+ if (Timeout != 0) {\r
+ Begin = GetApicTimerCurrentCount ();\r
+ TimeoutTicker = (UINT32) DivU64x32 (\r
+ MultU64x64 (\r
+ TimerFrequency,\r
+ Timeout\r
+ ),\r
+ 1000000u\r
+ );\r
+ TimerRound = (UINT32) DivU64x32Remainder (TimeoutTicker, TimerCycle / 2, &TimeoutTicker);\r
+ }\r
+ Index = 0;\r
+ while (Index < NumberOfBytes) {\r
+ if (DebugPortPollBuffer (Handle)) {\r
+ DebugPortReadBuffer (Handle, Buffer + Index, 1, 0);\r
+ Index ++; \r
+ continue;\r
+ }\r
+ if (Timeout != 0) {\r
+ if (TimerRound == 0) {\r
+ if (IsDebugTimerTimeout (TimerCycle, Begin, TimeoutTicker)) {\r
+ //\r
+ // If time out occurs.\r
+ //\r
+ return 0;\r
+ }\r
+ } else {\r
+ if (IsDebugTimerTimeout (TimerCycle, Begin, TimerCycle / 2)) {\r
+ TimerRound --;\r
+ Begin = GetApicTimerCurrentCount ();\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ return Index;\r
+}\r
+\r
/**\r
Set debug flag in mailbox.\r
\r
//\r
// Has received start symbol, try to read the rest part\r
//\r
- if (DebugPortReadBuffer (Handle, (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command), sizeof (DEBUG_PACKET_HEADER) - OFFSET_OF (DEBUG_PACKET_HEADER, Command), READ_PACKET_TIMEOUT) == 0) {\r
+ if (DebugAgentReadBuffer (Handle, (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command), sizeof (DEBUG_PACKET_HEADER) - OFFSET_OF (DEBUG_PACKET_HEADER, Command), READ_PACKET_TIMEOUT) == 0) {\r
//\r
// Timeout occur, exit\r
//\r
}\r
\r
/**\r
- Exectue Stepping command.\r
+ Execute Stepping command.\r
\r
@param[in] CpuContext Pointer to saved CPU context.\r
\r
Eflags = (IA32_EFLAGS32 *) &CpuContext->Eflags;\r
Eflags->Bits.TF = 1;\r
Eflags->Bits.RF = 1;\r
+ //\r
+ // Save and clear EFLAGS.IF to avoid interrupt happen when executing Stepping\r
+ //\r
+ SetDebugFlag (DEBUG_AGENT_FLAG_INTERRUPT_FLAG, Eflags->Bits.IF);\r
+ Eflags->Bits.IF = 0;\r
+ //\r
+ // Set Stepping Flag\r
+ //\r
+ SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 1);\r
+}\r
+\r
+/**\r
+ Do some cleanup after Stepping command done.\r
+\r
+ @param[in] CpuContext Pointer to saved CPU context.\r
+\r
+**/\r
+VOID\r
+CommandSteppingCleanup (\r
+ IN DEBUG_CPU_CONTEXT *CpuContext\r
+ )\r
+{\r
+ IA32_EFLAGS32 *Eflags;\r
+\r
+ Eflags = (IA32_EFLAGS32 *) &CpuContext->Eflags;\r
+ //\r
+ // Restore EFLAGS.IF\r
+ //\r
+ Eflags->Bits.IF = GetDebugFlag (DEBUG_AGENT_FLAG_INTERRUPT_FLAG);\r
+ //\r
+ // Clear Stepping flag\r
+ //\r
+ SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 0);\r
}\r
\r
/**\r
//\r
// Find the valid start symbol\r
//\r
- Received = DebugPortReadBuffer (Handle, &DebugHeader->StartSymbol, sizeof (DebugHeader->StartSymbol), TimeoutForStartSymbol);\r
+ Received = DebugAgentReadBuffer (Handle, &DebugHeader->StartSymbol, sizeof (DebugHeader->StartSymbol), TimeoutForStartSymbol);\r
if (Received < sizeof (DebugHeader->StartSymbol)) {\r
- DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "DebugPortReadBuffer(StartSymbol) timeout\n");\r
+ DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "DebugAgentReadBuffer(StartSymbol) timeout\n");\r
return RETURN_TIMEOUT;\r
}\r
\r
//\r
// Read Package header till field Length\r
//\r
- Received = DebugPortReadBuffer (\r
+ Received = DebugAgentReadBuffer (\r
Handle,\r
(UINT8 *) DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command),\r
OFFSET_OF (DEBUG_PACKET_HEADER, Length) + sizeof (DebugHeader->Length) - sizeof (DebugHeader->StartSymbol),\r
Timeout\r
);\r
if (Received == 0) {\r
- DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugPortReadBuffer(Command) timeout\n");\r
+ DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugAgentReadBuffer(Command) timeout\n");\r
return RETURN_TIMEOUT;\r
}\r
if (DebugHeader->Length < sizeof (DEBUG_PACKET_HEADER)) {\r
//\r
// Read the payload data include the CRC field\r
//\r
- Received = DebugPortReadBuffer (Handle, &DebugHeader->SequenceNo, (UINT8) (DebugHeader->Length - OFFSET_OF (DEBUG_PACKET_HEADER, SequenceNo)), Timeout);\r
+ Received = DebugAgentReadBuffer (Handle, &DebugHeader->SequenceNo, (UINT8) (DebugHeader->Length - OFFSET_OF (DEBUG_PACKET_HEADER, SequenceNo)), Timeout);\r
if (Received == 0) {\r
- DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugPortReadBuffer(SequenceNo) timeout\n");\r
+ DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugAgentReadBuffer(SequenceNo) timeout\n");\r
return RETURN_TIMEOUT;\r
}\r
//\r
if ((CpuContext->Dr6 & BIT14) != 0) {\r
Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;\r
//\r
- // If it's single step, no need to check DR0, to ensure single step work in PeCoffExtraActionLib\r
- // (right after triggering a breakpoint to report image load/unload).\r
+ // DR6.BIT14 Indicates (when set) that the debug exception was\r
+ // triggered by the single step execution mode.\r
+ // The single-step mode is the highest priority debug exception.\r
+ // This is single step, no need to check DR0, to ensure single step\r
+ // work in PeCoffExtraActionLib (right after triggering a breakpoint\r
+ // to report image load/unload).\r
//\r
return Cause;\r
\r
2. Compute the CRC of the compressed data buffer;\r
3. Compress the data and send to the debug channel.\r
\r
+ @param[in] Handle The debug channel handle to send the compressed data buffer.\r
@param[in] Data The data buffer.\r
@param[in] Length The length of the data buffer.\r
+ @param[in] Send TRUE to send the compressed data buffer.\r
@param[out] CompressedLength Return the length of the compressed data buffer.\r
It may be larger than the Length in some cases.\r
@param[out] CompressedCrc Return the CRC of the compressed data buffer.\r
- @param[in] Handle The debug channel handle to send the compressed data buffer.\r
**/\r
VOID\r
-CompressDataThenSend (\r
+CompressData (\r
+ IN DEBUG_PORT_HANDLE Handle,\r
IN UINT8 *Data,\r
IN UINT8 Length,\r
+ IN BOOLEAN Send,\r
OUT UINTN *CompressedLength, OPTIONAL\r
- OUT UINT16 *CompressedCrc, OPTIONAL\r
- IN DEBUG_PORT_HANDLE Handle OPTIONAL\r
+ OUT UINT16 *CompressedCrc OPTIONAL\r
)\r
{\r
- UINTN Index;\r
- UINT8 LastChar;\r
- UINT8 LastCharCount;\r
- UINT8 CurrentChar;\r
- UINTN CompressedIndex;\r
+ UINTN Index;\r
+ UINT8 LastChar;\r
+ UINT8 LastCharCount;\r
+ UINT8 CurrentChar;\r
+ UINTN CompressedIndex;\r
\r
ASSERT (Length > 0);\r
-\r
- LastChar = Data[0] + 1; // Just ensure it's different from the first byte.\r
+ LastChar = Data[0] + 1; // Just ensure it's different from the first byte.\r
LastCharCount = 0;\r
\r
for (Index = 0, CompressedIndex = 0; Index <= Length; Index++) {\r
if (CompressedCrc != NULL) {\r
*CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);\r
}\r
- if (Handle != NULL) {\r
+ if (Send) {\r
DebugPortWriteBuffer (Handle, &LastChar, 1);\r
}\r
\r
*CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);\r
*CompressedCrc = CalculateCrc16 (&LastCharCount, 1, *CompressedCrc);\r
}\r
- if (Handle != NULL) {\r
+ if (Send) {\r
DebugPortWriteBuffer (Handle, &LastChar, 1);\r
DebugPortWriteBuffer (Handle, &LastChar, 1);\r
DebugPortWriteBuffer (Handle, &LastCharCount, 1);\r
//\r
// Get the compressed data size without modifying the packet.\r
//\r
- CompressDataThenSend (\r
+ CompressData (\r
+ Handle,\r
(UINT8 *) (DebugHeader + 1),\r
CurrentDataSize,\r
+ FALSE,\r
&CompressedDataSize,\r
- NULL,\r
NULL\r
);\r
} else {\r
// Compute the CRC of the packet head without modifying the packet.\r
//\r
DebugHeader->Crc = CalculateCrc16 ((UINT8 *) DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0);\r
- CompressDataThenSend (\r
+ CompressData (\r
+ Handle,\r
(UINT8 *) (DebugHeader + 1),\r
CurrentDataSize,\r
+ FALSE,\r
NULL,\r
- &DebugHeader->Crc,\r
- NULL\r
+ &DebugHeader->Crc\r
);\r
//\r
// Send out the packet head.\r
//\r
// Compress and send out the packet data.\r
//\r
- CompressDataThenSend (\r
+ CompressData (\r
+ Handle,\r
(UINT8 *) (DebugHeader + 1),\r
CurrentDataSize,\r
+ TRUE,\r
NULL,\r
- NULL,\r
- Handle\r
+ NULL\r
);\r
} else {\r
\r
// Poll Attach symbols from HOST and ack OK\r
//\r
do {\r
- DebugPortReadBuffer (Handle, &InputCharacter, 1, 0);\r
+ DebugAgentReadBuffer (Handle, &InputCharacter, 1, 0);\r
} while (InputCharacter != DEBUG_STARTING_SYMBOL_ATTACH);\r
SendAckPacket (DEBUG_COMMAND_OK);\r
\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
- SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 0);\r
\r
if (!HaltDeferred) {\r
//\r
}\r
\r
mDebugMpContext.BreakAtCpuIndex = (UINT32) (-1);\r
- //\r
- // Set Stepping Flag\r
- //\r
- SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 1);\r
ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);\r
//\r
// Executing stepping command directly without sending ACK packet,\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
+ // If exception is issued when executing Stepping, will be handled in\r
+ // exception handle procedure.\r
//\r
if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {\r
- DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Debug agent meet one Exception, ExceptionNum is %d, EIP = 0x%x.\n", Vector, (UINTN)CpuContext->Eip);\r
+ DebugAgentMsgPrint (\r
+ DEBUG_AGENT_ERROR,\r
+ "Debug agent meet one Exception, ExceptionNum is %d, EIP = 0x%x.\n",\r
+ Vector,\r
+ (UINTN)CpuContext->Eip\r
+ );\r
ExceptionBuffer = (DEBUG_AGENT_EXCEPTION_BUFFER *) (UINTN) GetMailboxPointer()->ExceptionBufferPointer;\r
ExceptionBuffer->ExceptionContent.ExceptionNum = (UINT8) Vector;\r
ExceptionBuffer->ExceptionContent.ExceptionData = (UINT32) CpuContext->ExceptionData;\r
if (MultiProcessorDebugSupport()) {\r
mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;\r
}\r
+ //\r
+ // Clear Stepping Flag and restore EFLAGS.IF\r
+ //\r
+ CommandSteppingCleanup (CpuContext);\r
SendAckPacket (DEBUG_COMMAND_OK);\r
CommandCommunication (Vector, CpuContext, BreakReceived);\r
break;\r
//\r
CurrentDebugTimerInitCount = GetApicTimerInitCount ();\r
if (mDebugMpContext.DebugTimerInitCount != CurrentDebugTimerInitCount) {\r
- InitializeDebugTimer ();\r
+ InitializeDebugTimer (NULL, FALSE);\r
}\r
}\r
\r
\r
default:\r
if (Vector <= DEBUG_EXCEPT_SIMD) {\r
+ DebugAgentMsgPrint (\r
+ DEBUG_AGENT_ERROR,\r
+ "Exception happened, ExceptionNum is %d, EIP = 0x%x.\n",\r
+ Vector,\r
+ (UINTN) CpuContext->Eip\r
+ );\r
if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {\r
//\r
- // Stepping is finished, send Ack package.\r
+ // If exception happened when executing Stepping, send Ack package.\r
+ // HOST consider Stepping command was finished.\r
//\r
if (MultiProcessorDebugSupport()) {\r
mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;\r
}\r
+ //\r
+ // Clear Stepping flag and restore EFLAGS.IF\r
+ //\r
+ CommandSteppingCleanup (CpuContext);\r
SendAckPacket (DEBUG_COMMAND_OK);\r
} else {\r
//\r