source: rtems/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c @ 911b1d2

4.115
Last change on this file since 911b1d2 was 911b1d2, checked in by Sebastian Huber <sebastian.huber@…>, on 02/17/14 at 14:02:54

score: Rename rtems_smp_secondary_cpu_initialize()

Rename rtems_smp_secondary_cpu_initialize() into
_SMP_Start_multitasking_on_secondary_processor(). Move declaration to
<rtems/score/smpimpl.h>.

  • Property mode set to 100644
File size: 3.9 KB
Line 
1/*
2 * Copyright (c) 2013 embedded brains GmbH.  All rights reserved.
3 *
4 *  embedded brains GmbH
5 *  Obere Lagerstr. 30
6 *  82178 Puchheim
7 *  Germany
8 *  <rtems@embedded-brains.de>
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.com/license/LICENSE.
13 */
14
15#include <assert.h>
16
17#include <rtems/bspsmp.h>
18#include <rtems/score/smpimpl.h>
19
20#include <libcpu/powerpc-utility.h>
21
22#include <bsp.h>
23#include <bsp/mmu.h>
24#include <bsp/qoriq.h>
25#include <bsp/vectors.h>
26#include <bsp/irq-generic.h>
27#include <bsp/linker-symbols.h>
28
29LINKER_SYMBOL(bsp_exc_vector_base);
30
31void _start_core_1(void);
32
33#define CORE_COUNT 2
34
35#define ONE_CORE(core) (1 << (core))
36
37#define ALL_CORES ((1 << CORE_COUNT) - 1)
38
39#define IPI_INDEX 0
40
41#define TLB_BEGIN 8
42
43#define TLB_END 16
44
45#define TLB_COUNT (TLB_END - TLB_BEGIN)
46
47/*
48 * These values can be obtained with the debugger or a look into the
49 * U-Boot sources (arch/powerpc/cpu/mpc85xx/release.S).
50 */
51#if 1
52  #define BOOT_BEGIN 0x1fff0000
53  #define BOOT_LAST  0x1fffffff
54  #define SPIN_TABLE (BOOT_BEGIN + 0xf2a0)
55#else
56  #define BOOT_BEGIN 0x3fff0000
57  #define BOOT_LAST  0x3fffffff
58  #define SPIN_TABLE (BOOT_BEGIN + 0xf240)
59#endif
60
61#define TLB_BEGIN 8
62
63#define TLB_END 16
64
65#define TLB_COUNT (TLB_END - TLB_BEGIN)
66
67typedef struct {
68  uint32_t addr_upper;
69  uint32_t addr_lower;
70  uint32_t r3_upper;
71  uint32_t r3_lower;
72  uint32_t reserved;
73  uint32_t pir;
74  uint32_t r6_upper;
75  uint32_t r6_lower;
76} uboot_spin_table;
77
78static uint32_t initial_core_1_stack[4096 / sizeof(uint32_t)];
79
80static void mmu_config_undo(void)
81{
82  int i = 0;
83
84  for (i = TLB_BEGIN; i < TLB_END; ++i) {
85    qoriq_tlb1_invalidate(i);
86  }
87}
88
89static void release_core_1(void)
90{
91  const Per_CPU_Control *second_cpu = _Per_CPU_Get_by_index(1);
92  uboot_spin_table *spin_table = (uboot_spin_table *) SPIN_TABLE;
93  qoriq_mmu_context mmu_context;
94
95  qoriq_mmu_context_init(&mmu_context);
96  qoriq_mmu_add(&mmu_context, BOOT_BEGIN, BOOT_LAST, 0, 0, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW);
97  qoriq_mmu_partition(&mmu_context, TLB_COUNT);
98  qoriq_mmu_write_to_tlb1(&mmu_context, TLB_BEGIN);
99
100  spin_table->pir = 1;
101  spin_table->r3_lower = (uint32_t) second_cpu->interrupt_stack_high;
102  spin_table->addr_upper = 0;
103  rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
104  ppc_synchronize_data();
105  spin_table->addr_lower = (uint32_t) _start_core_1;
106  rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
107
108  mmu_config_undo();
109}
110
111void qoriq_secondary_cpu_initialize(void)
112{
113  const Per_CPU_Control *second_cpu = _Per_CPU_Get_by_index(1);
114
115  /* Disable decrementer */
116  PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(BOOKE_TCR, BOOKE_TCR_DIE);
117
118  /* Initialize exception handler */
119  ppc_exc_initialize_with_vector_base(
120    (uintptr_t) second_cpu->interrupt_stack_low,
121    rtems_configuration_get_interrupt_stack_size(),
122    bsp_exc_vector_base
123  );
124
125  /* Now it is possible to make the code execute only */
126  qoriq_mmu_change_perm(
127    FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SX,
128    FSL_EIS_MAS3_SX,
129    FSL_EIS_MAS3_SR
130  );
131
132  /* Initialize interrupt support */
133  bsp_interrupt_facility_initialize();
134
135  bsp_interrupt_vector_enable(QORIQ_IRQ_IPI_0);
136
137  _SMP_Start_multitasking_on_secondary_processor();
138}
139
140static void ipi_handler(void *arg)
141{
142  rtems_smp_process_interrupt();
143}
144
145uint32_t _CPU_SMP_Initialize(uint32_t configured_cpu_count)
146{
147  rtems_status_code sc;
148  uint32_t cores = configured_cpu_count < CORE_COUNT ?
149    configured_cpu_count : CORE_COUNT;
150
151  sc = rtems_interrupt_handler_install(
152    QORIQ_IRQ_IPI_0,
153    "IPI",
154    RTEMS_INTERRUPT_UNIQUE,
155    ipi_handler,
156    NULL
157  );
158  assert(sc == RTEMS_SUCCESSFUL);
159
160  if (cores > 1) {
161    release_core_1();
162  }
163
164  return cores;
165}
166
167void _CPU_SMP_Send_interrupt(uint32_t target_processor_index)
168{
169  uint32_t self = ppc_processor_id();
170  qoriq.pic.per_cpu [self].ipidr [IPI_INDEX].reg =
171    ONE_CORE(target_processor_index);
172}
Note: See TracBrowser for help on using the repository browser.