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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gdb-7.2/] [sim/] [mips/] [interp.c] - Blame information for rev 853

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

Line No. Rev Author Line
1 330 jeremybenn
/*> interp.c <*/
2
/* Simulator for the MIPS architecture.
3
 
4
   This file is part of the MIPS sim
5
 
6
                THIS SOFTWARE IS NOT COPYRIGHTED
7
 
8
   Cygnus offers the following for use in the public domain.  Cygnus
9
   makes no warranty with regard to the software or it's performance
10
   and the user accepts the software "AS IS" with all faults.
11
 
12
   CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13
   THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14
   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
15
 
16
NOTEs:
17
 
18
The IDT monitor (found on the VR4300 board), seems to lie about
19
register contents. It seems to treat the registers as sign-extended
20
32-bit values. This cause *REAL* problems when single-stepping 64-bit
21
code on the hardware.
22
 
23
*/
24
 
25
/* The TRACE manifests enable the provision of extra features. If they
26
   are not defined then a simpler (quicker) simulator is constructed
27
   without the required run-time checks, etc. */
28
#if 1 /* 0 to allow user build selection, 1 to force inclusion */
29
#define TRACE (1)
30
#endif
31
 
32
#include "bfd.h"
33
#include "sim-main.h"
34
#include "sim-utils.h"
35
#include "sim-options.h"
36
#include "sim-assert.h"
37
#include "sim-hw.h"
38
 
39
#include "itable.h"
40
 
41
 
42
#include "config.h"
43
 
44
#include <stdio.h>
45
#include <stdarg.h>
46
#include <ansidecl.h>
47
#include <ctype.h>
48
#include <limits.h>
49
#include <math.h>
50
#ifdef HAVE_STDLIB_H
51
#include <stdlib.h>
52
#endif
53
#ifdef HAVE_STRING_H
54
#include <string.h>
55
#else
56
#ifdef HAVE_STRINGS_H
57
#include <strings.h>
58
#endif
59
#endif
60
 
61
#include "getopt.h"
62
#include "libiberty.h"
63
#include "bfd.h"
64
#include "gdb/callback.h"   /* GDB simulator callback interface */
65
#include "gdb/remote-sim.h" /* GDB simulator interface */
66
 
67
#ifndef PARAMS
68
#define PARAMS(x) 
69
#endif
70
 
71
char* pr_addr PARAMS ((SIM_ADDR addr));
72
char* pr_uword64 PARAMS ((uword64 addr));
73
 
74
 
75
/* Within interp.c we refer to the sim_state and sim_cpu directly. */
76
#define CPU cpu
77
#define SD sd
78
 
79
 
80
/* The following reserved instruction value is used when a simulator
81
   trap is required. NOTE: Care must be taken, since this value may be
82
   used in later revisions of the MIPS ISA. */
83
 
84
#define RSVD_INSTRUCTION           (0x00000005)
85
#define RSVD_INSTRUCTION_MASK      (0xFC00003F)
86
 
87
#define RSVD_INSTRUCTION_ARG_SHIFT 6
88
#define RSVD_INSTRUCTION_ARG_MASK  0xFFFFF  
89
 
90
 
91
/* Bits in the Debug register */
92
#define Debug_DBD 0x80000000   /* Debug Branch Delay */
93
#define Debug_DM  0x40000000   /* Debug Mode         */
94
#define Debug_DBp 0x00000002   /* Debug Breakpoint indicator */
95
 
96
/*---------------------------------------------------------------------------*/
97
/*-- GDB simulator interface ------------------------------------------------*/
98
/*---------------------------------------------------------------------------*/
99
 
100
static void ColdReset PARAMS((SIM_DESC sd));
101
 
102
/*---------------------------------------------------------------------------*/
103
 
104
 
105
 
106
#define DELAYSLOT()     {\
107
                          if (STATE & simDELAYSLOT)\
108
                            sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
109
                          STATE |= simDELAYSLOT;\
110
                        }
111
 
112
#define JALDELAYSLOT()  {\
113
                          DELAYSLOT ();\
114
                          STATE |= simJALDELAYSLOT;\
115
                        }
116
 
117
#define NULLIFY()       {\
118
                          STATE &= ~simDELAYSLOT;\
119
                          STATE |= simSKIPNEXT;\
120
                        }
121
 
122
#define CANCELDELAYSLOT() {\
123
                            DSSTATE = 0;\
124
                            STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
125
                          }
126
 
127
#define INDELAYSLOT()   ((STATE & simDELAYSLOT) != 0)
128
#define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
129
 
130
/* Note that the monitor code essentially assumes this layout of memory.
131
   If you change these, change the monitor code, too.  */
132
/* FIXME Currently addresses are truncated to 32-bits, see
133
   mips/sim-main.c:address_translation(). If that changes, then these
134
   values will need to be extended, and tested for more carefully. */
135
#define K0BASE  (0x80000000)
136
#define K0SIZE  (0x20000000)
137
#define K1BASE  (0xA0000000)
138
#define K1SIZE  (0x20000000)
139
 
140
/* Simple run-time monitor support.
141
 
142
   We emulate the monitor by placing magic reserved instructions at
143
   the monitor's entry points; when we hit these instructions, instead
144
   of raising an exception (as we would normally), we look at the
145
   instruction and perform the appropriate monitory operation.
146
 
147
   `*_monitor_base' are the physical addresses at which the corresponding
148
        monitor vectors are located.  `0' means none.  By default,
149
        install all three.
150
    The RSVD_INSTRUCTION... macros specify the magic instructions we
151
    use at the monitor entry points.  */
152
static int firmware_option_p = 0;
153
static SIM_ADDR idt_monitor_base =     0xBFC00000;
154
static SIM_ADDR pmon_monitor_base =    0xBFC00500;
155
static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
156
 
157
static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
158
 
159
 
160
#define MEM_SIZE (8 << 20)      /* 8 MBytes */
161
 
162
 
163
#if defined(TRACE)
164
static char *tracefile = "trace.din"; /* default filename for trace log */
165
FILE *tracefh = NULL;
166
static void open_trace PARAMS((SIM_DESC sd));
167
#endif /* TRACE */
168
 
169
static const char * get_insn_name (sim_cpu *, int);
170
 
171
/* simulation target board.  NULL=canonical */
172
static char* board = NULL;
173
 
174
 
175
static DECLARE_OPTION_HANDLER (mips_option_handler);
176
 
177
enum {
178
  OPTION_DINERO_TRACE = OPTION_START,
179
  OPTION_DINERO_FILE,
180
  OPTION_FIRMWARE,
181
  OPTION_INFO_MEMORY,
182
  OPTION_BOARD
183
};
184
 
185
static int display_mem_info = 0;
186
 
187
static SIM_RC
188
mips_option_handler (sd, cpu, opt, arg, is_command)
189
     SIM_DESC sd;
190
     sim_cpu *cpu;
191
     int opt;
192
     char *arg;
193
     int is_command;
194
{
195
  int cpu_nr;
196
  switch (opt)
197
    {
198
    case OPTION_DINERO_TRACE: /* ??? */
199
#if defined(TRACE)
200
      /* Eventually the simTRACE flag could be treated as a toggle, to
201
         allow external control of the program points being traced
202
         (i.e. only from main onwards, excluding the run-time setup,
203
         etc.). */
204
      for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
205
        {
206
          sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
207
          if (arg == NULL)
208
            STATE |= simTRACE;
209
          else if (strcmp (arg, "yes") == 0)
210
            STATE |= simTRACE;
211
          else if (strcmp (arg, "no") == 0)
212
            STATE &= ~simTRACE;
213
          else if (strcmp (arg, "on") == 0)
214
            STATE |= simTRACE;
215
          else if (strcmp (arg, "off") == 0)
216
            STATE &= ~simTRACE;
217
          else
218
            {
219
              fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
220
              return SIM_RC_FAIL;
221
            }
222
        }
223
      return SIM_RC_OK;
224
#else /* !TRACE */
225
      fprintf(stderr,"\
226
Simulator constructed without dinero tracing support (for performance).\n\
227
Re-compile simulator with \"-DTRACE\" to enable this option.\n");
228
      return SIM_RC_FAIL;
229
#endif /* !TRACE */
230
 
231
    case OPTION_DINERO_FILE:
232
#if defined(TRACE)
233
      if (optarg != NULL) {
234
        char *tmp;
235
        tmp = (char *)malloc(strlen(optarg) + 1);
236
        if (tmp == NULL)
237
          {
238
            sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
239
            return SIM_RC_FAIL;
240
          }
241
        else {
242
          strcpy(tmp,optarg);
243
          tracefile = tmp;
244
          sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
245
        }
246
      }
247
#endif /* TRACE */
248
      return SIM_RC_OK;
249
 
250
    case OPTION_FIRMWARE:
251
      return sim_firmware_command (sd, arg);
252
 
253
    case OPTION_BOARD:
254
      {
255
        if (arg)
256
          {
257
            board = zalloc(strlen(arg) + 1);
258
            strcpy(board, arg);
259
          }
260
        return SIM_RC_OK;
261
      }
262
 
263
    case OPTION_INFO_MEMORY:
264
      display_mem_info = 1;
265
      break;
266
    }
267
 
268
  return SIM_RC_OK;
269
}
270
 
271
 
272
static const OPTION mips_options[] =
273
{
274
  { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
275
      '\0', "on|off", "Enable dinero tracing",
276
      mips_option_handler },
277
  { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
278
      '\0', "FILE", "Write dinero trace to FILE",
279
      mips_option_handler },
280
  { {"firmware", required_argument, NULL, OPTION_FIRMWARE},
281
    '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
282
    mips_option_handler },
283
  { {"board", required_argument, NULL, OPTION_BOARD},
284
     '\0', "none" /* rely on compile-time string concatenation for other options */
285
 
286
#define BOARD_JMR3904 "jmr3904"
287
           "|" BOARD_JMR3904
288
#define BOARD_JMR3904_PAL "jmr3904pal"
289
           "|" BOARD_JMR3904_PAL
290
#define BOARD_JMR3904_DEBUG "jmr3904debug"
291
           "|" BOARD_JMR3904_DEBUG
292
#define BOARD_BSP "bsp"
293
           "|" BOARD_BSP
294
 
295
    , "Customize simulation for a particular board.", mips_option_handler },
296
 
297
  /* These next two options have the same names as ones found in the
298
     memory_options[] array in common/sim-memopt.c.  This is because
299
     the intention is to provide an alternative handler for those two
300
     options.  We need an alternative handler because the memory
301
     regions are not set up until after the command line arguments
302
     have been parsed, and so we cannot display the memory info whilst
303
     processing the command line.  There is a hack in sim_open to
304
     remove these handlers when we want the real --memory-info option
305
     to work.  */
306
  { { "info-memory", no_argument, NULL, OPTION_INFO_MEMORY },
307
    '\0', NULL, "List configured memory regions", mips_option_handler },
308
  { { "memory-info", no_argument, NULL, OPTION_INFO_MEMORY },
309
    '\0', NULL, NULL, mips_option_handler },
310
 
311
  { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
312
};
313
 
314
 
315
int interrupt_pending;
316
 
317
void
318
interrupt_event (SIM_DESC sd, void *data)
319
{
320
  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
321
  address_word cia = CIA_GET (cpu);
322
  if (SR & status_IE)
323
    {
324
      interrupt_pending = 0;
325
      SignalExceptionInterrupt (1); /* interrupt "1" */
326
    }
327
  else if (!interrupt_pending)
328
    sim_events_schedule (sd, 1, interrupt_event, data);
329
}
330
 
331
 
332
/*---------------------------------------------------------------------------*/
333
/*-- Device registration hook -----------------------------------------------*/
334
/*---------------------------------------------------------------------------*/
335
static void device_init(SIM_DESC sd) {
336
#ifdef DEVICE_INIT
337
  extern void register_devices(SIM_DESC);
338
  register_devices(sd);
339
#endif
340
}
341
 
342
/*---------------------------------------------------------------------------*/
343
/*-- GDB simulator interface ------------------------------------------------*/
344
/*---------------------------------------------------------------------------*/
345
 
346
SIM_DESC
347
sim_open (kind, cb, abfd, argv)
348
     SIM_OPEN_KIND kind;
349
     host_callback *cb;
350
     struct bfd *abfd;
351
     char **argv;
352
{
353
  SIM_DESC sd = sim_state_alloc (kind, cb);
354
  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
355
 
356
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
357
 
358
  /* FIXME: watchpoints code shouldn't need this */
359
  STATE_WATCHPOINTS (sd)->pc = &(PC);
360
  STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC);
361
  STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
362
 
363
  /* Initialize the mechanism for doing insn profiling.  */
364
  CPU_INSN_NAME (cpu) = get_insn_name;
365
  CPU_MAX_INSNS (cpu) = nr_itable_entries;
366
 
367
  STATE = 0;
368
 
369
  if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
370
    return 0;
371
  sim_add_option_table (sd, NULL, mips_options);
372
 
373
 
374
  /* getopt will print the error message so we just have to exit if this fails.
375
     FIXME: Hmmm...  in the case of gdb we need getopt to call
376
     print_filtered.  */
377
  if (sim_parse_args (sd, argv) != SIM_RC_OK)
378
    {
379
      /* Uninstall the modules to avoid memory leaks,
380
         file descriptor leaks, etc.  */
381
      sim_module_uninstall (sd);
382
      return 0;
383
    }
384
 
385
  /* handle board-specific memory maps */
386
  if (board == NULL)
387
    {
388
      /* Allocate core managed memory */
389
      sim_memopt *entry, *match = NULL;
390
      address_word mem_size = 0;
391
      int mapped = 0;
392
 
393
      /* For compatibility with the old code - under this (at level one)
394
         are the kernel spaces K0 & K1.  Both of these map to a single
395
         smaller sub region */
396
      sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
397
 
398
      /* Look for largest memory region defined on command-line at
399
         phys address 0. */
400
#ifdef SIM_HAVE_FLATMEM
401
      mem_size = STATE_MEM_SIZE (sd);
402
#endif
403
      for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
404
        {
405
          /* If we find an entry at address 0, then we will end up
406
             allocating a new buffer in the "memory alias" command
407
             below. The region at address 0 will be deleted. */
408
          address_word size = (entry->modulo != 0
409
                               ? entry->modulo : entry->nr_bytes);
410
          if (entry->addr == 0
411
              && (!match || entry->level < match->level))
412
            match = entry;
413
          else if (entry->addr == K0BASE || entry->addr == K1BASE)
414
            mapped = 1;
415
          else
416
            {
417
              sim_memopt *alias;
418
              for (alias = entry->alias; alias != NULL; alias = alias->next)
419
                {
420
                  if (alias->addr == 0
421
                      && (!match || entry->level < match->level))
422
                    match = entry;
423
                  else if (alias->addr == K0BASE || alias->addr == K1BASE)
424
                    mapped = 1;
425
                }
426
            }
427
        }
428
 
429
      if (!mapped)
430
        {
431
          if (match)
432
            {
433
              /* Get existing memory region size. */
434
              mem_size = (match->modulo != 0
435
                          ? match->modulo : match->nr_bytes);
436
              /* Delete old region. */
437
              sim_do_commandf (sd, "memory delete %d:0x%lx@%d",
438
                               match->space, match->addr, match->level);
439
            }
440
          else if (mem_size == 0)
441
            mem_size = MEM_SIZE;
442
          /* Limit to KSEG1 size (512MB) */
443
          if (mem_size > K1SIZE)
444
            mem_size = K1SIZE;
445
          /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
446
          sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
447
                           K1BASE, K1SIZE, (long)mem_size, K0BASE);
448
        }
449
 
450
      device_init(sd);
451
    }
452
  else if (board != NULL
453
           && (strcmp(board, BOARD_BSP) == 0))
454
    {
455
      int i;
456
 
457
      STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
458
 
459
      /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
460
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
461
                       0x9FC00000,
462
                       4 * 1024 * 1024, /* 4 MB */
463
                       0xBFC00000);
464
 
465
      /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
466
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
467
                       0x80000000,
468
                       4 * 1024 * 1024, /* 4 MB */
469
                       0xA0000000);
470
 
471
      /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
472
      for (i=0; i<8; i++) /* 32 MB total */
473
        {
474
          unsigned size = 4 * 1024 * 1024;  /* 4 MB */
475
          sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
476
                           0x88000000 + (i * size),
477
                           size,
478
                           0xA8000000 + (i * size));
479
        }
480
    }
481
#if (WITH_HW)
482
  else if (board != NULL
483
           && (strcmp(board, BOARD_JMR3904) == 0 ||
484
               strcmp(board, BOARD_JMR3904_PAL) == 0 ||
485
               strcmp(board, BOARD_JMR3904_DEBUG) == 0))
486
    {
487
      /* match VIRTUAL memory layout of JMR-TX3904 board */
488
      int i;
489
 
490
      /* --- disable monitor unless forced on by user --- */
491
 
492
      if (! firmware_option_p)
493
        {
494
          idt_monitor_base = 0;
495
          pmon_monitor_base = 0;
496
          lsipmon_monitor_base = 0;
497
        }
498
 
499
      /* --- environment --- */
500
 
501
      STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
502
 
503
      /* --- memory --- */
504
 
505
      /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
506
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
507
                       0x9FC00000,
508
                       4 * 1024 * 1024, /* 4 MB */
509
                       0xBFC00000);
510
 
511
      /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
512
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
513
                       0x80000000,
514
                       4 * 1024 * 1024, /* 4 MB */
515
                       0xA0000000);
516
 
517
      /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
518
      for (i=0; i<8; i++) /* 32 MB total */
519
        {
520
          unsigned size = 4 * 1024 * 1024;  /* 4 MB */
521
          sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
522
                           0x88000000 + (i * size),
523
                           size,
524
                           0xA8000000 + (i * size));
525
        }
526
 
527
      /* Dummy memory regions for unsimulated devices - sorted by address */
528
 
529
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
530
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
531
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
532
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
533
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
534
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
535
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
536
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
537
      sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
538
 
539
 
540
      /* --- simulated devices --- */
541
      sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
542
      sim_hw_parse (sd, "/tx3904cpu");
543
      sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
544
      sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
545
      sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
546
      sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
547
      {
548
        /* FIXME: poking at dv-sockser internals, use tcp backend if
549
         --sockser_addr option was given.*/
550
        extern char* sockser_addr;
551
        if(sockser_addr == NULL)
552
          sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
553
        else
554
          sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
555
      }
556
      sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
557
      sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
558
 
559
      /* -- device connections --- */
560
      sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
561
      sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
562
      sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
563
      sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
564
      sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
565
      sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
566
 
567
      /* add PAL timer & I/O module */
568
      if(! strcmp(board, BOARD_JMR3904_PAL))
569
        {
570
         /* the device */
571
         sim_hw_parse (sd, "/pal@0xffff0000");
572
         sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
573
 
574
         /* wire up interrupt ports to irc */
575
         sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
576
         sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
577
         sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
578
        }
579
 
580
      if(! strcmp(board, BOARD_JMR3904_DEBUG))
581
        {
582
          /* -- DEBUG: glue interrupt generators --- */
583
          sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
584
          sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
585
          sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
586
          sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
587
          sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
588
          sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
589
          sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
590
          sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
591
          sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
592
          sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
593
          sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
594
          sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
595
          sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
596
          sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
597
          sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
598
          sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
599
          sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
600
          sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
601
          sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
602
        }
603
 
604
      device_init(sd);
605
    }
606
#endif
607
 
608
  if (display_mem_info)
609
    {
610
      struct option_list * ol;
611
      struct option_list * prev;
612
 
613
      /* This is a hack.  We want to execute the real --memory-info command
614
         line switch which is handled in common/sim-memopts.c, not the
615
         override we have defined in this file.  So we remove the
616
         mips_options array from the state options list.  This is safe
617
         because we have now processed all of the command line.  */
618
      for (ol = STATE_OPTIONS (sd), prev = NULL;
619
           ol != NULL;
620
           prev = ol, ol = ol->next)
621
        if (ol->options == mips_options)
622
          break;
623
 
624
      SIM_ASSERT (ol != NULL);
625
 
626
      if (prev == NULL)
627
        STATE_OPTIONS (sd) = ol->next;
628
      else
629
        prev->next = ol->next;
630
 
631
      sim_do_commandf (sd, "memory-info");
632
    }
633
 
634
  /* check for/establish the a reference program image */
635
  if (sim_analyze_program (sd,
636
                           (STATE_PROG_ARGV (sd) != NULL
637
                            ? *STATE_PROG_ARGV (sd)
638
                            : NULL),
639
                           abfd) != SIM_RC_OK)
640
    {
641
      sim_module_uninstall (sd);
642
      return 0;
643
    }
644
 
645
  /* Configure/verify the target byte order and other runtime
646
     configuration options */
647
  if (sim_config (sd) != SIM_RC_OK)
648
    {
649
      sim_module_uninstall (sd);
650
      return 0;
651
    }
652
 
653
  if (sim_post_argv_init (sd) != SIM_RC_OK)
654
    {
655
      /* Uninstall the modules to avoid memory leaks,
656
         file descriptor leaks, etc.  */
657
      sim_module_uninstall (sd);
658
      return 0;
659
    }
660
 
661
  /* verify assumptions the simulator made about the host type system.
662
     This macro does not return if there is a problem */
663
  SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
664
  SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
665
 
666
  /* This is NASTY, in that we are assuming the size of specific
667
     registers: */
668
  {
669
    int rn;
670
    for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
671
      {
672
        if (rn < 32)
673
          cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
674
        else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
675
          cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
676
        else if ((rn >= 33) && (rn <= 37))
677
          cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
678
        else if ((rn == SRIDX)
679
                 || (rn == FCR0IDX)
680
                 || (rn == FCR31IDX)
681
                 || ((rn >= 72) && (rn <= 89)))
682
          cpu->register_widths[rn] = 32;
683
        else
684
          cpu->register_widths[rn] = 0;
685
      }
686
 
687
 
688
  }
689
 
690
#if defined(TRACE)
691
  if (STATE & simTRACE)
692
    open_trace(sd);
693
#endif /* TRACE */
694
 
695
  /*
696
  sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
697
                  idt_monitor_base,
698
                  pmon_monitor_base,
699
                  lsipmon_monitor_base);
700
  */
701
 
702
  /* Write the monitor trap address handlers into the monitor (eeprom)
703
     address space.  This can only be done once the target endianness
704
     has been determined. */
705
  if (idt_monitor_base != 0)
706
    {
707
      unsigned loop;
708
      unsigned idt_monitor_size = 1 << 11;
709
 
710
      /* the default monitor region */
711
      sim_do_commandf (sd, "memory region 0x%x,0x%x",
712
                       idt_monitor_base, idt_monitor_size);
713
 
714
      /* Entry into the IDT monitor is via fixed address vectors, and
715
         not using machine instructions. To avoid clashing with use of
716
         the MIPS TRAP system, we place our own (simulator specific)
717
         "undefined" instructions into the relevant vector slots. */
718
      for (loop = 0; (loop < idt_monitor_size); loop += 4)
719
        {
720
          address_word vaddr = (idt_monitor_base + loop);
721
          unsigned32 insn = (RSVD_INSTRUCTION |
722
                             (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
723
                              << RSVD_INSTRUCTION_ARG_SHIFT));
724
          H2T (insn);
725
          sim_write (sd, vaddr, (char *)&insn, sizeof (insn));
726
        }
727
    }
728
 
729
  if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
730
    {
731
    /* The PMON monitor uses the same address space, but rather than
732
       branching into it the address of a routine is loaded. We can
733
       cheat for the moment, and direct the PMON routine to IDT style
734
       instructions within the monitor space. This relies on the IDT
735
       monitor not using the locations from 0xBFC00500 onwards as its
736
       entry points.*/
737
      unsigned loop;
738
      for (loop = 0; (loop < 24); loop++)
739
        {
740
          unsigned32 value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
741
          switch (loop)
742
            {
743
            case 0: /* read */
744
              value = 7;
745
              break;
746
            case 1: /* write */
747
              value = 8;
748
              break;
749
            case 2: /* open */
750
              value = 6;
751
              break;
752
            case 3: /* close */
753
              value = 10;
754
              break;
755
            case 5: /* printf */
756
              value = ((0x500 - 16) / 8); /* not an IDT reason code */
757
              break;
758
            case 8: /* cliexit */
759
              value = 17;
760
              break;
761
            case 11: /* flush_cache */
762
              value = 28;
763
              break;
764
          }
765
 
766
        SIM_ASSERT (idt_monitor_base != 0);
767
        value = ((unsigned int) idt_monitor_base + (value * 8));
768
        H2T (value);
769
 
770
        if (pmon_monitor_base != 0)
771
          {
772
            address_word vaddr = (pmon_monitor_base + (loop * 4));
773
            sim_write (sd, vaddr, (char *)&value, sizeof (value));
774
          }
775
 
776
        if (lsipmon_monitor_base != 0)
777
          {
778
            address_word vaddr = (lsipmon_monitor_base + (loop * 4));
779
            sim_write (sd, vaddr, (char *)&value, sizeof (value));
780
          }
781
      }
782
 
783
  /* Write an abort sequence into the TRAP (common) exception vector
784
     addresses.  This is to catch code executing a TRAP (et.al.)
785
     instruction without installing a trap handler. */
786
  if ((idt_monitor_base != 0) ||
787
      (pmon_monitor_base != 0) ||
788
      (lsipmon_monitor_base != 0))
789
    {
790
      unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
791
                             HALT_INSTRUCTION /* BREAK */ };
792
      H2T (halt[0]);
793
      H2T (halt[1]);
794
      sim_write (sd, 0x80000000, (char *) halt, sizeof (halt));
795
      sim_write (sd, 0x80000180, (char *) halt, sizeof (halt));
796
      sim_write (sd, 0x80000200, (char *) halt, sizeof (halt));
797
      /* XXX: Write here unconditionally? */
798
      sim_write (sd, 0xBFC00200, (char *) halt, sizeof (halt));
799
      sim_write (sd, 0xBFC00380, (char *) halt, sizeof (halt));
800
      sim_write (sd, 0xBFC00400, (char *) halt, sizeof (halt));
801
    }
802
  }
803
 
804
 
805
 
806
  return sd;
807
}
808
 
809
#if defined(TRACE)
810
static void
811
open_trace(sd)
812
     SIM_DESC sd;
813
{
814
  tracefh = fopen(tracefile,"wb+");
815
  if (tracefh == NULL)
816
    {
817
      sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
818
      tracefh = stderr;
819
  }
820
}
821
#endif /* TRACE */
822
 
823
/* Return name of an insn, used by insn profiling.  */
824
static const char *
825
get_insn_name (sim_cpu *cpu, int i)
826
{
827
  return itable[i].name;
828
}
829
 
830
void
831
sim_close (sd, quitting)
832
     SIM_DESC sd;
833
     int quitting;
834
{
835
#ifdef DEBUG
836
  printf("DBG: sim_close: entered (quitting = %d)\n",quitting);
837
#endif
838
 
839
 
840
  /* "quitting" is non-zero if we cannot hang on errors */
841
 
842
  /* shut down modules */
843
  sim_module_uninstall (sd);
844
 
845
  /* Ensure that any resources allocated through the callback
846
     mechanism are released: */
847
  sim_io_shutdown (sd);
848
 
849
#if defined(TRACE)
850
  if (tracefh != NULL && tracefh != stderr)
851
   fclose(tracefh);
852
  tracefh = NULL;
853
#endif /* TRACE */
854
 
855
  /* FIXME - free SD */
856
 
857
  return;
858
}
859
 
860
 
861
int
862
sim_write (sd,addr,buffer,size)
863
     SIM_DESC sd;
864
     SIM_ADDR addr;
865
     const unsigned char *buffer;
866
     int size;
867
{
868
  int index;
869
  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
870
 
871
  /* Return the number of bytes written, or zero if error. */
872
#ifdef DEBUG
873
  sim_io_printf(sd,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr),size);
874
#endif
875
 
876
  /* We use raw read and write routines, since we do not want to count
877
     the GDB memory accesses in our statistics gathering. */
878
 
879
  for (index = 0; index < size; index++)
880
    {
881
      address_word vaddr = (address_word)addr + index;
882
      address_word paddr;
883
      int cca;
884
      if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isSTORE, &paddr, &cca, isRAW))
885
        break;
886
      if (sim_core_write_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
887
        break;
888
    }
889
 
890
  return(index);
891
}
892
 
893
int
894
sim_read (sd,addr,buffer,size)
895
     SIM_DESC sd;
896
     SIM_ADDR addr;
897
     unsigned char *buffer;
898
     int size;
899
{
900
  int index;
901
  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
902
 
903
  /* Return the number of bytes read, or zero if error. */
904
#ifdef DEBUG
905
  sim_io_printf(sd,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr),size);
906
#endif /* DEBUG */
907
 
908
  for (index = 0; (index < size); index++)
909
    {
910
      address_word vaddr = (address_word)addr + index;
911
      address_word paddr;
912
      int cca;
913
      if (!address_translation (SD, CPU, NULL_CIA, vaddr, isDATA, isLOAD, &paddr, &cca, isRAW))
914
        break;
915
      if (sim_core_read_buffer (SD, CPU, read_map, buffer + index, paddr, 1) != 1)
916
        break;
917
    }
918
 
919
  return(index);
920
}
921
 
922
int
923
sim_store_register (sd,rn,memory,length)
924
     SIM_DESC sd;
925
     int rn;
926
     unsigned char *memory;
927
     int length;
928
{
929
  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
930
  /* NOTE: gdb (the client) stores registers in target byte order
931
     while the simulator uses host byte order */
932
#ifdef DEBUG
933
  sim_io_printf(sd,"sim_store_register(%d,*memory=0x%s);\n",rn,pr_addr(*((SIM_ADDR *)memory)));
934
#endif /* DEBUG */
935
 
936
  /* Unfortunately this suffers from the same problem as the register
937
     numbering one. We need to know what the width of each logical
938
     register number is for the architecture being simulated. */
939
 
940
  if (cpu->register_widths[rn] == 0)
941
    {
942
      sim_io_eprintf(sd,"Invalid register width for %d (register store ignored)\n",rn);
943
      return 0;
944
    }
945
 
946
 
947
 
948
  if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
949
    {
950
      cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
951
      if (cpu->register_widths[rn] == 32)
952
        {
953
          if (length == 8)
954
            {
955
              cpu->fgr[rn - FGR_BASE] =
956
                (unsigned32) T2H_8 (*(unsigned64*)memory);
957
              return 8;
958
            }
959
          else
960
            {
961
              cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
962
              return 4;
963
            }
964
        }
965
      else
966
        {
967
          if (length == 8)
968
            {
969
              cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
970
              return 8;
971
            }
972
          else
973
            {
974
              cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
975
              return 4;
976
            }
977
        }
978
    }
979
 
980
  if (cpu->register_widths[rn] == 32)
981
    {
982
      if (length == 8)
983
        {
984
          cpu->registers[rn] =
985
            (unsigned32) T2H_8 (*(unsigned64*)memory);
986
          return 8;
987
        }
988
      else
989
        {
990
          cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
991
          return 4;
992
        }
993
    }
994
  else
995
    {
996
      if (length == 8)
997
        {
998
          cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
999
          return 8;
1000
        }
1001
      else
1002
        {
1003
          cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
1004
          return 4;
1005
        }
1006
    }
1007
 
1008
  return 0;
1009
}
1010
 
1011
int
1012
sim_fetch_register (sd,rn,memory,length)
1013
     SIM_DESC sd;
1014
     int rn;
1015
     unsigned char *memory;
1016
     int length;
1017
{
1018
  sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
1019
  /* NOTE: gdb (the client) stores registers in target byte order
1020
     while the simulator uses host byte order */
1021
#ifdef DEBUG
1022
#if 0  /* FIXME: doesn't compile */
1023
  sim_io_printf(sd,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn,pr_addr(registers[rn]));
1024
#endif
1025
#endif /* DEBUG */
1026
 
1027
  if (cpu->register_widths[rn] == 0)
1028
    {
1029
      sim_io_eprintf (sd, "Invalid register width for %d (register fetch ignored)\n",rn);
1030
      return 0;
1031
    }
1032
 
1033
 
1034
 
1035
  /* Any floating point register */
1036
  if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
1037
    {
1038
      if (cpu->register_widths[rn] == 32)
1039
        {
1040
          if (length == 8)
1041
            {
1042
              *(unsigned64*)memory =
1043
                H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE]));
1044
              return 8;
1045
            }
1046
          else
1047
            {
1048
              *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]);
1049
              return 4;
1050
            }
1051
        }
1052
      else
1053
        {
1054
          if (length == 8)
1055
            {
1056
              *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
1057
              return 8;
1058
            }
1059
          else
1060
            {
1061
              *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
1062
              return 4;
1063
            }
1064
        }
1065
    }
1066
 
1067
  if (cpu->register_widths[rn] == 32)
1068
    {
1069
      if (length == 8)
1070
        {
1071
          *(unsigned64*)memory =
1072
            H2T_8 ((unsigned32) (cpu->registers[rn]));
1073
          return 8;
1074
        }
1075
      else
1076
        {
1077
          *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
1078
          return 4;
1079
        }
1080
    }
1081
  else
1082
    {
1083
      if (length == 8)
1084
        {
1085
          *(unsigned64*)memory =
1086
            H2T_8 ((unsigned64) (cpu->registers[rn]));
1087
          return 8;
1088
        }
1089
      else
1090
        {
1091
          *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
1092
          return 4;
1093
        }
1094
    }
1095
 
1096
  return 0;
1097
}
1098
 
1099
 
1100
SIM_RC
1101
sim_create_inferior (sd, abfd, argv,env)
1102
     SIM_DESC sd;
1103
     struct bfd *abfd;
1104
     char **argv;
1105
     char **env;
1106
{
1107
 
1108
#ifdef DEBUG
1109
#if 0 /* FIXME: doesn't compile */
1110
  printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1111
         pr_addr(PC));
1112
#endif
1113
#endif /* DEBUG */
1114
 
1115
  ColdReset(sd);
1116
 
1117
  if (abfd != NULL)
1118
    {
1119
      /* override PC value set by ColdReset () */
1120
      int cpu_nr;
1121
      for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1122
        {
1123
          sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1124
          CIA_SET (cpu, (unsigned64) bfd_get_start_address (abfd));
1125
        }
1126
    }
1127
 
1128
#if 0 /* def DEBUG */
1129
  if (argv || env)
1130
    {
1131
      /* We should really place the argv slot values into the argument
1132
         registers, and onto the stack as required. However, this
1133
         assumes that we have a stack defined, which is not
1134
         necessarily true at the moment. */
1135
      char **cptr;
1136
      sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1137
      for (cptr = argv; (cptr && *cptr); cptr++)
1138
        printf("DBG: arg \"%s\"\n",*cptr);
1139
    }
1140
#endif /* DEBUG */
1141
 
1142
  return SIM_RC_OK;
1143
}
1144
 
1145
void
1146
sim_do_command (sd,cmd)
1147
     SIM_DESC sd;
1148
     char *cmd;
1149
{
1150
  if (sim_args_command (sd, cmd) != SIM_RC_OK)
1151
    sim_io_printf (sd, "Error: \"%s\" is not a valid MIPS simulator command.\n",
1152
                   cmd);
1153
}
1154
 
1155
/*---------------------------------------------------------------------------*/
1156
/*-- Private simulator support interface ------------------------------------*/
1157
/*---------------------------------------------------------------------------*/
1158
 
1159
/* Read a null terminated string from memory, return in a buffer */
1160
static char *
1161
fetch_str (SIM_DESC sd,
1162
           address_word addr)
1163
{
1164
  char *buf;
1165
  int nr = 0;
1166
  char null;
1167
  while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1168
    nr++;
1169
  buf = NZALLOC (char, nr + 1);
1170
  sim_read (sd, addr, buf, nr);
1171
  return buf;
1172
}
1173
 
1174
 
1175
/* Implements the "sim firmware" command:
1176
        sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1177
                NAME can be idt, pmon, or lsipmon.  If omitted, ADDRESS
1178
                defaults to the normal address for that monitor.
1179
        sim firmware none --- don't emulate any ROM monitor.  Useful
1180
                if you need a clean address space.  */
1181
static SIM_RC
1182
sim_firmware_command (SIM_DESC sd, char *arg)
1183
{
1184
  int address_present = 0;
1185
  SIM_ADDR address;
1186
 
1187
  /* Signal occurrence of this option. */
1188
  firmware_option_p = 1;
1189
 
1190
  /* Parse out the address, if present.  */
1191
  {
1192
    char *p = strchr (arg, '@');
1193
    if (p)
1194
      {
1195
        char *q;
1196
        address_present = 1;
1197
        p ++; /* skip over @ */
1198
 
1199
        address = strtoul (p, &q, 0);
1200
        if (*q != '\0')
1201
          {
1202
            sim_io_printf (sd, "Invalid address given to the"
1203
                           "`sim firmware NAME@ADDRESS' command: %s\n",
1204
                           p);
1205
            return SIM_RC_FAIL;
1206
          }
1207
      }
1208
    else
1209
      {
1210
        address_present = 0;
1211
        address = -1; /* Dummy value.  */
1212
      }
1213
  }
1214
 
1215
  if (! strncmp (arg, "idt", 3))
1216
    {
1217
      idt_monitor_base = address_present ? address : 0xBFC00000;
1218
      pmon_monitor_base = 0;
1219
      lsipmon_monitor_base = 0;
1220
    }
1221
  else if (! strncmp (arg, "pmon", 4))
1222
    {
1223
      /* pmon uses indirect calls.  Hook into implied idt. */
1224
      pmon_monitor_base = address_present ? address : 0xBFC00500;
1225
      idt_monitor_base = pmon_monitor_base - 0x500;
1226
      lsipmon_monitor_base = 0;
1227
    }
1228
  else if (! strncmp (arg, "lsipmon", 7))
1229
    {
1230
      /* lsipmon uses indirect calls.  Hook into implied idt. */
1231
      pmon_monitor_base = 0;
1232
      lsipmon_monitor_base = address_present ? address : 0xBFC00200;
1233
      idt_monitor_base = lsipmon_monitor_base - 0x200;
1234
    }
1235
  else if (! strncmp (arg, "none", 4))
1236
    {
1237
      if (address_present)
1238
        {
1239
          sim_io_printf (sd,
1240
                         "The `sim firmware none' command does "
1241
                         "not take an `ADDRESS' argument.\n");
1242
          return SIM_RC_FAIL;
1243
        }
1244
      idt_monitor_base = 0;
1245
      pmon_monitor_base = 0;
1246
      lsipmon_monitor_base = 0;
1247
    }
1248
  else
1249
    {
1250
      sim_io_printf (sd, "\
1251
Unrecognized name given to the `sim firmware NAME' command: %s\n\
1252
Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1253
                     arg);
1254
      return SIM_RC_FAIL;
1255
    }
1256
 
1257
  return SIM_RC_OK;
1258
}
1259
 
1260
 
1261
 
1262
/* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1263
int
1264
sim_monitor (SIM_DESC sd,
1265
             sim_cpu *cpu,
1266
             address_word cia,
1267
             unsigned int reason)
1268
{
1269
#ifdef DEBUG
1270
  printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1271
#endif /* DEBUG */
1272
 
1273
  /* The IDT monitor actually allows two instructions per vector
1274
     slot. However, the simulator currently causes a trap on each
1275
     individual instruction. We cheat, and lose the bottom bit. */
1276
  reason >>= 1;
1277
 
1278
  /* The following callback functions are available, however the
1279
     monitor we are simulating does not make use of them: get_errno,
1280
     isatty, lseek, rename, system, time and unlink */
1281
  switch (reason)
1282
    {
1283
 
1284
    case 6: /* int open(char *path,int flags) */
1285
      {
1286
        char *path = fetch_str (sd, A0);
1287
        V0 = sim_io_open (sd, path, (int)A1);
1288
        zfree (path);
1289
        break;
1290
      }
1291
 
1292
    case 7: /* int read(int file,char *ptr,int len) */
1293
      {
1294
        int fd = A0;
1295
        int nr = A2;
1296
        char *buf = zalloc (nr);
1297
        V0 = sim_io_read (sd, fd, buf, nr);
1298
        sim_write (sd, A1, buf, nr);
1299
        zfree (buf);
1300
      }
1301
      break;
1302
 
1303
    case 8: /* int write(int file,char *ptr,int len) */
1304
      {
1305
        int fd = A0;
1306
        int nr = A2;
1307
        char *buf = zalloc (nr);
1308
        sim_read (sd, A1, buf, nr);
1309
        V0 = sim_io_write (sd, fd, buf, nr);
1310
        if (fd == 1)
1311
            sim_io_flush_stdout (sd);
1312
        else if (fd == 2)
1313
            sim_io_flush_stderr (sd);
1314
        zfree (buf);
1315
        break;
1316
      }
1317
 
1318
    case 10: /* int close(int file) */
1319
      {
1320
        V0 = sim_io_close (sd, (int)A0);
1321
        break;
1322
      }
1323
 
1324
    case 2:  /* Densan monitor: char inbyte(int waitflag) */
1325
      {
1326
        if (A0 == 0)     /* waitflag == NOWAIT */
1327
          V0 = (unsigned_word)-1;
1328
      }
1329
     /* Drop through to case 11 */
1330
 
1331
    case 11: /* char inbyte(void) */
1332
      {
1333
        char tmp;
1334
        /* ensure that all output has gone... */
1335
        sim_io_flush_stdout (sd);
1336
        if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1337
          {
1338
            sim_io_error(sd,"Invalid return from character read");
1339
            V0 = (unsigned_word)-1;
1340
          }
1341
        else
1342
          V0 = (unsigned_word)tmp;
1343
        break;
1344
      }
1345
 
1346
    case 3:  /* Densan monitor: void co(char chr) */
1347
    case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1348
      {
1349
        char tmp = (char)(A0 & 0xFF);
1350
        sim_io_write_stdout (sd, &tmp, sizeof(char));
1351
        break;
1352
      }
1353
 
1354
    case 17: /* void _exit() */
1355
      {
1356
        sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1357
        sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1358
                         (unsigned int)(A0 & 0xFFFFFFFF));
1359
        break;
1360
      }
1361
 
1362
    case 28: /* PMON flush_cache */
1363
      break;
1364
 
1365
    case 55: /* void get_mem_info(unsigned int *ptr) */
1366
      /* in:  A0 = pointer to three word memory location */
1367
      /* out: [A0 + 0] = size */
1368
      /*      [A0 + 4] = instruction cache size */
1369
      /*      [A0 + 8] = data cache size */
1370
      {
1371
        unsigned_4 value;
1372
        unsigned_4 zero = 0;
1373
        address_word mem_size;
1374
        sim_memopt *entry, *match = NULL;
1375
 
1376
        /* Search for memory region mapped to KSEG0 or KSEG1. */
1377
        for (entry = STATE_MEMOPT (sd);
1378
             entry != NULL;
1379
             entry = entry->next)
1380
          {
1381
            if ((entry->addr == K0BASE || entry->addr == K1BASE)
1382
                && (!match || entry->level < match->level))
1383
              match = entry;
1384
            else
1385
              {
1386
                sim_memopt *alias;
1387
                for (alias = entry->alias;
1388
                     alias != NULL;
1389
                     alias = alias->next)
1390
                  if ((alias->addr == K0BASE || alias->addr == K1BASE)
1391
                      && (!match || entry->level < match->level))
1392
                    match = entry;
1393
              }
1394
          }
1395
 
1396
        /* Get region size, limit to KSEG1 size (512MB). */
1397
        SIM_ASSERT (match != NULL);
1398
        mem_size = (match->modulo != 0
1399
                    ? match->modulo : match->nr_bytes);
1400
        if (mem_size > K1SIZE)
1401
          mem_size = K1SIZE;
1402
 
1403
        value = mem_size;
1404
        H2T (value);
1405
        sim_write (sd, A0 + 0, (char *)&value, 4);
1406
        sim_write (sd, A0 + 4, (char *)&zero, 4);
1407
        sim_write (sd, A0 + 8, (char *)&zero, 4);
1408
        /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1409
        break;
1410
      }
1411
 
1412
    case 158: /* PMON printf */
1413
      /* in:  A0 = pointer to format string */
1414
      /*      A1 = optional argument 1 */
1415
      /*      A2 = optional argument 2 */
1416
      /*      A3 = optional argument 3 */
1417
      /* out: void */
1418
      /* The following is based on the PMON printf source */
1419
      {
1420
        address_word s = A0;
1421
        char c;
1422
        signed_word *ap = &A1; /* 1st argument */
1423
        /* This isn't the quickest way, since we call the host print
1424
           routine for every character almost. But it does avoid
1425
           having to allocate and manage a temporary string buffer. */
1426
        /* TODO: Include check that we only use three arguments (A1,
1427
           A2 and A3) */
1428
        while (sim_read (sd, s++, &c, 1) && c != '\0')
1429
          {
1430
            if (c == '%')
1431
              {
1432
                char tmp[40];
1433
                enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1434
                int width = 0, trunc = 0, haddot = 0, longlong = 0;
1435
                while (sim_read (sd, s++, &c, 1) && c != '\0')
1436
                  {
1437
                    if (strchr ("dobxXulscefg%", c))
1438
                      break;
1439
                    else if (c == '-')
1440
                      fmt = FMT_LJUST;
1441
                    else if (c == '0')
1442
                      fmt = FMT_RJUST0;
1443
                    else if (c == '~')
1444
                      fmt = FMT_CENTER;
1445
                    else if (c == '*')
1446
                      {
1447
                        if (haddot)
1448
                          trunc = (int)*ap++;
1449
                        else
1450
                          width = (int)*ap++;
1451
                      }
1452
                    else if (c >= '1' && c <= '9')
1453
                      {
1454
                        address_word t = s;
1455
                        unsigned int n;
1456
                        while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1457
                          tmp[s - t] = c;
1458
                        tmp[s - t] = '\0';
1459
                        n = (unsigned int)strtol(tmp,NULL,10);
1460
                        if (haddot)
1461
                          trunc = n;
1462
                        else
1463
                          width = n;
1464
                        s--;
1465
                      }
1466
                    else if (c == '.')
1467
                      haddot = 1;
1468
                  }
1469
                switch (c)
1470
                  {
1471
                  case '%':
1472
                    sim_io_printf (sd, "%%");
1473
                    break;
1474
                  case 's':
1475
                    if ((int)*ap != 0)
1476
                      {
1477
                        address_word p = *ap++;
1478
                        char ch;
1479
                        while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1480
                          sim_io_printf(sd, "%c", ch);
1481
                      }
1482
                    else
1483
                      sim_io_printf(sd,"(null)");
1484
                    break;
1485
                  case 'c':
1486
                    sim_io_printf (sd, "%c", (int)*ap++);
1487
                    break;
1488
                  default:
1489
                    if (c == 'l')
1490
                      {
1491
                        sim_read (sd, s++, &c, 1);
1492
                        if (c == 'l')
1493
                          {
1494
                            longlong = 1;
1495
                            sim_read (sd, s++, &c, 1);
1496
                          }
1497
                      }
1498
                    if (strchr ("dobxXu", c))
1499
                      {
1500
                        word64 lv = (word64) *ap++;
1501
                        if (c == 'b')
1502
                          sim_io_printf(sd,"<binary not supported>");
1503
                        else
1504
                          {
1505
                            sprintf (tmp, "%%%s%c", longlong ? "ll" : "", c);
1506
                            if (longlong)
1507
                              sim_io_printf(sd, tmp, lv);
1508
                            else
1509
                              sim_io_printf(sd, tmp, (int)lv);
1510
                          }
1511
                      }
1512
                    else if (strchr ("eEfgG", c))
1513
                      {
1514
                        double dbl = *(double*)(ap++);
1515
                        sprintf (tmp, "%%%d.%d%c", width, trunc, c);
1516
                        sim_io_printf (sd, tmp, dbl);
1517
                        trunc = 0;
1518
                      }
1519
                  }
1520
              }
1521
            else
1522
              sim_io_printf(sd, "%c", c);
1523
          }
1524
        break;
1525
      }
1526
 
1527
    default:
1528
      /* Unknown reason.  */
1529
      return 0;
1530
  }
1531
  return 1;
1532
}
1533
 
1534
/* Store a word into memory.  */
1535
 
1536
static void
1537
store_word (SIM_DESC sd,
1538
            sim_cpu *cpu,
1539
            address_word cia,
1540
            uword64 vaddr,
1541
            signed_word val)
1542
{
1543
  address_word paddr;
1544
  int uncached;
1545
 
1546
  if ((vaddr & 3) != 0)
1547
    SignalExceptionAddressStore ();
1548
  else
1549
    {
1550
      if (AddressTranslation (vaddr, isDATA, isSTORE, &paddr, &uncached,
1551
                              isTARGET, isREAL))
1552
        {
1553
          const uword64 mask = 7;
1554
          uword64 memval;
1555
          unsigned int byte;
1556
 
1557
          paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1558
          byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1559
          memval = ((uword64) val) << (8 * byte);
1560
          StoreMemory (uncached, AccessLength_WORD, memval, 0, paddr, vaddr,
1561
                       isREAL);
1562
        }
1563
    }
1564
}
1565
 
1566
/* Load a word from memory.  */
1567
 
1568
static signed_word
1569
load_word (SIM_DESC sd,
1570
           sim_cpu *cpu,
1571
           address_word cia,
1572
           uword64 vaddr)
1573
{
1574
  if ((vaddr & 3) != 0)
1575
    {
1576
      SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1577
    }
1578
  else
1579
    {
1580
      address_word paddr;
1581
      int uncached;
1582
 
1583
      if (AddressTranslation (vaddr, isDATA, isLOAD, &paddr, &uncached,
1584
                              isTARGET, isREAL))
1585
        {
1586
          const uword64 mask = 0x7;
1587
          const unsigned int reverse = ReverseEndian ? 1 : 0;
1588
          const unsigned int bigend = BigEndianCPU ? 1 : 0;
1589
          uword64 memval;
1590
          unsigned int byte;
1591
 
1592
          paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1593
          LoadMemory (&memval,NULL,uncached, AccessLength_WORD, paddr, vaddr,
1594
                               isDATA, isREAL);
1595
          byte = (vaddr & mask) ^ (bigend << 2);
1596
          return EXTEND32 (memval >> (8 * byte));
1597
        }
1598
    }
1599
 
1600
  return 0;
1601
}
1602
 
1603
/* Simulate the mips16 entry and exit pseudo-instructions.  These
1604
   would normally be handled by the reserved instruction exception
1605
   code, but for ease of simulation we just handle them directly.  */
1606
 
1607
static void
1608
mips16_entry (SIM_DESC sd,
1609
              sim_cpu *cpu,
1610
              address_word cia,
1611
              unsigned int insn)
1612
{
1613
  int aregs, sregs, rreg;
1614
 
1615
#ifdef DEBUG
1616
  printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1617
#endif /* DEBUG */
1618
 
1619
  aregs = (insn & 0x700) >> 8;
1620
  sregs = (insn & 0x0c0) >> 6;
1621
  rreg =  (insn & 0x020) >> 5;
1622
 
1623
  /* This should be checked by the caller.  */
1624
  if (sregs == 3)
1625
    abort ();
1626
 
1627
  if (aregs < 5)
1628
    {
1629
      int i;
1630
      signed_word tsp;
1631
 
1632
      /* This is the entry pseudo-instruction.  */
1633
 
1634
      for (i = 0; i < aregs; i++)
1635
        store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1636
 
1637
      tsp = SP;
1638
      SP -= 32;
1639
 
1640
      if (rreg)
1641
        {
1642
          tsp -= 4;
1643
          store_word (SD, CPU, cia, (uword64) tsp, RA);
1644
        }
1645
 
1646
      for (i = 0; i < sregs; i++)
1647
        {
1648
          tsp -= 4;
1649
          store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1650
        }
1651
    }
1652
  else
1653
    {
1654
      int i;
1655
      signed_word tsp;
1656
 
1657
      /* This is the exit pseudo-instruction.  */
1658
 
1659
      tsp = SP + 32;
1660
 
1661
      if (rreg)
1662
        {
1663
          tsp -= 4;
1664
          RA = load_word (SD, CPU, cia, (uword64) tsp);
1665
        }
1666
 
1667
      for (i = 0; i < sregs; i++)
1668
        {
1669
          tsp -= 4;
1670
          GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1671
        }
1672
 
1673
      SP += 32;
1674
 
1675
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1676
        {
1677
          if (aregs == 5)
1678
            {
1679
              FGR[0] = WORD64LO (GPR[4]);
1680
              FPR_STATE[0] = fmt_uninterpreted;
1681
            }
1682
          else if (aregs == 6)
1683
            {
1684
              FGR[0] = WORD64LO (GPR[5]);
1685
              FGR[1] = WORD64LO (GPR[4]);
1686
              FPR_STATE[0] = fmt_uninterpreted;
1687
              FPR_STATE[1] = fmt_uninterpreted;
1688
            }
1689
        }
1690
 
1691
      PC = RA;
1692
    }
1693
 
1694
}
1695
 
1696
/*-- trace support ----------------------------------------------------------*/
1697
 
1698
/* The TRACE support is provided (if required) in the memory accessing
1699
   routines. Since we are also providing the architecture specific
1700
   features, the architecture simulation code can also deal with
1701
   notifying the TRACE world of cache flushes, etc. Similarly we do
1702
   not need to provide profiling support in the simulator engine,
1703
   since we can sample in the instruction fetch control loop. By
1704
   defining the TRACE manifest, we add tracing as a run-time
1705
   option. */
1706
 
1707
#if defined(TRACE)
1708
/* Tracing by default produces "din" format (as required by
1709
   dineroIII). Each line of such a trace file *MUST* have a din label
1710
   and address field. The rest of the line is ignored, so comments can
1711
   be included if desired. The first field is the label which must be
1712
   one of the following values:
1713
 
1714
 
1715
        1       write data
1716
        2       instruction fetch
1717
        3       escape record (treated as unknown access type)
1718
        4       escape record (causes cache flush)
1719
 
1720
   The address field is a 32bit (lower-case) hexadecimal address
1721
   value. The address should *NOT* be preceded by "0x".
1722
 
1723
   The size of the memory transfer is not important when dealing with
1724
   cache lines (as long as no more than a cache line can be
1725
   transferred in a single operation :-), however more information
1726
   could be given following the dineroIII requirement to allow more
1727
   complete memory and cache simulators to provide better
1728
   results. i.e. the University of Pisa has a cache simulator that can
1729
   also take bus size and speed as (variable) inputs to calculate
1730
   complete system performance (a much more useful ability when trying
1731
   to construct an end product, rather than a processor). They
1732
   currently have an ARM version of their tool called ChARM. */
1733
 
1734
 
1735
void
1736
dotrace (SIM_DESC sd,
1737
         sim_cpu *cpu,
1738
         FILE *tracefh,
1739
         int type,
1740
         SIM_ADDR address,
1741
         int width,
1742
         char *comment,...)
1743
{
1744
  if (STATE & simTRACE) {
1745
    va_list ap;
1746
    fprintf(tracefh,"%d %s ; width %d ; ",
1747
                type,
1748
                pr_addr(address),
1749
                width);
1750
    va_start(ap,comment);
1751
    vfprintf(tracefh,comment,ap);
1752
    va_end(ap);
1753
    fprintf(tracefh,"\n");
1754
  }
1755
  /* NOTE: Since the "din" format will only accept 32bit addresses, and
1756
     we may be generating 64bit ones, we should put the hi-32bits of the
1757
     address into the comment field. */
1758
 
1759
  /* TODO: Provide a buffer for the trace lines. We can then avoid
1760
     performing writes until the buffer is filled, or the file is
1761
     being closed. */
1762
 
1763
  /* NOTE: We could consider adding a comment field to the "din" file
1764
     produced using type 3 markers (unknown access). This would then
1765
     allow information about the program that the "din" is for, and
1766
     the MIPs world that was being simulated, to be placed into the
1767
     trace file. */
1768
 
1769
  return;
1770
}
1771
#endif /* TRACE */
1772
 
1773
/*---------------------------------------------------------------------------*/
1774
/*-- simulator engine -------------------------------------------------------*/
1775
/*---------------------------------------------------------------------------*/
1776
 
1777
static void
1778
ColdReset (SIM_DESC sd)
1779
{
1780
  int cpu_nr;
1781
  for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1782
    {
1783
      sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1784
      /* RESET: Fixed PC address: */
1785
      PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1786
      /* The reset vector address is in the unmapped, uncached memory space. */
1787
 
1788
      SR &= ~(status_SR | status_TS | status_RP);
1789
      SR |= (status_ERL | status_BEV);
1790
 
1791
      /* Cheat and allow access to the complete register set immediately */
1792
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1793
          && WITH_TARGET_WORD_BITSIZE == 64)
1794
        SR |= status_FR; /* 64bit registers */
1795
 
1796
      /* Ensure that any instructions with pending register updates are
1797
         cleared: */
1798
      PENDING_INVALIDATE();
1799
 
1800
      /* Initialise the FPU registers to the unknown state */
1801
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1802
        {
1803
          int rn;
1804
          for (rn = 0; (rn < 32); rn++)
1805
            FPR_STATE[rn] = fmt_uninterpreted;
1806
        }
1807
 
1808
      /* Initialise the Config0 register. */
1809
      C0_CONFIG = 0x80000000            /* Config1 present */
1810
        | 2;                            /* KSEG0 uncached */
1811
      if (WITH_TARGET_WORD_BITSIZE == 64)
1812
        {
1813
          /* FIXME Currently mips/sim-main.c:address_translation()
1814
             truncates all addresses to 32-bits. */
1815
          if (0 && WITH_TARGET_ADDRESS_BITSIZE == 64)
1816
            C0_CONFIG |= (2 << 13);     /* MIPS64, 64-bit addresses */
1817
          else
1818
            C0_CONFIG |= (1 << 13);     /* MIPS64, 32-bit addresses */
1819
        }
1820
      if (BigEndianMem)
1821
        C0_CONFIG |= 0x00008000;        /* Big Endian */
1822
    }
1823
}
1824
 
1825
 
1826
 
1827
 
1828
/* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1829
/* Signal an exception condition. This will result in an exception
1830
   that aborts the instruction. The instruction operation pseudocode
1831
   will never see a return from this function call. */
1832
 
1833
void
1834
signal_exception (SIM_DESC sd,
1835
                  sim_cpu *cpu,
1836
                  address_word cia,
1837
                  int exception,...)
1838
{
1839
  /* int vector; */
1840
 
1841
#ifdef DEBUG
1842
  sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1843
#endif /* DEBUG */
1844
 
1845
  /* Ensure that any active atomic read/modify/write operation will fail: */
1846
  LLBIT = 0;
1847
 
1848
  /* Save registers before interrupt dispatching */
1849
#ifdef SIM_CPU_EXCEPTION_TRIGGER
1850
  SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1851
#endif
1852
 
1853
  switch (exception) {
1854
 
1855
    case DebugBreakPoint:
1856
      if (! (Debug & Debug_DM))
1857
        {
1858
          if (INDELAYSLOT())
1859
            {
1860
              CANCELDELAYSLOT();
1861
 
1862
              Debug |= Debug_DBD;  /* signaled from within in delay slot */
1863
              DEPC = cia - 4;      /* reference the branch instruction */
1864
            }
1865
          else
1866
            {
1867
              Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1868
              DEPC = cia;
1869
            }
1870
 
1871
          Debug |= Debug_DM;            /* in debugging mode */
1872
          Debug |= Debug_DBp;           /* raising a DBp exception */
1873
          PC = 0xBFC00200;
1874
          sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1875
        }
1876
      break;
1877
 
1878
    case ReservedInstruction:
1879
     {
1880
       va_list ap;
1881
       unsigned int instruction;
1882
       va_start(ap,exception);
1883
       instruction = va_arg(ap,unsigned int);
1884
       va_end(ap);
1885
       /* Provide simple monitor support using ReservedInstruction
1886
          exceptions. The following code simulates the fixed vector
1887
          entry points into the IDT monitor by causing a simulator
1888
          trap, performing the monitor operation, and returning to
1889
          the address held in the $ra register (standard PCS return
1890
          address). This means we only need to pre-load the vector
1891
          space with suitable instruction values. For systems were
1892
          actual trap instructions are used, we would not need to
1893
          perform this magic. */
1894
       if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1895
         {
1896
           int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK;
1897
           if (!sim_monitor (SD, CPU, cia, reason))
1898
             sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia));
1899
 
1900
           /* NOTE: This assumes that a branch-and-link style
1901
              instruction was used to enter the vector (which is the
1902
              case with the current IDT monitor). */
1903
           sim_engine_restart (SD, CPU, NULL, RA);
1904
         }
1905
       /* Look for the mips16 entry and exit instructions, and
1906
          simulate a handler for them.  */
1907
       else if ((cia & 1) != 0
1908
                && (instruction & 0xf81f) == 0xe809
1909
                && (instruction & 0x0c0) != 0x0c0)
1910
         {
1911
           mips16_entry (SD, CPU, cia, instruction);
1912
           sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1913
         }
1914
       /* else fall through to normal exception processing */
1915
       sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1916
     }
1917
 
1918
    default:
1919
     /* Store exception code into current exception id variable (used
1920
        by exit code): */
1921
 
1922
     /* TODO: If not simulating exceptions then stop the simulator
1923
        execution. At the moment we always stop the simulation. */
1924
 
1925
#ifdef SUBTARGET_R3900
1926
      /* update interrupt-related registers */
1927
 
1928
      /* insert exception code in bits 6:2 */
1929
      CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1930
      /* shift IE/KU history bits left */
1931
      SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1932
 
1933
      if (STATE & simDELAYSLOT)
1934
        {
1935
          STATE &= ~simDELAYSLOT;
1936
          CAUSE |= cause_BD;
1937
          EPC = (cia - 4); /* reference the branch instruction */
1938
        }
1939
      else
1940
        EPC = cia;
1941
 
1942
     if (SR & status_BEV)
1943
       PC = (signed)0xBFC00000 + 0x180;
1944
     else
1945
       PC = (signed)0x80000000 + 0x080;
1946
#else
1947
     /* See figure 5-17 for an outline of the code below */
1948
     if (! (SR & status_EXL))
1949
       {
1950
         CAUSE = (exception << 2);
1951
         if (STATE & simDELAYSLOT)
1952
           {
1953
             STATE &= ~simDELAYSLOT;
1954
             CAUSE |= cause_BD;
1955
             EPC = (cia - 4); /* reference the branch instruction */
1956
           }
1957
         else
1958
           EPC = cia;
1959
         /* FIXME: TLB et.al. */
1960
         /* vector = 0x180; */
1961
       }
1962
     else
1963
       {
1964
         CAUSE = (exception << 2);
1965
         /* vector = 0x180; */
1966
       }
1967
     SR |= status_EXL;
1968
     /* Store exception code into current exception id variable (used
1969
        by exit code): */
1970
 
1971
     if (SR & status_BEV)
1972
       PC = (signed)0xBFC00200 + 0x180;
1973
     else
1974
       PC = (signed)0x80000000 + 0x180;
1975
#endif
1976
 
1977
     switch ((CAUSE >> 2) & 0x1F)
1978
       {
1979
       case Interrupt:
1980
         /* Interrupts arrive during event processing, no need to
1981
            restart */
1982
         return;
1983
 
1984
       case NMIReset:
1985
         /* Ditto */
1986
#ifdef SUBTARGET_3900
1987
         /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000  */
1988
         PC = (signed)0xBFC00000;
1989
#endif /* SUBTARGET_3900 */
1990
         return;
1991
 
1992
       case TLBModification:
1993
       case TLBLoad:
1994
       case TLBStore:
1995
       case AddressLoad:
1996
       case AddressStore:
1997
       case InstructionFetch:
1998
       case DataReference:
1999
         /* The following is so that the simulator will continue from the
2000
            exception handler address. */
2001
         sim_engine_halt (SD, CPU, NULL, PC,
2002
                          sim_stopped, SIM_SIGBUS);
2003
 
2004
       case ReservedInstruction:
2005
       case CoProcessorUnusable:
2006
         PC = EPC;
2007
         sim_engine_halt (SD, CPU, NULL, PC,
2008
                          sim_stopped, SIM_SIGILL);
2009
 
2010
       case IntegerOverflow:
2011
       case FPE:
2012
         sim_engine_halt (SD, CPU, NULL, PC,
2013
                          sim_stopped, SIM_SIGFPE);
2014
 
2015
       case BreakPoint:
2016
         sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
2017
         break;
2018
 
2019
       case SystemCall:
2020
       case Trap:
2021
         sim_engine_restart (SD, CPU, NULL, PC);
2022
         break;
2023
 
2024
       case Watch:
2025
         PC = EPC;
2026
         sim_engine_halt (SD, CPU, NULL, PC,
2027
                          sim_stopped, SIM_SIGTRAP);
2028
 
2029
       default: /* Unknown internal exception */
2030
         PC = EPC;
2031
         sim_engine_halt (SD, CPU, NULL, PC,
2032
                          sim_stopped, SIM_SIGABRT);
2033
 
2034
       }
2035
 
2036
    case SimulatorFault:
2037
     {
2038
       va_list ap;
2039
       char *msg;
2040
       va_start(ap,exception);
2041
       msg = va_arg(ap,char *);
2042
       va_end(ap);
2043
       sim_engine_abort (SD, CPU, NULL_CIA,
2044
                         "FATAL: Simulator error \"%s\"\n",msg);
2045
     }
2046
   }
2047
 
2048
  return;
2049
}
2050
 
2051
 
2052
 
2053
/* This function implements what the MIPS32 and MIPS64 ISAs define as
2054
   "UNPREDICTABLE" behaviour.
2055
 
2056
   About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2057
   may vary from processor implementation to processor implementation,
2058
   instruction to instruction, or as a function of time on the same
2059
   implementation or instruction.  Software can never depend on results
2060
   that are UNPREDICTABLE. ..."  (MIPS64 Architecture for Programmers
2061
   Volume II, The MIPS64 Instruction Set.  MIPS Document MD00087 revision
2062
   0.95, page 2.)
2063
 
2064
   For UNPREDICTABLE behaviour, we print a message, if possible print
2065
   the offending instructions mips.igen instruction name (provided by
2066
   the caller), and stop the simulator.
2067
 
2068
   XXX FIXME: eventually, stopping the simulator should be made conditional
2069
   on a command-line option.  */
2070
void
2071
unpredictable_action(sim_cpu *cpu, address_word cia)
2072
{
2073
  SIM_DESC sd = CPU_STATE(cpu);
2074
 
2075
  sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia));
2076
  sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT);
2077
}
2078
 
2079
 
2080
/*-- co-processor support routines ------------------------------------------*/
2081
 
2082
static int UNUSED
2083
CoProcPresent(unsigned int coproc_number)
2084
{
2085
  /* Return TRUE if simulator provides a model for the given co-processor number */
2086
  return(0);
2087
}
2088
 
2089
void
2090
cop_lw (SIM_DESC sd,
2091
        sim_cpu *cpu,
2092
        address_word cia,
2093
        int coproc_num,
2094
        int coproc_reg,
2095
        unsigned int memword)
2096
{
2097
  switch (coproc_num)
2098
    {
2099
    case 1:
2100
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2101
        {
2102
#ifdef DEBUG
2103
          printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2104
#endif
2105
          StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
2106
          break;
2107
        }
2108
 
2109
    default:
2110
#if 0 /* this should be controlled by a configuration option */
2111
      sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
2112
#endif
2113
      break;
2114
    }
2115
 
2116
  return;
2117
}
2118
 
2119
void
2120
cop_ld (SIM_DESC sd,
2121
        sim_cpu *cpu,
2122
        address_word cia,
2123
        int coproc_num,
2124
        int coproc_reg,
2125
        uword64 memword)
2126
{
2127
 
2128
#ifdef DEBUG
2129
  printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia) );
2130
#endif
2131
 
2132
  switch (coproc_num) {
2133
    case 1:
2134
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2135
        {
2136
          StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
2137
          break;
2138
        }
2139
 
2140
    default:
2141
#if 0 /* this message should be controlled by a configuration option */
2142
     sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
2143
#endif
2144
     break;
2145
  }
2146
 
2147
  return;
2148
}
2149
 
2150
 
2151
 
2152
 
2153
unsigned int
2154
cop_sw (SIM_DESC sd,
2155
        sim_cpu *cpu,
2156
        address_word cia,
2157
        int coproc_num,
2158
        int coproc_reg)
2159
{
2160
  unsigned int value = 0;
2161
 
2162
  switch (coproc_num)
2163
    {
2164
    case 1:
2165
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2166
        {
2167
          value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
2168
          break;
2169
        }
2170
 
2171
    default:
2172
#if 0 /* should be controlled by configuration option */
2173
      sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2174
#endif
2175
      break;
2176
    }
2177
 
2178
  return(value);
2179
}
2180
 
2181
uword64
2182
cop_sd (SIM_DESC sd,
2183
        sim_cpu *cpu,
2184
        address_word cia,
2185
        int coproc_num,
2186
        int coproc_reg)
2187
{
2188
  uword64 value = 0;
2189
  switch (coproc_num)
2190
    {
2191
    case 1:
2192
      if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2193
        {
2194
          value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
2195
          break;
2196
        }
2197
 
2198
    default:
2199
#if 0 /* should be controlled by configuration option */
2200
      sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2201
#endif
2202
      break;
2203
    }
2204
 
2205
  return(value);
2206
}
2207
 
2208
 
2209
 
2210
 
2211
void
2212
decode_coproc (SIM_DESC sd,
2213
               sim_cpu *cpu,
2214
               address_word cia,
2215
               unsigned int instruction)
2216
{
2217
  int coprocnum = ((instruction >> 26) & 3);
2218
 
2219
  switch (coprocnum)
2220
    {
2221
    case 0: /* standard CPU control and cache registers */
2222
      {
2223
        int code = ((instruction >> 21) & 0x1F);
2224
        int rt = ((instruction >> 16) & 0x1F);
2225
        int rd = ((instruction >> 11) & 0x1F);
2226
        int tail = instruction & 0x3ff;
2227
        /* R4000 Users Manual (second edition) lists the following CP0
2228
           instructions:
2229
                                                                   CODE><-RT><RD-><--TAIL--->
2230
           DMFC0   Doubleword Move From CP0        (VR4100 = 01000000001tttttddddd00000000000)
2231
           DMTC0   Doubleword Move To CP0          (VR4100 = 01000000101tttttddddd00000000000)
2232
           MFC0    word Move From CP0              (VR4100 = 01000000000tttttddddd00000000000)
2233
           MTC0    word Move To CP0                (VR4100 = 01000000100tttttddddd00000000000)
2234
           TLBR    Read Indexed TLB Entry          (VR4100 = 01000010000000000000000000000001)
2235
           TLBWI   Write Indexed TLB Entry         (VR4100 = 01000010000000000000000000000010)
2236
           TLBWR   Write Random TLB Entry          (VR4100 = 01000010000000000000000000000110)
2237
           TLBP    Probe TLB for Matching Entry    (VR4100 = 01000010000000000000000000001000)
2238
           CACHE   Cache operation                 (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2239
           ERET    Exception return                (VR4100 = 01000010000000000000000000011000)
2240
           */
2241
        if (((code == 0x00) || (code == 0x04)      /* MFC0  /  MTC0  */
2242
             || (code == 0x01) || (code == 0x05))  /* DMFC0 / DMTC0  */
2243
            && tail == 0)
2244
          {
2245
            /* Clear double/single coprocessor move bit. */
2246
            code &= ~1;
2247
 
2248
            /* M[TF]C0 (32 bits) | DM[TF]C0 (64 bits) */
2249
 
2250
            switch (rd)  /* NOTEs: Standard CP0 registers */
2251
              {
2252
                /* 0 = Index               R4000   VR4100  VR4300 */
2253
                /* 1 = Random              R4000   VR4100  VR4300 */
2254
                /* 2 = EntryLo0            R4000   VR4100  VR4300 */
2255
                /* 3 = EntryLo1            R4000   VR4100  VR4300 */
2256
                /* 4 = Context             R4000   VR4100  VR4300 */
2257
                /* 5 = PageMask            R4000   VR4100  VR4300 */
2258
                /* 6 = Wired               R4000   VR4100  VR4300 */
2259
                /* 8 = BadVAddr            R4000   VR4100  VR4300 */
2260
                /* 9 = Count               R4000   VR4100  VR4300 */
2261
                /* 10 = EntryHi            R4000   VR4100  VR4300 */
2262
                /* 11 = Compare            R4000   VR4100  VR4300 */
2263
                /* 12 = SR                 R4000   VR4100  VR4300 */
2264
#ifdef SUBTARGET_R3900
2265
              case 3:
2266
                /* 3 = Config              R3900                  */
2267
              case 7:
2268
                /* 7 = Cache               R3900                  */
2269
              case 15:
2270
                /* 15 = PRID               R3900                  */
2271
 
2272
                /* ignore */
2273
                break;
2274
 
2275
              case 8:
2276
                /* 8 = BadVAddr            R4000   VR4100  VR4300 */
2277
                if (code == 0x00)
2278
                  GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
2279
                else
2280
                  COP0_BADVADDR = GPR[rt];
2281
                break;
2282
 
2283
#endif /* SUBTARGET_R3900 */
2284
              case 12:
2285
                if (code == 0x00)
2286
                  GPR[rt] = SR;
2287
                else
2288
                  SR = GPR[rt];
2289
                break;
2290
                /* 13 = Cause              R4000   VR4100  VR4300 */
2291
              case 13:
2292
                if (code == 0x00)
2293
                  GPR[rt] = CAUSE;
2294
                else
2295
                  CAUSE = GPR[rt];
2296
                break;
2297
                /* 14 = EPC                R4000   VR4100  VR4300 */
2298
              case 14:
2299
                if (code == 0x00)
2300
                  GPR[rt] = (signed_word) (signed_address) EPC;
2301
                else
2302
                  EPC = GPR[rt];
2303
                break;
2304
                /* 15 = PRId               R4000   VR4100  VR4300 */
2305
#ifdef SUBTARGET_R3900
2306
                /* 16 = Debug */
2307
              case 16:
2308
                if (code == 0x00)
2309
                  GPR[rt] = Debug;
2310
                else
2311
                  Debug = GPR[rt];
2312
                break;
2313
#else
2314
                /* 16 = Config             R4000   VR4100  VR4300 */
2315
              case 16:
2316
                if (code == 0x00)
2317
                  GPR[rt] = C0_CONFIG;
2318
                else
2319
                  /* only bottom three bits are writable */
2320
                  C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7);
2321
                break;
2322
#endif
2323
#ifdef SUBTARGET_R3900
2324
                /* 17 = Debug */
2325
              case 17:
2326
                if (code == 0x00)
2327
                  GPR[rt] = DEPC;
2328
                else
2329
                  DEPC = GPR[rt];
2330
                break;
2331
#else
2332
                /* 17 = LLAddr             R4000   VR4100  VR4300 */
2333
#endif
2334
                /* 18 = WatchLo            R4000   VR4100  VR4300 */
2335
                /* 19 = WatchHi            R4000   VR4100  VR4300 */
2336
                /* 20 = XContext           R4000   VR4100  VR4300 */
2337
                /* 26 = PErr or ECC        R4000   VR4100  VR4300 */
2338
                /* 27 = CacheErr           R4000   VR4100 */
2339
                /* 28 = TagLo              R4000   VR4100  VR4300 */
2340
                /* 29 = TagHi              R4000   VR4100  VR4300 */
2341
                /* 30 = ErrorEPC           R4000   VR4100  VR4300 */
2342
                if (STATE_VERBOSE_P(SD))
2343
                  sim_io_eprintf (SD,
2344
                                  "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2345
                                  (unsigned long)cia);
2346
                GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
2347
                /* CPR[0,rd] = GPR[rt]; */
2348
              default:
2349
                if (code == 0x00)
2350
                  GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
2351
                else
2352
                  COP0_GPR[rd] = GPR[rt];
2353
#if 0
2354
                if (code == 0x00)
2355
                  sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2356
                else
2357
                  sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2358
#endif
2359
              }
2360
          }
2361
        else if ((code == 0x00 || code == 0x01)
2362
                 && rd == 16)
2363
          {
2364
            /* [D]MFC0 RT,C0_CONFIG,SEL */
2365
            signed32 cfg = 0;
2366
            switch (tail & 0x07)
2367
              {
2368
              case 0:
2369
                cfg = C0_CONFIG;
2370
                break;
2371
              case 1:
2372
                /* MIPS32 r/o Config1:
2373
                   Config2 present */
2374
                cfg = 0x80000000;
2375
                /* MIPS16 implemented.
2376
                   XXX How to check configuration? */
2377
                cfg |= 0x0000004;
2378
                if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2379
                  /* MDMX & FPU implemented */
2380
                  cfg |= 0x00000021;
2381
                break;
2382
              case 2:
2383
                /* MIPS32 r/o Config2:
2384
                   Config3 present. */
2385
                cfg = 0x80000000;
2386
                break;
2387
              case 3:
2388
                /* MIPS32 r/o Config3:
2389
                   SmartMIPS implemented. */
2390
                cfg = 0x00000002;
2391
                break;
2392
              }
2393
            GPR[rt] = cfg;
2394
          }
2395
        else if (code == 0x10 && (tail & 0x3f) == 0x18)
2396
          {
2397
            /* ERET */
2398
            if (SR & status_ERL)
2399
              {
2400
                /* Oops, not yet available */
2401
                sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
2402
                PC = EPC;
2403
                SR &= ~status_ERL;
2404
              }
2405
            else
2406
              {
2407
                PC = EPC;
2408
                SR &= ~status_EXL;
2409
              }
2410
          }
2411
        else if (code == 0x10 && (tail & 0x3f) == 0x10)
2412
          {
2413
            /* RFE */
2414
#ifdef SUBTARGET_R3900
2415
            /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2416
 
2417
            /* shift IE/KU history bits right */
2418
            SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
2419
 
2420
            /* TODO: CACHE register */
2421
#endif /* SUBTARGET_R3900 */
2422
          }
2423
        else if (code == 0x10 && (tail & 0x3f) == 0x1F)
2424
          {
2425
            /* DERET */
2426
            Debug &= ~Debug_DM;
2427
            DELAYSLOT();
2428
            DSPC = DEPC;
2429
          }
2430
        else
2431
          sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
2432
        /* TODO: When executing an ERET or RFE instruction we should
2433
           clear LLBIT, to ensure that any out-standing atomic
2434
           read/modify/write sequence fails. */
2435
      }
2436
    break;
2437
 
2438
    case 2: /* co-processor 2 */
2439
      {
2440
        int handle = 0;
2441
 
2442
 
2443
        if(! handle)
2444
          {
2445
            sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2446
                           instruction,pr_addr(cia));
2447
          }
2448
      }
2449
    break;
2450
 
2451
    case 1: /* should not occur (FPU co-processor) */
2452
    case 3: /* should not occur (FPU co-processor) */
2453
      SignalException(ReservedInstruction,instruction);
2454
      break;
2455
    }
2456
 
2457
  return;
2458
}
2459
 
2460
 
2461
/* This code copied from gdb's utils.c.  Would like to share this code,
2462
   but don't know of a common place where both could get to it. */
2463
 
2464
/* Temporary storage using circular buffer */
2465
#define NUMCELLS 16
2466
#define CELLSIZE 32
2467
static char*
2468
get_cell (void)
2469
{
2470
  static char buf[NUMCELLS][CELLSIZE];
2471
  static int cell=0;
2472
  if (++cell>=NUMCELLS) cell=0;
2473
  return buf[cell];
2474
}
2475
 
2476
/* Print routines to handle variable size regs, etc */
2477
 
2478
/* Eliminate warning from compiler on 32-bit systems */
2479
static int thirty_two = 32;
2480
 
2481
char*
2482
pr_addr(addr)
2483
  SIM_ADDR addr;
2484
{
2485
  char *paddr_str=get_cell();
2486
  switch (sizeof(addr))
2487
    {
2488
      case 8:
2489
        sprintf(paddr_str,"%08lx%08lx",
2490
                (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
2491
        break;
2492
      case 4:
2493
        sprintf(paddr_str,"%08lx",(unsigned long)addr);
2494
        break;
2495
      case 2:
2496
        sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
2497
        break;
2498
      default:
2499
        sprintf(paddr_str,"%x",addr);
2500
    }
2501
  return paddr_str;
2502
}
2503
 
2504
char*
2505
pr_uword64(addr)
2506
  uword64 addr;
2507
{
2508
  char *paddr_str=get_cell();
2509
  sprintf(paddr_str,"%08lx%08lx",
2510
          (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
2511
  return paddr_str;
2512
}
2513
 
2514
 
2515
void
2516
mips_core_signal (SIM_DESC sd,
2517
                 sim_cpu *cpu,
2518
                 sim_cia cia,
2519
                 unsigned map,
2520
                 int nr_bytes,
2521
                 address_word addr,
2522
                 transfer_type transfer,
2523
                 sim_core_signals sig)
2524
{
2525
  const char *copy = (transfer == read_transfer ? "read" : "write");
2526
  address_word ip = CIA_ADDR (cia);
2527
 
2528
  switch (sig)
2529
    {
2530
    case sim_core_unmapped_signal:
2531
      sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2532
                      nr_bytes, copy,
2533
                      (unsigned long) addr, (unsigned long) ip);
2534
      COP0_BADVADDR = addr;
2535
      SignalExceptionDataReference();
2536
      break;
2537
 
2538
    case sim_core_unaligned_signal:
2539
      sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
2540
                      nr_bytes, copy,
2541
                      (unsigned long) addr, (unsigned long) ip);
2542
      COP0_BADVADDR = addr;
2543
      if(transfer == read_transfer)
2544
        SignalExceptionAddressLoad();
2545
      else
2546
        SignalExceptionAddressStore();
2547
      break;
2548
 
2549
    default:
2550
      sim_engine_abort (sd, cpu, cia,
2551
                        "mips_core_signal - internal error - bad switch");
2552
    }
2553
}
2554
 
2555
 
2556
void
2557
mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
2558
{
2559
  ASSERT(cpu != NULL);
2560
 
2561
  if(cpu->exc_suspended > 0)
2562
    sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended);
2563
 
2564
  PC = cia;
2565
  memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
2566
  cpu->exc_suspended = 0;
2567
}
2568
 
2569
void
2570
mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
2571
{
2572
  ASSERT(cpu != NULL);
2573
 
2574
  if(cpu->exc_suspended > 0)
2575
    sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
2576
                   cpu->exc_suspended, exception);
2577
 
2578
  memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
2579
  memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
2580
  cpu->exc_suspended = exception;
2581
}
2582
 
2583
void
2584
mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
2585
{
2586
  ASSERT(cpu != NULL);
2587
 
2588
  if(exception == 0 && cpu->exc_suspended > 0)
2589
    {
2590
      /* warn not for breakpoints */
2591
      if(cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
2592
        sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
2593
                       cpu->exc_suspended);
2594
    }
2595
  else if(exception != 0 && cpu->exc_suspended > 0)
2596
    {
2597
      if(exception != cpu->exc_suspended)
2598
        sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2599
                       cpu->exc_suspended, exception);
2600
 
2601
      memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));
2602
    }
2603
  else if(exception != 0 && cpu->exc_suspended == 0)
2604
    {
2605
      sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
2606
    }
2607
  cpu->exc_suspended = 0;
2608
}
2609
 
2610
 
2611
/*---------------------------------------------------------------------------*/
2612
/*> EOF interp.c <*/

powered by: WebSVN 2.1.0

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