Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:08

0001 /**
0002  * @file
0003  * @ingroup RTEMSBSPsSPARCLEON3
0004  * @brief LEON3 SMP BSP Support
0005  */
0006 
0007 /*
0008  *  COPYRIGHT (c) 1989-2011.
0009  *  On-Line Applications Research Corporation (OAR).
0010  *
0011  *  The license and distribution terms for this file may be
0012  *  found in the file LICENSE in this distribution or at
0013  *  http://www.rtems.org/license/LICENSE.
0014  */
0015 
0016 #include <bsp.h>
0017 #include <bsp/bootcard.h>
0018 #include <bsp/fatal.h>
0019 #include <bsp/irq-generic.h>
0020 #include <bsp/leon3.h>
0021 #include <rtems/bspIo.h>
0022 #include <rtems/sysinit.h>
0023 #include <rtems/score/assert.h>
0024 #include <rtems/score/smpimpl.h>
0025 #include <stdlib.h>
0026 
0027 #if !defined(__leon__) || defined(RTEMS_PARAVIRT)
0028 uint32_t _CPU_SMP_Get_current_processor( void )
0029 {
0030   return _LEON3_Get_current_processor();
0031 }
0032 #endif
0033 
0034 static void bsp_inter_processor_interrupt( void *arg )
0035 {
0036   (void) arg;
0037   _SMP_Inter_processor_interrupt_handler(_Per_CPU_Get());
0038 }
0039 
0040 void bsp_start_on_secondary_processor(Per_CPU_Control *cpu_self)
0041 {
0042   if ( !leon3_data_cache_snooping_enabled() ) {
0043     bsp_fatal( LEON3_FATAL_INVALID_CACHE_CONFIG_SECONDARY_PROCESSOR );
0044   }
0045 
0046   _SMP_Start_multitasking_on_secondary_processor(cpu_self);
0047 }
0048 
0049 static rtems_interrupt_entry leon3_inter_processor_interrupt_entry =
0050   RTEMS_INTERRUPT_ENTRY_INITIALIZER(
0051     bsp_inter_processor_interrupt,
0052     NULL,
0053     "IPI"
0054   );
0055 
0056 static void leon3_install_inter_processor_interrupt( void )
0057 {
0058   rtems_status_code sc;
0059   rtems_vector_number irq;
0060 
0061   irq = LEON3_mp_irq;
0062 
0063   bsp_interrupt_set_affinity( irq, _SMP_Get_online_processors() );
0064 
0065   sc = rtems_interrupt_entry_install(
0066     irq,
0067     RTEMS_INTERRUPT_SHARED,
0068     &leon3_inter_processor_interrupt_entry
0069   );
0070   _Assert_Unused_variable_equals( sc, RTEMS_SUCCESSFUL );
0071 }
0072 
0073 uint32_t _CPU_SMP_Initialize( void )
0074 {
0075   if ( !leon3_data_cache_snooping_enabled() )
0076     bsp_fatal( LEON3_FATAL_INVALID_CACHE_CONFIG_BOOT_PROCESSOR );
0077 
0078   return leon3_get_cpu_count(LEON3_IrqCtrl_Regs);
0079 }
0080 
0081 bool _CPU_SMP_Start_processor( uint32_t cpu_index )
0082 {
0083   #if defined(RTEMS_DEBUG)
0084     printk( "Waking CPU %d\n", cpu_index );
0085   #endif
0086 
0087   grlib_store_32(
0088     &LEON3_IrqCtrl_Regs->mpstat,
0089     IRQAMP_MPSTAT_STATUS(1U << cpu_index)
0090   );
0091 
0092   return true;
0093 }
0094 
0095 void _CPU_SMP_Finalize_initialization( uint32_t cpu_count )
0096 {
0097   (void) cpu_count;
0098 
0099 #if !defined(RTEMS_DRVMGR_STARTUP)
0100   leon3_install_inter_processor_interrupt();
0101 #endif
0102 }
0103 
0104 void _CPU_SMP_Prepare_start_multitasking( void )
0105 {
0106   /* Do nothing */
0107 }
0108 
0109 void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
0110 {
0111   /* send interrupt to destination CPU */
0112   grlib_store_32(
0113     &LEON3_IrqCtrl_Regs->piforce[target_processor_index],
0114     1U << LEON3_mp_irq
0115   );
0116 }
0117 
0118 #if defined(RTEMS_DRVMGR_STARTUP)
0119 RTEMS_SYSINIT_ITEM(
0120   leon3_install_inter_processor_interrupt,
0121   RTEMS_SYSINIT_DRVMGR_LEVEL_1,
0122   RTEMS_SYSINIT_ORDER_LAST_BUT_4
0123 );
0124 #endif