2011-02-11 Yao Qi <yao@codesourcery.com>
[deliverable/binutils-gdb.git] / gdb / gdbserver / spu-low.c
CommitLineData
a13e2c95 1/* Low level interface to SPUs, for the remote server for GDB.
7b6bb8da
JB
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
a13e2c95
UW
4
5 Contributed by Ulrich Weigand <uweigand@de.ibm.com>.
6
7 This file is part of GDB.
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
a9762ec7 11 the Free Software Foundation; either version 3 of the License, or
a13e2c95
UW
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
a9762ec7 20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
a13e2c95
UW
21
22#include "server.h"
23
24#include <sys/wait.h>
25#include <stdio.h>
26#include <sys/ptrace.h>
27#include <fcntl.h>
28#include <string.h>
29#include <stdlib.h>
30#include <unistd.h>
31#include <errno.h>
32#include <sys/syscall.h>
33
34/* Some older glibc versions do not define this. */
35#ifndef __WNOTHREAD
36#define __WNOTHREAD 0x20000000 /* Don't wait on children of other
1b3f6016 37 threads in this group */
a13e2c95
UW
38#endif
39
40#define PTRACE_TYPE_RET long
41#define PTRACE_TYPE_ARG3 long
42
43/* Number of registers. */
44#define SPU_NUM_REGS 130
45#define SPU_NUM_CORE_REGS 128
46
47/* Special registers. */
48#define SPU_ID_REGNUM 128
49#define SPU_PC_REGNUM 129
50
51/* PPU side system calls. */
52#define INSTR_SC 0x44000002
53#define NR_spu_run 0x0116
54
55/* Get current thread ID (Linux task ID). */
5472f405 56#define current_ptid ((struct inferior_list_entry *)current_inferior)->id
a13e2c95
UW
57
58/* These are used in remote-utils.c. */
59int using_threads = 0;
a13e2c95 60
d05b4ac3
UW
61/* Defined in auto-generated file reg-spu.c. */
62void init_registers_spu (void);
63
a13e2c95
UW
64
65/* Fetch PPU register REGNO. */
66static CORE_ADDR
67fetch_ppc_register (int regno)
68{
69 PTRACE_TYPE_RET res;
70
5472f405 71 int tid = ptid_get_lwp (current_ptid);
a13e2c95
UW
72
73#ifndef __powerpc64__
74 /* If running as a 32-bit process on a 64-bit system, we attempt
75 to get the full 64-bit register content of the target process.
76 If the PPC special ptrace call fails, we're on a 32-bit system;
77 just fall through to the regular ptrace call in that case. */
78 {
79 char buf[8];
80
81 errno = 0;
82 ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
83 (PTRACE_TYPE_ARG3) (regno * 8), buf);
84 if (errno == 0)
85 ptrace (PPC_PTRACE_PEEKUSR_3264, tid,
86 (PTRACE_TYPE_ARG3) (regno * 8 + 4), buf + 4);
87 if (errno == 0)
88 return (CORE_ADDR) *(unsigned long long *)buf;
89 }
90#endif
91
92 errno = 0;
93 res = ptrace (PT_READ_U, tid,
1b3f6016 94 (PTRACE_TYPE_ARG3) (regno * sizeof (PTRACE_TYPE_RET)), 0);
a13e2c95
UW
95 if (errno != 0)
96 {
97 char mess[128];
98 sprintf (mess, "reading PPC register #%d", regno);
99 perror_with_name (mess);
100 }
101
102 return (CORE_ADDR) (unsigned long) res;
103}
104
105/* Fetch WORD from PPU memory at (aligned) MEMADDR in thread TID. */
106static int
107fetch_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET *word)
108{
109 errno = 0;
110
111#ifndef __powerpc64__
112 if (memaddr >> 32)
113 {
114 unsigned long long addr_8 = (unsigned long long) memaddr;
115 ptrace (PPC_PTRACE_PEEKTEXT_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
116 }
117 else
118#endif
119 *word = ptrace (PT_READ_I, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, 0);
120
121 return errno;
122}
123
124/* Store WORD into PPU memory at (aligned) MEMADDR in thread TID. */
125static int
126store_ppc_memory_1 (int tid, CORE_ADDR memaddr, PTRACE_TYPE_RET word)
127{
128 errno = 0;
129
130#ifndef __powerpc64__
131 if (memaddr >> 32)
132 {
133 unsigned long long addr_8 = (unsigned long long) memaddr;
134 ptrace (PPC_PTRACE_POKEDATA_3264, tid, (PTRACE_TYPE_ARG3) &addr_8, word);
135 }
136 else
137#endif
138 ptrace (PT_WRITE_D, tid, (PTRACE_TYPE_ARG3) (size_t) memaddr, word);
139
140 return errno;
141}
142
143/* Fetch LEN bytes of PPU memory at MEMADDR to MYADDR. */
144static int
145fetch_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
146{
147 int i, ret;
148
149 CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
150 int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
151 / sizeof (PTRACE_TYPE_RET));
152 PTRACE_TYPE_RET *buffer;
153
5472f405 154 int tid = ptid_get_lwp (current_ptid);
a13e2c95
UW
155
156 buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
157 for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
158 if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[i])) != 0)
159 return ret;
160
161 memcpy (myaddr,
162 (char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
163 len);
164
165 return 0;
166}
167
168/* Store LEN bytes from MYADDR to PPU memory at MEMADDR. */
169static int
170store_ppc_memory (CORE_ADDR memaddr, char *myaddr, int len)
171{
172 int i, ret;
173
174 CORE_ADDR addr = memaddr & -(CORE_ADDR) sizeof (PTRACE_TYPE_RET);
175 int count = ((((memaddr + len) - addr) + sizeof (PTRACE_TYPE_RET) - 1)
176 / sizeof (PTRACE_TYPE_RET));
177 PTRACE_TYPE_RET *buffer;
178
5472f405 179 int tid = ptid_get_lwp (current_ptid);
a13e2c95
UW
180
181 buffer = (PTRACE_TYPE_RET *) alloca (count * sizeof (PTRACE_TYPE_RET));
182
183 if (addr != memaddr || len < (int) sizeof (PTRACE_TYPE_RET))
184 if ((ret = fetch_ppc_memory_1 (tid, addr, &buffer[0])) != 0)
185 return ret;
186
187 if (count > 1)
188 if ((ret = fetch_ppc_memory_1 (tid, addr + (count - 1)
189 * sizeof (PTRACE_TYPE_RET),
190 &buffer[count - 1])) != 0)
191 return ret;
192
193 memcpy ((char *) buffer + (memaddr & (sizeof (PTRACE_TYPE_RET) - 1)),
1b3f6016 194 myaddr, len);
a13e2c95
UW
195
196 for (i = 0; i < count; i++, addr += sizeof (PTRACE_TYPE_RET))
197 if ((ret = store_ppc_memory_1 (tid, addr, buffer[i])) != 0)
198 return ret;
199
200 return 0;
201}
202
203
204/* If the PPU thread is currently stopped on a spu_run system call,
205 return to FD and ADDR the file handle and NPC parameter address
206 used with the system call. Return non-zero if successful. */
1b3f6016 207static int
a13e2c95
UW
208parse_spufs_run (int *fd, CORE_ADDR *addr)
209{
210 char buf[4];
211 CORE_ADDR pc = fetch_ppc_register (32); /* nip */
212
213 /* Fetch instruction preceding current NIP. */
214 if (fetch_ppc_memory (pc-4, buf, 4) != 0)
215 return 0;
216 /* It should be a "sc" instruction. */
217 if (*(unsigned int *)buf != INSTR_SC)
218 return 0;
219 /* System call number should be NR_spu_run. */
220 if (fetch_ppc_register (0) != NR_spu_run)
221 return 0;
222
223 /* Register 3 contains fd, register 4 the NPC param pointer. */
224 *fd = fetch_ppc_register (34); /* orig_gpr3 */
225 *addr = fetch_ppc_register (4);
226 return 1;
227}
228
229
230/* Copy LEN bytes at OFFSET in spufs file ANNEX into/from READBUF or WRITEBUF,
231 using the /proc file system. */
232static int
233spu_proc_xfer_spu (const char *annex, unsigned char *readbuf,
234 const unsigned char *writebuf,
235 CORE_ADDR offset, int len)
236{
237 char buf[128];
238 int fd = 0;
239 int ret = -1;
240
241 if (!annex)
242 return 0;
243
5472f405 244 sprintf (buf, "/proc/%ld/fd/%s", ptid_get_lwp (current_ptid), annex);
a13e2c95
UW
245 fd = open (buf, writebuf? O_WRONLY : O_RDONLY);
246 if (fd <= 0)
247 return -1;
248
249 if (offset != 0
250 && lseek (fd, (off_t) offset, SEEK_SET) != (off_t) offset)
251 {
252 close (fd);
374c1d38 253 return 0;
a13e2c95
UW
254 }
255
256 if (writebuf)
257 ret = write (fd, writebuf, (size_t) len);
258 else if (readbuf)
259 ret = read (fd, readbuf, (size_t) len);
260
261 close (fd);
262 return ret;
263}
264
265
266/* Start an inferior process and returns its pid.
267 ALLARGS is a vector of program-name and args. */
268static int
269spu_create_inferior (char *program, char **allargs)
270{
271 int pid;
95954743 272 ptid_t ptid;
a13e2c95
UW
273
274 pid = fork ();
275 if (pid < 0)
276 perror_with_name ("fork");
277
278 if (pid == 0)
279 {
280 ptrace (PTRACE_TRACEME, 0, 0, 0);
281
282 setpgid (0, 0);
283
2b876972
DJ
284 execv (program, allargs);
285 if (errno == ENOENT)
286 execvp (program, allargs);
a13e2c95
UW
287
288 fprintf (stderr, "Cannot exec %s: %s.\n", program,
289 strerror (errno));
290 fflush (stderr);
291 _exit (0177);
292 }
293
95954743
PA
294 add_process (pid, 0);
295
296 ptid = ptid_build (pid, pid, 0);
297 add_thread (ptid, NULL);
a13e2c95
UW
298 return pid;
299}
300
301/* Attach to an inferior process. */
302int
303spu_attach (unsigned long pid)
304{
95954743
PA
305 ptid_t ptid;
306
a13e2c95
UW
307 if (ptrace (PTRACE_ATTACH, pid, 0, 0) != 0)
308 {
309 fprintf (stderr, "Cannot attach to process %ld: %s (%d)\n", pid,
310 strerror (errno), errno);
311 fflush (stderr);
312 _exit (0177);
313 }
314
95954743
PA
315 add_process (pid, 1);
316 ptid = ptid_build (pid, pid, 0);
317 add_thread (ptid, NULL);
a13e2c95
UW
318 return 0;
319}
320
321/* Kill the inferior process. */
95954743 322static int
5472f405 323spu_kill (int pid)
a13e2c95 324{
4168d2d6 325 int status, ret;
5472f405
UW
326 struct process_info *process = find_process_pid (pid);
327 if (process == NULL)
328 return -1;
329
330 ptrace (PTRACE_KILL, pid, 0, 0);
4168d2d6
UW
331
332 do {
333 ret = waitpid (pid, &status, 0);
334 if (WIFEXITED (status) || WIFSIGNALED (status))
335 break;
336 } while (ret != -1 || errno != ECHILD);
337
338 clear_inferiors ();
5472f405 339 remove_process (process);
95954743 340 return 0;
a13e2c95
UW
341}
342
343/* Detach from inferior process. */
dd6953e1 344static int
95954743 345spu_detach (int pid)
a13e2c95 346{
5472f405
UW
347 struct process_info *process = find_process_pid (pid);
348 if (process == NULL)
349 return -1;
350
351 ptrace (PTRACE_DETACH, pid, 0, 0);
4168d2d6
UW
352
353 clear_inferiors ();
5472f405 354 remove_process (process);
dd6953e1 355 return 0;
a13e2c95
UW
356}
357
505106cd
PA
358static void
359spu_mourn (struct process_info *process)
360{
361 remove_process (process);
362}
363
444d6139 364static void
95954743 365spu_join (int pid)
444d6139
PA
366{
367 int status, ret;
5472f405
UW
368 struct process_info *process;
369
370 process = find_process_pid (pid);
371 if (process == NULL)
372 return;
444d6139
PA
373
374 do {
5472f405 375 ret = waitpid (pid, &status, 0);
444d6139
PA
376 if (WIFEXITED (status) || WIFSIGNALED (status))
377 break;
378 } while (ret != -1 || errno != ECHILD);
379}
380
a13e2c95
UW
381/* Return nonzero if the given thread is still alive. */
382static int
95954743 383spu_thread_alive (ptid_t ptid)
a13e2c95 384{
5472f405 385 return ptid_equal (ptid, current_ptid);
a13e2c95
UW
386}
387
388/* Resume process. */
389static void
2bd7c093 390spu_resume (struct thread_resume *resume_info, size_t n)
a13e2c95 391{
2bd7c093 392 size_t i;
a13e2c95 393
2bd7c093 394 for (i = 0; i < n; i++)
95954743 395 if (ptid_equal (resume_info[i].thread, minus_one_ptid)
5472f405 396 || ptid_equal (resume_info[i].thread, current_ptid))
2bd7c093
PA
397 break;
398
399 if (i == n)
a13e2c95
UW
400 return;
401
402 /* We don't support hardware single-stepping right now, assume
403 GDB knows to use software single-stepping. */
bd99dc85 404 if (resume_info[i].kind == resume_step)
a13e2c95
UW
405 fprintf (stderr, "Hardware single-step not supported.\n");
406
407 regcache_invalidate ();
408
409 errno = 0;
5472f405 410 ptrace (PTRACE_CONT, ptid_get_lwp (current_ptid), 0, resume_info[i].sig);
a13e2c95
UW
411 if (errno)
412 perror_with_name ("ptrace");
413}
414
415/* Wait for process, returns status. */
95954743
PA
416static ptid_t
417spu_wait (ptid_t ptid, struct target_waitstatus *ourstatus, int options)
a13e2c95 418{
5472f405 419 int pid = ptid_get_pid (ptid);
a13e2c95
UW
420 int w;
421 int ret;
422
a13e2c95
UW
423 while (1)
424 {
5472f405 425 ret = waitpid (pid, &w, WNOHANG | __WALL | __WNOTHREAD);
a13e2c95
UW
426
427 if (ret == -1)
428 {
429 if (errno != ECHILD)
430 perror_with_name ("waitpid");
431 }
432 else if (ret > 0)
433 break;
434
435 usleep (1000);
436 }
437
438 /* On the first wait, continue running the inferior until we are
439 blocked inside an spu_run system call. */
440 if (!server_waiting)
441 {
442 int fd;
443 CORE_ADDR addr;
444
445 while (!parse_spufs_run (&fd, &addr))
446 {
5472f405
UW
447 ptrace (PT_SYSCALL, pid, (PTRACE_TYPE_ARG3) 0, 0);
448 waitpid (pid, NULL, __WALL | __WNOTHREAD);
a13e2c95
UW
449 }
450 }
451
a13e2c95
UW
452 if (WIFEXITED (w))
453 {
454 fprintf (stderr, "\nChild exited with retcode = %x \n", WEXITSTATUS (w));
5b1c542e
PA
455 ourstatus->kind = TARGET_WAITKIND_EXITED;
456 ourstatus->value.integer = WEXITSTATUS (w);
a13e2c95 457 clear_inferiors ();
95954743 458 return pid_to_ptid (ret);
a13e2c95
UW
459 }
460 else if (!WIFSTOPPED (w))
461 {
462 fprintf (stderr, "\nChild terminated with signal = %x \n", WTERMSIG (w));
5b1c542e
PA
463 ourstatus->kind = TARGET_WAITKIND_SIGNALLED;
464 ourstatus->value.sig = target_signal_from_host (WTERMSIG (w));
a13e2c95 465 clear_inferiors ();
95954743 466 return pid_to_ptid (ret);
a13e2c95
UW
467 }
468
469 /* After attach, we may have received a SIGSTOP. Do not return this
470 as signal to GDB, or else it will try to continue with SIGSTOP ... */
471 if (!server_waiting)
472 {
5b1c542e
PA
473 ourstatus->kind = TARGET_WAITKIND_STOPPED;
474 ourstatus->value.sig = TARGET_SIGNAL_0;
95954743 475 return ptid_build (ret, ret, 0);
a13e2c95
UW
476 }
477
5b1c542e
PA
478 ourstatus->kind = TARGET_WAITKIND_STOPPED;
479 ourstatus->value.sig = target_signal_from_host (WSTOPSIG (w));
95954743 480 return ptid_build (ret, ret, 0);
a13e2c95
UW
481}
482
483/* Fetch inferior registers. */
484static void
85492558 485spu_fetch_registers (struct regcache *regcache, int regno)
a13e2c95
UW
486{
487 int fd;
488 CORE_ADDR addr;
489
a13e2c95
UW
490 /* We must be stopped on a spu_run system call. */
491 if (!parse_spufs_run (&fd, &addr))
492 return;
493
494 /* The ID register holds the spufs file handle. */
495 if (regno == -1 || regno == SPU_ID_REGNUM)
85492558 496 supply_register (regcache, SPU_ID_REGNUM, (char *)&fd);
a13e2c95
UW
497
498 /* The NPC register is found at ADDR. */
499 if (regno == -1 || regno == SPU_PC_REGNUM)
500 {
501 char buf[4];
502 if (fetch_ppc_memory (addr, buf, 4) == 0)
85492558 503 supply_register (regcache, SPU_PC_REGNUM, buf);
a13e2c95
UW
504 }
505
506 /* The GPRs are found in the "regs" spufs file. */
507 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
508 {
509 unsigned char buf[16*SPU_NUM_CORE_REGS];
510 char annex[32];
511 int i;
512
513 sprintf (annex, "%d/regs", fd);
514 if (spu_proc_xfer_spu (annex, buf, NULL, 0, sizeof buf) == sizeof buf)
515 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
85492558 516 supply_register (regcache, i, buf + i*16);
a13e2c95
UW
517 }
518}
519
520/* Store inferior registers. */
521static void
85492558 522spu_store_registers (struct regcache *regcache, int regno)
a13e2c95
UW
523{
524 int fd;
525 CORE_ADDR addr;
526
527 /* ??? Some callers use 0 to mean all registers. */
528 if (regno == 0)
529 regno = -1;
530
531 /* We must be stopped on a spu_run system call. */
532 if (!parse_spufs_run (&fd, &addr))
533 return;
534
535 /* The NPC register is found at ADDR. */
536 if (regno == -1 || regno == SPU_PC_REGNUM)
537 {
538 char buf[4];
85492558 539 collect_register (regcache, SPU_PC_REGNUM, buf);
a13e2c95
UW
540 store_ppc_memory (addr, buf, 4);
541 }
542
543 /* The GPRs are found in the "regs" spufs file. */
544 if (regno == -1 || (regno >= 0 && regno < SPU_NUM_CORE_REGS))
545 {
546 unsigned char buf[16*SPU_NUM_CORE_REGS];
547 char annex[32];
548 int i;
549
550 for (i = 0; i < SPU_NUM_CORE_REGS; i++)
85492558 551 collect_register (regcache, i, buf + i*16);
a13e2c95
UW
552
553 sprintf (annex, "%d/regs", fd);
554 spu_proc_xfer_spu (annex, NULL, buf, 0, sizeof buf);
555 }
556}
557
558/* Copy LEN bytes from inferior's memory starting at MEMADDR
559 to debugger memory starting at MYADDR. */
560static int
561spu_read_memory (CORE_ADDR memaddr, unsigned char *myaddr, int len)
562{
563 int fd, ret;
564 CORE_ADDR addr;
d2ed6730
UW
565 char annex[32], lslr_annex[32], buf[32];
566 CORE_ADDR lslr;
a13e2c95
UW
567
568 /* We must be stopped on a spu_run system call. */
569 if (!parse_spufs_run (&fd, &addr))
570 return 0;
571
572 /* Use the "mem" spufs file to access SPU local store. */
573 sprintf (annex, "%d/mem", fd);
574 ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr, len);
d2ed6730
UW
575 if (ret > 0)
576 return ret == len ? 0 : EIO;
577
578 /* SPU local store access wraps the address around at the
579 local store limit. We emulate this here. To avoid needing
580 an extra access to retrieve the LSLR, we only do that after
581 trying the original address first, and getting end-of-file. */
582 sprintf (lslr_annex, "%d/lslr", fd);
583 memset (buf, 0, sizeof buf);
584 if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
585 0, sizeof buf) <= 0)
586 return ret;
587
588 lslr = strtoul (buf, NULL, 16);
589 ret = spu_proc_xfer_spu (annex, myaddr, NULL, memaddr & lslr, len);
590
a13e2c95
UW
591 return ret == len ? 0 : EIO;
592}
593
594/* Copy LEN bytes of data from debugger memory at MYADDR
595 to inferior's memory at MEMADDR.
596 On failure (cannot write the inferior)
597 returns the value of errno. */
598static int
599spu_write_memory (CORE_ADDR memaddr, const unsigned char *myaddr, int len)
600{
601 int fd, ret;
602 CORE_ADDR addr;
d2ed6730
UW
603 char annex[32], lslr_annex[32], buf[32];
604 CORE_ADDR lslr;
a13e2c95
UW
605
606 /* We must be stopped on a spu_run system call. */
607 if (!parse_spufs_run (&fd, &addr))
608 return 0;
609
610 /* Use the "mem" spufs file to access SPU local store. */
611 sprintf (annex, "%d/mem", fd);
612 ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr, len);
d2ed6730
UW
613 if (ret > 0)
614 return ret == len ? 0 : EIO;
615
616 /* SPU local store access wraps the address around at the
617 local store limit. We emulate this here. To avoid needing
618 an extra access to retrieve the LSLR, we only do that after
619 trying the original address first, and getting end-of-file. */
620 sprintf (lslr_annex, "%d/lslr", fd);
621 memset (buf, 0, sizeof buf);
622 if (spu_proc_xfer_spu (lslr_annex, (unsigned char *)buf, NULL,
623 0, sizeof buf) <= 0)
624 return ret;
625
626 lslr = strtoul (buf, NULL, 16);
627 ret = spu_proc_xfer_spu (annex, NULL, myaddr, memaddr & lslr, len);
628
a13e2c95
UW
629 return ret == len ? 0 : EIO;
630}
631
632/* Look up special symbols -- unneded here. */
633static void
634spu_look_up_symbols (void)
635{
636}
637
638/* Send signal to inferior. */
639static void
ef57601b 640spu_request_interrupt (void)
a13e2c95 641{
5472f405 642 syscall (SYS_tkill, ptid_get_lwp (current_ptid), SIGINT);
a13e2c95
UW
643}
644
a13e2c95
UW
645static struct target_ops spu_target_ops = {
646 spu_create_inferior,
647 spu_attach,
648 spu_kill,
649 spu_detach,
505106cd 650 spu_mourn,
444d6139 651 spu_join,
a13e2c95
UW
652 spu_thread_alive,
653 spu_resume,
654 spu_wait,
655 spu_fetch_registers,
656 spu_store_registers,
90d74c30 657 NULL, /* prepare_to_access_memory */
0146f85b 658 NULL, /* done_accessing_memory */
a13e2c95
UW
659 spu_read_memory,
660 spu_write_memory,
661 spu_look_up_symbols,
ef57601b 662 spu_request_interrupt,
a13e2c95 663 NULL,
ab39bf24
UW
664 NULL,
665 NULL,
666 NULL,
667 NULL,
668 NULL,
669 NULL,
0e7f50da 670 spu_proc_xfer_spu,
59a016f0 671 hostio_last_error_from_errno,
a13e2c95
UW
672};
673
674void
675initialize_low (void)
676{
677 static const unsigned char breakpoint[] = { 0x00, 0x00, 0x3f, 0xff };
678
679 set_target_ops (&spu_target_ops);
680 set_breakpoint_data (breakpoint, sizeof breakpoint);
d05b4ac3 681 init_registers_spu ();
a13e2c95 682}
This page took 0.346908 seconds and 4 git commands to generate.