[rtems commit] bsp/qoriq: Add bsp_restart()

Sebastian Huber sebh at rtems.org
Fri Apr 22 12:31:11 UTC 2016


Module:    rtems
Branch:    master
Commit:    d8f4689dba6a11c2449d0e673cff5abcb9a07015
Changeset: http://git.rtems.org/rtems/commit/?id=d8f4689dba6a11c2449d0e673cff5abcb9a07015

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Apr 22 14:03:43 2016 +0200

bsp/qoriq: Add bsp_restart()

---

 c/src/lib/libbsp/powerpc/qoriq/Makefile.am         |   4 +-
 c/src/lib/libbsp/powerpc/qoriq/include/bsp.h       |   6 +
 .../lib/libbsp/powerpc/qoriq/startup/bsprestart.c  | 144 +++++++++++++++++++++
 c/src/lib/libbsp/powerpc/qoriq/startup/restart.S   |  80 ++++++++++++
 c/src/lib/libbsp/shared/include/fatal.h            |   5 +-
 5 files changed, 237 insertions(+), 2 deletions(-)

diff --git a/c/src/lib/libbsp/powerpc/qoriq/Makefile.am b/c/src/lib/libbsp/powerpc/qoriq/Makefile.am
index 2fd34e9..25def4f 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/Makefile.am
+++ b/c/src/lib/libbsp/powerpc/qoriq/Makefile.am
@@ -75,9 +75,11 @@ libbsp_a_SOURCES += \
 	startup/mmu.c \
 	startup/mmu-tlb1.S \
 	startup/mmu-config.c \
+	startup/restart.S \
 	startup/bsppredriverhook.c \
 	startup/bspstart.c \
-	startup/bspreset.c
+	startup/bspreset.c \
+	startup/bsprestart.c
 
 # Clock
 libbsp_a_SOURCES += clock/clock-config.c \
diff --git a/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h b/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h
index 089c8ca..d1fd907 100644
--- a/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h
+++ b/c/src/lib/libbsp/powerpc/qoriq/include/bsp.h
@@ -68,6 +68,8 @@ int qoriq_if_intercom_attach_detach(
   );
 #endif
 
+void bsp_restart(void *addr) RTEMS_NO_RETURN;
+
 void *bsp_idle_thread( uintptr_t ignored );
 #define BSP_IDLE_TASK_BODY bsp_idle_thread
 
@@ -98,6 +100,10 @@ qoriq_start_spin_table_addr[QORIQ_CPU_COUNT / QORIQ_THREAD_COUNT];
 
 void qoriq_start_thread(void);
 
+void qoriq_restart_secondary_processor(
+  const qoriq_start_spin_table *spin_table
+) RTEMS_NO_RETURN;
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/bsprestart.c b/c/src/lib/libbsp/powerpc/qoriq/startup/bsprestart.c
new file mode 100644
index 0000000..7df5135
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/qoriq/startup/bsprestart.c
@@ -0,0 +1,144 @@
+/**
+ * @file
+ *
+ * @ingroup QorIQ
+ *
+ * @brief BSP restart.
+ */
+
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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 <bsp.h>
+#include <bsp/irq.h>
+#include <bsp/fatal.h>
+#include <bsp/fdt.h>
+#include <bsp/linker-symbols.h>
+#include <bsp/qoriq.h>
+
+#include <libcpu/powerpc-utility.h>
+
+static RTEMS_NO_RETURN void do_restart(void *addr)
+{
+  void (*restart)(uintptr_t);
+  uintptr_t fdt;
+
+  restart = addr;
+
+  fdt = (uintptr_t) bsp_fdt_get();
+#ifdef BSP_FDT_BLOB_READ_ONLY
+  fdt -= (uintptr_t) bsp_section_rodata_begin;
+  fdt += (uintptr_t) bsp_section_rodata_load_begin;
+#endif
+
+  (*restart)(fdt);
+  bsp_fatal(QORIQ_FATAL_RESTART_FAILED);
+}
+
+#ifdef RTEMS_SMP
+
+#include <rtems/score/smpimpl.h>
+#include <rtems/score/smpbarrier.h>
+
+#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 = _SMP_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 */
+
+void bsp_restart(void *addr)
+{
+  rtems_interrupt_level level;
+
+  rtems_interrupt_local_disable(level);
+  (void) level;
+  do_restart(addr);
+}
+
+#endif /* !RTEMS_SMP */
diff --git a/c/src/lib/libbsp/powerpc/qoriq/startup/restart.S b/c/src/lib/libbsp/powerpc/qoriq/startup/restart.S
new file mode 100644
index 0000000..7dd9eb1
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/qoriq/startup/restart.S
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2016 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Dornierstr. 4
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * 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 <libcpu/powerpc-utility.h>
+
+#define FIRST_TLB 0
+
+#define SCRATCH_TLB QORIQ_TLB1_ENTRY_COUNT - 1
+
+	.global qoriq_restart_secondary_processor
+
+	.section ".bsp_start_text", "ax"
+
+qoriq_restart_secondary_processor:
+
+	mr	r14, r3
+
+	/* Invalidate all TS1 MMU entries */
+	li	r3, 1
+	bl	qoriq_tlb1_invalidate_all_by_ts
+
+	/* Add TS1 entry for the first 4GiB of RAM */
+	li	r3, SCRATCH_TLB
+	li	r4, FSL_EIS_MAS1_TS
+	li	r5, FSL_EIS_MAS2_I
+	li	r6, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW | FSL_EIS_MAS3_SX
+	li	r7, 0
+	li	r8, 0
+	li	r9, 11
+	bl	qoriq_tlb1_write
+
+	bl	qoriq_l1cache_invalidate
+
+	/* Set MSR and use TS1 for address translation */
+	LWI	r0, QORIQ_INITIAL_MSR | MSR_IS | MSR_DS
+	mtmsr	r0
+	isync
+
+	/* Invalidate all TS0 MMU entries */
+	li	r3, 0
+	bl	qoriq_tlb1_invalidate_all_by_ts
+
+	/* Add TS0 entry for the first 4GiB of RAM */
+	li	r3, FIRST_TLB
+	li	r4, 0
+	li	r5, FSL_EIS_MAS2_I
+	li	r6, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW | FSL_EIS_MAS3_SX
+	li	r7, 0
+	li	r8, 0
+	li	r9, 11
+	bl	qoriq_tlb1_write
+
+	/* Use TS0 for address translation */
+	LWI	r0, QORIQ_INITIAL_MSR
+	mtmsr	r0
+	isync
+
+	bl	qoriq_l1cache_invalidate
+
+	/* Wait for restart request */
+	li	r0, 0
+.Lrestartagain:
+	lwz	r4, 4(r14)
+	cmpw	r0, r4
+	beq	.Lrestartagain
+	isync
+	mtctr	r4
+	lwz	r3, 12(r14)
+	bctr
diff --git a/c/src/lib/libbsp/shared/include/fatal.h b/c/src/lib/libbsp/shared/include/fatal.h
index 25dda39..783d2b1 100644
--- a/c/src/lib/libbsp/shared/include/fatal.h
+++ b/c/src/lib/libbsp/shared/include/fatal.h
@@ -118,7 +118,10 @@ typedef enum {
   QORIQ_FATAL_SMP_IPI_HANDLER_INSTALL = BSP_FATAL_CODE_BLOCK(10),
   QORIQ_FATAL_FDT_NO_BUS_FREQUENCY,
   QORIQ_FATAL_FDT_NO_CLOCK_FREQUENCY,
-  QORIQ_FATAL_FDT_NO_TIMEBASE_FREQUENCY
+  QORIQ_FATAL_FDT_NO_TIMEBASE_FREQUENCY,
+  QORIQ_FATAL_RESTART_FAILED,
+  QORIQ_FATAL_RESTART_INSTALL_INTERRUPT,
+  QORIQ_FATAL_RESTART_INTERRUPT_FAILED
 } bsp_fatal_code;
 
 RTEMS_NO_RETURN static inline void




More information about the vc mailing list