1 /* 2 * QTest testcase for CXL 3 * 4 * This work is licensed under the terms of the GNU GPL, version 2 or later. 5 * See the COPYING file in the top-level directory. 6 */ 7 8 #include "qemu/osdep.h" 9 #include "libqtest-single.h" 10 11 #define QEMU_PXB_CMD \ 12 "-machine q35,cxl=on " \ 13 "-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52 " \ 14 "-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.size=4G " 15 16 #define QEMU_2PXB_CMD \ 17 "-machine q35,cxl=on " \ 18 "-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52 " \ 19 "-device pxb-cxl,id=cxl.1,bus=pcie.0,bus_nr=53 " \ 20 "-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=4G " 21 22 #define QEMU_VIRT_2PXB_CMD \ 23 "-machine virt,cxl=on -cpu max " \ 24 "-device pxb-cxl,id=cxl.0,bus=pcie.0,bus_nr=52 " \ 25 "-device pxb-cxl,id=cxl.1,bus=pcie.0,bus_nr=53 " \ 26 "-M cxl-fmw.0.targets.0=cxl.0,cxl-fmw.0.targets.1=cxl.1,cxl-fmw.0.size=4G " 27 28 #define QEMU_RP \ 29 "-device cxl-rp,id=rp0,bus=cxl.0,chassis=0,slot=0 " 30 31 /* Dual ports on first pxb */ 32 #define QEMU_2RP \ 33 "-device cxl-rp,id=rp0,bus=cxl.0,chassis=0,slot=0 " \ 34 "-device cxl-rp,id=rp1,bus=cxl.0,chassis=0,slot=1 " 35 36 /* Dual ports on each of the pxb instances */ 37 #define QEMU_4RP \ 38 "-device cxl-rp,id=rp0,bus=cxl.0,chassis=0,slot=0 " \ 39 "-device cxl-rp,id=rp1,bus=cxl.0,chassis=0,slot=1 " \ 40 "-device cxl-rp,id=rp2,bus=cxl.1,chassis=0,slot=2 " \ 41 "-device cxl-rp,id=rp3,bus=cxl.1,chassis=0,slot=3 " 42 43 #define QEMU_T3D_DEPRECATED \ 44 "-object memory-backend-file,id=cxl-mem0,mem-path=%s,size=256M " \ 45 "-object memory-backend-file,id=lsa0,mem-path=%s,size=256M " \ 46 "-device cxl-type3,bus=rp0,memdev=cxl-mem0,lsa=lsa0,id=cxl-pmem0 " 47 48 #define QEMU_T3D_PMEM \ 49 "-object memory-backend-file,id=cxl-mem0,mem-path=%s,size=256M " \ 50 "-object memory-backend-file,id=lsa0,mem-path=%s,size=256M " \ 51 "-device cxl-type3,bus=rp0,persistent-memdev=cxl-mem0,lsa=lsa0,id=pmem0 " 52 53 #define QEMU_T3D_VMEM \ 54 "-object memory-backend-ram,id=cxl-mem0,size=256M " \ 55 "-device cxl-type3,bus=rp0,volatile-memdev=cxl-mem0,id=mem0 " 56 57 #define QEMU_T3D_VMEM_LSA \ 58 "-object memory-backend-ram,id=cxl-mem0,size=256M " \ 59 "-object memory-backend-file,id=lsa0,mem-path=%s,size=256M " \ 60 "-device cxl-type3,bus=rp0,volatile-memdev=cxl-mem0,lsa=lsa0,id=mem0 " 61 62 #define QEMU_2T3D \ 63 "-object memory-backend-file,id=cxl-mem0,mem-path=%s,size=256M " \ 64 "-object memory-backend-file,id=lsa0,mem-path=%s,size=256M " \ 65 "-device cxl-type3,bus=rp0,persistent-memdev=cxl-mem0,lsa=lsa0,id=pmem0 " \ 66 "-object memory-backend-file,id=cxl-mem1,mem-path=%s,size=256M " \ 67 "-object memory-backend-file,id=lsa1,mem-path=%s,size=256M " \ 68 "-device cxl-type3,bus=rp1,persistent-memdev=cxl-mem1,lsa=lsa1,id=pmem1 " 69 70 #define QEMU_4T3D \ 71 "-object memory-backend-file,id=cxl-mem0,mem-path=%s,size=256M " \ 72 "-object memory-backend-file,id=lsa0,mem-path=%s,size=256M " \ 73 "-device cxl-type3,bus=rp0,persistent-memdev=cxl-mem0,lsa=lsa0,id=pmem0 " \ 74 "-object memory-backend-file,id=cxl-mem1,mem-path=%s,size=256M " \ 75 "-object memory-backend-file,id=lsa1,mem-path=%s,size=256M " \ 76 "-device cxl-type3,bus=rp1,persistent-memdev=cxl-mem1,lsa=lsa1,id=pmem1 " \ 77 "-object memory-backend-file,id=cxl-mem2,mem-path=%s,size=256M " \ 78 "-object memory-backend-file,id=lsa2,mem-path=%s,size=256M " \ 79 "-device cxl-type3,bus=rp2,persistent-memdev=cxl-mem2,lsa=lsa2,id=pmem2 " \ 80 "-object memory-backend-file,id=cxl-mem3,mem-path=%s,size=256M " \ 81 "-object memory-backend-file,id=lsa3,mem-path=%s,size=256M " \ 82 "-device cxl-type3,bus=rp3,persistent-memdev=cxl-mem3,lsa=lsa3,id=pmem3 " 83 84 static void cxl_basic_hb(void) 85 { 86 qtest_start("-machine q35,cxl=on"); 87 qtest_end(); 88 } 89 90 static void cxl_basic_pxb(void) 91 { 92 qtest_start("-machine q35,cxl=on -device pxb-cxl,bus=pcie.0"); 93 qtest_end(); 94 } 95 96 static void cxl_pxb_with_window(void) 97 { 98 qtest_start(QEMU_PXB_CMD); 99 qtest_end(); 100 } 101 102 static void cxl_2pxb_with_window(void) 103 { 104 qtest_start(QEMU_2PXB_CMD); 105 qtest_end(); 106 } 107 108 static void cxl_root_port(void) 109 { 110 qtest_start(QEMU_PXB_CMD QEMU_RP); 111 qtest_end(); 112 } 113 114 static void cxl_2root_port(void) 115 { 116 qtest_start(QEMU_PXB_CMD QEMU_2RP); 117 qtest_end(); 118 } 119 120 #ifdef CONFIG_POSIX 121 static void cxl_t3d_deprecated(void) 122 { 123 g_autoptr(GString) cmdline = g_string_new(NULL); 124 g_autofree const char *tmpfs = NULL; 125 126 tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL); 127 128 g_string_printf(cmdline, QEMU_PXB_CMD QEMU_RP QEMU_T3D_DEPRECATED, 129 tmpfs, tmpfs); 130 131 qtest_start(cmdline->str); 132 qtest_end(); 133 rmdir(tmpfs); 134 } 135 136 static void cxl_t3d_persistent(void) 137 { 138 g_autoptr(GString) cmdline = g_string_new(NULL); 139 g_autofree const char *tmpfs = NULL; 140 141 tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL); 142 143 g_string_printf(cmdline, QEMU_PXB_CMD QEMU_RP QEMU_T3D_PMEM, 144 tmpfs, tmpfs); 145 146 qtest_start(cmdline->str); 147 qtest_end(); 148 rmdir(tmpfs); 149 } 150 151 static void cxl_t3d_volatile(void) 152 { 153 g_autoptr(GString) cmdline = g_string_new(NULL); 154 155 g_string_printf(cmdline, QEMU_PXB_CMD QEMU_RP QEMU_T3D_VMEM); 156 157 qtest_start(cmdline->str); 158 qtest_end(); 159 } 160 161 static void cxl_t3d_volatile_lsa(void) 162 { 163 g_autoptr(GString) cmdline = g_string_new(NULL); 164 g_autofree const char *tmpfs = NULL; 165 166 tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL); 167 168 g_string_printf(cmdline, QEMU_PXB_CMD QEMU_RP QEMU_T3D_VMEM_LSA, 169 tmpfs); 170 171 qtest_start(cmdline->str); 172 qtest_end(); 173 rmdir(tmpfs); 174 } 175 176 static void cxl_1pxb_2rp_2t3d(void) 177 { 178 g_autoptr(GString) cmdline = g_string_new(NULL); 179 g_autofree const char *tmpfs = NULL; 180 181 tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL); 182 183 g_string_printf(cmdline, QEMU_PXB_CMD QEMU_2RP QEMU_2T3D, 184 tmpfs, tmpfs, tmpfs, tmpfs); 185 186 qtest_start(cmdline->str); 187 qtest_end(); 188 rmdir(tmpfs); 189 } 190 191 static void cxl_2pxb_4rp_4t3d(void) 192 { 193 g_autoptr(GString) cmdline = g_string_new(NULL); 194 g_autofree const char *tmpfs = NULL; 195 196 tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL); 197 198 g_string_printf(cmdline, QEMU_2PXB_CMD QEMU_4RP QEMU_4T3D, 199 tmpfs, tmpfs, tmpfs, tmpfs, tmpfs, tmpfs, 200 tmpfs, tmpfs); 201 202 qtest_start(cmdline->str); 203 qtest_end(); 204 rmdir(tmpfs); 205 } 206 207 static void cxl_virt_2pxb_4rp_4t3d(void) 208 { 209 g_autoptr(GString) cmdline = g_string_new(NULL); 210 g_autofree const char *tmpfs = NULL; 211 212 tmpfs = g_dir_make_tmp("cxl-test-XXXXXX", NULL); 213 214 g_string_printf(cmdline, QEMU_VIRT_2PXB_CMD QEMU_4RP QEMU_4T3D, 215 tmpfs, tmpfs, tmpfs, tmpfs, tmpfs, tmpfs, 216 tmpfs, tmpfs); 217 218 qtest_start(cmdline->str); 219 qtest_end(); 220 rmdir(tmpfs); 221 } 222 #endif /* CONFIG_POSIX */ 223 224 int main(int argc, char **argv) 225 { 226 const char *arch = qtest_get_arch(); 227 228 g_test_init(&argc, &argv, NULL); 229 if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { 230 qtest_add_func("/pci/cxl/basic_hostbridge", cxl_basic_hb); 231 qtest_add_func("/pci/cxl/basic_pxb", cxl_basic_pxb); 232 qtest_add_func("/pci/cxl/pxb_with_window", cxl_pxb_with_window); 233 qtest_add_func("/pci/cxl/pxb_x2_with_window", cxl_2pxb_with_window); 234 qtest_add_func("/pci/cxl/rp", cxl_root_port); 235 qtest_add_func("/pci/cxl/rp_x2", cxl_2root_port); 236 #ifdef CONFIG_POSIX 237 qtest_add_func("/pci/cxl/type3_device", cxl_t3d_deprecated); 238 qtest_add_func("/pci/cxl/type3_device_pmem", cxl_t3d_persistent); 239 qtest_add_func("/pci/cxl/type3_device_vmem", cxl_t3d_volatile); 240 qtest_add_func("/pci/cxl/type3_device_vmem_lsa", cxl_t3d_volatile_lsa); 241 qtest_add_func("/pci/cxl/rp_x2_type3_x2", cxl_1pxb_2rp_2t3d); 242 qtest_add_func("/pci/cxl/pxb_x2_root_port_x4_type3_x4", 243 cxl_2pxb_4rp_4t3d); 244 #endif 245 } else if (strcmp(arch, "aarch64") == 0) { 246 #ifdef CONFIG_POSIX 247 qtest_add_func("/pci/cxl/virt/pxb_x2_root_port_x4_type3_x4", 248 cxl_virt_2pxb_4rp_4t3d); 249 #endif 250 } 251 252 return g_test_run(); 253 } 254