Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:58

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSBSPsPowerPCQorIQ
0007  *
0008  * @brief BSP startup.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2010, 2017 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
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 /* Configuration parameters for console driver, ... */
0062 unsigned int BSP_bus_frequency;
0063 
0064 /* Configuration parameter for clock driver, ... */
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    * Get CPU identification dynamically. Note that the get_ppc_cpu_type() function
0173    * store the result in global variables so that it can be used latter...
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   /* Disable boot page translation */
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