qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PULL 15/21] hw/intc/arm_gic: Fix C_RPR value on idle prior


From: Peter Maydell
Subject: [Qemu-devel] [PULL 15/21] hw/intc/arm_gic: Fix C_RPR value on idle priority
Date: Thu, 25 Jan 2018 13:43:23 +0000

From: Luc MICHEL <address@hidden>

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 <address@hidden>
Message-id: address@hidden
Reviewed-by: Peter Maydell <address@hidden>
Signed-off-by: Peter Maydell <address@hidden>
---
 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 dad383e..713de30 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
-- 
2.7.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]