Skip to content

Commit 3fcb116

Browse files
anishnair-armchetan-rathore
authored andcommitted
fix(test): Added DMA writes to system memory
Rule: S_PCIe_04 Added DMA writes from Endpoint to Host memory along with PCIe P2P DMA transaction. Change-Id: I3bae7941eccac1ded07a39b76e93af7f3fb16743
1 parent 7d4587d commit 3fcb116

1 file changed

Lines changed: 226 additions & 61 deletions

File tree

test_pool/exerciser/e025.c

Lines changed: 226 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
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

3239
static
3340
uint32_t
@@ -106,87 +113,185 @@ get_target_exer_bdf(uint32_t req_rp_bdf, uint32_t *tgt_e_bdf,
106113

107114
static
108115
uint32_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

155173
static
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+
241406
uint32_t
242407
e025_entry(uint32_t num_pe)
243408
{

0 commit comments

Comments
 (0)