| 1 | /* |
| 2 | * Boot order test cases. |
| 3 | * |
| 4 | * Copyright (c) 2013 Red Hat Inc. |
| 5 | * |
| 6 | * Authors: |
| 7 | * Michael S. Tsirkin <mst@redhat.com>, |
| 8 | * |
| 9 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 10 | * See the COPYING file in the top-level directory. |
| 11 | */ |
| 12 | |
| 13 | /* |
| 14 | * How to add or update the tests or commit changes that affect ACPI tables: |
| 15 | * Contributor: |
| 16 | * 1. add empty files for new tables, if any, under tests/data/acpi |
| 17 | * 2. list any changed files in tests/qtest/bios-tables-test-allowed-diff.h |
| 18 | * 3. commit the above *before* making changes that affect the tables |
| 19 | * |
| 20 | * Contributor or ACPI Maintainer (steps 4-7 need to be redone to resolve conflicts |
| 21 | * in binary commit created in step 6): |
| 22 | * |
| 23 | * After 1-3 above tests will pass but ignore differences with the expected files. |
| 24 | * You will also notice that tests/qtest/bios-tables-test-allowed-diff.h lists |
| 25 | * a bunch of files. This is your hint that you need to do the below: |
| 26 | * 4. Run |
| 27 | * make check V=2 |
| 28 | * this will produce a bunch of warnings about differences |
| 29 | * between actual and expected ACPI tables. If you have IASL installed, |
| 30 | * they will also be disassembled so you can look at the disassembled |
| 31 | * output. If not - disassemble them yourself in any way you like. |
| 32 | * Look at the differences - make sure they make sense and match what the |
| 33 | * changes you are merging are supposed to do. |
| 34 | * Save the changes, preferably in form of ASL diff for the commit log in |
| 35 | * step 6. |
| 36 | * |
| 37 | * 5. From build directory, run: |
| 38 | * $(SRC_PATH)/tests/data/acpi/rebuild-expected-aml.sh |
| 39 | * 6. Now commit any changes to the expected binary, include diff from step 4 |
| 40 | * in commit log. |
| 41 | * Expected binary updates needs to be a separate patch from the code that |
| 42 | * introduces changes to ACPI tables. It lets the maintainer drop |
| 43 | * and regenerate binary updates in case of merge conflicts. Further, a code |
| 44 | * change is easily reviewable but a binary blob is not (without doing a |
| 45 | * disassembly). |
| 46 | * 7. Before sending patches to the list (Contributor) |
| 47 | * or before doing a pull request (Maintainer), make sure |
| 48 | * tests/qtest/bios-tables-test-allowed-diff.h is empty - this will ensure |
| 49 | * following changes to ACPI tables will be noticed. |
| 50 | * |
| 51 | * The resulting patchset/pull request then looks like this: |
| 52 | * - patch 1: list changed files in tests/qtest/bios-tables-test-allowed-diff.h. |
| 53 | * - patches 2 - n: real changes, may contain multiple patches. |
| 54 | * - patch n + 1: update golden master binaries and empty |
| 55 | * tests/qtest/bios-tables-test-allowed-diff.h |
| 56 | */ |
| 57 | |
| 58 | #include "qemu/osdep.h" |
| 59 | #include <glib/gstdio.h> |
| 60 | #include "hw/firmware/smbios.h" |
| 61 | #include "qemu/bitmap.h" |
| 62 | #include "qemu/bswap.h" |
| 63 | #include "acpi-utils.h" |
| 64 | #include "boot-sector.h" |
| 65 | #include "tpm-emu.h" |
| 66 | #include "hw/acpi/tpm.h" |
| 67 | #include "qemu/cutils.h" |
| 68 | |
| 69 | #define MACHINE_PC "pc" |
| 70 | #define MACHINE_Q35 "q35" |
| 71 | |
| 72 | #define ACPI_REBUILD_EXPECTED_AML "TEST_ACPI_REBUILD_AML" |
| 73 | |
| 74 | #define OEM_ID "TEST" |
| 75 | #define OEM_TABLE_ID "OEM" |
| 76 | #define OEM_TEST_ARGS "-machine x-oem-id=" OEM_ID ",x-oem-table-id=" \ |
| 77 | OEM_TABLE_ID |
| 78 | |
| 79 | typedef struct { |
| 80 | bool tcg_only; |
| 81 | const char *machine; |
| 82 | const char *arch; |
| 83 | const char *machine_param; |
| 84 | const char *variant; |
| 85 | const char *uefi_fl1; |
| 86 | const char *uefi_fl2; |
| 87 | const char *blkdev; |
| 88 | const char *cd; |
| 89 | const uint64_t ram_start; |
| 90 | const uint64_t scan_len; |
| 91 | uint64_t rsdp_addr; |
| 92 | uint8_t rsdp_table[36 /* ACPI 2.0+ RSDP size */]; |
| 93 | GArray *tables; |
| 94 | uint64_t smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE__MAX]; |
| 95 | SmbiosEntryPoint smbios_ep_table; |
| 96 | uint16_t smbios_cpu_max_speed; |
| 97 | uint16_t smbios_cpu_curr_speed; |
| 98 | uint8_t smbios_core_count; |
| 99 | uint16_t smbios_core_count2; |
| 100 | uint8_t smbios_thread_count; |
| 101 | uint16_t smbios_thread_count2; |
| 102 | uint8_t *required_struct_types; |
| 103 | int required_struct_types_len; |
| 104 | int type4_count; |
| 105 | QTestState *qts; |
| 106 | } test_data; |
| 107 | |
| 108 | static char disk[] = "tests/acpi-test-disk-XXXXXX"; |
| 109 | static const char *data_dir = "tests/data/acpi"; |
| 110 | #ifdef CONFIG_IASL |
| 111 | static const char *iasl = CONFIG_IASL; |
| 112 | #else |
| 113 | static const char *iasl; |
| 114 | #endif |
| 115 | |
| 116 | static int verbosity_level; |
| 117 | static GArray *load_expected_aml(test_data *data); |
| 118 | |
| 119 | static bool compare_signature(const AcpiSdtTable *sdt, const char *signature) |
| 120 | { |
| 121 | return !memcmp(sdt->aml, signature, 4); |
| 122 | } |
| 123 | |
| 124 | static void cleanup_table_descriptor(AcpiSdtTable *table) |
| 125 | { |
| 126 | g_free(table->aml); |
| 127 | if (table->aml_file && |
| 128 | !table->tmp_files_retain && |
| 129 | g_strstr_len(table->aml_file, -1, "aml-")) { |
| 130 | unlink(table->aml_file); |
| 131 | } |
| 132 | g_free(table->aml_file); |
| 133 | g_free(table->asl); |
| 134 | if (table->asl_file && |
| 135 | !table->tmp_files_retain) { |
| 136 | unlink(table->asl_file); |
| 137 | } |
| 138 | g_free(table->asl_file); |
| 139 | } |
| 140 | |
| 141 | static void free_test_data(test_data *data) |
| 142 | { |
| 143 | int i; |
| 144 | |
| 145 | if (!data->tables) { |
| 146 | return; |
| 147 | } |
| 148 | for (i = 0; i < data->tables->len; ++i) { |
| 149 | cleanup_table_descriptor(&g_array_index(data->tables, AcpiSdtTable, i)); |
| 150 | } |
| 151 | |
| 152 | g_array_free(data->tables, true); |
| 153 | } |
| 154 | |
| 155 | static void test_acpi_rsdp_table(test_data *data) |
| 156 | { |
| 157 | uint8_t *rsdp_table = data->rsdp_table; |
| 158 | |
| 159 | acpi_fetch_rsdp_table(data->qts, data->rsdp_addr, rsdp_table); |
| 160 | |
| 161 | switch (rsdp_table[15 /* Revision offset */]) { |
| 162 | case 0: /* ACPI 1.0 RSDP */ |
| 163 | /* With rev 1, checksum is only for the first 20 bytes */ |
| 164 | g_assert(!acpi_calc_checksum(rsdp_table, 20)); |
| 165 | break; |
| 166 | case 2: /* ACPI 2.0+ RSDP */ |
| 167 | /* With revision 2, we have 2 checksums */ |
| 168 | g_assert(!acpi_calc_checksum(rsdp_table, 20)); |
| 169 | g_assert(!acpi_calc_checksum(rsdp_table, 36)); |
| 170 | break; |
| 171 | default: |
| 172 | g_assert_not_reached(); |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | static void test_acpi_rxsdt_table(test_data *data) |
| 177 | { |
| 178 | const char *sig = "RSDT"; |
| 179 | AcpiSdtTable rsdt = {}; |
| 180 | int entry_size = 4; |
| 181 | int addr_off = 16 /* RsdtAddress */; |
| 182 | uint8_t *ent; |
| 183 | |
| 184 | if (data->rsdp_table[15 /* Revision offset */] != 0) { |
| 185 | addr_off = 24 /* XsdtAddress */; |
| 186 | entry_size = 8; |
| 187 | sig = "XSDT"; |
| 188 | } |
| 189 | /* read [RX]SDT table */ |
| 190 | acpi_fetch_table(data->qts, &rsdt.aml, &rsdt.aml_len, |
| 191 | &data->rsdp_table[addr_off], entry_size, sig, true); |
| 192 | |
| 193 | /* Load all tables and add to test list directly RSDT referenced tables */ |
| 194 | ACPI_FOREACH_RSDT_ENTRY(rsdt.aml, rsdt.aml_len, ent, entry_size) { |
| 195 | AcpiSdtTable ssdt_table = {}; |
| 196 | |
| 197 | acpi_fetch_table(data->qts, &ssdt_table.aml, &ssdt_table.aml_len, ent, |
| 198 | entry_size, NULL, true); |
| 199 | /* Add table to ASL test tables list */ |
| 200 | g_array_append_val(data->tables, ssdt_table); |
| 201 | } |
| 202 | cleanup_table_descriptor(&rsdt); |
| 203 | } |
| 204 | |
| 205 | static void test_acpi_fadt_table(test_data *data) |
| 206 | { |
| 207 | /* FADT table is 1st */ |
| 208 | AcpiSdtTable table = g_array_index(data->tables, typeof(table), 0); |
| 209 | uint8_t *fadt_aml = table.aml; |
| 210 | uint32_t fadt_len = table.aml_len; |
| 211 | uint32_t val; |
| 212 | int dsdt_offset = 40 /* DSDT */; |
| 213 | int dsdt_entry_size = 4; |
| 214 | |
| 215 | g_assert(compare_signature(&table, "FACP")); |
| 216 | |
| 217 | /* Since DSDT/FACS isn't in RSDT, add them to ASL test list manually */ |
| 218 | memcpy(&val, fadt_aml + 112 /* Flags */, 4); |
| 219 | val = le32_to_cpu(val); |
| 220 | if (!(val & 1UL << 20 /* HW_REDUCED_ACPI */)) { |
| 221 | acpi_fetch_table(data->qts, &table.aml, &table.aml_len, |
| 222 | fadt_aml + 36 /* FIRMWARE_CTRL */, 4, "FACS", false); |
| 223 | g_array_append_val(data->tables, table); |
| 224 | } |
| 225 | |
| 226 | memcpy(&val, fadt_aml + dsdt_offset, 4); |
| 227 | val = le32_to_cpu(val); |
| 228 | if (!val) { |
| 229 | dsdt_offset = 140 /* X_DSDT */; |
| 230 | dsdt_entry_size = 8; |
| 231 | } |
| 232 | acpi_fetch_table(data->qts, &table.aml, &table.aml_len, |
| 233 | fadt_aml + dsdt_offset, dsdt_entry_size, "DSDT", true); |
| 234 | g_array_append_val(data->tables, table); |
| 235 | |
| 236 | memset(fadt_aml + 36, 0, 4); /* sanitize FIRMWARE_CTRL ptr */ |
| 237 | memset(fadt_aml + 40, 0, 4); /* sanitize DSDT ptr */ |
| 238 | if (fadt_aml[8 /* FADT Major Version */] >= 3) { |
| 239 | memset(fadt_aml + 132, 0, 8); /* sanitize X_FIRMWARE_CTRL ptr */ |
| 240 | memset(fadt_aml + 140, 0, 8); /* sanitize X_DSDT ptr */ |
| 241 | } |
| 242 | |
| 243 | /* update checksum */ |
| 244 | fadt_aml[9 /* Checksum */] = 0; |
| 245 | fadt_aml[9 /* Checksum */] -= acpi_calc_checksum(fadt_aml, fadt_len); |
| 246 | } |
| 247 | |
| 248 | static void dump_aml_files(test_data *data, bool rebuild) |
| 249 | { |
| 250 | AcpiSdtTable *sdt, *exp_sdt; |
| 251 | GError *error = NULL; |
| 252 | gchar *aml_file = NULL; |
| 253 | test_data exp_data = {}; |
| 254 | gint fd; |
| 255 | ssize_t ret; |
| 256 | int i; |
| 257 | |
| 258 | exp_data.tables = load_expected_aml(data); |
| 259 | for (i = 0; i < data->tables->len; ++i) { |
| 260 | const char *ext = data->variant ? data->variant : ""; |
| 261 | sdt = &g_array_index(data->tables, AcpiSdtTable, i); |
| 262 | exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i); |
| 263 | g_assert(sdt->aml); |
| 264 | g_assert(exp_sdt->aml); |
| 265 | |
| 266 | if (rebuild) { |
| 267 | aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir, |
| 268 | data->arch, data->machine, |
| 269 | sdt->aml, ext); |
| 270 | |
| 271 | if (!g_file_test(aml_file, G_FILE_TEST_EXISTS) && |
| 272 | sdt->aml_len == exp_sdt->aml_len && |
| 273 | !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) { |
| 274 | /* identical tables, no need to write new files */ |
| 275 | g_free(aml_file); |
| 276 | continue; |
| 277 | } |
| 278 | fd = g_open(aml_file, O_WRONLY|O_TRUNC|O_CREAT, |
| 279 | S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH); |
| 280 | if (fd < 0) { |
| 281 | perror(aml_file); |
| 282 | } |
| 283 | g_assert(fd >= 0); |
| 284 | } else { |
| 285 | fd = g_file_open_tmp("aml-XXXXXX", &sdt->aml_file, &error); |
| 286 | g_assert_no_error(error); |
| 287 | } |
| 288 | |
| 289 | ret = qemu_write_full(fd, sdt->aml, sdt->aml_len); |
| 290 | g_assert(ret == sdt->aml_len); |
| 291 | |
| 292 | close(fd); |
| 293 | |
| 294 | g_free(aml_file); |
| 295 | } |
| 296 | free_test_data(&exp_data); |
| 297 | } |
| 298 | |
| 299 | static bool create_tmp_asl(AcpiSdtTable *sdt) |
| 300 | { |
| 301 | GError *error = NULL; |
| 302 | gint fd; |
| 303 | |
| 304 | fd = g_file_open_tmp("asl-XXXXXX.dsl", &sdt->asl_file, &error); |
| 305 | g_assert_no_error(error); |
| 306 | close(fd); |
| 307 | |
| 308 | return false; |
| 309 | } |
| 310 | |
| 311 | static bool load_asl(GArray *sdts, AcpiSdtTable *sdt) |
| 312 | { |
| 313 | AcpiSdtTable *temp; |
| 314 | GError *error = NULL; |
| 315 | GString *command_line = g_string_new(iasl); |
| 316 | gchar *out, *out_err; |
| 317 | gboolean ret; |
| 318 | int i; |
| 319 | |
| 320 | create_tmp_asl(sdt); |
| 321 | |
| 322 | /* build command line */ |
| 323 | g_string_append_printf(command_line, " -p %s ", sdt->asl_file); |
| 324 | if (compare_signature(sdt, "DSDT") || |
| 325 | compare_signature(sdt, "SSDT")) { |
| 326 | for (i = 0; i < sdts->len; ++i) { |
| 327 | temp = &g_array_index(sdts, AcpiSdtTable, i); |
| 328 | if (compare_signature(temp, "DSDT") || |
| 329 | compare_signature(temp, "SSDT")) { |
| 330 | g_string_append_printf(command_line, "-e %s ", temp->aml_file); |
| 331 | } |
| 332 | } |
| 333 | } |
| 334 | g_string_append_printf(command_line, "-d %s", sdt->aml_file); |
| 335 | |
| 336 | /* pass 'out' and 'out_err' in order to be redirected */ |
| 337 | ret = g_spawn_command_line_sync(command_line->str, &out, &out_err, NULL, &error); |
| 338 | g_assert_no_error(error); |
| 339 | if (ret) { |
| 340 | ret = g_file_get_contents(sdt->asl_file, &sdt->asl, |
| 341 | &sdt->asl_len, &error); |
| 342 | g_assert(ret); |
| 343 | g_assert_no_error(error); |
| 344 | ret = (sdt->asl_len > 0); |
| 345 | } |
| 346 | |
| 347 | g_free(out); |
| 348 | g_free(out_err); |
| 349 | g_string_free(command_line, true); |
| 350 | |
| 351 | return !ret; |
| 352 | } |
| 353 | |
| 354 | #define COMMENT_END "*/" |
| 355 | #define DEF_BLOCK "DefinitionBlock (" |
| 356 | #define BLOCK_NAME_END "," |
| 357 | |
| 358 | static GString *normalize_asl(gchar *asl_code) |
| 359 | { |
| 360 | GString *asl = g_string_new(asl_code); |
| 361 | gchar *comment, *block_name; |
| 362 | |
| 363 | /* strip comments (different generation days) */ |
| 364 | comment = g_strstr_len(asl->str, asl->len, COMMENT_END); |
| 365 | if (comment) { |
| 366 | comment += strlen(COMMENT_END); |
| 367 | while (*comment == '\n') { |
| 368 | comment++; |
| 369 | } |
| 370 | asl = g_string_erase(asl, 0, comment - asl->str); |
| 371 | } |
| 372 | |
| 373 | /* strip def block name (it has file path in it) */ |
| 374 | if (g_str_has_prefix(asl->str, DEF_BLOCK)) { |
| 375 | block_name = g_strstr_len(asl->str, asl->len, BLOCK_NAME_END); |
| 376 | g_assert(block_name); |
| 377 | asl = g_string_erase(asl, 0, |
| 378 | block_name + sizeof(BLOCK_NAME_END) - asl->str); |
| 379 | } |
| 380 | |
| 381 | return asl; |
| 382 | } |
| 383 | |
| 384 | static GArray *load_expected_aml(test_data *data) |
| 385 | { |
| 386 | int i; |
| 387 | AcpiSdtTable *sdt; |
| 388 | GError *error = NULL; |
| 389 | gboolean ret; |
| 390 | gsize aml_len; |
| 391 | |
| 392 | GArray *exp_tables = g_array_new(false, true, sizeof(AcpiSdtTable)); |
| 393 | if (verbosity_level >= 2) { |
| 394 | fputc('\n', stderr); |
| 395 | } |
| 396 | for (i = 0; i < data->tables->len; ++i) { |
| 397 | AcpiSdtTable exp_sdt; |
| 398 | gchar *aml_file = NULL; |
| 399 | const char *ext = data->variant ? data->variant : ""; |
| 400 | |
| 401 | sdt = &g_array_index(data->tables, AcpiSdtTable, i); |
| 402 | |
| 403 | memset(&exp_sdt, 0, sizeof(exp_sdt)); |
| 404 | |
| 405 | try_again: |
| 406 | aml_file = g_strdup_printf("%s/%s/%s/%.4s%s", data_dir, data->arch, |
| 407 | data->machine, sdt->aml, ext); |
| 408 | if (verbosity_level >= 2) { |
| 409 | fprintf(stderr, "Looking for expected file '%s'\n", aml_file); |
| 410 | } |
| 411 | if (g_file_test(aml_file, G_FILE_TEST_EXISTS)) { |
| 412 | exp_sdt.aml_file = aml_file; |
| 413 | } else if (*ext != '\0') { |
| 414 | /* try fallback to generic (extension less) expected file */ |
| 415 | ext = ""; |
| 416 | g_free(aml_file); |
| 417 | goto try_again; |
| 418 | } |
| 419 | g_assert(exp_sdt.aml_file); |
| 420 | if (verbosity_level >= 2) { |
| 421 | fprintf(stderr, "Using expected file '%s'\n", aml_file); |
| 422 | } |
| 423 | ret = g_file_get_contents(aml_file, (gchar **)&exp_sdt.aml, |
| 424 | &aml_len, &error); |
| 425 | exp_sdt.aml_len = aml_len; |
| 426 | g_assert(ret); |
| 427 | g_assert_no_error(error); |
| 428 | g_assert(exp_sdt.aml); |
| 429 | if (!exp_sdt.aml_len) { |
| 430 | fprintf(stderr, "Warning! zero length expected file '%s'\n", |
| 431 | aml_file); |
| 432 | } |
| 433 | |
| 434 | g_array_append_val(exp_tables, exp_sdt); |
| 435 | } |
| 436 | |
| 437 | return exp_tables; |
| 438 | } |
| 439 | |
| 440 | static bool test_acpi_find_diff_allowed(AcpiSdtTable *sdt) |
| 441 | { |
| 442 | const gchar *allowed_diff_file[] = { |
| 443 | #include "bios-tables-test-allowed-diff.h" |
| 444 | NULL |
| 445 | }; |
| 446 | const gchar **f; |
| 447 | |
| 448 | for (f = allowed_diff_file; *f; ++f) { |
| 449 | if (!g_strcmp0(sdt->aml_file, *f)) { |
| 450 | return true; |
| 451 | } |
| 452 | } |
| 453 | return false; |
| 454 | } |
| 455 | |
| 456 | /* test the list of tables in @data->tables against reference tables */ |
| 457 | static void test_acpi_asl(test_data *data) |
| 458 | { |
| 459 | int i; |
| 460 | AcpiSdtTable *sdt, *exp_sdt; |
| 461 | test_data exp_data = {}; |
| 462 | gboolean exp_err, err, all_tables_match = true; |
| 463 | |
| 464 | exp_data.tables = load_expected_aml(data); |
| 465 | dump_aml_files(data, false); |
| 466 | for (i = 0; i < data->tables->len; ++i) { |
| 467 | GString *asl, *exp_asl; |
| 468 | |
| 469 | sdt = &g_array_index(data->tables, AcpiSdtTable, i); |
| 470 | exp_sdt = &g_array_index(exp_data.tables, AcpiSdtTable, i); |
| 471 | |
| 472 | if (sdt->aml_len == exp_sdt->aml_len && |
| 473 | !memcmp(sdt->aml, exp_sdt->aml, sdt->aml_len)) { |
| 474 | /* Identical table binaries: no need to disassemble. */ |
| 475 | continue; |
| 476 | } |
| 477 | |
| 478 | fprintf(stderr, |
| 479 | "acpi-test: Warning! %.4s binary file mismatch. " |
| 480 | "Actual [aml:%s], Expected [aml:%s].\n" |
| 481 | "See source file tests/qtest/bios-tables-test.c " |
| 482 | "for instructions on how to update expected files.\n", |
| 483 | exp_sdt->aml, sdt->aml_file, exp_sdt->aml_file); |
| 484 | |
| 485 | all_tables_match = all_tables_match && |
| 486 | test_acpi_find_diff_allowed(exp_sdt); |
| 487 | |
| 488 | /* |
| 489 | * don't try to decompile if IASL isn't present, in this case user |
| 490 | * will just 'get binary file mismatch' warnings and test failure |
| 491 | */ |
| 492 | if (!iasl) { |
| 493 | continue; |
| 494 | } |
| 495 | |
| 496 | err = load_asl(data->tables, sdt); |
| 497 | asl = normalize_asl(sdt->asl); |
| 498 | |
| 499 | /* |
| 500 | * If expected file is empty - it's likely that it was a stub just |
| 501 | * created for step 1 above: we do want to decompile the actual one. |
| 502 | */ |
| 503 | if (exp_sdt->aml_len) { |
| 504 | exp_err = load_asl(exp_data.tables, exp_sdt); |
| 505 | exp_asl = normalize_asl(exp_sdt->asl); |
| 506 | } else { |
| 507 | exp_err = create_tmp_asl(exp_sdt); |
| 508 | exp_asl = g_string_new(""); |
| 509 | } |
| 510 | |
| 511 | /* TODO: check for warnings */ |
| 512 | g_assert(!err || exp_err || !exp_sdt->aml_len); |
| 513 | |
| 514 | if (g_strcmp0(asl->str, exp_asl->str)) { |
| 515 | sdt->tmp_files_retain = true; |
| 516 | if (exp_err) { |
| 517 | fprintf(stderr, |
| 518 | "Warning! iasl couldn't parse the expected aml\n"); |
| 519 | } else { |
| 520 | exp_sdt->tmp_files_retain = true; |
| 521 | fprintf(stderr, |
| 522 | "acpi-test: Warning! %.4s mismatch. " |
| 523 | "Actual [asl:%s, aml:%s], Expected [asl:%s, aml:%s].\n", |
| 524 | exp_sdt->aml, sdt->asl_file, sdt->aml_file, |
| 525 | exp_sdt->asl_file, exp_sdt->aml_file); |
| 526 | fflush(stderr); |
| 527 | if (verbosity_level >= 1) { |
| 528 | const char *diff_env = getenv("DIFF"); |
| 529 | const char *diff_cmd = diff_env ? diff_env : "diff -U 16"; |
| 530 | char *diff = g_strdup_printf("%s %s %s", diff_cmd, |
| 531 | exp_sdt->asl_file, sdt->asl_file); |
| 532 | int out = dup(STDOUT_FILENO); |
| 533 | int ret G_GNUC_UNUSED; |
| 534 | int dupret; |
| 535 | |
| 536 | g_assert(out >= 0); |
| 537 | dupret = dup2(STDERR_FILENO, STDOUT_FILENO); |
| 538 | g_assert(dupret >= 0); |
| 539 | ret = system(diff) ; |
| 540 | dupret = dup2(out, STDOUT_FILENO); |
| 541 | g_assert(dupret >= 0); |
| 542 | close(out); |
| 543 | g_free(diff); |
| 544 | } |
| 545 | } |
| 546 | } |
| 547 | g_string_free(asl, true); |
| 548 | g_string_free(exp_asl, true); |
| 549 | } |
| 550 | if (!iasl && !all_tables_match) { |
| 551 | fprintf(stderr, "to see ASL diff between mismatched files install IASL," |
| 552 | " rebuild QEMU from scratch and re-run tests with V=1" |
| 553 | " environment variable set"); |
| 554 | } |
| 555 | g_assert(all_tables_match); |
| 556 | |
| 557 | free_test_data(&exp_data); |
| 558 | } |
| 559 | |
| 560 | static bool smbios_ep2_table_ok(test_data *data, uint32_t addr) |
| 561 | { |
| 562 | struct smbios_21_entry_point *ep_table = &data->smbios_ep_table.ep21; |
| 563 | |
| 564 | qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table)); |
| 565 | if (memcmp(ep_table->anchor_string, "_SM_", 4)) { |
| 566 | return false; |
| 567 | } |
| 568 | if (memcmp(ep_table->intermediate_anchor_string, "_DMI_", 5)) { |
| 569 | return false; |
| 570 | } |
| 571 | if (ep_table->structure_table_length == 0) { |
| 572 | return false; |
| 573 | } |
| 574 | if (ep_table->number_of_structures == 0) { |
| 575 | return false; |
| 576 | } |
| 577 | if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table) || |
| 578 | acpi_calc_checksum((uint8_t *)ep_table + 0x10, |
| 579 | sizeof *ep_table - 0x10)) { |
| 580 | return false; |
| 581 | } |
| 582 | return true; |
| 583 | } |
| 584 | |
| 585 | static bool smbios_ep3_table_ok(test_data *data, uint64_t addr) |
| 586 | { |
| 587 | struct smbios_30_entry_point *ep_table = &data->smbios_ep_table.ep30; |
| 588 | |
| 589 | qtest_memread(data->qts, addr, ep_table, sizeof(*ep_table)); |
| 590 | if (memcmp(ep_table->anchor_string, "_SM3_", 5)) { |
| 591 | return false; |
| 592 | } |
| 593 | |
| 594 | if (acpi_calc_checksum((uint8_t *)ep_table, sizeof *ep_table)) { |
| 595 | return false; |
| 596 | } |
| 597 | |
| 598 | return true; |
| 599 | } |
| 600 | |
| 601 | static SmbiosEntryPointType test_smbios_entry_point(test_data *data) |
| 602 | { |
| 603 | uint32_t off; |
| 604 | |
| 605 | /* find smbios entry point structure */ |
| 606 | for (off = 0xf0000; off < 0x100000; off += 0x10) { |
| 607 | uint8_t sig[] = "_SM_", sig3[] = "_SM3_"; |
| 608 | int i; |
| 609 | |
| 610 | for (i = 0; i < sizeof sig - 1; ++i) { |
| 611 | sig[i] = qtest_readb(data->qts, off + i); |
| 612 | } |
| 613 | |
| 614 | if (!memcmp(sig, "_SM_", sizeof sig)) { |
| 615 | /* signature match, but is this a valid entry point? */ |
| 616 | if (smbios_ep2_table_ok(data, off)) { |
| 617 | data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] = off; |
| 618 | } |
| 619 | } |
| 620 | |
| 621 | for (i = 0; i < sizeof sig3 - 1; ++i) { |
| 622 | sig3[i] = qtest_readb(data->qts, off + i); |
| 623 | } |
| 624 | |
| 625 | if (!memcmp(sig3, "_SM3_", sizeof sig3)) { |
| 626 | if (smbios_ep3_table_ok(data, off)) { |
| 627 | data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] = off; |
| 628 | /* found 64-bit entry point, no need to look for 32-bit one */ |
| 629 | break; |
| 630 | } |
| 631 | } |
| 632 | } |
| 633 | |
| 634 | /* found at least one entry point */ |
| 635 | g_assert_true(data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_32] || |
| 636 | data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64]); |
| 637 | |
| 638 | return data->smbios_ep_addr[SMBIOS_ENTRY_POINT_TYPE_64] ? |
| 639 | SMBIOS_ENTRY_POINT_TYPE_64 : SMBIOS_ENTRY_POINT_TYPE_32; |
| 640 | } |
| 641 | |
| 642 | static inline bool smbios_single_instance(uint8_t type) |
| 643 | { |
| 644 | switch (type) { |
| 645 | case 0: |
| 646 | case 1: |
| 647 | case 2: |
| 648 | case 3: |
| 649 | case 16: |
| 650 | case 32: |
| 651 | case 127: |
| 652 | return true; |
| 653 | default: |
| 654 | return false; |
| 655 | } |
| 656 | } |
| 657 | |
| 658 | static void smbios_cpu_test(test_data *data, uint32_t addr, |
| 659 | SmbiosEntryPointType ep_type) |
| 660 | { |
| 661 | uint8_t core_count, expected_core_count = data->smbios_core_count; |
| 662 | uint8_t thread_count, expected_thread_count = data->smbios_thread_count; |
| 663 | uint16_t speed, expected_speed[2]; |
| 664 | uint16_t core_count2, expected_core_count2 = data->smbios_core_count2; |
| 665 | uint16_t thread_count2, expected_thread_count2 = data->smbios_thread_count2; |
| 666 | int offset[2]; |
| 667 | int i; |
| 668 | |
| 669 | /* Check CPU speed for backward compatibility */ |
| 670 | offset[0] = offsetof(struct smbios_type_4, max_speed); |
| 671 | offset[1] = offsetof(struct smbios_type_4, current_speed); |
| 672 | expected_speed[0] = data->smbios_cpu_max_speed ? : 2000; |
| 673 | expected_speed[1] = data->smbios_cpu_curr_speed ? : 2000; |
| 674 | |
| 675 | for (i = 0; i < 2; i++) { |
| 676 | speed = qtest_readw(data->qts, addr + offset[i]); |
| 677 | g_assert_cmpuint(speed, ==, expected_speed[i]); |
| 678 | } |
| 679 | |
| 680 | core_count = qtest_readb(data->qts, |
| 681 | addr + offsetof(struct smbios_type_4, core_count)); |
| 682 | |
| 683 | if (expected_core_count) { |
| 684 | g_assert_cmpuint(core_count, ==, expected_core_count); |
| 685 | } |
| 686 | |
| 687 | thread_count = qtest_readb(data->qts, |
| 688 | addr + offsetof(struct smbios_type_4, thread_count)); |
| 689 | |
| 690 | if (expected_thread_count) { |
| 691 | g_assert_cmpuint(thread_count, ==, expected_thread_count); |
| 692 | } |
| 693 | |
| 694 | if (ep_type == SMBIOS_ENTRY_POINT_TYPE_64) { |
| 695 | core_count2 = qtest_readw(data->qts, |
| 696 | addr + offsetof(struct smbios_type_4, core_count2)); |
| 697 | |
| 698 | /* Core Count has reached its limit, checking Core Count 2 */ |
| 699 | if (expected_core_count == 0xFF && expected_core_count2) { |
| 700 | g_assert_cmpuint(core_count2, ==, expected_core_count2); |
| 701 | } |
| 702 | |
| 703 | thread_count2 = qtest_readw(data->qts, |
| 704 | addr + offsetof(struct smbios_type_4, |
| 705 | thread_count2)); |
| 706 | |
| 707 | /* Thread Count has reached its limit, checking Thread Count 2 */ |
| 708 | if (expected_thread_count == 0xFF && expected_thread_count2) { |
| 709 | g_assert_cmpuint(thread_count2, ==, expected_thread_count2); |
| 710 | } |
| 711 | } |
| 712 | } |
| 713 | |
| 714 | static void smbios_type4_count_test(test_data *data, int type4_count) |
| 715 | { |
| 716 | int expected_type4_count = data->type4_count; |
| 717 | |
| 718 | if (expected_type4_count) { |
| 719 | g_assert_cmpuint(type4_count, ==, expected_type4_count); |
| 720 | } |
| 721 | } |
| 722 | |
| 723 | static void test_smbios_structs(test_data *data, SmbiosEntryPointType ep_type) |
| 724 | { |
| 725 | DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 }; |
| 726 | |
| 727 | SmbiosEntryPoint *ep_table = &data->smbios_ep_table; |
| 728 | int i = 0, len, max_len = 0, type4_count = 0; |
| 729 | uint8_t type, prv, crt; |
| 730 | uint64_t addr; |
| 731 | |
| 732 | if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) { |
| 733 | addr = le32_to_cpu(ep_table->ep21.structure_table_address); |
| 734 | } else { |
| 735 | addr = le64_to_cpu(ep_table->ep30.structure_table_address); |
| 736 | } |
| 737 | |
| 738 | /* walk the smbios tables */ |
| 739 | do { |
| 740 | |
| 741 | /* grab type and formatted area length from struct header */ |
| 742 | type = qtest_readb(data->qts, addr); |
| 743 | g_assert_cmpuint(type, <=, SMBIOS_MAX_TYPE); |
| 744 | len = qtest_readb(data->qts, addr + 1); |
| 745 | |
| 746 | /* single-instance structs must not have been encountered before */ |
| 747 | if (smbios_single_instance(type)) { |
| 748 | g_assert(!test_bit(type, struct_bitmap)); |
| 749 | } |
| 750 | set_bit(type, struct_bitmap); |
| 751 | |
| 752 | if (type == 4) { |
| 753 | smbios_cpu_test(data, addr, ep_type); |
| 754 | type4_count++; |
| 755 | } |
| 756 | |
| 757 | /* seek to end of unformatted string area of this struct ("\0\0") */ |
| 758 | prv = crt = 1; |
| 759 | while (prv || crt) { |
| 760 | prv = crt; |
| 761 | crt = qtest_readb(data->qts, addr + len); |
| 762 | len++; |
| 763 | } |
| 764 | |
| 765 | /* keep track of max. struct size */ |
| 766 | if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 && max_len < len) { |
| 767 | max_len = len; |
| 768 | g_assert_cmpuint(max_len, <=, ep_table->ep21.max_structure_size); |
| 769 | } |
| 770 | |
| 771 | /* start of next structure */ |
| 772 | addr += len; |
| 773 | |
| 774 | /* |
| 775 | * Until all structures have been scanned (ep21) |
| 776 | * or an EOF structure is found (ep30) |
| 777 | */ |
| 778 | } while (ep_type == SMBIOS_ENTRY_POINT_TYPE_32 ? |
| 779 | ++i < le16_to_cpu(ep_table->ep21.number_of_structures) : |
| 780 | type != 127); |
| 781 | |
| 782 | if (ep_type == SMBIOS_ENTRY_POINT_TYPE_32) { |
| 783 | /* |
| 784 | * Total table length and max struct size |
| 785 | * must match entry point values |
| 786 | */ |
| 787 | g_assert_cmpuint(le16_to_cpu(ep_table->ep21.structure_table_length), ==, |
| 788 | addr - le32_to_cpu(ep_table->ep21.structure_table_address)); |
| 789 | |
| 790 | g_assert_cmpuint(le16_to_cpu(ep_table->ep21.max_structure_size), ==, |
| 791 | max_len); |
| 792 | } |
| 793 | |
| 794 | /* required struct types must all be present */ |
| 795 | for (i = 0; i < data->required_struct_types_len; i++) { |
| 796 | g_assert(test_bit(data->required_struct_types[i], struct_bitmap)); |
| 797 | } |
| 798 | |
| 799 | smbios_type4_count_test(data, type4_count); |
| 800 | } |
| 801 | |
| 802 | static void test_acpi_load_tables(test_data *data) |
| 803 | { |
| 804 | if (data->uefi_fl1 && data->uefi_fl2) { /* use UEFI */ |
| 805 | g_assert(data->scan_len); |
| 806 | data->rsdp_addr = acpi_find_rsdp_address_uefi(data->qts, |
| 807 | data->ram_start, data->scan_len); |
| 808 | } else { |
| 809 | boot_sector_test(data->qts); |
| 810 | data->rsdp_addr = acpi_find_rsdp_address(data->qts); |
| 811 | g_assert_cmphex(data->rsdp_addr, <, 0x100000); |
| 812 | } |
| 813 | |
| 814 | data->tables = g_array_new(false, true, sizeof(AcpiSdtTable)); |
| 815 | test_acpi_rsdp_table(data); |
| 816 | test_acpi_rxsdt_table(data); |
| 817 | test_acpi_fadt_table(data); |
| 818 | } |
| 819 | |
| 820 | static char *test_acpi_create_args(test_data *data, const char *params) |
| 821 | { |
| 822 | char *args; |
| 823 | |
| 824 | if (data->uefi_fl1 && data->uefi_fl2) { /* use UEFI */ |
| 825 | /* |
| 826 | * TODO: convert '-drive if=pflash' to new syntax (see e33763be7cd3) |
| 827 | * when arm/virt boad starts to support it. |
| 828 | */ |
| 829 | if (data->cd) { |
| 830 | args = g_strdup_printf("-machine %s%s %s -accel tcg " |
| 831 | "-nodefaults -nographic " |
| 832 | "-drive if=pflash,format=raw,file=%s,readonly=on " |
| 833 | "-drive if=pflash,format=raw,file=%s,snapshot=on -cdrom %s %s", |
| 834 | data->machine, data->machine_param ?: "", |
| 835 | data->tcg_only ? "" : "-accel kvm", |
| 836 | data->uefi_fl1, data->uefi_fl2, data->cd, params ? params : ""); |
| 837 | } else { |
| 838 | args = g_strdup_printf("-machine %s%s %s -accel tcg " |
| 839 | "-nodefaults -nographic " |
| 840 | "-drive if=pflash,format=raw,file=%s,readonly=on " |
| 841 | "-drive if=pflash,format=raw,file=%s,snapshot=on %s", |
| 842 | data->machine, data->machine_param ?: "", |
| 843 | data->tcg_only ? "" : "-accel kvm", |
| 844 | data->uefi_fl1, data->uefi_fl2, params ? params : ""); |
| 845 | } |
| 846 | } else { |
| 847 | args = g_strdup_printf("-machine %s%s %s -accel tcg " |
| 848 | "-net none %s " |
| 849 | "-drive id=hd0,if=none,file=%s,format=raw " |
| 850 | "-device %s,drive=hd0 ", |
| 851 | data->machine, data->machine_param ?: "", |
| 852 | data->tcg_only ? "" : "-accel kvm", |
| 853 | params ? params : "", disk, |
| 854 | data->blkdev ?: "ide-hd"); |
| 855 | } |
| 856 | return args; |
| 857 | } |
| 858 | |
| 859 | static void test_vm_prepare(const char *params, test_data *data) |
| 860 | { |
| 861 | char *args = test_acpi_create_args(data, params); |
| 862 | data->qts = qtest_init(args); |
| 863 | g_free(args); |
| 864 | } |
| 865 | |
| 866 | static void process_smbios_tables_noexit(test_data *data) |
| 867 | { |
| 868 | /* |
| 869 | * TODO: make SMBIOS tests work with UEFI firmware, |
| 870 | * Bug on uefi-test-tools to provide entry point: |
| 871 | * https://bugs.launchpad.net/qemu/+bug/1821884 |
| 872 | */ |
| 873 | if (!(data->uefi_fl1 && data->uefi_fl2)) { |
| 874 | SmbiosEntryPointType ep_type = test_smbios_entry_point(data); |
| 875 | test_smbios_structs(data, ep_type); |
| 876 | } |
| 877 | } |
| 878 | |
| 879 | static void test_smbios(const char *params, test_data *data) |
| 880 | { |
| 881 | test_vm_prepare(params, data); |
| 882 | boot_sector_test(data->qts); |
| 883 | process_smbios_tables_noexit(data); |
| 884 | qtest_quit(data->qts); |
| 885 | } |
| 886 | |
| 887 | static void process_acpi_tables_noexit(test_data *data) |
| 888 | { |
| 889 | test_acpi_load_tables(data); |
| 890 | |
| 891 | if (getenv(ACPI_REBUILD_EXPECTED_AML)) { |
| 892 | dump_aml_files(data, true); |
| 893 | } else { |
| 894 | test_acpi_asl(data); |
| 895 | } |
| 896 | |
| 897 | process_smbios_tables_noexit(data); |
| 898 | } |
| 899 | |
| 900 | static void process_acpi_tables(test_data *data) |
| 901 | { |
| 902 | process_acpi_tables_noexit(data); |
| 903 | qtest_quit(data->qts); |
| 904 | } |
| 905 | |
| 906 | static void test_acpi_one(const char *params, test_data *data) |
| 907 | { |
| 908 | test_vm_prepare(params, data); |
| 909 | process_acpi_tables(data); |
| 910 | } |
| 911 | |
| 912 | static uint8_t base_required_struct_types[] = { |
| 913 | 0, 1, 3, 4, 16, 17, 19, 32, 127 |
| 914 | }; |
| 915 | |
| 916 | static void test_acpi_piix4_tcg(void) |
| 917 | { |
| 918 | test_data data = {}; |
| 919 | |
| 920 | /* Supplying -machine accel argument overrides the default (qtest). |
| 921 | * This is to make guest actually run. |
| 922 | */ |
| 923 | data.machine = MACHINE_PC; |
| 924 | data.arch = "x86"; |
| 925 | data.required_struct_types = base_required_struct_types; |
| 926 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 927 | test_acpi_one(NULL, &data); |
| 928 | free_test_data(&data); |
| 929 | } |
| 930 | |
| 931 | static void test_acpi_piix4_tcg_bridge(void) |
| 932 | { |
| 933 | test_data data = {}; |
| 934 | |
| 935 | data.machine = MACHINE_PC; |
| 936 | data.arch = "x86"; |
| 937 | data.variant = ".bridge"; |
| 938 | data.required_struct_types = base_required_struct_types; |
| 939 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 940 | test_vm_prepare("-S" |
| 941 | " -device pci-bridge,chassis_nr=1" |
| 942 | " -device pci-bridge,bus=pci.1,addr=1.0,chassis_nr=2" |
| 943 | " -device pci-testdev,bus=pci.0,addr=5.0" |
| 944 | " -device pci-testdev,bus=pci.1", &data); |
| 945 | |
| 946 | /* hotplugged bridges section */ |
| 947 | qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr", |
| 948 | "{'bus': 'pci.1', 'addr': '2.0', 'chassis_nr': 3 }"); |
| 949 | qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr_multifunc", |
| 950 | "{'bus': 'pci.1', 'addr': '0xf.1', 'chassis_nr': 4 }"); |
| 951 | qtest_qmp_device_add(data.qts, "pci-bridge", "hpbrhost", |
| 952 | "{'bus': 'pci.0', 'addr': '4.0', 'chassis_nr': 5 }"); |
| 953 | qtest_qmp_device_add(data.qts, "pci-testdev", "d1", "{'bus': 'pci.0' }"); |
| 954 | qtest_qmp_device_add(data.qts, "pci-testdev", "d2", "{'bus': 'pci.1' }"); |
| 955 | qtest_qmp_device_add(data.qts, "pci-testdev", "d3", "{'bus': 'hpbr', " |
| 956 | "'addr': '1.0' }"); |
| 957 | qtest_qmp_send(data.qts, "{'execute':'cont' }"); |
| 958 | qtest_qmp_eventwait(data.qts, "RESUME"); |
| 959 | |
| 960 | process_acpi_tables_noexit(&data); |
| 961 | free_test_data(&data); |
| 962 | |
| 963 | /* check that reboot/reset doesn't change any ACPI tables */ |
| 964 | qtest_system_reset(data.qts); |
| 965 | process_acpi_tables(&data); |
| 966 | free_test_data(&data); |
| 967 | } |
| 968 | |
| 969 | static void test_acpi_piix4_no_root_hotplug(void) |
| 970 | { |
| 971 | test_data data = {}; |
| 972 | |
| 973 | data.machine = MACHINE_PC; |
| 974 | data.arch = "x86"; |
| 975 | data.variant = ".roothp"; |
| 976 | data.required_struct_types = base_required_struct_types; |
| 977 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 978 | test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off " |
| 979 | "-device pci-bridge,chassis_nr=1 " |
| 980 | "-device pci-bridge,bus=pci.1,addr=1.0,chassis_nr=2 " |
| 981 | "-device pci-testdev,bus=pci.0 " |
| 982 | "-device pci-testdev,bus=pci.1", &data); |
| 983 | free_test_data(&data); |
| 984 | } |
| 985 | |
| 986 | static void test_acpi_piix4_no_bridge_hotplug(void) |
| 987 | { |
| 988 | test_data data = {}; |
| 989 | |
| 990 | data.machine = MACHINE_PC; |
| 991 | data.arch = "x86"; |
| 992 | data.variant = ".hpbridge"; |
| 993 | data.required_struct_types = base_required_struct_types; |
| 994 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 995 | test_acpi_one("-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off " |
| 996 | "-device pci-bridge,chassis_nr=1 " |
| 997 | "-device pci-bridge,bus=pci.1,addr=1.0,chassis_nr=2 " |
| 998 | "-device pci-testdev,bus=pci.0 " |
| 999 | "-device pci-testdev,bus=pci.1,addr=2.0", &data); |
| 1000 | free_test_data(&data); |
| 1001 | } |
| 1002 | |
| 1003 | static void test_acpi_piix4_no_acpi_pci_hotplug(void) |
| 1004 | { |
| 1005 | test_data data = {}; |
| 1006 | |
| 1007 | data.machine = MACHINE_PC; |
| 1008 | data.arch = "x86"; |
| 1009 | data.variant = ".hpbrroot"; |
| 1010 | data.required_struct_types = base_required_struct_types; |
| 1011 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 1012 | test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off " |
| 1013 | "-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off " |
| 1014 | "-device pci-bridge,chassis_nr=1,addr=4.0 " |
| 1015 | "-device pci-testdev,bus=pci.0,addr=5.0 " |
| 1016 | "-device pci-testdev,bus=pci.0,addr=6.0,acpi-index=101 " |
| 1017 | "-device pci-testdev,bus=pci.1,addr=1.0 " |
| 1018 | "-device pci-testdev,bus=pci.1,addr=2.0,acpi-index=201 " |
| 1019 | "-device pci-bridge,id=nhpbr,chassis_nr=2,shpc=off,addr=7.0 " |
| 1020 | "-device pci-testdev,bus=nhpbr,addr=1.0,acpi-index=301 " |
| 1021 | , &data); |
| 1022 | free_test_data(&data); |
| 1023 | } |
| 1024 | |
| 1025 | static void test_acpi_q35_tcg(void) |
| 1026 | { |
| 1027 | test_data data = {}; |
| 1028 | |
| 1029 | data.machine = MACHINE_Q35; |
| 1030 | data.arch = "x86"; |
| 1031 | data.required_struct_types = base_required_struct_types; |
| 1032 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 1033 | test_acpi_one(NULL, &data); |
| 1034 | free_test_data(&data); |
| 1035 | |
| 1036 | data.smbios_cpu_max_speed = 3000; |
| 1037 | data.smbios_cpu_curr_speed = 2600; |
| 1038 | test_acpi_one("-smbios type=4,max-speed=3000,current-speed=2600", &data); |
| 1039 | free_test_data(&data); |
| 1040 | } |
| 1041 | |
| 1042 | static void test_acpi_q35_kvm_type4_count(void) |
| 1043 | { |
| 1044 | test_data data = { |
| 1045 | .machine = MACHINE_Q35, |
| 1046 | .arch = "x86", |
| 1047 | .variant = ".type4-count", |
| 1048 | .required_struct_types = base_required_struct_types, |
| 1049 | .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), |
| 1050 | .type4_count = 5, |
| 1051 | }; |
| 1052 | |
| 1053 | test_acpi_one("-machine smbios-entry-point-type=64 " |
| 1054 | "-smp cpus=100,maxcpus=120,sockets=5," |
| 1055 | "dies=2,cores=4,threads=3", &data); |
| 1056 | free_test_data(&data); |
| 1057 | } |
| 1058 | |
| 1059 | static void test_acpi_q35_kvm_core_count(void) |
| 1060 | { |
| 1061 | test_data data = { |
| 1062 | .machine = MACHINE_Q35, |
| 1063 | .arch = "x86", |
| 1064 | .variant = ".core-count", |
| 1065 | .required_struct_types = base_required_struct_types, |
| 1066 | .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), |
| 1067 | .smbios_core_count = 9, |
| 1068 | .smbios_core_count2 = 9, |
| 1069 | }; |
| 1070 | |
| 1071 | test_acpi_one("-machine smbios-entry-point-type=64 " |
| 1072 | "-smp 54,sockets=2,dies=3,cores=3,threads=3", |
| 1073 | &data); |
| 1074 | free_test_data(&data); |
| 1075 | } |
| 1076 | |
| 1077 | static void test_acpi_q35_kvm_core_count2(void) |
| 1078 | { |
| 1079 | test_data data = { |
| 1080 | .machine = MACHINE_Q35, |
| 1081 | .arch = "x86", |
| 1082 | .variant = ".core-count2", |
| 1083 | .required_struct_types = base_required_struct_types, |
| 1084 | .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), |
| 1085 | .smbios_core_count = 0xFF, |
| 1086 | .smbios_core_count2 = 260, |
| 1087 | }; |
| 1088 | |
| 1089 | test_acpi_one("-machine smbios-entry-point-type=64 " |
| 1090 | "-smp 260,dies=2,cores=130,threads=1", |
| 1091 | &data); |
| 1092 | free_test_data(&data); |
| 1093 | } |
| 1094 | |
| 1095 | static void test_acpi_q35_kvm_thread_count(void) |
| 1096 | { |
| 1097 | test_data data = { |
| 1098 | .machine = MACHINE_Q35, |
| 1099 | .arch = "x86", |
| 1100 | .variant = ".thread-count", |
| 1101 | .required_struct_types = base_required_struct_types, |
| 1102 | .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), |
| 1103 | .smbios_thread_count = 27, |
| 1104 | .smbios_thread_count2 = 27, |
| 1105 | }; |
| 1106 | |
| 1107 | test_acpi_one("-machine smbios-entry-point-type=64 " |
| 1108 | "-smp cpus=15,maxcpus=54,sockets=2,dies=3,cores=3,threads=3", |
| 1109 | &data); |
| 1110 | free_test_data(&data); |
| 1111 | } |
| 1112 | |
| 1113 | static void test_acpi_q35_kvm_thread_count2(void) |
| 1114 | { |
| 1115 | test_data data = { |
| 1116 | .machine = MACHINE_Q35, |
| 1117 | .arch = "x86", |
| 1118 | .variant = ".thread-count2", |
| 1119 | .required_struct_types = base_required_struct_types, |
| 1120 | .required_struct_types_len = ARRAY_SIZE(base_required_struct_types), |
| 1121 | .smbios_thread_count = 0xFF, |
| 1122 | .smbios_thread_count2 = 260, |
| 1123 | }; |
| 1124 | |
| 1125 | test_acpi_one("-machine smbios-entry-point-type=64 " |
| 1126 | "-smp cpus=210,maxcpus=260,dies=2,cores=65,threads=2", |
| 1127 | &data); |
| 1128 | free_test_data(&data); |
| 1129 | } |
| 1130 | |
| 1131 | static void test_acpi_q35_tcg_bridge(void) |
| 1132 | { |
| 1133 | test_data data = {}; |
| 1134 | |
| 1135 | data.machine = MACHINE_Q35; |
| 1136 | data.arch = "x86", |
| 1137 | data.variant = ".bridge"; |
| 1138 | data.required_struct_types = base_required_struct_types; |
| 1139 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 1140 | test_acpi_one("-device pci-bridge,chassis_nr=1,id=br1" |
| 1141 | " -device pci-testdev,bus=pcie.0" |
| 1142 | " -device pci-testdev,bus=br1", &data); |
| 1143 | free_test_data(&data); |
| 1144 | } |
| 1145 | |
| 1146 | static void test_acpi_q35_tcg_no_acpi_hotplug(void) |
| 1147 | { |
| 1148 | test_data data = {}; |
| 1149 | |
| 1150 | data.machine = MACHINE_Q35; |
| 1151 | data.arch = "x86", |
| 1152 | data.variant = ".noacpihp"; |
| 1153 | data.required_struct_types = base_required_struct_types; |
| 1154 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 1155 | test_acpi_one("-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off" |
| 1156 | " -device pci-testdev,bus=pcie.0,acpi-index=101,addr=3.0" |
| 1157 | " -device pci-bridge,chassis_nr=1,id=shpcbr,addr=4.0" |
| 1158 | " -device pci-testdev,bus=shpcbr,addr=1.0,acpi-index=201" |
| 1159 | " -device pci-bridge,chassis_nr=2,shpc=off,id=noshpcbr,addr=5.0" |
| 1160 | " -device pci-testdev,bus=noshpcbr,addr=1.0,acpi-index=301" |
| 1161 | " -device pcie-root-port,id=hprp,port=0x0,chassis=1,addr=6.0" |
| 1162 | " -device pci-testdev,bus=hprp,acpi-index=401" |
| 1163 | " -device pcie-root-port,id=nohprp,port=0x0,chassis=2,hotplug=off," |
| 1164 | "addr=7.0" |
| 1165 | " -device pci-testdev,bus=nohprp,acpi-index=501" |
| 1166 | " -device pcie-root-port,id=nohprpint,port=0x0,chassis=3,hotplug=off," |
| 1167 | "multifunction=on,addr=8.0" |
| 1168 | " -device pci-testdev,bus=nohprpint,acpi-index=601,addr=0.1" |
| 1169 | " -device pcie-root-port,id=hprp2,port=0x0,chassis=4,bus=nohprpint," |
| 1170 | "addr=0.2" |
| 1171 | " -device pci-testdev,bus=hprp2,acpi-index=602" |
| 1172 | , &data); |
| 1173 | free_test_data(&data); |
| 1174 | } |
| 1175 | |
| 1176 | static void test_acpi_q35_multif_bridge(void) |
| 1177 | { |
| 1178 | test_data data = { |
| 1179 | .machine = MACHINE_Q35, |
| 1180 | .arch = "x86", |
| 1181 | .variant = ".multi-bridge", |
| 1182 | }; |
| 1183 | test_vm_prepare("-S" |
| 1184 | " -device virtio-balloon,id=balloon0,addr=0x4.0x2" |
| 1185 | " -device pcie-root-port,id=rp0,multifunction=on," |
| 1186 | "port=0x0,chassis=1,addr=0x2" |
| 1187 | " -device pcie-root-port,id=rp1,port=0x1,chassis=2,addr=0x3.0x1" |
| 1188 | " -device pcie-root-port,id=rp2,port=0x0,chassis=3,bus=rp1,addr=0.0" |
| 1189 | " -device pci-bridge,bus=rp2,chassis_nr=4,id=br1" |
| 1190 | " -device pcie-root-port,id=rphptgt1,port=0x0,chassis=5,addr=2.1" |
| 1191 | " -device pcie-root-port,id=rphptgt2,port=0x0,chassis=6,addr=2.2" |
| 1192 | " -device pcie-root-port,id=rphptgt3,port=0x0,chassis=7,addr=2.3" |
| 1193 | " -device pci-testdev,bus=pcie.0,addr=2.4" |
| 1194 | " -device pci-testdev,bus=pcie.0,addr=2.5,acpi-index=102" |
| 1195 | " -device pci-testdev,bus=pcie.0,addr=5.0" |
| 1196 | " -device pci-testdev,bus=pcie.0,addr=0xf.0,acpi-index=101" |
| 1197 | " -device pci-testdev,bus=rp0,addr=0.0" |
| 1198 | " -device pci-testdev,bus=br1" |
| 1199 | " -device pcie-root-port,id=rpnohp,chassis=8,addr=0xA.0,hotplug=off" |
| 1200 | " -device pcie-root-port,id=rp3,chassis=9,bus=rpnohp" |
| 1201 | , &data); |
| 1202 | |
| 1203 | /* hotplugged bridges section */ |
| 1204 | qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr1", |
| 1205 | "{'bus': 'br1', 'addr': '6.0', 'chassis_nr': 128 }"); |
| 1206 | qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr2-multiif", |
| 1207 | "{ 'bus': 'br1', 'addr': '2.2', 'chassis_nr': 129 }"); |
| 1208 | qtest_qmp_device_add(data.qts, "pcie-pci-bridge", "hpbr3", |
| 1209 | "{'bus': 'rphptgt1', 'addr': '0.0' }"); |
| 1210 | qtest_qmp_device_add(data.qts, "pcie-root-port", "hprp", |
| 1211 | "{'bus': 'rphptgt2', 'addr': '0.0' }"); |
| 1212 | qtest_qmp_device_add(data.qts, "pci-testdev", "hpnic", |
| 1213 | "{'bus': 'rphptgt3', 'addr': '0.0' }"); |
| 1214 | qtest_qmp_send(data.qts, "{'execute':'cont' }"); |
| 1215 | qtest_qmp_eventwait(data.qts, "RESUME"); |
| 1216 | |
| 1217 | process_acpi_tables_noexit(&data); |
| 1218 | free_test_data(&data); |
| 1219 | |
| 1220 | /* check that reboot/reset doesn't change any ACPI tables */ |
| 1221 | qtest_system_reset(data.qts); |
| 1222 | process_acpi_tables(&data); |
| 1223 | free_test_data(&data); |
| 1224 | } |
| 1225 | |
| 1226 | static void test_acpi_q35_tcg_mmio64(void) |
| 1227 | { |
| 1228 | test_data data = { |
| 1229 | .machine = MACHINE_Q35, |
| 1230 | .arch = "x86", |
| 1231 | .variant = ".mmio64", |
| 1232 | .tcg_only = true, |
| 1233 | .required_struct_types = base_required_struct_types, |
| 1234 | .required_struct_types_len = ARRAY_SIZE(base_required_struct_types) |
| 1235 | }; |
| 1236 | |
| 1237 | test_acpi_one("-m 128M,slots=1,maxmem=2G " |
| 1238 | "-cpu Opteron_G1 " |
| 1239 | "-object memory-backend-ram,id=ram0,size=128M " |
| 1240 | "-numa node,memdev=ram0 " |
| 1241 | "-device pci-testdev,membar=2G", |
| 1242 | &data); |
| 1243 | free_test_data(&data); |
| 1244 | } |
| 1245 | |
| 1246 | static void test_acpi_piix4_tcg_cphp(void) |
| 1247 | { |
| 1248 | test_data data = {}; |
| 1249 | |
| 1250 | data.machine = MACHINE_PC; |
| 1251 | data.arch = "x86"; |
| 1252 | data.variant = ".cphp"; |
| 1253 | test_acpi_one("-smp 2,cores=3,sockets=2,maxcpus=6" |
| 1254 | " -object memory-backend-ram,id=ram0,size=64M" |
| 1255 | " -object memory-backend-ram,id=ram1,size=64M" |
| 1256 | " -numa node,memdev=ram0 -numa node,memdev=ram1" |
| 1257 | " -numa dist,src=0,dst=1,val=21", |
| 1258 | &data); |
| 1259 | free_test_data(&data); |
| 1260 | } |
| 1261 | |
| 1262 | static void test_acpi_q35_tcg_cphp(void) |
| 1263 | { |
| 1264 | test_data data = {}; |
| 1265 | |
| 1266 | data.machine = MACHINE_Q35; |
| 1267 | data.arch = "x86", |
| 1268 | data.variant = ".cphp"; |
| 1269 | test_acpi_one(" -smp 2,cores=3,sockets=2,maxcpus=6" |
| 1270 | " -object memory-backend-ram,id=ram0,size=64M" |
| 1271 | " -object memory-backend-ram,id=ram1,size=64M" |
| 1272 | " -numa node,memdev=ram0 -numa node,memdev=ram1" |
| 1273 | " -numa dist,src=0,dst=1,val=21", |
| 1274 | &data); |
| 1275 | free_test_data(&data); |
| 1276 | } |
| 1277 | |
| 1278 | static uint8_t ipmi_required_struct_types[] = { |
| 1279 | 0, 1, 3, 4, 16, 17, 19, 32, 38, 127 |
| 1280 | }; |
| 1281 | |
| 1282 | static void test_acpi_q35_tcg_ipmi(void) |
| 1283 | { |
| 1284 | test_data data = {}; |
| 1285 | |
| 1286 | data.machine = MACHINE_Q35; |
| 1287 | data.arch = "x86", |
| 1288 | data.variant = ".ipmibt"; |
| 1289 | data.required_struct_types = ipmi_required_struct_types; |
| 1290 | data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types); |
| 1291 | test_acpi_one("-device ipmi-bmc-sim,id=bmc0" |
| 1292 | " -device isa-ipmi-bt,bmc=bmc0", |
| 1293 | &data); |
| 1294 | free_test_data(&data); |
| 1295 | } |
| 1296 | |
| 1297 | static void test_acpi_q35_tcg_smbus_ipmi(void) |
| 1298 | { |
| 1299 | test_data data = {}; |
| 1300 | |
| 1301 | data.machine = MACHINE_Q35; |
| 1302 | data.arch = "x86", |
| 1303 | data.variant = ".ipmismbus"; |
| 1304 | data.required_struct_types = ipmi_required_struct_types; |
| 1305 | data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types); |
| 1306 | test_acpi_one("-device ipmi-bmc-sim,id=bmc0" |
| 1307 | " -device smbus-ipmi,bmc=bmc0", |
| 1308 | &data); |
| 1309 | free_test_data(&data); |
| 1310 | } |
| 1311 | |
| 1312 | static void test_acpi_piix4_tcg_ipmi(void) |
| 1313 | { |
| 1314 | test_data data = {}; |
| 1315 | |
| 1316 | /* Supplying -machine accel argument overrides the default (qtest). |
| 1317 | * This is to make guest actually run. |
| 1318 | */ |
| 1319 | data.machine = MACHINE_PC; |
| 1320 | data.arch = "x86"; |
| 1321 | data.variant = ".ipmikcs"; |
| 1322 | data.required_struct_types = ipmi_required_struct_types; |
| 1323 | data.required_struct_types_len = ARRAY_SIZE(ipmi_required_struct_types); |
| 1324 | test_acpi_one("-device ipmi-bmc-sim,id=bmc0" |
| 1325 | " -device isa-ipmi-kcs,irq=0,bmc=bmc0", |
| 1326 | &data); |
| 1327 | free_test_data(&data); |
| 1328 | } |
| 1329 | |
| 1330 | static void test_acpi_q35_tcg_memhp(void) |
| 1331 | { |
| 1332 | test_data data = {}; |
| 1333 | |
| 1334 | data.machine = MACHINE_Q35; |
| 1335 | data.arch = "x86", |
| 1336 | data.variant = ".memhp"; |
| 1337 | test_acpi_one(" -m 128,slots=3,maxmem=1G" |
| 1338 | " -object memory-backend-ram,id=ram0,size=64M" |
| 1339 | " -object memory-backend-ram,id=ram1,size=64M" |
| 1340 | " -numa node,memdev=ram0 -numa node,memdev=ram1" |
| 1341 | " -numa dist,src=0,dst=1,val=21", |
| 1342 | &data); |
| 1343 | free_test_data(&data); |
| 1344 | } |
| 1345 | |
| 1346 | static void test_acpi_piix4_tcg_memhp(void) |
| 1347 | { |
| 1348 | test_data data = {}; |
| 1349 | |
| 1350 | data.machine = MACHINE_PC; |
| 1351 | data.arch = "x86"; |
| 1352 | data.variant = ".memhp"; |
| 1353 | test_acpi_one(" -m 128,slots=3,maxmem=1G" |
| 1354 | " -object memory-backend-ram,id=ram0,size=64M" |
| 1355 | " -object memory-backend-ram,id=ram1,size=64M" |
| 1356 | " -numa node,memdev=ram0 -numa node,memdev=ram1" |
| 1357 | " -numa dist,src=0,dst=1,val=21", |
| 1358 | &data); |
| 1359 | free_test_data(&data); |
| 1360 | } |
| 1361 | |
| 1362 | static void test_acpi_piix4_tcg_nosmm(void) |
| 1363 | { |
| 1364 | test_data data = {}; |
| 1365 | |
| 1366 | data.machine = MACHINE_PC; |
| 1367 | data.arch = "x86"; |
| 1368 | data.variant = ".nosmm"; |
| 1369 | test_acpi_one("-machine smm=off", &data); |
| 1370 | free_test_data(&data); |
| 1371 | } |
| 1372 | |
| 1373 | static void test_acpi_piix4_tcg_smm_compat(void) |
| 1374 | { |
| 1375 | test_data data = {}; |
| 1376 | |
| 1377 | data.machine = MACHINE_PC; |
| 1378 | data.arch = "x86"; |
| 1379 | data.variant = ".smm-compat"; |
| 1380 | test_acpi_one("-global PIIX4_PM.smm-compat=on", &data); |
| 1381 | free_test_data(&data); |
| 1382 | } |
| 1383 | |
| 1384 | static void test_acpi_piix4_tcg_smm_compat_nosmm(void) |
| 1385 | { |
| 1386 | test_data data = {}; |
| 1387 | |
| 1388 | data.machine = MACHINE_PC; |
| 1389 | data.arch = "x86"; |
| 1390 | data.variant = ".smm-compat-nosmm"; |
| 1391 | test_acpi_one("-global PIIX4_PM.smm-compat=on -machine smm=off", &data); |
| 1392 | free_test_data(&data); |
| 1393 | } |
| 1394 | |
| 1395 | static void test_acpi_piix4_tcg_nohpet(void) |
| 1396 | { |
| 1397 | test_data data = {}; |
| 1398 | |
| 1399 | data.machine = MACHINE_PC; |
| 1400 | data.arch = "x86"; |
| 1401 | data.machine_param = ",hpet=off"; |
| 1402 | data.variant = ".nohpet"; |
| 1403 | test_acpi_one(NULL, &data); |
| 1404 | free_test_data(&data); |
| 1405 | } |
| 1406 | |
| 1407 | static void test_acpi_q35_tcg_numamem(void) |
| 1408 | { |
| 1409 | test_data data = {}; |
| 1410 | |
| 1411 | data.machine = MACHINE_Q35; |
| 1412 | data.arch = "x86", |
| 1413 | data.variant = ".numamem"; |
| 1414 | test_acpi_one(" -object memory-backend-ram,id=ram0,size=128M" |
| 1415 | " -numa node -numa node,memdev=ram0", &data); |
| 1416 | free_test_data(&data); |
| 1417 | } |
| 1418 | |
| 1419 | static void test_acpi_q35_tcg_sp_mem(void) |
| 1420 | { |
| 1421 | test_data data = {}; |
| 1422 | |
| 1423 | data.machine = MACHINE_Q35; |
| 1424 | data.arch = "x86", |
| 1425 | data.variant = ".spmem"; |
| 1426 | test_acpi_one(" -m 128M,slots=4,maxmem=1G" |
| 1427 | " -object memory-backend-ram,id=ram0,size=128M" |
| 1428 | " -numa node,nodeid=0,memdev=ram0" |
| 1429 | " -numa node,nodeid=1" |
| 1430 | " -numa node,nodeid=2" |
| 1431 | " -object memory-backend-ram,id=spm0,size=128M" |
| 1432 | " -object memory-backend-ram,id=spm1,size=128M" |
| 1433 | " -device sp-mem,id=sp0,memdev=spm0,node=1" |
| 1434 | " -device sp-mem,id=sp1,memdev=spm1,node=2", |
| 1435 | &data); |
| 1436 | free_test_data(&data); |
| 1437 | } |
| 1438 | |
| 1439 | static void test_acpi_q35_kvm_xapic(void) |
| 1440 | { |
| 1441 | test_data data = {}; |
| 1442 | |
| 1443 | data.machine = MACHINE_Q35; |
| 1444 | data.arch = "x86", |
| 1445 | data.variant = ".xapic"; |
| 1446 | test_acpi_one(" -object memory-backend-ram,id=ram0,size=128M" |
| 1447 | " -numa node -numa node,memdev=ram0" |
| 1448 | " -machine kernel-irqchip=on -smp 1,maxcpus=288", &data); |
| 1449 | free_test_data(&data); |
| 1450 | } |
| 1451 | |
| 1452 | static void test_acpi_q35_tcg_nosmm(void) |
| 1453 | { |
| 1454 | test_data data = {}; |
| 1455 | |
| 1456 | data.machine = MACHINE_Q35; |
| 1457 | data.arch = "x86", |
| 1458 | data.variant = ".nosmm"; |
| 1459 | test_acpi_one("-machine smm=off", &data); |
| 1460 | free_test_data(&data); |
| 1461 | } |
| 1462 | |
| 1463 | static void test_acpi_q35_tcg_smm_compat(void) |
| 1464 | { |
| 1465 | test_data data = {}; |
| 1466 | |
| 1467 | data.machine = MACHINE_Q35; |
| 1468 | data.arch = "x86", |
| 1469 | data.variant = ".smm-compat"; |
| 1470 | test_acpi_one("-global ICH9-LPC.smm-compat=on", &data); |
| 1471 | free_test_data(&data); |
| 1472 | } |
| 1473 | |
| 1474 | static void test_acpi_q35_tcg_smm_compat_nosmm(void) |
| 1475 | { |
| 1476 | test_data data = {}; |
| 1477 | |
| 1478 | data.machine = MACHINE_Q35; |
| 1479 | data.arch = "x86", |
| 1480 | data.variant = ".smm-compat-nosmm"; |
| 1481 | test_acpi_one("-global ICH9-LPC.smm-compat=on -machine smm=off", &data); |
| 1482 | free_test_data(&data); |
| 1483 | } |
| 1484 | |
| 1485 | static void test_acpi_q35_tcg_nohpet(void) |
| 1486 | { |
| 1487 | test_data data = {}; |
| 1488 | |
| 1489 | data.machine = MACHINE_Q35; |
| 1490 | data.arch = "x86", |
| 1491 | data.machine_param = ",hpet=off"; |
| 1492 | data.variant = ".nohpet"; |
| 1493 | test_acpi_one(NULL, &data); |
| 1494 | free_test_data(&data); |
| 1495 | } |
| 1496 | |
| 1497 | static void test_acpi_q35_kvm_dmar(void) |
| 1498 | { |
| 1499 | test_data data = {}; |
| 1500 | |
| 1501 | data.machine = MACHINE_Q35; |
| 1502 | data.arch = "x86", |
| 1503 | data.variant = ".dmar"; |
| 1504 | test_acpi_one("-machine kernel-irqchip=split -accel kvm" |
| 1505 | " -device intel-iommu,intremap=on,device-iotlb=on", &data); |
| 1506 | free_test_data(&data); |
| 1507 | } |
| 1508 | |
| 1509 | static void test_acpi_q35_tcg_ivrs(void) |
| 1510 | { |
| 1511 | test_data data = {}; |
| 1512 | |
| 1513 | data.machine = MACHINE_Q35; |
| 1514 | data.arch = "x86", |
| 1515 | data.variant = ".ivrs"; |
| 1516 | data.tcg_only = true, |
| 1517 | test_acpi_one(" -device amd-iommu", &data); |
| 1518 | free_test_data(&data); |
| 1519 | } |
| 1520 | |
| 1521 | static void test_acpi_piix4_tcg_numamem(void) |
| 1522 | { |
| 1523 | test_data data = {}; |
| 1524 | |
| 1525 | data.machine = MACHINE_PC; |
| 1526 | data.arch = "x86"; |
| 1527 | data.variant = ".numamem"; |
| 1528 | test_acpi_one(" -object memory-backend-ram,id=ram0,size=128M" |
| 1529 | " -numa node -numa node,memdev=ram0", &data); |
| 1530 | free_test_data(&data); |
| 1531 | } |
| 1532 | |
| 1533 | uint64_t tpm_tis_base_addr; |
| 1534 | |
| 1535 | static void test_acpi_tcg_tpm(const char *machine, const char *arch, |
| 1536 | const char *tpm_if, uint64_t base, |
| 1537 | enum TPMVersion tpm_version) |
| 1538 | { |
| 1539 | gchar *tmp_dir_name = g_strdup_printf("qemu-test_acpi_%s_tcg_%s.XXXXXX", |
| 1540 | machine, tpm_if); |
| 1541 | char *tmp_path = g_dir_make_tmp(tmp_dir_name, NULL); |
| 1542 | TPMTestState test; |
| 1543 | test_data data = {}; |
| 1544 | GThread *thread; |
| 1545 | const char *suffix = tpm_version == TPM_VERSION_2_0 ? "tpm2" : "tpm12"; |
| 1546 | char *args, *variant = g_strdup_printf(".%s.%s", tpm_if, suffix); |
| 1547 | |
| 1548 | tpm_tis_base_addr = base; |
| 1549 | |
| 1550 | module_call_init(MODULE_INIT_QOM); |
| 1551 | |
| 1552 | test.addr = g_new0(SocketAddress, 1); |
| 1553 | test.addr->type = SOCKET_ADDRESS_TYPE_UNIX; |
| 1554 | test.addr->u.q_unix.path = g_build_filename(tmp_path, "sock", NULL); |
| 1555 | g_mutex_init(&test.data_mutex); |
| 1556 | g_cond_init(&test.data_cond); |
| 1557 | test.data_cond_signal = false; |
| 1558 | test.tpm_version = tpm_version; |
| 1559 | |
| 1560 | thread = g_thread_new(NULL, tpm_emu_ctrl_thread, &test); |
| 1561 | tpm_emu_test_wait_cond(&test); |
| 1562 | |
| 1563 | data.machine = machine; |
| 1564 | data.arch = arch; |
| 1565 | data.variant = variant; |
| 1566 | |
| 1567 | args = g_strdup_printf( |
| 1568 | " -chardev socket,id=chr,path=%s" |
| 1569 | " -tpmdev emulator,id=dev,chardev=chr" |
| 1570 | " -device tpm-%s,tpmdev=dev", |
| 1571 | test.addr->u.q_unix.path, tpm_if); |
| 1572 | |
| 1573 | test_acpi_one(args, &data); |
| 1574 | |
| 1575 | g_thread_join(thread); |
| 1576 | g_unlink(test.addr->u.q_unix.path); |
| 1577 | qapi_free_SocketAddress(test.addr); |
| 1578 | g_rmdir(tmp_path); |
| 1579 | g_free(variant); |
| 1580 | g_free(tmp_path); |
| 1581 | g_free(tmp_dir_name); |
| 1582 | g_free(args); |
| 1583 | free_test_data(&data); |
| 1584 | } |
| 1585 | |
| 1586 | static void test_acpi_q35_tcg_tpm2_tis(void) |
| 1587 | { |
| 1588 | test_acpi_tcg_tpm("q35", "x86", "tis", 0xFED40000, TPM_VERSION_2_0); |
| 1589 | } |
| 1590 | |
| 1591 | static void test_acpi_q35_tcg_tpm12_tis(void) |
| 1592 | { |
| 1593 | test_acpi_tcg_tpm("q35", "x86", "tis", 0xFED40000, TPM_VERSION_1_2); |
| 1594 | } |
| 1595 | |
| 1596 | static void test_acpi_tcg_dimm_pxm(const char *machine, const char *arch) |
| 1597 | { |
| 1598 | test_data data = {}; |
| 1599 | |
| 1600 | data.machine = machine; |
| 1601 | data.arch = arch; |
| 1602 | data.variant = ".dimmpxm"; |
| 1603 | test_acpi_one(" -machine nvdimm=on,nvdimm-persistence=cpu" |
| 1604 | " -smp 4,sockets=4" |
| 1605 | " -m 128M,slots=3,maxmem=1G" |
| 1606 | " -object memory-backend-ram,id=ram0,size=32M" |
| 1607 | " -object memory-backend-ram,id=ram1,size=32M" |
| 1608 | " -object memory-backend-ram,id=ram2,size=32M" |
| 1609 | " -object memory-backend-ram,id=ram3,size=32M" |
| 1610 | " -numa node,memdev=ram0,nodeid=0" |
| 1611 | " -numa node,memdev=ram1,nodeid=1" |
| 1612 | " -numa node,memdev=ram2,nodeid=2" |
| 1613 | " -numa node,memdev=ram3,nodeid=3" |
| 1614 | " -numa cpu,node-id=0,socket-id=0" |
| 1615 | " -numa cpu,node-id=1,socket-id=1" |
| 1616 | " -numa cpu,node-id=2,socket-id=2" |
| 1617 | " -numa cpu,node-id=3,socket-id=3" |
| 1618 | " -object memory-backend-ram,id=ram4,size=128M" |
| 1619 | " -object memory-backend-ram,id=nvm0,size=128M" |
| 1620 | " -device pc-dimm,id=dimm0,memdev=ram4,node=1" |
| 1621 | " -device nvdimm,id=dimm1,memdev=nvm0,node=2", |
| 1622 | &data); |
| 1623 | free_test_data(&data); |
| 1624 | } |
| 1625 | |
| 1626 | static void test_acpi_q35_tcg_dimm_pxm(void) |
| 1627 | { |
| 1628 | test_acpi_tcg_dimm_pxm(MACHINE_Q35, "x86"); |
| 1629 | } |
| 1630 | |
| 1631 | static void test_acpi_piix4_tcg_dimm_pxm(void) |
| 1632 | { |
| 1633 | test_acpi_tcg_dimm_pxm(MACHINE_PC, "x86"); |
| 1634 | } |
| 1635 | |
| 1636 | static void test_acpi_aarch64_virt_tcg_memhp(void) |
| 1637 | { |
| 1638 | test_data data = { |
| 1639 | .machine = "virt", |
| 1640 | .arch = "aarch64", |
| 1641 | .tcg_only = true, |
| 1642 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1643 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1644 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 1645 | .ram_start = 0x40000000ULL, |
| 1646 | .scan_len = 256ULL * MiB, |
| 1647 | }; |
| 1648 | |
| 1649 | data.variant = ".memhp"; |
| 1650 | test_acpi_one(" -machine nvdimm=on" |
| 1651 | " -cpu cortex-a57" |
| 1652 | " -m 256M,slots=3,maxmem=1G" |
| 1653 | " -object memory-backend-ram,id=ram0,size=128M" |
| 1654 | " -object memory-backend-ram,id=ram1,size=128M" |
| 1655 | " -numa node,memdev=ram0 -numa node,memdev=ram1" |
| 1656 | " -numa dist,src=0,dst=1,val=21" |
| 1657 | " -object memory-backend-ram,id=ram2,size=128M" |
| 1658 | " -object memory-backend-ram,id=nvm0,size=128M" |
| 1659 | " -device pc-dimm,id=dimm0,memdev=ram2,node=0" |
| 1660 | " -device nvdimm,id=dimm1,memdev=nvm0,node=1", |
| 1661 | &data); |
| 1662 | |
| 1663 | free_test_data(&data); |
| 1664 | |
| 1665 | } |
| 1666 | |
| 1667 | static void test_acpi_aarch64_virt_acpi_pci_hotplug(void) |
| 1668 | { |
| 1669 | test_data data = { |
| 1670 | .machine = "virt", |
| 1671 | .arch = "aarch64", |
| 1672 | .tcg_only = true, |
| 1673 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1674 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1675 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 1676 | .ram_start = 0x40000000ULL, |
| 1677 | .scan_len = 256ULL * MiB, |
| 1678 | .variant = ".acpipcihp", |
| 1679 | }; |
| 1680 | |
| 1681 | /* Use ACPI PCI Hotplug */ |
| 1682 | test_acpi_one(" -global acpi-ged.acpi-pci-hotplug-with-bridge-support=on" |
| 1683 | " -cpu cortex-a57" |
| 1684 | " -device pcie-root-port,id=pcie.1,bus=pcie.0,chassis=0,slot=1,addr=7.0" |
| 1685 | " -device pci-testdev,bus=pcie.1", |
| 1686 | &data); |
| 1687 | |
| 1688 | free_test_data(&data); |
| 1689 | } |
| 1690 | |
| 1691 | static void test_acpi_aarch64_virt_pcie_root_port_hpoff(void) |
| 1692 | { |
| 1693 | test_data data = { |
| 1694 | .machine = "virt", |
| 1695 | .arch = "aarch64", |
| 1696 | .tcg_only = true, |
| 1697 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1698 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1699 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 1700 | .ram_start = 0x40000000ULL, |
| 1701 | .scan_len = 256ULL * MiB, |
| 1702 | .variant = ".hpoffacpiindex", |
| 1703 | }; |
| 1704 | |
| 1705 | /* turn hotplug off on the pcie-root-port and use static acpi-index*/ |
| 1706 | test_acpi_one(" -device pcie-root-port,id=pcie.1,chassis=0," |
| 1707 | "slot=1,hotplug=off,addr=7.0" |
| 1708 | " -device pci-testdev,bus=pcie.1,acpi-index=12" |
| 1709 | " -cpu cortex-a57", |
| 1710 | &data); |
| 1711 | |
| 1712 | free_test_data(&data); |
| 1713 | } |
| 1714 | |
| 1715 | static void test_acpi_microvm_prepare(test_data *data) |
| 1716 | { |
| 1717 | data->machine = "microvm"; |
| 1718 | data->arch = "x86"; |
| 1719 | data->required_struct_types = NULL; /* no smbios */ |
| 1720 | data->required_struct_types_len = 0; |
| 1721 | data->blkdev = "virtio-blk-device"; |
| 1722 | } |
| 1723 | |
| 1724 | static void test_acpi_microvm_tcg(void) |
| 1725 | { |
| 1726 | test_data data = {}; |
| 1727 | |
| 1728 | test_acpi_microvm_prepare(&data); |
| 1729 | test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=off", |
| 1730 | &data); |
| 1731 | free_test_data(&data); |
| 1732 | } |
| 1733 | |
| 1734 | static void test_acpi_microvm_usb_tcg(void) |
| 1735 | { |
| 1736 | test_data data = {}; |
| 1737 | |
| 1738 | test_acpi_microvm_prepare(&data); |
| 1739 | data.variant = ".usb"; |
| 1740 | test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,usb=on,rtc=off", |
| 1741 | &data); |
| 1742 | free_test_data(&data); |
| 1743 | } |
| 1744 | |
| 1745 | static void test_acpi_microvm_rtc_tcg(void) |
| 1746 | { |
| 1747 | test_data data = {}; |
| 1748 | |
| 1749 | test_acpi_microvm_prepare(&data); |
| 1750 | data.variant = ".rtc"; |
| 1751 | test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=on", |
| 1752 | &data); |
| 1753 | free_test_data(&data); |
| 1754 | } |
| 1755 | |
| 1756 | static void test_acpi_microvm_pcie_tcg(void) |
| 1757 | { |
| 1758 | test_data data = {}; |
| 1759 | |
| 1760 | test_acpi_microvm_prepare(&data); |
| 1761 | data.variant = ".pcie"; |
| 1762 | data.tcg_only = true; /* need constant host-phys-bits */ |
| 1763 | test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=off,pcie=on", |
| 1764 | &data); |
| 1765 | free_test_data(&data); |
| 1766 | } |
| 1767 | |
| 1768 | static void test_acpi_microvm_ioapic2_tcg(void) |
| 1769 | { |
| 1770 | test_data data = {}; |
| 1771 | |
| 1772 | test_acpi_microvm_prepare(&data); |
| 1773 | data.variant = ".ioapic2"; |
| 1774 | test_acpi_one(" -machine microvm,acpi=on,ioapic2=on,rtc=off", |
| 1775 | &data); |
| 1776 | free_test_data(&data); |
| 1777 | } |
| 1778 | |
| 1779 | static void test_acpi_riscv64_virt_tcg_numamem(void) |
| 1780 | { |
| 1781 | test_data data = { |
| 1782 | .machine = "virt", |
| 1783 | .arch = "riscv64", |
| 1784 | .tcg_only = true, |
| 1785 | .uefi_fl1 = "pc-bios/edk2-riscv64-code.fd", |
| 1786 | .uefi_fl2 = "pc-bios/edk2-riscv64-vars.fd", |
| 1787 | .cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2", |
| 1788 | .ram_start = 0x80000000ULL, |
| 1789 | .scan_len = 128ULL * MiB, |
| 1790 | }; |
| 1791 | |
| 1792 | data.variant = ".numamem"; |
| 1793 | /* |
| 1794 | * RHCT will have ISA string encoded. To reduce the effort |
| 1795 | * of updating expected AML file for any new default ISA extension, |
| 1796 | * use the profile rva22s64. |
| 1797 | */ |
| 1798 | test_acpi_one(" -cpu rva22s64" |
| 1799 | " -object memory-backend-ram,id=ram0,size=128M" |
| 1800 | " -numa node,memdev=ram0", |
| 1801 | &data); |
| 1802 | free_test_data(&data); |
| 1803 | } |
| 1804 | |
| 1805 | static void test_acpi_aarch64_virt_tcg_numamem(void) |
| 1806 | { |
| 1807 | test_data data = { |
| 1808 | .machine = "virt", |
| 1809 | .arch = "aarch64", |
| 1810 | .tcg_only = true, |
| 1811 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1812 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1813 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 1814 | .ram_start = 0x40000000ULL, |
| 1815 | .scan_len = 128ULL * MiB, |
| 1816 | }; |
| 1817 | |
| 1818 | data.variant = ".numamem"; |
| 1819 | test_acpi_one(" -cpu cortex-a57" |
| 1820 | " -object memory-backend-ram,id=ram0,size=128M" |
| 1821 | " -numa node,memdev=ram0", |
| 1822 | &data); |
| 1823 | |
| 1824 | free_test_data(&data); |
| 1825 | |
| 1826 | } |
| 1827 | |
| 1828 | static void test_acpi_aarch64_virt_tcg_pxb(void) |
| 1829 | { |
| 1830 | test_data data = { |
| 1831 | .machine = "virt", |
| 1832 | .arch = "aarch64", |
| 1833 | .tcg_only = true, |
| 1834 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1835 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1836 | .ram_start = 0x40000000ULL, |
| 1837 | .scan_len = 128ULL * MiB, |
| 1838 | }; |
| 1839 | /* |
| 1840 | * While using -cdrom, the cdrom would auto plugged into pxb-pcie, |
| 1841 | * the reason is the bus of pxb-pcie is also root bus, it would lead |
| 1842 | * to the error only PCI/PCIE bridge could plug onto pxb. |
| 1843 | * Therefore,thr cdrom is defined and plugged onto the scsi controller |
| 1844 | * to solve the conflicts. |
| 1845 | */ |
| 1846 | data.variant = ".pxb"; |
| 1847 | test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1" |
| 1848 | " -device virtio-scsi-pci,id=scsi0,bus=pci.1" |
| 1849 | " -drive file=" |
| 1850 | "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2," |
| 1851 | "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on" |
| 1852 | " -device scsi-cd,bus=scsi0.0,scsi-id=0," |
| 1853 | "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1" |
| 1854 | " -cpu cortex-a57" |
| 1855 | " -device pxb-pcie,bus_nr=128", |
| 1856 | &data); |
| 1857 | |
| 1858 | free_test_data(&data); |
| 1859 | } |
| 1860 | |
| 1861 | static void test_acpi_aarch64_virt_tcg_acpi_spcr(void) |
| 1862 | { |
| 1863 | test_data data = { |
| 1864 | .machine = "virt", |
| 1865 | .arch = "aarch64", |
| 1866 | .tcg_only = true, |
| 1867 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1868 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1869 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 1870 | .ram_start = 0x40000000ULL, |
| 1871 | .scan_len = 128ULL * 1024 * 1024, |
| 1872 | .variant = ".acpispcr", |
| 1873 | }; |
| 1874 | |
| 1875 | test_acpi_one("-cpu cortex-a57 " |
| 1876 | " -machine spcr=off", &data); |
| 1877 | free_test_data(&data); |
| 1878 | } |
| 1879 | |
| 1880 | static void test_acpi_riscv64_virt_tcg_acpi_spcr(void) |
| 1881 | { |
| 1882 | test_data data = { |
| 1883 | .machine = "virt", |
| 1884 | .arch = "riscv64", |
| 1885 | .tcg_only = true, |
| 1886 | .uefi_fl1 = "pc-bios/edk2-riscv64-code.fd", |
| 1887 | .uefi_fl2 = "pc-bios/edk2-riscv64-vars.fd", |
| 1888 | .cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2", |
| 1889 | .ram_start = 0x80000000ULL, |
| 1890 | .scan_len = 128ULL * 1024 * 1024, |
| 1891 | .variant = ".acpispcr", |
| 1892 | }; |
| 1893 | |
| 1894 | test_acpi_one("-cpu rva22s64 " |
| 1895 | "-machine spcr=off", &data); |
| 1896 | free_test_data(&data); |
| 1897 | } |
| 1898 | |
| 1899 | static void test_acpi_tcg_acpi_hmat(const char *machine, const char *arch) |
| 1900 | { |
| 1901 | test_data data = {}; |
| 1902 | |
| 1903 | data.machine = machine; |
| 1904 | data.arch = arch; |
| 1905 | data.variant = ".acpihmat"; |
| 1906 | test_acpi_one(" -machine hmat=on" |
| 1907 | " -smp 2,sockets=2" |
| 1908 | " -m 128M,slots=2,maxmem=1G" |
| 1909 | " -object memory-backend-ram,size=64M,id=m0" |
| 1910 | " -object memory-backend-ram,size=64M,id=m1" |
| 1911 | " -numa node,nodeid=0,memdev=m0" |
| 1912 | " -numa node,nodeid=1,memdev=m1,initiator=0" |
| 1913 | " -numa cpu,node-id=0,socket-id=0" |
| 1914 | " -numa cpu,node-id=0,socket-id=1" |
| 1915 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 1916 | "data-type=access-latency,latency=1" |
| 1917 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 1918 | "data-type=access-bandwidth,bandwidth=65534M" |
| 1919 | " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," |
| 1920 | "data-type=access-latency,latency=65534" |
| 1921 | " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," |
| 1922 | "data-type=access-bandwidth,bandwidth=32767M" |
| 1923 | " -numa hmat-cache,node-id=0,size=10K,level=1," |
| 1924 | "associativity=direct,policy=write-back,line=8" |
| 1925 | " -numa hmat-cache,node-id=1,size=10K,level=1," |
| 1926 | "associativity=direct,policy=write-back,line=8", |
| 1927 | &data); |
| 1928 | free_test_data(&data); |
| 1929 | } |
| 1930 | |
| 1931 | static void test_acpi_q35_tcg_acpi_hmat(void) |
| 1932 | { |
| 1933 | test_acpi_tcg_acpi_hmat(MACHINE_Q35, "x86"); |
| 1934 | } |
| 1935 | |
| 1936 | static void test_acpi_piix4_tcg_acpi_hmat(void) |
| 1937 | { |
| 1938 | test_acpi_tcg_acpi_hmat(MACHINE_PC, "x86"); |
| 1939 | } |
| 1940 | |
| 1941 | static void test_acpi_aarch64_virt_tcg_acpi_hmat(void) |
| 1942 | { |
| 1943 | test_data data = { |
| 1944 | .machine = "virt", |
| 1945 | .arch = "aarch64", |
| 1946 | .tcg_only = true, |
| 1947 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 1948 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 1949 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 1950 | .ram_start = 0x40000000ULL, |
| 1951 | .scan_len = 128ULL * MiB, |
| 1952 | }; |
| 1953 | |
| 1954 | data.variant = ".acpihmatvirt"; |
| 1955 | |
| 1956 | test_acpi_one(" -machine hmat=on" |
| 1957 | " -cpu cortex-a57" |
| 1958 | " -smp 4,sockets=2" |
| 1959 | " -m 384M" |
| 1960 | " -object memory-backend-ram,size=128M,id=ram0" |
| 1961 | " -object memory-backend-ram,size=128M,id=ram1" |
| 1962 | " -object memory-backend-ram,size=128M,id=ram2" |
| 1963 | " -numa node,nodeid=0,memdev=ram0" |
| 1964 | " -numa node,nodeid=1,memdev=ram1" |
| 1965 | " -numa node,nodeid=2,memdev=ram2" |
| 1966 | " -numa cpu,node-id=0,socket-id=0" |
| 1967 | " -numa cpu,node-id=0,socket-id=0" |
| 1968 | " -numa cpu,node-id=1,socket-id=1" |
| 1969 | " -numa cpu,node-id=1,socket-id=1" |
| 1970 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 1971 | "data-type=access-latency,latency=10" |
| 1972 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 1973 | "data-type=access-bandwidth,bandwidth=10485760" |
| 1974 | " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," |
| 1975 | "data-type=access-latency,latency=20" |
| 1976 | " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," |
| 1977 | "data-type=access-bandwidth,bandwidth=5242880" |
| 1978 | " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," |
| 1979 | "data-type=access-latency,latency=30" |
| 1980 | " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," |
| 1981 | "data-type=access-bandwidth,bandwidth=1048576" |
| 1982 | " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," |
| 1983 | "data-type=access-latency,latency=20" |
| 1984 | " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," |
| 1985 | "data-type=access-bandwidth,bandwidth=5242880" |
| 1986 | " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," |
| 1987 | "data-type=access-latency,latency=10" |
| 1988 | " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," |
| 1989 | "data-type=access-bandwidth,bandwidth=10485760" |
| 1990 | " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," |
| 1991 | "data-type=access-latency,latency=30" |
| 1992 | " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," |
| 1993 | "data-type=access-bandwidth,bandwidth=1048576", |
| 1994 | &data); |
| 1995 | |
| 1996 | free_test_data(&data); |
| 1997 | } |
| 1998 | |
| 1999 | static void test_acpi_q35_tcg_acpi_hmat_noinitiator(void) |
| 2000 | { |
| 2001 | test_data data = {}; |
| 2002 | |
| 2003 | data.machine = MACHINE_Q35; |
| 2004 | data.arch = "x86"; |
| 2005 | data.variant = ".acpihmat-noinitiator"; |
| 2006 | test_acpi_one(" -machine hmat=on" |
| 2007 | " -smp 4,sockets=2" |
| 2008 | " -m 128M" |
| 2009 | " -object memory-backend-ram,size=32M,id=ram0" |
| 2010 | " -object memory-backend-ram,size=32M,id=ram1" |
| 2011 | " -object memory-backend-ram,size=64M,id=ram2" |
| 2012 | " -numa node,nodeid=0,memdev=ram0" |
| 2013 | " -numa node,nodeid=1,memdev=ram1" |
| 2014 | " -numa node,nodeid=2,memdev=ram2" |
| 2015 | " -numa cpu,node-id=0,socket-id=0" |
| 2016 | " -numa cpu,node-id=0,socket-id=0" |
| 2017 | " -numa cpu,node-id=1,socket-id=1" |
| 2018 | " -numa cpu,node-id=1,socket-id=1" |
| 2019 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 2020 | "data-type=access-latency,latency=10" |
| 2021 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 2022 | "data-type=access-bandwidth,bandwidth=10485760" |
| 2023 | " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," |
| 2024 | "data-type=access-latency,latency=20" |
| 2025 | " -numa hmat-lb,initiator=0,target=1,hierarchy=memory," |
| 2026 | "data-type=access-bandwidth,bandwidth=5242880" |
| 2027 | " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," |
| 2028 | "data-type=access-latency,latency=30" |
| 2029 | " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," |
| 2030 | "data-type=access-bandwidth,bandwidth=1048576" |
| 2031 | " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," |
| 2032 | "data-type=access-latency,latency=20" |
| 2033 | " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," |
| 2034 | "data-type=access-bandwidth,bandwidth=5242880" |
| 2035 | " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," |
| 2036 | "data-type=access-latency,latency=10" |
| 2037 | " -numa hmat-lb,initiator=1,target=1,hierarchy=memory," |
| 2038 | "data-type=access-bandwidth,bandwidth=10485760" |
| 2039 | " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," |
| 2040 | "data-type=access-latency,latency=30" |
| 2041 | " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," |
| 2042 | "data-type=access-bandwidth,bandwidth=1048576", |
| 2043 | &data); |
| 2044 | free_test_data(&data); |
| 2045 | } |
| 2046 | |
| 2047 | /* Test intended to hit corner cases of SRAT and HMAT */ |
| 2048 | static void test_acpi_q35_tcg_acpi_hmat_generic_x(void) |
| 2049 | { |
| 2050 | test_data data = {}; |
| 2051 | |
| 2052 | data.machine = MACHINE_Q35; |
| 2053 | data.arch = "x86"; |
| 2054 | data.variant = ".acpihmat-generic-x"; |
| 2055 | test_acpi_one(" -machine hmat=on,cxl=on" |
| 2056 | " -smp 3,sockets=3" |
| 2057 | " -m 128M,maxmem=384M,slots=2" |
| 2058 | " -device pcie-root-port,chassis=1,id=pci.1" |
| 2059 | " -device pci-testdev,bus=pci.1," |
| 2060 | "multifunction=on,addr=00.0" |
| 2061 | " -device pci-testdev,bus=pci.1,addr=00.1" |
| 2062 | " -device pci-testdev,bus=pci.1,id=gidev,addr=00.2" |
| 2063 | " -device pxb-cxl,bus_nr=64,bus=pcie.0,id=cxl.1" |
| 2064 | " -object memory-backend-ram,size=64M,id=ram0" |
| 2065 | " -object memory-backend-ram,size=64M,id=ram1" |
| 2066 | " -numa node,nodeid=0,cpus=0,memdev=ram0" |
| 2067 | " -numa node,nodeid=1" |
| 2068 | " -object acpi-generic-initiator,id=gi0,pci-dev=gidev,node=1" |
| 2069 | " -numa node,nodeid=2" |
| 2070 | " -object acpi-generic-port,id=gp0,pci-bus=cxl.1,node=2" |
| 2071 | " -numa node,nodeid=3,cpus=1" |
| 2072 | " -numa node,nodeid=4,memdev=ram1" |
| 2073 | " -numa node,nodeid=5,cpus=2" |
| 2074 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 2075 | "data-type=access-latency,latency=10" |
| 2076 | " -numa hmat-lb,initiator=0,target=0,hierarchy=memory," |
| 2077 | "data-type=access-bandwidth,bandwidth=800M" |
| 2078 | " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," |
| 2079 | "data-type=access-latency,latency=100" |
| 2080 | " -numa hmat-lb,initiator=0,target=2,hierarchy=memory," |
| 2081 | "data-type=access-bandwidth,bandwidth=200M" |
| 2082 | " -numa hmat-lb,initiator=0,target=4,hierarchy=memory," |
| 2083 | "data-type=access-latency,latency=100" |
| 2084 | " -numa hmat-lb,initiator=0,target=4,hierarchy=memory," |
| 2085 | "data-type=access-bandwidth,bandwidth=200M" |
| 2086 | " -numa hmat-lb,initiator=0,target=5,hierarchy=memory," |
| 2087 | "data-type=access-latency,latency=200" |
| 2088 | " -numa hmat-lb,initiator=0,target=5,hierarchy=memory," |
| 2089 | "data-type=access-bandwidth,bandwidth=400M" |
| 2090 | " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," |
| 2091 | "data-type=access-latency,latency=500" |
| 2092 | " -numa hmat-lb,initiator=1,target=0,hierarchy=memory," |
| 2093 | "data-type=access-bandwidth,bandwidth=100M" |
| 2094 | " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," |
| 2095 | "data-type=access-latency,latency=50" |
| 2096 | " -numa hmat-lb,initiator=1,target=2,hierarchy=memory," |
| 2097 | "data-type=access-bandwidth,bandwidth=400M" |
| 2098 | " -numa hmat-lb,initiator=1,target=4,hierarchy=memory," |
| 2099 | "data-type=access-latency,latency=50" |
| 2100 | " -numa hmat-lb,initiator=1,target=4,hierarchy=memory," |
| 2101 | "data-type=access-bandwidth,bandwidth=800M" |
| 2102 | " -numa hmat-lb,initiator=1,target=5,hierarchy=memory," |
| 2103 | "data-type=access-latency,latency=500" |
| 2104 | " -numa hmat-lb,initiator=1,target=5,hierarchy=memory," |
| 2105 | "data-type=access-bandwidth,bandwidth=100M" |
| 2106 | " -numa hmat-lb,initiator=3,target=0,hierarchy=memory," |
| 2107 | "data-type=access-latency,latency=20" |
| 2108 | " -numa hmat-lb,initiator=3,target=0,hierarchy=memory," |
| 2109 | "data-type=access-bandwidth,bandwidth=400M" |
| 2110 | " -numa hmat-lb,initiator=3,target=2,hierarchy=memory," |
| 2111 | "data-type=access-latency,latency=80" |
| 2112 | " -numa hmat-lb,initiator=3,target=2,hierarchy=memory," |
| 2113 | "data-type=access-bandwidth,bandwidth=200M" |
| 2114 | " -numa hmat-lb,initiator=3,target=4,hierarchy=memory," |
| 2115 | "data-type=access-latency,latency=80" |
| 2116 | " -numa hmat-lb,initiator=3,target=4,hierarchy=memory," |
| 2117 | "data-type=access-bandwidth,bandwidth=200M" |
| 2118 | " -numa hmat-lb,initiator=3,target=5,hierarchy=memory," |
| 2119 | "data-type=access-latency,latency=20" |
| 2120 | " -numa hmat-lb,initiator=3,target=5,hierarchy=memory," |
| 2121 | "data-type=access-bandwidth,bandwidth=400M" |
| 2122 | " -numa hmat-lb,initiator=5,target=0,hierarchy=memory," |
| 2123 | "data-type=access-latency,latency=20" |
| 2124 | " -numa hmat-lb,initiator=5,target=0,hierarchy=memory," |
| 2125 | "data-type=access-bandwidth,bandwidth=400M" |
| 2126 | " -numa hmat-lb,initiator=5,target=2,hierarchy=memory," |
| 2127 | "data-type=access-latency,latency=80" |
| 2128 | " -numa hmat-lb,initiator=5,target=4,hierarchy=memory," |
| 2129 | "data-type=access-bandwidth,bandwidth=200M" |
| 2130 | " -numa hmat-lb,initiator=5,target=4,hierarchy=memory," |
| 2131 | "data-type=access-latency,latency=80" |
| 2132 | " -numa hmat-lb,initiator=5,target=2,hierarchy=memory," |
| 2133 | "data-type=access-bandwidth,bandwidth=200M" |
| 2134 | " -numa hmat-lb,initiator=5,target=5,hierarchy=memory," |
| 2135 | "data-type=access-latency,latency=10" |
| 2136 | " -numa hmat-lb,initiator=5,target=5,hierarchy=memory," |
| 2137 | "data-type=access-bandwidth,bandwidth=800M", |
| 2138 | &data); |
| 2139 | free_test_data(&data); |
| 2140 | } |
| 2141 | |
| 2142 | #ifdef CONFIG_POSIX |
| 2143 | static void test_acpi_erst(const char *machine, const char *arch) |
| 2144 | { |
| 2145 | gchar *tmp_path = g_dir_make_tmp("qemu-test-erst.XXXXXX", NULL); |
| 2146 | gchar *params; |
| 2147 | test_data data = {}; |
| 2148 | |
| 2149 | data.machine = machine; |
| 2150 | data.arch = arch; |
| 2151 | data.variant = ".acpierst"; |
| 2152 | params = g_strdup_printf( |
| 2153 | " -object memory-backend-file,id=erstnvram," |
| 2154 | "mem-path=%s,size=0x10000,share=on" |
| 2155 | " -device acpi-erst,memdev=erstnvram", tmp_path); |
| 2156 | test_acpi_one(params, &data); |
| 2157 | free_test_data(&data); |
| 2158 | g_free(params); |
| 2159 | g_assert(g_rmdir(tmp_path) == 0); |
| 2160 | g_free(tmp_path); |
| 2161 | } |
| 2162 | |
| 2163 | static void test_acpi_piix4_acpi_erst(void) |
| 2164 | { |
| 2165 | test_acpi_erst(MACHINE_PC, "x86"); |
| 2166 | } |
| 2167 | |
| 2168 | static void test_acpi_q35_acpi_erst(void) |
| 2169 | { |
| 2170 | test_acpi_erst(MACHINE_Q35, "x86"); |
| 2171 | } |
| 2172 | |
| 2173 | static void test_acpi_microvm_acpi_erst(void) |
| 2174 | { |
| 2175 | gchar *tmp_path = g_dir_make_tmp("qemu-test-erst.XXXXXX", NULL); |
| 2176 | gchar *params; |
| 2177 | test_data data = {}; |
| 2178 | |
| 2179 | test_acpi_microvm_prepare(&data); |
| 2180 | data.variant = ".pcie"; |
| 2181 | data.tcg_only = true; /* need constant host-phys-bits */ |
| 2182 | params = g_strdup_printf(" -machine microvm," |
| 2183 | "acpi=on,ioapic2=off,rtc=off,pcie=on" |
| 2184 | " -object memory-backend-file,id=erstnvram," |
| 2185 | "mem-path=%s,size=0x10000,share=on" |
| 2186 | " -device acpi-erst,memdev=erstnvram", tmp_path); |
| 2187 | test_acpi_one(params, &data); |
| 2188 | g_free(params); |
| 2189 | g_assert(g_rmdir(tmp_path) == 0); |
| 2190 | g_free(tmp_path); |
| 2191 | free_test_data(&data); |
| 2192 | } |
| 2193 | #endif /* CONFIG_POSIX */ |
| 2194 | |
| 2195 | static void test_acpi_riscv64_virt_tcg(void) |
| 2196 | { |
| 2197 | test_data data = { |
| 2198 | .machine = "virt", |
| 2199 | .arch = "riscv64", |
| 2200 | .tcg_only = true, |
| 2201 | .uefi_fl1 = "pc-bios/edk2-riscv64-code.fd", |
| 2202 | .uefi_fl2 = "pc-bios/edk2-riscv64-vars.fd", |
| 2203 | .cd = "tests/data/uefi-boot-images/bios-tables-test.riscv64.iso.qcow2", |
| 2204 | .ram_start = 0x80000000ULL, |
| 2205 | .scan_len = 128ULL * MiB, |
| 2206 | }; |
| 2207 | |
| 2208 | /* |
| 2209 | * RHCT will have ISA string encoded. To reduce the effort |
| 2210 | * of updating expected AML file for any new default ISA extension, |
| 2211 | * use the profile rva22s64. |
| 2212 | */ |
| 2213 | test_acpi_one("-cpu rva22s64 ", &data); |
| 2214 | free_test_data(&data); |
| 2215 | } |
| 2216 | |
| 2217 | static void test_acpi_aarch64_virt_tcg(void) |
| 2218 | { |
| 2219 | test_data data = { |
| 2220 | .machine = "virt", |
| 2221 | .arch = "aarch64", |
| 2222 | .tcg_only = true, |
| 2223 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2224 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2225 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2226 | .ram_start = 0x40000000ULL, |
| 2227 | .scan_len = 128ULL * MiB, |
| 2228 | }; |
| 2229 | |
| 2230 | data.smbios_cpu_max_speed = 2900; |
| 2231 | data.smbios_cpu_curr_speed = 2700; |
| 2232 | test_acpi_one("-cpu cortex-a57 -machine ras=on " |
| 2233 | "-smbios type=4,max-speed=2900,current-speed=2700", &data); |
| 2234 | free_test_data(&data); |
| 2235 | } |
| 2236 | |
| 2237 | static void test_acpi_aarch64_virt_tcg_topology(void) |
| 2238 | { |
| 2239 | test_data data = { |
| 2240 | .machine = "virt", |
| 2241 | .arch = "aarch64", |
| 2242 | .variant = ".topology", |
| 2243 | .tcg_only = true, |
| 2244 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2245 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2246 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2247 | .ram_start = 0x40000000ULL, |
| 2248 | .scan_len = 128ULL * MiB, |
| 2249 | }; |
| 2250 | |
| 2251 | test_acpi_one("-cpu cortex-a57 " |
| 2252 | "-M virt,smp-cache.0.cache=l1i,smp-cache.0.topology=cluster," |
| 2253 | "smp-cache.1.cache=l1d,smp-cache.1.topology=cluster," |
| 2254 | "smp-cache.2.cache=l2,smp-cache.2.topology=cluster," |
| 2255 | "smp-cache.3.cache=l3,smp-cache.3.topology=cluster " |
| 2256 | "-smp sockets=1,clusters=2,cores=2,threads=2", &data); |
| 2257 | free_test_data(&data); |
| 2258 | } |
| 2259 | |
| 2260 | static void test_acpi_aarch64_virt_tcg_its_off(void) |
| 2261 | { |
| 2262 | test_data data = { |
| 2263 | .machine = "virt", |
| 2264 | .arch = "aarch64", |
| 2265 | .variant = ".its_off", |
| 2266 | .tcg_only = true, |
| 2267 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2268 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2269 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2270 | .ram_start = 0x40000000ULL, |
| 2271 | .scan_len = 128ULL * 1024 * 1024, |
| 2272 | }; |
| 2273 | |
| 2274 | test_acpi_one("-cpu cortex-a57 " |
| 2275 | "-M gic-version=3,iommu=smmuv3,its=off", &data); |
| 2276 | free_test_data(&data); |
| 2277 | } |
| 2278 | |
| 2279 | static void test_acpi_aarch64_virt_tcg_msi_gicv2m(void) |
| 2280 | { |
| 2281 | test_data data = { |
| 2282 | .machine = "virt", |
| 2283 | .arch = "aarch64", |
| 2284 | .variant = ".msi_gicv2m", |
| 2285 | .tcg_only = true, |
| 2286 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2287 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2288 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2289 | .ram_start = 0x40000000ULL, |
| 2290 | .scan_len = 128ULL * 1024 * 1024, |
| 2291 | }; |
| 2292 | |
| 2293 | test_acpi_one("-cpu cortex-a57 " |
| 2294 | "-M gic-version=3,iommu=smmuv3,msi=gicv2m", &data); |
| 2295 | free_test_data(&data); |
| 2296 | } |
| 2297 | |
| 2298 | static void test_acpi_aarch64_virt_tcg_wdat(void) |
| 2299 | { |
| 2300 | test_data data = { |
| 2301 | .machine = "virt", |
| 2302 | .arch = "aarch64", |
| 2303 | .variant = ".wdat", |
| 2304 | .tcg_only = true, |
| 2305 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2306 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2307 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2308 | .ram_start = 0x40000000ULL, |
| 2309 | .scan_len = 128ULL * MiB, |
| 2310 | }; |
| 2311 | |
| 2312 | test_acpi_one("-cpu cortex-a57 " |
| 2313 | "-device sbsa-gwdt,wdat=on", &data); |
| 2314 | free_test_data(&data); |
| 2315 | } |
| 2316 | |
| 2317 | static void test_acpi_aarch64_virt_tcg_gtdt_wd(void) |
| 2318 | { |
| 2319 | test_data data = { |
| 2320 | .machine = "virt", |
| 2321 | .arch = "aarch64", |
| 2322 | .variant = ".gwdt", |
| 2323 | .tcg_only = true, |
| 2324 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2325 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2326 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2327 | .ram_start = 0x40000000ULL, |
| 2328 | .scan_len = 128ULL * MiB, |
| 2329 | }; |
| 2330 | |
| 2331 | test_acpi_one("-cpu cortex-a57 -device sbsa-gwdt", &data); |
| 2332 | free_test_data(&data); |
| 2333 | } |
| 2334 | |
| 2335 | static void test_acpi_q35_viot(void) |
| 2336 | { |
| 2337 | test_data data = { |
| 2338 | .machine = MACHINE_Q35, |
| 2339 | .arch = "x86", |
| 2340 | .variant = ".viot", |
| 2341 | }; |
| 2342 | |
| 2343 | /* |
| 2344 | * To keep things interesting, two buses bypass the IOMMU. |
| 2345 | * VIOT should only describes the other two buses. |
| 2346 | */ |
| 2347 | test_acpi_one("-machine default_bus_bypass_iommu=on " |
| 2348 | "-device virtio-iommu-pci " |
| 2349 | "-device pxb-pcie,bus_nr=0x10,id=pcie.100,bus=pcie.0 " |
| 2350 | "-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on " |
| 2351 | "-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0", |
| 2352 | &data); |
| 2353 | free_test_data(&data); |
| 2354 | } |
| 2355 | |
| 2356 | #ifdef CONFIG_POSIX |
| 2357 | static void test_acpi_q35_cxl(void) |
| 2358 | { |
| 2359 | gchar *tmp_path = g_dir_make_tmp("qemu-test-cxl.XXXXXX", NULL); |
| 2360 | gchar *params; |
| 2361 | |
| 2362 | test_data data = { |
| 2363 | .machine = MACHINE_Q35, |
| 2364 | .arch = "x86", |
| 2365 | .variant = ".cxl", |
| 2366 | }; |
| 2367 | /* |
| 2368 | * A complex CXL setup. |
| 2369 | */ |
| 2370 | params = g_strdup_printf(" -machine cxl=on" |
| 2371 | " -object memory-backend-file,id=cxl-mem1,mem-path=%s,size=256M" |
| 2372 | " -object memory-backend-file,id=cxl-mem2,mem-path=%s,size=256M" |
| 2373 | " -object memory-backend-file,id=cxl-mem3,mem-path=%s,size=256M" |
| 2374 | " -object memory-backend-file,id=cxl-mem4,mem-path=%s,size=256M" |
| 2375 | " -object memory-backend-file,id=lsa1,mem-path=%s,size=256M" |
| 2376 | " -object memory-backend-file,id=lsa2,mem-path=%s,size=256M" |
| 2377 | " -object memory-backend-file,id=lsa3,mem-path=%s,size=256M" |
| 2378 | " -object memory-backend-file,id=lsa4,mem-path=%s,size=256M" |
| 2379 | " -device pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1" |
| 2380 | " -device pxb-cxl,bus_nr=222,bus=pcie.0,id=cxl.2" |
| 2381 | " -device cxl-rp,port=0,bus=cxl.1,id=rp1,chassis=0,slot=2" |
| 2382 | " -device cxl-type3,bus=rp1,persistent-memdev=cxl-mem1,lsa=lsa1" |
| 2383 | " -device cxl-rp,port=1,bus=cxl.1,id=rp2,chassis=0,slot=3" |
| 2384 | " -device cxl-type3,bus=rp2,persistent-memdev=cxl-mem2,lsa=lsa2" |
| 2385 | " -device cxl-rp,port=0,bus=cxl.2,id=rp3,chassis=0,slot=5" |
| 2386 | " -device cxl-type3,bus=rp3,persistent-memdev=cxl-mem3,lsa=lsa3" |
| 2387 | " -device cxl-rp,port=1,bus=cxl.2,id=rp4,chassis=0,slot=6" |
| 2388 | " -device cxl-type3,bus=rp4,persistent-memdev=cxl-mem4,lsa=lsa4" |
| 2389 | " -M cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=4G,cxl-fmw.0.interleave-granularity=8k," |
| 2390 | "cxl-fmw.1.targets.0=cxl.1,cxl-fmw.1.targets.1=cxl.2,cxl-fmw.1.size=4G,cxl-fmw.1.interleave-granularity=8k", |
| 2391 | tmp_path, tmp_path, tmp_path, tmp_path, |
| 2392 | tmp_path, tmp_path, tmp_path, tmp_path); |
| 2393 | test_acpi_one(params, &data); |
| 2394 | |
| 2395 | g_free(params); |
| 2396 | g_assert(g_rmdir(tmp_path) == 0); |
| 2397 | g_free(tmp_path); |
| 2398 | free_test_data(&data); |
| 2399 | } |
| 2400 | #endif /* CONFIG_POSIX */ |
| 2401 | |
| 2402 | static void test_acpi_aarch64_virt_viot(void) |
| 2403 | { |
| 2404 | test_data data = { |
| 2405 | .machine = "virt", |
| 2406 | .arch = "aarch64", |
| 2407 | .variant = ".viot", |
| 2408 | .tcg_only = true, |
| 2409 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2410 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2411 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2412 | .ram_start = 0x40000000ULL, |
| 2413 | .scan_len = 128ULL * MiB, |
| 2414 | }; |
| 2415 | |
| 2416 | test_acpi_one("-cpu cortex-a57 " |
| 2417 | "-device virtio-iommu-pci", &data); |
| 2418 | free_test_data(&data); |
| 2419 | } |
| 2420 | |
| 2421 | static void test_acpi_aarch64_virt_smmuv3_legacy(void) |
| 2422 | { |
| 2423 | test_data data = { |
| 2424 | .machine = "virt", |
| 2425 | .arch = "aarch64", |
| 2426 | .tcg_only = true, |
| 2427 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2428 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2429 | .ram_start = 0x40000000ULL, |
| 2430 | .scan_len = 128ULL * MiB, |
| 2431 | }; |
| 2432 | |
| 2433 | /* |
| 2434 | * cdrom is plugged into scsi controller to avoid conflict |
| 2435 | * with pxb-pcie. See comments in test_acpi_aarch64_virt_tcg_pxb() for |
| 2436 | * details. |
| 2437 | * |
| 2438 | * The setup includes three PCIe root complexes, one of which has |
| 2439 | * bypass_iommu enabled. The generated IORT table contains a single |
| 2440 | * SMMUv3 node and a Root Complex node with three ID mappings. Two |
| 2441 | * of the ID mappings have output references pointing to the SMMUv3 |
| 2442 | * node and the remaining one points to ITS. |
| 2443 | */ |
| 2444 | data.variant = ".smmuv3-legacy"; |
| 2445 | test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1" |
| 2446 | " -device virtio-scsi-pci,id=scsi0,bus=pci.1" |
| 2447 | " -drive file=" |
| 2448 | "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2," |
| 2449 | "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on" |
| 2450 | " -device scsi-cd,bus=scsi0.0,scsi-id=0," |
| 2451 | "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1" |
| 2452 | " -cpu cortex-a57" |
| 2453 | " -M iommu=smmuv3" |
| 2454 | " -device pxb-pcie,id=pcie.1,bus=pcie.0,bus_nr=0x10" |
| 2455 | " -device pxb-pcie,id=pcie.2,bus=pcie.0,bus_nr=0x20,bypass_iommu=on", |
| 2456 | &data); |
| 2457 | free_test_data(&data); |
| 2458 | } |
| 2459 | |
| 2460 | static void test_acpi_aarch64_virt_smmuv3_dev(void) |
| 2461 | { |
| 2462 | test_data data = { |
| 2463 | .machine = "virt", |
| 2464 | .arch = "aarch64", |
| 2465 | .tcg_only = true, |
| 2466 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2467 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2468 | .ram_start = 0x40000000ULL, |
| 2469 | .scan_len = 128ULL * MiB, |
| 2470 | }; |
| 2471 | |
| 2472 | /* |
| 2473 | * cdrom is plugged into scsi controller to avoid conflict |
| 2474 | * with pxb-pcie. See comments in test_acpi_aarch64_virt_tcg_pxb() |
| 2475 | * for details. |
| 2476 | * |
| 2477 | * The setup includes three PCie root complexes, two of which are |
| 2478 | * connected to separate SMMUv3 devices. The resulting IORT table |
| 2479 | * contains two SMMUv3 nodes and a Root Complex node with ID mappings |
| 2480 | * of which two of the ID mappings have output references pointing |
| 2481 | * to two different SMMUv3 nodes and the remaining ones pointing to |
| 2482 | * ITS. |
| 2483 | */ |
| 2484 | data.variant = ".smmuv3-dev"; |
| 2485 | test_acpi_one(" -device pcie-root-port,chassis=1,id=pci.1" |
| 2486 | " -device virtio-scsi-pci,id=scsi0,bus=pci.1" |
| 2487 | " -drive file=" |
| 2488 | "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2," |
| 2489 | "if=none,media=cdrom,id=drive-scsi0-0-0-1,readonly=on" |
| 2490 | " -device scsi-cd,bus=scsi0.0,scsi-id=0," |
| 2491 | "drive=drive-scsi0-0-0-1,id=scsi0-0-0-1,bootindex=1" |
| 2492 | " -cpu cortex-a57" |
| 2493 | " -device arm-smmuv3,primary-bus=pcie.0,id=smmuv3.0" |
| 2494 | " -device pxb-pcie,id=pcie.1,bus=pcie.0,bus_nr=0x10" |
| 2495 | " -device arm-smmuv3,primary-bus=pcie.1,id=smmuv3.1" |
| 2496 | " -device pxb-pcie,id=pcie.2,bus=pcie.0,bus_nr=0x20", |
| 2497 | &data); |
| 2498 | free_test_data(&data); |
| 2499 | } |
| 2500 | |
| 2501 | #ifndef _WIN32 |
| 2502 | # define DEV_NULL "/dev/null" |
| 2503 | #else |
| 2504 | # define DEV_NULL "nul" |
| 2505 | #endif |
| 2506 | |
| 2507 | static void test_acpi_q35_slic(void) |
| 2508 | { |
| 2509 | test_data data = { |
| 2510 | .machine = MACHINE_Q35, |
| 2511 | .arch = "x86", |
| 2512 | .variant = ".slic", |
| 2513 | }; |
| 2514 | |
| 2515 | test_acpi_one("-acpitable sig=SLIC,oem_id=\"CRASH \",oem_table_id=ME," |
| 2516 | "oem_rev=00002210,asl_compiler_id=qemu," |
| 2517 | "asl_compiler_rev=00000000,data=" DEV_NULL, |
| 2518 | &data); |
| 2519 | free_test_data(&data); |
| 2520 | } |
| 2521 | |
| 2522 | static void test_acpi_q35_applesmc(void) |
| 2523 | { |
| 2524 | test_data data = { |
| 2525 | .machine = MACHINE_Q35, |
| 2526 | .arch = "x86", |
| 2527 | .variant = ".applesmc", |
| 2528 | }; |
| 2529 | |
| 2530 | /* supply fake 64-byte OSK to silence missing key warning */ |
| 2531 | test_acpi_one("-device isa-applesmc,osk=any64characterfakeoskisenough" |
| 2532 | "topreventinvalidkeywarningsonstderr", &data); |
| 2533 | free_test_data(&data); |
| 2534 | } |
| 2535 | |
| 2536 | static void test_acpi_q35_pvpanic_isa(void) |
| 2537 | { |
| 2538 | test_data data = { |
| 2539 | .machine = MACHINE_Q35, |
| 2540 | .arch = "x86", |
| 2541 | .variant = ".pvpanic-isa", |
| 2542 | }; |
| 2543 | |
| 2544 | test_acpi_one("-device pvpanic", &data); |
| 2545 | free_test_data(&data); |
| 2546 | } |
| 2547 | |
| 2548 | static void test_acpi_pc_smbios_options(void) |
| 2549 | { |
| 2550 | uint8_t req_type11[] = { 11 }; |
| 2551 | test_data data = { |
| 2552 | .machine = MACHINE_PC, |
| 2553 | .arch = "x86", |
| 2554 | .variant = ".pc_smbios_options", |
| 2555 | .required_struct_types = req_type11, |
| 2556 | .required_struct_types_len = ARRAY_SIZE(req_type11), |
| 2557 | }; |
| 2558 | |
| 2559 | test_smbios("-smbios type=11,value=TEST", &data); |
| 2560 | free_test_data(&data); |
| 2561 | } |
| 2562 | |
| 2563 | static void test_acpi_pc_smbios_blob(void) |
| 2564 | { |
| 2565 | uint8_t req_type11[] = { 11 }; |
| 2566 | test_data data = { |
| 2567 | .machine = MACHINE_PC, |
| 2568 | .arch = "x86", |
| 2569 | .variant = ".pc_smbios_blob", |
| 2570 | .required_struct_types = req_type11, |
| 2571 | .required_struct_types_len = ARRAY_SIZE(req_type11), |
| 2572 | }; |
| 2573 | |
| 2574 | test_smbios("-machine smbios-entry-point-type=32 " |
| 2575 | "-smbios file=tests/data/smbios/type11_blob", &data); |
| 2576 | free_test_data(&data); |
| 2577 | } |
| 2578 | |
| 2579 | static void test_acpi_isapc_smbios_legacy(void) |
| 2580 | { |
| 2581 | uint8_t req_type11[] = { 1, 11 }; |
| 2582 | test_data data = { |
| 2583 | .machine = "isapc", |
| 2584 | .variant = ".pc_smbios_legacy", |
| 2585 | .required_struct_types = req_type11, |
| 2586 | .required_struct_types_len = ARRAY_SIZE(req_type11), |
| 2587 | }; |
| 2588 | |
| 2589 | test_smbios("-smbios file=tests/data/smbios/type11_blob.legacy " |
| 2590 | "-smbios type=1,family=TEST", &data); |
| 2591 | free_test_data(&data); |
| 2592 | } |
| 2593 | |
| 2594 | static void test_acpi_q35_wdat(void) |
| 2595 | { |
| 2596 | test_data data = { |
| 2597 | .machine = MACHINE_Q35, |
| 2598 | .arch = "x86", |
| 2599 | .variant = ".wdat", |
| 2600 | }; |
| 2601 | |
| 2602 | test_acpi_one("-machine wdat=on", &data); |
| 2603 | free_test_data(&data); |
| 2604 | } |
| 2605 | |
| 2606 | static void test_oem_fields(test_data *data) |
| 2607 | { |
| 2608 | int i; |
| 2609 | |
| 2610 | for (i = 0; i < data->tables->len; ++i) { |
| 2611 | AcpiSdtTable *sdt; |
| 2612 | |
| 2613 | sdt = &g_array_index(data->tables, AcpiSdtTable, i); |
| 2614 | /* FACS doesn't have OEMID and OEMTABLEID fields */ |
| 2615 | if (compare_signature(sdt, "FACS")) { |
| 2616 | continue; |
| 2617 | } |
| 2618 | |
| 2619 | /* Firmware Performance Data created by EDK2 not QEMU */ |
| 2620 | if (compare_signature(sdt, "FPDT")) { |
| 2621 | continue; |
| 2622 | } |
| 2623 | |
| 2624 | if (verbosity_level >= 2) { |
| 2625 | fprintf(stderr, "Checking '%.4s'\n", sdt->aml); |
| 2626 | } |
| 2627 | g_assert(strncmp((char *)sdt->aml + 10, OEM_ID, 6) == 0); |
| 2628 | g_assert(strncmp((char *)sdt->aml + 16, OEM_TABLE_ID, 8) == 0); |
| 2629 | } |
| 2630 | } |
| 2631 | |
| 2632 | static void test_acpi_piix4_oem_fields(void) |
| 2633 | { |
| 2634 | char *args; |
| 2635 | test_data data = {}; |
| 2636 | |
| 2637 | data.machine = MACHINE_PC; |
| 2638 | data.arch = "x86"; |
| 2639 | data.required_struct_types = base_required_struct_types; |
| 2640 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 2641 | |
| 2642 | args = test_acpi_create_args(&data, OEM_TEST_ARGS); |
| 2643 | data.qts = qtest_init(args); |
| 2644 | test_acpi_load_tables(&data); |
| 2645 | test_oem_fields(&data); |
| 2646 | qtest_quit(data.qts); |
| 2647 | free_test_data(&data); |
| 2648 | g_free(args); |
| 2649 | } |
| 2650 | |
| 2651 | static void test_acpi_q35_oem_fields(void) |
| 2652 | { |
| 2653 | char *args; |
| 2654 | test_data data = {}; |
| 2655 | |
| 2656 | data.machine = MACHINE_Q35; |
| 2657 | data.arch = "x86"; |
| 2658 | data.required_struct_types = base_required_struct_types; |
| 2659 | data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types); |
| 2660 | |
| 2661 | args = test_acpi_create_args(&data, OEM_TEST_ARGS); |
| 2662 | data.qts = qtest_init(args); |
| 2663 | test_acpi_load_tables(&data); |
| 2664 | test_oem_fields(&data); |
| 2665 | qtest_quit(data.qts); |
| 2666 | free_test_data(&data); |
| 2667 | g_free(args); |
| 2668 | } |
| 2669 | |
| 2670 | static void test_acpi_microvm_oem_fields(void) |
| 2671 | { |
| 2672 | test_data data = {}; |
| 2673 | char *args; |
| 2674 | |
| 2675 | test_acpi_microvm_prepare(&data); |
| 2676 | |
| 2677 | args = test_acpi_create_args(&data, |
| 2678 | OEM_TEST_ARGS",acpi=on"); |
| 2679 | data.qts = qtest_init(args); |
| 2680 | test_acpi_load_tables(&data); |
| 2681 | test_oem_fields(&data); |
| 2682 | qtest_quit(data.qts); |
| 2683 | free_test_data(&data); |
| 2684 | g_free(args); |
| 2685 | } |
| 2686 | |
| 2687 | static void test_acpi_aarch64_virt_oem_fields(void) |
| 2688 | { |
| 2689 | test_data data = { |
| 2690 | .machine = "virt", |
| 2691 | .arch = "aarch64", |
| 2692 | .tcg_only = true, |
| 2693 | .uefi_fl1 = "pc-bios/edk2-aarch64-code.fd", |
| 2694 | .uefi_fl2 = "pc-bios/edk2-aarch64-vars.fd", |
| 2695 | .cd = "tests/data/uefi-boot-images/bios-tables-test.aarch64.iso.qcow2", |
| 2696 | .ram_start = 0x40000000ULL, |
| 2697 | .scan_len = 128ULL * MiB, |
| 2698 | }; |
| 2699 | char *args; |
| 2700 | |
| 2701 | args = test_acpi_create_args(&data, "-cpu cortex-a57 "OEM_TEST_ARGS); |
| 2702 | data.qts = qtest_init(args); |
| 2703 | test_acpi_load_tables(&data); |
| 2704 | test_oem_fields(&data); |
| 2705 | qtest_quit(data.qts); |
| 2706 | free_test_data(&data); |
| 2707 | g_free(args); |
| 2708 | } |
| 2709 | |
| 2710 | #define LOONGARCH64_INIT_TEST_DATA(data) \ |
| 2711 | test_data data = { \ |
| 2712 | .machine = "virt", \ |
| 2713 | .arch = "loongarch64", \ |
| 2714 | .tcg_only = true, \ |
| 2715 | .uefi_fl1 = "pc-bios/edk2-loongarch64-code.fd", \ |
| 2716 | .uefi_fl2 = "pc-bios/edk2-loongarch64-vars.fd", \ |
| 2717 | .cd = "tests/data/uefi-boot-images/" \ |
| 2718 | "bios-tables-test.loongarch64.iso.qcow2", \ |
| 2719 | .ram_start = 0, \ |
| 2720 | .scan_len = 128ULL * MiB, \ |
| 2721 | } |
| 2722 | |
| 2723 | static void test_acpi_loongarch64_virt(void) |
| 2724 | { |
| 2725 | LOONGARCH64_INIT_TEST_DATA(data); |
| 2726 | |
| 2727 | test_acpi_one("-cpu la464 ", &data); |
| 2728 | free_test_data(&data); |
| 2729 | } |
| 2730 | |
| 2731 | static void test_acpi_loongarch64_virt_topology(void) |
| 2732 | { |
| 2733 | LOONGARCH64_INIT_TEST_DATA(data); |
| 2734 | |
| 2735 | data.variant = ".topology"; |
| 2736 | test_acpi_one("-cpu la464 -smp sockets=1,cores=2,threads=2", &data); |
| 2737 | free_test_data(&data); |
| 2738 | } |
| 2739 | |
| 2740 | static void test_acpi_loongarch64_virt_numamem(void) |
| 2741 | { |
| 2742 | LOONGARCH64_INIT_TEST_DATA(data); |
| 2743 | |
| 2744 | data.variant = ".numamem"; |
| 2745 | test_acpi_one(" -cpu la464 -m 128" |
| 2746 | " -object memory-backend-ram,id=ram0,size=64M" |
| 2747 | " -object memory-backend-ram,id=ram1,size=64M" |
| 2748 | " -numa node,memdev=ram0 -numa node,memdev=ram1" |
| 2749 | " -numa dist,src=0,dst=1,val=21", |
| 2750 | &data); |
| 2751 | free_test_data(&data); |
| 2752 | } |
| 2753 | |
| 2754 | static void test_acpi_loongarch64_virt_memhp(void) |
| 2755 | { |
| 2756 | LOONGARCH64_INIT_TEST_DATA(data); |
| 2757 | |
| 2758 | data.variant = ".memhp"; |
| 2759 | test_acpi_one(" -cpu la464 -m 128,slots=2,maxmem=256M" |
| 2760 | " -object memory-backend-ram,id=ram0,size=128M", |
| 2761 | &data); |
| 2762 | free_test_data(&data); |
| 2763 | } |
| 2764 | |
| 2765 | static void test_acpi_loongarch64_virt_oem_fields(void) |
| 2766 | { |
| 2767 | LOONGARCH64_INIT_TEST_DATA(data); |
| 2768 | char *args; |
| 2769 | |
| 2770 | args = test_acpi_create_args(&data, "-cpu la464 "OEM_TEST_ARGS); |
| 2771 | data.qts = qtest_init(args); |
| 2772 | test_acpi_load_tables(&data); |
| 2773 | test_oem_fields(&data); |
| 2774 | qtest_quit(data.qts); |
| 2775 | free_test_data(&data); |
| 2776 | g_free(args); |
| 2777 | } |
| 2778 | |
| 2779 | int main(int argc, char *argv[]) |
| 2780 | { |
| 2781 | const char *arch = qtest_get_arch(); |
| 2782 | bool has_kvm, has_tcg; |
| 2783 | char *v_env = getenv("V"); |
| 2784 | int ret; |
| 2785 | |
| 2786 | if (v_env) { |
| 2787 | verbosity_level = atoi(v_env); |
| 2788 | } |
| 2789 | |
| 2790 | g_test_init(&argc, &argv, NULL); |
| 2791 | |
| 2792 | has_kvm = qtest_has_accel("kvm"); |
| 2793 | has_tcg = qtest_has_accel("tcg"); |
| 2794 | |
| 2795 | if (!has_tcg && !has_kvm) { |
| 2796 | g_test_skip("No KVM or TCG accelerator available"); |
| 2797 | return 0; |
| 2798 | } |
| 2799 | |
| 2800 | if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) { |
| 2801 | ret = boot_sector_init(disk); |
| 2802 | if (ret) { |
| 2803 | return ret; |
| 2804 | } |
| 2805 | if (qtest_has_machine(MACHINE_PC)) { |
| 2806 | qtest_add_func("acpi/piix4", test_acpi_piix4_tcg); |
| 2807 | qtest_add_func("acpi/piix4/oem-fields", test_acpi_piix4_oem_fields); |
| 2808 | qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge); |
| 2809 | qtest_add_func("acpi/piix4/pci-hotplug/no_root_hotplug", |
| 2810 | test_acpi_piix4_no_root_hotplug); |
| 2811 | qtest_add_func("acpi/piix4/pci-hotplug/no_bridge_hotplug", |
| 2812 | test_acpi_piix4_no_bridge_hotplug); |
| 2813 | qtest_add_func("acpi/piix4/pci-hotplug/off", |
| 2814 | test_acpi_piix4_no_acpi_pci_hotplug); |
| 2815 | qtest_add_func("acpi/piix4/ipmi", test_acpi_piix4_tcg_ipmi); |
| 2816 | qtest_add_func("acpi/piix4/cpuhp", test_acpi_piix4_tcg_cphp); |
| 2817 | qtest_add_func("acpi/piix4/numamem", test_acpi_piix4_tcg_numamem); |
| 2818 | qtest_add_func("acpi/piix4/nosmm", test_acpi_piix4_tcg_nosmm); |
| 2819 | qtest_add_func("acpi/piix4/smm-compat", |
| 2820 | test_acpi_piix4_tcg_smm_compat); |
| 2821 | qtest_add_func("acpi/piix4/smm-compat-nosmm", |
| 2822 | test_acpi_piix4_tcg_smm_compat_nosmm); |
| 2823 | qtest_add_func("acpi/piix4/nohpet", test_acpi_piix4_tcg_nohpet); |
| 2824 | |
| 2825 | /* i386 does not support memory hotplug */ |
| 2826 | if (strcmp(arch, "i386")) { |
| 2827 | qtest_add_func("acpi/piix4/memhp", test_acpi_piix4_tcg_memhp); |
| 2828 | qtest_add_func("acpi/piix4/dimmpxm", |
| 2829 | test_acpi_piix4_tcg_dimm_pxm); |
| 2830 | qtest_add_func("acpi/piix4/acpihmat", |
| 2831 | test_acpi_piix4_tcg_acpi_hmat); |
| 2832 | } |
| 2833 | #ifdef CONFIG_POSIX |
| 2834 | qtest_add_func("acpi/piix4/acpierst", test_acpi_piix4_acpi_erst); |
| 2835 | #endif |
| 2836 | qtest_add_func("acpi/piix4/smbios-options", |
| 2837 | test_acpi_pc_smbios_options); |
| 2838 | qtest_add_func("acpi/piix4/smbios-blob", |
| 2839 | test_acpi_pc_smbios_blob); |
| 2840 | qtest_add_func("acpi/piix4/smbios-legacy", |
| 2841 | test_acpi_isapc_smbios_legacy); |
| 2842 | } |
| 2843 | if (qtest_has_machine(MACHINE_Q35)) { |
| 2844 | qtest_add_func("acpi/q35", test_acpi_q35_tcg); |
| 2845 | qtest_add_func("acpi/q35/oem-fields", test_acpi_q35_oem_fields); |
| 2846 | if (tpm_model_is_available("-machine q35", "tpm-tis")) { |
| 2847 | qtest_add_func("acpi/q35/tpm2-tis", test_acpi_q35_tcg_tpm2_tis); |
| 2848 | qtest_add_func("acpi/q35/tpm12-tis", |
| 2849 | test_acpi_q35_tcg_tpm12_tis); |
| 2850 | } |
| 2851 | qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge); |
| 2852 | qtest_add_func("acpi/q35/no-acpi-hotplug", |
| 2853 | test_acpi_q35_tcg_no_acpi_hotplug); |
| 2854 | qtest_add_func("acpi/q35/multif-bridge", |
| 2855 | test_acpi_q35_multif_bridge); |
| 2856 | qtest_add_func("acpi/q35/ipmi", test_acpi_q35_tcg_ipmi); |
| 2857 | qtest_add_func("acpi/q35/smbus/ipmi", test_acpi_q35_tcg_smbus_ipmi); |
| 2858 | qtest_add_func("acpi/q35/cpuhp", test_acpi_q35_tcg_cphp); |
| 2859 | qtest_add_func("acpi/q35/numamem", test_acpi_q35_tcg_numamem); |
| 2860 | qtest_add_func("acpi/q35/nosmm", test_acpi_q35_tcg_nosmm); |
| 2861 | qtest_add_func("acpi/q35/smm-compat", |
| 2862 | test_acpi_q35_tcg_smm_compat); |
| 2863 | qtest_add_func("acpi/q35/smm-compat-nosmm", |
| 2864 | test_acpi_q35_tcg_smm_compat_nosmm); |
| 2865 | qtest_add_func("acpi/q35/nohpet", test_acpi_q35_tcg_nohpet); |
| 2866 | qtest_add_func("acpi/q35/acpihmat-noinitiator", |
| 2867 | test_acpi_q35_tcg_acpi_hmat_noinitiator); |
| 2868 | qtest_add_func("acpi/q35/acpihmat-genericx", |
| 2869 | test_acpi_q35_tcg_acpi_hmat_generic_x); |
| 2870 | |
| 2871 | /* i386 does not support memory hotplug */ |
| 2872 | if (strcmp(arch, "i386")) { |
| 2873 | qtest_add_func("acpi/q35/memhp", test_acpi_q35_tcg_memhp); |
| 2874 | qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm); |
| 2875 | qtest_add_func("acpi/q35/sp-mem", test_acpi_q35_tcg_sp_mem); |
| 2876 | qtest_add_func("acpi/q35/acpihmat", |
| 2877 | test_acpi_q35_tcg_acpi_hmat); |
| 2878 | qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64); |
| 2879 | } |
| 2880 | #ifdef CONFIG_POSIX |
| 2881 | qtest_add_func("acpi/q35/acpierst", test_acpi_q35_acpi_erst); |
| 2882 | #endif |
| 2883 | qtest_add_func("acpi/q35/applesmc", test_acpi_q35_applesmc); |
| 2884 | qtest_add_func("acpi/q35/pvpanic-isa", test_acpi_q35_pvpanic_isa); |
| 2885 | if (has_tcg) { |
| 2886 | qtest_add_func("acpi/q35/ivrs", test_acpi_q35_tcg_ivrs); |
| 2887 | } |
| 2888 | if (has_kvm) { |
| 2889 | qtest_add_func("acpi/q35/kvm/xapic", test_acpi_q35_kvm_xapic); |
| 2890 | qtest_add_func("acpi/q35/kvm/dmar", test_acpi_q35_kvm_dmar); |
| 2891 | qtest_add_func("acpi/q35/type4-count", |
| 2892 | test_acpi_q35_kvm_type4_count); |
| 2893 | qtest_add_func("acpi/q35/core-count", |
| 2894 | test_acpi_q35_kvm_core_count); |
| 2895 | qtest_add_func("acpi/q35/core-count2", |
| 2896 | test_acpi_q35_kvm_core_count2); |
| 2897 | qtest_add_func("acpi/q35/thread-count", |
| 2898 | test_acpi_q35_kvm_thread_count); |
| 2899 | qtest_add_func("acpi/q35/thread-count2", |
| 2900 | test_acpi_q35_kvm_thread_count2); |
| 2901 | } |
| 2902 | if (qtest_has_device("virtio-iommu-pci")) { |
| 2903 | qtest_add_func("acpi/q35/viot", test_acpi_q35_viot); |
| 2904 | } |
| 2905 | #ifdef CONFIG_POSIX |
| 2906 | qtest_add_func("acpi/q35/cxl", test_acpi_q35_cxl); |
| 2907 | #endif |
| 2908 | qtest_add_func("acpi/q35/slic", test_acpi_q35_slic); |
| 2909 | qtest_add_func("acpi/q35/wdat", test_acpi_q35_wdat); |
| 2910 | } |
| 2911 | if (qtest_has_machine("microvm")) { |
| 2912 | qtest_add_func("acpi/microvm", test_acpi_microvm_tcg); |
| 2913 | qtest_add_func("acpi/microvm/usb", test_acpi_microvm_usb_tcg); |
| 2914 | qtest_add_func("acpi/microvm/rtc", test_acpi_microvm_rtc_tcg); |
| 2915 | qtest_add_func("acpi/microvm/ioapic2", |
| 2916 | test_acpi_microvm_ioapic2_tcg); |
| 2917 | qtest_add_func("acpi/microvm/oem-fields", |
| 2918 | test_acpi_microvm_oem_fields); |
| 2919 | if (has_tcg) { |
| 2920 | if (strcmp(arch, "x86_64") == 0) { |
| 2921 | qtest_add_func("acpi/microvm/pcie", |
| 2922 | test_acpi_microvm_pcie_tcg); |
| 2923 | #ifdef CONFIG_POSIX |
| 2924 | qtest_add_func("acpi/microvm/acpierst", |
| 2925 | test_acpi_microvm_acpi_erst); |
| 2926 | #endif |
| 2927 | } |
| 2928 | } |
| 2929 | } |
| 2930 | } else if (strcmp(arch, "aarch64") == 0) { |
| 2931 | if (has_tcg && qtest_has_device("virtio-blk-pci")) { |
| 2932 | qtest_add_func("acpi/virt", test_acpi_aarch64_virt_tcg); |
| 2933 | qtest_add_func("acpi/virt/acpihmatvirt", |
| 2934 | test_acpi_aarch64_virt_tcg_acpi_hmat); |
| 2935 | qtest_add_func("acpi/virt/topology", |
| 2936 | test_acpi_aarch64_virt_tcg_topology); |
| 2937 | qtest_add_func("acpi/virt/its_off", |
| 2938 | test_acpi_aarch64_virt_tcg_its_off); |
| 2939 | qtest_add_func("acpi/virt/msi_gicv2m", |
| 2940 | test_acpi_aarch64_virt_tcg_msi_gicv2m); |
| 2941 | qtest_add_func("acpi/virt/numamem", |
| 2942 | test_acpi_aarch64_virt_tcg_numamem); |
| 2943 | qtest_add_func("acpi/virt/memhp", test_acpi_aarch64_virt_tcg_memhp); |
| 2944 | qtest_add_func("acpi/virt/acpipcihp", |
| 2945 | test_acpi_aarch64_virt_acpi_pci_hotplug); |
| 2946 | qtest_add_func("acpi/virt/hpoffacpiindex", |
| 2947 | test_acpi_aarch64_virt_pcie_root_port_hpoff); |
| 2948 | qtest_add_func("acpi/virt/pxb", test_acpi_aarch64_virt_tcg_pxb); |
| 2949 | qtest_add_func("acpi/virt/oem-fields", |
| 2950 | test_acpi_aarch64_virt_oem_fields); |
| 2951 | qtest_add_func("acpi/virt/acpispcr", |
| 2952 | test_acpi_aarch64_virt_tcg_acpi_spcr); |
| 2953 | if (qtest_has_device("virtio-iommu-pci")) { |
| 2954 | qtest_add_func("acpi/virt/viot", test_acpi_aarch64_virt_viot); |
| 2955 | } |
| 2956 | qtest_add_func("acpi/virt/smmuv3-legacy", |
| 2957 | test_acpi_aarch64_virt_smmuv3_legacy); |
| 2958 | if (qtest_has_device("arm-smmuv3")) { |
| 2959 | qtest_add_func("acpi/virt/smmuv3-dev", |
| 2960 | test_acpi_aarch64_virt_smmuv3_dev); |
| 2961 | } |
| 2962 | qtest_add_func("acpi/virt/acpi-watchdog", |
| 2963 | test_acpi_aarch64_virt_tcg_wdat); |
| 2964 | qtest_add_func("acpi/virt/gwdt-watchdog", |
| 2965 | test_acpi_aarch64_virt_tcg_gtdt_wd); |
| 2966 | } |
| 2967 | } else if (strcmp(arch, "riscv64") == 0) { |
| 2968 | if (has_tcg && qtest_has_device("virtio-blk-pci")) { |
| 2969 | qtest_add_func("acpi/virt", test_acpi_riscv64_virt_tcg); |
| 2970 | qtest_add_func("acpi/virt/numamem", |
| 2971 | test_acpi_riscv64_virt_tcg_numamem); |
| 2972 | qtest_add_func("acpi/virt/acpispcr", |
| 2973 | test_acpi_riscv64_virt_tcg_acpi_spcr); |
| 2974 | } |
| 2975 | } else if (strcmp(arch, "loongarch64") == 0) { |
| 2976 | if (has_tcg && qtest_has_machine("virt")) { |
| 2977 | qtest_add_func("acpi/virt", test_acpi_loongarch64_virt); |
| 2978 | qtest_add_func("acpi/virt/topology", |
| 2979 | test_acpi_loongarch64_virt_topology); |
| 2980 | qtest_add_func("acpi/virt/numamem", |
| 2981 | test_acpi_loongarch64_virt_numamem); |
| 2982 | qtest_add_func("acpi/virt/memhp", test_acpi_loongarch64_virt_memhp); |
| 2983 | qtest_add_func("acpi/virt/oem-fields", |
| 2984 | test_acpi_loongarch64_virt_oem_fields); |
| 2985 | } |
| 2986 | } |
| 2987 | ret = g_test_run(); |
| 2988 | boot_sector_cleanup(disk); |
| 2989 | return ret; |
| 2990 | } |