summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Hellstrom <daniel@gaisler.com>2014-05-21 09:37:16 +0200
committerDaniel Cederman <cederman@gaisler.com>2014-06-27 11:03:24 +0200
commitd1578ad2e344165946332833864bd39f2dbc9e26 (patch)
tree2045eb61f19ca8306263f3c295dbec7f85aa4e50
parent31d0e1d7be3726840cb2edb1c7a26972decc48dc (diff)
LEON3: use CPU_Fatal_halt for halt
By removing the bsp_reset() mechanism and instead relying on the CPU_Fatal_halt() routine SMP and single-core can halt by updating the _Internal_errors_What_happened structure and set the state to SYSTEM_STATE_TERMINATED (the generic way). This will be better for test scripts and debugger that can generically look into why the OS stopped. For SMP systems, only the fatal-reporting CPU waits until all other CPUs are powered down (with a time out of one clock tick). The reason why a fatal stop happend may be because CPU0 was soft-locked up so we can never trust that CPU0 should do the halt for us.
-rw-r--r--c/src/lib/libbsp/sparc/leon3/Makefile.am4
-rw-r--r--c/src/lib/libbsp/sparc/leon3/configure.ac2
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/bspclean.c84
-rw-r--r--c/src/lib/libbsp/sparc/leon3/startup/bspreset.c62
4 files changed, 87 insertions, 65 deletions
diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
index d1f07a7f1f..9e600465ee 100644
--- a/c/src/lib/libbsp/sparc/leon3/Makefile.am
+++ b/c/src/lib/libbsp/sparc/leon3/Makefile.am
@@ -32,14 +32,14 @@ noinst_LIBRARIES += libbsp.a
libbsp_a_SOURCES =
# startup
-libbsp_a_SOURCES += ../../shared/bspclean.c ../../shared/bsplibc.c \
+libbsp_a_SOURCES += startup/bspclean.c
+libbsp_a_SOURCES += ../../shared/bsplibc.c \
../../shared/bsppost.c ../../shared/bootcard.c startup/bspstart.c \
../../sparc/shared/bsppretaskinghook.c startup/bsppredriver.c \
../../sparc/shared/startup/bspgetworkarea.c ../../shared/sbrk.c \
startup/setvec.c \
startup/spurious.c startup/bspidle.S startup/bspdelay.c \
../../shared/bspinit.c ../../sparc/shared/startup/early_malloc.c
-libbsp_a_SOURCES += startup/bspreset.c
libbsp_a_SOURCES += startup/cpucounter.c
libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
libbsp_a_SOURCES += startup/bsp_fatal_halt.c
diff --git a/c/src/lib/libbsp/sparc/leon3/configure.ac b/c/src/lib/libbsp/sparc/leon3/configure.ac
index 206a662c3a..90e3b2bdb7 100644
--- a/c/src/lib/libbsp/sparc/leon3/configure.ac
+++ b/c/src/lib/libbsp/sparc/leon3/configure.ac
@@ -43,7 +43,7 @@ RTEMS_BSPOPTS_HELP([BSP_HALT_AT_FATAL_EXIT],
[If defined, CPU is powered down on fatal exit. Otherwise generate system
error which will hand over to debugger, simulator, etc.])
-RTEMS_BSP_CLEANUP_OPTIONS(0, 1, 1)
+RTEMS_BSP_CLEANUP_OPTIONS(0, 0, 1)
RTEMS_BSP_LINKCMDS
# Explicitly list all Makefiles here
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspclean.c b/c/src/lib/libbsp/sparc/leon3/startup/bspclean.c
new file mode 100644
index 0000000000..3a036a010d
--- /dev/null
+++ b/c/src/lib/libbsp/sparc/leon3/startup/bspclean.c
@@ -0,0 +1,84 @@
+/**
+ * @file
+ * @ingroup sparc_leon3
+ * @brief LEON3 BSP fatal extension
+ *
+ * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
+ *
+ * embedded brains GmbH
+ * Dornierstr. 4
+ * 82178 Puchheim
+ * Germany
+ * <rtems@embedded-brains.de>
+ *
+ * COPYRIGHT (c) 2014
+ * Aeroflex Gaisler
+ *
+ * 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/bootcard.h>
+#include <rtems/bspIo.h>
+#include <rtems/score/smpimpl.h>
+
+void bsp_fatal_extension(
+ rtems_fatal_source source,
+ bool is_internal,
+ rtems_fatal_code code
+)
+{
+ /* On SMP we must wait for all other CPUs not requesting a fatal halt, they
+ * are responding to another CPU's fatal request. These CPUs goes into
+ * power-down. The CPU requesting fatal halt waits for the others and then
+ * handles the system shutdown via the normal procedure.
+ */
+ #ifdef RTEMS_SMP
+ if ((source == RTEMS_FATAL_SOURCE_SMP) &&
+ (code == SMP_FATAL_SHUTDOWN_RESPONSE)) {
+ leon3_power_down_loop(); /* CPU didn't start shutdown sequence .. */
+ } else {
+ volatile struct irqmp_regs *irqmp = LEON3_IrqCtrl_Regs;
+
+ if (irqmp != NULL) {
+ /*
+ * Value was choosen to get something in the magnitude of 1ms on a 200MHz
+ * processor.
+ */
+ uint32_t max_wait = 1234567;
+ uint32_t self_cpu = rtems_get_current_processor();
+
+ uint32_t cpu_count = rtems_get_processor_count();
+ uint32_t halt_mask = 0;
+ uint32_t i;
+
+ for (i = 0; i < cpu_count; ++i) {
+ if (i != self_cpu) {
+ halt_mask |= UINT32_C(1) << i;
+ }
+ }
+
+ /* Wait some time for secondary processors to halt */
+ i = 0;
+ while ((irqmp->mpstat & halt_mask) != halt_mask && i < max_wait) {
+ ++i;
+ }
+ }
+ }
+ #endif
+
+ #if (BSP_PRINT_EXCEPTION_CONTEXT)
+ if ( source == RTEMS_FATAL_SOURCE_EXCEPTION ) {
+ rtems_exception_frame_print( (const rtems_exception_frame *) code );
+ }
+ #endif
+
+ /*
+ * If user wants to implement custom reset/reboot it can be done here
+ */
+ #if (BSP_RESET_BOARD_AT_EXIT)
+ bsp_reset();
+ #endif
+}
diff --git a/c/src/lib/libbsp/sparc/leon3/startup/bspreset.c b/c/src/lib/libbsp/sparc/leon3/startup/bspreset.c
deleted file mode 100644
index c642a75623..0000000000
--- a/c/src/lib/libbsp/sparc/leon3/startup/bspreset.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 2014 embedded brains GmbH. All rights reserved.
- *
- * embedded brains GmbH
- * Dornierstr. 4
- * 82178 Puchheim
- * Germany
- * <rtems@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/bootcard.h>
-#include <leon.h>
-
-#ifdef RTEMS_SMP
-
-void bsp_reset(void)
-{
- uint32_t self_cpu = rtems_get_current_processor();
-
- if (self_cpu == 0) {
- volatile struct irqmp_regs *irqmp = LEON3_IrqCtrl_Regs;
-
- if (irqmp != NULL) {
- /*
- * Value was choosen to get something in the magnitude of 1ms on a 200MHz
- * processor.
- */
- uint32_t max_wait = 1234567;
-
- uint32_t cpu_count = rtems_get_processor_count();
- uint32_t halt_mask = 0;
- uint32_t i;
-
- for (i = 0; i < cpu_count; ++i) {
- if (i != self_cpu) {
- halt_mask |= UINT32_C(1) << i;
- }
- }
-
- /* Wait some time for secondary processors to halt */
- i = 0;
- while ((irqmp->mpstat & halt_mask) != halt_mask && i < max_wait) {
- ++i;
- }
- }
-
- __asm__ volatile (
- "mov 1, %g1\n"
- "ta 0\n"
- "nop"
- );
- }
-
- leon3_power_down_loop();
-}
-
-#endif /* RTEMS_SMP */