Skip to content

Commit

Permalink
arm: check active_irq in the common GIC code
Browse files Browse the repository at this point in the history
  • Loading branch information
Axel Heider committed Mar 8, 2023
1 parent 050a01a commit 0c6e69b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 44 deletions.
38 changes: 38 additions & 0 deletions include/arch/arm/arch/machine/gic_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,44 @@ irq_t irqInvalid = (uint16_t) -1;
*/
extern word_t active_irq[CONFIG_MAX_NUM_NODES];

static inline irq_t getActiveIRQ(void)
{
irq_t irq = active_irq[CURRENT_CPU_INDEX()];
if (!IS_IRQ_VALID(irq)) {
irq = arm_gic_get_pending_interrupt();
if (!IS_IRQ_VALID(irq)) {
return irqInvalid;
}
active_irq[CURRENT_CPU_INDEX()] = irq;
}
return CORE_IRQ_TO_IRQT(CURRENT_CPU_INDEX(), irq & IRQ_MASK);
}

static inline void ackInterrupt(irq_t irq)
{
word_t hw_irq = IRQT_TO_IRQ(irq);
if (is_irq_edge_triggered(hw_irq)) {
dist_pending_clr(hw_irq);
}

irq_t a_irq = active_irq[CURRENT_CPU_INDEX()];
if (!IS_IRQ_VALID(a_irq)) {
/* This is not supposed to happen. */
printf("WARNING: can't ack invalid IRQ %d\n", a_irq);
return;
}

if ((a_irq & IRQ_MASK) != hw_irq) {
/* The ack does not match the interrupt currently pending. */
printf("WARNING: ack IRQ %d differs from pending IRQ %d\n", a_irq, hw_irq);
hw_irq = a_irq;
return;
}

arm_gic_ack_interrupt(hw_irq);
active_irq[CURRENT_CPU_INDEX()] = IRQ_NONE;
}

static inline void handleSpuriousIRQ(void)
{
/* Nothing to do here */
Expand Down
28 changes: 7 additions & 21 deletions include/arch/arm/arch/machine/gic_v2.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,20 +156,9 @@ static inline void dist_enable_set(word_t irq)
gic_dist->enable_set[word] = BIT(bit);
}

static inline irq_t getActiveIRQ(void)
static inline irq_t arm_gic_get_pending_interrupt(void)
{
irq_t irq;
if (!IS_IRQ_VALID(active_irq[CURRENT_CPU_INDEX()])) {
active_irq[CURRENT_CPU_INDEX()] = gic_cpuiface->int_ack;
}

if (IS_IRQ_VALID(active_irq[CURRENT_CPU_INDEX()])) {
irq = CORE_IRQ_TO_IRQT(CURRENT_CPU_INDEX(), active_irq[CURRENT_CPU_INDEX()] & IRQ_MASK);
} else {
irq = irqInvalid;
}

return irq;
return gic_cpuiface->int_ack;
}

/*
Expand All @@ -194,16 +183,13 @@ static inline void maskInterrupt(bool_t disable, irq_t irq)
}
}

static inline void ackInterrupt(irq_t irq)
static inline void arm_gic_ack_interrupt(irq_t irq)
{
assert(IS_IRQ_VALID(active_irq[CURRENT_CPU_INDEX()])
&& (active_irq[CURRENT_CPU_INDEX()] & IRQ_MASK) == IRQT_TO_IRQ(irq));
if (is_irq_edge_triggered(IRQT_TO_IRQ(irq))) {
dist_pending_clr(IRQT_TO_IRQ(irq));
word_t hw_irq = IRQT_TO_IRQ(irq);
if (is_irq_edge_triggered(hw_irq)) {
dist_pending_clr(hw_irq);
}
gic_cpuiface->eoi = active_irq[CURRENT_CPU_INDEX()];
active_irq[CURRENT_CPU_INDEX()] = IRQ_NONE;

gic_cpuiface->eoi = irq;
}


Expand Down
29 changes: 6 additions & 23 deletions include/arch/arm/arch/machine/gic_v3.h
Original file line number Diff line number Diff line change
Expand Up @@ -286,23 +286,11 @@ static inline void gic_enable_set(word_t irq)

}

static inline irq_t getActiveIRQ(void)
static inline irq_t arm_gic_get_pending_interrupt(void)
{
irq_t irq;

if (!IS_IRQ_VALID(active_irq[CURRENT_CPU_INDEX()])) {
uint32_t val = 0;
SYSTEM_READ_WORD(ICC_IAR1_EL1, val);
active_irq[CURRENT_CPU_INDEX()] = val;
}

if (IS_IRQ_VALID(active_irq[CURRENT_CPU_INDEX()])) {
irq = CORE_IRQ_TO_IRQT(CURRENT_CPU_INDEX(), active_irq[CURRENT_CPU_INDEX()] & IRQ_MASK);
} else {
irq = irqInvalid;
}

return irq;
uint32_t val = 0;
SYSTEM_READ_WORD(ICC_IAR1_EL1, val);
return (irq_t)val;
}

/*
Expand Down Expand Up @@ -333,19 +321,14 @@ static inline void maskInterrupt(bool_t disable, irq_t irq)
}
}

static inline void ackInterrupt(irq_t irq)
static inline void arm_ack_interrupt(irq_t irq)
{
word_t hw_irq = IRQT_TO_IRQ(irq);
assert(IS_IRQ_VALID(active_irq[CURRENT_CPU_INDEX()]) && (active_irq[CURRENT_CPU_INDEX()] & IRQ_MASK) == hw_irq);

if (is_irq_edge_triggered(hw_irq)) {
gic_pending_clr(hw_irq);
}

/* Set End of Interrupt for active IRQ: ICC_EOIR1_EL1 */
SYSTEM_WRITE_WORD(ICC_EOIR1_EL1, active_irq[CURRENT_CPU_INDEX()]);
active_irq[CURRENT_CPU_INDEX()] = IRQ_NONE;

SYSTEM_WRITE_WORD(ICC_EOIR1_EL1, hw_irq);
}

#ifdef CONFIG_ARM_HYPERVISOR_SUPPORT
Expand Down

0 comments on commit 0c6e69b

Please sign in to comment.