[PATCH 5/5] LEON3: use CPU_Fatal_halt for halt

Joel Sherrill joel.sherrill at oarcorp.com
Thu Jul 3 15:00:00 UTC 2014


On 7/3/2014 2:29 AM, Daniel Hellstrom wrote:
> 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.

And in the last patch, the reason for this series. :)

Do we need a generic call to bsp_fatal_halt() before
_CPU_Fatal_halt() in interr.c?

And move setting _Internal_errors_What_happened
up to just after disable interrupts?

I am more comfortable adding a cross-architecture
solution than hacking on _CPU_Fatal_halt() and
introducing architecture specific differences. Sebastian
did a nice job cleaning this path up. If there is a case
missing, then we need to address it in a cross-BSP way.

Hopefully Sebastian will pipe up soon.

> ---
>  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 |   84 +++++++++++++++++++++++
>  c/src/lib/libbsp/sparc/leon3/startup/bspreset.c |   62 -----------------
>  4 files changed, 87 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
>
> diff --git a/c/src/lib/libbsp/sparc/leon3/Makefile.am b/c/src/lib/libbsp/sparc/leon3/Makefile.am
> index d1f07a7..9e60046 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 206a662..90e3b2b 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 0000000..3a036a0
> --- /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 at 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 c642a75..0000000
> --- 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 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/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 */

-- 
Joel Sherrill, Ph.D.             Director of Research & Development
joel.sherrill at OARcorp.com        On-Line Applications Research
Ask me about RTEMS: a free RTOS  Huntsville AL 35805
Support Available                (256) 722-9985



More information about the devel mailing list