diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/char/Kconfig | 3 | ||||
-rw-r--r-- | hw/char/meson.build | 2 | ||||
-rw-r--r-- | hw/core/register.c | 12 | ||||
-rw-r--r-- | hw/display/artist.c | 8 | ||||
-rw-r--r-- | hw/display/meson.build | 3 | ||||
-rw-r--r-- | hw/display/vga-isa.c | 10 | ||||
-rw-r--r-- | hw/display/virtio-gpu-udmabuf-stubs.c | 27 | ||||
-rw-r--r-- | hw/display/virtio-gpu.c | 2 | ||||
-rw-r--r-- | hw/display/xlnx_dp.c | 6 | ||||
-rw-r--r-- | hw/intc/sifive_clint.c | 25 | ||||
-rw-r--r-- | hw/riscv/Kconfig | 5 | ||||
-rw-r--r-- | hw/riscv/virt.c | 35 |
12 files changed, 110 insertions, 28 deletions
diff --git a/hw/char/Kconfig b/hw/char/Kconfig index 2e4f620b13..6b6cf2fc1d 100644 --- a/hw/char/Kconfig +++ b/hw/char/Kconfig @@ -68,3 +68,6 @@ config SIFIVE_UART config GOLDFISH_TTY bool + +config SHAKTI_UART + bool diff --git a/hw/char/meson.build b/hw/char/meson.build index 8361d0ab28..7b594f51b8 100644 --- a/hw/char/meson.build +++ b/hw/char/meson.build @@ -16,7 +16,7 @@ softmmu_ss.add(when: 'CONFIG_SERIAL', if_true: files('serial.c')) softmmu_ss.add(when: 'CONFIG_SERIAL_ISA', if_true: files('serial-isa.c')) softmmu_ss.add(when: 'CONFIG_SERIAL_PCI', if_true: files('serial-pci.c')) softmmu_ss.add(when: 'CONFIG_SERIAL_PCI_MULTI', if_true: files('serial-pci-multi.c')) -softmmu_ss.add(when: 'CONFIG_SHAKTI', if_true: files('shakti_uart.c')) +softmmu_ss.add(when: 'CONFIG_SHAKTI_UART', if_true: files('shakti_uart.c')) softmmu_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-console.c')) softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xen_console.c')) softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_uartlite.c')) diff --git a/hw/core/register.c b/hw/core/register.c index d6f8c20816..95b0150c0a 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -300,6 +300,18 @@ RegisterInfoArray *register_init_block32(DeviceState *owner, data, ops, debug_enabled, memory_size, 32); } +RegisterInfoArray *register_init_block64(DeviceState *owner, + const RegisterAccessInfo *rae, + int num, RegisterInfo *ri, + uint64_t *data, + const MemoryRegionOps *ops, + bool debug_enabled, + uint64_t memory_size) +{ + return register_init_block(owner, rae, num, ri, (void *) + data, ops, debug_enabled, memory_size, 64); +} + void register_finalize_block(RegisterInfoArray *r_array) { object_unparent(OBJECT(&r_array->mem)); diff --git a/hw/display/artist.c b/hw/display/artist.c index aa7bd594aa..21b7fd1b44 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -1170,8 +1170,8 @@ static void artist_vram_write(void *opaque, hwaddr addr, uint64_t val, } buf = vram_write_buffer(s); - posy = ADDR_TO_Y(addr); - posx = ADDR_TO_X(addr); + posy = ADDR_TO_Y(addr >> 2); + posx = ADDR_TO_X(addr >> 2); if (!buf->size) { return; @@ -1232,8 +1232,8 @@ static uint64_t artist_vram_read(void *opaque, hwaddr addr, unsigned size) return 0; } - posy = ADDR_TO_Y(addr); - posx = ADDR_TO_X(addr); + posy = ADDR_TO_Y(addr >> 2); + posx = ADDR_TO_X(addr >> 2); if (posy > buf->height || posx > buf->width) { return 0; diff --git a/hw/display/meson.build b/hw/display/meson.build index 1e6b707d3c..861c43ff98 100644 --- a/hw/display/meson.build +++ b/hw/display/meson.build @@ -56,7 +56,8 @@ if config_all_devices.has_key('CONFIG_VIRTIO_GPU') virtio_gpu_ss = ss.source_set() virtio_gpu_ss.add(when: 'CONFIG_VIRTIO_GPU', if_true: [files('virtio-gpu-base.c', 'virtio-gpu.c'), pixman]) - virtio_gpu_ss.add(when: 'CONFIG_LINUX', if_true: files('virtio-gpu-udmabuf.c')) + virtio_gpu_ss.add(when: 'CONFIG_LINUX', if_true: files('virtio-gpu-udmabuf.c'), + if_false: files('virtio-gpu-udmabuf-stubs.c')) virtio_gpu_ss.add(when: 'CONFIG_VHOST_USER_GPU', if_true: files('vhost-user-gpu.c')) hw_display_modules += {'virtio-gpu': virtio_gpu_ss} diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 90851e730b..8cea84f2be 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -33,6 +33,7 @@ #include "hw/loader.h" #include "hw/qdev-properties.h" #include "qom/object.h" +#include "qapi/error.h" #define TYPE_ISA_VGA "isa-vga" OBJECT_DECLARE_SIMPLE_TYPE(ISAVGAState, ISA_VGA) @@ -61,6 +62,15 @@ static void vga_isa_realizefn(DeviceState *dev, Error **errp) MemoryRegion *vga_io_memory; const MemoryRegionPortio *vga_ports, *vbe_ports; + /* + * make sure this device is not being added twice, if so + * exit without crashing qemu + */ + if (object_resolve_path_type("", TYPE_ISA_VGA, NULL)) { + error_setg(errp, "at most one %s device is permitted", TYPE_ISA_VGA); + return; + } + s->global_vmstate = true; vga_common_init(s, OBJECT(dev)); s->legacy_address_space = isa_address_space(isadev); diff --git a/hw/display/virtio-gpu-udmabuf-stubs.c b/hw/display/virtio-gpu-udmabuf-stubs.c new file mode 100644 index 0000000000..81f661441a --- /dev/null +++ b/hw/display/virtio-gpu-udmabuf-stubs.c @@ -0,0 +1,27 @@ +#include "qemu/osdep.h" +#include "hw/virtio/virtio-gpu.h" + +bool virtio_gpu_have_udmabuf(void) +{ + /* nothing (stub) */ + return false; +} + +void virtio_gpu_init_udmabuf(struct virtio_gpu_simple_resource *res) +{ + /* nothing (stub) */ +} + +void virtio_gpu_fini_udmabuf(struct virtio_gpu_simple_resource *res) +{ + /* nothing (stub) */ +} + +int virtio_gpu_update_dmabuf(VirtIOGPU *g, + uint32_t scanout_id, + struct virtio_gpu_simple_resource *res, + struct virtio_gpu_framebuffer *fb) +{ + /* nothing (stub) */ + return 0; +} diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 990e71fd40..72da5bf500 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -362,7 +362,7 @@ static void virtio_gpu_resource_create_blob(VirtIOGPU *g, ret = virtio_gpu_create_mapping_iov(g, cblob.nr_entries, sizeof(cblob), cmd, &res->addrs, &res->iov, &res->iov_cnt); - if (ret != 0 || res->iov) { + if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; g_free(res); return; diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 2bb7a5441a..9bb781e312 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -714,7 +714,11 @@ static uint64_t xlnx_dp_read(void *opaque, hwaddr offset, unsigned size) break; default: assert(offset <= (0x3AC >> 2)); - ret = s->core_registers[offset]; + if (offset == (0x3A8 >> 2) || offset == (0x3AC >> 2)) { + ret = s->core_registers[DP_INT_MASK]; + } else { + ret = s->core_registers[offset]; + } break; } diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c index 0f41e5ea1c..99c870ced2 100644 --- a/hw/intc/sifive_clint.c +++ b/hw/intc/sifive_clint.c @@ -59,8 +59,29 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value, riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0)); diff = cpu->env.timecmp - rtc_r; /* back to ns (note args switched in muldiv64) */ - next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); + uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); + + /* + * check if ns_diff overflowed and check if the addition would potentially + * overflow + */ + if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) || + ns_diff > INT64_MAX) { + next = INT64_MAX; + } else { + /* + * as it is very unlikely qemu_clock_get_ns will return a value + * greater than INT64_MAX, no additional check is needed for an + * unsigned integer overflow. + */ + next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff; + /* + * if ns_diff is INT64_MAX next may still be outside the range + * of a signed integer. + */ + next = MIN(next, INT64_MAX); + } + timer_mod(cpu->env.timer, next); } diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 0590f443fd..ff75add6f3 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -22,13 +22,10 @@ config OPENTITAN select IBEX select UNIMP -config SHAKTI - bool - config SHAKTI_C bool select UNIMP - select SHAKTI + select SHAKTI_UART select SIFIVE_CLINT select SIFIVE_PLIC diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 0e55411045..5624adda58 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -454,7 +454,7 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_cell(fdt, name, "interrupts", RTC_IRQ); g_free(name); - name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase); + name = g_strdup_printf("/flash@%" PRIx64, flashbase); qemu_fdt_add_subnode(mc->fdt, name); qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash"); qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg", @@ -540,6 +540,24 @@ static FWCfgState *create_fw_cfg(const MachineState *mc) return fw_cfg; } +/* + * Return the per-socket PLIC hart topology configuration string + * (caller must free with g_free()) + */ +static char *plic_hart_config_string(int hart_count) +{ + g_autofree const char **vals = g_new(const char *, hart_count + 1); + int i; + + for (i = 0; i < hart_count; i++) { + vals[i] = VIRT_PLIC_HART_CONFIG; + } + vals[i] = NULL; + + /* g_strjoinv() obliges us to cast away const here */ + return g_strjoinv(",", (char **)vals); +} + static void virt_machine_init(MachineState *machine) { const MemMapEntry *memmap = virt_memmap; @@ -548,13 +566,12 @@ static void virt_machine_init(MachineState *machine) MemoryRegion *main_mem = g_new(MemoryRegion, 1); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); char *plic_hart_config, *soc_name; - size_t plic_hart_config_len; target_ulong start_addr = memmap[VIRT_DRAM].base; target_ulong firmware_end_addr, kernel_start_addr; uint32_t fdt_load_addr; uint64_t kernel_entry; DeviceState *mmio_plic, *virtio_plic, *pcie_plic; - int i, j, base_hartid, hart_count; + int i, base_hartid, hart_count; /* Check socket count limit */ if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) { @@ -603,17 +620,7 @@ static void virt_machine_init(MachineState *machine) SIFIVE_CLINT_TIMEBASE_FREQ, true); /* Per-socket PLIC hart topology configuration string */ - plic_hart_config_len = - (strlen(VIRT_PLIC_HART_CONFIG) + 1) * hart_count; - plic_hart_config = g_malloc0(plic_hart_config_len); - for (j = 0; j < hart_count; j++) { - if (j != 0) { - strncat(plic_hart_config, ",", plic_hart_config_len); - } - strncat(plic_hart_config, VIRT_PLIC_HART_CONFIG, - plic_hart_config_len); - plic_hart_config_len -= (strlen(VIRT_PLIC_HART_CONFIG) + 1); - } + plic_hart_config = plic_hart_config_string(hart_count); /* Per-socket PLIC */ s->plic[i] = sifive_plic_create( |