Commit 6775d15d authored by Jon Doron's avatar Jon Doron Committed by Paolo Bonzini
Browse files

i386: Hyper-V VMBus ACPI DSDT entry



Guest OS uses ACPI to discover VMBus presence.  Add a corresponding
entry to DSDT in case VMBus has been enabled.

Experimentally Windows guests were found to require this entry to
include two IRQ resources. They seem to never be used but they still
have to be there.

Make IRQ numbers user-configurable via corresponding properties; use 7
and 13 by default.

Signed-off-by: default avatarEvgeny Yakovlev <eyakovlev@virtuozzo.com>
Signed-off-by: default avatarRoman Kagan <rkagan@virtuozzo.com>
Signed-off-by: default avatarMaciej S. Szmigiero <maciej.szmigiero@oracle.com>
Signed-off-by: default avatarJon Doron <arilou@gmail.com>
Message-Id: <20200424123444.3481728-6-arilou@gmail.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent cab78e7c
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -2641,6 +2641,12 @@ static const VMStateDescription vmstate_vmbus_bridge = {
    },
};

static Property vmbus_bridge_props[] = {
    DEFINE_PROP_UINT8("irq0", VMBusBridge, irq0, 7),
    DEFINE_PROP_UINT8("irq1", VMBusBridge, irq1, 13),
    DEFINE_PROP_END_OF_LIST()
};

static void vmbus_bridge_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *k = DEVICE_CLASS(klass);
@@ -2651,6 +2657,7 @@ static void vmbus_bridge_class_init(ObjectClass *klass, void *data)
    sk->explicit_ofw_unit_address = vmbus_bridge_ofw_unit_address;
    set_bit(DEVICE_CATEGORY_BRIDGE, k->categories);
    k->vmsd = &vmstate_vmbus_bridge;
    device_class_set_props(k, vmbus_bridge_props);
    /* override SysBusDevice's default */
    k->user_creatable = true;
}
+43 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@
#include "hw/mem/nvdimm.h"
#include "sysemu/numa.h"
#include "sysemu/reset.h"
#include "hw/hyperv/vmbus-bridge.h"

/* Supported chipsets: */
#include "hw/southbridge/piix.h"
@@ -1270,9 +1271,47 @@ static Aml *build_com_device_aml(uint8_t uid)
    return dev;
}

static Aml *build_vmbus_device_aml(VMBusBridge *vmbus_bridge)
{
    Aml *dev;
    Aml *method;
    Aml *crs;

    dev = aml_device("VMBS");
    aml_append(dev, aml_name_decl("STA", aml_int(0xF)));
    aml_append(dev, aml_name_decl("_HID", aml_string("VMBus")));
    aml_append(dev, aml_name_decl("_UID", aml_int(0x0)));
    aml_append(dev, aml_name_decl("_DDN", aml_string("VMBUS")));

    method = aml_method("_DIS", 0, AML_NOTSERIALIZED);
    aml_append(method, aml_store(aml_and(aml_name("STA"), aml_int(0xD), NULL),
                                     aml_name("STA")));
    aml_append(dev, method);

    method = aml_method("_PS0", 0, AML_NOTSERIALIZED);
    aml_append(method, aml_store(aml_or(aml_name("STA"), aml_int(0xF), NULL),
                                     aml_name("STA")));
    aml_append(dev, method);

    method = aml_method("_STA", 0, AML_NOTSERIALIZED);
    aml_append(method, aml_return(aml_name("STA")));
    aml_append(dev, method);

    aml_append(dev, aml_name_decl("_PS3", aml_int(0x0)));

    crs = aml_resource_template();
    aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq0));
    /* FIXME: newer HyperV gets by with only one IRQ */
    aml_append(crs, aml_irq_no_flags(vmbus_bridge->irq1));
    aml_append(dev, aml_name_decl("_CRS", crs));

    return dev;
}

static void build_isa_devices_aml(Aml *table)
{
    ISADevice *fdc = pc_find_fdc0();
    VMBusBridge *vmbus_bridge = vmbus_bridge_find();
    bool ambiguous;

    Aml *scope = aml_scope("_SB.PCI0.ISA");
@@ -1297,6 +1336,10 @@ static void build_isa_devices_aml(Aml *table)
        isa_build_aml(ISA_BUS(obj), scope);
    }

    if (vmbus_bridge) {
        aml_append(scope, build_vmbus_device_aml(vmbus_bridge));
    }

    aml_append(table, scope);
}

+3 −0
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@ typedef struct VMBus VMBus;
typedef struct VMBusBridge {
    SysBusDevice parent_obj;

    uint8_t irq0;
    uint8_t irq1;

    VMBus *bus;
} VMBusBridge;