aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2012-12-13 12:48:14 +0100
committerAlexander Graf <agraf@suse.de>2012-12-14 13:12:57 +0100
commit76aec1f8b6549d14576a3eb739c731df8f678ffb (patch)
tree814c024c6aeb43905525d8bbf1ed9ab39241bf4b
parentdbe30e13e87a71e85e88ae3ffd3460173cbc8193 (diff)
downloadqemu-76aec1f8b6549d14576a3eb739c731df8f678ffb.zip
qemu-76aec1f8b6549d14576a3eb739c731df8f678ffb.tar.gz
qemu-76aec1f8b6549d14576a3eb739c731df8f678ffb.tar.bz2
openpic: Accelerate pending irq search
When we're done with one interrupt, we need to search for the next pending interrupt in the queue. This search has grown quite big now that we have more than 256 possible irq lines. So let's memorize how many interrupts we have pending in our bitmaps, so that we can always bail out in the usual case - the one where we're all done. Signed-off-by: Alexander Graf <agraf@suse.de>
-rw-r--r--hw/openpic.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/hw/openpic.c b/hw/openpic.c
index 25d5cd7..3cbcea8 100644
--- a/hw/openpic.c
+++ b/hw/openpic.c
@@ -169,6 +169,7 @@ typedef struct IRQ_queue_t {
uint32_t queue[BF_WIDTH(MAX_IRQ)];
int next;
int priority;
+ int pending; /* nr of pending bits in queue */
} IRQ_queue_t;
typedef struct IRQ_src_t {
@@ -251,11 +252,13 @@ static void openpic_irq_raise(OpenPICState *opp, int n_CPU, IRQ_src_t *src);
static inline void IRQ_setbit(IRQ_queue_t *q, int n_IRQ)
{
+ q->pending++;
set_bit(q->queue, n_IRQ);
}
static inline void IRQ_resetbit(IRQ_queue_t *q, int n_IRQ)
{
+ q->pending--;
reset_bit(q->queue, n_IRQ);
}
@@ -271,6 +274,12 @@ static void IRQ_check(OpenPICState *opp, IRQ_queue_t *q)
next = -1;
priority = -1;
+
+ if (!q->pending) {
+ /* IRQ bitmap is empty */
+ goto out;
+ }
+
for (i = 0; i < opp->max_irq; i++) {
if (IRQ_testbit(q, i)) {
DPRINTF("IRQ_check: irq %d set ipvp_pr=%d pr=%d\n",
@@ -281,6 +290,8 @@ static void IRQ_check(OpenPICState *opp, IRQ_queue_t *q)
}
}
}
+
+out:
q->next = next;
q->priority = priority;
}