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 environment to support source level debugging.
919 If certain Debug Agent Library instance has to save some private data in the stack,
920 this function must work on the mode that doesn't return to the caller, then
921 the caller needs to wrap up all rest of logic after InitializeDebugAgent() into one
922 function and pass it into InitializeDebugAgent(). InitializeDebugAgent() is
923 responsible to invoke the passing-in function at the end of InitializeDebugAgent().
925 If the parameter Function is not NULL, Debug Agent Library instance will invoke it by
926 passing in the Context to be its parameter.
928 If Function() is NULL, Debug Agent Library instance will return after setup debug
931 @param[in] InitFlag Init flag is used to decide the initialize process.
932 @param[in] Context Context needed according to InitFlag; it was optional.
933 @param[in] Function Continue function called by debug agent library; it was
939 InitializeDebugAgent (
941 IN VOID
*Context
, OPTIONAL
942 IN DEBUG_AGENT_CONTINUE Function OPTIONAL
945 // BugBug: Add the code to build an GDT/IDT
947 if (Function
!= NULL
) {