[PATCH]: Fixes for HC11 simulator interrupts
Stephane Carrez
Stephane.Carrez@worldnet.fr
Sun May 20 08:37:00 GMT 2001
Hi!
I've committed the following patch that fixes and improves the interrupts
of HC11 simulator:
- The SCI shares several interrupt conditions on the same interrupt vector.
The patch fixes the interrupt logic for this.
- We keep track of the last interrupt masked sequence (IRQ and XIRQ) so
that useful information is reported by sim info.
Stephane
2001-05-20 Stephane Carrez <Stephane.Carrez@worldnet.fr>
* dv-m68hc11sio.c (m68hc11sio_tx_poll): Always check for
pending interrupts.
* interrupts.c (interrupts_process): Keep track of the last number
of masked insn cycles.
(interrupts_initialize): Clear last number of masked insn cycles.
(interrupts_info): Report them.
(interrupts_update_pending): Compute clear and set masks of
interrupts and clear the interrupt bits before setting them
(due to SCI interrupt sharing).
* interrupts.h (struct interrupts): New members last_mask_cycles
and xirq_last_mask_cycles.
Index: dv-m68hc11sio.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/dv-m68hc11sio.c,v
retrieving revision 1.4
diff -u -p -r1.4 dv-m68hc11sio.c
--- dv-m68hc11sio.c 2000/11/26 21:41:31 1.4
+++ dv-m68hc11sio.c 2001/05/20 15:32:14
@@ -1,5 +1,5 @@
/* dv-m68hc11sio.c -- Simulation of the 68HC11 serial device.
- Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@worldnet.fr)
(From a driver model Contributed by Cygnus Solutions.)
@@ -320,7 +320,6 @@ m68hc11sio_tx_poll (struct hw *me, void
SIM_DESC sd;
struct m68hc11sio *controller;
sim_cpu *cpu;
- int check_interrupt = 0;
controller = hw_data (me);
sd = hw_system (me);
@@ -329,13 +328,12 @@ m68hc11sio_tx_poll (struct hw *me, void
cpu->ios[M6811_SCSR] |= M6811_TDRE;
cpu->ios[M6811_SCSR] |= M6811_TC;
- /* Transmitter is enabled and we have something to sent. */
+ /* Transmitter is enabled and we have something to send. */
if ((cpu->ios[M6811_SCCR2] & M6811_TE) && controller->tx_has_char)
{
cpu->ios[M6811_SCSR] &= ~M6811_TDRE;
cpu->ios[M6811_SCSR] &= ~M6811_TC;
controller->tx_has_char = 0;
- check_interrupt = 1;
switch (controller->backend)
{
case sio_tcp:
@@ -371,8 +369,7 @@ m68hc11sio_tx_poll (struct hw *me, void
NULL);
}
- if (check_interrupt)
- interrupts_update_pending (&cpu->cpu_interrupts);
+ interrupts_update_pending (&cpu->cpu_interrupts);
}
/* Descriptions of the SIO I/O ports. These descriptions are only used to
Index: interrupts.c
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/interrupts.c,v
retrieving revision 1.3
diff -u -p -r1.3 interrupts.c
--- interrupts.c 2000/09/10 12:58:53 1.3
+++ interrupts.c 2001/05/20 15:32:30
@@ -1,5 +1,5 @@
/* interrupts.c -- 68HC11 Interrupts Emulation
- Copyright 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@worldnet.fr)
This file is part of GDB, GAS, and the GNU binutils.
@@ -67,10 +67,12 @@ interrupts_initialize (struct _sim_cpu *
interrupts->nb_interrupts_raised = 0;
interrupts->min_mask_cycles = CYCLES_MAX;
interrupts->max_mask_cycles = 0;
+ interrupts->last_mask_cycles = 0;
interrupts->start_mask_cycle = -1;
interrupts->xirq_start_mask_cycle = -1;
interrupts->xirq_max_mask_cycles = 0;
interrupts->xirq_min_mask_cycles = CYCLES_MAX;
+ interrupts->xirq_last_mask_cycles = 0;
for (i = 0; i < M6811_INT_NUMBER; i++)
{
@@ -89,7 +91,11 @@ interrupts_update_pending (struct interr
{
int i;
uint8 *ioregs;
+ unsigned long clear_mask;
+ unsigned long set_mask;
+ clear_mask = 0;
+ set_mask = 0;
ioregs = &interrupts->cpu->ios[0];
for (i = 0; i < TableSize(idefs); i++)
@@ -104,7 +110,7 @@ interrupts_update_pending (struct interr
if (!(data & idef->enabled_mask))
{
/* Disable it. */
- interrupts->pending_mask &= ~(1 << idef->int_number);
+ clear_mask |= (1 << idef->int_number);
continue;
}
}
@@ -114,13 +120,18 @@ interrupts_update_pending (struct interr
if (!(data & idef->int_mask))
{
/* Disable it. */
- interrupts->pending_mask &= ~(1 << idef->int_number);
+ clear_mask |= (1 << idef->int_number);
continue;
}
/* Ok, raise it. */
- interrupts->pending_mask |= (1 << idef->int_number);
+ set_mask |= (1 << idef->int_number);
}
+
+ /* Some interrupts are shared (M6811_INT_SCI) so clear
+ the interrupts before setting the new ones. */
+ interrupts->pending_mask &= ~clear_mask;
+ interrupts->pending_mask |= set_mask;
}
@@ -214,6 +225,7 @@ interrupts_process (struct interrupts *i
if (t > interrupts->max_mask_cycles)
interrupts->max_mask_cycles = t;
interrupts->start_mask_cycle = -1;
+ interrupts->last_mask_cycles = t;
}
if (ccr & M6811_X_BIT)
{
@@ -232,6 +244,7 @@ interrupts_process (struct interrupts *i
if (t > interrupts->xirq_max_mask_cycles)
interrupts->xirq_max_mask_cycles = t;
interrupts->xirq_start_mask_cycle = -1;
+ interrupts->xirq_last_mask_cycles = t;
}
id = interrupts_get_current (interrupts);
@@ -275,6 +288,10 @@ interrupts_info (SIM_DESC sd, struct int
{
signed64 t;
+ sim_io_printf (sd, "Interrupts Info:\n");
+ sim_io_printf (sd, " Interrupts raised: %lu\n",
+ interrupts->nb_interrupts_raised);
+
if (interrupts->start_mask_cycle >= 0)
{
t = cpu_current_cycle (interrupts->cpu);
@@ -282,20 +299,10 @@ interrupts_info (SIM_DESC sd, struct int
t -= interrupts->start_mask_cycle;
if (t > interrupts->max_mask_cycles)
interrupts->max_mask_cycles = t;
- }
- if (interrupts->xirq_start_mask_cycle >= 0)
- {
- t = cpu_current_cycle (interrupts->cpu);
- t -= interrupts->xirq_start_mask_cycle;
- if (t > interrupts->xirq_max_mask_cycles)
- interrupts->xirq_max_mask_cycles = t;
+ sim_io_printf (sd, " Current interrupts masked sequence: %s\n",
+ cycle_to_string (interrupts->cpu, t));
}
-
- sim_io_printf (sd, "Interrupts Info:\n");
- sim_io_printf (sd, " Interrupts raised: %lu\n",
- interrupts->nb_interrupts_raised);
-
t = interrupts->min_mask_cycles == CYCLES_MAX ?
interrupts->max_mask_cycles :
interrupts->min_mask_cycles;
@@ -306,6 +313,22 @@ interrupts_info (SIM_DESC sd, struct int
sim_io_printf (sd, " Longest interrupts masked sequence: %s\n",
cycle_to_string (interrupts->cpu, t));
+ t = interrupts->last_mask_cycles;
+ sim_io_printf (sd, " Last interrupts masked sequence: %s\n",
+ cycle_to_string (interrupts->cpu, t));
+
+ if (interrupts->xirq_start_mask_cycle >= 0)
+ {
+ t = cpu_current_cycle (interrupts->cpu);
+
+ t -= interrupts->xirq_start_mask_cycle;
+ if (t > interrupts->xirq_max_mask_cycles)
+ interrupts->xirq_max_mask_cycles = t;
+
+ sim_io_printf (sd, " XIRQ Current interrupts masked sequence: %s\n",
+ cycle_to_string (interrupts->cpu, t));
+ }
+
t = interrupts->xirq_min_mask_cycles == CYCLES_MAX ?
interrupts->xirq_max_mask_cycles :
interrupts->xirq_min_mask_cycles;
@@ -314,5 +337,9 @@ interrupts_info (SIM_DESC sd, struct int
t = interrupts->xirq_max_mask_cycles;
sim_io_printf (sd, " XIRQ Max interrupts masked sequence: %s\n",
+ cycle_to_string (interrupts->cpu, t));
+
+ t = interrupts->xirq_last_mask_cycles;
+ sim_io_printf (sd, " XIRQ Last interrupts masked sequence: %s\n",
cycle_to_string (interrupts->cpu, t));
}
Index: interrupts.h
===================================================================
RCS file: /cvs/src/src/sim/m68hc11/interrupts.h,v
retrieving revision 1.1
diff -u -p -r1.1 interrupts.h
--- interrupts.h 2000/07/27 11:23:39 1.1
+++ interrupts.h 2001/05/20 15:32:30
@@ -1,5 +1,5 @@
/* interrupts.h -- 68HC11 Interrupts Emulation
- Copyright 1999, 2000 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001 Free Software Foundation, Inc.
Written by Stephane Carrez (stcarrez@worldnet.fr)
This file is part of GDB, GAS, and the GNU binutils.
@@ -109,11 +109,13 @@ struct interrupts {
signed64 start_mask_cycle;
signed64 min_mask_cycles;
signed64 max_mask_cycles;
+ signed64 last_mask_cycles;
/* - Same for XIRQ. */
signed64 xirq_start_mask_cycle;
signed64 xirq_min_mask_cycles;
signed64 xirq_max_mask_cycles;
+ signed64 xirq_last_mask_cycles;
/* - Total number of interrupts raised. */
unsigned long nb_interrupts_raised;
More information about the Gdb-patches
mailing list