<div dir="ltr"><span style="font-size:12.8px">I don't necessarily see anything wrong but I don't see the overall design</span><div style="font-size:12.8px">and execution flow from the code. Is there some documentation?</div><div style="font-size:12.8px"><br></div><div style="font-size:12.8px">Sorry.. used the wrong reply to email address and it didn't hit the list.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Mar 3, 2016 at 8:47 AM, Sebastian Huber <span dir="ltr"><<a href="mailto:sebastian.huber@embedded-brains.de" target="_blank">sebastian.huber@embedded-brains.de</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Update #2554.<br>
---<br>
.../libbsp/arm/shared/arm-a9mpcore-clock-config.c | 68 +++++++++++++++++++---<br>
c/src/lib/libbsp/arm/shared/arm-gic-irq.c | 18 ++++++<br>
c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h | 5 ++<br>
c/src/lib/libbsp/i386/pc386/clock/ckinit.c | 15 +++--<br>
c/src/lib/libbsp/i386/shared/smp/smp-imps.c | 11 +++-<br>
.../lib/libbsp/powerpc/qoriq/clock/clock-config.c | 9 ++-<br>
c/src/lib/libbsp/powerpc/qoriq/include/irq.h | 5 ++<br>
c/src/lib/libbsp/powerpc/qoriq/irq/irq.c | 20 ++++---<br>
c/src/lib/libbsp/shared/clockdrv_shell.h | 12 ++++<br>
c/src/lib/libbsp/shared/include/fatal.h | 1 +<br>
c/src/lib/libbsp/sparc/erc32/clock/ckinit.c | 5 ++<br>
c/src/lib/libbsp/sparc/leon3/clock/ckinit.c | 11 ++++<br>
cpukit/score/include/rtems/score/smpimpl.h | 34 +++++++----<br>
cpukit/score/include/rtems/score/watchdogimpl.h | 7 ++-<br>
cpukit/score/src/kern_tc.c | 9 ++-<br>
cpukit/score/src/smp.c | 5 +-<br>
cpukit/score/src/watchdogtick.c | 10 ++--<br>
17 files changed, 199 insertions(+), 46 deletions(-)<br>
<br>
diff --git a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c<br>
index 8e2e153..3dcf708 100644<br>
--- a/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c<br>
+++ b/c/src/lib/libbsp/arm/shared/arm-a9mpcore-clock-config.c<br>
@@ -1,5 +1,5 @@<br>
/*<br>
- * Copyright (c) 2013-2015 embedded brains GmbH. All rights reserved.<br>
+ * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved.<br>
*<br>
* embedded brains GmbH<br>
* Dornierstr. 4<br>
@@ -15,9 +15,11 @@<br>
#include <bsp.h><br>
#include <bsp/fatal.h><br>
#include <bsp/irq.h><br>
+#include <bsp/irq-generic.h><br>
#include <bsp/arm-a9mpcore-regs.h><br>
#include <bsp/arm-a9mpcore-clock.h><br>
#include <rtems/timecounter.h><br>
+#include <rtems/score/smpimpl.h><br>
<br>
#define A9MPCORE_GT ((volatile a9mpcore_gt *) BSP_ARM_A9MPCORE_GT_BASE)<br>
<br>
@@ -77,6 +79,60 @@ static uint32_t a9mpcore_clock_get_timecount(struct timecounter *tc)<br>
return gt->cntrlower;<br>
}<br>
<br>
+static void a9mpcore_clock_gt_init(<br>
+ volatile a9mpcore_gt *gt,<br>
+ uint64_t cmpval,<br>
+ uint32_t interval<br>
+)<br>
+{<br>
+ gt->cmpvallower = (uint32_t) cmpval;<br>
+ gt->cmpvalupper = (uint32_t) (cmpval >> 32);<br>
+ gt->autoinc = interval;<br>
+ gt->ctrl = A9MPCORE_GT_CTRL_AUTOINC_EN<br>
+ | A9MPCORE_GT_CTRL_IRQ_EN<br>
+ | A9MPCORE_GT_CTRL_COMP_EN<br>
+ | A9MPCORE_GT_CTRL_TMR_EN;<br>
+}<br>
+<br>
+#ifdef RTEMS_SMP<br>
+typedef struct {<br>
+ uint64_t cmpval;<br>
+ uint32_t interval;<br>
+} a9mpcore_clock_init_data;<br>
+<br>
+static void a9mpcore_clock_secondary_action(void *arg)<br>
+{<br>
+ volatile a9mpcore_gt *gt = A9MPCORE_GT;<br>
+ a9mpcore_clock_init_data *init_data = arg;<br>
+<br>
+ a9mpcore_clock_gt_init(gt, init_data->cmpval, init_data->interval);<br>
+ bsp_interrupt_vector_enable(A9MPCORE_IRQ_GT);<br>
+}<br>
+#endif<br>
+<br>
+static void a9mpcore_clock_secondary_initialization(<br>
+ volatile a9mpcore_gt *gt,<br>
+ uint64_t cmpval,<br>
+ uint32_t interval<br>
+)<br>
+{<br>
+#ifdef RTEMS_SMP<br>
+ a9mpcore_clock_init_data init_data = {<br>
+ .cmpval = cmpval,<br>
+ .interval = interval<br>
+ };<br>
+<br>
+ _SMP_Before_multitasking_action_broadcast(<br>
+ a9mpcore_clock_secondary_action,<br>
+ &init_data<br>
+ );<br>
+<br>
+ if (cmpval - a9mpcore_clock_get_counter(gt) >= interval) {<br>
+ bsp_fatal(BSP_ARM_A9MPCORE_FATAL_CLOCK_SMP_INIT);<br>
+ }<br>
+#endif<br>
+}<br>
+<br>
static void a9mpcore_clock_initialize(void)<br>
{<br>
volatile a9mpcore_gt *gt = A9MPCORE_GT;<br>
@@ -91,14 +147,8 @@ static void a9mpcore_clock_initialize(void)<br>
cmpval = a9mpcore_clock_get_counter(gt);<br>
cmpval += interval;<br>
<br>
- gt->cmpvallower = (uint32_t) cmpval;<br>
- gt->cmpvalupper = (uint32_t) (cmpval >> 32);<br>
- gt->autoinc = interval;<br>
-<br>
- gt->ctrl = A9MPCORE_GT_CTRL_AUTOINC_EN<br>
- | A9MPCORE_GT_CTRL_IRQ_EN<br>
- | A9MPCORE_GT_CTRL_COMP_EN<br>
- | A9MPCORE_GT_CTRL_TMR_EN;<br>
+ a9mpcore_clock_gt_init(gt, cmpval, interval);<br>
+ a9mpcore_clock_secondary_initialization(gt, cmpval, interval);<br>
<br>
a9mpcore_tc.tc_get_timecount = a9mpcore_clock_get_timecount;<br>
a9mpcore_tc.tc_counter_mask = 0xffffffff;<br>
diff --git a/c/src/lib/libbsp/arm/shared/arm-gic-irq.c b/c/src/lib/libbsp/arm/shared/arm-gic-irq.c<br>
index 7623489..487ee16 100644<br>
--- a/c/src/lib/libbsp/arm/shared/arm-gic-irq.c<br>
+++ b/c/src/lib/libbsp/arm/shared/arm-gic-irq.c<br>
@@ -164,3 +164,21 @@ rtems_status_code arm_gic_irq_get_priority(<br>
<br>
return sc;<br>
}<br>
+<br>
+rtems_status_code arm_gic_irq_set_affinity(<br>
+ rtems_vector_number vector,<br>
+ uint8_t targets<br>
+)<br>
+{<br>
+ rtems_status_code sc = RTEMS_SUCCESSFUL;<br>
+<br>
+ if (bsp_interrupt_is_valid_vector(vector)) {<br>
+ volatile gic_dist *dist = ARM_GIC_DIST;<br>
+<br>
+ gic_id_set_targets(dist, vector, targets);<br>
+ } else {<br>
+ sc = RTEMS_INVALID_ID;<br>
+ }<br>
+<br>
+ return sc;<br>
+}<br>
diff --git a/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h b/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h<br>
index 7765c00..a8c29bb 100644<br>
--- a/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h<br>
+++ b/c/src/lib/libbsp/arm/shared/include/arm-gic-irq.h<br>
@@ -58,6 +58,11 @@ rtems_status_code arm_gic_irq_get_priority(<br>
uint8_t *priority<br>
);<br>
<br>
+rtems_status_code arm_gic_irq_set_affinity(<br>
+ rtems_vector_number vector,<br>
+ uint8_t targets<br>
+);<br>
+<br>
typedef enum {<br>
ARM_GIC_IRQ_SOFTWARE_IRQ_TO_ALL_IN_LIST,<br>
ARM_GIC_IRQ_SOFTWARE_IRQ_TO_ALL_EXCEPT_SELF,<br>
diff --git a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c<br>
index 04514d1..2291839 100644<br>
--- a/c/src/lib/libbsp/i386/pc386/clock/ckinit.c<br>
+++ b/c/src/lib/libbsp/i386/pc386/clock/ckinit.c<br>
@@ -65,11 +65,10 @@ extern volatile uint32_t Clock_driver_ticks;<br>
} while (0)<br>
<br>
<br>
-/*<br>
- * Hooks which get swapped based upon which nanoseconds since last<br>
- * tick method is preferred.<br>
- */<br>
-#define Clock_driver_support_at_tick()<br>
+#ifdef RTEMS_SMP<br>
+#define Clock_driver_support_at_tick() \<br>
+ _SMP_Send_message_broadcast(SMP_MESSAGE_CLOCK_TICK)<br>
+#endif<br>
<br>
#define Clock_driver_support_install_isr( _new, _old ) \<br>
do { \<br>
@@ -203,6 +202,12 @@ void Clock_driver_install_handler(void)<br>
clockOn();<br>
}<br>
<br>
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \<br>
+ do { \<br>
+ /* FIXME: Is there a way to do this on x86? */ \<br>
+ (void) online_processors; \<br>
+ } while (0)<br>
+<br>
void Clock_driver_support_initialize_hardware(void)<br>
{<br>
bool use_tsc = false;<br>
diff --git a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c<br>
index 158a45d..819c65d 100644<br>
--- a/c/src/lib/libbsp/i386/shared/smp/smp-imps.c<br>
+++ b/c/src/lib/libbsp/i386/shared/smp/smp-imps.c<br>
@@ -744,13 +744,22 @@ static void smp_apic_ack(void)<br>
IMPS_LAPIC_WRITE(LAPIC_EOI, 0 ); /* ACK the interrupt */<br>
}<br>
<br>
+/* FIXME: There should be a header file for this */<br>
+void Clock_isr(void *arg);<br>
+<br>
static void bsp_inter_processor_interrupt(void *arg)<br>
{<br>
+ unsigned long message;<br>
+<br>
(void) arg;<br>
<br>
smp_apic_ack();<br>
<br>
- _SMP_Inter_processor_interrupt_handler();<br>
+ message = _SMP_Inter_processor_interrupt_handler();<br>
+<br>
+ if ((message & SMP_MESSAGE_CLOCK_TICK) != 0) {<br>
+ Clock_isr(NULL);<br>
+ }<br>
}<br>
<br>
static void ipi_install_irq(void)<br>
diff --git a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c<br>
index 8da927f..17d4bde 100644<br>
--- a/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c<br>
+++ b/c/src/lib/libbsp/powerpc/qoriq/clock/clock-config.c<br>
@@ -7,7 +7,7 @@<br>
*/<br>
<br>
/*<br>
- * Copyright (c) 2011-2015 embedded brains GmbH. All rights reserved.<br>
+ * Copyright (c) 2011, 2016 embedded brains GmbH. All rights reserved.<br>
*<br>
* embedded brains GmbH<br>
* Dornierstr. 4<br>
@@ -55,6 +55,7 @@ static void qoriq_clock_handler_install(rtems_isr_entry *old_isr)<br>
<br>
*old_isr = NULL;<br>
<br>
+#if defined(RTEMS_MULTIPROCESSING) && !defined(RTEMS_SMP)<br>
sc = qoriq_pic_set_affinity(<br>
CLOCK_INTERRUPT,<br>
ppc_processor_id()<br>
@@ -62,6 +63,7 @@ static void qoriq_clock_handler_install(rtems_isr_entry *old_isr)<br>
if (sc != RTEMS_SUCCESSFUL) {<br>
rtems_fatal_error_occurred(0xdeadbeef);<br>
}<br>
+#endif<br>
<br>
sc = qoriq_pic_set_priority(<br>
CLOCK_INTERRUPT,<br>
@@ -126,8 +128,13 @@ static void qoriq_clock_cleanup(void)<br>
<br>
#define Clock_driver_support_initialize_hardware() \<br>
qoriq_clock_initialize()<br>
+<br>
#define Clock_driver_support_install_isr(clock_isr, old_isr) \<br>
qoriq_clock_handler_install(&old_isr)<br>
+<br>
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \<br>
+ qoriq_pic_set_affinities(CLOCK_INTERRUPT, online_processors[0])<br>
+<br>
#define Clock_driver_support_shutdown_hardware() \<br>
qoriq_clock_cleanup()<br>
<br>
diff --git a/c/src/lib/libbsp/powerpc/qoriq/include/irq.h b/c/src/lib/libbsp/powerpc/qoriq/include/irq.h<br>
index 1363ec3..fb7be65 100644<br>
--- a/c/src/lib/libbsp/powerpc/qoriq/include/irq.h<br>
+++ b/c/src/lib/libbsp/powerpc/qoriq/include/irq.h<br>
@@ -377,6 +377,11 @@ rtems_status_code qoriq_pic_set_affinity(<br>
uint32_t processor_index<br>
);<br>
<br>
+rtems_status_code qoriq_pic_set_affinities(<br>
+ rtems_vector_number vector,<br>
+ uint32_t processor_affinities<br>
+);<br>
+<br>
/** @} */<br>
<br>
#ifdef __cplusplus<br>
diff --git a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c<br>
index 6bc70ce..da7def3 100644<br>
--- a/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c<br>
+++ b/c/src/lib/libbsp/powerpc/qoriq/irq/irq.c<br>
@@ -147,21 +147,17 @@ rtems_status_code qoriq_pic_set_priority(<br>
return sc;<br>
}<br>
<br>
-rtems_status_code qoriq_pic_set_affinity(<br>
+rtems_status_code qoriq_pic_set_affinities(<br>
rtems_vector_number vector,<br>
- uint32_t processor_index<br>
+ uint32_t processor_affinities<br>
)<br>
{<br>
rtems_status_code sc = RTEMS_SUCCESSFUL;<br>
<br>
if (bsp_interrupt_is_valid_vector(vector)) {<br>
- if (processor_index <= 1) {<br>
- volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);<br>
+ volatile qoriq_pic_src_cfg *src_cfg = get_src_cfg(vector);<br>
<br>
- src_cfg->dr = BSP_BIT32(processor_index);<br>
- } else {<br>
- sc = RTEMS_INVALID_NUMBER;<br>
- }<br>
+ src_cfg->dr = processor_affinities;<br>
} else {<br>
sc = RTEMS_INVALID_ID;<br>
}<br>
@@ -169,6 +165,14 @@ rtems_status_code qoriq_pic_set_affinity(<br>
return sc;<br>
}<br>
<br>
+rtems_status_code qoriq_pic_set_affinity(<br>
+ rtems_vector_number vector,<br>
+ uint32_t processor_index<br>
+)<br>
+{<br>
+ return qoriq_pic_set_affinities(vector, BSP_BIT32(processor_index));<br>
+}<br>
+<br>
static rtems_status_code pic_vector_enable(rtems_vector_number vector, uint32_t msk)<br>
{<br>
rtems_status_code sc = RTEMS_SUCCESSFUL;<br>
diff --git a/c/src/lib/libbsp/shared/clockdrv_shell.h b/c/src/lib/libbsp/shared/clockdrv_shell.h<br>
index 9bf5d9b..af03861 100644<br>
--- a/c/src/lib/libbsp/shared/clockdrv_shell.h<br>
+++ b/c/src/lib/libbsp/shared/clockdrv_shell.h<br>
@@ -20,6 +20,7 @@<br>
#include <bsp.h><br>
#include <rtems/clockdrv.h><br>
#include <rtems/score/percpu.h><br>
+#include <rtems/score/smpimpl.h><br>
<br>
#ifdef Clock_driver_nanoseconds_since_last_tick<br>
#error "Update driver to use the timecounter instead of nanoseconds extension"<br>
@@ -51,6 +52,13 @@<br>
#define Clock_driver_support_at_tick()<br>
#endif<br>
<br>
+/**<br>
+ * @brief Do nothing by default.<br>
+ */<br>
+#ifndef Clock_driver_support_set_interrupt_affinity<br>
+ #define Clock_driver_support_set_interrupt_affinity(online_processors)<br>
+#endif<br>
+<br>
/*<br>
* A specialized clock driver may use for example rtems_timecounter_tick_simple()<br>
* instead of the default.<br>
@@ -199,6 +207,10 @@ rtems_device_driver Clock_initialize(<br>
(void) Old_ticker;<br>
Clock_driver_support_install_isr( Clock_isr, Old_ticker );<br>
<br>
+ #ifdef RTEMS_SMP<br>
+ Clock_driver_support_set_interrupt_affinity( _SMP_Online_processors );<br>
+ #endif<br>
+<br>
/*<br>
* Now initialize the hardware that is the source of the tick ISR.<br>
*/<br>
diff --git a/c/src/lib/libbsp/shared/include/fatal.h b/c/src/lib/libbsp/shared/include/fatal.h<br>
index 6c390d0..25dda39 100644<br>
--- a/c/src/lib/libbsp/shared/include/fatal.h<br>
+++ b/c/src/lib/libbsp/shared/include/fatal.h<br>
@@ -47,6 +47,7 @@ typedef enum {<br>
BSP_ARM_PL111_FATAL_REGISTER_DEV,<br>
BSP_ARM_PL111_FATAL_SEM_CREATE,<br>
BSP_ARM_PL111_FATAL_SEM_RELEASE,<br>
+ BSP_ARM_A9MPCORE_FATAL_CLOCK_SMP_INIT,<br>
<br>
/* LEON3 fatal codes */<br>
LEON3_FATAL_NO_IRQMP_CONTROLLER = BSP_FATAL_CODE_BLOCK(2),<br>
diff --git a/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c b/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c<br>
index f2d493e..d78fb0e 100644<br>
--- a/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c<br>
+++ b/c/src/lib/libbsp/sparc/erc32/clock/ckinit.c<br>
@@ -41,6 +41,11 @@<br>
_old = set_vector( _new, CLOCK_VECTOR, 1 ); \<br>
} while(0)<br>
<br>
+#define Clock_driver_support_set_interrupt_affinity( _online_processors ) \<br>
+ do { \<br>
+ (void) _online_processors; \<br>
+ } while (0)<br>
+<br>
extern int CLOCK_SPEED;<br>
<br>
static rtems_timecounter_simple erc32_tc;<br>
diff --git a/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c b/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c<br>
index 5d645dc..601d329 100644<br>
--- a/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c<br>
+++ b/c/src/lib/libbsp/sparc/leon3/clock/ckinit.c<br>
@@ -155,6 +155,17 @@ static void bsp_clock_handler_install(rtems_isr *new)<br>
}<br>
}<br>
<br>
+#define Clock_driver_support_set_interrupt_affinity(online_processors) \<br>
+ do { \<br>
+ uint32_t cpu_count = _SMP_Processor_count; \<br>
+ uint32_t cpu_index; \<br>
+ for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) { \<br>
+ if (_Processor_mask_Is_set(online_processors, cpu_index)) { \<br>
+ BSP_Cpu_Unmask_interrupt(clkirq, cpu_index); \<br>
+ } \<br>
+ } \<br>
+ } while (0)<br>
+<br>
static void leon3_clock_initialize(void)<br>
{<br>
volatile struct irqmp_timestamp_regs *irqmp_ts =<br>
diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h<br>
index 59a99ec..d1b7214 100644<br>
--- a/cpukit/score/include/rtems/score/smpimpl.h<br>
+++ b/cpukit/score/include/rtems/score/smpimpl.h<br>
@@ -60,6 +60,16 @@ extern "C" {<br>
#define SMP_MESSAGE_MULTICAST_ACTION 0x4UL<br>
<br>
/**<br>
+ * @brief SMP message to request a clock tick.<br>
+ *<br>
+ * This message is provided for systems without a proper interrupt affinity<br>
+ * support and may be used by the clock driver.<br>
+ *<br>
+ * @see _SMP_Send_message().<br>
+ */<br>
+#define SMP_MESSAGE_CLOCK_TICK 0x8UL<br>
+<br>
+/**<br>
* @brief SMP fatal codes.<br>
*/<br>
typedef enum {<br>
@@ -152,10 +162,13 @@ void _SMP_Multicast_actions_process( void );<br>
<br>
/**<br>
* @brief Interrupt handler for inter-processor interrupts.<br>
+ *<br>
+ * @return The received message.<br>
*/<br>
-static inline void _SMP_Inter_processor_interrupt_handler( void )<br>
+static inline long unsigned _SMP_Inter_processor_interrupt_handler( void )<br>
{<br>
Per_CPU_Control *cpu_self = _Per_CPU_Get();<br>
+ unsigned long message = 0;<br>
<br>
/*<br>
* In the common case the inter-processor interrupt is issued to carry out a<br>
@@ -164,7 +177,7 @@ static inline void _SMP_Inter_processor_interrupt_handler( void )<br>
cpu_self->dispatch_necessary = true;<br>
<br>
if ( _Atomic_Load_ulong( &cpu_self->message, ATOMIC_ORDER_RELAXED ) != 0 ) {<br>
- unsigned long message = _Atomic_Exchange_ulong(<br>
+ message = _Atomic_Exchange_ulong(<br>
&cpu_self->message,<br>
0UL,<br>
ATOMIC_ORDER_RELAXED<br>
@@ -183,6 +196,8 @@ static inline void _SMP_Inter_processor_interrupt_handler( void )<br>
_SMP_Multicast_actions_process();<br>
}<br>
}<br>
+<br>
+ return message;<br>
}<br>
<br>
/**<br>
@@ -197,7 +212,7 @@ static inline void _SMP_Inter_processor_interrupt_handler( void )<br>
bool _SMP_Should_start_processor( uint32_t cpu_index );<br>
<br>
/**<br>
- * @brief Sends a SMP message to a processor.<br>
+ * @brief Sends an SMP message to a processor.<br>
*<br>
* The target processor may be the sending processor.<br>
*<br>
@@ -207,21 +222,16 @@ bool _SMP_Should_start_processor( uint32_t cpu_index );<br>
void _SMP_Send_message( uint32_t cpu_index, unsigned long message );<br>
<br>
/**<br>
- * @brief Request of others CPUs.<br>
+ * @brief Sends an SMP message to all other online processors.<br>
*<br>
- * This method is invoked by RTEMS when it needs to make a request<br>
- * of the other CPUs. It should be implemented using some type of<br>
- * interprocessor interrupt. CPUs not including the originating<br>
- * CPU should receive the message.<br>
- *<br>
- * @param [in] message is message to send<br>
+ * @param[in] message The message.<br>
*/<br>
void _SMP_Send_message_broadcast(<br>
unsigned long message<br>
);<br>
<br>
/**<br>
- * @brief Sends a SMP message to a set of processors.<br>
+ * @brief Sends an SMP message to a set of processors.<br>
*<br>
* The sending processor may be part of the set.<br>
*<br>
@@ -238,7 +248,7 @@ void _SMP_Send_message_multicast(<br>
typedef void ( *SMP_Action_handler )( void *arg );<br>
<br>
/**<br>
- * @brief Initiates a SMP multicast action to a set of processors.<br>
+ * @brief Initiates an SMP multicast action to a set of processors.<br>
*<br>
* The current processor may be part of the set.<br>
*<br>
diff --git a/cpukit/score/include/rtems/score/watchdogimpl.h b/cpukit/score/include/rtems/score/watchdogimpl.h<br>
index 8064c77..49ac2a1 100644<br>
--- a/cpukit/score/include/rtems/score/watchdogimpl.h<br>
+++ b/cpukit/score/include/rtems/score/watchdogimpl.h<br>
@@ -23,6 +23,7 @@<br>
#include <rtems/score/assert.h><br>
#include <rtems/score/chainimpl.h><br>
#include <rtems/score/isrlock.h><br>
+#include <rtems/score/percpu.h><br>
<br>
#ifdef __cplusplus<br>
extern "C" {<br>
@@ -139,11 +140,11 @@ RTEMS_INLINE_ROUTINE void _Watchdog_Flash(<br>
void _Watchdog_Handler_initialization( void );<br>
<br>
/**<br>
- * @brief Triggers a watchdog tick.<br>
+ * @brief Performs a watchdog tick.<br>
*<br>
- * This routine executes TOD, watchdog and scheduler ticks.<br>
+ * @param cpu The processor for this watchdog tick.<br>
*/<br>
-void _Watchdog_Tick( void );<br>
+void _Watchdog_Tick( Per_CPU_Control *cpu );<br>
<br>
/**<br>
* @brief Removes @a the_watchdog from the watchdog chain.<br>
diff --git a/cpukit/score/src/kern_tc.c b/cpukit/score/src/kern_tc.c<br>
index 16d76a1..e56c292 100644<br>
--- a/cpukit/score/src/kern_tc.c<br>
+++ b/cpukit/score/src/kern_tc.c<br>
@@ -1974,10 +1974,15 @@ tc_ticktock(int cnt)<br>
void<br>
_Timecounter_Tick(void)<br>
{<br>
+ Per_CPU_Control *cpu_self = _Per_CPU_Get();<br>
+<br>
+ if (_Per_CPU_Is_boot_processor(cpu_self)) {<br>
#endif /* __rtems__ */<br>
tc_windup();<br>
#ifdef __rtems__<br>
- _Watchdog_Tick();<br>
+ };<br>
+<br>
+ _Watchdog_Tick(cpu_self);<br>
#endif /* __rtems__ */<br>
}<br>
#ifdef __rtems__<br>
@@ -2016,7 +2021,7 @@ _Timecounter_Tick_simple(uint32_t delta, uint32_t offset,<br>
<br>
_Timecounter_Release(lock_context);<br>
<br>
- _Watchdog_Tick();<br>
+ _Watchdog_Tick(_Per_CPU_Get());<br>
}<br>
#endif /* __rtems__ */<br>
<br>
diff --git a/cpukit/score/src/smp.c b/cpukit/score/src/smp.c<br>
index 4dacd4e..9d9507d 100644<br>
--- a/cpukit/score/src/smp.c<br>
+++ b/cpukit/score/src/smp.c<br>
@@ -189,7 +189,10 @@ void _SMP_Send_message_broadcast( unsigned long message )<br>
_Assert( _Debug_Is_thread_dispatching_allowed() );<br>
<br>
for ( cpu_index = 0 ; cpu_index < cpu_count ; ++cpu_index ) {<br>
- if ( cpu_index != cpu_index_self ) {<br>
+ if (<br>
+ cpu_index != cpu_index_self<br>
+ && _Processor_mask_Is_set( _SMP_Online_processors, cpu_index )<br>
+ ) {<br>
_SMP_Send_message( cpu_index, message );<br>
}<br>
}<br>
diff --git a/cpukit/score/src/watchdogtick.c b/cpukit/score/src/watchdogtick.c<br>
index cb68ea2..e89c088 100644<br>
--- a/cpukit/score/src/watchdogtick.c<br>
+++ b/cpukit/score/src/watchdogtick.c<br>
@@ -22,13 +22,15 @@<br>
#include "config.h"<br>
#endif<br>
<br>
-void _Watchdog_Tick( void )<br>
+void _Watchdog_Tick( Per_CPU_Control *cpu )<br>
{<br>
_Assert( !_Thread_Dispatch_is_enabled() );<br>
<br>
- _TOD_Tickle_ticks();<br>
+ if ( _Per_CPU_Is_boot_processor( cpu ) ) {<br>
+ _TOD_Tickle_ticks();<br>
<br>
- _Watchdog_Tickle_ticks();<br>
+ _Watchdog_Tickle_ticks();<br>
<br>
- _Scheduler_Tick();<br>
+ _Scheduler_Tick();<br>
+ }<br>
}<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.4.5<br>
<br>
_______________________________________________<br>
devel mailing list<br>
<a href="mailto:devel@rtems.org">devel@rtems.org</a><br>
<a href="http://lists.rtems.org/mailman/listinfo/devel" rel="noreferrer" target="_blank">http://lists.rtems.org/mailman/listinfo/devel</a><br>
</font></span></blockquote></div><br></div>