/* SPU native-dependent code for GDB, the GNU debugger.
- Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
static int
parse_spufs_run (int *fd, ULONGEST *addr)
{
+ enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
gdb_byte buf[4];
ULONGEST pc = fetch_ppc_register (32); /* nip */
if (fetch_ppc_memory (pc-4, buf, 4) != 0)
return 0;
/* It should be a "sc" instruction. */
- if (extract_unsigned_integer (buf, 4) != INSTR_SC)
+ if (extract_unsigned_integer (buf, 4, byte_order) != INSTR_SC)
return 0;
/* System call number should be NR_spu_run. */
if (fetch_ppc_register (0) != NR_spu_run)
/* The ID register holds the spufs file handle. */
if (regno == -1 || regno == SPU_ID_REGNUM)
{
+ struct gdbarch *gdbarch = get_regcache_arch (regcache);
+ enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
char buf[4];
- store_unsigned_integer (buf, 4, fd);
+ store_unsigned_integer (buf, 4, byte_order, fd);
regcache_raw_supply (regcache, SPU_ID_REGNUM, buf);
}
{
int fd;
ULONGEST addr;
- char mem_annex[32];
+ char mem_annex[32], lslr_annex[32];
+ gdb_byte buf[32];
+ ULONGEST lslr;
+ LONGEST ret;
/* We must be stopped on a spu_run system call. */
if (!parse_spufs_run (&fd, &addr))
/* Use the "mem" spufs file to access SPU local store. */
xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
- return spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
+ ret = spu_proc_xfer_spu (mem_annex, readbuf, writebuf, offset, len);
+ if (ret > 0)
+ return ret;
+
+ /* SPU local store access wraps the address around at the
+ local store limit. We emulate this here. To avoid needing
+ an extra access to retrieve the LSLR, we only do that after
+ trying the original address first, and getting end-of-file. */
+ xsnprintf (lslr_annex, sizeof lslr_annex, "%d/lslr", fd);
+ memset (buf, 0, sizeof buf);
+ if (spu_proc_xfer_spu (lslr_annex, buf, NULL, 0, sizeof buf) <= 0)
+ return ret;
+
+ lslr = strtoulst (buf, NULL, 16);
+ return spu_proc_xfer_spu (mem_annex, readbuf, writebuf,
+ offset & lslr, len);
}
return -1;