From 96ed7b7438a53e9081c1d6cd43c72bcd3cacd870 Mon Sep 17 00:00:00 2001 From: FDSoftware Date: Mon, 13 Apr 2026 15:43:07 -0300 Subject: [PATCH] SIMIA32: make port_lock/port_unlock nesting-aware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The SIMIA32 simulator port used a simple boolean flag (0/1) for port_lock()/port_unlock(). When ChibiOS timer callbacks call code that uses S-class chSysLock/chSysUnlock (e.g. CriticalSectionLocker inside efiPrintfInternal), chSysUnlock() would reset the flag to 0 even though chSysLockFromISR() had set it to 1 — effectively dropping the ISR lock and corrupting the cooperative scheduler's ready list and delta list. On real ARM hardware this never happens because both S-class and I-class locks manipulate BASEPRI identically, so nesting is implicit. Switch to a counter (++/--) so nested lock/unlock pairs balance correctly, matching the ARM port's behavior. --- os/common/ports/SIMIA32/chcore.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/os/common/ports/SIMIA32/chcore.h b/os/common/ports/SIMIA32/chcore.h index fc0ff0f0a4..3630daf3fe 100644 --- a/os/common/ports/SIMIA32/chcore.h +++ b/os/common/ports/SIMIA32/chcore.h @@ -385,10 +385,16 @@ static inline bool port_is_isr_context(void) { /** * @brief Kernel-lock action. * @details In this port this function disables interrupts globally. + * @note Uses a nesting counter so that an S-class chSysUnlock() from + * ISR context (e.g. CriticalSectionLocker inside a timer callback) + * does not accidentally drop a lock held by chSysLockFromISR(). + * On real ARM hardware both S-class and I-class locks manipulate + * BASEPRI identically, so nesting works implicitly; the simulator + * must emulate that behavior explicitly. */ static inline void port_lock(void) { - port_irq_sts = (syssts_t)1; + port_irq_sts++; } /** @@ -397,7 +403,7 @@ static inline void port_lock(void) { */ static inline void port_unlock(void) { - port_irq_sts = (syssts_t)0; + port_irq_sts--; } /** @@ -407,7 +413,7 @@ static inline void port_unlock(void) { */ static inline void port_lock_from_isr(void) { - port_irq_sts = (syssts_t)1; + port_irq_sts++; } /** @@ -417,7 +423,7 @@ static inline void port_lock_from_isr(void) { */ static inline void port_unlock_from_isr(void) { - port_irq_sts = (syssts_t)0; + port_irq_sts--; } /**