[PATCH 5/5] LEON3: use CPU_Fatal_halt for halt
Sebastian Huber
sebastian.huber at embedded-brains.de
Fri Jul 4 06:25:06 UTC 2014
On 2014-07-03 09:29, 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.
The reason for updating the system state and the _Internal_errors_What_happened
structure after the fatal extensions is that this lowers the run-time
environment requirements. On uni-processor systems you need only code memory,
read-only data and a stack. Access to global read-write data is not necessary
for the initial fatal extensions.
The _CPU_Fatal_halt() is fine, I haven't done it this myself due to a lack of time.
>
> 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 is a very good change.
[...]
> +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;
> + }
> + }
The application my not run on all processors. So you should add a check like this:
const Scheduler_Assignment *assignment = _Scheduler_Get_assignment( i );
if ( _Scheduler_Should_start_processor( assignment ) ) {
halt_mask |= UINT32_C(1) << i;
}
--
Sebastian Huber, embedded brains GmbH
Address : Dornierstr. 4, D-82178 Puchheim, Germany
Phone : +49 89 189 47 41-16
Fax : +49 89 189 47 41-09
E-Mail : sebastian.huber at embedded-brains.de
PGP : Public key available on request.
Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
More information about the devel
mailing list