[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