Update release-README after completing the 2.43 release.
[binutils-gdb.git] / sim / mips / interp.c
blobb15b228600c25d06ddadc65e2dac7e0de72eeefd
1 /*> interp.c <*/
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.
16 NOTEs:
18 The IDT monitor (found on the VR4300 board), seems to lie about
19 register contents. It seems to treat the registers as sign-extended
20 32-bit values. This cause *REAL* problems when single-stepping 64-bit
21 code on the hardware.
25 /* This must come before any other includes. */
26 #include "defs.h"
28 #include "bfd.h"
29 #include "sim-main.h"
30 #include "sim-utils.h"
31 #include "sim-options.h"
32 #include "sim-assert.h"
33 #include "sim-hw.h"
34 #include "sim-signal.h"
36 #include "itable.h"
38 #include <stdio.h>
39 #include <stdarg.h>
40 #include <ansidecl.h>
41 #include <ctype.h>
42 #include <limits.h>
43 #include <math.h>
44 #include <stdlib.h>
45 #include <string.h>
47 #include "getopt.h"
48 #include "libiberty.h"
49 #include "bfd.h"
50 #include "bfd/elf-bfd.h"
51 #include "sim/callback.h" /* GDB simulator callback interface */
52 #include "sim/sim.h" /* GDB simulator interface */
53 #include "sim-syscall.h" /* Simulator system call support */
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. */
60 #define CPU cpu
61 #define SD sd
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() {\
97 DELAYSLOT ();\
98 STATE |= simJALDELAYSLOT;\
101 #define NULLIFY() {\
102 STATE &= ~simDELAYSLOT;\
103 STATE |= simSKIPNEXT;\
106 #define CANCELDELAYSLOT() {\
107 DSSTATE = 0;\
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,
133 install all three.
134 The RSVD_INSTRUCTION... macros specify the magic instructions we
135 use at the monitor entry points. */
136 static int firmware_option_p = 0;
137 static address_word idt_monitor_base = 0xBFC00000;
138 static address_word pmon_monitor_base = 0xBFC00500;
139 static address_word lsipmon_monitor_base = 0xBFC00200;
141 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
143 #define MEM_SIZE (8 << 20) /* 8 MBytes */
146 #if WITH_TRACE_ANY_P
147 static char *tracefile = "trace.din"; /* default filename for trace log */
148 FILE *tracefh = NULL;
149 static void open_trace (SIM_DESC sd);
150 #else
151 #define open_trace(sd)
152 #endif
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);
162 enum {
163 OPTION_DINERO_TRACE = OPTION_START,
164 OPTION_DINERO_FILE,
165 OPTION_FIRMWARE,
166 OPTION_INFO_MEMORY,
167 OPTION_BOARD
170 static int display_mem_info = 0;
172 static SIM_RC
173 mips_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
174 int is_command)
176 int cpu_nr;
177 switch (opt)
179 case OPTION_DINERO_TRACE: /* ??? */
180 #if WITH_TRACE_ANY_P
181 /* Eventually the simTRACE flag could be treated as a toggle, to
182 allow external control of the program points being traced
183 (i.e. only from main onwards, excluding the run-time setup,
184 etc.). */
185 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
187 cpu = STATE_CPU (sd, cpu_nr);
188 if (arg == NULL)
189 STATE |= simTRACE;
190 else if (strcmp (arg, "yes") == 0)
191 STATE |= simTRACE;
192 else if (strcmp (arg, "no") == 0)
193 STATE &= ~simTRACE;
194 else if (strcmp (arg, "on") == 0)
195 STATE |= simTRACE;
196 else if (strcmp (arg, "off") == 0)
197 STATE &= ~simTRACE;
198 else
200 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
201 return SIM_RC_FAIL;
204 return SIM_RC_OK;
205 #else /* !WITH_TRACE_ANY_P */
206 fprintf(stderr,"\
207 Simulator constructed without dinero tracing support (for performance).\n\
208 Re-compile simulator with \"-DWITH_TRACE_ANY_P\" to enable this option.\n");
209 return SIM_RC_FAIL;
210 #endif /* !WITH_TRACE_ANY_P */
212 case OPTION_DINERO_FILE:
213 #if WITH_TRACE_ANY_P
214 if (optarg != NULL) {
215 char *tmp;
216 tmp = (char *)malloc(strlen(optarg) + 1);
217 if (tmp == NULL)
219 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
220 return SIM_RC_FAIL;
222 else {
223 strcpy(tmp,optarg);
224 tracefile = tmp;
225 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
228 #endif /* WITH_TRACE_ANY_P */
229 return SIM_RC_OK;
231 case OPTION_FIRMWARE:
232 return sim_firmware_command (sd, arg);
234 case OPTION_BOARD:
236 if (arg)
238 board = zalloc(strlen(arg) + 1);
239 strcpy(board, arg);
241 return SIM_RC_OK;
244 case OPTION_INFO_MEMORY:
245 display_mem_info = 1;
246 break;
249 return SIM_RC_OK;
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"
268 "|" BOARD_JMR3904
269 #define BOARD_JMR3904_PAL "jmr3904pal"
270 "|" BOARD_JMR3904_PAL
271 #define BOARD_JMR3904_DEBUG "jmr3904debug"
272 "|" BOARD_JMR3904_DEBUG
273 #define BOARD_BSP "bsp"
274 "|" BOARD_BSP
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
286 to work. */
287 { { "info-memory", no_argument, NULL, OPTION_INFO_MEMORY },
288 '\0', NULL, "List configured memory regions", mips_option_handler },
289 { { "memory-info", no_argument, NULL, OPTION_INFO_MEMORY },
290 '\0', NULL, NULL, mips_option_handler },
292 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
296 int interrupt_pending;
298 void
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);
303 if (SR & status_IE)
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) {
317 #ifdef DEVICE_INIT
318 extern void register_devices(SIM_DESC);
319 register_devices(sd);
320 #endif
323 /*---------------------------------------------------------------------------*/
324 /*-- GDB simulator interface ------------------------------------------------*/
325 /*---------------------------------------------------------------------------*/
327 static sim_cia
328 mips_pc_get (sim_cpu *cpu)
330 return PC;
333 static void
334 mips_pc_set (sim_cpu *cpu, sim_cia pc)
336 PC = pc;
339 static int mips_reg_fetch (SIM_CPU *, int, void *, int);
340 static int mips_reg_store (SIM_CPU *, int, const void *, int);
342 SIM_DESC
343 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
344 struct bfd *abfd, char * const *argv)
346 int i;
347 SIM_DESC sd = sim_state_alloc_extra (kind, cb,
348 sizeof (struct mips_sim_state));
349 sim_cpu *cpu;
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))
355 != SIM_RC_OK)
356 return 0;
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;
367 STATE = 0;
369 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
370 return 0;
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);
380 return 0;
383 /* handle board-specific memory maps */
384 if (board == NULL)
386 /* Allocate core managed memory */
387 sim_memopt *entry, *match = NULL;
388 address_word mem_size = 0;
389 int mapped = 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
397 phys address 0. */
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. */
403 if (entry->addr == 0
404 && (!match || entry->level < match->level))
405 match = entry;
406 else if (entry->addr == K0BASE || entry->addr == K1BASE)
407 mapped = 1;
408 else
410 sim_memopt *alias;
411 for (alias = entry->alias; alias != NULL; alias = alias->next)
413 if (alias->addr == 0
414 && (!match || entry->level < match->level))
415 match = entry;
416 else if (alias->addr == K0BASE || alias->addr == K1BASE)
417 mapped = 1;
422 if (!mapped)
424 if (match)
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)
434 mem_size = MEM_SIZE;
435 /* Limit to KSEG1 size (512MB) */
436 if (mem_size > K1SIZE)
437 mem_size = K1SIZE;
438 /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
439 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x%%0x%lx,0x%0x",
440 K1BASE, K1SIZE, (long)mem_size, K0BASE);
441 if (WITH_TARGET_WORD_BITSIZE == 64)
442 sim_do_commandf (sd, "memory alias 0x%x,0x%" PRIxTW ",0x%" PRIxTA,
443 (K0BASE), mem_size, EXTENDED(K0BASE));
446 device_init(sd);
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",
455 0x9FC00000,
456 4 * 1024 * 1024, /* 4 MB */
457 0xBFC00000);
459 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
460 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
461 0x80000000,
462 4 * 1024 * 1024, /* 4 MB */
463 0xA0000000);
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),
471 size,
472 0xA8000000 + (i * size));
475 #if (WITH_HW)
476 else if (board != NULL
477 && (strcmp(board, BOARD_JMR3904) == 0 ||
478 strcmp(board, BOARD_JMR3904_PAL) == 0 ||
479 strcmp(board, BOARD_JMR3904_DEBUG) == 0))
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;
496 /* --- memory --- */
498 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
499 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
500 0x9FC00000,
501 4 * 1024 * 1024, /* 4 MB */
502 0xBFC00000);
504 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
505 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
506 0x80000000,
507 4 * 1024 * 1024, /* 4 MB */
508 0xA0000000);
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),
516 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;
545 #else
546 # define sockser_addr NULL
547 #endif
548 if (sockser_addr == NULL)
549 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
550 else
551 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
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))
567 /* the device */
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");
601 device_init(sd);
603 #endif
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;
616 ol != NULL;
617 prev = ol, ol = ol->next)
618 if (ol->options == mips_options)
619 break;
621 SIM_ASSERT (ol != NULL);
623 if (prev == NULL)
624 STATE_OPTIONS (sd) = ol->next;
625 else
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);
635 return 0;
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);
643 return 0;
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);
651 return 0;
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
660 registers: */
662 int rn;
663 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
665 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
667 if (rn < 32)
668 mips_cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
669 else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
670 mips_cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
671 else if ((rn >= 33) && (rn <= 37))
672 mips_cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
673 else if ((rn == SRIDX)
674 || (rn == FCR0IDX)
675 || (rn == FCR31IDX)
676 || ((rn >= 72) && (rn <= 89)))
677 mips_cpu->register_widths[rn] = 32;
678 else
679 mips_cpu->register_widths[rn] = 0;
685 if (STATE & simTRACE)
686 open_trace(sd);
689 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
690 idt_monitor_base,
691 pmon_monitor_base,
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)
700 unsigned loop;
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));
708 else
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));
722 H2T (insn);
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
734 entry points.*/
735 unsigned loop;
736 for (loop = 0; (loop < 24); loop++)
738 uint32_t value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
739 switch (loop)
741 case 0: /* read */
742 value = 7;
743 break;
744 case 1: /* write */
745 value = 8;
746 break;
747 case 2: /* open */
748 value = 6;
749 break;
750 case 3: /* close */
751 value = 10;
752 break;
753 case 5: /* printf */
754 value = ((0x500 - 16) / 8); /* not an IDT reason code */
755 break;
756 case 8: /* cliexit */
757 value = 17;
758 break;
759 case 11: /* flush_cache */
760 value = 28;
761 break;
764 SIM_ASSERT (idt_monitor_base != 0);
765 value = ((unsigned int) idt_monitor_base + (value * 8));
766 H2T (value);
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 */ };
790 H2T (halt[0]);
791 H2T (halt[1]);
792 sim_write (sd, 0x80000000, halt, sizeof (halt));
793 sim_write (sd, 0x80000180, halt, sizeof (halt));
794 sim_write (sd, 0x80000200, halt, sizeof (halt));
795 /* XXX: Write here unconditionally? */
796 sim_write (sd, 0xBFC00200, halt, sizeof (halt));
797 sim_write (sd, 0xBFC00380, halt, sizeof (halt));
798 sim_write (sd, 0xBFC00400, halt, sizeof (halt));
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;
813 return sd;
816 #if WITH_TRACE_ANY_P
817 static void
818 open_trace (SIM_DESC sd)
820 tracefh = fopen(tracefile,"wb+");
821 if (tracefh == NULL)
823 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
824 tracefh = stderr;
827 #endif
829 /* Return name of an insn, used by insn profiling. */
830 static const char *
831 get_insn_name (sim_cpu *cpu, int i)
833 return itable[i].name;
836 void
837 mips_sim_close (SIM_DESC sd, int quitting)
839 #if WITH_TRACE_ANY_P
840 if (tracefh != NULL && tracefh != stderr)
841 fclose(tracefh);
842 tracefh = NULL;
843 #endif
846 static int
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);
861 return 0;
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)
869 if (length == 8)
871 mips_cpu->fgr[rn - FGR_BASE] =
872 (uint32_t) T2H_8 (*(uint64_t*)memory);
873 return 8;
875 else
877 mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
878 return 4;
881 else
883 if (length == 8)
885 mips_cpu->fgr[rn - FGR_BASE] = T2H_8 (*(uint64_t*)memory);
886 return 8;
888 else
890 mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
891 return 4;
896 if (mips_cpu->register_widths[rn] == 32)
898 if (length == 8)
900 mips_cpu->registers[rn] =
901 (uint32_t) T2H_8 (*(uint64_t*)memory);
902 return 8;
904 else
906 mips_cpu->registers[rn] = T2H_4 (*(uint32_t*)memory);
907 return 4;
910 else
912 if (length == 8)
914 mips_cpu->registers[rn] = T2H_8 (*(uint64_t*)memory);
915 return 8;
917 else
919 mips_cpu->registers[rn] = (int32_t) T2H_4(*(uint32_t*)memory);
920 return 4;
924 return 0;
927 static int
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);
938 return 0;
941 /* Any floating point register */
942 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
944 if (mips_cpu->register_widths[rn] == 32)
946 if (length == 8)
948 *(uint64_t*)memory =
949 H2T_8 ((uint32_t) (mips_cpu->fgr[rn - FGR_BASE]));
950 return 8;
952 else
954 *(uint32_t*)memory = H2T_4 (mips_cpu->fgr[rn - FGR_BASE]);
955 return 4;
958 else
960 if (length == 8)
962 *(uint64_t*)memory = H2T_8 (mips_cpu->fgr[rn - FGR_BASE]);
963 return 8;
965 else
967 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->fgr[rn - FGR_BASE]));
968 return 4;
973 if (mips_cpu->register_widths[rn] == 32)
975 if (length == 8)
977 *(uint64_t*)memory =
978 H2T_8 ((uint32_t) (mips_cpu->registers[rn]));
979 return 8;
981 else
983 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
984 return 4;
987 else
989 if (length == 8)
991 *(uint64_t*)memory =
992 H2T_8 ((uint64_t) (mips_cpu->registers[rn]));
993 return 8;
995 else
997 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
998 return 4;
1002 return 0;
1005 SIM_RC
1006 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1007 char * const *argv, char * const *env)
1010 #ifdef DEBUG
1011 #if 0 /* FIXME: doesn't compile */
1012 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1013 pr_addr(PC));
1014 #endif
1015 #endif /* DEBUG */
1017 ColdReset(sd);
1019 if (abfd != NULL)
1021 /* override PC value set by ColdReset () */
1022 int cpu_nr;
1023 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
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)
1033 pc = (uint32_t) pc;
1035 CPU_PC_SET (cpu, pc);
1039 #if 0 /* def DEBUG */
1040 if (argv || env)
1042 /* We should really place the argv slot values into the argument
1043 registers, and onto the stack as required. However, this
1044 assumes that we have a stack defined, which is not
1045 necessarily true at the moment. */
1046 char **cptr;
1047 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1048 for (cptr = argv; (cptr && *cptr); cptr++)
1049 printf("DBG: arg \"%s\"\n",*cptr);
1051 #endif /* DEBUG */
1053 return SIM_RC_OK;
1056 /*---------------------------------------------------------------------------*/
1057 /*-- Private simulator support interface ------------------------------------*/
1058 /*---------------------------------------------------------------------------*/
1060 /* Read a null terminated string from memory, return in a buffer */
1061 static char *
1062 fetch_str (SIM_DESC sd,
1063 address_word addr)
1065 char *buf;
1066 int nr = 0;
1067 unsigned char null;
1068 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1069 nr++;
1070 buf = NZALLOC (char, nr + 1);
1071 sim_read (sd, addr, buf, nr);
1072 return buf;
1076 /* Implements the "sim firmware" command:
1077 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1078 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1079 defaults to the normal address for that monitor.
1080 sim firmware none --- don't emulate any ROM monitor. Useful
1081 if you need a clean address space. */
1082 static SIM_RC
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, '@');
1094 if (p)
1096 char *q;
1097 address_present = 1;
1098 p ++; /* skip over @ */
1100 address = strtoul (p, &q, 0);
1101 if (*q != '\0')
1103 sim_io_printf (sd, "Invalid address given to the"
1104 "`sim firmware NAME@ADDRESS' command: %s\n",
1106 return SIM_RC_FAIL;
1109 else
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)
1140 sim_io_printf (sd,
1141 "The `sim firmware none' command does "
1142 "not take an `ADDRESS' argument.\n");
1143 return SIM_RC_FAIL;
1145 idt_monitor_base = 0;
1146 pmon_monitor_base = 0;
1147 lsipmon_monitor_base = 0;
1149 else
1151 sim_io_printf (sd, "\
1152 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1153 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1154 arg);
1155 return SIM_RC_FAIL;
1158 return SIM_RC_OK;
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 },
1176 { 0, -1, -1 }
1180 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1182 sim_monitor (SIM_DESC sd,
1183 sim_cpu *cpu,
1184 address_word cia,
1185 unsigned int reason)
1187 #ifdef DEBUG
1188 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1189 #endif /* DEBUG */
1191 /* The IDT monitor actually allows two instructions per vector
1192 slot. However, the simulator currently causes a trap on each
1193 individual instruction. We cheat, and lose the bottom bit. */
1194 reason >>= 1;
1196 /* The following callback functions are available, however the
1197 monitor we are simulating does not make use of them: get_errno,
1198 isatty, rename, system and time. */
1199 switch (reason)
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);
1206 free (path);
1207 break;
1210 case 7: /* int read(int file,char *ptr,int len) */
1212 int fd = A0;
1213 int nr = A2;
1214 char *buf = zalloc (nr);
1215 V0 = sim_io_read (sd, fd, buf, nr);
1216 sim_write (sd, A1, buf, nr);
1217 free (buf);
1219 break;
1221 case 8: /* int write(int file,char *ptr,int len) */
1223 int fd = A0;
1224 int nr = A2;
1225 char *buf = zalloc (nr);
1226 sim_read (sd, A1, buf, nr);
1227 V0 = sim_io_write (sd, fd, buf, nr);
1228 if (fd == 1)
1229 sim_io_flush_stdout (sd);
1230 else if (fd == 2)
1231 sim_io_flush_stderr (sd);
1232 free (buf);
1233 break;
1236 case 10: /* int close(int file) */
1238 V0 = sim_io_close (sd, (int)A0);
1239 break;
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) */
1251 char tmp;
1252 /* ensure that all output has gone... */
1253 sim_io_flush_stdout (sd);
1254 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1256 sim_io_error(sd,"Invalid return from character read");
1257 V0 = (unsigned_word)-1;
1259 else
1260 V0 = (unsigned_word)tmp;
1261 break;
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));
1269 break;
1272 case 13: /* int unlink(const char *path) */
1274 char *path = fetch_str (sd, A0);
1275 V0 = sim_io_unlink (sd, path);
1276 free (path);
1277 break;
1280 case 14: /* int lseek(int fd, int offset, int whence) */
1282 V0 = sim_io_lseek (sd, A0, A1, A2);
1283 break;
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] ==
1296 ELFCLASS32);
1297 static CB_SYSCALL s;
1298 CB_SYSCALL_INIT (&s);
1299 s.func = 15;
1300 /* Mask out the sign extension part for 64-bit targets because the
1301 MIPS simulator's memory model is still 32-bit. */
1302 s.arg1 = A0 & 0xFFFFFFFF;
1303 s.arg2 = A1 & 0xFFFFFFFF;
1304 s.p1 = sd;
1305 s.p2 = cpu;
1306 s.read_mem = sim_syscall_read_mem;
1307 s.write_mem = sim_syscall_write_mem;
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);
1316 V0 = s.result;
1317 cb->stat_map = saved_map;
1318 cb->syscall_map = saved_syscall_map;
1319 break;
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));
1327 break;
1330 case 28: /* PMON flush_cache */
1331 break;
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 */
1339 unsigned_4 value;
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);
1346 entry != NULL;
1347 entry = entry->next)
1349 if ((entry->addr == K0BASE || entry->addr == K1BASE)
1350 && (!match || entry->level < match->level))
1351 match = entry;
1352 else
1354 sim_memopt *alias;
1355 for (alias = entry->alias;
1356 alias != NULL;
1357 alias = alias->next)
1358 if ((alias->addr == K0BASE || alias->addr == K1BASE)
1359 && (!match || entry->level < match->level))
1360 match = entry;
1364 /* Get region size, limit to KSEG1 size (512MB). */
1365 SIM_ASSERT (match != NULL);
1366 mem_size = (match->modulo != 0
1367 ? match->modulo : match->nr_bytes);
1368 if (mem_size > K1SIZE)
1369 mem_size = K1SIZE;
1371 value = mem_size;
1372 H2T (value);
1373 sim_write (sd, A0 + 0, &value, 4);
1374 sim_write (sd, A0 + 4, &zero, 4);
1375 sim_write (sd, A0 + 8, &zero, 4);
1376 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1377 break;
1380 case 158: /* PMON printf */
1381 /* in: A0 = pointer to format string */
1382 /* A1 = optional argument 1 */
1383 /* A2 = optional argument 2 */
1384 /* A3 = optional argument 3 */
1385 /* out: void */
1386 /* The following is based on the PMON printf source */
1388 address_word s = A0;
1389 unsigned char c;
1390 address_word *ap = &A1; /* 1st argument */
1391 /* This isn't the quickest way, since we call the host print
1392 routine for every character almost. But it does avoid
1393 having to allocate and manage a temporary string buffer. */
1394 /* TODO: Include check that we only use three arguments (A1,
1395 A2 and A3) */
1396 while (sim_read (sd, s++, &c, 1) && c != '\0')
1398 if (c == '%')
1400 char tmp[40];
1401 /* The format logic isn't passed down.
1402 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
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))
1408 break;
1409 else if (c == '-')
1410 /* fmt = FMT_LJUST */;
1411 else if (c == '0')
1412 /* fmt = FMT_RJUST0 */;
1413 else if (c == '~')
1414 /* fmt = FMT_CENTER */;
1415 else if (c == '*')
1417 if (haddot)
1418 trunc = (int)*ap++;
1419 else
1420 width = (int)*ap++;
1422 else if (c >= '1' && c <= '9')
1424 address_word t = s;
1425 unsigned int n;
1426 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1427 tmp[s - t] = c;
1428 tmp[s - t] = '\0';
1429 n = (unsigned int)strtol(tmp,NULL,10);
1430 if (haddot)
1431 trunc = n;
1432 else
1433 width = n;
1434 s--;
1436 else if (c == '.')
1437 haddot = 1;
1439 switch (c)
1441 case '%':
1442 sim_io_printf (sd, "%%");
1443 break;
1444 case 's':
1445 if ((int)*ap != 0)
1447 address_word p = *ap++;
1448 unsigned char ch;
1449 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1450 sim_io_printf(sd, "%c", ch);
1452 else
1453 sim_io_printf(sd,"(null)");
1454 break;
1455 case 'c':
1456 sim_io_printf (sd, "%c", (int)*ap++);
1457 break;
1458 default:
1459 if (c == 'l')
1461 sim_read (sd, s++, &c, 1);
1462 if (c == 'l')
1464 longlong = 1;
1465 sim_read (sd, s++, &c, 1);
1468 if (strchr ("dobxXu", c))
1470 word64 lv = (word64) *ap++;
1471 if (c == 'b')
1472 sim_io_printf(sd,"<binary not supported>");
1473 else
1475 #define P_(c, fmt64, fmt32) \
1476 case c: \
1477 if (longlong) \
1478 sim_io_printf (sd, "%" fmt64, lv); \
1479 else \
1480 sim_io_printf (sd, "%" fmt32, (int)lv); \
1481 break;
1482 #define P(c, fmtc) P_(c, PRI##fmtc##64, PRI##fmtc##32)
1483 switch (c)
1485 P('d', d)
1486 P('o', o)
1487 P('x', x)
1488 P('X', X)
1489 P('u', u)
1492 #undef P
1493 #undef P_
1495 else if (strchr ("eEfgG", c))
1497 double dbl = *(double*)(ap++);
1499 #define P(c, fmtc) \
1500 case c: \
1501 sim_io_printf (sd, "%*.*" #fmtc, width, trunc, dbl); \
1502 break;
1503 switch (c)
1505 P('e', e)
1506 P('E', E)
1507 P('f', f)
1508 P('g', g)
1509 P('G', G)
1511 #undef P
1512 trunc = 0;
1516 else
1517 sim_io_printf(sd, "%c", c);
1519 break;
1522 default:
1523 /* Unknown reason. */
1524 return 0;
1526 return 1;
1529 /* Store a word into memory. */
1531 static void
1532 store_word (SIM_DESC sd,
1533 sim_cpu *cpu,
1534 address_word cia,
1535 uword64 vaddr,
1536 signed_word val)
1538 address_word paddr = vaddr;
1540 if ((vaddr & 3) != 0)
1541 SignalExceptionAddressStore ();
1542 else
1544 const uword64 mask = 7;
1545 uword64 memval;
1546 unsigned int byte;
1548 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1549 byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1550 memval = ((uword64) val) << (8 * byte);
1551 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr,
1552 isREAL);
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. */
1562 static signed_word
1563 load_word (SIM_DESC sd,
1564 sim_cpu *cpu,
1565 address_word cia,
1566 uword64 vaddr)
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);
1572 else
1574 address_word paddr = vaddr;
1575 const uword64 mask = 0x7;
1576 const unsigned int reverse = ReverseEndian ? 1 : 0;
1577 const unsigned int bigend = BigEndianCPU ? 1 : 0;
1578 uword64 memval;
1579 unsigned int byte;
1581 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1582 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA,
1583 isREAL);
1584 byte = (vaddr & mask) ^ (bigend << 2);
1585 return EXTEND32 (memval >> (8 * byte));
1588 return 0;
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. */
1595 static void
1596 mips16_entry (SIM_DESC sd,
1597 sim_cpu *cpu,
1598 address_word cia,
1599 unsigned int insn)
1601 int aregs, sregs, rreg;
1603 #ifdef DEBUG
1604 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1605 #endif /* DEBUG */
1607 aregs = (insn & 0x700) >> 8;
1608 sregs = (insn & 0x0c0) >> 6;
1609 rreg = (insn & 0x020) >> 5;
1611 /* This should be checked by the caller. */
1612 if (sregs == 3)
1613 abort ();
1615 if (aregs < 5)
1617 int i;
1618 signed_word tsp;
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]);
1625 tsp = SP;
1626 SP -= 32;
1628 if (rreg)
1630 tsp -= 4;
1631 store_word (SD, CPU, cia, (uword64) tsp, RA);
1634 for (i = 0; i < sregs; i++)
1636 tsp -= 4;
1637 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1640 else
1642 int i;
1643 signed_word tsp;
1645 /* This is the exit pseudo-instruction. */
1647 tsp = SP + 32;
1649 if (rreg)
1651 tsp -= 4;
1652 RA = load_word (SD, CPU, cia, (uword64) tsp);
1655 for (i = 0; i < sregs; i++)
1657 tsp -= 4;
1658 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1661 SP += 32;
1663 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1665 if (aregs == 5)
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;
1679 PC = RA;
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
1693 option. */
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:
1702 0 read data
1703 1 write data
1704 2 instruction fetch
1705 3 escape record (treated as unknown access type)
1706 4 escape record (causes cache flush)
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. */
1723 void
1724 dotrace (SIM_DESC sd,
1725 sim_cpu *cpu,
1726 FILE *tracefh,
1727 int type,
1728 address_word address,
1729 int width,
1730 const char *comment, ...)
1732 if (STATE & simTRACE) {
1733 va_list ap;
1734 fprintf(tracefh,"%d %s ; width %d ; ",
1735 type,
1736 pr_addr(address),
1737 width);
1738 va_start(ap,comment);
1739 vfprintf(tracefh,comment,ap);
1740 va_end(ap);
1741 fprintf(tracefh,"\n");
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
1749 being closed. */
1751 /* NOTE: We could consider adding a comment field to the "din" file
1752 produced using type 3 markers (unknown access). This would then
1753 allow information about the program that the "din" is for, and
1754 the MIPs world that was being simulated, to be placed into the
1755 trace file. */
1757 return;
1759 #endif /* WITH_TRACE_ANY_P */
1761 /*---------------------------------------------------------------------------*/
1762 /*-- simulator engine -------------------------------------------------------*/
1763 /*---------------------------------------------------------------------------*/
1765 static void
1766 ColdReset (SIM_DESC sd)
1768 int cpu_nr;
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
1785 cleared: */
1786 PENDING_INVALIDATE();
1788 /* Initialise the FPU registers to the unknown state */
1789 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1791 int rn;
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 */
1805 else
1806 C0_CONFIG |= (1 << 13); /* MIPS64, 32-bit addresses */
1808 if (BigEndianMem)
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. */
1821 void
1822 signal_exception (SIM_DESC sd,
1823 sim_cpu *cpu,
1824 address_word cia,
1825 int exception,...)
1827 /* int vector; */
1829 #ifdef DEBUG
1830 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1831 #endif /* DEBUG */
1833 /* Ensure that any active atomic read/modify/write operation will fail: */
1834 LLBIT = 0;
1836 /* Save registers before interrupt dispatching */
1837 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1838 SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1839 #endif
1841 switch (exception) {
1843 case DebugBreakPoint:
1844 if (! (Debug & Debug_DM))
1846 if (INDELAYSLOT())
1848 CANCELDELAYSLOT();
1850 Debug |= Debug_DBD; /* signaled from within in delay slot */
1851 DEPC = cia - 4; /* reference the branch instruction */
1853 else
1855 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1856 DEPC = cia;
1859 Debug |= Debug_DM; /* in debugging mode */
1860 Debug |= Debug_DBp; /* raising a DBp exception */
1861 PC = 0xBFC00200;
1862 sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1864 break;
1866 case ReservedInstruction:
1868 va_list ap;
1869 unsigned int instruction;
1870 va_start(ap,exception);
1871 instruction = va_arg(ap,unsigned int);
1872 va_end(ap);
1873 /* Provide simple monitor support using ReservedInstruction
1874 exceptions. The following code simulates the fixed vector
1875 entry points into the IDT monitor by causing a simulator
1876 trap, performing the monitor operation, and returning to
1877 the address held in the $ra register (standard PCS return
1878 address). This means we only need to pre-load the vector
1879 space with suitable instruction values. For systems were
1880 actual trap instructions are used, we would not need to
1881 perform this magic. */
1882 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
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;
1907 default:
1908 /* Store exception code into current exception id variable (used
1909 by exit code): */
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;
1925 CAUSE |= cause_BD;
1926 EPC = (cia - 4); /* reference the branch instruction */
1928 else
1929 EPC = cia;
1931 if (SR & status_BEV)
1932 PC = (signed)0xBFC00000 + 0x180;
1933 else
1934 PC = (signed)0x80000000 + 0x080;
1935 #else
1936 /* See figure 5-17 for an outline of the code below */
1937 if (! (SR & status_EXL))
1939 CAUSE = (exception << 2);
1940 if (STATE & simDELAYSLOT)
1942 STATE &= ~simDELAYSLOT;
1943 CAUSE |= cause_BD;
1944 EPC = (cia - 4); /* reference the branch instruction */
1946 else
1947 EPC = cia;
1948 /* FIXME: TLB et.al. */
1949 /* vector = 0x180; */
1951 else
1953 CAUSE = (exception << 2);
1954 /* vector = 0x180; */
1956 SR |= status_EXL;
1957 /* Store exception code into current exception id variable (used
1958 by exit code): */
1960 if (SR & status_BEV)
1961 PC = (signed)0xBFC00200 + 0x180;
1962 else
1963 PC = (signed)0x80000000 + 0x180;
1964 #endif
1966 switch ((CAUSE >> 2) & 0x1F)
1968 case Interrupt:
1969 /* Interrupts arrive during event processing, no need to
1970 restart */
1971 return;
1973 case NMIReset:
1974 /* Ditto */
1975 #ifdef SUBTARGET_3900
1976 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1977 PC = (signed)0xBFC00000;
1978 #endif /* SUBTARGET_3900 */
1979 return;
1981 case TLBModification:
1982 case TLBLoad:
1983 case TLBStore:
1984 case AddressLoad:
1985 case AddressStore:
1986 case InstructionFetch:
1987 case DataReference:
1988 /* The following is so that the simulator will continue from the
1989 exception handler address. */
1990 sim_engine_halt (SD, CPU, NULL, PC,
1991 sim_stopped, SIM_SIGBUS);
1993 case ReservedInstruction:
1994 case CoProcessorUnusable:
1995 PC = EPC;
1996 sim_engine_halt (SD, CPU, NULL, PC,
1997 sim_stopped, SIM_SIGILL);
1999 case IntegerOverflow:
2000 case FPE:
2001 sim_engine_halt (SD, CPU, NULL, PC,
2002 sim_stopped, SIM_SIGFPE);
2004 case BreakPoint:
2005 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
2006 break;
2008 case SystemCall:
2009 case Trap:
2010 sim_engine_restart (SD, CPU, NULL, PC);
2011 break;
2013 case Watch:
2014 PC = EPC;
2015 sim_engine_halt (SD, CPU, NULL, PC,
2016 sim_stopped, SIM_SIGTRAP);
2018 default: /* Unknown internal exception */
2019 PC = EPC;
2020 sim_engine_halt (SD, CPU, NULL, PC,
2021 sim_stopped, SIM_SIGABRT);
2025 case SimulatorFault:
2027 va_list ap;
2028 char *msg;
2029 va_start(ap,exception);
2030 msg = va_arg(ap,char *);
2031 va_end(ap);
2032 sim_engine_abort (SD, CPU, NULL_CIA,
2033 "FATAL: Simulator error \"%s\"\n",msg);
2037 return;
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
2051 0.95, page 2.)
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. */
2059 void
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 ------------------------------------------*/
2071 static int UNUSED
2072 CoProcPresent(unsigned int coproc_number)
2074 /* Return TRUE if simulator provides a model for the given co-processor number */
2075 return(0);
2078 void
2079 cop_lw (SIM_DESC sd,
2080 sim_cpu *cpu,
2081 address_word cia,
2082 int coproc_num,
2083 int coproc_reg,
2084 unsigned int memword)
2086 switch (coproc_num)
2088 case 1:
2089 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2091 #ifdef DEBUG
2092 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2093 #endif
2094 StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
2095 break;
2098 default:
2099 #if 0 /* this should be controlled by a configuration option */
2100 sim_io_printf(sd,"COP_LW(%d,%d,0x%08X) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,memword,pr_addr(cia));
2101 #endif
2102 break;
2105 return;
2108 void
2109 cop_ld (SIM_DESC sd,
2110 sim_cpu *cpu,
2111 address_word cia,
2112 int coproc_num,
2113 int coproc_reg,
2114 uword64 memword)
2117 #ifdef DEBUG
2118 printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia));
2119 #endif
2121 switch (coproc_num) {
2122 case 1:
2123 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2125 StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
2126 break;
2129 default:
2130 #if 0 /* this message should be controlled by a configuration option */
2131 sim_io_printf(sd,"COP_LD(%d,%d,0x%s) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(memword),pr_addr(cia));
2132 #endif
2133 break;
2136 return;
2142 unsigned int
2143 cop_sw (SIM_DESC sd,
2144 sim_cpu *cpu,
2145 address_word cia,
2146 int coproc_num,
2147 int coproc_reg)
2149 unsigned int value = 0;
2151 switch (coproc_num)
2153 case 1:
2154 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2156 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
2157 break;
2160 default:
2161 #if 0 /* should be controlled by configuration option */
2162 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2163 #endif
2164 break;
2167 return(value);
2170 uword64
2171 cop_sd (SIM_DESC sd,
2172 sim_cpu *cpu,
2173 address_word cia,
2174 int coproc_num,
2175 int coproc_reg)
2177 uword64 value = 0;
2178 switch (coproc_num)
2180 case 1:
2181 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2183 value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
2184 break;
2187 default:
2188 #if 0 /* should be controlled by configuration option */
2189 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2190 #endif
2191 break;
2194 return(value);
2200 void
2201 decode_coproc (SIM_DESC sd,
2202 sim_cpu *cpu,
2203 address_word cia,
2204 unsigned int instruction,
2205 int coprocnum,
2206 CP0_operation op,
2207 int rt,
2208 int rd,
2209 int sel)
2211 switch (coprocnum)
2213 case 0: /* standard CPU control and cache registers */
2215 /* R4000 Users Manual (second edition) lists the following CP0
2216 instructions:
2217 CODE><-RT><RD-><--TAIL--->
2218 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2219 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2220 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2221 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2222 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2223 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2224 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2225 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2226 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2227 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2229 if (((op == cp0_mfc0) || (op == cp0_mtc0) /* MFC0 / MTC0 */
2230 || (op == cp0_dmfc0) || (op == cp0_dmtc0)) /* DMFC0 / DMTC0 */
2231 && sel == 0)
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
2248 case 3:
2249 /* 3 = Config R3900 */
2250 case 7:
2251 /* 7 = Cache R3900 */
2252 case 15:
2253 /* 15 = PRID R3900 */
2255 /* ignore */
2256 break;
2258 case 8:
2259 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2260 if (op == cp0_mfc0 || op == cp0_dmfc0)
2261 GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
2262 else
2263 COP0_BADVADDR = GPR[rt];
2264 break;
2266 #endif /* SUBTARGET_R3900 */
2267 case 12:
2268 if (op == cp0_mfc0 || op == cp0_dmfc0)
2269 GPR[rt] = SR;
2270 else
2271 SR = GPR[rt];
2272 break;
2273 /* 13 = Cause R4000 VR4100 VR4300 */
2274 case 13:
2275 if (op == cp0_mfc0 || op == cp0_dmfc0)
2276 GPR[rt] = CAUSE;
2277 else
2278 CAUSE = GPR[rt];
2279 break;
2280 /* 14 = EPC R4000 VR4100 VR4300 */
2281 case 14:
2282 if (op == cp0_mfc0 || op == cp0_dmfc0)
2283 GPR[rt] = (signed_word) (signed_address) EPC;
2284 else
2285 EPC = GPR[rt];
2286 break;
2287 /* 15 = PRId R4000 VR4100 VR4300 */
2288 #ifdef SUBTARGET_R3900
2289 /* 16 = Debug */
2290 case 16:
2291 if (op == cp0_mfc0 || op == cp0_dmfc0)
2292 GPR[rt] = Debug;
2293 else
2294 Debug = GPR[rt];
2295 break;
2296 #else
2297 /* 16 = Config R4000 VR4100 VR4300 */
2298 case 16:
2299 if (op == cp0_mfc0 || op == cp0_dmfc0)
2300 GPR[rt] = C0_CONFIG;
2301 else
2302 /* only bottom three bits are writable */
2303 C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7);
2304 break;
2305 #endif
2306 #ifdef SUBTARGET_R3900
2307 /* 17 = Debug */
2308 case 17:
2309 if (op == cp0_mfc0 || op == cp0_dmfc0)
2310 GPR[rt] = DEPC;
2311 else
2312 DEPC = GPR[rt];
2313 break;
2314 #else
2315 /* 17 = LLAddr R4000 VR4100 VR4300 */
2316 #endif
2317 /* 18 = WatchLo R4000 VR4100 VR4300 */
2318 /* 19 = WatchHi R4000 VR4100 VR4300 */
2319 /* 20 = XContext R4000 VR4100 VR4300 */
2320 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2321 /* 27 = CacheErr R4000 VR4100 */
2322 /* 28 = TagLo R4000 VR4100 VR4300 */
2323 /* 29 = TagHi R4000 VR4100 VR4300 */
2324 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
2325 if (STATE_VERBOSE_P(SD))
2326 sim_io_eprintf (SD,
2327 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2328 (unsigned long)cia);
2329 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
2330 ATTRIBUTE_FALLTHROUGH;
2331 /* CPR[0,rd] = GPR[rt]; */
2332 default:
2333 if (op == cp0_mfc0 || op == cp0_dmfc0)
2334 GPR[rt] = (signed_word) (int32_t) COP0_GPR[rd];
2335 else
2336 COP0_GPR[rd] = GPR[rt];
2337 #if 0
2338 if (code == 0x00)
2339 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2340 else
2341 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2342 #endif
2345 else if ((op == cp0_mfc0 || op == cp0_dmfc0)
2346 && rd == 16)
2348 /* [D]MFC0 RT,C0_CONFIG,SEL */
2349 int32_t cfg = 0;
2350 switch (sel)
2352 case 0:
2353 cfg = C0_CONFIG;
2354 break;
2355 case 1:
2356 /* MIPS32 r/o Config1:
2357 Config2 present */
2358 cfg = 0x80000000;
2359 /* MIPS16 implemented.
2360 XXX How to check configuration? */
2361 cfg |= 0x0000004;
2362 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2363 /* MDMX & FPU implemented */
2364 cfg |= 0x00000021;
2365 break;
2366 case 2:
2367 /* MIPS32 r/o Config2:
2368 Config3 present. */
2369 cfg = 0x80000000;
2370 break;
2371 case 3:
2372 /* MIPS32 r/o Config3:
2373 SmartMIPS implemented. */
2374 cfg = 0x00000002;
2375 break;
2377 GPR[rt] = cfg;
2379 else if (op == cp0_eret && sel == 0x18)
2381 /* ERET */
2382 if (SR & status_ERL)
2384 /* Oops, not yet available */
2385 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
2386 PC = EPC;
2387 SR &= ~status_ERL;
2389 else
2391 PC = EPC;
2392 SR &= ~status_EXL;
2395 else if (op == cp0_rfe && sel == 0x10)
2397 /* RFE */
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)
2409 /* DERET */
2410 Debug &= ~Debug_DM;
2411 DELAYSLOT();
2412 DSPC = DEPC;
2414 else
2415 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
2416 /* TODO: When executing an ERET or RFE instruction we should
2417 clear LLBIT, to ensure that any out-standing atomic
2418 read/modify/write sequence fails. */
2420 break;
2422 case 2: /* co-processor 2 */
2424 int handle = 0;
2427 if (!handle)
2429 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2430 instruction,pr_addr(cia));
2433 break;
2435 case 1: /* should not occur (FPU co-processor) */
2436 case 3: /* should not occur (FPU co-processor) */
2437 SignalException(ReservedInstruction,instruction);
2438 break;
2441 return;
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 */
2449 #define NUMCELLS 16
2450 #define CELLSIZE 32
2451 static char*
2452 get_cell (void)
2454 static char buf[NUMCELLS][CELLSIZE];
2455 static int cell=0;
2456 if (++cell>=NUMCELLS) cell=0;
2457 return buf[cell];
2460 /* Print routines to handle variable size regs, etc */
2462 char*
2463 pr_addr (address_word addr)
2465 char *paddr_str=get_cell();
2466 sprintf (paddr_str, "%0*" PRIxTA, (int) (sizeof (addr) * 2), addr);
2467 return paddr_str;
2470 char*
2471 pr_uword64 (uword64 addr)
2473 char *paddr_str=get_cell();
2474 sprintf (paddr_str, "%016" PRIx64, addr);
2475 return paddr_str;
2479 void
2480 mips_core_signal (SIM_DESC sd,
2481 sim_cpu *cpu,
2482 sim_cia cia,
2483 unsigned map,
2484 int nr_bytes,
2485 address_word addr,
2486 transfer_type transfer,
2487 sim_core_signals sig)
2489 const char *copy = (transfer == read_transfer ? "read" : "write");
2490 address_word ip = CIA_ADDR (cia);
2492 switch (sig)
2494 case sim_core_unmapped_signal:
2495 sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2496 nr_bytes, copy,
2497 (unsigned long) addr, (unsigned long) ip);
2498 COP0_BADVADDR = addr;
2499 SignalExceptionDataReference();
2500 /* Shouldn't actually be reached. */
2501 abort ();
2503 case sim_core_unaligned_signal:
2504 sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
2505 nr_bytes, copy,
2506 (unsigned long) addr, (unsigned long) ip);
2507 COP0_BADVADDR = addr;
2508 if (transfer == read_transfer)
2509 SignalExceptionAddressLoad();
2510 else
2511 SignalExceptionAddressStore();
2512 /* Shouldn't actually be reached. */
2513 abort ();
2515 default:
2516 sim_engine_abort (sd, cpu, cia,
2517 "mips_core_signal - internal error - bad switch");
2522 void
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);
2533 PC = cia;
2534 memcpy (mips_cpu->exc_trigger_registers, mips_cpu->registers,
2535 sizeof (mips_cpu->exc_trigger_registers));
2536 mips_cpu->exc_suspended = 0;
2539 void
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;
2557 void
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 <*/