9
9
#include <zephyr/cache.h>
10
10
#include <zephyr/kernel.h>
11
11
#include <zephyr/ztest.h>
12
+ #include <zephyr/drivers/counter.h>
12
13
13
14
#include <dmm.h>
14
15
16
+ #define IS_ALIGNED64 (x ) IS_ALIGNED(x, sizeof(uint64_t))
17
+
15
18
#define DUT_CACHE DT_ALIAS(dut_cache)
16
19
#define DUT_NOCACHE DT_ALIAS(dut_nocache)
17
20
@@ -57,13 +60,49 @@ static const struct dmm_test_region dmm_test_regions[DMM_TEST_REGION_COUNT] = {
57
60
.size = DMM_TEST_GET_REG_SIZE (DUT_NOCACHE )
58
61
},
59
62
};
63
+ static const struct device * counter = DEVICE_DT_GET (DT_NODELABEL (cycle_timer ));
64
+ static uint32_t t_delta ;
65
+
66
+ static uint32_t ts_get (void )
67
+ {
68
+ uint32_t t ;
69
+
70
+ (void )counter_get_value (counter , & t );
71
+ return t ;
72
+ }
73
+
74
+ static uint32_t ts_from_get (uint32_t from )
75
+ {
76
+ return ts_get () - from ;
77
+ }
78
+
79
+ static uint32_t cyc_to_us (uint32_t cyc )
80
+ {
81
+ return counter_ticks_to_us (counter , cyc );
82
+ }
83
+
84
+ static uint32_t cyc_to_rem_ns (uint32_t cyc )
85
+ {
86
+ uint32_t us = counter_ticks_to_us (counter , cyc );
87
+ uint32_t ns ;
88
+
89
+ cyc = cyc - counter_us_to_ticks (counter , (uint64_t )us );
90
+ ns = counter_ticks_to_us (counter , 1000 * cyc );
91
+
92
+ return ns ;
93
+ }
60
94
61
95
static void * test_setup (void )
62
96
{
63
97
static struct dmm_fixture fixture ;
98
+ uint32_t t ;
64
99
100
+ counter_start (counter );
101
+ t = ts_get ();
102
+ t_delta = ts_get () - t ;
65
103
memcpy (fixture .regions , dmm_test_regions , sizeof (dmm_test_regions ));
66
104
fixture .fill_value = 0x1 ;
105
+
67
106
return & fixture ;
68
107
}
69
108
@@ -79,13 +118,25 @@ static bool dmm_buffer_in_region_check(struct dmm_test_region *dtr, void *buf, s
79
118
}
80
119
81
120
static void dmm_check_output_buffer (struct dmm_test_region * dtr , uint32_t * fill_value ,
82
- void * data , size_t size , bool was_prealloc , bool is_cached )
121
+ void * data , size_t size , bool was_prealloc ,
122
+ bool is_cached , bool print_report )
83
123
{
84
124
void * buf ;
85
125
int retval ;
126
+ uint32_t t ;
127
+ bool aligned ;
86
128
87
129
memset (data , (* fill_value )++ , size );
130
+ t = ts_get ();
88
131
retval = dmm_buffer_out_prepare (dtr -> mem_reg , data , size , & buf );
132
+ t = ts_from_get (t );
133
+ aligned = IS_ALIGNED64 (data ) && IS_ALIGNED64 (buf ) && IS_ALIGNED64 (size );
134
+
135
+ if (print_report ) {
136
+ TC_PRINT ("%saligned buffer out prepare size:%d buf:%p took %d.%dus (%d cycles)\n" ,
137
+ aligned ? "" : "not " , size , buf , cyc_to_us (t ), cyc_to_rem_ns (t ), t );
138
+ }
139
+
89
140
zassert_ok (retval );
90
141
if (IS_ENABLED (CONFIG_DCACHE ) && is_cached ) {
91
142
zassert_true (IS_ALIGNED (buf , CONFIG_DCACHE_LINE_SIZE ));
@@ -104,21 +155,37 @@ static void dmm_check_output_buffer(struct dmm_test_region *dtr, uint32_t *fill_
104
155
sys_cache_data_invd_range (buf , size );
105
156
zassert_mem_equal (buf , data , size );
106
157
158
+ t = ts_get ();
107
159
retval = dmm_buffer_out_release (dtr -> mem_reg , buf );
160
+ t = ts_from_get (t );
161
+ if (print_report ) {
162
+ TC_PRINT ("buffer out release buf:%p size:%d took %d.%dus (%d cycles)\n" ,
163
+ buf , size , cyc_to_us (t ), cyc_to_rem_ns (t ), t );
164
+ }
108
165
zassert_ok (retval );
109
166
}
110
167
111
168
static void dmm_check_input_buffer (struct dmm_test_region * dtr , uint32_t * fill_value ,
112
- void * data , size_t size , bool was_prealloc , bool is_cached )
169
+ void * data , size_t size , bool was_prealloc ,
170
+ bool is_cached , bool print_report )
113
171
{
114
172
void * buf ;
115
173
int retval ;
174
+ uint32_t t ;
116
175
uint8_t intermediate_buf [128 ];
176
+ bool aligned ;
117
177
118
- zassert_true (size < sizeof (intermediate_buf ));
178
+ zassert_true (size <= sizeof (intermediate_buf ));
119
179
180
+ t = ts_get ();
120
181
retval = dmm_buffer_in_prepare (dtr -> mem_reg , data , size , & buf );
182
+ t = ts_from_get (t );
183
+ aligned = IS_ALIGNED64 (data ) && IS_ALIGNED64 (buf ) && IS_ALIGNED64 (size );
121
184
zassert_ok (retval );
185
+ if (print_report ) {
186
+ TC_PRINT ("%saligned buffer in prepare buf:%p size:%d took %d.%dus (%d cycles)\n" ,
187
+ aligned ? "" : "not " , buf , size , cyc_to_us (t ), cyc_to_rem_ns (t ), t );
188
+ }
122
189
if (IS_ENABLED (CONFIG_DCACHE ) && is_cached ) {
123
190
zassert_true (IS_ALIGNED (buf , CONFIG_DCACHE_LINE_SIZE ));
124
191
}
@@ -144,74 +211,130 @@ static void dmm_check_input_buffer(struct dmm_test_region *dtr, uint32_t *fill_v
144
211
memset (buf , (* fill_value )++ , size );
145
212
}
146
213
214
+ t = ts_get ();
147
215
retval = dmm_buffer_in_release (dtr -> mem_reg , data , size , buf );
216
+ t = ts_from_get (t );
217
+ if (print_report ) {
218
+ TC_PRINT ("buffer in release buf:%p size:%d took %d.%dus (%d cycles)\n" ,
219
+ buf , size , cyc_to_us (t ), cyc_to_rem_ns (t ), t );
220
+ }
148
221
zassert_ok (retval );
149
222
150
223
zassert_mem_equal (data , intermediate_buf , size );
151
224
}
152
225
153
226
ZTEST_USER_F (dmm , test_check_dev_cache_in_allocate )
154
227
{
155
- uint8_t user_data [16 ] ;
228
+ uint8_t user_data [128 ] __aligned ( sizeof ( uint64_t )) ;
156
229
157
230
dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
158
- user_data , sizeof (user_data ), false, true);
231
+ user_data , 16 , false, true, false);
232
+ dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
233
+ user_data , 16 , false, true, true);
234
+ dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
235
+ user_data , sizeof (user_data ), false, true, true);
159
236
}
160
237
161
238
ZTEST_USER_F (dmm , test_check_dev_cache_in_preallocate )
162
239
{
163
240
static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_CACHE );
164
241
165
242
dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
166
- user_data , sizeof (user_data ), true, true);
243
+ user_data , sizeof (user_data ), true, true, true );
167
244
}
168
245
169
246
ZTEST_USER_F (dmm , test_check_dev_cache_out_allocate )
170
247
{
171
- uint8_t user_data [16 ];
248
+ uint8_t user_data [129 ] __aligned (sizeof (uint64_t ));
249
+
250
+ /* First run to get code into ICACHE so that following runs has consistent timing. */
251
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
252
+ user_data , 16 , false, true, false);
172
253
254
+ /* Aligned user buffer. */
255
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
256
+ user_data , 16 , false, true, true);
257
+ /* Unaligned user buffer. */
173
258
dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
174
- user_data , sizeof (user_data ), false, true);
259
+ & user_data [1 ], 16 , false, true, true);
260
+
261
+ /* Aligned user buffer. */
262
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
263
+ user_data , sizeof (user_data ) - 1 , false, true, true);
264
+ /* Unaligned user buffer. */
265
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
266
+ & user_data [1 ], sizeof (user_data ) - 1 , false, true, true);
175
267
}
176
268
177
269
ZTEST_USER_F (dmm , test_check_dev_cache_out_preallocate )
178
270
{
179
271
static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_CACHE );
180
272
181
273
dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_CACHE ], & fixture -> fill_value ,
182
- user_data , sizeof (user_data ), true, true);
274
+ user_data , sizeof (user_data ), true, true, true );
183
275
}
184
276
185
277
ZTEST_USER_F (dmm , test_check_dev_nocache_in_allocate )
186
278
{
187
- uint8_t user_data [16 ];
279
+ uint8_t user_data [129 ] __aligned (sizeof (uint64_t ));
280
+
281
+ dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
282
+ user_data , 16 , false, false, false);
283
+
284
+ /* Aligned user buffer. */
285
+ dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
286
+ user_data , 16 , false, false, true);
287
+
288
+ /* Unaligned user buffer. */
289
+ dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
290
+ & user_data [1 ], 16 , false, false, true);
188
291
292
+ /* Aligned user buffer. */
189
293
dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
190
- user_data , sizeof (user_data ), false, false);
294
+ user_data , sizeof (user_data ) - 1 , false, false, true);
295
+
296
+ /* Unaligned user buffer. */
297
+ dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
298
+ & user_data [1 ], sizeof (user_data ) - 1 , false, false, true);
191
299
}
192
300
193
301
ZTEST_USER_F (dmm , test_check_dev_nocache_in_preallocate )
194
302
{
195
303
static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_NOCACHE );
196
304
197
305
dmm_check_input_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
198
- user_data , sizeof (user_data ), true, false);
306
+ user_data , sizeof (user_data ), true, false, true );
199
307
}
200
308
201
309
ZTEST_USER_F (dmm , test_check_dev_nocache_out_allocate )
202
310
{
203
- uint8_t user_data [16 ] ;
311
+ uint8_t user_data [129 ] __aligned ( sizeof ( uint64_t )) ;
204
312
313
+ /* First run to get code into ICACHE so that following results are consistent. */
314
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
315
+ user_data , 16 , false, false, false);
316
+
317
+ /* Aligned user buffer. */
318
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
319
+ user_data , 16 , false, false, true);
320
+ /* Unaligned user buffer. */
321
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
322
+ & user_data [1 ], 16 , false, false, true);
323
+
324
+ /* Aligned user buffer. */
325
+ dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
326
+ user_data , sizeof (user_data ) - 1 , false, false, true);
327
+ /* Unaligned user buffer. */
205
328
dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
206
- user_data , sizeof (user_data ), false, false);
329
+ & user_data [ 1 ] , sizeof (user_data ) - 1 , false, false, true );
207
330
}
208
331
209
332
ZTEST_USER_F (dmm , test_check_dev_nocache_out_preallocate )
210
333
{
211
334
static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_NOCACHE );
212
335
213
336
dmm_check_output_buffer (& fixture -> regions [DMM_TEST_REGION_NOCACHE ], & fixture -> fill_value ,
214
- user_data , sizeof (user_data ), true, false);
337
+ user_data , sizeof (user_data ), true, false, true );
215
338
}
216
339
217
340
ZTEST_SUITE (dmm , NULL , test_setup , NULL , test_cleanup , NULL );
0 commit comments