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.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel