[fdcd80e] | 1 | /** |
---|
[d230d8e] | 2 | * @file |
---|
| 3 | * @ingroup sparc_leon3 |
---|
| 4 | * @brief LEON3 SMP BSP Support |
---|
[fdcd80e] | 5 | */ |
---|
| 6 | |
---|
| 7 | /* |
---|
| 8 | * COPYRIGHT (c) 1989-2011. |
---|
| 9 | * On-Line Applications Research Corporation (OAR). |
---|
| 10 | * |
---|
| 11 | * The license and distribution terms for this file may be |
---|
| 12 | * found in the file LICENSE in this distribution or at |
---|
[c499856] | 13 | * http://www.rtems.org/license/LICENSE. |
---|
[fdcd80e] | 14 | */ |
---|
| 15 | |
---|
| 16 | #include <bsp.h> |
---|
[6c5c2f3] | 17 | #include <bsp/bootcard.h> |
---|
[54f3476e] | 18 | #include <cache_.h> |
---|
[3d77001] | 19 | #include <leon.h> |
---|
[fdcd80e] | 20 | #include <rtems/bspIo.h> |
---|
[911b1d2] | 21 | #include <rtems/score/smpimpl.h> |
---|
[fdcd80e] | 22 | #include <stdlib.h> |
---|
| 23 | |
---|
[8df1f408] | 24 | #if !defined(__leon__) || defined(RTEMS_PARAVIRT) |
---|
[64a04ac] | 25 | uint32_t _CPU_SMP_Get_current_processor( void ) |
---|
| 26 | { |
---|
| 27 | return _LEON3_Get_current_processor(); |
---|
| 28 | } |
---|
| 29 | #endif |
---|
| 30 | |
---|
[4d9bd56] | 31 | static rtems_isr bsp_inter_processor_interrupt( |
---|
[fdcd80e] | 32 | rtems_vector_number vector |
---|
| 33 | ) |
---|
| 34 | { |
---|
[4d9bd56] | 35 | _SMP_Inter_processor_interrupt_handler(); |
---|
[fdcd80e] | 36 | } |
---|
| 37 | |
---|
[6c5c2f3] | 38 | void bsp_start_on_secondary_processor() |
---|
[fdcd80e] | 39 | { |
---|
[6c5c2f3] | 40 | uint32_t cpu_index_self = _CPU_SMP_Get_current_processor(); |
---|
| 41 | |
---|
[80186ca8] | 42 | leon3_set_cache_control_register(0x80000F); |
---|
[7fe05615] | 43 | /* Unmask IPI interrupts at Interrupt controller for this CPU */ |
---|
[6c5c2f3] | 44 | LEON3_IrqCtrl_Regs->mask[cpu_index_self] |= 1U << LEON3_MP_IRQ; |
---|
[8cacceb] | 45 | |
---|
[911b1d2] | 46 | _SMP_Start_multitasking_on_secondary_processor(); |
---|
[fdcd80e] | 47 | } |
---|
| 48 | |
---|
[53e008b] | 49 | uint32_t _CPU_SMP_Initialize( void ) |
---|
[fdcd80e] | 50 | { |
---|
[80186ca8] | 51 | leon3_set_cache_control_register(0x80000F); |
---|
[e644155a] | 52 | |
---|
[53e008b] | 53 | if ( rtems_configuration_get_maximum_processors() > 1 ) { |
---|
| 54 | LEON_Unmask_interrupt(LEON3_MP_IRQ); |
---|
| 55 | set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_MP_IRQ), 1); |
---|
| 56 | } |
---|
[d212acb7] | 57 | |
---|
[53e008b] | 58 | return leon3_get_cpu_count(LEON3_IrqCtrl_Regs); |
---|
| 59 | } |
---|
[fdcd80e] | 60 | |
---|
[53e008b] | 61 | bool _CPU_SMP_Start_processor( uint32_t cpu_index ) |
---|
| 62 | { |
---|
| 63 | #if defined(RTEMS_DEBUG) |
---|
| 64 | printk( "Waking CPU %d\n", cpu_index ); |
---|
[d212acb7] | 65 | #endif |
---|
[fdcd80e] | 66 | |
---|
[53e008b] | 67 | LEON3_IrqCtrl_Regs->mpstat = 1U << cpu_index; |
---|
[fdcd80e] | 68 | |
---|
[53e008b] | 69 | return true; |
---|
| 70 | } |
---|
[fdcd80e] | 71 | |
---|
[53e008b] | 72 | void _CPU_SMP_Finalize_initialization( uint32_t cpu_count ) |
---|
| 73 | { |
---|
| 74 | (void) cpu_count; |
---|
[3d77001] | 75 | |
---|
[53e008b] | 76 | /* Nothing to do */ |
---|
[fdcd80e] | 77 | } |
---|
| 78 | |
---|
[ca63ae2] | 79 | void _CPU_SMP_Send_interrupt(uint32_t target_processor_index) |
---|
[fdcd80e] | 80 | { |
---|
| 81 | /* send interrupt to destination CPU */ |
---|
[ca63ae2] | 82 | LEON3_IrqCtrl_Regs->force[target_processor_index] = 1 << LEON3_MP_IRQ; |
---|
[fdcd80e] | 83 | } |
---|
[54f3476e] | 84 | |
---|
[fecaeca1] | 85 | void _LEON3_Start_multitasking( |
---|
[54f3476e] | 86 | Context_Control *heir |
---|
| 87 | ) |
---|
| 88 | { |
---|
| 89 | _CPU_cache_invalidate_entire_instruction(); |
---|
| 90 | _CPU_Context_Restart_self( heir ); |
---|
| 91 | } |
---|