diff options
author | balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-07 18:49:57 +0000 |
---|---|---|
committer | balrog <balrog@c046a42c-6fe2-441c-8c8c-71466251a162> | 2008-12-07 18:49:57 +0000 |
commit | c6d86a33d36891bd5090ea72134b9854d6811173 (patch) | |
tree | 67fc4033db10455bf8fcc096de991c130c3a509a | |
parent | a4a771c055ea50f255f0d9a555c8628587afbea3 (diff) | |
download | hqemu-c6d86a33d36891bd5090ea72134b9854d6811173.zip hqemu-c6d86a33d36891bd5090ea72134b9854d6811173.tar.gz |
sh4: Add IRL (4-bit encoded interrupt input) support (Takashi YOSHII).
This patch adds IRL(4bit encoded 15 level interrupt input) support
to SH using qemu_irq as a multi level (!=on/off) signal.
Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp>
Signed-off-by: Andrzej Zaborowski <andrew.zaborowski@intel.com>
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5925 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r-- | hw/sh.h | 3 | ||||
-rw-r--r-- | hw/sh7750.c | 40 | ||||
-rw-r--r-- | hw/sh_intc.c | 15 | ||||
-rw-r--r-- | hw/sh_intc.h | 2 |
4 files changed, 59 insertions, 1 deletions
@@ -42,6 +42,9 @@ void sh_serial_init (target_phys_addr_t base, int feat, qemu_irq tei_source, qemu_irq bri_source); +/* sh7750.c */ +qemu_irq sh7750_irl(struct SH7750State *s); + /* tc58128.c */ int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2); diff --git a/hw/sh7750.c b/hw/sh7750.c index 1d18010..97597fc 100644 --- a/hw/sh7750.c +++ b/hw/sh7750.c @@ -412,7 +412,9 @@ enum { UNUSED = 0, /* interrupt sources */ - IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */ + IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7, + IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E, + IRL0, IRL1, IRL2, IRL3, HUDI, GPIOI, DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, @@ -428,6 +430,8 @@ enum { /* interrupt groups */ DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, + /* irl bundle */ + IRL, NR_SOURCES, }; @@ -529,6 +533,29 @@ static struct intc_group groups_pci[] = { PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), }; +static struct intc_vect vectors_irl[] = { + INTC_VECT(IRL_0, 0x200), + INTC_VECT(IRL_1, 0x220), + INTC_VECT(IRL_2, 0x240), + INTC_VECT(IRL_3, 0x260), + INTC_VECT(IRL_4, 0x280), + INTC_VECT(IRL_5, 0x2a0), + INTC_VECT(IRL_6, 0x2c0), + INTC_VECT(IRL_7, 0x2e0), + INTC_VECT(IRL_8, 0x300), + INTC_VECT(IRL_9, 0x320), + INTC_VECT(IRL_A, 0x340), + INTC_VECT(IRL_B, 0x360), + INTC_VECT(IRL_C, 0x380), + INTC_VECT(IRL_D, 0x3a0), + INTC_VECT(IRL_E, 0x3c0), +}; + +static struct intc_group groups_irl[] = { + INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, + IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E), +}; + /********************************************************************** Memory mapped cache and TLB **********************************************************************/ @@ -718,5 +745,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu) NULL, 0); } + sh_intc_register_sources(&s->intc, + _INTC_ARRAY(vectors_irl), + _INTC_ARRAY(groups_irl)); return s; } + +qemu_irq sh7750_irl(SH7750State *s) +{ + sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */ + return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL), + 1)[0]; +} + diff --git a/hw/sh_intc.c b/hw/sh_intc.c index 99db51c..b62633d 100644 --- a/hw/sh_intc.c +++ b/hw/sh_intc.c @@ -465,3 +465,18 @@ int sh_intc_init(struct intc_desc *desc, return 0; } + +/* Assert level <n> IRL interrupt. + 0:deassert. 1:lowest priority,... 15:highest priority. */ +void sh_intc_set_irl(void *opaque, int n, int level) +{ + struct intc_source *s = opaque; + int i, irl = level ^ 15; + for (i = 0; (s = sh_intc_source(s->parent, s->next_enum_id)); i++) { + if (i == irl) + sh_intc_toggle_source(s, s->enable_count?0:1, s->asserted?0:1); + else + if (s->asserted) + sh_intc_toggle_source(s, 0, -1); + } +} diff --git a/hw/sh_intc.h b/hw/sh_intc.h index 4362dcf..4e36f00 100644 --- a/hw/sh_intc.h +++ b/hw/sh_intc.h @@ -75,4 +75,6 @@ int sh_intc_init(struct intc_desc *desc, struct intc_prio_reg *prio_regs, int nr_prio_regs); +void sh_intc_set_irl(void *opaque, int n, int level); + #endif /* __SH_INTC_H__ */ |