source: rtems/bsps/powerpc/qoriq/start/bsprestart.c @ 8f8ccee

5
Last change on this file since 8f8ccee was 9964895, checked in by Sebastian Huber <sebastian.huber@…>, on 04/20/18 at 08:35:35

bsps: Move startup files to bsps

Adjust build support files to new directory layout.

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 3.4 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief BSP restart.
7 */
8
9/*
10 * Copyright (c) 2016, 2018 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
32#include <string.h>
33
34static char fdt_copy[BSP_FDT_BLOB_SIZE_MAX];
35
36static RTEMS_NO_RETURN void do_restart(void *addr)
37{
38  void (*restart)(uintptr_t);
39
40  qoriq_reset_qman_and_bman();
41
42  memcpy(fdt_copy, bsp_fdt_get(), sizeof(fdt_copy));
43  rtems_cache_flush_multiple_data_lines(fdt_copy, sizeof(fdt_copy));
44
45  restart = addr;
46  (*restart)((uintptr_t) fdt_copy);
47  bsp_fatal(QORIQ_FATAL_RESTART_FAILED);
48}
49
50#if defined(RTEMS_SMP) && !defined(QORIQ_IS_HYPERVISOR_GUEST)
51
52#include <rtems/score/smpimpl.h>
53#include <rtems/score/smpbarrier.h>
54
55#define RESTART_IPI_INDEX 1
56
57static SMP_barrier_Control restart_barrier = SMP_BARRIER_CONTROL_INITIALIZER;
58
59static void restart_interrupt(void *arg)
60{
61  uint32_t cpu_self_index;
62  uint32_t thread_index;
63  rtems_interrupt_level level;
64  SMP_barrier_State bs;
65
66  rtems_interrupt_local_disable(level);
67  (void) level;
68
69  _SMP_barrier_State_initialize(&bs);
70  _SMP_barrier_Wait(&restart_barrier, &bs, _SMP_Processor_count);
71
72  cpu_self_index = rtems_get_current_processor();
73  thread_index = cpu_self_index % QORIQ_THREAD_COUNT;
74
75  if (cpu_self_index == 0) {
76    do_restart(arg);
77  } else if (thread_index == 0) {
78    uint32_t real_processor_index;
79    const qoriq_start_spin_table *spin_table;
80
81    real_processor_index = cpu_self_index / QORIQ_THREAD_COUNT;
82    spin_table = qoriq_start_spin_table_addr[real_processor_index];
83
84    qoriq_restart_secondary_processor(spin_table);
85  } else {
86    uint32_t pir_reset_value;
87
88    /* Restore reset PIR value */
89    pir_reset_value = (cpu_self_index & ~0x1U) << 2;
90    PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR, pir_reset_value);
91
92    /* Thread Enable Clear (TENC) */
93    PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_TENC, 1U << thread_index);
94
95    RTEMS_UNREACHABLE();
96  }
97}
98
99static void raise_restart_interrupt(void)
100{
101  qoriq.pic.ipidr[RESTART_IPI_INDEX].reg =
102    _Processor_mask_To_uint32_t(_SMP_Get_online_processors(), 0);
103  ppc_synchronize_data();
104  ppc_synchronize_instructions();
105}
106
107void bsp_restart(void *addr)
108{
109  rtems_status_code sc;
110  size_t i;
111
112  for (i = 0; i < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr); ++i) {
113    qoriq_start_spin_table *spin_table;
114
115    spin_table = qoriq_start_spin_table_addr[i];
116    memset(spin_table, 0, sizeof(*spin_table));
117    rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table));
118  }
119
120  sc = rtems_interrupt_handler_install(
121    QORIQ_IRQ_IPI_0 + RESTART_IPI_INDEX,
122    "Restart",
123    RTEMS_INTERRUPT_UNIQUE,
124    restart_interrupt,
125    addr
126  );
127  if (sc != RTEMS_SUCCESSFUL) {
128    bsp_fatal(QORIQ_FATAL_RESTART_INSTALL_INTERRUPT);
129  }
130
131  raise_restart_interrupt();
132  bsp_fatal(QORIQ_FATAL_RESTART_INTERRUPT_FAILED);
133}
134
135#else /* !RTEMS_SMP || QORIQ_IS_HYPERVISOR_GUEST */
136
137void bsp_restart(void *addr)
138{
139  rtems_interrupt_level level;
140
141  rtems_interrupt_local_disable(level);
142  (void) level;
143  do_restart(addr);
144}
145
146#endif /* RTEMS_SMP && !QORIQ_IS_HYPERVISOR_GUEST */
Note: See TracBrowser for help on using the repository browser.