Priority bits implemented in arm-gic can be 8 to 4, un-implemented bits are read as zeros(RAZ).
Signed-off-by: Sai Pavan Boddu <sai.pavan.bo...@xilinx.com> --- hw/intc/arm_gic.c | 26 ++++++++++++++++++++++++-- hw/intc/arm_gic_common.c | 1 + include/hw/intc/arm_gic_common.h | 1 + 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 1d7da7b..dec8767 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -641,6 +641,23 @@ uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) return ret; } +static uint32_t gic_fullprio_mask(GICState *s, int cpu) +{ + /* + * Return a mask word which clears the unimplemented priority + * bits from a priority value for an interrupt. (Not to be + * confused with the group priority, whose mask depends on BPR.) + */ + int unimpBits; + + if (gic_is_vcpu(cpu)) { + unimpBits = GIC_VIRT_MAX_GROUP_PRIO_BITS; + } else { + unimpBits = 8 - s->n_prio_bits; + } + return ~0U << unimpBits; +} + void gic_dist_set_priority(GICState *s, int cpu, int irq, uint8_t val, MemTxAttrs attrs) { @@ -669,7 +686,7 @@ static uint32_t gic_dist_get_priority(GICState *s, int cpu, int irq, } prio = (prio << 1) & 0xff; /* Non-secure view */ } - return prio; + return prio & gic_fullprio_mask(s, cpu); } static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask, @@ -684,7 +701,7 @@ static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask, return; } } - s->priority_mask[cpu] = pmask; + s->priority_mask[cpu] = pmask & gic_fullprio_mask(s, cpu); } static uint32_t gic_get_priority_mask(GICState *s, int cpu, MemTxAttrs attrs) @@ -2055,6 +2072,11 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) return; } + if (s->n_prio_bits > 8) { + error_setg(errp, "num-priority-bits cannot be greater than 8"); + return; + } + /* This creates distributor, main CPU interface (s->cpuiomem[0]) and if * enabled, virtualization extensions related interfaces (main virtual * interface (s->vifaceiomem[0]) and virtual CPU interface). diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index e6c4fe7..7b44d56 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -357,6 +357,7 @@ static Property arm_gic_common_properties[] = { DEFINE_PROP_BOOL("has-security-extensions", GICState, security_extn, 0), /* True if the GIC should implement the virtualization extensions */ DEFINE_PROP_BOOL("has-virtualization-extensions", GICState, virt_extn, 0), + DEFINE_PROP_UINT32("num-priority-bits", GICState, n_prio_bits, 8), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index b5585fe..6e0d6b8 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -96,6 +96,7 @@ typedef struct GICState { uint16_t priority_mask[GIC_NCPU_VCPU]; uint16_t running_priority[GIC_NCPU_VCPU]; uint16_t current_pending[GIC_NCPU_VCPU]; + uint32_t n_prio_bits; /* If we present the GICv2 without security extensions to a guest, * the guest can configure the GICC_CTLR to configure group 1 binary point -- 2.7.4