Skip to content

Commit

Permalink
kernel: Enable interrupts for MULTITHREADING=n on supported arch's
Browse files Browse the repository at this point in the history
Some applications have a use case for a tiny MULTITHREADING=n build
(which lacks most of the kernel) but still want special-purpose
drivers in that mode that might need to handle interupts.  This
creates a chicken and egg problem, as arch code (for obvious reasons)
runs _Cstart() with interrupts disabled, and enables them only on
switching into a newly created thread context.  Zephyr does not have a
"turn interrupts on now, please" API at the architecture level.

So this creates one as an arch-specific wrapper around
_arch_irq_unlock().  It's implemented as an optional macro the arch
can define to enable this behavior, falling back to the previous
scheme (and printing a helpful message) if it doesn't find it defined.
Only ARM and x86 are enabled in this patch.

Fixes zephyrproject-rtos#8393

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
  • Loading branch information
Andy Ross authored and pabigot committed Jul 23, 2020
1 parent 6d9d60c commit 9fe2503
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 0 deletions.
3 changes: 3 additions & 0 deletions include/arch/arm/aarch32/asm_inline_gcc.h
Expand Up @@ -108,6 +108,9 @@ static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
#endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */
}

/* Used to unconditionally enable interrupts when MULTITHREADING=n */
#define Z_ARCH_INT_ENABLE() arch_irq_unlock(0)

static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
{
/* This convention works for both PRIMASK and BASEPRI */
Expand Down
3 changes: 3 additions & 0 deletions include/arch/arm/aarch64/asm_inline_gcc.h
Expand Up @@ -65,6 +65,9 @@ static ALWAYS_INLINE void arch_irq_unlock(unsigned int key)
: "memory", "cc");
}

/* Used to unconditionally enable interrupts when MULTITHREADING=n */
#define Z_ARCH_INT_ENABLE() arch_irq_unlock(0)

static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key)
{
/* We only check the (I)RQ bit on the DAIF register */
Expand Down
2 changes: 2 additions & 0 deletions include/arch/x86/arch.h
Expand Up @@ -205,6 +205,8 @@ extern unsigned char _irq_to_interrupt_vector[];
#define Z_IRQ_TO_INTERRUPT_VECTOR(irq) \
((unsigned int) _irq_to_interrupt_vector[irq])

/* Used to unconditionally enable interrupts when MULTITHREADING=n */
#define Z_ARCH_INT_ENABLE() arch_irq_unlock(0x200)

#endif /* _ASMLANGUAGE */

Expand Down
13 changes: 13 additions & 0 deletions kernel/init.c
Expand Up @@ -431,6 +431,18 @@ void z_early_boot_rand_get(uint8_t *buf, size_t length)
/* defined(CONFIG_ENTROPY_HAS_DRIVER) || defined(CONFIG_TEST_RANDOM_GENERATOR) */
#endif

#ifndef CONFIG_MULTITHREADING
static void enable_interrupts(void)
{
#ifdef Z_ARCH_INT_ENABLE
Z_ARCH_INT_ENABLE();
#else
# pragma message "Z_ARCH_INT_ENABLE not defined for this architecture."
# pragma message "Entry to MULTITHREADING=n app code will be with interrupts disabled."
#endif
}
#endif

/**
*
* @brief Initialize kernel
Expand Down Expand Up @@ -476,6 +488,7 @@ FUNC_NORETURN void z_cstart(void)
prepare_multithreading();
switch_to_main_thread();
#else
enable_interrupts();
bg_thread_main(NULL, NULL, NULL);

/* LCOV_EXCL_START
Expand Down

0 comments on commit 9fe2503

Please sign in to comment.