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