diff options
Diffstat (limited to 'hw')
37 files changed, 426 insertions, 276 deletions
diff --git a/hw/acpi/cpu.c b/hw/acpi/cpu.c index d19b7722f0..f10b190019 100644 --- a/hw/acpi/cpu.c +++ b/hw/acpi/cpu.c @@ -117,7 +117,7 @@ static void cpu_hotplug_wr(void *opaque, hwaddr addr, uint64_t data, DeviceState *dev = NULL; HotplugHandler *hotplug_ctrl = NULL; - if (!cdev->cpu) { + if (!cdev->cpu || cdev->cpu == first_cpu) { trace_cpuhp_acpi_ejecting_invalid_cpu(cpu_st->selector); break; } @@ -541,9 +541,11 @@ void build_cpus_aml(Aml *table, MachineState *machine, CPUHotplugFeatures opts, aml_buffer(madt_buf->len, (uint8_t *)madt_buf->data))); g_array_free(madt_buf, true); - method = aml_method("_EJ0", 1, AML_NOTSERIALIZED); - aml_append(method, aml_call1(CPU_EJECT_METHOD, uid)); - aml_append(dev, method); + if (CPU(arch_ids->cpus[i].cpu) != first_cpu) { + method = aml_method("_EJ0", 1, AML_NOTSERIALIZED); + aml_append(method, aml_call1(CPU_EJECT_METHOD, uid)); + aml_append(dev, method); + } method = aml_method("_OST", 3, AML_SERIALIZED); aml_append(method, diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index f011ea5b00..083b3172da 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -1272,8 +1272,6 @@ static void exynos4210_fimd_update(void *opaque) uint8_t *host_fb_addr; bool is_dirty = false; const int global_width = (s->vidtcon[2] & FIMD_VIDTCON2_SIZE_MASK) + 1; - const int global_height = ((s->vidtcon[2] >> FIMD_VIDTCON2_VER_SHIFT) & - FIMD_VIDTCON2_SIZE_MASK) + 1; if (!s || !s->console || !s->enabled || surface_bits_per_pixel(qemu_console_surface(s->console)) == 0) { @@ -1329,7 +1327,7 @@ static void exynos4210_fimd_update(void *opaque) fimd_copy_line_toqemu(global_width, s->ifb + global_width * line * RGBA_SIZE, d + global_width * line * bpp); } - dpy_gfx_update(s->console, 0, 0, global_width, global_height); + dpy_gfx_update_full(s->console); } s->invalidate = false; s->vidintcon[1] |= FIMD_VIDINT_INTFRMPEND; diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index fbc2b2422d..8ad7e5d824 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -229,7 +229,7 @@ static void g364fb_draw_blank(G364State *s) d += surface_stride(surface); } - dpy_gfx_update(s->con, 0, 0, s->width, s->height); + dpy_gfx_update_full(s->con); s->blanked = 1; } diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index 3c97d56434..eb7933d2a3 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -214,8 +214,7 @@ static void jazz_led_update_display(void *opaque) } s->state = REDRAW_NONE; - dpy_gfx_update(s->con, 0, 0, - surface_width(surface), surface_height(surface)); + dpy_gfx_update_full(s->con); } static void jazz_led_invalidate_display(void *opaque) diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c index 8392e59493..3360be6f84 100644 --- a/hw/display/tc6393xb.c +++ b/hw/display/tc6393xb.c @@ -461,7 +461,7 @@ static void tc6393xb_draw_graphic(TC6393xbState *s, int full_update) return; } - dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height); + dpy_gfx_update_full(s->con); } static void tc6393xb_draw_blank(TC6393xbState *s, int full_update) @@ -480,7 +480,7 @@ static void tc6393xb_draw_blank(TC6393xbState *s, int full_update) d += surface_stride(surface); } - dpy_gfx_update(s->con, 0, 0, s->scr_width, s->scr_height); + dpy_gfx_update_full(s->con); } static void tc6393xb_update_display(void *opaque) diff --git a/hw/display/vga.c b/hw/display/vga.c index 802cfd47db..3ba3f6853c 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -1745,8 +1745,7 @@ static void vga_draw_blank(VGACommonState *s, int full_update) memset(d, 0, w); d += surface_stride(surface); } - dpy_gfx_update(s->con, 0, 0, - s->last_scr_width, s->last_scr_height); + dpy_gfx_update_full(s->con); } #define GMODE_TEXT 0 diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c index 3558f38fe8..55d76405a9 100644 --- a/hw/display/virtio-gpu-3d.c +++ b/hw/display/virtio-gpu-3d.c @@ -86,7 +86,7 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g, &res_iovs, &num_iovs); if (res_iovs != NULL && num_iovs != 0) { - virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs); + virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs); } virgl_renderer_resource_unref(unref.resource_id); } @@ -291,7 +291,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g, VIRTIO_GPU_FILL_CMD(att_rb); trace_virtio_gpu_cmd_res_back_attach(att_rb.resource_id); - ret = virtio_gpu_create_mapping_iov(&att_rb, cmd, NULL, &res_iovs); + ret = virtio_gpu_create_mapping_iov(g, &att_rb, cmd, NULL, &res_iovs); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; @@ -301,7 +301,7 @@ static void virgl_resource_attach_backing(VirtIOGPU *g, res_iovs, att_rb.nr_entries); if (ret != 0) - virtio_gpu_cleanup_mapping_iov(res_iovs, att_rb.nr_entries); + virtio_gpu_cleanup_mapping_iov(g, res_iovs, att_rb.nr_entries); } static void virgl_resource_detach_backing(VirtIOGPU *g, @@ -320,7 +320,7 @@ static void virgl_resource_detach_backing(VirtIOGPU *g, if (res_iovs == NULL || num_iovs == 0) { return; } - virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs); + virtio_gpu_cleanup_mapping_iov(g, res_iovs, num_iovs); } diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 3ddd29c0de..7be3a9d404 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -17,6 +17,7 @@ #include "qemu/iov.h" #include "ui/console.h" #include "trace.h" +#include "sysemu/dma.h" #include "hw/virtio/virtio.h" #include "hw/virtio/virtio-gpu.h" #include "hw/virtio/virtio-bus.h" @@ -29,7 +30,8 @@ static struct virtio_gpu_simple_resource* virtio_gpu_find_resource(VirtIOGPU *g, uint32_t resource_id); -static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res); +static void virtio_gpu_cleanup_mapping(VirtIOGPU *g, + struct virtio_gpu_simple_resource *res); static void virtio_gpu_ctrl_hdr_bswap(struct virtio_gpu_ctrl_hdr *hdr) @@ -421,11 +423,6 @@ static void virtio_gpu_disable_scanout(VirtIOGPU *g, int scanout_id) scanout->height ?: 480, "Guest disabled display."); } - - if (g->disable_scanout) { - g->disable_scanout(g, scanout_id); - } - dpy_gfx_replace_surface(scanout->con, ds); scanout->resource_id = 0; scanout->ds = NULL; @@ -447,7 +444,7 @@ static void virtio_gpu_resource_destroy(VirtIOGPU *g, } pixman_image_unref(res->image); - virtio_gpu_cleanup_mapping(res); + virtio_gpu_cleanup_mapping(g, res); QTAILQ_REMOVE(&g->reslist, res, next); g->hostmem -= res->hostmem; g_free(res); @@ -693,7 +690,8 @@ static void virtio_gpu_set_scanout(VirtIOGPU *g, scanout->height = ss.r.height; } -int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, +int virtio_gpu_create_mapping_iov(VirtIOGPU *g, + struct virtio_gpu_resource_attach_backing *ab, struct virtio_gpu_ctrl_command *cmd, uint64_t **addr, struct iovec **iov) { @@ -729,7 +727,8 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, uint32_t l = le32_to_cpu(ents[i].length); hwaddr len = l; (*iov)[i].iov_len = l; - (*iov)[i].iov_base = cpu_physical_memory_map(a, &len, 1); + (*iov)[i].iov_base = dma_memory_map(VIRTIO_DEVICE(g)->dma_as, + a, &len, DMA_DIRECTION_TO_DEVICE); if (addr) { (*addr)[i] = a; } @@ -737,7 +736,7 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, qemu_log_mask(LOG_GUEST_ERROR, "%s: failed to map MMIO memory for" " resource %d element %d\n", __func__, ab->resource_id, i); - virtio_gpu_cleanup_mapping_iov(*iov, i); + virtio_gpu_cleanup_mapping_iov(g, *iov, i); g_free(ents); *iov = NULL; if (addr) { @@ -751,20 +750,24 @@ int virtio_gpu_create_mapping_iov(struct virtio_gpu_resource_attach_backing *ab, return 0; } -void virtio_gpu_cleanup_mapping_iov(struct iovec *iov, uint32_t count) +void virtio_gpu_cleanup_mapping_iov(VirtIOGPU *g, + struct iovec *iov, uint32_t count) { int i; for (i = 0; i < count; i++) { - cpu_physical_memory_unmap(iov[i].iov_base, iov[i].iov_len, 1, - iov[i].iov_len); + dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, + iov[i].iov_base, iov[i].iov_len, + DMA_DIRECTION_TO_DEVICE, + iov[i].iov_len); } g_free(iov); } -static void virtio_gpu_cleanup_mapping(struct virtio_gpu_simple_resource *res) +static void virtio_gpu_cleanup_mapping(VirtIOGPU *g, + struct virtio_gpu_simple_resource *res) { - virtio_gpu_cleanup_mapping_iov(res->iov, res->iov_cnt); + virtio_gpu_cleanup_mapping_iov(g, res->iov, res->iov_cnt); res->iov = NULL; res->iov_cnt = 0; g_free(res->addrs); @@ -796,7 +799,7 @@ virtio_gpu_resource_attach_backing(VirtIOGPU *g, return; } - ret = virtio_gpu_create_mapping_iov(&ab, cmd, &res->addrs, &res->iov); + ret = virtio_gpu_create_mapping_iov(g, &ab, cmd, &res->addrs, &res->iov); if (ret != 0) { cmd->error = VIRTIO_GPU_RESP_ERR_UNSPEC; return; @@ -823,7 +826,7 @@ virtio_gpu_resource_detach_backing(VirtIOGPU *g, cmd->error = VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID; return; } - virtio_gpu_cleanup_mapping(res); + virtio_gpu_cleanup_mapping(g, res); } static void virtio_gpu_simple_process_cmd(VirtIOGPU *g, @@ -1148,16 +1151,21 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, for (i = 0; i < res->iov_cnt; i++) { hwaddr len = res->iov[i].iov_len; res->iov[i].iov_base = - cpu_physical_memory_map(res->addrs[i], &len, 1); + dma_memory_map(VIRTIO_DEVICE(g)->dma_as, + res->addrs[i], &len, DMA_DIRECTION_TO_DEVICE); + if (!res->iov[i].iov_base || len != res->iov[i].iov_len) { /* Clean up the half-a-mapping we just created... */ if (res->iov[i].iov_base) { - cpu_physical_memory_unmap(res->iov[i].iov_base, - len, 0, 0); + dma_memory_unmap(VIRTIO_DEVICE(g)->dma_as, + res->iov[i].iov_base, + res->iov[i].iov_len, + DMA_DIRECTION_TO_DEVICE, + res->iov[i].iov_len); } /* ...and the mappings for previous loop iterations */ res->iov_cnt = i; - virtio_gpu_cleanup_mapping(res); + virtio_gpu_cleanup_mapping(g, res); pixman_image_unref(res->image); g_free(res); return -EINVAL; @@ -1187,7 +1195,7 @@ static int virtio_gpu_load(QEMUFile *f, void *opaque, size_t size, } dpy_gfx_replace_surface(scanout->con, scanout->ds); - dpy_gfx_update(scanout->con, 0, 0, scanout->width, scanout->height); + dpy_gfx_update_full(scanout->con); if (scanout->cursor.resource_id) { update_cursor(g, &scanout->cursor); } @@ -1205,11 +1213,6 @@ static void virtio_gpu_device_realize(DeviceState *qdev, Error **errp) Error *local_err = NULL; int i; - if (virtio_host_has_feature(vdev, VIRTIO_F_IOMMU_PLATFORM)) { - error_setg(errp, "virtio-gpu does not support vIOMMU yet"); - return; - } - if (g->conf.max_outputs > VIRTIO_GPU_MAX_SCANOUTS) { error_setg(errp, "invalid max_outputs > %d", VIRTIO_GPU_MAX_SCANOUTS); return; @@ -1289,7 +1292,7 @@ static void virtio_gpu_instance_init(Object *obj) { } -static void virtio_gpu_reset(VirtIODevice *vdev) +void virtio_gpu_reset(VirtIODevice *vdev) { VirtIOGPU *g = VIRTIO_GPU(vdev); struct virtio_gpu_simple_resource *res, *tmp; diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index 701d980872..1e601c1a3b 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -75,16 +75,6 @@ static void virtio_vga_gl_block(void *opaque, bool block) } } -static void virtio_vga_disable_scanout(VirtIOGPU *g, int scanout_id) -{ - VirtIOVGA *vvga = container_of(g, VirtIOVGA, vdev); - - if (scanout_id == 0) { - /* reset surface if needed */ - vvga->vga.graphic_mode = -1; - } -} - static const GraphicHwOps virtio_vga_ops = { .invalidate = virtio_vga_invalidate_display, .gfx_update = virtio_vga_update_display, @@ -166,7 +156,6 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp) vvga->vga_mrs, true); vga->con = g->scanout[0].con; - g->disable_scanout = virtio_vga_disable_scanout; graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga); for (i = 0; i < g->conf.max_outputs; i++) { @@ -179,8 +168,12 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp) static void virtio_vga_reset(DeviceState *dev) { VirtIOVGA *vvga = VIRTIO_VGA(dev); - vvga->vdev.enable = 0; + /* reset virtio-gpu */ + virtio_gpu_reset(VIRTIO_DEVICE(&vvga->vdev)); + + /* reset vga */ + vga_common_reset(&vvga->vga); vga_dirty_log_start(&vvga->vga); } diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 0bbb78b9a6..afbf1c5973 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -1116,7 +1116,6 @@ static inline void vmsvga_check_size(struct vmsvga_state_s *s) static void vmsvga_update_display(void *opaque) { struct vmsvga_state_s *s = opaque; - DisplaySurface *surface; if (!s->enable || !s->config) { /* in standard vga mode */ @@ -1125,15 +1124,13 @@ static void vmsvga_update_display(void *opaque) } vmsvga_check_size(s); - surface = qemu_console_surface(s->vga.con); vmsvga_fifo_run(s); vmsvga_update_rect_flush(s); if (s->invalidated) { s->invalidated = 0; - dpy_gfx_update(s->vga.con, 0, 0, - surface_width(surface), surface_height(surface)); + dpy_gfx_update_full(s->vga.con); } } diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 6439bd05ef..cc0f9bc9cc 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1186,8 +1186,7 @@ static void xlnx_dp_update_display(void *opaque) /* * XXX: We might want to update only what changed. */ - dpy_gfx_update(s->console, 0, 0, surface_width(s->g_plane.surface), - surface_height(s->g_plane.surface)); + dpy_gfx_update_full(s->console); } static const GraphicHwOps xlnx_dp_gfx_ops = { diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e1ee8ae9e0..1599caa7c5 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -2251,64 +2251,6 @@ build_tpm2(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) #define HOLE_640K_START (640 * KiB) #define HOLE_640K_END (1 * MiB) -static void build_srat_hotpluggable_memory(GArray *table_data, uint64_t base, - uint64_t len, int default_node) -{ - MemoryDeviceInfoList *info_list = qmp_memory_device_list(); - MemoryDeviceInfoList *info; - MemoryDeviceInfo *mi; - PCDIMMDeviceInfo *di; - uint64_t end = base + len, cur, size; - bool is_nvdimm; - AcpiSratMemoryAffinity *numamem; - MemoryAffinityFlags flags; - - for (cur = base, info = info_list; - cur < end; - cur += size, info = info->next) { - numamem = acpi_data_push(table_data, sizeof *numamem); - - if (!info) { - /* - * Entry is required for Windows to enable memory hotplug in OS - * and for Linux to enable SWIOTLB when booted with less than - * 4G of RAM. Windows works better if the entry sets proximity - * to the highest NUMA node in the machine at the end of the - * reserved space. - * Memory devices may override proximity set by this entry, - * providing _PXM method if necessary. - */ - build_srat_memory(numamem, end - 1, 1, default_node, - MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); - break; - } - - mi = info->value; - is_nvdimm = (mi->type == MEMORY_DEVICE_INFO_KIND_NVDIMM); - di = !is_nvdimm ? mi->u.dimm.data : mi->u.nvdimm.data; - - if (cur < di->addr) { - build_srat_memory(numamem, cur, di->addr - cur, default_node, - MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); - numamem = acpi_data_push(table_data, sizeof *numamem); - } - - size = di->size; - - flags = MEM_AFFINITY_ENABLED; - if (di->hotpluggable) { - flags |= MEM_AFFINITY_HOTPLUGGABLE; - } - if (is_nvdimm) { - flags |= MEM_AFFINITY_NON_VOLATILE; - } - - build_srat_memory(numamem, di->addr, size, di->node, flags); - } - - qapi_free_MemoryDeviceInfoList(info_list); -} - static void build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) { @@ -2414,10 +2356,19 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) build_srat_memory(numamem, 0, 0, 0, MEM_AFFINITY_NOFLAGS); } + /* + * Entry is required for Windows to enable memory hotplug in OS + * and for Linux to enable SWIOTLB when booted with less than + * 4G of RAM. Windows works better if the entry sets proximity + * to the highest NUMA node in the machine. + * Memory devices may override proximity set by this entry, + * providing _PXM method if necessary. + */ if (hotplugabble_address_space_size) { - build_srat_hotpluggable_memory(table_data, machine->device_memory->base, - hotplugabble_address_space_size, - pcms->numa_nodes - 1); + numamem = acpi_data_push(table_data, sizeof *numamem); + build_srat_memory(numamem, machine->device_memory->base, + hotplugabble_address_space_size, pcms->numa_nodes - 1, + MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED); } build_header(linker, table_data, diff --git a/hw/ide/macio.c b/hw/ide/macio.c index d3a85cba3b..bab8c45a43 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -26,6 +26,7 @@ #include "hw/hw.h" #include "hw/ppc/mac.h" #include "hw/ppc/mac_dbdma.h" +#include "hw/misc/macio/macio.h" #include "sysemu/block-backend.h" #include "sysemu/dma.h" @@ -460,6 +461,7 @@ static void macio_ide_initfn(Object *obj) static Property macio_ide_properties[] = { DEFINE_PROP_UINT32("channel", MACIOIDEState, channel, 0), + DEFINE_PROP_UINT32("addr", MACIOIDEState, addr, -1), DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 52aa3775f4..94da85c8d7 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -90,6 +90,15 @@ static void macio_bar_setup(MacIOState *s) macio_escc_legacy_setup(s); } +static void macio_init_child_obj(MacIOState *s, const char *childname, + void *child, size_t childsize, + const char *childtype) +{ + object_initialize_child(OBJECT(s), childname, child, childsize, childtype, + &error_abort, NULL); + qdev_set_parent_bus(DEVICE(child), BUS(&s->macio_bus)); +} + static void macio_common_realize(PCIDevice *d, Error **errp) { MacIOState *s = MACIO(d); @@ -210,10 +219,11 @@ static void macio_init_ide(MacIOState *s, MACIOIDEState *ide, size_t ide_size, int index) { gchar *name = g_strdup_printf("ide[%i]", index); + uint32_t addr = 0x1f000 + ((index + 1) * 0x1000); - sysbus_init_child_obj(OBJECT(s), name, ide, ide_size, TYPE_MACIO_IDE); - memory_region_add_subregion(&s->bar, 0x1f000 + ((index + 1) * 0x1000), - &ide->mem); + macio_init_child_obj(s, name, ide, ide_size, TYPE_MACIO_IDE); + qdev_prop_set_uint32(DEVICE(ide), "addr", addr); + memory_region_add_subregion(&s->bar, addr, &ide->mem); g_free(name); } @@ -229,7 +239,7 @@ static void macio_oldworld_init(Object *obj) qdev_prop_allow_set_link_before_realize, 0, NULL); - sysbus_init_child_obj(obj, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA); + macio_init_child_obj(s, "cuda", &s->cuda, sizeof(s->cuda), TYPE_CUDA); object_initialize(&os->nvram, sizeof(os->nvram), TYPE_MACIO_NVRAM); dev = DEVICE(&os->nvram); @@ -340,7 +350,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) object_property_set_link(OBJECT(&s->pmu), OBJECT(sysbus_dev), "gpio", &error_abort); qdev_prop_set_bit(DEVICE(&s->pmu), "has-adb", ns->has_adb); - qdev_set_parent_bus(DEVICE(&s->pmu), sysbus_get_default()); + qdev_set_parent_bus(DEVICE(&s->pmu), BUS(&s->macio_bus)); object_property_add_child(OBJECT(s), "pmu", OBJECT(&s->pmu), NULL); object_property_set_bool(OBJECT(&s->pmu), true, "realized", &err); @@ -356,7 +366,7 @@ static void macio_newworld_realize(PCIDevice *d, Error **errp) } else { /* CUDA */ object_initialize(&s->cuda, sizeof(s->cuda), TYPE_CUDA); - qdev_set_parent_bus(DEVICE(&s->cuda), sysbus_get_default()); + qdev_set_parent_bus(DEVICE(&s->cuda), BUS(&s->macio_bus)); object_property_add_child(OBJECT(s), "cuda", OBJECT(&s->cuda), NULL); qdev_prop_set_uint64(DEVICE(&s->cuda), "timebase-frequency", s->frequency); @@ -385,8 +395,8 @@ static void macio_newworld_init(Object *obj) qdev_prop_allow_set_link_before_realize, 0, NULL); - sysbus_init_child_obj(obj, "gpio", &ns->gpio, sizeof(ns->gpio), - TYPE_MACIO_GPIO); + macio_init_child_obj(s, "gpio", &ns->gpio, sizeof(ns->gpio), + TYPE_MACIO_GPIO); for (i = 0; i < 2; i++) { macio_init_ide(s, &ns->ide[i], sizeof(ns->ide[i]), i); @@ -399,10 +409,13 @@ static void macio_instance_init(Object *obj) memory_region_init(&s->bar, obj, "macio", 0x80000); - sysbus_init_child_obj(obj, "dbdma", &s->dbdma, sizeof(s->dbdma), - TYPE_MAC_DBDMA); + qbus_create_inplace(&s->macio_bus, sizeof(s->macio_bus), TYPE_MACIO_BUS, + DEVICE(obj), "macio.0"); - sysbus_init_child_obj(obj, "escc", &s->escc, sizeof(s->escc), TYPE_ESCC); + macio_init_child_obj(s, "dbdma", &s->dbdma, sizeof(s->dbdma), + TYPE_MAC_DBDMA); + + macio_init_child_obj(s, "escc", &s->escc, sizeof(s->escc), TYPE_ESCC); } static const VMStateDescription vmstate_macio_oldworld = { @@ -470,6 +483,12 @@ static void macio_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } +static const TypeInfo macio_bus_info = { + .name = TYPE_MACIO_BUS, + .parent = TYPE_BUS, + .instance_size = sizeof(MacIOBusState), +}; + static const TypeInfo macio_oldworld_type_info = { .name = TYPE_OLDWORLD_MACIO, .parent = TYPE_MACIO, @@ -501,6 +520,7 @@ static const TypeInfo macio_type_info = { static void macio_register_types(void) { + type_register_static(&macio_bus_info); type_register_static(&macio_type_info); type_register_static(&macio_oldworld_type_info); type_register_static(&macio_newworld_type_info); diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c index d117e20325..299de429ec 100644 --- a/hw/pci-bridge/gen_pcie_root_port.c +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -29,12 +29,8 @@ typedef struct GenPCIERootPort { bool migrate_msix; - /* additional resources to reserve on firmware init */ - uint32_t bus_reserve; - uint64_t io_reserve; - uint64_t mem_reserve; - uint64_t pref32_reserve; - uint64_t pref64_reserve; + /* additional resources to reserve */ + PCIResReserve res_reserve; } GenPCIERootPort; static uint8_t gen_rp_aer_vector(const PCIDevice *d) @@ -82,16 +78,15 @@ static void gen_rp_realize(DeviceState *dev, Error **errp) return; } - int rc = pci_bridge_qemu_reserve_cap_init(d, 0, grp->bus_reserve, - grp->io_reserve, grp->mem_reserve, grp->pref32_reserve, - grp->pref64_reserve, errp); + int rc = pci_bridge_qemu_reserve_cap_init(d, 0, + grp->res_reserve, errp); if (rc < 0) { rpc->parent_class.exit(d); return; } - if (!grp->io_reserve) { + if (!grp->res_reserve.io) { pci_word_test_and_clear_mask(d->wmask + PCI_COMMAND, PCI_COMMAND_IO); d->wmask[PCI_IO_BASE] = 0; @@ -117,12 +112,18 @@ static const VMStateDescription vmstate_rp_dev = { }; static Property gen_rp_props[] = { - DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, migrate_msix, true), - DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, bus_reserve, -1), - DEFINE_PROP_SIZE("io-reserve", GenPCIERootPort, io_reserve, -1), - DEFINE_PROP_SIZE("mem-reserve", GenPCIERootPort, mem_reserve, -1), - DEFINE_PROP_SIZE("pref32-reserve", GenPCIERootPort, pref32_reserve, -1), - DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, pref64_reserve, -1), + DEFINE_PROP_BOOL("x-migrate-msix", GenPCIERootPort, + migrate_msix, true), + DEFINE_PROP_UINT32("bus-reserve", GenPCIERootPort, + res_reserve.bus, -1), + DEFINE_PROP_SIZE("io-reserve", GenPCIERootPort, + res_reserve.io, -1), + DEFINE_PROP_SIZE("mem-reserve", GenPCIERootPort, + res_reserve.mem_non_pref, -1), + DEFINE_PROP_SIZE("pref32-reserve", GenPCIERootPort, + res_reserve.mem_pref_32, -1), + DEFINE_PROP_SIZE("pref64-reserve", GenPCIERootPort, + res_reserve.mem_pref_64, -1), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index b2d861d216..97a8e8b6a4 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -46,6 +46,9 @@ struct PCIBridgeDev { uint32_t flags; OnOffAuto msi; + + /* additional resources to reserve */ + PCIResReserve res_reserve; }; typedef struct PCIBridgeDev PCIBridgeDev; @@ -95,6 +98,12 @@ static void pci_bridge_dev_realize(PCIDevice *dev, Error **errp) error_free(local_err); } + err = pci_bridge_qemu_reserve_cap_init(dev, 0, + bridge_dev->res_reserve, errp); + if (err) { + goto cap_error; + } + if (shpc_present(dev)) { /* TODO: spec recommends using 64 bit prefetcheable BAR. * Check whether that works well. */ @@ -103,6 +112,8 @@ static void pci_bridge_dev_realize(PCIDevice *dev, Error **errp) } return; +cap_error: + msi_uninit(dev); msi_error: slotid_cap_cleanup(dev); slotid_error: @@ -116,6 +127,8 @@ shpc_error: static void pci_bridge_dev_exitfn(PCIDevice *dev) { PCIBridgeDev *bridge_dev = PCI_BRIDGE_DEV(dev); + + pci_del_capability(dev, PCI_CAP_ID_VNDR, sizeof(PCIBridgeQemuCap)); if (msi_present(dev)) { msi_uninit(dev); } @@ -162,6 +175,17 @@ static Property pci_bridge_dev_properties[] = { ON_OFF_AUTO_AUTO), DEFINE_PROP_BIT(PCI_BRIDGE_DEV_PROP_SHPC, PCIBridgeDev, flags, PCI_BRIDGE_DEV_F_SHPC_REQ, true), + DEFINE_PROP_UINT32("bus-reserve", PCIBridgeDev, + res_reserve.bus, -1), + DEFINE_PROP_SIZE("io-reserve", PCIBridgeDev, + res_reserve.io, -1), + DEFINE_PROP_SIZE("mem-reserve", PCIBridgeDev, + res_reserve.mem_non_pref, -1), + DEFINE_PROP_SIZE("pref32-reserve", PCIBridgeDev, + res_reserve.mem_pref_32, -1), + DEFINE_PROP_SIZE("pref64-reserve", PCIBridgeDev, + res_reserve.mem_pref_64, -1), + DEFINE_PROP_END_OF_LIST(), }; diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 4810a4de79..5a151e93e9 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -37,6 +37,7 @@ typedef struct GrackleState { PCIHostState parent_obj; + uint32_t ofw_addr; HeathrowState *pic; qemu_irq irqs[4]; MemoryRegion pci_mmio; @@ -146,12 +147,28 @@ static const TypeInfo grackle_pci_info = { }, }; +static char *grackle_ofw_unit_address(const SysBusDevice *dev) +{ + GrackleState *s = GRACKLE_PCI_HOST_BRIDGE(dev); + + return g_strdup_printf("%x", s->ofw_addr); +} + +static Property grackle_properties[] = { + DEFINE_PROP_UINT32("ofw-addr", GrackleState, ofw_addr, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void grackle_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = grackle_realize; + dc->props = grackle_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = grackle_ofw_unit_address; } static const TypeInfo grackle_host_info = { diff --git a/hw/pci-host/sabre.c b/hw/pci-host/sabre.c index e2f4ee480e..e33bd46967 100644 --- a/hw/pci-host/sabre.c +++ b/hw/pci-host/sabre.c @@ -496,6 +496,15 @@ static const TypeInfo sabre_pci_info = { }, }; +static char *sabre_ofw_unit_address(const SysBusDevice *dev) +{ + SabreState *s = SABRE_DEVICE(dev); + + return g_strdup_printf("%x,%x", + (uint32_t)((s->special_base >> 32) & 0xffffffff), + (uint32_t)(s->special_base & 0xffffffff)); +} + static Property sabre_properties[] = { DEFINE_PROP_UINT64("special-base", SabreState, special_base, 0), DEFINE_PROP_UINT64("mem-base", SabreState, mem_base, 0), @@ -505,11 +514,14 @@ static Property sabre_properties[] = { static void sabre_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = sabre_realize; dc->reset = sabre_reset; dc->props = sabre_properties; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = sabre_ofw_unit_address; } static const TypeInfo sabre_info = { diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index a843aa7b36..1378c5c7fb 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -118,6 +118,13 @@ static void pci_unin_init_irqs(UNINHostState *s) } } +static char *pci_unin_main_ofw_unit_address(const SysBusDevice *dev) +{ + UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); + + return g_strdup_printf("%x", s->ofw_addr); +} + static void pci_unin_main_realize(DeviceState *dev, Error **errp) { UNINHostState *s = UNI_NORTH_PCI_HOST_BRIDGE(dev); @@ -455,12 +462,21 @@ static const TypeInfo unin_internal_pci_host_info = { }, }; +static Property pci_unin_main_pci_host_props[] = { + DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), + DEFINE_PROP_END_OF_LIST() +}; + static void pci_unin_main_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); + SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); dc->realize = pci_unin_main_realize; + dc->props = pci_unin_main_pci_host_props; set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); + dc->fw_name = "pci"; + sbc->explicit_ofw_unit_address = pci_unin_main_ofw_unit_address; } static const TypeInfo pci_unin_main_info = { diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index 40a39f57cb..08b7e44e2e 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -411,38 +411,34 @@ void pci_bridge_map_irq(PCIBridge *br, const char* bus_name, int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset, - uint32_t bus_reserve, uint64_t io_reserve, - uint64_t mem_non_pref_reserve, - uint64_t mem_pref_32_reserve, - uint64_t mem_pref_64_reserve, - Error **errp) + PCIResReserve res_reserve, Error **errp) { - if (mem_pref_32_reserve != (uint64_t)-1 && - mem_pref_64_reserve != (uint64_t)-1) { + if (res_reserve.mem_pref_32 != (uint64_t)-1 && + res_reserve.mem_pref_64 != (uint64_t)-1) { error_setg(errp, "PCI resource reserve cap: PREF32 and PREF64 conflict"); return -EINVAL; } - if (mem_non_pref_reserve != (uint64_t)-1 && - mem_non_pref_reserve >= (1ULL << 32)) { + if (res_reserve.mem_non_pref != (uint64_t)-1 && + res_reserve.mem_non_pref >= (1ULL << 32)) { error_setg(errp, "PCI resource reserve cap: mem-reserve must be less than 4G"); return -EINVAL; } - if (mem_pref_32_reserve != (uint64_t)-1 && - mem_pref_32_reserve >= (1ULL << 32)) { + if (res_reserve.mem_pref_32 != (uint64_t)-1 && + res_reserve.mem_pref_32 >= (1ULL << 32)) { error_setg(errp, "PCI resource reserve cap: pref32-reserve must be less than 4G"); return -EINVAL; } - if (bus_reserve == (uint32_t)-1 && - io_reserve == (uint64_t)-1 && - mem_non_pref_reserve == (uint64_t)-1 && - mem_pref_32_reserve == (uint64_t)-1 && - mem_pref_64_reserve == (uint64_t)-1) { + if (res_reserve.bus == (uint32_t)-1 && + res_reserve.io == (uint64_t)-1 && + res_reserve.mem_non_pref == (uint64_t)-1 && + res_reserve.mem_pref_32 == (uint64_t)-1 && + res_reserve.mem_pref_64 == (uint64_t)-1) { return 0; } @@ -450,11 +446,11 @@ int pci_bridge_qemu_reserve_cap_init(PCIDevice *dev, int cap_offset, PCIBridgeQemuCap cap = { .len = cap_len, .type = REDHAT_PCI_CAP_RESOURCE_RESERVE, - .bus_res = bus_reserve, - .io = io_reserve, - .mem = mem_non_pref_reserve, - .mem_pref_32 = mem_pref_32_reserve, - .mem_pref_64 = mem_pref_64_reserve + .bus_res = res_reserve.bus, + .io = res_reserve.io, + .mem = res_reserve.mem_non_pref, + .mem_pref_32 = res_reserve.mem_pref_32, + .mem_pref_64 = res_reserve.mem_pref_64 }; int offset = pci_add_capability(dev, PCI_CAP_ID_VNDR, diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h index 41fd289e81..a741300ac9 100644 --- a/hw/ppc/mac.h +++ b/hw/ppc/mac.h @@ -86,32 +86,6 @@ typedef struct Core99MachineState { uint8_t via_config; } Core99MachineState; -/* MacIO */ -#define TYPE_MACIO_IDE "macio-ide" -#define MACIO_IDE(obj) OBJECT_CHECK(MACIOIDEState, (obj), TYPE_MACIO_IDE) - -typedef struct MACIOIDEState { - /*< private >*/ - SysBusDevice parent_obj; - /*< public >*/ - uint32_t channel; - qemu_irq real_ide_irq; - qemu_irq real_dma_irq; - qemu_irq ide_irq; - qemu_irq dma_irq; - - MemoryRegion mem; - IDEBus bus; - IDEDMA dma; - void *dbdma; - bool dma_active; - uint32_t timing_reg; - uint32_t irq_reg; -} MACIOIDEState; - -void macio_ide_init_drives(MACIOIDEState *ide, DriveInfo **hd_table); -void macio_ide_register_dma(MACIOIDEState *ide); - /* Grackle PCI */ #define TYPE_GRACKLE_PCI_HOST_BRIDGE "grackle-pcihost" diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index a6b95f024c..a630cb81cd 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -64,6 +64,7 @@ #include "hw/ppc/openpic.h" #include "hw/ide.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" @@ -344,6 +345,7 @@ static void ppc_core99_init(MachineState *machine) /* Uninorth main bus */ dev = qdev_create(NULL, TYPE_UNI_NORTH_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(dev, "ofw-addr", 0xf2000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); @@ -520,6 +522,54 @@ static void ppc_core99_init(MachineState *machine) qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *core99_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + MACIOIDEState *macio_ide; + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-newworld")) { + pci = PCI_DEVICE(dev); + return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn)); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) { + macio_ide = MACIO_IDE(dev); + return g_strdup_printf("ata-3@%x", macio_ide->addr); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup("cdrom"); + } + + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static int core99_kvm_type(const char *arg) { /* Always force PR KVM */ @@ -529,6 +579,7 @@ static int core99_kvm_type(const char *arg) static void core99_machine_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Mac99 based PowerMAC"; mc->init = ppc_core99_init; @@ -542,6 +593,8 @@ static void core99_machine_class_init(ObjectClass *oc, void *data) #else mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7400_v2.9"); #endif + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = core99_fw_dev_path; } static char *core99_get_via_config(Object *obj, Error **errp) @@ -598,7 +651,11 @@ static const TypeInfo core99_machine_info = { .parent = TYPE_MACHINE, .class_init = core99_machine_class_init, .instance_init = core99_instance_init, - .instance_size = sizeof(Core99MachineState) + .instance_size = sizeof(Core99MachineState), + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void mac_machine_register_types(void) diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index 80b5525775..9891c325a9 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -42,6 +42,7 @@ #include "hw/misc/macio/macio.h" #include "hw/ide.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "qemu/error-report.h" #include "sysemu/kvm.h" @@ -254,6 +255,7 @@ static void ppc_heathrow_init(MachineState *machine) /* Grackle PCI host bridge */ dev = qdev_create(NULL, TYPE_GRACKLE_PCI_HOST_BRIDGE); + qdev_prop_set_uint32(dev, "ofw-addr", 0x80000000); object_property_set_link(OBJECT(dev), OBJECT(pic_dev), "pic", &error_abort); qdev_init_nofail(dev); @@ -372,6 +374,54 @@ static void ppc_heathrow_init(MachineState *machine) qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); } +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *heathrow_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + MACIOIDEState *macio_ide; + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-oldworld")) { + pci = PCI_DEVICE(dev); + return g_strdup_printf("mac-io@%x", PCI_SLOT(pci->devfn)); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "macio-ide")) { + macio_ide = MACIO_IDE(dev); + return g_strdup_printf("ata-3@%x", macio_ide->addr); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup("cdrom"); + } + + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("hd"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static int heathrow_kvm_type(const char *arg) { /* Always force PR KVM */ @@ -381,6 +431,7 @@ static int heathrow_kvm_type(const char *arg) static void heathrow_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Heathrow based PowerMAC"; mc->init = ppc_heathrow_init; @@ -394,12 +445,18 @@ static void heathrow_class_init(ObjectClass *oc, void *data) mc->kvm_type = heathrow_kvm_type; mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("750_v3.1"); mc->default_display = "std"; + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = heathrow_fw_dev_path; } static const TypeInfo ppc_heathrow_machine_info = { .name = MACHINE_TYPE_NAME("g3beige"), .parent = TYPE_MACHINE, - .class_init = heathrow_class_init + .class_init = heathrow_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void ppc_heathrow_register_types(void) diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c index f5a9c24b6c..3be3fe4432 100644 --- a/hw/ppc/ppc405_boards.c +++ b/hw/ppc/ppc405_boards.c @@ -162,13 +162,6 @@ static void ref405ep_init(MachineState *machine) DriveInfo *dinfo; MemoryRegion *sysmem = get_system_memory(); -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* XXX: fix this */ memory_region_allocate_system_memory(&ram_memories[0], NULL, "ef405ep.ram", 0x08000000); @@ -463,13 +456,6 @@ static void taihu_405ep_init(MachineState *machine) int fl_idx, fl_sectors; DriveInfo *dinfo; -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* RAM is soldered to the board so the size cannot be changed */ ram_size = 0x08000000; memory_region_allocate_system_memory(ram, NULL, "taihu_405ep.ram", diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 3d4c43b8cc..f5720f979e 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -195,13 +195,6 @@ static void bamboo_init(MachineState *machine) exit(1); } -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - qemu_register_reset(main_cpu_reset, cpu); ppc_booke_timers_init(cpu, 400000000, 0); ppc_dcr_init(env, NULL, NULL); diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 9b6f534532..5aac58f36e 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -419,13 +419,6 @@ static void sam460ex_init(MachineState *machine) exit(1); } -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - qemu_register_reset(main_cpu_reset, cpu); boot_info = g_malloc0(sizeof(*boot_info)); env->load_info = boot_info; diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 4edb6c7d16..4a9dd4d9bc 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -607,6 +607,7 @@ static void spapr_populate_cpus_dt_node(void *fdt, sPAPRMachineState *spapr) spapr_populate_cpu_dt(cs, fdt, offset, spapr); } + g_free(rev); } static uint32_t spapr_pc_dimm_node(MemoryDeviceInfoList *list, ram_addr_t addr) @@ -2479,6 +2480,8 @@ static void spapr_init_cpus(sPAPRMachineState *spapr) object_property_set_int(core, core_id, CPU_CORE_PROP_CORE_ID, &error_fatal); object_property_set_bool(core, true, "realized", &error_fatal); + + object_unref(core); } } } diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index 876f0b3d9d..2398ce62c0 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -34,16 +34,16 @@ static void spapr_cpu_reset(void *opaque) cpu_reset(cs); - /* Set compatibility mode to match the boot CPU, which was either set - * by the machine reset code or by CAS. This should never fail. - */ - ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); - /* All CPUs start halted. CPU0 is unhalted from the machine level * reset code and the rest are explicitly started up by the guest * using an RTAS call */ cs->halted = 1; + /* Set compatibility mode to match the boot CPU, which was either set + * by the machine reset code or by CAS. This should never fail. + */ + ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); + env->spr[SPR_HIOR] = 0; lpcr = env->spr[SPR_LPCR]; @@ -90,6 +90,7 @@ void spapr_cpu_set_entry_state(PowerPCCPU *cpu, target_ulong nip, target_ulong r env->nip = nip; env->gpr[3] = r3; + kvmppc_set_reg_ppc_online(cpu, 1); CPU(cpu)->halted = 0; /* Enable Power-saving mode Exit Cause exceptions */ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] | pcc->lpcr_pm); diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index 5cd676e443..6bcb4f419b 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -1559,7 +1559,7 @@ static void spapr_phb_realize(DeviceState *dev, Error **errp) sPAPRMachineState *spapr = (sPAPRMachineState *) object_dynamic_cast(qdev_get_machine(), TYPE_SPAPR_MACHINE); - sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(spapr); + sPAPRMachineClass *smc = spapr ? SPAPR_MACHINE_GET_CLASS(spapr) : NULL; SysBusDevice *s = SYS_BUS_DEVICE(dev); sPAPRPHBState *sphb = SPAPR_PCI_HOST_BRIDGE(s); PCIHostState *phb = PCI_HOST_BRIDGE(s); diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c index 4ac96bc94b..d6a0952154 100644 --- a/hw/ppc/spapr_rtas.c +++ b/hw/ppc/spapr_rtas.c @@ -33,6 +33,7 @@ #include "sysemu/device_tree.h" #include "sysemu/cpus.h" #include "sysemu/hw_accel.h" +#include "kvm_ppc.h" #include "hw/ppc/spapr.h" #include "hw/ppc/spapr_vio.h" @@ -207,6 +208,7 @@ static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr, * guest */ ppc_store_lpcr(cpu, env->spr[SPR_LPCR] & ~pcc->lpcr_pm); cs->halted = 1; + kvmppc_set_reg_ppc_online(cpu, 0); qemu_cpu_kick(cs); } diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 7891464cd9..ee9b4b4490 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -211,13 +211,6 @@ static void virtex_init(MachineState *machine) int kernel_size; int i; -#ifdef TARGET_PPCEMB - if (!qtest_enabled()) { - warn_report("qemu-system-ppcemb is deprecated, " - "please use qemu-system-ppc instead."); - } -#endif - /* init CPUs */ cpu = ppc440_init_xilinx(&ram_size, 1, machine->cpu_type, 400000000); env = &cpu->env; diff --git a/hw/riscv/sifive_plic.c b/hw/riscv/sifive_plic.c index a91aeb97ab..f635e6ff67 100644 --- a/hw/riscv/sifive_plic.c +++ b/hw/riscv/sifive_plic.c @@ -81,36 +81,32 @@ static void sifive_plic_print_state(SiFivePLICState *plic) } } -static -void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool pending) +static uint32_t atomic_set_masked(uint32_t *a, uint32_t mask, uint32_t value) { - qemu_mutex_lock(&plic->lock); - uint32_t word = irq >> 5; - if (pending) { - plic->pending[word] |= (1 << (irq & 31)); - } else { - plic->pending[word] &= ~(1 << (irq & 31)); - } - qemu_mutex_unlock(&plic->lock); + uint32_t old, new, cmp = atomic_read(a); + + do { + old = cmp; + new = (old & ~mask) | (value & mask); + cmp = atomic_cmpxchg(a, old, new); + } while (old != cmp); + + return old; } -static -void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool claimed) +static void sifive_plic_set_pending(SiFivePLICState *plic, int irq, bool level) { - qemu_mutex_lock(&plic->lock); - uint32_t word = irq >> 5; - if (claimed) { - plic->claimed[word] |= (1 << (irq & 31)); - } else { - plic->claimed[word] &= ~(1 << (irq & 31)); - } - qemu_mutex_unlock(&plic->lock); + atomic_set_masked(&plic->pending[irq >> 5], 1 << (irq & 31), -!!level); } -static -int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid) +static void sifive_plic_set_claimed(SiFivePLICState *plic, int irq, bool level) { - int i, j, count = 0; + atomic_set_masked(&plic->claimed[irq >> 5], 1 << (irq & 31), -!!level); +} + +static int sifive_plic_irqs_pending(SiFivePLICState *plic, uint32_t addrid) +{ + int i, j; for (i = 0; i < plic->bitfield_words; i++) { uint32_t pending_enabled_not_claimed = (plic->pending[i] & ~plic->claimed[i]) & @@ -123,11 +119,11 @@ int sifive_plic_num_irqs_pending(SiFivePLICState *plic, uint32_t addrid) uint32_t prio = plic->source_priority[irq]; int enabled = pending_enabled_not_claimed & (1 << j); if (enabled && prio > plic->target_priority[addrid]) { - count++; + return 1; } } } - return count; + return 0; } static void sifive_plic_update(SiFivePLICState *plic) @@ -143,7 +139,7 @@ static void sifive_plic_update(SiFivePLICState *plic) if (!env) { continue; } - int level = sifive_plic_num_irqs_pending(plic, addrid) > 0; + int level = sifive_plic_irqs_pending(plic, addrid); switch (mode) { case PLICMode_M: riscv_set_local_interrupt(RISCV_CPU(cpu), MIP_MEIP, level); @@ -439,7 +435,6 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp) memory_region_init_io(&plic->mmio, OBJECT(dev), &sifive_plic_ops, plic, TYPE_SIFIVE_PLIC, plic->aperture_size); parse_hart_config(plic); - qemu_mutex_init(&plic->lock); plic->bitfield_words = (plic->num_sources + 31) >> 5; plic->source_priority = g_new0(uint32_t, plic->num_sources); plic->target_priority = g_new(uint32_t, plic->num_addrs); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index f0bf0d5d67..be5ef85e81 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -90,7 +90,7 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap, qemu_fdt_add_subnode(fdt, "/soc"); qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); - qemu_fdt_setprop_string(fdt, "/soc", "compatible", "ucbbar,spike-bare-soc"); + qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 818a537844..005169eabc 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -121,7 +121,7 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, qemu_fdt_add_subnode(fdt, "/soc"); qemu_fdt_setprop(fdt, "/soc", "ranges", NULL, 0); - qemu_fdt_setprop_string(fdt, "/soc", "compatible", "riscv-virtio-soc"); + qemu_fdt_setprop_string(fdt, "/soc", "compatible", "simple-bus"); qemu_fdt_setprop_cell(fdt, "/soc", "#size-cells", 0x2); qemu_fdt_setprop_cell(fdt, "/soc", "#address-cells", 0x2); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index d16843b30e..f76b19e4e9 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -51,6 +51,7 @@ #include "hw/ide.h" #include "hw/ide/pci.h" #include "hw/loader.h" +#include "hw/fw-path-provider.h" #include "elf.h" #include "trace.h" @@ -693,6 +694,56 @@ enum { sun4v_id = 64, }; +/* + * Implementation of an interface to adjust firmware path + * for the bootindex property handling. + */ +static char *sun4u_fw_dev_path(FWPathProvider *p, BusState *bus, + DeviceState *dev) +{ + PCIDevice *pci; + IDEBus *ide_bus; + IDEState *ide_s; + int bus_id; + + if (!strcmp(object_get_typename(OBJECT(dev)), "pbm-bridge")) { + pci = PCI_DEVICE(dev); + + if (PCI_FUNC(pci->devfn)) { + return g_strdup_printf("pci@%x,%x", PCI_SLOT(pci->devfn), + PCI_FUNC(pci->devfn)); + } else { + return g_strdup_printf("pci@%x", PCI_SLOT(pci->devfn)); + } + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-drive")) { + ide_bus = IDE_BUS(qdev_get_parent_bus(dev)); + ide_s = idebus_active_if(ide_bus); + bus_id = ide_bus->bus_id; + + if (ide_s->drive_kind == IDE_CD) { + return g_strdup_printf("ide@%x/cdrom", bus_id); + } + + return g_strdup_printf("ide@%x/disk", bus_id); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-hd")) { + return g_strdup("disk"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "ide-cd")) { + return g_strdup("cdrom"); + } + + if (!strcmp(object_get_typename(OBJECT(dev)), "virtio-blk-device")) { + return g_strdup("disk"); + } + + return NULL; +} + static const struct hwdef hwdefs[] = { /* Sun4u generic PC-like machine */ { @@ -723,6 +774,7 @@ static void sun4v_init(MachineState *machine) static void sun4u_class_init(ObjectClass *oc, void *data) { MachineClass *mc = MACHINE_CLASS(oc); + FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); mc->desc = "Sun4u platform"; mc->init = sun4u_init; @@ -731,12 +783,18 @@ static void sun4u_class_init(ObjectClass *oc, void *data) mc->is_default = 1; mc->default_boot_order = "c"; mc->default_cpu_type = SPARC_CPU_TYPE_NAME("TI-UltraSparc-IIi"); + mc->ignore_boot_device_suffixes = true; + fwc->get_dev_path = sun4u_fw_dev_path; } static const TypeInfo sun4u_type = { .name = MACHINE_TYPE_NAME("sun4u"), .parent = TYPE_MACHINE, .class_init = sun4u_class_init, + .interfaces = (InterfaceInfo[]) { + { TYPE_FW_PATH_PROVIDER }, + { } + }, }; static void sun4v_class_init(ObjectClass *oc, void *data) diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index d4cb5894a8..569c4053ea 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1073,10 +1073,8 @@ static void vhost_virtqueue_stop(struct vhost_dev *dev, .index = vhost_vq_index, }; int r; - int a; - a = virtio_queue_get_desc_addr(vdev, idx); - if (a == 0) { + if (virtio_queue_get_desc_addr(vdev, idx) == 0) { /* Don't stop the virtqueue which might have not been started */ return; } diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index d4e4d98b59..f6a588ab57 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -2006,14 +2006,25 @@ static int virtio_set_features_nocheck(VirtIODevice *vdev, uint64_t val) int virtio_set_features(VirtIODevice *vdev, uint64_t val) { - /* + int ret; + /* * The driver must not attempt to set features after feature negotiation * has finished. */ if (vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) { return -EINVAL; } - return virtio_set_features_nocheck(vdev, val); + ret = virtio_set_features_nocheck(vdev, val); + if (!ret && virtio_vdev_has_feature(vdev, VIRTIO_RING_F_EVENT_IDX)) { + /* VIRTIO_RING_F_EVENT_IDX changes the size of the caches. */ + int i; + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { + if (vdev->vq[i].vring.num != 0) { + virtio_init_region_cache(vdev, i); + } + } + } + return ret; } int virtio_load(VirtIODevice *vdev, QEMUFile *f, int version_id) |