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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.0/] [gdb/] [remote-or1k.c] - Blame information for rev 113

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

Line No. Rev Author Line
1 106 markom
/* Remote debugging interface for various or1k debugging protocols.
2
   Copyright 1993-1995, 2000 Free Software Foundation, Inc.
3
   Contributed by Cygnus Support.  Written by Marko Mlinar
4
   <markom@opencores.org>
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 2 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, write to the Free Software
20
   Foundation, Inc., 59 Temple Place - Suite 330,
21
   Boston, MA 02111-1307, USA.  */
22
 
23
#include "defs.h"
24
#include "inferior.h"
25
#include "bfd.h"
26
#include "symfile.h"
27
#include "gdb_wait.h"
28
#include "gdbcmd.h"
29
#include "gdbcore.h"
30
#include "target.h"
31
#include "remote-utils.h"
32
#include "gdb_string.h"
33
#include "tm.h"
34
 
35
#include <signal.h>
36
#include <sys/types.h>
37
#include <sys/stat.h>
38
#include <sys/ioctl.h>
39
#include <fcntl.h>
40
 
41
extern void jtag_init PARAMS ((char * args));
42 113 markom
extern unsigned long long int jtag_read_reg PARAMS ((unsigned int regno));
43
extern void jtag_write_reg PARAMS ((unsigned int regno, unsigned long long int data));
44 106 markom
extern void jtag_done PARAMS ((void));
45 113 markom
extern void jtag_set_chain PARAMS ((int chain));
46 106 markom
struct target_ops or1k_jtag_ops;
47
static struct or1k_target_ops or1k_target_jtag =
48
  {
49
    "jtag",
50
    jtag_init,
51
    jtag_done,
52
    jtag_read_reg,
53
    jtag_write_reg,
54 113 markom
    jtag_set_chain,
55 106 markom
    NULL,
56
    &or1k_jtag_ops,
57
    OPS_MAGIC
58
  };
59
 
60
struct target_ops or1k_sim_ops;
61
static struct or1k_target_ops or1k_target_sim =
62
  {
63
    "simulator",
64
    NULL,
65
    NULL,
66
    NULL,
67
    NULL,
68
    NULL,
69
    NULL,
70
    &or1k_sim_ops,
71
    OPS_MAGIC
72
  };
73
 
74
struct target_ops or1k_dummy_ops;
75
static struct or1k_target_ops or1k_target_dummy =
76
  {
77
    "dummy",
78
    NULL,
79
    NULL,
80
    NULL,
81
    NULL,
82
    NULL,
83
    NULL,
84
    &or1k_dummy_ops,
85
    OPS_MAGIC
86
  };
87
 
88
const char *str_err[] =
89
  {
90
    "None", "CRC error"
91
  };
92
 
93
const char *status_name[] =
94
  {
95
    "UNDEFINED", "CONNECTING", "DISCONNECTING", "RUNNING", "STOPPED"
96
  };
97
 
98 113 markom
/* Names for matchpoint related stuff.  */
99
static char *ct_names[] =
100
  {
101
    "DIS", "IFEA", "LEA", "SEA", "AEA", "LDATA", "SDATA", "ADATA"
102
  };
103
 
104
static char *cc_names[] =
105
  {
106
    "&", "==", "<", "<=", ">", ">=", "!=", "ERR"
107
  };
108
 
109
static char *ch_names[] =
110
  {
111
    "ERR", "&", "|", "ERR"
112
  };
113
 
114 106 markom
/* Implementation specific information.  Set by or1k_initialize.  */
115
struct struct_or1k_implementation or1k_implementation;
116
 
117
/* Current target status.  */
118
static enum target_status or1k_status = TARGET_UNDEFINED;
119
 
120
/* The target vector.  */
121
struct target_ops or1k_dummy_ops, or1k_jtag_ops, or1k_sim_ops;
122
 
123
/* Currently active target description (if or1k_is_open == 1) */
124
static struct target_ops *current_ops;
125
 
126
/* Currently active or1k target operations.  */
127
static struct or1k_target_ops *current_or1k_target = NULL;
128
 
129
/* Set to 1 if the target is open.  */
130
static int or1k_is_open = 0;
131
 
132
/* Error last occured, zero = ok.  */
133
static int err = 0;
134
 
135
/* Number of interrupts while waiting for process.  */
136
static int interrupt_count = 0;
137
 
138 113 markom
/* Reason of last stop.  */
139
static int hit_watchpoint = 0;
140
 
141 106 markom
/* Current register values.  */
142
static unsigned int dmr1 = 0;
143
static unsigned int dmr2 = 0;
144
static unsigned int dsr = 0;
145
static unsigned int drr = 0;
146
 
147
/* Current watchpoints.  */
148
static int dvr[8];
149
static struct dcr_struct dcr[8];
150
 
151
/* Handle low-level error that we can't recover from.  Note that just
152
   error()ing out from target_wait or some such low-level place will cause
153
   all hell to break loose--the rest of GDB will tend to get left in an
154
   inconsistent state.  */
155
 
156
static NORETURN void
157
or1k_error (char *string,...)
158
{
159
  va_list args;
160
 
161
  va_start (args, string);
162
 
163
  target_terminal_ours ();
164
  wrap_here ("");               /* Force out any buffered output */
165
  gdb_flush (gdb_stdout);
166
  if (error_pre_print)
167
    fprintf_filtered (gdb_stderr, error_pre_print);
168
  vfprintf_filtered (gdb_stderr, string, args);
169
  fprintf_filtered (gdb_stderr, "\n");
170
  va_end (args);
171
  gdb_flush (gdb_stderr);
172
 
173
  /* Clean up in such a way that or1k_close won't try to talk to the
174
     board (it almost surely won't work since we weren't able to talk to
175
     it).  */
176
  or1k_is_open = 0;
177
 
178
  printf_unfiltered ("Ending remote or1k debugging.\n");
179
  target_mourn_inferior ();
180
 
181
  return_to_top_level (RETURN_ERROR);
182
}
183
 
184
const char *
185
or1k_err_name (e)
186
     int e;
187
{
188
  return str_err[e];
189
}
190
 
191
/* putc_readable - print a character, displaying non-printable chars in
192
   ^x notation or in hex.  */
193
 
194
static void
195
fputc_readable (ch, file)
196
     int ch;
197
     struct ui_file *file;
198
{
199
  if (ch == '\n')
200
    fputc_unfiltered ('\n', file);
201
  else if (ch == '\r')
202
    fprintf_unfiltered (file, "\\r");
203
  else if (ch < 0x20)           /* ASCII control character */
204
    fprintf_unfiltered (file, "^%c", ch + '@');
205
  else if (ch >= 0x7f)          /* non-ASCII characters (rubout or greater) */
206
    fprintf_unfiltered (file, "[%02x]", ch & 0xff);
207
  else
208
    fputc_unfiltered (ch, file);
209
}
210
 
211
 
212
/* puts_readable - print a string, displaying non-printable chars in
213
   ^x notation or in hex.  */
214
 
215
static void
216
fputs_readable (string, file)
217
     char *string;
218
     struct ui_file *file;
219
{
220
  int c;
221
 
222
  while ((c = *string++) != '\0')
223
    fputc_readable (c, file);
224
}
225
 
226 113 markom
/* Sets scan chain.  */
227
 
228
static void
229
or1k_set_chain (chain)
230
     int chain;
231
{
232
  if (current_or1k_target != NULL && current_or1k_target->to_set_chain != NULL)
233
    current_or1k_target->to_set_chain (chain);
234
}
235
 
236 106 markom
/* Sets register/memory regno to data.  */
237
 
238 113 markom
static void
239 106 markom
or1k_write_reg (regno, data)
240
     unsigned int regno;
241 113 markom
     unsigned long long int data;
242 106 markom
{
243 113 markom
  if (current_or1k_target != NULL && current_or1k_target->to_write_reg != NULL)
244
    current_or1k_target->to_write_reg (regno, data);
245 106 markom
}
246
 
247
/* Reads register/memory from regno.  */
248
 
249 113 markom
static unsigned long long int
250 106 markom
or1k_read_reg (regno)
251
     unsigned int regno;
252
{
253 113 markom
  if (current_or1k_target != NULL && current_or1k_target->to_read_reg != NULL)
254
    return current_or1k_target->to_read_reg (regno);
255 106 markom
  else
256
    return 0x1234;
257
}
258
 
259 113 markom
/* Sets SPR register regno to data.  */
260
 
261
void
262
or1k_write_spr_reg (regno, data)
263
     unsigned int regno;
264
     unsigned int data;
265
{
266
  or1k_set_chain (SC_RISC_DEBUG);
267
  or1k_write_reg (regno + REG_SPACE, data);
268
}
269
 
270
/* Reads register SPR from regno.  */
271
 
272
unsigned int
273
or1k_read_spr_reg (regno)
274
     unsigned int regno;
275
{
276
  or1k_set_chain (SC_RISC_DEBUG);
277
  return or1k_read_reg (regno + REG_SPACE);
278
}
279
 
280 106 markom
/* Stalls the CPU.  */
281
 
282
static void
283
or1k_stall ()
284
{
285 113 markom
  int val;
286
  or1k_set_chain (SC_REGISTER);
287
  val = or1k_read_reg (JTAG_RISCOP);
288
  or1k_write_reg (JTAG_RISCOP, val | 1);
289
  or1k_flush_pipeline ();
290 106 markom
}
291
 
292
/* Unstalls the CPU.  */
293
 
294
static void
295
or1k_unstall ()
296
{
297 113 markom
  unsigned int val;
298
  or1k_set_chain (SC_REGISTER);
299
  val = or1k_read_reg (JTAG_RISCOP);
300
  or1k_write_reg (JTAG_RISCOP, val & ~1);
301 106 markom
}
302
 
303 113 markom
/* Resets the CPU and stalls it.  */
304 106 markom
static void
305 113 markom
or1k_reset ()
306
{
307
  unsigned int val;
308
  or1k_set_chain (SC_REGISTER);
309
  val = or1k_read_reg (JTAG_RISCOP);
310
  val &= ~3;
311
  or1k_write_reg (JTAG_RISCOP, val | 3); /* Assert reset signal.  */
312
  usleep (1000);  /* give it some time */
313
  or1k_flush_pipeline ();
314
  or1k_write_reg (JTAG_RISCOP, val | 1); /* Release reset signal, but keep in stall state.  */
315
  or1k_flush_pipeline ();
316
}
317
 
318
static void
319 106 markom
or1k_set_undefined_cleanups (arg)
320
     PTR arg;
321
{
322
  or1k_status = TARGET_UNDEFINED;
323
}
324
 
325
/* Initialize a new connection to the or1k board, and make sure we are
326
   really connected.  */
327
 
328
static void
329
or1k_init (args)
330
     char *args;
331
{
332
  struct cleanup *old_cleanups = make_cleanup (or1k_set_undefined_cleanups, NULL);
333
  int i;
334
 
335
  /* What is this code doing here?  I don't see any way it can happen, and
336
     it might mean or1k_initializing didn't get cleared properly.
337
     So I'll make it a warning.  */
338
 
339
  if (or1k_status == TARGET_CONNECTING)
340
    {
341
      warning ("internal error: or1k_initialize called twice");
342
      return;
343
    }
344
 
345
  or1k_status = TARGET_CONNECTING;
346 113 markom
  or1k_reset ();
347 106 markom
  if (current_or1k_target != NULL && current_or1k_target->to_init != NULL)
348
    current_or1k_target->to_init (args);
349
 
350
  /* Determine implementation configuration.  */
351 113 markom
  or1k_implementation.VR = or1k_read_spr_reg (VR_SPRNUM);
352
  or1k_implementation.UPR = or1k_read_spr_reg (UPR_SPRNUM);
353 106 markom
 
354
  /* Determine max number of supported matchpoints.  */
355
  or1k_implementation.num_matchpoints = 2;
356 113 markom
  or1k_implementation.num_used_matchpoints = 0;
357 106 markom
  or1k_implementation.num_gpr_regs = 32;
358
  /*!!! FINISH */
359
 
360
 
361
  /* Is implementation supported? */
362
 
363
  /* First we should have system and debug groups implemented. */
364
  if (or1k_implementation.VR & (1 << SPR_SYSTEM_GROUP) == 0)
365
    error ("System group should be available in the or1k implementation.");
366
  if (or1k_implementation.VR & (1 << SPR_DEBUG_GROUP) == 0)
367
    error ("Debug group should be available in the or1k implementation.");
368
 
369
 
370
 
371
  /* Delete break, watch, catch points.  */
372
  for(i = 0; i < NUM_MATCHPOINTS; i++)
373 113 markom
    or1k_write_spr_reg (DCR0_SPRNUM + i, 0);
374 106 markom
 
375
  dmr1 = 0;
376 113 markom
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
377 106 markom
  dmr2 = 0;
378 113 markom
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2);
379 106 markom
  if (err != 0)
380
    error ("Cannot connect.");
381
 
382
  /* Stop when breakpoint occurs.  */
383 113 markom
  or1k_write_spr_reg (DSR_SPRNUM, 0x1000);
384 106 markom
 
385
  do_cleanups (old_cleanups);
386
 
387
  /* This should cause an error if not connected.  */
388
  or1k_fetch_registers (-1);
389
 
390
  set_current_frame (create_new_frame (read_fp (), read_pc ()));
391
  select_frame (get_current_frame (), 0);
392
}
393
 
394
/* Kill the process running on the board.  */
395
 
396
void
397
or1k_kill ()
398
{
399
  if (or1k_status != TARGET_RUNNING)
400
    return;
401
  or1k_status = TARGET_UNDEFINED;
402 113 markom
  or1k_reset();
403
  or1k_status = TARGET_STOPPED;
404 106 markom
 
405
  inferior_pid = 0;
406
}
407
 
408
/* Open a connection to the remote board.  */
409
 
410
static void
411
or1k_open (name, from_tty)
412
     char *name;
413
     int from_tty;
414
{
415
  or1k_init (name);
416
 
417
  /* Switch to using remote target now.  */
418
  current_ops = current_or1k_target->gdb_ops;
419
  or1k_is_open = 1;
420
  push_target (current_ops);
421
 
422
  /* FIXME: Should we call start_remote here?  */
423
 
424
/* This is really the job of start_remote however, that makes an assumption
425
   that the target is about to print out a status message of some sort.  That
426
   doesn't happen here (in fact, it may not be possible to get the monitor to
427
   send the appropriate packet).  */
428
 
429
  flush_cached_frames ();
430
  registers_changed ();
431
  stop_pc = read_pc ();
432
  set_current_frame (create_new_frame (read_fp (), stop_pc));
433
  select_frame (get_current_frame (), 0);
434
  print_stack_frame (selected_frame, -1, 1);
435
}
436
 
437
/* Close a connection to the remote board.  */
438
 
439
static void
440
or1k_close (quitting)
441
     int quitting;
442
{
443
  if (or1k_is_open)
444
    {
445
      or1k_kill ();
446
      if (current_or1k_target != NULL && current_or1k_target->to_done != NULL)
447
        current_or1k_target->to_done ();
448
      current_or1k_target = NULL;
449
    }
450
  generic_mourn_inferior ();
451
}
452
 
453
/* Detach from the remote board.  */
454
 
455
static void
456
or1k_detach (args, from_tty)
457
     char *args;
458
     int from_tty;
459
{
460
  if (args)
461
    error ("Argument given to \"detach\" when remotely debugging.");
462
 
463
  pop_target ();
464
 
465
  or1k_close (1);
466
 
467
  if (from_tty)
468
    printf_unfiltered ("Ending remote or1k debugging.\n");
469
}
470
 
471
/* Resume execution of the target process.  STEP says whether to single-step
472
   or to run free; SIGGNAL is the signal value (e.g. SIGINT) to be given
473
   to the target, or zero for no signal.  */
474
 
475
static void
476
or1k_resume (pid, step, siggnal)
477
     int pid, step;
478
     enum target_signal siggnal;
479
{
480
  if (or1k_status != TARGET_STOPPED)
481
    if (or1k_status == TARGET_RUNNING)
482
      error ("Program is already running.");
483
    else
484
      error ("The program is not being run.");
485
 
486
  /* Clear reason register for later.  */
487 113 markom
  or1k_write_spr_reg (DRR_SPRNUM, 0);
488 106 markom
 
489
  if (step)
490
    {
491
      /* HW STEP.  Set DMR1_ST.  */
492
      dmr1 |= DMR1_ST;
493 113 markom
      or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
494 106 markom
      dmr1 &= ~DMR1_ST;
495
    }
496
 
497
  /* Run the target. */
498
  or1k_unstall ();
499
  or1k_status = TARGET_RUNNING;
500
}
501
 
502
/* Wait until the remote stops, and return a wait status.  */
503
 
504
static int
505
or1k_wait (pid, status)
506
     int pid;
507
     struct target_waitstatus *status;
508
{
509
  interrupt_count = 0;
510
 
511
  /* If we have not sent a single step or continue command, then the
512
     board is waiting for us to do something.  Return a status
513
     indicating that it is stopped.  */
514
  if (or1k_status != TARGET_RUNNING)
515
    {
516
      if (or1k_status != TARGET_STOPPED)
517
        error("Target in invalid state.");
518
      status->kind = TARGET_WAITKIND_STOPPED;
519
      status->value.sig = TARGET_SIGNAL_TRAP;
520
      return 0;
521
    }
522
 
523
  if (err)
524
    or1k_error ("Remote failure: %s", or1k_err_name (err));
525
 
526
  /* Wait for or1k DRR register to be nonzero.  */
527
  do
528
    {
529 113 markom
      drr = or1k_read_spr_reg (DRR_SPRNUM);
530 106 markom
      usleep (10);
531
    }
532
  while (drr == 0);
533
 
534
  status->kind = TARGET_WAITKIND_STOPPED;
535 113 markom
 
536
  or1k_flush_pipeline ();
537 106 markom
 
538
  if (drr & DRR_RSTE)
539
    status->value.sig = TARGET_SIGNAL_REALTIME_33;
540
  else if (drr & DRR_BUSEE)
541
    status->value.sig = TARGET_SIGNAL_BUS;
542
  else if (drr & DRR_DPFE)
543
    status->value.sig = TARGET_SIGNAL_REALTIME_34;
544
  else if (drr & DRR_IPFE)
545
    status->value.sig = TARGET_SIGNAL_REALTIME_35;
546
  else if (drr & DRR_LPINTE)
547
    status->value.sig = TARGET_SIGNAL_INT;
548
  else if (drr & DRR_AE)
549
    status->value.sig = TARGET_SIGNAL_REALTIME_36;
550
  else if (drr & DRR_IIE)
551
    status->value.sig = TARGET_SIGNAL_ILL;
552
  else if (drr & DRR_HPINTE)
553
    status->value.sig = TARGET_SIGNAL_INT;
554
  else if (drr & DRR_DME)
555
    status->value.sig = TARGET_SIGNAL_REALTIME_37;
556
  else if (drr & DRR_IME)
557
    status->value.sig = TARGET_SIGNAL_REALTIME_38;
558
  else if (drr & DRR_RE)
559
    status->value.sig = TARGET_SIGNAL_REALTIME_39;
560
  else if (drr & DRR_SCE)
561
    status->value.sig = TARGET_SIGNAL_REALTIME_40;
562
  else if (drr & DRR_BE)
563
    status->value.sig = TARGET_SIGNAL_TRAP;
564
  else
565
    {
566
      status->value.sig = TARGET_SIGNAL_UNKNOWN;
567
      warning ("Invalid exception occured.");
568
    }
569
 
570 113 markom
  /* Log remote stop.  */
571 106 markom
  or1k_status = TARGET_STOPPED;
572 113 markom
 
573
  /* Determine what caused trap - breakpoint or watchpoint.  */
574
  if (status->value.sig == TARGET_SIGNAL_TRAP)
575
    {
576
      /* Search all active breakpoints for a match.  */
577
      CORE_ADDR pc = read_pc ();
578
      int breakpoint = 0;
579
      int i;
580
      for (i = 0; i < or1k_implementation.num_used_matchpoints; i++)
581
        if (dvr[i] == pc && dcr[i].dp && dcr[i].cc == CC_EQUAL && !dcr[i].sc && dcr[i].ct == CT_FETCH)
582
          {
583
            breakpoint = 1;
584
            break;
585
          }
586
      hit_watchpoint = !breakpoint;
587
    }
588
  else
589
    hit_watchpoint = 0;
590 106 markom
 
591
  /* If the stop PC is in the _exit function, assume
592
     we hit the 'break 0x3ff' instruction in _exit, so this
593
     is not a normal breakpoint.  */
594
  {
595
    char *func_name;
596
    CORE_ADDR func_start;
597
    CORE_ADDR pc = read_pc ();
598
 
599
    find_pc_partial_function (pc, &func_name, &func_start, NULL);
600
    if (func_name != NULL && strcmp (func_name, "_exit") == 0
601
        && func_start == pc)
602
      status->kind = TARGET_WAITKIND_EXITED;
603
  }
604
  return 0;
605
}
606
 
607 113 markom
/* Fetch a word from the target board.  All memory accesses to the
608
   remote board are word aligned.  */
609 106 markom
 
610
static unsigned int
611
or1k_fetch_word (addr)
612
     CORE_ADDR addr;
613
{
614 113 markom
  if (addr & 3)
615
    {
616
      int subaddr = addr & 3;
617
      unsigned char buf[8];
618
      unsigned int low, high;
619
      addr >>= 2;
620
      low = or1k_read_reg (addr + MEM_SPACE);
621
      high = or1k_read_reg (addr + 1 + MEM_SPACE);
622
      memcpy (&buf[0], &low, 4);
623
      memcpy (&buf[4], &high, 4);
624
      memcpy (&low, &buf[subaddr], 4);
625
      return low;
626
    }
627
  else
628
    {
629
      addr >>= 2;
630
      return or1k_read_reg (addr + MEM_SPACE);
631
    }
632 106 markom
}
633
 
634
/* Store a word to the target board.  Returns errno code or zero for
635 113 markom
   success.  All memory accesses to the remote board are word aligned.  */
636 106 markom
static int
637
or1k_store_word (addr, val)
638
     CORE_ADDR addr;
639
     unsigned int val;
640
{
641 113 markom
  if (addr & 3)
642
    {
643
      int subaddr = addr & 3;
644
      unsigned char buf[8];
645
      unsigned int low, high;
646
      addr >>= 2;
647
      low = or1k_read_reg (addr + MEM_SPACE);
648
      high = or1k_read_reg (addr + 1 + MEM_SPACE);
649
      memcpy (&buf[0], &low, 4);
650
      memcpy (&buf[4], &high, 4);
651
      memcpy (&buf[subaddr], &val, 4);
652
      memcpy (&low, &buf[0], 4);
653
      memcpy (&high, &buf[4], 4);
654
      or1k_write_reg (addr + MEM_SPACE, low);
655
      or1k_write_reg (addr + 1 + MEM_SPACE, high);
656
    }
657
  else
658
    {
659
      addr >>= 2;
660
      or1k_write_reg (addr + MEM_SPACE, val);
661
    }
662 106 markom
  return err;
663
}
664
 
665
/* Fetch the remote registers.  */
666
 
667
void
668
or1k_fetch_registers (regno)
669
     int regno;
670
{
671
  unsigned int val;
672
 
673
  if (regno == -1)
674
    {
675
      for (regno = 0; regno < NUM_REGS; regno++)
676
        or1k_fetch_registers (regno);
677
      return;
678
    }
679
 
680
  if (regno >= NUM_REGS)
681
    error("Invalid register number!");
682
 
683
  /* Convert to SPRNUM and read.  */
684 113 markom
  val = or1k_read_spr_reg (REGNUM_TO_SPRNUM(regno));
685 106 markom
 
686
  {
687
    char buf[MAX_REGISTER_RAW_SIZE];
688
 
689
    /* We got the number the register holds, but gdb expects to see a
690
       value in the target byte ordering.  */
691
    store_unsigned_integer (buf, REGISTER_RAW_SIZE (regno), val);
692
    supply_register (regno, buf);
693
  }
694
  if (err)
695
    or1k_error ("Can't read register %d(%i): %s", regno, REGNUM_TO_SPRNUM(regno) + REG_SPACE, or1k_err_name (err));
696
}
697
 
698
/* Fetch and return instruction from the specified location.  */
699
 
700
unsigned int
701
or1k_fetch_instruction (addr)
702
     CORE_ADDR addr;
703
{
704
  char buf[OR1K_INSTLEN];
705
  int status;
706
 
707
  status = read_memory_nobpt (addr, buf, OR1K_INSTLEN);
708
  if (status)
709
    memory_error (status, addr);
710
  return extract_unsigned_integer (buf, OR1K_INSTLEN);
711
}
712
 
713 113 markom
/* Currently not needed.  */
714
 
715 106 markom
static void
716
or1k_prepare_to_store ()
717
{
718
}
719
 
720
/* Store remote register(s).  */
721
 
722
static void
723
or1k_store_registers (regno)
724
     int regno;
725
{
726
  if (regno == -1)
727
    {
728
      for (regno = 0; regno < NUM_REGS; regno++)
729
        or1k_store_registers (regno);
730
      return;
731
    }
732
 
733
  if (regno >= NUM_REGS)
734
    error("Invalid register number!");
735
 
736 113 markom
  or1k_write_spr_reg (REGNUM_TO_SPRNUM(regno), or1k_read_spr_reg (REGNUM_TO_SPRNUM(regno)));
737 106 markom
  if (err)
738 113 markom
    or1k_error ("Can't write register %d(%i): %s", regno, REGNUM_TO_SPRNUM(regno), or1k_err_name (err));
739 106 markom
}
740
 
741
/* Read or write LEN bytes from inferior memory at MEMADDR,
742
   transferring to or from debugger address MYADDR.  Write to inferior
743
   if SHOULD_WRITE is nonzero.  Returns length of data written or
744
   read; 0 for error.  Note that protocol gives us the correct value
745
   for a longword, since it transfers values in ASCII.  We want the
746
   byte values, so we have to swap the longword values.  */
747
 
748
static int
749
or1k_xfer_memory (memaddr, myaddr, len, write, ignore)
750
     CORE_ADDR memaddr;
751
     char *myaddr;
752
     int len;
753
     int write;
754
     struct target_ops *ignore;
755
{
756
  register int i;
757
  /* Round starting address down to longword boundary.  */
758
  register CORE_ADDR addr = memaddr & ~3;
759
  /* Round ending address up; get number of longwords that makes.  */
760
  register int count = (((memaddr + len) - addr) + 3) / 4;
761
  /* Allocate buffer of that many longwords.  */
762
  register char *buffer = alloca (count * 4);
763
 
764
  int status;
765
 
766
  if (memaddr >= MEM_SPACE)
767
    error("Invalid address");
768
 
769
  if (write)
770
    {
771
      /* Fill start and end extra bytes of buffer with existing data.  */
772
      if (addr != memaddr || len < 4)
773
        {
774
          /* Need part of initial word -- fetch it.  */
775
          store_unsigned_integer (&buffer[0], 4, or1k_fetch_word (addr));
776
        }
777
 
778
      if (count > 1)
779
        {
780
          /* Need part of last word -- fetch it.  FIXME: we do this even
781
             if we don't need it.  */
782
          store_unsigned_integer (&buffer[(count - 1) * 4], 4,
783
                                  or1k_fetch_word (addr + (count - 1) * 4));
784
        }
785
 
786
      /* Copy data to be written over corresponding part of buffer */
787
 
788
      memcpy ((char *) buffer + (memaddr & 3), myaddr, len);
789
 
790
      /* Write the entire buffer.  */
791
 
792
      for (i = 0; i < count; i++, addr += 4)
793
        {
794
          status = or1k_store_word (addr,
795
                               extract_unsigned_integer (&buffer[i * 4], 4));
796
          /* Report each kilobyte (we download 32-bit words at a time) */
797
          if (i % 256 == 255)
798
            {
799
              printf_unfiltered ("*");
800
              gdb_flush (gdb_stdout);
801
            }
802
          if (status)
803
            {
804
              errno = status;
805
              return 0;
806
            }
807
          /* FIXME: Do we want a QUIT here?  */
808
        }
809
      if (count >= 256)
810
        printf_unfiltered ("\n");
811
    }
812
  else
813
    {
814
      /* Read all the longwords */
815
      for (i = 0; i < count; i++, addr += 4)
816
        {
817
          store_unsigned_integer (&buffer[i * 4], 4, or1k_fetch_word (addr));
818
          QUIT;
819
        }
820
 
821
      /* Copy appropriate bytes out of the buffer.  */
822
      memcpy (myaddr, buffer + (memaddr & 3), len);
823
    }
824
  return len;
825
}
826
 
827 113 markom
/* Flushes pipeline. May not be needed by all implementations, but
828
   it doen't hurt to do it. This function should be called every time
829
   or1k stops.
830
   When or1k stops it still has instructions in pipeline.
831
   We do this by inserting nop instructions.
832
   IF cycle remains unaffacted by writing to DIR, and it still holds
833
   instruction, that caused break or watchpoint. */
834
 
835
void
836
or1k_flush_pipeline ()
837
{
838
  or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
839
  or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
840
  or1k_write_spr_reg (DIR_SPRNUM, NOP_INSTR);
841
}
842
 
843 106 markom
/* Print info on this target.  */
844
 
845
static void
846
or1k_files_info (ignore)
847
     struct target_ops *ignore;
848
{
849
  char *file = "nothing";
850
 
851
  if (exec_bfd)
852
    file = bfd_get_filename (exec_bfd);
853
 
854
  printf_filtered ("or1k_files_info: file \"%s\"\n", file);
855
 
856
  if (exec_bfd)
857
    {
858
      printf_filtered ("\tAttached to %s running program %s\n",
859
                       target_shortname, file);
860
    }
861
  /* Print target info. */
862
  printf_filtered ("Status: %s\n", status_name[or1k_status]);
863
}
864
 
865
/* Tell whether we can support a hardware breakpoint.  */
866
static int
867
or1k_can_use_hardware_breakpoint ()
868
{
869
  int i;
870
  /* Search for unused breakpoint.  */
871 113 markom
  return or1k_implementation.num_used_matchpoints < or1k_implementation.num_matchpoints;
872 106 markom
}
873
 
874
/* Insert a breakpoint.  On targets that don't have built-in breakpoint
875
   support, we read the contents of the target location and stash it,
876
   then overwrite it with a breakpoint instruction.  ADDR is the target
877
   location in the target machine.  CONTENTS_CACHE is a pointer to
878
   memory allocated for saving the target contents.  It is guaranteed
879
   by the caller to be long enough to save sizeof BREAKPOINT bytes (this
880
   is accomplished via BREAKPOINT_MAX).  */
881
 
882 113 markom
int
883 106 markom
or1k_insert_breakpoint (addr, contents_cache)
884
     CORE_ADDR addr;
885
     char *contents_cache;
886
{
887
  if (or1k_can_use_hardware_breakpoint())
888
    return set_breakpoint (addr);
889
  else
890
    return memory_insert_breakpoint (addr, contents_cache);
891
}
892
 
893 113 markom
int
894 106 markom
or1k_remove_breakpoint (addr, contents_cache)
895
     CORE_ADDR addr;
896
     char *contents_cache;
897
{
898
  /* First try to remove HW breakpoint at address */
899
  if (clear_breakpoint (addr))
900
    return memory_remove_breakpoint (addr, contents_cache);
901
  else
902
    return 0;
903
}
904
 
905 113 markom
/* Tell whether this target can support a hardware breakpoint.  CNT
906
   is the number of hardware breakpoints already installed.  This
907
   implements the TARGET_CAN_USE_HARDWARE_WATCHPOINT macro.
908
   Lower bound is estimated. !!! Can we estimate better? */
909
 
910
int
911
or1k_can_use_hardware_watchpoint (bp_type, cnt)
912
     enum bptype bp_type;
913
     int cnt;
914
{
915
  /* Are there at least two matchpoints left for watch? - estimate lower bound  */
916
  return cnt + ((bp_type == bp_hardware_watchpoint)?(1):(0))
917
    <= or1k_implementation.num_matchpoints;
918
}
919
 
920
/* Sifts unused matchpoints to higher indexses.  */
921
 
922
static void
923
sift_matchpoints ()
924
{
925
  int i, first_free = 0;
926
  unsigned int u;
927
  for (i = 0; i < or1k_implementation.num_matchpoints; i++)
928
    if (dcr[i].dp)
929
      {
930
        int chaining;
931
        dvr[first_free] = dvr[i];
932
        dcr[first_free] = dcr[i];
933
 
934
        /* Copy chaining bits.  */
935
        chaining = dmr1 & (3 << (2 * i));
936
        dmr1 &= ~(3 << (2 * first_free));
937
        dmr1 |= chaining << (2 * first_free);
938
        /* Copy watchpoint bits */
939
        chaining = dmr2 & (1 << i);
940
        dmr2 &= 1 << first_free;
941
        dmr2 |= chaining << first_free;
942
        /* !!! move references also */
943
 
944
        or1k_write_spr_reg (DVR0_SPRNUM + first_free, dvr[first_free]);
945
        memcpy (&u, &dcr[first_free], sizeof(dcr[first_free]));
946
        or1k_write_spr_reg (DCR0_SPRNUM + first_free, u);
947
        first_free++;
948
      }
949
  /* Disable unused.  */
950
  for (i = first_free; i < or1k_implementation.num_matchpoints; i++)
951
    {
952
      dmr2 &= ~(1 << i);
953
      dcr[i].dp = 0;
954
    }
955
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
956
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2);
957
}
958
 
959
/* Translates gdb watchpoint type into one in DCR register.  */
960
 
961
static int
962
translate_type (gdb_type)
963
     int gdb_type;
964
{
965
  switch (gdb_type)
966
    {
967
    case 0:
968
      return CT_SDATA;
969
    case 1:
970
      return CT_LDATA;
971
    case 2:
972
      return CT_ADATA;
973
    default:
974
      error ("Invalid type.");
975
    }
976
}
977
 
978
/* Set a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
979
   for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
980
   watchpoint. */
981
 
982
int
983
or1k_insert_watchpoint (addr, len, type)
984
     CORE_ADDR addr;
985
     int len;
986
     int type;
987
{
988
  int i;
989
  unsigned int u;
990
  if (len < 1)
991
    return -1;
992
 
993
  type = translate_type (type);
994
 
995
  /* Moves unused watchpoints to the top.  */
996
  sift_matchpoints ();
997
  /* Place at first free matchpoint.  */
998
  i = or1k_implementation.num_used_matchpoints;
999
  dvr[i] = addr;
1000
  dcr[i].dp = 1;
1001
  dcr[i].cc = CC_GREATE;
1002
  dcr[i].sc = 0;
1003
  dcr[i].ct = type;
1004
  or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
1005
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
1006
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
1007
 
1008
  /* Set && chaining here.  */
1009
  dmr1 &= ~(3 << (2 * i));
1010
  dmr1 |= 2 << (2 * i);
1011
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
1012
 
1013
  /* Set upper watchpoint bound.  */
1014
  i++;
1015
  dvr[i] = addr + len - 1;
1016
  dcr[i].dp = 1;
1017
  dcr[i].cc = CC_LESSE;
1018
  dcr[i].sc = 0;
1019
  dcr[i].ct = type;
1020
  or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
1021
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
1022
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
1023
 
1024
  /* Matchpoints will cause breakpoints */
1025
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 |= (1 << i));
1026
  or1k_implementation.num_used_matchpoints += 2;
1027
  return 0;
1028
}
1029
 
1030
/* Removes a data watchpoint.  ADDR and LEN should be obvious.  TYPE is 0
1031
   for a write watchpoint, 1 for a read watchpoint, or 2 for a read/write
1032
   watchpoint. */
1033
int
1034
or1k_remove_watchpoint (addr, len, type)
1035
     CORE_ADDR addr;
1036
     int len;
1037
     int type;
1038
{
1039
  int i, found = -1;
1040
  unsigned int u;
1041
  if (len < 1)
1042
    return -1;
1043
 
1044
  type = translate_type (type);
1045
 
1046
  /* Find the right one.  */
1047
  for (i = 0; i < or1k_implementation.num_used_matchpoints; i++)
1048
    if (dvr[i] == addr && dcr[i].dp && dcr[i].cc == CC_GREATE && !dcr[i].sc && dcr[i].ct == type
1049
        && dvr[i + 1] == addr + len - 1 && dcr[i + 1].dp && dcr[i + 1].cc == CC_LESSE
1050
        && !dcr[i + 1].sc && dcr[i + 1].ct == type)
1051
      {
1052
        found = i;
1053
        break;
1054
      }
1055
 
1056
  if (found < 0)
1057
    return -1;
1058
 
1059
  dcr[found].dp = 0;
1060
  memcpy (&u, &dcr[found], sizeof(dcr[found]));
1061
  or1k_write_spr_reg (DCR0_SPRNUM + found, u);
1062
  dcr[found + 1].dp = 0;
1063
  memcpy (&u, &dcr[found + 1], sizeof(dcr[found + 1]));
1064
  or1k_write_spr_reg (DCR0_SPRNUM + found + 1, u);
1065
 
1066
  /* Matchpoints will not cause breakpoints anymore. */
1067
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 &= ~(1 << i));
1068
  or1k_implementation.num_used_matchpoints -= 2;
1069
  return 0;
1070
}
1071
 
1072
int
1073
or1k_stopped_by_watchpoint (void)
1074
{
1075
  return hit_watchpoint;
1076
}
1077
 
1078 106 markom
/* Insert a breakpoint.  */
1079
 
1080
int
1081
set_breakpoint (addr)
1082
     CORE_ADDR addr;
1083
{
1084
  int i;
1085
  unsigned int u;
1086
  /* Search for unused breakpoint.  */
1087
  for (i = 0; i < NUM_MATCHPOINTS; i++)
1088
    if (dcr[i].dp == 0) break;
1089
  if (i >= NUM_MATCHPOINTS) return 1;
1090
  dvr[i] = addr;
1091
  dcr[i].dp = 1;
1092
  dcr[i].cc = CC_EQUAL;
1093
  dcr[i].sc = 0;
1094
  dcr[i].ct = CT_FETCH;
1095 113 markom
  or1k_write_spr_reg (DVR0_SPRNUM + i, dvr[i]);
1096 106 markom
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
1097 113 markom
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
1098
  or1k_implementation.num_used_matchpoints++;
1099
 
1100
  /* No chaining here.  */
1101
  dmr1 &= ~(3 << (2*i));
1102
  or1k_write_spr_reg (DMR1_SPRNUM, dmr1);
1103
  /* Matchpoints will cause breakpoints */
1104
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 |= (1 << i));
1105 106 markom
  return 0;
1106
}
1107
 
1108
/* Clear a breakpoint.  */
1109
 
1110
int
1111
clear_breakpoint (addr)
1112
     CORE_ADDR addr;
1113
{
1114
  int i;
1115
  unsigned int u;
1116
  /* Search for matching breakpoint.  */
1117
  for (i = 0; i < NUM_MATCHPOINTS; i++)
1118
    if ((dcr[i].dp == 1) && (dvr[i] == addr) && (dcr[i].cc == CC_EQUAL)
1119
        && (dcr[i].sc == 0) && (dcr[i].ct == CT_FETCH)) break;
1120
 
1121
  if (i >= NUM_MATCHPOINTS) return 1;
1122
  dcr[i].dp = 0;
1123
  memcpy (&u, &dcr[i], sizeof(dcr[i]));
1124 113 markom
  or1k_write_spr_reg (DCR0_SPRNUM + i, u);
1125
  /* Matchpoints will cause breakpoints */
1126
  or1k_write_spr_reg (DMR2_SPRNUM, dmr2 &= ~(1 << i));
1127
  or1k_implementation.num_used_matchpoints--;
1128 106 markom
  return 0;
1129
}
1130
 
1131
/* Start running on the target board.  */
1132
 
1133
static void
1134
or1k_create_inferior (execfile, args, env)
1135
     char *execfile;
1136
     char *args;
1137
     char **env;
1138
{
1139
  CORE_ADDR entry_pt;
1140
 
1141
  if (args && *args)
1142
    {
1143
      warning ("\
1144
Can't pass arguments to remote OR1K board; arguments ignored.");
1145
      /* And don't try to use them on the next "run" command.  */
1146
      execute_command ("set args", 0);
1147
    }
1148
 
1149
  if (execfile == 0 || exec_bfd == 0)
1150
    error ("No executable file specified");
1151
 
1152
  or1k_kill ();
1153
  remove_breakpoints ();
1154
 
1155
  entry_pt = (CORE_ADDR) bfd_get_start_address (exec_bfd);
1156
  init_wait_for_inferior ();
1157
 
1158
  /* FIXME: Should we set inferior_pid here?  */
1159 113 markom
 
1160 106 markom
  insert_breakpoints ();        /* Needed to get correct instruction in cache */
1161
  clear_proceed_status ();
1162
  or1k_status = TARGET_STOPPED;
1163
  proceed (entry_pt, TARGET_SIGNAL_DEFAULT, 0);
1164
}
1165
 
1166
/* Clean up after a process.  Actually nothing to do.  */
1167
 
1168
static void
1169
or1k_mourn_inferior ()
1170
{
1171
  generic_mourn_inferior ();
1172
}
1173
 
1174
static void
1175
or1k_dummy_open (name, from_tty)
1176
     char *name;
1177
     int from_tty;
1178
{
1179
  target_preopen (from_tty);
1180
  if (or1k_is_open)
1181
    unpush_target (current_ops);
1182
  current_or1k_target = &or1k_target_dummy;
1183
  or1k_open (name, from_tty);
1184
}
1185
 
1186
static void
1187
or1k_jtag_open (name, from_tty)
1188
     char *name;
1189
     int from_tty;
1190
{
1191
  target_preopen (from_tty);
1192
  if (or1k_is_open)
1193
    unpush_target (current_ops);
1194
  current_or1k_target = &or1k_target_jtag;
1195
  or1k_open (name, from_tty);
1196
}
1197
 
1198
static void
1199
or1k_sim_open (name, from_tty)
1200
     char *name;
1201
     int from_tty;
1202
{
1203
  /* target_preopen (from_tty); - do we need this ? */
1204
  if (or1k_is_open)
1205
    unpush_target (current_ops);
1206
  current_or1k_target = &or1k_target_sim;
1207
  or1k_open (name, from_tty);
1208
}
1209
 
1210
/* Executes command on the target.  */
1211
 
1212
void
1213
or1k_sim_cmd (char *args, int from_tty)
1214
{
1215
  if (current_or1k_target != NULL && current_or1k_target->to_exec_command != NULL)
1216
    current_or1k_target->to_exec_command (args, from_tty);
1217
  else
1218
    error ("Command not supported on this target. ");
1219
}
1220
 
1221 113 markom
/* Displays matchpoints usage.  */
1222
 
1223 106 markom
void
1224 113 markom
info_matchpoints_command (char *args, int from_tty)
1225
{
1226
  int i;
1227
  for (i = 0; i < or1k_implementation.num_matchpoints; i++)
1228
    {
1229
      printf_filtered ("WP%i ", i);
1230
      if (dcr[i].dp)
1231
        {
1232
          int chaining = (dmr1 << 2*i) & 3;
1233
          printf_filtered ("= %s ", ct_names[dcr[i].ct]);
1234
          if (dcr[i]. sc)
1235
            printf_filtered ("s%s %i", cc_names[dcr[i].cc], (int)dvr[i]);
1236
          else
1237
            printf_filtered ("%s %u", cc_names[dcr[i].cc], (unsigned int)dvr[i]);
1238
          if (chaining)
1239
            printf_filtered ("%s WP%i", ch_names[chaining], i - 1);
1240
        }
1241
      else
1242
        printf_filtered ("NOT USED");
1243
      if ((dmr2 >> i) & 1)
1244
        printf_filtered (", causes breakpoint");
1245
      if ((dmr2 >> (i + 11)) & 1)
1246
        printf_filtered (", increments counter");
1247
      printf_filtered ("\n");
1248
    }
1249
}
1250
 
1251
void
1252 106 markom
_initialize_remote_or1k ()
1253
{
1254
  /* Initialize the fields in or1k_ops that are common to all targets.  */
1255
  or1k_dummy_ops.to_close = or1k_close;
1256
  or1k_dummy_ops.to_detach = or1k_detach;
1257
  or1k_dummy_ops.to_resume = or1k_resume;
1258
  or1k_dummy_ops.to_wait = or1k_wait;
1259
  or1k_dummy_ops.to_fetch_registers = or1k_fetch_registers;
1260
  or1k_dummy_ops.to_store_registers = or1k_store_registers;
1261
  or1k_dummy_ops.to_prepare_to_store = or1k_prepare_to_store;
1262
  or1k_dummy_ops.to_xfer_memory = or1k_xfer_memory;
1263
  or1k_dummy_ops.to_files_info = or1k_files_info;
1264
  or1k_dummy_ops.to_insert_breakpoint = or1k_insert_breakpoint;
1265
  or1k_dummy_ops.to_remove_breakpoint = or1k_remove_breakpoint;
1266
  or1k_dummy_ops.to_kill = or1k_kill;
1267
  or1k_dummy_ops.to_load = generic_load;
1268
  or1k_dummy_ops.to_create_inferior = or1k_create_inferior;
1269
  or1k_dummy_ops.to_mourn_inferior = or1k_mourn_inferior;
1270
  or1k_dummy_ops.to_stratum = process_stratum;
1271
  or1k_dummy_ops.to_has_all_memory = 0; /* We can access memory while program is running.  */
1272
  or1k_dummy_ops.to_has_memory = 1;
1273
  or1k_dummy_ops.to_has_stack = 1;
1274
  or1k_dummy_ops.to_has_registers = 1;
1275
  or1k_dummy_ops.to_has_execution = 1;
1276
  or1k_dummy_ops.to_magic = OPS_MAGIC;
1277
 
1278
  /* Copy the common fields to all target vectors.  */
1279
  or1k_jtag_ops = or1k_sim_ops = or1k_dummy_ops;
1280
 
1281
  /* Initialize target-specific fields in the target vectors adn add targets.  */
1282
  or1k_jtag_ops.to_shortname = "jtag";
1283
  or1k_jtag_ops.to_longname = "Remote or1k debugging over JTAG port";
1284
  or1k_jtag_ops.to_doc = "\
1285
Debug a board using the OR1K remote debugging protocol over a parallel line.\n\
1286
The argument is the device it is connected to or, if it contains a colon,\n";
1287
  or1k_jtag_ops.to_open = or1k_jtag_open;
1288
  add_target (&or1k_jtag_ops);
1289
 
1290
  or1k_dummy_ops.to_shortname = "dummy";
1291
  or1k_dummy_ops.to_longname = "Dummy target";
1292
  or1k_dummy_ops.to_doc = "Actually no real target attached - more like /dev/null.\n";
1293
  or1k_dummy_ops.to_open = or1k_dummy_open;
1294
  add_target (&or1k_dummy_ops);
1295
 
1296
  or1k_sim_ops.to_shortname = "sim";
1297
  or1k_sim_ops.to_longname = "Remote or1k debugging using architecture simulator";
1298
  or1k_sim_ops.to_doc = "Debug using an architecture simulator.\n";
1299
  or1k_sim_ops.to_open = or1k_sim_open;
1300
  add_target (&or1k_sim_ops);
1301 113 markom
  add_info ("matchpoints", info_matchpoints_command, "Show current matchpoints allocation status.");
1302 106 markom
}

powered by: WebSVN 2.1.0

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