Dear,
thank you for the helpful answer. A port to the custom-made board based on Microchip Polarfire SoC containing RISC-V based microcontroller subsystem (MSS) represents the final goal. However, I can use a Beagle-V Fire board for the first experiments. RTEMS 6.1 contains a BSP for this board but this BSP seems unfinished.
So, as the first step, I would like to repair the existing RTEMS 6.1 BSP for the Beagle-V board and run hello world or flashing LED on hart 0 of the Beagle-V Fire board.
Particular problems:
- gcc options:
Problem:
1a) Instruction set. MSS contains e51 hart of rv64imac architecture and four u54 harts of rv64imafdc architecture. However, by default, BSP as well as the application is compiled with -march=rv64imafdc option.
1b) Switch off optimization. To be able to step the code in the debugger, it is better to switch off optimization. Default optimization option is -O2 but I would like to change it to -O0.
Used solution:
I modified beaglevfire_cache.cfg, riscv-rtems6-beaglevfire.pc and target.cfg to use -O0 and -march=rv64imac gcc options. With this option, I am not able to use extensions of u54 harts but it does not matter at this moment. At this moment, I would like to run hello world on e51 hart and suspend other harts.
- Memory mapping.
Problem:
The current Beagle V Fire port uses RAM starting at 0x10_0000_0000 which represents cached DDR DRAM. However, the DRAM must be trained before the use and the start-up code does not perform DRAM training. Therefore, the application had no chance to run and really, in the debugger I saw that the code failed on the first instruction. Therefore, I decided to change memory mapping to LIM staring at 0x0800_0000. LIM does not need any initialization or training and it represents the ideal memory for the first experiments with MSS. In the Microchip PFSoC MSS Configurator, I configured MSS to have size of 0x10_0000 bytes (1MB). I am sure that LIM is well configured because I use it for other applications which do not use RTEMS.
Used solution:
To configure RTEMS to use LIM, I modified linkcmds and beaglevfire.dts to use memory starting 0x0800_0000 of 0x10_0000 bytes. I used dtc and xxd to create new beaglevfire.h. Than, the code was possible to start but it failed in filesystem initialization. I switched it off using #define CONFIGURE_APPLICATON_DISABLE_FILESYSTEM in init.c
It seems I did everything well as the code passed until the function _Thread_Start_multitasking.
- To start symmetric multiprocessoring (SMP) or not to start SMP (and how to start SMP)?
After named mods, code passed until this function
void _Thread_Start_multitasking( void )
{
Per_CPU_Control *cpu_self = _Per_CPU_Get();
Thread_Control *heir;
#if defined(RTEMS_SMP)
_Per_CPU_Set_state( cpu_self, PER_CPU_STATE_UP );
_SMP_Try_to_process_message( cpu_self, SMP_MESSAGE_FORCE_PROCESSING );
#endif
heir = _Thread_Get_heir_and_make_it_executing( cpu_self );
_Profiling_Thread_dispatch_disable( cpu_self, 0 );
#if defined(RTEMS_SMP)
_CPU_SMP_Prepare_start_multitasking();
#endif
#if defined(_CPU_Start_multitasking)
_CPU_Start_multitasking( &heir->Registers );
#elif defined(RTEMS_SMP)
#if CPU_ENABLE_ROBUST_THREAD_DISPATCH == TRUE
#error “The CPU port has to provide _CPU_Start_multitasking()”
#endif
{
Context_Control trash;
/*
* Mark the trash context as executing to not confuse the
* _CPU_Context_switch(). On SMP configurations the context switch
* contains a special hand over section to atomically switch from the
* executing to the currently selected heir thread.
*/
_CPU_Context_Set_is_executing( &trash, true );
_CPU_Context_switch_no_return( &trash, &heir->Registers );
RTEMS_UNREACHABLE();
}
#else
_CPU_Context_Restart_self( &heir->Registers );
#endif
}
As by default, SMP is off, macro RTEMS_SMP is not defined. At next, if the macro RTEMS_SMP is not defined, the function _CPU_Start_multitasking is not defined, too. The function _Thread_Start_multitasking passes to the line _CPU_Context_Restart_self( &heir->Registers ); The code fails (jumps to exception handler) in the function _CPU_Context_Restart_self.
I tried to build few other BSPs (sparc, arm, …) and all of them define the function _CPU_Start_multitasking.
I tried to use SMP but not sure how to do it. I did not found the proper place, where to place #define RTEMS_SMP. I tried to define it via gcc parameter -DRTEMS_SMP. However, BSP build failed because of plenty of missing references.
I tried to set RTEMS_HAS_MULTIPROCESSORING = yes in target.cfg. BSP build and application build both passed. The function _CPU_Start_multitasking was defined. However, the code failed in this function:
static inline void _Scheduler_priority_Ready_queue_initialize(
Chain_Control *ready_queues,
Priority_Control maximum_priority
)
{
size_t index;
for ( index = 0 ; index <= (size_t) maximum_priority ; ++index ) {
_Chain_Initialize_empty( &ready_queues[ index ] );
}
}
I found that maximum_priority had an excessive value greater than 100000000. Next, I found that some sources were compiled with the macro RTEMS_SMP and some sources were compiled without this macro. So, the build is inconsistent and probably it is the reason of the uncanny behavior.
Currently the principal question is if to start SMP and how or what to do to make the code operational if SMP is off.
Other question if SMP is on - how to define codes for u54 harts. At this point, I would use e.g. wfi to let u54 harts wait forever.