GDBserver
/home/stan/gdb/src/gdb/gdbserver/spu-low.c
Go to the documentation of this file.
00001 /* Low level interface to SPUs, for the remote server for GDB.
00002    Copyright (C) 2006-2013 Free Software Foundation, Inc.
00003 
00004    Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
00005 
00006    This file is part of GDB.
00007 
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 3 of the License, or
00011    (at your option) any later version.
00012 
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017 
00018    You should have received a copy of the GNU General Public License
00019    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
00020 
00021 #include "server.h"
00022 
00023 #include "gdb_wait.h"
00024 #include <stdio.h>
00025 #include <sys/ptrace.h>
00026 #include <fcntl.h>
00027 #include <string.h>
00028 #include <stdlib.h>
00029 #include <unistd.h>
00030 #include <errno.h>
00031 #include <sys/syscall.h>
00032 #include "filestuff.h"
00033 #include "hostio.h"
00034 
00035 /* Some older glibc versions do not define this.  */
00036 #ifndef __WNOTHREAD
00037 #define __WNOTHREAD     0x20000000      /* Don't wait on children of other
00038                                            threads in this group */
00039 #endif
00040 
00041 #define PTRACE_TYPE_RET long
00042 #define PTRACE_TYPE_ARG3 long
00043 
00044 /* Number of registers.  */
00045 #define SPU_NUM_REGS         130
00046 #define SPU_NUM_CORE_REGS    128
00047 
00048 /* Special registers.  */
00049 #define SPU_ID_REGNUM        128
00050 #define SPU_PC_REGNUM        129
00051 
00052 /* PPU side system calls.  */
00053 #define INSTR_SC        0x44000002
00054 #define NR_spu_run      0x0116
00055 
00056 /* These are used in remote-utils.c.  */
00057 int using_threads = 0;
00058 
00059 /* Defined in auto-generated file reg-spu.c.  */
00060 void init_registers_spu (void);
00061 extern const struct target_desc *tdesc_spu;
00062 
00063 /* Fetch PPU register REGNO.  */
00064 static CORE_ADDR
00065 fetch_ppc_register (int regno)
00066 {
00067   PTRACE_TYPE_RET res;
00068 
00069   int tid = ptid_get_lwp (current_ptid);
00070 
00071 #ifndef __powerpc64__
00072   /* If running as a 32-bit process on a 64-bit system, we attempt
00073      to get the full 64-bit register content of the target process.
00074      If the PPC special ptrace call fails, we're on a 32-bit system;
00075      just fall through to the regular ptrace call in that case.  */
00076   {
00077     char buf[8];
00078 
00079     errno = 0;
00080     ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
00081             (PTRACE_TYPE_ARG3) (regno * 8), buf);
00082     if (errno == 0)
00083       ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
00084               (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
00085     if (errno == 0)
00086       return (CORE_ADDR) *(unsigned long long *)buf;
00087   }
00088 #endif
00089 
00090   errno = 0;
00091   res = ptrace (PT_READ_U, tid,
00092                 (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
00093   if (errno != 0)
00094     {
00095       char mess[128];
00096       sprintf (mess, "reading PPC register #%d", regno);
00097       perror_with_name (mess);
00098     }
00099 
00100   return (CORE_ADDR) (unsigned long) res;
00101 }
00102 
00103 /* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID.  */
00104 static int
00105 fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word)
00106 {
00107   errno = 0;
00108 
00109 #ifndef __powerpc64__
00110   if (memaddr >> 32)
00111     {
00112       unsigned long long addr_8 = (unsigned long long) memaddr;
00113       ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
00114     }
00115   else
00116 #endif
00117     *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
00118 
00119   return errno;
00120 }
00121 
00122 /* Store WORD into PPU memory at (aligned) MEMADDR in thread TID.  */
00123 static int
00124 store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word)
00125 {
00126   errno = 0;
00127 
00128 #ifndef __powerpc64__
00129   if (memaddr >> 32)
00130     {
00131       unsigned long long addr_8 = (unsigned long long) memaddr;
00132       ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
00133     }
00134   else
00135 #endif
00136     ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);
00137 
00138   return errno;
00139 }
00140 
00141 /* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR.  */
00142 static int
00143 fetch_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
00144 {
00145   int i, ret;
00146 
00147   CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
00148   int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
00149                / sizeof (PTRACE_TYPE_RET));
00150   PTRACE_TYPE_RET *buffer;
00151 
00152   int tid = ptid_get_lwp (current_ptid);
00153 
00154   buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
00155   for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
00156     if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[i])) != 0)
00157       return ret;
00158 
00159   memcpy (myaddr,
00160           (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
00161           len);
00162 
00163   return 0;
00164 }
00165 
00166 /* Store LEN bytes from MYADDR to PPU memory at MEMADDR.  */
00167 static int
00168 store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
00169 {
00170   int i, ret;
00171 
00172   CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
00173   int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
00174                / sizeof (PTRACE_TYPE_RET));
00175   PTRACE_TYPE_RET *buffer;
00176 
00177   int tid = ptid_get_lwp (current_ptid);
00178 
00179   buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
00180 
00181   if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
00182     if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[0])) != 0)
00183       return ret;
00184 
00185   if (count > 1)
00186     if ((ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
00187                                                * sizeof (PTRACE_TYPE_RET),
00188                                    &buffer[count - 1])) != 0)
00189       return ret;
00190 
00191   memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
00192           myaddr, len);
00193 
00194   for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
00195     if ((ret = store_ppc_memory_1 (tid, addr, buffer[i])) != 0)
00196       return ret;
00197 
00198   return 0;
00199 }
00200 
00201 
00202 /* If the PPU thread is currently stopped on a spu_run system call,
00203    return to FD and ADDR the file handle and NPC parameter address
00204    used with the system call.  Return non-zero if successful.  */
00205 static int
00206 parse_spufs_run (int *fd, CORE_ADDR *addr)
00207 {
00208   unsigned int insn;
00209   CORE_ADDR pc = fetch_ppc_register (32);  /* nip */
00210 
00211   /* Fetch instruction preceding current NIP.  */
00212   if (fetch_ppc_memory (pc-4, (char *) &insn, 4) != 0)
00213     return 0;
00214   /* It should be a "sc" instruction.  */
00215   if (insn != INSTR_SC)
00216     return 0;
00217   /* System call number should be NR_spu_run.  */
00218   if (fetch_ppc_register (0) != NR_spu_run)
00219     return 0;
00220 
00221   /* Register 3 contains fd, register 4 the NPC param pointer.  */
00222   *fd = fetch_ppc_register (34);  /* orig_gpr3 */
00223   *addr = fetch_ppc_register (4);
00224   return 1;
00225 }
00226 
00227 
00228 /* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
00229    using the /proc file system.  */
00230 static int
00231 spu_proc_xfer_spu (const char *annex, unsigned char *readbuf,
00232                    const unsigned char *writebuf,
00233                    CORE_ADDR offset, int len)
00234 {
00235   char buf[128];
00236   int fd = 0;
00237   int ret = -1;
00238 
00239   if (!annex)
00240     return 0;
00241 
00242   sprintf (buf, "/proc/%ld/fd/%s", ptid_get_lwp (current_ptid), annex);
00243   fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
00244   if (fd <= 0)
00245     return -1;
00246 
00247   if (offset != 0
00248       && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
00249     {
00250       close (fd);
00251       return 0;
00252     }
00253 
00254   if (writebuf)
00255     ret = write (fd, writebuf, (size_t) len);
00256   else if (readbuf)
00257     ret = read (fd, readbuf, (size_t) len);
00258 
00259   close (fd);
00260   return ret;
00261 }
00262 
00263 
00264 /* Start an inferior process and returns its pid.
00265    ALLARGS is a vector of program-name and args. */
00266 static int
00267 spu_create_inferior (char *program, char **allargs)
00268 {
00269   int pid;
00270   ptid_t ptid;
00271   struct process_info *proc;
00272 
00273   pid = fork ();
00274   if (pid < 0)
00275     perror_with_name ("fork");
00276 
00277   if (pid == 0)
00278     {
00279       close_most_fds ();
00280       ptrace (PTRACE_TRACEME, 0, 0, 0);
00281 
00282       setpgid (0, 0);
00283 
00284       execv (program, allargs);
00285       if (errno == ENOENT)
00286         execvp (program, allargs);
00287 
00288       fprintf (stderr, "Cannot exec %s: %s.\n", program,
00289                strerror (errno));
00290       fflush (stderr);
00291       _exit (0177);
00292     }
00293 
00294   proc = add_process (pid, 0);
00295   proc->tdesc = tdesc_spu;
00296 
00297   ptid = ptid_build (pid, pid, 0);
00298   add_thread (ptid, NULL);
00299   return pid;
00300 }
00301 
00302 /* Attach to an inferior process.  */
00303 int
00304 spu_attach (unsigned long  pid)
00305 {
00306   ptid_t ptid;
00307   struct process_info *proc;
00308 
00309   if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
00310     {
00311       fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
00312                strerror (errno), errno);
00313       fflush (stderr);
00314       _exit (0177);
00315     }
00316 
00317   proc = add_process (pid, 1);
00318   proc->tdesc = tdesc_spu;
00319   ptid = ptid_build (pid, pid, 0);
00320   add_thread (ptid, NULL);
00321   return 0;
00322 }
00323 
00324 /* Kill the inferior process.  */
00325 static int
00326 spu_kill (int pid)
00327 {
00328   int status, ret;
00329   struct process_info *process = find_process_pid (pid);
00330   if (process == NULL)
00331     return -1;
00332 
00333   ptrace (PTRACE_KILL, pid, 0, 0);
00334 
00335   do {
00336     ret = waitpid (pid, &status, 0);
00337     if (WIFEXITED (status) || WIFSIGNALED (status))
00338       break;
00339   } while (ret != -1 || errno != ECHILD);
00340 
00341   clear_inferiors ();
00342   remove_process (process);
00343   return 0;
00344 }
00345 
00346 /* Detach from inferior process.  */
00347 static int
00348 spu_detach (int pid)
00349 {
00350   struct process_info *process = find_process_pid (pid);
00351   if (process == NULL)
00352     return -1;
00353 
00354   ptrace (PTRACE_DETACH, pid, 0, 0);
00355 
00356   clear_inferiors ();
00357   remove_process (process);
00358   return 0;
00359 }
00360 
00361 static void
00362 spu_mourn (struct process_info *process)
00363 {
00364   remove_process (process);
00365 }
00366 
00367 static void
00368 spu_join (int pid)
00369 {
00370   int status, ret;
00371 
00372   do {
00373     ret = waitpid (pid, &status, 0);
00374     if (WIFEXITED (status) || WIFSIGNALED (status))
00375       break;
00376   } while (ret != -1 || errno != ECHILD);
00377 }
00378 
00379 /* Return nonzero if the given thread is still alive.  */
00380 static int
00381 spu_thread_alive (ptid_t ptid)
00382 {
00383   return ptid_equal (ptid, current_ptid);
00384 }
00385 
00386 /* Resume process.  */
00387 static void
00388 spu_resume (struct thread_resume *resume_info, size_t n)
00389 {
00390   size_t i;
00391 
00392   for (i = 0; i < n; i++)
00393     if (ptid_equal (resume_info[i].thread, minus_one_ptid)
00394         || ptid_equal (resume_info[i].thread, current_ptid))
00395       break;
00396 
00397   if (i == n)
00398     return;
00399 
00400   /* We don't support hardware single-stepping right now, assume
00401      GDB knows to use software single-stepping.  */
00402   if (resume_info[i].kind == resume_step)
00403     fprintf (stderr, "Hardware single-step not supported.\n");
00404 
00405   regcache_invalidate ();
00406 
00407   errno = 0;
00408   ptrace (PTRACE_CONT, ptid_get_lwp (current_ptid), 0, resume_info[i].sig);
00409   if (errno)
00410     perror_with_name ("ptrace");
00411 }
00412 
00413 /* Wait for process, returns status.  */
00414 static ptid_t
00415 spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
00416 {
00417   int pid = ptid_get_pid (ptid);
00418   int w;
00419   int ret;
00420 
00421   while (1)
00422     {
00423       ret = waitpid (pid, &w, WNOHANG | __WALL | __WNOTHREAD);
00424 
00425       if (ret == -1)
00426         {
00427           if (errno != ECHILD)
00428             perror_with_name ("waitpid");
00429         }
00430       else if (ret > 0)
00431         break;
00432 
00433       usleep (1000);
00434     }
00435 
00436   /* On the first wait, continue running the inferior until we are
00437      blocked inside an spu_run system call.  */
00438   if (!server_waiting)
00439     {
00440       int fd;
00441       CORE_ADDR addr;
00442 
00443       while (!parse_spufs_run (&fd, &addr))
00444         {
00445           ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
00446           waitpid (pid, NULL, __WALL | __WNOTHREAD);
00447         }
00448     }
00449 
00450   if (WIFEXITED (w))
00451     {
00452       fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
00453       ourstatus->kind =  TARGET_WAITKIND_EXITED;
00454       ourstatus->value.integer = WEXITSTATUS (w);
00455       clear_inferiors ();
00456       return pid_to_ptid (ret);
00457     }
00458   else if (!WIFSTOPPED (w))
00459     {
00460       fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
00461       ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
00462       ourstatus->value.sig = gdb_signal_from_host (WTERMSIG (w));
00463       clear_inferiors ();
00464       return pid_to_ptid (ret);
00465     }
00466 
00467   /* After attach, we may have received a SIGSTOP.  Do not return this
00468      as signal to GDB, or else it will try to continue with SIGSTOP ...  */
00469   if (!server_waiting)
00470     {
00471       ourstatus->kind = TARGET_WAITKIND_STOPPED;
00472       ourstatus->value.sig = GDB_SIGNAL_0;
00473       return ptid_build (ret, ret, 0);
00474     }
00475 
00476   ourstatus->kind = TARGET_WAITKIND_STOPPED;
00477   ourstatus->value.sig = gdb_signal_from_host (WSTOPSIG (w));
00478   return ptid_build (ret, ret, 0);
00479 }
00480 
00481 /* Fetch inferior registers.  */
00482 static void
00483 spu_fetch_registers (struct regcache *regcache, int regno)
00484 {
00485   int fd;
00486   CORE_ADDR addr;
00487 
00488   /* We must be stopped on a spu_run system call.  */
00489   if (!parse_spufs_run (&fd, &addr))
00490     return;
00491 
00492   /* The ID register holds the spufs file handle.  */
00493   if (regno == -1 || regno == SPU_ID_REGNUM)
00494     supply_register (regcache, SPU_ID_REGNUM, (char *)&fd);
00495 
00496   /* The NPC register is found at ADDR.  */
00497   if (regno == -1 || regno == SPU_PC_REGNUM)
00498     {
00499       char buf[4];
00500       if (fetch_ppc_memory (addr, buf, 4) == 0)
00501         supply_register (regcache, SPU_PC_REGNUM, buf);
00502     }
00503 
00504   /* The GPRs are found in the "regs" spufs file.  */
00505   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
00506     {
00507       unsigned char buf[16*SPU_NUM_CORE_REGS];
00508       char annex[32];
00509       int i;
00510 
00511       sprintf (annex, "%d/regs", fd);
00512       if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
00513         for (i = 0; i < SPU_NUM_CORE_REGS; i++)
00514           supply_register (regcache, i, buf + i*16);
00515     }
00516 }
00517 
00518 /* Store inferior registers.  */
00519 static void
00520 spu_store_registers (struct regcache *regcache, int regno)
00521 {
00522   int fd;
00523   CORE_ADDR addr;
00524 
00525   /* ??? Some callers use 0 to mean all registers.  */
00526   if (regno == 0)
00527     regno = -1;
00528 
00529   /* We must be stopped on a spu_run system call.  */
00530   if (!parse_spufs_run (&fd, &addr))
00531     return;
00532 
00533   /* The NPC register is found at ADDR.  */
00534   if (regno == -1 || regno == SPU_PC_REGNUM)
00535     {
00536       char buf[4];
00537       collect_register (regcache, SPU_PC_REGNUM, buf);
00538       store_ppc_memory (addr, buf, 4);
00539     }
00540 
00541   /* The GPRs are found in the "regs" spufs file.  */
00542   if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
00543     {
00544       unsigned char buf[16*SPU_NUM_CORE_REGS];
00545       char annex[32];
00546       int i;
00547 
00548       for (i = 0; i < SPU_NUM_CORE_REGS; i++)
00549         collect_register (regcache, i, buf + i*16);
00550 
00551       sprintf (annex, "%d/regs", fd);
00552       spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
00553     }
00554 }
00555 
00556 /* Copy LEN bytes from inferior's memory starting at MEMADDR
00557    to debugger memory starting at MYADDR.  */
00558 static int
00559 spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
00560 {
00561   int fd, ret;
00562   CORE_ADDR addr;
00563   char annex[32], lslr_annex[32], buf[32];
00564   CORE_ADDR lslr;
00565 
00566   /* We must be stopped on a spu_run system call.  */
00567   if (!parse_spufs_run (&fd, &addr))
00568     return 0;
00569 
00570   /* Use the "mem" spufs file to access SPU local store.  */
00571   sprintf (annex, "%d/mem", fd);
00572   ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
00573   if (ret > 0)
00574     return ret == len ? 0 : EIO;
00575 
00576   /* SPU local store access wraps the address around at the
00577      local store limit.  We emulate this here.  To avoid needing
00578      an extra access to retrieve the LSLR, we only do that after
00579      trying the original address first, and getting end-of-file.  */
00580   sprintf (lslr_annex, "%d/lslr", fd);
00581   memset (buf, 0, sizeof buf);
00582   if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
00583                          0, sizeof buf) <= 0)
00584     return ret;
00585 
00586   lslr = strtoul (buf, NULL, 16);
00587   ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr & lslr, len);
00588 
00589   return ret == len ? 0 : EIO;
00590 }
00591 
00592 /* Copy LEN bytes of data from debugger memory at MYADDR
00593    to inferior's memory at MEMADDR.
00594    On failure (cannot write the inferior)
00595    returns the value of errno.  */
00596 static int
00597 spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
00598 {
00599   int fd, ret;
00600   CORE_ADDR addr;
00601   char annex[32], lslr_annex[32], buf[32];
00602   CORE_ADDR lslr;
00603 
00604   /* We must be stopped on a spu_run system call.  */
00605   if (!parse_spufs_run (&fd, &addr))
00606     return 0;
00607 
00608   /* Use the "mem" spufs file to access SPU local store.  */
00609   sprintf (annex, "%d/mem", fd);
00610   ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
00611   if (ret > 0)
00612     return ret == len ? 0 : EIO;
00613 
00614   /* SPU local store access wraps the address around at the
00615      local store limit.  We emulate this here.  To avoid needing
00616      an extra access to retrieve the LSLR, we only do that after
00617      trying the original address first, and getting end-of-file.  */
00618   sprintf (lslr_annex, "%d/lslr", fd);
00619   memset (buf, 0, sizeof buf);
00620   if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
00621                          0, sizeof buf) <= 0)
00622     return ret;
00623 
00624   lslr = strtoul (buf, NULL, 16);
00625   ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr & lslr, len);
00626 
00627   return ret == len ? 0 : EIO;
00628 }
00629 
00630 /* Look up special symbols -- unneded here.  */
00631 static void
00632 spu_look_up_symbols (void)
00633 {
00634 }
00635 
00636 /* Send signal to inferior.  */
00637 static void
00638 spu_request_interrupt (void)
00639 {
00640   syscall (SYS_tkill, ptid_get_lwp (current_ptid), SIGINT);
00641 }
00642 
00643 static struct target_ops spu_target_ops = {
00644   spu_create_inferior,
00645   spu_attach,
00646   spu_kill,
00647   spu_detach,
00648   spu_mourn,
00649   spu_join,
00650   spu_thread_alive,
00651   spu_resume,
00652   spu_wait,
00653   spu_fetch_registers,
00654   spu_store_registers,
00655   NULL, /* prepare_to_access_memory */
00656   NULL, /* done_accessing_memory */
00657   spu_read_memory,
00658   spu_write_memory,
00659   spu_look_up_symbols,
00660   spu_request_interrupt,
00661   NULL,
00662   NULL,
00663   NULL,
00664   NULL,
00665   NULL,
00666   NULL,
00667   NULL,
00668   spu_proc_xfer_spu,
00669   hostio_last_error_from_errno,
00670 };
00671 
00672 void
00673 initialize_low (void)
00674 {
00675   static const unsigned char breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
00676 
00677   set_target_ops (&spu_target_ops);
00678   set_breakpoint_data (breakpoint, sizeof breakpoint);
00679   init_registers_spu ();
00680 }
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines