Possible off-by-one error in priority handling of hw/PL190.c
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Invalid
|
Undecided
|
Marc Bommert |
Bug Description
I have a problem when reading back VECTADDR in my proprietary OS's interrupt handler.
Example client code:
1) Write INTENCLEAR to clear all interrupt enable bits
2) Set all 16 vector control registers to zero
3) Set vector address #2 to value 2
4) Set vector control #2 to 0x21 (vector_
5) Enable interrupt 1 by writing 0x2 to INTENABLE
6) In interrupt handler: read VECTADDR [should read 0x2 (active IRQs vector address as set in step 3), reads 0x0 (active vector address index 3 instead of index 2)]
Problem:
So, for me, the block commented with /* Read vector address at the start of an ISR... */ in hw/pl190.c has an off by-one error and does not return the vector address of the pending interrupt, but of the next one in the list of priorities (i.e. vector address 3).
Solution:
In pl190_update_
I'll try to provide a patch for this.
Changed in qemu: | |
assignee: | nobody → Marc Bommert (brightwise) |
From 0cd0c1346f9adb7 b90df3e4e30a590 4eeda33bfa Mon Sep 17 00:00:00 2001
From: Marc Bommert <email address hidden>
Date: Sun, 26 Feb 2017 22:08:49 +0100
Subject: [PATCH] Fix off-by-one error in priority handling when reading
VECTADDR: Also, if enabled, have the "current" priority bit (1<<i) set in
s->prio_mask[i].
Signed-off-by: Marc Bommert <email address hidden>
---
hw/intc/pl190.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c vectors( PL190State *s) >prio_mask[ 16] = mask; update( s);
index 55ea15d..0369da8 100644
--- a/hw/intc/pl190.c
+++ b/hw/intc/pl190.c
@@ -80,12 +80,12 @@ static void pl190_update_
mask = 0;
for (i = 0; i < 16; i++)
{
- s->prio_mask[i] = mask;
if (s->vect_control[i] & 0x20)
{
n = s->vect_control[i] & 0x1f;
mask |= 1 << n;
}
+ s->prio_mask[i] = mask;
}
s-
pl190_
--
2.5.0