source: rtems/c/src/lib/libbsp/powerpc/qoriq/startup/bsprestart.c @ 76d1198

Last change on this file since 76d1198 was 76d1198, checked in by Sebastian Huber <sebastian.huber@…>, on Jul 7, 2017 at 5:45:57 AM

score: Introduce _SMP_Get_online_processors()

Update #3059.

  • Property mode set to 100644
File size: 3.3 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief BSP restart.
7 */
8
9/*
10 * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <bsp.h>
24#include <bsp/irq.h>
25#include <bsp/fatal.h>
26#include <bsp/fdt.h>
27#include <bsp/linker-symbols.h>
28#include <bsp/qoriq.h>
29
30#include <libcpu/powerpc-utility.h>
31
32static RTEMS_NO_RETURN void do_restart(void *addr)
33{
34  void (*restart)(uintptr_t);
35  uintptr_t fdt;
36
37  qoriq_reset_qman_and_bman();
38
39  restart = addr;
40
41  fdt = (uintptr_t) bsp_fdt_get();
42#ifdef BSP_FDT_BLOB_READ_ONLY
43  fdt -= (uintptr_t) bsp_section_rodata_begin;
44  fdt += (uintptr_t) bsp_section_rodata_load_begin;
45#endif
46
47  (*restart)(fdt);
48  bsp_fatal(QORIQ_FATAL_RESTART_FAILED);
49}
50
51#ifdef RTEMS_SMP
52
53#include <rtems/score/smpimpl.h>
54#include <rtems/score/smpbarrier.h>
55
56#define RESTART_IPI_INDEX 1
57
58static SMP_barrier_Control restart_barrier = SMP_BARRIER_CONTROL_INITIALIZER;
59
60static void restart_interrupt(void *arg)
61{
62  uint32_t cpu_self_index;
63  uint32_t thread_index;
64  rtems_interrupt_level level;
65  SMP_barrier_State bs;
66
67  rtems_interrupt_local_disable(level);
68  (void) level;
69
70  _SMP_barrier_State_initialize(&bs);
71  _SMP_barrier_Wait(&restart_barrier, &bs, _SMP_Processor_count);
72
73  cpu_self_index = rtems_get_current_processor();
74  thread_index = cpu_self_index % QORIQ_THREAD_COUNT;
75
76  if (cpu_self_index == 0) {
77    do_restart(arg);
78  } else if (thread_index == 0) {
79    uint32_t real_processor_index;
80    const qoriq_start_spin_table *spin_table;
81
82    real_processor_index = cpu_self_index / QORIQ_THREAD_COUNT;
83    spin_table = qoriq_start_spin_table_addr[real_processor_index];
84
85    qoriq_restart_secondary_processor(spin_table);
86  } else {
87    uint32_t pir_reset_value;
88
89    /* Restore reset PIR value */
90    pir_reset_value = (cpu_self_index & ~0x1U) << 2;
91    PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR, pir_reset_value);
92
93    /* Thread Enable Clear (TENC) */
94    PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_TENC, 1U << thread_index);
95
96    RTEMS_UNREACHABLE();
97  }
98}
99
100static void raise_restart_interrupt(void)
101{
102  qoriq.pic.ipidr[RESTART_IPI_INDEX].reg =
103    _Processor_mask_To_uint32_t(_SMP_Get_online_processors(), 0);
104  ppc_synchronize_data();
105  ppc_synchronize_instructions();
106}
107
108void bsp_restart(void *addr)
109{
110  rtems_status_code sc;
111  size_t i;
112
113  for (i = 0; i < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr); ++i) {
114    qoriq_start_spin_table *spin_table;
115
116    spin_table = qoriq_start_spin_table_addr[i];
117    memset(spin_table, 0, sizeof(*spin_table));
118    rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
119  }
120
121  sc = rtems_interrupt_handler_install(
122    QORIQ_IRQ_IPI_0 + RESTART_IPI_INDEX,
123    "Restart",
124    RTEMS_INTERRUPT_UNIQUE,
125    restart_interrupt,
126    addr
127  );
128  if (sc != RTEMS_SUCCESSFUL) {
129    bsp_fatal(QORIQ_FATAL_RESTART_INSTALL_INTERRUPT);
130  }
131
132  raise_restart_interrupt();
133  bsp_fatal(QORIQ_FATAL_RESTART_INTERRUPT_FAILED);
134}
135
136#else /* RTEMS_SMP */
137
138void bsp_restart(void *addr)
139{
140  rtems_interrupt_level level;
141
142  rtems_interrupt_local_disable(level);
143  (void) level;
144  do_restart(addr);
145}
146
147#endif /* !RTEMS_SMP */
Note: See TracBrowser for help on using the repository browser.