forked from Imagelibrary/rtems
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.
This commit is contained in:
@@ -32,14 +32,14 @@ noinst_LIBRARIES += libbsp.a
|
|||||||
libbsp_a_SOURCES =
|
libbsp_a_SOURCES =
|
||||||
|
|
||||||
# startup
|
# 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 \
|
../../shared/bsppost.c ../../shared/bootcard.c startup/bspstart.c \
|
||||||
../../sparc/shared/bsppretaskinghook.c startup/bsppredriver.c \
|
../../sparc/shared/bsppretaskinghook.c startup/bsppredriver.c \
|
||||||
../../sparc/shared/startup/bspgetworkarea.c ../../shared/sbrk.c \
|
../../sparc/shared/startup/bspgetworkarea.c ../../shared/sbrk.c \
|
||||||
startup/setvec.c \
|
startup/setvec.c \
|
||||||
startup/spurious.c startup/bspidle.S startup/bspdelay.c \
|
startup/spurious.c startup/bspidle.S startup/bspdelay.c \
|
||||||
../../shared/bspinit.c ../../sparc/shared/startup/early_malloc.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 += startup/cpucounter.c
|
||||||
libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
|
libbsp_a_SOURCES += ../../sparc/shared/startup/bsp_fatal_exit.c
|
||||||
libbsp_a_SOURCES += startup/bsp_fatal_halt.c
|
libbsp_a_SOURCES += startup/bsp_fatal_halt.c
|
||||||
|
|||||||
@@ -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
|
[If defined, CPU is powered down on fatal exit. Otherwise generate system
|
||||||
error which will hand over to debugger, simulator, etc.])
|
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
|
RTEMS_BSP_LINKCMDS
|
||||||
|
|
||||||
# Explicitly list all Makefiles here
|
# Explicitly list all Makefiles here
|
||||||
|
|||||||
87
c/src/lib/libbsp/sparc/leon3/startup/bspclean.c
Normal file
87
c/src/lib/libbsp/sparc/leon3/startup/bspclean.c
Normal file
@@ -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
|
||||||
|
* <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>
|
||||||
|
#include <rtems/score/schedulerimpl.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) {
|
||||||
|
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
|
||||||
|
}
|
||||||
@@ -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 */
|
|
||||||
Reference in New Issue
Block a user