summaryrefslogtreecommitdiffstats
path: root/hw/intc
diff options
context:
space:
mode:
Diffstat (limited to 'hw/intc')
-rw-r--r--hw/intc/armv7m_nvic.c9
-rw-r--r--hw/intc/loongarch_pch_pic.c10
-rw-r--r--hw/intc/xics.c10
-rw-r--r--hw/intc/xive.c4
4 files changed, 21 insertions, 12 deletions
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 13df002ce4..1f7763964c 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -2389,8 +2389,15 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr,
startvec = 8 * (offset - 0x280) + NVIC_FIRST_IRQ; /* vector # */
for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) {
+ /*
+ * Note that if the input line is still held high and the interrupt
+ * is not active then rule R_CVJS requires that the Pending state
+ * remains set; in that case we mustn't let it be cleared.
+ */
if (value & (1 << i) &&
- (attrs.secure || s->itns[startvec + i])) {
+ (attrs.secure || s->itns[startvec + i]) &&
+ !(setval == 0 && s->vectors[startvec + i].level &&
+ !s->vectors[startvec + i].active)) {
s->vectors[startvec + i].pending = setval;
}
}
diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c
index 3c9814a3b4..3380b09807 100644
--- a/hw/intc/loongarch_pch_pic.c
+++ b/hw/intc/loongarch_pch_pic.c
@@ -15,21 +15,21 @@
static void pch_pic_update_irq(LoongArchPCHPIC *s, uint64_t mask, int level)
{
- unsigned long val;
+ uint64_t val;
int irq;
if (level) {
val = mask & s->intirr & ~s->int_mask;
if (val) {
- irq = find_first_bit(&val, 64);
- s->intisr |= 0x1ULL << irq;
+ irq = ctz64(val);
+ s->intisr |= MAKE_64BIT_MASK(irq, 1);
qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 1);
}
} else {
val = mask & s->intisr;
if (val) {
- irq = find_first_bit(&val, 64);
- s->intisr &= ~(0x1ULL << irq);
+ irq = ctz64(val);
+ s->intisr &= ~MAKE_64BIT_MASK(irq, 1);
qemu_set_irq(s->parent_irq[s->htmsi_vector[irq]], 0);
}
}
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 24e67020db..5b0b4d9624 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -301,23 +301,25 @@ void icp_reset(ICPState *icp)
static void icp_realize(DeviceState *dev, Error **errp)
{
ICPState *icp = ICP(dev);
+ PowerPCCPU *cpu;
CPUPPCState *env;
Error *err = NULL;
assert(icp->xics);
assert(icp->cs);
- env = &POWERPC_CPU(icp->cs)->env;
+ cpu = POWERPC_CPU(icp->cs);
+ env = &cpu->env;
switch (PPC_INPUT(env)) {
case PPC_FLAGS_INPUT_POWER7:
- icp->output = env->irq_inputs[POWER7_INPUT_INT];
+ icp->output = qdev_get_gpio_in(DEVICE(cpu), POWER7_INPUT_INT);
break;
case PPC_FLAGS_INPUT_POWER9: /* For SPAPR xics emulation */
- icp->output = env->irq_inputs[POWER9_INPUT_INT];
+ icp->output = qdev_get_gpio_in(DEVICE(cpu), POWER9_INPUT_INT);
break;
case PPC_FLAGS_INPUT_970:
- icp->output = env->irq_inputs[PPC970_INPUT_INT];
+ icp->output = qdev_get_gpio_in(DEVICE(cpu), PPC970_INPUT_INT);
break;
default:
diff --git a/hw/intc/xive.c b/hw/intc/xive.c
index ae221fed73..a986b96843 100644
--- a/hw/intc/xive.c
+++ b/hw/intc/xive.c
@@ -695,8 +695,8 @@ static void xive_tctx_realize(DeviceState *dev, Error **errp)
env = &cpu->env;
switch (PPC_INPUT(env)) {
case PPC_FLAGS_INPUT_POWER9:
- tctx->hv_output = env->irq_inputs[POWER9_INPUT_HINT];
- tctx->os_output = env->irq_inputs[POWER9_INPUT_INT];
+ tctx->hv_output = qdev_get_gpio_in(DEVICE(cpu), POWER9_INPUT_HINT);
+ tctx->os_output = qdev_get_gpio_in(DEVICE(cpu), POWER9_INPUT_INT);
break;
default: