From bb80ae077ebcc7e0cdc0f7e2ec663896b6103da1 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:43 +0100 Subject: hw/clock: Remove unused clock_init*() functions clock_init*() inlined funtions are simple wrappers around clock_set*() and are not used. Remove them in favor of clock_set*(). Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20200806123858.30058-2-f4bug@amsat.org Signed-off-by: Peter Maydell --- include/hw/clock.h | 13 ------------- 1 file changed, 13 deletions(-) (limited to 'include/hw') diff --git a/include/hw/clock.h b/include/hw/clock.h index f822a94220..468fed0996 100644 --- a/include/hw/clock.h +++ b/include/hw/clock.h @@ -209,17 +209,4 @@ static inline bool clock_is_enabled(const Clock *clk) return clock_get(clk) != 0; } -static inline void clock_init(Clock *clk, uint64_t value) -{ - clock_set(clk, value); -} -static inline void clock_init_hz(Clock *clk, uint64_t value) -{ - clock_set_hz(clk, value); -} -static inline void clock_init_ns(Clock *clk, uint64_t value) -{ - clock_set_ns(clk, value); -} - #endif /* QEMU_HW_CLOCK_H */ -- cgit v1.2.3-55-g7522 From 15aa2876d9c7181c58305430f726461a2f24cb00 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:44 +0100 Subject: hw/clock: Let clock_set() return boolean value Let clock_set() return a boolean value whether the clock has been updated or not. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20200806123858.30058-3-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/core/clock.c | 7 ++++++- include/hw/clock.h | 12 +++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) (limited to 'include/hw') diff --git a/hw/core/clock.c b/hw/core/clock.c index 3c0daf7d4c..7066282f7b 100644 --- a/hw/core/clock.c +++ b/hw/core/clock.c @@ -34,11 +34,16 @@ void clock_clear_callback(Clock *clk) clock_set_callback(clk, NULL, NULL); } -void clock_set(Clock *clk, uint64_t period) +bool clock_set(Clock *clk, uint64_t period) { + if (clk->period == period) { + return false; + } trace_clock_set(CLOCK_PATH(clk), CLOCK_PERIOD_TO_NS(clk->period), CLOCK_PERIOD_TO_NS(period)); clk->period = period; + + return true; } static void clock_propagate_period(Clock *clk, bool call_callbacks) diff --git a/include/hw/clock.h b/include/hw/clock.h index 468fed0996..d85af45c96 100644 --- a/include/hw/clock.h +++ b/include/hw/clock.h @@ -127,17 +127,19 @@ void clock_set_source(Clock *clk, Clock *src); * @value: the clock's value, 0 means unclocked * * Set the local cached period value of @clk to @value. + * + * @return: true if the clock is changed. */ -void clock_set(Clock *clk, uint64_t value); +bool clock_set(Clock *clk, uint64_t value); -static inline void clock_set_hz(Clock *clk, unsigned hz) +static inline bool clock_set_hz(Clock *clk, unsigned hz) { - clock_set(clk, CLOCK_PERIOD_FROM_HZ(hz)); + return clock_set(clk, CLOCK_PERIOD_FROM_HZ(hz)); } -static inline void clock_set_ns(Clock *clk, unsigned ns) +static inline bool clock_set_ns(Clock *clk, unsigned ns) { - clock_set(clk, CLOCK_PERIOD_FROM_NS(ns)); + return clock_set(clk, CLOCK_PERIOD_FROM_NS(ns)); } /** -- cgit v1.2.3-55-g7522 From 96250eab904261b31d9d1ac3abbdb36737635ffa Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:44 +0100 Subject: hw/clock: Only propagate clock changes if the clock is changed Avoid propagating the clock change when the clock does not change. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Message-id: 20200806123858.30058-4-f4bug@amsat.org Signed-off-by: Peter Maydell --- include/hw/clock.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/hw') diff --git a/include/hw/clock.h b/include/hw/clock.h index d85af45c96..9ecd78b2c3 100644 --- a/include/hw/clock.h +++ b/include/hw/clock.h @@ -165,8 +165,9 @@ void clock_propagate(Clock *clk); */ static inline void clock_update(Clock *clk, uint64_t value) { - clock_set(clk, value); - clock_propagate(clk); + if (clock_set(clk, value)) { + clock_propagate(clk); + } } static inline void clock_update_hz(Clock *clk, unsigned hz) -- cgit v1.2.3-55-g7522 From b3aec952bf11ef54376db96dd673c6a34753b697 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:45 +0100 Subject: hw/sd/allwinner-sdhost: Use AddressSpace for DMA transfers Allow the device to execute the DMA transfers in a different AddressSpace. The A10 and H3 SoC keep using the system_memory address space, but via the proper dma_memory_access() API. Signed-off-by: Philippe Mathieu-Daudé Tested-by: Niek Linnenbank Reviewed-by: Niek Linnenbank Message-id: 20200814110057.307-1-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/arm/allwinner-a10.c | 2 ++ hw/arm/allwinner-h3.c | 2 ++ hw/sd/allwinner-sdhost.c | 37 +++++++++++++++++++++++++++++++------ include/hw/sd/allwinner-sdhost.h | 6 ++++++ 4 files changed, 41 insertions(+), 6 deletions(-) (limited to 'include/hw') diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index e258463747..d404f31e02 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -155,6 +155,8 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) } /* SD/MMC */ + object_property_set_link(OBJECT(&s->mmc0), "dma-memory", + OBJECT(get_system_memory()), &error_fatal); sysbus_realize(SYS_BUS_DEVICE(&s->mmc0), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc0), 0, AW_A10_MMC0_BASE); sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc0), 0, qdev_get_gpio_in(dev, 32)); diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c index ff92ded82c..43a8d3dc48 100644 --- a/hw/arm/allwinner-h3.c +++ b/hw/arm/allwinner-h3.c @@ -349,6 +349,8 @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(SYS_BUS_DEVICE(&s->sid), 0, s->memmap[AW_H3_SID]); /* SD/MMC */ + object_property_set_link(OBJECT(&s->mmc0), "dma-memory", + OBJECT(get_system_memory()), &error_fatal); sysbus_realize(SYS_BUS_DEVICE(&s->mmc0), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(&s->mmc0), 0, s->memmap[AW_H3_MMC0]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc0), 0, diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c index f9eb92c09e..e82afb75eb 100644 --- a/hw/sd/allwinner-sdhost.c +++ b/hw/sd/allwinner-sdhost.c @@ -21,7 +21,10 @@ #include "qemu/log.h" #include "qemu/module.h" #include "qemu/units.h" +#include "qapi/error.h" #include "sysemu/blockdev.h" +#include "sysemu/dma.h" +#include "hw/qdev-properties.h" #include "hw/irq.h" #include "hw/sd/allwinner-sdhost.h" #include "migration/vmstate.h" @@ -306,7 +309,7 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s, uint8_t buf[1024]; /* Read descriptor */ - cpu_physical_memory_read(desc_addr, desc, sizeof(*desc)); + dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc)); if (desc->size == 0) { desc->size = klass->max_desc_size; } else if (desc->size > klass->max_desc_size) { @@ -331,22 +334,24 @@ static uint32_t allwinner_sdhost_process_desc(AwSdHostState *s, /* Write to SD bus */ if (is_write) { - cpu_physical_memory_read((desc->addr & DESC_SIZE_MASK) + num_done, - buf, buf_bytes); + dma_memory_read(&s->dma_as, + (desc->addr & DESC_SIZE_MASK) + num_done, + buf, buf_bytes); sdbus_write_data(&s->sdbus, buf, buf_bytes); /* Read from SD bus */ } else { sdbus_read_data(&s->sdbus, buf, buf_bytes); - cpu_physical_memory_write((desc->addr & DESC_SIZE_MASK) + num_done, - buf, buf_bytes); + dma_memory_write(&s->dma_as, + (desc->addr & DESC_SIZE_MASK) + num_done, + buf, buf_bytes); } num_done += buf_bytes; } /* Clear hold flag and flush descriptor */ desc->status &= ~DESC_STATUS_HOLD; - cpu_physical_memory_write(desc_addr, desc, sizeof(*desc)); + dma_memory_write(&s->dma_as, desc_addr, desc, sizeof(*desc)); return num_done; } @@ -721,6 +726,12 @@ static const VMStateDescription vmstate_allwinner_sdhost = { } }; +static Property allwinner_sdhost_properties[] = { + DEFINE_PROP_LINK("dma-memory", AwSdHostState, dma_mr, + TYPE_MEMORY_REGION, MemoryRegion *), + DEFINE_PROP_END_OF_LIST(), +}; + static void allwinner_sdhost_init(Object *obj) { AwSdHostState *s = AW_SDHOST(obj); @@ -734,6 +745,18 @@ static void allwinner_sdhost_init(Object *obj) sysbus_init_irq(SYS_BUS_DEVICE(s), &s->irq); } +static void allwinner_sdhost_realize(DeviceState *dev, Error **errp) +{ + AwSdHostState *s = AW_SDHOST(dev); + + if (!s->dma_mr) { + error_setg(errp, TYPE_AW_SDHOST " 'dma-memory' link not set"); + return; + } + + address_space_init(&s->dma_as, s->dma_mr, "sdhost-dma"); +} + static void allwinner_sdhost_reset(DeviceState *dev) { AwSdHostState *s = AW_SDHOST(dev); @@ -792,6 +815,8 @@ static void allwinner_sdhost_class_init(ObjectClass *klass, void *data) dc->reset = allwinner_sdhost_reset; dc->vmsd = &vmstate_allwinner_sdhost; + dc->realize = allwinner_sdhost_realize; + device_class_set_props(dc, allwinner_sdhost_properties); } static void allwinner_sdhost_sun4i_class_init(ObjectClass *klass, void *data) diff --git a/include/hw/sd/allwinner-sdhost.h b/include/hw/sd/allwinner-sdhost.h index d94606a853..839732ebf3 100644 --- a/include/hw/sd/allwinner-sdhost.h +++ b/include/hw/sd/allwinner-sdhost.h @@ -71,6 +71,12 @@ typedef struct AwSdHostState { /** Interrupt output signal to notify CPU */ qemu_irq irq; + /** Memory region where DMA transfers are done */ + MemoryRegion *dma_mr; + + /** Address space used internally for DMA transfers */ + AddressSpace dma_as; + /** Number of bytes left in current DMA transfer */ uint32_t transfer_cnt; -- cgit v1.2.3-55-g7522 From 4757cb857934a5e2dcafe1f41e95233f5c0a878d Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:45 +0100 Subject: hw/net/allwinner-sun8i-emac: Use AddressSpace for DMA transfers Allow the device to execute the DMA transfers in a different AddressSpace. The H3 SoC keeps using the system_memory address space, but via the proper dma_memory_access() API. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Reviewed-by: Niek Linnenbank Tested-by: Niek Linnenbank Message-id: 20200814122907.27732-1-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/arm/allwinner-h3.c | 2 ++ hw/net/allwinner-sun8i-emac.c | 46 +++++++++++++++++++++++------------ include/hw/net/allwinner-sun8i-emac.h | 6 +++++ 3 files changed, 38 insertions(+), 16 deletions(-) (limited to 'include/hw') diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c index 43a8d3dc48..76ac51a3ef 100644 --- a/hw/arm/allwinner-h3.c +++ b/hw/arm/allwinner-h3.c @@ -365,6 +365,8 @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp) qemu_check_nic_model(&nd_table[0], TYPE_AW_SUN8I_EMAC); qdev_set_nic_properties(DEVICE(&s->emac), &nd_table[0]); } + object_property_set_link(OBJECT(&s->emac), "dma-memory", + OBJECT(get_system_memory()), &error_fatal); sysbus_realize(SYS_BUS_DEVICE(&s->emac), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(&s->emac), 0, s->memmap[AW_H3_EMAC]); sysbus_connect_irq(SYS_BUS_DEVICE(&s->emac), 0, diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c index 28637ff4c1..38d328587e 100644 --- a/hw/net/allwinner-sun8i-emac.c +++ b/hw/net/allwinner-sun8i-emac.c @@ -19,6 +19,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "migration/vmstate.h" #include "net/net.h" @@ -29,6 +30,7 @@ #include "net/checksum.h" #include "qemu/module.h" #include "exec/cpu-common.h" +#include "sysemu/dma.h" #include "hw/net/allwinner-sun8i-emac.h" /* EMAC register offsets */ @@ -337,12 +339,13 @@ static void allwinner_sun8i_emac_update_irq(AwSun8iEmacState *s) qemu_set_irq(s->irq, (s->int_sta & s->int_en) != 0); } -static uint32_t allwinner_sun8i_emac_next_desc(FrameDescriptor *desc, +static uint32_t allwinner_sun8i_emac_next_desc(AwSun8iEmacState *s, + FrameDescriptor *desc, size_t min_size) { uint32_t paddr = desc->next; - cpu_physical_memory_read(paddr, desc, sizeof(*desc)); + dma_memory_read(&s->dma_as, paddr, desc, sizeof(*desc)); if ((desc->status & DESC_STATUS_CTL) && (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) { @@ -352,7 +355,8 @@ static uint32_t allwinner_sun8i_emac_next_desc(FrameDescriptor *desc, } } -static uint32_t allwinner_sun8i_emac_get_desc(FrameDescriptor *desc, +static uint32_t allwinner_sun8i_emac_get_desc(AwSun8iEmacState *s, + FrameDescriptor *desc, uint32_t start_addr, size_t min_size) { @@ -360,7 +364,7 @@ static uint32_t allwinner_sun8i_emac_get_desc(FrameDescriptor *desc, /* Note that the list is a cycle. Last entry points back to the head. */ while (desc_addr != 0) { - cpu_physical_memory_read(desc_addr, desc, sizeof(*desc)); + dma_memory_read(&s->dma_as, desc_addr, desc, sizeof(*desc)); if ((desc->status & DESC_STATUS_CTL) && (desc->status2 & DESC_STATUS2_BUF_SIZE_MASK) >= min_size) { @@ -379,20 +383,21 @@ static uint32_t allwinner_sun8i_emac_rx_desc(AwSun8iEmacState *s, FrameDescriptor *desc, size_t min_size) { - return allwinner_sun8i_emac_get_desc(desc, s->rx_desc_curr, min_size); + return allwinner_sun8i_emac_get_desc(s, desc, s->rx_desc_curr, min_size); } static uint32_t allwinner_sun8i_emac_tx_desc(AwSun8iEmacState *s, FrameDescriptor *desc, size_t min_size) { - return allwinner_sun8i_emac_get_desc(desc, s->tx_desc_head, min_size); + return allwinner_sun8i_emac_get_desc(s, desc, s->tx_desc_head, min_size); } -static void allwinner_sun8i_emac_flush_desc(FrameDescriptor *desc, +static void allwinner_sun8i_emac_flush_desc(AwSun8iEmacState *s, + FrameDescriptor *desc, uint32_t phys_addr) { - cpu_physical_memory_write(phys_addr, desc, sizeof(*desc)); + dma_memory_write(&s->dma_as, phys_addr, desc, sizeof(*desc)); } static bool allwinner_sun8i_emac_can_receive(NetClientState *nc) @@ -450,8 +455,8 @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc, << RX_DESC_STATUS_FRM_LEN_SHIFT; } - cpu_physical_memory_write(desc.addr, buf, desc_bytes); - allwinner_sun8i_emac_flush_desc(&desc, s->rx_desc_curr); + dma_memory_write(&s->dma_as, desc.addr, buf, desc_bytes); + allwinner_sun8i_emac_flush_desc(s, &desc, s->rx_desc_curr); trace_allwinner_sun8i_emac_receive(s->rx_desc_curr, desc.addr, desc_bytes); @@ -465,7 +470,7 @@ static ssize_t allwinner_sun8i_emac_receive(NetClientState *nc, bytes_left -= desc_bytes; /* Move to the next descriptor */ - s->rx_desc_curr = allwinner_sun8i_emac_next_desc(&desc, 64); + s->rx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 64); if (!s->rx_desc_curr) { /* Not enough buffer space available */ s->int_sta |= INT_STA_RX_BUF_UA; @@ -501,10 +506,10 @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s) desc.status |= TX_DESC_STATUS_LENGTH_ERR; break; } - cpu_physical_memory_read(desc.addr, packet_buf + packet_bytes, bytes); + dma_memory_read(&s->dma_as, desc.addr, packet_buf + packet_bytes, bytes); packet_bytes += bytes; desc.status &= ~DESC_STATUS_CTL; - allwinner_sun8i_emac_flush_desc(&desc, s->tx_desc_curr); + allwinner_sun8i_emac_flush_desc(s, &desc, s->tx_desc_curr); /* After the last descriptor, send the packet */ if (desc.status2 & TX_DESC_STATUS2_LAST_DESC) { @@ -519,7 +524,7 @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s) packet_bytes = 0; transmitted++; } - s->tx_desc_curr = allwinner_sun8i_emac_next_desc(&desc, 0); + s->tx_desc_curr = allwinner_sun8i_emac_next_desc(s, &desc, 0); } /* Raise transmit completed interrupt */ @@ -623,7 +628,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset, break; case REG_TX_CUR_BUF: /* Transmit Current Buffer */ if (s->tx_desc_curr != 0) { - cpu_physical_memory_read(s->tx_desc_curr, &desc, sizeof(desc)); + dma_memory_read(&s->dma_as, s->tx_desc_curr, &desc, sizeof(desc)); value = desc.addr; } else { value = 0; @@ -636,7 +641,7 @@ static uint64_t allwinner_sun8i_emac_read(void *opaque, hwaddr offset, break; case REG_RX_CUR_BUF: /* Receive Current Buffer */ if (s->rx_desc_curr != 0) { - cpu_physical_memory_read(s->rx_desc_curr, &desc, sizeof(desc)); + dma_memory_read(&s->dma_as, s->rx_desc_curr, &desc, sizeof(desc)); value = desc.addr; } else { value = 0; @@ -790,6 +795,13 @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp) { AwSun8iEmacState *s = AW_SUN8I_EMAC(dev); + if (!s->dma_mr) { + error_setg(errp, TYPE_AW_SUN8I_EMAC " 'dma-memory' link not set"); + return; + } + + address_space_init(&s->dma_as, s->dma_mr, "emac-dma"); + qemu_macaddr_default_if_unset(&s->conf.macaddr); s->nic = qemu_new_nic(&net_allwinner_sun8i_emac_info, &s->conf, object_get_typename(OBJECT(dev)), dev->id, s); @@ -799,6 +811,8 @@ static void allwinner_sun8i_emac_realize(DeviceState *dev, Error **errp) static Property allwinner_sun8i_emac_properties[] = { DEFINE_NIC_PROPERTIES(AwSun8iEmacState, conf), DEFINE_PROP_UINT8("phy-addr", AwSun8iEmacState, mii_phy_addr, 0), + DEFINE_PROP_LINK("dma-memory", AwSun8iEmacState, dma_mr, + TYPE_MEMORY_REGION, MemoryRegion *), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/net/allwinner-sun8i-emac.h b/include/hw/net/allwinner-sun8i-emac.h index eda034e96b..dd1d7b96cd 100644 --- a/include/hw/net/allwinner-sun8i-emac.h +++ b/include/hw/net/allwinner-sun8i-emac.h @@ -49,6 +49,12 @@ typedef struct AwSun8iEmacState { /** Interrupt output signal to notify CPU */ qemu_irq irq; + /** Memory region where DMA transfers are done */ + MemoryRegion *dma_mr; + + /** Address space used internally for DMA transfers */ + AddressSpace dma_as; + /** Generic Network Interface Controller (NIC) for networking API */ NICState *nic; -- cgit v1.2.3-55-g7522 From 31a171cc8bc9d8524469c286c744dabe70f0c924 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:45 +0100 Subject: hw/arm/xilinx_zynq: Uninline cadence_uart_create() As we want to call qdev_connect_clock_in() before the device is realized, we need to uninline cadence_uart_create() first. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-id: 20200803105647.22223-2-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/arm/xilinx_zynq.c | 14 ++++++++++++-- include/hw/char/cadence_uart.h | 17 ----------------- 2 files changed, 12 insertions(+), 19 deletions(-) (limited to 'include/hw') diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index 32aa7323d9..cf6d9757b5 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -254,10 +254,20 @@ static void zynq_init(MachineState *machine) sysbus_create_simple(TYPE_CHIPIDEA, 0xE0002000, pic[53 - IRQ_OFFSET]); sysbus_create_simple(TYPE_CHIPIDEA, 0xE0003000, pic[76 - IRQ_OFFSET]); - dev = cadence_uart_create(0xE0000000, pic[59 - IRQ_OFFSET], serial_hd(0)); + dev = qdev_new(TYPE_CADENCE_UART); + busdev = SYS_BUS_DEVICE(dev); + qdev_prop_set_chr(dev, "chardev", serial_hd(0)); + sysbus_realize_and_unref(busdev, &error_fatal); + sysbus_mmio_map(busdev, 0, 0xE0000000); + sysbus_connect_irq(busdev, 0, pic[59 - IRQ_OFFSET]); qdev_connect_clock_in(dev, "refclk", qdev_get_clock_out(slcr, "uart0_ref_clk")); - dev = cadence_uart_create(0xE0001000, pic[82 - IRQ_OFFSET], serial_hd(1)); + dev = qdev_new(TYPE_CADENCE_UART); + busdev = SYS_BUS_DEVICE(dev); + qdev_prop_set_chr(dev, "chardev", serial_hd(1)); + sysbus_realize_and_unref(busdev, &error_fatal); + sysbus_mmio_map(busdev, 0, 0xE0001000); + sysbus_connect_irq(busdev, 0, pic[82 - IRQ_OFFSET]); qdev_connect_clock_in(dev, "refclk", qdev_get_clock_out(slcr, "uart1_ref_clk")); diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h index ed7b58d31d..dabc49ea4f 100644 --- a/include/hw/char/cadence_uart.h +++ b/include/hw/char/cadence_uart.h @@ -53,21 +53,4 @@ typedef struct { Clock *refclk; } CadenceUARTState; -static inline DeviceState *cadence_uart_create(hwaddr addr, - qemu_irq irq, - Chardev *chr) -{ - DeviceState *dev; - SysBusDevice *s; - - dev = qdev_new(TYPE_CADENCE_UART); - s = SYS_BUS_DEVICE(dev); - qdev_prop_set_chr(dev, "chardev", chr); - sysbus_realize_and_unref(s, &error_fatal); - sysbus_mmio_map(s, 0, addr); - sysbus_connect_irq(s, 0, irq); - - return dev; -} - #endif -- cgit v1.2.3-55-g7522 From f129360ca15723e43a8c44d1a2f025c0df1270cc Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:46 +0100 Subject: hw/qdev-clock: Uninline qdev_connect_clock_in() We want to assert the device is not realized. To avoid overloading this header including "hw/qdev-core.h", uninline the function first. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-id: 20200803105647.22223-4-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/core/qdev-clock.c | 5 +++++ include/hw/qdev-clock.h | 6 +----- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'include/hw') diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index 5cc1e82e51..f139b68b88 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -183,3 +183,8 @@ Clock *qdev_alias_clock(DeviceState *dev, const char *name, return ncl->clock; } + +void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source) +{ + clock_set_source(qdev_get_clock_in(dev, name), source); +} diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h index a340f65ff9..a897f7c9d0 100644 --- a/include/hw/qdev-clock.h +++ b/include/hw/qdev-clock.h @@ -71,11 +71,7 @@ Clock *qdev_get_clock_out(DeviceState *dev, const char *name); * Set the source clock of input clock @name of device @dev to @source. * @source period update will be propagated to @name clock. */ -static inline void qdev_connect_clock_in(DeviceState *dev, const char *name, - Clock *source) -{ - clock_set_source(qdev_get_clock_in(dev, name), source); -} +void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source); /** * qdev_alias_clock: -- cgit v1.2.3-55-g7522 From 739fa3255492f1c7541db1c7a9795fcf4b472c91 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:46 +0100 Subject: hw/qdev-clock: Avoid calling qdev_connect_clock_in after DeviceRealize Clock canonical name is set in device_set_realized (see the block added to hw/core/qdev.c in commit 0e6934f264). If we connect a clock after the device is realized, this code is not executed. This is currently not a problem as this name is only used for trace events, however this disrupt tracing. Add a comment to document qdev_connect_clock_in() must be called before the device is realized, and assert this condition. Signed-off-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis Message-id: 20200803105647.22223-5-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/core/qdev-clock.c | 1 + include/hw/qdev-clock.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'include/hw') diff --git a/hw/core/qdev-clock.c b/hw/core/qdev-clock.c index f139b68b88..47ecb5b4fa 100644 --- a/hw/core/qdev-clock.c +++ b/hw/core/qdev-clock.c @@ -186,5 +186,6 @@ Clock *qdev_alias_clock(DeviceState *dev, const char *name, void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source) { + assert(!dev->realized); clock_set_source(qdev_get_clock_in(dev, name), source); } diff --git a/include/hw/qdev-clock.h b/include/hw/qdev-clock.h index a897f7c9d0..64ca4d266f 100644 --- a/include/hw/qdev-clock.h +++ b/include/hw/qdev-clock.h @@ -70,6 +70,8 @@ Clock *qdev_get_clock_out(DeviceState *dev, const char *name); * * Set the source clock of input clock @name of device @dev to @source. * @source period update will be propagated to @name clock. + * + * Must be called before @dev is realized. */ void qdev_connect_clock_in(DeviceState *dev, const char *name, Clock *source); -- cgit v1.2.3-55-g7522 From 55d35c881924ce5a8ce410210865e47553762847 Mon Sep 17 00:00:00 2001 From: Philippe Mathieu-Daudé Date: Fri, 28 Aug 2020 10:02:46 +0100 Subject: hw/misc/unimp: Display the offset with width of the region size To have a better idea of how big is the region where the offset belongs, display the value with the width of the region size (i.e. a region of 0x1000 bytes uses 0x000 format). Reviewed-by: Richard Henderson Signed-off-by: Philippe Mathieu-Daudé Message-id: 20200812190206.31595-4-f4bug@amsat.org Signed-off-by: Peter Maydell --- hw/misc/unimp.c | 10 ++++++---- include/hw/misc/unimp.h | 1 + 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'include/hw') diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c index b4b318db1c..6cfc5727f0 100644 --- a/hw/misc/unimp.c +++ b/hw/misc/unimp.c @@ -23,8 +23,8 @@ static uint64_t unimp_read(void *opaque, hwaddr offset, unsigned size) UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque); qemu_log_mask(LOG_UNIMP, "%s: unimplemented device read " - "(size %d, offset 0x%" HWADDR_PRIx ")\n", - s->name, size, offset); + "(size %d, offset 0x%0*" HWADDR_PRIx ")\n", + s->name, size, s->offset_fmt_width, offset); return 0; } @@ -34,9 +34,9 @@ static void unimp_write(void *opaque, hwaddr offset, UnimplementedDeviceState *s = UNIMPLEMENTED_DEVICE(opaque); qemu_log_mask(LOG_UNIMP, "%s: unimplemented device write " - "(size %d, offset 0x%" HWADDR_PRIx + "(size %d, offset 0x%0*" HWADDR_PRIx ", value 0x%0*" PRIx64 ")\n", - s->name, size, offset, size << 1, value); + s->name, size, s->offset_fmt_width, offset, size << 1, value); } static const MemoryRegionOps unimp_ops = { @@ -63,6 +63,8 @@ static void unimp_realize(DeviceState *dev, Error **errp) return; } + s->offset_fmt_width = DIV_ROUND_UP(64 - clz64(s->size - 1), 4); + memory_region_init_io(&s->iomem, OBJECT(s), &unimp_ops, s, s->name, s->size); sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); diff --git a/include/hw/misc/unimp.h b/include/hw/misc/unimp.h index 4c1d13c9bf..c63968a2cd 100644 --- a/include/hw/misc/unimp.h +++ b/include/hw/misc/unimp.h @@ -20,6 +20,7 @@ typedef struct { SysBusDevice parent_obj; MemoryRegion iomem; + unsigned offset_fmt_width; char *name; uint64_t size; } UnimplementedDeviceState; -- cgit v1.2.3-55-g7522 From 512c65e62e9e1ae9863ae5a8493e9fad9dbf00e7 Mon Sep 17 00:00:00 2001 From: Eduardo Habkost Date: Fri, 28 Aug 2020 10:02:47 +0100 Subject: armsse: Define ARMSSEClass correctly TYPE_ARM_SSE is a TYPE_SYS_BUS_DEVICE subclass, but ARMSSEClass::parent_class is declared as DeviceClass. It never caused any problems by pure luck: We were not setting class_size for TYPE_ARM_SSE, so class_size of TYPE_SYS_BUS_DEVICE was being used (sizeof(SysBusDeviceClass)). This made the system allocate enough memory for TYPE_ARM_SSE devices even though ARMSSEClass was too small for a sysbus device. Additionally, the ARMSSEClass::info field ended up at the same offset as SysBusDeviceClass::explicit_ofw_unit_address. This would make sysbus_get_fw_dev_path() crash for the device. Luckily, sysbus_get_fw_dev_path() never gets called for TYPE_ARM_SSE devices, because qdev_get_fw_dev_path() is only used by the boot device code, and TYPE_ARM_SSE devices don't appear at the fw_boot_order list. Signed-off-by: Eduardo Habkost Message-id: 20200826181006.4097163-1-ehabkost@redhat.com Reviewed-by: Peter Maydell Signed-off-by: Peter Maydell --- hw/arm/armsse.c | 1 + include/hw/arm/armsse.h | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'include/hw') diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c index dcbff9bd8f..6381bbd94d 100644 --- a/hw/arm/armsse.c +++ b/hw/arm/armsse.c @@ -1160,6 +1160,7 @@ static const TypeInfo armsse_info = { .name = TYPE_ARMSSE, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(ARMSSE), + .class_size = sizeof(ARMSSEClass), .instance_init = armsse_init, .abstract = true, .interfaces = (InterfaceInfo[]) { diff --git a/include/hw/arm/armsse.h b/include/hw/arm/armsse.h index 84080c2299..b10173beab 100644 --- a/include/hw/arm/armsse.h +++ b/include/hw/arm/armsse.h @@ -220,7 +220,7 @@ typedef struct ARMSSE { typedef struct ARMSSEInfo ARMSSEInfo; typedef struct ARMSSEClass { - DeviceClass parent_class; + SysBusDeviceClass parent_class; const ARMSSEInfo *info; } ARMSSEClass; -- cgit v1.2.3-55-g7522