]>
Commit | Line | Data |
---|---|---|
4d2e26a3 MCC |
1 | ====== |
2 | Ptrace | |
3 | ====== | |
4 | ||
5 | GDB intends to support the following hardware debug features of BookE | |
6 | processors: | |
7 | ||
8 | 4 hardware breakpoints (IAC) | |
9 | 2 hardware watchpoints (read, write and read-write) (DAC) | |
10 | 2 value conditions for the hardware watchpoints (DVC) | |
11 | ||
12 | For that, we need to extend ptrace so that GDB can query and set these | |
13 | resources. Since we're extending, we're trying to create an interface | |
14 | that's extendable and that covers both BookE and server processors, so | |
15 | that GDB doesn't need to special-case each of them. We added the | |
16 | following 3 new ptrace requests. | |
17 | ||
18 | 1. PTRACE_PPC_GETHWDEBUGINFO | |
19 | ============================ | |
20 | ||
21 | Query for GDB to discover the hardware debug features. The main info to | |
22 | be returned here is the minimum alignment for the hardware watchpoints. | |
23 | BookE processors don't have restrictions here, but server processors have | |
24 | an 8-byte alignment restriction for hardware watchpoints. We'd like to avoid | |
25 | adding special cases to GDB based on what it sees in AUXV. | |
26 | ||
27 | Since we're at it, we added other useful info that the kernel can return to | |
28 | GDB: this query will return the number of hardware breakpoints, hardware | |
29 | watchpoints and whether it supports a range of addresses and a condition. | |
30 | The query will fill the following structure provided by the requesting process:: | |
31 | ||
32 | struct ppc_debug_info { | |
33 | unit32_t version; | |
34 | unit32_t num_instruction_bps; | |
35 | unit32_t num_data_bps; | |
36 | unit32_t num_condition_regs; | |
37 | unit32_t data_bp_alignment; | |
38 | unit32_t sizeof_condition; /* size of the DVC register */ | |
39 | uint64_t features; /* bitmask of the individual flags */ | |
40 | }; | |
41 | ||
42 | features will have bits indicating whether there is support for:: | |
43 | ||
44 | #define PPC_DEBUG_FEATURE_INSN_BP_RANGE 0x1 | |
45 | #define PPC_DEBUG_FEATURE_INSN_BP_MASK 0x2 | |
46 | #define PPC_DEBUG_FEATURE_DATA_BP_RANGE 0x4 | |
47 | #define PPC_DEBUG_FEATURE_DATA_BP_MASK 0x8 | |
48 | #define PPC_DEBUG_FEATURE_DATA_BP_DAWR 0x10 | |
fa725cc5 | 49 | #define PPC_DEBUG_FEATURE_DATA_BP_ARCH_31 0x20 |
4d2e26a3 MCC |
50 | |
51 | 2. PTRACE_SETHWDEBUG | |
52 | ||
53 | Sets a hardware breakpoint or watchpoint, according to the provided structure:: | |
54 | ||
55 | struct ppc_hw_breakpoint { | |
56 | uint32_t version; | |
57 | #define PPC_BREAKPOINT_TRIGGER_EXECUTE 0x1 | |
58 | #define PPC_BREAKPOINT_TRIGGER_READ 0x2 | |
59 | #define PPC_BREAKPOINT_TRIGGER_WRITE 0x4 | |
60 | uint32_t trigger_type; /* only some combinations allowed */ | |
61 | #define PPC_BREAKPOINT_MODE_EXACT 0x0 | |
62 | #define PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE 0x1 | |
63 | #define PPC_BREAKPOINT_MODE_RANGE_EXCLUSIVE 0x2 | |
64 | #define PPC_BREAKPOINT_MODE_MASK 0x3 | |
65 | uint32_t addr_mode; /* address match mode */ | |
66 | ||
67 | #define PPC_BREAKPOINT_CONDITION_MODE 0x3 | |
68 | #define PPC_BREAKPOINT_CONDITION_NONE 0x0 | |
69 | #define PPC_BREAKPOINT_CONDITION_AND 0x1 | |
70 | #define PPC_BREAKPOINT_CONDITION_EXACT 0x1 /* different name for the same thing as above */ | |
71 | #define PPC_BREAKPOINT_CONDITION_OR 0x2 | |
72 | #define PPC_BREAKPOINT_CONDITION_AND_OR 0x3 | |
73 | #define PPC_BREAKPOINT_CONDITION_BE_ALL 0x00ff0000 /* byte enable bits */ | |
74 | #define PPC_BREAKPOINT_CONDITION_BE(n) (1<<((n)+16)) | |
75 | uint32_t condition_mode; /* break/watchpoint condition flags */ | |
76 | ||
77 | uint64_t addr; | |
78 | uint64_t addr2; | |
79 | uint64_t condition_value; | |
80 | }; | |
81 | ||
82 | A request specifies one event, not necessarily just one register to be set. | |
83 | For instance, if the request is for a watchpoint with a condition, both the | |
84 | DAC and DVC registers will be set in the same request. | |
85 | ||
86 | With this GDB can ask for all kinds of hardware breakpoints and watchpoints | |
87 | that the BookE supports. COMEFROM breakpoints available in server processors | |
88 | are not contemplated, but that is out of the scope of this work. | |
89 | ||
90 | ptrace will return an integer (handle) uniquely identifying the breakpoint or | |
91 | watchpoint just created. This integer will be used in the PTRACE_DELHWDEBUG | |
92 | request to ask for its removal. Return -ENOSPC if the requested breakpoint | |
93 | can't be allocated on the registers. | |
94 | ||
95 | Some examples of using the structure to: | |
96 | ||
97 | - set a breakpoint in the first breakpoint register:: | |
98 | ||
99 | p.version = PPC_DEBUG_CURRENT_VERSION; | |
100 | p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; | |
101 | p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; | |
102 | p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; | |
103 | p.addr = (uint64_t) address; | |
104 | p.addr2 = 0; | |
105 | p.condition_value = 0; | |
106 | ||
107 | - set a watchpoint which triggers on reads in the second watchpoint register:: | |
108 | ||
109 | p.version = PPC_DEBUG_CURRENT_VERSION; | |
110 | p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ; | |
111 | p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; | |
112 | p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; | |
113 | p.addr = (uint64_t) address; | |
114 | p.addr2 = 0; | |
115 | p.condition_value = 0; | |
116 | ||
117 | - set a watchpoint which triggers only with a specific value:: | |
118 | ||
119 | p.version = PPC_DEBUG_CURRENT_VERSION; | |
120 | p.trigger_type = PPC_BREAKPOINT_TRIGGER_READ; | |
121 | p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; | |
122 | p.condition_mode = PPC_BREAKPOINT_CONDITION_AND | PPC_BREAKPOINT_CONDITION_BE_ALL; | |
123 | p.addr = (uint64_t) address; | |
124 | p.addr2 = 0; | |
125 | p.condition_value = (uint64_t) condition; | |
126 | ||
127 | - set a ranged hardware breakpoint:: | |
128 | ||
129 | p.version = PPC_DEBUG_CURRENT_VERSION; | |
130 | p.trigger_type = PPC_BREAKPOINT_TRIGGER_EXECUTE; | |
131 | p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; | |
132 | p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; | |
133 | p.addr = (uint64_t) begin_range; | |
134 | p.addr2 = (uint64_t) end_range; | |
135 | p.condition_value = 0; | |
136 | ||
137 | - set a watchpoint in server processors (BookS):: | |
138 | ||
139 | p.version = 1; | |
140 | p.trigger_type = PPC_BREAKPOINT_TRIGGER_RW; | |
141 | p.addr_mode = PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE; | |
142 | or | |
143 | p.addr_mode = PPC_BREAKPOINT_MODE_EXACT; | |
144 | ||
145 | p.condition_mode = PPC_BREAKPOINT_CONDITION_NONE; | |
146 | p.addr = (uint64_t) begin_range; | |
147 | /* For PPC_BREAKPOINT_MODE_RANGE_INCLUSIVE addr2 needs to be specified, where | |
148 | * addr2 - addr <= 8 Bytes. | |
149 | */ | |
150 | p.addr2 = (uint64_t) end_range; | |
151 | p.condition_value = 0; | |
152 | ||
153 | 3. PTRACE_DELHWDEBUG | |
154 | ||
155 | Takes an integer which identifies an existing breakpoint or watchpoint | |
156 | (i.e., the value returned from PTRACE_SETHWDEBUG), and deletes the | |
157 | corresponding breakpoint or watchpoint.. |