99#include <zephyr/cache.h>
1010#include <zephyr/kernel.h>
1111#include <zephyr/ztest.h>
12+ #include <zephyr/drivers/counter.h>
1213
1314#include <dmm.h>
1415
16+ #define IS_ALIGNED64 (x ) IS_ALIGNED(x, sizeof(uint64_t))
17+
1518#define DUT_CACHE DT_ALIAS(dut_cache)
1619#define DUT_NOCACHE DT_ALIAS(dut_nocache)
1720
@@ -57,13 +60,49 @@ static const struct dmm_test_region dmm_test_regions[DMM_TEST_REGION_COUNT] = {
5760.size = DMM_TEST_GET_REG_SIZE (DUT_NOCACHE )
5861},
5962};
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+ }
6094
6195static void * test_setup (void )
6296{
6397static struct dmm_fixture fixture ;
98+ uint32_t t ;
6499
100+ counter_start (counter );
101+ t = ts_get ();
102+ t_delta = ts_get () - t ;
65103memcpy (fixture .regions , dmm_test_regions , sizeof (dmm_test_regions ));
66104fixture .fill_value = 0x1 ;
105+
67106return & fixture ;
68107}
69108
@@ -79,13 +118,25 @@ static bool dmm_buffer_in_region_check(struct dmm_test_region *dtr, void *buf, s
79118}
80119
81120static 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 )
83123{
84124void * buf ;
85125int retval ;
126+ uint32_t t ;
127+ bool aligned ;
86128
87129memset (data , (* fill_value )++ , size );
130+ t = ts_get ();
88131retval = 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+
89140zassert_ok (retval );
90141if (IS_ENABLED (CONFIG_DCACHE ) && is_cached ) {
91142zassert_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_
104155sys_cache_data_invd_range (buf , size );
105156zassert_mem_equal (buf , data , size );
106157
158+ t = ts_get ();
107159retval = 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+ }
108165zassert_ok (retval );
109166}
110167
111168static 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 )
113171{
114172void * buf ;
115173int retval ;
174+ uint32_t t ;
116175uint8_t intermediate_buf [128 ];
176+ bool aligned ;
117177
118- zassert_true (size < sizeof (intermediate_buf ));
178+ zassert_true (size <= sizeof (intermediate_buf ));
119179
180+ t = ts_get ();
120181retval = 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 );
121184zassert_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+ }
122189if (IS_ENABLED (CONFIG_DCACHE ) && is_cached ) {
123190zassert_true (IS_ALIGNED (buf , CONFIG_DCACHE_LINE_SIZE ));
124191}
@@ -144,74 +211,130 @@ static void dmm_check_input_buffer(struct dmm_test_region *dtr, uint32_t *fill_v
144211memset (buf , (* fill_value )++ , size );
145212}
146213
214+ t = ts_get ();
147215retval = 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+ }
148221zassert_ok (retval );
149222
150223zassert_mem_equal (data , intermediate_buf , size );
151224}
152225
153226ZTEST_USER_F (dmm , test_check_dev_cache_in_allocate )
154227{
155- uint8_t user_data [16 ] ;
228+ uint8_t user_data [128 ] __aligned ( sizeof ( uint64_t )) ;
156229
157230dmm_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);
159236}
160237
161238ZTEST_USER_F (dmm , test_check_dev_cache_in_preallocate )
162239{
163240static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_CACHE );
164241
165242dmm_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 );
167244}
168245
169246ZTEST_USER_F (dmm , test_check_dev_cache_out_allocate )
170247{
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);
172253
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. */
173258dmm_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);
175267}
176268
177269ZTEST_USER_F (dmm , test_check_dev_cache_out_preallocate )
178270{
179271static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_CACHE );
180272
181273dmm_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 );
183275}
184276
185277ZTEST_USER_F (dmm , test_check_dev_nocache_in_allocate )
186278{
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);
188291
292+ /* Aligned user buffer. */
189293dmm_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);
191299}
192300
193301ZTEST_USER_F (dmm , test_check_dev_nocache_in_preallocate )
194302{
195303static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_NOCACHE );
196304
197305dmm_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 );
199307}
200308
201309ZTEST_USER_F (dmm , test_check_dev_nocache_out_allocate )
202310{
203- uint8_t user_data [16 ] ;
311+ uint8_t user_data [129 ] __aligned ( sizeof ( uint64_t )) ;
204312
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. */
205328dmm_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 );
207330}
208331
209332ZTEST_USER_F (dmm , test_check_dev_nocache_out_preallocate )
210333{
211334static uint8_t user_data [16 ] DMM_MEMORY_SECTION (DUT_NOCACHE );
212335
213336dmm_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 );
215338}
216339
217340ZTEST_SUITE (dmm , NULL , test_setup , NULL , test_cleanup , NULL );
0 commit comments