source: rtems/testsuites/smptests/smpfatal01/init.c

Last change on this file was bcef89f2, checked in by Sebastian Huber <sebastian.huber@…>, on 05/19/23 at 06:18:25

Update company name

The embedded brains GmbH & Co. KG is the legal successor of embedded
brains GmbH.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/*
4 * Copyright (c) 2014 embedded brains GmbH & Co. KG
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include "tmacros.h"
33
34#include <rtems.h>
35#include <rtems/score/percpu.h>
36#include <rtems/score/smpimpl.h>
37#include <rtems/score/smpbarrier.h>
38
39#include <assert.h>
40#include <stdlib.h>
41
42const char rtems_test_name[] = "SMPFATAL 1";
43
44#define MAX_CPUS 32
45
46static uint32_t main_cpu;
47
48static uint32_t other_cpu;
49
50static SMP_barrier_Control barrier = SMP_BARRIER_CONTROL_INITIALIZER;
51
52static void Init(rtems_task_argument arg)
53{
54  assert(0);
55}
56
57static void fatal_extension(
58  rtems_fatal_source source,
59  bool always_set_to_false,
60  rtems_fatal_code code
61)
62{
63  assert(!always_set_to_false);
64
65  if (source == RTEMS_FATAL_SOURCE_SMP) {
66    SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER;
67    uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
68    uint32_t self = rtems_scheduler_get_processor();
69
70    if (self == other_cpu) {
71      assert(code == SMP_FATAL_SHUTDOWN);
72    } else {
73      assert(code == SMP_FATAL_SHUTDOWN_RESPONSE);
74    }
75
76    _SMP_barrier_Wait(&barrier, &barrier_state, cpu_count);
77
78    if (self == other_cpu) {
79      uint32_t cpu;
80
81      for (cpu = 0; cpu < cpu_count; ++cpu) {
82        const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
83        Per_CPU_State state = _Per_CPU_Get_state(per_cpu);
84
85        assert(state == PER_CPU_STATE_SHUTDOWN);
86      }
87
88      for (cpu = cpu_count; cpu < MAX_CPUS; ++cpu) {
89        const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
90        Per_CPU_State state = _Per_CPU_Get_state(per_cpu);
91
92        assert(state == PER_CPU_STATE_INITIAL);
93      }
94
95      TEST_END();
96    } else {
97      _SMP_barrier_Wait(&barrier, &barrier_state, cpu_count);
98    }
99  }
100}
101
102static void shutdown_handler(void *arg)
103{
104  _SMP_Request_shutdown();
105  _SMP_Fatal(SMP_FATAL_SHUTDOWN);
106}
107
108static const Per_CPU_Job_context shutdown_context = {
109  .handler = shutdown_handler
110};
111
112static Per_CPU_Job shutdown_job = {
113  .context = &shutdown_context
114};
115
116static rtems_status_code test_driver_init(
117  rtems_device_major_number major,
118  rtems_device_minor_number minor,
119  void *arg
120)
121{
122  uint32_t self = rtems_scheduler_get_processor();
123  uint32_t cpu_count = rtems_scheduler_get_processor_maximum();
124  uint32_t cpu;
125
126  TEST_BEGIN();
127
128  assert(rtems_configuration_get_maximum_processors() == MAX_CPUS);
129
130  main_cpu = self;
131  other_cpu = (self + 1) % cpu_count;
132
133  for (cpu = 0; cpu < MAX_CPUS; ++cpu) {
134    const Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( cpu );
135    Per_CPU_State state = _Per_CPU_Get_state(per_cpu);
136
137    if (cpu == self) {
138      assert(state == PER_CPU_STATE_INITIAL);
139    } else if (cpu < cpu_count) {
140      assert(
141        state == PER_CPU_STATE_INITIAL
142          || state == PER_CPU_STATE_READY_TO_START_MULTITASKING
143      );
144    } else {
145      assert(state == PER_CPU_STATE_INITIAL);
146    }
147  }
148
149  if (cpu_count > 1) {
150    Per_CPU_Control *per_cpu = _Per_CPU_Get_by_index( other_cpu );
151
152    _Per_CPU_Submit_job(per_cpu, &shutdown_job);
153  } else {
154    TEST_END();
155    exit(0);
156  }
157
158  return RTEMS_SUCCESSFUL;
159}
160
161#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
162#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
163
164#define CONFIGURE_APPLICATION_EXTRA_DRIVERS \
165  { .initialization_entry = test_driver_init }
166
167#define CONFIGURE_INITIAL_EXTENSIONS \
168  { .fatal = fatal_extension }, \
169  RTEMS_TEST_INITIAL_EXTENSION
170
171#define CONFIGURE_MAXIMUM_PROCESSORS MAX_CPUS
172
173#define CONFIGURE_MAXIMUM_TASKS 1
174
175#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
176
177#define CONFIGURE_INIT
178
179#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.