From 1d939a68afe1673441250b495ed2e5f9b568a2fb Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:07 +0000 Subject: hw/arm/virt: Wire up memory region to CPUs explicitly Wire up the system memory region to the CPUs explicitly by setting the QOM property. This doesn't change anything over letting it default, but will be needed for adding a secure memory region later. Signed-off-by: Peter Maydell Reviewed-by: Edgar E. Iglesias Acked-by: Edgar E. Iglesias --- hw/arm/virt.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'hw/arm/virt.c') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 05f9087cca..82754dc80d 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1093,6 +1093,9 @@ static void machvirt_init(MachineState *machine) "reset-cbar", &error_abort); } + object_property_set_link(cpuobj, OBJECT(sysmem), "memory", + &error_abort); + object_property_set_bool(cpuobj, true, "realized", NULL); } g_strfreev(cpustr); -- cgit v1.2.3-55-g7522 From 3df708eb48180fcf11956b81fd6a036cd13ed5f1 Mon Sep 17 00:00:00 2001 From: Peter Maydell Date: Thu, 21 Jan 2016 14:15:07 +0000 Subject: hw/arm/virt: add secure memory region and UART Add a secure memory region to the virt board, which is the same as the nonsecure memory region except that it also has a secure-only UART in it. This is only created if the board is started with the '-machine secure=on' property. Signed-off-by: Peter Maydell Acked-by: Edgar E. Iglesias --- hw/arm/virt.c | 55 ++++++++++++++++++++++++++++++++++++++++++++------- include/hw/arm/virt.h | 1 + 2 files changed, 49 insertions(+), 7 deletions(-) (limited to 'hw/arm/virt.c') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 82754dc80d..134f452998 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -123,6 +123,7 @@ static const MemMapEntry a15memmap[] = { [VIRT_RTC] = { 0x09010000, 0x00001000 }, [VIRT_FW_CFG] = { 0x09020000, 0x00000018 }, [VIRT_GPIO] = { 0x09030000, 0x00001000 }, + [VIRT_SECURE_UART] = { 0x09040000, 0x00001000 }, [VIRT_MMIO] = { 0x0a000000, 0x00000200 }, /* ...repeating for a total of NUM_VIRTIO_TRANSPORTS, each of that size */ [VIRT_PLATFORM_BUS] = { 0x0c000000, 0x02000000 }, @@ -139,6 +140,7 @@ static const int a15irqmap[] = { [VIRT_RTC] = 2, [VIRT_PCIE] = 3, /* ... to 6 */ [VIRT_GPIO] = 7, + [VIRT_SECURE_UART] = 8, [VIRT_MMIO] = 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ [VIRT_GIC_V2M] = 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */ [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */ @@ -489,16 +491,22 @@ static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure) } } -static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) +static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic, int uart, + MemoryRegion *mem) { char *nodename; - hwaddr base = vbi->memmap[VIRT_UART].base; - hwaddr size = vbi->memmap[VIRT_UART].size; - int irq = vbi->irqmap[VIRT_UART]; + hwaddr base = vbi->memmap[uart].base; + hwaddr size = vbi->memmap[uart].size; + int irq = vbi->irqmap[uart]; const char compat[] = "arm,pl011\0arm,primecell"; const char clocknames[] = "uartclk\0apb_pclk"; + DeviceState *dev = qdev_create(NULL, "pl011"); + SysBusDevice *s = SYS_BUS_DEVICE(dev); - sysbus_create_simple("pl011", base, pic[irq]); + qdev_init_nofail(dev); + memory_region_add_subregion(mem, base, + sysbus_mmio_get_region(s, 0)); + sysbus_connect_irq(s, 0, pic[irq]); nodename = g_strdup_printf("/pl011@%" PRIx64, base); qemu_fdt_add_subnode(vbi->fdt, nodename); @@ -515,7 +523,14 @@ static void create_uart(const VirtBoardInfo *vbi, qemu_irq *pic) qemu_fdt_setprop(vbi->fdt, nodename, "clock-names", clocknames, sizeof(clocknames)); - qemu_fdt_setprop_string(vbi->fdt, "/chosen", "stdout-path", nodename); + if (uart == VIRT_UART) { + qemu_fdt_setprop_string(vbi->fdt, "/chosen", "stdout-path", nodename); + } else { + /* Mark as not usable by the normal world */ + qemu_fdt_setprop_string(vbi->fdt, nodename, "status", "disabled"); + qemu_fdt_setprop_string(vbi->fdt, nodename, "secure-status", "okay"); + } + g_free(nodename); } @@ -995,6 +1010,7 @@ static void machvirt_init(MachineState *machine) VirtMachineState *vms = VIRT_MACHINE(machine); qemu_irq pic[NUM_IRQS]; MemoryRegion *sysmem = get_system_memory(); + MemoryRegion *secure_sysmem = NULL; int gic_version = vms->gic_version; int n, max_cpus; MemoryRegion *ram = g_new(MemoryRegion, 1); @@ -1053,6 +1069,23 @@ static void machvirt_init(MachineState *machine) exit(1); } + if (vms->secure) { + if (kvm_enabled()) { + error_report("mach-virt: KVM does not support Security extensions"); + exit(1); + } + + /* The Secure view of the world is the same as the NonSecure, + * but with a few extra devices. Create it as a container region + * containing the system memory at low priority; any secure-only + * devices go in at higher priority and take precedence. + */ + secure_sysmem = g_new(MemoryRegion, 1); + memory_region_init(secure_sysmem, OBJECT(machine), "secure-memory", + UINT64_MAX); + memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1); + } + create_fdt(vbi); for (n = 0; n < smp_cpus; n++) { @@ -1095,6 +1128,10 @@ static void machvirt_init(MachineState *machine) object_property_set_link(cpuobj, OBJECT(sysmem), "memory", &error_abort); + if (vms->secure) { + object_property_set_link(cpuobj, OBJECT(secure_sysmem), + "secure-memory", &error_abort); + } object_property_set_bool(cpuobj, true, "realized", NULL); } @@ -1111,7 +1148,11 @@ static void machvirt_init(MachineState *machine) create_gic(vbi, pic, gic_version, vms->secure); - create_uart(vbi, pic); + create_uart(vbi, pic, VIRT_UART, sysmem); + + if (vms->secure) { + create_uart(vbi, pic, VIRT_SECURE_UART, secure_sysmem); + } create_rtc(vbi, pic); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 925faa7249..1ce7847ae6 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -60,6 +60,7 @@ enum { VIRT_PLATFORM_BUS, VIRT_PCIE_MMIO_HIGH, VIRT_GPIO, + VIRT_SECURE_UART, }; typedef struct MemMapEntry { -- cgit v1.2.3-55-g7522 From caa49adbccffb7d50cdd8d0faf0d88647901998b Mon Sep 17 00:00:00 2001 From: Christoffer Dall Date: Thu, 21 Jan 2016 14:15:07 +0000 Subject: hw/arm/virt: Add always-on property to the virt board timer The virt board has an arch timer, which is always on. Emit the "always-on" property to indicate to Linux that it can switch off the periodic timer and reduces the amount of interrupts injected into a guest. Signed-off-by: Christoffer Dall Reviewed-by: Andrew Jones Message-id: 1453204158-11412-1-git-send-email-christoffer.dall@linaro.org Signed-off-by: Peter Maydell --- hw/arm/virt.c | 1 + 1 file changed, 1 insertion(+) (limited to 'hw/arm/virt.c') diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 134f452998..15658f49c4 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -293,6 +293,7 @@ static void fdt_add_timer_nodes(const VirtBoardInfo *vbi, int gictype) qemu_fdt_setprop_string(vbi->fdt, "/timer", "compatible", "arm,armv7-timer"); } + qemu_fdt_setprop(vbi->fdt, "/timer", "always-on", NULL, 0); qemu_fdt_setprop_cells(vbi->fdt, "/timer", "interrupts", GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_S_EL1_IRQ, irqflags, GIC_FDT_IRQ_TYPE_PPI, ARCH_TIMER_NS_EL1_IRQ, irqflags, -- cgit v1.2.3-55-g7522