From f272a95646635a08a8bacdc64ca968282e0f20de Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Tue, 19 Sep 2023 17:38:10 +0100 Subject: add to acpi table Signed-off-by: Peter Maydell --- hw/arm/virt-acpi-build.c | 12 ++++++++---- hw/arm/virt.c | 43 +++++++++++++++++++++++++------------------ include/hw/arm/virt.h | 1 + 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 ', 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 ', 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; -- cgit v1.2.3