master
h 242 lines 8.81 KB
Raw
1 /*
2 * QOS SMMUv3 Module
3 *
4 * This module provides SMMUv3-specific helper functions for libqos tests,
5 * encapsulating SMMUv3 setup, and assertions.
6 *
7 * Copyright (c) 2026 Phytium Technology
8 *
9 * Author:
10 * Tao Tang <tangtao1634@phytium.com.cn>
11 *
12 * SPDX-License-Identifier: GPL-2.0-or-later
13 */
14
15 #ifndef QTEST_LIBQOS_SMMUV3_H
16 #define QTEST_LIBQOS_SMMUV3_H
17
18 #include "hw/misc/iommu-testdev.h"
19
20 /*
21 * SMMU MMIO register base for virt machine-wide SMMU. This does not
22 * apply to user-creatable device such as -device arm-smmuv3.
23 */
24 #define VIRT_SMMU_BASE 0x0000000009050000ull
25
26 /* SMMU queue and table base addresses */
27 #define QSMMU_CMDQ_BASE_ADDR 0x000000000e16b000ull
28 #define QSMMU_EVENTQ_BASE_ADDR 0x000000000e170000ull
29
30 /*
31 * Translation tables and descriptors for a mapping of
32 * - IOVA (Stage 1 only or nested translation stage)
33 * - IPA (Stage 2 only)
34 * to GPA.
35 *
36 * The translation is based on the Arm architecture with the following
37 * prerequisites:
38 * - Granule size: 4KB pages.
39 * - Page table levels: 4 levels (L0, L1, L2, L3), starting at level 0.
40 * - IOVA size: The walk resolves a IOVA: 0x8080604567
41 * - Address space: The 4-level lookup with 4KB granules supports up to a
42 * 48-bit (256TB) virtual address space. Each level uses a 9-bit index
43 * (512 entries per table). The breakdown is:
44 * - L0 index: IOVA bits [47:39]
45 * - L1 index: IOVA bits [38:30]
46 * - L2 index: IOVA bits [29:21]
47 * - L3 index: IOVA bits [20:12]
48 * - Page offset: IOVA bits [11:0]
49 *
50 * NOTE: All physical addresses defined here (QSMMU_VTTB, table addresses, etc.)
51 * appear to be within a secure RAM region. In practice, an offset is added
52 * to these values to place them in non-secure RAM. For example, when running
53 * in a virt machine type, the RAM base address (e.g., 0x40000000) is added to
54 * these constants.
55 */
56 #define QSMMU_IOVA 0x0000008080604567ull
57 #define QSMMU_VTTB 0x000000000e4d0000ull
58 #define QSMMU_STR_TAB_BASE 0x000000000e179000ull
59 #define QSMMU_CD_GPA (QSMMU_STR_TAB_BASE - 0x40ull)
60
61
62 #define QSMMU_L0_PTE_VAL 0x000000000e4d1000ull
63 #define QSMMU_L1_PTE_VAL 0x000000000e4d2000ull
64 #define QSMMU_L2_PTE_VAL 0x000000000e4d3000ull
65 #define QSMMU_L3_PTE_VAL 0x000000000ecba000ull
66
67 #define QSMMU_NON_LEAF_PTE_MASK 0x8000000000000003ull
68 #define QSMMU_LEAF_PTE_RO_MASK 0x04000000000007e3ull
69 #define QSMMU_LEAF_PTE_RW_MASK 0x0400000000000763ull
70 #define QSMMU_PTE_MASK 0x0000fffffffff000ull
71
72 /*
73 * Address-space base offsets for test tables.
74 * - Non-Secure uses a fixed offset, keeping internal layout identical.
75 *
76 * Note: Future spaces (e.g. Secure/Realm/Root) are not implemented here.
77 * When needed, introduce new offsets and reuse the helpers below so relative
78 * layout stays identical across spaces.
79 */
80 #define QSMMU_SPACE_OFFS_NS 0x0000000040000000ull
81
82 typedef enum QSMMUSecSID {
83 QSMMU_SEC_SID_NONSECURE = 0,
84 } QSMMUSecSID;
85
86 typedef enum QSMMUSpace {
87 QSMMU_SPACE_NONSECURE = 1,
88 } QSMMUSpace;
89
90 typedef enum QSMMUTransMode {
91 QSMMU_TM_S1_ONLY = 0,
92 QSMMU_TM_S2_ONLY = 1,
93 QSMMU_TM_NESTED = 2,
94 } QSMMUTransMode;
95
96 typedef struct QSMMUTestConfig {
97 QSMMUTransMode trans_mode; /* Translation mode (S1, S2, Nested) */
98 QSMMUSecSID sec_sid; /* SEC_SID of test device */
99 uint64_t dma_gpa; /* GPA for readback validation */
100 uint32_t dma_len; /* DMA length for testing */
101 uint32_t expected_result; /* Expected DMA result for validation */
102 } QSMMUTestConfig;
103
104 typedef struct QSMMUTestContext {
105 QTestState *qts; /* QTest state handle */
106 QPCIDevice *dev; /* PCI device handle */
107 QPCIBar bar; /* PCI BAR for MMIO access */
108 QSMMUTestConfig config; /* Test configuration */
109 uint64_t smmu_base; /* SMMU base address */
110 uint32_t trans_status; /* Translation configuration status */
111 uint32_t dma_result; /* DMA operation result */
112 uint32_t sid; /* Stream ID for the test */
113 QSMMUSpace tx_space; /* Cached transaction space */
114 } QSMMUTestContext;
115
116 /* Convert SEC_SID to corresponding Security Space */
117 QSMMUSpace qsmmu_sec_sid_to_space(QSMMUSecSID sec_sid);
118
119 /* Get base offset of the specific Security space */
120 uint64_t qsmmu_space_offset(QSMMUSpace sp);
121
122 uint32_t qsmmu_build_dma_attrs(QSMMUSpace space);
123
124 /*
125 * qsmmu_setup_and_enable_translation - Complete translation setup and enable
126 *
127 * @ctx: Test context containing configuration and device handles
128 *
129 * Returns: Translation status (0 = success, non-zero = error)
130 *
131 * This function performs the complete translation setup sequence:
132 * 1. Builds all required SMMU structures (STE, CD, page tables)
133 * 2. Programs SMMU registers for the appropriate security space
134 * 3. Returns configuration status
135 */
136 uint32_t qsmmu_setup_and_enable_translation(QSMMUTestContext *ctx);
137
138 /*
139 * qsmmu_build_translation - Build SMMU translation structures
140 *
141 * @qts: QTest state handle
142 * @mode: Translation mode (S1_ONLY, S2_ONLY, NESTED)
143 * @tx_space: Transaction security space
144 * @sid: Stream ID
145 *
146 * Returns: Build status (0 = success, non-zero = error)
147 *
148 * Constructs all necessary SMMU translation structures in guest memory
149 * using the fixed QSMMU_IOVA constant:
150 * - Stream Table Entry (STE) for the given SID
151 * - Context Descriptor (CD) if Stage 1 translation is involved
152 * - Complete page table hierarchy based on translation mode
153 *
154 * The structures are written to security-space-specific memory regions.
155 */
156 uint32_t qsmmu_build_translation(QTestState *qts, QSMMUTransMode mode,
157 QSMMUSpace tx_space, uint32_t sid);
158
159 /*
160 * qsmmu_bank_base - Get SMMU control bank base address
161 *
162 * @base: SMMU base address
163 * @sp: Security space
164 *
165 * Returns: Bank base address for the given security space
166 *
167 * Maps security space to the corresponding SMMU control register bank.
168 * Currently only Non-Secure bank is supported.
169 */
170 uint64_t qsmmu_bank_base(uint64_t base, QSMMUSpace sp);
171
172 /*
173 * qsmmu_program_bank - Program SMMU control bank registers
174 *
175 * @qts: QTest state handle
176 * @bank_base: SMMU bank base address
177 * @sp: Security space
178 *
179 * Programs a specific SMMU control bank with minimal configuration:
180 * - Global Bypass Attribute (GBPA)
181 * - Control registers (CR0, CR1)
182 * - Command queue (base, producer, consumer)
183 * - Event queue (base, producer, consumer)
184 * - Stream table configuration (base, format)
185 *
186 * Addresses are adjusted based on security space offset.
187 */
188 void qsmmu_program_bank(QTestState *qts, uint64_t bank_base, QSMMUSpace sp);
189
190 /*
191 * qsmmu_program_regs - Program all required SMMU register banks
192 *
193 * @qts: QTest state handle
194 * @smmu_base: SMMU base address
195 * @space: Target security space
196 *
197 * Programs SMMU registers for the requested security space which is called in
198 * qsmmu_setup_and_enable_translation. Always programs Non-Secure bank first,
199 * then the target space if different.
200 */
201 void qsmmu_program_regs(QTestState *qts, uint64_t smmu_base, QSMMUSpace space);
202
203 /* qsmmu_expected_dma_result - Calculate expected DMA result */
204 uint32_t qsmmu_expected_dma_result(QSMMUTestContext *ctx);
205
206 /*
207 * qsmmu_setup_translation_tables - Setup complete SMMU page table hierarchy
208 *
209 * @qts: QTest state handle
210 * @iova: Input Virtual Address or IPA to translate
211 * @space: Security space (NONSECURE, SECURE, REALM, ROOT)
212 * @is_cd: Whether translating CD address (vs regular IOVA)
213 * @mode: Translation mode (S1_ONLY, S2_ONLY, NESTED)
214 *
215 * This function builds the complete page table structure for translating
216 * the given IOVA through the SMMU. The structure varies based on mode:
217 *
218 * - S1_ONLY: Single Stage 1 walk (IOVA -> PA)
219 * - S2_ONLY: Single Stage 2 walk (IPA -> PA)
220 * - NESTED: Stage 1 walk (IOVA -> IPA) with nested S2 walks for each
221 * S1 table access, plus final S2 walk for the result IPA
222 *
223 * For nested mode, this creates a complex hierarchy:
224 * - 4 Stage 1 levels (L0-L3), each requiring a 4-level Stage 2 walk
225 * - 1 final Stage 2 walk for the resulting IPA
226 *
227 * The function writes all necessary Page Table Entries (PTEs) to guest
228 * memory using qtest_writeq(), setting up the complete translation path
229 * that the SMMU hardware will traverse during DMA operations.
230 */
231 void qsmmu_setup_translation_tables(QTestState *qts,
232 uint64_t iova,
233 QSMMUSpace space,
234 bool is_cd,
235 QSMMUTransMode mode);
236
237 /* High-level test execution helpers */
238 void qsmmu_run_translation_case(QTestState *qts, QPCIDevice *dev,
239 QPCIBar bar, uint64_t smmu_base,
240 const QSMMUTestConfig *cfg);
241
242 #endif /* QTEST_LIBQOS_SMMUV3_H */