]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbserver/linux-crisv32-low.c
* linespec.c (find_method): Add new not_found_ptr parameter to
[thirdparty/binutils-gdb.git] / gdb / gdbserver / linux-crisv32-low.c
CommitLineData
45b134e5 1/* GNU/Linux/CRIS specific low level interface, for the remote server for GDB.
6aba47ca 2 Copyright (C) 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
0fb0cc75 3 2007, 2008, 2009 Free Software Foundation, Inc.
45b134e5
OF
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
45b134e5
OF
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
45b134e5
OF
19
20#include "server.h"
21#include "linux-low.h"
22#include <sys/ptrace.h>
23
d05b4ac3
UW
24/* Defined in auto-generated file reg-crisv32.c. */
25void init_registers_crisv32 (void);
26
45b134e5
OF
27/* CRISv32 */
28#define cris_num_regs 49
29
30/* Note: Ignoring USP (having the stack pointer in two locations causes trouble
31 without any significant gain). */
32
33/* Locations need to match <include/asm/arch/ptrace.h>. */
34static int cris_regmap[] = {
35 1*4, 2*4, 3*4, 4*4,
36 5*4, 6*4, 7*4, 8*4,
37 9*4, 10*4, 11*4, 12*4,
38 13*4, 14*4, 24*4, 15*4,
39
40 -1, -1, -1, 16*4,
41 -1, 22*4, 23*4, 17*4,
42 -1, -1, 21*4, 20*4,
43 -1, 19*4, -1, 18*4,
44
45 25*4,
46
1b3f6016 47 26*4, -1, -1, 29*4,
45b134e5
OF
48 30*4, 31*4, 32*4, 33*4,
49 34*4, 35*4, 36*4, 37*4,
50 38*4, 39*4, 40*4, -1
1b3f6016 51
45b134e5
OF
52};
53
54extern int debug_threads;
55
56static CORE_ADDR
57cris_get_pc (void)
58{
59 unsigned long pc;
60 collect_register_by_name ("pc", &pc);
61 if (debug_threads)
62 fprintf (stderr, "stop pc is %08lx\n", pc);
63 return pc;
64}
65
66static void
67cris_set_pc (CORE_ADDR pc)
68{
69 unsigned long newpc = pc;
70 supply_register_by_name ("pc", &newpc);
71}
72
73static const unsigned short cris_breakpoint = 0xe938;
74#define cris_breakpoint_len 2
75
76static int
77cris_breakpoint_at (CORE_ADDR where)
78{
79 unsigned short insn;
80
f450004a
DJ
81 (*the_target->read_memory) (where, (unsigned char *) &insn,
82 cris_breakpoint_len);
45b134e5
OF
83 if (insn == cris_breakpoint)
84 return 1;
85
86 /* If necessary, recognize more trap instructions here. GDB only uses the
87 one. */
88 return 0;
89}
90
91/* We only place breakpoints in empty marker functions, and thread locking
92 is outside of the function. So rather than importing software single-step,
93 we can just run until exit. */
94
95/* FIXME: This function should not be needed, since we have PTRACE_SINGLESTEP
96 for CRISv32. Without it, td_ta_event_getmsg in thread_db_create_event
97 will fail when debugging multi-threaded applications. */
98
99static CORE_ADDR
100cris_reinsert_addr (void)
101{
102 unsigned long pc;
103 collect_register_by_name ("srp", &pc);
104 return pc;
105}
106
107static void
108cris_write_data_breakpoint (int bp, unsigned long start, unsigned long end)
109{
110 switch (bp)
111 {
112 case 0:
113 supply_register_by_name ("s3", &start);
114 supply_register_by_name ("s4", &end);
115 break;
116 case 1:
117 supply_register_by_name ("s5", &start);
118 supply_register_by_name ("s6", &end);
119 break;
120 case 2:
121 supply_register_by_name ("s7", &start);
122 supply_register_by_name ("s8", &end);
123 break;
124 case 3:
125 supply_register_by_name ("s9", &start);
126 supply_register_by_name ("s10", &end);
127 break;
128 case 4:
129 supply_register_by_name ("s11", &start);
130 supply_register_by_name ("s12", &end);
131 break;
132 case 5:
133 supply_register_by_name ("s13", &start);
134 supply_register_by_name ("s14", &end);
135 break;
136 }
137}
138
139static int
140cris_insert_watchpoint (char type, CORE_ADDR addr, int len)
141{
142 int bp;
143 unsigned long bp_ctrl;
144 unsigned long start, end;
145 unsigned long ccs;
1b3f6016 146
45b134e5
OF
147 /* Breakpoint/watchpoint types (GDB terminology):
148 0 = memory breakpoint for instructions
149 (not supported; done via memory write instead)
150 1 = hardware breakpoint for instructions (not supported)
151 2 = write watchpoint (supported)
152 3 = read watchpoint (supported)
153 4 = access watchpoint (supported). */
1b3f6016
PA
154
155 if (type < '2' || type > '4')
45b134e5
OF
156 {
157 /* Unsupported. */
158 return 1;
159 }
160
161 /* Read watchpoints are set as access watchpoints, because of GDB's
162 inability to deal with pure read watchpoints. */
163 if (type == '3')
164 type = '4';
165
166 /* Get the configuration register. */
167 collect_register_by_name ("s0", &bp_ctrl);
168
169 /* The watchpoint allocation scheme is the simplest possible.
170 For example, if a region is watched for read and
171 a write watch is requested, a new watchpoint will
172 be used. Also, if a watch for a region that is already
173 covered by one or more existing watchpoints, a new
174 watchpoint will be used. */
1b3f6016 175
45b134e5
OF
176 /* First, find a free data watchpoint. */
177 for (bp = 0; bp < 6; bp++)
178 {
179 /* Each data watchpoint's control registers occupy 2 bits
180 (hence the 3), starting at bit 2 for D0 (hence the 2)
181 with 4 bits between for each watchpoint (yes, the 4). */
1b3f6016 182 if (!(bp_ctrl & (0x3 << (2 + (bp * 4)))))
45b134e5
OF
183 break;
184 }
1b3f6016 185
45b134e5
OF
186 if (bp > 5)
187 {
188 /* We're out of watchpoints. */
189 return -1;
190 }
191
192 /* Configure the control register first. */
193 if (type == '3' || type == '4')
194 {
195 /* Trigger on read. */
196 bp_ctrl |= (1 << (2 + bp * 4));
197 }
1b3f6016 198 if (type == '2' || type == '4')
45b134e5
OF
199 {
200 /* Trigger on write. */
201 bp_ctrl |= (2 << (2 + bp * 4));
202 }
1b3f6016 203
45b134e5
OF
204 /* Setup the configuration register. */
205 supply_register_by_name ("s0", &bp_ctrl);
1b3f6016 206
45b134e5
OF
207 /* Setup the range. */
208 start = addr;
209 end = addr + len - 1;
210
211 /* Configure the watchpoint register. */
212 cris_write_data_breakpoint (bp, start, end);
213
214 collect_register_by_name ("ccs", &ccs);
215 /* Set the S1 flag to enable watchpoints. */
216 ccs |= (1 << 19);
217 supply_register_by_name ("ccs", &ccs);
218
219 return 0;
220}
221
222static int
223cris_remove_watchpoint (char type, CORE_ADDR addr, int len)
224{
225 int bp;
226 unsigned long bp_ctrl;
227 unsigned long start, end;
1b3f6016 228
45b134e5
OF
229 /* Breakpoint/watchpoint types:
230 0 = memory breakpoint for instructions
231 (not supported; done via memory write instead)
232 1 = hardware breakpoint for instructions (not supported)
233 2 = write watchpoint (supported)
234 3 = read watchpoint (supported)
235 4 = access watchpoint (supported). */
236 if (type < '2' || type > '4')
237 return -1;
1b3f6016 238
45b134e5
OF
239 /* Read watchpoints are set as access watchpoints, because of GDB's
240 inability to deal with pure read watchpoints. */
241 if (type == '3')
242 type = '4';
1b3f6016 243
45b134e5
OF
244 /* Get the configuration register. */
245 collect_register_by_name ("s0", &bp_ctrl);
246
247 /* Try to find a watchpoint that is configured for the
248 specified range, then check that read/write also matches. */
1b3f6016 249
45b134e5
OF
250 /* Ugly pointer arithmetic, since I cannot rely on a
251 single switch (addr) as there may be several watchpoints with
252 the same start address for example. */
253
254 unsigned long bp_d_regs[12];
255
256 /* Get all range registers to simplify search. */
257 collect_register_by_name ("s3", &bp_d_regs[0]);
258 collect_register_by_name ("s4", &bp_d_regs[1]);
259 collect_register_by_name ("s5", &bp_d_regs[2]);
260 collect_register_by_name ("s6", &bp_d_regs[3]);
261 collect_register_by_name ("s7", &bp_d_regs[4]);
262 collect_register_by_name ("s8", &bp_d_regs[5]);
263 collect_register_by_name ("s9", &bp_d_regs[6]);
264 collect_register_by_name ("s10", &bp_d_regs[7]);
265 collect_register_by_name ("s11", &bp_d_regs[8]);
266 collect_register_by_name ("s12", &bp_d_regs[9]);
267 collect_register_by_name ("s13", &bp_d_regs[10]);
268 collect_register_by_name ("s14", &bp_d_regs[11]);
269
1b3f6016 270 for (bp = 0; bp < 6; bp++)
45b134e5 271 {
1b3f6016 272 if (bp_d_regs[bp * 2] == addr
45b134e5
OF
273 && bp_d_regs[bp * 2 + 1] == (addr + len - 1)) {
274 /* Matching range. */
275 int bitpos = 2 + bp * 4;
276 int rw_bits;
1b3f6016 277
45b134e5
OF
278 /* Read/write bits for this BP. */
279 rw_bits = (bp_ctrl & (0x3 << bitpos)) >> bitpos;
1b3f6016 280
45b134e5 281 if ((type == '3' && rw_bits == 0x1)
1b3f6016 282 || (type == '2' && rw_bits == 0x2)
45b134e5
OF
283 || (type == '4' && rw_bits == 0x3))
284 {
285 /* Read/write matched. */
286 break;
287 }
288 }
289 }
1b3f6016 290
45b134e5
OF
291 if (bp > 5)
292 {
293 /* No watchpoint matched. */
294 return -1;
295 }
1b3f6016 296
45b134e5
OF
297 /* Found a matching watchpoint. Now, deconfigure it by
298 both disabling read/write in bp_ctrl and zeroing its
299 start/end addresses. */
300 bp_ctrl &= ~(3 << (2 + (bp * 4)));
301 /* Setup the configuration register. */
302 supply_register_by_name ("s0", &bp_ctrl);
303
304 start = end = 0;
305 /* Configure the watchpoint register. */
306 cris_write_data_breakpoint (bp, start, end);
307
308 /* Note that we don't clear the S1 flag here. It's done when continuing. */
309 return 0;
310}
311
312static int
313cris_stopped_by_watchpoint (void)
314{
315 unsigned long exs;
316
317 collect_register_by_name ("exs", &exs);
318
319 return (((exs & 0xff00) >> 8) == 0xc);
320}
321
322static CORE_ADDR
323cris_stopped_data_address (void)
324{
325 unsigned long eda;
326
327 collect_register_by_name ("eda", &eda);
328
329 /* FIXME: Possibly adjust to match watched range. */
330 return eda;
331}
332
333static void
334cris_fill_gregset (void *buf)
335{
336 int i;
337
338 for (i = 0; i < cris_num_regs; i++)
339 {
340 if (cris_regmap[i] != -1)
341 collect_register (i, ((char *) buf) + cris_regmap[i]);
342 }
343}
344
345static void
346cris_store_gregset (const void *buf)
347{
348 int i;
349
350 for (i = 0; i < cris_num_regs; i++)
351 {
352 if (cris_regmap[i] != -1)
353 supply_register (i, ((char *) buf) + cris_regmap[i]);
354 }
355}
356
357typedef unsigned long elf_gregset_t[cris_num_regs];
358
359struct regset_info target_regsets[] = {
360 { PTRACE_GETREGS, PTRACE_SETREGS, sizeof (elf_gregset_t),
361 GENERAL_REGS, cris_fill_gregset, cris_store_gregset },
362 { 0, 0, -1, -1, NULL, NULL }
363};
364
365struct linux_target_ops the_low_target = {
d05b4ac3 366 init_register_crisv32,
45b134e5
OF
367 -1,
368 NULL,
369 NULL,
370 NULL,
371 cris_get_pc,
372 cris_set_pc,
f450004a 373 (const unsigned char *) &cris_breakpoint,
45b134e5
OF
374 cris_breakpoint_len,
375 cris_reinsert_addr,
376 0,
377 cris_breakpoint_at,
378 cris_insert_watchpoint,
379 cris_remove_watchpoint,
380 cris_stopped_by_watchpoint,
381 cris_stopped_data_address,
382};