File indexing completed on 2025-05-11 08:23:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <libfdt.h>
0037
0038 #include <rtems.h>
0039 #include <rtems/config.h>
0040 #include <rtems/counter.h>
0041 #include <rtems/sysinit.h>
0042
0043 #include <libcpu/powerpc-utility.h>
0044
0045 #include <bsp.h>
0046 #include <bsp/bootcard.h>
0047 #include <bsp/fatal.h>
0048 #include <bsp/fdt.h>
0049 #include <bsp/intercom.h>
0050 #include <bsp/irq-generic.h>
0051 #include <bsp/linker-symbols.h>
0052 #include <bsp/mmu.h>
0053 #include <bsp/qoriq.h>
0054 #include <bsp/vectors.h>
0055
0056 LINKER_SYMBOL(bsp_exc_vector_base);
0057
0058 qoriq_start_spin_table *
0059 qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT];
0060
0061
0062 unsigned int BSP_bus_frequency;
0063
0064
0065 uint32_t bsp_time_base_frequency;
0066
0067 uint32_t qoriq_clock_frequency;
0068
0069 uint32_t _CPU_Counter_frequency(void)
0070 {
0071 #ifdef __PPC_CPU_E6500__
0072 return qoriq_clock_frequency;
0073 #else
0074 return bsp_time_base_frequency;
0075 #endif
0076 }
0077
0078 static void initialize_frequency_parameters(void)
0079 {
0080 const void *fdt = bsp_fdt_get();
0081 int node;
0082 int len;
0083 fdt32_t *val_fdt;
0084
0085 node = fdt_node_offset_by_prop_value(fdt, -1, "device_type", "cpu", 4);
0086
0087 val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "bus-frequency", &len);
0088 if (val_fdt == NULL || len != 4) {
0089 bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
0090 }
0091 BSP_bus_frequency = fdt32_to_cpu(*val_fdt) / QORIQ_BUS_CLOCK_DIVIDER;
0092
0093 val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "timebase-frequency", &len);
0094 if (val_fdt == NULL || len != 4) {
0095 bsp_fatal(QORIQ_FATAL_FDT_NO_BUS_FREQUENCY);
0096 }
0097 bsp_time_base_frequency = fdt32_to_cpu(*val_fdt);
0098
0099 #ifdef __PPC_CPU_E6500__
0100 val_fdt = (fdt32_t *) fdt_getprop(fdt, node, "clock-frequency", &len);
0101 if (val_fdt == NULL || len != 4) {
0102 bsp_fatal(QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY);
0103 }
0104 qoriq_clock_frequency = fdt32_to_cpu(*val_fdt);
0105 #endif
0106 }
0107
0108 #ifdef __powerpc64__
0109 #define VECTOR_TABLE_ENTRY_SIZE 32
0110 #else
0111 #define VECTOR_TABLE_ENTRY_SIZE 16
0112 #endif
0113
0114 #define MTIVOR(vec, offset) \
0115 do { \
0116 __asm__ volatile ("mtspr " RTEMS_XSTRING(vec) ", %0" : : "r" (offset)); \
0117 offset += VECTOR_TABLE_ENTRY_SIZE; \
0118 } while (0)
0119
0120 void qoriq_initialize_exceptions(void *interrupt_stack_begin)
0121 {
0122 uintptr_t addr;
0123
0124 ppc_exc_initialize_interrupt_stack(
0125 (uintptr_t) interrupt_stack_begin
0126 );
0127
0128 addr = (uintptr_t) bsp_exc_vector_base;
0129 ppc_mtivpr((void *) addr);
0130 MTIVOR(BOOKE_IVOR0, addr);
0131 MTIVOR(BOOKE_IVOR1, addr);
0132 MTIVOR(BOOKE_IVOR2, addr);
0133 MTIVOR(BOOKE_IVOR3, addr);
0134 MTIVOR(BOOKE_IVOR4, addr);
0135 MTIVOR(BOOKE_IVOR5, addr);
0136 MTIVOR(BOOKE_IVOR6, addr);
0137 #ifdef __PPC_CPU_E6500__
0138 MTIVOR(BOOKE_IVOR7, addr);
0139 #endif
0140 MTIVOR(BOOKE_IVOR8, addr);
0141 #ifdef __PPC_CPU_E6500__
0142 MTIVOR(BOOKE_IVOR9, addr);
0143 #endif
0144 MTIVOR(BOOKE_IVOR10, addr);
0145 MTIVOR(BOOKE_IVOR11, addr);
0146 MTIVOR(BOOKE_IVOR12, addr);
0147 MTIVOR(BOOKE_IVOR13, addr);
0148 MTIVOR(BOOKE_IVOR14, addr);
0149 MTIVOR(BOOKE_IVOR15, addr);
0150 MTIVOR(BOOKE_IVOR32, addr);
0151 MTIVOR(BOOKE_IVOR33, addr);
0152 #ifndef __PPC_CPU_E6500__
0153 MTIVOR(BOOKE_IVOR34, addr);
0154 #endif
0155 MTIVOR(BOOKE_IVOR35, addr);
0156 #ifdef __PPC_CPU_E6500__
0157 MTIVOR(BOOKE_IVOR36, addr);
0158 MTIVOR(BOOKE_IVOR37, addr);
0159 #ifndef QORIQ_IS_HYPERVISOR_GUEST
0160 MTIVOR(BOOKE_IVOR38, addr);
0161 MTIVOR(BOOKE_IVOR39, addr);
0162 MTIVOR(BOOKE_IVOR40, addr);
0163 MTIVOR(BOOKE_IVOR41, addr);
0164 MTIVOR(BOOKE_IVOR42, addr);
0165 #endif
0166 #endif
0167 }
0168
0169 void bsp_start(void)
0170 {
0171
0172
0173
0174
0175 get_ppc_cpu_type();
0176 get_ppc_cpu_revision();
0177
0178 initialize_frequency_parameters();
0179
0180 qoriq_initialize_exceptions(_ISR_Stack_area_begin);
0181 bsp_interrupt_initialize();
0182
0183 rtems_cache_coherent_add_area(
0184 bsp_section_nocacheheap_begin,
0185 (uintptr_t) bsp_section_nocacheheap_size
0186 );
0187
0188 #ifndef QORIQ_IS_HYPERVISOR_GUEST
0189
0190 #if QORIQ_CHIP_IS_T_VARIANT(QORIQ_CHIP_VARIANT)
0191 qoriq.lcc.bstar &= ~LCC_BSTAR_EN;
0192 #else
0193 qoriq.lcc.bptr &= ~BPTR_EN;
0194 #endif
0195 #endif
0196 }
0197
0198 uint32_t bsp_fdt_map_intr(const uint32_t *intr, size_t icells)
0199 {
0200 #ifndef QORIQ_IS_HYPERVISOR_GUEST
0201 return intr[0] - 16;
0202 #else
0203 return intr[0];
0204 #endif
0205 }
0206
0207 #ifdef RTEMS_MULTIPROCESSING
0208 RTEMS_SYSINIT_ITEM(
0209 qoriq_intercom_init,
0210 RTEMS_SYSINIT_BSP_PRE_DRIVERS,
0211 RTEMS_SYSINIT_ORDER_MIDDLE
0212 );
0213 #endif