master
c 82 lines 2.5 KB
Raw
1 /*
2 * IOMMU test device helpers for libqos qtests
3 *
4 * Copyright (c) 2026 Phytium Technology
5 *
6 * Author:
7 * Tao Tang <tangtao1634@phytium.com.cn>
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12 #include "qemu/osdep.h"
13 #include "../libqtest.h"
14 #include "pci.h"
15 #include "qos-iommu-testdev.h"
16
17 uint32_t qos_iommu_testdev_trigger_dma(QPCIDevice *dev, QPCIBar bar,
18 uint64_t iova, uint64_t gpa,
19 uint32_t len, uint32_t attrs)
20 {
21 uint32_t result = ITD_DMA_RESULT_BUSY;
22
23 qpci_io_writel(dev, bar, ITD_REG_DMA_GVA_LO, (uint32_t)iova);
24 qpci_io_writel(dev, bar, ITD_REG_DMA_GVA_HI, (uint32_t)(iova >> 32));
25 qpci_io_writel(dev, bar, ITD_REG_DMA_GPA_LO, (uint32_t)gpa);
26 qpci_io_writel(dev, bar, ITD_REG_DMA_GPA_HI, (uint32_t)(gpa >> 32));
27 qpci_io_writel(dev, bar, ITD_REG_DMA_LEN, len);
28 qpci_io_writel(dev, bar, ITD_REG_DMA_ATTRS, attrs);
29
30 qpci_io_writel(dev, bar, ITD_REG_DMA_DBELL, ITD_DMA_DBELL_ARM);
31 qpci_io_readl(dev, bar, ITD_REG_DMA_TRIGGERING);
32
33 for (int i = 0; i < 1000; i++) {
34 result = qpci_io_readl(dev, bar, ITD_REG_DMA_RESULT);
35 if (result != ITD_DMA_RESULT_BUSY) {
36 break;
37 }
38 g_usleep(1000);
39 }
40
41 if (result == ITD_DMA_RESULT_BUSY) {
42 return ITD_DMA_ERR_TX_FAIL;
43 }
44
45 return result;
46 }
47
48 void qos_iommu_testdev_single_translation(const QOSIOMMUTestdevDmaCfg *dma,
49 void *opaque,
50 QOSIOMMUTestdevSetupFn setup_fn,
51 QOSIOMMUTestdevAttrsFn attrs_fn,
52 QOSIOMMUTestdevValidateFn validate_fn,
53 QOSIOMMUTestdevReportFn report_fn,
54 uint32_t *dma_result_out)
55 {
56 uint32_t config_result;
57 uint32_t dma_result;
58 uint32_t attrs_val;
59
60 g_assert(dma);
61 g_assert(setup_fn);
62 g_assert(attrs_fn);
63
64 config_result = setup_fn(opaque);
65 g_assert_cmpuint(config_result, ==, 0);
66
67 attrs_val = attrs_fn(opaque);
68 dma_result = qos_iommu_testdev_trigger_dma(dma->dev, dma->bar,
69 dma->iova, dma->gpa,
70 dma->len, attrs_val);
71 if (dma_result_out) {
72 *dma_result_out = dma_result;
73 }
74
75 if (report_fn) {
76 report_fn(opaque, dma_result);
77 }
78
79 if (validate_fn) {
80 g_assert_true(validate_fn(opaque));
81 }
82 }