2 Processor specific parts of the GDB stub
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
16 #include <GdbDebugAgent.h>
19 // Array of exception types that need to be hooked by the debugger
20 // {EFI mapping, GDB mapping}
22 EFI_EXCEPTION_TYPE_ENTRY gExceptionType
[] = {
23 { EXCEPT_IA32_DIVIDE_ERROR
, GDB_SIGFPE
},
24 { EXCEPT_IA32_DEBUG
, GDB_SIGTRAP
},
25 { EXCEPT_IA32_NMI
, GDB_SIGEMT
},
26 { EXCEPT_IA32_BREAKPOINT
, GDB_SIGTRAP
},
27 { EXCEPT_IA32_OVERFLOW
, GDB_SIGSEGV
},
28 { EXCEPT_IA32_BOUND
, GDB_SIGSEGV
},
29 { EXCEPT_IA32_INVALID_OPCODE
, GDB_SIGILL
},
30 { EXCEPT_IA32_DOUBLE_FAULT
, GDB_SIGEMT
},
31 { EXCEPT_IA32_STACK_FAULT
, GDB_SIGSEGV
},
32 { EXCEPT_IA32_GP_FAULT
, GDB_SIGSEGV
},
33 { EXCEPT_IA32_PAGE_FAULT
, GDB_SIGSEGV
},
34 { EXCEPT_IA32_FP_ERROR
, GDB_SIGEMT
},
35 { EXCEPT_IA32_ALIGNMENT_CHECK
, GDB_SIGEMT
},
36 { EXCEPT_IA32_MACHINE_CHECK
, GDB_SIGEMT
}
40 // The offsets of registers SystemContext.
41 // The fields in the array are in the gdb ordering.
44 UINTN gRegisterOffsets
[] = {
45 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Eax
),
46 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Ecx
),
47 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Edx
),
48 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Ebx
),
49 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Esp
),
50 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Ebp
),
51 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Esi
),
52 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Edi
),
53 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Eip
),
54 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Eflags
),
55 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Cs
),
56 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Ss
),
57 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Ds
),
58 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Es
),
59 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Fs
),
60 OFFSET_OF(EFI_SYSTEM_CONTEXT_IA32
, Gs
)
67 IN EFI_SYSTEM_CONTEXT SystemContext
70 Print ((CHAR16
*)L
"EAX: %x ", SystemContext
.SystemContextIa32
->Eax
);
71 Print ((CHAR16
*)L
"ECX: %x ", SystemContext
.SystemContextIa32
->Ecx
);
72 Print ((CHAR16
*)L
"EDX: %x ", SystemContext
.SystemContextIa32
->Edx
);
73 Print ((CHAR16
*)L
"EBX: %x ", SystemContext
.SystemContextIa32
->Ebx
);
74 Print ((CHAR16
*)L
"ESP: %x ", SystemContext
.SystemContextIa32
->Esp
);
75 Print ((CHAR16
*)L
"EBP: %x ", SystemContext
.SystemContextIa32
->Ebp
);
76 Print ((CHAR16
*)L
"ESI: %x ", SystemContext
.SystemContextIa32
->Esi
);
77 Print ((CHAR16
*)L
"EDI: %x ", SystemContext
.SystemContextIa32
->Edi
);
78 Print ((CHAR16
*)L
"EIP: %x\n", SystemContext
.SystemContextIa32
->Eip
);
79 Print ((CHAR16
*)L
"EFlags: %x\n", SystemContext
.SystemContextIa32
->Eflags
);
85 IN EFI_SYSTEM_CONTEXT SystemContext
88 Print ((CHAR16
*)L
"DR0: %x ", SystemContext
.SystemContextIa32
->Dr0
);
89 Print ((CHAR16
*)L
"DR1: %x ", SystemContext
.SystemContextIa32
->Dr1
);
90 Print ((CHAR16
*)L
"DR2: %x ", SystemContext
.SystemContextIa32
->Dr2
);
91 Print ((CHAR16
*)L
"DR3: %x ", SystemContext
.SystemContextIa32
->Dr3
);
92 Print ((CHAR16
*)L
"DR6: %x ", SystemContext
.SystemContextIa32
->Dr6
);
93 Print ((CHAR16
*)L
"DR7: %x\n", SystemContext
.SystemContextIa32
->Dr7
);
98 Return the number of entries in the gExceptionType[]
100 @retval UINTN, the number of entries in the gExceptionType[] array.
107 return sizeof (gExceptionType
)/sizeof (EFI_EXCEPTION_TYPE_ENTRY
);
112 Check to see if the ISA is supported.
113 ISA = Instruction Set Architecture
115 @retval TRUE if Isa is supported,
120 IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
123 return (BOOLEAN
)(Isa
== IsaIa32
);
128 This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
129 It is, by default, set to find the register pointer of the IA32 member
131 @param SystemContext Register content at time of the exception
132 @param RegNumber The register to which we want to find a pointer
133 @retval the pointer to the RegNumber-th pointer
136 FindPointerToRegister(
137 IN EFI_SYSTEM_CONTEXT SystemContext
,
142 TempPtr
= ((UINT8
*)SystemContext
.SystemContextIa32
) + gRegisterOffsets
[RegNumber
];
143 return (UINTN
*)TempPtr
;
148 Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
150 @param SystemContext Register content at time of the exception
151 @param RegNumber the number of the register that we want to read
152 @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
153 @retval the pointer to the next character of the output buffer that is available to be written on.
157 IN EFI_SYSTEM_CONTEXT SystemContext
,
165 while (RegSize
< REG_SIZE
) {
166 *OutBufPtr
++ = mHexToStr
[((*FindPointerToRegister(SystemContext
, RegNumber
) >> (RegSize
+4)) & 0xf)];
167 *OutBufPtr
++ = mHexToStr
[((*FindPointerToRegister(SystemContext
, RegNumber
) >> RegSize
) & 0xf)];
168 RegSize
= RegSize
+ 8;
175 Reads the n-th register's value into an output buffer and sends it as a packet
177 @param SystemContext Register content at time of the exception
178 @param InBuffer Pointer to the input buffer received from gdb server
183 IN EFI_SYSTEM_CONTEXT SystemContext
,
188 CHAR8 OutBuffer
[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
189 CHAR8
*OutBufPtr
; // pointer to the output buffer
191 RegNumber
= AsciiStrHexToUintn (&InBuffer
[1]);
193 if ((RegNumber
< 0) || (RegNumber
>= sizeof (gRegisterOffsets
)/sizeof (UINTN
))) {
194 SendError (GDB_EINVALIDREGNUM
);
198 OutBufPtr
= OutBuffer
;
199 OutBufPtr
= BasicReadRegister(SystemContext
, RegNumber
, OutBufPtr
);
201 *OutBufPtr
= '\0'; // the end of the buffer
202 SendPacket(OutBuffer
);
207 Reads the general registers into an output buffer and sends it as a packet
209 @param SystemContext Register content at time of the exception
213 ReadGeneralRegisters (
214 IN EFI_SYSTEM_CONTEXT SystemContext
218 CHAR8 OutBuffer
[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
219 CHAR8
*OutBufPtr
; // pointer to the output buffer
221 OutBufPtr
= OutBuffer
;
222 for(i
= 0 ; i
< sizeof (gRegisterOffsets
)/sizeof (UINTN
) ; i
++) { // there are only 16 registers to read
223 OutBufPtr
= BasicReadRegister(SystemContext
, i
, OutBufPtr
);
226 *OutBufPtr
= '\0'; // the end of the buffer
227 SendPacket(OutBuffer
);
232 Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
234 @param SystemContext Register content at time of the exception
235 @param RegNumber the number of the register that we want to write
236 @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
237 @retval the pointer to the next character of the input buffer that can be used
241 IN EFI_SYSTEM_CONTEXT SystemContext
,
247 UINTN TempValue
; // the value transferred from a hex char
248 UINT32 NewValue
; // the new value of the RegNumber-th Register
252 while (RegSize
< REG_SIZE
) {
253 TempValue
= HexCharToInt(*InBufPtr
++);
256 SendError (GDB_EBADMEMDATA
);
260 NewValue
+= (TempValue
<< (RegSize
+4));
261 TempValue
= HexCharToInt(*InBufPtr
++);
264 SendError (GDB_EBADMEMDATA
);
268 NewValue
+= (TempValue
<< RegSize
);
269 RegSize
= RegSize
+ 8;
271 *(FindPointerToRegister(SystemContext
, RegNumber
)) = NewValue
;
277 Writes the new value of n-th register received into the input buffer to the n-th register
279 @param SystemContext Register content at time of the exception
280 @param InBuffer Ponter to the input buffer received from gdb server
285 IN EFI_SYSTEM_CONTEXT SystemContext
,
290 CHAR8 RegNumBuffer
[MAX_REG_NUM_BUF_SIZE
]; // put the 'n..' part of the message into this array
292 CHAR8
*InBufPtr
; // pointer to the input buffer
294 // find the register number to write
295 InBufPtr
= &InBuffer
[1];
296 RegNumBufPtr
= RegNumBuffer
;
297 while (*InBufPtr
!= '=') {
298 *RegNumBufPtr
++ = *InBufPtr
++;
300 *RegNumBufPtr
= '\0';
301 RegNumber
= AsciiStrHexToUintn (RegNumBuffer
);
303 // check if this is a valid Register Number
304 if ((RegNumber
< 0) || (RegNumber
>= sizeof (gRegisterOffsets
)/sizeof (UINTN
))) {
305 SendError (GDB_EINVALIDREGNUM
);
308 InBufPtr
++; // skips the '=' character
309 BasicWriteRegister (SystemContext
, RegNumber
, InBufPtr
);
315 Writes the new values received into the input buffer to the general registers
317 @param SystemContext Register content at time of the exception
318 @param InBuffer Pointer to the input buffer received from gdb server
322 WriteGeneralRegisters (
323 IN EFI_SYSTEM_CONTEXT SystemContext
,
328 CHAR8
*InBufPtr
; /// pointer to the input buffer
330 // check to see if the buffer is the right size which is
331 // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
332 if (AsciiStrLen(InBuffer
) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
333 //Bad message. Message is not the right length
334 SendError (GDB_EBADBUFSIZE
);
338 InBufPtr
= &InBuffer
[1];
340 // Read the new values for the registers from the input buffer to an array, NewValueArray.
341 // The values in the array are in the gdb ordering
342 for(i
=0; i
< sizeof (gRegisterOffsets
)/sizeof (UINTN
); i
++) { // there are only 16 registers to write
343 InBufPtr
= BasicWriteRegister(SystemContext
, i
, InBufPtr
);
350 Continue. addr is Address to resume. If addr is omitted, resume at current
353 @param SystemContext Register content at time of the exception
358 IN EFI_SYSTEM_CONTEXT SystemContext
,
362 if (PacketData
[1] != '\0') {
363 SystemContext
.SystemContextIa32
->Eip
= AsciiStrHexToUintn (&PacketData
[1]);
369 Single step. addr is the Address at which to resume. If addr is omitted, resume
372 @param SystemContext Register content at time of the exception
377 IN EFI_SYSTEM_CONTEXT SystemContext
,
386 Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
388 @param SystemContext Register content at time of the exception
389 @param BreakpointNumber Breakpoint number
391 @retval Address Data address from DR0-DR3 based on the breakpoint number.
395 GetBreakpointDataAddress (
396 IN EFI_SYSTEM_CONTEXT SystemContext
,
397 IN UINTN BreakpointNumber
402 if (BreakpointNumber
== 1) {
403 Address
= SystemContext
.SystemContextIa32
->Dr0
;
404 } else if (BreakpointNumber
== 2) {
405 Address
= SystemContext
.SystemContextIa32
->Dr1
;
406 } else if (BreakpointNumber
== 3) {
407 Address
= SystemContext
.SystemContextIa32
->Dr2
;
408 } else if (BreakpointNumber
== 4) {
409 Address
= SystemContext
.SystemContextIa32
->Dr3
;
419 Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
420 If no breakpoint is detected then it returns 0.
422 @param SystemContext Register content at time of the exception
424 @retval {1-4} Currently detected breakpoint value
425 @retval 0 No breakpoint detected.
429 GetBreakpointDetected (
430 IN EFI_SYSTEM_CONTEXT SystemContext
434 UINTN BreakpointNumber
;
436 Dr6
.UintN
= SystemContext
.SystemContextIa32
->Dr6
;
438 if (Dr6
.Bits
.B0
== 1) {
439 BreakpointNumber
= 1;
440 } else if (Dr6
.Bits
.B1
== 1) {
441 BreakpointNumber
= 2;
442 } else if (Dr6
.Bits
.B2
== 1) {
443 BreakpointNumber
= 3;
444 } else if (Dr6
.Bits
.B3
== 1) {
445 BreakpointNumber
= 4;
447 BreakpointNumber
= 0; //No breakpoint detected
450 return BreakpointNumber
;
455 Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
456 based on the Breakpoint number
458 @param SystemContext Register content at time of the exception
459 @param BreakpointNumber Breakpoint number
461 @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
462 For unknown value, it returns NotSupported.
467 IN EFI_SYSTEM_CONTEXT SystemContext
,
468 IN UINTN BreakpointNumber
472 BREAK_TYPE Type
= NotSupported
; //Default is NotSupported type
474 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
476 if (BreakpointNumber
== 1) {
477 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW0
;
478 } else if (BreakpointNumber
== 2) {
479 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW1
;
480 } else if (BreakpointNumber
== 3) {
481 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW2
;
482 } else if (BreakpointNumber
== 4) {
483 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW3
;
491 Parses Length and returns the length which DR7 LENn field accepts.
492 For example: If we receive 1-Byte length then we should return 0.
493 Zero gets written to DR7 LENn field.
495 @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
497 @retval Length Appropriate converted values which DR7 LENn field accepts.
505 if (Length
== 1) { //1-Byte length
507 } else if (Length
== 2) { //2-Byte length
509 } else if (Length
== 4) { //4-Byte length
511 } else { //Undefined or 8-byte length
518 Finds the next free debug register. If all the registers are occupied then
519 EFI_OUT_OF_RESOURCES is returned.
521 @param SystemContext Register content at time of the exception
522 @param Register Register value (0 - 3 for the first free debug register)
524 @retval EFI_STATUS Appropriate status value.
528 FindNextFreeDebugRegister (
529 IN EFI_SYSTEM_CONTEXT SystemContext
,
535 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
537 if (Dr7
.Bits
.G0
== 0) {
539 } else if (Dr7
.Bits
.G1
== 0) {
541 } else if (Dr7
.Bits
.G2
== 0) {
543 } else if (Dr7
.Bits
.G3
== 0) {
546 return EFI_OUT_OF_RESOURCES
;
554 Enables the debug register. Writes Address value to appropriate DR0-3 register.
555 Sets LENn, Gn, RWn bits in DR7 register.
557 @param SystemContext Register content at time of the exception
558 @param Register Register value (0 - 3)
559 @param Address Breakpoint address value
560 @param Type Breakpoint type (Instruction, Data write, Data read
563 @retval EFI_STATUS Appropriate status value.
567 EnableDebugRegister (
568 IN EFI_SYSTEM_CONTEXT SystemContext
,
577 //Convert length data
578 Length
= ConvertLengthData (Length
);
580 //For Instruction execution, length should be 0
581 //(Ref. Intel reference manual 18.2.4)
582 if ((Type
== 0) && (Length
!= 0)) {
583 return EFI_INVALID_PARAMETER
;
586 //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
587 //software breakpoint. We should send empty packet in both these cases.
588 if ((Type
== (BREAK_TYPE
)DataRead
) ||
589 (Type
== (BREAK_TYPE
)SoftwareBreakpoint
)) {
590 return EFI_UNSUPPORTED
;
593 //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
594 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
597 SystemContext
.SystemContextIa32
->Dr0
= Address
;
600 Dr7
.Bits
.LEN0
= Length
;
601 } else if (Register
== 1) {
602 SystemContext
.SystemContextIa32
->Dr1
= Address
;
605 Dr7
.Bits
.LEN1
= Length
;
606 } else if (Register
== 2) {
607 SystemContext
.SystemContextIa32
->Dr2
= Address
;
610 Dr7
.Bits
.LEN2
= Length
;
611 } else if (Register
== 3) {
612 SystemContext
.SystemContextIa32
->Dr3
= Address
;
615 Dr7
.Bits
.LEN3
= Length
;
617 return EFI_INVALID_PARAMETER
;
620 //Update Dr7 with appropriate Gn, RWn and LENn bits
621 SystemContext
.SystemContextIa32
->Dr7
= Dr7
.UintN
;
628 Returns register number 0 - 3 for the maching debug register.
629 This function compares incoming Address, Type, Length and
630 if there is a match then it returns the appropriate register number.
631 In case of mismatch, function returns EFI_NOT_FOUND message.
633 @param SystemContext Register content at time of the exception
634 @param Address Breakpoint address value
635 @param Length Breakpoint length value
636 @param Type Breakpoint type (Instruction, Data write,
637 Data read or write etc.)
638 @param Register Register value to be returned
640 @retval EFI_STATUS Appropriate status value.
644 FindMatchingDebugRegister (
645 IN EFI_SYSTEM_CONTEXT SystemContext
,
654 //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
655 //software breakpoint. We should send empty packet in both these cases.
656 if ((Type
== (BREAK_TYPE
)DataRead
) ||
657 (Type
== (BREAK_TYPE
)SoftwareBreakpoint
)) {
658 return EFI_UNSUPPORTED
;
661 //Convert length data
662 Length
= ConvertLengthData(Length
);
664 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
666 if ((Dr7
.Bits
.G0
== 1) &&
667 (Dr7
.Bits
.LEN0
== Length
) &&
668 (Dr7
.Bits
.RW0
== Type
) &&
669 (Address
== SystemContext
.SystemContextIa32
->Dr0
)) {
671 } else if ((Dr7
.Bits
.G1
== 1) &&
672 (Dr7
.Bits
.LEN1
== Length
) &&
673 (Dr7
.Bits
.RW1
== Type
) &&
674 (Address
== SystemContext
.SystemContextIa32
->Dr1
)) {
676 } else if ((Dr7
.Bits
.G2
== 1) &&
677 (Dr7
.Bits
.LEN2
== Length
) &&
678 (Dr7
.Bits
.RW2
== Type
) &&
679 (Address
== SystemContext
.SystemContextIa32
->Dr2
)) {
681 } else if ((Dr7
.Bits
.G3
== 1) &&
682 (Dr7
.Bits
.LEN3
== Length
) &&
683 (Dr7
.Bits
.RW3
== Type
) &&
684 (Address
== SystemContext
.SystemContextIa32
->Dr3
)) {
687 Print ((CHAR16
*)L
"No match found..\n");
688 return EFI_NOT_FOUND
;
696 Disables the particular debug register.
698 @param SystemContext Register content at time of the exception
699 @param Register Register to be disabled
701 @retval EFI_STATUS Appropriate status value.
705 DisableDebugRegister (
706 IN EFI_SYSTEM_CONTEXT SystemContext
,
713 //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
714 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
717 SystemContext
.SystemContextIa32
->Dr0
= Address
;
721 } else if (Register
== 1) {
722 SystemContext
.SystemContextIa32
->Dr1
= Address
;
726 } else if (Register
== 2) {
727 SystemContext
.SystemContextIa32
->Dr2
= Address
;
731 } else if (Register
== 3) {
732 SystemContext
.SystemContextIa32
->Dr3
= Address
;
737 return EFI_INVALID_PARAMETER
;
740 //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
741 SystemContext
.SystemContextIa32
->Dr7
= Dr7
.UintN
;
748 ‘Z1, [addr], [length]’
749 ‘Z2, [addr], [length]’
750 ‘Z3, [addr], [length]’
751 ‘Z4, [addr], [length]’
753 Insert hardware breakpoint/watchpoint at address addr of size length
755 @param SystemContext Register content at time of the exception
756 @param *PacketData Pointer to the Payload data for the packet
762 IN EFI_SYSTEM_CONTEXT SystemContext
,
771 BREAK_TYPE BreakType
= NotSupported
;
774 ErrorCode
= ParseBreakpointPacket (PacketData
, &Type
, &Address
, &Length
);
776 SendError ((UINT8
)ErrorCode
);
782 case 0: //Software breakpoint
783 BreakType
= SoftwareBreakpoint
;
786 case 1: //Hardware breakpoint
787 BreakType
= InstructionExecution
;
790 case 2: //Write watchpoint
791 BreakType
= DataWrite
;
794 case 3: //Read watchpoint
795 BreakType
= DataRead
;
798 case 4: //Access watchpoint
799 BreakType
= DataReadWrite
;
803 Print ((CHAR16
*)L
"Insert breakpoint default: %x\n", Type
);
804 SendError (GDB_EINVALIDBRKPOINTTYPE
);
808 // Find next free debug register
809 Status
= FindNextFreeDebugRegister (SystemContext
, &Register
);
810 if (EFI_ERROR(Status
)) {
811 Print ((CHAR16
*)L
"No space left on device\n");
812 SendError (GDB_ENOSPACE
);
816 // Write Address, length data at particular DR register
817 Status
= EnableDebugRegister (SystemContext
, Register
, Address
, Length
, (UINTN
)BreakType
);
818 if (EFI_ERROR(Status
)) {
819 if (Status
== EFI_UNSUPPORTED
) {
824 SendError (GDB_EINVALIDARG
);
833 ‘z1, [addr], [length]’
834 ‘z2, [addr], [length]’
835 ‘z3, [addr], [length]’
836 ‘z4, [addr], [length]’
838 Remove hardware breakpoint/watchpoint at address addr of size length
840 @param *PacketData Pointer to the Payload data for the packet
846 IN EFI_SYSTEM_CONTEXT SystemContext
,
854 BREAK_TYPE BreakType
= NotSupported
;
858 //Parse breakpoint packet data
859 ErrorCode
= ParseBreakpointPacket (PacketData
, &Type
, &Address
, &Length
);
861 SendError ((UINT8
)ErrorCode
);
867 case 0: //Software breakpoint
868 BreakType
= SoftwareBreakpoint
;
871 case 1: //Hardware breakpoint
872 BreakType
= InstructionExecution
;
875 case 2: //Write watchpoint
876 BreakType
= DataWrite
;
879 case 3: //Read watchpoint
880 BreakType
= DataRead
;
883 case 4: //Access watchpoint
884 BreakType
= DataReadWrite
;
888 SendError (GDB_EINVALIDBRKPOINTTYPE
);
892 //Find matching debug register
893 Status
= FindMatchingDebugRegister (SystemContext
, Address
, Length
, (UINTN
)BreakType
, &Register
);
894 if (EFI_ERROR(Status
)) {
895 if (Status
== EFI_UNSUPPORTED
) {
900 SendError (GDB_ENOSPACE
);
905 Status
= DisableDebugRegister(SystemContext
, Register
);
906 if (EFI_ERROR(Status
)) {
907 SendError (GDB_EINVALIDARG
);
916 Initialize debug agent.
918 This function is used to set up debug enviroment. It may enable interrupts.
920 @param[in] InitFlag Init flag is used to decide initialize process.
921 @param[in] Context Context needed according to InitFlag, it was optional.
926 InitializeDebugAgent (
928 IN VOID
*Context OPTIONAL
931 // BugBug: Add the code to build an GDT/IDT