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