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