File indexing completed on 2025-05-11 08:24:46
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #ifdef HAVE_CONFIG_H
0029 #include "config.h"
0030 #endif
0031
0032 #include <rtems/score/cpuimpl.h>
0033
0034 #include <tmacros.h>
0035
0036 const char rtems_test_name[] = "SPCONTEXT 1";
0037
0038 #define ITERATION_COUNT 2000
0039
0040 #define PRIORITY_HIGH 2
0041
0042 #define PRIORITY_LOW 3
0043
0044 #define FINISH_EVENT RTEMS_EVENT_0
0045
0046 typedef struct {
0047 rtems_id control_task;
0048 rtems_id validate_tasks[3];
0049 rtems_id timer;
0050 size_t task_index;
0051 int iteration_counter;
0052 } test_context;
0053
0054 static test_context test_instance;
0055
0056 static void validate_task(rtems_task_argument arg)
0057 {
0058 _CPU_Context_validate(arg);
0059 rtems_test_assert(0);
0060 }
0061
0062 static void start_validate_task(
0063 rtems_id *id,
0064 uintptr_t pattern,
0065 rtems_task_priority priority,
0066 bool fp_unit
0067 )
0068 {
0069 rtems_status_code sc;
0070 rtems_attribute fpu_state;
0071
0072 fpu_state = fp_unit ? RTEMS_FLOATING_POINT : RTEMS_DEFAULT_ATTRIBUTES;
0073
0074 sc = rtems_task_create(
0075 rtems_build_name('V', 'A', 'L', 'I'),
0076 priority,
0077 RTEMS_MINIMUM_STACK_SIZE,
0078 RTEMS_DEFAULT_MODES,
0079 fpu_state,
0080 id
0081 );
0082 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0083
0084 sc = rtems_task_start(*id, validate_task, pattern);
0085 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0086 }
0087
0088 static void reset_timer_or_finish(test_context *self, rtems_id timer)
0089 {
0090 rtems_status_code sc;
0091 int i = self->iteration_counter;
0092
0093 if (i < ITERATION_COUNT) {
0094 self->iteration_counter = i + 1;
0095
0096 sc = rtems_timer_reset(timer);
0097 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0098 } else {
0099 sc = rtems_event_send(self->control_task, FINISH_EVENT);
0100 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0101 }
0102 }
0103
0104 static void switch_priorities(test_context *self)
0105 {
0106 rtems_status_code sc;
0107 size_t index = self->task_index;
0108 size_t next = (index + 1) % RTEMS_ARRAY_SIZE(self->validate_tasks);
0109 size_t task_current_high = index;
0110 size_t task_next_high = next;
0111 rtems_task_priority priority;
0112
0113 self->task_index = next;
0114
0115 sc = rtems_task_set_priority(
0116 self->validate_tasks[task_next_high],
0117 PRIORITY_HIGH,
0118 &priority
0119 );
0120 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0121
0122 sc = rtems_task_set_priority(
0123 self->validate_tasks[task_current_high],
0124 PRIORITY_LOW,
0125 &priority
0126 );
0127 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0128 }
0129
0130 static void clobber_and_switch_timer(rtems_id timer, void *arg)
0131 {
0132 uintptr_t pattern = (uintptr_t) 0xffffffffffffffffU;
0133 test_context *self = arg;
0134
0135 reset_timer_or_finish(self, self->timer);
0136 switch_priorities(self);
0137
0138 _CPU_Context_volatile_clobber(pattern);
0139 }
0140
0141 static void start_timer(test_context *self)
0142 {
0143 rtems_status_code sc;
0144
0145 sc = rtems_timer_create(rtems_build_name('C', 'L', 'S', 'W'), &self->timer);
0146 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0147
0148 sc = rtems_timer_fire_after(self->timer, 2, clobber_and_switch_timer, self);
0149 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0150 }
0151
0152 static void wait_for_finish(void)
0153 {
0154 rtems_status_code sc;
0155 rtems_event_set out;
0156
0157 sc = rtems_event_receive(
0158 FINISH_EVENT,
0159 RTEMS_WAIT | RTEMS_EVENT_ALL,
0160 RTEMS_NO_TIMEOUT,
0161 &out
0162 );
0163 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0164 rtems_test_assert(out == FINISH_EVENT);
0165 }
0166
0167 static void test(
0168 test_context *self,
0169 bool task_0_fpu,
0170 bool task_1_fpu,
0171 bool task_2_fpu
0172 )
0173 {
0174 rtems_status_code sc;
0175 uintptr_t pattern_0 = (uintptr_t) 0xaaaaaaaaaaaaaaaaU;
0176 uintptr_t pattern_1 = (uintptr_t) 0x5555555555555555U;
0177 uintptr_t pattern_2 = (uintptr_t) 0x0000000000000000U;
0178
0179 memset(self, 0, sizeof(*self));
0180
0181 self->control_task = rtems_task_self();
0182 start_validate_task(
0183 &self->validate_tasks[0],
0184 pattern_0,
0185 PRIORITY_HIGH,
0186 task_0_fpu
0187 );
0188 start_validate_task(
0189 &self->validate_tasks[1],
0190 pattern_1,
0191 PRIORITY_LOW,
0192 task_1_fpu
0193 );
0194 start_validate_task(
0195 &self->validate_tasks[2],
0196 pattern_2,
0197 PRIORITY_LOW,
0198 task_2_fpu
0199 );
0200 start_timer(self);
0201 wait_for_finish();
0202
0203 sc = rtems_task_delete(self->validate_tasks[0]);
0204 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0205
0206 sc = rtems_task_delete(self->validate_tasks[1]);
0207 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0208
0209 sc = rtems_task_delete(self->validate_tasks[2]);
0210 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0211
0212 sc = rtems_timer_delete(self->timer);
0213 rtems_test_assert(sc == RTEMS_SUCCESSFUL);
0214 }
0215
0216 static void test_context_is_executing(void)
0217 {
0218 #if defined(RTEMS_SMP)
0219
0220
0221
0222
0223 static char stack[1024];
0224
0225 Context_Control context;
0226 bool is_executing;
0227
0228 memset(&context, 0, sizeof(context));
0229
0230 is_executing = _CPU_Context_Get_is_executing(&context);
0231 rtems_test_assert(!is_executing);
0232
0233 _CPU_Context_Set_is_executing(&context, true);
0234 is_executing = _CPU_Context_Get_is_executing(&context);
0235 rtems_test_assert(is_executing);
0236
0237 _CPU_Context_Set_is_executing(&context, false);
0238 is_executing = _CPU_Context_Get_is_executing(&context);
0239 rtems_test_assert(!is_executing);
0240
0241 _CPU_Context_Set_is_executing(&context, true);
0242 _CPU_Context_Initialize(
0243 &context,
0244 (void *) &stack[0],
0245 sizeof(stack),
0246 0,
0247 NULL,
0248 false,
0249 NULL
0250 );
0251 is_executing = _CPU_Context_Get_is_executing(&context);
0252 rtems_test_assert(is_executing);
0253 #endif
0254 }
0255
0256 static bool is_fp(int i)
0257 {
0258 return i != 0;
0259 }
0260
0261 static const char *desc(int i)
0262 {
0263 return is_fp(i) ? "F" : "N";
0264 }
0265
0266 static void Init(rtems_task_argument arg)
0267 {
0268 test_context *self = &test_instance;
0269 int i;
0270 int j;
0271 int k;
0272
0273 TEST_BEGIN();
0274
0275 test_context_is_executing();
0276
0277 for (i = 0; i < 2; ++i) {
0278 for (j = 0; j < 2; ++j) {
0279 for (k = 0; k < 2; ++k) {
0280 printf("Test configuration %s %s %s... ", desc(i), desc(j), desc(k));
0281 test(self, is_fp(i), is_fp(j), is_fp(k));
0282 printf("done\n");
0283 }
0284 }
0285 }
0286
0287 TEST_END();
0288
0289 rtems_test_exit(0);
0290 }
0291
0292 static void switch_extension(Thread_Control *executing, Thread_Control *heir)
0293 {
0294 uintptr_t pattern = (uintptr_t) 0xffffffffffffffffU;
0295
0296 _CPU_Context_volatile_clobber(pattern);
0297 }
0298
0299 #define CONFIGURE_MICROSECONDS_PER_TICK 1000
0300
0301 #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
0302 #define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
0303
0304 #define CONFIGURE_MAXIMUM_TASKS 4
0305 #define CONFIGURE_MAXIMUM_TIMERS 1
0306
0307 #define CONFIGURE_INITIAL_EXTENSIONS \
0308 { .thread_switch = switch_extension }, \
0309 RTEMS_TEST_INITIAL_EXTENSION
0310
0311 #define CONFIGURE_RTEMS_INIT_TASKS_TABLE
0312
0313 #define CONFIGURE_INIT
0314
0315 #include <rtems/confdefs.h>