ARMv7-M SMP: Applied the latest changes for ARMv7A-SMP

This commit is contained in:
Masayuki Ishikawa
2016-12-04 06:49:49 -06:00
committed by Gregory Nutt
parent 9c65b0321d
commit 84900298b7
3 changed files with 50 additions and 2 deletions
+13
View File
@@ -53,6 +53,7 @@
#include "up_arch.h" #include "up_arch.h"
#include "sched/sched.h" #include "sched/sched.h"
#include "irq/irq.h"
#include "up_internal.h" #include "up_internal.h"
/**************************************************************************** /****************************************************************************
@@ -319,6 +320,12 @@ static void up_dumpstate(void)
#endif #endif
#ifdef CONFIG_SMP
/* Show the CPU number */
_alert("CPU%d:\n", up_cpu_index());
#endif
/* Then dump the registers (if available) */ /* Then dump the registers (if available) */
up_registerdump(); up_registerdump();
@@ -351,6 +358,12 @@ static void _up_assert(int errorcode)
(void)up_irq_save(); (void)up_irq_save();
for (; ; ) for (; ; )
{ {
#ifdef CONFIG_SMP
/* Try (again) to stop activity on other CPUs */
(void)spin_trylock(&g_cpu_irqlock);
#endif
#ifdef CONFIG_ARCH_LEDS #ifdef CONFIG_ARCH_LEDS
board_autoled_on(LED_PANIC); board_autoled_on(LED_PANIC);
up_mdelay(250); up_mdelay(250);
@@ -165,6 +165,19 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#ifdef CONFIG_BUILD_PROTECTED #ifdef CONFIG_BUILD_PROTECTED
CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR; CURRENT_REGS[REG_LR] = EXC_RETURN_PRIVTHR;
#endif #endif
#ifdef CONFIG_SMP
/* In an SMP configuration, the interrupt disable logic also
* involves spinlocks that are configured per the TCB irqcount
* field. This is logically equivalent to enter_critical_section().
* The matching call to leave_critical_section() will be
* performed in up_sigdeliver().
*/
DEBUGASSERT(tcb->irqcount < INT16_MAX);
tcb->irqcount++;
#endif
/* And make sure that the saved context in the TCB is the same /* And make sure that the saved context in the TCB is the same
* as the interrupt return context. * as the interrupt return context.
*/ */
@@ -211,6 +224,19 @@ void up_schedule_sigaction(struct tcb_s *tcb, sig_deliver_t sigdeliver)
#ifdef CONFIG_BUILD_PROTECTED #ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR; tcb->xcp.regs[REG_LR] = EXC_RETURN_PRIVTHR;
#endif #endif
#ifdef CONFIG_SMP
/* In an SMP configuration, the interrupt disable logic also
* involves spinlocks that are configured per the TCB irqcount
* field. This is logically equivalent to enter_critical_section();
* The matching leave_critical_section will be performed in
* The matching call to leave_critical_section() will be performed
* in up_sigdeliver().
*/
DEBUGASSERT(tcb->irqcount < INT16_MAX);
tcb->irqcount++;
#endif
} }
} }
+11 -2
View File
@@ -124,9 +124,9 @@ void up_sigdeliver(void)
/* Then restore the task interrupt state */ /* Then restore the task interrupt state */
#ifdef CONFIG_ARMV7M_USEBASEPRI #ifdef CONFIG_ARMV7M_USEBASEPRI
up_irq_restore((uint8_t)regs[REG_BASEPRI]); leave_critical_section((uint8_t)regs[REG_BASEPRI]);
#else #else
up_irq_restore((uint16_t)regs[REG_PRIMASK]); leave_critical_section((uint16_t)regs[REG_PRIMASK]);
#endif #endif
/* Deliver the signal */ /* Deliver the signal */
@@ -136,9 +136,18 @@ void up_sigdeliver(void)
/* Output any debug messages BEFORE restoring errno (because they may /* Output any debug messages BEFORE restoring errno (because they may
* alter errno), then disable interrupts again and restore the original * alter errno), then disable interrupts again and restore the original
* errno that is needed by the user logic (it is probably EINTR). * errno that is needed by the user logic (it is probably EINTR).
*
* REVISIT: In SMP mode up_irq_save() probably only disables interrupts
* on the local CPU. We do not want to call enter_critical_section()
* here, however, because we don't want this state to stick after the
* call to up_fullcontextrestore().
*
* I would prefer that all interrupts are disabled when
* up_fullcontextrestore() is called, but that may not be necessary.
*/ */
sinfo("Resuming\n"); sinfo("Resuming\n");
(void)up_irq_save(); (void)up_irq_save();
rtcb->pterrno = saved_errno; rtcb->pterrno = saved_errno;