From 2086948a7b06ac238c4ff0c9263c1e578e900fdd Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 11 May 2018 06:54:59 +0200 Subject: 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 58bc57dc12..1d0bde164b 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 3d819f758b..0830b4f639 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 d70db39b85..361af2e392 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 3904c84bf9..2a63e03513 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 83a82dab75..abe0132aa8 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; -- cgit v1.2.3