diff options
author | Loic Poulain <loic.poulain@linaro.org> | 2020-02-10 22:56:13 +0100 |
---|---|---|
committer | Loic Poulain <loic.poulain@linaro.org> | 2020-02-10 22:56:13 +0100 |
commit | 4e5922c13eaef1203751a5d9442ff946c9a4d523 (patch) | |
tree | 09e5a679b1f121ecde26d3b025b09914ecb13f8d | |
parent | fb2246882a2c8d7f084ebe0617e97ac78467d156 (diff) |
hw: arm: virt: Add secondary uart and i2c
secure uart as secondary uart if non-secure
i2c controller + tmp105 sensor.
Signed-off-by: Loic Poulain <loic.poulain@linaro.org>
-rw-r--r-- | hw/arm/virt.c | 47 | ||||
-rw-r--r-- | include/hw/arm/virt.h | 1 |
2 files changed, 48 insertions, 0 deletions
diff --git a/hw/arm/virt.c b/hw/arm/virt.c index d4bedc2607..e59843186c 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -42,6 +42,7 @@ #include "hw/vfio/vfio-calxeda-xgmac.h" #include "hw/vfio/vfio-amd-xgbe.h" #include "hw/display/ramfb.h" +#include "hw/i2c/i2c.h" #include "net/net.h" #include "sysemu/device_tree.h" #include "sysemu/numa.h" @@ -137,6 +138,7 @@ static const MemMapEntry base_memmap[] = { [VIRT_GIC_REDIST] = { 0x080A0000, 0x00F60000 }, [VIRT_UART] = { 0x09000000, 0x00001000 }, [VIRT_RTC] = { 0x09010000, 0x00001000 }, + [VIRT_I2C] = { 0x0901A000, 0x00001000 }, [VIRT_FW_CFG] = { 0x09020000, 0x00000018 }, [VIRT_GPIO] = { 0x09030000, 0x00001000 }, [VIRT_SECURE_UART] = { 0x09040000, 0x00001000 }, @@ -754,6 +756,9 @@ static void create_uart(const VirtMachineState *vms, qemu_irq *pic, int uart, if (uart == VIRT_UART) { qemu_fdt_setprop_string(vms->fdt, "/chosen", "stdout-path", nodename); + qemu_fdt_setprop_string(vms->fdt, "/aliases", "serial0", nodename); + } else if (!vms->secure) { + qemu_fdt_setprop_string(vms->fdt, "/aliases", "serial1", nodename); } else { /* Mark as not usable by the normal world */ qemu_fdt_setprop_string(vms->fdt, nodename, "status", "disabled"); @@ -846,6 +851,39 @@ static void create_gpio(const VirtMachineState *vms, qemu_irq *pic) g_free(nodename); } +static void create_i2c(const VirtMachineState *vms, qemu_irq *pic) +{ + hwaddr base = vms->memmap[VIRT_I2C].base; + hwaddr size = vms->memmap[VIRT_I2C].size; + hwaddr i2c_addr = 0x48; + const char compat1[] = "arm,versatile-i2c"; + const char compat2[] = "ti,tmp105"; + DeviceState *dev; + char *nodename; + I2CBus *i2c; + + dev = sysbus_create_simple("versatile_i2c", base, NULL); + i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); + dev = i2c_create_slave(i2c, "tmp105", i2c_addr); + object_property_set_int(OBJECT(dev), 31000, "temperature", &error_abort); + + uint32_t phandle = qemu_fdt_alloc_phandle(vms->fdt); + nodename = g_strdup_printf("/i2c@%" PRIx64, base); + qemu_fdt_add_subnode(vms->fdt, nodename); + qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", 2, base, 2, size); + qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat1, sizeof(compat1)); + qemu_fdt_setprop_cell(vms->fdt, nodename, "#address-cells", 1); + qemu_fdt_setprop_cell(vms->fdt, nodename, "#size-cells", 0); + qemu_fdt_setprop_cell(vms->fdt, nodename, "phandle", phandle); + g_free(nodename); + + nodename = g_strdup_printf("/i2c@%" PRIx64 "/temp@%" PRIx64, base, i2c_addr); + qemu_fdt_add_subnode(vms->fdt, nodename); + qemu_fdt_setprop(vms->fdt, nodename, "compatible", compat2, sizeof(compat2)); + qemu_fdt_setprop_cell(vms->fdt, nodename, "reg", i2c_addr); + g_free(nodename); +} + static void create_virtio_devices(const VirtMachineState *vms, qemu_irq *pic) { int i; @@ -1716,11 +1754,18 @@ static void machvirt_init(MachineState *machine) fdt_add_pmu_nodes(vms); + qemu_fdt_add_subnode(vms->fdt, "/aliases"); create_uart(vms, pic, VIRT_UART, sysmem, serial_hd(0)); if (vms->secure) { create_secure_ram(vms, secure_sysmem); create_uart(vms, pic, VIRT_SECURE_UART, secure_sysmem, serial_hd(1)); + } else { + /* + * If secure mode is disabled then let's setup the "secure" + * UART so that normal world can use it. + */ + create_uart(vms, pic, VIRT_SECURE_UART, sysmem, serial_hd(1)); } vms->highmem_ecam &= vms->highmem && (!firmware_loaded || aarch64); @@ -1735,6 +1780,8 @@ static void machvirt_init(MachineState *machine) create_gpio(vms, pic); } + create_i2c(vms, pic); + /* connect powerdown request */ vms->powerdown_notifier.notify = virt_powerdown_req; qemu_register_powerdown_notifier(&vms->powerdown_notifier); diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 0b41083e9d..bfa12c14aa 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -68,6 +68,7 @@ enum { VIRT_UART, VIRT_MMIO, VIRT_RTC, + VIRT_I2C, VIRT_FW_CFG, VIRT_PCIE, VIRT_PCIE_MMIO, |