diff options
author | Andrew Cagney <cagney@redhat.com> | 1998-03-25 04:15:38 +0000 |
---|---|---|
committer | Andrew Cagney <cagney@redhat.com> | 1998-03-25 04:15:38 +0000 |
commit | 6100784a60a46ce81f1264a630cf003f74df78ce (patch) | |
tree | 872d16ff0f41d3fa580c29f797b16d1aded249a7 /sim/mn10300/interp.c | |
parent | 8388c9a5646ad6b1eff9db4851ccd8761decad9e (diff) | |
download | gdb-6100784a60a46ce81f1264a630cf003f74df78ce.zip gdb-6100784a60a46ce81f1264a630cf003f74df78ce.tar.gz gdb-6100784a60a46ce81f1264a630cf003f74df78ce.tar.bz2 |
* interp.c (sim_open): Create second 1mb memory region at 0x40000000.
(sim_open): Create a device tree.
(sim-hw.h): Include.
(do_interrupt): Delete, needs to use dv-mn103cpu.c
* dv-mn103int.c, dv-mn103cpu.c: New files.
Diffstat (limited to 'sim/mn10300/interp.c')
-rw-r--r-- | sim/mn10300/interp.c | 269 |
1 files changed, 119 insertions, 150 deletions
diff --git a/sim/mn10300/interp.c b/sim/mn10300/interp.c index eede9a7..4c14b70 100644 --- a/sim/mn10300/interp.c +++ b/sim/mn10300/interp.c @@ -3,6 +3,7 @@ #if WITH_COMMON #include "sim-main.h" #include "sim-options.h" +#include "sim-hw.h" #else #include "mn10300_sim.h" #endif @@ -892,151 +893,6 @@ sim_load (sd, prog, abfd, from_tty) /* For compatibility */ SIM_DESC simulator; -/* mn10300 interrupt model */ - -enum interrupt_type -{ - int_reset, - int_nmi, - int_intov1, - int_intp10, - int_intp11, - int_intp12, - int_intp13, - int_intcm4, - num_int_types -}; - -char *interrupt_names[] = { - "reset", - "nmi", - "intov1", - "intp10", - "intp11", - "intp12", - "intp13", - "intcm4", - NULL -}; - - -static void -do_interrupt (sd, data) - SIM_DESC sd; - void *data; -{ -#if 0 - char **interrupt_name = (char**)data; - enum interrupt_type inttype; - inttype = (interrupt_name - STATE_WATCHPOINTS (sd)->interrupt_names); - - /* For a hardware reset, drop everything and jump to the start - address */ - if (inttype == int_reset) - { - PC = 0; - PSW = 0x20; - ECR = 0; - sim_engine_restart (sd, NULL, NULL, NULL_CIA); - } - - /* Deliver an NMI when allowed */ - if (inttype == int_nmi) - { - if (PSW & PSW_NP) - { - /* We're already working on an NMI, so this one must wait - around until the previous one is done. The processor - ignores subsequent NMIs, so we don't need to count them. - Just keep re-scheduling a single NMI until it manages to - be delivered */ - if (STATE_CPU (sd, 0)->pending_nmi != NULL) - sim_events_deschedule (sd, STATE_CPU (sd, 0)->pending_nmi); - STATE_CPU (sd, 0)->pending_nmi = - sim_events_schedule (sd, 1, do_interrupt, data); - return; - } - else - { - /* NMI can be delivered. Do not deschedule pending_nmi as - that, if still in the event queue, is a second NMI that - needs to be delivered later. */ - FEPC = PC; - FEPSW = PSW; - /* Set the FECC part of the ECR. */ - ECR &= 0x0000ffff; - ECR |= 0x10; - PSW |= PSW_NP; - PSW &= ~PSW_EP; - PSW |= PSW_ID; - PC = 0x10; - sim_engine_restart (sd, NULL, NULL, NULL_CIA); - } - } - - /* deliver maskable interrupt when allowed */ - if (inttype > int_nmi && inttype < num_int_types) - { - if ((PSW & PSW_NP) || (PSW & PSW_ID)) - { - /* Can't deliver this interrupt, reschedule it for later */ - sim_events_schedule (sd, 1, do_interrupt, data); - return; - } - else - { - /* save context */ - EIPC = PC; - EIPSW = PSW; - /* Disable further interrupts. */ - PSW |= PSW_ID; - /* Indicate that we're doing interrupt not exception processing. */ - PSW &= ~PSW_EP; - /* Clear the EICC part of the ECR, will set below. */ - ECR &= 0xffff0000; - switch (inttype) - { - case int_intov1: - PC = 0x80; - ECR |= 0x80; - break; - case int_intp10: - PC = 0x90; - ECR |= 0x90; - break; - case int_intp11: - PC = 0xa0; - ECR |= 0xa0; - break; - case int_intp12: - PC = 0xb0; - ECR |= 0xb0; - break; - case int_intp13: - PC = 0xc0; - ECR |= 0xc0; - break; - case int_intcm4: - PC = 0xd0; - ECR |= 0xd0; - break; - default: - /* Should never be possible. */ - sim_engine_abort (sd, NULL, NULL_CIA, - "do_interrupt - internal error - bad switch"); - break; - } - } - sim_engine_restart (sd, NULL, NULL, NULL_CIA); - } - - /* some other interrupt? */ - sim_engine_abort (sd, NULL, NULL_CIA, - "do_interrupt - internal error - interrupt %d unknown", - inttype); -#endif /* 0 */ -} - /* These default values correspond to expected usage for the chip. */ SIM_DESC @@ -1047,6 +903,7 @@ sim_open (kind, cb, abfd, argv) char **argv; { SIM_DESC sd = sim_state_alloc (kind, cb); + struct hw *hw; mn10300_callback = cb; SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER); @@ -1054,19 +911,20 @@ sim_open (kind, cb, abfd, argv) /* for compatibility */ simulator = sd; - /* FIXME: should be better way of setting up interrupts */ + /* FIXME: should be better way of setting up interrupts. For + moment, only support watchpoints causing a breakpoint (gdb + halt). */ STATE_WATCHPOINTS (sd)->pc = &(PC); STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PC); - STATE_WATCHPOINTS (sd)->interrupt_handler = do_interrupt; - STATE_WATCHPOINTS (sd)->interrupt_names = interrupt_names; + STATE_WATCHPOINTS (sd)->interrupt_handler = NULL; + STATE_WATCHPOINTS (sd)->interrupt_names = NULL; if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK) return 0; /* Allocate core managed memory */ - - /* "Mirror" the ROM addresses below 1MB. */ sim_do_command (sd, "memory region 0,0x100000"); + sim_do_command (sd, "memory region 0x40000000,0x100000"); /* 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 @@ -1079,6 +937,117 @@ sim_open (kind, cb, abfd, argv) return 0; } + hw = hw_tree_create (sd, "core"); + hw_tree_parse (hw, "/"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/trace? true"); + + + /* interrupt controller */ + + hw_tree_parse (hw, "/mn103int@0x34000100"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/mn103int/trace? true"); + hw_tree_parse (hw, "/mn103int/reg 0x34000100 0x68 0x34000200 0x8 0x3400280 0x8"); + + /* NMI input's */ + hw_tree_parse (hw, "/glue@0x30000000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x30000000/trace? true"); + hw_tree_parse (hw, "/glue@0x30000000/reg 0x30000000 16"); + hw_tree_parse (hw, "/glue@0x30000000 > int1 nmirq /mn103int"); + hw_tree_parse (hw, "/glue@0x30000000 > int2 watchdog /mn103int"); + hw_tree_parse (hw, "/glue@0x30000000 > int3 syserr /mn103int"); + + /* NMI output */ + hw_tree_parse (hw, "/mn103int > nmi int0 /glue@0x30000000"); + + /* ACK input */ + hw_tree_parse (hw, "/glue@0x30002000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x30002000/trace? true"); + hw_tree_parse (hw, "/glue@0x30002000/reg 0x30002000 4"); + hw_tree_parse (hw, "/glue@0x30002000 > int ack /mn103int"); + + /* LEVEL output */ + hw_tree_parse (hw, "/glue@0x30004000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x30004000/trace? true"); + hw_tree_parse (hw, "/glue@0x30004000/reg 0x30004000 4"); + hw_tree_parse (hw, "/mn103int > level int /glue@0x30004000"); + + /* A bunch of interrupt inputs */ + hw_tree_parse (hw, "/glue@0x30006000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x30006000/trace? true"); + hw_tree_parse (hw, "/glue@0x30006000/reg 0x30006000 16"); + hw_tree_parse (hw, "/glue@0x30006000 > int0 irq-0 /mn103int"); + hw_tree_parse (hw, "/glue@0x30006000 > int1 irq-1 /mn103int"); + hw_tree_parse (hw, "/glue@0x30006000 > int2 irq-2 /mn103int"); + hw_tree_parse (hw, "/glue@0x30006000 > int3 irq-3 /mn103int"); + + + /* processor interrupt device */ + + /* the device */ + hw_tree_parse (hw, "/mn103cpu@0x20000000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/mn103cpu@0x20000000/trace? true"); + hw_tree_parse (hw, "/mn103cpu@0x20000000/reg 0x20000000 0x42"); + + /* DEBUG: ACK output wired upto a glue device */ + hw_tree_parse (hw, "/glue@0x20002000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x20002000/trace? true"); + hw_tree_parse (hw, "/glue@0x20002000/reg 0x20002000 4"); + hw_tree_parse (hw, "/mn103cpu > ack int0 /glue@0x20002000"); + + /* DEBUG: RESET/NMI/LEVEL wired up to a glue device */ + hw_tree_parse (hw, "/glue@0x20004000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x20004000/trace? true"); + hw_tree_parse (hw, "/glue@0x20004000/reg 0x20004000 12"); + hw_tree_parse (hw, "/glue@0x20004000 > int0 reset /mn103cpu"); + hw_tree_parse (hw, "/glue@0x20004000 > int1 nmi /mn103cpu"); + hw_tree_parse (hw, "/glue@0x20004000 > int2 level /mn103cpu"); + + /* The processor wired up to the real interrupt controller */ + hw_tree_parse (hw, "/mn103cpu > ack ack /mn103int"); + hw_tree_parse (hw, "/mn103int > level level /mn103cpu"); + hw_tree_parse (hw, "/mn103int > nmi nmi /mn103cpu"); + + + /* PAL */ + + /* the device */ + hw_tree_parse (hw, "/pal@0x31000000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/pal@0x31000000/trace? true"); + hw_tree_parse (hw, "/pal@0x31000000/reg 0x31000000 64"); + + /* DEBUG: PAL wired up to a glue device */ + hw_tree_parse (hw, "/glue@0x31002000"); + if (STATE_VERBOSE_P (sd)) + hw_tree_parse (hw, "/glue@0x31002000/trace? true"); + hw_tree_parse (hw, "/glue@0x31002000/reg 0x31002000 16"); + hw_tree_parse (hw, "/pal@0x31000000 > countdown int0 /glue@0x31002000"); + hw_tree_parse (hw, "/pal@0x31000000 > timer int1 /glue@0x31002000"); + hw_tree_parse (hw, "/pal@0x31000000 > int int2 /glue@0x31002000"); + hw_tree_parse (hw, "/glue@0x31002000 > int0 int3 /glue@0x31002000"); + hw_tree_parse (hw, "/glue@0x31002000 > int1 int3 /glue@0x31002000"); + hw_tree_parse (hw, "/glue@0x31002000 > int2 int3 /glue@0x31002000"); + + /* The PAL wired up to the real interrupt controller */ + hw_tree_parse (hw, "/pal@0x31000000 > countdown irq-0 /mn103int"); + hw_tree_parse (hw, "/pal@0x31000000 > timer irq-1 /mn103int"); + hw_tree_parse (hw, "/pal@0x31000000 > int irq-2 /mn103int"); + + + + hw_tree_finish (hw); + if (STATE_VERBOSE_P (sd)) + hw_tree_print (hw); + /* check for/establish the a reference program image */ if (sim_analyze_program (sd, (STATE_PROG_ARGV (sd) != NULL |