1 | /* |
---|
2 | * Copyright (c) 2013 embedded brains GmbH. All rights reserved. |
---|
3 | * |
---|
4 | * embedded brains GmbH |
---|
5 | * Dornierstr. 4 |
---|
6 | * 82178 Puchheim |
---|
7 | * Germany |
---|
8 | * <info@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.org/license/LICENSE. |
---|
13 | */ |
---|
14 | |
---|
15 | #include <bsp.h> |
---|
16 | #include <bsp/start.h> |
---|
17 | #include <bsp/arm-cp15-start.h> |
---|
18 | #include <bsp/arm-a9mpcore-start.h> |
---|
19 | #include <bsp/linker-symbols.h> |
---|
20 | #include <alt_address_space.h> |
---|
21 | #include "socal/socal.h" |
---|
22 | #include "socal/alt_sdr.h" |
---|
23 | #include "socal/hps.h" |
---|
24 | #include "../include/arm-cache-l1.h" |
---|
25 | |
---|
26 | #ifdef RTEMS_SMP |
---|
27 | #define MMU_DATA_READ_WRITE ARMV7_MMU_DATA_READ_WRITE_SHAREABLE |
---|
28 | #else |
---|
29 | #define MMU_DATA_READ_WRITE ARMV7_MMU_DATA_READ_WRITE_CACHED |
---|
30 | #endif |
---|
31 | |
---|
32 | /* 1 MB reset default value for address filtering start */ |
---|
33 | #define BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET 0x100000 |
---|
34 | |
---|
35 | #ifndef BSPSTARTHOOKS_MIN |
---|
36 | #define BSPSTARTHOOKS_MIN( a, b ) ( ( a ) < ( b ) ? ( a ) : ( b ) ) |
---|
37 | #endif |
---|
38 | |
---|
39 | LINKER_SYMBOL( bsp_section_nocache_size ); |
---|
40 | LINKER_SYMBOL( bsp_section_nocache_end ); |
---|
41 | LINKER_SYMBOL( bsp_section_nocache_begin ); |
---|
42 | |
---|
43 | BSP_START_DATA_SECTION static const arm_cp15_start_section_config |
---|
44 | altcycv_mmu_config_table[] = { |
---|
45 | ARMV7_CP15_START_DEFAULT_SECTIONS, |
---|
46 | { |
---|
47 | .begin = (uint32_t) bsp_section_nocache_begin, |
---|
48 | .end = (uint32_t) bsp_section_nocache_end, |
---|
49 | |
---|
50 | .flags = ARMV7_MMU_DATA_READ_WRITE | ARM_MMU_SECT_TEX_0 |
---|
51 | }, { /* Periphery area */ |
---|
52 | .begin = 0xFC000000U, |
---|
53 | .end = 0x00000000U, |
---|
54 | .flags = ARMV7_MMU_DEVICE |
---|
55 | } |
---|
56 | }; |
---|
57 | |
---|
58 | BSP_START_TEXT_SECTION static void setup_mmu_and_cache( const uint32_t CPU_ID ) |
---|
59 | { |
---|
60 | uint32_t ctrl = arm_cp15_get_control(); |
---|
61 | const uint32_t CORES = BSPSTARTHOOKS_MIN( |
---|
62 | (uintptr_t) bsp_processor_count, |
---|
63 | rtems_configuration_get_maximum_processors() ); |
---|
64 | |
---|
65 | /* We expect the L1 caches and program flow prediction to be off */ |
---|
66 | assert( ( ctrl & ARM_CP15_CTRL_I ) == 0 ); |
---|
67 | assert( ( ctrl & ARM_CP15_CTRL_C ) == 0 ); |
---|
68 | assert( ( ctrl & ARM_CP15_CTRL_Z ) == 0 ); |
---|
69 | |
---|
70 | ctrl = arm_cp15_start_setup_mmu_and_cache( |
---|
71 | ARM_CP15_CTRL_A | ARM_CP15_CTRL_M, |
---|
72 | ARM_CP15_CTRL_AFE |
---|
73 | ); |
---|
74 | |
---|
75 | if( CPU_ID == 0 ) { |
---|
76 | arm_cp15_start_setup_translation_table( |
---|
77 | (uint32_t *) bsp_translation_table_base, |
---|
78 | ARM_MMU_DEFAULT_CLIENT_DOMAIN, |
---|
79 | &altcycv_mmu_config_table[0], |
---|
80 | RTEMS_ARRAY_SIZE( altcycv_mmu_config_table ) |
---|
81 | ); |
---|
82 | } else { |
---|
83 | /* FIXME: Sharing the translation table between processors is brittle */ |
---|
84 | arm_cp15_set_translation_table_base((uint32_t *) bsp_translation_table_base); |
---|
85 | } |
---|
86 | |
---|
87 | /* Enable MMU */ |
---|
88 | ctrl |= ARM_CP15_CTRL_M; |
---|
89 | |
---|
90 | arm_cp15_set_control( ctrl ); |
---|
91 | |
---|
92 | if( CPU_ID == (CORES - 1) ) { |
---|
93 | /* Enable all cache levels for the last core */ |
---|
94 | rtems_cache_enable_instruction(); |
---|
95 | rtems_cache_enable_data(); |
---|
96 | } else { |
---|
97 | /* Enable only L1 cache */ |
---|
98 | arm_cache_l1_enable_data(); |
---|
99 | arm_cache_l1_enable_instruction(); |
---|
100 | } |
---|
101 | |
---|
102 | /* Enable flow control prediction aka. branch prediction */ |
---|
103 | |
---|
104 | /* TODO: With the current network stack 06-Feb2014 in_checksum() |
---|
105 | * becomes a severe performance bottle neck with branch prediction enabled |
---|
106 | ctrl |= ARM_CP15_CTRL_Z; |
---|
107 | arm_cp15_set_control(ctrl);*/ |
---|
108 | } |
---|
109 | |
---|
110 | BSP_START_TEXT_SECTION void bsp_start_hook_0( void ) |
---|
111 | { |
---|
112 | uint32_t ctrl; |
---|
113 | volatile a9mpcore_scu *scu = (volatile a9mpcore_scu *) BSP_ARM_A9MPCORE_SCU_BASE; |
---|
114 | uint32_t cpu_id = arm_cortex_a9_get_multiprocessor_cpu_id(); |
---|
115 | const uint32_t CORES = BSPSTARTHOOKS_MIN( |
---|
116 | (uintptr_t) bsp_processor_count, |
---|
117 | rtems_configuration_get_maximum_processors() ); |
---|
118 | |
---|
119 | assert( cpu_id < CORES ); |
---|
120 | |
---|
121 | if( cpu_id < CORES ) { |
---|
122 | if( cpu_id == 0 ) { |
---|
123 | ctrl = arm_cp15_mmu_disable( 32 ); |
---|
124 | |
---|
125 | ctrl &= ~( ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_Z ); |
---|
126 | arm_cp15_set_control( ctrl ); |
---|
127 | |
---|
128 | /* Enable Snoop Control Unit (SCU) */ |
---|
129 | arm_a9mpcore_start_scu_enable( scu ); |
---|
130 | } |
---|
131 | |
---|
132 | #ifdef RTEMS_SMP |
---|
133 | /* Enable cache coherency support for this processor */ |
---|
134 | uint32_t actlr = arm_cp15_get_auxiliary_control(); |
---|
135 | actlr |= ARM_CORTEX_A9_ACTL_SMP | ARM_CORTEX_A9_ACTL_FW; |
---|
136 | arm_cp15_set_auxiliary_control(actlr); |
---|
137 | #endif |
---|
138 | |
---|
139 | if (cpu_id == 0) { |
---|
140 | arm_a9mpcore_start_scu_invalidate(scu, cpu_id, 0xF); |
---|
141 | } |
---|
142 | |
---|
143 | setup_mmu_and_cache( cpu_id ); |
---|
144 | |
---|
145 | #ifdef RTEMS_SMP |
---|
146 | if (cpu_id != 0) { |
---|
147 | arm_a9mpcore_start_set_vector_base(); |
---|
148 | |
---|
149 | arm_gic_irq_initialize_secondary_cpu(); |
---|
150 | |
---|
151 | arm_cp15_set_domain_access_control( |
---|
152 | ARM_CP15_DAC_DOMAIN(ARM_MMU_DEFAULT_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT) |
---|
153 | ); |
---|
154 | _SMP_Start_multitasking_on_secondary_processor(); |
---|
155 | } |
---|
156 | #endif |
---|
157 | } else { |
---|
158 | /* FIXME: Shutdown processor */ |
---|
159 | while (1) { |
---|
160 | __asm__ volatile ("wfi"); |
---|
161 | } |
---|
162 | } |
---|
163 | } |
---|
164 | |
---|
165 | BSP_START_TEXT_SECTION void bsp_start_hook_1( void ) |
---|
166 | { |
---|
167 | uint32_t addr_filt_start; |
---|
168 | uint32_t addr_filt_end; |
---|
169 | |
---|
170 | /* Disable ECC. Preloader respectively UBoot enable ECC. |
---|
171 | But they do run without interrupts. Our BSP will enable interrupts |
---|
172 | and get spurious ECC error interrupts. Thus we disasable ECC |
---|
173 | until we either know about a better handling or Altera has modified |
---|
174 | it's SDRAM settings to not create possibly false ECC errors */ |
---|
175 | uint32_t ctlcfg = alt_read_word( ALT_SDR_CTL_CTLCFG_ADDR ); |
---|
176 | ctlcfg &= ALT_SDR_CTL_CTLCFG_ECCEN_CLR_MSK; |
---|
177 | alt_write_word( ALT_SDR_CTL_CTLCFG_ADDR, ctlcfg ); |
---|
178 | |
---|
179 | /* Perform L3 remap register programming first by setting the desired new MPU |
---|
180 | address space 0 mapping. Assume BOOTROM in order to be able to boot the |
---|
181 | second core. */ |
---|
182 | alt_addr_space_remap( |
---|
183 | ALT_ADDR_SPACE_MPU_ZERO_AT_BOOTROM, |
---|
184 | ALT_ADDR_SPACE_NONMPU_ZERO_AT_SDRAM, |
---|
185 | ALT_ADDR_SPACE_H2F_ACCESSIBLE, |
---|
186 | ALT_ADDR_SPACE_LWH2F_ACCESSIBLE ); |
---|
187 | |
---|
188 | /* Next, adjust the L2 cache address filtering range. Set the start address |
---|
189 | * to the default reset value and retain the existing end address |
---|
190 | * configuration. */ |
---|
191 | alt_l2_addr_filter_cfg_get( &addr_filt_start, &addr_filt_end ); |
---|
192 | |
---|
193 | if ( addr_filt_start != BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET ) { |
---|
194 | alt_l2_addr_filter_cfg_set( BSPSTART_L2_CACHE_ADDR_FILTERING_START_RESET, |
---|
195 | addr_filt_end ); |
---|
196 | } |
---|
197 | |
---|
198 | arm_a9mpcore_start_hook_1(); |
---|
199 | bsp_start_copy_sections(); |
---|
200 | |
---|
201 | bsp_start_clear_bss(); |
---|
202 | } |
---|