1 /* Cell SPU GNU/Linux multi-architecture debugging support.
2 Copyright (C) 2009 Free Software Foundation, Inc.
4 Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
6 This file is part of GDB.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #include "gdb_string.h"
25 #include "gdb_assert.h"
26 #include "arch-utils.h"
36 #include "ppc-linux-tdep.h"
39 /* This module's target vector. */
40 static struct target_ops spu_ops
;
42 /* Number of SPE objects loaded into the current inferior. */
43 static int spu_nr_solib
;
45 /* Stand-alone SPE executable? */
46 #define spu_standalone_p() \
47 (symfile_objfile && symfile_objfile->obfd \
48 && bfd_get_arch (symfile_objfile->obfd) == bfd_arch_spu)
50 /* PPU side system calls. */
51 #define INSTR_SC 0x44000002
52 #define NR_spu_run 0x0116
54 /* If the PPU thread is currently stopped on a spu_run system call,
55 return to FD and ADDR the file handle and NPC parameter address
56 used with the system call. Return non-zero if successful. */
58 parse_spufs_run (ptid_t ptid
, int *fd
, CORE_ADDR
*addr
)
60 enum bfd_endian byte_order
= gdbarch_byte_order (target_gdbarch
);
61 struct gdbarch_tdep
*tdep
;
62 struct regcache
*regcache
;
67 /* If we're not on PPU, there's nothing to detect. */
68 if (gdbarch_bfd_arch_info (target_gdbarch
)->arch
!= bfd_arch_powerpc
)
71 /* Get PPU-side registers. */
72 regcache
= get_thread_arch_regcache (ptid
, target_gdbarch
);
73 tdep
= gdbarch_tdep (target_gdbarch
);
75 /* Fetch instruction preceding current NIP. */
76 if (target_read_memory (regcache_read_pc (regcache
) - 4, buf
, 4) != 0)
78 /* It should be a "sc" instruction. */
79 if (extract_unsigned_integer (buf
, 4, byte_order
) != INSTR_SC
)
81 /* System call number should be NR_spu_run. */
82 regcache_cooked_read_unsigned (regcache
, tdep
->ppc_gp0_regnum
, ®val
);
83 if (regval
!= NR_spu_run
)
86 /* Register 3 contains fd, register 4 the NPC param pointer. */
87 regcache_cooked_read_unsigned (regcache
, PPC_ORIG_R3_REGNUM
, ®val
);
89 regcache_cooked_read_unsigned (regcache
, tdep
->ppc_gp0_regnum
+ 4, ®val
);
90 *addr
= (CORE_ADDR
) regval
;
94 /* Find gdbarch for SPU context SPUFS_FD. */
95 static struct gdbarch
*
96 spu_gdbarch (int spufs_fd
)
98 struct gdbarch_info info
;
99 gdbarch_info_init (&info
);
100 info
.bfd_arch_info
= bfd_lookup_arch (bfd_arch_spu
, bfd_mach_spu
);
101 info
.byte_order
= BFD_ENDIAN_BIG
;
102 info
.osabi
= GDB_OSABI_LINUX
;
103 info
.tdep_info
= (void *) &spufs_fd
;
104 return gdbarch_find_by_info (info
);
107 /* Override the to_thread_architecture routine. */
108 static struct gdbarch
*
109 spu_thread_architecture (struct target_ops
*ops
, ptid_t ptid
)
112 CORE_ADDR spufs_addr
;
114 if (parse_spufs_run (ptid
, &spufs_fd
, &spufs_addr
))
115 return spu_gdbarch (spufs_fd
);
117 return target_gdbarch
;
120 /* Override the to_region_ok_for_hw_watchpoint routine. */
122 spu_region_ok_for_hw_watchpoint (CORE_ADDR addr
, int len
)
124 struct target_ops
*ops_beneath
= find_target_beneath (&spu_ops
);
125 while (ops_beneath
&& !ops_beneath
->to_region_ok_for_hw_watchpoint
)
126 ops_beneath
= find_target_beneath (ops_beneath
);
128 /* We cannot watch SPU local store. */
129 if (SPUADDR_SPU (addr
) != -1)
133 return ops_beneath
->to_region_ok_for_hw_watchpoint (addr
, len
);
138 /* Override the to_fetch_registers routine. */
140 spu_fetch_registers (struct target_ops
*ops
,
141 struct regcache
*regcache
, int regno
)
143 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
144 enum bfd_endian byte_order
= gdbarch_byte_order (gdbarch
);
145 struct target_ops
*ops_beneath
= find_target_beneath (ops
);
147 CORE_ADDR spufs_addr
;
149 /* This version applies only if we're currently in spu_run. */
150 if (gdbarch_bfd_arch_info (gdbarch
)->arch
!= bfd_arch_spu
)
152 while (ops_beneath
&& !ops_beneath
->to_fetch_registers
)
153 ops_beneath
= find_target_beneath (ops_beneath
);
155 gdb_assert (ops_beneath
);
156 ops_beneath
->to_fetch_registers (ops_beneath
, regcache
, regno
);
160 /* We must be stopped on a spu_run system call. */
161 if (!parse_spufs_run (inferior_ptid
, &spufs_fd
, &spufs_addr
))
164 /* The ID register holds the spufs file handle. */
165 if (regno
== -1 || regno
== SPU_ID_REGNUM
)
168 store_unsigned_integer (buf
, 4, byte_order
, spufs_fd
);
169 regcache_raw_supply (regcache
, SPU_ID_REGNUM
, buf
);
172 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
173 if (regno
== -1 || regno
== SPU_PC_REGNUM
)
177 if (target_read (ops_beneath
, TARGET_OBJECT_MEMORY
, NULL
,
178 buf
, spufs_addr
, sizeof buf
) == sizeof buf
)
179 regcache_raw_supply (regcache
, SPU_PC_REGNUM
, buf
);
182 /* The GPRs are found in the "regs" spufs file. */
183 if (regno
== -1 || (regno
>= 0 && regno
< SPU_NUM_GPRS
))
185 char buf
[16 * SPU_NUM_GPRS
], annex
[32];
188 xsnprintf (annex
, sizeof annex
, "%d/regs", spufs_fd
);
189 if (target_read (ops_beneath
, TARGET_OBJECT_SPU
, annex
,
190 buf
, 0, sizeof buf
) == sizeof buf
)
191 for (i
= 0; i
< SPU_NUM_GPRS
; i
++)
192 regcache_raw_supply (regcache
, i
, buf
+ i
*16);
196 /* Override the to_store_registers routine. */
198 spu_store_registers (struct target_ops
*ops
,
199 struct regcache
*regcache
, int regno
)
201 struct gdbarch
*gdbarch
= get_regcache_arch (regcache
);
202 struct target_ops
*ops_beneath
= find_target_beneath (ops
);
204 CORE_ADDR spufs_addr
;
206 /* This version applies only if we're currently in spu_run. */
207 if (gdbarch_bfd_arch_info (gdbarch
)->arch
!= bfd_arch_spu
)
209 while (ops_beneath
&& !ops_beneath
->to_fetch_registers
)
210 ops_beneath
= find_target_beneath (ops_beneath
);
212 gdb_assert (ops_beneath
);
213 ops_beneath
->to_store_registers (ops_beneath
, regcache
, regno
);
217 /* We must be stopped on a spu_run system call. */
218 if (!parse_spufs_run (inferior_ptid
, &spufs_fd
, &spufs_addr
))
221 /* The NPC register is found in PPC memory at SPUFS_ADDR. */
222 if (regno
== -1 || regno
== SPU_PC_REGNUM
)
225 regcache_raw_collect (regcache
, SPU_PC_REGNUM
, buf
);
227 target_write (ops_beneath
, TARGET_OBJECT_MEMORY
, NULL
,
228 buf
, spufs_addr
, sizeof buf
);
231 /* The GPRs are found in the "regs" spufs file. */
232 if (regno
== -1 || (regno
>= 0 && regno
< SPU_NUM_GPRS
))
234 char buf
[16 * SPU_NUM_GPRS
], annex
[32];
237 for (i
= 0; i
< SPU_NUM_GPRS
; i
++)
238 regcache_raw_collect (regcache
, i
, buf
+ i
*16);
240 xsnprintf (annex
, sizeof annex
, "%d/regs", spufs_fd
);
241 target_write (ops_beneath
, TARGET_OBJECT_SPU
, annex
,
246 /* Override the to_xfer_partial routine. */
248 spu_xfer_partial (struct target_ops
*ops
, enum target_object object
,
249 const char *annex
, gdb_byte
*readbuf
,
250 const gdb_byte
*writebuf
, ULONGEST offset
, LONGEST len
)
252 struct target_ops
*ops_beneath
= find_target_beneath (ops
);
253 while (ops_beneath
&& !ops_beneath
->to_xfer_partial
)
254 ops_beneath
= find_target_beneath (ops_beneath
);
255 gdb_assert (ops_beneath
);
257 /* Use the "mem" spufs file to access SPU local store. */
258 if (object
== TARGET_OBJECT_MEMORY
)
260 int fd
= SPUADDR_SPU (offset
);
261 CORE_ADDR addr
= SPUADDR_ADDR (offset
);
264 if (fd
>= 0 && addr
< SPU_LS_SIZE
)
266 xsnprintf (mem_annex
, sizeof mem_annex
, "%d/mem", fd
);
267 return ops_beneath
->to_xfer_partial (ops_beneath
, TARGET_OBJECT_SPU
,
268 mem_annex
, readbuf
, writebuf
,
273 return ops_beneath
->to_xfer_partial (ops_beneath
, object
, annex
,
274 readbuf
, writebuf
, offset
, len
);
277 /* Override the to_search_memory routine. */
279 spu_search_memory (struct target_ops
* ops
,
280 CORE_ADDR start_addr
, ULONGEST search_space_len
,
281 const gdb_byte
*pattern
, ULONGEST pattern_len
,
282 CORE_ADDR
*found_addrp
)
284 struct target_ops
*ops_beneath
= find_target_beneath (ops
);
285 while (ops_beneath
&& !ops_beneath
->to_search_memory
)
286 ops_beneath
= find_target_beneath (ops_beneath
);
288 /* For SPU local store, always fall back to the simple method. Likewise
289 if we do not have any target-specific special implementation. */
290 if (!ops_beneath
|| SPUADDR_SPU (start_addr
) >= 0)
291 return simple_search_memory (ops
,
292 start_addr
, search_space_len
,
293 pattern
, pattern_len
, found_addrp
);
295 return ops_beneath
->to_search_memory (ops_beneath
,
296 start_addr
, search_space_len
,
297 pattern
, pattern_len
, found_addrp
);
301 /* Push and pop the SPU multi-architecture support target. */
304 spu_multiarch_activate (void)
306 /* If GDB was configured without SPU architecture support,
307 we cannot install SPU multi-architecture support either. */
308 if (spu_gdbarch (-1) == NULL
)
311 push_target (&spu_ops
);
313 /* Make sure the thread architecture is re-evaluated. */
314 registers_changed ();
318 spu_multiarch_deactivate (void)
320 unpush_target (&spu_ops
);
322 /* Make sure the thread architecture is re-evaluated. */
323 registers_changed ();
327 spu_multiarch_inferior_created (struct target_ops
*ops
, int from_tty
)
329 if (spu_standalone_p ())
330 spu_multiarch_activate ();
334 spu_multiarch_solib_loaded (struct so_list
*so
)
336 if (!spu_standalone_p ())
337 if (so
->abfd
&& bfd_get_arch (so
->abfd
) == bfd_arch_spu
)
338 if (spu_nr_solib
++ == 0)
339 spu_multiarch_activate ();
343 spu_multiarch_solib_unloaded (struct so_list
*so
)
345 if (!spu_standalone_p ())
346 if (so
->abfd
&& bfd_get_arch (so
->abfd
) == bfd_arch_spu
)
347 if (--spu_nr_solib
== 0)
348 spu_multiarch_deactivate ();
352 spu_mourn_inferior (struct target_ops
*ops
)
354 struct target_ops
*ops_beneath
= find_target_beneath (ops
);
355 while (ops_beneath
&& !ops_beneath
->to_mourn_inferior
)
356 ops_beneath
= find_target_beneath (ops_beneath
);
358 gdb_assert (ops_beneath
);
359 ops_beneath
->to_mourn_inferior (ops_beneath
);
360 spu_multiarch_deactivate ();
364 /* Initialize the SPU multi-architecture support target. */
369 spu_ops
.to_shortname
= "spu";
370 spu_ops
.to_longname
= "SPU multi-architecture support.";
371 spu_ops
.to_doc
= "SPU multi-architecture support.";
372 spu_ops
.to_mourn_inferior
= spu_mourn_inferior
;
373 spu_ops
.to_fetch_registers
= spu_fetch_registers
;
374 spu_ops
.to_store_registers
= spu_store_registers
;
375 spu_ops
.to_xfer_partial
= spu_xfer_partial
;
376 spu_ops
.to_search_memory
= spu_search_memory
;
377 spu_ops
.to_region_ok_for_hw_watchpoint
= spu_region_ok_for_hw_watchpoint
;
378 spu_ops
.to_thread_architecture
= spu_thread_architecture
;
379 spu_ops
.to_stratum
= arch_stratum
;
380 spu_ops
.to_magic
= OPS_MAGIC
;
384 _initialize_spu_multiarch (void)
386 /* Install ourselves on the target stack. */
388 add_target (&spu_ops
);
390 /* Install observers to watch for SPU objects. */
391 observer_attach_inferior_created (spu_multiarch_inferior_created
);
392 observer_attach_solib_loaded (spu_multiarch_solib_loaded
);
393 observer_attach_solib_unloaded (spu_multiarch_solib_unloaded
);