arch: update g_running_tasks when context switch occurred
When supporting high-priority interrupts, updating the g_running_tasks within a high-priority interrupt may be cause problems. The g_running_tasks should only be updated when it is determined that a task context switch has occurred. Signed-off-by: zhangyuan21 <zhangyuan21@xiaomi.com>
This commit is contained in:
parent
34c56139aa
commit
8f39ba6ae4
@ -32,6 +32,7 @@
|
||||
#include <nuttx/addrenv.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
||||
@ -79,7 +80,6 @@ void arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* CURRENT_REGS will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -89,6 +89,7 @@ void arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
@ -96,9 +97,16 @@ void arm_doirq(int irq, uint32_t *regs)
|
||||
*/
|
||||
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
/* Set CURRENT_REGS to NULL to indicate that we are no longer in an
|
||||
* interrupt handler.
|
||||
*/
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
||||
@ -81,6 +82,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
restore_critical_section();
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "gic.h"
|
||||
@ -70,15 +71,11 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* CURRENT_REGS will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then establish the correct
|
||||
* address environment before returning from the interrupt.
|
||||
*/
|
||||
/* Restore the cpu lock */
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
@ -86,13 +83,15 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
*/
|
||||
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Restore the cpu lock */
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
restore_critical_section();
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
||||
@ -81,6 +82,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
restore_critical_section();
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
|
||||
@ -63,6 +64,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
restore_critical_section();
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "arm_internal.h"
|
||||
#include "exc_return.h"
|
||||
@ -82,6 +83,13 @@ uint32_t *arm_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
restore_critical_section();
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
}
|
||||
|
@ -92,6 +92,13 @@ uint64_t *arm64_doirq(int irq, uint64_t * regs)
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
||||
restore_critical_section();
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "avr_internal.h"
|
||||
|
||||
@ -87,6 +88,16 @@ uint8_t *avr_doirq(uint8_t irq, uint8_t *regs)
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
if (regs != (uint8_t *)g_current_regs)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
regs = (uint8_t *)g_current_regs; /* Cast removes volatile attribute */
|
||||
|
||||
/* Restore the previous value of g_current_regs. NULL would indicate that
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "avr_internal.h"
|
||||
|
||||
@ -74,7 +75,6 @@ uint32_t *avr_doirq(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry.
|
||||
* If an interrupt level context switch has occurred, then restore
|
||||
@ -99,8 +99,14 @@ uint32_t *avr_doirq(int irq, uint32_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
|
@ -78,6 +78,13 @@ uint32_t *ceva_doirq(int irq, uint32_t *regs)
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
restore_critical_section();
|
||||
regs = CURRENT_REGS;
|
||||
}
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "hc_internal.h"
|
||||
|
||||
@ -74,7 +75,6 @@ uint8_t *hc_doirq(int irq, uint8_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -99,8 +99,14 @@ uint8_t *hc_doirq(int irq, uint8_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "mips_internal.h"
|
||||
|
||||
@ -80,7 +81,6 @@ uint32_t *mips_doirq(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -105,8 +105,14 @@ uint32_t *mips_doirq(int irq, uint32_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "lm32.h"
|
||||
|
||||
@ -65,7 +66,6 @@ uint32_t *lm32_doirq(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -90,8 +90,14 @@ uint32_t *lm32_doirq(int irq, uint32_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "minerva.h"
|
||||
|
||||
@ -64,7 +65,6 @@ uint32_t *minerva_doirq(int irq, uint32_t * regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -74,13 +74,13 @@ uint32_t *minerva_doirq(int irq, uint32_t * regs)
|
||||
|
||||
if (regs != g_current_regs)
|
||||
{
|
||||
# ifdef CONFIG_ARCH_FPU
|
||||
#ifdef CONFIG_ARCH_FPU
|
||||
/* Restore floating point registers */
|
||||
|
||||
up_restorefpu((uint32_t *) g_current_regs);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
# ifdef CONFIG_ARCH_ADDRENV
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously running
|
||||
* task is closed down gracefully (data caches dump, MMU flushed) and
|
||||
* set up the address environment for the new thread at the head of
|
||||
@ -88,10 +88,16 @@ uint32_t *minerva_doirq(int irq, uint32_t * regs)
|
||||
*/
|
||||
|
||||
addrenv_switch(NULL);
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
* from the input regs, then the lower level will know that a context
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "or1k_internal.h"
|
||||
|
||||
@ -69,6 +70,16 @@ uint32_t *or1k_doirq(int irq, uint32_t *regs)
|
||||
* switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
if (regs != (uint32_t *)CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
regs = (uint32_t *)CURRENT_REGS;
|
||||
|
||||
/* Restore the previous value of CURRENT_REGS. NULL would indicate that
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "renesas_internal.h"
|
||||
#include "group/group.h"
|
||||
@ -77,7 +78,6 @@ uint32_t *renesas_doirq(int irq, uint32_t * regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry.
|
||||
* If an interrupt level context switch has occurred, then restore the
|
||||
@ -102,9 +102,15 @@ uint32_t *renesas_doirq(int irq, uint32_t * regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
#endif
|
||||
/* Get the current value of regs... it may have changed because
|
||||
* of a context switch performed during interrupt processing.
|
||||
*/
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "riscv_internal.h"
|
||||
|
||||
@ -89,9 +90,9 @@ uintptr_t *riscv_doirq(int irq, uintptr_t *regs)
|
||||
* returning from the interrupt.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully (data caches dump,
|
||||
* MMU flushed) and set up the address environment for the new
|
||||
@ -99,11 +100,15 @@ uintptr_t *riscv_doirq(int irq, uintptr_t *regs)
|
||||
*/
|
||||
|
||||
addrenv_switch(NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
||||
restore_critical_section();
|
||||
|
@ -234,6 +234,7 @@ endif()
|
||||
target_include_directories(nuttx PRIVATE ${CMAKE_BINARY_DIR}/include/nuttx)
|
||||
target_include_directories(nuttx PRIVATE ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
target_include_directories(sim_head PUBLIC ${NUTTX_DIR}/sched)
|
||||
target_sources(sim_head PUBLIC sim_head.c sim_doirq.c)
|
||||
target_sources(arch PRIVATE ${SRCS})
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <nuttx/arch.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "sim_internal.h"
|
||||
|
||||
@ -64,6 +65,16 @@ void *sim_doirq(int irq, void *context)
|
||||
* context switch occurred during interrupt processing.
|
||||
*/
|
||||
|
||||
if (regs != CURRENT_REGS)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
regs = (void *)CURRENT_REGS;
|
||||
|
||||
/* Restore the previous value of CURRENT_REGS. NULL would indicate
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "sparc_internal.h"
|
||||
|
||||
@ -75,7 +76,6 @@ uint32_t *sparc_doirq(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* CURRENT_REGS will have a different value than it did on entry.
|
||||
* If an interrupt level context switch has occurred, then restore
|
||||
@ -100,8 +100,14 @@ uint32_t *sparc_doirq(int irq, uint32_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* CURRENT_REGS may have change value. If we return any value different
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/io.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "x86_internal.h"
|
||||
|
||||
@ -90,7 +91,6 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -115,8 +115,14 @@ static uint32_t *common_handler(int irq, uint32_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
|
@ -77,7 +77,6 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_FPU) || defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* g_current_regs will have a different value than it did on entry. If an
|
||||
* interrupt level context switch has occurred, then restore the floating
|
||||
@ -102,8 +101,14 @@ static uint64_t *common_handler(int irq, uint64_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* If a context switch occurred while processing the interrupt then
|
||||
* g_current_regs may have change value. If we return any value different
|
||||
|
@ -66,7 +66,6 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#if defined(CONFIG_ARCH_ADDRENV)
|
||||
/* Check for a context switch. If a context switch occurred, then
|
||||
* CURRENT_REGS will have a different value than it did on entry.
|
||||
*/
|
||||
@ -82,8 +81,14 @@ uint32_t *xtensa_irq_dispatch(int irq, uint32_t *regs)
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Restore the cpu lock */
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <nuttx/arch.h>
|
||||
#include <nuttx/board.h>
|
||||
#include <arch/board/board.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "chip.h"
|
||||
#include "z16_internal.h"
|
||||
@ -84,6 +85,16 @@ FAR chipreg_t *z16_doirq(int irq, FAR chipreg_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
if (regs != g_current_regs)
|
||||
{
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
/* Restore the previous value of g_current_regs. NULL would indicate
|
||||
* that we are no longer in an interrupt handler. It will be non-NULL
|
||||
* if we are returning from a nested interrupt.
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <nuttx/board.h>
|
||||
|
||||
#include <arch/irq.h>
|
||||
#include <sched/sched.h>
|
||||
|
||||
#include "chip/switch.h"
|
||||
#include "z80_internal.h"
|
||||
@ -69,13 +70,13 @@ FAR chipreg_t *z80_doirq(uint8_t irq, FAR chipreg_t *regs)
|
||||
|
||||
irq_dispatch(irq, regs);
|
||||
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* If a context switch occurred, 'newregs' will hold the new context */
|
||||
|
||||
newregs = IRQ_STATE();
|
||||
|
||||
if (newregs != regs)
|
||||
{
|
||||
#ifdef CONFIG_ARCH_ADDRENV
|
||||
/* Make sure that the address environment for the previously
|
||||
* running task is closed down gracefully and set up the
|
||||
* address environment for the new thread at the head of the
|
||||
@ -83,16 +84,18 @@ FAR chipreg_t *z80_doirq(uint8_t irq, FAR chipreg_t *regs)
|
||||
*/
|
||||
|
||||
addrenv_switch(NULL);
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task when context switch occurred.
|
||||
* g_running_tasks[] is only used by assertion logic for reporting
|
||||
* crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
||||
regs = newregs;
|
||||
|
||||
#else
|
||||
/* If a context switch occurred, 'regs' will hold the new context */
|
||||
|
||||
regs = IRQ_STATE();
|
||||
#endif
|
||||
|
||||
/* Indicate that we are no longer in interrupt processing logic */
|
||||
|
||||
IRQ_LEAVE(irq);
|
||||
|
@ -182,10 +182,4 @@ void irq_dispatch(int irq, FAR void *context)
|
||||
kmm_checkcorruption();
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Record the new "running" task. g_running_tasks[] is only used by
|
||||
* assertion logic for reporting crashes.
|
||||
*/
|
||||
|
||||
g_running_tasks[this_cpu()] = this_task();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user