]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/mips/interp.c
sim: overhaul & unify endian settings management
[thirdparty/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
35 #include "itable.h"
36
37 #include <stdio.h>
38 #include <stdarg.h>
39 #include <ansidecl.h>
40 #include <ctype.h>
41 #include <limits.h>
42 #include <math.h>
43 #include <stdlib.h>
44 #include <string.h>
45
46 #include "getopt.h"
47 #include "libiberty.h"
48 #include "bfd.h"
49 #include "elf-bfd.h"
50 #include "sim/callback.h" /* GDB simulator callback interface */
51 #include "sim/sim.h" /* GDB simulator interface */
52 #include "sim-syscall.h" /* Simulator system call support */
53
54 char* pr_addr (SIM_ADDR addr);
55 char* pr_uword64 (uword64 addr);
56
57
58 /* Within interp.c we refer to the sim_state and sim_cpu directly. */
59 #define CPU cpu
60 #define SD sd
61
62
63 /* The following reserved instruction value is used when a simulator
64 trap is required. NOTE: Care must be taken, since this value may be
65 used in later revisions of the MIPS ISA. */
66
67 #define RSVD_INSTRUCTION (0x00000039)
68 #define RSVD_INSTRUCTION_MASK (0xFC00003F)
69
70 #define RSVD_INSTRUCTION_ARG_SHIFT 6
71 #define RSVD_INSTRUCTION_ARG_MASK 0xFFFFF
72
73
74 /* Bits in the Debug register */
75 #define Debug_DBD 0x80000000 /* Debug Branch Delay */
76 #define Debug_DM 0x40000000 /* Debug Mode */
77 #define Debug_DBp 0x00000002 /* Debug Breakpoint indicator */
78
79 /*---------------------------------------------------------------------------*/
80 /*-- GDB simulator interface ------------------------------------------------*/
81 /*---------------------------------------------------------------------------*/
82
83 static void ColdReset (SIM_DESC sd);
84
85 /*---------------------------------------------------------------------------*/
86
87
88
89 #define DELAYSLOT() {\
90 if (STATE & simDELAYSLOT)\
91 sim_io_eprintf(sd,"Delay slot already activated (branch in delay slot?)\n");\
92 STATE |= simDELAYSLOT;\
93 }
94
95 #define JALDELAYSLOT() {\
96 DELAYSLOT ();\
97 STATE |= simJALDELAYSLOT;\
98 }
99
100 #define NULLIFY() {\
101 STATE &= ~simDELAYSLOT;\
102 STATE |= simSKIPNEXT;\
103 }
104
105 #define CANCELDELAYSLOT() {\
106 DSSTATE = 0;\
107 STATE &= ~(simDELAYSLOT | simJALDELAYSLOT);\
108 }
109
110 #define INDELAYSLOT() ((STATE & simDELAYSLOT) != 0)
111 #define INJALDELAYSLOT() ((STATE & simJALDELAYSLOT) != 0)
112
113 /* Note that the monitor code essentially assumes this layout of memory.
114 If you change these, change the monitor code, too. */
115 /* FIXME Currently addresses are truncated to 32-bits, see
116 mips/sim-main.c:address_translation(). If that changes, then these
117 values will need to be extended, and tested for more carefully. */
118 #define K0BASE (0x80000000)
119 #define K0SIZE (0x20000000)
120 #define K1BASE (0xA0000000)
121 #define K1SIZE (0x20000000)
122
123 /* Simple run-time monitor support.
124
125 We emulate the monitor by placing magic reserved instructions at
126 the monitor's entry points; when we hit these instructions, instead
127 of raising an exception (as we would normally), we look at the
128 instruction and perform the appropriate monitory operation.
129
130 `*_monitor_base' are the physical addresses at which the corresponding
131 monitor vectors are located. `0' means none. By default,
132 install all three.
133 The RSVD_INSTRUCTION... macros specify the magic instructions we
134 use at the monitor entry points. */
135 static int firmware_option_p = 0;
136 static SIM_ADDR idt_monitor_base = 0xBFC00000;
137 static SIM_ADDR pmon_monitor_base = 0xBFC00500;
138 static SIM_ADDR lsipmon_monitor_base = 0xBFC00200;
139
140 static SIM_RC sim_firmware_command (SIM_DESC sd, char* arg);
141
142 #define MEM_SIZE (8 << 20) /* 8 MBytes */
143
144
145 #if WITH_TRACE_ANY_P
146 static char *tracefile = "trace.din"; /* default filename for trace log */
147 FILE *tracefh = NULL;
148 static void open_trace (SIM_DESC sd);
149 #else
150 #define open_trace(sd)
151 #endif
152
153 static const char * get_insn_name (sim_cpu *, int);
154
155 /* simulation target board. NULL=canonical */
156 static char* board = NULL;
157
158
159 static DECLARE_OPTION_HANDLER (mips_option_handler);
160
161 enum {
162 OPTION_DINERO_TRACE = OPTION_START,
163 OPTION_DINERO_FILE,
164 OPTION_FIRMWARE,
165 OPTION_INFO_MEMORY,
166 OPTION_BOARD
167 };
168
169 static int display_mem_info = 0;
170
171 static SIM_RC
172 mips_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt, char *arg,
173 int is_command)
174 {
175 int cpu_nr;
176 switch (opt)
177 {
178 case OPTION_DINERO_TRACE: /* ??? */
179 #if WITH_TRACE_ANY_P
180 /* Eventually the simTRACE flag could be treated as a toggle, to
181 allow external control of the program points being traced
182 (i.e. only from main onwards, excluding the run-time setup,
183 etc.). */
184 for (cpu_nr = 0; cpu_nr < MAX_NR_PROCESSORS; cpu_nr++)
185 {
186 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
187 if (arg == NULL)
188 STATE |= simTRACE;
189 else if (strcmp (arg, "yes") == 0)
190 STATE |= simTRACE;
191 else if (strcmp (arg, "no") == 0)
192 STATE &= ~simTRACE;
193 else if (strcmp (arg, "on") == 0)
194 STATE |= simTRACE;
195 else if (strcmp (arg, "off") == 0)
196 STATE &= ~simTRACE;
197 else
198 {
199 fprintf (stderr, "Unrecognized dinero-trace option `%s'\n", arg);
200 return SIM_RC_FAIL;
201 }
202 }
203 return SIM_RC_OK;
204 #else /* !WITH_TRACE_ANY_P */
205 fprintf(stderr,"\
206 Simulator constructed without dinero tracing support (for performance).\n\
207 Re-compile simulator with \"-DWITH_TRACE_ANY_P\" to enable this option.\n");
208 return SIM_RC_FAIL;
209 #endif /* !WITH_TRACE_ANY_P */
210
211 case OPTION_DINERO_FILE:
212 #if WITH_TRACE_ANY_P
213 if (optarg != NULL) {
214 char *tmp;
215 tmp = (char *)malloc(strlen(optarg) + 1);
216 if (tmp == NULL)
217 {
218 sim_io_printf(sd,"Failed to allocate buffer for tracefile name \"%s\"\n",optarg);
219 return SIM_RC_FAIL;
220 }
221 else {
222 strcpy(tmp,optarg);
223 tracefile = tmp;
224 sim_io_printf(sd,"Placing trace information into file \"%s\"\n",tracefile);
225 }
226 }
227 #endif /* WITH_TRACE_ANY_P */
228 return SIM_RC_OK;
229
230 case OPTION_FIRMWARE:
231 return sim_firmware_command (sd, arg);
232
233 case OPTION_BOARD:
234 {
235 if (arg)
236 {
237 board = zalloc(strlen(arg) + 1);
238 strcpy(board, arg);
239 }
240 return SIM_RC_OK;
241 }
242
243 case OPTION_INFO_MEMORY:
244 display_mem_info = 1;
245 break;
246 }
247
248 return SIM_RC_OK;
249 }
250
251
252 static const OPTION mips_options[] =
253 {
254 { {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
255 '\0', "on|off", "Enable dinero tracing",
256 mips_option_handler },
257 { {"dinero-file", required_argument, NULL, OPTION_DINERO_FILE},
258 '\0', "FILE", "Write dinero trace to FILE",
259 mips_option_handler },
260 { {"firmware", required_argument, NULL, OPTION_FIRMWARE},
261 '\0', "[idt|pmon|lsipmon|none][@ADDRESS]", "Emulate ROM monitor",
262 mips_option_handler },
263 { {"board", required_argument, NULL, OPTION_BOARD},
264 '\0', "none" /* rely on compile-time string concatenation for other options */
265
266 #define BOARD_JMR3904 "jmr3904"
267 "|" BOARD_JMR3904
268 #define BOARD_JMR3904_PAL "jmr3904pal"
269 "|" BOARD_JMR3904_PAL
270 #define BOARD_JMR3904_DEBUG "jmr3904debug"
271 "|" BOARD_JMR3904_DEBUG
272 #define BOARD_BSP "bsp"
273 "|" BOARD_BSP
274
275 , "Customize simulation for a particular board.", mips_option_handler },
276
277 /* These next two options have the same names as ones found in the
278 memory_options[] array in common/sim-memopt.c. This is because
279 the intention is to provide an alternative handler for those two
280 options. We need an alternative handler because the memory
281 regions are not set up until after the command line arguments
282 have been parsed, and so we cannot display the memory info whilst
283 processing the command line. There is a hack in sim_open to
284 remove these handlers when we want the real --memory-info option
285 to work. */
286 { { "info-memory", no_argument, NULL, OPTION_INFO_MEMORY },
287 '\0', NULL, "List configured memory regions", mips_option_handler },
288 { { "memory-info", no_argument, NULL, OPTION_INFO_MEMORY },
289 '\0', NULL, NULL, mips_option_handler },
290
291 { {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
292 };
293
294
295 int interrupt_pending;
296
297 void
298 interrupt_event (SIM_DESC sd, void *data)
299 {
300 sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
301 address_word cia = CPU_PC_GET (cpu);
302 if (SR & status_IE)
303 {
304 interrupt_pending = 0;
305 SignalExceptionInterrupt (1); /* interrupt "1" */
306 }
307 else if (!interrupt_pending)
308 sim_events_schedule (sd, 1, interrupt_event, data);
309 }
310
311
312 /*---------------------------------------------------------------------------*/
313 /*-- Device registration hook -----------------------------------------------*/
314 /*---------------------------------------------------------------------------*/
315 static void device_init(SIM_DESC sd) {
316 #ifdef DEVICE_INIT
317 extern void register_devices(SIM_DESC);
318 register_devices(sd);
319 #endif
320 }
321
322 /*---------------------------------------------------------------------------*/
323 /*-- GDB simulator interface ------------------------------------------------*/
324 /*---------------------------------------------------------------------------*/
325
326 static sim_cia
327 mips_pc_get (sim_cpu *cpu)
328 {
329 return PC;
330 }
331
332 static void
333 mips_pc_set (sim_cpu *cpu, sim_cia pc)
334 {
335 PC = pc;
336 }
337
338 static int mips_reg_fetch (SIM_CPU *, int, unsigned char *, int);
339 static int mips_reg_store (SIM_CPU *, int, unsigned char *, int);
340
341 SIM_DESC
342 sim_open (SIM_OPEN_KIND kind, host_callback *cb,
343 struct bfd *abfd, char * const *argv)
344 {
345 int i;
346 SIM_DESC sd = sim_state_alloc_extra (kind, cb,
347 sizeof (struct mips_sim_state));
348 sim_cpu *cpu;
349
350 SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
351
352 /* The cpu data is kept in a separately allocated chunk of memory. */
353 if (sim_cpu_alloc_all (sd, 1) != SIM_RC_OK)
354 return 0;
355
356 cpu = STATE_CPU (sd, 0); /* FIXME */
357
358 /* FIXME: watchpoints code shouldn't need this */
359 STATE_WATCHPOINTS (sd)->interrupt_handler = interrupt_event;
360
361 /* Initialize the mechanism for doing insn profiling. */
362 CPU_INSN_NAME (cpu) = get_insn_name;
363 CPU_MAX_INSNS (cpu) = nr_itable_entries;
364
365 STATE = 0;
366
367 if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
368 return 0;
369 sim_add_option_table (sd, NULL, mips_options);
370
371
372 /* The parser will print an error message for us, so we silently return. */
373 if (sim_parse_args (sd, argv) != SIM_RC_OK)
374 {
375 /* Uninstall the modules to avoid memory leaks,
376 file descriptor leaks, etc. */
377 sim_module_uninstall (sd);
378 return 0;
379 }
380
381 /* handle board-specific memory maps */
382 if (board == NULL)
383 {
384 /* Allocate core managed memory */
385 sim_memopt *entry, *match = NULL;
386 address_word mem_size = 0;
387 int mapped = 0;
388
389 /* For compatibility with the old code - under this (at level one)
390 are the kernel spaces K0 & K1. Both of these map to a single
391 smaller sub region */
392 sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
393
394 /* Look for largest memory region defined on command-line at
395 phys address 0. */
396 for (entry = STATE_MEMOPT (sd); entry != NULL; entry = entry->next)
397 {
398 /* If we find an entry at address 0, then we will end up
399 allocating a new buffer in the "memory alias" command
400 below. The region at address 0 will be deleted. */
401 address_word size = (entry->modulo != 0
402 ? entry->modulo : entry->nr_bytes);
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 int i;
452
453 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
454
455 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
456 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
457 0x9FC00000,
458 4 * 1024 * 1024, /* 4 MB */
459 0xBFC00000);
460
461 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
462 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
463 0x80000000,
464 4 * 1024 * 1024, /* 4 MB */
465 0xA0000000);
466
467 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
468 for (i=0; i<8; i++) /* 32 MB total */
469 {
470 unsigned size = 4 * 1024 * 1024; /* 4 MB */
471 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
472 0x88000000 + (i * size),
473 size,
474 0xA8000000 + (i * size));
475 }
476 }
477 #if (WITH_HW)
478 else if (board != NULL
479 && (strcmp(board, BOARD_JMR3904) == 0 ||
480 strcmp(board, BOARD_JMR3904_PAL) == 0 ||
481 strcmp(board, BOARD_JMR3904_DEBUG) == 0))
482 {
483 /* match VIRTUAL memory layout of JMR-TX3904 board */
484 int i;
485
486 /* --- disable monitor unless forced on by user --- */
487
488 if (! firmware_option_p)
489 {
490 idt_monitor_base = 0;
491 pmon_monitor_base = 0;
492 lsipmon_monitor_base = 0;
493 }
494
495 /* --- environment --- */
496
497 STATE_ENVIRONMENT (sd) = OPERATING_ENVIRONMENT;
498
499 /* --- memory --- */
500
501 /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
502 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
503 0x9FC00000,
504 4 * 1024 * 1024, /* 4 MB */
505 0xBFC00000);
506
507 /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
508 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
509 0x80000000,
510 4 * 1024 * 1024, /* 4 MB */
511 0xA0000000);
512
513 /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
514 for (i=0; i<8; i++) /* 32 MB total */
515 {
516 unsigned size = 4 * 1024 * 1024; /* 4 MB */
517 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x,0x%0x",
518 0x88000000 + (i * size),
519 size,
520 0xA8000000 + (i * size));
521 }
522
523 /* Dummy memory regions for unsimulated devices - sorted by address */
524
525 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB1000000, 0x400); /* ISA I/O */
526 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2100000, 0x004); /* ISA ctl */
527 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2500000, 0x004); /* LED/switch */
528 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB2700000, 0x004); /* RTC */
529 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xB3C00000, 0x004); /* RTC */
530 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFF8000, 0x900); /* DRAMC */
531 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFF9000, 0x200); /* EBIF */
532 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFFE000, 0x01c); /* EBIF */
533 sim_do_commandf (sd, "memory alias 0x%x@1,0x%x", 0xFFFFF500, 0x300); /* PIO */
534
535
536 /* --- simulated devices --- */
537 sim_hw_parse (sd, "/tx3904irc@0xffffc000/reg 0xffffc000 0x20");
538 sim_hw_parse (sd, "/tx3904cpu");
539 sim_hw_parse (sd, "/tx3904tmr@0xfffff000/reg 0xfffff000 0x100");
540 sim_hw_parse (sd, "/tx3904tmr@0xfffff100/reg 0xfffff100 0x100");
541 sim_hw_parse (sd, "/tx3904tmr@0xfffff200/reg 0xfffff200 0x100");
542 sim_hw_parse (sd, "/tx3904sio@0xfffff300/reg 0xfffff300 0x100");
543 {
544 /* FIXME: poking at dv-sockser internals, use tcp backend if
545 --sockser_addr option was given.*/
546 #ifdef HAVE_DV_SOCKSER
547 extern char* sockser_addr;
548 #else
549 # define sockser_addr NULL
550 #endif
551 if (sockser_addr == NULL)
552 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend stdio");
553 else
554 sim_hw_parse (sd, "/tx3904sio@0xfffff300/backend tcp");
555 }
556 sim_hw_parse (sd, "/tx3904sio@0xfffff400/reg 0xfffff400 0x100");
557 sim_hw_parse (sd, "/tx3904sio@0xfffff400/backend stdio");
558
559 /* -- device connections --- */
560 sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
561 sim_hw_parse (sd, "/tx3904tmr@0xfffff000 > int tmr0 /tx3904irc");
562 sim_hw_parse (sd, "/tx3904tmr@0xfffff100 > int tmr1 /tx3904irc");
563 sim_hw_parse (sd, "/tx3904tmr@0xfffff200 > int tmr2 /tx3904irc");
564 sim_hw_parse (sd, "/tx3904sio@0xfffff300 > int sio0 /tx3904irc");
565 sim_hw_parse (sd, "/tx3904sio@0xfffff400 > int sio1 /tx3904irc");
566
567 /* add PAL timer & I/O module */
568 if(! strcmp(board, BOARD_JMR3904_PAL))
569 {
570 /* the device */
571 sim_hw_parse (sd, "/pal@0xffff0000");
572 sim_hw_parse (sd, "/pal@0xffff0000/reg 0xffff0000 64");
573
574 /* wire up interrupt ports to irc */
575 sim_hw_parse (sd, "/pal@0x31000000 > countdown tmr0 /tx3904irc");
576 sim_hw_parse (sd, "/pal@0x31000000 > timer tmr1 /tx3904irc");
577 sim_hw_parse (sd, "/pal@0x31000000 > int int0 /tx3904irc");
578 }
579
580 if(! strcmp(board, BOARD_JMR3904_DEBUG))
581 {
582 /* -- DEBUG: glue interrupt generators --- */
583 sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
584 sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
585 sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
586 sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
587 sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
588 sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
589 sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
590 sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
591 sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
592 sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
593 sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
594 sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
595 sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
596 sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
597 sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
598 sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
599 sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
600 sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
601 sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
602 }
603
604 device_init(sd);
605 }
606 #endif
607
608 if (display_mem_info)
609 {
610 struct option_list * ol;
611 struct option_list * prev;
612
613 /* This is a hack. We want to execute the real --memory-info command
614 line switch which is handled in common/sim-memopts.c, not the
615 override we have defined in this file. So we remove the
616 mips_options array from the state options list. This is safe
617 because we have now processed all of the command line. */
618 for (ol = STATE_OPTIONS (sd), prev = NULL;
619 ol != NULL;
620 prev = ol, ol = ol->next)
621 if (ol->options == mips_options)
622 break;
623
624 SIM_ASSERT (ol != NULL);
625
626 if (prev == NULL)
627 STATE_OPTIONS (sd) = ol->next;
628 else
629 prev->next = ol->next;
630
631 sim_do_commandf (sd, "memory-info");
632 }
633
634 /* check for/establish the a reference program image */
635 if (sim_analyze_program (sd,
636 (STATE_PROG_ARGV (sd) != NULL
637 ? *STATE_PROG_ARGV (sd)
638 : NULL),
639 abfd) != SIM_RC_OK)
640 {
641 sim_module_uninstall (sd);
642 return 0;
643 }
644
645 /* Configure/verify the target byte order and other runtime
646 configuration options */
647 if (sim_config (sd) != SIM_RC_OK)
648 {
649 sim_module_uninstall (sd);
650 return 0;
651 }
652
653 if (sim_post_argv_init (sd) != SIM_RC_OK)
654 {
655 /* Uninstall the modules to avoid memory leaks,
656 file descriptor leaks, etc. */
657 sim_module_uninstall (sd);
658 return 0;
659 }
660
661 /* verify assumptions the simulator made about the host type system.
662 This macro does not return if there is a problem */
663 SIM_ASSERT (sizeof(int) == (4 * sizeof(char)));
664 SIM_ASSERT (sizeof(word64) == (8 * sizeof(char)));
665
666 /* This is NASTY, in that we are assuming the size of specific
667 registers: */
668 {
669 int rn;
670 for (rn = 0; (rn < (LAST_EMBED_REGNUM + 1)); rn++)
671 {
672 if (rn < 32)
673 cpu->register_widths[rn] = WITH_TARGET_WORD_BITSIZE;
674 else if ((rn >= FGR_BASE) && (rn < (FGR_BASE + NR_FGR)))
675 cpu->register_widths[rn] = WITH_TARGET_FLOATING_POINT_BITSIZE;
676 else if ((rn >= 33) && (rn <= 37))
677 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 cpu->register_widths[rn] = 32;
683 else
684 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 0x%x,0x%" PRIxTW ",0x%" PRIxTA,
711 idt_monitor_base, idt_monitor_size,
712 EXTENDED (idt_monitor_base));
713 else
714 sim_do_commandf (sd, "memory region 0x%x,0x%" 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 unsigned32 insn = (RSVD_INSTRUCTION |
725 (((loop >> 2) & RSVD_INSTRUCTION_ARG_MASK)
726 << RSVD_INSTRUCTION_ARG_SHIFT));
727 H2T (insn);
728 sim_write (sd, vaddr, (unsigned char *)&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 unsigned32 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, (unsigned char *)&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, (unsigned char *)&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 unsigned32 halt[2] = { 0x2404002f /* addiu r4, r0, 47 */,
794 HALT_INSTRUCTION /* BREAK */ };
795 H2T (halt[0]);
796 H2T (halt[1]);
797 sim_write (sd, 0x80000000, (unsigned char *) halt, sizeof (halt));
798 sim_write (sd, 0x80000180, (unsigned char *) halt, sizeof (halt));
799 sim_write (sd, 0x80000200, (unsigned char *) halt, sizeof (halt));
800 /* XXX: Write here unconditionally? */
801 sim_write (sd, 0xBFC00200, (unsigned char *) halt, sizeof (halt));
802 sim_write (sd, 0xBFC00380, (unsigned char *) halt, sizeof (halt));
803 sim_write (sd, 0xBFC00400, (unsigned char *) 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, unsigned char *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 if (cpu->register_widths[rn] == 0)
862 {
863 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register store ignored)\n", rn);
864 return 0;
865 }
866
867 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
868 {
869 cpu->fpr_state[rn - FGR_BASE] = fmt_uninterpreted;
870 if (cpu->register_widths[rn] == 32)
871 {
872 if (length == 8)
873 {
874 cpu->fgr[rn - FGR_BASE] =
875 (unsigned32) T2H_8 (*(unsigned64*)memory);
876 return 8;
877 }
878 else
879 {
880 cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
881 return 4;
882 }
883 }
884 else
885 {
886 if (length == 8)
887 {
888 cpu->fgr[rn - FGR_BASE] = T2H_8 (*(unsigned64*)memory);
889 return 8;
890 }
891 else
892 {
893 cpu->fgr[rn - FGR_BASE] = T2H_4 (*(unsigned32*)memory);
894 return 4;
895 }
896 }
897 }
898
899 if (cpu->register_widths[rn] == 32)
900 {
901 if (length == 8)
902 {
903 cpu->registers[rn] =
904 (unsigned32) T2H_8 (*(unsigned64*)memory);
905 return 8;
906 }
907 else
908 {
909 cpu->registers[rn] = T2H_4 (*(unsigned32*)memory);
910 return 4;
911 }
912 }
913 else
914 {
915 if (length == 8)
916 {
917 cpu->registers[rn] = T2H_8 (*(unsigned64*)memory);
918 return 8;
919 }
920 else
921 {
922 cpu->registers[rn] = (signed32) T2H_4(*(unsigned32*)memory);
923 return 4;
924 }
925 }
926
927 return 0;
928 }
929
930 static int
931 mips_reg_fetch (SIM_CPU *cpu, int rn, unsigned char *memory, int length)
932 {
933 /* NOTE: gdb (the client) stores registers in target byte order
934 while the simulator uses host byte order */
935
936 if (cpu->register_widths[rn] == 0)
937 {
938 sim_io_eprintf (CPU_STATE (cpu), "Invalid register width for %d (register fetch ignored)\n", rn);
939 return 0;
940 }
941
942 /* Any floating point register */
943 if (rn >= FGR_BASE && rn < FGR_BASE + NR_FGR)
944 {
945 if (cpu->register_widths[rn] == 32)
946 {
947 if (length == 8)
948 {
949 *(unsigned64*)memory =
950 H2T_8 ((unsigned32) (cpu->fgr[rn - FGR_BASE]));
951 return 8;
952 }
953 else
954 {
955 *(unsigned32*)memory = H2T_4 (cpu->fgr[rn - FGR_BASE]);
956 return 4;
957 }
958 }
959 else
960 {
961 if (length == 8)
962 {
963 *(unsigned64*)memory = H2T_8 (cpu->fgr[rn - FGR_BASE]);
964 return 8;
965 }
966 else
967 {
968 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->fgr[rn - FGR_BASE]));
969 return 4;
970 }
971 }
972 }
973
974 if (cpu->register_widths[rn] == 32)
975 {
976 if (length == 8)
977 {
978 *(unsigned64*)memory =
979 H2T_8 ((unsigned32) (cpu->registers[rn]));
980 return 8;
981 }
982 else
983 {
984 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
985 return 4;
986 }
987 }
988 else
989 {
990 if (length == 8)
991 {
992 *(unsigned64*)memory =
993 H2T_8 ((unsigned64) (cpu->registers[rn]));
994 return 8;
995 }
996 else
997 {
998 *(unsigned32*)memory = H2T_4 ((unsigned32)(cpu->registers[rn]));
999 return 4;
1000 }
1001 }
1002
1003 return 0;
1004 }
1005
1006 SIM_RC
1007 sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
1008 char * const *argv, char * const *env)
1009 {
1010
1011 #ifdef DEBUG
1012 #if 0 /* FIXME: doesn't compile */
1013 printf("DBG: sim_create_inferior entered: start_address = 0x%s\n",
1014 pr_addr(PC));
1015 #endif
1016 #endif /* DEBUG */
1017
1018 ColdReset(sd);
1019
1020 if (abfd != NULL)
1021 {
1022 /* override PC value set by ColdReset () */
1023 int cpu_nr;
1024 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1025 {
1026 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1027 sim_cia pc = bfd_get_start_address (abfd);
1028
1029 /* The 64-bit BFD sign-extends MIPS addresses to model
1030 32-bit compatibility segments with 64-bit addressing.
1031 These addresses work as is on 64-bit targets but
1032 can be truncated for 32-bit targets. */
1033 if (WITH_TARGET_WORD_BITSIZE == 32)
1034 pc = (unsigned32) pc;
1035
1036 CPU_PC_SET (cpu, pc);
1037 }
1038 }
1039
1040 #if 0 /* def DEBUG */
1041 if (argv || env)
1042 {
1043 /* We should really place the argv slot values into the argument
1044 registers, and onto the stack as required. However, this
1045 assumes that we have a stack defined, which is not
1046 necessarily true at the moment. */
1047 char **cptr;
1048 sim_io_printf(sd,"sim_create_inferior() : passed arguments ignored\n");
1049 for (cptr = argv; (cptr && *cptr); cptr++)
1050 printf("DBG: arg \"%s\"\n",*cptr);
1051 }
1052 #endif /* DEBUG */
1053
1054 return SIM_RC_OK;
1055 }
1056
1057 /*---------------------------------------------------------------------------*/
1058 /*-- Private simulator support interface ------------------------------------*/
1059 /*---------------------------------------------------------------------------*/
1060
1061 /* Read a null terminated string from memory, return in a buffer */
1062 static char *
1063 fetch_str (SIM_DESC sd,
1064 address_word addr)
1065 {
1066 char *buf;
1067 int nr = 0;
1068 unsigned char null;
1069 while (sim_read (sd, addr + nr, &null, 1) == 1 && null != 0)
1070 nr++;
1071 buf = NZALLOC (char, nr + 1);
1072 sim_read (sd, addr, (unsigned char *)buf, nr);
1073 return buf;
1074 }
1075
1076
1077 /* Implements the "sim firmware" command:
1078 sim firmware NAME[@ADDRESS] --- emulate ROM monitor named NAME.
1079 NAME can be idt, pmon, or lsipmon. If omitted, ADDRESS
1080 defaults to the normal address for that monitor.
1081 sim firmware none --- don't emulate any ROM monitor. Useful
1082 if you need a clean address space. */
1083 static SIM_RC
1084 sim_firmware_command (SIM_DESC sd, char *arg)
1085 {
1086 int address_present = 0;
1087 SIM_ADDR address;
1088
1089 /* Signal occurrence of this option. */
1090 firmware_option_p = 1;
1091
1092 /* Parse out the address, if present. */
1093 {
1094 char *p = strchr (arg, '@');
1095 if (p)
1096 {
1097 char *q;
1098 address_present = 1;
1099 p ++; /* skip over @ */
1100
1101 address = strtoul (p, &q, 0);
1102 if (*q != '\0')
1103 {
1104 sim_io_printf (sd, "Invalid address given to the"
1105 "`sim firmware NAME@ADDRESS' command: %s\n",
1106 p);
1107 return SIM_RC_FAIL;
1108 }
1109 }
1110 else
1111 {
1112 address_present = 0;
1113 address = -1; /* Dummy value. */
1114 }
1115 }
1116
1117 if (! strncmp (arg, "idt", 3))
1118 {
1119 idt_monitor_base = address_present ? address : 0xBFC00000;
1120 pmon_monitor_base = 0;
1121 lsipmon_monitor_base = 0;
1122 }
1123 else if (! strncmp (arg, "pmon", 4))
1124 {
1125 /* pmon uses indirect calls. Hook into implied idt. */
1126 pmon_monitor_base = address_present ? address : 0xBFC00500;
1127 idt_monitor_base = pmon_monitor_base - 0x500;
1128 lsipmon_monitor_base = 0;
1129 }
1130 else if (! strncmp (arg, "lsipmon", 7))
1131 {
1132 /* lsipmon uses indirect calls. Hook into implied idt. */
1133 pmon_monitor_base = 0;
1134 lsipmon_monitor_base = address_present ? address : 0xBFC00200;
1135 idt_monitor_base = lsipmon_monitor_base - 0x200;
1136 }
1137 else if (! strncmp (arg, "none", 4))
1138 {
1139 if (address_present)
1140 {
1141 sim_io_printf (sd,
1142 "The `sim firmware none' command does "
1143 "not take an `ADDRESS' argument.\n");
1144 return SIM_RC_FAIL;
1145 }
1146 idt_monitor_base = 0;
1147 pmon_monitor_base = 0;
1148 lsipmon_monitor_base = 0;
1149 }
1150 else
1151 {
1152 sim_io_printf (sd, "\
1153 Unrecognized name given to the `sim firmware NAME' command: %s\n\
1154 Recognized firmware names are: `idt', `pmon', `lsipmon', and `none'.\n",
1155 arg);
1156 return SIM_RC_FAIL;
1157 }
1158
1159 return SIM_RC_OK;
1160 }
1161
1162 /* stat structures from MIPS32/64. */
1163 static const char stat32_map[] =
1164 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1165 ":st_rdev,2:st_size,4:st_atime,4:st_spare1,4:st_mtime,4:st_spare2,4"
1166 ":st_ctime,4:st_spare3,4:st_blksize,4:st_blocks,4:st_spare4,8";
1167
1168 static const char stat64_map[] =
1169 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2"
1170 ":st_rdev,2:st_size,8:st_atime,8:st_spare1,8:st_mtime,8:st_spare2,8"
1171 ":st_ctime,8:st_spare3,8:st_blksize,8:st_blocks,8:st_spare4,16";
1172
1173 /* Map for calls using the host struct stat. */
1174 static const CB_TARGET_DEFS_MAP CB_stat_map[] =
1175 {
1176 { "stat", CB_SYS_stat, 15 },
1177 { 0, -1, -1 }
1178 };
1179
1180
1181 /* Simple monitor interface (currently setup for the IDT and PMON monitors) */
1182 int
1183 sim_monitor (SIM_DESC sd,
1184 sim_cpu *cpu,
1185 address_word cia,
1186 unsigned int reason)
1187 {
1188 #ifdef DEBUG
1189 printf("DBG: sim_monitor: entered (reason = %d)\n",reason);
1190 #endif /* DEBUG */
1191
1192 /* The IDT monitor actually allows two instructions per vector
1193 slot. However, the simulator currently causes a trap on each
1194 individual instruction. We cheat, and lose the bottom bit. */
1195 reason >>= 1;
1196
1197 /* The following callback functions are available, however the
1198 monitor we are simulating does not make use of them: get_errno,
1199 isatty, rename, system and time. */
1200 switch (reason)
1201 {
1202
1203 case 6: /* int open(char *path,int flags) */
1204 {
1205 char *path = fetch_str (sd, A0);
1206 V0 = sim_io_open (sd, path, (int)A1);
1207 free (path);
1208 break;
1209 }
1210
1211 case 7: /* int read(int file,char *ptr,int len) */
1212 {
1213 int fd = A0;
1214 int nr = A2;
1215 char *buf = zalloc (nr);
1216 V0 = sim_io_read (sd, fd, buf, nr);
1217 sim_write (sd, A1, (unsigned char *)buf, nr);
1218 free (buf);
1219 }
1220 break;
1221
1222 case 8: /* int write(int file,char *ptr,int len) */
1223 {
1224 int fd = A0;
1225 int nr = A2;
1226 char *buf = zalloc (nr);
1227 sim_read (sd, A1, (unsigned char *)buf, nr);
1228 V0 = sim_io_write (sd, fd, buf, nr);
1229 if (fd == 1)
1230 sim_io_flush_stdout (sd);
1231 else if (fd == 2)
1232 sim_io_flush_stderr (sd);
1233 free (buf);
1234 break;
1235 }
1236
1237 case 10: /* int close(int file) */
1238 {
1239 V0 = sim_io_close (sd, (int)A0);
1240 break;
1241 }
1242
1243 case 2: /* Densan monitor: char inbyte(int waitflag) */
1244 {
1245 if (A0 == 0) /* waitflag == NOWAIT */
1246 V0 = (unsigned_word)-1;
1247 }
1248 /* Drop through to case 11 */
1249
1250 case 11: /* char inbyte(void) */
1251 {
1252 char tmp;
1253 /* ensure that all output has gone... */
1254 sim_io_flush_stdout (sd);
1255 if (sim_io_read_stdin (sd, &tmp, sizeof(char)) != sizeof(char))
1256 {
1257 sim_io_error(sd,"Invalid return from character read");
1258 V0 = (unsigned_word)-1;
1259 }
1260 else
1261 V0 = (unsigned_word)tmp;
1262 break;
1263 }
1264
1265 case 3: /* Densan monitor: void co(char chr) */
1266 case 12: /* void outbyte(char chr) : write a byte to "stdout" */
1267 {
1268 char tmp = (char)(A0 & 0xFF);
1269 sim_io_write_stdout (sd, &tmp, sizeof(char));
1270 break;
1271 }
1272
1273 case 13: /* int unlink(const char *path) */
1274 {
1275 char *path = fetch_str (sd, A0);
1276 V0 = sim_io_unlink (sd, path);
1277 free (path);
1278 break;
1279 }
1280
1281 case 14: /* int lseek(int fd, int offset, int whence) */
1282 {
1283 V0 = sim_io_lseek (sd, A0, A1, A2);
1284 break;
1285 }
1286
1287 case 15: /* int stat(const char *path, struct stat *buf); */
1288 {
1289 /* As long as the infrastructure doesn't cache anything
1290 related to the stat mapping, this trick gets us a dual
1291 "struct stat"-type mapping in the least error-prone way. */
1292 host_callback *cb = STATE_CALLBACK (sd);
1293 const char *saved_map = cb->stat_map;
1294 CB_TARGET_DEFS_MAP *saved_syscall_map = cb->syscall_map;
1295 bfd *prog_bfd = STATE_PROG_BFD (sd);
1296 int is_elf32bit = (elf_elfheader(prog_bfd)->e_ident[EI_CLASS] ==
1297 ELFCLASS32);
1298 static CB_SYSCALL s;
1299 CB_SYSCALL_INIT (&s);
1300 s.func = 15;
1301 /* Mask out the sign extension part for 64-bit targets because the
1302 MIPS simulator's memory model is still 32-bit. */
1303 s.arg1 = A0 & 0xFFFFFFFF;
1304 s.arg2 = A1 & 0xFFFFFFFF;
1305 s.p1 = (PTR) sd;
1306 s.p2 = (PTR) cpu;
1307 s.read_mem = sim_syscall_read_mem;
1308 s.write_mem = sim_syscall_write_mem;
1309
1310 cb->syscall_map = (CB_TARGET_DEFS_MAP *) CB_stat_map;
1311 cb->stat_map = is_elf32bit ? stat32_map : stat64_map;
1312
1313 if (cb_syscall (cb, &s) != CB_RC_OK)
1314 sim_engine_halt (sd, cpu, NULL, mips_pc_get (cpu),
1315 sim_stopped, SIM_SIGILL);
1316
1317 V0 = s.result;
1318 cb->stat_map = saved_map;
1319 cb->syscall_map = saved_syscall_map;
1320 break;
1321 }
1322
1323 case 17: /* void _exit() */
1324 {
1325 sim_io_eprintf (sd, "sim_monitor(17): _exit(int reason) to be coded\n");
1326 sim_engine_halt (SD, CPU, NULL, NULL_CIA, sim_exited,
1327 (unsigned int)(A0 & 0xFFFFFFFF));
1328 break;
1329 }
1330
1331 case 28: /* PMON flush_cache */
1332 break;
1333
1334 case 55: /* void get_mem_info(unsigned int *ptr) */
1335 /* in: A0 = pointer to three word memory location */
1336 /* out: [A0 + 0] = size */
1337 /* [A0 + 4] = instruction cache size */
1338 /* [A0 + 8] = data cache size */
1339 {
1340 unsigned_4 value;
1341 unsigned_4 zero = 0;
1342 address_word mem_size;
1343 sim_memopt *entry, *match = NULL;
1344
1345 /* Search for memory region mapped to KSEG0 or KSEG1. */
1346 for (entry = STATE_MEMOPT (sd);
1347 entry != NULL;
1348 entry = entry->next)
1349 {
1350 if ((entry->addr == K0BASE || entry->addr == K1BASE)
1351 && (!match || entry->level < match->level))
1352 match = entry;
1353 else
1354 {
1355 sim_memopt *alias;
1356 for (alias = entry->alias;
1357 alias != NULL;
1358 alias = alias->next)
1359 if ((alias->addr == K0BASE || alias->addr == K1BASE)
1360 && (!match || entry->level < match->level))
1361 match = entry;
1362 }
1363 }
1364
1365 /* Get region size, limit to KSEG1 size (512MB). */
1366 SIM_ASSERT (match != NULL);
1367 mem_size = (match->modulo != 0
1368 ? match->modulo : match->nr_bytes);
1369 if (mem_size > K1SIZE)
1370 mem_size = K1SIZE;
1371
1372 value = mem_size;
1373 H2T (value);
1374 sim_write (sd, A0 + 0, (unsigned char *)&value, 4);
1375 sim_write (sd, A0 + 4, (unsigned char *)&zero, 4);
1376 sim_write (sd, A0 + 8, (unsigned char *)&zero, 4);
1377 /* sim_io_eprintf (sd, "sim: get_mem_info() deprecated\n"); */
1378 break;
1379 }
1380
1381 case 158: /* PMON printf */
1382 /* in: A0 = pointer to format string */
1383 /* A1 = optional argument 1 */
1384 /* A2 = optional argument 2 */
1385 /* A3 = optional argument 3 */
1386 /* out: void */
1387 /* The following is based on the PMON printf source */
1388 {
1389 address_word s = A0;
1390 unsigned char c;
1391 address_word *ap = &A1; /* 1st argument */
1392 /* This isn't the quickest way, since we call the host print
1393 routine for every character almost. But it does avoid
1394 having to allocate and manage a temporary string buffer. */
1395 /* TODO: Include check that we only use three arguments (A1,
1396 A2 and A3) */
1397 while (sim_read (sd, s++, &c, 1) && c != '\0')
1398 {
1399 if (c == '%')
1400 {
1401 char tmp[40];
1402 enum {FMT_RJUST, FMT_LJUST, FMT_RJUST0, FMT_CENTER} fmt = FMT_RJUST;
1403 int width = 0, trunc = 0, haddot = 0, longlong = 0;
1404 while (sim_read (sd, s++, &c, 1) && c != '\0')
1405 {
1406 if (strchr ("dobxXulscefg%", c))
1407 break;
1408 else if (c == '-')
1409 fmt = FMT_LJUST;
1410 else if (c == '0')
1411 fmt = FMT_RJUST0;
1412 else if (c == '~')
1413 fmt = FMT_CENTER;
1414 else if (c == '*')
1415 {
1416 if (haddot)
1417 trunc = (int)*ap++;
1418 else
1419 width = (int)*ap++;
1420 }
1421 else if (c >= '1' && c <= '9')
1422 {
1423 address_word t = s;
1424 unsigned int n;
1425 while (sim_read (sd, s++, &c, 1) == 1 && isdigit (c))
1426 tmp[s - t] = c;
1427 tmp[s - t] = '\0';
1428 n = (unsigned int)strtol(tmp,NULL,10);
1429 if (haddot)
1430 trunc = n;
1431 else
1432 width = n;
1433 s--;
1434 }
1435 else if (c == '.')
1436 haddot = 1;
1437 }
1438 switch (c)
1439 {
1440 case '%':
1441 sim_io_printf (sd, "%%");
1442 break;
1443 case 's':
1444 if ((int)*ap != 0)
1445 {
1446 address_word p = *ap++;
1447 unsigned char ch;
1448 while (sim_read (sd, p++, &ch, 1) == 1 && ch != '\0')
1449 sim_io_printf(sd, "%c", ch);
1450 }
1451 else
1452 sim_io_printf(sd,"(null)");
1453 break;
1454 case 'c':
1455 sim_io_printf (sd, "%c", (int)*ap++);
1456 break;
1457 default:
1458 if (c == 'l')
1459 {
1460 sim_read (sd, s++, &c, 1);
1461 if (c == 'l')
1462 {
1463 longlong = 1;
1464 sim_read (sd, s++, &c, 1);
1465 }
1466 }
1467 if (strchr ("dobxXu", c))
1468 {
1469 word64 lv = (word64) *ap++;
1470 if (c == 'b')
1471 sim_io_printf(sd,"<binary not supported>");
1472 else
1473 {
1474 #define _P(c, fmt64, fmt32) \
1475 case c: \
1476 if (longlong) \
1477 sim_io_printf (sd, "%" fmt64, lv); \
1478 else \
1479 sim_io_printf (sd, "%" fmt32, (int)lv); \
1480 break;
1481 #define P(c, fmtc) _P(c, PRI##fmtc##64, PRI##fmtc##32)
1482 switch (c)
1483 {
1484 P('d', d)
1485 P('o', o)
1486 P('x', x)
1487 P('X', X)
1488 P('u', u)
1489 }
1490 }
1491 #undef P
1492 #undef _P
1493 }
1494 else if (strchr ("eEfgG", c))
1495 {
1496 double dbl = *(double*)(ap++);
1497
1498 #define P(c, fmtc) \
1499 case c: \
1500 sim_io_printf (sd, "%*.*" #fmtc, width, trunc, dbl); \
1501 break;
1502 switch (c)
1503 {
1504 P('e', e)
1505 P('E', E)
1506 P('f', f)
1507 P('g', g)
1508 P('G', G)
1509 }
1510 #undef P
1511 trunc = 0;
1512 }
1513 }
1514 }
1515 else
1516 sim_io_printf(sd, "%c", c);
1517 }
1518 break;
1519 }
1520
1521 default:
1522 /* Unknown reason. */
1523 return 0;
1524 }
1525 return 1;
1526 }
1527
1528 /* Store a word into memory. */
1529
1530 static void
1531 store_word (SIM_DESC sd,
1532 sim_cpu *cpu,
1533 address_word cia,
1534 uword64 vaddr,
1535 signed_word val)
1536 {
1537 address_word paddr = vaddr;
1538
1539 if ((vaddr & 3) != 0)
1540 SignalExceptionAddressStore ();
1541 else
1542 {
1543 const uword64 mask = 7;
1544 uword64 memval;
1545 unsigned int byte;
1546
1547 paddr = (paddr & ~mask) | ((paddr & mask) ^ (ReverseEndian << 2));
1548 byte = (vaddr & mask) ^ (BigEndianCPU << 2);
1549 memval = ((uword64) val) << (8 * byte);
1550 StoreMemory (AccessLength_WORD, memval, 0, paddr, vaddr,
1551 isREAL);
1552 }
1553 }
1554
1555 /* Load a word from memory. */
1556
1557 static signed_word
1558 load_word (SIM_DESC sd,
1559 sim_cpu *cpu,
1560 address_word cia,
1561 uword64 vaddr)
1562 {
1563 if ((vaddr & 3) != 0)
1564 {
1565 SIM_CORE_SIGNAL (SD, cpu, cia, read_map, AccessLength_WORD+1, vaddr, read_transfer, sim_core_unaligned_signal);
1566 }
1567 else
1568 {
1569 address_word paddr = vaddr;
1570 const uword64 mask = 0x7;
1571 const unsigned int reverse = ReverseEndian ? 1 : 0;
1572 const unsigned int bigend = BigEndianCPU ? 1 : 0;
1573 uword64 memval;
1574 unsigned int byte;
1575
1576 paddr = (paddr & ~mask) | ((paddr & mask) ^ (reverse << 2));
1577 LoadMemory (&memval, NULL, AccessLength_WORD, paddr, vaddr, isDATA,
1578 isREAL);
1579 byte = (vaddr & mask) ^ (bigend << 2);
1580 return EXTEND32 (memval >> (8 * byte));
1581 }
1582
1583 return 0;
1584 }
1585
1586 /* Simulate the mips16 entry and exit pseudo-instructions. These
1587 would normally be handled by the reserved instruction exception
1588 code, but for ease of simulation we just handle them directly. */
1589
1590 static void
1591 mips16_entry (SIM_DESC sd,
1592 sim_cpu *cpu,
1593 address_word cia,
1594 unsigned int insn)
1595 {
1596 int aregs, sregs, rreg;
1597
1598 #ifdef DEBUG
1599 printf("DBG: mips16_entry: entered (insn = 0x%08X)\n",insn);
1600 #endif /* DEBUG */
1601
1602 aregs = (insn & 0x700) >> 8;
1603 sregs = (insn & 0x0c0) >> 6;
1604 rreg = (insn & 0x020) >> 5;
1605
1606 /* This should be checked by the caller. */
1607 if (sregs == 3)
1608 abort ();
1609
1610 if (aregs < 5)
1611 {
1612 int i;
1613 signed_word tsp;
1614
1615 /* This is the entry pseudo-instruction. */
1616
1617 for (i = 0; i < aregs; i++)
1618 store_word (SD, CPU, cia, (uword64) (SP + 4 * i), GPR[i + 4]);
1619
1620 tsp = SP;
1621 SP -= 32;
1622
1623 if (rreg)
1624 {
1625 tsp -= 4;
1626 store_word (SD, CPU, cia, (uword64) tsp, RA);
1627 }
1628
1629 for (i = 0; i < sregs; i++)
1630 {
1631 tsp -= 4;
1632 store_word (SD, CPU, cia, (uword64) tsp, GPR[16 + i]);
1633 }
1634 }
1635 else
1636 {
1637 int i;
1638 signed_word tsp;
1639
1640 /* This is the exit pseudo-instruction. */
1641
1642 tsp = SP + 32;
1643
1644 if (rreg)
1645 {
1646 tsp -= 4;
1647 RA = load_word (SD, CPU, cia, (uword64) tsp);
1648 }
1649
1650 for (i = 0; i < sregs; i++)
1651 {
1652 tsp -= 4;
1653 GPR[i + 16] = load_word (SD, CPU, cia, (uword64) tsp);
1654 }
1655
1656 SP += 32;
1657
1658 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1659 {
1660 if (aregs == 5)
1661 {
1662 FGR[0] = WORD64LO (GPR[4]);
1663 FPR_STATE[0] = fmt_uninterpreted;
1664 }
1665 else if (aregs == 6)
1666 {
1667 FGR[0] = WORD64LO (GPR[5]);
1668 FGR[1] = WORD64LO (GPR[4]);
1669 FPR_STATE[0] = fmt_uninterpreted;
1670 FPR_STATE[1] = fmt_uninterpreted;
1671 }
1672 }
1673
1674 PC = RA;
1675 }
1676
1677 }
1678
1679 /*-- trace support ----------------------------------------------------------*/
1680
1681 /* The trace support is provided (if required) in the memory accessing
1682 routines. Since we are also providing the architecture specific
1683 features, the architecture simulation code can also deal with
1684 notifying the trace world of cache flushes, etc. Similarly we do
1685 not need to provide profiling support in the simulator engine,
1686 since we can sample in the instruction fetch control loop. By
1687 defining the trace manifest, we add tracing as a run-time
1688 option. */
1689
1690 #if WITH_TRACE_ANY_P
1691 /* Tracing by default produces "din" format (as required by
1692 dineroIII). Each line of such a trace file *MUST* have a din label
1693 and address field. The rest of the line is ignored, so comments can
1694 be included if desired. The first field is the label which must be
1695 one of the following values:
1696
1697 0 read data
1698 1 write data
1699 2 instruction fetch
1700 3 escape record (treated as unknown access type)
1701 4 escape record (causes cache flush)
1702
1703 The address field is a 32bit (lower-case) hexadecimal address
1704 value. The address should *NOT* be preceded by "0x".
1705
1706 The size of the memory transfer is not important when dealing with
1707 cache lines (as long as no more than a cache line can be
1708 transferred in a single operation :-), however more information
1709 could be given following the dineroIII requirement to allow more
1710 complete memory and cache simulators to provide better
1711 results. i.e. the University of Pisa has a cache simulator that can
1712 also take bus size and speed as (variable) inputs to calculate
1713 complete system performance (a much more useful ability when trying
1714 to construct an end product, rather than a processor). They
1715 currently have an ARM version of their tool called ChARM. */
1716
1717
1718 void
1719 dotrace (SIM_DESC sd,
1720 sim_cpu *cpu,
1721 FILE *tracefh,
1722 int type,
1723 SIM_ADDR address,
1724 int width,
1725 const char *comment, ...)
1726 {
1727 if (STATE & simTRACE) {
1728 va_list ap;
1729 fprintf(tracefh,"%d %s ; width %d ; ",
1730 type,
1731 pr_addr(address),
1732 width);
1733 va_start(ap,comment);
1734 vfprintf(tracefh,comment,ap);
1735 va_end(ap);
1736 fprintf(tracefh,"\n");
1737 }
1738 /* NOTE: Since the "din" format will only accept 32bit addresses, and
1739 we may be generating 64bit ones, we should put the hi-32bits of the
1740 address into the comment field. */
1741
1742 /* TODO: Provide a buffer for the trace lines. We can then avoid
1743 performing writes until the buffer is filled, or the file is
1744 being closed. */
1745
1746 /* NOTE: We could consider adding a comment field to the "din" file
1747 produced using type 3 markers (unknown access). This would then
1748 allow information about the program that the "din" is for, and
1749 the MIPs world that was being simulated, to be placed into the
1750 trace file. */
1751
1752 return;
1753 }
1754 #endif /* WITH_TRACE_ANY_P */
1755
1756 /*---------------------------------------------------------------------------*/
1757 /*-- simulator engine -------------------------------------------------------*/
1758 /*---------------------------------------------------------------------------*/
1759
1760 static void
1761 ColdReset (SIM_DESC sd)
1762 {
1763 int cpu_nr;
1764 for (cpu_nr = 0; cpu_nr < sim_engine_nr_cpus (sd); cpu_nr++)
1765 {
1766 sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
1767 /* RESET: Fixed PC address: */
1768 PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
1769 /* The reset vector address is in the unmapped, uncached memory space. */
1770
1771 SR &= ~(status_SR | status_TS | status_RP);
1772 SR |= (status_ERL | status_BEV);
1773
1774 /* Cheat and allow access to the complete register set immediately */
1775 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT
1776 && WITH_TARGET_WORD_BITSIZE == 64)
1777 SR |= status_FR; /* 64bit registers */
1778
1779 /* Ensure that any instructions with pending register updates are
1780 cleared: */
1781 PENDING_INVALIDATE();
1782
1783 /* Initialise the FPU registers to the unknown state */
1784 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
1785 {
1786 int rn;
1787 for (rn = 0; (rn < 32); rn++)
1788 FPR_STATE[rn] = fmt_uninterpreted;
1789 }
1790
1791 /* Initialise the Config0 register. */
1792 C0_CONFIG = 0x80000000 /* Config1 present */
1793 | 2; /* KSEG0 uncached */
1794 if (WITH_TARGET_WORD_BITSIZE == 64)
1795 {
1796 /* FIXME Currently mips/sim-main.c:address_translation()
1797 truncates all addresses to 32-bits. */
1798 if (0 && WITH_TARGET_ADDRESS_BITSIZE == 64)
1799 C0_CONFIG |= (2 << 13); /* MIPS64, 64-bit addresses */
1800 else
1801 C0_CONFIG |= (1 << 13); /* MIPS64, 32-bit addresses */
1802 }
1803 if (BigEndianMem)
1804 C0_CONFIG |= 0x00008000; /* Big Endian */
1805 }
1806 }
1807
1808
1809
1810
1811 /* Description from page A-26 of the "MIPS IV Instruction Set" manual (revision 3.1) */
1812 /* Signal an exception condition. This will result in an exception
1813 that aborts the instruction. The instruction operation pseudocode
1814 will never see a return from this function call. */
1815
1816 void
1817 signal_exception (SIM_DESC sd,
1818 sim_cpu *cpu,
1819 address_word cia,
1820 int exception,...)
1821 {
1822 /* int vector; */
1823
1824 #ifdef DEBUG
1825 sim_io_printf(sd,"DBG: SignalException(%d) PC = 0x%s\n",exception,pr_addr(cia));
1826 #endif /* DEBUG */
1827
1828 /* Ensure that any active atomic read/modify/write operation will fail: */
1829 LLBIT = 0;
1830
1831 /* Save registers before interrupt dispatching */
1832 #ifdef SIM_CPU_EXCEPTION_TRIGGER
1833 SIM_CPU_EXCEPTION_TRIGGER(sd, cpu, cia);
1834 #endif
1835
1836 switch (exception) {
1837
1838 case DebugBreakPoint:
1839 if (! (Debug & Debug_DM))
1840 {
1841 if (INDELAYSLOT())
1842 {
1843 CANCELDELAYSLOT();
1844
1845 Debug |= Debug_DBD; /* signaled from within in delay slot */
1846 DEPC = cia - 4; /* reference the branch instruction */
1847 }
1848 else
1849 {
1850 Debug &= ~Debug_DBD; /* not signaled from within a delay slot */
1851 DEPC = cia;
1852 }
1853
1854 Debug |= Debug_DM; /* in debugging mode */
1855 Debug |= Debug_DBp; /* raising a DBp exception */
1856 PC = 0xBFC00200;
1857 sim_engine_restart (SD, CPU, NULL, NULL_CIA);
1858 }
1859 break;
1860
1861 case ReservedInstruction:
1862 {
1863 va_list ap;
1864 unsigned int instruction;
1865 va_start(ap,exception);
1866 instruction = va_arg(ap,unsigned int);
1867 va_end(ap);
1868 /* Provide simple monitor support using ReservedInstruction
1869 exceptions. The following code simulates the fixed vector
1870 entry points into the IDT monitor by causing a simulator
1871 trap, performing the monitor operation, and returning to
1872 the address held in the $ra register (standard PCS return
1873 address). This means we only need to pre-load the vector
1874 space with suitable instruction values. For systems were
1875 actual trap instructions are used, we would not need to
1876 perform this magic. */
1877 if ((instruction & RSVD_INSTRUCTION_MASK) == RSVD_INSTRUCTION)
1878 {
1879 int reason = (instruction >> RSVD_INSTRUCTION_ARG_SHIFT) & RSVD_INSTRUCTION_ARG_MASK;
1880 if (!sim_monitor (SD, CPU, cia, reason))
1881 sim_io_error (sd, "sim_monitor: unhandled reason = %d, pc = 0x%s\n", reason, pr_addr (cia));
1882
1883 /* NOTE: This assumes that a branch-and-link style
1884 instruction was used to enter the vector (which is the
1885 case with the current IDT monitor). */
1886 sim_engine_restart (SD, CPU, NULL, RA);
1887 }
1888 /* Look for the mips16 entry and exit instructions, and
1889 simulate a handler for them. */
1890 else if ((cia & 1) != 0
1891 && (instruction & 0xf81f) == 0xe809
1892 && (instruction & 0x0c0) != 0x0c0)
1893 {
1894 mips16_entry (SD, CPU, cia, instruction);
1895 sim_engine_restart (sd, NULL, NULL, NULL_CIA);
1896 }
1897 /* else fall through to normal exception processing */
1898 sim_io_eprintf(sd,"ReservedInstruction at PC = 0x%s\n", pr_addr (cia));
1899 }
1900
1901 default:
1902 /* Store exception code into current exception id variable (used
1903 by exit code): */
1904
1905 /* TODO: If not simulating exceptions then stop the simulator
1906 execution. At the moment we always stop the simulation. */
1907
1908 #ifdef SUBTARGET_R3900
1909 /* update interrupt-related registers */
1910
1911 /* insert exception code in bits 6:2 */
1912 CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
1913 /* shift IE/KU history bits left */
1914 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
1915
1916 if (STATE & simDELAYSLOT)
1917 {
1918 STATE &= ~simDELAYSLOT;
1919 CAUSE |= cause_BD;
1920 EPC = (cia - 4); /* reference the branch instruction */
1921 }
1922 else
1923 EPC = cia;
1924
1925 if (SR & status_BEV)
1926 PC = (signed)0xBFC00000 + 0x180;
1927 else
1928 PC = (signed)0x80000000 + 0x080;
1929 #else
1930 /* See figure 5-17 for an outline of the code below */
1931 if (! (SR & status_EXL))
1932 {
1933 CAUSE = (exception << 2);
1934 if (STATE & simDELAYSLOT)
1935 {
1936 STATE &= ~simDELAYSLOT;
1937 CAUSE |= cause_BD;
1938 EPC = (cia - 4); /* reference the branch instruction */
1939 }
1940 else
1941 EPC = cia;
1942 /* FIXME: TLB et.al. */
1943 /* vector = 0x180; */
1944 }
1945 else
1946 {
1947 CAUSE = (exception << 2);
1948 /* vector = 0x180; */
1949 }
1950 SR |= status_EXL;
1951 /* Store exception code into current exception id variable (used
1952 by exit code): */
1953
1954 if (SR & status_BEV)
1955 PC = (signed)0xBFC00200 + 0x180;
1956 else
1957 PC = (signed)0x80000000 + 0x180;
1958 #endif
1959
1960 switch ((CAUSE >> 2) & 0x1F)
1961 {
1962 case Interrupt:
1963 /* Interrupts arrive during event processing, no need to
1964 restart */
1965 return;
1966
1967 case NMIReset:
1968 /* Ditto */
1969 #ifdef SUBTARGET_3900
1970 /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
1971 PC = (signed)0xBFC00000;
1972 #endif /* SUBTARGET_3900 */
1973 return;
1974
1975 case TLBModification:
1976 case TLBLoad:
1977 case TLBStore:
1978 case AddressLoad:
1979 case AddressStore:
1980 case InstructionFetch:
1981 case DataReference:
1982 /* The following is so that the simulator will continue from the
1983 exception handler address. */
1984 sim_engine_halt (SD, CPU, NULL, PC,
1985 sim_stopped, SIM_SIGBUS);
1986
1987 case ReservedInstruction:
1988 case CoProcessorUnusable:
1989 PC = EPC;
1990 sim_engine_halt (SD, CPU, NULL, PC,
1991 sim_stopped, SIM_SIGILL);
1992
1993 case IntegerOverflow:
1994 case FPE:
1995 sim_engine_halt (SD, CPU, NULL, PC,
1996 sim_stopped, SIM_SIGFPE);
1997
1998 case BreakPoint:
1999 sim_engine_halt (SD, CPU, NULL, PC, sim_stopped, SIM_SIGTRAP);
2000 break;
2001
2002 case SystemCall:
2003 case Trap:
2004 sim_engine_restart (SD, CPU, NULL, PC);
2005 break;
2006
2007 case Watch:
2008 PC = EPC;
2009 sim_engine_halt (SD, CPU, NULL, PC,
2010 sim_stopped, SIM_SIGTRAP);
2011
2012 default: /* Unknown internal exception */
2013 PC = EPC;
2014 sim_engine_halt (SD, CPU, NULL, PC,
2015 sim_stopped, SIM_SIGABRT);
2016
2017 }
2018
2019 case SimulatorFault:
2020 {
2021 va_list ap;
2022 char *msg;
2023 va_start(ap,exception);
2024 msg = va_arg(ap,char *);
2025 va_end(ap);
2026 sim_engine_abort (SD, CPU, NULL_CIA,
2027 "FATAL: Simulator error \"%s\"\n",msg);
2028 }
2029 }
2030
2031 return;
2032 }
2033
2034
2035
2036 /* This function implements what the MIPS32 and MIPS64 ISAs define as
2037 "UNPREDICTABLE" behaviour.
2038
2039 About UNPREDICTABLE behaviour they say: "UNPREDICTABLE results
2040 may vary from processor implementation to processor implementation,
2041 instruction to instruction, or as a function of time on the same
2042 implementation or instruction. Software can never depend on results
2043 that are UNPREDICTABLE. ..." (MIPS64 Architecture for Programmers
2044 Volume II, The MIPS64 Instruction Set. MIPS Document MD00087 revision
2045 0.95, page 2.)
2046
2047 For UNPREDICTABLE behaviour, we print a message, if possible print
2048 the offending instructions mips.igen instruction name (provided by
2049 the caller), and stop the simulator.
2050
2051 XXX FIXME: eventually, stopping the simulator should be made conditional
2052 on a command-line option. */
2053 void
2054 unpredictable_action(sim_cpu *cpu, address_word cia)
2055 {
2056 SIM_DESC sd = CPU_STATE(cpu);
2057
2058 sim_io_eprintf(sd, "UNPREDICTABLE: PC = 0x%s\n", pr_addr (cia));
2059 sim_engine_halt (SD, CPU, NULL, cia, sim_stopped, SIM_SIGABRT);
2060 }
2061
2062
2063 /*-- co-processor support routines ------------------------------------------*/
2064
2065 static int UNUSED
2066 CoProcPresent(unsigned int coproc_number)
2067 {
2068 /* Return TRUE if simulator provides a model for the given co-processor number */
2069 return(0);
2070 }
2071
2072 void
2073 cop_lw (SIM_DESC sd,
2074 sim_cpu *cpu,
2075 address_word cia,
2076 int coproc_num,
2077 int coproc_reg,
2078 unsigned int memword)
2079 {
2080 switch (coproc_num)
2081 {
2082 case 1:
2083 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2084 {
2085 #ifdef DEBUG
2086 printf("DBG: COP_LW: memword = 0x%08X (uword64)memword = 0x%s\n",memword,pr_addr(memword));
2087 #endif
2088 StoreFPR(coproc_reg,fmt_uninterpreted_32,(uword64)memword);
2089 break;
2090 }
2091
2092 default:
2093 #if 0 /* this should be controlled by a configuration option */
2094 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));
2095 #endif
2096 break;
2097 }
2098
2099 return;
2100 }
2101
2102 void
2103 cop_ld (SIM_DESC sd,
2104 sim_cpu *cpu,
2105 address_word cia,
2106 int coproc_num,
2107 int coproc_reg,
2108 uword64 memword)
2109 {
2110
2111 #ifdef DEBUG
2112 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) );
2113 #endif
2114
2115 switch (coproc_num) {
2116 case 1:
2117 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2118 {
2119 StoreFPR(coproc_reg,fmt_uninterpreted_64,memword);
2120 break;
2121 }
2122
2123 default:
2124 #if 0 /* this message should be controlled by a configuration option */
2125 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));
2126 #endif
2127 break;
2128 }
2129
2130 return;
2131 }
2132
2133
2134
2135
2136 unsigned int
2137 cop_sw (SIM_DESC sd,
2138 sim_cpu *cpu,
2139 address_word cia,
2140 int coproc_num,
2141 int coproc_reg)
2142 {
2143 unsigned int value = 0;
2144
2145 switch (coproc_num)
2146 {
2147 case 1:
2148 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2149 {
2150 value = (unsigned int)ValueFPR(coproc_reg,fmt_uninterpreted_32);
2151 break;
2152 }
2153
2154 default:
2155 #if 0 /* should be controlled by configuration option */
2156 sim_io_printf(sd,"COP_SW(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2157 #endif
2158 break;
2159 }
2160
2161 return(value);
2162 }
2163
2164 uword64
2165 cop_sd (SIM_DESC sd,
2166 sim_cpu *cpu,
2167 address_word cia,
2168 int coproc_num,
2169 int coproc_reg)
2170 {
2171 uword64 value = 0;
2172 switch (coproc_num)
2173 {
2174 case 1:
2175 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2176 {
2177 value = ValueFPR(coproc_reg,fmt_uninterpreted_64);
2178 break;
2179 }
2180
2181 default:
2182 #if 0 /* should be controlled by configuration option */
2183 sim_io_printf(sd,"COP_SD(%d,%d) at PC = 0x%s : TODO (architecture specific)\n",coproc_num,coproc_reg,pr_addr(cia));
2184 #endif
2185 break;
2186 }
2187
2188 return(value);
2189 }
2190
2191
2192
2193
2194 void
2195 decode_coproc (SIM_DESC sd,
2196 sim_cpu *cpu,
2197 address_word cia,
2198 unsigned int instruction,
2199 int coprocnum,
2200 CP0_operation op,
2201 int rt,
2202 int rd,
2203 int sel)
2204 {
2205 switch (coprocnum)
2206 {
2207 case 0: /* standard CPU control and cache registers */
2208 {
2209 /* R4000 Users Manual (second edition) lists the following CP0
2210 instructions:
2211 CODE><-RT><RD-><--TAIL--->
2212 DMFC0 Doubleword Move From CP0 (VR4100 = 01000000001tttttddddd00000000000)
2213 DMTC0 Doubleword Move To CP0 (VR4100 = 01000000101tttttddddd00000000000)
2214 MFC0 word Move From CP0 (VR4100 = 01000000000tttttddddd00000000000)
2215 MTC0 word Move To CP0 (VR4100 = 01000000100tttttddddd00000000000)
2216 TLBR Read Indexed TLB Entry (VR4100 = 01000010000000000000000000000001)
2217 TLBWI Write Indexed TLB Entry (VR4100 = 01000010000000000000000000000010)
2218 TLBWR Write Random TLB Entry (VR4100 = 01000010000000000000000000000110)
2219 TLBP Probe TLB for Matching Entry (VR4100 = 01000010000000000000000000001000)
2220 CACHE Cache operation (VR4100 = 101111bbbbbpppppiiiiiiiiiiiiiiii)
2221 ERET Exception return (VR4100 = 01000010000000000000000000011000)
2222 */
2223 if (((op == cp0_mfc0) || (op == cp0_mtc0) /* MFC0 / MTC0 */
2224 || (op == cp0_dmfc0) || (op == cp0_dmtc0)) /* DMFC0 / DMTC0 */
2225 && sel == 0)
2226 {
2227 switch (rd) /* NOTEs: Standard CP0 registers */
2228 {
2229 /* 0 = Index R4000 VR4100 VR4300 */
2230 /* 1 = Random R4000 VR4100 VR4300 */
2231 /* 2 = EntryLo0 R4000 VR4100 VR4300 */
2232 /* 3 = EntryLo1 R4000 VR4100 VR4300 */
2233 /* 4 = Context R4000 VR4100 VR4300 */
2234 /* 5 = PageMask R4000 VR4100 VR4300 */
2235 /* 6 = Wired R4000 VR4100 VR4300 */
2236 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2237 /* 9 = Count R4000 VR4100 VR4300 */
2238 /* 10 = EntryHi R4000 VR4100 VR4300 */
2239 /* 11 = Compare R4000 VR4100 VR4300 */
2240 /* 12 = SR R4000 VR4100 VR4300 */
2241 #ifdef SUBTARGET_R3900
2242 case 3:
2243 /* 3 = Config R3900 */
2244 case 7:
2245 /* 7 = Cache R3900 */
2246 case 15:
2247 /* 15 = PRID R3900 */
2248
2249 /* ignore */
2250 break;
2251
2252 case 8:
2253 /* 8 = BadVAddr R4000 VR4100 VR4300 */
2254 if (op == cp0_mfc0 || op == cp0_dmfc0)
2255 GPR[rt] = (signed_word) (signed_address) COP0_BADVADDR;
2256 else
2257 COP0_BADVADDR = GPR[rt];
2258 break;
2259
2260 #endif /* SUBTARGET_R3900 */
2261 case 12:
2262 if (op == cp0_mfc0 || op == cp0_dmfc0)
2263 GPR[rt] = SR;
2264 else
2265 SR = GPR[rt];
2266 break;
2267 /* 13 = Cause R4000 VR4100 VR4300 */
2268 case 13:
2269 if (op == cp0_mfc0 || op == cp0_dmfc0)
2270 GPR[rt] = CAUSE;
2271 else
2272 CAUSE = GPR[rt];
2273 break;
2274 /* 14 = EPC R4000 VR4100 VR4300 */
2275 case 14:
2276 if (op == cp0_mfc0 || op == cp0_dmfc0)
2277 GPR[rt] = (signed_word) (signed_address) EPC;
2278 else
2279 EPC = GPR[rt];
2280 break;
2281 /* 15 = PRId R4000 VR4100 VR4300 */
2282 #ifdef SUBTARGET_R3900
2283 /* 16 = Debug */
2284 case 16:
2285 if (op == cp0_mfc0 || op == cp0_dmfc0)
2286 GPR[rt] = Debug;
2287 else
2288 Debug = GPR[rt];
2289 break;
2290 #else
2291 /* 16 = Config R4000 VR4100 VR4300 */
2292 case 16:
2293 if (op == cp0_mfc0 || op == cp0_dmfc0)
2294 GPR[rt] = C0_CONFIG;
2295 else
2296 /* only bottom three bits are writable */
2297 C0_CONFIG = (C0_CONFIG & ~0x7) | (GPR[rt] & 0x7);
2298 break;
2299 #endif
2300 #ifdef SUBTARGET_R3900
2301 /* 17 = Debug */
2302 case 17:
2303 if (op == cp0_mfc0 || op == cp0_dmfc0)
2304 GPR[rt] = DEPC;
2305 else
2306 DEPC = GPR[rt];
2307 break;
2308 #else
2309 /* 17 = LLAddr R4000 VR4100 VR4300 */
2310 #endif
2311 /* 18 = WatchLo R4000 VR4100 VR4300 */
2312 /* 19 = WatchHi R4000 VR4100 VR4300 */
2313 /* 20 = XContext R4000 VR4100 VR4300 */
2314 /* 26 = PErr or ECC R4000 VR4100 VR4300 */
2315 /* 27 = CacheErr R4000 VR4100 */
2316 /* 28 = TagLo R4000 VR4100 VR4300 */
2317 /* 29 = TagHi R4000 VR4100 VR4300 */
2318 /* 30 = ErrorEPC R4000 VR4100 VR4300 */
2319 if (STATE_VERBOSE_P(SD))
2320 sim_io_eprintf (SD,
2321 "Warning: PC 0x%lx:interp.c decode_coproc DEADC0DE\n",
2322 (unsigned long)cia);
2323 GPR[rt] = 0xDEADC0DE; /* CPR[0,rd] */
2324 /* CPR[0,rd] = GPR[rt]; */
2325 default:
2326 if (op == cp0_mfc0 || op == cp0_dmfc0)
2327 GPR[rt] = (signed_word) (signed32) COP0_GPR[rd];
2328 else
2329 COP0_GPR[rd] = GPR[rt];
2330 #if 0
2331 if (code == 0x00)
2332 sim_io_printf(sd,"Warning: MFC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2333 else
2334 sim_io_printf(sd,"Warning: MTC0 %d,%d ignored, PC=%08x (architecture specific)\n",rt,rd, (unsigned)cia);
2335 #endif
2336 }
2337 }
2338 else if ((op == cp0_mfc0 || op == cp0_dmfc0)
2339 && rd == 16)
2340 {
2341 /* [D]MFC0 RT,C0_CONFIG,SEL */
2342 signed32 cfg = 0;
2343 switch (sel)
2344 {
2345 case 0:
2346 cfg = C0_CONFIG;
2347 break;
2348 case 1:
2349 /* MIPS32 r/o Config1:
2350 Config2 present */
2351 cfg = 0x80000000;
2352 /* MIPS16 implemented.
2353 XXX How to check configuration? */
2354 cfg |= 0x0000004;
2355 if (CURRENT_FLOATING_POINT == HARD_FLOATING_POINT)
2356 /* MDMX & FPU implemented */
2357 cfg |= 0x00000021;
2358 break;
2359 case 2:
2360 /* MIPS32 r/o Config2:
2361 Config3 present. */
2362 cfg = 0x80000000;
2363 break;
2364 case 3:
2365 /* MIPS32 r/o Config3:
2366 SmartMIPS implemented. */
2367 cfg = 0x00000002;
2368 break;
2369 }
2370 GPR[rt] = cfg;
2371 }
2372 else if (op == cp0_eret && sel == 0x18)
2373 {
2374 /* ERET */
2375 if (SR & status_ERL)
2376 {
2377 /* Oops, not yet available */
2378 sim_io_printf(sd,"Warning: ERET when SR[ERL] set not handled yet");
2379 PC = EPC;
2380 SR &= ~status_ERL;
2381 }
2382 else
2383 {
2384 PC = EPC;
2385 SR &= ~status_EXL;
2386 }
2387 }
2388 else if (op == cp0_rfe && sel == 0x10)
2389 {
2390 /* RFE */
2391 #ifdef SUBTARGET_R3900
2392 /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
2393
2394 /* shift IE/KU history bits right */
2395 SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
2396
2397 /* TODO: CACHE register */
2398 #endif /* SUBTARGET_R3900 */
2399 }
2400 else if (op == cp0_deret && sel == 0x1F)
2401 {
2402 /* DERET */
2403 Debug &= ~Debug_DM;
2404 DELAYSLOT();
2405 DSPC = DEPC;
2406 }
2407 else
2408 sim_io_eprintf(sd,"Unrecognised COP0 instruction 0x%08X at PC = 0x%s : No handler present\n",instruction,pr_addr(cia));
2409 /* TODO: When executing an ERET or RFE instruction we should
2410 clear LLBIT, to ensure that any out-standing atomic
2411 read/modify/write sequence fails. */
2412 }
2413 break;
2414
2415 case 2: /* co-processor 2 */
2416 {
2417 int handle = 0;
2418
2419
2420 if(! handle)
2421 {
2422 sim_io_eprintf(sd, "COP2 instruction 0x%08X at PC = 0x%s : No handler present\n",
2423 instruction,pr_addr(cia));
2424 }
2425 }
2426 break;
2427
2428 case 1: /* should not occur (FPU co-processor) */
2429 case 3: /* should not occur (FPU co-processor) */
2430 SignalException(ReservedInstruction,instruction);
2431 break;
2432 }
2433
2434 return;
2435 }
2436
2437
2438 /* This code copied from gdb's utils.c. Would like to share this code,
2439 but don't know of a common place where both could get to it. */
2440
2441 /* Temporary storage using circular buffer */
2442 #define NUMCELLS 16
2443 #define CELLSIZE 32
2444 static char*
2445 get_cell (void)
2446 {
2447 static char buf[NUMCELLS][CELLSIZE];
2448 static int cell=0;
2449 if (++cell>=NUMCELLS) cell=0;
2450 return buf[cell];
2451 }
2452
2453 /* Print routines to handle variable size regs, etc */
2454
2455 /* Eliminate warning from compiler on 32-bit systems */
2456 static int thirty_two = 32;
2457
2458 char*
2459 pr_addr (SIM_ADDR addr)
2460 {
2461 char *paddr_str=get_cell();
2462 switch (sizeof(addr))
2463 {
2464 case 8:
2465 sprintf(paddr_str,"%08lx%08lx",
2466 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
2467 break;
2468 case 4:
2469 sprintf(paddr_str,"%08lx",(unsigned long)addr);
2470 break;
2471 case 2:
2472 sprintf(paddr_str,"%04x",(unsigned short)(addr&0xffff));
2473 break;
2474 default:
2475 sprintf(paddr_str,"%x",addr);
2476 }
2477 return paddr_str;
2478 }
2479
2480 char*
2481 pr_uword64 (uword64 addr)
2482 {
2483 char *paddr_str=get_cell();
2484 sprintf(paddr_str,"%08lx%08lx",
2485 (unsigned long)(addr>>thirty_two),(unsigned long)(addr&0xffffffff));
2486 return paddr_str;
2487 }
2488
2489
2490 void
2491 mips_core_signal (SIM_DESC sd,
2492 sim_cpu *cpu,
2493 sim_cia cia,
2494 unsigned map,
2495 int nr_bytes,
2496 address_word addr,
2497 transfer_type transfer,
2498 sim_core_signals sig)
2499 {
2500 const char *copy = (transfer == read_transfer ? "read" : "write");
2501 address_word ip = CIA_ADDR (cia);
2502
2503 switch (sig)
2504 {
2505 case sim_core_unmapped_signal:
2506 sim_io_eprintf (sd, "mips-core: %d byte %s to unmapped address 0x%lx at 0x%lx\n",
2507 nr_bytes, copy,
2508 (unsigned long) addr, (unsigned long) ip);
2509 COP0_BADVADDR = addr;
2510 SignalExceptionDataReference();
2511 break;
2512
2513 case sim_core_unaligned_signal:
2514 sim_io_eprintf (sd, "mips-core: %d byte %s to unaligned address 0x%lx at 0x%lx\n",
2515 nr_bytes, copy,
2516 (unsigned long) addr, (unsigned long) ip);
2517 COP0_BADVADDR = addr;
2518 if(transfer == read_transfer)
2519 SignalExceptionAddressLoad();
2520 else
2521 SignalExceptionAddressStore();
2522 break;
2523
2524 default:
2525 sim_engine_abort (sd, cpu, cia,
2526 "mips_core_signal - internal error - bad switch");
2527 }
2528 }
2529
2530
2531 void
2532 mips_cpu_exception_trigger(SIM_DESC sd, sim_cpu* cpu, address_word cia)
2533 {
2534 ASSERT(cpu != NULL);
2535
2536 if(cpu->exc_suspended > 0)
2537 sim_io_eprintf(sd, "Warning, nested exception triggered (%d)\n", cpu->exc_suspended);
2538
2539 PC = cia;
2540 memcpy(cpu->exc_trigger_registers, cpu->registers, sizeof(cpu->exc_trigger_registers));
2541 cpu->exc_suspended = 0;
2542 }
2543
2544 void
2545 mips_cpu_exception_suspend(SIM_DESC sd, sim_cpu* cpu, int exception)
2546 {
2547 ASSERT(cpu != NULL);
2548
2549 if(cpu->exc_suspended > 0)
2550 sim_io_eprintf(sd, "Warning, nested exception signal (%d then %d)\n",
2551 cpu->exc_suspended, exception);
2552
2553 memcpy(cpu->exc_suspend_registers, cpu->registers, sizeof(cpu->exc_suspend_registers));
2554 memcpy(cpu->registers, cpu->exc_trigger_registers, sizeof(cpu->registers));
2555 cpu->exc_suspended = exception;
2556 }
2557
2558 void
2559 mips_cpu_exception_resume(SIM_DESC sd, sim_cpu* cpu, int exception)
2560 {
2561 ASSERT(cpu != NULL);
2562
2563 if(exception == 0 && cpu->exc_suspended > 0)
2564 {
2565 /* warn not for breakpoints */
2566 if(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 cpu->exc_suspended);
2569 }
2570 else if(exception != 0 && cpu->exc_suspended > 0)
2571 {
2572 if(exception != cpu->exc_suspended)
2573 sim_io_eprintf(sd, "Warning, resuming with mismatched exception signal (%d vs %d)\n",
2574 cpu->exc_suspended, exception);
2575
2576 memcpy(cpu->registers, cpu->exc_suspend_registers, sizeof(cpu->registers));
2577 }
2578 else if(exception != 0 && cpu->exc_suspended == 0)
2579 {
2580 sim_io_eprintf(sd, "Warning, ignoring spontanous exception signal (%d)\n", exception);
2581 }
2582 cpu->exc_suspended = 0;
2583 }
2584
2585
2586 /*---------------------------------------------------------------------------*/
2587 /*> EOF interp.c <*/