summaryrefslogtreecommitdiffstats
path: root/testsuites/smptests/smpfatal02
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2014-02-18 13:40:39 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2014-03-06 09:43:57 +0100
commit7336be9d78266adfb540170e5105caf8eb003d2f (patch)
tree5dc7ab7a5c3c33c7e007a8e8e48cb1167187b0ca /testsuites/smptests/smpfatal02
parentbsp/leon3: Unmask IPI only on secondary processor (diff)
downloadrtems-7336be9d78266adfb540170e5105caf8eb003d2f.tar.bz2
score: SMP initialization and shutdown changes
Rename _SMP_Request_other_cores_to_perform_first_context_switch() into _SMP_Request_start_multitasking() since this requests now a multitasking start on all configured and available processors. The name corresponds _Thread_Start_multitasking() and _SMP_Start_multitasking_on_secondary_processor() actions issued in response to this request. Move in source file to right place. Rename PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING into PER_CPU_STATE_READY_TO_START_MULTITASKING. Rename PER_CPU_STATE_BEGIN_MULTITASKING into PER_CPU_STATE_REQUEST_START_MULTITASKING. Rename _SMP_Request_other_cores_to_shutdown() into _SMP_Request_shutdown(). Add a per-CPU state lock to protect all changes. This was necessary to offer a controlled shutdown of the system (atomic read/writes alone are not sufficient for this kind of synchronization). Add documentation for Per_CPU_State. Delete debug output. New tests smptests/smpfatal01 and smptests/smpfatal02.
Diffstat (limited to 'testsuites/smptests/smpfatal02')
-rw-r--r--testsuites/smptests/smpfatal02/Makefile.am19
-rw-r--r--testsuites/smptests/smpfatal02/init.c135
-rw-r--r--testsuites/smptests/smpfatal02/smpfatal02.doc12
-rw-r--r--testsuites/smptests/smpfatal02/smpfatal02.scn2
4 files changed, 168 insertions, 0 deletions
diff --git a/testsuites/smptests/smpfatal02/Makefile.am b/testsuites/smptests/smpfatal02/Makefile.am
new file mode 100644
index 0000000000..bbce3b7b6d
--- /dev/null
+++ b/testsuites/smptests/smpfatal02/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = smpfatal02
+smpfatal02_SOURCES = init.c
+
+dist_rtems_tests_DATA = smpfatal02.scn smpfatal02.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(smpfatal02_OBJECTS)
+LINK_LIBS = $(smpfatal02_LDLIBS)
+
+smpfatal02$(EXEEXT): $(smpfatal02_OBJECTS) $(smpfatal02_DEPENDENCIES)
+ @rm -f smpfatal02$(EXEEXT)
+ $(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/smptests/smpfatal02/init.c b/testsuites/smptests/smpfatal02/init.c
new file mode 100644
index 0000000000..1e8da268a9
--- /dev/null
+++ b/testsuites/smptests/smpfatal02/init.c
@@ -0,0 +1,135 @@
+/*
+ * 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.com/license/LICENSE.
+ */
+
+#ifdef HAVE_CONFIG_H
+ #include "config.h"
+#endif
+
+#include <rtems.h>
+#include <rtems/score/percpu.h>
+#include <rtems/score/smpimpl.h>
+
+#include <assert.h>
+#include <stdlib.h>
+
+#define MAX_CPUS 32
+
+static uint32_t main_cpu;
+
+static void Init(rtems_task_argument arg)
+{
+ assert(0);
+}
+
+static void end_of_test(void)
+{
+ printk( "*** END OF TEST SMPFATAL 2 ***\n" );
+}
+
+static void fatal_extension(
+ rtems_fatal_source source,
+ bool is_internal,
+ rtems_fatal_code code
+)
+{
+ if (
+ source == RTEMS_FATAL_SOURCE_APPLICATION
+ || source == RTEMS_FATAL_SOURCE_SMP
+ ) {
+ uint32_t self = rtems_smp_get_current_processor();
+
+ assert(!is_internal);
+
+ if (self == main_cpu) {
+ uint32_t cpu;
+
+ assert(source == RTEMS_FATAL_SOURCE_APPLICATION);
+ assert(code == 0xdeadbeef);
+
+ for (cpu = 0; cpu < MAX_CPUS; ++cpu) {
+ const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
+ Per_CPU_State state = per_cpu->state;
+
+ assert(state == PER_CPU_STATE_SHUTDOWN);
+ }
+
+ end_of_test();
+ } else {
+ assert(source == RTEMS_FATAL_SOURCE_SMP);
+ assert(code == SMP_FATAL_SHUTDOWN);
+ }
+ }
+}
+
+static rtems_status_code test_driver_init(
+ rtems_device_major_number major,
+ rtems_device_minor_number minor,
+ void *arg
+)
+{
+ uint32_t self = rtems_smp_get_current_processor();
+ uint32_t cpu_count = rtems_smp_get_processor_count();
+ uint32_t cpu;
+
+ printk("\n\n*** TEST SMPFATAL 2 ***\n");
+
+ assert(rtems_configuration_get_maximum_processors() == MAX_CPUS);
+
+ main_cpu = self;
+
+ for (cpu = 0; cpu < MAX_CPUS; ++cpu) {
+ const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
+ Per_CPU_State state = per_cpu->state;
+
+ if (cpu == self) {
+ assert(state == PER_CPU_STATE_INITIAL);
+ } else if (cpu < cpu_count) {
+ assert(
+ state == PER_CPU_STATE_INITIAL
+ || state == PER_CPU_STATE_READY_TO_START_MULTITASKING
+ );
+ } else {
+ assert(state == PER_CPU_STATE_INITIAL);
+ }
+ }
+
+ if (cpu_count > 1) {
+ rtems_fatal(RTEMS_FATAL_SOURCE_APPLICATION, 0xdeadbeef);
+ } else {
+ end_of_test();
+ exit(0);
+ }
+
+ return RTEMS_SUCCESSFUL;
+}
+
+#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_APPLICATION_EXTRA_DRIVERS \
+ { .initialization_entry = test_driver_init }
+
+#define CONFIGURE_INITIAL_EXTENSIONS { .fatal = fatal_extension }
+
+#define CONFIGURE_SMP_APPLICATION
+
+#define CONFIGURE_SMP_MAXIMUM_PROCESSORS MAX_CPUS
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/smptests/smpfatal02/smpfatal02.doc b/testsuites/smptests/smpfatal02/smpfatal02.doc
new file mode 100644
index 0000000000..9e2e002b37
--- /dev/null
+++ b/testsuites/smptests/smpfatal02/smpfatal02.doc
@@ -0,0 +1,12 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: smpfatal02
+
+directives:
+
+ - _Per_CPU_State_change()
+
+concepts:
+
+ - Ensure that the system termination in case of fatal errors during driver
+ initialization works.
diff --git a/testsuites/smptests/smpfatal02/smpfatal02.scn b/testsuites/smptests/smpfatal02/smpfatal02.scn
new file mode 100644
index 0000000000..cde11a0e73
--- /dev/null
+++ b/testsuites/smptests/smpfatal02/smpfatal02.scn
@@ -0,0 +1,2 @@
+*** TEST SMPFATAL 2 ***
+*** END OF TEST SMPFATAL 2 ***