interp.c revision 1.1.1.7 1 /*> interp.c <*/
2 /* Simulator for the MIPS architecture.
3
4 This file is part of the MIPS sim
5
6 THIS SOFTWARE IS NOT COPYRIGHTED
7
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.
11
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.
15
16 NOTEs:
17
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.
22
23 */
24
25 /* This must come before any other includes. */
26 #include "defs.h"
27
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"
35
36 #include "itable.h"
37
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>
46
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 */
54
55 char* pr_addr (address_word addr);
56 char* pr_uword64 (uword64 addr);
57
58
59 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
60 #define CPU cpu
61 #define SD sd
62
63
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. */
67
68 #define RSVD_INSTRUCTION (0x00000039)
69 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
70
71 #define RSVD_INSTRUCTION_ARG_SHIFT 6
72 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
73
74
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 */
79
80 /*---------------------------------------------------------------------------*/
81 /*-- GDB simulator interface ------------------------------------------------*/
82 /*---------------------------------------------------------------------------*/
83
84 static void ColdReset (SIM_DESC sd);
85
86 /*---------------------------------------------------------------------------*/
87
88
89
90 #define DELAYSLOT() {\
91 if (STATE & simDELAYSLOT)\
92 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
93 STATE |= simDELAYSLOT;\
94 }
95
96 #define JALDELAYSLOT() {\
97 DELAYSLOT ();\
98 STATE |= simJALDELAYSLOT;\
99 }
100
101 #define NULLIFY() {\
102 STATE &= ~simDELAYSLOT;\
103 STATE |= simSKIPNEXT;\
104 }
105
106 #define CANCELDELAYSLOT() {\
107 DSSTATE = 0;\
108 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
109 }
110
111 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
112 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
113
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)
123
124 /* Simple run-time monitor support.
125
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.
130
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;
140
141 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
142
143 #define MEM_SIZE (8 << 20) /* 8 MBytes */
144
145
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
153
154 static const char * get_insn_name (sim_cpu *, int);
155
156 /* simulation target board. NULL=canonical */
157 static char* board = NULL;
158
159
160 static DECLARE_OPTION_HANDLER (mips_option_handler);
161
162 enum {
163 OPTION_DINERO_TRACE = OPTION_START,
164 OPTION_DINERO_FILE,
165 OPTION_FIRMWARE,
166 OPTION_INFO_MEMORY,
167 OPTION_BOARD
168 };
169
170 static int display_mem_info = 0;
171
172 static SIM_RC
173 mips_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
174 int is_command)
175 {
176 int cpu_nr;
177 switch (opt)
178 {
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++)
186 {
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
199 {
200 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
201 return SIM_RC_FAIL;
202 }
203 }
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 */
211
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)
218 {
219 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
220 return SIM_RC_FAIL;
221 }
222 else {
223 strcpy(tmp,optarg);
224 tracefile = tmp;
225 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
226 }
227 }
228 #endif /* WITH_TRACE_ANY_P */
229 return SIM_RC_OK;
230
231 case OPTION_FIRMWARE:
232 return sim_firmware_command (sd, arg);
233
234 case OPTION_BOARD:
235 {
236 if (arg)
237 {
238 board = zalloc(strlen(arg) + 1);
239 strcpy(board, arg);
240 }
241 return SIM_RC_OK;
242 }
243
244 case OPTION_INFO_MEMORY:
245 display_mem_info = 1;
246 break;
247 }
248
249 return SIM_RC_OK;
250 }
251
252
253 static const OPTION mips_options[] =
254 {
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 */
266
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
275
276 , "Customize simulation for a particular board.", mips_option_handler },
277
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 },
291
292 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
293 };
294
295
296 int interrupt_pending;
297
298 void
299 interrupt_event (SIM_DESC sd, void *data)
300 {
301 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
302 address_word cia = CPU_PC_GET (cpu);
303 if (SR & status_IE)
304 {
305 interrupt_pending = 0;
306 SignalExceptionInterrupt (1); /* interrupt "1" */
307 }
308 else if (!interrupt_pending)
309 sim_events_schedule (sd, 1, interrupt_event, data);
310 }
311
312
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
321 }
322
323 /*---------------------------------------------------------------------------*/
324 /*-- GDB simulator interface ------------------------------------------------*/
325 /*---------------------------------------------------------------------------*/
326
327 static sim_cia
328 mips_pc_get (sim_cpu *cpu)
329 {
330 return PC;
331 }
332
333 static void
334 mips_pc_set (sim_cpu *cpu, sim_cia pc)
335 {
336 PC = pc;
337 }
338
339 static int mips_reg_fetch (SIM_CPU *, int, void *, int);
340 static int mips_reg_store (SIM_CPU *, int, const void *, int);
341
342 SIM_DESC
343 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
344 struct bfd *abfd, char * const *argv)
345 {
346 int i;
347 SIM_DESC sd = sim_state_alloc_extra (kind, cb,
348 sizeof (struct mips_sim_state));
349 sim_cpu *cpu;
350
351 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
352
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;
357
358 cpu = STATE_CPU (sd, 0); /* FIXME */
359
360 /* FIXME: watchpoints code shouldn't need this */
361 STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
362
363 /* Initialize the mechanism for doing insn profiling. */
364 CPU_INSN_NAME (cpu) = get_insn_name;
365 CPU_MAX_INSNS (cpu) = nr_itable_entries;
366
367 STATE = 0;
368
369 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
370 return 0;
371 sim_add_option_table (sd, NULL, mips_options);
372
373
374 /* The parser will print an error message for us, so we silently return. */
375 if (sim_parse_args (sd, argv) != SIM_RC_OK)
376 {
377 /* Uninstall the modules to avoid memory leaks,
378 file descriptor leaks, etc. */
379 sim_module_uninstall (sd);
380 return 0;
381 }
382
383 /* handle board-specific memory maps */
384 if (board == NULL)
385 {
386 /* Allocate core managed memory */
387 sim_memopt *entry, *match = NULL;
388 address_word mem_size = 0;
389 int mapped = 0;
390
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 */
395
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)
399 {
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
409 {
410 sim_memopt *alias;
411 for (alias = entry->alias; alias != NULL; alias = alias->next)
412 {
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;
418 }
419 }
420 }
421
422 if (!mapped)
423 {
424 if (match)
425 {
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);
432 }
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));
444 }
445
446 device_init(sd);
447 }
448 else if (board != NULL
449 && (strcmp(board, BOARD_BSP) == 0))
450 {
451 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
452
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);
458
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);
464
465 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
466 for (i=0; i<8; i++) /* 32 MB total */
467 {
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));
473 }
474 }
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))
480 {
481 /* match VIRTUAL memory layout of JMR-TX3904 board */
482
483 /* --- disable monitor unless forced on by user --- */
484
485 if (! firmware_option_p)
486 {
487 idt_monitor_base = 0;
488 pmon_monitor_base = 0;
489 lsipmon_monitor_base = 0;
490 }
491
492 /* --- environment --- */
493
494 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
495
496 /* --- memory --- */
497
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);
503
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);
509
510 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
511 for (i=0; i<8; i++) /* 32 MB total */
512 {
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));
518 }
519
520 /* Dummy memory regions for unsimulated devices - sorted by address */
521
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 */
531
532
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");
540 {
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");
552 }
553 sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
554 sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
555
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");
563
564 /* add PAL timer & I/O module */
565 if (!strcmp(board, BOARD_JMR3904_PAL))
566 {
567 /* the device */
568 sim_hw_parse (sd, "/pal@0xffff0000");
569 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
570
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");
575 }
576
577 if (!strcmp(board, BOARD_JMR3904_DEBUG))
578 {
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");
599 }
600
601 device_init(sd);
602 }
603 #endif
604
605 if (display_mem_info)
606 {
607 struct option_list * ol;
608 struct option_list * prev;
609
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;
620
621 SIM_ASSERT (ol != NULL);
622
623 if (prev == NULL)
624 STATE_OPTIONS (sd) = ol->next;
625 else
626 prev->next = ol->next;
627
628 sim_do_commandf (sd, "memory-info");
629 }
630
631 /* check for/establish the a reference program image */
632 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
633 {
634 sim_module_uninstall (sd);
635 return 0;
636 }
637
638 /* Configure/verify the target byte order and other runtime
639 configuration options */
640 if (sim_config (sd) != SIM_RC_OK)
641 {
642 sim_module_uninstall (sd);
643 return 0;
644 }
645
646 if (sim_post_argv_init (sd) != SIM_RC_OK)
647 {
648 /* Uninstall the modules to avoid memory leaks,
649 file descriptor leaks, etc. */
650 sim_module_uninstall (sd);
651 return 0;
652 }
653
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)));
658
659 /* This is NASTY, in that we are assuming the size of specific
660 registers: */
661 {
662 int rn;
663 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
664 {
665 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
666
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;
680 }
681
682
683 }
684
685 if (STATE & simTRACE)
686 open_trace(sd);
687
688 /*
689 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
690 idt_monitor_base,
691 pmon_monitor_base,
692 lsipmon_monitor_base);
693 */
694
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)
699 {
700 unsigned loop;
701 address_word idt_monitor_size = 1 << 11;
702
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);
711
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)
717 {
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));
724 }
725 }
726
727 if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
728 {
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++)
737 {
738 uint32_t value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
739 switch (loop)
740 {
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;
762 }
763
764 SIM_ASSERT (idt_monitor_base != 0);
765 value = ((unsigned int) idt_monitor_base + (value * 8));
766 H2T (value);
767
768 if (pmon_monitor_base != 0)
769 {
770 address_word vaddr = (pmon_monitor_base + (loop * 4));
771 sim_write (sd, vaddr, &value, sizeof (value));
772 }
773
774 if (lsipmon_monitor_base != 0)
775 {
776 address_word vaddr = (lsipmon_monitor_base + (loop * 4));
777 sim_write (sd, vaddr, &value, sizeof (value));
778 }
779 }
780
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))
787 {
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));
799 }
800 }
801
802 /* CPU specific initialization. */
803 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
804 {
805 cpu = STATE_CPU (sd, i);
806
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;
811 }
812
813 return sd;
814 }
815
816 #if WITH_TRACE_ANY_P
817 static void
818 open_trace (SIM_DESC sd)
819 {
820 tracefh = fopen(tracefile,"wb+");
821 if (tracefh == NULL)
822 {
823 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
824 tracefh = stderr;
825 }
826 }
827 #endif
828
829 /* Return name of an insn, used by insn profiling. */
830 static const char *
831 get_insn_name (sim_cpu *cpu, int i)
832 {
833 return itable[i].name;
834 }
835
836 void
837 mips_sim_close (SIM_DESC sd, int quitting)
838 {
839 #if WITH_TRACE_ANY_P
840 if (tracefh != NULL && tracefh != stderr)
841 fclose(tracefh);
842 tracefh = NULL;
843 #endif
844 }
845
846 static int
847 mips_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
848 {
849 /* NOTE: gdb (the client) stores registers in target byte order
850 while the simulator uses host byte order */
851
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. */
855
856 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
857
858 if (mips_cpu->register_widths[rn] == 0)
859 {
860 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
861 return 0;
862 }
863
864 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
865 {
866 mips_cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
867 if (mips_cpu->register_widths[rn] == 32)
868 {
869 if (length == 8)
870 {
871 mips_cpu->fgr[rn - FGR_BASE] =
872 (uint32_t) T2H_8 (*(uint64_t*)memory);
873 return 8;
874 }
875 else
876 {
877 mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
878 return 4;
879 }
880 }
881 else
882 {
883 if (length == 8)
884 {
885 mips_cpu->fgr[rn - FGR_BASE] = T2H_8 (*(uint64_t*)memory);
886 return 8;
887 }
888 else
889 {
890 mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
891 return 4;
892 }
893 }
894 }
895
896 if (mips_cpu->register_widths[rn] == 32)
897 {
898 if (length == 8)
899 {
900 mips_cpu->registers[rn] =
901 (uint32_t) T2H_8 (*(uint64_t*)memory);
902 return 8;
903 }
904 else
905 {
906 mips_cpu->registers[rn] = T2H_4 (*(uint32_t*)memory);
907 return 4;
908 }
909 }
910 else
911 {
912 if (length == 8)
913 {
914 mips_cpu->registers[rn] = T2H_8 (*(uint64_t*)memory);
915 return 8;
916 }
917 else
918 {
919 mips_cpu->registers[rn] = (int32_t) T2H_4(*(uint32_t*)memory);
920 return 4;
921 }
922 }
923
924 return 0;
925 }
926
927 static int
928 mips_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
929 {
930 /* NOTE: gdb (the client) stores registers in target byte order
931 while the simulator uses host byte order */
932
933 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
934
935 if (mips_cpu->register_widths[rn] == 0)
936 {
937 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
938 return 0;
939 }
940
941 /* Any floating point register */
942 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
943 {
944 if (mips_cpu->register_widths[rn] == 32)
945 {
946 if (length == 8)
947 {
948 *(uint64_t*)memory =
949 H2T_8 ((uint32_t) (mips_cpu->fgr[rn - FGR_BASE]));
950 return 8;
951 }
952 else
953 {
954 *(uint32_t*)memory = H2T_4 (mips_cpu->fgr[rn - FGR_BASE]);
955 return 4;
956 }
957 }
958 else
959 {
960 if (length == 8)
961 {
962 *(uint64_t*)memory = H2T_8 (mips_cpu->fgr[rn - FGR_BASE]);
963 return 8;
964 }
965 else
966 {
967 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->fgr[rn - FGR_BASE]));
968 return 4;
969 }
970 }
971 }
972
973 if (mips_cpu->register_widths[rn] == 32)
974 {
975 if (length == 8)
976 {
977 *(uint64_t*)memory =
978 H2T_8 ((uint32_t) (mips_cpu->registers[rn]));
979 return 8;
980 }
981 else
982 {
983 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
984 return 4;
985 }
986 }
987 else
988 {
989 if (length == 8)
990 {
991 *(uint64_t*)memory =
992 H2T_8 ((uint64_t) (mips_cpu->registers[rn]));
993 return 8;
994 }
995 else
996 {
997 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
998 return 4;
999 }
1000 }
1001
1002 return 0;
1003 }
1004
1005 SIM_RC
1006 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1007 char * const *argv, char * const *env)
1008 {
1009
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 */
1016
1017 ColdReset(sd);
1018
1019 if (abfd != NULL)
1020 {
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++)
1024 {
1025 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1026 sim_cia pc = bfd_get_start_address (abfd);
1027
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;
1034
1035 CPU_PC_SET (cpu, pc);
1036 }
1037 }
1038
1039 #if 0 /* def DEBUG */
1040 if (argv || env)
1041 {
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);
1050 }
1051 #endif /* DEBUG */
1052
1053 return SIM_RC_OK;
1054 }
1055
1056 /*---------------------------------------------------------------------------*/
1057 /*-- Private simulator support interface ------------------------------------*/
1058 /*---------------------------------------------------------------------------*/
1059
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)
1064 {
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;
1073 }
1074
1075
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)
1084 {
1085 int address_present = 0;
1086 address_word address;
1087
1088 /* Signal occurrence of this option. */
1089 firmware_option_p = 1;
1090
1091 /* Parse out the address, if present. */
1092 {
1093 char *p = strchr (arg, '@');
1094 if (p)
1095 {
1096 char *q;
1097 address_present = 1;
1098 p ++; /* skip over @ */
1099
1100 address = strtoul (p, &q, 0);
1101 if (*q != '\0')
1102 {
1103 sim_io_printf (sd, "Invalid address given to the"
1104 "`sim firmware NAME@ADDRESS' command: %s\n",
1105 p);
1106 return SIM_RC_FAIL;
1107 }
1108 }
1109 else
1110 {
1111 address_present = 0;
1112 address = -1; /* Dummy value. */
1113 }
1114 }
1115
1116 if (! strncmp (arg, "idt", 3))
1117 {
1118 idt_monitor_base = address_present ? address : 0xBFC00000;
1119 pmon_monitor_base = 0;
1120 lsipmon_monitor_base = 0;
1121 }
1122 else if (! strncmp (arg, "pmon", 4))
1123 {
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;
1128 }
1129 else if (! strncmp (arg, "lsipmon", 7))
1130 {
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;
1135 }
1136 else if (! strncmp (arg, "none", 4))
1137 {
1138 if (address_present)
1139 {
1140 sim_io_printf (sd,
1141 "The `sim firmware none' command does "
1142 "not take an `ADDRESS' argument.\n");
1143 return SIM_RC_FAIL;
1144 }
1145 idt_monitor_base = 0;
1146 pmon_monitor_base = 0;
1147 lsipmon_monitor_base = 0;
1148 }
1149 else
1150 {
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;
1156 }
1157
1158 return SIM_RC_OK;
1159 }
1160
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";
1166
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";
1171
1172 /* Map for calls using the host struct stat. */
1173 static const CB_TARGET_DEFS_MAP CB_stat_map[] =
1174 {
1175 { "stat", CB_SYS_stat, 15 },
1176 { 0, -1, -1 }
1177 };
1178
1179
1180 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1181 int
1182 sim_monitor (SIM_DESC sd,
1183 sim_cpu *cpu,
1184 address_word cia,
1185 unsigned int reason)
1186 {
1187 #ifdef DEBUG
1188 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1189 #endif /* DEBUG */
1190
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;
1195
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)
1200 {
1201
1202 case 6: /* int open(char *path,int flags) */
1203 {
1204 char *path = fetch_str (sd, A0);
1205 V0 = sim_io_open (sd, path, (int)A1);
1206 free (path);
1207 break;
1208 }
1209
1210 case 7: /* int read(int file,char *ptr,int len) */
1211 {
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);
1218 }
1219 break;
1220
1221 case 8: /* int write(int file,char *ptr,int len) */
1222 {
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;
1234 }
1235
1236 case 10: /* int close(int file) */
1237 {
1238 V0 = sim_io_close (sd, (int)A0);
1239 break;
1240 }
1241
1242 case 2: /* Densan monitor: char inbyte(int waitflag) */
1243 {
1244 if (A0 == 0) /* waitflag == NOWAIT */
1245 V0 = (unsigned_word)-1;
1246 }
1247 ATTRIBUTE_FALLTHROUGH;
1248
1249 case 11: /* char inbyte(void) */
1250 {
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))
1255 {
1256 sim_io_error(sd,"Invalid return from character read");
1257 V0 = (unsigned_word)-1;
1258 }
1259 else
1260 V0 = (unsigned_word)tmp;
1261 break;
1262 }
1263
1264 case 3: /* Densan monitor: void co(char chr) */
1265 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1266 {
1267 char tmp = (char)(A0 & 0xFF);
1268 sim_io_write_stdout (sd, &tmp, sizeof(char));
1269 break;
1270 }
1271
1272 case 13: /* int unlink(const char *path) */
1273 {
1274 char *path = fetch_str (sd, A0);
1275 V0 = sim_io_unlink (sd, path);
1276 free (path);
1277 break;
1278 }
1279
1280 case 14: /* int lseek(int fd, int offset, int whence) */
1281 {
1282 V0 = sim_io_lseek (sd, A0, A1, A2);
1283 break;
1284 }
1285
1286 case 15: /* int stat(const char *path, struct stat *buf); */
1287 {
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;
1308
1309 cb->syscall_map = (CB_TARGET_DEFS_MAP *) CB_stat_map;
1310 cb->stat_map = is_elf32bit ? stat32_map : stat64_map;
1311
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);
1315
1316 V0 = s.result;
1317 cb->stat_map = saved_map;
1318 cb->syscall_map = saved_syscall_map;
1319 break;
1320 }
1321
1322 case 17: /* void _exit() */
1323 {
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;
1328 }
1329
1330 case 28: /* PMON flush_cache */
1331 break;
1332
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 */
1338 {
1339 unsigned_4 value;
1340 unsigned_4 zero = 0;
1341 address_word mem_size;
1342 sim_memopt *entry, *match = NULL;
1343
1344 /* Search for memory region mapped to KSEG0 or KSEG1. */
1345 for (entry = STATE_MEMOPT (sd);
1346 entry != NULL;
1347 entry = entry->next)
1348 {
1349 if ((entry->addr == K0BASE || entry->addr == K1BASE)
1350 && (!match || entry->level < match->level))
1351 match = entry;
1352 else
1353 {
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;
1361 }
1362 }
1363
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;
1370
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;
1378 }
1379
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 */
1387 {
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')
1397 {
1398 if (c == '%')
1399 {
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;
1403 */
1404 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1405 while (sim_read (sd, s++, &c, 1) && c != '\0')
1406 {
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 == '*')
1416 {
1417 if (haddot)
1418 trunc = (int)*ap++;
1419 else
1420 width = (int)*ap++;
1421 }
1422 else if (c >= '1' && c <= '9')
1423 {
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--;
1435 }
1436 else if (c == '.')
1437 haddot = 1;
1438 }
1439 switch (c)
1440 {
1441 case '%':
1442 sim_io_printf (sd, "%%");
1443 break;
1444 case 's':
1445 if ((int)*ap != 0)
1446 {
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);
1451 }
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')
1460 {
1461 sim_read (sd, s++, &c, 1);
1462 if (c == 'l')
1463 {
1464 longlong = 1;
1465 sim_read (sd, s++, &c, 1);
1466 }
1467 }
1468 if (strchr ("dobxXu", c))
1469 {
1470 word64 lv = (word64) *ap++;
1471 if (c == 'b')
1472 sim_io_printf(sd,"<binary not supported>");
1473 else
1474 {
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)
1484 {
1485 P('d', d)
1486 P('o', o)
1487 P('x', x)
1488 P('X', X)
1489 P('u', u)
1490 }
1491 }
1492 #undef P
1493 #undef P_
1494 }
1495 else if (strchr ("eEfgG", c))
1496 {
1497 double dbl = *(double*)(ap++);
1498
1499 #define P(c, fmtc) \
1500 case c: \
1501 sim_io_printf (sd, "%*.*" #fmtc, width, trunc, dbl); \
1502 break;
1503 switch (c)
1504 {
1505 P('e', e)
1506 P('E', E)
1507 P('f', f)
1508 P('g', g)
1509 P('G', G)
1510 }
1511 #undef P
1512 trunc = 0;
1513 }
1514 }
1515 }
1516 else
1517 sim_io_printf(sd, "%c", c);
1518 }
1519 break;
1520 }
1521
1522 default:
1523 /* Unknown reason. */
1524 return 0;
1525 }
1526 return 1;
1527 }
1528
1529 /* Store a word into memory. */
1530
1531 static void
1532 store_word (SIM_DESC sd,
1533 sim_cpu *cpu,
1534 address_word cia,
1535 uword64 vaddr,
1536 signed_word val)
1537 {
1538 address_word paddr = vaddr;
1539
1540 if ((vaddr & 3) != 0)
1541 SignalExceptionAddressStore ();
1542 else
1543 {
1544 const uword64 mask = 7;
1545 uword64 memval;
1546 unsigned int byte;
1547
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);
1553 }
1554 }
1555
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)
1559
1560 /* Load a word from memory. */
1561
1562 static signed_word
1563 load_word (SIM_DESC sd,
1564 sim_cpu *cpu,
1565 address_word cia,
1566 uword64 vaddr)
1567 {
1568 if ((vaddr & 3) != 0 && !MIPSR6_P (STATE_PROG_BFD (sd)))
1569 {
1570 SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1571 }
1572 else
1573 {
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;
1580
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));
1586 }
1587
1588 return 0;
1589 }
1590
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. */
1594
1595 static void
1596 mips16_entry (SIM_DESC sd,
1597 sim_cpu *cpu,
1598 address_word cia,
1599 unsigned int insn)
1600 {
1601 int aregs, sregs, rreg;
1602
1603 #ifdef DEBUG
1604 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1605 #endif /* DEBUG */
1606
1607 aregs = (insn & 0x700) >> 8;
1608 sregs = (insn & 0x0c0) >> 6;
1609 rreg = (insn & 0x020) >> 5;
1610
1611 /* This should be checked by the caller. */
1612 if (sregs == 3)
1613 abort ();
1614
1615 if (aregs < 5)
1616 {
1617 int i;
1618 signed_word tsp;
1619
1620 /* This is the entry pseudo-instruction. */
1621
1622 for (i = 0; i < aregs; i++)
1623 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1624
1625 tsp = SP;
1626 SP -= 32;
1627
1628 if (rreg)
1629 {
1630 tsp -= 4;
1631 store_word (SD, CPU, cia, (uword64) tsp, RA);
1632 }
1633
1634 for (i = 0; i < sregs; i++)
1635 {
1636 tsp -= 4;
1637 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1638 }
1639 }
1640 else
1641 {
1642 int i;
1643 signed_word tsp;
1644
1645 /* This is the exit pseudo-instruction. */
1646
1647 tsp = SP + 32;
1648
1649 if (rreg)
1650 {
1651 tsp -= 4;
1652 RA = load_word (SD, CPU, cia, (uword64) tsp);
1653 }
1654
1655 for (i = 0; i < sregs; i++)
1656 {
1657 tsp -= 4;
1658 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1659 }
1660
1661 SP += 32;
1662
1663 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1664 {
1665 if (aregs == 5)
1666 {
1667 FGR[0] = WORD64LO (GPR[4]);
1668 FPR_STATE[0] = fmt_uninterpreted;
1669 }
1670 else if (aregs == 6)
1671 {
1672 FGR[0] = WORD64LO (GPR[5]);
1673 FGR[1] = WORD64LO (GPR[4]);
1674 FPR_STATE[0] = fmt_uninterpreted;
1675 FPR_STATE[1] = fmt_uninterpreted;
1676 }
1677 }
1678
1679 PC = RA;
1680 }
1681
1682 }
1683
1684 /*-- trace support ----------------------------------------------------------*/
1685
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. */
1694
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:
1701
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)
1707
1708 The address field is a 32bit (lower-case) hexadecimal address
1709 value. The address should *NOT* be preceded by "0x".
1710
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. */
1721
1722
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, ...)
1731 {
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");
1742 }
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. */
1746
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. */
1750
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. */
1756
1757 return;
1758 }
1759 #endif /* WITH_TRACE_ANY_P */
1760
1761 /*---------------------------------------------------------------------------*/
1762 /*-- simulator engine -------------------------------------------------------*/
1763 /*---------------------------------------------------------------------------*/
1764
1765 static void
1766 ColdReset (SIM_DESC sd)
1767 {
1768 int cpu_nr;
1769 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1770 {
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. */
1775
1776 SR &= ~(status_SR | status_TS | status_RP);
1777 SR |= (status_ERL | status_BEV);
1778
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 */
1783
1784 /* Ensure that any instructions with pending register updates are
1785 cleared: */
1786 PENDING_INVALIDATE();
1787
1788 /* Initialise the FPU registers to the unknown state */
1789 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1790 {
1791 int rn;
1792 for (rn = 0; (rn < 32); rn++)
1793 FPR_STATE[rn] = fmt_uninterpreted;
1794 }
1795
1796 /* Initialise the Config0 register. */
1797 C0_CONFIG = 0x80000000 /* Config1 present */
1798 | 2; /* KSEG0 uncached */
1799 if (WITH_TARGET_WORD_BITSIZE == 64)
1800 {
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 */
1807 }
1808 if (BigEndianMem)
1809 C0_CONFIG |= 0x00008000; /* Big Endian */
1810 }
1811 }
1812
1813
1814
1815
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. */
1820
1821 void
1822 signal_exception (SIM_DESC sd,
1823 sim_cpu *cpu,
1824 address_word cia,
1825 int exception,...)
1826 {
1827 /* int vector; */
1828
1829 #ifdef DEBUG
1830 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1831 #endif /* DEBUG */
1832
1833 /* Ensure that any active atomic read/modify/write operation will fail: */
1834 LLBIT = 0;
1835
1836 /* Save registers before interrupt dispatching */
1837 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1838 SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1839 #endif
1840
1841 switch (exception) {
1842
1843 case DebugBreakPoint:
1844 if (! (Debug & Debug_DM))
1845 {
1846 if (INDELAYSLOT())
1847 {
1848 CANCELDELAYSLOT();
1849
1850 Debug |= Debug_DBD; /* signaled from within in delay slot */
1851 DEPC = cia - 4; /* reference the branch instruction */
1852 }
1853 else
1854 {
1855 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1856 DEPC = cia;
1857 }
1858
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);
1863 }
1864 break;
1865
1866 case ReservedInstruction:
1867 {
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)
1883 {
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));
1887
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);
1892 }
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)
1898 {
1899 mips16_entry (SD, CPU, cia, instruction);
1900 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1901 }
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;
1905 }
1906
1907 default:
1908 /* Store exception code into current exception id variable (used
1909 by exit code): */
1910
1911 /* TODO: If not simulating exceptions then stop the simulator
1912 execution. At the moment we always stop the simulation. */
1913
1914 #ifdef SUBTARGET_R3900
1915 /* update interrupt-related registers */
1916
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);
1921
1922 if (STATE & simDELAYSLOT)
1923 {
1924 STATE &= ~simDELAYSLOT;
1925 CAUSE |= cause_BD;
1926 EPC = (cia - 4); /* reference the branch instruction */
1927 }
1928 else
1929 EPC = cia;
1930
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))
1938 {
1939 CAUSE = (exception << 2);
1940 if (STATE & simDELAYSLOT)
1941 {
1942 STATE &= ~simDELAYSLOT;
1943 CAUSE |= cause_BD;
1944 EPC = (cia - 4); /* reference the branch instruction */
1945 }
1946 else
1947 EPC = cia;
1948 /* FIXME: TLB et.al. */
1949 /* vector = 0x180; */
1950 }
1951 else
1952 {
1953 CAUSE = (exception << 2);
1954 /* vector = 0x180; */
1955 }
1956 SR |= status_EXL;
1957 /* Store exception code into current exception id variable (used
1958 by exit code): */
1959
1960 if (SR & status_BEV)
1961 PC = (signed)0xBFC00200 + 0x180;
1962 else
1963 PC = (signed)0x80000000 + 0x180;
1964 #endif
1965
1966 switch ((CAUSE >> 2) & 0x1F)
1967 {
1968 case Interrupt:
1969 /* Interrupts arrive during event processing, no need to
1970 restart */
1971 return;
1972
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;
1980
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);
1992
1993 case ReservedInstruction:
1994 case CoProcessorUnusable:
1995 PC = EPC;
1996 sim_engine_halt (SD, CPU, NULL, PC,
1997 sim_stopped, SIM_SIGILL);
1998
1999 case IntegerOverflow:
2000 case FPE:
2001 sim_engine_halt (SD, CPU, NULL, PC,
2002 sim_stopped, SIM_SIGFPE);
2003
2004 case BreakPoint:
2005 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
2006 break;
2007
2008 case SystemCall:
2009 case Trap:
2010 sim_engine_restart (SD, CPU, NULL, PC);
2011 break;
2012
2013 case Watch:
2014 PC = EPC;
2015 sim_engine_halt (SD, CPU, NULL, PC,
2016 sim_stopped, SIM_SIGTRAP);
2017
2018 default: /* Unknown internal exception */
2019 PC = EPC;
2020 sim_engine_halt (SD, CPU, NULL, PC,
2021 sim_stopped, SIM_SIGABRT);
2022
2023 }
2024
2025 case SimulatorFault:
2026 {
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);
2034 }
2035 }
2036
2037 return;
2038 }
2039
2040
2041
2042 /* This function implements what the MIPS32 and MIPS64 ISAs define as
2043 "UNPREDICTABLE" behaviour.
2044
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.)
2052
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.
2056
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)
2061 {
2062 SIM_DESC sd = CPU_STATE(cpu);
2063
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);
2066 }
2067
2068
2069 /*-- co-processor support routines ------------------------------------------*/
2070
2071 static int UNUSED
2072 CoProcPresent(unsigned int coproc_number)
2073 {
2074 /* Return TRUE if simulator provides a model for the given co-processor number */
2075 return(0);
2076 }
2077
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)
2085 {
2086 switch (coproc_num)
2087 {
2088 case 1:
2089 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2090 {
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;
2096 }
2097
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;
2103 }
2104
2105 return;
2106 }
2107
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)
2115 {
2116
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
2120
2121 switch (coproc_num) {
2122 case 1:
2123 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2124 {
2125 StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
2126 break;
2127 }
2128
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;
2134 }
2135
2136 return;
2137 }
2138
2139
2140
2141
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)
2148 {
2149 unsigned int value = 0;
2150
2151 switch (coproc_num)
2152 {
2153 case 1:
2154 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2155 {
2156 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
2157 break;
2158 }
2159
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;
2165 }
2166
2167 return(value);
2168 }
2169
2170 uword64
2171 cop_sd (SIM_DESC sd,
2172 sim_cpu *cpu,
2173 address_word cia,
2174 int coproc_num,
2175 int coproc_reg)
2176 {
2177 uword64 value = 0;
2178 switch (coproc_num)
2179 {
2180 case 1:
2181 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2182 {
2183 value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
2184 break;
2185 }
2186
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;
2192 }
2193
2194 return(value);
2195 }
2196
2197
2198
2199
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)
2210 {
2211 switch (coprocnum)
2212 {
2213 case 0: /* standard CPU control and cache registers */
2214 {
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)
2228 */
2229 if (((op == cp0_mfc0) || (op == cp0_mtc0) /* MFC0 / MTC0 */
2230 || (op == cp0_dmfc0) || (op == cp0_dmtc0)) /* DMFC0 / DMTC0 */
2231 && sel == 0)
2232 {
2233 switch (rd) /* NOTEs: Standard CP0 registers */
2234 {
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 */
2254
2255 /* ignore */
2256 break;
2257
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;
2265
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
2343 }
2344 }
2345 else if ((op == cp0_mfc0 || op == cp0_dmfc0)
2346 && rd == 16)
2347 {
2348 /* [D]MFC0 RT,C0_CONFIG,SEL */
2349 int32_t cfg = 0;
2350 switch (sel)
2351 {
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;
2376 }
2377 GPR[rt] = cfg;
2378 }
2379 else if (op == cp0_eret && sel == 0x18)
2380 {
2381 /* ERET */
2382 if (SR & status_ERL)
2383 {
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;
2388 }
2389 else
2390 {
2391 PC = EPC;
2392 SR &= ~status_EXL;
2393 }
2394 }
2395 else if (op == cp0_rfe && sel == 0x10)
2396 {
2397 /* RFE */
2398 #ifdef SUBTARGET_R3900
2399 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2400
2401 /* shift IE/KU history bits right */
2402 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
2403
2404 /* TODO: CACHE register */
2405 #endif /* SUBTARGET_R3900 */
2406 }
2407 else if (op == cp0_deret && sel == 0x1F)
2408 {
2409 /* DERET */
2410 Debug &= ~Debug_DM;
2411 DELAYSLOT();
2412 DSPC = DEPC;
2413 }
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. */
2419 }
2420 break;
2421
2422 case 2: /* co-processor 2 */
2423 {
2424 int handle = 0;
2425
2426
2427 if (!handle)
2428 {
2429 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2430 instruction,pr_addr(cia));
2431 }
2432 }
2433 break;
2434
2435 case 1: /* should not occur (FPU co-processor) */
2436 case 3: /* should not occur (FPU co-processor) */
2437 SignalException(ReservedInstruction,instruction);
2438 break;
2439 }
2440
2441 return;
2442 }
2443
2444
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. */
2447
2448 /* Temporary storage using circular buffer */
2449 #define NUMCELLS 16
2450 #define CELLSIZE 32
2451 static char*
2452 get_cell (void)
2453 {
2454 static char buf[NUMCELLS][CELLSIZE];
2455 static int cell=0;
2456 if (++cell>=NUMCELLS) cell=0;
2457 return buf[cell];
2458 }
2459
2460 /* Print routines to handle variable size regs, etc */
2461
2462 char*
2463 pr_addr (address_word addr)
2464 {
2465 char *paddr_str=get_cell();
2466 sprintf (paddr_str, "%0*" PRIxTA, (int) (sizeof (addr) * 2), addr);
2467 return paddr_str;
2468 }
2469
2470 char*
2471 pr_uword64 (uword64 addr)
2472 {
2473 char *paddr_str=get_cell();
2474 sprintf (paddr_str, "%016" PRIx64, addr);
2475 return paddr_str;
2476 }
2477
2478
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)
2488 {
2489 const char *copy = (transfer == read_transfer ? "read" : "write");
2490 address_word ip = CIA_ADDR (cia);
2491
2492 switch (sig)
2493 {
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 ();
2502
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 ();
2514
2515 default:
2516 sim_engine_abort (sd, cpu, cia,
2517 "mips_core_signal - internal error - bad switch");
2518 }
2519 }
2520
2521
2522 void
2523 mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
2524 {
2525 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
2526
2527 ASSERT(cpu != NULL);
2528
2529 if (mips_cpu->exc_suspended > 0)
2530 sim_io_eprintf (sd, "Warning, nested exception triggered (%d)\n",
2531 mips_cpu->exc_suspended);
2532
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;
2537 }
2538
2539 void
2540 mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
2541 {
2542 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
2543
2544 ASSERT(cpu != NULL);
2545
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);
2549
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;
2555 }
2556
2557 void
2558 mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
2559 {
2560 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
2561
2562 ASSERT(cpu != NULL);
2563
2564 if (exception == 0 && mips_cpu->exc_suspended > 0)
2565 {
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);
2570 }
2571 else if (exception != 0 && mips_cpu->exc_suspended > 0)
2572 {
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);
2576
2577 memcpy (mips_cpu->registers, mips_cpu->exc_suspend_registers,
2578 sizeof (mips_cpu->registers));
2579 }
2580 else if (exception != 0 && mips_cpu->exc_suspended == 0)
2581 {
2582 sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
2583 }
2584 mips_cpu->exc_suspended = 0;
2585 }
2586
2587
2588 /*---------------------------------------------------------------------------*/
2589 /*> EOF interp.c <*/
2590