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