TianoCore EDK2 master
Loading...
Searching...
No Matches
DebugAgent.c
Go to the documentation of this file.
1
12#include "DebugAgent.h"
13#include "Ia32/DebugException.h"
14
15GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgVersionAlert[] = "\rThe SourceLevelDebugPkg you are using requires a newer version of the Intel(R) UDK Debugger Tool.\r\n";
16GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgSendInitPacket[] = "\rSend INIT break packet and try to connect the HOST (Intel(R) UDK Debugger Tool v1.5) ...\r\n";
17GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgConnectOK[] = "HOST connection is successful!\r\n";
18GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mErrorMsgConnectFail[] = "HOST connection is failed!\r\n";
19GLOBAL_REMOVE_IF_UNREFERENCED CHAR8 mWarningMsgIngoreBreakpoint[] = "Ignore break point in SMM for SMI issued during DXE debugging!\r\n";
20
21//
22// Vector Handoff Info list used by Debug Agent for persist
23//
24GLOBAL_REMOVE_IF_UNREFERENCED EFI_VECTOR_HANDOFF_INFO mVectorHandoffInfoDebugAgent[] = {
25 {
26 DEBUG_EXCEPT_DIVIDE_ERROR, // Vector 0
27 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
29 },
30 {
31 DEBUG_EXCEPT_DEBUG, // Vector 1
34 },
35 {
36 DEBUG_EXCEPT_NMI, // Vector 2
37 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
39 },
40 {
41 DEBUG_EXCEPT_BREAKPOINT, // Vector 3
44 },
45 {
46 DEBUG_EXCEPT_OVERFLOW, // Vector 4
47 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
49 },
50 {
51 DEBUG_EXCEPT_BOUND, // Vector 5
52 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
54 },
55 {
56 DEBUG_EXCEPT_INVALID_OPCODE, // Vector 6
57 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
59 },
60 {
61 DEBUG_EXCEPT_DOUBLE_FAULT, // Vector 8
62 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
64 },
65 {
66 DEBUG_EXCEPT_INVALID_TSS, // Vector 10
67 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
69 },
70 {
71 DEBUG_EXCEPT_SEG_NOT_PRESENT, // Vector 11
72 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
74 },
75 {
76 DEBUG_EXCEPT_STACK_FAULT, // Vector 12
77 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
79 },
80 {
81 DEBUG_EXCEPT_GP_FAULT, // Vector 13
82 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
84 },
85 {
86 DEBUG_EXCEPT_PAGE_FAULT, // Vector 14
87 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
89 },
90 {
91 DEBUG_EXCEPT_FP_ERROR, // Vector 16
92 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
94 },
95 {
96 DEBUG_EXCEPT_ALIGNMENT_CHECK, // Vector 17
97 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
99 },
100 {
101 DEBUG_EXCEPT_MACHINE_CHECK, // Vector 18
102 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
104 },
105 {
106 DEBUG_EXCEPT_SIMD, // Vector 19
107 EFI_VECTOR_HANDOFF_HOOK_BEFORE,
109 },
110 {
111 DEBUG_TIMER_VECTOR, // Vector 32
114 },
115 {
116 DEBUG_MAILBOX_VECTOR, // Vector 33
119 },
120 {
121 0,
122 EFI_VECTOR_HANDOFF_LAST_ENTRY,
123 { 0 }
124 }
125};
126
127GLOBAL_REMOVE_IF_UNREFERENCED UINTN mVectorHandoffInfoCount = sizeof (mVectorHandoffInfoDebugAgent) / sizeof (EFI_VECTOR_HANDOFF_INFO);
128
139UINT16
141 IN UINT8 *Data,
142 IN UINTN DataSize,
143 IN UINT16 Crc
144 )
145{
146 UINTN Index;
147 UINTN BitIndex;
148
149 for (Index = 0; Index < DataSize; Index++) {
150 Crc ^= (UINT16)Data[Index];
151 for (BitIndex = 0; BitIndex < 8; BitIndex++) {
152 if ((Crc & 0x8000) != 0) {
153 Crc <<= 1;
154 Crc ^= 0x1021;
155 } else {
156 Crc <<= 1;
157 }
158 }
159 }
160
161 return Crc;
162}
163
171BOOLEAN
173 VOID
174 )
175{
176 UINTN InterruptHandler;
177
178 InterruptHandler = (UINTN)GetExceptionHandlerInIdtEntry (0);
179 if ((InterruptHandler >= 4) && (*(UINT32 *)(InterruptHandler - 4) == AGENT_HANDLER_SIGNATURE)) {
180 return TRUE;
181 } else {
182 return FALSE;
183 }
184}
185
192VOID
194 IN UINTN AlignSize
195 )
196{
197 UINTN Pe32Data;
198 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
199
200 //
201 // Find Image Base
202 //
203 Pe32Data = PeCoffSearchImageBase ((UINTN)mErrorMsgVersionAlert);
204 if (Pe32Data != 0) {
205 ImageContext.ImageAddress = Pe32Data;
206 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
208 }
209}
210
217VOID
219 IN UINT32 Signature
220 )
221{
222 UINTN Dr0;
223 UINTN Dr1;
224
225 //
226 // Save Debug Register State
227 //
228 Dr0 = AsmReadDr0 ();
229 Dr1 = AsmReadDr1 ();
230
231 //
232 // DR0 = Signature
233 //
234 AsmWriteDr0 (SOFT_INTERRUPT_SIGNATURE);
235 AsmWriteDr1 (Signature);
236
237 //
238 // Do INT3 to communicate with HOST side
239 //
240 CpuBreakpoint ();
241
242 //
243 // Restore Debug Register State only when Host didn't change it inside exception handler.
244 // Dr registers can only be changed by setting the HW breakpoint.
245 //
246 AsmWriteDr0 (Dr0);
247 AsmWriteDr1 (Dr1);
248}
249
256VOID
258 IN DEBUG_AGENT_MAILBOX *Mailbox
259 )
260{
261 Mailbox->CheckSum = CalculateCheckSum8 ((UINT8 *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2);
262}
263
272VOID
274 IN DEBUG_AGENT_MAILBOX *Mailbox
275 )
276{
277 UINT8 CheckSum;
278
279 CheckSum = CalculateCheckSum8 ((UINT8 *)Mailbox, sizeof (DEBUG_AGENT_MAILBOX) - 2);
280 //
281 // The checksum updating process may be disturbed by hardware SMI, we need to check CheckSum field
282 // and ToBeCheckSum field to validate the mail box.
283 //
284 if ((CheckSum != Mailbox->CheckSum) && (CheckSum != Mailbox->ToBeCheckSum)) {
285 DEBUG ((DEBUG_ERROR, "DebugAgent: Mailbox checksum error, stack or heap crashed!\n"));
286 DEBUG ((DEBUG_ERROR, "DebugAgent: CheckSum = %x, Mailbox->CheckSum = %x, Mailbox->ToBeCheckSum = %x\n", CheckSum, Mailbox->CheckSum, Mailbox->ToBeCheckSum));
287 CpuDeadLoop ();
288 }
289}
290
299VOID
301 IN DEBUG_AGENT_MAILBOX *Mailbox,
302 IN UINTN Index,
303 IN UINT64 Value
304 )
305{
306 AcquireMpSpinLock (&mDebugMpContext.MailboxSpinLock);
307 switch (Index) {
308 case DEBUG_MAILBOX_DEBUG_FLAG_INDEX:
309 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugFlag.Uint64, sizeof (UINT64))
310 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT64));
311 Mailbox->DebugFlag.Uint64 = Value;
312 break;
313 case DEBUG_MAILBOX_DEBUG_PORT_HANDLE_INDEX:
314 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugPortHandle, sizeof (UINTN))
315 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINTN));
316 Mailbox->DebugPortHandle = (UINTN)Value;
317 break;
318 case DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX:
319 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->ExceptionBufferPointer, sizeof (UINTN))
320 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINTN));
321 Mailbox->ExceptionBufferPointer = (UINTN)Value;
322 break;
323 case DEBUG_MAILBOX_LAST_ACK:
324 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->LastAck, sizeof (UINT8))
325 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT8));
326 Mailbox->LastAck = (UINT8)Value;
327 break;
328 case DEBUG_MAILBOX_SEQUENCE_NO_INDEX:
329 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->SequenceNo, sizeof (UINT8))
330 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT8));
331 Mailbox->SequenceNo = (UINT8)Value;
332 break;
333 case DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX:
334 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->HostSequenceNo, sizeof (UINT8))
335 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT8));
336 Mailbox->HostSequenceNo = (UINT8)Value;
337 break;
338 case DEBUG_MAILBOX_DEBUG_TIMER_FREQUENCY:
339 Mailbox->ToBeCheckSum = Mailbox->CheckSum + CalculateSum8 ((UINT8 *)&Mailbox->DebugTimerFrequency, sizeof (UINT32))
340 - CalculateSum8 ((UINT8 *)&Value, sizeof (UINT32));
341 Mailbox->DebugTimerFrequency = (UINT32)Value;
342 break;
343 }
344
345 UpdateMailboxChecksum (Mailbox);
346 ReleaseMpSpinLock (&mDebugMpContext.MailboxSpinLock);
347}
348
366UINTN
368 IN DEBUG_PORT_HANDLE Handle,
369 IN UINT8 *Buffer,
370 IN UINTN NumberOfBytes,
371 IN UINTN Timeout
372 )
373{
374 UINTN Index;
375 UINT32 Begin;
376 UINT32 TimeoutTicker;
377 UINT32 TimerRound;
378 UINT32 TimerFrequency;
379 UINT32 TimerCycle;
380
381 Begin = 0;
382 TimeoutTicker = 0;
383 TimerRound = 0;
384 TimerFrequency = GetMailboxPointer ()->DebugTimerFrequency;
385 TimerCycle = GetApicTimerInitCount ();
386
387 if (Timeout != 0) {
388 Begin = GetApicTimerCurrentCount ();
389 TimeoutTicker = (UINT32)DivU64x32 (
390 MultU64x64 (
391 TimerFrequency,
392 Timeout
393 ),
394 1000000u
395 );
396 TimerRound = (UINT32)DivU64x32Remainder (TimeoutTicker, TimerCycle / 2, &TimeoutTicker);
397 }
398
399 Index = 0;
400 while (Index < NumberOfBytes) {
401 if (DebugPortPollBuffer (Handle)) {
402 DebugPortReadBuffer (Handle, Buffer + Index, 1, 0);
403 Index++;
404 continue;
405 }
406
407 if (Timeout != 0) {
408 if (TimerRound == 0) {
409 if (IsDebugTimerTimeout (TimerCycle, Begin, TimeoutTicker)) {
410 //
411 // If time out occurs.
412 //
413 return 0;
414 }
415 } else {
416 if (IsDebugTimerTimeout (TimerCycle, Begin, TimerCycle / 2)) {
417 TimerRound--;
418 Begin = GetApicTimerCurrentCount ();
419 }
420 }
421 }
422 }
423
424 return Index;
425}
426
434VOID
436 IN UINT64 FlagMask,
437 IN UINT32 FlagValue
438 )
439{
440 DEBUG_AGENT_MAILBOX *Mailbox;
441 UINT64 Data64;
442
443 Mailbox = GetMailboxPointer ();
444 Data64 = (Mailbox->DebugFlag.Uint64 & ~FlagMask) |
445 (LShiftU64 ((UINT64)FlagValue, LowBitSet64 (FlagMask)) & FlagMask);
446 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_DEBUG_FLAG_INDEX, Data64);
447}
448
457UINT32
459 IN UINT64 FlagMask
460 )
461{
462 DEBUG_AGENT_MAILBOX *Mailbox;
463 UINT32 DebugFlag;
464
465 Mailbox = GetMailboxPointer ();
466 DebugFlag = (UINT32)RShiftU64 (Mailbox->DebugFlag.Uint64 & FlagMask, LowBitSet64 (FlagMask));
467
468 return DebugFlag;
469}
470
478VOID
480 IN CHAR8 *Buffer,
481 IN UINTN Length
482 )
483{
484 DEBUG_PACKET_HEADER DebugHeader;
485 DEBUG_PORT_HANDLE Handle;
486
487 Handle = GetDebugPortHandle ();
488
489 DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
490 DebugHeader.Command = DEBUG_COMMAND_PRINT_MESSAGE;
491 DebugHeader.Length = sizeof (DEBUG_PACKET_HEADER) + (UINT8)Length;
492 DebugHeader.SequenceNo = 0xEE;
493 DebugHeader.Crc = 0;
494 DebugHeader.Crc = CalculateCrc16 (
495 (UINT8 *)Buffer,
496 Length,
497 CalculateCrc16 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0)
498 );
499
500 DebugPortWriteBuffer (Handle, (UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER));
501 DebugPortWriteBuffer (Handle, (UINT8 *)Buffer, Length);
502}
503
516VOID
517EFIAPI
519 IN UINT8 ErrorLevel,
520 IN CHAR8 *Format,
521 ...
522 )
523{
524 CHAR8 Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA];
525 VA_LIST Marker;
526
527 //
528 // Check driver debug mask value and global mask
529 //
530 if ((ErrorLevel & GetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL)) == 0) {
531 return;
532 }
533
534 //
535 // Convert the DEBUG() message to an ASCII String
536 //
537 VA_START (Marker, Format);
538 AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);
539 VA_END (Marker);
540
541 SendDebugMsgPacket (Buffer, AsciiStrLen (Buffer));
542}
543
559VOID
560EFIAPI
562 IN UINT8 ErrorLevel,
563 IN BOOLEAN IsSend,
564 IN UINT8 *Data,
565 IN UINT8 Length
566 )
567{
568 CHAR8 Buffer[DEBUG_DATA_MAXIMUM_REAL_DATA];
569 CHAR8 *DestBuffer;
570 UINTN Index;
571
572 //
573 // Check driver debug mask value and global mask
574 //
575 if ((ErrorLevel & GetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL)) == 0) {
576 return;
577 }
578
579 DestBuffer = Buffer;
580 if (IsSend) {
581 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Sent data [ ");
582 } else {
583 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA, "Received data [ ");
584 }
585
586 Index = 0;
587 while (TRUE) {
588 if (DestBuffer - Buffer > DEBUG_DATA_MAXIMUM_REAL_DATA - 6) {
589 //
590 // If there was no enough space in buffer, send out the debug message,
591 // reserving 6 bytes is for the last data and end characters "]\n".
592 //
593 SendDebugMsgPacket (Buffer, DestBuffer - Buffer);
594 DestBuffer = Buffer;
595 }
596
597 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "%02x ", Data[Index]);
598 Index++;
599 if (Index >= Length) {
600 //
601 // The last character of debug message has been formatted in buffer
602 //
603 DestBuffer += AsciiSPrint (DestBuffer, DEBUG_DATA_MAXIMUM_REAL_DATA - (DestBuffer - Buffer), "]\n");
604 SendDebugMsgPacket (Buffer, DestBuffer - Buffer);
605 break;
606 }
607 }
608}
609
624 IN DEBUG_PORT_HANDLE Handle,
625 IN OUT DEBUG_PACKET_HEADER *DebugHeader
626 )
627{
628 UINT16 Crc;
629 DEBUG_AGENT_MAILBOX *Mailbox;
630
631 //
632 // Has received start symbol, try to read the rest part
633 //
634 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) {
635 //
636 // Timeout occur, exit
637 //
638 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Timeout in Debug Timer interrupt\n");
639 return EFI_TIMEOUT;
640 }
641
642 Crc = DebugHeader->Crc;
643 DebugHeader->Crc = 0;
644 if (CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0) != Crc) {
645 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Debug Timer CRC (%x) against (%x)\n", Crc, CalculateCrc16 ((UINT8 *)&DebugHeader, DebugHeader->Length, 0));
646 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length);
647 return EFI_CRC_ERROR;
648 }
649
650 Mailbox = GetMailboxPointer ();
651 if (IS_REQUEST (DebugHeader)) {
652 if (DebugHeader->SequenceNo == (UINT8)(Mailbox->HostSequenceNo + 1)) {
653 //
654 // Only update HostSequenceNo for new command packet
655 //
656 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, DebugHeader->SequenceNo);
657 return EFI_SUCCESS;
658 }
659
660 if (DebugHeader->SequenceNo == Mailbox->HostSequenceNo) {
661 return EFI_SUCCESS;
662 }
663 }
664
665 return EFI_DEVICE_ERROR;
666}
667
675BOOLEAN
677 VOID
678 )
679{
680 return (BOOLEAN)(GetDebugFlag (DEBUG_AGENT_FLAG_HOST_ATTACHED) == 1);
681}
682
689VOID
691 IN BOOLEAN Attached
692 )
693{
694 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Attach status is %d\n", Attached);
695 SetDebugFlag (DEBUG_AGENT_FLAG_HOST_ATTACHED, (UINT32)Attached);
696}
697
707RETURN_STATUS
709 IN DEBUG_DATA_SET_DEBUG_SETTING *DebugSetting
710 )
711{
712 RETURN_STATUS Status;
713
714 Status = RETURN_SUCCESS;
715 switch (DebugSetting->Key) {
716 case DEBUG_AGENT_SETTING_SMM_ENTRY_BREAK:
717 SetDebugFlag (DEBUG_AGENT_FLAG_BREAK_ON_NEXT_SMI, DebugSetting->Value);
718 break;
719 case DEBUG_AGENT_SETTING_PRINT_ERROR_LEVEL:
720 SetDebugFlag (DEBUG_AGENT_FLAG_PRINT_ERROR_LEVEL, DebugSetting->Value);
721 break;
722 case DEBUG_AGENT_SETTING_BOOT_SCRIPT_ENTRY_BREAK:
723 SetDebugFlag (DEBUG_AGENT_FLAG_BREAK_BOOT_SCRIPT, DebugSetting->Value);
724 break;
725 default:
726 Status = RETURN_UNSUPPORTED;
727 }
728
729 return Status;
730}
731
738VOID
740 IN DEBUG_CPU_CONTEXT *CpuContext
741 )
742{
743 IA32_EFLAGS32 *Eflags;
744
745 Eflags = (IA32_EFLAGS32 *)&CpuContext->Eflags;
746 Eflags->Bits.TF = 0;
747 Eflags->Bits.RF = 1;
748}
749
756VOID
758 IN DEBUG_CPU_CONTEXT *CpuContext
759 )
760{
761 IA32_EFLAGS32 *Eflags;
762
763 Eflags = (IA32_EFLAGS32 *)&CpuContext->Eflags;
764 Eflags->Bits.TF = 1;
765 Eflags->Bits.RF = 1;
766 //
767 // Save and clear EFLAGS.IF to avoid interrupt happen when executing Stepping
768 //
769 SetDebugFlag (DEBUG_AGENT_FLAG_INTERRUPT_FLAG, Eflags->Bits.IF);
770 Eflags->Bits.IF = 0;
771 //
772 // Set Stepping Flag
773 //
774 SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 1);
775}
776
783VOID
785 IN DEBUG_CPU_CONTEXT *CpuContext
786 )
787{
788 IA32_EFLAGS32 *Eflags;
789
790 Eflags = (IA32_EFLAGS32 *)&CpuContext->Eflags;
791 //
792 // Restore EFLAGS.IF
793 //
794 Eflags->Bits.IF = GetDebugFlag (DEBUG_AGENT_FLAG_INTERRUPT_FLAG);
795 //
796 // Clear Stepping flag
797 //
798 SetDebugFlag (DEBUG_AGENT_FLAG_STEPPING, 0);
799}
800
808VOID
810 IN DEBUG_CPU_CONTEXT *CpuContext,
811 IN DEBUG_DATA_SET_HW_BREAKPOINT *SetHwBreakpoint
812 )
813{
814 UINT8 RegisterIndex;
815 UINTN Dr7Value;
816
817 RegisterIndex = SetHwBreakpoint->Type.Index;
818
819 //
820 // Set debug address
821 //
822 *((UINTN *)&CpuContext->Dr0 + RegisterIndex) = (UINTN)SetHwBreakpoint->Address;
823
824 Dr7Value = CpuContext->Dr7;
825
826 //
827 // Enable Gx, Lx
828 //
829 Dr7Value |= (UINTN)(0x3 << (RegisterIndex * 2));
830 //
831 // Set RWx and Lenx
832 //
833 Dr7Value &= (UINTN)(~(0xf << (16 + RegisterIndex * 4)));
834 Dr7Value |= (UINTN)((SetHwBreakpoint->Type.Length << 2) | SetHwBreakpoint->Type.Access) << (16 + RegisterIndex * 4);
835 //
836 // Enable GE, LE
837 //
838 Dr7Value |= 0x300;
839
840 CpuContext->Dr7 = Dr7Value;
841}
842
850VOID
852 IN DEBUG_CPU_CONTEXT *CpuContext,
853 IN DEBUG_DATA_CLEAR_HW_BREAKPOINT *ClearHwBreakpoint
854 )
855{
856 if ((ClearHwBreakpoint->IndexMask & BIT0) != 0) {
857 CpuContext->Dr0 = 0;
858 CpuContext->Dr7 &= (UINTN)(~(0x3 << 0));
859 }
860
861 if ((ClearHwBreakpoint->IndexMask & BIT1) != 0) {
862 CpuContext->Dr1 = 0;
863 CpuContext->Dr7 &= (UINTN)(~(0x3 << 2));
864 }
865
866 if ((ClearHwBreakpoint->IndexMask & BIT2) != 0) {
867 CpuContext->Dr2 = 0;
868 CpuContext->Dr7 &= (UINTN)(~(0x3 << 4));
869 }
870
871 if ((ClearHwBreakpoint->IndexMask & BIT3) != 0) {
872 CpuContext->Dr3 = 0;
873 CpuContext->Dr7 &= (UINTN)(~(0x3 << 6));
874 }
875}
876
886UINT16
888 IN UINT8 Index,
889 OUT UINT8 *Width
890 )
891{
892 if (Index < SOFT_DEBUGGER_REGISTER_ST0) {
893 switch (Index) {
894 case SOFT_DEBUGGER_REGISTER_FP_FCW:
895 *Width = (UINT8)sizeof (UINT16);
897
898 case SOFT_DEBUGGER_REGISTER_FP_FSW:
899 *Width = (UINT8)sizeof (UINT16);
901
902 case SOFT_DEBUGGER_REGISTER_FP_FTW:
903 *Width = (UINT8)sizeof (UINT16);
905
906 case SOFT_DEBUGGER_REGISTER_FP_OPCODE:
907 *Width = (UINT8)sizeof (UINT16);
908 return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Opcode);
909
910 case SOFT_DEBUGGER_REGISTER_FP_EIP:
911 *Width = (UINT8)sizeof (UINT32);
913
914 case SOFT_DEBUGGER_REGISTER_FP_CS:
915 *Width = (UINT8)sizeof (UINT16);
917
918 case SOFT_DEBUGGER_REGISTER_FP_DATAOFFSET:
919 *Width = (UINT8)sizeof (UINT32);
920 return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, DataOffset);
921
922 case SOFT_DEBUGGER_REGISTER_FP_DS:
923 *Width = (UINT8)sizeof (UINT16);
925
926 case SOFT_DEBUGGER_REGISTER_FP_MXCSR:
927 *Width = (UINT8)sizeof (UINT32);
928 return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Mxcsr);
929
930 case SOFT_DEBUGGER_REGISTER_FP_MXCSR_MASK:
931 *Width = (UINT8)sizeof (UINT32);
932 return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, Mxcsr_Mask);
933 }
934 }
935
936 if (Index <= SOFT_DEBUGGER_REGISTER_ST7) {
937 *Width = 10;
938 } else if (Index <= SOFT_DEBUGGER_REGISTER_XMM15) {
939 *Width = 16;
940 } else {
941 //
942 // MMX register
943 //
944 *Width = 8;
945 Index -= SOFT_DEBUGGER_REGISTER_MM0 - SOFT_DEBUGGER_REGISTER_ST0;
946 }
947
948 return OFFSET_OF (DEBUG_DATA_FX_SAVE_STATE, St0Mm0) + (Index - SOFT_DEBUGGER_REGISTER_ST0) * 16;
949}
950
961UINT8 *
963 IN DEBUG_CPU_CONTEXT *CpuContext,
964 IN UINT8 Index,
965 OUT UINT8 *Width
966 )
967{
968 UINT8 *Buffer;
969
970 if (Index < SOFT_DEBUGGER_REGISTER_FP_BASE) {
971 Buffer = (UINT8 *)CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, Dr0) + Index * sizeof (UINTN);
972 *Width = (UINT8)sizeof (UINTN);
973 } else {
974 //
975 // FPU/MMX/XMM registers
976 //
977 Buffer = (UINT8 *)CpuContext + OFFSET_OF (DEBUG_CPU_CONTEXT, FxSaveState) + ArchReadFxStatOffset (Index, Width);
978 }
979
980 return Buffer;
981}
982
990VOID
992 IN UINT8 CommandType,
993 IN UINT8 SequenceNo
994 )
995{
996 DEBUG_PACKET_HEADER DebugHeader;
997 DEBUG_PORT_HANDLE Handle;
998
999 Handle = GetDebugPortHandle ();
1000
1001 DebugHeader.StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
1002 DebugHeader.Command = CommandType;
1003 DebugHeader.Length = sizeof (DEBUG_PACKET_HEADER);
1004 DebugHeader.SequenceNo = SequenceNo;
1005 DebugHeader.Crc = 0;
1006 DebugHeader.Crc = CalculateCrc16 ((UINT8 *)&DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0);
1007
1008 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *)&DebugHeader, DebugHeader.Length);
1009 DebugPortWriteBuffer (Handle, (UINT8 *)&DebugHeader, DebugHeader.Length);
1010}
1011
1018VOID
1020 IN UINT8 AckCommand
1021 )
1022{
1023 UINT8 SequenceNo;
1024 DEBUG_AGENT_MAILBOX *Mailbox;
1025
1026 if (AckCommand != DEBUG_COMMAND_OK) {
1027 //
1028 // This is not ACK OK packet
1029 //
1030 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "Send ACK(%d)\n", AckCommand);
1031 }
1032
1033 Mailbox = GetMailboxPointer ();
1034 SequenceNo = Mailbox->HostSequenceNo;
1035 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "SendAckPacket: SequenceNo = %x\n", SequenceNo);
1036 SendPacketWithoutData (AckCommand, SequenceNo);
1037 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_LAST_ACK, AckCommand);
1038}
1039
1049UINT8
1051 IN OUT UINT8 *Data,
1052 IN UINTN Length
1053 )
1054{
1055 UINTN Index;
1056 UINT16 LastChar;
1057 UINTN LastCharCount;
1058 UINT8 CurrentChar;
1059
1060 LastChar = (UINT16)-1;
1061 LastCharCount = 0;
1062 for (Index = 0; Index < Length; Index++) {
1063 CurrentChar = Data[Index];
1064 if (LastCharCount == 2) {
1065 LastCharCount = 0;
1066 CopyMem (&Data[Index + CurrentChar], &Data[Index + 1], Length - Index - 1);
1067 SetMem (&Data[Index], CurrentChar, (UINT8)LastChar);
1068 LastChar = (UINT16)-1;
1069 Index += CurrentChar - 1;
1070 Length += CurrentChar - 1;
1071 } else {
1072 if (LastChar != CurrentChar) {
1073 LastCharCount = 0;
1074 }
1075
1076 LastCharCount++;
1077 LastChar = CurrentChar;
1078 }
1079 }
1080
1081 ASSERT (Length <= DEBUG_DATA_MAXIMUM_REAL_DATA);
1082
1083 return (UINT8)Length;
1084}
1085
1104RETURN_STATUS
1106 OUT UINT8 *InputPacket,
1107 OUT BOOLEAN *BreakReceived,
1108 OUT BOOLEAN *IncompatibilityFlag OPTIONAL,
1109 IN UINTN Timeout,
1110 IN BOOLEAN SkipStartSymbol
1111 )
1112{
1113 DEBUG_PACKET_HEADER *DebugHeader;
1114 UINTN Received;
1115 DEBUG_PORT_HANDLE Handle;
1116 UINT16 Crc;
1117 UINTN TimeoutForStartSymbol;
1118
1119 Handle = GetDebugPortHandle ();
1120 if (SkipStartSymbol) {
1121 TimeoutForStartSymbol = 0;
1122 } else {
1123 TimeoutForStartSymbol = Timeout;
1124 }
1125
1126 DebugHeader = (DEBUG_PACKET_HEADER *)InputPacket;
1127 while (TRUE) {
1128 //
1129 // Find the valid start symbol
1130 //
1131 Received = DebugAgentReadBuffer (Handle, &DebugHeader->StartSymbol, sizeof (DebugHeader->StartSymbol), TimeoutForStartSymbol);
1132 if (Received < sizeof (DebugHeader->StartSymbol)) {
1133 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "DebugAgentReadBuffer(StartSymbol) timeout\n");
1134 return RETURN_TIMEOUT;
1135 }
1136
1137 if ((DebugHeader->StartSymbol != DEBUG_STARTING_SYMBOL_NORMAL) && (DebugHeader->StartSymbol != DEBUG_STARTING_SYMBOL_COMPRESS)) {
1138 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Invalid start symbol received [%02x]\n", DebugHeader->StartSymbol);
1139 continue;
1140 }
1141
1142 //
1143 // Read Package header till field Length
1144 //
1145 Received = DebugAgentReadBuffer (
1146 Handle,
1147 (UINT8 *)DebugHeader + OFFSET_OF (DEBUG_PACKET_HEADER, Command),
1148 OFFSET_OF (DEBUG_PACKET_HEADER, Length) + sizeof (DebugHeader->Length) - sizeof (DebugHeader->StartSymbol),
1149 Timeout
1150 );
1151 if (Received == 0) {
1152 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugAgentReadBuffer(Command) timeout\n");
1153 return RETURN_TIMEOUT;
1154 }
1155
1156 if (DebugHeader->Length < sizeof (DEBUG_PACKET_HEADER)) {
1157 if (IncompatibilityFlag != NULL) {
1158 //
1159 // This is one old version debug packet format, set Incompatibility flag
1160 //
1161 *IncompatibilityFlag = TRUE;
1162 } else {
1163 //
1164 // Skip the bad small packet
1165 //
1166 continue;
1167 }
1168 } else {
1169 //
1170 // Read the payload data include the CRC field
1171 //
1172 Received = DebugAgentReadBuffer (Handle, &DebugHeader->SequenceNo, (UINT8)(DebugHeader->Length - OFFSET_OF (DEBUG_PACKET_HEADER, SequenceNo)), Timeout);
1173 if (Received == 0) {
1174 DebugAgentMsgPrint (DEBUG_AGENT_ERROR, "DebugAgentReadBuffer(SequenceNo) timeout\n");
1175 return RETURN_TIMEOUT;
1176 }
1177
1178 //
1179 // Calculate the CRC of Debug Packet
1180 //
1181 Crc = DebugHeader->Crc;
1182 DebugHeader->Crc = 0;
1183 if (Crc == CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0)) {
1184 break;
1185 }
1186
1187 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "CRC Error (received CRC is %x)\n", Crc);
1188 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length);
1189 }
1190 }
1191
1192 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, FALSE, (UINT8 *)DebugHeader, DebugHeader->Length);
1193
1194 if (DebugHeader->StartSymbol == DEBUG_STARTING_SYMBOL_COMPRESS) {
1195 DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
1196 DebugHeader->Length = DecompressDataInPlace (
1197 (UINT8 *)(DebugHeader + 1),
1198 DebugHeader->Length - sizeof (DEBUG_PACKET_HEADER)
1199 ) + sizeof (DEBUG_PACKET_HEADER);
1200 }
1201
1202 return RETURN_SUCCESS;
1203}
1204
1223RETURN_STATUS
1225 IN UINT8 Command,
1226 IN UINTN Timeout,
1227 OUT BOOLEAN *BreakReceived OPTIONAL,
1228 OUT BOOLEAN *IncompatibilityFlag OPTIONAL
1229 )
1230{
1231 RETURN_STATUS Status;
1232 UINT8 InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT];
1233 DEBUG_PACKET_HEADER *DebugHeader;
1234 UINT8 SequenceNo;
1235 UINT8 HostSequenceNo;
1236 UINT8 RetryCount;
1237
1238 RetryCount = 3;
1239 DebugHeader = (DEBUG_PACKET_HEADER *)InputPacketBuffer;
1240 Status = RETURN_TIMEOUT;
1241 while (RetryCount > 0) {
1242 SequenceNo = GetMailboxPointer ()->SequenceNo;
1243 HostSequenceNo = GetMailboxPointer ()->HostSequenceNo;
1244 SendPacketWithoutData (Command, SequenceNo);
1245 Status = ReceivePacket ((UINT8 *)DebugHeader, BreakReceived, IncompatibilityFlag, Timeout, FALSE);
1246 if (Status == RETURN_TIMEOUT) {
1247 if (Command == DEBUG_COMMAND_INIT_BREAK) {
1248 RetryCount--;
1249 } else {
1250 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Timeout when waiting for ACK packet.\n");
1251 }
1252
1253 continue;
1254 }
1255
1256 ASSERT_EFI_ERROR (Status);
1257 //
1258 // Status == RETURN_SUCCESS
1259 //
1260 if ((DebugHeader->Command == DEBUG_COMMAND_OK) && (DebugHeader->SequenceNo == SequenceNo)) {
1261 //
1262 // Received Ack OK
1263 //
1264 UpdateMailboxContent (GetMailboxPointer (), DEBUG_MAILBOX_SEQUENCE_NO_INDEX, ++SequenceNo);
1265 return Status;
1266 }
1267
1268 if ((DebugHeader->Command == DEBUG_COMMAND_GO) && ((DebugHeader->SequenceNo == HostSequenceNo) || (Command == DEBUG_COMMAND_INIT_BREAK))) {
1269 //
1270 // Received Old GO
1271 //
1272 if (Command == DEBUG_COMMAND_INIT_BREAK) {
1273 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Receive GO() in last boot\n");
1274 }
1275
1276 SendPacketWithoutData (DEBUG_COMMAND_OK, DebugHeader->SequenceNo);
1277 }
1278 }
1279
1280 ASSERT (Command == DEBUG_COMMAND_INIT_BREAK);
1281 return Status;
1282}
1283
1293UINT8
1295 IN UINTN Vector,
1296 IN DEBUG_CPU_CONTEXT *CpuContext
1297 )
1298{
1299 UINT8 Cause;
1300
1301 Cause = DEBUG_DATA_BREAK_CAUSE_UNKNOWN;
1302
1303 switch (Vector) {
1304 case DEBUG_INT1_VECTOR:
1305 case DEBUG_INT3_VECTOR:
1306
1307 if (Vector == DEBUG_INT1_VECTOR) {
1308 //
1309 // INT 1
1310 //
1311 if ((CpuContext->Dr6 & BIT14) != 0) {
1312 Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;
1313 //
1314 // DR6.BIT14 Indicates (when set) that the debug exception was
1315 // triggered by the single step execution mode.
1316 // The single-step mode is the highest priority debug exception.
1317 // This is single step, no need to check DR0, to ensure single step
1318 // work in PeCoffExtraActionLib (right after triggering a breakpoint
1319 // to report image load/unload).
1320 //
1321 return Cause;
1322 } else {
1323 Cause = DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT;
1324 }
1325 } else {
1326 //
1327 // INT 3
1328 //
1329 Cause = DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT;
1330 }
1331
1332 switch (CpuContext->Dr0) {
1333 case IMAGE_LOAD_SIGNATURE:
1334 case IMAGE_UNLOAD_SIGNATURE:
1335
1336 if (CpuContext->Dr3 == IO_PORT_BREAKPOINT_ADDRESS) {
1337 Cause = (UINT8)((CpuContext->Dr0 == IMAGE_LOAD_SIGNATURE) ?
1338 DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD : DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD);
1339 }
1340
1341 break;
1342
1343 case SOFT_INTERRUPT_SIGNATURE:
1344
1345 if (CpuContext->Dr1 == MEMORY_READY_SIGNATURE) {
1346 Cause = DEBUG_DATA_BREAK_CAUSE_MEMORY_READY;
1347 CpuContext->Dr0 = 0;
1348 } else if (CpuContext->Dr1 == SYSTEM_RESET_SIGNATURE) {
1349 Cause = DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET;
1350 CpuContext->Dr0 = 0;
1351 }
1352
1353 break;
1354
1355 default:
1356 break;
1357 }
1358
1359 break;
1360
1361 case DEBUG_TIMER_VECTOR:
1362 Cause = DEBUG_DATA_BREAK_CAUSE_USER_HALT;
1363 break;
1364
1365 default:
1366 if (Vector < 20) {
1367 if (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) == 1) {
1368 //
1369 // If stepping command is executing
1370 //
1371 Cause = DEBUG_DATA_BREAK_CAUSE_STEPPING;
1372 } else {
1373 Cause = DEBUG_DATA_BREAK_CAUSE_EXCEPTION;
1374 }
1375 }
1376
1377 break;
1378 }
1379
1380 return Cause;
1381}
1382
1392VOID
1394 OUT UINT8 *Dest,
1395 IN UINT8 *Src,
1396 IN UINT16 Count,
1397 IN UINT8 Width
1398 )
1399{
1400 UINT8 *Destination;
1401 UINT8 *Source;
1402 INT8 Step;
1403
1404 if (Src > Dest) {
1405 Destination = Dest;
1406 Source = Src;
1407 Step = Width;
1408 } else {
1409 //
1410 // Copy memory from tail to avoid memory overlap
1411 //
1412 Destination = Dest + (Count - 1) * Width;
1413 Source = Src + (Count - 1) * Width;
1414 Step = -Width;
1415 }
1416
1417 while (Count-- != 0) {
1418 switch (Width) {
1419 case 1:
1420 *(UINT8 *)Destination = MmioRead8 ((UINTN)Source);
1421 break;
1422 case 2:
1423 *(UINT16 *)Destination = MmioRead16 ((UINTN)Source);
1424 break;
1425 case 4:
1426 *(UINT32 *)Destination = MmioRead32 ((UINTN)Source);
1427 break;
1428 case 8:
1429 *(UINT64 *)Destination = MmioRead64 ((UINTN)Source);
1430 break;
1431 default:
1432 ASSERT (FALSE);
1433 }
1434
1435 Source += Step;
1436 Destination += Step;
1437 }
1438}
1439
1459VOID
1461 IN DEBUG_PORT_HANDLE Handle,
1462 IN UINT8 *Data,
1463 IN UINT8 Length,
1464 IN BOOLEAN Send,
1465 OUT UINTN *CompressedLength OPTIONAL,
1466 OUT UINT16 *CompressedCrc OPTIONAL
1467 )
1468{
1469 UINTN Index;
1470 UINT8 LastChar;
1471 UINT8 LastCharCount;
1472 UINT8 CurrentChar;
1473 UINTN CompressedIndex;
1474
1475 ASSERT (Length > 0);
1476 LastChar = Data[0] + 1; // Just ensure it's different from the first byte.
1477 LastCharCount = 0;
1478
1479 for (Index = 0, CompressedIndex = 0; Index <= Length; Index++) {
1480 if (Index < Length) {
1481 CurrentChar = Data[Index];
1482 } else {
1483 CurrentChar = (UINT8)LastChar + 1; // just ensure it's different from LastChar
1484 }
1485
1486 if (LastChar != CurrentChar) {
1487 if (LastCharCount == 1) {
1488 CompressedIndex++;
1489 if (CompressedCrc != NULL) {
1490 *CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);
1491 }
1492
1493 if (Send) {
1494 DebugPortWriteBuffer (Handle, &LastChar, 1);
1495 }
1496 } else if (LastCharCount >= 2) {
1497 CompressedIndex += 3;
1498 LastCharCount -= 2;
1499 if (CompressedCrc != NULL) {
1500 *CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);
1501 *CompressedCrc = CalculateCrc16 (&LastChar, 1, *CompressedCrc);
1502 *CompressedCrc = CalculateCrc16 (&LastCharCount, 1, *CompressedCrc);
1503 }
1504
1505 if (Send) {
1506 DebugPortWriteBuffer (Handle, &LastChar, 1);
1507 DebugPortWriteBuffer (Handle, &LastChar, 1);
1508 DebugPortWriteBuffer (Handle, &LastCharCount, 1);
1509 }
1510 }
1511
1512 LastCharCount = 0;
1513 }
1514
1515 LastCharCount++;
1516 LastChar = CurrentChar;
1517 }
1518
1519 if (CompressedLength != NULL) {
1520 *CompressedLength = CompressedIndex;
1521 }
1522}
1523
1536RETURN_STATUS
1538 IN UINT8 *Data,
1539 IN UINT16 Count,
1540 IN UINT8 Width,
1541 IN DEBUG_PACKET_HEADER *DebugHeader
1542 )
1543{
1544 RETURN_STATUS Status;
1545 BOOLEAN LastPacket;
1546 DEBUG_PORT_HANDLE Handle;
1547 UINT8 SequenceNo;
1548 UINTN RemainingDataSize;
1549 UINT8 CurrentDataSize;
1550 UINTN CompressedDataSize;
1551
1552 Handle = GetDebugPortHandle ();
1553
1554 RemainingDataSize = Count * Width;
1555 while (TRUE) {
1556 SequenceNo = GetMailboxPointer ()->HostSequenceNo;
1557 if (RemainingDataSize <= DEBUG_DATA_MAXIMUM_REAL_DATA) {
1558 //
1559 // If the remaining data is less one real packet size, this is the last data packet
1560 //
1561 CurrentDataSize = (UINT8)RemainingDataSize;
1562 LastPacket = TRUE;
1563 DebugHeader->Command = DEBUG_COMMAND_OK;
1564 } else {
1565 //
1566 // Data is too larger to be sent in one packet, calculate the actual data size could
1567 // be sent in one Maximum data packet
1568 //
1569 CurrentDataSize = (DEBUG_DATA_MAXIMUM_REAL_DATA / Width) * Width;
1570 LastPacket = FALSE;
1571 DebugHeader->Command = DEBUG_COMMAND_IN_PROGRESS;
1572 }
1573
1574 //
1575 // Construct the rest Debug header
1576 //
1577 DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_NORMAL;
1578 DebugHeader->Length = CurrentDataSize + sizeof (DEBUG_PACKET_HEADER);
1579 DebugHeader->SequenceNo = SequenceNo;
1580 DebugHeader->Crc = 0;
1581 CopyMemByWidth ((UINT8 *)(DebugHeader + 1), Data, CurrentDataSize / Width, Width);
1582
1583 //
1584 // Compression/decompression support was added since revision 0.4.
1585 // Revision 0.3 shouldn't compress the packet.
1586 //
1587 if (PcdGet32 (PcdTransferProtocolRevision) >= DEBUG_AGENT_REVISION_04) {
1588 //
1589 // Get the compressed data size without modifying the packet.
1590 //
1591 CompressData (
1592 Handle,
1593 (UINT8 *)(DebugHeader + 1),
1594 CurrentDataSize,
1595 FALSE,
1596 &CompressedDataSize,
1597 NULL
1598 );
1599 } else {
1600 CompressedDataSize = CurrentDataSize;
1601 }
1602
1603 if (CompressedDataSize < CurrentDataSize) {
1604 DebugHeader->Length = (UINT8)CompressedDataSize + sizeof (DEBUG_PACKET_HEADER);
1605 DebugHeader->StartSymbol = DEBUG_STARTING_SYMBOL_COMPRESS;
1606 //
1607 // Compute the CRC of the packet head without modifying the packet.
1608 //
1609 DebugHeader->Crc = CalculateCrc16 ((UINT8 *)DebugHeader, sizeof (DEBUG_PACKET_HEADER), 0);
1610 CompressData (
1611 Handle,
1612 (UINT8 *)(DebugHeader + 1),
1613 CurrentDataSize,
1614 FALSE,
1615 NULL,
1616 &DebugHeader->Crc
1617 );
1618 //
1619 // Send out the packet head.
1620 //
1621 DebugPortWriteBuffer (Handle, (UINT8 *)DebugHeader, sizeof (DEBUG_PACKET_HEADER));
1622 //
1623 // Compress and send out the packet data.
1624 //
1625 CompressData (
1626 Handle,
1627 (UINT8 *)(DebugHeader + 1),
1628 CurrentDataSize,
1629 TRUE,
1630 NULL,
1631 NULL
1632 );
1633 } else {
1634 //
1635 // Calculate and fill the checksum, DebugHeader->Crc should be 0 before invoking CalculateCrc16 ()
1636 //
1637 DebugHeader->Crc = CalculateCrc16 ((UINT8 *)DebugHeader, DebugHeader->Length, 0);
1638
1639 DebugAgentDataMsgPrint (DEBUG_AGENT_VERBOSE, TRUE, (UINT8 *)DebugHeader, DebugHeader->Length);
1640
1641 DebugPortWriteBuffer (Handle, (UINT8 *)DebugHeader, DebugHeader->Length);
1642 }
1643
1644 while (TRUE) {
1645 Status = ReceivePacket ((UINT8 *)DebugHeader, NULL, NULL, READ_PACKET_TIMEOUT, FALSE);
1646 if (Status == RETURN_TIMEOUT) {
1647 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Timeout in SendDataResponsePacket()\n");
1648 break;
1649 }
1650
1651 if ((DebugHeader->Command == DEBUG_COMMAND_OK) && (DebugHeader->SequenceNo == SequenceNo) && LastPacket) {
1652 //
1653 // If this is the last packet, return RETURN_SUCCESS.
1654 //
1655 return RETURN_SUCCESS;
1656 }
1657
1658 if ((DebugHeader->Command == DEBUG_COMMAND_CONTINUE) && (DebugHeader->SequenceNo == (UINT8)(SequenceNo + 1))) {
1659 //
1660 // Calculate the rest data size
1661 //
1662 Data += CurrentDataSize;
1663 RemainingDataSize -= CurrentDataSize;
1664 UpdateMailboxContent (GetMailboxPointer (), DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, DebugHeader->SequenceNo);
1665 break;
1666 }
1667
1668 if (DebugHeader->SequenceNo >= SequenceNo) {
1669 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Received one old or new command(SequenceNo is %x, last SequenceNo is %x)\n", SequenceNo, DebugHeader->SequenceNo);
1670 break;
1671 }
1672 }
1673 }
1674}
1675
1687RETURN_STATUS
1689 IN UINT8 *Data,
1690 IN UINT16 DataSize,
1691 IN OUT DEBUG_PACKET_HEADER *DebugHeader
1692 )
1693{
1694 return ReadMemoryAndSendResponsePacket (Data, DataSize, 1, DebugHeader);
1695}
1696
1712RETURN_STATUS
1714 IN UINT8 BreakCause,
1715 IN UINTN Timeout,
1716 OUT BOOLEAN *BreakReceived
1717 )
1718{
1719 RETURN_STATUS Status;
1720 DEBUG_PORT_HANDLE Handle;
1721 BOOLEAN IncompatibilityFlag;
1722
1723 IncompatibilityFlag = FALSE;
1724 Handle = GetDebugPortHandle ();
1725
1726 //
1727 // Send init break and wait ack in Timeout
1728 //
1729 DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgSendInitPacket, AsciiStrLen (mErrorMsgSendInitPacket));
1730 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET) {
1731 Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_INIT_BREAK, Timeout, BreakReceived, &IncompatibilityFlag);
1732 } else {
1733 Status = SendCommandAndWaitForAckOK (DEBUG_COMMAND_ATTACH_BREAK, Timeout, BreakReceived, &IncompatibilityFlag);
1734 }
1735
1736 if (IncompatibilityFlag) {
1737 //
1738 // If the incompatible Debug Packet received, the HOST should be running transfer protocol before PcdTransferProtocolRevision.
1739 // It could be UDK Debugger for Windows v1.1/v1.2 or for Linux v0.8/v1.2.
1740 //
1741 DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgVersionAlert, AsciiStrLen (mErrorMsgVersionAlert));
1742 CpuDeadLoop ();
1743 }
1744
1745 if (RETURN_ERROR (Status)) {
1746 DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgConnectFail, AsciiStrLen (mErrorMsgConnectFail));
1747 } else {
1748 DebugPortWriteBuffer (Handle, (UINT8 *)mErrorMsgConnectOK, AsciiStrLen (mErrorMsgConnectOK));
1749 //
1750 // Set Attach flag
1751 //
1753 }
1754
1755 return Status;
1756}
1757
1770VOID
1772 IN UINT8 BreakCause,
1773 IN UINT32 ProcessorIndex,
1774 OUT BOOLEAN *BreakReceived
1775 )
1776{
1777 UINT8 InputCharacter;
1778 DEBUG_PORT_HANDLE Handle;
1779
1780 Handle = GetDebugPortHandle ();
1781
1782 if (IsHostAttached ()) {
1783 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Send Break Packet to HOST.\n", ProcessorIndex);
1784 SendCommandAndWaitForAckOK (DEBUG_COMMAND_BREAK_POINT, READ_PACKET_TIMEOUT, BreakReceived, NULL);
1785 } else {
1786 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "processor[%x]:Try to attach HOST.\n", ProcessorIndex);
1787 //
1788 // If HOST is not attached, try to attach it firstly.
1789 //
1790 //
1791 // Poll Attach symbols from HOST and ack OK
1792 //
1793 do {
1794 DebugAgentReadBuffer (Handle, &InputCharacter, 1, 0);
1795 } while (InputCharacter != DEBUG_STARTING_SYMBOL_ATTACH);
1796
1797 SendAckPacket (DEBUG_COMMAND_OK);
1798
1799 //
1800 // Try to attach HOST
1801 //
1802 while (AttachHost (BreakCause, 0, NULL) != RETURN_SUCCESS) {
1803 }
1804 }
1805}
1806
1818VOID
1820 IN UINTN Vector,
1821 IN OUT DEBUG_CPU_CONTEXT *CpuContext,
1822 IN BOOLEAN BreakReceived
1823 )
1824{
1825 RETURN_STATUS Status;
1826 UINT8 InputPacketBuffer[DEBUG_DATA_UPPER_LIMIT + sizeof (UINT64) - 1];
1827 DEBUG_PACKET_HEADER *DebugHeader;
1828 UINT8 Width;
1829 UINT8 Data8;
1830 UINT32 Data32;
1831 UINT64 Data64;
1832 DEBUG_DATA_READ_MEMORY *MemoryRead;
1833 DEBUG_DATA_WRITE_MEMORY *MemoryWrite;
1834 DEBUG_DATA_READ_IO *IoRead;
1835 DEBUG_DATA_WRITE_IO *IoWrite;
1836 DEBUG_DATA_READ_REGISTER *RegisterRead;
1837 DEBUG_DATA_WRITE_REGISTER *RegisterWrite;
1838 UINT8 *RegisterBuffer;
1839 DEBUG_DATA_READ_MSR *MsrRegisterRead;
1840 DEBUG_DATA_WRITE_MSR *MsrRegisterWrite;
1841 DEBUG_DATA_CPUID *Cpuid;
1843 DEBUG_DATA_RESPONSE_CPUID CpuidResponse;
1844 DEBUG_DATA_SEARCH_SIGNATURE *SearchSignature;
1846 DEBUG_DATA_RESPONSE_GET_REVISION DebugAgentRevision;
1847 DEBUG_DATA_SET_VIEWPOINT *SetViewPoint;
1848 BOOLEAN HaltDeferred;
1849 UINT32 ProcessorIndex;
1850 DEBUG_AGENT_EXCEPTION_BUFFER AgentExceptionBuffer;
1851 UINT32 IssuedViewPoint;
1852 DEBUG_AGENT_MAILBOX *Mailbox;
1853 UINT8 *AlignedDataPtr;
1854
1855 ProcessorIndex = 0;
1856 IssuedViewPoint = 0;
1857 HaltDeferred = BreakReceived;
1858
1860 ProcessorIndex = GetProcessorIndex ();
1861 SetCpuStopFlagByIndex (ProcessorIndex, TRUE);
1862 if (mDebugMpContext.ViewPointIndex == ProcessorIndex) {
1863 //
1864 // Only the current view processor could set AgentInProgress Flag.
1865 //
1866 IssuedViewPoint = ProcessorIndex;
1867 }
1868 }
1869
1870 if (IssuedViewPoint == ProcessorIndex) {
1871 //
1872 // Set AgentInProgress Flag.
1873 //
1874 SetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS, 1);
1875 }
1876
1877 while (TRUE) {
1879 //
1880 // Check if the current processor is HOST view point
1881 //
1882 if (mDebugMpContext.ViewPointIndex != ProcessorIndex) {
1883 if (mDebugMpContext.RunCommandSet) {
1884 //
1885 // If HOST view point sets RUN flag, run GO command to leave
1886 //
1887 SetCpuStopFlagByIndex (ProcessorIndex, FALSE);
1888 CommandGo (CpuContext);
1889 break;
1890 } else {
1891 //
1892 // Run into loop again
1893 //
1894 CpuPause ();
1895 continue;
1896 }
1897 }
1898 }
1899
1900 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
1901
1902 DebugHeader = (DEBUG_PACKET_HEADER *)InputPacketBuffer;
1903
1904 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "TARGET: Try to get command from HOST...\n");
1905 Status = ReceivePacket ((UINT8 *)DebugHeader, &BreakReceived, NULL, READ_PACKET_TIMEOUT, TRUE);
1906 if ((Status != RETURN_SUCCESS) || !IS_REQUEST (DebugHeader)) {
1907 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Get command[%x] sequenceno[%x] returned status is [%x] \n", DebugHeader->Command, DebugHeader->SequenceNo, Status);
1908 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Get command failed or it's response packet not expected! \n");
1909 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
1910 continue;
1911 }
1912
1913 Mailbox = GetMailboxPointer ();
1914 if (DebugHeader->SequenceNo == Mailbox->HostSequenceNo) {
1915 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "TARGET: Receive one old command[%x] against command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo);
1916 SendAckPacket (Mailbox->LastAck);
1917 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
1918 continue;
1919 } else if (DebugHeader->SequenceNo == (UINT8)(Mailbox->HostSequenceNo + 1)) {
1920 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, (UINT8)DebugHeader->SequenceNo);
1921 } else {
1922 DebugAgentMsgPrint (DEBUG_AGENT_WARNING, "Receive one invalid command[%x] against command[%x]\n", DebugHeader->SequenceNo, Mailbox->HostSequenceNo);
1923 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
1924 continue;
1925 }
1926
1927 //
1928 // Save CPU content before executing HOST command
1929 //
1930 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_EXCEPTION_BUFFER_POINTER_INDEX, (UINT64)(UINTN)&AgentExceptionBuffer.JumpBuffer);
1931 if (SetJump (&AgentExceptionBuffer.JumpBuffer) != 0) {
1932 //
1933 // If HOST command failed, continue to wait for HOST's next command
1934 // If needed, agent could send exception info to HOST.
1935 //
1936 SendAckPacket (DEBUG_COMMAND_ABORT);
1937 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
1938 continue;
1939 }
1940
1941 DebugAgentMsgPrint (DEBUG_AGENT_INFO, "Processor[%x]:Received one command(%x)\n", mDebugMpContext.ViewPointIndex, DebugHeader->Command);
1942
1943 switch (DebugHeader->Command) {
1944 case DEBUG_COMMAND_HALT:
1945 SendAckPacket (DEBUG_COMMAND_HALT_DEFERRED);
1946 HaltDeferred = TRUE;
1947 BreakReceived = FALSE;
1948 Status = RETURN_SUCCESS;
1949 break;
1950
1951 case DEBUG_COMMAND_RESET:
1952 SendAckPacket (DEBUG_COMMAND_OK);
1953 SendAckPacket (DEBUG_COMMAND_OK);
1954 SendAckPacket (DEBUG_COMMAND_OK);
1955 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
1956
1957 ResetCold ();
1958 //
1959 // Assume system resets in 2 seconds, otherwise send TIMEOUT packet.
1960 // PCD can be used if 2 seconds isn't long enough for some platforms.
1961 //
1962 MicroSecondDelay (2000000);
1963 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, Mailbox->HostSequenceNo + 1);
1964 SendAckPacket (DEBUG_COMMAND_TIMEOUT);
1965 SendAckPacket (DEBUG_COMMAND_TIMEOUT);
1966 SendAckPacket (DEBUG_COMMAND_TIMEOUT);
1967 break;
1968
1969 case DEBUG_COMMAND_GO:
1970 CommandGo (CpuContext);
1971 //
1972 // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO
1973 // If HOST changed Dr0 before GO, we will not change Dr0 here
1974 //
1975 Data8 = GetBreakCause (Vector, CpuContext);
1976 if ((Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD) || (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD)) {
1977 CpuContext->Dr0 = 0;
1978 }
1979
1980 if (!HaltDeferred) {
1981 //
1982 // If no HALT command received when being in-active mode
1983 //
1985 Data32 = FindNextPendingBreakCpu ();
1986 if (Data32 != -1) {
1987 //
1988 // If there are still others processors being in break state,
1989 // send OK packet to HOST to finish this go command
1990 //
1991 SendAckPacket (DEBUG_COMMAND_OK);
1992 CpuPause ();
1993 //
1994 // Set current view to the next breaking processor
1995 //
1996 mDebugMpContext.ViewPointIndex = Data32;
1997 mDebugMpContext.BreakAtCpuIndex = mDebugMpContext.ViewPointIndex;
1998 SetCpuBreakFlagByIndex (mDebugMpContext.ViewPointIndex, FALSE);
1999 //
2000 // Send break packet to HOST to let HOST break again
2001 //
2002 SendBreakPacketToHost (DEBUG_DATA_BREAK_CAUSE_UNKNOWN, mDebugMpContext.BreakAtCpuIndex, &BreakReceived);
2003 //
2004 // Continue to run into loop to read command packet from HOST
2005 //
2006 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2007 break;
2008 }
2009
2010 //
2011 // If no else processor break, set stop bitmask,
2012 // and set Running flag for all processors.
2013 //
2014 SetCpuStopFlagByIndex (ProcessorIndex, FALSE);
2016 CpuPause ();
2017 //
2018 // Wait for all processors are in running state
2019 //
2020 while (TRUE) {
2021 if (IsAllCpuRunning ()) {
2022 break;
2023 }
2024 }
2025
2026 //
2027 // Set BSP to be current view point.
2028 //
2029 SetDebugViewPoint (mDebugMpContext.BspIndex);
2030 CpuPause ();
2031 //
2032 // Clear breaking processor index and running flag
2033 //
2034 mDebugMpContext.BreakAtCpuIndex = (UINT32)(-1);
2036 }
2037
2038 //
2039 // Send OK packet to HOST to finish this go command
2040 //
2041 SendAckPacket (DEBUG_COMMAND_OK);
2042
2043 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2044
2045 if (!IsHostAttached ()) {
2046 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_SEQUENCE_NO_INDEX, 0);
2047 UpdateMailboxContent (Mailbox, DEBUG_MAILBOX_HOST_SEQUENCE_NO_INDEX, 0);
2048 }
2049
2050 return;
2051 } else {
2052 //
2053 // If received HALT command, need to defer the GO command
2054 //
2055 SendAckPacket (DEBUG_COMMAND_HALT_PROCESSED);
2056 HaltDeferred = FALSE;
2057
2058 Vector = DEBUG_TIMER_VECTOR;
2059 }
2060
2061 break;
2062
2063 case DEBUG_COMMAND_BREAK_CAUSE:
2064 BreakCause.StopAddress = CpuContext->Eip;
2065 if (MultiProcessorDebugSupport () && (ProcessorIndex != mDebugMpContext.BreakAtCpuIndex)) {
2066 BreakCause.Cause = GetBreakCause (DEBUG_TIMER_VECTOR, CpuContext);
2067 } else {
2068 BreakCause.Cause = GetBreakCause (Vector, CpuContext);
2069 }
2070
2071 SendDataResponsePacket ((UINT8 *)&BreakCause, (UINT16)sizeof (DEBUG_DATA_RESPONSE_BREAK_CAUSE), DebugHeader);
2072 break;
2073
2074 case DEBUG_COMMAND_SET_HW_BREAKPOINT:
2075 SetDebugRegister (CpuContext, (DEBUG_DATA_SET_HW_BREAKPOINT *)(DebugHeader + 1));
2076 SendAckPacket (DEBUG_COMMAND_OK);
2077 break;
2078
2079 case DEBUG_COMMAND_CLEAR_HW_BREAKPOINT:
2080 ClearDebugRegister (CpuContext, (DEBUG_DATA_CLEAR_HW_BREAKPOINT *)(DebugHeader + 1));
2081 SendAckPacket (DEBUG_COMMAND_OK);
2082 break;
2083
2084 case DEBUG_COMMAND_SINGLE_STEPPING:
2085 CommandStepping (CpuContext);
2086 //
2087 // Clear Dr0 to avoid to be recognized as IMAGE_LOAD/_UNLOAD again when hitting a breakpoint after GO
2088 // If HOST changed Dr0 before GO, we will not change Dr0 here
2089 //
2090 Data8 = GetBreakCause (Vector, CpuContext);
2091 if ((Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD) || (Data8 == DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD)) {
2092 CpuContext->Dr0 = 0;
2093 }
2094
2095 mDebugMpContext.BreakAtCpuIndex = (UINT32)(-1);
2096 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2097 //
2098 // Executing stepping command directly without sending ACK packet,
2099 // ACK packet will be sent after stepping done.
2100 //
2101 return;
2102
2103 case DEBUG_COMMAND_SET_SW_BREAKPOINT:
2104 Data64 = (UINTN)(((DEBUG_DATA_SET_SW_BREAKPOINT *)(DebugHeader + 1))->Address);
2105 Data8 = *(UINT8 *)(UINTN)Data64;
2106 *(UINT8 *)(UINTN)Data64 = DEBUG_SW_BREAKPOINT_SYMBOL;
2107 Status = SendDataResponsePacket ((UINT8 *)&Data8, (UINT16)sizeof (UINT8), DebugHeader);
2108 break;
2109
2110 case DEBUG_COMMAND_READ_MEMORY:
2111 MemoryRead = (DEBUG_DATA_READ_MEMORY *)(DebugHeader + 1);
2112 Status = ReadMemoryAndSendResponsePacket ((UINT8 *)(UINTN)MemoryRead->Address, MemoryRead->Count, MemoryRead->Width, DebugHeader);
2113 break;
2114
2115 case DEBUG_COMMAND_WRITE_MEMORY:
2116 MemoryWrite = (DEBUG_DATA_WRITE_MEMORY *)(DebugHeader + 1);
2117 //
2118 // Copy data into one memory with 8-byte alignment address
2119 //
2120 AlignedDataPtr = ALIGN_POINTER ((UINT8 *)&MemoryWrite->Data, sizeof (UINT64));
2121 if (AlignedDataPtr != (UINT8 *)&MemoryWrite->Data) {
2122 CopyMem (AlignedDataPtr, (UINT8 *)&MemoryWrite->Data, MemoryWrite->Count * MemoryWrite->Width);
2123 }
2124
2125 CopyMemByWidth ((UINT8 *)(UINTN)MemoryWrite->Address, AlignedDataPtr, MemoryWrite->Count, MemoryWrite->Width);
2126 SendAckPacket (DEBUG_COMMAND_OK);
2127 break;
2128
2129 case DEBUG_COMMAND_READ_IO:
2130 IoRead = (DEBUG_DATA_READ_IO *)(DebugHeader + 1);
2131 switch (IoRead->Width) {
2132 case 1:
2133 Data64 = IoRead8 ((UINTN)IoRead->Port);
2134 break;
2135 case 2:
2136 Data64 = IoRead16 ((UINTN)IoRead->Port);
2137 break;
2138 case 4:
2139 Data64 = IoRead32 ((UINTN)IoRead->Port);
2140 break;
2141 case 8:
2142 Data64 = IoRead64 ((UINTN)IoRead->Port);
2143 break;
2144 default:
2145 Data64 = (UINT64)-1;
2146 }
2147
2148 Status = SendDataResponsePacket ((UINT8 *)&Data64, IoRead->Width, DebugHeader);
2149 break;
2150
2151 case DEBUG_COMMAND_WRITE_IO:
2152 IoWrite = (DEBUG_DATA_WRITE_IO *)(DebugHeader + 1);
2153 switch (IoWrite->Width) {
2154 case 1:
2155 Data64 = IoWrite8 ((UINTN)IoWrite->Port, *(UINT8 *)&IoWrite->Data);
2156 break;
2157 case 2:
2158 Data64 = IoWrite16 ((UINTN)IoWrite->Port, *(UINT16 *)&IoWrite->Data);
2159 break;
2160 case 4:
2161 Data64 = IoWrite32 ((UINTN)IoWrite->Port, *(UINT32 *)&IoWrite->Data);
2162 break;
2163 case 8:
2164 Data64 = IoWrite64 ((UINTN)IoWrite->Port, *(UINT64 *)&IoWrite->Data);
2165 break;
2166 default:
2167 Data64 = (UINT64)-1;
2168 }
2169
2170 SendAckPacket (DEBUG_COMMAND_OK);
2171 break;
2172
2173 case DEBUG_COMMAND_READ_ALL_REGISTERS:
2174 Status = SendDataResponsePacket ((UINT8 *)CpuContext, sizeof (*CpuContext), DebugHeader);
2175 break;
2176
2177 case DEBUG_COMMAND_READ_REGISTER:
2178 RegisterRead = (DEBUG_DATA_READ_REGISTER *)(DebugHeader + 1);
2179
2180 if (RegisterRead->Index <= SOFT_DEBUGGER_REGISTER_MAX) {
2181 RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterRead->Index, &Width);
2182 Status = SendDataResponsePacket (RegisterBuffer, Width, DebugHeader);
2183 } else {
2184 Status = RETURN_UNSUPPORTED;
2185 }
2186
2187 break;
2188
2189 case DEBUG_COMMAND_WRITE_REGISTER:
2190 RegisterWrite = (DEBUG_DATA_WRITE_REGISTER *)(DebugHeader + 1);
2191 if (RegisterWrite->Index <= SOFT_DEBUGGER_REGISTER_MAX) {
2192 RegisterBuffer = ArchReadRegisterBuffer (CpuContext, RegisterWrite->Index, &Width);
2193 ASSERT (Width == RegisterWrite->Length);
2194 CopyMem (RegisterBuffer, RegisterWrite->Data, Width);
2195 SendAckPacket (DEBUG_COMMAND_OK);
2196 } else {
2197 Status = RETURN_UNSUPPORTED;
2198 }
2199
2200 break;
2201
2202 case DEBUG_COMMAND_ARCH_MODE:
2203 Data8 = DEBUG_ARCH_SYMBOL;
2204 Status = SendDataResponsePacket ((UINT8 *)&Data8, (UINT16)sizeof (UINT8), DebugHeader);
2205 break;
2206
2207 case DEBUG_COMMAND_READ_MSR:
2208 MsrRegisterRead = (DEBUG_DATA_READ_MSR *)(DebugHeader + 1);
2209 Data64 = AsmReadMsr64 (MsrRegisterRead->Index);
2210 Status = SendDataResponsePacket ((UINT8 *)&Data64, (UINT16)sizeof (UINT64), DebugHeader);
2211 break;
2212
2213 case DEBUG_COMMAND_WRITE_MSR:
2214 MsrRegisterWrite = (DEBUG_DATA_WRITE_MSR *)(DebugHeader + 1);
2215 AsmWriteMsr64 (MsrRegisterWrite->Index, MsrRegisterWrite->Value);
2216 SendAckPacket (DEBUG_COMMAND_OK);
2217 break;
2218
2219 case DEBUG_COMMAND_SET_DEBUG_SETTING:
2220 Status = SetDebugSetting ((DEBUG_DATA_SET_DEBUG_SETTING *)(DebugHeader + 1));
2221 if (Status == RETURN_SUCCESS) {
2222 SendAckPacket (DEBUG_COMMAND_OK);
2223 }
2224
2225 break;
2226
2227 case DEBUG_COMMAND_GET_REVISION:
2228 DebugAgentRevision.Revision = PcdGet32 (PcdTransferProtocolRevision);
2229 DebugAgentRevision.Capabilities = DEBUG_AGENT_CAPABILITIES;
2230 Status = SendDataResponsePacket ((UINT8 *)&DebugAgentRevision, (UINT16)sizeof (DEBUG_DATA_RESPONSE_GET_REVISION), DebugHeader);
2231 break;
2232
2233 case DEBUG_COMMAND_GET_EXCEPTION:
2234 Exception.ExceptionNum = (UINT8)Vector;
2235 Exception.ExceptionData = (UINT32)CpuContext->ExceptionData;
2236 Status = SendDataResponsePacket ((UINT8 *)&Exception, (UINT16)sizeof (DEBUG_DATA_RESPONSE_GET_EXCEPTION), DebugHeader);
2237 break;
2238
2239 case DEBUG_COMMAND_SET_VIEWPOINT:
2240 SetViewPoint = (DEBUG_DATA_SET_VIEWPOINT *)(DebugHeader + 1);
2242 if (IsCpuStopped (SetViewPoint->ViewPoint)) {
2243 SetDebugViewPoint (SetViewPoint->ViewPoint);
2244 SendAckPacket (DEBUG_COMMAND_OK);
2245 } else {
2246 //
2247 // If CPU is not halted
2248 //
2249 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
2250 }
2251 } else if (SetViewPoint->ViewPoint == 0) {
2252 SendAckPacket (DEBUG_COMMAND_OK);
2253 } else {
2254 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
2255 }
2256
2257 break;
2258
2259 case DEBUG_COMMAND_GET_VIEWPOINT:
2260 Data32 = mDebugMpContext.ViewPointIndex;
2261 SendDataResponsePacket ((UINT8 *)&Data32, (UINT16)sizeof (UINT32), DebugHeader);
2262 break;
2263
2264 case DEBUG_COMMAND_MEMORY_READY:
2265 Data8 = (UINT8)GetDebugFlag (DEBUG_AGENT_FLAG_MEMORY_READY);
2266 SendDataResponsePacket (&Data8, (UINT16)sizeof (UINT8), DebugHeader);
2267 break;
2268
2269 case DEBUG_COMMAND_DETACH:
2271 SendAckPacket (DEBUG_COMMAND_OK);
2272 break;
2273
2274 case DEBUG_COMMAND_CPUID:
2275 Cpuid = (DEBUG_DATA_CPUID *)(DebugHeader + 1);
2276 AsmCpuidEx (
2277 Cpuid->Eax,
2278 Cpuid->Ecx,
2279 &CpuidResponse.Eax,
2280 &CpuidResponse.Ebx,
2281 &CpuidResponse.Ecx,
2282 &CpuidResponse.Edx
2283 );
2284 SendDataResponsePacket ((UINT8 *)&CpuidResponse, (UINT16)sizeof (CpuidResponse), DebugHeader);
2285 break;
2286
2287 case DEBUG_COMMAND_SEARCH_SIGNATURE:
2288 SearchSignature = (DEBUG_DATA_SEARCH_SIGNATURE *)(DebugHeader + 1);
2289 if ((SearchSignature->Alignment != 0) &&
2290 (SearchSignature->Alignment == GetPowerOfTwo32 (SearchSignature->Alignment))
2291 )
2292 {
2293 if (SearchSignature->Positive) {
2294 for (
2295 Data64 = ALIGN_VALUE ((UINTN)SearchSignature->Start, SearchSignature->Alignment);
2296 Data64 <= SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength;
2297 Data64 += SearchSignature->Alignment
2298 )
2299 {
2300 if (CompareMem ((VOID *)(UINTN)Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) {
2301 break;
2302 }
2303 }
2304
2305 if (Data64 > SearchSignature->Start + SearchSignature->Count - SearchSignature->DataLength) {
2306 Data64 = (UINT64)-1;
2307 }
2308 } else {
2309 for (
2310 Data64 = ALIGN_VALUE ((UINTN)SearchSignature->Start - SearchSignature->Alignment, SearchSignature->Alignment);
2311 Data64 >= SearchSignature->Start - SearchSignature->Count;
2312 Data64 -= SearchSignature->Alignment
2313 )
2314 {
2315 if (CompareMem ((VOID *)(UINTN)Data64, &SearchSignature->Data, SearchSignature->DataLength) == 0) {
2316 break;
2317 }
2318 }
2319
2320 if (Data64 < SearchSignature->Start - SearchSignature->Count) {
2321 Data64 = (UINT64)-1;
2322 }
2323 }
2324
2325 SendDataResponsePacket ((UINT8 *)&Data64, (UINT16)sizeof (Data64), DebugHeader);
2326 } else {
2327 Status = RETURN_UNSUPPORTED;
2328 }
2329
2330 break;
2331
2332 default:
2333 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
2334 break;
2335 }
2336
2337 if (Status == RETURN_UNSUPPORTED) {
2338 SendAckPacket (DEBUG_COMMAND_NOT_SUPPORTED);
2339 } else if (Status != RETURN_SUCCESS) {
2340 SendAckPacket (DEBUG_COMMAND_ABORT);
2341 }
2342
2343 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2344 CpuPause ();
2345 }
2346}
2347
2355VOID
2356EFIAPI
2358 IN UINT32 Vector,
2359 IN DEBUG_CPU_CONTEXT *CpuContext
2360 )
2361{
2362 UINT8 InputCharacter;
2363 UINT8 BreakCause;
2364 UINTN SavedEip;
2365 BOOLEAN BreakReceived;
2366 UINT32 ProcessorIndex;
2367 UINT32 CurrentDebugTimerInitCount;
2368 DEBUG_PORT_HANDLE Handle;
2369 UINT8 Data8;
2370 UINT8 *Al;
2371 UINT32 IssuedViewPoint;
2372 DEBUG_AGENT_EXCEPTION_BUFFER *ExceptionBuffer;
2373
2374 InputCharacter = 0;
2375 ProcessorIndex = 0;
2376 IssuedViewPoint = 0;
2377 BreakReceived = FALSE;
2378
2379 if (mSkipBreakpoint) {
2380 //
2381 // If Skip Breakpoint flag is set, means communication is disturbed by hardware SMI, we need to ignore the break points in SMM
2382 //
2383 if ((Vector == DEBUG_INT1_VECTOR) || (Vector == DEBUG_INT3_VECTOR)) {
2384 DebugPortWriteBuffer (GetDebugPortHandle (), (UINT8 *)mWarningMsgIngoreBreakpoint, AsciiStrLen (mWarningMsgIngoreBreakpoint));
2385 return;
2386 }
2387 }
2388
2390 ProcessorIndex = GetProcessorIndex ();
2391 //
2392 // If this processor has already halted before, need to check it later
2393 //
2394 if (IsCpuStopped (ProcessorIndex)) {
2395 IssuedViewPoint = ProcessorIndex;
2396 }
2397 }
2398
2399 if ((IssuedViewPoint == ProcessorIndex) && (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) != 1)) {
2400 //
2401 // Check if this exception is issued by Debug Agent itself
2402 // If yes, fill the debug agent exception buffer and LongJump() back to
2403 // the saved CPU content in CommandCommunication()
2404 // If exception is issued when executing Stepping, will be handled in
2405 // exception handle procedure.
2406 //
2407 if (GetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS) == 1) {
2409 DEBUG_AGENT_ERROR,
2410 "Debug agent meet one Exception, ExceptionNum is %d, EIP = 0x%x.\n",
2411 Vector,
2412 (UINTN)CpuContext->Eip
2413 );
2414 ExceptionBuffer = (DEBUG_AGENT_EXCEPTION_BUFFER *)(UINTN)GetMailboxPointer ()->ExceptionBufferPointer;
2415 ExceptionBuffer->ExceptionContent.ExceptionNum = (UINT8)Vector;
2416 ExceptionBuffer->ExceptionContent.ExceptionData = (UINT32)CpuContext->ExceptionData;
2417 LongJump ((BASE_LIBRARY_JUMP_BUFFER *)(UINTN)(ExceptionBuffer), 1);
2418 }
2419 }
2420
2422 //
2423 // If RUN command is executing, wait for it done.
2424 //
2425 while (mDebugMpContext.RunCommandSet) {
2426 CpuPause ();
2427 }
2428 }
2429
2430 Handle = GetDebugPortHandle ();
2431 BreakCause = GetBreakCause (Vector, CpuContext);
2432 switch (Vector) {
2433 case DEBUG_INT1_VECTOR:
2434 case DEBUG_INT3_VECTOR:
2435 switch (BreakCause) {
2436 case DEBUG_DATA_BREAK_CAUSE_SYSTEM_RESET:
2437 if (AttachHost (BreakCause, READ_PACKET_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) {
2438 //
2439 // Try to connect HOST, return if fails
2440 //
2441 break;
2442 }
2443
2444 CommandCommunication (Vector, CpuContext, BreakReceived);
2445 break;
2446
2447 case DEBUG_DATA_BREAK_CAUSE_STEPPING:
2448 //
2449 // Stepping is finished, send Ack package.
2450 //
2452 mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;
2453 }
2454
2455 //
2456 // Clear Stepping Flag and restore EFLAGS.IF
2457 //
2458 CommandSteppingCleanup (CpuContext);
2459 SendAckPacket (DEBUG_COMMAND_OK);
2460 CommandCommunication (Vector, CpuContext, BreakReceived);
2461 break;
2462
2463 case DEBUG_DATA_BREAK_CAUSE_MEMORY_READY:
2464 //
2465 // Memory is ready
2466 //
2467 SendCommandAndWaitForAckOK (DEBUG_COMMAND_MEMORY_READY, READ_PACKET_TIMEOUT, &BreakReceived, NULL);
2468 CommandCommunication (Vector, CpuContext, BreakReceived);
2469 break;
2470
2471 case DEBUG_DATA_BREAK_CAUSE_IMAGE_LOAD:
2472 case DEBUG_DATA_BREAK_CAUSE_IMAGE_UNLOAD:
2473 //
2474 // Set AL to DEBUG_AGENT_IMAGE_CONTINUE
2475 //
2476 Al = ArchReadRegisterBuffer (CpuContext, SOFT_DEBUGGER_REGISTER_AX, &Data8);
2477 *Al = DEBUG_AGENT_IMAGE_CONTINUE;
2478
2479 if (!IsHostAttached ()) {
2480 //
2481 // If HOST is not connected for image load/unload, return
2482 //
2483 break;
2484 }
2485
2486 //
2487 // Continue to run the following common code
2488 //
2489
2490 case DEBUG_DATA_BREAK_CAUSE_HW_BREAKPOINT:
2491 case DEBUG_DATA_BREAK_CAUSE_SW_BREAKPOINT:
2492 default:
2493 //
2494 // Send Break packet to HOST
2495 //
2496 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2497 //
2498 // Only the first breaking processor could send BREAK_POINT to HOST
2499 //
2500 if (IsFirstBreakProcessor (ProcessorIndex)) {
2501 SendBreakPacketToHost (BreakCause, ProcessorIndex, &BreakReceived);
2502 }
2503
2504 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2505
2506 if (Vector == DEBUG_INT3_VECTOR) {
2507 //
2508 // go back address located "0xCC"
2509 //
2510 CpuContext->Eip--;
2511 SavedEip = CpuContext->Eip;
2512 CommandCommunication (Vector, CpuContext, BreakReceived);
2513 if ((SavedEip == CpuContext->Eip) &&
2514 (*(UINT8 *)(UINTN)CpuContext->Eip == DEBUG_SW_BREAKPOINT_SYMBOL))
2515 {
2516 //
2517 // If this is not a software breakpoint set by HOST,
2518 // restore EIP
2519 //
2520 CpuContext->Eip++;
2521 }
2522 } else {
2523 CommandCommunication (Vector, CpuContext, BreakReceived);
2524 }
2525
2526 break;
2527 }
2528
2529 break;
2530
2531 case DEBUG_TIMER_VECTOR:
2532
2533 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2534
2536 if (DebugAgentIsBsp (ProcessorIndex)) {
2537 //
2538 // If current processor is BSP, check Apic timer's init count if changed,
2539 // it may be re-written when switching BSP.
2540 // If it changed, re-initialize debug timer
2541 //
2542 CurrentDebugTimerInitCount = GetApicTimerInitCount ();
2543 if (mDebugMpContext.DebugTimerInitCount != CurrentDebugTimerInitCount) {
2546 }
2547 }
2548
2549 if (!DebugAgentIsBsp (ProcessorIndex) || mDebugMpContext.IpiSentByAp) {
2550 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2551 //
2552 // If current processor is not BSP or this is one IPI sent by AP
2553 //
2554 if (mDebugMpContext.BreakAtCpuIndex != (UINT32)(-1)) {
2555 CommandCommunication (Vector, CpuContext, FALSE);
2556 }
2557
2558 //
2559 // Clear EOI before exiting interrupt process routine.
2560 //
2561 SendApicEoi ();
2562 break;
2563 }
2564 }
2565
2566 //
2567 // Only BSP could run here
2568 //
2569 while (TRUE) {
2570 //
2571 // If there is data in debug port, will check whether it is break(attach/break-in) symbol,
2572 // If yes, go into communication mode with HOST.
2573 // If no, exit interrupt process.
2574 //
2575 if (DebugReadBreakSymbol (Handle, &InputCharacter) == EFI_NOT_FOUND) {
2576 break;
2577 }
2578
2579 if ((!IsHostAttached () && (InputCharacter == DEBUG_STARTING_SYMBOL_ATTACH)) ||
2580 (IsHostAttached () && (InputCharacter == DEBUG_COMMAND_HALT)) ||
2581 (IsHostAttached () && (InputCharacter == DEBUG_COMMAND_GO))
2582 )
2583 {
2584 DebugAgentMsgPrint (DEBUG_AGENT_VERBOSE, "Received data [%02x]\n", InputCharacter);
2585 //
2586 // Ack OK for break-in symbol
2587 //
2588 SendAckPacket (DEBUG_COMMAND_OK);
2589
2590 //
2591 // If receive GO command in Debug Timer, means HOST may lost ACK packet before.
2592 //
2593 if (InputCharacter == DEBUG_COMMAND_GO) {
2594 break;
2595 }
2596
2597 if (!IsHostAttached ()) {
2598 //
2599 // Try to attach HOST, if no ack received after 200ms, return
2600 //
2601 if (AttachHost (BreakCause, READ_PACKET_TIMEOUT, &BreakReceived) != RETURN_SUCCESS) {
2602 break;
2603 }
2604 }
2605
2607 if (FindNextPendingBreakCpu () != -1) {
2608 SetCpuBreakFlagByIndex (ProcessorIndex, TRUE);
2609 } else {
2610 HaltOtherProcessors (ProcessorIndex);
2611 }
2612 }
2613
2614 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2615 CommandCommunication (Vector, CpuContext, BreakReceived);
2616 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2617 break;
2618 }
2619 }
2620
2621 //
2622 // Clear EOI before exiting interrupt process routine.
2623 //
2624 SendApicEoi ();
2625
2626 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2627
2628 break;
2629
2630 default:
2631 if (Vector <= DEBUG_EXCEPT_SIMD) {
2633 DEBUG_AGENT_ERROR,
2634 "Exception happened, ExceptionNum is %d, EIP = 0x%x.\n",
2635 Vector,
2636 (UINTN)CpuContext->Eip
2637 );
2638 if (BreakCause == DEBUG_DATA_BREAK_CAUSE_STEPPING) {
2639 //
2640 // If exception happened when executing Stepping, send Ack package.
2641 // HOST consider Stepping command was finished.
2642 //
2644 mDebugMpContext.BreakAtCpuIndex = ProcessorIndex;
2645 }
2646
2647 //
2648 // Clear Stepping flag and restore EFLAGS.IF
2649 //
2650 CommandSteppingCleanup (CpuContext);
2651 SendAckPacket (DEBUG_COMMAND_OK);
2652 } else {
2653 //
2654 // Exception occurs, send Break packet to HOST
2655 //
2656 AcquireMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2657 //
2658 // Only the first breaking processor could send BREAK_POINT to HOST
2659 //
2660 if (IsFirstBreakProcessor (ProcessorIndex)) {
2661 SendBreakPacketToHost (BreakCause, ProcessorIndex, &BreakReceived);
2662 }
2663
2664 ReleaseMpSpinLock (&mDebugMpContext.DebugPortSpinLock);
2665 }
2666
2667 CommandCommunication (Vector, CpuContext, BreakReceived);
2668 }
2669
2670 break;
2671 }
2672
2674 //
2675 // Clear flag and wait for all processors run here
2676 //
2678 while (mDebugMpContext.RunCommandSet) {
2679 CpuPause ();
2680 }
2681
2682 //
2683 // Only current (view) processor could clean up AgentInProgress flag.
2684 //
2685 if (mDebugMpContext.ViewPointIndex == ProcessorIndex) {
2686 IssuedViewPoint = mDebugMpContext.ViewPointIndex;
2687 }
2688 }
2689
2690 if ((IssuedViewPoint == ProcessorIndex) && (GetDebugFlag (DEBUG_AGENT_FLAG_STEPPING) != 1)) {
2691 //
2692 // If the command is not stepping, clean up AgentInProgress flag
2693 //
2694 SetDebugFlag (DEBUG_AGENT_FLAG_AGENT_IN_PROGRESS, 0);
2695 }
2696
2697 return;
2698}
UINT64 UINTN
UINTN EFIAPI MicroSecondDelay(IN UINTN MicroSeconds)
VOID EFIAPI ResetCold(VOID)
UINT64 EFIAPI DivU64x32(IN UINT64 Dividend, IN UINT32 Divisor)
Definition: DivU64x32.c:29
RETURNS_TWICE UINTN EFIAPI SetJump(OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer)
UINT64 EFIAPI MultU64x64(IN UINT64 Multiplicand, IN UINT64 Multiplier)
Definition: MultU64x64.c:27
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
UINT32 EFIAPI GetPowerOfTwo32(IN UINT32 Operand)
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
UINT8 EFIAPI CalculateSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:33
VOID EFIAPI CpuPause(VOID)
UINT8 EFIAPI CalculateCheckSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
Definition: CheckSum.c:71
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI DivU64x32Remainder(IN UINT64 Dividend, IN UINT32 Divisor, OUT UINT32 *Remainder OPTIONAL)
INTN EFIAPI LowBitSet64(IN UINT64 Operand)
Definition: LowBitSet64.c:27
VOID EFIAPI CpuBreakpoint(VOID)
Definition: CpuBreakpoint.c:26
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID EFIAPI LongJump(IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, IN UINTN Value)
Definition: LongJump.c:29
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
Definition: SetMemWrapper.c:38
UINT32 EFIAPI AsmCpuidEx(IN UINT32 Index, IN UINT32 SubIndex, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuIdEx.c:43
VOID SendAckPacket(IN UINT8 AckCommand)
Definition: DebugAgent.c:1019
VOID UpdateMailboxContent(IN DEBUG_AGENT_MAILBOX *Mailbox, IN UINTN Index, IN UINT64 Value)
Definition: DebugAgent.c:300
UINT8 DecompressDataInPlace(IN OUT UINT8 *Data, IN UINTN Length)
Definition: DebugAgent.c:1050
UINT32 GetDebugFlag(IN UINT64 FlagMask)
Definition: DebugAgent.c:458
UINT8 * ArchReadRegisterBuffer(IN DEBUG_CPU_CONTEXT *CpuContext, IN UINT8 Index, OUT UINT8 *Width)
Definition: DebugAgent.c:962
VOID CompressData(IN DEBUG_PORT_HANDLE Handle, IN UINT8 *Data, IN UINT8 Length, IN BOOLEAN Send, OUT UINTN *CompressedLength OPTIONAL, OUT UINT16 *CompressedCrc OPTIONAL)
Definition: DebugAgent.c:1460
VOID EFIAPI DebugAgentMsgPrint(IN UINT8 ErrorLevel, IN CHAR8 *Format,...)
Definition: DebugAgent.c:518
VOID SetDebugRegister(IN DEBUG_CPU_CONTEXT *CpuContext, IN DEBUG_DATA_SET_HW_BREAKPOINT *SetHwBreakpoint)
Definition: DebugAgent.c:809
BOOLEAN IsHostAttached(VOID)
Definition: DebugAgent.c:676
UINT16 CalculateCrc16(IN UINT8 *Data, IN UINTN DataSize, IN UINT16 Crc)
Definition: DebugAgent.c:140
VOID CommandSteppingCleanup(IN DEBUG_CPU_CONTEXT *CpuContext)
Definition: DebugAgent.c:784
VOID VerifyMailboxChecksum(IN DEBUG_AGENT_MAILBOX *Mailbox)
Definition: DebugAgent.c:273
VOID CommandStepping(IN DEBUG_CPU_CONTEXT *CpuContext)
Definition: DebugAgent.c:757
RETURN_STATUS SendDataResponsePacket(IN UINT8 *Data, IN UINT16 DataSize, IN OUT DEBUG_PACKET_HEADER *DebugHeader)
Definition: DebugAgent.c:1688
VOID SendDebugMsgPacket(IN CHAR8 *Buffer, IN UINTN Length)
Definition: DebugAgent.c:479
VOID UpdateMailboxChecksum(IN DEBUG_AGENT_MAILBOX *Mailbox)
Definition: DebugAgent.c:257
RETURN_STATUS SetDebugSetting(IN DEBUG_DATA_SET_DEBUG_SETTING *DebugSetting)
Definition: DebugAgent.c:708
VOID ClearDebugRegister(IN DEBUG_CPU_CONTEXT *CpuContext, IN DEBUG_DATA_CLEAR_HW_BREAKPOINT *ClearHwBreakpoint)
Definition: DebugAgent.c:851
VOID EFIAPI DebugAgentDataMsgPrint(IN UINT8 ErrorLevel, IN BOOLEAN IsSend, IN UINT8 *Data, IN UINT8 Length)
Definition: DebugAgent.c:561
RETURN_STATUS ReceivePacket(OUT UINT8 *InputPacket, OUT BOOLEAN *BreakReceived, OUT BOOLEAN *IncompatibilityFlag OPTIONAL, IN UINTN Timeout, IN BOOLEAN SkipStartSymbol)
Definition: DebugAgent.c:1105
VOID CopyMemByWidth(OUT UINT8 *Dest, IN UINT8 *Src, IN UINT16 Count, IN UINT8 Width)
Definition: DebugAgent.c:1393
RETURN_STATUS ReadMemoryAndSendResponsePacket(IN UINT8 *Data, IN UINT16 Count, IN UINT8 Width, IN DEBUG_PACKET_HEADER *DebugHeader)
Definition: DebugAgent.c:1537
VOID CommandGo(IN DEBUG_CPU_CONTEXT *CpuContext)
Definition: DebugAgent.c:739
VOID SendPacketWithoutData(IN UINT8 CommandType, IN UINT8 SequenceNo)
Definition: DebugAgent.c:991
RETURN_STATUS SendCommandAndWaitForAckOK(IN UINT8 Command, IN UINTN Timeout, OUT BOOLEAN *BreakReceived OPTIONAL, OUT BOOLEAN *IncompatibilityFlag OPTIONAL)
Definition: DebugAgent.c:1224
VOID SetDebugFlag(IN UINT64 FlagMask, IN UINT32 FlagValue)
Definition: DebugAgent.c:435
VOID CommandCommunication(IN UINTN Vector, IN OUT DEBUG_CPU_CONTEXT *CpuContext, IN BOOLEAN BreakReceived)
Definition: DebugAgent.c:1819
VOID FindAndReportModuleImageInfo(IN UINTN AlignSize)
Definition: DebugAgent.c:193
UINTN DebugAgentReadBuffer(IN DEBUG_PORT_HANDLE Handle, IN UINT8 *Buffer, IN UINTN NumberOfBytes, IN UINTN Timeout)
Definition: DebugAgent.c:367
VOID EFIAPI InterruptProcess(IN UINT32 Vector, IN DEBUG_CPU_CONTEXT *CpuContext)
Definition: DebugAgent.c:2357
VOID SetHostAttached(IN BOOLEAN Attached)
Definition: DebugAgent.c:690
BOOLEAN IsDebugAgentInitialzed(VOID)
Definition: DebugAgent.c:172
RETURN_STATUS AttachHost(IN UINT8 BreakCause, IN UINTN Timeout, OUT BOOLEAN *BreakReceived)
Definition: DebugAgent.c:1713
VOID TriggerSoftInterrupt(IN UINT32 Signature)
Definition: DebugAgent.c:218
UINT16 ArchReadFxStatOffset(IN UINT8 Index, OUT UINT8 *Width)
Definition: DebugAgent.c:887
UINT8 GetBreakCause(IN UINTN Vector, IN DEBUG_CPU_CONTEXT *CpuContext)
Definition: DebugAgent.c:1294
EFI_STATUS ReadRemainingBreakPacket(IN DEBUG_PORT_HANDLE Handle, IN OUT DEBUG_PACKET_HEADER *DebugHeader)
Definition: DebugAgent.c:623
VOID SendBreakPacketToHost(IN UINT8 BreakCause, IN UINT32 ProcessorIndex, OUT BOOLEAN *BreakReceived)
Definition: DebugAgent.c:1771
DEBUG_AGENT_MAILBOX * GetMailboxPointer(VOID)
BOOLEAN MultiProcessorDebugSupport(VOID)
VOID * GetExceptionHandlerInIdtEntry(IN UINTN ExceptionNum)
DEBUG_PORT_HANDLE GetDebugPortHandle(VOID)
EFI_STATUS DebugReadBreakSymbol(IN DEBUG_PORT_HANDLE Handle, OUT UINT8 *BreakSymbol)
Definition: SerialIo.c:806
#define EFI_DEBUG_AGENT_GUID
BOOLEAN EFIAPI SaveAndSetDebugTimerInterrupt(IN BOOLEAN EnableStatus)
UINTN EFIAPI DebugPortReadBuffer(IN DEBUG_PORT_HANDLE Handle, IN UINT8 *Buffer, IN UINTN NumberOfBytes, IN UINTN Timeout)
BOOLEAN EFIAPI DebugPortPollBuffer(IN DEBUG_PORT_HANDLE Handle)
UINTN EFIAPI DebugPortWriteBuffer(IN DEBUG_PORT_HANDLE Handle, IN UINT8 *Buffer, IN UINTN NumberOfBytes)
VOID SetCpuStopFlagByIndex(IN UINT32 ProcessorIndex, IN BOOLEAN StopFlag)
Definition: DebugMp.c:172
VOID SetDebugViewPoint(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:276
UINT32 FindNextPendingBreakCpu(VOID)
Definition: DebugMp.c:311
VOID HaltOtherProcessors(IN UINT32 CurrentProcessorIndex)
Definition: DebugMp.c:68
UINT32 GetProcessorIndex(VOID)
Definition: DebugMp.c:97
BOOLEAN IsFirstBreakProcessor(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:361
BOOLEAN DebugAgentIsBsp(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:134
VOID ReleaseMpSpinLock(IN OUT SPIN_LOCK *MpSpinLock)
Definition: DebugMp.c:50
VOID AcquireMpSpinLock(IN OUT SPIN_LOCK *MpSpinLock)
Definition: DebugMp.c:25
VOID SetCpuRunningFlag(IN BOOLEAN RunningFlag)
Definition: DebugMp.c:260
BOOLEAN IsAllCpuRunning(VOID)
Definition: DebugMp.c:334
VOID SetCpuBreakFlagByIndex(IN UINT32 ProcessorIndex, IN BOOLEAN BreakFlag)
Definition: DebugMp.c:204
BOOLEAN IsCpuStopped(IN UINT32 ProcessorIndex)
Definition: DebugMp.c:237
VOID SetIpiSentByApFlag(IN BOOLEAN IpiSentByApFlag)
Definition: DebugMp.c:293
VOID EFIAPI PeCoffLoaderRelocateImageExtraAction(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
UINT32 InitializeDebugTimer(OUT UINT32 *TimerFrequency, IN BOOLEAN DumpFlag)
Definition: DebugTimer.c:20
BOOLEAN IsDebugTimerTimeout(IN UINT32 TimerCycle, IN UINT32 Timer, IN UINT32 TimeoutTicker)
Definition: DebugTimer.c:119
UINTN EFIAPI AsmWriteDr1(UINTN Dr1)
UINTN EFIAPI AsmReadDr1(VOID)
UINTN EFIAPI AsmReadDr0(VOID)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
UINTN EFIAPI AsmWriteDr0(UINTN Dr0)
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
Definition: IoLibArmVirt.c:200
UINT64 EFIAPI IoRead64(IN UINTN Port)
Definition: IoLib.c:29
UINT64 EFIAPI IoWrite64(IN UINTN Port, IN UINT64 Value)
Definition: IoLib.c:55
UINT64 EFIAPI MmioRead64(IN UINTN Address)
Definition: IoLib.c:355
UINT16 EFIAPI MmioRead16(IN UINTN Address)
Definition: IoLib.c:170
UINT8 EFIAPI MmioRead8(IN UINTN Address)
Definition: IoLib.c:82
UINT8 EFIAPI IoRead8(IN UINTN Port)
Definition: IoLibArmVirt.c:175
UINT32 EFIAPI MmioRead32(IN UINTN Address)
Definition: IoLib.c:262
UINT16 EFIAPI IoRead16(IN UINTN Port)
Definition: IoLibArmVirt.c:225
UINT32 EFIAPI IoRead32(IN UINTN Port)
Definition: IoLibArmVirt.c:275
UINT32 EFIAPI IoWrite32(IN UINTN Port, IN UINT32 Value)
Definition: IoLibArmVirt.c:300
UINT16 EFIAPI IoWrite16(IN UINTN Port, IN UINT16 Value)
Definition: IoLibArmVirt.c:250
UINT32 EFIAPI GetApicTimerInitCount(VOID)
Definition: BaseXApicLib.c:698
VOID EFIAPI SendApicEoi(VOID)
Definition: BaseXApicLib.c:885
UINT32 EFIAPI GetApicTimerCurrentCount(VOID)
Definition: BaseXApicLib.c:712
UINTN EFIAPI AsciiVSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString, IN VA_LIST Marker)
Definition: PrintLib.c:702
UINTN EFIAPI AsciiSPrint(OUT CHAR8 *StartOfBuffer, IN UINTN BufferSize, IN CONST CHAR8 *FormatString,...)
Definition: PrintLib.c:813
#define NULL
Definition: Base.h:319
#define RETURN_ERROR(StatusCode)
Definition: Base.h:1061
#define RETURN_UNSUPPORTED
Definition: Base.h:1081
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define VA_START(Marker, Parameter)
Definition: Base.h:661
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define RETURN_TIMEOUT
Definition: Base.h:1162
CHAR8 * VA_LIST
Definition: Base.h:643
#define IN
Definition: Base.h:279
#define OFFSET_OF(TYPE, Field)
Definition: Base.h:758
#define OUT
Definition: Base.h:284
#define GLOBAL_REMOVE_IF_UNREFERENCED
Definition: Base.h:48
#define VA_END(Marker)
Definition: Base.h:691
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
UINTN EFIAPI PeCoffSearchImageBase(IN UINTN Address)
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
#define EFI_VECTOR_HANDOFF_DO_NOT_HOOK
UINT32 ViewPointIndex
Current view point to be debugged.
Definition: DebugMp.h:25
BOOLEAN IpiSentByAp
TRUE: IPI is sent by AP. FALSE: IPI is sent by BSP.
Definition: DebugMp.h:29
SPIN_LOCK MailboxSpinLock
Lock for accessing mail box.
Definition: DebugMp.h:22
UINT32 DebugTimerInitCount
Record BSP's init timer count.
Definition: DebugMp.h:28
UINT32 BspIndex
Processor index value of BSP.
Definition: DebugMp.h:26
BOOLEAN RunCommandSet
TRUE: RUN command is executing. FALSE: RUN command has been executed.
Definition: DebugMp.h:30
SPIN_LOCK DebugPortSpinLock
Lock for access debug port.
Definition: DebugMp.h:21
UINT32 BreakAtCpuIndex
Processor index value of the current breaking CPU.
Definition: DebugMp.h:27
PHYSICAL_ADDRESS ImageAddress
Definition: PeCoffLib.h:79