summaryrefslogtreecommitdiffstats
path: root/hw/arm/virt-acpi-build.c
diff options
context:
space:
mode:
authorIgor Mammedov2021-09-24 14:27:58 +0200
committerMichael S. Tsirkin2021-10-05 23:30:57 +0200
commita86d86ac0ae39b7e8fcce08fffd2e0ab5aa287df (patch)
tree0ca939a5b02b6d2bae396eee817629ab9160038e /hw/arm/virt-acpi-build.c
parentacpi: arm/virt: build_spcr: fix invalid cast (diff)
downloadqemu-a86d86ac0ae39b7e8fcce08fffd2e0ab5aa287df.tar.gz
qemu-a86d86ac0ae39b7e8fcce08fffd2e0ab5aa287df.tar.xz
qemu-a86d86ac0ae39b7e8fcce08fffd2e0ab5aa287df.zip
acpi: arm/virt: build_spcr: use acpi_table_begin()/acpi_table_end() instead of build_header()
it replaces error-prone pointer arithmetic for build_header() API, with 2 calls to start and finish table creation, which hides offsets magic from API user. while at it, replace packed structure with endian agnostic build_append_FOO() API. PS: Spec is Microsoft hosted, however 1.02 is no where to be found (MS lists only the current revision) and the current revision is 1.07, so bring comments in line with 1.07 as this is the only available spec. There is no content change between originally implemented 1.02 (using QEMU code as reference) and 1.07. The only change is renaming 'Reserved2' field to 'Language', with the same 0 value. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Eric Auger <eric.auger@redhat.com> Message-Id: <20210924122802.1455362-32-imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/arm/virt-acpi-build.c')
-rw-r--r--hw/arm/virt-acpi-build.c68
1 files changed, 41 insertions, 27 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 7b8706b305..7b79fae0ad 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -453,39 +453,53 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
g_array_free(its_idmaps, true);
}
+/*
+ * Serial Port Console Redirection Table (SPCR)
+ * Rev: 1.07
+ */
static void
build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
{
- AcpiSerialPortConsoleRedirection *spcr;
- const MemMapEntry *uart_memmap = &vms->memmap[VIRT_UART];
- int irq = vms->irqmap[VIRT_UART] + ARM_SPI_BASE;
- int spcr_start = table_data->len;
-
- spcr = acpi_data_push(table_data, sizeof(*spcr));
-
- spcr->interface_type = 0x3; /* ARM PL011 UART */
-
- spcr->base_address.space_id = AML_AS_SYSTEM_MEMORY;
- spcr->base_address.bit_width = 8;
- spcr->base_address.bit_offset = 0;
- spcr->base_address.access_width = 1;
- spcr->base_address.address = cpu_to_le64(uart_memmap->base);
-
- spcr->interrupt_types = (1 << 3); /* Bit[3] ARMH GIC interrupt */
- spcr->gsi = cpu_to_le32(irq); /* Global System Interrupt */
+ AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = vms->oem_id,
+ .oem_table_id = vms->oem_table_id };
- spcr->baud = 3; /* Baud Rate: 3 = 9600 */
- spcr->parity = 0; /* No Parity */
- spcr->stopbits = 1; /* 1 Stop bit */
- spcr->flowctrl = (1 << 1); /* Bit[1] = RTS/CTS hardware flow control */
- spcr->term_type = 0; /* Terminal Type: 0 = VT100 */
+ acpi_table_begin(&table, table_data);
- spcr->pci_device_id = 0xffff; /* PCI Device ID: not a PCI device */
- spcr->pci_vendor_id = 0xffff; /* PCI Vendor ID: not a PCI device */
+ /* Interface Type */
+ build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */
+ build_append_int_noprefix(table_data, 0, 3); /* Reserved */
+ /* Base Address */
+ build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1,
+ vms->memmap[VIRT_UART].base);
+ /* Interrupt Type */
+ build_append_int_noprefix(table_data,
+ (1 << 3) /* Bit[3] ARMH GIC interrupt */, 1);
+ build_append_int_noprefix(table_data, 0, 1); /* IRQ */
+ /* Global System Interrupt */
+ build_append_int_noprefix(table_data,
+ vms->irqmap[VIRT_UART] + ARM_SPI_BASE, 4);
+ build_append_int_noprefix(table_data, 3 /* 9600 */, 1); /* Baud Rate */
+ build_append_int_noprefix(table_data, 0 /* No Parity */, 1); /* Parity */
+ /* Stop Bits */
+ build_append_int_noprefix(table_data, 1 /* 1 Stop bit */, 1);
+ /* Flow Control */
+ build_append_int_noprefix(table_data,
+ (1 << 1) /* RTS/CTS hardware flow control */, 1);
+ /* Terminal Type */
+ build_append_int_noprefix(table_data, 0 /* VT100 */, 1);
+ build_append_int_noprefix(table_data, 0, 1); /* Language */
+ /* PCI Device ID */
+ build_append_int_noprefix(table_data, 0xffff /* not a PCI device*/, 2);
+ /* PCI Vendor ID */
+ build_append_int_noprefix(table_data, 0xffff /* not a PCI device*/, 2);
+ build_append_int_noprefix(table_data, 0, 1); /* PCI Bus Number */
+ build_append_int_noprefix(table_data, 0, 1); /* PCI Device Number */
+ build_append_int_noprefix(table_data, 0, 1); /* PCI Function Number */
+ build_append_int_noprefix(table_data, 0, 4); /* PCI Flags */
+ build_append_int_noprefix(table_data, 0, 1); /* PCI Segment */
+ build_append_int_noprefix(table_data, 0, 4); /* Reserved */
- build_header(linker, table_data, (void *)(table_data->data + spcr_start),
- "SPCR", table_data->len - spcr_start, 2, vms->oem_id,
- vms->oem_table_id);
+ acpi_table_end(linker, &table);
}
/*