Skip to content

Commit

Permalink
acpi: extend aml_interrupt() to support multiple irqs
Browse files Browse the repository at this point in the history
ASL Interrupt() macro translates to Extended Interrupt Descriptor
which supports variable number of IRQs. It will be used for
conversion of ASL code for pc/q35 machines that use it for
returning several IRQs in _PSR object.

Signed-off-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Shannon Zhao <shannon.zhao@linaro.org>
Signed-off-by: Shannon Zhao <shannon.zhao@linaro.org>
Message-id: 1449804086-3464-3-git-send-email-zhaoshenglong@huawei.com
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
  • Loading branch information
Igor Mammedov authored and pm215 committed Dec 17, 2015
1 parent 4dbfc88 commit 45fcf53
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 21 deletions.
22 changes: 13 additions & 9 deletions hw/acpi/aml-build.c
Expand Up @@ -598,23 +598,27 @@ Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
AmlLevelAndEdge level_and_edge,
AmlActiveHighAndLow high_and_low, AmlShared shared,
uint32_t irq)
uint32_t *irq_list, uint8_t irq_count)
{
int i;
Aml *var = aml_alloc();
uint8_t irq_flags = con_and_pro | (level_and_edge << 1)
| (high_and_low << 2) | (shared << 3);
const int header_bytes_in_len = 2;
uint16_t len = header_bytes_in_len + irq_count * sizeof(uint32_t);

assert(irq_count > 0);

build_append_byte(var->buf, 0x89); /* Extended irq descriptor */
build_append_byte(var->buf, 6); /* Length, bits[7:0] minimum value = 6 */
build_append_byte(var->buf, 0); /* Length, bits[15:8] minimum value = 0 */
build_append_byte(var->buf, len & 0xFF); /* Length, bits[7:0] */
build_append_byte(var->buf, len >> 8); /* Length, bits[15:8] */
build_append_byte(var->buf, irq_flags); /* Interrupt Vector Information. */
build_append_byte(var->buf, 0x01); /* Interrupt table length = 1 */
build_append_byte(var->buf, irq_count); /* Interrupt table length */

/* Interrupt Number */
build_append_byte(var->buf, extract32(irq, 0, 8)); /* bits[7:0] */
build_append_byte(var->buf, extract32(irq, 8, 8)); /* bits[15:8] */
build_append_byte(var->buf, extract32(irq, 16, 8)); /* bits[23:16] */
build_append_byte(var->buf, extract32(irq, 24, 8)); /* bits[31:24] */
/* Interrupt Number List */
for (i = 0; i < irq_count; i++) {
build_append_int_noprefix(var->buf, irq_list[i], 4);
}
return var;
}

Expand Down
23 changes: 12 additions & 11 deletions hw/arm/virt-acpi-build.c
Expand Up @@ -71,7 +71,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")));
Expand All @@ -82,7 +82,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
Expand All @@ -94,7 +94,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")));
Expand All @@ -105,7 +105,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);
}
Expand Down Expand Up @@ -136,14 +136,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)));
Expand All @@ -152,15 +152,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;
Expand Down Expand Up @@ -199,18 +199,19 @@ 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, AML_NOTSERIALIZED);
aml_append(dev_gsi, method);
Expand Down
2 changes: 1 addition & 1 deletion include/hw/acpi/aml-build.h
Expand Up @@ -223,7 +223,7 @@ Aml *aml_memory32_fixed(uint32_t addr, uint32_t size,
Aml *aml_interrupt(AmlConsumerAndProducer con_and_pro,
AmlLevelAndEdge level_and_edge,
AmlActiveHighAndLow high_and_low, AmlShared shared,
uint32_t irq);
uint32_t *irq_list, uint8_t irq_count);
Aml *aml_io(AmlIODecode dec, uint16_t min_base, uint16_t max_base,
uint8_t aln, uint8_t len);
Aml *aml_operation_region(const char *name, AmlRegionSpace rs,
Expand Down

0 comments on commit 45fcf53

Please sign in to comment.