SH: Use qemu_irq in timer emulation.
PATCH 1/1 SH: Use qemu_irq in timer emulation.
Presently, SH device emulation does not use qemu_irq mechanism, which makes it hard to integrate it with existing models. In particular, SMSC LAN91C111 emulation uses qemu_irq interface. This patch, for starters, switches timer emulation to use qemu_irq, the next patch will switch serial emulation.
- Volodya
* hw/sh.h (tmu012_init): Accept qemu_irq, not intc_source.
* hw/sh7750.c (sh7750_init): Pass qemu_irq to tmu012_init.
* hw/sh_intc.c (sh_intc_set_irq): New. (sh_intc_init): Allocate irqs.
* hw/sh_intc.h (struct intc_desc): New field irqs.
* hw/sh_timer.c (sh_timer_state): Use qemu_irq, not intc_source. (sh_timer_update): Use qemu_set_irq, not sh_intc_toggle_source. (sh_timer_init, tmu012_init): Adjust.
--- hw/sh.h | 4 ++-- hw/sh7750.c | 12 ++++++------ hw/sh_intc.c | 10 ++++++++++ hw/sh_intc.h | 5 ++++- hw/sh_timer.c | 10 +++++----- 5 files changed, 27 insertions(+), 14 deletions(-)
hw/sh.h +2 -2
@@ -28,8 +28,8 @@ int sh7750_register_io_device(struct SH7750State *s,#define TMU012_FEAT_3CHAN (1 << 1)#define TMU012_FEAT_EXTCLK (1 << 2)void tmu012_init (target_phys_addr_t base,int feat,uint32_t freq, -struct intc_source *ch0_irq,struct intc_source *ch1_irq, -struct intc_source *ch2_irq0,struct intc_source *ch2_irq1); +qemu_irq ch0_irq,qemu_irq ch1_irq, +qemu_irq ch2_irq0,qemu_irq ch2_irq1);/* sh_serial.c */
hw/sh7750.c +6 -6
@@ -678,10 +678,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu)tmu012_init (0x1fd80000 ,TMU012_FEAT_TOCR |TMU012_FEAT_3CHAN |TMU012_FEAT_EXTCLK , s->periph_freq, -sh_intc_source (&s->intc,TMU0 ), -sh_intc_source (&s->intc,TMU1 ), -sh_intc_source (&s->intc,TMU2_TUNI ), -sh_intc_source (&s->intc,TMU2_TICPI )); + s->intc.irqs[TMU0 ], + s->intc.irqs[TMU1 ], + s->intc.irqs[TMU2_TUNI ], + s->intc.irqs[TMU2_TICPI ]);if (cpu->id & (SH_CPU_SH7750 |SH_CPU_SH7750S |SH_CPU_SH7751 )) { sh_intc_register_sources(&s->intc,
@@ -700,8 +700,8 @@ SH7750State *sh7750_init(CPUSH4State * cpu)_INTC_ARRAY (vectors_tmu34), NULL, 0);tmu012_init (0x1e100000 ,0 , s->periph_freq, -sh_intc_source (&s->intc,TMU3 ), -sh_intc_source (&s->intc,TMU4 ), + s->intc.irqs[TMU3 ], + s->intc.irqs[TMU4 ],NULL ,NULL ); }
hw/sh_intc.c +10 -0
@@ -73,6 +73,14 @@ void sh_intc_toggle_source(struct intc_source *source, } } +void sh_intc_set_irq (void *opaque,int n,int level) +{ +struct intc_desc *desc = opaque; +struct intc_source *source = &(desc->sources[n]); + +sh_intc_toggle_source (source,0 , level ?1 :-1 ); +} +int sh_intc_get_pending_vector (struct intc_desc *desc,int imask) {unsigned int i;
@@ -428,6 +436,8 @@ int sh_intc_init(struct intc_desc *desc, source->parent = desc; } + + desc->irqs =qemu_allocate_irqs (sh_intc_set_irq, desc, nr_sources); desc->iomemtype =cpu_register_io_memory (0 , sh_intc_readfn, sh_intc_writefn, desc);
hw/sh_intc.h +4 -1
@@ -1,6 +1,9 @@#ifndef __SH_INTC_H__#define __SH_INTC_H__ +#include "qemu-common.h" +#include "irq.h" +typedef unsigned char intc_enum ; struct intc_vect {
@@ -43,13 +46,13 @@ struct intc_source { };struct intc_desc { +qemu_irq *irqs;struct intc_source *sources;int nr_sources;struct intc_mask_reg *mask_regs;int nr_mask_regs;struct intc_prio_reg *prio_regs;int nr_prio_regs; -int iomemtype;int pending;/* number of interrupt sources that has pending set */ };
hw/sh_timer.c +5 -5
@@ -36,7 +36,7 @@ typedef struct {int old_level;int feat;int enabled; -struct intc_source *irq; +qemu_irq irq; } sh_timer_state;/* Check all active timers, and schedule the next timer interrupt. */
@@ -46,7 +46,7 @@ static void sh_timer_update(sh_timer_state *s)int new_level = s->int_level && (s->tcr &TIMER_TCR_UNIE );if (new_level != s->old_level) -sh_intc_toggle_source (s->irq,0 , new_level ?1 :-1 ); +qemu_set_irq (s->irq, new_level); s->old_level = s->int_level; s->int_level = new_level;
@@ -185,7 +185,7 @@ static void sh_timer_tick(void *opaque)sh_timer_update (s); } -static void *sh_timer_init (uint32_t freq,int feat,struct intc_source *irq) +static void *sh_timer_init (uint32_t freq,int feat,qemu_irq irq) {sh_timer_state *s;QEMUBH *bh;
@@ -307,8 +307,8 @@ static CPUWriteMemoryFunc *tmu012_writefn[] = { };void tmu012_init (target_phys_addr_t base,int feat,uint32_t freq, -struct intc_source *ch0_irq,struct intc_source *ch1_irq, -struct intc_source *ch2_irq0,struct intc_source *ch2_irq1) +qemu_irq ch0_irq,qemu_irq ch1_irq, +qemu_irq ch2_irq0,qemu_irq ch2_irq1) {int iomemtype;tmu012_state *s;
Signature · 1 line
1.5.3.5
Aurelien Jarno
AppliedQuoted 6 lines · Vladimir Prus
Presently, SH device emulation does not use
qemu_irqmechanism, which makes it hard to integrate it with existing models. In particular, SMSC LAN91C111 emulation usesqemu_irqinterface. This patch, for starters, switches timer emulation to useqemu_irq, the next patch will switch serial emulation.
Applied, thanks.
Quoted 168 lines
- Volodya
*
hw/sh.h(tmu012_init): Acceptqemu_irq, notintc_source.
*hw/sh7750.c(sh7750_init): Passqemu_irqtotmu012_init.
*hw/sh_intc.c(sh_intc_set_irq): New. (sh_intc_init): Allocate irqs.
*hw/sh_intc.h(structintc_desc): New field irqs.
*hw/sh_timer.c(sh_timer_state): Useqemu_irq, notintc_source. (sh_timer_update): Useqemu_set_irq, notsh_intc_toggle_source. (sh_timer_init,tmu012_init): Adjust.--- hw/sh.h | 4 ++-- hw/sh7750.c | 12 ++++++------ hw/sh_intc.c | 10 ++++++++++ hw/sh_intc.h | 5 ++++- hw/sh_timer.c | 10 +++++----- 5 files changed, 27 insertions(+), 14 deletions(-)hw/sh.h +2
-2@@ -28,8 +28,8 @@ int sh7750_register_io_device(struct SH7750State *s,#define TMU012_FEAT_3CHAN (1 << 1)#define TMU012_FEAT_EXTCLK (1 << 2)void tmu012_init (target_phys_addr_t base,int feat,uint32_t freq, -struct intc_source *ch0_irq,struct intc_source *ch1_irq, -struct intc_source *ch2_irq0,struct intc_source *ch2_irq1); +qemu_irq ch0_irq,qemu_irq ch1_irq, +qemu_irq ch2_irq0,qemu_irq ch2_irq1);/* sh_serial.c */ hw/sh7750.c +6
-6@@ -678,10 +678,10 @@ SH7750State *sh7750_init(CPUSH4State * cpu)tmu012_init (0x1fd80000 ,TMU012_FEAT_TOCR |TMU012_FEAT_3CHAN |TMU012_FEAT_EXTCLK , s->periph_freq, -sh_intc_source (&s->intc,TMU0 ), -sh_intc_source (&s->intc,TMU1 ), -sh_intc_source (&s->intc,TMU2_TUNI ), -sh_intc_source (&s->intc,TMU2_TICPI )); + s->intc.irqs[TMU0 ], + s->intc.irqs[TMU1 ], + s->intc.irqs[TMU2_TUNI ], + s->intc.irqs[TMU2_TICPI ]);if (cpu->id & (SH_CPU_SH7750 |SH_CPU_SH7750S |SH_CPU_SH7751 )) { sh_intc_register_sources(&s->intc,@@ -700,8 +700,8 @@ SH7750State *sh7750_init(CPUSH4State * cpu)_INTC_ARRAY (vectors_tmu34), NULL, 0);tmu012_init (0x1e100000 ,0 , s->periph_freq, -sh_intc_source (&s->intc,TMU3 ), -sh_intc_source (&s->intc,TMU4 ), + s->intc.irqs[TMU3 ], + s->intc.irqs[TMU4 ],NULL ,NULL ); }hw/sh_intc.c +10
-0@@ -73,6 +73,14 @@ void sh_intc_toggle_source(struct intc_source *source, } } +void sh_intc_set_irq (void *opaque,int n,int level) +{ +struct intc_desc *desc = opaque; +struct intc_source *source = &(desc->sources[n]); + +sh_intc_toggle_source (source,0 , level ?1 :-1 ); +} +int sh_intc_get_pending_vector (struct intc_desc *desc,int imask) {unsigned int i;@@ -428,6 +436,8 @@ int sh_intc_init(struct intc_desc *desc, source->parent = desc; } + + desc->irqs =qemu_allocate_irqs (sh_intc_set_irq, desc, nr_sources); desc->iomemtype =cpu_register_io_memory (0 , sh_intc_readfn, sh_intc_writefn, desc);hw/sh_intc.h +4
-1@@ -1,6 +1,9 @@#ifndef __SH_INTC_H__#define __SH_INTC_H__ +#include "qemu-common.h" +#include "irq.h" +typedef unsigned char intc_enum ; struct intc_vect {@@ -43,13 +46,13 @@ struct intc_source { };struct intc_desc { +qemu_irq *irqs;struct intc_source *sources;int nr_sources;struct intc_mask_reg *mask_regs;int nr_mask_regs;struct intc_prio_reg *prio_regs;int nr_prio_regs; -int iomemtype;int pending;/* number of interrupt sources that has pending set */ };hw/sh_timer.c +5
-5@@ -36,7 +36,7 @@ typedef struct {int old_level;int feat;int enabled; -struct intc_source *irq; +qemu_irq irq; } sh_timer_state;/* Check all active timers, and schedule the next timer interrupt. */ @@ -46,7 +46,7 @@ static void sh_timer_update(sh_timer_state *s)int new_level = s->int_level && (s->tcr &TIMER_TCR_UNIE );if (new_level != s->old_level) -sh_intc_toggle_source (s->irq,0 , new_level ?1 :-1 ); +qemu_set_irq (s->irq, new_level); s->old_level = s->int_level; s->int_level = new_level;@@ -185,7 +185,7 @@ static void sh_timer_tick(void *opaque)sh_timer_update (s); } -static void *sh_timer_init (uint32_t freq,int feat,struct intc_source *irq) +static void *sh_timer_init (uint32_t freq,int feat,qemu_irq irq) {sh_timer_state *s;QEMUBH *bh;@@ -307,8 +307,8 @@ static CPUWriteMemoryFunc *tmu012_writefn[] = { };void tmu012_init (target_phys_addr_t base,int feat,uint32_t freq, -struct intc_source *ch0_irq,struct intc_source *ch1_irq, -struct intc_source *ch2_irq0,struct intc_source *ch2_irq1) +qemu_irq ch0_irq,qemu_irq ch1_irq, +qemu_irq ch2_irq0,qemu_irq ch2_irq1) {int iomemtype;tmu012_state *s;Signature · 1 line
1.5.3.5
Signature · 4 lines
.''`. Aurelien Jarno | GPG: 1024D/F1BCDB73 : :' : Debian developer | Electrical Engineer `. `' [email protected] | [email protected] `- people.debian.org/~aurel32 | www.aurel32.net