source: rtems/bsps/powerpc/qoriq/start/bspstart.c @ 65f868c

5
Last change on this file since 65f868c was 65f868c, checked in by Sebastian Huber <sebastian.huber@…>, on 05/23/18 at 12:17:25

Add _CPU_Counter_frequency()

Add rtems_counter_frequency() API function. Use it to initialize the
counter value converter via the new system initialization step
(RTEMS_SYSINIT_CPU_COUNTER). This decouples the counter implementation
and the counter converter. It avoids an unnecessary pull in of the
64-bit integer division from libgcc.

Update #3456.

  • Property mode set to 100644
File size: 4.7 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup QorIQ
5 *
6 * @brief BSP startup.
7 */
8
9/*
10 * Copyright (c) 2010, 2017 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 <libfdt.h>
24
25#include <rtems.h>
26#include <rtems/config.h>
27#include <rtems/counter.h>
28#include <rtems/sysinit.h>
29
30#include <libcpu/powerpc-utility.h>
31
32#include <bsp.h>
33#include <bsp/bootcard.h>
34#include <bsp/console-termios.h>
35#include <bsp/fatal.h>
36#include <bsp/fdt.h>
37#include <bsp/intercom.h>
38#include <bsp/irq-generic.h>
39#include <bsp/linker-symbols.h>
40#include <bsp/mmu.h>
41#include <bsp/qoriq.h>
42#include <bsp/vectors.h>
43
44LINKER_SYMBOL(bsp_exc_vector_base);
45
46qoriq_start_spin_table *
47qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT];
48
49/* Configuration parameters for console driver, ... */
50unsigned int BSP_bus_frequency;
51
52/* Configuration parameter for clock driver, ... */
53uint32_t bsp_time_base_frequency;
54
55uint32_t qoriq_clock_frequency;
56
57uint32_t _CPU_Counter_frequency(void)
58{
59#ifdef __PPC_CPU_E6500__
60  return qoriq_clock_frequency;
61#else
62  return bsp_time_base_frequency;
63#endif
64}
65
66static void initialize_frequency_parameters(void)
67{
68  const void *fdt = bsp_fdt_get();
69  int node;
70  int len;
71  fdt32_t *val_fdt;
72
73  node = fdt_node_offset_by_prop_value(fdt, -1, "device_type", "cpu", 4);
74
75  val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "bus-frequency", &len);
76  if (val_fdt == NULL || len != 4) {
77    bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
78  }
79  BSP_bus_frequency = fdt32_to_cpu(*val_fdt) / QORIQ_BUS_CLOCK_DIVIDER;
80
81  val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
82  if (val_fdt == NULL || len != 4) {
83    bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
84  }
85  bsp_time_base_frequency = fdt32_to_cpu(*val_fdt);
86
87  #ifdef __PPC_CPU_E6500__
88    val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
89    if (val_fdt == NULL || len != 4) {
90      bsp_fatal(QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY);
91    }
92    qoriq_clock_frequency = fdt32_to_cpu(*val_fdt);
93  #endif
94}
95
96#define MTIVPR(base) \
97  __asm__ volatile ("mtivpr %0" : : "r" (base))
98
99#ifdef __powerpc64__
100#define VECTOR_TABLE_ENTRY_SIZE 32
101#else
102#define VECTOR_TABLE_ENTRY_SIZE 16
103#endif
104
105#define MTIVOR(vec, offset) \
106  do { \
107    __asm__ volatile ("mtspr " RTEMS_XSTRING(vec) ", %0" : : "r" (offset)); \
108    offset += VECTOR_TABLE_ENTRY_SIZE; \
109  } while (0)
110
111void qoriq_initialize_exceptions(void *interrupt_stack_begin)
112{
113  uintptr_t addr;
114
115  ppc_exc_initialize_interrupt_stack(
116    (uintptr_t) interrupt_stack_begin,
117    rtems_configuration_get_interrupt_stack_size()
118  );
119
120  addr = (uintptr_t) bsp_exc_vector_base;
121  MTIVPR(addr);
122  MTIVOR(BOOKE_IVOR0,  addr);
123  MTIVOR(BOOKE_IVOR1,  addr);
124  MTIVOR(BOOKE_IVOR2,  addr);
125  MTIVOR(BOOKE_IVOR3,  addr);
126  MTIVOR(BOOKE_IVOR4,  addr);
127  MTIVOR(BOOKE_IVOR5,  addr);
128  MTIVOR(BOOKE_IVOR6,  addr);
129#ifdef __PPC_CPU_E6500__
130  MTIVOR(BOOKE_IVOR7,  addr);
131#endif
132  MTIVOR(BOOKE_IVOR8,  addr);
133#ifdef __PPC_CPU_E6500__
134  MTIVOR(BOOKE_IVOR9,  addr);
135#endif
136  MTIVOR(BOOKE_IVOR10, addr);
137  MTIVOR(BOOKE_IVOR11, addr);
138  MTIVOR(BOOKE_IVOR12, addr);
139  MTIVOR(BOOKE_IVOR13, addr);
140  MTIVOR(BOOKE_IVOR14, addr);
141  MTIVOR(BOOKE_IVOR15, addr);
142  MTIVOR(BOOKE_IVOR32, addr);
143  MTIVOR(BOOKE_IVOR33, addr);
144#ifndef __PPC_CPU_E6500__
145  MTIVOR(BOOKE_IVOR34, addr);
146#endif
147  MTIVOR(BOOKE_IVOR35, addr);
148#ifdef __PPC_CPU_E6500__
149  MTIVOR(BOOKE_IVOR36, addr);
150  MTIVOR(BOOKE_IVOR37, addr);
151#ifndef QORIQ_IS_HYPERVISOR_GUEST
152  MTIVOR(BOOKE_IVOR38, addr);
153  MTIVOR(BOOKE_IVOR39, addr);
154  MTIVOR(BOOKE_IVOR40, addr);
155  MTIVOR(BOOKE_IVOR41, addr);
156  MTIVOR(BOOKE_IVOR42, addr);
157#endif
158#endif
159}
160
161void bsp_start(void)
162{
163  /*
164   * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
165   * store the result in global variables so that it can be used latter...
166   */
167  get_ppc_cpu_type();
168  get_ppc_cpu_revision();
169
170  initialize_frequency_parameters();
171
172  qoriq_initialize_exceptions(bsp_section_work_begin);
173  bsp_interrupt_initialize();
174
175  rtems_cache_coherent_add_area(
176    bsp_section_nocacheheap_begin,
177    (uintptr_t) bsp_section_nocacheheap_size
178  );
179
180#ifndef QORIQ_IS_HYPERVISOR_GUEST
181  /* Disable boot page translation */
182#if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
183  qoriq.lcc.bstar &= ~LCC_BSTAR_EN;
184#else
185  qoriq.lcc.bptr &= ~BPTR_EN;
186#endif
187#endif
188}
189
190uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
191{
192#ifndef QORIQ_IS_HYPERVISOR_GUEST
193  return intr[0] - 16;
194#else
195  return intr[0];
196#endif
197}
198
199#ifdef RTEMS_MULTIPROCESSING
200RTEMS_SYSINIT_ITEM(
201  qoriq_intercom_init,
202  RTEMS_SYSINIT_BSP_PRE_DRIVERS,
203  RTEMS_SYSINIT_ORDER_MIDDLE
204);
205#endif
Note: See TracBrowser for help on using the repository browser.