source: rtems/c/src/lib/libbsp/powerpc/qoriq/startup/smp.c @ 5f91272

4.115
Last change on this file since 5f91272 was 5f91272, checked in by Sebastian Huber <sebastian.huber@…>, on 06/20/13 at 09:17:23

bsps/powerpc: Delete bsp_exceptions_in_RAM

Delete ppc_exc_vector_base. Add and use
ppc_exc_initialize_with_vector_base().

  • 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
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
46int bsp_smp_processor_id(void)
47{
48  return (int) ppc_processor_id();
49}
50
51/*
52 * These values can be obtained with the debugger or a look into the
53 * U-Boot sources (arch/powerpc/cpu/mpc85xx/release.S).
54 */
55#if 1
56  #define BOOT_BEGIN 0x1fff0000
57  #define BOOT_LAST  0x1fffffff
58  #define SPIN_TABLE (BOOT_BEGIN + 0xf2a0)
59#else
60  #define BOOT_BEGIN 0x3fff0000
61  #define BOOT_LAST  0x3fffffff
62  #define SPIN_TABLE (BOOT_BEGIN + 0xf240)
63#endif
64
65#define TLB_BEGIN 8
66
67#define TLB_END 16
68
69#define TLB_COUNT (TLB_END - TLB_BEGIN)
70
71typedef struct {
72  uint32_t addr_upper;
73  uint32_t addr_lower;
74  uint32_t r3_upper;
75  uint32_t r3_lower;
76  uint32_t reserved;
77  uint32_t pir;
78  uint32_t r6_upper;
79  uint32_t r6_lower;
80} uboot_spin_table;
81
82static uint32_t initial_core_1_stack[4096 / sizeof(uint32_t)];
83
84static void mmu_config_undo(void)
85{
86  int i = 0;
87
88  for (i = TLB_BEGIN; i < TLB_END; ++i) {
89    qoriq_tlb1_invalidate(i);
90  }
91}
92
93static void release_core_1(void)
94{
95  uboot_spin_table *spin_table = (uboot_spin_table *) SPIN_TABLE;
96  qoriq_mmu_context mmu_context;
97
98  qoriq_mmu_context_init(&mmu_context);
99  qoriq_mmu_add(&mmu_context, BOOT_BEGIN, BOOT_LAST, 0, 0, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW);
100  qoriq_mmu_partition(&mmu_context, TLB_COUNT);
101  qoriq_mmu_write_to_tlb1(&mmu_context, TLB_BEGIN);
102
103  spin_table->pir = 1;
104  spin_table->r3_lower = (uint32_t) _Per_CPU_Information[1].interrupt_stack_high;
105  spin_table->addr_upper = 0;
106  rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
107  ppc_synchronize_data();
108  spin_table->addr_lower = (uint32_t) _start_core_1;
109  rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
110
111  mmu_config_undo();
112}
113
114void qoriq_secondary_cpu_initialize(void)
115{
116  /* Disable decrementer */
117  PPC_CLEAR_SPECIAL_PURPOSE_REGISTER_BITS(BOOKE_TCR, BOOKE_TCR_DIE);
118
119  /* Initialize exception handler */
120  ppc_exc_initialize_with_vector_base(
121    PPC_INTERRUPT_DISABLE_MASK_DEFAULT,
122    (uintptr_t) _Per_CPU_Information[1].interrupt_stack_low,
123    rtems_configuration_get_interrupt_stack_size(),
124    bsp_exc_vector_base
125  );
126
127  /* Now it is possible to make the code execute only */
128  qoriq_mmu_change_perm(
129    FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SX,
130    FSL_EIS_MAS3_SX,
131    FSL_EIS_MAS3_SR
132  );
133
134  /* Initialize interrupt support */
135  bsp_interrupt_facility_initialize();
136
137  bsp_interrupt_vector_enable(QORIQ_IRQ_IPI_0);
138
139  rtems_smp_secondary_cpu_initialize();
140}
141
142static void ipi_handler(void *arg)
143{
144  rtems_smp_process_interrupt();
145}
146
147uint32_t bsp_smp_initialize(uint32_t configured_cpu_count)
148{
149  rtems_status_code sc;
150  uint32_t cores = configured_cpu_count < CORE_COUNT ?
151    configured_cpu_count : CORE_COUNT;
152
153  sc = rtems_interrupt_handler_install(
154    QORIQ_IRQ_IPI_0,
155    "IPI",
156    RTEMS_INTERRUPT_UNIQUE,
157    ipi_handler,
158    NULL
159  );
160  assert(sc == RTEMS_SUCCESSFUL);
161
162  if (cores > 1) {
163    release_core_1();
164  }
165
166  return cores;
167}
168
169void bsp_smp_broadcast_interrupt(void)
170{
171  uint32_t self = ppc_processor_id();
172  qoriq.pic.per_cpu [self].ipidr [IPI_INDEX].reg = ALL_CORES;
173}
174
175void bsp_smp_interrupt_cpu(int core)
176{
177  uint32_t self = ppc_processor_id();
178  qoriq.pic.per_cpu [self].ipidr [IPI_INDEX].reg = ONE_CORE(core);
179}
Note: See TracBrowser for help on using the repository browser.