source: rtems/c/src/lib/libbsp/powerpc/qoriq/startup/bspsmp.c @ 64a04ac

4.115
Last change on this file since 64a04ac was 64a04ac, checked in by Sebastian Huber <sebastian.huber@…>, on May 12, 2014 at 6:53:11 AM

bsps: Use standard file name for BSP support

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