aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2023-09-19 17:38:10 +0100
committerPeter Maydell <peter.maydell@linaro.org>2023-09-21 11:22:56 +0100
commitf272a95646635a08a8bacdc64ca968282e0f20de (patch)
tree60fd7c42134498b3cffe23ff6a17fd61d4cd1586
parentef702e803c86083c0be391f08e3bfe606e4e66b4 (diff)
add to acpi table
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--hw/arm/virt-acpi-build.c12
-rw-r--r--hw/arm/virt.c43
-rw-r--r--include/hw/arm/virt.h1
3 files changed, 34 insertions, 22 deletions
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 83ae739a12..de9b98029a 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -77,11 +77,11 @@ static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
}
static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
- uint32_t uart_irq)
+ uint32_t uart_irq, int uartidx)
{
- Aml *dev = aml_device("COM0");
+ Aml *dev = aml_device("COM%d", uartidx);
aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0011")));
- aml_append(dev, aml_name_decl("_UID", aml_int(0)));
+ aml_append(dev, aml_name_decl("_UID", aml_int(uartidx)));
Aml *crs = aml_resource_template();
aml_append(crs, aml_memory32_fixed(uart_memmap->base,
@@ -860,7 +860,11 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
scope = aml_scope("\\_SB");
acpi_dsdt_add_cpus(scope, vms);
acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0],
- (irqmap[VIRT_UART0] + ARM_SPI_BASE));
+ (irqmap[VIRT_UART0] + ARM_SPI_BASE), 0);
+ if (vms->second_uart_present) {
+ acpi_dsdt_add_uart(scope, &memmap[VIRT_UART1],
+ (irqmap[VIRT_UART1] + ARM_SPI_BASE), 1);
+ }
if (vmc->acpi_expose_flash) {
acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
}
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a036d3fa76..63dbfb937a 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -857,21 +857,9 @@ static void create_uart(const VirtMachineState *vms, int uart,
MemoryRegion *mem, Chardev *chr)
{
char *nodename;
- /*
- * The first UART always always exists. If the security extensions are
- * enabled, the second UART also always exists. Otherwise, it only exists
- * if a backend is configured explicitly via '-serial <backend>', where
- * 'null' creates a dummy backend. This allows enabling the second UART
- * explicitly on demand and does not interfere with any existing setup that
- * just expect one (or two if security extensions are enabled) UARTs.
- */
switch(uart) {
case VIRT_UART0:
- break;
case VIRT_UART1:
- if (!vms->secure && !chr) {
- return;
- }
break;
default:
error_report("unsupported UART ID %d", uart);
@@ -2301,17 +2289,36 @@ static void machvirt_init(MachineState *machine)
fdt_add_pmu_nodes(vms);
/*
- * These end up in the DTB in reverse order of creation, so
- * we must create UART0 last to ensure it appears as the
- * first TTYAMA0 for Linux.
- * For back-compatibility, if UART1 is the secure UART and
- * thus always created, we create it second.
+ * The first UART always always exists. If the security extensions are
+ * enabled, the second UART also always exists. Otherwise, it only exists
+ * if a backend is configured explicitly via '-serial <backend>', where
+ * 'null' creates a dummy backend. This allows enabling the second UART
+ * explicitly on demand and does not interfere with any existing setup that
+ * just expect one (or two if security extensions are enabled) UARTs.
+ *
+ * The nodes end up in the DTB in reverse order of creation, so we must
+ * create UART0 last to ensure it appears as the first node in the DTB,
+ * for compatibility with guest software that just iterates through the
+ * DTB to find the first UART, as older versions of EDK2 do.
+ * DTB readers that follow the spec, as Linux does, should honour the
+ * aliases node information and /chosen/stdout-path regardless of
+ * the order that nodes appear in the DTB.
+ *
+ * For similar back-compatibility reasons, if UART1 is the secure UART
+ * we create it second (and so it appears first in the DTB), because
+ * that's what QEMU has always done.
*/
if (!vms->secure) {
- create_uart(vms, VIRT_UART1, sysmem, serial_hd(1));
+ Chardev *serial1 = serial_hd(1);
+
+ if (serial1) {
+ vms->second_uart_present = true;
+ create_uart(vms, VIRT_UART1, sysmem, serial1);
+ }
}
create_uart(vms, VIRT_UART0, sysmem, serial_hd(0));
if (vms->secure) {
+ vms->second_uart_present = true;
create_uart(vms, VIRT_UART1, secure_sysmem, serial_hd(1));
}
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index ddad477d50..3628c532cb 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -160,6 +160,7 @@ struct VirtMachineState {
bool ras;
bool mte;
bool dtb_randomness;
+ bool second_uart_present;
OnOffAuto acpi;
VirtGICType gic_version;
VirtIOMMUType iommu;