1 From 12d4393d0830a2a63828d302f177a9b8e31f433a Mon Sep 17 00:00:00 2001
2 From: Brendan Fennell <bfennell@skynet.ie>
3 Date: Wed, 26 Sep 2012 16:46:28 +0100
4 Subject: [PATCH] pl190: fix read of VECTADDR
6 Reading VECTADDR was causing us to set the current priority to
7 the wrong value, the most obvious effect of which was that we
8 would return the vector for the wrong interrupt as the result
11 Signed-off-by: Brendan Fennell <bfennell@skynet.ie>
12 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
13 (cherry picked from commit 14c126baf1c38607c5bd988878de85a06cefd8cf)
15 Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
17 hw/pl190.c | 18 ++++++++++++------
18 1 file changed, 12 insertions(+), 6 deletions(-)
20 diff --git a/hw/pl190.c b/hw/pl190.c
21 index cb50afb..7332f4d 100644
24 @@ -117,12 +117,18 @@ static uint64_t pl190_read(void *opaque, target_phys_addr_t offset,
26 case 12: /* VECTADDR */
27 /* Read vector address at the start of an ISR. Increases the
28 - current priority level to that of the current interrupt. */
29 - for (i = 0; i < s->priority; i++)
31 - if ((s->level | s->soft_level) & s->prio_mask[i])
34 + * current priority level to that of the current interrupt.
36 + * Since an enabled interrupt X at priority P causes prio_mask[Y]
37 + * to have bit X set for all Y > P, this loop will stop with
38 + * i == the priority of the highest priority set interrupt.
40 + for (i = 0; i < s->priority; i++) {
41 + if ((s->level | s->soft_level) & s->prio_mask[i + 1]) {
46 /* Reading this value with no pending interrupts is undefined.
47 We return the default address. */
48 if (i == PL190_NUM_PRIO)