ChangeLog:

* spu-multiarch.c (spu_xfer_partial): Wrap around local store
	limit on local store memory accesses.
	* spu-linux-nat.c (spu_xfer_partial): Likewise.
	* spu-tdep.c (spu_lslr): Remove.
	(spu_pointer_to_address): Do not truncate addresses.
	(spu_integer_to_address): Likewise.
	(spu_overlay_new_objfile): Use SPU_OVERLAY_LMA.
	* spu-tdep.h: Add comments.
	(SPUADDR_SPU): Respect SPU_OVERLAY_LMA bit.
	(SPU_OVERLAY_LMA): Define.

gdbserver/ChangeLog:

	* spu-low.c (spu_read_memory): Wrap around local store limit.
	(spu_write_memory): Likewise.

testsuite/ChangeLog:

	* gdb.arch/spu-ls.exp: New file.
	* gdb.arch/spu-ls.c: Likewise.
This commit is contained in:
Ulrich Weigand 2010-06-19 17:36:51 +00:00
parent fbece226ba
commit d2ed6730f2
10 changed files with 251 additions and 32 deletions

View File

@ -1,3 +1,16 @@
2010-06-19 Ulrich Weigand <uweigand@de.ibm.com>
* spu-multiarch.c (spu_xfer_partial): Wrap around local store
limit on local store memory accesses.
* spu-linux-nat.c (spu_xfer_partial): Likewise.
* spu-tdep.c (spu_lslr): Remove.
(spu_pointer_to_address): Do not truncate addresses.
(spu_integer_to_address): Likewise.
(spu_overlay_new_objfile): Use SPU_OVERLAY_LMA.
* spu-tdep.h: Add comments.
(SPUADDR_SPU): Respect SPU_OVERLAY_LMA bit.
(SPU_OVERLAY_LMA): Define.
2010-06-18 Stan Shebs <stan@codesourcery.com>
* osdata.c (get_osdata): Warn separately if target does not report

View File

@ -1,3 +1,8 @@
2010-06-19 Ulrich Weigand <uweigand@de.ibm.com>
* spu-low.c (spu_read_memory): Wrap around local store limit.
(spu_write_memory): Likewise.
2010-06-15 Pedro Alves <pedro@codesourcery.com>
* linux-x86-low.c (amd64_emit_const, amd64_emit_void_call_2)

View File

@ -561,7 +561,8 @@ spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
{
int fd, ret;
CORE_ADDR addr;
char annex[32];
char annex[32], lslr_annex[32], buf[32];
CORE_ADDR lslr;
/* We must be stopped on a spu_run system call. */
if (!parse_spufs_run (&fd, &addr))
@ -570,6 +571,22 @@ spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
/* Use the "mem" spufs file to access SPU local store. */
sprintf (annex, "%d/mem", fd);
ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
if (ret > 0)
return ret == len ? 0 : EIO;
/* 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. */
sprintf (lslr_annex, "%d/lslr", fd);
memset (buf, 0, sizeof buf);
if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
0, sizeof buf) <= 0)
return ret;
lslr = strtoul (buf, NULL, 16);
ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr & lslr, len);
return ret == len ? 0 : EIO;
}
@ -582,7 +599,8 @@ spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
{
int fd, ret;
CORE_ADDR addr;
char annex[32];
char annex[32], lslr_annex[32], buf[32];
CORE_ADDR lslr;
/* We must be stopped on a spu_run system call. */
if (!parse_spufs_run (&fd, &addr))
@ -591,6 +609,22 @@ spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
/* Use the "mem" spufs file to access SPU local store. */
sprintf (annex, "%d/mem", fd);
ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
if (ret > 0)
return ret == len ? 0 : EIO;
/* 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. */
sprintf (lslr_annex, "%d/lslr", fd);
memset (buf, 0, sizeof buf);
if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
0, sizeof buf) <= 0)
return ret;
lslr = strtoul (buf, NULL, 16);
ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr & lslr, len);
return ret == len ? 0 : EIO;
}

View File

@ -562,7 +562,10 @@ spu_xfer_partial (struct target_ops *ops,
{
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))
@ -570,7 +573,22 @@ spu_xfer_partial (struct target_ops *ops,
/* 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;

View File

@ -259,14 +259,35 @@ spu_xfer_partial (struct target_ops *ops, enum target_object object,
{
int fd = SPUADDR_SPU (offset);
CORE_ADDR addr = SPUADDR_ADDR (offset);
char mem_annex[32];
char mem_annex[32], lslr_annex[32];
gdb_byte buf[32];
ULONGEST lslr;
LONGEST ret;
if (fd >= 0 && addr < SPU_LS_SIZE)
if (fd >= 0)
{
xsnprintf (mem_annex, sizeof mem_annex, "%d/mem", fd);
ret = ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
mem_annex, readbuf, writebuf,
addr, 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 (ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
lslr_annex, buf, NULL,
0, sizeof buf) <= 0)
return ret;
lslr = strtoulst (buf, NULL, 16);
return ops_beneath->to_xfer_partial (ops_beneath, TARGET_OBJECT_SPU,
mem_annex, readbuf, writebuf,
addr, len);
addr & lslr, len);
}
}

View File

@ -364,23 +364,6 @@ spu_gdbarch_id (struct gdbarch *gdbarch)
return id;
}
static ULONGEST
spu_lslr (int id)
{
gdb_byte buf[32];
char annex[32];
if (id == -1)
return SPU_LS_SIZE - 1;
xsnprintf (annex, sizeof annex, "%d/lslr", id);
memset (buf, 0, sizeof buf);
target_read (&current_target, TARGET_OBJECT_SPU, annex,
buf, 0, sizeof buf);
return strtoulst (buf, NULL, 16);
}
static int
spu_address_class_type_flags (int byte_size, int dwarf2_addr_class)
{
@ -426,7 +409,6 @@ spu_pointer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
int id = spu_gdbarch_id (gdbarch);
ULONGEST lslr = spu_lslr (id);
enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
ULONGEST addr
= extract_unsigned_integer (buf, TYPE_LENGTH (type), byte_order);
@ -435,7 +417,7 @@ spu_pointer_to_address (struct gdbarch *gdbarch,
if (TYPE_ADDRESS_CLASS_1 (type))
return addr;
return addr? SPUADDR (id, addr & lslr) : 0;
return addr? SPUADDR (id, addr) : 0;
}
static CORE_ADDR
@ -443,10 +425,9 @@ spu_integer_to_address (struct gdbarch *gdbarch,
struct type *type, const gdb_byte *buf)
{
int id = spu_gdbarch_id (gdbarch);
ULONGEST lslr = spu_lslr (id);
ULONGEST addr = unpack_long (type, buf);
return SPUADDR (id, addr & lslr);
return SPUADDR (id, addr);
}
@ -1777,7 +1758,7 @@ spu_overlay_update (struct obj_section *osect)
/* Whenever a new objfile is loaded, read the target's _ovly_table.
If there is one, go through all sections and make sure for non-
overlay sections LMA equals VMA, while for overlay sections LMA
is larger than local store size. */
is larger than SPU_OVERLAY_LMA. */
static void
spu_overlay_new_objfile (struct objfile *objfile)
{
@ -1807,7 +1788,7 @@ spu_overlay_new_objfile (struct objfile *objfile)
if (ovly_table[ndx].mapped_ptr == 0)
bfd_section_lma (obfd, bsect) = bfd_section_vma (obfd, bsect);
else
bfd_section_lma (obfd, bsect) = bsect->filepos + SPU_LS_SIZE;
bfd_section_lma (obfd, bsect) = SPU_OVERLAY_LMA + bsect->filepos;
}
}

View File

@ -50,14 +50,71 @@ enum spu_regnum
/* Local store. */
#define SPU_LS_SIZE 0x40000
/* Address conversions. */
/* Address conversions.
In a combined PPU/SPU debugging session, we have to consider multiple
address spaces: the PPU 32- or 64-bit address space, and the 32-bit
local store address space for each SPU context. As it is currently
not yet possible to use the program_space / address_space mechanism
to represent this, we encode all those addresses into one single
64-bit address for the whole process. For SPU programs using overlays,
this address space must also include separate ranges reserved for the
LMA of overlay sections.
The following combinations are supported for combined debugging:
PPU address (this relies on the fact that PPC 64-bit user space
addresses can never have the highest-most bit set):
+-+---------------------------------+
|0| ADDR [63] |
+-+---------------------------------+
SPU address for SPU context with id SPU (this assumes that SPU
IDs, which are file descriptors, are never larger than 2^30):
+-+-+--------------+----------------+
|1|0| SPU [30] | ADDR [32] |
+-+-+--------------+----------------+
SPU overlay section LMA for SPU context with id SPU:
+-+-+--------------+----------------+
|1|1| SPU [30] | ADDR [32] |
+-+-+--------------+----------------+
In SPU stand-alone debugging mode (using spu-linux-nat.c),
the following combinations are supported:
SPU address:
+-+-+--------------+----------------+
|0|0| 0 | ADDR [32] |
+-+-+--------------+----------------+
SPU overlay section LMA:
+-+-+--------------+----------------+
|0|1| 0 | ADDR [32] |
+-+-+--------------+----------------+
The following macros allow manipulation of addresses in the
above formats. */
#define SPUADDR(spu, addr) \
((spu) != -1? (ULONGEST)1 << 63 | (ULONGEST)(spu) << 32 | (addr) : (addr))
#define SPUADDR_SPU(addr) \
(((addr) & (ULONGEST)1 << 63) \
? (int) ((ULONGEST)(addr) >> 32 & 0x7fffffff) \
? (int) ((ULONGEST)(addr) >> 32 & 0x3fffffff) \
: -1)
#define SPUADDR_ADDR(addr) \
(((addr) & (ULONGEST)1 << 63)? (ULONGEST)(addr) & 0xffffffff : (addr))
#define SPU_OVERLAY_LMA ((ULONGEST)1 << 62)
#endif

View File

@ -1,3 +1,8 @@
2010-06-19 Ulrich Weigand <Ulrich.Weigand@de.ibm.com>
* gdb.arch/spu-ls.exp: New file.
* gdb.arch/spu-ls.c: Likewise.
2010-06-18 Stan Shebs <stan@codesourcery.com>
* gdb.threads/thread-specific.exp: Add tests of $_thread.

View File

@ -0,0 +1,31 @@
/* Copyright 2010 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
This file is part of the gdb testsuite.
Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
Tests for SPU local-store access. */
char *ptr = (char *)0x12345678;
char array[256];
int
main (unsigned long long speid, unsigned long long argp,
unsigned long long envp)
{
return 0;
}

View File

@ -0,0 +1,54 @@
# Copyright 2010 Free Software Foundation, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This file is part of the gdb testsuite.
#
# Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
# Tests for SPU local-store access.
if { ![istarget "spu-*-elf"] } then {
verbose "Skipping SPU-only testcase"
return
}
set testfile "spu-ls"
set srcfile ${testfile}.c
set binfile ${objdir}/${subdir}/${testfile}
set sources ${srcdir}/${subdir}/${srcfile}
if { [gdb_compile $sources ${binfile} executable { debug }] != "" } {
return -1
}
gdb_exit
gdb_start
gdb_reinitialize_dir $srcdir/$subdir
gdb_load ${binfile}
if ![runto_main] then {
fail "Can't run to main"
return 0
}
gdb_test "print ptr" " = 0x12345678 \".*\"" "print ptr"
gdb_test_no_output "set ptr = array + \$lslr + 1" "set ptr = array + \$lslr + 1"
gdb_test_no_output "set array\[0\] = 1" "set array\[0\] = 1"
gdb_test "print *ptr" " = 1 '\\\\001'" "print *ptr"
gdb_test_no_output "set *ptr = 2" "set *ptr = 2"
gdb_test "print array\[0\]" " = 2 '\\\\002'" "print array\[0\]"
gdb_exit
return 0