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 | |
---|
29 | #include <libchip/ns16550.h> |
---|
30 | |
---|
31 | #include <libcpu/powerpc-utility.h> |
---|
32 | |
---|
33 | #include <bsp.h> |
---|
34 | #include <bsp/bootcard.h> |
---|
35 | #include <bsp/console-termios.h> |
---|
36 | #include <bsp/fatal.h> |
---|
37 | #include <bsp/fdt.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 | |
---|
44 | LINKER_SYMBOL(bsp_exc_vector_base); |
---|
45 | |
---|
46 | qoriq_start_spin_table * |
---|
47 | qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT]; |
---|
48 | |
---|
49 | /* Configuration parameters for console driver, ... */ |
---|
50 | unsigned int BSP_bus_frequency; |
---|
51 | |
---|
52 | /* Configuration parameter for clock driver, ... */ |
---|
53 | uint32_t bsp_clicks_per_usec; |
---|
54 | |
---|
55 | void BSP_panic(char *s) |
---|
56 | { |
---|
57 | rtems_interrupt_level level; |
---|
58 | |
---|
59 | rtems_interrupt_local_disable(level); |
---|
60 | (void) level; |
---|
61 | |
---|
62 | printk("%s PANIC %s\n", rtems_get_version_string(), s); |
---|
63 | |
---|
64 | while (1) { |
---|
65 | /* Do nothing */ |
---|
66 | } |
---|
67 | } |
---|
68 | |
---|
69 | void _BSP_Fatal_error(unsigned n) |
---|
70 | { |
---|
71 | rtems_interrupt_level level; |
---|
72 | |
---|
73 | rtems_interrupt_local_disable(level); |
---|
74 | (void) level; |
---|
75 | |
---|
76 | printk("%s PANIC ERROR %u\n", rtems_get_version_string(), n); |
---|
77 | |
---|
78 | while (1) { |
---|
79 | /* Do nothing */ |
---|
80 | } |
---|
81 | } |
---|
82 | |
---|
83 | static void initialize_frequency_parameters(void) |
---|
84 | { |
---|
85 | const void *fdt = bsp_fdt_get(); |
---|
86 | int node; |
---|
87 | int len; |
---|
88 | fdt32_t *val_fdt; |
---|
89 | |
---|
90 | node = fdt_node_offset_by_prop_value(fdt, -1, "device_type", "cpu", 4); |
---|
91 | |
---|
92 | val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "bus-frequency", &len); |
---|
93 | if (val_fdt == NULL || len != 4) { |
---|
94 | bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY); |
---|
95 | } |
---|
96 | BSP_bus_frequency = fdt32_to_cpu(*val_fdt) / QORIQ_BUS_CLOCK_DIVIDER; |
---|
97 | |
---|
98 | val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len); |
---|
99 | if (val_fdt == NULL || len != 4) { |
---|
100 | bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY); |
---|
101 | } |
---|
102 | bsp_clicks_per_usec = fdt32_to_cpu(*val_fdt) / 1000000; |
---|
103 | |
---|
104 | #ifdef __PPC_CPU_E6500__ |
---|
105 | val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len); |
---|
106 | if (val_fdt == NULL || len != 4) { |
---|
107 | bsp_fatal(QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY); |
---|
108 | } |
---|
109 | #endif |
---|
110 | rtems_counter_initialize_converter(fdt32_to_cpu(*val_fdt)); |
---|
111 | } |
---|
112 | |
---|
113 | void bsp_start(void) |
---|
114 | { |
---|
115 | unsigned long i = 0; |
---|
116 | |
---|
117 | /* |
---|
118 | * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function |
---|
119 | * store the result in global variables so that it can be used latter... |
---|
120 | */ |
---|
121 | get_ppc_cpu_type(); |
---|
122 | get_ppc_cpu_revision(); |
---|
123 | |
---|
124 | initialize_frequency_parameters(); |
---|
125 | |
---|
126 | /* Initialize some console parameters */ |
---|
127 | for (i = 0; i < console_device_count; ++i) { |
---|
128 | const console_device *dev = &console_device_table[i]; |
---|
129 | const rtems_termios_device_handler *ns16550 = |
---|
130 | #ifdef BSP_USE_UART_INTERRUPTS |
---|
131 | &ns16550_handler_interrupt; |
---|
132 | #else |
---|
133 | &ns16550_handler_polled; |
---|
134 | #endif |
---|
135 | |
---|
136 | if (dev->handler == ns16550) { |
---|
137 | ns16550_context *ctx = (ns16550_context *) dev->context; |
---|
138 | |
---|
139 | ctx->clock = BSP_bus_frequency; |
---|
140 | } |
---|
141 | } |
---|
142 | |
---|
143 | /* Initialize exception handler */ |
---|
144 | ppc_exc_initialize_with_vector_base( |
---|
145 | (uintptr_t) bsp_section_work_begin, |
---|
146 | rtems_configuration_get_interrupt_stack_size(), |
---|
147 | bsp_exc_vector_base |
---|
148 | ); |
---|
149 | |
---|
150 | /* Now it is possible to make the code execute only */ |
---|
151 | qoriq_mmu_change_perm( |
---|
152 | FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SX, |
---|
153 | FSL_EIS_MAS3_SX, |
---|
154 | FSL_EIS_MAS3_SR |
---|
155 | ); |
---|
156 | |
---|
157 | /* Initalize interrupt support */ |
---|
158 | bsp_interrupt_initialize(); |
---|
159 | |
---|
160 | rtems_cache_coherent_add_area( |
---|
161 | bsp_section_nocacheheap_begin, |
---|
162 | (uintptr_t) bsp_section_nocacheheap_size |
---|
163 | ); |
---|
164 | |
---|
165 | /* Disable boot page translation */ |
---|
166 | #if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT) |
---|
167 | qoriq.lcc.bstar &= ~LCC_BSTAR_EN; |
---|
168 | #else |
---|
169 | qoriq.lcc.bptr &= ~BPTR_EN; |
---|
170 | #endif |
---|
171 | } |
---|
172 | |
---|
173 | uint32_t bsp_fdt_map_intr(uint32_t intr) |
---|
174 | { |
---|
175 | return intr - 16; |
---|
176 | } |
---|