1/*> 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
16NOTEs:
17
18The IDT monitor (found on the VR4300 board), seems to lie about
19register contents. It seems to treat the registers as sign-extended
2032-bit values. This cause *REAL* problems when single-stepping 64-bit
21code 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
73char* pr_addr PARAMS ((SIM_ADDR addr));
74char* 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
102static 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.  */
154static int firmware_option_p = 0;
155static SIM_ADDR idt_monitor_base =     0xBFC00000;
156static SIM_ADDR pmon_monitor_base =    0xBFC00500;
157static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
158
159static 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)
166static char *tracefile = "trace.din"; /* default filename for trace log */
167FILE *tracefh = NULL;
168static void open_trace PARAMS((SIM_DESC sd));
169#endif /* TRACE */
170
171static const char * get_insn_name (sim_cpu *, int);
172
173/* simulation target board.  NULL=canonical */
174static char* board = NULL;
175
176
177static DECLARE_OPTION_HANDLER (mips_option_handler);
178
179enum {
180  OPTION_DINERO_TRACE = OPTION_START,
181  OPTION_DINERO_FILE,
182  OPTION_FIRMWARE,
183  OPTION_INFO_MEMORY,
184  OPTION_BOARD
185};
186
187static int display_mem_info = 0;
188
189static SIM_RC
190mips_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,"\
228Simulator constructed without dinero tracing support (for performance).\n\
229Re-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
274static 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
317int interrupt_pending;
318
319void
320interrupt_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/*---------------------------------------------------------------------------*/
337static 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
348SIM_DESC
349sim_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)
812static void
813open_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.  */
826static const char *
827get_insn_name (sim_cpu *cpu, int i)
828{
829  return itable[i].name;
830}
831
832void
833sim_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
863int
864sim_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
895int
896sim_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
924int
925sim_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
1013int
1014sim_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
1102SIM_RC
1103sim_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
1147void
1148sim_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 */
1162static char *
1163fetch_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.  */
1183static SIM_RC
1184sim_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, "\
1253Unrecognized name given to the `sim firmware NAME' command: %s\n\
1254Recognized 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) */
1265int
1266sim_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
1538static void
1539store_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
1570static signed_word
1571load_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
1609static void
1610mips16_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	0       read data
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
1737void
1738dotrace (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
1779static void
1780ColdReset (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
1835void
1836signal_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.  */
2072void
2073unpredictable_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
2084static int UNUSED
2085CoProcPresent(unsigned int coproc_number)
2086{
2087  /* Return TRUE if simulator provides a model for the given co-processor number */
2088  return(0);
2089}
2090
2091void
2092cop_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
2121void
2122cop_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
2155unsigned int
2156cop_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
2183uword64
2184cop_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
2213void
2214decode_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
2469static char*
2470get_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 */
2481static int thirty_two = 32;
2482
2483char*
2484pr_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
2506char*
2507pr_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
2517void
2518mips_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
2558void
2559mips_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
2571void
2572mips_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
2585void
2586mips_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 <*/
2615