master
h 164 lines 6.04 KB
Raw
1 /*
2 * QOS RISC-V IOMMU Module
3 *
4 * This module provides RISC-V IOMMU-specific helper functions for libqos tests,
5 * encapsulating RISC-V IOMMU setup, and assertions.
6 *
7 * Copyright (c) 2026 Chao Liu <chao.liu.zevorn@gmail.com>
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
12 #ifndef QTEST_LIBQOS_RISCV_IOMMU_H
13 #define QTEST_LIBQOS_RISCV_IOMMU_H
14
15 #include "hw/misc/iommu-testdev.h"
16
17 /* RISC-V IOMMU MMIO register base for virt machine */
18 #define VIRT_RISCV_IOMMU_BASE 0x0000000003010000ull
19
20 /* RISC-V IOMMU queue and table base addresses */
21 #define QRIOMMU_CQ_BASE_ADDR 0x000000000e160000ull
22 #define QRIOMMU_FQ_BASE_ADDR 0x000000000e170000ull
23
24 /* RISC-V IOMMU queue sizing */
25 #define QRIOMMU_QUEUE_ENTRIES 1024
26 #define QRIOMMU_CQ_ENTRY_SIZE 16
27 #define QRIOMMU_FQ_ENTRY_SIZE 32
28
29 /*
30 * Translation tables and descriptors for RISC-V IOMMU.
31 * Similar to ARM SMMUv3, but using RISC-V IOMMU terminology:
32 * - Device Context (DC) instead of STE
33 * - First-stage context (FSC) for S-stage translation
34 * - IOHGATP for G-stage translation
35 *
36 * Granule size: 4KB pages
37 * Page table levels: 3 levels for SV39 (L0, L1, L2)
38 * IOVA size: 39-bit virtual address space
39 */
40 #define QRIOMMU_IOVA 0x0000000080604567ull
41 #define QRIOMMU_IOHGATP 0x0000000000010000ull
42 #define QRIOMMU_DDT_BASE 0x0000000000014000ull
43 #define QRIOMMU_DC_BASE (QRIOMMU_DDT_BASE)
44
45 #define QRIOMMU_L0_PTE_VAL 0x0000000000011000ull
46 #define QRIOMMU_L1_PTE_VAL 0x0000000000012000ull
47 #define QRIOMMU_L2_PTE_VAL 0x0000000000013000ull
48
49 #define QRIOMMU_G_IOHGATP 0x0000000000020000ull
50 #define QRIOMMU_G_L0_PTE_VAL 0x0000000000021000ull
51 #define QRIOMMU_G_L1_PTE_VAL 0x0000000000022000ull
52
53 /*
54 * PTE masks for RISC-V IOMMU page tables.
55 * Values match PTE_V, PTE_R, PTE_W, PTE_A, PTE_D in target/riscv/cpu_bits.h
56 */
57 #define QRIOMMU_NON_LEAF_PTE_MASK 0x011 /* PTE_V | PTE_U */
58 #define QRIOMMU_LEAF_PTE_RW_MASK 0x0d7 /* V | R | W | A | D | PTE_U */
59 #define QRIOMMU_PTE_PPN_MASK 0x003ffffffffffc00ull
60
61 /* Address-space base offset for test tables */
62 #define QRIOMMU_SPACE_OFFS 0x0000000080000000ull
63
64 typedef enum QRIOMMUTransMode {
65 QRIOMMU_TM_BARE = 0, /* No translation (pass-through) */
66 QRIOMMU_TM_S_STAGE_ONLY = 1, /* First-stage only (S-stage) */
67 QRIOMMU_TM_G_STAGE_ONLY = 2, /* Second-stage only (G-stage) */
68 QRIOMMU_TM_NESTED = 3, /* Nested translation (S + G) */
69 } QRIOMMUTransMode;
70
71 typedef struct QRIOMMUTestConfig {
72 QRIOMMUTransMode trans_mode; /* Translation mode */
73 uint64_t dma_gpa; /* GPA for readback validation */
74 uint32_t dma_len; /* DMA length for testing */
75 uint32_t expected_result; /* Expected DMA result */
76 } QRIOMMUTestConfig;
77
78 typedef struct QRIOMMUTestContext {
79 QTestState *qts; /* QTest state handle */
80 QPCIDevice *dev; /* PCI device handle */
81 QPCIBar bar; /* PCI BAR for MMIO access */
82 QRIOMMUTestConfig config; /* Test configuration */
83 uint64_t iommu_base; /* RISC-V IOMMU base address */
84 uint32_t trans_status; /* Translation configuration status */
85 uint32_t dma_result; /* DMA operation result */
86 uint32_t device_id; /* Device ID for the test */
87 } QRIOMMUTestContext;
88
89 /*
90 * qriommu_setup_and_enable_translation - Complete translation setup and enable
91 *
92 * @ctx: Test context containing configuration and device handles
93 *
94 * Returns: Translation status (0 = success, non-zero = error)
95 *
96 * This function performs the complete translation setup sequence:
97 * 1. Builds all required RISC-V IOMMU structures (DC, page tables)
98 * 2. Programs RISC-V IOMMU registers
99 * 3. Returns configuration status
100 */
101 uint32_t qriommu_setup_and_enable_translation(QRIOMMUTestContext *ctx);
102
103 /*
104 * qriommu_build_translation - Build RISC-V IOMMU translation structures
105 *
106 * @qts: QTest state handle
107 * @mode: Translation mode (BARE, S_STAGE_ONLY, G_STAGE_ONLY, NESTED)
108 * @device_id: Device ID
109 *
110 * Returns: Build status (0 = success, non-zero = error)
111 *
112 * Constructs all necessary RISC-V IOMMU translation structures in guest memory:
113 * - Device Context (DC) for the given device ID
114 * - First-stage context (FSC) if S-stage translation is involved
115 * - Complete page table hierarchy based on translation mode
116 */
117 uint32_t qriommu_build_translation(QTestState *qts, QRIOMMUTransMode mode,
118 uint32_t device_id);
119
120 /*
121 * qriommu_program_regs - Program all required RISC-V IOMMU registers
122 *
123 * @qts: QTest state handle
124 * @iommu_base: RISC-V IOMMU base address
125 *
126 * Programs RISC-V IOMMU registers:
127 * - Device Directory Table Pointer (DDTP)
128 * - Command queue (base, head, tail)
129 * - Fault queue (base, head, tail)
130 * - Control and status registers
131 */
132 void qriommu_program_regs(QTestState *qts, uint64_t iommu_base);
133
134 /*
135 * qriommu_setup_translation_tables - Setup RISC-V IOMMU page table hierarchy
136 *
137 * @qts: QTest state handle
138 * @iova: Input Virtual Address to translate
139 * @mode: Translation mode
140 *
141 * This function builds the complete page table structure for translating
142 * the given IOVA through the RISC-V IOMMU. The structure varies based on mode:
143 *
144 * - BARE: No translation (pass-through)
145 * - S_STAGE_ONLY: Single S-stage walk (IOVA -> PA)
146 * - G_STAGE_ONLY: Single G-stage walk (IPA -> PA)
147 * - NESTED: S-stage walk (IOVA -> IPA) + G-stage walk (IPA -> PA)
148 */
149 void qriommu_setup_translation_tables(QTestState *qts,
150 uint64_t iova,
151 QRIOMMUTransMode mode);
152
153 /* High-level test execution helpers */
154 void qriommu_run_translation_case(QTestState *qts, QPCIDevice *dev,
155 QPCIBar bar, uint64_t iommu_base,
156 const QRIOMMUTestConfig *cfg);
157
158 /* Calculate expected DMA result */
159 uint32_t qriommu_expected_dma_result(QRIOMMUTestContext *ctx);
160
161 /* Build DMA attributes for RISC-V IOMMU */
162 uint32_t qriommu_build_dma_attrs(void);
163
164 #endif /* QTEST_LIBQOS_RISCV_IOMMU_H */