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