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