Commit c6d86a33d36891bd5090ea72134b9854d6811173
1 parent
a4a771c0
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
Showing
4 changed files
with
59 additions
and
1 deletions
hw/sh.h
| @@ -42,6 +42,9 @@ void sh_serial_init (target_phys_addr_t base, int feat, | @@ -42,6 +42,9 @@ void sh_serial_init (target_phys_addr_t base, int feat, | ||
| 42 | qemu_irq tei_source, | 42 | qemu_irq tei_source, |
| 43 | qemu_irq bri_source); | 43 | qemu_irq bri_source); |
| 44 | 44 | ||
| 45 | +/* sh7750.c */ | ||
| 46 | +qemu_irq sh7750_irl(struct SH7750State *s); | ||
| 47 | + | ||
| 45 | /* tc58128.c */ | 48 | /* tc58128.c */ |
| 46 | int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2); | 49 | int tc58128_init(struct SH7750State *s, const char *zone1, const char *zone2); |
| 47 | 50 |
hw/sh7750.c
| @@ -412,7 +412,9 @@ enum { | @@ -412,7 +412,9 @@ enum { | ||
| 412 | UNUSED = 0, | 412 | UNUSED = 0, |
| 413 | 413 | ||
| 414 | /* interrupt sources */ | 414 | /* interrupt sources */ |
| 415 | - IRL0, IRL1, IRL2, IRL3, /* only IRLM mode supported */ | 415 | + IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, IRL_7, |
| 416 | + IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E, | ||
| 417 | + IRL0, IRL1, IRL2, IRL3, | ||
| 416 | HUDI, GPIOI, | 418 | HUDI, GPIOI, |
| 417 | DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, | 419 | DMAC_DMTE0, DMAC_DMTE1, DMAC_DMTE2, DMAC_DMTE3, |
| 418 | DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, | 420 | DMAC_DMTE4, DMAC_DMTE5, DMAC_DMTE6, DMAC_DMTE7, |
| @@ -428,6 +430,8 @@ enum { | @@ -428,6 +430,8 @@ enum { | ||
| 428 | 430 | ||
| 429 | /* interrupt groups */ | 431 | /* interrupt groups */ |
| 430 | DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, | 432 | DMAC, PCIC1, TMU2, RTC, SCI1, SCIF, REF, |
| 433 | + /* irl bundle */ | ||
| 434 | + IRL, | ||
| 431 | 435 | ||
| 432 | NR_SOURCES, | 436 | NR_SOURCES, |
| 433 | }; | 437 | }; |
| @@ -529,6 +533,29 @@ static struct intc_group groups_pci[] = { | @@ -529,6 +533,29 @@ static struct intc_group groups_pci[] = { | ||
| 529 | PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), | 533 | PCIC1_PCIDMA0, PCIC1_PCIDMA1, PCIC1_PCIDMA2, PCIC1_PCIDMA3), |
| 530 | }; | 534 | }; |
| 531 | 535 | ||
| 536 | +static struct intc_vect vectors_irl[] = { | ||
| 537 | + INTC_VECT(IRL_0, 0x200), | ||
| 538 | + INTC_VECT(IRL_1, 0x220), | ||
| 539 | + INTC_VECT(IRL_2, 0x240), | ||
| 540 | + INTC_VECT(IRL_3, 0x260), | ||
| 541 | + INTC_VECT(IRL_4, 0x280), | ||
| 542 | + INTC_VECT(IRL_5, 0x2a0), | ||
| 543 | + INTC_VECT(IRL_6, 0x2c0), | ||
| 544 | + INTC_VECT(IRL_7, 0x2e0), | ||
| 545 | + INTC_VECT(IRL_8, 0x300), | ||
| 546 | + INTC_VECT(IRL_9, 0x320), | ||
| 547 | + INTC_VECT(IRL_A, 0x340), | ||
| 548 | + INTC_VECT(IRL_B, 0x360), | ||
| 549 | + INTC_VECT(IRL_C, 0x380), | ||
| 550 | + INTC_VECT(IRL_D, 0x3a0), | ||
| 551 | + INTC_VECT(IRL_E, 0x3c0), | ||
| 552 | +}; | ||
| 553 | + | ||
| 554 | +static struct intc_group groups_irl[] = { | ||
| 555 | + INTC_GROUP(IRL, IRL_0, IRL_1, IRL_2, IRL_3, IRL_4, IRL_5, IRL_6, | ||
| 556 | + IRL_7, IRL_8, IRL_9, IRL_A, IRL_B, IRL_C, IRL_D, IRL_E), | ||
| 557 | +}; | ||
| 558 | + | ||
| 532 | /********************************************************************** | 559 | /********************************************************************** |
| 533 | Memory mapped cache and TLB | 560 | Memory mapped cache and TLB |
| 534 | **********************************************************************/ | 561 | **********************************************************************/ |
| @@ -718,5 +745,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu) | @@ -718,5 +745,16 @@ SH7750State *sh7750_init(CPUSH4State * cpu) | ||
| 718 | NULL, 0); | 745 | NULL, 0); |
| 719 | } | 746 | } |
| 720 | 747 | ||
| 748 | + sh_intc_register_sources(&s->intc, | ||
| 749 | + _INTC_ARRAY(vectors_irl), | ||
| 750 | + _INTC_ARRAY(groups_irl)); | ||
| 721 | return s; | 751 | return s; |
| 722 | } | 752 | } |
| 753 | + | ||
| 754 | +qemu_irq sh7750_irl(SH7750State *s) | ||
| 755 | +{ | ||
| 756 | + sh_intc_toggle_source(sh_intc_source(&s->intc, IRL), 1, 0); /* enable */ | ||
| 757 | + return qemu_allocate_irqs(sh_intc_set_irl, sh_intc_source(&s->intc, IRL), | ||
| 758 | + 1)[0]; | ||
| 759 | +} | ||
| 760 | + |
hw/sh_intc.c
| @@ -465,3 +465,18 @@ int sh_intc_init(struct intc_desc *desc, | @@ -465,3 +465,18 @@ int sh_intc_init(struct intc_desc *desc, | ||
| 465 | 465 | ||
| 466 | return 0; | 466 | return 0; |
| 467 | } | 467 | } |
| 468 | + | ||
| 469 | +/* Assert level <n> IRL interrupt. | ||
| 470 | + 0:deassert. 1:lowest priority,... 15:highest priority. */ | ||
| 471 | +void sh_intc_set_irl(void *opaque, int n, int level) | ||
| 472 | +{ | ||
| 473 | + struct intc_source *s = opaque; | ||
| 474 | + int i, irl = level ^ 15; | ||
| 475 | + for (i = 0; (s = sh_intc_source(s->parent, s->next_enum_id)); i++) { | ||
| 476 | + if (i == irl) | ||
| 477 | + sh_intc_toggle_source(s, s->enable_count?0:1, s->asserted?0:1); | ||
| 478 | + else | ||
| 479 | + if (s->asserted) | ||
| 480 | + sh_intc_toggle_source(s, 0, -1); | ||
| 481 | + } | ||
| 482 | +} |
hw/sh_intc.h
| @@ -75,4 +75,6 @@ int sh_intc_init(struct intc_desc *desc, | @@ -75,4 +75,6 @@ int sh_intc_init(struct intc_desc *desc, | ||
| 75 | struct intc_prio_reg *prio_regs, | 75 | struct intc_prio_reg *prio_regs, |
| 76 | int nr_prio_regs); | 76 | int nr_prio_regs); |
| 77 | 77 | ||
| 78 | +void sh_intc_set_irl(void *opaque, int n, int level); | ||
| 79 | + | ||
| 78 | #endif /* __SH_INTC_H__ */ | 80 | #endif /* __SH_INTC_H__ */ |