aboutsummaryrefslogtreecommitdiff
path: root/hw/arm/virt.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/arm/virt.c')
-rw-r--r--hw/arm/virt.c63
1 files changed, 55 insertions, 8 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index c7a1f75..0784ee7 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -165,11 +165,11 @@ static const MemMapEntry base_memmap[] = {
[VIRT_GIC_ITS] = { 0x08080000, 0x00020000 },
/* This redistributor space allows up to 2*64kB*123 CPUs */
[VIRT_GIC_REDIST] = { 0x080A0000, 0x00F60000 },
- [VIRT_UART] = { 0x09000000, 0x00001000 },
+ [VIRT_UART0] = { 0x09000000, 0x00001000 },
[VIRT_RTC] = { 0x09010000, 0x00001000 },
[VIRT_FW_CFG] = { 0x09020000, 0x00000018 },
[VIRT_GPIO] = { 0x09030000, 0x00001000 },
- [VIRT_SECURE_UART] = { 0x09040000, 0x00001000 },
+ [VIRT_UART1] = { 0x09040000, 0x00001000 },
[VIRT_SMMU] = { 0x09050000, 0x00020000 },
[VIRT_PCDIMM_ACPI] = { 0x09070000, MEMORY_HOTPLUG_IO_LEN },
[VIRT_ACPI_GED] = { 0x09080000, ACPI_GED_EVT_SEL_LEN },
@@ -212,11 +212,11 @@ static MemMapEntry extended_memmap[] = {
};
static const int a15irqmap[] = {
- [VIRT_UART] = 1,
+ [VIRT_UART0] = 1,
[VIRT_RTC] = 2,
[VIRT_PCIE] = 3, /* ... to 6 */
[VIRT_GPIO] = 7,
- [VIRT_SECURE_UART] = 8,
+ [VIRT_UART1] = 8,
[VIRT_ACPI_GED] = 9,
[VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */
[VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */
@@ -271,6 +271,17 @@ static void create_fdt(VirtMachineState *vms)
qemu_fdt_setprop_cell(fdt, "/", "#size-cells", 0x2);
qemu_fdt_setprop_string(fdt, "/", "model", "linux,dummy-virt");
+ /*
+ * For QEMU, all DMA is coherent. Advertising this in the root node
+ * has two benefits:
+ *
+ * - It avoids potential bugs where we forget to mark a DMA
+ * capable device as being dma-coherent
+ * - It avoids spurious warnings from the Linux kernel about
+ * devices which can't do DMA at all
+ */
+ qemu_fdt_setprop(fdt, "/", "dma-coherent", NULL, 0);
+
/* /chosen must exist for load_dtb to fill in necessary properties later */
qemu_fdt_add_subnode(fdt, "/chosen");
if (vms->dtb_randomness) {
@@ -284,6 +295,8 @@ static void create_fdt(VirtMachineState *vms)
}
}
+ qemu_fdt_add_subnode(fdt, "/aliases");
+
/* Clock node, for the benefit of the UART. The kernel device tree
* binding documentation claims the PL011 node clock properties are
* optional but in practice if you omit them the kernel refuses to
@@ -904,7 +917,7 @@ static void create_gic(VirtMachineState *vms, MemoryRegion *mem)
}
static void create_uart(const VirtMachineState *vms, int uart,
- MemoryRegion *mem, Chardev *chr)
+ MemoryRegion *mem, Chardev *chr, bool secure)
{
char *nodename;
hwaddr base = vms->memmap[uart].base;
@@ -937,9 +950,13 @@ static void create_uart(const VirtMachineState *vms, int uart,
qemu_fdt_setprop(ms->fdt, nodename, "clock-names",
clocknames, sizeof(clocknames));
- if (uart == VIRT_UART) {
+ if (uart == VIRT_UART0) {
qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
+ qemu_fdt_setprop_string(ms->fdt, "/aliases", "serial0", nodename);
} else {
+ qemu_fdt_setprop_string(ms->fdt, "/aliases", "serial1", nodename);
+ }
+ if (secure) {
/* Mark as not usable by the normal world */
qemu_fdt_setprop_string(ms->fdt, nodename, "status", "disabled");
qemu_fdt_setprop_string(ms->fdt, nodename, "secure-status", "okay");
@@ -2313,11 +2330,41 @@ static void machvirt_init(MachineState *machine)
fdt_add_pmu_nodes(vms);
- create_uart(vms, VIRT_UART, sysmem, serial_hd(0));
+ /*
+ * The first UART 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>'.
+ * This avoids potentially breaking existing user setups that expect
+ * only one NonSecure UART to be present (for instance, older EDK2
+ * binaries).
+ *
+ * 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) {
+ Chardev *serial1 = serial_hd(1);
+
+ if (serial1) {
+ vms->second_ns_uart_present = true;
+ create_uart(vms, VIRT_UART1, sysmem, serial1, false);
+ }
+ }
+ create_uart(vms, VIRT_UART0, sysmem, serial_hd(0), false);
+ if (vms->secure) {
+ create_uart(vms, VIRT_UART1, secure_sysmem, serial_hd(1), true);
+ }
if (vms->secure) {
create_secure_ram(vms, secure_sysmem, secure_tag_sysmem);
- create_uart(vms, VIRT_SECURE_UART, secure_sysmem, serial_hd(1));
}
if (tag_sysmem) {