[rtems commit] riscv: Add dummy SMP support

Sebastian Huber sebh at rtems.org
Fri Jun 29 09:56:49 UTC 2018


Module:    rtems
Branch:    master
Commit:    2086948a7b06ac238c4ff0c9263c1e578e900fdd
Changeset: http://git.rtems.org/rtems/commit/?id=2086948a7b06ac238c4ff0c9263c1e578e900fdd

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri May 11 06:54:59 2018 +0200

riscv: Add dummy SMP support

Update #3433.

---

 bsps/riscv/riscv/start/start.S                     |  10 ++
 c/src/lib/libbsp/riscv/riscv/Makefile.am           |   3 +
 cpukit/score/cpu/riscv/include/rtems/score/cpu.h   | 140 +++------------------
 .../score/cpu/riscv/include/rtems/score/cpuimpl.h  |  12 +-
 testsuites/smptests/smpfatal08/init.c              |   3 +-
 5 files changed, 42 insertions(+), 126 deletions(-)

diff --git a/bsps/riscv/riscv/start/start.S b/bsps/riscv/riscv/start/start.S
index 58bc57d..1d0bde1 100644
--- a/bsps/riscv/riscv/start/start.S
+++ b/bsps/riscv/riscv/start/start.S
@@ -52,6 +52,11 @@ SYM(_start):
 	la	gp, __global_pointer$
 	.option	pop
 
+#ifdef RTEMS_SMP
+	csrr	s0, mhartid
+	bnez	s0, .Lloop_forever
+#endif
+
 	la	t0, ISR_Handler
 	csrw	mtvec, t0
 
@@ -70,6 +75,11 @@ SYM(_start):
 
 	j	boot_card
 
+#ifdef RTEMS_SMP
+.Lloop_forever:
+	j	.Lloop_forever
+#endif
+
 	.align	4
 bsp_start_vector_table_begin:
 	.word	_RISCV_Exception_default /* User int */
diff --git a/c/src/lib/libbsp/riscv/riscv/Makefile.am b/c/src/lib/libbsp/riscv/riscv/Makefile.am
index 3d819f7..0830b4f 100644
--- a/c/src/lib/libbsp/riscv/riscv/Makefile.am
+++ b/c/src/lib/libbsp/riscv/riscv/Makefile.am
@@ -61,6 +61,9 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/cache/nocache.c
 # debugio
 librtemsbsp_a_SOURCES += ../../../../../../bsps/riscv/riscv/console/console-io.c
 
+if HAS_SMP
+librtemsbsp_a_SOURCES += ../../../../../../bsps/shared/start/bspsmp-dummy.c
+endif
 
 include $(top_srcdir)/../../../../automake/local.am
 include $(srcdir)/../../../../../../bsps/shared/irq-sources.am
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
index d70db39..361af2e 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpu.h
@@ -80,43 +80,6 @@ typedef struct {
   unsigned long mcause;
   unsigned long mepc;
 #ifdef RTEMS_SMP
-  /**
-   * @brief On SMP configurations the thread context must contain a boolean
-   * indicator to signal if this context is executing on a processor.
-   *
-   * This field must be updated during a context switch.  The context switch
-   * to the heir must wait until the heir context indicates that it is no
-   * longer executing on a processor.  The context switch must also check if
-   * a thread dispatch is necessary to honor updates of the heir thread for
-   * this processor.  This indicator must be updated using an atomic test and
-   * set operation to ensure that at most one processor uses the heir
-   * context at the same time.
-   *
-   * @code
-   * void _CPU_Context_switch(
-   *   Context_Control *executing,
-   *   Context_Control *heir
-   * )
-   * {
-   *   save( executing );
-   *
-   *   executing->is_executing = false;
-   *   memory_barrier();
-   *
-   *   if ( test_and_set( &heir->is_executing ) ) {
-   *     do {
-   *       Per_CPU_Control *cpu_self = _Per_CPU_Get_snapshot();
-   *
-   *       if ( cpu_self->dispatch_necessary ) {
-   *         heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
-   *       }
-   *     } while ( test_and_set( &heir->is_executing ) );
-   *   }
-   *
-   *   restore( heir );
-   * }
-   * @endcode
-   */
   volatile bool is_executing;
 #endif
 } Context_Control;
@@ -480,102 +443,36 @@ uint32_t _CPU_Counter_frequency( void );
 CPU_Counter_ticks _CPU_Counter_read( void );
 
 #ifdef RTEMS_SMP
-/**
- * @brief Performs CPU specific SMP initialization in the context of the boot
- * processor.
- *
- * This function is invoked on the boot processor during system
- * initialization.  All interrupt stacks are allocated at this point in case
- * the CPU port allocates the interrupt stacks.  This function is called
- * before _CPU_SMP_Start_processor() or _CPU_SMP_Finalize_initialization() is
- * used.
- *
- * @return The count of physically or virtually available processors.
- * Depending on the configuration the application may use not all processors.
- */
+
 uint32_t _CPU_SMP_Initialize( void );
 
-/**
- * @brief Starts a processor specified by its index.
- *
- * This function is invoked on the boot processor during system
- * initialization.
- *
- * This function will be called after _CPU_SMP_Initialize().
- *
- * @param[in] cpu_index The processor index.
- *
- * @retval true Successful operation.
- * @retval false Unable to start this processor.
- */
 bool _CPU_SMP_Start_processor( uint32_t cpu_index );
 
-/**
- * @brief Performs final steps of CPU specific SMP initialization in the
- * context of the boot processor.
- *
- * This function is invoked on the boot processor during system
- * initialization.
- *
- * This function will be called after all processors requested by the
- * application have been started.
- *
- * @param[in] cpu_count The minimum value of the count of processors
- * requested by the application configuration and the count of physically or
- * virtually available processors.
- */
 void _CPU_SMP_Finalize_initialization( uint32_t cpu_count );
 
-/**
- * @brief Returns the index of the current processor.
- *
- * An architecture specific method must be used to obtain the index of the
- * current processor in the system.  The set of processor indices is the
- * range of integers starting with zero up to the processor count minus one.
- */
-uint32_t _CPU_SMP_Get_current_processor( void );
+void _CPU_SMP_Prepare_start_multitasking( void );
+
+static inline uint32_t _CPU_SMP_Get_current_processor( void )
+{
+  unsigned long mhartid;
+
+  __asm__ volatile ( "csrr %0, mhartid" : "=&r" ( mhartid ) );
+
+  return (uint32_t) mhartid;
+}
 
-/**
- * @brief Sends an inter-processor interrupt to the specified target
- * processor.
- *
- * This operation is undefined for target processor indices out of range.
- *
- * @param[in] target_processor_index The target processor index.
- */
 void _CPU_SMP_Send_interrupt( uint32_t target_processor_index );
 
-/**
- * @brief Broadcasts a processor event.
- *
- * Some architectures provide a low-level synchronization primitive for
- * processors in a multi-processor environment.  Processors waiting for this
- * event may go into a low-power state and stop generating system bus
- * transactions.  This function must ensure that preceding store operations
- * can be observed by other processors.
- *
- * @see _CPU_SMP_Processor_event_receive().
- */
-void _CPU_SMP_Processor_event_broadcast( void );
+static inline void _CPU_SMP_Processor_event_broadcast( void )
+{
+  __asm__ volatile ( "" : : : "memory" );
+}
 
-/**
- * @brief Receives a processor event.
- *
- * This function will wait for the processor event and may wait forever if no
- * such event arrives.
- *
- * @see _CPU_SMP_Processor_event_broadcast().
- */
 static inline void _CPU_SMP_Processor_event_receive( void )
 {
   __asm__ volatile ( "" : : : "memory" );
 }
 
-/**
- * @brief Gets the is executing indicator of the thread context.
- *
- * @param[in] context The context.
- */
 static inline bool _CPU_Context_Get_is_executing(
   const Context_Control *context
 )
@@ -583,12 +480,6 @@ static inline bool _CPU_Context_Get_is_executing(
   return context->is_executing;
 }
 
-/**
- * @brief Sets the is executing indicator of the thread context.
- *
- * @param[in] context The context.
- * @param[in] is_executing The new value for the is executing indicator.
- */
 static inline void _CPU_Context_Set_is_executing(
   Context_Control *context,
   bool is_executing
@@ -596,6 +487,7 @@ static inline void _CPU_Context_Set_is_executing(
 {
   context->is_executing = is_executing;
 }
+
 #endif /* RTEMS_SMP */
 
 /** Type that can store a 32-bit integer or a pointer. */
diff --git a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
index 3904c84..2a63e03 100644
--- a/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
+++ b/cpukit/score/cpu/riscv/include/rtems/score/cpuimpl.h
@@ -5,7 +5,7 @@
  */
 
 /*
- * Copyright (c) 2013 embedded brains GmbH
+ * Copyright (c) 2013, 2018 embedded brains GmbH
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -36,6 +36,16 @@
 
 #define CPU_PER_CPU_CONTROL_SIZE 0
 
+#if __riscv_xlen == 32
+
+#define CPU_INTERRUPT_FRAME_SIZE 144
+
+#elif __riscv_xlen == 64
+
+#define CPU_INTERRUPT_FRAME_SIZE 288
+
+#endif /* __riscv_xlen */
+
 #ifndef ASM
 
 #ifdef __cplusplus
diff --git a/testsuites/smptests/smpfatal08/init.c b/testsuites/smptests/smpfatal08/init.c
index 83a82da..abe0132 100644
--- a/testsuites/smptests/smpfatal08/init.c
+++ b/testsuites/smptests/smpfatal08/init.c
@@ -71,7 +71,8 @@ void _CPU_SMP_Prepare_start_multitasking(void)
 }
 
 #if defined(RTEMS_PARAVIRT) \
-  || (!defined(__leon__) && !defined(__PPC__) && !defined(__arm__))
+  || (!defined(__leon__) && !defined(__PPC__) \
+    && !defined(__arm__) && !defined(__riscv))
 uint32_t _CPU_SMP_Get_current_processor(void)
 {
   return 0;




More information about the vc mailing list