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
28 #include "sim-utils.h"
29 #include "sim-options.h"
30 #include "sim-assert.h"
56 #include "libiberty.h"
58 #include "gdb/callback.h" /* GDB simulator callback interface */
59 #include "gdb/remote-sim.h" /* GDB simulator interface */
61 char* pr_addr (SIM_ADDR addr
);
62 char* pr_uword64 (uword64 addr
);
65 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
70 /* The following reserved instruction value is used when a simulator
71 trap is required. NOTE: Care must be taken, since this value may be
72 used in later revisions of the MIPS ISA. */
74 #define RSVD_INSTRUCTION (0x00000039)
75 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
77 #define RSVD_INSTRUCTION_ARG_SHIFT 6
78 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
81 /* Bits in the Debug register */
82 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
83 #define Debug_DM 0x40000000 /* Debug Mode */
84 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
86 /*---------------------------------------------------------------------------*/
87 /*-- GDB simulator interface ------------------------------------------------*/
88 /*---------------------------------------------------------------------------*/
90 static void ColdReset (SIM_DESC sd
);
92 /*---------------------------------------------------------------------------*/
96 #define DELAYSLOT() {\
97 if (STATE & simDELAYSLOT)\
98 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
99 STATE |= simDELAYSLOT;\
102 #define JALDELAYSLOT() {\
104 STATE |= simJALDELAYSLOT;\
108 STATE &= ~simDELAYSLOT;\
109 STATE |= simSKIPNEXT;\
112 #define CANCELDELAYSLOT() {\
114 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
117 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
118 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
120 /* Note that the monitor code essentially assumes this layout of memory.
121 If you change these, change the monitor code, too. */
122 /* FIXME Currently addresses are truncated to 32-bits, see
123 mips/sim-main.c:address_translation(). If that changes, then these
124 values will need to be extended, and tested for more carefully. */
125 #define K0BASE (0x80000000)
126 #define K0SIZE (0x20000000)
127 #define K1BASE (0xA0000000)
128 #define K1SIZE (0x20000000)
130 /* Simple run-time monitor support.
132 We emulate the monitor by placing magic reserved instructions at
133 the monitor's entry points; when we hit these instructions, instead
134 of raising an exception (as we would normally), we look at the
135 instruction and perform the appropriate monitory operation.
137 `*_monitor_base' are the physical addresses at which the corresponding
138 monitor vectors are located. `0' means none. By default,
140 The RSVD_INSTRUCTION... macros specify the magic instructions we
141 use at the monitor entry points. */
142 static int firmware_option_p
= 0;
143 static SIM_ADDR idt_monitor_base
= 0xBFC00000;
144 static SIM_ADDR pmon_monitor_base
= 0xBFC00500;
145 static SIM_ADDR lsipmon_monitor_base
= 0xBFC00200;
147 static SIM_RC
sim_firmware_command (SIM_DESC sd
, char* arg
);
149 #define MEM_SIZE (8 << 20) /* 8 MBytes */
153 static char *tracefile
= "trace.din"; /* default filename for trace log */
154 FILE *tracefh
= NULL
;
155 static void open_trace (SIM_DESC sd
);
157 #define open_trace(sd)
160 static const char * get_insn_name (sim_cpu
*, int);
162 /* simulation target board. NULL=canonical */
163 static char* board
= NULL
;
166 static DECLARE_OPTION_HANDLER (mips_option_handler
);
169 OPTION_DINERO_TRACE
= OPTION_START
,
176 static int display_mem_info
= 0;
179 mips_option_handler (SIM_DESC sd
, sim_cpu
*cpu
, int opt
, char *arg
,
185 case OPTION_DINERO_TRACE
: /* ??? */
187 /* Eventually the simTRACE flag could be treated as a toggle, to
188 allow external control of the program points being traced
189 (i.e. only from main onwards, excluding the run-time setup,
191 for (cpu_nr
= 0; cpu_nr
< MAX_NR_PROCESSORS
; cpu_nr
++)
193 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
196 else if (strcmp (arg
, "yes") == 0)
198 else if (strcmp (arg
, "no") == 0)
200 else if (strcmp (arg
, "on") == 0)
202 else if (strcmp (arg
, "off") == 0)
206 fprintf (stderr
, "Unrecognized dinero-trace option `%s'\n", arg
);
211 #else /* !WITH_TRACE_ANY_P */
213 Simulator constructed without dinero tracing support (for performance).\n\
214 Re-compile simulator with \"-DWITH_TRACE_ANY_P\" to enable this option.\n");
216 #endif /* !WITH_TRACE_ANY_P */
218 case OPTION_DINERO_FILE
:
220 if (optarg
!= NULL
) {
222 tmp
= (char *)malloc(strlen(optarg
) + 1);
225 sim_io_printf(sd
,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg
);
231 sim_io_printf(sd
,"Placing trace information into file \"%s\"\n",tracefile
);
234 #endif /* WITH_TRACE_ANY_P */
237 case OPTION_FIRMWARE
:
238 return sim_firmware_command (sd
, arg
);
244 board
= zalloc(strlen(arg
) + 1);
250 case OPTION_INFO_MEMORY
:
251 display_mem_info
= 1;
259 static const OPTION mips_options
[] =
261 { {"dinero-trace", optional_argument
, NULL
, OPTION_DINERO_TRACE
},
262 '\0', "on|off", "Enable dinero tracing",
263 mips_option_handler
},
264 { {"dinero-file", required_argument
, NULL
, OPTION_DINERO_FILE
},
265 '\0', "FILE", "Write dinero trace to FILE",
266 mips_option_handler
},
267 { {"firmware", required_argument
, NULL
, OPTION_FIRMWARE
},
268 '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
269 mips_option_handler
},
270 { {"board", required_argument
, NULL
, OPTION_BOARD
},
271 '\0', "none" /* rely on compile-time string concatenation for other options */
273 #define BOARD_JMR3904 "jmr3904"
275 #define BOARD_JMR3904_PAL "jmr3904pal"
276 "|" BOARD_JMR3904_PAL
277 #define BOARD_JMR3904_DEBUG "jmr3904debug"
278 "|" BOARD_JMR3904_DEBUG
279 #define BOARD_BSP "bsp"
282 , "Customize simulation for a particular board.", mips_option_handler
},
284 /* These next two options have the same names as ones found in the
285 memory_options[] array in common/sim-memopt.c. This is because
286 the intention is to provide an alternative handler for those two
287 options. We need an alternative handler because the memory
288 regions are not set up until after the command line arguments
289 have been parsed, and so we cannot display the memory info whilst
290 processing the command line. There is a hack in sim_open to
291 remove these handlers when we want the real --memory-info option
293 { { "info-memory", no_argument
, NULL
, OPTION_INFO_MEMORY
},
294 '\0', NULL
, "List configured memory regions", mips_option_handler
},
295 { { "memory-info", no_argument
, NULL
, OPTION_INFO_MEMORY
},
296 '\0', NULL
, NULL
, mips_option_handler
},
298 { {NULL
, no_argument
, NULL
, 0}, '\0', NULL
, NULL
, NULL
}
302 int interrupt_pending
;
305 interrupt_event (SIM_DESC sd
, void *data
)
307 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
308 address_word cia
= CPU_PC_GET (cpu
);
311 interrupt_pending
= 0;
312 SignalExceptionInterrupt (1); /* interrupt "1" */
314 else if (!interrupt_pending
)
315 sim_events_schedule (sd
, 1, interrupt_event
, data
);
319 /*---------------------------------------------------------------------------*/
320 /*-- Device registration hook -----------------------------------------------*/
321 /*---------------------------------------------------------------------------*/
322 static void device_init(SIM_DESC sd
) {
324 extern void register_devices(SIM_DESC
);
325 register_devices(sd
);
329 /*---------------------------------------------------------------------------*/
330 /*-- GDB simulator interface ------------------------------------------------*/
331 /*---------------------------------------------------------------------------*/
334 mips_pc_get (sim_cpu
*cpu
)
340 mips_pc_set (sim_cpu
*cpu
, sim_cia pc
)
346 sim_open (SIM_OPEN_KIND kind
, host_callback
*cb
, struct bfd
*abfd
, char **argv
)
349 SIM_DESC sd
= sim_state_alloc (kind
, cb
);
352 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
354 /* The cpu data is kept in a separately allocated chunk of memory. */
355 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
358 cpu
= STATE_CPU (sd
, 0); /* FIXME */
360 /* FIXME: watchpoints code shouldn't need this */
361 STATE_WATCHPOINTS (sd
)->pc
= &(PC
);
362 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PC
);
363 STATE_WATCHPOINTS (sd
)->interrupt_handler
= interrupt_event
;
365 /* Initialize the mechanism for doing insn profiling. */
366 CPU_INSN_NAME (cpu
) = get_insn_name
;
367 CPU_MAX_INSNS (cpu
) = nr_itable_entries
;
371 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
373 sim_add_option_table (sd
, NULL
, mips_options
);
376 /* getopt will print the error message so we just have to exit if this fails.
377 FIXME: Hmmm... in the case of gdb we need getopt to call
379 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
381 /* Uninstall the modules to avoid memory leaks,
382 file descriptor leaks, etc. */
383 sim_module_uninstall (sd
);
387 /* handle board-specific memory maps */
390 /* Allocate core managed memory */
391 sim_memopt
*entry
, *match
= NULL
;
392 address_word mem_size
= 0;
395 /* For compatibility with the old code - under this (at level one)
396 are the kernel spaces K0 & K1. Both of these map to a single
397 smaller sub region */
398 sim_do_command(sd
," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
400 /* Look for largest memory region defined on command-line at
402 #ifdef SIM_HAVE_FLATMEM
403 mem_size
= STATE_MEM_SIZE (sd
);
405 for (entry
= STATE_MEMOPT (sd
); entry
!= NULL
; entry
= entry
->next
)
407 /* If we find an entry at address 0, then we will end up
408 allocating a new buffer in the "memory alias" command
409 below. The region at address 0 will be deleted. */
410 address_word size
= (entry
->modulo
!= 0
411 ? entry
->modulo
: entry
->nr_bytes
);
413 && (!match
|| entry
->level
< match
->level
))
415 else if (entry
->addr
== K0BASE
|| entry
->addr
== K1BASE
)
420 for (alias
= entry
->alias
; alias
!= NULL
; alias
= alias
->next
)
423 && (!match
|| entry
->level
< match
->level
))
425 else if (alias
->addr
== K0BASE
|| alias
->addr
== K1BASE
)
435 /* Get existing memory region size. */
436 mem_size
= (match
->modulo
!= 0
437 ? match
->modulo
: match
->nr_bytes
);
438 /* Delete old region. */
439 sim_do_commandf (sd
, "memory delete %d:0x%lx@%d",
440 match
->space
, match
->addr
, match
->level
);
442 else if (mem_size
== 0)
444 /* Limit to KSEG1 size (512MB) */
445 if (mem_size
> K1SIZE
)
447 /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
448 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
449 K1BASE
, K1SIZE
, (long)mem_size
, K0BASE
);
454 else if (board
!= NULL
455 && (strcmp(board
, BOARD_BSP
) == 0))
459 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
461 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
462 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
464 4 * 1024 * 1024, /* 4 MB */
467 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
468 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
470 4 * 1024 * 1024, /* 4 MB */
473 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
474 for (i
=0; i
<8; i
++) /* 32 MB total */
476 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
477 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
478 0x88000000 + (i
* size
),
480 0xA8000000 + (i
* size
));
484 else if (board
!= NULL
485 && (strcmp(board
, BOARD_JMR3904
) == 0 ||
486 strcmp(board
, BOARD_JMR3904_PAL
) == 0 ||
487 strcmp(board
, BOARD_JMR3904_DEBUG
) == 0))
489 /* match VIRTUAL memory layout of JMR-TX3904 board */
492 /* --- disable monitor unless forced on by user --- */
494 if (! firmware_option_p
)
496 idt_monitor_base
= 0;
497 pmon_monitor_base
= 0;
498 lsipmon_monitor_base
= 0;
501 /* --- environment --- */
503 STATE_ENVIRONMENT (sd
) = OPERATING_ENVIRONMENT
;
507 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
508 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
510 4 * 1024 * 1024, /* 4 MB */
513 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
514 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
516 4 * 1024 * 1024, /* 4 MB */
519 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
520 for (i
=0; i
<8; i
++) /* 32 MB total */
522 unsigned size
= 4 * 1024 * 1024; /* 4 MB */
523 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx,0x%0x",
524 0x88000000 + (i
* size
),
526 0xA8000000 + (i
* size
));
529 /* Dummy memory regions for unsimulated devices - sorted by address */
531 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB1000000, 0x400); /* ISA I/O */
532 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB2100000, 0x004); /* ISA ctl */
533 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB2500000, 0x004); /* LED/switch */
534 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB2700000, 0x004); /* RTC */
535 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xB3C00000, 0x004); /* RTC */
536 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFF8000, 0x900); /* DRAMC */
537 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFF9000, 0x200); /* EBIF */
538 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFFE000, 0x01c); /* EBIF */
539 sim_do_commandf (sd
, "memory alias 0x%lx@1,0x%lx", 0xFFFFF500, 0x300); /* PIO */
542 /* --- simulated devices --- */
543 sim_hw_parse (sd
, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
544 sim_hw_parse (sd
, "/tx3904cpu");
545 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
546 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
547 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
548 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
550 /* FIXME: poking at dv-sockser internals, use tcp backend if
551 --sockser_addr option was given.*/
552 extern char* sockser_addr
;
553 if(sockser_addr
== NULL
)
554 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend stdio");
556 sim_hw_parse (sd
, "/tx3904sio@0xfffff300/backend tcp");
558 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
559 sim_hw_parse (sd
, "/tx3904sio@0xfffff400/backend stdio");
561 /* -- device connections --- */
562 sim_hw_parse (sd
, "/tx3904irc > ip level /tx3904cpu");
563 sim_hw_parse (sd
, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
564 sim_hw_parse (sd
, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
565 sim_hw_parse (sd
, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
566 sim_hw_parse (sd
, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
567 sim_hw_parse (sd
, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
569 /* add PAL timer & I/O module */
570 if(! strcmp(board
, BOARD_JMR3904_PAL
))
573 sim_hw_parse (sd
, "/pal@0xffff0000");
574 sim_hw_parse (sd
, "/pal@0xffff0000/reg 0xffff0000 64");
576 /* wire up interrupt ports to irc */
577 sim_hw_parse (sd
, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
578 sim_hw_parse (sd
, "/pal@0x31000000 > timer tmr1 /tx3904irc");
579 sim_hw_parse (sd
, "/pal@0x31000000 > int int0 /tx3904irc");
582 if(! strcmp(board
, BOARD_JMR3904_DEBUG
))
584 /* -- DEBUG: glue interrupt generators --- */
585 sim_hw_parse (sd
, "/glue@0xffff0000/reg 0xffff0000 0x50");
586 sim_hw_parse (sd
, "/glue@0xffff0000 > int0 int0 /tx3904irc");
587 sim_hw_parse (sd
, "/glue@0xffff0000 > int1 int1 /tx3904irc");
588 sim_hw_parse (sd
, "/glue@0xffff0000 > int2 int2 /tx3904irc");
589 sim_hw_parse (sd
, "/glue@0xffff0000 > int3 int3 /tx3904irc");
590 sim_hw_parse (sd
, "/glue@0xffff0000 > int4 int4 /tx3904irc");
591 sim_hw_parse (sd
, "/glue@0xffff0000 > int5 int5 /tx3904irc");
592 sim_hw_parse (sd
, "/glue@0xffff0000 > int6 int6 /tx3904irc");
593 sim_hw_parse (sd
, "/glue@0xffff0000 > int7 int7 /tx3904irc");
594 sim_hw_parse (sd
, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
595 sim_hw_parse (sd
, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
596 sim_hw_parse (sd
, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
597 sim_hw_parse (sd
, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
598 sim_hw_parse (sd
, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
599 sim_hw_parse (sd
, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
600 sim_hw_parse (sd
, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
601 sim_hw_parse (sd
, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
602 sim_hw_parse (sd
, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
603 sim_hw_parse (sd
, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
610 if (display_mem_info
)
612 struct option_list
* ol
;
613 struct option_list
* prev
;
615 /* This is a hack. We want to execute the real --memory-info command
616 line switch which is handled in common/sim-memopts.c, not the
617 override we have defined in this file. So we remove the
618 mips_options array from the state options list. This is safe
619 because we have now processed all of the command line. */
620 for (ol
= STATE_OPTIONS (sd
), prev
= NULL
;
622 prev
= ol
, ol
= ol
->next
)
623 if (ol
->options
== mips_options
)
626 SIM_ASSERT (ol
!= NULL
);
629 STATE_OPTIONS (sd
) = ol
->next
;
631 prev
->next
= ol
->next
;
633 sim_do_commandf (sd
, "memory-info");
636 /* check for/establish the a reference program image */
637 if (sim_analyze_program (sd
,
638 (STATE_PROG_ARGV (sd
) != NULL
639 ? *STATE_PROG_ARGV (sd
)
643 sim_module_uninstall (sd
);
647 /* Configure/verify the target byte order and other runtime
648 configuration options */
649 if (sim_config (sd
) != SIM_RC_OK
)
651 sim_module_uninstall (sd
);
655 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
657 /* Uninstall the modules to avoid memory leaks,
658 file descriptor leaks, etc. */
659 sim_module_uninstall (sd
);
663 /* verify assumptions the simulator made about the host type system.
664 This macro does not return if there is a problem */
665 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
666 SIM_ASSERT (sizeof(word64
) == (8 * sizeof(char)));
668 /* This is NASTY, in that we are assuming the size of specific
672 for (rn
= 0; (rn
< (LAST_EMBED_REGNUM
+ 1)); rn
++)
675 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
676 else if ((rn
>= FGR_BASE
) && (rn
< (FGR_BASE
+ NR_FGR
)))
677 cpu
->register_widths
[rn
] = WITH_TARGET_FLOATING_POINT_BITSIZE
;
678 else if ((rn
>= 33) && (rn
<= 37))
679 cpu
->register_widths
[rn
] = WITH_TARGET_WORD_BITSIZE
;
680 else if ((rn
== SRIDX
)
683 || ((rn
>= 72) && (rn
<= 89)))
684 cpu
->register_widths
[rn
] = 32;
686 cpu
->register_widths
[rn
] = 0;
692 if (STATE
& simTRACE
)
696 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
699 lsipmon_monitor_base);
702 /* Write the monitor trap address handlers into the monitor (eeprom)
703 address space. This can only be done once the target endianness
704 has been determined. */
705 if (idt_monitor_base
!= 0)
708 unsigned idt_monitor_size
= 1 << 11;
710 /* the default monitor region */
711 sim_do_commandf (sd
, "memory region 0x%x,0x%x",
712 idt_monitor_base
, idt_monitor_size
);
714 /* Entry into the IDT monitor is via fixed address vectors, and
715 not using machine instructions. To avoid clashing with use of
716 the MIPS TRAP system, we place our own (simulator specific)
717 "undefined" instructions into the relevant vector slots. */
718 for (loop
= 0; (loop
< idt_monitor_size
); loop
+= 4)
720 address_word vaddr
= (idt_monitor_base
+ loop
);
721 unsigned32 insn
= (RSVD_INSTRUCTION
|
722 (((loop
>> 2) & RSVD_INSTRUCTION_ARG_MASK
)
723 << RSVD_INSTRUCTION_ARG_SHIFT
));
725 sim_write (sd
, vaddr
, (unsigned char *)&insn
, sizeof (insn
));
729 if ((pmon_monitor_base
!= 0) || (lsipmon_monitor_base
!= 0))
731 /* The PMON monitor uses the same address space, but rather than
732 branching into it the address of a routine is loaded. We can
733 cheat for the moment, and direct the PMON routine to IDT style
734 instructions within the monitor space. This relies on the IDT
735 monitor not using the locations from 0xBFC00500 onwards as its
738 for (loop
= 0; (loop
< 24); loop
++)
740 unsigned32 value
= ((0x500 - 8) / 8); /* default UNDEFINED reason code */
756 value
= ((0x500 - 16) / 8); /* not an IDT reason code */
758 case 8: /* cliexit */
761 case 11: /* flush_cache */
766 SIM_ASSERT (idt_monitor_base
!= 0);
767 value
= ((unsigned int) idt_monitor_base
+ (value
* 8));
770 if (pmon_monitor_base
!= 0)
772 address_word vaddr
= (pmon_monitor_base
+ (loop
* 4));
773 sim_write (sd
, vaddr
, (unsigned char *)&value
, sizeof (value
));
776 if (lsipmon_monitor_base
!= 0)
778 address_word vaddr
= (lsipmon_monitor_base
+ (loop
* 4));
779 sim_write (sd
, vaddr
, (unsigned char *)&value
, sizeof (value
));
783 /* Write an abort sequence into the TRAP (common) exception vector
784 addresses. This is to catch code executing a TRAP (et.al.)
785 instruction without installing a trap handler. */
786 if ((idt_monitor_base
!= 0) ||
787 (pmon_monitor_base
!= 0) ||
788 (lsipmon_monitor_base
!= 0))
790 unsigned32 halt
[2] = { 0x2404002f /* addiu r4, r0, 47 */,
791 HALT_INSTRUCTION
/* BREAK */ };
794 sim_write (sd
, 0x80000000, (unsigned char *) halt
, sizeof (halt
));
795 sim_write (sd
, 0x80000180, (unsigned char *) halt
, sizeof (halt
));
796 sim_write (sd
, 0x80000200, (unsigned char *) halt
, sizeof (halt
));
797 /* XXX: Write here unconditionally? */
798 sim_write (sd
, 0xBFC00200, (unsigned char *) halt
, sizeof (halt
));
799 sim_write (sd
, 0xBFC00380, (unsigned char *) halt
, sizeof (halt
));
800 sim_write (sd
, 0xBFC00400, (unsigned char *) halt
, sizeof (halt
));
804 /* CPU specific initialization. */
805 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
807 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
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 sim_close (SIM_DESC sd
, int quitting
)
840 printf("DBG: sim_close: entered (quitting = %d)\n",quitting
);
844 /* "quitting" is non-zero if we cannot hang on errors */
846 /* shut down modules */
847 sim_module_uninstall (sd
);
849 /* Ensure that any resources allocated through the callback
850 mechanism are released: */
851 sim_io_shutdown (sd
);
854 if (tracefh
!= NULL
&& tracefh
!= stderr
)
859 /* FIXME - free SD */
866 sim_write (SIM_DESC sd
, SIM_ADDR addr
, const unsigned char *buffer
, int size
)
869 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
871 /* Return the number of bytes written, or zero if error. */
873 sim_io_printf(sd
,"sim_write(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
876 /* We use raw read and write routines, since we do not want to count
877 the GDB memory accesses in our statistics gathering. */
879 for (index
= 0; index
< size
; index
++)
881 address_word vaddr
= (address_word
)addr
+ index
;
884 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isSTORE
, &paddr
, &cca
, isRAW
))
886 if (sim_core_write_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
894 sim_read (SIM_DESC sd
, SIM_ADDR addr
, unsigned char *buffer
, int size
)
897 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
899 /* Return the number of bytes read, or zero if error. */
901 sim_io_printf(sd
,"sim_read(0x%s,buffer,%d);\n",pr_addr(addr
),size
);
904 for (index
= 0; (index
< size
); index
++)
906 address_word vaddr
= (address_word
)addr
+ index
;
909 if (!address_translation (SD
, CPU
, NULL_CIA
, vaddr
, isDATA
, isLOAD
, &paddr
, &cca
, isRAW
))
911 if (sim_core_read_buffer (SD
, CPU
, read_map
, buffer
+ index
, paddr
, 1) != 1)
919 sim_store_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
921 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
922 /* NOTE: gdb (the client) stores registers in target byte order
923 while the simulator uses host byte order */
925 sim_io_printf(sd
,"sim_store_register(%d,*memory=0x%s);\n",rn
,pr_addr(*((SIM_ADDR
*)memory
)));
928 /* Unfortunately this suffers from the same problem as the register
929 numbering one. We need to know what the width of each logical
930 register number is for the architecture being simulated. */
932 if (cpu
->register_widths
[rn
] == 0)
934 sim_io_eprintf(sd
,"Invalid register width for %d (register store ignored)\n",rn
);
940 if (rn
>= FGR_BASE
&& rn
< FGR_BASE
+ NR_FGR
)
942 cpu
->fpr_state
[rn
- FGR_BASE
] = fmt_uninterpreted
;
943 if (cpu
->register_widths
[rn
] == 32)
947 cpu
->fgr
[rn
- FGR_BASE
] =
948 (unsigned32
) T2H_8 (*(unsigned64
*)memory
);
953 cpu
->fgr
[rn
- FGR_BASE
] = T2H_4 (*(unsigned32
*)memory
);
961 cpu
->fgr
[rn
- FGR_BASE
] = T2H_8 (*(unsigned64
*)memory
);
966 cpu
->fgr
[rn
- FGR_BASE
] = T2H_4 (*(unsigned32
*)memory
);
972 if (cpu
->register_widths
[rn
] == 32)
977 (unsigned32
) T2H_8 (*(unsigned64
*)memory
);
982 cpu
->registers
[rn
] = T2H_4 (*(unsigned32
*)memory
);
990 cpu
->registers
[rn
] = T2H_8 (*(unsigned64
*)memory
);
995 cpu
->registers
[rn
] = (signed32
) T2H_4(*(unsigned32
*)memory
);
1004 sim_fetch_register (SIM_DESC sd
, int rn
, unsigned char *memory
, int length
)
1006 sim_cpu
*cpu
= STATE_CPU (sd
, 0); /* FIXME */
1007 /* NOTE: gdb (the client) stores registers in target byte order
1008 while the simulator uses host byte order */
1010 #if 0 /* FIXME: doesn't compile */
1011 sim_io_printf(sd
,"sim_fetch_register(%d=0x%s,mem) : place simulator registers into memory\n",rn
,pr_addr(registers
[rn
]));
1015 if (cpu
->register_widths
[rn
] == 0)
1017 sim_io_eprintf (sd
, "Invalid register width for %d (register fetch ignored)\n",rn
);
1023 /* Any floating point register */
1024 if (rn
>= FGR_BASE
&& rn
< FGR_BASE
+ NR_FGR
)
1026 if (cpu
->register_widths
[rn
] == 32)
1030 *(unsigned64
*)memory
=
1031 H2T_8 ((unsigned32
) (cpu
->fgr
[rn
- FGR_BASE
]));
1036 *(unsigned32
*)memory
= H2T_4 (cpu
->fgr
[rn
- FGR_BASE
]);
1044 *(unsigned64
*)memory
= H2T_8 (cpu
->fgr
[rn
- FGR_BASE
]);
1049 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->fgr
[rn
- FGR_BASE
]));
1055 if (cpu
->register_widths
[rn
] == 32)
1059 *(unsigned64
*)memory
=
1060 H2T_8 ((unsigned32
) (cpu
->registers
[rn
]));
1065 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1073 *(unsigned64
*)memory
=
1074 H2T_8 ((unsigned64
) (cpu
->registers
[rn
]));
1079 *(unsigned32
*)memory
= H2T_4 ((unsigned32
)(cpu
->registers
[rn
]));
1088 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
, char **argv
, char **env
)
1092 #if 0 /* FIXME: doesn't compile */
1093 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1102 /* override PC value set by ColdReset () */
1104 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1106 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1107 CPU_PC_SET (cpu
, (unsigned64
) bfd_get_start_address (abfd
));
1111 #if 0 /* def DEBUG */
1114 /* We should really place the argv slot values into the argument
1115 registers, and onto the stack as required. However, this
1116 assumes that we have a stack defined, which is not
1117 necessarily true at the moment. */
1119 sim_io_printf(sd
,"sim_create_inferior() : passed arguments ignored\n");
1120 for (cptr
= argv
; (cptr
&& *cptr
); cptr
++)
1121 printf("DBG: arg \"%s\"\n",*cptr
);
1128 /*---------------------------------------------------------------------------*/
1129 /*-- Private simulator support interface ------------------------------------*/
1130 /*---------------------------------------------------------------------------*/
1132 /* Read a null terminated string from memory, return in a buffer */
1134 fetch_str (SIM_DESC sd
,
1140 while (sim_read (sd
, addr
+ nr
, &null
, 1) == 1 && null
!= 0)
1142 buf
= NZALLOC (char, nr
+ 1);
1143 sim_read (sd
, addr
, (unsigned char *)buf
, nr
);
1148 /* Implements the "sim firmware" command:
1149 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1150 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1151 defaults to the normal address for that monitor.
1152 sim firmware none --- don't emulate any ROM monitor. Useful
1153 if you need a clean address space. */
1155 sim_firmware_command (SIM_DESC sd
, char *arg
)
1157 int address_present
= 0;
1160 /* Signal occurrence of this option. */
1161 firmware_option_p
= 1;
1163 /* Parse out the address, if present. */
1165 char *p
= strchr (arg
, '@');
1169 address_present
= 1;
1170 p
++; /* skip over @ */
1172 address
= strtoul (p
, &q
, 0);
1175 sim_io_printf (sd
, "Invalid address given to the"
1176 "`sim firmware NAME@ADDRESS' command: %s\n",
1183 address_present
= 0;
1184 address
= -1; /* Dummy value. */
1188 if (! strncmp (arg
, "idt", 3))
1190 idt_monitor_base
= address_present
? address
: 0xBFC00000;
1191 pmon_monitor_base
= 0;
1192 lsipmon_monitor_base
= 0;
1194 else if (! strncmp (arg
, "pmon", 4))
1196 /* pmon uses indirect calls. Hook into implied idt. */
1197 pmon_monitor_base
= address_present
? address
: 0xBFC00500;
1198 idt_monitor_base
= pmon_monitor_base
- 0x500;
1199 lsipmon_monitor_base
= 0;
1201 else if (! strncmp (arg
, "lsipmon", 7))
1203 /* lsipmon uses indirect calls. Hook into implied idt. */
1204 pmon_monitor_base
= 0;
1205 lsipmon_monitor_base
= address_present
? address
: 0xBFC00200;
1206 idt_monitor_base
= lsipmon_monitor_base
- 0x200;
1208 else if (! strncmp (arg
, "none", 4))
1210 if (address_present
)
1213 "The `sim firmware none' command does "
1214 "not take an `ADDRESS' argument.\n");
1217 idt_monitor_base
= 0;
1218 pmon_monitor_base
= 0;
1219 lsipmon_monitor_base
= 0;
1223 sim_io_printf (sd
, "\
1224 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1225 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1235 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1237 sim_monitor (SIM_DESC sd
,
1240 unsigned int reason
)
1243 printf("DBG: sim_monitor: entered (reason = %d)\n",reason
);
1246 /* The IDT monitor actually allows two instructions per vector
1247 slot. However, the simulator currently causes a trap on each
1248 individual instruction. We cheat, and lose the bottom bit. */
1251 /* The following callback functions are available, however the
1252 monitor we are simulating does not make use of them: get_errno,
1253 isatty, lseek, rename, system, time and unlink */
1257 case 6: /* int open(char *path,int flags) */
1259 char *path
= fetch_str (sd
, A0
);
1260 V0
= sim_io_open (sd
, path
, (int)A1
);
1265 case 7: /* int read(int file,char *ptr,int len) */
1269 char *buf
= zalloc (nr
);
1270 V0
= sim_io_read (sd
, fd
, buf
, nr
);
1271 sim_write (sd
, A1
, (unsigned char *)buf
, nr
);
1276 case 8: /* int write(int file,char *ptr,int len) */
1280 char *buf
= zalloc (nr
);
1281 sim_read (sd
, A1
, (unsigned char *)buf
, nr
);
1282 V0
= sim_io_write (sd
, fd
, buf
, nr
);
1284 sim_io_flush_stdout (sd
);
1286 sim_io_flush_stderr (sd
);
1291 case 10: /* int close(int file) */
1293 V0
= sim_io_close (sd
, (int)A0
);
1297 case 2: /* Densan monitor: char inbyte(int waitflag) */
1299 if (A0
== 0) /* waitflag == NOWAIT */
1300 V0
= (unsigned_word
)-1;
1302 /* Drop through to case 11 */
1304 case 11: /* char inbyte(void) */
1307 /* ensure that all output has gone... */
1308 sim_io_flush_stdout (sd
);
1309 if (sim_io_read_stdin (sd
, &tmp
, sizeof(char)) != sizeof(char))
1311 sim_io_error(sd
,"Invalid return from character read");
1312 V0
= (unsigned_word
)-1;
1315 V0
= (unsigned_word
)tmp
;
1319 case 3: /* Densan monitor: void co(char chr) */
1320 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1322 char tmp
= (char)(A0
& 0xFF);
1323 sim_io_write_stdout (sd
, &tmp
, sizeof(char));
1327 case 17: /* void _exit() */
1329 sim_io_eprintf (sd
, "sim_monitor(17): _exit(int reason) to be coded\n");
1330 sim_engine_halt (SD
, CPU
, NULL
, NULL_CIA
, sim_exited
,
1331 (unsigned int)(A0
& 0xFFFFFFFF));
1335 case 28: /* PMON flush_cache */
1338 case 55: /* void get_mem_info(unsigned int *ptr) */
1339 /* in: A0 = pointer to three word memory location */
1340 /* out: [A0 + 0] = size */
1341 /* [A0 + 4] = instruction cache size */
1342 /* [A0 + 8] = data cache size */
1345 unsigned_4 zero
= 0;
1346 address_word mem_size
;
1347 sim_memopt
*entry
, *match
= NULL
;
1349 /* Search for memory region mapped to KSEG0 or KSEG1. */
1350 for (entry
= STATE_MEMOPT (sd
);
1352 entry
= entry
->next
)
1354 if ((entry
->addr
== K0BASE
|| entry
->addr
== K1BASE
)
1355 && (!match
|| entry
->level
< match
->level
))
1360 for (alias
= entry
->alias
;
1362 alias
= alias
->next
)
1363 if ((alias
->addr
== K0BASE
|| alias
->addr
== K1BASE
)
1364 && (!match
|| entry
->level
< match
->level
))
1369 /* Get region size, limit to KSEG1 size (512MB). */
1370 SIM_ASSERT (match
!= NULL
);
1371 mem_size
= (match
->modulo
!= 0
1372 ? match
->modulo
: match
->nr_bytes
);
1373 if (mem_size
> K1SIZE
)
1378 sim_write (sd
, A0
+ 0, (unsigned char *)&value
, 4);
1379 sim_write (sd
, A0
+ 4, (unsigned char *)&zero
, 4);
1380 sim_write (sd
, A0
+ 8, (unsigned char *)&zero
, 4);
1381 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1385 case 158: /* PMON printf */
1386 /* in: A0 = pointer to format string */
1387 /* A1 = optional argument 1 */
1388 /* A2 = optional argument 2 */
1389 /* A3 = optional argument 3 */
1391 /* The following is based on the PMON printf source */
1393 address_word s
= A0
;
1395 signed_word
*ap
= &A1
; /* 1st argument */
1396 /* This isn't the quickest way, since we call the host print
1397 routine for every character almost. But it does avoid
1398 having to allocate and manage a temporary string buffer. */
1399 /* TODO: Include check that we only use three arguments (A1,
1401 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1406 enum {FMT_RJUST
, FMT_LJUST
, FMT_RJUST0
, FMT_CENTER
} fmt
= FMT_RJUST
;
1407 int width
= 0, trunc
= 0, haddot
= 0, longlong
= 0;
1408 while (sim_read (sd
, s
++, &c
, 1) && c
!= '\0')
1410 if (strchr ("dobxXulscefg%", c
))
1425 else if (c
>= '1' && c
<= '9')
1429 while (sim_read (sd
, s
++, &c
, 1) == 1 && isdigit (c
))
1432 n
= (unsigned int)strtol(tmp
,NULL
,10);
1445 sim_io_printf (sd
, "%%");
1450 address_word p
= *ap
++;
1452 while (sim_read (sd
, p
++, &ch
, 1) == 1 && ch
!= '\0')
1453 sim_io_printf(sd
, "%c", ch
);
1456 sim_io_printf(sd
,"(null)");
1459 sim_io_printf (sd
, "%c", (int)*ap
++);
1464 sim_read (sd
, s
++, &c
, 1);
1468 sim_read (sd
, s
++, &c
, 1);
1471 if (strchr ("dobxXu", c
))
1473 word64 lv
= (word64
) *ap
++;
1475 sim_io_printf(sd
,"<binary not supported>");
1478 sprintf (tmp
, "%%%s%c", longlong
? "ll" : "", c
);
1480 sim_io_printf(sd
, tmp
, lv
);
1482 sim_io_printf(sd
, tmp
, (int)lv
);
1485 else if (strchr ("eEfgG", c
))
1487 double dbl
= *(double*)(ap
++);
1488 sprintf (tmp
, "%%%d.%d%c", width
, trunc
, c
);
1489 sim_io_printf (sd
, tmp
, dbl
);
1495 sim_io_printf(sd
, "%c", c
);
1501 /* Unknown reason. */
1507 /* Store a word into memory. */
1510 store_word (SIM_DESC sd
,
1519 if ((vaddr
& 3) != 0)
1520 SignalExceptionAddressStore ();
1523 if (AddressTranslation (vaddr
, isDATA
, isSTORE
, &paddr
, &uncached
,
1526 const uword64 mask
= 7;
1530 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (ReverseEndian
<< 2));
1531 byte
= (vaddr
& mask
) ^ (BigEndianCPU
<< 2);
1532 memval
= ((uword64
) val
) << (8 * byte
);
1533 StoreMemory (uncached
, AccessLength_WORD
, memval
, 0, paddr
, vaddr
,
1539 /* Load a word from memory. */
1542 load_word (SIM_DESC sd
,
1547 if ((vaddr
& 3) != 0)
1549 SIM_CORE_SIGNAL (SD
, cpu
, cia
, read_map
, AccessLength_WORD
+1, vaddr
, read_transfer
, sim_core_unaligned_signal
);
1556 if (AddressTranslation (vaddr
, isDATA
, isLOAD
, &paddr
, &uncached
,
1559 const uword64 mask
= 0x7;
1560 const unsigned int reverse
= ReverseEndian
? 1 : 0;
1561 const unsigned int bigend
= BigEndianCPU
? 1 : 0;
1565 paddr
= (paddr
& ~mask
) | ((paddr
& mask
) ^ (reverse
<< 2));
1566 LoadMemory (&memval
,NULL
,uncached
, AccessLength_WORD
, paddr
, vaddr
,
1568 byte
= (vaddr
& mask
) ^ (bigend
<< 2);
1569 return EXTEND32 (memval
>> (8 * byte
));
1576 /* Simulate the mips16 entry and exit pseudo-instructions. These
1577 would normally be handled by the reserved instruction exception
1578 code, but for ease of simulation we just handle them directly. */
1581 mips16_entry (SIM_DESC sd
,
1586 int aregs
, sregs
, rreg
;
1589 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn
);
1592 aregs
= (insn
& 0x700) >> 8;
1593 sregs
= (insn
& 0x0c0) >> 6;
1594 rreg
= (insn
& 0x020) >> 5;
1596 /* This should be checked by the caller. */
1605 /* This is the entry pseudo-instruction. */
1607 for (i
= 0; i
< aregs
; i
++)
1608 store_word (SD
, CPU
, cia
, (uword64
) (SP
+ 4 * i
), GPR
[i
+ 4]);
1616 store_word (SD
, CPU
, cia
, (uword64
) tsp
, RA
);
1619 for (i
= 0; i
< sregs
; i
++)
1622 store_word (SD
, CPU
, cia
, (uword64
) tsp
, GPR
[16 + i
]);
1630 /* This is the exit pseudo-instruction. */
1637 RA
= load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1640 for (i
= 0; i
< sregs
; i
++)
1643 GPR
[i
+ 16] = load_word (SD
, CPU
, cia
, (uword64
) tsp
);
1648 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1652 FGR
[0] = WORD64LO (GPR
[4]);
1653 FPR_STATE
[0] = fmt_uninterpreted
;
1655 else if (aregs
== 6)
1657 FGR
[0] = WORD64LO (GPR
[5]);
1658 FGR
[1] = WORD64LO (GPR
[4]);
1659 FPR_STATE
[0] = fmt_uninterpreted
;
1660 FPR_STATE
[1] = fmt_uninterpreted
;
1669 /*-- trace support ----------------------------------------------------------*/
1671 /* The trace support is provided (if required) in the memory accessing
1672 routines. Since we are also providing the architecture specific
1673 features, the architecture simulation code can also deal with
1674 notifying the trace world of cache flushes, etc. Similarly we do
1675 not need to provide profiling support in the simulator engine,
1676 since we can sample in the instruction fetch control loop. By
1677 defining the trace manifest, we add tracing as a run-time
1680 #if WITH_TRACE_ANY_P
1681 /* Tracing by default produces "din" format (as required by
1682 dineroIII). Each line of such a trace file *MUST* have a din label
1683 and address field. The rest of the line is ignored, so comments can
1684 be included if desired. The first field is the label which must be
1685 one of the following values:
1690 3 escape record (treated as unknown access type)
1691 4 escape record (causes cache flush)
1693 The address field is a 32bit (lower-case) hexadecimal address
1694 value. The address should *NOT* be preceded by "0x".
1696 The size of the memory transfer is not important when dealing with
1697 cache lines (as long as no more than a cache line can be
1698 transferred in a single operation :-), however more information
1699 could be given following the dineroIII requirement to allow more
1700 complete memory and cache simulators to provide better
1701 results. i.e. the University of Pisa has a cache simulator that can
1702 also take bus size and speed as (variable) inputs to calculate
1703 complete system performance (a much more useful ability when trying
1704 to construct an end product, rather than a processor). They
1705 currently have an ARM version of their tool called ChARM. */
1709 dotrace (SIM_DESC sd
,
1717 if (STATE
& simTRACE
) {
1719 fprintf(tracefh
,"%d %s ; width %d ; ",
1723 va_start(ap
,comment
);
1724 vfprintf(tracefh
,comment
,ap
);
1726 fprintf(tracefh
,"\n");
1728 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1729 we may be generating 64bit ones, we should put the hi-32bits of the
1730 address into the comment field. */
1732 /* TODO: Provide a buffer for the trace lines. We can then avoid
1733 performing writes until the buffer is filled, or the file is
1736 /* NOTE: We could consider adding a comment field to the "din" file
1737 produced using type 3 markers (unknown access). This would then
1738 allow information about the program that the "din" is for, and
1739 the MIPs world that was being simulated, to be placed into the
1744 #endif /* WITH_TRACE_ANY_P */
1746 /*---------------------------------------------------------------------------*/
1747 /*-- simulator engine -------------------------------------------------------*/
1748 /*---------------------------------------------------------------------------*/
1751 ColdReset (SIM_DESC sd
)
1754 for (cpu_nr
= 0; cpu_nr
< sim_engine_nr_cpus (sd
); cpu_nr
++)
1756 sim_cpu
*cpu
= STATE_CPU (sd
, cpu_nr
);
1757 /* RESET: Fixed PC address: */
1758 PC
= (unsigned_word
) UNSIGNED64 (0xFFFFFFFFBFC00000);
1759 /* The reset vector address is in the unmapped, uncached memory space. */
1761 SR
&= ~(status_SR
| status_TS
| status_RP
);
1762 SR
|= (status_ERL
| status_BEV
);
1764 /* Cheat and allow access to the complete register set immediately */
1765 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
1766 && WITH_TARGET_WORD_BITSIZE
== 64)
1767 SR
|= status_FR
; /* 64bit registers */
1769 /* Ensure that any instructions with pending register updates are
1771 PENDING_INVALIDATE();
1773 /* Initialise the FPU registers to the unknown state */
1774 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
1777 for (rn
= 0; (rn
< 32); rn
++)
1778 FPR_STATE
[rn
] = fmt_uninterpreted
;
1781 /* Initialise the Config0 register. */
1782 C0_CONFIG
= 0x80000000 /* Config1 present */
1783 | 2; /* KSEG0 uncached */
1784 if (WITH_TARGET_WORD_BITSIZE
== 64)
1786 /* FIXME Currently mips/sim-main.c:address_translation()
1787 truncates all addresses to 32-bits. */
1788 if (0 && WITH_TARGET_ADDRESS_BITSIZE
== 64)
1789 C0_CONFIG
|= (2 << 13); /* MIPS64, 64-bit addresses */
1791 C0_CONFIG
|= (1 << 13); /* MIPS64, 32-bit addresses */
1794 C0_CONFIG
|= 0x00008000; /* Big Endian */
1801 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1802 /* Signal an exception condition. This will result in an exception
1803 that aborts the instruction. The instruction operation pseudocode
1804 will never see a return from this function call. */
1807 signal_exception (SIM_DESC sd
,
1815 sim_io_printf(sd
,"DBG: SignalException(%d) PC = 0x%s\n",exception
,pr_addr(cia
));
1818 /* Ensure that any active atomic read/modify/write operation will fail: */
1821 /* Save registers before interrupt dispatching */
1822 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1823 SIM_CPU_EXCEPTION_TRIGGER(sd
, cpu
, cia
);
1826 switch (exception
) {
1828 case DebugBreakPoint
:
1829 if (! (Debug
& Debug_DM
))
1835 Debug
|= Debug_DBD
; /* signaled from within in delay slot */
1836 DEPC
= cia
- 4; /* reference the branch instruction */
1840 Debug
&= ~Debug_DBD
; /* not signaled from within a delay slot */
1844 Debug
|= Debug_DM
; /* in debugging mode */
1845 Debug
|= Debug_DBp
; /* raising a DBp exception */
1847 sim_engine_restart (SD
, CPU
, NULL
, NULL_CIA
);
1851 case ReservedInstruction
:
1854 unsigned int instruction
;
1855 va_start(ap
,exception
);
1856 instruction
= va_arg(ap
,unsigned int);
1858 /* Provide simple monitor support using ReservedInstruction
1859 exceptions. The following code simulates the fixed vector
1860 entry points into the IDT monitor by causing a simulator
1861 trap, performing the monitor operation, and returning to
1862 the address held in the $ra register (standard PCS return
1863 address). This means we only need to pre-load the vector
1864 space with suitable instruction values. For systems were
1865 actual trap instructions are used, we would not need to
1866 perform this magic. */
1867 if ((instruction
& RSVD_INSTRUCTION_MASK
) == RSVD_INSTRUCTION
)
1869 int reason
= (instruction
>> RSVD_INSTRUCTION_ARG_SHIFT
) & RSVD_INSTRUCTION_ARG_MASK
;
1870 if (!sim_monitor (SD
, CPU
, cia
, reason
))
1871 sim_io_error (sd
, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason
, pr_addr (cia
));
1873 /* NOTE: This assumes that a branch-and-link style
1874 instruction was used to enter the vector (which is the
1875 case with the current IDT monitor). */
1876 sim_engine_restart (SD
, CPU
, NULL
, RA
);
1878 /* Look for the mips16 entry and exit instructions, and
1879 simulate a handler for them. */
1880 else if ((cia
& 1) != 0
1881 && (instruction
& 0xf81f) == 0xe809
1882 && (instruction
& 0x0c0) != 0x0c0)
1884 mips16_entry (SD
, CPU
, cia
, instruction
);
1885 sim_engine_restart (sd
, NULL
, NULL
, NULL_CIA
);
1887 /* else fall through to normal exception processing */
1888 sim_io_eprintf(sd
,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia
));
1892 /* Store exception code into current exception id variable (used
1895 /* TODO: If not simulating exceptions then stop the simulator
1896 execution. At the moment we always stop the simulation. */
1898 #ifdef SUBTARGET_R3900
1899 /* update interrupt-related registers */
1901 /* insert exception code in bits 6:2 */
1902 CAUSE
= LSMASKED32(CAUSE
, 31, 7) | LSINSERTED32(exception
, 6, 2);
1903 /* shift IE/KU history bits left */
1904 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 3, 0), 5, 2);
1906 if (STATE
& simDELAYSLOT
)
1908 STATE
&= ~simDELAYSLOT
;
1910 EPC
= (cia
- 4); /* reference the branch instruction */
1915 if (SR
& status_BEV
)
1916 PC
= (signed)0xBFC00000 + 0x180;
1918 PC
= (signed)0x80000000 + 0x080;
1920 /* See figure 5-17 for an outline of the code below */
1921 if (! (SR
& status_EXL
))
1923 CAUSE
= (exception
<< 2);
1924 if (STATE
& simDELAYSLOT
)
1926 STATE
&= ~simDELAYSLOT
;
1928 EPC
= (cia
- 4); /* reference the branch instruction */
1932 /* FIXME: TLB et.al. */
1933 /* vector = 0x180; */
1937 CAUSE
= (exception
<< 2);
1938 /* vector = 0x180; */
1941 /* Store exception code into current exception id variable (used
1944 if (SR
& status_BEV
)
1945 PC
= (signed)0xBFC00200 + 0x180;
1947 PC
= (signed)0x80000000 + 0x180;
1950 switch ((CAUSE
>> 2) & 0x1F)
1953 /* Interrupts arrive during event processing, no need to
1959 #ifdef SUBTARGET_3900
1960 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1961 PC
= (signed)0xBFC00000;
1962 #endif /* SUBTARGET_3900 */
1965 case TLBModification
:
1970 case InstructionFetch
:
1972 /* The following is so that the simulator will continue from the
1973 exception handler address. */
1974 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1975 sim_stopped
, SIM_SIGBUS
);
1977 case ReservedInstruction
:
1978 case CoProcessorUnusable
:
1980 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1981 sim_stopped
, SIM_SIGILL
);
1983 case IntegerOverflow
:
1985 sim_engine_halt (SD
, CPU
, NULL
, PC
,
1986 sim_stopped
, SIM_SIGFPE
);
1989 sim_engine_halt (SD
, CPU
, NULL
, PC
, sim_stopped
, SIM_SIGTRAP
);
1994 sim_engine_restart (SD
, CPU
, NULL
, PC
);
1999 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2000 sim_stopped
, SIM_SIGTRAP
);
2002 default: /* Unknown internal exception */
2004 sim_engine_halt (SD
, CPU
, NULL
, PC
,
2005 sim_stopped
, SIM_SIGABRT
);
2009 case SimulatorFault
:
2013 va_start(ap
,exception
);
2014 msg
= va_arg(ap
,char *);
2016 sim_engine_abort (SD
, CPU
, NULL_CIA
,
2017 "FATAL: Simulator error \"%s\"\n",msg
);
2026 /* This function implements what the MIPS32 and MIPS64 ISAs define as
2027 "UNPREDICTABLE" behaviour.
2029 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2030 may vary from processor implementation to processor implementation,
2031 instruction to instruction, or as a function of time on the same
2032 implementation or instruction. Software can never depend on results
2033 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
2034 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
2037 For UNPREDICTABLE behaviour, we print a message, if possible print
2038 the offending instructions mips.igen instruction name (provided by
2039 the caller), and stop the simulator.
2041 XXX FIXME: eventually, stopping the simulator should be made conditional
2042 on a command-line option. */
2044 unpredictable_action(sim_cpu
*cpu
, address_word cia
)
2046 SIM_DESC sd
= CPU_STATE(cpu
);
2048 sim_io_eprintf(sd
, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia
));
2049 sim_engine_halt (SD
, CPU
, NULL
, cia
, sim_stopped
, SIM_SIGABRT
);
2053 /*-- co-processor support routines ------------------------------------------*/
2056 CoProcPresent(unsigned int coproc_number
)
2058 /* Return TRUE if simulator provides a model for the given co-processor number */
2063 cop_lw (SIM_DESC sd
,
2068 unsigned int memword
)
2073 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2076 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword
,pr_addr(memword
));
2078 StoreFPR(coproc_reg
,fmt_uninterpreted_32
,(uword64
)memword
);
2083 #if 0 /* this should be controlled by a configuration option */
2084 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
));
2093 cop_ld (SIM_DESC sd
,
2102 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
) );
2105 switch (coproc_num
) {
2107 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2109 StoreFPR(coproc_reg
,fmt_uninterpreted_64
,memword
);
2114 #if 0 /* this message should be controlled by a configuration option */
2115 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
));
2127 cop_sw (SIM_DESC sd
,
2133 unsigned int value
= 0;
2138 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2140 value
= (unsigned int)ValueFPR(coproc_reg
,fmt_uninterpreted_32
);
2145 #if 0 /* should be controlled by configuration option */
2146 sim_io_printf(sd
,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
2155 cop_sd (SIM_DESC sd
,
2165 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2167 value
= ValueFPR(coproc_reg
,fmt_uninterpreted_64
);
2172 #if 0 /* should be controlled by configuration option */
2173 sim_io_printf(sd
,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num
,coproc_reg
,pr_addr(cia
));
2185 decode_coproc (SIM_DESC sd
,
2188 unsigned int instruction
,
2197 case 0: /* standard CPU control and cache registers */
2199 /* R4000 Users Manual (second edition) lists the following CP0
2201 CODE><-RT><RD-><--TAIL--->
2202 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2203 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2204 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2205 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2206 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2207 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2208 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2209 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2210 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2211 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2213 if (((op
== cp0_mfc0
) || (op
== cp0_mtc0
) /* MFC0 / MTC0 */
2214 || (op
== cp0_dmfc0
) || (op
== cp0_dmtc0
)) /* DMFC0 / DMTC0 */
2217 switch (rd
) /* NOTEs: Standard CP0 registers */
2219 /* 0 = Index R4000 VR4100 VR4300 */
2220 /* 1 = Random R4000 VR4100 VR4300 */
2221 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
2222 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
2223 /* 4 = Context R4000 VR4100 VR4300 */
2224 /* 5 = PageMask R4000 VR4100 VR4300 */
2225 /* 6 = Wired R4000 VR4100 VR4300 */
2226 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2227 /* 9 = Count R4000 VR4100 VR4300 */
2228 /* 10 = EntryHi R4000 VR4100 VR4300 */
2229 /* 11 = Compare R4000 VR4100 VR4300 */
2230 /* 12 = SR R4000 VR4100 VR4300 */
2231 #ifdef SUBTARGET_R3900
2233 /* 3 = Config R3900 */
2235 /* 7 = Cache R3900 */
2237 /* 15 = PRID R3900 */
2243 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2244 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2245 GPR
[rt
] = (signed_word
) (signed_address
) COP0_BADVADDR
;
2247 COP0_BADVADDR
= GPR
[rt
];
2250 #endif /* SUBTARGET_R3900 */
2252 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2257 /* 13 = Cause R4000 VR4100 VR4300 */
2259 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2264 /* 14 = EPC R4000 VR4100 VR4300 */
2266 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2267 GPR
[rt
] = (signed_word
) (signed_address
) EPC
;
2271 /* 15 = PRId R4000 VR4100 VR4300 */
2272 #ifdef SUBTARGET_R3900
2275 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2281 /* 16 = Config R4000 VR4100 VR4300 */
2283 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2284 GPR
[rt
] = C0_CONFIG
;
2286 /* only bottom three bits are writable */
2287 C0_CONFIG
= (C0_CONFIG
& ~0x7) | (GPR
[rt
] & 0x7);
2290 #ifdef SUBTARGET_R3900
2293 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2299 /* 17 = LLAddr R4000 VR4100 VR4300 */
2301 /* 18 = WatchLo R4000 VR4100 VR4300 */
2302 /* 19 = WatchHi R4000 VR4100 VR4300 */
2303 /* 20 = XContext R4000 VR4100 VR4300 */
2304 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2305 /* 27 = CacheErr R4000 VR4100 */
2306 /* 28 = TagLo R4000 VR4100 VR4300 */
2307 /* 29 = TagHi R4000 VR4100 VR4300 */
2308 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
2309 if (STATE_VERBOSE_P(SD
))
2311 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2312 (unsigned long)cia
);
2313 GPR
[rt
] = 0xDEADC0DE; /* CPR[0,rd] */
2314 /* CPR[0,rd] = GPR[rt]; */
2316 if (op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2317 GPR
[rt
] = (signed_word
) (signed32
) COP0_GPR
[rd
];
2319 COP0_GPR
[rd
] = GPR
[rt
];
2322 sim_io_printf(sd
,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
2324 sim_io_printf(sd
,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt
,rd
, (unsigned)cia
);
2328 else if ((op
== cp0_mfc0
|| op
== cp0_dmfc0
)
2331 /* [D]MFC0 RT,C0_CONFIG,SEL */
2339 /* MIPS32 r/o Config1:
2342 /* MIPS16 implemented.
2343 XXX How to check configuration? */
2345 if (CURRENT_FLOATING_POINT
== HARD_FLOATING_POINT
)
2346 /* MDMX & FPU implemented */
2350 /* MIPS32 r/o Config2:
2355 /* MIPS32 r/o Config3:
2356 SmartMIPS implemented. */
2362 else if (op
== cp0_eret
&& sel
== 0x18)
2365 if (SR
& status_ERL
)
2367 /* Oops, not yet available */
2368 sim_io_printf(sd
,"Warning: ERET when SR[ERL] set not handled yet");
2378 else if (op
== cp0_rfe
&& sel
== 0x10)
2381 #ifdef SUBTARGET_R3900
2382 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2384 /* shift IE/KU history bits right */
2385 SR
= LSMASKED32(SR
, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR
, 5, 2), 3, 0);
2387 /* TODO: CACHE register */
2388 #endif /* SUBTARGET_R3900 */
2390 else if (op
== cp0_deret
&& sel
== 0x1F)
2398 sim_io_eprintf(sd
,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction
,pr_addr(cia
));
2399 /* TODO: When executing an ERET or RFE instruction we should
2400 clear LLBIT, to ensure that any out-standing atomic
2401 read/modify/write sequence fails. */
2405 case 2: /* co-processor 2 */
2412 sim_io_eprintf(sd
, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2413 instruction
,pr_addr(cia
));
2418 case 1: /* should not occur (FPU co-processor) */
2419 case 3: /* should not occur (FPU co-processor) */
2420 SignalException(ReservedInstruction
,instruction
);
2428 /* This code copied from gdb's utils.c. Would like to share this code,
2429 but don't know of a common place where both could get to it. */
2431 /* Temporary storage using circular buffer */
2437 static char buf
[NUMCELLS
][CELLSIZE
];
2439 if (++cell
>=NUMCELLS
) cell
=0;
2443 /* Print routines to handle variable size regs, etc */
2445 /* Eliminate warning from compiler on 32-bit systems */
2446 static int thirty_two
= 32;
2449 pr_addr (SIM_ADDR addr
)
2451 char *paddr_str
=get_cell();
2452 switch (sizeof(addr
))
2455 sprintf(paddr_str
,"%08lx%08lx",
2456 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
2459 sprintf(paddr_str
,"%08lx",(unsigned long)addr
);
2462 sprintf(paddr_str
,"%04x",(unsigned short)(addr
&0xffff));
2465 sprintf(paddr_str
,"%x",addr
);
2471 pr_uword64 (uword64 addr
)
2473 char *paddr_str
=get_cell();
2474 sprintf(paddr_str
,"%08lx%08lx",
2475 (unsigned long)(addr
>>thirty_two
),(unsigned long)(addr
&0xffffffff));
2481 mips_core_signal (SIM_DESC sd
,
2487 transfer_type transfer
,
2488 sim_core_signals sig
)
2490 const char *copy
= (transfer
== read_transfer
? "read" : "write");
2491 address_word ip
= CIA_ADDR (cia
);
2495 case sim_core_unmapped_signal
:
2496 sim_io_eprintf (sd
, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2498 (unsigned long) addr
, (unsigned long) ip
);
2499 COP0_BADVADDR
= addr
;
2500 SignalExceptionDataReference();
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();
2515 sim_engine_abort (sd
, cpu
, cia
,
2516 "mips_core_signal - internal error - bad switch");
2522 mips_cpu_exception_trigger(SIM_DESC sd
, sim_cpu
* cpu
, address_word cia
)
2524 ASSERT(cpu
!= NULL
);
2526 if(cpu
->exc_suspended
> 0)
2527 sim_io_eprintf(sd
, "Warning, nested exception triggered (%d)\n", cpu
->exc_suspended
);
2530 memcpy(cpu
->exc_trigger_registers
, cpu
->registers
, sizeof(cpu
->exc_trigger_registers
));
2531 cpu
->exc_suspended
= 0;
2535 mips_cpu_exception_suspend(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
2537 ASSERT(cpu
!= NULL
);
2539 if(cpu
->exc_suspended
> 0)
2540 sim_io_eprintf(sd
, "Warning, nested exception signal (%d then %d)\n",
2541 cpu
->exc_suspended
, exception
);
2543 memcpy(cpu
->exc_suspend_registers
, cpu
->registers
, sizeof(cpu
->exc_suspend_registers
));
2544 memcpy(cpu
->registers
, cpu
->exc_trigger_registers
, sizeof(cpu
->registers
));
2545 cpu
->exc_suspended
= exception
;
2549 mips_cpu_exception_resume(SIM_DESC sd
, sim_cpu
* cpu
, int exception
)
2551 ASSERT(cpu
!= NULL
);
2553 if(exception
== 0 && cpu
->exc_suspended
> 0)
2555 /* warn not for breakpoints */
2556 if(cpu
->exc_suspended
!= sim_signal_to_host(sd
, SIM_SIGTRAP
))
2557 sim_io_eprintf(sd
, "Warning, resuming but ignoring pending exception signal (%d)\n",
2558 cpu
->exc_suspended
);
2560 else if(exception
!= 0 && cpu
->exc_suspended
> 0)
2562 if(exception
!= cpu
->exc_suspended
)
2563 sim_io_eprintf(sd
, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2564 cpu
->exc_suspended
, exception
);
2566 memcpy(cpu
->registers
, cpu
->exc_suspend_registers
, sizeof(cpu
->registers
));
2568 else if(exception
!= 0 && cpu
->exc_suspended
== 0)
2570 sim_io_eprintf(sd
, "Warning, ignoring spontanous exception signal (%d)\n", exception
);
2572 cpu
->exc_suspended
= 0;
2576 /*---------------------------------------------------------------------------*/
2577 /*> EOF interp.c <*/