mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-08 10:13:56 -06:00
hw/misc: In STM32L4x5 EXTI, correct configurable interrupts
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> Message-id: 20240629110800.539969-2-ines.varhol@telecom-paris.fr Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
7d9b3c34f3
commit
9c4887e3b6
2 changed files with 15 additions and 15 deletions
|
@ -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()
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue