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