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