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