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