diff options
Diffstat (limited to 'sim/mn10300')
-rw-r--r-- | sim/mn10300/ChangeLog | 25 | ||||
-rw-r--r-- | sim/mn10300/Makefile.in | 2 | ||||
-rw-r--r-- | sim/mn10300/dv-mn103int.c | 7 | ||||
-rw-r--r-- | sim/mn10300/dv-mn103tim.c | 2 | ||||
-rw-r--r-- | sim/mn10300/interp.c | 28 | ||||
-rw-r--r-- | sim/mn10300/mn10300.igen | 3 |
6 files changed, 60 insertions, 7 deletions
diff --git a/sim/mn10300/ChangeLog b/sim/mn10300/ChangeLog index d992099..161acf2 100644 --- a/sim/mn10300/ChangeLog +++ b/sim/mn10300/ChangeLog @@ -1,3 +1,28 @@ +1999-04-16 Frank Ch. Eigler <fche@cygnus.com> + + * interp.c (program_interrupt): Detect undesired recursion using + static flag. Set NMIRC register's SYSEF flag during + --board=stdeval1 mode. + * dv-mn103-int.c (write_icr): Add backdoor address to allow CPU to + set SYSEF flag. + +1999-04-02 Keith Seitz <keiths@cygnus.com> + + * Makefile.in (SIM_EXTRA_CFLAGS): Define a POLL_QUIT_INTERVAL + for use in the simulator so that the poll_quit callback is + not called too often. + +Tue Mar 9 21:26:41 1999 Andrew Cagney <cagney@b1.cygnus.com> + + * dv-mn103int.c (mn103int_ioctl): Return something. + * dv-mn103tim.c (write_tm6md): GCC suggested parentheses around && + within ||. + +Tue Feb 16 23:57:17 1999 Jeffrey A Law (law@cygnus.com) + + * mn10300.igen (retf): Fix return address computation and store + the new pc value into nia. + 1998-12-29 Frank Ch. Eigler <fche@cygnus.com> * Makefile.in (WITH_COMMON_OBJS): Build also dv-sockser.o. diff --git a/sim/mn10300/Makefile.in b/sim/mn10300/Makefile.in index f5123c4..612576c 100644 --- a/sim/mn10300/Makefile.in +++ b/sim/mn10300/Makefile.in @@ -51,7 +51,7 @@ NL_TARGET = -DNL_TARGET_mn10300 INCLUDE = mn10300_sim.h $(srcdir)/../../include/callback.h # List of extra flags to always pass to $(CC). -SIM_EXTRA_CFLAGS = @sim_gen@ +SIM_EXTRA_CFLAGS = @sim_gen@ -DPOLL_QUIT_INTERVAL=0x20 ## COMMON_POST_CONFIG_FRAG diff --git a/sim/mn10300/dv-mn103int.c b/sim/mn10300/dv-mn103int.c index 11982fb..d64e007 100644 --- a/sim/mn10300/dv-mn103int.c +++ b/sim/mn10300/dv-mn103int.c @@ -585,6 +585,12 @@ write_icr (struct hw *me, group->gid, val)); group->request &= ~EXTRACT_ID (val); break; + /* Special backdoor access to SYSEF flag from CPU. See + interp.c:program_interrupt(). */ + case 3: + HW_TRACE ((me, "write-icr-special group=%d:0 nmi 0x%02x", + group->gid, val)); + group->request |= EXTRACT_ID (val); default: break; } @@ -815,6 +821,7 @@ mn103int_ioctl(struct hw *me, struct mn103int *controller = (struct mn103int *)hw_data(me); controller->group[0].request = EXTRACT_ID(4); mn103int_port_event(me, 2 /* nmi_port(syserr) */, NULL, 0, 0); + return 0; } diff --git a/sim/mn10300/dv-mn103tim.c b/sim/mn10300/dv-mn103tim.c index d93bb71..cd79f91 100644 --- a/sim/mn10300/dv-mn103tim.c +++ b/sim/mn10300/dv-mn103tim.c @@ -842,7 +842,7 @@ write_tm6md (struct hw *me, unsigned_word offset = address - timers->block[0].base; - if ( offset != 0x84 && nr_bytes > 1 || nr_bytes > 2 ) + if ((offset != 0x84 && nr_bytes > 1) || nr_bytes > 2 ) { hw_abort (me, "Bad write size of %d bytes to TM6MD", nr_bytes); } diff --git a/sim/mn10300/interp.c b/sim/mn10300/interp.c index d5e833e..12dffff 100644 --- a/sim/mn10300/interp.c +++ b/sim/mn10300/interp.c @@ -1329,19 +1329,39 @@ program_interrupt (SIM_DESC sd, { int status; struct hw *device; + static int in_interrupt = 0; #ifdef SIM_CPU_EXCEPTION_TRIGGER SIM_CPU_EXCEPTION_TRIGGER(sd,cpu,cia); #endif - /* copy NMI handler code from dv-mn103cpu.c */ - /* XXX: possible infinite recursion if these store_*() calls fail! */ - store_word (SP - 4, CIA_GET (cpu)); - store_half (SP - 8, PSW); + /* avoid infinite recursion */ + if (in_interrupt) + { + (*mn10300_callback->printf_filtered) (mn10300_callback, + "ERROR: recursion in program_interrupt during software exception dispatch."); + } + else + { + in_interrupt = 1; + /* copy NMI handler code from dv-mn103cpu.c */ + store_word (SP - 4, CIA_GET (cpu)); + store_half (SP - 8, PSW); + + /* Set the SYSEF flag in NMICR by backdoor method. See + dv-mn103int.c:write_icr(). This is necessary because + software exceptions are not modelled by actually talking to + the interrupt controller, so it cannot set its own SYSEF + flag. */ + if ((NULL != board) && (strcmp(board, BOARD_AM32) == 0)) + store_byte (0x34000103, 0x04); + } + PSW &= ~PSW_IE; SP = SP - 8; CIA_SET (cpu, 0x40000008); + in_interrupt = 0; sim_engine_halt(sd, cpu, NULL, cia, sim_stopped, sig); } diff --git a/sim/mn10300/mn10300.igen b/sim/mn10300/mn10300.igen index 7c4f03d..1b42db4 100644 --- a/sim/mn10300/mn10300.igen +++ b/sim/mn10300/mn10300.igen @@ -3486,7 +3486,7 @@ PC = cia; State.regs[REG_SP] += IMM8; sp = State.regs[REG_SP]; - State.regs[REG_PC] = State.regs[REG_MDR] - 3; + State.regs[REG_PC] = State.regs[REG_MDR]; offset = -4; mask = REGS; @@ -3533,5 +3533,6 @@ State.regs[REG_LAR] = load_word (sp + offset); offset -= 4; } + nia = PC; } |