From 71aa735b0a12201c2b14a76004ee3a58ff43798c Mon Sep 17 00:00:00 2001 From: Luc MICHEL Date: Thu, 25 Jan 2018 11:45:30 +0000 Subject: [PATCH] hw/intc/arm_gic: Fix C_RPR value on idle priority When there is no active interrupts in the GIC, a read to the C_RPR register should return the value of the "Idle priority", which is either the maximum value an IRQ priority field can be set to, or 0xff. Since the QEMU GIC model implements all the 8 priority bits, the Idle priority is 0xff. Internally, when there is no active interrupt, the running priority value is 0x100. The gic_get_running_priority function returns an uint8_t and thus, truncate this value to 0x00 when returning it. This is wrong since a value of 0x00 correspond to the maximum possible priority. This commit fixes the returned value when the internal value is 0x100. Note that it is correct for the Non-Secure view to return 0xff even though from the NS world point of view, only 7 priority bits are implemented. The specification states that the Idle priority can be 0xff even when not all the 8 priority bits are implemented. This has been verified against a real GICv2 hardware on a Xilinx ZynqMP based board. Regarding the ARM11MPCore version of the GIC, the specification is not clear on that point, so this commit does not alter its behavior. Signed-off-by: Luc MICHEL Message-id: 20180119145756.7629-4-luc.michel@greensocs.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/intc/arm_gic.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index dad383ea12..713de3084f 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -504,6 +504,11 @@ static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value, static uint8_t gic_get_running_priority(GICState *s, int cpu, MemTxAttrs attrs) { + if ((s->revision != REV_11MPCORE) && (s->running_priority[cpu] > 0xff)) { + /* Idle priority */ + return 0xff; + } + if (s->security_extn && !attrs.secure) { if (s->running_priority[cpu] & 0x80) { /* Running priority in upper half of range: return the Non-secure