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