2828#define TEST_DESC "Check 2/4/8 Bytes targeted writes "
2929#define TEST_RULE "S_PCIe_04"
3030
31+ #define TEST_DMA_BUF_SIZE SIZE_4KB
32+ #define TEST_DMA_SRC_SIZE (SIZE_4KB/2)
33+ #define TEST_DMA_DST_SIZE (SIZE_4KB/2)
34+ #define TEST_DMA_PATTERN 0xABCDC0DEABCDC0DE
35+
36+ uint64_t test_dma_src_buffer [TEST_DMA_SRC_SIZE /8 ];
37+ uint64_t test_dma_dst_buffer [TEST_DMA_DST_SIZE /8 ];
3138
3239static
3340uint32_t
@@ -106,87 +113,185 @@ get_target_exer_bdf(uint32_t req_rp_bdf, uint32_t *tgt_e_bdf,
106113
107114static
108115uint32_t
109- check_sequence (uint64_t dma_addr , uint32_t tgt_instance , uint32_t req_instance ,
116+ check_p2p_sequence (uint64_t dma_src , uint32_t tgt_instance , uint32_t req_instance ,
110117 uint64_t bar_base , uint32_t size )
111118{
112119 uint32_t status ;
113120 uint64_t transaction_data ;
114121 uint64_t idx ;
115122
116123 /* Copy the contents of the memory to requestor exercise's memory */
117- val_exerciser_set_param (DMA_ATTRIBUTES , (uint64_t )dma_addr , size , req_instance );
118- val_exerciser_ops (START_DMA , EDMA_TO_DEVICE , req_instance );
124+ if (val_exerciser_set_param (DMA_ATTRIBUTES , (uint64_t )dma_src , size , req_instance ))
125+ return ACS_STATUS_FAIL ;
126+
127+ if (val_exerciser_ops (START_DMA , EDMA_TO_DEVICE , req_instance ))
128+ return ACS_STATUS_FAIL ;
119129
120130 /* Set the destination buffer as BAR base address of target exerciser */
121- val_exerciser_set_param (DMA_ATTRIBUTES , (uint64_t )bar_base , size , req_instance );
131+ if (val_exerciser_set_param (DMA_ATTRIBUTES , (uint64_t )bar_base , size , req_instance ))
132+ return ACS_STATUS_FAIL ;
122133
123134 /* Start the transaction monitoring in the target exerciser */
124135 status = val_exerciser_ops (START_TXN_MONITOR , CFG_READ , tgt_instance );
125136 if (status == PCIE_CAP_NOT_FOUND )
126137 {
127138 val_print (ERROR , "\n Transaction Monitoring capability not found" );
128- return 1 ;
139+ return ACS_STATUS_FAIL ;
129140 }
130141
131142 /* Copy the contents from requestor exerciser to target exerciser's BAR address */
132- val_exerciser_ops (START_DMA , EDMA_FROM_DEVICE , req_instance );
143+ if (val_exerciser_ops (START_DMA , EDMA_FROM_DEVICE , req_instance ))
144+ return ACS_STATUS_FAIL ;
133145
134146 /* Stop the transaction monitoring in the target exerciser */
135147 status = val_exerciser_ops (STOP_TXN_MONITOR , CFG_READ , tgt_instance );
136148 if (status == PCIE_CAP_NOT_FOUND )
137149 {
138150 val_print (ERROR , "\n Transaction Monitoring capability not found" );
139- return 1 ;
151+ return ACS_STATUS_FAIL ;
140152 }
141153
142154 /* Compare the transaction data */
143- val_exerciser_get_param (DATA_ATTRIBUTES , & transaction_data , & idx , tgt_instance );
144- if (val_memory_compare (& transaction_data , (void * )dma_addr , size ))
155+ status = val_exerciser_get_param (DATA_ATTRIBUTES , (uint64_t * )& transaction_data ,
156+ & idx , tgt_instance );
157+ if (status )
158+ {
159+ val_print (ERROR , "\n Read Transaction data failed" );
160+ return ACS_STATUS_FAIL ;
161+ }
162+ if (val_memory_compare ((void * )& transaction_data , (void * )dma_src , size ))
145163 {
146164 val_print (ERROR ,
147165 "\n Data mismatch for target exerciser instance: %x" , tgt_instance );
148- val_print (ERROR , " with value: %x" , transaction_data );
149- return 1 ;
166+ val_print (ERROR , " with value: %x\n " , transaction_data );
167+ return ACS_STATUS_FAIL ;
150168 }
151169
152- return 0 ;
170+ return ACS_STATUS_PASS ;
153171}
154172
155173static
156- void
157- payload ( void )
174+ uint32_t
175+ check_host_sequence ( uint64_t dma_src , uint64_t dma_dst , uint32_t req_instance , uint32_t size )
158176{
177+ uint64_t tmp_zerobuf = 0 ;
159178
160- uint32_t status ;
161- uint32_t pe_index ;
162- uint32_t req_instance ;
163- uint32_t fail_cnt ;
164- uint32_t test_skip ;
165- uint32_t req_e_bdf , req_rp_bdf , tgt_e_bdf , tgt_rp_bdf , tgt_instance ;
166- uint64_t bar_base ;
167- uint64_t dma_buffer = 0xABCDC0DEABCDC0DE ;
179+ /* Copy the contents of host memory to requestor exerciser's memory. */
180+ if (val_exerciser_set_param (DMA_ATTRIBUTES , dma_src , size , req_instance ))
181+ return ACS_STATUS_FAIL ;
168182
183+ if (val_exerciser_ops (START_DMA , EDMA_TO_DEVICE , req_instance ))
184+ return ACS_STATUS_FAIL ;
169185
170- fail_cnt = 0 ;
171- test_skip = 1 ;
172- pe_index = val_pe_get_index_mpid (val_pe_get_mpid ());
173- req_instance = val_exerciser_get_info (EXERCISER_NUM_CARDS );
186+ // Clear the destination buffer; cleaning the first 8 bytes is sufficient
187+ * ((uint64_t * )dma_dst ) = 0 ;
188+ val_pe_cache_clean_invalidate_range (dma_dst , size );
174189
175- /* Check If PCIe Hierarchy supports P2P. */
176- if (val_pcie_p2p_support () == ACS_STATUS_PAL_NOT_IMPLEMENTED ) {
177- val_set_status (pe_index , RESULT_WARNING (02 ));
178- return ;
190+ /* Copy the contents from requestor exerciser to host memory. */
191+ if (val_exerciser_set_param (DMA_ATTRIBUTES , dma_dst , size , req_instance ))
192+ return ACS_STATUS_FAIL ;
193+
194+ if (val_exerciser_ops (START_DMA , EDMA_FROM_DEVICE , req_instance ))
195+ return ACS_STATUS_FAIL ;
196+
197+ val_pe_cache_invalidate_range (dma_dst , size );
198+
199+ if ((val_memory_compare ((void * ) dma_src , (void * )dma_dst , size )) ||
200+ (val_memory_compare ((void * )(((uint8_t * ) dma_dst ) + size ),
201+ (void * )& tmp_zerobuf , 8 - size )))
202+ {
203+ val_print (ERROR ,
204+ "\n Host memory data mismatch for exerciser instance: %x" , req_instance );
205+ val_print (ERROR , " with value: %x" , ((uint32_t * )(dma_dst ))[0 ]);
206+ return ACS_STATUS_FAIL ;
207+ }
208+
209+ return ACS_STATUS_PASS ;
210+ }
211+
212+ static const char * printStatus (uint32_t ret_status )
213+ {
214+ switch (ret_status ) {
215+ case ACS_STATUS_FAIL :
216+ return "FAILED" ;
217+ case ACS_STATUS_SKIP :
218+ return "SKIPPED" ;
219+ case ACS_STATUS_PASS :
220+ return "PASSED" ;
221+ default :
222+ return "UNKNOWN" ;
179223 }
224+ }
180225
226+ static
227+ uint32_t
228+ host_dma_test (uint32_t req_instance , uint64_t dma_src , uint64_t dma_dst )
229+ {
230+ uint32_t req_e_bdf ;
231+ uint32_t ret_status = ACS_STATUS_SKIP ;
232+ // Data sizes = 2Bytes, 4Bytes, 8Bytes
233+ uint32_t datasizes [3 ] = {2 , 4 , 8 };
234+ uint32_t i ;
235+ uint32_t test_fail = 0 ;
236+ uint32_t count = (sizeof (datasizes )/sizeof (datasizes [0 ]));
237+
238+ val_print (DEBUG , "\n Testing endpoint to Host DMA\n" );
181239 while (req_instance -- != 0 )
182240 {
241+ /* if init fail moves to next exerciser */
242+ if (val_exerciser_init (req_instance ))
243+ continue ;
244+
245+ req_e_bdf = val_exerciser_get_bdf (req_instance );
246+ val_print (DEBUG , " Requester exerciser BDF - 0x%x\n" , req_e_bdf );
247+
248+ for (i = 0 ; i < count ; i ++ )
249+ {
250+ ret_status = check_host_sequence (dma_src , dma_dst , req_instance , datasizes [i ]);
251+ if (ret_status != ACS_STATUS_PASS )
252+ {
253+ val_print (ERROR ,
254+ " Failed for %dByte host memory transaction from exerciser: %x\n" ,
255+ datasizes [i ], req_instance );
256+ // Continue running the tests even if this fails
257+ test_fail ++ ;
258+ }
259+ }
260+ }
261+ // Check whether test failed in any instance
262+ if (test_fail )
263+ {
264+ ret_status = ACS_STATUS_FAIL ;
265+ }
266+ // else test is either skip or pass
267+ val_print (INFO , "Endpoint to Host DMA test %s\n" , printStatus (ret_status ));
268+ return ret_status ;
269+ }
270+
271+ static
272+ uint32_t
273+ p2p_dma_test (uint32_t req_instance , uint64_t dma_src )
274+ {
275+ uint32_t ret_status = ACS_STATUS_SKIP ;
276+ uint32_t req_e_bdf , req_rp_bdf , tgt_e_bdf , tgt_rp_bdf , tgt_instance ;
277+ uint64_t bar_base ;
278+ // Data sizes = 2Bytes, 4Bytes, 8Bytes
279+ uint32_t datasizes [3 ] = {2 , 4 , 8 };
280+ uint32_t i ;
281+ uint32_t test_fail = 0 ;
282+ uint32_t count = (sizeof (datasizes )/sizeof (datasizes [0 ]));
283+
183284
285+ val_print (DEBUG , "\n Testing endpoint to endpoint DMA\n" );
286+
287+ while (req_instance -- != 0 )
288+ {
184289 /* if init fail moves to next exerciser */
185290 if (val_exerciser_init (req_instance ))
186291 continue ;
187292
188293 req_e_bdf = val_exerciser_get_bdf (req_instance );
189- val_print (DEBUG , "\n Requester exerciser BDF - 0x%x" , req_e_bdf );
294+ val_print (DEBUG , " Requester exerciser BDF - 0x%x\n " , req_e_bdf );
190295
191296 /* Get RP of the exerciser */
192297 if (val_pcie_get_rootport (req_e_bdf , & req_rp_bdf ))
@@ -197,47 +302,107 @@ payload(void)
197302 if (get_target_exer_bdf (req_rp_bdf , & tgt_e_bdf , & tgt_rp_bdf , & bar_base , & tgt_instance ))
198303 continue ;
199304
200- test_skip = 0 ;
201-
202- /* Passing the buffer address as a value, to be configured as the source address for
203- * performing DMA */
204- status = check_sequence ((uint64_t )& dma_buffer , tgt_instance , req_instance , bar_base , 2 );
205- if (status )
305+ for (i = 0 ; i < count ; i ++ )
206306 {
207- val_print (ERROR ,
208- "\n Failed for 2B transaction from exerciser: %x" , req_instance );
209- fail_cnt ++ ;
307+ /* Passing the buffer address as a value, to be configured as the source address for
308+ * performing DMA */
309+ ret_status = check_p2p_sequence (dma_src , tgt_instance , req_instance ,
310+ bar_base , datasizes [i ]);
311+ if (ret_status != ACS_STATUS_PASS )
312+ {
313+ val_print (ERROR ,
314+ " Failed for %dBytes transaction from exerciser: %x\n" ,
315+ datasizes [i ], req_instance );
316+ test_fail ++ ;
317+ }
210318 }
211319
212- status = check_sequence ((uint64_t )& dma_buffer , tgt_instance , req_instance , bar_base , 4 );
213- if (status )
214- {
215- val_print (ERROR ,
216- "\n Failed for 4B transaction from exerciser: %x" , req_instance );
217- fail_cnt ++ ;
320+ }
321+ // Check whether test failed in any instance
322+ if (test_fail )
323+ {
324+ ret_status = ACS_STATUS_FAIL ;
325+ }
326+ // else test is either skip or pass
327+ val_print (INFO , "Endpoint to Endpoint DMA test %s\n" , printStatus (ret_status ));
328+ return ret_status ;
329+ }
330+
331+ static
332+ void
333+ set_status (uint32_t pe_index , uint32_t ret_status , int32_t instance )
334+ {
335+ switch (ret_status ) {
336+ case ACS_STATUS_PASS :
337+ val_set_status (pe_index , RESULT_PASS );
338+ break ;
339+ case ACS_STATUS_FAIL :
340+ val_set_status (pe_index , RESULT_FAIL (instance ));
341+ break ;
342+ case ACS_STATUS_SKIP :
343+ val_set_status (pe_index , RESULT_SKIP (instance ));
344+ break ;
345+ }
346+ return ;
347+ }
348+
349+ static
350+ void
351+ payload (void )
352+ {
353+ uint32_t pe_index ;
354+ uint32_t req_instance ;
355+ uint32_t p2p_status ;
356+ uint32_t test_status = 0 ;
357+
358+ do
359+ {
360+ pe_index = val_pe_get_index_mpid (val_pe_get_mpid ());
361+ req_instance = val_exerciser_get_info (EXERCISER_NUM_CARDS );
362+
363+ // Initialize the DMA source buffer with 8 bytes, as this is the maximum transfer size
364+ test_dma_src_buffer [0 ] = TEST_DMA_PATTERN ;
365+ val_pe_cache_clean_invalidate_range ((uint64_t )test_dma_src_buffer , 8 );
366+
367+ val_print (DEBUG , "\nPerforming Endpoint to Host DMA transfer\n" );
368+ test_status = host_dma_test (req_instance ,
369+ (uint64_t ) test_dma_src_buffer ,
370+ (uint64_t ) test_dma_dst_buffer );
371+ if (test_status != ACS_STATUS_PASS ) {
372+ set_status (pe_index , test_status , 1 );
373+ break ;
374+ }
375+ else {
376+ val_print (DEBUG , "Endpoint to Host DMA transfer Success\n" );
218377 }
219378
220- status = check_sequence ((uint64_t )& dma_buffer , tgt_instance , req_instance , bar_base , 8 );
221- if (status )
379+ /* Check If PCIe Hierarchy supports P2P. */
380+ p2p_status = val_pcie_p2p_support ();
381+ if (p2p_status == ACS_STATUS_PASS )
222382 {
223- val_print (ERROR ,
224- "\n Failed for 8B transaction from exerciser: %x" , req_instance );
225- fail_cnt ++ ;
383+ val_print (DEBUG , "Platform supports PCIe P2P dma transfer " );
384+ val_print (DEBUG , "performing Endpoint to Endpoint transfer\n" );
385+ test_status = p2p_dma_test (req_instance , (uint64_t )test_dma_src_buffer );
386+ if (test_status != ACS_STATUS_PASS ) {
387+ set_status (pe_index , test_status , 2 );
388+ break ;
389+ }
390+ else {
391+ val_print (DEBUG , "Endpoint to Endpoint DMA transfer Success\n" );
392+ }
226393 }
394+ else
395+ {
396+ val_print (DEBUG , "Platform do not support PCIe P2P dma transfer\n" );
397+ }
398+ } while (0 );
227399
228- }
229-
230- if (test_skip == 1 )
231- val_set_status (pe_index , RESULT_SKIP (02 ));
232- else if (fail_cnt )
233- val_set_status (pe_index , RESULT_FAIL (fail_cnt ));
234- else
235- val_set_status (pe_index , RESULT_PASS );
236-
400+ if (test_status == ACS_STATUS_PASS )
401+ set_status (pe_index , test_status , 0 );
237402 return ;
238-
239403}
240404
405+
241406uint32_t
242407e025_entry (uint32_t num_pe )
243408{
0 commit comments