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"
34 #include "sim-signal.h"
48 #include "libiberty.h"
50 #include "bfd/elf-bfd.h"
51 #include "sim/callback.h" /* GDB simulator callback interface */
52 #include "sim/sim.h" /* GDB simulator interface */
53 #include "sim-syscall.h" /* Simulator system call support */
55 char* pr_addr (address_word addr
);
56 char* pr_uword64 (uword64 addr
);
59 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
64 /* The following reserved instruction value is used when a simulator
65 trap is required. NOTE: Care must be taken, since this value may be
66 used in later revisions of the MIPS ISA. */
68 #define RSVD_INSTRUCTION (0x00000039)
69 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
71 #define RSVD_INSTRUCTION_ARG_SHIFT 6
72 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
75 /* Bits in the Debug register */
76 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
77 #define Debug_DM 0x40000000 /* Debug Mode */
78 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
80 /*---------------------------------------------------------------------------*/
81 /*-- GDB simulator interface ------------------------------------------------*/
82 /*---------------------------------------------------------------------------*/
84 static void ColdReset (SIM_DESC sd
);
86 /*---------------------------------------------------------------------------*/
90 #define DELAYSLOT() {\
91 if (STATE & simDELAYSLOT)\
92 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
93 STATE |= simDELAYSLOT;\
96 #define JALDELAYSLOT() {\
98 STATE |= simJALDELAYSLOT;\
102 STATE &= ~simDELAYSLOT;\
103 STATE |= simSKIPNEXT;\
106 #define CANCELDELAYSLOT() {\
108 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
111 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
112 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
114 /* Note that the monitor code essentially assumes this layout of memory.
115 If you change these, change the monitor code, too. */
116 /* FIXME Currently addresses are truncated to 32-bits, see
117 mips/sim-main.c:address_translation(). If that changes, then these
118 values will need to be extended, and tested for more carefully. */
119 #define K0BASE (0x80000000)
120 #define K0SIZE (0x20000000)
121 #define K1BASE (0xA0000000)
122 #define K1SIZE (0x20000000)
124 /* Simple run-time monitor support.
126 We emulate the monitor by placing magic reserved instructions at
127 the monitor's entry points; when we hit these instructions, instead
128 of raising an exception (as we would normally), we look at the
129 instruction and perform the appropriate monitory operation.
131 `*_monitor_base' are the physical addresses at which the corresponding
132 monitor vectors are located. `0' means none. By default,
134 The RSVD_INSTRUCTION... macros specify the magic instructions we
135 use at the monitor entry points. */
136 static int firmware_option_p
= 0;
137 static address_word idt_monitor_base
= 0xBFC00000;
138 static address_word pmon_monitor_base
= 0xBFC00500;
139 static address_word lsipmon_monitor_base
= 0xBFC00200;
141 static SIM_RC
sim_firmware_command (SIM_DESC sd
, char* arg
);
143 #define MEM_SIZE (8 << 20) /* 8 MBytes */
147 static char *tracefile
= "trace.din"; /* default filename for trace log */
148 FILE *tracefh
= NULL
;
149 static void open_trace (SIM_DESC sd
);
151 #define open_trace(sd)
154 static const char * get_insn_name (sim_cpu
*, int);
156 /* simulation target board. NULL=canonical */
157 static char* board
= NULL
;
160 static DECLARE_OPTION_HANDLER (mips_option_handler
);
163 OPTION_DINERO_TRACE
= OPTION_START
,
170 static int display_mem_info
= 0;
173 mips_option_handler (SIM_DESC sd
, sim_cpu
*cpu
, int opt
, char *arg
,
179 case OPTION_DINERO_TRACE
: /* ??? */
181 /* Eventually the simTRACE flag could be treated as a toggle, to
182 allow external control of the program points being traced
183 (i.e. only from main onwards, excluding the run-time setup,
185 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
187 cpu
= STATE_CPU (sd
, cpu_nr
);
190 else if (strcmp (arg
, "yes") == 0)
192 else if (strcmp (arg
, "no") == 0)
194 else if (strcmp (arg
, "on") == 0)
196 else if (strcmp (arg
, "off") == 0)
200 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
205 #else /* !WITH_TRACE_ANY_P */
207 Simulator constructed without dinero tracing support (for performance).\n\
208 Re-compile simulator with \"-DWITH_TRACE_ANY_P\" to enable this option.\n");
210 #endif /* !WITH_TRACE_ANY_P */
212 case OPTION_DINERO_FILE
:
214 if (optarg
!= NULL
) {
216 tmp
= (char *)malloc(strlen(optarg
) + 1);
219 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
225 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
228 #endif /* WITH_TRACE_ANY_P */
231 case OPTION_FIRMWARE
:
232 return sim_firmware_command (sd
, arg
);
238 board
= zalloc(strlen(arg
) + 1);
244 case OPTION_INFO_MEMORY
:
245 display_mem_info
= 1;
253 static const OPTION mips_options
[] =
255 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
256 '\0', "on|off", "Enable dinero tracing",
257 mips_option_handler
},
258 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
259 '\0', "FILE", "Write dinero trace to FILE",
260 mips_option_handler
},
261 { {"firmware", required_argument
, NULL
, OPTION_FIRMWARE
},
262 '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
263 mips_option_handler
},
264 { {"board", required_argument
, NULL
, OPTION_BOARD
},
265 '\0', "none" /* rely on compile-time string concatenation for other options */
267 #define BOARD_JMR3904 "jmr3904"
269 #define BOARD_JMR3904_PAL "jmr3904pal"
270 "|" BOARD_JMR3904_PAL
271 #define BOARD_JMR3904_DEBUG "jmr3904debug"
272 "|" BOARD_JMR3904_DEBUG
273 #define BOARD_BSP "bsp"
276 , "Customize simulation for a particular board.", mips_option_handler
},
278 /* These next two options have the same names as ones found in the
279 memory_options[] array in common/sim-memopt.c. This is because
280 the intention is to provide an alternative handler for those two
281 options. We need an alternative handler because the memory
282 regions are not set up until after the command line arguments
283 have been parsed, and so we cannot display the memory info whilst
284 processing the command line. There is a hack in sim_open to
285 remove these handlers when we want the real --memory-info option
287 { { "info-memory", no_argument
, NULL
, OPTION_INFO_MEMORY
},
288 '\0', NULL
, "List configured memory regions", mips_option_handler
},
289 { { "memory-info", no_argument
, NULL
, OPTION_INFO_MEMORY
},
290 '\0', NULL
, NULL
, mips_option_handler
},
292 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
296 int interrupt_pending
;
299 interrupt_event (SIM_DESC sd
, void *data
)
301 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
302 address_word cia
= CPU_PC_GET (cpu
);
305 interrupt_pending
= 0;
306 SignalExceptionInterrupt (1); /* interrupt "1" */
308 else if (!interrupt_pending
)
309 sim_events_schedule (sd
, 1, interrupt_event
, data
);
313 /*---------------------------------------------------------------------------*/
314 /*-- Device registration hook -----------------------------------------------*/
315 /*---------------------------------------------------------------------------*/
316 static void device_init(SIM_DESC sd
) {
318 extern void register_devices(SIM_DESC
);
319 register_devices(sd
);
323 /*---------------------------------------------------------------------------*/
324 /*-- GDB simulator interface ------------------------------------------------*/
325 /*---------------------------------------------------------------------------*/
328 mips_pc_get (sim_cpu
*cpu
)
334 mips_pc_set (sim_cpu
*cpu
, sim_cia pc
)
339 static int mips_reg_fetch (SIM_CPU
*, int, void *, int);
340 static int mips_reg_store (SIM_CPU
*, int, const void *, int);
343 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
,
344 struct bfd
*abfd
, char * const *argv
)
347 SIM_DESC sd
= sim_state_alloc_extra (kind
, cb
,
348 sizeof (struct mips_sim_state
));
351 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
353 /* The cpu data is kept in a separately allocated chunk of memory. */
354 if (sim_cpu_alloc_all_extra (sd
, 0, sizeof (struct mips_sim_cpu
))
358 cpu
= STATE_CPU (sd
, 0); /* FIXME */
360 /* FIXME: watchpoints code shouldn't need this */
361 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
363 /* Initialize the mechanism for doing insn profiling. */
364 CPU_INSN_NAME (cpu
) = get_insn_name
;
365 CPU_MAX_INSNS (cpu
) = nr_itable_entries
;
369 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
371 sim_add_option_table (sd
, NULL
, mips_options
);
374 /* The parser will print an error message for us, so we silently return. */
375 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
377 /* Uninstall the modules to avoid memory leaks,
378 file descriptor leaks, etc. */
379 sim_module_uninstall (sd
);
383 /* handle board-specific memory maps */
386 /* Allocate core managed memory */
387 sim_memopt
*entry
, *match
= NULL
;
388 address_word mem_size
= 0;
391 /* For compatibility with the old code - under this (at level one)
392 are the kernel spaces K0 & K1. Both of these map to a single
393 smaller sub region */
394 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
396 /* Look for largest memory region defined on command-line at
398 for (entry
= STATE_MEMOPT (sd
); entry
!= NULL
; entry
= entry
->next
)
400 /* If we find an entry at address 0, then we will end up
401 allocating a new buffer in the "memory alias" command
402 below. The region at address 0 will be deleted. */
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%" PRIxTW
"@%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%x@1,0x%x%%0x%lx,0x%0x",
440 K1BASE
, K1SIZE
, (long)mem_size
, K0BASE
);
441 if (WITH_TARGET_WORD_BITSIZE
== 64)
442 sim_do_commandf (sd
, "memory alias 0x%x,0x%" PRIxTW
",0x%" PRIxTA
,
443 (K0BASE
), mem_size
, EXTENDED(K0BASE
));
448 else if (board
!= NULL
449 && (strcmp(board
, BOARD_BSP
) == 0))
451 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
453 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
454 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x,0x%0x",
456 4 * 1024 * 1024, /* 4 MB */
459 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
460 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x,0x%0x",
462 4 * 1024 * 1024, /* 4 MB */
465 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
466 for (i
=0; i
<8; i
++) /* 32 MB total */
468 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
469 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x,0x%0x",
470 0x88000000 + (i
* size
),
472 0xA8000000 + (i
* size
));
476 else if (board
!= NULL
477 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
478 strcmp(board
, BOARD_JMR3904_PAL
) == 0 ||
479 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
481 /* match VIRTUAL memory layout of JMR-TX3904 board */
483 /* --- disable monitor unless forced on by user --- */
485 if (! firmware_option_p
)
487 idt_monitor_base
= 0;
488 pmon_monitor_base
= 0;
489 lsipmon_monitor_base
= 0;
492 /* --- environment --- */
494 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
498 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
499 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x,0x%0x",
501 4 * 1024 * 1024, /* 4 MB */
504 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
505 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x,0x%0x",
507 4 * 1024 * 1024, /* 4 MB */
510 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
511 for (i
=0; i
<8; i
++) /* 32 MB total */
513 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
514 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x,0x%0x",
515 0x88000000 + (i
* size
),
517 0xA8000000 + (i
* size
));
520 /* Dummy memory regions for unsimulated devices - sorted by address */
522 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xB1000000, 0x400); /* ISA I/O */
523 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xB2100000, 0x004); /* ISA ctl */
524 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xB2500000, 0x004); /* LED/switch */
525 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xB2700000, 0x004); /* RTC */
526 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xB3C00000, 0x004); /* RTC */
527 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xFFFF8000, 0x900); /* DRAMC */
528 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xFFFF9000, 0x200); /* EBIF */
529 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xFFFFE000, 0x01c); /* EBIF */
530 sim_do_commandf (sd
, "memory alias 0x%x@1,0x%x", 0xFFFFF500, 0x300); /* PIO */
533 /* --- simulated devices --- */
534 sim_hw_parse (sd
, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
535 sim_hw_parse (sd
, "/tx3904cpu");
536 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
537 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
538 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
539 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
541 /* FIXME: poking at dv-sockser internals, use tcp backend if
542 --sockser_addr option was given.*/
543 #ifdef HAVE_DV_SOCKSER
544 extern char* sockser_addr
;
546 # define sockser_addr NULL
548 if (sockser_addr
== NULL
)
549 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend stdio");
551 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend tcp");
553 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
554 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/backend stdio");
556 /* -- device connections --- */
557 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
558 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
559 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
560 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
561 sim_hw_parse (sd
, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
562 sim_hw_parse (sd
, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
564 /* add PAL timer & I/O module */
565 if (!strcmp(board
, BOARD_JMR3904_PAL
))
568 sim_hw_parse (sd
, "/pal@0xffff0000");
569 sim_hw_parse (sd
, "/pal@0xffff0000/reg 0xffff0000 64");
571 /* wire up interrupt ports to irc */
572 sim_hw_parse (sd
, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
573 sim_hw_parse (sd
, "/pal@0x31000000 > timer tmr1 /tx3904irc");
574 sim_hw_parse (sd
, "/pal@0x31000000 > int int0 /tx3904irc");
577 if (!strcmp(board
, BOARD_JMR3904_DEBUG
))
579 /* -- DEBUG: glue interrupt generators --- */
580 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
581 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
582 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
583 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
584 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
585 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
586 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
587 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
588 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
589 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
590 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
591 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
592 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
593 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
594 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
595 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
596 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
597 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
598 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
605 if (display_mem_info
)
607 struct option_list
* ol
;
608 struct option_list
* prev
;
610 /* This is a hack. We want to execute the real --memory-info command
611 line switch which is handled in common/sim-memopts.c, not the
612 override we have defined in this file. So we remove the
613 mips_options array from the state options list. This is safe
614 because we have now processed all of the command line. */
615 for (ol
= STATE_OPTIONS (sd
), prev
= NULL
;
617 prev
= ol
, ol
= ol
->next
)
618 if (ol
->options
== mips_options
)
621 SIM_ASSERT (ol
!= NULL
);
624 STATE_OPTIONS (sd
) = ol
->next
;
626 prev
->next
= ol
->next
;
628 sim_do_commandf (sd
, "memory-info");
631 /* check for/establish the a reference program image */
632 if (sim_analyze_program (sd
, STATE_PROG_FILE (sd
), abfd
) != SIM_RC_OK
)
634 sim_module_uninstall (sd
);
638 /* Configure/verify the target byte order and other runtime
639 configuration options */
640 if (sim_config (sd
) != SIM_RC_OK
)
642 sim_module_uninstall (sd
);
646 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
648 /* Uninstall the modules to avoid memory leaks,
649 file descriptor leaks, etc. */
650 sim_module_uninstall (sd
);
654 /* verify assumptions the simulator made about the host type system.
655 This macro does not return if there is a problem */
656 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
657 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
659 /* This is NASTY, in that we are assuming the size of specific
663 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
665 struct mips_sim_cpu
*mips_cpu
= MIPS_SIM_CPU (cpu
);
668 mips_cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
669 else if ((rn
>= FGR_BASE
) && (rn
< (FGR_BASE
+ NR_FGR
)))
670 mips_cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
671 else if ((rn
>= 33) && (rn
<= 37))
672 mips_cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
673 else if ((rn
== SRIDX
)
676 || ((rn
>= 72) && (rn
<= 89)))
677 mips_cpu
->register_widths
[rn
] = 32;
679 mips_cpu
->register_widths
[rn
] = 0;
685 if (STATE
& simTRACE
)
689 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
692 lsipmon_monitor_base);
695 /* Write the monitor trap address handlers into the monitor (eeprom)
696 address space. This can only be done once the target endianness
697 has been determined. */
698 if (idt_monitor_base
!= 0)
701 address_word idt_monitor_size
= 1 << 11;
703 /* the default monitor region */
704 if (WITH_TARGET_WORD_BITSIZE
== 64)
705 sim_do_commandf (sd
, "memory alias %#" PRIxTA
",%#" PRIxTA
",%#" PRIxTA
,
706 idt_monitor_base
, idt_monitor_size
,
707 EXTENDED (idt_monitor_base
));
709 sim_do_commandf (sd
, "memory region %#" PRIxTA
",%#" PRIxTA
,
710 idt_monitor_base
, idt_monitor_size
);
712 /* Entry into the IDT monitor is via fixed address vectors, and
713 not using machine instructions. To avoid clashing with use of
714 the MIPS TRAP system, we place our own (simulator specific)
715 "undefined" instructions into the relevant vector slots. */
716 for (loop
= 0; (loop
< idt_monitor_size
); loop
+= 4)
718 address_word vaddr
= (idt_monitor_base
+ loop
);
719 uint32_t insn
= (RSVD_INSTRUCTION
|
720 (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
)
721 << RSVD_INSTRUCTION_ARG_SHIFT
));
723 sim_write (sd
, vaddr
, &insn
, sizeof (insn
));
727 if ((pmon_monitor_base
!= 0) || (lsipmon_monitor_base
!= 0))
729 /* The PMON monitor uses the same address space, but rather than
730 branching into it the address of a routine is loaded. We can
731 cheat for the moment, and direct the PMON routine to IDT style
732 instructions within the monitor space. This relies on the IDT
733 monitor not using the locations from 0xBFC00500 onwards as its
736 for (loop
= 0; (loop
< 24); loop
++)
738 uint32_t value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
754 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
756 case 8: /* cliexit */
759 case 11: /* flush_cache */
764 SIM_ASSERT (idt_monitor_base
!= 0);
765 value
= ((unsigned int) idt_monitor_base
+ (value
* 8));
768 if (pmon_monitor_base
!= 0)
770 address_word vaddr
= (pmon_monitor_base
+ (loop
* 4));
771 sim_write (sd
, vaddr
, &value
, sizeof (value
));
774 if (lsipmon_monitor_base
!= 0)
776 address_word vaddr
= (lsipmon_monitor_base
+ (loop
* 4));
777 sim_write (sd
, vaddr
, &value
, sizeof (value
));
781 /* Write an abort sequence into the TRAP (common) exception vector
782 addresses. This is to catch code executing a TRAP (et.al.)
783 instruction without installing a trap handler. */
784 if ((idt_monitor_base
!= 0) ||
785 (pmon_monitor_base
!= 0) ||
786 (lsipmon_monitor_base
!= 0))
788 uint32_t halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
789 HALT_INSTRUCTION
/* BREAK */ };
792 sim_write (sd
, 0x80000000, halt
, sizeof (halt
));
793 sim_write (sd
, 0x80000180, halt
, sizeof (halt
));
794 sim_write (sd
, 0x80000200, halt
, sizeof (halt
));
795 /* XXX: Write here unconditionally? */
796 sim_write (sd
, 0xBFC00200, halt
, sizeof (halt
));
797 sim_write (sd
, 0xBFC00380, halt
, sizeof (halt
));
798 sim_write (sd
, 0xBFC00400, halt
, sizeof (halt
));
802 /* CPU specific initialization. */
803 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
805 cpu
= STATE_CPU (sd
, i
);
807 CPU_REG_FETCH (cpu
) = mips_reg_fetch
;
808 CPU_REG_STORE (cpu
) = mips_reg_store
;
809 CPU_PC_FETCH (cpu
) = mips_pc_get
;
810 CPU_PC_STORE (cpu
) = mips_pc_set
;
818 open_trace (SIM_DESC sd
)
820 tracefh
= fopen(tracefile
,"wb+");
823 sim_io_eprintf(sd
,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile
);
829 /* Return name of an insn, used by insn profiling. */
831 get_insn_name (sim_cpu
*cpu
, int i
)
833 return itable
[i
].name
;
837 mips_sim_close (SIM_DESC sd
, int quitting
)
840 if (tracefh
!= NULL
&& tracefh
!= stderr
)
847 mips_reg_store (SIM_CPU
*cpu
, int rn
, const void *memory
, int length
)
849 /* NOTE: gdb (the client) stores registers in target byte order
850 while the simulator uses host byte order */
852 /* Unfortunately this suffers from the same problem as the register
853 numbering one. We need to know what the width of each logical
854 register number is for the architecture being simulated. */
856 struct mips_sim_cpu
*mips_cpu
= MIPS_SIM_CPU (cpu
);
858 if (mips_cpu
->register_widths
[rn
] == 0)
860 sim_io_eprintf (CPU_STATE (cpu
), "Invalid register width for %d (register store ignored)\n", rn
);
864 if (rn
>= FGR_BASE
&& rn
< FGR_BASE
+ NR_FGR
)
866 mips_cpu
->fpr_state
[rn
- FGR_BASE
] = fmt_uninterpreted
;
867 if (mips_cpu
->register_widths
[rn
] == 32)
871 mips_cpu
->fgr
[rn
- FGR_BASE
] =
872 (uint32_t) T2H_8 (*(uint64_t*)memory
);
877 mips_cpu
->fgr
[rn
- FGR_BASE
] = T2H_4 (*(uint32_t*)memory
);
885 mips_cpu
->fgr
[rn
- FGR_BASE
] = T2H_8 (*(uint64_t*)memory
);
890 mips_cpu
->fgr
[rn
- FGR_BASE
] = T2H_4 (*(uint32_t*)memory
);
896 if (mips_cpu
->register_widths
[rn
] == 32)
900 mips_cpu
->registers
[rn
] =
901 (uint32_t) T2H_8 (*(uint64_t*)memory
);
906 mips_cpu
->registers
[rn
] = T2H_4 (*(uint32_t*)memory
);
914 mips_cpu
->registers
[rn
] = T2H_8 (*(uint64_t*)memory
);
919 mips_cpu
->registers
[rn
] = (int32_t) T2H_4(*(uint32_t*)memory
);
928 mips_reg_fetch (SIM_CPU
*cpu
, int rn
, void *memory
, int length
)
930 /* NOTE: gdb (the client) stores registers in target byte order
931 while the simulator uses host byte order */
933 struct mips_sim_cpu
*mips_cpu
= MIPS_SIM_CPU (cpu
);
935 if (mips_cpu
->register_widths
[rn
] == 0)
937 sim_io_eprintf (CPU_STATE (cpu
), "Invalid register width for %d (register fetch ignored)\n", rn
);
941 /* Any floating point register */
942 if (rn
>= FGR_BASE
&& rn
< FGR_BASE
+ NR_FGR
)
944 if (mips_cpu
->register_widths
[rn
] == 32)
949 H2T_8 ((uint32_t) (mips_cpu
->fgr
[rn
- FGR_BASE
]));
954 *(uint32_t*)memory
= H2T_4 (mips_cpu
->fgr
[rn
- FGR_BASE
]);
962 *(uint64_t*)memory
= H2T_8 (mips_cpu
->fgr
[rn
- FGR_BASE
]);
967 *(uint32_t*)memory
= H2T_4 ((uint32_t)(mips_cpu
->fgr
[rn
- FGR_BASE
]));
973 if (mips_cpu
->register_widths
[rn
] == 32)
978 H2T_8 ((uint32_t) (mips_cpu
->registers
[rn
]));
983 *(uint32_t*)memory
= H2T_4 ((uint32_t)(mips_cpu
->registers
[rn
]));
992 H2T_8 ((uint64_t) (mips_cpu
->registers
[rn
]));
997 *(uint32_t*)memory
= H2T_4 ((uint32_t)(mips_cpu
->registers
[rn
]));
1006 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1007 char * const *argv
, char * const *env
)
1011 #if 0 /* FIXME: doesn't compile */
1012 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1021 /* override PC value set by ColdReset () */
1023 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1025 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1026 sim_cia pc
= bfd_get_start_address (abfd
);
1028 /* The 64-bit BFD sign-extends MIPS addresses to model
1029 32-bit compatibility segments with 64-bit addressing.
1030 These addresses work as is on 64-bit targets but
1031 can be truncated for 32-bit targets. */
1032 if (WITH_TARGET_WORD_BITSIZE
== 32)
1035 CPU_PC_SET (cpu
, pc
);
1039 #if 0 /* def DEBUG */
1042 /* We should really place the argv slot values into the argument
1043 registers, and onto the stack as required. However, this
1044 assumes that we have a stack defined, which is not
1045 necessarily true at the moment. */
1047 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1048 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1049 printf("DBG: arg \"%s\"\n",*cptr
);
1056 /*---------------------------------------------------------------------------*/
1057 /*-- Private simulator support interface ------------------------------------*/
1058 /*---------------------------------------------------------------------------*/
1060 /* Read a null terminated string from memory, return in a buffer */
1062 fetch_str (SIM_DESC sd
,
1068 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1070 buf
= NZALLOC (char, nr
+ 1);
1071 sim_read (sd
, addr
, buf
, nr
);
1076 /* Implements the "sim firmware" command:
1077 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1078 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1079 defaults to the normal address for that monitor.
1080 sim firmware none --- don't emulate any ROM monitor. Useful
1081 if you need a clean address space. */
1083 sim_firmware_command (SIM_DESC sd
, char *arg
)
1085 int address_present
= 0;
1086 address_word address
;
1088 /* Signal occurrence of this option. */
1089 firmware_option_p
= 1;
1091 /* Parse out the address, if present. */
1093 char *p
= strchr (arg
, '@');
1097 address_present
= 1;
1098 p
++; /* skip over @ */
1100 address
= strtoul (p
, &q
, 0);
1103 sim_io_printf (sd
, "Invalid address given to the"
1104 "`sim firmware NAME@ADDRESS' command: %s\n",
1111 address_present
= 0;
1112 address
= -1; /* Dummy value. */
1116 if (! strncmp (arg
, "idt", 3))
1118 idt_monitor_base
= address_present
? address
: 0xBFC00000;
1119 pmon_monitor_base
= 0;
1120 lsipmon_monitor_base
= 0;
1122 else if (! strncmp (arg
, "pmon", 4))
1124 /* pmon uses indirect calls. Hook into implied idt. */
1125 pmon_monitor_base
= address_present
? address
: 0xBFC00500;
1126 idt_monitor_base
= pmon_monitor_base
- 0x500;
1127 lsipmon_monitor_base
= 0;
1129 else if (! strncmp (arg
, "lsipmon", 7))
1131 /* lsipmon uses indirect calls. Hook into implied idt. */
1132 pmon_monitor_base
= 0;
1133 lsipmon_monitor_base
= address_present
? address
: 0xBFC00200;
1134 idt_monitor_base
= lsipmon_monitor_base
- 0x200;
1136 else if (! strncmp (arg
, "none", 4))
1138 if (address_present
)
1141 "The `sim firmware none' command does "
1142 "not take an `ADDRESS' argument.\n");
1145 idt_monitor_base
= 0;
1146 pmon_monitor_base
= 0;
1147 lsipmon_monitor_base
= 0;
1151 sim_io_printf (sd
, "\
1152 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1153 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1161 /* stat structures from MIPS32/64. */
1162 static const char stat32_map
[] =
1163 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1164 ":st_rdev,2:st_size,4:st_atime,4:st_spare1,4:st_mtime,4:st_spare2,4"
1165 ":st_ctime,4:st_spare3,4:st_blksize,4:st_blocks,4:st_spare4,8";
1167 static const char stat64_map
[] =
1168 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1169 ":st_rdev,2:st_size,8:st_atime,8:st_spare1,8:st_mtime,8:st_spare2,8"
1170 ":st_ctime,8:st_spare3,8:st_blksize,8:st_blocks,8:st_spare4,16";
1172 /* Map for calls using the host struct stat. */
1173 static const CB_TARGET_DEFS_MAP CB_stat_map
[] =
1175 { "stat", CB_SYS_stat
, 15 },
1180 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1182 sim_monitor (SIM_DESC sd
,
1185 unsigned int reason
)
1188 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1191 /* The IDT monitor actually allows two instructions per vector
1192 slot. However, the simulator currently causes a trap on each
1193 individual instruction. We cheat, and lose the bottom bit. */
1196 /* The following callback functions are available, however the
1197 monitor we are simulating does not make use of them: get_errno,
1198 isatty, rename, system and time. */
1202 case 6: /* int open(char *path,int flags) */
1204 char *path
= fetch_str (sd
, A0
);
1205 V0
= sim_io_open (sd
, path
, (int)A1
);
1210 case 7: /* int read(int file,char *ptr,int len) */
1214 char *buf
= zalloc (nr
);
1215 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1216 sim_write (sd
, A1
, buf
, nr
);
1221 case 8: /* int write(int file,char *ptr,int len) */
1225 char *buf
= zalloc (nr
);
1226 sim_read (sd
, A1
, buf
, nr
);
1227 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1229 sim_io_flush_stdout (sd
);
1231 sim_io_flush_stderr (sd
);
1236 case 10: /* int close(int file) */
1238 V0
= sim_io_close (sd
, (int)A0
);
1242 case 2: /* Densan monitor: char inbyte(int waitflag) */
1244 if (A0
== 0) /* waitflag == NOWAIT */
1245 V0
= (unsigned_word
)-1;
1247 ATTRIBUTE_FALLTHROUGH
;
1249 case 11: /* char inbyte(void) */
1252 /* ensure that all output has gone... */
1253 sim_io_flush_stdout (sd
);
1254 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1256 sim_io_error(sd
,"Invalid return from character read");
1257 V0
= (unsigned_word
)-1;
1260 V0
= (unsigned_word
)tmp
;
1264 case 3: /* Densan monitor: void co(char chr) */
1265 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1267 char tmp
= (char)(A0
& 0xFF);
1268 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1272 case 13: /* int unlink(const char *path) */
1274 char *path
= fetch_str (sd
, A0
);
1275 V0
= sim_io_unlink (sd
, path
);
1280 case 14: /* int lseek(int fd, int offset, int whence) */
1282 V0
= sim_io_lseek (sd
, A0
, A1
, A2
);
1286 case 15: /* int stat(const char *path, struct stat *buf); */
1288 /* As long as the infrastructure doesn't cache anything
1289 related to the stat mapping, this trick gets us a dual
1290 "struct stat"-type mapping in the least error-prone way. */
1291 host_callback
*cb
= STATE_CALLBACK (sd
);
1292 const char *saved_map
= cb
->stat_map
;
1293 CB_TARGET_DEFS_MAP
*saved_syscall_map
= cb
->syscall_map
;
1294 bfd
*prog_bfd
= STATE_PROG_BFD (sd
);
1295 int is_elf32bit
= (elf_elfheader(prog_bfd
)->e_ident
[EI_CLASS
] ==
1297 static CB_SYSCALL s
;
1298 CB_SYSCALL_INIT (&s
);
1300 /* Mask out the sign extension part for 64-bit targets because the
1301 MIPS simulator's memory model is still 32-bit. */
1302 s
.arg1
= A0
& 0xFFFFFFFF;
1303 s
.arg2
= A1
& 0xFFFFFFFF;
1306 s
.read_mem
= sim_syscall_read_mem
;
1307 s
.write_mem
= sim_syscall_write_mem
;
1309 cb
->syscall_map
= (CB_TARGET_DEFS_MAP
*) CB_stat_map
;
1310 cb
->stat_map
= is_elf32bit
? stat32_map
: stat64_map
;
1312 if (cb_syscall (cb
, &s
) != CB_RC_OK
)
1313 sim_engine_halt (sd
, cpu
, NULL
, mips_pc_get (cpu
),
1314 sim_stopped
, SIM_SIGILL
);
1317 cb
->stat_map
= saved_map
;
1318 cb
->syscall_map
= saved_syscall_map
;
1322 case 17: /* void _exit() */
1324 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1325 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1326 (unsigned int)(A0
& 0xFFFFFFFF));
1330 case 28: /* PMON flush_cache */
1333 case 55: /* void get_mem_info(unsigned int *ptr) */
1334 /* in: A0 = pointer to three word memory location */
1335 /* out: [A0 + 0] = size */
1336 /* [A0 + 4] = instruction cache size */
1337 /* [A0 + 8] = data cache size */
1340 unsigned_4 zero
= 0;
1341 address_word mem_size
;
1342 sim_memopt
*entry
, *match
= NULL
;
1344 /* Search for memory region mapped to KSEG0 or KSEG1. */
1345 for (entry
= STATE_MEMOPT (sd
);
1347 entry
= entry
->next
)
1349 if ((entry
->addr
== K0BASE
|| entry
->addr
== K1BASE
)
1350 && (!match
|| entry
->level
< match
->level
))
1355 for (alias
= entry
->alias
;
1357 alias
= alias
->next
)
1358 if ((alias
->addr
== K0BASE
|| alias
->addr
== K1BASE
)
1359 && (!match
|| entry
->level
< match
->level
))
1364 /* Get region size, limit to KSEG1 size (512MB). */
1365 SIM_ASSERT (match
!= NULL
);
1366 mem_size
= (match
->modulo
!= 0
1367 ? match
->modulo
: match
->nr_bytes
);
1368 if (mem_size
> K1SIZE
)
1373 sim_write (sd
, A0
+ 0, &value
, 4);
1374 sim_write (sd
, A0
+ 4, &zero
, 4);
1375 sim_write (sd
, A0
+ 8, &zero
, 4);
1376 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1380 case 158: /* PMON printf */
1381 /* in: A0 = pointer to format string */
1382 /* A1 = optional argument 1 */
1383 /* A2 = optional argument 2 */
1384 /* A3 = optional argument 3 */
1386 /* The following is based on the PMON printf source */
1388 address_word s
= A0
;
1390 address_word
*ap
= &A1
; /* 1st argument */
1391 /* This isn't the quickest way, since we call the host print
1392 routine for every character almost. But it does avoid
1393 having to allocate and manage a temporary string buffer. */
1394 /* TODO: Include check that we only use three arguments (A1,
1396 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1401 /* The format logic isn't passed down.
1402 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1404 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1405 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1407 if (strchr ("dobxXulscefg%", c
))
1410 /* fmt = FMT_LJUST */;
1412 /* fmt = FMT_RJUST0 */;
1414 /* fmt = FMT_CENTER */;
1422 else if (c
>= '1' && c
<= '9')
1426 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1429 n
= (unsigned int)strtol(tmp
,NULL
,10);
1442 sim_io_printf (sd
, "%%");
1447 address_word p
= *ap
++;
1449 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1450 sim_io_printf(sd
, "%c", ch
);
1453 sim_io_printf(sd
,"(null)");
1456 sim_io_printf (sd
, "%c", (int)*ap
++);
1461 sim_read (sd
, s
++, &c
, 1);
1465 sim_read (sd
, s
++, &c
, 1);
1468 if (strchr ("dobxXu", c
))
1470 word64 lv
= (word64
) *ap
++;
1472 sim_io_printf(sd
,"<binary not supported>");
1475 #define P_(c, fmt64, fmt32) \
1478 sim_io_printf (sd, "%" fmt64, lv); \
1480 sim_io_printf (sd, "%" fmt32, (int)lv); \
1482 #define P(c, fmtc) P_(c, PRI##fmtc##64, PRI##fmtc##32)
1495 else if (strchr ("eEfgG", c
))
1497 double dbl
= *(double*)(ap
++);
1499 #define P(c, fmtc) \
1501 sim_io_printf (sd, "%*.*" #fmtc, width, trunc, dbl); \
1517 sim_io_printf(sd
, "%c", c
);
1523 /* Unknown reason. */
1529 /* Store a word into memory. */
1532 store_word (SIM_DESC sd
,
1538 address_word paddr
= vaddr
;
1540 if ((vaddr
& 3) != 0)
1541 SignalExceptionAddressStore ();
1544 const uword64 mask
= 7;
1548 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1549 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1550 memval
= ((uword64
) val
) << (8 * byte
);
1551 StoreMemory (AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1556 #define MIPSR6_P(abfd) \
1557 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6 \
1558 || (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == EF_MIPS_ARCH_64R6)
1560 /* Load a word from memory. */
1563 load_word (SIM_DESC sd
,
1568 if ((vaddr
& 3) != 0 && !MIPSR6_P (STATE_PROG_BFD (sd
)))
1570 SIM_CORE_SIGNAL (SD
, cpu
, cia
, read_map
, AccessLength_WORD
+1, vaddr
, read_transfer
, sim_core_unaligned_signal
);
1574 address_word paddr
= vaddr
;
1575 const uword64 mask
= 0x7;
1576 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1577 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1581 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1582 LoadMemory (&memval
, NULL
, AccessLength_WORD
, paddr
, vaddr
, isDATA
,
1584 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1585 return EXTEND32 (memval
>> (8 * byte
));
1591 /* Simulate the mips16 entry and exit pseudo-instructions. These
1592 would normally be handled by the reserved instruction exception
1593 code, but for ease of simulation we just handle them directly. */
1596 mips16_entry (SIM_DESC sd
,
1601 int aregs
, sregs
, rreg
;
1604 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1607 aregs
= (insn
& 0x700) >> 8;
1608 sregs
= (insn
& 0x0c0) >> 6;
1609 rreg
= (insn
& 0x020) >> 5;
1611 /* This should be checked by the caller. */
1620 /* This is the entry pseudo-instruction. */
1622 for (i
= 0; i
< aregs
; i
++)
1623 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1631 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1634 for (i
= 0; i
< sregs
; i
++)
1637 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1645 /* This is the exit pseudo-instruction. */
1652 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1655 for (i
= 0; i
< sregs
; i
++)
1658 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1663 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1667 FGR
[0] = WORD64LO (GPR
[4]);
1668 FPR_STATE
[0] = fmt_uninterpreted
;
1670 else if (aregs
== 6)
1672 FGR
[0] = WORD64LO (GPR
[5]);
1673 FGR
[1] = WORD64LO (GPR
[4]);
1674 FPR_STATE
[0] = fmt_uninterpreted
;
1675 FPR_STATE
[1] = fmt_uninterpreted
;
1684 /*-- trace support ----------------------------------------------------------*/
1686 /* The trace support is provided (if required) in the memory accessing
1687 routines. Since we are also providing the architecture specific
1688 features, the architecture simulation code can also deal with
1689 notifying the trace world of cache flushes, etc. Similarly we do
1690 not need to provide profiling support in the simulator engine,
1691 since we can sample in the instruction fetch control loop. By
1692 defining the trace manifest, we add tracing as a run-time
1695 #if WITH_TRACE_ANY_P
1696 /* Tracing by default produces "din" format (as required by
1697 dineroIII). Each line of such a trace file *MUST* have a din label
1698 and address field. The rest of the line is ignored, so comments can
1699 be included if desired. The first field is the label which must be
1700 one of the following values:
1705 3 escape record (treated as unknown access type)
1706 4 escape record (causes cache flush)
1708 The address field is a 32bit (lower-case) hexadecimal address
1709 value. The address should *NOT* be preceded by "0x".
1711 The size of the memory transfer is not important when dealing with
1712 cache lines (as long as no more than a cache line can be
1713 transferred in a single operation :-), however more information
1714 could be given following the dineroIII requirement to allow more
1715 complete memory and cache simulators to provide better
1716 results. i.e. the University of Pisa has a cache simulator that can
1717 also take bus size and speed as (variable) inputs to calculate
1718 complete system performance (a much more useful ability when trying
1719 to construct an end product, rather than a processor). They
1720 currently have an ARM version of their tool called ChARM. */
1724 dotrace (SIM_DESC sd
,
1728 address_word address
,
1730 const char *comment
, ...)
1732 if (STATE
& simTRACE
) {
1734 fprintf(tracefh
,"%d %s ; width %d ; ",
1738 va_start(ap
,comment
);
1739 vfprintf(tracefh
,comment
,ap
);
1741 fprintf(tracefh
,"\n");
1743 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1744 we may be generating 64bit ones, we should put the hi-32bits of the
1745 address into the comment field. */
1747 /* TODO: Provide a buffer for the trace lines. We can then avoid
1748 performing writes until the buffer is filled, or the file is
1751 /* NOTE: We could consider adding a comment field to the "din" file
1752 produced using type 3 markers (unknown access). This would then
1753 allow information about the program that the "din" is for, and
1754 the MIPs world that was being simulated, to be placed into the
1759 #endif /* WITH_TRACE_ANY_P */
1761 /*---------------------------------------------------------------------------*/
1762 /*-- simulator engine -------------------------------------------------------*/
1763 /*---------------------------------------------------------------------------*/
1766 ColdReset (SIM_DESC sd
)
1769 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1771 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1772 /* RESET: Fixed PC address: */
1773 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1774 /* The reset vector address is in the unmapped, uncached memory space. */
1776 SR
&= ~(status_SR
| status_TS
| status_RP
);
1777 SR
|= (status_ERL
| status_BEV
);
1779 /* Cheat and allow access to the complete register set immediately */
1780 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1781 && WITH_TARGET_WORD_BITSIZE
== 64)
1782 SR
|= status_FR
; /* 64bit registers */
1784 /* Ensure that any instructions with pending register updates are
1786 PENDING_INVALIDATE();
1788 /* Initialise the FPU registers to the unknown state */
1789 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1792 for (rn
= 0; (rn
< 32); rn
++)
1793 FPR_STATE
[rn
] = fmt_uninterpreted
;
1796 /* Initialise the Config0 register. */
1797 C0_CONFIG
= 0x80000000 /* Config1 present */
1798 | 2; /* KSEG0 uncached */
1799 if (WITH_TARGET_WORD_BITSIZE
== 64)
1801 /* FIXME Currently mips/sim-main.c:address_translation()
1802 truncates all addresses to 32-bits. */
1803 if (0 && WITH_TARGET_ADDRESS_BITSIZE
== 64)
1804 C0_CONFIG
|= (2 << 13); /* MIPS64, 64-bit addresses */
1806 C0_CONFIG
|= (1 << 13); /* MIPS64, 32-bit addresses */
1809 C0_CONFIG
|= 0x00008000; /* Big Endian */
1816 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1817 /* Signal an exception condition. This will result in an exception
1818 that aborts the instruction. The instruction operation pseudocode
1819 will never see a return from this function call. */
1822 signal_exception (SIM_DESC sd
,
1830 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1833 /* Ensure that any active atomic read/modify/write operation will fail: */
1836 /* Save registers before interrupt dispatching */
1837 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1838 SIM_CPU_EXCEPTION_TRIGGER(sd
, cpu
, cia
);
1841 switch (exception
) {
1843 case DebugBreakPoint
:
1844 if (! (Debug
& Debug_DM
))
1850 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1851 DEPC
= cia
- 4; /* reference the branch instruction */
1855 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1859 Debug
|= Debug_DM
; /* in debugging mode */
1860 Debug
|= Debug_DBp
; /* raising a DBp exception */
1862 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1866 case ReservedInstruction
:
1869 unsigned int instruction
;
1870 va_start(ap
,exception
);
1871 instruction
= va_arg(ap
,unsigned int);
1873 /* Provide simple monitor support using ReservedInstruction
1874 exceptions. The following code simulates the fixed vector
1875 entry points into the IDT monitor by causing a simulator
1876 trap, performing the monitor operation, and returning to
1877 the address held in the $ra register (standard PCS return
1878 address). This means we only need to pre-load the vector
1879 space with suitable instruction values. For systems were
1880 actual trap instructions are used, we would not need to
1881 perform this magic. */
1882 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1884 int reason
= (instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
;
1885 if (!sim_monitor (SD
, CPU
, cia
, reason
))
1886 sim_io_error (sd
, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason
, pr_addr (cia
));
1888 /* NOTE: This assumes that a branch-and-link style
1889 instruction was used to enter the vector (which is the
1890 case with the current IDT monitor). */
1891 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1893 /* Look for the mips16 entry and exit instructions, and
1894 simulate a handler for them. */
1895 else if ((cia
& 1) != 0
1896 && (instruction
& 0xf81f) == 0xe809
1897 && (instruction
& 0x0c0) != 0x0c0)
1899 mips16_entry (SD
, CPU
, cia
, instruction
);
1900 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1902 /* else fall through to normal exception processing */
1903 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1904 ATTRIBUTE_FALLTHROUGH
;
1908 /* Store exception code into current exception id variable (used
1911 /* TODO: If not simulating exceptions then stop the simulator
1912 execution. At the moment we always stop the simulation. */
1914 #ifdef SUBTARGET_R3900
1915 /* update interrupt-related registers */
1917 /* insert exception code in bits 6:2 */
1918 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1919 /* shift IE/KU history bits left */
1920 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1922 if (STATE
& simDELAYSLOT
)
1924 STATE
&= ~simDELAYSLOT
;
1926 EPC
= (cia
- 4); /* reference the branch instruction */
1931 if (SR
& status_BEV
)
1932 PC
= (signed)0xBFC00000 + 0x180;
1934 PC
= (signed)0x80000000 + 0x080;
1936 /* See figure 5-17 for an outline of the code below */
1937 if (! (SR
& status_EXL
))
1939 CAUSE
= (exception
<< 2);
1940 if (STATE
& simDELAYSLOT
)
1942 STATE
&= ~simDELAYSLOT
;
1944 EPC
= (cia
- 4); /* reference the branch instruction */
1948 /* FIXME: TLB et.al. */
1949 /* vector = 0x180; */
1953 CAUSE
= (exception
<< 2);
1954 /* vector = 0x180; */
1957 /* Store exception code into current exception id variable (used
1960 if (SR
& status_BEV
)
1961 PC
= (signed)0xBFC00200 + 0x180;
1963 PC
= (signed)0x80000000 + 0x180;
1966 switch ((CAUSE
>> 2) & 0x1F)
1969 /* Interrupts arrive during event processing, no need to
1975 #ifdef SUBTARGET_3900
1976 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1977 PC
= (signed)0xBFC00000;
1978 #endif /* SUBTARGET_3900 */
1981 case TLBModification
:
1986 case InstructionFetch
:
1988 /* The following is so that the simulator will continue from the
1989 exception handler address. */
1990 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1991 sim_stopped
, SIM_SIGBUS
);
1993 case ReservedInstruction
:
1994 case CoProcessorUnusable
:
1996 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1997 sim_stopped
, SIM_SIGILL
);
1999 case IntegerOverflow
:
2001 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2002 sim_stopped
, SIM_SIGFPE
);
2005 sim_engine_halt (SD
, CPU
, NULL
, PC
, sim_stopped
, SIM_SIGTRAP
);
2010 sim_engine_restart (SD
, CPU
, NULL
, PC
);
2015 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2016 sim_stopped
, SIM_SIGTRAP
);
2018 default: /* Unknown internal exception */
2020 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2021 sim_stopped
, SIM_SIGABRT
);
2025 case SimulatorFault
:
2029 va_start(ap
,exception
);
2030 msg
= va_arg(ap
,char *);
2032 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2033 "FATAL: Simulator error \"%s\"\n",msg
);
2042 /* This function implements what the MIPS32 and MIPS64 ISAs define as
2043 "UNPREDICTABLE" behaviour.
2045 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2046 may vary from processor implementation to processor implementation,
2047 instruction to instruction, or as a function of time on the same
2048 implementation or instruction. Software can never depend on results
2049 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
2050 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
2053 For UNPREDICTABLE behaviour, we print a message, if possible print
2054 the offending instructions mips.igen instruction name (provided by
2055 the caller), and stop the simulator.
2057 XXX FIXME: eventually, stopping the simulator should be made conditional
2058 on a command-line option. */
2060 unpredictable_action(sim_cpu
*cpu
, address_word cia
)
2062 SIM_DESC sd
= CPU_STATE(cpu
);
2064 sim_io_eprintf(sd
, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia
));
2065 sim_engine_halt (SD
, CPU
, NULL
, cia
, sim_stopped
, SIM_SIGABRT
);
2069 /*-- co-processor support routines ------------------------------------------*/
2072 CoProcPresent(unsigned int coproc_number
)
2074 /* Return TRUE if simulator provides a model for the given co-processor number */
2079 cop_lw (SIM_DESC sd
,
2084 unsigned int memword
)
2089 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2092 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
2094 StoreFPR(coproc_reg
,fmt_uninterpreted_32
,(uword64
)memword
);
2099 #if 0 /* this should be controlled by a configuration option */
2100 sim_io_printf(sd
,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,memword
,pr_addr(cia
));
2109 cop_ld (SIM_DESC sd
,
2118 printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num
, coproc_reg
, pr_uword64(memword
), pr_addr(cia
));
2121 switch (coproc_num
) {
2123 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2125 StoreFPR(coproc_reg
,fmt_uninterpreted_64
,memword
);
2130 #if 0 /* this message should be controlled by a configuration option */
2131 sim_io_printf(sd
,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(memword
),pr_addr(cia
));
2143 cop_sw (SIM_DESC sd
,
2149 unsigned int value
= 0;
2154 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2156 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted_32
);
2161 #if 0 /* should be controlled by configuration option */
2162 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
2171 cop_sd (SIM_DESC sd
,
2181 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2183 value
= ValueFPR(coproc_reg
,fmt_uninterpreted_64
);
2188 #if 0 /* should be controlled by configuration option */
2189 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
2201 decode_coproc (SIM_DESC sd
,
2204 unsigned int instruction
,
2213 case 0: /* standard CPU control and cache registers */
2215 /* R4000 Users Manual (second edition) lists the following CP0
2217 CODE><-RT><RD-><--TAIL--->
2218 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2219 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2220 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2221 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2222 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2223 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2224 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2225 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2226 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2227 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2229 if (((op
== cp0_mfc0
) || (op
== cp0_mtc0
) /* MFC0 / MTC0 */
2230 || (op
== cp0_dmfc0
) || (op
== cp0_dmtc0
)) /* DMFC0 / DMTC0 */
2233 switch (rd
) /* NOTEs: Standard CP0 registers */
2235 /* 0 = Index R4000 VR4100 VR4300 */
2236 /* 1 = Random R4000 VR4100 VR4300 */
2237 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
2238 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
2239 /* 4 = Context R4000 VR4100 VR4300 */
2240 /* 5 = PageMask R4000 VR4100 VR4300 */
2241 /* 6 = Wired R4000 VR4100 VR4300 */
2242 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2243 /* 9 = Count R4000 VR4100 VR4300 */
2244 /* 10 = EntryHi R4000 VR4100 VR4300 */
2245 /* 11 = Compare R4000 VR4100 VR4300 */
2246 /* 12 = SR R4000 VR4100 VR4300 */
2247 #ifdef SUBTARGET_R3900
2249 /* 3 = Config R3900 */
2251 /* 7 = Cache R3900 */
2253 /* 15 = PRID R3900 */
2259 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2260 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2261 GPR
[rt
] = (signed_word
) (signed_address
) COP0_BADVADDR
;
2263 COP0_BADVADDR
= GPR
[rt
];
2266 #endif /* SUBTARGET_R3900 */
2268 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2273 /* 13 = Cause R4000 VR4100 VR4300 */
2275 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2280 /* 14 = EPC R4000 VR4100 VR4300 */
2282 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2283 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
2287 /* 15 = PRId R4000 VR4100 VR4300 */
2288 #ifdef SUBTARGET_R3900
2291 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2297 /* 16 = Config R4000 VR4100 VR4300 */
2299 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2300 GPR
[rt
] = C0_CONFIG
;
2302 /* only bottom three bits are writable */
2303 C0_CONFIG
= (C0_CONFIG
& ~0x7) | (GPR
[rt
] & 0x7);
2306 #ifdef SUBTARGET_R3900
2309 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2315 /* 17 = LLAddr R4000 VR4100 VR4300 */
2317 /* 18 = WatchLo R4000 VR4100 VR4300 */
2318 /* 19 = WatchHi R4000 VR4100 VR4300 */
2319 /* 20 = XContext R4000 VR4100 VR4300 */
2320 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2321 /* 27 = CacheErr R4000 VR4100 */
2322 /* 28 = TagLo R4000 VR4100 VR4300 */
2323 /* 29 = TagHi R4000 VR4100 VR4300 */
2324 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
2325 if (STATE_VERBOSE_P(SD
))
2327 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2328 (unsigned long)cia
);
2329 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
2330 ATTRIBUTE_FALLTHROUGH
;
2331 /* CPR[0,rd] = GPR[rt]; */
2333 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2334 GPR
[rt
] = (signed_word
) (int32_t) COP0_GPR
[rd
];
2336 COP0_GPR
[rd
] = GPR
[rt
];
2339 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
2341 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
2345 else if ((op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2348 /* [D]MFC0 RT,C0_CONFIG,SEL */
2356 /* MIPS32 r/o Config1:
2359 /* MIPS16 implemented.
2360 XXX How to check configuration? */
2362 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2363 /* MDMX & FPU implemented */
2367 /* MIPS32 r/o Config2:
2372 /* MIPS32 r/o Config3:
2373 SmartMIPS implemented. */
2379 else if (op
== cp0_eret
&& sel
== 0x18)
2382 if (SR
& status_ERL
)
2384 /* Oops, not yet available */
2385 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
2395 else if (op
== cp0_rfe
&& sel
== 0x10)
2398 #ifdef SUBTARGET_R3900
2399 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2401 /* shift IE/KU history bits right */
2402 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
2404 /* TODO: CACHE register */
2405 #endif /* SUBTARGET_R3900 */
2407 else if (op
== cp0_deret
&& sel
== 0x1F)
2415 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
2416 /* TODO: When executing an ERET or RFE instruction we should
2417 clear LLBIT, to ensure that any out-standing atomic
2418 read/modify/write sequence fails. */
2422 case 2: /* co-processor 2 */
2429 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2430 instruction
,pr_addr(cia
));
2435 case 1: /* should not occur (FPU co-processor) */
2436 case 3: /* should not occur (FPU co-processor) */
2437 SignalException(ReservedInstruction
,instruction
);
2445 /* This code copied from gdb's utils.c. Would like to share this code,
2446 but don't know of a common place where both could get to it. */
2448 /* Temporary storage using circular buffer */
2454 static char buf
[NUMCELLS
][CELLSIZE
];
2456 if (++cell
>=NUMCELLS
) cell
=0;
2460 /* Print routines to handle variable size regs, etc */
2463 pr_addr (address_word addr
)
2465 char *paddr_str
=get_cell();
2466 sprintf (paddr_str
, "%0*" PRIxTA
, (int) (sizeof (addr
) * 2), addr
);
2471 pr_uword64 (uword64 addr
)
2473 char *paddr_str
=get_cell();
2474 sprintf (paddr_str
, "%016" PRIx64
, addr
);
2480 mips_core_signal (SIM_DESC sd
,
2486 transfer_type transfer
,
2487 sim_core_signals sig
)
2489 const char *copy
= (transfer
== read_transfer
? "read" : "write");
2490 address_word ip
= CIA_ADDR (cia
);
2494 case sim_core_unmapped_signal
:
2495 sim_io_eprintf (sd
, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2497 (unsigned long) addr
, (unsigned long) ip
);
2498 COP0_BADVADDR
= addr
;
2499 SignalExceptionDataReference();
2500 /* Shouldn't actually be reached. */
2503 case sim_core_unaligned_signal
:
2504 sim_io_eprintf (sd
, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
2506 (unsigned long) addr
, (unsigned long) ip
);
2507 COP0_BADVADDR
= addr
;
2508 if (transfer
== read_transfer
)
2509 SignalExceptionAddressLoad();
2511 SignalExceptionAddressStore();
2512 /* Shouldn't actually be reached. */
2516 sim_engine_abort (sd
, cpu
, cia
,
2517 "mips_core_signal - internal error - bad switch");
2523 mips_cpu_exception_trigger(SIM_DESC sd
, sim_cpu
* cpu
, address_word cia
)
2525 struct mips_sim_cpu
*mips_cpu
= MIPS_SIM_CPU (cpu
);
2527 ASSERT(cpu
!= NULL
);
2529 if (mips_cpu
->exc_suspended
> 0)
2530 sim_io_eprintf (sd
, "Warning, nested exception triggered (%d)\n",
2531 mips_cpu
->exc_suspended
);
2534 memcpy (mips_cpu
->exc_trigger_registers
, mips_cpu
->registers
,
2535 sizeof (mips_cpu
->exc_trigger_registers
));
2536 mips_cpu
->exc_suspended
= 0;
2540 mips_cpu_exception_suspend(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
2542 struct mips_sim_cpu
*mips_cpu
= MIPS_SIM_CPU (cpu
);
2544 ASSERT(cpu
!= NULL
);
2546 if (mips_cpu
->exc_suspended
> 0)
2547 sim_io_eprintf(sd
, "Warning, nested exception signal (%d then %d)\n",
2548 mips_cpu
->exc_suspended
, exception
);
2550 memcpy (mips_cpu
->exc_suspend_registers
, mips_cpu
->registers
,
2551 sizeof (mips_cpu
->exc_suspend_registers
));
2552 memcpy (mips_cpu
->registers
, mips_cpu
->exc_trigger_registers
,
2553 sizeof (mips_cpu
->registers
));
2554 mips_cpu
->exc_suspended
= exception
;
2558 mips_cpu_exception_resume(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
2560 struct mips_sim_cpu
*mips_cpu
= MIPS_SIM_CPU (cpu
);
2562 ASSERT(cpu
!= NULL
);
2564 if (exception
== 0 && mips_cpu
->exc_suspended
> 0)
2566 /* warn not for breakpoints */
2567 if (mips_cpu
->exc_suspended
!= sim_signal_to_host(sd
, SIM_SIGTRAP
))
2568 sim_io_eprintf(sd
, "Warning, resuming but ignoring pending exception signal (%d)\n",
2569 mips_cpu
->exc_suspended
);
2571 else if (exception
!= 0 && mips_cpu
->exc_suspended
> 0)
2573 if (exception
!= mips_cpu
->exc_suspended
)
2574 sim_io_eprintf(sd
, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2575 mips_cpu
->exc_suspended
, exception
);
2577 memcpy (mips_cpu
->registers
, mips_cpu
->exc_suspend_registers
,
2578 sizeof (mips_cpu
->registers
));
2580 else if (exception
!= 0 && mips_cpu
->exc_suspended
== 0)
2582 sim_io_eprintf(sd
, "Warning, ignoring spontanous exception signal (%d)\n", exception
);
2584 mips_cpu
->exc_suspended
= 0;
2588 /*---------------------------------------------------------------------------*/
2589 /*> EOF interp.c <*/