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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gdb-6.8/] [sim/] [mips/] [interp.c] - Blame information for rev 438

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

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

powered by: WebSVN 2.1.0

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