source: rtems/c/src/lib/libbsp/sparc/leon3/smp/smp_leon3.c @ 7ec8d95

4.115
Last change on this file since 7ec8d95 was 7ec8d95, checked in by Sebastian Huber <sebastian.huber@…>, on 02/19/14 at 15:42:23

bsp/leon3: Add and use leon3_get_cpu_count()

  • Property mode set to 100644
File size: 2.2 KB
Line 
1/**
2 * @file
3 * @ingroup sparc_leon3
4 * @brief LEON3 SMP BSP Support
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
13 *  http://www.rtems.com/license/LICENSE.
14 */
15
16#include <bsp.h>
17#include <leon.h>
18#include <rtems/bspIo.h>
19#include <rtems/score/smpimpl.h>
20#include <stdlib.h>
21
22static inline void sparc_leon3_set_cctrl( unsigned int val )
23{
24  __asm__ volatile( "sta %0, [%%g0] 2" : : "r" (val) );
25}
26
27static inline unsigned int sparc_leon3_get_cctrl( void )
28{
29  unsigned int v = 0;
30  __asm__ volatile( "lda [%%g0] 2, %0" : "=r" (v) : "0" (v) );
31  return v;
32}
33
34static rtems_isr bsp_inter_processor_interrupt(
35  rtems_vector_number vector
36)
37{
38  _SMP_Inter_processor_interrupt_handler();
39}
40
41void leon3_secondary_cpu_initialize(uint32_t cpu)
42{
43  sparc_leon3_set_cctrl( 0x80000F );
44  LEON_Unmask_interrupt(LEON3_MP_IRQ);
45  LEON3_IrqCtrl_Regs->mask[cpu] |= 1 << LEON3_MP_IRQ;
46
47  _SMP_Start_multitasking_on_secondary_processor();
48}
49
50uint32_t _CPU_SMP_Initialize( uint32_t configured_cpu_count )
51{
52  uint32_t max_cpu_count;
53  uint32_t used_cpu_count;
54  uint32_t cpu;
55
56  sparc_leon3_set_cctrl( 0x80000F );
57
58  max_cpu_count = leon3_get_cpu_count(LEON3_IrqCtrl_Regs);
59  used_cpu_count = configured_cpu_count < max_cpu_count ?
60    configured_cpu_count : max_cpu_count;
61
62  #if defined(RTEMS_DEBUG)
63    printk( "Found %d CPUs\n", max_cpu_count );
64
65    if ( max_cpu_count > configured_cpu_count ) {
66      printk(
67        "%d CPUs IS MORE THAN CONFIGURED -- ONLY USING %d\n",
68        max_cpu_count,
69        configured_cpu_count
70      );
71    }
72  #endif
73
74  if ( used_cpu_count > 1 ) {
75    LEON_Unmask_interrupt(LEON3_MP_IRQ);
76    set_vector(bsp_inter_processor_interrupt, LEON_TRAP_TYPE(LEON3_MP_IRQ), 1);
77  }
78
79  for ( cpu = 1 ; cpu < used_cpu_count ; ++cpu ) {
80    #if defined(RTEMS_DEBUG)
81      printk( "Waking CPU %d\n", cpu );
82    #endif
83
84    LEON3_IrqCtrl_Regs->mpstat = 1 << cpu;
85  }
86
87  return used_cpu_count;
88}
89
90void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
91{
92  /* send interrupt to destination CPU */
93  LEON3_IrqCtrl_Regs->force[target_processor_index] = 1 << LEON3_MP_IRQ;
94}
Note: See TracBrowser for help on using the repository browser.