X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fgdbserver%2Fspu-low.c;h=a56a8893c4a3179b22a73025121e4f17653e451f;hb=45614f153407762d83e8ecaf271b9b6e524c62db;hp=d9ac815d20ff726c3adb29b33a5682a99e2ea353;hpb=505106cdc7c816a44bbfee11daf500f4e5e14072;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/gdbserver/spu-low.c b/gdb/gdbserver/spu-low.c index d9ac815d20..a56a8893c4 100644 --- a/gdb/gdbserver/spu-low.c +++ b/gdb/gdbserver/spu-low.c @@ -1,5 +1,5 @@ /* Low level interface to SPUs, for the remote server for GDB. - Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. + Copyright (C) 2006-2015 Free Software Foundation, Inc. Contributed by Ulrich Weigand . @@ -20,15 +20,13 @@ #include "server.h" -#include -#include +#include "gdb_wait.h" #include #include -#include -#include #include -#include #include +#include "filestuff.h" +#include "hostio.h" /* Some older glibc versions do not define this. */ #ifndef __WNOTHREAD @@ -51,15 +49,12 @@ #define INSTR_SC 0x44000002 #define NR_spu_run 0x0116 -/* Get current thread ID (Linux task ID). */ -#define current_ptid ((struct inferior_list_entry *)current_inferior)->id - /* These are used in remote-utils.c. */ int using_threads = 0; /* Defined in auto-generated file reg-spu.c. */ void init_registers_spu (void); - +extern const struct target_desc *tdesc_spu; /* Fetch PPU register REGNO. */ static CORE_ADDR @@ -206,14 +201,14 @@ store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len) static int parse_spufs_run (int *fd, CORE_ADDR *addr) { - char buf[4]; + unsigned int insn; CORE_ADDR pc = fetch_ppc_register (32); /* nip */ /* Fetch instruction preceding current NIP. */ - if (fetch_ppc_memory (pc-4, buf, 4) != 0) + if (fetch_ppc_memory (pc-4, (char *) &insn, 4) != 0) return 0; /* It should be a "sc" instruction. */ - if (*(unsigned int *)buf != INSTR_SC) + if (insn != INSTR_SC) return 0; /* System call number should be NR_spu_run. */ if (fetch_ppc_register (0) != NR_spu_run) @@ -269,6 +264,7 @@ spu_create_inferior (char *program, char **allargs) { int pid; ptid_t ptid; + struct process_info *proc; pid = fork (); if (pid < 0) @@ -276,6 +272,7 @@ spu_create_inferior (char *program, char **allargs) if (pid == 0) { + close_most_fds (); ptrace (PTRACE_TRACEME, 0, 0, 0); setpgid (0, 0); @@ -290,7 +287,8 @@ spu_create_inferior (char *program, char **allargs) _exit (0177); } - add_process (pid, 0); + proc = add_process (pid, 0); + proc->tdesc = tdesc_spu; ptid = ptid_build (pid, pid, 0); add_thread (ptid, NULL); @@ -302,6 +300,7 @@ int spu_attach (unsigned long pid) { ptid_t ptid; + struct process_info *proc; if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0) { @@ -311,7 +310,8 @@ spu_attach (unsigned long pid) _exit (0177); } - add_process (pid, 1); + proc = add_process (pid, 1); + proc->tdesc = tdesc_spu; ptid = ptid_build (pid, pid, 0); add_thread (ptid, NULL); return 0; @@ -364,11 +364,6 @@ static void spu_join (int pid) { int status, ret; - struct process_info *process; - - process = find_process_pid (pid); - if (process == NULL) - return; do { ret = waitpid (pid, &status, 0); @@ -460,7 +455,7 @@ spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) { fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w)); ourstatus->kind = TARGET_WAITKIND_SIGNALLED; - ourstatus->value.sig = target_signal_from_host (WTERMSIG (w)); + ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w)); clear_inferiors (); return pid_to_ptid (ret); } @@ -470,12 +465,12 @@ spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options) if (!server_waiting) { ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = TARGET_SIGNAL_0; + ourstatus->value.sig = GDB_SIGNAL_0; return ptid_build (ret, ret, 0); } ourstatus->kind = TARGET_WAITKIND_STOPPED; - ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w)); + ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w)); return ptid_build (ret, ret, 0); } @@ -561,7 +556,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 +566,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 +594,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 +604,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; } @@ -619,13 +648,21 @@ static struct target_ops spu_target_ops = { spu_wait, spu_fetch_registers, spu_store_registers, + NULL, /* prepare_to_access_memory */ + NULL, /* done_accessing_memory */ spu_read_memory, spu_write_memory, spu_look_up_symbols, spu_request_interrupt, NULL, + NULL, /* supports_z_point_type */ NULL, NULL, + NULL, /* stopped_by_sw_breakpoint */ + NULL, /* supports_stopped_by_sw_breakpoint */ + NULL, /* stopped_by_hw_breakpoint */ + NULL, /* supports_stopped_by_hw_breakpoint */ + NULL, /* supports_conditional_breakpoints */ NULL, NULL, NULL,