Remove path name from test case
[binutils-gdb.git] / sim / mips / interp.c
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 sim_cpu *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 address_word size = (entry->modulo != 0
404 ? entry->modulo : entry->nr_bytes);
405 if (entry->addr == 0
406 && (!match || entry->level < match->level))
407 match = entry;
408 else if (entry->addr == K0BASE || entry->addr == K1BASE)
409 mapped = 1;
410 else
411 {
412 sim_memopt *alias;
413 for (alias = entry->alias; alias != NULL; alias = alias->next)
414 {
415 if (alias->addr == 0
416 && (!match || entry->level < match->level))
417 match = entry;
418 else if (alias->addr == K0BASE || alias->addr == K1BASE)
419 mapped = 1;
420 }
421 }
422 }
423
424 if (!mapped)
425 {
426 if (match)
427 {
428 /* Get existing memory region size. */
429 mem_size = (match->modulo != 0
430 ? match->modulo : match->nr_bytes);
431 /* Delete old region. */
432 sim_do_commandf (sd, "memory delete %d:0x%" PRIxTW "@%d",
433 match->space, match->addr, match->level);
434 }
435 else if (mem_size == 0)
436 mem_size = MEM_SIZE;
437 /* Limit to KSEG1 size (512MB) */
438 if (mem_size > K1SIZE)
439 mem_size = K1SIZE;
440 /* memory alias K1BASE@1,K1SIZE%MEMSIZE,K0BASE */
441 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x%%0x%lx,0x%0x",
442 K1BASE, K1SIZE, (long)mem_size, K0BASE);
443 if (WITH_TARGET_WORD_BITSIZE == 64)
444 sim_do_commandf (sd, "memory alias 0x%x,0x%" PRIxTW ",0x%" PRIxTA,
445 (K0BASE), mem_size, EXTENDED(K0BASE));
446 }
447
448 device_init(sd);
449 }
450 else if (board != NULL
451 && (strcmp(board, BOARD_BSP) == 0))
452 {
453 int i;
454
455 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
456
457 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
458 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
459 0x9FC00000,
460 4 * 1024 * 1024, /* 4 MB */
461 0xBFC00000);
462
463 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
464 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
465 0x80000000,
466 4 * 1024 * 1024, /* 4 MB */
467 0xA0000000);
468
469 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
470 for (i=0; i<8; i++) /* 32 MB total */
471 {
472 unsigned size = 4 * 1024 * 1024; /* 4 MB */
473 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
474 0x88000000 + (i * size),
475 size,
476 0xA8000000 + (i * size));
477 }
478 }
479 #if (WITH_HW)
480 else if (board != NULL
481 && (strcmp(board, BOARD_JMR3904) == 0 ||
482 strcmp(board, BOARD_JMR3904_PAL) == 0 ||
483 strcmp(board, BOARD_JMR3904_DEBUG) == 0))
484 {
485 /* match VIRTUAL memory layout of JMR-TX3904 board */
486 int i;
487
488 /* --- disable monitor unless forced on by user --- */
489
490 if (! firmware_option_p)
491 {
492 idt_monitor_base = 0;
493 pmon_monitor_base = 0;
494 lsipmon_monitor_base = 0;
495 }
496
497 /* --- environment --- */
498
499 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
500
501 /* --- memory --- */
502
503 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
504 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
505 0x9FC00000,
506 4 * 1024 * 1024, /* 4 MB */
507 0xBFC00000);
508
509 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
510 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
511 0x80000000,
512 4 * 1024 * 1024, /* 4 MB */
513 0xA0000000);
514
515 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
516 for (i=0; i<8; i++) /* 32 MB total */
517 {
518 unsigned size = 4 * 1024 * 1024; /* 4 MB */
519 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
520 0x88000000 + (i * size),
521 size,
522 0xA8000000 + (i * size));
523 }
524
525 /* Dummy memory regions for unsimulated devices - sorted by address */
526
527 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB1000000, 0x400); /* ISA I/O */
528 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2100000, 0x004); /* ISA ctl */
529 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2500000, 0x004); /* LED/switch */
530 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2700000, 0x004); /* RTC */
531 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB3C00000, 0x004); /* RTC */
532 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFF8000, 0x900); /* DRAMC */
533 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFF9000, 0x200); /* EBIF */
534 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFFE000, 0x01c); /* EBIF */
535 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFFF500, 0x300); /* PIO */
536
537
538 /* --- simulated devices --- */
539 sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
540 sim_hw_parse (sd, "/tx3904cpu");
541 sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
542 sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
543 sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
544 sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
545 {
546 /* FIXME: poking at dv-sockser internals, use tcp backend if
547 --sockser_addr option was given.*/
548 #ifdef HAVE_DV_SOCKSER
549 extern char* sockser_addr;
550 #else
551 # define sockser_addr NULL
552 #endif
553 if (sockser_addr == NULL)
554 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
555 else
556 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
557 }
558 sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
559 sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
560
561 /* -- device connections --- */
562 sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
563 sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
564 sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
565 sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
566 sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
567 sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
568
569 /* add PAL timer & I/O module */
570 if (!strcmp(board, BOARD_JMR3904_PAL))
571 {
572 /* the device */
573 sim_hw_parse (sd, "/pal@0xffff0000");
574 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
575
576 /* wire up interrupt ports to irc */
577 sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
578 sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
579 sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
580 }
581
582 if (!strcmp(board, BOARD_JMR3904_DEBUG))
583 {
584 /* -- DEBUG: glue interrupt generators --- */
585 sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
586 sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
587 sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
588 sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
589 sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
590 sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
591 sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
592 sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
593 sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
594 sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
595 sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
596 sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
597 sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
598 sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
599 sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
600 sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
601 sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
602 sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
603 sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
604 }
605
606 device_init(sd);
607 }
608 #endif
609
610 if (display_mem_info)
611 {
612 struct option_list * ol;
613 struct option_list * prev;
614
615 /* This is a hack. We want to execute the real --memory-info command
616 line switch which is handled in common/sim-memopts.c, not the
617 override we have defined in this file. So we remove the
618 mips_options array from the state options list. This is safe
619 because we have now processed all of the command line. */
620 for (ol = STATE_OPTIONS (sd), prev = NULL;
621 ol != NULL;
622 prev = ol, ol = ol->next)
623 if (ol->options == mips_options)
624 break;
625
626 SIM_ASSERT (ol != NULL);
627
628 if (prev == NULL)
629 STATE_OPTIONS (sd) = ol->next;
630 else
631 prev->next = ol->next;
632
633 sim_do_commandf (sd, "memory-info");
634 }
635
636 /* check for/establish the a reference program image */
637 if (sim_analyze_program (sd, STATE_PROG_FILE (sd), abfd) != SIM_RC_OK)
638 {
639 sim_module_uninstall (sd);
640 return 0;
641 }
642
643 /* Configure/verify the target byte order and other runtime
644 configuration options */
645 if (sim_config (sd) != SIM_RC_OK)
646 {
647 sim_module_uninstall (sd);
648 return 0;
649 }
650
651 if (sim_post_argv_init (sd) != SIM_RC_OK)
652 {
653 /* Uninstall the modules to avoid memory leaks,
654 file descriptor leaks, etc. */
655 sim_module_uninstall (sd);
656 return 0;
657 }
658
659 /* verify assumptions the simulator made about the host type system.
660 This macro does not return if there is a problem */
661 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
662 SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
663
664 /* This is NASTY, in that we are assuming the size of specific
665 registers: */
666 {
667 int rn;
668 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
669 {
670 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
671
672 if (rn < 32)
673 mips_cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
674 else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
675 mips_cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
676 else if ((rn >= 33) && (rn <= 37))
677 mips_cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
678 else if ((rn == SRIDX)
679 || (rn == FCR0IDX)
680 || (rn == FCR31IDX)
681 || ((rn >= 72) && (rn <= 89)))
682 mips_cpu->register_widths[rn] = 32;
683 else
684 mips_cpu->register_widths[rn] = 0;
685 }
686
687
688 }
689
690 if (STATE & simTRACE)
691 open_trace(sd);
692
693 /*
694 sim_io_eprintf (sd, "idt@%x pmon@%x lsipmon@%x\n",
695 idt_monitor_base,
696 pmon_monitor_base,
697 lsipmon_monitor_base);
698 */
699
700 /* Write the monitor trap address handlers into the monitor (eeprom)
701 address space. This can only be done once the target endianness
702 has been determined. */
703 if (idt_monitor_base != 0)
704 {
705 unsigned loop;
706 address_word idt_monitor_size = 1 << 11;
707
708 /* the default monitor region */
709 if (WITH_TARGET_WORD_BITSIZE == 64)
710 sim_do_commandf (sd, "memory alias %#" PRIxTA ",%#" PRIxTA ",%#" PRIxTA,
711 idt_monitor_base, idt_monitor_size,
712 EXTENDED (idt_monitor_base));
713 else
714 sim_do_commandf (sd, "memory region %#" PRIxTA ",%#" PRIxTA,
715 idt_monitor_base, idt_monitor_size);
716
717 /* Entry into the IDT monitor is via fixed address vectors, and
718 not using machine instructions. To avoid clashing with use of
719 the MIPS TRAP system, we place our own (simulator specific)
720 "undefined" instructions into the relevant vector slots. */
721 for (loop = 0; (loop < idt_monitor_size); loop += 4)
722 {
723 address_word vaddr = (idt_monitor_base + loop);
724 uint32_t insn = (RSVD_INSTRUCTION |
725 (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
726 << RSVD_INSTRUCTION_ARG_SHIFT));
727 H2T (insn);
728 sim_write (sd, vaddr, &insn, sizeof (insn));
729 }
730 }
731
732 if ((pmon_monitor_base != 0) || (lsipmon_monitor_base != 0))
733 {
734 /* The PMON monitor uses the same address space, but rather than
735 branching into it the address of a routine is loaded. We can
736 cheat for the moment, and direct the PMON routine to IDT style
737 instructions within the monitor space. This relies on the IDT
738 monitor not using the locations from 0xBFC00500 onwards as its
739 entry points.*/
740 unsigned loop;
741 for (loop = 0; (loop < 24); loop++)
742 {
743 uint32_t value = ((0x500 - 8) / 8); /* default UNDEFINED reason code */
744 switch (loop)
745 {
746 case 0: /* read */
747 value = 7;
748 break;
749 case 1: /* write */
750 value = 8;
751 break;
752 case 2: /* open */
753 value = 6;
754 break;
755 case 3: /* close */
756 value = 10;
757 break;
758 case 5: /* printf */
759 value = ((0x500 - 16) / 8); /* not an IDT reason code */
760 break;
761 case 8: /* cliexit */
762 value = 17;
763 break;
764 case 11: /* flush_cache */
765 value = 28;
766 break;
767 }
768
769 SIM_ASSERT (idt_monitor_base != 0);
770 value = ((unsigned int) idt_monitor_base + (value * 8));
771 H2T (value);
772
773 if (pmon_monitor_base != 0)
774 {
775 address_word vaddr = (pmon_monitor_base + (loop * 4));
776 sim_write (sd, vaddr, &value, sizeof (value));
777 }
778
779 if (lsipmon_monitor_base != 0)
780 {
781 address_word vaddr = (lsipmon_monitor_base + (loop * 4));
782 sim_write (sd, vaddr, &value, sizeof (value));
783 }
784 }
785
786 /* Write an abort sequence into the TRAP (common) exception vector
787 addresses. This is to catch code executing a TRAP (et.al.)
788 instruction without installing a trap handler. */
789 if ((idt_monitor_base != 0) ||
790 (pmon_monitor_base != 0) ||
791 (lsipmon_monitor_base != 0))
792 {
793 uint32_t halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
794 HALT_INSTRUCTION /* BREAK */ };
795 H2T (halt[0]);
796 H2T (halt[1]);
797 sim_write (sd, 0x80000000, halt, sizeof (halt));
798 sim_write (sd, 0x80000180, halt, sizeof (halt));
799 sim_write (sd, 0x80000200, halt, sizeof (halt));
800 /* XXX: Write here unconditionally? */
801 sim_write (sd, 0xBFC00200, halt, sizeof (halt));
802 sim_write (sd, 0xBFC00380, halt, sizeof (halt));
803 sim_write (sd, 0xBFC00400, halt, sizeof (halt));
804 }
805 }
806
807 /* CPU specific initialization. */
808 for (i = 0; i < MAX_NR_PROCESSORS; ++i)
809 {
810 SIM_CPU *cpu = STATE_CPU (sd, i);
811
812 CPU_REG_FETCH (cpu) = mips_reg_fetch;
813 CPU_REG_STORE (cpu) = mips_reg_store;
814 CPU_PC_FETCH (cpu) = mips_pc_get;
815 CPU_PC_STORE (cpu) = mips_pc_set;
816 }
817
818 return sd;
819 }
820
821 #if WITH_TRACE_ANY_P
822 static void
823 open_trace (SIM_DESC sd)
824 {
825 tracefh = fopen(tracefile,"wb+");
826 if (tracefh == NULL)
827 {
828 sim_io_eprintf(sd,"Failed to create file \"%s\", writing trace information to stderr.\n",tracefile);
829 tracefh = stderr;
830 }
831 }
832 #endif
833
834 /* Return name of an insn, used by insn profiling. */
835 static const char *
836 get_insn_name (sim_cpu *cpu, int i)
837 {
838 return itable[i].name;
839 }
840
841 void
842 mips_sim_close (SIM_DESC sd, int quitting)
843 {
844 #if WITH_TRACE_ANY_P
845 if (tracefh != NULL && tracefh != stderr)
846 fclose(tracefh);
847 tracefh = NULL;
848 #endif
849 }
850
851 static int
852 mips_reg_store (SIM_CPU *cpu, int rn, const void *memory, int length)
853 {
854 /* NOTE: gdb (the client) stores registers in target byte order
855 while the simulator uses host byte order */
856
857 /* Unfortunately this suffers from the same problem as the register
858 numbering one. We need to know what the width of each logical
859 register number is for the architecture being simulated. */
860
861 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
862
863 if (mips_cpu->register_widths[rn] == 0)
864 {
865 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
866 return 0;
867 }
868
869 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
870 {
871 mips_cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
872 if (mips_cpu->register_widths[rn] == 32)
873 {
874 if (length == 8)
875 {
876 mips_cpu->fgr[rn - FGR_BASE] =
877 (uint32_t) T2H_8 (*(uint64_t*)memory);
878 return 8;
879 }
880 else
881 {
882 mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
883 return 4;
884 }
885 }
886 else
887 {
888 if (length == 8)
889 {
890 mips_cpu->fgr[rn - FGR_BASE] = T2H_8 (*(uint64_t*)memory);
891 return 8;
892 }
893 else
894 {
895 mips_cpu->fgr[rn - FGR_BASE] = T2H_4 (*(uint32_t*)memory);
896 return 4;
897 }
898 }
899 }
900
901 if (mips_cpu->register_widths[rn] == 32)
902 {
903 if (length == 8)
904 {
905 mips_cpu->registers[rn] =
906 (uint32_t) T2H_8 (*(uint64_t*)memory);
907 return 8;
908 }
909 else
910 {
911 mips_cpu->registers[rn] = T2H_4 (*(uint32_t*)memory);
912 return 4;
913 }
914 }
915 else
916 {
917 if (length == 8)
918 {
919 mips_cpu->registers[rn] = T2H_8 (*(uint64_t*)memory);
920 return 8;
921 }
922 else
923 {
924 mips_cpu->registers[rn] = (int32_t) T2H_4(*(uint32_t*)memory);
925 return 4;
926 }
927 }
928
929 return 0;
930 }
931
932 static int
933 mips_reg_fetch (SIM_CPU *cpu, int rn, void *memory, int length)
934 {
935 /* NOTE: gdb (the client) stores registers in target byte order
936 while the simulator uses host byte order */
937
938 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
939
940 if (mips_cpu->register_widths[rn] == 0)
941 {
942 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
943 return 0;
944 }
945
946 /* Any floating point register */
947 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
948 {
949 if (mips_cpu->register_widths[rn] == 32)
950 {
951 if (length == 8)
952 {
953 *(uint64_t*)memory =
954 H2T_8 ((uint32_t) (mips_cpu->fgr[rn - FGR_BASE]));
955 return 8;
956 }
957 else
958 {
959 *(uint32_t*)memory = H2T_4 (mips_cpu->fgr[rn - FGR_BASE]);
960 return 4;
961 }
962 }
963 else
964 {
965 if (length == 8)
966 {
967 *(uint64_t*)memory = H2T_8 (mips_cpu->fgr[rn - FGR_BASE]);
968 return 8;
969 }
970 else
971 {
972 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->fgr[rn - FGR_BASE]));
973 return 4;
974 }
975 }
976 }
977
978 if (mips_cpu->register_widths[rn] == 32)
979 {
980 if (length == 8)
981 {
982 *(uint64_t*)memory =
983 H2T_8 ((uint32_t) (mips_cpu->registers[rn]));
984 return 8;
985 }
986 else
987 {
988 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
989 return 4;
990 }
991 }
992 else
993 {
994 if (length == 8)
995 {
996 *(uint64_t*)memory =
997 H2T_8 ((uint64_t) (mips_cpu->registers[rn]));
998 return 8;
999 }
1000 else
1001 {
1002 *(uint32_t*)memory = H2T_4 ((uint32_t)(mips_cpu->registers[rn]));
1003 return 4;
1004 }
1005 }
1006
1007 return 0;
1008 }
1009
1010 SIM_RC
1011 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1012 char * const *argv, char * const *env)
1013 {
1014
1015 #ifdef DEBUG
1016 #if 0 /* FIXME: doesn't compile */
1017 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1018 pr_addr(PC));
1019 #endif
1020 #endif /* DEBUG */
1021
1022 ColdReset(sd);
1023
1024 if (abfd != NULL)
1025 {
1026 /* override PC value set by ColdReset () */
1027 int cpu_nr;
1028 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1029 {
1030 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1031 sim_cia pc = bfd_get_start_address (abfd);
1032
1033 /* The 64-bit BFD sign-extends MIPS addresses to model
1034 32-bit compatibility segments with 64-bit addressing.
1035 These addresses work as is on 64-bit targets but
1036 can be truncated for 32-bit targets. */
1037 if (WITH_TARGET_WORD_BITSIZE == 32)
1038 pc = (uint32_t) pc;
1039
1040 CPU_PC_SET (cpu, pc);
1041 }
1042 }
1043
1044 #if 0 /* def DEBUG */
1045 if (argv || env)
1046 {
1047 /* We should really place the argv slot values into the argument
1048 registers, and onto the stack as required. However, this
1049 assumes that we have a stack defined, which is not
1050 necessarily true at the moment. */
1051 char **cptr;
1052 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1053 for (cptr = argv; (cptr && *cptr); cptr++)
1054 printf("DBG: arg \"%s\"\n",*cptr);
1055 }
1056 #endif /* DEBUG */
1057
1058 return SIM_RC_OK;
1059 }
1060
1061 /*---------------------------------------------------------------------------*/
1062 /*-- Private simulator support interface ------------------------------------*/
1063 /*---------------------------------------------------------------------------*/
1064
1065 /* Read a null terminated string from memory, return in a buffer */
1066 static char *
1067 fetch_str (SIM_DESC sd,
1068 address_word addr)
1069 {
1070 char *buf;
1071 int nr = 0;
1072 unsigned char null;
1073 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1074 nr++;
1075 buf = NZALLOC (char, nr + 1);
1076 sim_read (sd, addr, buf, nr);
1077 return buf;
1078 }
1079
1080
1081 /* Implements the "sim firmware" command:
1082 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1083 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1084 defaults to the normal address for that monitor.
1085 sim firmware none --- don't emulate any ROM monitor. Useful
1086 if you need a clean address space. */
1087 static SIM_RC
1088 sim_firmware_command (SIM_DESC sd, char *arg)
1089 {
1090 int address_present = 0;
1091 address_word address;
1092
1093 /* Signal occurrence of this option. */
1094 firmware_option_p = 1;
1095
1096 /* Parse out the address, if present. */
1097 {
1098 char *p = strchr (arg, '@');
1099 if (p)
1100 {
1101 char *q;
1102 address_present = 1;
1103 p ++; /* skip over @ */
1104
1105 address = strtoul (p, &q, 0);
1106 if (*q != '\0')
1107 {
1108 sim_io_printf (sd, "Invalid address given to the"
1109 "`sim firmware NAME@ADDRESS' command: %s\n",
1110 p);
1111 return SIM_RC_FAIL;
1112 }
1113 }
1114 else
1115 {
1116 address_present = 0;
1117 address = -1; /* Dummy value. */
1118 }
1119 }
1120
1121 if (! strncmp (arg, "idt", 3))
1122 {
1123 idt_monitor_base = address_present ? address : 0xBFC00000;
1124 pmon_monitor_base = 0;
1125 lsipmon_monitor_base = 0;
1126 }
1127 else if (! strncmp (arg, "pmon", 4))
1128 {
1129 /* pmon uses indirect calls. Hook into implied idt. */
1130 pmon_monitor_base = address_present ? address : 0xBFC00500;
1131 idt_monitor_base = pmon_monitor_base - 0x500;
1132 lsipmon_monitor_base = 0;
1133 }
1134 else if (! strncmp (arg, "lsipmon", 7))
1135 {
1136 /* lsipmon uses indirect calls. Hook into implied idt. */
1137 pmon_monitor_base = 0;
1138 lsipmon_monitor_base = address_present ? address : 0xBFC00200;
1139 idt_monitor_base = lsipmon_monitor_base - 0x200;
1140 }
1141 else if (! strncmp (arg, "none", 4))
1142 {
1143 if (address_present)
1144 {
1145 sim_io_printf (sd,
1146 "The `sim firmware none' command does "
1147 "not take an `ADDRESS' argument.\n");
1148 return SIM_RC_FAIL;
1149 }
1150 idt_monitor_base = 0;
1151 pmon_monitor_base = 0;
1152 lsipmon_monitor_base = 0;
1153 }
1154 else
1155 {
1156 sim_io_printf (sd, "\
1157 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1158 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1159 arg);
1160 return SIM_RC_FAIL;
1161 }
1162
1163 return SIM_RC_OK;
1164 }
1165
1166 /* stat structures from MIPS32/64. */
1167 static const char stat32_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,4:st_atime,4:st_spare1,4:st_mtime,4:st_spare2,4"
1170 ":st_ctime,4:st_spare3,4:st_blksize,4:st_blocks,4:st_spare4,8";
1171
1172 static const char stat64_map[] =
1173 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1174 ":st_rdev,2:st_size,8:st_atime,8:st_spare1,8:st_mtime,8:st_spare2,8"
1175 ":st_ctime,8:st_spare3,8:st_blksize,8:st_blocks,8:st_spare4,16";
1176
1177 /* Map for calls using the host struct stat. */
1178 static const CB_TARGET_DEFS_MAP CB_stat_map[] =
1179 {
1180 { "stat", CB_SYS_stat, 15 },
1181 { 0, -1, -1 }
1182 };
1183
1184
1185 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1186 int
1187 sim_monitor (SIM_DESC sd,
1188 sim_cpu *cpu,
1189 address_word cia,
1190 unsigned int reason)
1191 {
1192 #ifdef DEBUG
1193 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1194 #endif /* DEBUG */
1195
1196 /* The IDT monitor actually allows two instructions per vector
1197 slot. However, the simulator currently causes a trap on each
1198 individual instruction. We cheat, and lose the bottom bit. */
1199 reason >>= 1;
1200
1201 /* The following callback functions are available, however the
1202 monitor we are simulating does not make use of them: get_errno,
1203 isatty, rename, system and time. */
1204 switch (reason)
1205 {
1206
1207 case 6: /* int open(char *path,int flags) */
1208 {
1209 char *path = fetch_str (sd, A0);
1210 V0 = sim_io_open (sd, path, (int)A1);
1211 free (path);
1212 break;
1213 }
1214
1215 case 7: /* int read(int file,char *ptr,int len) */
1216 {
1217 int fd = A0;
1218 int nr = A2;
1219 char *buf = zalloc (nr);
1220 V0 = sim_io_read (sd, fd, buf, nr);
1221 sim_write (sd, A1, buf, nr);
1222 free (buf);
1223 }
1224 break;
1225
1226 case 8: /* int write(int file,char *ptr,int len) */
1227 {
1228 int fd = A0;
1229 int nr = A2;
1230 char *buf = zalloc (nr);
1231 sim_read (sd, A1, buf, nr);
1232 V0 = sim_io_write (sd, fd, buf, nr);
1233 if (fd == 1)
1234 sim_io_flush_stdout (sd);
1235 else if (fd == 2)
1236 sim_io_flush_stderr (sd);
1237 free (buf);
1238 break;
1239 }
1240
1241 case 10: /* int close(int file) */
1242 {
1243 V0 = sim_io_close (sd, (int)A0);
1244 break;
1245 }
1246
1247 case 2: /* Densan monitor: char inbyte(int waitflag) */
1248 {
1249 if (A0 == 0) /* waitflag == NOWAIT */
1250 V0 = (unsigned_word)-1;
1251 }
1252 /* Drop through to case 11 */
1253
1254 case 11: /* char inbyte(void) */
1255 {
1256 char tmp;
1257 /* ensure that all output has gone... */
1258 sim_io_flush_stdout (sd);
1259 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1260 {
1261 sim_io_error(sd,"Invalid return from character read");
1262 V0 = (unsigned_word)-1;
1263 }
1264 else
1265 V0 = (unsigned_word)tmp;
1266 break;
1267 }
1268
1269 case 3: /* Densan monitor: void co(char chr) */
1270 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1271 {
1272 char tmp = (char)(A0 & 0xFF);
1273 sim_io_write_stdout (sd, &tmp, sizeof(char));
1274 break;
1275 }
1276
1277 case 13: /* int unlink(const char *path) */
1278 {
1279 char *path = fetch_str (sd, A0);
1280 V0 = sim_io_unlink (sd, path);
1281 free (path);
1282 break;
1283 }
1284
1285 case 14: /* int lseek(int fd, int offset, int whence) */
1286 {
1287 V0 = sim_io_lseek (sd, A0, A1, A2);
1288 break;
1289 }
1290
1291 case 15: /* int stat(const char *path, struct stat *buf); */
1292 {
1293 /* As long as the infrastructure doesn't cache anything
1294 related to the stat mapping, this trick gets us a dual
1295 "struct stat"-type mapping in the least error-prone way. */
1296 host_callback *cb = STATE_CALLBACK (sd);
1297 const char *saved_map = cb->stat_map;
1298 CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
1299 bfd *prog_bfd = STATE_PROG_BFD (sd);
1300 int is_elf32bit = (elf_elfheader(prog_bfd)->e_ident[EI_CLASS] ==
1301 ELFCLASS32);
1302 static CB_SYSCALL s;
1303 CB_SYSCALL_INIT (&s);
1304 s.func = 15;
1305 /* Mask out the sign extension part for 64-bit targets because the
1306 MIPS simulator's memory model is still 32-bit. */
1307 s.arg1 = A0 & 0xFFFFFFFF;
1308 s.arg2 = A1 & 0xFFFFFFFF;
1309 s.p1 = sd;
1310 s.p2 = cpu;
1311 s.read_mem = sim_syscall_read_mem;
1312 s.write_mem = sim_syscall_write_mem;
1313
1314 cb->syscall_map = (CB_TARGET_DEFS_MAP *) CB_stat_map;
1315 cb->stat_map = is_elf32bit ? stat32_map : stat64_map;
1316
1317 if (cb_syscall (cb, &s) != CB_RC_OK)
1318 sim_engine_halt (sd, cpu, NULL, mips_pc_get (cpu),
1319 sim_stopped, SIM_SIGILL);
1320
1321 V0 = s.result;
1322 cb->stat_map = saved_map;
1323 cb->syscall_map = saved_syscall_map;
1324 break;
1325 }
1326
1327 case 17: /* void _exit() */
1328 {
1329 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1330 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1331 (unsigned int)(A0 & 0xFFFFFFFF));
1332 break;
1333 }
1334
1335 case 28: /* PMON flush_cache */
1336 break;
1337
1338 case 55: /* void get_mem_info(unsigned int *ptr) */
1339 /* in: A0 = pointer to three word memory location */
1340 /* out: [A0 + 0] = size */
1341 /* [A0 + 4] = instruction cache size */
1342 /* [A0 + 8] = data cache size */
1343 {
1344 unsigned_4 value;
1345 unsigned_4 zero = 0;
1346 address_word mem_size;
1347 sim_memopt *entry, *match = NULL;
1348
1349 /* Search for memory region mapped to KSEG0 or KSEG1. */
1350 for (entry = STATE_MEMOPT (sd);
1351 entry != NULL;
1352 entry = entry->next)
1353 {
1354 if ((entry->addr == K0BASE || entry->addr == K1BASE)
1355 && (!match || entry->level < match->level))
1356 match = entry;
1357 else
1358 {
1359 sim_memopt *alias;
1360 for (alias = entry->alias;
1361 alias != NULL;
1362 alias = alias->next)
1363 if ((alias->addr == K0BASE || alias->addr == K1BASE)
1364 && (!match || entry->level < match->level))
1365 match = entry;
1366 }
1367 }
1368
1369 /* Get region size, limit to KSEG1 size (512MB). */
1370 SIM_ASSERT (match != NULL);
1371 mem_size = (match->modulo != 0
1372 ? match->modulo : match->nr_bytes);
1373 if (mem_size > K1SIZE)
1374 mem_size = K1SIZE;
1375
1376 value = mem_size;
1377 H2T (value);
1378 sim_write (sd, A0 + 0, &value, 4);
1379 sim_write (sd, A0 + 4, &zero, 4);
1380 sim_write (sd, A0 + 8, &zero, 4);
1381 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1382 break;
1383 }
1384
1385 case 158: /* PMON printf */
1386 /* in: A0 = pointer to format string */
1387 /* A1 = optional argument 1 */
1388 /* A2 = optional argument 2 */
1389 /* A3 = optional argument 3 */
1390 /* out: void */
1391 /* The following is based on the PMON printf source */
1392 {
1393 address_word s = A0;
1394 unsigned char c;
1395 address_word *ap = &A1; /* 1st argument */
1396 /* This isn't the quickest way, since we call the host print
1397 routine for every character almost. But it does avoid
1398 having to allocate and manage a temporary string buffer. */
1399 /* TODO: Include check that we only use three arguments (A1,
1400 A2 and A3) */
1401 while (sim_read (sd, s++, &c, 1) && c != '\0')
1402 {
1403 if (c == '%')
1404 {
1405 char tmp[40];
1406 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1407 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1408 while (sim_read (sd, s++, &c, 1) && c != '\0')
1409 {
1410 if (strchr ("dobxXulscefg%", c))
1411 break;
1412 else if (c == '-')
1413 fmt = FMT_LJUST;
1414 else if (c == '0')
1415 fmt = FMT_RJUST0;
1416 else if (c == '~')
1417 fmt = FMT_CENTER;
1418 else if (c == '*')
1419 {
1420 if (haddot)
1421 trunc = (int)*ap++;
1422 else
1423 width = (int)*ap++;
1424 }
1425 else if (c >= '1' && c <= '9')
1426 {
1427 address_word t = s;
1428 unsigned int n;
1429 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1430 tmp[s - t] = c;
1431 tmp[s - t] = '\0';
1432 n = (unsigned int)strtol(tmp,NULL,10);
1433 if (haddot)
1434 trunc = n;
1435 else
1436 width = n;
1437 s--;
1438 }
1439 else if (c == '.')
1440 haddot = 1;
1441 }
1442 switch (c)
1443 {
1444 case '%':
1445 sim_io_printf (sd, "%%");
1446 break;
1447 case 's':
1448 if ((int)*ap != 0)
1449 {
1450 address_word p = *ap++;
1451 unsigned char ch;
1452 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1453 sim_io_printf(sd, "%c", ch);
1454 }
1455 else
1456 sim_io_printf(sd,"(null)");
1457 break;
1458 case 'c':
1459 sim_io_printf (sd, "%c", (int)*ap++);
1460 break;
1461 default:
1462 if (c == 'l')
1463 {
1464 sim_read (sd, s++, &c, 1);
1465 if (c == 'l')
1466 {
1467 longlong = 1;
1468 sim_read (sd, s++, &c, 1);
1469 }
1470 }
1471 if (strchr ("dobxXu", c))
1472 {
1473 word64 lv = (word64) *ap++;
1474 if (c == 'b')
1475 sim_io_printf(sd,"<binary not supported>");
1476 else
1477 {
1478 #define P_(c, fmt64, fmt32) \
1479 case c: \
1480 if (longlong) \
1481 sim_io_printf (sd, "%" fmt64, lv); \
1482 else \
1483 sim_io_printf (sd, "%" fmt32, (int)lv); \
1484 break;
1485 #define P(c, fmtc) P_(c, PRI##fmtc##64, PRI##fmtc##32)
1486 switch (c)
1487 {
1488 P('d', d)
1489 P('o', o)
1490 P('x', x)
1491 P('X', X)
1492 P('u', u)
1493 }
1494 }
1495 #undef P
1496 #undef P_
1497 }
1498 else if (strchr ("eEfgG", c))
1499 {
1500 double dbl = *(double*)(ap++);
1501
1502 #define P(c, fmtc) \
1503 case c: \
1504 sim_io_printf (sd, "%*.*" #fmtc, width, trunc, dbl); \
1505 break;
1506 switch (c)
1507 {
1508 P('e', e)
1509 P('E', E)
1510 P('f', f)
1511 P('g', g)
1512 P('G', G)
1513 }
1514 #undef P
1515 trunc = 0;
1516 }
1517 }
1518 }
1519 else
1520 sim_io_printf(sd, "%c", c);
1521 }
1522 break;
1523 }
1524
1525 default:
1526 /* Unknown reason. */
1527 return 0;
1528 }
1529 return 1;
1530 }
1531
1532 /* Store a word into memory. */
1533
1534 static void
1535 store_word (SIM_DESC sd,
1536 sim_cpu *cpu,
1537 address_word cia,
1538 uword64 vaddr,
1539 signed_word val)
1540 {
1541 address_word paddr = vaddr;
1542
1543 if ((vaddr & 3) != 0)
1544 SignalExceptionAddressStore ();
1545 else
1546 {
1547 const uword64 mask = 7;
1548 uword64 memval;
1549 unsigned int byte;
1550
1551 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1552 byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1553 memval = ((uword64) val) << (8 * byte);
1554 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr,
1555 isREAL);
1556 }
1557 }
1558
1559 #define MIPSR6_P(abfd) \
1560 ((elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_32R6 \
1561 || (elf_elfheader (abfd)->e_flags & EF_MIPS_ARCH) == E_MIPS_ARCH_64R6)
1562
1563 /* Load a word from memory. */
1564
1565 static signed_word
1566 load_word (SIM_DESC sd,
1567 sim_cpu *cpu,
1568 address_word cia,
1569 uword64 vaddr)
1570 {
1571 if ((vaddr & 3) != 0 && !MIPSR6_P (STATE_PROG_BFD (sd)))
1572 {
1573 SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1574 }
1575 else
1576 {
1577 address_word paddr = vaddr;
1578 const uword64 mask = 0x7;
1579 const unsigned int reverse = ReverseEndian ? 1 : 0;
1580 const unsigned int bigend = BigEndianCPU ? 1 : 0;
1581 uword64 memval;
1582 unsigned int byte;
1583
1584 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1585 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA,
1586 isREAL);
1587 byte = (vaddr & mask) ^ (bigend << 2);
1588 return EXTEND32 (memval >> (8 * byte));
1589 }
1590
1591 return 0;
1592 }
1593
1594 /* Simulate the mips16 entry and exit pseudo-instructions. These
1595 would normally be handled by the reserved instruction exception
1596 code, but for ease of simulation we just handle them directly. */
1597
1598 static void
1599 mips16_entry (SIM_DESC sd,
1600 sim_cpu *cpu,
1601 address_word cia,
1602 unsigned int insn)
1603 {
1604 int aregs, sregs, rreg;
1605
1606 #ifdef DEBUG
1607 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1608 #endif /* DEBUG */
1609
1610 aregs = (insn & 0x700) >> 8;
1611 sregs = (insn & 0x0c0) >> 6;
1612 rreg = (insn & 0x020) >> 5;
1613
1614 /* This should be checked by the caller. */
1615 if (sregs == 3)
1616 abort ();
1617
1618 if (aregs < 5)
1619 {
1620 int i;
1621 signed_word tsp;
1622
1623 /* This is the entry pseudo-instruction. */
1624
1625 for (i = 0; i < aregs; i++)
1626 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1627
1628 tsp = SP;
1629 SP -= 32;
1630
1631 if (rreg)
1632 {
1633 tsp -= 4;
1634 store_word (SD, CPU, cia, (uword64) tsp, RA);
1635 }
1636
1637 for (i = 0; i < sregs; i++)
1638 {
1639 tsp -= 4;
1640 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1641 }
1642 }
1643 else
1644 {
1645 int i;
1646 signed_word tsp;
1647
1648 /* This is the exit pseudo-instruction. */
1649
1650 tsp = SP + 32;
1651
1652 if (rreg)
1653 {
1654 tsp -= 4;
1655 RA = load_word (SD, CPU, cia, (uword64) tsp);
1656 }
1657
1658 for (i = 0; i < sregs; i++)
1659 {
1660 tsp -= 4;
1661 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1662 }
1663
1664 SP += 32;
1665
1666 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1667 {
1668 if (aregs == 5)
1669 {
1670 FGR[0] = WORD64LO (GPR[4]);
1671 FPR_STATE[0] = fmt_uninterpreted;
1672 }
1673 else if (aregs == 6)
1674 {
1675 FGR[0] = WORD64LO (GPR[5]);
1676 FGR[1] = WORD64LO (GPR[4]);
1677 FPR_STATE[0] = fmt_uninterpreted;
1678 FPR_STATE[1] = fmt_uninterpreted;
1679 }
1680 }
1681
1682 PC = RA;
1683 }
1684
1685 }
1686
1687 /*-- trace support ----------------------------------------------------------*/
1688
1689 /* The trace support is provided (if required) in the memory accessing
1690 routines. Since we are also providing the architecture specific
1691 features, the architecture simulation code can also deal with
1692 notifying the trace world of cache flushes, etc. Similarly we do
1693 not need to provide profiling support in the simulator engine,
1694 since we can sample in the instruction fetch control loop. By
1695 defining the trace manifest, we add tracing as a run-time
1696 option. */
1697
1698 #if WITH_TRACE_ANY_P
1699 /* Tracing by default produces "din" format (as required by
1700 dineroIII). Each line of such a trace file *MUST* have a din label
1701 and address field. The rest of the line is ignored, so comments can
1702 be included if desired. The first field is the label which must be
1703 one of the following values:
1704
1705 0 read data
1706 1 write data
1707 2 instruction fetch
1708 3 escape record (treated as unknown access type)
1709 4 escape record (causes cache flush)
1710
1711 The address field is a 32bit (lower-case) hexadecimal address
1712 value. The address should *NOT* be preceded by "0x".
1713
1714 The size of the memory transfer is not important when dealing with
1715 cache lines (as long as no more than a cache line can be
1716 transferred in a single operation :-), however more information
1717 could be given following the dineroIII requirement to allow more
1718 complete memory and cache simulators to provide better
1719 results. i.e. the University of Pisa has a cache simulator that can
1720 also take bus size and speed as (variable) inputs to calculate
1721 complete system performance (a much more useful ability when trying
1722 to construct an end product, rather than a processor). They
1723 currently have an ARM version of their tool called ChARM. */
1724
1725
1726 void
1727 dotrace (SIM_DESC sd,
1728 sim_cpu *cpu,
1729 FILE *tracefh,
1730 int type,
1731 address_word address,
1732 int width,
1733 const char *comment, ...)
1734 {
1735 if (STATE & simTRACE) {
1736 va_list ap;
1737 fprintf(tracefh,"%d %s ; width %d ; ",
1738 type,
1739 pr_addr(address),
1740 width);
1741 va_start(ap,comment);
1742 vfprintf(tracefh,comment,ap);
1743 va_end(ap);
1744 fprintf(tracefh,"\n");
1745 }
1746 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1747 we may be generating 64bit ones, we should put the hi-32bits of the
1748 address into the comment field. */
1749
1750 /* TODO: Provide a buffer for the trace lines. We can then avoid
1751 performing writes until the buffer is filled, or the file is
1752 being closed. */
1753
1754 /* NOTE: We could consider adding a comment field to the "din" file
1755 produced using type 3 markers (unknown access). This would then
1756 allow information about the program that the "din" is for, and
1757 the MIPs world that was being simulated, to be placed into the
1758 trace file. */
1759
1760 return;
1761 }
1762 #endif /* WITH_TRACE_ANY_P */
1763
1764 /*---------------------------------------------------------------------------*/
1765 /*-- simulator engine -------------------------------------------------------*/
1766 /*---------------------------------------------------------------------------*/
1767
1768 static void
1769 ColdReset (SIM_DESC sd)
1770 {
1771 int cpu_nr;
1772 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1773 {
1774 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1775 /* RESET: Fixed PC address: */
1776 PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1777 /* The reset vector address is in the unmapped, uncached memory space. */
1778
1779 SR &= ~(status_SR | status_TS | status_RP);
1780 SR |= (status_ERL | status_BEV);
1781
1782 /* Cheat and allow access to the complete register set immediately */
1783 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1784 && WITH_TARGET_WORD_BITSIZE == 64)
1785 SR |= status_FR; /* 64bit registers */
1786
1787 /* Ensure that any instructions with pending register updates are
1788 cleared: */
1789 PENDING_INVALIDATE();
1790
1791 /* Initialise the FPU registers to the unknown state */
1792 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1793 {
1794 int rn;
1795 for (rn = 0; (rn < 32); rn++)
1796 FPR_STATE[rn] = fmt_uninterpreted;
1797 }
1798
1799 /* Initialise the Config0 register. */
1800 C0_CONFIG = 0x80000000 /* Config1 present */
1801 | 2; /* KSEG0 uncached */
1802 if (WITH_TARGET_WORD_BITSIZE == 64)
1803 {
1804 /* FIXME Currently mips/sim-main.c:address_translation()
1805 truncates all addresses to 32-bits. */
1806 if (0 && WITH_TARGET_ADDRESS_BITSIZE == 64)
1807 C0_CONFIG |= (2 << 13); /* MIPS64, 64-bit addresses */
1808 else
1809 C0_CONFIG |= (1 << 13); /* MIPS64, 32-bit addresses */
1810 }
1811 if (BigEndianMem)
1812 C0_CONFIG |= 0x00008000; /* Big Endian */
1813 }
1814 }
1815
1816
1817
1818
1819 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1820 /* Signal an exception condition. This will result in an exception
1821 that aborts the instruction. The instruction operation pseudocode
1822 will never see a return from this function call. */
1823
1824 void
1825 signal_exception (SIM_DESC sd,
1826 sim_cpu *cpu,
1827 address_word cia,
1828 int exception,...)
1829 {
1830 /* int vector; */
1831
1832 #ifdef DEBUG
1833 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1834 #endif /* DEBUG */
1835
1836 /* Ensure that any active atomic read/modify/write operation will fail: */
1837 LLBIT = 0;
1838
1839 /* Save registers before interrupt dispatching */
1840 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1841 SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1842 #endif
1843
1844 switch (exception) {
1845
1846 case DebugBreakPoint:
1847 if (! (Debug & Debug_DM))
1848 {
1849 if (INDELAYSLOT())
1850 {
1851 CANCELDELAYSLOT();
1852
1853 Debug |= Debug_DBD; /* signaled from within in delay slot */
1854 DEPC = cia - 4; /* reference the branch instruction */
1855 }
1856 else
1857 {
1858 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1859 DEPC = cia;
1860 }
1861
1862 Debug |= Debug_DM; /* in debugging mode */
1863 Debug |= Debug_DBp; /* raising a DBp exception */
1864 PC = 0xBFC00200;
1865 sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1866 }
1867 break;
1868
1869 case ReservedInstruction:
1870 {
1871 va_list ap;
1872 unsigned int instruction;
1873 va_start(ap,exception);
1874 instruction = va_arg(ap,unsigned int);
1875 va_end(ap);
1876 /* Provide simple monitor support using ReservedInstruction
1877 exceptions. The following code simulates the fixed vector
1878 entry points into the IDT monitor by causing a simulator
1879 trap, performing the monitor operation, and returning to
1880 the address held in the $ra register (standard PCS return
1881 address). This means we only need to pre-load the vector
1882 space with suitable instruction values. For systems were
1883 actual trap instructions are used, we would not need to
1884 perform this magic. */
1885 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1886 {
1887 int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK;
1888 if (!sim_monitor (SD, CPU, cia, reason))
1889 sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia));
1890
1891 /* NOTE: This assumes that a branch-and-link style
1892 instruction was used to enter the vector (which is the
1893 case with the current IDT monitor). */
1894 sim_engine_restart (SD, CPU, NULL, RA);
1895 }
1896 /* Look for the mips16 entry and exit instructions, and
1897 simulate a handler for them. */
1898 else if ((cia & 1) != 0
1899 && (instruction & 0xf81f) == 0xe809
1900 && (instruction & 0x0c0) != 0x0c0)
1901 {
1902 mips16_entry (SD, CPU, cia, instruction);
1903 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1904 }
1905 /* else fall through to normal exception processing */
1906 sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1907 }
1908
1909 default:
1910 /* Store exception code into current exception id variable (used
1911 by exit code): */
1912
1913 /* TODO: If not simulating exceptions then stop the simulator
1914 execution. At the moment we always stop the simulation. */
1915
1916 #ifdef SUBTARGET_R3900
1917 /* update interrupt-related registers */
1918
1919 /* insert exception code in bits 6:2 */
1920 CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1921 /* shift IE/KU history bits left */
1922 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1923
1924 if (STATE & simDELAYSLOT)
1925 {
1926 STATE &= ~simDELAYSLOT;
1927 CAUSE |= cause_BD;
1928 EPC = (cia - 4); /* reference the branch instruction */
1929 }
1930 else
1931 EPC = cia;
1932
1933 if (SR & status_BEV)
1934 PC = (signed)0xBFC00000 + 0x180;
1935 else
1936 PC = (signed)0x80000000 + 0x080;
1937 #else
1938 /* See figure 5-17 for an outline of the code below */
1939 if (! (SR & status_EXL))
1940 {
1941 CAUSE = (exception << 2);
1942 if (STATE & simDELAYSLOT)
1943 {
1944 STATE &= ~simDELAYSLOT;
1945 CAUSE |= cause_BD;
1946 EPC = (cia - 4); /* reference the branch instruction */
1947 }
1948 else
1949 EPC = cia;
1950 /* FIXME: TLB et.al. */
1951 /* vector = 0x180; */
1952 }
1953 else
1954 {
1955 CAUSE = (exception << 2);
1956 /* vector = 0x180; */
1957 }
1958 SR |= status_EXL;
1959 /* Store exception code into current exception id variable (used
1960 by exit code): */
1961
1962 if (SR & status_BEV)
1963 PC = (signed)0xBFC00200 + 0x180;
1964 else
1965 PC = (signed)0x80000000 + 0x180;
1966 #endif
1967
1968 switch ((CAUSE >> 2) & 0x1F)
1969 {
1970 case Interrupt:
1971 /* Interrupts arrive during event processing, no need to
1972 restart */
1973 return;
1974
1975 case NMIReset:
1976 /* Ditto */
1977 #ifdef SUBTARGET_3900
1978 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1979 PC = (signed)0xBFC00000;
1980 #endif /* SUBTARGET_3900 */
1981 return;
1982
1983 case TLBModification:
1984 case TLBLoad:
1985 case TLBStore:
1986 case AddressLoad:
1987 case AddressStore:
1988 case InstructionFetch:
1989 case DataReference:
1990 /* The following is so that the simulator will continue from the
1991 exception handler address. */
1992 sim_engine_halt (SD, CPU, NULL, PC,
1993 sim_stopped, SIM_SIGBUS);
1994
1995 case ReservedInstruction:
1996 case CoProcessorUnusable:
1997 PC = EPC;
1998 sim_engine_halt (SD, CPU, NULL, PC,
1999 sim_stopped, SIM_SIGILL);
2000
2001 case IntegerOverflow:
2002 case FPE:
2003 sim_engine_halt (SD, CPU, NULL, PC,
2004 sim_stopped, SIM_SIGFPE);
2005
2006 case BreakPoint:
2007 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
2008 break;
2009
2010 case SystemCall:
2011 case Trap:
2012 sim_engine_restart (SD, CPU, NULL, PC);
2013 break;
2014
2015 case Watch:
2016 PC = EPC;
2017 sim_engine_halt (SD, CPU, NULL, PC,
2018 sim_stopped, SIM_SIGTRAP);
2019
2020 default: /* Unknown internal exception */
2021 PC = EPC;
2022 sim_engine_halt (SD, CPU, NULL, PC,
2023 sim_stopped, SIM_SIGABRT);
2024
2025 }
2026
2027 case SimulatorFault:
2028 {
2029 va_list ap;
2030 char *msg;
2031 va_start(ap,exception);
2032 msg = va_arg(ap,char *);
2033 va_end(ap);
2034 sim_engine_abort (SD, CPU, NULL_CIA,
2035 "FATAL: Simulator error \"%s\"\n",msg);
2036 }
2037 }
2038
2039 return;
2040 }
2041
2042
2043
2044 /* This function implements what the MIPS32 and MIPS64 ISAs define as
2045 "UNPREDICTABLE" behaviour.
2046
2047 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2048 may vary from processor implementation to processor implementation,
2049 instruction to instruction, or as a function of time on the same
2050 implementation or instruction. Software can never depend on results
2051 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
2052 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
2053 0.95, page 2.)
2054
2055 For UNPREDICTABLE behaviour, we print a message, if possible print
2056 the offending instructions mips.igen instruction name (provided by
2057 the caller), and stop the simulator.
2058
2059 XXX FIXME: eventually, stopping the simulator should be made conditional
2060 on a command-line option. */
2061 void
2062 unpredictable_action(sim_cpu *cpu, address_word cia)
2063 {
2064 SIM_DESC sd = CPU_STATE(cpu);
2065
2066 sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia));
2067 sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT);
2068 }
2069
2070
2071 /*-- co-processor support routines ------------------------------------------*/
2072
2073 static int UNUSED
2074 CoProcPresent(unsigned int coproc_number)
2075 {
2076 /* Return TRUE if simulator provides a model for the given co-processor number */
2077 return(0);
2078 }
2079
2080 void
2081 cop_lw (SIM_DESC sd,
2082 sim_cpu *cpu,
2083 address_word cia,
2084 int coproc_num,
2085 int coproc_reg,
2086 unsigned int memword)
2087 {
2088 switch (coproc_num)
2089 {
2090 case 1:
2091 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2092 {
2093 #ifdef DEBUG
2094 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2095 #endif
2096 StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
2097 break;
2098 }
2099
2100 default:
2101 #if 0 /* this should be controlled by a configuration option */
2102 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));
2103 #endif
2104 break;
2105 }
2106
2107 return;
2108 }
2109
2110 void
2111 cop_ld (SIM_DESC sd,
2112 sim_cpu *cpu,
2113 address_word cia,
2114 int coproc_num,
2115 int coproc_reg,
2116 uword64 memword)
2117 {
2118
2119 #ifdef DEBUG
2120 printf("DBG: COP_LD: coproc_num = %d, coproc_reg = %d, value = 0x%s : PC = 0x%s\n", coproc_num, coproc_reg, pr_uword64(memword), pr_addr(cia));
2121 #endif
2122
2123 switch (coproc_num) {
2124 case 1:
2125 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2126 {
2127 StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
2128 break;
2129 }
2130
2131 default:
2132 #if 0 /* this message should be controlled by a configuration option */
2133 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));
2134 #endif
2135 break;
2136 }
2137
2138 return;
2139 }
2140
2141
2142
2143
2144 unsigned int
2145 cop_sw (SIM_DESC sd,
2146 sim_cpu *cpu,
2147 address_word cia,
2148 int coproc_num,
2149 int coproc_reg)
2150 {
2151 unsigned int value = 0;
2152
2153 switch (coproc_num)
2154 {
2155 case 1:
2156 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2157 {
2158 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
2159 break;
2160 }
2161
2162 default:
2163 #if 0 /* should be controlled by configuration option */
2164 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2165 #endif
2166 break;
2167 }
2168
2169 return(value);
2170 }
2171
2172 uword64
2173 cop_sd (SIM_DESC sd,
2174 sim_cpu *cpu,
2175 address_word cia,
2176 int coproc_num,
2177 int coproc_reg)
2178 {
2179 uword64 value = 0;
2180 switch (coproc_num)
2181 {
2182 case 1:
2183 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2184 {
2185 value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
2186 break;
2187 }
2188
2189 default:
2190 #if 0 /* should be controlled by configuration option */
2191 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2192 #endif
2193 break;
2194 }
2195
2196 return(value);
2197 }
2198
2199
2200
2201
2202 void
2203 decode_coproc (SIM_DESC sd,
2204 sim_cpu *cpu,
2205 address_word cia,
2206 unsigned int instruction,
2207 int coprocnum,
2208 CP0_operation op,
2209 int rt,
2210 int rd,
2211 int sel)
2212 {
2213 switch (coprocnum)
2214 {
2215 case 0: /* standard CPU control and cache registers */
2216 {
2217 /* R4000 Users Manual (second edition) lists the following CP0
2218 instructions:
2219 CODE><-RT><RD-><--TAIL--->
2220 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2221 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2222 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2223 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2224 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2225 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2226 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2227 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2228 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2229 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2230 */
2231 if (((op == cp0_mfc0) || (op == cp0_mtc0) /* MFC0 / MTC0 */
2232 || (op == cp0_dmfc0) || (op == cp0_dmtc0)) /* DMFC0 / DMTC0 */
2233 && sel == 0)
2234 {
2235 switch (rd) /* NOTEs: Standard CP0 registers */
2236 {
2237 /* 0 = Index R4000 VR4100 VR4300 */
2238 /* 1 = Random R4000 VR4100 VR4300 */
2239 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
2240 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
2241 /* 4 = Context R4000 VR4100 VR4300 */
2242 /* 5 = PageMask R4000 VR4100 VR4300 */
2243 /* 6 = Wired R4000 VR4100 VR4300 */
2244 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2245 /* 9 = Count R4000 VR4100 VR4300 */
2246 /* 10 = EntryHi R4000 VR4100 VR4300 */
2247 /* 11 = Compare R4000 VR4100 VR4300 */
2248 /* 12 = SR R4000 VR4100 VR4300 */
2249 #ifdef SUBTARGET_R3900
2250 case 3:
2251 /* 3 = Config R3900 */
2252 case 7:
2253 /* 7 = Cache R3900 */
2254 case 15:
2255 /* 15 = PRID R3900 */
2256
2257 /* ignore */
2258 break;
2259
2260 case 8:
2261 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2262 if (op == cp0_mfc0 || op == cp0_dmfc0)
2263 GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
2264 else
2265 COP0_BADVADDR = GPR[rt];
2266 break;
2267
2268 #endif /* SUBTARGET_R3900 */
2269 case 12:
2270 if (op == cp0_mfc0 || op == cp0_dmfc0)
2271 GPR[rt] = SR;
2272 else
2273 SR = GPR[rt];
2274 break;
2275 /* 13 = Cause R4000 VR4100 VR4300 */
2276 case 13:
2277 if (op == cp0_mfc0 || op == cp0_dmfc0)
2278 GPR[rt] = CAUSE;
2279 else
2280 CAUSE = GPR[rt];
2281 break;
2282 /* 14 = EPC R4000 VR4100 VR4300 */
2283 case 14:
2284 if (op == cp0_mfc0 || op == cp0_dmfc0)
2285 GPR[rt] = (signed_word) (signed_address) EPC;
2286 else
2287 EPC = GPR[rt];
2288 break;
2289 /* 15 = PRId R4000 VR4100 VR4300 */
2290 #ifdef SUBTARGET_R3900
2291 /* 16 = Debug */
2292 case 16:
2293 if (op == cp0_mfc0 || op == cp0_dmfc0)
2294 GPR[rt] = Debug;
2295 else
2296 Debug = GPR[rt];
2297 break;
2298 #else
2299 /* 16 = Config R4000 VR4100 VR4300 */
2300 case 16:
2301 if (op == cp0_mfc0 || op == cp0_dmfc0)
2302 GPR[rt] = C0_CONFIG;
2303 else
2304 /* only bottom three bits are writable */
2305 C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7);
2306 break;
2307 #endif
2308 #ifdef SUBTARGET_R3900
2309 /* 17 = Debug */
2310 case 17:
2311 if (op == cp0_mfc0 || op == cp0_dmfc0)
2312 GPR[rt] = DEPC;
2313 else
2314 DEPC = GPR[rt];
2315 break;
2316 #else
2317 /* 17 = LLAddr R4000 VR4100 VR4300 */
2318 #endif
2319 /* 18 = WatchLo R4000 VR4100 VR4300 */
2320 /* 19 = WatchHi R4000 VR4100 VR4300 */
2321 /* 20 = XContext R4000 VR4100 VR4300 */
2322 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2323 /* 27 = CacheErr R4000 VR4100 */
2324 /* 28 = TagLo R4000 VR4100 VR4300 */
2325 /* 29 = TagHi R4000 VR4100 VR4300 */
2326 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
2327 if (STATE_VERBOSE_P(SD))
2328 sim_io_eprintf (SD,
2329 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2330 (unsigned long)cia);
2331 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
2332 /* CPR[0,rd] = GPR[rt]; */
2333 default:
2334 if (op == cp0_mfc0 || op == cp0_dmfc0)
2335 GPR[rt] = (signed_word) (int32_t) COP0_GPR[rd];
2336 else
2337 COP0_GPR[rd] = GPR[rt];
2338 #if 0
2339 if (code == 0x00)
2340 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2341 else
2342 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2343 #endif
2344 }
2345 }
2346 else if ((op == cp0_mfc0 || op == cp0_dmfc0)
2347 && rd == 16)
2348 {
2349 /* [D]MFC0 RT,C0_CONFIG,SEL */
2350 int32_t cfg = 0;
2351 switch (sel)
2352 {
2353 case 0:
2354 cfg = C0_CONFIG;
2355 break;
2356 case 1:
2357 /* MIPS32 r/o Config1:
2358 Config2 present */
2359 cfg = 0x80000000;
2360 /* MIPS16 implemented.
2361 XXX How to check configuration? */
2362 cfg |= 0x0000004;
2363 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2364 /* MDMX & FPU implemented */
2365 cfg |= 0x00000021;
2366 break;
2367 case 2:
2368 /* MIPS32 r/o Config2:
2369 Config3 present. */
2370 cfg = 0x80000000;
2371 break;
2372 case 3:
2373 /* MIPS32 r/o Config3:
2374 SmartMIPS implemented. */
2375 cfg = 0x00000002;
2376 break;
2377 }
2378 GPR[rt] = cfg;
2379 }
2380 else if (op == cp0_eret && sel == 0x18)
2381 {
2382 /* ERET */
2383 if (SR & status_ERL)
2384 {
2385 /* Oops, not yet available */
2386 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
2387 PC = EPC;
2388 SR &= ~status_ERL;
2389 }
2390 else
2391 {
2392 PC = EPC;
2393 SR &= ~status_EXL;
2394 }
2395 }
2396 else if (op == cp0_rfe && sel == 0x10)
2397 {
2398 /* RFE */
2399 #ifdef SUBTARGET_R3900
2400 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2401
2402 /* shift IE/KU history bits right */
2403 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
2404
2405 /* TODO: CACHE register */
2406 #endif /* SUBTARGET_R3900 */
2407 }
2408 else if (op == cp0_deret && sel == 0x1F)
2409 {
2410 /* DERET */
2411 Debug &= ~Debug_DM;
2412 DELAYSLOT();
2413 DSPC = DEPC;
2414 }
2415 else
2416 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
2417 /* TODO: When executing an ERET or RFE instruction we should
2418 clear LLBIT, to ensure that any out-standing atomic
2419 read/modify/write sequence fails. */
2420 }
2421 break;
2422
2423 case 2: /* co-processor 2 */
2424 {
2425 int handle = 0;
2426
2427
2428 if (!handle)
2429 {
2430 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2431 instruction,pr_addr(cia));
2432 }
2433 }
2434 break;
2435
2436 case 1: /* should not occur (FPU co-processor) */
2437 case 3: /* should not occur (FPU co-processor) */
2438 SignalException(ReservedInstruction,instruction);
2439 break;
2440 }
2441
2442 return;
2443 }
2444
2445
2446 /* This code copied from gdb's utils.c. Would like to share this code,
2447 but don't know of a common place where both could get to it. */
2448
2449 /* Temporary storage using circular buffer */
2450 #define NUMCELLS 16
2451 #define CELLSIZE 32
2452 static char*
2453 get_cell (void)
2454 {
2455 static char buf[NUMCELLS][CELLSIZE];
2456 static int cell=0;
2457 if (++cell>=NUMCELLS) cell=0;
2458 return buf[cell];
2459 }
2460
2461 /* Print routines to handle variable size regs, etc */
2462
2463 char*
2464 pr_addr (address_word addr)
2465 {
2466 char *paddr_str=get_cell();
2467 sprintf (paddr_str, "%0*" PRIxTA, (int) (sizeof (addr) * 2), addr);
2468 return paddr_str;
2469 }
2470
2471 char*
2472 pr_uword64 (uword64 addr)
2473 {
2474 char *paddr_str=get_cell();
2475 sprintf (paddr_str, "%016" PRIx64, addr);
2476 return paddr_str;
2477 }
2478
2479
2480 void
2481 mips_core_signal (SIM_DESC sd,
2482 sim_cpu *cpu,
2483 sim_cia cia,
2484 unsigned map,
2485 int nr_bytes,
2486 address_word addr,
2487 transfer_type transfer,
2488 sim_core_signals sig)
2489 {
2490 const char *copy = (transfer == read_transfer ? "read" : "write");
2491 address_word ip = CIA_ADDR (cia);
2492
2493 switch (sig)
2494 {
2495 case sim_core_unmapped_signal:
2496 sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2497 nr_bytes, copy,
2498 (unsigned long) addr, (unsigned long) ip);
2499 COP0_BADVADDR = addr;
2500 SignalExceptionDataReference();
2501 break;
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 break;
2513
2514 default:
2515 sim_engine_abort (sd, cpu, cia,
2516 "mips_core_signal - internal error - bad switch");
2517 }
2518 }
2519
2520
2521 void
2522 mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
2523 {
2524 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
2525
2526 ASSERT(cpu != NULL);
2527
2528 if (mips_cpu->exc_suspended > 0)
2529 sim_io_eprintf (sd, "Warning, nested exception triggered (%d)\n",
2530 mips_cpu->exc_suspended);
2531
2532 PC = cia;
2533 memcpy (mips_cpu->exc_trigger_registers, mips_cpu->registers,
2534 sizeof (mips_cpu->exc_trigger_registers));
2535 mips_cpu->exc_suspended = 0;
2536 }
2537
2538 void
2539 mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
2540 {
2541 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
2542
2543 ASSERT(cpu != NULL);
2544
2545 if (mips_cpu->exc_suspended > 0)
2546 sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
2547 mips_cpu->exc_suspended, exception);
2548
2549 memcpy (mips_cpu->exc_suspend_registers, mips_cpu->registers,
2550 sizeof (mips_cpu->exc_suspend_registers));
2551 memcpy (mips_cpu->registers, mips_cpu->exc_trigger_registers,
2552 sizeof (mips_cpu->registers));
2553 mips_cpu->exc_suspended = exception;
2554 }
2555
2556 void
2557 mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
2558 {
2559 struct mips_sim_cpu *mips_cpu = MIPS_SIM_CPU (cpu);
2560
2561 ASSERT(cpu != NULL);
2562
2563 if (exception == 0 && mips_cpu->exc_suspended > 0)
2564 {
2565 /* warn not for breakpoints */
2566 if (mips_cpu->exc_suspended != sim_signal_to_host(sd, SIM_SIGTRAP))
2567 sim_io_eprintf(sd, "Warning, resuming but ignoring pending exception signal (%d)\n",
2568 mips_cpu->exc_suspended);
2569 }
2570 else if (exception != 0 && mips_cpu->exc_suspended > 0)
2571 {
2572 if (exception != mips_cpu->exc_suspended)
2573 sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2574 mips_cpu->exc_suspended, exception);
2575
2576 memcpy (mips_cpu->registers, mips_cpu->exc_suspend_registers,
2577 sizeof (mips_cpu->registers));
2578 }
2579 else if (exception != 0 && mips_cpu->exc_suspended == 0)
2580 {
2581 sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
2582 }
2583 mips_cpu->exc_suspended = 0;
2584 }
2585
2586
2587 /*---------------------------------------------------------------------------*/
2588 /*> EOF interp.c <*/