diff options
Diffstat (limited to 'hw/arm/virt-acpi-build.c')
-rw-r--r-- | hw/arm/virt-acpi-build.c | 77 |
1 files changed, 61 insertions, 16 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 8fd0b1c57b..32ec19e884 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -43,6 +43,7 @@ #include "hw/pci/pci.h" #define ARM_SPI_BASE 32 +#define ACPI_POWER_BUTTON_DEVICE "PWRB" typedef struct VirtAcpiCpuInfo { DECLARE_BITMAP(found_cpus, VIRT_ACPI_CPU_ID_LIMIT); @@ -71,7 +72,7 @@ static void acpi_dsdt_add_cpus(Aml *scope, int smp_cpus) } static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, - int uart_irq) + uint32_t uart_irq) { Aml *dev = aml_device("COM0"); aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0011"))); @@ -82,7 +83,7 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, uart_memmap->size, AML_READ_WRITE)); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, uart_irq)); + AML_EXCLUSIVE, &uart_irq, 1)); aml_append(dev, aml_name_decl("_CRS", crs)); /* The _ADR entry is used to link this device to the UART described @@ -94,7 +95,7 @@ static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, } static void acpi_dsdt_add_rtc(Aml *scope, const MemMapEntry *rtc_memmap, - int rtc_irq) + uint32_t rtc_irq) { Aml *dev = aml_device("RTC0"); aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0013"))); @@ -105,7 +106,7 @@ static void acpi_dsdt_add_rtc(Aml *scope, const MemMapEntry *rtc_memmap, rtc_memmap->size, AML_READ_WRITE)); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, rtc_irq)); + AML_EXCLUSIVE, &rtc_irq, 1)); aml_append(dev, aml_name_decl("_CRS", crs)); aml_append(scope, dev); } @@ -136,14 +137,14 @@ static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap) static void acpi_dsdt_add_virtio(Aml *scope, const MemMapEntry *virtio_mmio_memmap, - int mmio_irq, int num) + uint32_t mmio_irq, int num) { hwaddr base = virtio_mmio_memmap->base; hwaddr size = virtio_mmio_memmap->size; - int irq = mmio_irq; int i; for (i = 0; i < num; i++) { + uint32_t irq = mmio_irq + i; Aml *dev = aml_device("VR%02u", i); aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005"))); aml_append(dev, aml_name_decl("_UID", aml_int(i))); @@ -152,15 +153,15 @@ static void acpi_dsdt_add_virtio(Aml *scope, aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE)); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, irq + i)); + AML_EXCLUSIVE, &irq, 1)); aml_append(dev, aml_name_decl("_CRS", crs)); aml_append(scope, dev); base += size; } } -static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq, - bool use_highmem) +static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, + uint32_t irq, bool use_highmem) { Aml *method, *crs, *ifctx, *UUID, *ifctx1, *elsectx, *buf; int i, bus_no; @@ -199,29 +200,30 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq, /* Create GSI link device */ for (i = 0; i < PCI_NUM_PINS; i++) { + uint32_t irqs = irq + i; Aml *dev_gsi = aml_device("GSI%d", i); aml_append(dev_gsi, aml_name_decl("_HID", aml_string("PNP0C0F"))); aml_append(dev_gsi, aml_name_decl("_UID", aml_int(0))); crs = aml_resource_template(); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, irq + i)); + AML_EXCLUSIVE, &irqs, 1)); aml_append(dev_gsi, aml_name_decl("_PRS", crs)); crs = aml_resource_template(); aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, - AML_EXCLUSIVE, irq + i)); + AML_EXCLUSIVE, &irqs, 1)); aml_append(dev_gsi, aml_name_decl("_CRS", crs)); - method = aml_method("_SRS", 1); + method = aml_method("_SRS", 1, AML_NOTSERIALIZED); aml_append(dev_gsi, method); aml_append(dev, dev_gsi); } - method = aml_method("_CBA", 0); + method = aml_method("_CBA", 0, AML_NOTSERIALIZED); aml_append(method, aml_return(aml_int(base_ecam))); aml_append(dev, method); - method = aml_method("_CRS", 0); + method = aml_method("_CRS", 0, AML_NOTSERIALIZED); Aml *rbuf = aml_resource_template(); aml_append(rbuf, aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE, @@ -254,7 +256,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq, /* Declare an _OSC (OS Control Handoff) method */ aml_append(dev, aml_name_decl("SUPP", aml_int(0))); aml_append(dev, aml_name_decl("CTRL", aml_int(0))); - method = aml_method("_OSC", 4); + method = aml_method("_OSC", 4, AML_NOTSERIALIZED); aml_append(method, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1")); @@ -296,7 +298,7 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq, aml_append(method, elsectx); aml_append(dev, method); - method = aml_method("_DSM", 4); + method = aml_method("_DSM", 4, AML_NOTSERIALIZED); /* PCI Firmware Specification 3.0 * 4.6.1. _DSM for PCI Express Slot Information @@ -323,6 +325,46 @@ static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap, int irq, aml_append(scope, dev); } +static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap, + uint32_t gpio_irq) +{ + Aml *dev = aml_device("GPO0"); + aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061"))); + aml_append(dev, aml_name_decl("_ADR", aml_int(0))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + + Aml *crs = aml_resource_template(); + aml_append(crs, aml_memory32_fixed(gpio_memmap->base, gpio_memmap->size, + AML_READ_WRITE)); + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, &gpio_irq, 1)); + aml_append(dev, aml_name_decl("_CRS", crs)); + + Aml *aei = aml_resource_template(); + /* Pin 3 for power button */ + const uint32_t pin_list[1] = {3}; + aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH, + AML_EXCLUSIVE, AML_PULL_UP, 0, pin_list, 1, + "GPO0", NULL, 0)); + aml_append(dev, aml_name_decl("_AEI", aei)); + + /* _E03 is handle for power button */ + Aml *method = aml_method("_E03", 0, AML_NOTSERIALIZED); + aml_append(method, aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE), + aml_int(0x80))); + aml_append(dev, method); + aml_append(scope, dev); +} + +static void acpi_dsdt_add_power_button(Aml *scope) +{ + Aml *dev = aml_device(ACPI_POWER_BUTTON_DEVICE); + aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C0C"))); + aml_append(dev, aml_name_decl("_ADR", aml_int(0))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + aml_append(scope, dev); +} + /* RSDP */ static GArray * build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt) @@ -539,6 +581,9 @@ build_dsdt(GArray *table_data, GArray *linker, VirtGuestInfo *guest_info) (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS); acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE), guest_info->use_highmem); + acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO], + (irqmap[VIRT_GPIO] + ARM_SPI_BASE)); + acpi_dsdt_add_power_button(scope); aml_append(dsdt, scope); |