2 Processor specific parts of the GDB stub
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
10 #include <GdbStubInternal.h>
13 // Array of exception types that need to be hooked by the debugger
14 // {EFI mapping, GDB mapping}
16 EFI_EXCEPTION_TYPE_ENTRY gExceptionType
[] = {
17 { EXCEPT_IA32_DIVIDE_ERROR
, GDB_SIGFPE
},
18 { EXCEPT_IA32_DEBUG
, GDB_SIGTRAP
},
19 { EXCEPT_IA32_NMI
, GDB_SIGEMT
},
20 { EXCEPT_IA32_BREAKPOINT
, GDB_SIGTRAP
},
21 { EXCEPT_IA32_OVERFLOW
, GDB_SIGSEGV
},
22 { EXCEPT_IA32_BOUND
, GDB_SIGSEGV
},
23 { EXCEPT_IA32_INVALID_OPCODE
, GDB_SIGILL
},
24 { EXCEPT_IA32_DOUBLE_FAULT
, GDB_SIGEMT
},
25 { EXCEPT_IA32_STACK_FAULT
, GDB_SIGSEGV
},
26 { EXCEPT_IA32_GP_FAULT
, GDB_SIGSEGV
},
27 { EXCEPT_IA32_PAGE_FAULT
, GDB_SIGSEGV
},
28 { EXCEPT_IA32_FP_ERROR
, GDB_SIGEMT
},
29 { EXCEPT_IA32_ALIGNMENT_CHECK
, GDB_SIGEMT
},
30 { EXCEPT_IA32_MACHINE_CHECK
, GDB_SIGEMT
}
33 // The offsets of registers SystemContext.
34 // The fields in the array are in the gdb ordering.
37 UINTN gRegisterOffsets
[] = {
38 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Eax
),
39 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Ecx
),
40 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Edx
),
41 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Ebx
),
42 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Esp
),
43 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Ebp
),
44 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Esi
),
45 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Edi
),
46 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Eip
),
47 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Eflags
),
48 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Cs
),
49 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Ss
),
50 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Ds
),
51 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Es
),
52 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Fs
),
53 OFFSET_OF (EFI_SYSTEM_CONTEXT_IA32
, Gs
)
59 IN EFI_SYSTEM_CONTEXT SystemContext
62 Print ((CHAR16
*)L
"EAX: %x ", SystemContext
.SystemContextIa32
->Eax
);
63 Print ((CHAR16
*)L
"ECX: %x ", SystemContext
.SystemContextIa32
->Ecx
);
64 Print ((CHAR16
*)L
"EDX: %x ", SystemContext
.SystemContextIa32
->Edx
);
65 Print ((CHAR16
*)L
"EBX: %x ", SystemContext
.SystemContextIa32
->Ebx
);
66 Print ((CHAR16
*)L
"ESP: %x ", SystemContext
.SystemContextIa32
->Esp
);
67 Print ((CHAR16
*)L
"EBP: %x ", SystemContext
.SystemContextIa32
->Ebp
);
68 Print ((CHAR16
*)L
"ESI: %x ", SystemContext
.SystemContextIa32
->Esi
);
69 Print ((CHAR16
*)L
"EDI: %x ", SystemContext
.SystemContextIa32
->Edi
);
70 Print ((CHAR16
*)L
"EIP: %x\n", SystemContext
.SystemContextIa32
->Eip
);
71 Print ((CHAR16
*)L
"EFlags: %x\n", SystemContext
.SystemContextIa32
->Eflags
);
77 IN EFI_SYSTEM_CONTEXT SystemContext
80 Print ((CHAR16
*)L
"DR0: %x ", SystemContext
.SystemContextIa32
->Dr0
);
81 Print ((CHAR16
*)L
"DR1: %x ", SystemContext
.SystemContextIa32
->Dr1
);
82 Print ((CHAR16
*)L
"DR2: %x ", SystemContext
.SystemContextIa32
->Dr2
);
83 Print ((CHAR16
*)L
"DR3: %x ", SystemContext
.SystemContextIa32
->Dr3
);
84 Print ((CHAR16
*)L
"DR6: %x ", SystemContext
.SystemContextIa32
->Dr6
);
85 Print ((CHAR16
*)L
"DR7: %x\n", SystemContext
.SystemContextIa32
->Dr7
);
89 Return the number of entries in the gExceptionType[]
91 @retval UINTN, the number of entries in the gExceptionType[] array.
98 return sizeof (gExceptionType
)/sizeof (EFI_EXCEPTION_TYPE_ENTRY
);
102 Return the number of entries in the gRegisters[]
104 @retval UINTN, the number of entries (registers) in the gRegisters[] array.
111 return sizeof (gRegisterOffsets
)/sizeof (UINTN
);
115 Check to see if the ISA is supported.
116 ISA = Instruction Set Architecture
118 @retval TRUE if Isa is supported,
123 IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
126 return (BOOLEAN
)(Isa
== IsaIa32
);
130 This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
131 It is, by default, set to find the register pointer of the IA32 member
133 @param SystemContext Register content at time of the exception
134 @param RegNumber The register to which we want to find a pointer
135 @retval the pointer to the RegNumber-th pointer
138 FindPointerToRegister (
139 IN EFI_SYSTEM_CONTEXT SystemContext
,
145 TempPtr
= ((UINT8
*)SystemContext
.SystemContextIa32
) + gRegisterOffsets
[RegNumber
];
146 return (UINTN
*)TempPtr
;
150 Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
152 @param SystemContext Register content at time of the exception
153 @param RegNumber the number of the register that we want to read
154 @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
155 @retval the pointer to the next character of the output buffer that is available to be written on.
159 IN EFI_SYSTEM_CONTEXT SystemContext
,
167 while (RegSize
< REG_SIZE
) {
168 *OutBufPtr
++ = mHexToStr
[((*FindPointerToRegister (SystemContext
, RegNumber
) >> (RegSize
+4)) & 0xf)];
169 *OutBufPtr
++ = mHexToStr
[((*FindPointerToRegister (SystemContext
, RegNumber
) >> RegSize
) & 0xf)];
170 RegSize
= RegSize
+ 8;
177 Reads the n-th register's value into an output buffer and sends it as a packet
179 @param SystemContext Register content at time of the exception
180 @param InBuffer Pointer to the input buffer received from gdb server
185 IN EFI_SYSTEM_CONTEXT SystemContext
,
190 CHAR8 OutBuffer
[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
191 CHAR8
*OutBufPtr
; // pointer to the output buffer
193 RegNumber
= AsciiStrHexToUintn (&InBuffer
[1]);
195 if ((RegNumber
< 0) || (RegNumber
>= MaxRegisterCount ())) {
196 SendError (GDB_EINVALIDREGNUM
);
200 OutBufPtr
= OutBuffer
;
201 OutBufPtr
= BasicReadRegister (SystemContext
, RegNumber
, OutBufPtr
);
203 *OutBufPtr
= '\0'; // the end of the buffer
204 SendPacket (OutBuffer
);
208 Reads the general registers into an output buffer and sends it as a packet
210 @param SystemContext Register content at time of the exception
214 ReadGeneralRegisters (
215 IN EFI_SYSTEM_CONTEXT SystemContext
219 CHAR8 OutBuffer
[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
220 CHAR8
*OutBufPtr
; // pointer to the output buffer
222 OutBufPtr
= OutBuffer
;
223 for (i
= 0; i
< MaxRegisterCount (); i
++) {
224 // there are only 16 registers to read
225 OutBufPtr
= BasicReadRegister (SystemContext
, i
, OutBufPtr
);
228 *OutBufPtr
= '\0'; // the end of the buffer
229 SendPacket (OutBuffer
);
233 Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
235 @param SystemContext Register content at time of the exception
236 @param RegNumber the number of the register that we want to write
237 @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
238 @retval the pointer to the next character of the input buffer that can be used
242 IN EFI_SYSTEM_CONTEXT SystemContext
,
248 UINTN TempValue
; // the value transferred from a hex char
249 UINT32 NewValue
; // the new value of the RegNumber-th Register
253 while (RegSize
< REG_SIZE
) {
254 TempValue
= HexCharToInt (*InBufPtr
++);
257 SendError (GDB_EBADMEMDATA
);
261 NewValue
+= (TempValue
<< (RegSize
+4));
262 TempValue
= HexCharToInt (*InBufPtr
++);
265 SendError (GDB_EBADMEMDATA
);
269 NewValue
+= (TempValue
<< RegSize
);
270 RegSize
= RegSize
+ 8;
273 *(FindPointerToRegister (SystemContext
, RegNumber
)) = NewValue
;
278 Writes the new value of n-th register received into the input buffer to the n-th register
280 @param SystemContext Register content at time of the exception
281 @param InBuffer Pointer to the input buffer received from gdb server
286 IN EFI_SYSTEM_CONTEXT SystemContext
,
291 CHAR8 RegNumBuffer
[MAX_REG_NUM_BUF_SIZE
]; // put the 'n..' part of the message into this array
293 CHAR8
*InBufPtr
; // pointer to the input buffer
295 // find the register number to write
296 InBufPtr
= &InBuffer
[1];
297 RegNumBufPtr
= RegNumBuffer
;
298 while (*InBufPtr
!= '=') {
299 *RegNumBufPtr
++ = *InBufPtr
++;
302 *RegNumBufPtr
= '\0';
303 RegNumber
= AsciiStrHexToUintn (RegNumBuffer
);
305 // check if this is a valid Register Number
306 if ((RegNumber
< 0) || (RegNumber
>= MaxRegisterCount ())) {
307 SendError (GDB_EINVALIDREGNUM
);
311 InBufPtr
++; // skips the '=' character
312 BasicWriteRegister (SystemContext
, RegNumber
, InBufPtr
);
317 Writes the new values received into the input buffer to the general registers
319 @param SystemContext Register content at time of the exception
320 @param InBuffer Pointer to the input buffer received from gdb server
324 WriteGeneralRegisters (
325 IN EFI_SYSTEM_CONTEXT SystemContext
,
330 CHAR8
*InBufPtr
; /// pointer to the input buffer
332 // check to see if the buffer is the right size which is
333 // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
334 if (AsciiStrLen (InBuffer
) != 129) {
335 // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
336 // Bad message. Message is not the right length
337 SendError (GDB_EBADBUFSIZE
);
341 InBufPtr
= &InBuffer
[1];
343 // Read the new values for the registers from the input buffer to an array, NewValueArray.
344 // The values in the array are in the gdb ordering
345 for (i
= 0; i
< MaxRegisterCount (); i
++) {
346 // there are only 16 registers to write
347 InBufPtr
= BasicWriteRegister (SystemContext
, i
, InBufPtr
);
354 Insert Single Step in the SystemContext
356 @param SystemContext Register content at time of the exception
360 IN EFI_SYSTEM_CONTEXT SystemContext
363 SystemContext
.SystemContextIa32
->Eflags
|= TF_BIT
; // Setting the TF bit.
367 Remove Single Step in the SystemContext
369 @param SystemContext Register content at time of the exception
373 IN EFI_SYSTEM_CONTEXT SystemContext
376 SystemContext
.SystemContextIa32
->Eflags
&= ~TF_BIT
; // clearing the TF bit.
380 Continue. addr is Address to resume. If addr is omitted, resume at current
383 @param SystemContext Register content at time of the exception
388 IN EFI_SYSTEM_CONTEXT SystemContext
,
392 if (PacketData
[1] != '\0') {
393 SystemContext
.SystemContextIa32
->Eip
= AsciiStrHexToUintn (&PacketData
[1]);
398 Single step. addr is the Address at which to resume. If addr is omitted, resume
401 @param SystemContext Register content at time of the exception
406 IN EFI_SYSTEM_CONTEXT SystemContext
,
410 if (PacketData
[1] != '\0') {
411 SystemContext
.SystemContextIa32
->Eip
= AsciiStrHexToUintn (&PacketData
[1]);
414 AddSingleStep (SystemContext
);
418 Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
420 @param SystemContext Register content at time of the exception
421 @param BreakpointNumber Breakpoint number
423 @retval Address Data address from DR0-DR3 based on the breakpoint number.
427 GetBreakpointDataAddress (
428 IN EFI_SYSTEM_CONTEXT SystemContext
,
429 IN UINTN BreakpointNumber
434 if (BreakpointNumber
== 1) {
435 Address
= SystemContext
.SystemContextIa32
->Dr0
;
436 } else if (BreakpointNumber
== 2) {
437 Address
= SystemContext
.SystemContextIa32
->Dr1
;
438 } else if (BreakpointNumber
== 3) {
439 Address
= SystemContext
.SystemContextIa32
->Dr2
;
440 } else if (BreakpointNumber
== 4) {
441 Address
= SystemContext
.SystemContextIa32
->Dr3
;
450 Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
451 If no breakpoint is detected then it returns 0.
453 @param SystemContext Register content at time of the exception
455 @retval {1-4} Currently detected breakpoint value
456 @retval 0 No breakpoint detected.
460 GetBreakpointDetected (
461 IN EFI_SYSTEM_CONTEXT SystemContext
465 UINTN BreakpointNumber
;
467 Dr6
.UintN
= SystemContext
.SystemContextIa32
->Dr6
;
469 if (Dr6
.Bits
.B0
== 1) {
470 BreakpointNumber
= 1;
471 } else if (Dr6
.Bits
.B1
== 1) {
472 BreakpointNumber
= 2;
473 } else if (Dr6
.Bits
.B2
== 1) {
474 BreakpointNumber
= 3;
475 } else if (Dr6
.Bits
.B3
== 1) {
476 BreakpointNumber
= 4;
478 BreakpointNumber
= 0; // No breakpoint detected
481 return BreakpointNumber
;
485 Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
486 based on the Breakpoint number
488 @param SystemContext Register content at time of the exception
489 @param BreakpointNumber Breakpoint number
491 @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
492 For unknown value, it returns NotSupported.
497 IN EFI_SYSTEM_CONTEXT SystemContext
,
498 IN UINTN BreakpointNumber
502 BREAK_TYPE Type
= NotSupported
; // Default is NotSupported type
504 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
506 if (BreakpointNumber
== 1) {
507 Type
= (BREAK_TYPE
)Dr7
.Bits
.RW0
;
508 } else if (BreakpointNumber
== 2) {
509 Type
= (BREAK_TYPE
)Dr7
.Bits
.RW1
;
510 } else if (BreakpointNumber
== 3) {
511 Type
= (BREAK_TYPE
)Dr7
.Bits
.RW2
;
512 } else if (BreakpointNumber
== 4) {
513 Type
= (BREAK_TYPE
)Dr7
.Bits
.RW3
;
520 Parses Length and returns the length which DR7 LENn field accepts.
521 For example: If we receive 1-Byte length then we should return 0.
522 Zero gets written to DR7 LENn field.
524 @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
526 @retval Length Appropriate converted values which DR7 LENn field accepts.
537 } else if (Length
== 2) {
540 } else if (Length
== 4) {
544 // Undefined or 8-byte length
550 Finds the next free debug register. If all the registers are occupied then
551 EFI_OUT_OF_RESOURCES is returned.
553 @param SystemContext Register content at time of the exception
554 @param Register Register value (0 - 3 for the first free debug register)
556 @retval EFI_STATUS Appropriate status value.
560 FindNextFreeDebugRegister (
561 IN EFI_SYSTEM_CONTEXT SystemContext
,
567 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
569 if (Dr7
.Bits
.G0
== 0) {
571 } else if (Dr7
.Bits
.G1
== 0) {
573 } else if (Dr7
.Bits
.G2
== 0) {
575 } else if (Dr7
.Bits
.G3
== 0) {
578 return EFI_OUT_OF_RESOURCES
;
585 Enables the debug register. Writes Address value to appropriate DR0-3 register.
586 Sets LENn, Gn, RWn bits in DR7 register.
588 @param SystemContext Register content at time of the exception
589 @param Register Register value (0 - 3)
590 @param Address Breakpoint address value
591 @param Type Breakpoint type (Instruction, Data write, Data read
594 @retval EFI_STATUS Appropriate status value.
598 EnableDebugRegister (
599 IN EFI_SYSTEM_CONTEXT SystemContext
,
608 // Convert length data
609 Length
= ConvertLengthData (Length
);
611 // For Instruction execution, length should be 0
612 // (Ref. Intel reference manual 18.2.4)
613 if ((Type
== 0) && (Length
!= 0)) {
614 return EFI_INVALID_PARAMETER
;
617 // Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
618 // software breakpoint. We should send empty packet in both these cases.
619 if ((Type
== (BREAK_TYPE
)DataRead
) ||
620 (Type
== (BREAK_TYPE
)SoftwareBreakpoint
))
622 return EFI_UNSUPPORTED
;
625 // Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
626 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
629 SystemContext
.SystemContextIa32
->Dr0
= Address
;
632 Dr7
.Bits
.LEN0
= Length
;
633 } else if (Register
== 1) {
634 SystemContext
.SystemContextIa32
->Dr1
= Address
;
637 Dr7
.Bits
.LEN1
= Length
;
638 } else if (Register
== 2) {
639 SystemContext
.SystemContextIa32
->Dr2
= Address
;
642 Dr7
.Bits
.LEN2
= Length
;
643 } else if (Register
== 3) {
644 SystemContext
.SystemContextIa32
->Dr3
= Address
;
647 Dr7
.Bits
.LEN3
= Length
;
649 return EFI_INVALID_PARAMETER
;
652 // Update Dr7 with appropriate Gn, RWn and LENn bits
653 SystemContext
.SystemContextIa32
->Dr7
= Dr7
.UintN
;
659 Returns register number 0 - 3 for the matching debug register.
660 This function compares incoming Address, Type, Length and
661 if there is a match then it returns the appropriate register number.
662 In case of mismatch, function returns EFI_NOT_FOUND message.
664 @param SystemContext Register content at time of the exception
665 @param Address Breakpoint address value
666 @param Length Breakpoint length value
667 @param Type Breakpoint type (Instruction, Data write,
668 Data read or write etc.)
669 @param Register Register value to be returned
671 @retval EFI_STATUS Appropriate status value.
675 FindMatchingDebugRegister (
676 IN EFI_SYSTEM_CONTEXT SystemContext
,
685 // Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
686 // software breakpoint. We should send empty packet in both these cases.
687 if ((Type
== (BREAK_TYPE
)DataRead
) ||
688 (Type
== (BREAK_TYPE
)SoftwareBreakpoint
))
690 return EFI_UNSUPPORTED
;
693 // Convert length data
694 Length
= ConvertLengthData (Length
);
696 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
698 if ((Dr7
.Bits
.G0
== 1) &&
699 (Dr7
.Bits
.LEN0
== Length
) &&
700 (Dr7
.Bits
.RW0
== Type
) &&
701 (Address
== SystemContext
.SystemContextIa32
->Dr0
))
704 } else if ((Dr7
.Bits
.G1
== 1) &&
705 (Dr7
.Bits
.LEN1
== Length
) &&
706 (Dr7
.Bits
.RW1
== Type
) &&
707 (Address
== SystemContext
.SystemContextIa32
->Dr1
))
710 } else if ((Dr7
.Bits
.G2
== 1) &&
711 (Dr7
.Bits
.LEN2
== Length
) &&
712 (Dr7
.Bits
.RW2
== Type
) &&
713 (Address
== SystemContext
.SystemContextIa32
->Dr2
))
716 } else if ((Dr7
.Bits
.G3
== 1) &&
717 (Dr7
.Bits
.LEN3
== Length
) &&
718 (Dr7
.Bits
.RW3
== Type
) &&
719 (Address
== SystemContext
.SystemContextIa32
->Dr3
))
723 Print ((CHAR16
*)L
"No match found..\n");
724 return EFI_NOT_FOUND
;
731 Disables the particular debug register.
733 @param SystemContext Register content at time of the exception
734 @param Register Register to be disabled
736 @retval EFI_STATUS Appropriate status value.
740 DisableDebugRegister (
741 IN EFI_SYSTEM_CONTEXT SystemContext
,
748 // Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
749 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
752 SystemContext
.SystemContextIa32
->Dr0
= Address
;
756 } else if (Register
== 1) {
757 SystemContext
.SystemContextIa32
->Dr1
= Address
;
761 } else if (Register
== 2) {
762 SystemContext
.SystemContextIa32
->Dr2
= Address
;
766 } else if (Register
== 3) {
767 SystemContext
.SystemContextIa32
->Dr3
= Address
;
772 return EFI_INVALID_PARAMETER
;
775 // Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
776 SystemContext
.SystemContextIa32
->Dr7
= Dr7
.UintN
;
782 ‘Z1, [addr], [length]’
783 ‘Z2, [addr], [length]’
784 ‘Z3, [addr], [length]’
785 ‘Z4, [addr], [length]’
787 Insert hardware breakpoint/watchpoint at address addr of size length
789 @param SystemContext Register content at time of the exception
790 @param *PacketData Pointer to the Payload data for the packet
796 IN EFI_SYSTEM_CONTEXT SystemContext
,
805 BREAK_TYPE BreakType
= NotSupported
;
808 ErrorCode
= ParseBreakpointPacket (PacketData
, &Type
, &Address
, &Length
);
810 SendError ((UINT8
)ErrorCode
);
815 case 0: // Software breakpoint
816 BreakType
= SoftwareBreakpoint
;
819 case 1: // Hardware breakpoint
820 BreakType
= InstructionExecution
;
823 case 2: // Write watchpoint
824 BreakType
= DataWrite
;
827 case 3: // Read watchpoint
828 BreakType
= DataRead
;
831 case 4: // Access watchpoint
832 BreakType
= DataReadWrite
;
836 Print ((CHAR16
*)L
"Insert breakpoint default: %x\n", Type
);
837 SendError (GDB_EINVALIDBRKPOINTTYPE
);
841 // Find next free debug register
842 Status
= FindNextFreeDebugRegister (SystemContext
, &Register
);
843 if (EFI_ERROR (Status
)) {
844 Print ((CHAR16
*)L
"No space left on device\n");
845 SendError (GDB_ENOSPACE
);
849 // Write Address, length data at particular DR register
850 Status
= EnableDebugRegister (SystemContext
, Register
, Address
, Length
, (UINTN
)BreakType
);
851 if (EFI_ERROR (Status
)) {
852 if (Status
== EFI_UNSUPPORTED
) {
853 Print ((CHAR16
*)L
"Not supported\n");
858 Print ((CHAR16
*)L
"Invalid argument\n");
859 SendError (GDB_EINVALIDARG
);
867 ‘z1, [addr], [length]’
868 ‘z2, [addr], [length]’
869 ‘z3, [addr], [length]’
870 ‘z4, [addr], [length]’
872 Remove hardware breakpoint/watchpoint at address addr of size length
874 @param *PacketData Pointer to the Payload data for the packet
880 IN EFI_SYSTEM_CONTEXT SystemContext
,
888 BREAK_TYPE BreakType
= NotSupported
;
892 // Parse breakpoint packet data
893 ErrorCode
= ParseBreakpointPacket (PacketData
, &Type
, &Address
, &Length
);
895 SendError ((UINT8
)ErrorCode
);
900 case 0: // Software breakpoint
901 BreakType
= SoftwareBreakpoint
;
904 case 1: // Hardware breakpoint
905 BreakType
= InstructionExecution
;
908 case 2: // Write watchpoint
909 BreakType
= DataWrite
;
912 case 3: // Read watchpoint
913 BreakType
= DataRead
;
916 case 4: // Access watchpoint
917 BreakType
= DataReadWrite
;
921 SendError (GDB_EINVALIDBRKPOINTTYPE
);
925 // Find matching debug register
926 Status
= FindMatchingDebugRegister (SystemContext
, Address
, Length
, (UINTN
)BreakType
, &Register
);
927 if (EFI_ERROR (Status
)) {
928 if (Status
== EFI_UNSUPPORTED
) {
929 Print ((CHAR16
*)L
"Not supported.\n");
934 Print ((CHAR16
*)L
"No matching register found.\n");
935 SendError (GDB_ENOSPACE
);
940 Status
= DisableDebugRegister (SystemContext
, Register
);
941 if (EFI_ERROR (Status
)) {
942 Print ((CHAR16
*)L
"Invalid argument.\n");
943 SendError (GDB_EINVALIDARG
);
951 InitializeProcessor (
967 IN EFI_EXCEPTION_TYPE ExceptionType
,
968 IN OUT EFI_SYSTEM_CONTEXT SystemContext