source: rtems/testsuites/smptests/smpcache01/init.c @ 9b91c84

5
Last change on this file since 9b91c84 was 9b91c84, checked in by Sebastian Huber <sebastian.huber@…>, on 04/05/17 at 09:29:02

smpcache01: Fix test to run on QorIQ T4240

  • Property mode set to 100644
File size: 7.2 KB
RevLine 
[9a9ab85]1/*
2 * Copyright (c) 2014 Aeroflex Gaisler AB.  All rights reserved.
[9b91c84]3 * Copyright (c) 2017 embedded brains GmbH.
[9a9ab85]4 *
5 * The license and distribution terms for this file may be
6 * found in the file LICENSE in this distribution or at
7 * http://www.rtems.org/license/LICENSE.
8 */
9
10#ifdef HAVE_CONFIG_H
11  #include "config.h"
12#endif
13
14#include <rtems/score/atomic.h>
15#include <rtems/score/smpbarrier.h>
[26c142e5]16#include <rtems/score/smpimpl.h>
[9a9ab85]17#include <rtems.h>
18#include <limits.h>
[9b91c84]19#include <setjmp.h>
[9a9ab85]20#include <string.h>
21
22#include "tmacros.h"
23
24const char rtems_test_name[] = "SMPCACHE 1";
25
[6e1206a]26CPU_STRUCTURE_ALIGNMENT static int data_to_flush[1024];
27
[9a9ab85]28#define CPU_COUNT 32
29
30#define WORKER_PRIORITY 100
31
32typedef struct {
33  SMP_barrier_Control barrier;
34  uint32_t count[CPU_COUNT];
[9b91c84]35  bool do_longjmp[CPU_COUNT];
36  jmp_buf instruction_invalidate_return_context[CPU_COUNT];
[9a9ab85]37} test_context;
38
39static test_context ctx = {
40  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
41};
42
[6e1206a]43static void function_to_flush( void )
44{
45  /* Does nothing. Used to give a pointer to instruction address space. */
46}
47
[b1b5ddf0]48static void test_action( void *arg )
[9a9ab85]49{
[26c142e5]50  rtems_test_assert(arg == &ctx);
[9a9ab85]51
52  ctx.count[rtems_get_current_processor()]++;
53}
54
[b1b5ddf0]55typedef void ( *test_case )(
56  size_t set_size,
57  const cpu_set_t *cpu_set,
58  SMP_barrier_State *bs
59);
60
61static void test_cache_flush_multiple_data_lines(
62  size_t set_size,
63  const cpu_set_t *cpu_set,
64  SMP_barrier_State *bs
65)
[9a9ab85]66{
[6e1206a]67  rtems_cache_flush_multiple_data_lines_processor_set( &data_to_flush,
68      sizeof(data_to_flush), set_size, cpu_set );
[b1b5ddf0]69}
70
71static void test_cache_invalidate_multiple_data_lines(
72  size_t set_size,
73  const cpu_set_t *cpu_set,
74  SMP_barrier_State *bs
75)
76{
[6e1206a]77  rtems_cache_invalidate_multiple_data_lines_processor_set( &data_to_flush,
78      sizeof(data_to_flush), set_size, cpu_set );
[9a9ab85]79}
80
[b1b5ddf0]81static void test_cache_flush_entire_data(
82  size_t set_size,
83  const cpu_set_t *cpu_set,
84  SMP_barrier_State *bs
85)
[9a9ab85]86{
[b1b5ddf0]87  rtems_cache_flush_entire_data_processor_set( set_size, cpu_set );
[9a9ab85]88}
89
[b1b5ddf0]90static void test_cache_invalidate_entire_instruction(
91  size_t set_size,
92  const cpu_set_t *cpu_set,
93  SMP_barrier_State *bs
94)
[9a9ab85]95{
[b1b5ddf0]96  rtems_cache_invalidate_entire_instruction();
[9a9ab85]97}
98
[b1b5ddf0]99static void test_cache_invalidate_multiple_instruction_lines(
100  size_t set_size,
101  const cpu_set_t *cpu_set,
102  SMP_barrier_State *bs
103)
[9a9ab85]104{
[9b91c84]105  uint32_t self = rtems_get_current_processor();
106
107  ctx.do_longjmp[self] = true;
108
109  if (setjmp(ctx.instruction_invalidate_return_context[self]) == 0) {
110    rtems_cache_invalidate_multiple_instruction_lines( &function_to_flush,
111        4 /* arbitrary size */ );
112  }
113
114  ctx.do_longjmp[self] = false;
115}
116
117static void barrier( SMP_barrier_State *bs )
118{
119  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
120}
121
122static void broadcast_test_init( void )
123{
124  ctx.count[rtems_get_current_processor()] = 0;
[9a9ab85]125}
126
[9b91c84]127static void broadcast_test_body(
[b1b5ddf0]128  size_t set_size,
129  const cpu_set_t *cpu_set,
130  SMP_barrier_State *bs
131)
[9a9ab85]132{
[b1b5ddf0]133  _SMP_Multicast_action( set_size, cpu_set, test_action, &ctx );
[9b91c84]134}
[9a9ab85]135
[9b91c84]136static void broadcast_test_fini( void )
137{
138  rtems_test_assert(
139    ctx.count[rtems_get_current_processor()] == rtems_get_processor_count()
140  );
[9a9ab85]141}
142
[b1b5ddf0]143static test_case test_cases[] = {
144  test_cache_flush_multiple_data_lines,
145  test_cache_invalidate_multiple_data_lines,
146  test_cache_flush_entire_data,
147  test_cache_invalidate_entire_instruction,
148  test_cache_invalidate_multiple_instruction_lines,
[9b91c84]149  broadcast_test_body
[b1b5ddf0]150};
[9a9ab85]151
[b1b5ddf0]152static void call_tests( size_t set_size,
153    const cpu_set_t *cpu_set, SMP_barrier_State *bs  )
154{
155  size_t i;
156
[9b91c84]157  broadcast_test_init();
158
[b1b5ddf0]159  for (i = 0; i < RTEMS_ARRAY_SIZE( test_cases ); ++i) {
[9b91c84]160    barrier( bs );
161    ( *test_cases[ i ] )( set_size, cpu_set, bs );
162    barrier( bs );
[b1b5ddf0]163  }
[9b91c84]164
165  broadcast_test_fini();
[9a9ab85]166}
167
[b1b5ddf0]168static void call_tests_isr_disabled( size_t set_size,
169    const cpu_set_t *cpu_set, SMP_barrier_State *bs  )
[9a9ab85]170{
[b1b5ddf0]171  size_t i;
[9a9ab85]172
[9b91c84]173  broadcast_test_init();
174
[b1b5ddf0]175  for (i = 0; i < RTEMS_ARRAY_SIZE( test_cases ); ++i) {
176    ISR_Level isr_level;
[9a9ab85]177
[4b04cb61]178    _ISR_Local_disable( isr_level );
[9b91c84]179    barrier( bs );
180    ( *test_cases[ i ] )( set_size, cpu_set, bs );
[4b04cb61]181    _ISR_Local_enable( isr_level );
[9b91c84]182    barrier( bs );
[b1b5ddf0]183  }
[9b91c84]184
185  broadcast_test_fini();
[b1b5ddf0]186}
[9a9ab85]187
[dab902d5]188static void call_tests_with_thread_dispatch_disabled( size_t set_size,
[b1b5ddf0]189    const cpu_set_t *cpu_set, SMP_barrier_State *bs )
190{
191  size_t i;
192
[9b91c84]193  broadcast_test_init();
194
[b1b5ddf0]195  for (i = 0; i < RTEMS_ARRAY_SIZE( test_cases ); ++i) {
[dab902d5]196    Per_CPU_Control *cpu_self;
197
198    cpu_self = _Thread_Dispatch_disable();
[9b91c84]199    barrier( bs );
200    ( *test_cases[ i ] )( set_size, cpu_set, bs );
201    barrier( bs );
[dab902d5]202    _Thread_Dispatch_enable( cpu_self );
[b1b5ddf0]203  }
[9b91c84]204
205  broadcast_test_fini();
[9a9ab85]206}
207
208static void cmlog(  const char* str )
209{
210  if ( rtems_get_current_processor() == 0 )
211    printf( "%s", str );
212}
213
214static void all_tests( void )
215{
216  uint32_t cpu_count = rtems_get_processor_count();
217  size_t set_size = CPU_ALLOC_SIZE( rtems_get_processor_count() );
218  cpu_set_t *cpu_set = CPU_ALLOC( rtems_get_processor_count() );
219  SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
220
221  /* Send message to all available CPUs */
222  CPU_FILL_S( set_size, cpu_set );
223
[b1b5ddf0]224  /* Call test cases */
225  cmlog( "Calling test cases. " );
226  call_tests( set_size, cpu_set, &bs );
[9a9ab85]227  cmlog( "Done!\n");
228
[b1b5ddf0]229  /* Call test cases with ISR disabled */
230  cmlog( "Calling test cases with ISR disabled. " );
231  call_tests_isr_disabled( set_size, cpu_set, &bs );
[9a9ab85]232  cmlog( "Done!\n" );
233
[dab902d5]234  /* Call test cases with thread dispatch disabled */
235  cmlog( "Calling test cases with thread_dispatch_disabled. ");
236  call_tests_with_thread_dispatch_disabled( set_size, cpu_set, &bs );
[9a9ab85]237  cmlog( "Done!\n");
238
239  /* Done. Free up memory. */
240  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count);
241  CPU_FREE( cpu_set );
242}
243
244static void worker_task(rtems_task_argument arg)
245{
246  rtems_status_code sc;
247
248  all_tests();
249
250  sc = rtems_task_suspend(RTEMS_SELF);
251  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
252}
253
254static void test_smp_cache_manager( void )
255{
256  rtems_status_code sc;
257  size_t worker_index;
258  uint32_t cpu_count = rtems_get_processor_count();
259
260  for (worker_index = 1; worker_index < cpu_count; ++worker_index) {
261    rtems_id worker_id;
262
263    sc = rtems_task_create(
264      rtems_build_name('W', 'R', 'K', '0'+worker_index),
265      WORKER_PRIORITY,
266      RTEMS_MINIMUM_STACK_SIZE,
267      RTEMS_DEFAULT_MODES,
268      RTEMS_DEFAULT_ATTRIBUTES,
269      &worker_id
270    );
271    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
272
273    sc = rtems_task_start( worker_id, worker_task, 0 );
274    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
275  }
276
277  all_tests();
278}
279
280
281static void Init(rtems_task_argument arg)
282{
283  TEST_BEGIN();
284
285  test_smp_cache_manager();
286
287  TEST_END();
288  rtems_test_exit(0);
289}
290
[9b91c84]291static void fatal_extension(
292  rtems_fatal_source source,
293  bool always_set_to_false,
294  rtems_fatal_code error
295)
296{
297  uint32_t self = rtems_get_current_processor();
298
299  if (source == RTEMS_FATAL_SOURCE_EXCEPTION && ctx.do_longjmp[self]) {
300    _ISR_Set_level(0);
301    longjmp(ctx.instruction_invalidate_return_context[self], 1);
302  }
303}
304
[9a9ab85]305#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
306#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
307
[54835ae]308#define CONFIGURE_MAXIMUM_PROCESSORS CPU_COUNT
[9a9ab85]309
310#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
311
312#define CONFIGURE_MAXIMUM_TIMERS 1
313
[9b91c84]314#define CONFIGURE_INITIAL_EXTENSIONS \
315  { .fatal = fatal_extension }, \
316  RTEMS_TEST_INITIAL_EXTENSION
[9a9ab85]317
318#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
319
320#define CONFIGURE_INIT
321
322#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.