aboutsummaryrefslogtreecommitdiff
path: root/sim/mips/interp.c
diff options
context:
space:
mode:
authorFrank Ch. Eigler <fche@redhat.com>1998-05-18 15:55:05 +0000
committerFrank Ch. Eigler <fche@redhat.com>1998-05-18 15:55:05 +0000
commit3fa454e95fe104add1b25e53a8dc1decc1c270f1 (patch)
tree9bb506f391e5eaece890333cda94a9a3f2e219af /sim/mips/interp.c
parentd9c2c0c569da93bb393a078ebadbb89c1b6cca3b (diff)
downloadgdb-3fa454e95fe104add1b25e53a8dc1decc1c270f1.zip
gdb-3fa454e95fe104add1b25e53a8dc1decc1c270f1.tar.gz
gdb-3fa454e95fe104add1b25e53a8dc1decc1c270f1.tar.bz2
* Monster patch - may destablize MIPS sims for a little while.
* Followup patch for SCEI PR 15853 * First check-in of TX3904 interrupt controller devices for ECC. [sanitized] * First implementation of MIPS hardware interrupt emulation. Mon May 18 18:22:42 1998 Frank Ch. Eigler <fche@cygnus.com> * configure.in (SIM_AC_OPTION_HARDWARE): Added common hardware modules. Recognize TX39 target with "mips*tx39" pattern. * configure: Rebuilt. * sim-main.h (*): Added many macros defining bits in TX39 control registers. (SignalInterrupt): Send actual PC instead of NULL. (SignalNMIReset): New exception type. * interp.c (board): New variable for future use to identify a particular board being simulated. (mips_option_handler,mips_options): Added "--board" option. (interrupt_event): Send actual PC. (sim_open): Make memory layout conditional on board setting. (signal_exception): Initial implementation of hardware interrupt handling. Accept another break instruction variant for simulator exit. (decode_coproc): Implement RFE instruction for TX39. (mips.igen): Decode RFE instruction as such. start-sanitize-tx3904 * configure.in (tx3904cpu,tx3904irc): Added devices for tx3904. * interp.c: Define "jmr3904" and "jmr3904debug" board types and bbegin to implement memory map. * dv-tx3904cpu.c: New file. * dv-tx3904irc.c: New file. end-sanitize-tx3904
Diffstat (limited to 'sim/mips/interp.c')
-rw-r--r--sim/mips/interp.c219
1 files changed, 179 insertions, 40 deletions
diff --git a/sim/mips/interp.c b/sim/mips/interp.c
index ff1252d..f83fdc3 100644
--- a/sim/mips/interp.c
+++ b/sim/mips/interp.c
@@ -37,6 +37,7 @@ code on the hardware.
#include "sim-utils.h"
#include "sim-options.h"
#include "sim-assert.h"
+#include "sim-hw.h"
/* start-sanitize-sky */
#ifdef TARGET_SKY
@@ -113,6 +114,7 @@ char* pr_uword64 PARAMS ((uword64 addr));
halt is required. NOTE: Care must be taken, since this value may
be used in later revisions of the MIPS ISA. */
#define HALT_INSTRUCTION (0x03ff000d)
+#define HALT_INSTRUCTION2 (0x0000ffcd)
#define HALT_INSTRUCTION_MASK (0x03FFFFC0)
@@ -180,6 +182,10 @@ FILE *tracefh = NULL;
static void open_trace PARAMS((SIM_DESC sd));
#endif /* TRACE */
+/* simulation target board. NULL=canonical */
+static char* board = NULL;
+
+
static DECLARE_OPTION_HANDLER (mips_option_handler);
enum {
@@ -195,8 +201,10 @@ enum {
,OPTION_GS_REFRESH2
#endif
/* end-sanitize-sky */
+ ,OPTION_BOARD
};
+
static SIM_RC
mips_option_handler (sd, cpu, opt, arg, is_command)
SIM_DESC sd;
@@ -265,10 +273,10 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
#ifdef SKY_FUNIT
case OPTION_FLOAT_TYPE:
/* Use host (fast) or target (accurate) floating point implementation. */
- if (arg && strcmp (arg, "host") == 0)
- STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET;
- else if (arg && strcmp (arg, "target") == 0)
- STATE_FP_TYPE_OPT (sd) |= STATE_FP_TYPE_OPT_TARGET;
+ if (arg && strcmp (arg, "fast") == 0)
+ STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_ACCURATE;
+ else if (arg && strcmp (arg, "accurate") == 0)
+ STATE_FP_TYPE_OPT (sd) |= STATE_FP_TYPE_OPT_ACCURATE;
else
{
fprintf (stderr, "Unrecognized float-type option `%s'\n", arg);
@@ -318,11 +326,22 @@ Re-compile simulator with \"-DTRACE\" to enable this option.\n");
#endif
/* end-sanitize-sky */
+
+ case OPTION_BOARD:
+ {
+ if (arg)
+ {
+ board = zalloc(strlen(arg) + 1);
+ strcpy(board, arg);
+ }
+ return SIM_RC_OK;
+ }
}
-
+
return SIM_RC_OK;
}
+
static const OPTION mips_options[] =
{
{ {"dinero-trace", optional_argument, NULL, OPTION_DINERO_TRACE},
@@ -335,7 +354,7 @@ static const OPTION mips_options[] =
#ifdef TARGET_SKY
#ifdef SKY_FUNIT
{ {"float-type", required_argument, NULL, OPTION_FLOAT_TYPE},
- '\0', "host|target", "Use host (fast) or target (accurate) floating point",
+ '\0', "fast|accurate", "Use fast (host) or accurate (target) floating point",
mips_option_handler },
#endif
{ {"enable-gs", required_argument, NULL, OPTION_GS_ENABLE},
@@ -349,6 +368,19 @@ static const OPTION mips_options[] =
mips_option_handler },
#endif
/* end-sanitize-sky */
+
+ { {"board", required_argument, NULL, OPTION_BOARD},
+ '\0', "none" /* rely on compile-time string concatenation for other options */
+
+/* start-sanitize-tx3904 */
+#define BOARD_JMR3904 "jmr3904"
+ "|" BOARD_JMR3904
+#define BOARD_JMR3904_DEBUG "jmr3904debug"
+ "|" BOARD_JMR3904_DEBUG
+/* end-sanitize-tx3904 */
+
+ , "Customize simulation for a particular board.", mips_option_handler },
+
{ {NULL, no_argument, NULL, 0}, '\0', NULL, NULL, NULL }
};
@@ -359,6 +391,7 @@ static void
interrupt_event (SIM_DESC sd, void *data)
{
sim_cpu *cpu = STATE_CPU (sd, 0); /* FIXME */
+ address_word cia = CIA_GET (cpu);
if (SR & status_IE)
{
interrupt_pending = 0;
@@ -397,8 +430,8 @@ sim_open (kind, cb, abfd, argv)
/* start-sanitize-sky */
#if defined(TARGET_SKY) && defined(SKY_FUNIT)
- /* Set "--float-type host" as the default. */
- STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_TARGET;
+ /* Set "--float-type fast" as the default. */
+ STATE_FP_TYPE_OPT (sd) &= ~STATE_FP_TYPE_OPT_ACCURATE;
#endif
/* end-sanitize-sky */
@@ -413,33 +446,6 @@ sim_open (kind, cb, abfd, argv)
return 0;
sim_add_option_table (sd, NULL, mips_options);
- /* Allocate core managed memory */
-
- /* the monitor */
- sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
- /* For compatibility with the old code - under this (at level one)
- are the kernel spaces K0 & K1. Both of these map to a single
- smaller sub region */
- sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
-/* start-sanitize-sky */
-#ifndef TARGET_SKY
-/* end-sanitize-sky */
- sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
- K1BASE, K0SIZE,
- MEM_SIZE, /* actual size */
- K0BASE);
-/* start-sanitize-sky */
-#else
- sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
- K1BASE, K0SIZE,
- MEM_SIZE, /* actual size */
- K0BASE,
- 0); /* add alias at 0x0000 */
-#endif
-/* end-sanitize-sky */
-
- device_init(sd);
-
/* getopt will print the error message so we just have to exit if this fails.
FIXME: Hmmm... in the case of gdb we need getopt to call
print_filtered. */
@@ -451,6 +457,99 @@ sim_open (kind, cb, abfd, argv)
return 0;
}
+ /* handle board-specific memory maps */
+ if (board == NULL)
+ {
+ /* Allocate core managed memory */
+
+ /* the monitor */
+ sim_do_commandf (sd, "memory region 0x%lx,0x%lx", MONITOR_BASE, MONITOR_SIZE);
+ /* For compatibility with the old code - under this (at level one)
+ are the kernel spaces K0 & K1. Both of these map to a single
+ smaller sub region */
+ sim_do_command(sd," memory region 0x7fff8000,0x8000") ; /* MTZ- 32 k stack */
+ /* start-sanitize-sky */
+#ifndef TARGET_SKY
+ /* end-sanitize-sky */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x",
+ K1BASE, K0SIZE,
+ MEM_SIZE, /* actual size */
+ K0BASE);
+ /* start-sanitize-sky */
+#else
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx%%0x%lx,0x%0x,0x%0x",
+ K1BASE, K0SIZE,
+ MEM_SIZE, /* actual size */
+ K0BASE,
+ 0); /* add alias at 0x0000 */
+#endif
+ /* end-sanitize-sky */
+
+ device_init(sd);
+ }
+
+ /* start-sanitize-tx3904 */
+ else if(! strcmp(board, BOARD_JMR3904) ||
+ (! strcmp(board, BOARD_JMR3904_DEBUG)))
+ {
+ /* match VIRTUAL memory layout of JMR-TX3904 board */
+
+ /* --- memory --- */
+
+ /* ROM: 0x9FC0_0000 - 0x9FFF_FFFF and 0xBFC0_0000 - 0xBFFF_FFFF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+ 0x9FC00000,
+ 4 * 1024 * 1024, /* 4 MB */
+ 0xBFC00000);
+
+ /* SRAM: 0x8000_0000 - 0x803F_FFFF and 0xA000_0000 - 0xA03F_FFFF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+ 0x80000000,
+ 4 * 1024 * 1024, /* 4 MB */
+ 0xA0000000);
+
+ /* DRAM: 0x8800_0000 - 0x89FF_FFFF and 0xA800_0000 - 0xA9FF_FFFF */
+ sim_do_commandf (sd, "memory alias 0x%lx@1,0x%lx,0x%0x",
+ 0x88000000,
+ 32 * 1024 * 1024, /* 32 MB */
+ 0xA8000000);
+
+ /* --- simulated devices --- */
+ sim_hw_parse (sd, "/tx3904irc@0xffffc00/reg 0xffffc000 0x20");
+ sim_hw_parse (sd, "/tx3904cpu");
+
+ /* -- device connections --- */
+ sim_hw_parse (sd, "/tx3904irc > ip level /tx3904cpu");
+
+ if(! strcmp(board, BOARD_JMR3904_DEBUG))
+ {
+ /* -- DEBUG: glue interrupt generators --- */
+ sim_hw_parse (sd, "/glue@0xffff0000/reg 0xffff0000 0x50");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int0 int0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int1 int1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int2 int2 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int3 int3 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int4 int4 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int5 int5 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int6 int6 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int7 int7 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int8 dmac0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int9 dmac1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int10 dmac2 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int11 dmac3 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int12 sio0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int13 sio1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int14 tmr0 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int15 tmr1 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int16 tmr2 /tx3904irc");
+ sim_hw_parse (sd, "/glue@0xffff0000 > int17 nmi /tx3904cpu");
+ }
+
+ device_init(sd);
+ }
+ /* end-sanitize-tx3904 */
+
+
/* check for/establish the a reference program image */
if (sim_analyze_program (sd,
(STATE_PROG_ARGV (sd) != NULL
@@ -1275,7 +1374,7 @@ sim_monitor (SIM_DESC sd,
int width = 0, trunc = 0, haddot = 0, longlong = 0;
while (sim_read (sd, s++, &c, 1) && c != '\0')
{
- if (strchr ("dobxXulscefg%", s))
+ if (strchr ("dobxXulscefg%", c))
break;
else if (c == '-')
fmt = FMT_LJUST;
@@ -1622,7 +1721,7 @@ ColdReset (SIM_DESC sd)
{
sim_cpu *cpu = STATE_CPU (sd, cpu_nr);
/* RESET: Fixed PC address: */
- PC = UNSIGNED64 (0xFFFFFFFFBFC00000);
+ PC = (unsigned_word) UNSIGNED64 (0xFFFFFFFFBFC00000);
/* The reset vector address is in the unmapped, uncached memory space. */
SR &= ~(status_SR | status_TS | status_RP);
@@ -1760,8 +1859,8 @@ signal_exception (SIM_DESC sd,
instruction = va_arg(ap,unsigned int);
va_end(ap);
/* Check for our special terminating BREAK: */
- if ((instruction & HALT_INSTRUCTION_MASK)
- == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK))
+ if ((instruction & HALT_INSTRUCTION_MASK) == (HALT_INSTRUCTION & HALT_INSTRUCTION_MASK) ||
+ (instruction & HALT_INSTRUCTION_MASK) == (HALT_INSTRUCTION2 & HALT_INSTRUCTION_MASK))
{
sim_engine_halt (SD, CPU, NULL, cia,
sim_exited, (unsigned int)(A0 & 0xFFFFFFFF));
@@ -1781,6 +1880,28 @@ signal_exception (SIM_DESC sd,
/* TODO: If not simulating exceptions then stop the simulator
execution. At the moment we always stop the simulation. */
+#ifdef SUBTARGET_R3900
+ /* update interrupt-related registers */
+
+ /* insert exception code in bits 6:2 */
+ CAUSE = LSMASKED32(CAUSE, 31, 7) | LSINSERTED32(exception, 6, 2);
+ /* shift IE/KU history bits left */
+ SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 3, 0), 5, 2);
+
+ if (STATE & simDELAYSLOT)
+ {
+ STATE &= ~simDELAYSLOT;
+ CAUSE |= cause_BD;
+ EPC = (cia - 4); /* reference the branch instruction */
+ }
+ else
+ EPC = cia;
+
+ if (SR & status_BEV)
+ PC = (signed)0xBFC00000 + 0x180;
+ else
+ PC = (signed)0x80000000 + 0x080;
+#else
/* See figure 5-17 for an outline of the code below */
if (! (SR & status_EXL))
{
@@ -1804,10 +1925,12 @@ signal_exception (SIM_DESC sd,
SR |= status_EXL;
/* Store exception code into current exception id variable (used
by exit code): */
+
if (SR & status_BEV)
PC = (signed)0xBFC00200 + 0x180;
else
PC = (signed)0x80000000 + 0x180;
+#endif
switch ((CAUSE >> 2) & 0x1F)
{
@@ -1815,7 +1938,15 @@ signal_exception (SIM_DESC sd,
/* Interrupts arrive during event processing, no need to
restart */
return;
-
+
+ case NMIReset:
+ /* Ditto */
+#ifdef SUBTARGET_3900
+ /* Exception vector: BEV=0 BFC00000 / BEF=1 BFC00000 */
+ PC = (signed)0xBFC00000;
+#endif SUBTARGET_3900
+ return;
+
case TLBModification:
case TLBLoad:
case TLBStore:
@@ -3304,6 +3435,14 @@ decode_coproc (SIM_DESC sd,
else if (code == 0x10 && (instruction & 0x3f) == 0x10)
{
/* RFE */
+#ifdef SUBTARGET_R3900
+ /* TX39: Copy IEp/KUp -> IEc/KUc, and IEo/KUo -> IEp/KUp */
+
+ /* shift IE/KU history bits right */
+ SR = LSMASKED32(SR, 31, 4) | LSINSERTED32(LSEXTRACTED32(SR, 5, 2), 3, 0);
+
+ /* TODO: CACHE register */
+#endif /* SUBTARGET_R3900 */
}
else if (code == 0x10 && (instruction & 0x3f) == 0x1F)
{