/*
- * ARM Generic Interrupt Controller v3
+ * ARM Generic Interrupt Controller v3 (emulation)
*
* Copyright (c) 2015 Huawei.
* Copyright (c) 2016 Linaro Limited
#include "qemu/osdep.h"
#include "qapi/error.h"
-#include "hw/sysbus.h"
+#include "qemu/module.h"
#include "hw/intc/arm_gicv3.h"
#include "gicv3_internal.h"
cs->hppi.grp = gicv3_irq_group(cs->gic, cs, cs->hppi.irq);
}
+ if ((cs->gicr_ctlr & GICR_CTLR_ENABLE_LPIS) && cs->gic->lpi_enable &&
+ (cs->gic->gicd_ctlr & GICD_CTLR_EN_GRP1NS) &&
+ (cs->hpplpi.prio != 0xff)) {
+ if (irqbetter(cs, cs->hpplpi.irq, cs->hpplpi.prio)) {
+ cs->hppi.irq = cs->hpplpi.irq;
+ cs->hppi.prio = cs->hpplpi.prio;
+ cs->hppi.grp = cs->hpplpi.grp;
+ seenbetter = true;
+ }
+ }
+
/* If the best interrupt we just found would preempt whatever
* was the previous best interrupt before this update, then
* we know it's definitely the best one now.
* interrupt has reduced in priority and any other interrupt could
* now be the new best one).
*/
- if (!seenbetter && cs->hppi.prio != 0xff && cs->hppi.irq < GIC_INTERNAL) {
+ if (!seenbetter && cs->hppi.prio != 0xff &&
+ (cs->hppi.irq < GIC_INTERNAL ||
+ cs->hppi.irq >= GICV3_LPI_INTID_START)) {
gicv3_full_update_noirqset(cs->gic);
}
}
static void arm_gicv3_post_load(GICv3State *s)
{
+ int i;
/* Recalculate our cached idea of the current highest priority
* pending interrupt, but don't set IRQ or FIQ lines.
*/
+ for (i = 0; i < s->num_cpu; i++) {
+ gicv3_redist_update_lpi_only(&s->cpu[i]);
+ }
gicv3_full_update_noirqset(s);
/* Repopulate the cache of GICv3CPUState pointers for target CPUs */
gicv3_cache_all_target_cpustates(s);
.read_with_attrs = gicv3_dist_read,
.write_with_attrs = gicv3_dist_write,
.endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 1,
+ .impl.max_access_size = 8,
},
{
.read_with_attrs = gicv3_redist_read,
.write_with_attrs = gicv3_redist_write,
.endianness = DEVICE_NATIVE_ENDIAN,
+ .valid.min_access_size = 1,
+ .valid.max_access_size = 8,
+ .impl.min_access_size = 1,
+ .impl.max_access_size = 8,
}
};
return;
}
- if (s->nb_redist_regions != 1) {
- error_setg(errp, "VGICv3 redist region number(%d) not equal to 1",
- s->nb_redist_regions);
- return;
- }
-
- gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops, &local_err);
- if (local_err) {
- error_propagate(errp, local_err);
- return;
- }
+ gicv3_init_irqs_and_mmio(s, gicv3_set_irq, gic_ops);
gicv3_init_cpuif(s);
}