From 99648958668d3a33ee57974479b36201fe303f34 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 20 Apr 2018 10:35:35 +0200 Subject: bsps: Move startup files to bsps Adjust build support files to new directory layout. This patch is a part of the BSP source reorganization. Update #3285. --- bsps/powerpc/qoriq/start/bsprestart.c | 146 ++++++++++++++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 bsps/powerpc/qoriq/start/bsprestart.c (limited to 'bsps/powerpc/qoriq/start/bsprestart.c') diff --git a/bsps/powerpc/qoriq/start/bsprestart.c b/bsps/powerpc/qoriq/start/bsprestart.c new file mode 100644 index 0000000000..36e751e50d --- /dev/null +++ b/bsps/powerpc/qoriq/start/bsprestart.c @@ -0,0 +1,146 @@ +/** + * @file + * + * @ingroup QorIQ + * + * @brief BSP restart. + */ + +/* + * Copyright (c) 2016, 2018 embedded brains GmbH. All rights reserved. + * + * embedded brains GmbH + * Dornierstr. 4 + * 82178 Puchheim + * Germany + * + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.org/license/LICENSE. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include + +static char fdt_copy[BSP_FDT_BLOB_SIZE_MAX]; + +static RTEMS_NO_RETURN void do_restart(void *addr) +{ + void (*restart)(uintptr_t); + + qoriq_reset_qman_and_bman(); + + memcpy(fdt_copy, bsp_fdt_get(), sizeof(fdt_copy)); + rtems_cache_flush_multiple_data_lines(fdt_copy, sizeof(fdt_copy)); + + restart = addr; + (*restart)((uintptr_t) fdt_copy); + bsp_fatal(QORIQ_FATAL_RESTART_FAILED); +} + +#if defined(RTEMS_SMP) && !defined(QORIQ_IS_HYPERVISOR_GUEST) + +#include +#include + +#define RESTART_IPI_INDEX 1 + +static SMP_barrier_Control restart_barrier = SMP_BARRIER_CONTROL_INITIALIZER; + +static void restart_interrupt(void *arg) +{ + uint32_t cpu_self_index; + uint32_t thread_index; + rtems_interrupt_level level; + SMP_barrier_State bs; + + rtems_interrupt_local_disable(level); + (void) level; + + _SMP_barrier_State_initialize(&bs); + _SMP_barrier_Wait(&restart_barrier, &bs, _SMP_Processor_count); + + cpu_self_index = rtems_get_current_processor(); + thread_index = cpu_self_index % QORIQ_THREAD_COUNT; + + if (cpu_self_index == 0) { + do_restart(arg); + } else if (thread_index == 0) { + uint32_t real_processor_index; + const qoriq_start_spin_table *spin_table; + + real_processor_index = cpu_self_index / QORIQ_THREAD_COUNT; + spin_table = qoriq_start_spin_table_addr[real_processor_index]; + + qoriq_restart_secondary_processor(spin_table); + } else { + uint32_t pir_reset_value; + + /* Restore reset PIR value */ + pir_reset_value = (cpu_self_index & ~0x1U) << 2; + PPC_SET_SPECIAL_PURPOSE_REGISTER(BOOKE_PIR, pir_reset_value); + + /* Thread Enable Clear (TENC) */ + PPC_SET_SPECIAL_PURPOSE_REGISTER(FSL_EIS_TENC, 1U << thread_index); + + RTEMS_UNREACHABLE(); + } +} + +static void raise_restart_interrupt(void) +{ + qoriq.pic.ipidr[RESTART_IPI_INDEX].reg = + _Processor_mask_To_uint32_t(_SMP_Get_online_processors(), 0); + ppc_synchronize_data(); + ppc_synchronize_instructions(); +} + +void bsp_restart(void *addr) +{ + rtems_status_code sc; + size_t i; + + for (i = 0; i < RTEMS_ARRAY_SIZE(qoriq_start_spin_table_addr); ++i) { + qoriq_start_spin_table *spin_table; + + spin_table = qoriq_start_spin_table_addr[i]; + memset(spin_table, 0, sizeof(*spin_table)); + rtems_cache_flush_multiple_data_lines(spin_table, sizeof(*spin_table)); + } + + sc = rtems_interrupt_handler_install( + QORIQ_IRQ_IPI_0 + RESTART_IPI_INDEX, + "Restart", + RTEMS_INTERRUPT_UNIQUE, + restart_interrupt, + addr + ); + if (sc != RTEMS_SUCCESSFUL) { + bsp_fatal(QORIQ_FATAL_RESTART_INSTALL_INTERRUPT); + } + + raise_restart_interrupt(); + bsp_fatal(QORIQ_FATAL_RESTART_INTERRUPT_FAILED); +} + +#else /* !RTEMS_SMP || QORIQ_IS_HYPERVISOR_GUEST */ + +void bsp_restart(void *addr) +{ + rtems_interrupt_level level; + + rtems_interrupt_local_disable(level); + (void) level; + do_restart(addr); +} + +#endif /* RTEMS_SMP && !QORIQ_IS_HYPERVISOR_GUEST */ -- cgit v1.2.3