2 /* Simulator for the MIPS architecture.
4 This file is part of the MIPS sim
6 THIS SOFTWARE IS NOT COPYRIGHTED
8 Cygnus offers the following for use in the public domain. Cygnus
9 makes no warranty with regard to the software or it's performance
10 and the user accepts the software "AS IS" with all faults.
12 CYGNUS DISCLAIMS ANY WARRANTIES, EXPRESS OR IMPLIED, WITH REGARD TO
13 THIS SOFTWARE INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 The IDT monitor (found on the VR4300 board), seems to lie about
19 register contents. It seems to treat the registers as sign-extended
20 32-bit values. This cause *REAL* problems when single-stepping 64-bit
25 /* This must come before any other includes. */
30 #include "sim-utils.h"
31 #include "sim-options.h"
32 #include "sim-assert.h"
47 #include "libiberty.h"
50 #include "sim/callback.h" /* GDB simulator callback interface */
51 #include "sim/sim.h" /* GDB simulator interface */
52 #include "sim-syscall.h" /* Simulator system call support */
54 char* pr_addr (SIM_ADDR addr
);
55 char* pr_uword64 (uword64 addr
);
58 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
63 /* The following reserved instruction value is used when a simulator
64 trap is required. NOTE: Care must be taken, since this value may be
65 used in later revisions of the MIPS ISA. */
67 #define RSVD_INSTRUCTION (0x00000039)
68 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
70 #define RSVD_INSTRUCTION_ARG_SHIFT 6
71 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
74 /* Bits in the Debug register */
75 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
76 #define Debug_DM 0x40000000 /* Debug Mode */
77 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
79 /*---------------------------------------------------------------------------*/
80 /*-- GDB simulator interface ------------------------------------------------*/
81 /*---------------------------------------------------------------------------*/
83 static void ColdReset (SIM_DESC sd
);
85 /*---------------------------------------------------------------------------*/
89 #define DELAYSLOT() {\
90 if (STATE & simDELAYSLOT)\
91 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
92 STATE |= simDELAYSLOT;\
95 #define JALDELAYSLOT() {\
97 STATE |= simJALDELAYSLOT;\
101 STATE &= ~simDELAYSLOT;\
102 STATE |= simSKIPNEXT;\
105 #define CANCELDELAYSLOT() {\
107 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
110 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
111 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
113 /* Note that the monitor code essentially assumes this layout of memory.
114 If you change these, change the monitor code, too. */
115 /* FIXME Currently addresses are truncated to 32-bits, see
116 mips/sim-main.c:address_translation(). If that changes, then these
117 values will need to be extended, and tested for more carefully. */
118 #define K0BASE (0x80000000)
119 #define K0SIZE (0x20000000)
120 #define K1BASE (0xA0000000)
121 #define K1SIZE (0x20000000)
123 /* Simple run-time monitor support.
125 We emulate the monitor by placing magic reserved instructions at
126 the monitor's entry points; when we hit these instructions, instead
127 of raising an exception (as we would normally), we look at the
128 instruction and perform the appropriate monitory operation.
130 `*_monitor_base' are the physical addresses at which the corresponding
131 monitor vectors are located. `0' means none. By default,
133 The RSVD_INSTRUCTION... macros specify the magic instructions we
134 use at the monitor entry points. */
135 static int firmware_option_p
= 0;
136 static SIM_ADDR idt_monitor_base
= 0xBFC00000;
137 static SIM_ADDR pmon_monitor_base
= 0xBFC00500;
138 static SIM_ADDR lsipmon_monitor_base
= 0xBFC00200;
140 static SIM_RC
sim_firmware_command (SIM_DESC sd
, char* arg
);
142 #define MEM_SIZE (8 << 20) /* 8 MBytes */
146 static char *tracefile
= "trace.din"; /* default filename for trace log */
147 FILE *tracefh
= NULL
;
148 static void open_trace (SIM_DESC sd
);
150 #define open_trace(sd)
153 static const char * get_insn_name (sim_cpu
*, int);
155 /* simulation target board. NULL=canonical */
156 static char* board
= NULL
;
159 static DECLARE_OPTION_HANDLER (mips_option_handler
);
162 OPTION_DINERO_TRACE
= OPTION_START
,
169 static int display_mem_info
= 0;
172 mips_option_handler (SIM_DESC sd
, sim_cpu
*cpu
, int opt
, char *arg
,
178 case OPTION_DINERO_TRACE
: /* ??? */
180 /* Eventually the simTRACE flag could be treated as a toggle, to
181 allow external control of the program points being traced
182 (i.e. only from main onwards, excluding the run-time setup,
184 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
186 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
189 else if (strcmp (arg
, "yes") == 0)
191 else if (strcmp (arg
, "no") == 0)
193 else if (strcmp (arg
, "on") == 0)
195 else if (strcmp (arg
, "off") == 0)
199 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
204 #else /* !WITH_TRACE_ANY_P */
206 Simulator constructed without dinero tracing support (for performance).\n\
207 Re-compile simulator with \"-DWITH_TRACE_ANY_P\" to enable this option.\n");
209 #endif /* !WITH_TRACE_ANY_P */
211 case OPTION_DINERO_FILE
:
213 if (optarg
!= NULL
) {
215 tmp
= (char *)malloc(strlen(optarg
) + 1);
218 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
224 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
227 #endif /* WITH_TRACE_ANY_P */
230 case OPTION_FIRMWARE
:
231 return sim_firmware_command (sd
, arg
);
237 board
= zalloc(strlen(arg
) + 1);
243 case OPTION_INFO_MEMORY
:
244 display_mem_info
= 1;
252 static const OPTION mips_options
[] =
254 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
255 '\0', "on|off", "Enable dinero tracing",
256 mips_option_handler
},
257 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
258 '\0', "FILE", "Write dinero trace to FILE",
259 mips_option_handler
},
260 { {"firmware", required_argument
, NULL
, OPTION_FIRMWARE
},
261 '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
262 mips_option_handler
},
263 { {"board", required_argument
, NULL
, OPTION_BOARD
},
264 '\0', "none" /* rely on compile-time string concatenation for other options */
266 #define BOARD_JMR3904 "jmr3904"
268 #define BOARD_JMR3904_PAL "jmr3904pal"
269 "|" BOARD_JMR3904_PAL
270 #define BOARD_JMR3904_DEBUG "jmr3904debug"
271 "|" BOARD_JMR3904_DEBUG
272 #define BOARD_BSP "bsp"
275 , "Customize simulation for a particular board.", mips_option_handler
},
277 /* These next two options have the same names as ones found in the
278 memory_options[] array in common/sim-memopt.c. This is because
279 the intention is to provide an alternative handler for those two
280 options. We need an alternative handler because the memory
281 regions are not set up until after the command line arguments
282 have been parsed, and so we cannot display the memory info whilst
283 processing the command line. There is a hack in sim_open to
284 remove these handlers when we want the real --memory-info option
286 { { "info-memory", no_argument
, NULL
, OPTION_INFO_MEMORY
},
287 '\0', NULL
, "List configured memory regions", mips_option_handler
},
288 { { "memory-info", no_argument
, NULL
, OPTION_INFO_MEMORY
},
289 '\0', NULL
, NULL
, mips_option_handler
},
291 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
295 int interrupt_pending
;
298 interrupt_event (SIM_DESC sd
, void *data
)
300 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
301 address_word cia
= CPU_PC_GET (cpu
);
304 interrupt_pending
= 0;
305 SignalExceptionInterrupt (1); /* interrupt "1" */
307 else if (!interrupt_pending
)
308 sim_events_schedule (sd
, 1, interrupt_event
, data
);
312 /*---------------------------------------------------------------------------*/
313 /*-- Device registration hook -----------------------------------------------*/
314 /*---------------------------------------------------------------------------*/
315 static void device_init(SIM_DESC sd
) {
317 extern void register_devices(SIM_DESC
);
318 register_devices(sd
);
322 /*---------------------------------------------------------------------------*/
323 /*-- GDB simulator interface ------------------------------------------------*/
324 /*---------------------------------------------------------------------------*/
327 mips_pc_get (sim_cpu
*cpu
)
333 mips_pc_set (sim_cpu
*cpu
, sim_cia pc
)
338 static int mips_reg_fetch (SIM_CPU
*, int, unsigned char *, int);
339 static int mips_reg_store (SIM_CPU
*, int, unsigned char *, int);
342 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
,
343 struct bfd
*abfd
, char * const *argv
)
346 SIM_DESC sd
= sim_state_alloc_extra (kind
, cb
,
347 sizeof (struct mips_sim_state
));
350 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
352 /* The cpu data is kept in a separately allocated chunk of memory. */
353 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
356 cpu
= STATE_CPU (sd
, 0); /* FIXME */
358 /* FIXME: watchpoints code shouldn't need this */
359 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
361 /* Initialize the mechanism for doing insn profiling. */
362 CPU_INSN_NAME (cpu
) = get_insn_name
;
363 CPU_MAX_INSNS (cpu
) = nr_itable_entries
;
367 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
369 sim_add_option_table (sd
, NULL
, mips_options
);
372 /* The parser will print an error message for us, so we silently return. */
373 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
375 /* Uninstall the modules to avoid memory leaks,
376 file descriptor leaks, etc. */
377 sim_module_uninstall (sd
);
381 /* handle board-specific memory maps */
384 /* Allocate core managed memory */
385 sim_memopt
*entry
, *match
= NULL
;
386 address_word mem_size
= 0;
389 /* For compatibility with the old code - under this (at level one)
390 are the kernel spaces K0 & K1. Both of these map to a single
391 smaller sub region */
392 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
394 /* Look for largest memory region defined on command-line at
396 for (entry
= STATE_MEMOPT (sd
); entry
!= NULL
; entry
= entry
->next
)
398 /* If we find an entry at address 0, then we will end up
399 allocating a new buffer in the "memory alias" command
400 below. The region at address 0 will be deleted. */
401 address_word size
= (entry
->modulo
!= 0
402 ? entry
->modulo
: entry
->nr_bytes
);
404 && (!match
|| entry
->level
< match
->level
))
406 else if (entry
->addr
== K0BASE
|| entry
->addr
== K1BASE
)
411 for (alias
= entry
->alias
; alias
!= NULL
; alias
= alias
->next
)
414 && (!match
|| entry
->level
< match
->level
))
416 else if (alias
->addr
== K0BASE
|| alias
->addr
== K1BASE
)
426 /* Get existing memory region size. */
427 mem_size
= (match
->modulo
!= 0
428 ? match
->modulo
: match
->nr_bytes
);
429 /* Delete old region. */
430 sim_do_commandf (sd
, "memory delete %d:0x%lx@%d",
431 match
->space
, match
->addr
, match
->level
);
433 else if (mem_size
== 0)
435 /* Limit to KSEG1 size (512MB) */
436 if (mem_size
> K1SIZE
)
438 /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
439 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
440 K1BASE
, K1SIZE
, (long)mem_size
, K0BASE
);
441 if (WITH_TARGET_WORD_BITSIZE
== 64)
442 sim_do_commandf (sd
, "memory alias 0x%x,0x%" PRIxTW
",0x%" PRIxTA
,
443 (K0BASE
), mem_size
, EXTENDED(K0BASE
));
448 else if (board
!= NULL
449 && (strcmp(board
, BOARD_BSP
) == 0))
453 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
455 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
456 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
458 4 * 1024 * 1024, /* 4 MB */
461 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
462 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
464 4 * 1024 * 1024, /* 4 MB */
467 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
468 for (i
=0; i
<8; i
++) /* 32 MB total */
470 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
471 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
472 0x88000000 + (i
* size
),
474 0xA8000000 + (i
* size
));
478 else if (board
!= NULL
479 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
480 strcmp(board
, BOARD_JMR3904_PAL
) == 0 ||
481 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
483 /* match VIRTUAL memory layout of JMR-TX3904 board */
486 /* --- disable monitor unless forced on by user --- */
488 if (! firmware_option_p
)
490 idt_monitor_base
= 0;
491 pmon_monitor_base
= 0;
492 lsipmon_monitor_base
= 0;
495 /* --- environment --- */
497 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
501 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
502 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
504 4 * 1024 * 1024, /* 4 MB */
507 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
508 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
510 4 * 1024 * 1024, /* 4 MB */
513 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
514 for (i
=0; i
<8; i
++) /* 32 MB total */
516 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
517 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
518 0x88000000 + (i
* size
),
520 0xA8000000 + (i
* size
));
523 /* Dummy memory regions for unsimulated devices - sorted by address */
525 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
526 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
527 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
528 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
529 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
530 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
531 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
532 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
533 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
536 /* --- simulated devices --- */
537 sim_hw_parse (sd
, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
538 sim_hw_parse (sd
, "/tx3904cpu");
539 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
540 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
541 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
542 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
544 /* FIXME: poking at dv-sockser internals, use tcp backend if
545 --sockser_addr option was given.*/
546 #ifdef HAVE_DV_SOCKSER
547 extern char* sockser_addr
;
549 # define sockser_addr NULL
551 if (sockser_addr
== NULL
)
552 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend stdio");
554 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend tcp");
556 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
557 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/backend stdio");
559 /* -- device connections --- */
560 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
561 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
562 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
563 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
564 sim_hw_parse (sd
, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
565 sim_hw_parse (sd
, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
567 /* add PAL timer & I/O module */
568 if(! strcmp(board
, BOARD_JMR3904_PAL
))
571 sim_hw_parse (sd
, "/pal@0xffff0000");
572 sim_hw_parse (sd
, "/pal@0xffff0000/reg 0xffff0000 64");
574 /* wire up interrupt ports to irc */
575 sim_hw_parse (sd
, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
576 sim_hw_parse (sd
, "/pal@0x31000000 > timer tmr1 /tx3904irc");
577 sim_hw_parse (sd
, "/pal@0x31000000 > int int0 /tx3904irc");
580 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
582 /* -- DEBUG: glue interrupt generators --- */
583 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
584 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
585 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
586 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
587 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
588 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
589 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
590 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
591 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
592 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
593 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
594 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
595 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
596 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
597 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
598 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
599 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
600 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
601 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
608 if (display_mem_info
)
610 struct option_list
* ol
;
611 struct option_list
* prev
;
613 /* This is a hack. We want to execute the real --memory-info command
614 line switch which is handled in common/sim-memopts.c, not the
615 override we have defined in this file. So we remove the
616 mips_options array from the state options list. This is safe
617 because we have now processed all of the command line. */
618 for (ol
= STATE_OPTIONS (sd
), prev
= NULL
;
620 prev
= ol
, ol
= ol
->next
)
621 if (ol
->options
== mips_options
)
624 SIM_ASSERT (ol
!= NULL
);
627 STATE_OPTIONS (sd
) = ol
->next
;
629 prev
->next
= ol
->next
;
631 sim_do_commandf (sd
, "memory-info");
634 /* check for/establish the a reference program image */
635 if (sim_analyze_program (sd
,
636 (STATE_PROG_ARGV (sd
) != NULL
637 ? *STATE_PROG_ARGV (sd
)
641 sim_module_uninstall (sd
);
645 /* Configure/verify the target byte order and other runtime
646 configuration options */
647 if (sim_config (sd
) != SIM_RC_OK
)
649 sim_module_uninstall (sd
);
653 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
655 /* Uninstall the modules to avoid memory leaks,
656 file descriptor leaks, etc. */
657 sim_module_uninstall (sd
);
661 /* verify assumptions the simulator made about the host type system.
662 This macro does not return if there is a problem */
663 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
664 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
666 /* This is NASTY, in that we are assuming the size of specific
670 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
673 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
674 else if ((rn
>= FGR_BASE
) && (rn
< (FGR_BASE
+ NR_FGR
)))
675 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
676 else if ((rn
>= 33) && (rn
<= 37))
677 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
678 else if ((rn
== SRIDX
)
681 || ((rn
>= 72) && (rn
<= 89)))
682 cpu
->register_widths
[rn
] = 32;
684 cpu
->register_widths
[rn
] = 0;
690 if (STATE
& simTRACE
)
694 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
697 lsipmon_monitor_base);
700 /* Write the monitor trap address handlers into the monitor (eeprom)
701 address space. This can only be done once the target endianness
702 has been determined. */
703 if (idt_monitor_base
!= 0)
706 address_word idt_monitor_size
= 1 << 11;
708 /* the default monitor region */
709 if (WITH_TARGET_WORD_BITSIZE
== 64)
710 sim_do_commandf (sd
, "memory alias 0x%x,0x%" PRIxTW
",0x%" PRIxTA
,
711 idt_monitor_base
, idt_monitor_size
,
712 EXTENDED (idt_monitor_base
));
714 sim_do_commandf (sd
, "memory region 0x%x,0x%x",
715 idt_monitor_base
, idt_monitor_size
);
717 /* Entry into the IDT monitor is via fixed address vectors, and
718 not using machine instructions. To avoid clashing with use of
719 the MIPS TRAP system, we place our own (simulator specific)
720 "undefined" instructions into the relevant vector slots. */
721 for (loop
= 0; (loop
< idt_monitor_size
); loop
+= 4)
723 address_word vaddr
= (idt_monitor_base
+ loop
);
724 unsigned32 insn
= (RSVD_INSTRUCTION
|
725 (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
)
726 << RSVD_INSTRUCTION_ARG_SHIFT
));
728 sim_write (sd
, vaddr
, (unsigned char *)&insn
, sizeof (insn
));
732 if ((pmon_monitor_base
!= 0) || (lsipmon_monitor_base
!= 0))
734 /* The PMON monitor uses the same address space, but rather than
735 branching into it the address of a routine is loaded. We can
736 cheat for the moment, and direct the PMON routine to IDT style
737 instructions within the monitor space. This relies on the IDT
738 monitor not using the locations from 0xBFC00500 onwards as its
741 for (loop
= 0; (loop
< 24); loop
++)
743 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
759 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
761 case 8: /* cliexit */
764 case 11: /* flush_cache */
769 SIM_ASSERT (idt_monitor_base
!= 0);
770 value
= ((unsigned int) idt_monitor_base
+ (value
* 8));
773 if (pmon_monitor_base
!= 0)
775 address_word vaddr
= (pmon_monitor_base
+ (loop
* 4));
776 sim_write (sd
, vaddr
, (unsigned char *)&value
, sizeof (value
));
779 if (lsipmon_monitor_base
!= 0)
781 address_word vaddr
= (lsipmon_monitor_base
+ (loop
* 4));
782 sim_write (sd
, vaddr
, (unsigned char *)&value
, sizeof (value
));
786 /* Write an abort sequence into the TRAP (common) exception vector
787 addresses. This is to catch code executing a TRAP (et.al.)
788 instruction without installing a trap handler. */
789 if ((idt_monitor_base
!= 0) ||
790 (pmon_monitor_base
!= 0) ||
791 (lsipmon_monitor_base
!= 0))
793 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
794 HALT_INSTRUCTION
/* BREAK */ };
797 sim_write (sd
, 0x80000000, (unsigned char *) halt
, sizeof (halt
));
798 sim_write (sd
, 0x80000180, (unsigned char *) halt
, sizeof (halt
));
799 sim_write (sd
, 0x80000200, (unsigned char *) halt
, sizeof (halt
));
800 /* XXX: Write here unconditionally? */
801 sim_write (sd
, 0xBFC00200, (unsigned char *) halt
, sizeof (halt
));
802 sim_write (sd
, 0xBFC00380, (unsigned char *) halt
, sizeof (halt
));
803 sim_write (sd
, 0xBFC00400, (unsigned char *) halt
, sizeof (halt
));
807 /* CPU specific initialization. */
808 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
810 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
812 CPU_REG_FETCH (cpu
) = mips_reg_fetch
;
813 CPU_REG_STORE (cpu
) = mips_reg_store
;
814 CPU_PC_FETCH (cpu
) = mips_pc_get
;
815 CPU_PC_STORE (cpu
) = mips_pc_set
;
823 open_trace (SIM_DESC sd
)
825 tracefh
= fopen(tracefile
,"wb+");
828 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
834 /* Return name of an insn, used by insn profiling. */
836 get_insn_name (sim_cpu
*cpu
, int i
)
838 return itable
[i
].name
;
842 mips_sim_close (SIM_DESC sd
, int quitting
)
845 if (tracefh
!= NULL
&& tracefh
!= stderr
)
852 mips_reg_store (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
854 /* NOTE: gdb (the client) stores registers in target byte order
855 while the simulator uses host byte order */
857 /* Unfortunately this suffers from the same problem as the register
858 numbering one. We need to know what the width of each logical
859 register number is for the architecture being simulated. */
861 if (cpu
->register_widths
[rn
] == 0)
863 sim_io_eprintf (CPU_STATE (cpu
), "Invalid register width for %d (register store ignored)\n", rn
);
867 if (rn
>= FGR_BASE
&& rn
< FGR_BASE
+ NR_FGR
)
869 cpu
->fpr_state
[rn
- FGR_BASE
] = fmt_uninterpreted
;
870 if (cpu
->register_widths
[rn
] == 32)
874 cpu
->fgr
[rn
- FGR_BASE
] =
875 (unsigned32
) T2H_8 (*(unsigned64
*)memory
);
880 cpu
->fgr
[rn
- FGR_BASE
] = T2H_4 (*(unsigned32
*)memory
);
888 cpu
->fgr
[rn
- FGR_BASE
] = T2H_8 (*(unsigned64
*)memory
);
893 cpu
->fgr
[rn
- FGR_BASE
] = T2H_4 (*(unsigned32
*)memory
);
899 if (cpu
->register_widths
[rn
] == 32)
904 (unsigned32
) T2H_8 (*(unsigned64
*)memory
);
909 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
917 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
922 cpu
->registers
[rn
] = (signed32
) T2H_4(*(unsigned32
*)memory
);
931 mips_reg_fetch (SIM_CPU
*cpu
, int rn
, unsigned char *memory
, int length
)
933 /* NOTE: gdb (the client) stores registers in target byte order
934 while the simulator uses host byte order */
936 if (cpu
->register_widths
[rn
] == 0)
938 sim_io_eprintf (CPU_STATE (cpu
), "Invalid register width for %d (register fetch ignored)\n", rn
);
942 /* Any floating point register */
943 if (rn
>= FGR_BASE
&& rn
< FGR_BASE
+ NR_FGR
)
945 if (cpu
->register_widths
[rn
] == 32)
949 *(unsigned64
*)memory
=
950 H2T_8 ((unsigned32
) (cpu
->fgr
[rn
- FGR_BASE
]));
955 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGR_BASE
]);
963 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGR_BASE
]);
968 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->fgr
[rn
- FGR_BASE
]));
974 if (cpu
->register_widths
[rn
] == 32)
978 *(unsigned64
*)memory
=
979 H2T_8 ((unsigned32
) (cpu
->registers
[rn
]));
984 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
992 *(unsigned64
*)memory
=
993 H2T_8 ((unsigned64
) (cpu
->registers
[rn
]));
998 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1007 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1008 char * const *argv
, char * const *env
)
1012 #if 0 /* FIXME: doesn't compile */
1013 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1022 /* override PC value set by ColdReset () */
1024 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1026 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1027 sim_cia pc
= bfd_get_start_address (abfd
);
1029 /* The 64-bit BFD sign-extends MIPS addresses to model
1030 32-bit compatibility segments with 64-bit addressing.
1031 These addresses work as is on 64-bit targets but
1032 can be truncated for 32-bit targets. */
1033 if (WITH_TARGET_WORD_BITSIZE
== 32)
1034 pc
= (unsigned32
) pc
;
1036 CPU_PC_SET (cpu
, pc
);
1040 #if 0 /* def DEBUG */
1043 /* We should really place the argv slot values into the argument
1044 registers, and onto the stack as required. However, this
1045 assumes that we have a stack defined, which is not
1046 necessarily true at the moment. */
1048 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1049 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1050 printf("DBG: arg \"%s\"\n",*cptr
);
1057 /*---------------------------------------------------------------------------*/
1058 /*-- Private simulator support interface ------------------------------------*/
1059 /*---------------------------------------------------------------------------*/
1061 /* Read a null terminated string from memory, return in a buffer */
1063 fetch_str (SIM_DESC sd
,
1069 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1071 buf
= NZALLOC (char, nr
+ 1);
1072 sim_read (sd
, addr
, (unsigned char *)buf
, nr
);
1077 /* Implements the "sim firmware" command:
1078 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1079 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1080 defaults to the normal address for that monitor.
1081 sim firmware none --- don't emulate any ROM monitor. Useful
1082 if you need a clean address space. */
1084 sim_firmware_command (SIM_DESC sd
, char *arg
)
1086 int address_present
= 0;
1089 /* Signal occurrence of this option. */
1090 firmware_option_p
= 1;
1092 /* Parse out the address, if present. */
1094 char *p
= strchr (arg
, '@');
1098 address_present
= 1;
1099 p
++; /* skip over @ */
1101 address
= strtoul (p
, &q
, 0);
1104 sim_io_printf (sd
, "Invalid address given to the"
1105 "`sim firmware NAME@ADDRESS' command: %s\n",
1112 address_present
= 0;
1113 address
= -1; /* Dummy value. */
1117 if (! strncmp (arg
, "idt", 3))
1119 idt_monitor_base
= address_present
? address
: 0xBFC00000;
1120 pmon_monitor_base
= 0;
1121 lsipmon_monitor_base
= 0;
1123 else if (! strncmp (arg
, "pmon", 4))
1125 /* pmon uses indirect calls. Hook into implied idt. */
1126 pmon_monitor_base
= address_present
? address
: 0xBFC00500;
1127 idt_monitor_base
= pmon_monitor_base
- 0x500;
1128 lsipmon_monitor_base
= 0;
1130 else if (! strncmp (arg
, "lsipmon", 7))
1132 /* lsipmon uses indirect calls. Hook into implied idt. */
1133 pmon_monitor_base
= 0;
1134 lsipmon_monitor_base
= address_present
? address
: 0xBFC00200;
1135 idt_monitor_base
= lsipmon_monitor_base
- 0x200;
1137 else if (! strncmp (arg
, "none", 4))
1139 if (address_present
)
1142 "The `sim firmware none' command does "
1143 "not take an `ADDRESS' argument.\n");
1146 idt_monitor_base
= 0;
1147 pmon_monitor_base
= 0;
1148 lsipmon_monitor_base
= 0;
1152 sim_io_printf (sd
, "\
1153 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1154 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1162 /* stat structures from MIPS32/64. */
1163 static const char stat32_map
[] =
1164 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1165 ":st_rdev,2:st_size,4:st_atime,4:st_spare1,4:st_mtime,4:st_spare2,4"
1166 ":st_ctime,4:st_spare3,4:st_blksize,4:st_blocks,4:st_spare4,8";
1168 static const char stat64_map
[] =
1169 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1170 ":st_rdev,2:st_size,8:st_atime,8:st_spare1,8:st_mtime,8:st_spare2,8"
1171 ":st_ctime,8:st_spare3,8:st_blksize,8:st_blocks,8:st_spare4,16";
1173 /* Map for calls using the host struct stat. */
1174 static const CB_TARGET_DEFS_MAP CB_stat_map
[] =
1176 { "stat", CB_SYS_stat
, 15 },
1181 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1183 sim_monitor (SIM_DESC sd
,
1186 unsigned int reason
)
1189 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1192 /* The IDT monitor actually allows two instructions per vector
1193 slot. However, the simulator currently causes a trap on each
1194 individual instruction. We cheat, and lose the bottom bit. */
1197 /* The following callback functions are available, however the
1198 monitor we are simulating does not make use of them: get_errno,
1199 isatty, rename, system and time. */
1203 case 6: /* int open(char *path,int flags) */
1205 char *path
= fetch_str (sd
, A0
);
1206 V0
= sim_io_open (sd
, path
, (int)A1
);
1211 case 7: /* int read(int file,char *ptr,int len) */
1215 char *buf
= zalloc (nr
);
1216 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1217 sim_write (sd
, A1
, (unsigned char *)buf
, nr
);
1222 case 8: /* int write(int file,char *ptr,int len) */
1226 char *buf
= zalloc (nr
);
1227 sim_read (sd
, A1
, (unsigned char *)buf
, nr
);
1228 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1230 sim_io_flush_stdout (sd
);
1232 sim_io_flush_stderr (sd
);
1237 case 10: /* int close(int file) */
1239 V0
= sim_io_close (sd
, (int)A0
);
1243 case 2: /* Densan monitor: char inbyte(int waitflag) */
1245 if (A0
== 0) /* waitflag == NOWAIT */
1246 V0
= (unsigned_word
)-1;
1248 /* Drop through to case 11 */
1250 case 11: /* char inbyte(void) */
1253 /* ensure that all output has gone... */
1254 sim_io_flush_stdout (sd
);
1255 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1257 sim_io_error(sd
,"Invalid return from character read");
1258 V0
= (unsigned_word
)-1;
1261 V0
= (unsigned_word
)tmp
;
1265 case 3: /* Densan monitor: void co(char chr) */
1266 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1268 char tmp
= (char)(A0
& 0xFF);
1269 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1273 case 13: /* int unlink(const char *path) */
1275 char *path
= fetch_str (sd
, A0
);
1276 V0
= sim_io_unlink (sd
, path
);
1281 case 14: /* int lseek(int fd, int offset, int whence) */
1283 V0
= sim_io_lseek (sd
, A0
, A1
, A2
);
1287 case 15: /* int stat(const char *path, struct stat *buf); */
1289 /* As long as the infrastructure doesn't cache anything
1290 related to the stat mapping, this trick gets us a dual
1291 "struct stat"-type mapping in the least error-prone way. */
1292 host_callback
*cb
= STATE_CALLBACK (sd
);
1293 const char *saved_map
= cb
->stat_map
;
1294 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
1295 bfd
*prog_bfd
= STATE_PROG_BFD (sd
);
1296 int is_elf32bit
= (elf_elfheader(prog_bfd
)->e_ident
[EI_CLASS
] ==
1298 static CB_SYSCALL s
;
1299 CB_SYSCALL_INIT (&s
);
1301 /* Mask out the sign extension part for 64-bit targets because the
1302 MIPS simulator's memory model is still 32-bit. */
1303 s
.arg1
= A0
& 0xFFFFFFFF;
1304 s
.arg2
= A1
& 0xFFFFFFFF;
1307 s
.read_mem
= sim_syscall_read_mem
;
1308 s
.write_mem
= sim_syscall_write_mem
;
1310 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) CB_stat_map
;
1311 cb
->stat_map
= is_elf32bit
? stat32_map
: stat64_map
;
1313 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1314 sim_engine_halt (sd
, cpu
, NULL
, mips_pc_get (cpu
),
1315 sim_stopped
, SIM_SIGILL
);
1318 cb
->stat_map
= saved_map
;
1319 cb
->syscall_map
= saved_syscall_map
;
1323 case 17: /* void _exit() */
1325 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1326 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1327 (unsigned int)(A0
& 0xFFFFFFFF));
1331 case 28: /* PMON flush_cache */
1334 case 55: /* void get_mem_info(unsigned int *ptr) */
1335 /* in: A0 = pointer to three word memory location */
1336 /* out: [A0 + 0] = size */
1337 /* [A0 + 4] = instruction cache size */
1338 /* [A0 + 8] = data cache size */
1341 unsigned_4 zero
= 0;
1342 address_word mem_size
;
1343 sim_memopt
*entry
, *match
= NULL
;
1345 /* Search for memory region mapped to KSEG0 or KSEG1. */
1346 for (entry
= STATE_MEMOPT (sd
);
1348 entry
= entry
->next
)
1350 if ((entry
->addr
== K0BASE
|| entry
->addr
== K1BASE
)
1351 && (!match
|| entry
->level
< match
->level
))
1356 for (alias
= entry
->alias
;
1358 alias
= alias
->next
)
1359 if ((alias
->addr
== K0BASE
|| alias
->addr
== K1BASE
)
1360 && (!match
|| entry
->level
< match
->level
))
1365 /* Get region size, limit to KSEG1 size (512MB). */
1366 SIM_ASSERT (match
!= NULL
);
1367 mem_size
= (match
->modulo
!= 0
1368 ? match
->modulo
: match
->nr_bytes
);
1369 if (mem_size
> K1SIZE
)
1374 sim_write (sd
, A0
+ 0, (unsigned char *)&value
, 4);
1375 sim_write (sd
, A0
+ 4, (unsigned char *)&zero
, 4);
1376 sim_write (sd
, A0
+ 8, (unsigned char *)&zero
, 4);
1377 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1381 case 158: /* PMON printf */
1382 /* in: A0 = pointer to format string */
1383 /* A1 = optional argument 1 */
1384 /* A2 = optional argument 2 */
1385 /* A3 = optional argument 3 */
1387 /* The following is based on the PMON printf source */
1389 address_word s
= A0
;
1391 signed_word
*ap
= &A1
; /* 1st argument */
1392 /* This isn't the quickest way, since we call the host print
1393 routine for every character almost. But it does avoid
1394 having to allocate and manage a temporary string buffer. */
1395 /* TODO: Include check that we only use three arguments (A1,
1397 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1402 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1403 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1404 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1406 if (strchr ("dobxXulscefg%", c
))
1421 else if (c
>= '1' && c
<= '9')
1425 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1428 n
= (unsigned int)strtol(tmp
,NULL
,10);
1441 sim_io_printf (sd
, "%%");
1446 address_word p
= *ap
++;
1448 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1449 sim_io_printf(sd
, "%c", ch
);
1452 sim_io_printf(sd
,"(null)");
1455 sim_io_printf (sd
, "%c", (int)*ap
++);
1460 sim_read (sd
, s
++, &c
, 1);
1464 sim_read (sd
, s
++, &c
, 1);
1467 if (strchr ("dobxXu", c
))
1469 word64 lv
= (word64
) *ap
++;
1471 sim_io_printf(sd
,"<binary not supported>");
1474 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1476 sim_io_printf(sd
, tmp
, lv
);
1478 sim_io_printf(sd
, tmp
, (int)lv
);
1481 else if (strchr ("eEfgG", c
))
1483 double dbl
= *(double*)(ap
++);
1484 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1485 sim_io_printf (sd
, tmp
, dbl
);
1491 sim_io_printf(sd
, "%c", c
);
1497 /* Unknown reason. */
1503 /* Store a word into memory. */
1506 store_word (SIM_DESC sd
,
1512 address_word paddr
= vaddr
;
1514 if ((vaddr
& 3) != 0)
1515 SignalExceptionAddressStore ();
1518 const uword64 mask
= 7;
1522 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1523 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1524 memval
= ((uword64
) val
) << (8 * byte
);
1525 StoreMemory (AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1530 /* Load a word from memory. */
1533 load_word (SIM_DESC sd
,
1538 if ((vaddr
& 3) != 0)
1540 SIM_CORE_SIGNAL (SD
, cpu
, cia
, read_map
, AccessLength_WORD
+1, vaddr
, read_transfer
, sim_core_unaligned_signal
);
1544 address_word paddr
= vaddr
;
1545 const uword64 mask
= 0x7;
1546 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1547 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1551 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1552 LoadMemory (&memval
, NULL
, AccessLength_WORD
, paddr
, vaddr
, isDATA
,
1554 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1555 return EXTEND32 (memval
>> (8 * byte
));
1561 /* Simulate the mips16 entry and exit pseudo-instructions. These
1562 would normally be handled by the reserved instruction exception
1563 code, but for ease of simulation we just handle them directly. */
1566 mips16_entry (SIM_DESC sd
,
1571 int aregs
, sregs
, rreg
;
1574 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1577 aregs
= (insn
& 0x700) >> 8;
1578 sregs
= (insn
& 0x0c0) >> 6;
1579 rreg
= (insn
& 0x020) >> 5;
1581 /* This should be checked by the caller. */
1590 /* This is the entry pseudo-instruction. */
1592 for (i
= 0; i
< aregs
; i
++)
1593 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1601 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1604 for (i
= 0; i
< sregs
; i
++)
1607 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1615 /* This is the exit pseudo-instruction. */
1622 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1625 for (i
= 0; i
< sregs
; i
++)
1628 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1633 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1637 FGR
[0] = WORD64LO (GPR
[4]);
1638 FPR_STATE
[0] = fmt_uninterpreted
;
1640 else if (aregs
== 6)
1642 FGR
[0] = WORD64LO (GPR
[5]);
1643 FGR
[1] = WORD64LO (GPR
[4]);
1644 FPR_STATE
[0] = fmt_uninterpreted
;
1645 FPR_STATE
[1] = fmt_uninterpreted
;
1654 /*-- trace support ----------------------------------------------------------*/
1656 /* The trace support is provided (if required) in the memory accessing
1657 routines. Since we are also providing the architecture specific
1658 features, the architecture simulation code can also deal with
1659 notifying the trace world of cache flushes, etc. Similarly we do
1660 not need to provide profiling support in the simulator engine,
1661 since we can sample in the instruction fetch control loop. By
1662 defining the trace manifest, we add tracing as a run-time
1665 #if WITH_TRACE_ANY_P
1666 /* Tracing by default produces "din" format (as required by
1667 dineroIII). Each line of such a trace file *MUST* have a din label
1668 and address field. The rest of the line is ignored, so comments can
1669 be included if desired. The first field is the label which must be
1670 one of the following values:
1675 3 escape record (treated as unknown access type)
1676 4 escape record (causes cache flush)
1678 The address field is a 32bit (lower-case) hexadecimal address
1679 value. The address should *NOT* be preceded by "0x".
1681 The size of the memory transfer is not important when dealing with
1682 cache lines (as long as no more than a cache line can be
1683 transferred in a single operation :-), however more information
1684 could be given following the dineroIII requirement to allow more
1685 complete memory and cache simulators to provide better
1686 results. i.e. the University of Pisa has a cache simulator that can
1687 also take bus size and speed as (variable) inputs to calculate
1688 complete system performance (a much more useful ability when trying
1689 to construct an end product, rather than a processor). They
1690 currently have an ARM version of their tool called ChARM. */
1694 dotrace (SIM_DESC sd
,
1702 if (STATE
& simTRACE
) {
1704 fprintf(tracefh
,"%d %s ; width %d ; ",
1708 va_start(ap
,comment
);
1709 vfprintf(tracefh
,comment
,ap
);
1711 fprintf(tracefh
,"\n");
1713 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1714 we may be generating 64bit ones, we should put the hi-32bits of the
1715 address into the comment field. */
1717 /* TODO: Provide a buffer for the trace lines. We can then avoid
1718 performing writes until the buffer is filled, or the file is
1721 /* NOTE: We could consider adding a comment field to the "din" file
1722 produced using type 3 markers (unknown access). This would then
1723 allow information about the program that the "din" is for, and
1724 the MIPs world that was being simulated, to be placed into the
1729 #endif /* WITH_TRACE_ANY_P */
1731 /*---------------------------------------------------------------------------*/
1732 /*-- simulator engine -------------------------------------------------------*/
1733 /*---------------------------------------------------------------------------*/
1736 ColdReset (SIM_DESC sd
)
1739 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1741 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1742 /* RESET: Fixed PC address: */
1743 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1744 /* The reset vector address is in the unmapped, uncached memory space. */
1746 SR
&= ~(status_SR
| status_TS
| status_RP
);
1747 SR
|= (status_ERL
| status_BEV
);
1749 /* Cheat and allow access to the complete register set immediately */
1750 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1751 && WITH_TARGET_WORD_BITSIZE
== 64)
1752 SR
|= status_FR
; /* 64bit registers */
1754 /* Ensure that any instructions with pending register updates are
1756 PENDING_INVALIDATE();
1758 /* Initialise the FPU registers to the unknown state */
1759 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1762 for (rn
= 0; (rn
< 32); rn
++)
1763 FPR_STATE
[rn
] = fmt_uninterpreted
;
1766 /* Initialise the Config0 register. */
1767 C0_CONFIG
= 0x80000000 /* Config1 present */
1768 | 2; /* KSEG0 uncached */
1769 if (WITH_TARGET_WORD_BITSIZE
== 64)
1771 /* FIXME Currently mips/sim-main.c:address_translation()
1772 truncates all addresses to 32-bits. */
1773 if (0 && WITH_TARGET_ADDRESS_BITSIZE
== 64)
1774 C0_CONFIG
|= (2 << 13); /* MIPS64, 64-bit addresses */
1776 C0_CONFIG
|= (1 << 13); /* MIPS64, 32-bit addresses */
1779 C0_CONFIG
|= 0x00008000; /* Big Endian */
1786 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1787 /* Signal an exception condition. This will result in an exception
1788 that aborts the instruction. The instruction operation pseudocode
1789 will never see a return from this function call. */
1792 signal_exception (SIM_DESC sd
,
1800 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1803 /* Ensure that any active atomic read/modify/write operation will fail: */
1806 /* Save registers before interrupt dispatching */
1807 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1808 SIM_CPU_EXCEPTION_TRIGGER(sd
, cpu
, cia
);
1811 switch (exception
) {
1813 case DebugBreakPoint
:
1814 if (! (Debug
& Debug_DM
))
1820 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1821 DEPC
= cia
- 4; /* reference the branch instruction */
1825 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1829 Debug
|= Debug_DM
; /* in debugging mode */
1830 Debug
|= Debug_DBp
; /* raising a DBp exception */
1832 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1836 case ReservedInstruction
:
1839 unsigned int instruction
;
1840 va_start(ap
,exception
);
1841 instruction
= va_arg(ap
,unsigned int);
1843 /* Provide simple monitor support using ReservedInstruction
1844 exceptions. The following code simulates the fixed vector
1845 entry points into the IDT monitor by causing a simulator
1846 trap, performing the monitor operation, and returning to
1847 the address held in the $ra register (standard PCS return
1848 address). This means we only need to pre-load the vector
1849 space with suitable instruction values. For systems were
1850 actual trap instructions are used, we would not need to
1851 perform this magic. */
1852 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1854 int reason
= (instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
;
1855 if (!sim_monitor (SD
, CPU
, cia
, reason
))
1856 sim_io_error (sd
, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason
, pr_addr (cia
));
1858 /* NOTE: This assumes that a branch-and-link style
1859 instruction was used to enter the vector (which is the
1860 case with the current IDT monitor). */
1861 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1863 /* Look for the mips16 entry and exit instructions, and
1864 simulate a handler for them. */
1865 else if ((cia
& 1) != 0
1866 && (instruction
& 0xf81f) == 0xe809
1867 && (instruction
& 0x0c0) != 0x0c0)
1869 mips16_entry (SD
, CPU
, cia
, instruction
);
1870 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1872 /* else fall through to normal exception processing */
1873 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1877 /* Store exception code into current exception id variable (used
1880 /* TODO: If not simulating exceptions then stop the simulator
1881 execution. At the moment we always stop the simulation. */
1883 #ifdef SUBTARGET_R3900
1884 /* update interrupt-related registers */
1886 /* insert exception code in bits 6:2 */
1887 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1888 /* shift IE/KU history bits left */
1889 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1891 if (STATE
& simDELAYSLOT
)
1893 STATE
&= ~simDELAYSLOT
;
1895 EPC
= (cia
- 4); /* reference the branch instruction */
1900 if (SR
& status_BEV
)
1901 PC
= (signed)0xBFC00000 + 0x180;
1903 PC
= (signed)0x80000000 + 0x080;
1905 /* See figure 5-17 for an outline of the code below */
1906 if (! (SR
& status_EXL
))
1908 CAUSE
= (exception
<< 2);
1909 if (STATE
& simDELAYSLOT
)
1911 STATE
&= ~simDELAYSLOT
;
1913 EPC
= (cia
- 4); /* reference the branch instruction */
1917 /* FIXME: TLB et.al. */
1918 /* vector = 0x180; */
1922 CAUSE
= (exception
<< 2);
1923 /* vector = 0x180; */
1926 /* Store exception code into current exception id variable (used
1929 if (SR
& status_BEV
)
1930 PC
= (signed)0xBFC00200 + 0x180;
1932 PC
= (signed)0x80000000 + 0x180;
1935 switch ((CAUSE
>> 2) & 0x1F)
1938 /* Interrupts arrive during event processing, no need to
1944 #ifdef SUBTARGET_3900
1945 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1946 PC
= (signed)0xBFC00000;
1947 #endif /* SUBTARGET_3900 */
1950 case TLBModification
:
1955 case InstructionFetch
:
1957 /* The following is so that the simulator will continue from the
1958 exception handler address. */
1959 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1960 sim_stopped
, SIM_SIGBUS
);
1962 case ReservedInstruction
:
1963 case CoProcessorUnusable
:
1965 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1966 sim_stopped
, SIM_SIGILL
);
1968 case IntegerOverflow
:
1970 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1971 sim_stopped
, SIM_SIGFPE
);
1974 sim_engine_halt (SD
, CPU
, NULL
, PC
, sim_stopped
, SIM_SIGTRAP
);
1979 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1984 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1985 sim_stopped
, SIM_SIGTRAP
);
1987 default: /* Unknown internal exception */
1989 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1990 sim_stopped
, SIM_SIGABRT
);
1994 case SimulatorFault
:
1998 va_start(ap
,exception
);
1999 msg
= va_arg(ap
,char *);
2001 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2002 "FATAL: Simulator error \"%s\"\n",msg
);
2011 /* This function implements what the MIPS32 and MIPS64 ISAs define as
2012 "UNPREDICTABLE" behaviour.
2014 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2015 may vary from processor implementation to processor implementation,
2016 instruction to instruction, or as a function of time on the same
2017 implementation or instruction. Software can never depend on results
2018 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
2019 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
2022 For UNPREDICTABLE behaviour, we print a message, if possible print
2023 the offending instructions mips.igen instruction name (provided by
2024 the caller), and stop the simulator.
2026 XXX FIXME: eventually, stopping the simulator should be made conditional
2027 on a command-line option. */
2029 unpredictable_action(sim_cpu
*cpu
, address_word cia
)
2031 SIM_DESC sd
= CPU_STATE(cpu
);
2033 sim_io_eprintf(sd
, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia
));
2034 sim_engine_halt (SD
, CPU
, NULL
, cia
, sim_stopped
, SIM_SIGABRT
);
2038 /*-- co-processor support routines ------------------------------------------*/
2041 CoProcPresent(unsigned int coproc_number
)
2043 /* Return TRUE if simulator provides a model for the given co-processor number */
2048 cop_lw (SIM_DESC sd
,
2053 unsigned int memword
)
2058 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2061 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
2063 StoreFPR(coproc_reg
,fmt_uninterpreted_32
,(uword64
)memword
);
2068 #if 0 /* this should be controlled by a configuration option */
2069 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
));
2078 cop_ld (SIM_DESC sd
,
2087 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
) );
2090 switch (coproc_num
) {
2092 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2094 StoreFPR(coproc_reg
,fmt_uninterpreted_64
,memword
);
2099 #if 0 /* this message should be controlled by a configuration option */
2100 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
));
2112 cop_sw (SIM_DESC sd
,
2118 unsigned int value
= 0;
2123 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2125 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted_32
);
2130 #if 0 /* should be controlled by configuration option */
2131 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
2140 cop_sd (SIM_DESC sd
,
2150 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2152 value
= ValueFPR(coproc_reg
,fmt_uninterpreted_64
);
2157 #if 0 /* should be controlled by configuration option */
2158 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
2170 decode_coproc (SIM_DESC sd
,
2173 unsigned int instruction
,
2182 case 0: /* standard CPU control and cache registers */
2184 /* R4000 Users Manual (second edition) lists the following CP0
2186 CODE><-RT><RD-><--TAIL--->
2187 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2188 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2189 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2190 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2191 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2192 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2193 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2194 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2195 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2196 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2198 if (((op
== cp0_mfc0
) || (op
== cp0_mtc0
) /* MFC0 / MTC0 */
2199 || (op
== cp0_dmfc0
) || (op
== cp0_dmtc0
)) /* DMFC0 / DMTC0 */
2202 switch (rd
) /* NOTEs: Standard CP0 registers */
2204 /* 0 = Index R4000 VR4100 VR4300 */
2205 /* 1 = Random R4000 VR4100 VR4300 */
2206 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
2207 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
2208 /* 4 = Context R4000 VR4100 VR4300 */
2209 /* 5 = PageMask R4000 VR4100 VR4300 */
2210 /* 6 = Wired R4000 VR4100 VR4300 */
2211 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2212 /* 9 = Count R4000 VR4100 VR4300 */
2213 /* 10 = EntryHi R4000 VR4100 VR4300 */
2214 /* 11 = Compare R4000 VR4100 VR4300 */
2215 /* 12 = SR R4000 VR4100 VR4300 */
2216 #ifdef SUBTARGET_R3900
2218 /* 3 = Config R3900 */
2220 /* 7 = Cache R3900 */
2222 /* 15 = PRID R3900 */
2228 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2229 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2230 GPR
[rt
] = (signed_word
) (signed_address
) COP0_BADVADDR
;
2232 COP0_BADVADDR
= GPR
[rt
];
2235 #endif /* SUBTARGET_R3900 */
2237 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2242 /* 13 = Cause R4000 VR4100 VR4300 */
2244 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2249 /* 14 = EPC R4000 VR4100 VR4300 */
2251 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2252 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
2256 /* 15 = PRId R4000 VR4100 VR4300 */
2257 #ifdef SUBTARGET_R3900
2260 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2266 /* 16 = Config R4000 VR4100 VR4300 */
2268 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2269 GPR
[rt
] = C0_CONFIG
;
2271 /* only bottom three bits are writable */
2272 C0_CONFIG
= (C0_CONFIG
& ~0x7) | (GPR
[rt
] & 0x7);
2275 #ifdef SUBTARGET_R3900
2278 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2284 /* 17 = LLAddr R4000 VR4100 VR4300 */
2286 /* 18 = WatchLo R4000 VR4100 VR4300 */
2287 /* 19 = WatchHi R4000 VR4100 VR4300 */
2288 /* 20 = XContext R4000 VR4100 VR4300 */
2289 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2290 /* 27 = CacheErr R4000 VR4100 */
2291 /* 28 = TagLo R4000 VR4100 VR4300 */
2292 /* 29 = TagHi R4000 VR4100 VR4300 */
2293 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
2294 if (STATE_VERBOSE_P(SD
))
2296 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2297 (unsigned long)cia
);
2298 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
2299 /* CPR[0,rd] = GPR[rt]; */
2301 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2302 GPR
[rt
] = (signed_word
) (signed32
) COP0_GPR
[rd
];
2304 COP0_GPR
[rd
] = GPR
[rt
];
2307 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
2309 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
2313 else if ((op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2316 /* [D]MFC0 RT,C0_CONFIG,SEL */
2324 /* MIPS32 r/o Config1:
2327 /* MIPS16 implemented.
2328 XXX How to check configuration? */
2330 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2331 /* MDMX & FPU implemented */
2335 /* MIPS32 r/o Config2:
2340 /* MIPS32 r/o Config3:
2341 SmartMIPS implemented. */
2347 else if (op
== cp0_eret
&& sel
== 0x18)
2350 if (SR
& status_ERL
)
2352 /* Oops, not yet available */
2353 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
2363 else if (op
== cp0_rfe
&& sel
== 0x10)
2366 #ifdef SUBTARGET_R3900
2367 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2369 /* shift IE/KU history bits right */
2370 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
2372 /* TODO: CACHE register */
2373 #endif /* SUBTARGET_R3900 */
2375 else if (op
== cp0_deret
&& sel
== 0x1F)
2383 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
2384 /* TODO: When executing an ERET or RFE instruction we should
2385 clear LLBIT, to ensure that any out-standing atomic
2386 read/modify/write sequence fails. */
2390 case 2: /* co-processor 2 */
2397 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2398 instruction
,pr_addr(cia
));
2403 case 1: /* should not occur (FPU co-processor) */
2404 case 3: /* should not occur (FPU co-processor) */
2405 SignalException(ReservedInstruction
,instruction
);
2413 /* This code copied from gdb's utils.c. Would like to share this code,
2414 but don't know of a common place where both could get to it. */
2416 /* Temporary storage using circular buffer */
2422 static char buf
[NUMCELLS
][CELLSIZE
];
2424 if (++cell
>=NUMCELLS
) cell
=0;
2428 /* Print routines to handle variable size regs, etc */
2430 /* Eliminate warning from compiler on 32-bit systems */
2431 static int thirty_two
= 32;
2434 pr_addr (SIM_ADDR addr
)
2436 char *paddr_str
=get_cell();
2437 switch (sizeof(addr
))
2440 sprintf(paddr_str
,"%08lx%08lx",
2441 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
2444 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
2447 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
2450 sprintf(paddr_str
,"%x",addr
);
2456 pr_uword64 (uword64 addr
)
2458 char *paddr_str
=get_cell();
2459 sprintf(paddr_str
,"%08lx%08lx",
2460 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
2466 mips_core_signal (SIM_DESC sd
,
2472 transfer_type transfer
,
2473 sim_core_signals sig
)
2475 const char *copy
= (transfer
== read_transfer
? "read" : "write");
2476 address_word ip
= CIA_ADDR (cia
);
2480 case sim_core_unmapped_signal
:
2481 sim_io_eprintf (sd
, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2483 (unsigned long) addr
, (unsigned long) ip
);
2484 COP0_BADVADDR
= addr
;
2485 SignalExceptionDataReference();
2488 case sim_core_unaligned_signal
:
2489 sim_io_eprintf (sd
, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
2491 (unsigned long) addr
, (unsigned long) ip
);
2492 COP0_BADVADDR
= addr
;
2493 if(transfer
== read_transfer
)
2494 SignalExceptionAddressLoad();
2496 SignalExceptionAddressStore();
2500 sim_engine_abort (sd
, cpu
, cia
,
2501 "mips_core_signal - internal error - bad switch");
2507 mips_cpu_exception_trigger(SIM_DESC sd
, sim_cpu
* cpu
, address_word cia
)
2509 ASSERT(cpu
!= NULL
);
2511 if(cpu
->exc_suspended
> 0)
2512 sim_io_eprintf(sd
, "Warning, nested exception triggered (%d)\n", cpu
->exc_suspended
);
2515 memcpy(cpu
->exc_trigger_registers
, cpu
->registers
, sizeof(cpu
->exc_trigger_registers
));
2516 cpu
->exc_suspended
= 0;
2520 mips_cpu_exception_suspend(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
2522 ASSERT(cpu
!= NULL
);
2524 if(cpu
->exc_suspended
> 0)
2525 sim_io_eprintf(sd
, "Warning, nested exception signal (%d then %d)\n",
2526 cpu
->exc_suspended
, exception
);
2528 memcpy(cpu
->exc_suspend_registers
, cpu
->registers
, sizeof(cpu
->exc_suspend_registers
));
2529 memcpy(cpu
->registers
, cpu
->exc_trigger_registers
, sizeof(cpu
->registers
));
2530 cpu
->exc_suspended
= exception
;
2534 mips_cpu_exception_resume(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
2536 ASSERT(cpu
!= NULL
);
2538 if(exception
== 0 && cpu
->exc_suspended
> 0)
2540 /* warn not for breakpoints */
2541 if(cpu
->exc_suspended
!= sim_signal_to_host(sd
, SIM_SIGTRAP
))
2542 sim_io_eprintf(sd
, "Warning, resuming but ignoring pending exception signal (%d)\n",
2543 cpu
->exc_suspended
);
2545 else if(exception
!= 0 && cpu
->exc_suspended
> 0)
2547 if(exception
!= cpu
->exc_suspended
)
2548 sim_io_eprintf(sd
, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2549 cpu
->exc_suspended
, exception
);
2551 memcpy(cpu
->registers
, cpu
->exc_suspend_registers
, sizeof(cpu
->registers
));
2553 else if(exception
!= 0 && cpu
->exc_suspended
== 0)
2555 sim_io_eprintf(sd
, "Warning, ignoring spontanous exception signal (%d)\n", exception
);
2557 cpu
->exc_suspended
= 0;
2561 /*---------------------------------------------------------------------------*/
2562 /*> EOF interp.c <*/