aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2011-04-25 21:42:17 -0400
committerMike Frysinger <vapier@gentoo.org>2024-01-01 18:23:25 -0500
commit00c4a7f8d136bce908b6d8a812acdd0e68899e9a (patch)
tree4b1bfdb070ced27eeda365812ff4d55529de33f6
parent7eb2c710983289b2b268c251de57ded08b12c23e (diff)
downloadgdb-00c4a7f8d136bce908b6d8a812acdd0e68899e9a.zip
gdb-00c4a7f8d136bce908b6d8a812acdd0e68899e9a.tar.gz
gdb-00c4a7f8d136bce908b6d8a812acdd0e68899e9a.tar.bz2
sim: bfin: keep output port levels from SIC level and up-to-date
When the internal interrupt routes get updated (via the IAR MMRs), we need to resend all the output levels as they might have changed. We also need to do this after the MMR write is committed instead of before so that we send out the most up-to-date value. Further, we need to send both high and low levels so that when a line goes low, the other side is made aware of this. Signed-off-by: Mike Frysinger <vapier@gentoo.org> 2011-04-25 Mike Frysinger <vapier@gentoo.org> * dv-bfin_sic.c (bfin_sic_forward_interrupts): Declare new local "levels" array. Drop empty ipend if check. Set levels to 1 instead of calling hw_port_event directly. Add a new loop over the levels array at the end of the func and move the HW_TRACE/hw_port_event call there. (bfin_sic_52x_io_write_buffer): Move the forward interrupts call after the value32p write, and run this code for IAR MMRs too. (bfin_sic_537_io_write_buffer, bfin_sic_54x_io_write_buffer, bfin_sic_561_io_write_buffer): Likewise.
-rw-r--r--sim/bfin/dv-bfin_sic.c49
1 files changed, 25 insertions, 24 deletions
diff --git a/sim/bfin/dv-bfin_sic.c b/sim/bfin/dv-bfin_sic.c
index ac302a7..cf4f09e 100644
--- a/sim/bfin/dv-bfin_sic.c
+++ b/sim/bfin/dv-bfin_sic.c
@@ -104,15 +104,16 @@ static const char * const *mmr_names;
static void
bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
{
+ int levels[IVG15 - IVG7 + 1];
int my_port;
bu32 ipend;
- /* Process pending and unmasked interrupts. */
- ipend = *isr & *imask;
+ /* Gather all the signals based on their mappings/masks, and then send
+ out the updated levels to the CEC. */
+
+ memset (levels, 0, sizeof (levels));
- /* Usually none are pending unmasked, so avoid bit twiddling. */
- if (!ipend)
- return;
+ ipend = *isr & *imask;
for (my_port = 0; my_port < 32; ++my_port)
{
@@ -128,8 +129,14 @@ bfin_sic_forward_interrupts (struct hw *me, bu32 *isr, bu32 *imask, bu32 *iar)
iar_idx = my_port / 8;
iar_off = (my_port % 8) * 4;
iar_val = (iar[iar_idx] & (0xf << iar_off)) >> iar_off;
- HW_TRACE ((me, "forwarding int %i to CEC", IVG7 + iar_val));
- hw_port_event (me, IVG7 + iar_val, 1);
+ levels[iar_val] = 1;
+ }
+
+ for (my_port = 0; my_port < ARRAY_SIZE (levels); ++my_port)
+ {
+ HW_TRACE ((me, "setting level to CEC for int %2i to %i",
+ IVG7 + my_port, levels[my_port]));
+ hw_port_event (me, IVG7 + my_port, levels[my_port]);
}
}
@@ -176,11 +183,11 @@ bfin_sic_52x_io_write_buffer (struct hw *me, const void *source, int space,
break;
case mmr_offset(bf52x.imask0):
case mmr_offset(bf52x.imask1):
- bfin_sic_52x_forward_interrupts (me, sic);
- *value32p = value;
- break;
case mmr_offset(bf52x.iar0) ... mmr_offset(bf52x.iar3):
case mmr_offset(bf52x.iar4) ... mmr_offset(bf52x.iar7):
+ *value32p = value;
+ bfin_sic_52x_forward_interrupts (me, sic);
+ break;
case mmr_offset(bf52x.iwr0):
case mmr_offset(bf52x.iwr1):
*value32p = value;
@@ -287,13 +294,10 @@ bfin_sic_537_io_write_buffer (struct hw *me, const void *source, int space,
/* XXX: what to do ... */
break;
case mmr_offset(bf537.imask):
- bfin_sic_537_forward_interrupts (me, sic);
+ case mmr_offset(bf537.iar0) ... mmr_offset(bf537.iar3):
*value32p = value;
+ bfin_sic_537_forward_interrupts (me, sic);
break;
- case mmr_offset(bf537.iar0):
- case mmr_offset(bf537.iar1):
- case mmr_offset(bf537.iar2):
- case mmr_offset(bf537.iar3):
case mmr_offset(bf537.iwr):
*value32p = value;
break;
@@ -337,10 +341,7 @@ bfin_sic_537_io_read_buffer (struct hw *me, void *dest, int space,
dv_store_2 (dest, *value16p);
break;
case mmr_offset(bf537.imask):
- case mmr_offset(bf537.iar0):
- case mmr_offset(bf537.iar1):
- case mmr_offset(bf537.iar2):
- case mmr_offset(bf537.iar3):
+ case mmr_offset(bf537.iar0) ... mmr_offset(bf537.iar3):
case mmr_offset(bf537.isr):
case mmr_offset(bf537.iwr):
dv_store_4 (dest, *value32p);
@@ -399,10 +400,10 @@ bfin_sic_54x_io_write_buffer (struct hw *me, const void *source, int space,
/* XXX: what to do ... */
break;
case mmr_offset(bf54x.imask0) ... mmr_offset(bf54x.imask2):
- bfin_sic_54x_forward_interrupts (me, sic);
+ case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
*value32p = value;
+ bfin_sic_54x_forward_interrupts (me, sic);
break;
- case mmr_offset(bf54x.iar0) ... mmr_offset(bf54x.iar11):
case mmr_offset(bf54x.iwr0) ... mmr_offset(bf54x.iwr2):
*value32p = value;
break;
@@ -505,11 +506,11 @@ bfin_sic_561_io_write_buffer (struct hw *me, const void *source, int space,
break;
case mmr_offset(bf561.imask0):
case mmr_offset(bf561.imask1):
- bfin_sic_561_forward_interrupts (me, sic);
- *value32p = value;
- break;
case mmr_offset(bf561.iar0) ... mmr_offset(bf561.iar3):
case mmr_offset(bf561.iar4) ... mmr_offset(bf561.iar7):
+ *value32p = value;
+ bfin_sic_561_forward_interrupts (me, sic);
+ break;
case mmr_offset(bf561.iwr0):
case mmr_offset(bf561.iwr1):
*value32p = value;