[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 1/2] hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
From: |
Inès Varhol |
Subject: |
[PATCH 1/2] hw/misc: In STM32L4x5 EXTI, correct configurable interrupts |
Date: |
Sat, 29 Jun 2024 13:07:08 +0200 |
The implementation of configurable interrupts (interrupts supporting
edge selection) was incorrectly expecting alternating input levels :
this commits adds a new status field `irq_levels` to actually detect
edges.
Signed-off-by: Inès Varhol <ines.varhol@telecom-paris.fr>
---
include/hw/misc/stm32l4x5_exti.h | 2 ++
hw/misc/stm32l4x5_exti.c | 28 +++++++++++++---------------
2 files changed, 15 insertions(+), 15 deletions(-)
diff --git a/include/hw/misc/stm32l4x5_exti.h b/include/hw/misc/stm32l4x5_exti.h
index be961d2f01..55f763fa37 100644
--- a/include/hw/misc/stm32l4x5_exti.h
+++ b/include/hw/misc/stm32l4x5_exti.h
@@ -45,6 +45,8 @@ struct Stm32l4x5ExtiState {
uint32_t swier[EXTI_NUM_REGISTER];
uint32_t pr[EXTI_NUM_REGISTER];
+ /* used for edge detection */
+ uint32_t irq_levels[EXTI_NUM_REGISTER];
qemu_irq irq[EXTI_NUM_INTERRUPT_OUT_LINES];
};
diff --git a/hw/misc/stm32l4x5_exti.c b/hw/misc/stm32l4x5_exti.c
index 495a0004ab..6a2ec62d78 100644
--- a/hw/misc/stm32l4x5_exti.c
+++ b/hw/misc/stm32l4x5_exti.c
@@ -88,6 +88,7 @@ static void stm32l4x5_exti_reset_hold(Object *obj, ResetType
type)
s->ftsr[bank] = 0x00000000;
s->swier[bank] = 0x00000000;
s->pr[bank] = 0x00000000;
+ s->irq_levels[bank] = 0x00000000;
}
}
@@ -102,27 +103,23 @@ static void stm32l4x5_exti_set_irq(void *opaque, int irq,
int level)
/* Shift the value to enable access in x2 registers. */
irq %= EXTI_MAX_IRQ_PER_BANK;
+ if (level == extract32(s->irq_levels[bank], irq, 1)) {
+ /* No change in IRQ line state: do nothing */
+ return;
+ }
+ s->irq_levels[bank] = deposit32(s->irq_levels[bank], irq, 1, level);
+
/* If the interrupt is masked, pr won't be raised */
if (!extract32(s->imr[bank], irq, 1)) {
return;
}
- if (((1 << irq) & s->rtsr[bank]) && level) {
- /* Rising Edge */
- s->pr[bank] |= 1 << irq;
- qemu_irq_pulse(s->irq[oirq]);
- } else if (((1 << irq) & s->ftsr[bank]) && !level) {
- /* Falling Edge */
+ if ((level && extract32(s->rtsr[bank], irq, 1)) ||
+ (!level && extract32(s->ftsr[bank], irq, 1))) {
+
s->pr[bank] |= 1 << irq;
qemu_irq_pulse(s->irq[oirq]);
}
- /*
- * In the following situations :
- * - falling edge but rising trigger selected
- * - rising edge but falling trigger selected
- * - no trigger selected
- * No action is required
- */
}
static uint64_t stm32l4x5_exti_read(void *opaque, hwaddr addr,
@@ -255,8 +252,8 @@ static void stm32l4x5_exti_init(Object *obj)
static const VMStateDescription vmstate_stm32l4x5_exti = {
.name = TYPE_STM32L4X5_EXTI,
- .version_id = 1,
- .minimum_version_id = 1,
+ .version_id = 2,
+ .minimum_version_id = 2,
.fields = (VMStateField[]) {
VMSTATE_UINT32_ARRAY(imr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(emr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
@@ -264,6 +261,7 @@ static const VMStateDescription vmstate_stm32l4x5_exti = {
VMSTATE_UINT32_ARRAY(ftsr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(swier, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
VMSTATE_UINT32_ARRAY(pr, Stm32l4x5ExtiState, EXTI_NUM_REGISTER),
+ VMSTATE_UINT32_ARRAY(irq_levels, Stm32l4x5ExtiState,
EXTI_NUM_REGISTER),
VMSTATE_END_OF_LIST()
}
};
--
2.43.2