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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [gdb-5.3/] [sim/] [mips/] [interp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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