Commit 1962f31b authored by Shameer Kolothum's avatar Shameer Kolothum Committed by Michael S. Tsirkin
Browse files

hw/arm: Use GED for system_powerdown event



For machines 4.2 or higher with ACPI boot use GED for system_powerdown
event instead of GPIO. Guest boot with DT still uses GPIO.

Signed-off-by: default avatarShameer Kolothum <shameerali.kolothum.thodi@huawei.com>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Reviewed-by: default avatarIgor Mammedov <imammedo@redhat.com>
Message-Id: <20190918130633.4872-9-shameerali.kolothum.thodi@huawei.com>
Acked-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Reviewed-by: default avatarMichael S. Tsirkin <mst@redhat.com>
Signed-off-by: default avatarMichael S. Tsirkin <mst@redhat.com>
parent c345680c
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@

static const uint32_t ged_supported_events[] = {
    ACPI_GED_MEM_HOTPLUG_EVT,
    ACPI_GED_PWR_DOWN_EVT,
};

/*
@@ -104,6 +105,11 @@ void build_ged_aml(Aml *table, const char *name, HotplugHandler *hotplug_dev,
                aml_append(if_ctx, aml_call0(MEMORY_DEVICES_CONTAINER "."
                                             MEMORY_SLOT_SCAN_METHOD));
                break;
            case ACPI_GED_PWR_DOWN_EVT:
                aml_append(if_ctx,
                           aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
                                      aml_int(0x80)));
                break;
            default:
                /*
                 * Please make sure all the events in ged_supported_events[]
@@ -184,6 +190,8 @@ static void acpi_ged_send_event(AcpiDeviceIf *adev, AcpiEventStatusBits ev)

    if (ev & ACPI_MEMORY_HOTPLUG_STATUS) {
        sel = ACPI_GED_MEM_HOTPLUG_EVT;
    } else if (ev & ACPI_POWER_DOWN_STATUS) {
        sel = ACPI_GED_PWR_DOWN_EVT;
    } else {
        /* Unknown event. Return without generating interrupt. */
        warn_report("GED: Unsupported event %d. No irq injected", ev);
+3 −3
Original line number Diff line number Diff line
@@ -50,7 +50,6 @@
#include "migration/vmstate.h"

#define ARM_SPI_BASE 32
#define ACPI_POWER_BUTTON_DEVICE "PWRB"

static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus)
{
@@ -741,13 +740,14 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
                    (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
    acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
                      vms->highmem, vms->highmem_ecam);
    acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
                       (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
    if (vms->acpi_dev) {
        build_ged_aml(scope, "\\_SB."GED_DEVICE,
                      HOTPLUG_HANDLER(vms->acpi_dev),
                      irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
                      memmap[VIRT_ACPI_GED].base);
    } else {
        acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
                           (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
    }

    if (vms->acpi_dev) {
+12 −6
Original line number Diff line number Diff line
@@ -536,10 +536,10 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms, qemu_irq *pic)
    DeviceState *dev;
    MachineState *ms = MACHINE(vms);
    int irq = vms->irqmap[VIRT_ACPI_GED];
    uint32_t event = 0;
    uint32_t event = ACPI_GED_PWR_DOWN_EVT;

    if (ms->ram_slots) {
        event = ACPI_GED_MEM_HOTPLUG_EVT;
        event |= ACPI_GED_MEM_HOTPLUG_EVT;
    }

    dev = qdev_create(NULL, TYPE_ACPI_GED);
@@ -793,9 +793,15 @@ static void create_rtc(const VirtMachineState *vms, qemu_irq *pic)
static DeviceState *gpio_key_dev;
static void virt_powerdown_req(Notifier *n, void *opaque)
{
    VirtMachineState *s = container_of(n, VirtMachineState, powerdown_notifier);

    if (s->acpi_dev) {
        acpi_send_event(s->acpi_dev, ACPI_POWER_DOWN_STATUS);
    } else {
        /* use gpio Pin 3 for power button event */
        qemu_set_irq(qdev_get_gpio_in(gpio_key_dev, 0), 1);
    }
}

static void create_gpio(const VirtMachineState *vms, qemu_irq *pic)
{
@@ -1723,10 +1729,10 @@ static void machvirt_init(MachineState *machine)

    create_pcie(vms, pic);

    create_gpio(vms, pic);

    if (has_ged && aarch64 && firmware_loaded && acpi_enabled) {
        vms->acpi_dev = create_acpi_ged(vms, pic);
    } else {
        create_gpio(vms, pic);
    }

     /* connect powerdown request */
+1 −0
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@ typedef enum {
    ACPI_MEMORY_HOTPLUG_STATUS = 8,
    ACPI_NVDIMM_HOTPLUG_STATUS = 16,
    ACPI_VMGENID_CHANGE_STATUS = 32,
    ACPI_POWER_DOWN_STATUS = 64,
} AcpiEventStatusBits;

#define TYPE_ACPI_DEVICE_IF "acpi-device-interface"
+3 −0
Original line number Diff line number Diff line
@@ -62,6 +62,8 @@
#include "hw/sysbus.h"
#include "hw/acpi/memory_hotplug.h"

#define ACPI_POWER_BUTTON_DEVICE "PWRB"

#define TYPE_ACPI_GED "acpi-ged"
#define ACPI_GED(obj) \
    OBJECT_CHECK(AcpiGedState, (obj), TYPE_ACPI_GED)
@@ -79,6 +81,7 @@
 * through GED.
 */
#define ACPI_GED_MEM_HOTPLUG_EVT   0x1
#define ACPI_GED_PWR_DOWN_EVT      0x2

typedef struct GEDState {
    MemoryRegion io;