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