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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [or1ksim/] [libtoplevel.c] - Blame information for rev 161

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

Line No. Rev Author Line
1 19 jeremybenn
/* libtoplevel.c -- Top level simulator library source file
2
 
3
   Copyright (C) 1999 Damjan Lampret, lampret@opencores.org
4
   Copyright (C) 2008 Embecosm Limited
5
 
6
   Contributor Jeremy Bennett <jeremy.bennett@embecosm.com>
7
 
8
   This file is part of OpenRISC 1000 Architectural Simulator.
9
 
10
   This program is free software; you can redistribute it and/or modify it
11
   under the terms of the GNU General Public License as published by the Free
12
   Software Foundation; either version 3 of the License, or (at your option)
13
   any later version.
14
 
15
   This program is distributed in the hope that it will be useful, but WITHOUT
16
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17
   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
18
   more details.
19
 
20
   You should have received a copy of the GNU General Public License along
21
   with this program.  If not, see <http://www.gnu.org/licenses/>. */
22
 
23
/* This program is commented throughout in a fashion suitable for processing
24
   with Doxygen. */
25
 
26
 
27
/* Autoconf and/or portability configuration */
28
#include "config.h"
29
 
30
/* System includes */
31
#include <stdlib.h>
32
#include <unistd.h>
33
#include <signal.h>
34
 
35
/* Package includes */
36
#include "or1ksim.h"
37
#include "sim-config.h"
38
#include "toplevel-support.h"
39
#include "sched.h"
40
#include "execute.h"
41
#include "pic.h"
42 82 jeremybenn
#include "jtag.h"
43 19 jeremybenn
 
44 143 jeremybenn
/* Indices of GDB registers that are not GPRs. Must match GDB settings! */
45
#define MAX_GPRS    32                  /*!< Maximum GPRs */
46
#define PPC_REGNUM  (MAX_GPRS + 0)      /*!< Previous PC */
47
#define NPC_REGNUM  (MAX_GPRS + 1)      /*!< Next PC */
48
#define SR_REGNUM   (MAX_GPRS + 2)      /*!< Supervision Register */
49 19 jeremybenn
 
50 143 jeremybenn
 
51 19 jeremybenn
/*---------------------------------------------------------------------------*/
52
/*!Initialize the simulator.
53
 
54
   Allows specification of an (optional) config file and an image file. Builds
55
   up dummy argc/argv to pass to the existing argument parser.
56
 
57
   @param[in] config_file  Or1ksim configuration file name
58
   @param[in] image_file   The program image to execute
59
   @param[in] class_ptr    Pointer to a C++ class instance (for use when
60
                           called by C++)
61
   @param[in] upr          Upcall routine for reads
62
   @param[in] upw          Upcall routine for writes
63
 
64
   @return  0 on success and an error code on failure                        */
65
/*---------------------------------------------------------------------------*/
66
int
67
or1ksim_init (const char *config_file,
68
              const char *image_file,
69
              void       *class_ptr,
70 93 jeremybenn
              int       (*upr) (void              *class_ptr,
71
                                unsigned long int  addr,
72
                                unsigned char      mask[],
73
                                unsigned char      rdata[],
74
                                int                data_len),
75
              int       (*upw) (void              *class_ptr,
76
                                unsigned long int  addr,
77
                                unsigned char      mask[],
78
                                unsigned char      wdata[],
79
                                int                data_len))
80 19 jeremybenn
{
81
  int   dummy_argc;
82
  char *dummy_argv[4];
83
 
84
  /* Dummy argv array. Varies depending on whether an image file is
85
     specified. */
86
  dummy_argv[0] = "libsim";
87
  dummy_argv[1] = "-f";
88
  dummy_argv[2] = (char *) ((NULL != config_file) ? config_file : "sim.cfg");
89
  dummy_argv[3] = (char *) image_file;
90
 
91
  dummy_argc = (NULL == image_file) ? 3 : 4;
92
 
93
  /* Initialization copied from existing main() */
94
  srand (getpid ());
95
  init_defconfig ();
96
  reg_config_secs ();
97
 
98
  if (parse_args (dummy_argc, dummy_argv))
99
    {
100
      return OR1KSIM_RC_BADINIT;
101
    }
102
 
103 143 jeremybenn
  config.sim.is_library = 1;    /* Library operation */
104
  config.sim.profile    = 0;     /* No profiling */
105
  config.sim.mprofile   = 0;
106 19 jeremybenn
 
107 143 jeremybenn
  config.ext.class_ptr  = class_ptr;    /* SystemC linkage */
108
  config.ext.read_up    = upr;
109
  config.ext.write_up   = upw;
110 19 jeremybenn
 
111
  print_config ();              /* Will go eventually */
112
  signal (SIGINT, ctrl_c);      /* Not sure we want this really */
113
 
114
  runtime.sim.hush = 1;         /* Not sure if this is needed */
115
  do_stats = config.cpu.superscalar ||
116
             config.cpu.dependstats ||
117
             config.sim.history     ||
118
             config.sim.exe_log;
119
 
120
  sim_init ();
121
 
122
  runtime.sim.ext_int_set = 0;   /* No interrupts pending to be set */
123
  runtime.sim.ext_int_clr = 0;   /* No interrupts pending to be cleared */
124
 
125
  return OR1KSIM_RC_OK;
126
 
127 143 jeremybenn
}       /* or1ksim_init () */
128 19 jeremybenn
 
129
 
130
/*---------------------------------------------------------------------------*/
131
/*!Run the simulator
132
 
133
   The argument is a time in seconds, which is converted to a number of
134
   cycles, if positive. A negative value means "run for ever".
135
 
136 97 jeremybenn
   With the JTAG interface, it is possible to stall the processor between
137
   calls of this function (but not during upcalls). In which case we return
138
   immediately.
139
 
140
   @todo Is it possible (or desirable) to permit JTAG activity during upcalls,
141
         in which case we could stall mid-run.
142
 
143
   @todo Should the JTAG functionality require enabling?
144
 
145 19 jeremybenn
   The semantics are that the duration for which the run may occur may be
146
   changed mid-run by a call to or1ksim_reset_duration(). This is to allow for
147
   the upcalls to generic components adding time, and reducing the time
148
   permitted for ISS execution before synchronization of the parent SystemC
149
   wrapper.
150
 
151
   This is over-ridden if the call was for a negative duration, which means
152
   run forever!
153
 
154
   Uses a simplified version of the old main program loop. Returns success if
155
   the requested number of cycles were run and an error code otherwise.
156
 
157
   @param[in] duration  Time to execute for (seconds)
158
 
159
   @return  OR1KSIM_RC_OK if we run to completion, OR1KSIM_RC_BRKPT if we hit
160
            a breakpoint (not clear how this can be set without CLI access)  */
161
/*---------------------------------------------------------------------------*/
162
int
163
or1ksim_run (double duration)
164
{
165
  const int  num_ints = sizeof (runtime.sim.ext_int_set) * 8;
166
 
167 97 jeremybenn
  /* If we are stalled we can't do anything. We treat this as hitting a
168 143 jeremybenn
     breakpoint or halting. */
169 97 jeremybenn
  if(runtime.cpu.stalled)
170
    {
171 143 jeremybenn
      return runtime.cpu.halted ? OR1KSIM_RC_HALTED : OR1KSIM_RC_BRKPT;
172 97 jeremybenn
    }
173
 
174
  /* Reset the duration */
175 19 jeremybenn
  or1ksim_reset_duration (duration);
176
 
177
  /* Loop until we have done enough cycles (or forever if we had a negative
178
     duration) */
179
  while (duration < 0.0 || (runtime.sim.cycles < runtime.sim.end_cycles))
180
    {
181
      long long int time_start = runtime.sim.cycles;
182
      int i;                    /* Interrupt # */
183
 
184
      /* Each cycle has counter of mem_cycles; this value is joined with cycles
185
       * at the end of the cycle; no sim originated memory accesses should be
186 82 jeremybenn
       * performed in between. */
187 19 jeremybenn
      runtime.sim.mem_cycles = 0;
188
 
189
      if (cpu_clock ())
190
        {
191 143 jeremybenn
          /* This is probably wrong. This is an Or1ksim breakpoint, not a GNU
192
             one. */
193
          return runtime.cpu.halted ? OR1KSIM_RC_HALTED : OR1KSIM_RC_BRKPT;
194 19 jeremybenn
        }
195
 
196 143 jeremybenn
      /* If we are stalled we can't do anything. We treat this as hitting a
197
         breakpoint or halting. */
198
      if(runtime.cpu.stalled)
199
        {
200
          return runtime.cpu.halted ? OR1KSIM_RC_HALTED : OR1KSIM_RC_BRKPT;
201
        }
202
 
203 19 jeremybenn
      runtime.sim.cycles += runtime.sim.mem_cycles;
204
 
205
      /* Take any external interrupts. Outer test is for the common case for
206
         efficiency. */
207
      if (0 != runtime.sim.ext_int_set)
208
        {
209
          for (i = 0; i < num_ints; i++)
210
            {
211
              if (0x1 == ((runtime.sim.ext_int_set >> i) & 0x1))
212
                {
213
                  report_interrupt (i);
214
                  runtime.sim.ext_int_set &= ~(1 << i); /* Clear req flag */
215
                }
216
            }
217
        }
218
 
219
      /* Clear any interrupts as requested. For edge triggered interrupts this
220
         will happen in the same cycle. For level triggered, it must be an
221
         explicit call. */
222
      if (0 != runtime.sim.ext_int_clr)
223
        {
224
          for (i = 0; i < num_ints; i++)
225
            {
226
              /* Only clear interrupts that have been explicitly cleared */
227
              if(0x1 == ((runtime.sim.ext_int_clr >> i) & 0x1))
228
                {
229
                  clear_interrupt(i);
230
                  runtime.sim.ext_int_clr &= ~(1 << i); /* Clear clr flag */
231
                }
232
            }
233
        }
234
 
235
      /* Update the scheduler queue */
236
      scheduler.job_queue->time -= (runtime.sim.cycles - time_start);
237
 
238
      if (scheduler.job_queue->time <= 0)
239
        {
240
          do_scheduler ();
241
        }
242
    }
243
 
244
  return  OR1KSIM_RC_OK;
245
 
246 143 jeremybenn
}       /* or1ksim_run () */
247 19 jeremybenn
 
248
 
249
/*---------------------------------------------------------------------------*/
250 143 jeremybenn
/*!Step the simulator
251
 
252
   This is just a wrapper for the run function, specifying a time
253
   corresponding to a single cycle. This will in fact mean that a single
254
   instruction is executed, even if takes more than one cycle to execute.
255
 
256
   @todo What happens if an event is triggered - that may mean multiple
257
         instructions.
258
 
259
   @return  OR1KSIM_RC_OK if we step to completion, OR1KSIM_RC_BRKPT if we hit
260
            a breakpoint (not clear how this can be set without CLI access)  */
261
/*---------------------------------------------------------------------------*/
262
int
263
or1ksim_step ()
264
{
265
  return  or1ksim_run ((double) config.sim.clkcycle_ps / 1e12);
266
 
267
}       /* or1ksim_step () */
268
 
269
 
270
/*---------------------------------------------------------------------------*/
271 19 jeremybenn
/*!Reset the run-time simulation end point
272
 
273
  Reset the time for which the simulation should run to the specified duration
274
  from NOW (i.e. NOT from when the run started).
275
 
276
  @param[in] duration  Time to run for in seconds                            */
277
/*---------------------------------------------------------------------------*/
278
void
279
or1ksim_reset_duration (double duration)
280
{
281
  runtime.sim.end_cycles =
282
    runtime.sim.cycles +
283
    (long long int) (duration * 1.0e12 / (double) config.sim.clkcycle_ps);
284
 
285 143 jeremybenn
}       /* or1ksim_reset_duration () */
286 19 jeremybenn
 
287
 
288
/*---------------------------------------------------------------------------*/
289
/*!Return time executed so far
290
 
291
   Internal utility to return the time executed so far. Note that this is a
292
   re-entrant routine.
293
 
294
   @return  Time executed so far in seconds                                  */
295
/*---------------------------------------------------------------------------*/
296
static double
297
internal_or1ksim_time ()
298
{
299
  return (double) runtime.sim.cycles * (double) config.sim.clkcycle_ps /
300
    1.0e12;
301
 
302
}       // or1ksim_cycle_count()
303
 
304
 
305
/*---------------------------------------------------------------------------*/
306
/*!Mark a time point in the simulation
307
 
308
   Sets the internal parameter recording this point in the simulation        */
309
/*---------------------------------------------------------------------------*/
310
void
311
or1ksim_set_time_point ()
312
{
313
  runtime.sim.time_point = internal_or1ksim_time ();
314
 
315 143 jeremybenn
}       /* or1ksim_set_time_point () */
316 19 jeremybenn
 
317
 
318
/*---------------------------------------------------------------------------*/
319
/*!Return the time since the time point was set
320
 
321
  Get the value from the internal parameter                                  */
322
/*---------------------------------------------------------------------------*/
323
double
324
or1ksim_get_time_period ()
325
{
326
  return internal_or1ksim_time () - runtime.sim.time_point;
327
 
328 143 jeremybenn
}       /* or1ksim_get_time_period () */
329 19 jeremybenn
 
330
 
331
/*---------------------------------------------------------------------------*/
332
/*!Return the endianism of the model
333
 
334
   Note that this is a re-entrant routine.
335
 
336
   @return 1 if the model is little endian, 0 otherwise.                     */
337
/*---------------------------------------------------------------------------*/
338
int
339
or1ksim_is_le ()
340
{
341
#ifdef OR32_BIG_ENDIAN
342
  return 0;
343
#else
344
  return 1;
345
#endif
346
 
347 143 jeremybenn
}       /* or1ksim_is_le () */
348 19 jeremybenn
 
349
 
350
/*---------------------------------------------------------------------------*/
351
/*!Return the clock rate
352
 
353
   Value is part of the configuration
354
 
355
   @return  Clock rate in Hz.                                                */
356
/*---------------------------------------------------------------------------*/
357
unsigned long int
358
or1ksim_clock_rate ()
359
{
360
  return (unsigned long int) (1000000000000ULL /
361
                              (unsigned long long int) (config.sim.
362
                                                        clkcycle_ps));
363 143 jeremybenn
}       /* or1ksim_clock_rate () */
364 19 jeremybenn
 
365
 
366
/*---------------------------------------------------------------------------*/
367
/*!Trigger an edge triggered interrupt
368
 
369
   This function is appropriate for edge triggered interrupts, which are taken
370
   and then immediately cleared.
371
 
372
   @note There is no check that the specified interrupt number is reasonable
373
   (i.e. <= 31).
374
 
375
   @param[in] i  The interrupt number                                        */
376
/*---------------------------------------------------------------------------*/
377
void
378
or1ksim_interrupt (int i)
379
{
380
  if (!config.pic.edge_trigger)
381
    {
382
      fprintf (stderr, "Warning: or1ksim_interrupt should not be used for "
383 93 jeremybenn
               "level triggered interrupts. Ignored\n");
384 19 jeremybenn
    }
385
  else
386
    {
387
      runtime.sim.ext_int_set |= 1 << i;        // Better not be > 31!
388
      runtime.sim.ext_int_clr |= 1 << i;        // Better not be > 31!
389
    }
390 143 jeremybenn
}       /* or1ksim_interrupt () */
391 19 jeremybenn
 
392
 
393
/*---------------------------------------------------------------------------*/
394
/*!Set a level triggered interrupt
395
 
396
   This function is appropriate for level triggered interrupts, which must be
397
   explicitly cleared in a separate call.
398
 
399
   @note There is no check that the specified interrupt number is reasonable
400
   (i.e. <= 31).
401
 
402
   @param[in] i  The interrupt number to set                                 */
403
/*---------------------------------------------------------------------------*/
404
void
405
or1ksim_interrupt_set (int i)
406
{
407
  if (config.pic.edge_trigger)
408
    {
409
      fprintf (stderr, "Warning: or1ksim_interrupt_set should not be used for "
410 93 jeremybenn
               "edge triggered interrupts. Ignored\n");
411 19 jeremybenn
    }
412
  else
413
    {
414
      runtime.sim.ext_int_set |= 1 << i;        // Better not be > 31!
415
    }
416 143 jeremybenn
}       /* or1ksim_interrupt () */
417 19 jeremybenn
 
418
 
419
/*---------------------------------------------------------------------------*/
420
/*!Clear a level triggered interrupt
421
 
422
   This function is appropriate for level triggered interrupts, which must be
423
   explicitly set first in a separate call.
424
 
425
   @note There is no check that the specified interrupt number is reasonable
426
   (i.e. <= 31).
427
 
428
   @param[in] i  The interrupt number to clear                               */
429
/*---------------------------------------------------------------------------*/
430
void
431
or1ksim_interrupt_clear (int i)
432
{
433
  if (config.pic.edge_trigger)
434
    {
435
      fprintf (stderr, "Warning: or1ksim_interrupt_clear should not be used "
436 93 jeremybenn
               "for edge triggered interrupts. Ignored\n");
437 19 jeremybenn
    }
438
  else
439
    {
440
      runtime.sim.ext_int_clr |= 1 << i;        // Better not be > 31!
441
    }
442 143 jeremybenn
}       /* or1ksim_interrupt () */
443 82 jeremybenn
 
444
 
445
/*---------------------------------------------------------------------------*/
446
/*!Reset the JTAG interface
447
 
448
   @note Like all the JTAG interface functions, this must not be called
449
         re-entrantly while a call to any other function (e.g. or1kim_run ())
450
         is in progress. It is the responsibility of the caller to ensure this
451
         constraint is met, for example by use of a SystemC mutex.
452
 
453
   @return  The time in seconds which the reset took.                        */
454
/*---------------------------------------------------------------------------*/
455
double
456
or1ksim_jtag_reset ()
457
{
458 98 jeremybenn
  /* Number of JTAG clock cycles a reset sequence takes */
459
  const double  JTAG_RESET_CYCLES = 5.0;
460 82 jeremybenn
 
461 98 jeremybenn
  jtag_reset ();
462
 
463
  return  JTAG_RESET_CYCLES  * (double) config.debug.jtagcycle_ps / 1.0e12;
464
 
465 82 jeremybenn
}       /* or1ksim_jtag_reset () */
466
 
467
 
468
/*---------------------------------------------------------------------------*/
469
/*!Shift a JTAG instruction register
470
 
471
   @note Like all the JTAG interface functions, this must not be called
472
         re-entrantly while a call to any other function (e.g. or1kim_run ())
473
         is in progress. It is the responsibility of the caller to ensure this
474
         constraint is met, for example by use of a SystemC mutex.
475
 
476
   The register is represented as a vector of bytes, with the byte at offset
477
   zero being shifted first, and the least significant bit in each byte being
478
   shifted first. Where the register will not fit in an exact number of bytes,
479
   the odd bits are in the highest numbered byte, shifted to the low end.
480
 
481
   The only JTAG instruction for which we have any significant behavior in
482
   this model is DEBUG. For completeness the register is parsed and a warning
483
   given if any register other than DEBUG is shifted.
484
 
485 98 jeremybenn
   @param[in,out] jreg      The register to shift in, and the register shifted
486
                            back out.
487
   @param[in]     num_bits  The number of bits in the register. Just for
488
                            sanity check (it should always be 4).
489 82 jeremybenn
 
490
   @return  The time in seconds which the shift took.                        */
491
/*---------------------------------------------------------------------------*/
492
double
493 98 jeremybenn
or1ksim_jtag_shift_ir (unsigned char *jreg,
494
                       int            num_bits)
495 82 jeremybenn
{
496 98 jeremybenn
  jtag_shift_ir (jreg, num_bits);
497 82 jeremybenn
 
498 98 jeremybenn
  return  (double) num_bits * (double) config.debug.jtagcycle_ps / 1.0e12;
499
 
500 82 jeremybenn
}       /* or1ksim_jtag_shift_ir () */
501
 
502
 
503
/*---------------------------------------------------------------------------*/
504
/*!Shift a JTAG data register
505
 
506
   @note Like all the JTAG interface functions, this must not be called
507
         re-entrantly while a call to any other function (e.g. or1kim_run ())
508
         is in progress. It is the responsibility of the caller to ensure this
509
         constraint is met, for example by use of a SystemC mutex.
510
 
511
   The register is represented as a vector of bytes, with the byte at offset
512
   zero being shifted first, and the least significant bit in each byte being
513
   shifted first. Where the register will not fit in an exact number of bytes,
514
   the odd bits are in the highest numbered byte, shifted to the low end.
515
 
516
   The register is parsed to determine which of the six possible register
517
   types it could be.
518
   - MODULE_SELECT
519
   - WRITE_COMMNAND
520
   - READ_COMMAND
521
   - GO_COMMAND
522
   - WRITE_CONTROL
523
   - READ_CONTROL
524
 
525
   @note In practice READ_COMMAND is not used. However the functionality is
526
         provided for future compatibility.
527
 
528 98 jeremybenn
   @param[in,out] jreg      The register to shift in, and the register shifted
529
                            back out.
530
   @param[in]     num_bits  The number of bits in the register. This is
531
                            essential to prevent bugs where the size of
532
                            register supplied is incorrect.
533 82 jeremybenn
 
534
   @return  The time in seconds which the shift took.                        */
535
/*---------------------------------------------------------------------------*/
536
double
537 98 jeremybenn
or1ksim_jtag_shift_dr (unsigned char *jreg,
538
                       int            num_bits)
539 82 jeremybenn
{
540 98 jeremybenn
  jtag_shift_dr (jreg, num_bits);
541 82 jeremybenn
 
542 98 jeremybenn
  return  (double) num_bits * (double) config.debug.jtagcycle_ps / 1.0e12;
543
 
544 82 jeremybenn
}       /* or1ksim_jtag_shift_dr () */
545 143 jeremybenn
 
546
 
547
/*---------------------------------------------------------------------------*/
548
/*!Read a block of memory.
549
 
550
   @param[out] buf   Where to put the data.
551
   @param[in]  addr  The address to read from.
552
   @param[in]  len   The number of bytes to read.
553
 
554
   @return  Number of bytes read, or zero if error.                          */
555
/*---------------------------------------------------------------------------*/
556
int
557
or1ksim_read_mem (unsigned char *buf,
558
                  unsigned int   addr,
559
                  int            len)
560
{
561
  int             off;                  /* Offset into the memory */
562
 
563
  /* Fill the buffer with data */
564
  for (off = 0; off < len; off++)
565
    {
566
      /* Check memory area is valid */
567
      if (NULL == verify_memoryarea (addr + off))
568
        {
569
          /* Fail silently - others can raise any error message. */
570
          return  0;
571
        }
572
      else
573
        {
574
          /* Get the memory direct - no translation. */
575
          buf[off] = eval_direct8 (addr + off, 0, 0);
576
        }
577
    }
578
 
579
  return  len;
580
 
581
}       /* or1ksim_read_mem () */
582
 
583
 
584
/*---------------------------------------------------------------------------*/
585
/*!Write a block of memory.
586
 
587
   @param[in] buf   Where to get the data from.
588
   @param[in] addr  The address to write to.
589
   @param[in] len   The number of bytes to write.
590
 
591
   @return  Number of bytes written, or zero if error.                       */
592
/*---------------------------------------------------------------------------*/
593
int
594
or1ksim_write_mem (unsigned char *buf,
595
                   unsigned int   addr,
596
                   int            len)
597
{
598
  int             off;                  /* Offset into the memory */
599
 
600
  /* Write the bytes to memory */
601
  for (off = 0; off < len; off++)
602
    {
603
      if (NULL == verify_memoryarea (addr + off))
604
        {
605
          /* Fail silently - others can raise any error message. */
606
          return  0;
607
        }
608
      else
609
        {
610
          /* circumvent the read-only check usually done for mem accesses data
611
             is in host order, because that's what set_direct32 needs */
612
          set_program8 (addr + off, buf[off]);
613
        }
614
    }
615
 
616
  return  len;
617
 
618
}       /* or1ksim_write_mem () */
619
 
620
 
621
/*---------------------------------------------------------------------------*/
622
/*!Read a single register
623
 
624
   The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
625
   (i.e. SPR NPC) and SR (i.e. SPR SR).
626
 
627
   @param[out] buf     Where to put the data.
628
   @param[in]  regnum  The register to read.
629
   @param[in]  len     Size of the register in bytes
630
 
631
   @return  Size of the register, or zero if error.                          */
632
/*---------------------------------------------------------------------------*/
633
int
634
or1ksim_read_reg (unsigned char *buf,
635
                  int            regnum,
636
                  int            len)
637
{
638
  unsigned long int *regbuf = (unsigned long *) buf;
639
 
640
  if (4 != len)
641
    {
642
      return  0;                 /* Not 32-bit reg */
643
    }
644
 
645
  /* Get the relevant register */
646
  if (regnum < MAX_GPRS)
647
    {
648
      *regbuf = cpu_state.reg[regnum];
649
    }
650
  else if (PPC_REGNUM == regnum)
651
    {
652
      *regbuf = cpu_state.sprs[SPR_PPC];
653
    }
654
  else if (NPC_REGNUM == regnum)
655
    {
656
      *regbuf = cpu_state.pc;
657
    }
658
  else if (SR_REGNUM == regnum)
659
    {
660
      *regbuf = cpu_state.sprs[SPR_SR];
661
    }
662
  else
663
    {
664
      /* Silent error response if we don't know the register */
665
      return  0;
666
    }
667
 
668
  return  len;
669
 
670
}       /* or1ksim_read_reg () */
671
 
672
 
673
/*---------------------------------------------------------------------------*/
674
/*!Write a single register
675
 
676
   The registers follow the GDB sequence for OR1K: GPR0 through GPR31, PC
677
   (i.e. SPR NPC) and SR (i.e. SPR SR). The register is specified as a
678
   sequence of bytes in target endian order.
679
 
680
   Each byte is packed as a pair of hex digits.
681
 
682
   @param[in] buf     Where to get the data from.
683
   @param[in] regnum  The register to write.
684
   @param[in]  len     Size of the register in bytes
685
 
686
   @return  Size of the register, or zero if error.                          */
687
/*---------------------------------------------------------------------------*/
688
int
689
or1ksim_write_reg (unsigned char *buf,
690
                   int            regnum,
691
                   int            len)
692
{
693
  unsigned long int *regbuf = (unsigned long *) buf;
694
  unsigned long int  regval = *regbuf;
695
 
696
  if (4 != len)
697
    {
698
      return  0;                 /* Not 32-bit reg */
699
    }
700
 
701
  /* Set the relevant register */
702
  if (regnum < MAX_GPRS)
703
    {
704
      cpu_state.reg[regnum] =regval;
705
    }
706
  else if (PPC_REGNUM == regnum)
707
    {
708
      cpu_state.sprs[SPR_PPC] = regval;
709
    }
710
  else if (NPC_REGNUM == regnum)
711
    {
712
      if (cpu_state.pc != regval)
713
        {
714
          cpu_state.pc         = regval;
715
          cpu_state.delay_insn = 0;
716
          pcnext               = regval + 4;
717
        }
718
    }
719
  else if (SR_REGNUM == regnum)
720
    {
721
      cpu_state.sprs[SPR_SR] = regval;
722
    }
723
  else
724
    {
725
      /* Silent error response if we don't know the register */
726
      return  0;
727
    }
728
 
729
  return  len;
730
 
731
}       /* or1ksim_write_reg () */
732
 
733
 

powered by: WebSVN 2.1.0

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