source: rtems/testsuites/smptests/smpcache01/init.c @ 6e1206a

4.115
Last change on this file since 6e1206a was 6e1206a, checked in by Daniel Cederman <cederman@…>, on 09/11/14 at 15:55:34

smptests/smpcache01: Remove invalidation of data cache lines from test

Invalidation of entire data cache might cause data written to the stack
to get lost.

  • Property mode set to 100644
File size: 8.4 KB
Line 
1/*
2 * Copyright (c) 2014 Aeroflex Gaisler AB.  All rights reserved.
3 *
4 * The license and distribution terms for this file may be
5 * found in the file LICENSE in this distribution or at
6 * http://www.rtems.org/license/LICENSE.
7 */
8
9#ifdef HAVE_CONFIG_H
10  #include "config.h"
11#endif
12
13#include <rtems/score/atomic.h>
14#include <rtems/score/smpbarrier.h>
15#include <rtems.h>
16#include <limits.h>
17#include <string.h>
18
19#include "tmacros.h"
20
21const char rtems_test_name[] = "SMPCACHE 1";
22
23CPU_STRUCTURE_ALIGNMENT static int data_to_flush[1024];
24
25#define CPU_COUNT 32
26
27#define WORKER_PRIORITY 100
28
29typedef void (*Cache_manager_Function_ptr)(const void *d_addr, size_t n_bytes);
30
31void
32_Cache_manager_Send_smp_msg(
33    const size_t setsize,
34    const cpu_set_t *set,
35    Cache_manager_Function_ptr func,
36    const void * addr,
37    size_t size
38  );
39
40typedef struct {
41  SMP_barrier_Control barrier;
42  uint32_t count[CPU_COUNT];
43} test_context;
44
45static test_context ctx = {
46  .barrier = SMP_BARRIER_CONTROL_INITIALIZER,
47};
48
49static void function_to_flush( void )
50{
51  /* Does nothing. Used to give a pointer to instruction address space. */
52}
53
54static void test_cache_message( const void *d_addr, size_t n_bytes )
55{
56  rtems_test_assert(n_bytes == 123);
57  rtems_test_assert(d_addr == 0);
58
59  ctx.count[rtems_get_current_processor()]++;
60}
61
62static void cache_manager_smp_functions( size_t set_size,
63    cpu_set_t *cpu_set )
64{
65  rtems_cache_flush_multiple_data_lines_processor_set( &data_to_flush,
66      sizeof(data_to_flush), set_size, cpu_set );
67  rtems_cache_invalidate_multiple_data_lines_processor_set( &data_to_flush,
68      sizeof(data_to_flush), set_size, cpu_set );
69  rtems_cache_flush_entire_data_processor_set( set_size, cpu_set );
70  rtems_cache_invalidate_entire_instruction();
71  rtems_cache_invalidate_multiple_instruction_lines( &function_to_flush,
72      4 /* arbitrary size */ );
73}
74
75static void standard_funcs_test( size_t set_size, cpu_set_t *cpu_set )
76{
77  cache_manager_smp_functions( set_size, cpu_set );
78}
79
80static void standard_funcs_isrdisabled_test( size_t set_size,
81    cpu_set_t *cpu_set, SMP_barrier_State *bs  )
82{
83  ISR_Level isr_level;
84
85  _ISR_Disable_without_giant( isr_level );
86
87  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
88
89  cache_manager_smp_functions( set_size, cpu_set );
90
91  _ISR_Enable_without_giant( isr_level );
92}
93
94static void standard_funcs_giant_taken_test( size_t set_size,
95    cpu_set_t *cpu_set, SMP_barrier_State *bs )
96{
97  if ( rtems_get_current_processor() == 0)
98    _Giant_Acquire();
99
100  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
101
102  cache_manager_smp_functions( set_size, cpu_set );
103
104  if ( rtems_get_current_processor() == 0)
105    _Giant_Release();
106}
107
108static void test_func_test( size_t set_size, cpu_set_t *cpu_set,
109    SMP_barrier_State *bs )
110{
111  ctx.count[rtems_get_current_processor()] = 0;
112  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
113
114  _Cache_manager_Send_smp_msg( set_size, cpu_set, test_cache_message, 0, 123 );
115
116  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
117
118  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
119      rtems_get_processor_count() );
120}
121
122static void test_func_isrdisabled_test( size_t set_size, cpu_set_t *cpu_set,
123    SMP_barrier_State *bs )
124{
125  ISR_Level isr_level;
126
127  ctx.count[rtems_get_current_processor()] = 0;
128  _ISR_Disable_without_giant( isr_level );
129
130  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
131
132  _Cache_manager_Send_smp_msg( set_size, cpu_set, test_cache_message, 0, 123 );
133
134  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
135
136  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
137      rtems_get_processor_count() );
138
139  _ISR_Enable_without_giant( isr_level );
140}
141
142static void test_func_giant_taken_test( size_t set_size, cpu_set_t *cpu_set,
143    SMP_barrier_State *bs )
144{
145  ctx.count[rtems_get_current_processor()] = 0;
146
147  if ( rtems_get_current_processor() == 0)
148    _Giant_Acquire();
149
150  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
151
152  _Cache_manager_Send_smp_msg( set_size, cpu_set, test_cache_message, 0, 123 );
153
154  _SMP_barrier_Wait( &ctx.barrier, bs, rtems_get_processor_count() );
155
156  rtems_test_assert( ctx.count[rtems_get_current_processor()] ==
157      rtems_get_processor_count() );
158
159  if ( rtems_get_current_processor() == 0)
160    _Giant_Release();
161}
162
163static void cmlog(  const char* str )
164{
165  if ( rtems_get_current_processor() == 0 )
166    printf( "%s", str );
167}
168
169static void all_tests( void )
170{
171  uint32_t cpu_count = rtems_get_processor_count();
172  size_t set_size = CPU_ALLOC_SIZE( rtems_get_processor_count() );
173  cpu_set_t *cpu_set = CPU_ALLOC( rtems_get_processor_count() );
174  SMP_barrier_State bs = SMP_BARRIER_STATE_INITIALIZER;
175
176  /* Send message to all available CPUs */
177  CPU_FILL_S( set_size, cpu_set );
178
179  /* Call SMP cache manager functions */
180  cmlog( "Calling standard SMP cache functions. " );
181  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
182  standard_funcs_test( set_size, cpu_set );
183  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
184  cmlog( "Done!\n");
185
186  /* Call SMP cache manager functions with ISR disabled */
187  cmlog( "Calling standard SMP cache functions with ISR disabled. " );
188  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
189  standard_funcs_isrdisabled_test( set_size, cpu_set, &bs );
190  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
191  cmlog( "Done!\n" );
192
193  /* Call SMP cache manager functions with core 0 holding the giant lock */
194  cmlog( "Calling standard SMP cache functions with CPU0 holding "
195      "the giant lock. " );
196  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
197  standard_funcs_giant_taken_test( set_size, cpu_set, &bs );
198  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
199  cmlog( "Done!\n");
200
201  /* Call a test function using SMP cache manager and verify that all
202   * cores invoke the function */
203  cmlog( "Calling a test function using the SMP cache manager to "
204      "verify that all CPUs receive the SMP message. " );
205  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
206  test_func_test( set_size, cpu_set, &bs );
207  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
208  cmlog( "Done!\n");
209
210  /* Call a test function using SMP cache manager and verify that all
211   * cores invoke the function. ISR disabled. */
212  cmlog( "Calling a test function using the SMP cache manager to "
213      "verify that all CPUs receive the SMP message. With ISR disabled. " );
214  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
215  test_func_isrdisabled_test( set_size, cpu_set, &bs );
216  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
217  cmlog( "Done!\n" );
218
219  /* Call a test function using SMP cache manager and verify that all
220   * cores invoke the function. Core 0 holding giant lock. */
221  cmlog( "Calling a test function using the SMP cache manager to "
222      "verify that all CPUs receive the SMP message. With CPU0 "
223      "holding the giant lock. " );
224  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
225  test_func_giant_taken_test( set_size, cpu_set, &bs );
226  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count );
227  cmlog( "Done!\n" );
228
229  /* Done. Free up memory. */
230  _SMP_barrier_Wait( &ctx.barrier, &bs, cpu_count);
231  CPU_FREE( cpu_set );
232}
233
234static void worker_task(rtems_task_argument arg)
235{
236  rtems_status_code sc;
237
238  all_tests();
239
240  sc = rtems_task_suspend(RTEMS_SELF);
241  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
242}
243
244static void test_smp_cache_manager( void )
245{
246  rtems_status_code sc;
247  size_t worker_index;
248  uint32_t cpu_count = rtems_get_processor_count();
249
250  for (worker_index = 1; worker_index < cpu_count; ++worker_index) {
251    rtems_id worker_id;
252
253    sc = rtems_task_create(
254      rtems_build_name('W', 'R', 'K', '0'+worker_index),
255      WORKER_PRIORITY,
256      RTEMS_MINIMUM_STACK_SIZE,
257      RTEMS_DEFAULT_MODES,
258      RTEMS_DEFAULT_ATTRIBUTES,
259      &worker_id
260    );
261    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
262
263    sc = rtems_task_start( worker_id, worker_task, 0 );
264    rtems_test_assert( sc == RTEMS_SUCCESSFUL );
265  }
266
267  all_tests();
268}
269
270
271static void Init(rtems_task_argument arg)
272{
273  TEST_BEGIN();
274
275  test_smp_cache_manager();
276
277  TEST_END();
278  rtems_test_exit(0);
279}
280
281#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
282#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
283
284#define CONFIGURE_SMP_APPLICATION
285
286#define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT
287
288#define CONFIGURE_MAXIMUM_TASKS CPU_COUNT
289
290#define CONFIGURE_MAXIMUM_TIMERS 1
291
292#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
293
294#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
295
296#define CONFIGURE_INIT
297
298#include <rtems/confdefs.h>
Note: See TracBrowser for help on using the repository browser.