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