const char *variant;
const char *uefi_fl1;
const char *uefi_fl2;
+ const char *blkdev;
const char *cd;
const uint64_t ram_start;
const uint64_t scan_len;
GArray *tables;
uint32_t smbios_ep_addr;
struct smbios_21_entry_point smbios_ep_table;
+ uint16_t smbios_cpu_max_speed;
+ uint16_t smbios_cpu_curr_speed;
uint8_t *required_struct_types;
int required_struct_types_len;
QTestState *qts;
}
}
+static bool smbios_cpu_test(test_data *data, uint32_t addr)
+{
+ uint16_t expect_speed[2];
+ uint16_t real;
+ int offset[2];
+ int i;
+
+ /* Check CPU speed for backward compatibility */
+ offset[0] = offsetof(struct smbios_type_4, max_speed);
+ offset[1] = offsetof(struct smbios_type_4, current_speed);
+ expect_speed[0] = data->smbios_cpu_max_speed ? : 2000;
+ expect_speed[1] = data->smbios_cpu_curr_speed ? : 2000;
+
+ for (i = 0; i < 2; i++) {
+ real = qtest_readw(data->qts, addr + offset[i]);
+ if (real != expect_speed[i]) {
+ fprintf(stderr, "Unexpected SMBIOS CPU speed: real %u expect %u\n",
+ real, expect_speed[i]);
+ return false;
+ }
+ }
+
+ return true;
+}
+
static void test_smbios_structs(test_data *data)
{
DECLARE_BITMAP(struct_bitmap, SMBIOS_MAX_TYPE+1) = { 0 };
}
set_bit(type, struct_bitmap);
+ if (type == 4) {
+ g_assert(smbios_cpu_test(data, addr));
+ }
+
/* seek to end of unformatted string area of this struct ("\0\0") */
prv = crt = 1;
while (prv || crt) {
data->uefi_fl1, data->uefi_fl2, data->cd, params ? params : "");
} else {
- /* Disable kernel irqchip to be able to override apic irq0. */
- args = g_strdup_printf("-machine %s,kernel-irqchip=off %s -accel tcg "
+ args = g_strdup_printf("-machine %s %s -accel tcg "
"-net none -display none %s "
"-drive id=hd0,if=none,file=%s,format=raw "
- "-device ide-hd,drive=hd0 ",
+ "-device %s,drive=hd0 ",
data->machine, data->tcg_only ? "" : "-accel kvm",
- params ? params : "", disk);
+ params ? params : "", disk,
+ data->blkdev ?: "ide-hd");
}
data->qts = qtest_init(args);
free_test_data(&data);
}
+static void test_acpi_piix4_no_root_hotplug(void)
+{
+ test_data data;
+
+ memset(&data, 0, sizeof(data));
+ data.machine = MACHINE_PC;
+ data.variant = ".roothp";
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
+ test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off "
+ "-device pci-bridge,chassis_nr=1", &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_piix4_no_bridge_hotplug(void)
+{
+ test_data data;
+
+ memset(&data, 0, sizeof(data));
+ data.machine = MACHINE_PC;
+ data.variant = ".hpbridge";
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
+ test_acpi_one("-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off "
+ "-device pci-bridge,chassis_nr=1", &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_piix4_no_acpi_pci_hotplug(void)
+{
+ test_data data;
+
+ memset(&data, 0, sizeof(data));
+ data.machine = MACHINE_PC;
+ data.variant = ".hpbrroot";
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
+ test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off "
+ "-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off "
+ "-device pci-bridge,chassis_nr=1", &data);
+ free_test_data(&data);
+}
+
static void test_acpi_q35_tcg(void)
{
test_data data;
data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
test_acpi_one(NULL, &data);
free_test_data(&data);
+
+ data.smbios_cpu_max_speed = 3000;
+ data.smbios_cpu_curr_speed = 2600;
+ test_acpi_one("-smbios type=4,max-speed=3000,current-speed=2600", &data);
+ free_test_data(&data);
}
static void test_acpi_q35_tcg_bridge(void)
}
+static void test_acpi_microvm_prepare(test_data *data)
+{
+ memset(data, 0, sizeof(*data));
+ data->machine = "microvm";
+ data->required_struct_types = NULL; /* no smbios */
+ data->required_struct_types_len = 0;
+ data->blkdev = "virtio-blk-device";
+}
+
+static void test_acpi_microvm_tcg(void)
+{
+ test_data data;
+
+ test_acpi_microvm_prepare(&data);
+ test_acpi_one(" -machine microvm,acpi=on,rtc=off",
+ &data);
+ free_test_data(&data);
+}
+
+static void test_acpi_microvm_pcie_tcg(void)
+{
+ test_data data;
+
+ test_acpi_microvm_prepare(&data);
+ data.variant = ".pcie";
+ data.tcg_only = true; /* need constant host-phys-bits */
+ test_acpi_one(" -machine microvm,acpi=on,rtc=off,pcie=on",
+ &data);
+ free_test_data(&data);
+}
+
static void test_acpi_virt_tcg_numamem(void)
{
test_data data = {
test_acpi_one("-cpu cortex-a57", &data);
free_test_data(&data);
+
+ data.smbios_cpu_max_speed = 2900;
+ data.smbios_cpu_curr_speed = 2700;
+ test_acpi_one("-cpu cortex-a57 "
+ "-smbios type=4,max-speed=2900,current-speed=2700", &data);
+ free_test_data(&data);
}
int main(int argc, char *argv[])
qtest_add_func("acpi/q35/tpm-tis", test_acpi_q35_tcg_tpm_tis);
qtest_add_func("acpi/piix4", test_acpi_piix4_tcg);
qtest_add_func("acpi/piix4/bridge", test_acpi_piix4_tcg_bridge);
+ qtest_add_func("acpi/piix4/pci-hotplug/no_root_hotplug",
+ test_acpi_piix4_no_root_hotplug);
+ qtest_add_func("acpi/piix4/pci-hotplug/no_bridge_hotplug",
+ test_acpi_piix4_no_bridge_hotplug);
+ qtest_add_func("acpi/piix4/pci-hotplug/off",
+ test_acpi_piix4_no_acpi_pci_hotplug);
qtest_add_func("acpi/q35", test_acpi_q35_tcg);
qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
qtest_add_func("acpi/q35/dimmpxm", test_acpi_q35_tcg_dimm_pxm);
qtest_add_func("acpi/piix4/acpihmat", test_acpi_piix4_tcg_acpi_hmat);
qtest_add_func("acpi/q35/acpihmat", test_acpi_q35_tcg_acpi_hmat);
+ qtest_add_func("acpi/microvm", test_acpi_microvm_tcg);
+ if (strcmp(arch, "x86_64") == 0) {
+ qtest_add_func("acpi/microvm/pcie", test_acpi_microvm_pcie_tcg);
+ }
} else if (strcmp(arch, "aarch64") == 0) {
qtest_add_func("acpi/virt", test_acpi_virt_tcg);
qtest_add_func("acpi/virt/numamem", test_acpi_virt_tcg_numamem);