diff options
author | Jamin Lin <jamin_lin@aspeedtech.com> | 2025-03-07 11:59:24 +0800 |
---|---|---|
committer | Cédric Le Goater <clg@redhat.com> | 2025-03-09 14:36:53 +0100 |
commit | 5824e8bf6beb226aa5dee94d4e92b671e9b082f1 (patch) | |
tree | 6b7d2990d57911b415ad0c27ab8b4d0a00b4c11b | |
parent | ab24c6a2df8e6c8055b6f1dfe80697320b327c50 (diff) | |
download | qemu-5824e8bf6beb226aa5dee94d4e92b671e9b082f1.zip qemu-5824e8bf6beb226aa5dee94d4e92b671e9b082f1.tar.gz qemu-5824e8bf6beb226aa5dee94d4e92b671e9b082f1.tar.bz2 |
hw/intc/aspeed: Introduce IRQ handler function to reduce code duplication
The behavior of the INTC set IRQ is almost identical between INTC and INTCIO.
To reduce duplicated code, introduce the "aspeed_intc_set_irq_handler" function
to handle both INTC and INTCIO IRQ behavior. No functional change.
Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
Link: https://lore.kernel.org/qemu-devel/20250307035945.3698802-16-jamin_lin@aspeedtech.com
Signed-off-by: Cédric Le Goater <clg@redhat.com>
-rw-r--r-- | hw/intc/aspeed_intc.c | 70 |
1 files changed, 39 insertions, 31 deletions
diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index be24516..3aa97ad 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -76,11 +76,45 @@ static void aspeed_intc_update(AspeedINTCState *s, int inpin_idx, qemu_set_irq(s->output_pins[outpin_idx], level); } +static void aspeed_intc_set_irq_handler(AspeedINTCState *s, + const AspeedINTCIRQ *intc_irq, + uint32_t select) +{ + const char *name = object_get_typename(OBJECT(s)); + uint32_t status_reg; + int outpin_idx; + int inpin_idx; + + status_reg = intc_irq->status_reg; + outpin_idx = intc_irq->outpin_idx; + inpin_idx = intc_irq->inpin_idx; + + if (s->mask[inpin_idx] || s->regs[status_reg]) { + /* + * a. mask is not 0 means in ISR mode + * sources interrupt routine are executing. + * b. status register value is not 0 means previous + * source interrupt does not be executed, yet. + * + * save source interrupt to pending variable. + */ + s->pending[inpin_idx] |= select; + trace_aspeed_intc_pending_irq(name, inpin_idx, s->pending[inpin_idx]); + } else { + /* + * notify firmware which source interrupt are coming + * by setting status register + */ + s->regs[status_reg] = select; + trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx, + s->regs[status_reg]); + aspeed_intc_update(s, inpin_idx, outpin_idx, 1); + } +} + /* - * The address of GICINT128 to GICINT136 are from 0x1000 to 0x1804. - * Utilize "address & 0x0f00" to get the irq and irq output pin index - * The value of irq should be 0 to num_inpins. - * The irq 0 indicates GICINT128, irq 1 indicates GICINT129 and so on. + * GICINT128 to GICINT136 map 1:1 to input and output IRQs 0 to 8. + * The value of input IRQ should be between 0 and the number of inputs. */ static void aspeed_intc_set_irq(void *opaque, int irq, int level) { @@ -88,20 +122,15 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level) AspeedINTCClass *aic = ASPEED_INTC_GET_CLASS(s); const char *name = object_get_typename(OBJECT(s)); const AspeedINTCIRQ *intc_irq; - uint32_t status_reg; uint32_t select = 0; uint32_t enable; - int outpin_idx; int inpin_idx; int i; assert(irq < aic->num_inpins); intc_irq = &aic->irq_table[irq]; - status_reg = intc_irq->status_reg; - outpin_idx = intc_irq->outpin_idx; inpin_idx = intc_irq->inpin_idx; - trace_aspeed_intc_set_irq(name, inpin_idx, level); enable = s->enable[inpin_idx]; @@ -122,28 +151,7 @@ static void aspeed_intc_set_irq(void *opaque, int irq, int level) } trace_aspeed_intc_select(name, select); - - if (s->mask[inpin_idx] || s->regs[status_reg]) { - /* - * a. mask is not 0 means in ISR mode - * sources interrupt routine are executing. - * b. status register value is not 0 means previous - * source interrupt does not be executed, yet. - * - * save source interrupt to pending variable. - */ - s->pending[inpin_idx] |= select; - trace_aspeed_intc_pending_irq(name, inpin_idx, s->pending[inpin_idx]); - } else { - /* - * notify firmware which source interrupt are coming - * by setting status register - */ - s->regs[status_reg] = select; - trace_aspeed_intc_trigger_irq(name, inpin_idx, outpin_idx, - s->regs[status_reg]); - aspeed_intc_update(s, inpin_idx, outpin_idx, 1); - } + aspeed_intc_set_irq_handler(s, intc_irq, select); } static void aspeed_intc_enable_handler(AspeedINTCState *s, hwaddr offset, |