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