diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-04-25 21:42:17 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2024-01-01 18:23:25 -0500 |
commit | 00c4a7f8d136bce908b6d8a812acdd0e68899e9a (patch) | |
tree | 4b1bfdb070ced27eeda365812ff4d55529de33f6 | |
parent | 7eb2c710983289b2b268c251de57ded08b12c23e (diff) | |
download | gdb-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.c | 49 |
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; |