OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-7.2/] [gdb/] [gdbserver/] [spu-low.c] - Blame information for rev 342

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.