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