[b7212b9] | 1 | /** |
---|
| 2 | * @file |
---|
| 3 | * |
---|
| 4 | * @ingroup arm_shared |
---|
| 5 | * |
---|
| 6 | * @brief A9MPCORE_START Support |
---|
| 7 | */ |
---|
| 8 | |
---|
[db42c079] | 9 | /* |
---|
[f5c10645] | 10 | * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. |
---|
[db42c079] | 11 | * |
---|
| 12 | * embedded brains GmbH |
---|
| 13 | * Dornierstr. 4 |
---|
| 14 | * 82178 Puchheim |
---|
| 15 | * Germany |
---|
| 16 | * <info@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 |
---|
[c499856] | 20 | * http://www.rtems.org/license/LICENSE. |
---|
[db42c079] | 21 | */ |
---|
| 22 | |
---|
| 23 | #ifndef LIBBSP_ARM_SHARED_ARM_A9MPCORE_START_H |
---|
| 24 | #define LIBBSP_ARM_SHARED_ARM_A9MPCORE_START_H |
---|
| 25 | |
---|
[911b1d2] | 26 | #include <rtems/score/smpimpl.h> |
---|
[db42c079] | 27 | |
---|
| 28 | #include <libcpu/arm-cp15.h> |
---|
| 29 | |
---|
| 30 | #include <bsp.h> |
---|
| 31 | #include <bsp/start.h> |
---|
| 32 | #include <bsp/arm-a9mpcore-regs.h> |
---|
[0b74e10f] | 33 | #include <bsp/arm-errata.h> |
---|
[db42c079] | 34 | |
---|
| 35 | #ifdef __cplusplus |
---|
| 36 | extern "C" { |
---|
| 37 | #endif /* __cplusplus */ |
---|
| 38 | |
---|
[9a037da9] | 39 | BSP_START_TEXT_SECTION static inline uint32_t |
---|
| 40 | arm_cp15_get_control(void); |
---|
| 41 | |
---|
| 42 | BSP_START_TEXT_SECTION static inline void |
---|
| 43 | arm_cp15_set_control(uint32_t val); |
---|
| 44 | |
---|
[db42c079] | 45 | BSP_START_TEXT_SECTION static inline uint32_t |
---|
| 46 | arm_cp15_get_auxiliary_control(void); |
---|
| 47 | |
---|
| 48 | BSP_START_TEXT_SECTION static inline void |
---|
| 49 | arm_cp15_set_auxiliary_control(uint32_t val); |
---|
| 50 | |
---|
[9a037da9] | 51 | BSP_START_TEXT_SECTION static inline void |
---|
| 52 | arm_cp15_set_vector_base_address(void *base); |
---|
| 53 | |
---|
[0034629] | 54 | BSP_START_TEXT_SECTION static inline void |
---|
| 55 | arm_a9mpcore_start_set_vector_base(void) |
---|
[ca59217] | 56 | { |
---|
| 57 | /* |
---|
| 58 | * Do not use bsp_vector_table_begin == 0, since this will get optimized away. |
---|
| 59 | */ |
---|
| 60 | if (bsp_vector_table_end != bsp_vector_table_size) { |
---|
| 61 | uint32_t ctrl; |
---|
| 62 | |
---|
| 63 | /* |
---|
| 64 | * For now we assume that every Cortex-A9 MPCore has the Security Extensions. |
---|
| 65 | * Later it might be necessary to evaluate the ID_PFR1 register. |
---|
| 66 | */ |
---|
| 67 | arm_cp15_set_vector_base_address(bsp_vector_table_begin); |
---|
| 68 | |
---|
| 69 | ctrl = arm_cp15_get_control(); |
---|
| 70 | ctrl &= ~ARM_CP15_CTRL_V; |
---|
| 71 | arm_cp15_set_control(ctrl); |
---|
| 72 | } |
---|
| 73 | } |
---|
| 74 | |
---|
[0034629] | 75 | BSP_START_TEXT_SECTION static inline void arm_a9mpcore_start_scu_invalidate( |
---|
[f5c10645] | 76 | volatile a9mpcore_scu *scu, |
---|
| 77 | uint32_t cpu_id, |
---|
| 78 | uint32_t ways |
---|
| 79 | ) |
---|
| 80 | { |
---|
| 81 | scu->invss = (ways & 0xf) << ((cpu_id & 0x3) * 4); |
---|
| 82 | } |
---|
| 83 | |
---|
[0034629] | 84 | BSP_START_TEXT_SECTION static inline void |
---|
[0b74e10f] | 85 | arm_a9mpcore_start_errata_764369_handler(volatile a9mpcore_scu *scu) |
---|
[db42c079] | 86 | { |
---|
[0b74e10f] | 87 | if (arm_errata_is_applicable_processor_errata_764369()) { |
---|
| 88 | scu->diagn_ctrl |= A9MPCORE_SCU_DIAGN_CTRL_MIGRATORY_BIT_DISABLE; |
---|
| 89 | } |
---|
| 90 | } |
---|
[db42c079] | 91 | |
---|
[0034629] | 92 | BSP_START_TEXT_SECTION static inline void |
---|
[0b74e10f] | 93 | arm_a9mpcore_start_scu_enable(volatile a9mpcore_scu *scu) |
---|
| 94 | { |
---|
[db42c079] | 95 | scu->ctrl |= A9MPCORE_SCU_CTRL_SCU_EN; |
---|
[707b6172] | 96 | arm_a9mpcore_start_errata_764369_handler(scu); |
---|
[0b74e10f] | 97 | } |
---|
[db42c079] | 98 | |
---|
[0034629] | 99 | BSP_START_TEXT_SECTION static inline void arm_a9mpcore_start_hook_0(void) |
---|
[0b74e10f] | 100 | { |
---|
| 101 | volatile a9mpcore_scu *scu = |
---|
| 102 | (volatile a9mpcore_scu *) BSP_ARM_A9MPCORE_SCU_BASE; |
---|
| 103 | uint32_t cpu_id; |
---|
| 104 | |
---|
| 105 | arm_a9mpcore_start_scu_enable(scu); |
---|
| 106 | |
---|
| 107 | #ifdef RTEMS_SMP |
---|
[db42c079] | 108 | /* Enable cache coherency support for this processor */ |
---|
[0b74e10f] | 109 | { |
---|
| 110 | uint32_t actlr = arm_cp15_get_auxiliary_control(); |
---|
| 111 | actlr |= ARM_CORTEX_A9_ACTL_SMP; |
---|
| 112 | arm_cp15_set_auxiliary_control(actlr); |
---|
| 113 | } |
---|
| 114 | #endif |
---|
[db42c079] | 115 | |
---|
| 116 | cpu_id = arm_cortex_a9_get_multiprocessor_cpu_id(); |
---|
[f5c10645] | 117 | |
---|
| 118 | arm_a9mpcore_start_scu_invalidate(scu, cpu_id, 0xf); |
---|
| 119 | |
---|
[0b74e10f] | 120 | #ifdef RTEMS_SMP |
---|
[db42c079] | 121 | if (cpu_id != 0) { |
---|
[ca59217] | 122 | arm_a9mpcore_start_set_vector_base(); |
---|
| 123 | |
---|
[db42c079] | 124 | if (cpu_id < rtems_configuration_get_maximum_processors()) { |
---|
| 125 | uint32_t ctrl; |
---|
| 126 | |
---|
| 127 | arm_gic_irq_initialize_secondary_cpu(); |
---|
| 128 | |
---|
| 129 | ctrl = arm_cp15_start_setup_mmu_and_cache( |
---|
| 130 | 0, |
---|
| 131 | ARM_CP15_CTRL_AFE | ARM_CP15_CTRL_Z |
---|
| 132 | ); |
---|
| 133 | |
---|
| 134 | arm_cp15_set_domain_access_control( |
---|
| 135 | ARM_CP15_DAC_DOMAIN(ARM_MMU_DEFAULT_CLIENT_DOMAIN, ARM_CP15_DAC_CLIENT) |
---|
| 136 | ); |
---|
| 137 | |
---|
| 138 | /* FIXME: Sharing the translation table between processors is brittle */ |
---|
[0b74e10f] | 139 | arm_cp15_set_translation_table_base( |
---|
| 140 | (uint32_t *) bsp_translation_table_base |
---|
| 141 | ); |
---|
[db42c079] | 142 | |
---|
| 143 | ctrl |= ARM_CP15_CTRL_I | ARM_CP15_CTRL_C | ARM_CP15_CTRL_M; |
---|
| 144 | arm_cp15_set_control(ctrl); |
---|
| 145 | |
---|
[911b1d2] | 146 | _SMP_Start_multitasking_on_secondary_processor(); |
---|
[db42c079] | 147 | } else { |
---|
| 148 | /* FIXME: Shutdown processor */ |
---|
| 149 | while (1) { |
---|
| 150 | __asm__ volatile ("wfi"); |
---|
| 151 | } |
---|
| 152 | } |
---|
| 153 | } |
---|
| 154 | #endif |
---|
| 155 | } |
---|
| 156 | |
---|
[0034629] | 157 | BSP_START_TEXT_SECTION static inline void arm_a9mpcore_start_global_timer(void) |
---|
[0df8d7f2] | 158 | { |
---|
| 159 | volatile a9mpcore_gt *gt = (volatile a9mpcore_gt *) BSP_ARM_A9MPCORE_GT_BASE; |
---|
| 160 | |
---|
| 161 | gt->ctrl = 0; |
---|
| 162 | gt->cntrlower = 0; |
---|
| 163 | gt->cntrupper = 0; |
---|
| 164 | gt->ctrl = A9MPCORE_GT_CTRL_TMR_EN; |
---|
| 165 | } |
---|
| 166 | |
---|
[0034629] | 167 | BSP_START_TEXT_SECTION static inline void arm_a9mpcore_start_hook_1(void) |
---|
[9a037da9] | 168 | { |
---|
[0df8d7f2] | 169 | arm_a9mpcore_start_global_timer(); |
---|
[ca59217] | 170 | arm_a9mpcore_start_set_vector_base(); |
---|
[9a037da9] | 171 | } |
---|
| 172 | |
---|
[db42c079] | 173 | #ifdef __cplusplus |
---|
| 174 | } |
---|
| 175 | #endif /* __cplusplus */ |
---|
| 176 | |
---|
| 177 | #endif /* LIBBSP_ARM_SHARED_ARM_A9MPCORE_START_H */ |
---|