From 5e92a40a38dc65958e56313f3a638cfe20c4b82b Mon Sep 17 00:00:00 2001 From: Daniel Hellstrom Date: Wed, 21 May 2014 09:37:16 +0200 Subject: 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. --- c/src/lib/libbsp/sparc/leon3/Makefile.am | 4 +- c/src/lib/libbsp/sparc/leon3/configure.ac | 2 +- c/src/lib/libbsp/sparc/leon3/startup/bspclean.c | 87 +++++++++++++++++++++++++ c/src/lib/libbsp/sparc/leon3/startup/bspreset.c | 62 ------------------ 4 files changed, 90 insertions(+), 65 deletions(-) create mode 100644 c/src/lib/libbsp/sparc/leon3/startup/bspclean.c delete mode 100644 c/src/lib/libbsp/sparc/leon3/startup/bspreset.c (limited to 'c/src/lib/libbsp/sparc') diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am index fa297acdc4..c5c9b77826 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 8ace8a30fd..c29dc529bb 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_POWER_DOWN_AT_FATAL_HALT], [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..0d7d85552e --- /dev/null +++ b/c/src/lib/libbsp/sparc/leon3/startup/bspclean.c @@ -0,0 +1,87 @@ +/** + * @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 + * + * + * 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 +#include +#include +#include +#include + +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) { + const Scheduler_Assignment *assignment = _Scheduler_Get_assignment( i ); + + if ( (i != self_cpu) && + _Scheduler_Should_start_processor( assignment ) ) { + 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 - * - * - * 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 - -#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 */ -- cgit v1.2.3