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

Subversion Repositories openrisc

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

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

powered by: WebSVN 2.1.0

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