OLD | NEW |
1 /* Target dependent code for GDB on TI C6x systems. | 1 /* Target dependent code for GDB on TI C6x systems. |
2 | 2 |
3 Copyright (C) 2010-2012 Free Software Foundation, Inc. | 3 Copyright (C) 2010-2013 Free Software Foundation, Inc. |
4 Contributed by Andrew Jenner <andrew@codesourcery.com> | 4 Contributed by Andrew Jenner <andrew@codesourcery.com> |
5 Contributed by Yao Qi <yao@codesourcery.com> | 5 Contributed by Yao Qi <yao@codesourcery.com> |
6 | 6 |
7 This file is part of GDB. | 7 This file is part of GDB. |
8 | 8 |
9 This program is free software; you can redistribute it and/or modify | 9 This program is free software; you can redistribute it and/or modify |
10 it under the terms of the GNU General Public License as published by | 10 it under the terms of the GNU General Public License as published by |
11 the Free Software Foundation; either version 3 of the License, or | 11 the Free Software Foundation; either version 3 of the License, or |
12 (at your option) any later version. | 12 (at your option) any later version. |
13 | 13 |
(...skipping 17 matching lines...) Expand all Loading... |
31 #define PTRACE_GET_THREAD_AREA 25 | 31 #define PTRACE_GET_THREAD_AREA 25 |
32 #endif | 32 #endif |
33 | 33 |
34 /* There are at most 69 registers accessible in ptrace. */ | 34 /* There are at most 69 registers accessible in ptrace. */ |
35 #define TIC6X_NUM_REGS 69 | 35 #define TIC6X_NUM_REGS 69 |
36 | 36 |
37 #include <asm/ptrace.h> | 37 #include <asm/ptrace.h> |
38 | 38 |
39 /* Defined in auto-generated file tic6x-c64xp-linux.c. */ | 39 /* Defined in auto-generated file tic6x-c64xp-linux.c. */ |
40 void init_registers_tic6x_c64xp_linux (void); | 40 void init_registers_tic6x_c64xp_linux (void); |
| 41 extern const struct target_desc *tdesc_tic6x_c64xp_linux; |
| 42 |
41 /* Defined in auto-generated file tic6x-c64x-linux.c. */ | 43 /* Defined in auto-generated file tic6x-c64x-linux.c. */ |
42 void init_registers_tic6x_c64x_linux (void); | 44 void init_registers_tic6x_c64x_linux (void); |
| 45 extern const struct target_desc *tdesc_tic6x_c64x_linux; |
| 46 |
43 /* Defined in auto-generated file tic62x-c6xp-linux.c. */ | 47 /* Defined in auto-generated file tic62x-c6xp-linux.c. */ |
44 void init_registers_tic6x_c62x_linux (void); | 48 void init_registers_tic6x_c62x_linux (void); |
| 49 extern const struct target_desc *tdesc_tic6x_c62x_linux; |
45 | 50 |
46 union tic6x_register | 51 union tic6x_register |
47 { | 52 { |
48 unsigned char buf[4]; | 53 unsigned char buf[4]; |
49 | 54 |
50 int reg32; | 55 int reg32; |
51 }; | 56 }; |
52 | 57 |
53 /* Return the ptrace ``address'' of register REGNO. */ | 58 /* Return the ptrace ``address'' of register REGNO. */ |
54 | 59 |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
160 -1, -1, -1 | 165 -1, -1, -1 |
161 }; | 166 }; |
162 | 167 |
163 #endif | 168 #endif |
164 | 169 |
165 extern struct linux_target_ops the_low_target; | 170 extern struct linux_target_ops the_low_target; |
166 | 171 |
167 static int *tic6x_regmap; | 172 static int *tic6x_regmap; |
168 static unsigned int tic6x_breakpoint; | 173 static unsigned int tic6x_breakpoint; |
169 | 174 |
170 static void | 175 /* Forward definition. */ |
171 tic6x_arch_setup (void) | 176 static struct usrregs_info tic6x_usrregs_info; |
| 177 |
| 178 static const struct target_desc * |
| 179 tic6x_read_description (void) |
172 { | 180 { |
173 register unsigned int csr asm ("B2"); | 181 register unsigned int csr asm ("B2"); |
174 unsigned int cpuid; | 182 unsigned int cpuid; |
| 183 const struct target_desc *tdesc; |
175 | 184 |
176 /* Determine the CPU we're running on to find the register order. */ | 185 /* Determine the CPU we're running on to find the register order. */ |
177 __asm__ ("MVC .S2 CSR,%0" : "=r" (csr) :); | 186 __asm__ ("MVC .S2 CSR,%0" : "=r" (csr) :); |
178 cpuid = csr >> 24; | 187 cpuid = csr >> 24; |
179 switch (cpuid) | 188 switch (cpuid) |
180 { | 189 { |
181 case 0x00: /* C62x */ | 190 case 0x00: /* C62x */ |
182 case 0x02: /* C67x */ | 191 case 0x02: /* C67x */ |
183 tic6x_regmap = tic6x_regmap_c62x; | 192 tic6x_regmap = tic6x_regmap_c62x; |
184 tic6x_breakpoint = 0x0000a122; /* BNOP .S2 0,5 */ | 193 tic6x_breakpoint = 0x0000a122; /* BNOP .S2 0,5 */ |
185 init_registers_tic6x_c62x_linux (); | 194 tdesc = tdesc_tic6x_c62x_linux; |
186 break; | 195 break; |
187 case 0x03: /* C67x+ */ | 196 case 0x03: /* C67x+ */ |
188 tic6x_regmap = tic6x_regmap_c64x; | 197 tic6x_regmap = tic6x_regmap_c64x; |
189 tic6x_breakpoint = 0x0000a122; /* BNOP .S2 0,5 */ | 198 tic6x_breakpoint = 0x0000a122; /* BNOP .S2 0,5 */ |
190 init_registers_tic6x_c64x_linux (); | 199 tdesc = tdesc_tic6x_c64x_linux; |
191 break; | 200 break; |
192 case 0x0c: /* C64x */ | 201 case 0x0c: /* C64x */ |
193 tic6x_regmap = tic6x_regmap_c64x; | 202 tic6x_regmap = tic6x_regmap_c64x; |
194 tic6x_breakpoint = 0x0000a122; /* BNOP .S2 0,5 */ | 203 tic6x_breakpoint = 0x0000a122; /* BNOP .S2 0,5 */ |
195 init_registers_tic6x_c64x_linux (); | 204 tdesc = tdesc_tic6x_c64x_linux; |
196 break; | 205 break; |
197 case 0x10: /* C64x+ */ | 206 case 0x10: /* C64x+ */ |
198 case 0x14: /* C674x */ | 207 case 0x14: /* C674x */ |
199 case 0x15: /* C66x */ | 208 case 0x15: /* C66x */ |
200 tic6x_regmap = tic6x_regmap_c64xp; | 209 tic6x_regmap = tic6x_regmap_c64xp; |
201 tic6x_breakpoint = 0x56454314; /* illegal opcode */ | 210 tic6x_breakpoint = 0x56454314; /* illegal opcode */ |
202 init_registers_tic6x_c64xp_linux (); | 211 tdesc = tdesc_tic6x_c64xp_linux; |
203 break; | 212 break; |
204 default: | 213 default: |
205 error ("Unknown CPU ID 0x%02x", cpuid); | 214 error ("Unknown CPU ID 0x%02x", cpuid); |
206 } | 215 } |
207 the_low_target.regmap = tic6x_regmap; | 216 tic6x_usrregs_info.regmap = tic6x_regmap; |
| 217 return tdesc; |
208 } | 218 } |
209 | 219 |
210 static int | 220 static int |
211 tic6x_cannot_fetch_register (int regno) | 221 tic6x_cannot_fetch_register (int regno) |
212 { | 222 { |
213 return (tic6x_regmap[regno] == -1); | 223 return (tic6x_regmap[regno] == -1); |
214 } | 224 } |
215 | 225 |
216 static int | 226 static int |
217 tic6x_cannot_store_register (int regno) | 227 tic6x_cannot_store_register (int regno) |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
304 tic6x_store_gregset (struct regcache *regcache, const void *buf) | 314 tic6x_store_gregset (struct regcache *regcache, const void *buf) |
305 { | 315 { |
306 const union tic6x_register *regset = buf; | 316 const union tic6x_register *regset = buf; |
307 int i; | 317 int i; |
308 | 318 |
309 for (i = 0; i < TIC6X_NUM_REGS; i++) | 319 for (i = 0; i < TIC6X_NUM_REGS; i++) |
310 if (tic6x_regmap[i] != -1) | 320 if (tic6x_regmap[i] != -1) |
311 tic6x_supply_register (regcache, i, regset + tic6x_regmap[i]); | 321 tic6x_supply_register (regcache, i, regset + tic6x_regmap[i]); |
312 } | 322 } |
313 | 323 |
314 struct regset_info target_regsets[] = { | 324 static struct regset_info tic6x_regsets[] = { |
315 { PTRACE_GETREGS, PTRACE_SETREGS, 0, TIC6X_NUM_REGS * 4, GENERAL_REGS, | 325 { PTRACE_GETREGS, PTRACE_SETREGS, 0, TIC6X_NUM_REGS * 4, GENERAL_REGS, |
316 tic6x_fill_gregset, tic6x_store_gregset }, | 326 tic6x_fill_gregset, tic6x_store_gregset }, |
317 { 0, 0, 0, -1, -1, NULL, NULL } | 327 { 0, 0, 0, -1, -1, NULL, NULL } |
318 }; | 328 }; |
319 | 329 |
| 330 static void |
| 331 tic6x_arch_setup (void) |
| 332 { |
| 333 current_process ()->tdesc = tic6x_read_description (); |
| 334 } |
| 335 |
| 336 static struct regsets_info tic6x_regsets_info = |
| 337 { |
| 338 tic6x_regsets, /* regsets */ |
| 339 0, /* num_regsets */ |
| 340 NULL, /* disabled_regsets */ |
| 341 }; |
| 342 |
| 343 static struct usrregs_info tic6x_usrregs_info = |
| 344 { |
| 345 TIC6X_NUM_REGS, |
| 346 NULL, /* Set in tic6x_read_description. */ |
| 347 }; |
| 348 |
| 349 static struct regs_info regs_info = |
| 350 { |
| 351 NULL, /* regset_bitmap */ |
| 352 &tic6x_usrregs_info, |
| 353 &tic6x_regsets_info |
| 354 }; |
| 355 |
| 356 static const struct regs_info * |
| 357 tic6x_regs_info (void) |
| 358 { |
| 359 return ®s_info; |
| 360 } |
| 361 |
320 struct linux_target_ops the_low_target = { | 362 struct linux_target_ops the_low_target = { |
321 tic6x_arch_setup, | 363 tic6x_arch_setup, |
322 TIC6X_NUM_REGS, | 364 tic6x_regs_info, |
323 0, | |
324 NULL, | |
325 tic6x_cannot_fetch_register, | 365 tic6x_cannot_fetch_register, |
326 tic6x_cannot_store_register, | 366 tic6x_cannot_store_register, |
327 NULL, /* fetch_register */ | 367 NULL, /* fetch_register */ |
328 tic6x_get_pc, | 368 tic6x_get_pc, |
329 tic6x_set_pc, | 369 tic6x_set_pc, |
330 (const unsigned char *) &tic6x_breakpoint, | 370 (const unsigned char *) &tic6x_breakpoint, |
331 tic6x_breakpoint_len, | 371 tic6x_breakpoint_len, |
332 NULL, | 372 NULL, |
333 0, | 373 0, |
334 tic6x_breakpoint_at, | 374 tic6x_breakpoint_at, |
335 }; | 375 }; |
| 376 |
| 377 void |
| 378 initialize_low_arch (void) |
| 379 { |
| 380 /* Initialize the Linux target descriptions. */ |
| 381 init_registers_tic6x_c64xp_linux (); |
| 382 init_registers_tic6x_c64x_linux (); |
| 383 init_registers_tic6x_c62x_linux (); |
| 384 |
| 385 initialize_regsets_info (&tic6x_regsets_info); |
| 386 } |
OLD | NEW |