Skip to content

Commit 166cff3

Browse files
committed
Workaround: Implement g_nvic_prio_bits for disabled.c
When __uvisor_mode is UVISOR_DISABLED the NVIC APIs are used instead of the vIRQ ones. Now that those APIs are pre-compiled into a library, the NVIC APIs use the uVisor built-in definitions from cmsis/core_generic.h. In that file __NVIC_PRIO_BITS is re-defined as a global variable which is evaluated at start-up. This behaviour has now been mirrored to the case of disabled uVisor. Warning: This is a workaround. Applications that are written following the uVisor guidelines for the use of vIRQ APIs will work without problems: > The vIRQ_SetVector must be used before any other vIRQ API for any given IRQn slot. While this is currently the case for all mbed OS code, it is not guaranteed to work with new code. For example, if vIRQ_SetPriority is called before vIRQ_SetVector unpredictable behaviour will follow. This issue will be fixed by a more generalized approach to disabled uVisor.
1 parent 255224d commit 166cff3

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

api/src/disabled.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@
2121
#include <stdint.h>
2222
#include <string.h>
2323

24+
/* Number of implemented priority bits */
25+
uint8_t g_nvic_prio_bits;
26+
2427
/* Symbols exported by the mbed linker script */
2528
UVISOR_EXTERN uint32_t __uvisor_cfgtbl_ptr_start;
2629
UVISOR_EXTERN uint32_t __uvisor_cfgtbl_ptr_end;
@@ -186,7 +189,8 @@ static void uvisor_disabled_default_vector(void)
186189

187190
void uvisor_disabled_set_vector(uint32_t irqn, uint32_t vector)
188191
{
189-
uint8_t box_id;
192+
uint8_t prio_bits, box_id;
193+
uint8_t volatile *prio;
190194

191195
/* Check IRQn.
192196
* We only allow user IRQs to be registered (NVIC). This is consistent with
@@ -204,6 +208,17 @@ void uvisor_disabled_set_vector(uint32_t irqn, uint32_t vector)
204208
* user vectors explicitly set using this API are registered in the table. */
205209
if (SCB->VTOR != (uint32_t) g_irq_table) {
206210
SCB->VTOR = (uint32_t) g_irq_table;
211+
212+
/* Detect the number of implemented priority bits.
213+
* The architecture specifies that unused/not implemented bits in the
214+
* NVIC IP registers read back as 0. */
215+
__disable_irq();
216+
prio = (uint8_t volatile *) &(NVIC->IP[0]);
217+
prio_bits = *prio;
218+
*prio = 0xFFU;
219+
g_nvic_prio_bits = (uint8_t) __builtin_popcount(*prio);
220+
*prio = prio_bits;
221+
__enable_irq();
207222
}
208223

209224
/* Register IRQ.

0 commit comments

Comments
 (0)