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 <GdbStubInternal.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 Return the number of entries in the gRegisters[]
114 @retval UINTN, the number of entries (registers) in the gRegisters[] array.
121 return sizeof (gRegisterOffsets
)/sizeof (UINTN
);
126 Check to see if the ISA is supported.
127 ISA = Instruction Set Architecture
129 @retval TRUE if Isa is supported,
134 IN EFI_INSTRUCTION_SET_ARCHITECTURE Isa
137 return (BOOLEAN
)(Isa
== IsaIa32
);
142 This takes in the register number and the System Context, and returns a pointer to the RegNumber-th register in gdb ordering
143 It is, by default, set to find the register pointer of the IA32 member
145 @param SystemContext Register content at time of the exception
146 @param RegNumber The register to which we want to find a pointer
147 @retval the pointer to the RegNumber-th pointer
150 FindPointerToRegister (
151 IN EFI_SYSTEM_CONTEXT SystemContext
,
156 TempPtr
= ((UINT8
*)SystemContext
.SystemContextIa32
) + gRegisterOffsets
[RegNumber
];
157 return (UINTN
*)TempPtr
;
162 Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
164 @param SystemContext Register content at time of the exception
165 @param RegNumber the number of the register that we want to read
166 @param OutBufPtr pointer to the output buffer's end. the new data will be added from this point on.
167 @retval the pointer to the next character of the output buffer that is available to be written on.
171 IN EFI_SYSTEM_CONTEXT SystemContext
,
179 while (RegSize
< REG_SIZE
) {
180 *OutBufPtr
++ = mHexToStr
[((*FindPointerToRegister (SystemContext
, RegNumber
) >> (RegSize
+4)) & 0xf)];
181 *OutBufPtr
++ = mHexToStr
[((*FindPointerToRegister (SystemContext
, RegNumber
) >> RegSize
) & 0xf)];
182 RegSize
= RegSize
+ 8;
189 Reads the n-th register's value into an output buffer and sends it as a packet
191 @param SystemContext Register content at time of the exception
192 @param InBuffer Pointer to the input buffer received from gdb server
197 IN EFI_SYSTEM_CONTEXT SystemContext
,
202 CHAR8 OutBuffer
[9]; // 1 reg=8 hex chars, and the end '\0' (escape seq)
203 CHAR8
*OutBufPtr
; // pointer to the output buffer
205 RegNumber
= AsciiStrHexToUintn (&InBuffer
[1]);
207 if ((RegNumber
< 0) || (RegNumber
>= MaxRegisterCount())) {
208 SendError (GDB_EINVALIDREGNUM
);
212 OutBufPtr
= OutBuffer
;
213 OutBufPtr
= BasicReadRegister (SystemContext
, RegNumber
, OutBufPtr
);
215 *OutBufPtr
= '\0'; // the end of the buffer
216 SendPacket(OutBuffer
);
221 Reads the general registers into an output buffer and sends it as a packet
223 @param SystemContext Register content at time of the exception
227 ReadGeneralRegisters (
228 IN EFI_SYSTEM_CONTEXT SystemContext
232 CHAR8 OutBuffer
[129]; // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
233 CHAR8
*OutBufPtr
; // pointer to the output buffer
235 OutBufPtr
= OutBuffer
;
236 for (i
= 0 ; i
< MaxRegisterCount() ; i
++) { // there are only 16 registers to read
237 OutBufPtr
= BasicReadRegister (SystemContext
, i
, OutBufPtr
);
240 *OutBufPtr
= '\0'; // the end of the buffer
241 SendPacket(OutBuffer
);
246 Adds the RegNumber-th register's value to the output buffer, starting at the given OutBufPtr
248 @param SystemContext Register content at time of the exception
249 @param RegNumber the number of the register that we want to write
250 @param InBufPtr pointer to the output buffer. the new data will be extracted from the input buffer from this point on.
251 @retval the pointer to the next character of the input buffer that can be used
255 IN EFI_SYSTEM_CONTEXT SystemContext
,
261 UINTN TempValue
; // the value transferred from a hex char
262 UINT32 NewValue
; // the new value of the RegNumber-th Register
266 while (RegSize
< REG_SIZE
) {
267 TempValue
= HexCharToInt(*InBufPtr
++);
270 SendError (GDB_EBADMEMDATA
);
274 NewValue
+= (TempValue
<< (RegSize
+4));
275 TempValue
= HexCharToInt(*InBufPtr
++);
278 SendError (GDB_EBADMEMDATA
);
282 NewValue
+= (TempValue
<< RegSize
);
283 RegSize
= RegSize
+ 8;
285 *(FindPointerToRegister (SystemContext
, RegNumber
)) = NewValue
;
291 Writes the new value of n-th register received into the input buffer to the n-th register
293 @param SystemContext Register content at time of the exception
294 @param InBuffer Ponter to the input buffer received from gdb server
299 IN EFI_SYSTEM_CONTEXT SystemContext
,
304 CHAR8 RegNumBuffer
[MAX_REG_NUM_BUF_SIZE
]; // put the 'n..' part of the message into this array
306 CHAR8
*InBufPtr
; // pointer to the input buffer
308 // find the register number to write
309 InBufPtr
= &InBuffer
[1];
310 RegNumBufPtr
= RegNumBuffer
;
311 while (*InBufPtr
!= '=') {
312 *RegNumBufPtr
++ = *InBufPtr
++;
314 *RegNumBufPtr
= '\0';
315 RegNumber
= AsciiStrHexToUintn (RegNumBuffer
);
317 // check if this is a valid Register Number
318 if ((RegNumber
< 0) || (RegNumber
>= MaxRegisterCount())) {
319 SendError (GDB_EINVALIDREGNUM
);
322 InBufPtr
++; // skips the '=' character
323 BasicWriteRegister (SystemContext
, RegNumber
, InBufPtr
);
329 Writes the new values received into the input buffer to the general registers
331 @param SystemContext Register content at time of the exception
332 @param InBuffer Pointer to the input buffer received from gdb server
336 WriteGeneralRegisters (
337 IN EFI_SYSTEM_CONTEXT SystemContext
,
342 CHAR8
*InBufPtr
; /// pointer to the input buffer
344 // check to see if the buffer is the right size which is
345 // 1 (for 'G') + 16 (for 16 registers) * 8 ( for 8 hex chars each) = 129
346 if (AsciiStrLen(InBuffer
) != 129) { // 16 regs, 8 hex chars each, and the end '\0' (escape seq)
347 //Bad message. Message is not the right length
348 SendError (GDB_EBADBUFSIZE
);
352 InBufPtr
= &InBuffer
[1];
354 // Read the new values for the registers from the input buffer to an array, NewValueArray.
355 // The values in the array are in the gdb ordering
356 for (i
=0; i
< MaxRegisterCount(); i
++) { // there are only 16 registers to write
357 InBufPtr
= BasicWriteRegister (SystemContext
, i
, InBufPtr
);
365 Insert Single Step in the SystemContext
367 @param SystemContext Register content at time of the exception
371 IN EFI_SYSTEM_CONTEXT SystemContext
374 SystemContext
.SystemContextIa32
->Eflags
|= TF_BIT
; //Setting the TF bit.
379 Remove Single Step in the SystemContext
381 @param SystemContext Register content at time of the exception
385 IN EFI_SYSTEM_CONTEXT SystemContext
388 SystemContext
.SystemContextIa32
->Eflags
&= ~TF_BIT
; // clearing the TF bit.
394 Continue. addr is Address to resume. If addr is omitted, resume at current
397 @param SystemContext Register content at time of the exception
402 IN EFI_SYSTEM_CONTEXT SystemContext
,
406 if (PacketData
[1] != '\0') {
407 SystemContext
.SystemContextIa32
->Eip
= AsciiStrHexToUintn (&PacketData
[1]);
413 Single step. addr is the Address at which to resume. If addr is omitted, resume
416 @param SystemContext Register content at time of the exception
421 IN EFI_SYSTEM_CONTEXT SystemContext
,
425 if (PacketData
[1] != '\0') {
426 SystemContext
.SystemContextIa32
->Eip
= AsciiStrHexToUintn (&PacketData
[1]);
429 AddSingleStep (SystemContext
);
434 Returns breakpoint data address from DR0-DR3 based on the input breakpoint number
436 @param SystemContext Register content at time of the exception
437 @param BreakpointNumber Breakpoint number
439 @retval Address Data address from DR0-DR3 based on the breakpoint number.
443 GetBreakpointDataAddress (
444 IN EFI_SYSTEM_CONTEXT SystemContext
,
445 IN UINTN BreakpointNumber
450 if (BreakpointNumber
== 1) {
451 Address
= SystemContext
.SystemContextIa32
->Dr0
;
452 } else if (BreakpointNumber
== 2) {
453 Address
= SystemContext
.SystemContextIa32
->Dr1
;
454 } else if (BreakpointNumber
== 3) {
455 Address
= SystemContext
.SystemContextIa32
->Dr2
;
456 } else if (BreakpointNumber
== 4) {
457 Address
= SystemContext
.SystemContextIa32
->Dr3
;
467 Returns currently detected breakpoint value based on the register DR6 B0-B3 field.
468 If no breakpoint is detected then it returns 0.
470 @param SystemContext Register content at time of the exception
472 @retval {1-4} Currently detected breakpoint value
473 @retval 0 No breakpoint detected.
477 GetBreakpointDetected (
478 IN EFI_SYSTEM_CONTEXT SystemContext
482 UINTN BreakpointNumber
;
484 Dr6
.UintN
= SystemContext
.SystemContextIa32
->Dr6
;
486 if (Dr6
.Bits
.B0
== 1) {
487 BreakpointNumber
= 1;
488 } else if (Dr6
.Bits
.B1
== 1) {
489 BreakpointNumber
= 2;
490 } else if (Dr6
.Bits
.B2
== 1) {
491 BreakpointNumber
= 3;
492 } else if (Dr6
.Bits
.B3
== 1) {
493 BreakpointNumber
= 4;
495 BreakpointNumber
= 0; //No breakpoint detected
498 return BreakpointNumber
;
503 Returns Breakpoint type (InstructionExecution, DataWrite, DataRead or DataReadWrite)
504 based on the Breakpoint number
506 @param SystemContext Register content at time of the exception
507 @param BreakpointNumber Breakpoint number
509 @retval BREAK_TYPE Breakpoint type value read from register DR7 RWn field
510 For unknown value, it returns NotSupported.
515 IN EFI_SYSTEM_CONTEXT SystemContext
,
516 IN UINTN BreakpointNumber
520 BREAK_TYPE Type
= NotSupported
; //Default is NotSupported type
522 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
524 if (BreakpointNumber
== 1) {
525 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW0
;
526 } else if (BreakpointNumber
== 2) {
527 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW1
;
528 } else if (BreakpointNumber
== 3) {
529 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW2
;
530 } else if (BreakpointNumber
== 4) {
531 Type
= (BREAK_TYPE
) Dr7
.Bits
.RW3
;
539 Parses Length and returns the length which DR7 LENn field accepts.
540 For example: If we receive 1-Byte length then we should return 0.
541 Zero gets written to DR7 LENn field.
543 @param Length Breakpoint length in Bytes (1 byte, 2 byte, 4 byte)
545 @retval Length Appropriate converted values which DR7 LENn field accepts.
553 if (Length
== 1) { //1-Byte length
555 } else if (Length
== 2) { //2-Byte length
557 } else if (Length
== 4) { //4-Byte length
559 } else { //Undefined or 8-byte length
566 Finds the next free debug register. If all the registers are occupied then
567 EFI_OUT_OF_RESOURCES is returned.
569 @param SystemContext Register content at time of the exception
570 @param Register Register value (0 - 3 for the first free debug register)
572 @retval EFI_STATUS Appropriate status value.
576 FindNextFreeDebugRegister (
577 IN EFI_SYSTEM_CONTEXT SystemContext
,
583 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
585 if (Dr7
.Bits
.G0
== 0) {
587 } else if (Dr7
.Bits
.G1
== 0) {
589 } else if (Dr7
.Bits
.G2
== 0) {
591 } else if (Dr7
.Bits
.G3
== 0) {
594 return EFI_OUT_OF_RESOURCES
;
602 Enables the debug register. Writes Address value to appropriate DR0-3 register.
603 Sets LENn, Gn, RWn bits in DR7 register.
605 @param SystemContext Register content at time of the exception
606 @param Register Register value (0 - 3)
607 @param Address Breakpoint address value
608 @param Type Breakpoint type (Instruction, Data write, Data read
611 @retval EFI_STATUS Appropriate status value.
615 EnableDebugRegister (
616 IN EFI_SYSTEM_CONTEXT SystemContext
,
625 //Convert length data
626 Length
= ConvertLengthData (Length
);
628 //For Instruction execution, length should be 0
629 //(Ref. Intel reference manual 18.2.4)
630 if ((Type
== 0) && (Length
!= 0)) {
631 return EFI_INVALID_PARAMETER
;
634 //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
635 //software breakpoint. We should send empty packet in both these cases.
636 if ((Type
== (BREAK_TYPE
)DataRead
) ||
637 (Type
== (BREAK_TYPE
)SoftwareBreakpoint
)) {
638 return EFI_UNSUPPORTED
;
641 //Read DR7 so appropriate Gn, RWn and LENn bits can be modified.
642 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
645 SystemContext
.SystemContextIa32
->Dr0
= Address
;
648 Dr7
.Bits
.LEN0
= Length
;
649 } else if (Register
== 1) {
650 SystemContext
.SystemContextIa32
->Dr1
= Address
;
653 Dr7
.Bits
.LEN1
= Length
;
654 } else if (Register
== 2) {
655 SystemContext
.SystemContextIa32
->Dr2
= Address
;
658 Dr7
.Bits
.LEN2
= Length
;
659 } else if (Register
== 3) {
660 SystemContext
.SystemContextIa32
->Dr3
= Address
;
663 Dr7
.Bits
.LEN3
= Length
;
665 return EFI_INVALID_PARAMETER
;
668 //Update Dr7 with appropriate Gn, RWn and LENn bits
669 SystemContext
.SystemContextIa32
->Dr7
= Dr7
.UintN
;
676 Returns register number 0 - 3 for the maching debug register.
677 This function compares incoming Address, Type, Length and
678 if there is a match then it returns the appropriate register number.
679 In case of mismatch, function returns EFI_NOT_FOUND message.
681 @param SystemContext Register content at time of the exception
682 @param Address Breakpoint address value
683 @param Length Breakpoint length value
684 @param Type Breakpoint type (Instruction, Data write,
685 Data read or write etc.)
686 @param Register Register value to be returned
688 @retval EFI_STATUS Appropriate status value.
692 FindMatchingDebugRegister (
693 IN EFI_SYSTEM_CONTEXT SystemContext
,
702 //Hardware doesn't support ReadWatch (z3 packet) type. GDB can handle
703 //software breakpoint. We should send empty packet in both these cases.
704 if ((Type
== (BREAK_TYPE
)DataRead
) ||
705 (Type
== (BREAK_TYPE
)SoftwareBreakpoint
)) {
706 return EFI_UNSUPPORTED
;
709 //Convert length data
710 Length
= ConvertLengthData(Length
);
712 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
714 if ((Dr7
.Bits
.G0
== 1) &&
715 (Dr7
.Bits
.LEN0
== Length
) &&
716 (Dr7
.Bits
.RW0
== Type
) &&
717 (Address
== SystemContext
.SystemContextIa32
->Dr0
)) {
719 } else if ((Dr7
.Bits
.G1
== 1) &&
720 (Dr7
.Bits
.LEN1
== Length
) &&
721 (Dr7
.Bits
.RW1
== Type
) &&
722 (Address
== SystemContext
.SystemContextIa32
->Dr1
)) {
724 } else if ((Dr7
.Bits
.G2
== 1) &&
725 (Dr7
.Bits
.LEN2
== Length
) &&
726 (Dr7
.Bits
.RW2
== Type
) &&
727 (Address
== SystemContext
.SystemContextIa32
->Dr2
)) {
729 } else if ((Dr7
.Bits
.G3
== 1) &&
730 (Dr7
.Bits
.LEN3
== Length
) &&
731 (Dr7
.Bits
.RW3
== Type
) &&
732 (Address
== SystemContext
.SystemContextIa32
->Dr3
)) {
735 Print ((CHAR16
*)L
"No match found..\n");
736 return EFI_NOT_FOUND
;
744 Disables the particular debug register.
746 @param SystemContext Register content at time of the exception
747 @param Register Register to be disabled
749 @retval EFI_STATUS Appropriate status value.
753 DisableDebugRegister (
754 IN EFI_SYSTEM_CONTEXT SystemContext
,
761 //Read DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
762 Dr7
.UintN
= SystemContext
.SystemContextIa32
->Dr7
;
765 SystemContext
.SystemContextIa32
->Dr0
= Address
;
769 } else if (Register
== 1) {
770 SystemContext
.SystemContextIa32
->Dr1
= Address
;
774 } else if (Register
== 2) {
775 SystemContext
.SystemContextIa32
->Dr2
= Address
;
779 } else if (Register
== 3) {
780 SystemContext
.SystemContextIa32
->Dr3
= Address
;
785 return EFI_INVALID_PARAMETER
;
788 //Update DR7 register so appropriate Gn, RWn and LENn bits can be turned off.
789 SystemContext
.SystemContextIa32
->Dr7
= Dr7
.UintN
;
796 ‘Z1, [addr], [length]’
797 ‘Z2, [addr], [length]’
798 ‘Z3, [addr], [length]’
799 ‘Z4, [addr], [length]’
801 Insert hardware breakpoint/watchpoint at address addr of size length
803 @param SystemContext Register content at time of the exception
804 @param *PacketData Pointer to the Payload data for the packet
810 IN EFI_SYSTEM_CONTEXT SystemContext
,
819 BREAK_TYPE BreakType
= NotSupported
;
822 ErrorCode
= ParseBreakpointPacket (PacketData
, &Type
, &Address
, &Length
);
824 SendError ((UINT8
)ErrorCode
);
830 case 0: //Software breakpoint
831 BreakType
= SoftwareBreakpoint
;
834 case 1: //Hardware breakpoint
835 BreakType
= InstructionExecution
;
838 case 2: //Write watchpoint
839 BreakType
= DataWrite
;
842 case 3: //Read watchpoint
843 BreakType
= DataRead
;
846 case 4: //Access watchpoint
847 BreakType
= DataReadWrite
;
851 Print ((CHAR16
*)L
"Insert breakpoint default: %x\n", Type
);
852 SendError (GDB_EINVALIDBRKPOINTTYPE
);
856 // Find next free debug register
857 Status
= FindNextFreeDebugRegister (SystemContext
, &Register
);
858 if (EFI_ERROR(Status
)) {
859 Print ((CHAR16
*)L
"No space left on device\n");
860 SendError (GDB_ENOSPACE
);
864 // Write Address, length data at particular DR register
865 Status
= EnableDebugRegister (SystemContext
, Register
, Address
, Length
, (UINTN
)BreakType
);
866 if (EFI_ERROR(Status
)) {
868 if (Status
== EFI_UNSUPPORTED
) {
869 Print ((CHAR16
*)L
"Not supported\n");
874 Print ((CHAR16
*)L
"Invalid argument\n");
875 SendError (GDB_EINVALIDARG
);
884 ‘z1, [addr], [length]’
885 ‘z2, [addr], [length]’
886 ‘z3, [addr], [length]’
887 ‘z4, [addr], [length]’
889 Remove hardware breakpoint/watchpoint at address addr of size length
891 @param *PacketData Pointer to the Payload data for the packet
897 IN EFI_SYSTEM_CONTEXT SystemContext
,
905 BREAK_TYPE BreakType
= NotSupported
;
909 //Parse breakpoint packet data
910 ErrorCode
= ParseBreakpointPacket (PacketData
, &Type
, &Address
, &Length
);
912 SendError ((UINT8
)ErrorCode
);
918 case 0: //Software breakpoint
919 BreakType
= SoftwareBreakpoint
;
922 case 1: //Hardware breakpoint
923 BreakType
= InstructionExecution
;
926 case 2: //Write watchpoint
927 BreakType
= DataWrite
;
930 case 3: //Read watchpoint
931 BreakType
= DataRead
;
934 case 4: //Access watchpoint
935 BreakType
= DataReadWrite
;
939 SendError (GDB_EINVALIDBRKPOINTTYPE
);
943 //Find matching debug register
944 Status
= FindMatchingDebugRegister (SystemContext
, Address
, Length
, (UINTN
)BreakType
, &Register
);
945 if (EFI_ERROR(Status
)) {
947 if (Status
== EFI_UNSUPPORTED
) {
948 Print ((CHAR16
*)L
"Not supported.\n");
953 Print ((CHAR16
*)L
"No matching register found.\n");
954 SendError (GDB_ENOSPACE
);
959 Status
= DisableDebugRegister (SystemContext
, Register
);
960 if (EFI_ERROR(Status
)) {
961 Print ((CHAR16
*)L
"Invalid argument.\n");
962 SendError (GDB_EINVALIDARG
);
971 InitializeProcessor (
987 IN EFI_EXCEPTION_TYPE ExceptionType
,
988 IN OUT EFI_SYSTEM_CONTEXT SystemContext