diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-04-25 19:12:51 -0400 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2024-01-01 18:23:25 -0500 |
commit | 7eb2c710983289b2b268c251de57ded08b12c23e (patch) | |
tree | e70197ea597ff53eac053a59fe7631bfcb2f2d17 | |
parent | d07460446a94b5a1a3b68c9cdaee2b6b25227d67 (diff) | |
download | gdb-7eb2c710983289b2b268c251de57ded08b12c23e.zip gdb-7eb2c710983289b2b268c251de57ded08b12c23e.tar.gz gdb-7eb2c710983289b2b268c251de57ded08b12c23e.tar.bz2 |
sim: bfin: separate port levels from isa levels in the CEC
Since the input ports are level based (coming from the SIC/ctimer), make
sure we keep those values separate from levels manually raised via insns
(like RAISE and EXCPT) or cleared via MMRs (writes to ILAT). This way
the peripherals can raise/lower their interrupt lines without affecting
manual tweaking, and we get behavior that matches the hardware.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
2011-04-25 Mike Frysinger <vapier@gentoo.org>
* dv-bfin_cec.c (bfin_cec): Add "plat" member.
(bfin_cec_io_read_buffer): Merge "plat" with "ilat" when reading
the ILAT MMR.
(bfin_cec_port_event): Use the incoming level to set/clear bits
in "plat". When the bit isn't yet set, also call _cec_raise.
(_cec_raise): Merge "plat" with "ilat" when calling __cec_get_ivg.
-rw-r--r-- | sim/bfin/dv-bfin_cec.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/sim/bfin/dv-bfin_cec.c b/sim/bfin/dv-bfin_cec.c index d2c955b..54b6b2c 100644 --- a/sim/bfin/dv-bfin_cec.c +++ b/sim/bfin/dv-bfin_cec.c @@ -37,6 +37,9 @@ struct bfin_cec struct hw *me; struct hw_event *pending; + /* The port levels which latch into ilat. */ + bu32 plat; + /* Order after here is important -- matches hardware MMR layout. */ bu32 evt_override, imask, ipend, ilat, iprio; }; @@ -135,7 +138,15 @@ bfin_cec_io_read_buffer (struct hw *me, void *dest, HW_TRACE_READ (); - dv_store_4 (dest, *valuep); + switch (mmr_off) + { + case mmr_offset(ilat): + dv_store_4 (dest, *valuep | cec->plat); + break; + default: + dv_store_4 (dest, *valuep); + break; + } return nr_bytes; } @@ -165,7 +176,18 @@ bfin_cec_port_event (struct hw *me, int my_port, struct hw *source, int source_port, int level) { struct bfin_cec *cec = hw_data (me); - _cec_raise (cec->cpu, cec, my_port); + bu32 bit = 1 << my_port; + + if (level) + { + if (!(cec->plat & bit)) + { + cec->plat |= bit; + _cec_raise (cec->cpu, cec, my_port); + } + } + else + cec->plat &= ~bit; } static void @@ -507,7 +529,7 @@ _cec_raise (SIM_CPU *cpu, struct bfin_cec *cec, int ivg) if (irpten) goto done; /* All interrupts are masked anyways. */ - ivg = __cec_get_ivg (cec->ilat & cec->imask); + ivg = __cec_get_ivg ((cec->plat | cec->ilat) & cec->imask); if (ivg < 0) goto done; /* Nothing latched. */ |