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