diff options
Diffstat (limited to 'hw')
1155 files changed, 16155 insertions, 8455 deletions
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c index 928523a..31e2162 100644 --- a/hw/9pfs/9p-local.c +++ b/hw/9pfs/9p-local.c @@ -766,16 +766,19 @@ out: return err; } -static int local_fstat(FsContext *fs_ctx, int fid_type, - V9fsFidOpenState *fs, struct stat *stbuf) +static int local_fid_fd(int fid_type, V9fsFidOpenState *fs) { - int err, fd; - if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir.stream); + return dirfd(fs->dir.stream); } else { - fd = fs->fd; + return fs->fd; } +} + +static int local_fstat(FsContext *fs_ctx, int fid_type, + V9fsFidOpenState *fs, struct stat *stbuf) +{ + int err, fd = local_fid_fd(fid_type, fs); err = fstat(fd, stbuf); if (err) { @@ -1039,6 +1042,14 @@ static int local_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size) return ret; } +static int local_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState *fs, + off_t size) +{ + int fd = local_fid_fd(fid_type, fs); + + return ftruncate(fd, size); +} + static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) { char *dirpath = g_path_get_dirname(fs_path->data); @@ -1089,6 +1100,14 @@ out: return ret; } +static int local_futimens(FsContext *s, int fid_type, V9fsFidOpenState *fs, + const struct timespec *times) +{ + int fd = local_fid_fd(fid_type, fs); + + return qemu_futimens(fd, times); +} + static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name, int flags) { @@ -1167,13 +1186,7 @@ out: static int local_fsync(FsContext *ctx, int fid_type, V9fsFidOpenState *fs, int datasync) { - int fd; - - if (fid_type == P9_FID_DIR) { - fd = dirfd(fs->dir.stream); - } else { - fd = fs->fd; - } + int fd = local_fid_fd(fid_type, fs); if (datasync) { return qemu_fdatasync(fd); @@ -1575,6 +1588,13 @@ static int local_parse_opts(QemuOpts *opts, FsDriverEntry *fse, Error **errp) return 0; } +static bool local_has_valid_file_handle(int fid_type, V9fsFidOpenState *fs) +{ + return + (fid_type == P9_FID_FILE && fs->fd != -1) || + (fid_type == P9_FID_DIR && fs->dir.stream != NULL); +} + FileOperations local_ops = { .parse_opts = local_parse_opts, .init = local_init, @@ -1612,4 +1632,7 @@ FileOperations local_ops = { .name_to_path = local_name_to_path, .renameat = local_renameat, .unlinkat = local_unlinkat, + .has_valid_file_handle = local_has_valid_file_handle, + .ftruncate = local_ftruncate, + .futimens = local_futimens, }; diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c index 2abaf3a..9cd1884 100644 --- a/hw/9pfs/9p-synth.c +++ b/hw/9pfs/9p-synth.c @@ -356,6 +356,13 @@ static int synth_truncate(FsContext *ctx, V9fsPath *path, off_t offset) return -1; } +static int synth_ftruncate(FsContext *ctx, int fid_type, V9fsFidOpenState *fs, + off_t size) +{ + errno = ENOSYS; + return -1; +} + static int synth_chmod(FsContext *fs_ctx, V9fsPath *path, FsCred *credp) { errno = EPERM; @@ -417,6 +424,13 @@ static int synth_utimensat(FsContext *fs_ctx, V9fsPath *path, return 0; } +static int synth_futimens(FsContext *fs_ctx, int fid_type, V9fsFidOpenState *fs, + const struct timespec *buf) +{ + errno = ENOSYS; + return -1; +} + static int synth_remove(FsContext *ctx, const char *path) { errno = EPERM; @@ -615,6 +629,11 @@ static int synth_init(FsContext *ctx, Error **errp) return 0; } +static bool synth_has_valid_file_handle(int fid_type, V9fsFidOpenState *fs) +{ + return false; +} + FileOperations synth_ops = { .init = synth_init, .lstat = synth_lstat, @@ -650,4 +669,7 @@ FileOperations synth_ops = { .name_to_path = synth_name_to_path, .renameat = synth_renameat, .unlinkat = synth_unlinkat, + .has_valid_file_handle = synth_has_valid_file_handle, + .ftruncate = synth_ftruncate, + .futimens = synth_futimens, }; diff --git a/hw/9pfs/9p-util.h b/hw/9pfs/9p-util.h index 7bc4ec8..a1924fe 100644 --- a/hw/9pfs/9p-util.h +++ b/hw/9pfs/9p-util.h @@ -103,6 +103,7 @@ static inline int errno_to_dotl(int err) { #define qemu_renameat renameat #define qemu_utimensat utimensat #define qemu_unlinkat unlinkat +#define qemu_futimens futimens static inline void close_preserve_errno(int fd) { diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c index 7cad2bc..8b001b9 100644 --- a/hw/9pfs/9p.c +++ b/hw/9pfs/9p.c @@ -434,16 +434,24 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu) V9fsFidState *f; GHashTableIter iter; gpointer fid; + int err; + int nclosed = 0; + + /* prevent multiple coroutines running this function simultaniously */ + if (s->reclaiming) { + return; + } + s->reclaiming = true; g_hash_table_iter_init(&iter, s->fids); QSLIST_HEAD(, V9fsFidState) reclaim_list = QSLIST_HEAD_INITIALIZER(reclaim_list); + /* Pick FIDs to be closed, collect them on reclaim_list. */ while (g_hash_table_iter_next(&iter, &fid, (gpointer *) &f)) { /* - * Unlink fids cannot be reclaimed. Check - * for them and skip them. Also skip fids + * Unlinked fids cannot be reclaimed, skip those, and also skip fids * currently being operated on. */ if (f->ref || f->flags & FID_NON_RECLAIMABLE) { @@ -493,23 +501,42 @@ void coroutine_fn v9fs_reclaim_fd(V9fsPDU *pdu) } } /* - * Now close the fid in reclaim list. Free them if they - * are already clunked. + * Close the picked FIDs altogether on a background I/O driver thread. Do + * this all at once to keep latency (i.e. amount of thread hops between main + * thread <-> fs driver background thread) as low as possible. */ + v9fs_co_run_in_worker({ + QSLIST_FOREACH(f, &reclaim_list, reclaim_next) { + err = (f->fid_type == P9_FID_DIR) ? + s->ops->closedir(&s->ctx, &f->fs_reclaim) : + s->ops->close(&s->ctx, &f->fs_reclaim); + + /* 'man 2 close' suggests to ignore close() errors except of EBADF */ + if (unlikely(err && errno == EBADF)) { + /* + * unexpected case as FIDs were picked above by having a valid + * file descriptor + */ + error_report("9pfs: v9fs_reclaim_fd() WARNING: close() failed with EBADF"); + } else { + /* total_open_fd must only be mutated on main thread */ + nclosed++; + } + } + }); + total_open_fd -= nclosed; + /* Free the closed FIDs. */ while (!QSLIST_EMPTY(&reclaim_list)) { f = QSLIST_FIRST(&reclaim_list); QSLIST_REMOVE(&reclaim_list, f, V9fsFidState, reclaim_next); - if (f->fid_type == P9_FID_FILE) { - v9fs_co_close(pdu, &f->fs_reclaim); - } else if (f->fid_type == P9_FID_DIR) { - v9fs_co_closedir(pdu, &f->fs_reclaim); - } /* * Now drop the fid reference, free it * if clunked. */ put_fid(pdu, f); } + + s->reclaiming = false; } /* @@ -1574,6 +1601,11 @@ out_nofid: pdu_complete(pdu, err); } +static bool fid_has_valid_file_handle(V9fsState *s, V9fsFidState *fidp) +{ + return s->ops->has_valid_file_handle(fidp->fid_type, &fidp->fs); +} + static void coroutine_fn v9fs_getattr(void *opaque) { int32_t fid; @@ -1596,9 +1628,7 @@ static void coroutine_fn v9fs_getattr(void *opaque) retval = -ENOENT; goto out_nofid; } - if ((fidp->fid_type == P9_FID_FILE && fidp->fs.fd != -1) || - (fidp->fid_type == P9_FID_DIR && fidp->fs.dir.stream)) - { + if (fid_has_valid_file_handle(pdu->s, fidp)) { retval = v9fs_co_fstat(pdu, fidp, &stbuf); } else { retval = v9fs_co_lstat(pdu, &fidp->path, &stbuf); @@ -1705,7 +1735,11 @@ static void coroutine_fn v9fs_setattr(void *opaque) } else { times[1].tv_nsec = UTIME_OMIT; } - err = v9fs_co_utimensat(pdu, &fidp->path, times); + if (fid_has_valid_file_handle(pdu->s, fidp)) { + err = v9fs_co_futimens(pdu, fidp, times); + } else { + err = v9fs_co_utimensat(pdu, &fidp->path, times); + } if (err < 0) { goto out; } @@ -1730,7 +1764,11 @@ static void coroutine_fn v9fs_setattr(void *opaque) } } if (v9iattr.valid & (P9_ATTR_SIZE)) { - err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size); + if (fid_has_valid_file_handle(pdu->s, fidp)) { + err = v9fs_co_ftruncate(pdu, fidp, v9iattr.size); + } else { + err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size); + } if (err < 0) { goto out; } @@ -4324,6 +4362,8 @@ int v9fs_device_realize_common(V9fsState *s, const V9fsTransport *t, s->ctx.fst = &fse->fst; fsdev_throttle_init(s->ctx.fst); + s->reclaiming = false; + rc = 0; out: if (rc) { diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h index 5e041e1..259ad32 100644 --- a/hw/9pfs/9p.h +++ b/hw/9pfs/9p.h @@ -362,6 +362,7 @@ struct V9fsState { uint64_t qp_ndevices; /* Amount of entries in qpd_table. */ uint16_t qp_affix_next; uint64_t qp_fullpath_next; + bool reclaiming; }; /* 9p2000.L open flags */ diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c index 2068a47..bce7dd9 100644 --- a/hw/9pfs/codir.c +++ b/hw/9pfs/codir.c @@ -20,6 +20,7 @@ #include "fsdev/qemu-fsdev.h" #include "qemu/thread.h" #include "qemu/main-loop.h" +#include "qemu/error-report.h" #include "coth.h" #include "9p-xattr.h" #include "9p-util.h" @@ -353,7 +354,11 @@ int coroutine_fn v9fs_co_closedir(V9fsPDU *pdu, V9fsFidOpenState *fs) err = -errno; } }); - if (!err) { + /* 'man 2 close' suggests to ignore close() errors except of EBADF */ + if (unlikely(err && errno == EBADF)) { + /* unexpected case as we should have checked for a valid file handle */ + error_report("9pfs: WARNING: v9fs_co_closedir() failed with EBADF"); + } else { total_open_fd--; } return err; diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c index 71174c3..6e775c8 100644 --- a/hw/9pfs/cofile.c +++ b/hw/9pfs/cofile.c @@ -20,6 +20,7 @@ #include "fsdev/qemu-fsdev.h" #include "qemu/thread.h" #include "qemu/main-loop.h" +#include "qemu/error-report.h" #include "coth.h" int coroutine_fn v9fs_co_st_gen(V9fsPDU *pdu, V9fsPath *path, mode_t st_mode, @@ -197,7 +198,11 @@ int coroutine_fn v9fs_co_close(V9fsPDU *pdu, V9fsFidOpenState *fs) err = -errno; } }); - if (!err) { + /* 'man 2 close' suggests to ignore close() errors except of EBADF */ + if (unlikely(err && errno == EBADF)) { + /* unexpected case as we should have checked for a valid file handle */ + error_report("9pfs: WARNING: v9fs_co_close() failed with EBADF"); + } else { total_open_fd--; } return err; diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c index 67e3ae5..12fa8c9 100644 --- a/hw/9pfs/cofs.c +++ b/hw/9pfs/cofs.c @@ -139,6 +139,25 @@ int coroutine_fn v9fs_co_utimensat(V9fsPDU *pdu, V9fsPath *path, return err; } +int coroutine_fn v9fs_co_futimens(V9fsPDU *pdu, V9fsFidState *fidp, + struct timespec times[2]) +{ + int err; + V9fsState *s = pdu->s; + + if (v9fs_request_cancelled(pdu)) { + return -EINTR; + } + v9fs_co_run_in_worker( + { + err = s->ops->futimens(&s->ctx, fidp->fid_type, &fidp->fs, times); + if (err < 0) { + err = -errno; + } + }); + return err; +} + int coroutine_fn v9fs_co_chown(V9fsPDU *pdu, V9fsPath *path, uid_t uid, gid_t gid) { @@ -184,6 +203,24 @@ int coroutine_fn v9fs_co_truncate(V9fsPDU *pdu, V9fsPath *path, off_t size) return err; } +int coroutine_fn v9fs_co_ftruncate(V9fsPDU *pdu, V9fsFidState *fidp, off_t size) +{ + int err; + V9fsState *s = pdu->s; + + if (v9fs_request_cancelled(pdu)) { + return -EINTR; + } + v9fs_co_run_in_worker( + { + err = s->ops->ftruncate(&s->ctx, fidp->fid_type, &fidp->fs, size); + if (err < 0) { + err = -errno; + } + }); + return err; +} + int coroutine_fn v9fs_co_mknod(V9fsPDU *pdu, V9fsFidState *fidp, V9fsString *name, uid_t uid, gid_t gid, dev_t dev, mode_t mode, struct stat *stbuf) diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h index 2c54249..7906fa7 100644 --- a/hw/9pfs/coth.h +++ b/hw/9pfs/coth.h @@ -71,8 +71,12 @@ int coroutine_fn v9fs_co_statfs(V9fsPDU *, V9fsPath *, struct statfs *); int coroutine_fn v9fs_co_lstat(V9fsPDU *, V9fsPath *, struct stat *); int coroutine_fn v9fs_co_chmod(V9fsPDU *, V9fsPath *, mode_t); int coroutine_fn v9fs_co_utimensat(V9fsPDU *, V9fsPath *, struct timespec [2]); +int coroutine_fn v9fs_co_futimens(V9fsPDU *pdu, V9fsFidState *fidp, + struct timespec times[2]); int coroutine_fn v9fs_co_chown(V9fsPDU *, V9fsPath *, uid_t, gid_t); int coroutine_fn v9fs_co_truncate(V9fsPDU *, V9fsPath *, off_t); +int coroutine_fn v9fs_co_ftruncate(V9fsPDU *pdu, V9fsFidState *fidp, + off_t size); int coroutine_fn v9fs_co_llistxattr(V9fsPDU *, V9fsPath *, void *, size_t); int coroutine_fn v9fs_co_lgetxattr(V9fsPDU *, V9fsPath *, V9fsString *, void *, size_t); diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c index bb2843d..81b91e4 100644 --- a/hw/9pfs/virtio-9p-device.c +++ b/hw/9pfs/virtio-9p-device.c @@ -248,7 +248,7 @@ static const Property virtio_9p_properties[] = { DEFINE_PROP_STRING("fsdev", V9fsVirtioState, state.fsconf.fsdev_id), }; -static void virtio_9p_class_init(ObjectClass *klass, void *data) +static void virtio_9p_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -42,6 +42,7 @@ source ufs/Kconfig source usb/Kconfig source virtio/Kconfig source vfio/Kconfig +source vfio-user/Kconfig source vmapple/Kconfig source xen/Kconfig source watchdog/Kconfig diff --git a/hw/acpi/acpi-pci-hotplug-stub.c b/hw/acpi/acpi-pci-hotplug-stub.c index b67b4a9..b7bc6e4 100644 --- a/hw/acpi/acpi-pci-hotplug-stub.c +++ b/hw/acpi/acpi-pci-hotplug-stub.c @@ -34,7 +34,7 @@ void acpi_pcihp_reset(AcpiPciHpState *s) { } -bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus) +bool acpi_pcihp_is_hotpluggable_bus(AcpiPciHpState *s, BusState *bus) { return true; } diff --git a/hw/acpi/erst.c b/hw/acpi/erst.c index ec64f92..099cabb 100644 --- a/hw/acpi/erst.c +++ b/hw/acpi/erst.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "hw/qdev-core.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qom/object.h" #include "hw/pci/pci_device.h" #include "qom/object_interfaces.h" @@ -23,7 +23,7 @@ #include "hw/acpi/acpi-defs.h" #include "hw/acpi/aml-build.h" #include "hw/acpi/bios-linker-loader.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/hostmem.h" #include "hw/acpi/erst.h" #include "trace.h" @@ -1018,7 +1018,7 @@ static const Property erst_properties[] = { default_record_size, ERST_RECORD_SIZE), }; -static void erst_class_init(ObjectClass *klass, void *data) +static void erst_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1044,7 +1044,7 @@ static const TypeInfo erst_type_info = { .parent = TYPE_PCI_DEVICE, .class_init = erst_class_init, .instance_size = sizeof(ERSTDeviceState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } } diff --git a/hw/acpi/generic_event_device.c b/hw/acpi/generic_event_device.c index c85d97c..7a62f8d 100644 --- a/hw/acpi/generic_event_device.c +++ b/hw/acpi/generic_event_device.c @@ -458,18 +458,18 @@ static void acpi_ged_initfn(Object *obj) * container for memory hotplug IO and expose it as GED sysbus * MMIO so that boards can map it separately. */ - memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container", - MEMORY_HOTPLUG_IO_LEN); - sysbus_init_mmio(sbd, &s->container_memhp); - acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev), - &s->memhp_state, 0); + memory_region_init(&s->container_memhp, OBJECT(dev), "memhp container", + MEMORY_HOTPLUG_IO_LEN); + sysbus_init_mmio(sbd, &s->container_memhp); + acpi_memory_hotplug_init(&s->container_memhp, OBJECT(dev), + &s->memhp_state, 0); memory_region_init_io(&ged_st->regs, obj, &ged_regs_ops, ged_st, TYPE_ACPI_GED "-regs", ACPI_GED_REG_COUNT); sysbus_init_mmio(sbd, &ged_st->regs); } -static void acpi_ged_class_init(ObjectClass *class, void *data) +static void acpi_ged_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(class); @@ -494,7 +494,7 @@ static const TypeInfo acpi_ged_info = { .instance_size = sizeof(AcpiGedState), .instance_init = acpi_ged_initfn, .class_init = acpi_ged_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { TYPE_ACPI_DEVICE_IF }, { } diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c index c7a735b..967b674 100644 --- a/hw/acpi/ich9.c +++ b/hw/acpi/ich9.c @@ -41,15 +41,6 @@ #include "hw/mem/pc-dimm.h" #include "hw/mem/nvdimm.h" -//#define DEBUG - -#ifdef DEBUG -#define ICH9_DEBUG(fmt, ...) \ -do { printf("%s "fmt, __func__, ## __VA_ARGS__); } while (0) -#else -#define ICH9_DEBUG(fmt, ...) do { } while (0) -#endif - static void ich9_pm_update_sci_fn(ACPIREGS *regs) { ICH9LPCPMRegs *pm = container_of(regs, ICH9LPCPMRegs, acpi_regs); @@ -135,8 +126,6 @@ static const MemoryRegionOps ich9_smi_ops = { void ich9_pm_iospace_update(ICH9LPCPMRegs *pm, uint32_t pm_io_base) { - ICH9_DEBUG("to 0x%x\n", pm_io_base); - assert((pm_io_base & ICH9_PMIO_MASK) == 0); pm->pm_io_base = pm_io_base; @@ -570,7 +559,7 @@ void ich9_pm_device_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, bool ich9_pm_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus) { ICH9LPCState *lpc = ICH9_LPC_DEVICE(hotplug_dev); - return acpi_pcihp_is_hotpluggbale_bus(&lpc->pm.acpi_pci_hotplug, bus); + return acpi_pcihp_is_hotpluggable_bus(&lpc->pm.acpi_pci_hotplug, bus); } void ich9_pm_ospm_status(AcpiDeviceIf *adev, ACPIOSTInfoList ***list) diff --git a/hw/acpi/pci.c b/hw/acpi/pci.c index f88f450..d511a85 100644 --- a/hw/acpi/pci.c +++ b/hw/acpi/pci.c @@ -133,7 +133,7 @@ static void acpi_generic_initiator_set_node(Object *obj, Visitor *v, ms->numa_state->nodes[gi->node].has_gi = true; } -static void acpi_generic_initiator_class_init(ObjectClass *oc, void *data) +static void acpi_generic_initiator_class_init(ObjectClass *oc, const void *data) { object_class_property_add_str(oc, "pci-dev", NULL, acpi_generic_initiator_set_pci_device); @@ -247,7 +247,7 @@ static void acpi_generic_port_set_node(Object *obj, Visitor *v, gp->node = value; } -static void acpi_generic_port_class_init(ObjectClass *oc, void *data) +static void acpi_generic_port_class_init(ObjectClass *oc, const void *data) { object_class_property_add_str(oc, "pci-bus", NULL, acpi_generic_port_set_pci_bus); diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 5f79c90..aac9001 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -371,7 +371,7 @@ void acpi_pcihp_device_unplug_request_cb(HotplugHandler *hotplug_dev, acpi_send_event(DEVICE(hotplug_dev), ACPI_PCI_HOTPLUG_STATUS); } -bool acpi_pcihp_is_hotpluggbale_bus(AcpiPciHpState *s, BusState *bus) +bool acpi_pcihp_is_hotpluggable_bus(AcpiPciHpState *s, BusState *bus) { Object *o = OBJECT(bus->parent); diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c index 6d023e5..d98b80d 100644 --- a/hw/acpi/piix4.c +++ b/hw/acpi/piix4.c @@ -406,7 +406,7 @@ static bool piix4_is_hotpluggable_bus(HotplugHandler *hotplug_dev, BusState *bus) { PIIX4PMState *s = PIIX4_PM(hotplug_dev); - return acpi_pcihp_is_hotpluggbale_bus(&s->acpi_pci_hotplug, bus); + return acpi_pcihp_is_hotpluggable_bus(&s->acpi_pci_hotplug, bus); } static void piix4_pm_machine_ready(Notifier *n, void *opaque) @@ -619,7 +619,7 @@ static const Property piix4_pm_properties[] = { not_migrate_acpi_index, false), }; -static void piix4_pm_class_init(ObjectClass *klass, void *data) +static void piix4_pm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -657,7 +657,7 @@ static const TypeInfo piix4_pm_info = { .instance_init = piix4_pm_init, .instance_size = sizeof(PIIX4PMState), .class_init = piix4_pm_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { TYPE_ACPI_DEVICE_IF }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, diff --git a/hw/acpi/vmclock.c b/hw/acpi/vmclock.c index 7387e5c..c582c0c 100644 --- a/hw/acpi/vmclock.c +++ b/hw/acpi/vmclock.c @@ -154,7 +154,7 @@ static void vmclock_realize(DeviceState *dev, Error **errp) vmclock_update_guest(vms); } -static void vmclock_device_class_init(ObjectClass *klass, void *data) +static void vmclock_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c index 008768e..fac3d6d 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -218,7 +218,7 @@ static const Property vmgenid_device_properties[] = { DEFINE_PROP_UUID(VMGENID_GUID, VmGenIdState, guid), }; -static void vmgenid_device_class_init(ObjectClass *klass, void *data) +static void vmgenid_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/adc/aspeed_adc.c b/hw/adc/aspeed_adc.c index 1cc554f..3e820ca 100644 --- a/hw/adc/aspeed_adc.c +++ b/hw/adc/aspeed_adc.c @@ -291,7 +291,7 @@ static const Property aspeed_adc_engine_properties[] = { DEFINE_PROP_UINT32("nr-channels", AspeedADCEngineState, nr_channels, 0), }; -static void aspeed_adc_engine_class_init(ObjectClass *klass, void *data) +static void aspeed_adc_engine_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -369,7 +369,7 @@ static void aspeed_adc_realize(DeviceState *dev, Error **errp) } } -static void aspeed_adc_class_init(ObjectClass *klass, void *data) +static void aspeed_adc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedADCClass *aac = ASPEED_ADC_CLASS(klass); @@ -379,7 +379,7 @@ static void aspeed_adc_class_init(ObjectClass *klass, void *data) aac->nr_engines = 1; } -static void aspeed_2600_adc_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_adc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedADCClass *aac = ASPEED_ADC_CLASS(klass); @@ -388,7 +388,7 @@ static void aspeed_2600_adc_class_init(ObjectClass *klass, void *data) aac->nr_engines = 2; } -static void aspeed_1030_adc_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_adc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedADCClass *aac = ASPEED_ADC_CLASS(klass); @@ -397,7 +397,7 @@ static void aspeed_1030_adc_class_init(ObjectClass *klass, void *data) aac->nr_engines = 2; } -static void aspeed_2700_adc_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_adc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedADCClass *aac = ASPEED_ADC_CLASS(klass); diff --git a/hw/adc/npcm7xx_adc.c b/hw/adc/npcm7xx_adc.c index 0a83d28..ddb219d 100644 --- a/hw/adc/npcm7xx_adc.c +++ b/hw/adc/npcm7xx_adc.c @@ -271,7 +271,7 @@ static const Property npcm7xx_timer_properties[] = { DEFINE_PROP_UINT32("iref", NPCM7xxADCState, iref, NPCM7XX_ADC_DEFAULT_IREF), }; -static void npcm7xx_adc_class_init(ObjectClass *klass, void *data) +static void npcm7xx_adc_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/adc/stm32f2xx_adc.c b/hw/adc/stm32f2xx_adc.c index e3b21f9..a490ae6 100644 --- a/hw/adc/stm32f2xx_adc.c +++ b/hw/adc/stm32f2xx_adc.c @@ -284,7 +284,7 @@ static void stm32f2xx_adc_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); } -static void stm32f2xx_adc_class_init(ObjectClass *klass, void *data) +static void stm32f2xx_adc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/adc/zynq-xadc.c b/hw/adc/zynq-xadc.c index 26d9a7b..748a51b 100644 --- a/hw/adc/zynq-xadc.c +++ b/hw/adc/zynq-xadc.c @@ -281,7 +281,7 @@ static const VMStateDescription vmstate_zynq_xadc = { } }; -static void zynq_xadc_class_init(ObjectClass *klass, void *data) +static void zynq_xadc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index 570ea9e..19562b5 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -8,6 +8,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/target_page.h" #include "elf.h" #include "hw/loader.h" #include "alpha_sys.h" diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index e8711ae..4c56f98 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "qemu/module.h" #include "qemu/units.h" +#include "exec/cpu-interrupt.h" #include "qapi/error.h" #include "hw/pci/pci_host.h" #include "cpu.h" @@ -934,7 +935,7 @@ static const TypeInfo typhoon_pcihost_info = { }; static void typhoon_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig index a55b44d..f543d94 100644 --- a/hw/arm/Kconfig +++ b/hw/arm/Kconfig @@ -147,7 +147,6 @@ config OMAP bool select FRAMEBUFFER select I2C - select NAND select PFLASH_CFI01 select SD select SERIAL_MM diff --git a/hw/arm/allwinner-a10.c b/hw/arm/allwinner-a10.c index f1b3997..dc910d4 100644 --- a/hw/arm/allwinner-a10.c +++ b/hw/arm/allwinner-a10.c @@ -208,7 +208,7 @@ static void aw_a10_realize(DeviceState *dev, Error **errp) sysbus_mmio_map_overlap(SYS_BUS_DEVICE(&s->wdt), 0, AW_A10_WDT_BASE, 1); } -static void aw_a10_class_init(ObjectClass *oc, void *data) +static void aw_a10_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/allwinner-h3.c b/hw/arm/allwinner-h3.c index 1b1afa4..edffc21 100644 --- a/hw/arm/allwinner-h3.c +++ b/hw/arm/allwinner-h3.c @@ -466,7 +466,7 @@ static void allwinner_h3_realize(DeviceState *dev, Error **errp) } } -static void allwinner_h3_class_init(ObjectClass *oc, void *data) +static void allwinner_h3_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/allwinner-r40.c b/hw/arm/allwinner-r40.c index cef6e4d..0bf7008 100644 --- a/hw/arm/allwinner-r40.c +++ b/hw/arm/allwinner-r40.c @@ -539,7 +539,7 @@ static void allwinner_r40_realize(DeviceState *dev, Error **errp) } } -static void allwinner_r40_class_init(ObjectClass *oc, void *data) +static void allwinner_r40_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/armsse.c b/hw/arm/armsse.c index ffd732f..50ab7f4 100644 --- a/hw/arm/armsse.c +++ b/hw/arm/armsse.c @@ -1691,7 +1691,7 @@ static void armsse_reset(DeviceState *dev) s->nsccfg = 0; } -static void armsse_class_init(ObjectClass *klass, void *data) +static void armsse_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(klass); @@ -1713,7 +1713,7 @@ static const TypeInfo armsse_info = { .class_size = sizeof(ARMSSEClass), .instance_init = armsse_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IDAU_INTERFACE }, { } } @@ -1730,7 +1730,7 @@ static void armsse_register_types(void) .name = armsse_variants[i].name, .parent = TYPE_ARM_SSE, .class_init = armsse_class_init, - .class_data = (void *)&armsse_variants[i], + .class_data = &armsse_variants[i], }; type_register_static(&ti); } diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c index 6400917..cea3eb4 100644 --- a/hw/arm/armv7m.c +++ b/hw/arm/armv7m.c @@ -565,7 +565,7 @@ static const VMStateDescription vmstate_armv7m = { } }; -static void armv7m_class_init(ObjectClass *klass, void *data) +static void armv7m_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -636,7 +636,7 @@ static const Property bitband_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void bitband_class_init(ObjectClass *klass, void *data) +static void bitband_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/aspeed.c b/hw/arm/aspeed.c index 82f4258..d0b3336 100644 --- a/hw/arm/aspeed.c +++ b/hw/arm/aspeed.c @@ -27,6 +27,7 @@ #include "system/reset.h" #include "hw/loader.h" #include "qemu/error-report.h" +#include "qemu/datadir.h" #include "qemu/units.h" #include "hw/qdev-clock.h" #include "system/system.h" @@ -305,6 +306,33 @@ static void aspeed_install_boot_rom(AspeedMachineState *bmc, BlockBackend *blk, rom_size, &error_abort); } +#define VBOOTROM_FILE_NAME "ast27x0_bootrom.bin" + +/* + * This function locates the vbootrom image file specified via the command line + * using the -bios option. It loads the specified image into the vbootrom + * memory region and handles errors if the file cannot be found or loaded. + */ +static void aspeed_load_vbootrom(AspeedMachineState *bmc, const char *bios_name, + Error **errp) +{ + g_autofree char *filename = NULL; + AspeedSoCState *soc = bmc->soc; + int ret; + + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (!filename) { + error_setg(errp, "Could not find vbootrom image '%s'", bios_name); + return; + } + + ret = load_image_mr(filename, &soc->vbootrom); + if (ret < 0) { + error_setg(errp, "Failed to load vbootrom image '%s'", bios_name); + return; + } +} + void aspeed_board_init_flashes(AspeedSMCState *s, const char *flashtype, unsigned int count, int unit0) { @@ -380,6 +408,7 @@ static void aspeed_machine_init(MachineState *machine) AspeedMachineClass *amc = ASPEED_MACHINE_GET_CLASS(machine); AspeedSoCClass *sc; int i; + const char *bios_name = NULL; DriveInfo *emmc0 = NULL; bool boot_emmc; @@ -482,6 +511,11 @@ static void aspeed_machine_init(MachineState *machine) } } + if (amc->vbootrom) { + bios_name = machine->firmware ?: VBOOTROM_FILE_NAME; + aspeed_load_vbootrom(bmc, bios_name, &error_abort); + } + arm_load_kernel(ARM_CPU(first_cpu), machine, &aspeed_board_binfo); } @@ -1227,7 +1261,7 @@ static void aspeed_machine_ast2600_class_emmc_init(ObjectClass *oc) "Set or unset boot from EMMC"); } -static void aspeed_machine_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1243,7 +1277,8 @@ static void aspeed_machine_class_init(ObjectClass *oc, void *data) aspeed_machine_class_props_init(oc); } -static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_palmetto_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1260,7 +1295,8 @@ static void aspeed_machine_palmetto_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_quanta_q71l_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_quanta_q71l_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1278,7 +1314,7 @@ static void aspeed_machine_quanta_q71l_class_init(ObjectClass *oc, void *data) } static void aspeed_machine_supermicrox11_bmc_class_init(ObjectClass *oc, - void *data) + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1297,7 +1333,7 @@ static void aspeed_machine_supermicrox11_bmc_class_init(ObjectClass *oc, } static void aspeed_machine_supermicro_x11spi_bmc_class_init(ObjectClass *oc, - void *data) + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1315,7 +1351,8 @@ static void aspeed_machine_supermicro_x11spi_bmc_class_init(ObjectClass *oc, aspeed_machine_class_init_cpus_defaults(mc); } -static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1332,7 +1369,8 @@ static void aspeed_machine_ast2500_evb_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_yosemitev2_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_yosemitev2_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1350,7 +1388,8 @@ static void aspeed_machine_yosemitev2_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_romulus_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1367,7 +1406,8 @@ static void aspeed_machine_romulus_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_tiogapass_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_tiogapass_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1385,7 +1425,8 @@ static void aspeed_machine_tiogapass_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1402,7 +1443,8 @@ static void aspeed_machine_sonorapass_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1419,7 +1461,8 @@ static void aspeed_machine_witherspoon_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1441,7 +1484,7 @@ static void aspeed_machine_ast2600_evb_class_init(ObjectClass *oc, void *data) aspeed_machine_ast2600_class_emmc_init(oc); }; -static void aspeed_machine_g220a_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_g220a_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1459,7 +1502,8 @@ static void aspeed_machine_g220a_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_fp5280g2_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_fp5280g2_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1477,7 +1521,7 @@ static void aspeed_machine_fp5280g2_class_init(ObjectClass *oc, void *data) aspeed_machine_class_init_cpus_defaults(mc); }; -static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_rainier_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1499,7 +1543,7 @@ static void aspeed_machine_rainier_class_init(ObjectClass *oc, void *data) #define FUJI_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB) -static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_fuji_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1521,7 +1565,8 @@ static void aspeed_machine_fuji_class_init(ObjectClass *oc, void *data) #define BLETCHLEY_BMC_RAM_SIZE ASPEED_RAM_SIZE(2 * GiB) -static void aspeed_machine_bletchley_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_bletchley_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1566,7 +1611,7 @@ static void fby35_reset(MachineState *state, ResetType type) object_property_set_bool(OBJECT(gpio), "gpioB5", false, &error_fatal); } -static void aspeed_machine_fby35_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_fby35_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1644,7 +1689,7 @@ static void ast1030_evb_i2c_init(AspeedMachineState *bmc) } static void aspeed_minibmc_machine_ast1030_evb_class_init(ObjectClass *oc, - void *data) + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1673,7 +1718,8 @@ static void ast2700_evb_i2c_init(AspeedMachineState *bmc) TYPE_TMP105, 0x4d); } -static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1689,12 +1735,14 @@ static void aspeed_machine_ast2700a0_evb_class_init(ObjectClass *oc, void *data) amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON; amc->uart_default = ASPEED_DEV_UART12; amc->i2c_init = ast2700_evb_i2c_init; + amc->vbootrom = true; mc->auto_create_sdcard = true; mc->default_ram_size = 1 * GiB; aspeed_machine_class_init_cpus_defaults(mc); } -static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, void *data) +static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1709,6 +1757,7 @@ static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, void *data) amc->macs_mask = ASPEED_MAC0_ON | ASPEED_MAC1_ON | ASPEED_MAC2_ON; amc->uart_default = ASPEED_DEV_UART12; amc->i2c_init = ast2700_evb_i2c_init; + amc->vbootrom = true; mc->auto_create_sdcard = true; mc->default_ram_size = 1 * GiB; aspeed_machine_class_init_cpus_defaults(mc); @@ -1716,7 +1765,7 @@ static void aspeed_machine_ast2700a1_evb_class_init(ObjectClass *oc, void *data) #endif static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc, - void *data) + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); @@ -1736,7 +1785,7 @@ static void aspeed_machine_qcom_dc_scm_v1_class_init(ObjectClass *oc, }; static void aspeed_machine_qcom_firework_class_init(ObjectClass *oc, - void *data) + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); AspeedMachineClass *amc = ASPEED_MACHINE_CLASS(oc); diff --git a/hw/arm/aspeed_ast10x0.c b/hw/arm/aspeed_ast10x0.c index ec329f4..e6e1ee6 100644 --- a/hw/arm/aspeed_ast10x0.c +++ b/hw/arm/aspeed_ast10x0.c @@ -11,7 +11,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/qdev-clock.h" #include "hw/misc/unimp.h" @@ -415,7 +415,7 @@ static void aspeed_soc_ast1030_realize(DeviceState *dev_soc, Error **errp) sc->memmap[ASPEED_DEV_JTAG1], 0x20); } -static void aspeed_soc_ast1030_class_init(ObjectClass *klass, void *data) +static void aspeed_soc_ast1030_class_init(ObjectClass *klass, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-m4"), /* TODO cortex-m4f */ diff --git a/hw/arm/aspeed_ast2400.c b/hw/arm/aspeed_ast2400.c index 0158f6e..c7b0f21 100644 --- a/hw/arm/aspeed_ast2400.c +++ b/hw/arm/aspeed_ast2400.c @@ -502,7 +502,7 @@ static void aspeed_ast2400_soc_realize(DeviceState *dev, Error **errp) aspeed_soc_get_irq(s, ASPEED_DEV_HACE)); } -static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) +static void aspeed_soc_ast2400_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("arm926"), @@ -530,7 +530,7 @@ static void aspeed_soc_ast2400_class_init(ObjectClass *oc, void *data) sc->get_irq = aspeed_soc_ast2400_get_irq; } -static void aspeed_soc_ast2500_class_init(ObjectClass *oc, void *data) +static void aspeed_soc_ast2500_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("arm1176"), diff --git a/hw/arm/aspeed_ast2600.c b/hw/arm/aspeed_ast2600.c index 1f994ba..d12707f 100644 --- a/hw/arm/aspeed_ast2600.c +++ b/hw/arm/aspeed_ast2600.c @@ -653,7 +653,7 @@ static bool aspeed_soc_ast2600_boot_from_emmc(AspeedSoCState *s) return !!(hw_strap1 & SCU_AST2600_HW_STRAP_BOOT_SRC_EMMC); } -static void aspeed_soc_ast2600_class_init(ObjectClass *oc, void *data) +static void aspeed_soc_ast2600_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a7"), diff --git a/hw/arm/aspeed_ast27x0-fc.c b/hw/arm/aspeed_ast27x0-fc.c new file mode 100644 index 0000000..7087be4 --- /dev/null +++ b/hw/arm/aspeed_ast27x0-fc.c @@ -0,0 +1,200 @@ +/* + * ASPEED SoC 2700 family + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "system/block-backend.h" +#include "system/system.h" +#include "hw/arm/aspeed.h" +#include "hw/boards.h" +#include "hw/qdev-clock.h" +#include "hw/arm/aspeed_soc.h" +#include "hw/loader.h" +#include "hw/arm/boot.h" +#include "hw/block/flash.h" + + +#define TYPE_AST2700A1FC MACHINE_TYPE_NAME("ast2700fc") +OBJECT_DECLARE_SIMPLE_TYPE(Ast2700FCState, AST2700A1FC); + +static struct arm_boot_info ast2700fc_board_info = { + .board_id = -1, /* device-tree-only board */ +}; + +struct Ast2700FCState { + MachineState parent_obj; + + MemoryRegion ca35_memory; + MemoryRegion ca35_dram; + MemoryRegion ssp_memory; + MemoryRegion tsp_memory; + + Clock *ssp_sysclk; + Clock *tsp_sysclk; + + Aspeed27x0SoCState ca35; + Aspeed27x0SSPSoCState ssp; + Aspeed27x0TSPSoCState tsp; + + bool mmio_exec; +}; + +#define AST2700FC_BMC_RAM_SIZE (1 * GiB) +#define AST2700FC_CM4_DRAM_SIZE (32 * MiB) + +#define AST2700FC_HW_STRAP1 0x000000C0 +#define AST2700FC_HW_STRAP2 0x00000003 +#define AST2700FC_FMC_MODEL "w25q01jvq" +#define AST2700FC_SPI_MODEL "w25q512jv" + +static void ast2700fc_ca35_init(MachineState *machine) +{ + Ast2700FCState *s = AST2700A1FC(machine); + AspeedSoCState *soc; + AspeedSoCClass *sc; + + object_initialize_child(OBJECT(s), "ca35", &s->ca35, "ast2700-a1"); + soc = ASPEED_SOC(&s->ca35); + sc = ASPEED_SOC_GET_CLASS(soc); + + memory_region_init(&s->ca35_memory, OBJECT(&s->ca35), "ca35-memory", + UINT64_MAX); + memory_region_add_subregion(get_system_memory(), 0, &s->ca35_memory); + + if (!memory_region_init_ram(&s->ca35_dram, OBJECT(&s->ca35), "ca35-dram", + AST2700FC_BMC_RAM_SIZE, &error_abort)) { + return; + } + if (!object_property_set_link(OBJECT(&s->ca35), "memory", + OBJECT(&s->ca35_memory), + &error_abort)) { + return; + }; + if (!object_property_set_link(OBJECT(&s->ca35), "dram", + OBJECT(&s->ca35_dram), &error_abort)) { + return; + } + if (!object_property_set_int(OBJECT(&s->ca35), "ram-size", + AST2700FC_BMC_RAM_SIZE, &error_abort)) { + return; + } + + for (int i = 0; i < sc->macs_num; i++) { + if (!qemu_configure_nic_device(DEVICE(&soc->ftgmac100[i]), + true, NULL)) { + break; + } + } + if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap1", + AST2700FC_HW_STRAP1, &error_abort)) { + return; + } + if (!object_property_set_int(OBJECT(&s->ca35), "hw-strap2", + AST2700FC_HW_STRAP2, &error_abort)) { + return; + } + aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART12, serial_hd(0)); + if (!qdev_realize(DEVICE(&s->ca35), NULL, &error_abort)) { + return; + } + + /* + * AST2700 EVB has a LM75 temperature sensor on I2C bus 0 at address 0x4d. + */ + i2c_slave_create_simple(aspeed_i2c_get_bus(&soc->i2c, 0), "tmp105", 0x4d); + + aspeed_board_init_flashes(&soc->fmc, AST2700FC_FMC_MODEL, 2, 0); + aspeed_board_init_flashes(&soc->spi[0], AST2700FC_SPI_MODEL, 1, 2); + + ast2700fc_board_info.ram_size = machine->ram_size; + ast2700fc_board_info.loader_start = sc->memmap[ASPEED_DEV_SDRAM]; + + arm_load_kernel(ARM_CPU(first_cpu), machine, &ast2700fc_board_info); +} + +static void ast2700fc_ssp_init(MachineState *machine) +{ + AspeedSoCState *soc; + Ast2700FCState *s = AST2700A1FC(machine); + s->ssp_sysclk = clock_new(OBJECT(s), "SSP_SYSCLK"); + clock_set_hz(s->ssp_sysclk, 200000000ULL); + + object_initialize_child(OBJECT(s), "ssp", &s->ssp, TYPE_ASPEED27X0SSP_SOC); + memory_region_init(&s->ssp_memory, OBJECT(&s->ssp), "ssp-memory", + UINT64_MAX); + + qdev_connect_clock_in(DEVICE(&s->ssp), "sysclk", s->ssp_sysclk); + if (!object_property_set_link(OBJECT(&s->ssp), "memory", + OBJECT(&s->ssp_memory), &error_abort)) { + return; + } + + soc = ASPEED_SOC(&s->ssp); + aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART4, serial_hd(1)); + if (!qdev_realize(DEVICE(&s->ssp), NULL, &error_abort)) { + return; + } +} + +static void ast2700fc_tsp_init(MachineState *machine) +{ + AspeedSoCState *soc; + Ast2700FCState *s = AST2700A1FC(machine); + s->tsp_sysclk = clock_new(OBJECT(s), "TSP_SYSCLK"); + clock_set_hz(s->tsp_sysclk, 200000000ULL); + + object_initialize_child(OBJECT(s), "tsp", &s->tsp, TYPE_ASPEED27X0TSP_SOC); + memory_region_init(&s->tsp_memory, OBJECT(&s->tsp), "tsp-memory", + UINT64_MAX); + + qdev_connect_clock_in(DEVICE(&s->tsp), "sysclk", s->tsp_sysclk); + if (!object_property_set_link(OBJECT(&s->tsp), "memory", + OBJECT(&s->tsp_memory), &error_abort)) { + return; + } + + soc = ASPEED_SOC(&s->tsp); + aspeed_soc_uart_set_chr(soc, ASPEED_DEV_UART7, serial_hd(2)); + if (!qdev_realize(DEVICE(&s->tsp), NULL, &error_abort)) { + return; + } +} + +static void ast2700fc_init(MachineState *machine) +{ + ast2700fc_ca35_init(machine); + ast2700fc_ssp_init(machine); + ast2700fc_tsp_init(machine); +} + +static void ast2700fc_class_init(ObjectClass *oc, const void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->alias = "ast2700fc"; + mc->desc = "ast2700 full core support"; + mc->init = ast2700fc_init; + mc->no_floppy = 1; + mc->no_cdrom = 1; + mc->min_cpus = mc->max_cpus = mc->default_cpus = 6; +} + +static const TypeInfo ast2700fc_types[] = { + { + .name = MACHINE_TYPE_NAME("ast2700fc"), + .parent = TYPE_MACHINE, + .class_init = ast2700fc_class_init, + .instance_size = sizeof(Ast2700FCState), + }, +}; + +DEFINE_TYPES(ast2700fc_types) diff --git a/hw/arm/aspeed_ast27x0-ssp.c b/hw/arm/aspeed_ast27x0-ssp.c new file mode 100644 index 0000000..80ec599 --- /dev/null +++ b/hw/arm/aspeed_ast27x0-ssp.c @@ -0,0 +1,294 @@ +/* + * ASPEED Ast27x0 SSP SoC + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/qdev-clock.h" +#include "hw/misc/unimp.h" +#include "hw/arm/aspeed_soc.h" + +#define AST2700_SSP_RAM_SIZE (32 * MiB) + +static const hwaddr aspeed_soc_ast27x0ssp_memmap[] = { + [ASPEED_DEV_SRAM] = 0x00000000, + [ASPEED_DEV_INTC] = 0x72100000, + [ASPEED_DEV_SCU] = 0x72C02000, + [ASPEED_DEV_SCUIO] = 0x74C02000, + [ASPEED_DEV_UART0] = 0x74C33000, + [ASPEED_DEV_UART1] = 0x74C33100, + [ASPEED_DEV_UART2] = 0x74C33200, + [ASPEED_DEV_UART3] = 0x74C33300, + [ASPEED_DEV_UART4] = 0x72C1A000, + [ASPEED_DEV_INTCIO] = 0x74C18000, + [ASPEED_DEV_IPC0] = 0x72C1C000, + [ASPEED_DEV_IPC1] = 0x74C39000, + [ASPEED_DEV_UART5] = 0x74C33400, + [ASPEED_DEV_UART6] = 0x74C33500, + [ASPEED_DEV_UART7] = 0x74C33600, + [ASPEED_DEV_UART8] = 0x74C33700, + [ASPEED_DEV_UART9] = 0x74C33800, + [ASPEED_DEV_UART10] = 0x74C33900, + [ASPEED_DEV_UART11] = 0x74C33A00, + [ASPEED_DEV_UART12] = 0x74C33B00, + [ASPEED_DEV_TIMER1] = 0x72C10000, +}; + +static const int aspeed_soc_ast27x0ssp_irqmap[] = { + [ASPEED_DEV_SCU] = 12, + [ASPEED_DEV_UART0] = 164, + [ASPEED_DEV_UART1] = 164, + [ASPEED_DEV_UART2] = 164, + [ASPEED_DEV_UART3] = 164, + [ASPEED_DEV_UART4] = 8, + [ASPEED_DEV_UART5] = 164, + [ASPEED_DEV_UART6] = 164, + [ASPEED_DEV_UART7] = 164, + [ASPEED_DEV_UART8] = 164, + [ASPEED_DEV_UART9] = 164, + [ASPEED_DEV_UART10] = 164, + [ASPEED_DEV_UART11] = 164, + [ASPEED_DEV_UART12] = 164, + [ASPEED_DEV_TIMER1] = 16, +}; + +/* SSPINT 164 */ +static const int ast2700_ssp132_ssp164_intcmap[] = { + [ASPEED_DEV_UART0] = 7, + [ASPEED_DEV_UART1] = 8, + [ASPEED_DEV_UART2] = 9, + [ASPEED_DEV_UART3] = 10, + [ASPEED_DEV_UART5] = 11, + [ASPEED_DEV_UART6] = 12, + [ASPEED_DEV_UART7] = 13, + [ASPEED_DEV_UART8] = 14, + [ASPEED_DEV_UART9] = 15, + [ASPEED_DEV_UART10] = 16, + [ASPEED_DEV_UART11] = 17, + [ASPEED_DEV_UART12] = 18, +}; + +struct nvic_intc_irq_info { + int irq; + int intc_idx; + int orgate_idx; + const int *ptr; +}; + +static struct nvic_intc_irq_info ast2700_ssp_intcmap[] = { + {160, 1, 0, NULL}, + {161, 1, 1, NULL}, + {162, 1, 2, NULL}, + {163, 1, 3, NULL}, + {164, 1, 4, ast2700_ssp132_ssp164_intcmap}, + {165, 1, 5, NULL}, + {166, 1, 6, NULL}, + {167, 1, 7, NULL}, + {168, 1, 8, NULL}, + {169, 1, 9, NULL}, + {128, 0, 1, NULL}, + {129, 0, 2, NULL}, + {130, 0, 3, NULL}, + {131, 0, 4, NULL}, + {132, 0, 5, ast2700_ssp132_ssp164_intcmap}, + {133, 0, 6, NULL}, + {134, 0, 7, NULL}, + {135, 0, 8, NULL}, + {136, 0, 9, NULL}, +}; + +static qemu_irq aspeed_soc_ast27x0ssp_get_irq(AspeedSoCState *s, int dev) +{ + Aspeed27x0SSPSoCState *a = ASPEED27X0SSP_SOC(s); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + + int or_idx; + int idx; + int i; + + for (i = 0; i < ARRAY_SIZE(ast2700_ssp_intcmap); i++) { + if (sc->irqmap[dev] == ast2700_ssp_intcmap[i].irq) { + assert(ast2700_ssp_intcmap[i].ptr); + or_idx = ast2700_ssp_intcmap[i].orgate_idx; + idx = ast2700_ssp_intcmap[i].intc_idx; + return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]), + ast2700_ssp_intcmap[i].ptr[dev]); + } + } + + return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]); +} + +static void aspeed_soc_ast27x0ssp_init(Object *obj) +{ + Aspeed27x0SSPSoCState *a = ASPEED27X0SSP_SOC(obj); + AspeedSoCState *s = ASPEED_SOC(obj); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + int i; + + object_initialize_child(obj, "armv7m", &a->armv7m, TYPE_ARMV7M); + object_initialize_child(obj, "scu", &s->scu, TYPE_ASPEED_2700_SCU); + s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0); + qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->silicon_rev); + + for (i = 0; i < sc->uarts_num; i++) { + object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM); + } + + object_initialize_child(obj, "intc0", &a->intc[0], + TYPE_ASPEED_2700SSP_INTC); + object_initialize_child(obj, "intc1", &a->intc[1], + TYPE_ASPEED_2700SSP_INTCIO); + + object_initialize_child(obj, "timerctrl", &s->timerctrl, + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "ipc0", &a->ipc[0], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "ipc1", &a->ipc[1], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "scuio", &a->scuio, + TYPE_UNIMPLEMENTED_DEVICE); +} + +static void aspeed_soc_ast27x0ssp_realize(DeviceState *dev_soc, Error **errp) +{ + Aspeed27x0SSPSoCState *a = ASPEED27X0SSP_SOC(dev_soc); + AspeedSoCState *s = ASPEED_SOC(dev_soc); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + DeviceState *armv7m; + g_autofree char *sram_name = NULL; + int i; + + if (!clock_has_source(s->sysclk)) { + error_setg(errp, "sysclk clock must be wired up by the board code"); + return; + } + + /* AST27X0 SSP Core */ + armv7m = DEVICE(&a->armv7m); + qdev_prop_set_uint32(armv7m, "num-irq", 256); + qdev_prop_set_string(armv7m, "cpu-type", aspeed_soc_cpu_type(sc)); + qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk); + object_property_set_link(OBJECT(&a->armv7m), "memory", + OBJECT(s->memory), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&a->armv7m), &error_abort); + + sram_name = g_strdup_printf("aspeed.dram.%d", + CPU(a->armv7m.cpu)->cpu_index); + + if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, + errp)) { + return; + } + memory_region_add_subregion(s->memory, + sc->memmap[ASPEED_DEV_SRAM], + &s->sram); + + /* SCU */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { + return; + } + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); + + /* INTC */ + if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) { + return; + } + + aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[0]), 0, + sc->memmap[ASPEED_DEV_INTC]); + + /* INTCIO */ + if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[1]), errp)) { + return; + } + + aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[1]), 0, + sc->memmap[ASPEED_DEV_INTCIO]); + + /* irq source orgates -> INTC0 */ + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_inpins; i++) { + qdev_connect_gpio_out(DEVICE(&a->intc[0].orgates[i]), 0, + qdev_get_gpio_in(DEVICE(&a->intc[0]), i)); + } + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_outpins; i++) { + assert(i < ARRAY_SIZE(ast2700_ssp_intcmap)); + sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[0]), i, + qdev_get_gpio_in(DEVICE(&a->armv7m), + ast2700_ssp_intcmap[i].irq)); + } + /* irq source orgates -> INTCIO */ + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_inpins; i++) { + qdev_connect_gpio_out(DEVICE(&a->intc[1].orgates[i]), 0, + qdev_get_gpio_in(DEVICE(&a->intc[1]), i)); + } + /* INTCIO -> INTC */ + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_outpins; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i, + qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i)); + } + /* UART */ + if (!aspeed_soc_uart_realize(s, errp)) { + return; + } + + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->timerctrl), + "aspeed.timerctrl", + sc->memmap[ASPEED_DEV_TIMER1], 0x200); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[0]), + "aspeed.ipc0", + sc->memmap[ASPEED_DEV_IPC0], 0x1000); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[1]), + "aspeed.ipc1", + sc->memmap[ASPEED_DEV_IPC1], 0x1000); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->scuio), + "aspeed.scuio", + sc->memmap[ASPEED_DEV_SCUIO], 0x1000); +} + +static void aspeed_soc_ast27x0ssp_class_init(ObjectClass *klass, const void *data) +{ + static const char * const valid_cpu_types[] = { + ARM_CPU_TYPE_NAME("cortex-m4"), /* TODO: cortex-m4f */ + NULL + }; + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSoCClass *sc = ASPEED_SOC_CLASS(dc); + + /* Reason: The Aspeed SoC can only be instantiated from a board */ + dc->user_creatable = false; + dc->realize = aspeed_soc_ast27x0ssp_realize; + + sc->valid_cpu_types = valid_cpu_types; + sc->silicon_rev = AST2700_A1_SILICON_REV; + sc->sram_size = AST2700_SSP_RAM_SIZE; + sc->spis_num = 0; + sc->ehcis_num = 0; + sc->wdts_num = 0; + sc->macs_num = 0; + sc->uarts_num = 13; + sc->uarts_base = ASPEED_DEV_UART0; + sc->irqmap = aspeed_soc_ast27x0ssp_irqmap; + sc->memmap = aspeed_soc_ast27x0ssp_memmap; + sc->num_cpus = 1; + sc->get_irq = aspeed_soc_ast27x0ssp_get_irq; +} + +static const TypeInfo aspeed_soc_ast27x0ssp_types[] = { + { + .name = TYPE_ASPEED27X0SSP_SOC, + .parent = TYPE_ASPEED_SOC, + .instance_size = sizeof(Aspeed27x0SSPSoCState), + .instance_init = aspeed_soc_ast27x0ssp_init, + .class_init = aspeed_soc_ast27x0ssp_class_init, + }, +}; + +DEFINE_TYPES(aspeed_soc_ast27x0ssp_types) diff --git a/hw/arm/aspeed_ast27x0-tsp.c b/hw/arm/aspeed_ast27x0-tsp.c new file mode 100644 index 0000000..4e0efae --- /dev/null +++ b/hw/arm/aspeed_ast27x0-tsp.c @@ -0,0 +1,294 @@ +/* + * ASPEED Ast27x0 TSP SoC + * + * Copyright (C) 2025 ASPEED Technology Inc. + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/qdev-clock.h" +#include "hw/misc/unimp.h" +#include "hw/arm/aspeed_soc.h" + +#define AST2700_TSP_RAM_SIZE (32 * MiB) + +static const hwaddr aspeed_soc_ast27x0tsp_memmap[] = { + [ASPEED_DEV_SRAM] = 0x00000000, + [ASPEED_DEV_INTC] = 0x72100000, + [ASPEED_DEV_SCU] = 0x72C02000, + [ASPEED_DEV_SCUIO] = 0x74C02000, + [ASPEED_DEV_UART0] = 0x74C33000, + [ASPEED_DEV_UART1] = 0x74C33100, + [ASPEED_DEV_UART2] = 0x74C33200, + [ASPEED_DEV_UART3] = 0x74C33300, + [ASPEED_DEV_UART4] = 0x72C1A000, + [ASPEED_DEV_INTCIO] = 0x74C18000, + [ASPEED_DEV_IPC0] = 0x72C1C000, + [ASPEED_DEV_IPC1] = 0x74C39000, + [ASPEED_DEV_UART5] = 0x74C33400, + [ASPEED_DEV_UART6] = 0x74C33500, + [ASPEED_DEV_UART7] = 0x74C33600, + [ASPEED_DEV_UART8] = 0x74C33700, + [ASPEED_DEV_UART9] = 0x74C33800, + [ASPEED_DEV_UART10] = 0x74C33900, + [ASPEED_DEV_UART11] = 0x74C33A00, + [ASPEED_DEV_UART12] = 0x74C33B00, + [ASPEED_DEV_TIMER1] = 0x72C10000, +}; + +static const int aspeed_soc_ast27x0tsp_irqmap[] = { + [ASPEED_DEV_SCU] = 12, + [ASPEED_DEV_UART0] = 164, + [ASPEED_DEV_UART1] = 164, + [ASPEED_DEV_UART2] = 164, + [ASPEED_DEV_UART3] = 164, + [ASPEED_DEV_UART4] = 8, + [ASPEED_DEV_UART5] = 164, + [ASPEED_DEV_UART6] = 164, + [ASPEED_DEV_UART7] = 164, + [ASPEED_DEV_UART8] = 164, + [ASPEED_DEV_UART9] = 164, + [ASPEED_DEV_UART10] = 164, + [ASPEED_DEV_UART11] = 164, + [ASPEED_DEV_UART12] = 164, + [ASPEED_DEV_TIMER1] = 16, +}; + +/* TSPINT 164 */ +static const int ast2700_tsp132_tsp164_intcmap[] = { + [ASPEED_DEV_UART0] = 7, + [ASPEED_DEV_UART1] = 8, + [ASPEED_DEV_UART2] = 9, + [ASPEED_DEV_UART3] = 10, + [ASPEED_DEV_UART5] = 11, + [ASPEED_DEV_UART6] = 12, + [ASPEED_DEV_UART7] = 13, + [ASPEED_DEV_UART8] = 14, + [ASPEED_DEV_UART9] = 15, + [ASPEED_DEV_UART10] = 16, + [ASPEED_DEV_UART11] = 17, + [ASPEED_DEV_UART12] = 18, +}; + +struct nvic_intc_irq_info { + int irq; + int intc_idx; + int orgate_idx; + const int *ptr; +}; + +static struct nvic_intc_irq_info ast2700_tsp_intcmap[] = { + {160, 1, 0, NULL}, + {161, 1, 1, NULL}, + {162, 1, 2, NULL}, + {163, 1, 3, NULL}, + {164, 1, 4, ast2700_tsp132_tsp164_intcmap}, + {165, 1, 5, NULL}, + {166, 1, 6, NULL}, + {167, 1, 7, NULL}, + {168, 1, 8, NULL}, + {169, 1, 9, NULL}, + {128, 0, 1, NULL}, + {129, 0, 2, NULL}, + {130, 0, 3, NULL}, + {131, 0, 4, NULL}, + {132, 0, 5, ast2700_tsp132_tsp164_intcmap}, + {133, 0, 6, NULL}, + {134, 0, 7, NULL}, + {135, 0, 8, NULL}, + {136, 0, 9, NULL}, +}; + +static qemu_irq aspeed_soc_ast27x0tsp_get_irq(AspeedSoCState *s, int dev) +{ + Aspeed27x0TSPSoCState *a = ASPEED27X0TSP_SOC(s); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + + int or_idx; + int idx; + int i; + + for (i = 0; i < ARRAY_SIZE(ast2700_tsp_intcmap); i++) { + if (sc->irqmap[dev] == ast2700_tsp_intcmap[i].irq) { + assert(ast2700_tsp_intcmap[i].ptr); + or_idx = ast2700_tsp_intcmap[i].orgate_idx; + idx = ast2700_tsp_intcmap[i].intc_idx; + return qdev_get_gpio_in(DEVICE(&a->intc[idx].orgates[or_idx]), + ast2700_tsp_intcmap[i].ptr[dev]); + } + } + + return qdev_get_gpio_in(DEVICE(&a->armv7m), sc->irqmap[dev]); +} + +static void aspeed_soc_ast27x0tsp_init(Object *obj) +{ + Aspeed27x0TSPSoCState *a = ASPEED27X0TSP_SOC(obj); + AspeedSoCState *s = ASPEED_SOC(obj); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + int i; + + object_initialize_child(obj, "armv7m", &a->armv7m, TYPE_ARMV7M); + object_initialize_child(obj, "scu", &s->scu, TYPE_ASPEED_2700_SCU); + s->sysclk = qdev_init_clock_in(DEVICE(s), "sysclk", NULL, NULL, 0); + qdev_prop_set_uint32(DEVICE(&s->scu), "silicon-rev", sc->silicon_rev); + + for (i = 0; i < sc->uarts_num; i++) { + object_initialize_child(obj, "uart[*]", &s->uart[i], TYPE_SERIAL_MM); + } + + object_initialize_child(obj, "intc0", &a->intc[0], + TYPE_ASPEED_2700TSP_INTC); + object_initialize_child(obj, "intc1", &a->intc[1], + TYPE_ASPEED_2700TSP_INTCIO); + + object_initialize_child(obj, "timerctrl", &s->timerctrl, + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "ipc0", &a->ipc[0], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "ipc1", &a->ipc[1], + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "scuio", &a->scuio, + TYPE_UNIMPLEMENTED_DEVICE); +} + +static void aspeed_soc_ast27x0tsp_realize(DeviceState *dev_soc, Error **errp) +{ + Aspeed27x0TSPSoCState *a = ASPEED27X0TSP_SOC(dev_soc); + AspeedSoCState *s = ASPEED_SOC(dev_soc); + AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); + DeviceState *armv7m; + g_autofree char *sram_name = NULL; + int i; + + if (!clock_has_source(s->sysclk)) { + error_setg(errp, "sysclk clock must be wired up by the board code"); + return; + } + + /* AST27X0 TSP Core */ + armv7m = DEVICE(&a->armv7m); + qdev_prop_set_uint32(armv7m, "num-irq", 256); + qdev_prop_set_string(armv7m, "cpu-type", aspeed_soc_cpu_type(sc)); + qdev_connect_clock_in(armv7m, "cpuclk", s->sysclk); + object_property_set_link(OBJECT(&a->armv7m), "memory", + OBJECT(s->memory), &error_abort); + sysbus_realize(SYS_BUS_DEVICE(&a->armv7m), &error_abort); + + sram_name = g_strdup_printf("aspeed.dram.%d", + CPU(a->armv7m.cpu)->cpu_index); + + if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, + errp)) { + return; + } + memory_region_add_subregion(s->memory, + sc->memmap[ASPEED_DEV_SRAM], + &s->sram); + + /* SCU */ + if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { + return; + } + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->scu), 0, sc->memmap[ASPEED_DEV_SCU]); + + /* INTC */ + if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[0]), errp)) { + return; + } + + aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[0]), 0, + sc->memmap[ASPEED_DEV_INTC]); + + /* INTCIO */ + if (!sysbus_realize(SYS_BUS_DEVICE(&a->intc[1]), errp)) { + return; + } + + aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->intc[1]), 0, + sc->memmap[ASPEED_DEV_INTCIO]); + + /* irq source orgates -> INTC */ + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_inpins; i++) { + qdev_connect_gpio_out(DEVICE(&a->intc[0].orgates[i]), 0, + qdev_get_gpio_in(DEVICE(&a->intc[0]), i)); + } + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[0])->num_outpins; i++) { + assert(i < ARRAY_SIZE(ast2700_tsp_intcmap)); + sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[0]), i, + qdev_get_gpio_in(DEVICE(&a->armv7m), + ast2700_tsp_intcmap[i].irq)); + } + /* irq source orgates -> INTC */ + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_inpins; i++) { + qdev_connect_gpio_out(DEVICE(&a->intc[1].orgates[i]), 0, + qdev_get_gpio_in(DEVICE(&a->intc[1]), i)); + } + /* INTCIO -> INTC */ + for (i = 0; i < ASPEED_INTC_GET_CLASS(&a->intc[1])->num_outpins; i++) { + sysbus_connect_irq(SYS_BUS_DEVICE(&a->intc[1]), i, + qdev_get_gpio_in(DEVICE(&a->intc[0].orgates[0]), i)); + } + /* UART */ + if (!aspeed_soc_uart_realize(s, errp)) { + return; + } + + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->timerctrl), + "aspeed.timerctrl", + sc->memmap[ASPEED_DEV_TIMER1], 0x200); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[0]), + "aspeed.ipc0", + sc->memmap[ASPEED_DEV_IPC0], 0x1000); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->ipc[1]), + "aspeed.ipc1", + sc->memmap[ASPEED_DEV_IPC1], 0x1000); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&a->scuio), + "aspeed.scuio", + sc->memmap[ASPEED_DEV_SCUIO], 0x1000); +} + +static void aspeed_soc_ast27x0tsp_class_init(ObjectClass *klass, const void *data) +{ + static const char * const valid_cpu_types[] = { + ARM_CPU_TYPE_NAME("cortex-m4"), /* TODO cortex-m4f */ + NULL + }; + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedSoCClass *sc = ASPEED_SOC_CLASS(dc); + + /* Reason: The Aspeed SoC can only be instantiated from a board */ + dc->user_creatable = false; + dc->realize = aspeed_soc_ast27x0tsp_realize; + + sc->valid_cpu_types = valid_cpu_types; + sc->silicon_rev = AST2700_A1_SILICON_REV; + sc->sram_size = AST2700_TSP_RAM_SIZE; + sc->spis_num = 0; + sc->ehcis_num = 0; + sc->wdts_num = 0; + sc->macs_num = 0; + sc->uarts_num = 13; + sc->uarts_base = ASPEED_DEV_UART0; + sc->irqmap = aspeed_soc_ast27x0tsp_irqmap; + sc->memmap = aspeed_soc_ast27x0tsp_memmap; + sc->num_cpus = 1; + sc->get_irq = aspeed_soc_ast27x0tsp_get_irq; +} + +static const TypeInfo aspeed_soc_ast27x0tsp_types[] = { + { + .name = TYPE_ASPEED27X0TSP_SOC, + .parent = TYPE_ASPEED_SOC, + .instance_size = sizeof(Aspeed27x0TSPSoCState), + .instance_init = aspeed_soc_ast27x0tsp_init, + .class_init = aspeed_soc_ast27x0tsp_class_init, + }, +}; + +DEFINE_TYPES(aspeed_soc_ast27x0tsp_types) diff --git a/hw/arm/aspeed_ast27x0.c b/hw/arm/aspeed_ast27x0.c index dce7255..6aa3841 100644 --- a/hw/arm/aspeed_ast27x0.c +++ b/hw/arm/aspeed_ast27x0.c @@ -23,8 +23,19 @@ #include "qobject/qlist.h" #include "qemu/log.h" +#define AST2700_SOC_IO_SIZE 0x00FE0000 +#define AST2700_SOC_IOMEM_SIZE 0x01000000 +#define AST2700_SOC_DPMCU_SIZE 0x00040000 +#define AST2700_SOC_LTPI_SIZE 0x01000000 + static const hwaddr aspeed_soc_ast2700_memmap[] = { + [ASPEED_DEV_VBOOTROM] = 0x00000000, + [ASPEED_DEV_IOMEM] = 0x00020000, [ASPEED_DEV_SRAM] = 0x10000000, + [ASPEED_DEV_DPMCU] = 0x11000000, + [ASPEED_DEV_IOMEM0] = 0x12000000, + [ASPEED_DEV_EHCI1] = 0x12061000, + [ASPEED_DEV_EHCI2] = 0x12063000, [ASPEED_DEV_HACE] = 0x12070000, [ASPEED_DEV_EMMC] = 0x12090000, [ASPEED_DEV_INTC] = 0x12100000, @@ -35,7 +46,8 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = { [ASPEED_DEV_RTC] = 0x12C0F000, [ASPEED_DEV_TIMER1] = 0x12C10000, [ASPEED_DEV_SLI] = 0x12C17000, - [ASPEED_DEV_UART4] = 0X12C1A000, + [ASPEED_DEV_UART4] = 0x12C1A000, + [ASPEED_DEV_IOMEM1] = 0x14000000, [ASPEED_DEV_FMC] = 0x14000000, [ASPEED_DEV_SPI0] = 0x14010000, [ASPEED_DEV_SPI1] = 0x14020000, @@ -47,27 +59,30 @@ static const hwaddr aspeed_soc_ast2700_memmap[] = { [ASPEED_DEV_ETH2] = 0x14060000, [ASPEED_DEV_ETH3] = 0x14070000, [ASPEED_DEV_SDHCI] = 0x14080000, + [ASPEED_DEV_EHCI3] = 0x14121000, + [ASPEED_DEV_EHCI4] = 0x14123000, [ASPEED_DEV_ADC] = 0x14C00000, [ASPEED_DEV_SCUIO] = 0x14C02000, [ASPEED_DEV_GPIO] = 0x14C0B000, [ASPEED_DEV_I2C] = 0x14C0F000, [ASPEED_DEV_INTCIO] = 0x14C18000, [ASPEED_DEV_SLIIO] = 0x14C1E000, - [ASPEED_DEV_VUART] = 0X14C30000, - [ASPEED_DEV_UART0] = 0X14C33000, - [ASPEED_DEV_UART1] = 0X14C33100, - [ASPEED_DEV_UART2] = 0X14C33200, - [ASPEED_DEV_UART3] = 0X14C33300, - [ASPEED_DEV_UART5] = 0X14C33400, - [ASPEED_DEV_UART6] = 0X14C33500, - [ASPEED_DEV_UART7] = 0X14C33600, - [ASPEED_DEV_UART8] = 0X14C33700, - [ASPEED_DEV_UART9] = 0X14C33800, - [ASPEED_DEV_UART10] = 0X14C33900, - [ASPEED_DEV_UART11] = 0X14C33A00, - [ASPEED_DEV_UART12] = 0X14C33B00, + [ASPEED_DEV_VUART] = 0x14C30000, + [ASPEED_DEV_UART0] = 0x14C33000, + [ASPEED_DEV_UART1] = 0x14C33100, + [ASPEED_DEV_UART2] = 0x14C33200, + [ASPEED_DEV_UART3] = 0x14C33300, + [ASPEED_DEV_UART5] = 0x14C33400, + [ASPEED_DEV_UART6] = 0x14C33500, + [ASPEED_DEV_UART7] = 0x14C33600, + [ASPEED_DEV_UART8] = 0x14C33700, + [ASPEED_DEV_UART9] = 0x14C33800, + [ASPEED_DEV_UART10] = 0x14C33900, + [ASPEED_DEV_UART11] = 0x14C33A00, + [ASPEED_DEV_UART12] = 0x14C33B00, [ASPEED_DEV_WDT] = 0x14C37000, [ASPEED_DEV_SPI_BOOT] = 0x100000000, + [ASPEED_DEV_LTPI] = 0x300000000, [ASPEED_DEV_SDRAM] = 0x400000000, }; @@ -91,6 +106,8 @@ static const int aspeed_soc_ast2700a0_irqmap[] = { [ASPEED_DEV_TIMER7] = 22, [ASPEED_DEV_TIMER8] = 23, [ASPEED_DEV_DP] = 28, + [ASPEED_DEV_EHCI1] = 33, + [ASPEED_DEV_EHCI2] = 37, [ASPEED_DEV_LPC] = 128, [ASPEED_DEV_IBT] = 128, [ASPEED_DEV_KCS] = 128, @@ -137,6 +154,8 @@ static const int aspeed_soc_ast2700a1_irqmap[] = { [ASPEED_DEV_TIMER7] = 22, [ASPEED_DEV_TIMER8] = 23, [ASPEED_DEV_DP] = 28, + [ASPEED_DEV_EHCI1] = 33, + [ASPEED_DEV_EHCI2] = 37, [ASPEED_DEV_LPC] = 192, [ASPEED_DEV_IBT] = 192, [ASPEED_DEV_KCS] = 192, @@ -212,6 +231,8 @@ static const int ast2700_gic132_gic196_intcmap[] = { [ASPEED_DEV_UART10] = 16, [ASPEED_DEV_UART11] = 17, [ASPEED_DEV_UART12] = 18, + [ASPEED_DEV_EHCI3] = 28, + [ASPEED_DEV_EHCI4] = 29, }; /* GICINT 133 */ @@ -325,8 +346,9 @@ static void aspeed_ram_capacity_write(void *opaque, hwaddr addr, uint64_t data, * If writes the data to the address which is beyond the ram size, * it would write the data to the "address % ram_size". */ - result = address_space_write(&s->dram_as, addr % ram_size, - MEMTXATTRS_UNSPECIFIED, &data, 4); + address_space_stl_le(&s->dram_as, addr % ram_size, data, + MEMTXATTRS_UNSPECIFIED, &result); + if (result != MEMTX_OK) { qemu_log_mask(LOG_GUEST_ERROR, "%s: DRAM write failed, addr:0x%" HWADDR_PRIx @@ -339,9 +361,10 @@ static const MemoryRegionOps aspeed_ram_capacity_ops = { .read = aspeed_ram_capacity_read, .write = aspeed_ram_capacity_write, .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, .valid = { - .min_access_size = 1, - .max_access_size = 8, + .min_access_size = 4, + .max_access_size = 4, }, }; @@ -434,6 +457,11 @@ static void aspeed_soc_ast2700_init(Object *obj) object_initialize_child(obj, "spi[*]", &s->spi[i], typename); } + for (i = 0; i < sc->ehcis_num; i++) { + object_initialize_child(obj, "ehci[*]", &s->ehci[i], + TYPE_PLATFORM_EHCI); + } + snprintf(typename, sizeof(typename), "aspeed.sdmc-%s", socname); object_initialize_child(obj, "sdmc", &s->sdmc, typename); object_property_add_alias(obj, "ram-size", OBJECT(&s->sdmc), @@ -491,6 +519,16 @@ static void aspeed_soc_ast2700_init(Object *obj) snprintf(typename, sizeof(typename), "aspeed.hace-%s", socname); object_initialize_child(obj, "hace", &s->hace, typename); + object_initialize_child(obj, "dpmcu", &s->dpmcu, + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "ltpi", &s->ltpi, + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "iomem", &s->iomem, + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "iomem0", &s->iomem0, + TYPE_UNIMPLEMENTED_DEVICE); + object_initialize_child(obj, "iomem1", &s->iomem1, + TYPE_UNIMPLEMENTED_DEVICE); } /* @@ -526,8 +564,11 @@ static bool aspeed_soc_ast2700_gic_realize(DeviceState *dev, Error **errp) if (!sysbus_realize(gicbusdev, errp)) { return false; } - sysbus_mmio_map(gicbusdev, 0, sc->memmap[ASPEED_GIC_DIST]); - sysbus_mmio_map(gicbusdev, 1, sc->memmap[ASPEED_GIC_REDIST]); + + aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->gic), 0, + sc->memmap[ASPEED_GIC_DIST]); + aspeed_mmio_map(s, SYS_BUS_DEVICE(&a->gic), 1, + sc->memmap[ASPEED_GIC_REDIST]); for (i = 0; i < sc->num_cpus; i++) { DeviceState *cpudev = DEVICE(&a->cpu[i]); @@ -577,7 +618,7 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) AspeedSoCClass *sc = ASPEED_SOC_GET_CLASS(s); AspeedINTCClass *ic = ASPEED_INTC_GET_CLASS(&a->intc[0]); AspeedINTCClass *icio = ASPEED_INTC_GET_CLASS(&a->intc[1]); - g_autofree char *sram_name = NULL; + g_autofree char *name = NULL; qemu_irq irq; /* Default boot region (SPI memory or ROMs) */ @@ -649,14 +690,22 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) } /* SRAM */ - sram_name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index); - if (!memory_region_init_ram(&s->sram, OBJECT(s), sram_name, sc->sram_size, - errp)) { + name = g_strdup_printf("aspeed.sram.%d", CPU(&a->cpu[0])->cpu_index); + if (!memory_region_init_ram(&s->sram, OBJECT(s), name, sc->sram_size, + errp)) { return; } memory_region_add_subregion(s->memory, sc->memmap[ASPEED_DEV_SRAM], &s->sram); + /* VBOOTROM */ + if (!memory_region_init_ram(&s->vbootrom, OBJECT(s), "aspeed.vbootrom", + 0x20000, errp)) { + return; + } + memory_region_add_subregion(s->memory, + sc->memmap[ASPEED_DEV_VBOOTROM], &s->vbootrom); + /* SCU */ if (!sysbus_realize(SYS_BUS_DEVICE(&s->scu), errp)) { return; @@ -709,6 +758,17 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) ASPEED_SMC_GET_CLASS(&s->spi[i])->flash_window_base); } + /* EHCI */ + for (i = 0; i < sc->ehcis_num; i++) { + if (!sysbus_realize(SYS_BUS_DEVICE(&s->ehci[i]), errp)) { + return; + } + aspeed_mmio_map(s, SYS_BUS_DEVICE(&s->ehci[i]), 0, + sc->memmap[ASPEED_DEV_EHCI1 + i]); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->ehci[i]), 0, + aspeed_soc_get_irq(s, ASPEED_DEV_EHCI1 + i)); + } + /* * SDMC - SDRAM Memory Controller * The SDMC controller is unlocked at SPL stage. @@ -876,14 +936,29 @@ static void aspeed_soc_ast2700_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->hace), 0, aspeed_soc_get_irq(s, ASPEED_DEV_HACE)); - create_unimplemented_device("ast2700.dpmcu", 0x11000000, 0x40000); - create_unimplemented_device("ast2700.iomem0", 0x12000000, 0x01000000); - create_unimplemented_device("ast2700.iomem1", 0x14000000, 0x01000000); - create_unimplemented_device("ast2700.ltpi", 0x30000000, 0x1000000); - create_unimplemented_device("ast2700.io", 0x0, 0x4000000); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->dpmcu), + "aspeed.dpmcu", + sc->memmap[ASPEED_DEV_DPMCU], + AST2700_SOC_DPMCU_SIZE); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->ltpi), + "aspeed.ltpi", + sc->memmap[ASPEED_DEV_LTPI], + AST2700_SOC_LTPI_SIZE); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem), + "aspeed.io", + sc->memmap[ASPEED_DEV_IOMEM], + AST2700_SOC_IO_SIZE); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem0), + "aspeed.iomem0", + sc->memmap[ASPEED_DEV_IOMEM0], + AST2700_SOC_IOMEM_SIZE); + aspeed_mmio_map_unimplemented(s, SYS_BUS_DEVICE(&s->iomem1), + "aspeed.iomem1", + sc->memmap[ASPEED_DEV_IOMEM1], + AST2700_SOC_IOMEM_SIZE); } -static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data) +static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a35"), @@ -900,6 +975,7 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2700_A0_SILICON_REV; sc->sram_size = 0x20000; sc->spis_num = 3; + sc->ehcis_num = 2; sc->wdts_num = 8; sc->macs_num = 1; sc->uarts_num = 13; @@ -910,7 +986,7 @@ static void aspeed_soc_ast2700a0_class_init(ObjectClass *oc, void *data) sc->get_irq = aspeed_soc_ast2700_get_irq; } -static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, void *data) +static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a35"), @@ -927,6 +1003,7 @@ static void aspeed_soc_ast2700a1_class_init(ObjectClass *oc, void *data) sc->silicon_rev = AST2700_A1_SILICON_REV; sc->sram_size = 0x20000; sc->spis_num = 3; + sc->ehcis_num = 4; sc->wdts_num = 8; sc->macs_num = 3; sc->uarts_num = 13; diff --git a/hw/arm/aspeed_soc_common.c b/hw/arm/aspeed_soc_common.c index 1ddcb26..1c4ac93 100644 --- a/hw/arm/aspeed_soc_common.c +++ b/hw/arm/aspeed_soc_common.c @@ -146,7 +146,7 @@ static const Property aspeed_soc_properties[] = { MemoryRegion *), }; -static void aspeed_soc_class_init(ObjectClass *oc, void *data) +static void aspeed_soc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); AspeedSoCClass *sc = ASPEED_SOC_CLASS(oc); diff --git a/hw/arm/b-l475e-iot01a.c b/hw/arm/b-l475e-iot01a.c index c9a5209..34ed2e0 100644 --- a/hw/arm/b-l475e-iot01a.c +++ b/hw/arm/b-l475e-iot01a.c @@ -110,7 +110,7 @@ static void bl475e_init(MachineState *machine) } } -static void bl475e_machine_init(ObjectClass *oc, void *data) +static void bl475e_machine_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char *machine_valid_cpu_types[] = { diff --git a/hw/arm/bananapi_m2u.c b/hw/arm/bananapi_m2u.c index 4d84d10..b750a57 100644 --- a/hw/arm/bananapi_m2u.c +++ b/hw/arm/bananapi_m2u.c @@ -19,7 +19,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/boards.h" diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c index adc9730..8a1e72d 100644 --- a/hw/arm/bcm2835_peripherals.c +++ b/hw/arm/bcm2835_peripherals.c @@ -520,7 +520,7 @@ void bcm_soc_peripherals_common_realize(DeviceState *dev, Error **errp) create_unimp(s, &s->sdramc, "bcm2835-sdramc", SDRAMC_OFFSET, 0x100); } -static void bcm2835_peripherals_class_init(ObjectClass *oc, void *data) +static void bcm2835_peripherals_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); BCMSocPeripheralBaseClass *bc = BCM_SOC_PERIPHERALS_BASE_CLASS(oc); diff --git a/hw/arm/bcm2836.c b/hw/arm/bcm2836.c index 95e1680..cd61ba1 100644 --- a/hw/arm/bcm2836.c +++ b/hw/arm/bcm2836.c @@ -163,7 +163,7 @@ static void bcm2836_realize(DeviceState *dev, Error **errp) } } -static void bcm283x_base_class_init(ObjectClass *oc, void *data) +static void bcm283x_base_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -171,7 +171,7 @@ static void bcm283x_base_class_init(ObjectClass *oc, void *data) dc->user_creatable = false; } -static void bcm2835_class_init(ObjectClass *oc, void *data) +static void bcm2835_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); BCM283XBaseClass *bc = BCM283X_BASE_CLASS(oc); @@ -182,7 +182,7 @@ static void bcm2835_class_init(ObjectClass *oc, void *data) dc->realize = bcm2835_realize; }; -static void bcm2836_class_init(ObjectClass *oc, void *data) +static void bcm2836_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); BCM283XBaseClass *bc = BCM283X_BASE_CLASS(oc); @@ -196,7 +196,7 @@ static void bcm2836_class_init(ObjectClass *oc, void *data) }; #ifdef TARGET_AARCH64 -static void bcm2837_class_init(ObjectClass *oc, void *data) +static void bcm2837_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); BCM283XBaseClass *bc = BCM283X_BASE_CLASS(oc); diff --git a/hw/arm/bcm2838.c b/hw/arm/bcm2838.c index ddb7c5f..22aa754 100644 --- a/hw/arm/bcm2838.c +++ b/hw/arm/bcm2838.c @@ -233,7 +233,7 @@ static void bcm2838_realize(DeviceState *dev, Error **errp) qdev_pass_gpios(DEVICE(&s->gic), DEVICE(&s->peripherals), NULL); } -static void bcm2838_class_init(ObjectClass *oc, void *data) +static void bcm2838_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); BCM283XBaseClass *bc_base = BCM283X_BASE_CLASS(oc); diff --git a/hw/arm/bcm2838_peripherals.c b/hw/arm/bcm2838_peripherals.c index e28bef4..812b5b8 100644 --- a/hw/arm/bcm2838_peripherals.c +++ b/hw/arm/bcm2838_peripherals.c @@ -196,7 +196,7 @@ static void bcm2838_peripherals_realize(DeviceState *dev, Error **errp) create_unimp(s_base, &s->asb, "bcm2838-asb", BRDG_OFFSET, 0x24); } -static void bcm2838_peripherals_class_init(ObjectClass *oc, void *data) +static void bcm2838_peripherals_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); BCM2838PeripheralClass *bc = BCM2838_PERIPHERALS_CLASS(oc); diff --git a/hw/arm/boot.c b/hw/arm/boot.c index e296b62f..becd827 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -14,9 +14,12 @@ #include <libfdt.h> #include "hw/arm/boot.h" #include "hw/arm/linux-boot-if.h" +#include "cpu.h" +#include "exec/target_page.h" #include "system/kvm.h" #include "system/tcg.h" #include "system/system.h" +#include "system/memory.h" #include "system/numa.h" #include "hw/boards.h" #include "system/reset.h" @@ -524,7 +527,7 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, if (binfo->dtb_filename) { char *filename; - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename); + filename = qemu_find_file(QEMU_FILE_TYPE_DTB, binfo->dtb_filename); if (!filename) { fprintf(stderr, "Couldn't open dtb file %s\n", binfo->dtb_filename); goto fail; @@ -741,7 +744,7 @@ static void do_cpu_reset(void *opaque) } else { if (arm_feature(env, ARM_FEATURE_EL3) && (info->secure_boot || - (info->secure_board_setup && cs == first_cpu))) { + (info->secure_board_setup && cpu == info->primary_cpu))) { /* Start this CPU in Secure SVC */ target_el = 3; } @@ -749,7 +752,7 @@ static void do_cpu_reset(void *opaque) arm_emulate_firmware_reset(cs, target_el); - if (cs == first_cpu) { + if (cpu == info->primary_cpu) { AddressSpace *as = arm_boot_address_space(cpu, info); cpu_set_pc(cs, info->loader_start); @@ -1236,6 +1239,9 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) info->dtb_filename = ms->dtb; info->dtb_limit = 0; + /* We assume the CPU passed as argument is the primary CPU. */ + info->primary_cpu = cpu; + /* Load the kernel. */ if (!info->kernel_filename || info->firmware_loaded) { arm_setup_firmware_boot(cpu, info); @@ -1285,12 +1291,8 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) object_property_set_int(cpuobj, "psci-conduit", info->psci_conduit, &error_abort); - /* - * Secondary CPUs start in PSCI powered-down state. Like the - * code in do_cpu_reset(), we assume first_cpu is the primary - * CPU. - */ - if (cs != first_cpu) { + /* Secondary CPUs start in PSCI powered-down state. */ + if (ARM_CPU(cs) != info->primary_cpu) { object_property_set_bool(cpuobj, "start-powered-off", true, &error_abort); } diff --git a/hw/arm/collie.c b/hw/arm/collie.c index eaa5c52..93bb190 100644 --- a/hw/arm/collie.c +++ b/hw/arm/collie.c @@ -16,7 +16,7 @@ #include "strongarm.h" #include "hw/arm/boot.h" #include "hw/block/flash.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/object.h" #include "qemu/error-report.h" @@ -69,7 +69,7 @@ static void collie_init(MachineState *machine) arm_load_kernel(cms->sa1110->cpu, machine, &collie_binfo); } -static void collie_machine_class_init(ObjectClass *oc, void *data) +static void collie_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/digic.c b/hw/arm/digic.c index 5836619..d831bc9 100644 --- a/hw/arm/digic.c +++ b/hw/arm/digic.c @@ -79,7 +79,7 @@ static void digic_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(sbd, 0, DIGIC_UART_BASE); } -static void digic_class_init(ObjectClass *oc, void *data) +static void digic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/digic_boards.c b/hw/arm/digic_boards.c index 2492faf..466b8b8 100644 --- a/hw/arm/digic_boards.c +++ b/hw/arm/digic_boards.c @@ -80,7 +80,7 @@ static void digic4_board_init(MachineState *machine, DigicBoard *board) static void digic_load_rom(DigicState *s, hwaddr addr, hwaddr max_size, const char *filename) { - target_long rom_size; + ssize_t rom_size; if (qtest_enabled()) { /* qtest runs no code so don't attempt a ROM load which diff --git a/hw/arm/exynos4210.c b/hw/arm/exynos4210.c index 0c27588..76001ff 100644 --- a/hw/arm/exynos4210.c +++ b/hw/arm/exynos4210.c @@ -842,7 +842,7 @@ static void exynos4210_init(Object *obj) TYPE_EXYNOS4210_COMBINER); } -static void exynos4210_class_init(ObjectClass *klass, void *data) +static void exynos4210_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/exynos4_boards.c b/hw/arm/exynos4_boards.c index 43dc89d..7304974 100644 --- a/hw/arm/exynos4_boards.c +++ b/hw/arm/exynos4_boards.c @@ -28,7 +28,7 @@ #include "hw/sysbus.h" #include "net/net.h" #include "hw/arm/boot.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/exynos4210.h" #include "hw/net/lan9118.h" #include "hw/qdev-properties.h" @@ -154,7 +154,7 @@ static const char * const valid_cpu_types[] = { NULL }; -static void nuri_class_init(ObjectClass *oc, void *data) +static void nuri_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -174,7 +174,7 @@ static const TypeInfo nuri_type = { .class_init = nuri_class_init, }; -static void smdkc210_class_init(ObjectClass *oc, void *data) +static void smdkc210_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/fby35.c b/hw/arm/fby35.c index 6d3663f..c14fc2e 100644 --- a/hw/arm/fby35.c +++ b/hw/arm/fby35.c @@ -77,6 +77,7 @@ static void fby35_bmc_init(Fby35State *s) memory_region_init(&s->bmc_memory, OBJECT(&s->bmc), "bmc-memory", UINT64_MAX); + memory_region_add_subregion(get_system_memory(), 0, &s->bmc_memory); memory_region_init_ram(&s->bmc_dram, OBJECT(&s->bmc), "bmc-dram", FBY35_BMC_RAM_SIZE, &error_abort); @@ -162,7 +163,7 @@ static void fby35_instance_init(Object *obj) FBY35(obj)->mmio_exec = false; } -static void fby35_class_init(ObjectClass *oc, void *data) +static void fby35_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c index 02214ca..7aad635 100644 --- a/hw/arm/fsl-imx25.c +++ b/hw/arm/fsl-imx25.c @@ -311,7 +311,7 @@ static const Property fsl_imx25_properties[] = { DEFINE_PROP_UINT32("fec-phy-num", FslIMX25State, phy_num, 0), }; -static void fsl_imx25_class_init(ObjectClass *oc, void *data) +static void fsl_imx25_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c index 9de0f21..e9f70ad 100644 --- a/hw/arm/fsl-imx31.c +++ b/hw/arm/fsl-imx31.c @@ -23,7 +23,7 @@ #include "qapi/error.h" #include "hw/arm/fsl-imx31.h" #include "system/system.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/qdev-properties.h" #include "chardev/char.h" #include "target/arm/cpu-qom.h" @@ -218,7 +218,7 @@ static void fsl_imx31_realize(DeviceState *dev, Error **errp) &s->iram_alias); } -static void fsl_imx31_class_init(ObjectClass *oc, void *data) +static void fsl_imx31_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/fsl-imx6.c b/hw/arm/fsl-imx6.c index a114dc0..f3a6002 100644 --- a/hw/arm/fsl-imx6.c +++ b/hw/arm/fsl-imx6.c @@ -484,7 +484,7 @@ static const Property fsl_imx6_properties[] = { DEFINE_PROP_UINT32("fec-phy-num", FslIMX6State, phy_num, 0), }; -static void fsl_imx6_class_init(ObjectClass *oc, void *data) +static void fsl_imx6_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/fsl-imx6ul.c b/hw/arm/fsl-imx6ul.c index ce8d3ef..883c7fc 100644 --- a/hw/arm/fsl-imx6ul.c +++ b/hw/arm/fsl-imx6ul.c @@ -715,7 +715,7 @@ static const Property fsl_imx6ul_properties[] = { true), }; -static void fsl_imx6ul_class_init(ObjectClass *oc, void *data) +static void fsl_imx6ul_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/fsl-imx7.c b/hw/arm/fsl-imx7.c index ed1f10b..02f7602 100644 --- a/hw/arm/fsl-imx7.c +++ b/hw/arm/fsl-imx7.c @@ -748,7 +748,7 @@ static const Property fsl_imx7_properties[] = { true), }; -static void fsl_imx7_class_init(ObjectClass *oc, void *data) +static void fsl_imx7_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/fsl-imx8mp.c b/hw/arm/fsl-imx8mp.c index 82edf61..23e662c 100644 --- a/hw/arm/fsl-imx8mp.c +++ b/hw/arm/fsl-imx8mp.c @@ -9,7 +9,7 @@ */ #include "qemu/osdep.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/bsa.h" #include "hw/arm/fsl-imx8mp.h" #include "hw/intc/arm_gicv3.h" @@ -689,7 +689,7 @@ static const Property fsl_imx8mp_properties[] = { DEFINE_PROP_BOOL("fec1-phy-connected", FslImx8mpState, phy_connected, true), }; -static void fsl_imx8mp_class_init(ObjectClass *oc, void *data) +static void fsl_imx8mp_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index 0f3c207..3ae26eb 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -139,7 +139,7 @@ static void highbank_regs_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); } -static void highbank_regs_class_init(ObjectClass *klass, void *data) +static void highbank_regs_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -341,7 +341,7 @@ static void midway_init(MachineState *machine) calxeda_init(machine, CALXEDA_MIDWAY); } -static void highbank_class_init(ObjectClass *oc, void *data) +static void highbank_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a9"), @@ -365,7 +365,7 @@ static const TypeInfo highbank_type = { .class_init = highbank_class_init, }; -static void midway_class_init(ObjectClass *oc, void *data) +static void midway_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a15"), diff --git a/hw/arm/imx8mp-evk.c b/hw/arm/imx8mp-evk.c index b5aec06e..b3082fa 100644 --- a/hw/arm/imx8mp-evk.c +++ b/hw/arm/imx8mp-evk.c @@ -7,7 +7,7 @@ */ #include "qemu/osdep.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/boot.h" #include "hw/arm/fsl-imx8mp.h" #include "hw/boards.h" diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c index 8aa2e6e..b1d8fbd 100644 --- a/hw/arm/integratorcp.c +++ b/hw/arm/integratorcp.c @@ -16,7 +16,7 @@ #include "hw/misc/arm_integrator_debug.h" #include "hw/net/smc91c111.h" #include "net/net.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/runstate.h" #include "system/system.h" #include "qemu/log.h" @@ -699,7 +699,7 @@ static const Property core_properties[] = { DEFINE_PROP_UINT32("memsz", IntegratorCMState, memsz, 0), }; -static void core_class_init(ObjectClass *klass, void *data) +static void core_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -708,14 +708,14 @@ static void core_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_integratorcm; } -static void icp_pic_class_init(ObjectClass *klass, void *data) +static void icp_pic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->vmsd = &vmstate_icp_pic; } -static void icp_control_class_init(ObjectClass *klass, void *data) +static void icp_control_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/kzm.c b/hw/arm/kzm.c index 08d2b30..362c145 100644 --- a/hw/arm/kzm.c +++ b/hw/arm/kzm.c @@ -19,7 +19,7 @@ #include "hw/arm/boot.h" #include "hw/boards.h" #include "qemu/error-report.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "net/net.h" #include "hw/net/lan9118.h" #include "hw/char/serial-mm.h" diff --git a/hw/arm/meson.build b/hw/arm/meson.build index ac473ce..d90be8f 100644 --- a/hw/arm/meson.build +++ b/hw/arm/meson.build @@ -1,78 +1,85 @@ arm_ss = ss.source_set() -arm_ss.add(files('boot.c')) +arm_common_ss = ss.source_set() arm_ss.add(when: 'CONFIG_ARM_VIRT', if_true: files('virt.c')) arm_ss.add(when: 'CONFIG_ACPI', if_true: files('virt-acpi-build.c')) -arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c')) -arm_ss.add(when: 'CONFIG_EMCRAFT_SF2', if_true: files('msf2-som.c')) -arm_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c')) -arm_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c')) -arm_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c')) -arm_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c')) -arm_ss.add(when: 'CONFIG_MUSICPAL', if_true: files('musicpal.c')) -arm_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c')) -arm_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c')) -arm_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c')) -arm_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c', 'npcm8xx_boards.c')) -arm_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c')) +arm_common_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic_boards.c')) +arm_common_ss.add(when: 'CONFIG_EMCRAFT_SF2', if_true: files('msf2-som.c')) +arm_common_ss.add(when: 'CONFIG_HIGHBANK', if_true: files('highbank.c')) +arm_common_ss.add(when: 'CONFIG_INTEGRATOR', if_true: files('integratorcp.c')) +arm_common_ss.add(when: 'CONFIG_MICROBIT', if_true: files('microbit.c')) +arm_common_ss.add(when: 'CONFIG_MPS3R', if_true: files('mps3r.c')) +arm_common_ss.add(when: 'CONFIG_MUSICPAL', if_true: [files('musicpal.c')]) +arm_common_ss.add(when: 'CONFIG_NETDUINOPLUS2', if_true: files('netduinoplus2.c')) +arm_common_ss.add(when: 'CONFIG_OLIMEX_STM32_H405', if_true: files('olimex-stm32-h405.c')) +arm_common_ss.add(when: 'CONFIG_NPCM7XX', if_true: files('npcm7xx.c', 'npcm7xx_boards.c')) +arm_common_ss.add(when: 'CONFIG_NPCM8XX', if_true: files('npcm8xx.c', 'npcm8xx_boards.c')) +arm_common_ss.add(when: 'CONFIG_REALVIEW', if_true: files('realview.c')) arm_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa-ref.c')) -arm_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c')) -arm_ss.add(when: 'CONFIG_STM32VLDISCOVERY', if_true: files('stm32vldiscovery.c')) -arm_ss.add(when: 'CONFIG_ZYNQ', if_true: files('xilinx_zynq.c')) -arm_ss.add(when: 'CONFIG_SABRELITE', if_true: files('sabrelite.c')) +arm_common_ss.add(when: 'CONFIG_STELLARIS', if_true: files('stellaris.c')) +arm_common_ss.add(when: 'CONFIG_STM32VLDISCOVERY', if_true: files('stm32vldiscovery.c')) +arm_common_ss.add(when: 'CONFIG_ZYNQ', if_true: files('xilinx_zynq.c')) +arm_common_ss.add(when: 'CONFIG_SABRELITE', if_true: files('sabrelite.c')) -arm_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m.c')) -arm_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210.c')) -arm_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic.c')) -arm_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c')) -arm_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c')) -arm_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c')) -arm_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c')) +arm_common_ss.add(when: 'CONFIG_ARM_V7M', if_true: files('armv7m.c')) +arm_common_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4210.c')) +arm_common_ss.add(when: 'CONFIG_DIGIC', if_true: files('digic.c')) +arm_common_ss.add(when: 'CONFIG_OMAP', if_true: files('omap1.c')) +arm_common_ss.add(when: 'CONFIG_ALLWINNER_A10', if_true: files('allwinner-a10.c', 'cubieboard.c')) +arm_common_ss.add(when: 'CONFIG_ALLWINNER_H3', if_true: files('allwinner-h3.c', 'orangepi.c')) +arm_common_ss.add(when: 'CONFIG_ALLWINNER_R40', if_true: files('allwinner-r40.c', 'bananapi_m2u.c')) arm_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2836.c', 'raspi.c')) -arm_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c', 'raspi4b.c')) -arm_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c')) -arm_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c')) -arm_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c')) -arm_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-iot01a.c')) -arm_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c')) -arm_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c')) -arm_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX31', if_true: files('fsl-imx31.c', 'kzm.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX6', if_true: files('fsl-imx6.c')) +arm_common_ss.add(when: ['CONFIG_RASPI', 'TARGET_AARCH64'], if_true: files('bcm2838.c', 'raspi4b.c')) +arm_common_ss.add(when: 'CONFIG_STM32F100_SOC', if_true: files('stm32f100_soc.c')) +arm_common_ss.add(when: 'CONFIG_STM32F205_SOC', if_true: files('stm32f205_soc.c')) +arm_common_ss.add(when: 'CONFIG_STM32F405_SOC', if_true: files('stm32f405_soc.c')) +arm_common_ss.add(when: 'CONFIG_B_L475E_IOT01A', if_true: files('b-l475e-iot01a.c')) +arm_common_ss.add(when: 'CONFIG_STM32L4X5_SOC', if_true: files('stm32l4x5_soc.c')) +arm_common_ss.add(when: 'CONFIG_XLNX_ZYNQMP_ARM', if_true: files('xlnx-zynqmp.c', 'xlnx-zcu102.c')) +arm_common_ss.add(when: 'CONFIG_XLNX_VERSAL', if_true: files('xlnx-versal.c', 'xlnx-versal-virt.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX25', if_true: files('fsl-imx25.c', 'imx25_pdk.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX31', if_true: files('fsl-imx31.c', 'kzm.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX6', if_true: files('fsl-imx6.c')) arm_ss.add(when: 'CONFIG_ASPEED_SOC', if_true: files( 'aspeed.c', 'aspeed_soc_common.c', 'aspeed_ast2400.c', 'aspeed_ast2600.c', + 'aspeed_ast27x0-ssp.c', + 'aspeed_ast27x0-tsp.c', 'aspeed_ast10x0.c', 'aspeed_eeprom.c', 'fby35.c')) -arm_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files('aspeed_ast27x0.c')) -arm_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2.c')) -arm_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2-tz.c')) -arm_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-soc.c')) -arm_ss.add(when: 'CONFIG_MUSCA', if_true: files('musca.c')) -arm_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c')) -arm_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c')) -arm_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c')) -arm_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c')) +arm_common_ss.add(when: ['CONFIG_ASPEED_SOC', 'TARGET_AARCH64'], if_true: files( + 'aspeed_ast27x0.c', + 'aspeed_ast27x0-fc.c',)) +arm_common_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2.c')) +arm_common_ss.add(when: 'CONFIG_MPS2', if_true: files('mps2-tz.c')) +arm_common_ss.add(when: 'CONFIG_MSF2', if_true: files('msf2-soc.c')) +arm_common_ss.add(when: 'CONFIG_MUSCA', if_true: files('musca.c')) +arm_common_ss.add(when: 'CONFIG_ARMSSE', if_true: files('armsse.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX7', if_true: files('fsl-imx7.c', 'mcimx7d-sabre.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP', if_true: files('fsl-imx8mp.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX8MP_EVK', if_true: files('imx8mp-evk.c')) +arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmuv3.c')) +arm_common_ss.add(when: 'CONFIG_FSL_IMX6UL', if_true: files('fsl-imx6ul.c', 'mcimx6ul-evk.c')) +arm_common_ss.add(when: 'CONFIG_NRF51_SOC', if_true: files('nrf51_soc.c')) arm_ss.add(when: 'CONFIG_XEN', if_true: files( 'xen-stubs.c', 'xen-pvh.c', )) -system_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c')) -system_ss.add(when: 'CONFIG_COLLIE', if_true: files('collie.c')) -system_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c')) -system_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c')) -system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c')) -system_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_peripherals.c')) -system_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c')) -system_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c')) -system_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c')) -system_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c')) +arm_common_ss.add(when: 'CONFIG_ARM_SMMUV3', if_true: files('smmu-common.c')) +arm_common_ss.add(when: 'CONFIG_COLLIE', if_true: files('collie.c')) +arm_common_ss.add(when: 'CONFIG_EXYNOS4', if_true: files('exynos4_boards.c')) +arm_common_ss.add(when: 'CONFIG_NETDUINO2', if_true: files('netduino2.c')) +arm_common_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2835_peripherals.c')) +arm_common_ss.add(when: 'CONFIG_RASPI', if_true: files('bcm2838_peripherals.c')) +arm_common_ss.add(when: 'CONFIG_STRONGARM', if_true: files('strongarm.c')) +arm_common_ss.add(when: 'CONFIG_SX1', if_true: files('omap_sx1.c')) +arm_common_ss.add(when: 'CONFIG_VERSATILE', if_true: files('versatilepb.c')) +arm_common_ss.add(when: 'CONFIG_VEXPRESS', if_true: files('vexpress.c')) + +arm_common_ss.add(files('boot.c')) hw_arch += {'arm': arm_ss} +hw_common_arch += {'arm': arm_common_ss} diff --git a/hw/arm/microbit.c b/hw/arm/microbit.c index 3f56fb4..525443f 100644 --- a/hw/arm/microbit.c +++ b/hw/arm/microbit.c @@ -13,7 +13,7 @@ #include "hw/boards.h" #include "hw/arm/boot.h" #include "system/system.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/nrf51_soc.h" #include "hw/i2c/microbit_i2c.h" @@ -60,7 +60,7 @@ static void microbit_init(MachineState *machine) 0, s->nrf51.flash_size); } -static void microbit_machine_class_init(ObjectClass *oc, void *data) +static void microbit_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/mps2-tz.c b/hw/arm/mps2-tz.c index 13ed868..5dd87cc 100644 --- a/hw/arm/mps2-tz.c +++ b/hw/arm/mps2-tz.c @@ -54,7 +54,7 @@ #include "hw/arm/armv7m.h" #include "hw/or-irq.h" #include "hw/boards.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "system/reset.h" #include "hw/misc/unimp.h" @@ -1267,7 +1267,7 @@ static void mps2_machine_reset(MachineState *machine, ResetType type) qemu_devices_reset(type); } -static void mps2tz_class_init(ObjectClass *oc, void *data) +static void mps2tz_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); IDAUInterfaceClass *iic = IDAU_INTERFACE_CLASS(oc); @@ -1304,7 +1304,7 @@ static void mps2tz_set_default_ram_info(MPS2TZMachineClass *mmc) g_assert_not_reached(); } -static void mps2tz_an505_class_init(ObjectClass *oc, void *data) +static void mps2tz_an505_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); @@ -1338,7 +1338,7 @@ static void mps2tz_an505_class_init(ObjectClass *oc, void *data) mps2tz_set_default_ram_info(mmc); } -static void mps2tz_an521_class_init(ObjectClass *oc, void *data) +static void mps2tz_an521_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); @@ -1372,7 +1372,7 @@ static void mps2tz_an521_class_init(ObjectClass *oc, void *data) mps2tz_set_default_ram_info(mmc); } -static void mps3tz_an524_class_init(ObjectClass *oc, void *data) +static void mps3tz_an524_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); @@ -1411,7 +1411,7 @@ static void mps3tz_an524_class_init(ObjectClass *oc, void *data) "are BRAM (default) and QSPI."); } -static void mps3tz_an547_class_init(ObjectClass *oc, void *data) +static void mps3tz_an547_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2TZMachineClass *mmc = MPS2TZ_MACHINE_CLASS(oc); @@ -1453,7 +1453,7 @@ static const TypeInfo mps2tz_info = { .instance_size = sizeof(MPS2TZMachineState), .class_size = sizeof(MPS2TZMachineClass), .class_init = mps2tz_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IDAU_INTERFACE }, { } }, diff --git a/hw/arm/mps2.c b/hw/arm/mps2.c index 3f8db0c..bd378e3 100644 --- a/hw/arm/mps2.c +++ b/hw/arm/mps2.c @@ -33,7 +33,7 @@ #include "hw/arm/armv7m.h" #include "hw/or-irq.h" #include "hw/boards.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/qdev-properties.h" #include "hw/misc/unimp.h" @@ -224,7 +224,11 @@ static void mps2_common_init(MachineState *machine) switch (mmc->fpga_type) { case FPGA_AN385: case FPGA_AN386: + qdev_prop_set_uint32(armv7m, "num-irq", 32); + break; case FPGA_AN500: + /* The AN500 configures its Cortex-M7 with 16 MPU regions */ + qdev_prop_set_uint32(armv7m, "mpu-ns-regions", 16); qdev_prop_set_uint32(armv7m, "num-irq", 32); break; case FPGA_AN511: @@ -464,7 +468,7 @@ static void mps2_common_init(MachineState *machine) 0, 0x400000); } -static void mps2_class_init(ObjectClass *oc, void *data) +static void mps2_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -474,7 +478,7 @@ static void mps2_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "mps.ram"; } -static void mps2_an385_class_init(ObjectClass *oc, void *data) +static void mps2_an385_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc); @@ -493,7 +497,7 @@ static void mps2_an385_class_init(ObjectClass *oc, void *data) mmc->has_block_ram = true; } -static void mps2_an386_class_init(ObjectClass *oc, void *data) +static void mps2_an386_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc); @@ -512,7 +516,7 @@ static void mps2_an386_class_init(ObjectClass *oc, void *data) mmc->has_block_ram = true; } -static void mps2_an500_class_init(ObjectClass *oc, void *data) +static void mps2_an500_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc); @@ -531,7 +535,7 @@ static void mps2_an500_class_init(ObjectClass *oc, void *data) mmc->has_block_ram = false; } -static void mps2_an511_class_init(ObjectClass *oc, void *data) +static void mps2_an511_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS2MachineClass *mmc = MPS2_MACHINE_CLASS(oc); diff --git a/hw/arm/mps3r.c b/hw/arm/mps3r.c index 1bddb5e..48c73ac 100644 --- a/hw/arm/mps3r.c +++ b/hw/arm/mps3r.c @@ -28,7 +28,7 @@ #include "qemu/units.h" #include "qapi/error.h" #include "qobject/qlist.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "cpu.h" #include "system/system.h" #include "hw/boards.h" @@ -583,14 +583,14 @@ static void mps3r_set_default_ram_info(MPS3RMachineClass *mmc) g_assert_not_reached(); } -static void mps3r_class_init(ObjectClass *oc, void *data) +static void mps3r_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); mc->init = mps3r_common_init; } -static void mps3r_an536_class_init(ObjectClass *oc, void *data) +static void mps3r_an536_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MPS3RMachineClass *mmc = MPS3R_MACHINE_CLASS(oc); diff --git a/hw/arm/msf2-soc.c b/hw/arm/msf2-soc.c index e8a5b23..c5e9c717 100644 --- a/hw/arm/msf2-soc.c +++ b/hw/arm/msf2-soc.c @@ -25,7 +25,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/char/serial-mm.h" #include "hw/arm/msf2-soc.h" #include "hw/misc/unimp.h" @@ -236,7 +236,7 @@ static const Property m2sxxx_soc_properties[] = { DEFINE_PROP_UINT8("apb1div", MSF2State, apb1div, 2), }; -static void m2sxxx_soc_class_init(ObjectClass *klass, void *data) +static void m2sxxx_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/msf2-som.c b/hw/arm/msf2-som.c index 9b20f1e..29c76c6 100644 --- a/hw/arm/msf2-som.c +++ b/hw/arm/msf2-som.c @@ -33,7 +33,7 @@ #include "hw/qdev-properties.h" #include "hw/arm/boot.h" #include "hw/qdev-clock.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/msf2-soc.h" #define DDR_BASE_ADDRESS 0xA0000000 diff --git a/hw/arm/musca.c b/hw/arm/musca.c index e9c092a..250b3b5 100644 --- a/hw/arm/musca.c +++ b/hw/arm/musca.c @@ -22,7 +22,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/arm/boot.h" #include "hw/arm/armsse.h" @@ -594,7 +594,7 @@ static void musca_init(MachineState *machine) 0, 0x2000000); } -static void musca_class_init(ObjectClass *oc, void *data) +static void musca_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char * const valid_cpu_types[] = { @@ -609,7 +609,7 @@ static void musca_class_init(ObjectClass *oc, void *data) mc->init = musca_init; } -static void musca_a_class_init(ObjectClass *oc, void *data) +static void musca_a_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MuscaMachineClass *mmc = MUSCA_MACHINE_CLASS(oc); @@ -623,7 +623,7 @@ static void musca_a_class_init(ObjectClass *oc, void *data) mmc->num_mpcs = ARRAY_SIZE(a_mpc_info); } -static void musca_b1_class_init(ObjectClass *oc, void *data) +static void musca_b1_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MuscaMachineClass *mmc = MUSCA_MACHINE_CLASS(oc); diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c index 48a32c2..329b162 100644 --- a/hw/arm/musicpal.c +++ b/hw/arm/musicpal.c @@ -286,7 +286,7 @@ static const VMStateDescription musicpal_lcd_vmsd = { } }; -static void musicpal_lcd_class_init(ObjectClass *klass, void *data) +static void musicpal_lcd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -407,7 +407,7 @@ static const VMStateDescription mv88w8618_pic_vmsd = { } }; -static void mv88w8618_pic_class_init(ObjectClass *klass, void *data) +static void mv88w8618_pic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -601,7 +601,7 @@ static const VMStateDescription mv88w8618_pit_vmsd = { } }; -static void mv88w8618_pit_class_init(ObjectClass *klass, void *data) +static void mv88w8618_pit_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -687,7 +687,7 @@ static const VMStateDescription mv88w8618_flashcfg_vmsd = { } }; -static void mv88w8618_flashcfg_class_init(ObjectClass *klass, void *data) +static void mv88w8618_flashcfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1026,7 +1026,7 @@ static const VMStateDescription musicpal_gpio_vmsd = { } }; -static void musicpal_gpio_class_init(ObjectClass *klass, void *data) +static void musicpal_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1171,7 +1171,7 @@ static const VMStateDescription musicpal_key_vmsd = { } }; -static void musicpal_key_class_init(ObjectClass *klass, void *data) +static void musicpal_key_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1348,7 +1348,7 @@ static void musicpal_machine_init(MachineClass *mc) DEFINE_MACHINE("musicpal", musicpal_machine_init) -static void mv88w8618_wlan_class_init(ObjectClass *klass, void *data) +static void mv88w8618_wlan_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/npcm7xx.c b/hw/arm/npcm7xx.c index 2d6e08b..2f30c49 100644 --- a/hw/arm/npcm7xx.c +++ b/hw/arm/npcm7xx.c @@ -821,7 +821,7 @@ static const Property npcm7xx_properties[] = { MemoryRegion *), }; -static void npcm7xx_class_init(ObjectClass *oc, void *data) +static void npcm7xx_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -830,7 +830,7 @@ static void npcm7xx_class_init(ObjectClass *oc, void *data) device_class_set_props(dc, npcm7xx_properties); } -static void npcm730_class_init(ObjectClass *oc, void *data) +static void npcm730_class_init(ObjectClass *oc, const void *data) { NPCM7xxClass *nc = NPCM7XX_CLASS(oc); @@ -839,7 +839,7 @@ static void npcm730_class_init(ObjectClass *oc, void *data) nc->num_cpus = 2; } -static void npcm750_class_init(ObjectClass *oc, void *data) +static void npcm750_class_init(ObjectClass *oc, const void *data) { NPCM7xxClass *nc = NPCM7XX_CLASS(oc); diff --git a/hw/arm/npcm7xx_boards.c b/hw/arm/npcm7xx_boards.c index eb28b97..465a0e5 100644 --- a/hw/arm/npcm7xx_boards.c +++ b/hw/arm/npcm7xx_boards.c @@ -453,7 +453,7 @@ static void npcm7xx_set_soc_type(NPCM7xxMachineClass *nmc, const char *type) mc->default_cpus = mc->min_cpus = mc->max_cpus = sc->num_cpus; } -static void npcm7xx_machine_class_init(ObjectClass *oc, void *data) +static void npcm7xx_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char * const valid_cpu_types[] = { @@ -472,7 +472,7 @@ static void npcm7xx_machine_class_init(ObjectClass *oc, void *data) * Schematics: * https://github.com/Nuvoton-Israel/nuvoton-info/blob/master/npcm7xx-poleg/evaluation-board/board_deliverables/NPCM750x_EB_ver.A1.1_COMPLETE.pdf */ -static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data) +static void npcm750_evb_machine_class_init(ObjectClass *oc, const void *data) { NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); @@ -485,7 +485,7 @@ static void npcm750_evb_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_size = 512 * MiB; }; -static void gsj_machine_class_init(ObjectClass *oc, void *data) +static void gsj_machine_class_init(ObjectClass *oc, const void *data) { NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); @@ -498,7 +498,7 @@ static void gsj_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_size = 512 * MiB; }; -static void gbs_bmc_machine_class_init(ObjectClass *oc, void *data) +static void gbs_bmc_machine_class_init(ObjectClass *oc, const void *data) { NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); @@ -511,7 +511,7 @@ static void gbs_bmc_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_size = 1 * GiB; } -static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data) +static void kudo_bmc_machine_class_init(ObjectClass *oc, const void *data) { NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); @@ -524,7 +524,7 @@ static void kudo_bmc_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_size = 1 * GiB; }; -static void mori_bmc_machine_class_init(ObjectClass *oc, void *data) +static void mori_bmc_machine_class_init(ObjectClass *oc, const void *data) { NPCM7xxMachineClass *nmc = NPCM7XX_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/npcm8xx.c b/hw/arm/npcm8xx.c index f182acc..a276fea 100644 --- a/hw/arm/npcm8xx.c +++ b/hw/arm/npcm8xx.c @@ -67,6 +67,12 @@ /* SDHCI Modules */ #define NPCM8XX_MMC_BA 0xf0842000 +/* PCS Module */ +#define NPCM8XX_PCS_BA 0xf0780000 + +/* PSPI Modules */ +#define NPCM8XX_PSPI_BA 0xf0201000 + /* Run PLL1 at 1600 MHz */ #define NPCM8XX_PLLCON1_FIXUP_VAL 0x00402101 /* Run the CPU from PLL1 and UART from PLL2 */ @@ -82,7 +88,12 @@ enum NPCM8xxInterrupt { NPCM8XX_ADC_IRQ = 0, NPCM8XX_PECI_IRQ = 6, NPCM8XX_KCS_HIB_IRQ = 9, + NPCM8XX_GMAC1_IRQ = 14, + NPCM8XX_GMAC2_IRQ, + NPCM8XX_GMAC3_IRQ, + NPCM8XX_GMAC4_IRQ, NPCM8XX_MMC_IRQ = 26, + NPCM8XX_PSPI_IRQ = 28, NPCM8XX_TIMER0_IRQ = 32, /* Timer Module 0 */ NPCM8XX_TIMER1_IRQ, NPCM8XX_TIMER2_IRQ, @@ -256,6 +267,14 @@ static const hwaddr npcm8xx_smbus_addr[] = { 0xfff0a000, }; +/* Register base address for each GMAC Module */ +static const hwaddr npcm8xx_gmac_addr[] = { + 0xf0802000, + 0xf0804000, + 0xf0806000, + 0xf0808000, +}; + /* Register base address for each USB host EHCI registers */ static const hwaddr npcm8xx_ehci_addr[] = { 0xf0828100, @@ -346,6 +365,7 @@ static struct arm_boot_info npcm8xx_binfo = { .secure_boot = false, .board_id = -1, .board_setup_addr = NPCM8XX_BOARD_SETUP_ADDR, + .psci_conduit = QEMU_PSCI_CONDUIT_SMC, }; void npcm8xx_load_kernel(MachineState *machine, NPCM8xxState *soc) @@ -440,7 +460,13 @@ static void npcm8xx_init(Object *obj) object_initialize_child(obj, "mft[*]", &s->mft[i], TYPE_NPCM7XX_MFT); } + for (i = 0; i < ARRAY_SIZE(s->gmac); i++) { + object_initialize_child(obj, "gmac[*]", &s->gmac[i], TYPE_NPCM_GMAC); + } + object_initialize_child(obj, "pcs", &s->pcs, TYPE_NPCM_PCS); + object_initialize_child(obj, "mmc", &s->mmc, TYPE_NPCM7XX_SDHCI); + object_initialize_child(obj, "pspi", &s->pspi, TYPE_NPCM_PSPI); } static void npcm8xx_realize(DeviceState *dev, Error **errp) @@ -664,6 +690,35 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp) } /* + * GMAC Modules. Cannot fail. + */ + QEMU_BUILD_BUG_ON(ARRAY_SIZE(npcm8xx_gmac_addr) != ARRAY_SIZE(s->gmac)); + for (i = 0; i < ARRAY_SIZE(s->gmac); i++) { + SysBusDevice *sbd = SYS_BUS_DEVICE(&s->gmac[i]); + + /* This is used to make sure that the NIC can create the device */ + qemu_configure_nic_device(DEVICE(sbd), false, NULL); + + /* + * The device exists regardless of whether it's connected to a QEMU + * netdev backend. So always instantiate it even if there is no + * backend. + */ + sysbus_realize(sbd, &error_abort); + sysbus_mmio_map(sbd, 0, npcm8xx_gmac_addr[i]); + /* + * N.B. The values for the second argument sysbus_connect_irq are + * chosen to match the registration order in npcm7xx_emc_realize. + */ + sysbus_connect_irq(sbd, 0, npcm8xx_irq(s, NPCM8XX_GMAC1_IRQ + i)); + } + /* + * GMAC Physical Coding Sublayer(PCS) Module. Cannot fail. + */ + sysbus_realize(SYS_BUS_DEVICE(&s->pcs), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->pcs), 0, NPCM8XX_PCS_BA); + + /* * Flash Interface Unit (FIU). Can fail if incorrect number of chip selects * specified, but this is a programming error. */ @@ -705,6 +760,11 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp) sysbus_connect_irq(SYS_BUS_DEVICE(&s->mmc), 0, npcm8xx_irq(s, NPCM8XX_MMC_IRQ)); + /* PSPI */ + sysbus_realize(SYS_BUS_DEVICE(&s->pspi), &error_abort); + sysbus_mmio_map(SYS_BUS_DEVICE(&s->pspi), 0, NPCM8XX_PSPI_BA); + sysbus_connect_irq(SYS_BUS_DEVICE(&s->pspi), 0, + npcm8xx_irq(s, NPCM8XX_PSPI_IRQ)); create_unimplemented_device("npcm8xx.shm", 0xc0001000, 4 * KiB); create_unimplemented_device("npcm8xx.gicextra", 0xdfffa000, 24 * KiB); @@ -720,7 +780,6 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp) create_unimplemented_device("npcm8xx.siox[1]", 0xf0101000, 4 * KiB); create_unimplemented_device("npcm8xx.siox[2]", 0xf0102000, 4 * KiB); create_unimplemented_device("npcm8xx.tmps", 0xf0188000, 4 * KiB); - create_unimplemented_device("npcm8xx.pspi", 0xf0201000, 4 * KiB); create_unimplemented_device("npcm8xx.viru1", 0xf0204000, 4 * KiB); create_unimplemented_device("npcm8xx.viru2", 0xf0205000, 4 * KiB); create_unimplemented_device("npcm8xx.jtm1", 0xf0208000, 4 * KiB); @@ -732,12 +791,7 @@ static void npcm8xx_realize(DeviceState *dev, Error **errp) create_unimplemented_device("npcm8xx.ahbpci", 0xf0400000, 1 * MiB); create_unimplemented_device("npcm8xx.dap", 0xf0500000, 960 * KiB); create_unimplemented_device("npcm8xx.mcphy", 0xf05f0000, 64 * KiB); - create_unimplemented_device("npcm8xx.pcs", 0xf0780000, 256 * KiB); create_unimplemented_device("npcm8xx.tsgen", 0xf07fc000, 8 * KiB); - create_unimplemented_device("npcm8xx.gmac1", 0xf0802000, 8 * KiB); - create_unimplemented_device("npcm8xx.gmac2", 0xf0804000, 8 * KiB); - create_unimplemented_device("npcm8xx.gmac3", 0xf0806000, 8 * KiB); - create_unimplemented_device("npcm8xx.gmac4", 0xf0808000, 8 * KiB); create_unimplemented_device("npcm8xx.copctl", 0xf080c000, 4 * KiB); create_unimplemented_device("npcm8xx.tipctl", 0xf080d000, 4 * KiB); create_unimplemented_device("npcm8xx.rst", 0xf080e000, 4 * KiB); @@ -779,7 +833,7 @@ static const Property npcm8xx_properties[] = { MemoryRegion *), }; -static void npcm8xx_class_init(ObjectClass *oc, void *data) +static void npcm8xx_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); NPCM8xxClass *nc = NPCM8XX_CLASS(oc); diff --git a/hw/arm/npcm8xx_boards.c b/hw/arm/npcm8xx_boards.c index 3fb8478..3bf3e1f 100644 --- a/hw/arm/npcm8xx_boards.c +++ b/hw/arm/npcm8xx_boards.c @@ -209,11 +209,11 @@ static void npcm8xx_set_soc_type(NPCM8xxMachineClass *nmc, const char *type) mc->default_cpus = mc->min_cpus = mc->max_cpus = sc->num_cpus; } -static void npcm8xx_machine_class_init(ObjectClass *oc, void *data) +static void npcm8xx_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char * const valid_cpu_types[] = { - ARM_CPU_TYPE_NAME("cortex-a9"), + ARM_CPU_TYPE_NAME("cortex-a35"), NULL }; @@ -224,7 +224,7 @@ static void npcm8xx_machine_class_init(ObjectClass *oc, void *data) mc->valid_cpu_types = valid_cpu_types; } -static void npcm845_evb_machine_class_init(ObjectClass *oc, void *data) +static void npcm845_evb_machine_class_init(ObjectClass *oc, const void *data) { NPCM8xxMachineClass *nmc = NPCM8XX_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/nrf51_soc.c b/hw/arm/nrf51_soc.c index dee06ab..d8cc321 100644 --- a/hw/arm/nrf51_soc.c +++ b/hw/arm/nrf51_soc.c @@ -216,7 +216,7 @@ static const Property nrf51_soc_properties[] = { NRF51822_FLASH_SIZE), }; -static void nrf51_soc_class_init(ObjectClass *klass, void *data) +static void nrf51_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 3ee10b4..74458fb 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -23,7 +23,7 @@ #include "qemu/main-loop.h" #include "qapi/error.h" #include "cpu.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/hw.h" #include "hw/irq.h" #include "hw/qdev-properties.h" @@ -144,7 +144,7 @@ static inline void omap_timer_update(struct omap_mpu_timer_s *timer) int64_t expires; if (timer->enable && timer->st && timer->rate) { - timer->val = timer->reset_val; /* Should skip this on clk enable */ + timer->val = timer->reset_val; /* Should skip this on clk enable */ expires = muldiv64((uint64_t) timer->val << (timer->ptv + 1), NANOSECONDS_PER_SECOND, timer->rate); @@ -212,13 +212,13 @@ static uint64_t omap_mpu_timer_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* CNTL_TIMER */ + case 0x00: /* CNTL_TIMER */ return (s->enable << 5) | (s->ptv << 2) | (s->ar << 1) | s->st; - case 0x04: /* LOAD_TIM */ + case 0x04: /* LOAD_TIM */ break; - case 0x08: /* READ_TIM */ + case 0x08: /* READ_TIM */ return omap_timer_read(s); } @@ -237,7 +237,7 @@ static void omap_mpu_timer_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* CNTL_TIMER */ + case 0x00: /* CNTL_TIMER */ omap_timer_sync(s); s->enable = (value >> 5) & 1; s->ptv = (value >> 2) & 7; @@ -246,11 +246,11 @@ static void omap_mpu_timer_write(void *opaque, hwaddr addr, omap_timer_update(s); return; - case 0x04: /* LOAD_TIM */ + case 0x04: /* LOAD_TIM */ s->reset_val = value; return; - case 0x08: /* READ_TIM */ + case 0x08: /* READ_TIM */ OMAP_RO_REG(addr); break; @@ -318,14 +318,14 @@ static uint64_t omap_wd_timer_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* CNTL_TIMER */ + case 0x00: /* CNTL_TIMER */ return (s->timer.ptv << 9) | (s->timer.ar << 8) | (s->timer.st << 7) | (s->free << 1); - case 0x04: /* READ_TIMER */ + case 0x04: /* READ_TIMER */ return omap_timer_read(&s->timer); - case 0x08: /* TIMER_MODE */ + case 0x08: /* TIMER_MODE */ return s->mode << 15; } @@ -344,7 +344,7 @@ static void omap_wd_timer_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* CNTL_TIMER */ + case 0x00: /* CNTL_TIMER */ omap_timer_sync(&s->timer); s->timer.ptv = (value >> 9) & 7; s->timer.ar = (value >> 8) & 1; @@ -353,11 +353,11 @@ static void omap_wd_timer_write(void *opaque, hwaddr addr, omap_timer_update(&s->timer); break; - case 0x04: /* LOAD_TIMER */ + case 0x04: /* LOAD_TIMER */ s->timer.reset_val = value & 0xffff; break; - case 0x08: /* TIMER_MODE */ + case 0x08: /* TIMER_MODE */ if (!s->mode && ((value >> 15) & 1)) omap_clk_get(s->timer.clk); s->mode |= (value >> 15) & 1; @@ -442,13 +442,13 @@ static uint64_t omap_os_timer_read(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* TVR */ + case 0x00: /* TVR */ return s->timer.reset_val; - case 0x04: /* TCR */ + case 0x04: /* TCR */ return omap_timer_read(&s->timer); - case 0x08: /* CR */ + case 0x08: /* CR */ return (s->timer.ar << 3) | (s->timer.it_ena << 2) | s->timer.st; default: @@ -470,15 +470,15 @@ static void omap_os_timer_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* TVR */ + case 0x00: /* TVR */ s->timer.reset_val = value & 0x00ffffff; break; - case 0x04: /* TCR */ + case 0x04: /* TCR */ OMAP_RO_REG(addr); break; - case 0x08: /* CR */ + case 0x08: /* CR */ s->timer.ar = (value >> 3) & 1; s->timer.it_ena = (value >> 2) & 1; if (s->timer.st != (value & 1) || (value & 2)) { @@ -543,34 +543,34 @@ static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x14: /* IT_STATUS */ + case 0x14: /* IT_STATUS */ ret = s->ulpd_pm_regs[addr >> 2]; s->ulpd_pm_regs[addr >> 2] = 0; qemu_irq_lower(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K)); return ret; - case 0x18: /* Reserved */ - case 0x1c: /* Reserved */ - case 0x20: /* Reserved */ - case 0x28: /* Reserved */ - case 0x2c: /* Reserved */ + case 0x18: /* Reserved */ + case 0x1c: /* Reserved */ + case 0x20: /* Reserved */ + case 0x28: /* Reserved */ + case 0x2c: /* Reserved */ OMAP_BAD_REG(addr); /* fall through */ - case 0x00: /* COUNTER_32_LSB */ - case 0x04: /* COUNTER_32_MSB */ - case 0x08: /* COUNTER_HIGH_FREQ_LSB */ - case 0x0c: /* COUNTER_HIGH_FREQ_MSB */ - case 0x10: /* GAUGING_CTRL */ - case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */ - case 0x30: /* CLOCK_CTRL */ - case 0x34: /* SOFT_REQ */ - case 0x38: /* COUNTER_32_FIQ */ - case 0x3c: /* DPLL_CTRL */ - case 0x40: /* STATUS_REQ */ + case 0x00: /* COUNTER_32_LSB */ + case 0x04: /* COUNTER_32_MSB */ + case 0x08: /* COUNTER_HIGH_FREQ_LSB */ + case 0x0c: /* COUNTER_HIGH_FREQ_MSB */ + case 0x10: /* GAUGING_CTRL */ + case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */ + case 0x30: /* CLOCK_CTRL */ + case 0x34: /* SOFT_REQ */ + case 0x38: /* COUNTER_32_FIQ */ + case 0x3c: /* DPLL_CTRL */ + case 0x40: /* STATUS_REQ */ /* XXX: check clk::usecount state for every clock */ - case 0x48: /* LOCL_TIME */ - case 0x4c: /* APLL_CTRL */ - case 0x50: /* POWER_CTRL */ + case 0x48: /* LOCL_TIME */ + case 0x4c: /* APLL_CTRL */ + case 0x50: /* POWER_CTRL */ return s->ulpd_pm_regs[addr >> 2]; } @@ -581,22 +581,22 @@ static uint64_t omap_ulpd_pm_read(void *opaque, hwaddr addr, static inline void omap_ulpd_clk_update(struct omap_mpu_state_s *s, uint16_t diff, uint16_t value) { - if (diff & (1 << 4)) /* USB_MCLK_EN */ + if (diff & (1 << 4)) /* USB_MCLK_EN */ omap_clk_onoff(omap_findclk(s, "usb_clk0"), (value >> 4) & 1); - if (diff & (1 << 5)) /* DIS_USB_PVCI_CLK */ + if (diff & (1 << 5)) /* DIS_USB_PVCI_CLK */ omap_clk_onoff(omap_findclk(s, "usb_w2fc_ck"), (~value >> 5) & 1); } static inline void omap_ulpd_req_update(struct omap_mpu_state_s *s, uint16_t diff, uint16_t value) { - if (diff & (1 << 0)) /* SOFT_DPLL_REQ */ + if (diff & (1 << 0)) /* SOFT_DPLL_REQ */ omap_clk_canidle(omap_findclk(s, "dpll4"), (~value >> 0) & 1); - if (diff & (1 << 1)) /* SOFT_COM_REQ */ + if (diff & (1 << 1)) /* SOFT_COM_REQ */ omap_clk_canidle(omap_findclk(s, "com_mclk_out"), (~value >> 1) & 1); - if (diff & (1 << 2)) /* SOFT_SDW_REQ */ + if (diff & (1 << 2)) /* SOFT_SDW_REQ */ omap_clk_canidle(omap_findclk(s, "bt_mclk_out"), (~value >> 2) & 1); - if (diff & (1 << 3)) /* SOFT_USB_REQ */ + if (diff & (1 << 3)) /* SOFT_USB_REQ */ omap_clk_canidle(omap_findclk(s, "usb_clk0"), (~value >> 3) & 1); } @@ -615,16 +615,16 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* COUNTER_32_LSB */ - case 0x04: /* COUNTER_32_MSB */ - case 0x08: /* COUNTER_HIGH_FREQ_LSB */ - case 0x0c: /* COUNTER_HIGH_FREQ_MSB */ - case 0x14: /* IT_STATUS */ - case 0x40: /* STATUS_REQ */ + case 0x00: /* COUNTER_32_LSB */ + case 0x04: /* COUNTER_32_MSB */ + case 0x08: /* COUNTER_HIGH_FREQ_LSB */ + case 0x0c: /* COUNTER_HIGH_FREQ_MSB */ + case 0x14: /* IT_STATUS */ + case 0x40: /* STATUS_REQ */ OMAP_RO_REG(addr); break; - case 0x10: /* GAUGING_CTRL */ + case 0x10: /* GAUGING_CTRL */ /* Bits 0 and 1 seem to be confused in the OMAP 310 TRM */ if ((s->ulpd_pm_regs[addr >> 2] ^ value) & 1) { now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); @@ -638,50 +638,50 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr, ticks = muldiv64(now, 32768, NANOSECONDS_PER_SECOND); s->ulpd_pm_regs[0x00 >> 2] = (ticks >> 0) & 0xffff; s->ulpd_pm_regs[0x04 >> 2] = (ticks >> 16) & 0xffff; - if (ticks >> 32) /* OVERFLOW_32K */ + if (ticks >> 32) /* OVERFLOW_32K */ s->ulpd_pm_regs[0x14 >> 2] |= 1 << 2; /* High frequency ticks */ ticks = muldiv64(now, 12000000, NANOSECONDS_PER_SECOND); s->ulpd_pm_regs[0x08 >> 2] = (ticks >> 0) & 0xffff; s->ulpd_pm_regs[0x0c >> 2] = (ticks >> 16) & 0xffff; - if (ticks >> 32) /* OVERFLOW_HI_FREQ */ + if (ticks >> 32) /* OVERFLOW_HI_FREQ */ s->ulpd_pm_regs[0x14 >> 2] |= 1 << 1; - s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */ + s->ulpd_pm_regs[0x14 >> 2] |= 1 << 0; /* IT_GAUGING */ qemu_irq_raise(qdev_get_gpio_in(s->ih[1], OMAP_INT_GAUGE_32K)); } } s->ulpd_pm_regs[addr >> 2] = value; break; - case 0x18: /* Reserved */ - case 0x1c: /* Reserved */ - case 0x20: /* Reserved */ - case 0x28: /* Reserved */ - case 0x2c: /* Reserved */ + case 0x18: /* Reserved */ + case 0x1c: /* Reserved */ + case 0x20: /* Reserved */ + case 0x28: /* Reserved */ + case 0x2c: /* Reserved */ OMAP_BAD_REG(addr); /* fall through */ - case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */ - case 0x38: /* COUNTER_32_FIQ */ - case 0x48: /* LOCL_TIME */ - case 0x50: /* POWER_CTRL */ + case 0x24: /* SETUP_ANALOG_CELL3_ULPD1 */ + case 0x38: /* COUNTER_32_FIQ */ + case 0x48: /* LOCL_TIME */ + case 0x50: /* POWER_CTRL */ s->ulpd_pm_regs[addr >> 2] = value; break; - case 0x30: /* CLOCK_CTRL */ + case 0x30: /* CLOCK_CTRL */ diff = s->ulpd_pm_regs[addr >> 2] ^ value; s->ulpd_pm_regs[addr >> 2] = value & 0x3f; omap_ulpd_clk_update(s, diff, value); break; - case 0x34: /* SOFT_REQ */ + case 0x34: /* SOFT_REQ */ diff = s->ulpd_pm_regs[addr >> 2] ^ value; s->ulpd_pm_regs[addr >> 2] = value & 0x1f; omap_ulpd_req_update(s, diff, value); break; - case 0x3c: /* DPLL_CTRL */ + case 0x3c: /* DPLL_CTRL */ /* XXX: OMAP310 TRM claims bit 3 is PLL_ENABLE, and bit 4 is * omitted altogether, probably a typo. */ /* This register has identical semantics with DPLL(1:3) control @@ -689,11 +689,11 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr, diff = s->ulpd_pm_regs[addr >> 2] & value; s->ulpd_pm_regs[addr >> 2] = value & 0x2fff; if (diff & (0x3ff << 2)) { - if (value & (1 << 4)) { /* PLL_ENABLE */ - div = ((value >> 5) & 3) + 1; /* PLL_DIV */ - mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */ + if (value & (1 << 4)) { /* PLL_ENABLE */ + div = ((value >> 5) & 3) + 1; /* PLL_DIV */ + mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */ } else { - div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */ + div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */ mult = 1; } omap_clk_setrate(omap_findclk(s, "dpll4"), div, mult); @@ -708,10 +708,10 @@ static void omap_ulpd_pm_write(void *opaque, hwaddr addr, s->ulpd_pm_regs[addr >> 2] |= 2; break; - case 0x4c: /* APLL_CTRL */ + case 0x4c: /* APLL_CTRL */ diff = s->ulpd_pm_regs[addr >> 2] & value; s->ulpd_pm_regs[addr >> 2] = value & 0xf; - if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */ + if (diff & (1 << 0)) /* APLL_NDPLL_SWITCH */ omap_clk_reparent(omap_findclk(s, "ck_48m"), omap_findclk(s, (value & (1 << 0)) ? "apll" : "dpll4")); break; @@ -775,43 +775,43 @@ static uint64_t omap_pin_cfg_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* FUNC_MUX_CTRL_0 */ - case 0x04: /* FUNC_MUX_CTRL_1 */ - case 0x08: /* FUNC_MUX_CTRL_2 */ + case 0x00: /* FUNC_MUX_CTRL_0 */ + case 0x04: /* FUNC_MUX_CTRL_1 */ + case 0x08: /* FUNC_MUX_CTRL_2 */ return s->func_mux_ctrl[addr >> 2]; - case 0x0c: /* COMP_MODE_CTRL_0 */ + case 0x0c: /* COMP_MODE_CTRL_0 */ return s->comp_mode_ctrl[0]; - case 0x10: /* FUNC_MUX_CTRL_3 */ - case 0x14: /* FUNC_MUX_CTRL_4 */ - case 0x18: /* FUNC_MUX_CTRL_5 */ - case 0x1c: /* FUNC_MUX_CTRL_6 */ - case 0x20: /* FUNC_MUX_CTRL_7 */ - case 0x24: /* FUNC_MUX_CTRL_8 */ - case 0x28: /* FUNC_MUX_CTRL_9 */ - case 0x2c: /* FUNC_MUX_CTRL_A */ - case 0x30: /* FUNC_MUX_CTRL_B */ - case 0x34: /* FUNC_MUX_CTRL_C */ - case 0x38: /* FUNC_MUX_CTRL_D */ + case 0x10: /* FUNC_MUX_CTRL_3 */ + case 0x14: /* FUNC_MUX_CTRL_4 */ + case 0x18: /* FUNC_MUX_CTRL_5 */ + case 0x1c: /* FUNC_MUX_CTRL_6 */ + case 0x20: /* FUNC_MUX_CTRL_7 */ + case 0x24: /* FUNC_MUX_CTRL_8 */ + case 0x28: /* FUNC_MUX_CTRL_9 */ + case 0x2c: /* FUNC_MUX_CTRL_A */ + case 0x30: /* FUNC_MUX_CTRL_B */ + case 0x34: /* FUNC_MUX_CTRL_C */ + case 0x38: /* FUNC_MUX_CTRL_D */ return s->func_mux_ctrl[(addr >> 2) - 1]; - case 0x40: /* PULL_DWN_CTRL_0 */ - case 0x44: /* PULL_DWN_CTRL_1 */ - case 0x48: /* PULL_DWN_CTRL_2 */ - case 0x4c: /* PULL_DWN_CTRL_3 */ + case 0x40: /* PULL_DWN_CTRL_0 */ + case 0x44: /* PULL_DWN_CTRL_1 */ + case 0x48: /* PULL_DWN_CTRL_2 */ + case 0x4c: /* PULL_DWN_CTRL_3 */ return s->pull_dwn_ctrl[(addr & 0xf) >> 2]; - case 0x50: /* GATE_INH_CTRL_0 */ + case 0x50: /* GATE_INH_CTRL_0 */ return s->gate_inh_ctrl[0]; - case 0x60: /* VOLTAGE_CTRL_0 */ + case 0x60: /* VOLTAGE_CTRL_0 */ return s->voltage_ctrl[0]; - case 0x70: /* TEST_DBG_CTRL_0 */ + case 0x70: /* TEST_DBG_CTRL_0 */ return s->test_dbg_ctrl[0]; - case 0x80: /* MOD_CONF_CTRL_0 */ + case 0x80: /* MOD_CONF_CTRL_0 */ return s->mod_conf_ctrl[0]; } @@ -823,10 +823,10 @@ static inline void omap_pin_funcmux0_update(struct omap_mpu_state_s *s, uint32_t diff, uint32_t value) { if (s->compat1509) { - if (diff & (1 << 9)) /* BLUETOOTH */ + if (diff & (1 << 9)) /* BLUETOOTH */ omap_clk_onoff(omap_findclk(s, "bt_mclk_out"), (~value >> 9) & 1); - if (diff & (1 << 7)) /* USB.CLKO */ + if (diff & (1 << 7)) /* USB.CLKO */ omap_clk_onoff(omap_findclk(s, "usb.clko"), (value >> 7) & 1); } @@ -856,23 +856,23 @@ static inline void omap_pin_modconf1_update(struct omap_mpu_state_s *s, omap_findclk(s, ((value >> 31) & 1) ? "ck_48m" : "armper_ck")); } - if (diff & (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */ + if (diff & (1 << 30)) /* CONF_MOD_UART2_CLK_MODE_R */ omap_clk_reparent(omap_findclk(s, "uart2_ck"), omap_findclk(s, ((value >> 30) & 1) ? "ck_48m" : "armper_ck")); - if (diff & (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */ + if (diff & (1 << 29)) /* CONF_MOD_UART1_CLK_MODE_R */ omap_clk_reparent(omap_findclk(s, "uart1_ck"), omap_findclk(s, ((value >> 29) & 1) ? "ck_48m" : "armper_ck")); - if (diff & (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */ + if (diff & (1 << 23)) /* CONF_MOD_MMC_SD_CLK_REQ_R */ omap_clk_reparent(omap_findclk(s, "mmc_ck"), omap_findclk(s, ((value >> 23) & 1) ? "ck_48m" : "armper_ck")); - if (diff & (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */ + if (diff & (1 << 12)) /* CONF_MOD_COM_MCLK_12_48_S */ omap_clk_reparent(omap_findclk(s, "com_mclk_out"), omap_findclk(s, ((value >> 12) & 1) ? "ck_48m" : "armper_ck")); - if (diff & (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */ + if (diff & (1 << 9)) /* CONF_MOD_USB_HOST_HHC_UHO */ omap_clk_onoff(omap_findclk(s, "usb_hhc_ck"), (value >> 9) & 1); } @@ -888,63 +888,63 @@ static void omap_pin_cfg_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* FUNC_MUX_CTRL_0 */ + case 0x00: /* FUNC_MUX_CTRL_0 */ diff = s->func_mux_ctrl[addr >> 2] ^ value; s->func_mux_ctrl[addr >> 2] = value; omap_pin_funcmux0_update(s, diff, value); return; - case 0x04: /* FUNC_MUX_CTRL_1 */ + case 0x04: /* FUNC_MUX_CTRL_1 */ diff = s->func_mux_ctrl[addr >> 2] ^ value; s->func_mux_ctrl[addr >> 2] = value; omap_pin_funcmux1_update(s, diff, value); return; - case 0x08: /* FUNC_MUX_CTRL_2 */ + case 0x08: /* FUNC_MUX_CTRL_2 */ s->func_mux_ctrl[addr >> 2] = value; return; - case 0x0c: /* COMP_MODE_CTRL_0 */ + case 0x0c: /* COMP_MODE_CTRL_0 */ s->comp_mode_ctrl[0] = value; s->compat1509 = (value != 0x0000eaef); omap_pin_funcmux0_update(s, ~0, s->func_mux_ctrl[0]); omap_pin_funcmux1_update(s, ~0, s->func_mux_ctrl[1]); return; - case 0x10: /* FUNC_MUX_CTRL_3 */ - case 0x14: /* FUNC_MUX_CTRL_4 */ - case 0x18: /* FUNC_MUX_CTRL_5 */ - case 0x1c: /* FUNC_MUX_CTRL_6 */ - case 0x20: /* FUNC_MUX_CTRL_7 */ - case 0x24: /* FUNC_MUX_CTRL_8 */ - case 0x28: /* FUNC_MUX_CTRL_9 */ - case 0x2c: /* FUNC_MUX_CTRL_A */ - case 0x30: /* FUNC_MUX_CTRL_B */ - case 0x34: /* FUNC_MUX_CTRL_C */ - case 0x38: /* FUNC_MUX_CTRL_D */ + case 0x10: /* FUNC_MUX_CTRL_3 */ + case 0x14: /* FUNC_MUX_CTRL_4 */ + case 0x18: /* FUNC_MUX_CTRL_5 */ + case 0x1c: /* FUNC_MUX_CTRL_6 */ + case 0x20: /* FUNC_MUX_CTRL_7 */ + case 0x24: /* FUNC_MUX_CTRL_8 */ + case 0x28: /* FUNC_MUX_CTRL_9 */ + case 0x2c: /* FUNC_MUX_CTRL_A */ + case 0x30: /* FUNC_MUX_CTRL_B */ + case 0x34: /* FUNC_MUX_CTRL_C */ + case 0x38: /* FUNC_MUX_CTRL_D */ s->func_mux_ctrl[(addr >> 2) - 1] = value; return; - case 0x40: /* PULL_DWN_CTRL_0 */ - case 0x44: /* PULL_DWN_CTRL_1 */ - case 0x48: /* PULL_DWN_CTRL_2 */ - case 0x4c: /* PULL_DWN_CTRL_3 */ + case 0x40: /* PULL_DWN_CTRL_0 */ + case 0x44: /* PULL_DWN_CTRL_1 */ + case 0x48: /* PULL_DWN_CTRL_2 */ + case 0x4c: /* PULL_DWN_CTRL_3 */ s->pull_dwn_ctrl[(addr & 0xf) >> 2] = value; return; - case 0x50: /* GATE_INH_CTRL_0 */ + case 0x50: /* GATE_INH_CTRL_0 */ s->gate_inh_ctrl[0] = value; return; - case 0x60: /* VOLTAGE_CTRL_0 */ + case 0x60: /* VOLTAGE_CTRL_0 */ s->voltage_ctrl[0] = value; return; - case 0x70: /* TEST_DBG_CTRL_0 */ + case 0x70: /* TEST_DBG_CTRL_0 */ s->test_dbg_ctrl[0] = value; return; - case 0x80: /* MOD_CONF_CTRL_0 */ + case 0x80: /* MOD_CONF_CTRL_0 */ diff = s->mod_conf_ctrl[0] ^ value; s->mod_conf_ctrl[0] = value; omap_pin_modconf1_update(s, diff, value); @@ -998,17 +998,17 @@ static uint64_t omap_id_read(void *opaque, hwaddr addr, } switch (addr) { - case 0xfffe1800: /* DIE_ID_LSB */ + case 0xfffe1800: /* DIE_ID_LSB */ return 0xc9581f0e; - case 0xfffe1804: /* DIE_ID_MSB */ + case 0xfffe1804: /* DIE_ID_MSB */ return 0xa8858bfa; - case 0xfffe2000: /* PRODUCT_ID_LSB */ + case 0xfffe2000: /* PRODUCT_ID_LSB */ return 0x00aaaafc; - case 0xfffe2004: /* PRODUCT_ID_MSB */ + case 0xfffe2004: /* PRODUCT_ID_MSB */ return 0xcafeb574; - case 0xfffed400: /* JTAG_ID_LSB */ + case 0xfffed400: /* JTAG_ID_LSB */ switch (s->mpu_model) { case omap310: return 0x03310315; @@ -1019,7 +1019,7 @@ static uint64_t omap_id_read(void *opaque, hwaddr addr, } break; - case 0xfffed404: /* JTAG_ID_MSB */ + case 0xfffed404: /* JTAG_ID_MSB */ switch (s->mpu_model) { case omap310: return 0xfb57402f; @@ -1080,22 +1080,22 @@ static uint64_t omap_mpui_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* CTRL */ + case 0x00: /* CTRL */ return s->mpui_ctrl; - case 0x04: /* DEBUG_ADDR */ + case 0x04: /* DEBUG_ADDR */ return 0x01ffffff; - case 0x08: /* DEBUG_DATA */ + case 0x08: /* DEBUG_DATA */ return 0xffffffff; - case 0x0c: /* DEBUG_FLAG */ + case 0x0c: /* DEBUG_FLAG */ return 0x00000800; - case 0x10: /* STATUS */ + case 0x10: /* STATUS */ return 0x00000000; /* Not in OMAP310 */ - case 0x14: /* DSP_STATUS */ - case 0x18: /* DSP_BOOT_CONFIG */ + case 0x14: /* DSP_STATUS */ + case 0x18: /* DSP_BOOT_CONFIG */ return 0x00000000; - case 0x1c: /* DSP_MPUI_CONFIG */ + case 0x1c: /* DSP_MPUI_CONFIG */ return 0x0000ffff; } @@ -1114,20 +1114,20 @@ static void omap_mpui_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* CTRL */ + case 0x00: /* CTRL */ s->mpui_ctrl = value & 0x007fffff; break; - case 0x04: /* DEBUG_ADDR */ - case 0x08: /* DEBUG_DATA */ - case 0x0c: /* DEBUG_FLAG */ - case 0x10: /* STATUS */ + case 0x04: /* DEBUG_ADDR */ + case 0x08: /* DEBUG_DATA */ + case 0x0c: /* DEBUG_FLAG */ + case 0x10: /* STATUS */ /* Not in OMAP310 */ - case 0x14: /* DSP_STATUS */ + case 0x14: /* DSP_STATUS */ OMAP_RO_REG(addr); break; - case 0x18: /* DSP_BOOT_CONFIG */ - case 0x1c: /* DSP_MPUI_CONFIG */ + case 0x18: /* DSP_BOOT_CONFIG */ + case 0x1c: /* DSP_MPUI_CONFIG */ break; default: @@ -1178,19 +1178,19 @@ static uint64_t omap_tipb_bridge_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* TIPB_CNTL */ + case 0x00: /* TIPB_CNTL */ return s->control; - case 0x04: /* TIPB_BUS_ALLOC */ + case 0x04: /* TIPB_BUS_ALLOC */ return s->alloc; - case 0x08: /* MPU_TIPB_CNTL */ + case 0x08: /* MPU_TIPB_CNTL */ return s->buffer; - case 0x0c: /* ENHANCED_TIPB_CNTL */ + case 0x0c: /* ENHANCED_TIPB_CNTL */ return s->enh_control; - case 0x10: /* ADDRESS_DBG */ - case 0x14: /* DATA_DEBUG_LOW */ - case 0x18: /* DATA_DEBUG_HIGH */ + case 0x10: /* ADDRESS_DBG */ + case 0x14: /* DATA_DEBUG_LOW */ + case 0x18: /* DATA_DEBUG_HIGH */ return 0xffff; - case 0x1c: /* DEBUG_CNTR_SIG */ + case 0x1c: /* DEBUG_CNTR_SIG */ return 0x00f8; } @@ -1209,27 +1209,27 @@ static void omap_tipb_bridge_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* TIPB_CNTL */ + case 0x00: /* TIPB_CNTL */ s->control = value & 0xffff; break; - case 0x04: /* TIPB_BUS_ALLOC */ + case 0x04: /* TIPB_BUS_ALLOC */ s->alloc = value & 0x003f; break; - case 0x08: /* MPU_TIPB_CNTL */ + case 0x08: /* MPU_TIPB_CNTL */ s->buffer = value & 0x0003; break; - case 0x0c: /* ENHANCED_TIPB_CNTL */ + case 0x0c: /* ENHANCED_TIPB_CNTL */ s->width_intr = !(value & 2); s->enh_control = value & 0x000f; break; - case 0x10: /* ADDRESS_DBG */ - case 0x14: /* DATA_DEBUG_LOW */ - case 0x18: /* DATA_DEBUG_HIGH */ - case 0x1c: /* DEBUG_CNTR_SIG */ + case 0x10: /* ADDRESS_DBG */ + case 0x14: /* DATA_DEBUG_LOW */ + case 0x18: /* DATA_DEBUG_HIGH */ + case 0x1c: /* DEBUG_CNTR_SIG */ OMAP_RO_REG(addr); break; @@ -1280,23 +1280,23 @@ static uint64_t omap_tcmi_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* IMIF_PRIO */ - case 0x04: /* EMIFS_PRIO */ - case 0x08: /* EMIFF_PRIO */ - case 0x0c: /* EMIFS_CONFIG */ - case 0x10: /* EMIFS_CS0_CONFIG */ - case 0x14: /* EMIFS_CS1_CONFIG */ - case 0x18: /* EMIFS_CS2_CONFIG */ - case 0x1c: /* EMIFS_CS3_CONFIG */ - case 0x24: /* EMIFF_MRS */ - case 0x28: /* TIMEOUT1 */ - case 0x2c: /* TIMEOUT2 */ - case 0x30: /* TIMEOUT3 */ - case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */ - case 0x40: /* EMIFS_CFG_DYN_WAIT */ + case 0x00: /* IMIF_PRIO */ + case 0x04: /* EMIFS_PRIO */ + case 0x08: /* EMIFF_PRIO */ + case 0x0c: /* EMIFS_CONFIG */ + case 0x10: /* EMIFS_CS0_CONFIG */ + case 0x14: /* EMIFS_CS1_CONFIG */ + case 0x18: /* EMIFS_CS2_CONFIG */ + case 0x1c: /* EMIFS_CS3_CONFIG */ + case 0x24: /* EMIFF_MRS */ + case 0x28: /* TIMEOUT1 */ + case 0x2c: /* TIMEOUT2 */ + case 0x30: /* TIMEOUT3 */ + case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */ + case 0x40: /* EMIFS_CFG_DYN_WAIT */ return s->tcmi_regs[addr >> 2]; - case 0x20: /* EMIFF_SDRAM_CONFIG */ + case 0x20: /* EMIFF_SDRAM_CONFIG */ ret = s->tcmi_regs[addr >> 2]; s->tcmi_regs[addr >> 2] &= ~1; /* XXX: Clear SLRF on SDRAM access */ /* XXX: We can try using the VGA_DIRTY flag for this */ @@ -1318,23 +1318,23 @@ static void omap_tcmi_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* IMIF_PRIO */ - case 0x04: /* EMIFS_PRIO */ - case 0x08: /* EMIFF_PRIO */ - case 0x10: /* EMIFS_CS0_CONFIG */ - case 0x14: /* EMIFS_CS1_CONFIG */ - case 0x18: /* EMIFS_CS2_CONFIG */ - case 0x1c: /* EMIFS_CS3_CONFIG */ - case 0x20: /* EMIFF_SDRAM_CONFIG */ - case 0x24: /* EMIFF_MRS */ - case 0x28: /* TIMEOUT1 */ - case 0x2c: /* TIMEOUT2 */ - case 0x30: /* TIMEOUT3 */ - case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */ - case 0x40: /* EMIFS_CFG_DYN_WAIT */ + case 0x00: /* IMIF_PRIO */ + case 0x04: /* EMIFS_PRIO */ + case 0x08: /* EMIFF_PRIO */ + case 0x10: /* EMIFS_CS0_CONFIG */ + case 0x14: /* EMIFS_CS1_CONFIG */ + case 0x18: /* EMIFS_CS2_CONFIG */ + case 0x1c: /* EMIFS_CS3_CONFIG */ + case 0x20: /* EMIFF_SDRAM_CONFIG */ + case 0x24: /* EMIFF_MRS */ + case 0x28: /* TIMEOUT1 */ + case 0x2c: /* TIMEOUT2 */ + case 0x30: /* TIMEOUT3 */ + case 0x3c: /* EMIFF_SDRAM_CONFIG_2 */ + case 0x40: /* EMIFS_CFG_DYN_WAIT */ s->tcmi_regs[addr >> 2] = value; break; - case 0x0c: /* EMIFS_CONFIG */ + case 0x0c: /* EMIFS_CONFIG */ s->tcmi_regs[addr >> 2] = (value & 0xf) | (1 << 4); break; @@ -1393,7 +1393,7 @@ static uint64_t omap_dpll_read(void *opaque, hwaddr addr, return omap_badwidth_read16(opaque, addr); } - if (addr == 0x00) /* CTL_REG */ + if (addr == 0x00) /* CTL_REG */ return s->mode; OMAP_BAD_REG(addr); @@ -1413,16 +1413,16 @@ static void omap_dpll_write(void *opaque, hwaddr addr, return; } - if (addr == 0x00) { /* CTL_REG */ + if (addr == 0x00) { /* CTL_REG */ /* See omap_ulpd_pm_write() too */ diff = s->mode & value; s->mode = value & 0x2fff; if (diff & (0x3ff << 2)) { - if (value & (1 << 4)) { /* PLL_ENABLE */ - div = ((value >> 5) & 3) + 1; /* PLL_DIV */ - mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */ + if (value & (1 << 4)) { /* PLL_ENABLE */ + div = ((value >> 5) & 3) + 1; /* PLL_DIV */ + mult = MIN((value >> 7) & 0x1f, 1); /* PLL_MULT */ } else { - div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */ + div = bypass_div[((value >> 2) & 3)]; /* BYPASS_DIV */ mult = 1; } omap_clk_setrate(s->dpll, div, mult); @@ -1474,31 +1474,31 @@ static uint64_t omap_clkm_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* ARM_CKCTL */ + case 0x00: /* ARM_CKCTL */ return s->clkm.arm_ckctl; - case 0x04: /* ARM_IDLECT1 */ + case 0x04: /* ARM_IDLECT1 */ return s->clkm.arm_idlect1; - case 0x08: /* ARM_IDLECT2 */ + case 0x08: /* ARM_IDLECT2 */ return s->clkm.arm_idlect2; - case 0x0c: /* ARM_EWUPCT */ + case 0x0c: /* ARM_EWUPCT */ return s->clkm.arm_ewupct; - case 0x10: /* ARM_RSTCT1 */ + case 0x10: /* ARM_RSTCT1 */ return s->clkm.arm_rstct1; - case 0x14: /* ARM_RSTCT2 */ + case 0x14: /* ARM_RSTCT2 */ return s->clkm.arm_rstct2; - case 0x18: /* ARM_SYSST */ + case 0x18: /* ARM_SYSST */ return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start; - case 0x1c: /* ARM_CKOUT1 */ + case 0x1c: /* ARM_CKOUT1 */ return s->clkm.arm_ckout1; - case 0x20: /* ARM_CKOUT2 */ + case 0x20: /* ARM_CKOUT2 */ break; } @@ -1511,7 +1511,7 @@ static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s, { omap_clk clk; - if (diff & (1 << 14)) { /* ARM_INTHCK_SEL */ + if (diff & (1 << 14)) { /* ARM_INTHCK_SEL */ if (value & (1 << 14)) /* Reserved */; else { @@ -1519,7 +1519,7 @@ static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s, omap_clk_reparent(clk, omap_findclk(s, "tc_ck")); } } - if (diff & (1 << 12)) { /* ARM_TIMXO */ + if (diff & (1 << 12)) { /* ARM_TIMXO */ clk = omap_findclk(s, "armtim_ck"); if (value & (1 << 12)) omap_clk_reparent(clk, omap_findclk(s, "clkin")); @@ -1527,27 +1527,27 @@ static inline void omap_clkm_ckctl_update(struct omap_mpu_state_s *s, omap_clk_reparent(clk, omap_findclk(s, "ck_gen1")); } /* XXX: en_dspck */ - if (diff & (3 << 10)) { /* DSPMMUDIV */ + if (diff & (3 << 10)) { /* DSPMMUDIV */ clk = omap_findclk(s, "dspmmu_ck"); omap_clk_setrate(clk, 1 << ((value >> 10) & 3), 1); } - if (diff & (3 << 8)) { /* TCDIV */ + if (diff & (3 << 8)) { /* TCDIV */ clk = omap_findclk(s, "tc_ck"); omap_clk_setrate(clk, 1 << ((value >> 8) & 3), 1); } - if (diff & (3 << 6)) { /* DSPDIV */ + if (diff & (3 << 6)) { /* DSPDIV */ clk = omap_findclk(s, "dsp_ck"); omap_clk_setrate(clk, 1 << ((value >> 6) & 3), 1); } - if (diff & (3 << 4)) { /* ARMDIV */ + if (diff & (3 << 4)) { /* ARMDIV */ clk = omap_findclk(s, "arm_ck"); omap_clk_setrate(clk, 1 << ((value >> 4) & 3), 1); } - if (diff & (3 << 2)) { /* LCDDIV */ + if (diff & (3 << 2)) { /* LCDDIV */ clk = omap_findclk(s, "lcd_ck"); omap_clk_setrate(clk, 1 << ((value >> 2) & 3), 1); } - if (diff & (3 << 0)) { /* PERDIV */ + if (diff & (3 << 0)) { /* PERDIV */ clk = omap_findclk(s, "armper_ck"); omap_clk_setrate(clk, 1 << ((value >> 0) & 3), 1); } @@ -1566,25 +1566,25 @@ static inline void omap_clkm_idlect1_update(struct omap_mpu_state_s *s, qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN); } -#define SET_CANIDLE(clock, bit) \ - if (diff & (1 << bit)) { \ - clk = omap_findclk(s, clock); \ - omap_clk_canidle(clk, (value >> bit) & 1); \ +#define SET_CANIDLE(clock, bit) \ + if (diff & (1 << bit)) { \ + clk = omap_findclk(s, clock); \ + omap_clk_canidle(clk, (value >> bit) & 1); \ } - SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */ - SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */ - SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */ - SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */ - SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */ - SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */ - SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */ - SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */ - SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */ - SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */ - SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */ - SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */ - SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */ - SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */ + SET_CANIDLE("mpuwd_ck", 0) /* IDLWDT_ARM */ + SET_CANIDLE("armxor_ck", 1) /* IDLXORP_ARM */ + SET_CANIDLE("mpuper_ck", 2) /* IDLPER_ARM */ + SET_CANIDLE("lcd_ck", 3) /* IDLLCD_ARM */ + SET_CANIDLE("lb_ck", 4) /* IDLLB_ARM */ + SET_CANIDLE("hsab_ck", 5) /* IDLHSAB_ARM */ + SET_CANIDLE("tipb_ck", 6) /* IDLIF_ARM */ + SET_CANIDLE("dma_ck", 6) /* IDLIF_ARM */ + SET_CANIDLE("tc_ck", 6) /* IDLIF_ARM */ + SET_CANIDLE("dpll1", 7) /* IDLDPLL_ARM */ + SET_CANIDLE("dpll2", 7) /* IDLDPLL_ARM */ + SET_CANIDLE("dpll3", 7) /* IDLDPLL_ARM */ + SET_CANIDLE("mpui_ck", 8) /* IDLAPI_ARM */ + SET_CANIDLE("armtim_ck", 9) /* IDLTIM_ARM */ } static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s, @@ -1592,22 +1592,22 @@ static inline void omap_clkm_idlect2_update(struct omap_mpu_state_s *s, { omap_clk clk; -#define SET_ONOFF(clock, bit) \ - if (diff & (1 << bit)) { \ - clk = omap_findclk(s, clock); \ - omap_clk_onoff(clk, (value >> bit) & 1); \ +#define SET_ONOFF(clock, bit) \ + if (diff & (1 << bit)) { \ + clk = omap_findclk(s, clock); \ + omap_clk_onoff(clk, (value >> bit) & 1); \ } - SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */ - SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */ - SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */ - SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */ - SET_ONOFF("lb_ck", 4) /* EN_LBCK */ - SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */ - SET_ONOFF("mpui_ck", 6) /* EN_APICK */ - SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */ - SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */ - SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */ - SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */ + SET_ONOFF("mpuwd_ck", 0) /* EN_WDTCK */ + SET_ONOFF("armxor_ck", 1) /* EN_XORPCK */ + SET_ONOFF("mpuper_ck", 2) /* EN_PERCK */ + SET_ONOFF("lcd_ck", 3) /* EN_LCDCK */ + SET_ONOFF("lb_ck", 4) /* EN_LBCK */ + SET_ONOFF("hsab_ck", 5) /* EN_HSABCK */ + SET_ONOFF("mpui_ck", 6) /* EN_APICK */ + SET_ONOFF("armtim_ck", 7) /* EN_TIMCK */ + SET_CANIDLE("dma_ck", 8) /* DMACK_REQ */ + SET_ONOFF("arm_gpio_ck", 9) /* EN_GPIOCK */ + SET_ONOFF("lbfree_ck", 10) /* EN_LBFREECK */ } static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s, @@ -1615,7 +1615,7 @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s, { omap_clk clk; - if (diff & (3 << 4)) { /* TCLKOUT */ + if (diff & (3 << 4)) { /* TCLKOUT */ clk = omap_findclk(s, "tclk_out"); switch ((value >> 4) & 3) { case 1: @@ -1630,7 +1630,7 @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s, omap_clk_onoff(clk, 0); } } - if (diff & (3 << 2)) { /* DCLKOUT */ + if (diff & (3 << 2)) { /* DCLKOUT */ clk = omap_findclk(s, "dclk_out"); switch ((value >> 2) & 3) { case 0: @@ -1647,7 +1647,7 @@ static inline void omap_clkm_ckout1_update(struct omap_mpu_state_s *s, break; } } - if (diff & (3 << 0)) { /* ACLKOUT */ + if (diff & (3 << 0)) { /* ACLKOUT */ clk = omap_findclk(s, "aclk_out"); switch ((value >> 0) & 3) { case 1: @@ -1685,51 +1685,51 @@ static void omap_clkm_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x00: /* ARM_CKCTL */ + case 0x00: /* ARM_CKCTL */ diff = s->clkm.arm_ckctl ^ value; s->clkm.arm_ckctl = value & 0x7fff; omap_clkm_ckctl_update(s, diff, value); return; - case 0x04: /* ARM_IDLECT1 */ + case 0x04: /* ARM_IDLECT1 */ diff = s->clkm.arm_idlect1 ^ value; s->clkm.arm_idlect1 = value & 0x0fff; omap_clkm_idlect1_update(s, diff, value); return; - case 0x08: /* ARM_IDLECT2 */ + case 0x08: /* ARM_IDLECT2 */ diff = s->clkm.arm_idlect2 ^ value; s->clkm.arm_idlect2 = value & 0x07ff; omap_clkm_idlect2_update(s, diff, value); return; - case 0x0c: /* ARM_EWUPCT */ + case 0x0c: /* ARM_EWUPCT */ s->clkm.arm_ewupct = value & 0x003f; return; - case 0x10: /* ARM_RSTCT1 */ + case 0x10: /* ARM_RSTCT1 */ diff = s->clkm.arm_rstct1 ^ value; s->clkm.arm_rstct1 = value & 0x0007; if (value & 9) { qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); s->clkm.cold_start = 0xa; } - if (diff & ~value & 4) { /* DSP_RST */ + if (diff & ~value & 4) { /* DSP_RST */ omap_mpui_reset(s); omap_tipb_bridge_reset(s->private_tipb); omap_tipb_bridge_reset(s->public_tipb); } - if (diff & 2) { /* DSP_EN */ + if (diff & 2) { /* DSP_EN */ clk = omap_findclk(s, "dsp_ck"); omap_clk_canidle(clk, (~value >> 1) & 1); } return; - case 0x14: /* ARM_RSTCT2 */ + case 0x14: /* ARM_RSTCT2 */ s->clkm.arm_rstct2 = value & 0x0001; return; - case 0x18: /* ARM_SYSST */ + case 0x18: /* ARM_SYSST */ if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) { s->clkm.clocking_scheme = (value >> 11) & 7; trace_omap1_pwl_clocking_scheme( @@ -1738,13 +1738,13 @@ static void omap_clkm_write(void *opaque, hwaddr addr, s->clkm.cold_start &= value & 0x3f; return; - case 0x1c: /* ARM_CKOUT1 */ + case 0x1c: /* ARM_CKOUT1 */ diff = s->clkm.arm_ckout1 ^ value; s->clkm.arm_ckout1 = value & 0x003f; omap_clkm_ckout1_update(s, diff, value); return; - case 0x20: /* ARM_CKOUT2 */ + case 0x20: /* ARM_CKOUT2 */ default: OMAP_BAD_REG(addr); } @@ -1767,16 +1767,16 @@ static uint64_t omap_clkdsp_read(void *opaque, hwaddr addr, } switch (addr) { - case 0x04: /* DSP_IDLECT1 */ + case 0x04: /* DSP_IDLECT1 */ return s->clkm.dsp_idlect1; - case 0x08: /* DSP_IDLECT2 */ + case 0x08: /* DSP_IDLECT2 */ return s->clkm.dsp_idlect2; - case 0x14: /* DSP_RSTCT2 */ + case 0x14: /* DSP_RSTCT2 */ return s->clkm.dsp_rstct2; - case 0x18: /* DSP_SYSST */ + case 0x18: /* DSP_SYSST */ return (s->clkm.clocking_scheme << 11) | s->clkm.cold_start | (cpu->halted << 6); /* Quite useless... */ } @@ -1790,7 +1790,7 @@ static inline void omap_clkdsp_idlect1_update(struct omap_mpu_state_s *s, { omap_clk clk; - SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */ + SET_CANIDLE("dspxor_ck", 1); /* IDLXORP_DSP */ } static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s, @@ -1798,7 +1798,7 @@ static inline void omap_clkdsp_idlect2_update(struct omap_mpu_state_s *s, { omap_clk clk; - SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */ + SET_ONOFF("dspxor_ck", 1); /* EN_XORPCK */ } static void omap_clkdsp_write(void *opaque, hwaddr addr, @@ -1813,23 +1813,23 @@ static void omap_clkdsp_write(void *opaque, hwaddr addr, } switch (addr) { - case 0x04: /* DSP_IDLECT1 */ + case 0x04: /* DSP_IDLECT1 */ diff = s->clkm.dsp_idlect1 ^ value; s->clkm.dsp_idlect1 = value & 0x01f7; omap_clkdsp_idlect1_update(s, diff, value); break; - case 0x08: /* DSP_IDLECT2 */ + case 0x08: /* DSP_IDLECT2 */ s->clkm.dsp_idlect2 = value & 0x0037; diff = s->clkm.dsp_idlect1 ^ value; omap_clkdsp_idlect2_update(s, diff, value); break; - case 0x14: /* DSP_RSTCT2 */ + case 0x14: /* DSP_RSTCT2 */ s->clkm.dsp_rstct2 = value & 0x0001; break; - case 0x18: /* DSP_SYSST */ + case 0x18: /* DSP_SYSST */ s->clkm.cold_start &= value & 0x3f; break; @@ -1928,8 +1928,8 @@ static void omap_mpuio_set(void *opaque, int line, int level) qemu_irq_raise(s->irq); /* TODO: wakeup */ } - if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */ - (s->event >> 1) == line) /* PIN_SELECT */ + if ((s->event & (1 << 0)) && /* SET_GPIO_EVENT_MODE */ + (s->event >> 1) == line) /* PIN_SELECT */ s->latch = s->inputs; } } @@ -1959,47 +1959,47 @@ static uint64_t omap_mpuio_read(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* INPUT_LATCH */ + case 0x00: /* INPUT_LATCH */ return s->inputs; - case 0x04: /* OUTPUT_REG */ + case 0x04: /* OUTPUT_REG */ return s->outputs; - case 0x08: /* IO_CNTL */ + case 0x08: /* IO_CNTL */ return s->dir; - case 0x10: /* KBR_LATCH */ + case 0x10: /* KBR_LATCH */ return s->row_latch; - case 0x14: /* KBC_REG */ + case 0x14: /* KBC_REG */ return s->cols; - case 0x18: /* GPIO_EVENT_MODE_REG */ + case 0x18: /* GPIO_EVENT_MODE_REG */ return s->event; - case 0x1c: /* GPIO_INT_EDGE_REG */ + case 0x1c: /* GPIO_INT_EDGE_REG */ return s->edge; - case 0x20: /* KBD_INT */ + case 0x20: /* KBD_INT */ return (~s->row_latch & 0x1f) && !s->kbd_mask; - case 0x24: /* GPIO_INT */ + case 0x24: /* GPIO_INT */ ret = s->ints; s->ints &= s->mask; if (ret) qemu_irq_lower(s->irq); return ret; - case 0x28: /* KBD_MASKIT */ + case 0x28: /* KBD_MASKIT */ return s->kbd_mask; - case 0x2c: /* GPIO_MASKIT */ + case 0x2c: /* GPIO_MASKIT */ return s->mask; - case 0x30: /* GPIO_DEBOUNCING_REG */ + case 0x30: /* GPIO_DEBOUNCING_REG */ return s->debounce; - case 0x34: /* GPIO_LATCH_REG */ + case 0x34: /* GPIO_LATCH_REG */ return s->latch; } @@ -2021,7 +2021,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x04: /* OUTPUT_REG */ + case 0x04: /* OUTPUT_REG */ diff = (s->outputs ^ value) & ~s->dir; s->outputs = value; while ((ln = ctz32(diff)) != 32) { @@ -2031,7 +2031,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr, } break; - case 0x08: /* IO_CNTL */ + case 0x08: /* IO_CNTL */ diff = s->outputs & (s->dir ^ value); s->dir = value; @@ -2043,37 +2043,37 @@ static void omap_mpuio_write(void *opaque, hwaddr addr, } break; - case 0x14: /* KBC_REG */ + case 0x14: /* KBC_REG */ s->cols = value; omap_mpuio_kbd_update(s); break; - case 0x18: /* GPIO_EVENT_MODE_REG */ + case 0x18: /* GPIO_EVENT_MODE_REG */ s->event = value & 0x1f; break; - case 0x1c: /* GPIO_INT_EDGE_REG */ + case 0x1c: /* GPIO_INT_EDGE_REG */ s->edge = value; break; - case 0x28: /* KBD_MASKIT */ + case 0x28: /* KBD_MASKIT */ s->kbd_mask = value & 1; omap_mpuio_kbd_update(s); break; - case 0x2c: /* GPIO_MASKIT */ + case 0x2c: /* GPIO_MASKIT */ s->mask = value; break; - case 0x30: /* GPIO_DEBOUNCING_REG */ + case 0x30: /* GPIO_DEBOUNCING_REG */ s->debounce = value & 0x1ff; break; - case 0x00: /* INPUT_LATCH */ - case 0x10: /* KBR_LATCH */ - case 0x20: /* KBD_INT */ - case 0x24: /* GPIO_INT */ - case 0x34: /* GPIO_LATCH_REG */ + case 0x00: /* INPUT_LATCH */ + case 0x10: /* KBR_LATCH */ + case 0x20: /* KBD_INT */ + case 0x24: /* GPIO_INT */ + case 0x34: /* GPIO_LATCH_REG */ OMAP_RO_REG(addr); return; @@ -2176,24 +2176,24 @@ struct omap_uwire_s { static void omap_uwire_transfer_start(struct omap_uwire_s *s) { - int chipselect = (s->control >> 10) & 3; /* INDEX */ + int chipselect = (s->control >> 10) & 3; /* INDEX */ - if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */ + if ((s->control >> 5) & 0x1f) { /* NB_BITS_WR */ if (s->control & (1 << 12)) { /* CS_CMD */ qemu_log_mask(LOG_UNIMP, "uWireSlave TX CS:%d data:0x%04x\n", chipselect, s->txbuf >> (16 - ((s->control >> 5) & 0x1f))); } - s->control &= ~(1 << 14); /* CSRB */ + s->control &= ~(1 << 14); /* CSRB */ /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or * a DRQ. When is the level IRQ supposed to be reset? */ } - if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */ + if ((s->control >> 0) & 0x1f) { /* NB_BITS_RD */ if (s->control & (1 << 12)) { /* CS_CMD */ qemu_log_mask(LOG_UNIMP, "uWireSlave RX CS:%d\n", chipselect); } - s->control |= 1 << 15; /* RDRB */ + s->control |= 1 << 15; /* RDRB */ /* TODO: depending on s->setup[4] bits [1:0] assert an IRQ or * a DRQ. When is the level IRQ supposed to be reset? */ } @@ -2209,22 +2209,22 @@ static uint64_t omap_uwire_read(void *opaque, hwaddr addr, unsigned size) } switch (offset) { - case 0x00: /* RDR */ - s->control &= ~(1 << 15); /* RDRB */ + case 0x00: /* RDR */ + s->control &= ~(1 << 15); /* RDRB */ return s->rxbuf; - case 0x04: /* CSR */ + case 0x04: /* CSR */ return s->control; - case 0x08: /* SR1 */ + case 0x08: /* SR1 */ return s->setup[0]; - case 0x0c: /* SR2 */ + case 0x0c: /* SR2 */ return s->setup[1]; - case 0x10: /* SR3 */ + case 0x10: /* SR3 */ return s->setup[2]; - case 0x14: /* SR4 */ + case 0x14: /* SR4 */ return s->setup[3]; - case 0x18: /* SR5 */ + case 0x18: /* SR5 */ return s->setup[4]; } @@ -2244,39 +2244,39 @@ static void omap_uwire_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* TDR */ - s->txbuf = value; /* TD */ - if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */ - ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */ - (s->control & (1 << 12)))) { /* CS_CMD */ - s->control |= 1 << 14; /* CSRB */ + case 0x00: /* TDR */ + s->txbuf = value; /* TD */ + if ((s->setup[4] & (1 << 2)) && /* AUTO_TX_EN */ + ((s->setup[4] & (1 << 3)) || /* CS_TOGGLE_TX_EN */ + (s->control & (1 << 12)))) { /* CS_CMD */ + s->control |= 1 << 14; /* CSRB */ omap_uwire_transfer_start(s); } break; - case 0x04: /* CSR */ + case 0x04: /* CSR */ s->control = value & 0x1fff; - if (value & (1 << 13)) /* START */ + if (value & (1 << 13)) /* START */ omap_uwire_transfer_start(s); break; - case 0x08: /* SR1 */ + case 0x08: /* SR1 */ s->setup[0] = value & 0x003f; break; - case 0x0c: /* SR2 */ + case 0x0c: /* SR2 */ s->setup[1] = value & 0x0fc0; break; - case 0x10: /* SR3 */ + case 0x10: /* SR3 */ s->setup[2] = value & 0x0003; break; - case 0x14: /* SR4 */ + case 0x14: /* SR4 */ s->setup[3] = value & 0x0001; break; - case 0x18: /* SR5 */ + case 0x18: /* SR5 */ s->setup[4] = value & 0x000f; break; @@ -2350,9 +2350,9 @@ static uint64_t omap_pwl_read(void *opaque, hwaddr addr, unsigned size) } switch (offset) { - case 0x00: /* PWL_LEVEL */ + case 0x00: /* PWL_LEVEL */ return s->level; - case 0x04: /* PWL_CTRL */ + case 0x04: /* PWL_CTRL */ return s->enable; } OMAP_BAD_REG(addr); @@ -2371,11 +2371,11 @@ static void omap_pwl_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* PWL_LEVEL */ + case 0x00: /* PWL_LEVEL */ s->level = value; omap_pwl_update(s); break; - case 0x04: /* PWL_CTRL */ + case 0x04: /* PWL_CTRL */ s->enable = value & 1; omap_pwl_update(s); break; @@ -2443,11 +2443,11 @@ static uint64_t omap_pwt_read(void *opaque, hwaddr addr, unsigned size) } switch (offset) { - case 0x00: /* FRC */ + case 0x00: /* FRC */ return s->frc; - case 0x04: /* VCR */ + case 0x04: /* VCR */ return s->vrc; - case 0x08: /* GCR */ + case 0x08: /* GCR */ return s->gcr; } OMAP_BAD_REG(addr); @@ -2466,10 +2466,10 @@ static void omap_pwt_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* FRC */ + case 0x00: /* FRC */ s->frc = value & 0x3f; break; - case 0x04: /* VRC */ + case 0x04: /* VRC */ if ((value ^ s->vrc) & 1) { if (value & 1) { trace_omap1_pwt_buzz( @@ -2494,7 +2494,7 @@ static void omap_pwt_write(void *opaque, hwaddr addr, } s->vrc = value & 0x7f; break; - case 0x08: /* GCR */ + case 0x08: /* GCR */ s->gcr = value & 3; break; default: @@ -2577,69 +2577,69 @@ static uint64_t omap_rtc_read(void *opaque, hwaddr addr, unsigned size) } switch (offset) { - case 0x00: /* SECONDS_REG */ + case 0x00: /* SECONDS_REG */ return to_bcd(s->current_tm.tm_sec); - case 0x04: /* MINUTES_REG */ + case 0x04: /* MINUTES_REG */ return to_bcd(s->current_tm.tm_min); - case 0x08: /* HOURS_REG */ + case 0x08: /* HOURS_REG */ if (s->pm_am) return ((s->current_tm.tm_hour > 11) << 7) | to_bcd(((s->current_tm.tm_hour - 1) % 12) + 1); else return to_bcd(s->current_tm.tm_hour); - case 0x0c: /* DAYS_REG */ + case 0x0c: /* DAYS_REG */ return to_bcd(s->current_tm.tm_mday); - case 0x10: /* MONTHS_REG */ + case 0x10: /* MONTHS_REG */ return to_bcd(s->current_tm.tm_mon + 1); - case 0x14: /* YEARS_REG */ + case 0x14: /* YEARS_REG */ return to_bcd(s->current_tm.tm_year % 100); - case 0x18: /* WEEK_REG */ + case 0x18: /* WEEK_REG */ return s->current_tm.tm_wday; - case 0x20: /* ALARM_SECONDS_REG */ + case 0x20: /* ALARM_SECONDS_REG */ return to_bcd(s->alarm_tm.tm_sec); - case 0x24: /* ALARM_MINUTES_REG */ + case 0x24: /* ALARM_MINUTES_REG */ return to_bcd(s->alarm_tm.tm_min); - case 0x28: /* ALARM_HOURS_REG */ + case 0x28: /* ALARM_HOURS_REG */ if (s->pm_am) return ((s->alarm_tm.tm_hour > 11) << 7) | to_bcd(((s->alarm_tm.tm_hour - 1) % 12) + 1); else return to_bcd(s->alarm_tm.tm_hour); - case 0x2c: /* ALARM_DAYS_REG */ + case 0x2c: /* ALARM_DAYS_REG */ return to_bcd(s->alarm_tm.tm_mday); - case 0x30: /* ALARM_MONTHS_REG */ + case 0x30: /* ALARM_MONTHS_REG */ return to_bcd(s->alarm_tm.tm_mon + 1); - case 0x34: /* ALARM_YEARS_REG */ + case 0x34: /* ALARM_YEARS_REG */ return to_bcd(s->alarm_tm.tm_year % 100); - case 0x40: /* RTC_CTRL_REG */ + case 0x40: /* RTC_CTRL_REG */ return (s->pm_am << 3) | (s->auto_comp << 2) | (s->round << 1) | s->running; - case 0x44: /* RTC_STATUS_REG */ + case 0x44: /* RTC_STATUS_REG */ i = s->status; s->status &= ~0x3d; return i; - case 0x48: /* RTC_INTERRUPTS_REG */ + case 0x48: /* RTC_INTERRUPTS_REG */ return s->interrupts; - case 0x4c: /* RTC_COMP_LSB_REG */ + case 0x4c: /* RTC_COMP_LSB_REG */ return ((uint16_t) s->comp_reg) & 0xff; - case 0x50: /* RTC_COMP_MSB_REG */ + case 0x50: /* RTC_COMP_MSB_REG */ return ((uint16_t) s->comp_reg) >> 8; } @@ -2661,17 +2661,17 @@ static void omap_rtc_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* SECONDS_REG */ + case 0x00: /* SECONDS_REG */ s->ti -= s->current_tm.tm_sec; s->ti += from_bcd(value); return; - case 0x04: /* MINUTES_REG */ + case 0x04: /* MINUTES_REG */ s->ti -= s->current_tm.tm_min * 60; s->ti += from_bcd(value) * 60; return; - case 0x08: /* HOURS_REG */ + case 0x08: /* HOURS_REG */ s->ti -= s->current_tm.tm_hour * 3600; if (s->pm_am) { s->ti += (from_bcd(value & 0x3f) & 12) * 3600; @@ -2680,12 +2680,12 @@ static void omap_rtc_write(void *opaque, hwaddr addr, s->ti += from_bcd(value & 0x3f) * 3600; return; - case 0x0c: /* DAYS_REG */ + case 0x0c: /* DAYS_REG */ s->ti -= s->current_tm.tm_mday * 86400; s->ti += from_bcd(value) * 86400; return; - case 0x10: /* MONTHS_REG */ + case 0x10: /* MONTHS_REG */ memcpy(&new_tm, &s->current_tm, sizeof(new_tm)); new_tm.tm_mon = from_bcd(value); ti[0] = mktimegm(&s->current_tm); @@ -2701,7 +2701,7 @@ static void omap_rtc_write(void *opaque, hwaddr addr, } return; - case 0x14: /* YEARS_REG */ + case 0x14: /* YEARS_REG */ memcpy(&new_tm, &s->current_tm, sizeof(new_tm)); new_tm.tm_year += from_bcd(value) - (new_tm.tm_year % 100); ti[0] = mktimegm(&s->current_tm); @@ -2717,20 +2717,20 @@ static void omap_rtc_write(void *opaque, hwaddr addr, } return; - case 0x18: /* WEEK_REG */ - return; /* Ignored */ + case 0x18: /* WEEK_REG */ + return; /* Ignored */ - case 0x20: /* ALARM_SECONDS_REG */ + case 0x20: /* ALARM_SECONDS_REG */ s->alarm_tm.tm_sec = from_bcd(value); omap_rtc_alarm_update(s); return; - case 0x24: /* ALARM_MINUTES_REG */ + case 0x24: /* ALARM_MINUTES_REG */ s->alarm_tm.tm_min = from_bcd(value); omap_rtc_alarm_update(s); return; - case 0x28: /* ALARM_HOURS_REG */ + case 0x28: /* ALARM_HOURS_REG */ if (s->pm_am) s->alarm_tm.tm_hour = ((from_bcd(value & 0x3f)) % 12) + @@ -2740,22 +2740,22 @@ static void omap_rtc_write(void *opaque, hwaddr addr, omap_rtc_alarm_update(s); return; - case 0x2c: /* ALARM_DAYS_REG */ + case 0x2c: /* ALARM_DAYS_REG */ s->alarm_tm.tm_mday = from_bcd(value); omap_rtc_alarm_update(s); return; - case 0x30: /* ALARM_MONTHS_REG */ + case 0x30: /* ALARM_MONTHS_REG */ s->alarm_tm.tm_mon = from_bcd(value); omap_rtc_alarm_update(s); return; - case 0x34: /* ALARM_YEARS_REG */ + case 0x34: /* ALARM_YEARS_REG */ s->alarm_tm.tm_year = from_bcd(value); omap_rtc_alarm_update(s); return; - case 0x40: /* RTC_CTRL_REG */ + case 0x40: /* RTC_CTRL_REG */ s->pm_am = (value >> 3) & 1; s->auto_comp = (value >> 2) & 1; s->round = (value >> 1) & 1; @@ -2764,21 +2764,21 @@ static void omap_rtc_write(void *opaque, hwaddr addr, s->status |= s->running << 1; return; - case 0x44: /* RTC_STATUS_REG */ + case 0x44: /* RTC_STATUS_REG */ s->status &= ~((value & 0xc0) ^ 0x80); omap_rtc_interrupts_update(s); return; - case 0x48: /* RTC_INTERRUPTS_REG */ + case 0x48: /* RTC_INTERRUPTS_REG */ s->interrupts = value; return; - case 0x4c: /* RTC_COMP_LSB_REG */ + case 0x4c: /* RTC_COMP_LSB_REG */ s->comp_reg &= 0xff00; s->comp_reg |= 0x00ff & value; return; - case 0x50: /* RTC_COMP_MSB_REG */ + case 0x50: /* RTC_COMP_MSB_REG */ s->comp_reg &= 0x00ff; s->comp_reg |= 0xff00 & (value << 8); return; @@ -2929,12 +2929,12 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) { int irq; - switch ((s->spcr[0] >> 4) & 3) { /* RINTM */ + switch ((s->spcr[0] >> 4) & 3) { /* RINTM */ case 0: - irq = (s->spcr[0] >> 1) & 1; /* RRDY */ + irq = (s->spcr[0] >> 1) & 1; /* RRDY */ break; case 3: - irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */ + irq = (s->spcr[0] >> 3) & 1; /* RSYNCERR */ break; default: irq = 0; @@ -2944,12 +2944,12 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) if (irq) qemu_irq_pulse(s->rxirq); - switch ((s->spcr[1] >> 4) & 3) { /* XINTM */ + switch ((s->spcr[1] >> 4) & 3) { /* XINTM */ case 0: - irq = (s->spcr[1] >> 1) & 1; /* XRDY */ + irq = (s->spcr[1] >> 1) & 1; /* XRDY */ break; case 3: - irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */ + irq = (s->spcr[1] >> 3) & 1; /* XSYNCERR */ break; default: irq = 0; @@ -2962,9 +2962,9 @@ static void omap_mcbsp_intr_update(struct omap_mcbsp_s *s) static void omap_mcbsp_rx_newdata(struct omap_mcbsp_s *s) { - if ((s->spcr[0] >> 1) & 1) /* RRDY */ - s->spcr[0] |= 1 << 2; /* RFULL */ - s->spcr[0] |= 1 << 1; /* RRDY */ + if ((s->spcr[0] >> 1) & 1) /* RRDY */ + s->spcr[0] |= 1 << 2; /* RFULL */ + s->spcr[0] |= 1 << 1; /* RRDY */ qemu_irq_raise(s->rxdrq); omap_mcbsp_intr_update(s); } @@ -3004,14 +3004,14 @@ static void omap_mcbsp_rx_stop(struct omap_mcbsp_s *s) static void omap_mcbsp_rx_done(struct omap_mcbsp_s *s) { - s->spcr[0] &= ~(1 << 1); /* RRDY */ + s->spcr[0] &= ~(1 << 1); /* RRDY */ qemu_irq_lower(s->rxdrq); omap_mcbsp_intr_update(s); } static void omap_mcbsp_tx_newdata(struct omap_mcbsp_s *s) { - s->spcr[1] |= 1 << 1; /* XRDY */ + s->spcr[1] |= 1 << 1; /* XRDY */ qemu_irq_raise(s->txdrq); omap_mcbsp_intr_update(s); } @@ -3046,7 +3046,7 @@ static void omap_mcbsp_tx_start(struct omap_mcbsp_s *s) static void omap_mcbsp_tx_done(struct omap_mcbsp_s *s) { - s->spcr[1] &= ~(1 << 1); /* XRDY */ + s->spcr[1] &= ~(1 << 1); /* XRDY */ qemu_irq_lower(s->txdrq); omap_mcbsp_intr_update(s); if (s->codec && s->codec->cts) @@ -3064,27 +3064,27 @@ static void omap_mcbsp_req_update(struct omap_mcbsp_s *s) { int prev_rx_rate, prev_tx_rate; int rx_rate = 0, tx_rate = 0; - int cpu_rate = 1500000; /* XXX */ + int cpu_rate = 1500000; /* XXX */ /* TODO: check CLKSTP bit */ - if (s->spcr[1] & (1 << 6)) { /* GRST */ - if (s->spcr[0] & (1 << 0)) { /* RRST */ - if ((s->srgr[1] & (1 << 13)) && /* CLKSM */ - (s->pcr & (1 << 8))) { /* CLKRM */ - if (~s->pcr & (1 << 7)) /* SCLKME */ + if (s->spcr[1] & (1 << 6)) { /* GRST */ + if (s->spcr[0] & (1 << 0)) { /* RRST */ + if ((s->srgr[1] & (1 << 13)) && /* CLKSM */ + (s->pcr & (1 << 8))) { /* CLKRM */ + if (~s->pcr & (1 << 7)) /* SCLKME */ rx_rate = cpu_rate / - ((s->srgr[0] & 0xff) + 1); /* CLKGDV */ + ((s->srgr[0] & 0xff) + 1); /* CLKGDV */ } else if (s->codec) rx_rate = s->codec->rx_rate; } - if (s->spcr[1] & (1 << 0)) { /* XRST */ - if ((s->srgr[1] & (1 << 13)) && /* CLKSM */ - (s->pcr & (1 << 9))) { /* CLKXM */ - if (~s->pcr & (1 << 7)) /* SCLKME */ + if (s->spcr[1] & (1 << 0)) { /* XRST */ + if ((s->srgr[1] & (1 << 13)) && /* CLKSM */ + (s->pcr & (1 << 9))) { /* CLKXM */ + if (~s->pcr & (1 << 7)) /* SCLKME */ tx_rate = cpu_rate / - ((s->srgr[0] & 0xff) + 1); /* CLKGDV */ + ((s->srgr[0] & 0xff) + 1); /* CLKGDV */ } else if (s->codec) tx_rate = s->codec->tx_rate; @@ -3121,11 +3121,11 @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* DRR2 */ - if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */ + case 0x00: /* DRR2 */ + if (((s->rcr[0] >> 5) & 7) < 3) /* RWDLEN1 */ return 0x0000; /* Fall through. */ - case 0x02: /* DRR1 */ + case 0x02: /* DRR1 */ if (s->rx_req < 2) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Rx FIFO underrun\n", __func__); omap_mcbsp_rx_done(s); @@ -3143,63 +3143,63 @@ static uint64_t omap_mcbsp_read(void *opaque, hwaddr addr, } return 0x0000; - case 0x04: /* DXR2 */ - case 0x06: /* DXR1 */ + case 0x04: /* DXR2 */ + case 0x06: /* DXR1 */ return 0x0000; - case 0x08: /* SPCR2 */ + case 0x08: /* SPCR2 */ return s->spcr[1]; - case 0x0a: /* SPCR1 */ + case 0x0a: /* SPCR1 */ return s->spcr[0]; - case 0x0c: /* RCR2 */ + case 0x0c: /* RCR2 */ return s->rcr[1]; - case 0x0e: /* RCR1 */ + case 0x0e: /* RCR1 */ return s->rcr[0]; - case 0x10: /* XCR2 */ + case 0x10: /* XCR2 */ return s->xcr[1]; - case 0x12: /* XCR1 */ + case 0x12: /* XCR1 */ return s->xcr[0]; - case 0x14: /* SRGR2 */ + case 0x14: /* SRGR2 */ return s->srgr[1]; - case 0x16: /* SRGR1 */ + case 0x16: /* SRGR1 */ return s->srgr[0]; - case 0x18: /* MCR2 */ + case 0x18: /* MCR2 */ return s->mcr[1]; - case 0x1a: /* MCR1 */ + case 0x1a: /* MCR1 */ return s->mcr[0]; - case 0x1c: /* RCERA */ + case 0x1c: /* RCERA */ return s->rcer[0]; - case 0x1e: /* RCERB */ + case 0x1e: /* RCERB */ return s->rcer[1]; - case 0x20: /* XCERA */ + case 0x20: /* XCERA */ return s->xcer[0]; - case 0x22: /* XCERB */ + case 0x22: /* XCERB */ return s->xcer[1]; - case 0x24: /* PCR0 */ + case 0x24: /* PCR0 */ return s->pcr; - case 0x26: /* RCERC */ + case 0x26: /* RCERC */ return s->rcer[2]; - case 0x28: /* RCERD */ + case 0x28: /* RCERD */ return s->rcer[3]; - case 0x2a: /* XCERC */ + case 0x2a: /* XCERC */ return s->xcer[2]; - case 0x2c: /* XCERD */ + case 0x2c: /* XCERD */ return s->xcer[3]; - case 0x2e: /* RCERE */ + case 0x2e: /* RCERE */ return s->rcer[4]; - case 0x30: /* RCERF */ + case 0x30: /* RCERF */ return s->rcer[5]; - case 0x32: /* XCERE */ + case 0x32: /* XCERE */ return s->xcer[4]; - case 0x34: /* XCERF */ + case 0x34: /* XCERF */ return s->xcer[5]; - case 0x36: /* RCERG */ + case 0x36: /* RCERG */ return s->rcer[6]; - case 0x38: /* RCERH */ + case 0x38: /* RCERH */ return s->rcer[7]; - case 0x3a: /* XCERG */ + case 0x3a: /* XCERG */ return s->xcer[6]; - case 0x3c: /* XCERH */ + case 0x3c: /* XCERH */ return s->xcer[7]; } @@ -3214,16 +3214,16 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr, int offset = addr & OMAP_MPUI_REG_MASK; switch (offset) { - case 0x00: /* DRR2 */ - case 0x02: /* DRR1 */ + case 0x00: /* DRR2 */ + case 0x02: /* DRR1 */ OMAP_RO_REG(addr); return; - case 0x04: /* DXR2 */ - if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */ + case 0x04: /* DXR2 */ + if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */ return; /* Fall through. */ - case 0x06: /* DXR1 */ + case 0x06: /* DXR1 */ if (s->tx_req > 1) { s->tx_req -= 2; if (s->codec && s->codec->cts) { @@ -3237,15 +3237,15 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr, } return; - case 0x08: /* SPCR2 */ + case 0x08: /* SPCR2 */ s->spcr[1] &= 0x0002; s->spcr[1] |= 0x03f9 & value; - s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */ - if (~value & 1) /* XRST */ + s->spcr[1] |= 0x0004 & (value << 2); /* XEMPTY := XRST */ + if (~value & 1) /* XRST */ s->spcr[1] &= ~6; omap_mcbsp_req_update(s); return; - case 0x0a: /* SPCR1 */ + case 0x0a: /* SPCR1 */ s->spcr[0] &= 0x0006; s->spcr[0] |= 0xf8f9 & value; if (value & (1 << 15)) { /* DLB */ @@ -3253,7 +3253,7 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr, "%s: Digital Loopback mode enable attempt\n", __func__); } - if (~value & 1) { /* RRST */ + if (~value & 1) { /* RRST */ s->spcr[0] &= ~6; s->rx_req = 0; omap_mcbsp_rx_done(s); @@ -3261,27 +3261,27 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr, omap_mcbsp_req_update(s); return; - case 0x0c: /* RCR2 */ + case 0x0c: /* RCR2 */ s->rcr[1] = value & 0xffff; return; - case 0x0e: /* RCR1 */ + case 0x0e: /* RCR1 */ s->rcr[0] = value & 0x7fe0; return; - case 0x10: /* XCR2 */ + case 0x10: /* XCR2 */ s->xcr[1] = value & 0xffff; return; - case 0x12: /* XCR1 */ + case 0x12: /* XCR1 */ s->xcr[0] = value & 0x7fe0; return; - case 0x14: /* SRGR2 */ + case 0x14: /* SRGR2 */ s->srgr[1] = value & 0xffff; omap_mcbsp_req_update(s); return; - case 0x16: /* SRGR1 */ + case 0x16: /* SRGR1 */ s->srgr[0] = value & 0xffff; omap_mcbsp_req_update(s); return; - case 0x18: /* MCR2 */ + case 0x18: /* MCR2 */ s->mcr[1] = value & 0x03e3; if (value & 3) { /* XMCM */ qemu_log_mask(LOG_UNIMP, @@ -3289,7 +3289,7 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr, __func__); } return; - case 0x1a: /* MCR1 */ + case 0x1a: /* MCR1 */ s->mcr[0] = value & 0x03e1; if (value & 1) { /* RMCM */ qemu_log_mask(LOG_UNIMP, @@ -3297,55 +3297,55 @@ static void omap_mcbsp_writeh(void *opaque, hwaddr addr, __func__); } return; - case 0x1c: /* RCERA */ + case 0x1c: /* RCERA */ s->rcer[0] = value & 0xffff; return; - case 0x1e: /* RCERB */ + case 0x1e: /* RCERB */ s->rcer[1] = value & 0xffff; return; - case 0x20: /* XCERA */ + case 0x20: /* XCERA */ s->xcer[0] = value & 0xffff; return; - case 0x22: /* XCERB */ + case 0x22: /* XCERB */ s->xcer[1] = value & 0xffff; return; - case 0x24: /* PCR0 */ + case 0x24: /* PCR0 */ s->pcr = value & 0x7faf; return; - case 0x26: /* RCERC */ + case 0x26: /* RCERC */ s->rcer[2] = value & 0xffff; return; - case 0x28: /* RCERD */ + case 0x28: /* RCERD */ s->rcer[3] = value & 0xffff; return; - case 0x2a: /* XCERC */ + case 0x2a: /* XCERC */ s->xcer[2] = value & 0xffff; return; - case 0x2c: /* XCERD */ + case 0x2c: /* XCERD */ s->xcer[3] = value & 0xffff; return; - case 0x2e: /* RCERE */ + case 0x2e: /* RCERE */ s->rcer[4] = value & 0xffff; return; - case 0x30: /* RCERF */ + case 0x30: /* RCERF */ s->rcer[5] = value & 0xffff; return; - case 0x32: /* XCERE */ + case 0x32: /* XCERE */ s->xcer[4] = value & 0xffff; return; - case 0x34: /* XCERF */ + case 0x34: /* XCERF */ s->xcer[5] = value & 0xffff; return; - case 0x36: /* RCERG */ + case 0x36: /* RCERG */ s->rcer[6] = value & 0xffff; return; - case 0x38: /* RCERH */ + case 0x38: /* RCERH */ s->rcer[7] = value & 0xffff; return; - case 0x3a: /* XCERG */ + case 0x3a: /* XCERG */ s->xcer[6] = value & 0xffff; return; - case 0x3c: /* XCERH */ + case 0x3c: /* XCERH */ s->xcer[7] = value & 0xffff; return; } @@ -3359,8 +3359,8 @@ static void omap_mcbsp_writew(void *opaque, hwaddr addr, struct omap_mcbsp_s *s = opaque; int offset = addr & OMAP_MPUI_REG_MASK; - if (offset == 0x04) { /* DXR */ - if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */ + if (offset == 0x04) { /* DXR */ + if (((s->xcr[0] >> 5) & 7) < 3) /* XWDLEN1 */ return; if (s->tx_req > 3) { s->tx_req -= 4; @@ -3504,15 +3504,15 @@ static void omap_lpg_update(struct omap_lpg_s *s) int64_t on, period = 1, ticks = 1000; static const int per[8] = { 1, 2, 4, 8, 12, 16, 20, 24 }; - if (~s->control & (1 << 6)) /* LPGRES */ + if (~s->control & (1 << 6)) /* LPGRES */ on = 0; - else if (s->control & (1 << 7)) /* PERM_ON */ + else if (s->control & (1 << 7)) /* PERM_ON */ on = period; else { - period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */ + period = muldiv64(ticks, per[s->control & 7], /* PERCTRL */ 256 / 32); on = (s->clk && s->power) ? muldiv64(ticks, - per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */ + per[(s->control >> 3) & 7], 256) : 0; /* ONCTRL */ } timer_del(s->tm); @@ -3550,10 +3550,10 @@ static uint64_t omap_lpg_read(void *opaque, hwaddr addr, unsigned size) } switch (offset) { - case 0x00: /* LCR */ + case 0x00: /* LCR */ return s->control; - case 0x04: /* PMR */ + case 0x04: /* PMR */ return s->power; } @@ -3573,14 +3573,14 @@ static void omap_lpg_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* LCR */ - if (~value & (1 << 6)) /* LPGRES */ + case 0x00: /* LCR */ + if (~value & (1 << 6)) /* LPGRES */ omap_lpg_reset(s); s->control = value & 0xff; omap_lpg_update(s); return; - case 0x04: /* PMR */ + case 0x04: /* PMR */ s->power = value & 0x01; omap_lpg_update(s); return; @@ -3630,7 +3630,7 @@ static uint64_t omap_mpui_io_read(void *opaque, hwaddr addr, return omap_badwidth_read16(opaque, addr); } - if (addr == OMAP_MPUI_BASE) /* CMR */ + if (addr == OMAP_MPUI_BASE) /* CMR */ return 0xfe4d; OMAP_BAD_REG(addr); @@ -3703,25 +3703,25 @@ static const struct omap_map_s { const char *name; } omap15xx_dsp_mm[] = { /* Strobe 0 */ - { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */ - { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */ - { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */ - { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */ - { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */ - { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */ - { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */ - { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */ - { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */ - { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */ - { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */ - { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */ - { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */ - { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */ - { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */ - { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */ - { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */ + { 0xe1010000, 0xfffb0000, 0x800, "UART1 BT" }, /* CS0 */ + { 0xe1010800, 0xfffb0800, 0x800, "UART2 COM" }, /* CS1 */ + { 0xe1011800, 0xfffb1800, 0x800, "McBSP1 audio" }, /* CS3 */ + { 0xe1012000, 0xfffb2000, 0x800, "MCSI2 communication" }, /* CS4 */ + { 0xe1012800, 0xfffb2800, 0x800, "MCSI1 BT u-Law" }, /* CS5 */ + { 0xe1013000, 0xfffb3000, 0x800, "uWire" }, /* CS6 */ + { 0xe1013800, 0xfffb3800, 0x800, "I^2C" }, /* CS7 */ + { 0xe1014000, 0xfffb4000, 0x800, "USB W2FC" }, /* CS8 */ + { 0xe1014800, 0xfffb4800, 0x800, "RTC" }, /* CS9 */ + { 0xe1015000, 0xfffb5000, 0x800, "MPUIO" }, /* CS10 */ + { 0xe1015800, 0xfffb5800, 0x800, "PWL" }, /* CS11 */ + { 0xe1016000, 0xfffb6000, 0x800, "PWT" }, /* CS12 */ + { 0xe1017000, 0xfffb7000, 0x800, "McBSP3" }, /* CS14 */ + { 0xe1017800, 0xfffb7800, 0x800, "MMC" }, /* CS15 */ + { 0xe1019000, 0xfffb9000, 0x800, "32-kHz timer" }, /* CS18 */ + { 0xe1019800, 0xfffb9800, 0x800, "UART3" }, /* CS19 */ + { 0xe101c800, 0xfffbc800, 0x800, "TIPB switches" }, /* CS25 */ /* Strobe 1 */ - { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */ + { 0xe101e000, 0xfffce000, 0x800, "GPIOs" }, /* CS28 */ { 0 } }; @@ -4025,18 +4025,18 @@ struct omap_mpu_state_s *omap310_mpu_init(MemoryRegion *dram, 0xfffbd800, omap_findclk(s, "clk32-kHz")); /* Register mappings not currently implemented: - * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310) - * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310) - * USB W2FC fffb4000 - fffb47ff - * Camera Interface fffb6800 - fffb6fff - * USB Host fffba000 - fffba7ff - * FAC fffba800 - fffbafff - * HDQ/1-Wire fffbc000 - fffbc7ff - * TIPB switches fffbc800 - fffbcfff - * Mailbox fffcf000 - fffcf7ff - * Local bus IF fffec100 - fffec1ff - * Local bus MMU fffec200 - fffec2ff - * DSP MMU fffed200 - fffed2ff + * MCSI2 Comm fffb2000 - fffb27ff (not mapped on OMAP310) + * MCSI1 Bluetooth fffb2800 - fffb2fff (not mapped on OMAP310) + * USB W2FC fffb4000 - fffb47ff + * Camera Interface fffb6800 - fffb6fff + * USB Host fffba000 - fffba7ff + * FAC fffba800 - fffbafff + * HDQ/1-Wire fffbc000 - fffbc7ff + * TIPB switches fffbc800 - fffbcfff + * Mailbox fffcf000 - fffcf7ff + * Local bus IF fffec100 - fffec1ff + * Local bus MMU fffec200 - fffec2ff + * DSP MMU fffed200 - fffed2ff */ omap_setup_dsp_mapping(system_memory, omap15xx_dsp_mm); diff --git a/hw/arm/omap_sx1.c b/hw/arm/omap_sx1.c index 24b4043..5d4a31b 100644 --- a/hw/arm/omap_sx1.c +++ b/hw/arm/omap_sx1.c @@ -1,7 +1,7 @@ /* omap_sx1.c Support for the Siemens SX1 smartphone emulation. * * Copyright (C) 2008 - * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> * Copyright (C) 2007 Vladimir Ananiev <vovan888@gmail.com> * * based on PalmOne's (TM) PDAs support (palm.c) @@ -34,7 +34,7 @@ #include "hw/arm/boot.h" #include "hw/block/flash.h" #include "system/qtest.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qemu/cutils.h" #include "qemu/error-report.h" @@ -202,7 +202,7 @@ static void sx1_init_v2(MachineState *machine) sx1_init(machine, 2); } -static void sx1_machine_v2_class_init(ObjectClass *oc, void *data) +static void sx1_machine_v2_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -221,7 +221,7 @@ static const TypeInfo sx1_machine_v2_type = { .class_init = sx1_machine_v2_class_init, }; -static void sx1_machine_v1_class_init(ObjectClass *oc, void *data) +static void sx1_machine_v1_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/orangepi.c b/hw/arm/orangepi.c index 634af9b..e095688 100644 --- a/hw/arm/orangepi.c +++ b/hw/arm/orangepi.c @@ -19,7 +19,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/boards.h" diff --git a/hw/arm/raspi.c b/hw/arm/raspi.c index dce35ca..9d9af63 100644 --- a/hw/arm/raspi.c +++ b/hw/arm/raspi.c @@ -337,7 +337,7 @@ static void raspi_machine_class_init(MachineClass *mc, mc->init = raspi_machine_init; }; -static void raspi0_machine_class_init(ObjectClass *oc, void *data) +static void raspi0_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); @@ -347,7 +347,7 @@ static void raspi0_machine_class_init(ObjectClass *oc, void *data) raspi_machine_class_init(mc, rmc->board_rev); }; -static void raspi1ap_machine_class_init(ObjectClass *oc, void *data) +static void raspi1ap_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); @@ -357,7 +357,7 @@ static void raspi1ap_machine_class_init(ObjectClass *oc, void *data) raspi_machine_class_init(mc, rmc->board_rev); }; -static void raspi2b_machine_class_init(ObjectClass *oc, void *data) +static void raspi2b_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); @@ -368,7 +368,7 @@ static void raspi2b_machine_class_init(ObjectClass *oc, void *data) }; #ifdef TARGET_AARCH64 -static void raspi3ap_machine_class_init(ObjectClass *oc, void *data) +static void raspi3ap_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); @@ -378,7 +378,7 @@ static void raspi3ap_machine_class_init(ObjectClass *oc, void *data) raspi_machine_class_init(mc, rmc->board_rev); }; -static void raspi3b_machine_class_init(ObjectClass *oc, void *data) +static void raspi3b_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); diff --git a/hw/arm/raspi4b.c b/hw/arm/raspi4b.c index f6de103..20082d5 100644 --- a/hw/arm/raspi4b.c +++ b/hw/arm/raspi4b.c @@ -107,7 +107,7 @@ static void raspi4b_machine_init(MachineState *machine) raspi_base_machine_init(machine, &soc->parent_obj); } -static void raspi4b_machine_class_init(ObjectClass *oc, void *data) +static void raspi4b_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); RaspiBaseMachineClass *rmc = RASPI_BASE_MACHINE_CLASS(oc); diff --git a/hw/arm/realview.c b/hw/arm/realview.c index 008eeaf..5c90504 100644 --- a/hw/arm/realview.c +++ b/hw/arm/realview.c @@ -413,7 +413,7 @@ static void realview_pbx_a9_init(MachineState *machine) realview_init(machine, BOARD_PBX_A9); } -static void realview_eb_class_init(ObjectClass *oc, void *data) +static void realview_eb_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -433,7 +433,7 @@ static const TypeInfo realview_eb_type = { .class_init = realview_eb_class_init, }; -static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data) +static void realview_eb_mpcore_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -454,7 +454,7 @@ static const TypeInfo realview_eb_mpcore_type = { .class_init = realview_eb_mpcore_class_init, }; -static void realview_pb_a8_class_init(ObjectClass *oc, void *data) +static void realview_pb_a8_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -473,7 +473,7 @@ static const TypeInfo realview_pb_a8_type = { .class_init = realview_pb_a8_class_init, }; -static void realview_pbx_a9_class_init(ObjectClass *oc, void *data) +static void realview_pbx_a9_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/sbsa-ref.c b/hw/arm/sbsa-ref.c index aa09d7a..15c1ff4 100644 --- a/hw/arm/sbsa-ref.c +++ b/hw/arm/sbsa-ref.c @@ -19,6 +19,7 @@ */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "qemu/datadir.h" #include "qapi/error.h" #include "qemu/error-report.h" @@ -53,8 +54,7 @@ #include "target/arm/cpu-qom.h" #include "target/arm/gtimer.h" -#define RAMLIMIT_GB 8192 -#define RAMLIMIT_BYTES (RAMLIMIT_GB * GiB) +#define RAMLIMIT_BYTES (8 * TiB) #define NUM_IRQS 256 #define NUM_SMMU_IRQS 4 @@ -756,7 +756,9 @@ static void sbsa_ref_init(MachineState *machine) sms->smp_cpus = smp_cpus; if (machine->ram_size > sbsa_ref_memmap[SBSA_MEM].size) { - error_report("sbsa-ref: cannot model more than %dGB RAM", RAMLIMIT_GB); + char *size_str = size_to_str(RAMLIMIT_BYTES); + + error_report("sbsa-ref: cannot model more than %s of RAM", size_str); exit(1); } @@ -880,7 +882,7 @@ static void sbsa_ref_instance_init(Object *obj) sbsa_flash_create(sms); } -static void sbsa_ref_class_init(ObjectClass *oc, void *data) +static void sbsa_ref_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); static const char * const valid_cpu_types[] = { diff --git a/hw/arm/smmu-common.c b/hw/arm/smmu-common.c index 1aa2eab..f39b99e 100644 --- a/hw/arm/smmu-common.c +++ b/hw/arm/smmu-common.c @@ -965,7 +965,7 @@ static const Property smmu_dev_properties[] = { TYPE_PCI_BUS, PCIBus *), }; -static void smmu_base_class_init(ObjectClass *klass, void *data) +static void smmu_base_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/arm/smmuv3.c b/hw/arm/smmuv3.c index 1a96287..ab67972 100644 --- a/hw/arm/smmuv3.c +++ b/hw/arm/smmuv3.c @@ -25,6 +25,7 @@ #include "hw/qdev-core.h" #include "hw/pci/pci.h" #include "cpu.h" +#include "exec/target_page.h" #include "trace.h" #include "qemu/log.h" #include "qemu/error-report.h" @@ -1983,7 +1984,7 @@ static void smmuv3_instance_init(Object *obj) /* Nothing much to do here as of now */ } -static void smmuv3_class_init(ObjectClass *klass, void *data) +static void smmuv3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -2030,7 +2031,7 @@ static int smmuv3_notify_flag_changed(IOMMUMemoryRegion *iommu, } static void smmuv3_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c index 3361111..031ea3a 100644 --- a/hw/arm/stellaris.c +++ b/hw/arm/stellaris.c @@ -20,7 +20,7 @@ #include "net/net.h" #include "hw/boards.h" #include "qemu/log.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/arm/armv7m.h" #include "hw/char/pl011.h" @@ -1413,7 +1413,7 @@ static void lm3s6965evb_init(MachineState *machine) * Stellaris LM3S811 Evaluation Board Schematics: * https://www.ti.com/lit/ug/symlink/spmu030.pdf */ -static void lm3s811evb_class_init(ObjectClass *oc, void *data) +static void lm3s811evb_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1433,7 +1433,7 @@ static const TypeInfo lm3s811evb_type = { * Stellaris: LM3S6965 Evaluation Board Schematics: * https://www.ti.com/lit/ug/symlink/spmu029.pdf */ -static void lm3s6965evb_class_init(ObjectClass *oc, void *data) +static void lm3s6965evb_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1458,7 +1458,7 @@ static void stellaris_machine_init(void) type_init(stellaris_machine_init) -static void stellaris_i2c_class_init(ObjectClass *klass, void *data) +static void stellaris_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1477,7 +1477,7 @@ static const TypeInfo stellaris_i2c_info = { .class_init = stellaris_i2c_class_init, }; -static void stellaris_adc_class_init(ObjectClass *klass, void *data) +static void stellaris_adc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1494,7 +1494,7 @@ static const TypeInfo stellaris_adc_info = { .class_init = stellaris_adc_class_init, }; -static void stellaris_sys_class_init(ObjectClass *klass, void *data) +static void stellaris_sys_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/arm/stm32f100_soc.c b/hw/arm/stm32f100_soc.c index 53b5636..0702d51 100644 --- a/hw/arm/stm32f100_soc.c +++ b/hw/arm/stm32f100_soc.c @@ -27,7 +27,7 @@ #include "qapi/error.h" #include "qemu/module.h" #include "hw/arm/boot.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/stm32f100_soc.h" #include "hw/qdev-properties.h" #include "hw/qdev-clock.h" @@ -181,7 +181,7 @@ static void stm32f100_soc_realize(DeviceState *dev_soc, Error **errp) create_unimplemented_device("CRC", 0x40023000, 0x400); } -static void stm32f100_soc_class_init(ObjectClass *klass, void *data) +static void stm32f100_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c index 47a54e5..229af7f 100644 --- a/hw/arm/stm32f205_soc.c +++ b/hw/arm/stm32f205_soc.c @@ -26,7 +26,7 @@ #include "qapi/error.h" #include "qemu/module.h" #include "hw/arm/boot.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/arm/stm32f205_soc.h" #include "hw/qdev-properties.h" #include "hw/qdev-clock.h" @@ -202,7 +202,7 @@ static void stm32f205_soc_realize(DeviceState *dev_soc, Error **errp) } } -static void stm32f205_soc_class_init(ObjectClass *klass, void *data) +static void stm32f205_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/stm32f405_soc.c b/hw/arm/stm32f405_soc.c index 18d8824..c8684e2 100644 --- a/hw/arm/stm32f405_soc.c +++ b/hw/arm/stm32f405_soc.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/arm/stm32f405_soc.h" #include "hw/qdev-clock.h" @@ -298,7 +298,7 @@ static void stm32f405_soc_realize(DeviceState *dev_soc, Error **errp) create_unimplemented_device("RNG", 0x50060800, 0x400); } -static void stm32f405_soc_class_init(ObjectClass *klass, void *data) +static void stm32f405_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/stm32l4x5_soc.c b/hw/arm/stm32l4x5_soc.c index dbf7532..64da555 100644 --- a/hw/arm/stm32l4x5_soc.c +++ b/hw/arm/stm32l4x5_soc.c @@ -24,7 +24,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/or-irq.h" #include "hw/arm/stm32l4x5_soc.h" @@ -435,7 +435,7 @@ static void stm32l4x5_soc_realize(DeviceState *dev_soc, Error **errp) create_unimplemented_device("QUADSPI", 0xA0001000, 0x400); } -static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data) +static void stm32l4x5_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -446,21 +446,21 @@ static void stm32l4x5_soc_class_init(ObjectClass *klass, void *data) /* No vmstate or reset required: device has no internal state */ } -static void stm32l4x5xc_soc_class_init(ObjectClass *oc, void *data) +static void stm32l4x5xc_soc_class_init(ObjectClass *oc, const void *data) { Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc); ssc->flash_size = 256 * KiB; } -static void stm32l4x5xe_soc_class_init(ObjectClass *oc, void *data) +static void stm32l4x5xe_soc_class_init(ObjectClass *oc, const void *data) { Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc); ssc->flash_size = 512 * KiB; } -static void stm32l4x5xg_soc_class_init(ObjectClass *oc, void *data) +static void stm32l4x5xg_soc_class_init(ObjectClass *oc, const void *data) { Stm32l4x5SocClass *ssc = STM32L4X5_SOC_CLASS(oc); diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index a31f4b4..229c98d 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -215,7 +215,7 @@ static const VMStateDescription vmstate_strongarm_pic_regs = { }, }; -static void strongarm_pic_class_init(ObjectClass *klass, void *data) +static void strongarm_pic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -448,7 +448,8 @@ static const VMStateDescription vmstate_strongarm_rtc_regs = { }, }; -static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, void *data) +static void strongarm_rtc_sysbus_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -693,7 +694,7 @@ static const VMStateDescription vmstate_strongarm_gpio_regs = { }, }; -static void strongarm_gpio_class_init(ObjectClass *klass, void *data) +static void strongarm_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -865,7 +866,7 @@ static const VMStateDescription vmstate_strongarm_ppc_regs = { }, }; -static void strongarm_ppc_class_init(ObjectClass *klass, void *data) +static void strongarm_ppc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1336,7 +1337,7 @@ static const Property strongarm_uart_properties[] = { DEFINE_PROP_CHR("chardev", StrongARMUARTState, chr), }; -static void strongarm_uart_class_init(ObjectClass *klass, void *data) +static void strongarm_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1589,7 +1590,7 @@ static const VMStateDescription vmstate_strongarm_ssp_regs = { }, }; -static void strongarm_ssp_class_init(ObjectClass *klass, void *data) +static void strongarm_ssp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/strongarm.h b/hw/arm/strongarm.h index 192821f..b11b3a3 100644 --- a/hw/arm/strongarm.h +++ b/hw/arm/strongarm.h @@ -1,7 +1,7 @@ #ifndef STRONGARM_H #define STRONGARM_H -#include "exec/memory.h" +#include "system/memory.h" #include "target/arm/cpu-qom.h" #define SA_CS0 0x00000000 diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c index 3576644..5cf1a70 100644 --- a/hw/arm/versatilepb.c +++ b/hw/arm/versatilepb.c @@ -412,7 +412,7 @@ static void vab_init(MachineState *machine) versatile_init(machine, 0x25e); } -static void versatilepb_class_init(ObjectClass *oc, void *data) +static void versatilepb_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -433,7 +433,7 @@ static const TypeInfo versatilepb_type = { .class_init = versatilepb_class_init, }; -static void versatileab_class_init(ObjectClass *oc, void *data) +static void versatileab_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -462,7 +462,7 @@ static void versatile_machine_init(void) type_init(versatile_machine_init) -static void vpb_sic_class_init(ObjectClass *klass, void *data) +static void vpb_sic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c index 76c6107..35f8d05 100644 --- a/hw/arm/vexpress.c +++ b/hw/arm/vexpress.c @@ -777,7 +777,7 @@ static void vexpress_a9_instance_init(Object *obj) vms->virt = false; } -static void vexpress_class_init(ObjectClass *oc, void *data) +static void vexpress_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -795,7 +795,7 @@ static void vexpress_class_init(ObjectClass *oc, void *data) "Security Extensions (TrustZone)"); } -static void vexpress_a9_class_init(ObjectClass *oc, void *data) +static void vexpress_a9_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a9"), @@ -811,7 +811,7 @@ static void vexpress_a9_class_init(ObjectClass *oc, void *data) vmc->daughterboard = &a9_daughterboard; } -static void vexpress_a15_class_init(ObjectClass *oc, void *data) +static void vexpress_a15_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a15"), diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c index 3ac8f8e..cd90c47 100644 --- a/hw/arm/virt-acpi-build.c +++ b/hw/arm/virt-acpi-build.c @@ -266,6 +266,43 @@ static int iort_idmap_compare(gconstpointer a, gconstpointer b) return idmap_a->input_base - idmap_b->input_base; } +/* Compute ID ranges (RIDs) from RC that are directed to the ITS Group node */ +static void create_rc_its_idmaps(GArray *its_idmaps, GArray *smmu_idmaps) +{ + AcpiIortIdMapping *idmap; + AcpiIortIdMapping next_range = {0}; + + /* + * Based on the RID ranges that are directed to the SMMU, determine the + * bypassed RID ranges, i.e., the ones that are directed to the ITS Group + * node and do not pass through the SMMU, by subtracting the SMMU-bound + * ranges from the full RID range (0x0000–0xFFFF). + */ + for (int i = 0; i < smmu_idmaps->len; i++) { + idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i); + + if (next_range.input_base < idmap->input_base) { + next_range.id_count = idmap->input_base - next_range.input_base; + g_array_append_val(its_idmaps, next_range); + } + + next_range.input_base = idmap->input_base + idmap->id_count; + } + + /* + * Append the last RC -> ITS ID mapping. + * + * RIDs are 16-bit, according to the PCI Express 2.0 Base Specification, rev + * 0.9, section 2.2.6.2, "Transaction Descriptor - Transaction ID Field", + * hence the end of the range is 0x10000. + */ + if (next_range.input_base < 0x10000) { + next_range.id_count = 0x10000 - next_range.input_base; + g_array_append_val(its_idmaps, next_range); + } +} + + /* * Input Output Remapping Table (IORT) * Conforms to "IO Remapping Table System Software on ARM Platforms", @@ -276,10 +313,9 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { int i, nb_nodes, rc_mapping_count; size_t node_size, smmu_offset = 0; - AcpiIortIdMapping *idmap; uint32_t id = 0; - GArray *smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping)); - GArray *its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping)); + GArray *rc_smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping)); + GArray *rc_its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping)); AcpiTable table = { .sig = "IORT", .rev = 3, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; @@ -287,40 +323,39 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) acpi_table_begin(&table, table_data); if (vms->iommu == VIRT_IOMMU_SMMUV3) { - AcpiIortIdMapping next_range = {0}; - object_child_foreach_recursive(object_get_root(), - iort_host_bridges, smmu_idmaps); + iort_host_bridges, rc_smmu_idmaps); /* Sort the smmu idmap by input_base */ - g_array_sort(smmu_idmaps, iort_idmap_compare); + g_array_sort(rc_smmu_idmaps, iort_idmap_compare); /* - * Split the whole RIDs by mapping from RC to SMMU, - * build the ID mapping from RC to ITS directly. + * Knowing the ID ranges from the RC to the SMMU, it's possible to + * determine the ID ranges from RC that are directed to the ITS. */ - for (i = 0; i < smmu_idmaps->len; i++) { - idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i); + create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps); - if (next_range.input_base < idmap->input_base) { - next_range.id_count = idmap->input_base - next_range.input_base; - g_array_append_val(its_idmaps, next_range); - } + nb_nodes = 2; /* RC and SMMUv3 */ + rc_mapping_count = rc_smmu_idmaps->len; - next_range.input_base = idmap->input_base + idmap->id_count; - } + if (vms->its) { + /* + * Knowing the ID ranges from the RC to the SMMU, it's possible to + * determine the ID ranges from RC that go directly to ITS. + */ + create_rc_its_idmaps(rc_its_idmaps, rc_smmu_idmaps); - /* Append the last RC -> ITS ID mapping */ - if (next_range.input_base < 0x10000) { - next_range.id_count = 0x10000 - next_range.input_base; - g_array_append_val(its_idmaps, next_range); + nb_nodes++; /* ITS */ + rc_mapping_count += rc_its_idmaps->len; } - - nb_nodes = 3; /* RC, ITS, SMMUv3 */ - rc_mapping_count = smmu_idmaps->len + its_idmaps->len; } else { - nb_nodes = 2; /* RC, ITS */ - rc_mapping_count = 1; + if (vms->its) { + nb_nodes = 2; /* RC and ITS */ + rc_mapping_count = 1; /* Direct map to ITS */ + } else { + nb_nodes = 1; /* RC only */ + rc_mapping_count = 0; /* No output mapping */ + } } /* Number of IORT Nodes */ build_append_int_noprefix(table_data, nb_nodes, 4); @@ -329,31 +364,43 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) build_append_int_noprefix(table_data, IORT_NODE_OFFSET, 4); build_append_int_noprefix(table_data, 0, 4); /* Reserved */ - /* Table 12 ITS Group Format */ - build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */ - node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */; - build_append_int_noprefix(table_data, node_size, 2); /* Length */ - build_append_int_noprefix(table_data, 1, 1); /* Revision */ - build_append_int_noprefix(table_data, id++, 4); /* Identifier */ - build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */ - build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */ - build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */ - /* GIC ITS Identifier Array */ - build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4); + if (vms->its) { + /* Table 12 ITS Group Format */ + build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */ + node_size = 20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */; + build_append_int_noprefix(table_data, node_size, 2); /* Length */ + build_append_int_noprefix(table_data, 1, 1); /* Revision */ + build_append_int_noprefix(table_data, id++, 4); /* Identifier */ + build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */ + build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */ + build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */ + /* GIC ITS Identifier Array */ + build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4); + } if (vms->iommu == VIRT_IOMMU_SMMUV3) { int irq = vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE; - + int smmu_mapping_count, offset_to_id_array; + + if (vms->its) { + smmu_mapping_count = 1; /* ITS Group node */ + offset_to_id_array = SMMU_V3_ENTRY_SIZE; /* Just after the header */ + } else { + smmu_mapping_count = 0; /* No ID mappings */ + offset_to_id_array = 0; /* No ID mappings array */ + } smmu_offset = table_data->len - table.table_offset; /* Table 9 SMMUv3 Format */ build_append_int_noprefix(table_data, 4 /* SMMUv3 */, 1); /* Type */ - node_size = SMMU_V3_ENTRY_SIZE + ID_MAPPING_ENTRY_SIZE; + node_size = SMMU_V3_ENTRY_SIZE + + (ID_MAPPING_ENTRY_SIZE * smmu_mapping_count); build_append_int_noprefix(table_data, node_size, 2); /* Length */ build_append_int_noprefix(table_data, 4, 1); /* Revision */ build_append_int_noprefix(table_data, id++, 4); /* Identifier */ - build_append_int_noprefix(table_data, 1, 4); /* Number of ID mappings */ + /* Number of ID mappings */ + build_append_int_noprefix(table_data, smmu_mapping_count, 4); /* Reference to ID Array */ - build_append_int_noprefix(table_data, SMMU_V3_ENTRY_SIZE, 4); + build_append_int_noprefix(table_data, offset_to_id_array, 4); /* Base address */ build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8); /* Flags */ @@ -369,9 +416,11 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) build_append_int_noprefix(table_data, 0, 4); /* Proximity domain */ /* DeviceID mapping index (ignored since interrupts are GSIV based) */ build_append_int_noprefix(table_data, 0, 4); - - /* output IORT node is the ITS group node (the first node) */ - build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); + /* Array of ID mappings */ + if (smmu_mapping_count) { + /* Output IORT node is the ITS Group node (the first node). */ + build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); + } } /* Table 17 Root Complex Node */ @@ -407,29 +456,44 @@ build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) if (vms->iommu == VIRT_IOMMU_SMMUV3) { AcpiIortIdMapping *range; - /* translated RIDs connect to SMMUv3 node: RC -> SMMUv3 -> ITS */ - for (i = 0; i < smmu_idmaps->len; i++) { - range = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i); - /* output IORT node is the smmuv3 node */ + /* + * Map RIDs (input) from RC to SMMUv3 nodes: RC -> SMMUv3. + * + * N.B.: The mapping from SMMUv3 to ITS Group node (SMMUv3 -> ITS) is + * defined in the SMMUv3 table, where all SMMUv3 IDs are mapped to the + * ITS Group node, if ITS is available. + */ + for (i = 0; i < rc_smmu_idmaps->len; i++) { + range = &g_array_index(rc_smmu_idmaps, AcpiIortIdMapping, i); + /* Output IORT node is the SMMUv3 node. */ build_iort_id_mapping(table_data, range->input_base, range->id_count, smmu_offset); } - /* bypassed RIDs connect to ITS group node directly: RC -> ITS */ - for (i = 0; i < its_idmaps->len; i++) { - range = &g_array_index(its_idmaps, AcpiIortIdMapping, i); - /* output IORT node is the ITS group node (the first node) */ - build_iort_id_mapping(table_data, range->input_base, - range->id_count, IORT_NODE_OFFSET); + if (vms->its) { + /* + * Map bypassed (don't go through the SMMU) RIDs (input) to + * ITS Group node directly: RC -> ITS. + */ + for (i = 0; i < rc_its_idmaps->len; i++) { + range = &g_array_index(rc_its_idmaps, AcpiIortIdMapping, i); + /* Output IORT node is the ITS Group node (the first node). */ + build_iort_id_mapping(table_data, range->input_base, + range->id_count, IORT_NODE_OFFSET); + } } } else { - /* output IORT node is the ITS group node (the first node) */ + /* + * Map all RIDs (input) to ITS Group node directly, since there is no + * SMMU: RC -> ITS. + * Output IORT node is the ITS Group node (the first node). + */ build_iort_id_mapping(table_data, 0, 0x10000, IORT_NODE_OFFSET); } acpi_table_end(linker, &table); - g_array_free(smmu_idmaps, true); - g_array_free(its_idmaps, true); + g_array_free(rc_smmu_idmaps, true); + g_array_free(rc_its_idmaps, true); } /* @@ -537,15 +601,12 @@ build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) static void build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); /* * Table 5-117 Flag Definitions * set only "Timer interrupt Mode" and assume "Timer Interrupt * polarity" bit as '0: Interrupt is Active high' */ - uint32_t irqflags = vmc->claim_edge_triggered_timers ? - 1 : /* Interrupt is Edge triggered */ - 0; /* Interrupt is Level triggered */ + const uint32_t irqflags = 0; /* Interrupt is Level triggered */ AcpiTable table = { .sig = "GTDT", .rev = 3, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; @@ -670,7 +731,6 @@ static void build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) { int i; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); const MemMapEntry *memmap = vms->memmap; AcpiTable table = { .sig = "APIC", .rev = 4, .oem_id = vms->oem_id, .oem_table_id = vms->oem_table_id }; @@ -741,7 +801,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms) memmap[VIRT_HIGH_GIC_REDIST2].size); } - if (its_class_name() && !vmc->no_its) { + if (vms->its) { /* * ACPI spec, Revision 6.0 Errata A * (original 6.0 definition has invalid Length) @@ -973,10 +1033,8 @@ void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables) vms->oem_table_id); } - if (its_class_name() && !vmc->no_its) { - acpi_add_table(table_offsets, tables_blob); - build_iort(tables_blob, tables->linker, vms); - } + acpi_add_table(table_offsets, tables_blob); + build_iort(tables_blob, tables->linker, vms); #ifdef CONFIG_TPM if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) { diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 3e72ada..3bcdf92 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -107,7 +107,7 @@ static void arm_virt_compat_set(MachineClass *mc) #define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \ static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \ ObjectClass *oc, \ - void *data) \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ arm_virt_compat_set(mc); \ @@ -370,14 +370,9 @@ static void fdt_add_timer_nodes(const VirtMachineState *vms) * the correct information. */ ARMCPU *armcpu; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI; MachineState *ms = MACHINE(vms); - if (vmc->claim_edge_triggered_timers) { - irqflags = GIC_FDT_IRQ_FLAGS_EDGE_LO_HI; - } - if (vms->gic_version == VIRT_GIC_VERSION_2) { irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START, GIC_FDT_IRQ_PPI_CPU_WIDTH, @@ -710,21 +705,18 @@ static inline DeviceState *create_acpi_ged(VirtMachineState *vms) static void create_its(VirtMachineState *vms) { - const char *itsclass = its_class_name(); DeviceState *dev; - if (!strcmp(itsclass, "arm-gicv3-its")) { - if (!vms->tcg_its) { - itsclass = NULL; - } - } - - if (!itsclass) { - /* Do nothing if not supported */ + assert(vms->its); + if (!kvm_irqchip_in_kernel() && !vms->tcg_its) { + /* + * Do nothing if ITS is neither supported by the host nor emulated by + * the machine. + */ return; } - dev = qdev_new(itsclass); + dev = qdev_new(its_class_name()); object_property_set_link(OBJECT(dev), "parent-gicv3", OBJECT(vms->gic), &error_abort); @@ -1492,9 +1484,12 @@ static void create_virtio_iommu_dt_bindings(VirtMachineState *vms) qemu_fdt_setprop_cell(ms->fdt, node, "phandle", vms->iommu_phandle); g_free(node); - qemu_fdt_setprop_cells(ms->fdt, vms->pciehb_nodename, "iommu-map", - 0x0, vms->iommu_phandle, 0x0, bdf, - bdf + 1, vms->iommu_phandle, bdf + 1, 0xffff - bdf); + if (!vms->default_bus_bypass_iommu) { + qemu_fdt_setprop_cells(ms->fdt, vms->pciehb_nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, bdf, + bdf + 1, vms->iommu_phandle, bdf + 1, + 0xffff - bdf); + } } static void create_pcie(VirtMachineState *vms) @@ -1617,8 +1612,10 @@ static void create_pcie(VirtMachineState *vms) switch (vms->iommu) { case VIRT_IOMMU_SMMUV3: create_smmu(vms, vms->bus); - qemu_fdt_setprop_cells(ms->fdt, nodename, "iommu-map", - 0x0, vms->iommu_phandle, 0x0, 0x10000); + if (!vms->default_bus_bypass_iommu) { + qemu_fdt_setprop_cells(ms->fdt, nodename, "iommu-map", + 0x0, vms->iommu_phandle, 0x0, 0x10000); + } break; default: g_assert_not_reached(); @@ -1704,7 +1701,6 @@ static void virt_build_smbios(VirtMachineState *vms) { MachineClass *mc = MACHINE_GET_CLASS(vms); MachineState *ms = MACHINE(vms); - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); uint8_t *smbios_tables, *smbios_anchor; size_t smbios_tables_len, smbios_anchor_len; struct smbios_phys_mem_area mem_array; @@ -1714,8 +1710,7 @@ static void virt_build_smbios(VirtMachineState *vms) product = "KVM Virtual Machine"; } - smbios_set_defaults("QEMU", product, - vmc->smbios_old_sys_ver ? "1.0" : mc->name); + smbios_set_defaults("QEMU", product, mc->name); /* build the array of physical mem area from base_memmap */ mem_array.address = vms->memmap[VIRT_MEM].base; @@ -1770,24 +1765,18 @@ void virt_machine_done(Notifier *notifier, void *data) static uint64_t virt_cpu_mp_affinity(VirtMachineState *vms, int idx) { - uint8_t clustersz = ARM_DEFAULT_CPUS_PER_CLUSTER; - VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms); + uint8_t clustersz; - if (!vmc->disallow_affinity_adjustment) { - /* Adjust MPIDR like 64-bit KVM hosts, which incorporate the - * GIC's target-list limitations. 32-bit KVM hosts currently - * always create clusters of 4 CPUs, but that is expected to - * change when they gain support for gicv3. When KVM is enabled - * it will override the changes we make here, therefore our - * purposes are to make TCG consistent (with 64-bit KVM hosts) - * and to improve SGI efficiency. - */ - if (vms->gic_version == VIRT_GIC_VERSION_2) { - clustersz = GIC_TARGETLIST_BITS; - } else { - clustersz = GICV3_TARGETLIST_BITS; - } + /* + * Adjust MPIDR to make TCG consistent (with 64-bit KVM hosts) + * and to improve SGI efficiency. + */ + if (vms->gic_version == VIRT_GIC_VERSION_2) { + clustersz = GIC_TARGETLIST_BITS; + } else { + clustersz = GICV3_TARGETLIST_BITS; } + return arm_build_mp_affinity(idx, clustersz); } @@ -2037,10 +2026,11 @@ static void finalize_gic_version(VirtMachineState *vms) } /* - * virt_cpu_post_init() must be called after the CPUs have - * been realized and the GIC has been created. + * virt_post_cpus_gic_realized() must be called after the CPUs and + * the GIC have both been realized. */ -static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem) +static void virt_post_cpus_gic_realized(VirtMachineState *vms, + MemoryRegion *sysmem) { int max_cpus = MACHINE(vms)->smp.max_cpus; bool aarch64, pmu, steal_time; @@ -2211,14 +2201,14 @@ static void machvirt_init(MachineState *machine) exit(1); } - if (vms->secure && (kvm_enabled() || hvf_enabled())) { + if (vms->secure && !tcg_enabled() && !qtest_enabled()) { error_report("mach-virt: %s does not support providing " "Security extensions (TrustZone) to the guest CPU", current_accel_name()); exit(1); } - if (vms->virt && (kvm_enabled() || hvf_enabled())) { + if (vms->virt && !tcg_enabled() && !qtest_enabled()) { error_report("mach-virt: %s does not support providing " "Virtualization extensions to the guest CPU", current_accel_name()); @@ -2273,10 +2263,6 @@ static void machvirt_init(MachineState *machine) object_property_set_bool(cpuobj, "kvm-steal-time", false, NULL); } - if (vmc->no_pmu && object_property_find(cpuobj, "pmu")) { - object_property_set_bool(cpuobj, "pmu", false, NULL); - } - if (vmc->no_tcg_lpa2 && object_property_find(cpuobj, "lpa2")) { object_property_set_bool(cpuobj, "lpa2", false, NULL); } @@ -2361,7 +2347,7 @@ static void machvirt_init(MachineState *machine) create_gic(vms, sysmem); - virt_cpu_post_init(vms, sysmem); + virt_post_cpus_gic_realized(vms, sysmem); fdt_add_pmu_nodes(vms); @@ -3124,7 +3110,7 @@ static int virt_hvf_get_physical_address_range(MachineState *ms) return requested_ipa_size; } -static void virt_machine_class_init(ObjectClass *oc, void *data) +static void virt_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -3348,22 +3334,14 @@ static void virt_instance_init(Object *obj) vms->highmem_compact = !vmc->no_highmem_compact; vms->gic_version = VIRT_GIC_VERSION_NOSEL; - vms->highmem_ecam = !vmc->no_highmem_ecam; + vms->highmem_ecam = true; vms->highmem_mmio = true; vms->highmem_redists = true; - if (vmc->no_its) { - vms->its = false; - } else { - /* Default allows ITS instantiation */ - vms->its = true; - - if (vmc->no_tcg_its) { - vms->tcg_its = false; - } else { - vms->tcg_its = true; - } - } + /* Default allows ITS instantiation */ + vms->its = true; + /* Allow ITS emulation if the machine version supports it */ + vms->tcg_its = !vmc->no_tcg_its; /* Default disallows iommu instantiation */ vms->iommu = VIRT_IOMMU_NONE; @@ -3396,7 +3374,7 @@ static const TypeInfo virt_machine_info = { .class_size = sizeof(VirtMachineClass), .class_init = virt_machine_class_init, .instance_init = virt_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, @@ -3583,99 +3561,3 @@ static void virt_machine_4_1_options(MachineClass *mc) mc->auto_enable_numa_with_memhp = false; } DEFINE_VIRT_MACHINE(4, 1) - -static void virt_machine_4_0_options(MachineClass *mc) -{ - virt_machine_4_1_options(mc); - compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len); -} -DEFINE_VIRT_MACHINE(4, 0) - -static void virt_machine_3_1_options(MachineClass *mc) -{ - virt_machine_4_0_options(mc); - compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len); -} -DEFINE_VIRT_MACHINE(3, 1) - -static void virt_machine_3_0_options(MachineClass *mc) -{ - virt_machine_3_1_options(mc); - compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len); -} -DEFINE_VIRT_MACHINE(3, 0) - -static void virt_machine_2_12_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_3_0_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len); - vmc->no_highmem_ecam = true; - mc->max_cpus = 255; -} -DEFINE_VIRT_MACHINE(2, 12) - -static void virt_machine_2_11_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_12_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len); - vmc->smbios_old_sys_ver = true; -} -DEFINE_VIRT_MACHINE(2, 11) - -static void virt_machine_2_10_options(MachineClass *mc) -{ - virt_machine_2_11_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len); - /* before 2.11 we never faulted accesses to bad addresses */ - mc->ignore_memory_transaction_failures = true; -} -DEFINE_VIRT_MACHINE(2, 10) - -static void virt_machine_2_9_options(MachineClass *mc) -{ - virt_machine_2_10_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_9, hw_compat_2_9_len); -} -DEFINE_VIRT_MACHINE(2, 9) - -static void virt_machine_2_8_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_9_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_8, hw_compat_2_8_len); - /* For 2.8 and earlier we falsely claimed in the DT that - * our timers were edge-triggered, not level-triggered. - */ - vmc->claim_edge_triggered_timers = true; -} -DEFINE_VIRT_MACHINE(2, 8) - -static void virt_machine_2_7_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_8_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_7, hw_compat_2_7_len); - /* ITS was introduced with 2.8 */ - vmc->no_its = true; - /* Stick with 1K pages for migration compatibility */ - mc->minimum_page_bits = 0; -} -DEFINE_VIRT_MACHINE(2, 7) - -static void virt_machine_2_6_options(MachineClass *mc) -{ - VirtMachineClass *vmc = VIRT_MACHINE_CLASS(OBJECT_CLASS(mc)); - - virt_machine_2_7_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_6, hw_compat_2_6_len); - vmc->disallow_affinity_adjustment = true; - /* Disable PMU for 2.6 as PMU support was first introduced in 2.7 */ - vmc->no_pmu = true; -} -DEFINE_VIRT_MACHINE(2, 6) diff --git a/hw/arm/xen-pvh.c b/hw/arm/xen-pvh.c index d1509bd..4b26bcf 100644 --- a/hw/arm/xen-pvh.c +++ b/hw/arm/xen-pvh.c @@ -49,7 +49,7 @@ static void xen_pvh_set_pci_intx_irq(void *opaque, int intx_irq, int level) } } -static void xen_arm_machine_class_init(ObjectClass *oc, void *data) +static void xen_arm_machine_class_init(ObjectClass *oc, const void *data) { XenPVHMachineClass *xpc = XEN_PVH_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c index b891666..0372cd0 100644 --- a/hw/arm/xilinx_zynq.c +++ b/hw/arm/xilinx_zynq.c @@ -453,7 +453,7 @@ static void zynq_init(MachineState *machine) arm_load_kernel(zynq_machine->cpu[0], machine, &zynq_binfo); } -static void zynq_machine_class_init(ObjectClass *oc, void *data) +static void zynq_machine_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { ARM_CPU_TYPE_NAME("cortex-a9"), diff --git a/hw/arm/xlnx-versal-virt.c b/hw/arm/xlnx-versal-virt.c index 0c6f035..adadbb7 100644 --- a/hw/arm/xlnx-versal-virt.c +++ b/hw/arm/xlnx-versal-virt.c @@ -808,7 +808,7 @@ static void versal_virt_machine_finalize(Object *obj) g_free(s->ospi_model); } -static void versal_virt_machine_class_init(ObjectClass *oc, void *data) +static void versal_virt_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/xlnx-versal.c b/hw/arm/xlnx-versal.c index 278545a..a42b9e7 100644 --- a/hw/arm/xlnx-versal.c +++ b/hw/arm/xlnx-versal.c @@ -17,9 +17,7 @@ #include "hw/sysbus.h" #include "net/net.h" #include "system/system.h" -#include "system/kvm.h" #include "hw/arm/boot.h" -#include "kvm_arm.h" #include "hw/misc/unimp.h" #include "hw/arm/xlnx-versal.h" #include "qemu/log.h" @@ -977,7 +975,7 @@ static const Property versal_properties[] = { TYPE_CAN_BUS, CanBusState *), }; -static void versal_class_init(ObjectClass *klass, void *data) +static void versal_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c index 4fdb153..14b6641 100644 --- a/hw/arm/xlnx-zcu102.c +++ b/hw/arm/xlnx-zcu102.c @@ -267,7 +267,7 @@ static void xlnx_zcu102_machine_instance_init(Object *obj) 0); } -static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data) +static void xlnx_zcu102_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c index d6022ff..ec96a46 100644 --- a/hw/arm/xlnx-zynqmp.c +++ b/hw/arm/xlnx-zynqmp.c @@ -22,9 +22,7 @@ #include "hw/intc/arm_gic_common.h" #include "hw/misc/unimp.h" #include "hw/boards.h" -#include "system/kvm.h" #include "system/system.h" -#include "kvm_arm.h" #include "target/arm/cpu-qom.h" #include "target/arm/gtimer.h" @@ -855,7 +853,7 @@ static const Property xlnx_zynqmp_props[] = { CanBusState *), }; -static void xlnx_zynqmp_class_init(ObjectClass *oc, void *data) +static void xlnx_zynqmp_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c index 05c5737..eb7a847 100644 --- a/hw/audio/ac97.c +++ b/hw/audio/ac97.c @@ -886,7 +886,7 @@ static void nabm_writel(void *opaque, uint32_t addr, uint32_t val) static int write_audio(AC97LinkState *s, AC97BusMasterRegs *r, int max, int *stop) { - uint8_t tmpbuf[4096]; + QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; uint32_t addr = r->bd.addr; uint32_t temp = r->picb << 1; uint32_t written = 0; @@ -959,7 +959,7 @@ static void write_bup(AC97LinkState *s, int elapsed) static int read_audio(AC97LinkState *s, AC97BusMasterRegs *r, int max, int *stop) { - uint8_t tmpbuf[4096]; + QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; uint32_t addr = r->bd.addr; uint32_t temp = r->picb << 1; uint32_t nread = 0; @@ -1328,7 +1328,7 @@ static const Property ac97_properties[] = { DEFINE_AUDIO_PROPERTIES(AC97LinkState, card), }; -static void ac97_class_init(ObjectClass *klass, void *data) +static void ac97_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1351,7 +1351,7 @@ static const TypeInfo ac97_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(AC97LinkState), .class_init = ac97_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c index 8c9767b..1f29a7e 100644 --- a/hw/audio/adlib.c +++ b/hw/audio/adlib.c @@ -303,7 +303,7 @@ static const Property adlib_properties[] = { DEFINE_PROP_UINT32 ("freq", AdlibState, freq, 44100), }; -static void adlib_class_initfn (ObjectClass *klass, void *data) +static void adlib_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS (klass); diff --git a/hw/audio/asc.c b/hw/audio/asc.c index cea7a1c..edd42d6 100644 --- a/hw/audio/asc.c +++ b/hw/audio/asc.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "qemu/timer.h" +#include "qapi/error.h" #include "hw/sysbus.h" #include "hw/irq.h" #include "audio/audio.h" @@ -653,11 +654,17 @@ static void asc_realize(DeviceState *dev, Error **errp) s->voice = AUD_open_out(&s->card, s->voice, "asc.out", s, asc_out_cb, &as); + if (!s->voice) { + AUD_remove_card(&s->card); + error_setg(errp, "Initializing audio stream failed"); + return; + } + s->shift = 1; s->samples = AUD_get_buffer_size_out(s->voice) >> s->shift; s->mixbuf = g_malloc0(s->samples << s->shift); - s->silentbuf = g_malloc0(s->samples << s->shift); + s->silentbuf = g_malloc(s->samples << s->shift); memset(s->silentbuf, 0x80, s->samples << s->shift); /* Add easc registers if required */ @@ -699,7 +706,7 @@ static const Property asc_properties[] = { DEFINE_PROP_UINT8("asctype", ASCState, type, ASC_TYPE_ASC), }; -static void asc_class_init(ObjectClass *oc, void *data) +static void asc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c index 8321f89..97cceb4 100644 --- a/hw/audio/cs4231.c +++ b/hw/audio/cs4231.c @@ -160,7 +160,7 @@ static void cs4231_init(Object *obj) sysbus_init_irq(dev, &s->irq); } -static void cs4231_class_init(ObjectClass *klass, void *data) +static void cs4231_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c index 5a9be80..6dfff20 100644 --- a/hw/audio/cs4231a.c +++ b/hw/audio/cs4231a.c @@ -528,7 +528,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos, int dma_len, int len) { int temp, net; - uint8_t tmpbuf[4096]; + QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); temp = len; @@ -547,7 +547,7 @@ static int cs_write_audio (CSState *s, int nchan, int dma_pos, copied = k->read_memory(s->isa_dma, nchan, tmpbuf, dma_pos, to_copy); if (s->tab) { int i; - int16_t linbuf[4096]; + QEMU_UNINITIALIZED int16_t linbuf[4096]; for (i = 0; i < copied; ++i) linbuf[i] = s->tab[tmpbuf[i]]; @@ -682,6 +682,10 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp) return; } + if (s->irq >= ISA_NUM_IRQS) { + error_setg(errp, "Invalid IRQ %d (max %d)", s->irq, ISA_NUM_IRQS - 1); + return; + } s->pic = isa_bus_get_irq(bus, s->irq); k = ISADMA_GET_CLASS(s->isa_dma); k->register_channel(s->isa_dma, s->dma, cs_dma_read, s); @@ -696,7 +700,7 @@ static const Property cs4231a_properties[] = { DEFINE_PROP_UINT32 ("dma", CSState, dma, 3), }; -static void cs4231a_class_initfn (ObjectClass *klass, void *data) +static void cs4231a_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS (klass); diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c index 75f71e5..a6a32a6 100644 --- a/hw/audio/es1370.c +++ b/hw/audio/es1370.c @@ -604,7 +604,7 @@ static uint64_t es1370_read(void *opaque, hwaddr addr, unsigned size) static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel, int max, bool *irq) { - uint8_t tmpbuf[4096]; + QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; size_t to_transfer; uint32_t addr = d->frame_addr; int sc = d->scount & 0xffff; @@ -872,7 +872,7 @@ static const Property es1370_properties[] = { DEFINE_AUDIO_PROPERTIES(ES1370State, card), }; -static void es1370_class_init (ObjectClass *klass, void *data) +static void es1370_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS (klass); PCIDeviceClass *k = PCI_DEVICE_CLASS (klass); @@ -896,7 +896,7 @@ static const TypeInfo es1370_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof (ES1370State), .class_init = es1370_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/audio/gus.c b/hw/audio/gus.c index e718c11..c36df02 100644 --- a/hw/audio/gus.c +++ b/hw/audio/gus.c @@ -183,7 +183,7 @@ static int GUS_read_DMA (void *opaque, int nchan, int dma_pos, int dma_len) { GUSState *s = opaque; IsaDmaClass *k = ISADMA_GET_CLASS(s->isa_dma); - char tmpbuf[4096]; + QEMU_UNINITIALIZED char tmpbuf[4096]; int pos = dma_pos, mode, left = dma_len - dma_pos; ldebug ("read DMA %#x %d\n", dma_pos, dma_len); @@ -298,7 +298,7 @@ static const Property gus_properties[] = { DEFINE_PROP_UINT32 ("dma", GUSState, emu.gusdma, 3), }; -static void gus_class_initfn (ObjectClass *klass, void *data) +static void gus_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS (klass); diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c index 6f3a8f6..66edad2 100644 --- a/hw/audio/hda-codec.c +++ b/hw/audio/hda-codec.c @@ -900,7 +900,7 @@ static void hda_audio_init_micro(HDACodecDevice *hda, Error **errp) hda_audio_init(hda, desc, errp); } -static void hda_audio_base_class_init(ObjectClass *klass, void *data) +static void hda_audio_base_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); @@ -922,7 +922,7 @@ static const TypeInfo hda_audio_info = { .abstract = true, }; -static void hda_audio_output_class_init(ObjectClass *klass, void *data) +static void hda_audio_output_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); @@ -937,7 +937,7 @@ static const TypeInfo hda_audio_output_info = { .class_init = hda_audio_output_class_init, }; -static void hda_audio_duplex_class_init(ObjectClass *klass, void *data) +static void hda_audio_duplex_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); @@ -952,7 +952,7 @@ static const TypeInfo hda_audio_duplex_info = { .class_init = hda_audio_duplex_class_init, }; -static void hda_audio_micro_class_init(ObjectClass *klass, void *data) +static void hda_audio_micro_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); HDACodecDeviceClass *k = HDA_CODEC_DEVICE_CLASS(klass); diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c index 3214992..b256c8c 100644 --- a/hw/audio/intel-hda.c +++ b/hw/audio/intel-hda.c @@ -1220,7 +1220,7 @@ static const Property intel_hda_properties[] = { DEFINE_PROP_BOOL("old_msi_addr", IntelHDAState, old_msi_addr, false), }; -static void intel_hda_class_init(ObjectClass *klass, void *data) +static void intel_hda_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1234,7 +1234,7 @@ static void intel_hda_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, intel_hda_properties); } -static void intel_hda_class_init_ich6(ObjectClass *klass, void *data) +static void intel_hda_class_init_ich6(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1245,7 +1245,7 @@ static void intel_hda_class_init_ich6(ObjectClass *klass, void *data) dc->desc = "Intel HD Audio Controller (ich6)"; } -static void intel_hda_class_init_ich9(ObjectClass *klass, void *data) +static void intel_hda_class_init_ich9(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1262,7 +1262,7 @@ static const TypeInfo intel_hda_info = { .instance_size = sizeof(IntelHDAState), .class_init = intel_hda_class_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -1280,7 +1280,7 @@ static const TypeInfo intel_hda_info_ich9 = { .class_init = intel_hda_class_init_ich9, }; -static void hda_codec_device_class_init(ObjectClass *klass, void *data) +static void hda_codec_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->realize = hda_codec_dev_realize; diff --git a/hw/audio/marvell_88w8618.c b/hw/audio/marvell_88w8618.c index 28f9af3..c5c79d0 100644 --- a/hw/audio/marvell_88w8618.c +++ b/hw/audio/marvell_88w8618.c @@ -66,7 +66,7 @@ static void mv88w8618_audio_callback(void *opaque, int free_out, int free_in) { mv88w8618_audio_state *s = opaque; int16_t *codec_buffer; - int8_t buf[4096]; + QEMU_UNINITIALIZED int8_t buf[4096]; int8_t *mem_buffer; int pos, block_size; @@ -287,7 +287,7 @@ static const VMStateDescription mv88w8618_audio_vmsd = { } }; -static void mv88w8618_audio_class_init(ObjectClass *klass, void *data) +static void mv88w8618_audio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c index 17be185..a419161 100644 --- a/hw/audio/pcspk.c +++ b/hw/audio/pcspk.c @@ -221,7 +221,7 @@ static const Property pcspk_properties[] = { DEFINE_PROP_BOOL("migrate", PCSpkState, migrate, true), }; -static void pcspk_class_initfn(ObjectClass *klass, void *data) +static void pcspk_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c index f771d72..5d9d6c1 100644 --- a/hw/audio/pl041.c +++ b/hw/audio/pl041.c @@ -632,7 +632,7 @@ static const Property pl041_device_properties[] = { DEFAULT_FIFO_DEPTH), }; -static void pl041_device_class_init(ObjectClass *klass, void *data) +static void pl041_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c index 0c661b4..bac6411 100644 --- a/hw/audio/sb16.c +++ b/hw/audio/sb16.c @@ -1181,7 +1181,7 @@ static int write_audio (SB16State *s, int nchan, int dma_pos, IsaDma *isa_dma = nchan == s->dma ? s->isa_dma : s->isa_hdma; IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma); int temp, net; - uint8_t tmpbuf[4096]; + QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; temp = len; net = 0; @@ -1449,7 +1449,7 @@ static const Property sb16_properties[] = { DEFINE_PROP_UINT32 ("dma16", SB16State, hdma, 5), }; -static void sb16_class_initfn (ObjectClass *klass, void *data) +static void sb16_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS (klass); diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c index 4e115e0..d5231e1 100644 --- a/hw/audio/via-ac97.c +++ b/hw/audio/via-ac97.c @@ -175,7 +175,7 @@ static void out_cb(void *opaque, int avail) ViaAC97SGDChannel *c = &s->aur; int temp, to_copy, copied; bool stop = false; - uint8_t tmpbuf[4096]; + QEMU_UNINITIALIZED uint8_t tmpbuf[4096]; if (c->stat & STAT_PAUSED) { return; @@ -463,7 +463,7 @@ static const Property via_ac97_properties[] = { DEFINE_AUDIO_PROPERTIES(ViaAC97State, card), }; -static void via_ac97_class_init(ObjectClass *klass, void *data) +static void via_ac97_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -487,7 +487,7 @@ static const TypeInfo via_ac97_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(ViaAC97State), .class_init = via_ac97_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -501,7 +501,7 @@ static void via_mc97_realize(PCIDevice *pci_dev, Error **errp) pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03); } -static void via_mc97_class_init(ObjectClass *klass, void *data) +static void via_mc97_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -522,7 +522,7 @@ static const TypeInfo via_mc97_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = via_mc97_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/audio/virtio-snd-pci.c b/hw/audio/virtio-snd-pci.c index 74d93f4..9eb0007 100644 --- a/hw/audio/virtio-snd-pci.c +++ b/hw/audio/virtio-snd-pci.c @@ -42,7 +42,7 @@ static void virtio_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_snd_pci_class_init(ObjectClass *klass, void *data) +static void virtio_snd_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *vpciklass = VIRTIO_PCI_CLASS(klass); diff --git a/hw/audio/virtio-snd.c b/hw/audio/virtio-snd.c index 0b47741..eca3319 100644 --- a/hw/audio/virtio-snd.c +++ b/hw/audio/virtio-snd.c @@ -1361,7 +1361,7 @@ static void virtio_snd_reset(VirtIODevice *vdev) } } -static void virtio_snd_class_init(ObjectClass *klass, void *data) +static void virtio_snd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c index 8d381db..2846b55 100644 --- a/hw/audio/wm8750.c +++ b/hw/audio/wm8750.c @@ -710,7 +710,7 @@ static const Property wm8750_properties[] = { DEFINE_AUDIO_PROPERTIES(WM8750State, card), }; -static void wm8750_class_init(ObjectClass *klass, void *data) +static void wm8750_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c index 48ef478..e166ca1 100644 --- a/hw/avr/arduino.c +++ b/hw/avr/arduino.c @@ -56,7 +56,7 @@ static void arduino_machine_init(MachineState *machine) } } -static void arduino_machine_class_init(ObjectClass *oc, void *data) +static void arduino_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -69,7 +69,7 @@ static void arduino_machine_class_init(ObjectClass *oc, void *data) mc->no_parallel = 1; } -static void arduino_duemilanove_class_init(ObjectClass *oc, void *data) +static void arduino_duemilanove_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); @@ -84,7 +84,7 @@ static void arduino_duemilanove_class_init(ObjectClass *oc, void *data) amc->xtal_hz = 16 * 1000 * 1000; }; -static void arduino_uno_class_init(ObjectClass *oc, void *data) +static void arduino_uno_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); @@ -99,7 +99,7 @@ static void arduino_uno_class_init(ObjectClass *oc, void *data) amc->xtal_hz = 16 * 1000 * 1000; }; -static void arduino_mega_class_init(ObjectClass *oc, void *data) +static void arduino_mega_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); @@ -114,7 +114,7 @@ static void arduino_mega_class_init(ObjectClass *oc, void *data) amc->xtal_hz = 16 * 1000 * 1000; }; -static void arduino_mega2560_class_init(ObjectClass *oc, void *data) +static void arduino_mega2560_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc); diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c index 11fab184..95b6da5 100644 --- a/hw/avr/atmega.c +++ b/hw/avr/atmega.c @@ -12,8 +12,9 @@ #include "qemu/module.h" #include "qemu/units.h" #include "qapi/error.h" -#include "exec/memory.h" -#include "exec/address-spaces.h" +#include "exec/target_page.h" +#include "system/memory.h" +#include "system/address-spaces.h" #include "system/system.h" #include "hw/qdev-properties.h" #include "hw/sysbus.h" @@ -385,7 +386,7 @@ static const Property atmega_props[] = { xtal_freq_hz, 0), }; -static void atmega_class_init(ObjectClass *oc, void *data) +static void atmega_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -395,7 +396,7 @@ static void atmega_class_init(ObjectClass *oc, void *data) dc->user_creatable = false; } -static void atmega168_class_init(ObjectClass *oc, void *data) +static void atmega168_class_init(ObjectClass *oc, const void *data) { AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); @@ -410,7 +411,7 @@ static void atmega168_class_init(ObjectClass *oc, void *data) amc->dev = dev168_328; }; -static void atmega328_class_init(ObjectClass *oc, void *data) +static void atmega328_class_init(ObjectClass *oc, const void *data) { AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); @@ -425,7 +426,7 @@ static void atmega328_class_init(ObjectClass *oc, void *data) amc->dev = dev168_328; }; -static void atmega1280_class_init(ObjectClass *oc, void *data) +static void atmega1280_class_init(ObjectClass *oc, const void *data) { AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); @@ -440,7 +441,7 @@ static void atmega1280_class_init(ObjectClass *oc, void *data) amc->dev = dev1280_2560; }; -static void atmega2560_class_init(ObjectClass *oc, void *data) +static void atmega2560_class_init(ObjectClass *oc, const void *data) { AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc); diff --git a/hw/block/Kconfig b/hw/block/Kconfig index a898e04..737dbcd 100644 --- a/hw/block/Kconfig +++ b/hw/block/Kconfig @@ -13,9 +13,6 @@ config FDC_SYSBUS config SSI_M25P80 bool -config NAND - bool - config PFLASH_CFI01 bool diff --git a/hw/block/fdc-isa.c b/hw/block/fdc-isa.c index a10c24a..6d1790e 100644 --- a/hw/block/fdc-isa.c +++ b/hw/block/fdc-isa.c @@ -42,7 +42,7 @@ #include "system/block-backend.h" #include "system/blockdev.h" #include "system/system.h" -#include "exec/ioport.h" +#include "system/ioport.h" #include "qemu/log.h" #include "qemu/main-loop.h" #include "qemu/module.h" @@ -298,7 +298,7 @@ static const Property isa_fdc_properties[] = { FloppyDriveType), }; -static void isabus_fdc_class_init(ObjectClass *klass, void *data) +static void isabus_fdc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); @@ -331,7 +331,7 @@ static const TypeInfo isa_fdc_info = { .instance_size = sizeof(FDCtrlISABus), .class_init = isabus_fdc_class_init, .instance_init = isabus_fdc_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/block/fdc-sysbus.c b/hw/block/fdc-sysbus.c index 381b492..956860a 100644 --- a/hw/block/fdc-sysbus.c +++ b/hw/block/fdc-sysbus.c @@ -26,7 +26,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qom/object.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/sysbus.h" #include "hw/block/fdc.h" #include "migration/vmstate.h" @@ -176,7 +176,7 @@ static const VMStateDescription vmstate_sysbus_fdc = { } }; -static void sysbus_fdc_common_class_init(ObjectClass *klass, void *data) +static void sysbus_fdc_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -208,7 +208,7 @@ static const Property sysbus_fdc_properties[] = { FloppyDriveType), }; -static void sysbus_fdc_class_init(ObjectClass *klass, void *data) +static void sysbus_fdc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -231,7 +231,7 @@ static const Property sun4m_fdc_properties[] = { FloppyDriveType), }; -static void sun4m_fdc_class_init(ObjectClass *klass, void *data) +static void sun4m_fdc_class_init(ObjectClass *klass, const void *data) { FDCtrlSysBusClass *sbdc = SYSBUS_FDC_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 2df941d..d0f08c7 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -553,7 +553,7 @@ static void floppy_drive_realize(DeviceState *qdev, Error **errp) fd_revalidate(drive); } -static void floppy_drive_class_init(ObjectClass *klass, void *data) +static void floppy_drive_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->realize = floppy_drive_realize; diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index 0887c10..a5336d9 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -528,7 +528,7 @@ struct Flash { struct M25P80Class { SSIPeripheralClass parent_class; - FlashPartInfo *pi; + const FlashPartInfo *pi; }; OBJECT_DECLARE_TYPE(Flash, M25P80Class, M25P80) @@ -1857,7 +1857,7 @@ static const VMStateDescription vmstate_m25p80 = { } }; -static void m25p80_class_init(ObjectClass *klass, void *data) +static void m25p80_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass); @@ -1893,7 +1893,7 @@ static void m25p80_register_types(void) .name = known_devices[i].part_name, .parent = TYPE_M25P80, .class_init = m25p80_class_init, - .class_data = (void *)&known_devices[i], + .class_data = &known_devices[i], }; type_register_static(&ti); } diff --git a/hw/block/meson.build b/hw/block/meson.build index 16a51bf..6557044 100644 --- a/hw/block/meson.build +++ b/hw/block/meson.build @@ -6,7 +6,6 @@ system_ss.add(files( system_ss.add(when: 'CONFIG_FDC', if_true: files('fdc.c')) system_ss.add(when: 'CONFIG_FDC_ISA', if_true: files('fdc-isa.c')) system_ss.add(when: 'CONFIG_FDC_SYSBUS', if_true: files('fdc-sysbus.c')) -system_ss.add(when: 'CONFIG_NAND', if_true: files('nand.c')) system_ss.add(when: 'CONFIG_PFLASH_CFI01', if_true: files('pflash_cfi01.c')) system_ss.add(when: 'CONFIG_PFLASH_CFI02', if_true: files('pflash_cfi02.c')) system_ss.add(when: 'CONFIG_SSI_M25P80', if_true: files('m25p80.c')) diff --git a/hw/block/nand.c b/hw/block/nand.c deleted file mode 100644 index e98c55b..0000000 --- a/hw/block/nand.c +++ /dev/null @@ -1,835 +0,0 @@ -/* - * Flash NAND memory emulation. Based on "16M x 8 Bit NAND Flash - * Memory" datasheet for the KM29U128AT / K9F2808U0A chips from - * Samsung Electronic. - * - * Copyright (c) 2006 Openedhand Ltd. - * Written by Andrzej Zaborowski <balrog@zabor.org> - * - * Support for additional features based on "MT29F2G16ABCWP 2Gx16" - * datasheet from Micron Technology and "NAND02G-B2C" datasheet - * from ST Microelectronics. - * - * This code is licensed under the GNU GPL v2. - * - * Contributions after 2012-01-13 are licensed under the terms of the - * GNU GPL, version 2 or (at your option) any later version. - */ - -#ifndef NAND_IO - -#include "qemu/osdep.h" -#include "hw/hw.h" -#include "hw/qdev-properties.h" -#include "hw/qdev-properties-system.h" -#include "hw/block/flash.h" -#include "system/block-backend.h" -#include "migration/vmstate.h" -#include "qapi/error.h" -#include "qemu/error-report.h" -#include "qemu/module.h" -#include "qom/object.h" - -# define NAND_CMD_READ0 0x00 -# define NAND_CMD_READ1 0x01 -# define NAND_CMD_READ2 0x50 -# define NAND_CMD_LPREAD2 0x30 -# define NAND_CMD_NOSERIALREAD2 0x35 -# define NAND_CMD_RANDOMREAD1 0x05 -# define NAND_CMD_RANDOMREAD2 0xe0 -# define NAND_CMD_READID 0x90 -# define NAND_CMD_RESET 0xff -# define NAND_CMD_PAGEPROGRAM1 0x80 -# define NAND_CMD_PAGEPROGRAM2 0x10 -# define NAND_CMD_CACHEPROGRAM2 0x15 -# define NAND_CMD_BLOCKERASE1 0x60 -# define NAND_CMD_BLOCKERASE2 0xd0 -# define NAND_CMD_READSTATUS 0x70 -# define NAND_CMD_COPYBACKPRG1 0x85 - -# define NAND_IOSTATUS_ERROR (1 << 0) -# define NAND_IOSTATUS_PLANE0 (1 << 1) -# define NAND_IOSTATUS_PLANE1 (1 << 2) -# define NAND_IOSTATUS_PLANE2 (1 << 3) -# define NAND_IOSTATUS_PLANE3 (1 << 4) -# define NAND_IOSTATUS_READY (1 << 6) -# define NAND_IOSTATUS_UNPROTCT (1 << 7) - -# define MAX_PAGE 0x800 -# define MAX_OOB 0x40 - -typedef struct NANDFlashState NANDFlashState; -struct NANDFlashState { - DeviceState parent_obj; - - uint8_t manf_id, chip_id; - uint8_t buswidth; /* in BYTES */ - int size, pages; - int page_shift, oob_shift, erase_shift, addr_shift; - uint8_t *storage; - BlockBackend *blk; - int mem_oob; - - uint8_t cle, ale, ce, wp, gnd; - - uint8_t io[MAX_PAGE + MAX_OOB + 0x400]; - uint8_t *ioaddr; - int iolen; - - uint32_t cmd; - uint64_t addr; - int addrlen; - int status; - int offset; - - void (*blk_write)(NANDFlashState *s); - void (*blk_erase)(NANDFlashState *s); - /* - * Returns %true when block containing (@addr + @offset) is - * successfully loaded, otherwise %false. - */ - bool (*blk_load)(NANDFlashState *s, uint64_t addr, unsigned offset); - - uint32_t ioaddr_vmstate; -}; - -#define TYPE_NAND "nand" - -OBJECT_DECLARE_SIMPLE_TYPE(NANDFlashState, NAND) - -static void mem_and(uint8_t *dest, const uint8_t *src, size_t n) -{ - /* Like memcpy() but we logical-AND the data into the destination */ - int i; - for (i = 0; i < n; i++) { - dest[i] &= src[i]; - } -} - -# define NAND_NO_AUTOINCR 0x00000001 -# define NAND_BUSWIDTH_16 0x00000002 -# define NAND_NO_PADDING 0x00000004 -# define NAND_CACHEPRG 0x00000008 -# define NAND_COPYBACK 0x00000010 -# define NAND_IS_AND 0x00000020 -# define NAND_4PAGE_ARRAY 0x00000040 -# define NAND_NO_READRDY 0x00000100 -# define NAND_SAMSUNG_LP (NAND_NO_PADDING | NAND_COPYBACK) - -# define NAND_IO - -# define PAGE(addr) ((addr) >> ADDR_SHIFT) -# define PAGE_START(page) (PAGE(page) * (NAND_PAGE_SIZE + OOB_SIZE)) -# define PAGE_MASK ((1 << ADDR_SHIFT) - 1) -# define OOB_SHIFT (PAGE_SHIFT - 5) -# define OOB_SIZE (1 << OOB_SHIFT) -# define SECTOR(addr) ((addr) >> (9 + ADDR_SHIFT - PAGE_SHIFT)) -# define SECTOR_OFFSET(addr) ((addr) & ((511 >> PAGE_SHIFT) << 8)) - -# define NAND_PAGE_SIZE 256 -# define PAGE_SHIFT 8 -# define PAGE_SECTORS 1 -# define ADDR_SHIFT 8 -# include "nand.c" -# define NAND_PAGE_SIZE 512 -# define PAGE_SHIFT 9 -# define PAGE_SECTORS 1 -# define ADDR_SHIFT 8 -# include "nand.c" -# define NAND_PAGE_SIZE 2048 -# define PAGE_SHIFT 11 -# define PAGE_SECTORS 4 -# define ADDR_SHIFT 16 -# include "nand.c" - -/* Information based on Linux drivers/mtd/nand/raw/nand_ids.c */ -static const struct { - int size; - int width; - int page_shift; - int erase_shift; - uint32_t options; -} nand_flash_ids[0x100] = { - [0 ... 0xff] = { 0 }, - - [0x6b] = { 4, 8, 9, 4, 0 }, - [0xe3] = { 4, 8, 9, 4, 0 }, - [0xe5] = { 4, 8, 9, 4, 0 }, - [0xd6] = { 8, 8, 9, 4, 0 }, - [0xe6] = { 8, 8, 9, 4, 0 }, - - [0x33] = { 16, 8, 9, 5, 0 }, - [0x73] = { 16, 8, 9, 5, 0 }, - [0x43] = { 16, 16, 9, 5, NAND_BUSWIDTH_16 }, - [0x53] = { 16, 16, 9, 5, NAND_BUSWIDTH_16 }, - - [0x35] = { 32, 8, 9, 5, 0 }, - [0x75] = { 32, 8, 9, 5, 0 }, - [0x45] = { 32, 16, 9, 5, NAND_BUSWIDTH_16 }, - [0x55] = { 32, 16, 9, 5, NAND_BUSWIDTH_16 }, - - [0x36] = { 64, 8, 9, 5, 0 }, - [0x76] = { 64, 8, 9, 5, 0 }, - [0x46] = { 64, 16, 9, 5, NAND_BUSWIDTH_16 }, - [0x56] = { 64, 16, 9, 5, NAND_BUSWIDTH_16 }, - - [0x78] = { 128, 8, 9, 5, 0 }, - [0x39] = { 128, 8, 9, 5, 0 }, - [0x79] = { 128, 8, 9, 5, 0 }, - [0x72] = { 128, 16, 9, 5, NAND_BUSWIDTH_16 }, - [0x49] = { 128, 16, 9, 5, NAND_BUSWIDTH_16 }, - [0x74] = { 128, 16, 9, 5, NAND_BUSWIDTH_16 }, - [0x59] = { 128, 16, 9, 5, NAND_BUSWIDTH_16 }, - - [0x71] = { 256, 8, 9, 5, 0 }, - - /* - * These are the new chips with large page size. The pagesize and the - * erasesize is determined from the extended id bytes - */ -# define LP_OPTIONS (NAND_SAMSUNG_LP | NAND_NO_READRDY | NAND_NO_AUTOINCR) -# define LP_OPTIONS16 (LP_OPTIONS | NAND_BUSWIDTH_16) - - /* 512 Megabit */ - [0xa2] = { 64, 8, 0, 0, LP_OPTIONS }, - [0xf2] = { 64, 8, 0, 0, LP_OPTIONS }, - [0xb2] = { 64, 16, 0, 0, LP_OPTIONS16 }, - [0xc2] = { 64, 16, 0, 0, LP_OPTIONS16 }, - - /* 1 Gigabit */ - [0xa1] = { 128, 8, 0, 0, LP_OPTIONS }, - [0xf1] = { 128, 8, 0, 0, LP_OPTIONS }, - [0xb1] = { 128, 16, 0, 0, LP_OPTIONS16 }, - [0xc1] = { 128, 16, 0, 0, LP_OPTIONS16 }, - - /* 2 Gigabit */ - [0xaa] = { 256, 8, 0, 0, LP_OPTIONS }, - [0xda] = { 256, 8, 0, 0, LP_OPTIONS }, - [0xba] = { 256, 16, 0, 0, LP_OPTIONS16 }, - [0xca] = { 256, 16, 0, 0, LP_OPTIONS16 }, - - /* 4 Gigabit */ - [0xac] = { 512, 8, 0, 0, LP_OPTIONS }, - [0xdc] = { 512, 8, 0, 0, LP_OPTIONS }, - [0xbc] = { 512, 16, 0, 0, LP_OPTIONS16 }, - [0xcc] = { 512, 16, 0, 0, LP_OPTIONS16 }, - - /* 8 Gigabit */ - [0xa3] = { 1024, 8, 0, 0, LP_OPTIONS }, - [0xd3] = { 1024, 8, 0, 0, LP_OPTIONS }, - [0xb3] = { 1024, 16, 0, 0, LP_OPTIONS16 }, - [0xc3] = { 1024, 16, 0, 0, LP_OPTIONS16 }, - - /* 16 Gigabit */ - [0xa5] = { 2048, 8, 0, 0, LP_OPTIONS }, - [0xd5] = { 2048, 8, 0, 0, LP_OPTIONS }, - [0xb5] = { 2048, 16, 0, 0, LP_OPTIONS16 }, - [0xc5] = { 2048, 16, 0, 0, LP_OPTIONS16 }, -}; - -static void nand_reset(DeviceState *dev) -{ - NANDFlashState *s = NAND(dev); - s->cmd = NAND_CMD_READ0; - s->addr = 0; - s->addrlen = 0; - s->iolen = 0; - s->offset = 0; - s->status &= NAND_IOSTATUS_UNPROTCT; - s->status |= NAND_IOSTATUS_READY; -} - -static inline void nand_pushio_byte(NANDFlashState *s, uint8_t value) -{ - s->ioaddr[s->iolen++] = value; - for (value = s->buswidth; --value;) { - s->ioaddr[s->iolen++] = 0; - } -} - -/* - * nand_load_block: Load block containing (s->addr + @offset). - * Returns length of data available at @offset in this block. - */ -static unsigned nand_load_block(NANDFlashState *s, unsigned offset) -{ - unsigned iolen; - - if (!s->blk_load(s, s->addr, offset)) { - return 0; - } - - iolen = (1 << s->page_shift); - if (s->gnd) { - iolen += 1 << s->oob_shift; - } - assert(offset <= iolen); - iolen -= offset; - - return iolen; -} - -static void nand_command(NANDFlashState *s) -{ - switch (s->cmd) { - case NAND_CMD_READ0: - s->iolen = 0; - break; - - case NAND_CMD_READID: - s->ioaddr = s->io; - s->iolen = 0; - nand_pushio_byte(s, s->manf_id); - nand_pushio_byte(s, s->chip_id); - nand_pushio_byte(s, 'Q'); /* Don't-care byte (often 0xa5) */ - if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { - /* Page Size, Block Size, Spare Size; bit 6 indicates - * 8 vs 16 bit width NAND. - */ - nand_pushio_byte(s, (s->buswidth == 2) ? 0x55 : 0x15); - } else { - nand_pushio_byte(s, 0xc0); /* Multi-plane */ - } - break; - - case NAND_CMD_RANDOMREAD2: - case NAND_CMD_NOSERIALREAD2: - if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP)) - break; - s->iolen = nand_load_block(s, s->addr & ((1 << s->addr_shift) - 1)); - break; - - case NAND_CMD_RESET: - nand_reset(DEVICE(s)); - break; - - case NAND_CMD_PAGEPROGRAM1: - s->ioaddr = s->io; - s->iolen = 0; - break; - - case NAND_CMD_PAGEPROGRAM2: - if (s->wp) { - s->blk_write(s); - } - break; - - case NAND_CMD_BLOCKERASE1: - break; - - case NAND_CMD_BLOCKERASE2: - s->addr &= (1ull << s->addrlen * 8) - 1; - s->addr <<= nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP ? - 16 : 8; - - if (s->wp) { - s->blk_erase(s); - } - break; - - case NAND_CMD_READSTATUS: - s->ioaddr = s->io; - s->iolen = 0; - nand_pushio_byte(s, s->status); - break; - - default: - printf("%s: Unknown NAND command 0x%02x\n", __func__, s->cmd); - } -} - -static int nand_pre_save(void *opaque) -{ - NANDFlashState *s = NAND(opaque); - - s->ioaddr_vmstate = s->ioaddr - s->io; - - return 0; -} - -static int nand_post_load(void *opaque, int version_id) -{ - NANDFlashState *s = NAND(opaque); - - if (s->ioaddr_vmstate > sizeof(s->io)) { - return -EINVAL; - } - s->ioaddr = s->io + s->ioaddr_vmstate; - - return 0; -} - -static const VMStateDescription vmstate_nand = { - .name = "nand", - .version_id = 1, - .minimum_version_id = 1, - .pre_save = nand_pre_save, - .post_load = nand_post_load, - .fields = (const VMStateField[]) { - VMSTATE_UINT8(cle, NANDFlashState), - VMSTATE_UINT8(ale, NANDFlashState), - VMSTATE_UINT8(ce, NANDFlashState), - VMSTATE_UINT8(wp, NANDFlashState), - VMSTATE_UINT8(gnd, NANDFlashState), - VMSTATE_BUFFER(io, NANDFlashState), - VMSTATE_UINT32(ioaddr_vmstate, NANDFlashState), - VMSTATE_INT32(iolen, NANDFlashState), - VMSTATE_UINT32(cmd, NANDFlashState), - VMSTATE_UINT64(addr, NANDFlashState), - VMSTATE_INT32(addrlen, NANDFlashState), - VMSTATE_INT32(status, NANDFlashState), - VMSTATE_INT32(offset, NANDFlashState), - /* XXX: do we want to save s->storage too? */ - VMSTATE_END_OF_LIST() - } -}; - -static void nand_realize(DeviceState *dev, Error **errp) -{ - int pagesize; - NANDFlashState *s = NAND(dev); - int ret; - - - s->buswidth = nand_flash_ids[s->chip_id].width >> 3; - s->size = nand_flash_ids[s->chip_id].size << 20; - if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { - s->page_shift = 11; - s->erase_shift = 6; - } else { - s->page_shift = nand_flash_ids[s->chip_id].page_shift; - s->erase_shift = nand_flash_ids[s->chip_id].erase_shift; - } - - switch (1 << s->page_shift) { - case 256: - nand_init_256(s); - break; - case 512: - nand_init_512(s); - break; - case 2048: - nand_init_2048(s); - break; - default: - error_setg(errp, "Unsupported NAND block size %#x", - 1 << s->page_shift); - return; - } - - pagesize = 1 << s->oob_shift; - s->mem_oob = 1; - if (s->blk) { - if (!blk_supports_write_perm(s->blk)) { - error_setg(errp, "Can't use a read-only drive"); - return; - } - ret = blk_set_perm(s->blk, BLK_PERM_CONSISTENT_READ | BLK_PERM_WRITE, - BLK_PERM_ALL, errp); - if (ret < 0) { - return; - } - if (blk_getlength(s->blk) >= - (s->pages << s->page_shift) + (s->pages << s->oob_shift)) { - pagesize = 0; - s->mem_oob = 0; - } - } else { - pagesize += 1 << s->page_shift; - } - if (pagesize) { - s->storage = (uint8_t *) memset(g_malloc(s->pages * pagesize), - 0xff, s->pages * pagesize); - } - /* Give s->ioaddr a sane value in case we save state before it is used. */ - s->ioaddr = s->io; -} - -static const Property nand_properties[] = { - DEFINE_PROP_UINT8("manufacturer_id", NANDFlashState, manf_id, 0), - DEFINE_PROP_UINT8("chip_id", NANDFlashState, chip_id, 0), - DEFINE_PROP_DRIVE("drive", NANDFlashState, blk), -}; - -static void nand_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - - dc->realize = nand_realize; - device_class_set_legacy_reset(dc, nand_reset); - dc->vmsd = &vmstate_nand; - device_class_set_props(dc, nand_properties); - set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); -} - -static const TypeInfo nand_info = { - .name = TYPE_NAND, - .parent = TYPE_DEVICE, - .instance_size = sizeof(NANDFlashState), - .class_init = nand_class_init, -}; - -static void nand_register_types(void) -{ - type_register_static(&nand_info); -} - -/* - * Chip inputs are CLE, ALE, CE, WP, GND and eight I/O pins. Chip - * outputs are R/B and eight I/O pins. - * - * CE, WP and R/B are active low. - */ -void nand_setpins(DeviceState *dev, uint8_t cle, uint8_t ale, - uint8_t ce, uint8_t wp, uint8_t gnd) -{ - NANDFlashState *s = NAND(dev); - - s->cle = cle; - s->ale = ale; - s->ce = ce; - s->wp = wp; - s->gnd = gnd; - if (wp) { - s->status |= NAND_IOSTATUS_UNPROTCT; - } else { - s->status &= ~NAND_IOSTATUS_UNPROTCT; - } -} - -void nand_getpins(DeviceState *dev, int *rb) -{ - *rb = 1; -} - -void nand_setio(DeviceState *dev, uint32_t value) -{ - int i; - NANDFlashState *s = NAND(dev); - - if (!s->ce && s->cle) { - if (nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) { - if (s->cmd == NAND_CMD_READ0 && value == NAND_CMD_LPREAD2) - return; - if (value == NAND_CMD_RANDOMREAD1) { - s->addr &= ~((1 << s->addr_shift) - 1); - s->addrlen = 0; - return; - } - } - if (value == NAND_CMD_READ0) { - s->offset = 0; - } else if (value == NAND_CMD_READ1) { - s->offset = 0x100; - value = NAND_CMD_READ0; - } else if (value == NAND_CMD_READ2) { - s->offset = 1 << s->page_shift; - value = NAND_CMD_READ0; - } - - s->cmd = value; - - if (s->cmd == NAND_CMD_READSTATUS || - s->cmd == NAND_CMD_PAGEPROGRAM2 || - s->cmd == NAND_CMD_BLOCKERASE1 || - s->cmd == NAND_CMD_BLOCKERASE2 || - s->cmd == NAND_CMD_NOSERIALREAD2 || - s->cmd == NAND_CMD_RANDOMREAD2 || - s->cmd == NAND_CMD_RESET) { - nand_command(s); - } - - if (s->cmd != NAND_CMD_RANDOMREAD2) { - s->addrlen = 0; - } - } - - if (s->ale) { - unsigned int shift = s->addrlen * 8; - uint64_t mask = ~(0xffull << shift); - uint64_t v = (uint64_t)value << shift; - - s->addr = (s->addr & mask) | v; - s->addrlen ++; - - switch (s->addrlen) { - case 1: - if (s->cmd == NAND_CMD_READID) { - nand_command(s); - } - break; - case 2: /* fix cache address as a byte address */ - s->addr <<= (s->buswidth - 1); - break; - case 3: - if (!(nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && - (s->cmd == NAND_CMD_READ0 || - s->cmd == NAND_CMD_PAGEPROGRAM1)) { - nand_command(s); - } - break; - case 4: - if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && - nand_flash_ids[s->chip_id].size < 256 && /* 1Gb or less */ - (s->cmd == NAND_CMD_READ0 || - s->cmd == NAND_CMD_PAGEPROGRAM1)) { - nand_command(s); - } - break; - case 5: - if ((nand_flash_ids[s->chip_id].options & NAND_SAMSUNG_LP) && - nand_flash_ids[s->chip_id].size >= 256 && /* 2Gb or more */ - (s->cmd == NAND_CMD_READ0 || - s->cmd == NAND_CMD_PAGEPROGRAM1)) { - nand_command(s); - } - break; - default: - break; - } - } - - if (!s->cle && !s->ale && s->cmd == NAND_CMD_PAGEPROGRAM1) { - if (s->iolen < (1 << s->page_shift) + (1 << s->oob_shift)) { - for (i = s->buswidth; i--; value >>= 8) { - s->io[s->iolen ++] = (uint8_t) (value & 0xff); - } - } - } else if (!s->cle && !s->ale && s->cmd == NAND_CMD_COPYBACKPRG1) { - if ((s->addr & ((1 << s->addr_shift) - 1)) < - (1 << s->page_shift) + (1 << s->oob_shift)) { - for (i = s->buswidth; i--; s->addr++, value >>= 8) { - s->io[s->iolen + (s->addr & ((1 << s->addr_shift) - 1))] = - (uint8_t) (value & 0xff); - } - } - } -} - -uint32_t nand_getio(DeviceState *dev) -{ - int offset; - uint32_t x = 0; - NANDFlashState *s = NAND(dev); - - /* Allow sequential reading */ - if (!s->iolen && s->cmd == NAND_CMD_READ0) { - offset = (int) (s->addr & ((1 << s->addr_shift) - 1)) + s->offset; - s->offset = 0; - s->iolen = nand_load_block(s, offset); - } - - if (s->ce || s->iolen <= 0) { - return 0; - } - - for (offset = s->buswidth; offset--;) { - x |= s->ioaddr[offset] << (offset << 3); - } - /* after receiving READ STATUS command all subsequent reads will - * return the status register value until another command is issued - */ - if (s->cmd != NAND_CMD_READSTATUS) { - s->addr += s->buswidth; - s->ioaddr += s->buswidth; - s->iolen -= s->buswidth; - } - return x; -} - -uint32_t nand_getbuswidth(DeviceState *dev) -{ - NANDFlashState *s = (NANDFlashState *) dev; - return s->buswidth << 3; -} - -DeviceState *nand_init(BlockBackend *blk, int manf_id, int chip_id) -{ - DeviceState *dev; - - if (nand_flash_ids[chip_id].size == 0) { - hw_error("%s: Unsupported NAND chip ID.\n", __func__); - } - dev = qdev_new(TYPE_NAND); - qdev_prop_set_uint8(dev, "manufacturer_id", manf_id); - qdev_prop_set_uint8(dev, "chip_id", chip_id); - if (blk) { - qdev_prop_set_drive_err(dev, "drive", blk, &error_fatal); - } - - qdev_realize(dev, NULL, &error_fatal); - return dev; -} - -type_init(nand_register_types) - -#else - -/* Program a single page */ -static void glue(nand_blk_write_, NAND_PAGE_SIZE)(NANDFlashState *s) -{ - uint64_t off, page, sector, soff; - uint8_t iobuf[(PAGE_SECTORS + 2) * 0x200]; - if (PAGE(s->addr) >= s->pages) - return; - - if (!s->blk) { - mem_and(s->storage + PAGE_START(s->addr) + (s->addr & PAGE_MASK) + - s->offset, s->io, s->iolen); - } else if (s->mem_oob) { - sector = SECTOR(s->addr); - off = (s->addr & PAGE_MASK) + s->offset; - soff = SECTOR_OFFSET(s->addr); - if (blk_pread(s->blk, sector << BDRV_SECTOR_BITS, - PAGE_SECTORS << BDRV_SECTOR_BITS, iobuf, 0) < 0) { - printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); - return; - } - - mem_and(iobuf + (soff | off), s->io, MIN(s->iolen, NAND_PAGE_SIZE - off)); - if (off + s->iolen > NAND_PAGE_SIZE) { - page = PAGE(s->addr); - mem_and(s->storage + (page << OOB_SHIFT), s->io + NAND_PAGE_SIZE - off, - MIN(OOB_SIZE, off + s->iolen - NAND_PAGE_SIZE)); - } - - if (blk_pwrite(s->blk, sector << BDRV_SECTOR_BITS, - PAGE_SECTORS << BDRV_SECTOR_BITS, iobuf, 0) < 0) { - printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); - } - } else { - off = PAGE_START(s->addr) + (s->addr & PAGE_MASK) + s->offset; - sector = off >> 9; - soff = off & 0x1ff; - if (blk_pread(s->blk, sector << BDRV_SECTOR_BITS, - (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS, iobuf, 0) < 0) { - printf("%s: read error in sector %" PRIu64 "\n", __func__, sector); - return; - } - - mem_and(iobuf + soff, s->io, s->iolen); - - if (blk_pwrite(s->blk, sector << BDRV_SECTOR_BITS, - (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS, iobuf, 0) < 0) { - printf("%s: write error in sector %" PRIu64 "\n", __func__, sector); - } - } - s->offset = 0; -} - -/* Erase a single block */ -static void glue(nand_blk_erase_, NAND_PAGE_SIZE)(NANDFlashState *s) -{ - uint64_t i, page, addr; - uint8_t iobuf[0x200] = { [0 ... 0x1ff] = 0xff, }; - addr = s->addr & ~((1 << (ADDR_SHIFT + s->erase_shift)) - 1); - - if (PAGE(addr) >= s->pages) { - return; - } - - if (!s->blk) { - memset(s->storage + PAGE_START(addr), - 0xff, (NAND_PAGE_SIZE + OOB_SIZE) << s->erase_shift); - } else if (s->mem_oob) { - memset(s->storage + (PAGE(addr) << OOB_SHIFT), - 0xff, OOB_SIZE << s->erase_shift); - i = SECTOR(addr); - page = SECTOR(addr + (1 << (ADDR_SHIFT + s->erase_shift))); - for (; i < page; i ++) - if (blk_pwrite(s->blk, i << BDRV_SECTOR_BITS, - BDRV_SECTOR_SIZE, iobuf, 0) < 0) { - printf("%s: write error in sector %" PRIu64 "\n", __func__, i); - } - } else { - addr = PAGE_START(addr); - page = addr >> 9; - if (blk_pread(s->blk, page << BDRV_SECTOR_BITS, - BDRV_SECTOR_SIZE, iobuf, 0) < 0) { - printf("%s: read error in sector %" PRIu64 "\n", __func__, page); - } - memset(iobuf + (addr & 0x1ff), 0xff, (~addr & 0x1ff) + 1); - if (blk_pwrite(s->blk, page << BDRV_SECTOR_BITS, - BDRV_SECTOR_SIZE, iobuf, 0) < 0) { - printf("%s: write error in sector %" PRIu64 "\n", __func__, page); - } - - memset(iobuf, 0xff, 0x200); - i = (addr & ~0x1ff) + 0x200; - for (addr += ((NAND_PAGE_SIZE + OOB_SIZE) << s->erase_shift) - 0x200; - i < addr; i += 0x200) { - if (blk_pwrite(s->blk, i, BDRV_SECTOR_SIZE, iobuf, 0) < 0) { - printf("%s: write error in sector %" PRIu64 "\n", - __func__, i >> 9); - } - } - - page = i >> 9; - if (blk_pread(s->blk, page << BDRV_SECTOR_BITS, - BDRV_SECTOR_SIZE, iobuf, 0) < 0) { - printf("%s: read error in sector %" PRIu64 "\n", __func__, page); - } - memset(iobuf, 0xff, ((addr - 1) & 0x1ff) + 1); - if (blk_pwrite(s->blk, page << BDRV_SECTOR_BITS, - BDRV_SECTOR_SIZE, iobuf, 0) < 0) { - printf("%s: write error in sector %" PRIu64 "\n", __func__, page); - } - } -} - -static bool glue(nand_blk_load_, NAND_PAGE_SIZE)(NANDFlashState *s, - uint64_t addr, unsigned offset) -{ - if (PAGE(addr) >= s->pages) { - return false; - } - - if (offset > NAND_PAGE_SIZE + OOB_SIZE) { - return false; - } - - if (s->blk) { - if (s->mem_oob) { - if (blk_pread(s->blk, SECTOR(addr) << BDRV_SECTOR_BITS, - PAGE_SECTORS << BDRV_SECTOR_BITS, s->io, 0) < 0) { - printf("%s: read error in sector %" PRIu64 "\n", - __func__, SECTOR(addr)); - } - memcpy(s->io + SECTOR_OFFSET(s->addr) + NAND_PAGE_SIZE, - s->storage + (PAGE(s->addr) << OOB_SHIFT), - OOB_SIZE); - s->ioaddr = s->io + SECTOR_OFFSET(s->addr) + offset; - } else { - if (blk_pread(s->blk, PAGE_START(addr), - (PAGE_SECTORS + 2) << BDRV_SECTOR_BITS, s->io, 0) - < 0) { - printf("%s: read error in sector %" PRIu64 "\n", - __func__, PAGE_START(addr) >> 9); - } - s->ioaddr = s->io + (PAGE_START(addr) & 0x1ff) + offset; - } - } else { - memcpy(s->io, s->storage + PAGE_START(s->addr) + - offset, NAND_PAGE_SIZE + OOB_SIZE - offset); - s->ioaddr = s->io; - } - - return true; -} - -static void glue(nand_init_, NAND_PAGE_SIZE)(NANDFlashState *s) -{ - s->oob_shift = PAGE_SHIFT - 5; - s->pages = s->size >> PAGE_SHIFT; - s->addr_shift = ADDR_SHIFT; - - s->blk_erase = glue(nand_blk_erase_, NAND_PAGE_SIZE); - s->blk_write = glue(nand_blk_write_, NAND_PAGE_SIZE); - s->blk_load = glue(nand_blk_load_, NAND_PAGE_SIZE); -} - -# undef NAND_PAGE_SIZE -# undef PAGE_SHIFT -# undef PAGE_SECTORS -# undef ADDR_SHIFT -#endif /* NAND_IO */ diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c index b5ea927..168101d 100644 --- a/hw/block/pflash_cfi01.c +++ b/hw/block/pflash_cfi01.c @@ -934,7 +934,7 @@ static const Property pflash_cfi01_properties[] = { old_multiple_chip_handling, false), }; -static void pflash_cfi01_class_init(ObjectClass *klass, void *data) +static void pflash_cfi01_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c index 315a536..3244b69 100644 --- a/hw/block/pflash_cfi02.c +++ b/hw/block/pflash_cfi02.c @@ -968,7 +968,7 @@ static void pflash_cfi02_unrealize(DeviceState *dev) g_free(pfl->sector_erase_map); } -static void pflash_cfi02_class_init(ObjectClass *klass, void *data) +static void pflash_cfi02_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/block/swim.c b/hw/block/swim.c index 4645468..ad04736 100644 --- a/hw/block/swim.c +++ b/hw/block/swim.c @@ -253,7 +253,7 @@ static void swim_drive_realize(DeviceState *qdev, Error **errp) blk_set_dev_ops(drive->blk, &swim_block_ops, drive); } -static void swim_drive_class_init(ObjectClass *klass, void *data) +static void swim_drive_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->realize = swim_drive_realize; @@ -550,7 +550,7 @@ static const VMStateDescription vmstate_sysbus_swim = { } }; -static void sysbus_swim_class_init(ObjectClass *oc, void *data) +static void sysbus_swim_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/block/vhost-user-blk.c b/hw/block/vhost-user-blk.c index ae42327..0eebbcd 100644 --- a/hw/block/vhost-user-blk.c +++ b/hw/block/vhost-user-blk.c @@ -204,7 +204,7 @@ err_host_notifiers: return ret; } -static void vhost_user_blk_stop(VirtIODevice *vdev) +static int vhost_user_blk_stop(VirtIODevice *vdev) { VHostUserBlk *s = VHOST_USER_BLK(vdev); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -212,26 +212,26 @@ static void vhost_user_blk_stop(VirtIODevice *vdev) int ret; if (!s->started_vu) { - return; + return 0; } s->started_vu = false; if (!k->set_guest_notifiers) { - return; + return 0; } - vhost_dev_stop(&s->dev, vdev, true); + ret = vhost_dev_stop(&s->dev, vdev, true); - ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } vhost_dev_disable_notifiers(&s->dev, vdev); + return ret; } -static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserBlk *s = VHOST_USER_BLK(vdev); bool should_start = virtio_device_should_start(vdev, status); @@ -239,11 +239,11 @@ static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) int ret; if (!s->connected) { - return; + return -1; } if (vhost_dev_is_started(&s->dev) == should_start) { - return; + return 0; } if (should_start) { @@ -253,9 +253,12 @@ static void vhost_user_blk_set_status(VirtIODevice *vdev, uint8_t status) qemu_chr_fe_disconnect(&s->chardev); } } else { - vhost_user_blk_stop(vdev); + ret = vhost_user_blk_stop(vdev); + if (ret < 0) { + return ret; + } } - + return 0; } static uint64_t vhost_user_blk_get_features(VirtIODevice *vdev, @@ -583,7 +586,7 @@ static const Property vhost_user_blk_properties[] = { VIRTIO_BLK_F_WRITE_ZEROES, true), }; -static void vhost_user_blk_class_init(ObjectClass *klass, void *data) +static void vhost_user_blk_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c index 5077793..9bab271 100644 --- a/hw/block/virtio-blk.c +++ b/hw/block/virtio-blk.c @@ -1270,7 +1270,7 @@ static uint64_t virtio_blk_get_features(VirtIODevice *vdev, uint64_t features, return features; } -static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) { VirtIOBlock *s = VIRTIO_BLK(vdev); @@ -1279,7 +1279,7 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) } if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { - return; + return 0; } /* A guest that supports VIRTIO_BLK_F_CONFIG_WCE must be able to send @@ -1302,6 +1302,7 @@ static void virtio_blk_set_status(VirtIODevice *vdev, uint8_t status) virtio_vdev_has_feature(vdev, VIRTIO_BLK_F_WCE)); } + return 0; } static void virtio_blk_save_device(VirtIODevice *vdev, QEMUFile *f) @@ -1802,7 +1803,7 @@ static void virtio_blk_device_realize(DeviceState *dev, Error **errp) * called after ->start_ioeventfd() has already set blk's AioContext. */ s->change = - qdev_add_vm_change_state_handler(dev, virtio_blk_dma_restart_cb, s); + qdev_add_vm_change_state_handler(dev, virtio_blk_dma_restart_cb, NULL, s); blk_ram_registrar_init(&s->blk_ram_registrar, s->blk); blk_set_dev_ops(s->blk, &virtio_block_ops, s); @@ -1886,7 +1887,7 @@ static const Property virtio_blk_properties[] = { conf.x_enable_wce_if_config_wce, true), }; -static void virtio_blk_class_init(ObjectClass *klass, void *data) +static void virtio_blk_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c index ec04102..74de897 100644 --- a/hw/block/xen-block.c +++ b/hw/block/xen-block.c @@ -679,7 +679,7 @@ static const Property xen_block_props[] = { TYPE_IOTHREAD, IOThread *), }; -static void xen_block_class_init(ObjectClass *class, void *data) +static void xen_block_class_init(ObjectClass *class, const void *data) { DeviceClass *dev_class = DEVICE_CLASS(class); XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class); @@ -724,7 +724,7 @@ static void xen_disk_realize(XenBlockDevice *blockdev, Error **errp) blockdev->info = blk_supports_write_perm(conf->blk) ? 0 : VDISK_READONLY; } -static void xen_disk_class_init(ObjectClass *class, void *data) +static void xen_disk_class_init(ObjectClass *class, const void *data) { DeviceClass *dev_class = DEVICE_CLASS(class); XenBlockDeviceClass *blockdev_class = XEN_BLOCK_DEVICE_CLASS(class); @@ -771,7 +771,7 @@ static void xen_cdrom_realize(XenBlockDevice *blockdev, Error **errp) blockdev->info = VDISK_READONLY | VDISK_CDROM; } -static void xen_cdrom_class_init(ObjectClass *class, void *data) +static void xen_cdrom_class_init(ObjectClass *class, const void *data) { DeviceClass *dev_class = DEVICE_CLASS(class); XenBlockDeviceClass *blockdev_class = XEN_BLOCK_DEVICE_CLASS(class); diff --git a/hw/char/avr_usart.c b/hw/char/avr_usart.c index e8012ca..fae1521 100644 --- a/hw/char/avr_usart.c +++ b/hw/char/avr_usart.c @@ -295,7 +295,7 @@ static void avr_usart_realize(DeviceState *dev, Error **errp) avr_usart_reset(dev); } -static void avr_usart_class_init(ObjectClass *klass, void *data) +static void avr_usart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c index 9b073fc..2b397f2 100644 --- a/hw/char/bcm2835_aux.c +++ b/hw/char/bcm2835_aux.c @@ -296,7 +296,7 @@ static const Property bcm2835_aux_props[] = { DEFINE_PROP_CHR("chardev", BCM2835AuxState, chr), }; -static void bcm2835_aux_class_init(ObjectClass *oc, void *data) +static void bcm2835_aux_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c index ebd846a..0dfa356 100644 --- a/hw/char/cadence_uart.c +++ b/hw/char/cadence_uart.c @@ -621,7 +621,7 @@ static const Property cadence_uart_properties[] = { DEFINE_PROP_CHR("chardev", CadenceUARTState, chr), }; -static void cadence_uart_class_init(ObjectClass *klass, void *data) +static void cadence_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/char/cmsdk-apb-uart.c b/hw/char/cmsdk-apb-uart.c index 0506500..32090f3 100644 --- a/hw/char/cmsdk-apb-uart.c +++ b/hw/char/cmsdk-apb-uart.c @@ -382,7 +382,7 @@ static const Property cmsdk_apb_uart_properties[] = { DEFINE_PROP_UINT32("pclk-frq", CMSDKAPBUART, pclk_frq, 0), }; -static void cmsdk_apb_uart_class_init(ObjectClass *klass, void *data) +static void cmsdk_apb_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/debugcon.c b/hw/char/debugcon.c index 1bc3bf8..bf44aaf 100644 --- a/hw/char/debugcon.c +++ b/hw/char/debugcon.c @@ -120,7 +120,7 @@ static const Property debugcon_isa_properties[] = { DEFINE_PROP_UINT32("readback", ISADebugconState, state.readback, 0xe9), }; -static void debugcon_isa_class_initfn(ObjectClass *klass, void *data) +static void debugcon_isa_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c index b0b0714..0f6af51 100644 --- a/hw/char/digic-uart.c +++ b/hw/char/digic-uart.c @@ -176,7 +176,7 @@ static const Property digic_uart_properties[] = { DEFINE_PROP_CHR("chardev", DigicUartState, chr), }; -static void digic_uart_class_init(ObjectClass *klass, void *data) +static void digic_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/diva-gsp.c b/hw/char/diva-gsp.c index ecec1f7..e1f0713 100644 --- a/hw/char/diva-gsp.c +++ b/hw/char/diva-gsp.c @@ -51,7 +51,6 @@ typedef struct PCIDivaSerialState { SerialState state[PCI_SERIAL_MAX_PORTS]; uint32_t level[PCI_SERIAL_MAX_PORTS]; qemu_irq *irqs; - uint8_t prog_if; bool disable; } PCIDivaSerialState; @@ -124,8 +123,8 @@ static void diva_pci_realize(PCIDevice *dev, Error **errp) size_t i, offset = 0; size_t portmask = di.omask; - pci->dev.config[PCI_CLASS_PROG] = pci->prog_if; - pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; + pci->dev.config[PCI_CLASS_PROG] = 2; /* 16550 compatible */ + pci->dev.config[PCI_INTERRUPT_PIN] = 1; memory_region_init(&pci->membar, OBJECT(pci), "serial_ports", 4096); pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &pci->membar); pci->irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci, di.nports); @@ -178,12 +177,11 @@ static const Property diva_serial_properties[] = { DEFINE_PROP_CHR("chardev2", PCIDivaSerialState, state[1].chr), DEFINE_PROP_CHR("chardev3", PCIDivaSerialState, state[2].chr), DEFINE_PROP_CHR("chardev4", PCIDivaSerialState, state[3].chr), - DEFINE_PROP_UINT8("prog_if", PCIDivaSerialState, prog_if, 0x02), DEFINE_PROP_UINT32("subvendor", PCIDivaSerialState, subvendor, PCI_DEVICE_ID_HP_DIVA_TOSCA1), }; -static void diva_serial_class_initfn(ObjectClass *klass, void *data) +static void diva_serial_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); @@ -242,7 +240,7 @@ static void diva_aux_exit(PCIDevice *dev) qemu_free_irq(pci->irq); } -static void diva_aux_class_initfn(ObjectClass *klass, void *data) +static void diva_aux_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); @@ -268,7 +266,7 @@ static const TypeInfo diva_aux_info = { .instance_size = sizeof(DivaAuxState), .instance_init = diva_aux_init, .class_init = diva_aux_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -282,7 +280,7 @@ static const TypeInfo diva_serial_pci_info = { .instance_size = sizeof(PCIDivaSerialState), .instance_init = diva_serial_init, .class_init = diva_serial_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/char/escc.c b/hw/char/escc.c index a5fdd8f..afe4ca4 100644 --- a/hw/char/escc.c +++ b/hw/char/escc.c @@ -1101,7 +1101,7 @@ static const Property escc_properties[] = { DEFINE_PROP_STRING("chnA-sunkbd-layout", ESCCState, chn[1].sunkbd_layout), }; -static void escc_class_init(ObjectClass *klass, void *data) +static void escc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/exynos4210_uart.c b/hw/char/exynos4210_uart.c index a1a9a12..6521b4c 100644 --- a/hw/char/exynos4210_uart.c +++ b/hw/char/exynos4210_uart.c @@ -711,7 +711,7 @@ static const Property exynos4210_uart_properties[] = { DEFINE_PROP_UINT32("tx-size", Exynos4210UartState, tx.size, 16), }; -static void exynos4210_uart_class_init(ObjectClass *klass, void *data) +static void exynos4210_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/goldfish_tty.c b/hw/char/goldfish_tty.c index 7374561..a37408a 100644 --- a/hw/char/goldfish_tty.c +++ b/hw/char/goldfish_tty.c @@ -15,7 +15,7 @@ #include "chardev/char-fe.h" #include "qemu/log.h" #include "trace.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/dma.h" #include "hw/char/goldfish_tty.h" @@ -256,7 +256,7 @@ static void goldfish_tty_instance_init(Object *obj) sysbus_init_irq(dev, &s->irq); } -static void goldfish_tty_class_init(ObjectClass *oc, void *data) +static void goldfish_tty_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/char/grlib_apbuart.c b/hw/char/grlib_apbuart.c index db6bcda..81c26e3 100644 --- a/hw/char/grlib_apbuart.c +++ b/hw/char/grlib_apbuart.c @@ -281,7 +281,7 @@ static const Property grlib_apbuart_properties[] = { DEFINE_PROP_CHR("chrdev", UART, chr), }; -static void grlib_apbuart_class_init(ObjectClass *klass, void *data) +static void grlib_apbuart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/ibex_uart.c b/hw/char/ibex_uart.c index 392375a..d6f0d18 100644 --- a/hw/char/ibex_uart.c +++ b/hw/char/ibex_uart.c @@ -542,7 +542,7 @@ static void ibex_uart_realize(DeviceState *dev, Error **errp) s, NULL, true); } -static void ibex_uart_class_init(ObjectClass *klass, void *data) +static void ibex_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c index 6f14f84..509b014 100644 --- a/hw/char/imx_serial.c +++ b/hw/char/imx_serial.c @@ -467,7 +467,7 @@ static const Property imx_serial_properties[] = { DEFINE_PROP_CHR("chardev", IMXSerialState, chr), }; -static void imx_serial_class_init(ObjectClass *klass, void *data) +static void imx_serial_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c index a287997..752c6c8 100644 --- a/hw/char/ipoctal232.c +++ b/hw/char/ipoctal232.c @@ -569,7 +569,7 @@ static const Property ipoctal_properties[] = { DEFINE_PROP_CHR("chardev7", IPOctalState, ch[7].dev), }; -static void ipoctal_class_init(ObjectClass *klass, void *data) +static void ipoctal_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IPackDeviceClass *ic = IPACK_DEVICE_CLASS(klass); diff --git a/hw/char/mcf_uart.c b/hw/char/mcf_uart.c index 529c26b..87bfcbe 100644 --- a/hw/char/mcf_uart.c +++ b/hw/char/mcf_uart.c @@ -322,7 +322,7 @@ static const Property mcf_uart_properties[] = { DEFINE_PROP_CHR("chardev", mcf_uart_state, chr), }; -static void mcf_uart_class_init(ObjectClass *oc, void *data) +static void mcf_uart_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/char/mchp_pfsoc_mmuart.c b/hw/char/mchp_pfsoc_mmuart.c index 3c3224c..6149f9d 100644 --- a/hw/char/mchp_pfsoc_mmuart.c +++ b/hw/char/mchp_pfsoc_mmuart.c @@ -121,7 +121,7 @@ static const VMStateDescription mchp_pfsoc_mmuart_vmstate = { } }; -static void mchp_pfsoc_mmuart_class_init(ObjectClass *oc, void *data) +static void mchp_pfsoc_mmuart_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/char/nrf51_uart.c b/hw/char/nrf51_uart.c index 82a61ee..41d4234 100644 --- a/hw/char/nrf51_uart.c +++ b/hw/char/nrf51_uart.c @@ -308,7 +308,7 @@ static const Property nrf51_uart_properties[] = { DEFINE_PROP_CHR("chardev", NRF51UARTState, chr), }; -static void nrf51_uart_class_init(ObjectClass *klass, void *data) +static void nrf51_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/omap_uart.c b/hw/char/omap_uart.c index 07fb868..8cbf6ce 100644 --- a/hw/char/omap_uart.c +++ b/hw/char/omap_uart.c @@ -21,7 +21,7 @@ #include "chardev/char.h" #include "hw/arm/omap.h" #include "hw/char/serial-mm.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" /* UARTs */ struct omap_uart_s { diff --git a/hw/char/parallel.c b/hw/char/parallel.c index e1651d5..8732e4e 100644 --- a/hw/char/parallel.c +++ b/hw/char/parallel.c @@ -610,7 +610,7 @@ static const Property parallel_isa_properties[] = { DEFINE_PROP_CHR("chardev", ISAParallelState, state.chr), }; -static void parallel_isa_class_initfn(ObjectClass *klass, void *data) +static void parallel_isa_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); @@ -627,7 +627,7 @@ static const TypeInfo parallel_isa_info = { .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(ISAParallelState), .class_init = parallel_isa_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/char/pl011.c b/hw/char/pl011.c index 0e9ec13..01335d9 100644 --- a/hw/char/pl011.c +++ b/hw/char/pl011.c @@ -669,7 +669,7 @@ static void pl011_reset(DeviceState *dev) pl011_reset_tx_fifo(s); } -static void pl011_class_init(ObjectClass *oc, void *data) +static void pl011_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/char/renesas_sci.c b/hw/char/renesas_sci.c index ea94494..b9d0ed1 100644 --- a/hw/char/renesas_sci.c +++ b/hw/char/renesas_sci.c @@ -324,7 +324,7 @@ static const Property rsci_properties[] = { DEFINE_PROP_CHR("chardev", RSCIState, chr), }; -static void rsci_class_init(ObjectClass *klass, void *data) +static void rsci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/riscv_htif.c b/hw/char/riscv_htif.c index ec5db5a..c884be5 100644 --- a/hw/char/riscv_htif.c +++ b/hw/char/riscv_htif.c @@ -28,7 +28,7 @@ #include "chardev/char-fe.h" #include "qemu/timer.h" #include "qemu/error-report.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "exec/tswap.h" #include "system/dma.h" #include "system/runstate.h" diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c index ddb9a72..3e40d5e 100644 --- a/hw/char/sclpconsole-lm.c +++ b/hw/char/sclpconsole-lm.c @@ -214,7 +214,7 @@ static int process_mdb(SCLPEvent *event, MDBO *mdbo) { int rc; int len; - uint8_t buffer[SIZE_BUFFER]; + QEMU_UNINITIALIZED uint8_t buffer[SIZE_BUFFER]; len = be16_to_cpu(mdbo->length); len -= sizeof(mdbo->length) + sizeof(mdbo->type) @@ -339,7 +339,7 @@ static const Property console_properties[] = { DEFINE_PROP_BOOL("echo", SCLPConsoleLM, echo, true), }; -static void console_class_init(ObjectClass *klass, void *data) +static void console_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCLPEventClass *ec = SCLP_EVENT_CLASS(klass); diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c index 01233b9..95e3045 100644 --- a/hw/char/sclpconsole.c +++ b/hw/char/sclpconsole.c @@ -255,7 +255,7 @@ static const Property console_properties[] = { DEFINE_PROP_CHR("chardev", SCLPConsole, chr), }; -static void console_class_init(ObjectClass *klass, void *data) +static void console_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCLPEventClass *ec = SCLP_EVENT_CLASS(klass); diff --git a/hw/char/serial-isa.c b/hw/char/serial-isa.c index 3d91389..0ea59a3 100644 --- a/hw/char/serial-isa.c +++ b/hw/char/serial-isa.c @@ -119,7 +119,7 @@ static const Property serial_isa_properties[] = { DEFINE_PROP_UINT32("irq", ISASerialState, isairq, -1), }; -static void serial_isa_class_initfn(ObjectClass *klass, void *data) +static void serial_isa_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); @@ -146,7 +146,7 @@ static const TypeInfo serial_isa_info = { .instance_size = sizeof(ISASerialState), .instance_init = serial_isa_initfn, .class_init = serial_isa_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/char/serial-mm.c b/hw/char/serial-mm.c index 6338e7c..13aba78 100644 --- a/hw/char/serial-mm.c +++ b/hw/char/serial-mm.c @@ -134,7 +134,7 @@ static const Property serial_mm_properties[] = { DEFINE_PROP_UINT8("endianness", SerialMM, endianness, DEVICE_NATIVE_ENDIAN), }; -static void serial_mm_class_init(ObjectClass *oc, void *data) +static void serial_mm_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/char/serial-pci-multi.c b/hw/char/serial-pci-multi.c index 718ae25..13df272 100644 --- a/hw/char/serial-pci-multi.c +++ b/hw/char/serial-pci-multi.c @@ -46,7 +46,6 @@ typedef struct PCIMultiSerialState { SerialState state[PCI_SERIAL_MAX_PORTS]; uint32_t level[PCI_SERIAL_MAX_PORTS]; IRQState irqs[PCI_SERIAL_MAX_PORTS]; - uint8_t prog_if; } PCIMultiSerialState; static void multi_serial_pci_exit(PCIDevice *dev) @@ -97,8 +96,8 @@ static void multi_serial_pci_realize(PCIDevice *dev, Error **errp) SerialState *s; size_t i, nports = multi_serial_get_port_count(pc); - pci->dev.config[PCI_CLASS_PROG] = pci->prog_if; - pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; + pci->dev.config[PCI_CLASS_PROG] = 2; /* 16550 compatible */ + pci->dev.config[PCI_INTERRUPT_PIN] = 1; memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * nports); pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar); @@ -133,7 +132,6 @@ static const VMStateDescription vmstate_pci_multi_serial = { static const Property multi_2x_serial_pci_properties[] = { DEFINE_PROP_CHR("chardev1", PCIMultiSerialState, state[0].chr), DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr), - DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02), }; static const Property multi_4x_serial_pci_properties[] = { @@ -141,10 +139,10 @@ static const Property multi_4x_serial_pci_properties[] = { DEFINE_PROP_CHR("chardev2", PCIMultiSerialState, state[1].chr), DEFINE_PROP_CHR("chardev3", PCIMultiSerialState, state[2].chr), DEFINE_PROP_CHR("chardev4", PCIMultiSerialState, state[3].chr), - DEFINE_PROP_UINT8("prog_if", PCIMultiSerialState, prog_if, 0x02), }; -static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data) +static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); @@ -159,7 +157,8 @@ static void multi_2x_serial_pci_class_initfn(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } -static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, void *data) +static void multi_4x_serial_pci_class_initfn(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); @@ -192,7 +191,7 @@ static const TypeInfo multi_2x_serial_pci_info = { .instance_size = sizeof(PCIMultiSerialState), .instance_init = multi_serial_init, .class_init = multi_2x_serial_pci_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -204,7 +203,7 @@ static const TypeInfo multi_4x_serial_pci_info = { .instance_size = sizeof(PCIMultiSerialState), .instance_init = multi_serial_init, .class_init = multi_4x_serial_pci_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/char/serial-pci.c b/hw/char/serial-pci.c index 6659cef..46efabc 100644 --- a/hw/char/serial-pci.c +++ b/hw/char/serial-pci.c @@ -38,7 +38,6 @@ struct PCISerialState { PCIDevice dev; SerialState state; - uint8_t prog_if; }; #define TYPE_PCI_SERIAL "pci-serial" @@ -53,8 +52,8 @@ static void serial_pci_realize(PCIDevice *dev, Error **errp) return; } - pci->dev.config[PCI_CLASS_PROG] = pci->prog_if; - pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; + pci->dev.config[PCI_CLASS_PROG] = 2; /* 16550 compatible */ + pci->dev.config[PCI_INTERRUPT_PIN] = 1; s->irq = pci_allocate_irq(&pci->dev); memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, "serial", 8); @@ -81,11 +80,7 @@ static const VMStateDescription vmstate_pci_serial = { } }; -static const Property serial_pci_properties[] = { - DEFINE_PROP_UINT8("prog_if", PCISerialState, prog_if, 0x02), -}; - -static void serial_pci_class_initfn(ObjectClass *klass, void *data) +static void serial_pci_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); @@ -96,7 +91,6 @@ static void serial_pci_class_initfn(ObjectClass *klass, void *data) pc->revision = 1; pc->class_id = PCI_CLASS_COMMUNICATION_SERIAL; dc->vmsd = &vmstate_pci_serial; - device_class_set_props(dc, serial_pci_properties); set_bit(DEVICE_CATEGORY_INPUT, dc->categories); } @@ -115,7 +109,7 @@ static const TypeInfo serial_pci_info = { .instance_size = sizeof(PCISerialState), .instance_init = serial_pci_init, .class_init = serial_pci_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/char/serial.c b/hw/char/serial.c index 70044e1..03fec3f 100644 --- a/hw/char/serial.c +++ b/hw/char/serial.c @@ -970,7 +970,7 @@ static const Property serial_properties[] = { DEFINE_PROP_BOOL("wakeup", SerialState, wakeup, false), }; -static void serial_class_init(ObjectClass *klass, void* data) +static void serial_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/sh_serial.c b/hw/char/sh_serial.c index 41c8175..30447fa 100644 --- a/hw/char/sh_serial.c +++ b/hw/char/sh_serial.c @@ -78,10 +78,6 @@ struct SHSerialState { qemu_irq bri; }; -typedef struct {} SHSerialStateClass; - -OBJECT_DEFINE_TYPE(SHSerialState, sh_serial, SH_SERIAL, SYS_BUS_DEVICE) - static void sh_serial_clear_fifo(SHSerialState *s) { memset(s->rx_fifo, 0, SH_RX_FIFO_LENGTH); @@ -434,29 +430,37 @@ static void sh_serial_realize(DeviceState *d, Error **errp) s->etu = NANOSECONDS_PER_SECOND / 9600; } -static void sh_serial_finalize(Object *obj) +static void sh_serial_unrealize(DeviceState *dev) { - SHSerialState *s = SH_SERIAL(obj); + SHSerialState *s = SH_SERIAL(dev); timer_del(&s->fifo_timeout_timer); } -static void sh_serial_init(Object *obj) -{ -} - static const Property sh_serial_properties[] = { DEFINE_PROP_CHR("chardev", SHSerialState, chr), DEFINE_PROP_UINT8("features", SHSerialState, feat, 0), }; -static void sh_serial_class_init(ObjectClass *oc, void *data) +static void sh_serial_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); device_class_set_props(dc, sh_serial_properties); dc->realize = sh_serial_realize; + dc->unrealize = sh_serial_unrealize; device_class_set_legacy_reset(dc, sh_serial_reset); /* Reason: part of SuperH CPU/SoC, needs to be wired up */ dc->user_creatable = false; } + +static const TypeInfo sh_serial_types[] = { + { + .name = TYPE_SH_SERIAL, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(SHSerialState), + .class_init = sh_serial_class_init, + }, +}; + +DEFINE_TYPES(sh_serial_types) diff --git a/hw/char/shakti_uart.c b/hw/char/shakti_uart.c index 09975d9..6e216ed 100644 --- a/hw/char/shakti_uart.c +++ b/hw/char/shakti_uart.c @@ -161,7 +161,7 @@ static const Property shakti_uart_properties[] = { DEFINE_PROP_CHR("chardev", ShaktiUartState, chr), }; -static void shakti_uart_class_init(ObjectClass *klass, void *data) +static void shakti_uart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); device_class_set_legacy_reset(dc, shakti_uart_reset); diff --git a/hw/char/sifive_uart.c b/hw/char/sifive_uart.c index b45e6c0..0fc89e7 100644 --- a/hw/char/sifive_uart.c +++ b/hw/char/sifive_uart.c @@ -334,7 +334,7 @@ static const VMStateDescription vmstate_sifive_uart = { }; -static void sifive_uart_class_init(ObjectClass *oc, void *data) +static void sifive_uart_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c index 6451d01..fc8ea60 100644 --- a/hw/char/spapr_vty.c +++ b/hw/char/spapr_vty.c @@ -182,7 +182,7 @@ static const VMStateDescription vmstate_spapr_vty = { }, }; -static void spapr_vty_class_init(ObjectClass *klass, void *data) +static void spapr_vty_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c index 87882da..45c3064 100644 --- a/hw/char/stm32f2xx_usart.c +++ b/hw/char/stm32f2xx_usart.c @@ -220,7 +220,7 @@ static void stm32f2xx_usart_realize(DeviceState *dev, Error **errp) s, NULL, true); } -static void stm32f2xx_usart_class_init(ObjectClass *klass, void *data) +static void stm32f2xx_usart_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/char/stm32l4x5_usart.c b/hw/char/stm32l4x5_usart.c index bcc310b..afbe4ba 100644 --- a/hw/char/stm32l4x5_usart.c +++ b/hw/char/stm32l4x5_usart.c @@ -594,7 +594,8 @@ static void stm32l4x5_usart_base_realize(DeviceState *dev, Error **errp) s, NULL, true); } -static void stm32l4x5_usart_base_class_init(ObjectClass *klass, void *data) +static void stm32l4x5_usart_base_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -605,21 +606,21 @@ static void stm32l4x5_usart_base_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_stm32l4x5_usart_base; } -static void stm32l4x5_usart_class_init(ObjectClass *oc, void *data) +static void stm32l4x5_usart_class_init(ObjectClass *oc, const void *data) { Stm32l4x5UsartBaseClass *subc = STM32L4X5_USART_BASE_CLASS(oc); subc->type = STM32L4x5_USART; } -static void stm32l4x5_uart_class_init(ObjectClass *oc, void *data) +static void stm32l4x5_uart_class_init(ObjectClass *oc, const void *data) { Stm32l4x5UsartBaseClass *subc = STM32L4X5_USART_BASE_CLASS(oc); subc->type = STM32L4x5_UART; } -static void stm32l4x5_lpuart_class_init(ObjectClass *oc, void *data) +static void stm32l4x5_lpuart_class_init(ObjectClass *oc, const void *data) { Stm32l4x5UsartBaseClass *subc = STM32L4X5_USART_BASE_CLASS(oc); diff --git a/hw/char/terminal3270.c b/hw/char/terminal3270.c index 04ee26d..d950c17 100644 --- a/hw/char/terminal3270.c +++ b/hw/char/terminal3270.c @@ -292,7 +292,7 @@ static const VMStateDescription terminal3270_vmstate = { .unmigratable = 1, }; -static void terminal_class_init(ObjectClass *klass, void *data) +static void terminal_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); EmulatedCcw3270Class *ck = EMULATED_CCW_3270_CLASS(klass); diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c index aa6d611..0932a35 100644 --- a/hw/char/virtio-console.c +++ b/hw/char/virtio-console.c @@ -261,7 +261,7 @@ static void virtconsole_unrealize(DeviceState *dev) } } -static void virtconsole_class_init(ObjectClass *klass, void *data) +static void virtconsole_class_init(ObjectClass *klass, const void *data) { VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass); @@ -278,7 +278,7 @@ static const Property virtserialport_properties[] = { DEFINE_PROP_CHR("chardev", VirtConsole, chr), }; -static void virtserialport_class_init(ObjectClass *klass, void *data) +static void virtserialport_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass); diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index b6d2743..673c50f 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -622,7 +622,7 @@ static void guest_reset(VirtIOSerial *vser) } } -static void set_status(VirtIODevice *vdev, uint8_t status) +static int set_status(VirtIODevice *vdev, uint8_t status) { VirtIOSerial *vser; VirtIOSerialPort *port; @@ -650,6 +650,7 @@ static void set_status(VirtIODevice *vdev, uint8_t status) vsc->enable_backend(port, vdev->vm_running); } } + return 0; } static void vser_reset(VirtIODevice *vdev) @@ -840,7 +841,7 @@ static const Property virtser_props[] = { DEFINE_PROP_STRING("name", VirtIOSerialPort, name), }; -static void virtser_bus_class_init(ObjectClass *klass, void *data) +static void virtser_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); k->print_dev = virtser_bus_dev_print; @@ -1092,7 +1093,7 @@ static void virtio_serial_device_realize(DeviceState *dev, Error **errp) QLIST_INSERT_HEAD(&vserdevices.devices, vser, next); } -static void virtio_serial_port_class_init(ObjectClass *klass, void *data) +static void virtio_serial_port_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); @@ -1159,7 +1160,7 @@ static const Property virtio_serial_properties[] = { VIRTIO_CONSOLE_F_EMERG_WRITE, true), }; -static void virtio_serial_class_init(ObjectClass *klass, void *data) +static void virtio_serial_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -1188,7 +1189,7 @@ static const TypeInfo virtio_device_info = { .parent = TYPE_VIRTIO_DEVICE, .instance_size = sizeof(VirtIOSerial), .class_init = virtio_serial_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c index d03c188..9c34a55 100644 --- a/hw/char/xen_console.c +++ b/hw/char/xen_console.c @@ -492,7 +492,7 @@ static const Property xen_console_properties[] = { DEFINE_PROP_INT32("idx", XenConsole, dev, -1), }; -static void xen_console_class_init(ObjectClass *class, void *data) +static void xen_console_class_init(ObjectClass *class, const void *data) { DeviceClass *dev_class = DEVICE_CLASS(class); XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class); diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c index 4037c93..8008171 100644 --- a/hw/char/xilinx_uartlite.c +++ b/hw/char/xilinx_uartlite.c @@ -241,7 +241,7 @@ static void xilinx_uartlite_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); } -static void xilinx_uartlite_class_init(ObjectClass *klass, void *data) +static void xilinx_uartlite_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/core/bus.c b/hw/core/bus.c index b9d8949..bddfc22 100644 --- a/hw/core/bus.c +++ b/hw/core/bus.c @@ -232,7 +232,7 @@ static char *default_bus_get_fw_dev_path(DeviceState *dev) return g_strdup(object_get_typename(OBJECT(dev))); } -static void bus_class_init(ObjectClass *class, void *data) +static void bus_class_init(ObjectClass *class, const void *data) { BusClass *bc = BUS_CLASS(class); ResettableClass *rc = RESETTABLE_CLASS(class); @@ -260,7 +260,7 @@ static const TypeInfo bus_info = { .instance_init = qbus_initfn, .instance_finalize = qbus_finalize, .class_init = bus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_RESETTABLE_INTERFACE }, { } }, diff --git a/hw/core/clock.c b/hw/core/clock.c index a81f888..9c90676 100644 --- a/hw/core/clock.c +++ b/hw/core/clock.c @@ -206,7 +206,7 @@ static void clock_finalizefn(Object *obj) g_free(clk->canonical_path); } -static void clock_class_init(ObjectClass *klass, void *data) +static void clock_class_init(ObjectClass *klass, const void *data) { klass->unparent = clock_unparent; } diff --git a/hw/core/cpu-common.c b/hw/core/cpu-common.c index 9064dd2..39e674a 100644 --- a/hw/core/cpu-common.c +++ b/hw/core/cpu-common.c @@ -25,6 +25,9 @@ #include "qemu/log.h" #include "qemu/main-loop.h" #include "qemu/lockcnt.h" +#include "qemu/error-report.h" +#include "qemu/qemu-print.h" +#include "qemu/target-info.h" #include "exec/log.h" #include "exec/gdbstub.h" #include "system/tcg.h" @@ -152,6 +155,21 @@ ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model) return NULL; } +char *cpu_model_from_type(const char *typename) +{ + g_autofree char *suffix = g_strdup_printf("-%s", target_cpu_type()); + + if (!object_class_by_name(typename)) { + return NULL; + } + + if (g_str_has_suffix(typename, suffix)) { + return g_strndup(typename, strlen(typename) - strlen(suffix)); + } + + return g_strdup(typename); +} + static void cpu_common_parse_features(const char *typename, char *features, Error **errp) { @@ -183,12 +201,41 @@ static void cpu_common_parse_features(const char *typename, char *features, } } +const char *parse_cpu_option(const char *cpu_option) +{ + ObjectClass *oc; + CPUClass *cc; + gchar **model_pieces; + const char *cpu_type; + + model_pieces = g_strsplit(cpu_option, ",", 2); + if (!model_pieces[0]) { + error_report("-cpu option cannot be empty"); + exit(1); + } + + oc = cpu_class_by_name(target_cpu_type(), model_pieces[0]); + if (oc == NULL) { + error_report("unable to find CPU model '%s'", model_pieces[0]); + g_strfreev(model_pieces); + exit(EXIT_FAILURE); + } + + cpu_type = object_class_get_name(oc); + cc = CPU_CLASS(oc); + cc->parse_features(cpu_type, model_pieces[1], &error_fatal); + g_strfreev(model_pieces); + return cpu_type; +} + bool cpu_exec_realizefn(CPUState *cpu, Error **errp) { if (!accel_cpu_common_realize(cpu, errp)) { return false; } + gdb_init_cpu(cpu); + /* Wait until cpu initialization complete before exposing cpu. */ cpu_list_add(cpu); @@ -259,7 +306,6 @@ static void cpu_common_initfn(Object *obj) /* cache the cpu class for the hotpath */ cpu->cc = CPU_GET_CLASS(cpu); - gdb_init_cpu(cpu); cpu->cpu_index = UNASSIGNED_CPU_INDEX; cpu->cluster_index = UNASSIGNED_CLUSTER_INDEX; cpu->as = NULL; @@ -320,7 +366,7 @@ static int64_t cpu_common_get_arch_id(CPUState *cpu) return cpu->cpu_index; } -static void cpu_common_class_init(ObjectClass *klass, void *data) +static void cpu_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -359,3 +405,32 @@ static void cpu_register_types(void) } type_init(cpu_register_types) + +static void cpu_list_entry(gpointer data, gpointer user_data) +{ + CPUClass *cc = CPU_CLASS(OBJECT_CLASS(data)); + const char *typename = object_class_get_name(OBJECT_CLASS(data)); + g_autofree char *model = cpu_model_from_type(typename); + + if (cc->deprecation_note) { + qemu_printf(" %s (deprecated)\n", model); + } else { + qemu_printf(" %s\n", model); + } +} + +void list_cpus(void) +{ + CPUClass *cc = CPU_CLASS(object_class_by_name(target_cpu_type())); + + if (cc->list_cpus) { + cc->list_cpus(); + } else { + GSList *list; + + list = object_class_get_list_sorted(TYPE_CPU, false); + qemu_printf("Available CPUs:\n"); + g_slist_foreach(list, cpu_list_entry, NULL); + g_slist_free(list); + } +} diff --git a/hw/core/cpu-system.c b/hw/core/cpu-system.c index aed5076..3c84176 100644 --- a/hw/core/cpu-system.c +++ b/hw/core/cpu-system.c @@ -20,9 +20,9 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "exec/cputlb.h" -#include "exec/memory.h" +#include "system/memory.h" #include "exec/tb-flush.h" #include "exec/tswap.h" #include "hw/qdev-core.h" @@ -133,7 +133,7 @@ bool cpu_virtio_is_big_endian(CPUState *cpu) if (cpu->cc->sysemu_ops->virtio_is_big_endian) { return cpu->cc->sysemu_ops->virtio_is_big_endian(cpu); } - return target_words_bigendian(); + return target_big_endian(); } GuestPanicInformation *cpu_get_crash_info(CPUState *cpu) diff --git a/hw/core/generic-loader.c b/hw/core/generic-loader.c index d3a426a..e72bbde 100644 --- a/hw/core/generic-loader.c +++ b/hw/core/generic-loader.c @@ -182,7 +182,7 @@ static const Property generic_loader_props[] = { DEFINE_PROP_STRING("file", GenericLoaderState, file), }; -static void generic_loader_class_init(ObjectClass *klass, void *data) +static void generic_loader_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/core/guest-loader.c b/hw/core/guest-loader.c index 76271df..3db89d7 100644 --- a/hw/core/guest-loader.c +++ b/hw/core/guest-loader.c @@ -118,7 +118,7 @@ static const Property guest_loader_props[] = { DEFINE_PROP_STRING("initrd", GuestLoaderState, initrd), }; -static void guest_loader_class_init(ObjectClass *klass, void *data) +static void guest_loader_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/core/loader-fit.c b/hw/core/loader-fit.c index 6eb6640..2dea485 100644 --- a/hw/core/loader-fit.c +++ b/hw/core/loader-fit.c @@ -20,7 +20,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/units.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/loader.h" #include "hw/loader-fit.h" #include "qemu/cutils.h" diff --git a/hw/core/loader.c b/hw/core/loader.c index 2e35f0a..e7056ba 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -59,7 +59,7 @@ #include "uboot_image.h" #include "hw/loader.h" #include "hw/nvram/fw_cfg.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/boards.h" #include "qemu/cutils.h" #include "system/runstate.h" @@ -1333,20 +1333,6 @@ void rom_set_fw(FWCfgState *f) fw_cfg = f; } -void rom_set_order_override(int order) -{ - if (!fw_cfg) - return; - fw_cfg_set_order_override(fw_cfg, order); -} - -void rom_reset_order_override(void) -{ - if (!fw_cfg) - return; - fw_cfg_reset_order_override(fw_cfg); -} - void rom_transaction_begin(void) { Rom *rom; @@ -1410,7 +1396,7 @@ typedef struct RomSec { * work, but this way saves a little work later by avoiding * dealing with "gaps" of 0 length. */ -static gint sort_secs(gconstpointer a, gconstpointer b) +static gint sort_secs(gconstpointer a, gconstpointer b, gpointer d) { RomSec *ra = (RomSec *) a; RomSec *rb = (RomSec *) b; @@ -1463,7 +1449,7 @@ RomGap rom_find_largest_gap_between(hwaddr base, size_t size) /* sentinel */ secs = add_romsec_to_list(secs, base + size, 1); - secs = g_list_sort(secs, sort_secs); + secs = g_list_sort_with_data(secs, sort_secs, NULL); for (it = g_list_first(secs); it; it = g_list_next(it)) { cand = (RomSec *) it->data; diff --git a/hw/core/machine-qmp-cmds.c b/hw/core/machine-qmp-cmds.c index fd8b4e0..d82043e 100644 --- a/hw/core/machine-qmp-cmds.c +++ b/hw/core/machine-qmp-cmds.c @@ -19,6 +19,7 @@ #include "qapi/qobject-input-visitor.h" #include "qapi/type-helpers.h" #include "qemu/uuid.h" +#include "qemu/target-info.h" #include "qom/qom-qobject.h" #include "system/hostmem.h" #include "system/hw_accel.h" @@ -73,6 +74,7 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props, for (el = machines; el; el = el->next) { MachineClass *mc = el->data; + const char *default_cpu_type = machine_class_default_cpu_type(mc); MachineInfo *info; info = g_malloc0(sizeof(*info)); @@ -91,8 +93,8 @@ MachineInfoList *qmp_query_machines(bool has_compat_props, bool compat_props, info->numa_mem_supported = mc->numa_mem_supported; info->deprecated = !!mc->deprecation_reason; info->acpi = !!object_class_property_find(OBJECT_CLASS(mc), "acpi"); - if (mc->default_cpu_type) { - info->default_cpu_type = g_strdup(mc->default_cpu_type); + if (default_cpu_type) { + info->default_cpu_type = g_strdup(default_cpu_type); } if (mc->default_ram_id) { info->default_ram_id = g_strdup(mc->default_ram_id); @@ -133,9 +135,9 @@ CurrentMachineParams *qmp_query_current_machine(Error **errp) return params; } -TargetInfo *qmp_query_target(Error **errp) +QemuTargetInfo *qmp_query_target(Error **errp) { - TargetInfo *info = g_malloc0(sizeof(*info)); + QemuTargetInfo *info = g_malloc0(sizeof(*info)); info->arch = qapi_enum_parse(&SysEmuTarget_lookup, target_name(), -1, &error_abort); diff --git a/hw/core/machine.c b/hw/core/machine.c index abfcedd..e869821 100644 --- a/hw/core/machine.c +++ b/hw/core/machine.c @@ -37,11 +37,13 @@ #include "hw/virtio/virtio-iommu.h" #include "audio/audio.h" -GlobalProperty hw_compat_10_0[] = {}; +GlobalProperty hw_compat_10_0[] = { + { "scsi-hd", "dpofua", "off" }, +}; const size_t hw_compat_10_0_len = G_N_ELEMENTS(hw_compat_10_0); GlobalProperty hw_compat_9_2[] = { - {"arm-cpu", "backcompat-pauth-default-use-qarma5", "true"}, + { "arm-cpu", "backcompat-pauth-default-use-qarma5", "true"}, { "virtio-balloon-pci", "vectors", "0" }, { "virtio-balloon-pci-transitional", "vectors", "0" }, { "virtio-balloon-pci-non-transitional", "vectors", "0" }, @@ -58,12 +60,12 @@ GlobalProperty hw_compat_9_1[] = { const size_t hw_compat_9_1_len = G_N_ELEMENTS(hw_compat_9_1); GlobalProperty hw_compat_9_0[] = { - {"arm-cpu", "backcompat-cntfrq", "true" }, + { "arm-cpu", "backcompat-cntfrq", "true" }, { "scsi-hd", "migrate-emulated-scsi-request", "false" }, { "scsi-cd", "migrate-emulated-scsi-request", "false" }, - {"vfio-pci", "skip-vsc-check", "false" }, + { "vfio-pci", "skip-vsc-check", "false" }, { "virtio-pci", "x-pcie-pm-no-soft-reset", "off" }, - {"sd-card", "spec_version", "2" }, + { "sd-card", "spec_version", "2" }, }; const size_t hw_compat_9_0_len = G_N_ELEMENTS(hw_compat_9_0); @@ -283,24 +285,6 @@ GlobalProperty hw_compat_2_6[] = { }; const size_t hw_compat_2_6_len = G_N_ELEMENTS(hw_compat_2_6); -GlobalProperty hw_compat_2_5[] = { - { "isa-fdc", "fallback", "144" }, - { "pvscsi", "x-old-pci-configuration", "on" }, - { "pvscsi", "x-disable-pcie", "on" }, - { "vmxnet3", "x-old-msi-offsets", "on" }, - { "vmxnet3", "x-disable-pcie", "on" }, -}; -const size_t hw_compat_2_5_len = G_N_ELEMENTS(hw_compat_2_5); - -GlobalProperty hw_compat_2_4[] = { - { "e1000", "extra_mac_registers", "off" }, - { "virtio-pci", "x-disable-pcie", "on" }, - { "virtio-pci", "migrate-extra", "off" }, - { "fw_cfg_mem", "dma_enabled", "off" }, - { "fw_cfg_io", "dma_enabled", "off" } -}; -const size_t hw_compat_2_4_len = G_N_ELEMENTS(hw_compat_2_4); - MachineState *current_machine; static char *machine_get_kernel(Object *obj, Error **errp) @@ -1100,7 +1084,7 @@ out: return r; } -static void machine_class_init(ObjectClass *oc, void *data) +static void machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1243,7 +1227,7 @@ static void machine_class_init(ObjectClass *oc, void *data) "Memory size configuration"); } -static void machine_class_base_init(ObjectClass *oc, void *data) +static void machine_class_base_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); mc->max_cpus = mc->max_cpus ?: 1; diff --git a/hw/core/null-machine.c b/hw/core/null-machine.c index 7f1fb56..a6e477a 100644 --- a/hw/core/null-machine.c +++ b/hw/core/null-machine.c @@ -14,7 +14,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "hw/boards.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/core/cpu.h" static void machine_none_init(MachineState *mch) diff --git a/hw/core/or-irq.c b/hw/core/or-irq.c index 4d0d3ca..3942c70 100644 --- a/hw/core/or-irq.c +++ b/hw/core/or-irq.c @@ -119,7 +119,7 @@ static const Property or_irq_properties[] = { DEFINE_PROP_UINT16("num-lines", OrIRQState, num_lines, 1), }; -static void or_irq_class_init(ObjectClass *klass, void *data) +static void or_irq_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/core/platform-bus.c b/hw/core/platform-bus.c index 1d00c4d..6950063 100644 --- a/hw/core/platform-bus.c +++ b/hw/core/platform-bus.c @@ -209,7 +209,7 @@ static const Property platform_bus_properties[] = { DEFINE_PROP_UINT32("mmio_size", PlatformBusDevice, mmio_size, 0), }; -static void platform_bus_class_init(ObjectClass *klass, void *data) +static void platform_bus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c index 7f63d17..0aeb10f 100644 --- a/hw/core/ptimer.c +++ b/hw/core/ptimer.c @@ -11,7 +11,7 @@ #include "migration/vmstate.h" #include "qemu/host-utils.h" #include "exec/replay-core.h" -#include "system/cpu-timers.h" +#include "exec/icount.h" #include "system/qtest.h" #include "block/aio.h" #include "hw/clock.h" diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c index 8e11e63..24e145d 100644 --- a/hw/core/qdev-properties-system.c +++ b/hw/core/qdev-properties-system.c @@ -145,6 +145,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const char *name, if (ctx != bdrv_get_aio_context(bs)) { error_setg(errp, "Different aio context is not supported for new " "node"); + return; } blk_replace_bs(blk, bs, errp); diff --git a/hw/core/qdev.c b/hw/core/qdev.c index 2745b5e..f600226 100644 --- a/hw/core/qdev.c +++ b/hw/core/qdev.c @@ -693,7 +693,7 @@ static void device_finalize(Object *obj) g_free(dev->id); } -static void device_class_base_init(ObjectClass *class, void *data) +static void device_class_base_init(ObjectClass *class, const void *data) { DeviceClass *klass = DEVICE_CLASS(class); @@ -731,7 +731,7 @@ device_vmstate_if_get_id(VMStateIf *obj) return qdev_get_dev_path(dev); } -static void device_class_init(ObjectClass *class, void *data) +static void device_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); VMStateIfClass *vc = VMSTATE_IF_CLASS(class); @@ -870,7 +870,7 @@ static const TypeInfo device_type_info = { .class_init = device_class_init, .abstract = true, .class_size = sizeof(DeviceClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_VMSTATE_IF }, { TYPE_RESETTABLE_INTERFACE }, { } diff --git a/hw/core/register.c b/hw/core/register.c index 95b0150..8f63d9f 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -319,7 +319,7 @@ void register_finalize_block(RegisterInfoArray *r_array) g_free(r_array); } -static void register_class_init(ObjectClass *oc, void *data) +static void register_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/core/reset.c b/hw/core/reset.c index 8a3e0e5..65f82fa 100644 --- a/hw/core/reset.c +++ b/hw/core/reset.c @@ -84,7 +84,7 @@ static void legacy_reset_finalize(Object *obj) { } -static void legacy_reset_class_init(ObjectClass *klass, void *data) +static void legacy_reset_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/core/resetcontainer.c b/hw/core/resetcontainer.c index e4ece68..5ff1700 100644 --- a/hw/core/resetcontainer.c +++ b/hw/core/resetcontainer.c @@ -68,7 +68,8 @@ static void resettable_container_finalize(Object *obj) { } -static void resettable_container_class_init(ObjectClass *klass, void *data) +static void resettable_container_class_init(ObjectClass *klass, + const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/core/split-irq.c b/hw/core/split-irq.c index fc12274..f8b4875 100644 --- a/hw/core/split-irq.c +++ b/hw/core/split-irq.c @@ -63,7 +63,7 @@ static const Property split_irq_properties[] = { DEFINE_PROP_UINT16("num-lines", SplitIRQ, num_lines, 1), }; -static void split_irq_class_init(ObjectClass *klass, void *data) +static void split_irq_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/core/sysbus-fdt.c b/hw/core/sysbus-fdt.c index e85066b..c339a27 100644 --- a/hw/core/sysbus-fdt.c +++ b/hw/core/sysbus-fdt.c @@ -35,6 +35,7 @@ #include "hw/vfio/vfio-platform.h" #include "hw/vfio/vfio-calxeda-xgmac.h" #include "hw/vfio/vfio-amd-xgbe.h" +#include "hw/vfio/vfio-region.h" #include "hw/display/ramfb.h" #include "hw/uefi/var-service-api.h" #include "hw/arm/fdt.h" diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c index 98819d5..e71367a 100644 --- a/hw/core/sysbus.c +++ b/hw/core/sysbus.c @@ -21,7 +21,7 @@ #include "qapi/error.h" #include "hw/sysbus.h" #include "monitor/monitor.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" static void sysbus_dev_print(Monitor *mon, DeviceState *dev, int indent); static char *sysbus_get_fw_dev_path(DeviceState *dev); @@ -71,7 +71,7 @@ void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque) } -static void system_bus_class_init(ObjectClass *klass, void *data) +static void system_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -280,7 +280,7 @@ static char *sysbus_get_fw_dev_path(DeviceState *dev) return g_strdup(qdev_fw_name(dev)); } -static void sysbus_device_class_init(ObjectClass *klass, void *data) +static void sysbus_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->realize = sysbus_device_realize; @@ -320,7 +320,8 @@ BusState *sysbus_get_default(void) return main_system_bus; } -static void dynamic_sysbus_device_class_init(ObjectClass *klass, void *data) +static void dynamic_sysbus_device_class_init(ObjectClass *klass, + const void *data) { DeviceClass *k = DEVICE_CLASS(klass); diff --git a/hw/core/vm-change-state-handler.c b/hw/core/vm-change-state-handler.c index 7064995..99c642b 100644 --- a/hw/core/vm-change-state-handler.c +++ b/hw/core/vm-change-state-handler.c @@ -40,6 +40,7 @@ static int qdev_get_dev_tree_depth(DeviceState *dev) * qdev_add_vm_change_state_handler: * @dev: the device that owns this handler * @cb: the callback function to be invoked + * @cb_ret: the callback function with return value to be invoked * @opaque: user data passed to the callback function * * This function works like qemu_add_vm_change_state_handler() except callbacks @@ -50,25 +51,30 @@ static int qdev_get_dev_tree_depth(DeviceState *dev) * controller's callback is invoked before the children on its bus when the VM * starts running. The order is reversed when the VM stops running. * + * Note that the parameter `cb` and `cb_ret` are mutually exclusive. + * * Returns: an entry to be freed with qemu_del_vm_change_state_handler() */ VMChangeStateEntry *qdev_add_vm_change_state_handler(DeviceState *dev, VMChangeStateHandler *cb, + VMChangeStateHandlerWithRet *cb_ret, void *opaque) { - return qdev_add_vm_change_state_handler_full(dev, cb, NULL, opaque); + assert(!cb || !cb_ret); + return qdev_add_vm_change_state_handler_full(dev, cb, NULL, cb_ret, opaque); } /* * Exactly like qdev_add_vm_change_state_handler() but passes a prepare_cb - * argument too. + * and the cb_ret arguments too. */ VMChangeStateEntry *qdev_add_vm_change_state_handler_full( - DeviceState *dev, VMChangeStateHandler *cb, - VMChangeStateHandler *prepare_cb, void *opaque) + DeviceState *dev, VMChangeStateHandler *cb, VMChangeStateHandler *prepare_cb, + VMChangeStateHandlerWithRet *cb_ret, void *opaque) { int depth = qdev_get_dev_tree_depth(dev); - return qemu_add_vm_change_state_handler_prio_full(cb, prepare_cb, opaque, - depth); + assert(!cb || !cb_ret); + return qemu_add_vm_change_state_handler_prio_full(cb, prepare_cb, cb_ret, + opaque, depth); } diff --git a/hw/cpu/a15mpcore.c b/hw/cpu/a15mpcore.c index 676f65a..bd36dd9 100644 --- a/hw/cpu/a15mpcore.c +++ b/hw/cpu/a15mpcore.c @@ -161,7 +161,7 @@ static const Property a15mp_priv_properties[] = { DEFINE_PROP_UINT32("num-irq", A15MPPrivState, num_irq, 0), }; -static void a15mp_priv_class_init(ObjectClass *klass, void *data) +static void a15mp_priv_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c index 1b9f2be..64bebbd 100644 --- a/hw/cpu/a9mpcore.c +++ b/hw/cpu/a9mpcore.c @@ -175,7 +175,7 @@ static const Property a9mp_priv_properties[] = { DEFINE_PROP_UINT32("num-irq", A9MPPrivState, num_irq, 0), }; -static void a9mp_priv_class_init(ObjectClass *klass, void *data) +static void a9mp_priv_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/cpu/arm11mpcore.c b/hw/cpu/arm11mpcore.c index b56bee6..01772e7 100644 --- a/hw/cpu/arm11mpcore.c +++ b/hw/cpu/arm11mpcore.c @@ -144,7 +144,7 @@ static const Property mpcore_priv_properties[] = { DEFINE_PROP_UINT32("num-irq", ARM11MPCorePriveState, num_irq, 64), }; -static void mpcore_priv_class_init(ObjectClass *klass, void *data) +static void mpcore_priv_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/cpu/cluster.c b/hw/cpu/cluster.c index 9da5221..ef3b3d1 100644 --- a/hw/cpu/cluster.c +++ b/hw/cpu/cluster.c @@ -72,7 +72,7 @@ static void cpu_cluster_realize(DeviceState *dev, Error **errp) assert(cbdata.cpu_count > 0); } -static void cpu_cluster_class_init(ObjectClass *klass, void *data) +static void cpu_cluster_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/cpu/core.c b/hw/cpu/core.c index 495a5c3..5cb2e9a 100644 --- a/hw/cpu/core.c +++ b/hw/cpu/core.c @@ -77,7 +77,7 @@ static void cpu_core_instance_init(Object *obj) } } -static void cpu_core_class_init(ObjectClass *oc, void *data) +static void cpu_core_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/cpu/realview_mpcore.c b/hw/cpu/realview_mpcore.c index b140888..099b71a 100644 --- a/hw/cpu/realview_mpcore.c +++ b/hw/cpu/realview_mpcore.c @@ -107,7 +107,7 @@ static void mpcore_rirq_init(Object *obj) } } -static void mpcore_rirq_class_init(ObjectClass *klass, void *data) +static void mpcore_rirq_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/cxl/cxl-device-utils.c b/hw/cxl/cxl-device-utils.c index 52ad1e4..e150d74 100644 --- a/hw/cxl/cxl-device-utils.c +++ b/hw/cxl/cxl-device-utils.c @@ -95,11 +95,15 @@ static uint64_t mailbox_reg_read(void *opaque, hwaddr offset, unsigned size) } if (offset == A_CXL_DEV_MAILBOX_STS) { uint64_t status_reg = cxl_dstate->mbox_reg_state64[offset / size]; - if (cci->bg.complete_pct) { - status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP, - 0); - cxl_dstate->mbox_reg_state64[offset / size] = status_reg; - } + int bgop; + + qemu_mutex_lock(&cci->bg.lock); + bgop = !(cci->bg.complete_pct == 100 || cci->bg.aborted); + + status_reg = FIELD_DP64(status_reg, CXL_DEV_MAILBOX_STS, BG_OP, + bgop); + cxl_dstate->mbox_reg_state64[offset / size] = status_reg; + qemu_mutex_unlock(&cci->bg.lock); } return cxl_dstate->mbox_reg_state64[offset / size]; default: diff --git a/hw/cxl/cxl-mailbox-utils.c b/hw/cxl/cxl-mailbox-utils.c index 516c01d..299f232 100644 --- a/hw/cxl/cxl-mailbox-utils.c +++ b/hw/cxl/cxl-mailbox-utils.c @@ -7,6 +7,8 @@ * COPYING file in the top-level directory. */ +#include <math.h> + #include "qemu/osdep.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" @@ -26,6 +28,11 @@ #define CXL_DC_EVENT_LOG_SIZE 8 #define CXL_NUM_EXTENTS_SUPPORTED 512 #define CXL_NUM_TAGS_SUPPORTED 0 +#define CXL_ALERTS_LIFE_USED_WARN_THRESH (1 << 0) +#define CXL_ALERTS_OVER_TEMP_WARN_THRESH (1 << 1) +#define CXL_ALERTS_UNDER_TEMP_WARN_THRESH (1 << 2) +#define CXL_ALERTS_COR_VMEM_ERR_WARN_THRESH (1 << 3) +#define CXL_ALERTS_COR_PMEM_ERR_WARN_THRESH (1 << 4) /* * How to add a new command, example. The command set FOO, with cmd BAR. @@ -56,6 +63,9 @@ enum { INFOSTAT = 0x00, #define IS_IDENTIFY 0x1 #define BACKGROUND_OPERATION_STATUS 0x2 + #define GET_RESPONSE_MSG_LIMIT 0x3 + #define SET_RESPONSE_MSG_LIMIT 0x4 + #define BACKGROUND_OPERATION_ABORT 0x5 EVENTS = 0x01, #define GET_RECORDS 0x0 #define CLEAR_RECORDS 0x1 @@ -81,9 +91,13 @@ enum { #define GET_PARTITION_INFO 0x0 #define GET_LSA 0x2 #define SET_LSA 0x3 + HEALTH_INFO_ALERTS = 0x42, + #define GET_ALERT_CONFIG 0x1 + #define SET_ALERT_CONFIG 0x2 SANITIZE = 0x44, #define OVERWRITE 0x0 #define SECURE_ERASE 0x1 + #define MEDIA_OPERATIONS 0x2 PERSISTENT_MEM = 0x45, #define GET_SECURITY_STATE 0x0 MEDIA_AND_POISON = 0x43, @@ -412,12 +426,58 @@ static CXLRetCode cmd_infostat_identify(const struct cxl_cmd *cmd, is_identify->component_type = 0x3; /* Type 3 */ } - /* TODO: Allow this to vary across different CCIs */ - is_identify->max_message_size = 9; /* 512 bytes - MCTP_CXL_MAILBOX_BYTES */ + is_identify->max_message_size = (uint8_t)log2(cci->payload_max); *len_out = sizeof(*is_identify); return CXL_MBOX_SUCCESS; } +/* CXL r3.1 section 8.2.9.1.3: Get Response Message Limit (Opcode 0003h) */ +static CXLRetCode cmd_get_response_msg_limit(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + struct { + uint8_t rsp_limit; + } QEMU_PACKED *get_rsp_msg_limit = (void *)payload_out; + QEMU_BUILD_BUG_ON(sizeof(*get_rsp_msg_limit) != 1); + + get_rsp_msg_limit->rsp_limit = (uint8_t)log2(cci->payload_max); + + *len_out = sizeof(*get_rsp_msg_limit); + return CXL_MBOX_SUCCESS; +} + +/* CXL r3.1 section 8.2.9.1.4: Set Response Message Limit (Opcode 0004h) */ +static CXLRetCode cmd_set_response_msg_limit(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + struct { + uint8_t rsp_limit; + } QEMU_PACKED *in = (void *)payload_in; + QEMU_BUILD_BUG_ON(sizeof(*in) != 1); + struct { + uint8_t rsp_limit; + } QEMU_PACKED *out = (void *)payload_out; + QEMU_BUILD_BUG_ON(sizeof(*out) != 1); + + if (in->rsp_limit < 8 || in->rsp_limit > 10) { + return CXL_MBOX_INVALID_INPUT; + } + + cci->payload_max = 1 << in->rsp_limit; + out->rsp_limit = in->rsp_limit; + + *len_out = sizeof(*out); + return CXL_MBOX_SUCCESS; +} + static void cxl_set_dsp_active_bm(PCIBus *b, PCIDevice *d, void *private) { @@ -636,6 +696,41 @@ static CXLRetCode cmd_infostat_bg_op_sts(const struct cxl_cmd *cmd, return CXL_MBOX_SUCCESS; } +/* + * CXL r3.1 Section 8.2.9.1.5: + * Request Abort Background Operation (Opcode 0005h) + */ +static CXLRetCode cmd_infostat_bg_op_abort(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + int bg_set = cci->bg.opcode >> 8; + int bg_cmd = cci->bg.opcode & 0xff; + const struct cxl_cmd *bg_c = &cci->cxl_cmd_set[bg_set][bg_cmd]; + + if (!(bg_c->effect & CXL_MBOX_BACKGROUND_OPERATION_ABORT)) { + return CXL_MBOX_REQUEST_ABORT_NOTSUP; + } + + qemu_mutex_lock(&cci->bg.lock); + if (cci->bg.runtime) { + /* operation is near complete, let it finish */ + if (cci->bg.complete_pct < 85) { + timer_del(cci->bg.timer); + cci->bg.ret_code = CXL_MBOX_ABORTED; + cci->bg.starttime = 0; + cci->bg.runtime = 0; + cci->bg.aborted = true; + } + } + qemu_mutex_unlock(&cci->bg.lock); + + return CXL_MBOX_SUCCESS; +} + #define CXL_FW_SLOTS 2 #define CXL_FW_SIZE 0x02000000 /* 32 mb */ @@ -1523,6 +1618,97 @@ static CXLRetCode cmd_ccls_set_lsa(const struct cxl_cmd *cmd, return CXL_MBOX_SUCCESS; } +/* CXL r3.2 Section 8.2.10.9.3.2 Get Alert Configuration (Opcode 4201h) */ +static CXLRetCode cmd_get_alert_config(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); + CXLAlertConfig *out = (CXLAlertConfig *)payload_out; + + memcpy(out, &ct3d->alert_config, sizeof(ct3d->alert_config)); + *len_out = sizeof(ct3d->alert_config); + + return CXL_MBOX_SUCCESS; +} + +/* CXL r3.2 Section 8.2.10.9.3.3 Set Alert Configuration (Opcode 4202h) */ +static CXLRetCode cmd_set_alert_config(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); + CXLAlertConfig *alert_config = &ct3d->alert_config; + struct { + uint8_t valid_alert_actions; + uint8_t enable_alert_actions; + uint8_t life_used_warn_thresh; + uint8_t rsvd; + uint16_t over_temp_warn_thresh; + uint16_t under_temp_warn_thresh; + uint16_t cor_vmem_err_warn_thresh; + uint16_t cor_pmem_err_warn_thresh; + } QEMU_PACKED *in = (void *)payload_in; + + if (in->valid_alert_actions & CXL_ALERTS_LIFE_USED_WARN_THRESH) { + /* + * CXL r3.2 Table 8-149 The life used warning threshold shall be + * less than the life used critical alert value. + */ + if (in->life_used_warn_thresh >= + alert_config->life_used_crit_alert_thresh) { + return CXL_MBOX_INVALID_INPUT; + } + alert_config->life_used_warn_thresh = in->life_used_warn_thresh; + alert_config->enable_alerts |= CXL_ALERTS_LIFE_USED_WARN_THRESH; + } + + if (in->valid_alert_actions & CXL_ALERTS_OVER_TEMP_WARN_THRESH) { + /* + * CXL r3.2 Table 8-149 The Device Over-Temperature Warning Threshold + * shall be less than the the Device Over-Temperature Critical + * Alert Threshold. + */ + if (in->over_temp_warn_thresh >= + alert_config->over_temp_crit_alert_thresh) { + return CXL_MBOX_INVALID_INPUT; + } + alert_config->over_temp_warn_thresh = in->over_temp_warn_thresh; + alert_config->enable_alerts |= CXL_ALERTS_OVER_TEMP_WARN_THRESH; + } + + if (in->valid_alert_actions & CXL_ALERTS_UNDER_TEMP_WARN_THRESH) { + /* + * CXL r3.2 Table 8-149 The Device Under-Temperature Warning Threshold + * shall be higher than the the Device Under-Temperature Critical + * Alert Threshold. + */ + if (in->under_temp_warn_thresh <= + alert_config->under_temp_crit_alert_thresh) { + return CXL_MBOX_INVALID_INPUT; + } + alert_config->under_temp_warn_thresh = in->under_temp_warn_thresh; + alert_config->enable_alerts |= CXL_ALERTS_UNDER_TEMP_WARN_THRESH; + } + + if (in->valid_alert_actions & CXL_ALERTS_COR_VMEM_ERR_WARN_THRESH) { + alert_config->cor_vmem_err_warn_thresh = in->cor_vmem_err_warn_thresh; + alert_config->enable_alerts |= CXL_ALERTS_COR_VMEM_ERR_WARN_THRESH; + } + + if (in->valid_alert_actions & CXL_ALERTS_COR_PMEM_ERR_WARN_THRESH) { + alert_config->cor_pmem_err_warn_thresh = in->cor_pmem_err_warn_thresh; + alert_config->enable_alerts |= CXL_ALERTS_COR_PMEM_ERR_WARN_THRESH; + } + return CXL_MBOX_SUCCESS; +} + /* Perform the actual device zeroing */ static void __do_sanitization(CXLType3Dev *ct3d) { @@ -1553,34 +1739,10 @@ static void __do_sanitization(CXLType3Dev *ct3d) cxl_discard_all_event_records(&ct3d->cxl_dstate); } -/* - * CXL r3.1 Section 8.2.9.9.5.1: Sanitize (Opcode 4400h) - * - * Once the Sanitize command has started successfully, the device shall be - * placed in the media disabled state. If the command fails or is interrupted - * by a reset or power failure, it shall remain in the media disabled state - * until a successful Sanitize command has been completed. During this state: - * - * 1. Memory writes to the device will have no effect, and all memory reads - * will return random values (no user data returned, even for locations that - * the failed Sanitize operation didn’t sanitize yet). - * - * 2. Mailbox commands shall still be processed in the disabled state, except - * that commands that access Sanitized areas shall fail with the Media Disabled - * error code. - */ -static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd, - uint8_t *payload_in, - size_t len_in, - uint8_t *payload_out, - size_t *len_out, - CXLCCI *cci) +static int get_sanitize_duration(uint64_t total_mem) { - CXLType3Dev *ct3d = CXL_TYPE3(cci->d); - uint64_t total_mem; /* in Mb */ - int secs; + int secs = 0; - total_mem = (ct3d->cxl_dstate.vmem_size + ct3d->cxl_dstate.pmem_size) >> 20; if (total_mem <= 512) { secs = 4; } else if (total_mem <= 1024) { @@ -1609,6 +1771,39 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd, secs = 240 * 60; /* max 4 hrs */ } + return secs; +} + +/* + * CXL r3.1 Section 8.2.9.9.5.1: Sanitize (Opcode 4400h) + * + * Once the Sanitize command has started successfully, the device shall be + * placed in the media disabled state. If the command fails or is interrupted + * by a reset or power failure, it shall remain in the media disabled state + * until a successful Sanitize command has been completed. During this state: + * + * 1. Memory writes to the device will have no effect, and all memory reads + * will return random values (no user data returned, even for locations that + * the failed Sanitize operation didn’t sanitize yet). + * + * 2. Mailbox commands shall still be processed in the disabled state, except + * that commands that access Sanitized areas shall fail with the Media Disabled + * error code. + */ +static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); + uint64_t total_mem; /* in Mb */ + int secs; + + total_mem = (ct3d->cxl_dstate.vmem_size + ct3d->cxl_dstate.pmem_size) >> 20; + secs = get_sanitize_duration(total_mem); + /* EBUSY other bg cmds as of now */ cci->bg.runtime = secs * 1000UL; *len_out = 0; @@ -1619,6 +1814,324 @@ static CXLRetCode cmd_sanitize_overwrite(const struct cxl_cmd *cmd, return CXL_MBOX_BG_STARTED; } +struct dpa_range_list_entry { + uint64_t starting_dpa; + uint64_t length; +} QEMU_PACKED; + +struct CXLSanitizeInfo { + uint32_t dpa_range_count; + uint8_t fill_value; + struct dpa_range_list_entry dpa_range_list[]; +} QEMU_PACKED; + +static uint64_t get_vmr_size(CXLType3Dev *ct3d, MemoryRegion **vmr) +{ + MemoryRegion *mr; + if (ct3d->hostvmem) { + mr = host_memory_backend_get_memory(ct3d->hostvmem); + if (vmr) { + *vmr = mr; + } + return memory_region_size(mr); + } + return 0; +} + +static uint64_t get_pmr_size(CXLType3Dev *ct3d, MemoryRegion **pmr) +{ + MemoryRegion *mr; + if (ct3d->hostpmem) { + mr = host_memory_backend_get_memory(ct3d->hostpmem); + if (pmr) { + *pmr = mr; + } + return memory_region_size(mr); + } + return 0; +} + +static uint64_t get_dc_size(CXLType3Dev *ct3d, MemoryRegion **dc_mr) +{ + MemoryRegion *mr; + if (ct3d->dc.host_dc) { + mr = host_memory_backend_get_memory(ct3d->dc.host_dc); + if (dc_mr) { + *dc_mr = mr; + } + return memory_region_size(mr); + } + return 0; +} + +static int validate_dpa_addr(CXLType3Dev *ct3d, uint64_t dpa_addr, + size_t length) +{ + uint64_t vmr_size, pmr_size, dc_size; + + if ((dpa_addr % CXL_CACHE_LINE_SIZE) || + (length % CXL_CACHE_LINE_SIZE) || + (length <= 0)) { + return -EINVAL; + } + + vmr_size = get_vmr_size(ct3d, NULL); + pmr_size = get_pmr_size(ct3d, NULL); + dc_size = get_dc_size(ct3d, NULL); + + if (dpa_addr + length > vmr_size + pmr_size + dc_size) { + return -EINVAL; + } + + if (dpa_addr > vmr_size + pmr_size) { + if (!ct3_test_region_block_backed(ct3d, dpa_addr, length)) { + return -ENODEV; + } + } + + return 0; +} + +static int sanitize_range(CXLType3Dev *ct3d, uint64_t dpa_addr, size_t length, + uint8_t fill_value) +{ + + uint64_t vmr_size, pmr_size; + AddressSpace *as = NULL; + MemTxAttrs mem_attrs = {}; + + vmr_size = get_vmr_size(ct3d, NULL); + pmr_size = get_pmr_size(ct3d, NULL); + + if (dpa_addr < vmr_size) { + as = &ct3d->hostvmem_as; + } else if (dpa_addr < vmr_size + pmr_size) { + as = &ct3d->hostpmem_as; + } else { + if (!ct3_test_region_block_backed(ct3d, dpa_addr, length)) { + return -ENODEV; + } + as = &ct3d->dc.host_dc_as; + } + + return address_space_set(as, dpa_addr, fill_value, length, mem_attrs); +} + +/* Perform the actual device zeroing */ +static void __do_sanitize(CXLType3Dev *ct3d) +{ + struct CXLSanitizeInfo *san_info = ct3d->media_op_sanitize; + int dpa_range_count = san_info->dpa_range_count; + int rc = 0; + int i; + + for (i = 0; i < dpa_range_count; i++) { + rc = sanitize_range(ct3d, san_info->dpa_range_list[i].starting_dpa, + san_info->dpa_range_list[i].length, + san_info->fill_value); + if (rc) { + goto exit; + } + } +exit: + g_free(ct3d->media_op_sanitize); + ct3d->media_op_sanitize = NULL; + return; +} + +enum { + MEDIA_OP_CLASS_GENERAL = 0x0, + #define MEDIA_OP_GEN_SUBC_DISCOVERY 0x0 + MEDIA_OP_CLASS_SANITIZE = 0x1, + #define MEDIA_OP_SAN_SUBC_SANITIZE 0x0 + #define MEDIA_OP_SAN_SUBC_ZERO 0x1 +}; + +struct media_op_supported_list_entry { + uint8_t media_op_class; + uint8_t media_op_subclass; +}; + +struct media_op_discovery_out_pl { + uint64_t dpa_range_granularity; + uint16_t total_supported_operations; + uint16_t num_of_supported_operations; + struct media_op_supported_list_entry entry[]; +} QEMU_PACKED; + +static const struct media_op_supported_list_entry media_op_matrix[] = { + { MEDIA_OP_CLASS_GENERAL, MEDIA_OP_GEN_SUBC_DISCOVERY }, + { MEDIA_OP_CLASS_SANITIZE, MEDIA_OP_SAN_SUBC_SANITIZE }, + { MEDIA_OP_CLASS_SANITIZE, MEDIA_OP_SAN_SUBC_ZERO }, +}; + +static CXLRetCode media_operations_discovery(uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out) +{ + struct { + uint8_t media_operation_class; + uint8_t media_operation_subclass; + uint8_t rsvd[2]; + uint32_t dpa_range_count; + struct { + uint16_t start_index; + uint16_t num_ops; + } discovery_osa; + } QEMU_PACKED *media_op_in_disc_pl = (void *)payload_in; + struct media_op_discovery_out_pl *media_out_pl = + (struct media_op_discovery_out_pl *)payload_out; + int num_ops, start_index, i; + int count = 0; + + if (len_in < sizeof(*media_op_in_disc_pl)) { + return CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + num_ops = media_op_in_disc_pl->discovery_osa.num_ops; + start_index = media_op_in_disc_pl->discovery_osa.start_index; + + /* + * As per spec CXL r3.2 8.2.10.9.5.3 dpa_range_count should be zero and + * start index should not exceed the total number of entries for discovery + * sub class command. + */ + if (media_op_in_disc_pl->dpa_range_count || + start_index > ARRAY_SIZE(media_op_matrix)) { + return CXL_MBOX_INVALID_INPUT; + } + + media_out_pl->dpa_range_granularity = CXL_CACHE_LINE_SIZE; + media_out_pl->total_supported_operations = + ARRAY_SIZE(media_op_matrix); + if (num_ops > 0) { + for (i = start_index; i < start_index + num_ops; i++) { + media_out_pl->entry[count].media_op_class = + media_op_matrix[i].media_op_class; + media_out_pl->entry[count].media_op_subclass = + media_op_matrix[i].media_op_subclass; + count++; + if (count == num_ops) { + break; + } + } + } + + media_out_pl->num_of_supported_operations = count; + *len_out = sizeof(*media_out_pl) + count * sizeof(*media_out_pl->entry); + return CXL_MBOX_SUCCESS; +} + +static CXLRetCode media_operations_sanitize(CXLType3Dev *ct3d, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + uint8_t fill_value, + CXLCCI *cci) +{ + struct media_operations_sanitize { + uint8_t media_operation_class; + uint8_t media_operation_subclass; + uint8_t rsvd[2]; + uint32_t dpa_range_count; + struct dpa_range_list_entry dpa_range_list[]; + } QEMU_PACKED *media_op_in_sanitize_pl = (void *)payload_in; + uint32_t dpa_range_count = media_op_in_sanitize_pl->dpa_range_count; + uint64_t total_mem = 0; + size_t dpa_range_list_size; + int secs = 0, i; + + if (dpa_range_count == 0) { + return CXL_MBOX_SUCCESS; + } + + dpa_range_list_size = dpa_range_count * sizeof(struct dpa_range_list_entry); + if (len_in < (sizeof(*media_op_in_sanitize_pl) + dpa_range_list_size)) { + return CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + for (i = 0; i < dpa_range_count; i++) { + uint64_t start_dpa = + media_op_in_sanitize_pl->dpa_range_list[i].starting_dpa; + uint64_t length = media_op_in_sanitize_pl->dpa_range_list[i].length; + + if (validate_dpa_addr(ct3d, start_dpa, length)) { + return CXL_MBOX_INVALID_INPUT; + } + total_mem += length; + } + ct3d->media_op_sanitize = g_malloc0(sizeof(struct CXLSanitizeInfo) + + dpa_range_list_size); + + ct3d->media_op_sanitize->dpa_range_count = dpa_range_count; + ct3d->media_op_sanitize->fill_value = fill_value; + memcpy(ct3d->media_op_sanitize->dpa_range_list, + media_op_in_sanitize_pl->dpa_range_list, + dpa_range_list_size); + secs = get_sanitize_duration(total_mem >> 20); + + /* EBUSY other bg cmds as of now */ + cci->bg.runtime = secs * 1000UL; + *len_out = 0; + /* + * media op sanitize is targeted so no need to disable media or + * clear event logs + */ + return CXL_MBOX_BG_STARTED; +} + +static CXLRetCode cmd_media_operations(const struct cxl_cmd *cmd, + uint8_t *payload_in, + size_t len_in, + uint8_t *payload_out, + size_t *len_out, + CXLCCI *cci) +{ + struct { + uint8_t media_operation_class; + uint8_t media_operation_subclass; + uint8_t rsvd[2]; + uint32_t dpa_range_count; + } QEMU_PACKED *media_op_in_common_pl = (void *)payload_in; + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); + uint8_t media_op_cl = 0; + uint8_t media_op_subclass = 0; + + if (len_in < sizeof(*media_op_in_common_pl)) { + return CXL_MBOX_INVALID_PAYLOAD_LENGTH; + } + + media_op_cl = media_op_in_common_pl->media_operation_class; + media_op_subclass = media_op_in_common_pl->media_operation_subclass; + + switch (media_op_cl) { + case MEDIA_OP_CLASS_GENERAL: + if (media_op_subclass != MEDIA_OP_GEN_SUBC_DISCOVERY) { + return CXL_MBOX_UNSUPPORTED; + } + + return media_operations_discovery(payload_in, len_in, payload_out, + len_out); + case MEDIA_OP_CLASS_SANITIZE: + switch (media_op_subclass) { + case MEDIA_OP_SAN_SUBC_SANITIZE: + return media_operations_sanitize(ct3d, payload_in, len_in, + payload_out, len_out, 0xF, + cci); + case MEDIA_OP_SAN_SUBC_ZERO: + return media_operations_sanitize(ct3d, payload_in, len_in, + payload_out, len_out, 0, + cci); + default: + return CXL_MBOX_UNSUPPORTED; + } + default: + return CXL_MBOX_UNSUPPORTED; + } +} + static CXLRetCode cmd_get_security_state(const struct cxl_cmd *cmd, uint8_t *payload_in, size_t len_in, @@ -2715,6 +3228,8 @@ static CXLRetCode cmd_dcd_release_dyn_cap(const struct cxl_cmd *cmd, } static const struct cxl_cmd cxl_cmd_set[256][256] = { + [INFOSTAT][BACKGROUND_OPERATION_ABORT] = { "BACKGROUND_OPERATION_ABORT", + cmd_infostat_bg_op_abort, 0, 0 }, [EVENTS][GET_RECORDS] = { "EVENTS_GET_RECORDS", cmd_events_get_records, 1, 0 }, [EVENTS][CLEAR_RECORDS] = { "EVENTS_CLEAR_RECORDS", @@ -2727,9 +3242,11 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { [FIRMWARE_UPDATE][GET_INFO] = { "FIRMWARE_UPDATE_GET_INFO", cmd_firmware_update_get_info, 0, 0 }, [FIRMWARE_UPDATE][TRANSFER] = { "FIRMWARE_UPDATE_TRANSFER", - cmd_firmware_update_transfer, ~0, CXL_MBOX_BACKGROUND_OPERATION }, + cmd_firmware_update_transfer, ~0, + CXL_MBOX_BACKGROUND_OPERATION | CXL_MBOX_BACKGROUND_OPERATION_ABORT }, [FIRMWARE_UPDATE][ACTIVATE] = { "FIRMWARE_UPDATE_ACTIVATE", - cmd_firmware_update_activate, 2, CXL_MBOX_BACKGROUND_OPERATION }, + cmd_firmware_update_activate, 2, + CXL_MBOX_BACKGROUND_OPERATION | CXL_MBOX_BACKGROUND_OPERATION_ABORT }, [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 }, [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8, CXL_MBOX_IMMEDIATE_POLICY_CHANGE }, @@ -2755,9 +3272,20 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { [CCLS][GET_LSA] = { "CCLS_GET_LSA", cmd_ccls_get_lsa, 8, 0 }, [CCLS][SET_LSA] = { "CCLS_SET_LSA", cmd_ccls_set_lsa, ~0, CXL_MBOX_IMMEDIATE_CONFIG_CHANGE | CXL_MBOX_IMMEDIATE_DATA_CHANGE }, + [HEALTH_INFO_ALERTS][GET_ALERT_CONFIG] = { + "HEALTH_INFO_ALERTS_GET_ALERT_CONFIG", + cmd_get_alert_config, 0, 0 }, + [HEALTH_INFO_ALERTS][SET_ALERT_CONFIG] = { + "HEALTH_INFO_ALERTS_SET_ALERT_CONFIG", + cmd_set_alert_config, 12, CXL_MBOX_IMMEDIATE_POLICY_CHANGE }, [SANITIZE][OVERWRITE] = { "SANITIZE_OVERWRITE", cmd_sanitize_overwrite, 0, (CXL_MBOX_IMMEDIATE_DATA_CHANGE | CXL_MBOX_SECURITY_STATE_CHANGE | + CXL_MBOX_BACKGROUND_OPERATION | + CXL_MBOX_BACKGROUND_OPERATION_ABORT)}, + [SANITIZE][MEDIA_OPERATIONS] = { "MEDIA_OPERATIONS", cmd_media_operations, + ~0, + (CXL_MBOX_IMMEDIATE_DATA_CHANGE | CXL_MBOX_BACKGROUND_OPERATION)}, [PERSISTENT_MEM][GET_SECURITY_STATE] = { "GET_SECURITY_STATE", cmd_get_security_state, 0, 0 }, @@ -2771,7 +3299,8 @@ static const struct cxl_cmd cxl_cmd_set[256][256] = { "MEDIA_AND_POISON_GET_SCAN_MEDIA_CAPABILITIES", cmd_media_get_scan_media_capabilities, 16, 0 }, [MEDIA_AND_POISON][SCAN_MEDIA] = { "MEDIA_AND_POISON_SCAN_MEDIA", - cmd_media_scan_media, 17, CXL_MBOX_BACKGROUND_OPERATION }, + cmd_media_scan_media, 17, + (CXL_MBOX_BACKGROUND_OPERATION | CXL_MBOX_BACKGROUND_OPERATION_ABORT)}, [MEDIA_AND_POISON][GET_SCAN_MEDIA_RESULTS] = { "MEDIA_AND_POISON_GET_SCAN_MEDIA_RESULTS", cmd_media_get_scan_media_results, 0, 0 }, @@ -2795,6 +3324,8 @@ static const struct cxl_cmd cxl_cmd_set_sw[256][256] = { [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 0 }, [INFOSTAT][BACKGROUND_OPERATION_STATUS] = { "BACKGROUND_OPERATION_STATUS", cmd_infostat_bg_op_sts, 0, 0 }, + [INFOSTAT][BACKGROUND_OPERATION_ABORT] = { "BACKGROUND_OPERATION_ABORT", + cmd_infostat_bg_op_abort, 0, 0 }, [TIMESTAMP][GET] = { "TIMESTAMP_GET", cmd_timestamp_get, 0, 0 }, [TIMESTAMP][SET] = { "TIMESTAMP_SET", cmd_timestamp_set, 8, CXL_MBOX_IMMEDIATE_POLICY_CHANGE }, @@ -2881,6 +3412,7 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd, cci->bg.opcode = (set << 8) | cmd; cci->bg.complete_pct = 0; + cci->bg.aborted = false; cci->bg.ret_code = 0; now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); @@ -2894,10 +3426,12 @@ int cxl_process_cci_message(CXLCCI *cci, uint8_t set, uint8_t cmd, static void bg_timercb(void *opaque) { CXLCCI *cci = opaque; - uint64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); - uint64_t total_time = cci->bg.starttime + cci->bg.runtime; + uint64_t now, total_time; - assert(cci->bg.runtime > 0); + qemu_mutex_lock(&cci->bg.lock); + + now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + total_time = cci->bg.starttime + cci->bg.runtime; if (now >= total_time) { /* we are done */ uint16_t ret = CXL_MBOX_SUCCESS; @@ -2916,6 +3450,12 @@ static void bg_timercb(void *opaque) cxl_dev_enable_media(&ct3d->cxl_dstate); } break; + case 0x4402: /* Media Operations sanitize */ + { + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); + __do_sanitize(ct3d); + } + break; case 0x4304: /* scan media */ { CXLType3Dev *ct3d = CXL_TYPE3(cci->d); @@ -2950,6 +3490,8 @@ static void bg_timercb(void *opaque) msi_notify(pdev, cxl_dstate->mbox_msi_n); } } + + qemu_mutex_unlock(&cci->bg.lock); } static void cxl_rebuild_cel(CXLCCI *cci) @@ -2978,12 +3520,21 @@ void cxl_init_cci(CXLCCI *cci, size_t payload_max) cci->bg.complete_pct = 0; cci->bg.starttime = 0; cci->bg.runtime = 0; + cci->bg.aborted = false; cci->bg.timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, bg_timercb, cci); + qemu_mutex_init(&cci->bg.lock); memset(&cci->fw, 0, sizeof(cci->fw)); cci->fw.active_slot = 1; cci->fw.slot[cci->fw.active_slot - 1] = true; + cci->initialized = true; +} + +void cxl_destroy_cci(CXLCCI *cci) +{ + qemu_mutex_destroy(&cci->bg.lock); + cci->initialized = false; } static void cxl_copy_cci_commands(CXLCCI *cci, const struct cxl_cmd (*cxl_cmds)[256]) @@ -3047,6 +3598,10 @@ void cxl_initialize_t3_ld_cci(CXLCCI *cci, DeviceState *d, DeviceState *intf, static const struct cxl_cmd cxl_cmd_set_t3_fm_owned_ld_mctp[256][256] = { [INFOSTAT][IS_IDENTIFY] = { "IDENTIFY", cmd_infostat_identify, 0, 0}, + [INFOSTAT][GET_RESPONSE_MSG_LIMIT] = { "GET_RESPONSE_MSG_LIMIT", + cmd_get_response_msg_limit, 0, 0 }, + [INFOSTAT][SET_RESPONSE_MSG_LIMIT] = { "SET_RESPONSE_MSG_LIMIT", + cmd_set_response_msg_limit, 1, 0 }, [LOGS][GET_SUPPORTED] = { "LOGS_GET_SUPPORTED", cmd_logs_get_supported, 0, 0 }, [LOGS][GET_LOG] = { "LOGS_GET_LOG", cmd_logs_get_log, 0x18, 0 }, diff --git a/hw/cxl/switch-mailbox-cci.c b/hw/cxl/switch-mailbox-cci.c index 833b824..223f220 100644 --- a/hw/cxl/switch-mailbox-cci.c +++ b/hw/cxl/switch-mailbox-cci.c @@ -72,7 +72,7 @@ static const Property cxl_switch_cci_props[] = { target, TYPE_CXL_USP, PCIDevice *), }; -static void cswmbcci_class_init(ObjectClass *oc, void *data) +static void cswmbcci_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); @@ -99,7 +99,7 @@ static const TypeInfo cswmbcci_info = { .parent = TYPE_PCI_DEVICE, .class_init = cswmbcci_class_init, .instance_size = sizeof(CSWMBCCIDev), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/display/apple-gfx-mmio.m b/hw/display/apple-gfx-mmio.m index b2e0e7a..b0b6e29 100644 --- a/hw/display/apple-gfx-mmio.m +++ b/hw/display/apple-gfx-mmio.m @@ -261,7 +261,7 @@ static const Property apple_gfx_mmio_properties[] = { qdev_prop_apple_gfx_display_mode, AppleGFXDisplayMode), }; -static void apple_gfx_mmio_class_init(ObjectClass *klass, void *data) +static void apple_gfx_mmio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/display/apple-gfx-pci.m b/hw/display/apple-gfx-pci.m index b939bb9..b0694f4 100644 --- a/hw/display/apple-gfx-pci.m +++ b/hw/display/apple-gfx-pci.m @@ -121,7 +121,7 @@ static const Property apple_gfx_pci_properties[] = { qdev_prop_apple_gfx_display_mode, AppleGFXDisplayMode), }; -static void apple_gfx_pci_class_init(ObjectClass *klass, void *data) +static void apple_gfx_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pci = PCI_DEVICE_CLASS(klass); @@ -147,7 +147,7 @@ static const TypeInfo apple_gfx_pci_types[] = { .instance_size = sizeof(AppleGFXPCIState), .class_init = apple_gfx_pci_class_init, .instance_init = apple_gfx_pci_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { }, }, diff --git a/hw/display/apple-gfx.h b/hw/display/apple-gfx.h index 3900cdb..a8b1d1e 100644 --- a/hw/display/apple-gfx.h +++ b/hw/display/apple-gfx.h @@ -9,7 +9,7 @@ #define QEMU_APPLE_GFX_H #include "qemu/queue.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/qdev-properties.h" #include "ui/surface.h" diff --git a/hw/display/apple-gfx.m b/hw/display/apple-gfx.m index c432357..174d56a 100644 --- a/hw/display/apple-gfx.m +++ b/hw/display/apple-gfx.m @@ -18,7 +18,7 @@ #include "qapi/visitor.h" #include "qapi/error.h" #include "block/aio-wait.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/dma.h" #include "migration/blocker.h" #include "ui/console.h" @@ -69,7 +69,7 @@ struct PGTask_s { mach_vm_address_t address; uint64_t len; /* - * All unique MemoryRegions for which a mapping has been created in in this + * All unique MemoryRegions for which a mapping has been created in this * task, and on which we have thus called memory_region_ref(). There are * usually very few regions of system RAM in total, so we expect this array * to be very short. Therefore, no need for sorting or fancy search @@ -454,7 +454,7 @@ static void set_cursor_glyph(void *opaque) /* ------ DMA (device reading system memory) ------ */ typedef struct AppleGFXReadMemoryJob { - QemuSemaphore sem; + QemuEvent event; hwaddr physical_address; uint64_t length; void *dst; @@ -470,7 +470,7 @@ static void apple_gfx_do_read_memory(void *opaque) job->dst, job->length, MEMTXATTRS_UNSPECIFIED); job->success = (r == MEMTX_OK); - qemu_sem_post(&job->sem); + qemu_event_set(&job->event); } static bool apple_gfx_read_memory(AppleGFXState *s, hwaddr physical_address, @@ -483,11 +483,11 @@ static bool apple_gfx_read_memory(AppleGFXState *s, hwaddr physical_address, trace_apple_gfx_read_memory(physical_address, length, dst); /* Performing DMA requires BQL, so do it in a BH. */ - qemu_sem_init(&job.sem, 0); + qemu_event_init(&job.event, 0); aio_bh_schedule_oneshot(qemu_get_aio_context(), apple_gfx_do_read_memory, &job); - qemu_sem_wait(&job.sem); - qemu_sem_destroy(&job.sem); + qemu_event_wait(&job.event); + qemu_event_destroy(&job.event); return job.success; } diff --git a/hw/display/artist.c b/hw/display/artist.c index f24c1d8..3fafc8a 100644 --- a/hw/display/artist.c +++ b/hw/display/artist.c @@ -1487,7 +1487,7 @@ static void artist_reset(DeviceState *qdev) { } -static void artist_class_init(ObjectClass *klass, void *data) +static void artist_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/ati.c b/hw/display/ati.c index 864fa4f..7de2773 100644 --- a/hw/display/ati.c +++ b/hw/display/ati.c @@ -1049,7 +1049,7 @@ static const Property ati_vga_properties[] = { DEFINE_PROP_UINT8("x-pixman", ATIVGAState, use_pixman, DEFAULT_X_PIXMAN), }; -static void ati_vga_class_init(ObjectClass *klass, void *data) +static void ati_vga_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1079,7 +1079,7 @@ static const TypeInfo ati_vga_info = { .instance_size = sizeof(ATIVGAState), .class_init = ati_vga_class_init, .instance_init = ati_vga_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c index a5bded5..820e67a 100644 --- a/hw/display/bcm2835_fb.c +++ b/hw/display/bcm2835_fb.c @@ -442,7 +442,7 @@ static const Property bcm2835_fb_props[] = { initial_config.alpha, 2), /* alpha ignored */ }; -static void bcm2835_fb_class_init(ObjectClass *klass, void *data) +static void bcm2835_fb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c index 086f7a0..ad2821c 100644 --- a/hw/display/bochs-display.c +++ b/hw/display/bochs-display.c @@ -351,7 +351,7 @@ static const Property bochs_display_properties[] = { DEFINE_EDID_PROPERTIES(BochsDisplayState, edid_info), }; -static void bochs_display_class_init(ObjectClass *klass, void *data) +static void bochs_display_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -374,7 +374,7 @@ static const TypeInfo bochs_display_type_info = { .instance_size = sizeof(BochsDisplayState), .instance_init = bochs_display_init, .class_init = bochs_display_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, diff --git a/hw/display/cg3.c b/hw/display/cg3.c index 3f971d8..daeef15 100644 --- a/hw/display/cg3.c +++ b/hw/display/cg3.c @@ -368,7 +368,7 @@ static const Property cg3_properties[] = { DEFINE_PROP_UINT16("depth", CG3State, depth, -1), }; -static void cg3_class_init(ObjectClass *klass, void *data) +static void cg3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c index 76124d3..ef08694 100644 --- a/hw/display/cirrus_vga.c +++ b/hw/display/cirrus_vga.c @@ -2991,7 +2991,7 @@ static const Property pci_vga_cirrus_properties[] = { cirrus_vga.vga.global_vmstate, false), }; -static void cirrus_vga_class_init(ObjectClass *klass, void *data) +static void cirrus_vga_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -3013,7 +3013,7 @@ static const TypeInfo cirrus_vga_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCICirrusVGAState), .class_init = cirrus_vga_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/display/cirrus_vga_isa.c b/hw/display/cirrus_vga_isa.c index 60b7fd2..4b55c48 100644 --- a/hw/display/cirrus_vga_isa.c +++ b/hw/display/cirrus_vga_isa.c @@ -76,7 +76,7 @@ static const Property isa_cirrus_vga_properties[] = { cirrus_vga.enable_blitter, true), }; -static void isa_cirrus_vga_class_init(ObjectClass *klass, void *data) +static void isa_cirrus_vga_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/dm163.c b/hw/display/dm163.c index f6f0ec0..f8340d8 100644 --- a/hw/display/dm163.c +++ b/hw/display/dm163.c @@ -325,7 +325,7 @@ static void dm163_realize(DeviceState *dev, Error **errp) RGB_MATRIX_NUM_ROWS * LED_SQUARE_SIZE); } -static void dm163_class_init(ObjectClass *klass, void *data) +static void dm163_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/display/dpcd.c b/hw/display/dpcd.c index 108faf7..a157dc6 100644 --- a/hw/display/dpcd.c +++ b/hw/display/dpcd.c @@ -141,7 +141,7 @@ static const VMStateDescription vmstate_dpcd = { } }; -static void dpcd_class_init(ObjectClass *oc, void *data) +static void dpcd_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/display/edid-region.c b/hw/display/edid-region.c index 675429d..f1596fb 100644 --- a/hw/display/edid-region.c +++ b/hw/display/edid-region.c @@ -1,5 +1,5 @@ #include "qemu/osdep.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/display/edid.h" static uint64_t edid_region_read(void *ptr, hwaddr addr, unsigned size) diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c index 04c864a..c61e028 100644 --- a/hw/display/exynos4210_fimd.c +++ b/hw/display/exynos4210_fimd.c @@ -1958,7 +1958,7 @@ static void exynos4210_fimd_realize(DeviceState *dev, Error **errp) s->console = graphic_console_init(dev, 0, &exynos4210_fimd_ops, s); } -static void exynos4210_fimd_class_init(ObjectClass *klass, void *data) +static void exynos4210_fimd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/framebuffer.h b/hw/display/framebuffer.h index 38fa0dc..29a828c 100644 --- a/hw/display/framebuffer.h +++ b/hw/display/framebuffer.h @@ -1,7 +1,7 @@ #ifndef QEMU_FRAMEBUFFER_H #define QEMU_FRAMEBUFFER_H -#include "exec/memory.h" +#include "system/memory.h" /* Framebuffer device helper routines. */ diff --git a/hw/display/g364fb.c b/hw/display/g364fb.c index 30b5ea6..a6ddc21 100644 --- a/hw/display/g364fb.c +++ b/hw/display/g364fb.c @@ -526,7 +526,7 @@ static const VMStateDescription vmstate_g364fb_sysbus = { } }; -static void g364fb_sysbus_class_init(ObjectClass *klass, void *data) +static void g364fb_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/i2c-ddc.c b/hw/display/i2c-ddc.c index d8ab9ee..2adfc1a 100644 --- a/hw/display/i2c-ddc.c +++ b/hw/display/i2c-ddc.c @@ -99,7 +99,7 @@ static const Property i2c_ddc_properties[] = { DEFINE_EDID_PROPERTIES(I2CDDCState, edid_info), }; -static void i2c_ddc_class_init(ObjectClass *oc, void *data) +static void i2c_ddc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc); diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c index 1448488..90e82b5 100644 --- a/hw/display/jazz_led.c +++ b/hw/display/jazz_led.c @@ -294,7 +294,7 @@ static void jazz_led_reset(DeviceState *d) qemu_console_resize(s->con, 60, 80); } -static void jazz_led_class_init(ObjectClass *klass, void *data) +static void jazz_led_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/macfb.c b/hw/display/macfb.c index b08eb06..574d667 100644 --- a/hw/display/macfb.c +++ b/hw/display/macfb.c @@ -793,7 +793,7 @@ static const VMStateDescription vmstate_macfb_nubus = { } }; -static void macfb_sysbus_class_init(ObjectClass *klass, void *data) +static void macfb_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -804,7 +804,7 @@ static void macfb_sysbus_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, macfb_sysbus_properties); } -static void macfb_nubus_class_init(ObjectClass *klass, void *data) +static void macfb_nubus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); MacfbNubusDeviceClass *ndc = NUBUS_MACFB_CLASS(klass); diff --git a/hw/display/next-fb.c b/hw/display/next-fb.c index 8446ff3..ec81b76 100644 --- a/hw/display/next-fb.c +++ b/hw/display/next-fb.c @@ -119,7 +119,7 @@ static void nextfb_realize(DeviceState *dev, Error **errp) qemu_console_resize(s->con, s->cols, s->rows); } -static void nextfb_class_init(ObjectClass *oc, void *data) +static void nextfb_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/display/pl110.c b/hw/display/pl110.c index 4d4f477..09c3c59 100644 --- a/hw/display/pl110.c +++ b/hw/display/pl110.c @@ -580,7 +580,7 @@ static void pl111_init(Object *obj) s->version = VERSION_PL111; } -static void pl110_class_init(ObjectClass *klass, void *data) +static void pl110_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/qxl.c b/hw/display/qxl.c index da14da5..18f482c 100644 --- a/hw/display/qxl.c +++ b/hw/display/qxl.c @@ -2498,7 +2498,7 @@ static const Property qxl_properties[] = { DEFINE_PROP_BOOL("global-vmstate", PCIQXLDevice, vga.global_vmstate, false), }; -static void qxl_pci_class_init(ObjectClass *klass, void *data) +static void qxl_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -2517,13 +2517,13 @@ static const TypeInfo qxl_pci_type_info = { .instance_size = sizeof(PCIQXLDevice), .abstract = true, .class_init = qxl_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void qxl_primary_class_init(ObjectClass *klass, void *data) +static void qxl_primary_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -2543,7 +2543,7 @@ static const TypeInfo qxl_primary_info = { module_obj("qxl-vga"); module_kconfig(QXL); -static void qxl_secondary_class_init(ObjectClass *klass, void *data) +static void qxl_secondary_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/display/ramfb-standalone.c b/hw/display/ramfb-standalone.c index 1be106b..08f2d5d 100644 --- a/hw/display/ramfb-standalone.c +++ b/hw/display/ramfb-standalone.c @@ -64,7 +64,7 @@ static const Property ramfb_properties[] = { DEFINE_PROP_BOOL("x-migrate", RAMFBStandaloneState, migrate, true), }; -static void ramfb_class_initfn(ObjectClass *klass, void *data) +static void ramfb_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c index 16f8cb4..d00d3e9 100644 --- a/hw/display/sii9022.c +++ b/hw/display/sii9022.c @@ -167,7 +167,7 @@ static void sii9022_realize(DeviceState *dev, Error **errp) i2c_slave_create_simple(bus, TYPE_I2CDDC, 0x50); } -static void sii9022_class_init(ObjectClass *klass, void *data) +static void sii9022_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/display/sm501.c b/hw/display/sm501.c index 09edcf8..6d2f186 100644 --- a/hw/display/sm501.c +++ b/hw/display/sm501.c @@ -2077,7 +2077,7 @@ static const VMStateDescription vmstate_sm501_sysbus = { } }; -static void sm501_sysbus_class_init(ObjectClass *klass, void *data) +static void sm501_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2167,7 +2167,7 @@ static const VMStateDescription vmstate_sm501_pci = { } }; -static void sm501_pci_class_init(ObjectClass *klass, void *data) +static void sm501_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -2196,7 +2196,7 @@ static const TypeInfo sm501_pci_info = { .instance_size = sizeof(SM501PCIState), .class_init = sm501_pci_class_init, .instance_init = sm501_pci_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/display/ssd0303.c b/hw/display/ssd0303.c index e292cff..8778143 100644 --- a/hw/display/ssd0303.c +++ b/hw/display/ssd0303.c @@ -311,7 +311,7 @@ static void ssd0303_realize(DeviceState *dev, Error **errp) qemu_console_resize(s->con, 96 * MAGNIFY, 16 * MAGNIFY); } -static void ssd0303_class_init(ObjectClass *klass, void *data) +static void ssd0303_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c index 96cf0dc..af5ff4f 100644 --- a/hw/display/ssd0323.c +++ b/hw/display/ssd0323.c @@ -361,7 +361,7 @@ static void ssd0323_realize(SSIPeripheral *d, Error **errp) qdev_init_gpio_in(dev, ssd0323_cd, 1); } -static void ssd0323_class_init(ObjectClass *klass, void *data) +static void ssd0323_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass); diff --git a/hw/display/tcx.c b/hw/display/tcx.c index 5968d33..4853c5e 100644 --- a/hw/display/tcx.c +++ b/hw/display/tcx.c @@ -885,7 +885,7 @@ static const Property tcx_properties[] = { DEFINE_PROP_UINT16("depth", TCXState, depth, -1), }; -static void tcx_class_init(ObjectClass *klass, void *data) +static void tcx_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/vga-isa.c b/hw/display/vga-isa.c index 2920628..3618913 100644 --- a/hw/display/vga-isa.c +++ b/hw/display/vga-isa.c @@ -92,7 +92,7 @@ static const Property vga_isa_properties[] = { DEFINE_PROP_UINT32("vgamem_mb", ISAVGAState, state.vram_size_mb, 8), }; -static void vga_isa_class_initfn(ObjectClass *klass, void *data) +static void vga_isa_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/vga-mmio.c b/hw/display/vga-mmio.c index 1e0c2db..3326385 100644 --- a/hw/display/vga-mmio.c +++ b/hw/display/vga-mmio.c @@ -116,7 +116,7 @@ static const Property vga_mmio_properties[] = { DEFINE_PROP_UINT32("vgamem_mb", VGAMmioState, vga.vram_size_mb, 8), }; -static void vga_mmio_class_initfn(ObjectClass *klass, void *data) +static void vga_mmio_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c index dd084c2..b81f7fd 100644 --- a/hw/display/vga-pci.c +++ b/hw/display/vga-pci.c @@ -350,7 +350,7 @@ static const Property secondary_pci_properties[] = { DEFINE_EDID_PROPERTIES(PCIVGAState, edid_info), }; -static void vga_pci_class_init(ObjectClass *klass, void *data) +static void vga_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -369,14 +369,14 @@ static const TypeInfo vga_pci_type_info = { .instance_size = sizeof(PCIVGAState), .abstract = true, .class_init = vga_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { TYPE_ACPI_DEV_AML_IF }, { }, }, }; -static void vga_class_init(ObjectClass *klass, void *data) +static void vga_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -392,7 +392,7 @@ static void vga_class_init(ObjectClass *klass, void *data) vga_get_big_endian_fb, vga_set_big_endian_fb); } -static void secondary_class_init(ObjectClass *klass, void *data) +static void secondary_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/display/vga.c b/hw/display/vga.c index b01f67c..20475eb 100644 --- a/hw/display/vga.c +++ b/hw/display/vga.c @@ -2264,7 +2264,7 @@ bool vga_common_init(VGACommonState *s, Object *obj, Error **errp) * into a device attribute set by the machine/platform to remove * all target endian dependencies from this file. */ - s->default_endian_fb = target_words_bigendian(); + s->default_endian_fb = target_big_endian(); s->big_endian_fb = s->default_endian_fb; vga_dirty_log_start(s); diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h index f77c1c1..747b5cc 100644 --- a/hw/display/vga_int.h +++ b/hw/display/vga_int.h @@ -26,8 +26,8 @@ #define HW_VGA_INT_H #include "ui/console.h" -#include "exec/ioport.h" -#include "exec/memory.h" +#include "system/ioport.h" +#include "system/memory.h" #include "hw/display/bochs-vbe.h" #include "hw/acpi/acpi_aml_interface.h" diff --git a/hw/display/vhost-user-gpu.c b/hw/display/vhost-user-gpu.c index 2aed624..9fc6bbc 100644 --- a/hw/display/vhost-user-gpu.c +++ b/hw/display/vhost-user-gpu.c @@ -18,6 +18,7 @@ #include "chardev/char-fe.h" #include "qapi/error.h" #include "migration/blocker.h" +#include "standard-headers/drm/drm_fourcc.h" typedef enum VhostUserGpuRequest { VHOST_USER_GPU_NONE = 0, @@ -249,7 +250,9 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) case VHOST_USER_GPU_DMABUF_SCANOUT: { VhostUserGpuDMABUFScanout *m = &msg->payload.dmabuf_scanout; int fd = qemu_chr_fe_get_msgfd(&g->vhost_chr); - uint64_t modifier = 0; + uint32_t offset = 0; + uint32_t stride = m->fd_stride; + uint64_t modifier = DRM_FORMAT_MOD_INVALID; QemuDmaBuf *dmabuf; if (m->scanout_id >= g->parent_obj.conf.max_outputs) { @@ -282,10 +285,10 @@ vhost_user_gpu_handle_display(VhostUserGPU *g, VhostUserGpuMsg *msg) } dmabuf = qemu_dmabuf_new(m->width, m->height, - m->fd_stride, 0, 0, + &offset, &stride, 0, 0, m->fd_width, m->fd_height, m->fd_drm_fourcc, modifier, - fd, false, m->fd_flags & + &fd, 1, false, m->fd_flags & VIRTIO_GPU_RESOURCE_FLAG_Y_0_TOP); dpy_gl_scanout_dmabuf(con, dmabuf); @@ -513,7 +516,7 @@ vhost_user_gpu_set_config(VirtIODevice *vdev, } } -static void +static int vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val) { VhostUserGPU *g = VHOST_USER_GPU(vdev); @@ -522,18 +525,24 @@ vhost_user_gpu_set_status(VirtIODevice *vdev, uint8_t val) if (val & VIRTIO_CONFIG_S_DRIVER_OK && vdev->vm_running) { if (!vhost_user_gpu_do_set_socket(g, &err)) { error_report_err(err); - return; + return 0; } vhost_user_backend_start(g->vhost); } else { + int ret; + /* unblock any wait and stop processing */ if (g->vhost_gpu_fd != -1) { vhost_user_gpu_update_blocked(g, true); qemu_chr_fe_deinit(&g->vhost_chr, true); g->vhost_gpu_fd = -1; } - vhost_user_backend_stop(g->vhost); + ret = vhost_user_backend_stop(g->vhost); + if (ret < 0) { + return ret; + } } + return 0; } static bool @@ -658,7 +667,7 @@ static const Property vhost_user_gpu_properties[] = { }; static void -vhost_user_gpu_class_init(ObjectClass *klass, void *data) +vhost_user_gpu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/display/virtio-gpu-base.c b/hw/display/virtio-gpu-base.c index 321a6f4..9eb806b 100644 --- a/hw/display/virtio-gpu-base.c +++ b/hw/display/virtio-gpu-base.c @@ -262,7 +262,7 @@ virtio_gpu_base_device_unrealize(DeviceState *qdev) } static void -virtio_gpu_base_class_init(ObjectClass *klass, void *data) +virtio_gpu_base_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/display/virtio-gpu-gl.c b/hw/display/virtio-gpu-gl.c index 683fad3..c06a078 100644 --- a/hw/display/virtio-gpu-gl.c +++ b/hw/display/virtio-gpu-gl.c @@ -182,7 +182,7 @@ static void virtio_gpu_gl_device_unrealize(DeviceState *qdev) g_array_unref(g->capset_ids); } -static void virtio_gpu_gl_class_init(ObjectClass *klass, void *data) +static void virtio_gpu_gl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/display/virtio-gpu-pci-rutabaga.c b/hw/display/virtio-gpu-pci-rutabaga.c index abbb898..5fdff37 100644 --- a/hw/display/virtio-gpu-pci-rutabaga.c +++ b/hw/display/virtio-gpu-pci-rutabaga.c @@ -34,7 +34,7 @@ static const TypeInfo virtio_gpu_rutabaga_pci_info[] = { .parent = TYPE_VIRTIO_GPU_PCI_BASE, .instance_size = sizeof(VirtIOGPURutabagaPCI), .instance_init = virtio_gpu_rutabaga_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, } diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c index 6d78970..c0d71b6 100644 --- a/hw/display/virtio-gpu-pci.c +++ b/hw/display/virtio-gpu-pci.c @@ -57,7 +57,7 @@ static void virtio_gpu_pci_base_realize(VirtIOPCIProxy *vpci_dev, Error **errp) } } -static void virtio_gpu_pci_base_class_init(ObjectClass *klass, void *data) +static void virtio_gpu_pci_base_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/display/virtio-gpu-rutabaga.c b/hw/display/virtio-gpu-rutabaga.c index f6eb294..ed5ae52 100644 --- a/hw/display/virtio-gpu-rutabaga.c +++ b/hw/display/virtio-gpu-rutabaga.c @@ -1110,7 +1110,7 @@ static const Property virtio_gpu_rutabaga_properties[] = { DEFINE_PROP_STRING("wsi", VirtIOGPURutabaga, wsi), }; -static void virtio_gpu_rutabaga_class_init(ObjectClass *klass, void *data) +static void virtio_gpu_rutabaga_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/display/virtio-gpu-udmabuf.c b/hw/display/virtio-gpu-udmabuf.c index 85ca23c..d804f32 100644 --- a/hw/display/virtio-gpu-udmabuf.c +++ b/hw/display/virtio-gpu-udmabuf.c @@ -19,12 +19,13 @@ #include "hw/virtio/virtio-gpu.h" #include "hw/virtio/virtio-gpu-pixman.h" #include "trace.h" -#include "exec/ramblock.h" +#include "system/ramblock.h" #include "system/hostmem.h" #include <sys/ioctl.h> #include <linux/memfd.h> #include "qemu/memfd.h" #include "standard-headers/linux/udmabuf.h" +#include "standard-headers/drm/drm_fourcc.h" static void virtio_gpu_create_udmabuf(struct virtio_gpu_simple_resource *res) { @@ -176,16 +177,19 @@ static VGPUDMABuf struct virtio_gpu_rect *r) { VGPUDMABuf *dmabuf; + uint32_t offset = 0; if (res->dmabuf_fd < 0) { return NULL; } dmabuf = g_new0(VGPUDMABuf, 1); - dmabuf->buf = qemu_dmabuf_new(r->width, r->height, fb->stride, + dmabuf->buf = qemu_dmabuf_new(r->width, r->height, + &offset, &fb->stride, r->x, r->y, fb->width, fb->height, qemu_pixman_to_drm_format(fb->format), - 0, res->dmabuf_fd, true, false); + DRM_FORMAT_MOD_INVALID, &res->dmabuf_fd, + 1, true, false); dmabuf->scanout_id = scanout_id; QTAILQ_INSERT_HEAD(&g->dmabuf.bufs, dmabuf, next); diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c index 11a7a85..0a1a625 100644 --- a/hw/display/virtio-gpu.c +++ b/hw/display/virtio-gpu.c @@ -1684,7 +1684,7 @@ static const Property virtio_gpu_properties[] = { DEFINE_PROP_UINT8("x-scanout-vmstate-version", VirtIOGPU, scanout_vmstate_version, 2), }; -static void virtio_gpu_class_init(ObjectClass *klass, void *data) +static void virtio_gpu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c index fefbdb6..40e60f7 100644 --- a/hw/display/virtio-vga.c +++ b/hw/display/virtio-vga.c @@ -213,7 +213,7 @@ static const Property virtio_vga_base_properties[] = { DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy), }; -static void virtio_vga_base_class_init(ObjectClass *klass, void *data) +static void virtio_vga_base_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c index 2dd661e..bc1a8ed 100644 --- a/hw/display/vmware_vga.c +++ b/hw/display/vmware_vga.c @@ -618,7 +618,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s) uint32_t cmd, colour; int args, len, maxloop = 1024; int x, y, dx, dy, width, height; - struct vmsvga_cursor_definition_s cursor; + QEMU_UNINITIALIZED struct vmsvga_cursor_definition_s cursor; uint32_t cmd_start; len = vmsvga_fifo_length(s); @@ -1339,7 +1339,7 @@ static const Property vga_vmware_properties[] = { chip.vga.global_vmstate, false), }; -static void vmsvga_class_init(ObjectClass *klass, void *data) +static void vmsvga_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1363,7 +1363,7 @@ static const TypeInfo vmsvga_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(struct pci_vmsvga_state_s), .class_init = vmsvga_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c index 1272da0..7c980ee 100644 --- a/hw/display/xlnx_dp.c +++ b/hw/display/xlnx_dp.c @@ -1391,7 +1391,7 @@ static const Property xlnx_dp_device_properties[] = { DEFINE_AUDIO_PROPERTIES(XlnxDPState, aud_card), }; -static void xlnx_dp_class_init(ObjectClass *oc, void *data) +static void xlnx_dp_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c index 9b2fca2..a2771dd 100644 --- a/hw/dma/bcm2835_dma.c +++ b/hw/dma/bcm2835_dma.c @@ -385,7 +385,7 @@ static void bcm2835_dma_realize(DeviceState *dev, Error **errp) bcm2835_dma_reset(dev); } -static void bcm2835_dma_class_init(ObjectClass *klass, void *data) +static void bcm2835_dma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/i82374.c b/hw/dma/i82374.c index 0bf69ef..e226eda 100644 --- a/hw/dma/i82374.c +++ b/hw/dma/i82374.c @@ -143,7 +143,7 @@ static const Property i82374_properties[] = { DEFINE_PROP_UINT32("iobase", I82374State, iobase, 0x400), }; -static void i82374_class_init(ObjectClass *klass, void *data) +static void i82374_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/i8257.c b/hw/dma/i8257.c index 74c38d2..2463952 100644 --- a/hw/dma/i8257.c +++ b/hw/dma/i8257.c @@ -592,7 +592,7 @@ static const Property i8257_properties[] = { DEFINE_PROP_INT32("dshift", I8257State, dshift, 0), }; -static void i8257_class_init(ObjectClass *klass, void *data) +static void i8257_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IsaDmaClass *idc = ISADMA_CLASS(klass); @@ -618,7 +618,7 @@ static const TypeInfo i8257_info = { .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(I8257State), .class_init = i8257_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ISADMA }, { } } diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c index 9a8c3c3..101f91f 100644 --- a/hw/dma/omap_dma.c +++ b/hw/dma/omap_dma.c @@ -131,9 +131,9 @@ struct omap_dma_s { #define LAST_FRAME_INTR (1 << 4) #define END_BLOCK_INTR (1 << 5) #define SYNC (1 << 6) -#define END_PKT_INTR (1 << 7) -#define TRANS_ERR_INTR (1 << 8) -#define MISALIGN_INTR (1 << 11) +#define END_PKT_INTR (1 << 7) +#define TRANS_ERR_INTR (1 << 8) +#define MISALIGN_INTR (1 << 11) static inline void omap_dma_interrupts_update(struct omap_dma_s *s) { @@ -526,12 +526,12 @@ static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma) /* Check all the conditions that terminate the transfer starting * with those that can occur the soonest. */ -#define INTR_CHECK(cond, id, nelements) \ - if (cond) { \ - elements[id] = nelements; \ - if (elements[id] < min_elems) \ - min_elems = elements[id]; \ - } else \ +#define INTR_CHECK(cond, id, nelements) \ + if (cond) { \ + elements[id] = nelements; \ + if (elements[id] < min_elems) \ + min_elems = elements[id]; \ + } else \ elements[id] = INT_MAX; /* Elements */ @@ -740,7 +740,7 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, struct omap_dma_channel_s *ch, int reg, uint16_t *value) { switch (reg) { - case 0x00: /* SYS_DMA_CSDP_CH0 */ + case 0x00: /* SYS_DMA_CSDP_CH0 */ *value = (ch->burst[1] << 14) | (ch->pack[1] << 13) | (ch->port[1] << 9) | @@ -750,9 +750,9 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, (ch->data_type >> 1); break; - case 0x02: /* SYS_DMA_CCR_CH0 */ + case 0x02: /* SYS_DMA_CCR_CH0 */ if (s->model <= omap_dma_3_1) - *value = 0 << 10; /* FIFO_FLUSH reads as 0 */ + *value = 0 << 10; /* FIFO_FLUSH reads as 0 */ else *value = ch->omap_3_1_compatible_disable << 10; *value |= (ch->mode[1] << 14) | @@ -765,11 +765,11 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, (ch->fs << 5) | ch->sync; break; - case 0x04: /* SYS_DMA_CICR_CH0 */ + case 0x04: /* SYS_DMA_CICR_CH0 */ *value = ch->interrupts; break; - case 0x06: /* SYS_DMA_CSR_CH0 */ + case 0x06: /* SYS_DMA_CSR_CH0 */ *value = ch->status; ch->status &= SYNC; if (!ch->omap_3_1_compatible_disable && ch->sibling) { @@ -779,77 +779,77 @@ static int omap_dma_ch_reg_read(struct omap_dma_s *s, qemu_irq_lower(ch->irq); break; - case 0x08: /* SYS_DMA_CSSA_L_CH0 */ + case 0x08: /* SYS_DMA_CSSA_L_CH0 */ *value = ch->addr[0] & 0x0000ffff; break; - case 0x0a: /* SYS_DMA_CSSA_U_CH0 */ + case 0x0a: /* SYS_DMA_CSSA_U_CH0 */ *value = ch->addr[0] >> 16; break; - case 0x0c: /* SYS_DMA_CDSA_L_CH0 */ + case 0x0c: /* SYS_DMA_CDSA_L_CH0 */ *value = ch->addr[1] & 0x0000ffff; break; - case 0x0e: /* SYS_DMA_CDSA_U_CH0 */ + case 0x0e: /* SYS_DMA_CDSA_U_CH0 */ *value = ch->addr[1] >> 16; break; - case 0x10: /* SYS_DMA_CEN_CH0 */ + case 0x10: /* SYS_DMA_CEN_CH0 */ *value = ch->elements; break; - case 0x12: /* SYS_DMA_CFN_CH0 */ + case 0x12: /* SYS_DMA_CFN_CH0 */ *value = ch->frames; break; - case 0x14: /* SYS_DMA_CFI_CH0 */ + case 0x14: /* SYS_DMA_CFI_CH0 */ *value = ch->frame_index[0]; break; - case 0x16: /* SYS_DMA_CEI_CH0 */ + case 0x16: /* SYS_DMA_CEI_CH0 */ *value = ch->element_index[0]; break; - case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */ + case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */ if (ch->omap_3_1_compatible_disable) - *value = ch->active_set.src & 0xffff; /* CSAC */ + *value = ch->active_set.src & 0xffff; /* CSAC */ else *value = ch->cpc; break; - case 0x1a: /* DMA_CDAC */ - *value = ch->active_set.dest & 0xffff; /* CDAC */ + case 0x1a: /* DMA_CDAC */ + *value = ch->active_set.dest & 0xffff; /* CDAC */ break; - case 0x1c: /* DMA_CDEI */ + case 0x1c: /* DMA_CDEI */ *value = ch->element_index[1]; break; - case 0x1e: /* DMA_CDFI */ + case 0x1e: /* DMA_CDFI */ *value = ch->frame_index[1]; break; - case 0x20: /* DMA_COLOR_L */ + case 0x20: /* DMA_COLOR_L */ *value = ch->color & 0xffff; break; - case 0x22: /* DMA_COLOR_U */ + case 0x22: /* DMA_COLOR_U */ *value = ch->color >> 16; break; - case 0x24: /* DMA_CCR2 */ + case 0x24: /* DMA_CCR2 */ *value = (ch->bs << 2) | (ch->transparent_copy << 1) | ch->constant_fill; break; - case 0x28: /* DMA_CLNK_CTRL */ + case 0x28: /* DMA_CLNK_CTRL */ *value = (ch->link_enabled << 15) | (ch->link_next_ch & 0xf); break; - case 0x2a: /* DMA_LCH_CTRL */ + case 0x2a: /* DMA_LCH_CTRL */ *value = (ch->interleave_disabled << 15) | ch->type; break; @@ -864,7 +864,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, struct omap_dma_channel_s *ch, int reg, uint16_t value) { switch (reg) { - case 0x00: /* SYS_DMA_CSDP_CH0 */ + case 0x00: /* SYS_DMA_CSDP_CH0 */ ch->burst[1] = (value & 0xc000) >> 14; ch->pack[1] = (value & 0x2000) >> 13; ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9); @@ -887,7 +887,7 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, } break; - case 0x02: /* SYS_DMA_CCR_CH0 */ + case 0x02: /* SYS_DMA_CCR_CH0 */ ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14); ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12); ch->end_prog = (value & 0x0800) >> 11; @@ -909,88 +909,88 @@ static int omap_dma_ch_reg_write(struct omap_dma_s *s, break; - case 0x04: /* SYS_DMA_CICR_CH0 */ + case 0x04: /* SYS_DMA_CICR_CH0 */ ch->interrupts = value & 0x3f; break; - case 0x06: /* SYS_DMA_CSR_CH0 */ + case 0x06: /* SYS_DMA_CSR_CH0 */ OMAP_RO_REG((hwaddr) reg); break; - case 0x08: /* SYS_DMA_CSSA_L_CH0 */ + case 0x08: /* SYS_DMA_CSSA_L_CH0 */ ch->addr[0] &= 0xffff0000; ch->addr[0] |= value; break; - case 0x0a: /* SYS_DMA_CSSA_U_CH0 */ + case 0x0a: /* SYS_DMA_CSSA_U_CH0 */ ch->addr[0] &= 0x0000ffff; ch->addr[0] |= (uint32_t) value << 16; break; - case 0x0c: /* SYS_DMA_CDSA_L_CH0 */ + case 0x0c: /* SYS_DMA_CDSA_L_CH0 */ ch->addr[1] &= 0xffff0000; ch->addr[1] |= value; break; - case 0x0e: /* SYS_DMA_CDSA_U_CH0 */ + case 0x0e: /* SYS_DMA_CDSA_U_CH0 */ ch->addr[1] &= 0x0000ffff; ch->addr[1] |= (uint32_t) value << 16; break; - case 0x10: /* SYS_DMA_CEN_CH0 */ + case 0x10: /* SYS_DMA_CEN_CH0 */ ch->elements = value; break; - case 0x12: /* SYS_DMA_CFN_CH0 */ + case 0x12: /* SYS_DMA_CFN_CH0 */ ch->frames = value; break; - case 0x14: /* SYS_DMA_CFI_CH0 */ + case 0x14: /* SYS_DMA_CFI_CH0 */ ch->frame_index[0] = (int16_t) value; break; - case 0x16: /* SYS_DMA_CEI_CH0 */ + case 0x16: /* SYS_DMA_CEI_CH0 */ ch->element_index[0] = (int16_t) value; break; - case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */ + case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */ OMAP_RO_REG((hwaddr) reg); break; - case 0x1c: /* DMA_CDEI */ + case 0x1c: /* DMA_CDEI */ ch->element_index[1] = (int16_t) value; break; - case 0x1e: /* DMA_CDFI */ + case 0x1e: /* DMA_CDFI */ ch->frame_index[1] = (int16_t) value; break; - case 0x20: /* DMA_COLOR_L */ + case 0x20: /* DMA_COLOR_L */ ch->color &= 0xffff0000; ch->color |= value; break; - case 0x22: /* DMA_COLOR_U */ + case 0x22: /* DMA_COLOR_U */ ch->color &= 0xffff; ch->color |= (uint32_t)value << 16; break; - case 0x24: /* DMA_CCR2 */ + case 0x24: /* DMA_CCR2 */ ch->bs = (value >> 2) & 0x1; ch->transparent_copy = (value >> 1) & 0x1; ch->constant_fill = value & 0x1; break; - case 0x28: /* DMA_CLNK_CTRL */ + case 0x28: /* DMA_CLNK_CTRL */ ch->link_enabled = (value >> 15) & 0x1; - if (value & (1 << 14)) { /* Stop_Lnk */ + if (value & (1 << 14)) { /* Stop_Lnk */ ch->link_enabled = 0; omap_dma_disable_channel(s, ch); } ch->link_next_ch = value & 0x1f; break; - case 0x2a: /* DMA_LCH_CTRL */ + case 0x2a: /* DMA_LCH_CTRL */ ch->interleave_disabled = (value >> 15) & 0x1; ch->type = value & 0xf; break; @@ -1005,7 +1005,7 @@ static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset, uint16_t value) { switch (offset) { - case 0xbc0: /* DMA_LCD_CSDP */ + case 0xbc0: /* DMA_LCD_CSDP */ s->brust_f2 = (value >> 14) & 0x3; s->pack_f2 = (value >> 13) & 0x1; s->data_type_f2 = (1 << ((value >> 11) & 0x3)); @@ -1014,7 +1014,7 @@ static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset, s->data_type_f1 = (1 << ((value >> 0) & 0x3)); break; - case 0xbc2: /* DMA_LCD_CCR */ + case 0xbc2: /* DMA_LCD_CCR */ s->mode_f2 = (value >> 14) & 0x3; s->mode_f1 = (value >> 12) & 0x3; s->end_prog = (value >> 11) & 0x1; @@ -1026,7 +1026,7 @@ static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset, s->bs = (value >> 4) & 0x1; break; - case 0xbc4: /* DMA_LCD_CTRL */ + case 0xbc4: /* DMA_LCD_CTRL */ s->dst = (value >> 8) & 0x1; s->src = ((value >> 6) & 0x3) << 1; s->condition = 0; @@ -1035,91 +1035,91 @@ static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset, s->dual = value & 1; break; - case 0xbc8: /* TOP_B1_L */ + case 0xbc8: /* TOP_B1_L */ s->src_f1_top &= 0xffff0000; s->src_f1_top |= 0x0000ffff & value; break; - case 0xbca: /* TOP_B1_U */ + case 0xbca: /* TOP_B1_U */ s->src_f1_top &= 0x0000ffff; s->src_f1_top |= (uint32_t)value << 16; break; - case 0xbcc: /* BOT_B1_L */ + case 0xbcc: /* BOT_B1_L */ s->src_f1_bottom &= 0xffff0000; s->src_f1_bottom |= 0x0000ffff & value; break; - case 0xbce: /* BOT_B1_U */ + case 0xbce: /* BOT_B1_U */ s->src_f1_bottom &= 0x0000ffff; s->src_f1_bottom |= (uint32_t) value << 16; break; - case 0xbd0: /* TOP_B2_L */ + case 0xbd0: /* TOP_B2_L */ s->src_f2_top &= 0xffff0000; s->src_f2_top |= 0x0000ffff & value; break; - case 0xbd2: /* TOP_B2_U */ + case 0xbd2: /* TOP_B2_U */ s->src_f2_top &= 0x0000ffff; s->src_f2_top |= (uint32_t) value << 16; break; - case 0xbd4: /* BOT_B2_L */ + case 0xbd4: /* BOT_B2_L */ s->src_f2_bottom &= 0xffff0000; s->src_f2_bottom |= 0x0000ffff & value; break; - case 0xbd6: /* BOT_B2_U */ + case 0xbd6: /* BOT_B2_U */ s->src_f2_bottom &= 0x0000ffff; s->src_f2_bottom |= (uint32_t) value << 16; break; - case 0xbd8: /* DMA_LCD_SRC_EI_B1 */ + case 0xbd8: /* DMA_LCD_SRC_EI_B1 */ s->element_index_f1 = value; break; - case 0xbda: /* DMA_LCD_SRC_FI_B1_L */ + case 0xbda: /* DMA_LCD_SRC_FI_B1_L */ s->frame_index_f1 &= 0xffff0000; s->frame_index_f1 |= 0x0000ffff & value; break; - case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */ + case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */ s->frame_index_f1 &= 0x0000ffff; s->frame_index_f1 |= (uint32_t) value << 16; break; - case 0xbdc: /* DMA_LCD_SRC_EI_B2 */ + case 0xbdc: /* DMA_LCD_SRC_EI_B2 */ s->element_index_f2 = value; break; - case 0xbde: /* DMA_LCD_SRC_FI_B2_L */ + case 0xbde: /* DMA_LCD_SRC_FI_B2_L */ s->frame_index_f2 &= 0xffff0000; s->frame_index_f2 |= 0x0000ffff & value; break; - case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */ + case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */ s->frame_index_f2 &= 0x0000ffff; s->frame_index_f2 |= (uint32_t) value << 16; break; - case 0xbe0: /* DMA_LCD_SRC_EN_B1 */ + case 0xbe0: /* DMA_LCD_SRC_EN_B1 */ s->elements_f1 = value; break; - case 0xbe4: /* DMA_LCD_SRC_FN_B1 */ + case 0xbe4: /* DMA_LCD_SRC_FN_B1 */ s->frames_f1 = value; break; - case 0xbe2: /* DMA_LCD_SRC_EN_B2 */ + case 0xbe2: /* DMA_LCD_SRC_EN_B2 */ s->elements_f2 = value; break; - case 0xbe6: /* DMA_LCD_SRC_FN_B2 */ + case 0xbe6: /* DMA_LCD_SRC_FN_B2 */ s->frames_f2 = value; break; - case 0xbea: /* DMA_LCD_LCH_CTRL */ + case 0xbea: /* DMA_LCD_LCH_CTRL */ s->lch_type = value & 0xf; break; @@ -1133,7 +1133,7 @@ static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, uint16_t *ret) { switch (offset) { - case 0xbc0: /* DMA_LCD_CSDP */ + case 0xbc0: /* DMA_LCD_CSDP */ *ret = (s->brust_f2 << 14) | (s->pack_f2 << 13) | ((s->data_type_f2 >> 1) << 11) | @@ -1142,7 +1142,7 @@ static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, ((s->data_type_f1 >> 1) << 0); break; - case 0xbc2: /* DMA_LCD_CCR */ + case 0xbc2: /* DMA_LCD_CCR */ *ret = (s->mode_f2 << 14) | (s->mode_f1 << 12) | (s->end_prog << 11) | @@ -1154,7 +1154,7 @@ static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, (s->bs << 4); break; - case 0xbc4: /* DMA_LCD_CTRL */ + case 0xbc4: /* DMA_LCD_CTRL */ qemu_irq_lower(s->irq); *ret = (s->dst << 8) | ((s->src & 0x6) << 5) | @@ -1163,79 +1163,79 @@ static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, s->dual; break; - case 0xbc8: /* TOP_B1_L */ + case 0xbc8: /* TOP_B1_L */ *ret = s->src_f1_top & 0xffff; break; - case 0xbca: /* TOP_B1_U */ + case 0xbca: /* TOP_B1_U */ *ret = s->src_f1_top >> 16; break; - case 0xbcc: /* BOT_B1_L */ + case 0xbcc: /* BOT_B1_L */ *ret = s->src_f1_bottom & 0xffff; break; - case 0xbce: /* BOT_B1_U */ + case 0xbce: /* BOT_B1_U */ *ret = s->src_f1_bottom >> 16; break; - case 0xbd0: /* TOP_B2_L */ + case 0xbd0: /* TOP_B2_L */ *ret = s->src_f2_top & 0xffff; break; - case 0xbd2: /* TOP_B2_U */ + case 0xbd2: /* TOP_B2_U */ *ret = s->src_f2_top >> 16; break; - case 0xbd4: /* BOT_B2_L */ + case 0xbd4: /* BOT_B2_L */ *ret = s->src_f2_bottom & 0xffff; break; - case 0xbd6: /* BOT_B2_U */ + case 0xbd6: /* BOT_B2_U */ *ret = s->src_f2_bottom >> 16; break; - case 0xbd8: /* DMA_LCD_SRC_EI_B1 */ + case 0xbd8: /* DMA_LCD_SRC_EI_B1 */ *ret = s->element_index_f1; break; - case 0xbda: /* DMA_LCD_SRC_FI_B1_L */ + case 0xbda: /* DMA_LCD_SRC_FI_B1_L */ *ret = s->frame_index_f1 & 0xffff; break; - case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */ + case 0xbf4: /* DMA_LCD_SRC_FI_B1_U */ *ret = s->frame_index_f1 >> 16; break; - case 0xbdc: /* DMA_LCD_SRC_EI_B2 */ + case 0xbdc: /* DMA_LCD_SRC_EI_B2 */ *ret = s->element_index_f2; break; - case 0xbde: /* DMA_LCD_SRC_FI_B2_L */ + case 0xbde: /* DMA_LCD_SRC_FI_B2_L */ *ret = s->frame_index_f2 & 0xffff; break; - case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */ + case 0xbf6: /* DMA_LCD_SRC_FI_B2_U */ *ret = s->frame_index_f2 >> 16; break; - case 0xbe0: /* DMA_LCD_SRC_EN_B1 */ + case 0xbe0: /* DMA_LCD_SRC_EN_B1 */ *ret = s->elements_f1; break; - case 0xbe4: /* DMA_LCD_SRC_FN_B1 */ + case 0xbe4: /* DMA_LCD_SRC_FN_B1 */ *ret = s->frames_f1; break; - case 0xbe2: /* DMA_LCD_SRC_EN_B2 */ + case 0xbe2: /* DMA_LCD_SRC_EN_B2 */ *ret = s->elements_f2; break; - case 0xbe6: /* DMA_LCD_SRC_FN_B2 */ + case 0xbe6: /* DMA_LCD_SRC_FN_B2 */ *ret = s->frames_f2; break; - case 0xbea: /* DMA_LCD_LCH_CTRL */ + case 0xbea: /* DMA_LCD_LCH_CTRL */ *ret = s->lch_type; break; @@ -1249,7 +1249,7 @@ static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset, uint16_t value) { switch (offset) { - case 0x300: /* SYS_DMA_LCD_CTRL */ + case 0x300: /* SYS_DMA_LCD_CTRL */ s->src = (value & 0x40) ? imif : emiff; s->condition = 0; /* Assume no bus errors and thus no BUS_ERROR irq bits. */ @@ -1257,42 +1257,42 @@ static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset, s->dual = value & 1; break; - case 0x302: /* SYS_DMA_LCD_TOP_F1_L */ + case 0x302: /* SYS_DMA_LCD_TOP_F1_L */ s->src_f1_top &= 0xffff0000; s->src_f1_top |= 0x0000ffff & value; break; - case 0x304: /* SYS_DMA_LCD_TOP_F1_U */ + case 0x304: /* SYS_DMA_LCD_TOP_F1_U */ s->src_f1_top &= 0x0000ffff; s->src_f1_top |= (uint32_t)value << 16; break; - case 0x306: /* SYS_DMA_LCD_BOT_F1_L */ + case 0x306: /* SYS_DMA_LCD_BOT_F1_L */ s->src_f1_bottom &= 0xffff0000; s->src_f1_bottom |= 0x0000ffff & value; break; - case 0x308: /* SYS_DMA_LCD_BOT_F1_U */ + case 0x308: /* SYS_DMA_LCD_BOT_F1_U */ s->src_f1_bottom &= 0x0000ffff; s->src_f1_bottom |= (uint32_t)value << 16; break; - case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */ + case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */ s->src_f2_top &= 0xffff0000; s->src_f2_top |= 0x0000ffff & value; break; - case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */ + case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */ s->src_f2_top &= 0x0000ffff; s->src_f2_top |= (uint32_t)value << 16; break; - case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */ + case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */ s->src_f2_bottom &= 0xffff0000; s->src_f2_bottom |= 0x0000ffff & value; break; - case 0x310: /* SYS_DMA_LCD_BOT_F2_U */ + case 0x310: /* SYS_DMA_LCD_BOT_F2_U */ s->src_f2_bottom &= 0x0000ffff; s->src_f2_bottom |= (uint32_t)value << 16; break; @@ -1309,7 +1309,7 @@ static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, int i; switch (offset) { - case 0x300: /* SYS_DMA_LCD_CTRL */ + case 0x300: /* SYS_DMA_LCD_CTRL */ i = s->condition; s->condition = 0; qemu_irq_lower(s->irq); @@ -1317,35 +1317,35 @@ static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, (s->interrupts << 1) | s->dual; break; - case 0x302: /* SYS_DMA_LCD_TOP_F1_L */ + case 0x302: /* SYS_DMA_LCD_TOP_F1_L */ *ret = s->src_f1_top & 0xffff; break; - case 0x304: /* SYS_DMA_LCD_TOP_F1_U */ + case 0x304: /* SYS_DMA_LCD_TOP_F1_U */ *ret = s->src_f1_top >> 16; break; - case 0x306: /* SYS_DMA_LCD_BOT_F1_L */ + case 0x306: /* SYS_DMA_LCD_BOT_F1_L */ *ret = s->src_f1_bottom & 0xffff; break; - case 0x308: /* SYS_DMA_LCD_BOT_F1_U */ + case 0x308: /* SYS_DMA_LCD_BOT_F1_U */ *ret = s->src_f1_bottom >> 16; break; - case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */ + case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */ *ret = s->src_f2_top & 0xffff; break; - case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */ + case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */ *ret = s->src_f2_top >> 16; break; - case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */ + case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */ *ret = s->src_f2_bottom & 0xffff; break; - case 0x310: /* SYS_DMA_LCD_BOT_F2_U */ + case 0x310: /* SYS_DMA_LCD_BOT_F2_U */ *ret = s->src_f2_bottom >> 16; break; @@ -1358,18 +1358,18 @@ static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset, static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value) { switch (offset) { - case 0x400: /* SYS_DMA_GCR */ + case 0x400: /* SYS_DMA_GCR */ s->gcr = value; break; - case 0x404: /* DMA_GSCR */ + case 0x404: /* DMA_GSCR */ if (value & 0x8) omap_dma_disable_3_1_mapping(s); else omap_dma_enable_3_1_mapping(s); break; - case 0x408: /* DMA_GRST */ + case 0x408: /* DMA_GRST */ if (value & 0x1) omap_dma_reset(s->dma); break; @@ -1384,57 +1384,57 @@ static int omap_dma_sys_read(struct omap_dma_s *s, int offset, uint16_t *ret) { switch (offset) { - case 0x400: /* SYS_DMA_GCR */ + case 0x400: /* SYS_DMA_GCR */ *ret = s->gcr; break; - case 0x404: /* DMA_GSCR */ + case 0x404: /* DMA_GSCR */ *ret = s->omap_3_1_mapping_disabled << 3; break; - case 0x408: /* DMA_GRST */ + case 0x408: /* DMA_GRST */ *ret = 0; break; - case 0x442: /* DMA_HW_ID */ - case 0x444: /* DMA_PCh2_ID */ - case 0x446: /* DMA_PCh0_ID */ - case 0x448: /* DMA_PCh1_ID */ - case 0x44a: /* DMA_PChG_ID */ - case 0x44c: /* DMA_PChD_ID */ + case 0x442: /* DMA_HW_ID */ + case 0x444: /* DMA_PCh2_ID */ + case 0x446: /* DMA_PCh0_ID */ + case 0x448: /* DMA_PCh1_ID */ + case 0x44a: /* DMA_PChG_ID */ + case 0x44c: /* DMA_PChD_ID */ *ret = 1; break; - case 0x44e: /* DMA_CAPS_0_U */ + case 0x44e: /* DMA_CAPS_0_U */ *ret = (s->caps[0] >> 16) & 0xffff; break; - case 0x450: /* DMA_CAPS_0_L */ + case 0x450: /* DMA_CAPS_0_L */ *ret = (s->caps[0] >> 0) & 0xffff; break; - case 0x452: /* DMA_CAPS_1_U */ + case 0x452: /* DMA_CAPS_1_U */ *ret = (s->caps[1] >> 16) & 0xffff; break; - case 0x454: /* DMA_CAPS_1_L */ + case 0x454: /* DMA_CAPS_1_L */ *ret = (s->caps[1] >> 0) & 0xffff; break; - case 0x456: /* DMA_CAPS_2 */ + case 0x456: /* DMA_CAPS_2 */ *ret = s->caps[2]; break; - case 0x458: /* DMA_CAPS_3 */ + case 0x458: /* DMA_CAPS_3 */ *ret = s->caps[3]; break; - case 0x45a: /* DMA_CAPS_4 */ + case 0x45a: /* DMA_CAPS_4 */ *ret = s->caps[4]; break; - case 0x460: /* DMA_PCh2_SR */ - case 0x480: /* DMA_PCh0_SR */ - case 0x482: /* DMA_PCh1_SR */ - case 0x4c0: /* DMA_PChD_SR_0 */ + case 0x460: /* DMA_PCh2_SR */ + case 0x480: /* DMA_PCh0_SR */ + case 0x482: /* DMA_PCh1_SR */ + case 0x4c0: /* DMA_PChD_SR_0 */ qemu_log_mask(LOG_UNIMP, "%s: Physical Channel Status Registers not implemented\n", __func__); @@ -1582,38 +1582,38 @@ static void omap_dma_setcaps(struct omap_dma_s *s) case omap_dma_3_2: /* XXX Only available for sDMA */ s->caps[0] = - (1 << 19) | /* Constant Fill Capability */ - (1 << 18); /* Transparent BLT Capability */ + (1 << 19) | /* Constant Fill Capability */ + (1 << 18); /* Transparent BLT Capability */ s->caps[1] = - (1 << 1); /* 1-bit palettized capability (DMA 3.2 only) */ + (1 << 1); /* 1-bit palettized capability (DMA 3.2 only) */ s->caps[2] = - (1 << 8) | /* SEPARATE_SRC_AND_DST_INDEX_CPBLTY */ - (1 << 7) | /* DST_DOUBLE_INDEX_ADRS_CPBLTY */ - (1 << 6) | /* DST_SINGLE_INDEX_ADRS_CPBLTY */ - (1 << 5) | /* DST_POST_INCRMNT_ADRS_CPBLTY */ - (1 << 4) | /* DST_CONST_ADRS_CPBLTY */ - (1 << 3) | /* SRC_DOUBLE_INDEX_ADRS_CPBLTY */ - (1 << 2) | /* SRC_SINGLE_INDEX_ADRS_CPBLTY */ - (1 << 1) | /* SRC_POST_INCRMNT_ADRS_CPBLTY */ - (1 << 0); /* SRC_CONST_ADRS_CPBLTY */ + (1 << 8) | /* SEPARATE_SRC_AND_DST_INDEX_CPBLTY */ + (1 << 7) | /* DST_DOUBLE_INDEX_ADRS_CPBLTY */ + (1 << 6) | /* DST_SINGLE_INDEX_ADRS_CPBLTY */ + (1 << 5) | /* DST_POST_INCRMNT_ADRS_CPBLTY */ + (1 << 4) | /* DST_CONST_ADRS_CPBLTY */ + (1 << 3) | /* SRC_DOUBLE_INDEX_ADRS_CPBLTY */ + (1 << 2) | /* SRC_SINGLE_INDEX_ADRS_CPBLTY */ + (1 << 1) | /* SRC_POST_INCRMNT_ADRS_CPBLTY */ + (1 << 0); /* SRC_CONST_ADRS_CPBLTY */ s->caps[3] = - (1 << 6) | /* BLOCK_SYNCHR_CPBLTY (DMA 4 only) */ - (1 << 7) | /* PKT_SYNCHR_CPBLTY (DMA 4 only) */ - (1 << 5) | /* CHANNEL_CHAINING_CPBLTY */ - (1 << 4) | /* LCh_INTERLEAVE_CPBLTY */ - (1 << 3) | /* AUTOINIT_REPEAT_CPBLTY (DMA 3.2 only) */ - (1 << 2) | /* AUTOINIT_ENDPROG_CPBLTY (DMA 3.2 only) */ - (1 << 1) | /* FRAME_SYNCHR_CPBLTY */ - (1 << 0); /* ELMNT_SYNCHR_CPBLTY */ + (1 << 6) | /* BLOCK_SYNCHR_CPBLTY (DMA 4 only) */ + (1 << 7) | /* PKT_SYNCHR_CPBLTY (DMA 4 only) */ + (1 << 5) | /* CHANNEL_CHAINING_CPBLTY */ + (1 << 4) | /* LCh_INTERLEAVE_CPBLTY */ + (1 << 3) | /* AUTOINIT_REPEAT_CPBLTY (DMA 3.2 only) */ + (1 << 2) | /* AUTOINIT_ENDPROG_CPBLTY (DMA 3.2 only) */ + (1 << 1) | /* FRAME_SYNCHR_CPBLTY */ + (1 << 0); /* ELMNT_SYNCHR_CPBLTY */ s->caps[4] = - (1 << 7) | /* PKT_INTERRUPT_CPBLTY (DMA 4 only) */ - (1 << 6) | /* SYNC_STATUS_CPBLTY */ - (1 << 5) | /* BLOCK_INTERRUPT_CPBLTY */ - (1 << 4) | /* LAST_FRAME_INTERRUPT_CPBLTY */ - (1 << 3) | /* FRAME_INTERRUPT_CPBLTY */ - (1 << 2) | /* HALF_FRAME_INTERRUPT_CPBLTY */ - (1 << 1) | /* EVENT_DROP_INTERRUPT_CPBLTY */ - (1 << 0); /* TIMEOUT_INTERRUPT_CPBLTY (DMA 3.2 only) */ + (1 << 7) | /* PKT_INTERRUPT_CPBLTY (DMA 4 only) */ + (1 << 6) | /* SYNC_STATUS_CPBLTY */ + (1 << 5) | /* BLOCK_INTERRUPT_CPBLTY */ + (1 << 4) | /* LAST_FRAME_INTERRUPT_CPBLTY */ + (1 << 3) | /* FRAME_INTERRUPT_CPBLTY */ + (1 << 2) | /* HALF_FRAME_INTERRUPT_CPBLTY */ + (1 << 1) | /* EVENT_DROP_INTERRUPT_CPBLTY */ + (1 << 0); /* TIMEOUT_INTERRUPT_CPBLTY (DMA 3.2 only) */ break; } } diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 8a9b073..277d934 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -413,7 +413,7 @@ static const Property pl080_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void pl080_class_init(ObjectClass *oc, void *data) +static void pl080_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c index 545aa44..a570bb0 100644 --- a/hw/dma/pl330.c +++ b/hw/dma/pl330.c @@ -1671,7 +1671,7 @@ static const Property pl330_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void pl330_class_init(ObjectClass *klass, void *data) +static void pl330_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c index 5bf5434..b6ed1d4 100644 --- a/hw/dma/rc4030.c +++ b/hw/dma/rc4030.c @@ -32,7 +32,7 @@ #include "qemu/timer.h" #include "qemu/log.h" #include "qemu/module.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "trace.h" #include "qom/object.h" @@ -701,7 +701,7 @@ static void rc4030_unrealize(DeviceState *dev) object_unparent(OBJECT(&s->dma_mr)); } -static void rc4030_class_init(ObjectClass *klass, void *class_data) +static void rc4030_class_init(ObjectClass *klass, const void *class_data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -720,7 +720,7 @@ static const TypeInfo rc4030_info = { }; static void rc4030_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/dma/sifive_pdma.c b/hw/dma/sifive_pdma.c index a115af8..48de3a2 100644 --- a/hw/dma/sifive_pdma.c +++ b/hw/dma/sifive_pdma.c @@ -464,7 +464,7 @@ static void sifive_pdma_realize(DeviceState *dev, Error **errp) } } -static void sifive_pdma_class_init(ObjectClass *klass, void *data) +static void sifive_pdma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/sparc32_dma.c b/hw/dma/sparc32_dma.c index 280b747..60c23b6 100644 --- a/hw/dma/sparc32_dma.c +++ b/hw/dma/sparc32_dma.c @@ -274,7 +274,7 @@ static void sparc32_dma_device_init(Object *obj) qdev_init_gpio_out(dev, s->gpio, 2); } -static void sparc32_dma_device_class_init(ObjectClass *klass, void *data) +static void sparc32_dma_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -316,7 +316,8 @@ static void sparc32_espdma_device_realize(DeviceState *dev, Error **errp) sysbus_realize(SYS_BUS_DEVICE(sysbus), &error_fatal); } -static void sparc32_espdma_device_class_init(ObjectClass *klass, void *data) +static void sparc32_espdma_device_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -351,7 +352,8 @@ static void sparc32_ledma_device_realize(DeviceState *dev, Error **errp) sysbus_realize(SYS_BUS_DEVICE(lance), &error_fatal); } -static void sparc32_ledma_device_class_init(ObjectClass *klass, void *data) +static void sparc32_ledma_device_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -426,7 +428,7 @@ static void sparc32_dma_init(Object *obj) TYPE_SPARC32_LEDMA_DEVICE); } -static void sparc32_dma_class_init(ObjectClass *klass, void *data) +static void sparc32_dma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/xilinx_axidma.c b/hw/dma/xilinx_axidma.c index 22fe357..2020399 100644 --- a/hw/dma/xilinx_axidma.c +++ b/hw/dma/xilinx_axidma.c @@ -621,7 +621,7 @@ static const Property axidma_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void axidma_class_init(ObjectClass *klass, void *data) +static void axidma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -639,7 +639,8 @@ static StreamSinkClass xilinx_axidma_control_stream_class = { .push = xilinx_axidma_control_stream_push, }; -static void xilinx_axidma_stream_class_init(ObjectClass *klass, void *data) +static void xilinx_axidma_stream_class_init(ObjectClass *klass, + const void *data) { StreamSinkClass *ssc = STREAM_SINK_CLASS(klass); @@ -661,7 +662,7 @@ static const TypeInfo xilinx_axidma_data_stream_info = { .instance_size = sizeof(XilinxAXIDMAStreamSink), .class_init = xilinx_axidma_stream_class_init, .class_data = &xilinx_axidma_data_stream_class, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_STREAM_SINK }, { } } @@ -673,7 +674,7 @@ static const TypeInfo xilinx_axidma_control_stream_info = { .instance_size = sizeof(XilinxAXIDMAStreamSink), .class_init = xilinx_axidma_stream_class_init, .class_data = &xilinx_axidma_control_stream_class, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_STREAM_SINK }, { } } diff --git a/hw/dma/xlnx-zdma.c b/hw/dma/xlnx-zdma.c index bb27cb2..0c075e7 100644 --- a/hw/dma/xlnx-zdma.c +++ b/hw/dma/xlnx-zdma.c @@ -816,7 +816,7 @@ static const Property zdma_props[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void zdma_class_init(ObjectClass *klass, void *data) +static void zdma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/xlnx-zynq-devcfg.c b/hw/dma/xlnx-zynq-devcfg.c index 0fd0d23..2684571 100644 --- a/hw/dma/xlnx-zynq-devcfg.c +++ b/hw/dma/xlnx-zynq-devcfg.c @@ -380,7 +380,7 @@ static void xlnx_zynq_devcfg_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); } -static void xlnx_zynq_devcfg_class_init(ObjectClass *klass, void *data) +static void xlnx_zynq_devcfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/dma/xlnx_csu_dma.c b/hw/dma/xlnx_csu_dma.c index 1afaa0b..d8c7da1 100644 --- a/hw/dma/xlnx_csu_dma.c +++ b/hw/dma/xlnx_csu_dma.c @@ -287,7 +287,7 @@ static uint32_t xlnx_csu_dma_advance(XlnxCSUDMA *s, uint32_t len) static void xlnx_csu_dma_src_notify(void *opaque) { XlnxCSUDMA *s = XLNX_CSU_DMA(opaque); - unsigned char buf[4 * 1024]; + QEMU_UNINITIALIZED unsigned char buf[4 * 1024]; size_t rlen = 0; ptimer_transaction_begin(s->src_timer); @@ -712,7 +712,7 @@ static const Property xlnx_csu_dma_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void xlnx_csu_dma_class_init(ObjectClass *klass, void *data) +static void xlnx_csu_dma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); StreamSinkClass *ssc = STREAM_SINK_CLASS(klass); @@ -744,7 +744,7 @@ static const TypeInfo xlnx_csu_dma_info = { .class_init = xlnx_csu_dma_class_init, .class_size = sizeof(XlnxCSUDMAClass), .instance_init = xlnx_csu_dma_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_STREAM_SINK }, { } } diff --git a/hw/dma/xlnx_dpdma.c b/hw/dma/xlnx_dpdma.c index 2657808..3d88ccc 100644 --- a/hw/dma/xlnx_dpdma.c +++ b/hw/dma/xlnx_dpdma.c @@ -593,7 +593,7 @@ static void xlnx_dpdma_reset(DeviceState *dev) } } -static void xlnx_dpdma_class_init(ObjectClass *oc, void *data) +static void xlnx_dpdma_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/fsi/aspeed_apb2opb.c b/hw/fsi/aspeed_apb2opb.c index 0e2cc14..172ba16 100644 --- a/hw/fsi/aspeed_apb2opb.c +++ b/hw/fsi/aspeed_apb2opb.c @@ -320,7 +320,7 @@ static void fsi_aspeed_apb2opb_reset(DeviceState *dev) memcpy(s->regs, aspeed_apb2opb_reset, ASPEED_APB2OPB_NR_REGS); } -static void fsi_aspeed_apb2opb_class_init(ObjectClass *klass, void *data) +static void fsi_aspeed_apb2opb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/fsi/cfam.c b/hw/fsi/cfam.c index c62f0f7..e2145c5 100644 --- a/hw/fsi/cfam.c +++ b/hw/fsi/cfam.c @@ -145,7 +145,7 @@ static void fsi_cfam_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&cfam->lbus.mr, 0, &fsi_dev->iomem); } -static void fsi_cfam_class_init(ObjectClass *klass, void *data) +static void fsi_cfam_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->bus_type = TYPE_FSI_BUS; diff --git a/hw/fsi/fsi-master.c b/hw/fsi/fsi-master.c index 50fb1cd..083a550 100644 --- a/hw/fsi/fsi-master.c +++ b/hw/fsi/fsi-master.c @@ -144,7 +144,7 @@ static void fsi_master_reset(DeviceState *dev) s->regs[FSI_MVER] = 0xe0050101; } -static void fsi_master_class_init(ObjectClass *klass, void *data) +static void fsi_master_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/fsi/fsi.c b/hw/fsi/fsi.c index 83ddb17..6c52d5e 100644 --- a/hw/fsi/fsi.c +++ b/hw/fsi/fsi.c @@ -76,7 +76,7 @@ static void fsi_slave_init(Object *o) s, TYPE_FSI_SLAVE, 0x400); } -static void fsi_slave_class_init(ObjectClass *klass, void *data) +static void fsi_slave_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/fsi/lbus.c b/hw/fsi/lbus.c index 4f87b28..8ec7f5f 100644 --- a/hw/fsi/lbus.c +++ b/hw/fsi/lbus.c @@ -91,7 +91,7 @@ static void fsi_scratchpad_reset(DeviceState *dev) memset(s->regs, 0, sizeof(s->regs)); } -static void fsi_scratchpad_class_init(ObjectClass *klass, void *data) +static void fsi_scratchpad_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/aspeed_gpio.c b/hw/gpio/aspeed_gpio.c index aedaf52..609a556 100644 --- a/hw/gpio/aspeed_gpio.c +++ b/hw/gpio/aspeed_gpio.c @@ -1473,7 +1473,7 @@ static const VMStateDescription vmstate_aspeed_gpio = { } }; -static void aspeed_gpio_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1483,7 +1483,7 @@ static void aspeed_gpio_class_init(ObjectClass *klass, void *data) dc->vmsd = &vmstate_aspeed_gpio; } -static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, const void *data) { AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); @@ -1496,7 +1496,7 @@ static void aspeed_gpio_ast2400_class_init(ObjectClass *klass, void *data) agc->reg_ops = &aspeed_gpio_ops; } -static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_2500_class_init(ObjectClass *klass, const void *data) { AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); @@ -1509,7 +1509,8 @@ static void aspeed_gpio_2500_class_init(ObjectClass *klass, void *data) agc->reg_ops = &aspeed_gpio_ops; } -static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass, + const void *data) { AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); @@ -1522,7 +1523,8 @@ static void aspeed_gpio_ast2600_3_3v_class_init(ObjectClass *klass, void *data) agc->reg_ops = &aspeed_gpio_ops; } -static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, + const void *data) { AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); @@ -1535,7 +1537,7 @@ static void aspeed_gpio_ast2600_1_8v_class_init(ObjectClass *klass, void *data) agc->reg_ops = &aspeed_gpio_ops; } -static void aspeed_gpio_1030_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_1030_class_init(ObjectClass *klass, const void *data) { AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); @@ -1548,7 +1550,7 @@ static void aspeed_gpio_1030_class_init(ObjectClass *klass, void *data) agc->reg_ops = &aspeed_gpio_ops; } -static void aspeed_gpio_2700_class_init(ObjectClass *klass, void *data) +static void aspeed_gpio_2700_class_init(ObjectClass *klass, const void *data) { AspeedGPIOClass *agc = ASPEED_GPIO_CLASS(klass); diff --git a/hw/gpio/bcm2835_gpio.c b/hw/gpio/bcm2835_gpio.c index 5a5f1df..dfb5d5c 100644 --- a/hw/gpio/bcm2835_gpio.c +++ b/hw/gpio/bcm2835_gpio.c @@ -319,7 +319,7 @@ static void bcm2835_gpio_realize(DeviceState *dev, Error **errp) s->sdbus_sdhost = SD_BUS(obj); } -static void bcm2835_gpio_class_init(ObjectClass *klass, void *data) +static void bcm2835_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/bcm2838_gpio.c b/hw/gpio/bcm2838_gpio.c index 53be8f2..1069e78 100644 --- a/hw/gpio/bcm2838_gpio.c +++ b/hw/gpio/bcm2838_gpio.c @@ -364,7 +364,7 @@ static void bcm2838_gpio_realize(DeviceState *dev, Error **errp) s->sdbus_sdhost = SD_BUS(obj); } -static void bcm2838_gpio_class_init(ObjectClass *klass, void *data) +static void bcm2838_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/gpio_key.c b/hw/gpio/gpio_key.c index 2fcab9e..40c028b 100644 --- a/hw/gpio/gpio_key.c +++ b/hw/gpio/gpio_key.c @@ -85,7 +85,7 @@ static void gpio_key_realize(DeviceState *dev, Error **errp) s->timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, gpio_key_timer_expired, s); } -static void gpio_key_class_init(ObjectClass *klass, void *data) +static void gpio_key_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c index 8c8299c..450ece4 100644 --- a/hw/gpio/imx_gpio.c +++ b/hw/gpio/imx_gpio.c @@ -72,7 +72,7 @@ static void imx_gpio_update_int(IMXGPIOState *s) static void imx_gpio_set_int_line(IMXGPIOState *s, int line, IMXGPIOLevel level) { /* if this signal isn't configured as an input signal, nothing to do */ - if (!extract32(s->gdir, line, 1)) { + if (extract32(s->gdir, line, 1)) { return; } @@ -321,7 +321,7 @@ static void imx_gpio_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } -static void imx_gpio_class_init(ObjectClass *klass, void *data) +static void imx_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/mpc8xxx.c b/hw/gpio/mpc8xxx.c index a3c1d2f..257497a 100644 --- a/hw/gpio/mpc8xxx.c +++ b/hw/gpio/mpc8xxx.c @@ -199,7 +199,7 @@ static void mpc8xxx_gpio_initfn(Object *obj) qdev_init_gpio_out(dev, s->out, 32); } -static void mpc8xxx_gpio_class_init(ObjectClass *klass, void *data) +static void mpc8xxx_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/npcm7xx_gpio.c b/hw/gpio/npcm7xx_gpio.c index 2916056..66f8256 100644 --- a/hw/gpio/npcm7xx_gpio.c +++ b/hw/gpio/npcm7xx_gpio.c @@ -396,7 +396,7 @@ static const Property npcm7xx_gpio_properties[] = { DEFINE_PROP_UINT32("reset-odsc", NPCM7xxGPIOState, reset_odsc, 0), }; -static void npcm7xx_gpio_class_init(ObjectClass *klass, void *data) +static void npcm7xx_gpio_class_init(ObjectClass *klass, const void *data) { ResettableClass *reset = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/nrf51_gpio.c b/hw/gpio/nrf51_gpio.c index d08c254..d94c0c4 100644 --- a/hw/gpio/nrf51_gpio.c +++ b/hw/gpio/nrf51_gpio.c @@ -304,7 +304,7 @@ static void nrf51_gpio_init(Object *obj) qdev_init_gpio_out_named(DEVICE(s), &s->detect, "detect", 1); } -static void nrf51_gpio_class_init(ObjectClass *klass, void *data) +static void nrf51_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c index 8a9f14b..f27806b 100644 --- a/hw/gpio/omap_gpio.c +++ b/hw/gpio/omap_gpio.c @@ -80,25 +80,25 @@ static uint64_t omap_gpio_read(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* DATA_INPUT */ + case 0x00: /* DATA_INPUT */ return s->inputs & s->pins; - case 0x04: /* DATA_OUTPUT */ + case 0x04: /* DATA_OUTPUT */ return s->outputs; - case 0x08: /* DIRECTION_CONTROL */ + case 0x08: /* DIRECTION_CONTROL */ return s->dir; - case 0x0c: /* INTERRUPT_CONTROL */ + case 0x0c: /* INTERRUPT_CONTROL */ return s->edge; - case 0x10: /* INTERRUPT_MASK */ + case 0x10: /* INTERRUPT_MASK */ return s->mask; - case 0x14: /* INTERRUPT_STATUS */ + case 0x14: /* INTERRUPT_STATUS */ return s->ints; - case 0x18: /* PIN_CONTROL (not in OMAP310) */ + case 0x18: /* PIN_CONTROL (not in OMAP310) */ OMAP_BAD_REG(addr); return s->pins; } @@ -121,11 +121,11 @@ static void omap_gpio_write(void *opaque, hwaddr addr, } switch (offset) { - case 0x00: /* DATA_INPUT */ + case 0x00: /* DATA_INPUT */ OMAP_RO_REG(addr); return; - case 0x04: /* DATA_OUTPUT */ + case 0x04: /* DATA_OUTPUT */ diff = (s->outputs ^ value) & ~s->dir; s->outputs = value; while ((ln = ctz32(diff)) != 32) { @@ -135,7 +135,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr, } break; - case 0x08: /* DIRECTION_CONTROL */ + case 0x08: /* DIRECTION_CONTROL */ diff = s->outputs & (s->dir ^ value); s->dir = value; @@ -147,21 +147,21 @@ static void omap_gpio_write(void *opaque, hwaddr addr, } break; - case 0x0c: /* INTERRUPT_CONTROL */ + case 0x0c: /* INTERRUPT_CONTROL */ s->edge = value; break; - case 0x10: /* INTERRUPT_MASK */ + case 0x10: /* INTERRUPT_MASK */ s->mask = value; break; - case 0x14: /* INTERRUPT_STATUS */ + case 0x14: /* INTERRUPT_STATUS */ s->ints &= ~value; if (!s->ints) qemu_irq_lower(s->irq); break; - case 0x18: /* PIN_CONTROL (not in OMAP310 TRM) */ + case 0x18: /* PIN_CONTROL (not in OMAP310 TRM) */ OMAP_BAD_REG(addr); s->pins = value; break; @@ -229,7 +229,7 @@ static const Property omap_gpio_properties[] = { DEFINE_PROP_INT32("mpu_model", Omap1GpioState, mpu_model, 0), }; -static void omap_gpio_class_init(ObjectClass *klass, void *data) +static void omap_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/pca9552.c b/hw/gpio/pca9552.c index 1ac0cf6..1e10238 100644 --- a/hw/gpio/pca9552.c +++ b/hw/gpio/pca9552.c @@ -76,7 +76,7 @@ static void pca955x_display_pins_status(PCA955xState *s, return; } if (trace_event_get_state_backends(TRACE_PCA955X_GPIO_STATUS)) { - char *buf = g_newa(char, k->pin_count + 1); + char buf[PCA955X_PIN_COUNT_MAX + 1]; for (i = 0; i < k->pin_count; i++) { if (extract32(pins_status, i, 1)) { @@ -432,7 +432,7 @@ static const Property pca955x_properties[] = { DEFINE_PROP_STRING("description", PCA955xState, description), }; -static void pca955x_class_init(ObjectClass *klass, void *data) +static void pca955x_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); @@ -454,7 +454,7 @@ static const TypeInfo pca955x_info = { .abstract = true, }; -static void pca9552_class_init(ObjectClass *oc, void *data) +static void pca9552_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCA955xClass *pc = PCA955X_CLASS(oc); diff --git a/hw/gpio/pca9554.c b/hw/gpio/pca9554.c index 7301fce..de3f883 100644 --- a/hw/gpio/pca9554.c +++ b/hw/gpio/pca9554.c @@ -292,7 +292,7 @@ static const Property pca9554_properties[] = { DEFINE_PROP_STRING("description", PCA9554State, description), }; -static void pca9554_class_init(ObjectClass *klass, void *data) +static void pca9554_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/gpio/pcf8574.c b/hw/gpio/pcf8574.c index 208efe6..274b44b 100644 --- a/hw/gpio/pcf8574.c +++ b/hw/gpio/pcf8574.c @@ -138,7 +138,7 @@ static void pcf8574_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out_named(dev, &s->intrq, "nINT", 1); } -static void pcf8574_class_init(ObjectClass *klass, void *data) +static void pcf8574_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c index 2e69785..1acca3f 100644 --- a/hw/gpio/pl061.c +++ b/hw/gpio/pl061.c @@ -566,7 +566,7 @@ static const Property pl061_props[] = { DEFINE_PROP_UINT32("pulldowns", PL061State, pulldowns, 0x0), }; -static void pl061_class_init(ObjectClass *klass, void *data) +static void pl061_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/gpio/sifive_gpio.c b/hw/gpio/sifive_gpio.c index 0d5206a..5831647 100644 --- a/hw/gpio/sifive_gpio.c +++ b/hw/gpio/sifive_gpio.c @@ -370,7 +370,7 @@ static void sifive_gpio_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(DEVICE(s), s->output, s->ngpio); } -static void sifive_gpio_class_init(ObjectClass *klass, void *data) +static void sifive_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/gpio/stm32l4x5_gpio.c b/hw/gpio/stm32l4x5_gpio.c index f69fc1d..414ce83 100644 --- a/hw/gpio/stm32l4x5_gpio.c +++ b/hw/gpio/stm32l4x5_gpio.c @@ -454,7 +454,7 @@ static const Property stm32l4x5_gpio_properties[] = { DEFINE_PROP_UINT32("pupd-reset", Stm32l4x5GpioState, pupdr_reset, 0), }; -static void stm32l4x5_gpio_class_init(ObjectClass *klass, void *data) +static void stm32l4x5_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c index 7342440..b8d27f5 100644 --- a/hw/gpio/zaurus.c +++ b/hw/gpio/zaurus.c @@ -243,7 +243,7 @@ static const VMStateDescription vmstate_scoop_regs = { }, }; -static void scoop_sysbus_class_init(ObjectClass *klass, void *data) +static void scoop_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/hppa/machine.c b/hw/hppa/machine.c index c5f2476..dacedc5 100644 --- a/hw/hppa/machine.c +++ b/hw/hppa/machine.c @@ -11,6 +11,7 @@ #include "elf.h" #include "hw/loader.h" #include "qemu/error-report.h" +#include "exec/target_page.h" #include "system/reset.h" #include "system/system.h" #include "system/qtest.h" @@ -682,7 +683,7 @@ static void hppa_nmi(NMIState *n, int cpu_index, Error **errp) } } -static void HP_B160L_machine_init_class_init(ObjectClass *oc, void *data) +static void HP_B160L_machine_init_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { TYPE_HPPA_CPU, @@ -712,13 +713,13 @@ static const TypeInfo HP_B160L_machine_init_typeinfo = { .name = MACHINE_TYPE_NAME("B160L"), .parent = TYPE_MACHINE, .class_init = HP_B160L_machine_init_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { } }, }; -static void HP_C3700_machine_init_class_init(ObjectClass *oc, void *data) +static void HP_C3700_machine_init_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { TYPE_HPPA64_CPU, @@ -748,7 +749,7 @@ static const TypeInfo HP_C3700_machine_init_typeinfo = { .name = MACHINE_TYPE_NAME("C3700"), .parent = TYPE_MACHINE, .class_init = HP_C3700_machine_init_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { } }, diff --git a/hw/hyperv/hv-balloon-our_range_memslots.h b/hw/hyperv/hv-balloon-our_range_memslots.h index df3b686..b1f19d7 100644 --- a/hw/hyperv/hv-balloon-our_range_memslots.h +++ b/hw/hyperv/hv-balloon-our_range_memslots.h @@ -11,7 +11,7 @@ #define HW_HYPERV_HV_BALLOON_OUR_RANGE_MEMSLOTS_H -#include "exec/memory.h" +#include "system/memory.h" #include "qom/object.h" #include "hv-balloon-page_range_tree.h" diff --git a/hw/hyperv/hv-balloon.c b/hw/hyperv/hv-balloon.c index 6f33c3e..6dbcb2d 100644 --- a/hw/hyperv/hv-balloon.c +++ b/hw/hyperv/hv-balloon.c @@ -10,9 +10,9 @@ #include "qemu/osdep.h" #include "hv-balloon-internal.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "exec/cpu-common.h" -#include "exec/ramblock.h" +#include "system/ramblock.h" #include "hw/boards.h" #include "hw/hyperv/dynmem-proto.h" #include "hw/hyperv/hv-balloon.h" @@ -67,10 +67,6 @@ * these requests */ -struct HvBalloonClass { - VMBusDeviceClass parent_class; -} HvBalloonClass; - typedef enum State { /* not a real state */ S_NO_CHANGE = 0, @@ -162,8 +158,9 @@ typedef struct HvBalloon { MemoryRegion *mr; } HvBalloon; -OBJECT_DEFINE_TYPE_WITH_INTERFACES(HvBalloon, hv_balloon, HV_BALLOON, VMBUS_DEVICE, \ - { TYPE_MEMORY_DEVICE }, { }) +OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(HvBalloon, hv_balloon, \ + HV_BALLOON, VMBUS_DEVICE, \ + { TYPE_MEMORY_DEVICE }, { }) #define HV_BALLOON_SET_STATE(hvb, news) \ do { \ @@ -1743,7 +1740,7 @@ static const Property hv_balloon_properties[] = { DEFINE_PROP_UINT64(HV_BALLOON_ADDR_PROP, HvBalloon, addr, 0), }; -static void hv_balloon_class_init(ObjectClass *klass, void *data) +static void hv_balloon_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VMBusDeviceClass *vdc = VMBUS_DEVICE_CLASS(klass); diff --git a/hw/hyperv/hyperv.c b/hw/hyperv/hyperv.c index 831e04f..e4d0688 100644 --- a/hw/hyperv/hyperv.c +++ b/hw/hyperv/hyperv.c @@ -11,8 +11,10 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include "qapi/error.h" -#include "exec/address-spaces.h" -#include "exec/memory.h" +#include "system/address-spaces.h" +#include "system/memory.h" +#include "exec/target_page.h" +#include "linux/kvm.h" #include "system/kvm.h" #include "qemu/bitops.h" #include "qemu/error-report.h" @@ -23,8 +25,7 @@ #include "hw/hyperv/hyperv.h" #include "qom/object.h" #include "target/i386/kvm/hyperv-proto.h" -#include "target/i386/cpu.h" -#include "exec/cpu-all.h" +#include "exec/target_page.h" struct SynICState { DeviceState parent_obj; @@ -133,7 +134,7 @@ static void synic_reset(DeviceState *dev) assert(QLIST_EMPTY(&synic->sint_routes)); } -static void synic_class_init(ObjectClass *klass, void *data) +static void synic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/hyperv/hyperv_testdev.c b/hw/hyperv/hyperv_testdev.c index a630ca7..2d4a636 100644 --- a/hw/hyperv/hyperv_testdev.c +++ b/hw/hyperv/hyperv_testdev.c @@ -303,7 +303,7 @@ static void hv_test_dev_realizefn(DeviceState *d, Error **errp) memory_region_add_subregion(io, 0x3000, &dev->sint_control); } -static void hv_test_dev_class_init(ObjectClass *klass, void *data) +static void hv_test_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/hyperv/meson.build b/hw/hyperv/meson.build index d3d2668..d1cf781 100644 --- a/hw/hyperv/meson.build +++ b/hw/hyperv/meson.build @@ -1,5 +1,6 @@ -specific_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c')) -specific_ss.add(when: 'CONFIG_HYPERV_TESTDEV', if_true: files('hyperv_testdev.c')) -specific_ss.add(when: 'CONFIG_VMBUS', if_true: files('vmbus.c')) -specific_ss.add(when: 'CONFIG_SYNDBG', if_true: files('syndbg.c')) -specific_ss.add(when: 'CONFIG_HV_BALLOON', if_true: files('hv-balloon.c', 'hv-balloon-page_range_tree.c', 'hv-balloon-our_range_memslots.c'), if_false: files('hv-balloon-stub.c')) +system_ss.add(when: 'CONFIG_HYPERV', if_true: files('hyperv.c')) +system_ss.add(when: 'CONFIG_HYPERV_TESTDEV', if_true: files('hyperv_testdev.c')) +system_ss.add(when: 'CONFIG_VMBUS', if_true: files('vmbus.c')) +system_ss.add(when: 'CONFIG_SYNDBG', if_true: files('syndbg.c')) +system_ss.add(when: 'CONFIG_HV_BALLOON', if_true: files('hv-balloon.c', 'hv-balloon-page_range_tree.c', 'hv-balloon-our_range_memslots.c')) +system_ss.add(when: 'CONFIG_HV_BALLOON', if_false: files('hv-balloon-stub.c')) diff --git a/hw/hyperv/syndbg.c b/hw/hyperv/syndbg.c index d3e3917..ac7e15f 100644 --- a/hw/hyperv/syndbg.c +++ b/hw/hyperv/syndbg.c @@ -10,11 +10,12 @@ #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/sockets.h" +#include "qemu/units.h" #include "qapi/error.h" #include "migration/vmstate.h" #include "hw/qdev-properties.h" #include "hw/loader.h" -#include "cpu.h" +#include "exec/target_page.h" #include "hw/hyperv/hyperv.h" #include "hw/hyperv/vmbus-bridge.h" #include "hw/hyperv/hyperv-proto.h" @@ -183,12 +184,15 @@ static bool create_udp_pkt(HvSynDbg *syndbg, void *pkt, uint32_t pkt_len, return true; } +#define MSG_BUFSZ (4 * KiB) + static uint16_t handle_recv_msg(HvSynDbg *syndbg, uint64_t outgpa, uint32_t count, bool is_raw, uint32_t options, uint64_t timeout, uint32_t *retrieved_count) { uint16_t ret; - uint8_t data_buf[TARGET_PAGE_SIZE - UDP_PKT_HEADER_SIZE]; + g_assert(MSG_BUFSZ >= qemu_target_page_size()); + QEMU_UNINITIALIZED uint8_t data_buf[MSG_BUFSZ]; hwaddr out_len; void *out_data; ssize_t recv_byte_count; @@ -201,7 +205,7 @@ static uint16_t handle_recv_msg(HvSynDbg *syndbg, uint64_t outgpa, recv_byte_count = 0; } else { recv_byte_count = recv(syndbg->socket, data_buf, - MIN(sizeof(data_buf), count), MSG_WAITALL); + MIN(MSG_BUFSZ, count), MSG_WAITALL); if (recv_byte_count == -1) { return HV_STATUS_INVALID_PARAMETER; } @@ -372,7 +376,7 @@ static const Property hv_syndbg_properties[] = { DEFINE_PROP_BOOL("use_hcalls", HvSynDbg, use_hcalls, false), }; -static void hv_syndbg_class_init(ObjectClass *klass, void *data) +static void hv_syndbg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/hyperv/vmbus.c b/hw/hyperv/vmbus.c index f195e56..961406c 100644 --- a/hw/hyperv/vmbus.c +++ b/hw/hyperv/vmbus.c @@ -10,6 +10,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" +#include "exec/target_page.h" #include "qapi/error.h" #include "migration/vmstate.h" #include "hw/qdev-properties.h" @@ -18,7 +19,7 @@ #include "hw/hyperv/vmbus.h" #include "hw/hyperv/vmbus-bridge.h" #include "hw/sysbus.h" -#include "cpu.h" +#include "exec/target_page.h" #include "trace.h" enum { @@ -2350,7 +2351,7 @@ static const Property vmbus_dev_props[] = { }; -static void vmbus_dev_class_init(ObjectClass *klass, void *data) +static void vmbus_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *kdev = DEVICE_CLASS(klass); device_class_set_props(kdev, vmbus_dev_props); @@ -2468,7 +2469,7 @@ static char *vmbus_get_fw_dev_path(DeviceState *dev) return g_strdup_printf("%s@%s", qdev_fw_name(dev), uuid); } -static void vmbus_class_init(ObjectClass *klass, void *data) +static void vmbus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -2655,7 +2656,7 @@ static const Property vmbus_bridge_props[] = { DEFINE_PROP_UINT8("irq", VMBusBridge, irq, 7), }; -static void vmbus_bridge_class_init(ObjectClass *klass, void *data) +static void vmbus_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); SysBusDeviceClass *sk = SYS_BUS_DEVICE_CLASS(klass); diff --git a/hw/i2c/allwinner-i2c.c b/hw/i2c/allwinner-i2c.c index 66d6431..fe887e1 100644 --- a/hw/i2c/allwinner-i2c.c +++ b/hw/i2c/allwinner-i2c.c @@ -438,7 +438,7 @@ static void allwinner_i2c_realize(DeviceState *dev, Error **errp) s->bus = i2c_init_bus(dev, "i2c"); } -static void allwinner_i2c_class_init(ObjectClass *klass, void *data) +static void allwinner_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/i2c/aspeed_i2c.c b/hw/i2c/aspeed_i2c.c index a8fbb9f..83fb906 100644 --- a/hw/i2c/aspeed_i2c.c +++ b/hw/i2c/aspeed_i2c.c @@ -1263,7 +1263,7 @@ static const Property aspeed_i2c_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void aspeed_i2c_class_init(ObjectClass *klass, void *data) +static void aspeed_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1390,7 +1390,8 @@ static void aspeed_i2c_bus_slave_send_async(I2CSlave *slave, uint8_t data) aspeed_i2c_bus_raise_interrupt(bus); } -static void aspeed_i2c_bus_slave_class_init(ObjectClass *klass, void *data) +static void aspeed_i2c_bus_slave_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); @@ -1451,7 +1452,7 @@ static const Property aspeed_i2c_bus_properties[] = { AspeedI2CState *), }; -static void aspeed_i2c_bus_class_init(ObjectClass *klass, void *data) +static void aspeed_i2c_bus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1483,7 +1484,7 @@ static uint8_t *aspeed_2400_i2c_bus_pool_base(AspeedI2CBus *bus) return &pool_page[ARRAY_FIELD_EX32(bus->regs, I2CD_POOL_CTRL, OFFSET)]; } -static void aspeed_2400_i2c_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass); @@ -1517,7 +1518,7 @@ static uint8_t *aspeed_2500_i2c_bus_pool_base(AspeedI2CBus *bus) return bus->pool; } -static void aspeed_2500_i2c_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass); @@ -1547,7 +1548,7 @@ static qemu_irq aspeed_2600_i2c_bus_get_irq(AspeedI2CBus *bus) return bus->irq; } -static void aspeed_2600_i2c_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass); @@ -1571,7 +1572,7 @@ static const TypeInfo aspeed_2600_i2c_info = { .class_init = aspeed_2600_i2c_class_init, }; -static void aspeed_1030_i2c_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass); @@ -1595,7 +1596,7 @@ static const TypeInfo aspeed_1030_i2c_info = { .class_init = aspeed_1030_i2c_class_init, }; -static void aspeed_2700_i2c_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedI2CClass *aic = ASPEED_I2C_CLASS(klass); diff --git a/hw/i2c/bcm2835_i2c.c b/hw/i2c/bcm2835_i2c.c index 67bfdef..be11cca 100644 --- a/hw/i2c/bcm2835_i2c.c +++ b/hw/i2c/bcm2835_i2c.c @@ -258,7 +258,7 @@ static const VMStateDescription vmstate_bcm2835_i2c = { } }; -static void bcm2835_i2c_class_init(ObjectClass *klass, void *data) +static void bcm2835_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c index de5f5aa..e020f31 100644 --- a/hw/i2c/bitbang_i2c.c +++ b/hw/i2c/bitbang_i2c.c @@ -222,7 +222,7 @@ static void gpio_i2c_init(Object *obj) qdev_init_gpio_out(dev, &s->out, 1); } -static void gpio_i2c_class_init(ObjectClass *klass, void *data) +static void gpio_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/core.c b/hw/i2c/core.c index 26bb185..4b6345b 100644 --- a/hw/i2c/core.c +++ b/hw/i2c/core.c @@ -401,7 +401,7 @@ static bool i2c_slave_match(I2CSlave *candidate, uint8_t address, return false; } -static void i2c_slave_class_init(ObjectClass *klass, void *data) +static void i2c_slave_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); diff --git a/hw/i2c/exynos4210_i2c.c b/hw/i2c/exynos4210_i2c.c index b1d0009..9d0c1cd 100644 --- a/hw/i2c/exynos4210_i2c.c +++ b/hw/i2c/exynos4210_i2c.c @@ -309,7 +309,7 @@ static void exynos4210_i2c_init(Object *obj) s->bus = i2c_init_bus(dev, "i2c"); } -static void exynos4210_i2c_class_init(ObjectClass *klass, void *data) +static void exynos4210_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/i2c_mux_pca954x.c b/hw/i2c/i2c_mux_pca954x.c index 779cc4e..a8ef640 100644 --- a/hw/i2c/i2c_mux_pca954x.c +++ b/hw/i2c/i2c_mux_pca954x.c @@ -172,13 +172,13 @@ I2CBus *pca954x_i2c_get_bus(I2CSlave *mux, uint8_t channel) return pca954x->bus[channel]; } -static void pca9546_class_init(ObjectClass *klass, void *data) +static void pca9546_class_init(ObjectClass *klass, const void *data) { Pca954xClass *s = PCA954X_CLASS(klass); s->nchans = PCA9546_CHANNEL_COUNT; } -static void pca9548_class_init(ObjectClass *klass, void *data) +static void pca9548_class_init(ObjectClass *klass, const void *data) { Pca954xClass *s = PCA954X_CLASS(klass); s->nchans = PCA9548_CHANNEL_COUNT; @@ -215,7 +215,7 @@ static const Property pca954x_props[] = { DEFINE_PROP_STRING("name", Pca954xState, name), }; -static void pca954x_class_init(ObjectClass *klass, void *data) +static void pca954x_class_init(ObjectClass *klass, const void *data) { I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c index d62213b..d26177c 100644 --- a/hw/i2c/imx_i2c.c +++ b/hw/i2c/imx_i2c.c @@ -79,13 +79,12 @@ static void imx_i2c_reset(DeviceState *dev) static inline void imx_i2c_raise_interrupt(IMXI2CState *s) { - /* - * raise an interrupt if the device is enabled and it is configured - * to generate some interrupts. - */ - if (imx_i2c_is_enabled(s) && imx_i2c_interrupt_is_enabled(s)) { + if (imx_i2c_is_enabled(s)) { s->i2sr |= I2SR_IIF; - qemu_irq_raise(s->irq); + + if (imx_i2c_interrupt_is_enabled(s)) { + qemu_irq_raise(s->irq); + } } } @@ -297,7 +296,7 @@ static void imx_i2c_realize(DeviceState *dev, Error **errp) s->bus = i2c_init_bus(dev, NULL); } -static void imx_i2c_class_init(ObjectClass *klass, void *data) +static void imx_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/microbit_i2c.c b/hw/i2c/microbit_i2c.c index 06fbd18..2291d63 100644 --- a/hw/i2c/microbit_i2c.c +++ b/hw/i2c/microbit_i2c.c @@ -105,7 +105,7 @@ static void microbit_i2c_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } -static void microbit_i2c_class_init(ObjectClass *klass, void *data) +static void microbit_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/mpc_i2c.c b/hw/i2c/mpc_i2c.c index 913d044..25f91b7 100644 --- a/hw/i2c/mpc_i2c.c +++ b/hw/i2c/mpc_i2c.c @@ -334,7 +334,7 @@ static void mpc_i2c_realize(DeviceState *dev, Error **errp) i2c->bus = i2c_init_bus(dev, "i2c"); } -static void mpc_i2c_class_init(ObjectClass *klass, void *data) +static void mpc_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/npcm7xx_smbus.c b/hw/i2c/npcm7xx_smbus.c index 22d68fc..179852a 100644 --- a/hw/i2c/npcm7xx_smbus.c +++ b/hw/i2c/npcm7xx_smbus.c @@ -1075,7 +1075,7 @@ static const VMStateDescription vmstate_npcm7xx_smbus = { }, }; -static void npcm7xx_smbus_class_init(ObjectClass *klass, void *data) +static void npcm7xx_smbus_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c index a641db2..751bf74 100644 --- a/hw/i2c/omap_i2c.c +++ b/hw/i2c/omap_i2c.c @@ -55,16 +55,16 @@ struct OMAPI2CState { uint16_t test; }; -#define OMAP2_INTR_REV 0x34 -#define OMAP2_GC_REV 0x34 +#define OMAP2_INTR_REV 0x34 +#define OMAP2_GC_REV 0x34 static void omap_i2c_interrupts_update(OMAPI2CState *s) { qemu_set_irq(s->irq, s->stat & s->mask); - if ((s->dma >> 15) & 1) /* RDMA_EN */ - qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */ - if ((s->dma >> 7) & 1) /* XDMA_EN */ - qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */ + if ((s->dma >> 15) & 1) /* RDMA_EN */ + qemu_set_irq(s->drq[0], (s->stat >> 3) & 1); /* RRDY */ + if ((s->dma >> 7) & 1) /* XDMA_EN */ + qemu_set_irq(s->drq[1], (s->stat >> 4) & 1); /* XRDY */ } static void omap_i2c_fifo_run(OMAPI2CState *s) @@ -74,25 +74,25 @@ static void omap_i2c_fifo_run(OMAPI2CState *s) if (!i2c_bus_busy(s->bus)) return; - if ((s->control >> 2) & 1) { /* RM */ - if ((s->control >> 1) & 1) { /* STP */ + if ((s->control >> 2) & 1) { /* RM */ + if ((s->control >> 1) & 1) { /* STP */ i2c_end_transfer(s->bus); - s->control &= ~(1 << 1); /* STP */ + s->control &= ~(1 << 1); /* STP */ s->count_cur = s->count; s->txlen = 0; - } else if ((s->control >> 9) & 1) { /* TRX */ + } else if ((s->control >> 9) & 1) { /* TRX */ while (ack && s->txlen) ack = (i2c_send(s->bus, (s->fifo >> ((-- s->txlen) << 3)) & 0xff) >= 0); - s->stat |= 1 << 4; /* XRDY */ + s->stat |= 1 << 4; /* XRDY */ } else { while (s->rxlen < 4) s->fifo |= i2c_recv(s->bus) << ((s->rxlen ++) << 3); - s->stat |= 1 << 3; /* RRDY */ + s->stat |= 1 << 3; /* RRDY */ } } else { - if ((s->control >> 9) & 1) { /* TRX */ + if ((s->control >> 9) & 1) { /* TRX */ while (ack && s->count_cur && s->txlen) { ack = (i2c_send(s->bus, (s->fifo >> ((-- s->txlen) << 3)) & @@ -100,12 +100,12 @@ static void omap_i2c_fifo_run(OMAPI2CState *s) s->count_cur --; } if (ack && s->count_cur) - s->stat |= 1 << 4; /* XRDY */ + s->stat |= 1 << 4; /* XRDY */ else - s->stat &= ~(1 << 4); /* XRDY */ + s->stat &= ~(1 << 4); /* XRDY */ if (!s->count_cur) { - s->stat |= 1 << 2; /* ARDY */ - s->control &= ~(1 << 10); /* MST */ + s->stat |= 1 << 2; /* ARDY */ + s->control &= ~(1 << 10); /* MST */ } } else { while (s->count_cur && s->rxlen < 4) { @@ -113,26 +113,26 @@ static void omap_i2c_fifo_run(OMAPI2CState *s) s->count_cur --; } if (s->rxlen) - s->stat |= 1 << 3; /* RRDY */ + s->stat |= 1 << 3; /* RRDY */ else - s->stat &= ~(1 << 3); /* RRDY */ + s->stat &= ~(1 << 3); /* RRDY */ } if (!s->count_cur) { - if ((s->control >> 1) & 1) { /* STP */ + if ((s->control >> 1) & 1) { /* STP */ i2c_end_transfer(s->bus); - s->control &= ~(1 << 1); /* STP */ + s->control &= ~(1 << 1); /* STP */ s->count_cur = s->count; s->txlen = 0; } else { - s->stat |= 1 << 2; /* ARDY */ - s->control &= ~(1 << 10); /* MST */ + s->stat |= 1 << 2; /* ARDY */ + s->control &= ~(1 << 10); /* MST */ } } } - s->stat |= (!ack) << 1; /* NACK */ + s->stat |= (!ack) << 1; /* NACK */ if (!ack) - s->control &= ~(1 << 1); /* STP */ + s->control &= ~(1 << 1); /* STP */ } static void omap_i2c_reset(DeviceState *dev) @@ -163,16 +163,16 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr) uint16_t ret; switch (offset) { - case 0x00: /* I2C_REV */ - return s->revision; /* REV */ + case 0x00: /* I2C_REV */ + return s->revision; /* REV */ - case 0x04: /* I2C_IE */ + case 0x04: /* I2C_IE */ return s->mask; - case 0x08: /* I2C_STAT */ + case 0x08: /* I2C_STAT */ return s->stat | (i2c_bus_busy(s->bus) << 12); - case 0x0c: /* I2C_IV */ + case 0x0c: /* I2C_IV */ if (s->revision >= OMAP2_INTR_REV) break; ret = ctz32(s->stat & s->mask); @@ -185,18 +185,18 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr) omap_i2c_interrupts_update(s); return ret; - case 0x10: /* I2C_SYSS */ - return (s->control >> 15) & 1; /* I2C_EN */ + case 0x10: /* I2C_SYSS */ + return (s->control >> 15) & 1; /* I2C_EN */ - case 0x14: /* I2C_BUF */ + case 0x14: /* I2C_BUF */ return s->dma; - case 0x18: /* I2C_CNT */ - return s->count_cur; /* DCOUNT */ + case 0x18: /* I2C_CNT */ + return s->count_cur; /* DCOUNT */ - case 0x1c: /* I2C_DATA */ + case 0x1c: /* I2C_DATA */ ret = 0; - if (s->control & (1 << 14)) { /* BE */ + if (s->control & (1 << 14)) { /* BE */ ret |= ((s->fifo >> 0) & 0xff) << 8; ret |= ((s->fifo >> 8) & 0xff) << 0; } else { @@ -204,7 +204,7 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr) ret |= ((s->fifo >> 0) & 0xff) << 0; } if (s->rxlen == 1) { - s->stat |= 1 << 15; /* SBD */ + s->stat |= 1 << 15; /* SBD */ s->rxlen = 0; } else if (s->rxlen > 1) { if (s->rxlen > 2) @@ -214,41 +214,41 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr) /* XXX: remote access (qualifier) error - what's that? */ } if (!s->rxlen) { - s->stat &= ~(1 << 3); /* RRDY */ - if (((s->control >> 10) & 1) && /* MST */ - ((~s->control >> 9) & 1)) { /* TRX */ - s->stat |= 1 << 2; /* ARDY */ - s->control &= ~(1 << 10); /* MST */ + s->stat &= ~(1 << 3); /* RRDY */ + if (((s->control >> 10) & 1) && /* MST */ + ((~s->control >> 9) & 1)) { /* TRX */ + s->stat |= 1 << 2; /* ARDY */ + s->control &= ~(1 << 10); /* MST */ } } - s->stat &= ~(1 << 11); /* ROVR */ + s->stat &= ~(1 << 11); /* ROVR */ omap_i2c_fifo_run(s); omap_i2c_interrupts_update(s); return ret; - case 0x20: /* I2C_SYSC */ + case 0x20: /* I2C_SYSC */ return 0; - case 0x24: /* I2C_CON */ + case 0x24: /* I2C_CON */ return s->control; - case 0x28: /* I2C_OA */ + case 0x28: /* I2C_OA */ return s->addr[0]; - case 0x2c: /* I2C_SA */ + case 0x2c: /* I2C_SA */ return s->addr[1]; - case 0x30: /* I2C_PSC */ + case 0x30: /* I2C_PSC */ return s->divider; - case 0x34: /* I2C_SCLL */ + case 0x34: /* I2C_SCLL */ return s->times[0]; - case 0x38: /* I2C_SCLH */ + case 0x38: /* I2C_SCLH */ return s->times[1]; - case 0x3c: /* I2C_SYSTEST */ - if (s->test & (1 << 15)) { /* ST_EN */ + case 0x3c: /* I2C_SYSTEST */ + if (s->test & (1 << 15)) { /* ST_EN */ s->test ^= 0xa; return s->test; } else @@ -267,17 +267,17 @@ static void omap_i2c_write(void *opaque, hwaddr addr, int nack; switch (offset) { - case 0x00: /* I2C_REV */ - case 0x0c: /* I2C_IV */ - case 0x10: /* I2C_SYSS */ + case 0x00: /* I2C_REV */ + case 0x0c: /* I2C_IV */ + case 0x10: /* I2C_SYSS */ OMAP_RO_REG(addr); return; - case 0x04: /* I2C_IE */ + case 0x04: /* I2C_IE */ s->mask = value & (s->revision < OMAP2_GC_REV ? 0x1f : 0x3f); break; - case 0x08: /* I2C_STAT */ + case 0x08: /* I2C_STAT */ if (s->revision < OMAP2_INTR_REV) { OMAP_RO_REG(addr); return; @@ -288,40 +288,40 @@ static void omap_i2c_write(void *opaque, hwaddr addr, omap_i2c_interrupts_update(s); break; - case 0x14: /* I2C_BUF */ + case 0x14: /* I2C_BUF */ s->dma = value & 0x8080; - if (value & (1 << 15)) /* RDMA_EN */ - s->mask &= ~(1 << 3); /* RRDY_IE */ - if (value & (1 << 7)) /* XDMA_EN */ - s->mask &= ~(1 << 4); /* XRDY_IE */ + if (value & (1 << 15)) /* RDMA_EN */ + s->mask &= ~(1 << 3); /* RRDY_IE */ + if (value & (1 << 7)) /* XDMA_EN */ + s->mask &= ~(1 << 4); /* XRDY_IE */ break; - case 0x18: /* I2C_CNT */ - s->count = value; /* DCOUNT */ + case 0x18: /* I2C_CNT */ + s->count = value; /* DCOUNT */ break; - case 0x1c: /* I2C_DATA */ + case 0x1c: /* I2C_DATA */ if (s->txlen > 2) { /* XXX: remote access (qualifier) error - what's that? */ break; } s->fifo <<= 16; s->txlen += 2; - if (s->control & (1 << 14)) { /* BE */ + if (s->control & (1 << 14)) { /* BE */ s->fifo |= ((value >> 8) & 0xff) << 8; s->fifo |= ((value >> 0) & 0xff) << 0; } else { s->fifo |= ((value >> 0) & 0xff) << 8; s->fifo |= ((value >> 8) & 0xff) << 0; } - s->stat &= ~(1 << 10); /* XUDF */ + s->stat &= ~(1 << 10); /* XUDF */ if (s->txlen > 2) - s->stat &= ~(1 << 4); /* XRDY */ + s->stat &= ~(1 << 4); /* XRDY */ omap_i2c_fifo_run(s); omap_i2c_interrupts_update(s); break; - case 0x20: /* I2C_SYSC */ + case 0x20: /* I2C_SYSC */ if (s->revision < OMAP2_INTR_REV) { OMAP_BAD_REG(addr); return; @@ -332,9 +332,9 @@ static void omap_i2c_write(void *opaque, hwaddr addr, } break; - case 0x24: /* I2C_CON */ + case 0x24: /* I2C_CON */ s->control = value & 0xcf87; - if (~value & (1 << 15)) { /* I2C_EN */ + if (~value & (1 << 15)) { /* I2C_EN */ if (s->revision < OMAP2_INTR_REV) { omap_i2c_reset(DEVICE(s)); } @@ -351,14 +351,14 @@ static void omap_i2c_write(void *opaque, hwaddr addr, __func__); break; } - if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */ - nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */ - (~value >> 9) & 1); /* TRX */ - s->stat |= nack << 1; /* NACK */ - s->control &= ~(1 << 0); /* STT */ + if ((value & (1 << 15)) && value & (1 << 0)) { /* STT */ + nack = !!i2c_start_transfer(s->bus, s->addr[1], /* SA */ + (~value >> 9) & 1); /* TRX */ + s->stat |= nack << 1; /* NACK */ + s->control &= ~(1 << 0); /* STT */ s->fifo = 0; if (nack) - s->control &= ~(1 << 1); /* STP */ + s->control &= ~(1 << 1); /* STP */ else { s->count_cur = s->count; omap_i2c_fifo_run(s); @@ -367,34 +367,34 @@ static void omap_i2c_write(void *opaque, hwaddr addr, } break; - case 0x28: /* I2C_OA */ + case 0x28: /* I2C_OA */ s->addr[0] = value & 0x3ff; break; - case 0x2c: /* I2C_SA */ + case 0x2c: /* I2C_SA */ s->addr[1] = value & 0x3ff; break; - case 0x30: /* I2C_PSC */ + case 0x30: /* I2C_PSC */ s->divider = value; break; - case 0x34: /* I2C_SCLL */ + case 0x34: /* I2C_SCLL */ s->times[0] = value; break; - case 0x38: /* I2C_SCLH */ + case 0x38: /* I2C_SCLH */ s->times[1] = value; break; - case 0x3c: /* I2C_SYSTEST */ + case 0x3c: /* I2C_SYSTEST */ s->test = value & 0xf80f; - if (value & (1 << 11)) /* SBB */ + if (value & (1 << 11)) /* SBB */ if (s->revision >= OMAP2_INTR_REV) { s->stat |= 0x3f; omap_i2c_interrupts_update(s); } - if (value & (1 << 15)) { /* ST_EN */ + if (value & (1 << 15)) { /* ST_EN */ qemu_log_mask(LOG_UNIMP, "%s: System Test not supported\n", __func__); } @@ -413,7 +413,7 @@ static void omap_i2c_writeb(void *opaque, hwaddr addr, int offset = addr & OMAP_MPUI_REG_MASK; switch (offset) { - case 0x1c: /* I2C_DATA */ + case 0x1c: /* I2C_DATA */ if (s->txlen > 2) { /* XXX: remote access (qualifier) error - what's that? */ break; @@ -421,9 +421,9 @@ static void omap_i2c_writeb(void *opaque, hwaddr addr, s->fifo <<= 8; s->txlen += 1; s->fifo |= value & 0xff; - s->stat &= ~(1 << 10); /* XUDF */ + s->stat &= ~(1 << 10); /* XUDF */ if (s->txlen > 2) - s->stat &= ~(1 << 4); /* XRDY */ + s->stat &= ~(1 << 4); /* XRDY */ omap_i2c_fifo_run(s); omap_i2c_interrupts_update(s); break; @@ -515,7 +515,7 @@ static const Property omap_i2c_properties[] = { DEFINE_PROP_UINT8("revision", OMAPI2CState, revision, 0), }; -static void omap_i2c_class_init(ObjectClass *klass, void *data) +static void omap_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/pmbus_device.c b/hw/i2c/pmbus_device.c index ba1d2fd..853dc4b 100644 --- a/hw/i2c/pmbus_device.c +++ b/hw/i2c/pmbus_device.c @@ -1902,7 +1902,7 @@ static void pmbus_device_finalize(Object *obj) g_free(pmdev->pages); } -static void pmbus_device_class_init(ObjectClass *klass, void *data) +static void pmbus_device_class_init(ObjectClass *klass, const void *data) { SMBusDeviceClass *k = SMBUS_DEVICE_CLASS(klass); diff --git a/hw/i2c/ppc4xx_i2c.c b/hw/i2c/ppc4xx_i2c.c index 7b124a7..09d4c49 100644 --- a/hw/i2c/ppc4xx_i2c.c +++ b/hw/i2c/ppc4xx_i2c.c @@ -354,7 +354,7 @@ static void ppc4xx_i2c_init(Object *o) bitbang_i2c_init(&s->bitbang, s->bus); } -static void ppc4xx_i2c_class_init(ObjectClass *klass, void *data) +static void ppc4xx_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i2c/smbus_eeprom.c b/hw/i2c/smbus_eeprom.c index e3e96d4..0a1088f 100644 --- a/hw/i2c/smbus_eeprom.c +++ b/hw/i2c/smbus_eeprom.c @@ -137,7 +137,7 @@ static void smbus_eeprom_realize(DeviceState *dev, Error **errp) } } -static void smbus_eeprom_class_initfn(ObjectClass *klass, void *data) +static void smbus_eeprom_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SMBusDeviceClass *sc = SMBUS_DEVICE_CLASS(klass); diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c index 208f263..956c9b5 100644 --- a/hw/i2c/smbus_ich9.c +++ b/hw/i2c/smbus_ich9.c @@ -118,7 +118,7 @@ static void build_ich9_smb_aml(AcpiDevAmlIf *adev, Aml *scope) qbus_build_aml(bus, scope); } -static void ich9_smb_class_init(ObjectClass *klass, void *data) +static void ich9_smb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -145,7 +145,7 @@ static const TypeInfo ich9_smb_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(ICH9SMBState), .class_init = ich9_smb_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { TYPE_ACPI_DEV_AML_IF }, { }, diff --git a/hw/i2c/smbus_slave.c b/hw/i2c/smbus_slave.c index 9f9afc2..cfb61c8 100644 --- a/hw/i2c/smbus_slave.c +++ b/hw/i2c/smbus_slave.c @@ -201,7 +201,7 @@ static int smbus_i2c_send(I2CSlave *s, uint8_t data) return 0; } -static void smbus_device_class_init(ObjectClass *klass, void *data) +static void smbus_device_class_init(ObjectClass *klass, const void *data) { I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); diff --git a/hw/i386/Kconfig b/hw/i386/Kconfig index d34ce07..eb65bda 100644 --- a/hw/i386/Kconfig +++ b/hw/i386/Kconfig @@ -10,6 +10,11 @@ config SGX bool depends on KVM +config TDX + bool + select X86_FW_OVMF + depends on KVM + config PC bool imply APPLESMC @@ -26,6 +31,7 @@ config PC imply QXL imply SEV imply SGX + imply TDX imply TEST_DEVICES imply TPM_CRB imply TPM_TIS_ISA diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 3fffa4a..61851cc 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -139,7 +139,7 @@ static void init_common_fadt_data(MachineState *ms, Object *o, /* * "ICH9-LPC" or "PIIX4_PM" has "smm-compat" property to keep the old * behavior for compatibility irrelevant to smm_enabled, which doesn't - * comforms to ACPI spec. + * conform to the ACPI spec. */ bool smm_enabled = object_property_get_bool(o, "smm-compat", NULL) ? true : x86_machine_is_smm_enabled(x86ms); @@ -589,8 +589,8 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus) } } -static bool build_append_notfication_callback(Aml *parent_scope, - const PCIBus *bus) +static bool build_append_notification_callback(Aml *parent_scope, + const PCIBus *bus) { Aml *method; PCIBus *sec; @@ -604,7 +604,7 @@ static bool build_append_notfication_callback(Aml *parent_scope, continue; } nr_notifiers = nr_notifiers + - build_append_notfication_callback(br_scope, sec); + build_append_notification_callback(br_scope, sec); /* * add new child scope to parent * and keep track of bus that have PCNT, @@ -1773,7 +1773,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, PCIBus *b = PCI_HOST_BRIDGE(pci_host)->bus; scope = aml_scope("\\_SB.PCI0"); - has_pcnt = build_append_notfication_callback(scope, b); + has_pcnt = build_append_notification_callback(scope, b); if (has_pcnt) { aml_append(dsdt, scope); } @@ -2333,10 +2333,10 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, build_append_int_noprefix(table_data, ivhd_blob->len + 24, 2); /* DeviceID */ build_append_int_noprefix(table_data, - object_property_get_int(OBJECT(&s->pci), "addr", + object_property_get_int(OBJECT(s->pci), "addr", &error_abort), 2); /* Capability offset */ - build_append_int_noprefix(table_data, s->pci.capab_offset, 2); + build_append_int_noprefix(table_data, s->pci->capab_offset, 2); /* IOMMU base address */ build_append_int_noprefix(table_data, s->mr_mmio.addr, 8); /* PCI Segment Group */ @@ -2368,10 +2368,10 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, build_append_int_noprefix(table_data, ivhd_blob->len + 40, 2); /* DeviceID */ build_append_int_noprefix(table_data, - object_property_get_int(OBJECT(&s->pci), "addr", + object_property_get_int(OBJECT(s->pci), "addr", &error_abort), 2); /* Capability offset */ - build_append_int_noprefix(table_data, s->pci.capab_offset, 2); + build_append_int_noprefix(table_data, s->pci->capab_offset, 2); /* IOMMU base address */ build_append_int_noprefix(table_data, s->mr_mmio.addr, 8); /* PCI Segment Group */ diff --git a/hw/i386/acpi-build.h b/hw/i386/acpi-build.h index 0dce155..275ec05 100644 --- a/hw/i386/acpi-build.h +++ b/hw/i386/acpi-build.h @@ -5,7 +5,7 @@ extern const struct AcpiGenericAddress x86_nvdimm_acpi_dsmio; -/* PCI Hot-plug registers bases. See docs/spec/acpi_pci_hotplug.txt */ +/* PCI Hot-plug registers' base. See docs/specs/acpi_pci_hotplug.rst */ #define ACPI_PCIHP_SEJ_BASE 0x8 #define ACPI_PCIHP_BNMR_BASE 0x10 diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c index 0cc2919..7bd0806 100644 --- a/hw/i386/acpi-common.c +++ b/hw/i386/acpi-common.c @@ -23,7 +23,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/acpi/acpi.h" #include "hw/acpi/aml-build.h" #include "hw/acpi/utils.h" diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c index 279da6b..bc65717 100644 --- a/hw/i386/acpi-microvm.c +++ b/hw/i386/acpi-microvm.c @@ -24,7 +24,7 @@ #include "qemu/cutils.h" #include "qapi/error.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/acpi/acpi.h" #include "hw/acpi/acpi_aml_interface.h" #include "hw/acpi/aml-build.h" diff --git a/hw/i386/amd_iommu.c b/hw/i386/amd_iommu.c index 5f9b952..963aa24 100644 --- a/hw/i386/amd_iommu.c +++ b/hw/i386/amd_iommu.c @@ -167,11 +167,11 @@ static void amdvi_generate_msi_interrupt(AMDVIState *s) { MSIMessage msg = {}; MemTxAttrs attrs = { - .requester_id = pci_requester_id(&s->pci.dev) + .requester_id = pci_requester_id(&s->pci->dev) }; - if (msi_enabled(&s->pci.dev)) { - msg = msi_get_message(&s->pci.dev, 0); + if (msi_enabled(&s->pci->dev)) { + msg = msi_get_message(&s->pci->dev, 0); address_space_stl_le(&address_space_memory, msg.address, msg.data, attrs, NULL); } @@ -239,7 +239,7 @@ static void amdvi_page_fault(AMDVIState *s, uint16_t devid, info |= AMDVI_EVENT_IOPF_I | AMDVI_EVENT_IOPF; amdvi_encode_event(evt, devid, addr, info); amdvi_log_event(s, evt); - pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, + pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, PCI_STATUS_SIG_TARGET_ABORT); } /* @@ -256,7 +256,7 @@ static void amdvi_log_devtab_error(AMDVIState *s, uint16_t devid, amdvi_encode_event(evt, devid, devtab, info); amdvi_log_event(s, evt); - pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, + pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, PCI_STATUS_SIG_TARGET_ABORT); } /* log an event trying to access command buffer @@ -269,7 +269,7 @@ static void amdvi_log_command_error(AMDVIState *s, hwaddr addr) amdvi_encode_event(evt, 0, addr, info); amdvi_log_event(s, evt); - pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, + pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, PCI_STATUS_SIG_TARGET_ABORT); } /* log an illegal command event @@ -310,7 +310,7 @@ static void amdvi_log_pagetab_error(AMDVIState *s, uint16_t devid, info |= AMDVI_EVENT_PAGE_TAB_HW_ERROR; amdvi_encode_event(evt, devid, addr, info); amdvi_log_event(s, evt); - pci_word_test_and_set_mask(s->pci.dev.config + PCI_STATUS, + pci_word_test_and_set_mask(s->pci->dev.config + PCI_STATUS, PCI_STATUS_SIG_TARGET_ABORT); } @@ -1426,7 +1426,6 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) AMDVIState *s = opaque; AMDVIAddressSpace **iommu_as, *amdvi_dev_as; int bus_num = pci_bus_num(bus); - X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s); iommu_as = s->address_spaces[bus_num]; @@ -1486,15 +1485,8 @@ static AddressSpace *amdvi_host_dma_iommu(PCIBus *bus, void *opaque, int devfn) AMDVI_INT_ADDR_FIRST, &amdvi_dev_as->iommu_ir, 1); - if (!x86_iommu->pt_supported) { - memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false); - memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), - true); - } else { - memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), - false); - memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, true); - } + memory_region_set_enabled(&amdvi_dev_as->iommu_nodma, false); + memory_region_set_enabled(MEMORY_REGION(&amdvi_dev_as->iommu), true); } return &iommu_as[devfn]->as; } @@ -1607,26 +1599,92 @@ static void amdvi_sysbus_reset(DeviceState *dev) { AMDVIState *s = AMD_IOMMU_DEVICE(dev); - msi_reset(&s->pci.dev); + msi_reset(&s->pci->dev); amdvi_init(s); } +static const VMStateDescription vmstate_amdvi_sysbus_migratable = { + .name = "amd-iommu", + .version_id = 1, + .minimum_version_id = 1, + .priority = MIG_PRI_IOMMU, + .fields = (VMStateField[]) { + /* Updated in amdvi_handle_control_write() */ + VMSTATE_BOOL(enabled, AMDVIState), + VMSTATE_BOOL(ga_enabled, AMDVIState), + VMSTATE_BOOL(ats_enabled, AMDVIState), + VMSTATE_BOOL(cmdbuf_enabled, AMDVIState), + VMSTATE_BOOL(completion_wait_intr, AMDVIState), + VMSTATE_BOOL(evtlog_enabled, AMDVIState), + VMSTATE_BOOL(evtlog_intr, AMDVIState), + /* Updated in amdvi_handle_devtab_write() */ + VMSTATE_UINT64(devtab, AMDVIState), + VMSTATE_UINT64(devtab_len, AMDVIState), + /* Updated in amdvi_handle_cmdbase_write() */ + VMSTATE_UINT64(cmdbuf, AMDVIState), + VMSTATE_UINT64(cmdbuf_len, AMDVIState), + /* Updated in amdvi_handle_cmdhead_write() */ + VMSTATE_UINT32(cmdbuf_head, AMDVIState), + /* Updated in amdvi_handle_cmdtail_write() */ + VMSTATE_UINT32(cmdbuf_tail, AMDVIState), + /* Updated in amdvi_handle_evtbase_write() */ + VMSTATE_UINT64(evtlog, AMDVIState), + VMSTATE_UINT32(evtlog_len, AMDVIState), + /* Updated in amdvi_handle_evthead_write() */ + VMSTATE_UINT32(evtlog_head, AMDVIState), + /* Updated in amdvi_handle_evttail_write() */ + VMSTATE_UINT32(evtlog_tail, AMDVIState), + /* Updated in amdvi_handle_pprbase_write() */ + VMSTATE_UINT64(ppr_log, AMDVIState), + VMSTATE_UINT32(pprlog_len, AMDVIState), + /* Updated in amdvi_handle_pprhead_write() */ + VMSTATE_UINT32(pprlog_head, AMDVIState), + /* Updated in amdvi_handle_tailhead_write() */ + VMSTATE_UINT32(pprlog_tail, AMDVIState), + /* MMIO registers */ + VMSTATE_UINT8_ARRAY(mmior, AMDVIState, AMDVI_MMIO_SIZE), + VMSTATE_UINT8_ARRAY(romask, AMDVIState, AMDVI_MMIO_SIZE), + VMSTATE_UINT8_ARRAY(w1cmask, AMDVIState, AMDVI_MMIO_SIZE), + VMSTATE_END_OF_LIST() + } +}; + static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) { + DeviceClass *dc = (DeviceClass *) object_get_class(OBJECT(dev)); AMDVIState *s = AMD_IOMMU_DEVICE(dev); MachineState *ms = MACHINE(qdev_get_machine()); PCMachineState *pcms = PC_MACHINE(ms); X86MachineState *x86ms = X86_MACHINE(ms); PCIBus *bus = pcms->pcibus; - s->iotlb = g_hash_table_new_full(amdvi_uint64_hash, - amdvi_uint64_equal, g_free, g_free); + if (s->pci_id) { + PCIDevice *pdev = NULL; + int ret = pci_qdev_find_device(s->pci_id, &pdev); - /* This device should take care of IOMMU PCI properties */ - if (!qdev_realize(DEVICE(&s->pci), &bus->qbus, errp)) { - return; + if (ret) { + error_report("Cannot find PCI device '%s'", s->pci_id); + return; + } + + if (!object_dynamic_cast(OBJECT(pdev), TYPE_AMD_IOMMU_PCI)) { + error_report("Device '%s' must be an AMDVI-PCI device type", s->pci_id); + return; + } + + s->pci = AMD_IOMMU_PCI(pdev); + dc->vmsd = &vmstate_amdvi_sysbus_migratable; + } else { + s->pci = AMD_IOMMU_PCI(object_new(TYPE_AMD_IOMMU_PCI)); + /* This device should take care of IOMMU PCI properties */ + if (!qdev_realize(DEVICE(s->pci), &bus->qbus, errp)) { + return; + } } + s->iotlb = g_hash_table_new_full(amdvi_uint64_hash, + amdvi_uint64_equal, g_free, g_free); + /* Pseudo address space under root PCI bus. */ x86ms->ioapic_as = amdvi_host_dma_iommu(bus, s, AMDVI_IOAPIC_SB_DEVID); @@ -1657,12 +1715,21 @@ static void amdvi_sysbus_realize(DeviceState *dev, Error **errp) exit(EXIT_FAILURE); } + if (s->xtsup) { + if (kvm_irqchip_is_split() && !kvm_enable_x2apic()) { + error_report("AMD IOMMU xtsup=on requires x2APIC support on " + "the KVM side"); + exit(EXIT_FAILURE); + } + } + pci_setup_iommu(bus, &amdvi_iommu_ops, s); amdvi_init(s); } static const Property amdvi_properties[] = { DEFINE_PROP_BOOL("xtsup", AMDVIState, xtsup, false), + DEFINE_PROP_STRING("pci-id", AMDVIState, pci_id), }; static const VMStateDescription vmstate_amdvi_sysbus = { @@ -1670,14 +1737,7 @@ static const VMStateDescription vmstate_amdvi_sysbus = { .unmigratable = 1 }; -static void amdvi_sysbus_instance_init(Object *klass) -{ - AMDVIState *s = AMD_IOMMU_DEVICE(klass); - - object_initialize(&s->pci, sizeof(s->pci), TYPE_AMD_IOMMU_PCI); -} - -static void amdvi_sysbus_class_init(ObjectClass *klass, void *data) +static void amdvi_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); X86IOMMUClass *dc_class = X86_IOMMU_DEVICE_CLASS(klass); @@ -1696,11 +1756,10 @@ static const TypeInfo amdvi_sysbus = { .name = TYPE_AMD_IOMMU_DEVICE, .parent = TYPE_X86_IOMMU_DEVICE, .instance_size = sizeof(AMDVIState), - .instance_init = amdvi_sysbus_instance_init, .class_init = amdvi_sysbus_class_init }; -static void amdvi_pci_class_init(ObjectClass *klass, void *data) +static void amdvi_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1719,13 +1778,14 @@ static const TypeInfo amdvi_pci = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(AMDVIPCIState), .class_init = amdvi_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, void *data) +static void amdvi_iommu_memory_region_class_init(ObjectClass *klass, + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/i386/amd_iommu.h b/hw/i386/amd_iommu.h index 2812513..5672bde 100644 --- a/hw/i386/amd_iommu.h +++ b/hw/i386/amd_iommu.h @@ -315,7 +315,8 @@ struct AMDVIPCIState { struct AMDVIState { X86IOMMUState iommu; /* IOMMU bus device */ - AMDVIPCIState pci; /* IOMMU PCI device */ + AMDVIPCIState *pci; /* IOMMU PCI device */ + char *pci_id; /* ID of AMDVI-PCI device, if user created */ uint32_t version; @@ -328,7 +329,7 @@ struct AMDVIState { bool excl_enabled; hwaddr devtab; /* base address device table */ - size_t devtab_len; /* device table length */ + uint64_t devtab_len; /* device table length */ hwaddr cmdbuf; /* command buffer base address */ uint64_t cmdbuf_len; /* command buffer length */ diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 0608aec..69d72ad 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -1728,8 +1728,6 @@ static bool vtd_as_pt_enabled(VTDAddressSpace *as) static bool vtd_switch_address_space(VTDAddressSpace *as) { bool use_iommu, pt; - /* Whether we need to take the BQL on our own */ - bool take_bql = !bql_locked(); assert(as); @@ -1746,9 +1744,7 @@ static bool vtd_switch_address_space(VTDAddressSpace *as) * from vtd_pt_enable_fast_path(). However the memory APIs need * it. We'd better make sure we have had it already, or, take it. */ - if (take_bql) { - bql_lock(); - } + BQL_LOCK_GUARD(); /* Turn off first then on the other */ if (use_iommu) { @@ -1801,10 +1797,6 @@ static bool vtd_switch_address_space(VTDAddressSpace *as) memory_region_set_enabled(&as->iommu_ir_fault, false); } - if (take_bql) { - bql_unlock(); - } - return use_iommu; } @@ -4213,9 +4205,30 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, VTDAddressSpace *vtd_dev_as; char name[128]; + vtd_iommu_lock(s); vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key); + vtd_iommu_unlock(s); + if (!vtd_dev_as) { - struct vtd_as_key *new_key = g_malloc(sizeof(*new_key)); + struct vtd_as_key *new_key; + /* Slow path */ + + /* + * memory_region_add_subregion_overlap requires the bql, + * make sure we own it. + */ + BQL_LOCK_GUARD(); + vtd_iommu_lock(s); + + /* Check again as we released the lock for a moment */ + vtd_dev_as = g_hash_table_lookup(s->vtd_address_spaces, &key); + if (vtd_dev_as) { + vtd_iommu_unlock(s); + return vtd_dev_as; + } + + /* Still nothing, allocate a new address space */ + new_key = g_malloc(sizeof(*new_key)); new_key->bus = bus; new_key->devfn = devfn; @@ -4306,6 +4319,8 @@ VTDAddressSpace *vtd_find_add_as(IntelIOMMUState *s, PCIBus *bus, vtd_switch_address_space(vtd_dev_as); g_hash_table_insert(s->vtd_address_spaces, new_key, vtd_dev_as); + + vtd_iommu_unlock(s); } return vtd_dev_as; } @@ -4859,7 +4874,7 @@ static void vtd_realize(DeviceState *dev, Error **errp) qemu_add_machine_init_done_notifier(&vtd_machine_done_notify); } -static void vtd_class_init(ObjectClass *klass, void *data) +static void vtd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); X86IOMMUClass *x86_class = X86_IOMMU_DEVICE_CLASS(klass); @@ -4887,7 +4902,7 @@ static const TypeInfo vtd_info = { }; static void vtd_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c index 7575106..1be9bfe 100644 --- a/hw/i386/kvm/apic.c +++ b/hw/i386/kvm/apic.c @@ -17,6 +17,7 @@ #include "system/hw_accel.h" #include "system/kvm.h" #include "kvm/kvm_i386.h" +#include "kvm/tdx.h" static inline void kvm_apic_set_reg(struct kvm_lapic_state *kapic, int reg_id, uint32_t val) @@ -141,6 +142,10 @@ static void kvm_apic_put(CPUState *cs, run_on_cpu_data data) struct kvm_lapic_state kapic; int ret; + if (is_tdx_vm()) { + return; + } + kvm_put_apicbase(s->cpu, s->apicbase); kvm_put_apic_state(s, &kapic); @@ -240,7 +245,7 @@ static void kvm_apic_unrealize(DeviceState *dev) { } -static void kvm_apic_class_init(ObjectClass *klass, void *data) +static void kvm_apic_class_init(ObjectClass *klass, const void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c index 1744355..f563827 100644 --- a/hw/i386/kvm/clock.c +++ b/hw/i386/kvm/clock.c @@ -309,7 +309,7 @@ static const Property kvmclock_properties[] = { mach_use_reliable_get_clock, true), }; -static void kvmclock_class_init(ObjectClass *klass, void *data) +static void kvmclock_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c index 3b92771..14b78f3 100644 --- a/hw/i386/kvm/i8254.c +++ b/hw/i386/kvm/i8254.c @@ -292,7 +292,7 @@ static const Property kvm_pit_properties[] = { lost_tick_policy, LOST_TICK_POLICY_DELAY), }; -static void kvm_pit_class_init(ObjectClass *klass, void *data) +static void kvm_pit_class_init(ObjectClass *klass, const void *data) { KVMPITClass *kpc = KVM_PIT_CLASS(klass); PITCommonClass *k = PIT_COMMON_CLASS(klass); diff --git a/hw/i386/kvm/i8259.c b/hw/i386/kvm/i8259.c index 272c04d..8a72d6e 100644 --- a/hw/i386/kvm/i8259.c +++ b/hw/i386/kvm/i8259.c @@ -139,7 +139,7 @@ qemu_irq *kvm_i8259_init(ISABus *bus) return qemu_allocate_irqs(kvm_pic_set_irq, NULL, ISA_NUM_IRQS); } -static void kvm_i8259_class_init(ObjectClass *klass, void *data) +static void kvm_i8259_class_init(ObjectClass *klass, const void *data) { KVMPICClass *kpc = KVM_PIC_CLASS(klass); PICCommonClass *k = PIC_COMMON_CLASS(klass); diff --git a/hw/i386/kvm/ioapic.c b/hw/i386/kvm/ioapic.c index 5419e19..693ee97 100644 --- a/hw/i386/kvm/ioapic.c +++ b/hw/i386/kvm/ioapic.c @@ -137,7 +137,7 @@ static const Property kvm_ioapic_properties[] = { DEFINE_PROP_UINT32("gsi_base", KVMIOAPICState, kvm_gsi_base, 0), }; -static void kvm_ioapic_class_init(ObjectClass *klass, void *data) +static void kvm_ioapic_class_init(ObjectClass *klass, const void *data) { IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/kvm/xen-stubs.c b/hw/i386/kvm/xen-stubs.c index d03131e..ce73119 100644 --- a/hw/i386/kvm/xen-stubs.c +++ b/hw/i386/kvm/xen-stubs.c @@ -12,7 +12,6 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc-target.h" #include "xen_evtchn.h" #include "xen_primary_console.h" @@ -38,15 +37,3 @@ void xen_primary_console_create(void) void xen_primary_console_set_be_port(uint16_t port) { } -#ifdef TARGET_I386 -EvtchnInfoList *qmp_xen_event_list(Error **errp) -{ - error_setg(errp, "Xen event channel emulation not enabled"); - return NULL; -} - -void qmp_xen_event_inject(uint32_t port, Error **errp) -{ - error_setg(errp, "Xen event channel emulation not enabled"); -} -#endif diff --git a/hw/i386/kvm/xen_evtchn.c b/hw/i386/kvm/xen_evtchn.c index 9b8b092..dd566c4 100644 --- a/hw/i386/kvm/xen_evtchn.c +++ b/hw/i386/kvm/xen_evtchn.c @@ -19,11 +19,11 @@ #include "monitor/monitor.h" #include "monitor/hmp.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc-target.h" +#include "qapi/qapi-commands-misc-i386.h" #include "qobject/qdict.h" #include "qom/object.h" #include "exec/target_page.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "migration/vmstate.h" #include "trace.h" @@ -271,7 +271,7 @@ static const VMStateDescription xen_evtchn_vmstate = { } }; -static void xen_evtchn_class_init(ObjectClass *klass, void *data) +static void xen_evtchn_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/kvm/xen_gnttab.c b/hw/i386/kvm/xen_gnttab.c index 7b843a7..4b9e272 100644 --- a/hw/i386/kvm/xen_gnttab.c +++ b/hw/i386/kvm/xen_gnttab.c @@ -17,7 +17,7 @@ #include "qapi/error.h" #include "qom/object.h" #include "exec/target_page.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "migration/vmstate.h" #include "hw/sysbus.h" @@ -135,7 +135,7 @@ static const VMStateDescription xen_gnttab_vmstate = { } }; -static void xen_gnttab_class_init(ObjectClass *klass, void *data) +static void xen_gnttab_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/kvm/xen_overlay.c b/hw/i386/kvm/xen_overlay.c index db9aa79..3cb7361 100644 --- a/hw/i386/kvm/xen_overlay.c +++ b/hw/i386/kvm/xen_overlay.c @@ -16,7 +16,7 @@ #include "qapi/error.h" #include "qom/object.h" #include "exec/target_page.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "migration/vmstate.h" #include "hw/sysbus.h" @@ -151,7 +151,7 @@ static void xen_overlay_reset(DeviceState *dev) kvm_xen_soft_reset(); } -static void xen_overlay_class_init(ObjectClass *klass, void *data) +static void xen_overlay_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/kvm/xen_primary_console.c b/hw/i386/kvm/xen_primary_console.c index 8ad2363..6e9d641 100644 --- a/hw/i386/kvm/xen_primary_console.c +++ b/hw/i386/kvm/xen_primary_console.c @@ -67,7 +67,7 @@ static void xen_primary_console_realize(DeviceState *dev, Error **errp) xen_primary_console_singleton = s; } -static void xen_primary_console_class_init(ObjectClass *klass, void *data) +static void xen_primary_console_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/kvm/xen_xenstore.c b/hw/i386/kvm/xen_xenstore.c index 227ad7a..42955cc 100644 --- a/hw/i386/kvm/xen_xenstore.c +++ b/hw/i386/kvm/xen_xenstore.c @@ -259,7 +259,7 @@ static const VMStateDescription xen_xenstore_vmstate = { } }; -static void xen_xenstore_class_init(ObjectClass *klass, void *data) +static void xen_xenstore_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/meson.build b/hw/i386/meson.build index 10bdfde..7896f34 100644 --- a/hw/i386/meson.build +++ b/hw/i386/meson.build @@ -32,6 +32,7 @@ i386_ss.add(when: 'CONFIG_PC', if_true: files( 'port92.c')) i386_ss.add(when: 'CONFIG_X86_FW_OVMF', if_true: files('pc_sysfw_ovmf.c'), if_false: files('pc_sysfw_ovmf-stubs.c')) +i386_ss.add(when: 'CONFIG_TDX', if_true: files('tdvf.c', 'tdvf-hob.c')) subdir('kvm') subdir('xen') diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index d0a236c..e0daf0d 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -635,7 +635,7 @@ GlobalProperty microvm_properties[] = { { "pcie-root-port", "io-reserve", "0" }, }; -static void microvm_class_init(ObjectClass *oc, void *data) +static void microvm_class_init(ObjectClass *oc, const void *data) { X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); MicrovmMachineClass *mmc = MICROVM_MACHINE_CLASS(oc); @@ -726,7 +726,7 @@ static const TypeInfo microvm_machine_info = { .instance_init = microvm_machine_initfn, .class_size = sizeof(MicrovmMachineClass), .class_init = microvm_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, diff --git a/hw/i386/monitor.c b/hw/i386/monitor.c index 1921e4d..79df965 100644 --- a/hw/i386/monitor.c +++ b/hw/i386/monitor.c @@ -26,7 +26,7 @@ #include "monitor/monitor.h" #include "qobject/qdict.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc-target.h" +#include "qapi/qapi-commands-misc-i386.h" #include "hw/i386/x86.h" #include "hw/rtc/mc146818rtc.h" diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c index cd07a05..6e6b96b 100644 --- a/hw/i386/multiboot.c +++ b/hw/i386/multiboot.c @@ -29,6 +29,7 @@ #include "multiboot.h" #include "hw/loader.h" #include "elf.h" +#include "exec/target_page.h" #include "system/system.h" #include "qemu/error-report.h" diff --git a/hw/i386/nitro_enclave.c b/hw/i386/nitro_enclave.c index 4b69f26..5ee50f3 100644 --- a/hw/i386/nitro_enclave.c +++ b/hw/i386/nitro_enclave.c @@ -293,7 +293,7 @@ static void nitro_enclave_set_parent_id(Object *obj, const char *value, nems->parent_id = g_strdup(value); } -static void nitro_enclave_class_init(ObjectClass *oc, void *data) +static void nitro_enclave_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); MicrovmMachineClass *mmc = MICROVM_MACHINE_CLASS(oc); diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 1b5d55e..b211633 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "exec/target_page.h" #include "hw/i386/pc.h" #include "hw/char/serial-isa.h" #include "hw/char/parallel.h" @@ -43,6 +44,7 @@ #include "system/xen.h" #include "system/reset.h" #include "kvm/kvm_i386.h" +#include "kvm/tdx.h" #include "hw/xen/xen.h" #include "qobject/qlist.h" #include "qemu/error-report.h" @@ -258,28 +260,6 @@ GlobalProperty pc_compat_2_6[] = { }; const size_t pc_compat_2_6_len = G_N_ELEMENTS(pc_compat_2_6); -GlobalProperty pc_compat_2_5[] = {}; -const size_t pc_compat_2_5_len = G_N_ELEMENTS(pc_compat_2_5); - -GlobalProperty pc_compat_2_4[] = { - PC_CPU_MODEL_IDS("2.4.0") - { "Haswell-" TYPE_X86_CPU, "abm", "off" }, - { "Haswell-noTSX-" TYPE_X86_CPU, "abm", "off" }, - { "Broadwell-" TYPE_X86_CPU, "abm", "off" }, - { "Broadwell-noTSX-" TYPE_X86_CPU, "abm", "off" }, - { "host" "-" TYPE_X86_CPU, "host-cache-info", "on" }, - { TYPE_X86_CPU, "check", "off" }, - { "qemu64" "-" TYPE_X86_CPU, "sse4a", "on" }, - { "qemu64" "-" TYPE_X86_CPU, "abm", "on" }, - { "qemu64" "-" TYPE_X86_CPU, "popcnt", "on" }, - { "qemu32" "-" TYPE_X86_CPU, "popcnt", "on" }, - { "Opteron_G2" "-" TYPE_X86_CPU, "rdtscp", "on" }, - { "Opteron_G3" "-" TYPE_X86_CPU, "rdtscp", "on" }, - { "Opteron_G4" "-" TYPE_X86_CPU, "rdtscp", "on" }, - { "Opteron_G5" "-" TYPE_X86_CPU, "rdtscp", "on", } -}; -const size_t pc_compat_2_4_len = G_N_ELEMENTS(pc_compat_2_4); - /* * @PC_FW_DATA: * Size of the chunk of memory at the top of RAM for the BIOS ACPI tables @@ -975,21 +955,23 @@ void pc_memory_init(PCMachineState *pcms, /* Initialize PC system firmware */ pc_system_firmware_init(pcms, rom_memory); - option_rom_mr = g_malloc(sizeof(*option_rom_mr)); - if (machine_require_guest_memfd(machine)) { - memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom", - PC_ROM_SIZE, &error_fatal); - } else { - memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, - &error_fatal); - if (pcmc->pci_enabled) { - memory_region_set_readonly(option_rom_mr, true); + if (!is_tdx_vm()) { + option_rom_mr = g_malloc(sizeof(*option_rom_mr)); + if (machine_require_guest_memfd(machine)) { + memory_region_init_ram_guest_memfd(option_rom_mr, NULL, "pc.rom", + PC_ROM_SIZE, &error_fatal); + } else { + memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE, + &error_fatal); + if (pcmc->pci_enabled) { + memory_region_set_readonly(option_rom_mr, true); + } } + memory_region_add_subregion_overlap(rom_memory, + PC_ROM_MIN_VGA, + option_rom_mr, + 1); } - memory_region_add_subregion_overlap(rom_memory, - PC_ROM_MIN_VGA, - option_rom_mr, - 1); fw_cfg = fw_cfg_arch_create(machine, x86ms->boot_cpus, x86ms->apic_id_limit); @@ -998,14 +980,13 @@ void pc_memory_init(PCMachineState *pcms, if (machine->device_memory) { uint64_t *val = g_malloc(sizeof(*val)); - uint64_t res_mem_end = machine->device_memory->base; - - if (!pcmc->broken_reserved_end) { - res_mem_end += memory_region_size(&machine->device_memory->mr); - } + uint64_t res_mem_end; if (pcms->cxl_devices_state.is_enabled) { res_mem_end = cxl_resv_end; + } else { + res_mem_end = machine->device_memory->base + + memory_region_size(&machine->device_memory->mr); } *val = cpu_to_le64(ROUND_UP(res_mem_end, 1 * GiB)); fw_cfg_add_file(fw_cfg, "etc/reserved-memory-end", val, sizeof(*val)); @@ -1043,9 +1024,7 @@ uint64_t pc_pci_hole64_start(void) hole64_start = pc_get_cxl_range_end(pcms); } else if (pcmc->has_reserved_memory && (ms->ram_size < ms->maxram_size)) { pc_get_device_memory_range(pcms, &hole64_start, &size); - if (!pcmc->broken_reserved_end) { - hole64_start += size; - } + hole64_start += size; } else { hole64_start = pc_above_4g_end(pcms); } @@ -1057,7 +1036,6 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus) { DeviceState *dev = NULL; - rom_set_order_override(FW_CFG_ORDER_OVERRIDE_VGA); if (pci_bus) { PCIDevice *pcidev = pci_vga_init(pci_bus); dev = pcidev ? &pcidev->qdev : NULL; @@ -1065,7 +1043,7 @@ DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus) ISADevice *isadev = isa_vga_init(isa_bus); dev = isadev ? DEVICE(isadev) : NULL; } - rom_reset_order_override(); + return dev; } @@ -1255,8 +1233,6 @@ void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) bool default_is_ne2k = g_str_equal(mc->default_nic, TYPE_ISA_NE2000); NICInfo *nd; - rom_set_order_override(FW_CFG_ORDER_OVERRIDE_NIC); - while ((nd = qemu_find_nic_info(TYPE_ISA_NE2000, default_is_ne2k, NULL))) { pc_init_ne2k_isa(isa_bus, nd, &error_fatal); } @@ -1265,8 +1241,6 @@ void pc_nic_init(PCMachineClass *pcmc, ISABus *isa_bus, PCIBus *pci_bus) if (pci_bus) { pci_init_nic_devices(pci_bus, mc->default_nic); } - - rom_reset_order_override(); } void pc_i8259_create(ISABus *isa_bus, qemu_irq *i8259_irqs) @@ -1765,7 +1739,7 @@ static bool pc_hotplug_allowed(MachineState *ms, DeviceState *dev, Error **errp) return true; } -static void pc_machine_class_init(ObjectClass *oc, void *data) +static void pc_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); @@ -1869,7 +1843,7 @@ static const TypeInfo pc_machine_info = { .instance_init = pc_machine_initfn, .class_size = sizeof(PCMachineClass), .class_init = pc_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c index dbb59df..ea7572e 100644 --- a/hw/i386/pc_piix.c +++ b/hw/i386/pc_piix.c @@ -47,7 +47,7 @@ #include "hw/i386/kvm/clock.h" #include "hw/sysbus.h" #include "hw/i2c/smbus_eeprom.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/acpi/acpi.h" #include "qapi/error.h" #include "qemu/error-report.h" @@ -285,6 +285,8 @@ static void pc_init1(MachineState *machine, const char *pci_type) pcms->idebus[0] = qdev_get_child_bus(dev, "ide.0"); pcms->idebus[1] = qdev_get_child_bus(dev, "ide.1"); } else { + uint32_t irq; + isa_bus = isa_bus_new(NULL, system_memory, system_io, &error_abort); isa_bus_register_input_irqs(isa_bus, x86ms->gsi); @@ -292,6 +294,9 @@ static void pc_init1(MachineState *machine, const char *pci_type) x86ms->rtc = isa_new(TYPE_MC146818_RTC); qdev_prop_set_int32(DEVICE(x86ms->rtc), "base_year", 2000); isa_realize_and_unref(x86ms->rtc, isa_bus, &error_fatal); + irq = object_property_get_uint(OBJECT(x86ms->rtc), "irq", + &error_fatal); + isa_connect_gpio_out(ISA_DEVICE(x86ms->rtc), 0, irq); i8257_dma_init(OBJECT(machine), isa_bus, 0); pcms->hpet_enabled = false; @@ -778,32 +783,6 @@ static void pc_i440fx_machine_2_6_options(MachineClass *m) DEFINE_I440FX_MACHINE(2, 6); -static void pc_i440fx_machine_2_5_options(MachineClass *m) -{ - X86MachineClass *x86mc = X86_MACHINE_CLASS(m); - - pc_i440fx_machine_2_6_options(m); - x86mc->save_tsc_khz = false; - m->legacy_fw_cfg_order = 1; - compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len); - compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len); -} - -DEFINE_I440FX_MACHINE(2, 5); - -static void pc_i440fx_machine_2_4_options(MachineClass *m) -{ - PCMachineClass *pcmc = PC_MACHINE_CLASS(m); - - pc_i440fx_machine_2_5_options(m); - m->hw_version = "2.4.0"; - pcmc->broken_reserved_end = true; - compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len); - compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len); -} - -DEFINE_I440FX_MACHINE(2, 4); - #ifdef CONFIG_ISAPC static void isapc_machine_options(MachineClass *m) { diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c index c538b3d..33211b1 100644 --- a/hw/i386/pc_q35.c +++ b/hw/i386/pc_q35.c @@ -672,29 +672,3 @@ static void pc_q35_machine_2_6_options(MachineClass *m) } DEFINE_Q35_MACHINE(2, 6); - -static void pc_q35_machine_2_5_options(MachineClass *m) -{ - X86MachineClass *x86mc = X86_MACHINE_CLASS(m); - - pc_q35_machine_2_6_options(m); - x86mc->save_tsc_khz = false; - m->legacy_fw_cfg_order = 1; - compat_props_add(m->compat_props, hw_compat_2_5, hw_compat_2_5_len); - compat_props_add(m->compat_props, pc_compat_2_5, pc_compat_2_5_len); -} - -DEFINE_Q35_MACHINE(2, 5); - -static void pc_q35_machine_2_4_options(MachineClass *m) -{ - PCMachineClass *pcmc = PC_MACHINE_CLASS(m); - - pc_q35_machine_2_5_options(m); - m->hw_version = "2.4.0"; - pcmc->broken_reserved_end = true; - compat_props_add(m->compat_props, hw_compat_2_4, hw_compat_2_4_len); - compat_props_add(m->compat_props, pc_compat_2_4, pc_compat_2_4_len); -} - -DEFINE_Q35_MACHINE(2, 4); diff --git a/hw/i386/pc_sysfw.c b/hw/i386/pc_sysfw.c index 1eeb58a..821396c 100644 --- a/hw/i386/pc_sysfw.c +++ b/hw/i386/pc_sysfw.c @@ -37,6 +37,7 @@ #include "hw/block/flash.h" #include "system/kvm.h" #include "target/i386/sev.h" +#include "kvm/tdx.h" #define FLASH_SECTOR_SIZE 4096 @@ -280,5 +281,11 @@ void x86_firmware_configure(hwaddr gpa, void *ptr, int size) } sev_encrypt_flash(gpa, ptr, size, &error_fatal); + } else if (is_tdx_vm()) { + ret = tdx_parse_tdvf(ptr, size); + if (ret) { + error_report("failed to parse TDVF for TDX VM"); + exit(1); + } } } diff --git a/hw/i386/pc_sysfw_ovmf.c b/hw/i386/pc_sysfw_ovmf.c index 07a4c26..da947c3 100644 --- a/hw/i386/pc_sysfw_ovmf.c +++ b/hw/i386/pc_sysfw_ovmf.c @@ -26,6 +26,7 @@ #include "qemu/osdep.h" #include "qemu/error-report.h" #include "hw/i386/pc.h" +#include "exec/target_page.h" #include "cpu.h" #define OVMF_TABLE_FOOTER_GUID "96b582de-1fb2-45f7-baea-a366c55a082d" diff --git a/hw/i386/port92.c b/hw/i386/port92.c index 1ba3f32..39b6f31 100644 --- a/hw/i386/port92.c +++ b/hw/i386/port92.c @@ -97,7 +97,7 @@ static void port92_realizefn(DeviceState *dev, Error **errp) isa_register_ioport(isadev, &s->io, 0x92); } -static void port92_class_initfn(ObjectClass *klass, void *data) +static void port92_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/sgx-epc.c b/hw/i386/sgx-epc.c index 875e1c5..2b3b282 100644 --- a/hw/i386/sgx-epc.c +++ b/hw/i386/sgx-epc.c @@ -17,7 +17,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "target/i386/cpu.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" static const Property sgx_epc_properties[] = { DEFINE_PROP_UINT64(SGX_EPC_ADDR_PROP, SGXEPCDevice, addr, 0), @@ -147,7 +147,7 @@ static void sgx_epc_md_fill_device_info(const MemoryDeviceState *md, info->type = MEMORY_DEVICE_INFO_KIND_SGX_EPC; } -static void sgx_epc_class_init(ObjectClass *oc, void *data) +static void sgx_epc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc); @@ -173,7 +173,7 @@ static const TypeInfo sgx_epc_info = { .instance_init = sgx_epc_init, .class_init = sgx_epc_class_init, .class_size = sizeof(DeviceClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_MEMORY_DEVICE }, { } }, diff --git a/hw/i386/sgx-stub.c b/hw/i386/sgx-stub.c index 38ff75e..d295e54 100644 --- a/hw/i386/sgx-stub.c +++ b/hw/i386/sgx-stub.c @@ -3,20 +3,20 @@ #include "monitor/hmp-target.h" #include "hw/i386/pc.h" #include "hw/i386/sgx-epc.h" +#include "qapi/qapi-commands-misc-i386.h" #include "qapi/error.h" -#include "qapi/qapi-commands-misc-target.h" void sgx_epc_build_srat(GArray *table_data) { } -SGXInfo *qmp_query_sgx(Error **errp) +SgxInfo *qmp_query_sgx(Error **errp) { error_setg(errp, "SGX support is not compiled in"); return NULL; } -SGXInfo *qmp_query_sgx_capabilities(Error **errp) +SgxInfo *qmp_query_sgx_capabilities(Error **errp) { error_setg(errp, "SGX support is not compiled in"); return NULL; diff --git a/hw/i386/sgx.c b/hw/i386/sgx.c index e665e21..e280154 100644 --- a/hw/i386/sgx.c +++ b/hw/i386/sgx.c @@ -19,8 +19,8 @@ #include "monitor/hmp-target.h" #include "qapi/error.h" #include "qemu/error-report.h" -#include "qapi/qapi-commands-misc-target.h" -#include "exec/address-spaces.h" +#include "qapi/qapi-commands-misc-i386.h" +#include "system/address-spaces.h" #include "system/hw_accel.h" #include "system/reset.h" #include <sys/ioctl.h> @@ -84,10 +84,10 @@ static uint64_t sgx_calc_section_metric(uint64_t low, uint64_t high) ((high & MAKE_64BIT_MASK(0, 20)) << 32); } -static SGXEPCSectionList *sgx_calc_host_epc_sections(void) +static SgxEpcSectionList *sgx_calc_host_epc_sections(void) { - SGXEPCSectionList *head = NULL, **tail = &head; - SGXEPCSection *section; + SgxEpcSectionList *head = NULL, **tail = &head; + SgxEpcSection *section; uint32_t i, type; uint32_t eax, ebx, ecx, edx; uint32_t j = 0; @@ -104,7 +104,7 @@ static SGXEPCSectionList *sgx_calc_host_epc_sections(void) break; } - section = g_new0(SGXEPCSection, 1); + section = g_new0(SgxEpcSection, 1); section->node = j++; section->size = sgx_calc_section_metric(ecx, edx); QAPI_LIST_APPEND(tail, section); @@ -153,9 +153,9 @@ static void sgx_epc_reset(void *opaque) } } -SGXInfo *qmp_query_sgx_capabilities(Error **errp) +SgxInfo *qmp_query_sgx_capabilities(Error **errp) { - SGXInfo *info = NULL; + SgxInfo *info = NULL; uint32_t eax, ebx, ecx, edx; Error *local_err = NULL; @@ -166,7 +166,7 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) return NULL; } - info = g_new0(SGXInfo, 1); + info = g_new0(SgxInfo, 1); host_cpuid(0x7, 0, &eax, &ebx, &ecx, &edx); info->sgx = ebx & (1U << 2) ? true : false; @@ -183,17 +183,17 @@ SGXInfo *qmp_query_sgx_capabilities(Error **errp) return info; } -static SGXEPCSectionList *sgx_get_epc_sections_list(void) +static SgxEpcSectionList *sgx_get_epc_sections_list(void) { GSList *device_list = sgx_epc_get_device_list(); - SGXEPCSectionList *head = NULL, **tail = &head; - SGXEPCSection *section; + SgxEpcSectionList *head = NULL, **tail = &head; + SgxEpcSection *section; for (; device_list; device_list = device_list->next) { DeviceState *dev = device_list->data; Object *obj = OBJECT(dev); - section = g_new0(SGXEPCSection, 1); + section = g_new0(SgxEpcSection, 1); section->node = object_property_get_uint(obj, SGX_EPC_NUMA_NODE_PROP, &error_abort); section->size = object_property_get_uint(obj, SGX_EPC_SIZE_PROP, @@ -205,9 +205,9 @@ static SGXEPCSectionList *sgx_get_epc_sections_list(void) return head; } -SGXInfo *qmp_query_sgx(Error **errp) +SgxInfo *qmp_query_sgx(Error **errp) { - SGXInfo *info = NULL; + SgxInfo *info = NULL; X86MachineState *x86ms; PCMachineState *pcms = (PCMachineState *)object_dynamic_cast(qdev_get_machine(), @@ -223,7 +223,7 @@ SGXInfo *qmp_query_sgx(Error **errp) return NULL; } - info = g_new0(SGXInfo, 1); + info = g_new0(SgxInfo, 1); info->sgx = true; info->sgx1 = true; @@ -237,8 +237,8 @@ SGXInfo *qmp_query_sgx(Error **errp) void hmp_info_sgx(Monitor *mon, const QDict *qdict) { Error *err = NULL; - SGXEPCSectionList *section_list, *section; - g_autoptr(SGXInfo) info = qmp_query_sgx(&err); + SgxEpcSectionList *section_list, *section; + g_autoptr(SgxInfo) info = qmp_query_sgx(&err); uint64_t size = 0; if (err) { diff --git a/hw/i386/tdvf-hob.c b/hw/i386/tdvf-hob.c new file mode 100644 index 0000000..782b3d1 --- /dev/null +++ b/hw/i386/tdvf-hob.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2025 Intel Corporation + * Author: Isaku Yamahata <isaku.yamahata at gmail.com> + * <isaku.yamahata at intel.com> + * Xiaoyao Li <xiaoyao.li@intel.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" +#include "standard-headers/uefi/uefi.h" +#include "hw/pci/pcie_host.h" +#include "tdvf-hob.h" + +typedef struct TdvfHob { + hwaddr hob_addr; + void *ptr; + int size; + + /* working area */ + void *current; + void *end; +} TdvfHob; + +static uint64_t tdvf_current_guest_addr(const TdvfHob *hob) +{ + return hob->hob_addr + (hob->current - hob->ptr); +} + +static void tdvf_align(TdvfHob *hob, size_t align) +{ + hob->current = QEMU_ALIGN_PTR_UP(hob->current, align); +} + +static void *tdvf_get_area(TdvfHob *hob, uint64_t size) +{ + void *ret; + + if (hob->current + size > hob->end) { + error_report("TD_HOB overrun, size = 0x%" PRIx64, size); + exit(1); + } + + ret = hob->current; + hob->current += size; + tdvf_align(hob, 8); + return ret; +} + +static void tdvf_hob_add_memory_resources(TdxGuest *tdx, TdvfHob *hob) +{ + EFI_HOB_RESOURCE_DESCRIPTOR *region; + EFI_RESOURCE_ATTRIBUTE_TYPE attr; + EFI_RESOURCE_TYPE resource_type; + + TdxRamEntry *e; + int i; + + for (i = 0; i < tdx->nr_ram_entries; i++) { + e = &tdx->ram_entries[i]; + + if (e->type == TDX_RAM_UNACCEPTED) { + resource_type = EFI_RESOURCE_MEMORY_UNACCEPTED; + attr = EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED; + } else if (e->type == TDX_RAM_ADDED) { + resource_type = EFI_RESOURCE_SYSTEM_MEMORY; + attr = EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE; + } else { + error_report("unknown TDX_RAM_ENTRY type %d", e->type); + exit(1); + } + + region = tdvf_get_area(hob, sizeof(*region)); + *region = (EFI_HOB_RESOURCE_DESCRIPTOR) { + .Header = { + .HobType = EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, + .HobLength = cpu_to_le16(sizeof(*region)), + .Reserved = cpu_to_le32(0), + }, + .Owner = EFI_HOB_OWNER_ZERO, + .ResourceType = cpu_to_le32(resource_type), + .ResourceAttribute = cpu_to_le32(attr), + .PhysicalStart = cpu_to_le64(e->address), + .ResourceLength = cpu_to_le64(e->length), + }; + } +} + +void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob) +{ + TdvfHob hob = { + .hob_addr = td_hob->address, + .size = td_hob->size, + .ptr = td_hob->mem_ptr, + + .current = td_hob->mem_ptr, + .end = td_hob->mem_ptr + td_hob->size, + }; + + EFI_HOB_GENERIC_HEADER *last_hob; + EFI_HOB_HANDOFF_INFO_TABLE *hit; + + /* Note, Efi{Free}Memory{Bottom,Top} are ignored, leave 'em zeroed. */ + hit = tdvf_get_area(&hob, sizeof(*hit)); + *hit = (EFI_HOB_HANDOFF_INFO_TABLE) { + .Header = { + .HobType = EFI_HOB_TYPE_HANDOFF, + .HobLength = cpu_to_le16(sizeof(*hit)), + .Reserved = cpu_to_le32(0), + }, + .Version = cpu_to_le32(EFI_HOB_HANDOFF_TABLE_VERSION), + .BootMode = cpu_to_le32(0), + .EfiMemoryTop = cpu_to_le64(0), + .EfiMemoryBottom = cpu_to_le64(0), + .EfiFreeMemoryTop = cpu_to_le64(0), + .EfiFreeMemoryBottom = cpu_to_le64(0), + .EfiEndOfHobList = cpu_to_le64(0), /* initialized later */ + }; + + tdvf_hob_add_memory_resources(tdx, &hob); + + last_hob = tdvf_get_area(&hob, sizeof(*last_hob)); + *last_hob = (EFI_HOB_GENERIC_HEADER) { + .HobType = EFI_HOB_TYPE_END_OF_HOB_LIST, + .HobLength = cpu_to_le16(sizeof(*last_hob)), + .Reserved = cpu_to_le32(0), + }; + hit->EfiEndOfHobList = tdvf_current_guest_addr(&hob); +} diff --git a/hw/i386/tdvf-hob.h b/hw/i386/tdvf-hob.h new file mode 100644 index 0000000..4fc6a37 --- /dev/null +++ b/hw/i386/tdvf-hob.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#ifndef HW_I386_TD_HOB_H +#define HW_I386_TD_HOB_H + +#include "hw/i386/tdvf.h" +#include "target/i386/kvm/tdx.h" + +void tdvf_hob_create(TdxGuest *tdx, TdxFirmwareEntry *td_hob); + +#define EFI_RESOURCE_ATTRIBUTE_TDVF_PRIVATE \ + (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED) + +#define EFI_RESOURCE_ATTRIBUTE_TDVF_UNACCEPTED \ + (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_TESTED) + +#define EFI_RESOURCE_ATTRIBUTE_TDVF_MMIO \ + (EFI_RESOURCE_ATTRIBUTE_PRESENT | \ + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \ + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE) + +#endif diff --git a/hw/i386/tdvf.c b/hw/i386/tdvf.c new file mode 100644 index 0000000..645d9d1 --- /dev/null +++ b/hw/i386/tdvf.c @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2025 Intel Corporation + * Author: Isaku Yamahata <isaku.yamahata at gmail.com> + * <isaku.yamahata at intel.com> + * Xiaoyao Li <xiaoyao.li@intel.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qemu/error-report.h" + +#include "hw/i386/pc.h" +#include "hw/i386/tdvf.h" +#include "system/kvm.h" + +#define TDX_METADATA_OFFSET_GUID "e47a6535-984a-4798-865e-4685a7bf8ec2" +#define TDX_METADATA_VERSION 1 +#define TDVF_SIGNATURE 0x46564454 /* TDVF as little endian */ +#define TDVF_ALIGNMENT 4096 + +/* + * the raw structs read from TDVF keeps the name convention in + * TDVF Design Guide spec. + */ +typedef struct { + uint32_t DataOffset; + uint32_t RawDataSize; + uint64_t MemoryAddress; + uint64_t MemoryDataSize; + uint32_t Type; + uint32_t Attributes; +} TdvfSectionEntry; + +typedef struct { + uint32_t Signature; + uint32_t Length; + uint32_t Version; + uint32_t NumberOfSectionEntries; + TdvfSectionEntry SectionEntries[]; +} TdvfMetadata; + +struct tdx_metadata_offset { + uint32_t offset; +}; + +static TdvfMetadata *tdvf_get_metadata(void *flash_ptr, int size) +{ + TdvfMetadata *metadata; + uint32_t offset = 0; + uint8_t *data; + + if ((uint32_t) size != size) { + return NULL; + } + + if (pc_system_ovmf_table_find(TDX_METADATA_OFFSET_GUID, &data, NULL)) { + offset = size - le32_to_cpu(((struct tdx_metadata_offset *)data)->offset); + + if (offset + sizeof(*metadata) > size) { + return NULL; + } + } else { + error_report("Cannot find TDX_METADATA_OFFSET_GUID"); + return NULL; + } + + metadata = flash_ptr + offset; + + /* Finally, verify the signature to determine if this is a TDVF image. */ + metadata->Signature = le32_to_cpu(metadata->Signature); + if (metadata->Signature != TDVF_SIGNATURE) { + error_report("Invalid TDVF signature in metadata!"); + return NULL; + } + + /* Sanity check that the TDVF doesn't overlap its own metadata. */ + metadata->Length = le32_to_cpu(metadata->Length); + if (offset + metadata->Length > size) { + return NULL; + } + + /* Only version 1 is supported/defined. */ + metadata->Version = le32_to_cpu(metadata->Version); + if (metadata->Version != TDX_METADATA_VERSION) { + return NULL; + } + + return metadata; +} + +static int tdvf_parse_and_check_section_entry(const TdvfSectionEntry *src, + TdxFirmwareEntry *entry) +{ + entry->data_offset = le32_to_cpu(src->DataOffset); + entry->data_len = le32_to_cpu(src->RawDataSize); + entry->address = le64_to_cpu(src->MemoryAddress); + entry->size = le64_to_cpu(src->MemoryDataSize); + entry->type = le32_to_cpu(src->Type); + entry->attributes = le32_to_cpu(src->Attributes); + + /* sanity check */ + if (entry->size < entry->data_len) { + error_report("Broken metadata RawDataSize 0x%x MemoryDataSize 0x%"PRIx64, + entry->data_len, entry->size); + return -1; + } + if (!QEMU_IS_ALIGNED(entry->address, TDVF_ALIGNMENT)) { + error_report("MemoryAddress 0x%"PRIx64" not page aligned", entry->address); + return -1; + } + if (!QEMU_IS_ALIGNED(entry->size, TDVF_ALIGNMENT)) { + error_report("MemoryDataSize 0x%"PRIx64" not page aligned", entry->size); + return -1; + } + + switch (entry->type) { + case TDVF_SECTION_TYPE_BFV: + case TDVF_SECTION_TYPE_CFV: + /* The sections that must be copied from firmware image to TD memory */ + if (entry->data_len == 0) { + error_report("%d section with RawDataSize == 0", entry->type); + return -1; + } + break; + case TDVF_SECTION_TYPE_TD_HOB: + case TDVF_SECTION_TYPE_TEMP_MEM: + /* The sections that no need to be copied from firmware image */ + if (entry->data_len != 0) { + error_report("%d section with RawDataSize 0x%x != 0", + entry->type, entry->data_len); + return -1; + } + break; + default: + error_report("TDVF contains unsupported section type %d", entry->type); + return -1; + } + + return 0; +} + +int tdvf_parse_metadata(TdxFirmware *fw, void *flash_ptr, int size) +{ + g_autofree TdvfSectionEntry *sections = NULL; + TdvfMetadata *metadata; + ssize_t entries_size; + int i; + + metadata = tdvf_get_metadata(flash_ptr, size); + if (!metadata) { + return -EINVAL; + } + + /* load and parse metadata entries */ + fw->nr_entries = le32_to_cpu(metadata->NumberOfSectionEntries); + if (fw->nr_entries < 2) { + error_report("Invalid number of fw entries (%u) in TDVF Metadata", + fw->nr_entries); + return -EINVAL; + } + + entries_size = fw->nr_entries * sizeof(TdvfSectionEntry); + if (metadata->Length != sizeof(*metadata) + entries_size) { + error_report("TDVF metadata len (0x%x) mismatch, expected (0x%x)", + metadata->Length, + (uint32_t)(sizeof(*metadata) + entries_size)); + return -EINVAL; + } + + fw->entries = g_new(TdxFirmwareEntry, fw->nr_entries); + sections = g_new(TdvfSectionEntry, fw->nr_entries); + + memcpy(sections, (void *)metadata + sizeof(*metadata), entries_size); + + for (i = 0; i < fw->nr_entries; i++) { + if (tdvf_parse_and_check_section_entry(§ions[i], &fw->entries[i])) { + goto err; + } + } + + fw->mem_ptr = flash_ptr; + return 0; + +err: + fw->entries = 0; + g_free(fw->entries); + return -EINVAL; +} diff --git a/hw/i386/vapic.c b/hw/i386/vapic.c index 14de9b7..0c1c92c 100644 --- a/hw/i386/vapic.c +++ b/hw/i386/vapic.c @@ -11,12 +11,13 @@ #include "qemu/osdep.h" #include "qemu/module.h" +#include "exec/target_page.h" #include "system/system.h" #include "system/cpus.h" #include "system/hw_accel.h" #include "system/kvm.h" #include "system/runstate.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/i386/apic_internal.h" #include "hw/sysbus.h" #include "hw/boards.h" @@ -846,7 +847,7 @@ static const VMStateDescription vmstate_vapic = { } }; -static void vapic_class_init(ObjectClass *klass, void *data) +static void vapic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/vmmouse.c b/hw/i386/vmmouse.c index 3e07d12..3896159 100644 --- a/hw/i386/vmmouse.c +++ b/hw/i386/vmmouse.c @@ -321,7 +321,7 @@ static const Property vmmouse_properties[] = { DEFINE_PROP_LINK("i8042", VMMouseState, i8042, TYPE_I8042, ISAKBDState *), }; -static void vmmouse_class_initfn(ObjectClass *klass, void *data) +static void vmmouse_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/vmport.c b/hw/i386/vmport.c index 2f19b97..6d93457 100644 --- a/hw/i386/vmport.c +++ b/hw/i386/vmport.c @@ -286,7 +286,7 @@ static const Property vmport_properties[] = { DEFINE_PROP_UINT8("vmware-vmx-type", VMPortState, vmware_vmx_type, 2), }; -static void vmport_class_initfn(ObjectClass *klass, void *data) +static void vmport_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/i386/x86-common.c b/hw/i386/x86-common.c index 1b0671c..b1b5f11 100644 --- a/hw/i386/x86-common.c +++ b/hw/i386/x86-common.c @@ -44,6 +44,7 @@ #include "standard-headers/asm-x86/bootparam.h" #include CONFIG_DEVICES #include "kvm/kvm_i386.h" +#include "kvm/tdx.h" #ifdef CONFIG_XEN_EMU #include "hw/xen/xen.h" @@ -1035,11 +1036,14 @@ void x86_bios_rom_init(X86MachineState *x86ms, const char *default_firmware, if (machine_require_guest_memfd(MACHINE(x86ms))) { memory_region_init_ram_guest_memfd(&x86ms->bios, NULL, "pc.bios", bios_size, &error_fatal); + if (is_tdx_vm()) { + tdx_set_tdvf_region(&x86ms->bios); + } } else { memory_region_init_ram(&x86ms->bios, NULL, "pc.bios", bios_size, &error_fatal); } - if (sev_enabled()) { + if (sev_enabled() || is_tdx_vm()) { /* * The concept of a "reset" simply doesn't exist for * confidential computing guests, we have to destroy and diff --git a/hw/i386/x86-iommu.c b/hw/i386/x86-iommu.c index 5cdd165..d34a684 100644 --- a/hw/i386/x86-iommu.c +++ b/hw/i386/x86-iommu.c @@ -132,7 +132,7 @@ static const Property x86_iommu_properties[] = { DEFINE_PROP_BOOL("pt", X86IOMMUState, pt_supported, true), }; -static void x86_iommu_class_init(ObjectClass *klass, void *data) +static void x86_iommu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = x86_iommu_realize; diff --git a/hw/i386/x86.c b/hw/i386/x86.c index 69bfc00..f80533d 100644 --- a/hw/i386/x86.c +++ b/hw/i386/x86.c @@ -372,7 +372,7 @@ static void x86_machine_initfn(Object *obj) x86ms->above_4g_mem_start = 4 * GiB; } -static void x86_machine_class_init(ObjectClass *oc, void *data) +static void x86_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); X86MachineClass *x86mc = X86_MACHINE_CLASS(oc); @@ -382,7 +382,6 @@ static void x86_machine_class_init(ObjectClass *oc, void *data) mc->get_default_cpu_node_id = x86_get_default_cpu_node_id; mc->possible_cpu_arch_ids = x86_possible_cpu_arch_ids; mc->kvm_type = x86_kvm_type; - x86mc->save_tsc_khz = true; x86mc->fwcfg_dma_enabled = true; nc->nmi_monitor_handler = x86_nmi; @@ -450,7 +449,7 @@ static const TypeInfo x86_machine_info = { .instance_init = x86_machine_initfn, .class_size = sizeof(X86MachineClass), .class_init = x86_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { } }, diff --git a/hw/i386/xen/xen-pvh.c b/hw/i386/xen/xen-pvh.c index f6356f2..067f73e 100644 --- a/hw/i386/xen/xen-pvh.c +++ b/hw/i386/xen/xen-pvh.c @@ -76,7 +76,7 @@ static void xen_pvh_set_pci_intx_irq(void *opaque, int irq, int level) } } -static void xen_pvh_machine_class_init(ObjectClass *oc, void *data) +static void xen_pvh_machine_class_init(ObjectClass *oc, const void *data) { XenPVHMachineClass *xpc = XEN_PVH_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/i386/xen/xen_apic.c b/hw/i386/xen/xen_apic.c index a94e900..f30398f 100644 --- a/hw/i386/xen/xen_apic.c +++ b/hw/i386/xen/xen_apic.c @@ -76,7 +76,7 @@ static void xen_send_msi(MSIMessage *msi) xen_hvm_inject_msi(msi->address, msi->data); } -static void xen_apic_class_init(ObjectClass *klass, void *data) +static void xen_apic_class_init(ObjectClass *klass, const void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); diff --git a/hw/i386/xen/xen_platform.c b/hw/i386/xen/xen_platform.c index dd648a2..c8b852b 100644 --- a/hw/i386/xen/xen_platform.c +++ b/hw/i386/xen/xen_platform.c @@ -581,7 +581,7 @@ static void platform_reset(DeviceState *dev) platform_fixed_ioport_reset(s); } -static void xen_platform_class_init(ObjectClass *klass, void *data) +static void xen_platform_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -604,7 +604,7 @@ static const TypeInfo xen_platform_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIXenPlatformState), .class_init = xen_platform_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/i386/xen/xen_pvdevice.c b/hw/i386/xen/xen_pvdevice.c index 9453da9..87a974a 100644 --- a/hw/i386/xen/xen_pvdevice.c +++ b/hw/i386/xen/xen_pvdevice.c @@ -122,7 +122,7 @@ static const Property xen_pv_props[] = { DEFINE_PROP_UINT32("size", XenPVDevice, size, 0x400000), }; -static void xen_pv_class_init(ObjectClass *klass, void *data) +static void xen_pv_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -139,7 +139,7 @@ static const TypeInfo xen_pv_type_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(XenPVDevice), .class_init = xen_pv_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/ide/ahci-allwinner.c b/hw/ide/ahci-allwinner.c index 575be36..bc7a116 100644 --- a/hw/ide/ahci-allwinner.c +++ b/hw/ide/ahci-allwinner.c @@ -103,7 +103,7 @@ static const VMStateDescription vmstate_allwinner_ahci = { } }; -static void allwinner_ahci_class_init(ObjectClass *klass, void *data) +static void allwinner_ahci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ide/ahci-sysbus.c b/hw/ide/ahci-sysbus.c index 03a5bd4..210818d 100644 --- a/hw/ide/ahci-sysbus.c +++ b/hw/ide/ahci-sysbus.c @@ -22,7 +22,7 @@ */ #include "qemu/osdep.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" @@ -66,7 +66,7 @@ static const Property sysbus_ahci_properties[] = { DEFINE_PROP_UINT32("num-ports", SysbusAHCIState, ahci.ports, 1), }; -static void sysbus_ahci_class_init(ObjectClass *klass, void *data) +static void sysbus_ahci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ide/cf.c b/hw/ide/cf.c index cfb4394..f87cd41 100644 --- a/hw/ide/cf.c +++ b/hw/ide/cf.c @@ -31,7 +31,7 @@ static const Property ide_cf_properties[] = { IDEDrive, dev.chs_trans, BIOS_ATA_TRANSLATION_AUTO), }; -static void ide_cf_class_init(ObjectClass *klass, void *data) +static void ide_cf_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IDEDeviceClass *k = IDE_DEVICE_CLASS(klass); diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c index 8e568e4..2a59516 100644 --- a/hw/ide/cmd646.c +++ b/hw/ide/cmd646.c @@ -317,7 +317,7 @@ static const Property cmd646_ide_properties[] = { DEFINE_PROP_UINT32("secondary", PCIIDEState, secondary, 0), }; -static void cmd646_ide_class_init(ObjectClass *klass, void *data) +static void cmd646_ide_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/ide/ich.c b/hw/ide/ich.c index a831284..4cade0d 100644 --- a/hw/ide/ich.c +++ b/hw/ide/ich.c @@ -175,7 +175,7 @@ static void pci_ich9_uninit(PCIDevice *dev) ahci_uninit(&d->ahci); } -static void ich_ahci_class_init(ObjectClass *klass, void *data) +static void ich_ahci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -197,7 +197,7 @@ static const TypeInfo ich_ahci_info = { .instance_size = sizeof(AHCIPCIState), .instance_init = pci_ich9_ahci_init, .class_init = ich_ahci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/ide/ide-bus.c b/hw/ide/ide-bus.c index 437502b..b24e4d1 100644 --- a/hw/ide/ide-bus.c +++ b/hw/ide/ide-bus.c @@ -29,7 +29,7 @@ static char *idebus_get_fw_dev_path(DeviceState *dev); static void idebus_unrealize(BusState *qdev); -static void ide_bus_class_init(ObjectClass *klass, void *data) +static void ide_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); diff --git a/hw/ide/ide-dev.c b/hw/ide/ide-dev.c index 26f0517..5d47858 100644 --- a/hw/ide/ide-dev.c +++ b/hw/ide/ide-dev.c @@ -198,7 +198,7 @@ static const Property ide_hd_properties[] = { DEFINE_PROP_UINT16("rotation_rate", IDEDrive, dev.rotation_rate, 0), }; -static void ide_hd_class_init(ObjectClass *klass, void *data) +static void ide_hd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IDEDeviceClass *k = IDE_DEVICE_CLASS(klass); @@ -220,7 +220,7 @@ static const Property ide_cd_properties[] = { DEFINE_IDE_DEV_PROPERTIES(), }; -static void ide_cd_class_init(ObjectClass *klass, void *data) +static void ide_cd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IDEDeviceClass *k = IDE_DEVICE_CLASS(klass); @@ -238,7 +238,7 @@ static const TypeInfo ide_cd_info = { .class_init = ide_cd_class_init, }; -static void ide_device_class_init(ObjectClass *klass, void *data) +static void ide_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->realize = ide_qdev_realize; diff --git a/hw/ide/isa.c b/hw/ide/isa.c index 4863ad8..5f41841 100644 --- a/hw/ide/isa.c +++ b/hw/ide/isa.c @@ -107,7 +107,7 @@ static const Property isa_ide_properties[] = { DEFINE_PROP_UINT32("irq", ISAIDEState, irqnum, 14), }; -static void isa_ide_class_initfn(ObjectClass *klass, void *data) +static void isa_ide_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ide/macio.c b/hw/ide/macio.c index c8e8e44..c23bf32 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -463,7 +463,7 @@ static const Property macio_ide_properties[] = { DEFINE_PROP_UINT32("addr", MACIOIDEState, addr, -1), }; -static void macio_ide_class_init(ObjectClass *oc, void *data) +static void macio_ide_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c index 13f1617..699874d 100644 --- a/hw/ide/mmio.c +++ b/hw/ide/mmio.c @@ -145,7 +145,7 @@ static const Property mmio_ide_properties[] = { DEFINE_PROP_UINT32("shift", MMIOIDEState, shift, 0), }; -static void mmio_ide_class_init(ObjectClass *oc, void *data) +static void mmio_ide_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ide/pci.c b/hw/ide/pci.c index 0ed72e4..1e50bb9 100644 --- a/hw/ide/pci.c +++ b/hw/ide/pci.c @@ -625,7 +625,7 @@ static const TypeInfo pci_ide_type_info = { .instance_size = sizeof(PCIIDEState), .instance_init = pci_ide_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/ide/piix.c b/hw/ide/piix.c index 818ff60..a0f2709 100644 --- a/hw/ide/piix.c +++ b/hw/ide/piix.c @@ -178,7 +178,7 @@ static void pci_piix_ide_exitfn(PCIDevice *dev) } /* NOTE: for the PIIX3, the IRQs and IOports are hardcoded */ -static void piix3_ide_class_init(ObjectClass *klass, void *data) +static void piix3_ide_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -201,7 +201,7 @@ static const TypeInfo piix3_ide_info = { }; /* NOTE: for the PIIX4, the IRQs and IOports are hardcoded */ -static void piix4_ide_class_init(ObjectClass *klass, void *data) +static void piix4_ide_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/ide/sii3112.c b/hw/ide/sii3112.c index ce8a1e4..9b28c69 100644 --- a/hw/ide/sii3112.c +++ b/hw/ide/sii3112.c @@ -290,7 +290,7 @@ static void sii3112_pci_realize(PCIDevice *dev, Error **errp) } } -static void sii3112_pci_class_init(ObjectClass *klass, void *data) +static void sii3112_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pd = PCI_DEVICE_CLASS(klass); diff --git a/hw/ide/via.c b/hw/ide/via.c index 89fd28f..dedc267 100644 --- a/hw/ide/via.c +++ b/hw/ide/via.c @@ -245,7 +245,7 @@ static void via_ide_exitfn(PCIDevice *dev) } } -static void via_ide_class_init(ObjectClass *klass, void *data) +static void via_ide_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/input/adb-kbd.c b/hw/input/adb-kbd.c index 3649d03..507557d 100644 --- a/hw/input/adb-kbd.c +++ b/hw/input/adb-kbd.c @@ -375,7 +375,7 @@ static void adb_kbd_initfn(Object *obj) d->devaddr = ADB_DEVID_KEYBOARD; } -static void adb_kbd_class_init(ObjectClass *oc, void *data) +static void adb_kbd_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc); diff --git a/hw/input/adb-mouse.c b/hw/input/adb-mouse.c index 77b280d..373ef3f 100644 --- a/hw/input/adb-mouse.c +++ b/hw/input/adb-mouse.c @@ -287,7 +287,7 @@ static void adb_mouse_initfn(Object *obj) d->devaddr = ADB_DEVID_MOUSE; } -static void adb_mouse_class_init(ObjectClass *oc, void *data) +static void adb_mouse_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ADBDeviceClass *adc = ADB_DEVICE_CLASS(oc); diff --git a/hw/input/adb.c b/hw/input/adb.c index aff7130..bcb11ed 100644 --- a/hw/input/adb.c +++ b/hw/input/adb.c @@ -259,7 +259,7 @@ static void adb_bus_unrealize(BusState *qbus) vmstate_unregister(NULL, &vmstate_adb_bus, adb_bus); } -static void adb_bus_class_init(ObjectClass *klass, void *data) +static void adb_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -299,7 +299,7 @@ static void adb_device_realizefn(DeviceState *dev, Error **errp) bus->devices[bus->nb_devices++] = d; } -static void adb_device_class_init(ObjectClass *oc, void *data) +static void adb_device_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/input/lasips2.c b/hw/input/lasips2.c index d9f8c36..de62572 100644 --- a/hw/input/lasips2.c +++ b/hw/input/lasips2.c @@ -29,7 +29,7 @@ #include "hw/input/lasips2.h" #include "exec/hwaddr.h" #include "trace.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "migration/vmstate.h" #include "hw/irq.h" #include "qapi/error.h" @@ -306,7 +306,7 @@ static void lasips2_init(Object *obj) "lasips2-port-input-irq", 2); } -static void lasips2_class_init(ObjectClass *klass, void *data) +static void lasips2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -347,7 +347,7 @@ static void lasips2_port_init(Object *obj) "ps2-input-irq", 1); } -static void lasips2_port_class_init(ObjectClass *klass, void *data) +static void lasips2_port_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -397,7 +397,7 @@ static void lasips2_kbd_port_init(Object *obj) lp->lasips2 = container_of(s, LASIPS2State, kbd_port); } -static void lasips2_kbd_port_class_init(ObjectClass *klass, void *data) +static void lasips2_kbd_port_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); @@ -447,7 +447,7 @@ static void lasips2_mouse_port_init(Object *obj) lp->lasips2 = container_of(s, LASIPS2State, mouse_port); } -static void lasips2_mouse_port_class_init(ObjectClass *klass, void *data) +static void lasips2_mouse_port_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LASIPS2PortDeviceClass *lpdc = LASIPS2_PORT_CLASS(klass); diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c index fa0c549..71f5f97 100644 --- a/hw/input/pckbd.c +++ b/hw/input/pckbd.c @@ -750,7 +750,7 @@ static const VMStateDescription vmstate_kbd_mmio = { } }; -static void i8042_mmio_class_init(ObjectClass *klass, void *data) +static void i8042_mmio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -939,7 +939,7 @@ static const Property i8042_properties[] = { DEFINE_PROP_UINT8("mouse-irq", ISAKBDState, mouse_irq, 12), }; -static void i8042_class_initfn(ObjectClass *klass, void *data) +static void i8042_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); @@ -958,7 +958,7 @@ static const TypeInfo i8042_info = { .instance_size = sizeof(ISAKBDState), .instance_init = i8042_initfn, .class_init = i8042_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/input/pl050.c b/hw/input/pl050.c index 6519e26..c5f4a3f 100644 --- a/hw/input/pl050.c +++ b/hw/input/pl050.c @@ -203,7 +203,7 @@ static void pl050_mouse_init(Object *obj) object_initialize_child(obj, "mouse", &s->mouse, TYPE_PS2_MOUSE_DEVICE); } -static void pl050_kbd_class_init(ObjectClass *oc, void *data) +static void pl050_kbd_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PL050DeviceClass *pdc = PL050_CLASS(oc); @@ -220,7 +220,7 @@ static const TypeInfo pl050_kbd_info = { .class_init = pl050_kbd_class_init, }; -static void pl050_mouse_class_init(ObjectClass *oc, void *data) +static void pl050_mouse_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PL050DeviceClass *pdc = PL050_CLASS(oc); @@ -249,7 +249,7 @@ static void pl050_init(Object *obj) qdev_init_gpio_in_named(DEVICE(obj), pl050_set_irq, "ps2-input-irq", 1); } -static void pl050_class_init(ObjectClass *oc, void *data) +static void pl050_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/input/ps2.c b/hw/input/ps2.c index 6a41b02..7f7b1fc 100644 --- a/hw/input/ps2.c +++ b/hw/input/ps2.c @@ -1254,7 +1254,7 @@ static void ps2_mouse_realize(DeviceState *dev, Error **errp) qemu_input_handler_register(dev, &ps2_mouse_handler); } -static void ps2_kbd_class_init(ObjectClass *klass, void *data) +static void ps2_kbd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1273,7 +1273,7 @@ static const TypeInfo ps2_kbd_info = { .class_init = ps2_kbd_class_init }; -static void ps2_mouse_class_init(ObjectClass *klass, void *data) +static void ps2_mouse_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1299,7 +1299,7 @@ static void ps2_init(Object *obj) qdev_init_gpio_out(DEVICE(obj), &s->irq, 1); } -static void ps2_class_init(ObjectClass *klass, void *data) +static void ps2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/input/stellaris_gamepad.c b/hw/input/stellaris_gamepad.c index 98382a0..fec1161 100644 --- a/hw/input/stellaris_gamepad.c +++ b/hw/input/stellaris_gamepad.c @@ -82,7 +82,7 @@ static const Property stellaris_gamepad_properties[] = { keycodes, qdev_prop_uint32, uint32_t), }; -static void stellaris_gamepad_class_init(ObjectClass *klass, void *data) +static void stellaris_gamepad_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/input/virtio-input-hid.c b/hw/input/virtio-input-hid.c index 812faae..d986c3c 100644 --- a/hw/input/virtio-input-hid.c +++ b/hw/input/virtio-input-hid.c @@ -242,7 +242,7 @@ static const Property virtio_input_hid_properties[] = { DEFINE_PROP_UINT32("head", VirtIOInputHID, head, 0), }; -static void virtio_input_hid_class_init(ObjectClass *klass, void *data) +static void virtio_input_hid_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass); @@ -383,7 +383,7 @@ static const Property virtio_mouse_properties[] = { DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true), }; -static void virtio_mouse_class_init(ObjectClass *klass, void *data) +static void virtio_mouse_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -507,7 +507,7 @@ static const Property virtio_tablet_properties[] = { DEFINE_PROP_BOOL("wheel-axis", VirtIOInputHID, wheel_axis, true), }; -static void virtio_tablet_class_init(ObjectClass *klass, void *data) +static void virtio_tablet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/input/virtio-input-host.c b/hw/input/virtio-input-host.c index b21a790..bbfee9d 100644 --- a/hw/input/virtio-input-host.c +++ b/hw/input/virtio-input-host.c @@ -224,7 +224,7 @@ static const Property virtio_input_host_properties[] = { DEFINE_PROP_STRING("evdev", VirtIOInputHost, evdev), }; -static void virtio_input_host_class_init(ObjectClass *klass, void *data) +static void virtio_input_host_class_init(ObjectClass *klass, const void *data) { VirtIOInputClass *vic = VIRTIO_INPUT_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c index 1394d99..a3f554f 100644 --- a/hw/input/virtio-input.c +++ b/hw/input/virtio-input.c @@ -189,7 +189,7 @@ static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f, return f; } -static void virtio_input_set_status(VirtIODevice *vdev, uint8_t val) +static int virtio_input_set_status(VirtIODevice *vdev, uint8_t val) { VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev); VirtIOInput *vinput = VIRTIO_INPUT(vdev); @@ -202,6 +202,7 @@ static void virtio_input_set_status(VirtIODevice *vdev, uint8_t val) } } } + return 0; } static void virtio_input_reset(VirtIODevice *vdev) @@ -304,7 +305,7 @@ static const Property virtio_input_properties[] = { DEFINE_PROP_STRING("serial", VirtIOInput, serial), }; -static void virtio_input_class_init(ObjectClass *klass, void *data) +static void virtio_input_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/intc/allwinner-a10-pic.c b/hw/intc/allwinner-a10-pic.c index 93a604f..0409734 100644 --- a/hw/intc/allwinner-a10-pic.c +++ b/hw/intc/allwinner-a10-pic.c @@ -187,7 +187,7 @@ static void aw_a10_pic_reset(DeviceState *d) } } -static void aw_a10_pic_class_init(ObjectClass *klass, void *data) +static void aw_a10_pic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/apic.c b/hw/intc/apic.c index d18c1db..bcb1035 100644 --- a/hw/intc/apic.c +++ b/hw/intc/apic.c @@ -1176,7 +1176,7 @@ static void apic_unrealize(DeviceState *dev) local_apics[s->initial_apic_id] = NULL; } -static void apic_class_init(ObjectClass *klass, void *data) +static void apic_class_init(ObjectClass *klass, const void *data) { APICCommonClass *k = APIC_COMMON_CLASS(klass); diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c index 2a3e878..37a7a70 100644 --- a/hw/intc/apic_common.c +++ b/hw/intc/apic_common.c @@ -466,7 +466,7 @@ static void apic_common_initfn(Object *obj) apic_common_set_id, NULL, NULL); } -static void apic_common_class_init(ObjectClass *klass, void *data) +static void apic_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 3581ff8..899f133 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -59,7 +59,7 @@ static const uint8_t gic_id_gicv2[] = { static inline int gic_get_current_cpu(GICState *s) { if (!qtest_enabled() && s->num_cpu > 1) { - return current_cpu->cpu_index; + return current_cpu->cpu_index - s->first_cpu_index; } return 0; } @@ -2162,7 +2162,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) } -static void arm_gic_class_init(ObjectClass *klass, void *data) +static void arm_gic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ARMGICClass *agc = ARM_GIC_CLASS(klass); diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index 5ac56e3..ed5be05 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -350,6 +350,7 @@ static void arm_gic_common_linux_init(ARMLinuxBootIf *obj, static const Property arm_gic_common_properties[] = { DEFINE_PROP_UINT32("num-cpu", GICState, num_cpu, 1), + DEFINE_PROP_UINT32("first-cpu-index", GICState, first_cpu_index, 0), DEFINE_PROP_UINT32("num-irq", GICState, num_irq, 32), /* Revision can be 1 or 2 for GIC architecture specification * versions 1 or 2, or 0 to indicate the legacy 11MPCore GIC. @@ -362,7 +363,7 @@ static const Property arm_gic_common_properties[] = { DEFINE_PROP_UINT32("num-priority-bits", GICState, n_prio_bits, 8), }; -static void arm_gic_common_class_init(ObjectClass *klass, void *data) +static void arm_gic_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -382,7 +383,7 @@ static const TypeInfo arm_gic_common_type = { .class_size = sizeof(ARMGICCommonClass), .class_init = arm_gic_common_class_init, .abstract = true, - .interfaces = (InterfaceInfo []) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ARM_LINUX_BOOT_IF }, { }, }, diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index 40adb02..1e9232f 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -584,7 +584,7 @@ static void kvm_arm_gic_realize(DeviceState *dev, Error **errp) } } -static void kvm_arm_gic_class_init(ObjectClass *klass, void *data) +static void kvm_arm_gic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/intc/arm_gicv2m.c b/hw/intc/arm_gicv2m.c index 3a8c626..cef0688 100644 --- a/hw/intc/arm_gicv2m.c +++ b/hw/intc/arm_gicv2m.c @@ -175,7 +175,7 @@ static const Property gicv2m_properties[] = { DEFINE_PROP_UINT32("num-spi", ARMGICv2mState, num_spi, 64), }; -static void gicv2m_class_init(ObjectClass *klass, void *data) +static void gicv2m_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/arm_gicv3.c b/hw/intc/arm_gicv3.c index 58e18ff..6059ce9 100644 --- a/hw/intc/arm_gicv3.c +++ b/hw/intc/arm_gicv3.c @@ -452,7 +452,7 @@ static void arm_gic_realize(DeviceState *dev, Error **errp) gicv3_init_cpuif(s); } -static void arm_gicv3_class_init(ObjectClass *klass, void *data) +static void arm_gicv3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ARMGICv3CommonClass *agcc = ARM_GICV3_COMMON_CLASS(klass); diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c index 76b2283..1cee681 100644 --- a/hw/intc/arm_gicv3_common.c +++ b/hw/intc/arm_gicv3_common.c @@ -623,7 +623,7 @@ static const Property arm_gicv3_common_properties[] = { MemoryRegion *), }; -static void arm_gicv3_common_class_init(ObjectClass *klass, void *data) +static void arm_gicv3_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -644,7 +644,7 @@ static const TypeInfo arm_gicv3_common_type = { .class_init = arm_gicv3_common_class_init, .instance_finalize = arm_gicv3_finalize, .abstract = true, - .interfaces = (InterfaceInfo []) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ARM_LINUX_BOOT_IF }, { }, }, diff --git a/hw/intc/arm_gicv3_its.c b/hw/intc/arm_gicv3_its.c index 936368c..577b445 100644 --- a/hw/intc/arm_gicv3_its.c +++ b/hw/intc/arm_gicv3_its.c @@ -2007,7 +2007,7 @@ static const Property gicv3_its_props[] = { GICv3State *), }; -static void gicv3_its_class_init(ObjectClass *klass, void *data) +static void gicv3_its_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/intc/arm_gicv3_its_common.c b/hw/intc/arm_gicv3_its_common.c index 70dbee8..e946e3f 100644 --- a/hw/intc/arm_gicv3_its_common.c +++ b/hw/intc/arm_gicv3_its_common.c @@ -135,7 +135,7 @@ static void gicv3_its_common_reset_hold(Object *obj, ResetType type) memset(&s->baser, 0, sizeof(s->baser)); } -static void gicv3_its_common_class_init(ObjectClass *klass, void *data) +static void gicv3_its_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/intc/arm_gicv3_its_kvm.c b/hw/intc/arm_gicv3_its_kvm.c index e198974..9812d50 100644 --- a/hw/intc/arm_gicv3_its_kvm.c +++ b/hw/intc/arm_gicv3_its_kvm.c @@ -239,7 +239,7 @@ static const Property kvm_arm_its_props[] = { GICv3State *), }; -static void kvm_arm_its_class_init(ObjectClass *klass, void *data) +static void kvm_arm_its_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c index 8e17cab..3be3bf6 100644 --- a/hw/intc/arm_gicv3_kvm.c +++ b/hw/intc/arm_gicv3_kvm.c @@ -893,7 +893,7 @@ static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) } } -static void kvm_arm_gicv3_class_init(ObjectClass *klass, void *data) +static void kvm_arm_gicv3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 7212c87..6d85720 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -988,6 +988,7 @@ static void nvic_nmi_trigger(void *opaque, int n, int level) static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; + ARMISARegisters *isar = &cpu->isar; uint32_t val; switch (offset) { @@ -1263,17 +1264,17 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_pfr0; + return GET_IDREG(isar, ID_PFR0); case 0xd44: /* PFR1. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_pfr1; + return GET_IDREG(isar, ID_PFR1); case 0xd48: /* DFR0. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_dfr0; + return GET_IDREG(isar, ID_DFR0); case 0xd4c: /* AFR0. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; @@ -1283,52 +1284,52 @@ static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr0; + return GET_IDREG(isar, ID_MMFR0); case 0xd54: /* MMFR1. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr1; + return GET_IDREG(isar, ID_MMFR1); case 0xd58: /* MMFR2. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr2; + return GET_IDREG(isar, ID_MMFR2); case 0xd5c: /* MMFR3. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_mmfr3; + return GET_IDREG(isar, ID_MMFR3); case 0xd60: /* ISAR0. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar0; + return GET_IDREG(&cpu->isar, ID_ISAR0); case 0xd64: /* ISAR1. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar1; + return GET_IDREG(&cpu->isar, ID_ISAR1); case 0xd68: /* ISAR2. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar2; + return GET_IDREG(&cpu->isar, ID_ISAR2); case 0xd6c: /* ISAR3. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar3; + return GET_IDREG(&cpu->isar, ID_ISAR3); case 0xd70: /* ISAR4. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar4; + return GET_IDREG(&cpu->isar, ID_ISAR4); case 0xd74: /* ISAR5. */ if (!arm_feature(&cpu->env, ARM_FEATURE_M_MAIN)) { goto bad_offset; } - return cpu->isar.id_isar5; + return GET_IDREG(&cpu->isar, ID_ISAR5); case 0xd78: /* CLIDR */ return cpu->clidr; case 0xd7c: /* CTR */ @@ -2730,7 +2731,7 @@ static void armv7m_nvic_instance_init(Object *obj) qdev_init_gpio_in_named(dev, nvic_nmi_trigger, "NMI", 1); } -static void armv7m_nvic_class_init(ObjectClass *klass, void *data) +static void armv7m_nvic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/aspeed_intc.c b/hw/intc/aspeed_intc.c index bae7dc9..5cd786d 100644 --- a/hw/intc/aspeed_intc.c +++ b/hw/intc/aspeed_intc.c @@ -62,6 +62,95 @@ REG32(GICINT196_STATUS, 0x44) REG32(GICINT197_EN, 0x50) REG32(GICINT197_STATUS, 0x54) +/* + * SSP INTC Registers + */ +REG32(SSPINT128_EN, 0x2000) +REG32(SSPINT128_STATUS, 0x2004) +REG32(SSPINT129_EN, 0x2100) +REG32(SSPINT129_STATUS, 0x2104) +REG32(SSPINT130_EN, 0x2200) +REG32(SSPINT130_STATUS, 0x2204) +REG32(SSPINT131_EN, 0x2300) +REG32(SSPINT131_STATUS, 0x2304) +REG32(SSPINT132_EN, 0x2400) +REG32(SSPINT132_STATUS, 0x2404) +REG32(SSPINT133_EN, 0x2500) +REG32(SSPINT133_STATUS, 0x2504) +REG32(SSPINT134_EN, 0x2600) +REG32(SSPINT134_STATUS, 0x2604) +REG32(SSPINT135_EN, 0x2700) +REG32(SSPINT135_STATUS, 0x2704) +REG32(SSPINT136_EN, 0x2800) +REG32(SSPINT136_STATUS, 0x2804) +REG32(SSPINT137_EN, 0x2900) +REG32(SSPINT137_STATUS, 0x2904) +REG32(SSPINT138_EN, 0x2A00) +REG32(SSPINT138_STATUS, 0x2A04) +REG32(SSPINT160_169_EN, 0x2B00) +REG32(SSPINT160_169_STATUS, 0x2B04) + +/* + * SSP INTCIO Registers + */ +REG32(SSPINT160_EN, 0x180) +REG32(SSPINT160_STATUS, 0x184) +REG32(SSPINT161_EN, 0x190) +REG32(SSPINT161_STATUS, 0x194) +REG32(SSPINT162_EN, 0x1A0) +REG32(SSPINT162_STATUS, 0x1A4) +REG32(SSPINT163_EN, 0x1B0) +REG32(SSPINT163_STATUS, 0x1B4) +REG32(SSPINT164_EN, 0x1C0) +REG32(SSPINT164_STATUS, 0x1C4) +REG32(SSPINT165_EN, 0x1D0) +REG32(SSPINT165_STATUS, 0x1D4) + +/* + * TSP INTC Registers + */ +REG32(TSPINT128_EN, 0x3000) +REG32(TSPINT128_STATUS, 0x3004) +REG32(TSPINT129_EN, 0x3100) +REG32(TSPINT129_STATUS, 0x3104) +REG32(TSPINT130_EN, 0x3200) +REG32(TSPINT130_STATUS, 0x3204) +REG32(TSPINT131_EN, 0x3300) +REG32(TSPINT131_STATUS, 0x3304) +REG32(TSPINT132_EN, 0x3400) +REG32(TSPINT132_STATUS, 0x3404) +REG32(TSPINT133_EN, 0x3500) +REG32(TSPINT133_STATUS, 0x3504) +REG32(TSPINT134_EN, 0x3600) +REG32(TSPINT134_STATUS, 0x3604) +REG32(TSPINT135_EN, 0x3700) +REG32(TSPINT135_STATUS, 0x3704) +REG32(TSPINT136_EN, 0x3800) +REG32(TSPINT136_STATUS, 0x3804) +REG32(TSPINT137_EN, 0x3900) +REG32(TSPINT137_STATUS, 0x3904) +REG32(TSPINT138_EN, 0x3A00) +REG32(TSPINT138_STATUS, 0x3A04) +REG32(TSPINT160_169_EN, 0x3B00) +REG32(TSPINT160_169_STATUS, 0x3B04) + +/* + * TSP INTCIO Registers + */ + +REG32(TSPINT160_EN, 0x200) +REG32(TSPINT160_STATUS, 0x204) +REG32(TSPINT161_EN, 0x210) +REG32(TSPINT161_STATUS, 0x214) +REG32(TSPINT162_EN, 0x220) +REG32(TSPINT162_STATUS, 0x224) +REG32(TSPINT163_EN, 0x230) +REG32(TSPINT163_STATUS, 0x234) +REG32(TSPINT164_EN, 0x240) +REG32(TSPINT164_STATUS, 0x244) +REG32(TSPINT165_EN, 0x250) +REG32(TSPINT165_STATUS, 0x254) + static const AspeedINTCIRQ *aspeed_intc_get_irq(AspeedINTCClass *aic, uint32_t reg) { @@ -450,6 +539,90 @@ static void aspeed_intc_write(void *opaque, hwaddr offset, uint64_t data, } } +static void aspeed_ssp_intc_write(void *opaque, hwaddr offset, uint64_t data, + unsigned size) +{ + AspeedINTCState *s = ASPEED_INTC(opaque); + const char *name = object_get_typename(OBJECT(s)); + uint32_t reg = offset >> 2; + + trace_aspeed_intc_write(name, offset, size, data); + + switch (reg) { + case R_SSPINT128_EN: + case R_SSPINT129_EN: + case R_SSPINT130_EN: + case R_SSPINT131_EN: + case R_SSPINT132_EN: + case R_SSPINT133_EN: + case R_SSPINT134_EN: + case R_SSPINT135_EN: + case R_SSPINT136_EN: + case R_SSPINT160_169_EN: + aspeed_intc_enable_handler(s, offset, data); + break; + case R_SSPINT128_STATUS: + case R_SSPINT129_STATUS: + case R_SSPINT130_STATUS: + case R_SSPINT131_STATUS: + case R_SSPINT132_STATUS: + case R_SSPINT133_STATUS: + case R_SSPINT134_STATUS: + case R_SSPINT135_STATUS: + case R_SSPINT136_STATUS: + aspeed_intc_status_handler(s, offset, data); + break; + case R_SSPINT160_169_STATUS: + aspeed_intc_status_handler_multi_outpins(s, offset, data); + break; + default: + s->regs[reg] = data; + break; + } +} + +static void aspeed_tsp_intc_write(void *opaque, hwaddr offset, uint64_t data, + unsigned size) +{ + AspeedINTCState *s = ASPEED_INTC(opaque); + const char *name = object_get_typename(OBJECT(s)); + uint32_t reg = offset >> 2; + + trace_aspeed_intc_write(name, offset, size, data); + + switch (reg) { + case R_TSPINT128_EN: + case R_TSPINT129_EN: + case R_TSPINT130_EN: + case R_TSPINT131_EN: + case R_TSPINT132_EN: + case R_TSPINT133_EN: + case R_TSPINT134_EN: + case R_TSPINT135_EN: + case R_TSPINT136_EN: + case R_TSPINT160_169_EN: + aspeed_intc_enable_handler(s, offset, data); + break; + case R_TSPINT128_STATUS: + case R_TSPINT129_STATUS: + case R_TSPINT130_STATUS: + case R_TSPINT131_STATUS: + case R_TSPINT132_STATUS: + case R_TSPINT133_STATUS: + case R_TSPINT134_STATUS: + case R_TSPINT135_STATUS: + case R_TSPINT136_STATUS: + aspeed_intc_status_handler(s, offset, data); + break; + case R_TSPINT160_169_STATUS: + aspeed_intc_status_handler_multi_outpins(s, offset, data); + break; + default: + s->regs[reg] = data; + break; + } +} + static uint64_t aspeed_intcio_read(void *opaque, hwaddr offset, unsigned int size) { @@ -496,11 +669,75 @@ static void aspeed_intcio_write(void *opaque, hwaddr offset, uint64_t data, } } +static void aspeed_ssp_intcio_write(void *opaque, hwaddr offset, uint64_t data, + unsigned size) +{ + AspeedINTCState *s = ASPEED_INTC(opaque); + const char *name = object_get_typename(OBJECT(s)); + uint32_t reg = offset >> 2; + + trace_aspeed_intc_write(name, offset, size, data); + + switch (reg) { + case R_SSPINT160_EN: + case R_SSPINT161_EN: + case R_SSPINT162_EN: + case R_SSPINT163_EN: + case R_SSPINT164_EN: + case R_SSPINT165_EN: + aspeed_intc_enable_handler(s, offset, data); + break; + case R_SSPINT160_STATUS: + case R_SSPINT161_STATUS: + case R_SSPINT162_STATUS: + case R_SSPINT163_STATUS: + case R_SSPINT164_STATUS: + case R_SSPINT165_STATUS: + aspeed_intc_status_handler(s, offset, data); + break; + default: + s->regs[reg] = data; + break; + } +} + +static void aspeed_tsp_intcio_write(void *opaque, hwaddr offset, uint64_t data, + unsigned size) +{ + AspeedINTCState *s = ASPEED_INTC(opaque); + const char *name = object_get_typename(OBJECT(s)); + uint32_t reg = offset >> 2; + + trace_aspeed_intc_write(name, offset, size, data); + + switch (reg) { + case R_TSPINT160_EN: + case R_TSPINT161_EN: + case R_TSPINT162_EN: + case R_TSPINT163_EN: + case R_TSPINT164_EN: + case R_TSPINT165_EN: + aspeed_intc_enable_handler(s, offset, data); + break; + case R_TSPINT160_STATUS: + case R_TSPINT161_STATUS: + case R_TSPINT162_STATUS: + case R_TSPINT163_STATUS: + case R_TSPINT164_STATUS: + case R_TSPINT165_STATUS: + aspeed_intc_status_handler(s, offset, data); + break; + default: + s->regs[reg] = data; + break; + } +} static const MemoryRegionOps aspeed_intc_ops = { .read = aspeed_intc_read, .write = aspeed_intc_write, .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, .valid = { .min_access_size = 4, .max_access_size = 4, @@ -511,6 +748,51 @@ static const MemoryRegionOps aspeed_intcio_ops = { .read = aspeed_intcio_read, .write = aspeed_intcio_write, .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + } +}; + +static const MemoryRegionOps aspeed_ssp_intc_ops = { + .read = aspeed_intc_read, + .write = aspeed_ssp_intc_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + } +}; + +static const MemoryRegionOps aspeed_ssp_intcio_ops = { + .read = aspeed_intcio_read, + .write = aspeed_ssp_intcio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + } +}; + +static const MemoryRegionOps aspeed_tsp_intc_ops = { + .read = aspeed_intc_read, + .write = aspeed_tsp_intc_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + } +}; + +static const MemoryRegionOps aspeed_tsp_intcio_ops = { + .read = aspeed_intcio_read, + .write = aspeed_tsp_intcio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, .valid = { .min_access_size = 4, .max_access_size = 4, @@ -583,7 +865,7 @@ static void aspeed_intc_unrealize(DeviceState *dev) s->regs = NULL; } -static void aspeed_intc_class_init(ObjectClass *klass, void *data) +static void aspeed_intc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); @@ -620,7 +902,7 @@ static AspeedINTCIRQ aspeed_2700_intc_irqs[ASPEED_INTC_MAX_INPINS] = { {9, 18, 1, R_GICINT136_EN, R_GICINT136_STATUS}, }; -static void aspeed_2700_intc_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_intc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); @@ -651,7 +933,7 @@ static AspeedINTCIRQ aspeed_2700_intcio_irqs[ASPEED_INTC_MAX_INPINS] = { {5, 5, 1, R_GICINT197_EN, R_GICINT197_STATUS}, }; -static void aspeed_2700_intcio_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_intcio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); @@ -674,11 +956,153 @@ static const TypeInfo aspeed_2700_intcio_info = { .class_init = aspeed_2700_intcio_class_init, }; +static AspeedINTCIRQ aspeed_2700ssp_intc_irqs[ASPEED_INTC_MAX_INPINS] = { + {0, 0, 10, R_SSPINT160_169_EN, R_SSPINT160_169_STATUS}, + {1, 10, 1, R_SSPINT128_EN, R_SSPINT128_STATUS}, + {2, 11, 1, R_SSPINT129_EN, R_SSPINT129_STATUS}, + {3, 12, 1, R_SSPINT130_EN, R_SSPINT130_STATUS}, + {4, 13, 1, R_SSPINT131_EN, R_SSPINT131_STATUS}, + {5, 14, 1, R_SSPINT132_EN, R_SSPINT132_STATUS}, + {6, 15, 1, R_SSPINT133_EN, R_SSPINT133_STATUS}, + {7, 16, 1, R_SSPINT134_EN, R_SSPINT134_STATUS}, + {8, 17, 1, R_SSPINT135_EN, R_SSPINT135_STATUS}, + {9, 18, 1, R_SSPINT136_EN, R_SSPINT136_STATUS}, +}; + +static void aspeed_2700ssp_intc_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); + + dc->desc = "ASPEED 2700 SSP INTC Controller"; + aic->num_lines = 32; + aic->num_inpins = 10; + aic->num_outpins = 19; + aic->mem_size = 0x4000; + aic->nr_regs = 0x2B08 >> 2; + aic->reg_offset = 0x0; + aic->reg_ops = &aspeed_ssp_intc_ops; + aic->irq_table = aspeed_2700ssp_intc_irqs; + aic->irq_table_count = ARRAY_SIZE(aspeed_2700ssp_intc_irqs); +} + +static const TypeInfo aspeed_2700ssp_intc_info = { + .name = TYPE_ASPEED_2700SSP_INTC, + .parent = TYPE_ASPEED_INTC, + .class_init = aspeed_2700ssp_intc_class_init, +}; + +static AspeedINTCIRQ aspeed_2700ssp_intcio_irqs[ASPEED_INTC_MAX_INPINS] = { + {0, 0, 1, R_SSPINT160_EN, R_SSPINT160_STATUS}, + {1, 1, 1, R_SSPINT161_EN, R_SSPINT161_STATUS}, + {2, 2, 1, R_SSPINT162_EN, R_SSPINT162_STATUS}, + {3, 3, 1, R_SSPINT163_EN, R_SSPINT163_STATUS}, + {4, 4, 1, R_SSPINT164_EN, R_SSPINT164_STATUS}, + {5, 5, 1, R_SSPINT165_EN, R_SSPINT165_STATUS}, +}; + +static void aspeed_2700ssp_intcio_class_init(ObjectClass *klass, + const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); + + dc->desc = "ASPEED 2700 SSP INTC IO Controller"; + aic->num_lines = 32; + aic->num_inpins = 6; + aic->num_outpins = 6; + aic->mem_size = 0x400; + aic->nr_regs = 0x1d8 >> 2; + aic->reg_offset = 0; + aic->reg_ops = &aspeed_ssp_intcio_ops; + aic->irq_table = aspeed_2700ssp_intcio_irqs; + aic->irq_table_count = ARRAY_SIZE(aspeed_2700ssp_intcio_irqs); +} + +static const TypeInfo aspeed_2700ssp_intcio_info = { + .name = TYPE_ASPEED_2700SSP_INTCIO, + .parent = TYPE_ASPEED_INTC, + .class_init = aspeed_2700ssp_intcio_class_init, +}; + +static AspeedINTCIRQ aspeed_2700tsp_intc_irqs[ASPEED_INTC_MAX_INPINS] = { + {0, 0, 10, R_TSPINT160_169_EN, R_TSPINT160_169_STATUS}, + {1, 10, 1, R_TSPINT128_EN, R_TSPINT128_STATUS}, + {2, 11, 1, R_TSPINT129_EN, R_TSPINT129_STATUS}, + {3, 12, 1, R_TSPINT130_EN, R_TSPINT130_STATUS}, + {4, 13, 1, R_TSPINT131_EN, R_TSPINT131_STATUS}, + {5, 14, 1, R_TSPINT132_EN, R_TSPINT132_STATUS}, + {6, 15, 1, R_TSPINT133_EN, R_TSPINT133_STATUS}, + {7, 16, 1, R_TSPINT134_EN, R_TSPINT134_STATUS}, + {8, 17, 1, R_TSPINT135_EN, R_TSPINT135_STATUS}, + {9, 18, 1, R_TSPINT136_EN, R_TSPINT136_STATUS}, +}; + +static void aspeed_2700tsp_intc_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); + + dc->desc = "ASPEED 2700 TSP INTC Controller"; + aic->num_lines = 32; + aic->num_inpins = 10; + aic->num_outpins = 19; + aic->mem_size = 0x4000; + aic->nr_regs = 0x3B08 >> 2; + aic->reg_offset = 0; + aic->reg_ops = &aspeed_tsp_intc_ops; + aic->irq_table = aspeed_2700tsp_intc_irqs; + aic->irq_table_count = ARRAY_SIZE(aspeed_2700tsp_intc_irqs); +} + +static const TypeInfo aspeed_2700tsp_intc_info = { + .name = TYPE_ASPEED_2700TSP_INTC, + .parent = TYPE_ASPEED_INTC, + .class_init = aspeed_2700tsp_intc_class_init, +}; + +static AspeedINTCIRQ aspeed_2700tsp_intcio_irqs[ASPEED_INTC_MAX_INPINS] = { + {0, 0, 1, R_TSPINT160_EN, R_TSPINT160_STATUS}, + {1, 1, 1, R_TSPINT161_EN, R_TSPINT161_STATUS}, + {2, 2, 1, R_TSPINT162_EN, R_TSPINT162_STATUS}, + {3, 3, 1, R_TSPINT163_EN, R_TSPINT163_STATUS}, + {4, 4, 1, R_TSPINT164_EN, R_TSPINT164_STATUS}, + {5, 5, 1, R_TSPINT165_EN, R_TSPINT165_STATUS}, +}; + +static void aspeed_2700tsp_intcio_class_init(ObjectClass *klass, + const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + AspeedINTCClass *aic = ASPEED_INTC_CLASS(klass); + + dc->desc = "ASPEED 2700 TSP INTC IO Controller"; + aic->num_lines = 32; + aic->num_inpins = 6; + aic->num_outpins = 6; + aic->mem_size = 0x400; + aic->nr_regs = 0x258 >> 2; + aic->reg_offset = 0x0; + aic->reg_ops = &aspeed_tsp_intcio_ops; + aic->irq_table = aspeed_2700tsp_intcio_irqs; + aic->irq_table_count = ARRAY_SIZE(aspeed_2700tsp_intcio_irqs); +} + +static const TypeInfo aspeed_2700tsp_intcio_info = { + .name = TYPE_ASPEED_2700TSP_INTCIO, + .parent = TYPE_ASPEED_INTC, + .class_init = aspeed_2700tsp_intcio_class_init, +}; + static void aspeed_intc_register_types(void) { type_register_static(&aspeed_intc_info); type_register_static(&aspeed_2700_intc_info); type_register_static(&aspeed_2700_intcio_info); + type_register_static(&aspeed_2700ssp_intc_info); + type_register_static(&aspeed_2700ssp_intcio_info); + type_register_static(&aspeed_2700tsp_intc_info); + type_register_static(&aspeed_2700tsp_intcio_info); } type_init(aspeed_intc_register_types); diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c index 55fe51a..7120088 100644 --- a/hw/intc/aspeed_vic.c +++ b/hw/intc/aspeed_vic.c @@ -339,7 +339,7 @@ static const VMStateDescription vmstate_aspeed_vic = { } }; -static void aspeed_vic_class_init(ObjectClass *klass, void *data) +static void aspeed_vic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = aspeed_vic_realize; diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c index 4a42fcf..55e0a5a 100644 --- a/hw/intc/bcm2835_ic.c +++ b/hw/intc/bcm2835_ic.c @@ -219,7 +219,7 @@ static const VMStateDescription vmstate_bcm2835_ic = { } }; -static void bcm2835_ic_class_init(ObjectClass *klass, void *data) +static void bcm2835_ic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c index 197a0e2..1c02853 100644 --- a/hw/intc/bcm2836_control.c +++ b/hw/intc/bcm2836_control.c @@ -384,7 +384,7 @@ static const VMStateDescription vmstate_bcm2836_control = { } }; -static void bcm2836_control_class_init(ObjectClass *klass, void *data) +static void bcm2836_control_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c index 6ddbcd4..ebbe234 100644 --- a/hw/intc/exynos4210_combiner.c +++ b/hw/intc/exynos4210_combiner.c @@ -329,7 +329,7 @@ static const Property exynos4210_combiner_properties[] = { DEFINE_PROP_UINT32("external", Exynos4210CombinerState, external, 0), }; -static void exynos4210_combiner_class_init(ObjectClass *klass, void *data) +static void exynos4210_combiner_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c index 01a5393..7e2d79d 100644 --- a/hw/intc/exynos4210_gic.c +++ b/hw/intc/exynos4210_gic.c @@ -115,7 +115,7 @@ static const Property exynos4210_gic_properties[] = { DEFINE_PROP_UINT32("num-cpu", Exynos4210GicState, num_cpu, 1), }; -static void exynos4210_gic_class_init(ObjectClass *klass, void *data) +static void exynos4210_gic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/goldfish_pic.c b/hw/intc/goldfish_pic.c index aa5162c..2359861 100644 --- a/hw/intc/goldfish_pic.c +++ b/hw/intc/goldfish_pic.c @@ -185,7 +185,7 @@ static const Property goldfish_pic_properties[] = { DEFINE_PROP_UINT8("index", GoldfishPICState, idx, 0), }; -static void goldfish_pic_class_init(ObjectClass *oc, void *data) +static void goldfish_pic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(oc); @@ -204,7 +204,7 @@ static const TypeInfo goldfish_pic_info = { .class_init = goldfish_pic_class_init, .instance_init = goldfish_pic_instance_init, .instance_size = sizeof(GoldfishPICState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_INTERRUPT_STATS_PROVIDER }, { } }, diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c index 95cdb41..e0f2646 100644 --- a/hw/intc/grlib_irqmp.c +++ b/hw/intc/grlib_irqmp.c @@ -380,7 +380,7 @@ static const Property grlib_irqmp_properties[] = { DEFINE_PROP_UINT32("ncpus", IRQMP, ncpus, 1), }; -static void grlib_irqmp_class_init(ObjectClass *klass, void *data) +static void grlib_irqmp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/heathrow_pic.c b/hw/intc/heathrow_pic.c index 729498f..447e8c2 100644 --- a/hw/intc/heathrow_pic.c +++ b/hw/intc/heathrow_pic.c @@ -184,7 +184,7 @@ static void heathrow_init(Object *obj) sysbus_init_mmio(sbd, &s->mem); } -static void heathrow_class_init(ObjectClass *oc, void *data) +static void heathrow_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c index d88b20f..b6f96bf 100644 --- a/hw/intc/i8259.c +++ b/hw/intc/i8259.c @@ -32,10 +32,7 @@ #include "trace.h" #include "qom/object.h" -/* debug PIC */ -//#define DEBUG_PIC - -//#define DEBUG_IRQ_LATENCY +/*#define DEBUG_IRQ_LATENCY*/ #define TYPE_I8259 "isa-i8259" typedef struct PICClass PICClass; @@ -436,7 +433,7 @@ qemu_irq *i8259_init(ISABus *bus, qemu_irq parent_irq_in) return irq_set; } -static void i8259_class_init(ObjectClass *klass, void *data) +static void i8259_class_init(ObjectClass *klass, const void *data) { PICClass *k = PIC_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/i8259_common.c b/hw/intc/i8259_common.c index c77ff68..602e44c 100644 --- a/hw/intc/i8259_common.c +++ b/hw/intc/i8259_common.c @@ -200,7 +200,7 @@ static const Property pic_properties_common[] = { DEFINE_PROP_BIT("master", PICCommonState, master, 0, false), }; -static void pic_common_class_init(ObjectClass *klass, void *data) +static void pic_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); @@ -226,7 +226,7 @@ static const TypeInfo pic_common_type = { .class_size = sizeof(PICCommonClass), .class_init = pic_common_class_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_INTERRUPT_STATS_PROVIDER }, { } }, diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c index e1c9ce7..09c3bfa 100644 --- a/hw/intc/imx_avic.c +++ b/hw/intc/imx_avic.c @@ -341,7 +341,7 @@ static void imx_avic_init(Object *obj) } -static void imx_avic_class_init(ObjectClass *klass, void *data) +static void imx_avic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/imx_gpcv2.c b/hw/intc/imx_gpcv2.c index 9e5cf28..58d286c 100644 --- a/hw/intc/imx_gpcv2.c +++ b/hw/intc/imx_gpcv2.c @@ -102,7 +102,7 @@ static const VMStateDescription vmstate_imx_gpcv2 = { }, }; -static void imx_gpcv2_class_init(ObjectClass *klass, void *data) +static void imx_gpcv2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c index 8cd1d85..133bef8 100644 --- a/hw/intc/ioapic.c +++ b/hw/intc/ioapic.c @@ -480,7 +480,7 @@ static const Property ioapic_properties[] = { DEFINE_PROP_UINT8("version", IOAPICCommonState, version, IOAPIC_VER_DEF), }; -static void ioapic_class_init(ObjectClass *klass, void *data) +static void ioapic_class_init(ObjectClass *klass, const void *data) { IOAPICCommonClass *k = IOAPIC_COMMON_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/ioapic_common.c b/hw/intc/ioapic_common.c index 7698963..fce3486 100644 --- a/hw/intc/ioapic_common.c +++ b/hw/intc/ioapic_common.c @@ -197,7 +197,7 @@ static const VMStateDescription vmstate_ioapic_common = { } }; -static void ioapic_common_class_init(ObjectClass *klass, void *data) +static void ioapic_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); @@ -215,7 +215,7 @@ static const TypeInfo ioapic_common_type = { .class_size = sizeof(IOAPICCommonClass), .class_init = ioapic_common_class_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_INTERRUPT_STATS_PROVIDER }, { } }, diff --git a/hw/intc/ioapic_internal.h b/hw/intc/ioapic_internal.h index 37b8565..5120576 100644 --- a/hw/intc/ioapic_internal.h +++ b/hw/intc/ioapic_internal.h @@ -22,7 +22,7 @@ #ifndef HW_INTC_IOAPIC_INTERNAL_H #define HW_INTC_IOAPIC_INTERNAL_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/intc/ioapic.h" #include "hw/sysbus.h" #include "qemu/notify.h" diff --git a/hw/intc/loongarch_extioi.c b/hw/intc/loongarch_extioi.c index a51a215..8b8ac6b 100644 --- a/hw/intc/loongarch_extioi.c +++ b/hw/intc/loongarch_extioi.c @@ -11,7 +11,8 @@ #include "qapi/error.h" #include "hw/irq.h" #include "hw/loongarch/virt.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" +#include "system/kvm.h" #include "hw/intc/loongarch_extioi.h" #include "trace.h" @@ -351,23 +352,29 @@ static void loongarch_extioi_realize(DeviceState *dev, Error **errp) return; } - for (i = 0; i < EXTIOI_IRQS; i++) { - sysbus_init_irq(sbd, &s->irq[i]); - } - - qdev_init_gpio_in(dev, extioi_setirq, EXTIOI_IRQS); - memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, - s, "extioi_system_mem", 0x900); - sysbus_init_mmio(sbd, &s->extioi_system_mem); - if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) { - memory_region_init_io(&s->virt_extend, OBJECT(s), &extioi_virt_ops, - s, "extioi_virt", EXTIOI_VIRT_SIZE); - sysbus_init_mmio(sbd, &s->virt_extend); s->features |= EXTIOI_VIRT_HAS_FEATURES; } else { s->status |= BIT(EXTIOI_ENABLE); } + + if (kvm_irqchip_in_kernel()) { + kvm_extioi_realize(dev, errp); + } else { + for (i = 0; i < EXTIOI_IRQS; i++) { + sysbus_init_irq(sbd, &s->irq[i]); + } + + qdev_init_gpio_in(dev, extioi_setirq, EXTIOI_IRQS); + memory_region_init_io(&s->extioi_system_mem, OBJECT(s), &extioi_ops, + s, "extioi_system_mem", 0x900); + sysbus_init_mmio(sbd, &s->extioi_system_mem); + if (s->features & BIT(EXTIOI_HAS_VIRT_EXTENSION)) { + memory_region_init_io(&s->virt_extend, OBJECT(s), &extioi_virt_ops, + s, "extioi_virt", EXTIOI_VIRT_SIZE); + sysbus_init_mmio(sbd, &s->virt_extend); + } + } } static void loongarch_extioi_unrealize(DeviceState *dev) @@ -377,11 +384,26 @@ static void loongarch_extioi_unrealize(DeviceState *dev) g_free(s->cpu); } -static void loongarch_extioi_reset(DeviceState *d) +static void loongarch_extioi_reset_hold(Object *obj, ResetType type) +{ + LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_GET_CLASS(obj); + + if (lec->parent_phases.hold) { + lec->parent_phases.hold(obj, type); + } + + if (kvm_irqchip_in_kernel()) { + kvm_extioi_put(obj, 0); + } +} + +static int vmstate_extioi_pre_save(void *opaque) { - LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(d); + if (kvm_irqchip_in_kernel()) { + return kvm_extioi_get(opaque); + } - s->status = 0; + return 0; } static int vmstate_extioi_post_load(void *opaque, int version_id) @@ -389,6 +411,10 @@ static int vmstate_extioi_post_load(void *opaque, int version_id) LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(opaque); int i, start_irq; + if (kvm_irqchip_in_kernel()) { + return kvm_extioi_put(opaque, version_id); + } + for (i = 0; i < (EXTIOI_IRQS / 4); i++) { start_irq = i * 4; extioi_update_sw_coremap(s, start_irq, s->coremap[i], false); @@ -401,17 +427,20 @@ static int vmstate_extioi_post_load(void *opaque, int version_id) return 0; } -static void loongarch_extioi_class_init(ObjectClass *klass, void *data) +static void loongarch_extioi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongArchExtIOIClass *lec = LOONGARCH_EXTIOI_CLASS(klass); LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_extioi_realize, &lec->parent_realize); device_class_set_parent_unrealize(dc, loongarch_extioi_unrealize, &lec->parent_unrealize); - device_class_set_legacy_reset(dc, loongarch_extioi_reset); + resettable_class_set_parent_phases(rc, NULL, loongarch_extioi_reset_hold, + NULL, &lec->parent_phases); + lecc->pre_save = vmstate_extioi_pre_save; lecc->post_load = vmstate_extioi_post_load; } diff --git a/hw/intc/loongarch_extioi_common.c b/hw/intc/loongarch_extioi_common.c index ff3974f..4a904b3 100644 --- a/hw/intc/loongarch_extioi_common.c +++ b/hw/intc/loongarch_extioi_common.c @@ -108,6 +108,43 @@ static void loongarch_extioi_common_realize(DeviceState *dev, Error **errp) } } +static void loongarch_extioi_common_reset_hold(Object *obj, ResetType type) +{ + LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_GET_CLASS(obj); + LoongArchExtIOICommonState *s = LOONGARCH_EXTIOI_COMMON(obj); + ExtIOICore *core; + int i; + + if (lecc->parent_phases.hold) { + lecc->parent_phases.hold(obj, type); + } + + /* Clear HW registers for the board */ + memset(s->nodetype, 0, sizeof(s->nodetype)); + memset(s->bounce, 0, sizeof(s->bounce)); + memset(s->isr, 0, sizeof(s->isr)); + memset(s->enable, 0, sizeof(s->enable)); + memset(s->ipmap, 0, sizeof(s->ipmap)); + memset(s->coremap, 0, sizeof(s->coremap)); + memset(s->sw_pending, 0, sizeof(s->sw_pending)); + memset(s->sw_ipmap, 0, sizeof(s->sw_ipmap)); + memset(s->sw_coremap, 0, sizeof(s->sw_coremap)); + + for (i = 0; i < s->num_cpu; i++) { + core = s->cpu + i; + /* EXTIOI with targeted CPU available however not present */ + if (!core->cpu) { + continue; + } + + /* Clear HW registers for CPUs */ + memset(core->coreisr, 0, sizeof(core->coreisr)); + memset(core->sw_isr, 0, sizeof(core->sw_isr)); + } + + s->status = 0; +} + static int loongarch_extioi_common_pre_save(void *opaque) { LoongArchExtIOICommonState *s = (LoongArchExtIOICommonState *)opaque; @@ -174,14 +211,19 @@ static const Property extioi_properties[] = { features, EXTIOI_HAS_VIRT_EXTENSION, 0), }; -static void loongarch_extioi_common_class_init(ObjectClass *klass, void *data) +static void loongarch_extioi_common_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongArchExtIOICommonClass *lecc = LOONGARCH_EXTIOI_COMMON_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_extioi_common_realize, &lecc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, + loongarch_extioi_common_reset_hold, + NULL, &lecc->parent_phases); device_class_set_props(dc, extioi_properties); dc->vmsd = &vmstate_loongarch_extioi; hc->plug = loongarch_extioi_cpu_plug; @@ -195,7 +237,7 @@ static const TypeInfo loongarch_extioi_common_types[] = { .instance_size = sizeof(LoongArchExtIOICommonState), .class_size = sizeof(LoongArchExtIOICommonClass), .class_init = loongarch_extioi_common_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, diff --git a/hw/intc/loongarch_extioi_kvm.c b/hw/intc/loongarch_extioi_kvm.c new file mode 100644 index 0000000..0133540 --- /dev/null +++ b/hw/intc/loongarch_extioi_kvm.c @@ -0,0 +1,140 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch EXTIOI interrupt kvm support + * + * Copyright (C) 2025 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qemu/typedefs.h" +#include "hw/intc/loongarch_extioi.h" +#include "linux/kvm.h" +#include "qapi/error.h" +#include "system/kvm.h" + +static void kvm_extioi_access_reg(int fd, uint64_t addr, void *val, bool write) +{ + kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_REGS, + addr, val, write, &error_abort); +} + +static void kvm_extioi_access_sw_state(int fd, uint64_t addr, + void *val, bool write) +{ + kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_SW_STATUS, + addr, val, write, &error_abort); +} + +static void kvm_extioi_access_sw_status(void *opaque, bool write) +{ + LoongArchExtIOICommonState *lecs = LOONGARCH_EXTIOI_COMMON(opaque); + LoongArchExtIOIState *les = LOONGARCH_EXTIOI(opaque); + int addr; + + addr = KVM_DEV_LOONGARCH_EXTIOI_SW_STATUS_STATE; + kvm_extioi_access_sw_state(les->dev_fd, addr, &lecs->status, write); +} + +static void kvm_extioi_access_regs(void *opaque, bool write) +{ + LoongArchExtIOICommonState *lecs = LOONGARCH_EXTIOI_COMMON(opaque); + LoongArchExtIOIState *les = LOONGARCH_EXTIOI(opaque); + int fd = les->dev_fd; + int addr, offset, cpu; + + for (addr = EXTIOI_NODETYPE_START; addr < EXTIOI_NODETYPE_END; addr += 4) { + offset = (addr - EXTIOI_NODETYPE_START) / 4; + kvm_extioi_access_reg(fd, addr, &lecs->nodetype[offset], write); + } + + for (addr = EXTIOI_IPMAP_START; addr < EXTIOI_IPMAP_END; addr += 4) { + offset = (addr - EXTIOI_IPMAP_START) / 4; + kvm_extioi_access_reg(fd, addr, &lecs->ipmap[offset], write); + } + + for (addr = EXTIOI_ENABLE_START; addr < EXTIOI_ENABLE_END; addr += 4) { + offset = (addr - EXTIOI_ENABLE_START) / 4; + kvm_extioi_access_reg(fd, addr, &lecs->enable[offset], write); + } + + for (addr = EXTIOI_BOUNCE_START; addr < EXTIOI_BOUNCE_END; addr += 4) { + offset = (addr - EXTIOI_BOUNCE_START) / 4; + kvm_extioi_access_reg(fd, addr, &lecs->bounce[offset], write); + } + + for (addr = EXTIOI_ISR_START; addr < EXTIOI_ISR_END; addr += 4) { + offset = (addr - EXTIOI_ISR_START) / 4; + kvm_extioi_access_reg(fd, addr, &lecs->isr[offset], write); + } + + for (addr = EXTIOI_COREMAP_START; addr < EXTIOI_COREMAP_END; addr += 4) { + offset = (addr - EXTIOI_COREMAP_START) / 4; + kvm_extioi_access_reg(fd, addr, &lecs->coremap[offset], write); + } + + for (cpu = 0; cpu < lecs->num_cpu; cpu++) { + for (addr = EXTIOI_COREISR_START; + addr < EXTIOI_COREISR_END; addr += 4) { + offset = (addr - EXTIOI_COREISR_START) / 4; + kvm_extioi_access_reg(fd, (cpu << 16) | addr, + &lecs->cpu[cpu].coreisr[offset], write); + } + } +} + +int kvm_extioi_get(void *opaque) +{ + kvm_extioi_access_regs(opaque, false); + kvm_extioi_access_sw_status(opaque, false); + return 0; +} + +int kvm_extioi_put(void *opaque, int version_id) +{ + LoongArchExtIOIState *les = LOONGARCH_EXTIOI(opaque); + int fd = les->dev_fd; + + if (fd == 0) { + return 0; + } + + kvm_extioi_access_regs(opaque, true); + kvm_extioi_access_sw_status(opaque, true); + kvm_device_access(fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL, + KVM_DEV_LOONGARCH_EXTIOI_CTRL_LOAD_FINISHED, + NULL, true, &error_abort); + return 0; +} + +void kvm_extioi_realize(DeviceState *dev, Error **errp) +{ + LoongArchExtIOICommonState *lecs = LOONGARCH_EXTIOI_COMMON(dev); + LoongArchExtIOIState *les = LOONGARCH_EXTIOI(dev); + int ret; + + ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_LOONGARCH_EIOINTC, false); + if (ret < 0) { + fprintf(stderr, "create KVM_LOONGARCH_EIOINTC failed: %s\n", + strerror(-ret)); + abort(); + } + + les->dev_fd = ret; + ret = kvm_device_access(les->dev_fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL, + KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_NUM_CPU, + &lecs->num_cpu, true, NULL); + if (ret < 0) { + fprintf(stderr, "KVM_LOONGARCH_EXTIOI_INIT_NUM_CPU failed: %s\n", + strerror(-ret)); + abort(); + } + + ret = kvm_device_access(les->dev_fd, KVM_DEV_LOONGARCH_EXTIOI_GRP_CTRL, + KVM_DEV_LOONGARCH_EXTIOI_CTRL_INIT_FEATURE, + &lecs->features, true, NULL); + if (ret < 0) { + fprintf(stderr, "KVM_LOONGARCH_EXTIOI_INIT_FEATURE failed: %s\n", + strerror(-ret)); + abort(); + } +} diff --git a/hw/intc/loongarch_ipi.c b/hw/intc/loongarch_ipi.c index b10641d..fc8005c 100644 --- a/hw/intc/loongarch_ipi.c +++ b/hw/intc/loongarch_ipi.c @@ -11,6 +11,7 @@ #include "qapi/error.h" #include "hw/intc/loongarch_ipi.h" #include "hw/qdev-properties.h" +#include "system/kvm.h" #include "target/loongarch/cpu.h" static AddressSpace *get_iocsr_as(CPUState *cpu) @@ -91,6 +92,40 @@ static void loongarch_ipi_realize(DeviceState *dev, Error **errp) lics->cpu[i].ipi = lics; qdev_init_gpio_out(dev, &lics->cpu[i].irq, 1); } + + if (kvm_irqchip_in_kernel()) { + kvm_ipi_realize(dev, errp); + } +} + +static void loongarch_ipi_reset_hold(Object *obj, ResetType type) +{ + int i; + LoongarchIPIClass *lic = LOONGARCH_IPI_GET_CLASS(obj); + LoongsonIPICommonState *lics = LOONGSON_IPI_COMMON(obj); + IPICore *core; + + if (lic->parent_phases.hold) { + lic->parent_phases.hold(obj, type); + } + + for (i = 0; i < lics->num_cpu; i++) { + core = lics->cpu + i; + /* IPI with targeted CPU available however not present */ + if (!core->cpu) { + continue; + } + + core->status = 0; + core->en = 0; + core->set = 0; + core->clear = 0; + memset(core->buf, 0, sizeof(core->buf)); + } + + if (kvm_irqchip_in_kernel()) { + kvm_ipi_put(obj, 0); + } } static void loongarch_ipi_cpu_plug(HotplugHandler *hotplug_dev, @@ -140,19 +175,42 @@ static void loongarch_ipi_cpu_unplug(HotplugHandler *hotplug_dev, core->cpu = NULL; } -static void loongarch_ipi_class_init(ObjectClass *klass, void *data) +static int loongarch_ipi_pre_save(void *opaque) +{ + if (kvm_irqchip_in_kernel()) { + return kvm_ipi_get(opaque); + } + + return 0; +} + +static int loongarch_ipi_post_load(void *opaque, int version_id) +{ + if (kvm_irqchip_in_kernel()) { + return kvm_ipi_put(opaque, version_id); + } + + return 0; +} + +static void loongarch_ipi_class_init(ObjectClass *klass, const void *data) { LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); LoongarchIPIClass *lic = LOONGARCH_IPI_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_ipi_realize, &lic->parent_realize); + resettable_class_set_parent_phases(rc, NULL, loongarch_ipi_reset_hold, + NULL, &lic->parent_phases); licc->get_iocsr_as = get_iocsr_as; licc->cpu_by_arch_id = loongarch_cpu_by_arch_id; hc->plug = loongarch_ipi_cpu_plug; hc->unplug = loongarch_ipi_cpu_unplug; + licc->pre_save = loongarch_ipi_pre_save; + licc->post_load = loongarch_ipi_post_load; } static const TypeInfo loongarch_ipi_types[] = { @@ -162,7 +220,7 @@ static const TypeInfo loongarch_ipi_types[] = { .instance_size = sizeof(LoongarchIPIState), .class_size = sizeof(LoongarchIPIClass), .class_init = loongarch_ipi_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, diff --git a/hw/intc/loongarch_ipi_kvm.c b/hw/intc/loongarch_ipi_kvm.c new file mode 100644 index 0000000..4cb3acc --- /dev/null +++ b/hw/intc/loongarch_ipi_kvm.c @@ -0,0 +1,85 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch IPI interrupt KVM support + * + * Copyright (C) 2025 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/intc/loongarch_ipi.h" +#include "system/kvm.h" +#include "target/loongarch/cpu.h" + +static void kvm_ipi_access_reg(int fd, uint64_t addr, uint32_t *val, bool write) +{ + kvm_device_access(fd, KVM_DEV_LOONGARCH_IPI_GRP_REGS, + addr, val, write, &error_abort); +} + +static void kvm_ipi_access_regs(void *opaque, bool write) +{ + LoongsonIPICommonState *ipi = (LoongsonIPICommonState *)opaque; + LoongarchIPIState *lis = LOONGARCH_IPI(opaque); + IPICore *core; + uint64_t attr; + int cpu, fd = lis->dev_fd; + + if (fd == 0) { + return; + } + + for (cpu = 0; cpu < ipi->num_cpu; cpu++) { + core = &ipi->cpu[cpu]; + attr = (cpu << 16) | CORE_STATUS_OFF; + kvm_ipi_access_reg(fd, attr, &core->status, write); + + attr = (cpu << 16) | CORE_EN_OFF; + kvm_ipi_access_reg(fd, attr, &core->en, write); + + attr = (cpu << 16) | CORE_SET_OFF; + kvm_ipi_access_reg(fd, attr, &core->set, write); + + attr = (cpu << 16) | CORE_CLEAR_OFF; + kvm_ipi_access_reg(fd, attr, &core->clear, write); + + attr = (cpu << 16) | CORE_BUF_20; + kvm_ipi_access_reg(fd, attr, &core->buf[0], write); + + attr = (cpu << 16) | CORE_BUF_28; + kvm_ipi_access_reg(fd, attr, &core->buf[2], write); + + attr = (cpu << 16) | CORE_BUF_30; + kvm_ipi_access_reg(fd, attr, &core->buf[4], write); + + attr = (cpu << 16) | CORE_BUF_38; + kvm_ipi_access_reg(fd, attr, &core->buf[6], write); + } +} + +int kvm_ipi_get(void *opaque) +{ + kvm_ipi_access_regs(opaque, false); + return 0; +} + +int kvm_ipi_put(void *opaque, int version_id) +{ + kvm_ipi_access_regs(opaque, true); + return 0; +} + +void kvm_ipi_realize(DeviceState *dev, Error **errp) +{ + LoongarchIPIState *lis = LOONGARCH_IPI(dev); + int ret; + + ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_LOONGARCH_IPI, false); + if (ret < 0) { + fprintf(stderr, "IPI KVM_CREATE_DEVICE failed: %s\n", + strerror(-ret)); + abort(); + } + + lis->dev_fd = ret; +} diff --git a/hw/intc/loongarch_pch_msi.c b/hw/intc/loongarch_pch_msi.c index 66b5c1e..f6d1631 100644 --- a/hw/intc/loongarch_pch_msi.c +++ b/hw/intc/loongarch_pch_msi.c @@ -13,6 +13,7 @@ #include "hw/pci/msi.h" #include "hw/misc/unimp.h" #include "migration/vmstate.h" +#include "system/kvm.h" #include "trace.h" static uint64_t loongarch_msi_mem_read(void *opaque, hwaddr addr, unsigned size) @@ -26,6 +27,15 @@ static void loongarch_msi_mem_write(void *opaque, hwaddr addr, LoongArchPCHMSI *s = (LoongArchPCHMSI *)opaque; int irq_num; + if (kvm_irqchip_in_kernel()) { + MSIMessage msg; + + msg.address = addr; + msg.data = val; + kvm_irqchip_send_msi(kvm_state, msg); + return; + } + /* * vector number is irq number from upper extioi intc * need subtract irq base to get msi vector offset @@ -42,13 +52,6 @@ static const MemoryRegionOps loongarch_pch_msi_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -static void pch_msi_irq_handler(void *opaque, int irq, int level) -{ - LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(opaque); - - qemu_set_irq(s->pch_msi_irq[irq], level); -} - static void loongarch_pch_msi_realize(DeviceState *dev, Error **errp) { LoongArchPCHMSI *s = LOONGARCH_PCH_MSI(dev); @@ -59,9 +62,7 @@ static void loongarch_pch_msi_realize(DeviceState *dev, Error **errp) } s->pch_msi_irq = g_new(qemu_irq, s->irq_num); - qdev_init_gpio_out(dev, s->pch_msi_irq, s->irq_num); - qdev_init_gpio_in(dev, pch_msi_irq_handler, s->irq_num); } static void loongarch_pch_msi_unrealize(DeviceState *dev) @@ -88,7 +89,7 @@ static const Property loongarch_msi_properties[] = { DEFINE_PROP_UINT32("msi_irq_num", LoongArchPCHMSI, irq_num, 0), }; -static void loongarch_pch_msi_class_init(ObjectClass *klass, void *data) +static void loongarch_pch_msi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/loongarch_pch_pic.c b/hw/intc/loongarch_pch_pic.c index acd75cc..c4b242d 100644 --- a/hw/intc/loongarch_pch_pic.c +++ b/hw/intc/loongarch_pch_pic.c @@ -7,8 +7,10 @@ #include "qemu/osdep.h" #include "qemu/bitops.h" +#include "qemu/log.h" #include "hw/irq.h" #include "hw/intc/loongarch_pch_pic.h" +#include "system/kvm.h" #include "trace.h" #include "qapi/error.h" @@ -47,6 +49,11 @@ static void pch_pic_irq_handler(void *opaque, int irq, int level) assert(irq < s->irq_num); trace_loongarch_pch_pic_irq_handler(irq, level); + if (kvm_irqchip_in_kernel()) { + kvm_set_irq(kvm_state, irq, !!level); + return; + } + if (s->intedge & mask) { /* Edge triggered */ if (level) { @@ -71,308 +78,196 @@ static void pch_pic_irq_handler(void *opaque, int irq, int level) pch_pic_update_irq(s, mask, level); } -static uint64_t loongarch_pch_pic_low_readw(void *opaque, hwaddr addr, - unsigned size) +static uint64_t pch_pic_read(void *opaque, hwaddr addr, uint64_t field_mask) { LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); uint64_t val = 0; - uint32_t offset = addr & 0xfff; + uint32_t offset; - switch (offset) { - case PCH_PIC_INT_ID_LO: - val = PCH_PIC_INT_ID_VAL; + offset = addr & 7; + addr -= offset; + switch (addr) { + case PCH_PIC_INT_ID: + val = cpu_to_le64(s->id.data); break; - case PCH_PIC_INT_ID_HI: - /* - * With 7A1000 manual - * bit 0-15 pch irqchip version - * bit 16-31 irq number supported with pch irqchip - */ - val = deposit32(PCH_PIC_INT_ID_VER, 16, 16, s->irq_num - 1); + case PCH_PIC_INT_MASK: + val = s->int_mask; break; - case PCH_PIC_INT_MASK_LO: - val = (uint32_t)s->int_mask; + case PCH_PIC_INT_EDGE: + val = s->intedge; break; - case PCH_PIC_INT_MASK_HI: - val = s->int_mask >> 32; + case PCH_PIC_HTMSI_EN: + val = s->htmsi_en; break; - case PCH_PIC_INT_EDGE_LO: - val = (uint32_t)s->intedge; + case PCH_PIC_AUTO_CTRL0: + case PCH_PIC_AUTO_CTRL1: + /* PCH PIC connect to EXTIOI always, discard auto_ctrl access */ break; - case PCH_PIC_INT_EDGE_HI: - val = s->intedge >> 32; + case PCH_PIC_INT_STATUS: + val = s->intisr & (~s->int_mask); break; - case PCH_PIC_HTMSI_EN_LO: - val = (uint32_t)s->htmsi_en; + case PCH_PIC_INT_POL: + val = s->int_polarity; break; - case PCH_PIC_HTMSI_EN_HI: - val = s->htmsi_en >> 32; + case PCH_PIC_HTMSI_VEC ... PCH_PIC_HTMSI_VEC_END: + val = *(uint64_t *)(s->htmsi_vector + addr - PCH_PIC_HTMSI_VEC); break; - case PCH_PIC_AUTO_CTRL0_LO: - case PCH_PIC_AUTO_CTRL0_HI: - case PCH_PIC_AUTO_CTRL1_LO: - case PCH_PIC_AUTO_CTRL1_HI: + case PCH_PIC_ROUTE_ENTRY ... PCH_PIC_ROUTE_ENTRY_END: + val = *(uint64_t *)(s->route_entry + addr - PCH_PIC_ROUTE_ENTRY); break; default: + qemu_log_mask(LOG_GUEST_ERROR, + "pch_pic_read: Bad address 0x%"PRIx64"\n", addr); break; } - trace_loongarch_pch_pic_low_readw(size, addr, val); - return val; + return (val >> (offset * 8)) & field_mask; } -static uint64_t get_writew_val(uint64_t value, uint32_t target, bool hi) -{ - uint64_t mask = 0xffffffff00000000; - uint64_t data = target; - - return hi ? (value & ~mask) | (data << 32) : (value & mask) | data; -} - -static void loongarch_pch_pic_low_writew(void *opaque, hwaddr addr, - uint64_t value, unsigned size) +static void pch_pic_write(void *opaque, hwaddr addr, uint64_t value, + uint64_t field_mask) { LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); - uint32_t offset, old_valid, data = (uint32_t)value; - uint64_t old, int_mask; - offset = addr & 0xfff; - - trace_loongarch_pch_pic_low_writew(size, addr, data); - - switch (offset) { - case PCH_PIC_INT_MASK_LO: - old = s->int_mask; - s->int_mask = get_writew_val(old, data, 0); - old_valid = (uint32_t)old; - if (old_valid & ~data) { - pch_pic_update_irq(s, (old_valid & ~data), 1); - } - if (~old_valid & data) { - pch_pic_update_irq(s, (~old_valid & data), 0); - } - break; - case PCH_PIC_INT_MASK_HI: + uint32_t offset; + uint64_t old, mask, data, *ptemp; + + offset = addr & 7; + addr -= offset; + mask = field_mask << (offset * 8); + data = (value & field_mask) << (offset * 8); + switch (addr) { + case PCH_PIC_INT_MASK: old = s->int_mask; - s->int_mask = get_writew_val(old, data, 1); - old_valid = (uint32_t)(old >> 32); - int_mask = old_valid & ~data; - if (int_mask) { - pch_pic_update_irq(s, int_mask << 32, 1); + s->int_mask = (old & ~mask) | data; + if (old & ~data) { + pch_pic_update_irq(s, old & ~data, 1); } - int_mask = ~old_valid & data; - if (int_mask) { - pch_pic_update_irq(s, int_mask << 32, 0); + + if (~old & data) { + pch_pic_update_irq(s, ~old & data, 0); } break; - case PCH_PIC_INT_EDGE_LO: - s->intedge = get_writew_val(s->intedge, data, 0); - break; - case PCH_PIC_INT_EDGE_HI: - s->intedge = get_writew_val(s->intedge, data, 1); + case PCH_PIC_INT_EDGE: + s->intedge = (s->intedge & ~mask) | data; break; - case PCH_PIC_INT_CLEAR_LO: + case PCH_PIC_INT_CLEAR: if (s->intedge & data) { - s->intirr &= (~data); + s->intirr &= ~data; pch_pic_update_irq(s, data, 0); - s->intisr &= (~data); + s->intisr &= ~data; } break; - case PCH_PIC_INT_CLEAR_HI: - value <<= 32; - if (s->intedge & value) { - s->intirr &= (~value); - pch_pic_update_irq(s, value, 0); - s->intisr &= (~value); - } + case PCH_PIC_HTMSI_EN: + s->htmsi_en = (s->htmsi_en & ~mask) | data; break; - case PCH_PIC_HTMSI_EN_LO: - s->htmsi_en = get_writew_val(s->htmsi_en, data, 0); + case PCH_PIC_AUTO_CTRL0: + case PCH_PIC_AUTO_CTRL1: + /* Discard auto_ctrl access */ break; - case PCH_PIC_HTMSI_EN_HI: - s->htmsi_en = get_writew_val(s->htmsi_en, data, 1); + case PCH_PIC_INT_POL: + s->int_polarity = (s->int_polarity & ~mask) | data; break; - case PCH_PIC_AUTO_CTRL0_LO: - case PCH_PIC_AUTO_CTRL0_HI: - case PCH_PIC_AUTO_CTRL1_LO: - case PCH_PIC_AUTO_CTRL1_HI: + case PCH_PIC_HTMSI_VEC ... PCH_PIC_HTMSI_VEC_END: + ptemp = (uint64_t *)(s->htmsi_vector + addr - PCH_PIC_HTMSI_VEC); + *ptemp = (*ptemp & ~mask) | data; + break; + case PCH_PIC_ROUTE_ENTRY ... PCH_PIC_ROUTE_ENTRY_END: + ptemp = (uint64_t *)(s->route_entry + addr - PCH_PIC_ROUTE_ENTRY); + *ptemp = (*ptemp & ~mask) | data; break; default: + qemu_log_mask(LOG_GUEST_ERROR, + "pch_pic_write: Bad address 0x%"PRIx64"\n", addr); break; } } -static uint64_t loongarch_pch_pic_high_readw(void *opaque, hwaddr addr, - unsigned size) +static uint64_t loongarch_pch_pic_read(void *opaque, hwaddr addr, + unsigned size) { - LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); uint64_t val = 0; - uint32_t offset = addr & 0xfff; - switch (offset) { - case STATUS_LO_START: - val = (uint32_t)(s->intisr & (~s->int_mask)); + switch (size) { + case 1: + val = pch_pic_read(opaque, addr, UCHAR_MAX); break; - case STATUS_HI_START: - val = (s->intisr & (~s->int_mask)) >> 32; + case 2: + val = pch_pic_read(opaque, addr, USHRT_MAX); break; - case POL_LO_START: - val = (uint32_t)s->int_polarity; + case 4: + val = pch_pic_read(opaque, addr, UINT_MAX); break; - case POL_HI_START: - val = s->int_polarity >> 32; + case 8: + val = pch_pic_read(opaque, addr, UINT64_MAX); break; default: + qemu_log_mask(LOG_GUEST_ERROR, + "loongarch_pch_pic_read: Bad size %d\n", size); break; } - trace_loongarch_pch_pic_high_readw(size, addr, val); + trace_loongarch_pch_pic_read(size, addr, val); return val; } -static void loongarch_pch_pic_high_writew(void *opaque, hwaddr addr, - uint64_t value, unsigned size) +static void loongarch_pch_pic_write(void *opaque, hwaddr addr, + uint64_t value, unsigned size) { - LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); - uint32_t offset, data = (uint32_t)value; - offset = addr & 0xfff; - - trace_loongarch_pch_pic_high_writew(size, addr, data); + trace_loongarch_pch_pic_write(size, addr, value); - switch (offset) { - case STATUS_LO_START: - s->intisr = get_writew_val(s->intisr, data, 0); - break; - case STATUS_HI_START: - s->intisr = get_writew_val(s->intisr, data, 1); + switch (size) { + case 1: + pch_pic_write(opaque, addr, value, UCHAR_MAX); break; - case POL_LO_START: - s->int_polarity = get_writew_val(s->int_polarity, data, 0); + case 2: + pch_pic_write(opaque, addr, value, USHRT_MAX); break; - case POL_HI_START: - s->int_polarity = get_writew_val(s->int_polarity, data, 1); break; - default: - break; - } -} - -static uint64_t loongarch_pch_pic_readb(void *opaque, hwaddr addr, - unsigned size) -{ - LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); - uint64_t val = 0; - uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET; - int64_t offset_tmp; - - switch (offset) { - case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END: - offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET; - if (offset_tmp >= 0 && offset_tmp < 64) { - val = s->htmsi_vector[offset_tmp]; - } - break; - case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END: - offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET; - if (offset_tmp >= 0 && offset_tmp < 64) { - val = s->route_entry[offset_tmp]; - } - break; - default: - break; - } - - trace_loongarch_pch_pic_readb(size, addr, val); - return val; -} - -static void loongarch_pch_pic_writeb(void *opaque, hwaddr addr, - uint64_t data, unsigned size) -{ - LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); - int32_t offset_tmp; - uint32_t offset = (addr & 0xfff) + PCH_PIC_ROUTE_ENTRY_OFFSET; - - trace_loongarch_pch_pic_writeb(size, addr, data); - - switch (offset) { - case PCH_PIC_HTMSI_VEC_OFFSET ... PCH_PIC_HTMSI_VEC_END: - offset_tmp = offset - PCH_PIC_HTMSI_VEC_OFFSET; - if (offset_tmp >= 0 && offset_tmp < 64) { - s->htmsi_vector[offset_tmp] = (uint8_t)(data & 0xff); - } + case 4: + pch_pic_write(opaque, addr, value, UINT_MAX); break; - case PCH_PIC_ROUTE_ENTRY_OFFSET ... PCH_PIC_ROUTE_ENTRY_END: - offset_tmp = offset - PCH_PIC_ROUTE_ENTRY_OFFSET; - if (offset_tmp >= 0 && offset_tmp < 64) { - s->route_entry[offset_tmp] = (uint8_t)(data & 0xff); - } + case 8: + pch_pic_write(opaque, addr, value, UINT64_MAX); break; default: + qemu_log_mask(LOG_GUEST_ERROR, + "loongarch_pch_pic_write: Bad size %d\n", size); break; } } -static const MemoryRegionOps loongarch_pch_pic_reg32_low_ops = { - .read = loongarch_pch_pic_low_readw, - .write = loongarch_pch_pic_low_writew, - .valid = { - .min_access_size = 4, - .max_access_size = 8, - }, - .impl = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -static const MemoryRegionOps loongarch_pch_pic_reg32_high_ops = { - .read = loongarch_pch_pic_high_readw, - .write = loongarch_pch_pic_high_writew, - .valid = { - .min_access_size = 4, - .max_access_size = 8, - }, - .impl = { - .min_access_size = 4, - .max_access_size = 4, - }, - .endianness = DEVICE_LITTLE_ENDIAN, -}; - -static const MemoryRegionOps loongarch_pch_pic_reg8_ops = { - .read = loongarch_pch_pic_readb, - .write = loongarch_pch_pic_writeb, +static const MemoryRegionOps loongarch_pch_pic_ops = { + .read = loongarch_pch_pic_read, + .write = loongarch_pch_pic_write, .valid = { .min_access_size = 1, - .max_access_size = 1, + .max_access_size = 8, + /* + * PCH PIC device would not work correctly if the guest was doing + * unaligned access. This might not be a limitation on the real + * device but in practice there is no reason for a guest to access + * this device unaligned. + */ + .unaligned = false, }, .impl = { .min_access_size = 1, - .max_access_size = 1, + .max_access_size = 8, }, .endianness = DEVICE_LITTLE_ENDIAN, }; -static void loongarch_pch_pic_reset(DeviceState *d) +static void loongarch_pic_reset_hold(Object *obj, ResetType type) { - LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(d); - int i; - - s->int_mask = -1; - s->htmsi_en = 0x0; - s->intedge = 0x0; - s->intclr = 0x0; - s->auto_crtl0 = 0x0; - s->auto_crtl1 = 0x0; - for (i = 0; i < 64; i++) { - s->route_entry[i] = 0x1; - s->htmsi_vector[i] = 0x0; + LoongarchPICClass *lpc = LOONGARCH_PIC_GET_CLASS(obj); + + if (lpc->parent_phases.hold) { + lpc->parent_phases.hold(obj, type); + } + + if (kvm_irqchip_in_kernel()) { + kvm_pic_put(obj, 0); } - s->intirr = 0x0; - s->intisr = 0x0; - s->last_intirr = 0x0; - s->int_polarity = 0x0; } static void loongarch_pic_realize(DeviceState *dev, Error **errp) @@ -390,28 +285,49 @@ static void loongarch_pic_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, s->parent_irq, s->irq_num); qdev_init_gpio_in(dev, pch_pic_irq_handler, s->irq_num); - memory_region_init_io(&s->iomem32_low, OBJECT(dev), - &loongarch_pch_pic_reg32_low_ops, - s, PCH_PIC_NAME(.reg32_part1), 0x100); - memory_region_init_io(&s->iomem8, OBJECT(dev), &loongarch_pch_pic_reg8_ops, - s, PCH_PIC_NAME(.reg8), 0x2a0); - memory_region_init_io(&s->iomem32_high, OBJECT(dev), - &loongarch_pch_pic_reg32_high_ops, - s, PCH_PIC_NAME(.reg32_part2), 0xc60); - sysbus_init_mmio(sbd, &s->iomem32_low); - sysbus_init_mmio(sbd, &s->iomem8); - sysbus_init_mmio(sbd, &s->iomem32_high); + if (kvm_irqchip_in_kernel()) { + kvm_pic_realize(dev, errp); + } else { + memory_region_init_io(&s->iomem, OBJECT(dev), + &loongarch_pch_pic_ops, + s, TYPE_LOONGARCH_PIC, VIRT_PCH_REG_SIZE); + sysbus_init_mmio(sbd, &s->iomem); + } +} + +static int loongarch_pic_pre_save(LoongArchPICCommonState *opaque) +{ + if (kvm_irqchip_in_kernel()) { + return kvm_pic_get(opaque); + } + + return 0; +} + +static int loongarch_pic_post_load(LoongArchPICCommonState *opaque, + int version_id) +{ + if (kvm_irqchip_in_kernel()) { + return kvm_pic_put(opaque, version_id); + } + + return 0; } -static void loongarch_pic_class_init(ObjectClass *klass, void *data) +static void loongarch_pic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongarchPICClass *lpc = LOONGARCH_PIC_CLASS(klass); + LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); - device_class_set_legacy_reset(dc, loongarch_pch_pic_reset); + resettable_class_set_parent_phases(rc, NULL, loongarch_pic_reset_hold, + NULL, &lpc->parent_phases); device_class_set_parent_realize(dc, loongarch_pic_realize, &lpc->parent_realize); + lpcc->pre_save = loongarch_pic_pre_save; + lpcc->post_load = loongarch_pic_post_load; } static const TypeInfo loongarch_pic_types[] = { diff --git a/hw/intc/loongarch_pic_common.c b/hw/intc/loongarch_pic_common.c index e7f541d..de17050 100644 --- a/hw/intc/loongarch_pic_common.c +++ b/hw/intc/loongarch_pic_common.c @@ -44,6 +44,40 @@ static void loongarch_pic_common_realize(DeviceState *dev, Error **errp) } } +static void loongarch_pic_common_reset_hold(Object *obj, ResetType type) +{ + LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(obj); + int i; + + /* + * With Loongson 7A1000 user manual + * Chapter 5.2 "Description of Interrupt-related Registers" + * + * Interrupt controller identification register 1 + * Bit 24-31 Interrupt Controller ID + * Interrupt controller identification register 2 + * Bit 0-7 Interrupt Controller version number + * Bit 16-23 The number of interrupt sources supported + */ + s->id.desc.id = PCH_PIC_INT_ID_VAL; + s->id.desc.version = PCH_PIC_INT_ID_VER; + s->id.desc.irq_num = s->irq_num - 1; + s->int_mask = UINT64_MAX; + s->htmsi_en = 0x0; + s->intedge = 0x0; + s->intclr = 0x0; + s->auto_crtl0 = 0x0; + s->auto_crtl1 = 0x0; + for (i = 0; i < 64; i++) { + s->route_entry[i] = 0x1; + s->htmsi_vector[i] = 0x0; + } + s->intirr = 0x0; + s->intisr = 0x0; + s->last_intirr = 0x0; + s->int_polarity = 0x0; +} + static const Property loongarch_pic_common_properties[] = { DEFINE_PROP_UINT32("pch_pic_irq_num", LoongArchPICCommonState, irq_num, 0), }; @@ -71,13 +105,18 @@ static const VMStateDescription vmstate_loongarch_pic_common = { } }; -static void loongarch_pic_common_class_init(ObjectClass *klass, void *data) +static void loongarch_pic_common_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongArchPICCommonClass *lpcc = LOONGARCH_PIC_COMMON_CLASS(klass); + ResettableClass *rc = RESETTABLE_CLASS(klass); device_class_set_parent_realize(dc, loongarch_pic_common_realize, &lpcc->parent_realize); + resettable_class_set_parent_phases(rc, NULL, + loongarch_pic_common_reset_hold, + NULL, &lpcc->parent_phases); device_class_set_props(dc, loongarch_pic_common_properties); dc->vmsd = &vmstate_loongarch_pic_common; } diff --git a/hw/intc/loongarch_pic_kvm.c b/hw/intc/loongarch_pic_kvm.c new file mode 100644 index 0000000..dd504ec --- /dev/null +++ b/hw/intc/loongarch_pic_kvm.c @@ -0,0 +1,89 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * LoongArch kvm pch pic interrupt support + * + * Copyright (C) 2025 Loongson Technology Corporation Limited + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "hw/boards.h" +#include "hw/intc/loongarch_pch_pic.h" +#include "hw/loongarch/virt.h" +#include "hw/pci-host/ls7a.h" +#include "system/kvm.h" + +static void kvm_pch_pic_access_reg(int fd, uint64_t addr, void *val, bool write) +{ + kvm_device_access(fd, KVM_DEV_LOONGARCH_PCH_PIC_GRP_REGS, + addr, val, write, &error_abort); +} + +static void kvm_pch_pic_access(void *opaque, bool write) +{ + LoongArchPICCommonState *s = LOONGARCH_PIC_COMMON(opaque); + LoongarchPICState *lps = LOONGARCH_PIC(opaque); + int fd = lps->dev_fd; + int addr, offset; + + if (fd == 0) { + return; + } + + kvm_pch_pic_access_reg(fd, PCH_PIC_INT_MASK, &s->int_mask, write); + kvm_pch_pic_access_reg(fd, PCH_PIC_HTMSI_EN, &s->htmsi_en, write); + kvm_pch_pic_access_reg(fd, PCH_PIC_INT_EDGE, &s->intedge, write); + kvm_pch_pic_access_reg(fd, PCH_PIC_AUTO_CTRL0, &s->auto_crtl0, write); + kvm_pch_pic_access_reg(fd, PCH_PIC_AUTO_CTRL1, &s->auto_crtl1, write); + + for (addr = PCH_PIC_ROUTE_ENTRY; + addr < PCH_PIC_ROUTE_ENTRY_END; addr++) { + offset = addr - PCH_PIC_ROUTE_ENTRY; + kvm_pch_pic_access_reg(fd, addr, &s->route_entry[offset], write); + } + + for (addr = PCH_PIC_HTMSI_VEC; addr < PCH_PIC_HTMSI_VEC_END; addr++) { + offset = addr - PCH_PIC_HTMSI_VEC; + kvm_pch_pic_access_reg(fd, addr, &s->htmsi_vector[offset], write); + } + + kvm_pch_pic_access_reg(fd, PCH_PIC_INT_REQUEST, &s->intirr, write); + kvm_pch_pic_access_reg(fd, PCH_PIC_INT_STATUS, &s->intisr, write); + kvm_pch_pic_access_reg(fd, PCH_PIC_INT_POL, &s->int_polarity, write); +} + +int kvm_pic_get(void *opaque) +{ + kvm_pch_pic_access(opaque, false); + return 0; +} + +int kvm_pic_put(void *opaque, int version_id) +{ + kvm_pch_pic_access(opaque, true); + return 0; +} + +void kvm_pic_realize(DeviceState *dev, Error **errp) +{ + LoongarchPICState *lps = LOONGARCH_PIC(dev); + uint64_t pch_pic_base = VIRT_PCH_REG_BASE; + int ret; + + ret = kvm_create_device(kvm_state, KVM_DEV_TYPE_LOONGARCH_PCHPIC, false); + if (ret < 0) { + fprintf(stderr, "Create KVM_LOONGARCH_PCHPIC failed: %s\n", + strerror(-ret)); + abort(); + } + + lps->dev_fd = ret; + ret = kvm_device_access(lps->dev_fd, KVM_DEV_LOONGARCH_PCH_PIC_GRP_CTRL, + KVM_DEV_LOONGARCH_PCH_PIC_CTRL_INIT, + &pch_pic_base, true, NULL); + if (ret < 0) { + fprintf(stderr, "KVM_LOONGARCH_PCH_PIC_INIT failed: %s\n", + strerror(-ret)); + abort(); + } +} diff --git a/hw/intc/loongson_ipi.c b/hw/intc/loongson_ipi.c index d2268a2..fbc73e8 100644 --- a/hw/intc/loongson_ipi.c +++ b/hw/intc/loongson_ipi.c @@ -101,7 +101,7 @@ static const Property loongson_ipi_properties[] = { DEFINE_PROP_UINT32("num-cpu", LoongsonIPICommonState, num_cpu, 1), }; -static void loongson_ipi_class_init(ObjectClass *klass, void *data) +static void loongson_ipi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongsonIPIClass *lic = LOONGSON_IPI_CLASS(klass); diff --git a/hw/intc/loongson_ipi_common.c b/hw/intc/loongson_ipi_common.c index f5ab502..8cd78d4 100644 --- a/hw/intc/loongson_ipi_common.c +++ b/hw/intc/loongson_ipi_common.c @@ -11,6 +11,7 @@ #include "hw/irq.h" #include "qemu/log.h" #include "migration/vmstate.h" +#include "system/kvm.h" #include "trace.h" MemTxResult loongson_ipi_core_readl(void *opaque, hwaddr addr, uint64_t *data, @@ -255,6 +256,10 @@ static void loongson_ipi_common_realize(DeviceState *dev, Error **errp) LoongsonIPICommonState *s = LOONGSON_IPI_COMMON(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + if (kvm_irqchip_in_kernel()) { + return; + } + memory_region_init_io(&s->ipi_iocsr_mem, OBJECT(dev), &loongson_ipi_iocsr_ops, s, "loongson_ipi_iocsr", 0x48); @@ -277,10 +282,38 @@ static void loongson_ipi_common_unrealize(DeviceState *dev) g_free(s->cpu); } +static int loongson_ipi_common_pre_save(void *opaque) +{ + IPICore *ipicore = (IPICore *)opaque; + LoongsonIPICommonState *s = ipicore->ipi; + LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_GET_CLASS(s); + + if (licc->pre_save) { + return licc->pre_save(s); + } + + return 0; +} + +static int loongson_ipi_common_post_load(void *opaque, int version_id) +{ + IPICore *ipicore = (IPICore *)opaque; + LoongsonIPICommonState *s = ipicore->ipi; + LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_GET_CLASS(s); + + if (licc->post_load) { + return licc->post_load(s, version_id); + } + + return 0; +} + static const VMStateDescription vmstate_ipi_core = { .name = "ipi-single", .version_id = 2, .minimum_version_id = 2, + .pre_save = loongson_ipi_common_pre_save, + .post_load = loongson_ipi_common_post_load, .fields = (const VMStateField[]) { VMSTATE_UINT32(status, IPICore), VMSTATE_UINT32(en, IPICore), @@ -303,7 +336,7 @@ static const VMStateDescription vmstate_loongson_ipi_common = { } }; -static void loongson_ipi_common_class_init(ObjectClass *klass, void *data) +static void loongson_ipi_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); LoongsonIPICommonClass *licc = LOONGSON_IPI_COMMON_CLASS(klass); diff --git a/hw/intc/m68k_irqc.c b/hw/intc/m68k_irqc.c index a82b80f..2532322 100644 --- a/hw/intc/m68k_irqc.c +++ b/hw/intc/m68k_irqc.c @@ -90,7 +90,7 @@ static const Property m68k_irqc_properties[] = { TYPE_M68K_CPU, ArchCPU *), }; -static void m68k_irqc_class_init(ObjectClass *oc, void *data) +static void m68k_irqc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); @@ -110,7 +110,7 @@ static const TypeInfo m68k_irqc_type_info = { .instance_size = sizeof(M68KIRQCState), .instance_init = m68k_irqc_instance_init, .class_init = m68k_irqc_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { TYPE_INTERRUPT_STATS_PROVIDER }, { } diff --git a/hw/intc/meson.build b/hw/intc/meson.build index 602da30..3137521 100644 --- a/hw/intc/meson.build +++ b/hw/intc/meson.build @@ -71,6 +71,12 @@ specific_ss.add(when: 'CONFIG_M68K_IRQC', if_true: files('m68k_irqc.c')) specific_ss.add(when: 'CONFIG_LOONGSON_IPI_COMMON', if_true: files('loongson_ipi_common.c')) specific_ss.add(when: 'CONFIG_LOONGSON_IPI', if_true: files('loongson_ipi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_IPI', if_true: files('loongarch_ipi.c')) +specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_LOONGARCH_IPI'], + if_true: files('loongarch_ipi_kvm.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_PIC', if_true: files('loongarch_pch_pic.c', 'loongarch_pic_common.c')) +specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_LOONGARCH_PCH_PIC'], + if_true: files('loongarch_pic_kvm.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_PCH_MSI', if_true: files('loongarch_pch_msi.c')) specific_ss.add(when: 'CONFIG_LOONGARCH_EXTIOI', if_true: files('loongarch_extioi.c', 'loongarch_extioi_common.c')) +specific_ss.add(when: ['CONFIG_KVM', 'CONFIG_LOONGARCH_EXTIOI'], + if_true: files('loongarch_extioi_kvm.c')) diff --git a/hw/intc/mips_gic.c b/hw/intc/mips_gic.c index bd1dedd..0c50ba4 100644 --- a/hw/intc/mips_gic.c +++ b/hw/intc/mips_gic.c @@ -14,7 +14,7 @@ #include "qemu/module.h" #include "qapi/error.h" #include "hw/sysbus.h" -#include "exec/memory.h" +#include "system/memory.h" #include "system/kvm.h" #include "system/reset.h" #include "kvm_mips.h" @@ -442,7 +442,7 @@ static const Property mips_gic_properties[] = { DEFINE_PROP_UINT32("num-irq", MIPSGICState, num_irq, 256), }; -static void mips_gic_class_init(ObjectClass *klass, void *data) +static void mips_gic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c index 095a3d5..c61158b 100644 --- a/hw/intc/omap_intc.c +++ b/hw/intc/omap_intc.c @@ -102,8 +102,8 @@ static inline void omap_inth_update(OMAPIntcState *s, int is_fiq) } } -#define INT_FALLING_EDGE 0 -#define INT_LOW_LEVEL 1 +#define INT_FALLING_EDGE 0 +#define INT_LOW_LEVEL 1 static void omap_set_intr(void *opaque, int irq, int req) { @@ -142,13 +142,13 @@ static uint64_t omap_inth_read(void *opaque, hwaddr addr, offset &= 0xff; switch (offset) { - case 0x00: /* ITR */ + case 0x00: /* ITR */ return bank->irqs; - case 0x04: /* MIR */ + case 0x04: /* MIR */ return bank->mask; - case 0x10: /* SIR_IRQ_CODE */ + case 0x10: /* SIR_IRQ_CODE */ case 0x14: /* SIR_FIQ_CODE */ if (bank_no != 0) break; @@ -159,49 +159,49 @@ static uint64_t omap_inth_read(void *opaque, hwaddr addr, bank->irqs &= ~(1 << i); return line_no; - case 0x18: /* CONTROL_REG */ + case 0x18: /* CONTROL_REG */ if (bank_no != 0) break; return 0; - case 0x1c: /* ILR0 */ - case 0x20: /* ILR1 */ - case 0x24: /* ILR2 */ - case 0x28: /* ILR3 */ - case 0x2c: /* ILR4 */ - case 0x30: /* ILR5 */ - case 0x34: /* ILR6 */ - case 0x38: /* ILR7 */ - case 0x3c: /* ILR8 */ - case 0x40: /* ILR9 */ - case 0x44: /* ILR10 */ - case 0x48: /* ILR11 */ - case 0x4c: /* ILR12 */ - case 0x50: /* ILR13 */ - case 0x54: /* ILR14 */ - case 0x58: /* ILR15 */ - case 0x5c: /* ILR16 */ - case 0x60: /* ILR17 */ - case 0x64: /* ILR18 */ - case 0x68: /* ILR19 */ - case 0x6c: /* ILR20 */ - case 0x70: /* ILR21 */ - case 0x74: /* ILR22 */ - case 0x78: /* ILR23 */ - case 0x7c: /* ILR24 */ - case 0x80: /* ILR25 */ - case 0x84: /* ILR26 */ - case 0x88: /* ILR27 */ - case 0x8c: /* ILR28 */ - case 0x90: /* ILR29 */ - case 0x94: /* ILR30 */ - case 0x98: /* ILR31 */ + case 0x1c: /* ILR0 */ + case 0x20: /* ILR1 */ + case 0x24: /* ILR2 */ + case 0x28: /* ILR3 */ + case 0x2c: /* ILR4 */ + case 0x30: /* ILR5 */ + case 0x34: /* ILR6 */ + case 0x38: /* ILR7 */ + case 0x3c: /* ILR8 */ + case 0x40: /* ILR9 */ + case 0x44: /* ILR10 */ + case 0x48: /* ILR11 */ + case 0x4c: /* ILR12 */ + case 0x50: /* ILR13 */ + case 0x54: /* ILR14 */ + case 0x58: /* ILR15 */ + case 0x5c: /* ILR16 */ + case 0x60: /* ILR17 */ + case 0x64: /* ILR18 */ + case 0x68: /* ILR19 */ + case 0x6c: /* ILR20 */ + case 0x70: /* ILR21 */ + case 0x74: /* ILR22 */ + case 0x78: /* ILR23 */ + case 0x7c: /* ILR24 */ + case 0x80: /* ILR25 */ + case 0x84: /* ILR26 */ + case 0x88: /* ILR27 */ + case 0x8c: /* ILR28 */ + case 0x90: /* ILR29 */ + case 0x94: /* ILR30 */ + case 0x98: /* ILR31 */ i = (offset - 0x1c) >> 2; return (bank->priority[i] << 2) | (((bank->sens_edge >> i) & 1) << 1) | ((bank->fiq >> i) & 1); - case 0x9c: /* ISR */ + case 0x9c: /* ISR */ return 0x00000000; } @@ -219,24 +219,24 @@ static void omap_inth_write(void *opaque, hwaddr addr, offset &= 0xff; switch (offset) { - case 0x00: /* ITR */ + case 0x00: /* ITR */ /* Important: ignore the clearing if the IRQ is level-triggered and the input bit is 1 */ bank->irqs &= value | (bank->inputs & bank->sens_edge); return; - case 0x04: /* MIR */ + case 0x04: /* MIR */ bank->mask = value; omap_inth_update(s, 0); omap_inth_update(s, 1); return; - case 0x10: /* SIR_IRQ_CODE */ - case 0x14: /* SIR_FIQ_CODE */ + case 0x10: /* SIR_IRQ_CODE */ + case 0x14: /* SIR_FIQ_CODE */ OMAP_RO_REG(addr); break; - case 0x18: /* CONTROL_REG */ + case 0x18: /* CONTROL_REG */ if (bank_no != 0) break; if (value & 2) { @@ -251,38 +251,38 @@ static void omap_inth_write(void *opaque, hwaddr addr, } return; - case 0x1c: /* ILR0 */ - case 0x20: /* ILR1 */ - case 0x24: /* ILR2 */ - case 0x28: /* ILR3 */ - case 0x2c: /* ILR4 */ - case 0x30: /* ILR5 */ - case 0x34: /* ILR6 */ - case 0x38: /* ILR7 */ - case 0x3c: /* ILR8 */ - case 0x40: /* ILR9 */ - case 0x44: /* ILR10 */ - case 0x48: /* ILR11 */ - case 0x4c: /* ILR12 */ - case 0x50: /* ILR13 */ - case 0x54: /* ILR14 */ - case 0x58: /* ILR15 */ - case 0x5c: /* ILR16 */ - case 0x60: /* ILR17 */ - case 0x64: /* ILR18 */ - case 0x68: /* ILR19 */ - case 0x6c: /* ILR20 */ - case 0x70: /* ILR21 */ - case 0x74: /* ILR22 */ - case 0x78: /* ILR23 */ - case 0x7c: /* ILR24 */ - case 0x80: /* ILR25 */ - case 0x84: /* ILR26 */ - case 0x88: /* ILR27 */ - case 0x8c: /* ILR28 */ - case 0x90: /* ILR29 */ - case 0x94: /* ILR30 */ - case 0x98: /* ILR31 */ + case 0x1c: /* ILR0 */ + case 0x20: /* ILR1 */ + case 0x24: /* ILR2 */ + case 0x28: /* ILR3 */ + case 0x2c: /* ILR4 */ + case 0x30: /* ILR5 */ + case 0x34: /* ILR6 */ + case 0x38: /* ILR7 */ + case 0x3c: /* ILR8 */ + case 0x40: /* ILR9 */ + case 0x44: /* ILR10 */ + case 0x48: /* ILR11 */ + case 0x4c: /* ILR12 */ + case 0x50: /* ILR13 */ + case 0x54: /* ILR14 */ + case 0x58: /* ILR15 */ + case 0x5c: /* ILR16 */ + case 0x60: /* ILR17 */ + case 0x64: /* ILR18 */ + case 0x68: /* ILR19 */ + case 0x6c: /* ILR20 */ + case 0x70: /* ILR21 */ + case 0x74: /* ILR22 */ + case 0x78: /* ILR23 */ + case 0x7c: /* ILR24 */ + case 0x80: /* ILR25 */ + case 0x84: /* ILR26 */ + case 0x88: /* ILR27 */ + case 0x8c: /* ILR28 */ + case 0x90: /* ILR29 */ + case 0x94: /* ILR30 */ + case 0x98: /* ILR31 */ i = (offset - 0x1c) >> 2; bank->priority[i] = (value >> 2) & 0x1f; bank->sens_edge &= ~(1 << i); @@ -291,7 +291,7 @@ static void omap_inth_write(void *opaque, hwaddr addr, bank->fiq |= (value & 1) << i; return; - case 0x9c: /* ISR */ + case 0x9c: /* ISR */ for (i = 0; i < 32; i ++) if (value & (1 << i)) { omap_set_intr(s, 32 * bank_no + i, 1); @@ -379,7 +379,7 @@ static const Property omap_intc_properties[] = { DEFINE_PROP_UINT32("size", OMAPIntcState, size, 0x100), }; -static void omap_intc_class_init(ObjectClass *klass, void *data) +static void omap_intc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/ompic.c b/hw/intc/ompic.c index 42af456..047c367 100644 --- a/hw/intc/ompic.c +++ b/hw/intc/ompic.c @@ -13,7 +13,7 @@ #include "hw/qdev-properties.h" #include "hw/sysbus.h" #include "migration/vmstate.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qom/object.h" #define TYPE_OR1K_OMPIC "or1k-ompic" @@ -155,7 +155,7 @@ static const VMStateDescription vmstate_or1k_ompic = { } }; -static void or1k_ompic_class_init(ObjectClass *klass, void *data) +static void or1k_ompic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c index 78a82d0..87733eb 100644 --- a/hw/intc/openpic.c +++ b/hw/intc/openpic.c @@ -1611,7 +1611,7 @@ static const Property openpic_properties[] = { DEFINE_PROP_UINT32("nb_cpus", OpenPICState, nb_cpus, 1), }; -static void openpic_class_init(ObjectClass *oc, void *data) +static void openpic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c index 9cdaa97..673ea9c 100644 --- a/hw/intc/openpic_kvm.c +++ b/hw/intc/openpic_kvm.c @@ -267,7 +267,7 @@ static const Property kvm_openpic_properties[] = { OPENPIC_MODEL_FSL_MPIC_20), }; -static void kvm_openpic_class_init(ObjectClass *oc, void *data) +static void kvm_openpic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c index a5e2d76..838c21c 100644 --- a/hw/intc/pl190.c +++ b/hw/intc/pl190.c @@ -273,7 +273,7 @@ static const VMStateDescription vmstate_pl190 = { } }; -static void pl190_class_init(ObjectClass *klass, void *data) +static void pl190_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/pnv_xive.c b/hw/intc/pnv_xive.c index ccbe95a..935c0e4 100644 --- a/hw/intc/pnv_xive.c +++ b/hw/intc/pnv_xive.c @@ -2068,7 +2068,7 @@ static const Property pnv_xive_properties[] = { DEFINE_PROP_LINK("chip", PnvXive, chip, TYPE_PNV_CHIP, PnvChip *), }; -static void pnv_xive_class_init(ObjectClass *klass, void *data) +static void pnv_xive_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -2106,7 +2106,7 @@ static const TypeInfo pnv_xive_info = { .instance_size = sizeof(PnvXive), .class_init = pnv_xive_class_init, .class_size = sizeof(PnvXiveClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/intc/pnv_xive2.c b/hw/intc/pnv_xive2.c index 0b81dad..ec8b0c6 100644 --- a/hw/intc/pnv_xive2.c +++ b/hw/intc/pnv_xive2.c @@ -2505,7 +2505,7 @@ static int pnv_xive2_dt_xscom(PnvXScomInterface *dev, void *fdt, return 0; } -static void pnv_xive2_class_init(ObjectClass *klass, void *data) +static void pnv_xive2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -2547,7 +2547,7 @@ static const TypeInfo pnv_xive2_info = { .instance_size = sizeof(PnvXive2), .class_init = pnv_xive2_class_init, .class_size = sizeof(PnvXive2Class), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/intc/ppc-uic.c b/hw/intc/ppc-uic.c index 7de4bf9..bc4dc90 100644 --- a/hw/intc/ppc-uic.c +++ b/hw/intc/ppc-uic.c @@ -281,7 +281,7 @@ static const VMStateDescription ppc_uic_vmstate = { }, }; -static void ppc_uic_class_init(ObjectClass *klass, void *data) +static void ppc_uic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/realview_gic.c b/hw/intc/realview_gic.c index 9b12116..63e25c2 100644 --- a/hw/intc/realview_gic.c +++ b/hw/intc/realview_gic.c @@ -63,7 +63,7 @@ static void realview_gic_init(Object *obj) qdev_prop_set_uint32(DEVICE(&s->gic), "num-cpu", 1); } -static void realview_gic_class_init(ObjectClass *oc, void *data) +static void realview_gic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c index db374a7..b0139f0 100644 --- a/hw/intc/riscv_aclint.c +++ b/hw/intc/riscv_aclint.c @@ -328,7 +328,7 @@ static const VMStateDescription vmstate_riscv_mtimer = { } }; -static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) +static void riscv_aclint_mtimer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = riscv_aclint_mtimer_realize; @@ -509,7 +509,7 @@ static void riscv_aclint_swi_reset_enter(Object *obj, ResetType type) } } -static void riscv_aclint_swi_class_init(ObjectClass *klass, void *data) +static void riscv_aclint_swi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = riscv_aclint_swi_realize; diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c index 5964cde..8bcd9f4 100644 --- a/hw/intc/riscv_aplic.c +++ b/hw/intc/riscv_aplic.c @@ -22,7 +22,7 @@ #include "qemu/module.h" #include "qemu/error-report.h" #include "qemu/bswap.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/sysbus.h" #include "hw/pci/msi.h" #include "hw/boards.h" @@ -997,7 +997,7 @@ static const VMStateDescription vmstate_riscv_aplic = { } }; -static void riscv_aplic_class_init(ObjectClass *klass, void *data) +static void riscv_aplic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c index 241b12f..2169988 100644 --- a/hw/intc/riscv_imsic.c +++ b/hw/intc/riscv_imsic.c @@ -22,7 +22,7 @@ #include "qemu/module.h" #include "qemu/error-report.h" #include "qemu/bswap.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/sysbus.h" #include "hw/pci/msi.h" #include "hw/boards.h" @@ -416,7 +416,7 @@ static const VMStateDescription vmstate_riscv_imsic = { } }; -static void riscv_imsic_class_init(ObjectClass *klass, void *data) +static void riscv_imsic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/rx_icu.c b/hw/intc/rx_icu.c index ca13c5f..f861552 100644 --- a/hw/intc/rx_icu.c +++ b/hw/intc/rx_icu.c @@ -368,7 +368,7 @@ static const Property rxicu_properties[] = { qdev_prop_uint8, uint8_t), }; -static void rxicu_class_init(ObjectClass *klass, void *data) +static void rxicu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c index 4fae023..8f4c9fd 100644 --- a/hw/intc/s390_flic.c +++ b/hw/intc/s390_flic.c @@ -450,7 +450,7 @@ static const Property qemu_s390_flic_properties[] = { migrate_all_state, true), }; -static void qemu_s390_flic_class_init(ObjectClass *oc, void *data) +static void qemu_s390_flic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc); @@ -477,7 +477,7 @@ static void s390_flic_common_realize(DeviceState *dev, Error **errp) fs->ais_supported = s390_has_feat(S390_FEAT_ADAPTER_INT_SUPPRESSION); } -static void s390_flic_class_init(ObjectClass *oc, void *data) +static void s390_flic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c index 10aaafb..f833a39 100644 --- a/hw/intc/s390_flic_kvm.c +++ b/hw/intc/s390_flic_kvm.c @@ -670,7 +670,7 @@ static void kvm_s390_flic_reset(DeviceState *dev) flic_enable_pfault(flic); } -static void kvm_s390_flic_class_init(ObjectClass *oc, void *data) +static void kvm_s390_flic_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc); diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c index a5b0f6e..3160b21 100644 --- a/hw/intc/sifive_plic.c +++ b/hw/intc/sifive_plic.c @@ -446,7 +446,7 @@ static const Property sifive_plic_properties[] = { DEFINE_PROP_UINT32("aperture-size", SiFivePLICState, aperture_size, 0), }; -static void sifive_plic_class_init(ObjectClass *klass, void *data) +static void sifive_plic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/slavio_intctl.c b/hw/intc/slavio_intctl.c index f83709a..00b80bb 100644 --- a/hw/intc/slavio_intctl.c +++ b/hw/intc/slavio_intctl.c @@ -441,7 +441,7 @@ static void slavio_intctl_init(Object *obj) } } -static void slavio_intctl_class_init(ObjectClass *klass, void *data) +static void slavio_intctl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); InterruptStatsProviderClass *ic = INTERRUPT_STATS_PROVIDER_CLASS(klass); @@ -460,7 +460,7 @@ static const TypeInfo slavio_intctl_info = { .instance_size = sizeof(SLAVIO_INTCTLState), .instance_init = slavio_intctl_init, .class_init = slavio_intctl_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_INTERRUPT_STATS_PROVIDER }, { } }, diff --git a/hw/intc/spapr_xive.c b/hw/intc/spapr_xive.c index ce734b0..440edb9 100644 --- a/hw/intc/spapr_xive.c +++ b/hw/intc/spapr_xive.c @@ -809,7 +809,7 @@ static bool spapr_xive_in_kernel_xptr(const XivePresenter *xptr) return spapr_xive_in_kernel(SPAPR_XIVE(xptr)); } -static void spapr_xive_class_init(ObjectClass *klass, void *data) +static void spapr_xive_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XiveRouterClass *xrc = XIVE_ROUTER_CLASS(klass); @@ -856,7 +856,7 @@ static const TypeInfo spapr_xive_info = { .instance_size = sizeof(SpaprXive), .class_init = spapr_xive_class_init, .class_size = sizeof(SpaprXiveClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_SPAPR_INTC }, { } }, diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 0ba9a02..334aa6a 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -314,12 +314,8 @@ loongson_ipi_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x loongson_ipi_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%"PRIx64 # loongarch_pch_pic.c loongarch_pch_pic_irq_handler(int irq, int level) "irq %d level %d" -loongarch_pch_pic_low_readw(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 -loongarch_pch_pic_low_writew(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 -loongarch_pch_pic_high_readw(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 -loongarch_pch_pic_high_writew(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 -loongarch_pch_pic_readb(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 -loongarch_pch_pic_writeb(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 +loongarch_pch_pic_read(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 +loongarch_pch_pic_write(unsigned size, uint64_t addr, uint64_t val) "size: %u addr: 0x%"PRIx64 "val: 0x%" PRIx64 # loongarch_pch_msi.c loongarch_msi_set_irq(int irq_num) "set msi irq %d" diff --git a/hw/intc/xics.c b/hw/intc/xics.c index 9c1b7bb..d9a199e 100644 --- a/hw/intc/xics.c +++ b/hw/intc/xics.c @@ -350,7 +350,7 @@ static const Property icp_properties[] = { DEFINE_PROP_LINK(ICP_PROP_CPU, ICPState, cs, TYPE_CPU, CPUState *), }; -static void icp_class_init(ObjectClass *klass, void *data) +static void icp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -681,7 +681,7 @@ static const Property ics_properties[] = { XICSFabric *), }; -static void ics_class_init(ObjectClass *klass, void *data) +static void ics_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/intc/xics_pnv.c b/hw/intc/xics_pnv.c index 753c067..ff602d9 100644 --- a/hw/intc/xics_pnv.c +++ b/hw/intc/xics_pnv.c @@ -176,7 +176,7 @@ static void pnv_icp_realize(DeviceState *dev, Error **errp) icp, "icp-thread", 0x1000); } -static void pnv_icp_class_init(ObjectClass *klass, void *data) +static void pnv_icp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ICPStateClass *icpc = ICP_CLASS(klass); diff --git a/hw/intc/xics_spapr.c b/hw/intc/xics_spapr.c index a0d97bd..7663596 100644 --- a/hw/intc/xics_spapr.c +++ b/hw/intc/xics_spapr.c @@ -436,7 +436,7 @@ static void xics_spapr_deactivate(SpaprInterruptController *intc) } } -static void ics_spapr_class_init(ObjectClass *klass, void *data) +static void ics_spapr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ICSStateClass *isc = ICS_CLASS(klass); @@ -461,7 +461,7 @@ static const TypeInfo ics_spapr_info = { .name = TYPE_ICS_SPAPR, .parent = TYPE_ICS, .class_init = ics_spapr_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_SPAPR_INTC }, { } }, diff --git a/hw/intc/xilinx_intc.c b/hw/intc/xilinx_intc.c index ab1c4a3..5257ad5 100644 --- a/hw/intc/xilinx_intc.c +++ b/hw/intc/xilinx_intc.c @@ -214,7 +214,7 @@ static const Property xilinx_intc_properties[] = { DEFINE_PROP_UINT32("kind-of-intr", XpsIntc, c_kind_of_intr, 0), }; -static void xilinx_intc_class_init(ObjectClass *klass, void *data) +static void xilinx_intc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/xive.c b/hw/intc/xive.c index 3eb28c2..27b473e 100644 --- a/hw/intc/xive.c +++ b/hw/intc/xive.c @@ -930,7 +930,7 @@ static const Property xive_tctx_properties[] = { XivePresenter *), }; -static void xive_tctx_class_init(ObjectClass *klass, void *data) +static void xive_tctx_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1412,7 +1412,7 @@ static const Property xive_source_properties[] = { XiveNotifier *), }; -static void xive_source_class_init(ObjectClass *klass, void *data) +static void xive_source_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2085,7 +2085,7 @@ static const Property xive_router_properties[] = { TYPE_XIVE_FABRIC, XiveFabric *), }; -static void xive_router_class_init(ObjectClass *klass, void *data) +static void xive_router_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XiveNotifierClass *xnc = XIVE_NOTIFIER_CLASS(klass); @@ -2108,7 +2108,7 @@ static const TypeInfo xive_router_info = { .instance_size = sizeof(XiveRouter), .class_size = sizeof(XiveRouterClass), .class_init = xive_router_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XIVE_NOTIFIER }, { TYPE_XIVE_PRESENTER }, { } @@ -2254,7 +2254,7 @@ static const Property xive_end_source_properties[] = { XiveRouter *), }; -static void xive_end_source_class_init(ObjectClass *klass, void *data) +static void xive_end_source_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/xive2.c b/hw/intc/xive2.c index 7d584df..a08cf90 100644 --- a/hw/intc/xive2.c +++ b/hw/intc/xive2.c @@ -1590,7 +1590,7 @@ static const Property xive2_router_properties[] = { TYPE_XIVE_FABRIC, XiveFabric *), }; -static void xive2_router_class_init(ObjectClass *klass, void *data) +static void xive2_router_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XiveNotifierClass *xnc = XIVE_NOTIFIER_CLASS(klass); @@ -1609,7 +1609,7 @@ static const TypeInfo xive2_router_info = { .instance_size = sizeof(Xive2Router), .class_size = sizeof(Xive2RouterClass), .class_init = xive2_router_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XIVE_NOTIFIER }, { TYPE_XIVE_PRESENTER }, { } @@ -1805,7 +1805,7 @@ static const Property xive2_end_source_properties[] = { Xive2Router *), }; -static void xive2_end_source_class_init(ObjectClass *klass, void *data) +static void xive2_end_source_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/xlnx-pmu-iomod-intc.c b/hw/intc/xlnx-pmu-iomod-intc.c index ccdab24..9200585 100644 --- a/hw/intc/xlnx-pmu-iomod-intc.c +++ b/hw/intc/xlnx-pmu-iomod-intc.c @@ -531,7 +531,7 @@ static const VMStateDescription vmstate_xlnx_pmu_io_intc = { } }; -static void xlnx_pmu_io_intc_class_init(ObjectClass *klass, void *data) +static void xlnx_pmu_io_intc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/intc/xlnx-zynqmp-ipi.c b/hw/intc/xlnx-zynqmp-ipi.c index 7241377..610cd0e 100644 --- a/hw/intc/xlnx-zynqmp-ipi.c +++ b/hw/intc/xlnx-zynqmp-ipi.c @@ -355,7 +355,7 @@ static const VMStateDescription vmstate_zynqmp_pmu_ipi = { } }; -static void xlnx_zynqmp_ipi_class_init(ObjectClass *klass, void *data) +static void xlnx_zynqmp_ipi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c index b6defae..ab602bf 100644 --- a/hw/ipack/ipack.c +++ b/hw/ipack/ipack.c @@ -74,7 +74,7 @@ static const Property ipack_device_props[] = { DEFINE_PROP_INT32("slot", IPackDevice, slot, -1), }; -static void ipack_device_class_init(ObjectClass *klass, void *data) +static void ipack_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c index 470a4203..40b3051 100644 --- a/hw/ipack/tpci200.c +++ b/hw/ipack/tpci200.c @@ -629,7 +629,7 @@ static const VMStateDescription vmstate_tpci200 = { } }; -static void tpci200_class_init(ObjectClass *klass, void *data) +static void tpci200_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -650,7 +650,7 @@ static const TypeInfo tpci200_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(TPCI200State), .class_init = tpci200_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c index fdeaa52..b91e487 100644 --- a/hw/ipmi/ipmi.c +++ b/hw/ipmi/ipmi.c @@ -78,7 +78,7 @@ static int ipmi_do_hw_op(IPMIInterface *s, enum ipmi_op op, int checkonly) } } -static void ipmi_interface_class_init(ObjectClass *class, void *data) +static void ipmi_interface_class_init(ObjectClass *class, const void *data) { IPMIInterfaceClass *ik = IPMI_INTERFACE_CLASS(class); @@ -112,7 +112,7 @@ static const Property ipmi_bmc_properties[] = { DEFINE_PROP_UINT8("slave_addr", IPMIBmc, slave_addr, 0x20), }; -static void bmc_class_init(ObjectClass *oc, void *data) +static void bmc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c index e563214..9f1ba7b 100644 --- a/hw/ipmi/ipmi_bmc_extern.c +++ b/hw/ipmi/ipmi_bmc_extern.c @@ -513,7 +513,7 @@ static const Property ipmi_bmc_extern_properties[] = { DEFINE_PROP_CHR("chardev", IPMIBmcExtern, chr), }; -static void ipmi_bmc_extern_class_init(ObjectClass *oc, void *data) +static void ipmi_bmc_extern_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); IPMIBmcClass *bk = IPMI_BMC_CLASS(oc); diff --git a/hw/ipmi/ipmi_bmc_sim.c b/hw/ipmi/ipmi_bmc_sim.c index 41fe683..04e1dcd 100644 --- a/hw/ipmi/ipmi_bmc_sim.c +++ b/hw/ipmi/ipmi_bmc_sim.c @@ -2278,7 +2278,7 @@ static const Property ipmi_sim_properties[] = { DEFINE_PROP_UUID_NODEFAULT("guid", IPMIBmcSim, uuid), }; -static void ipmi_sim_class_init(ObjectClass *oc, void *data) +static void ipmi_sim_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); IPMIBmcClass *bk = IPMI_BMC_CLASS(oc); diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c index 76585e7..0ad91cc 100644 --- a/hw/ipmi/isa_ipmi_bt.c +++ b/hw/ipmi/isa_ipmi_bt.c @@ -139,7 +139,7 @@ static const Property ipmi_isa_properties[] = { DEFINE_PROP_INT32("irq", ISAIPMIBTDevice, isairq, 5), }; -static void isa_ipmi_bt_class_init(ObjectClass *oc, void *data) +static void isa_ipmi_bt_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); @@ -161,7 +161,7 @@ static const TypeInfo isa_ipmi_bt_info = { .instance_size = sizeof(ISAIPMIBTDevice), .instance_init = isa_ipmi_bt_init, .class_init = isa_ipmi_bt_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IPMI_INTERFACE }, { TYPE_ACPI_DEV_AML_IF }, { } diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c index ba3ae20..418d234 100644 --- a/hw/ipmi/isa_ipmi_kcs.c +++ b/hw/ipmi/isa_ipmi_kcs.c @@ -145,7 +145,7 @@ static const Property ipmi_isa_properties[] = { DEFINE_PROP_INT32("irq", ISAIPMIKCSDevice, isairq, 5), }; -static void isa_ipmi_kcs_class_init(ObjectClass *oc, void *data) +static void isa_ipmi_kcs_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); @@ -167,7 +167,7 @@ static const TypeInfo isa_ipmi_kcs_info = { .instance_size = sizeof(ISAIPMIKCSDevice), .instance_init = isa_ipmi_kcs_init, .class_init = isa_ipmi_kcs_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IPMI_INTERFACE }, { TYPE_ACPI_DEV_AML_IF }, { } diff --git a/hw/ipmi/pci_ipmi_bt.c b/hw/ipmi/pci_ipmi_bt.c index 7ba8b3a..905101d 100644 --- a/hw/ipmi/pci_ipmi_bt.c +++ b/hw/ipmi/pci_ipmi_bt.c @@ -119,7 +119,7 @@ static void *pci_ipmi_bt_get_backend_data(IPMIInterface *ii) return &pib->bt; } -static void pci_ipmi_bt_class_init(ObjectClass *oc, void *data) +static void pci_ipmi_bt_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); @@ -145,7 +145,7 @@ static const TypeInfo pci_ipmi_bt_info = { .instance_size = sizeof(PCIIPMIBTDevice), .instance_init = pci_ipmi_bt_instance_init, .class_init = pci_ipmi_bt_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IPMI_INTERFACE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } diff --git a/hw/ipmi/pci_ipmi_kcs.c b/hw/ipmi/pci_ipmi_kcs.c index 0aa3514..4d6cde8 100644 --- a/hw/ipmi/pci_ipmi_kcs.c +++ b/hw/ipmi/pci_ipmi_kcs.c @@ -118,7 +118,7 @@ static void *pci_ipmi_kcs_get_backend_data(IPMIInterface *ii) return &pik->kcs; } -static void pci_ipmi_kcs_class_init(ObjectClass *oc, void *data) +static void pci_ipmi_kcs_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); @@ -144,7 +144,7 @@ static const TypeInfo pci_ipmi_kcs_info = { .instance_size = sizeof(PCIIPMIKCSDevice), .instance_init = pci_ipmi_kcs_instance_init, .class_init = pci_ipmi_kcs_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IPMI_INTERFACE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } diff --git a/hw/ipmi/smbus_ipmi.c b/hw/ipmi/smbus_ipmi.c index 56865df..78c332d 100644 --- a/hw/ipmi/smbus_ipmi.c +++ b/hw/ipmi/smbus_ipmi.c @@ -351,7 +351,7 @@ static void smbus_ipmi_get_fwinfo(struct IPMIInterface *ii, IPMIFwInfo *info) info->uuid = sid->uuid; } -static void smbus_ipmi_class_init(ObjectClass *oc, void *data) +static void smbus_ipmi_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); IPMIInterfaceClass *iic = IPMI_INTERFACE_CLASS(oc); @@ -376,7 +376,7 @@ static const TypeInfo smbus_ipmi_info = { .instance_size = sizeof(SMBusIPMIDevice), .instance_init = smbus_ipmi_init, .class_init = smbus_ipmi_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_IPMI_INTERFACE }, { TYPE_ACPI_DEV_AML_IF }, { } diff --git a/hw/isa/fdc37m81x-superio.c b/hw/isa/fdc37m81x-superio.c index 55e91fb..c2a38f0 100644 --- a/hw/isa/fdc37m81x-superio.c +++ b/hw/isa/fdc37m81x-superio.c @@ -11,7 +11,7 @@ #include "qemu/osdep.h" #include "hw/isa/superio.h" -static void fdc37m81x_class_init(ObjectClass *klass, void *data) +static void fdc37m81x_class_init(ObjectClass *klass, const void *data) { ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); diff --git a/hw/isa/i82378.c b/hw/isa/i82378.c index cbaa152..06e8f0c 100644 --- a/hw/isa/i82378.c +++ b/hw/isa/i82378.c @@ -122,7 +122,7 @@ static void i82378_init(Object *obj) qdev_init_gpio_in(dev, i82378_request_pic_irq, 16); } -static void i82378_class_init(ObjectClass *klass, void *data) +static void i82378_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -142,7 +142,7 @@ static const TypeInfo i82378_type_info = { .instance_size = sizeof(I82378State), .instance_init = i82378_init, .class_init = i82378_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c index 2599c12..6c9802e 100644 --- a/hw/isa/isa-bus.c +++ b/hw/isa/isa-bus.c @@ -29,7 +29,7 @@ static ISABus *isabus; static char *isabus_get_fw_dev_path(DeviceState *dev); -static void isa_bus_class_init(ObjectClass *klass, void *data) +static void isa_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -205,7 +205,7 @@ ISADevice *isa_vga_init(ISABus *bus) } } -static void isabus_bridge_class_init(ObjectClass *klass, void *data) +static void isabus_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -220,7 +220,7 @@ static const TypeInfo isabus_bridge_info = { .class_init = isabus_bridge_class_init, }; -static void isa_device_class_init(ObjectClass *klass, void *data) +static void isa_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->bus_type = TYPE_ISA_BUS; diff --git a/hw/isa/isa-superio.c b/hw/isa/isa-superio.c index 4260da5..2853485 100644 --- a/hw/isa/isa-superio.c +++ b/hw/isa/isa-superio.c @@ -172,7 +172,7 @@ static void isa_superio_realize(DeviceState *dev, Error **errp) } } -static void isa_superio_class_init(ObjectClass *oc, void *data) +static void isa_superio_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c index dcb0ac2..304dffa 100644 --- a/hw/isa/lpc_ich9.c +++ b/hw/isa/lpc_ich9.c @@ -182,7 +182,6 @@ static uint64_t ich9_cc_read(void *opaque, hwaddr addr, } /* IRQ routing */ -/* */ static void ich9_lpc_rout(uint8_t pirq_rout, int *pic_irq, int *pic_dis) { *pic_irq = pirq_rout & ICH9_LPC_PIRQ_ROUT_MASK; @@ -875,7 +874,7 @@ static void build_ich9_isa_aml(AcpiDevAmlIf *adev, Aml *scope) qbus_build_aml(bus, scope); } -static void ich9_lpc_class_init(ObjectClass *klass, void *data) +static void ich9_lpc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -915,7 +914,7 @@ static const TypeInfo ich9_lpc_info = { .instance_size = sizeof(ICH9LPCState), .instance_init = ich9_lpc_initfn, .class_init = ich9_lpc_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { TYPE_ACPI_DEVICE_IF }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, diff --git a/hw/isa/pc87312.c b/hw/isa/pc87312.c index 5f58684..388da8f 100644 --- a/hw/isa/pc87312.c +++ b/hw/isa/pc87312.c @@ -332,7 +332,7 @@ static const Property pc87312_properties[] = { DEFINE_PROP_UINT8("config", PC87312State, config, 1), }; -static void pc87312_class_init(ObjectClass *klass, void *data) +static void pc87312_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); diff --git a/hw/isa/piix.c b/hw/isa/piix.c index 7fc9e3e..52c14d3 100644 --- a/hw/isa/piix.c +++ b/hw/isa/piix.c @@ -417,7 +417,7 @@ static const Property pci_piix_props[] = { DEFINE_PROP_BOOL("smm-enabled", PIIXState, smm_enabled, false), }; -static void pci_piix_class_init(ObjectClass *klass, void *data) +static void pci_piix_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -445,7 +445,7 @@ static const TypeInfo piix_pci_type_info = { .instance_init = pci_piix_init, .abstract = true, .class_init = pci_piix_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { TYPE_ACPI_DEV_AML_IF }, { }, @@ -464,7 +464,7 @@ static void piix3_init(Object *obj) object_initialize_child(obj, "ide", &d->ide, TYPE_PIIX3_IDE); } -static void piix3_class_init(ObjectClass *klass, void *data) +static void piix3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -494,7 +494,7 @@ static void piix4_init(Object *obj) object_initialize_child(obj, "ide", &s->ide, TYPE_PIIX4_IDE); } -static void piix4_class_init(ObjectClass *klass, void *data) +static void piix4_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/isa/smc37c669-superio.c b/hw/isa/smc37c669-superio.c index d2e58c9..0ec63f5 100644 --- a/hw/isa/smc37c669-superio.c +++ b/hw/isa/smc37c669-superio.c @@ -58,7 +58,7 @@ static unsigned int get_fdc_dma(ISASuperIODevice *sio, uint8_t index) return 2; } -static void smc37c669_class_init(ObjectClass *klass, void *data) +static void smc37c669_class_init(ObjectClass *klass, const void *data) { ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); diff --git a/hw/isa/vt82c686.c b/hw/isa/vt82c686.c index 43bd67e..3379586 100644 --- a/hw/isa/vt82c686.c +++ b/hw/isa/vt82c686.c @@ -220,7 +220,7 @@ typedef struct via_pm_init_info { uint16_t device_id; } ViaPMInitInfo; -static void via_pm_class_init(ObjectClass *klass, void *data) +static void via_pm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -243,7 +243,7 @@ static const TypeInfo via_pm_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(ViaPMState), .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -259,7 +259,7 @@ static const TypeInfo vt82c686b_pm_info = { .name = TYPE_VT82C686B_PM, .parent = TYPE_VIA_PM, .class_init = via_pm_class_init, - .class_data = (void *)&vt82c686b_pm_init_info, + .class_data = &vt82c686b_pm_init_info, }; static const ViaPMInitInfo vt8231_pm_init_info = { @@ -272,7 +272,7 @@ static const TypeInfo vt8231_pm_info = { .name = TYPE_VT8231_PM, .parent = TYPE_VIA_PM, .class_init = via_pm_class_init, - .class_data = (void *)&vt8231_pm_init_info, + .class_data = &vt8231_pm_init_info, }; @@ -337,7 +337,7 @@ static void via_superio_devices_enable(ViaSuperIOState *s, uint8_t data) isa_fdc_set_enabled(s->superio.floppy, data & BIT(4)); } -static void via_superio_class_init(ObjectClass *klass, void *data) +static void via_superio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); @@ -456,7 +456,7 @@ static void vt82c686b_superio_init(Object *obj) VIA_SUPERIO(obj)->io_ops = &vt82c686b_superio_cfg_ops; } -static void vt82c686b_superio_class_init(ObjectClass *klass, void *data) +static void vt82c686b_superio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); @@ -565,7 +565,7 @@ static void vt8231_superio_init(Object *obj) VIA_SUPERIO(obj)->io_ops = &vt8231_superio_cfg_ops; } -static void vt8231_superio_class_init(ObjectClass *klass, void *data) +static void vt8231_superio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ISASuperIOClass *sc = ISA_SUPERIO_CLASS(klass); @@ -634,7 +634,7 @@ static const TypeInfo via_isa_info = { .instance_size = sizeof(ViaISAState), .instance_init = via_isa_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -833,7 +833,7 @@ static void vt82c686b_init(Object *obj) object_initialize_child(obj, "pm", &s->pm, TYPE_VT82C686B_PM); } -static void vt82c686b_class_init(ObjectClass *klass, void *data) +static void vt82c686b_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -898,7 +898,7 @@ static void vt8231_init(Object *obj) object_initialize_child(obj, "pm", &s->pm, TYPE_VT8231_PM); } -static void vt8231_class_init(ObjectClass *klass, void *data) +static void vt8231_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/loongarch/boot.c b/hw/loongarch/boot.c index 354cf45..14d6c52 100644 --- a/hw/loongarch/boot.c +++ b/hw/loongarch/boot.c @@ -35,12 +35,6 @@ struct loongarch_linux_hdr { uint32_t pe_header_offset; } QEMU_PACKED; -struct memmap_entry *memmap_table; -unsigned memmap_entries; - -ram_addr_t initrd_offset; -uint64_t initrd_size; - static const unsigned int slave_boot_code[] = { /* Configure reset ebase. */ 0x0400302c, /* csrwr $t0, LOONGARCH_CSR_EENTRY */ @@ -94,12 +88,16 @@ static inline void *guidcpy(void *dst, const void *src) return memcpy(dst, src, sizeof(efi_guid_t)); } -static void init_efi_boot_memmap(struct efi_system_table *systab, +static void init_efi_boot_memmap(MachineState *ms, + struct efi_system_table *systab, void *p, void *start) { unsigned i; struct efi_boot_memmap *boot_memmap = p; efi_guid_t tbl_guid = LINUX_EFI_BOOT_MEMMAP_GUID; + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms); + struct memmap_entry *memmap_table; + unsigned int memmap_entries; /* efi_configuration_table 1 */ guidcpy(&systab->tables[0].guid, &tbl_guid); @@ -111,6 +109,8 @@ static void init_efi_boot_memmap(struct efi_system_table *systab, boot_memmap->map_size = 0; efi_memory_desc_t *map = p + sizeof(struct efi_boot_memmap); + memmap_table = lvms->memmap_table; + memmap_entries = lvms->memmap_entries; for (i = 0; i < memmap_entries; i++) { map = (void *)boot_memmap + sizeof(*map); map[i].type = memmap_table[i].type; @@ -121,7 +121,8 @@ static void init_efi_boot_memmap(struct efi_system_table *systab, } } -static void init_efi_initrd_table(struct efi_system_table *systab, +static void init_efi_initrd_table(struct loongarch_boot_info *info, + struct efi_system_table *systab, void *p, void *start) { efi_guid_t tbl_guid = LINUX_EFI_INITRD_MEDIA_GUID; @@ -132,8 +133,8 @@ static void init_efi_initrd_table(struct efi_system_table *systab, systab->tables[1].table = (struct efi_configuration_table *)(p - start); systab->nr_tables = 2; - initrd_table->base = initrd_offset; - initrd_table->size = initrd_size; + initrd_table->base = info->initrd_addr; + initrd_table->size = info->initrd_size; } static void init_efi_fdt_table(struct efi_system_table *systab) @@ -146,10 +147,12 @@ static void init_efi_fdt_table(struct efi_system_table *systab) systab->nr_tables = 3; } -static void init_systab(struct loongarch_boot_info *info, void *p, void *start) +static void init_systab(MachineState *ms, + struct loongarch_boot_info *info, void *p, void *start) { void *bp_tables_start; struct efi_system_table *systab = p; + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms); info->a2 = p - start; @@ -166,10 +169,10 @@ static void init_systab(struct loongarch_boot_info *info, void *p, void *start) systab->tables = p; bp_tables_start = p; - init_efi_boot_memmap(systab, p, start); + init_efi_boot_memmap(ms, systab, p, start); p += ROUND_UP(sizeof(struct efi_boot_memmap) + - sizeof(efi_memory_desc_t) * memmap_entries, 64 * KiB); - init_efi_initrd_table(systab, p, start); + sizeof(efi_memory_desc_t) * lvms->memmap_entries, 64 * KiB); + init_efi_initrd_table(info, systab, p, start); p += ROUND_UP(sizeof(struct efi_initrd), 64 * KiB); init_efi_fdt_table(systab); @@ -235,16 +238,56 @@ static int64_t load_loongarch_linux_image(const char *filename, return size; } +static ram_addr_t alloc_initrd_memory(struct loongarch_boot_info *info, + uint64_t advice_start, ssize_t rd_size) +{ + hwaddr base, ram_size, gap, low_end; + ram_addr_t initrd_end, initrd_start; + + base = VIRT_LOWMEM_BASE; + gap = VIRT_LOWMEM_SIZE; + initrd_start = advice_start; + initrd_end = initrd_start + rd_size; + + ram_size = info->ram_size; + low_end = base + MIN(ram_size, gap); + if (initrd_end <= low_end) { + return initrd_start; + } + + if (ram_size <= gap) { + error_report("The low memory too small for initial ram disk '%s'," + "You need to expand the ram", + info->initrd_filename); + exit(1); + } + + /* + * Try to load initrd in the high memory + */ + ram_size -= gap; + initrd_start = VIRT_HIGHMEM_BASE; + if (rd_size <= ram_size) { + return initrd_start; + } + + error_report("The high memory too small for initial ram disk '%s'," + "You need to expand the ram", + info->initrd_filename); + exit(1); +} + static int64_t load_kernel_info(struct loongarch_boot_info *info) { - uint64_t kernel_entry, kernel_low, kernel_high; - ssize_t kernel_size; + uint64_t kernel_entry, kernel_low, kernel_high, initrd_offset = 0; + ssize_t kernel_size, initrd_size; kernel_size = load_elf(info->kernel_filename, NULL, cpu_loongarch_virt_to_phys, NULL, &kernel_entry, &kernel_low, &kernel_high, NULL, ELFDATA2LSB, EM_LOONGARCH, 1, 0); + kernel_entry = cpu_loongarch_virt_to_phys(NULL, kernel_entry); if (kernel_size < 0) { kernel_size = load_loongarch_linux_image(info->kernel_filename, &kernel_entry, &kernel_low, @@ -262,15 +305,10 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) initrd_size = get_image_size(info->initrd_filename); if (initrd_size > 0) { initrd_offset = ROUND_UP(kernel_high + 4 * kernel_size, 64 * KiB); - - if (initrd_offset + initrd_size > info->ram_size) { - error_report("memory too small for initial ram disk '%s'", - info->initrd_filename); - exit(1); - } - - initrd_size = load_image_targphys(info->initrd_filename, initrd_offset, - info->ram_size - initrd_offset); + initrd_offset = alloc_initrd_memory(info, initrd_offset, + initrd_size); + initrd_size = load_image_targphys(info->initrd_filename, + initrd_offset, initrd_size); } if (initrd_size == (target_ulong)-1) { @@ -278,8 +316,9 @@ static int64_t load_kernel_info(struct loongarch_boot_info *info) info->initrd_filename); exit(1); } - } else { - initrd_size = 0; + + info->initrd_addr = initrd_offset; + info->initrd_size = initrd_size; } return kernel_entry; @@ -334,17 +373,19 @@ static void loongarch_firmware_boot(LoongArchVirtMachineState *lvms, fw_cfg_add_kernel_info(info, lvms->fw_cfg); } -static void init_boot_rom(struct loongarch_boot_info *info, void *p) +static void init_boot_rom(MachineState *ms, + struct loongarch_boot_info *info, void *p) { void *start = p; init_cmdline(info, p, start); p += COMMAND_LINE_SIZE; - init_systab(info, p, start); + init_systab(ms, info, p, start); } -static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) +static void loongarch_direct_kernel_boot(MachineState *ms, + struct loongarch_boot_info *info) { void *p, *bp; int64_t kernel_addr = VIRT_FLASH0_BASE; @@ -362,7 +403,7 @@ static void loongarch_direct_kernel_boot(struct loongarch_boot_info *info) /* Load cmdline and system tables at [0 - 1 MiB] */ p = g_malloc0(1 * MiB); bp = p; - init_boot_rom(info, p); + init_boot_rom(ms, info, p); rom_add_blob_fixed_as("boot_info", bp, 1 * MiB, 0, &address_space_memory); /* Load slave boot code at pflash0 . */ @@ -402,6 +443,6 @@ void loongarch_load_kernel(MachineState *ms, struct loongarch_boot_info *info) if (lvms->bios_loaded) { loongarch_firmware_boot(lvms, info); } else { - loongarch_direct_kernel_boot(info); + loongarch_direct_kernel_boot(ms, info); } } diff --git a/hw/loongarch/virt-acpi-build.c b/hw/loongarch/virt-acpi-build.c index fced6c4..2cd2d9d 100644 --- a/hw/loongarch/virt-acpi-build.c +++ b/hw/loongarch/virt-acpi-build.c @@ -514,7 +514,7 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine); GArray *table_offsets; AcpiFadtData fadt_data; - unsigned facs, rsdt, dsdt; + unsigned facs, xsdt, dsdt; uint8_t *u; GArray *tables_blob = tables->table_data; @@ -575,8 +575,8 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) acpi_add_table(table_offsets, tables_blob); { AcpiMcfgInfo mcfg = { - .base = cpu_to_le64(VIRT_PCI_CFG_BASE), - .size = cpu_to_le64(VIRT_PCI_CFG_SIZE), + .base = VIRT_PCI_CFG_BASE, + .size = VIRT_PCI_CFG_SIZE, }; build_mcfg(tables_blob, tables->linker, &mcfg, lvms->oem_id, lvms->oem_table_id); @@ -600,17 +600,17 @@ static void acpi_build(AcpiBuildTables *tables, MachineState *machine) } /* RSDT is pointed to by RSDP */ - rsdt = tables_blob->len; - build_rsdt(tables_blob, tables->linker, table_offsets, + xsdt = tables_blob->len; + build_xsdt(tables_blob, tables->linker, table_offsets, lvms->oem_id, lvms->oem_table_id); /* RSDP is in FSEG memory, so allocate it separately */ { AcpiRsdpData rsdp_data = { - .revision = 0, + .revision = 2, .oem_id = lvms->oem_id, - .xsdt_tbl_offset = NULL, - .rsdt_tbl_offset = &rsdt, + .xsdt_tbl_offset = &xsdt, + .rsdt_tbl_offset = NULL, }; build_rsdp(tables->rsdp, tables->linker, &rsdp_data); } diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c index b2793c8..b15ada2 100644 --- a/hw/loongarch/virt.c +++ b/hw/loongarch/virt.c @@ -8,6 +8,7 @@ #include "qemu/units.h" #include "qemu/datadir.h" #include "qapi/error.h" +#include "exec/target_page.h" #include "hw/boards.h" #include "hw/char/serial-mm.h" #include "system/kvm.h" @@ -18,7 +19,7 @@ #include "system/reset.h" #include "system/rtc.h" #include "hw/loongarch/virt.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/irq.h" #include "net/net.h" #include "hw/loader.h" @@ -135,6 +136,10 @@ static void virt_build_smbios(LoongArchVirtMachineState *lvms) return; } + if (kvm_enabled()) { + product = "KVM Virtual Machine"; + } + smbios_set_defaults("QEMU", product, mc->name); smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64, @@ -167,8 +172,15 @@ static void virt_powerdown_req(Notifier *notifier, void *opaque) acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS); } -static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) +static void memmap_add_entry(MachineState *ms, uint64_t address, + uint64_t length, uint32_t type) { + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms); + struct memmap_entry *memmap_table; + unsigned int memmap_entries; + + memmap_table = lvms->memmap_table; + memmap_entries = lvms->memmap_entries; /* Ensure there are no duplicate entries. */ for (unsigned i = 0; i < memmap_entries; i++) { assert(memmap_table[i].address != address); @@ -181,6 +193,8 @@ static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type) memmap_table[memmap_entries].type = cpu_to_le32(type); memmap_table[memmap_entries].reserved = 0; memmap_entries++; + lvms->memmap_table = memmap_table; + lvms->memmap_entries = memmap_entries; } static DeviceState *create_acpi_ged(DeviceState *pch_pic, @@ -400,12 +414,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) lvms->ipi = ipi; sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal); - /* IPI iocsr memory region */ - memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX, - sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0)); - memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR, - sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1)); - /* Create EXTIOI device */ extioi = qdev_new(TYPE_LOONGARCH_EXTIOI); lvms->extioi = extioi; @@ -413,12 +421,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) qdev_prop_set_bit(extioi, "has-virtualization-extension", true); } sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal); - memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); - if (virt_is_veiointc_enabled(lvms)) { - memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE, - sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1)); - } virt_cpu_irq_init(lvms); pch_pic = qdev_new(TYPE_LOONGARCH_PIC); @@ -426,19 +428,6 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num); d = SYS_BUS_DEVICE(pch_pic); sysbus_realize_and_unref(d, &error_fatal); - memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE, - sysbus_mmio_get_region(d, 0)); - memory_region_add_subregion(get_system_memory(), - VIRT_IOAPIC_REG_BASE + PCH_PIC_ROUTE_ENTRY_OFFSET, - sysbus_mmio_get_region(d, 1)); - memory_region_add_subregion(get_system_memory(), - VIRT_IOAPIC_REG_BASE + PCH_PIC_INT_STATUS_LO, - sysbus_mmio_get_region(d, 2)); - - /* Connect pch_pic irqs to extioi */ - for (i = 0; i < num; i++) { - qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i)); - } pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI); start = num; @@ -448,12 +437,40 @@ static void virt_irq_init(LoongArchVirtMachineState *lvms) d = SYS_BUS_DEVICE(pch_msi); sysbus_realize_and_unref(d, &error_fatal); sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW); - for (i = 0; i < num; i++) { - /* Connect pch_msi irqs to extioi */ - qdev_connect_gpio_out(DEVICE(d), i, - qdev_get_gpio_in(extioi, i + start)); - } + if (kvm_irqchip_in_kernel()) { + kvm_loongarch_init_irq_routing(); + } else { + /* IPI iocsr memory region */ + memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0)); + memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR, + sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1)); + + /* EXTIOI iocsr memory region */ + memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE, + sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0)); + if (virt_is_veiointc_enabled(lvms)) { + memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE, + sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1)); + } + + /* PCH_PIC memory region */ + memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE, + sysbus_mmio_get_region(SYS_BUS_DEVICE(pch_pic), 0)); + + /* Connect pch_pic irqs to extioi */ + for (i = 0; i < VIRT_PCH_PIC_IRQ_NUM; i++) { + qdev_connect_gpio_out(DEVICE(pch_pic), i, + qdev_get_gpio_in(extioi, i)); + } + + for (i = VIRT_PCH_PIC_IRQ_NUM; i < EXTIOI_IRQS; i++) { + /* Connect pch_msi irqs to extioi */ + qdev_connect_gpio_out(DEVICE(pch_msi), i - VIRT_PCH_PIC_IRQ_NUM, + qdev_get_gpio_in(extioi, i)); + } + } virt_devices_init(pch_pic, lvms); } @@ -514,6 +531,10 @@ static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr, switch (addr) { case MISC_FUNC_REG: + if (kvm_irqchip_in_kernel()) { + return MEMTX_OK; + } + if (!virt_is_veiointc_enabled(lvms)) { return MEMTX_OK; } @@ -564,6 +585,10 @@ static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr, ret = 0x303030354133ULL; /* "3A5000" */ break; case MISC_FUNC_REG: + if (kvm_irqchip_in_kernel()) { + return MEMTX_OK; + } + if (!virt_is_veiointc_enabled(lvms)) { ret |= BIT_ULL(IOCSRM_EXTIOI_EN); break; @@ -624,13 +649,13 @@ static void fw_cfg_add_memory(MachineState *ms) } if (size >= gap) { - memmap_add_entry(base, gap, 1); + memmap_add_entry(ms, base, gap, 1); size -= gap; base = VIRT_HIGHMEM_BASE; } if (size) { - memmap_add_entry(base, size, 1); + memmap_add_entry(ms, base, size, 1); base += size; } @@ -645,7 +670,7 @@ static void fw_cfg_add_memory(MachineState *ms) * lowram: [base, +(gap - numa_info[0].node_mem)) * highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap)) */ - memmap_add_entry(base, gap - numa_info[0].node_mem, 1); + memmap_add_entry(ms, base, gap - numa_info[0].node_mem, 1); size = ram_size - gap; base = VIRT_HIGHMEM_BASE; } else { @@ -653,7 +678,7 @@ static void fw_cfg_add_memory(MachineState *ms) } if (size) { - memmap_add_entry(base, size, 1); + memmap_add_entry(ms, base, size, 1); } } @@ -739,8 +764,8 @@ static void virt_init(MachineState *machine) rom_set_fw(lvms->fw_cfg); if (lvms->fw_cfg != NULL) { fw_cfg_add_file(lvms->fw_cfg, "etc/memmap", - memmap_table, - sizeof(struct memmap_entry) * (memmap_entries)); + lvms->memmap_table, + sizeof(struct memmap_entry) * lvms->memmap_entries); } /* Initialize the IO interrupt subsystem */ @@ -772,6 +797,48 @@ static void virt_set_acpi(Object *obj, Visitor *v, const char *name, visit_type_OnOffAuto(v, name, &lvms->acpi, errp); } +static char *virt_get_oem_id(Object *obj, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + + return g_strdup(lvms->oem_id); +} + +static void virt_set_oem_id(Object *obj, const char *value, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + size_t len = strlen(value); + + if (len > 6) { + error_setg(errp, + "User specified oem-id value is bigger than 6 bytes in size"); + return; + } + + strncpy(lvms->oem_id, value, 6); +} + +static char *virt_get_oem_table_id(Object *obj, Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + + return g_strdup(lvms->oem_table_id); +} + +static void virt_set_oem_table_id(Object *obj, const char *value, + Error **errp) +{ + LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); + size_t len = strlen(value); + + if (len > 8) { + error_setg(errp, + "User specified oem-table-id value is bigger than 8 bytes in size"); + return; + } + strncpy(lvms->oem_table_id, value, 8); +} + static void virt_initfn(Object *obj) { LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj); @@ -1132,7 +1199,7 @@ static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx) } } -static void virt_class_init(ObjectClass *oc, void *data) +static void virt_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -1176,6 +1243,22 @@ static void virt_class_init(ObjectClass *oc, void *data) #ifdef CONFIG_TPM machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS); #endif + object_class_property_add_str(oc, "x-oem-id", + virt_get_oem_id, + virt_set_oem_id); + object_class_property_set_description(oc, "x-oem-id", + "Override the default value of field OEMID " + "in ACPI table header." + "The string may be up to 6 bytes in size"); + + + object_class_property_add_str(oc, "x-oem-table-id", + virt_get_oem_table_id, + virt_set_oem_table_id); + object_class_property_set_description(oc, "x-oem-table-id", + "Override the default value of field OEM Table ID " + "in ACPI table header." + "The string may be up to 8 bytes in size"); } static const TypeInfo virt_machine_types[] = { @@ -1185,7 +1268,7 @@ static const TypeInfo virt_machine_types[] = { .instance_size = sizeof(LoongArchVirtMachineState), .class_init = virt_class_init, .instance_init = virt_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, diff --git a/hw/m68k/mcf5206.c b/hw/m68k/mcf5206.c index c22e615..a25e782 100644 --- a/hw/m68k/mcf5206.c +++ b/hw/m68k/mcf5206.c @@ -605,7 +605,7 @@ static const Property mcf5206_mbar_properties[] = { TYPE_M68K_CPU, M68kCPU *), }; -static void mcf5206_mbar_class_init(ObjectClass *oc, void *data) +static void mcf5206_mbar_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/m68k/mcf_intc.c b/hw/m68k/mcf_intc.c index 7b92139..e3055b8 100644 --- a/hw/m68k/mcf_intc.c +++ b/hw/m68k/mcf_intc.c @@ -182,7 +182,7 @@ static const Property mcf_intc_properties[] = { TYPE_M68K_CPU, M68kCPU *), }; -static void mcf_intc_class_init(ObjectClass *oc, void *data) +static void mcf_intc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/m68k/next-cube.c b/hw/m68k/next-cube.c index 7ea7e91..957644b 100644 --- a/hw/m68k/next-cube.c +++ b/hw/m68k/next-cube.c @@ -12,6 +12,7 @@ #include "qemu/osdep.h" #include "exec/hwaddr.h" +#include "exec/cpu-interrupt.h" #include "system/system.h" #include "system/qtest.h" #include "hw/irq.h" @@ -793,7 +794,7 @@ static const VMStateDescription next_scsi_vmstate = { }, }; -static void next_scsi_class_init(ObjectClass *klass, void *data) +static void next_scsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1063,7 +1064,7 @@ static const VMStateDescription next_rtc_vmstate = { }, }; -static void next_rtc_class_init(ObjectClass *klass, void *data) +static void next_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1227,7 +1228,7 @@ static const VMStateDescription next_pc_vmstate = { }, }; -static void next_pc_class_init(ObjectClass *klass, void *data) +static void next_pc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1347,7 +1348,7 @@ static void next_cube_init(MachineState *machine) memory_region_add_subregion(sysmem, 0x02000000, &m->dmamem); } -static void next_machine_class_init(ObjectClass *oc, void *data) +static void next_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/m68k/next-kbd.c b/hw/m68k/next-kbd.c index 68b1778..2bec945 100644 --- a/hw/m68k/next-kbd.c +++ b/hw/m68k/next-kbd.c @@ -312,7 +312,7 @@ static const VMStateDescription nextkbd_vmstate = { .unmigratable = 1, /* TODO: Implement this when m68k CPU is migratable */ }; -static void nextkbd_class_init(ObjectClass *oc, void *data) +static void nextkbd_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/m68k/q800-glue.c b/hw/m68k/q800-glue.c index 168665b..36de67c 100644 --- a/hw/m68k/q800-glue.c +++ b/hw/m68k/q800-glue.c @@ -228,7 +228,7 @@ static void glue_init(Object *obj) s->nmi_release = timer_new_ms(QEMU_CLOCK_VIRTUAL, glue_nmi_release, s); } -static void glue_class_init(ObjectClass *klass, void *data) +static void glue_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -248,7 +248,7 @@ static const TypeInfo glue_info_types[] = { .instance_init = glue_init, .instance_finalize = glue_finalize, .class_init = glue_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { } }, diff --git a/hw/m68k/q800.c b/hw/m68k/q800.c index 1e5b0e2..793b23f 100644 --- a/hw/m68k/q800.c +++ b/hw/m68k/q800.c @@ -24,6 +24,7 @@ #include "qemu/units.h" #include "qemu/datadir.h" #include "qemu/guest-random.h" +#include "exec/target_page.h" #include "system/system.h" #include "cpu.h" #include "hw/boards.h" @@ -726,7 +727,7 @@ static GlobalProperty hw_compat_q800[] = { }; static const size_t hw_compat_q800_len = G_N_ELEMENTS(hw_compat_q800); -static void q800_machine_class_init(ObjectClass *oc, void *data) +static void q800_machine_class_init(ObjectClass *oc, const void *data) { static const char * const valid_cpu_types[] = { M68K_CPU_TYPE_NAME("m68040"), diff --git a/hw/m68k/virt.c b/hw/m68k/virt.c index 295a614..875fd00 100644 --- a/hw/m68k/virt.c +++ b/hw/m68k/virt.c @@ -10,6 +10,7 @@ #include "qemu/osdep.h" #include "qemu/units.h" #include "qemu/guest-random.h" +#include "exec/target_page.h" #include "system/system.h" #include "cpu.h" #include "hw/boards.h" @@ -309,7 +310,7 @@ static void virt_init(MachineState *machine) } } -static void virt_machine_class_init(ObjectClass *oc, void *data) +static void virt_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); mc->desc = "QEMU M68K Virtual Machine"; @@ -338,7 +339,7 @@ type_init(virt_machine_register_types) #define DEFINE_VIRT_MACHINE_IMPL(latest, ...) \ static void MACHINE_VER_SYM(class_init, virt, __VA_ARGS__)( \ ObjectClass *oc, \ - void *data) \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ MACHINE_VER_SYM(options, virt, __VA_ARGS__)(mc); \ diff --git a/hw/mem/cxl_type3.c b/hw/mem/cxl_type3.c index 43aa02a..94e7274 100644 --- a/hw/mem/cxl_type3.c +++ b/hw/mem/cxl_type3.c @@ -843,6 +843,19 @@ static DOEProtocol doe_cdat_prot[] = { { } }; +/* Initialize CXL device alerts with default threshold values. */ +static void init_alert_config(CXLType3Dev *ct3d) +{ + ct3d->alert_config = (CXLAlertConfig) { + .life_used_crit_alert_thresh = 75, + .life_used_warn_thresh = 40, + .over_temp_crit_alert_thresh = 35, + .under_temp_crit_alert_thresh = 10, + .over_temp_warn_thresh = 25, + .under_temp_warn_thresh = 20 + }; +} + static void ct3_realize(PCIDevice *pci_dev, Error **errp) { ERRP_GUARD(); @@ -910,6 +923,7 @@ static void ct3_realize(PCIDevice *pci_dev, Error **errp) goto err_msix_uninit; } + init_alert_config(ct3d); pcie_cap_deverr_init(pci_dev); /* Leave a bit of room for expansion */ rc = pcie_aer_init(pci_dev, PCI_ERR_VER, 0x200, PCI_ERR_SIZEOF, errp); @@ -969,6 +983,7 @@ static void ct3_exit(PCIDevice *pci_dev) cxl_doe_cdat_release(cxl_cstate); msix_uninit_exclusive_bar(pci_dev); g_free(regs->special_ops); + cxl_destroy_cci(&ct3d->cci); if (ct3d->dc.host_dc) { cxl_destroy_dc_regions(ct3d); address_space_destroy(&ct3d->dc.host_dc_as); @@ -1224,12 +1239,17 @@ static void ct3d_reset(DeviceState *dev) * Bring up an endpoint to target with MCTP over VDM. * This device is emulating an MLD with single LD for now. */ + if (ct3d->vdm_fm_owned_ld_mctp_cci.initialized) { + cxl_destroy_cci(&ct3d->vdm_fm_owned_ld_mctp_cci); + } cxl_initialize_t3_fm_owned_ld_mctpcci(&ct3d->vdm_fm_owned_ld_mctp_cci, DEVICE(ct3d), DEVICE(ct3d), 512); /* Max payload made up */ + if (ct3d->ld0_cci.initialized) { + cxl_destroy_cci(&ct3d->ld0_cci); + } cxl_initialize_t3_ld_cci(&ct3d->ld0_cci, DEVICE(ct3d), DEVICE(ct3d), 512); /* Max payload made up */ - } static const Property ct3_props[] = { @@ -2141,7 +2161,7 @@ void qmp_cxl_release_dynamic_capacity(const char *path, uint16_t host_id, } } -static void ct3_class_init(ObjectClass *oc, void *data) +static void ct3_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); @@ -2174,7 +2194,7 @@ static const TypeInfo ct3d_info = { .class_size = sizeof(struct CXLType3Class), .class_init = ct3_class_init, .instance_size = sizeof(CXLType3Dev), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CXL_DEVICE }, { INTERFACE_PCIE_DEVICE }, {} diff --git a/hw/mem/memory-device.c b/hw/mem/memory-device.c index 1de8dfe..1a432e9 100644 --- a/hw/mem/memory-device.c +++ b/hw/mem/memory-device.c @@ -17,7 +17,7 @@ #include "qemu/range.h" #include "hw/virtio/vhost.h" #include "system/kvm.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "trace.h" static bool memory_device_is_empty(const MemoryDeviceState *md) diff --git a/hw/mem/npcm7xx_mc.c b/hw/mem/npcm7xx_mc.c index abc5af5..07fc108 100644 --- a/hw/mem/npcm7xx_mc.c +++ b/hw/mem/npcm7xx_mc.c @@ -65,7 +65,7 @@ static void npcm7xx_mc_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->mmio); } -static void npcm7xx_mc_class_init(ObjectClass *klass, void *data) +static void npcm7xx_mc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c index c05007a..23ab143e 100644 --- a/hw/mem/nvdimm.c +++ b/hw/mem/nvdimm.c @@ -250,7 +250,7 @@ static const Property nvdimm_properties[] = { DEFINE_PROP_BOOL(NVDIMM_UNARMED_PROP, NVDIMMDevice, unarmed, false), }; -static void nvdimm_class_init(ObjectClass *oc, void *data) +static void nvdimm_class_init(ObjectClass *oc, const void *data) { PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc); MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc); diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c index 799a618..f701d5b 100644 --- a/hw/mem/pc-dimm.c +++ b/hw/mem/pc-dimm.c @@ -276,7 +276,7 @@ static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md, } } -static void pc_dimm_class_init(ObjectClass *oc, void *data) +static void pc_dimm_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc); @@ -301,7 +301,7 @@ static const TypeInfo pc_dimm_info = { .instance_init = pc_dimm_init, .class_init = pc_dimm_class_init, .class_size = sizeof(PCDIMMDeviceClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_MEMORY_DEVICE }, { } }, diff --git a/hw/mem/sparse-mem.c b/hw/mem/sparse-mem.c index 8bed5db..d7b00e5 100644 --- a/hw/mem/sparse-mem.c +++ b/hw/mem/sparse-mem.c @@ -136,7 +136,7 @@ static void sparse_mem_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->mmio); } -static void sparse_mem_class_init(ObjectClass *klass, void *data) +static void sparse_mem_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/meson.build b/hw/meson.build index b91f761..791ce21 100644 --- a/hw/meson.build +++ b/hw/meson.build @@ -39,6 +39,7 @@ subdir('uefi') subdir('ufs') subdir('usb') subdir('vfio') +subdir('vfio-user') subdir('virtio') subdir('vmapple') subdir('watchdog') diff --git a/hw/microblaze/boot.c b/hw/microblaze/boot.c index 60b4ef0..4a9c9df 100644 --- a/hw/microblaze/boot.c +++ b/hw/microblaze/boot.c @@ -130,7 +130,7 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, bool is_little_endian, dtb_arg = current_machine->dtb; /* default to pcbios dtb as passed by machine_init */ if (!dtb_arg && dtb_filename) { - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_filename); + filename = qemu_find_file(QEMU_FILE_TYPE_DTB, dtb_filename); } boot_info.machine_cpu_reset = machine_cpu_reset; diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c index 21ad215..6e923c4 100644 --- a/hw/microblaze/petalogix_ml605_mmu.c +++ b/hw/microblaze/petalogix_ml605_mmu.c @@ -36,7 +36,7 @@ #include "hw/boards.h" #include "hw/char/serial-mm.h" #include "hw/qdev-properties.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/ssi/ssi.h" #include "boot.h" @@ -80,8 +80,6 @@ petalogix_ml605_init(MachineState *machine) MemoryRegion *phys_lmb_bram = g_new(MemoryRegion, 1); MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32]; - EndianMode endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG - : ENDIAN_MODE_LITTLE; /* init CPUs */ cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); @@ -113,7 +111,7 @@ petalogix_ml605_init(MachineState *machine) dev = qdev_new("xlnx.xps-intc"); - qdev_prop_set_enum(dev, "endianness", endianness); + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); qdev_prop_set_uint32(dev, "kind-of-intr", 1 << TIMER_IRQ); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, INTC_BASEADDR); @@ -129,7 +127,7 @@ petalogix_ml605_init(MachineState *machine) /* 2 timers at irq 2 @ 100 Mhz. */ dev = qdev_new("xlnx.xps-timer"); - qdev_prop_set_enum(dev, "endianness", endianness); + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); qdev_prop_set_uint32(dev, "one-timer-only", 0); qdev_prop_set_uint32(dev, "clock-frequency", 100 * 1000000); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); @@ -177,7 +175,7 @@ petalogix_ml605_init(MachineState *machine) SSIBus *spi; dev = qdev_new("xlnx.xps-spi"); - qdev_prop_set_enum(dev, "endianness", endianness); + qdev_prop_set_enum(dev, "endianness", ENDIAN_MODE_LITTLE); qdev_prop_set_uint8(dev, "num-ss-bits", NUM_SPI_FLASHES); busdev = SYS_BUS_DEVICE(dev); sysbus_realize_and_unref(busdev, &error_fatal); @@ -218,12 +216,7 @@ petalogix_ml605_init(MachineState *machine) static void petalogix_ml605_machine_init(MachineClass *mc) { -#if TARGET_BIG_ENDIAN - mc->desc = "PetaLogix linux refdesign for xilinx ml605 (big endian)"; - mc->deprecation_reason = "big endian support is not tested"; -#else mc->desc = "PetaLogix linux refdesign for xilinx ml605 (little endian)"; -#endif mc->init = petalogix_ml605_init; } diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c index bdba200..e8d0ddf 100644 --- a/hw/microblaze/petalogix_s3adsp1800_mmu.c +++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c @@ -33,7 +33,7 @@ #include "system/system.h" #include "hw/boards.h" #include "hw/misc/unimp.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/char/xilinx_uartlite.h" #include "boot.h" @@ -58,9 +58,20 @@ #define TYPE_PETALOGIX_S3ADSP1800_MACHINE \ MACHINE_TYPE_NAME("petalogix-s3adsp1800") +struct S3Adsp1800MachineState { + MachineState parent_class; + + EndianMode endianness; +}; + +OBJECT_DECLARE_TYPE(S3Adsp1800MachineState, MachineClass, + PETALOGIX_S3ADSP1800_MACHINE) + + static void petalogix_s3adsp1800_init(MachineState *machine) { + S3Adsp1800MachineState *psms = PETALOGIX_S3ADSP1800_MACHINE(machine); ram_addr_t ram_size = machine->ram_size; DeviceState *dev; MicroBlazeCPU *cpu; @@ -71,13 +82,12 @@ petalogix_s3adsp1800_init(MachineState *machine) MemoryRegion *phys_ram = g_new(MemoryRegion, 1); qemu_irq irq[32]; MemoryRegion *sysmem = get_system_memory(); - EndianMode endianness = TARGET_BIG_ENDIAN ? ENDIAN_MODE_BIG - : ENDIAN_MODE_LITTLE; + EndianMode endianness = psms->endianness; cpu = MICROBLAZE_CPU(object_new(TYPE_MICROBLAZE_CPU)); object_property_set_str(OBJECT(cpu), "version", "7.10.d", &error_abort); object_property_set_bool(OBJECT(cpu), "little-endian", - !TARGET_BIG_ENDIAN, &error_abort); + endianness == ENDIAN_MODE_LITTLE, &error_abort); qdev_realize(DEVICE(cpu), NULL, &error_abort); /* Attach emulated BRAM through the LMB. */ @@ -135,19 +145,41 @@ petalogix_s3adsp1800_init(MachineState *machine) create_unimplemented_device("xps_gpio", GPIO_BASEADDR, 0x10000); - microblaze_load_kernel(cpu, !TARGET_BIG_ENDIAN, ddr_base, ram_size, - machine->initrd_filename, + microblaze_load_kernel(cpu, endianness == ENDIAN_MODE_LITTLE, ddr_base, + ram_size, machine->initrd_filename, BINARY_DEVICE_TREE_FILE, NULL); } -static void petalogix_s3adsp1800_machine_class_init(ObjectClass *oc, void *data) +static int machine_get_endianness(Object *obj, Error **errp G_GNUC_UNUSED) +{ + S3Adsp1800MachineState *ms = PETALOGIX_S3ADSP1800_MACHINE(obj); + return ms->endianness; +} + +static void machine_set_endianness(Object *obj, int endianness, Error **errp) +{ + S3Adsp1800MachineState *ms = PETALOGIX_S3ADSP1800_MACHINE(obj); + ms->endianness = endianness; +} + +static void petalogix_s3adsp1800_machine_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); + ObjectProperty *prop; mc->desc = "PetaLogix linux refdesign for xilinx Spartan 3ADSP1800"; mc->init = petalogix_s3adsp1800_init; mc->is_default = true; + + prop = object_class_property_add_enum(oc, "endianness", "EndianMode", + &EndianMode_lookup, + machine_get_endianness, + machine_set_endianness); + object_property_set_default_str(prop, TARGET_BIG_ENDIAN ? "big" : "little"); + object_class_property_set_description(oc, "endianness", + "Defines whether the machine runs in big or little endian mode"); } static const TypeInfo petalogix_s3adsp1800_machine_types[] = { @@ -155,6 +187,7 @@ static const TypeInfo petalogix_s3adsp1800_machine_types[] = { .name = TYPE_PETALOGIX_S3ADSP1800_MACHINE, .parent = TYPE_MACHINE, .class_init = petalogix_s3adsp1800_machine_class_init, + .instance_size = sizeof(S3Adsp1800MachineState), }, }; diff --git a/hw/microblaze/xlnx-zynqmp-pmu.c b/hw/microblaze/xlnx-zynqmp-pmu.c index bdbf732..e909802 100644 --- a/hw/microblaze/xlnx-zynqmp-pmu.c +++ b/hw/microblaze/xlnx-zynqmp-pmu.c @@ -17,7 +17,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/boards.h" #include "cpu.h" #include "boot.h" @@ -121,7 +121,7 @@ static void xlnx_zynqmp_pmu_soc_realize(DeviceState *dev, Error **errp) } } -static void xlnx_zynqmp_pmu_soc_class_init(ObjectClass *oc, void *data) +static void xlnx_zynqmp_pmu_soc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -181,12 +181,7 @@ static void xlnx_zynqmp_pmu_init(MachineState *machine) static void xlnx_zynqmp_pmu_machine_init(MachineClass *mc) { -#if TARGET_BIG_ENDIAN - mc->desc = "Xilinx ZynqMP PMU machine (big endian)"; - mc->deprecation_reason = "big endian support is not tested"; -#else mc->desc = "Xilinx ZynqMP PMU machine (little endian)"; -#endif mc->init = xlnx_zynqmp_pmu_init; } diff --git a/hw/mips/cps.c b/hw/mips/cps.c index 0d8cbdc..2a3ba3f 100644 --- a/hw/mips/cps.c +++ b/hw/mips/cps.c @@ -173,7 +173,7 @@ static const Property mips_cps_properties[] = { DEFINE_PROP_BOOL("cpu-big-endian", MIPSCPSState, cpu_is_bigendian, false), }; -static void mips_cps_class_init(ObjectClass *klass, void *data) +static void mips_cps_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/mips/jazz.c b/hw/mips/jazz.c index 1700c37..7fb0b97 100644 --- a/hw/mips/jazz.c +++ b/hw/mips/jazz.c @@ -59,12 +59,6 @@ enum jazz_model_e { JAZZ_PICA61, }; -#if TARGET_BIG_ENDIAN -#define BIOS_FILENAME "mips_bios.bin" -#else -#define BIOS_FILENAME "mipsel_bios.bin" -#endif - static void main_cpu_reset(void *opaque) { MIPSCPU *cpu = opaque; @@ -168,6 +162,8 @@ static void mips_jazz_init_net(IOMMUMemoryRegion *rc4030_dma_mr, static void mips_jazz_init(MachineState *machine, enum jazz_model_e jazz_model) { + const char *bios_name = TARGET_BIG_ENDIAN ? "mips_bios.bin" + : "mipsel_bios.bin"; MemoryRegion *address_space = get_system_memory(); char *filename; int bios_size, n; @@ -245,7 +241,8 @@ static void mips_jazz_init(MachineState *machine, memory_region_add_subregion(address_space, 0xfff00000LL, bios2); /* load the BIOS image. */ - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware ?: BIOS_FILENAME); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, + machine->firmware ?: bios_name); if (filename) { bios_size = load_image_targphys(filename, 0xfff00000LL, MAGNUM_BIOS_SIZE); @@ -415,7 +412,7 @@ void mips_pica61_init(MachineState *machine) mips_jazz_init(machine, JAZZ_PICA61); } -static void mips_magnum_class_init(ObjectClass *oc, void *data) +static void mips_magnum_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -432,7 +429,7 @@ static const TypeInfo mips_magnum_type = { .class_init = mips_magnum_class_init, }; -static void mips_pica61_class_init(ObjectClass *oc, void *data) +static void mips_pica61_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/mips/loongson3_virt.c b/hw/mips/loongson3_virt.c index 1da20dc..de6fbcc 100644 --- a/hw/mips/loongson3_virt.c +++ b/hw/mips/loongson3_virt.c @@ -667,7 +667,7 @@ static void mips_loongson3_virt_init(MachineState *machine) loongson3_virt_devices_init(machine, liointc); } -static void loongson3v_machine_class_init(ObjectClass *oc, void *data) +static void loongson3v_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/mips/malta.c b/hw/mips/malta.c index 8e9cea7..cbdbb21 100644 --- a/hw/mips/malta.c +++ b/hw/mips/malta.c @@ -94,12 +94,6 @@ typedef struct { bool display_inited; } MaltaFPGAState; -#if TARGET_BIG_ENDIAN -#define BIOS_FILENAME "mips_bios.bin" -#else -#define BIOS_FILENAME "mipsel_bios.bin" -#endif - #define TYPE_MIPS_MALTA "mips-malta" OBJECT_DECLARE_SIMPLE_TYPE(MaltaState, MIPS_MALTA) @@ -383,11 +377,7 @@ static uint64_t malta_fpga_read(void *opaque, hwaddr addr, /* STATUS Register */ case 0x00208: -#if TARGET_BIG_ENDIAN - val = 0x00000012; -#else - val = 0x00000010; -#endif + val = TARGET_BIG_ENDIAN ? 0x00000012 : 0x00000010; break; /* JMPRS Register */ @@ -1177,9 +1167,12 @@ void mips_malta_init(MachineState *machine) target_long bios_size = FLASH_SIZE; /* Load firmware from flash. */ if (!dinfo) { + const char *bios_name = TARGET_BIG_ENDIAN ? "mips_bios.bin" + : "mipsel_bios.bin"; + /* Load a BIOS image. */ filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, - machine->firmware ?: BIOS_FILENAME); + machine->firmware ?: bios_name); if (filename) { bios_size = load_image_targphys(filename, FLASH_ADDRESS, BIOS_SIZE); @@ -1197,8 +1190,7 @@ void mips_malta_init(MachineState *machine) * In little endian mode the 32bit words in the bios are swapped, * a neat trick which allows bi-endian firmware. */ -#if !TARGET_BIG_ENDIAN - { + if (!TARGET_BIG_ENDIAN) { uint32_t *end, *addr; const size_t swapsize = MIN(bios_size, 0x3e0000); addr = rom_ptr(FLASH_ADDRESS, swapsize); @@ -1211,7 +1203,6 @@ void mips_malta_init(MachineState *machine) addr++; } } -#endif } /* diff --git a/hw/mips/mipssim.c b/hw/mips/mipssim.c index c530688..e843307 100644 --- a/hw/mips/mipssim.c +++ b/hw/mips/mipssim.c @@ -28,7 +28,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qemu/datadir.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/clock.h" #include "hw/mips/mips.h" #include "hw/char/serial-mm.h" @@ -46,12 +46,6 @@ #define BIOS_SIZE (4 * MiB) -#if TARGET_BIG_ENDIAN -#define BIOS_FILENAME "mips_bios.bin" -#else -#define BIOS_FILENAME "mipsel_bios.bin" -#endif - static struct _loaderparams { int ram_size; const char *kernel_filename; @@ -143,6 +137,8 @@ mips_mipssim_init(MachineState *machine) const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; + const char *bios_name = TARGET_BIG_ENDIAN ? "mips_bios.bin" + : "mipsel_bios.bin"; char *filename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *isa = g_new(MemoryRegion, 1); @@ -179,7 +175,8 @@ mips_mipssim_init(MachineState *machine) /* Map the BIOS / boot exception handler. */ memory_region_add_subregion(address_space_mem, 0x1fc00000LL, bios); /* Load a BIOS / boot exception handler image. */ - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, machine->firmware ?: BIOS_FILENAME); + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, + machine->firmware ?: bios_name); if (filename) { bios_size = load_image_targphys(filename, 0x1fc00000LL, BIOS_SIZE); g_free(filename); diff --git a/hw/misc/a9scu.c b/hw/misc/a9scu.c index 088d4ad..bb00ae2 100644 --- a/hw/misc/a9scu.c +++ b/hw/misc/a9scu.c @@ -127,7 +127,7 @@ static const Property a9_scu_properties[] = { DEFINE_PROP_UINT32("num-cpu", A9SCUState, num_cpu, 1), }; -static void a9_scu_class_init(ObjectClass *klass, void *data) +static void a9_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-a10-ccm.c b/hw/misc/allwinner-a10-ccm.c index 6ca1daa..6b188c2 100644 --- a/hw/misc/allwinner-a10-ccm.c +++ b/hw/misc/allwinner-a10-ccm.c @@ -199,7 +199,7 @@ static const VMStateDescription allwinner_a10_ccm_vmstate = { } }; -static void allwinner_a10_ccm_class_init(ObjectClass *klass, void *data) +static void allwinner_a10_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/allwinner-a10-dramc.c b/hw/misc/allwinner-a10-dramc.c index badc4c5..c16814c 100644 --- a/hw/misc/allwinner-a10-dramc.c +++ b/hw/misc/allwinner-a10-dramc.c @@ -154,7 +154,7 @@ static const VMStateDescription allwinner_a10_dramc_vmstate = { } }; -static void allwinner_a10_dramc_class_init(ObjectClass *klass, void *data) +static void allwinner_a10_dramc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/allwinner-cpucfg.c b/hw/misc/allwinner-cpucfg.c index a4f7a01..90dd872 100644 --- a/hw/misc/allwinner-cpucfg.c +++ b/hw/misc/allwinner-cpucfg.c @@ -258,7 +258,7 @@ static const VMStateDescription allwinner_cpucfg_vmstate = { } }; -static void allwinner_cpucfg_class_init(ObjectClass *klass, void *data) +static void allwinner_cpucfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-h3-ccu.c b/hw/misc/allwinner-h3-ccu.c index e765f4c..be91c0c 100644 --- a/hw/misc/allwinner-h3-ccu.c +++ b/hw/misc/allwinner-h3-ccu.c @@ -218,7 +218,7 @@ static const VMStateDescription allwinner_h3_ccu_vmstate = { } }; -static void allwinner_h3_ccu_class_init(ObjectClass *klass, void *data) +static void allwinner_h3_ccu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-h3-dramc.c b/hw/misc/allwinner-h3-dramc.c index c4f3eb9..8834524 100644 --- a/hw/misc/allwinner-h3-dramc.c +++ b/hw/misc/allwinner-h3-dramc.c @@ -24,7 +24,7 @@ #include "migration/vmstate.h" #include "qemu/log.h" #include "qemu/module.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/qdev-properties.h" #include "qapi/error.h" #include "hw/misc/allwinner-h3-dramc.h" @@ -331,7 +331,7 @@ static const VMStateDescription allwinner_h3_dramc_vmstate = { } }; -static void allwinner_h3_dramc_class_init(ObjectClass *klass, void *data) +static void allwinner_h3_dramc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-h3-sysctrl.c b/hw/misc/allwinner-h3-sysctrl.c index 32a0ceb..6b86524 100644 --- a/hw/misc/allwinner-h3-sysctrl.c +++ b/hw/misc/allwinner-h3-sysctrl.c @@ -116,7 +116,8 @@ static const VMStateDescription allwinner_h3_sysctrl_vmstate = { } }; -static void allwinner_h3_sysctrl_class_init(ObjectClass *klass, void *data) +static void allwinner_h3_sysctrl_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-r40-ccu.c b/hw/misc/allwinner-r40-ccu.c index 8f37a92..4e21eea 100644 --- a/hw/misc/allwinner-r40-ccu.c +++ b/hw/misc/allwinner-r40-ccu.c @@ -185,7 +185,7 @@ static const VMStateDescription allwinner_r40_ccu_vmstate = { } }; -static void allwinner_r40_ccu_class_init(ObjectClass *klass, void *data) +static void allwinner_r40_ccu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-r40-dramc.c b/hw/misc/allwinner-r40-dramc.c index 96e1848..1c8e17e 100644 --- a/hw/misc/allwinner-r40-dramc.c +++ b/hw/misc/allwinner-r40-dramc.c @@ -24,7 +24,7 @@ #include "migration/vmstate.h" #include "qemu/log.h" #include "qemu/module.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/qdev-properties.h" #include "qapi/error.h" #include "qemu/bitops.h" @@ -484,7 +484,7 @@ static const VMStateDescription allwinner_r40_dramc_vmstate = { } }; -static void allwinner_r40_dramc_class_init(ObjectClass *klass, void *data) +static void allwinner_r40_dramc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-sid.c b/hw/misc/allwinner-sid.c index 2bb81f9..1e66c14 100644 --- a/hw/misc/allwinner-sid.c +++ b/hw/misc/allwinner-sid.c @@ -143,7 +143,7 @@ static const VMStateDescription allwinner_sid_vmstate = { } }; -static void allwinner_sid_class_init(ObjectClass *klass, void *data) +static void allwinner_sid_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/allwinner-sramc.c b/hw/misc/allwinner-sramc.c index 51df5e4..ed299ec 100644 --- a/hw/misc/allwinner-sramc.c +++ b/hw/misc/allwinner-sramc.c @@ -135,7 +135,7 @@ static void allwinner_sramc_reset(DeviceState *dev) } } -static void allwinner_sramc_class_init(ObjectClass *klass, void *data) +static void allwinner_sramc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -163,7 +163,7 @@ static const TypeInfo allwinner_sramc_info = { .class_init = allwinner_sramc_class_init, }; -static void allwinner_r40_sramc_class_init(ObjectClass *klass, void *data) +static void allwinner_r40_sramc_class_init(ObjectClass *klass, const void *data) { AwSRAMCClass *sc = AW_SRAMC_CLASS(klass); diff --git a/hw/misc/applesmc.c b/hw/misc/applesmc.c index 97ea842..a015d4a 100644 --- a/hw/misc/applesmc.c +++ b/hw/misc/applesmc.c @@ -375,7 +375,7 @@ static void build_applesmc_aml(AcpiDevAmlIf *adev, Aml *scope) aml_append(scope, dev); } -static void qdev_applesmc_class_init(ObjectClass *klass, void *data) +static void qdev_applesmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); @@ -393,7 +393,7 @@ static const TypeInfo applesmc_isa_info = { .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(AppleSMCState), .class_init = qdev_applesmc_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/misc/arm11scu.c b/hw/misc/arm11scu.c index 02493ce..2ad4fd1 100644 --- a/hw/misc/arm11scu.c +++ b/hw/misc/arm11scu.c @@ -79,7 +79,7 @@ static const Property arm11_scu_properties[] = { DEFINE_PROP_UINT32("num-cpu", ARM11SCUState, num_cpu, 1), }; -static void arm11_scu_class_init(ObjectClass *oc, void *data) +static void arm11_scu_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/misc/arm_l2x0.c b/hw/misc/arm_l2x0.c index 39b4642..8b4b61e 100644 --- a/hw/misc/arm_l2x0.c +++ b/hw/misc/arm_l2x0.c @@ -177,7 +177,7 @@ static const Property l2x0_properties[] = { DEFINE_PROP_UINT32("cache-type", L2x0State, cache_type, 0x1c100100), }; -static void l2x0_class_init(ObjectClass *klass, void *data) +static void l2x0_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c index 0166340..0f4e37c 100644 --- a/hw/misc/arm_sysctl.c +++ b/hw/misc/arm_sysctl.c @@ -634,7 +634,7 @@ static const Property arm_sysctl_properties[] = { db_clock_reset, qdev_prop_uint32, uint32_t), }; -static void arm_sysctl_class_init(ObjectClass *klass, void *data) +static void arm_sysctl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/armsse-cpu-pwrctrl.c b/hw/misc/armsse-cpu-pwrctrl.c index 2d3a0ac..66e9218 100644 --- a/hw/misc/armsse-cpu-pwrctrl.c +++ b/hw/misc/armsse-cpu-pwrctrl.c @@ -125,7 +125,7 @@ static void pwrctrl_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); } -static void pwrctrl_class_init(ObjectClass *klass, void *data) +static void pwrctrl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/armsse-cpuid.c b/hw/misc/armsse-cpuid.c index 58cb373..a57764d 100644 --- a/hw/misc/armsse-cpuid.c +++ b/hw/misc/armsse-cpuid.c @@ -106,7 +106,7 @@ static void armsse_cpuid_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); } -static void armsse_cpuid_class_init(ObjectClass *klass, void *data) +static void armsse_cpuid_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/armsse-mhu.c b/hw/misc/armsse-mhu.c index 91c4910..d5d307a 100644 --- a/hw/misc/armsse-mhu.c +++ b/hw/misc/armsse-mhu.c @@ -176,7 +176,7 @@ static void armsse_mhu_init(Object *obj) sysbus_init_irq(sbd, &s->cpu1irq); } -static void armsse_mhu_class_init(ObjectClass *klass, void *data) +static void armsse_mhu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/armv7m_ras.c b/hw/misc/armv7m_ras.c index de24922..7bf5acd 100644 --- a/hw/misc/armv7m_ras.c +++ b/hw/misc/armv7m_ras.c @@ -72,7 +72,7 @@ static void armv7m_ras_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); } -static void armv7m_ras_class_init(ObjectClass *klass, void *data) +static void armv7m_ras_class_init(ObjectClass *klass, const void *data) { /* This device has no state: no need for vmstate or reset */ } diff --git a/hw/misc/aspeed_hace.c b/hw/misc/aspeed_hace.c index d75da33..726368f 100644 --- a/hw/misc/aspeed_hace.c +++ b/hw/misc/aspeed_hace.c @@ -10,14 +10,17 @@ */ #include "qemu/osdep.h" +#include "qemu/cutils.h" #include "qemu/log.h" #include "qemu/error-report.h" +#include "qemu/iov.h" #include "hw/misc/aspeed_hace.h" #include "qapi/error.h" #include "migration/vmstate.h" #include "crypto/hash.h" #include "hw/qdev-properties.h" #include "hw/irq.h" +#include "trace.h" #define R_CRYPT_CMD (0x10 / 4) @@ -27,9 +30,12 @@ #define TAG_IRQ BIT(15) #define R_HASH_SRC (0x20 / 4) -#define R_HASH_DEST (0x24 / 4) +#define R_HASH_DIGEST (0x24 / 4) #define R_HASH_KEY_BUFF (0x28 / 4) #define R_HASH_SRC_LEN (0x2c / 4) +#define R_HASH_SRC_HI (0x90 / 4) +#define R_HASH_DIGEST_HI (0x94 / 4) +#define R_HASH_KEY_BUFF_HI (0x98 / 4) #define R_HASH_CMD (0x30 / 4) /* Hash algorithm selection */ @@ -84,6 +90,42 @@ static const struct { QCRYPTO_HASH_ALGO_SHA256 }, }; +static void hace_hexdump(const char *desc, const char *buf, size_t size) +{ + g_autoptr(GString) str = g_string_sized_new(64); + size_t len; + size_t i; + + for (i = 0; i < size; i += len) { + len = MIN(16, size - i); + g_string_truncate(str, 0); + qemu_hexdump_line(str, buf + i, len, 1, 4); + trace_aspeed_hace_hexdump(desc, i, str->str); + } +} + +static void hace_iov_hexdump(const char *desc, const struct iovec *iov, + const unsigned int iov_cnt) +{ + size_t size = 0; + char *buf; + int i; + + for (i = 0; i < iov_cnt; i++) { + size += iov[i].iov_len; + } + + buf = g_malloc(size); + + if (!buf) { + return; + } + + iov_to_buf(iov, iov_cnt, 0, buf, size); + hace_hexdump(desc, buf, size); + g_free(buf); +} + static int hash_algo_lookup(uint32_t reg) { int i; @@ -142,171 +184,269 @@ static bool has_padding(AspeedHACEState *s, struct iovec *iov, return false; } -static int reconstruct_iov(AspeedHACEState *s, struct iovec *iov, int id, - uint32_t *pad_offset) +static uint64_t hash_get_source_addr(AspeedHACEState *s) { - int i, iov_count; - if (*pad_offset != 0) { - s->iov_cache[s->iov_count].iov_base = iov[id].iov_base; - s->iov_cache[s->iov_count].iov_len = *pad_offset; - ++s->iov_count; - } - for (i = 0; i < s->iov_count; i++) { - iov[i].iov_base = s->iov_cache[i].iov_base; - iov[i].iov_len = s->iov_cache[i].iov_len; + AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s); + uint64_t src_addr = 0; + + src_addr = deposit64(src_addr, 0, 32, s->regs[R_HASH_SRC]); + if (ahc->has_dma64) { + src_addr = deposit64(src_addr, 32, 32, s->regs[R_HASH_SRC_HI]); } - iov_count = s->iov_count; - s->iov_count = 0; - s->total_req_len = 0; - return iov_count; + + return src_addr; } -static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode, - bool acc_mode) +static int hash_prepare_direct_iov(AspeedHACEState *s, struct iovec *iov, + bool acc_mode, bool *acc_final_request) { - struct iovec iov[ASPEED_HACE_MAX_SG]; uint32_t total_msg_len; uint32_t pad_offset; - g_autofree uint8_t *digest_buf = NULL; - size_t digest_len = 0; - bool sg_acc_mode_final_request = false; - int i; + uint64_t src; void *haddr; - Error *local_err = NULL; + hwaddr plen; + int iov_idx; + + plen = s->regs[R_HASH_SRC_LEN]; + src = hash_get_source_addr(s); + trace_aspeed_hace_hash_addr("src", src); + haddr = address_space_map(&s->dram_as, src, &plen, false, + MEMTXATTRS_UNSPECIFIED); + if (haddr == NULL) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unable to map address, addr=0x%" HWADDR_PRIx + " ,plen=0x%" HWADDR_PRIx "\n", + __func__, src, plen); + return -1; + } - if (acc_mode && s->hash_ctx == NULL) { - s->hash_ctx = qcrypto_hash_new(algo, &local_err); - if (s->hash_ctx == NULL) { - qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash failed : %s", - error_get_pretty(local_err)); - error_free(local_err); - return; + iov[0].iov_base = haddr; + iov_idx = 1; + + if (acc_mode) { + s->total_req_len += plen; + + if (has_padding(s, &iov[0], plen, &total_msg_len, + &pad_offset)) { + /* Padding being present indicates the final request */ + *acc_final_request = true; + iov[0].iov_len = pad_offset; + } else { + iov[0].iov_len = plen; } + } else { + iov[0].iov_len = plen; } - if (sg_mode) { - uint32_t len = 0; - - for (i = 0; !(len & SG_LIST_LEN_LAST); i++) { - uint32_t addr, src; - hwaddr plen; + return iov_idx; +} - if (i == ASPEED_HACE_MAX_SG) { - qemu_log_mask(LOG_GUEST_ERROR, - "aspeed_hace: guest failed to set end of sg list marker\n"); - break; - } +static int hash_prepare_sg_iov(AspeedHACEState *s, struct iovec *iov, + bool acc_mode, bool *acc_final_request) +{ + uint32_t total_msg_len; + uint32_t pad_offset; + uint32_t len = 0; + uint32_t sg_addr; + uint64_t src; + int iov_idx; + hwaddr plen; + void *haddr; - src = s->regs[R_HASH_SRC] + (i * SG_LIST_ENTRY_SIZE); + src = hash_get_source_addr(s); + for (iov_idx = 0; !(len & SG_LIST_LEN_LAST); iov_idx++) { + if (iov_idx == ASPEED_HACE_MAX_SG) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Failed to set end of sg list marker\n", + __func__); + return -1; + } - len = address_space_ldl_le(&s->dram_as, src, + len = address_space_ldl_le(&s->dram_as, src, + MEMTXATTRS_UNSPECIFIED, NULL); + sg_addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE, MEMTXATTRS_UNSPECIFIED, NULL); + sg_addr &= SG_LIST_ADDR_MASK; + trace_aspeed_hace_hash_sg(iov_idx, src, sg_addr, len); + /* + * To maintain compatibility with older SoCs such as the AST2600, + * the AST2700 HW automatically set bit 34 of the 64-bit sg_addr. + * As a result, the firmware only needs to provide a 32-bit sg_addr + * containing bits [31:0]. This is sufficient for the AST2700, as + * it uses a DRAM offset rather than a DRAM address. + */ + plen = len & SG_LIST_LEN_MASK; + haddr = address_space_map(&s->dram_as, sg_addr, &plen, false, + MEMTXATTRS_UNSPECIFIED); - addr = address_space_ldl_le(&s->dram_as, src + SG_LIST_LEN_SIZE, - MEMTXATTRS_UNSPECIFIED, NULL); - addr &= SG_LIST_ADDR_MASK; + if (haddr == NULL) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Unable to map address, sg_addr=0x%x, " + "plen=0x%" HWADDR_PRIx "\n", + __func__, sg_addr, plen); + return -1; + } - plen = len & SG_LIST_LEN_MASK; - haddr = address_space_map(&s->dram_as, addr, &plen, false, - MEMTXATTRS_UNSPECIFIED); - if (haddr == NULL) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: qcrypto failed\n", __func__); - return; - } - iov[i].iov_base = haddr; - if (acc_mode) { - s->total_req_len += plen; - - if (has_padding(s, &iov[i], plen, &total_msg_len, - &pad_offset)) { - /* Padding being present indicates the final request */ - sg_acc_mode_final_request = true; - iov[i].iov_len = pad_offset; - } else { - iov[i].iov_len = plen; - } + src += SG_LIST_ENTRY_SIZE; + + iov[iov_idx].iov_base = haddr; + if (acc_mode) { + s->total_req_len += plen; + + if (has_padding(s, &iov[iov_idx], plen, &total_msg_len, + &pad_offset)) { + /* Padding being present indicates the final request */ + *acc_final_request = true; + iov[iov_idx].iov_len = pad_offset; } else { - iov[i].iov_len = plen; + iov[iov_idx].iov_len = plen; } + } else { + iov[iov_idx].iov_len = plen; } - } else { - hwaddr len = s->regs[R_HASH_SRC_LEN]; + } - haddr = address_space_map(&s->dram_as, s->regs[R_HASH_SRC], - &len, false, MEMTXATTRS_UNSPECIFIED); - if (haddr == NULL) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto failed\n", __func__); + return iov_idx; +} + +static uint64_t hash_get_digest_addr(AspeedHACEState *s) +{ + AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s); + uint64_t digest_addr = 0; + + digest_addr = deposit64(digest_addr, 0, 32, s->regs[R_HASH_DIGEST]); + if (ahc->has_dma64) { + digest_addr = deposit64(digest_addr, 32, 32, s->regs[R_HASH_DIGEST_HI]); + } + + return digest_addr; +} + +static void hash_write_digest_and_unmap_iov(AspeedHACEState *s, + struct iovec *iov, + int iov_idx, + uint8_t *digest_buf, + size_t digest_len) +{ + uint64_t digest_addr = 0; + + digest_addr = hash_get_digest_addr(s); + trace_aspeed_hace_hash_addr("digest", digest_addr); + if (address_space_write(&s->dram_as, digest_addr, + MEMTXATTRS_UNSPECIFIED, + digest_buf, digest_len)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: Failed to write digest to 0x%" HWADDR_PRIx "\n", + __func__, digest_addr); + } + + if (trace_event_get_state_backends(TRACE_ASPEED_HACE_HEXDUMP)) { + hace_hexdump("digest", (char *)digest_buf, digest_len); + } + + for (; iov_idx > 0; iov_idx--) { + address_space_unmap(&s->dram_as, iov[iov_idx - 1].iov_base, + iov[iov_idx - 1].iov_len, false, + iov[iov_idx - 1].iov_len); + } +} + +static void hash_execute_non_acc_mode(AspeedHACEState *s, int algo, + struct iovec *iov, int iov_idx) +{ + g_autofree uint8_t *digest_buf = NULL; + Error *local_err = NULL; + size_t digest_len = 0; + + if (qcrypto_hash_bytesv(algo, iov, iov_idx, &digest_buf, + &digest_len, &local_err) < 0) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: qcrypto hash bytesv failed : %s", + __func__, error_get_pretty(local_err)); + error_free(local_err); + return; + } + + hash_write_digest_and_unmap_iov(s, iov, iov_idx, digest_buf, digest_len); +} + +static void hash_execute_acc_mode(AspeedHACEState *s, int algo, + struct iovec *iov, int iov_idx, + bool final_request) +{ + g_autofree uint8_t *digest_buf = NULL; + Error *local_err = NULL; + size_t digest_len = 0; + + trace_aspeed_hace_hash_execute_acc_mode(final_request); + + if (s->hash_ctx == NULL) { + s->hash_ctx = qcrypto_hash_new(algo, &local_err); + if (s->hash_ctx == NULL) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto hash new failed : %s", + __func__, error_get_pretty(local_err)); + error_free(local_err); return; } - iov[0].iov_base = haddr; - iov[0].iov_len = len; - i = 1; - - if (s->iov_count) { - /* - * In aspeed sdk kernel driver, sg_mode is disabled in hash_final(). - * Thus if we received a request with sg_mode disabled, it is - * required to check whether cache is empty. If no, we should - * combine cached iov and the current iov. - */ - s->total_req_len += len; - if (has_padding(s, iov, len, &total_msg_len, &pad_offset)) { - i = reconstruct_iov(s, iov, 0, &pad_offset); - } - } } - if (acc_mode) { - if (qcrypto_hash_updatev(s->hash_ctx, iov, i, &local_err) < 0) { - qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash update failed : %s", - error_get_pretty(local_err)); + if (qcrypto_hash_updatev(s->hash_ctx, iov, iov_idx, &local_err) < 0) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: qcrypto hash updatev failed : %s", + __func__, error_get_pretty(local_err)); + error_free(local_err); + return; + } + + if (final_request) { + if (qcrypto_hash_finalize_bytes(s->hash_ctx, &digest_buf, + &digest_len, &local_err)) { + qemu_log_mask(LOG_GUEST_ERROR, + "%s: qcrypto hash finalize bytes failed : %s", + __func__, error_get_pretty(local_err)); error_free(local_err); - return; + local_err = NULL; } - if (sg_acc_mode_final_request) { - if (qcrypto_hash_finalize_bytes(s->hash_ctx, &digest_buf, - &digest_len, &local_err)) { - qemu_log_mask(LOG_GUEST_ERROR, - "qcrypto hash finalize failed : %s", - error_get_pretty(local_err)); - error_free(local_err); - local_err = NULL; - } + qcrypto_hash_free(s->hash_ctx); + + s->hash_ctx = NULL; + s->total_req_len = 0; + } - qcrypto_hash_free(s->hash_ctx); + hash_write_digest_and_unmap_iov(s, iov, iov_idx, digest_buf, digest_len); +} - s->hash_ctx = NULL; - s->iov_count = 0; - s->total_req_len = 0; - } - } else if (qcrypto_hash_bytesv(algo, iov, i, &digest_buf, - &digest_len, &local_err) < 0) { - qemu_log_mask(LOG_GUEST_ERROR, "qcrypto hash bytesv failed : %s", - error_get_pretty(local_err)); - error_free(local_err); - return; +static void do_hash_operation(AspeedHACEState *s, int algo, bool sg_mode, + bool acc_mode) +{ + QEMU_UNINITIALIZED struct iovec iov[ASPEED_HACE_MAX_SG]; + bool acc_final_request = false; + int iov_idx = -1; + + /* Prepares the iov for hashing operations based on the selected mode */ + if (sg_mode) { + iov_idx = hash_prepare_sg_iov(s, iov, acc_mode, &acc_final_request); + } else { + iov_idx = hash_prepare_direct_iov(s, iov, acc_mode, + &acc_final_request); } - if (address_space_write(&s->dram_as, s->regs[R_HASH_DEST], - MEMTXATTRS_UNSPECIFIED, - digest_buf, digest_len)) { + if (iov_idx <= 0) { qemu_log_mask(LOG_GUEST_ERROR, - "aspeed_hace: address space write failed\n"); + "%s: Failed to prepare iov\n", __func__); + return; } - for (; i > 0; i--) { - address_space_unmap(&s->dram_as, iov[i - 1].iov_base, - iov[i - 1].iov_len, false, - iov[i - 1].iov_len); + if (trace_event_get_state_backends(TRACE_ASPEED_HACE_HEXDUMP)) { + hace_iov_hexdump("plaintext", iov, iov_idx); } - /* - * Set status bits to indicate completion. Testing shows hardware sets - * these irrespective of HASH_IRQ_EN. - */ - s->regs[R_STATUS] |= HASH_IRQ; + /* Executes the hash operation */ + if (acc_mode) { + hash_execute_acc_mode(s, algo, iov, iov_idx, acc_final_request); + } else { + hash_execute_non_acc_mode(s, algo, iov, iov_idx); + } } static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size) @@ -315,12 +455,7 @@ static uint64_t aspeed_hace_read(void *opaque, hwaddr addr, unsigned int size) addr >>= 2; - if (addr >= ASPEED_HACE_NR_REGS) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: Out-of-bounds read at offset 0x%" HWADDR_PRIx "\n", - __func__, addr << 2); - return 0; - } + trace_aspeed_hace_read(addr << 2, s->regs[addr]); return s->regs[addr]; } @@ -333,12 +468,7 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data, addr >>= 2; - if (addr >= ASPEED_HACE_NR_REGS) { - qemu_log_mask(LOG_GUEST_ERROR, - "%s: Out-of-bounds write at offset 0x%" HWADDR_PRIx "\n", - __func__, addr << 2); - return; - } + trace_aspeed_hace_write(addr << 2, data); switch (addr) { case R_STATUS: @@ -362,7 +492,7 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data, case R_HASH_SRC: data &= ahc->src_mask; break; - case R_HASH_DEST: + case R_HASH_DIGEST: data &= ahc->dest_mask; break; case R_HASH_KEY_BUFF: @@ -390,10 +520,16 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data, qemu_log_mask(LOG_GUEST_ERROR, "%s: Invalid hash algorithm selection 0x%"PRIx64"\n", __func__, data & ahc->hash_mask); - break; + } else { + do_hash_operation(s, algo, data & HASH_SG_EN, + ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM)); } - do_hash_operation(s, algo, data & HASH_SG_EN, - ((data & HASH_HMAC_MASK) == HASH_DIGEST_ACCUM)); + + /* + * Set status bits to indicate completion. Testing shows hardware sets + * these irrespective of HASH_IRQ_EN. + */ + s->regs[R_STATUS] |= HASH_IRQ; if (data & HASH_IRQ_EN) { qemu_irq_raise(s->irq); @@ -410,6 +546,15 @@ static void aspeed_hace_write(void *opaque, hwaddr addr, uint64_t data, } } break; + case R_HASH_SRC_HI: + data &= ahc->src_hi_mask; + break; + case R_HASH_DIGEST_HI: + data &= ahc->dest_hi_mask; + break; + case R_HASH_KEY_BUFF_HI: + data &= ahc->key_hi_mask; + break; default: break; } @@ -430,14 +575,14 @@ static const MemoryRegionOps aspeed_hace_ops = { static void aspeed_hace_reset(DeviceState *dev) { struct AspeedHACEState *s = ASPEED_HACE(dev); + AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s); if (s->hash_ctx != NULL) { qcrypto_hash_free(s->hash_ctx); s->hash_ctx = NULL; } - memset(s->regs, 0, sizeof(s->regs)); - s->iov_count = 0; + memset(s->regs, 0, ahc->nr_regs << 2); s->total_req_len = 0; } @@ -445,11 +590,13 @@ static void aspeed_hace_realize(DeviceState *dev, Error **errp) { AspeedHACEState *s = ASPEED_HACE(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); + AspeedHACEClass *ahc = ASPEED_HACE_GET_CLASS(s); sysbus_init_irq(sbd, &s->irq); + s->regs = g_new(uint32_t, ahc->nr_regs); memory_region_init_io(&s->iomem, OBJECT(s), &aspeed_hace_ops, s, - TYPE_ASPEED_HACE, 0x1000); + TYPE_ASPEED_HACE, ahc->nr_regs << 2); if (!s->dram_mr) { error_setg(errp, TYPE_ASPEED_HACE ": 'dram' link not set"); @@ -469,21 +616,28 @@ static const Property aspeed_hace_properties[] = { static const VMStateDescription vmstate_aspeed_hace = { .name = TYPE_ASPEED_HACE, - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .fields = (const VMStateField[]) { - VMSTATE_UINT32_ARRAY(regs, AspeedHACEState, ASPEED_HACE_NR_REGS), VMSTATE_UINT32(total_req_len, AspeedHACEState), - VMSTATE_UINT32(iov_count, AspeedHACEState), VMSTATE_END_OF_LIST(), } }; -static void aspeed_hace_class_init(ObjectClass *klass, void *data) +static void aspeed_hace_unrealize(DeviceState *dev) +{ + AspeedHACEState *s = ASPEED_HACE(dev); + + g_free(s->regs); + s->regs = NULL; +} + +static void aspeed_hace_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = aspeed_hace_realize; + dc->unrealize = aspeed_hace_unrealize; device_class_set_legacy_reset(dc, aspeed_hace_reset); device_class_set_props(dc, aspeed_hace_properties); dc->vmsd = &vmstate_aspeed_hace; @@ -497,13 +651,14 @@ static const TypeInfo aspeed_hace_info = { .class_size = sizeof(AspeedHACEClass) }; -static void aspeed_ast2400_hace_class_init(ObjectClass *klass, void *data) +static void aspeed_ast2400_hace_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass); dc->desc = "AST2400 Hash and Crypto Engine"; + ahc->nr_regs = 0x64 >> 2; ahc->src_mask = 0x0FFFFFFF; ahc->dest_mask = 0x0FFFFFF8; ahc->key_mask = 0x0FFFFFC0; @@ -516,13 +671,14 @@ static const TypeInfo aspeed_ast2400_hace_info = { .class_init = aspeed_ast2400_hace_class_init, }; -static void aspeed_ast2500_hace_class_init(ObjectClass *klass, void *data) +static void aspeed_ast2500_hace_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass); dc->desc = "AST2500 Hash and Crypto Engine"; + ahc->nr_regs = 0x64 >> 2; ahc->src_mask = 0x3fffffff; ahc->dest_mask = 0x3ffffff8; ahc->key_mask = 0x3FFFFFC0; @@ -535,13 +691,14 @@ static const TypeInfo aspeed_ast2500_hace_info = { .class_init = aspeed_ast2500_hace_class_init, }; -static void aspeed_ast2600_hace_class_init(ObjectClass *klass, void *data) +static void aspeed_ast2600_hace_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass); dc->desc = "AST2600 Hash and Crypto Engine"; + ahc->nr_regs = 0x64 >> 2; ahc->src_mask = 0x7FFFFFFF; ahc->dest_mask = 0x7FFFFFF8; ahc->key_mask = 0x7FFFFFF8; @@ -554,13 +711,14 @@ static const TypeInfo aspeed_ast2600_hace_info = { .class_init = aspeed_ast2600_hace_class_init, }; -static void aspeed_ast1030_hace_class_init(ObjectClass *klass, void *data) +static void aspeed_ast1030_hace_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass); dc->desc = "AST1030 Hash and Crypto Engine"; + ahc->nr_regs = 0x64 >> 2; ahc->src_mask = 0x7FFFFFFF; ahc->dest_mask = 0x7FFFFFF8; ahc->key_mask = 0x7FFFFFF8; @@ -573,24 +731,43 @@ static const TypeInfo aspeed_ast1030_hace_info = { .class_init = aspeed_ast1030_hace_class_init, }; -static void aspeed_ast2700_hace_class_init(ObjectClass *klass, void *data) +static void aspeed_ast2700_hace_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedHACEClass *ahc = ASPEED_HACE_CLASS(klass); dc->desc = "AST2700 Hash and Crypto Engine"; + ahc->nr_regs = 0x9C >> 2; ahc->src_mask = 0x7FFFFFFF; ahc->dest_mask = 0x7FFFFFF8; ahc->key_mask = 0x7FFFFFF8; ahc->hash_mask = 0x00147FFF; /* + * The AST2700 supports a maximum DRAM size of 8 GB, with a DRAM + * addressable range from 0x0_0000_0000 to 0x1_FFFF_FFFF. Since this range + * fits within 34 bits, only bits [33:0] are needed to store the DRAM + * offset. To optimize address storage, the high physical address bits + * [1:0] of the source, digest and key buffer addresses are stored as + * dram_offset bits [33:32]. + * + * This approach eliminates the need to reduce the high part of the DRAM + * physical address for DMA operations. Previously, this was calculated as + * (high physical address bits [7:0] - 4), since the DRAM start address is + * 0x4_00000000, making the high part address [7:0] - 4. + */ + ahc->src_hi_mask = 0x00000003; + ahc->dest_hi_mask = 0x00000003; + ahc->key_hi_mask = 0x00000003; + + /* * Currently, it does not support the CRYPT command. Instead, it only * sends an interrupt to notify the firmware that the crypt command * has completed. It is a temporary workaround. */ ahc->raise_crypt_interrupt_workaround = true; + ahc->has_dma64 = true; } static const TypeInfo aspeed_ast2700_hace_info = { diff --git a/hw/misc/aspeed_i3c.c b/hw/misc/aspeed_i3c.c index ab39c64..3bef1c8 100644 --- a/hw/misc/aspeed_i3c.c +++ b/hw/misc/aspeed_i3c.c @@ -327,7 +327,7 @@ static const Property aspeed_i3c_device_properties[] = { DEFINE_PROP_UINT8("device-id", AspeedI3CDevice, id, 0), }; -static void aspeed_i3c_device_class_init(ObjectClass *klass, void *data) +static void aspeed_i3c_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -356,7 +356,7 @@ static const VMStateDescription vmstate_aspeed_i3c = { } }; -static void aspeed_i3c_class_init(ObjectClass *klass, void *data) +static void aspeed_i3c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/aspeed_lpc.c b/hw/misc/aspeed_lpc.c index 228d250..78406da 100644 --- a/hw/misc/aspeed_lpc.c +++ b/hw/misc/aspeed_lpc.c @@ -458,7 +458,7 @@ static const Property aspeed_lpc_properties[] = { DEFINE_PROP_UINT32("hicr7", AspeedLPCState, hicr7, 0), }; -static void aspeed_lpc_class_init(ObjectClass *klass, void *data) +static void aspeed_lpc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/aspeed_peci.c b/hw/misc/aspeed_peci.c index 9025b35..a7a449a 100644 --- a/hw/misc/aspeed_peci.c +++ b/hw/misc/aspeed_peci.c @@ -130,7 +130,7 @@ static void aspeed_peci_reset(DeviceState *dev) memset(s->regs, 0, sizeof(s->regs)); } -static void aspeed_peci_class_init(ObjectClass *klass, void *data) +static void aspeed_peci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/aspeed_sbc.c b/hw/misc/aspeed_sbc.c index e4a6bd1..a7d101b 100644 --- a/hw/misc/aspeed_sbc.c +++ b/hw/misc/aspeed_sbc.c @@ -141,7 +141,7 @@ static const Property aspeed_sbc_properties[] = { DEFINE_PROP_UINT32("signing-settings", AspeedSBCState, signing_settings, 0), }; -static void aspeed_sbc_class_init(ObjectClass *klass, void *data) +static void aspeed_sbc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -159,7 +159,7 @@ static const TypeInfo aspeed_sbc_info = { .class_size = sizeof(AspeedSBCClass) }; -static void aspeed_ast2600_sbc_class_init(ObjectClass *klass, void *data) +static void aspeed_ast2600_sbc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/aspeed_scu.c b/hw/misc/aspeed_scu.c index 1af1a35..4930e00 100644 --- a/hw/misc/aspeed_scu.c +++ b/hw/misc/aspeed_scu.c @@ -618,7 +618,7 @@ static const Property aspeed_scu_properties[] = { DEFINE_PROP_UINT32("hw-prot-key", AspeedSCUState, hw_prot_key, 0), }; -static void aspeed_scu_class_init(ObjectClass *klass, void *data) +static void aspeed_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = aspeed_scu_realize; @@ -637,7 +637,7 @@ static const TypeInfo aspeed_scu_info = { .abstract = true, }; -static void aspeed_2400_scu_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass); @@ -659,7 +659,7 @@ static const TypeInfo aspeed_2400_scu_info = { .class_init = aspeed_2400_scu_class_init, }; -static void aspeed_2500_scu_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass); @@ -835,7 +835,7 @@ static void aspeed_ast2600_scu_reset(DeviceState *dev) s->regs[PROT_KEY] = s->hw_prot_key; } -static void aspeed_2600_scu_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass); @@ -954,7 +954,7 @@ static void aspeed_ast2700_scu_reset(DeviceState *dev) s->regs[AST2700_HW_STRAP1] = s->hw_strap1; } -static void aspeed_2700_scu_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass); @@ -1068,7 +1068,7 @@ static const uint32_t ast2700_a0_resets_io[ASPEED_AST2700_SCU_NR_REGS] = { [AST2700_SCUIO_CLK_DUTY_MEAS_RST] = 0x0c9100d2, }; -static void aspeed_2700_scuio_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_scuio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass); @@ -1126,7 +1126,7 @@ static void aspeed_ast1030_scu_reset(DeviceState *dev) s->regs[PROT_KEY] = s->hw_prot_key; } -static void aspeed_1030_scu_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_scu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSCUClass *asc = ASPEED_SCU_CLASS(klass); diff --git a/hw/misc/aspeed_sdmc.c b/hw/misc/aspeed_sdmc.c index f359640..f04d993 100644 --- a/hw/misc/aspeed_sdmc.c +++ b/hw/misc/aspeed_sdmc.c @@ -299,7 +299,7 @@ static const Property aspeed_sdmc_properties[] = { DEFINE_PROP_BOOL("unlocked", AspeedSDMCState, unlocked, false), }; -static void aspeed_sdmc_class_init(ObjectClass *klass, void *data) +static void aspeed_sdmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = aspeed_sdmc_realize; @@ -380,7 +380,7 @@ static void aspeed_2400_sdmc_write(AspeedSDMCState *s, uint32_t reg, static const uint64_t aspeed_2400_ram_sizes[] = { 64 * MiB, 128 * MiB, 256 * MiB, 512 * MiB, 0}; -static void aspeed_2400_sdmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_sdmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); @@ -448,7 +448,7 @@ static void aspeed_2500_sdmc_write(AspeedSDMCState *s, uint32_t reg, static const uint64_t aspeed_2500_ram_sizes[] = { 128 * MiB, 256 * MiB, 512 * MiB, 1024 * MiB, 0}; -static void aspeed_2500_sdmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_sdmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); @@ -542,7 +542,7 @@ static void aspeed_2600_sdmc_write(AspeedSDMCState *s, uint32_t reg, static const uint64_t aspeed_2600_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB, 2048 * MiB, 0}; -static void aspeed_2600_sdmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_sdmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); @@ -670,7 +670,7 @@ static const uint64_t aspeed_2700_ram_sizes[] = { 256 * MiB, 512 * MiB, 1024 * MiB, 2048 * MiB, 4096 * MiB, 8192 * MiB, 0}; -static void aspeed_2700_sdmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_sdmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDMCClass *asc = ASPEED_SDMC_CLASS(klass); diff --git a/hw/misc/aspeed_sli.c b/hw/misc/aspeed_sli.c index fe720ea..c514840 100644 --- a/hw/misc/aspeed_sli.c +++ b/hw/misc/aspeed_sli.c @@ -124,7 +124,7 @@ static void aspeed_sliio_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } -static void aspeed_sli_class_init(ObjectClass *klass, void *data) +static void aspeed_sli_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -140,14 +140,14 @@ static const TypeInfo aspeed_sli_info = { .abstract = true, }; -static void aspeed_2700_sli_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_sli_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->desc = "AST2700 SLI Controller"; } -static void aspeed_2700_sliio_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_sliio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/aspeed_xdma.c b/hw/misc/aspeed_xdma.c index 1dd32f7..cc03c42 100644 --- a/hw/misc/aspeed_xdma.c +++ b/hw/misc/aspeed_xdma.c @@ -150,7 +150,7 @@ static const VMStateDescription aspeed_xdma_vmstate = { }, }; -static void aspeed_2600_xdma_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_xdma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass); @@ -173,7 +173,7 @@ static const TypeInfo aspeed_2600_xdma_info = { .class_init = aspeed_2600_xdma_class_init, }; -static void aspeed_2500_xdma_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_xdma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass); @@ -195,7 +195,7 @@ static const TypeInfo aspeed_2500_xdma_info = { .class_init = aspeed_2500_xdma_class_init, }; -static void aspeed_2400_xdma_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_xdma_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedXDMAClass *axc = ASPEED_XDMA_CLASS(klass); @@ -217,7 +217,7 @@ static const TypeInfo aspeed_2400_xdma_info = { .class_init = aspeed_2400_xdma_class_init, }; -static void aspeed_xdma_class_init(ObjectClass *classp, void *data) +static void aspeed_xdma_class_init(ObjectClass *classp, const void *data) { DeviceClass *dc = DEVICE_CLASS(classp); diff --git a/hw/misc/auxbus.c b/hw/misc/auxbus.c index 28d50d9..877f345 100644 --- a/hw/misc/auxbus.c +++ b/hw/misc/auxbus.c @@ -50,7 +50,7 @@ static void aux_slave_dev_print(Monitor *mon, DeviceState *dev, int indent); static inline I2CBus *aux_bridge_get_i2c_bus(AUXTOI2CState *bridge); /* aux-bus implementation (internal not public) */ -static void aux_bus_class_init(ObjectClass *klass, void *data) +static void aux_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -256,7 +256,7 @@ struct AUXTOI2CState { I2CBus *i2c_bus; }; -static void aux_bridge_class_init(ObjectClass *oc, void *data) +static void aux_bridge_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -311,7 +311,7 @@ void aux_init_mmio(AUXSlave *aux_slave, MemoryRegion *mmio) aux_slave->mmio = mmio; } -static void aux_slave_class_init(ObjectClass *klass, void *data) +static void aux_slave_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); diff --git a/hw/misc/avr_power.c b/hw/misc/avr_power.c index ac7b96f..411f016 100644 --- a/hw/misc/avr_power.c +++ b/hw/misc/avr_power.c @@ -90,7 +90,7 @@ static void avr_mask_init(Object *dev) s->val = 0x00; } -static void avr_mask_class_init(ObjectClass *klass, void *data) +static void avr_mask_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/axp2xx.c b/hw/misc/axp2xx.c index af64687..46d1771 100644 --- a/hw/misc/axp2xx.c +++ b/hw/misc/axp2xx.c @@ -225,7 +225,7 @@ static const VMStateDescription vmstate_axp2xx = { } }; -static void axp2xx_class_init(ObjectClass *oc, void *data) +static void axp2xx_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); I2CSlaveClass *isc = I2C_SLAVE_CLASS(oc); @@ -247,7 +247,7 @@ static const TypeInfo axp2xx_info = { .abstract = true, }; -static void axp209_class_init(ObjectClass *oc, void *data) +static void axp209_class_init(ObjectClass *oc, const void *data) { AXP2xxClass *sc = AXP2XX_CLASS(oc); @@ -260,7 +260,7 @@ static const TypeInfo axp209_info = { .class_init = axp209_class_init }; -static void axp221_class_init(ObjectClass *oc, void *data) +static void axp221_class_init(ObjectClass *oc, const void *data) { AXP2xxClass *sc = AXP2XX_CLASS(oc); diff --git a/hw/misc/bcm2835_cprman.c b/hw/misc/bcm2835_cprman.c index 0c4d4b7..efe6f90 100644 --- a/hw/misc/bcm2835_cprman.c +++ b/hw/misc/bcm2835_cprman.c @@ -131,7 +131,7 @@ static const VMStateDescription pll_vmstate = { } }; -static void pll_class_init(ObjectClass *klass, void *data) +static void pll_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -237,7 +237,7 @@ static const VMStateDescription pll_channel_vmstate = { } }; -static void pll_channel_class_init(ObjectClass *klass, void *data) +static void pll_channel_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -360,7 +360,7 @@ static const VMStateDescription clock_mux_vmstate = { } }; -static void clock_mux_class_init(ObjectClass *klass, void *data) +static void clock_mux_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -417,7 +417,7 @@ static const VMStateDescription dsi0hsck_mux_vmstate = { } }; -static void dsi0hsck_mux_class_init(ObjectClass *klass, void *data) +static void dsi0hsck_mux_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -790,7 +790,7 @@ static const Property cprman_properties[] = { DEFINE_PROP_UINT32("xosc-freq-hz", BCM2835CprmanState, xosc_freq, 19200000), }; -static void cprman_class_init(ObjectClass *klass, void *data) +static void cprman_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/bcm2835_mbox.c b/hw/misc/bcm2835_mbox.c index ed6dbea..603eaaa 100644 --- a/hw/misc/bcm2835_mbox.c +++ b/hw/misc/bcm2835_mbox.c @@ -314,7 +314,7 @@ static void bcm2835_mbox_realize(DeviceState *dev, Error **errp) bcm2835_mbox_reset(dev); } -static void bcm2835_mbox_class_init(ObjectClass *klass, void *data) +static void bcm2835_mbox_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/bcm2835_mphi.c b/hw/misc/bcm2835_mphi.c index 7309cf2..55d79e7 100644 --- a/hw/misc/bcm2835_mphi.c +++ b/hw/misc/bcm2835_mphi.c @@ -166,7 +166,7 @@ const VMStateDescription vmstate_mphi_state = { } }; -static void mphi_class_init(ObjectClass *klass, void *data) +static void mphi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/bcm2835_powermgt.c b/hw/misc/bcm2835_powermgt.c index e4e9bae..3ec7aba 100644 --- a/hw/misc/bcm2835_powermgt.c +++ b/hw/misc/bcm2835_powermgt.c @@ -136,7 +136,7 @@ static void bcm2835_powermgt_reset(DeviceState *dev) s->wdog = 0x00000000; } -static void bcm2835_powermgt_class_init(ObjectClass *klass, void *data) +static void bcm2835_powermgt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index 2bae64b..a21c6a5 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -556,7 +556,7 @@ static const Property bcm2835_property_props[] = { DEFINE_PROP_STRING("command-line", BCM2835PropertyState, command_line), }; -static void bcm2835_property_class_init(ObjectClass *klass, void *data) +static void bcm2835_property_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/bcm2835_rng.c b/hw/misc/bcm2835_rng.c index 06f4081..e4d2c22 100644 --- a/hw/misc/bcm2835_rng.c +++ b/hw/misc/bcm2835_rng.c @@ -123,7 +123,7 @@ static void bcm2835_rng_reset(DeviceState *dev) s->rng_status = 0; } -static void bcm2835_rng_class_init(ObjectClass *klass, void *data) +static void bcm2835_rng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/bcm2835_thermal.c b/hw/misc/bcm2835_thermal.c index 1c1b067..33bfc91 100644 --- a/hw/misc/bcm2835_thermal.c +++ b/hw/misc/bcm2835_thermal.c @@ -113,7 +113,7 @@ static const VMStateDescription bcm2835_thermal_vmstate = { } }; -static void bcm2835_thermal_class_init(ObjectClass *klass, void *data) +static void bcm2835_thermal_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/debugexit.c b/hw/misc/debugexit.c index 577b884..04a9fc3 100644 --- a/hw/misc/debugexit.c +++ b/hw/misc/debugexit.c @@ -61,7 +61,7 @@ static const Property debug_exit_properties[] = { DEFINE_PROP_UINT32("iosize", ISADebugExitState, iosize, 0x02), }; -static void debug_exit_class_initfn(ObjectClass *klass, void *data) +static void debug_exit_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/djmemc.c b/hw/misc/djmemc.c index 96d5efb..c5b09f5 100644 --- a/hw/misc/djmemc.c +++ b/hw/misc/djmemc.c @@ -113,7 +113,7 @@ static const VMStateDescription vmstate_djmemc = { } }; -static void djmemc_class_init(ObjectClass *oc, void *data) +static void djmemc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/misc/eccmemctl.c b/hw/misc/eccmemctl.c index d7452c4..81fc536 100644 --- a/hw/misc/eccmemctl.c +++ b/hw/misc/eccmemctl.c @@ -329,7 +329,7 @@ static const Property ecc_properties[] = { DEFINE_PROP_UINT32("version", ECCState, version, -1), }; -static void ecc_class_init(ObjectClass *klass, void *data) +static void ecc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/edu.c b/hw/misc/edu.c index 504178b..cece633 100644 --- a/hw/misc/edu.c +++ b/hw/misc/edu.c @@ -415,7 +415,7 @@ static void edu_instance_init(Object *obj) &edu->dma_mask, OBJ_PROP_FLAG_READWRITE); } -static void edu_class_init(ObjectClass *class, void *data) +static void edu_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); PCIDeviceClass *k = PCI_DEVICE_CLASS(class); @@ -429,21 +429,18 @@ static void edu_class_init(ObjectClass *class, void *data) set_bit(DEVICE_CATEGORY_MISC, dc->categories); } -static void pci_edu_register_types(void) -{ - static InterfaceInfo interfaces[] = { - { INTERFACE_CONVENTIONAL_PCI_DEVICE }, - { }, - }; - static const TypeInfo edu_info = { +static const TypeInfo edu_types[] = { + { .name = TYPE_PCI_EDU_DEVICE, .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(EduState), .instance_init = edu_instance_init, .class_init = edu_class_init, - .interfaces = interfaces, - }; + .interfaces = (const InterfaceInfo[]) { + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { }, + }, + } +}; - type_register_static(&edu_info); -} -type_init(pci_edu_register_types) +DEFINE_TYPES(edu_types) diff --git a/hw/misc/empty_slot.c b/hw/misc/empty_slot.c index 221ea7c..239d760 100644 --- a/hw/misc/empty_slot.c +++ b/hw/misc/empty_slot.c @@ -84,7 +84,7 @@ static const Property empty_slot_properties[] = { DEFINE_PROP_STRING("name", EmptySlot, name), }; -static void empty_slot_class_init(ObjectClass *klass, void *data) +static void empty_slot_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/exynos4210_clk.c b/hw/misc/exynos4210_clk.c index 886d10b..fdf5bdd 100644 --- a/hw/misc/exynos4210_clk.c +++ b/hw/misc/exynos4210_clk.c @@ -141,7 +141,7 @@ static const VMStateDescription exynos4210_clk_vmstate = { } }; -static void exynos4210_clk_class_init(ObjectClass *klass, void *data) +static void exynos4210_clk_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/exynos4210_pmu.c b/hw/misc/exynos4210_pmu.c index d44aac3..a86ec9a 100644 --- a/hw/misc/exynos4210_pmu.c +++ b/hw/misc/exynos4210_pmu.c @@ -498,7 +498,7 @@ static const VMStateDescription exynos4210_pmu_vmstate = { } }; -static void exynos4210_pmu_class_init(ObjectClass *klass, void *data) +static void exynos4210_pmu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/exynos4210_rng.c b/hw/misc/exynos4210_rng.c index a741cf1..2d0ebc4 100644 --- a/hw/misc/exynos4210_rng.c +++ b/hw/misc/exynos4210_rng.c @@ -255,7 +255,7 @@ static const VMStateDescription exynos4210_rng_vmstate = { } }; -static void exynos4210_rng_class_init(ObjectClass *klass, void *data) +static void exynos4210_rng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/grlib_ahb_apb_pnp.c b/hw/misc/grlib_ahb_apb_pnp.c index 5b05f15..cdca00a 100644 --- a/hw/misc/grlib_ahb_apb_pnp.c +++ b/hw/misc/grlib_ahb_apb_pnp.c @@ -168,7 +168,7 @@ static void grlib_ahb_pnp_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &ahb_pnp->iomem); } -static void grlib_ahb_pnp_class_init(ObjectClass *klass, void *data) +static void grlib_ahb_pnp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -280,7 +280,7 @@ static void grlib_apb_pnp_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &apb_pnp->iomem); } -static void grlib_apb_pnp_class_init(ObjectClass *klass, void *data) +static void grlib_apb_pnp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/i2c-echo.c b/hw/misc/i2c-echo.c index fcd407d..2bb99ec 100644 --- a/hw/misc/i2c-echo.c +++ b/hw/misc/i2c-echo.c @@ -145,7 +145,7 @@ static void i2c_echo_realize(DeviceState *dev, Error **errp) state->bh = qemu_bh_new(i2c_echo_bh, state); } -static void i2c_echo_class_init(ObjectClass *oc, void *data) +static void i2c_echo_class_init(ObjectClass *oc, const void *data) { I2CSlaveClass *sc = I2C_SLAVE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c index 9654d23..a6665d5 100644 --- a/hw/misc/imx25_ccm.c +++ b/hw/misc/imx25_ccm.c @@ -292,7 +292,7 @@ static void imx25_ccm_init(Object *obj) sysbus_init_mmio(sd, &s->iomem); } -static void imx25_ccm_class_init(ObjectClass *klass, void *data) +static void imx25_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IMXCCMClass *ccm = IMX_CCM_CLASS(klass); diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c index 93130b2..339458e 100644 --- a/hw/misc/imx31_ccm.c +++ b/hw/misc/imx31_ccm.c @@ -319,7 +319,7 @@ static void imx31_ccm_init(Object *obj) sysbus_init_mmio(sd, &s->iomem); } -static void imx31_ccm_class_init(ObjectClass *klass, void *data) +static void imx31_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IMXCCMClass *ccm = IMX_CCM_CLASS(klass); diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c index 7d522ed..a10b67d 100644 --- a/hw/misc/imx6_ccm.c +++ b/hw/misc/imx6_ccm.c @@ -741,7 +741,7 @@ static void imx6_ccm_init(Object *obj) sysbus_init_mmio(sd, &s->container); } -static void imx6_ccm_class_init(ObjectClass *klass, void *data) +static void imx6_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IMXCCMClass *ccm = IMX_CCM_CLASS(klass); diff --git a/hw/misc/imx6_src.c b/hw/misc/imx6_src.c index 06cc462..8d2c417 100644 --- a/hw/misc/imx6_src.c +++ b/hw/misc/imx6_src.c @@ -273,7 +273,7 @@ static void imx6_src_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } -static void imx6_src_class_init(ObjectClass *klass, void *data) +static void imx6_src_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/imx6ul_ccm.c b/hw/misc/imx6ul_ccm.c index c836dfe..7f3ae61 100644 --- a/hw/misc/imx6ul_ccm.c +++ b/hw/misc/imx6ul_ccm.c @@ -904,7 +904,7 @@ static void imx6ul_ccm_init(Object *obj) sysbus_init_mmio(sd, &s->container); } -static void imx6ul_ccm_class_init(ObjectClass *klass, void *data) +static void imx6ul_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IMXCCMClass *ccm = IMX_CCM_CLASS(klass); diff --git a/hw/misc/imx7_ccm.c b/hw/misc/imx7_ccm.c index c3ecfd7..c061a58 100644 --- a/hw/misc/imx7_ccm.c +++ b/hw/misc/imx7_ccm.c @@ -262,7 +262,7 @@ static uint32_t imx7_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock) return freq; } -static void imx7_ccm_class_init(ObjectClass *klass, void *data) +static void imx7_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IMXCCMClass *ccm = IMX_CCM_CLASS(klass); @@ -293,7 +293,7 @@ static const VMStateDescription vmstate_imx7_analog = { }, }; -static void imx7_analog_class_init(ObjectClass *klass, void *data) +static void imx7_analog_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/imx7_gpr.c b/hw/misc/imx7_gpr.c index b03341a..e12b496 100644 --- a/hw/misc/imx7_gpr.c +++ b/hw/misc/imx7_gpr.c @@ -102,7 +102,7 @@ static void imx7_gpr_init(Object *obj) sysbus_init_mmio(sd, &s->mmio); } -static void imx7_gpr_class_init(ObjectClass *klass, void *data) +static void imx7_gpr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/imx7_snvs.c b/hw/misc/imx7_snvs.c index c8a096b..6a8733d 100644 --- a/hw/misc/imx7_snvs.c +++ b/hw/misc/imx7_snvs.c @@ -143,7 +143,7 @@ static void imx7_snvs_init(Object *obj) qemu_clock_get_ns(rtc_clock) / NANOSECONDS_PER_SECOND; } -static void imx7_snvs_class_init(ObjectClass *klass, void *data) +static void imx7_snvs_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/imx7_src.c b/hw/misc/imx7_src.c index 35341c6..df0b0a6 100644 --- a/hw/misc/imx7_src.c +++ b/hw/misc/imx7_src.c @@ -251,7 +251,7 @@ static void imx7_src_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } -static void imx7_src_class_init(ObjectClass *klass, void *data) +static void imx7_src_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/imx8mp_analog.c b/hw/misc/imx8mp_analog.c index f7e7c83..23ffae8 100644 --- a/hw/misc/imx8mp_analog.c +++ b/hw/misc/imx8mp_analog.c @@ -138,7 +138,7 @@ static const VMStateDescription imx8mp_analog_vmstate = { }, }; -static void imx8mp_analog_class_init(ObjectClass *klass, void *data) +static void imx8mp_analog_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/imx8mp_ccm.c b/hw/misc/imx8mp_ccm.c index 1a1c932..911911e 100644 --- a/hw/misc/imx8mp_ccm.c +++ b/hw/misc/imx8mp_ccm.c @@ -150,7 +150,7 @@ static uint32_t imx8mp_ccm_get_clock_frequency(IMXCCMState *dev, IMXClk clock) return freq; } -static void imx8mp_ccm_class_init(ObjectClass *klass, void *data) +static void imx8mp_ccm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); IMXCCMClass *ccm = IMX_CCM_CLASS(klass); diff --git a/hw/misc/imx_rngc.c b/hw/misc/imx_rngc.c index 0cbf28d..630f6cb 100644 --- a/hw/misc/imx_rngc.c +++ b/hw/misc/imx_rngc.c @@ -254,7 +254,7 @@ static const VMStateDescription vmstate_imx_rngc = { } }; -static void imx_rngc_class_init(ObjectClass *klass, void *data) +static void imx_rngc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/iosb.c b/hw/misc/iosb.c index 31927ea..96221e1 100644 --- a/hw/misc/iosb.c +++ b/hw/misc/iosb.c @@ -111,7 +111,7 @@ static const VMStateDescription vmstate_iosb = { } }; -static void iosb_class_init(ObjectClass *oc, void *data) +static void iosb_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/misc/iotkit-secctl.c b/hw/misc/iotkit-secctl.c index 04ced35..afd9ab4 100644 --- a/hw/misc/iotkit-secctl.c +++ b/hw/misc/iotkit-secctl.c @@ -818,7 +818,7 @@ static const Property iotkit_secctl_props[] = { DEFINE_PROP_UINT32("sse-version", IoTKitSecCtl, sse_version, 0), }; -static void iotkit_secctl_class_init(ObjectClass *klass, void *data) +static void iotkit_secctl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/iotkit-sysctl.c b/hw/misc/iotkit-sysctl.c index c654af2..d70e51a 100644 --- a/hw/misc/iotkit-sysctl.c +++ b/hw/misc/iotkit-sysctl.c @@ -844,7 +844,7 @@ static const Property iotkit_sysctl_props[] = { 0x10000000), }; -static void iotkit_sysctl_class_init(ObjectClass *klass, void *data) +static void iotkit_sysctl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/iotkit-sysinfo.c b/hw/misc/iotkit-sysinfo.c index 75260f7..57405cb 100644 --- a/hw/misc/iotkit-sysinfo.c +++ b/hw/misc/iotkit-sysinfo.c @@ -158,7 +158,7 @@ static void iotkit_sysinfo_realize(DeviceState *dev, Error **errp) } } -static void iotkit_sysinfo_class_init(ObjectClass *klass, void *data) +static void iotkit_sysinfo_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/ivshmem-flat.c b/hw/misc/ivshmem-flat.c index a0ac754..be28c24 100644 --- a/hw/misc/ivshmem-flat.c +++ b/hw/misc/ivshmem-flat.c @@ -17,7 +17,7 @@ #include "hw/qdev-properties-system.h" #include "hw/sysbus.h" #include "chardev/char-fe.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "trace.h" #include "hw/misc/ivshmem-flat.h" @@ -431,7 +431,7 @@ static const Property ivshmem_flat_props[] = { DEFINE_PROP_UINT32("shmem-size", IvshmemFTState, shmem_size, 4 * MiB), }; -static void ivshmem_flat_class_init(ObjectClass *klass, void *data) +static void ivshmem_flat_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/ivshmem-pci.c b/hw/misc/ivshmem-pci.c index 900d523..5a10bca 100644 --- a/hw/misc/ivshmem-pci.c +++ b/hw/misc/ivshmem-pci.c @@ -979,7 +979,7 @@ static int ivshmem_post_load(void *opaque, int version_id) return 0; } -static void ivshmem_common_class_init(ObjectClass *klass, void *data) +static void ivshmem_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1002,7 +1002,7 @@ static const TypeInfo ivshmem_common_info = { .instance_size = sizeof(IVShmemState), .abstract = true, .class_init = ivshmem_common_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -1044,7 +1044,7 @@ static void ivshmem_plain_realize(PCIDevice *dev, Error **errp) ivshmem_common_realize(dev, errp); } -static void ivshmem_plain_class_init(ObjectClass *klass, void *data) +static void ivshmem_plain_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1103,7 +1103,7 @@ static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp) ivshmem_common_realize(dev, errp); } -static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data) +static void ivshmem_doorbell_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/misc/lasi.c b/hw/misc/lasi.c index 24d20ff..9f758c6 100644 --- a/hw/misc/lasi.c +++ b/hw/misc/lasi.c @@ -263,7 +263,7 @@ static void lasi_init(Object *obj) qdev_init_gpio_in(DEVICE(obj), lasi_set_irq, LASI_IRQS); } -static void lasi_class_init(ObjectClass *klass, void *data) +static void lasi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/led.c b/hw/misc/led.c index 9364d99..f7f7090 100644 --- a/hw/misc/led.c +++ b/hw/misc/led.c @@ -107,7 +107,7 @@ static const Property led_properties[] = { DEFINE_PROP_BOOL("gpio-active-high", LEDState, gpio_active_high, true), }; -static void led_class_init(ObjectClass *klass, void *data) +static void led_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mac_via.c b/hw/misc/mac_via.c index 03b1fed..bc37e2a 100644 --- a/hw/misc/mac_via.c +++ b/hw/misc/mac_via.c @@ -16,7 +16,7 @@ */ #include "qemu/osdep.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "migration/vmstate.h" #include "hw/sysbus.h" #include "hw/irq.h" @@ -1326,7 +1326,7 @@ static const Property mos6522_q800_via1_properties[] = { DEFINE_PROP_DRIVE("drive", MOS6522Q800VIA1State, blk), }; -static void mos6522_q800_via1_class_init(ObjectClass *oc, void *data) +static void mos6522_q800_via1_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); @@ -1415,7 +1415,7 @@ static const VMStateDescription vmstate_q800_via2 = { } }; -static void mos6522_q800_via2_class_init(ObjectClass *oc, void *data) +static void mos6522_q800_via2_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c index 34731ae..bcd00c9 100644 --- a/hw/misc/macio/cuda.c +++ b/hw/misc/macio/cuda.c @@ -558,7 +558,7 @@ static const Property cuda_properties[] = { DEFINE_PROP_UINT64("timebase-frequency", CUDAState, tb_frequency, 0), }; -static void cuda_class_init(ObjectClass *oc, void *data) +static void cuda_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -598,7 +598,7 @@ static void mos6522_cuda_reset_hold(Object *obj, ResetType type) ms->timers[1].frequency = (SCALE_US * 6000) / 4700; } -static void mos6522_cuda_class_init(ObjectClass *oc, void *data) +static void mos6522_cuda_class_init(ObjectClass *oc, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(oc); MOS6522DeviceClass *mdc = MOS6522_CLASS(oc); diff --git a/hw/misc/macio/gpio.c b/hw/misc/macio/gpio.c index e87bfca..990551f 100644 --- a/hw/misc/macio/gpio.c +++ b/hw/misc/macio/gpio.c @@ -194,7 +194,7 @@ static void macio_gpio_nmi(NMIState *n, int cpu_index, Error **errp) macio_set_gpio(MACIO_GPIO(n), 9, false); } -static void macio_gpio_class_init(ObjectClass *oc, void *data) +static void macio_gpio_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); @@ -210,7 +210,7 @@ static const TypeInfo macio_gpio_init_info = { .instance_size = sizeof(MacIOGPIOState), .instance_init = macio_gpio_init, .class_init = macio_gpio_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { } }, diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index de0f934..b2b42dd 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -917,7 +917,7 @@ static void mac_dbdma_realize(DeviceState *dev, Error **errp) s->bh = qemu_bh_new_guarded(DBDMA_run_bh, s, &dev->mem_reentrancy_guard); } -static void mac_dbdma_class_init(ObjectClass *oc, void *data) +static void mac_dbdma_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/misc/macio/macio.c b/hw/misc/macio/macio.c index 194b152..6710485 100644 --- a/hw/misc/macio/macio.c +++ b/hw/misc/macio/macio.c @@ -385,7 +385,7 @@ static const VMStateDescription vmstate_macio_oldworld = { } }; -static void macio_oldworld_class_init(ObjectClass *oc, void *data) +static void macio_oldworld_class_init(ObjectClass *oc, const void *data) { PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -410,7 +410,7 @@ static const Property macio_newworld_properties[] = { DEFINE_PROP_BOOL("has-adb", NewWorldMacIOState, has_adb, false), }; -static void macio_newworld_class_init(ObjectClass *oc, void *data) +static void macio_newworld_class_init(ObjectClass *oc, const void *data) { PCIDeviceClass *pdc = PCI_DEVICE_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -425,7 +425,7 @@ static const Property macio_properties[] = { DEFINE_PROP_UINT64("frequency", MacIOState, frequency, 0), }; -static void macio_class_init(ObjectClass *klass, void *data) +static void macio_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -465,7 +465,7 @@ static const TypeInfo macio_type_info = { .instance_init = macio_instance_init, .abstract = true, .class_init = macio_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/misc/macio/pmu.c b/hw/misc/macio/pmu.c index 7319055..3734913 100644 --- a/hw/misc/macio/pmu.c +++ b/hw/misc/macio/pmu.c @@ -764,7 +764,7 @@ static const Property pmu_properties[] = { DEFINE_PROP_BOOL("has-adb", PMUState, has_adb, true), }; -static void pmu_class_init(ObjectClass *oc, void *data) +static void pmu_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -808,7 +808,7 @@ static void mos6522_pmu_reset_hold(Object *obj, ResetType type) s->last_b = ms->b = TACK | TREQ; } -static void mos6522_pmu_class_init(ObjectClass *oc, void *data) +static void mos6522_pmu_class_init(ObjectClass *oc, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(oc); MOS6522DeviceClass *mdc = MOS6522_CLASS(oc); diff --git a/hw/misc/mchp_pfsoc_dmc.c b/hw/misc/mchp_pfsoc_dmc.c index 43d8e97..599f845 100644 --- a/hw/misc/mchp_pfsoc_dmc.c +++ b/hw/misc/mchp_pfsoc_dmc.c @@ -110,7 +110,8 @@ static void mchp_pfsoc_ddr_sgmii_phy_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->sgmii_phy); } -static void mchp_pfsoc_ddr_sgmii_phy_class_init(ObjectClass *klass, void *data) +static void mchp_pfsoc_ddr_sgmii_phy_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -192,7 +193,7 @@ static void mchp_pfsoc_ddr_cfg_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->cfg); } -static void mchp_pfsoc_ddr_cfg_class_init(ObjectClass *klass, void *data) +static void mchp_pfsoc_ddr_cfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mchp_pfsoc_ioscb.c b/hw/misc/mchp_pfsoc_ioscb.c index a71d134..10fc7ea 100644 --- a/hw/misc/mchp_pfsoc_ioscb.c +++ b/hw/misc/mchp_pfsoc_ioscb.c @@ -292,7 +292,7 @@ static void mchp_pfsoc_ioscb_realize(DeviceState *dev, Error **errp) sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); } -static void mchp_pfsoc_ioscb_class_init(ObjectClass *klass, void *data) +static void mchp_pfsoc_ioscb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mchp_pfsoc_sysreg.c b/hw/misc/mchp_pfsoc_sysreg.c index 7876fe0..f47c835 100644 --- a/hw/misc/mchp_pfsoc_sysreg.c +++ b/hw/misc/mchp_pfsoc_sysreg.c @@ -27,7 +27,9 @@ #include "hw/irq.h" #include "hw/sysbus.h" #include "hw/misc/mchp_pfsoc_sysreg.h" +#include "system/runstate.h" +#define MSS_RESET_CR 0x18 #define ENVM_CR 0xb8 #define MESSAGE_INT 0x118c @@ -56,6 +58,11 @@ static void mchp_pfsoc_sysreg_write(void *opaque, hwaddr offset, { MchpPfSoCSysregState *s = opaque; switch (offset) { + case MSS_RESET_CR: + if (value == 0xdead) { + qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET); + } + break; case MESSAGE_INT: qemu_irq_lower(s->irq); break; @@ -85,7 +92,7 @@ static void mchp_pfsoc_sysreg_realize(DeviceState *dev, Error **errp) sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->irq); } -static void mchp_pfsoc_sysreg_class_init(ObjectClass *klass, void *data) +static void mchp_pfsoc_sysreg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c index 95f1991..5484b73 100644 --- a/hw/misc/mips_cmgcr.c +++ b/hw/misc/mips_cmgcr.c @@ -229,7 +229,7 @@ static void mips_gcr_realize(DeviceState *dev, Error **errp) s->vps = g_new(MIPSGCRVPState, s->num_vps); } -static void mips_gcr_class_init(ObjectClass *klass, void *data) +static void mips_gcr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); device_class_set_props(dc, mips_gcr_properties); diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c index b7a13d1..9bfb7c9 100644 --- a/hw/misc/mips_cpc.c +++ b/hw/misc/mips_cpc.c @@ -166,7 +166,7 @@ static const Property mips_cpc_properties[] = { DEFINE_PROP_UINT64("vp-start-running", MIPSCPCState, vp_start_running, 0x1), }; -static void mips_cpc_class_init(ObjectClass *klass, void *data) +static void mips_cpc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c index 2d126eb..fc17385 100644 --- a/hw/misc/mips_itu.c +++ b/hw/misc/mips_itu.c @@ -540,7 +540,7 @@ static const Property mips_itu_properties[] = { ITC_SEMAPH_NUM_MAX), }; -static void mips_itu_class_init(ObjectClass *klass, void *data) +static void mips_itu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mos6522.c b/hw/misc/mos6522.c index 0b8f6a4..8dd6b82 100644 --- a/hw/misc/mos6522.c +++ b/hw/misc/mos6522.c @@ -700,7 +700,7 @@ static const Property mos6522_properties[] = { DEFINE_PROP_UINT64("frequency", MOS6522State, frequency, 0), }; -static void mos6522_class_init(ObjectClass *oc, void *data) +static void mos6522_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c index 04a3da5..bee1309 100644 --- a/hw/misc/mps2-fpgaio.c +++ b/hw/misc/mps2-fpgaio.c @@ -328,7 +328,7 @@ static const Property mps2_fpgaio_properties[] = { DEFINE_PROP_BOOL("has-dbgctrl", MPS2FPGAIO, has_dbgctrl, false), }; -static void mps2_fpgaio_class_init(ObjectClass *klass, void *data) +static void mps2_fpgaio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/mps2-scc.c b/hw/misc/mps2-scc.c index 5f8d6bc..a9a5d4a 100644 --- a/hw/misc/mps2-scc.c +++ b/hw/misc/mps2-scc.c @@ -474,7 +474,7 @@ static const Property mps2_scc_properties[] = { qdev_prop_uint32, uint32_t), }; -static void mps2_scc_class_init(ObjectClass *klass, void *data) +static void mps2_scc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/msf2-sysreg.c b/hw/misc/msf2-sysreg.c index 20009ad..ce0ad50 100644 --- a/hw/misc/msf2-sysreg.c +++ b/hw/misc/msf2-sysreg.c @@ -136,7 +136,7 @@ static void msf2_sysreg_realize(DeviceState *dev, Error **errp) } } -static void msf2_sysreg_class_init(ObjectClass *klass, void *data) +static void msf2_sysreg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/npcm7xx_mft.c b/hw/misc/npcm7xx_mft.c index e565cac..b35e971 100644 --- a/hw/misc/npcm7xx_mft.c +++ b/hw/misc/npcm7xx_mft.c @@ -515,7 +515,7 @@ static const VMStateDescription vmstate_npcm7xx_mft = { }, }; -static void npcm7xx_mft_class_init(ObjectClass *klass, void *data) +static void npcm7xx_mft_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/npcm7xx_pwm.c b/hw/misc/npcm7xx_pwm.c index f7f77e3..2de18d0 100644 --- a/hw/misc/npcm7xx_pwm.c +++ b/hw/misc/npcm7xx_pwm.c @@ -543,7 +543,7 @@ static const VMStateDescription vmstate_npcm7xx_pwm_module = { }, }; -static void npcm7xx_pwm_class_init(ObjectClass *klass, void *data) +static void npcm7xx_pwm_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/npcm7xx_rng.c b/hw/misc/npcm7xx_rng.c index 7f7e5ec..7d47a1c 100644 --- a/hw/misc/npcm7xx_rng.c +++ b/hw/misc/npcm7xx_rng.c @@ -158,7 +158,7 @@ static const VMStateDescription vmstate_npcm7xx_rng = { }, }; -static void npcm7xx_rng_class_init(ObjectClass *klass, void *data) +static void npcm7xx_rng_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/npcm_clk.c b/hw/misc/npcm_clk.c index b6a893f..c48d40b 100644 --- a/hw/misc/npcm_clk.c +++ b/hw/misc/npcm_clk.c @@ -1102,7 +1102,7 @@ static const VMStateDescription vmstate_npcm_clk = { }, }; -static void npcm7xx_clk_pll_class_init(ObjectClass *klass, void *data) +static void npcm7xx_clk_pll_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1112,7 +1112,7 @@ static void npcm7xx_clk_pll_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } -static void npcm7xx_clk_sel_class_init(ObjectClass *klass, void *data) +static void npcm7xx_clk_sel_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1122,7 +1122,7 @@ static void npcm7xx_clk_sel_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } -static void npcm7xx_clk_divider_class_init(ObjectClass *klass, void *data) +static void npcm7xx_clk_divider_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1132,7 +1132,7 @@ static void npcm7xx_clk_divider_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } -static void npcm_clk_class_init(ObjectClass *klass, void *data) +static void npcm_clk_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -1142,7 +1142,7 @@ static void npcm_clk_class_init(ObjectClass *klass, void *data) rc->phases.enter = npcm_clk_enter_reset; } -static void npcm7xx_clk_class_init(ObjectClass *klass, void *data) +static void npcm7xx_clk_class_init(ObjectClass *klass, const void *data) { NPCMCLKClass *c = NPCM_CLK_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -1152,7 +1152,7 @@ static void npcm7xx_clk_class_init(ObjectClass *klass, void *data) c->cold_reset_values = npcm7xx_cold_reset_values; } -static void npcm8xx_clk_class_init(ObjectClass *klass, void *data) +static void npcm8xx_clk_class_init(ObjectClass *klass, const void *data) { NPCMCLKClass *c = NPCM_CLK_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/npcm_gcr.c b/hw/misc/npcm_gcr.c index 4e8ce2c..2acaa16 100644 --- a/hw/misc/npcm_gcr.c +++ b/hw/misc/npcm_gcr.c @@ -422,7 +422,7 @@ static const Property npcm_gcr_properties[] = { DEFINE_PROP_UINT32("power-on-straps", NPCMGCRState, reset_pwron, 0), }; -static void npcm_gcr_class_init(ObjectClass *klass, void *data) +static void npcm_gcr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -432,7 +432,7 @@ static void npcm_gcr_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, npcm_gcr_properties); } -static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data) +static void npcm7xx_gcr_class_init(ObjectClass *klass, const void *data) { NPCMGCRClass *c = NPCM_GCR_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -446,7 +446,7 @@ static void npcm7xx_gcr_class_init(ObjectClass *klass, void *data) rc->phases.enter = npcm7xx_gcr_enter_reset; } -static void npcm8xx_gcr_class_init(ObjectClass *klass, void *data) +static void npcm8xx_gcr_class_init(ObjectClass *klass, const void *data) { NPCMGCRClass *c = NPCM_GCR_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c index 1e67acd..8cd7ffe 100644 --- a/hw/misc/nrf51_rng.c +++ b/hw/misc/nrf51_rng.c @@ -240,7 +240,7 @@ static const VMStateDescription vmstate_rng = { } }; -static void nrf51_rng_class_init(ObjectClass *klass, void *data) +static void nrf51_rng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/omap_clk.c b/hw/misc/omap_clk.c index 0157c9b..da95c4a 100644 --- a/hw/misc/omap_clk.c +++ b/hw/misc/omap_clk.c @@ -30,170 +30,170 @@ struct clk { struct clk *parent; struct clk *child1; struct clk *sibling; -#define ALWAYS_ENABLED (1 << 0) -#define CLOCK_IN_OMAP310 (1 << 10) -#define CLOCK_IN_OMAP730 (1 << 11) -#define CLOCK_IN_OMAP1510 (1 << 12) -#define CLOCK_IN_OMAP16XX (1 << 13) +#define ALWAYS_ENABLED (1 << 0) +#define CLOCK_IN_OMAP310 (1 << 10) +#define CLOCK_IN_OMAP730 (1 << 11) +#define CLOCK_IN_OMAP1510 (1 << 12) +#define CLOCK_IN_OMAP16XX (1 << 13) uint32_t flags; int id; - int running; /* Is currently ticking */ - int enabled; /* Is enabled, regardless of its input clk */ - unsigned long rate; /* Current rate (if .running) */ - unsigned int divisor; /* Rate relative to input (if .enabled) */ - unsigned int multiplier; /* Rate relative to input (if .enabled) */ - qemu_irq users[16]; /* Who to notify on change */ - int usecount; /* Automatically idle when unused */ + int running; /* Is currently ticking */ + int enabled; /* Is enabled, regardless of its input clk */ + unsigned long rate; /* Current rate (if .running) */ + unsigned int divisor; /* Rate relative to input (if .enabled) */ + unsigned int multiplier; /* Rate relative to input (if .enabled) */ + qemu_irq users[16]; /* Who to notify on change */ + int usecount; /* Automatically idle when unused */ }; static struct clk xtal_osc12m = { - .name = "xtal_osc_12m", - .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "xtal_osc_12m", + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk xtal_osc32k = { - .name = "xtal_osc_32k", - .rate = 32768, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "xtal_osc_32k", + .rate = 32768, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk ck_ref = { - .name = "ck_ref", - .alias = "clkin", - .parent = &xtal_osc12m, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "ck_ref", + .alias = "clkin", + .parent = &xtal_osc12m, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; /* If a dpll is disabled it becomes a bypass, child clocks don't stop */ static struct clk dpll1 = { - .name = "dpll1", - .parent = &ck_ref, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "dpll1", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk dpll2 = { - .name = "dpll2", - .parent = &ck_ref, - .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + .name = "dpll2", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk dpll3 = { - .name = "dpll3", - .parent = &ck_ref, - .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + .name = "dpll3", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk dpll4 = { - .name = "dpll4", - .parent = &ck_ref, - .multiplier = 4, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "dpll4", + .parent = &ck_ref, + .multiplier = 4, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk apll = { - .name = "apll", - .parent = &ck_ref, - .multiplier = 48, - .divisor = 12, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "apll", + .parent = &ck_ref, + .multiplier = 48, + .divisor = 12, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk ck_48m = { - .name = "ck_48m", - .parent = &dpll4, /* either dpll4 or apll */ - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "ck_48m", + .parent = &dpll4, /* either dpll4 or apll */ + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk ck_dpll1out = { - .name = "ck_dpll1out", - .parent = &dpll1, - .flags = CLOCK_IN_OMAP16XX, + .name = "ck_dpll1out", + .parent = &dpll1, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk sossi_ck = { - .name = "ck_sossi", - .parent = &ck_dpll1out, - .flags = CLOCK_IN_OMAP16XX, + .name = "ck_sossi", + .parent = &ck_dpll1out, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk clkm1 = { - .name = "clkm1", - .alias = "ck_gen1", - .parent = &dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "clkm1", + .alias = "ck_gen1", + .parent = &dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk clkm2 = { - .name = "clkm2", - .alias = "ck_gen2", - .parent = &dpll1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "clkm2", + .alias = "ck_gen2", + .parent = &dpll1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk clkm3 = { - .name = "clkm3", - .alias = "ck_gen3", - .parent = &dpll1, /* either dpll1 or ck_ref */ - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "clkm3", + .alias = "ck_gen3", + .parent = &dpll1, /* either dpll1 or ck_ref */ + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk arm_ck = { - .name = "arm_ck", - .alias = "mpu_ck", - .parent = &clkm1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "arm_ck", + .alias = "mpu_ck", + .parent = &clkm1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk armper_ck = { - .name = "armper_ck", - .alias = "mpuper_ck", - .parent = &clkm1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "armper_ck", + .alias = "mpuper_ck", + .parent = &clkm1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk arm_gpio_ck = { - .name = "arm_gpio_ck", - .alias = "mpu_gpio_ck", - .parent = &clkm1, - .divisor = 1, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .name = "arm_gpio_ck", + .alias = "mpu_gpio_ck", + .parent = &clkm1, + .divisor = 1, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, }; static struct clk armxor_ck = { - .name = "armxor_ck", - .alias = "mpuxor_ck", - .parent = &ck_ref, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "armxor_ck", + .alias = "mpuxor_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk armtim_ck = { - .name = "armtim_ck", - .alias = "mputim_ck", - .parent = &ck_ref, /* either CLKIN or DPLL1 */ - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "armtim_ck", + .alias = "mputim_ck", + .parent = &ck_ref, /* either CLKIN or DPLL1 */ + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk armwdt_ck = { - .name = "armwdt_ck", - .alias = "mpuwd_ck", - .parent = &clkm1, - .divisor = 14, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "armwdt_ck", + .alias = "mpuwd_ck", + .parent = &clkm1, + .divisor = 14, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk arminth_ck16xx = { - .name = "arminth_ck", - .parent = &arm_ck, - .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, + .name = "arminth_ck", + .parent = &arm_ck, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, /* Note: On 16xx the frequency can be divided by 2 by programming * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1 * @@ -202,48 +202,48 @@ static struct clk arminth_ck16xx = { }; static struct clk dsp_ck = { - .name = "dsp_ck", - .parent = &clkm2, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "dsp_ck", + .parent = &clkm2, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, }; static struct clk dspmmu_ck = { - .name = "dspmmu_ck", - .parent = &clkm2, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .name = "dspmmu_ck", + .parent = &clkm2, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, }; static struct clk dspper_ck = { - .name = "dspper_ck", - .parent = &clkm2, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "dspper_ck", + .parent = &clkm2, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, }; static struct clk dspxor_ck = { - .name = "dspxor_ck", - .parent = &ck_ref, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "dspxor_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, }; static struct clk dsptim_ck = { - .name = "dsptim_ck", - .parent = &ck_ref, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "dsptim_ck", + .parent = &ck_ref, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, }; static struct clk tc_ck = { - .name = "tc_ck", - .parent = &clkm3, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .name = "tc_ck", + .parent = &clkm3, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk arminth_ck15xx = { - .name = "arminth_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + .name = "arminth_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, /* Note: On 1510 the frequency follows TC_CK * * 16xx version is in MPU clocks. @@ -252,259 +252,259 @@ static struct clk arminth_ck15xx = { static struct clk tipb_ck = { /* No-idle controlled by "tc_ck" */ - .name = "tipb_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + .name = "tipb_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk l3_ocpi_ck = { /* No-idle controlled by "tc_ck" */ - .name = "l3_ocpi_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX, + .name = "l3_ocpi_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk tc1_ck = { - .name = "tc1_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX, + .name = "tc1_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk tc2_ck = { - .name = "tc2_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX, + .name = "tc2_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk dma_ck = { /* No-idle controlled by "tc_ck" */ - .name = "dma_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .name = "dma_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk dma_lcdfree_ck = { - .name = "dma_lcdfree_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, + .name = "dma_lcdfree_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, }; static struct clk api_ck = { - .name = "api_ck", - .alias = "mpui_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .name = "api_ck", + .alias = "mpui_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk lb_ck = { - .name = "lb_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .name = "lb_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, }; static struct clk lbfree_ck = { - .name = "lbfree_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .name = "lbfree_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, }; static struct clk hsab_ck = { - .name = "hsab_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .name = "hsab_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, }; static struct clk rhea1_ck = { - .name = "rhea1_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, + .name = "rhea1_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, }; static struct clk rhea2_ck = { - .name = "rhea2_ck", - .parent = &tc_ck, - .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, + .name = "rhea2_ck", + .parent = &tc_ck, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, }; static struct clk lcd_ck_16xx = { - .name = "lcd_ck", - .parent = &clkm3, - .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730, + .name = "lcd_ck", + .parent = &clkm3, + .flags = CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP730, }; static struct clk lcd_ck_1510 = { - .name = "lcd_ck", - .parent = &clkm3, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .name = "lcd_ck", + .parent = &clkm3, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, }; static struct clk uart1_1510 = { - .name = "uart1_ck", + .name = "uart1_ck", /* Direct from ULPD, no real parent */ - .parent = &armper_ck, /* either armper_ck or dpll4 */ - .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + .parent = &armper_ck, /* either armper_ck or dpll4 */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk uart1_16xx = { - .name = "uart1_ck", + .name = "uart1_ck", /* Direct from ULPD, no real parent */ - .parent = &armper_ck, - .rate = 48000000, - .flags = CLOCK_IN_OMAP16XX, + .parent = &armper_ck, + .rate = 48000000, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk uart2_ck = { - .name = "uart2_ck", + .name = "uart2_ck", /* Direct from ULPD, no real parent */ - .parent = &armper_ck, /* either armper_ck or dpll4 */ - .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | + .parent = &armper_ck, /* either armper_ck or dpll4 */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk uart3_1510 = { - .name = "uart3_ck", + .name = "uart3_ck", /* Direct from ULPD, no real parent */ - .parent = &armper_ck, /* either armper_ck or dpll4 */ - .rate = 12000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, + .parent = &armper_ck, /* either armper_ck or dpll4 */ + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310 | ALWAYS_ENABLED, }; static struct clk uart3_16xx = { - .name = "uart3_ck", + .name = "uart3_ck", /* Direct from ULPD, no real parent */ - .parent = &armper_ck, - .rate = 48000000, - .flags = CLOCK_IN_OMAP16XX, + .parent = &armper_ck, + .rate = 48000000, + .flags = CLOCK_IN_OMAP16XX, }; -static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */ - .name = "usb_clk0", - .alias = "usb.clko", +static struct clk usb_clk0 = { /* 6 MHz output on W4_USB_CLK0 */ + .name = "usb_clk0", + .alias = "usb.clko", /* Direct from ULPD, no parent */ - .rate = 6000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .rate = 6000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk usb_hhc_ck1510 = { - .name = "usb_hhc_ck", + .name = "usb_hhc_ck", /* Direct from ULPD, no parent */ - .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, + .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */ + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP310, }; static struct clk usb_hhc_ck16xx = { - .name = "usb_hhc_ck", + .name = "usb_hhc_ck", /* Direct from ULPD, no parent */ - .rate = 48000000, + .rate = 48000000, /* OTG_SYSCON_2.OTG_PADEN == 0 (not 1510-compatible) */ - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk usb_w2fc_mclk = { - .name = "usb_w2fc_mclk", - .alias = "usb_w2fc_ck", - .parent = &ck_48m, - .rate = 48000000, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "usb_w2fc_mclk", + .alias = "usb_w2fc_ck", + .parent = &ck_48m, + .rate = 48000000, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, }; static struct clk mclk_1510 = { - .name = "mclk", + .name = "mclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .rate = 12000000, - .flags = CLOCK_IN_OMAP1510, + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510, }; static struct clk bclk_310 = { - .name = "bt_mclk_out", /* Alias midi_mclk_out? */ - .parent = &armper_ck, - .flags = CLOCK_IN_OMAP310, + .name = "bt_mclk_out", /* Alias midi_mclk_out? */ + .parent = &armper_ck, + .flags = CLOCK_IN_OMAP310, }; static struct clk mclk_310 = { - .name = "com_mclk_out", - .parent = &armper_ck, - .flags = CLOCK_IN_OMAP310, + .name = "com_mclk_out", + .parent = &armper_ck, + .flags = CLOCK_IN_OMAP310, }; static struct clk mclk_16xx = { - .name = "mclk", + .name = "mclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk bclk_1510 = { - .name = "bclk", + .name = "bclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .rate = 12000000, - .flags = CLOCK_IN_OMAP1510, + .rate = 12000000, + .flags = CLOCK_IN_OMAP1510, }; static struct clk bclk_16xx = { - .name = "bclk", + .name = "bclk", /* Direct from ULPD, no parent. May be enabled by ext hardware. */ - .flags = CLOCK_IN_OMAP16XX, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk mmc1_ck = { - .name = "mmc_ck", - .id = 1, + .name = "mmc_ck", + .id = 1, /* Functional clock is direct from ULPD, interface clock is ARMPER */ - .parent = &armper_ck, /* either armper_ck or dpll4 */ - .rate = 48000000, - .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, + .parent = &armper_ck, /* either armper_ck or dpll4 */ + .rate = 48000000, + .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | CLOCK_IN_OMAP310, }; static struct clk mmc2_ck = { - .name = "mmc_ck", - .id = 2, + .name = "mmc_ck", + .id = 2, /* Functional clock is direct from ULPD, interface clock is ARMPER */ - .parent = &armper_ck, - .rate = 48000000, - .flags = CLOCK_IN_OMAP16XX, + .parent = &armper_ck, + .rate = 48000000, + .flags = CLOCK_IN_OMAP16XX, }; static struct clk cam_mclk = { - .name = "cam.mclk", - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, - .rate = 12000000, + .name = "cam.mclk", + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .rate = 12000000, }; static struct clk cam_exclk = { - .name = "cam.exclk", - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "cam.exclk", + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, /* Either 12M from cam.mclk or 48M from dpll4 */ - .parent = &cam_mclk, + .parent = &cam_mclk, }; static struct clk cam_lclk = { - .name = "cam.lclk", - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, + .name = "cam.lclk", + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX, }; static struct clk i2c_fck = { - .name = "i2c_fck", - .id = 1, - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .name = "i2c_fck", + .id = 1, + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, - .parent = &armxor_ck, + .parent = &armxor_ck, }; static struct clk i2c_ick = { - .name = "i2c_ick", - .id = 1, - .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, - .parent = &armper_ck, + .name = "i2c_ick", + .id = 1, + .flags = CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, + .parent = &armper_ck, }; static struct clk clk32k = { - .name = "clk32-kHz", - .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | + .name = "clk32-kHz", + .flags = CLOCK_IN_OMAP310 | CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX | ALWAYS_ENABLED, - .parent = &xtal_osc32k, + .parent = &xtal_osc32k, }; static struct clk *onchip_clks[] = { diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c index e389651..67c486f 100644 --- a/hw/misc/pc-testdev.c +++ b/hw/misc/pc-testdev.c @@ -193,7 +193,7 @@ static void testdev_realizefn(DeviceState *d, Error **errp) memory_region_add_subregion(mem, 0xff000000, &dev->iomem); } -static void testdev_class_init(ObjectClass *klass, void *data) +static void testdev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c index f6718a7..ba71c50 100644 --- a/hw/misc/pci-testdev.c +++ b/hw/misc/pci-testdev.c @@ -90,6 +90,7 @@ struct PCITestDevState { int current; uint64_t membar_size; + bool membar_backed; MemoryRegion membar; }; @@ -258,8 +259,14 @@ static void pci_testdev_realize(PCIDevice *pci_dev, Error **errp) pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &d->portio); if (d->membar_size) { - memory_region_init(&d->membar, OBJECT(d), "pci-testdev-membar", - d->membar_size); + if (d->membar_backed) + memory_region_init_ram(&d->membar, OBJECT(d), + "pci-testdev-membar-backed", + d->membar_size, NULL); + else + memory_region_init(&d->membar, OBJECT(d), + "pci-testdev-membar", + d->membar_size); pci_register_bar(pci_dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_PREFETCH | @@ -321,9 +328,10 @@ static void qdev_pci_testdev_reset(DeviceState *dev) static const Property pci_testdev_properties[] = { DEFINE_PROP_SIZE("membar", PCITestDevState, membar_size, 0), + DEFINE_PROP_BOOL("membar-backed", PCITestDevState, membar_backed, false), }; -static void pci_testdev_class_init(ObjectClass *klass, void *data) +static void pci_testdev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -345,7 +353,7 @@ static const TypeInfo pci_testdev_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCITestDevState), .class_init = pci_testdev_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/misc/pvpanic-isa.c b/hw/misc/pvpanic-isa.c index c3713dc..f7b421c 100644 --- a/hw/misc/pvpanic-isa.c +++ b/hw/misc/pvpanic-isa.c @@ -104,7 +104,7 @@ static const Property pvpanic_isa_properties[] = { PVPANIC_EVENTS), }; -static void pvpanic_isa_class_init(ObjectClass *klass, void *data) +static void pvpanic_isa_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); @@ -121,7 +121,7 @@ static const TypeInfo pvpanic_isa_info = { .instance_size = sizeof(PVPanicISAState), .instance_init = pvpanic_isa_initfn, .class_init = pvpanic_isa_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/misc/pvpanic-mmio.c b/hw/misc/pvpanic-mmio.c index 70097ce..2a36310 100644 --- a/hw/misc/pvpanic-mmio.c +++ b/hw/misc/pvpanic-mmio.c @@ -36,7 +36,7 @@ static const Property pvpanic_mmio_properties[] = { PVPANIC_PANICKED | PVPANIC_CRASH_LOADED), }; -static void pvpanic_mmio_class_init(ObjectClass *klass, void *data) +static void pvpanic_mmio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/pvpanic-pci.c b/hw/misc/pvpanic-pci.c index e5f0788..2869b6a 100644 --- a/hw/misc/pvpanic-pci.c +++ b/hw/misc/pvpanic-pci.c @@ -58,7 +58,7 @@ static const Property pvpanic_pci_properties[] = { PVPANIC_EVENTS), }; -static void pvpanic_pci_class_init(ObjectClass *klass, void *data) +static void pvpanic_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pc = PCI_DEVICE_CLASS(klass); @@ -80,7 +80,7 @@ static const TypeInfo pvpanic_pci_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PVPanicPCIState), .class_init = pvpanic_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } } diff --git a/hw/misc/sbsa_ec.c b/hw/misc/sbsa_ec.c index a1e8136..dfee1af 100644 --- a/hw/misc/sbsa_ec.c +++ b/hw/misc/sbsa_ec.c @@ -73,7 +73,7 @@ static void sbsa_ec_init(Object *obj) sysbus_init_mmio(dev, &s->iomem); } -static void sbsa_ec_class_init(ObjectClass *klass, void *data) +static void sbsa_ec_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/sifive_e_aon.c b/hw/misc/sifive_e_aon.c index 17a522c..6eef38d 100644 --- a/hw/misc/sifive_e_aon.c +++ b/hw/misc/sifive_e_aon.c @@ -294,7 +294,7 @@ static const Property sifive_e_aon_properties[] = { SIFIVE_E_LFCLK_DEFAULT_FREQ), }; -static void sifive_e_aon_class_init(ObjectClass *oc, void *data) +static void sifive_e_aon_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/misc/sifive_u_otp.c b/hw/misc/sifive_u_otp.c index d6df867..1ebed2f 100644 --- a/hw/misc/sifive_u_otp.c +++ b/hw/misc/sifive_u_otp.c @@ -270,7 +270,7 @@ static void sifive_u_otp_realize(DeviceState *dev, Error **errp) memset(s->fuse_wo, 0x00, sizeof(s->fuse_wo)); } -static void sifive_u_otp_class_init(ObjectClass *klass, void *data) +static void sifive_u_otp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/sifive_u_prci.c b/hw/misc/sifive_u_prci.c index cafe6a6..6e75cb6 100644 --- a/hw/misc/sifive_u_prci.c +++ b/hw/misc/sifive_u_prci.c @@ -146,7 +146,7 @@ static void sifive_u_prci_reset(DeviceState *dev) s->coreclksel = SIFIVE_U_PRCI_CORECLKSEL_HFCLK; } -static void sifive_u_prci_class_init(ObjectClass *klass, void *data) +static void sifive_u_prci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/slavio_misc.c b/hw/misc/slavio_misc.c index dace6d2..a034df3 100644 --- a/hw/misc/slavio_misc.c +++ b/hw/misc/slavio_misc.c @@ -483,7 +483,7 @@ static void slavio_misc_init(Object *obj) qdev_init_gpio_in(dev, slavio_set_power_fail, 1); } -static void slavio_misc_class_init(ObjectClass *klass, void *data) +static void slavio_misc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/stm32_rcc.c b/hw/misc/stm32_rcc.c index 26672b5..5815b3e 100644 --- a/hw/misc/stm32_rcc.c +++ b/hw/misc/stm32_rcc.c @@ -60,7 +60,7 @@ static void stm32_rcc_write(void *opaque, hwaddr addr, uint32_t value = val64; uint32_t prev_value, new_value, irq_offset; - trace_stm32_rcc_write(value, addr); + trace_stm32_rcc_write(addr, value); if (addr > STM32_RCC_DCKCFGR2) { qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset 0x%"HWADDR_PRIx"\n", @@ -138,7 +138,7 @@ static const VMStateDescription vmstate_stm32_rcc = { } }; -static void stm32_rcc_class_init(ObjectClass *klass, void *data) +static void stm32_rcc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c index 6c7b722..d285896 100644 --- a/hw/misc/stm32f2xx_syscfg.c +++ b/hw/misc/stm32f2xx_syscfg.c @@ -138,7 +138,7 @@ static void stm32f2xx_syscfg_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); } -static void stm32f2xx_syscfg_class_init(ObjectClass *klass, void *data) +static void stm32f2xx_syscfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/stm32f4xx_exti.c b/hw/misc/stm32f4xx_exti.c index efd996d..0688e6e 100644 --- a/hw/misc/stm32f4xx_exti.c +++ b/hw/misc/stm32f4xx_exti.c @@ -164,7 +164,7 @@ static const VMStateDescription vmstate_stm32f4xx_exti = { } }; -static void stm32f4xx_exti_class_init(ObjectClass *klass, void *data) +static void stm32f4xx_exti_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/stm32f4xx_syscfg.c b/hw/misc/stm32f4xx_syscfg.c index 7d0f3eb..addfb03 100644 --- a/hw/misc/stm32f4xx_syscfg.c +++ b/hw/misc/stm32f4xx_syscfg.c @@ -147,7 +147,7 @@ static const VMStateDescription vmstate_stm32f4xx_syscfg = { } }; -static void stm32f4xx_syscfg_class_init(ObjectClass *klass, void *data) +static void stm32f4xx_syscfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/stm32l4x5_exti.c b/hw/misc/stm32l4x5_exti.c index e281841..9c00216 100644 --- a/hw/misc/stm32l4x5_exti.c +++ b/hw/misc/stm32l4x5_exti.c @@ -271,7 +271,7 @@ static const VMStateDescription vmstate_stm32l4x5_exti = { } }; -static void stm32l4x5_exti_class_init(ObjectClass *klass, void *data) +static void stm32l4x5_exti_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/stm32l4x5_rcc.c b/hw/misc/stm32l4x5_rcc.c index 158b743..0e1f27f 100644 --- a/hw/misc/stm32l4x5_rcc.c +++ b/hw/misc/stm32l4x5_rcc.c @@ -141,7 +141,7 @@ static const VMStateDescription clock_mux_vmstate = { } }; -static void clock_mux_class_init(ObjectClass *klass, void *data) +static void clock_mux_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -295,7 +295,7 @@ static const VMStateDescription pll_vmstate = { } }; -static void pll_class_init(ObjectClass *klass, void *data) +static void pll_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1439,7 +1439,7 @@ static const Property stm32l4x5_rcc_properties[] = { sai2_extclk_frequency, 0), }; -static void stm32l4x5_rcc_class_init(ObjectClass *klass, void *data) +static void stm32l4x5_rcc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/stm32l4x5_syscfg.c b/hw/misc/stm32l4x5_syscfg.c index a947a9e..4e21756 100644 --- a/hw/misc/stm32l4x5_syscfg.c +++ b/hw/misc/stm32l4x5_syscfg.c @@ -259,7 +259,7 @@ static const VMStateDescription vmstate_stm32l4x5_syscfg = { } }; -static void stm32l4x5_syscfg_class_init(ObjectClass *klass, void *data) +static void stm32l4x5_syscfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/trace-events b/hw/misc/trace-events index 4383808..e3f64c0 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -302,6 +302,14 @@ aspeed_peci_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" aspeed_peci_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64 aspeed_peci_raise_interrupt(uint32_t ctrl, uint32_t status) "ctrl 0x%" PRIx32 " status 0x%" PRIx32 +# aspeed_hace.c +aspeed_hace_read(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64 +aspeed_hace_write(uint64_t offset, uint64_t data) "offset 0x%" PRIx64 " data 0x%" PRIx64 +aspeed_hace_hash_sg(int index, uint64_t list_addr, uint64_t buf_addr, uint32_t len) "%d: list_addr 0x%" PRIx64 " buf_addr 0x%" PRIx64 " len 0x%" PRIx32 +aspeed_hace_hash_addr(const char *s, uint64_t addr) "%s: 0x%" PRIx64 +aspeed_hace_hash_execute_acc_mode(bool final_request) "final request: %d" +aspeed_hace_hexdump(const char *desc, uint32_t offset, char *s) "%s: 0x%08x: %s" + # bcm2835_property.c bcm2835_mbox_property(uint32_t tag, uint32_t bufsize, size_t resplen) "mbox property tag:0x%08x in_sz:%u out_sz:%zu" diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c index 6d827d2..a158d4a 100644 --- a/hw/misc/tz-mpc.c +++ b/hw/misc/tz-mpc.c @@ -592,7 +592,7 @@ static const Property tz_mpc_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void tz_mpc_class_init(ObjectClass *klass, void *data) +static void tz_mpc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -611,7 +611,7 @@ static const TypeInfo tz_mpc_info = { }; static void tz_mpc_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/misc/tz-msc.c b/hw/misc/tz-msc.c index 505df4e..af0cc5d 100644 --- a/hw/misc/tz-msc.c +++ b/hw/misc/tz-msc.c @@ -285,7 +285,7 @@ static const Property tz_msc_properties[] = { TYPE_IDAU_INTERFACE, IDAUInterface *), }; -static void tz_msc_class_init(ObjectClass *klass, void *data) +static void tz_msc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/tz-ppc.c b/hw/misc/tz-ppc.c index 1daa54c..e4235a8 100644 --- a/hw/misc/tz-ppc.c +++ b/hw/misc/tz-ppc.c @@ -325,7 +325,7 @@ static const Property tz_ppc_properties[] = { DEFINE_PORT(15), }; -static void tz_ppc_class_init(ObjectClass *klass, void *data) +static void tz_ppc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/unimp.c b/hw/misc/unimp.c index 257282a..4370c14 100644 --- a/hw/misc/unimp.c +++ b/hw/misc/unimp.c @@ -75,7 +75,7 @@ static const Property unimp_properties[] = { DEFINE_PROP_STRING("name", UnimplementedDeviceState, name), }; -static void unimp_class_init(ObjectClass *klass, void *data) +static void unimp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/virt_ctrl.c b/hw/misc/virt_ctrl.c index a210a59..9f16093 100644 --- a/hw/misc/virt_ctrl.c +++ b/hw/misc/virt_ctrl.c @@ -125,7 +125,7 @@ static void virt_ctrl_instance_init(Object *obj) sysbus_init_irq(dev, &s->irq); } -static void virt_ctrl_class_init(ObjectClass *oc, void *data) +static void virt_ctrl_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/misc/vmcoreinfo.c b/hw/misc/vmcoreinfo.c index b0145fa..9c2e900 100644 --- a/hw/misc/vmcoreinfo.c +++ b/hw/misc/vmcoreinfo.c @@ -83,7 +83,7 @@ static const VMStateDescription vmstate_vmcoreinfo = { }, }; -static void vmcoreinfo_device_class_init(ObjectClass *klass, void *data) +static void vmcoreinfo_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/xlnx-versal-cframe-reg.c b/hw/misc/xlnx-versal-cframe-reg.c index 8db0f7e..1ce083e 100644 --- a/hw/misc/xlnx-versal-cframe-reg.c +++ b/hw/misc/xlnx-versal-cframe-reg.c @@ -803,7 +803,7 @@ static const Property cframe_bcast_regs_props[] = { TYPE_XLNX_CFI_IF, XlnxCfiIf *), }; -static void cframe_reg_class_init(ObjectClass *klass, void *data) +static void cframe_reg_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -817,7 +817,7 @@ static void cframe_reg_class_init(ObjectClass *klass, void *data) xcic->cfi_transfer_packet = cframe_reg_cfi_transfer_packet; } -static void cframe_bcast_reg_class_init(ObjectClass *klass, void *data) +static void cframe_bcast_reg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -833,7 +833,7 @@ static const TypeInfo cframe_reg_info = { .instance_size = sizeof(XlnxVersalCFrameReg), .class_init = cframe_reg_class_init, .instance_init = cframe_reg_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XLNX_CFI_IF }, { } } diff --git a/hw/misc/xlnx-versal-cfu.c b/hw/misc/xlnx-versal-cfu.c index 26d06e2..b920fc7 100644 --- a/hw/misc/xlnx-versal-cfu.c +++ b/hw/misc/xlnx-versal-cfu.c @@ -496,7 +496,7 @@ static const VMStateDescription vmstate_cfu_sfr = { } }; -static void cfu_apb_class_init(ObjectClass *klass, void *data) +static void cfu_apb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -505,7 +505,7 @@ static void cfu_apb_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, cfu_props); } -static void cfu_fdro_class_init(ObjectClass *klass, void *data) +static void cfu_fdro_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -516,7 +516,7 @@ static void cfu_fdro_class_init(ObjectClass *klass, void *data) rc->phases.enter = cfu_fdro_reset_enter; } -static void cfu_sfr_class_init(ObjectClass *klass, void *data) +static void cfu_sfr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -532,7 +532,7 @@ static const TypeInfo cfu_apb_info = { .instance_size = sizeof(XlnxVersalCFUAPB), .class_init = cfu_apb_class_init, .instance_init = cfu_apb_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XLNX_CFI_IF }, { } } @@ -545,7 +545,7 @@ static const TypeInfo cfu_fdro_info = { .class_init = cfu_fdro_class_init, .instance_init = cfu_fdro_init, .instance_finalize = cfu_fdro_finalize, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XLNX_CFI_IF }, { } } diff --git a/hw/misc/xlnx-versal-crl.c b/hw/misc/xlnx-versal-crl.c index f143900..08ff2fc 100644 --- a/hw/misc/xlnx-versal-crl.c +++ b/hw/misc/xlnx-versal-crl.c @@ -394,7 +394,7 @@ static const VMStateDescription vmstate_crl = { } }; -static void crl_class_init(ObjectClass *klass, void *data) +static void crl_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/xlnx-versal-pmc-iou-slcr.c b/hw/misc/xlnx-versal-pmc-iou-slcr.c index e469c04..d76df46 100644 --- a/hw/misc/xlnx-versal-pmc-iou-slcr.c +++ b/hw/misc/xlnx-versal-pmc-iou-slcr.c @@ -1419,7 +1419,8 @@ static const VMStateDescription vmstate_pmc_iou_slcr = { } }; -static void xlnx_versal_pmc_iou_slcr_class_init(ObjectClass *klass, void *data) +static void xlnx_versal_pmc_iou_slcr_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/xlnx-versal-trng.c b/hw/misc/xlnx-versal-trng.c index ba93f93..f34dd3e 100644 --- a/hw/misc/xlnx-versal-trng.c +++ b/hw/misc/xlnx-versal-trng.c @@ -682,7 +682,7 @@ static const VMStateDescription vmstate_trng = { } }; -static void trng_class_init(ObjectClass *klass, void *data) +static void trng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/misc/xlnx-versal-xramc.c b/hw/misc/xlnx-versal-xramc.c index d1e76be..07370b8 100644 --- a/hw/misc/xlnx-versal-xramc.c +++ b/hw/misc/xlnx-versal-xramc.c @@ -222,7 +222,7 @@ static const Property xram_ctrl_properties[] = { DEFINE_PROP_UINT64("size", XlnxXramCtrl, cfg.size, 1 * MiB), }; -static void xram_ctrl_class_init(ObjectClass *klass, void *data) +static void xram_ctrl_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/xlnx-zynqmp-apu-ctrl.c b/hw/misc/xlnx-zynqmp-apu-ctrl.c index 87e4a14..e85da32 100644 --- a/hw/misc/xlnx-zynqmp-apu-ctrl.c +++ b/hw/misc/xlnx-zynqmp-apu-ctrl.c @@ -224,7 +224,7 @@ static const VMStateDescription vmstate_zynqmp_apu = { } }; -static void zynqmp_apu_class_init(ObjectClass *klass, void *data) +static void zynqmp_apu_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/xlnx-zynqmp-crf.c b/hw/misc/xlnx-zynqmp-crf.c index e5aba56..cccca0e 100644 --- a/hw/misc/xlnx-zynqmp-crf.c +++ b/hw/misc/xlnx-zynqmp-crf.c @@ -239,7 +239,7 @@ static const VMStateDescription vmstate_crf = { } }; -static void crf_class_init(ObjectClass *klass, void *data) +static void crf_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c index a766bab..010387b 100644 --- a/hw/misc/zynq_slcr.c +++ b/hw/misc/zynq_slcr.c @@ -627,7 +627,7 @@ static const Property zynq_slcr_props[] = { DEFINE_PROP_UINT8("boot-mode", ZynqSLCRState, boot_mode, 1), }; -static void zynq_slcr_class_init(ObjectClass *klass, void *data) +static void zynq_slcr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c index 5adb41d..30a8157 100644 --- a/hw/net/allwinner-sun8i-emac.c +++ b/hw/net/allwinner-sun8i-emac.c @@ -875,7 +875,8 @@ static const VMStateDescription vmstate_aw_emac = { } }; -static void allwinner_sun8i_emac_class_init(ObjectClass *klass, void *data) +static void allwinner_sun8i_emac_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c index 47f1e7f..77d089d 100644 --- a/hw/net/allwinner_emac.c +++ b/hw/net/allwinner_emac.c @@ -514,7 +514,7 @@ static const VMStateDescription vmstate_aw_emac = { } }; -static void aw_emac_class_init(ObjectClass *klass, void *data) +static void aw_emac_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index 80fbbac..50025d5 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -1817,7 +1817,7 @@ static const Property gem_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void gem_class_init(ObjectClass *klass, void *data) +static void gem_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/can/can_kvaser_pci.c b/hw/net/can/can_kvaser_pci.c index 9e363d5..be16769 100644 --- a/hw/net/can/can_kvaser_pci.c +++ b/hw/net/can/can_kvaser_pci.c @@ -282,7 +282,7 @@ static void kvaser_pci_instance_init(Object *obj) 0); } -static void kvaser_pci_class_init(ObjectClass *klass, void *data) +static void kvaser_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -305,7 +305,7 @@ static const TypeInfo kvaser_pci_info = { .instance_size = sizeof(KvaserPCIState), .class_init = kvaser_pci_class_init, .instance_init = kvaser_pci_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/can/can_mioe3680_pci.c b/hw/net/can/can_mioe3680_pci.c index 580f099..44f3ba3 100644 --- a/hw/net/can/can_mioe3680_pci.c +++ b/hw/net/can/can_mioe3680_pci.c @@ -223,7 +223,7 @@ static void mioe3680_pci_instance_init(Object *obj) 0); } -static void mioe3680_pci_class_init(ObjectClass *klass, void *data) +static void mioe3680_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -248,7 +248,7 @@ static const TypeInfo mioe3680_pci_info = { .instance_size = sizeof(Mioe3680PCIState), .class_init = mioe3680_pci_class_init, .instance_init = mioe3680_pci_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/can/can_pcm3680_pci.c b/hw/net/can/can_pcm3680_pci.c index 3195b79..7296d63 100644 --- a/hw/net/can/can_pcm3680_pci.c +++ b/hw/net/can/can_pcm3680_pci.c @@ -224,7 +224,7 @@ static void pcm3680i_pci_instance_init(Object *obj) 0); } -static void pcm3680i_pci_class_init(ObjectClass *klass, void *data) +static void pcm3680i_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -249,7 +249,7 @@ static const TypeInfo pcm3680i_pci_info = { .instance_size = sizeof(Pcm3680iPCIState), .class_init = pcm3680i_pci_class_init, .instance_init = pcm3680i_pci_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/can/ctucan_pci.c b/hw/net/can/ctucan_pci.c index a8c77b9..bed6785 100644 --- a/hw/net/can/ctucan_pci.c +++ b/hw/net/can/ctucan_pci.c @@ -237,7 +237,7 @@ static void ctucan_pci_instance_init(Object *obj) #endif } -static void ctucan_pci_class_init(ObjectClass *klass, void *data) +static void ctucan_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -262,7 +262,7 @@ static const TypeInfo ctucan_pci_info = { .instance_size = sizeof(CtuCanPCIState), .class_init = ctucan_pci_class_init, .instance_init = ctucan_pci_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/can/xlnx-versal-canfd.c b/hw/net/can/xlnx-versal-canfd.c index b5a4a4a..3eb1119 100644 --- a/hw/net/can/xlnx-versal-canfd.c +++ b/hw/net/can/xlnx-versal-canfd.c @@ -1278,7 +1278,7 @@ static void tx_fifo_stamp(XlnxVersalCANFDState *s, uint32_t tb0_regid) } } -static gint g_cmp_ids(gconstpointer data1, gconstpointer data2) +static gint g_cmp_ids(gconstpointer data1, gconstpointer data2, gpointer d) { tx_ready_reg_info *tx_reg_1 = (tx_ready_reg_info *) data1; tx_ready_reg_info *tx_reg_2 = (tx_ready_reg_info *) data2; @@ -1316,7 +1316,7 @@ static GSList *prepare_tx_data(XlnxVersalCANFDState *s) temp->can_id = s->regs[reg_num]; temp->reg_num = reg_num; list = g_slist_prepend(list, temp); - list = g_slist_sort(list, g_cmp_ids); + list = g_slist_sort_with_data(list, g_cmp_ids, NULL); } reg_ready >>= 1; @@ -2052,7 +2052,7 @@ static const Property canfd_core_properties[] = { CanBusState *), }; -static void canfd_class_init(ObjectClass *klass, void *data) +static void canfd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/can/xlnx-zynqmp-can.c b/hw/net/can/xlnx-zynqmp-can.c index 9fbdeea..ca9edd4 100644 --- a/hw/net/can/xlnx-zynqmp-can.c +++ b/hw/net/can/xlnx-zynqmp-can.c @@ -1176,7 +1176,7 @@ static const Property xlnx_zynqmp_can_properties[] = { CanBusState *), }; -static void xlnx_zynqmp_can_class_init(ObjectClass *klass, void *data) +static void xlnx_zynqmp_can_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c index c80ddb1..d490320 100644 --- a/hw/net/dp8393x.c +++ b/hw/net/dp8393x.c @@ -939,7 +939,7 @@ static const Property dp8393x_properties[] = { DEFINE_PROP_BOOL("big_endian", dp8393xState, big_endian, false), }; -static void dp8393x_class_init(ObjectClass *klass, void *data) +static void dp8393x_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/e1000.c b/hw/net/e1000.c index 3d0b227..a80a7b0 100644 --- a/hw/net/e1000.c +++ b/hw/net/e1000.c @@ -127,10 +127,8 @@ struct E1000State_st { QEMUTimer *flush_queue_timer; /* Compatibility flags for migration to/from qemu 1.3.0 and older */ -#define E1000_FLAG_MAC_BIT 2 #define E1000_FLAG_TSO_BIT 3 #define E1000_FLAG_VET_BIT 4 -#define E1000_FLAG_MAC (1 << E1000_FLAG_MAC_BIT) #define E1000_FLAG_TSO (1 << E1000_FLAG_TSO_BIT) #define E1000_FLAG_VET (1 << E1000_FLAG_VET_BIT) @@ -1212,52 +1210,51 @@ enum { NWRITEOPS = ARRAY_SIZE(macreg_writeops) }; enum { MAC_ACCESS_PARTIAL = 1, MAC_ACCESS_FLAG_NEEDED = 2 }; -#define markflag(x) ((E1000_FLAG_##x << 2) | MAC_ACCESS_FLAG_NEEDED) /* In the array below the meaning of the bits is: [f|f|f|f|f|f|n|p] * f - flag bits (up to 6 possible flags) * n - flag needed - * p - partially implenented */ + * p - partially implemented */ static const uint8_t mac_reg_access[0x8000] = { - [IPAV] = markflag(MAC), [WUC] = markflag(MAC), - [IP6AT] = markflag(MAC), [IP4AT] = markflag(MAC), - [FFVT] = markflag(MAC), [WUPM] = markflag(MAC), - [ECOL] = markflag(MAC), [MCC] = markflag(MAC), - [DC] = markflag(MAC), [TNCRS] = markflag(MAC), - [RLEC] = markflag(MAC), [XONRXC] = markflag(MAC), - [XOFFTXC] = markflag(MAC), [RFC] = markflag(MAC), - [TSCTFC] = markflag(MAC), [MGTPRC] = markflag(MAC), - [WUS] = markflag(MAC), [AIT] = markflag(MAC), - [FFLT] = markflag(MAC), [FFMT] = markflag(MAC), - [SCC] = markflag(MAC), [FCRUC] = markflag(MAC), - [LATECOL] = markflag(MAC), [COLC] = markflag(MAC), - [SEQEC] = markflag(MAC), [CEXTERR] = markflag(MAC), - [XONTXC] = markflag(MAC), [XOFFRXC] = markflag(MAC), - [RJC] = markflag(MAC), [RNBC] = markflag(MAC), - [MGTPDC] = markflag(MAC), [MGTPTC] = markflag(MAC), - [RUC] = markflag(MAC), [ROC] = markflag(MAC), - [GORCL] = markflag(MAC), [GORCH] = markflag(MAC), - [GOTCL] = markflag(MAC), [GOTCH] = markflag(MAC), - [BPRC] = markflag(MAC), [MPRC] = markflag(MAC), - [TSCTC] = markflag(MAC), [PRC64] = markflag(MAC), - [PRC127] = markflag(MAC), [PRC255] = markflag(MAC), - [PRC511] = markflag(MAC), [PRC1023] = markflag(MAC), - [PRC1522] = markflag(MAC), [PTC64] = markflag(MAC), - [PTC127] = markflag(MAC), [PTC255] = markflag(MAC), - [PTC511] = markflag(MAC), [PTC1023] = markflag(MAC), - [PTC1522] = markflag(MAC), [MPTC] = markflag(MAC), - [BPTC] = markflag(MAC), - - [TDFH] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [TDFT] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [TDFHS] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [TDFTS] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [TDFPC] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [RDFH] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [RDFT] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [RDFHS] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [RDFTS] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [RDFPC] = markflag(MAC) | MAC_ACCESS_PARTIAL, - [PBM] = markflag(MAC) | MAC_ACCESS_PARTIAL, + [IPAV] = MAC_ACCESS_FLAG_NEEDED, [WUC] = MAC_ACCESS_FLAG_NEEDED, + [IP6AT] = MAC_ACCESS_FLAG_NEEDED, [IP4AT] = MAC_ACCESS_FLAG_NEEDED, + [FFVT] = MAC_ACCESS_FLAG_NEEDED, [WUPM] = MAC_ACCESS_FLAG_NEEDED, + [ECOL] = MAC_ACCESS_FLAG_NEEDED, [MCC] = MAC_ACCESS_FLAG_NEEDED, + [DC] = MAC_ACCESS_FLAG_NEEDED, [TNCRS] = MAC_ACCESS_FLAG_NEEDED, + [RLEC] = MAC_ACCESS_FLAG_NEEDED, [XONRXC] = MAC_ACCESS_FLAG_NEEDED, + [XOFFTXC] = MAC_ACCESS_FLAG_NEEDED, [RFC] = MAC_ACCESS_FLAG_NEEDED, + [TSCTFC] = MAC_ACCESS_FLAG_NEEDED, [MGTPRC] = MAC_ACCESS_FLAG_NEEDED, + [WUS] = MAC_ACCESS_FLAG_NEEDED, [AIT] = MAC_ACCESS_FLAG_NEEDED, + [FFLT] = MAC_ACCESS_FLAG_NEEDED, [FFMT] = MAC_ACCESS_FLAG_NEEDED, + [SCC] = MAC_ACCESS_FLAG_NEEDED, [FCRUC] = MAC_ACCESS_FLAG_NEEDED, + [LATECOL] = MAC_ACCESS_FLAG_NEEDED, [COLC] = MAC_ACCESS_FLAG_NEEDED, + [SEQEC] = MAC_ACCESS_FLAG_NEEDED, [CEXTERR] = MAC_ACCESS_FLAG_NEEDED, + [XONTXC] = MAC_ACCESS_FLAG_NEEDED, [XOFFRXC] = MAC_ACCESS_FLAG_NEEDED, + [RJC] = MAC_ACCESS_FLAG_NEEDED, [RNBC] = MAC_ACCESS_FLAG_NEEDED, + [MGTPDC] = MAC_ACCESS_FLAG_NEEDED, [MGTPTC] = MAC_ACCESS_FLAG_NEEDED, + [RUC] = MAC_ACCESS_FLAG_NEEDED, [ROC] = MAC_ACCESS_FLAG_NEEDED, + [GORCL] = MAC_ACCESS_FLAG_NEEDED, [GORCH] = MAC_ACCESS_FLAG_NEEDED, + [GOTCL] = MAC_ACCESS_FLAG_NEEDED, [GOTCH] = MAC_ACCESS_FLAG_NEEDED, + [BPRC] = MAC_ACCESS_FLAG_NEEDED, [MPRC] = MAC_ACCESS_FLAG_NEEDED, + [TSCTC] = MAC_ACCESS_FLAG_NEEDED, [PRC64] = MAC_ACCESS_FLAG_NEEDED, + [PRC127] = MAC_ACCESS_FLAG_NEEDED, [PRC255] = MAC_ACCESS_FLAG_NEEDED, + [PRC511] = MAC_ACCESS_FLAG_NEEDED, [PRC1023] = MAC_ACCESS_FLAG_NEEDED, + [PRC1522] = MAC_ACCESS_FLAG_NEEDED, [PTC64] = MAC_ACCESS_FLAG_NEEDED, + [PTC127] = MAC_ACCESS_FLAG_NEEDED, [PTC255] = MAC_ACCESS_FLAG_NEEDED, + [PTC511] = MAC_ACCESS_FLAG_NEEDED, [PTC1023] = MAC_ACCESS_FLAG_NEEDED, + [PTC1522] = MAC_ACCESS_FLAG_NEEDED, [MPTC] = MAC_ACCESS_FLAG_NEEDED, + [BPTC] = MAC_ACCESS_FLAG_NEEDED, + + [TDFH] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [TDFT] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [TDFHS] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [TDFTS] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [TDFPC] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [RDFH] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [RDFT] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [RDFHS] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [RDFTS] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [RDFPC] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, + [PBM] = MAC_ACCESS_FLAG_NEEDED | MAC_ACCESS_PARTIAL, }; static void @@ -1419,13 +1416,6 @@ static int e1000_tx_tso_post_load(void *opaque, int version_id) return 0; } -static bool e1000_full_mac_needed(void *opaque) -{ - E1000State *s = opaque; - - return chkflag(MAC); -} - static bool e1000_tso_state_needed(void *opaque) { E1000State *s = opaque; @@ -1451,7 +1441,6 @@ static const VMStateDescription vmstate_e1000_full_mac_state = { .name = "e1000/full_mac_state", .version_id = 1, .minimum_version_id = 1, - .needed = e1000_full_mac_needed, .fields = (const VMStateField[]) { VMSTATE_UINT32_ARRAY(mac_reg, E1000State, 0x8000), VMSTATE_END_OF_LIST() @@ -1679,8 +1668,6 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp) static const Property e1000_properties[] = { DEFINE_NIC_PROPERTIES(E1000State, conf), - DEFINE_PROP_BIT("extra_mac_registers", E1000State, - compat_flags, E1000_FLAG_MAC_BIT, true), DEFINE_PROP_BIT("migrate_tso_props", E1000State, compat_flags, E1000_FLAG_TSO_BIT, true), DEFINE_PROP_BIT("init-vet", E1000State, @@ -1694,7 +1681,7 @@ typedef struct E1000Info { uint16_t phy_id2; } E1000Info; -static void e1000_class_init(ObjectClass *klass, void *data) +static void e1000_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1732,7 +1719,7 @@ static const TypeInfo e1000_base_info = { .instance_init = e1000_instance_init, .class_size = sizeof(E1000BaseClass), .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -1770,7 +1757,7 @@ static void e1000_register_types(void) type_info.name = info->name; type_info.parent = TYPE_E1000_BASE; - type_info.class_data = (void *)info; + type_info.class_data = info; type_info.class_init = e1000_class_init; type_register_static(&type_info); diff --git a/hw/net/e1000e.c b/hw/net/e1000e.c index b72cbab..89e6d52 100644 --- a/hw/net/e1000e.c +++ b/hw/net/e1000e.c @@ -673,7 +673,7 @@ static const Property e1000e_properties[] = { DEFINE_PROP_BOOL("migrate-timadj", E1000EState, timadj, true), }; -static void e1000e_class_init(ObjectClass *class, void *data) +static void e1000e_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); ResettableClass *rc = RESETTABLE_CLASS(class); @@ -721,7 +721,7 @@ static const TypeInfo e1000e_info = { .instance_size = sizeof(E1000EState), .class_init = e1000e_class_init, .instance_init = e1000e_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/net/e1000x_regs.h b/hw/net/e1000x_regs.h index cd896fc..e9a74de 100644 --- a/hw/net/e1000x_regs.h +++ b/hw/net/e1000x_regs.h @@ -900,7 +900,7 @@ struct e1000_context_desc { uint16_t tucse; /* TCP checksum end */ } tcp_fields; } upper_setup; - uint32_t cmd_and_length; /* */ + uint32_t cmd_and_length; union { uint32_t data; struct { diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c index 29a3986..d47df5a 100644 --- a/hw/net/eepro100.c +++ b/hw/net/eepro100.c @@ -2060,7 +2060,7 @@ static const Property e100_properties[] = { DEFINE_NIC_PROPERTIES(EEPRO100State, conf), }; -static void eepro100_class_init(ObjectClass *klass, void *data) +static void eepro100_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -2094,7 +2094,7 @@ static void eepro100_register_types(void) type_info.class_init = eepro100_class_init; type_info.instance_size = sizeof(EEPRO100State); type_info.instance_init = eepro100_instance_init; - type_info.interfaces = (InterfaceInfo[]) { + type_info.interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }; diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c index adde644..846f6cb 100644 --- a/hw/net/fsl_etsec/etsec.c +++ b/hw/net/fsl_etsec/etsec.c @@ -389,6 +389,7 @@ static void etsec_realize(DeviceState *dev, Error **errp) { eTSEC *etsec = ETSEC_COMMON(dev); + qemu_macaddr_default_if_unset(&etsec->conf.macaddr); etsec->nic = qemu_new_nic(&net_etsec_info, &etsec->conf, object_get_typename(OBJECT(dev)), dev->id, &dev->mem_reentrancy_guard, etsec); @@ -418,7 +419,7 @@ static const Property etsec_properties[] = { DEFINE_NIC_PROPERTIES(eTSEC, conf), }; -static void etsec_class_init(ObjectClass *klass, void *data) +static void etsec_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index 1f524d7..c41ce88 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -1260,7 +1260,7 @@ static const Property ftgmac100_properties[] = { DEFINE_PROP_BOOL("dma64", FTGMAC100State, dma64, false), }; -static void ftgmac100_class_init(ObjectClass *klass, void *data) +static void ftgmac100_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1419,7 +1419,7 @@ static const Property aspeed_mii_properties[] = { FTGMAC100State *), }; -static void aspeed_mii_class_init(ObjectClass *klass, void *data) +static void aspeed_mii_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/i82596.c b/hw/net/i82596.c index ee919da..c1ff3e6 100644 --- a/hw/net/i82596.c +++ b/hw/net/i82596.c @@ -5,7 +5,7 @@ * This work is licensed under the GNU GPL license version 2 or later. * * This software was written to be compatible with the specification: - * https://www.intel.com/assets/pdf/general/82596ca.pdf + * https://parisc.docs.kernel.org/en/latest/_downloads/96672be0650d9fc046bbcea40b92482f/82596CA.pdf */ #include "qemu/osdep.h" @@ -15,7 +15,7 @@ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qemu/module.h" #include "trace.h" #include "i82596.h" @@ -177,6 +177,26 @@ static void set_individual_address(I82596State *s, uint32_t addr) trace_i82596_new_mac(nc->info_str); } +static void i82596_configure(I82596State *s, uint32_t addr) +{ + uint8_t byte_cnt; + byte_cnt = get_byte(addr + 8) & 0x0f; + + byte_cnt = MAX(byte_cnt, 4); + byte_cnt = MIN(byte_cnt, sizeof(s->config)); + /* copy byte_cnt max. */ + address_space_read(&address_space_memory, addr + 8, + MEMTXATTRS_UNSPECIFIED, s->config, byte_cnt); + /* config byte according to page 35ff */ + s->config[2] &= 0x82; /* mask valid bits */ + s->config[2] |= 0x40; + s->config[7] &= 0xf7; /* clear zero bit */ + assert(I596_NOCRC_INS == 0); /* do CRC insertion */ + s->config[10] = MAX(s->config[10], 5); /* min frame length */ + s->config[12] &= 0x40; /* only full duplex field valid */ + s->config[13] |= 0x3f; /* set ones in byte 13 */ +} + static void set_multicast_list(I82596State *s, uint32_t addr) { uint16_t mc_count, i; @@ -234,7 +254,6 @@ static void command_loop(I82596State *s) { uint16_t cmd; uint16_t status; - uint8_t byte_cnt; DBG(printf("STARTING COMMAND LOOP cmd_p=%08x\n", s->cmd_p)); @@ -254,20 +273,7 @@ static void command_loop(I82596State *s) set_individual_address(s, s->cmd_p); break; case CmdConfigure: - byte_cnt = get_byte(s->cmd_p + 8) & 0x0f; - byte_cnt = MAX(byte_cnt, 4); - byte_cnt = MIN(byte_cnt, sizeof(s->config)); - /* copy byte_cnt max. */ - address_space_read(&address_space_memory, s->cmd_p + 8, - MEMTXATTRS_UNSPECIFIED, s->config, byte_cnt); - /* config byte according to page 35ff */ - s->config[2] &= 0x82; /* mask valid bits */ - s->config[2] |= 0x40; - s->config[7] &= 0xf7; /* clear zero bit */ - assert(I596_NOCRC_INS == 0); /* do CRC insertion */ - s->config[10] = MAX(s->config[10], 5); /* min frame length */ - s->config[12] &= 0x40; /* only full duplex field valid */ - s->config[13] |= 0x3f; /* set ones in byte 13 */ + i82596_configure(s, s->cmd_p); break; case CmdTDR: /* get signal LINK */ diff --git a/hw/net/i82596.h b/hw/net/i82596.h index f0bbe81..dc1fa1a 100644 --- a/hw/net/i82596.h +++ b/hw/net/i82596.h @@ -3,8 +3,8 @@ #define I82596_IOPORT_SIZE 0x20 -#include "exec/memory.h" -#include "exec/address-spaces.h" +#include "system/memory.h" +#include "system/address-spaces.h" #define PORT_RESET 0x00 /* reset 82596 */ #define PORT_SELFTEST 0x01 /* selftest */ diff --git a/hw/net/igb.c b/hw/net/igb.c index e318df4..e4c0236 100644 --- a/hw/net/igb.c +++ b/hw/net/igb.c @@ -599,7 +599,7 @@ static const Property igb_properties[] = { DEFINE_PROP_BOOL("x-pcie-flr-init", IGBState, has_flr, true), }; -static void igb_class_init(ObjectClass *class, void *data) +static void igb_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); ResettableClass *rc = RESETTABLE_CLASS(class); @@ -635,7 +635,7 @@ static const TypeInfo igb_info = { .instance_size = sizeof(IGBState), .class_init = igb_class_init, .instance_init = igb_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/net/igbvf.c b/hw/net/igbvf.c index 21a97d4..31d72c4 100644 --- a/hw/net/igbvf.c +++ b/hw/net/igbvf.c @@ -299,7 +299,7 @@ static void igbvf_pci_uninit(PCIDevice *dev) msix_uninit(dev, &s->msix, &s->msix); } -static void igbvf_class_init(ObjectClass *class, void *data) +static void igbvf_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); PCIDeviceClass *c = PCI_DEVICE_CLASS(class); @@ -325,7 +325,7 @@ static const TypeInfo igbvf_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(IgbVfState), .class_init = igbvf_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c index b7c9ee0..e5e34dd 100644 --- a/hw/net/imx_fec.c +++ b/hw/net/imx_fec.c @@ -1230,7 +1230,7 @@ static const Property imx_eth_properties[] = { IMXFECState *), }; -static void imx_eth_class_init(ObjectClass *klass, void *data) +static void imx_eth_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c index afee68c..6dda1e5 100644 --- a/hw/net/lan9118.c +++ b/hw/net/lan9118.c @@ -1309,7 +1309,7 @@ static const Property lan9118_properties[] = { DEFINE_PROP_UINT32("mode_16bit", lan9118_state, mode_16bit, 0), }; -static void lan9118_class_init(ObjectClass *klass, void *data) +static void lan9118_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/lan9118_phy.c b/hw/net/lan9118_phy.c index 5c53a4a..4c4e03d 100644 --- a/hw/net/lan9118_phy.c +++ b/hw/net/lan9118_phy.c @@ -200,7 +200,7 @@ static const VMStateDescription vmstate_lan9118_phy = { } }; -static void lan9118_phy_class_init(ObjectClass *klass, void *data) +static void lan9118_phy_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/lance.c b/hw/net/lance.c index 1549238..dfb855c 100644 --- a/hw/net/lance.c +++ b/hw/net/lance.c @@ -143,7 +143,7 @@ static const Property lance_properties[] = { DEFINE_NIC_PROPERTIES(SysBusPCNetState, state.conf), }; -static void lance_class_init(ObjectClass *klass, void *data) +static void lance_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/lasi_i82596.c b/hw/net/lasi_i82596.c index cad01f5..9e1dd21 100644 --- a/hw/net/lasi_i82596.c +++ b/hw/net/lasi_i82596.c @@ -162,7 +162,7 @@ static const Property lasi_82596_properties[] = { DEFINE_NIC_PROPERTIES(SysBusI82596State, state.conf), }; -static void lasi_82596_class_init(ObjectClass *klass, void *data) +static void lasi_82596_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c index d5572a8..ae128fa 100644 --- a/hw/net/mcf_fec.c +++ b/hw/net/mcf_fec.c @@ -664,7 +664,7 @@ static const Property mcf_fec_properties[] = { DEFINE_NIC_PROPERTIES(mcf_fec_state, conf), }; -static void mcf_fec_class_init(ObjectClass *oc, void *data) +static void mcf_fec_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c index 8852b6f..583aa1c 100644 --- a/hw/net/mipsnet.c +++ b/hw/net/mipsnet.c @@ -270,7 +270,7 @@ static const Property mipsnet_properties[] = { DEFINE_NIC_PROPERTIES(MIPSnetState, conf), }; -static void mipsnet_class_init(ObjectClass *klass, void *data) +static void mipsnet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/msf2-emac.c b/hw/net/msf2-emac.c index 80f75f1..5904597 100644 --- a/hw/net/msf2-emac.c +++ b/hw/net/msf2-emac.c @@ -565,7 +565,7 @@ static const VMStateDescription vmstate_msf2_emac = { } }; -static void msf2_emac_class_init(ObjectClass *klass, void *data) +static void msf2_emac_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/mv88w8618_eth.c b/hw/net/mv88w8618_eth.c index 5a9d14b..6f08846 100644 --- a/hw/net/mv88w8618_eth.c +++ b/hw/net/mv88w8618_eth.c @@ -377,7 +377,7 @@ static const Property mv88w8618_eth_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void mv88w8618_eth_class_init(ObjectClass *klass, void *data) +static void mv88w8618_eth_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c index 2097365..673c785 100644 --- a/hw/net/ne2000-isa.c +++ b/hw/net/ne2000-isa.c @@ -85,7 +85,7 @@ static const Property ne2000_isa_properties[] = { DEFINE_NIC_PROPERTIES(ISANE2000State, ne2000.c), }; -static void isa_ne2000_class_initfn(ObjectClass *klass, void *data) +static void isa_ne2000_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/ne2000-pci.c b/hw/net/ne2000-pci.c index 6840d0e..ce937e1 100644 --- a/hw/net/ne2000-pci.c +++ b/hw/net/ne2000-pci.c @@ -100,7 +100,7 @@ static const Property ne2000_properties[] = { DEFINE_NIC_PROPERTIES(PCINE2000State, ne2000.c), }; -static void ne2000_class_init(ObjectClass *klass, void *data) +static void ne2000_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -122,7 +122,7 @@ static const TypeInfo ne2000_info = { .instance_size = sizeof(PCINE2000State), .class_init = ne2000_class_init, .instance_init = ne2000_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c index b482c5f..b1923c8 100644 --- a/hw/net/ne2000.c +++ b/hw/net/ne2000.c @@ -25,7 +25,7 @@ #include "qemu/osdep.h" #include "net/eth.h" #include "qemu/module.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/irq.h" #include "migration/vmstate.h" #include "ne2000.h" diff --git a/hw/net/npcm7xx_emc.c b/hw/net/npcm7xx_emc.c index e06f652..9ba35e2 100644 --- a/hw/net/npcm7xx_emc.c +++ b/hw/net/npcm7xx_emc.c @@ -849,7 +849,7 @@ static const Property npcm7xx_emc_properties[] = { DEFINE_NIC_PROPERTIES(NPCM7xxEMCState, conf), }; -static void npcm7xx_emc_class_init(ObjectClass *klass, void *data) +static void npcm7xx_emc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/npcm_gmac.c b/hw/net/npcm_gmac.c index e1fb383..a434112 100644 --- a/hw/net/npcm_gmac.c +++ b/hw/net/npcm_gmac.c @@ -916,7 +916,7 @@ static const Property npcm_gmac_properties[] = { DEFINE_NIC_PROPERTIES(NPCMGMACState, conf), }; -static void npcm_gmac_class_init(ObjectClass *klass, void *data) +static void npcm_gmac_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/npcm_pcs.c b/hw/net/npcm_pcs.c index ce5034e..6aec105 100644 --- a/hw/net/npcm_pcs.c +++ b/hw/net/npcm_pcs.c @@ -387,7 +387,7 @@ static const VMStateDescription vmstate_npcm_pcs = { }, }; -static void npcm_pcs_class_init(ObjectClass *klass, void *data) +static void npcm_pcs_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c index 54daab7..7e955c0 100644 --- a/hw/net/opencores_eth.c +++ b/hw/net/opencores_eth.c @@ -747,7 +747,7 @@ static const Property open_eth_properties[] = { DEFINE_NIC_PROPERTIES(OpenEthState, conf), }; -static void open_eth_class_init(ObjectClass *klass, void *data) +static void open_eth_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c index b314ea7..0ca5bc2 100644 --- a/hw/net/pcnet-pci.c +++ b/hw/net/pcnet-pci.c @@ -256,7 +256,7 @@ static const Property pcnet_properties[] = { DEFINE_NIC_PROPERTIES(PCIPCNetState, state.conf), }; -static void pcnet_class_init(ObjectClass *klass, void *data) +static void pcnet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -280,7 +280,7 @@ static const TypeInfo pcnet_info = { .instance_size = sizeof(PCIPCNetState), .class_init = pcnet_class_init, .instance_init = pcnet_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h index eb7f46a..a94356e 100644 --- a/hw/net/pcnet.h +++ b/hw/net/pcnet.h @@ -7,7 +7,7 @@ #define PCNET_LOOPTEST_CRC 1 #define PCNET_LOOPTEST_NOCRC 2 -#include "exec/memory.h" +#include "system/memory.h" #include "hw/irq.h" /* BUS CONFIGURATION REGISTERS */ diff --git a/hw/net/rocker/rocker.c b/hw/net/rocker/rocker.c index aa5d87f..cc49701 100644 --- a/hw/net/rocker/rocker.c +++ b/hw/net/rocker/rocker.c @@ -1475,7 +1475,7 @@ static const VMStateDescription rocker_vmsd = { .unmigratable = 1, }; -static void rocker_class_init(ObjectClass *klass, void *data) +static void rocker_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1498,7 +1498,7 @@ static const TypeInfo rocker_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(Rocker), .class_init = rocker_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/rocker/rocker.h b/hw/net/rocker/rocker.h index 6e0962f..ae06c1c 100644 --- a/hw/net/rocker/rocker.h +++ b/hw/net/rocker/rocker.h @@ -36,15 +36,7 @@ static inline G_GNUC_PRINTF(1, 2) int DPRINTF(const char *fmt, ...) } #endif -#define __le16 uint16_t -#define __le32 uint32_t -#define __le64 uint64_t - -#define __be16 uint16_t -#define __be32 uint32_t -#define __be64 uint64_t - -static inline bool ipv4_addr_is_multicast(__be32 addr) +static inline bool ipv4_addr_is_multicast(uint32_t addr) { return (addr & htonl(0xf0000000)) == htonl(0xe0000000); } @@ -52,8 +44,8 @@ static inline bool ipv4_addr_is_multicast(__be32 addr) typedef struct ipv6_addr { union { uint8_t addr8[16]; - __be16 addr16[8]; - __be32 addr32[4]; + uint16_t addr16[8]; + uint32_t addr32[4]; }; } Ipv6Addr; diff --git a/hw/net/rocker/rocker_hw.h b/hw/net/rocker/rocker_hw.h index 1786323..7ec6bfb 100644 --- a/hw/net/rocker/rocker_hw.h +++ b/hw/net/rocker/rocker_hw.h @@ -9,10 +9,6 @@ #ifndef ROCKER_HW_H #define ROCKER_HW_H -#define __le16 uint16_t -#define __le32 uint32_t -#define __le64 uint64_t - /* * Return codes */ @@ -124,12 +120,12 @@ enum { */ typedef struct rocker_desc { - __le64 buf_addr; + uint64_t buf_addr; uint64_t cookie; - __le16 buf_size; - __le16 tlv_size; - __le16 rsvd[5]; /* pad to 32 bytes */ - __le16 comp_err; + uint16_t buf_size; + uint16_t tlv_size; + uint16_t rsvd[5]; /* pad to 32 bytes */ + uint16_t comp_err; } __attribute__((packed, aligned(8))) RockerDesc; /* @@ -137,9 +133,9 @@ typedef struct rocker_desc { */ typedef struct rocker_tlv { - __le32 type; - __le16 len; - __le16 rsvd; + uint32_t type; + uint16_t len; + uint16_t rsvd; } __attribute__((packed, aligned(8))) RockerTlv; /* cmd msg */ diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c index 3378f63..4aed178 100644 --- a/hw/net/rocker/rocker_of_dpa.c +++ b/hw/net/rocker/rocker_of_dpa.c @@ -52,10 +52,10 @@ typedef struct of_dpa_flow_key { uint32_t tunnel_id; /* overlay tunnel id */ uint32_t tbl_id; /* table id */ struct { - __be16 vlan_id; /* 0 if no VLAN */ + uint16_t vlan_id; /* 0 if no VLAN */ MACAddr src; /* ethernet source address */ MACAddr dst; /* ethernet destination address */ - __be16 type; /* ethernet frame type */ + uint16_t type; /* ethernet frame type */ } eth; struct { uint8_t proto; /* IP protocol or ARP opcode */ @@ -66,14 +66,14 @@ typedef struct of_dpa_flow_key { union { struct { struct { - __be32 src; /* IP source address */ - __be32 dst; /* IP destination address */ + uint32_t src; /* IP source address */ + uint32_t dst; /* IP destination address */ } addr; union { struct { - __be16 src; /* TCP/UDP/SCTP source port */ - __be16 dst; /* TCP/UDP/SCTP destination port */ - __be16 flags; /* TCP flags */ + uint16_t src; /* TCP/UDP/SCTP source port */ + uint16_t dst; /* TCP/UDP/SCTP destination port */ + uint16_t flags; /* TCP flags */ } tp; struct { MACAddr sha; /* ARP source hardware address */ @@ -86,11 +86,11 @@ typedef struct of_dpa_flow_key { Ipv6Addr src; /* IPv6 source address */ Ipv6Addr dst; /* IPv6 destination address */ } addr; - __be32 label; /* IPv6 flow label */ + uint32_t label; /* IPv6 flow label */ struct { - __be16 src; /* TCP/UDP/SCTP source port */ - __be16 dst; /* TCP/UDP/SCTP destination port */ - __be16 flags; /* TCP flags */ + uint16_t src; /* TCP/UDP/SCTP source port */ + uint16_t dst; /* TCP/UDP/SCTP destination port */ + uint16_t flags; /* TCP flags */ } tp; struct { Ipv6Addr target; /* ND target address */ @@ -112,13 +112,13 @@ typedef struct of_dpa_flow_action { struct { uint32_t group_id; uint32_t tun_log_lport; - __be16 vlan_id; + uint16_t vlan_id; } write; struct { - __be16 new_vlan_id; + uint16_t new_vlan_id; uint32_t out_pport; uint8_t copy_to_cpu; - __be16 vlan_id; + uint16_t vlan_id; } apply; } OfDpaFlowAction; @@ -143,7 +143,7 @@ typedef struct of_dpa_flow { typedef struct of_dpa_flow_pkt_fields { uint32_t tunnel_id; struct eth_header *ethhdr; - __be16 *h_proto; + uint16_t *h_proto; struct vlan_header *vlanhdr; struct ip_header *ipv4hdr; struct ip6_header *ipv6hdr; @@ -180,7 +180,7 @@ typedef struct of_dpa_group { uint32_t group_id; MACAddr src_mac; MACAddr dst_mac; - __be16 vlan_id; + uint16_t vlan_id; } l2_rewrite; struct { uint16_t group_count; @@ -190,13 +190,13 @@ typedef struct of_dpa_group { uint32_t group_id; MACAddr src_mac; MACAddr dst_mac; - __be16 vlan_id; + uint16_t vlan_id; uint8_t ttl_check; } l3_unicast; }; } OfDpaGroup; -static int of_dpa_mask2prefix(__be32 mask) +static int of_dpa_mask2prefix(uint32_t mask) { int i; int count = 32; @@ -451,7 +451,7 @@ static void of_dpa_flow_pkt_parse(OfDpaFlowContext *fc, fc->iovcnt = iovcnt + 2; } -static void of_dpa_flow_pkt_insert_vlan(OfDpaFlowContext *fc, __be16 vlan_id) +static void of_dpa_flow_pkt_insert_vlan(OfDpaFlowContext *fc, uint16_t vlan_id) { OfDpaFlowPktFields *fields = &fc->fields; uint16_t h_proto = fields->ethhdr->h_proto; @@ -486,7 +486,7 @@ static void of_dpa_flow_pkt_strip_vlan(OfDpaFlowContext *fc) static void of_dpa_flow_pkt_hdr_rewrite(OfDpaFlowContext *fc, uint8_t *src_mac, uint8_t *dst_mac, - __be16 vlan_id) + uint16_t vlan_id) { OfDpaFlowPktFields *fields = &fc->fields; diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c index 135ab57..654a087 100644 --- a/hw/net/rtl8139.c +++ b/hw/net/rtl8139.c @@ -1816,7 +1816,7 @@ static int rtl8139_transmit_one(RTL8139State *s, int descriptor) PCIDevice *d = PCI_DEVICE(s); int txsize = s->TxStatus[descriptor] & 0x1fff; - uint8_t txbuffer[0x2000]; + QEMU_UNINITIALIZED uint8_t txbuffer[0x2000]; DPRINTF("+++ transmit reading %d bytes from host memory at 0x%08x\n", txsize, s->TxAddr[descriptor]); @@ -3414,7 +3414,7 @@ static const Property rtl8139_properties[] = { DEFINE_NIC_PROPERTIES(RTL8139State, conf), }; -static void rtl8139_class_init(ObjectClass *klass, void *data) +static void rtl8139_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -3438,7 +3438,7 @@ static const TypeInfo rtl8139_info = { .instance_size = sizeof(RTL8139State), .class_init = rtl8139_class_init, .instance_init = rtl8139_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c index 9ce42b5..5cd78e3 100644 --- a/hw/net/smc91c111.c +++ b/hw/net/smc91c111.c @@ -913,7 +913,7 @@ static const Property smc91c111_properties[] = { DEFINE_NIC_PROPERTIES(smc91c111_state, conf), }; -static void smc91c111_class_init(ObjectClass *klass, void *data) +static void smc91c111_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c index 13fc656..f6f217d 100644 --- a/hw/net/spapr_llan.c +++ b/hw/net/spapr_llan.c @@ -848,7 +848,7 @@ static const VMStateDescription vmstate_spapr_llan = { } }; -static void spapr_vlan_class_init(ObjectClass *klass, void *data) +static void spapr_vlan_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c index a420732..2fc51e1 100644 --- a/hw/net/stellaris_enet.c +++ b/hw/net/stellaris_enet.c @@ -501,7 +501,7 @@ static const Property stellaris_enet_properties[] = { DEFINE_NIC_PROPERTIES(stellaris_enet_state, conf), }; -static void stellaris_enet_class_init(ObjectClass *klass, void *data) +static void stellaris_enet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/sungem.c b/hw/net/sungem.c index 12a9a9d..b405eb8 100644 --- a/hw/net/sungem.c +++ b/hw/net/sungem.c @@ -1454,7 +1454,7 @@ static const VMStateDescription vmstate_sungem = { } }; -static void sungem_class_init(ObjectClass *klass, void *data) +static void sungem_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1477,7 +1477,7 @@ static const TypeInfo sungem_info = { .instance_size = sizeof(SunGEMState), .class_init = sungem_class_init, .instance_init = sungem_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } } diff --git a/hw/net/sunhme.c b/hw/net/sunhme.c index fa234d0..c2f7a84 100644 --- a/hw/net/sunhme.c +++ b/hw/net/sunhme.c @@ -937,7 +937,7 @@ static const VMStateDescription vmstate_hme = { } }; -static void sunhme_class_init(ObjectClass *klass, void *data) +static void sunhme_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -958,7 +958,7 @@ static const TypeInfo sunhme_info = { .class_init = sunhme_class_init, .instance_size = sizeof(SunHMEState), .instance_init = sunhme_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } } diff --git a/hw/net/tulip.c b/hw/net/tulip.c index a0646bb..319af90 100644 --- a/hw/net/tulip.c +++ b/hw/net/tulip.c @@ -629,7 +629,7 @@ static void tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n) static void tulip_setup_frame(TULIPState *s, struct tulip_descriptor *desc) { - uint8_t buf[4096]; + QEMU_UNINITIALIZED uint8_t buf[4096]; int len = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK; int i; @@ -1011,7 +1011,7 @@ static const Property tulip_properties[] = { DEFINE_NIC_PROPERTIES(TULIPState, c), }; -static void tulip_class_init(ObjectClass *klass, void *data) +static void tulip_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1035,7 +1035,7 @@ static const TypeInfo tulip_info = { .instance_size = sizeof(TULIPState), .class_init = tulip_class_init, .instance_init = tulip_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index bd37651..eb93607 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -382,7 +382,7 @@ static void virtio_net_drop_tx_queue_data(VirtIODevice *vdev, VirtQueue *vq) } } -static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) +static int virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) { VirtIONet *n = VIRTIO_NET(vdev); VirtIONetQueue *q; @@ -437,6 +437,7 @@ static void virtio_net_set_status(struct VirtIODevice *vdev, uint8_t status) } } } + return 0; } static void virtio_net_set_link_status(NetClientState *nc) @@ -1910,9 +1911,9 @@ static ssize_t virtio_net_receive_rcu(NetClientState *nc, const uint8_t *buf, VirtIONet *n = qemu_get_nic_opaque(nc); VirtIONetQueue *q; VirtIODevice *vdev = VIRTIO_DEVICE(n); - VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; - size_t lens[VIRTQUEUE_MAX_SIZE]; - struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; + QEMU_UNINITIALIZED VirtQueueElement *elems[VIRTQUEUE_MAX_SIZE]; + QEMU_UNINITIALIZED size_t lens[VIRTQUEUE_MAX_SIZE]; + QEMU_UNINITIALIZED struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; struct virtio_net_hdr_v1_hash extra_hdr; unsigned mhdr_cnt = 0; size_t offset, i, guest_offset, j; @@ -4134,7 +4135,7 @@ static const Property virtio_net_properties[] = { VIRTIO_NET_F_HOST_USO, true), }; -static void virtio_net_class_init(ObjectClass *klass, void *data) +static void virtio_net_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index f370d4a..7c0ca56 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -41,19 +41,9 @@ #define PCI_DEVICE_ID_VMWARE_VMXNET3_REVISION 0x1 #define VMXNET3_MSIX_BAR_SIZE 0x2000 -/* Compatibility flags for migration */ -#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT 0 -#define VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS \ - (1 << VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT) -#define VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT 1 -#define VMXNET3_COMPAT_FLAG_DISABLE_PCIE \ - (1 << VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT) - #define VMXNET3_EXP_EP_OFFSET (0x48) -#define VMXNET3_MSI_OFFSET(s) \ - ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x50 : 0x84) -#define VMXNET3_MSIX_OFFSET(s) \ - ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0 : 0x9c) +#define VMXNET3_MSI_OFFSET (0x84) +#define VMXNET3_MSIX_OFFSET (0x9c) #define VMXNET3_DSN_OFFSET (0x100) #define VMXNET3_BAR0_IDX (0) @@ -61,8 +51,7 @@ #define VMXNET3_MSIX_BAR_IDX (2) #define VMXNET3_OFF_MSIX_TABLE (0x000) -#define VMXNET3_OFF_MSIX_PBA(s) \ - ((s)->compat_flags & VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS ? 0x800 : 0x1000) +#define VMXNET3_OFF_MSIX_PBA (0x1000) /* Link speed in Mbps should be shifted by 16 */ #define VMXNET3_LINK_SPEED (1000 << 16) @@ -2122,8 +2111,8 @@ vmxnet3_init_msix(VMXNET3State *s) &s->msix_bar, VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_TABLE, &s->msix_bar, - VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA(s), - VMXNET3_MSIX_OFFSET(s), NULL); + VMXNET3_MSIX_BAR_IDX, VMXNET3_OFF_MSIX_PBA, + VMXNET3_MSIX_OFFSET, NULL); if (0 > res) { VMW_WRPRN("Failed to initialize MSI-X, error %d", res); @@ -2221,7 +2210,7 @@ static void vmxnet3_pci_realize(PCIDevice *pci_dev, Error **errp) /* Interrupt pin A */ pci_dev->config[PCI_INTERRUPT_PIN] = 0x01; - ret = msi_init(pci_dev, VMXNET3_MSI_OFFSET(s), VMXNET3_MAX_NMSIX_INTRS, + ret = msi_init(pci_dev, VMXNET3_MSI_OFFSET, VMXNET3_MAX_NMSIX_INTRS, VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK, NULL); /* Any error other than -ENOTSUP(board's MSI support is broken) * is a programming error. Fall back to INTx silently on -ENOTSUP */ @@ -2249,6 +2238,7 @@ static void vmxnet3_instance_init(Object *obj) device_add_bootindex_property(obj, &s->conf.bootindex, "bootindex", "/ethernet-phy@0", DEVICE(obj)); + PCI_DEVICE(obj)->cap_present |= QEMU_PCI_CAP_EXPRESS; } static void vmxnet3_pci_uninit(PCIDevice *pci_dev) @@ -2472,30 +2462,12 @@ static const VMStateDescription vmstate_vmxnet3 = { static const Property vmxnet3_properties[] = { DEFINE_NIC_PROPERTIES(VMXNET3State, conf), - DEFINE_PROP_BIT("x-old-msi-offsets", VMXNET3State, compat_flags, - VMXNET3_COMPAT_FLAG_OLD_MSI_OFFSETS_BIT, false), - DEFINE_PROP_BIT("x-disable-pcie", VMXNET3State, compat_flags, - VMXNET3_COMPAT_FLAG_DISABLE_PCIE_BIT, false), }; -static void vmxnet3_realize(DeviceState *qdev, Error **errp) -{ - VMXNET3Class *vc = VMXNET3_DEVICE_GET_CLASS(qdev); - PCIDevice *pci_dev = PCI_DEVICE(qdev); - VMXNET3State *s = VMXNET3(qdev); - - if (!(s->compat_flags & VMXNET3_COMPAT_FLAG_DISABLE_PCIE)) { - pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; - } - - vc->parent_dc_realize(qdev, errp); -} - -static void vmxnet3_class_init(ObjectClass *class, void *data) +static void vmxnet3_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); PCIDeviceClass *c = PCI_DEVICE_CLASS(class); - VMXNET3Class *vc = VMXNET3_DEVICE_CLASS(class); c->realize = vmxnet3_pci_realize; c->exit = vmxnet3_pci_uninit; @@ -2506,8 +2478,6 @@ static void vmxnet3_class_init(ObjectClass *class, void *data) c->class_id = PCI_CLASS_NETWORK_ETHERNET; c->subsystem_vendor_id = PCI_VENDOR_ID_VMWARE; c->subsystem_id = PCI_DEVICE_ID_VMWARE_VMXNET3; - device_class_set_parent_realize(dc, vmxnet3_realize, - &vc->parent_dc_realize); dc->desc = "VMWare Paravirtualized Ethernet v3"; device_class_set_legacy_reset(dc, vmxnet3_qdev_reset); dc->vmsd = &vmstate_vmxnet3; @@ -2522,7 +2492,7 @@ static const TypeInfo vmxnet3_info = { .instance_size = sizeof(VMXNET3State), .class_init = vmxnet3_class_init, .instance_init = vmxnet3_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } diff --git a/hw/net/vmxnet3.h b/hw/net/vmxnet3.h index f9283f9..dbc69d5 100644 --- a/hw/net/vmxnet3.h +++ b/hw/net/vmxnet3.h @@ -63,8 +63,8 @@ * details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * along with this program; if not, see + * <https://www.gnu.org/licenses/>. * * The full GNU General Public License is included in this distribution in * the file called "COPYING". diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index c486912..34c6a1d 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -559,7 +559,7 @@ static const Property xen_netdev_properties[] = { DEFINE_PROP_INT32("idx", XenNetDev, dev, -1), }; -static void xen_netdev_class_init(ObjectClass *class, void *data) +static void xen_netdev_class_init(ObjectClass *class, const void *data) { DeviceClass *dev_class = DEVICE_CLASS(class); XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class); diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c index e3cc4c6..d45f872 100644 --- a/hw/net/xgmac.c +++ b/hw/net/xgmac.c @@ -207,7 +207,7 @@ static void xgmac_enet_send(XgmacState *s) struct desc bd; int frame_size; int len; - uint8_t frame[8192]; + QEMU_UNINITIALIZED uint8_t frame[8192]; uint8_t *ptr; ptr = frame; @@ -418,7 +418,7 @@ static const Property xgmac_properties[] = { DEFINE_NIC_PROPERTIES(XgmacState, conf), }; -static void xgmac_enet_class_init(ObjectClass *klass, void *data) +static void xgmac_enet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c index 457952a..1f5c748 100644 --- a/hw/net/xilinx_axienet.c +++ b/hw/net/xilinx_axienet.c @@ -1007,7 +1007,7 @@ static const Property xilinx_enet_properties[] = { tx_control_dev, TYPE_STREAM_SINK, StreamSink *), }; -static void xilinx_enet_class_init(ObjectClass *klass, void *data) +static void xilinx_enet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1017,14 +1017,15 @@ static void xilinx_enet_class_init(ObjectClass *klass, void *data) } static void xilinx_enet_control_stream_class_init(ObjectClass *klass, - void *data) + const void *data) { StreamSinkClass *ssc = STREAM_SINK_CLASS(klass); ssc->push = xilinx_axienet_control_stream_push; } -static void xilinx_enet_data_stream_class_init(ObjectClass *klass, void *data) +static void xilinx_enet_data_stream_class_init(ObjectClass *klass, + const void *data) { StreamSinkClass *ssc = STREAM_SINK_CLASS(klass); @@ -1044,7 +1045,7 @@ static const TypeInfo xilinx_enet_data_stream_info = { .parent = TYPE_OBJECT, .instance_size = sizeof(XilinxAXIEnetStreamSink), .class_init = xilinx_enet_data_stream_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_STREAM_SINK }, { } } @@ -1055,7 +1056,7 @@ static const TypeInfo xilinx_enet_control_stream_info = { .parent = TYPE_OBJECT, .instance_size = sizeof(XilinxAXIEnetStreamSink), .class_init = xilinx_enet_control_stream_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_STREAM_SINK }, { } } diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c index 15d9b95..42b19d0 100644 --- a/hw/net/xilinx_ethlite.c +++ b/hw/net/xilinx_ethlite.c @@ -385,7 +385,7 @@ static const Property xilinx_ethlite_properties[] = { DEFINE_NIC_PROPERTIES(XlnxXpsEthLite, conf), }; -static void xilinx_ethlite_class_init(ObjectClass *klass, void *data) +static void xilinx_ethlite_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nubus/mac-nubus-bridge.c b/hw/nubus/mac-nubus-bridge.c index a0da5a8..0dac8d1 100644 --- a/hw/nubus/mac-nubus-bridge.c +++ b/hw/nubus/mac-nubus-bridge.c @@ -40,7 +40,7 @@ static void mac_nubus_bridge_init(Object *obj) sysbus_init_mmio(sbd, &s->slot_alias); } -static void mac_nubus_bridge_class_init(ObjectClass *klass, void *data) +static void mac_nubus_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nubus/nubus-bridge.c b/hw/nubus/nubus-bridge.c index 8fe4362..fb14402 100644 --- a/hw/nubus/nubus-bridge.c +++ b/hw/nubus/nubus-bridge.c @@ -28,7 +28,7 @@ static const Property nubus_bridge_properties[] = { bus.slot_available_mask, 0xffff), }; -static void nubus_bridge_class_init(ObjectClass *klass, void *data) +static void nubus_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nubus/nubus-bus.c b/hw/nubus/nubus-bus.c index 07c279b..44820f1 100644 --- a/hw/nubus/nubus-bus.c +++ b/hw/nubus/nubus-bus.c @@ -162,7 +162,7 @@ static bool nubus_check_address(BusState *bus, DeviceState *dev, Error **errp) return true; } -static void nubus_class_init(ObjectClass *oc, void *data) +static void nubus_class_init(ObjectClass *oc, const void *data) { BusClass *bc = BUS_CLASS(oc); diff --git a/hw/nubus/nubus-device.c b/hw/nubus/nubus-device.c index 6755c3d..7797e61 100644 --- a/hw/nubus/nubus-device.c +++ b/hw/nubus/nubus-device.c @@ -112,7 +112,7 @@ static const Property nubus_device_properties[] = { DEFINE_PROP_STRING("romfile", NubusDevice, romfile), }; -static void nubus_device_class_init(ObjectClass *oc, void *data) +static void nubus_device_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/nubus/nubus-virtio-mmio.c b/hw/nubus/nubus-virtio-mmio.c index 7a98731..63aeca5 100644 --- a/hw/nubus/nubus-virtio-mmio.c +++ b/hw/nubus/nubus-virtio-mmio.c @@ -81,7 +81,7 @@ static void nubus_virtio_mmio_init(Object *obj) "pic-input-irq", 1); } -static void nubus_virtio_mmio_class_init(ObjectClass *oc, void *data) +static void nubus_virtio_mmio_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); NubusVirtioMMIODeviceClass *nvmdc = NUBUS_VIRTIO_MMIO_CLASS(oc); diff --git a/hw/nvme/ctrl.c b/hw/nvme/ctrl.c index d6b77d4..2200028 100644 --- a/hw/nvme/ctrl.c +++ b/hw/nvme/ctrl.c @@ -1057,7 +1057,8 @@ static uint16_t nvme_map_sgl(NvmeCtrl *n, NvmeSg *sg, NvmeSglDescriptor sgl, */ #define SEG_CHUNK_SIZE 256 - NvmeSglDescriptor segment[SEG_CHUNK_SIZE], *sgld, *last_sgld; + QEMU_UNINITIALIZED NvmeSglDescriptor segment[SEG_CHUNK_SIZE]; + NvmeSglDescriptor *sgld, *last_sgld; uint64_t nsgld; uint32_t seg_len; uint16_t status; @@ -5128,7 +5129,7 @@ static uint16_t nvme_error_info(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, uint64_t off, NvmeRequest *req) { - uint32_t nslist[1024]; + uint32_t nslist[1024] = {}; uint32_t trans_len; int i = 0; uint32_t nsid; @@ -5138,7 +5139,6 @@ static uint16_t nvme_changed_nslist(NvmeCtrl *n, uint8_t rae, uint32_t buf_len, return NVME_INVALID_FIELD | NVME_DNR; } - memset(nslist, 0x0, sizeof(nslist)); trans_len = MIN(sizeof(nslist) - off, buf_len); while ((nsid = find_first_bit(n->changed_nsids, NVME_CHANGED_NSID_SIZE)) != @@ -9183,7 +9183,7 @@ static const VMStateDescription nvme_vmstate = { .unmigratable = 1, }; -static void nvme_class_init(ObjectClass *oc, void *data) +static void nvme_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); @@ -9221,7 +9221,7 @@ static const TypeInfo nvme_info = { .instance_size = sizeof(NvmeCtrl), .instance_init = nvme_instance_init, .class_init = nvme_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/nvme/ns.c b/hw/nvme/ns.c index 4ab8ba7..6df2e8e 100644 --- a/hw/nvme/ns.c +++ b/hw/nvme/ns.c @@ -806,7 +806,7 @@ static const Property nvme_ns_props[] = { DEFINE_PROP_STRING("fdp.ruhs", NvmeNamespace, params.fdp.ruhs), }; -static void nvme_ns_class_init(ObjectClass *oc, void *data) +static void nvme_ns_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/nvme/subsys.c b/hw/nvme/subsys.c index b617ac3..777e1c6 100644 --- a/hw/nvme/subsys.c +++ b/hw/nvme/subsys.c @@ -218,7 +218,7 @@ static const Property nvme_subsystem_props[] = { DEFINE_PROP_UINT16("fdp.nruh", NvmeSubsystem, params.fdp.nruh, 0), }; -static void nvme_subsys_class_init(ObjectClass *oc, void *data) +static void nvme_subsys_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -226,7 +226,6 @@ static void nvme_subsys_class_init(ObjectClass *oc, void *data) dc->realize = nvme_subsys_realize; dc->desc = "Virtual NVMe subsystem"; - dc->hotpluggable = false; device_class_set_props(dc, nvme_subsystem_props); } diff --git a/hw/nvram/bcm2835_otp.c b/hw/nvram/bcm2835_otp.c index c4aed28..6816b53 100644 --- a/hw/nvram/bcm2835_otp.c +++ b/hw/nvram/bcm2835_otp.c @@ -164,7 +164,7 @@ static const VMStateDescription vmstate_bcm2835_otp = { } }; -static void bcm2835_otp_class_init(ObjectClass *klass, void *data) +static void bcm2835_otp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nvram/ds1225y.c b/hw/nvram/ds1225y.c index 6b2aa8c..dbfd0d2 100644 --- a/hw/nvram/ds1225y.c +++ b/hw/nvram/ds1225y.c @@ -147,7 +147,7 @@ static const Property nvram_sysbus_properties[] = { DEFINE_PROP_STRING("filename", SysBusNvRamState, nvram.filename), }; -static void nvram_sysbus_class_init(ObjectClass *klass, void *data) +static void nvram_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nvram/eeprom_at24c.c b/hw/nvram/eeprom_at24c.c index ff7a21e..82ea97e 100644 --- a/hw/nvram/eeprom_at24c.c +++ b/hw/nvram/eeprom_at24c.c @@ -235,7 +235,7 @@ static const Property at24c_eeprom_props[] = { }; static -void at24c_eeprom_class_init(ObjectClass *klass, void *data) +void at24c_eeprom_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c index a757939..aa24050 100644 --- a/hw/nvram/fw_cfg.c +++ b/hw/nvram/fw_cfg.c @@ -27,7 +27,7 @@ #include "system/system.h" #include "system/dma.h" #include "system/reset.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/boards.h" #include "hw/nvram/fw_cfg.h" #include "hw/qdev-properties.h" @@ -817,62 +817,6 @@ void fw_cfg_modify_i64(FWCfgState *s, uint16_t key, uint64_t value) g_free(old); } -void fw_cfg_set_order_override(FWCfgState *s, int order) -{ - assert(s->fw_cfg_order_override == 0); - s->fw_cfg_order_override = order; -} - -void fw_cfg_reset_order_override(FWCfgState *s) -{ - assert(s->fw_cfg_order_override != 0); - s->fw_cfg_order_override = 0; -} - -/* - * This is the legacy order list. For legacy systems, files are in - * the fw_cfg in the order defined below, by the "order" value. Note - * that some entries (VGA ROMs, NIC option ROMS, etc.) go into a - * specific area, but there may be more than one and they occur in the - * order that the user specifies them on the command line. Those are - * handled in a special manner, using the order override above. - * - * For non-legacy, the files are sorted by filename to avoid this kind - * of complexity in the future. - * - * This is only for x86, other arches don't implement versioning so - * they won't set legacy mode. - */ -static struct { - const char *name; - int order; -} fw_cfg_order[] = { - { "etc/boot-menu-wait", 10 }, - { "bootsplash.jpg", 11 }, - { "bootsplash.bmp", 12 }, - { "etc/boot-fail-wait", 15 }, - { "etc/smbios/smbios-tables", 20 }, - { "etc/smbios/smbios-anchor", 30 }, - { "etc/e820", 40 }, - { "etc/reserved-memory-end", 50 }, - { "genroms/kvmvapic.bin", 55 }, - { "genroms/linuxboot.bin", 60 }, - { }, /* VGA ROMs from pc_vga_init come here, 70. */ - { }, /* NIC option ROMs from pc_nic_init come here, 80. */ - { "etc/system-states", 90 }, - { }, /* User ROMs come here, 100. */ - { }, /* Device FW comes here, 110. */ - { "etc/extra-pci-roots", 120 }, - { "etc/acpi/tables", 130 }, - { "etc/table-loader", 140 }, - { "etc/tpm/log", 150 }, - { "etc/acpi/rsdp", 160 }, - { "bootorder", 170 }, - { "etc/msr_feature_control", 180 }, - -#define FW_CFG_ORDER_OVERRIDE_LAST 200 -}; - /* * Any sub-page size update to these table MRs will be lost during migration, * as we use aligned size in ram_load_precopy() -> qemu_ram_resize() path. @@ -890,29 +834,6 @@ static void fw_cfg_acpi_mr_save(FWCfgState *s, const char *filename, size_t len) } } -static int get_fw_cfg_order(FWCfgState *s, const char *name) -{ - int i; - - if (s->fw_cfg_order_override > 0) { - return s->fw_cfg_order_override; - } - - for (i = 0; i < ARRAY_SIZE(fw_cfg_order); i++) { - if (fw_cfg_order[i].name == NULL) { - continue; - } - - if (strcmp(name, fw_cfg_order[i].name) == 0) { - return fw_cfg_order[i].order; - } - } - - /* Stick unknown stuff at the end. */ - warn_report("Unknown firmware file in legacy mode: %s", name); - return FW_CFG_ORDER_OVERRIDE_LAST; -} - void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, FWCfgCallback select_cb, FWCfgWriteCallback write_cb, @@ -921,7 +842,6 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, { int i, index, count; size_t dsize; - MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); int order = 0; if (!s->files) { @@ -933,22 +853,11 @@ void fw_cfg_add_file_callback(FWCfgState *s, const char *filename, count = be32_to_cpu(s->files->count); assert(count < fw_cfg_file_slots(s)); - /* Find the insertion point. */ - if (mc->legacy_fw_cfg_order) { - /* - * Sort by order. For files with the same order, we keep them - * in the sequence in which they were added. - */ - order = get_fw_cfg_order(s, filename); - for (index = count; - index > 0 && order < s->entry_order[index - 1]; - index--); - } else { - /* Sort by file name. */ - for (index = count; - index > 0 && strcmp(filename, s->files->f[index - 1].name) < 0; - index--); - } + /* Find the insertion point, sorting by file name. */ + for (index = count; + index > 0 && strcmp(filename, s->files->f[index - 1].name) < 0; + index--) + ; /* * Move all the entries from the index point and after down one @@ -1058,7 +967,6 @@ bool fw_cfg_add_file_from_generator(FWCfgState *s, static void fw_cfg_machine_reset(void *opaque) { - MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); FWCfgState *s = opaque; void *ptr; size_t len; @@ -1068,11 +976,9 @@ static void fw_cfg_machine_reset(void *opaque) ptr = fw_cfg_modify_file(s, "bootorder", (uint8_t *)buf, len); g_free(ptr); - if (!mc->legacy_fw_cfg_order) { - buf = get_boot_devices_lchs_list(&len); - ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len); - g_free(ptr); - } + buf = get_boot_devices_lchs_list(&len); + ptr = fw_cfg_modify_file(s, "bios-geometry", (uint8_t *)buf, len); + g_free(ptr); } static void fw_cfg_machine_ready(struct Notifier *n, void *data) @@ -1228,7 +1134,7 @@ void load_image_to_fw_cfg(FWCfgState *fw_cfg, uint16_t size_key, fw_cfg_add_bytes(fw_cfg, data_key, data, size); } -static void fw_cfg_class_init(ObjectClass *klass, void *data) +static void fw_cfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1303,7 +1209,7 @@ static void fw_cfg_io_realize(DeviceState *dev, Error **errp) fw_cfg_common_realize(dev, errp); } -static void fw_cfg_io_class_init(ObjectClass *klass, void *data) +static void fw_cfg_io_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1364,7 +1270,7 @@ static void fw_cfg_mem_realize(DeviceState *dev, Error **errp) fw_cfg_common_realize(dev, errp); } -static void fw_cfg_mem_class_init(ObjectClass *klass, void *data) +static void fw_cfg_mem_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nvram/mac_nvram.c b/hw/nvram/mac_nvram.c index 0d82e5a..66526a2 100644 --- a/hw/nvram/mac_nvram.c +++ b/hw/nvram/mac_nvram.c @@ -140,7 +140,7 @@ static const Property macio_nvram_properties[] = { DEFINE_PROP_DRIVE("drive", MacIONVRAMState, blk), }; -static void macio_nvram_class_init(ObjectClass *oc, void *data) +static void macio_nvram_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/nvram/npcm7xx_otp.c b/hw/nvram/npcm7xx_otp.c index f00ebfa..1fb752b 100644 --- a/hw/nvram/npcm7xx_otp.c +++ b/hw/nvram/npcm7xx_otp.c @@ -391,7 +391,7 @@ static const VMStateDescription vmstate_npcm7xx_otp = { }, }; -static void npcm7xx_otp_class_init(ObjectClass *klass, void *data) +static void npcm7xx_otp_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -403,14 +403,14 @@ static void npcm7xx_otp_class_init(ObjectClass *klass, void *data) rc->phases.enter = npcm7xx_otp_enter_reset; } -static void npcm7xx_key_storage_class_init(ObjectClass *klass, void *data) +static void npcm7xx_key_storage_class_init(ObjectClass *klass, const void *data) { NPCM7xxOTPClass *oc = NPCM7XX_OTP_CLASS(klass); oc->mmio_ops = &npcm7xx_key_storage_ops; } -static void npcm7xx_fuse_array_class_init(ObjectClass *klass, void *data) +static void npcm7xx_fuse_array_class_init(ObjectClass *klass, const void *data) { NPCM7xxOTPClass *oc = NPCM7XX_OTP_CLASS(klass); diff --git a/hw/nvram/nrf51_nvm.c b/hw/nvram/nrf51_nvm.c index 2ed4078..23cc9fe 100644 --- a/hw/nvram/nrf51_nvm.c +++ b/hw/nvram/nrf51_nvm.c @@ -370,7 +370,7 @@ static const VMStateDescription vmstate_nvm = { } }; -static void nrf51_nvm_class_init(ObjectClass *klass, void *data) +static void nrf51_nvm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c index a45827f..d0ac4e57 100644 --- a/hw/nvram/spapr_nvram.c +++ b/hw/nvram/spapr_nvram.c @@ -257,7 +257,7 @@ static const Property spapr_nvram_properties[] = { DEFINE_PROP_DRIVE("drive", SpaprNvram, blk), }; -static void spapr_nvram_class_init(ObjectClass *klass, void *data) +static void spapr_nvram_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); diff --git a/hw/nvram/xlnx-bbram.c b/hw/nvram/xlnx-bbram.c index 14cc907..5702bb3 100644 --- a/hw/nvram/xlnx-bbram.c +++ b/hw/nvram/xlnx-bbram.c @@ -525,7 +525,7 @@ static const Property bbram_ctrl_props[] = { DEFINE_PROP_UINT32("crc-zpads", XlnxBBRam, crc_zpads, 1), }; -static void bbram_ctrl_class_init(ObjectClass *klass, void *data) +static void bbram_ctrl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/nvram/xlnx-efuse.c b/hw/nvram/xlnx-efuse.c index 176e88f..4c23f8b 100644 --- a/hw/nvram/xlnx-efuse.c +++ b/hw/nvram/xlnx-efuse.c @@ -274,7 +274,7 @@ static const Property efuse_properties[] = { qdev_prop_uint32, uint32_t), }; -static void efuse_class_init(ObjectClass *klass, void *data) +static void efuse_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nvram/xlnx-versal-efuse-cache.c b/hw/nvram/xlnx-versal-efuse-cache.c index 2fb5994..d4ec96a 100644 --- a/hw/nvram/xlnx-versal-efuse-cache.c +++ b/hw/nvram/xlnx-versal-efuse-cache.c @@ -89,7 +89,7 @@ static const Property efuse_cache_props[] = { TYPE_XLNX_EFUSE, XlnxEFuse *), }; -static void efuse_cache_class_init(ObjectClass *klass, void *data) +static void efuse_cache_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/nvram/xlnx-versal-efuse-ctrl.c b/hw/nvram/xlnx-versal-efuse-ctrl.c index ff4d544..9096219 100644 --- a/hw/nvram/xlnx-versal-efuse-ctrl.c +++ b/hw/nvram/xlnx-versal-efuse-ctrl.c @@ -751,7 +751,7 @@ static const Property efuse_ctrl_props[] = { extra_pg0_lock_spec, qdev_prop_uint16, uint16_t), }; -static void efuse_ctrl_class_init(ObjectClass *klass, void *data) +static void efuse_ctrl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/nvram/xlnx-zynqmp-efuse.c b/hw/nvram/xlnx-zynqmp-efuse.c index 15024da..5a218c3 100644 --- a/hw/nvram/xlnx-zynqmp-efuse.c +++ b/hw/nvram/xlnx-zynqmp-efuse.c @@ -839,7 +839,7 @@ static const Property zynqmp_efuse_props[] = { TYPE_XLNX_EFUSE, XlnxEFuse *), }; -static void zynqmp_efuse_class_init(ObjectClass *klass, void *data) +static void zynqmp_efuse_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/openrisc/boot.c b/hw/openrisc/boot.c index 0a5881b..c81efe8 100644 --- a/hw/openrisc/boot.c +++ b/hw/openrisc/boot.c @@ -9,6 +9,7 @@ #include "qemu/osdep.h" #include "cpu.h" #include "exec/cpu-defs.h" +#include "exec/target_page.h" #include "elf.h" #include "hw/loader.h" #include "hw/openrisc/boot.h" diff --git a/hw/openrisc/openrisc_sim.c b/hw/openrisc/openrisc_sim.c index 83d7c2a..880c8eb 100644 --- a/hw/openrisc/openrisc_sim.c +++ b/hw/openrisc/openrisc_sim.c @@ -28,7 +28,7 @@ #include "net/net.h" #include "hw/openrisc/boot.h" #include "hw/qdev-properties.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/device_tree.h" #include "system/system.h" #include "hw/sysbus.h" @@ -357,7 +357,7 @@ static void openrisc_sim_init(MachineState *machine) } } -static void openrisc_sim_machine_init(ObjectClass *oc, void *data) +static void openrisc_sim_machine_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/openrisc/virt.c b/hw/openrisc/virt.c index 3055306..a98071c 100644 --- a/hw/openrisc/virt.c +++ b/hw/openrisc/virt.c @@ -11,7 +11,7 @@ #include "qemu/guest-random.h" #include "qapi/error.h" #include "cpu.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/irq.h" #include "hw/boards.h" #include "hw/char/serial-mm.h" @@ -543,7 +543,7 @@ static void openrisc_virt_init(MachineState *machine) } } -static void openrisc_virt_machine_init(ObjectClass *oc, void *data) +static void openrisc_virt_machine_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/pci-bridge/cxl_downstream.c b/hw/pci-bridge/cxl_downstream.c index e337f1a..1065245 100644 --- a/hw/pci-bridge/cxl_downstream.c +++ b/hw/pci-bridge/cxl_downstream.c @@ -219,7 +219,7 @@ static const Property cxl_dsp_props[] = { width, PCIE_LINK_WIDTH_16), }; -static void cxl_dsp_class_init(ObjectClass *oc, void *data) +static void cxl_dsp_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *k = PCI_DEVICE_CLASS(oc); @@ -241,7 +241,7 @@ static const TypeInfo cxl_dsp_info = { .instance_size = sizeof(CXLDownstreamPort), .parent = TYPE_PCIE_SLOT, .class_init = cxl_dsp_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CXL_DEVICE }, { } diff --git a/hw/pci-bridge/cxl_root_port.c b/hw/pci-bridge/cxl_root_port.c index c0037f2..e6a4035 100644 --- a/hw/pci-bridge/cxl_root_port.c +++ b/hw/pci-bridge/cxl_root_port.c @@ -262,7 +262,7 @@ static void cxl_rp_write_config(PCIDevice *d, uint32_t address, uint32_t val, cxl_rp_dvsec_write_config(d, address, val, len); } -static void cxl_root_port_class_init(ObjectClass *oc, void *data) +static void cxl_root_port_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *k = PCI_DEVICE_CLASS(oc); @@ -294,7 +294,7 @@ static const TypeInfo cxl_root_port_info = { .parent = TYPE_PCIE_ROOT_PORT, .instance_size = sizeof(CXLRootPort), .class_init = cxl_root_port_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CXL_DEVICE }, { } }, diff --git a/hw/pci-bridge/cxl_upstream.c b/hw/pci-bridge/cxl_upstream.c index 28b109c..208e0c6 100644 --- a/hw/pci-bridge/cxl_upstream.c +++ b/hw/pci-bridge/cxl_upstream.c @@ -371,7 +371,7 @@ static const Property cxl_upstream_props[] = { width, PCIE_LINK_WIDTH_16), }; -static void cxl_upstream_class_init(ObjectClass *oc, void *data) +static void cxl_upstream_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *k = PCI_DEVICE_CLASS(oc); @@ -394,7 +394,7 @@ static const TypeInfo cxl_usp_info = { .parent = TYPE_PCIE_PORT, .instance_size = sizeof(CXLUpstreamPort), .class_init = cxl_upstream_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CXL_DEVICE }, { } diff --git a/hw/pci-bridge/gen_pcie_root_port.c b/hw/pci-bridge/gen_pcie_root_port.c index 3c0b41e..d9078e7 100644 --- a/hw/pci-bridge/gen_pcie_root_port.c +++ b/hw/pci-bridge/gen_pcie_root_port.c @@ -147,7 +147,7 @@ static const Property gen_rp_props[] = { width, PCIE_LINK_WIDTH_32), }; -static void gen_rp_dev_class_init(ObjectClass *klass, void *data) +static void gen_rp_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/pci-bridge/i82801b11.c b/hw/pci-bridge/i82801b11.c index 00d2fbd..1d73c14 100644 --- a/hw/pci-bridge/i82801b11.c +++ b/hw/pci-bridge/i82801b11.c @@ -87,7 +87,7 @@ static const VMStateDescription i82801b11_bridge_dev_vmstate = { } }; -static void i82801b11_bridge_class_init(ObjectClass *klass, void *data) +static void i82801b11_bridge_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -107,7 +107,7 @@ static const TypeInfo i82801b11_bridge_info = { .parent = TYPE_PCI_BRIDGE, .instance_size = sizeof(I82801b11Bridge), .class_init = i82801b11_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c index be752a4..bba640f 100644 --- a/hw/pci-bridge/ioh3420.c +++ b/hw/pci-bridge/ioh3420.c @@ -96,7 +96,7 @@ static const VMStateDescription vmstate_ioh3420 = { } }; -static void ioh3420_class_init(ObjectClass *klass, void *data) +static void ioh3420_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c index 0a91a8a..b328e50 100644 --- a/hw/pci-bridge/pci_bridge_dev.c +++ b/hw/pci-bridge/pci_bridge_dev.c @@ -28,7 +28,7 @@ #include "hw/pci/shpc.h" #include "hw/pci/slotid_cap.h" #include "hw/qdev-properties.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/pci/pci_bus.h" #include "hw/hotplug.h" #include "qom/object.h" @@ -240,7 +240,7 @@ void pci_bridge_dev_unplug_request_cb(HotplugHandler *hotplug_dev, shpc_device_unplug_request_cb(hotplug_dev, dev, errp); } -static void pci_bridge_dev_class_init(ObjectClass *klass, void *data) +static void pci_bridge_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -268,7 +268,7 @@ static const TypeInfo pci_bridge_dev_info = { .instance_size = sizeof(PCIBridgeDev), .class_init = pci_bridge_dev_class_init, .instance_finalize = pci_bridge_dev_instance_finalize, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } @@ -280,7 +280,7 @@ static const TypeInfo pci_bridge_dev_info = { * different pci id, so we can match it easily in the guest for * automagic multiseat configuration. See docs/multiseat.txt for more. */ -static void pci_bridge_dev_seat_class_init(ObjectClass *klass, void *data) +static void pci_bridge_dev_seat_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c index 3396ab4..3a29dfe 100644 --- a/hw/pci-bridge/pci_expander_bridge.c +++ b/hw/pci-bridge/pci_expander_bridge.c @@ -92,7 +92,7 @@ static void prop_pxb_uid_get(Object *obj, Visitor *v, const char *name, visit_type_uint32(v, name, &uid, errp); } -static void pxb_bus_class_init(ObjectClass *class, void *data) +static void pxb_bus_class_init(ObjectClass *class, const void *data) { PCIBusClass *pbc = PCI_BUS_CLASS(class); @@ -169,7 +169,7 @@ static char *pxb_host_ofw_unit_address(const SysBusDevice *dev) return NULL; } -static void pxb_host_class_init(ObjectClass *class, void *data) +static void pxb_host_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(class); @@ -224,7 +224,7 @@ void pxb_cxl_hook_up_registers(CXLState *cxl_state, PCIBus *bus, Error **errp) cxl_state->next_mr_idx++; } -static void pxb_cxl_host_class_init(ObjectClass *class, void *data) +static void pxb_cxl_host_class_init(ObjectClass *class, const void *data) { DeviceClass *dc = DEVICE_CLASS(class); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(class); @@ -427,7 +427,7 @@ static const Property pxb_dev_properties[] = { DEFINE_PROP_BOOL("bypass_iommu", PXBDev, bypass_iommu, false), }; -static void pxb_dev_class_init(ObjectClass *klass, void *data) +static void pxb_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -449,7 +449,7 @@ static const TypeInfo pxb_dev_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PXBDev), .class_init = pxb_dev_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -465,7 +465,7 @@ static void pxb_pcie_dev_realize(PCIDevice *dev, Error **errp) pxb_dev_realize_common(dev, PCIE, errp); } -static void pxb_pcie_dev_class_init(ObjectClass *klass, void *data) +static void pxb_pcie_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -486,7 +486,7 @@ static const TypeInfo pxb_pcie_dev_info = { .parent = TYPE_PXB_DEV, .instance_size = sizeof(PXBPCIEDev), .class_init = pxb_pcie_dev_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -510,7 +510,7 @@ static const Property pxb_cxl_dev_properties[] = { DEFINE_PROP_BOOL("hdm_for_passthrough", PXBCXLDev, hdm_for_passthrough, false), }; -static void pxb_cxl_dev_class_init(ObjectClass *klass, void *data) +static void pxb_cxl_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -537,7 +537,7 @@ static const TypeInfo pxb_cxl_dev_info = { .instance_size = sizeof(PXBCXLDev), .class_init = pxb_cxl_dev_class_init, .interfaces = - (InterfaceInfo[]){ + (const InterfaceInfo[]){ { INTERFACE_CONVENTIONAL_PCI_DEVICE }, {}, }, diff --git a/hw/pci-bridge/pcie_pci_bridge.c b/hw/pci-bridge/pcie_pci_bridge.c index 2429503..fce292a 100644 --- a/hw/pci-bridge/pcie_pci_bridge.c +++ b/hw/pci-bridge/pcie_pci_bridge.c @@ -137,7 +137,7 @@ static const VMStateDescription pcie_pci_bridge_dev_vmstate = { } }; -static void pcie_pci_bridge_class_init(ObjectClass *klass, void *data) +static void pcie_pci_bridge_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -162,7 +162,7 @@ static const TypeInfo pcie_pci_bridge_info = { .parent = TYPE_PCI_BRIDGE, .instance_size = sizeof(PCIEPCIBridge), .class_init = pcie_pci_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { INTERFACE_PCIE_DEVICE }, { }, diff --git a/hw/pci-bridge/pcie_root_port.c b/hw/pci-bridge/pcie_root_port.c index dd40b36..22c2fdb 100644 --- a/hw/pci-bridge/pcie_root_port.c +++ b/hw/pci-bridge/pcie_root_port.c @@ -167,7 +167,7 @@ static void rp_instance_post_init(Object *obj) } } -static void rp_class_init(ObjectClass *klass, void *data) +static void rp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -188,7 +188,7 @@ static const TypeInfo rp_info = { .class_init = rp_class_init, .abstract = true, .class_size = sizeof(PCIERootPortClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/pci-bridge/simba.c b/hw/pci-bridge/simba.c index 5fe090d..bbae594 100644 --- a/hw/pci-bridge/simba.c +++ b/hw/pci-bridge/simba.c @@ -66,7 +66,7 @@ static void simba_pci_bridge_realize(PCIDevice *dev, Error **errp) pci_bridge_update_mappings(PCI_BRIDGE(br)); } -static void simba_pci_bridge_class_init(ObjectClass *klass, void *data) +static void simba_pci_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -87,7 +87,7 @@ static const TypeInfo simba_pci_bridge_info = { .parent = TYPE_PCI_BRIDGE, .class_init = simba_pci_bridge_class_init, .instance_size = sizeof(SimbaPCIBridge), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c index d4e94f2..dc7d1aa 100644 --- a/hw/pci-bridge/xio3130_downstream.c +++ b/hw/pci-bridge/xio3130_downstream.c @@ -153,7 +153,7 @@ static const VMStateDescription vmstate_xio3130_downstream = { } }; -static void xio3130_downstream_class_init(ObjectClass *klass, void *data) +static void xio3130_downstream_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -175,7 +175,7 @@ static const TypeInfo xio3130_downstream_info = { .name = TYPE_XIO3130_DOWNSTREAM, .parent = TYPE_PCIE_SLOT, .class_init = xio3130_downstream_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c index fb1547b..40057b7 100644 --- a/hw/pci-bridge/xio3130_upstream.c +++ b/hw/pci-bridge/xio3130_upstream.c @@ -123,7 +123,7 @@ static const VMStateDescription vmstate_xio3130_upstream = { } }; -static void xio3130_upstream_class_init(ObjectClass *klass, void *data) +static void xio3130_upstream_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -144,7 +144,7 @@ static const TypeInfo xio3130_upstream_info = { .name = "x3130-upstream", .parent = TYPE_PCIE_PORT, .class_init = xio3130_upstream_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/pci-host/articia.c b/hw/pci-host/articia.c index f3fcc49..cc65aac 100644 --- a/hw/pci-host/articia.c +++ b/hw/pci-host/articia.c @@ -195,7 +195,7 @@ static void articia_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out(dev, s->irq, ARRAY_SIZE(s->irq)); } -static void articia_class_init(ObjectClass *klass, void *data) +static void articia_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -228,7 +228,7 @@ static void articia_pci_host_cfg_write(PCIDevice *d, uint32_t addr, } } -static void articia_pci_host_class_init(ObjectClass *klass, void *data) +static void articia_pci_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -246,7 +246,7 @@ static void articia_pci_host_class_init(ObjectClass *klass, void *data) /* TYPE_ARTICIA_PCI_BRIDGE */ -static void articia_pci_bridge_class_init(ObjectClass *klass, void *data) +static void articia_pci_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -273,7 +273,7 @@ static const TypeInfo articia_types[] = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(ArticiaHostState), .class_init = articia_pci_host_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -283,7 +283,7 @@ static const TypeInfo articia_types[] = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = articia_pci_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-host/astro.c b/hw/pci-host/astro.c index 039cc3a..859e308 100644 --- a/hw/pci-host/astro.c +++ b/hw/pci-host/astro.c @@ -35,6 +35,7 @@ #include "target/hppa/cpu.h" #include "trace.h" #include "qom/object.h" +#include "exec/target_page.h" /* * Helper functions @@ -481,7 +482,7 @@ static const VMStateDescription vmstate_elroy = { } }; -static void elroy_pcihost_class_init(ObjectClass *klass, void *data) +static void elroy_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -908,7 +909,7 @@ static void astro_realize(DeviceState *obj, Error **errp) } } -static void astro_class_init(ObjectClass *klass, void *data) +static void astro_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -931,7 +932,7 @@ static const TypeInfo astro_chip_info = { }; static void astro_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 4966914..7d6251a 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -757,7 +757,7 @@ PCIBus *bonito_init(qemu_irq *pic) return phb->bus; } -static void bonito_pci_class_init(ObjectClass *klass, void *data) +static void bonito_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -783,13 +783,13 @@ static const TypeInfo bonito_pci_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIBonitoState), .class_init = bonito_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void bonito_host_class_init(ObjectClass *klass, void *data) +static void bonito_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/designware.c b/hw/pci-host/designware.c index 5598d18..f6e49ce 100644 --- a/hw/pci-host/designware.c +++ b/hw/pci-host/designware.c @@ -20,8 +20,8 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "qemu/module.h" #include "qemu/log.h" +#include "qemu/bitops.h" #include "hw/pci/msi.h" #include "hw/pci/pci_bridge.h" #include "hw/pci/pci_host.h" @@ -55,7 +55,8 @@ #define DESIGNWARE_PCIE_ATU_DEVFN(x) (((x) >> 16) & 0xff) #define DESIGNWARE_PCIE_ATU_UPPER_TARGET 0x91C -static void designware_pcie_root_bus_class_init(ObjectClass *klass, void *data) +static void designware_pcie_root_bus_class_init(ObjectClass *klass, + const void *data) { BusClass *k = BUS_CLASS(klass); @@ -162,11 +163,9 @@ designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len) break; case DESIGNWARE_PCIE_MSI_ADDR_LO: - val = root->msi.base; - break; - case DESIGNWARE_PCIE_MSI_ADDR_HI: - val = root->msi.base >> 32; + val = extract64(root->msi.base, + address == DESIGNWARE_PCIE_MSI_ADDR_LO ? 0 : 32, 32); break; case DESIGNWARE_PCIE_MSI_INTR0_ENABLE: @@ -190,19 +189,16 @@ designware_pcie_root_config_read(PCIDevice *d, uint32_t address, int len) break; case DESIGNWARE_PCIE_ATU_LOWER_BASE: - val = viewport->base; - break; - case DESIGNWARE_PCIE_ATU_UPPER_BASE: - val = viewport->base >> 32; + val = extract64(viewport->base, + address == DESIGNWARE_PCIE_ATU_LOWER_BASE ? 0 : 32, 32); break; case DESIGNWARE_PCIE_ATU_LOWER_TARGET: - val = viewport->target; - break; - case DESIGNWARE_PCIE_ATU_UPPER_TARGET: - val = viewport->target >> 32; + val = extract64(viewport->target, + address == DESIGNWARE_PCIE_ATU_LOWER_TARGET ? 0 : 32, + 32); break; case DESIGNWARE_PCIE_ATU_LIMIT: @@ -321,14 +317,10 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address, break; case DESIGNWARE_PCIE_MSI_ADDR_LO: - root->msi.base &= 0xFFFFFFFF00000000ULL; - root->msi.base |= val; - designware_pcie_root_update_msi_mapping(root); - break; - case DESIGNWARE_PCIE_MSI_ADDR_HI: - root->msi.base &= 0x00000000FFFFFFFFULL; - root->msi.base |= (uint64_t)val << 32; + root->msi.base = deposit64(root->msi.base, + address == DESIGNWARE_PCIE_MSI_ADDR_LO + ? 0 : 32, 32, val); designware_pcie_root_update_msi_mapping(root); break; @@ -355,23 +347,17 @@ static void designware_pcie_root_config_write(PCIDevice *d, uint32_t address, break; case DESIGNWARE_PCIE_ATU_LOWER_BASE: - viewport->base &= 0xFFFFFFFF00000000ULL; - viewport->base |= val; - break; - case DESIGNWARE_PCIE_ATU_UPPER_BASE: - viewport->base &= 0x00000000FFFFFFFFULL; - viewport->base |= (uint64_t)val << 32; + viewport->base = deposit64(viewport->base, + address == DESIGNWARE_PCIE_ATU_LOWER_BASE + ? 0 : 32, 32, val); break; case DESIGNWARE_PCIE_ATU_LOWER_TARGET: - viewport->target &= 0xFFFFFFFF00000000ULL; - viewport->target |= val; - break; - case DESIGNWARE_PCIE_ATU_UPPER_TARGET: - viewport->target &= 0x00000000FFFFFFFFULL; - viewport->target |= (uint64_t)val << 32; + viewport->target = deposit64(viewport->target, + address == DESIGNWARE_PCIE_ATU_LOWER_TARGET + ? 0 : 32, 32, val); break; case DESIGNWARE_PCIE_ATU_LIMIT: @@ -601,7 +587,8 @@ static const VMStateDescription vmstate_designware_pcie_root = { } }; -static void designware_pcie_root_class_init(ObjectClass *klass, void *data) +static void designware_pcie_root_class_init(ObjectClass *klass, + const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -741,7 +728,8 @@ static const VMStateDescription vmstate_designware_pcie_host = { } }; -static void designware_pcie_host_class_init(ObjectClass *klass, void *data) +static void designware_pcie_host_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); @@ -780,7 +768,7 @@ static const TypeInfo designware_pcie_types[] = { .parent = TYPE_PCI_BRIDGE, .instance_size = sizeof(DesignwarePCIERoot), .class_init = designware_pcie_root_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/pci-host/dino.c b/hw/pci-host/dino.c index 58fdbf7..11b353b 100644 --- a/hw/pci-host/dino.c +++ b/hw/pci-host/dino.c @@ -497,7 +497,7 @@ static const Property dino_pcihost_properties[] = { MemoryRegion *), }; -static void dino_pcihost_class_init(ObjectClass *klass, void *data) +static void dino_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/fsl_imx8m_phy.c b/hw/pci-host/fsl_imx8m_phy.c index aa304b1..04da3f9 100644 --- a/hw/pci-host/fsl_imx8m_phy.c +++ b/hw/pci-host/fsl_imx8m_phy.c @@ -76,7 +76,7 @@ static const VMStateDescription fsl_imx8m_pcie_phy_vmstate = { } }; -static void fsl_imx8m_pcie_phy_class_init(ObjectClass *klass, void *data) +static void fsl_imx8m_pcie_phy_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/pci-host/gpex-acpi.c b/hw/pci-host/gpex-acpi.c index e8b4c64..0aba47c 100644 --- a/hw/pci-host/gpex-acpi.c +++ b/hw/pci-host/gpex-acpi.c @@ -182,7 +182,7 @@ void acpi_dsdt_add_gpex(Aml *scope, struct GPEXConfig *cfg) /* * Resources defined for PXBs are composed of the following parts: - * 1. The resources the pci-brige/pcie-root-port need. + * 1. The resources the pci-bridge/pcie-root-port need. * 2. The resources the devices behind pxb need. */ crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent), &crs_range_set, diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c index 9fcedd7..b806a22 100644 --- a/hw/pci-host/gpex.c +++ b/hw/pci-host/gpex.c @@ -192,7 +192,7 @@ static const Property gpex_host_properties[] = { DEFINE_PROP_UINT8("num-irqs", GPEXHost, num_irqs, PCI_NUM_PINS), }; -static void gpex_host_class_init(ObjectClass *klass, void *data) +static void gpex_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); @@ -237,7 +237,7 @@ static const VMStateDescription vmstate_gpex_root = { } }; -static void gpex_root_class_init(ObjectClass *klass, void *data) +static void gpex_root_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -261,7 +261,7 @@ static const TypeInfo gpex_root_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(GPEXRootState), .class_init = gpex_root_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c index 84e5ee8..f9da5a9 100644 --- a/hw/pci-host/grackle.c +++ b/hw/pci-host/grackle.c @@ -94,7 +94,7 @@ static void grackle_pci_realize(PCIDevice *d, Error **errp) d->config[PCI_CLASS_PROG] = 0x01; } -static void grackle_pci_class_init(ObjectClass *klass, void *data) +static void grackle_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -116,7 +116,7 @@ static const TypeInfo grackle_pci_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = grackle_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -133,7 +133,7 @@ static const Property grackle_properties[] = { DEFINE_PROP_UINT32("ofw-addr", GrackleState, ofw_addr, -1), }; -static void grackle_class_init(ObjectClass *klass, void *data) +static void grackle_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); diff --git a/hw/pci-host/gt64120.c b/hw/pci-host/gt64120.c index d5c13a8..b12a256 100644 --- a/hw/pci-host/gt64120.c +++ b/hw/pci-host/gt64120.c @@ -320,38 +320,6 @@ static void gt64120_isd_mapping(GT64120State *s) memory_region_transaction_commit(); } -static void gt64120_update_pci_cfgdata_mapping(GT64120State *s) -{ - /* Indexed on MByteSwap bit, see Table 158: PCI_0 Command, Offset: 0xc00 */ - static const MemoryRegionOps *pci_host_data_ops[] = { - &pci_host_data_be_ops, &pci_host_data_le_ops - }; - PCIHostState *phb = PCI_HOST_BRIDGE(s); - - memory_region_transaction_begin(); - - /* - * The setting of the MByteSwap bit and MWordSwap bit in the PCI Internal - * Command Register determines how data transactions from the CPU to/from - * PCI are handled along with the setting of the Endianness bit in the CPU - * Configuration Register. See: - * - Table 16: 32-bit PCI Transaction Endianness - * - Table 158: PCI_0 Command, Offset: 0xc00 - */ - - if (memory_region_is_mapped(&phb->data_mem)) { - memory_region_del_subregion(&s->ISD_mem, &phb->data_mem); - object_unparent(OBJECT(&phb->data_mem)); - } - memory_region_init_io(&phb->data_mem, OBJECT(phb), - pci_host_data_ops[s->regs[GT_PCI0_CMD] & 1], - s, "pci-conf-data", 4); - memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGDATA << 2, - &phb->data_mem, 1); - - memory_region_transaction_commit(); -} - static void gt64120_pci_mapping(GT64120State *s) { memory_region_transaction_begin(); @@ -645,7 +613,6 @@ static void gt64120_writel(void *opaque, hwaddr addr, case GT_PCI0_CMD: case GT_PCI1_CMD: s->regs[saddr] = val & 0x0401fc0f; - gt64120_update_pci_cfgdata_mapping(s); break; case GT_PCI0_TOR: case GT_PCI0_BS_SCS10: @@ -1024,6 +991,48 @@ static const MemoryRegionOps isd_mem_ops = { }, }; +static bool bswap(const GT64120State *s) +{ + PCIHostState *phb = PCI_HOST_BRIDGE(s); + /*check for bus == 0 && device == 0, Bits 11:15 = Device , Bits 16:23 = Bus*/ + bool is_phb_dev0 = extract32(phb->config_reg, 11, 13) == 0; + bool le_mode = FIELD_EX32(s->regs[GT_PCI0_CMD], GT_PCI0_CMD, MByteSwap); + /* Only swap for non-bridge devices in big-endian mode */ + return !le_mode && !is_phb_dev0; +} + +static uint64_t gt64120_pci_data_read(void *opaque, hwaddr addr, unsigned size) +{ + GT64120State *s = opaque; + uint32_t val = pci_host_data_le_ops.read(opaque, addr, size); + + if (bswap(s)) { + val = bswap32(val); + } + return val; +} + +static void gt64120_pci_data_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + GT64120State *s = opaque; + + if (bswap(s)) { + val = bswap32(val); + } + pci_host_data_le_ops.write(opaque, addr, val, size); +} + +static const MemoryRegionOps gt64120_pci_data_ops = { + .read = gt64120_pci_data_read, + .write = gt64120_pci_data_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, + .max_access_size = 4, + }, +}; + static void gt64120_reset(DeviceState *dev) { GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev); @@ -1178,7 +1187,6 @@ static void gt64120_reset(DeviceState *dev) gt64120_isd_mapping(s); gt64120_pci_mapping(s); - gt64120_update_pci_cfgdata_mapping(s); } static void gt64120_realize(DeviceState *dev, Error **errp) @@ -1202,6 +1210,12 @@ static void gt64120_realize(DeviceState *dev, Error **errp) memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGADDR << 2, &phb->conf_mem, 1); + memory_region_init_io(&phb->data_mem, OBJECT(phb), + >64120_pci_data_ops, + s, "pci-conf-data", 4); + memory_region_add_subregion_overlap(&s->ISD_mem, GT_PCI0_CFGDATA << 2, + &phb->data_mem, 1); + /* * The whole address space decoded by the GT-64120A doesn't generate @@ -1244,7 +1258,7 @@ static void gt64120_pci_reset_hold(Object *obj, ResetType type) pci_set_byte(d->config + 0x3d, 0x01); } -static void gt64120_pci_class_init(ObjectClass *klass, void *data) +static void gt64120_pci_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -1268,7 +1282,7 @@ static const TypeInfo gt64120_pci_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = gt64120_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -1279,7 +1293,7 @@ static const Property gt64120_properties[] = { cpu_little_endian, false), }; -static void gt64120_class_init(ObjectClass *klass, void *data) +static void gt64120_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c index 1e69691..e13bb1b 100644 --- a/hw/pci-host/i440fx.c +++ b/hw/pci-host/i440fx.c @@ -315,7 +315,7 @@ static void i440fx_pcihost_realize(DeviceState *dev, Error **errp) i440fx_update_memory_mappings(f); } -static void i440fx_class_init(ObjectClass *klass, void *data) +static void i440fx_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -341,7 +341,7 @@ static const TypeInfo i440fx_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCII440FXState), .class_init = i440fx_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -364,7 +364,7 @@ static const Property i440fx_props[] = { DEFINE_PROP_STRING(I440FX_HOST_PROP_PCI_TYPE, I440FXState, pci_type), }; -static void i440fx_pcihost_class_init(ObjectClass *klass, void *data) +static void i440fx_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); diff --git a/hw/pci-host/mv64361.c b/hw/pci-host/mv64361.c index 9c41c15..e05b677 100644 --- a/hw/pci-host/mv64361.c +++ b/hw/pci-host/mv64361.c @@ -17,7 +17,7 @@ #include "hw/irq.h" #include "hw/intc/i8259.h" #include "hw/qdev-properties.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qemu/log.h" #include "qemu/error-report.h" #include "trace.h" @@ -26,7 +26,7 @@ #define TYPE_MV64361_PCI_BRIDGE "mv64361-pcibridge" -static void mv64361_pcibridge_class_init(ObjectClass *klass, void *data) +static void mv64361_pcibridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -46,7 +46,7 @@ static const TypeInfo mv64361_pcibridge_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = mv64361_pcibridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -102,7 +102,7 @@ static const Property mv64361_pcihost_props[] = { DEFINE_PROP_UINT8("index", MV64361PCIState, index, 0), }; -static void mv64361_pcihost_class_init(ObjectClass *klass, void *data) +static void mv64361_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -923,7 +923,7 @@ static void mv64361_reset(DeviceState *dev) set_mem_windows(s, 0xfbfff); } -static void mv64361_class_init(ObjectClass *klass, void *data) +static void mv64361_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/pnv_phb.c b/hw/pci-host/pnv_phb.c index 6c1e76f..4b0ced7 100644 --- a/hw/pci-host/pnv_phb.c +++ b/hw/pci-host/pnv_phb.c @@ -194,7 +194,7 @@ static const Property pnv_phb_properties[] = { PnvPhb4PecState *), }; -static void pnv_phb_class_init(ObjectClass *klass, void *data) +static void pnv_phb_class_init(ObjectClass *klass, const void *data) { PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -304,7 +304,7 @@ static const Property pnv_phb_root_port_properties[] = { DEFINE_PROP_UINT32("version", PnvPHBRootPort, version, 0), }; -static void pnv_phb_root_port_class_init(ObjectClass *klass, void *data) +static void pnv_phb_root_port_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/pci-host/pnv_phb3.c b/hw/pci-host/pnv_phb3.c index 82884e1..a4335f4 100644 --- a/hw/pci-host/pnv_phb3.c +++ b/hw/pci-host/pnv_phb3.c @@ -888,7 +888,7 @@ DECLARE_INSTANCE_CHECKER(IOMMUMemoryRegion, PNV_PHB3_IOMMU_MEMORY_REGION, TYPE_PNV_PHB3_IOMMU_MEMORY_REGION) static void pnv_phb3_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); @@ -1097,7 +1097,7 @@ static const Property pnv_phb3_properties[] = { DEFINE_PROP_LINK("phb-base", PnvPHB3, phb_base, TYPE_PNV_PHB, PnvPHB *), }; -static void pnv_phb3_class_init(ObjectClass *klass, void *data) +static void pnv_phb3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1149,7 +1149,7 @@ static void pnv_phb3_root_bus_set_prop(Object *obj, Visitor *v, } } -static void pnv_phb3_root_bus_class_init(ObjectClass *klass, void *data) +static void pnv_phb3_root_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); diff --git a/hw/pci-host/pnv_phb3_msi.c b/hw/pci-host/pnv_phb3_msi.c index 8198664..3a83311 100644 --- a/hw/pci-host/pnv_phb3_msi.c +++ b/hw/pci-host/pnv_phb3_msi.c @@ -284,7 +284,7 @@ static void phb3_msi_instance_init(Object *obj) ics->offset = 0; } -static void phb3_msi_class_init(ObjectClass *klass, void *data) +static void phb3_msi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ICSStateClass *isc = ICS_CLASS(klass); diff --git a/hw/pci-host/pnv_phb3_pbcq.c b/hw/pci-host/pnv_phb3_pbcq.c index 82f70ef..1f7a149 100644 --- a/hw/pci-host/pnv_phb3_pbcq.c +++ b/hw/pci-host/pnv_phb3_pbcq.c @@ -337,7 +337,7 @@ static void phb3_pbcq_instance_init(Object *obj) OBJ_PROP_LINK_STRONG); } -static void pnv_pbcq_class_init(ObjectClass *klass, void *data) +static void pnv_pbcq_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -354,7 +354,7 @@ static const TypeInfo pnv_pbcq_type_info = { .instance_size = sizeof(PnvPBCQState), .instance_init = phb3_pbcq_instance_init, .class_init = pnv_pbcq_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/pci-host/pnv_phb4.c b/hw/pci-host/pnv_phb4.c index 178c73f..77ea352 100644 --- a/hw/pci-host/pnv_phb4.c +++ b/hw/pci-host/pnv_phb4.c @@ -1362,7 +1362,7 @@ DECLARE_INSTANCE_CHECKER(IOMMUMemoryRegion, PNV_PHB4_IOMMU_MEMORY_REGION, TYPE_PNV_PHB4_IOMMU_MEMORY_REGION) static void pnv_phb4_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); @@ -1696,7 +1696,7 @@ static const Property pnv_phb4_properties[] = { DEFINE_PROP_LINK("phb-base", PnvPHB4, phb_base, TYPE_PNV_PHB, PnvPHB *), }; -static void pnv_phb4_class_init(ObjectClass *klass, void *data) +static void pnv_phb4_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XiveNotifierClass *xfc = XIVE_NOTIFIER_CLASS(klass); @@ -1714,7 +1714,7 @@ static const TypeInfo pnv_phb4_type_info = { .instance_init = pnv_phb4_instance_init, .instance_size = sizeof(PnvPHB4), .class_init = pnv_phb4_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XIVE_NOTIFIER }, { }, } @@ -1761,7 +1761,7 @@ static void pnv_phb4_root_bus_set_prop(Object *obj, Visitor *v, } } -static void pnv_phb4_root_bus_class_init(ObjectClass *klass, void *data) +static void pnv_phb4_root_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); diff --git a/hw/pci-host/pnv_phb4_pec.c b/hw/pci-host/pnv_phb4_pec.c index cb8a7e3..5bac1c4 100644 --- a/hw/pci-host/pnv_phb4_pec.c +++ b/hw/pci-host/pnv_phb4_pec.c @@ -354,7 +354,7 @@ static uint32_t pnv_pec_xscom_nest_base(PnvPhb4PecState *pec) */ static const uint32_t pnv_pec_num_phbs[] = { 1, 2, 3 }; -static void pnv_pec_class_init(ObjectClass *klass, void *data) +static void pnv_pec_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -388,7 +388,7 @@ static const TypeInfo pnv_pec_type_info = { .instance_size = sizeof(PnvPhb4PecState), .class_init = pnv_pec_class_init, .class_size = sizeof(PnvPhb4PecClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } @@ -419,7 +419,7 @@ static uint32_t pnv_phb5_pec_xscom_nest_base(PnvPhb4PecState *pec) */ static const uint32_t pnv_phb5_pec_num_stacks[] = { 3, 3 }; -static void pnv_phb5_pec_class_init(ObjectClass *klass, void *data) +static void pnv_phb5_pec_class_init(ObjectClass *klass, const void *data) { PnvPhb4PecClass *pecc = PNV_PHB4_PEC_CLASS(klass); static const char compat[] = "ibm,power10-pbcq"; @@ -445,7 +445,7 @@ static const TypeInfo pnv_phb5_pec_type_info = { .instance_size = sizeof(PnvPhb4PecState), .class_init = pnv_phb5_pec_class_init, .class_size = sizeof(PnvPhb4PecClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/pci-host/ppc440_pcix.c b/hw/pci-host/ppc440_pcix.c index 07924bc..744b85e 100644 --- a/hw/pci-host/ppc440_pcix.c +++ b/hw/pci-host/ppc440_pcix.c @@ -519,7 +519,7 @@ static void ppc440_pcix_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } -static void ppc440_pcix_class_init(ObjectClass *klass, void *data) +static void ppc440_pcix_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/ppc4xx_pci.c b/hw/pci-host/ppc4xx_pci.c index 292cb30..2547817 100644 --- a/hw/pci-host/ppc4xx_pci.c +++ b/hw/pci-host/ppc4xx_pci.c @@ -349,7 +349,7 @@ static void ppc4xx_pcihost_realize(DeviceState *dev, Error **errp) qemu_register_reset(ppc4xx_pci_reset, s); } -static void ppc4xx_host_bridge_class_init(ObjectClass *klass, void *data) +static void ppc4xx_host_bridge_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -370,13 +370,13 @@ static const TypeInfo ppc4xx_host_bridge_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = ppc4xx_host_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void ppc4xx_pcihost_class_init(ObjectClass *klass, void *data) +static void ppc4xx_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/ppce500.c b/hw/pci-host/ppce500.c index 9b905d1..52269b0 100644 --- a/hw/pci-host/ppce500.c +++ b/hw/pci-host/ppce500.c @@ -16,7 +16,6 @@ #include "qemu/osdep.h" #include "hw/irq.h" -#include "hw/ppc/e500-ccsr.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" #include "hw/pci/pci_device.h" @@ -418,11 +417,12 @@ static const VMStateDescription vmstate_ppce500_pci = { static void e500_pcihost_bridge_realize(PCIDevice *d, Error **errp) { PPCE500PCIBridgeState *b = PPC_E500_PCI_BRIDGE(d); - PPCE500CCSRState *ccsr = CCSR( + SysBusDevice *ccsr = SYS_BUS_DEVICE( object_resolve_path_component(qdev_get_machine(), "e500-ccsr")); + MemoryRegion *ccsr_space = sysbus_mmio_get_region(ccsr, 0); - memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", &ccsr->ccsr_space, - 0, int128_get64(ccsr->ccsr_space.size)); + memory_region_init_alias(&b->bar0, OBJECT(ccsr), "e500-pci-bar0", + ccsr_space, 0, int128_get64(ccsr_space->size)); pci_register_bar(d, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &b->bar0); } @@ -490,7 +490,7 @@ static void e500_pcihost_realize(DeviceState *dev, Error **errp) pci_bus_set_route_irq_fn(b, e500_route_intx_pin_to_irq); } -static void e500_host_bridge_class_init(ObjectClass *klass, void *data) +static void e500_host_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -512,7 +512,7 @@ static const Property pcihost_properties[] = { DEFINE_PROP_UINT32("first_pin_irq", PPCE500PCIState, first_pin_irq, 0x1), }; -static void e500_pcihost_class_init(ObjectClass *klass, void *data) +static void e500_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -528,7 +528,7 @@ static const TypeInfo e500_pci_types[] = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PPCE500PCIBridgeState), .class_init = e500_host_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c index 06be3d7..1951ae4 100644 --- a/hw/pci-host/q35.c +++ b/hw/pci-host/q35.c @@ -184,7 +184,7 @@ static const Property q35_host_props[] = { DEFINE_PROP_BOOL("x-pci-hole64-fix", Q35PCIHost, pci_hole64_fix, true), }; -static void q35_host_class_init(ObjectClass *klass, void *data) +static void q35_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); @@ -667,7 +667,7 @@ static const Property mch_props[] = { DEFINE_PROP_BOOL("smbase-smram", MCHPCIState, has_smram_at_smbase, true), }; -static void mch_class_init(ObjectClass *klass, void *data) +static void mch_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -703,7 +703,7 @@ static const TypeInfo mch_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(MCHPCIState), .class_init = mch_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-host/raven.c b/hw/pci-host/raven.c index e3d8d20..f8c0be5 100644 --- a/hw/pci-host/raven.c +++ b/hw/pci-host/raven.c @@ -24,7 +24,6 @@ */ #include "qemu/osdep.h" -#include "qemu/datadir.h" #include "qemu/units.h" #include "qemu/log.h" #include "qapi/error.h" @@ -35,9 +34,7 @@ #include "migration/vmstate.h" #include "hw/intc/i8259.h" #include "hw/irq.h" -#include "hw/loader.h" #include "hw/or-irq.h" -#include "elf.h" #include "qom/object.h" #define TYPE_RAVEN_PCI_DEVICE "raven" @@ -47,10 +44,6 @@ OBJECT_DECLARE_SIMPLE_TYPE(RavenPCIState, RAVEN_PCI_DEVICE) struct RavenPCIState { PCIDevice dev; - - uint32_t elf_machine; - char *bios_name; - MemoryRegion bios; }; typedef struct PRePPCIState PREPPCIState; @@ -75,11 +68,8 @@ struct PRePPCIState { RavenPCIState pci_dev; int contiguous_map; - bool is_legacy_prep; }; -#define BIOS_SIZE (1 * MiB) - #define PCI_IO_BASE_ADDR 0x80000000 /* Physical address on main bus */ static inline uint32_t raven_pci_io_config(hwaddr addr) @@ -243,22 +233,18 @@ static void raven_pcihost_realizefn(DeviceState *d, Error **errp) MemoryRegion *address_space_mem = get_system_memory(); int i; - if (s->is_legacy_prep) { - for (i = 0; i < PCI_NUM_PINS; i++) { - sysbus_init_irq(dev, &s->pci_irqs[i]); - } - } else { - /* According to PReP specification section 6.1.6 "System Interrupt - * Assignments", all PCI interrupts are routed via IRQ 15 */ - s->or_irq = OR_IRQ(object_new(TYPE_OR_IRQ)); - object_property_set_int(OBJECT(s->or_irq), "num-lines", PCI_NUM_PINS, - &error_fatal); - qdev_realize(DEVICE(s->or_irq), NULL, &error_fatal); - sysbus_init_irq(dev, &s->or_irq->out_irq); - - for (i = 0; i < PCI_NUM_PINS; i++) { - s->pci_irqs[i] = qdev_get_gpio_in(DEVICE(s->or_irq), i); - } + /* + * According to PReP specification section 6.1.6 "System Interrupt + * Assignments", all PCI interrupts are routed via IRQ 15 + */ + s->or_irq = OR_IRQ(object_new(TYPE_OR_IRQ)); + object_property_set_int(OBJECT(s->or_irq), "num-lines", PCI_NUM_PINS, + &error_fatal); + qdev_realize(DEVICE(s->or_irq), NULL, &error_fatal); + sysbus_init_irq(dev, &s->or_irq->out_irq); + + for (i = 0; i < PCI_NUM_PINS; i++) { + s->pci_irqs[i] = qdev_get_gpio_in(DEVICE(s->or_irq), i); } qdev_init_gpio_in(d, raven_change_gpio, 1); @@ -338,48 +324,9 @@ static void raven_pcihost_initfn(Object *obj) static void raven_realize(PCIDevice *d, Error **errp) { - RavenPCIState *s = RAVEN_PCI_DEVICE(d); - char *filename; - int bios_size = -1; - d->config[PCI_CACHE_LINE_SIZE] = 0x08; d->config[PCI_LATENCY_TIMER] = 0x10; d->config[PCI_CAPABILITY_LIST] = 0x00; - - if (!memory_region_init_rom_nomigrate(&s->bios, OBJECT(s), "bios", - BIOS_SIZE, errp)) { - return; - } - memory_region_add_subregion(get_system_memory(), (uint32_t)(-BIOS_SIZE), - &s->bios); - if (s->bios_name) { - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, s->bios_name); - if (filename) { - if (s->elf_machine != EM_NONE) { - bios_size = load_elf(filename, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, - ELFDATA2MSB, s->elf_machine, 0, 0); - } - if (bios_size < 0) { - bios_size = get_image_size(filename); - if (bios_size > 0 && bios_size <= BIOS_SIZE) { - hwaddr bios_addr; - bios_size = (bios_size + 0xfff) & ~0xfff; - bios_addr = (uint32_t)(-BIOS_SIZE); - bios_size = load_image_targphys(filename, bios_addr, - bios_size); - } - } - } - g_free(filename); - if (bios_size < 0 || bios_size > BIOS_SIZE) { - memory_region_del_subregion(get_system_memory(), &s->bios); - error_setg(errp, "Could not load bios image '%s'", s->bios_name); - return; - } - } - - vmstate_register_ram_global(&s->bios); } static const VMStateDescription vmstate_raven = { @@ -392,7 +339,7 @@ static const VMStateDescription vmstate_raven = { }, }; -static void raven_class_init(ObjectClass *klass, void *data) +static void raven_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -416,28 +363,18 @@ static const TypeInfo raven_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(RavenPCIState), .class_init = raven_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static const Property raven_pcihost_properties[] = { - DEFINE_PROP_UINT32("elf-machine", PREPPCIState, pci_dev.elf_machine, - EM_NONE), - DEFINE_PROP_STRING("bios-name", PREPPCIState, pci_dev.bios_name), - /* Temporary workaround until legacy prep machine is removed */ - DEFINE_PROP_BOOL("is-legacy-prep", PREPPCIState, is_legacy_prep, - false), -}; - -static void raven_pcihost_class_init(ObjectClass *klass, void *data) +static void raven_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories); dc->realize = raven_pcihost_realizefn; - device_class_set_props(dc, raven_pcihost_properties); dc->fw_name = "pci"; } diff --git a/hw/pci-host/remote.c b/hw/pci-host/remote.c index bfb25ef..e6d2af4 100644 --- a/hw/pci-host/remote.c +++ b/hw/pci-host/remote.c @@ -28,7 +28,7 @@ #include "hw/pci/pcie_host.h" #include "hw/qdev-properties.h" #include "hw/pci-host/remote.h" -#include "exec/memory.h" +#include "system/memory.h" static const char *remote_pcihost_root_bus_path(PCIHostState *host_bridge, PCIBus *rootbus) @@ -46,7 +46,7 @@ static void remote_pcihost_realize(DeviceState *dev, Error **errp) 0, TYPE_PCIE_BUS); } -static void remote_pcihost_class_init(ObjectClass *klass, void *data) +static void remote_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); diff --git a/hw/pci-host/sabre.c b/hw/pci-host/sabre.c index be6641d..538624c 100644 --- a/hw/pci-host/sabre.c +++ b/hw/pci-host/sabre.c @@ -456,7 +456,7 @@ static void sabre_pci_realize(PCIDevice *d, Error **errp) PCI_STATUS_DEVSEL_MEDIUM); } -static void sabre_pci_class_init(ObjectClass *klass, void *data) +static void sabre_pci_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -477,7 +477,7 @@ static const TypeInfo sabre_pci_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(SabrePCIState), .class_init = sabre_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -497,7 +497,7 @@ static const Property sabre_properties[] = { DEFINE_PROP_UINT64("mem-base", SabreState, mem_base, 0), }; -static void sabre_class_init(ObjectClass *klass, void *data) +static void sabre_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); diff --git a/hw/pci-host/sh_pci.c b/hw/pci-host/sh_pci.c index 4edebce..de8f6a8 100644 --- a/hw/pci-host/sh_pci.c +++ b/hw/pci-host/sh_pci.c @@ -153,7 +153,7 @@ static void sh_pcic_pci_realize(PCIDevice *d, Error **errp) PCI_STATUS_FAST_BACK | PCI_STATUS_DEVSEL_MEDIUM); } -static void sh_pcic_pci_class_init(ObjectClass *klass, void *data) +static void sh_pcic_pci_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -168,7 +168,7 @@ static void sh_pcic_pci_class_init(ObjectClass *klass, void *data) dc->user_creatable = false; } -static void sh_pcic_host_class_init(ObjectClass *klass, void *data) +static void sh_pcic_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -186,7 +186,7 @@ static const TypeInfo sh_pcic_types[] = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = sh_pcic_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 37e2461..194037d 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -311,7 +311,7 @@ static void unin_internal_pci_host_realize(PCIDevice *d, Error **errp) d->config[PCI_CAPABILITY_LIST] = 0x00; } -static void unin_main_pci_host_class_init(ObjectClass *klass, void *data) +static void unin_main_pci_host_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -333,13 +333,13 @@ static const TypeInfo unin_main_pci_host_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = unin_main_pci_host_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void u3_agp_pci_host_class_init(ObjectClass *klass, void *data) +static void u3_agp_pci_host_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -361,13 +361,13 @@ static const TypeInfo u3_agp_pci_host_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = u3_agp_pci_host_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void unin_agp_pci_host_class_init(ObjectClass *klass, void *data) +static void unin_agp_pci_host_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -389,13 +389,14 @@ static const TypeInfo unin_agp_pci_host_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = unin_agp_pci_host_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void unin_internal_pci_host_class_init(ObjectClass *klass, void *data) +static void unin_internal_pci_host_class_init(ObjectClass *klass, + const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -417,7 +418,7 @@ static const TypeInfo unin_internal_pci_host_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = unin_internal_pci_host_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -427,7 +428,7 @@ static const Property pci_unin_main_pci_host_props[] = { DEFINE_PROP_UINT32("ofw-addr", UNINHostState, ofw_addr, -1), }; -static void pci_unin_main_class_init(ObjectClass *klass, void *data) +static void pci_unin_main_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); @@ -447,7 +448,7 @@ static const TypeInfo pci_unin_main_info = { .class_init = pci_unin_main_class_init, }; -static void pci_u3_agp_class_init(ObjectClass *klass, void *data) +static void pci_u3_agp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -463,7 +464,7 @@ static const TypeInfo pci_u3_agp_info = { .class_init = pci_u3_agp_class_init, }; -static void pci_unin_agp_class_init(ObjectClass *klass, void *data) +static void pci_unin_agp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -479,7 +480,7 @@ static const TypeInfo pci_unin_agp_info = { .class_init = pci_unin_agp_class_init, }; -static void pci_unin_internal_class_init(ObjectClass *klass, void *data) +static void pci_unin_internal_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -535,7 +536,7 @@ static void unin_init(Object *obj) sysbus_init_mmio(sbd, &s->mem); } -static void unin_class_init(ObjectClass *klass, void *data) +static void unin_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c index 33a8ceb..8ea26e3 100644 --- a/hw/pci-host/versatile.c +++ b/hw/pci-host/versatile.c @@ -471,7 +471,7 @@ static void versatile_pci_host_realize(PCIDevice *d, Error **errp) pci_set_byte(d->config + PCI_LATENCY_TIMER, 0x10); } -static void versatile_pci_host_class_init(ObjectClass *klass, void *data) +static void versatile_pci_host_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -492,7 +492,7 @@ static const TypeInfo versatile_pci_host_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = versatile_pci_host_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -503,7 +503,7 @@ static const Property pci_vpb_properties[] = { PCI_VPB_IRQMAP_ASSUME_OK), }; -static void pci_vpb_class_init(ObjectClass *klass, void *data) +static void pci_vpb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/pci-host/xen_igd_pt.c b/hw/pci-host/xen_igd_pt.c index d094b67..5dd17ef 100644 --- a/hw/pci-host/xen_igd_pt.c +++ b/hw/pci-host/xen_igd_pt.c @@ -95,7 +95,8 @@ static void igd_pt_i440fx_realize(PCIDevice *pci_dev, Error **errp) } } -static void igd_passthrough_i440fx_class_init(ObjectClass *klass, void *data) +static void igd_passthrough_i440fx_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/pci-host/xilinx-pcie.c b/hw/pci-host/xilinx-pcie.c index 1868848..c71492d 100644 --- a/hw/pci-host/xilinx-pcie.c +++ b/hw/pci-host/xilinx-pcie.c @@ -165,7 +165,7 @@ static const Property xilinx_pcie_host_props[] = { DEFINE_PROP_BOOL("link_up", XilinxPCIEHost, link_up, true), }; -static void xilinx_pcie_host_class_init(ObjectClass *klass, void *data) +static void xilinx_pcie_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); @@ -286,7 +286,7 @@ static void xilinx_pcie_root_realize(PCIDevice *pci_dev, Error **errp) } } -static void xilinx_pcie_root_class_init(ObjectClass *klass, void *data) +static void xilinx_pcie_root_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -314,7 +314,7 @@ static const TypeInfo xilinx_pcie_root_info = { .parent = TYPE_PCI_BRIDGE, .instance_size = sizeof(XilinxPCIERoot), .class_init = xilinx_pcie_root_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 66f27b9..8c7f670 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -72,7 +72,7 @@ static uint8_t *msix_pending_byte(PCIDevice *dev, int vector) return dev->msix_pba + vector / 8; } -static int msix_is_pending(PCIDevice *dev, int vector) +int msix_is_pending(PCIDevice *dev, unsigned int vector) { return *msix_pending_byte(dev, vector) & msix_pending_mask(vector); } diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 2844ec5..c70b5ce 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -32,6 +32,7 @@ #include "hw/pci/pci_host.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" +#include "migration/cpr.h" #include "migration/qemu-file-types.h" #include "migration/vmstate.h" #include "net/net.h" @@ -54,13 +55,6 @@ #include "hw/xen/xen.h" #include "hw/i386/kvm/xen_evtchn.h" -//#define DEBUG_PCI -#ifdef DEBUG_PCI -# define PCI_DPRINTF(format, ...) printf(format, ## __VA_ARGS__) -#else -# define PCI_DPRINTF(format, ...) do { } while (0) -#endif - bool pci_available = true; static char *pcibus_get_dev_path(DeviceState *dev); @@ -101,6 +95,7 @@ static const Property pci_props[] = { QEMU_PCIE_ARI_NEXTFN_1_BITNR, false), DEFINE_PROP_SIZE32("x-max-bounce-buffer-size", PCIDevice, max_bounce_buffer_size, DEFAULT_MAX_BOUNCE_BUFFER_SIZE), + DEFINE_PROP_STRING("sriov-pf", PCIDevice, sriov_pf), DEFINE_PROP_BIT("x-pcie-ext-tag", PCIDevice, cap_present, QEMU_PCIE_EXT_TAG_BITNR, true), { .name = "busnr", .info = &prop_pci_busnr }, @@ -134,6 +129,12 @@ static GSequence *pci_acpi_index_list(void) return used_acpi_index_list; } +static void pci_set_master(PCIDevice *d, bool enable) +{ + memory_region_set_enabled(&d->bus_master_enable_region, enable); + d->is_master = enable; /* cache the status */ +} + static void pci_init_bus_master(PCIDevice *pci_dev) { AddressSpace *dma_as = pci_device_iommu_address_space(pci_dev); @@ -141,7 +142,7 @@ static void pci_init_bus_master(PCIDevice *pci_dev) memory_region_init_alias(&pci_dev->bus_master_enable_region, OBJECT(pci_dev), "bus master", dma_as->root, 0, memory_region_size(dma_as->root)); - memory_region_set_enabled(&pci_dev->bus_master_enable_region, false); + pci_set_master(pci_dev, false); memory_region_add_subregion(&pci_dev->bus_master_container_region, 0, &pci_dev->bus_master_enable_region); } @@ -261,7 +262,7 @@ static GByteArray *pci_bus_fw_cfg_gen_data(Object *obj, Error **errp) return byte_array; } -static void pci_bus_class_init(ObjectClass *klass, void *data) +static void pci_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); PCIBusClass *pbc = PCI_BUS_CLASS(klass); @@ -288,7 +289,7 @@ static const TypeInfo pci_bus_info = { .instance_size = sizeof(PCIBus), .class_size = sizeof(PCIBusClass), .class_init = pci_bus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_CFG_DATA_GENERATOR_INTERFACE }, { } } @@ -309,7 +310,7 @@ static const TypeInfo conventional_pci_interface_info = { .parent = TYPE_INTERFACE, }; -static void pcie_bus_class_init(ObjectClass *klass, void *data) +static void pcie_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -537,6 +538,10 @@ static void pci_reset_regions(PCIDevice *dev) static void pci_do_device_reset(PCIDevice *dev) { + if ((dev->cap_present & QEMU_PCI_SKIP_RESET_ON_CPR) && cpr_is_incoming()) { + return; + } + pci_device_deassert_intx(dev); assert(dev->irq_state == 0); @@ -810,9 +815,8 @@ static int get_pci_config_device(QEMUFile *f, void *pv, size_t size, pci_bridge_update_mappings(PCI_BRIDGE(s)); } - memory_region_set_enabled(&s->bus_master_enable_region, - pci_get_word(s->config + PCI_COMMAND) - & PCI_COMMAND_MASTER); + pci_set_master(s, pci_get_word(s->config + PCI_COMMAND) + & PCI_COMMAND_MASTER); g_free(config); return 0; @@ -1112,13 +1116,8 @@ static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev, Error **errp) dev->config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION; } - /* - * With SR/IOV and ARI, a device at function 0 need not be a multifunction - * device, as it may just be a VF that ended up with function 0 in - * the legacy PCI interpretation. Avoid failing in such cases: - */ - if (pci_is_vf(dev) && - dev->exp.sriov_vf.pf->cap_present & QEMU_PCI_CAP_MULTIFUNCTION) { + /* SR/IOV is not handled here. */ + if (pci_is_vf(dev)) { return; } @@ -1151,7 +1150,8 @@ static void pci_init_multifunction(PCIBus *bus, PCIDevice *dev, Error **errp) } /* function 0 indicates single function, so function > 0 must be NULL */ for (func = 1; func < PCI_FUNC_MAX; ++func) { - if (bus->devices[PCI_DEVFN(slot, func)]) { + PCIDevice *device = bus->devices[PCI_DEVFN(slot, func)]; + if (device && !pci_is_vf(device)) { error_setg(errp, "PCI: %x.0 indicates single function, " "but %x.%x is already populated.", slot, slot, func); @@ -1439,6 +1439,7 @@ static void pci_qdev_unrealize(DeviceState *dev) pci_unregister_io_regions(pci_dev); pci_del_option_rom(pci_dev); + pcie_sriov_unregister_device(pci_dev); if (pc->exit) { pc->exit(pci_dev); @@ -1470,7 +1471,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, pcibus_t size = memory_region_size(memory); uint8_t hdr_type; - assert(!pci_is_vf(pci_dev)); /* VFs must use pcie_sriov_vf_register_bar */ assert(region_num >= 0); assert(region_num < PCI_NUM_REGIONS); assert(is_power_of_2(size)); @@ -1482,7 +1482,6 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, r = &pci_dev->io_regions[region_num]; assert(!r->size); - r->addr = PCI_BAR_UNMAPPED; r->size = size; r->type = type; r->memory = memory; @@ -1490,22 +1489,35 @@ void pci_register_bar(PCIDevice *pci_dev, int region_num, ? pci_get_bus(pci_dev)->address_space_io : pci_get_bus(pci_dev)->address_space_mem; - wmask = ~(size - 1); - if (region_num == PCI_ROM_SLOT) { - /* ROM enable bit is writable */ - wmask |= PCI_ROM_ADDRESS_ENABLE; - } - - addr = pci_bar(pci_dev, region_num); - pci_set_long(pci_dev->config + addr, type); + if (pci_is_vf(pci_dev)) { + PCIDevice *pf = pci_dev->exp.sriov_vf.pf; + assert(!pf || type == pf->exp.sriov_pf.vf_bar_type[region_num]); - if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) && - r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) { - pci_set_quad(pci_dev->wmask + addr, wmask); - pci_set_quad(pci_dev->cmask + addr, ~0ULL); + r->addr = pci_bar_address(pci_dev, region_num, r->type, r->size); + if (r->addr != PCI_BAR_UNMAPPED) { + memory_region_add_subregion_overlap(r->address_space, + r->addr, r->memory, 1); + } } else { - pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff); - pci_set_long(pci_dev->cmask + addr, 0xffffffff); + r->addr = PCI_BAR_UNMAPPED; + + wmask = ~(size - 1); + if (region_num == PCI_ROM_SLOT) { + /* ROM enable bit is writable */ + wmask |= PCI_ROM_ADDRESS_ENABLE; + } + + addr = pci_bar(pci_dev, region_num); + pci_set_long(pci_dev->config + addr, type); + + if (!(r->type & PCI_BASE_ADDRESS_SPACE_IO) && + r->type & PCI_BASE_ADDRESS_MEM_TYPE_64) { + pci_set_quad(pci_dev->wmask + addr, wmask); + pci_set_quad(pci_dev->cmask + addr, ~0ULL); + } else { + pci_set_long(pci_dev->wmask + addr, wmask & 0xffffffff); + pci_set_long(pci_dev->cmask + addr, 0xffffffff); + } } } @@ -1594,7 +1606,11 @@ static pcibus_t pci_config_get_bar_addr(PCIDevice *d, int reg, pci_get_word(pf->config + sriov_cap + PCI_SRIOV_VF_OFFSET); uint16_t vf_stride = pci_get_word(pf->config + sriov_cap + PCI_SRIOV_VF_STRIDE); - uint32_t vf_num = (d->devfn - (pf->devfn + vf_offset)) / vf_stride; + uint32_t vf_num = d->devfn - (pf->devfn + vf_offset); + + if (vf_num) { + vf_num /= vf_stride; + } if (type & PCI_BASE_ADDRESS_MEM_TYPE_64) { new_addr = pci_get_quad(pf->config + bar); @@ -1719,7 +1735,7 @@ static void pci_update_mappings(PCIDevice *d) pci_update_vga(d); } -static inline int pci_irq_disabled(PCIDevice *d) +int pci_irq_disabled(PCIDevice *d) { return pci_get_word(d->config + PCI_COMMAND) & PCI_COMMAND_INTX_DISABLE; } @@ -1781,9 +1797,8 @@ void pci_default_write_config(PCIDevice *d, uint32_t addr, uint32_t val_in, int if (ranges_overlap(addr, l, PCI_COMMAND, 2)) { pci_update_irq_disabled(d, was_irq_disabled); - memory_region_set_enabled(&d->bus_master_enable_region, - (pci_get_word(d->config + PCI_COMMAND) - & PCI_COMMAND_MASTER) && d->enabled); + pci_set_master(d, (pci_get_word(d->config + PCI_COMMAND) & + PCI_COMMAND_MASTER) && d->enabled); } msi_write_config(d, addr, val_in, l); @@ -2268,6 +2283,11 @@ static void pci_qdev_realize(DeviceState *qdev, Error **errp) } } + if (!pcie_sriov_register_device(pci_dev, errp)) { + pci_qdev_unrealize(DEVICE(pci_dev)); + return; + } + /* * A PCIe Downstream Port that do not have ARI Forwarding enabled must * associate only Device 0 with the device attached to the bus @@ -2439,12 +2459,12 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, uint32_t size) /* Only a valid rom will be patched. */ rom_magic = pci_get_word(ptr); if (rom_magic != 0xaa55) { - PCI_DPRINTF("Bad ROM magic %04x\n", rom_magic); + trace_pci_bad_rom_magic(rom_magic, 0xaa55); return; } pcir_offset = pci_get_word(ptr + 0x18); if (pcir_offset + 8 >= size || memcmp(ptr + pcir_offset, "PCIR", 4)) { - PCI_DPRINTF("Bad PCIR offset 0x%x or signature\n", pcir_offset); + trace_pci_bad_pcir_offset(pcir_offset); return; } @@ -2453,8 +2473,8 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, uint32_t size) rom_vendor_id = pci_get_word(ptr + pcir_offset + 4); rom_device_id = pci_get_word(ptr + pcir_offset + 6); - PCI_DPRINTF("%s: ROM id %04x%04x / PCI id %04x%04x\n", pdev->romfile, - vendor_id, device_id, rom_vendor_id, rom_device_id); + trace_pci_rom_and_pci_ids(pdev->romfile, vendor_id, device_id, + rom_vendor_id, rom_device_id); checksum = ptr[6]; @@ -2462,7 +2482,7 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, uint32_t size) /* Patch vendor id and checksum (at offset 6 for etherboot roms). */ checksum += (uint8_t)rom_vendor_id + (uint8_t)(rom_vendor_id >> 8); checksum -= (uint8_t)vendor_id + (uint8_t)(vendor_id >> 8); - PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum); + trace_pci_rom_checksum_change(ptr[6], checksum); ptr[6] = checksum; pci_set_word(ptr + pcir_offset + 4, vendor_id); } @@ -2471,7 +2491,7 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, uint32_t size) /* Patch device id and checksum (at offset 6 for etherboot roms). */ checksum += (uint8_t)rom_device_id + (uint8_t)(rom_device_id >> 8); checksum -= (uint8_t)device_id + (uint8_t)(device_id >> 8); - PCI_DPRINTF("ROM checksum %02x / %02x\n", ptr[6], checksum); + trace_pci_rom_checksum_change(ptr[6], checksum); ptr[6] = checksum; pci_set_word(ptr + pcir_offset + 6, device_id); } @@ -2522,6 +2542,14 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, return; } + if (pci_is_vf(pdev)) { + if (pdev->rom_bar > 0) { + error_setg(errp, "ROM BAR cannot be enabled for SR-IOV VF"); + } + + return; + } + if (load_file || pdev->romsize == UINT32_MAX) { path = qemu_find_file(QEMU_FILE_TYPE_BIOS, pdev->romfile); if (path == NULL) { @@ -2795,7 +2823,7 @@ MemoryRegion *pci_address_space_io(PCIDevice *dev) return pci_get_bus(dev)->address_space_io; } -static void pci_device_class_init(ObjectClass *klass, void *data) +static void pci_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); @@ -2809,7 +2837,7 @@ static void pci_device_class_init(ObjectClass *klass, void *data) "access to indirect DMA memory"); } -static void pci_device_class_base_init(ObjectClass *klass, void *data) +static void pci_device_class_base_init(ObjectClass *klass, const void *data) { if (!object_class_is_abstract(klass)) { ObjectClass *conventional = @@ -2916,6 +2944,23 @@ AddressSpace *pci_device_iommu_address_space(PCIDevice *dev) return &address_space_memory; } +int pci_iommu_init_iotlb_notifier(PCIDevice *dev, IOMMUNotifier *n, + IOMMUNotify fn, void *opaque) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->init_iotlb_notifier) { + iommu_bus->iommu_ops->init_iotlb_notifier(bus, iommu_bus->iommu_opaque, + devfn, n, fn, opaque); + return 0; + } + + return -ENODEV; +} + bool pci_device_set_iommu_device(PCIDevice *dev, HostIOMMUDevice *hiod, Error **errp) { @@ -2947,6 +2992,170 @@ void pci_device_unset_iommu_device(PCIDevice *dev) } } +int pci_pri_request_page(PCIDevice *dev, uint32_t pasid, bool priv_req, + bool exec_req, hwaddr addr, bool lpig, + uint16_t prgi, bool is_read, bool is_write) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + if (!dev->is_master || + ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) { + return -EPERM; + } + + if (!pcie_pri_enabled(dev)) { + return -EPERM; + } + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->pri_request_page) { + return iommu_bus->iommu_ops->pri_request_page(bus, + iommu_bus->iommu_opaque, + devfn, pasid, priv_req, + exec_req, addr, lpig, prgi, + is_read, is_write); + } + + return -ENODEV; +} + +int pci_pri_register_notifier(PCIDevice *dev, uint32_t pasid, + IOMMUPRINotifier *notifier) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + if (!dev->is_master || + ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) { + return -EPERM; + } + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->pri_register_notifier) { + iommu_bus->iommu_ops->pri_register_notifier(bus, + iommu_bus->iommu_opaque, + devfn, pasid, notifier); + return 0; + } + + return -ENODEV; +} + +void pci_pri_unregister_notifier(PCIDevice *dev, uint32_t pasid) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->pri_unregister_notifier) { + iommu_bus->iommu_ops->pri_unregister_notifier(bus, + iommu_bus->iommu_opaque, + devfn, pasid); + } +} + +ssize_t pci_ats_request_translation(PCIDevice *dev, uint32_t pasid, + bool priv_req, bool exec_req, + hwaddr addr, size_t length, + bool no_write, IOMMUTLBEntry *result, + size_t result_length, + uint32_t *err_count) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + if (!dev->is_master || + ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev))) { + return -EPERM; + } + + if (result_length == 0) { + return -ENOSPC; + } + + if (!pcie_ats_enabled(dev)) { + return -EPERM; + } + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->ats_request_translation) { + return iommu_bus->iommu_ops->ats_request_translation(bus, + iommu_bus->iommu_opaque, + devfn, pasid, priv_req, + exec_req, addr, length, + no_write, result, + result_length, err_count); + } + + return -ENODEV; +} + +int pci_iommu_register_iotlb_notifier(PCIDevice *dev, uint32_t pasid, + IOMMUNotifier *n) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + if ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev)) { + return -EPERM; + } + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->register_iotlb_notifier) { + iommu_bus->iommu_ops->register_iotlb_notifier(bus, + iommu_bus->iommu_opaque, devfn, + pasid, n); + return 0; + } + + return -ENODEV; +} + +int pci_iommu_unregister_iotlb_notifier(PCIDevice *dev, uint32_t pasid, + IOMMUNotifier *n) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + if ((pasid != PCI_NO_PASID) && !pcie_pasid_enabled(dev)) { + return -EPERM; + } + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->unregister_iotlb_notifier) { + iommu_bus->iommu_ops->unregister_iotlb_notifier(bus, + iommu_bus->iommu_opaque, + devfn, pasid, n); + return 0; + } + + return -ENODEV; +} + +int pci_iommu_get_iotlb_info(PCIDevice *dev, uint8_t *addr_width, + uint32_t *min_page_size) +{ + PCIBus *bus; + PCIBus *iommu_bus; + int devfn; + + pci_device_get_iommu_bus_devfn(dev, &bus, &iommu_bus, &devfn); + if (iommu_bus && iommu_bus->iommu_ops->get_iotlb_info) { + iommu_bus->iommu_ops->get_iotlb_info(iommu_bus->iommu_opaque, + addr_width, min_page_size); + return 0; + } + + return -ENODEV; +} + void pci_setup_iommu(PCIBus *bus, const PCIIOMMUOps *ops, void *opaque) { /* @@ -3081,9 +3290,8 @@ void pci_set_enabled(PCIDevice *d, bool state) d->enabled = state; pci_update_mappings(d); - memory_region_set_enabled(&d->bus_master_enable_region, - (pci_get_word(d->config + PCI_COMMAND) - & PCI_COMMAND_MASTER) && d->enabled); + pci_set_master(d, (pci_get_word(d->config + PCI_COMMAND) + & PCI_COMMAND_MASTER) && d->enabled); if (qdev_is_realized(&d->qdev)) { pci_device_reset(d); } diff --git a/hw/pci/pci_bridge.c b/hw/pci/pci_bridge.c index aee4dd7..76255c4 100644 --- a/hw/pci/pci_bridge.c +++ b/hw/pci/pci_bridge.c @@ -482,7 +482,7 @@ static const Property pci_bridge_properties[] = { pcie_writeable_slt_bug, false), }; -static void pci_bridge_class_init(ObjectClass *klass, void *data) +static void pci_bridge_class_init(ObjectClass *klass, const void *data) { AcpiDevAmlIfClass *adevc = ACPI_DEV_AML_IF_CLASS(klass); DeviceClass *k = DEVICE_CLASS(klass); @@ -497,7 +497,7 @@ static const TypeInfo pci_bridge_type_info = { .instance_size = sizeof(PCIBridge), .class_init = pci_bridge_class_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c index 80f91f4..7179d99 100644 --- a/hw/pci/pci_host.c +++ b/hw/pci/pci_host.c @@ -217,12 +217,6 @@ const MemoryRegionOps pci_host_data_le_ops = { .endianness = DEVICE_LITTLE_ENDIAN, }; -const MemoryRegionOps pci_host_data_be_ops = { - .read = pci_host_data_read, - .write = pci_host_data_write, - .endianness = DEVICE_BIG_ENDIAN, -}; - static bool pci_host_needed(void *opaque) { PCIHostState *s = opaque; @@ -246,7 +240,7 @@ static const Property pci_host_properties_common[] = { DEFINE_PROP_BOOL(PCI_HOST_BYPASS_IOMMU, PCIHostState, bypass_iommu, false), }; -static void pci_host_class_init(ObjectClass *klass, void *data) +static void pci_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); device_class_set_props(dc, pci_host_properties_common); diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c index 1b12db6..eaeb688 100644 --- a/hw/pci/pcie.c +++ b/hw/pci/pcie.c @@ -1214,3 +1214,81 @@ void pcie_acs_reset(PCIDevice *dev) pci_set_word(dev->config + dev->exp.acs_cap + PCI_ACS_CTRL, 0); } } + +/* PASID */ +void pcie_pasid_init(PCIDevice *dev, uint16_t offset, uint8_t pasid_width, + bool exec_perm, bool priv_mod) +{ + static const uint16_t control_reg_rw_mask = 0x07; + uint16_t capability_reg; + + assert(pasid_width <= PCI_EXT_CAP_PASID_MAX_WIDTH); + + pcie_add_capability(dev, PCI_EXT_CAP_ID_PASID, PCI_PASID_VER, offset, + PCI_EXT_CAP_PASID_SIZEOF); + + capability_reg = ((uint16_t)pasid_width) << PCI_PASID_CAP_WIDTH_SHIFT; + capability_reg |= exec_perm ? PCI_PASID_CAP_EXEC : 0; + capability_reg |= priv_mod ? PCI_PASID_CAP_PRIV : 0; + pci_set_word(dev->config + offset + PCI_PASID_CAP, capability_reg); + + /* Everything is disabled by default */ + pci_set_word(dev->config + offset + PCI_PASID_CTRL, 0); + + pci_set_word(dev->wmask + offset + PCI_PASID_CTRL, control_reg_rw_mask); + + dev->exp.pasid_cap = offset; +} + +/* PRI */ +void pcie_pri_init(PCIDevice *dev, uint16_t offset, uint32_t outstanding_pr_cap, + bool prg_response_pasid_req) +{ + static const uint16_t control_reg_rw_mask = 0x3; + static const uint16_t status_reg_rw1_mask = 0x3; + static const uint32_t pr_alloc_reg_rw_mask = 0xffffffff; + uint16_t status_reg; + + status_reg = prg_response_pasid_req ? PCI_PRI_STATUS_PASID : 0; + status_reg |= PCI_PRI_STATUS_STOPPED; /* Stopped by default */ + + pcie_add_capability(dev, PCI_EXT_CAP_ID_PRI, PCI_PRI_VER, offset, + PCI_EXT_CAP_PRI_SIZEOF); + /* Disabled by default */ + + pci_set_word(dev->config + offset + PCI_PRI_STATUS, status_reg); + pci_set_long(dev->config + offset + PCI_PRI_MAX_REQ, outstanding_pr_cap); + + pci_set_word(dev->wmask + offset + PCI_PRI_CTRL, control_reg_rw_mask); + pci_set_word(dev->w1cmask + offset + PCI_PRI_STATUS, status_reg_rw1_mask); + pci_set_long(dev->wmask + offset + PCI_PRI_ALLOC_REQ, pr_alloc_reg_rw_mask); + + dev->exp.pri_cap = offset; +} + +bool pcie_pri_enabled(const PCIDevice *dev) +{ + if (!pci_is_express(dev) || !dev->exp.pri_cap) { + return false; + } + return (pci_get_word(dev->config + dev->exp.pri_cap + PCI_PRI_CTRL) & + PCI_PRI_CTRL_ENABLE) != 0; +} + +bool pcie_pasid_enabled(const PCIDevice *dev) +{ + if (!pci_is_express(dev) || !dev->exp.pasid_cap) { + return false; + } + return (pci_get_word(dev->config + dev->exp.pasid_cap + PCI_PASID_CTRL) & + PCI_PASID_CTRL_ENABLE) != 0; +} + +bool pcie_ats_enabled(const PCIDevice *dev) +{ + if (!pci_is_express(dev) || !dev->exp.ats_cap) { + return false; + } + return (pci_get_word(dev->config + dev->exp.ats_cap + PCI_ATS_CTRL) & + PCI_ATS_CTRL_ENABLE) != 0; +} diff --git a/hw/pci/pcie_port.c b/hw/pci/pcie_port.c index c73db30..f3841a2 100644 --- a/hw/pci/pcie_port.c +++ b/hw/pci/pcie_port.c @@ -118,7 +118,7 @@ static const Property pcie_port_props[] = { PCIE_AER_LOG_MAX_DEFAULT), }; -static void pcie_port_class_init(ObjectClass *oc, void *data) +static void pcie_port_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -188,7 +188,7 @@ int pcie_count_ds_ports(PCIBus *bus) return dsp_count; } -static bool pcie_slot_is_hotpluggbale_bus(HotplugHandler *plug_handler, +static bool pcie_slot_is_hotpluggable_bus(HotplugHandler *plug_handler, BusState *bus) { PCIESlot *s = PCIE_SLOT(bus->parent); @@ -211,7 +211,7 @@ static const Property pcie_slot_props[] = { hide_native_hotplug_cap, false), }; -static void pcie_slot_class_init(ObjectClass *oc, void *data) +static void pcie_slot_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -221,7 +221,7 @@ static void pcie_slot_class_init(ObjectClass *oc, void *data) hc->plug = pcie_cap_slot_plug_cb; hc->unplug = pcie_cap_slot_unplug_cb; hc->unplug_request = pcie_cap_slot_unplug_request_cb; - hc->is_hotpluggable_bus = pcie_slot_is_hotpluggbale_bus; + hc->is_hotpluggable_bus = pcie_slot_is_hotpluggable_bus; } static const TypeInfo pcie_slot_type_info = { @@ -230,7 +230,7 @@ static const TypeInfo pcie_slot_type_info = { .instance_size = sizeof(PCIESlot), .abstract = true, .class_init = pcie_slot_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/pci/pcie_sriov.c b/hw/pci/pcie_sriov.c index 1eb4358..3ad1874 100644 --- a/hw/pci/pcie_sriov.c +++ b/hw/pci/pcie_sriov.c @@ -15,11 +15,12 @@ #include "hw/pci/pcie.h" #include "hw/pci/pci_bus.h" #include "hw/qdev-properties.h" -#include "qemu/error-report.h" #include "qemu/range.h" #include "qapi/error.h" #include "trace.h" +static GHashTable *pfs; + static void unparent_vfs(PCIDevice *dev, uint16_t total_vfs) { for (uint16_t i = 0; i < total_vfs; i++) { @@ -31,17 +32,57 @@ static void unparent_vfs(PCIDevice *dev, uint16_t total_vfs) dev->exp.sriov_pf.vf = NULL; } -bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset, - const char *vfname, uint16_t vf_dev_id, - uint16_t init_vfs, uint16_t total_vfs, - uint16_t vf_offset, uint16_t vf_stride, - Error **errp) +static void register_vfs(PCIDevice *dev) +{ + uint16_t num_vfs; + uint16_t i; + uint16_t sriov_cap = dev->exp.sriov_cap; + + assert(sriov_cap > 0); + num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF); + + trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn), num_vfs); + for (i = 0; i < num_vfs; i++) { + pci_set_enabled(dev->exp.sriov_pf.vf[i], true); + } + + pci_set_word(dev->wmask + sriov_cap + PCI_SRIOV_NUM_VF, 0); +} + +static void unregister_vfs(PCIDevice *dev) +{ + uint8_t *cfg = dev->config + dev->exp.sriov_cap; + uint16_t i; + + trace_sriov_unregister_vfs(dev->name, PCI_SLOT(dev->devfn), + PCI_FUNC(dev->devfn)); + for (i = 0; i < pci_get_word(cfg + PCI_SRIOV_TOTAL_VF); i++) { + pci_set_enabled(dev->exp.sriov_pf.vf[i], false); + } + + pci_set_word(dev->wmask + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0xffff); +} + +static bool pcie_sriov_pf_init_common(PCIDevice *dev, uint16_t offset, + uint16_t vf_dev_id, uint16_t init_vfs, + uint16_t total_vfs, uint16_t vf_offset, + uint16_t vf_stride, Error **errp) { - BusState *bus = qdev_get_parent_bus(&dev->qdev); int32_t devfn = dev->devfn + vf_offset; uint8_t *cfg = dev->config + offset; uint8_t *wmask; + if (!pci_is_express(dev)) { + error_setg(errp, "PCI Express is required for SR-IOV PF"); + return false; + } + + if (pci_is_vf(dev)) { + error_setg(errp, "a device cannot be a SR-IOV PF and a VF at the same time"); + return false; + } + if (total_vfs && (uint32_t)devfn + (uint32_t)(total_vfs - 1) * vf_stride >= PCI_DEVFN_MAX) { error_setg(errp, "VF addr overflows"); @@ -84,6 +125,28 @@ bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset, qdev_prop_set_bit(&dev->qdev, "multifunction", true); + return true; +} + +bool pcie_sriov_pf_init(PCIDevice *dev, uint16_t offset, + const char *vfname, uint16_t vf_dev_id, + uint16_t init_vfs, uint16_t total_vfs, + uint16_t vf_offset, uint16_t vf_stride, + Error **errp) +{ + BusState *bus = qdev_get_parent_bus(&dev->qdev); + int32_t devfn = dev->devfn + vf_offset; + + if (pfs && g_hash_table_contains(pfs, dev->qdev.id)) { + error_setg(errp, "attaching user-created SR-IOV VF unsupported"); + return false; + } + + if (!pcie_sriov_pf_init_common(dev, offset, vf_dev_id, init_vfs, + total_vfs, vf_offset, vf_stride, errp)) { + return false; + } + dev->exp.sriov_pf.vf = g_new(PCIDevice *, total_vfs); for (uint16_t i = 0; i < total_vfs; i++) { @@ -113,7 +176,22 @@ void pcie_sriov_pf_exit(PCIDevice *dev) { uint8_t *cfg = dev->config + dev->exp.sriov_cap; - unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF)); + if (dev->exp.sriov_pf.vf_user_created) { + uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID); + uint16_t total_vfs = pci_get_word(dev->config + PCI_SRIOV_TOTAL_VF); + uint16_t vf_dev_id = pci_get_word(dev->config + PCI_SRIOV_VF_DID); + + unregister_vfs(dev); + + for (uint16_t i = 0; i < total_vfs; i++) { + dev->exp.sriov_pf.vf[i]->exp.sriov_vf.pf = NULL; + + pci_config_set_vendor_id(dev->exp.sriov_pf.vf[i]->config, ven_id); + pci_config_set_device_id(dev->exp.sriov_pf.vf[i]->config, vf_dev_id); + } + } else { + unparent_vfs(dev, pci_get_word(cfg + PCI_SRIOV_TOTAL_VF)); + } } void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num, @@ -146,69 +224,179 @@ void pcie_sriov_pf_init_vf_bar(PCIDevice *dev, int region_num, void pcie_sriov_vf_register_bar(PCIDevice *dev, int region_num, MemoryRegion *memory) { - PCIIORegion *r; - PCIBus *bus = pci_get_bus(dev); uint8_t type; - pcibus_t size = memory_region_size(memory); - assert(pci_is_vf(dev)); /* PFs must use pci_register_bar */ - assert(region_num >= 0); - assert(region_num < PCI_NUM_REGIONS); + assert(dev->exp.sriov_vf.pf); type = dev->exp.sriov_vf.pf->exp.sriov_pf.vf_bar_type[region_num]; - if (!is_power_of_2(size)) { - error_report("%s: PCI region size must be a power" - " of two - type=0x%x, size=0x%"FMT_PCIBUS, - __func__, type, size); - exit(1); - } + return pci_register_bar(dev, region_num, type, memory); +} - r = &dev->io_regions[region_num]; - r->memory = memory; - r->address_space = - type & PCI_BASE_ADDRESS_SPACE_IO - ? bus->address_space_io - : bus->address_space_mem; - r->size = size; - r->type = type; - - r->addr = pci_bar_address(dev, region_num, r->type, r->size); - if (r->addr != PCI_BAR_UNMAPPED) { - memory_region_add_subregion_overlap(r->address_space, - r->addr, r->memory, 1); - } +static gint compare_vf_devfns(gconstpointer a, gconstpointer b) +{ + return (*(PCIDevice **)a)->devfn - (*(PCIDevice **)b)->devfn; } -static void register_vfs(PCIDevice *dev) +int16_t pcie_sriov_pf_init_from_user_created_vfs(PCIDevice *dev, + uint16_t offset, + Error **errp) { - uint16_t num_vfs; + GPtrArray *pf; + PCIDevice **vfs; + BusState *bus = qdev_get_parent_bus(DEVICE(dev)); + uint16_t ven_id = pci_get_word(dev->config + PCI_VENDOR_ID); + uint16_t size = PCI_EXT_CAP_SRIOV_SIZEOF; + uint16_t vf_dev_id; + uint16_t vf_offset; + uint16_t vf_stride; uint16_t i; - uint16_t sriov_cap = dev->exp.sriov_cap; - assert(sriov_cap > 0); - num_vfs = pci_get_word(dev->config + sriov_cap + PCI_SRIOV_NUM_VF); + if (!pfs || !dev->qdev.id) { + return 0; + } - trace_sriov_register_vfs(dev->name, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), num_vfs); - for (i = 0; i < num_vfs; i++) { - pci_set_enabled(dev->exp.sriov_pf.vf[i], true); + pf = g_hash_table_lookup(pfs, dev->qdev.id); + if (!pf) { + return 0; } - pci_set_word(dev->wmask + sriov_cap + PCI_SRIOV_NUM_VF, 0); + if (pf->len > UINT16_MAX) { + error_setg(errp, "too many VFs"); + return -1; + } + + g_ptr_array_sort(pf, compare_vf_devfns); + vfs = (void *)pf->pdata; + + if (vfs[0]->devfn <= dev->devfn) { + error_setg(errp, "a VF function number is less than the PF function number"); + return -1; + } + + vf_dev_id = pci_get_word(vfs[0]->config + PCI_DEVICE_ID); + vf_offset = vfs[0]->devfn - dev->devfn; + vf_stride = pf->len < 2 ? 0 : vfs[1]->devfn - vfs[0]->devfn; + + for (i = 0; i < pf->len; i++) { + if (bus != qdev_get_parent_bus(&vfs[i]->qdev)) { + error_setg(errp, "SR-IOV VF parent bus mismatches with PF"); + return -1; + } + + if (ven_id != pci_get_word(vfs[i]->config + PCI_VENDOR_ID)) { + error_setg(errp, "SR-IOV VF vendor ID mismatches with PF"); + return -1; + } + + if (vf_dev_id != pci_get_word(vfs[i]->config + PCI_DEVICE_ID)) { + error_setg(errp, "inconsistent SR-IOV VF device IDs"); + return -1; + } + + for (size_t j = 0; j < PCI_NUM_REGIONS; j++) { + if (vfs[i]->io_regions[j].size != vfs[0]->io_regions[j].size || + vfs[i]->io_regions[j].type != vfs[0]->io_regions[j].type) { + error_setg(errp, "inconsistent SR-IOV BARs"); + return -1; + } + } + + if (vfs[i]->devfn - vfs[0]->devfn != vf_stride * i) { + error_setg(errp, "inconsistent SR-IOV stride"); + return -1; + } + } + + if (!pcie_sriov_pf_init_common(dev, offset, vf_dev_id, pf->len, + pf->len, vf_offset, vf_stride, errp)) { + return -1; + } + + if (!pcie_find_capability(dev, PCI_EXT_CAP_ID_ARI)) { + pcie_ari_init(dev, offset + size); + size += PCI_ARI_SIZEOF; + } + + for (i = 0; i < pf->len; i++) { + vfs[i]->exp.sriov_vf.pf = dev; + vfs[i]->exp.sriov_vf.vf_number = i; + + /* set vid/did according to sr/iov spec - they are not used */ + pci_config_set_vendor_id(vfs[i]->config, 0xffff); + pci_config_set_device_id(vfs[i]->config, 0xffff); + } + + dev->exp.sriov_pf.vf = vfs; + dev->exp.sriov_pf.vf_user_created = true; + + for (i = 0; i < PCI_NUM_REGIONS; i++) { + PCIIORegion *region = &vfs[0]->io_regions[i]; + + if (region->size) { + pcie_sriov_pf_init_vf_bar(dev, i, region->type, region->size); + } + } + + return size; } -static void unregister_vfs(PCIDevice *dev) +bool pcie_sriov_register_device(PCIDevice *dev, Error **errp) { - uint8_t *cfg = dev->config + dev->exp.sriov_cap; - uint16_t i; + if (!dev->exp.sriov_pf.vf && dev->qdev.id && + pfs && g_hash_table_contains(pfs, dev->qdev.id)) { + error_setg(errp, "attaching user-created SR-IOV VF unsupported"); + return false; + } - trace_sriov_unregister_vfs(dev->name, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); - for (i = 0; i < pci_get_word(cfg + PCI_SRIOV_TOTAL_VF); i++) { - pci_set_enabled(dev->exp.sriov_pf.vf[i], false); + if (dev->sriov_pf) { + PCIDevice *pci_pf; + GPtrArray *pf; + + if (!PCI_DEVICE_GET_CLASS(dev)->sriov_vf_user_creatable) { + error_setg(errp, "user cannot create SR-IOV VF with this device type"); + return false; + } + + if (!pci_is_express(dev)) { + error_setg(errp, "PCI Express is required for SR-IOV VF"); + return false; + } + + if (!pci_qdev_find_device(dev->sriov_pf, &pci_pf)) { + error_setg(errp, "PCI device specified as SR-IOV PF already exists"); + return false; + } + + if (!pfs) { + pfs = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); + } + + pf = g_hash_table_lookup(pfs, dev->sriov_pf); + if (!pf) { + pf = g_ptr_array_new(); + g_hash_table_insert(pfs, g_strdup(dev->sriov_pf), pf); + } + + g_ptr_array_add(pf, dev); } - pci_set_word(dev->wmask + dev->exp.sriov_cap + PCI_SRIOV_NUM_VF, 0xffff); + return true; +} + +void pcie_sriov_unregister_device(PCIDevice *dev) +{ + if (dev->sriov_pf && pfs) { + GPtrArray *pf = g_hash_table_lookup(pfs, dev->sriov_pf); + + if (pf) { + g_ptr_array_remove_fast(pf, dev); + + if (!pf->len) { + g_hash_table_remove(pfs, dev->sriov_pf); + g_ptr_array_free(pf, FALSE); + } + } + } } void pcie_sriov_config_write(PCIDevice *dev, uint32_t address, @@ -304,7 +492,7 @@ void pcie_sriov_pf_add_sup_pgsize(PCIDevice *dev, uint16_t opt_sup_pgsize) uint16_t pcie_sriov_vf_number(PCIDevice *dev) { - assert(pci_is_vf(dev)); + assert(dev->exp.sriov_vf.pf); return dev->exp.sriov_vf.vf_number; } diff --git a/hw/pci/trace-events b/hw/pci/trace-events index 6a99689..02c80d3 100644 --- a/hw/pci/trace-events +++ b/hw/pci/trace-events @@ -6,6 +6,10 @@ pci_pm_transition(const char *dev, uint32_t bus, uint32_t slot, uint32_t func, u pci_update_mappings_del(const char *dev, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "%s %02x:%02x.%x %d,0x%"PRIx64"+0x%"PRIx64 pci_update_mappings_add(const char *dev, uint32_t bus, uint32_t slot, uint32_t func, int bar, uint64_t addr, uint64_t size) "%s %02x:%02x.%x %d,0x%"PRIx64"+0x%"PRIx64 pci_route_irq(int dev_irq, const char *dev_path, int parent_irq, const char *parent_path) "IRQ %d @%s -> IRQ %d @%s" +pci_bad_rom_magic(uint16_t bad_rom_magic, uint16_t good_rom_magic) "Bad ROM magic number: %04"PRIX16". Should be: %04"PRIX16 +pci_bad_pcir_offset(uint16_t pcir_offset) "Bad PCIR offset 0x%"PRIx16" or signature" +pci_rom_and_pci_ids(char *romfile, uint16_t vendor_id, uint16_t device_id, uint16_t rom_vendor_id, uint16_t rom_device_id) "%s: ROM ID %04"PRIx16":%04"PRIx16" | PCI ID %04"PRIx16":%04"PRIx16 +pci_rom_checksum_change(uint8_t old_checksum, uint8_t new_checksum) "ROM checksum changed from %02"PRIx8" to %02"PRIx8 # pci_host.c pci_cfg_read(const char *dev, uint32_t bus, uint32_t slot, uint32_t func, unsigned offs, unsigned val) "%s %02x:%02x.%x @0x%x -> 0x%x" diff --git a/hw/ppc/amigaone.c b/hw/ppc/amigaone.c index e9407a5..12279f4 100644 --- a/hw/ppc/amigaone.c +++ b/hw/ppc/amigaone.c @@ -173,7 +173,7 @@ static const Property nvram_properties[] = { DEFINE_PROP_DRIVE("drive", A1NVRAMState, blk), }; -static void nvram_class_init(ObjectClass *oc, void *data) +static void nvram_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c index 69269aa..723c97f 100644 --- a/hw/ppc/e500.c +++ b/hw/ppc/e500.c @@ -18,6 +18,7 @@ #include "qemu/datadir.h" #include "qemu/units.h" #include "qemu/guest-random.h" +#include "exec/target_page.h" #include "qapi/error.h" #include "e500.h" #include "e500-ccsr.h" @@ -78,8 +79,6 @@ #define MPC85XX_ESDHC_IRQ 72 #define RTC_REGS_OFFSET 0x68 -#define PLATFORM_CLK_FREQ_HZ (400 * 1000 * 1000) - struct boot_info { uint32_t dt_base; @@ -119,7 +118,7 @@ static uint32_t *pci_map_create(void *fdt, uint32_t mpic, int first_slot, } static void dt_serial_create(void *fdt, unsigned long long offset, - const char *soc, const char *mpic, + const char *soc, uint32_t freq, const char *mpic, const char *alias, int idx, bool defcon) { char *ser; @@ -130,7 +129,7 @@ static void dt_serial_create(void *fdt, unsigned long long offset, qemu_fdt_setprop_string(fdt, ser, "compatible", "ns16550"); qemu_fdt_setprop_cells(fdt, ser, "reg", offset, 0x100); qemu_fdt_setprop_cell(fdt, ser, "cell-index", idx); - qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", PLATFORM_CLK_FREQ_HZ); + qemu_fdt_setprop_cell(fdt, ser, "clock-frequency", freq); qemu_fdt_setprop_cells(fdt, ser, "interrupts", 42, 2); qemu_fdt_setprop_phandle(fdt, ser, "interrupt-parent", mpic); qemu_fdt_setprop_string(fdt, "/aliases", alias, ser); @@ -381,8 +380,7 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, int fdt_size; void *fdt; uint8_t hypercall[16]; - uint32_t clock_freq = PLATFORM_CLK_FREQ_HZ; - uint32_t tb_freq = PLATFORM_CLK_FREQ_HZ; + uint32_t clock_freq, tb_freq; int i; char compatible_sb[] = "fsl,mpc8544-immr\0simple-bus"; char *soc; @@ -410,7 +408,7 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, if (dtb_file) { char *filename; - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, dtb_file); + filename = qemu_find_file(QEMU_FILE_TYPE_DTB, dtb_file); if (!filename) { goto out; } @@ -483,6 +481,9 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, if (kvmppc_get_hasidle(env)) { qemu_fdt_setprop(fdt, "/hypervisor", "has-idle", NULL, 0); } + } else { + clock_freq = pmc->clock_freq; + tb_freq = pmc->tb_freq; } /* Create CPU nodes */ @@ -563,12 +564,12 @@ static int ppce500_load_device_tree(PPCE500MachineState *pms, */ if (serial_hd(1)) { dt_serial_create(fdt, MPC8544_SERIAL1_REGS_OFFSET, - soc, mpic, "serial1", 1, false); + soc, pmc->clock_freq, mpic, "serial1", 1, false); } if (serial_hd(0)) { dt_serial_create(fdt, MPC8544_SERIAL0_REGS_OFFSET, - soc, mpic, "serial0", 0, true); + soc, pmc->clock_freq, mpic, "serial0", 0, true); } /* i2c */ @@ -930,7 +931,6 @@ void ppce500_init(MachineState *machine) CPUPPCState *firstenv = NULL; MemoryRegion *ccsr_addr_space; SysBusDevice *s; - PPCE500CCSRState *ccsr; I2CBus *i2c; irqs = g_new0(IrqLines, smp_cpus); @@ -967,7 +967,7 @@ void ppce500_init(MachineState *machine) env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i; env->mpic_iack = pmc->ccsrbar_base + MPC8544_MPIC_REGS_OFFSET + 0xa0; - ppc_booke_timers_init(cpu, PLATFORM_CLK_FREQ_HZ, PPC_TIMER_E500); + ppc_booke_timers_init(cpu, pmc->tb_freq, PPC_TIMER_E500); /* Register reset handler */ if (!i) { @@ -992,10 +992,10 @@ void ppce500_init(MachineState *machine) memory_region_add_subregion(address_space_mem, 0, machine->ram); dev = qdev_new("e500-ccsr"); + s = SYS_BUS_DEVICE(dev); object_property_add_child(OBJECT(machine), "e500-ccsr", OBJECT(dev)); - sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); - ccsr = CCSR(dev); - ccsr_addr_space = &ccsr->ccsr_space; + sysbus_realize_and_unref(s, &error_fatal); + ccsr_addr_space = sysbus_mmio_get_region(s, 0); memory_region_add_subregion(address_space_mem, pmc->ccsrbar_base, ccsr_addr_space); @@ -1283,6 +1283,7 @@ static void e500_ccsr_initfn(Object *obj) PPCE500CCSRState *ccsr = CCSR(obj); memory_region_init(&ccsr->ccsr_space, obj, "e500-ccsr", MPC8544_CCSRBAR_SIZE); + sysbus_init_mmio(SYS_BUS_DEVICE(ccsr), &ccsr->ccsr_space); } static const TypeInfo e500_ccsr_info = { diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h index 01db102..00f4905 100644 --- a/hw/ppc/e500.h +++ b/hw/ppc/e500.h @@ -5,6 +5,8 @@ #include "hw/platform-bus.h" #include "qom/object.h" +#define PLATFORM_CLK_FREQ_HZ (400 * 1000 * 1000) + struct PPCE500MachineState { /*< private >*/ MachineState parent_obj; @@ -37,6 +39,8 @@ struct PPCE500MachineClass { hwaddr pci_mmio_base; hwaddr pci_mmio_bus_base; hwaddr spin_base; + uint32_t clock_freq; + uint32_t tb_freq; }; void ppce500_init(MachineState *machine); diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c index 70a8033..4f1d659 100644 --- a/hw/ppc/e500plat.c +++ b/hw/ppc/e500plat.c @@ -68,7 +68,7 @@ HotplugHandler *e500plat_machine_get_hotpug_handler(MachineState *machine, #define TYPE_E500PLAT_MACHINE MACHINE_TYPE_NAME("ppce500") -static void e500plat_machine_class_init(ObjectClass *oc, void *data) +static void e500plat_machine_class_init(ObjectClass *oc, const void *data) { PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -93,6 +93,8 @@ static void e500plat_machine_class_init(ObjectClass *oc, void *data) pmc->pci_mmio_base = 0xC00000000ULL; pmc->pci_mmio_bus_base = 0xE0000000ULL; pmc->spin_base = 0xFEF000000ULL; + pmc->clock_freq = PLATFORM_CLK_FREQ_HZ; + pmc->tb_freq = PLATFORM_CLK_FREQ_HZ; mc->desc = "generic paravirt e500 platform"; mc->init = e500plat_init; @@ -107,7 +109,7 @@ static const TypeInfo e500plat_info = { .name = TYPE_E500PLAT_MACHINE, .parent = TYPE_PPCE500_MACHINE, .class_init = e500plat_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c index 8109e21..0b6e096 100644 --- a/hw/ppc/mac_newworld.c +++ b/hw/ppc/mac_newworld.c @@ -50,6 +50,7 @@ #include "qemu/datadir.h" #include "qemu/units.h" #include "qapi/error.h" +#include "exec/target_page.h" #include "hw/ppc/ppc.h" #include "hw/qdev-properties.h" #include "hw/nvram/mac_nvram.h" @@ -562,7 +563,7 @@ static int core99_kvm_type(MachineState *machine, const char *arg) return 2; } -static void core99_machine_class_init(ObjectClass *oc, void *data) +static void core99_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); @@ -638,7 +639,7 @@ static const TypeInfo core99_machine_info = { .class_init = core99_machine_class_init, .instance_init = core99_instance_init, .instance_size = sizeof(Core99MachineState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { } }, diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c index b581469..40ae936 100644 --- a/hw/ppc/mac_oldworld.c +++ b/hw/ppc/mac_oldworld.c @@ -28,6 +28,7 @@ #include "qemu/datadir.h" #include "qemu/units.h" #include "qapi/error.h" +#include "exec/target_page.h" #include "hw/ppc/ppc.h" #include "hw/qdev-properties.h" #include "hw/boards.h" @@ -401,7 +402,7 @@ static int heathrow_kvm_type(MachineState *machine, const char *arg) return 2; } -static void heathrow_class_init(ObjectClass *oc, void *data) +static void heathrow_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); @@ -429,7 +430,7 @@ static const TypeInfo ppc_heathrow_machine_info = { .name = MACHINE_TYPE_NAME("g3beige"), .parent = TYPE_MACHINE, .class_init = heathrow_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { } }, diff --git a/hw/ppc/mpc8544ds.c b/hw/ppc/mpc8544ds.c index d74af76..5826985 100644 --- a/hw/ppc/mpc8544ds.c +++ b/hw/ppc/mpc8544ds.c @@ -37,7 +37,7 @@ static void mpc8544ds_init(MachineState *machine) ppce500_init(machine); } -static void mpc8544ds_machine_class_init(ObjectClass *oc, void *data) +static void mpc8544ds_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); PPCE500MachineClass *pmc = PPCE500_MACHINE_CLASS(oc); @@ -55,6 +55,8 @@ static void mpc8544ds_machine_class_init(ObjectClass *oc, void *data) pmc->pci_mmio_bus_base = 0xC0000000ULL; pmc->pci_pio_base = 0xE1000000ULL; pmc->spin_base = 0xEF000000ULL; + pmc->clock_freq = PLATFORM_CLK_FREQ_HZ; + pmc->tb_freq = PLATFORM_CLK_FREQ_HZ; mc->desc = "mpc8544ds"; mc->init = mpc8544ds_init; diff --git a/hw/ppc/pef.c b/hw/ppc/pef.c index 8b2d726..254f570 100644 --- a/hw/ppc/pef.c +++ b/hw/ppc/pef.c @@ -128,7 +128,7 @@ OBJECT_DEFINE_TYPE_WITH_INTERFACES(PefGuest, { TYPE_USER_CREATABLE }, { NULL }) -static void pef_guest_class_init(ObjectClass *oc, void *data) +static void pef_guest_class_init(ObjectClass *oc, const void *data) { ConfidentialGuestSupportClass *klass = CONFIDENTIAL_GUEST_SUPPORT_CLASS(oc); diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c index 246d6d6..e15cf96 100644 --- a/hw/ppc/pegasos2.c +++ b/hw/ppc/pegasos2.c @@ -31,7 +31,7 @@ #include "qemu/error-report.h" #include "system/kvm.h" #include "kvm_ppc.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/qom-qobject.h" #include "qobject/qdict.h" #include "trace.h" @@ -588,7 +588,7 @@ static bool pegasos2_setprop(MachineState *ms, const char *path, return true; } -static void pegasos2_machine_class_init(ObjectClass *oc, void *data) +static void pegasos2_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); PPCVirtualHypervisorClass *vhc = PPC_VIRTUAL_HYPERVISOR_CLASS(oc); @@ -619,7 +619,7 @@ static const TypeInfo pegasos2_machine_info = { .parent = TYPE_MACHINE, .class_init = pegasos2_machine_class_init, .instance_size = sizeof(Pegasos2MachineState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PPC_VIRTUAL_HYPERVISOR }, { TYPE_VOF_MACHINE_IF }, { } diff --git a/hw/ppc/pnv.c b/hw/ppc/pnv.c index 63f2232..4a49e9d 100644 --- a/hw/ppc/pnv.c +++ b/hw/ppc/pnv.c @@ -1618,7 +1618,7 @@ static uint32_t pnv_chip_power8_xscom_pcba(PnvChip *chip, uint64_t addr) return ((addr >> 4) & ~0xfull) | ((addr >> 3) & 0xf); } -static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) +static void pnv_chip_power8e_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); @@ -1642,7 +1642,7 @@ static void pnv_chip_power8e_class_init(ObjectClass *klass, void *data) &k->parent_realize); } -static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) +static void pnv_chip_power8_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); @@ -1666,7 +1666,7 @@ static void pnv_chip_power8_class_init(ObjectClass *klass, void *data) &k->parent_realize); } -static void pnv_chip_power8nvl_class_init(ObjectClass *klass, void *data) +static void pnv_chip_power8nvl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); @@ -1954,7 +1954,7 @@ static uint32_t pnv_chip_power9_xscom_pcba(PnvChip *chip, uint64_t addr) return addr >> 3; } -static void pnv_chip_power9_class_init(ObjectClass *klass, void *data) +static void pnv_chip_power9_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); @@ -2302,7 +2302,7 @@ static uint32_t pnv_chip_power10_xscom_pcba(PnvChip *chip, uint64_t addr) return addr >> 3; } -static void pnv_chip_power10_class_init(ObjectClass *klass, void *data) +static void pnv_chip_power10_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvChipClass *k = PNV_CHIP_CLASS(klass); @@ -2461,7 +2461,7 @@ static const Property pnv_chip_properties[] = { DEFINE_PROP_BOOL("lpar-per-core", PnvChip, lpar_per_core, false), }; -static void pnv_chip_class_init(ObjectClass *klass, void *data) +static void pnv_chip_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2724,7 +2724,7 @@ static void pnv_machine_set_hb(Object *obj, bool value, Error **errp) } } -static void pnv_machine_power8_class_init(ObjectClass *oc, void *data) +static void pnv_machine_power8_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); XICSFabricClass *xic = XICS_FABRIC_CLASS(oc); @@ -2753,7 +2753,7 @@ static void pnv_machine_power8_class_init(ObjectClass *oc, void *data) machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB); } -static void pnv_machine_power9_class_init(ObjectClass *oc, void *data) +static void pnv_machine_power9_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); XiveFabricClass *xfc = XIVE_FABRIC_CLASS(oc); @@ -2792,7 +2792,7 @@ static void pnv_machine_power9_class_init(ObjectClass *oc, void *data) "Use 1 LPAR per core mode"); } -static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data) +static void pnv_machine_p10_common_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc); @@ -2822,7 +2822,7 @@ static void pnv_machine_p10_common_class_init(ObjectClass *oc, void *data) machine_class_allow_dynamic_sysbus_dev(mc, TYPE_PNV_PHB); } -static void pnv_machine_power10_class_init(ObjectClass *oc, void *data) +static void pnv_machine_power10_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -2847,7 +2847,8 @@ static void pnv_machine_power10_class_init(ObjectClass *oc, void *data) "Use 1 LPAR per core mode"); } -static void pnv_machine_p10_rainier_class_init(ObjectClass *oc, void *data) +static void pnv_machine_p10_rainier_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); PnvMachineClass *pmc = PNV_MACHINE_CLASS(oc); @@ -2912,7 +2913,7 @@ static void pnv_nmi(NMIState *n, int cpu_index, Error **errp) } } -static void pnv_machine_class_init(ObjectClass *oc, void *data) +static void pnv_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); InterruptStatsProviderClass *ispc = INTERRUPT_STATS_PROVIDER_CLASS(oc); @@ -2972,7 +2973,7 @@ static const TypeInfo types[] = { .name = MACHINE_TYPE_NAME("powernv10"), .parent = TYPE_PNV_MACHINE, .class_init = pnv_machine_power10_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XIVE_FABRIC }, { }, }, @@ -2981,7 +2982,7 @@ static const TypeInfo types[] = { .name = MACHINE_TYPE_NAME("powernv9"), .parent = TYPE_PNV_MACHINE, .class_init = pnv_machine_power9_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XIVE_FABRIC }, { }, }, @@ -2990,7 +2991,7 @@ static const TypeInfo types[] = { .name = MACHINE_TYPE_NAME("powernv8"), .parent = TYPE_PNV_MACHINE, .class_init = pnv_machine_power8_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XICS_FABRIC }, { }, }, @@ -3002,7 +3003,7 @@ static const TypeInfo types[] = { .instance_size = sizeof(PnvMachineState), .class_init = pnv_machine_class_init, .class_size = sizeof(PnvMachineClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_INTERRUPT_STATS_PROVIDER }, { TYPE_NMI }, { }, diff --git a/hw/ppc/pnv_adu.c b/hw/ppc/pnv_adu.c index d09a167..005fbda 100644 --- a/hw/ppc/pnv_adu.c +++ b/hw/ppc/pnv_adu.c @@ -189,7 +189,7 @@ static const Property pnv_adu_properties[] = { DEFINE_PROP_LINK("lpc", PnvADU, lpc, TYPE_PNV_LPC, PnvLpcController *), }; -static void pnv_adu_class_init(ObjectClass *klass, void *data) +static void pnv_adu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -204,7 +204,7 @@ static const TypeInfo pnv_adu_type_info = { .parent = TYPE_DEVICE, .instance_size = sizeof(PnvADU), .class_init = pnv_adu_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } }, }; diff --git a/hw/ppc/pnv_chiptod.c b/hw/ppc/pnv_chiptod.c index c8987ae..b9e9c7b 100644 --- a/hw/ppc/pnv_chiptod.c +++ b/hw/ppc/pnv_chiptod.c @@ -456,7 +456,7 @@ static const Property pnv_chiptod_properties[] = { DEFINE_PROP_LINK("chip", PnvChipTOD , chip, TYPE_PNV_CHIP, PnvChip *), }; -static void pnv_chiptod_power9_class_init(ObjectClass *klass, void *data) +static void pnv_chiptod_power9_class_init(ObjectClass *klass, const void *data) { PnvChipTODClass *pctc = PNV_CHIPTOD_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -478,7 +478,7 @@ static const TypeInfo pnv_chiptod_power9_type_info = { .parent = TYPE_PNV_CHIPTOD, .instance_size = sizeof(PnvChipTOD), .class_init = pnv_chiptod_power9_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } @@ -492,7 +492,7 @@ static int pnv_chiptod_power10_dt_xscom(PnvXScomInterface *dev, void *fdt, return pnv_chiptod_dt_xscom(dev, fdt, xscom_offset, compat, sizeof(compat)); } -static void pnv_chiptod_power10_class_init(ObjectClass *klass, void *data) +static void pnv_chiptod_power10_class_init(ObjectClass *klass, const void *data) { PnvChipTODClass *pctc = PNV_CHIPTOD_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -514,7 +514,7 @@ static const TypeInfo pnv_chiptod_power10_type_info = { .parent = TYPE_PNV_CHIPTOD, .instance_size = sizeof(PnvChipTOD), .class_init = pnv_chiptod_power10_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } @@ -555,7 +555,7 @@ static void pnv_chiptod_unrealize(DeviceState *dev) qemu_unregister_reset(pnv_chiptod_reset, chiptod); } -static void pnv_chiptod_class_init(ObjectClass *klass, void *data) +static void pnv_chiptod_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/pnv_core.c b/hw/ppc/pnv_core.c index a33977d..08c2022 100644 --- a/hw/ppc/pnv_core.c +++ b/hw/ppc/pnv_core.c @@ -449,7 +449,7 @@ static const Property pnv_core_properties[] = { DEFINE_PROP_LINK("chip", PnvCore, chip, TYPE_PNV_CHIP, PnvChip *), }; -static void pnv_core_power8_class_init(ObjectClass *oc, void *data) +static void pnv_core_power8_class_init(ObjectClass *oc, const void *data) { PnvCoreClass *pcc = PNV_CORE_CLASS(oc); @@ -457,7 +457,7 @@ static void pnv_core_power8_class_init(ObjectClass *oc, void *data) pcc->xscom_size = PNV_XSCOM_EX_SIZE; } -static void pnv_core_power9_class_init(ObjectClass *oc, void *data) +static void pnv_core_power9_class_init(ObjectClass *oc, const void *data) { PnvCoreClass *pcc = PNV_CORE_CLASS(oc); @@ -465,7 +465,7 @@ static void pnv_core_power9_class_init(ObjectClass *oc, void *data) pcc->xscom_size = PNV_XSCOM_EX_SIZE; } -static void pnv_core_power10_class_init(ObjectClass *oc, void *data) +static void pnv_core_power10_class_init(ObjectClass *oc, const void *data) { PnvCoreClass *pcc = PNV_CORE_CLASS(oc); @@ -473,7 +473,7 @@ static void pnv_core_power10_class_init(ObjectClass *oc, void *data) pcc->xscom_size = PNV10_XSCOM_EC_SIZE; } -static void pnv_core_class_init(ObjectClass *oc, void *data) +static void pnv_core_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -700,7 +700,7 @@ static const Property pnv_quad_properties[] = { DEFINE_PROP_UINT32("quad-id", PnvQuad, quad_id, 0), }; -static void pnv_quad_power9_class_init(ObjectClass *oc, void *data) +static void pnv_quad_power9_class_init(ObjectClass *oc, const void *data) { PnvQuadClass *pqc = PNV_QUAD_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -711,7 +711,7 @@ static void pnv_quad_power9_class_init(ObjectClass *oc, void *data) pqc->xscom_size = PNV9_XSCOM_EQ_SIZE; } -static void pnv_quad_power10_class_init(ObjectClass *oc, void *data) +static void pnv_quad_power10_class_init(ObjectClass *oc, const void *data) { PnvQuadClass *pqc = PNV_QUAD_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -725,7 +725,7 @@ static void pnv_quad_power10_class_init(ObjectClass *oc, void *data) pqc->xscom_qme_size = PNV10_XSCOM_QME_SIZE; } -static void pnv_quad_class_init(ObjectClass *oc, void *data) +static void pnv_quad_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ppc/pnv_homer.c b/hw/ppc/pnv_homer.c index 18a53a8..2208ffe 100644 --- a/hw/ppc/pnv_homer.c +++ b/hw/ppc/pnv_homer.c @@ -20,7 +20,7 @@ #include "qemu/log.h" #include "qapi/error.h" #include "exec/hwaddr.h" -#include "exec/memory.h" +#include "system/memory.h" #include "system/cpus.h" #include "hw/qdev-core.h" #include "hw/qdev-properties.h" @@ -89,7 +89,7 @@ static hwaddr pnv_homer_power8_get_base(PnvChip *chip) return PNV_HOMER_BASE(chip); } -static void pnv_homer_power8_class_init(ObjectClass *klass, void *data) +static void pnv_homer_power8_class_init(ObjectClass *klass, const void *data) { PnvHomerClass *homer = PNV_HOMER_CLASS(klass); @@ -156,7 +156,7 @@ static hwaddr pnv_homer_power9_get_base(PnvChip *chip) return PNV9_HOMER_BASE(chip); } -static void pnv_homer_power9_class_init(ObjectClass *klass, void *data) +static void pnv_homer_power9_class_init(ObjectClass *klass, const void *data) { PnvHomerClass *homer = PNV_HOMER_CLASS(klass); @@ -223,7 +223,7 @@ static hwaddr pnv_homer_power10_get_base(PnvChip *chip) return PNV10_HOMER_BASE(chip); } -static void pnv_homer_power10_class_init(ObjectClass *klass, void *data) +static void pnv_homer_power10_class_init(ObjectClass *klass, const void *data) { PnvHomerClass *homer = PNV_HOMER_CLASS(klass); @@ -266,7 +266,7 @@ static const Property pnv_homer_properties[] = { DEFINE_PROP_LINK("chip", PnvHomer, chip, TYPE_PNV_CHIP, PnvChip *), }; -static void pnv_homer_class_init(ObjectClass *klass, void *data) +static void pnv_homer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/pnv_i2c.c b/hw/ppc/pnv_i2c.c index 8d35f45..60de479 100644 --- a/hw/ppc/pnv_i2c.c +++ b/hw/ppc/pnv_i2c.c @@ -549,7 +549,7 @@ static const Property pnv_i2c_properties[] = { DEFINE_PROP_UINT32("num-busses", PnvI2C, num_busses, 1), }; -static void pnv_i2c_class_init(ObjectClass *klass, void *data) +static void pnv_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xscomc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -569,7 +569,7 @@ static const TypeInfo pnv_i2c_info = { .parent = TYPE_DEVICE, .instance_size = sizeof(PnvI2C), .class_init = pnv_i2c_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/ppc/pnv_lpc.c b/hw/ppc/pnv_lpc.c index d812dc8..f6beba0 100644 --- a/hw/ppc/pnv_lpc.c +++ b/hw/ppc/pnv_lpc.c @@ -714,7 +714,7 @@ static void pnv_lpc_power8_realize(DeviceState *dev, Error **errp) PNV_XSCOM_LPC_SIZE); } -static void pnv_lpc_power8_class_init(ObjectClass *klass, void *data) +static void pnv_lpc_power8_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -732,7 +732,7 @@ static const TypeInfo pnv_lpc_power8_info = { .name = TYPE_PNV8_LPC, .parent = TYPE_PNV_LPC, .class_init = pnv_lpc_power8_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } @@ -760,7 +760,7 @@ static void pnv_lpc_power9_realize(DeviceState *dev, Error **errp) qdev_init_gpio_out_named(dev, lpc->psi_irq_serirq, "SERIRQ", 4); } -static void pnv_lpc_power9_class_init(ObjectClass *klass, void *data) +static void pnv_lpc_power9_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvLpcClass *plc = PNV_LPC_CLASS(klass); @@ -777,7 +777,7 @@ static const TypeInfo pnv_lpc_power9_info = { .class_init = pnv_lpc_power9_class_init, }; -static void pnv_lpc_power10_class_init(ObjectClass *klass, void *data) +static void pnv_lpc_power10_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -843,7 +843,7 @@ static const Property pnv_lpc_properties[] = { DEFINE_PROP_BOOL("psi-serirq", PnvLpcController, psi_has_serirq, false), }; -static void pnv_lpc_class_init(ObjectClass *klass, void *data) +static void pnv_lpc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/pnv_n1_chiplet.c b/hw/ppc/pnv_n1_chiplet.c index 03ff9fb..053f647 100644 --- a/hw/ppc/pnv_n1_chiplet.c +++ b/hw/ppc/pnv_n1_chiplet.c @@ -136,7 +136,7 @@ static void pnv_n1_chiplet_realize(DeviceState *dev, Error **errp) PNV10_XSCOM_N1_PB_SCOM_ES_SIZE); } -static void pnv_n1_chiplet_class_init(ObjectClass *klass, void *data) +static void pnv_n1_chiplet_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -159,7 +159,7 @@ static const TypeInfo pnv_n1_chiplet_info = { .instance_init = pnv_n1_chiplet_instance_init, .instance_size = sizeof(PnvN1Chiplet), .class_init = pnv_n1_chiplet_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/ppc/pnv_nest_pervasive.c b/hw/ppc/pnv_nest_pervasive.c index 780fa69..1b1b14f 100644 --- a/hw/ppc/pnv_nest_pervasive.c +++ b/hw/ppc/pnv_nest_pervasive.c @@ -181,7 +181,7 @@ static void pnv_nest_pervasive_realize(DeviceState *dev, Error **errp) PNV10_XSCOM_CHIPLET_CTRL_REGS_SIZE); } -static void pnv_nest_pervasive_class_init(ObjectClass *klass, void *data) +static void pnv_nest_pervasive_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -194,7 +194,7 @@ static const TypeInfo pnv_nest_pervasive_info = { .parent = TYPE_DEVICE, .instance_size = sizeof(PnvNestChipletPervasive), .class_init = pnv_nest_pervasive_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/ppc/pnv_occ.c b/hw/ppc/pnv_occ.c index 0c9d3da..24b789c 100644 --- a/hw/ppc/pnv_occ.c +++ b/hw/ppc/pnv_occ.c @@ -172,7 +172,7 @@ const MemoryRegionOps pnv_occ_sram_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_occ_power8_class_init(ObjectClass *klass, void *data) +static void pnv_occ_power8_class_init(ObjectClass *klass, const void *data) { PnvOCCClass *poc = PNV_OCC_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -246,7 +246,7 @@ static const MemoryRegionOps pnv_occ_power9_xscom_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_occ_power9_class_init(ObjectClass *klass, void *data) +static void pnv_occ_power9_class_init(ObjectClass *klass, const void *data) { PnvOCCClass *poc = PNV_OCC_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -266,7 +266,7 @@ static const TypeInfo pnv_occ_power9_type_info = { .class_init = pnv_occ_power9_class_init, }; -static void pnv_occ_power10_class_init(ObjectClass *klass, void *data) +static void pnv_occ_power10_class_init(ObjectClass *klass, const void *data) { PnvOCCClass *poc = PNV_OCC_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -335,7 +335,7 @@ static const Property pnv_occ_properties[] = { DEFINE_PROP_LINK("homer", PnvOCC, homer, TYPE_PNV_HOMER, PnvHomer *), }; -static void pnv_occ_class_init(ObjectClass *klass, void *data) +static void pnv_occ_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -789,7 +789,7 @@ static bool occ_opal_process_command(PnvOCC *occ, static bool occ_model_tick(PnvOCC *occ) { - struct occ_dynamic_data dynamic_data; + QEMU_UNINITIALIZED struct occ_dynamic_data dynamic_data; if (!occ_read_dynamic_data(occ, &dynamic_data, NULL)) { /* Can't move OCC state field to safe because we can't map it! */ diff --git a/hw/ppc/pnv_pnor.c b/hw/ppc/pnv_pnor.c index 9db44ca..af7cfd0 100644 --- a/hw/ppc/pnv_pnor.c +++ b/hw/ppc/pnv_pnor.c @@ -119,7 +119,7 @@ static const Property pnv_pnor_properties[] = { DEFINE_PROP_DRIVE("drive", PnvPnor, blk), }; -static void pnv_pnor_class_init(ObjectClass *klass, void *data) +static void pnv_pnor_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/pnv_psi.c b/hw/ppc/pnv_psi.c index 1fe11dd..5d947d8 100644 --- a/hw/ppc/pnv_psi.c +++ b/hw/ppc/pnv_psi.c @@ -18,7 +18,7 @@ */ #include "qemu/osdep.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/irq.h" #include "target/ppc/cpu.h" #include "qemu/log.h" @@ -557,7 +557,7 @@ static const Property pnv_psi_properties[] = { DEFINE_PROP_UINT64("fsp-bar", PnvPsi, fsp_bar, 0), }; -static void pnv_psi_power8_class_init(ObjectClass *klass, void *data) +static void pnv_psi_power8_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvPsiClass *ppc = PNV_PSI_CLASS(klass); @@ -887,7 +887,7 @@ static void pnv_psi_power9_realize(DeviceState *dev, Error **errp) pnv_psi_realize(dev, errp); } -static void pnv_psi_power9_class_init(ObjectClass *klass, void *data) +static void pnv_psi_power9_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvPsiClass *ppc = PNV_PSI_CLASS(klass); @@ -913,13 +913,13 @@ static const TypeInfo pnv_psi_power9_info = { .instance_size = sizeof(Pnv9Psi), .instance_init = pnv_psi_power9_instance_init, .class_init = pnv_psi_power9_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_XIVE_NOTIFIER }, { }, }, }; -static void pnv_psi_power10_class_init(ObjectClass *klass, void *data) +static void pnv_psi_power10_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvPsiClass *ppc = PNV_PSI_CLASS(klass); @@ -939,7 +939,7 @@ static const TypeInfo pnv_psi_power10_info = { .class_init = pnv_psi_power10_class_init, }; -static void pnv_psi_class_init(ObjectClass *klass, void *data) +static void pnv_psi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xdc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -959,7 +959,7 @@ static const TypeInfo pnv_psi_info = { .class_init = pnv_psi_class_init, .class_size = sizeof(PnvPsiClass), .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/ppc/pnv_sbe.c b/hw/ppc/pnv_sbe.c index 74cee4e..34dc013 100644 --- a/hw/ppc/pnv_sbe.c +++ b/hw/ppc/pnv_sbe.c @@ -331,7 +331,7 @@ static const MemoryRegionOps pnv_sbe_power9_xscom_mbox_ops = { .endianness = DEVICE_BIG_ENDIAN, }; -static void pnv_sbe_power9_class_init(ObjectClass *klass, void *data) +static void pnv_sbe_power9_class_init(ObjectClass *klass, const void *data) { PnvSBEClass *psc = PNV_SBE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -350,7 +350,7 @@ static const TypeInfo pnv_sbe_power9_type_info = { .class_init = pnv_sbe_power9_class_init, }; -static void pnv_sbe_power10_class_init(ObjectClass *klass, void *data) +static void pnv_sbe_power10_class_init(ObjectClass *klass, const void *data) { PnvSBEClass *psc = PNV_SBE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -386,7 +386,7 @@ static void pnv_sbe_realize(DeviceState *dev, Error **errp) sbe->timer = timer_new_us(QEMU_CLOCK_VIRTUAL, sbe_timer, sbe); } -static void pnv_sbe_class_init(ObjectClass *klass, void *data) +static void pnv_sbe_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c index 3a80931..43d0d0e 100644 --- a/hw/ppc/ppc.c +++ b/hw/ppc/ppc.c @@ -27,6 +27,7 @@ #include "hw/ppc/ppc.h" #include "hw/ppc/ppc_e500.h" #include "qemu/timer.h" +#include "exec/cpu-interrupt.h" #include "system/cpus.h" #include "qemu/log.h" #include "qemu/main-loop.h" diff --git a/hw/ppc/ppc440_bamboo.c b/hw/ppc/ppc440_bamboo.c index 099fda3..6fff0d8 100644 --- a/hw/ppc/ppc440_bamboo.c +++ b/hw/ppc/ppc440_bamboo.c @@ -64,7 +64,7 @@ static int bamboo_load_device_tree(MachineState *machine, uint32_t tb_freq = 400000000; uint32_t clock_freq = 400000000; - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); + filename = qemu_find_file(QEMU_FILE_TYPE_DTB, BINARY_DEVICE_TREE_FILE); if (!filename) { return -1; } diff --git a/hw/ppc/ppc440_uc.c b/hw/ppc/ppc440_uc.c index 9da30a1..89e3fae 100644 --- a/hw/ppc/ppc440_uc.c +++ b/hw/ppc/ppc440_uc.c @@ -1027,7 +1027,7 @@ static const Property ppc460ex_pcie_props[] = { PowerPCCPU *), }; -static void ppc460ex_pcie_class_init(ObjectClass *klass, void *data) +static void ppc460ex_pcie_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c index 9ce9777..f36c519 100644 --- a/hw/ppc/ppc4xx_devs.c +++ b/hw/ppc/ppc4xx_devs.c @@ -236,7 +236,7 @@ static const Property ppc4xx_mal_properties[] = { DEFINE_PROP_UINT8("rxc-num", Ppc4xxMalState, rxcnum, 0), }; -static void ppc4xx_mal_class_init(ObjectClass *oc, void *data) +static void ppc4xx_mal_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -326,7 +326,7 @@ static void ppc405_plb_realize(DeviceState *dev, Error **errp) ppc4xx_dcr_register(dcr, PLB4A1_ACR, plb, &dcr_read_plb, &dcr_write_plb); } -static void ppc405_plb_class_init(ObjectClass *oc, void *data) +static void ppc405_plb_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -512,7 +512,7 @@ static void ppc405_ebc_realize(DeviceState *dev, Error **errp) ppc4xx_dcr_register(dcr, EBC0_CFGDATA, ebc, &dcr_read_ebc, &dcr_write_ebc); } -static void ppc405_ebc_class_init(ObjectClass *oc, void *data) +static void ppc405_ebc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -543,7 +543,7 @@ static const Property ppc4xx_dcr_properties[] = { PowerPCCPU *), }; -static void ppc4xx_dcr_class_init(ObjectClass *oc, void *data) +static void ppc4xx_dcr_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ppc/ppc4xx_sdram.c b/hw/ppc/ppc4xx_sdram.c index 562bff8..5927698 100644 --- a/hw/ppc/ppc4xx_sdram.c +++ b/hw/ppc/ppc4xx_sdram.c @@ -34,7 +34,7 @@ #include "qapi/error.h" #include "qemu/log.h" #include "qemu/error-report.h" -#include "exec/address-spaces.h" /* get_system_memory() */ +#include "system/address-spaces.h" /* get_system_memory() */ #include "hw/irq.h" #include "hw/qdev-properties.h" #include "hw/ppc/ppc4xx.h" @@ -431,7 +431,7 @@ static const Property ppc4xx_sdram_ddr_props[] = { DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdrState, nbanks, 4), }; -static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, void *data) +static void ppc4xx_sdram_ddr_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -715,7 +715,7 @@ static const Property ppc4xx_sdram_ddr2_props[] = { DEFINE_PROP_UINT32("nbanks", Ppc4xxSdramDdr2State, nbanks, 4), }; -static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, void *data) +static void ppc4xx_sdram_ddr2_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ppc/ppc_booke.c b/hw/ppc/ppc_booke.c index 925e670b..3872ae2 100644 --- a/hw/ppc/ppc_booke.c +++ b/hw/ppc/ppc_booke.c @@ -24,6 +24,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/target_page.h" #include "hw/ppc/ppc.h" #include "qemu/timer.h" #include "system/reset.h" diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c index baab74c..2310f62 100644 --- a/hw/ppc/ppce500_spin.c +++ b/hw/ppc/ppce500_spin.c @@ -175,7 +175,7 @@ static void ppce500_spin_initfn(Object *obj) sysbus_init_mmio(dev, &s->iomem); } -static void ppce500_spin_class_init(ObjectClass *klass, void *data) +static void ppce500_spin_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c index 3e68d8e..982e40e 100644 --- a/hw/ppc/prep.c +++ b/hw/ppc/prep.c @@ -35,10 +35,12 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/log.h" +#include "qemu/datadir.h" #include "hw/loader.h" #include "hw/rtc/mc146818rtc.h" #include "hw/isa/pc87312.h" #include "hw/qdev-properties.h" +#include "exec/target_page.h" #include "system/kvm.h" #include "system/reset.h" #include "trace.h" @@ -54,6 +56,8 @@ #define KERNEL_LOAD_ADDR 0x01000000 #define INITRD_LOAD_ADDR 0x01800000 +#define BIOS_ADDR 0xfff00000 +#define BIOS_SIZE (1 * MiB) #define NVRAM_SIZE 0x2000 static void fw_cfg_boot_set(void *opaque, const char *boot_device, @@ -240,6 +244,9 @@ static void ibm_40p_init(MachineState *machine) ISADevice *isa_dev; ISABus *isa_bus; void *fw_cfg; + MemoryRegion *bios = g_new(MemoryRegion, 1); + char *filename; + ssize_t bios_size = -1; uint32_t kernel_base = 0, initrd_base = 0; long kernel_size = 0, initrd_size = 0; char boot_device; @@ -262,10 +269,27 @@ static void ibm_40p_init(MachineState *machine) cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL); qemu_register_reset(ppc_prep_reset, cpu); + /* allocate and load firmware */ + filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); + if (!filename) { + error_report("Could not find bios image '%s'", bios_name); + exit(1); + } + memory_region_init_rom(bios, NULL, "bios", BIOS_SIZE, &error_fatal); + memory_region_add_subregion(get_system_memory(), BIOS_ADDR, bios); + bios_size = load_elf(filename, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + ELFDATA2MSB, PPC_ELF_MACHINE, 0, 0); + if (bios_size < 0) { + bios_size = load_image_targphys(filename, BIOS_ADDR, BIOS_SIZE); + } + if (bios_size < 0 || bios_size > BIOS_SIZE) { + error_report("Could not load bios image '%s'", filename); + return; + } + g_free(filename); + /* PCI host */ dev = qdev_new("raven-pcihost"); - qdev_prop_set_string(dev, "bios-name", bios_name); - qdev_prop_set_uint32(dev, "elf-machine", PPC_ELF_MACHINE); pcihost = SYS_BUS_DEVICE(dev); object_property_add_child(qdev_get_machine(), "raven", OBJECT(dev)); sysbus_realize_and_unref(pcihost, &error_fatal); diff --git a/hw/ppc/prep_systemio.c b/hw/ppc/prep_systemio.c index b1f2e13..41cd923 100644 --- a/hw/ppc/prep_systemio.c +++ b/hw/ppc/prep_systemio.c @@ -28,7 +28,7 @@ #include "hw/isa/isa.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/object.h" #include "qemu/error-report.h" /* for error_report() */ #include "qemu/module.h" @@ -290,7 +290,7 @@ static const Property prep_systemio_properties[] = { DEFINE_PROP_UINT8("equipment", PrepSystemIoState, equipment, 0), }; -static void prep_systemio_class_initfn(ObjectClass *klass, void *data) +static void prep_systemio_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/rs6000_mc.c b/hw/ppc/rs6000_mc.c index 0e5d53b..a096405 100644 --- a/hw/ppc/rs6000_mc.c +++ b/hw/ppc/rs6000_mc.c @@ -24,7 +24,7 @@ #include "hw/isa/isa.h" #include "hw/qdev-properties.h" #include "migration/vmstate.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qapi/error.h" #include "trace.h" #include "qom/object.h" @@ -212,7 +212,7 @@ static const Property rs6000mc_properties[] = { DEFINE_PROP_BOOL("auto-configure", RS6000MCState, autoconfigure, true), }; -static void rs6000mc_class_initfn(ObjectClass *klass, void *data) +static void rs6000mc_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ppc/sam460ex.c b/hw/ppc/sam460ex.c index 7dc3b30..ee31bd8 100644 --- a/hw/ppc/sam460ex.c +++ b/hw/ppc/sam460ex.c @@ -24,7 +24,7 @@ #include "exec/page-protection.h" #include "hw/loader.h" #include "elf.h" -#include "exec/memory.h" +#include "system/memory.h" #include "ppc440.h" #include "hw/pci-host/ppc4xx.h" #include "hw/block/flash.h" @@ -142,7 +142,7 @@ static int sam460ex_load_device_tree(MachineState *machine, uint32_t clock_freq = CPU_FREQ; int offset; - filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); + filename = qemu_find_file(QEMU_FILE_TYPE_DTB, BINARY_DEVICE_TREE_FILE); if (!filename) { error_report("Couldn't find dtb file `%s'", BINARY_DEVICE_TREE_FILE); exit(1); diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c index 6fef1d1..702f774 100644 --- a/hw/ppc/spapr.c +++ b/hw/ppc/spapr.c @@ -77,7 +77,7 @@ #include "hw/virtio/virtio-scsi.h" #include "hw/virtio/vhost-scsi-common.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "system/confidential-guest-support.h" #include "hw/usb.h" #include "qemu/config-file.h" @@ -4595,7 +4595,7 @@ static void spapr_cpu_exec_exit(PPCVirtualHypervisor *vhyp, PowerPCCPU *cpu) } } -static void spapr_machine_class_init(ObjectClass *oc, void *data) +static void spapr_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); SpaprMachineClass *smc = SPAPR_MACHINE_CLASS(oc); @@ -4717,7 +4717,7 @@ static const TypeInfo spapr_machine_info = { .instance_finalize = spapr_machine_finalizefn, .class_size = sizeof(SpaprMachineClass), .class_init = spapr_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { TYPE_NMI }, { TYPE_HOTPLUG_HANDLER }, @@ -4739,7 +4739,7 @@ static void spapr_machine_latest_class_options(MachineClass *mc) #define DEFINE_SPAPR_MACHINE_IMPL(latest, ...) \ static void MACHINE_VER_SYM(class_init, spapr, __VA_ARGS__)( \ ObjectClass *oc, \ - void *data) \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ MACHINE_VER_SYM(class_options, spapr, __VA_ARGS__)(mc); \ diff --git a/hw/ppc/spapr_caps.c b/hw/ppc/spapr_caps.c index 815c94e..f2f5722 100644 --- a/hw/ppc/spapr_caps.c +++ b/hw/ppc/spapr_caps.c @@ -27,7 +27,7 @@ #include "qapi/error.h" #include "qapi/visitor.h" #include "system/hw_accel.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "target/ppc/cpu.h" #include "target/ppc/mmu-hash64.h" #include "cpu-models.h" diff --git a/hw/ppc/spapr_cpu_core.c b/hw/ppc/spapr_cpu_core.c index faf9170..4952f9b 100644 --- a/hw/ppc/spapr_cpu_core.c +++ b/hw/ppc/spapr_cpu_core.c @@ -373,7 +373,7 @@ static const Property spapr_cpu_core_properties[] = { DEFINE_PROP_INT32("node-id", SpaprCpuCore, node_id, CPU_UNSET_NUMA_NODE_ID), }; -static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) +static void spapr_cpu_core_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); SpaprCpuCoreClass *scc = SPAPR_CPU_CORE_CLASS(oc); @@ -388,7 +388,7 @@ static void spapr_cpu_core_class_init(ObjectClass *oc, void *data) #define DEFINE_SPAPR_CPU_CORE_TYPE(cpu_model) \ { \ .parent = TYPE_SPAPR_CPU_CORE, \ - .class_data = (void *) POWERPC_CPU_TYPE_NAME(cpu_model), \ + .class_data = POWERPC_CPU_TYPE_NAME(cpu_model), \ .class_init = spapr_cpu_core_class_init, \ .name = SPAPR_CPU_CORE_TYPE_NAME(cpu_model), \ } diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c index 549b652..d2044b4 100644 --- a/hw/ppc/spapr_drc.c +++ b/hw/ppc/spapr_drc.c @@ -589,7 +589,7 @@ static void spapr_dr_connector_instance_init(Object *obj) drc->state = drck->empty_state; } -static void spapr_dr_connector_class_init(ObjectClass *k, void *data) +static void spapr_dr_connector_class_init(ObjectClass *k, const void *data) { DeviceClass *dk = DEVICE_CLASS(k); @@ -665,7 +665,7 @@ static void unrealize_physical(DeviceState *d) qemu_unregister_reset(drc_physical_reset, drcp); } -static void spapr_drc_physical_class_init(ObjectClass *k, void *data) +static void spapr_drc_physical_class_init(ObjectClass *k, const void *data) { DeviceClass *dk = DEVICE_CLASS(k); SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); @@ -679,7 +679,7 @@ static void spapr_drc_physical_class_init(ObjectClass *k, void *data) drck->empty_state = SPAPR_DRC_STATE_PHYSICAL_POWERON; } -static void spapr_drc_logical_class_init(ObjectClass *k, void *data) +static void spapr_drc_logical_class_init(ObjectClass *k, const void *data) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); @@ -690,7 +690,7 @@ static void spapr_drc_logical_class_init(ObjectClass *k, void *data) drck->empty_state = SPAPR_DRC_STATE_LOGICAL_UNUSABLE; } -static void spapr_drc_cpu_class_init(ObjectClass *k, void *data) +static void spapr_drc_cpu_class_init(ObjectClass *k, const void *data) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); @@ -701,7 +701,7 @@ static void spapr_drc_cpu_class_init(ObjectClass *k, void *data) drck->dt_populate = spapr_core_dt_populate; } -static void spapr_drc_pci_class_init(ObjectClass *k, void *data) +static void spapr_drc_pci_class_init(ObjectClass *k, const void *data) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); @@ -712,7 +712,7 @@ static void spapr_drc_pci_class_init(ObjectClass *k, void *data) drck->dt_populate = spapr_pci_dt_populate; } -static void spapr_drc_lmb_class_init(ObjectClass *k, void *data) +static void spapr_drc_lmb_class_init(ObjectClass *k, const void *data) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); @@ -723,7 +723,7 @@ static void spapr_drc_lmb_class_init(ObjectClass *k, void *data) drck->dt_populate = spapr_lmb_dt_populate; } -static void spapr_drc_phb_class_init(ObjectClass *k, void *data) +static void spapr_drc_phb_class_init(ObjectClass *k, const void *data) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); @@ -734,7 +734,7 @@ static void spapr_drc_phb_class_init(ObjectClass *k, void *data) drck->dt_populate = spapr_phb_dt_populate; } -static void spapr_drc_pmem_class_init(ObjectClass *k, void *data) +static void spapr_drc_pmem_class_init(ObjectClass *k, const void *data) { SpaprDrcClass *drck = SPAPR_DR_CONNECTOR_CLASS(k); diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c index 29453a8..1e936f3 100644 --- a/hw/ppc/spapr_hcall.c +++ b/hw/ppc/spapr_hcall.c @@ -9,6 +9,7 @@ #include "qemu/module.h" #include "qemu/error-report.h" #include "exec/tb-flush.h" +#include "exec/target_page.h" #include "helper_regs.h" #include "hw/ppc/ppc.h" #include "hw/ppc/spapr.h" diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c index db3a14c..c2432a0 100644 --- a/hw/ppc/spapr_iommu.c +++ b/hw/ppc/spapr_iommu.c @@ -668,7 +668,7 @@ int spapr_tcet_dma_dt(void *fdt, int node_off, const char *propname, tcet->liobn, 0, tcet->nb_table << tcet->page_shift); } -static void spapr_tce_table_class_init(ObjectClass *klass, void *data) +static void spapr_tce_table_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = spapr_tce_table_realize; @@ -693,7 +693,8 @@ static const TypeInfo spapr_tce_table_info = { .class_init = spapr_tce_table_class_init, }; -static void spapr_iommu_memory_region_class_init(ObjectClass *klass, void *data) +static void spapr_iommu_memory_region_class_init(ObjectClass *klass, + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/ppc/spapr_nested.c b/hw/ppc/spapr_nested.c index 3797220..10cf634 100644 --- a/hw/ppc/spapr_nested.c +++ b/hw/ppc/spapr_nested.c @@ -1,7 +1,7 @@ #include "qemu/osdep.h" #include "qemu/cutils.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" +#include "exec/target_long.h" #include "helper_regs.h" #include "hw/ppc/ppc.h" #include "hw/ppc/spapr.h" diff --git a/hw/ppc/spapr_nvdimm.c b/hw/ppc/spapr_nvdimm.c index 6e93ff9..72b4a63 100644 --- a/hw/ppc/spapr_nvdimm.c +++ b/hw/ppc/spapr_nvdimm.c @@ -888,7 +888,7 @@ static const Property spapr_nvdimm_properties[] = { }; #endif -static void spapr_nvdimm_class_init(ObjectClass *oc, void *data) +static void spapr_nvdimm_class_init(ObjectClass *oc, const void *data) { NVDIMMClass *nvc = NVDIMM_CLASS(oc); diff --git a/hw/ppc/spapr_ovec.c b/hw/ppc/spapr_ovec.c index 88e2953..75ab4fe 100644 --- a/hw/ppc/spapr_ovec.c +++ b/hw/ppc/spapr_ovec.c @@ -15,7 +15,8 @@ #include "hw/ppc/spapr_ovec.h" #include "migration/vmstate.h" #include "qemu/bitmap.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" +#include "system/memory.h" #include "qemu/error-report.h" #include "trace.h" #include <libfdt.h> diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c index e0a9d50..1ac1185 100644 --- a/hw/ppc/spapr_pci.c +++ b/hw/ppc/spapr_pci.c @@ -34,7 +34,7 @@ #include "hw/pci/pci_host.h" #include "hw/ppc/spapr.h" #include "hw/pci-host/spapr.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include <libfdt.h> #include "trace.h" #include "qemu/error-report.h" @@ -2173,7 +2173,7 @@ static const char *spapr_phb_root_bus_path(PCIHostState *host_bridge, return sphb->dtbusname; } -static void spapr_phb_class_init(ObjectClass *klass, void *data) +static void spapr_phb_class_init(ObjectClass *klass, const void *data) { PCIHostBridgeClass *hc = PCI_HOST_BRIDGE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -2200,7 +2200,7 @@ static const TypeInfo spapr_phb_info = { .instance_size = sizeof(SpaprPhbState), .instance_finalize = spapr_phb_finalizefn, .class_init = spapr_phb_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c index 76b2a34..e318d0d 100644 --- a/hw/ppc/spapr_pci_vfio.c +++ b/hw/ppc/spapr_pci_vfio.c @@ -24,7 +24,7 @@ #include "hw/pci-host/spapr.h" #include "hw/pci/msix.h" #include "hw/pci/pci_device.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-container.h" #include "qemu/error-report.h" #include CONFIG_DEVICES /* CONFIG_VFIO_PCI */ @@ -85,7 +85,7 @@ static int vfio_eeh_container_op(VFIOContainer *container, uint32_t op) static VFIOContainer *vfio_eeh_as_container(AddressSpace *as) { - VFIOAddressSpace *space = vfio_get_address_space(as); + VFIOAddressSpace *space = vfio_address_space_get(as); VFIOContainerBase *bcontainer = NULL; if (QLIST_EMPTY(&space->containers)) { @@ -105,7 +105,7 @@ static VFIOContainer *vfio_eeh_as_container(AddressSpace *as) } out: - vfio_put_address_space(space); + vfio_address_space_put(space); return container_of(bcontainer, VFIOContainer, bcontainer); } diff --git a/hw/ppc/spapr_rng.c b/hw/ppc/spapr_rng.c index 95def5b..6fec607 100644 --- a/hw/ppc/spapr_rng.c +++ b/hw/ppc/spapr_rng.c @@ -136,7 +136,7 @@ static const Property spapr_rng_properties[] = { RngBackend *), }; -static void spapr_rng_class_init(ObjectClass *oc, void *data) +static void spapr_rng_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ppc/spapr_rtc.c b/hw/ppc/spapr_rtc.c index 46fbc78..1f7d2d8 100644 --- a/hw/ppc/spapr_rtc.c +++ b/hw/ppc/spapr_rtc.c @@ -163,7 +163,7 @@ static const VMStateDescription vmstate_spapr_rtc = { }, }; -static void spapr_rtc_class_init(ObjectClass *oc, void *data) +static void spapr_rtc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ppc/spapr_tpm_proxy.c b/hw/ppc/spapr_tpm_proxy.c index ceaa0ac..1297b3a 100644 --- a/hw/ppc/spapr_tpm_proxy.c +++ b/hw/ppc/spapr_tpm_proxy.c @@ -41,8 +41,8 @@ static ssize_t tpm_execute(SpaprTpmProxy *tpm_proxy, target_ulong *args) target_ulong data_in_size = args[2]; uint64_t data_out = ppc64_phys_to_real(args[3]); target_ulong data_out_size = args[4]; - uint8_t buf_in[TPM_SPAPR_BUFSIZE]; - uint8_t buf_out[TPM_SPAPR_BUFSIZE]; + QEMU_UNINITIALIZED uint8_t buf_in[TPM_SPAPR_BUFSIZE]; + QEMU_UNINITIALIZED uint8_t buf_out[TPM_SPAPR_BUFSIZE]; ssize_t ret; trace_spapr_tpm_execute(data_in, data_in_size, data_out, data_out_size); @@ -149,7 +149,7 @@ static const Property spapr_tpm_proxy_properties[] = { DEFINE_PROP_STRING("host-path", SpaprTpmProxy, host_path), }; -static void spapr_tpm_proxy_class_init(ObjectClass *k, void *data) +static void spapr_tpm_proxy_class_init(ObjectClass *k, const void *data) { DeviceClass *dk = DEVICE_CLASS(k); diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c index 09243c1..7759436 100644 --- a/hw/ppc/spapr_vio.c +++ b/hw/ppc/spapr_vio.c @@ -50,7 +50,7 @@ static char *spapr_vio_get_dev_name(DeviceState *qdev) return g_strdup_printf("%s@%x", pc->dt_name, dev->reg); } -static void spapr_vio_bus_class_init(ObjectClass *klass, void *data) +static void spapr_vio_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -599,7 +599,7 @@ SpaprVioBus *spapr_vio_bus_init(void) return bus; } -static void spapr_vio_bridge_class_init(ObjectClass *klass, void *data) +static void spapr_vio_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -631,7 +631,7 @@ const VMStateDescription vmstate_spapr_vio = { }, }; -static void vio_spapr_device_class_init(ObjectClass *klass, void *data) +static void vio_spapr_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->realize = spapr_vio_busdev_realize; diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c index 17115be..c9969ae 100644 --- a/hw/ppc/virtex_ml507.c +++ b/hw/ppc/virtex_ml507.c @@ -146,7 +146,7 @@ static int xilinx_load_device_tree(MachineState *machine, /* Try the local "ppc.dtb" override. */ fdt = load_device_tree("ppc.dtb", &fdt_size); if (!fdt) { - path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE); + path = qemu_find_file(QEMU_FILE_TYPE_DTB, BINARY_DEVICE_TREE_FILE); if (path) { fdt = load_device_tree(path, &fdt_size); g_free(path); diff --git a/hw/ppc/vof.c b/hw/ppc/vof.c index 09cb77d..f14efa3 100644 --- a/hw/ppc/vof.c +++ b/hw/ppc/vof.c @@ -15,7 +15,7 @@ #include "qemu/units.h" #include "qemu/log.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/ppc/vof.h" #include "hw/ppc/fdt.h" #include "system/runstate.h" diff --git a/hw/remote/iommu.c b/hw/remote/iommu.c index 7c56aad..3e0758a 100644 --- a/hw/remote/iommu.c +++ b/hw/remote/iommu.c @@ -13,8 +13,8 @@ #include "hw/remote/iommu.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci.h" -#include "exec/memory.h" -#include "exec/address-spaces.h" +#include "system/memory.h" +#include "system/address-spaces.h" #include "trace.h" /** diff --git a/hw/remote/machine.c b/hw/remote/machine.c index fdc6c44..e4b4783 100644 --- a/hw/remote/machine.c +++ b/hw/remote/machine.c @@ -16,7 +16,7 @@ #include "qemu/osdep.h" #include "hw/remote/machine.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qapi/error.h" #include "hw/pci/pci_host.h" #include "hw/remote/iohub.h" @@ -121,7 +121,7 @@ static void remote_machine_dev_unplug_cb(HotplugHandler *hotplug_dev, } } -static void remote_machine_class_init(ObjectClass *oc, void *data) +static void remote_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -146,7 +146,7 @@ static const TypeInfo remote_machine = { .instance_size = sizeof(RemoteMachineState), .instance_init = remote_machine_instance_init, .class_init = remote_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/remote/memory.c b/hw/remote/memory.c index 6d60da9..00193a5 100644 --- a/hw/remote/memory.c +++ b/hw/remote/memory.c @@ -11,7 +11,7 @@ #include "qemu/osdep.h" #include "hw/remote/memory.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "qapi/error.h" static void remote_sysmem_reset(void) diff --git a/hw/remote/proxy-memory-listener.c b/hw/remote/proxy-memory-listener.c index a926f61..30ac749 100644 --- a/hw/remote/proxy-memory-listener.c +++ b/hw/remote/proxy-memory-listener.c @@ -10,9 +10,9 @@ #include "qemu/int128.h" #include "qemu/range.h" -#include "exec/memory.h" +#include "system/memory.h" #include "exec/cpu-common.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/remote/mpqemu-link.h" diff --git a/hw/remote/proxy.c b/hw/remote/proxy.c index 96d831a..b0165aa 100644 --- a/hw/remote/proxy.c +++ b/hw/remote/proxy.c @@ -195,7 +195,7 @@ static const Property proxy_properties[] = { DEFINE_PROP_STRING("fd", PCIProxyDev, fd), }; -static void pci_proxy_dev_class_init(ObjectClass *klass, void *data) +static void pci_proxy_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -215,7 +215,7 @@ static const TypeInfo pci_proxy_dev_type_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIProxyDev), .class_init = pci_proxy_dev_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/remote/remote-obj.c b/hw/remote/remote-obj.c index 2f25f92..8588290 100644 --- a/hw/remote/remote-obj.c +++ b/hw/remote/remote-obj.c @@ -163,7 +163,7 @@ static void remote_object_finalize(Object *obj) g_free(o->devid); } -static void remote_object_class_init(ObjectClass *klass, void *data) +static void remote_object_class_init(ObjectClass *klass, const void *data) { RemoteObjectClass *k = REMOTE_OBJECT_CLASS(klass); @@ -188,7 +188,7 @@ static const TypeInfo remote_object_info = { .instance_finalize = remote_object_finalize, .class_size = sizeof(RemoteObjectClass), .class_init = remote_object_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } } diff --git a/hw/remote/vfio-user-obj.c b/hw/remote/vfio-user-obj.c index 6e51a92..ea6165e 100644 --- a/hw/remote/vfio-user-obj.c +++ b/hw/remote/vfio-user-obj.c @@ -57,7 +57,7 @@ #include "hw/qdev-core.h" #include "hw/pci/pci.h" #include "qemu/timer.h" -#include "exec/memory.h" +#include "system/memory.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" #include "hw/remote/vfio-user-obj.h" @@ -917,7 +917,7 @@ static void vfu_object_finalize(Object *obj) } } -static void vfu_object_class_init(ObjectClass *klass, void *data) +static void vfu_object_class_init(ObjectClass *klass, const void *data) { VfuObjectClass *k = VFU_OBJECT_CLASS(klass); @@ -944,7 +944,7 @@ static const TypeInfo vfu_object_info = { .instance_finalize = vfu_object_finalize, .class_size = sizeof(VfuObjectClass), .class_init = vfu_object_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_USER_CREATABLE }, { } } diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 765b9e2..828a867 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -37,7 +37,7 @@ bool riscv_is_32bit(RISCVHartArrayState *harts) { RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(&harts->harts[0]); - return mcc->misa_mxl_max == MXL_RV32; + return mcc->def->misa_mxl_max == MXL_RV32; } /* diff --git a/hw/riscv/microblaze-v-generic.c b/hw/riscv/microblaze-v-generic.c index d8e6790..e863c50 100644 --- a/hw/riscv/microblaze-v-generic.c +++ b/hw/riscv/microblaze-v-generic.c @@ -22,7 +22,7 @@ #include "net/net.h" #include "hw/boards.h" #include "hw/char/serial-mm.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/char/xilinx_uartlite.h" #include "hw/misc/unimp.h" diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 9c846f9..2e74783 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -39,6 +39,7 @@ #include "qemu/units.h" #include "qemu/cutils.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/boards.h" #include "hw/loader.h" #include "hw/sysbus.h" @@ -61,9 +62,6 @@ #define BIOS_FILENAME "hss.bin" #define RESET_VECTOR 0x20220000 -/* CLINT timebase frequency */ -#define CLINT_TIMEBASE_FREQ 1000000 - /* GEM version */ #define GEM_REVISION 0x0107010c @@ -193,6 +191,7 @@ static void microchip_pfsoc_soc_instance_init(Object *obj) static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); + MicrochipIcicleKitState *iks = MICROCHIP_ICICLE_KIT_MACHINE(ms); MicrochipPFSoCState *s = MICROCHIP_PFSOC(dev); const MemMapEntry *memmap = microchip_pfsoc_memmap; MemoryRegion *system_memory = get_system_memory(); @@ -253,7 +252,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) memmap[MICROCHIP_PFSOC_CLINT].base + RISCV_ACLINT_SWI_SIZE, RISCV_ACLINT_DEFAULT_MTIMER_SIZE, 0, ms->smp.cpus, RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, - CLINT_TIMEBASE_FREQ, false); + iks->clint_timebase_freq, false); /* L2 cache controller */ create_unimplemented_device("microchip.pfsoc.l2cc", @@ -479,7 +478,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp) qspi_xip_mem); } -static void microchip_pfsoc_soc_class_init(ObjectClass *oc, void *data) +static void microchip_pfsoc_soc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -516,7 +515,6 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) uint64_t mem_low_size, mem_high_size; hwaddr firmware_load_addr; const char *firmware_name; - bool kernel_as_payload = false; target_ulong firmware_end_addr, kernel_start_addr; uint64_t kernel_entry; uint64_t fdt_load_addr; @@ -579,45 +577,50 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) } /* - * We follow the following table to select which payload we execute. - * - * -bios | -kernel | payload - * -------+------------+-------- - * N | N | HSS - * Y | don't care | HSS - * N | Y | kernel + * We follow the following table to select which firmware we use. * - * This ensures backwards compatibility with how we used to expose -bios - * to users but allows them to run through direct kernel booting as well. - * - * When -kernel is used for direct boot, -dtb must be present to provide - * a valid device tree for the board, as we don't generate device tree. + * -bios | -kernel | firmware + * --------------+------------+-------- + * none | N | error + * none | Y | kernel + * NULL, default | N | BIOS_FILENAME + * NULL, default | Y | RISCV64_BIOS_BIN + * other | don't care | other */ - - if (machine->kernel_filename && machine->dtb) { - int fdt_size; - machine->fdt = load_device_tree(machine->dtb, &fdt_size); - if (!machine->fdt) { - error_report("load_device_tree() failed"); + if (machine->firmware && !strcmp(machine->firmware, "none")) { + if (!machine->kernel_filename) { + error_report("for -bios none, a kernel is required"); exit(1); } - firmware_name = RISCV64_BIOS_BIN; - firmware_load_addr = memmap[MICROCHIP_PFSOC_DRAM_LO].base; - kernel_as_payload = true; - } - - if (!kernel_as_payload) { - firmware_name = BIOS_FILENAME; + firmware_name = NULL; + firmware_load_addr = RESET_VECTOR; + } else if (!machine->firmware || !strcmp(machine->firmware, "default")) { + if (machine->kernel_filename) { + firmware_name = RISCV64_BIOS_BIN; + firmware_load_addr = memmap[MICROCHIP_PFSOC_DRAM_LO].base; + } else { + firmware_name = BIOS_FILENAME; + firmware_load_addr = RESET_VECTOR; + } + } else { + firmware_name = machine->firmware; firmware_load_addr = RESET_VECTOR; } - /* Load the firmware */ - firmware_end_addr = riscv_find_and_load_firmware(machine, firmware_name, - &firmware_load_addr, NULL); + /* Load the firmware if necessary */ + firmware_end_addr = firmware_load_addr; + if (firmware_name) { + char *filename = riscv_find_firmware(firmware_name, NULL); + if (filename) { + firmware_end_addr = riscv_load_firmware(filename, + &firmware_load_addr, NULL); + g_free(filename); + } + } riscv_boot_info_init(&boot_info, &s->soc.u_cpus); - if (kernel_as_payload) { + if (machine->kernel_filename) { kernel_start_addr = riscv_calc_kernel_start_addr(&boot_info, firmware_end_addr); @@ -625,21 +628,84 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) true, NULL); kernel_entry = boot_info.image_low_addr; - /* Compute the fdt load address in dram */ - fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base, - memmap[MICROCHIP_PFSOC_DRAM_LO].size, - machine, &boot_info); - riscv_load_fdt(fdt_load_addr, machine->fdt); + if (machine->dtb) { + int fdt_size; + machine->fdt = load_device_tree(machine->dtb, &fdt_size); + if (!machine->fdt) { + error_report("load_device_tree() failed"); + exit(1); + } + + /* Compute the FDT load address in DRAM */ + hwaddr kernel_ram_base = memmap[MICROCHIP_PFSOC_DRAM_LO].base; + hwaddr kernel_ram_size = memmap[MICROCHIP_PFSOC_DRAM_LO].size; + + if (kernel_entry - kernel_ram_base >= kernel_ram_size) { + kernel_ram_base = memmap[MICROCHIP_PFSOC_DRAM_HI].base; + kernel_ram_size = mem_high_size; + } + + fdt_load_addr = riscv_compute_fdt_addr(kernel_ram_base, kernel_ram_size, + machine, &boot_info); + riscv_load_fdt(fdt_load_addr, machine->fdt); + } else { + warn_report_once("The QEMU microchip-icicle-kit machine does not " + "generate a device tree, so no device tree is " + "being provided to the guest."); + fdt_load_addr = 0; + } + + hwaddr start_addr; + if (firmware_name) { + start_addr = firmware_load_addr; + } else { + start_addr = kernel_entry; + } /* Load the reset vector */ - riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, firmware_load_addr, + riscv_setup_rom_reset_vec(machine, &s->soc.u_cpus, start_addr, memmap[MICROCHIP_PFSOC_ENVM_DATA].base, memmap[MICROCHIP_PFSOC_ENVM_DATA].size, kernel_entry, fdt_load_addr); } } -static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data) +static void microchip_icicle_kit_set_clint_timebase_freq(Object *obj, + Visitor *v, + const char *name, + void *opaque, + Error **errp) +{ + MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(obj); + uint32_t value; + + if (!visit_type_uint32(v, name, &value, errp)) { + return; + } + + s->clint_timebase_freq = value; +} + +static void microchip_icicle_kit_get_clint_timebase_freq(Object *obj, + Visitor *v, + const char *name, + void *opaque, + Error **errp) +{ + MicrochipIcicleKitState *s = MICROCHIP_ICICLE_KIT_MACHINE(obj); + uint32_t value = s->clint_timebase_freq; + + visit_type_uint32(v, name, &value, errp); +} + +static void microchip_icicle_kit_machine_instance_init(Object *obj) +{ + MicrochipIcicleKitState *m = MICROCHIP_ICICLE_KIT_MACHINE(obj); + m->clint_timebase_freq = 1000000; +} + +static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -660,12 +726,20 @@ static void microchip_icicle_kit_machine_class_init(ObjectClass *oc, void *data) * See memory_tests() in mss_ddr.c in the HSS source code. */ mc->default_ram_size = 1537 * MiB; + + object_class_property_add(oc, "clint-timebase-frequency", "uint32_t", + microchip_icicle_kit_get_clint_timebase_freq, + microchip_icicle_kit_set_clint_timebase_freq, + NULL, NULL); + object_class_property_set_description(oc, "clint-timebase-frequency", + "Set CLINT timebase frequency in Hz."); } static const TypeInfo microchip_icicle_kit_machine_typeinfo = { .name = MACHINE_TYPE_NAME("microchip-icicle-kit"), .parent = TYPE_MACHINE, .class_init = microchip_icicle_kit_machine_class_init, + .instance_init = microchip_icicle_kit_machine_instance_init, .instance_size = sizeof(MicrochipIcicleKitState), }; diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c index 98a67fe..d369a8a 100644 --- a/hw/riscv/opentitan.c +++ b/hw/riscv/opentitan.c @@ -28,7 +28,7 @@ #include "hw/riscv/boot.h" #include "qemu/units.h" #include "system/system.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" /* * This version of the OpenTitan machine currently supports @@ -112,7 +112,7 @@ static void opentitan_machine_init(MachineState *machine) } } -static void opentitan_machine_class_init(ObjectClass *oc, void *data) +static void opentitan_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -313,7 +313,7 @@ static const Property lowrisc_ibex_soc_props[] = { DEFINE_PROP_UINT32("resetvec", LowRISCIbexSoCState, resetvec, 0x20000400), }; -static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data) +static void lowrisc_ibex_soc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/riscv/riscv-iommu-pci.c b/hw/riscv/riscv-iommu-pci.c index 1245186..cdb4a7a 100644 --- a/hw/riscv/riscv-iommu-pci.c +++ b/hw/riscv/riscv-iommu-pci.c @@ -17,6 +17,7 @@ */ #include "qemu/osdep.h" +#include "exec/target_page.h" #include "hw/pci/msi.h" #include "hw/pci/msix.h" #include "hw/pci/pci_bus.h" @@ -67,12 +68,6 @@ typedef struct RISCVIOMMUStatePci { RISCVIOMMUState iommu; /* common IOMMU state */ } RISCVIOMMUStatePci; -struct RISCVIOMMUPciClass { - /*< public >*/ - DeviceRealize parent_realize; - ResettablePhases parent_phases; -}; - /* interrupt delivery callback */ static void riscv_iommu_pci_notify(RISCVIOMMUState *iommu, unsigned vector) { @@ -183,7 +178,7 @@ static void riscv_iommu_pci_reset_hold(Object *obj, ResetType type) trace_riscv_iommu_pci_reset_hold(type); } -static void riscv_iommu_pci_class_init(ObjectClass *klass, void *data) +static void riscv_iommu_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -208,7 +203,7 @@ static const TypeInfo riscv_iommu_pci = { .class_init = riscv_iommu_pci_class_init, .instance_init = riscv_iommu_pci_init, .instance_size = sizeof(RISCVIOMMUStatePci), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { }, }, diff --git a/hw/riscv/riscv-iommu-sys.c b/hw/riscv/riscv-iommu-sys.c index 65b24fb..e34d00a 100644 --- a/hw/riscv/riscv-iommu-sys.c +++ b/hw/riscv/riscv-iommu-sys.c @@ -26,7 +26,6 @@ #include "qemu/host-utils.h" #include "qemu/module.h" #include "qom/object.h" -#include "exec/exec-all.h" #include "trace.h" #include "riscv-iommu.h" @@ -54,12 +53,6 @@ struct RISCVIOMMUStateSys { uint8_t *msix_pba; }; -struct RISCVIOMMUSysClass { - /*< public >*/ - DeviceRealize parent_realize; - ResettablePhases parent_phases; -}; - static uint64_t msix_table_mmio_read(void *opaque, hwaddr addr, unsigned size) { @@ -227,7 +220,7 @@ static void riscv_iommu_sys_reset_hold(Object *obj, ResetType type) trace_riscv_iommu_sys_reset_hold(type); } -static void riscv_iommu_sys_class_init(ObjectClass *klass, void *data) +static void riscv_iommu_sys_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/riscv/riscv-iommu.c b/hw/riscv/riscv-iommu.c index 76e0fcd..a877e5d 100644 --- a/hw/riscv/riscv-iommu.c +++ b/hw/riscv/riscv-iommu.c @@ -18,6 +18,7 @@ #include "qemu/osdep.h" #include "qom/object.h" +#include "exec/target_page.h" #include "hw/pci/pci_bus.h" #include "hw/pci/pci_device.h" #include "hw/qdev-properties.h" @@ -2512,7 +2513,7 @@ static const Property riscv_iommu_properties[] = { RISCV_IOMMU_IOCOUNT_NUM), }; -static void riscv_iommu_class_init(ObjectClass *klass, void* data) +static void riscv_iommu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2653,7 +2654,7 @@ static int riscv_iommu_memory_region_index_len(IOMMUMemoryRegion *iommu_mr) return 1 << as->iommu->pid_bits; } -static void riscv_iommu_memory_region_init(ObjectClass *klass, void *data) +static void riscv_iommu_memory_region_init(ObjectClass *klass, const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c index a55d156..7f26760 100644 --- a/hw/riscv/riscv_hart.c +++ b/hw/riscv/riscv_hart.c @@ -72,7 +72,7 @@ static void csr_call(char *cmd, uint64_t cpu_num, int csrno, uint64_t *val) ret = riscv_csrr(env, csrno, (target_ulong *)val); } else if (strcmp(cmd, "set_csr") == 0) { ret = riscv_csrrw(env, csrno, NULL, *(target_ulong *)val, - MAKE_64BIT_MASK(0, TARGET_LONG_BITS)); + MAKE_64BIT_MASK(0, TARGET_LONG_BITS), 0); } g_assert(ret == RISCV_EXCP_NONE); @@ -104,8 +104,11 @@ static bool csr_qtest_callback(CharBackend *chr, gchar **words) static void riscv_cpu_register_csr_qtest_callback(void) { - static GOnce once; - g_once(&once, (GThreadFunc)qtest_set_command_cb, csr_qtest_callback); + static bool first = true; + if (first) { + first = false; + qtest_set_command_cb(csr_qtest_callback); + } } #endif @@ -160,7 +163,7 @@ static void riscv_harts_realize(DeviceState *dev, Error **errp) } } -static void riscv_harts_class_init(ObjectClass *klass, void *data) +static void riscv_harts_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c index e2242b9..3e7f441 100644 --- a/hw/riscv/shakti_c.c +++ b/hw/riscv/shakti_c.c @@ -25,7 +25,7 @@ #include "hw/intc/riscv_aclint.h" #include "system/system.h" #include "hw/qdev-properties.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/riscv/boot.h" static const struct MemmapEntry { @@ -71,7 +71,7 @@ static void shakti_c_machine_instance_init(Object *obj) { } -static void shakti_c_machine_class_init(ObjectClass *klass, void *data) +static void shakti_c_machine_class_init(ObjectClass *klass, const void *data) { MachineClass *mc = MACHINE_CLASS(klass); static const char * const valid_cpu_types[] = { @@ -142,7 +142,7 @@ static void shakti_c_soc_state_realize(DeviceState *dev, Error **errp) shakti_c_memmap[SHAKTI_C_ROM].base, &sss->rom); } -static void shakti_c_soc_class_init(ObjectClass *klass, void *data) +static void shakti_c_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = shakti_c_soc_state_realize; diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 73d3b74..7baed19 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -143,7 +143,7 @@ static void sifive_e_machine_instance_init(Object *obj) s->revb = false; } -static void sifive_e_machine_class_init(ObjectClass *oc, void *data) +static void sifive_e_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -284,7 +284,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp) &s->xip_mem); } -static void sifive_e_soc_class_init(ObjectClass *oc, void *data) +static void sifive_e_soc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 679f202..d69f942 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -713,7 +713,7 @@ static void sifive_u_machine_instance_init(Object *obj) object_property_set_description(obj, "serial", "Board serial number"); } -static void sifive_u_machine_class_init(ObjectClass *oc, void *data) +static void sifive_u_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -946,7 +946,7 @@ static const Property sifive_u_soc_props[] = { DEFINE_PROP_STRING("cpu-type", SiFiveUSoCState, cpu_type), }; -static void sifive_u_soc_class_init(ObjectClass *oc, void *data) +static void sifive_u_soc_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 74a2001..641aae8 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -342,7 +342,7 @@ static void spike_machine_instance_init(Object *obj) { } -static void spike_machine_class_init(ObjectClass *oc, void *data) +static void spike_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/riscv/virt-acpi-build.c b/hw/riscv/virt-acpi-build.c index 1ad6800..8b5683d 100644 --- a/hw/riscv/virt-acpi-build.c +++ b/hw/riscv/virt-acpi-build.c @@ -199,6 +199,32 @@ acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap, } /* + * Add DSDT entry for the IOMMU platform device. + * ACPI ID for IOMMU is defined in the section 6.2 of RISC-V BRS spec. + * https://github.com/riscv-non-isa/riscv-brs/releases/download/v0.8/riscv-brs-spec.pdf + */ +static void acpi_dsdt_add_iommu_sys(Aml *scope, const MemMapEntry *iommu_memmap, + uint32_t iommu_irq) +{ + uint32_t i; + + Aml *dev = aml_device("IMU0"); + aml_append(dev, aml_name_decl("_HID", aml_string("RSCV0004"))); + aml_append(dev, aml_name_decl("_UID", aml_int(0))); + + Aml *crs = aml_resource_template(); + aml_append(crs, aml_memory32_fixed(iommu_memmap->base, + iommu_memmap->size, AML_READ_WRITE)); + for (i = iommu_irq; i < iommu_irq + 4; i++) { + aml_append(crs, aml_interrupt(AML_CONSUMER, AML_EDGE, AML_ACTIVE_LOW, + AML_EXCLUSIVE, &i, 1)); + } + + aml_append(dev, aml_name_decl("_CRS", crs)); + aml_append(scope, dev); +} + +/* * Serial Port Console Redirection Table (SPCR) * Rev: 1.10 */ @@ -261,7 +287,7 @@ static void build_rhct(GArray *table_data, uint32_t isa_offset, num_rhct_nodes, cmo_offset = 0; RISCVCPU *cpu = &s->soc[0].harts[0]; uint32_t mmu_offset = 0; - uint8_t satp_mode_max; + bool rv32 = riscv_cpu_is_32bit(cpu); g_autofree char *isa = NULL; AcpiTable table = { .sig = "RHCT", .rev = 1, .oem_id = s->oem_id, @@ -281,7 +307,7 @@ static void build_rhct(GArray *table_data, num_rhct_nodes++; } - if (cpu->cfg.satp_mode.supported != 0) { + if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) { num_rhct_nodes++; } @@ -341,22 +367,21 @@ static void build_rhct(GArray *table_data, } /* MMU node structure */ - if (cpu->cfg.satp_mode.supported != 0) { - satp_mode_max = satp_mode_max_from_map(cpu->cfg.satp_mode.map); + if (!rv32 && cpu->cfg.max_satp_mode >= VM_1_10_SV39) { mmu_offset = table_data->len - table.table_offset; build_append_int_noprefix(table_data, 2, 2); /* Type */ build_append_int_noprefix(table_data, 8, 2); /* Length */ build_append_int_noprefix(table_data, 0x1, 2); /* Revision */ build_append_int_noprefix(table_data, 0, 1); /* Reserved */ /* MMU Type */ - if (satp_mode_max == VM_1_10_SV57) { + if (cpu->cfg.max_satp_mode == VM_1_10_SV57) { build_append_int_noprefix(table_data, 2, 1); /* Sv57 */ - } else if (satp_mode_max == VM_1_10_SV48) { + } else if (cpu->cfg.max_satp_mode == VM_1_10_SV48) { build_append_int_noprefix(table_data, 1, 1); /* Sv48 */ - } else if (satp_mode_max == VM_1_10_SV39) { + } else if (cpu->cfg.max_satp_mode == VM_1_10_SV39) { build_append_int_noprefix(table_data, 0, 1); /* Sv39 */ } else { - assert(1); + g_assert_not_reached(); } } @@ -450,6 +475,9 @@ static void build_dsdt(GArray *table_data, } acpi_dsdt_add_uart(scope, &memmap[VIRT_UART0], UART0_IRQ); + if (virt_is_iommu_sys_enabled(s)) { + acpi_dsdt_add_iommu_sys(scope, &memmap[VIRT_IOMMU_SYS], IOMMU_SYS_IRQ); + } if (socket_count == 1) { virtio_acpi_dsdt_add(scope, memmap[VIRT_VIRTIO].base, @@ -602,6 +630,187 @@ static void build_madt(GArray *table_data, acpi_table_end(linker, &table); } +#define ID_MAPPING_ENTRY_SIZE 20 +#define IOMMU_ENTRY_SIZE 40 +#define RISCV_INTERRUPT_WIRE_OFFSSET 40 +#define ROOT_COMPLEX_ENTRY_SIZE 20 +#define RIMT_NODE_OFFSET 48 + +/* + * ID Mapping Structure + */ +static void build_rimt_id_mapping(GArray *table_data, uint32_t source_id_base, + uint32_t num_ids, uint32_t dest_id_base) +{ + /* Source ID Base */ + build_append_int_noprefix(table_data, source_id_base, 4); + /* Number of IDs */ + build_append_int_noprefix(table_data, num_ids, 4); + /* Destination Device ID Base */ + build_append_int_noprefix(table_data, source_id_base, 4); + /* Destination IOMMU Offset */ + build_append_int_noprefix(table_data, dest_id_base, 4); + /* Flags */ + build_append_int_noprefix(table_data, 0, 4); +} + +struct AcpiRimtIdMapping { + uint32_t source_id_base; + uint32_t num_ids; +}; +typedef struct AcpiRimtIdMapping AcpiRimtIdMapping; + +/* Build the rimt ID mapping to IOMMU for a given PCI host bridge */ +static int rimt_host_bridges(Object *obj, void *opaque) +{ + GArray *idmap_blob = opaque; + + if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) { + PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus; + + if (bus && !pci_bus_bypass_iommu(bus)) { + int min_bus, max_bus; + + pci_bus_range(bus, &min_bus, &max_bus); + + AcpiRimtIdMapping idmap = { + .source_id_base = min_bus << 8, + .num_ids = (max_bus - min_bus + 1) << 8, + }; + g_array_append_val(idmap_blob, idmap); + } + } + + return 0; +} + +static int rimt_idmap_compare(gconstpointer a, gconstpointer b) +{ + AcpiRimtIdMapping *idmap_a = (AcpiRimtIdMapping *)a; + AcpiRimtIdMapping *idmap_b = (AcpiRimtIdMapping *)b; + + return idmap_a->source_id_base - idmap_b->source_id_base; +} + +/* + * RISC-V IO Mapping Table (RIMT) + * https://github.com/riscv-non-isa/riscv-acpi-rimt/releases/download/v0.99/rimt-spec.pdf + */ +static void build_rimt(GArray *table_data, BIOSLinker *linker, + RISCVVirtState *s) +{ + int i, nb_nodes, rc_mapping_count; + size_t node_size, iommu_offset = 0; + uint32_t id = 0; + g_autoptr(GArray) iommu_idmaps = g_array_new(false, true, + sizeof(AcpiRimtIdMapping)); + + AcpiTable table = { .sig = "RIMT", .rev = 1, .oem_id = s->oem_id, + .oem_table_id = s->oem_table_id }; + + acpi_table_begin(&table, table_data); + + object_child_foreach_recursive(object_get_root(), + rimt_host_bridges, iommu_idmaps); + + /* Sort the ID mapping by Source ID Base*/ + g_array_sort(iommu_idmaps, rimt_idmap_compare); + + nb_nodes = 2; /* RC, IOMMU */ + rc_mapping_count = iommu_idmaps->len; + /* Number of RIMT Nodes */ + build_append_int_noprefix(table_data, nb_nodes, 4); + + /* Offset to Array of RIMT Nodes */ + build_append_int_noprefix(table_data, RIMT_NODE_OFFSET, 4); + build_append_int_noprefix(table_data, 0, 4); /* Reserved */ + + iommu_offset = table_data->len - table.table_offset; + /* IOMMU Device Structure */ + build_append_int_noprefix(table_data, 0, 1); /* Type - IOMMU*/ + build_append_int_noprefix(table_data, 1, 1); /* Revision */ + node_size = IOMMU_ENTRY_SIZE; + build_append_int_noprefix(table_data, node_size, 2); /* Length */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + build_append_int_noprefix(table_data, id++, 2); /* ID */ + if (virt_is_iommu_sys_enabled(s)) { + /* Hardware ID */ + build_append_int_noprefix(table_data, 'R', 1); + build_append_int_noprefix(table_data, 'S', 1); + build_append_int_noprefix(table_data, 'C', 1); + build_append_int_noprefix(table_data, 'V', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '4', 1); + /* Base Address */ + build_append_int_noprefix(table_data, + s->memmap[VIRT_IOMMU_SYS].base, 8); + build_append_int_noprefix(table_data, 0, 4); /* Flags */ + } else { + /* Hardware ID */ + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '1', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '0', 1); + build_append_int_noprefix(table_data, '1', 1); + build_append_int_noprefix(table_data, '4', 1); + + build_append_int_noprefix(table_data, 0, 8); /* Base Address */ + build_append_int_noprefix(table_data, 1, 4); /* Flags */ + } + + build_append_int_noprefix(table_data, 0, 4); /* Proximity Domain */ + build_append_int_noprefix(table_data, 0, 2); /* PCI Segment number */ + /* PCIe B/D/F */ + if (virt_is_iommu_sys_enabled(s)) { + build_append_int_noprefix(table_data, 0, 2); + } else { + build_append_int_noprefix(table_data, s->pci_iommu_bdf, 2); + } + /* Number of interrupt wires */ + build_append_int_noprefix(table_data, 0, 2); + /* Interrupt wire array offset */ + build_append_int_noprefix(table_data, RISCV_INTERRUPT_WIRE_OFFSSET, 2); + + /* PCIe Root Complex Node */ + build_append_int_noprefix(table_data, 1, 1); /* Type */ + build_append_int_noprefix(table_data, 1, 1); /* Revision */ + node_size = ROOT_COMPLEX_ENTRY_SIZE + + ID_MAPPING_ENTRY_SIZE * rc_mapping_count; + build_append_int_noprefix(table_data, node_size, 2); /* Length */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + build_append_int_noprefix(table_data, id++, 2); /* ID */ + build_append_int_noprefix(table_data, 0, 4); /* Flags */ + build_append_int_noprefix(table_data, 0, 2); /* Reserved */ + /* PCI Segment number */ + build_append_int_noprefix(table_data, 0, 2); + /* ID mapping array offset */ + build_append_int_noprefix(table_data, ROOT_COMPLEX_ENTRY_SIZE, 2); + /* Number of ID mappings */ + build_append_int_noprefix(table_data, rc_mapping_count, 2); + + /* Output Reference */ + AcpiRimtIdMapping *range; + + /* ID mapping array */ + for (i = 0; i < iommu_idmaps->len; i++) { + range = &g_array_index(iommu_idmaps, AcpiRimtIdMapping, i); + if (virt_is_iommu_sys_enabled(s)) { + range->source_id_base = 0; + } else { + range->source_id_base = s->pci_iommu_bdf + 1; + } + range->num_ids = 0xffff - s->pci_iommu_bdf; + build_rimt_id_mapping(table_data, range->source_id_base, + range->num_ids, iommu_offset); + } + + acpi_table_end(linker, &table); +} + /* * ACPI spec, Revision 6.5+ * 5.2.16 System Resource Affinity Table (SRAT) @@ -679,6 +888,11 @@ static void virt_acpi_build(RISCVVirtState *s, AcpiBuildTables *tables) acpi_add_table(table_offsets, tables_blob); build_rhct(tables_blob, tables->linker, s); + if (virt_is_iommu_sys_enabled(s) || s->pci_iommu_bdf) { + acpi_add_table(table_offsets, tables_blob); + build_rimt(tables_blob, tables->linker, s); + } + acpi_add_table(table_offsets, tables_blob); spcr_setup(tables_blob, tables->linker, s); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 85849e6..cf280a9 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -166,8 +166,8 @@ static void virt_flash_map1(PFlashCFI01 *flash, static void virt_flash_map(RISCVVirtState *s, MemoryRegion *sysmem) { - hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; - hwaddr flashbase = virt_memmap[VIRT_FLASH].base; + hwaddr flashsize = s->memmap[VIRT_FLASH].size / 2; + hwaddr flashbase = s->memmap[VIRT_FLASH].base; virt_flash_map1(s->flash[0], flashbase, flashsize, sysmem); @@ -237,10 +237,10 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, uint32_t cpu_phandle; MachineState *ms = MACHINE(s); bool is_32_bit = riscv_is_32bit(&s->soc[0]); - uint8_t satp_mode_max; for (cpu = s->soc[socket].num_harts - 1; cpu >= 0; cpu--) { RISCVCPU *cpu_ptr = &s->soc[socket].harts[cpu]; + int8_t satp_mode_max = cpu_ptr->cfg.max_satp_mode; g_autofree char *cpu_name = NULL; g_autofree char *core_name = NULL; g_autofree char *intc_name = NULL; @@ -252,8 +252,7 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, s->soc[socket].hartid_base + cpu); qemu_fdt_add_subnode(ms->fdt, cpu_name); - if (cpu_ptr->cfg.satp_mode.supported != 0) { - satp_mode_max = satp_mode_max_from_map(cpu_ptr->cfg.satp_mode.map); + if (satp_mode_max != -1) { sv_name = g_strdup_printf("riscv,%s", satp_mode_str(satp_mode_max, is_32_bit)); qemu_fdt_setprop_string(ms->fdt, cpu_name, "mmu-type", sv_name); @@ -301,16 +300,16 @@ static void create_fdt_socket_cpus(RISCVVirtState *s, int socket, } } -static void create_fdt_socket_memory(RISCVVirtState *s, - const MemMapEntry *memmap, int socket) +static void create_fdt_socket_memory(RISCVVirtState *s, int socket) { g_autofree char *mem_name = NULL; - uint64_t addr, size; + hwaddr addr; + uint64_t size; MachineState *ms = MACHINE(s); - addr = memmap[VIRT_DRAM].base + riscv_socket_mem_offset(ms, socket); + addr = s->memmap[VIRT_DRAM].base + riscv_socket_mem_offset(ms, socket); size = riscv_socket_mem_size(ms, socket); - mem_name = g_strdup_printf("/memory@%lx", (long)addr); + mem_name = g_strdup_printf("/memory@%"HWADDR_PRIx, addr); qemu_fdt_add_subnode(ms->fdt, mem_name); qemu_fdt_setprop_cells(ms->fdt, mem_name, "reg", addr >> 32, addr, size >> 32, size); @@ -319,7 +318,7 @@ static void create_fdt_socket_memory(RISCVVirtState *s, } static void create_fdt_socket_clint(RISCVVirtState *s, - const MemMapEntry *memmap, int socket, + int socket, uint32_t *intc_phandles) { int cpu; @@ -340,21 +339,22 @@ static void create_fdt_socket_clint(RISCVVirtState *s, clint_cells[cpu * 4 + 3] = cpu_to_be32(IRQ_M_TIMER); } - clint_addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket); + clint_addr = s->memmap[VIRT_CLINT].base + + (s->memmap[VIRT_CLINT].size * socket); clint_name = g_strdup_printf("/soc/clint@%lx", clint_addr); qemu_fdt_add_subnode(ms->fdt, clint_name); qemu_fdt_setprop_string_array(ms->fdt, clint_name, "compatible", (char **)&clint_compat, ARRAY_SIZE(clint_compat)); qemu_fdt_setprop_cells(ms->fdt, clint_name, "reg", - 0x0, clint_addr, 0x0, memmap[VIRT_CLINT].size); + 0x0, clint_addr, 0x0, s->memmap[VIRT_CLINT].size); qemu_fdt_setprop(ms->fdt, clint_name, "interrupts-extended", clint_cells, s->soc[socket].num_harts * sizeof(uint32_t) * 4); riscv_socket_fdt_write_id(ms, clint_name, socket); } static void create_fdt_socket_aclint(RISCVVirtState *s, - const MemMapEntry *memmap, int socket, + int socket, uint32_t *intc_phandles) { int cpu; @@ -381,8 +381,10 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, aclint_cells_size = s->soc[socket].num_harts * sizeof(uint32_t) * 2; if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) { - addr = memmap[VIRT_CLINT].base + (memmap[VIRT_CLINT].size * socket); + addr = s->memmap[VIRT_CLINT].base + + (s->memmap[VIRT_CLINT].size * socket); name = g_strdup_printf("/soc/mswi@%lx", addr); + qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_setprop_string(ms->fdt, name, "compatible", "riscv,aclint-mswi"); @@ -397,13 +399,13 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, } if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { - addr = memmap[VIRT_CLINT].base + + addr = s->memmap[VIRT_CLINT].base + (RISCV_ACLINT_DEFAULT_MTIMER_SIZE * socket); size = RISCV_ACLINT_DEFAULT_MTIMER_SIZE; } else { - addr = memmap[VIRT_CLINT].base + RISCV_ACLINT_SWI_SIZE + - (memmap[VIRT_CLINT].size * socket); - size = memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE; + addr = s->memmap[VIRT_CLINT].base + RISCV_ACLINT_SWI_SIZE + + (s->memmap[VIRT_CLINT].size * socket); + size = s->memmap[VIRT_CLINT].size - RISCV_ACLINT_SWI_SIZE; } name = g_strdup_printf("/soc/mtimer@%lx", addr); qemu_fdt_add_subnode(ms->fdt, name); @@ -420,14 +422,15 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, g_free(name); if (s->aia_type != VIRT_AIA_TYPE_APLIC_IMSIC) { - addr = memmap[VIRT_ACLINT_SSWI].base + - (memmap[VIRT_ACLINT_SSWI].size * socket); + addr = s->memmap[VIRT_ACLINT_SSWI].base + + (s->memmap[VIRT_ACLINT_SSWI].size * socket); + name = g_strdup_printf("/soc/sswi@%lx", addr); qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_setprop_string(ms->fdt, name, "compatible", "riscv,aclint-sswi"); qemu_fdt_setprop_cells(ms->fdt, name, "reg", - 0x0, addr, 0x0, memmap[VIRT_ACLINT_SSWI].size); + 0x0, addr, 0x0, s->memmap[VIRT_ACLINT_SSWI].size); qemu_fdt_setprop(ms->fdt, name, "interrupts-extended", aclint_sswi_cells, aclint_cells_size); qemu_fdt_setprop(ms->fdt, name, "interrupt-controller", NULL, 0); @@ -438,7 +441,7 @@ static void create_fdt_socket_aclint(RISCVVirtState *s, } static void create_fdt_socket_plic(RISCVVirtState *s, - const MemMapEntry *memmap, int socket, + int socket, uint32_t *phandle, uint32_t *intc_phandles, uint32_t *plic_phandles) { @@ -452,7 +455,8 @@ static void create_fdt_socket_plic(RISCVVirtState *s, }; plic_phandles[socket] = (*phandle)++; - plic_addr = memmap[VIRT_PLIC].base + (memmap[VIRT_PLIC].size * socket); + plic_addr = s->memmap[VIRT_PLIC].base + + (s->memmap[VIRT_PLIC].size * socket); plic_name = g_strdup_printf("/soc/plic@%lx", plic_addr); qemu_fdt_add_subnode(ms->fdt, plic_name); qemu_fdt_setprop_cell(ms->fdt, plic_name, @@ -491,7 +495,7 @@ static void create_fdt_socket_plic(RISCVVirtState *s, } qemu_fdt_setprop_cells(ms->fdt, plic_name, "reg", - 0x0, plic_addr, 0x0, memmap[VIRT_PLIC].size); + 0x0, plic_addr, 0x0, s->memmap[VIRT_PLIC].size); qemu_fdt_setprop_cell(ms->fdt, plic_name, "riscv,ndev", VIRT_IRQCHIP_NUM_SOURCES - 1); riscv_socket_fdt_write_id(ms, plic_name, socket); @@ -500,8 +504,8 @@ static void create_fdt_socket_plic(RISCVVirtState *s, if (!socket) { platform_bus_add_all_fdt_nodes(ms->fdt, plic_name, - memmap[VIRT_PLATFORM_BUS].base, - memmap[VIRT_PLATFORM_BUS].size, + s->memmap[VIRT_PLATFORM_BUS].base, + s->memmap[VIRT_PLATFORM_BUS].size, VIRT_PLATFORM_BUS_IRQ); } } @@ -588,7 +592,7 @@ static void create_fdt_one_imsic(RISCVVirtState *s, hwaddr base_addr, qemu_fdt_setprop_cell(ms->fdt, imsic_name, "phandle", msi_phandle); } -static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, +static void create_fdt_imsic(RISCVVirtState *s, uint32_t *phandle, uint32_t *intc_phandles, uint32_t *msi_m_phandle, uint32_t *msi_s_phandle) { @@ -597,12 +601,12 @@ static void create_fdt_imsic(RISCVVirtState *s, const MemMapEntry *memmap, if (!kvm_enabled()) { /* M-level IMSIC node */ - create_fdt_one_imsic(s, memmap[VIRT_IMSIC_M].base, intc_phandles, + create_fdt_one_imsic(s, s->memmap[VIRT_IMSIC_M].base, intc_phandles, *msi_m_phandle, true, 0); } /* S-level IMSIC node */ - create_fdt_one_imsic(s, memmap[VIRT_IMSIC_S].base, intc_phandles, + create_fdt_one_imsic(s, s->memmap[VIRT_IMSIC_S].base, intc_phandles, *msi_s_phandle, false, imsic_num_bits(s->aia_guests + 1)); @@ -679,7 +683,7 @@ static void create_fdt_one_aplic(RISCVVirtState *s, int socket, } static void create_fdt_socket_aplic(RISCVVirtState *s, - const MemMapEntry *memmap, int socket, + int socket, uint32_t msi_m_phandle, uint32_t msi_s_phandle, uint32_t *phandle, @@ -696,18 +700,19 @@ static void create_fdt_socket_aplic(RISCVVirtState *s, if (!kvm_enabled()) { /* M-level APLIC node */ - aplic_addr = memmap[VIRT_APLIC_M].base + - (memmap[VIRT_APLIC_M].size * socket); - create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_M].size, + aplic_addr = s->memmap[VIRT_APLIC_M].base + + (s->memmap[VIRT_APLIC_M].size * socket); + create_fdt_one_aplic(s, socket, aplic_addr, + s->memmap[VIRT_APLIC_M].size, msi_m_phandle, intc_phandles, aplic_m_phandle, aplic_s_phandle, true, num_harts); } /* S-level APLIC node */ - aplic_addr = memmap[VIRT_APLIC_S].base + - (memmap[VIRT_APLIC_S].size * socket); - create_fdt_one_aplic(s, socket, aplic_addr, memmap[VIRT_APLIC_S].size, + aplic_addr = s->memmap[VIRT_APLIC_S].base + + (s->memmap[VIRT_APLIC_S].size * socket); + create_fdt_one_aplic(s, socket, aplic_addr, s->memmap[VIRT_APLIC_S].size, msi_s_phandle, intc_phandles, aplic_s_phandle, 0, false, num_harts); @@ -715,8 +720,8 @@ static void create_fdt_socket_aplic(RISCVVirtState *s, if (!socket) { g_autofree char *aplic_name = fdt_get_aplic_nodename(aplic_addr); platform_bus_add_all_fdt_nodes(ms->fdt, aplic_name, - memmap[VIRT_PLATFORM_BUS].base, - memmap[VIRT_PLATFORM_BUS].size, + s->memmap[VIRT_PLATFORM_BUS].base, + s->memmap[VIRT_PLATFORM_BUS].size, VIRT_PLATFORM_BUS_IRQ); } @@ -734,7 +739,7 @@ static void create_fdt_pmu(RISCVVirtState *s) riscv_pmu_generate_fdt_node(ms->fdt, hart.pmu_avail_ctrs, pmu_name); } -static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, +static void create_fdt_sockets(RISCVVirtState *s, uint32_t *phandle, uint32_t *irq_mmio_phandle, uint32_t *irq_pcie_phandle, @@ -770,20 +775,20 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, create_fdt_socket_cpus(s, socket, clust_name, phandle, &intc_phandles[phandle_pos]); - create_fdt_socket_memory(s, memmap, socket); + create_fdt_socket_memory(s, socket); if (virt_aclint_allowed() && s->have_aclint) { - create_fdt_socket_aclint(s, memmap, socket, + create_fdt_socket_aclint(s, socket, &intc_phandles[phandle_pos]); } else if (tcg_enabled()) { - create_fdt_socket_clint(s, memmap, socket, + create_fdt_socket_clint(s, socket, &intc_phandles[phandle_pos]); } } if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { - create_fdt_imsic(s, memmap, phandle, intc_phandles, - &msi_m_phandle, &msi_s_phandle); + create_fdt_imsic(s, phandle, intc_phandles, + &msi_m_phandle, &msi_s_phandle); *msi_pcie_phandle = msi_s_phandle; } @@ -792,7 +797,7 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, * mode, we'll use only one APLIC instance. */ if (!virt_use_emulated_aplic(s->aia_type)) { - create_fdt_socket_aplic(s, memmap, 0, + create_fdt_socket_aplic(s, 0, msi_m_phandle, msi_s_phandle, phandle, &intc_phandles[0], xplic_phandles, ms->smp.cpus); @@ -806,11 +811,11 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, phandle_pos -= s->soc[socket].num_harts; if (s->aia_type == VIRT_AIA_TYPE_NONE) { - create_fdt_socket_plic(s, memmap, socket, phandle, + create_fdt_socket_plic(s, socket, phandle, &intc_phandles[phandle_pos], xplic_phandles); } else { - create_fdt_socket_aplic(s, memmap, socket, + create_fdt_socket_aplic(s, socket, msi_m_phandle, msi_s_phandle, phandle, &intc_phandles[phandle_pos], xplic_phandles, @@ -837,21 +842,24 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap, riscv_socket_fdt_write_distance_matrix(ms); } -static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap, - uint32_t irq_virtio_phandle) +static void create_fdt_virtio(RISCVVirtState *s, uint32_t irq_virtio_phandle) { int i; MachineState *ms = MACHINE(s); + hwaddr virtio_base = s->memmap[VIRT_VIRTIO].base; for (i = 0; i < VIRTIO_COUNT; i++) { - g_autofree char *name = g_strdup_printf("/soc/virtio_mmio@%lx", - (long)(memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size)); + g_autofree char *name = NULL; + uint64_t size = s->memmap[VIRT_VIRTIO].size; + hwaddr addr = virtio_base + i * size; + + name = g_strdup_printf("/soc/virtio_mmio@%"HWADDR_PRIx, addr); qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_setprop_string(ms->fdt, name, "compatible", "virtio,mmio"); qemu_fdt_setprop_cells(ms->fdt, name, "reg", - 0x0, memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size, - 0x0, memmap[VIRT_VIRTIO].size); + 0x0, addr, + 0x0, size); qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_virtio_phandle); if (s->aia_type == VIRT_AIA_TYPE_NONE) { @@ -864,7 +872,7 @@ static void create_fdt_virtio(RISCVVirtState *s, const MemMapEntry *memmap, } } -static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, +static void create_fdt_pcie(RISCVVirtState *s, uint32_t irq_pcie_phandle, uint32_t msi_pcie_phandle, uint32_t iommu_sys_phandle) @@ -872,8 +880,8 @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, g_autofree char *name = NULL; MachineState *ms = MACHINE(s); - name = g_strdup_printf("/soc/pci@%lx", - (long) memmap[VIRT_PCIE_ECAM].base); + name = g_strdup_printf("/soc/pci@%"HWADDR_PRIx, + s->memmap[VIRT_PCIE_ECAM].base); qemu_fdt_setprop_cell(ms->fdt, name, "#address-cells", FDT_PCI_ADDR_CELLS); qemu_fdt_setprop_cell(ms->fdt, name, "#interrupt-cells", @@ -884,19 +892,19 @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_string(ms->fdt, name, "device_type", "pci"); qemu_fdt_setprop_cell(ms->fdt, name, "linux,pci-domain", 0); qemu_fdt_setprop_cells(ms->fdt, name, "bus-range", 0, - memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1); + s->memmap[VIRT_PCIE_ECAM].size / PCIE_MMCFG_SIZE_MIN - 1); qemu_fdt_setprop(ms->fdt, name, "dma-coherent", NULL, 0); if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { qemu_fdt_setprop_cell(ms->fdt, name, "msi-parent", msi_pcie_phandle); } qemu_fdt_setprop_cells(ms->fdt, name, "reg", 0, - memmap[VIRT_PCIE_ECAM].base, 0, memmap[VIRT_PCIE_ECAM].size); + s->memmap[VIRT_PCIE_ECAM].base, 0, s->memmap[VIRT_PCIE_ECAM].size); qemu_fdt_setprop_sized_cells(ms->fdt, name, "ranges", 1, FDT_PCI_RANGE_IOPORT, 2, 0, - 2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size, + 2, s->memmap[VIRT_PCIE_PIO].base, 2, s->memmap[VIRT_PCIE_PIO].size, 1, FDT_PCI_RANGE_MMIO, - 2, memmap[VIRT_PCIE_MMIO].base, - 2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size, + 2, s->memmap[VIRT_PCIE_MMIO].base, + 2, s->memmap[VIRT_PCIE_MMIO].base, 2, s->memmap[VIRT_PCIE_MMIO].size, 1, FDT_PCI_RANGE_MMIO_64BIT, 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.base, 2, virt_high_pcie_memmap.size); @@ -910,16 +918,15 @@ static void create_fdt_pcie(RISCVVirtState *s, const MemMapEntry *memmap, create_pcie_irq_map(s, ms->fdt, name, irq_pcie_phandle); } -static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap, - uint32_t *phandle) +static void create_fdt_reset(RISCVVirtState *s, uint32_t *phandle) { char *name; uint32_t test_phandle; MachineState *ms = MACHINE(s); test_phandle = (*phandle)++; - name = g_strdup_printf("/soc/test@%lx", - (long)memmap[VIRT_TEST].base); + name = g_strdup_printf("/soc/test@%"HWADDR_PRIx, + s->memmap[VIRT_TEST].base); qemu_fdt_add_subnode(ms->fdt, name); { static const char * const compat[3] = { @@ -929,7 +936,7 @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap, (char **)&compat, ARRAY_SIZE(compat)); } qemu_fdt_setprop_cells(ms->fdt, name, "reg", - 0x0, memmap[VIRT_TEST].base, 0x0, memmap[VIRT_TEST].size); + 0x0, s->memmap[VIRT_TEST].base, 0x0, s->memmap[VIRT_TEST].size); qemu_fdt_setprop_cell(ms->fdt, name, "phandle", test_phandle); test_phandle = qemu_fdt_get_phandle(ms->fdt, name); g_free(name); @@ -951,18 +958,19 @@ static void create_fdt_reset(RISCVVirtState *s, const MemMapEntry *memmap, g_free(name); } -static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap, +static void create_fdt_uart(RISCVVirtState *s, uint32_t irq_mmio_phandle) { g_autofree char *name = NULL; MachineState *ms = MACHINE(s); - name = g_strdup_printf("/soc/serial@%lx", (long)memmap[VIRT_UART0].base); + name = g_strdup_printf("/soc/serial@%"HWADDR_PRIx, + s->memmap[VIRT_UART0].base); qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_setprop_string(ms->fdt, name, "compatible", "ns16550a"); qemu_fdt_setprop_cells(ms->fdt, name, "reg", - 0x0, memmap[VIRT_UART0].base, - 0x0, memmap[VIRT_UART0].size); + 0x0, s->memmap[VIRT_UART0].base, + 0x0, s->memmap[VIRT_UART0].size); qemu_fdt_setprop_cell(ms->fdt, name, "clock-frequency", 3686400); qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle); if (s->aia_type == VIRT_AIA_TYPE_NONE) { @@ -975,18 +983,19 @@ static void create_fdt_uart(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_string(ms->fdt, "/aliases", "serial0", name); } -static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap, +static void create_fdt_rtc(RISCVVirtState *s, uint32_t irq_mmio_phandle) { g_autofree char *name = NULL; MachineState *ms = MACHINE(s); - name = g_strdup_printf("/soc/rtc@%lx", (long)memmap[VIRT_RTC].base); + name = g_strdup_printf("/soc/rtc@%"HWADDR_PRIx, + s->memmap[VIRT_RTC].base); qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_setprop_string(ms->fdt, name, "compatible", "google,goldfish-rtc"); qemu_fdt_setprop_cells(ms->fdt, name, "reg", - 0x0, memmap[VIRT_RTC].base, 0x0, memmap[VIRT_RTC].size); + 0x0, s->memmap[VIRT_RTC].base, 0x0, s->memmap[VIRT_RTC].size); qemu_fdt_setprop_cell(ms->fdt, name, "interrupt-parent", irq_mmio_phandle); if (s->aia_type == VIRT_AIA_TYPE_NONE) { @@ -996,11 +1005,11 @@ static void create_fdt_rtc(RISCVVirtState *s, const MemMapEntry *memmap, } } -static void create_fdt_flash(RISCVVirtState *s, const MemMapEntry *memmap) +static void create_fdt_flash(RISCVVirtState *s) { MachineState *ms = MACHINE(s); - hwaddr flashsize = virt_memmap[VIRT_FLASH].size / 2; - hwaddr flashbase = virt_memmap[VIRT_FLASH].base; + hwaddr flashsize = s->memmap[VIRT_FLASH].size / 2; + hwaddr flashbase = s->memmap[VIRT_FLASH].base; g_autofree char *name = g_strdup_printf("/flash@%" PRIx64, flashbase); qemu_fdt_add_subnode(ms->fdt, name); @@ -1011,11 +1020,11 @@ static void create_fdt_flash(RISCVVirtState *s, const MemMapEntry *memmap) qemu_fdt_setprop_cell(ms->fdt, name, "bank-width", 4); } -static void create_fdt_fw_cfg(RISCVVirtState *s, const MemMapEntry *memmap) +static void create_fdt_fw_cfg(RISCVVirtState *s) { MachineState *ms = MACHINE(s); - hwaddr base = memmap[VIRT_FW_CFG].base; - hwaddr size = memmap[VIRT_FW_CFG].size; + hwaddr base = s->memmap[VIRT_FW_CFG].base; + hwaddr size = s->memmap[VIRT_FW_CFG].size; g_autofree char *nodename = g_strdup_printf("/fw-cfg@%" PRIx64, base); qemu_fdt_add_subnode(ms->fdt, nodename); @@ -1034,8 +1043,8 @@ static void create_fdt_virtio_iommu(RISCVVirtState *s, uint16_t bdf) g_autofree char *iommu_node = NULL; g_autofree char *pci_node = NULL; - pci_node = g_strdup_printf("/soc/pci@%lx", - (long) virt_memmap[VIRT_PCIE_ECAM].base); + pci_node = g_strdup_printf("/soc/pci@%"HWADDR_PRIx, + s->memmap[VIRT_PCIE_ECAM].base); iommu_node = g_strdup_printf("%s/virtio_iommu@%x,%x", pci_node, PCI_SLOT(bdf), PCI_FUNC(bdf)); iommu_phandle = qemu_fdt_alloc_phandle(fdt); @@ -1103,8 +1112,8 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf) g_autofree char *iommu_node = NULL; g_autofree char *pci_node = NULL; - pci_node = g_strdup_printf("/soc/pci@%lx", - (long) virt_memmap[VIRT_PCIE_ECAM].base); + pci_node = g_strdup_printf("/soc/pci@%"HWADDR_PRIx, + s->memmap[VIRT_PCIE_ECAM].base); iommu_node = g_strdup_printf("%s/iommu@%x", pci_node, bdf); iommu_phandle = qemu_fdt_alloc_phandle(fdt); qemu_fdt_add_subnode(fdt, iommu_node); @@ -1117,6 +1126,7 @@ static void create_fdt_iommu(RISCVVirtState *s, uint16_t bdf) qemu_fdt_setprop_cells(fdt, pci_node, "iommu-map", 0, iommu_phandle, 0, bdf, bdf + 1, iommu_phandle, bdf + 1, 0xffff - bdf); + s->pci_iommu_bdf = bdf; } static void finalize_fdt(RISCVVirtState *s) @@ -1125,27 +1135,27 @@ static void finalize_fdt(RISCVVirtState *s) uint32_t irq_pcie_phandle = 1, irq_virtio_phandle = 1; uint32_t iommu_sys_phandle = 1; - create_fdt_sockets(s, virt_memmap, &phandle, &irq_mmio_phandle, + create_fdt_sockets(s, &phandle, &irq_mmio_phandle, &irq_pcie_phandle, &irq_virtio_phandle, &msi_pcie_phandle); - create_fdt_virtio(s, virt_memmap, irq_virtio_phandle); + create_fdt_virtio(s, irq_virtio_phandle); if (virt_is_iommu_sys_enabled(s)) { create_fdt_iommu_sys(s, irq_mmio_phandle, msi_pcie_phandle, &iommu_sys_phandle); } - create_fdt_pcie(s, virt_memmap, irq_pcie_phandle, msi_pcie_phandle, + create_fdt_pcie(s, irq_pcie_phandle, msi_pcie_phandle, iommu_sys_phandle); - create_fdt_reset(s, virt_memmap, &phandle); + create_fdt_reset(s, &phandle); - create_fdt_uart(s, virt_memmap, irq_mmio_phandle); + create_fdt_uart(s, irq_mmio_phandle); - create_fdt_rtc(s, virt_memmap, irq_mmio_phandle); + create_fdt_rtc(s, irq_mmio_phandle); } -static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap) +static void create_fdt(RISCVVirtState *s) { MachineState *ms = MACHINE(s); uint8_t rng_seed[32]; @@ -1172,7 +1182,8 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap) * The "/soc/pci@..." node is needed for PCIE hotplugs * that might happen before finalize_fdt(). */ - name = g_strdup_printf("/soc/pci@%lx", (long) memmap[VIRT_PCIE_ECAM].base); + name = g_strdup_printf("/soc/pci@%"HWADDR_PRIx, + s->memmap[VIRT_PCIE_ECAM].base); qemu_fdt_add_subnode(ms->fdt, name); qemu_fdt_add_subnode(ms->fdt, "/chosen"); @@ -1184,8 +1195,8 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap) qemu_fdt_add_subnode(ms->fdt, "/aliases"); - create_fdt_flash(s, memmap); - create_fdt_fw_cfg(s, memmap); + create_fdt_flash(s); + create_fdt_fw_cfg(s); create_fdt_pmu(s); } @@ -1261,9 +1272,8 @@ static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem, return dev; } -static FWCfgState *create_fw_cfg(const MachineState *ms) +static FWCfgState *create_fw_cfg(const MachineState *ms, hwaddr base) { - hwaddr base = virt_memmap[VIRT_FW_CFG].base; FWCfgState *fw_cfg; fw_cfg = fw_cfg_init_mem_wide(base + 8, base, 8, base + 16, @@ -1360,14 +1370,13 @@ static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip) { DeviceState *dev; SysBusDevice *sysbus; - const MemMapEntry *memmap = virt_memmap; int i; MemoryRegion *sysmem = get_system_memory(); dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE); dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE); qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS); - qdev_prop_set_uint32(dev, "mmio_size", memmap[VIRT_PLATFORM_BUS].size); + qdev_prop_set_uint32(dev, "mmio_size", s->memmap[VIRT_PLATFORM_BUS].size); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); s->platform_bus_dev = dev; @@ -1378,7 +1387,7 @@ static void create_platform_bus(RISCVVirtState *s, DeviceState *irqchip) } memory_region_add_subregion(sysmem, - memmap[VIRT_PLATFORM_BUS].base, + s->memmap[VIRT_PLATFORM_BUS].base, sysbus_mmio_get_region(sysbus, 0)); } @@ -1425,9 +1434,8 @@ static void virt_machine_done(Notifier *notifier, void *data) { RISCVVirtState *s = container_of(notifier, RISCVVirtState, machine_done); - const MemMapEntry *memmap = virt_memmap; MachineState *machine = MACHINE(s); - hwaddr start_addr = memmap[VIRT_DRAM].base; + hwaddr start_addr = s->memmap[VIRT_DRAM].base; target_ulong firmware_end_addr, kernel_start_addr; const char *firmware_name = riscv_default_firmware_name(&s->soc[0]); uint64_t fdt_load_addr; @@ -1471,14 +1479,14 @@ static void virt_machine_done(Notifier *notifier, void *data) * let's overwrite the address we jump to after reset to * the base of the flash. */ - start_addr = virt_memmap[VIRT_FLASH].base; + start_addr = s->memmap[VIRT_FLASH].base; } else { /* * Pflash was supplied but either KVM guest or bios is not none. * In this case, base of the flash would contain S-mode payload. */ riscv_setup_firmware_boot(machine); - kernel_entry = virt_memmap[VIRT_FLASH].base; + kernel_entry = s->memmap[VIRT_FLASH].base; } } @@ -1492,15 +1500,15 @@ static void virt_machine_done(Notifier *notifier, void *data) kernel_entry = boot_info.image_low_addr; } - fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base, - memmap[VIRT_DRAM].size, + fdt_load_addr = riscv_compute_fdt_addr(s->memmap[VIRT_DRAM].base, + s->memmap[VIRT_DRAM].size, machine, &boot_info); riscv_load_fdt(fdt_load_addr, machine->fdt); /* load the reset vector */ riscv_setup_rom_reset_vec(machine, &s->soc[0], start_addr, - virt_memmap[VIRT_MROM].base, - virt_memmap[VIRT_MROM].size, kernel_entry, + s->memmap[VIRT_MROM].base, + s->memmap[VIRT_MROM].size, kernel_entry, fdt_load_addr); /* @@ -1521,7 +1529,6 @@ static void virt_machine_done(Notifier *notifier, void *data) static void virt_machine_init(MachineState *machine) { - const MemMapEntry *memmap = virt_memmap; RISCVVirtState *s = RISCV_VIRT_MACHINE(machine); MemoryRegion *system_memory = get_system_memory(); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); @@ -1529,6 +1536,8 @@ static void virt_machine_init(MachineState *machine) int i, base_hartid, hart_count; int socket_count = riscv_socket_count(machine); + s->memmap = virt_memmap; + /* Check socket count limit */ if (VIRT_SOCKETS_MAX < socket_count) { error_report("number of sockets/nodes should be less than %d", @@ -1576,7 +1585,7 @@ static void virt_machine_init(MachineState *machine) if (virt_aclint_allowed() && s->have_aclint) { if (s->aia_type == VIRT_AIA_TYPE_APLIC_IMSIC) { /* Per-socket ACLINT MTIMER */ - riscv_aclint_mtimer_create(memmap[VIRT_CLINT].base + + riscv_aclint_mtimer_create(s->memmap[VIRT_CLINT].base + i * RISCV_ACLINT_DEFAULT_MTIMER_SIZE, RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, @@ -1585,28 +1594,28 @@ static void virt_machine_init(MachineState *machine) RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); } else { /* Per-socket ACLINT MSWI, MTIMER, and SSWI */ - riscv_aclint_swi_create(memmap[VIRT_CLINT].base + - i * memmap[VIRT_CLINT].size, + riscv_aclint_swi_create(s->memmap[VIRT_CLINT].base + + i * s->memmap[VIRT_CLINT].size, base_hartid, hart_count, false); - riscv_aclint_mtimer_create(memmap[VIRT_CLINT].base + - i * memmap[VIRT_CLINT].size + + riscv_aclint_mtimer_create(s->memmap[VIRT_CLINT].base + + i * s->memmap[VIRT_CLINT].size + RISCV_ACLINT_SWI_SIZE, RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); - riscv_aclint_swi_create(memmap[VIRT_ACLINT_SSWI].base + - i * memmap[VIRT_ACLINT_SSWI].size, + riscv_aclint_swi_create(s->memmap[VIRT_ACLINT_SSWI].base + + i * s->memmap[VIRT_ACLINT_SSWI].size, base_hartid, hart_count, true); } } else if (tcg_enabled()) { /* Per-socket SiFive CLINT */ riscv_aclint_swi_create( - memmap[VIRT_CLINT].base + i * memmap[VIRT_CLINT].size, + s->memmap[VIRT_CLINT].base + i * s->memmap[VIRT_CLINT].size, base_hartid, hart_count, false); - riscv_aclint_mtimer_create(memmap[VIRT_CLINT].base + - i * memmap[VIRT_CLINT].size + RISCV_ACLINT_SWI_SIZE, + riscv_aclint_mtimer_create(s->memmap[VIRT_CLINT].base + + i * s->memmap[VIRT_CLINT].size + RISCV_ACLINT_SWI_SIZE, RISCV_ACLINT_DEFAULT_MTIMER_SIZE, base_hartid, hart_count, RISCV_ACLINT_DEFAULT_MTIMECMP, RISCV_ACLINT_DEFAULT_MTIME, RISCV_ACLINT_DEFAULT_TIMEBASE_FREQ, true); @@ -1614,11 +1623,11 @@ static void virt_machine_init(MachineState *machine) /* Per-socket interrupt controller */ if (s->aia_type == VIRT_AIA_TYPE_NONE) { - s->irqchip[i] = virt_create_plic(memmap, i, + s->irqchip[i] = virt_create_plic(s->memmap, i, base_hartid, hart_count); } else { s->irqchip[i] = virt_create_aia(s->aia_type, s->aia_guests, - memmap, i, base_hartid, + s->memmap, i, base_hartid, hart_count); } @@ -1640,8 +1649,8 @@ static void virt_machine_init(MachineState *machine) if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) { kvm_riscv_aia_create(machine, IMSIC_MMIO_GROUP_MIN_SHIFT, VIRT_IRQCHIP_NUM_SOURCES, VIRT_IRQCHIP_NUM_MSIS, - memmap[VIRT_APLIC_S].base, - memmap[VIRT_IMSIC_S].base, + s->memmap[VIRT_APLIC_S].base, + s->memmap[VIRT_IMSIC_S].base, s->aia_guests); } @@ -1657,37 +1666,36 @@ static void virt_machine_init(MachineState *machine) virt_high_pcie_memmap.size = VIRT32_HIGH_PCIE_MMIO_SIZE; } else { virt_high_pcie_memmap.size = VIRT64_HIGH_PCIE_MMIO_SIZE; - virt_high_pcie_memmap.base = memmap[VIRT_DRAM].base + machine->ram_size; + virt_high_pcie_memmap.base = s->memmap[VIRT_DRAM].base + + machine->ram_size; virt_high_pcie_memmap.base = ROUND_UP(virt_high_pcie_memmap.base, virt_high_pcie_memmap.size); } - s->memmap = virt_memmap; - /* register system main memory (actual RAM) */ - memory_region_add_subregion(system_memory, memmap[VIRT_DRAM].base, - machine->ram); + memory_region_add_subregion(system_memory, s->memmap[VIRT_DRAM].base, + machine->ram); /* boot rom */ memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom", - memmap[VIRT_MROM].size, &error_fatal); - memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base, + s->memmap[VIRT_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, s->memmap[VIRT_MROM].base, mask_rom); /* * Init fw_cfg. Must be done before riscv_load_fdt, otherwise the * device tree cannot be altered and we get FDT_ERR_NOSPACE. */ - s->fw_cfg = create_fw_cfg(machine); + s->fw_cfg = create_fw_cfg(machine, s->memmap[VIRT_FW_CFG].base); rom_set_fw(s->fw_cfg); /* SiFive Test MMIO device */ - sifive_test_create(memmap[VIRT_TEST].base); + sifive_test_create(s->memmap[VIRT_TEST].base); /* VirtIO MMIO devices */ for (i = 0; i < VIRTIO_COUNT; i++) { sysbus_create_simple("virtio-mmio", - memmap[VIRT_VIRTIO].base + i * memmap[VIRT_VIRTIO].size, + s->memmap[VIRT_VIRTIO].base + i * s->memmap[VIRT_VIRTIO].size, qdev_get_gpio_in(virtio_irqchip, VIRTIO_IRQ + i)); } @@ -1695,11 +1703,11 @@ static void virt_machine_init(MachineState *machine) create_platform_bus(s, mmio_irqchip); - serial_mm_init(system_memory, memmap[VIRT_UART0].base, + serial_mm_init(system_memory, s->memmap[VIRT_UART0].base, 0, qdev_get_gpio_in(mmio_irqchip, UART0_IRQ), 399193, serial_hd(0), DEVICE_LITTLE_ENDIAN); - sysbus_create_simple("goldfish_rtc", memmap[VIRT_RTC].base, + sysbus_create_simple("goldfish_rtc", s->memmap[VIRT_RTC].base, qdev_get_gpio_in(mmio_irqchip, RTC_IRQ)); for (i = 0; i < ARRAY_SIZE(s->flash); i++) { @@ -1717,7 +1725,7 @@ static void virt_machine_init(MachineState *machine) exit(1); } } else { - create_fdt(s, memmap); + create_fdt(s); } if (virt_is_iommu_sys_enabled(s)) { @@ -1906,7 +1914,7 @@ static void virt_machine_device_plug_cb(HotplugHandler *hotplug_dev, } } -static void virt_machine_class_init(ObjectClass *oc, void *data) +static void virt_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -1980,7 +1988,7 @@ static const TypeInfo virt_machine_typeinfo = { .class_init = virt_machine_class_init, .instance_init = virt_machine_instance_init, .instance_size = sizeof(RISCVVirtState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, diff --git a/hw/rtc/allwinner-rtc.c b/hw/rtc/allwinner-rtc.c index fd8355a..a747bff 100644 --- a/hw/rtc/allwinner-rtc.c +++ b/hw/rtc/allwinner-rtc.c @@ -315,7 +315,7 @@ static const Property allwinner_rtc_properties[] = { DEFINE_PROP_INT32("base-year", AwRtcState, base_year, 0), }; -static void allwinner_rtc_class_init(ObjectClass *klass, void *data) +static void allwinner_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -330,7 +330,7 @@ static void allwinner_rtc_sun4i_init(Object *obj) s->base_year = 2010; } -static void allwinner_rtc_sun4i_class_init(ObjectClass *klass, void *data) +static void allwinner_rtc_sun4i_class_init(ObjectClass *klass, const void *data) { AwRtcClass *arc = AW_RTC_CLASS(klass); @@ -346,7 +346,7 @@ static void allwinner_rtc_sun6i_init(Object *obj) s->base_year = 1970; } -static void allwinner_rtc_sun6i_class_init(ObjectClass *klass, void *data) +static void allwinner_rtc_sun6i_class_init(ObjectClass *klass, const void *data) { AwRtcClass *arc = AW_RTC_CLASS(klass); @@ -362,7 +362,7 @@ static void allwinner_rtc_sun7i_init(Object *obj) s->base_year = 1970; } -static void allwinner_rtc_sun7i_class_init(ObjectClass *klass, void *data) +static void allwinner_rtc_sun7i_class_init(ObjectClass *klass, const void *data) { AwRtcClass *arc = AW_RTC_CLASS(klass); allwinner_rtc_sun4i_class_init(klass, arc); diff --git a/hw/rtc/aspeed_rtc.c b/hw/rtc/aspeed_rtc.c index fbdeb07..c4feea2 100644 --- a/hw/rtc/aspeed_rtc.c +++ b/hw/rtc/aspeed_rtc.c @@ -156,7 +156,7 @@ static void aspeed_rtc_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } -static void aspeed_rtc_class_init(ObjectClass *klass, void *data) +static void aspeed_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/rtc/ds1338.c b/hw/rtc/ds1338.c index 8dd17fd..5f1ee2e 100644 --- a/hw/rtc/ds1338.c +++ b/hw/rtc/ds1338.c @@ -220,7 +220,7 @@ static void ds1338_reset(DeviceState *dev) s->addr_byte = false; } -static void ds1338_class_init(ObjectClass *klass, void *data) +static void ds1338_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/rtc/exynos4210_rtc.c b/hw/rtc/exynos4210_rtc.c index aa1b3cd..624b4f6 100644 --- a/hw/rtc/exynos4210_rtc.c +++ b/hw/rtc/exynos4210_rtc.c @@ -592,7 +592,7 @@ static void exynos4210_rtc_finalize(Object *obj) ptimer_free(s->ptimer_1Hz); } -static void exynos4210_rtc_class_init(ObjectClass *klass, void *data) +static void exynos4210_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/rtc/goldfish_rtc.c b/hw/rtc/goldfish_rtc.c index d83cc26..78df031 100644 --- a/hw/rtc/goldfish_rtc.c +++ b/hw/rtc/goldfish_rtc.c @@ -273,7 +273,7 @@ static const Property goldfish_rtc_properties[] = { false), }; -static void goldfish_rtc_class_init(ObjectClass *klass, void *data) +static void goldfish_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/rtc/ls7a_rtc.c b/hw/rtc/ls7a_rtc.c index fce23a3..10097b2 100644 --- a/hw/rtc/ls7a_rtc.c +++ b/hw/rtc/ls7a_rtc.c @@ -464,7 +464,7 @@ static const VMStateDescription vmstate_ls7a_rtc = { } }; -static void ls7a_rtc_class_init(ObjectClass *klass, void *data) +static void ls7a_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->vmsd = &vmstate_ls7a_rtc; diff --git a/hw/rtc/m41t80.c b/hw/rtc/m41t80.c index 9600695..c631ec3 100644 --- a/hw/rtc/m41t80.c +++ b/hw/rtc/m41t80.c @@ -94,7 +94,7 @@ static int m41t80_event(I2CSlave *i2c, enum i2c_event event) return 0; } -static void m41t80_class_init(ObjectClass *klass, void *data) +static void m41t80_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *sc = I2C_SLAVE_CLASS(klass); diff --git a/hw/rtc/m48t59-isa.c b/hw/rtc/m48t59-isa.c index 9c3855a..9e2f656 100644 --- a/hw/rtc/m48t59-isa.c +++ b/hw/rtc/m48t59-isa.c @@ -113,7 +113,7 @@ static void m48t59_isa_realize(DeviceState *dev, Error **errp) } } -static void m48txx_isa_class_init(ObjectClass *klass, void *data) +static void m48txx_isa_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); NvramClass *nc = NVRAM_CLASS(klass); @@ -126,7 +126,7 @@ static void m48txx_isa_class_init(ObjectClass *klass, void *data) nc->toggle_lock = m48txx_isa_toggle_lock; } -static void m48txx_isa_concrete_class_init(ObjectClass *klass, void *data) +static void m48txx_isa_concrete_class_init(ObjectClass *klass, const void *data) { M48txxISADeviceClass *u = M48TXX_ISA_CLASS(klass); const M48txxInfo *info = data; @@ -140,7 +140,7 @@ static const TypeInfo m48txx_isa_type_info = { .instance_size = sizeof(M48txxISAState), .abstract = true, .class_init = m48txx_isa_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NVRAM }, { } } diff --git a/hw/rtc/m48t59.c b/hw/rtc/m48t59.c index 3fb2f27..68be2da 100644 --- a/hw/rtc/m48t59.c +++ b/hw/rtc/m48t59.c @@ -622,7 +622,7 @@ static const Property m48t59_sysbus_properties[] = { DEFINE_PROP_INT32("base-year", M48txxSysBusState, state.base_year, 0), }; -static void m48txx_sysbus_class_init(ObjectClass *klass, void *data) +static void m48txx_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); NvramClass *nc = NVRAM_CLASS(klass); @@ -636,7 +636,8 @@ static void m48txx_sysbus_class_init(ObjectClass *klass, void *data) nc->toggle_lock = m48txx_sysbus_toggle_lock; } -static void m48txx_sysbus_concrete_class_init(ObjectClass *klass, void *data) +static void m48txx_sysbus_concrete_class_init(ObjectClass *klass, + const void *data) { M48txxSysBusDeviceClass *u = M48TXX_SYS_BUS_CLASS(klass); const M48txxInfo *info = data; @@ -657,7 +658,7 @@ static const TypeInfo m48txx_sysbus_type_info = { .instance_init = m48t59_init1, .abstract = true, .class_init = m48txx_sysbus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NVRAM }, { } } diff --git a/hw/rtc/mc146818rtc.c b/hw/rtc/mc146818rtc.c index e322fc2..f9f5cf3 100644 --- a/hw/rtc/mc146818rtc.c +++ b/hw/rtc/mc146818rtc.c @@ -819,7 +819,7 @@ static const VMStateDescription vmstate_rtc_irq_reinject_on_ack_count = { static const VMStateDescription vmstate_rtc = { .name = "mc146818rtc", .version_id = 3, - .minimum_version_id = 1, + .minimum_version_id = 3, .pre_save = rtc_pre_save, .post_load = rtc_post_load, .fields = (const VMStateField[]) { @@ -829,13 +829,13 @@ static const VMStateDescription vmstate_rtc = { VMSTATE_TIMER_PTR(periodic_timer, MC146818RtcState), VMSTATE_INT64(next_periodic_time, MC146818RtcState), VMSTATE_UNUSED(3*8), - VMSTATE_UINT32_V(irq_coalesced, MC146818RtcState, 2), - VMSTATE_UINT32_V(period, MC146818RtcState, 2), - VMSTATE_UINT64_V(base_rtc, MC146818RtcState, 3), - VMSTATE_UINT64_V(last_update, MC146818RtcState, 3), - VMSTATE_INT64_V(offset, MC146818RtcState, 3), - VMSTATE_TIMER_PTR_V(update_timer, MC146818RtcState, 3), - VMSTATE_UINT64_V(next_alarm_time, MC146818RtcState, 3), + VMSTATE_UINT32(irq_coalesced, MC146818RtcState), + VMSTATE_UINT32(period, MC146818RtcState), + VMSTATE_UINT64(base_rtc, MC146818RtcState), + VMSTATE_UINT64(last_update, MC146818RtcState), + VMSTATE_INT64(offset, MC146818RtcState), + VMSTATE_TIMER_PTR(update_timer, MC146818RtcState), + VMSTATE_UINT64(next_alarm_time, MC146818RtcState), VMSTATE_END_OF_LIST() }, .subsections = (const VMStateDescription * const []) { @@ -929,8 +929,6 @@ static void rtc_realizefn(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->io, 0, &s->coalesced_io); memory_region_add_coalescing(&s->coalesced_io, 0, 1); - qdev_set_legacy_instance_id(dev, s->io_base, 3); - object_property_add_tm(OBJECT(s), "date", rtc_get_date); qdev_init_gpio_out(dev, &s->irq, 1); @@ -1018,7 +1016,7 @@ static void rtc_build_aml(AcpiDevAmlIf *adev, Aml *scope) aml_append(scope, dev); } -static void rtc_class_initfn(ObjectClass *klass, void *data) +static void rtc_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -1038,7 +1036,7 @@ static const TypeInfo mc146818rtc_info = { .parent = TYPE_ISA_DEVICE, .instance_size = sizeof(MC146818RtcState), .class_init = rtc_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_ACPI_DEV_AML_IF }, { }, }, diff --git a/hw/rtc/pl031.c b/hw/rtc/pl031.c index ed439bd..e545b9d 100644 --- a/hw/rtc/pl031.c +++ b/hw/rtc/pl031.c @@ -332,7 +332,7 @@ static const Property pl031_properties[] = { PL031State, migrate_tick_offset, true), }; -static void pl031_class_init(ObjectClass *klass, void *data) +static void pl031_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/rtc/rs5c372.c b/hw/rtc/rs5c372.c index 5542f74..bb92453 100644 --- a/hw/rtc/rs5c372.c +++ b/hw/rtc/rs5c372.c @@ -210,7 +210,7 @@ static void rs5c372_init(Object *obj) qdev_prop_set_uint8(DEVICE(obj), "address", 0x32); } -static void rs5c372_class_init(ObjectClass *klass, void *data) +static void rs5c372_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/rtc/sun4v-rtc.c b/hw/rtc/sun4v-rtc.c index ffcc0aa..29e24ef 100644 --- a/hw/rtc/sun4v-rtc.c +++ b/hw/rtc/sun4v-rtc.c @@ -75,7 +75,7 @@ static void sun4v_rtc_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &s->iomem); } -static void sun4v_rtc_class_init(ObjectClass *klass, void *data) +static void sun4v_rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/rtc/xlnx-zynqmp-rtc.c b/hw/rtc/xlnx-zynqmp-rtc.c index b596b60..500982a 100644 --- a/hw/rtc/xlnx-zynqmp-rtc.c +++ b/hw/rtc/xlnx-zynqmp-rtc.c @@ -251,7 +251,7 @@ static const VMStateDescription vmstate_rtc = { } }; -static void rtc_class_init(ObjectClass *klass, void *data) +static void rtc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/rx/rx-gdbsim.c b/hw/rx/rx-gdbsim.c index 4afd77e..5b9004e 100644 --- a/hw/rx/rx-gdbsim.c +++ b/hw/rx/rx-gdbsim.c @@ -155,7 +155,7 @@ static void rx_gdbsim_init(MachineState *machine) } } -static void rx_gdbsim_class_init(ObjectClass *oc, void *data) +static void rx_gdbsim_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -165,7 +165,7 @@ static void rx_gdbsim_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "ext-sdram"; } -static void rx62n7_class_init(ObjectClass *oc, void *data) +static void rx62n7_class_init(ObjectClass *oc, const void *data) { RxGdbSimMachineClass *rxc = RX_GDBSIM_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); @@ -175,7 +175,7 @@ static void rx62n7_class_init(ObjectClass *oc, void *data) mc->desc = "gdb simulator (R5F562N7 MCU and external RAM)"; }; -static void rx62n8_class_init(ObjectClass *oc, void *data) +static void rx62n8_class_init(ObjectClass *oc, const void *data) { RxGdbSimMachineClass *rxc = RX_GDBSIM_MACHINE_CLASS(oc); MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/rx/rx62n.c b/hw/rx/rx62n.c index e6bac4f..a2a243a 100644 --- a/hw/rx/rx62n.c +++ b/hw/rx/rx62n.c @@ -264,7 +264,7 @@ static const Property rx62n_properties[] = { DEFINE_PROP_UINT32("xtal-frequency-hz", RX62NState, xtal_freq_hz, 0), }; -static void rx62n_class_init(ObjectClass *klass, void *data) +static void rx62n_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -272,7 +272,7 @@ static void rx62n_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, rx62n_properties); } -static void r5f562n7_class_init(ObjectClass *oc, void *data) +static void r5f562n7_class_init(ObjectClass *oc, const void *data) { RX62NClass *rxc = RX62N_MCU_CLASS(oc); @@ -281,7 +281,7 @@ static void r5f562n7_class_init(ObjectClass *oc, void *data) rxc->data_flash_size = 32 * KiB; }; -static void r5f562n8_class_init(ObjectClass *oc, void *data) +static void r5f562n8_class_init(ObjectClass *oc, const void *data) { RX62NClass *rxc = RX62N_MCU_CLASS(oc); diff --git a/hw/s390x/3270-ccw.c b/hw/s390x/3270-ccw.c index 3a8930d..3f0d384 100644 --- a/hw/s390x/3270-ccw.c +++ b/hw/s390x/3270-ccw.c @@ -150,7 +150,7 @@ out_err: g_free(sch); } -static void emulated_ccw_3270_class_init(ObjectClass *klass, void *data) +static void emulated_ccw_3270_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/s390x/ap-bridge.c b/hw/s390x/ap-bridge.c index ef8fa2b..edeb3db 100644 --- a/hw/s390x/ap-bridge.c +++ b/hw/s390x/ap-bridge.c @@ -22,7 +22,7 @@ static char *ap_bus_get_dev_path(DeviceState *dev) return g_strdup_printf("/1"); } -static void ap_bus_class_init(ObjectClass *oc, void *data) +static void ap_bus_class_init(ObjectClass *oc, const void *data) { BusClass *k = BUS_CLASS(oc); @@ -61,7 +61,7 @@ void s390_init_ap(void) qbus_set_hotplug_handler(bus, OBJECT(dev)); } -static void ap_bridge_class_init(ObjectClass *oc, void *data) +static void ap_bridge_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc); @@ -75,7 +75,7 @@ static const TypeInfo ap_bridge_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = 0, .class_init = ap_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/s390x/ap-device.c b/hw/s390x/ap-device.c index 237d1f1..7331044 100644 --- a/hw/s390x/ap-device.c +++ b/hw/s390x/ap-device.c @@ -12,7 +12,7 @@ #include "qapi/error.h" #include "hw/s390x/ap-device.h" -static void ap_class_init(ObjectClass *klass, void *data) +static void ap_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/s390x/ap-stub.c b/hw/s390x/ap-stub.c new file mode 100644 index 0000000..001fe5f --- /dev/null +++ b/hw/s390x/ap-stub.c @@ -0,0 +1,21 @@ +/* + * VFIO based AP matrix device assignment + * + * Copyright 2025 IBM Corp. + * Author(s): Rorie Reyes <rreyes@linux.ibm.com> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "hw/s390x/ap-bridge.h" + +int ap_chsc_sei_nt0_get_event(void *res) +{ + return EVENT_INFORMATION_NOT_STORED; +} + +bool ap_chsc_sei_nt0_have_event(void) +{ + return false; +} diff --git a/hw/s390x/ccw-device.c b/hw/s390x/ccw-device.c index 1ea9934..8be1813 100644 --- a/hw/s390x/ccw-device.c +++ b/hw/s390x/ccw-device.c @@ -57,7 +57,7 @@ static void ccw_device_set_loadparm(Object *obj, Visitor *v, Error **errp) { CcwDevice *dev = CCW_DEVICE(obj); - char *val; + g_autofree char *val = NULL; int index; index = object_property_get_int(obj, "bootindex", NULL); @@ -94,7 +94,7 @@ static void ccw_device_reset_hold(Object *obj, ResetType type) css_reset_sch(ccw_dev->sch); } -static void ccw_device_class_init(ObjectClass *klass, void *data) +static void ccw_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); CCWDeviceClass *k = CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/cpu-topology.c b/hw/s390x/cpu-topology.c index 7d4e1f5..b513f89 100644 --- a/hw/s390x/cpu-topology.c +++ b/hw/s390x/cpu-topology.c @@ -23,8 +23,8 @@ #include "target/s390x/cpu.h" #include "hw/s390x/s390-virtio-ccw.h" #include "hw/s390x/cpu-topology.h" -#include "qapi/qapi-commands-machine-target.h" -#include "qapi/qapi-events-machine-target.h" +#include "qapi/qapi-commands-machine-s390x.h" +#include "qapi/qapi-events-machine-s390x.h" /* * s390_topology is used to keep the topology information. diff --git a/hw/s390x/css-bridge.c b/hw/s390x/css-bridge.c index c48d557..0f87b8c 100644 --- a/hw/s390x/css-bridge.c +++ b/hw/s390x/css-bridge.c @@ -70,7 +70,7 @@ static char *virtual_css_bus_get_dev_path(DeviceState *dev) return g_strdup_printf("/%02x.%1x.%04x", sch->cssid, sch->ssid, sch->devno); } -static void virtual_css_bus_class_init(ObjectClass *klass, void *data) +static void virtual_css_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -117,7 +117,7 @@ static bool prop_get_true(Object *obj, Error **errp) return true; } -static void virtual_css_bridge_class_init(ObjectClass *klass, void *data) +static void virtual_css_bridge_class_init(ObjectClass *klass, const void *data) { HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -136,7 +136,7 @@ static const TypeInfo virtual_css_bridge_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(VirtualCssBridge), .class_init = virtual_css_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 17afcbb..53444f6 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -14,7 +14,7 @@ #include "qapi/visitor.h" #include "qemu/bitops.h" #include "qemu/error-report.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/s390x/ioinst.h" #include "hw/qdev-properties.h" #include "hw/s390x/css.h" diff --git a/hw/s390x/event-facility.c b/hw/s390x/event-facility.c index 2b0332c..fee286e 100644 --- a/hw/s390x/event-facility.c +++ b/hw/s390x/event-facility.c @@ -4,6 +4,7 @@ * handles SCLP event types * - Signal Quiesce - system power down * - ASCII Console Data - VT220 read and write + * - Control-Program Identification - Send OS data from guest to host * * Copyright IBM, Corp. 2012 * @@ -40,18 +41,12 @@ struct SCLPEventFacility { SysBusDevice parent_obj; SCLPEventsBus sbus; SCLPEvent quiesce, cpu_hotplug; + SCLPEventCPI cpi; /* guest's receive mask */ union { uint32_t receive_mask_pieces[2]; sccb_mask_t receive_mask; }; - /* - * when false, we keep the same broken, backwards compatible behaviour as - * before, allowing only masks of size exactly 4; when true, we implement - * the architecture correctly, allowing all valid mask sizes. Needed for - * migration toward older versions. - */ - bool allow_all_mask_sizes; /* length of the receive mask */ uint16_t mask_length; }; @@ -294,8 +289,7 @@ static void write_event_mask(SCLPEventFacility *ef, SCCB *sccb) uint16_t mask_length = be16_to_cpu(we_mask->mask_length); sccb_mask_t tmp_mask; - if (!mask_length || (mask_length > SCLP_EVENT_MASK_LEN_MAX) || - ((mask_length != 4) && !ef->allow_all_mask_sizes)) { + if (!mask_length || mask_length > SCLP_EVENT_MASK_LEN_MAX) { sccb->h.response_code = cpu_to_be16(SCLP_RC_INVALID_MASK_LENGTH); return; } @@ -355,13 +349,6 @@ static bool vmstate_event_facility_mask64_needed(void *opaque) return (ef->receive_mask & 0xFFFFFFFF) != 0; } -static bool vmstate_event_facility_mask_length_needed(void *opaque) -{ - SCLPEventFacility *ef = opaque; - - return ef->allow_all_mask_sizes; -} - static const VMStateDescription vmstate_event_facility_mask64 = { .name = "vmstate-event-facility/mask64", .version_id = 0, @@ -377,7 +364,6 @@ static const VMStateDescription vmstate_event_facility_mask_length = { .name = "vmstate-event-facility/mask_length", .version_id = 0, .minimum_version_id = 0, - .needed = vmstate_event_facility_mask_length_needed, .fields = (const VMStateField[]) { VMSTATE_UINT16(mask_length, SCLPEventFacility), VMSTATE_END_OF_LIST() @@ -399,31 +385,12 @@ static const VMStateDescription vmstate_event_facility = { } }; -static void sclp_event_set_allow_all_mask_sizes(Object *obj, bool value, - Error **errp) -{ - SCLPEventFacility *ef = (SCLPEventFacility *)obj; - - ef->allow_all_mask_sizes = value; -} - -static bool sclp_event_get_allow_all_mask_sizes(Object *obj, Error **errp) -{ - SCLPEventFacility *ef = (SCLPEventFacility *)obj; - - return ef->allow_all_mask_sizes; -} - static void init_event_facility(Object *obj) { SCLPEventFacility *event_facility = EVENT_FACILITY(obj); DeviceState *sdev = DEVICE(obj); event_facility->mask_length = 4; - event_facility->allow_all_mask_sizes = true; - object_property_add_bool(obj, "allow_all_mask_sizes", - sclp_event_get_allow_all_mask_sizes, - sclp_event_set_allow_all_mask_sizes); /* Spawn a new bus for SCLP events */ qbus_init(&event_facility->sbus, sizeof(event_facility->sbus), @@ -460,7 +427,7 @@ static void reset_event_facility(DeviceState *dev) sdev->receive_mask = 0; } -static void init_event_facility_class(ObjectClass *klass, void *data) +static void init_event_facility_class(ObjectClass *klass, const void *data) { SysBusDeviceClass *sbdc = SYS_BUS_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(sbdc); @@ -497,7 +464,7 @@ static void event_realize(DeviceState *qdev, Error **errp) } } -static void event_class_init(ObjectClass *klass, void *data) +static void event_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c index ce6f607..2f08239 100644 --- a/hw/s390x/ipl.c +++ b/hw/s390x/ipl.c @@ -26,7 +26,6 @@ #include "hw/s390x/vfio-ccw.h" #include "hw/s390x/css.h" #include "hw/s390x/ebcdic.h" -#include "target/s390x/kvm/pv.h" #include "hw/scsi/scsi.h" #include "hw/virtio/virtio-net.h" #include "ipl.h" @@ -676,7 +675,7 @@ static void s390_ipl_prepare_qipl(S390CPU *cpu) cpu_physical_memory_unmap(addr, len, 1, len); } -int s390_ipl_prepare_pv_header(Error **errp) +int s390_ipl_prepare_pv_header(struct S390PVResponse *pv_resp, Error **errp) { IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); IPLBlockPV *ipib_pv = &ipib->pv; @@ -685,12 +684,13 @@ int s390_ipl_prepare_pv_header(Error **errp) cpu_physical_memory_read(ipib_pv->pv_header_addr, hdr, ipib_pv->pv_header_len); - rc = s390_pv_set_sec_parms((uintptr_t)hdr, ipib_pv->pv_header_len, errp); + rc = s390_pv_set_sec_parms((uintptr_t)hdr, ipib_pv->pv_header_len, + pv_resp, errp); g_free(hdr); return rc; } -int s390_ipl_pv_unpack(void) +int s390_ipl_pv_unpack(struct S390PVResponse *pv_resp) { IplParameterBlock *ipib = s390_ipl_get_iplb_pv(); IPLBlockPV *ipib_pv = &ipib->pv; @@ -699,7 +699,8 @@ int s390_ipl_pv_unpack(void) for (i = 0; i < ipib_pv->num_comp; i++) { rc = s390_pv_unpack(ipib_pv->components[i].addr, TARGET_PAGE_ALIGN(ipib_pv->components[i].size), - ipib_pv->components[i].tweak_pref); + ipib_pv->components[i].tweak_pref, + pv_resp); if (rc) { break; } @@ -736,7 +737,7 @@ static void s390_ipl_reset(DeviceState *dev) } } -static void s390_ipl_class_init(ObjectClass *klass, void *data) +static void s390_ipl_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h index 8e3882d..505cded 100644 --- a/hw/s390x/ipl.h +++ b/hw/s390x/ipl.h @@ -14,10 +14,13 @@ #define HW_S390_IPL_H #include "cpu.h" -#include "exec/address-spaces.h" +#include "exec/target_page.h" +#include "system/address-spaces.h" +#include "system/memory.h" #include "hw/qdev-core.h" #include "hw/s390x/ipl/qipl.h" #include "qom/object.h" +#include "target/s390x/kvm/pv.h" #define DIAG308_FLAGS_LP_VALID 0x80 #define MAX_BOOT_DEVS 8 /* Max number of devices that may have a bootindex */ @@ -26,8 +29,9 @@ void s390_ipl_convert_loadparm(char *ascii_lp, uint8_t *ebcdic_lp); void s390_ipl_fmt_loadparm(uint8_t *loadparm, char *str, Error **errp); void s390_rebuild_iplb(uint16_t index, IplParameterBlock *iplb); void s390_ipl_update_diag308(IplParameterBlock *iplb); -int s390_ipl_prepare_pv_header(Error **errp); -int s390_ipl_pv_unpack(void); +int s390_ipl_prepare_pv_header(struct S390PVResponse *pv_resp, + Error **errp); +int s390_ipl_pv_unpack(struct S390PVResponse *pv_resp); void s390_ipl_prepare_cpu(S390CPU *cpu); IplParameterBlock *s390_ipl_get_iplb(void); IplParameterBlock *s390_ipl_get_iplb_pv(void); diff --git a/hw/s390x/meson.build b/hw/s390x/meson.build index 3bbebfd..1bc8583 100644 --- a/hw/s390x/meson.build +++ b/hw/s390x/meson.build @@ -13,6 +13,7 @@ s390x_ss.add(files( 's390-skeys.c', 's390-stattrib.c', 'sclp.c', + 'sclpcpi.c', 'sclpcpu.c', 'sclpquiesce.c', 'tod.c', @@ -33,6 +34,7 @@ s390x_ss.add(when: 'CONFIG_S390_CCW_VIRTIO', if_true: files( )) s390x_ss.add(when: 'CONFIG_TERMINAL3270', if_true: files('3270-ccw.c')) s390x_ss.add(when: 'CONFIG_VFIO', if_true: files('s390-pci-vfio.c')) +s390x_ss.add(when: 'CONFIG_VFIO_AP', if_false: files('ap-stub.c')) virtio_ss = ss.source_set() virtio_ss.add(files('virtio-ccw.c')) diff --git a/hw/s390x/s390-ccw.c b/hw/s390x/s390-ccw.c index 909475f..10c81a4 100644 --- a/hw/s390x/s390-ccw.c +++ b/hw/s390x/s390-ccw.c @@ -175,7 +175,7 @@ static void s390_ccw_instance_init(Object *obj) "/disk@0,0", DEVICE(obj)); } -static void s390_ccw_class_init(ObjectClass *klass, void *data) +static void s390_ccw_class_init(ObjectClass *klass, const void *data) { S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index d96819f..e6aa445 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -14,6 +14,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" #include "qapi/visitor.h" +#include "exec/target_page.h" #include "hw/s390x/s390-pci-bus.h" #include "hw/s390x/s390-pci-inst.h" #include "hw/s390x/s390-pci-kvm.h" @@ -1372,7 +1373,7 @@ static void s390_pcihost_reset(DeviceState *dev) pci_for_each_device_under_bus(bus, s390_pci_enumerate_bridge, s); } -static void s390_pcihost_class_init(ObjectClass *klass, void *data) +static void s390_pcihost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); @@ -1392,7 +1393,7 @@ static const TypeInfo s390_pcihost_info = { .parent = TYPE_PCI_HOST_BRIDGE, .instance_size = sizeof(S390pciState), .class_init = s390_pcihost_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } @@ -1556,7 +1557,7 @@ static const VMStateDescription s390_pci_device_vmstate = { .unmigratable = 1, }; -static void s390_pci_device_class_init(ObjectClass *klass, void *data) +static void s390_pci_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1582,7 +1583,8 @@ static const TypeInfo s390_pci_iommu_info = { .instance_size = sizeof(S390PCIIOMMU), }; -static void s390_iommu_memory_region_class_init(ObjectClass *klass, void *data) +static void s390_iommu_memory_region_class_init(ObjectClass *klass, + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 8cdeb6c..b5dddb2 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -13,7 +13,8 @@ #include "qemu/osdep.h" #include "exec/memop.h" -#include "exec/memory.h" +#include "exec/target_page.h" +#include "system/memory.h" #include "qemu/error-report.h" #include "system/hw_accel.h" #include "hw/boards.h" diff --git a/hw/s390x/s390-pci-vfio.c b/hw/s390x/s390-pci-vfio.c index db152a6..aaf9131 100644 --- a/hw/s390x/s390-pci-vfio.c +++ b/hw/s390x/s390-pci-vfio.c @@ -20,7 +20,8 @@ #include "hw/s390x/s390-pci-clp.h" #include "hw/s390x/s390-pci-vfio.h" #include "hw/vfio/pci.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-container.h" +#include "hw/vfio/vfio-helpers.h" /* * Get the current DMA available count from vfio. Returns true if vfio is diff --git a/hw/s390x/s390-skeys-kvm.c b/hw/s390x/s390-skeys-kvm.c index 0215e94..f3056d6 100644 --- a/hw/s390x/s390-skeys-kvm.c +++ b/hw/s390x/s390-skeys-kvm.c @@ -52,7 +52,7 @@ static int kvm_s390_skeys_set(S390SKeysState *ss, uint64_t start_gfn, return kvm_vm_ioctl(kvm_state, KVM_S390_SET_SKEYS, &args); } -static void kvm_s390_skeys_class_init(ObjectClass *oc, void *data) +static void kvm_s390_skeys_class_init(ObjectClass *oc, const void *data) { S390SKeysClass *skeyclass = S390_SKEYS_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c index 067ea03..8eeecfd 100644 --- a/hw/s390x/s390-skeys.c +++ b/hw/s390x/s390-skeys.c @@ -11,16 +11,16 @@ #include "qemu/osdep.h" #include "qemu/units.h" +#include "exec/target_page.h" #include "hw/s390x/s390-virtio-ccw.h" #include "hw/qdev-properties.h" #include "hw/s390x/storage-keys.h" #include "qapi/error.h" #include "qapi/qapi-commands-machine.h" -#include "qapi/qapi-commands-misc-target.h" #include "qobject/qdict.h" #include "qemu/error-report.h" #include "system/memory_mapping.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/kvm.h" #include "migration/qemu-file-types.h" #include "migration/register.h" @@ -303,7 +303,7 @@ static int qemu_s390_skeys_get(S390SKeysState *ss, uint64_t start_gfn, return 0; } -static void qemu_s390_skeys_class_init(ObjectClass *oc, void *data) +static void qemu_s390_skeys_class_init(ObjectClass *oc, const void *data) { S390SKeysClass *skeyclass = S390_SKEYS_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -465,7 +465,7 @@ static void s390_skeys_realize(DeviceState *dev, Error **errp) register_savevm_live(TYPE_S390_SKEYS, 0, 1, &savevm_s390_storage_keys, ss); } -static void s390_skeys_class_init(ObjectClass *oc, void *data) +static void s390_skeys_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/s390-stattrib-kvm.c b/hw/s390x/s390-stattrib-kvm.c index d0ff043..e1fee36 100644 --- a/hw/s390x/s390-stattrib-kvm.c +++ b/hw/s390x/s390-stattrib-kvm.c @@ -16,7 +16,7 @@ #include "qemu/error-report.h" #include "system/kvm.h" #include "system/memory_mapping.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "kvm/kvm_s390x.h" #include "qapi/error.h" @@ -188,7 +188,7 @@ static int kvm_s390_stattrib_get_active(S390StAttribState *sa) return kvm_s390_cmma_active(); } -static void kvm_s390_stattrib_class_init(ObjectClass *oc, void *data) +static void kvm_s390_stattrib_class_init(ObjectClass *oc, const void *data) { S390StAttribClass *sac = S390_STATTRIB_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/s390-stattrib.c b/hw/s390x/s390-stattrib.c index 35bf697..f74cf32 100644 --- a/hw/s390x/s390-stattrib.c +++ b/hw/s390x/s390-stattrib.c @@ -16,7 +16,7 @@ #include "hw/qdev-properties.h" #include "hw/s390x/storage-attributes.h" #include "qemu/error-report.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "qapi/error.h" #include "qobject/qdict.h" #include "cpu.h" @@ -307,7 +307,7 @@ static int qemu_s390_get_active(S390StAttribState *sa) return true; } -static void qemu_s390_stattrib_class_init(ObjectClass *oc, void *data) +static void qemu_s390_stattrib_class_init(ObjectClass *oc, const void *data) { S390StAttribClass *sa_cl = S390_STATTRIB_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -360,7 +360,7 @@ static void s390_stattrib_realize(DeviceState *dev, Error **errp) &savevm_s390_stattrib_handlers, dev); } -static void s390_stattrib_class_init(ObjectClass *oc, void *data) +static void s390_stattrib_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c index 5af3c4f..a79bd13 100644 --- a/hw/s390x/s390-virtio-ccw.c +++ b/hw/s390x/s390-virtio-ccw.c @@ -13,7 +13,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "system/confidential-guest-support.h" #include "hw/boards.h" #include "hw/s390x/sclp.h" @@ -35,7 +35,7 @@ #include "hw/s390x/css-bridge.h" #include "hw/s390x/ap-bridge.h" #include "migration/register.h" -#include "cpu_models.h" +#include "target/s390x/cpu_models.h" #include "hw/nmi.h" #include "hw/qdev-properties.h" #include "hw/s390x/tod.h" @@ -260,9 +260,21 @@ static void s390_create_sclpconsole(SCLPDevice *sclp, qdev_realize_and_unref(dev, ev_fac_bus, &error_fatal); } +static void s390_create_sclpcpi(SCLPDevice *sclp) +{ + SCLPEventFacility *ef = sclp->event_facility; + BusState *ev_fac_bus = sclp_get_event_facility_bus(ef); + DeviceState *dev; + + dev = qdev_new(TYPE_SCLP_EVENT_CPI); + object_property_add_child(OBJECT(ef), "sclpcpi", OBJECT(dev)); + qdev_realize_and_unref(dev, ev_fac_bus, &error_fatal); +} + static void ccw_init(MachineState *machine) { MachineClass *mc = MACHINE_GET_CLASS(machine); + S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); S390CcwMachineState *ms = S390_CCW_MACHINE(machine); int ret; VirtualCssBus *css_bus; @@ -323,6 +335,12 @@ static void ccw_init(MachineState *machine) /* init the TOD clock */ s390_init_tod(); + + /* init SCLP event Control-Program Identification */ + if (s390mc->use_cpi) { + s390_create_sclpcpi(ms->sclp); + } + } static void s390_cpu_plug(HotplugHandler *hotplug_dev, @@ -365,7 +383,8 @@ static void s390_machine_unprotect(S390CcwMachineState *ms) ram_block_discard_disable(false); } -static int s390_machine_protect(S390CcwMachineState *ms) +static int s390_machine_protect(S390CcwMachineState *ms, + struct S390PVResponse *pv_resp) { Error *local_err = NULL; int rc; @@ -408,19 +427,19 @@ static int s390_machine_protect(S390CcwMachineState *ms) } /* Set SE header and unpack */ - rc = s390_ipl_prepare_pv_header(&local_err); + rc = s390_ipl_prepare_pv_header(pv_resp, &local_err); if (rc) { goto out_err; } /* Decrypt image */ - rc = s390_ipl_pv_unpack(); + rc = s390_ipl_pv_unpack(pv_resp); if (rc) { goto out_err; } /* Verify integrity */ - rc = s390_pv_verify(); + rc = s390_pv_verify(pv_resp); if (rc) { goto out_err; } @@ -452,6 +471,7 @@ static void s390_pv_prepare_reset(S390CcwMachineState *ms) static void s390_machine_reset(MachineState *machine, ResetType type) { S390CcwMachineState *ms = S390_CCW_MACHINE(machine); + struct S390PVResponse pv_resp; enum s390_reset reset_type; CPUState *cs, *t; S390CPU *cpu; @@ -540,8 +560,8 @@ static void s390_machine_reset(MachineState *machine, ResetType type) } run_on_cpu(cs, s390_do_cpu_reset, RUN_ON_CPU_NULL); - if (s390_machine_protect(ms)) { - s390_pv_inject_reset_error(cs); + if (s390_machine_protect(ms, &pv_resp)) { + s390_pv_inject_reset_error(cs, pv_resp); /* * Continue after the diag308 so the guest knows something * went wrong. @@ -746,39 +766,6 @@ static inline void machine_set_dea_key_wrap(Object *obj, bool value, ms->dea_key_wrap = value; } -static S390CcwMachineClass *current_mc; - -/* - * Get the class of the s390-ccw-virtio machine that is currently in use. - * Note: libvirt is using the "none" machine to probe for the features of the - * host CPU, so in case this is called with the "none" machine, the function - * returns the TYPE_S390_CCW_MACHINE base class. In this base class, all the - * various "*_allowed" variables are enabled, so that the *_allowed() wrappers - * below return the correct default value for the "none" machine. - * - * Attention! Do *not* add additional new wrappers for CPU features via this - * mechanism anymore. CPU features should be handled via the CPU models, - * i.e. checking with s390_has_feat() should be sufficient. - */ -static S390CcwMachineClass *get_machine_class(void) -{ - if (unlikely(!current_mc)) { - /* - * No s390 ccw machine was instantiated, we are likely to - * be called for the 'none' machine. The properties will - * have their after-initialization values. - */ - current_mc = S390_CCW_MACHINE_CLASS( - object_class_by_name(TYPE_S390_CCW_MACHINE)); - } - return current_mc; -} - -bool hpage_1m_allowed(void) -{ - return get_machine_class()->hpage_1m_allowed; -} - static void machine_get_loadparm(Object *obj, Visitor *v, const char *name, void *opaque, Error **errp) @@ -802,9 +789,10 @@ static void machine_set_loadparm(Object *obj, Visitor *v, } s390_ipl_fmt_loadparm(ms->loadparm, val, errp); + g_free(val); } -static void ccw_machine_class_init(ObjectClass *oc, void *data) +static void ccw_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); NMIClass *nc = NMI_CLASS(oc); @@ -812,8 +800,8 @@ static void ccw_machine_class_init(ObjectClass *oc, void *data) S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); DumpSKeysInterface *dsi = DUMP_SKEYS_INTERFACE_CLASS(oc); - s390mc->hpage_1m_allowed = true; s390mc->max_threads = 1; + s390mc->use_cpi = true; mc->reset = s390_machine_reset; mc->block_default_type = IF_VIRTIO; mc->no_cdrom = 1; @@ -875,7 +863,7 @@ static const TypeInfo ccw_machine_info = { .instance_init = s390_machine_initfn, .class_size = sizeof(S390CcwMachineClass), .class_init = ccw_machine_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_NMI }, { TYPE_HOTPLUG_HANDLER}, { TYPE_DUMP_SKEYS_INTERFACE}, @@ -886,13 +874,12 @@ static const TypeInfo ccw_machine_info = { #define DEFINE_CCW_MACHINE_IMPL(latest, ...) \ static void MACHINE_VER_SYM(mach_init, ccw, __VA_ARGS__)(MachineState *mach) \ { \ - current_mc = S390_CCW_MACHINE_CLASS(MACHINE_GET_CLASS(mach)); \ MACHINE_VER_SYM(instance_options, ccw, __VA_ARGS__)(mach); \ ccw_init(mach); \ } \ static void MACHINE_VER_SYM(class_init, ccw, __VA_ARGS__)( \ ObjectClass *oc, \ - void *data) \ + const void *data) \ { \ MachineClass *mc = MACHINE_CLASS(oc); \ MACHINE_VER_SYM(class_options, ccw, __VA_ARGS__)(mc); \ @@ -940,6 +927,9 @@ static void ccw_machine_10_0_instance_options(MachineState *machine) static void ccw_machine_10_0_class_options(MachineClass *mc) { + S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); + s390mc->use_cpi = false; + ccw_machine_10_1_class_options(mc); compat_props_add(mc->compat_props, hw_compat_10_0, hw_compat_10_0_len); } @@ -1177,116 +1167,6 @@ static void ccw_machine_4_2_class_options(MachineClass *mc) } DEFINE_CCW_MACHINE(4, 2); -static void ccw_machine_4_1_instance_options(MachineState *machine) -{ - static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_1 }; - ccw_machine_4_2_instance_options(machine); - s390_set_qemu_cpu_model(0x2964, 13, 2, qemu_cpu_feat); -} - -static void ccw_machine_4_1_class_options(MachineClass *mc) -{ - ccw_machine_4_2_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_4_1, hw_compat_4_1_len); -} -DEFINE_CCW_MACHINE(4, 1); - -static void ccw_machine_4_0_instance_options(MachineState *machine) -{ - static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V4_0 }; - ccw_machine_4_1_instance_options(machine); - s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat); -} - -static void ccw_machine_4_0_class_options(MachineClass *mc) -{ - ccw_machine_4_1_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_4_0, hw_compat_4_0_len); -} -DEFINE_CCW_MACHINE(4, 0); - -static void ccw_machine_3_1_instance_options(MachineState *machine) -{ - static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V3_1 }; - ccw_machine_4_0_instance_options(machine); - s390_cpudef_featoff_greater(14, 1, S390_FEAT_MULTIPLE_EPOCH); - s390_cpudef_group_featoff_greater(14, 1, S390_FEAT_GROUP_MULTIPLE_EPOCH_PTFF); - s390_set_qemu_cpu_model(0x2827, 12, 2, qemu_cpu_feat); -} - -static void ccw_machine_3_1_class_options(MachineClass *mc) -{ - ccw_machine_4_0_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_3_1, hw_compat_3_1_len); -} -DEFINE_CCW_MACHINE(3, 1); - -static void ccw_machine_3_0_instance_options(MachineState *machine) -{ - ccw_machine_3_1_instance_options(machine); -} - -static void ccw_machine_3_0_class_options(MachineClass *mc) -{ - S390CcwMachineClass *s390mc = S390_CCW_MACHINE_CLASS(mc); - - s390mc->hpage_1m_allowed = false; - ccw_machine_3_1_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_3_0, hw_compat_3_0_len); -} -DEFINE_CCW_MACHINE(3, 0); - -static void ccw_machine_2_12_instance_options(MachineState *machine) -{ - ccw_machine_3_0_instance_options(machine); - s390_cpudef_featoff_greater(11, 1, S390_FEAT_PPA15); - s390_cpudef_featoff_greater(11, 1, S390_FEAT_BPB); -} - -static void ccw_machine_2_12_class_options(MachineClass *mc) -{ - ccw_machine_3_0_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_12, hw_compat_2_12_len); -} -DEFINE_CCW_MACHINE(2, 12); - -#ifdef CONFIG_S390X_LEGACY_CPUS - -static void ccw_machine_2_11_instance_options(MachineState *machine) -{ - static const S390FeatInit qemu_cpu_feat = { S390_FEAT_LIST_QEMU_V2_11 }; - ccw_machine_2_12_instance_options(machine); - - /* before 2.12 we emulated the very first z900 */ - s390_set_qemu_cpu_model(0x2064, 7, 1, qemu_cpu_feat); -} - -static void ccw_machine_2_11_class_options(MachineClass *mc) -{ - static GlobalProperty compat[] = { - { TYPE_SCLP_EVENT_FACILITY, "allow_all_mask_sizes", "off", }, - }; - - ccw_machine_2_12_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_11, hw_compat_2_11_len); - compat_props_add(mc->compat_props, compat, G_N_ELEMENTS(compat)); -} -DEFINE_CCW_MACHINE(2, 11); - -static void ccw_machine_2_10_instance_options(MachineState *machine) -{ - ccw_machine_2_11_instance_options(machine); -} - -static void ccw_machine_2_10_class_options(MachineClass *mc) -{ - ccw_machine_2_11_class_options(mc); - compat_props_add(mc->compat_props, hw_compat_2_10, hw_compat_2_10_len); -} -DEFINE_CCW_MACHINE(2, 10); - -#endif - static void ccw_machine_register_types(void) { type_register_static(&ccw_machine_info); diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c index 5945c9b..9718564 100644 --- a/hw/s390x/sclp.c +++ b/hw/s390x/sclp.c @@ -424,7 +424,7 @@ static void sclp_init(Object *obj) sclp_memory_init(sclp); } -static void sclp_class_init(ObjectClass *oc, void *data) +static void sclp_class_init(ObjectClass *oc, const void *data) { SCLPDeviceClass *sc = SCLP_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/sclpcpi.c b/hw/s390x/sclpcpi.c new file mode 100644 index 0000000..7aa039d --- /dev/null +++ b/hw/s390x/sclpcpi.c @@ -0,0 +1,212 @@ + /* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * SCLP event type 11 - Control-Program Identification (CPI): + * CPI is used to send program identifiers from the guest to the + * Service-Call Logical Processor (SCLP). It is not sent by the SCLP. + * + * Control-program identifiers provide data about the guest operating + * system. The control-program identifiers are: system type, system name, + * system level and sysplex name. + * + * In Linux, all the control-program identifiers are user configurable. The + * system type, system name, and sysplex name use EBCDIC characters from + * this set: capital A-Z, 0-9, $, @, #, and blank. In Linux, the system + * type, system name and sysplex name are arbitrary free-form texts. + * + * In Linux, the 8-byte hexadecimal system-level has the format + * 0x<a><b><cc><dd><eeee><ff><gg><hh>, where: + * <a>: is a 4-bit digit, its most significant bit indicates hypervisor use + * <b>: is one digit that represents Linux distributions as follows + * 0: generic Linux + * 1: Red Hat Enterprise Linux + * 2: SUSE Linux Enterprise Server + * 3: Canonical Ubuntu + * 4: Fedora + * 5: openSUSE Leap + * 6: Debian GNU/Linux + * 7: Red Hat Enterprise Linux CoreOS + * <cc>: are two digits for a distribution-specific encoding of the major + * version of the distribution + * <dd>: are two digits for a distribution-specific encoding of the minor + * version of the distribution + * <eeee>: are four digits for the patch level of the distribution + * <ff>: are two digits for the major version of the kernel + * <gg>: are two digits for the minor version of the kernel + * <hh>: are two digits for the stable version of the kernel + * (e.g. 74872343805430528, when converted to hex is 0x010a000000060b00). On + * machines prior to z16, some of the values are not available to display. + * + * Sysplex refers to a cluster of logical partitions that communicates and + * co-operates with each other. + * + * The CPI feature is supported since 10.1. + * + * Copyright IBM, Corp. 2024 + * + * Authors: + * Shalini Chellathurai Saroja <shalini@linux.ibm.com> + * + */ + +#include "qemu/osdep.h" +#include "qemu/timer.h" +#include "hw/s390x/event-facility.h" +#include "hw/s390x/ebcdic.h" +#include "qapi/qapi-visit-machine.h" +#include "migration/vmstate.h" + +typedef struct Data { + uint8_t id_format; + uint8_t reserved0; + uint8_t system_type[8]; + uint64_t reserved1; + uint8_t system_name[8]; + uint64_t reserved2; + uint64_t system_level; + uint64_t reserved3; + uint8_t sysplex_name[8]; + uint8_t reserved4[16]; +} QEMU_PACKED Data; + +typedef struct ControlProgramIdMsg { + EventBufferHeader ebh; + Data data; +} QEMU_PACKED ControlProgramIdMsg; + +static bool can_handle_event(uint8_t type) +{ + return type == SCLP_EVENT_CTRL_PGM_ID; +} + +static sccb_mask_t send_mask(void) +{ + return 0; +} + +/* Enable SCLP to accept buffers of event type CPI from the control-program. */ +static sccb_mask_t receive_mask(void) +{ + return SCLP_EVENT_MASK_CTRL_PGM_ID; +} + +static int write_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr) +{ + ControlProgramIdMsg *cpim = container_of(evt_buf_hdr, ControlProgramIdMsg, + ebh); + SCLPEventCPI *e = SCLP_EVENT_CPI(event); + + ascii_put(e->system_type, (char *)cpim->data.system_type, + sizeof(cpim->data.system_type)); + ascii_put(e->system_name, (char *)cpim->data.system_name, + sizeof(cpim->data.system_name)); + ascii_put(e->sysplex_name, (char *)cpim->data.sysplex_name, + sizeof(cpim->data.sysplex_name)); + e->system_level = ldq_be_p(&cpim->data.system_level); + e->timestamp = qemu_clock_get_ns(QEMU_CLOCK_HOST); + + cpim->ebh.flags = SCLP_EVENT_BUFFER_ACCEPTED; + return SCLP_RC_NORMAL_COMPLETION; +} + +static char *get_system_type(Object *obj, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + return g_strndup((char *) e->system_type, sizeof(e->system_type)); +} + +static char *get_system_name(Object *obj, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + return g_strndup((char *) e->system_name, sizeof(e->system_name)); +} + +static char *get_sysplex_name(Object *obj, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + return g_strndup((char *) e->sysplex_name, sizeof(e->sysplex_name)); +} + +static void get_system_level(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + visit_type_uint64(v, name, &e->system_level, errp); +} + +static void get_timestamp(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + SCLPEventCPI *e = SCLP_EVENT_CPI(obj); + + visit_type_uint64(v, name, &e->timestamp, errp); +} + +static const VMStateDescription vmstate_sclpcpi = { + .name = "s390_control_program_id", + .version_id = 0, + .fields = (const VMStateField[]) { + VMSTATE_UINT8_ARRAY(system_type, SCLPEventCPI, 8), + VMSTATE_UINT8_ARRAY(system_name, SCLPEventCPI, 8), + VMSTATE_UINT64(system_level, SCLPEventCPI), + VMSTATE_UINT8_ARRAY(sysplex_name, SCLPEventCPI, 8), + VMSTATE_UINT64(timestamp, SCLPEventCPI), + VMSTATE_END_OF_LIST() + } +}; + +static void cpi_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + SCLPEventClass *k = SCLP_EVENT_CLASS(klass); + + dc->user_creatable = false; + dc->vmsd = &vmstate_sclpcpi; + + k->can_handle_event = can_handle_event; + k->get_send_mask = send_mask; + k->get_receive_mask = receive_mask; + k->write_event_data = write_event_data; + + object_class_property_add_str(klass, "system_type", get_system_type, NULL); + object_class_property_set_description(klass, "system_type", + "operating system e.g. \"LINUX \""); + + object_class_property_add_str(klass, "system_name", get_system_name, NULL); + object_class_property_set_description(klass, "system_name", + "user configurable name of the VM e.g. \"TESTVM \""); + + object_class_property_add_str(klass, "sysplex_name", get_sysplex_name, + NULL); + object_class_property_set_description(klass, "sysplex_name", + "name of the cluster which the VM belongs to, if any" + " e.g. \"PLEX \""); + + object_class_property_add(klass, "system_level", "uint64", get_system_level, + NULL, NULL, NULL); + object_class_property_set_description(klass, "system_level", + "distribution and kernel version in Linux e.g. 74872343805430528"); + + object_class_property_add(klass, "timestamp", "uint64", get_timestamp, + NULL, NULL, NULL); + object_class_property_set_description(klass, "timestamp", + "latest update of CPI data in nanoseconds since the UNIX EPOCH"); +} + +static const TypeInfo sclp_cpi_info = { + .name = TYPE_SCLP_EVENT_CPI, + .parent = TYPE_SCLP_EVENT, + .instance_size = sizeof(SCLPEventCPI), + .class_init = cpi_class_init, +}; + +static void sclp_cpi_register_types(void) +{ + type_register_static(&sclp_cpi_info); +} + +type_init(sclp_cpi_register_types) diff --git a/hw/s390x/sclpcpu.c b/hw/s390x/sclpcpu.c index a178a9d..4b6ebfe 100644 --- a/hw/s390x/sclpcpu.c +++ b/hw/s390x/sclpcpu.c @@ -73,7 +73,7 @@ static int read_event_data(SCLPEvent *event, EventBufferHeader *evt_buf_hdr, return 1; } -static void sclp_cpu_class_init(ObjectClass *oc, void *data) +static void sclp_cpu_class_init(ObjectClass *oc, const void *data) { SCLPEventClass *k = SCLP_EVENT_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c index 7bb5aad..da4c8f3 100644 --- a/hw/s390x/sclpquiesce.c +++ b/hw/s390x/sclpquiesce.c @@ -112,7 +112,7 @@ static void quiesce_reset(DeviceState *dev) event->event_pending = false; } -static void quiesce_class_init(ObjectClass *klass, void *data) +static void quiesce_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCLPEventClass *k = SCLP_EVENT_CLASS(klass); diff --git a/hw/s390x/tod-kvm.c b/hw/s390x/tod-kvm.c index 5da9037..c9b8896 100644 --- a/hw/s390x/tod-kvm.c +++ b/hw/s390x/tod-kvm.c @@ -133,7 +133,7 @@ static void kvm_s390_tod_realize(DeviceState *dev, Error **errp) qemu_add_vm_change_state_handler(kvm_s390_tod_vm_state_change, td); } -static void kvm_s390_tod_class_init(ObjectClass *oc, void *data) +static void kvm_s390_tod_class_init(ObjectClass *oc, const void *data) { S390TODClass *tdc = S390_TOD_CLASS(oc); diff --git a/hw/s390x/tod-tcg.c b/hw/s390x/tod-tcg.c index 3b3ef88..0cc9662 100644 --- a/hw/s390x/tod-tcg.c +++ b/hw/s390x/tod-tcg.c @@ -52,7 +52,7 @@ static void qemu_s390_tod_set(S390TODState *td, const S390TOD *tod, } } -static void qemu_s390_tod_class_init(ObjectClass *oc, void *data) +static void qemu_s390_tod_class_init(ObjectClass *oc, const void *data) { S390TODClass *tdc = S390_TOD_CLASS(oc); diff --git a/hw/s390x/tod.c b/hw/s390x/tod.c index 6afbb23..3f913cc 100644 --- a/hw/s390x/tod.c +++ b/hw/s390x/tod.c @@ -111,7 +111,7 @@ static void s390_tod_realize(DeviceState *dev, Error **errp) register_savevm_live("todclock", 0, 1, &savevm_tod, td); } -static void s390_tod_class_init(ObjectClass *oc, void *data) +static void s390_tod_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/s390x/vhost-scsi-ccw.c b/hw/s390x/vhost-scsi-ccw.c index e6bf0c5..8341b23 100644 --- a/hw/s390x/vhost-scsi-ccw.c +++ b/hw/s390x/vhost-scsi-ccw.c @@ -46,7 +46,7 @@ static const Property vhost_ccw_scsi_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void vhost_ccw_scsi_class_init(ObjectClass *klass, void *data) +static void vhost_ccw_scsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/vhost-user-fs-ccw.c b/hw/s390x/vhost-user-fs-ccw.c index 6a9654d..cc1b822 100644 --- a/hw/s390x/vhost-user-fs-ccw.c +++ b/hw/s390x/vhost-user-fs-ccw.c @@ -48,7 +48,7 @@ static void vhost_user_fs_ccw_instance_init(Object *obj) TYPE_VHOST_USER_FS); } -static void vhost_user_fs_ccw_class_init(ObjectClass *klass, void *data) +static void vhost_user_fs_ccw_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/vhost-vsock-ccw.c b/hw/s390x/vhost-vsock-ccw.c index 875ccf3..552e9e8 100644 --- a/hw/s390x/vhost-vsock-ccw.c +++ b/hw/s390x/vhost-vsock-ccw.c @@ -35,7 +35,7 @@ static void vhost_vsock_ccw_realize(VirtioCcwDevice *ccw_dev, Error **errp) qdev_realize(vdev, BUS(&ccw_dev->bus), errp); } -static void vhost_vsock_ccw_class_init(ObjectClass *klass, void *data) +static void vhost_vsock_ccw_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-9p.c b/hw/s390x/virtio-ccw-9p.c index 287ae2b..72bf6ec 100644 --- a/hw/s390x/virtio-ccw-9p.c +++ b/hw/s390x/virtio-ccw-9p.c @@ -48,7 +48,7 @@ static const Property virtio_ccw_9p_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_9p_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_9p_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-balloon.c b/hw/s390x/virtio-ccw-balloon.c index 1180efa..399b40f 100644 --- a/hw/s390x/virtio-ccw-balloon.c +++ b/hw/s390x/virtio-ccw-balloon.c @@ -53,7 +53,7 @@ static const Property virtio_ccw_balloon_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_balloon_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_balloon_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-blk.c b/hw/s390x/virtio-ccw-blk.c index db9d442..7d8c4a75 100644 --- a/hw/s390x/virtio-ccw-blk.c +++ b/hw/s390x/virtio-ccw-blk.c @@ -51,7 +51,7 @@ static const Property virtio_ccw_blk_properties[] = { DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), }; -static void virtio_ccw_blk_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_blk_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-crypto.c b/hw/s390x/virtio-ccw-crypto.c index b693f87..75e7146 100644 --- a/hw/s390x/virtio-ccw-crypto.c +++ b/hw/s390x/virtio-ccw-crypto.c @@ -51,7 +51,7 @@ static const Property virtio_ccw_crypto_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_crypto_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_crypto_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-gpu.c b/hw/s390x/virtio-ccw-gpu.c index a6b14c2..edb6a47 100644 --- a/hw/s390x/virtio-ccw-gpu.c +++ b/hw/s390x/virtio-ccw-gpu.c @@ -49,7 +49,7 @@ static const Property virtio_ccw_gpu_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_gpu_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_gpu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-input.c b/hw/s390x/virtio-ccw-input.c index 6ca10d5..2250d8c 100644 --- a/hw/s390x/virtio-ccw-input.c +++ b/hw/s390x/virtio-ccw-input.c @@ -50,7 +50,7 @@ static const Property virtio_ccw_input_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_input_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_input_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-md.c b/hw/s390x/virtio-ccw-md.c index de33328..0370f58 100644 --- a/hw/s390x/virtio-ccw-md.c +++ b/hw/s390x/virtio-ccw-md.c @@ -140,7 +140,7 @@ static const TypeInfo virtio_ccw_md_info = { .instance_size = sizeof(VirtIOMDCcw), .class_size = sizeof(VirtIOMDCcwClass), .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_MEMORY_DEVICE }, { } }, diff --git a/hw/s390x/virtio-ccw-mem.c b/hw/s390x/virtio-ccw-mem.c index 90fd89f..daa485d 100644 --- a/hw/s390x/virtio-ccw-mem.c +++ b/hw/s390x/virtio-ccw-mem.c @@ -160,7 +160,7 @@ static const Property virtio_ccw_mem_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_mem_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_mem_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-net.c b/hw/s390x/virtio-ccw-net.c index 80a5581..a7d4afb 100644 --- a/hw/s390x/virtio-ccw-net.c +++ b/hw/s390x/virtio-ccw-net.c @@ -54,7 +54,7 @@ static const Property virtio_ccw_net_properties[] = { DEFINE_PROP_CCW_LOADPARM("loadparm", CcwDevice, loadparm), }; -static void virtio_ccw_net_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_net_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-rng.c b/hw/s390x/virtio-ccw-rng.c index ccd124e..3263287 100644 --- a/hw/s390x/virtio-ccw-rng.c +++ b/hw/s390x/virtio-ccw-rng.c @@ -50,7 +50,7 @@ static const Property virtio_ccw_rng_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_rng_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_rng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-scsi.c b/hw/s390x/virtio-ccw-scsi.c index bfcea3c..06b4c6c 100644 --- a/hw/s390x/virtio-ccw-scsi.c +++ b/hw/s390x/virtio-ccw-scsi.c @@ -60,7 +60,7 @@ static const Property virtio_ccw_scsi_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_scsi_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_scsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw-serial.c b/hw/s390x/virtio-ccw-serial.c index 59743d1..0dac590 100644 --- a/hw/s390x/virtio-ccw-serial.c +++ b/hw/s390x/virtio-ccw-serial.c @@ -60,7 +60,7 @@ static const Property virtio_ccw_serial_properties[] = { VIRTIO_CCW_MAX_REV), }; -static void virtio_ccw_serial_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_serial_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_CLASS(klass); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index 43f3b16..d2f85b3 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -12,7 +12,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "system/kvm.h" #include "net/net.h" #include "hw/virtio/virtio.h" @@ -1228,7 +1228,7 @@ static void virtio_ccw_busdev_unplug(HotplugHandler *hotplug_dev, virtio_ccw_stop_ioeventfd(_dev); } -static void virtio_ccw_device_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); CCWDeviceClass *k = CCW_DEVICE_CLASS(dc); @@ -1262,7 +1262,7 @@ static void virtio_ccw_bus_new(VirtioBusState *bus, size_t bus_size, qbus_init(bus, bus_size, TYPE_VIRTIO_CCW_BUS, qdev, virtio_bus_name); } -static void virtio_ccw_bus_class_init(ObjectClass *klass, void *data) +static void virtio_ccw_bus_class_init(ObjectClass *klass, const void *data) { VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); BusClass *bus_class = BUS_CLASS(klass); diff --git a/hw/scsi/esp-pci.c b/hw/scsi/esp-pci.c index fe4e045..12c86eb 100644 --- a/hw/scsi/esp-pci.c +++ b/hw/scsi/esp-pci.c @@ -427,7 +427,7 @@ static void esp_pci_init(Object *obj) object_initialize_child(obj, "esp", &pci->esp, TYPE_ESP); } -static void esp_pci_class_init(ObjectClass *klass, void *data) +static void esp_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -450,7 +450,7 @@ static const TypeInfo esp_pci_info = { .instance_init = esp_pci_init, .instance_size = sizeof(PCIESPState), .class_init = esp_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -557,7 +557,7 @@ static void dc390_scsi_realize(PCIDevice *dev, Error **errp) contents[EE_CHKSUM2] = chksum >> 8; } -static void dc390_class_init(ObjectClass *klass, void *data) +static void dc390_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 01bdfe2..f24991f 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -1568,7 +1568,7 @@ static const VMStateDescription vmstate_sysbus_esp_scsi = { } }; -static void sysbus_esp_class_init(ObjectClass *klass, void *data) +static void sysbus_esp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1594,7 +1594,7 @@ static void esp_init(Object *obj) fifo8_create(&s->cmdfifo, ESP_CMDFIFO_SZ); } -static void esp_class_init(ObjectClass *klass, void *data) +static void esp_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index 6689ebb..9ea4aa0 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -1112,7 +1112,7 @@ bad: static void lsi_memcpy(LSIState *s, uint32_t dest, uint32_t src, int count) { int n; - uint8_t buf[LSI_BUF_SIZE]; + QEMU_UNINITIALIZED uint8_t buf[LSI_BUF_SIZE]; trace_lsi_memcpy(dest, src, count); while (count) { @@ -2375,7 +2375,7 @@ static void lsi_scsi_exit(PCIDevice *dev) timer_free(s->scripts_timer); } -static void lsi_class_init(ObjectClass *klass, void *data) +static void lsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -2396,13 +2396,13 @@ static const TypeInfo lsi_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(LSIState), .class_init = lsi_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void lsi53c810_class_init(ObjectClass *klass, void *data) +static void lsi53c810_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index d56bfc7..844643d 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -981,13 +981,11 @@ static int megasas_event_wait(MegasasState *s, MegasasCmd *cmd) static int megasas_dcmd_pd_get_list(MegasasState *s, MegasasCmd *cmd) { - struct mfi_pd_list info; - size_t dcmd_size = sizeof(info); + struct mfi_pd_list info = {}; BusChild *kid; uint32_t offset, dcmd_limit, num_pd_disks = 0, max_pd_disks; dma_addr_t residual; - memset(&info, 0, dcmd_size); offset = 8; dcmd_limit = offset + sizeof(struct mfi_pd_address); if (cmd->iov_size < dcmd_limit) { @@ -1429,11 +1427,10 @@ static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd) static int megasas_dcmd_get_properties(MegasasState *s, MegasasCmd *cmd) { - struct mfi_ctrl_props info; + struct mfi_ctrl_props info = {}; size_t dcmd_size = sizeof(info); dma_addr_t residual; - memset(&info, 0x0, dcmd_size); if (cmd->iov_size < dcmd_size) { trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size, dcmd_size); @@ -2486,7 +2483,7 @@ typedef struct MegasasInfo { const VMStateDescription *vmsd; const Property *props; size_t props_count; - InterfaceInfo *interfaces; + const InterfaceInfo *interfaces; } MegasasInfo; static struct MegasasInfo megasas_devices[] = { @@ -2503,7 +2500,7 @@ static struct MegasasInfo megasas_devices[] = { .vmsd = &vmstate_megasas_gen1, .props = megasas_properties_gen1, .props_count = ARRAY_SIZE(megasas_properties_gen1), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -2520,14 +2517,14 @@ static struct MegasasInfo megasas_devices[] = { .vmsd = &vmstate_megasas_gen2, .props = megasas_properties_gen2, .props_count = ARRAY_SIZE(megasas_properties_gen2), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { } }, } }; -static void megasas_class_init(ObjectClass *oc, void *data) +static void megasas_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); @@ -2572,7 +2569,7 @@ static void megasas_register_types(void) type_info.name = info->name; type_info.parent = TYPE_MEGASAS_BASE; - type_info.class_data = (void *)info; + type_info.class_data = info; type_info.class_init = megasas_class_init; type_info.interfaces = info->interfaces; diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c index ba7a7d0..1ebe0b8 100644 --- a/hw/scsi/mptsas.c +++ b/hw/scsi/mptsas.c @@ -1416,7 +1416,7 @@ static const Property mptsas_properties[] = { DEFINE_PROP_ON_OFF_AUTO("msi", MPTSASState, msi, ON_OFF_AUTO_AUTO), }; -static void mptsas1068_class_init(ObjectClass *oc, void *data) +static void mptsas1068_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); @@ -1441,7 +1441,7 @@ static const TypeInfo mptsas_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(MPTSASState), .class_init = mptsas1068_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index ece1107..9b12ee7 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -400,7 +400,7 @@ static void scsi_qdev_realize(DeviceState *qdev, Error **errp) return; } dev->vmsentry = qdev_add_vm_change_state_handler(DEVICE(dev), - scsi_dma_restart_cb, dev); + scsi_dma_restart_cb, NULL, dev); } static void scsi_qdev_unrealize(DeviceState *qdev) @@ -2001,7 +2001,7 @@ static const Property scsi_props[] = { DEFINE_PROP_UINT32("lun", SCSIDevice, lun, -1), }; -static void scsi_device_class_init(ObjectClass *klass, void *data) +static void scsi_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); set_bit(DEVICE_CATEGORY_STORAGE, k->categories); @@ -2030,7 +2030,7 @@ static const TypeInfo scsi_device_type_info = { .instance_init = scsi_dev_instance_init, }; -static void scsi_bus_class_init(ObjectClass *klass, void *data) +static void scsi_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); @@ -2046,7 +2046,7 @@ static const TypeInfo scsi_bus_info = { .parent = TYPE_BUS, .instance_size = sizeof(SCSIBus), .class_init = scsi_bus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index e59632e..b4782c6 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -74,7 +74,7 @@ struct SCSIDiskClass { */ DMAIOFunc *dma_readv; DMAIOFunc *dma_writev; - bool (*need_fua_emulation)(SCSICommand *cmd); + bool (*need_fua)(SCSICommand *cmd); void (*update_sense)(SCSIRequest *r); }; @@ -85,7 +85,7 @@ typedef struct SCSIDiskReq { uint32_t sector_count; uint32_t buflen; bool started; - bool need_fua_emulation; + bool need_fua; struct iovec iov; QEMUIOVector qiov; BlockAcctCookie acct; @@ -389,24 +389,6 @@ static bool scsi_is_cmd_fua(SCSICommand *cmd) } } -static void scsi_write_do_fua(SCSIDiskReq *r) -{ - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - - assert(r->req.aiocb == NULL); - assert(!r->req.io_canceled); - - if (r->need_fua_emulation) { - block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, - BLOCK_ACCT_FLUSH); - r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete, r); - return; - } - - scsi_req_complete(&r->req, GOOD); - scsi_req_unref(&r->req); -} - static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret) { assert(r->req.aiocb == NULL); @@ -416,12 +398,7 @@ static void scsi_dma_complete_noio(SCSIDiskReq *r, int ret) r->sector += r->sector_count; r->sector_count = 0; - if (r->req.cmd.mode == SCSI_XFER_TO_DEV) { - scsi_write_do_fua(r); - return; - } else { - scsi_req_complete(&r->req, GOOD); - } + scsi_req_complete(&r->req, GOOD); done: scsi_req_unref(&r->req); @@ -564,7 +541,7 @@ static void scsi_read_data(SCSIRequest *req) first = !r->started; r->started = true; - if (first && r->need_fua_emulation) { + if (first && r->need_fua) { block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, BLOCK_ACCT_FLUSH); r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, scsi_do_read_cb, r); @@ -589,8 +566,7 @@ static void scsi_write_complete_noio(SCSIDiskReq *r, int ret) r->sector += n; r->sector_count -= n; if (r->sector_count == 0) { - scsi_write_do_fua(r); - return; + scsi_req_complete(&r->req, GOOD); } else { scsi_init_iovec(r, SCSI_DMA_BUF_SIZE); trace_scsi_disk_write_complete_noio(r->req.tag, r->qiov.size); @@ -623,6 +599,7 @@ static void scsi_write_data(SCSIRequest *req) SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s)); + BlockCompletionFunc *cb; /* No data transfer may already be in progress */ assert(r->req.aiocb == NULL); @@ -648,11 +625,10 @@ static void scsi_write_data(SCSIRequest *req) if (r->req.cmd.buf[0] == VERIFY_10 || r->req.cmd.buf[0] == VERIFY_12 || r->req.cmd.buf[0] == VERIFY_16) { - if (r->req.sg) { - scsi_dma_complete_noio(r, 0); - } else { - scsi_write_complete_noio(r, 0); - } + block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, + BLOCK_ACCT_FLUSH); + cb = r->req.sg ? scsi_dma_complete : scsi_write_complete; + r->req.aiocb = blk_aio_flush(s->qdev.conf.blk, cb, r); return; } @@ -2391,7 +2367,7 @@ static int32_t scsi_disk_dma_command(SCSIRequest *req, uint8_t *buf) scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE)); return 0; } - r->need_fua_emulation = sdc->need_fua_emulation(&r->req.cmd); + r->need_fua = sdc->need_fua(&r->req.cmd); if (r->sector_count == 0) { scsi_req_complete(&r->req, GOOD); } @@ -3137,7 +3113,8 @@ BlockAIOCB *scsi_dma_writev(int64_t offset, QEMUIOVector *iov, { SCSIDiskReq *r = opaque; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, 0, cb, cb_opaque); + int flags = r->need_fua ? BDRV_REQ_FUA : 0; + return blk_aio_pwritev(s->qdev.conf.blk, offset, iov, flags, cb, cb_opaque); } static char *scsi_property_get_loadparm(Object *obj, Error **errp) @@ -3177,7 +3154,7 @@ static void scsi_property_add_specifics(DeviceClass *dc) } } -static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data) +static void scsi_disk_base_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCSIDiskClass *sdc = SCSI_DISK_BASE_CLASS(klass); @@ -3186,7 +3163,7 @@ static void scsi_disk_base_class_initfn(ObjectClass *klass, void *data) device_class_set_legacy_reset(dc, scsi_disk_reset); sdc->dma_readv = scsi_dma_readv; sdc->dma_writev = scsi_dma_writev; - sdc->need_fua_emulation = scsi_is_cmd_fua; + sdc->need_fua = scsi_is_cmd_fua; } static const TypeInfo scsi_disk_base_info = { @@ -3215,7 +3192,7 @@ static const Property scsi_hd_properties[] = { DEFINE_PROP_BIT("removable", SCSIDiskState, features, SCSI_DISK_F_REMOVABLE, false), DEFINE_PROP_BIT("dpofua", SCSIDiskState, features, - SCSI_DISK_F_DPOFUA, false), + SCSI_DISK_F_DPOFUA, true), DEFINE_PROP_UINT64("wwn", SCSIDiskState, qdev.wwn, 0), DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, qdev.port_wwn, 0), DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0), @@ -3247,7 +3224,7 @@ static const VMStateDescription vmstate_scsi_disk_state = { } }; -static void scsi_hd_class_initfn(ObjectClass *klass, void *data) +static void scsi_hd_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); @@ -3289,7 +3266,7 @@ static const Property scsi_cd_properties[] = { SCSI_DISK_QUIRK_MODE_PAGE_TRUNCATED, 0), }; -static void scsi_cd_class_initfn(ObjectClass *klass, void *data) +static void scsi_cd_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); @@ -3326,7 +3303,7 @@ static const Property scsi_block_properties[] = { DEFAULT_IO_TIMEOUT), }; -static void scsi_block_class_initfn(ObjectClass *klass, void *data) +static void scsi_block_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); @@ -3338,7 +3315,7 @@ static void scsi_block_class_initfn(ObjectClass *klass, void *data) sdc->dma_readv = scsi_block_dma_readv; sdc->dma_writev = scsi_block_dma_writev; sdc->update_sense = scsi_block_update_sense; - sdc->need_fua_emulation = scsi_block_no_fua; + sdc->need_fua = scsi_block_no_fua; dc->desc = "SCSI block device passthrough"; device_class_set_props(dc, scsi_block_properties); dc->vmsd = &vmstate_scsi_disk_state; diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index 6566720..9e380a2 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -786,7 +786,7 @@ static int scsi_generic_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, return scsi_bus_parse_cdb(dev, cmd, buf, buf_len, hba_private); } -static void scsi_generic_class_initfn(ObjectClass *klass, void *data) +static void scsi_generic_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SCSIDeviceClass *sc = SCSI_DEVICE_CLASS(klass); diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index 6962194..20f70fb 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -1267,7 +1267,7 @@ static const VMStateDescription vmstate_spapr_vscsi = { }, }; -static void spapr_vscsi_class_init(ObjectClass *klass, void *data) +static void spapr_vscsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); diff --git a/hw/scsi/vhost-scsi-common.c b/hw/scsi/vhost-scsi-common.c index 4c86370..43525ba 100644 --- a/hw/scsi/vhost-scsi-common.c +++ b/hw/scsi/vhost-scsi-common.c @@ -101,24 +101,25 @@ err_host_notifiers: return ret; } -void vhost_scsi_common_stop(VHostSCSICommon *vsc) +int vhost_scsi_common_stop(VHostSCSICommon *vsc) { VirtIODevice *vdev = VIRTIO_DEVICE(vsc); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); int ret = 0; - vhost_dev_stop(&vsc->dev, vdev, true); + ret = vhost_dev_stop(&vsc->dev, vdev, true); if (k->set_guest_notifiers) { - ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); - if (ret < 0) { - error_report("vhost guest notifier cleanup failed: %d", ret); + int r = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); + if (r < 0) { + error_report("vhost guest notifier cleanup failed: %d", ret); + return r; } } - assert(ret >= 0); vhost_dev_disable_notifiers(&vsc->dev, vdev); + return ret; } uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features, diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c index 66e0c21..cdf405b 100644 --- a/hw/scsi/vhost-scsi.c +++ b/hw/scsi/vhost-scsi.c @@ -114,7 +114,7 @@ static void vhost_scsi_stop(VHostSCSI *s) vhost_scsi_common_stop(vsc); } -static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) +static int vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) { VHostSCSI *s = VHOST_SCSI(vdev); VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); @@ -125,7 +125,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) } if (vhost_dev_is_started(&vsc->dev) == start) { - return; + return 0; } if (start) { @@ -139,6 +139,7 @@ static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) } else { vhost_scsi_stop(s); } + return 0; } static void vhost_dummy_handle_output(VirtIODevice *vdev, VirtQueue *vq) @@ -358,12 +359,15 @@ static const Property vhost_scsi_properties[] = { DEFINE_PROP_BIT64("t10_pi", VHostSCSICommon, host_features, VIRTIO_SCSI_F_T10_PI, false), + DEFINE_PROP_BIT64("hotplug", VHostSCSICommon, host_features, + VIRTIO_SCSI_F_HOTPLUG, + false), DEFINE_PROP_BOOL("migratable", VHostSCSICommon, migratable, false), DEFINE_PROP_BOOL("worker_per_virtqueue", VirtIOSCSICommon, conf.worker_per_virtqueue, false), }; -static void vhost_scsi_class_init(ObjectClass *klass, void *data) +static void vhost_scsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -397,7 +401,7 @@ static const TypeInfo vhost_scsi_info = { .instance_size = sizeof(VHostSCSI), .class_init = vhost_scsi_class_init, .instance_init = vhost_scsi_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { } }, diff --git a/hw/scsi/vhost-user-scsi.c b/hw/scsi/vhost-user-scsi.c index adb41b9..25f2d89 100644 --- a/hw/scsi/vhost-user-scsi.c +++ b/hw/scsi/vhost-user-scsi.c @@ -52,19 +52,19 @@ static int vhost_user_scsi_start(VHostUserSCSI *s, Error **errp) return ret; } -static void vhost_user_scsi_stop(VHostUserSCSI *s) +static int vhost_user_scsi_stop(VHostUserSCSI *s) { VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); if (!s->started_vu) { - return; + return 0; } s->started_vu = false; - vhost_scsi_common_stop(vsc); + return vhost_scsi_common_stop(vsc); } -static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserSCSI *s = (VHostUserSCSI *)vdev; DeviceState *dev = DEVICE(vdev); @@ -75,11 +75,11 @@ static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) int ret; if (!s->connected) { - return; + return -1; } if (vhost_dev_is_started(&vsc->dev) == should_start) { - return; + return 0; } if (should_start) { @@ -91,8 +91,12 @@ static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) qemu_chr_fe_disconnect(&vs->conf.chardev); } } else { - vhost_user_scsi_stop(s); + ret = vhost_user_scsi_stop(s); + if (ret) { + return ret; + } } + return 0; } static void vhost_user_scsi_handle_output(VirtIODevice *vdev, VirtQueue *vq) @@ -386,7 +390,7 @@ static const VMStateDescription vmstate_vhost_scsi = { }, }; -static void vhost_user_scsi_class_init(ObjectClass *klass, void *data) +static void vhost_user_scsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -422,7 +426,7 @@ static const TypeInfo vhost_user_scsi_info = { .instance_size = sizeof(VHostUserSCSI), .class_init = vhost_user_scsi_class_init, .instance_init = vhost_user_scsi_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { } }, diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index f5a3aa2..34ae14f 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -1395,7 +1395,7 @@ static const VMStateDescription vmstate_virtio_scsi = { }, }; -static void virtio_scsi_common_class_init(ObjectClass *klass, void *data) +static void virtio_scsi_common_class_init(ObjectClass *klass, const void *data) { VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -1404,7 +1404,7 @@ static void virtio_scsi_common_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); } -static void virtio_scsi_class_init(ObjectClass *klass, void *data) +static void virtio_scsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -1438,7 +1438,7 @@ static const TypeInfo virtio_scsi_info = { .parent = TYPE_VIRTIO_SCSI_COMMON, .instance_size = sizeof(VirtIOSCSI), .class_init = virtio_scsi_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c index f07e377..7c98b1b 100644 --- a/hw/scsi/vmw_pvscsi.c +++ b/hw/scsi/vmw_pvscsi.c @@ -68,18 +68,7 @@ struct PVSCSIClass { OBJECT_DECLARE_TYPE(PVSCSIState, PVSCSIClass, PVSCSI) -/* Compatibility flags for migration */ -#define PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT 0 -#define PVSCSI_COMPAT_OLD_PCI_CONFIGURATION \ - (1 << PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT) -#define PVSCSI_COMPAT_DISABLE_PCIE_BIT 1 -#define PVSCSI_COMPAT_DISABLE_PCIE \ - (1 << PVSCSI_COMPAT_DISABLE_PCIE_BIT) - -#define PVSCSI_USE_OLD_PCI_CONFIGURATION(s) \ - ((s)->compat_flags & PVSCSI_COMPAT_OLD_PCI_CONFIGURATION) -#define PVSCSI_MSI_OFFSET(s) \ - (PVSCSI_USE_OLD_PCI_CONFIGURATION(s) ? 0x50 : 0x7c) +#define PVSCSI_MSI_OFFSET (0x7c) #define PVSCSI_EXP_EP_OFFSET (0x40) typedef struct PVSCSIRingInfo { @@ -129,8 +118,6 @@ struct PVSCSIState { uint8_t msi_used; /* For migration compatibility */ PVSCSIRingInfo rings; /* Data transfer rings manager */ uint32_t resetting; /* Reset in progress */ - - uint32_t compat_flags; }; typedef struct PVSCSIRequest { @@ -1110,7 +1097,7 @@ pvscsi_init_msi(PVSCSIState *s) int res; PCIDevice *d = PCI_DEVICE(s); - res = msi_init(d, PVSCSI_MSI_OFFSET(s), PVSCSI_MSIX_NUM_VECTORS, + res = msi_init(d, PVSCSI_MSI_OFFSET, PVSCSI_MSIX_NUM_VECTORS, PVSCSI_USE_64BIT, PVSCSI_PER_VECTOR_MASK, NULL); if (res < 0) { trace_pvscsi_init_msi_fail(res); @@ -1158,15 +1145,11 @@ pvscsi_realizefn(PCIDevice *pci_dev, Error **errp) trace_pvscsi_state("init"); /* PCI subsystem ID, subsystem vendor ID, revision */ - if (PVSCSI_USE_OLD_PCI_CONFIGURATION(s)) { - pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, 0x1000); - } else { - pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, - PCI_VENDOR_ID_VMWARE); - pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, - PCI_DEVICE_ID_VMWARE_PVSCSI); - pci_config_set_revision(pci_dev->config, 0x2); - } + pci_set_word(pci_dev->config + PCI_SUBSYSTEM_VENDOR_ID, + PCI_VENDOR_ID_VMWARE); + pci_set_word(pci_dev->config + PCI_SUBSYSTEM_ID, + PCI_DEVICE_ID_VMWARE_PVSCSI); + pci_config_set_revision(pci_dev->config, 0x2); /* PCI latency timer = 255 */ pci_dev->config[PCI_LATENCY_TIMER] = 0xff; @@ -1234,21 +1217,8 @@ pvscsi_post_load(void *opaque, int version_id) return 0; } -static bool pvscsi_vmstate_need_pcie_device(void *opaque) -{ - PVSCSIState *s = PVSCSI(opaque); - - return !(s->compat_flags & PVSCSI_COMPAT_DISABLE_PCIE); -} - -static bool pvscsi_vmstate_test_pci_device(void *opaque, int version_id) -{ - return !pvscsi_vmstate_need_pcie_device(opaque); -} - static const VMStateDescription vmstate_pvscsi_pcie_device = { .name = "pvscsi/pcie", - .needed = pvscsi_vmstate_need_pcie_device, .fields = (const VMStateField[]) { VMSTATE_PCI_DEVICE(parent_obj, PVSCSIState), VMSTATE_END_OF_LIST() @@ -1262,9 +1232,6 @@ static const VMStateDescription vmstate_pvscsi = { .pre_save = pvscsi_pre_save, .post_load = pvscsi_post_load, .fields = (const VMStateField[]) { - VMSTATE_STRUCT_TEST(parent_obj, PVSCSIState, - pvscsi_vmstate_test_pci_device, 0, - vmstate_pci_device, PCIDevice), VMSTATE_UINT8(msi_used, PVSCSIState), VMSTATE_UINT32(resetting, PVSCSIState), VMSTATE_UINT64(reg_interrupt_status, PVSCSIState), @@ -1298,30 +1265,17 @@ static const VMStateDescription vmstate_pvscsi = { static const Property pvscsi_properties[] = { DEFINE_PROP_UINT8("use_msg", PVSCSIState, use_msg, 1), - DEFINE_PROP_BIT("x-old-pci-configuration", PVSCSIState, compat_flags, - PVSCSI_COMPAT_OLD_PCI_CONFIGURATION_BIT, false), - DEFINE_PROP_BIT("x-disable-pcie", PVSCSIState, compat_flags, - PVSCSI_COMPAT_DISABLE_PCIE_BIT, false), }; -static void pvscsi_realize(DeviceState *qdev, Error **errp) +static void pvscsi_instance_init(Object *obj) { - PVSCSIClass *pvs_c = PVSCSI_GET_CLASS(qdev); - PCIDevice *pci_dev = PCI_DEVICE(qdev); - PVSCSIState *s = PVSCSI(qdev); - - if (!(s->compat_flags & PVSCSI_COMPAT_DISABLE_PCIE)) { - pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; - } - - pvs_c->parent_dc_realize(qdev, errp); + PCI_DEVICE(obj)->cap_present |= QEMU_PCI_CAP_EXPRESS; } -static void pvscsi_class_init(ObjectClass *klass, void *data) +static void pvscsi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - PVSCSIClass *pvs_k = PVSCSI_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); k->realize = pvscsi_realizefn; @@ -1330,8 +1284,6 @@ static void pvscsi_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VMWARE_PVSCSI; k->class_id = PCI_CLASS_STORAGE_SCSI; k->subsystem_id = 0x1000; - device_class_set_parent_realize(dc, pvscsi_realize, - &pvs_k->parent_dc_realize); device_class_set_legacy_reset(dc, pvscsi_reset); dc->vmsd = &vmstate_pvscsi; device_class_set_props(dc, pvscsi_properties); @@ -1346,7 +1298,8 @@ static const TypeInfo pvscsi_info = { .class_size = sizeof(PVSCSIClass), .instance_size = sizeof(PVSCSIState), .class_init = pvscsi_class_init, - .interfaces = (InterfaceInfo[]) { + .instance_init = pvscsi_instance_init, + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { INTERFACE_PCIE_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, diff --git a/hw/scsi/vmw_pvscsi.h b/hw/scsi/vmw_pvscsi.h index 17fcf66..a3ae517 100644 --- a/hw/scsi/vmw_pvscsi.h +++ b/hw/scsi/vmw_pvscsi.h @@ -14,8 +14,8 @@ * details. * * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * along with this program; if not, see + * <https://www.gnu.org/licenses/>. * * Maintained by: Arvind Kumar <arvindkumar@vmware.com> * diff --git a/hw/sd/allwinner-sdhost.c b/hw/sd/allwinner-sdhost.c index 03980d2..b31da5c 100644 --- a/hw/sd/allwinner-sdhost.c +++ b/hw/sd/allwinner-sdhost.c @@ -888,14 +888,15 @@ static void allwinner_sdhost_reset(DeviceState *dev) } } -static void allwinner_sdhost_bus_class_init(ObjectClass *klass, void *data) +static void allwinner_sdhost_bus_class_init(ObjectClass *klass, + const void *data) { SDBusClass *sbc = SD_BUS_CLASS(klass); sbc->set_inserted = allwinner_sdhost_set_inserted; } -static void allwinner_sdhost_class_init(ObjectClass *klass, void *data) +static void allwinner_sdhost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -905,7 +906,8 @@ static void allwinner_sdhost_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, allwinner_sdhost_properties); } -static void allwinner_sdhost_sun4i_class_init(ObjectClass *klass, void *data) +static void allwinner_sdhost_sun4i_class_init(ObjectClass *klass, + const void *data) { AwSdHostClass *sc = AW_SDHOST_CLASS(klass); sc->max_desc_size = 8 * KiB; @@ -913,7 +915,8 @@ static void allwinner_sdhost_sun4i_class_init(ObjectClass *klass, void *data) sc->can_calibrate = false; } -static void allwinner_sdhost_sun5i_class_init(ObjectClass *klass, void *data) +static void allwinner_sdhost_sun5i_class_init(ObjectClass *klass, + const void *data) { AwSdHostClass *sc = AW_SDHOST_CLASS(klass); sc->max_desc_size = 64 * KiB; @@ -922,7 +925,7 @@ static void allwinner_sdhost_sun5i_class_init(ObjectClass *klass, void *data) } static void allwinner_sdhost_sun50i_a64_class_init(ObjectClass *klass, - void *data) + const void *data) { AwSdHostClass *sc = AW_SDHOST_CLASS(klass); sc->max_desc_size = 64 * KiB; @@ -931,7 +934,7 @@ static void allwinner_sdhost_sun50i_a64_class_init(ObjectClass *klass, } static void allwinner_sdhost_sun50i_a64_emmc_class_init(ObjectClass *klass, - void *data) + const void *data) { AwSdHostClass *sc = AW_SDHOST_CLASS(klass); sc->max_desc_size = 8 * KiB; diff --git a/hw/sd/aspeed_sdhci.c b/hw/sd/aspeed_sdhci.c index 12cbbae..fc38ad3 100644 --- a/hw/sd/aspeed_sdhci.c +++ b/hw/sd/aspeed_sdhci.c @@ -208,7 +208,7 @@ static const Property aspeed_sdhci_properties[] = { DEFINE_PROP_UINT8("num-slots", AspeedSDHCIState, num_slots, 0), }; -static void aspeed_sdhci_class_init(ObjectClass *classp, void *data) +static void aspeed_sdhci_class_init(ObjectClass *classp, const void *data) { DeviceClass *dc = DEVICE_CLASS(classp); @@ -218,7 +218,7 @@ static void aspeed_sdhci_class_init(ObjectClass *classp, void *data) device_class_set_props(dc, aspeed_sdhci_properties); } -static void aspeed_2400_sdhci_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_sdhci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); @@ -227,7 +227,7 @@ static void aspeed_2400_sdhci_class_init(ObjectClass *klass, void *data) asc->capareg = 0x0000000001e80080; } -static void aspeed_2500_sdhci_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_sdhci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); @@ -236,7 +236,7 @@ static void aspeed_2500_sdhci_class_init(ObjectClass *klass, void *data) asc->capareg = 0x0000000001e80080; } -static void aspeed_2600_sdhci_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_sdhci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); @@ -245,7 +245,7 @@ static void aspeed_2600_sdhci_class_init(ObjectClass *klass, void *data) asc->capareg = 0x0000000701f80080; } -static void aspeed_2700_sdhci_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_sdhci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSDHCIClass *asc = ASPEED_SDHCI_CLASS(klass); diff --git a/hw/sd/bcm2835_sdhost.c b/hw/sd/bcm2835_sdhost.c index 0724949..29debdf 100644 --- a/hw/sd/bcm2835_sdhost.c +++ b/hw/sd/bcm2835_sdhost.c @@ -428,7 +428,7 @@ static void bcm2835_sdhost_reset(DeviceState *dev) s->fifo_len = 0; } -static void bcm2835_sdhost_class_init(ObjectClass *klass, void *data) +static void bcm2835_sdhost_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/sd/cadence_sdhci.c b/hw/sd/cadence_sdhci.c index ad9daa2..d576855 100644 --- a/hw/sd/cadence_sdhci.c +++ b/hw/sd/cadence_sdhci.c @@ -165,7 +165,7 @@ static const VMStateDescription vmstate_cadence_sdhci = { }, }; -static void cadence_sdhci_class_init(ObjectClass *classp, void *data) +static void cadence_sdhci_class_init(ObjectClass *classp, const void *data) { DeviceClass *dc = DEVICE_CLASS(classp); diff --git a/hw/sd/npcm7xx_sdhci.c b/hw/sd/npcm7xx_sdhci.c index 99028c1..0233d7b 100644 --- a/hw/sd/npcm7xx_sdhci.c +++ b/hw/sd/npcm7xx_sdhci.c @@ -149,7 +149,7 @@ static const VMStateDescription vmstate_npcm7xx_sdhci = { }, }; -static void npcm7xx_sdhci_class_init(ObjectClass *classp, void *data) +static void npcm7xx_sdhci_class_init(ObjectClass *classp, const void *data) { DeviceClass *dc = DEVICE_CLASS(classp); diff --git a/hw/sd/omap_mmc.c b/hw/sd/omap_mmc.c index bbe7b97..b7648d4 100644 --- a/hw/sd/omap_mmc.c +++ b/hw/sd/omap_mmc.c @@ -612,7 +612,7 @@ static void omap_mmc_initfn(Object *obj) qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_SD_BUS, DEVICE(obj), "sd-bus"); } -static void omap_mmc_class_init(ObjectClass *oc, void *data) +static void omap_mmc_class_init(ObjectClass *oc, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(oc); diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c index 03d2ae7..b8fc9f8 100644 --- a/hw/sd/pl181.c +++ b/hw/sd/pl181.c @@ -509,7 +509,7 @@ static void pl181_init(Object *obj) qbus_init(&s->sdbus, sizeof(s->sdbus), TYPE_PL181_BUS, dev, "sd-bus"); } -static void pl181_class_init(ObjectClass *klass, void *data) +static void pl181_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); @@ -519,7 +519,7 @@ static void pl181_class_init(ObjectClass *klass, void *data) k->user_creatable = false; } -static void pl181_bus_class_init(ObjectClass *klass, void *data) +static void pl181_bus_class_init(ObjectClass *klass, const void *data) { SDBusClass *sbc = SD_BUS_CLASS(klass); @@ -2751,7 +2751,7 @@ static const Property emmc_properties[] = { DEFINE_PROP_UINT8("boot-config", SDState, boot_config, 0x0), }; -static void sdmmc_common_class_init(ObjectClass *klass, void *data) +static void sdmmc_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); @@ -2774,7 +2774,7 @@ static void sdmmc_common_class_init(ObjectClass *klass, void *data) sc->get_readonly = sd_get_readonly; } -static void sd_class_init(ObjectClass *klass, void *data) +static void sd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); @@ -2793,7 +2793,7 @@ static void sd_class_init(ObjectClass *klass, void *data) * board to ensure that ssi transfers only occur when the chip select * is asserted. */ -static void sd_spi_class_init(ObjectClass *klass, void *data) +static void sd_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); @@ -2802,7 +2802,7 @@ static void sd_spi_class_init(ObjectClass *klass, void *data) sc->proto = &sd_proto_spi; } -static void emmc_class_init(ObjectClass *klass, void *data) +static void emmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDCardClass *sc = SDMMC_COMMON_CLASS(klass); diff --git a/hw/sd/sdhci-pci.c b/hw/sd/sdhci-pci.c index bca149e..c18b91f 100644 --- a/hw/sd/sdhci-pci.c +++ b/hw/sd/sdhci-pci.c @@ -54,7 +54,7 @@ static void sdhci_pci_exit(PCIDevice *dev) sdhci_uninitfn(s); } -static void sdhci_pci_class_init(ObjectClass *klass, void *data) +static void sdhci_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -75,7 +75,7 @@ static const TypeInfo sdhci_pci_types[] = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(SDHCIState), .class_init = sdhci_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c index 69baf73..226ff13 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1620,7 +1620,7 @@ static void sdhci_sysbus_unrealize(DeviceState *dev) } } -static void sdhci_sysbus_class_init(ObjectClass *klass, void *data) +static void sdhci_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1633,7 +1633,7 @@ static void sdhci_sysbus_class_init(ObjectClass *klass, void *data) /* --- qdev bus master --- */ -static void sdhci_bus_class_init(ObjectClass *klass, void *data) +static void sdhci_bus_class_init(ObjectClass *klass, const void *data) { SDBusClass *sbc = SD_BUS_CLASS(klass); diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c index c4a58da..6c90a86 100644 --- a/hw/sd/ssi-sd.c +++ b/hw/sd/ssi-sd.c @@ -389,7 +389,7 @@ static void ssi_sd_reset(DeviceState *dev) s->stopping = 0; } -static void ssi_sd_class_init(ObjectClass *klass, void *data) +static void ssi_sd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass); diff --git a/hw/sensor/adm1266.c b/hw/sensor/adm1266.c index 25b87a7..9017ce6 100644 --- a/hw/sensor/adm1266.c +++ b/hw/sensor/adm1266.c @@ -223,7 +223,7 @@ static void adm1266_init(Object *obj) } } -static void adm1266_class_init(ObjectClass *klass, void *data) +static void adm1266_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/sensor/adm1272.c b/hw/sensor/adm1272.c index 3fc1e5d..0c739aa 100644 --- a/hw/sensor/adm1272.c +++ b/hw/sensor/adm1272.c @@ -511,7 +511,7 @@ static void adm1272_init(Object *obj) } -static void adm1272_class_init(ObjectClass *klass, void *data) +static void adm1272_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/sensor/dps310.c b/hw/sensor/dps310.c index 6966a53..bcf6154 100644 --- a/hw/sensor/dps310.c +++ b/hw/sensor/dps310.c @@ -197,7 +197,7 @@ static const VMStateDescription vmstate_dps310 = { } }; -static void dps310_class_init(ObjectClass *klass, void *data) +static void dps310_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/sensor/emc141x.c b/hw/sensor/emc141x.c index 33c1bd3..7b2ce38 100644 --- a/hw/sensor/emc141x.c +++ b/hw/sensor/emc141x.c @@ -277,7 +277,7 @@ static void emc141x_class_init(ObjectClass *klass, const void *data) dc->vmsd = &vmstate_emc141x; } -static void emc1413_class_init(ObjectClass *klass, void *data) +static void emc1413_class_init(ObjectClass *klass, const void *data) { EMC141XClass *ec = EMC141X_CLASS(klass); @@ -286,7 +286,7 @@ static void emc1413_class_init(ObjectClass *klass, void *data) ec->sensors_count = 3; } -static void emc1414_class_init(ObjectClass *klass, void *data) +static void emc1414_class_init(ObjectClass *klass, const void *data) { EMC141XClass *ec = EMC141X_CLASS(klass); diff --git a/hw/sensor/isl_pmbus_vr.c b/hw/sensor/isl_pmbus_vr.c index c60282c..e8d29b0 100644 --- a/hw/sensor/isl_pmbus_vr.c +++ b/hw/sensor/isl_pmbus_vr.c @@ -242,7 +242,7 @@ static void isl_pmbus_vr_class_init(ObjectClass *klass, const void *data, k->device_num_pages = pages; } -static void isl69260_class_init(ObjectClass *klass, void *data) +static void isl69260_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -251,7 +251,7 @@ static void isl69260_class_init(ObjectClass *klass, void *data) isl_pmbus_vr_class_init(klass, data, 2); } -static void raa228000_class_init(ObjectClass *klass, void *data) +static void raa228000_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -260,7 +260,7 @@ static void raa228000_class_init(ObjectClass *klass, void *data) isl_pmbus_vr_class_init(klass, data, 1); } -static void raa229004_class_init(ObjectClass *klass, void *data) +static void raa229004_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -269,7 +269,7 @@ static void raa229004_class_init(ObjectClass *klass, void *data) isl_pmbus_vr_class_init(klass, data, 2); } -static void isl69259_class_init(ObjectClass *klass, void *data) +static void isl69259_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/sensor/lsm303dlhc_mag.c b/hw/sensor/lsm303dlhc_mag.c index 0447153..f9e501d 100644 --- a/hw/sensor/lsm303dlhc_mag.c +++ b/hw/sensor/lsm303dlhc_mag.c @@ -530,7 +530,7 @@ static void lsm303dlhc_mag_initfn(Object *obj) /* * Set the virtual method pointers (bus state change, tx/rx, etc.). */ -static void lsm303dlhc_mag_class_init(ObjectClass *klass, void *data) +static void lsm303dlhc_mag_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/sensor/max31785.c b/hw/sensor/max31785.c index 3577a7c..c755814 100644 --- a/hw/sensor/max31785.c +++ b/hw/sensor/max31785.c @@ -544,7 +544,7 @@ static void max31785_init(Object *obj) } } -static void max31785_class_init(ObjectClass *klass, void *data) +static void max31785_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/sensor/max34451.c b/hw/sensor/max34451.c index 93b53f3..a369d2b 100644 --- a/hw/sensor/max34451.c +++ b/hw/sensor/max34451.c @@ -746,7 +746,7 @@ static void max34451_init(Object *obj) } -static void max34451_class_init(ObjectClass *klass, void *data) +static void max34451_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/sensor/tmp105.c b/hw/sensor/tmp105.c index ef2824f..f5b6110 100644 --- a/hw/sensor/tmp105.c +++ b/hw/sensor/tmp105.c @@ -313,7 +313,7 @@ static void tmp105_initfn(Object *obj) tmp105_set_temperature, NULL, NULL); } -static void tmp105_class_init(ObjectClass *klass, void *data) +static void tmp105_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); diff --git a/hw/sensor/tmp421.c b/hw/sensor/tmp421.c index 007f7cd..3421c44 100644 --- a/hw/sensor/tmp421.c +++ b/hw/sensor/tmp421.c @@ -337,7 +337,7 @@ static void tmp421_realize(DeviceState *dev, Error **errp) tmp421_reset(&s->i2c); } -static void tmp421_class_init(ObjectClass *klass, void *data) +static void tmp421_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); @@ -382,7 +382,7 @@ static void tmp421_register_types(void) .name = devices[i].name, .parent = TYPE_TMP421, .class_init = tmp421_class_init, - .class_data = (void *) &devices[i], + .class_data = &devices[i], }; type_register_static(&ti); } diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c index 6faf0e3..300eabc 100644 --- a/hw/sh4/sh7750.c +++ b/hw/sh4/sh7750.c @@ -29,13 +29,13 @@ #include "hw/irq.h" #include "hw/sh4/sh.h" #include "system/system.h" +#include "target/sh4/cpu.h" #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "sh7750_regs.h" #include "sh7750_regnames.h" #include "hw/sh4/sh_intc.h" #include "hw/timer/tmu012.h" -#include "exec/exec-all.h" #include "exec/cputlb.h" #include "trace.h" diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c index 5aaafb4..8ac7e62 100644 --- a/hw/sparc/sun4m.c +++ b/hw/sparc/sun4m.c @@ -27,6 +27,7 @@ #include "qapi/error.h" #include "qemu/datadir.h" #include "cpu.h" +#include "exec/target_page.h" #include "hw/sysbus.h" #include "qemu/error-report.h" #include "qemu/timer.h" @@ -594,7 +595,7 @@ static void idreg_realize(DeviceState *ds, Error **errp) sysbus_init_mmio(dev, &s->mem); } -static void idreg_class_init(ObjectClass *oc, void *data) +static void idreg_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -644,7 +645,7 @@ static void afx_realize(DeviceState *ds, Error **errp) sysbus_init_mmio(dev, &s->mem); } -static void afx_class_init(ObjectClass *oc, void *data) +static void afx_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); @@ -726,7 +727,7 @@ static void prom_realize(DeviceState *ds, Error **errp) sysbus_init_mmio(dev, &s->prom); } -static void prom_class_init(ObjectClass *klass, void *data) +static void prom_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -770,7 +771,7 @@ static void ram_initfn(Object *obj) "Valid value is ID of a hostmem backend"); } -static void ram_class_init(ObjectClass *klass, void *data) +static void ram_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1097,7 +1098,7 @@ enum { ss600mp_id, }; -static void sun4m_machine_class_init(ObjectClass *oc, void *data) +static void sun4m_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -1108,7 +1109,7 @@ static void sun4m_machine_class_init(ObjectClass *oc, void *data) mc->default_ram_id = "sun4m.ram"; } -static void ss5_class_init(ObjectClass *oc, void *data) +static void ss5_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1145,7 +1146,7 @@ static void ss5_class_init(ObjectClass *oc, void *data) smc->hwdef = &ss5_hwdef; } -static void ss10_class_init(ObjectClass *oc, void *data) +static void ss10_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1180,7 +1181,7 @@ static void ss10_class_init(ObjectClass *oc, void *data) smc->hwdef = &ss10_hwdef; } -static void ss600mp_class_init(ObjectClass *oc, void *data) +static void ss600mp_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1213,7 +1214,7 @@ static void ss600mp_class_init(ObjectClass *oc, void *data) smc->hwdef = &ss600mp_hwdef; } -static void ss20_class_init(ObjectClass *oc, void *data) +static void ss20_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1264,7 +1265,7 @@ static void ss20_class_init(ObjectClass *oc, void *data) smc->hwdef = &ss20_hwdef; } -static void voyager_class_init(ObjectClass *oc, void *data) +static void voyager_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1296,7 +1297,7 @@ static void voyager_class_init(ObjectClass *oc, void *data) smc->hwdef = &voyager_hwdef; } -static void ss_lx_class_init(ObjectClass *oc, void *data) +static void ss_lx_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1329,7 +1330,7 @@ static void ss_lx_class_init(ObjectClass *oc, void *data) smc->hwdef = &ss_lx_hwdef; } -static void ss4_class_init(ObjectClass *oc, void *data) +static void ss4_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1362,7 +1363,7 @@ static void ss4_class_init(ObjectClass *oc, void *data) smc->hwdef = &ss4_hwdef; } -static void scls_class_init(ObjectClass *oc, void *data) +static void scls_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); @@ -1394,7 +1395,7 @@ static void scls_class_init(ObjectClass *oc, void *data) smc->hwdef = &scls_hwdef; } -static void sbook_class_init(ObjectClass *oc, void *data) +static void sbook_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); Sun4mMachineClass *smc = SUN4M_MACHINE_CLASS(mc); diff --git a/hw/sparc/sun4m_iommu.c b/hw/sparc/sun4m_iommu.c index 5a4c1f5..a7ff36e 100644 --- a/hw/sparc/sun4m_iommu.c +++ b/hw/sparc/sun4m_iommu.c @@ -29,7 +29,7 @@ #include "hw/sysbus.h" #include "migration/vmstate.h" #include "qemu/module.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "trace.h" /* @@ -372,7 +372,7 @@ static const Property iommu_properties[] = { DEFINE_PROP_UINT32("version", IOMMUState, version, 0), }; -static void iommu_class_init(ObjectClass *klass, void *data) +static void iommu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -389,7 +389,8 @@ static const TypeInfo iommu_info = { .class_init = iommu_class_init, }; -static void sun4m_iommu_memory_region_class_init(ObjectClass *klass, void *data) +static void sun4m_iommu_memory_region_class_init(ObjectClass *klass, + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/sparc64/niagara.c b/hw/sparc64/niagara.c index 805ba6b..1ffe920 100644 --- a/hw/sparc64/niagara.c +++ b/hw/sparc64/niagara.c @@ -157,7 +157,7 @@ static void niagara_init(MachineState *machine) sun4v_rtc_init(NIAGARA_RTC_BASE); } -static void niagara_class_init(ObjectClass *oc, void *data) +static void niagara_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c index d3cb727..e9f9b0a 100644 --- a/hw/sparc64/sun4u.c +++ b/hw/sparc64/sun4u.c @@ -28,6 +28,7 @@ #include "qapi/error.h" #include "qemu/datadir.h" #include "cpu.h" +#include "exec/target_page.h" #include "hw/irq.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bridge.h" @@ -265,7 +266,7 @@ static void power_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(sbd, &d->power_mmio); } -static void power_class_init(ObjectClass *klass, void *data) +static void power_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -372,7 +373,7 @@ static const Property ebus_properties[] = { console_serial_base, 0), }; -static void ebus_class_init(ObjectClass *klass, void *data) +static void ebus_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -390,7 +391,7 @@ static const TypeInfo ebus_info = { .parent = TYPE_PCI_DEVICE, .class_init = ebus_class_init, .instance_size = sizeof(EbusState), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -463,7 +464,7 @@ static void prom_realize(DeviceState *ds, Error **errp) sysbus_init_mmio(dev, &s->prom); } -static void prom_class_init(ObjectClass *klass, void *data) +static void prom_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -523,7 +524,7 @@ static const Property ram_properties[] = { DEFINE_PROP_UINT64("size", RamDevice, size, 0), }; -static void ram_class_init(ObjectClass *klass, void *data) +static void ram_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -786,7 +787,7 @@ static GlobalProperty hw_compat_sparc64[] = { }; static const size_t hw_compat_sparc64_len = G_N_ELEMENTS(hw_compat_sparc64); -static void sun4u_class_init(ObjectClass *oc, void *data) +static void sun4u_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc); @@ -810,13 +811,13 @@ static const TypeInfo sun4u_type = { .name = MACHINE_TYPE_NAME("sun4u"), .parent = TYPE_MACHINE, .class_init = sun4u_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_FW_PATH_PROVIDER }, { } }, }; -static void sun4v_class_init(ObjectClass *oc, void *data) +static void sun4v_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/sparc64/sun4u_iommu.c b/hw/sparc64/sun4u_iommu.c index eba811a..14645f4 100644 --- a/hw/sparc64/sun4u_iommu.c +++ b/hw/sparc64/sun4u_iommu.c @@ -27,7 +27,7 @@ #include "qemu/osdep.h" #include "hw/sysbus.h" #include "hw/sparc/sun4u_iommu.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qemu/log.h" #include "qemu/module.h" #include "trace.h" @@ -305,7 +305,7 @@ static void iommu_init(Object *obj) sysbus_init_mmio(sbd, &s->iomem); } -static void iommu_class_init(ObjectClass *klass, void *data) +static void iommu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -320,7 +320,8 @@ static const TypeInfo iommu_info = { .class_init = iommu_class_init, }; -static void sun4u_iommu_memory_region_class_init(ObjectClass *klass, void *data) +static void sun4u_iommu_memory_region_class_init(ObjectClass *klass, + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/ssi/allwinner-a10-spi.c b/hw/ssi/allwinner-a10-spi.c index d2f6bb9..6b7cca8 100644 --- a/hw/ssi/allwinner-a10-spi.c +++ b/hw/ssi/allwinner-a10-spi.c @@ -535,7 +535,7 @@ static void allwinner_a10_spi_realize(DeviceState *dev, Error **errp) fifo8_create(&s->rx_fifo, AW_A10_SPI_FIFO_SIZE); } -static void allwinner_a10_spi_class_init(ObjectClass *klass, void *data) +static void allwinner_a10_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index faef1a8..614528b 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -359,7 +359,7 @@ static const MemoryRegionOps aspeed_smc_flash_default_ops = { .endianness = DEVICE_LITTLE_ENDIAN, .valid = { .min_access_size = 1, - .max_access_size = 4, + .max_access_size = 8, }, }; @@ -670,7 +670,7 @@ static const MemoryRegionOps aspeed_smc_flash_ops = { .endianness = DEVICE_LITTLE_ENDIAN, .valid = { .min_access_size = 1, - .max_access_size = 4, + .max_access_size = 8, }, }; @@ -1294,7 +1294,7 @@ static const Property aspeed_smc_properties[] = { TYPE_MEMORY_REGION, MemoryRegion *), }; -static void aspeed_smc_class_init(ObjectClass *klass, void *data) +static void aspeed_smc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1341,7 +1341,7 @@ static const Property aspeed_smc_flash_properties[] = { AspeedSMCState *), }; -static void aspeed_smc_flash_class_init(ObjectClass *klass, void *data) +static void aspeed_smc_flash_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -1383,7 +1383,7 @@ static const AspeedSegments aspeed_2400_smc_segments[] = { { 0x10000000, 32 * MiB }, }; -static void aspeed_2400_smc_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_smc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1429,7 +1429,7 @@ static const AspeedSegments aspeed_2400_fmc_segments[] = { { 0x2A000000, 32 * MiB } }; -static void aspeed_2400_fmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_fmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1473,7 +1473,7 @@ static int aspeed_2400_spi1_addr_width(const AspeedSMCState *s) return s->regs[R_SPI_CTRL0] & CTRL_AST2400_SPI_4BYTE ? 4 : 3; } -static void aspeed_2400_spi1_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_spi1_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1515,7 +1515,7 @@ static const AspeedSegments aspeed_2500_fmc_segments[] = { { 0x2A000000, 32 * MiB }, }; -static void aspeed_2500_fmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_fmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1555,7 +1555,7 @@ static const AspeedSegments aspeed_2500_spi1_segments[] = { { 0x32000000, 96 * MiB }, /* end address is readonly */ }; -static void aspeed_2500_spi1_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_spi1_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1591,7 +1591,7 @@ static const AspeedSegments aspeed_2500_spi2_segments[] = { { 0x3A000000, 96 * MiB }, /* end address is readonly */ }; -static void aspeed_2500_spi2_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_spi2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1674,7 +1674,7 @@ static const AspeedSegments aspeed_2600_fmc_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2600_fmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_fmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1715,7 +1715,7 @@ static const AspeedSegments aspeed_2600_spi1_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2600_spi1_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_spi1_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1756,7 +1756,7 @@ static const AspeedSegments aspeed_2600_spi2_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2600_spi2_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_spi2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1839,7 +1839,7 @@ static const AspeedSegments aspeed_1030_fmc_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_1030_fmc_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_fmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1879,7 +1879,7 @@ static const AspeedSegments aspeed_1030_spi1_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_1030_spi1_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_spi1_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -1917,7 +1917,7 @@ static const AspeedSegments aspeed_1030_spi2_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_1030_spi2_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_spi2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -2022,7 +2022,7 @@ static const AspeedSegments aspeed_2700_fmc_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2700_fmc_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_fmc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -2064,7 +2064,7 @@ static const AspeedSegments aspeed_2700_spi0_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2700_spi0_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_spi0_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -2104,7 +2104,7 @@ static const AspeedSegments aspeed_2700_spi1_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2700_spi1_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_spi1_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); @@ -2144,7 +2144,7 @@ static const AspeedSegments aspeed_2700_spi2_segments[] = { { 0x0, 0 }, /* disabled */ }; -static void aspeed_2700_spi2_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_spi2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedSMCClass *asc = ASPEED_SMC_CLASS(klass); diff --git a/hw/ssi/bcm2835_spi.c b/hw/ssi/bcm2835_spi.c index ebd8809..bf8ba35 100644 --- a/hw/ssi/bcm2835_spi.c +++ b/hw/ssi/bcm2835_spi.c @@ -264,7 +264,7 @@ static const VMStateDescription vmstate_bcm2835_spi = { } }; -static void bcm2835_spi_class_init(ObjectClass *klass, void *data) +static void bcm2835_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c index 6b28cda..f05be68 100644 --- a/hw/ssi/ibex_spi_host.c +++ b/hw/ssi/ibex_spi_host.c @@ -622,7 +622,7 @@ static void ibex_spi_host_init(Object *obj) sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio); } -static void ibex_spi_host_class_init(ObjectClass *klass, void *data) +static void ibex_spi_host_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = ibex_spi_host_realize; diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c index 2e31787..1312f58 100644 --- a/hw/ssi/imx_spi.c +++ b/hw/ssi/imx_spi.c @@ -475,7 +475,7 @@ static void imx_spi_realize(DeviceState *dev, Error **errp) fifo32_create(&s->rx_fifo, ECSPI_FIFO_SIZE); } -static void imx_spi_class_init(ObjectClass *klass, void *data) +static void imx_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c index 340adcd..fd7ba7e 100644 --- a/hw/ssi/mss-spi.c +++ b/hw/ssi/mss-spi.c @@ -398,7 +398,7 @@ static const VMStateDescription vmstate_mss_spi = { } }; -static void mss_spi_class_init(ObjectClass *klass, void *data) +static void mss_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c index 8df4bec..056ce13 100644 --- a/hw/ssi/npcm7xx_fiu.c +++ b/hw/ssi/npcm7xx_fiu.c @@ -557,7 +557,7 @@ static const Property npcm7xx_fiu_properties[] = { DEFINE_PROP_SIZE("flash-size", NPCM7xxFIUState, flash_size, 0), }; -static void npcm7xx_fiu_class_init(ObjectClass *klass, void *data) +static void npcm7xx_fiu_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c index 41a5323..a31dcc0 100644 --- a/hw/ssi/npcm_pspi.c +++ b/hw/ssi/npcm_pspi.c @@ -199,7 +199,7 @@ static const VMStateDescription vmstate_npcm_pspi = { }; -static void npcm_pspi_class_init(ObjectClass *klass, void *data) +static void npcm_pspi_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index 53c9c22..1dc0bcb 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -292,7 +292,7 @@ static void pl022_realize(DeviceState *dev, Error **errp) s->ssi = ssi_create_bus(dev, "ssi"); } -static void pl022_class_init(ObjectClass *klass, void *data) +static void pl022_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index 367a2ff..f40e883 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -1199,7 +1199,7 @@ static int pnv_spi_dt_xscom(PnvXScomInterface *dev, void *fdt, return 0; } -static void pnv_spi_class_init(ObjectClass *klass, void *data) +static void pnv_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PnvXScomInterfaceClass *xscomc = PNV_XSCOM_INTERFACE_CLASS(klass); @@ -1217,7 +1217,7 @@ static const TypeInfo pnv_spi_info = { .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(PnvSpi), .class_init = pnv_spi_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_PNV_XSCOM_INTERFACE }, { } } diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c index 76f8654..3e01fef 100644 --- a/hw/ssi/sifive_spi.c +++ b/hw/ssi/sifive_spi.c @@ -332,7 +332,7 @@ static const Property sifive_spi_properties[] = { DEFINE_PROP_UINT32("num-cs", SiFiveSPIState, num_cs, 1), }; -static void sifive_spi_class_init(ObjectClass *klass, void *data) +static void sifive_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c index 872c4e8..d0de640 100644 --- a/hw/ssi/ssi.c +++ b/hw/ssi/ssi.c @@ -55,7 +55,7 @@ static bool ssi_bus_check_address(BusState *b, DeviceState *dev, Error **errp) return true; } -static void ssi_bus_class_init(ObjectClass *klass, void *data) +static void ssi_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); @@ -112,7 +112,7 @@ static const Property ssi_peripheral_properties[] = { DEFINE_PROP_UINT8("cs", SSIPeripheral, cs_index, 0), }; -static void ssi_peripheral_class_init(ObjectClass *klass, void *data) +static void ssi_peripheral_class_init(ObjectClass *klass, const void *data) { SSIPeripheralClass *ssc = SSI_PERIPHERAL_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c index ea9b74a..871d573 100644 --- a/hw/ssi/stm32f2xx_spi.c +++ b/hw/ssi/stm32f2xx_spi.c @@ -202,7 +202,7 @@ static void stm32f2xx_spi_init(Object *obj) s->ssi = ssi_create_bus(dev, "ssi"); } -static void stm32f2xx_spi_class_init(ObjectClass *klass, void *data) +static void stm32f2xx_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c index be5baa6..4144c8a 100644 --- a/hw/ssi/xilinx_spi.c +++ b/hw/ssi/xilinx_spi.c @@ -379,7 +379,7 @@ static const Property xilinx_spi_properties[] = { DEFINE_PROP_UINT8("num-ss-bits", XilinxSPI, num_cs, 1), }; -static void xilinx_spi_class_init(ObjectClass *klass, void *data) +static void xilinx_spi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c index 60d0920..a79f3b8 100644 --- a/hw/ssi/xilinx_spips.c +++ b/hw/ssi/xilinx_spips.c @@ -1430,7 +1430,7 @@ static const Property xilinx_spips_properties[] = { DEFINE_PROP_UINT8("num-txrx-bytes", XilinxSPIPS, num_txrx_bytes, 1), }; -static void xilinx_qspips_class_init(ObjectClass *klass, void * data) +static void xilinx_qspips_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass); @@ -1442,7 +1442,7 @@ static void xilinx_qspips_class_init(ObjectClass *klass, void * data) xsc->tx_fifo_size = TXFF_A_Q; } -static void xilinx_spips_class_init(ObjectClass *klass, void *data) +static void xilinx_spips_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass); @@ -1458,7 +1458,7 @@ static void xilinx_spips_class_init(ObjectClass *klass, void *data) xsc->tx_fifo_size = TXFF_A; } -static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, void * data) +static void xlnx_zynqmp_qspips_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); XilinxSPIPSClass *xsc = XILINX_SPIPS_CLASS(klass); diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c index 9e96c9b..56d51ce 100644 --- a/hw/ssi/xlnx-versal-ospi.c +++ b/hw/ssi/xlnx-versal-ospi.c @@ -1831,7 +1831,7 @@ static const Property xlnx_versal_ospi_properties[] = { ind_write_disabled, false), }; -static void xlnx_versal_ospi_class_init(ObjectClass *klass, void *data) +static void xlnx_versal_ospi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/a9gtimer.c b/hw/timer/a9gtimer.c index 9835c35..690140f 100644 --- a/hw/timer/a9gtimer.c +++ b/hw/timer/a9gtimer.c @@ -377,7 +377,7 @@ static const Property a9_gtimer_properties[] = { DEFINE_PROP_UINT32("num-cpu", A9GTimerState, num_cpu, 0), }; -static void a9_gtimer_class_init(ObjectClass *klass, void *data) +static void a9_gtimer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c index da3d717..e4c3532 100644 --- a/hw/timer/allwinner-a10-pit.c +++ b/hw/timer/allwinner-a10-pit.c @@ -288,7 +288,7 @@ static void a10_pit_finalize(Object *obj) } } -static void a10_pit_class_init(ObjectClass *klass, void *data) +static void a10_pit_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/arm_mptimer.c b/hw/timer/arm_mptimer.c index 803dad1..7cc5915 100644 --- a/hw/timer/arm_mptimer.c +++ b/hw/timer/arm_mptimer.c @@ -304,7 +304,7 @@ static const Property arm_mptimer_properties[] = { DEFINE_PROP_UINT32("num-cpu", ARMMPTimerState, num_cpu, 0), }; -static void arm_mptimer_class_init(ObjectClass *klass, void *data) +static void arm_mptimer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c index 1213b77..56638ff 100644 --- a/hw/timer/arm_timer.c +++ b/hw/timer/arm_timer.c @@ -392,7 +392,7 @@ static const Property sp804_properties[] = { DEFINE_PROP_UINT32("freq1", SP804State, freq1, 1000000), }; -static void sp804_class_init(ObjectClass *klass, void *data) +static void sp804_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); diff --git a/hw/timer/armv7m_systick.c b/hw/timer/armv7m_systick.c index a07febd..7e4ddcd 100644 --- a/hw/timer/armv7m_systick.c +++ b/hw/timer/armv7m_systick.c @@ -285,7 +285,7 @@ static const VMStateDescription vmstate_systick = { } }; -static void systick_class_init(ObjectClass *klass, void *data) +static void systick_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c index ecda495..57db035 100644 --- a/hw/timer/aspeed_timer.c +++ b/hw/timer/aspeed_timer.c @@ -895,7 +895,7 @@ static const Property aspeed_timer_properties[] = { AspeedSCUState *), }; -static void timer_class_init(ObjectClass *klass, void *data) +static void timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -915,7 +915,7 @@ static const TypeInfo aspeed_timer_info = { .abstract = true, }; -static void aspeed_2400_timer_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass); @@ -931,7 +931,7 @@ static const TypeInfo aspeed_2400_timer_info = { .class_init = aspeed_2400_timer_class_init, }; -static void aspeed_2500_timer_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass); @@ -947,7 +947,7 @@ static const TypeInfo aspeed_2500_timer_info = { .class_init = aspeed_2500_timer_class_init, }; -static void aspeed_2600_timer_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass); @@ -963,7 +963,7 @@ static const TypeInfo aspeed_2600_timer_info = { .class_init = aspeed_2600_timer_class_init, }; -static void aspeed_1030_timer_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass); @@ -979,7 +979,7 @@ static const TypeInfo aspeed_1030_timer_info = { .class_init = aspeed_1030_timer_class_init, }; -static void aspeed_2700_timer_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedTimerClass *awc = ASPEED_TIMER_CLASS(klass); diff --git a/hw/timer/avr_timer16.c b/hw/timer/avr_timer16.c index 96baf9c..012d829 100644 --- a/hw/timer/avr_timer16.c +++ b/hw/timer/avr_timer16.c @@ -595,7 +595,7 @@ static void avr_timer16_realize(DeviceState *dev, Error **errp) s->enabled = true; } -static void avr_timer16_class_init(ObjectClass *klass, void *data) +static void avr_timer16_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/bcm2835_systmr.c b/hw/timer/bcm2835_systmr.c index 2f0fee3..7929aaa 100644 --- a/hw/timer/bcm2835_systmr.c +++ b/hw/timer/bcm2835_systmr.c @@ -154,7 +154,7 @@ static const VMStateDescription bcm2835_systmr_vmstate = { } }; -static void bcm2835_systmr_class_init(ObjectClass *klass, void *data) +static void bcm2835_systmr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/cadence_ttc.c b/hw/timer/cadence_ttc.c index 54dbd4c..9c7ba16 100644 --- a/hw/timer/cadence_ttc.c +++ b/hw/timer/cadence_ttc.c @@ -451,7 +451,7 @@ static const VMStateDescription vmstate_cadence_ttc = { } }; -static void cadence_ttc_class_init(ObjectClass *klass, void *data) +static void cadence_ttc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/cmsdk-apb-dualtimer.c b/hw/timer/cmsdk-apb-dualtimer.c index 2ecd8df..34c550a 100644 --- a/hw/timer/cmsdk-apb-dualtimer.c +++ b/hw/timer/cmsdk-apb-dualtimer.c @@ -534,7 +534,7 @@ static const VMStateDescription cmsdk_apb_dualtimer_vmstate = { } }; -static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, void *data) +static void cmsdk_apb_dualtimer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/cmsdk-apb-timer.c b/hw/timer/cmsdk-apb-timer.c index 16d0b21..4095267 100644 --- a/hw/timer/cmsdk-apb-timer.c +++ b/hw/timer/cmsdk-apb-timer.c @@ -261,7 +261,7 @@ static const VMStateDescription cmsdk_apb_timer_vmstate = { } }; -static void cmsdk_apb_timer_class_init(ObjectClass *klass, void *data) +static void cmsdk_apb_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c index 00c3297..355138d 100644 --- a/hw/timer/digic-timer.c +++ b/hw/timer/digic-timer.c @@ -161,7 +161,7 @@ static void digic_timer_finalize(Object *obj) ptimer_free(s->ptimer); } -static void digic_timer_class_init(ObjectClass *klass, void *class_data) +static void digic_timer_class_init(ObjectClass *klass, const void *class_data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/exynos4210_mct.c b/hw/timer/exynos4210_mct.c index 5c6e139..bb0f9c8 100644 --- a/hw/timer/exynos4210_mct.c +++ b/hw/timer/exynos4210_mct.c @@ -1546,7 +1546,7 @@ static void exynos4210_mct_finalize(Object *obj) } } -static void exynos4210_mct_class_init(ObjectClass *klass, void *data) +static void exynos4210_mct_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/exynos4210_pwm.c b/hw/timer/exynos4210_pwm.c index 703d1d2..69f737a 100644 --- a/hw/timer/exynos4210_pwm.c +++ b/hw/timer/exynos4210_pwm.c @@ -420,7 +420,7 @@ static void exynos4210_pwm_finalize(Object *obj) } } -static void exynos4210_pwm_class_init(ObjectClass *klass, void *data) +static void exynos4210_pwm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/grlib_gptimer.c b/hw/timer/grlib_gptimer.c index f0802b6..0e06fa0 100644 --- a/hw/timer/grlib_gptimer.c +++ b/hw/timer/grlib_gptimer.c @@ -409,7 +409,7 @@ static const Property grlib_gptimer_properties[] = { DEFINE_PROP_UINT32("nr-timers", GPTimerUnit, nr_timers, 2), }; -static void grlib_gptimer_class_init(ObjectClass *klass, void *data) +static void grlib_gptimer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index ccb97b6..cb48cc1 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -36,7 +36,7 @@ #include "hw/rtc/mc146818rtc_regs.h" #include "migration/vmstate.h" #include "hw/timer/i8254.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/object.h" #include "trace.h" @@ -328,16 +328,16 @@ static const VMStateDescription vmstate_hpet_timer = { static const VMStateDescription vmstate_hpet = { .name = "hpet", .version_id = 2, - .minimum_version_id = 1, + .minimum_version_id = 2, .pre_save = hpet_pre_save, .post_load = hpet_post_load, .fields = (const VMStateField[]) { VMSTATE_UINT64(config, HPETState), VMSTATE_UINT64(isr, HPETState), VMSTATE_UINT64(hpet_counter, HPETState), - VMSTATE_UINT8_V(num_timers_save, HPETState, 2), + VMSTATE_UINT8(num_timers_save, HPETState), VMSTATE_VALIDATE("num_timers must match", hpet_validate_num_timers), - VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0, + VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers_save, 0, vmstate_hpet_timer, HPETTimer), VMSTATE_END_OF_LIST() }, @@ -426,30 +426,11 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr, uint64_t cur_tick; trace_hpet_ram_read(addr); + addr &= ~4; - /*address range of all TN regs*/ - if (addr >= 0x100 && addr <= 0x3ff) { - uint8_t timer_id = (addr - 0x100) / 0x20; - HPETTimer *timer = &s->timer[timer_id]; - - if (timer_id > s->num_timers) { - trace_hpet_timer_id_out_of_range(timer_id); - return 0; - } - - switch (addr & 0x18) { - case HPET_TN_CFG: // including interrupt capabilities - return timer->config >> shift; - case HPET_TN_CMP: // comparator register - return timer->cmp >> shift; - case HPET_TN_ROUTE: - return timer->fsb >> shift; - default: - trace_hpet_ram_read_invalid(); - break; - } - } else { - switch (addr & ~4) { + /*address range of all global regs*/ + if (addr <= 0xff) { + switch (addr) { case HPET_ID: // including HPET_PERIOD return s->capability >> shift; case HPET_CFG: @@ -468,6 +449,26 @@ static uint64_t hpet_ram_read(void *opaque, hwaddr addr, trace_hpet_ram_read_invalid(); break; } + } else { + uint8_t timer_id = (addr - 0x100) / 0x20; + HPETTimer *timer = &s->timer[timer_id]; + + if (timer_id > s->num_timers) { + trace_hpet_timer_id_out_of_range(timer_id); + return 0; + } + + switch (addr & 0x1f) { + case HPET_TN_CFG: // including interrupt capabilities + return timer->config >> shift; + case HPET_TN_CMP: // comparator register + return timer->cmp >> shift; + case HPET_TN_ROUTE: + return timer->fsb >> shift; + default: + trace_hpet_ram_read_invalid(); + break; + } } return 0; } @@ -482,9 +483,67 @@ static void hpet_ram_write(void *opaque, hwaddr addr, uint64_t old_val, new_val, cleared; trace_hpet_ram_write(addr, value); + addr &= ~4; - /*address range of all TN regs*/ - if (addr >= 0x100 && addr <= 0x3ff) { + /*address range of all global regs*/ + if (addr <= 0xff) { + switch (addr) { + case HPET_ID: + return; + case HPET_CFG: + old_val = s->config; + new_val = deposit64(old_val, shift, len, value); + new_val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK); + s->config = new_val; + if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) { + /* Enable main counter and interrupt generation. */ + s->hpet_offset = + ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + for (i = 0; i < s->num_timers; i++) { + if (timer_enabled(&s->timer[i]) && (s->isr & (1 << i))) { + update_irq(&s->timer[i], 1); + } + hpet_set_timer(&s->timer[i]); + } + } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) { + /* Halt main counter and disable interrupt generation. */ + s->hpet_counter = hpet_get_ticks(s); + for (i = 0; i < s->num_timers; i++) { + hpet_del_timer(&s->timer[i]); + } + } + /* i8254 and RTC output pins are disabled + * when HPET is in legacy mode */ + if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) { + qemu_set_irq(s->pit_enabled, 0); + qemu_irq_lower(s->irqs[0]); + qemu_irq_lower(s->irqs[RTC_ISA_IRQ]); + } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) { + qemu_irq_lower(s->irqs[0]); + qemu_set_irq(s->pit_enabled, 1); + qemu_set_irq(s->irqs[RTC_ISA_IRQ], s->rtc_irq_level); + } + break; + case HPET_STATUS: + new_val = value << shift; + cleared = new_val & s->isr; + for (i = 0; i < s->num_timers; i++) { + if (cleared & (1 << i)) { + update_irq(&s->timer[i], 0); + } + } + break; + case HPET_COUNTER: + if (hpet_enabled(s)) { + trace_hpet_ram_write_counter_write_while_enabled(); + } + s->hpet_counter = deposit64(s->hpet_counter, shift, len, value); + break; + default: + trace_hpet_ram_write_invalid(); + break; + } + } else { uint8_t timer_id = (addr - 0x100) / 0x20; HPETTimer *timer = &s->timer[timer_id]; @@ -550,63 +609,6 @@ static void hpet_ram_write(void *opaque, hwaddr addr, break; } return; - } else { - switch (addr & ~4) { - case HPET_ID: - return; - case HPET_CFG: - old_val = s->config; - new_val = deposit64(old_val, shift, len, value); - new_val = hpet_fixup_reg(new_val, old_val, HPET_CFG_WRITE_MASK); - s->config = new_val; - if (activating_bit(old_val, new_val, HPET_CFG_ENABLE)) { - /* Enable main counter and interrupt generation. */ - s->hpet_offset = - ticks_to_ns(s->hpet_counter) - qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - for (i = 0; i < s->num_timers; i++) { - if (timer_enabled(&s->timer[i]) && (s->isr & (1 << i))) { - update_irq(&s->timer[i], 1); - } - hpet_set_timer(&s->timer[i]); - } - } else if (deactivating_bit(old_val, new_val, HPET_CFG_ENABLE)) { - /* Halt main counter and disable interrupt generation. */ - s->hpet_counter = hpet_get_ticks(s); - for (i = 0; i < s->num_timers; i++) { - hpet_del_timer(&s->timer[i]); - } - } - /* i8254 and RTC output pins are disabled - * when HPET is in legacy mode */ - if (activating_bit(old_val, new_val, HPET_CFG_LEGACY)) { - qemu_set_irq(s->pit_enabled, 0); - qemu_irq_lower(s->irqs[0]); - qemu_irq_lower(s->irqs[RTC_ISA_IRQ]); - } else if (deactivating_bit(old_val, new_val, HPET_CFG_LEGACY)) { - qemu_irq_lower(s->irqs[0]); - qemu_set_irq(s->pit_enabled, 1); - qemu_set_irq(s->irqs[RTC_ISA_IRQ], s->rtc_irq_level); - } - break; - case HPET_STATUS: - new_val = value << shift; - cleared = new_val & s->isr; - for (i = 0; i < s->num_timers; i++) { - if (cleared & (1 << i)) { - update_irq(&s->timer[i], 0); - } - } - break; - case HPET_COUNTER: - if (hpet_enabled(s)) { - trace_hpet_ram_write_counter_write_while_enabled(); - } - s->hpet_counter = deposit64(s->hpet_counter, shift, len, value); - break; - default: - trace_hpet_ram_write_invalid(); - break; - } } } @@ -689,8 +691,14 @@ static void hpet_realize(DeviceState *dev, Error **errp) int i; HPETTimer *timer; + if (s->num_timers < HPET_MIN_TIMERS || s->num_timers > HPET_MAX_TIMERS) { + error_setg(errp, "hpet.num_timers must be between %d and %d", + HPET_MIN_TIMERS, HPET_MAX_TIMERS); + return; + } if (!s->intcap) { - warn_report("Hpet's intcap not initialized"); + error_setg(errp, "hpet.hpet-intcap not initialized"); + return; } if (hpet_fw_cfg.count == UINT8_MAX) { /* first instance */ @@ -698,7 +706,7 @@ static void hpet_realize(DeviceState *dev, Error **errp) } if (hpet_fw_cfg.count == 8) { - error_setg(errp, "Only 8 instances of HPET is allowed"); + error_setg(errp, "Only 8 instances of HPET are allowed"); return; } @@ -708,11 +716,6 @@ static void hpet_realize(DeviceState *dev, Error **errp) sysbus_init_irq(sbd, &s->irqs[i]); } - if (s->num_timers < HPET_MIN_TIMERS) { - s->num_timers = HPET_MIN_TIMERS; - } else if (s->num_timers > HPET_MAX_TIMERS) { - s->num_timers = HPET_MAX_TIMERS; - } for (i = 0; i < HPET_MAX_TIMERS; i++) { timer = &s->timer[i]; timer->qemu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, hpet_timer, timer); @@ -736,7 +739,7 @@ static const Property hpet_device_properties[] = { DEFINE_PROP_BOOL("hpet-offset-saved", HPETState, hpet_offset_saved, true), }; -static void hpet_device_class_init(ObjectClass *klass, void *data) +static void hpet_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c index 058fc61..4b25c48 100644 --- a/hw/timer/i8254.c +++ b/hw/timer/i8254.c @@ -350,7 +350,7 @@ static void pit_realizefn(DeviceState *dev, Error **errp) pc->parent_realize(dev, errp); } -static void pit_class_initfn(ObjectClass *klass, void *data) +static void pit_class_initfn(ObjectClass *klass, const void *data) { PITClass *pc = PIT_CLASS(klass); PITCommonClass *k = PIT_COMMON_CLASS(klass); diff --git a/hw/timer/i8254_common.c b/hw/timer/i8254_common.c index 29105af..ad09159 100644 --- a/hw/timer/i8254_common.c +++ b/hw/timer/i8254_common.c @@ -242,7 +242,7 @@ static const Property pit_common_properties[] = { DEFINE_PROP_UINT32("iobase", PITCommonState, iobase, -1), }; -static void pit_common_class_init(ObjectClass *klass, void *data) +static void pit_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c index 3ebc870..c7320ef 100644 --- a/hw/timer/ibex_timer.c +++ b/hw/timer/ibex_timer.c @@ -286,7 +286,7 @@ static void ibex_timer_realize(DeviceState *dev, Error **errp) } -static void ibex_timer_class_init(ObjectClass *klass, void *data) +static void ibex_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c index f40ab16..6123321 100644 --- a/hw/timer/imx_epit.c +++ b/hw/timer/imx_epit.c @@ -427,7 +427,7 @@ static void imx_epit_dev_reset(DeviceState *dev) imx_epit_reset(s, true); } -static void imx_epit_class_init(ObjectClass *klass, void *data) +static void imx_epit_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c index 200a892..8c7cbfd 100644 --- a/hw/timer/imx_gpt.c +++ b/hw/timer/imx_gpt.c @@ -518,7 +518,7 @@ static void imx_gpt_realize(DeviceState *dev, Error **errp) s->timer = ptimer_init(imx_gpt_timeout, s, PTIMER_POLICY_LEGACY); } -static void imx_gpt_class_init(ObjectClass *klass, void *data) +static void imx_gpt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/mss-timer.c b/hw/timer/mss-timer.c index 594da64..2ce8211 100644 --- a/hw/timer/mss-timer.c +++ b/hw/timer/mss-timer.c @@ -285,7 +285,7 @@ static const Property mss_timer_properties[] = { 100 * 1000000), }; -static void mss_timer_class_init(ObjectClass *klass, void *data) +static void mss_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/npcm7xx_timer.c b/hw/timer/npcm7xx_timer.c index c55ba02..6a116ad 100644 --- a/hw/timer/npcm7xx_timer.c +++ b/hw/timer/npcm7xx_timer.c @@ -689,7 +689,7 @@ static const VMStateDescription vmstate_npcm7xx_timer_ctrl = { }, }; -static void npcm7xx_timer_class_init(ObjectClass *klass, void *data) +static void npcm7xx_timer_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/nrf51_timer.c b/hw/timer/nrf51_timer.c index 11ad8b5..e228fde 100644 --- a/hw/timer/nrf51_timer.c +++ b/hw/timer/nrf51_timer.c @@ -383,7 +383,7 @@ static const Property nrf51_timer_properties[] = { DEFINE_PROP_UINT8("id", NRF51TimerState, id, 0), }; -static void nrf51_timer_class_init(ObjectClass *klass, void *data) +static void nrf51_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/pxa2xx_timer.c b/hw/timer/pxa2xx_timer.c index 9e4dd0f..6d4ac31 100644 --- a/hw/timer/pxa2xx_timer.c +++ b/hw/timer/pxa2xx_timer.c @@ -19,41 +19,41 @@ #include "qom/object.h" #include "system/watchdog.h" -#define OSMR0 0x00 -#define OSMR1 0x04 -#define OSMR2 0x08 -#define OSMR3 0x0c -#define OSMR4 0x80 -#define OSMR5 0x84 -#define OSMR6 0x88 -#define OSMR7 0x8c -#define OSMR8 0x90 -#define OSMR9 0x94 -#define OSMR10 0x98 -#define OSMR11 0x9c -#define OSCR 0x10 /* OS Timer Count */ -#define OSCR4 0x40 -#define OSCR5 0x44 -#define OSCR6 0x48 -#define OSCR7 0x4c -#define OSCR8 0x50 -#define OSCR9 0x54 -#define OSCR10 0x58 -#define OSCR11 0x5c -#define OSSR 0x14 /* Timer status register */ -#define OWER 0x18 -#define OIER 0x1c /* Interrupt enable register 3-0 to E3-E0 */ -#define OMCR4 0xc0 /* OS Match Control registers */ -#define OMCR5 0xc4 -#define OMCR6 0xc8 -#define OMCR7 0xcc -#define OMCR8 0xd0 -#define OMCR9 0xd4 -#define OMCR10 0xd8 -#define OMCR11 0xdc -#define OSNR 0x20 - -#define PXA25X_FREQ 3686400 /* 3.6864 MHz */ +#define OSMR0 0x00 +#define OSMR1 0x04 +#define OSMR2 0x08 +#define OSMR3 0x0c +#define OSMR4 0x80 +#define OSMR5 0x84 +#define OSMR6 0x88 +#define OSMR7 0x8c +#define OSMR8 0x90 +#define OSMR9 0x94 +#define OSMR10 0x98 +#define OSMR11 0x9c +#define OSCR 0x10 /* OS Timer Count */ +#define OSCR4 0x40 +#define OSCR5 0x44 +#define OSCR6 0x48 +#define OSCR7 0x4c +#define OSCR8 0x50 +#define OSCR9 0x54 +#define OSCR10 0x58 +#define OSCR11 0x5c +#define OSSR 0x14 /* Timer status register */ +#define OWER 0x18 +#define OIER 0x1c /* Interrupt enable register 3-0 to E3-E0 */ +#define OMCR4 0xc0 /* OS Match Control registers */ +#define OMCR5 0xc4 +#define OMCR6 0xc8 +#define OMCR7 0xcc +#define OMCR8 0xd0 +#define OMCR9 0xd4 +#define OMCR10 0xd8 +#define OMCR11 0xdc +#define OSNR 0x20 + +#define PXA25X_FREQ 3686400 /* 3.6864 MHz */ static int pxa2xx_timer4_freq[8] = { [0] = 0, @@ -106,7 +106,7 @@ struct PXA2xxTimerInfo { PXA2xxTimer4 tm4[8]; }; -#define PXA2XX_TIMER_HAVE_TM4 0 +#define PXA2XX_TIMER_HAVE_TM4 0 static inline int pxa2xx_timer_has_tm4(PXA2xxTimerInfo *s) { @@ -230,7 +230,7 @@ static uint64_t pxa2xx_timer_read(void *opaque, hwaddr offset, NANOSECONDS_PER_SECOND); case OIER: return s->irq_enabled; - case OSSR: /* Status register */ + case OSSR: /* Status register */ return s->events; case OWER: return s->reset3; @@ -336,7 +336,7 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset, case OIER: s->irq_enabled = value & 0xfff; break; - case OSSR: /* Status register */ + case OSSR: /* Status register */ value &= s->events; s->events &= ~value; for (i = 0; i < 4; i ++, value >>= 1) @@ -345,7 +345,7 @@ static void pxa2xx_timer_write(void *opaque, hwaddr offset, if (pxa2xx_timer_has_tm4(s) && !(s->events & 0xff0) && value) qemu_irq_lower(s->irq4); break; - case OWER: /* XXX: Reset on OSMR3 match? */ + case OWER: /* XXX: Reset on OSMR3 match? */ s->reset3 = value; break; case OMCR7: tm ++; @@ -555,7 +555,7 @@ static const Property pxa25x_timer_dev_properties[] = { PXA2XX_TIMER_HAVE_TM4, false), }; -static void pxa25x_timer_dev_class_init(ObjectClass *klass, void *data) +static void pxa25x_timer_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -570,7 +570,7 @@ static const TypeInfo pxa25x_timer_dev_info = { .class_init = pxa25x_timer_dev_class_init, }; -static void pxa2xx_timer_class_init(ObjectClass *oc, void *data) +static void pxa2xx_timer_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/timer/renesas_cmt.c b/hw/timer/renesas_cmt.c index 93e7f58..cdff7f4 100644 --- a/hw/timer/renesas_cmt.c +++ b/hw/timer/renesas_cmt.c @@ -257,7 +257,7 @@ static const Property rcmt_properties[] = { DEFINE_PROP_UINT64("input-freq", RCMTState, input_freq, 0), }; -static void rcmt_class_init(ObjectClass *klass, void *data) +static void rcmt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/renesas_tmr.c b/hw/timer/renesas_tmr.c index 884349c..95707f2 100644 --- a/hw/timer/renesas_tmr.c +++ b/hw/timer/renesas_tmr.c @@ -467,7 +467,7 @@ static const Property rtmr_properties[] = { DEFINE_PROP_UINT64("input-freq", RTMRState, input_freq, 0), }; -static void rtmr_class_init(ObjectClass *klass, void *data) +static void rtmr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/sh_timer.c b/hw/timer/sh_timer.c index 7788939..d4fa32c 100644 --- a/hw/timer/sh_timer.c +++ b/hw/timer/sh_timer.c @@ -9,7 +9,7 @@ */ #include "qemu/osdep.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/log.h" #include "hw/irq.h" #include "hw/sh4/sh.h" diff --git a/hw/timer/sifive_pwm.c b/hw/timer/sifive_pwm.c index fc796e9..e85e389 100644 --- a/hw/timer/sifive_pwm.c +++ b/hw/timer/sifive_pwm.c @@ -441,7 +441,7 @@ static void sifive_pwm_realize(DeviceState *dev, Error **errp) sifive_pwm_interrupt_3, s); } -static void sifive_pwm_class_init(ObjectClass *klass, void *data) +static void sifive_pwm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/slavio_timer.c b/hw/timer/slavio_timer.c index 65b24e4..3e071fb 100644 --- a/hw/timer/slavio_timer.c +++ b/hw/timer/slavio_timer.c @@ -424,7 +424,7 @@ static const Property slavio_timer_properties[] = { DEFINE_PROP_UINT32("num_cpus", SLAVIO_TIMERState, num_cpus, 0), }; -static void slavio_timer_class_init(ObjectClass *klass, void *data) +static void slavio_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/sse-counter.c b/hw/timer/sse-counter.c index f17064a..31f77ac 100644 --- a/hw/timer/sse-counter.c +++ b/hw/timer/sse-counter.c @@ -448,7 +448,7 @@ static const VMStateDescription sse_counter_vmstate = { } }; -static void sse_counter_class_init(ObjectClass *klass, void *data) +static void sse_counter_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/sse-timer.c b/hw/timer/sse-timer.c index e106739..866d5ee 100644 --- a/hw/timer/sse-timer.c +++ b/hw/timer/sse-timer.c @@ -444,7 +444,7 @@ static const Property sse_timer_properties[] = { DEFINE_PROP_LINK("counter", SSETimer, counter, TYPE_SSE_COUNTER, SSECounter *), }; -static void sse_timer_class_init(ObjectClass *klass, void *data) +static void sse_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/stellaris-gptm.c b/hw/timer/stellaris-gptm.c index f28958c..d97b2f8 100644 --- a/hw/timer/stellaris-gptm.c +++ b/hw/timer/stellaris-gptm.c @@ -308,7 +308,7 @@ static void stellaris_gptm_realize(DeviceState *dev, Error **errp) s->timer[1] = timer_new_ns(QEMU_CLOCK_VIRTUAL, gptm_tick, &s->opaque[1]); } -static void stellaris_gptm_class_init(ObjectClass *klass, void *data) +static void stellaris_gptm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c index 4707190..be844e7 100644 --- a/hw/timer/stm32f2xx_timer.c +++ b/hw/timer/stm32f2xx_timer.c @@ -320,7 +320,7 @@ static void stm32f2xx_timer_realize(DeviceState *dev, Error **errp) s->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, stm32f2xx_timer_interrupt, s); } -static void stm32f2xx_timer_class_init(ObjectClass *klass, void *data) +static void stm32f2xx_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/timer/xilinx_timer.c b/hw/timer/xilinx_timer.c index 4620528..ff4a224 100644 --- a/hw/timer/xilinx_timer.c +++ b/hw/timer/xilinx_timer.c @@ -268,7 +268,7 @@ static const Property xilinx_timer_properties[] = { DEFINE_PROP_UINT8("one-timer-only", XpsTimerState, one_timer_only, 0), }; -static void xilinx_timer_class_init(ObjectClass *klass, void *data) +static void xilinx_timer_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/tpm/tpm_crb.c b/hw/tpm/tpm_crb.c index 6cdeb72..bc7a78f 100644 --- a/hw/tpm/tpm_crb.c +++ b/hw/tpm/tpm_crb.c @@ -18,7 +18,7 @@ #include "qemu/module.h" #include "qapi/error.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "hw/qdev-properties.h" #include "hw/pci/pci_ids.h" #include "hw/acpi/tpm.h" @@ -315,7 +315,7 @@ static void tpm_crb_realize(DeviceState *dev, Error **errp) } } -static void tpm_crb_class_init(ObjectClass *klass, void *data) +static void tpm_crb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); TPMIfClass *tc = TPM_IF_CLASS(klass); @@ -337,7 +337,7 @@ static const TypeInfo tpm_crb_info = { .parent = TYPE_DEVICE, .instance_size = sizeof(CRBState), .class_init = tpm_crb_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_TPM_IF }, { } } diff --git a/hw/tpm/tpm_ppi.h b/hw/tpm/tpm_ppi.h index bf5d4a3..88f316e 100644 --- a/hw/tpm/tpm_ppi.h +++ b/hw/tpm/tpm_ppi.h @@ -12,7 +12,7 @@ #ifndef TPM_TPM_PPI_H #define TPM_TPM_PPI_H -#include "exec/memory.h" +#include "system/memory.h" typedef struct TPMPPI { MemoryRegion ram; diff --git a/hw/tpm/tpm_spapr.c b/hw/tpm/tpm_spapr.c index 9a031e1..ea608ba 100644 --- a/hw/tpm/tpm_spapr.c +++ b/hw/tpm/tpm_spapr.c @@ -387,7 +387,7 @@ static void tpm_spapr_realizefn(SpaprVioDevice *dev, Error **errp) s->buffer = g_malloc(TPM_SPAPR_BUFFER_MAX); } -static void tpm_spapr_class_init(ObjectClass *klass, void *data) +static void tpm_spapr_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass); @@ -414,7 +414,7 @@ static const TypeInfo tpm_spapr_info = { .parent = TYPE_VIO_SPAPR_DEVICE, .instance_size = sizeof(SpaprTpmState), .class_init = tpm_spapr_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_TPM_IF }, { } } diff --git a/hw/tpm/tpm_tis_i2c.c b/hw/tpm/tpm_tis_i2c.c index 92d3de1..5ce84dc 100644 --- a/hw/tpm/tpm_tis_i2c.c +++ b/hw/tpm/tpm_tis_i2c.c @@ -526,7 +526,7 @@ static void tpm_tis_i2c_reset(DeviceState *dev) return tpm_tis_reset(s); } -static void tpm_tis_i2c_class_init(ObjectClass *klass, void *data) +static void tpm_tis_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); I2CSlaveClass *k = I2C_SLAVE_CLASS(klass); @@ -552,7 +552,7 @@ static const TypeInfo tpm_tis_i2c_info = { .parent = TYPE_I2C_SLAVE, .instance_size = sizeof(TPMStateI2C), .class_init = tpm_tis_i2c_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_TPM_IF }, { } } diff --git a/hw/tpm/tpm_tis_isa.c b/hw/tpm/tpm_tis_isa.c index 876cb02..dce8305 100644 --- a/hw/tpm/tpm_tis_isa.c +++ b/hw/tpm/tpm_tis_isa.c @@ -166,7 +166,7 @@ static void build_tpm_tis_isa_aml(AcpiDevAmlIf *adev, Aml *scope) aml_append(scope, dev); } -static void tpm_tis_isa_class_init(ObjectClass *klass, void *data) +static void tpm_tis_isa_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); TPMIfClass *tc = TPM_IF_CLASS(klass); @@ -189,7 +189,7 @@ static const TypeInfo tpm_tis_isa_info = { .instance_size = sizeof(TPMStateISA), .instance_init = tpm_tis_isa_initfn, .class_init = tpm_tis_isa_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_TPM_IF }, { TYPE_ACPI_DEV_AML_IF }, { } diff --git a/hw/tpm/tpm_tis_sysbus.c b/hw/tpm/tpm_tis_sysbus.c index 4f18769..2ffa858 100644 --- a/hw/tpm/tpm_tis_sysbus.c +++ b/hw/tpm/tpm_tis_sysbus.c @@ -124,7 +124,7 @@ static void tpm_tis_sysbus_realizefn(DeviceState *dev, Error **errp) } } -static void tpm_tis_sysbus_class_init(ObjectClass *klass, void *data) +static void tpm_tis_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); TPMIfClass *tc = TPM_IF_CLASS(klass); @@ -145,7 +145,7 @@ static const TypeInfo tpm_tis_sysbus_info = { .instance_size = sizeof(TPMStateSysBus), .instance_init = tpm_tis_sysbus_initfn, .class_init = tpm_tis_sysbus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_TPM_IF }, { } } diff --git a/hw/tricore/tc27x_soc.c b/hw/tricore/tc27x_soc.c index 81bb16d..f3b8498 100644 --- a/hw/tricore/tc27x_soc.c +++ b/hw/tricore/tc27x_soc.c @@ -201,14 +201,14 @@ static void tc27x_soc_init(Object *obj) object_initialize_child(obj, "tc27x", &s->cpu, sc->cpu_type); } -static void tc27x_soc_class_init(ObjectClass *klass, void *data) +static void tc27x_soc_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = tc27x_soc_realize; } -static void tc277d_soc_class_init(ObjectClass *oc, void *data) +static void tc277d_soc_class_init(ObjectClass *oc, const void *data) { TC27XSoCClass *sc = TC27X_SOC_CLASS(oc); diff --git a/hw/tricore/triboard.c b/hw/tricore/triboard.c index f5baa8c..cb45b01 100644 --- a/hw/tricore/triboard.c +++ b/hw/tricore/triboard.c @@ -65,7 +65,7 @@ static void triboard_machine_init(MachineState *machine) } static void triboard_machine_tc277d_class_init(ObjectClass *oc, - void *data) + const void *data) { MachineClass *mc = MACHINE_CLASS(oc); TriBoardMachineClass *amc = TRIBOARD_MACHINE_CLASS(oc); diff --git a/hw/tricore/tricore_testdevice.c b/hw/tricore/tricore_testdevice.c index d2da74e..e8daf95 100644 --- a/hw/tricore/tricore_testdevice.c +++ b/hw/tricore/tricore_testdevice.c @@ -58,7 +58,7 @@ static void tricore_testdevice_init(Object *obj) "tricore_testdevice", 0x4); } -static void tricore_testdevice_class_init(ObjectClass *klass, void *data) +static void tricore_testdevice_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/uefi/var-service-sysbus.c b/hw/uefi/var-service-sysbus.c index 97da867..a5aa218 100644 --- a/hw/uefi/var-service-sysbus.c +++ b/hw/uefi/var-service-sysbus.c @@ -64,7 +64,7 @@ static void uefi_vars_sysbus_realize(DeviceState *dev, Error **errp) uefi_vars_realize(&uv->state, errp); } -static void uefi_vars_sysbus_class_init(ObjectClass *klass, void *data) +static void uefi_vars_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -100,7 +100,7 @@ static void uefi_vars_x64_realize(DeviceState *dev, Error **errp) sysbus_mmio_map(sysbus, 0, hwinfo.mmio_address); } -static void uefi_vars_x64_class_init(ObjectClass *klass, void *data) +static void uefi_vars_x64_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/ufs/lu.c b/hw/ufs/lu.c index 1c3794b..2d8ffd7 100644 --- a/hw/ufs/lu.c +++ b/hw/ufs/lu.c @@ -194,7 +194,7 @@ static int ufs_emulate_wlun_inquiry(UfsRequest *req, uint8_t *outbuf, static UfsReqResult ufs_emulate_scsi_cmd(UfsLu *lu, UfsRequest *req) { uint8_t lun = lu->lun; - uint8_t outbuf[4096]; + QEMU_UNINITIALIZED uint8_t outbuf[4096]; uint8_t sense_buf[UFS_SENSE_SIZE]; uint8_t scsi_status; int len = 0; @@ -419,7 +419,7 @@ static void ufs_lu_unrealize(DeviceState *dev) } } -static void ufs_lu_class_init(ObjectClass *oc, void *data) +static void ufs_lu_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/ufs/ufs.c b/hw/ufs/ufs.c index 542f13b..0577747 100644 --- a/hw/ufs/ufs.c +++ b/hw/ufs/ufs.c @@ -1844,7 +1844,7 @@ static const VMStateDescription ufs_vmstate = { .unmigratable = 1, }; -static void ufs_class_init(ObjectClass *oc, void *data) +static void ufs_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PCIDeviceClass *pc = PCI_DEVICE_CLASS(oc); @@ -1880,7 +1880,7 @@ static char *ufs_bus_get_dev_path(DeviceState *dev) return qdev_get_dev_path(bus->parent); } -static void ufs_bus_class_init(ObjectClass *class, void *data) +static void ufs_bus_class_init(ObjectClass *class, const void *data) { BusClass *bc = BUS_CLASS(class); bc->get_dev_path = ufs_bus_get_dev_path; @@ -1892,7 +1892,7 @@ static const TypeInfo ufs_info = { .parent = TYPE_PCI_DEVICE, .class_init = ufs_class_init, .instance_size = sizeof(UfsHc), - .interfaces = (InterfaceInfo[]){ { INTERFACE_PCIE_DEVICE }, {} }, + .interfaces = (const InterfaceInfo[]){ { INTERFACE_PCIE_DEVICE }, {} }, }; static const TypeInfo ufs_bus_info = { diff --git a/hw/usb/bus.c b/hw/usb/bus.c index f45b82c..8dd2ce4 100644 --- a/hw/usb/bus.c +++ b/hw/usb/bus.c @@ -26,7 +26,7 @@ static const Property usb_props[] = { DEFINE_PROP_STRING("pcap", USBDevice, pcap_filename), }; -static void usb_bus_class_init(ObjectClass *klass, void *data) +static void usb_bus_class_init(ObjectClass *klass, const void *data) { BusClass *k = BUS_CLASS(klass); HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); @@ -42,7 +42,7 @@ static const TypeInfo usb_bus_info = { .parent = TYPE_BUS, .instance_size = sizeof(USBBus), .class_init = usb_bus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } @@ -713,7 +713,7 @@ static void usb_device_instance_init(Object *obj) } } -static void usb_device_class_init(ObjectClass *klass, void *data) +static void usb_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->bus_type = TYPE_USB_BUS; diff --git a/hw/usb/canokey.c b/hw/usb/canokey.c index e2d6617..cbefbb5 100644 --- a/hw/usb/canokey.c +++ b/hw/usb/canokey.c @@ -300,7 +300,7 @@ static const Property canokey_properties[] = { DEFINE_PROP_STRING("file", CanoKeyState, file), }; -static void canokey_class_init(ObjectClass *klass, void *data) +static void canokey_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/ccid-card-emulated.c b/hw/usb/ccid-card-emulated.c index b1e330f..c21cefd 100644 --- a/hw/usb/ccid-card-emulated.c +++ b/hw/usb/ccid-card-emulated.c @@ -591,7 +591,7 @@ static const Property emulated_card_properties[] = { DEFINE_PROP_UINT8("debug", EmulatedState, debug, 0), }; -static void emulated_class_initfn(ObjectClass *klass, void *data) +static void emulated_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); CCIDCardClass *cc = CCID_CARD_CLASS(klass); diff --git a/hw/usb/ccid-card-passthru.c b/hw/usb/ccid-card-passthru.c index bf81485..1eea21a 100644 --- a/hw/usb/ccid-card-passthru.c +++ b/hw/usb/ccid-card-passthru.c @@ -393,7 +393,7 @@ static const Property passthru_card_properties[] = { DEFINE_PROP_UINT8("debug", PassthruState, debug, 0), }; -static void passthru_class_initfn(ObjectClass *klass, void *data) +static void passthru_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); CCIDCardClass *cc = CCID_CARD_CLASS(klass); diff --git a/hw/usb/chipidea.c b/hw/usb/chipidea.c index b1c8540..250c2b3 100644 --- a/hw/usb/chipidea.c +++ b/hw/usb/chipidea.c @@ -144,7 +144,7 @@ static void chipidea_init(Object *obj) } } -static void chipidea_class_init(ObjectClass *klass, void *data) +static void chipidea_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass); diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c index 40f0312..26af709 100644 --- a/hw/usb/dev-audio.c +++ b/hw/usb/dev-audio.c @@ -997,7 +997,7 @@ static const Property usb_audio_properties[] = { DEFINE_PROP_BOOL("multi", USBAudioState, multi, false), }; -static void usb_audio_class_init(ObjectClass *klass, void *data) +static void usb_audio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *k = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-hid.c b/hw/usb/dev-hid.c index accdd46..54d064e 100644 --- a/hw/usb/dev-hid.c +++ b/hw/usb/dev-hid.c @@ -774,7 +774,7 @@ static const VMStateDescription vmstate_usb_kbd = { } }; -static void usb_hid_class_initfn(ObjectClass *klass, void *data) +static void usb_hid_class_initfn(ObjectClass *klass, const void *data) { USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -799,7 +799,7 @@ static const Property usb_tablet_properties[] = { DEFINE_PROP_UINT32("head", USBHIDState, head, 0), }; -static void usb_tablet_class_initfn(ObjectClass *klass, void *data) +static void usb_tablet_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -821,7 +821,7 @@ static const Property usb_mouse_properties[] = { DEFINE_PROP_UINT32("usb_version", USBHIDState, usb_version, 2), }; -static void usb_mouse_class_initfn(ObjectClass *klass, void *data) +static void usb_mouse_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -844,7 +844,7 @@ static const Property usb_keyboard_properties[] = { DEFINE_PROP_STRING("display", USBHIDState, display), }; -static void usb_keyboard_class_initfn(ObjectClass *klass, void *data) +static void usb_keyboard_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-hub.c b/hw/usb/dev-hub.c index 3880e2a..a19350d 100644 --- a/hw/usb/dev-hub.c +++ b/hw/usb/dev-hub.c @@ -670,7 +670,7 @@ static const Property usb_hub_properties[] = { DEFINE_PROP_BOOL("port-power", USBHubState, port_power, false), }; -static void usb_hub_class_initfn(ObjectClass *klass, void *data) +static void usb_hub_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c index 4cd14c3..ce45c9c 100644 --- a/hw/usb/dev-mtp.c +++ b/hw/usb/dev-mtp.c @@ -2082,7 +2082,7 @@ static const Property mtp_properties[] = { DEFINE_PROP_BOOL("readonly", MTPState, readonly, true), }; -static void usb_mtp_class_initfn(ObjectClass *klass, void *data) +static void usb_mtp_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c index a87a0ff..81cc09d 100644 --- a/hw/usb/dev-network.c +++ b/hw/usb/dev-network.c @@ -1411,7 +1411,7 @@ static const Property net_properties[] = { DEFINE_NIC_PROPERTIES(USBNetState, conf), }; -static void usb_net_class_initfn(ObjectClass *klass, void *data) +static void usb_net_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-serial.c b/hw/usb/dev-serial.c index 31f6cf5..1c116d8 100644 --- a/hw/usb/dev-serial.c +++ b/hw/usb/dev-serial.c @@ -637,7 +637,7 @@ static const Property serial_properties[] = { DEFINE_PROP_BOOL("always-plugged", USBSerialState, always_plugged, false), }; -static void usb_serial_dev_class_init(ObjectClass *klass, void *data) +static void usb_serial_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -658,7 +658,7 @@ static const TypeInfo usb_serial_dev_type_info = { .class_init = usb_serial_dev_class_init, }; -static void usb_serial_class_initfn(ObjectClass *klass, void *data) +static void usb_serial_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -678,7 +678,7 @@ static const Property braille_properties[] = { DEFINE_PROP_CHR("chardev", USBSerialState, cs), }; -static void usb_braille_class_initfn(ObjectClass *klass, void *data) +static void usb_braille_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c index 84ca8c4..6ce7154 100644 --- a/hw/usb/dev-smartcard-reader.c +++ b/hw/usb/dev-smartcard-reader.c @@ -1433,7 +1433,7 @@ static const Property ccid_properties[] = { DEFINE_PROP_UINT8("debug", USBCCIDState, debug, 0), }; -static void ccid_class_initfn(ObjectClass *klass, void *data) +static void ccid_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); @@ -1458,13 +1458,13 @@ static const TypeInfo ccid_info = { .parent = TYPE_USB_DEVICE, .instance_size = sizeof(USBCCIDState), .class_init = ccid_class_initfn, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } }; -static void ccid_card_class_init(ObjectClass *klass, void *data) +static void ccid_card_class_init(ObjectClass *klass, const void *data) { DeviceClass *k = DEVICE_CLASS(klass); k->bus_type = TYPE_CCID_BUS; diff --git a/hw/usb/dev-storage-bot.c b/hw/usb/dev-storage-bot.c index 1e5c5c7..df6ab7f 100644 --- a/hw/usb/dev-storage-bot.c +++ b/hw/usb/dev-storage-bot.c @@ -40,7 +40,7 @@ static void usb_msd_bot_realize(USBDevice *dev, Error **errp) usb_msd_handle_reset(dev); } -static void usb_msd_class_bot_initfn(ObjectClass *klass, void *data) +static void usb_msd_class_bot_initfn(ObjectClass *klass, const void *data) { USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-storage-classic.c b/hw/usb/dev-storage-classic.c index 56ef39d..dabe156 100644 --- a/hw/usb/dev-storage-classic.c +++ b/hw/usb/dev-storage-classic.c @@ -74,7 +74,7 @@ static const Property msd_properties[] = { DEFINE_PROP_BOOL("commandlog", MSDState, commandlog, false), }; -static void usb_msd_class_storage_initfn(ObjectClass *klass, void *data) +static void usb_msd_class_storage_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c index 4f1e8b7..b13fe34 100644 --- a/hw/usb/dev-storage.c +++ b/hw/usb/dev-storage.c @@ -585,7 +585,7 @@ static const VMStateDescription vmstate_usb_msd = { } }; -static void usb_msd_class_initfn_common(ObjectClass *klass, void *data) +static void usb_msd_class_initfn_common(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c index b1d6b6e..21cc283 100644 --- a/hw/usb/dev-uas.c +++ b/hw/usb/dev-uas.c @@ -956,7 +956,7 @@ static const Property uas_properties[] = { DEFINE_PROP_UINT32("log-scsi-req", UASDevice, requestlog, 0), }; -static void usb_uas_class_initfn(ObjectClass *klass, void *data) +static void usb_uas_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/dev-wacom.c b/hw/usb/dev-wacom.c index 7177c17..f4b71a2 100644 --- a/hw/usb/dev-wacom.c +++ b/hw/usb/dev-wacom.c @@ -420,7 +420,7 @@ static const VMStateDescription vmstate_usb_wacom = { .unmigratable = 1, }; -static void usb_wacom_class_init(ObjectClass *klass, void *data) +static void usb_wacom_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-dwc2.c b/hw/usb/hcd-dwc2.c index e815271..8386450 100644 --- a/hw/usb/hcd-dwc2.c +++ b/hw/usb/hcd-dwc2.c @@ -1452,7 +1452,7 @@ static const Property dwc2_usb_properties[] = { DEFINE_PROP_UINT32("usb_version", DWC2State, usb_version, 2), }; -static void dwc2_class_init(ObjectClass *klass, void *data) +static void dwc2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); DWC2Class *c = DWC2_USB_CLASS(klass); diff --git a/hw/usb/hcd-dwc3.c b/hw/usb/hcd-dwc3.c index 0bceee2..98a342b 100644 --- a/hw/usb/hcd-dwc3.c +++ b/hw/usb/hcd-dwc3.c @@ -666,7 +666,7 @@ static const Property usb_dwc3_properties[] = { 0x12345678), }; -static void usb_dwc3_class_init(ObjectClass *klass, void *data) +static void usb_dwc3_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-ehci-pci.c b/hw/usb/hcd-ehci-pci.c index e003167..38ad340 100644 --- a/hw/usb/hcd-ehci-pci.c +++ b/hw/usb/hcd-ehci-pci.c @@ -150,7 +150,7 @@ static const VMStateDescription vmstate_ehci_pci = { } }; -static void ehci_class_init(ObjectClass *klass, void *data) +static void ehci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -172,13 +172,13 @@ static const TypeInfo ehci_pci_type_info = { .instance_finalize = usb_ehci_pci_finalize, .abstract = true, .class_init = ehci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -static void ehci_data_class_init(ObjectClass *klass, void *data) +static void ehci_data_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-ehci-sysbus.c b/hw/usb/hcd-ehci-sysbus.c index 768c3dd..0449f5f 100644 --- a/hw/usb/hcd-ehci-sysbus.c +++ b/hw/usb/hcd-ehci-sysbus.c @@ -80,7 +80,7 @@ static void ehci_sysbus_finalize(Object *obj) usb_ehci_finalize(s); } -static void ehci_sysbus_class_init(ObjectClass *klass, void *data) +static void ehci_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(klass); @@ -95,7 +95,7 @@ static void ehci_sysbus_class_init(ObjectClass *klass, void *data) set_bit(DEVICE_CATEGORY_USB, dc->categories); } -static void ehci_platform_class_init(ObjectClass *oc, void *data) +static void ehci_platform_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -105,7 +105,7 @@ static void ehci_platform_class_init(ObjectClass *oc, void *data) set_bit(DEVICE_CATEGORY_USB, dc->categories); } -static void ehci_exynos4210_class_init(ObjectClass *oc, void *data) +static void ehci_exynos4210_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -115,7 +115,7 @@ static void ehci_exynos4210_class_init(ObjectClass *oc, void *data) set_bit(DEVICE_CATEGORY_USB, dc->categories); } -static void ehci_aw_h3_class_init(ObjectClass *oc, void *data) +static void ehci_aw_h3_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -125,7 +125,7 @@ static void ehci_aw_h3_class_init(ObjectClass *oc, void *data) set_bit(DEVICE_CATEGORY_USB, dc->categories); } -static void ehci_npcm7xx_class_init(ObjectClass *oc, void *data) +static void ehci_npcm7xx_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -137,7 +137,7 @@ static void ehci_npcm7xx_class_init(ObjectClass *oc, void *data) set_bit(DEVICE_CATEGORY_USB, dc->categories); } -static void ehci_tegra2_class_init(ObjectClass *oc, void *data) +static void ehci_tegra2_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -154,7 +154,7 @@ static void ehci_ppc4xx_init(Object *o) s->ehci.companion_enable = true; } -static void ehci_ppc4xx_class_init(ObjectClass *oc, void *data) +static void ehci_ppc4xx_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); @@ -220,7 +220,7 @@ static void fusbh200_ehci_init(Object *obj) &f->mem_vendor); } -static void fusbh200_ehci_class_init(ObjectClass *oc, void *data) +static void fusbh200_ehci_class_init(ObjectClass *oc, const void *data) { SysBusEHCIClass *sec = SYS_BUS_EHCI_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/usb/hcd-ohci-pci.c b/hw/usb/hcd-ohci-pci.c index b3684a2..94d1077 100644 --- a/hw/usb/hcd-ohci-pci.c +++ b/hw/usb/hcd-ohci-pci.c @@ -126,7 +126,7 @@ static const VMStateDescription vmstate_ohci = { } }; -static void ohci_pci_class_init(ObjectClass *klass, void *data) +static void ohci_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -149,7 +149,7 @@ static const TypeInfo ohci_pci_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(OHCIPCIState), .class_init = ohci_pci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/usb/hcd-ohci-sysbus.c b/hw/usb/hcd-ohci-sysbus.c index 1531194..3fc6cce 100644 --- a/hw/usb/hcd-ohci-sysbus.c +++ b/hw/usb/hcd-ohci-sysbus.c @@ -64,7 +64,7 @@ static const Property ohci_sysbus_properties[] = { DEFINE_PROP_DMAADDR("dma-offset", OHCISysBusState, dma_offset, 0), }; -static void ohci_sysbus_class_init(ObjectClass *klass, void *data) +static void ohci_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c index 71b5491..72a9f9f 100644 --- a/hw/usb/hcd-ohci.c +++ b/hw/usb/hcd-ohci.c @@ -577,7 +577,7 @@ static int ohci_service_iso_td(OHCIState *ohci, struct ohci_ed *ed) USBDevice *dev; USBEndpoint *ep; USBPacket *pkt; - uint8_t buf[8192]; + QEMU_UNINITIALIZED uint8_t buf[8192]; bool int_req; struct ohci_iso_td iso_td; uint32_t addr; diff --git a/hw/usb/hcd-uhci.c b/hw/usb/hcd-uhci.c index 0561a6d..4822c70 100644 --- a/hw/usb/hcd-uhci.c +++ b/hw/usb/hcd-uhci.c @@ -1260,7 +1260,7 @@ static const Property uhci_properties_standalone[] = { DEFINE_PROP_UINT32("maxframes", UHCIState, maxframes, 128), }; -static void uhci_class_init(ObjectClass *klass, void *data) +static void uhci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1278,13 +1278,13 @@ static const TypeInfo uhci_pci_type_info = { .class_size = sizeof(UHCIPCIDeviceClass), .abstract = true, .class_init = uhci_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, }; -void uhci_data_class_init(ObjectClass *klass, void *data) +void uhci_data_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-uhci.h b/hw/usb/hcd-uhci.h index 6d26b94..e0a6525 100644 --- a/hw/usb/hcd-uhci.h +++ b/hw/usb/hcd-uhci.h @@ -28,7 +28,7 @@ #ifndef HW_USB_HCD_UHCI_H #define HW_USB_HCD_UHCI_H -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/timer.h" #include "hw/pci/pci_device.h" #include "hw/usb.h" @@ -88,7 +88,7 @@ typedef struct UHCIInfo { bool notuser; /* disallow user_creatable */ } UHCIInfo; -void uhci_data_class_init(ObjectClass *klass, void *data); +void uhci_data_class_init(ObjectClass *klass, const void *data); void usb_uhci_common_realize(PCIDevice *dev, Error **errp); #define TYPE_PIIX3_USB_UHCI "piix3-usb-uhci" diff --git a/hw/usb/hcd-xhci-nec.c b/hw/usb/hcd-xhci-nec.c index 1df518b..9e0fea2 100644 --- a/hw/usb/hcd-xhci-nec.c +++ b/hw/usb/hcd-xhci-nec.c @@ -50,7 +50,7 @@ static void nec_xhci_instance_init(Object *obj) pci->xhci.numslots = nec->slots; } -static void nec_xhci_class_init(ObjectClass *klass, void *data) +static void nec_xhci_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-xhci-pci.c b/hw/usb/hcd-xhci-pci.c index d908eb7..b93c80b 100644 --- a/hw/usb/hcd-xhci-pci.c +++ b/hw/usb/hcd-xhci-pci.c @@ -223,7 +223,7 @@ static const Property xhci_pci_properties[] = { conditional_intr_mapping, false), }; -static void xhci_class_init(ObjectClass *klass, void *data) +static void xhci_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); @@ -248,14 +248,14 @@ static const TypeInfo xhci_pci_info = { .class_init = xhci_class_init, .instance_init = xhci_instance_init, .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } }, }; -static void qemu_xhci_class_init(ObjectClass *klass, void *data) +static void qemu_xhci_class_init(ObjectClass *klass, const void *data) { PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-xhci-sysbus.c b/hw/usb/hcd-xhci-sysbus.c index ce43322..244698e 100644 --- a/hw/usb/hcd-xhci-sysbus.c +++ b/hw/usb/hcd-xhci-sysbus.c @@ -96,7 +96,7 @@ static const VMStateDescription vmstate_xhci_sysbus = { } }; -static void xhci_sysbus_class_init(ObjectClass *klass, void *data) +static void xhci_sysbus_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c index 64c3a23..292c378 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1187,6 +1187,12 @@ static void xhci_ep_free_xfer(XHCITransfer *xfer) g_free(xfer); } +static void xhci_xfer_unmap(XHCITransfer *xfer) +{ + usb_packet_unmap(&xfer->packet, &xfer->sgl); + qemu_sglist_destroy(&xfer->sgl); +} + static int xhci_ep_nuke_one_xfer(XHCITransfer *t, TRBCCode report) { int killed = 0; @@ -1198,6 +1204,7 @@ static int xhci_ep_nuke_one_xfer(XHCITransfer *t, TRBCCode report) if (t->running_async) { usb_cancel_packet(&t->packet); + xhci_xfer_unmap(t); t->running_async = 0; killed = 1; } @@ -1480,12 +1487,6 @@ err: return -1; } -static void xhci_xfer_unmap(XHCITransfer *xfer) -{ - usb_packet_unmap(&xfer->packet, &xfer->sgl); - qemu_sglist_destroy(&xfer->sgl); -} - static void xhci_xfer_report(XHCITransfer *xfer) { uint32_t edtla = 0; @@ -3638,7 +3639,7 @@ static const Property xhci_properties[] = { DeviceState *), }; -static void xhci_class_init(ObjectClass *klass, void *data) +static void xhci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c index c3d642c..b74670a 100644 --- a/hw/usb/host-libusb.c +++ b/hw/usb/host-libusb.c @@ -1781,7 +1781,7 @@ static const Property usb_host_dev_properties[] = { suppress_remote_wake, true), }; -static void usb_host_class_initfn(ObjectClass *klass, void *data) +static void usb_host_class_initfn(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/imx-usb-phy.c b/hw/usb/imx-usb-phy.c index f519250..c25566d 100644 --- a/hw/usb/imx-usb-phy.c +++ b/hw/usb/imx-usb-phy.c @@ -214,7 +214,7 @@ static void imx_usbphy_realize(DeviceState *dev, Error **errp) sysbus_init_mmio(SYS_BUS_DEVICE(s), &s->iomem); } -static void imx_usbphy_class_init(ObjectClass *klass, void *data) +static void imx_usbphy_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c index f3a83b3..f516ff4 100644 --- a/hw/usb/redirect.c +++ b/hw/usb/redirect.c @@ -2582,7 +2582,7 @@ static const Property usbredir_properties[] = { suppress_remote_wake, true), }; -static void usbredir_class_initfn(ObjectClass *klass, void *data) +static void usbredir_class_initfn(ObjectClass *klass, const void *data) { USBDeviceClass *uc = USB_DEVICE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/u2f-emulated.c b/hw/usb/u2f-emulated.c index e1dd19e..ace5ece 100644 --- a/hw/usb/u2f-emulated.c +++ b/hw/usb/u2f-emulated.c @@ -377,7 +377,7 @@ static const Property u2f_emulated_properties[] = { DEFINE_PROP_STRING("counter", U2FEmulatedState, counter), }; -static void u2f_emulated_class_init(ObjectClass *klass, void *data) +static void u2f_emulated_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); U2FKeyClass *kc = U2F_KEY_CLASS(klass); diff --git a/hw/usb/u2f-passthru.c b/hw/usb/u2f-passthru.c index 8df5215..fa8d9cd 100644 --- a/hw/usb/u2f-passthru.c +++ b/hw/usb/u2f-passthru.c @@ -520,7 +520,7 @@ static const Property u2f_passthru_properties[] = { DEFINE_PROP_STRING("hidraw", U2FPassthruState, hidraw), }; -static void u2f_passthru_class_init(ObjectClass *klass, void *data) +static void u2f_passthru_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); U2FKeyClass *kc = U2F_KEY_CLASS(klass); diff --git a/hw/usb/u2f.c b/hw/usb/u2f.c index 1fb59cf..b051a99 100644 --- a/hw/usb/u2f.c +++ b/hw/usb/u2f.c @@ -317,7 +317,7 @@ const VMStateDescription vmstate_u2f_key = { } }; -static void u2f_key_class_init(ObjectClass *klass, void *data) +static void u2f_key_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); USBDeviceClass *uc = USB_DEVICE_CLASS(klass); diff --git a/hw/usb/xlnx-usb-subsystem.c b/hw/usb/xlnx-usb-subsystem.c index d8deeb6..98967ef 100644 --- a/hw/usb/xlnx-usb-subsystem.c +++ b/hw/usb/xlnx-usb-subsystem.c @@ -69,7 +69,7 @@ static void versal_usb2_init(Object *obj) object_property_add_alias(obj, "dma", OBJECT(&s->dwc3.sysbus_xhci), "dma"); } -static void versal_usb2_class_init(ObjectClass *klass, void *data) +static void versal_usb2_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/usb/xlnx-versal-usb2-ctrl-regs.c b/hw/usb/xlnx-versal-usb2-ctrl-regs.c index 66c793a..4114672 100644 --- a/hw/usb/xlnx-versal-usb2-ctrl-regs.c +++ b/hw/usb/xlnx-versal-usb2-ctrl-regs.c @@ -202,7 +202,7 @@ static const VMStateDescription vmstate_usb2_ctrl_regs = { } }; -static void usb2_ctrl_regs_class_init(ObjectClass *klass, void *data) +static void usb2_ctrl_regs_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/vfio-user/Kconfig b/hw/vfio-user/Kconfig new file mode 100644 index 0000000..24bdf7a --- /dev/null +++ b/hw/vfio-user/Kconfig @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +config VFIO_USER + bool + default y + depends on VFIO_PCI + diff --git a/hw/vfio-user/container.c b/hw/vfio-user/container.c new file mode 100644 index 0000000..3133fef --- /dev/null +++ b/hw/vfio-user/container.c @@ -0,0 +1,370 @@ +/* + * Container for vfio-user IOMMU type: rather than communicating with the kernel + * vfio driver, we communicate over a socket to a server using the vfio-user + * protocol. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <sys/ioctl.h> +#include <linux/vfio.h> +#include "qemu/osdep.h" + +#include "hw/vfio-user/container.h" +#include "hw/vfio-user/device.h" +#include "hw/vfio-user/trace.h" +#include "hw/vfio/vfio-cpr.h" +#include "hw/vfio/vfio-device.h" +#include "hw/vfio/vfio-listener.h" +#include "qapi/error.h" + +/* + * When DMA space is the physical address space, the region add/del listeners + * will fire during memory update transactions. These depend on BQL being held, + * so do any resulting map/demap ops async while keeping BQL. + */ +static void vfio_user_listener_begin(VFIOContainerBase *bcontainer) +{ + VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer, + bcontainer); + + container->proxy->async_ops = true; +} + +static void vfio_user_listener_commit(VFIOContainerBase *bcontainer) +{ + VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer, + bcontainer); + + /* wait here for any async requests sent during the transaction */ + container->proxy->async_ops = false; + vfio_user_wait_reqs(container->proxy); +} + +static int vfio_user_dma_unmap(const VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + IOMMUTLBEntry *iotlb, bool unmap_all) +{ + VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer, + bcontainer); + Error *local_err = NULL; + int ret = 0; + + VFIOUserDMAUnmap *msgp = g_malloc(sizeof(*msgp)); + + vfio_user_request_msg(&msgp->hdr, VFIO_USER_DMA_UNMAP, sizeof(*msgp), 0); + msgp->argsz = sizeof(struct vfio_iommu_type1_dma_unmap); + msgp->flags = unmap_all ? VFIO_DMA_UNMAP_FLAG_ALL : 0; + msgp->iova = iova; + msgp->size = size; + trace_vfio_user_dma_unmap(msgp->iova, msgp->size, msgp->flags, + container->proxy->async_ops); + + if (container->proxy->async_ops) { + if (!vfio_user_send_nowait(container->proxy, &msgp->hdr, NULL, + 0, &local_err)) { + error_report_err(local_err); + ret = -EFAULT; + } else { + ret = 0; + } + } else { + if (!vfio_user_send_wait(container->proxy, &msgp->hdr, NULL, + 0, &local_err)) { + error_report_err(local_err); + ret = -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + ret = -msgp->hdr.error_reply; + } + + g_free(msgp); + } + + return ret; +} + +static int vfio_user_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova, + ram_addr_t size, void *vaddr, bool readonly, + MemoryRegion *mrp) +{ + VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer, + bcontainer); + int fd = memory_region_get_fd(mrp); + Error *local_err = NULL; + int ret; + + VFIOUserFDs *fds = NULL; + VFIOUserDMAMap *msgp = g_malloc0(sizeof(*msgp)); + + vfio_user_request_msg(&msgp->hdr, VFIO_USER_DMA_MAP, sizeof(*msgp), 0); + msgp->argsz = sizeof(struct vfio_iommu_type1_dma_map); + msgp->flags = VFIO_DMA_MAP_FLAG_READ; + msgp->offset = 0; + msgp->iova = iova; + msgp->size = size; + + /* + * vaddr enters as a QEMU process address; make it either a file offset + * for mapped areas or leave as 0. + */ + if (fd != -1) { + msgp->offset = qemu_ram_block_host_offset(mrp->ram_block, vaddr); + } + + if (!readonly) { + msgp->flags |= VFIO_DMA_MAP_FLAG_WRITE; + } + + trace_vfio_user_dma_map(msgp->iova, msgp->size, msgp->offset, msgp->flags, + container->proxy->async_ops); + + /* + * The async_ops case sends without blocking. They're later waited for in + * vfio_send_wait_reqs. + */ + if (container->proxy->async_ops) { + /* can't use auto variable since we don't block */ + if (fd != -1) { + fds = vfio_user_getfds(1); + fds->send_fds = 1; + fds->fds[0] = fd; + } + + if (!vfio_user_send_nowait(container->proxy, &msgp->hdr, fds, + 0, &local_err)) { + error_report_err(local_err); + ret = -EFAULT; + } else { + ret = 0; + } + } else { + VFIOUserFDs local_fds = { 1, 0, &fd }; + + fds = fd != -1 ? &local_fds : NULL; + + if (!vfio_user_send_wait(container->proxy, &msgp->hdr, fds, + 0, &local_err)) { + error_report_err(local_err); + ret = -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + ret = -msgp->hdr.error_reply; + } + + g_free(msgp); + } + + return ret; +} + +static int +vfio_user_set_dirty_page_tracking(const VFIOContainerBase *bcontainer, + bool start, Error **errp) +{ + error_setg_errno(errp, ENOTSUP, "Not supported"); + return -ENOTSUP; +} + +static int vfio_user_query_dirty_bitmap(const VFIOContainerBase *bcontainer, + VFIOBitmap *vbmap, hwaddr iova, + hwaddr size, Error **errp) +{ + error_setg_errno(errp, ENOTSUP, "Not supported"); + return -ENOTSUP; +} + +static bool vfio_user_setup(VFIOContainerBase *bcontainer, Error **errp) +{ + VFIOUserContainer *container = container_of(bcontainer, VFIOUserContainer, + bcontainer); + + assert(container->proxy->dma_pgsizes != 0); + bcontainer->pgsizes = container->proxy->dma_pgsizes; + bcontainer->dma_max_mappings = container->proxy->max_dma; + + /* No live migration support yet. */ + bcontainer->dirty_pages_supported = false; + bcontainer->max_dirty_bitmap_size = container->proxy->max_bitmap; + bcontainer->dirty_pgsizes = container->proxy->migr_pgsize; + + return true; +} + +static VFIOUserContainer *vfio_user_create_container(VFIODevice *vbasedev, + Error **errp) +{ + VFIOUserContainer *container; + + container = VFIO_IOMMU_USER(object_new(TYPE_VFIO_IOMMU_USER)); + container->proxy = vbasedev->proxy; + return container; +} + +/* + * Try to mirror vfio_container_connect() as much as possible. + */ +static VFIOUserContainer * +vfio_user_container_connect(AddressSpace *as, VFIODevice *vbasedev, + Error **errp) +{ + VFIOContainerBase *bcontainer; + VFIOUserContainer *container; + VFIOAddressSpace *space; + VFIOIOMMUClass *vioc; + int ret; + + space = vfio_address_space_get(as); + + container = vfio_user_create_container(vbasedev, errp); + if (!container) { + goto put_space_exit; + } + + bcontainer = &container->bcontainer; + + if (!vfio_cpr_register_container(bcontainer, errp)) { + goto free_container_exit; + } + + ret = ram_block_uncoordinated_discard_disable(true); + if (ret) { + error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken"); + goto unregister_container_exit; + } + + vioc = VFIO_IOMMU_GET_CLASS(bcontainer); + assert(vioc->setup); + + if (!vioc->setup(bcontainer, errp)) { + goto enable_discards_exit; + } + + vfio_address_space_insert(space, bcontainer); + + if (!vfio_listener_register(bcontainer, errp)) { + goto listener_release_exit; + } + + bcontainer->initialized = true; + + return container; + +listener_release_exit: + vfio_listener_unregister(bcontainer); + if (vioc->release) { + vioc->release(bcontainer); + } + +enable_discards_exit: + ram_block_uncoordinated_discard_disable(false); + +unregister_container_exit: + vfio_cpr_unregister_container(bcontainer); + +free_container_exit: + object_unref(container); + +put_space_exit: + vfio_address_space_put(space); + + return NULL; +} + +static void vfio_user_container_disconnect(VFIOUserContainer *container) +{ + VFIOContainerBase *bcontainer = &container->bcontainer; + VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); + VFIOAddressSpace *space = bcontainer->space; + + ram_block_uncoordinated_discard_disable(false); + + vfio_listener_unregister(bcontainer); + if (vioc->release) { + vioc->release(bcontainer); + } + + vfio_cpr_unregister_container(bcontainer); + object_unref(container); + + vfio_address_space_put(space); +} + +static bool vfio_user_device_get(VFIOUserContainer *container, + VFIODevice *vbasedev, Error **errp) +{ + struct vfio_device_info info = { .argsz = sizeof(info) }; + + + if (!vfio_user_get_device_info(vbasedev->proxy, &info, errp)) { + return false; + } + + vbasedev->fd = -1; + + vfio_device_prepare(vbasedev, &container->bcontainer, &info); + + return true; +} + +/* + * vfio_user_device_attach: attach a device to a new container. + */ +static bool vfio_user_device_attach(const char *name, VFIODevice *vbasedev, + AddressSpace *as, Error **errp) +{ + VFIOUserContainer *container; + + container = vfio_user_container_connect(as, vbasedev, errp); + if (container == NULL) { + error_prepend(errp, "failed to connect proxy"); + return false; + } + + return vfio_user_device_get(container, vbasedev, errp); +} + +static void vfio_user_device_detach(VFIODevice *vbasedev) +{ + VFIOUserContainer *container = container_of(vbasedev->bcontainer, + VFIOUserContainer, bcontainer); + + vfio_device_unprepare(vbasedev); + + vfio_user_container_disconnect(container); +} + +static int vfio_user_pci_hot_reset(VFIODevice *vbasedev, bool single) +{ + /* ->needs_reset is always false for vfio-user. */ + return 0; +} + +static void vfio_iommu_user_class_init(ObjectClass *klass, const void *data) +{ + VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); + + vioc->setup = vfio_user_setup; + vioc->listener_begin = vfio_user_listener_begin, + vioc->listener_commit = vfio_user_listener_commit, + vioc->dma_map = vfio_user_dma_map; + vioc->dma_unmap = vfio_user_dma_unmap; + vioc->attach_device = vfio_user_device_attach; + vioc->detach_device = vfio_user_device_detach; + vioc->set_dirty_page_tracking = vfio_user_set_dirty_page_tracking; + vioc->query_dirty_bitmap = vfio_user_query_dirty_bitmap; + vioc->pci_hot_reset = vfio_user_pci_hot_reset; +}; + +static const TypeInfo types[] = { + { + .name = TYPE_VFIO_IOMMU_USER, + .parent = TYPE_VFIO_IOMMU, + .instance_size = sizeof(VFIOUserContainer), + .class_init = vfio_iommu_user_class_init, + }, +}; + +DEFINE_TYPES(types) diff --git a/hw/vfio-user/container.h b/hw/vfio-user/container.h new file mode 100644 index 0000000..2bb1fa1 --- /dev/null +++ b/hw/vfio-user/container.h @@ -0,0 +1,23 @@ +/* + * vfio-user specific definitions. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_USER_CONTAINER_H +#define HW_VFIO_USER_CONTAINER_H + +#include "qemu/osdep.h" + +#include "hw/vfio/vfio-container-base.h" +#include "hw/vfio-user/proxy.h" + +/* MMU container sub-class for vfio-user. */ +typedef struct VFIOUserContainer { + VFIOContainerBase bcontainer; + VFIOUserProxy *proxy; +} VFIOUserContainer; + +OBJECT_DECLARE_SIMPLE_TYPE(VFIOUserContainer, VFIO_IOMMU_USER); + +#endif /* HW_VFIO_USER_CONTAINER_H */ diff --git a/hw/vfio-user/device.c b/hw/vfio-user/device.c new file mode 100644 index 0000000..0609a7d --- /dev/null +++ b/hw/vfio-user/device.c @@ -0,0 +1,441 @@ +/* + * vfio protocol over a UNIX socket device handling. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/lockable.h" +#include "qemu/thread.h" + +#include "hw/vfio-user/device.h" +#include "hw/vfio-user/trace.h" + +/* + * These are to defend against a malign server trying + * to force us to run out of memory. + */ +#define VFIO_USER_MAX_REGIONS 100 +#define VFIO_USER_MAX_IRQS 50 + +bool vfio_user_get_device_info(VFIOUserProxy *proxy, + struct vfio_device_info *info, Error **errp) +{ + VFIOUserDeviceInfo msg; + uint32_t argsz = sizeof(msg) - sizeof(msg.hdr); + + memset(&msg, 0, sizeof(msg)); + vfio_user_request_msg(&msg.hdr, VFIO_USER_DEVICE_GET_INFO, sizeof(msg), 0); + msg.argsz = argsz; + + if (!vfio_user_send_wait(proxy, &msg.hdr, NULL, 0, errp)) { + return false; + } + + if (msg.hdr.flags & VFIO_USER_ERROR) { + error_setg_errno(errp, -msg.hdr.error_reply, + "VFIO_USER_DEVICE_GET_INFO failed"); + return false; + } + + trace_vfio_user_get_info(msg.num_regions, msg.num_irqs); + + memcpy(info, &msg.argsz, argsz); + + /* defend against a malicious server */ + if (info->num_regions > VFIO_USER_MAX_REGIONS || + info->num_irqs > VFIO_USER_MAX_IRQS) { + error_setg_errno(errp, EINVAL, "invalid reply"); + return false; + } + + return true; +} + +void vfio_user_device_reset(VFIOUserProxy *proxy) +{ + Error *local_err = NULL; + VFIOUserHdr hdr; + + vfio_user_request_msg(&hdr, VFIO_USER_DEVICE_RESET, sizeof(hdr), 0); + + if (!vfio_user_send_wait(proxy, &hdr, NULL, 0, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return; + } + + if (hdr.flags & VFIO_USER_ERROR) { + error_printf("reset reply error %d\n", hdr.error_reply); + } +} + +static int vfio_user_get_region_info(VFIOUserProxy *proxy, + struct vfio_region_info *info, + VFIOUserFDs *fds) +{ + g_autofree VFIOUserRegionInfo *msgp = NULL; + Error *local_err = NULL; + uint32_t size; + + /* data returned can be larger than vfio_region_info */ + if (info->argsz < sizeof(*info)) { + error_printf("vfio_user_get_region_info argsz too small\n"); + return -E2BIG; + } + if (fds != NULL && fds->send_fds != 0) { + error_printf("vfio_user_get_region_info can't send FDs\n"); + return -EINVAL; + } + + size = info->argsz + sizeof(VFIOUserHdr); + msgp = g_malloc0(size); + + vfio_user_request_msg(&msgp->hdr, VFIO_USER_DEVICE_GET_REGION_INFO, + sizeof(*msgp), 0); + msgp->argsz = info->argsz; + msgp->index = info->index; + + if (!vfio_user_send_wait(proxy, &msgp->hdr, fds, size, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + return -msgp->hdr.error_reply; + } + trace_vfio_user_get_region_info(msgp->index, msgp->flags, msgp->size); + + memcpy(info, &msgp->argsz, info->argsz); + + /* + * If at least one region is directly mapped into the VM, then we can no + * longer rely on the sequential nature of vfio-user request handling to + * ensure that posted writes are completed before a subsequent read. In this + * case, disable posted write support. This is a per-device property, not + * per-region. + */ + if (info->flags & VFIO_REGION_INFO_FLAG_MMAP) { + vfio_user_disable_posted_writes(proxy); + } + + return 0; +} + +static int vfio_user_device_io_get_region_info(VFIODevice *vbasedev, + struct vfio_region_info *info, + int *fd) +{ + VFIOUserFDs fds = { 0, 1, fd}; + int ret; + + if (info->index > vbasedev->num_regions) { + return -EINVAL; + } + + ret = vfio_user_get_region_info(vbasedev->proxy, info, &fds); + if (ret) { + return ret; + } + + /* cap_offset in valid area */ + if ((info->flags & VFIO_REGION_INFO_FLAG_CAPS) && + (info->cap_offset < sizeof(*info) || info->cap_offset > info->argsz)) { + return -EINVAL; + } + + return 0; +} + +static int vfio_user_device_io_get_irq_info(VFIODevice *vbasedev, + struct vfio_irq_info *info) +{ + VFIOUserProxy *proxy = vbasedev->proxy; + Error *local_err = NULL; + VFIOUserIRQInfo msg; + + memset(&msg, 0, sizeof(msg)); + vfio_user_request_msg(&msg.hdr, VFIO_USER_DEVICE_GET_IRQ_INFO, + sizeof(msg), 0); + msg.argsz = info->argsz; + msg.index = info->index; + + if (!vfio_user_send_wait(proxy, &msg.hdr, NULL, 0, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return -EFAULT; + } + + if (msg.hdr.flags & VFIO_USER_ERROR) { + return -msg.hdr.error_reply; + } + trace_vfio_user_get_irq_info(msg.index, msg.flags, msg.count); + + memcpy(info, &msg.argsz, sizeof(*info)); + return 0; +} + +static int irq_howmany(int *fdp, uint32_t cur, uint32_t max) +{ + int n = 0; + + if (fdp[cur] != -1) { + do { + n++; + } while (n < max && fdp[cur + n] != -1); + } else { + do { + n++; + } while (n < max && fdp[cur + n] == -1); + } + + return n; +} + +static int vfio_user_device_io_set_irqs(VFIODevice *vbasedev, + struct vfio_irq_set *irq) +{ + VFIOUserProxy *proxy = vbasedev->proxy; + g_autofree VFIOUserIRQSet *msgp = NULL; + uint32_t size, nfds, send_fds, sent_fds, max; + Error *local_err = NULL; + + if (irq->argsz < sizeof(*irq)) { + error_printf("vfio_user_set_irqs argsz too small\n"); + return -EINVAL; + } + + /* + * Handle simple case + */ + if ((irq->flags & VFIO_IRQ_SET_DATA_EVENTFD) == 0) { + size = sizeof(VFIOUserHdr) + irq->argsz; + msgp = g_malloc0(size); + + vfio_user_request_msg(&msgp->hdr, VFIO_USER_DEVICE_SET_IRQS, size, 0); + msgp->argsz = irq->argsz; + msgp->flags = irq->flags; + msgp->index = irq->index; + msgp->start = irq->start; + msgp->count = irq->count; + trace_vfio_user_set_irqs(msgp->index, msgp->start, msgp->count, + msgp->flags); + + if (!vfio_user_send_wait(proxy, &msgp->hdr, NULL, 0, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + return -msgp->hdr.error_reply; + } + + return 0; + } + + /* + * Calculate the number of FDs to send + * and adjust argsz + */ + nfds = (irq->argsz - sizeof(*irq)) / sizeof(int); + irq->argsz = sizeof(*irq); + msgp = g_malloc0(sizeof(*msgp)); + /* + * Send in chunks if over max_send_fds + */ + for (sent_fds = 0; nfds > sent_fds; sent_fds += send_fds) { + VFIOUserFDs *arg_fds, loop_fds; + + /* must send all valid FDs or all invalid FDs in single msg */ + max = nfds - sent_fds; + if (max > proxy->max_send_fds) { + max = proxy->max_send_fds; + } + send_fds = irq_howmany((int *)irq->data, sent_fds, max); + + vfio_user_request_msg(&msgp->hdr, VFIO_USER_DEVICE_SET_IRQS, + sizeof(*msgp), 0); + msgp->argsz = irq->argsz; + msgp->flags = irq->flags; + msgp->index = irq->index; + msgp->start = irq->start + sent_fds; + msgp->count = send_fds; + trace_vfio_user_set_irqs(msgp->index, msgp->start, msgp->count, + msgp->flags); + + loop_fds.send_fds = send_fds; + loop_fds.recv_fds = 0; + loop_fds.fds = (int *)irq->data + sent_fds; + arg_fds = loop_fds.fds[0] != -1 ? &loop_fds : NULL; + + if (!vfio_user_send_wait(proxy, &msgp->hdr, arg_fds, 0, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + return -msgp->hdr.error_reply; + } + } + + return 0; +} + +static int vfio_user_device_io_region_read(VFIODevice *vbasedev, uint8_t index, + off_t off, uint32_t count, + void *data) +{ + g_autofree VFIOUserRegionRW *msgp = NULL; + VFIOUserProxy *proxy = vbasedev->proxy; + int size = sizeof(*msgp) + count; + Error *local_err = NULL; + + if (count > proxy->max_xfer_size) { + return -EINVAL; + } + + msgp = g_malloc0(size); + vfio_user_request_msg(&msgp->hdr, VFIO_USER_REGION_READ, sizeof(*msgp), 0); + msgp->offset = off; + msgp->region = index; + msgp->count = count; + trace_vfio_user_region_rw(msgp->region, msgp->offset, msgp->count); + + if (!vfio_user_send_wait(proxy, &msgp->hdr, NULL, size, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + return -msgp->hdr.error_reply; + } else if (msgp->count > count) { + return -E2BIG; + } else { + memcpy(data, &msgp->data, msgp->count); + } + + return msgp->count; +} + +/* + * If this is a posted write, and VFIO_PROXY_NO_POST is not set, then we are OK + * to send the write to the socket without waiting for the server's reply: + * a subsequent read (of any region) will not pass the posted write, as all + * messages are handled sequentially. + */ +static int vfio_user_device_io_region_write(VFIODevice *vbasedev, uint8_t index, + off_t off, unsigned count, + void *data, bool post) +{ + VFIOUserRegionRW *msgp = NULL; + VFIOUserProxy *proxy = vbasedev->proxy; + int size = sizeof(*msgp) + count; + Error *local_err = NULL; + bool can_multi; + int flags = 0; + int ret; + + if (count > proxy->max_xfer_size) { + return -EINVAL; + } + + if (proxy->flags & VFIO_PROXY_NO_POST) { + post = false; + } + + if (post) { + flags |= VFIO_USER_NO_REPLY; + } + + /* write eligible to be in a WRITE_MULTI msg ? */ + can_multi = (proxy->flags & VFIO_PROXY_USE_MULTI) && post && + count <= VFIO_USER_MULTI_DATA; + + /* + * This should be a rare case, so first check without the lock, + * if we're wrong, vfio_send_queued() will flush any posted writes + * we missed here + */ + if (proxy->wr_multi != NULL || + (proxy->num_outgoing > VFIO_USER_OUT_HIGH && can_multi)) { + + /* + * re-check with lock + * + * if already building a WRITE_MULTI msg, + * add this one if possible else flush pending before + * sending the current one + * + * else if outgoing queue is over the highwater, + * start a new WRITE_MULTI message + */ + WITH_QEMU_LOCK_GUARD(&proxy->lock) { + if (proxy->wr_multi != NULL) { + if (can_multi) { + vfio_user_add_multi(proxy, index, off, count, data); + return count; + } + vfio_user_flush_multi(proxy); + } else if (proxy->num_outgoing > VFIO_USER_OUT_HIGH && can_multi) { + vfio_user_create_multi(proxy); + vfio_user_add_multi(proxy, index, off, count, data); + return count; + } + } + } + + msgp = g_malloc0(size); + vfio_user_request_msg(&msgp->hdr, VFIO_USER_REGION_WRITE, size, flags); + msgp->offset = off; + msgp->region = index; + msgp->count = count; + memcpy(&msgp->data, data, count); + trace_vfio_user_region_rw(msgp->region, msgp->offset, msgp->count); + + /* async send will free msg after it's sent */ + if (post) { + if (!vfio_user_send_async(proxy, &msgp->hdr, NULL, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + return -EFAULT; + } + + return count; + } + + if (!vfio_user_send_wait(proxy, &msgp->hdr, NULL, 0, &local_err)) { + error_prepend(&local_err, "%s: ", __func__); + error_report_err(local_err); + g_free(msgp); + return -EFAULT; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + ret = -msgp->hdr.error_reply; + } else { + ret = count; + } + + g_free(msgp); + return ret; +} + +/* + * Socket-based io_ops + */ +VFIODeviceIOOps vfio_user_device_io_ops_sock = { + .get_region_info = vfio_user_device_io_get_region_info, + .get_irq_info = vfio_user_device_io_get_irq_info, + .set_irqs = vfio_user_device_io_set_irqs, + .region_read = vfio_user_device_io_region_read, + .region_write = vfio_user_device_io_region_write, + +}; diff --git a/hw/vfio-user/device.h b/hw/vfio-user/device.h new file mode 100644 index 0000000..d183a39 --- /dev/null +++ b/hw/vfio-user/device.h @@ -0,0 +1,24 @@ +#ifndef VFIO_USER_DEVICE_H +#define VFIO_USER_DEVICE_H + +/* + * vfio protocol over a UNIX socket device handling. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "linux/vfio.h" + +#include "hw/vfio-user/proxy.h" + +bool vfio_user_get_device_info(VFIOUserProxy *proxy, + struct vfio_device_info *info, Error **errp); + +void vfio_user_device_reset(VFIOUserProxy *proxy); + +extern VFIODeviceIOOps vfio_user_device_io_ops_sock; + +#endif /* VFIO_USER_DEVICE_H */ diff --git a/hw/vfio-user/meson.build b/hw/vfio-user/meson.build new file mode 100644 index 0000000..2ed0ae5 --- /dev/null +++ b/hw/vfio-user/meson.build @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +vfio_user_ss = ss.source_set() +vfio_user_ss.add(files( + 'container.c', + 'device.c', + 'pci.c', + 'proxy.c', +)) + +system_ss.add_all(when: 'CONFIG_VFIO_USER', if_true: vfio_user_ss) diff --git a/hw/vfio-user/pci.c b/hw/vfio-user/pci.c new file mode 100644 index 0000000..be71c77 --- /dev/null +++ b/hw/vfio-user/pci.c @@ -0,0 +1,475 @@ +/* + * vfio PCI device over a UNIX socket. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <sys/ioctl.h> +#include "qemu/osdep.h" +#include "qapi-visit-sockets.h" +#include "qemu/error-report.h" + +#include "hw/qdev-properties.h" +#include "hw/vfio/pci.h" +#include "hw/vfio-user/device.h" +#include "hw/vfio-user/proxy.h" + +#define TYPE_VFIO_USER_PCI "vfio-user-pci" +OBJECT_DECLARE_SIMPLE_TYPE(VFIOUserPCIDevice, VFIO_USER_PCI) + +struct VFIOUserPCIDevice { + VFIOPCIDevice device; + SocketAddress *socket; + bool send_queued; /* all sends are queued */ + uint32_t wait_time; /* timeout for message replies */ + bool no_post; /* all region writes are sync */ +}; + +/* + * The server maintains the device's pending interrupts, + * via its MSIX table and PBA, so we treat these accesses + * like PCI config space and forward them. + */ +static uint64_t vfio_user_pba_read(void *opaque, hwaddr addr, + unsigned size) +{ + VFIOPCIDevice *vdev = opaque; + VFIORegion *region = &vdev->bars[vdev->msix->pba_bar].region; + uint64_t data; + + /* server copy is what matters */ + data = vfio_region_read(region, addr + vdev->msix->pba_offset, size); + return data; +} + +static void vfio_user_pba_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + /* dropped */ +} + +static const MemoryRegionOps vfio_user_pba_ops = { + .read = vfio_user_pba_read, + .write = vfio_user_pba_write, + .endianness = DEVICE_LITTLE_ENDIAN, +}; + +static void vfio_user_msix_setup(VFIOPCIDevice *vdev) +{ + MemoryRegion *vfio_reg, *msix_reg, *pba_reg; + + pba_reg = g_new0(MemoryRegion, 1); + vdev->msix->pba_region = pba_reg; + + vfio_reg = vdev->bars[vdev->msix->pba_bar].mr; + msix_reg = &vdev->pdev.msix_pba_mmio; + memory_region_init_io(pba_reg, OBJECT(vdev), &vfio_user_pba_ops, vdev, + "VFIO MSIX PBA", int128_get64(msix_reg->size)); + memory_region_add_subregion_overlap(vfio_reg, vdev->msix->pba_offset, + pba_reg, 1); +} + +static void vfio_user_msix_teardown(VFIOPCIDevice *vdev) +{ + MemoryRegion *mr, *sub; + + mr = vdev->bars[vdev->msix->pba_bar].mr; + sub = vdev->msix->pba_region; + memory_region_del_subregion(mr, sub); + + g_free(vdev->msix->pba_region); + vdev->msix->pba_region = NULL; +} + +static void vfio_user_dma_read(VFIOPCIDevice *vdev, VFIOUserDMARW *msg) +{ + PCIDevice *pdev = &vdev->pdev; + VFIOUserProxy *proxy = vdev->vbasedev.proxy; + VFIOUserDMARW *res; + MemTxResult r; + size_t size; + + if (msg->hdr.size < sizeof(*msg)) { + vfio_user_send_error(proxy, &msg->hdr, EINVAL); + return; + } + if (msg->count > proxy->max_xfer_size) { + vfio_user_send_error(proxy, &msg->hdr, E2BIG); + return; + } + + /* switch to our own message buffer */ + size = msg->count + sizeof(VFIOUserDMARW); + res = g_malloc0(size); + memcpy(res, msg, sizeof(*res)); + g_free(msg); + + r = pci_dma_read(pdev, res->offset, &res->data, res->count); + + switch (r) { + case MEMTX_OK: + if (res->hdr.flags & VFIO_USER_NO_REPLY) { + g_free(res); + return; + } + vfio_user_send_reply(proxy, &res->hdr, size); + break; + case MEMTX_ERROR: + vfio_user_send_error(proxy, &res->hdr, EFAULT); + break; + case MEMTX_DECODE_ERROR: + vfio_user_send_error(proxy, &res->hdr, ENODEV); + break; + case MEMTX_ACCESS_ERROR: + vfio_user_send_error(proxy, &res->hdr, EPERM); + break; + default: + error_printf("vfio_user_dma_read unknown error %d\n", r); + vfio_user_send_error(vdev->vbasedev.proxy, &res->hdr, EINVAL); + } +} + +static void vfio_user_dma_write(VFIOPCIDevice *vdev, VFIOUserDMARW *msg) +{ + PCIDevice *pdev = &vdev->pdev; + VFIOUserProxy *proxy = vdev->vbasedev.proxy; + MemTxResult r; + + if (msg->hdr.size < sizeof(*msg)) { + vfio_user_send_error(proxy, &msg->hdr, EINVAL); + return; + } + /* make sure transfer count isn't larger than the message data */ + if (msg->count > msg->hdr.size - sizeof(*msg)) { + vfio_user_send_error(proxy, &msg->hdr, E2BIG); + return; + } + + r = pci_dma_write(pdev, msg->offset, &msg->data, msg->count); + + switch (r) { + case MEMTX_OK: + if ((msg->hdr.flags & VFIO_USER_NO_REPLY) == 0) { + vfio_user_send_reply(proxy, &msg->hdr, sizeof(msg->hdr)); + } else { + g_free(msg); + } + break; + case MEMTX_ERROR: + vfio_user_send_error(proxy, &msg->hdr, EFAULT); + break; + case MEMTX_DECODE_ERROR: + vfio_user_send_error(proxy, &msg->hdr, ENODEV); + break; + case MEMTX_ACCESS_ERROR: + vfio_user_send_error(proxy, &msg->hdr, EPERM); + break; + default: + error_printf("vfio_user_dma_write unknown error %d\n", r); + vfio_user_send_error(vdev->vbasedev.proxy, &msg->hdr, EINVAL); + } +} + +/* + * Incoming request message callback. + * + * Runs off main loop, so BQL held. + */ +static void vfio_user_pci_process_req(void *opaque, VFIOUserMsg *msg) +{ + VFIOPCIDevice *vdev = opaque; + VFIOUserHdr *hdr = msg->hdr; + + /* no incoming PCI requests pass FDs */ + if (msg->fds != NULL) { + vfio_user_send_error(vdev->vbasedev.proxy, hdr, EINVAL); + vfio_user_putfds(msg); + return; + } + + switch (hdr->command) { + case VFIO_USER_DMA_READ: + vfio_user_dma_read(vdev, (VFIOUserDMARW *)hdr); + break; + case VFIO_USER_DMA_WRITE: + vfio_user_dma_write(vdev, (VFIOUserDMARW *)hdr); + break; + default: + error_printf("vfio_user_pci_process_req unknown cmd %d\n", + hdr->command); + vfio_user_send_error(vdev->vbasedev.proxy, hdr, ENOSYS); + } +} + +/* + * Emulated devices don't use host hot reset + */ +static void vfio_user_compute_needs_reset(VFIODevice *vbasedev) +{ + vbasedev->needs_reset = false; +} + +static Object *vfio_user_pci_get_object(VFIODevice *vbasedev) +{ + VFIOUserPCIDevice *vdev = container_of(vbasedev, VFIOUserPCIDevice, + device.vbasedev); + + return OBJECT(vdev); +} + +static VFIODeviceOps vfio_user_pci_ops = { + .vfio_compute_needs_reset = vfio_user_compute_needs_reset, + .vfio_eoi = vfio_pci_intx_eoi, + .vfio_get_object = vfio_user_pci_get_object, + /* No live migration support yet. */ + .vfio_save_config = NULL, + .vfio_load_config = NULL, +}; + +static void vfio_user_pci_realize(PCIDevice *pdev, Error **errp) +{ + ERRP_GUARD(); + VFIOUserPCIDevice *udev = VFIO_USER_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); + VFIODevice *vbasedev = &vdev->vbasedev; + const char *sock_name; + AddressSpace *as; + SocketAddress addr; + VFIOUserProxy *proxy; + + if (!udev->socket) { + error_setg(errp, "No socket specified"); + error_append_hint(errp, "e.g. -device '{" + "\"driver\":\"vfio-user-pci\", " + "\"socket\": {\"path\": \"/tmp/vfio-user.sock\", " + "\"type\": \"unix\"}'" + "}'\n"); + return; + } + + sock_name = udev->socket->u.q_unix.path; + + vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name); + + memset(&addr, 0, sizeof(addr)); + addr.type = SOCKET_ADDRESS_TYPE_UNIX; + addr.u.q_unix.path = (char *)sock_name; + proxy = vfio_user_connect_dev(&addr, errp); + if (!proxy) { + return; + } + vbasedev->proxy = proxy; + vfio_user_set_handler(vbasedev, vfio_user_pci_process_req, vdev); + + vbasedev->name = g_strdup_printf("vfio-user:%s", sock_name); + + if (udev->send_queued) { + proxy->flags |= VFIO_PROXY_FORCE_QUEUED; + } + + if (udev->no_post) { + proxy->flags |= VFIO_PROXY_NO_POST; + } + + /* user specified or 5 sec default */ + proxy->wait_time = udev->wait_time; + + if (!vfio_user_validate_version(proxy, errp)) { + goto error; + } + + /* + * Use socket-based device I/O instead of vfio kernel driver. + */ + vbasedev->io_ops = &vfio_user_device_io_ops_sock; + + /* + * vfio-user devices are effectively mdevs (don't use a host iommu). + */ + vbasedev->mdev = true; + + /* + * Enable per-region fds. + */ + vbasedev->use_region_fds = true; + + as = pci_device_iommu_address_space(pdev); + if (!vfio_device_attach_by_iommu_type(TYPE_VFIO_IOMMU_USER, + vbasedev->name, vbasedev, + as, errp)) { + goto error; + } + + if (!vfio_pci_populate_device(vdev, errp)) { + goto error; + } + + if (!vfio_pci_config_setup(vdev, errp)) { + goto error; + } + + /* + * vfio_pci_config_setup will have registered the device's BARs + * and setup any MSIX BARs, so errors after it succeeds must + * use out_teardown + */ + + if (!vfio_pci_add_capabilities(vdev, errp)) { + goto out_teardown; + } + + if (vdev->msix != NULL) { + vfio_user_msix_setup(vdev); + } + + if (!vfio_pci_interrupt_setup(vdev, errp)) { + goto out_teardown; + } + + vfio_pci_register_err_notifier(vdev); + vfio_pci_register_req_notifier(vdev); + + return; + +out_teardown: + vfio_pci_teardown_msi(vdev); + vfio_pci_bars_exit(vdev); +error: + error_prepend(errp, VFIO_MSG_PREFIX, vdev->vbasedev.name); + vfio_pci_put_device(vdev); +} + +static void vfio_user_instance_init(Object *obj) +{ + PCIDevice *pci_dev = PCI_DEVICE(obj); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); + VFIODevice *vbasedev = &vdev->vbasedev; + + device_add_bootindex_property(obj, &vdev->bootindex, + "bootindex", NULL, + &pci_dev->qdev); + vdev->host.domain = ~0U; + vdev->host.bus = ~0U; + vdev->host.slot = ~0U; + vdev->host.function = ~0U; + + vfio_device_init(vbasedev, VFIO_DEVICE_TYPE_PCI, &vfio_user_pci_ops, + DEVICE(vdev), false); + + vdev->nv_gpudirect_clique = 0xFF; + + /* + * QEMU_PCI_CAP_EXPRESS initialization does not depend on QEMU command + * line, therefore, no need to wait to realize like other devices. + */ + pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; +} + +static void vfio_user_instance_finalize(Object *obj) +{ + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); + VFIODevice *vbasedev = &vdev->vbasedev; + + if (vdev->msix != NULL) { + vfio_user_msix_teardown(vdev); + } + + vfio_pci_put_device(vdev); + + if (vbasedev->proxy != NULL) { + vfio_user_disconnect(vbasedev->proxy); + } +} + +static void vfio_user_pci_reset(DeviceState *dev) +{ + VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev); + VFIODevice *vbasedev = &vdev->vbasedev; + + vfio_pci_pre_reset(vdev); + + if (vbasedev->reset_works) { + vfio_user_device_reset(vbasedev->proxy); + } + + vfio_pci_post_reset(vdev); +} + +static const Property vfio_user_pci_dev_properties[] = { + DEFINE_PROP_UINT32("x-pci-vendor-id", VFIOPCIDevice, + vendor_id, PCI_ANY_ID), + DEFINE_PROP_UINT32("x-pci-device-id", VFIOPCIDevice, + device_id, PCI_ANY_ID), + DEFINE_PROP_UINT32("x-pci-sub-vendor-id", VFIOPCIDevice, + sub_vendor_id, PCI_ANY_ID), + DEFINE_PROP_UINT32("x-pci-sub-device-id", VFIOPCIDevice, + sub_device_id, PCI_ANY_ID), + DEFINE_PROP_BOOL("x-send-queued", VFIOUserPCIDevice, send_queued, false), + DEFINE_PROP_UINT32("x-msg-timeout", VFIOUserPCIDevice, wait_time, 5000), + DEFINE_PROP_BOOL("x-no-posted-writes", VFIOUserPCIDevice, no_post, false), +}; + +static void vfio_user_pci_set_socket(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + VFIOUserPCIDevice *udev = VFIO_USER_PCI(obj); + bool success; + + if (udev->device.vbasedev.proxy) { + error_setg(errp, "Proxy is connected"); + return; + } + + qapi_free_SocketAddress(udev->socket); + + udev->socket = NULL; + + success = visit_type_SocketAddress(v, name, &udev->socket, errp); + + if (!success) { + return; + } + + if (udev->socket->type != SOCKET_ADDRESS_TYPE_UNIX) { + error_setg(errp, "Unsupported socket type %s", + SocketAddressType_str(udev->socket->type)); + qapi_free_SocketAddress(udev->socket); + udev->socket = NULL; + return; + } +} + +static void vfio_user_pci_dev_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass); + + device_class_set_legacy_reset(dc, vfio_user_pci_reset); + device_class_set_props(dc, vfio_user_pci_dev_properties); + + object_class_property_add(klass, "socket", "SocketAddress", NULL, + vfio_user_pci_set_socket, NULL, NULL); + object_class_property_set_description(klass, "socket", + "SocketAddress (UNIX sockets only)"); + + dc->desc = "VFIO over socket PCI device assignment"; + pdc->realize = vfio_user_pci_realize; +} + +static const TypeInfo vfio_user_pci_dev_info = { + .name = TYPE_VFIO_USER_PCI, + .parent = TYPE_VFIO_PCI_BASE, + .instance_size = sizeof(VFIOUserPCIDevice), + .class_init = vfio_user_pci_dev_class_init, + .instance_init = vfio_user_instance_init, + .instance_finalize = vfio_user_instance_finalize, +}; + +static void register_vfio_user_dev_type(void) +{ + type_register_static(&vfio_user_pci_dev_info); +} + + type_init(register_vfio_user_dev_type) diff --git a/hw/vfio-user/protocol.h b/hw/vfio-user/protocol.h new file mode 100644 index 0000000..3249a4a --- /dev/null +++ b/hw/vfio-user/protocol.h @@ -0,0 +1,242 @@ +#ifndef VFIO_USER_PROTOCOL_H +#define VFIO_USER_PROTOCOL_H + +/* + * vfio protocol over a UNIX socket. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * Each message has a standard header that describes the command + * being sent, which is almost always a VFIO ioctl(). + * + * The header may be followed by command-specific data, such as the + * region and offset info for read and write commands. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +typedef struct { + uint16_t id; + uint16_t command; + uint32_t size; + uint32_t flags; + uint32_t error_reply; +} VFIOUserHdr; + +/* VFIOUserHdr commands */ +enum vfio_user_command { + VFIO_USER_VERSION = 1, + VFIO_USER_DMA_MAP = 2, + VFIO_USER_DMA_UNMAP = 3, + VFIO_USER_DEVICE_GET_INFO = 4, + VFIO_USER_DEVICE_GET_REGION_INFO = 5, + VFIO_USER_DEVICE_GET_REGION_IO_FDS = 6, + VFIO_USER_DEVICE_GET_IRQ_INFO = 7, + VFIO_USER_DEVICE_SET_IRQS = 8, + VFIO_USER_REGION_READ = 9, + VFIO_USER_REGION_WRITE = 10, + VFIO_USER_DMA_READ = 11, + VFIO_USER_DMA_WRITE = 12, + VFIO_USER_DEVICE_RESET = 13, + VFIO_USER_DIRTY_PAGES = 14, + VFIO_USER_REGION_WRITE_MULTI = 15, + VFIO_USER_MAX, +}; + +/* VFIOUserHdr flags */ +#define VFIO_USER_REQUEST 0x0 +#define VFIO_USER_REPLY 0x1 +#define VFIO_USER_TYPE 0xF + +#define VFIO_USER_NO_REPLY 0x10 +#define VFIO_USER_ERROR 0x20 + + +/* + * VFIO_USER_VERSION + */ +typedef struct { + VFIOUserHdr hdr; + uint16_t major; + uint16_t minor; + char capabilities[]; +} VFIOUserVersion; + +#define VFIO_USER_MAJOR_VER 0 +#define VFIO_USER_MINOR_VER 0 + +#define VFIO_USER_CAP "capabilities" + +/* "capabilities" members */ +#define VFIO_USER_CAP_MAX_FDS "max_msg_fds" +#define VFIO_USER_CAP_MAX_XFER "max_data_xfer_size" +#define VFIO_USER_CAP_PGSIZES "pgsizes" +#define VFIO_USER_CAP_MAP_MAX "max_dma_maps" +#define VFIO_USER_CAP_MIGR "migration" +#define VFIO_USER_CAP_MULTI "write_multiple" + +/* "migration" members */ +#define VFIO_USER_CAP_PGSIZE "pgsize" +#define VFIO_USER_CAP_MAX_BITMAP "max_bitmap_size" + +/* + * Max FDs mainly comes into play when a device supports multiple interrupts + * where each ones uses an eventfd to inject it into the guest. + * It is clamped by the the number of FDs the qio channel supports in a + * single message. + */ +#define VFIO_USER_DEF_MAX_FDS 8 +#define VFIO_USER_MAX_MAX_FDS 16 + +/* + * Max transfer limits the amount of data in region and DMA messages. + * Region R/W will be very small (limited by how much a single instruction + * can process) so just use a reasonable limit here. + */ +#define VFIO_USER_DEF_MAX_XFER (1024 * 1024) +#define VFIO_USER_MAX_MAX_XFER (64 * 1024 * 1024) + +/* + * Default pagesizes supported is 4k. + */ +#define VFIO_USER_DEF_PGSIZE 4096 + +/* + * Default max number of DMA mappings is stolen from the + * linux kernel "dma_entry_limit" + */ +#define VFIO_USER_DEF_MAP_MAX 65535 + +/* + * Default max bitmap size is also take from the linux kernel, + * where usage of signed ints limits the VA range to 2^31 bytes. + * Dividing that by the number of bits per byte yields 256MB + */ +#define VFIO_USER_DEF_MAX_BITMAP (256 * 1024 * 1024) + +/* + * VFIO_USER_DMA_MAP + * imported from struct vfio_iommu_type1_dma_map + */ +typedef struct { + VFIOUserHdr hdr; + uint32_t argsz; + uint32_t flags; + uint64_t offset; /* FD offset */ + uint64_t iova; + uint64_t size; +} VFIOUserDMAMap; + +/* + * VFIO_USER_DMA_UNMAP + * imported from struct vfio_iommu_type1_dma_unmap + */ +typedef struct { + VFIOUserHdr hdr; + uint32_t argsz; + uint32_t flags; + uint64_t iova; + uint64_t size; +} VFIOUserDMAUnmap; + +/* + * VFIO_USER_DEVICE_GET_INFO + * imported from struct vfio_device_info + */ +typedef struct { + VFIOUserHdr hdr; + uint32_t argsz; + uint32_t flags; + uint32_t num_regions; + uint32_t num_irqs; +} VFIOUserDeviceInfo; + +/* + * VFIO_USER_DEVICE_GET_REGION_INFO + * imported from struct vfio_region_info + */ +typedef struct { + VFIOUserHdr hdr; + uint32_t argsz; + uint32_t flags; + uint32_t index; + uint32_t cap_offset; + uint64_t size; + uint64_t offset; +} VFIOUserRegionInfo; + +/* + * VFIO_USER_DEVICE_GET_IRQ_INFO + * imported from struct vfio_irq_info + */ +typedef struct { + VFIOUserHdr hdr; + uint32_t argsz; + uint32_t flags; + uint32_t index; + uint32_t count; +} VFIOUserIRQInfo; + +/* + * VFIO_USER_DEVICE_SET_IRQS + * imported from struct vfio_irq_set + */ +typedef struct { + VFIOUserHdr hdr; + uint32_t argsz; + uint32_t flags; + uint32_t index; + uint32_t start; + uint32_t count; +} VFIOUserIRQSet; + +/* + * VFIO_USER_REGION_READ + * VFIO_USER_REGION_WRITE + */ +typedef struct { + VFIOUserHdr hdr; + uint64_t offset; + uint32_t region; + uint32_t count; + char data[]; +} VFIOUserRegionRW; + +/* + * VFIO_USER_DMA_READ + * VFIO_USER_DMA_WRITE + */ +typedef struct { + VFIOUserHdr hdr; + uint64_t offset; + uint32_t count; + char data[]; +} VFIOUserDMARW; + +/* imported from struct vfio_bitmap */ +typedef struct { + uint64_t pgsize; + uint64_t size; + char data[]; +} VFIOUserBitmap; + +/* + * VFIO_USER_REGION_WRITE_MULTI + */ +#define VFIO_USER_MULTI_DATA 8 +#define VFIO_USER_MULTI_MAX 200 + +typedef struct { + uint64_t offset; + uint32_t region; + uint32_t count; + char data[VFIO_USER_MULTI_DATA]; +} VFIOUserWROne; + +typedef struct { + VFIOUserHdr hdr; + uint64_t wr_cnt; + VFIOUserWROne wrs[VFIO_USER_MULTI_MAX]; +} VFIOUserWRMulti; + +#endif /* VFIO_USER_PROTOCOL_H */ diff --git a/hw/vfio-user/proxy.c b/hw/vfio-user/proxy.c new file mode 100644 index 0000000..c418954 --- /dev/null +++ b/hw/vfio-user/proxy.c @@ -0,0 +1,1356 @@ +/* + * vfio protocol over a UNIX socket. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include <sys/ioctl.h> + +#include "hw/vfio/vfio-device.h" +#include "hw/vfio-user/proxy.h" +#include "hw/vfio-user/trace.h" +#include "qapi/error.h" +#include "qobject/qbool.h" +#include "qobject/qdict.h" +#include "qobject/qjson.h" +#include "qobject/qnum.h" +#include "qemu/error-report.h" +#include "qemu/lockable.h" +#include "qemu/main-loop.h" +#include "qemu/thread.h" +#include "system/iothread.h" + +static IOThread *vfio_user_iothread; + +static void vfio_user_shutdown(VFIOUserProxy *proxy); +static VFIOUserMsg *vfio_user_getmsg(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds); +static void vfio_user_recycle(VFIOUserProxy *proxy, VFIOUserMsg *msg); + +static void vfio_user_recv(void *opaque); +static void vfio_user_send(void *opaque); +static void vfio_user_cb(void *opaque); + +static void vfio_user_request(void *opaque); + +static inline void vfio_user_set_error(VFIOUserHdr *hdr, uint32_t err) +{ + hdr->flags |= VFIO_USER_ERROR; + hdr->error_reply = err; +} + +/* + * Functions called by main, CPU, or iothread threads + */ + +static void vfio_user_shutdown(VFIOUserProxy *proxy) +{ + qio_channel_shutdown(proxy->ioc, QIO_CHANNEL_SHUTDOWN_READ, NULL); + qio_channel_set_aio_fd_handler(proxy->ioc, proxy->ctx, NULL, + proxy->ctx, NULL, NULL); +} + +/* + * Same return values as qio_channel_writev_full(): + * + * QIO_CHANNEL_ERR_BLOCK: *errp not set + * -1: *errp will be populated + * otherwise: bytes written + */ +static ssize_t vfio_user_send_qio(VFIOUserProxy *proxy, VFIOUserMsg *msg, + Error **errp) +{ + VFIOUserFDs *fds = msg->fds; + struct iovec iov = { + .iov_base = msg->hdr, + .iov_len = msg->hdr->size, + }; + size_t numfds = 0; + int *fdp = NULL; + ssize_t ret; + + if (fds != NULL && fds->send_fds != 0) { + numfds = fds->send_fds; + fdp = fds->fds; + } + + ret = qio_channel_writev_full(proxy->ioc, &iov, 1, fdp, numfds, 0, errp); + + if (ret == -1) { + vfio_user_set_error(msg->hdr, EIO); + vfio_user_shutdown(proxy); + } + trace_vfio_user_send_write(msg->hdr->id, ret); + + return ret; +} + +static VFIOUserMsg *vfio_user_getmsg(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds) +{ + VFIOUserMsg *msg; + + msg = QTAILQ_FIRST(&proxy->free); + if (msg != NULL) { + QTAILQ_REMOVE(&proxy->free, msg, next); + } else { + msg = g_malloc0(sizeof(*msg)); + qemu_cond_init(&msg->cv); + } + + msg->hdr = hdr; + msg->fds = fds; + return msg; +} + +/* + * Recycle a message list entry to the free list. + */ +static void vfio_user_recycle(VFIOUserProxy *proxy, VFIOUserMsg *msg) +{ + if (msg->type == VFIO_MSG_NONE) { + error_printf("vfio_user_recycle - freeing free msg\n"); + return; + } + + /* free msg buffer if no one is waiting to consume the reply */ + if (msg->type == VFIO_MSG_NOWAIT || msg->type == VFIO_MSG_ASYNC) { + g_free(msg->hdr); + if (msg->fds != NULL) { + g_free(msg->fds); + } + } + + msg->type = VFIO_MSG_NONE; + msg->hdr = NULL; + msg->fds = NULL; + msg->complete = false; + msg->pending = false; + QTAILQ_INSERT_HEAD(&proxy->free, msg, next); +} + +VFIOUserFDs *vfio_user_getfds(int numfds) +{ + VFIOUserFDs *fds = g_malloc0(sizeof(*fds) + (numfds * sizeof(int))); + + fds->fds = (int *)((char *)fds + sizeof(*fds)); + + return fds; +} + +/* + * Functions only called by iothread + */ + +/* + * Process a received message. + */ +static void vfio_user_process(VFIOUserProxy *proxy, VFIOUserMsg *msg, + bool isreply) +{ + + /* + * Replies signal a waiter, if none just check for errors + * and free the message buffer. + * + * Requests get queued for the BH. + */ + if (isreply) { + msg->complete = true; + if (msg->type == VFIO_MSG_WAIT) { + qemu_cond_signal(&msg->cv); + } else { + if (msg->hdr->flags & VFIO_USER_ERROR) { + error_printf("vfio_user_process: error reply on async "); + error_printf("request command %x error %s\n", + msg->hdr->command, + strerror(msg->hdr->error_reply)); + } + /* youngest nowait msg has been ack'd */ + if (proxy->last_nowait == msg) { + proxy->last_nowait = NULL; + } + vfio_user_recycle(proxy, msg); + } + } else { + QTAILQ_INSERT_TAIL(&proxy->incoming, msg, next); + qemu_bh_schedule(proxy->req_bh); + } +} + +/* + * Complete a partial message read + */ +static int vfio_user_complete(VFIOUserProxy *proxy, Error **errp) +{ + VFIOUserMsg *msg = proxy->part_recv; + size_t msgleft = proxy->recv_left; + bool isreply; + char *data; + int ret; + + data = (char *)msg->hdr + (msg->hdr->size - msgleft); + while (msgleft > 0) { + ret = qio_channel_read(proxy->ioc, data, msgleft, errp); + + /* error or would block */ + if (ret <= 0) { + /* try for rest on next iternation */ + if (ret == QIO_CHANNEL_ERR_BLOCK) { + proxy->recv_left = msgleft; + } + return ret; + } + trace_vfio_user_recv_read(msg->hdr->id, ret); + + msgleft -= ret; + data += ret; + } + + /* + * Read complete message, process it. + */ + proxy->part_recv = NULL; + proxy->recv_left = 0; + isreply = (msg->hdr->flags & VFIO_USER_TYPE) == VFIO_USER_REPLY; + vfio_user_process(proxy, msg, isreply); + + /* return positive value */ + return 1; +} + +/* + * Receive and process one incoming message. + * + * For replies, find matching outgoing request and wake any waiters. + * For requests, queue in incoming list and run request BH. + */ +static int vfio_user_recv_one(VFIOUserProxy *proxy, Error **errp) +{ + VFIOUserMsg *msg = NULL; + g_autofree int *fdp = NULL; + VFIOUserFDs *reqfds; + VFIOUserHdr hdr; + struct iovec iov = { + .iov_base = &hdr, + .iov_len = sizeof(hdr), + }; + bool isreply = false; + int i, ret; + size_t msgleft, numfds = 0; + char *data = NULL; + char *buf = NULL; + + /* + * Complete any partial reads + */ + if (proxy->part_recv != NULL) { + ret = vfio_user_complete(proxy, errp); + + /* still not complete, try later */ + if (ret == QIO_CHANNEL_ERR_BLOCK) { + return ret; + } + + if (ret <= 0) { + goto fatal; + } + /* else fall into reading another msg */ + } + + /* + * Read header + */ + ret = qio_channel_readv_full(proxy->ioc, &iov, 1, &fdp, &numfds, 0, + errp); + if (ret == QIO_CHANNEL_ERR_BLOCK) { + return ret; + } + + /* read error or other side closed connection */ + if (ret <= 0) { + goto fatal; + } + + if (ret < sizeof(hdr)) { + error_setg(errp, "short read of header"); + goto fatal; + } + + /* + * Validate header + */ + if (hdr.size < sizeof(VFIOUserHdr)) { + error_setg(errp, "bad header size"); + goto fatal; + } + switch (hdr.flags & VFIO_USER_TYPE) { + case VFIO_USER_REQUEST: + isreply = false; + break; + case VFIO_USER_REPLY: + isreply = true; + break; + default: + error_setg(errp, "unknown message type"); + goto fatal; + } + trace_vfio_user_recv_hdr(proxy->sockname, hdr.id, hdr.command, hdr.size, + hdr.flags); + + /* + * For replies, find the matching pending request. + * For requests, reap incoming FDs. + */ + if (isreply) { + QTAILQ_FOREACH(msg, &proxy->pending, next) { + if (hdr.id == msg->id) { + break; + } + } + if (msg == NULL) { + error_setg(errp, "unexpected reply"); + goto err; + } + QTAILQ_REMOVE(&proxy->pending, msg, next); + + /* + * Process any received FDs + */ + if (numfds != 0) { + if (msg->fds == NULL || msg->fds->recv_fds < numfds) { + error_setg(errp, "unexpected FDs"); + goto err; + } + msg->fds->recv_fds = numfds; + memcpy(msg->fds->fds, fdp, numfds * sizeof(int)); + } + } else { + if (numfds != 0) { + reqfds = vfio_user_getfds(numfds); + memcpy(reqfds->fds, fdp, numfds * sizeof(int)); + } else { + reqfds = NULL; + } + } + + /* + * Put the whole message into a single buffer. + */ + if (isreply) { + if (hdr.size > msg->rsize) { + error_setg(errp, "reply larger than recv buffer"); + goto err; + } + *msg->hdr = hdr; + data = (char *)msg->hdr + sizeof(hdr); + } else { + if (hdr.size > proxy->max_xfer_size + sizeof(VFIOUserDMARW)) { + error_setg(errp, "vfio_user_recv request larger than max"); + goto err; + } + buf = g_malloc0(hdr.size); + memcpy(buf, &hdr, sizeof(hdr)); + data = buf + sizeof(hdr); + msg = vfio_user_getmsg(proxy, (VFIOUserHdr *)buf, reqfds); + msg->type = VFIO_MSG_REQ; + } + + /* + * Read rest of message. + */ + msgleft = hdr.size - sizeof(hdr); + while (msgleft > 0) { + ret = qio_channel_read(proxy->ioc, data, msgleft, errp); + + /* prepare to complete read on next iternation */ + if (ret == QIO_CHANNEL_ERR_BLOCK) { + proxy->part_recv = msg; + proxy->recv_left = msgleft; + return ret; + } + + if (ret <= 0) { + goto fatal; + } + trace_vfio_user_recv_read(hdr.id, ret); + + msgleft -= ret; + data += ret; + } + + vfio_user_process(proxy, msg, isreply); + return 0; + + /* + * fatal means the other side closed or we don't trust the stream + * err means this message is corrupt + */ +fatal: + vfio_user_shutdown(proxy); + proxy->state = VFIO_PROXY_ERROR; + + /* set error if server side closed */ + if (ret == 0) { + error_setg(errp, "server closed socket"); + } + +err: + for (i = 0; i < numfds; i++) { + close(fdp[i]); + } + if (isreply && msg != NULL) { + /* force an error to keep sending thread from hanging */ + vfio_user_set_error(msg->hdr, EINVAL); + msg->complete = true; + qemu_cond_signal(&msg->cv); + } + return -1; +} + +static void vfio_user_recv(void *opaque) +{ + VFIOUserProxy *proxy = opaque; + + QEMU_LOCK_GUARD(&proxy->lock); + + if (proxy->state == VFIO_PROXY_CONNECTED) { + Error *local_err = NULL; + + while (vfio_user_recv_one(proxy, &local_err) == 0) { + ; + } + + if (local_err != NULL) { + error_report_err(local_err); + } + } +} + +/* + * Send a single message, same return semantics as vfio_user_send_qio(). + * + * Sent async messages are freed, others are moved to pending queue. + */ +static ssize_t vfio_user_send_one(VFIOUserProxy *proxy, Error **errp) +{ + VFIOUserMsg *msg; + ssize_t ret; + + msg = QTAILQ_FIRST(&proxy->outgoing); + ret = vfio_user_send_qio(proxy, msg, errp); + if (ret < 0) { + return ret; + } + + QTAILQ_REMOVE(&proxy->outgoing, msg, next); + proxy->num_outgoing--; + if (msg->type == VFIO_MSG_ASYNC) { + vfio_user_recycle(proxy, msg); + } else { + QTAILQ_INSERT_TAIL(&proxy->pending, msg, next); + msg->pending = true; + } + + return ret; +} + +/* + * Send messages from outgoing queue when the socket buffer has space. + * If we deplete 'outgoing', remove ourselves from the poll list. + */ +static void vfio_user_send(void *opaque) +{ + VFIOUserProxy *proxy = opaque; + + QEMU_LOCK_GUARD(&proxy->lock); + + if (proxy->state == VFIO_PROXY_CONNECTED) { + while (!QTAILQ_EMPTY(&proxy->outgoing)) { + Error *local_err = NULL; + int ret; + + ret = vfio_user_send_one(proxy, &local_err); + + if (ret == QIO_CHANNEL_ERR_BLOCK) { + return; + } else if (ret == -1) { + error_report_err(local_err); + return; + } + } + qio_channel_set_aio_fd_handler(proxy->ioc, proxy->ctx, + vfio_user_recv, NULL, NULL, proxy); + + /* queue empty - send any pending multi write msgs */ + if (proxy->wr_multi != NULL) { + vfio_user_flush_multi(proxy); + } + } +} + +static void vfio_user_cb(void *opaque) +{ + VFIOUserProxy *proxy = opaque; + + QEMU_LOCK_GUARD(&proxy->lock); + + proxy->state = VFIO_PROXY_CLOSED; + qemu_cond_signal(&proxy->close_cv); +} + + +/* + * Functions called by main or CPU threads + */ + +/* + * Process incoming requests. + * + * The bus-specific callback has the form: + * request(opaque, msg) + * where 'opaque' was specified in vfio_user_set_handler + * and 'msg' is the inbound message. + * + * The callback is responsible for disposing of the message buffer, + * usually by re-using it when calling vfio_send_reply or vfio_send_error, + * both of which free their message buffer when the reply is sent. + * + * If the callback uses a new buffer, it needs to free the old one. + */ +static void vfio_user_request(void *opaque) +{ + VFIOUserProxy *proxy = opaque; + VFIOUserMsgQ new, free; + VFIOUserMsg *msg, *m1; + + /* reap all incoming */ + QTAILQ_INIT(&new); + WITH_QEMU_LOCK_GUARD(&proxy->lock) { + QTAILQ_FOREACH_SAFE(msg, &proxy->incoming, next, m1) { + QTAILQ_REMOVE(&proxy->incoming, msg, next); + QTAILQ_INSERT_TAIL(&new, msg, next); + } + } + + /* process list */ + QTAILQ_INIT(&free); + QTAILQ_FOREACH_SAFE(msg, &new, next, m1) { + QTAILQ_REMOVE(&new, msg, next); + trace_vfio_user_recv_request(msg->hdr->command); + proxy->request(proxy->req_arg, msg); + QTAILQ_INSERT_HEAD(&free, msg, next); + } + + /* free list */ + WITH_QEMU_LOCK_GUARD(&proxy->lock) { + QTAILQ_FOREACH_SAFE(msg, &free, next, m1) { + vfio_user_recycle(proxy, msg); + } + } +} + +/* + * Messages are queued onto the proxy's outgoing list. + * + * It handles 3 types of messages: + * + * async messages - replies and posted writes + * + * There will be no reply from the server, so message + * buffers are freed after they're sent. + * + * nowait messages - map/unmap during address space transactions + * + * These are also sent async, but a reply is expected so that + * vfio_wait_reqs() can wait for the youngest nowait request. + * They transition from the outgoing list to the pending list + * when sent, and are freed when the reply is received. + * + * wait messages - all other requests + * + * The reply to these messages is waited for by their caller. + * They also transition from outgoing to pending when sent, but + * the message buffer is returned to the caller with the reply + * contents. The caller is responsible for freeing these messages. + * + * As an optimization, if the outgoing list and the socket send + * buffer are empty, the message is sent inline instead of being + * added to the outgoing list. The rest of the transitions are + * unchanged. + */ +static bool vfio_user_send_queued(VFIOUserProxy *proxy, VFIOUserMsg *msg, + Error **errp) +{ + int ret; + + /* older coalesced writes go first */ + if (proxy->wr_multi != NULL && + ((msg->hdr->flags & VFIO_USER_TYPE) == VFIO_USER_REQUEST)) { + vfio_user_flush_multi(proxy); + } + + /* + * Unsent outgoing msgs - add to tail + */ + if (!QTAILQ_EMPTY(&proxy->outgoing)) { + QTAILQ_INSERT_TAIL(&proxy->outgoing, msg, next); + proxy->num_outgoing++; + return true; + } + + /* + * Try inline - if blocked, queue it and kick send poller + */ + if (proxy->flags & VFIO_PROXY_FORCE_QUEUED) { + ret = QIO_CHANNEL_ERR_BLOCK; + } else { + ret = vfio_user_send_qio(proxy, msg, errp); + } + + if (ret == QIO_CHANNEL_ERR_BLOCK) { + QTAILQ_INSERT_HEAD(&proxy->outgoing, msg, next); + proxy->num_outgoing = 1; + qio_channel_set_aio_fd_handler(proxy->ioc, proxy->ctx, + vfio_user_recv, proxy->ctx, + vfio_user_send, proxy); + return true; + } + if (ret == -1) { + return false; + } + + /* + * Sent - free async, add others to pending + */ + if (msg->type == VFIO_MSG_ASYNC) { + vfio_user_recycle(proxy, msg); + } else { + QTAILQ_INSERT_TAIL(&proxy->pending, msg, next); + msg->pending = true; + } + + return true; +} + +/* + * nowait send - vfio_wait_reqs() can wait for it later + * + * Returns false if we did not successfully receive a reply message, in which + * case @errp will be populated. + * + * In either case, ownership of @hdr and @fds is taken, and the caller must + * *not* free them itself. + */ +bool vfio_user_send_nowait(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds, int rsize, Error **errp) +{ + VFIOUserMsg *msg; + + QEMU_LOCK_GUARD(&proxy->lock); + + msg = vfio_user_getmsg(proxy, hdr, fds); + msg->id = hdr->id; + msg->rsize = rsize ? rsize : hdr->size; + msg->type = VFIO_MSG_NOWAIT; + + if (hdr->flags & VFIO_USER_NO_REPLY) { + error_setg_errno(errp, EINVAL, "%s on NO_REPLY message", __func__); + vfio_user_recycle(proxy, msg); + return false; + } + + if (!vfio_user_send_queued(proxy, msg, errp)) { + vfio_user_recycle(proxy, msg); + return false; + } + + proxy->last_nowait = msg; + + return true; +} + +/* + * Returns false if we did not successfully receive a reply message, in which + * case @errp will be populated. + * + * In either case, the caller must free @hdr and @fds if needed. + */ +bool vfio_user_send_wait(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds, int rsize, Error **errp) +{ + VFIOUserMsg *msg; + bool ok = false; + + if (hdr->flags & VFIO_USER_NO_REPLY) { + error_setg_errno(errp, EINVAL, "%s on NO_REPLY message", __func__); + return false; + } + + qemu_mutex_lock(&proxy->lock); + + msg = vfio_user_getmsg(proxy, hdr, fds); + msg->id = hdr->id; + msg->rsize = rsize ? rsize : hdr->size; + msg->type = VFIO_MSG_WAIT; + + ok = vfio_user_send_queued(proxy, msg, errp); + + if (ok) { + while (!msg->complete) { + if (!qemu_cond_timedwait(&msg->cv, &proxy->lock, + proxy->wait_time)) { + VFIOUserMsgQ *list; + + list = msg->pending ? &proxy->pending : &proxy->outgoing; + QTAILQ_REMOVE(list, msg, next); + error_setg_errno(errp, ETIMEDOUT, + "timed out waiting for reply"); + ok = false; + break; + } + } + } + + vfio_user_recycle(proxy, msg); + + qemu_mutex_unlock(&proxy->lock); + + return ok; +} + +/* + * async send - msg can be queued, but will be freed when sent + * + * Returns false on failure, in which case @errp will be populated. + * + * In either case, ownership of @hdr and @fds is taken, and the caller must + * *not* free them itself. + */ +bool vfio_user_send_async(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds, Error **errp) +{ + VFIOUserMsg *msg; + + QEMU_LOCK_GUARD(&proxy->lock); + + msg = vfio_user_getmsg(proxy, hdr, fds); + msg->id = hdr->id; + msg->rsize = 0; + msg->type = VFIO_MSG_ASYNC; + + if (!(hdr->flags & (VFIO_USER_NO_REPLY | VFIO_USER_REPLY))) { + error_setg_errno(errp, EINVAL, "%s on sync message", __func__); + vfio_user_recycle(proxy, msg); + return false; + } + + if (!vfio_user_send_queued(proxy, msg, errp)) { + vfio_user_recycle(proxy, msg); + return false; + } + + return true; +} + +void vfio_user_wait_reqs(VFIOUserProxy *proxy) +{ + VFIOUserMsg *msg; + + /* + * Any DMA map/unmap requests sent in the middle + * of a memory region transaction were sent nowait. + * Wait for them here. + */ + qemu_mutex_lock(&proxy->lock); + if (proxy->last_nowait != NULL) { + /* + * Change type to WAIT to wait for reply + */ + msg = proxy->last_nowait; + msg->type = VFIO_MSG_WAIT; + proxy->last_nowait = NULL; + while (!msg->complete) { + if (!qemu_cond_timedwait(&msg->cv, &proxy->lock, + proxy->wait_time)) { + VFIOUserMsgQ *list; + + list = msg->pending ? &proxy->pending : &proxy->outgoing; + QTAILQ_REMOVE(list, msg, next); + error_printf("vfio_wait_reqs - timed out\n"); + break; + } + } + + if (msg->hdr->flags & VFIO_USER_ERROR) { + error_printf("vfio_user_wait_reqs - error reply on async "); + error_printf("request: command %x error %s\n", msg->hdr->command, + strerror(msg->hdr->error_reply)); + } + + /* + * Change type back to NOWAIT to free + */ + msg->type = VFIO_MSG_NOWAIT; + vfio_user_recycle(proxy, msg); + } + + qemu_mutex_unlock(&proxy->lock); +} + +/* + * Reply to an incoming request. + */ +void vfio_user_send_reply(VFIOUserProxy *proxy, VFIOUserHdr *hdr, int size) +{ + Error *local_err = NULL; + + if (size < sizeof(VFIOUserHdr)) { + error_printf("%s: size too small", __func__); + g_free(hdr); + return; + } + + /* + * convert header to associated reply + */ + hdr->flags = VFIO_USER_REPLY; + hdr->size = size; + + if (!vfio_user_send_async(proxy, hdr, NULL, &local_err)) { + error_report_err(local_err); + } +} + +/* + * Send an error reply to an incoming request. + */ +void vfio_user_send_error(VFIOUserProxy *proxy, VFIOUserHdr *hdr, int error) +{ + Error *local_err = NULL; + + /* + * convert header to associated reply + */ + hdr->flags = VFIO_USER_REPLY; + hdr->flags |= VFIO_USER_ERROR; + hdr->error_reply = error; + hdr->size = sizeof(*hdr); + + if (!vfio_user_send_async(proxy, hdr, NULL, &local_err)) { + error_report_err(local_err); + } +} + +/* + * Close FDs erroneously received in an incoming request. + */ +void vfio_user_putfds(VFIOUserMsg *msg) +{ + VFIOUserFDs *fds = msg->fds; + int i; + + for (i = 0; i < fds->recv_fds; i++) { + close(fds->fds[i]); + } + g_free(fds); + msg->fds = NULL; +} + +void +vfio_user_disable_posted_writes(VFIOUserProxy *proxy) +{ + WITH_QEMU_LOCK_GUARD(&proxy->lock) { + proxy->flags |= VFIO_PROXY_NO_POST; + } +} + +static QLIST_HEAD(, VFIOUserProxy) vfio_user_sockets = + QLIST_HEAD_INITIALIZER(vfio_user_sockets); + +VFIOUserProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp) +{ + VFIOUserProxy *proxy; + QIOChannelSocket *sioc; + QIOChannel *ioc; + char *sockname; + + if (addr->type != SOCKET_ADDRESS_TYPE_UNIX) { + error_setg(errp, "vfio_user_connect - bad address family"); + return NULL; + } + sockname = addr->u.q_unix.path; + + sioc = qio_channel_socket_new(); + ioc = QIO_CHANNEL(sioc); + if (qio_channel_socket_connect_sync(sioc, addr, errp)) { + object_unref(OBJECT(ioc)); + return NULL; + } + qio_channel_set_blocking(ioc, false, NULL); + + proxy = g_malloc0(sizeof(VFIOUserProxy)); + proxy->sockname = g_strdup_printf("unix:%s", sockname); + proxy->ioc = ioc; + + /* init defaults */ + proxy->max_xfer_size = VFIO_USER_DEF_MAX_XFER; + proxy->max_send_fds = VFIO_USER_DEF_MAX_FDS; + proxy->max_dma = VFIO_USER_DEF_MAP_MAX; + proxy->dma_pgsizes = VFIO_USER_DEF_PGSIZE; + proxy->max_bitmap = VFIO_USER_DEF_MAX_BITMAP; + proxy->migr_pgsize = VFIO_USER_DEF_PGSIZE; + + proxy->flags = VFIO_PROXY_CLIENT; + proxy->state = VFIO_PROXY_CONNECTED; + + qemu_mutex_init(&proxy->lock); + qemu_cond_init(&proxy->close_cv); + + if (vfio_user_iothread == NULL) { + vfio_user_iothread = iothread_create("VFIO user", errp); + } + + proxy->ctx = iothread_get_aio_context(vfio_user_iothread); + proxy->req_bh = qemu_bh_new(vfio_user_request, proxy); + + QTAILQ_INIT(&proxy->outgoing); + QTAILQ_INIT(&proxy->incoming); + QTAILQ_INIT(&proxy->free); + QTAILQ_INIT(&proxy->pending); + QLIST_INSERT_HEAD(&vfio_user_sockets, proxy, next); + + return proxy; +} + +void vfio_user_set_handler(VFIODevice *vbasedev, + void (*handler)(void *opaque, VFIOUserMsg *msg), + void *req_arg) +{ + VFIOUserProxy *proxy = vbasedev->proxy; + + proxy->request = handler; + proxy->req_arg = req_arg; + qio_channel_set_aio_fd_handler(proxy->ioc, proxy->ctx, + vfio_user_recv, NULL, NULL, proxy); +} + +void vfio_user_disconnect(VFIOUserProxy *proxy) +{ + VFIOUserMsg *r1, *r2; + + qemu_mutex_lock(&proxy->lock); + + /* our side is quitting */ + if (proxy->state == VFIO_PROXY_CONNECTED) { + vfio_user_shutdown(proxy); + if (!QTAILQ_EMPTY(&proxy->pending)) { + error_printf("vfio_user_disconnect: outstanding requests\n"); + } + } + object_unref(OBJECT(proxy->ioc)); + proxy->ioc = NULL; + qemu_bh_delete(proxy->req_bh); + proxy->req_bh = NULL; + + proxy->state = VFIO_PROXY_CLOSING; + QTAILQ_FOREACH_SAFE(r1, &proxy->outgoing, next, r2) { + qemu_cond_destroy(&r1->cv); + QTAILQ_REMOVE(&proxy->outgoing, r1, next); + g_free(r1); + } + QTAILQ_FOREACH_SAFE(r1, &proxy->incoming, next, r2) { + qemu_cond_destroy(&r1->cv); + QTAILQ_REMOVE(&proxy->incoming, r1, next); + g_free(r1); + } + QTAILQ_FOREACH_SAFE(r1, &proxy->pending, next, r2) { + qemu_cond_destroy(&r1->cv); + QTAILQ_REMOVE(&proxy->pending, r1, next); + g_free(r1); + } + QTAILQ_FOREACH_SAFE(r1, &proxy->free, next, r2) { + qemu_cond_destroy(&r1->cv); + QTAILQ_REMOVE(&proxy->free, r1, next); + g_free(r1); + } + + /* + * Make sure the iothread isn't blocking anywhere + * with a ref to this proxy by waiting for a BH + * handler to run after the proxy fd handlers were + * deleted above. + */ + aio_bh_schedule_oneshot(proxy->ctx, vfio_user_cb, proxy); + qemu_cond_wait(&proxy->close_cv, &proxy->lock); + + /* we now hold the only ref to proxy */ + qemu_mutex_unlock(&proxy->lock); + qemu_cond_destroy(&proxy->close_cv); + qemu_mutex_destroy(&proxy->lock); + + QLIST_REMOVE(proxy, next); + if (QLIST_EMPTY(&vfio_user_sockets)) { + iothread_destroy(vfio_user_iothread); + vfio_user_iothread = NULL; + } + + g_free(proxy->sockname); + g_free(proxy); +} + +void vfio_user_request_msg(VFIOUserHdr *hdr, uint16_t cmd, + uint32_t size, uint32_t flags) +{ + static uint16_t next_id; + + hdr->id = qatomic_fetch_inc(&next_id); + hdr->command = cmd; + hdr->size = size; + hdr->flags = (flags & ~VFIO_USER_TYPE) | VFIO_USER_REQUEST; + hdr->error_reply = 0; +} + +struct cap_entry { + const char *name; + bool (*check)(VFIOUserProxy *proxy, QObject *qobj, Error **errp); +}; + +static bool caps_parse(VFIOUserProxy *proxy, QDict *qdict, + struct cap_entry caps[], Error **errp) +{ + QObject *qobj; + struct cap_entry *p; + + for (p = caps; p->name != NULL; p++) { + qobj = qdict_get(qdict, p->name); + if (qobj != NULL) { + if (!p->check(proxy, qobj, errp)) { + return false; + } + qdict_del(qdict, p->name); + } + } + + /* warning, for now */ + if (qdict_size(qdict) != 0) { + warn_report("spurious capabilities"); + } + return true; +} + +static bool check_migr_pgsize(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QNum *qn = qobject_to(QNum, qobj); + uint64_t pgsize; + + if (qn == NULL || !qnum_get_try_uint(qn, &pgsize)) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_PGSIZE); + return false; + } + + /* must be larger than default */ + if (pgsize & (VFIO_USER_DEF_PGSIZE - 1)) { + error_setg(errp, "pgsize 0x%"PRIx64" too small", pgsize); + return false; + } + + proxy->migr_pgsize = pgsize; + return true; +} + +static bool check_bitmap(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QNum *qn = qobject_to(QNum, qobj); + uint64_t bitmap_size; + + if (qn == NULL || !qnum_get_try_uint(qn, &bitmap_size)) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_MAX_BITMAP); + return false; + } + + /* can only lower it */ + if (bitmap_size > VFIO_USER_DEF_MAX_BITMAP) { + error_setg(errp, "%s too large", VFIO_USER_CAP_MAX_BITMAP); + return false; + } + + proxy->max_bitmap = bitmap_size; + return true; +} + +static struct cap_entry caps_migr[] = { + { VFIO_USER_CAP_PGSIZE, check_migr_pgsize }, + { VFIO_USER_CAP_MAX_BITMAP, check_bitmap }, + { NULL } +}; + +static bool check_max_fds(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QNum *qn = qobject_to(QNum, qobj); + uint64_t max_send_fds; + + if (qn == NULL || !qnum_get_try_uint(qn, &max_send_fds) || + max_send_fds > VFIO_USER_MAX_MAX_FDS) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_MAX_FDS); + return false; + } + proxy->max_send_fds = max_send_fds; + return true; +} + +static bool check_max_xfer(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QNum *qn = qobject_to(QNum, qobj); + uint64_t max_xfer_size; + + if (qn == NULL || !qnum_get_try_uint(qn, &max_xfer_size) || + max_xfer_size > VFIO_USER_MAX_MAX_XFER) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_MAX_XFER); + return false; + } + proxy->max_xfer_size = max_xfer_size; + return true; +} + +static bool check_pgsizes(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QNum *qn = qobject_to(QNum, qobj); + uint64_t pgsizes; + + if (qn == NULL || !qnum_get_try_uint(qn, &pgsizes)) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_PGSIZES); + return false; + } + + /* must be larger than default */ + if (pgsizes & (VFIO_USER_DEF_PGSIZE - 1)) { + error_setg(errp, "pgsize 0x%"PRIx64" too small", pgsizes); + return false; + } + + proxy->dma_pgsizes = pgsizes; + return true; +} + +static bool check_max_dma(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QNum *qn = qobject_to(QNum, qobj); + uint64_t max_dma; + + if (qn == NULL || !qnum_get_try_uint(qn, &max_dma)) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_MAP_MAX); + return false; + } + + /* can only lower it */ + if (max_dma > VFIO_USER_DEF_MAP_MAX) { + error_setg(errp, "%s too large", VFIO_USER_CAP_MAP_MAX); + return false; + } + + proxy->max_dma = max_dma; + return true; +} + +static bool check_migr(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QDict *qdict = qobject_to(QDict, qobj); + + if (qdict == NULL) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_MAX_FDS); + return true; + } + return caps_parse(proxy, qdict, caps_migr, errp); +} + +static bool check_multi(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QBool *qb = qobject_to(QBool, qobj); + + if (qb == NULL) { + error_setg(errp, "malformed %s", VFIO_USER_CAP_MULTI); + return false; + } + if (qbool_get_bool(qb)) { + proxy->flags |= VFIO_PROXY_USE_MULTI; + } + return true; +} + +static struct cap_entry caps_cap[] = { + { VFIO_USER_CAP_MAX_FDS, check_max_fds }, + { VFIO_USER_CAP_MAX_XFER, check_max_xfer }, + { VFIO_USER_CAP_PGSIZES, check_pgsizes }, + { VFIO_USER_CAP_MAP_MAX, check_max_dma }, + { VFIO_USER_CAP_MIGR, check_migr }, + { VFIO_USER_CAP_MULTI, check_multi }, + { NULL } +}; + +static bool check_cap(VFIOUserProxy *proxy, QObject *qobj, Error **errp) +{ + QDict *qdict = qobject_to(QDict, qobj); + + if (qdict == NULL) { + error_setg(errp, "malformed %s", VFIO_USER_CAP); + return false; + } + return caps_parse(proxy, qdict, caps_cap, errp); +} + +static struct cap_entry ver_0_0[] = { + { VFIO_USER_CAP, check_cap }, + { NULL } +}; + +static bool caps_check(VFIOUserProxy *proxy, int minor, const char *caps, + Error **errp) +{ + QObject *qobj; + QDict *qdict; + bool ret; + + qobj = qobject_from_json(caps, NULL); + if (qobj == NULL) { + error_setg(errp, "malformed capabilities %s", caps); + return false; + } + qdict = qobject_to(QDict, qobj); + if (qdict == NULL) { + error_setg(errp, "capabilities %s not an object", caps); + qobject_unref(qobj); + return false; + } + ret = caps_parse(proxy, qdict, ver_0_0, errp); + + qobject_unref(qobj); + return ret; +} + +static GString *caps_json(void) +{ + QDict *dict = qdict_new(); + QDict *capdict = qdict_new(); + QDict *migdict = qdict_new(); + GString *str; + + qdict_put_int(migdict, VFIO_USER_CAP_PGSIZE, VFIO_USER_DEF_PGSIZE); + qdict_put_int(migdict, VFIO_USER_CAP_MAX_BITMAP, VFIO_USER_DEF_MAX_BITMAP); + qdict_put_obj(capdict, VFIO_USER_CAP_MIGR, QOBJECT(migdict)); + + qdict_put_int(capdict, VFIO_USER_CAP_MAX_FDS, VFIO_USER_MAX_MAX_FDS); + qdict_put_int(capdict, VFIO_USER_CAP_MAX_XFER, VFIO_USER_DEF_MAX_XFER); + qdict_put_int(capdict, VFIO_USER_CAP_PGSIZES, VFIO_USER_DEF_PGSIZE); + qdict_put_int(capdict, VFIO_USER_CAP_MAP_MAX, VFIO_USER_DEF_MAP_MAX); + qdict_put_bool(capdict, VFIO_USER_CAP_MULTI, true); + + qdict_put_obj(dict, VFIO_USER_CAP, QOBJECT(capdict)); + + str = qobject_to_json(QOBJECT(dict)); + qobject_unref(dict); + return str; +} + +bool vfio_user_validate_version(VFIOUserProxy *proxy, Error **errp) +{ + g_autofree VFIOUserVersion *msgp = NULL; + GString *caps; + char *reply; + int size, caplen; + + caps = caps_json(); + caplen = caps->len + 1; + size = sizeof(*msgp) + caplen; + msgp = g_malloc0(size); + + vfio_user_request_msg(&msgp->hdr, VFIO_USER_VERSION, size, 0); + msgp->major = VFIO_USER_MAJOR_VER; + msgp->minor = VFIO_USER_MINOR_VER; + memcpy(&msgp->capabilities, caps->str, caplen); + g_string_free(caps, true); + trace_vfio_user_version(msgp->major, msgp->minor, msgp->capabilities); + + if (!vfio_user_send_wait(proxy, &msgp->hdr, NULL, 0, errp)) { + return false; + } + + if (msgp->hdr.flags & VFIO_USER_ERROR) { + error_setg_errno(errp, msgp->hdr.error_reply, "version reply"); + return false; + } + + if (msgp->major != VFIO_USER_MAJOR_VER || + msgp->minor > VFIO_USER_MINOR_VER) { + error_setg(errp, "incompatible server version"); + return false; + } + + reply = msgp->capabilities; + if (reply[msgp->hdr.size - sizeof(*msgp) - 1] != '\0') { + error_setg(errp, "corrupt version reply"); + return false; + } + + if (!caps_check(proxy, msgp->minor, reply, errp)) { + return false; + } + + trace_vfio_user_version(msgp->major, msgp->minor, msgp->capabilities); + return true; +} + +void vfio_user_flush_multi(VFIOUserProxy *proxy) +{ + VFIOUserMsg *msg; + VFIOUserWRMulti *wm = proxy->wr_multi; + Error *local_err = NULL; + + proxy->wr_multi = NULL; + + /* adjust size for actual # of writes */ + wm->hdr.size -= (VFIO_USER_MULTI_MAX - wm->wr_cnt) * sizeof(VFIOUserWROne); + + msg = vfio_user_getmsg(proxy, &wm->hdr, NULL); + msg->id = wm->hdr.id; + msg->rsize = 0; + msg->type = VFIO_MSG_ASYNC; + trace_vfio_user_wrmulti("flush", wm->wr_cnt); + + if (!vfio_user_send_queued(proxy, msg, &local_err)) { + error_report_err(local_err); + vfio_user_recycle(proxy, msg); + } +} + +void vfio_user_create_multi(VFIOUserProxy *proxy) +{ + VFIOUserWRMulti *wm; + + wm = g_malloc0(sizeof(*wm)); + vfio_user_request_msg(&wm->hdr, VFIO_USER_REGION_WRITE_MULTI, + sizeof(*wm), VFIO_USER_NO_REPLY); + proxy->wr_multi = wm; +} + +void vfio_user_add_multi(VFIOUserProxy *proxy, uint8_t index, + off_t offset, uint32_t count, void *data) +{ + VFIOUserWRMulti *wm = proxy->wr_multi; + VFIOUserWROne *w1 = &wm->wrs[wm->wr_cnt]; + + w1->offset = offset; + w1->region = index; + w1->count = count; + memcpy(&w1->data, data, count); + + wm->wr_cnt++; + trace_vfio_user_wrmulti("add", wm->wr_cnt); + if (wm->wr_cnt == VFIO_USER_MULTI_MAX || + proxy->num_outgoing < VFIO_USER_OUT_LOW) { + vfio_user_flush_multi(proxy); + } +} diff --git a/hw/vfio-user/proxy.h b/hw/vfio-user/proxy.h new file mode 100644 index 0000000..61e64a0 --- /dev/null +++ b/hw/vfio-user/proxy.h @@ -0,0 +1,135 @@ +#ifndef VFIO_USER_PROXY_H +#define VFIO_USER_PROXY_H + +/* + * vfio protocol over a UNIX socket. + * + * Copyright © 2018, 2021 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "io/channel.h" +#include "io/channel-socket.h" + +#include "qemu/queue.h" +#include "qemu/sockets.h" +#include "qemu/thread.h" +#include "hw/vfio/vfio-device.h" +#include "hw/vfio-user/protocol.h" + +typedef struct { + int send_fds; + int recv_fds; + int *fds; +} VFIOUserFDs; + +enum msg_type { + VFIO_MSG_NONE, + VFIO_MSG_ASYNC, + VFIO_MSG_WAIT, + VFIO_MSG_NOWAIT, + VFIO_MSG_REQ, +}; + +typedef struct VFIOUserMsg { + QTAILQ_ENTRY(VFIOUserMsg) next; + VFIOUserHdr *hdr; + VFIOUserFDs *fds; + uint32_t rsize; + uint32_t id; + QemuCond cv; + bool complete; + bool pending; + enum msg_type type; +} VFIOUserMsg; + + +enum proxy_state { + VFIO_PROXY_CONNECTED = 1, + VFIO_PROXY_ERROR = 2, + VFIO_PROXY_CLOSING = 3, + VFIO_PROXY_CLOSED = 4, +}; + +typedef QTAILQ_HEAD(VFIOUserMsgQ, VFIOUserMsg) VFIOUserMsgQ; + +typedef struct VFIOUserProxy { + QLIST_ENTRY(VFIOUserProxy) next; + char *sockname; + struct QIOChannel *ioc; + void (*request)(void *opaque, VFIOUserMsg *msg); + void *req_arg; + uint64_t max_xfer_size; + uint64_t max_send_fds; + uint64_t max_dma; + uint64_t dma_pgsizes; + uint64_t max_bitmap; + uint64_t migr_pgsize; + int flags; + uint32_t wait_time; + QemuCond close_cv; + AioContext *ctx; + QEMUBH *req_bh; + bool async_ops; + + /* + * above only changed when BQL is held + * below are protected by per-proxy lock + */ + QemuMutex lock; + VFIOUserMsgQ free; + VFIOUserMsgQ pending; + VFIOUserMsgQ incoming; + VFIOUserMsgQ outgoing; + VFIOUserMsg *last_nowait; + VFIOUserMsg *part_recv; + size_t recv_left; + VFIOUserWRMulti *wr_multi; + int num_outgoing; + enum proxy_state state; +} VFIOUserProxy; + +/* VFIOProxy flags */ +#define VFIO_PROXY_CLIENT 0x1 +#define VFIO_PROXY_FORCE_QUEUED 0x4 +#define VFIO_PROXY_NO_POST 0x8 +#define VFIO_PROXY_USE_MULTI 0x16 + +/* coalescing high and low water marks for VFIOProxy num_outgoing */ +#define VFIO_USER_OUT_HIGH 1024 +#define VFIO_USER_OUT_LOW 128 + +typedef struct VFIODevice VFIODevice; + +VFIOUserProxy *vfio_user_connect_dev(SocketAddress *addr, Error **errp); +void vfio_user_disconnect(VFIOUserProxy *proxy); +void vfio_user_set_handler(VFIODevice *vbasedev, + void (*handler)(void *opaque, VFIOUserMsg *msg), + void *reqarg); +bool vfio_user_validate_version(VFIOUserProxy *proxy, Error **errp); + +VFIOUserFDs *vfio_user_getfds(int numfds); +void vfio_user_putfds(VFIOUserMsg *msg); + +void vfio_user_disable_posted_writes(VFIOUserProxy *proxy); + +void vfio_user_request_msg(VFIOUserHdr *hdr, uint16_t cmd, + uint32_t size, uint32_t flags); +void vfio_user_wait_reqs(VFIOUserProxy *proxy); +bool vfio_user_send_wait(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds, int rsize, Error **errp); +bool vfio_user_send_nowait(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds, int rsize, Error **errp); +bool vfio_user_send_async(VFIOUserProxy *proxy, VFIOUserHdr *hdr, + VFIOUserFDs *fds, Error **errp); + +void vfio_user_send_reply(VFIOUserProxy *proxy, VFIOUserHdr *hdr, int size); +void vfio_user_send_error(VFIOUserProxy *proxy, VFIOUserHdr *hdr, int error); + +void vfio_user_flush_multi(VFIOUserProxy *proxy); +void vfio_user_create_multi(VFIOUserProxy *proxy); +void vfio_user_add_multi(VFIOUserProxy *proxy, uint8_t index, + off_t offset, uint32_t count, void *data); + +#endif /* VFIO_USER_PROXY_H */ diff --git a/hw/vfio-user/trace-events b/hw/vfio-user/trace-events new file mode 100644 index 0000000..abb67f4 --- /dev/null +++ b/hw/vfio-user/trace-events @@ -0,0 +1,20 @@ +# See docs/devel/tracing.rst for syntax documentation. +# +# SPDX-License-Identifier: GPL-2.0-or-later + +# common.c +vfio_user_recv_hdr(const char *name, uint16_t id, uint16_t cmd, uint32_t size, uint32_t flags) " (%s) id 0x%x cmd 0x%x size 0x%x flags 0x%x" +vfio_user_recv_read(uint16_t id, int read) " id 0x%x read 0x%x" +vfio_user_recv_request(uint16_t cmd) " command 0x%x" +vfio_user_send_write(uint16_t id, int wrote) " id 0x%x wrote 0x%x" +vfio_user_version(uint16_t major, uint16_t minor, const char *caps) " major %d minor %d caps: %s" +vfio_user_get_info(uint32_t nregions, uint32_t nirqs) " #regions %d #irqs %d" +vfio_user_get_region_info(uint32_t index, uint32_t flags, uint64_t size) " index %d flags 0x%x size 0x%"PRIx64 +vfio_user_region_rw(uint32_t region, uint64_t off, uint32_t count) " region %d offset 0x%"PRIx64" count %d" +vfio_user_get_irq_info(uint32_t index, uint32_t flags, uint32_t count) " index %d flags 0x%x count %d" +vfio_user_set_irqs(uint32_t index, uint32_t start, uint32_t count, uint32_t flags) " index %d start %d count %d flags 0x%x" +vfio_user_wrmulti(const char *s, uint64_t wr_cnt) " %s count 0x%"PRIx64 + +# container.c +vfio_user_dma_map(uint64_t iova, uint64_t size, uint64_t off, uint32_t flags, bool async_ops) " iova 0x%"PRIx64" size 0x%"PRIx64" off 0x%"PRIx64" flags 0x%x async_ops %d" +vfio_user_dma_unmap(uint64_t iova, uint64_t size, uint32_t flags, bool async_ops) " iova 0x%"PRIx64" size 0x%"PRIx64" flags 0x%x async_ops %d" diff --git a/hw/vfio-user/trace.h b/hw/vfio-user/trace.h new file mode 100644 index 0000000..9cf02d9 --- /dev/null +++ b/hw/vfio-user/trace.h @@ -0,0 +1,4 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include "trace/trace-hw_vfio_user.h" diff --git a/hw/vfio/Kconfig b/hw/vfio/Kconfig index 7cdba05..91d9023 100644 --- a/hw/vfio/Kconfig +++ b/hw/vfio/Kconfig @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + config VFIO bool depends on LINUX diff --git a/hw/vfio/amd-xgbe.c b/hw/vfio/amd-xgbe.c index 5927503..58f590e 100644 --- a/hw/vfio/amd-xgbe.c +++ b/hw/vfio/amd-xgbe.c @@ -34,7 +34,7 @@ static const VMStateDescription vfio_platform_amd_xgbe_vmstate = { .unmigratable = 1, }; -static void vfio_amd_xgbe_class_init(ObjectClass *klass, void *data) +static void vfio_amd_xgbe_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VFIOAmdXgbeDeviceClass *vcxc = diff --git a/hw/vfio/ap.c b/hw/vfio/ap.c index c7ab4ff..1df4438 100644 --- a/hw/vfio/ap.c +++ b/hw/vfio/ap.c @@ -10,16 +10,19 @@ * directory. */ +#include <stdbool.h> #include "qemu/osdep.h" #include CONFIG_DEVICES /* CONFIG_IOMMUFD */ #include <linux/vfio.h> #include <sys/ioctl.h> #include "qapi/error.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "system/iommufd.h" #include "hw/s390x/ap-device.h" +#include "hw/s390x/css.h" #include "qemu/error-report.h" #include "qemu/event_notifier.h" +#include "qemu/lockable.h" #include "qemu/main-loop.h" #include "qemu/module.h" #include "qemu/option.h" @@ -28,7 +31,7 @@ #include "migration/vmstate.h" #include "hw/qdev-properties.h" #include "hw/s390x/ap-bridge.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qom/object.h" #define TYPE_VFIO_AP_DEVICE "vfio-ap" @@ -37,8 +40,23 @@ struct VFIOAPDevice { APDevice apdev; VFIODevice vdev; EventNotifier req_notifier; + EventNotifier cfg_notifier; }; +typedef struct APConfigChgEvent { + QTAILQ_ENTRY(APConfigChgEvent) next; +} APConfigChgEvent; + +static QTAILQ_HEAD(, APConfigChgEvent) cfg_chg_events = + QTAILQ_HEAD_INITIALIZER(cfg_chg_events); + +static QemuMutex cfg_chg_events_lock; + +static void __attribute__((constructor)) vfio_ap_global_init(void) +{ + qemu_mutex_init(&cfg_chg_events_lock); +} + OBJECT_DECLARE_SIMPLE_TYPE(VFIOAPDevice, VFIO_AP_DEVICE) static void vfio_ap_compute_needs_reset(VFIODevice *vdev) @@ -70,14 +88,65 @@ static void vfio_ap_req_notifier_handler(void *opaque) } } +static void vfio_ap_cfg_chg_notifier_handler(void *opaque) +{ + APConfigChgEvent *cfg_chg_event; + VFIOAPDevice *vapdev = opaque; + + if (!event_notifier_test_and_clear(&vapdev->cfg_notifier)) { + return; + } + + cfg_chg_event = g_new0(APConfigChgEvent, 1); + + WITH_QEMU_LOCK_GUARD(&cfg_chg_events_lock) { + QTAILQ_INSERT_TAIL(&cfg_chg_events, cfg_chg_event, next); + } + + css_generate_css_crws(0); + +} + +int ap_chsc_sei_nt0_get_event(void *res) +{ + ChscSeiNt0Res *nt0_res = (ChscSeiNt0Res *)res; + APConfigChgEvent *cfg_chg_event; + + WITH_QEMU_LOCK_GUARD(&cfg_chg_events_lock) { + if (QTAILQ_EMPTY(&cfg_chg_events)) { + return EVENT_INFORMATION_NOT_STORED; + } + + cfg_chg_event = QTAILQ_FIRST(&cfg_chg_events); + QTAILQ_REMOVE(&cfg_chg_events, cfg_chg_event, next); + } + + memset(nt0_res, 0, sizeof(*nt0_res)); + g_free(cfg_chg_event); + nt0_res->flags |= PENDING_EVENT_INFO_BITMASK; + nt0_res->length = sizeof(ChscSeiNt0Res); + nt0_res->code = NT0_RES_RESPONSE_CODE; + nt0_res->nt = NT0_RES_NT_DEFAULT; + nt0_res->rs = NT0_RES_RS_AP_CHANGE; + nt0_res->cc = NT0_RES_CC_AP_CHANGE; + + return EVENT_INFORMATION_STORED; +} + +bool ap_chsc_sei_nt0_have_event(void) +{ + QEMU_LOCK_GUARD(&cfg_chg_events_lock); + return !QTAILQ_EMPTY(&cfg_chg_events); +} + static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev, unsigned int irq, Error **errp) { int fd; - size_t argsz; + int ret; IOHandler *fd_read; EventNotifier *notifier; - g_autofree struct vfio_irq_info *irq_info = NULL; + struct vfio_irq_info irq_info; VFIODevice *vdev = &vapdev->vdev; switch (irq) { @@ -85,6 +154,10 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev, notifier = &vapdev->req_notifier; fd_read = vfio_ap_req_notifier_handler; break; + case VFIO_AP_CFG_CHG_IRQ_INDEX: + notifier = &vapdev->cfg_notifier; + fd_read = vfio_ap_cfg_chg_notifier_handler; + break; default: error_setg(errp, "vfio: Unsupported device irq(%d)", irq); return false; @@ -96,14 +169,15 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev, return false; } - argsz = sizeof(*irq_info); - irq_info = g_malloc0(argsz); - irq_info->index = irq; - irq_info->argsz = argsz; + ret = vfio_device_get_irq_info(vdev, irq, &irq_info); - if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, - irq_info) < 0 || irq_info->count < 1) { - error_setg_errno(errp, errno, "vfio: Error getting irq info"); + if (ret < 0) { + error_setg_errno(errp, -ret, "vfio: Error getting irq info"); + return false; + } + + if (irq_info.count < 1) { + error_setg(errp, "vfio: Error getting irq info, count=0"); return false; } @@ -117,8 +191,8 @@ static bool vfio_ap_register_irq_notifier(VFIOAPDevice *vapdev, fd = event_notifier_get_fd(notifier); qemu_set_fd_handler(fd, fd_read, NULL, vapdev); - if (!vfio_set_irq_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd, - errp)) { + if (!vfio_device_irq_set_signaling(vdev, irq, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd, + errp)) { qemu_set_fd_handler(fd, NULL, NULL, vapdev); event_notifier_cleanup(notifier); } @@ -136,13 +210,16 @@ static void vfio_ap_unregister_irq_notifier(VFIOAPDevice *vapdev, case VFIO_AP_REQ_IRQ_INDEX: notifier = &vapdev->req_notifier; break; + case VFIO_AP_CFG_CHG_IRQ_INDEX: + notifier = &vapdev->cfg_notifier; + break; default: error_report("vfio: Unsupported device irq(%d)", irq); return; } - if (!vfio_set_irq_signaling(&vapdev->vdev, irq, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { + if (!vfio_device_irq_set_signaling(&vapdev->vdev, irq, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { warn_reportf_err(err, VFIO_MSG_PREFIX, vapdev->vdev.name); } @@ -162,7 +239,7 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp) return; } - if (!vfio_attach_device(vbasedev->name, vbasedev, + if (!vfio_device_attach(vbasedev->name, vbasedev, &address_space_memory, errp)) { goto error; } @@ -175,6 +252,15 @@ static void vfio_ap_realize(DeviceState *dev, Error **errp) warn_report_err(err); } + if (!vfio_ap_register_irq_notifier(vapdev, VFIO_AP_CFG_CHG_IRQ_INDEX, &err)) + { + /* + * Report this error, but do not make it a failing condition. + * Lack of this IRQ in the host does not prevent normal operation. + */ + warn_report_err(err); + } + return; error: @@ -187,7 +273,8 @@ static void vfio_ap_unrealize(DeviceState *dev) VFIOAPDevice *vapdev = VFIO_AP_DEVICE(dev); vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_REQ_IRQ_INDEX); - vfio_detach_device(&vapdev->vdev); + vfio_ap_unregister_irq_notifier(vapdev, VFIO_AP_CFG_CHG_IRQ_INDEX); + vfio_device_detach(&vapdev->vdev); g_free(vapdev->vdev.name); } @@ -241,7 +328,7 @@ static void vfio_ap_set_fd(Object *obj, const char *str, Error **errp) } #endif -static void vfio_ap_class_init(ObjectClass *klass, void *data) +static void vfio_ap_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/vfio/calxeda-xgmac.c b/hw/vfio/calxeda-xgmac.c index a5ef262..03f2ff5 100644 --- a/hw/vfio/calxeda-xgmac.c +++ b/hw/vfio/calxeda-xgmac.c @@ -34,7 +34,7 @@ static const VMStateDescription vfio_platform_calxeda_xgmac_vmstate = { .unmigratable = 1, }; -static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, void *data) +static void vfio_calxeda_xgmac_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VFIOCalxedaXgmacDeviceClass *vcxc = diff --git a/hw/vfio/ccw.c b/hw/vfio/ccw.c index e5e0d9e..cea9d6e 100644 --- a/hw/vfio/ccw.c +++ b/hw/vfio/ccw.c @@ -21,13 +21,13 @@ #include <sys/ioctl.h> #include "qapi/error.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "system/iommufd.h" #include "hw/s390x/s390-ccw.h" #include "hw/s390x/vfio-ccw.h" #include "hw/qdev-properties.h" #include "hw/s390x/ccw-device.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" #include "qemu/module.h" @@ -376,8 +376,8 @@ static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, Error **errp) { VFIODevice *vdev = &vcdev->vdev; - g_autofree struct vfio_irq_info *irq_info = NULL; - size_t argsz; + struct vfio_irq_info irq_info; + int ret; int fd; EventNotifier *notifier; IOHandler *fd_read; @@ -406,13 +406,15 @@ static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, return false; } - argsz = sizeof(*irq_info); - irq_info = g_malloc0(argsz); - irq_info->index = irq; - irq_info->argsz = argsz; - if (ioctl(vdev->fd, VFIO_DEVICE_GET_IRQ_INFO, - irq_info) < 0 || irq_info->count < 1) { - error_setg_errno(errp, errno, "vfio: Error getting irq info"); + ret = vfio_device_get_irq_info(vdev, irq, &irq_info); + + if (ret < 0) { + error_setg_errno(errp, -ret, "vfio: Error getting irq info"); + return false; + } + + if (irq_info.count < 1) { + error_setg(errp, "vfio: Error getting irq info, count=0"); return false; } @@ -426,8 +428,8 @@ static bool vfio_ccw_register_irq_notifier(VFIOCCWDevice *vcdev, fd = event_notifier_get_fd(notifier); qemu_set_fd_handler(fd, fd_read, NULL, vcdev); - if (!vfio_set_irq_signaling(vdev, irq, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) { + if (!vfio_device_irq_set_signaling(vdev, irq, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) { qemu_set_fd_handler(fd, NULL, NULL, vcdev); event_notifier_cleanup(notifier); } @@ -456,8 +458,8 @@ static void vfio_ccw_unregister_irq_notifier(VFIOCCWDevice *vcdev, return; } - if (!vfio_set_irq_signaling(&vcdev->vdev, irq, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { + if (!vfio_device_irq_set_signaling(&vcdev->vdev, irq, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { warn_reportf_err(err, VFIO_MSG_PREFIX, vcdev->vdev.name); } @@ -488,7 +490,7 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp) return false; } - ret = vfio_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info); + ret = vfio_device_get_region_info(vdev, VFIO_CCW_CONFIG_REGION_INDEX, &info); if (ret) { error_setg_errno(errp, -ret, "vfio: Error getting config info"); return false; @@ -502,11 +504,10 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp) vcdev->io_region_offset = info->offset; vcdev->io_region = g_malloc0(info->size); - g_free(info); /* check for the optional async command region */ - ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, - VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info); + ret = vfio_device_get_region_info_type(vdev, VFIO_REGION_TYPE_CCW, + VFIO_REGION_SUBTYPE_CCW_ASYNC_CMD, &info); if (!ret) { vcdev->async_cmd_region_size = info->size; if (sizeof(*vcdev->async_cmd_region) != vcdev->async_cmd_region_size) { @@ -515,11 +516,10 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp) } vcdev->async_cmd_region_offset = info->offset; vcdev->async_cmd_region = g_malloc0(info->size); - g_free(info); } - ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, - VFIO_REGION_SUBTYPE_CCW_SCHIB, &info); + ret = vfio_device_get_region_info_type(vdev, VFIO_REGION_TYPE_CCW, + VFIO_REGION_SUBTYPE_CCW_SCHIB, &info); if (!ret) { vcdev->schib_region_size = info->size; if (sizeof(*vcdev->schib_region) != vcdev->schib_region_size) { @@ -528,11 +528,10 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp) } vcdev->schib_region_offset = info->offset; vcdev->schib_region = g_malloc(info->size); - g_free(info); } - ret = vfio_get_dev_region_info(vdev, VFIO_REGION_TYPE_CCW, - VFIO_REGION_SUBTYPE_CCW_CRW, &info); + ret = vfio_device_get_region_info_type(vdev, VFIO_REGION_TYPE_CCW, + VFIO_REGION_SUBTYPE_CCW_CRW, &info); if (!ret) { vcdev->crw_region_size = info->size; @@ -542,7 +541,6 @@ static bool vfio_ccw_get_region(VFIOCCWDevice *vcdev, Error **errp) } vcdev->crw_region_offset = info->offset; vcdev->crw_region = g_malloc(info->size); - g_free(info); } return true; @@ -552,7 +550,6 @@ out_err: g_free(vcdev->schib_region); g_free(vcdev->async_cmd_region); g_free(vcdev->io_region); - g_free(info); return false; } @@ -583,7 +580,7 @@ static void vfio_ccw_realize(DeviceState *dev, Error **errp) goto out_unrealize; } - if (!vfio_attach_device(cdev->mdevid, vbasedev, + if (!vfio_device_attach(cdev->mdevid, vbasedev, &address_space_memory, errp)) { goto out_attach_dev_err; } @@ -620,7 +617,7 @@ out_irq_notifier_err: out_io_notifier_err: vfio_ccw_put_region(vcdev); out_region_err: - vfio_detach_device(vbasedev); + vfio_device_detach(vbasedev); out_attach_dev_err: g_free(vbasedev->name); out_unrealize: @@ -639,7 +636,7 @@ static void vfio_ccw_unrealize(DeviceState *dev) vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_CRW_IRQ_INDEX); vfio_ccw_unregister_irq_notifier(vcdev, VFIO_CCW_IO_IRQ_INDEX); vfio_ccw_put_region(vcdev); - vfio_detach_device(&vcdev->vdev); + vfio_device_detach(&vcdev->vdev); g_free(vcdev->vdev.name); if (cdc->unrealize) { @@ -689,7 +686,7 @@ static void vfio_ccw_set_fd(Object *obj, const char *str, Error **errp) } #endif -static void vfio_ccw_class_init(ObjectClass *klass, void *data) +static void vfio_ccw_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); S390CCWDeviceClass *cdc = S390_CCW_DEVICE_CLASS(klass); diff --git a/hw/vfio/container-base.c b/hw/vfio/container-base.c index 749a3fd..d834bd4 100644 --- a/hw/vfio/container-base.c +++ b/hw/vfio/container-base.c @@ -10,29 +10,87 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ +#include <sys/ioctl.h> +#include <linux/vfio.h> + #include "qemu/osdep.h" +#include "system/tcg.h" +#include "system/ram_addr.h" #include "qapi/error.h" #include "qemu/error-report.h" #include "hw/vfio/vfio-container-base.h" +#include "hw/vfio/vfio-device.h" /* vfio_device_reset_handler */ +#include "system/reset.h" +#include "vfio-helpers.h" + +#include "trace.h" + +static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces = + QLIST_HEAD_INITIALIZER(vfio_address_spaces); + +VFIOAddressSpace *vfio_address_space_get(AddressSpace *as) +{ + VFIOAddressSpace *space; + + QLIST_FOREACH(space, &vfio_address_spaces, list) { + if (space->as == as) { + return space; + } + } + + /* No suitable VFIOAddressSpace, create a new one */ + space = g_malloc0(sizeof(*space)); + space->as = as; + QLIST_INIT(&space->containers); + + if (QLIST_EMPTY(&vfio_address_spaces)) { + qemu_register_reset(vfio_device_reset_handler, NULL); + } + + QLIST_INSERT_HEAD(&vfio_address_spaces, space, list); + + return space; +} + +void vfio_address_space_put(VFIOAddressSpace *space) +{ + if (!QLIST_EMPTY(&space->containers)) { + return; + } + + QLIST_REMOVE(space, list); + g_free(space); + + if (QLIST_EMPTY(&vfio_address_spaces)) { + qemu_unregister_reset(vfio_device_reset_handler, NULL); + } +} + +void vfio_address_space_insert(VFIOAddressSpace *space, + VFIOContainerBase *bcontainer) +{ + QLIST_INSERT_HEAD(&space->containers, bcontainer, next); + bcontainer->space = space; +} int vfio_container_dma_map(VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - void *vaddr, bool readonly) + void *vaddr, bool readonly, MemoryRegion *mr) { VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); g_assert(vioc->dma_map); - return vioc->dma_map(bcontainer, iova, size, vaddr, readonly); + return vioc->dma_map(bcontainer, iova, size, vaddr, readonly, mr); } int vfio_container_dma_unmap(VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) + IOMMUTLBEntry *iotlb, bool unmap_all) { VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); g_assert(vioc->dma_unmap); - return vioc->dma_unmap(bcontainer, iova, size, iotlb); + return vioc->dma_unmap(bcontainer, iova, size, iotlb, unmap_all); } bool vfio_container_add_section_window(VFIOContainerBase *bcontainer, @@ -83,7 +141,67 @@ int vfio_container_set_dirty_page_tracking(VFIOContainerBase *bcontainer, return ret; } -int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, +static bool vfio_container_devices_dirty_tracking_is_started( + const VFIOContainerBase *bcontainer) +{ + VFIODevice *vbasedev; + + QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { + if (!vbasedev->dirty_tracking) { + return false; + } + } + + return true; +} + +bool vfio_container_dirty_tracking_is_started( + const VFIOContainerBase *bcontainer) +{ + return vfio_container_devices_dirty_tracking_is_started(bcontainer) || + bcontainer->dirty_pages_started; +} + +bool vfio_container_devices_dirty_tracking_is_supported( + const VFIOContainerBase *bcontainer) +{ + VFIODevice *vbasedev; + + QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { + if (vbasedev->device_dirty_page_tracking == ON_OFF_AUTO_OFF) { + return false; + } + if (!vbasedev->dirty_pages_supported) { + return false; + } + } + + return true; +} + +static int vfio_device_dma_logging_report(VFIODevice *vbasedev, hwaddr iova, + hwaddr size, void *bitmap) +{ + uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature) + + sizeof(struct vfio_device_feature_dma_logging_report), + sizeof(uint64_t))] = {}; + struct vfio_device_feature *feature = (struct vfio_device_feature *)buf; + struct vfio_device_feature_dma_logging_report *report = + (struct vfio_device_feature_dma_logging_report *)feature->data; + + report->iova = iova; + report->length = size; + report->page_size = qemu_real_host_page_size(); + report->bitmap = (uintptr_t)bitmap; + + feature->argsz = sizeof(buf); + feature->flags = VFIO_DEVICE_FEATURE_GET | + VFIO_DEVICE_FEATURE_DMA_LOGGING_REPORT; + + return vbasedev->io_ops->device_feature(vbasedev, feature); +} + +static int vfio_container_iommu_query_dirty_bitmap(const VFIOContainerBase *bcontainer, VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp) { VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); @@ -93,6 +211,74 @@ int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, errp); } +static int vfio_container_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer, + VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp) +{ + VFIODevice *vbasedev; + int ret; + + QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { + ret = vfio_device_dma_logging_report(vbasedev, iova, size, + vbmap->bitmap); + if (ret) { + error_setg_errno(errp, -ret, + "%s: Failed to get DMA logging report, iova: " + "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx, + vbasedev->name, iova, size); + + return ret; + } + } + + return 0; +} + +int vfio_container_query_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, + uint64_t size, ram_addr_t ram_addr, Error **errp) +{ + bool all_device_dirty_tracking = + vfio_container_devices_dirty_tracking_is_supported(bcontainer); + uint64_t dirty_pages; + VFIOBitmap vbmap; + int ret; + + if (!bcontainer->dirty_pages_supported && !all_device_dirty_tracking) { + cpu_physical_memory_set_dirty_range(ram_addr, size, + tcg_enabled() ? DIRTY_CLIENTS_ALL : + DIRTY_CLIENTS_NOCODE); + return 0; + } + + ret = vfio_bitmap_alloc(&vbmap, size); + if (ret) { + error_setg_errno(errp, -ret, + "Failed to allocate dirty tracking bitmap"); + return ret; + } + + if (all_device_dirty_tracking) { + ret = vfio_container_devices_query_dirty_bitmap(bcontainer, &vbmap, iova, size, + errp); + } else { + ret = vfio_container_iommu_query_dirty_bitmap(bcontainer, &vbmap, iova, size, + errp); + } + + if (ret) { + goto out; + } + + dirty_pages = cpu_physical_memory_set_dirty_lebitmap(vbmap.bitmap, ram_addr, + vbmap.pages); + + trace_vfio_container_query_dirty_bitmap(iova, size, vbmap.size, ram_addr, + dirty_pages); +out: + g_free(vbmap.bitmap); + + return ret; +} + static gpointer copy_iova_range(gconstpointer src, gpointer data) { Range *source = (Range *)src; diff --git a/hw/vfio/container.c b/hw/vfio/container.c index 7c57bdd2..3e13fea 100644 --- a/hw/vfio/container.c +++ b/hw/vfio/container.c @@ -22,18 +22,26 @@ #include <sys/ioctl.h> #include <linux/vfio.h> -#include "hw/vfio/vfio-common.h" -#include "exec/address-spaces.h" -#include "exec/memory.h" -#include "exec/ram_addr.h" +#include "hw/vfio/vfio-device.h" +#include "system/address-spaces.h" +#include "system/memory.h" +#include "system/ram_addr.h" #include "qemu/error-report.h" #include "qemu/range.h" #include "system/reset.h" #include "trace.h" #include "qapi/error.h" +#include "migration/cpr.h" +#include "migration/blocker.h" #include "pci.h" +#include "hw/vfio/vfio-container.h" +#include "vfio-helpers.h" +#include "vfio-listener.h" -VFIOGroupList vfio_group_list = +#define TYPE_HOST_IOMMU_DEVICE_LEGACY_VFIO TYPE_HOST_IOMMU_DEVICE "-legacy-vfio" + +typedef QLIST_HEAD(VFIOGroupList, VFIOGroup) VFIOGroupList; +static VFIOGroupList vfio_group_list = QLIST_HEAD_INITIALIZER(vfio_group_list); static int vfio_ram_block_discard_disable(VFIOContainer *container, bool state) @@ -112,12 +120,9 @@ unmap_exit: return ret; } -/* - * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86 - */ -static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, - hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) +static int vfio_legacy_dma_unmap_one(const VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + IOMMUTLBEntry *iotlb) { const VFIOContainer *container = container_of(bcontainer, VFIOContainer, bcontainer); @@ -131,8 +136,10 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, int ret; Error *local_err = NULL; - if (iotlb && vfio_devices_all_dirty_tracking_started(bcontainer)) { - if (!vfio_devices_all_device_dirty_tracking(bcontainer) && + g_assert(!cpr_is_incoming()); + + if (iotlb && vfio_container_dirty_tracking_is_started(bcontainer)) { + if (!vfio_container_devices_dirty_tracking_is_supported(bcontainer) && bcontainer->dirty_pages_supported) { return vfio_dma_unmap_bitmap(container, iova, size, iotlb); } @@ -163,7 +170,7 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, } if (need_dirty_sync) { - ret = vfio_get_dirty_bitmap(bcontainer, iova, size, + ret = vfio_container_query_dirty_bitmap(bcontainer, iova, size, iotlb->translated_addr, &local_err); if (ret) { error_report_err(local_err); @@ -174,8 +181,37 @@ static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, return 0; } +/* + * DMA - Mapping and unmapping for the "type1" IOMMU interface used on x86 + */ +static int vfio_legacy_dma_unmap(const VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, + IOMMUTLBEntry *iotlb, bool unmap_all) +{ + int ret; + + if (unmap_all) { + /* The unmap ioctl doesn't accept a full 64-bit span. */ + Int128 llsize = int128_rshift(int128_2_64(), 1); + + ret = vfio_legacy_dma_unmap_one(bcontainer, 0, int128_get64(llsize), + iotlb); + + if (ret == 0) { + ret = vfio_legacy_dma_unmap_one(bcontainer, int128_get64(llsize), + int128_get64(llsize), iotlb); + } + + } else { + ret = vfio_legacy_dma_unmap_one(bcontainer, iova, size, iotlb); + } + + return ret; +} + static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova, - ram_addr_t size, void *vaddr, bool readonly) + ram_addr_t size, void *vaddr, bool readonly, + MemoryRegion *mr) { const VFIOContainer *container = container_of(bcontainer, VFIOContainer, bcontainer); @@ -198,7 +234,7 @@ static int vfio_legacy_dma_map(const VFIOContainerBase *bcontainer, hwaddr iova, */ if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0 || (errno == EBUSY && - vfio_legacy_dma_unmap(bcontainer, iova, size, NULL) == 0 && + vfio_legacy_dma_unmap(bcontainer, iova, size, NULL, false) == 0 && ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map) == 0)) { return 0; } @@ -273,37 +309,6 @@ static int vfio_legacy_query_dirty_bitmap(const VFIOContainerBase *bcontainer, return ret; } -static struct vfio_info_cap_header * -vfio_get_iommu_type1_info_cap(struct vfio_iommu_type1_info *info, uint16_t id) -{ - if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) { - return NULL; - } - - return vfio_get_cap((void *)info, info->cap_offset, id); -} - -bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, - unsigned int *avail) -{ - struct vfio_info_cap_header *hdr; - struct vfio_iommu_type1_info_dma_avail *cap; - - /* If the capability cannot be found, assume no DMA limiting */ - hdr = vfio_get_iommu_type1_info_cap(info, - VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL); - if (!hdr) { - return false; - } - - if (avail != NULL) { - cap = (void *) hdr; - *avail = cap->avail; - } - - return true; -} - static bool vfio_get_info_iova_range(struct vfio_iommu_type1_info *info, VFIOContainerBase *bcontainer) { @@ -330,7 +335,7 @@ static bool vfio_get_info_iova_range(struct vfio_iommu_type1_info *info, return true; } -static void vfio_kvm_device_add_group(VFIOGroup *group) +static void vfio_group_add_kvm_device(VFIOGroup *group) { Error *err = NULL; @@ -339,7 +344,7 @@ static void vfio_kvm_device_add_group(VFIOGroup *group) } } -static void vfio_kvm_device_del_group(VFIOGroup *group) +static void vfio_group_del_kvm_device(VFIOGroup *group) { Error *err = NULL; @@ -424,7 +429,12 @@ static VFIOContainer *vfio_create_container(int fd, VFIOGroup *group, return NULL; } - if (!vfio_set_iommu(fd, group->fd, &iommu_type, errp)) { + /* + * During CPR, just set the container type and skip the ioctls, as the + * container and group are already configured in the kernel. + */ + if (!cpr_is_incoming() && + !vfio_set_iommu(fd, group->fd, &iommu_type, errp)) { return NULL; } @@ -535,16 +545,10 @@ static bool vfio_legacy_setup(VFIOContainerBase *bcontainer, Error **errp) return true; } -static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as, - Error **errp) +static bool vfio_container_attach_discard_disable(VFIOContainer *container, + VFIOGroup *group, Error **errp) { - VFIOContainer *container; - VFIOContainerBase *bcontainer; - int ret, fd; - VFIOAddressSpace *space; - VFIOIOMMUClass *vioc; - - space = vfio_get_address_space(as); + int ret; /* * VFIO is currently incompatible with discarding of RAM insofar as the @@ -577,108 +581,158 @@ static bool vfio_connect_container(VFIOGroup *group, AddressSpace *as, * details once we know which type of IOMMU we are using. */ - QLIST_FOREACH(bcontainer, &space->containers, next) { - container = container_of(bcontainer, VFIOContainer, bcontainer); - if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) { - ret = vfio_ram_block_discard_disable(container, true); - if (ret) { - error_setg_errno(errp, -ret, - "Cannot set discarding of RAM broken"); - if (ioctl(group->fd, VFIO_GROUP_UNSET_CONTAINER, - &container->fd)) { - error_report("vfio: error disconnecting group %d from" - " container", group->groupid); - } - return false; - } - group->container = container; - QLIST_INSERT_HEAD(&container->group_list, group, container_next); - vfio_kvm_device_add_group(group); - return true; + ret = vfio_ram_block_discard_disable(container, true); + if (ret) { + error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken"); + if (ioctl(group->fd, VFIO_GROUP_UNSET_CONTAINER, &container->fd)) { + error_report("vfio: error disconnecting group %d from" + " container", group->groupid); } } + return !ret; +} - fd = qemu_open("/dev/vfio/vfio", O_RDWR, errp); - if (fd < 0) { - goto put_space_exit; +static bool vfio_container_group_add(VFIOContainer *container, VFIOGroup *group, + Error **errp) +{ + if (!vfio_container_attach_discard_disable(container, group, errp)) { + return false; + } + group->container = container; + QLIST_INSERT_HEAD(&container->group_list, group, container_next); + vfio_group_add_kvm_device(group); + /* + * Remember the container fd for each group, so we can attach to the same + * container after CPR. + */ + cpr_resave_fd("vfio_container_for_group", group->groupid, container->fd); + return true; +} + +static void vfio_container_group_del(VFIOContainer *container, VFIOGroup *group) +{ + QLIST_REMOVE(group, container_next); + group->container = NULL; + vfio_group_del_kvm_device(group); + vfio_ram_block_discard_disable(container, false); + cpr_delete_fd("vfio_container_for_group", group->groupid); +} + +static bool vfio_container_connect(VFIOGroup *group, AddressSpace *as, + Error **errp) +{ + VFIOContainer *container; + VFIOContainerBase *bcontainer; + int ret, fd = -1; + VFIOAddressSpace *space; + VFIOIOMMUClass *vioc = NULL; + bool new_container = false; + bool group_was_added = false; + + space = vfio_address_space_get(as); + fd = cpr_find_fd("vfio_container_for_group", group->groupid); + + if (!cpr_is_incoming()) { + QLIST_FOREACH(bcontainer, &space->containers, next) { + container = container_of(bcontainer, VFIOContainer, bcontainer); + if (!ioctl(group->fd, VFIO_GROUP_SET_CONTAINER, &container->fd)) { + return vfio_container_group_add(container, group, errp); + } + } + + fd = qemu_open("/dev/vfio/vfio", O_RDWR, errp); + if (fd < 0) { + goto fail; + } + } else { + /* + * For incoming CPR, the group is already attached in the kernel. + * If a container with matching fd is found, then update the + * userland group list and return. If not, then after the loop, + * create the container struct and group list. + */ + QLIST_FOREACH(bcontainer, &space->containers, next) { + container = container_of(bcontainer, VFIOContainer, bcontainer); + + if (vfio_cpr_container_match(container, group, fd)) { + return vfio_container_group_add(container, group, errp); + } + } } ret = ioctl(fd, VFIO_GET_API_VERSION); if (ret != VFIO_API_VERSION) { error_setg(errp, "supported vfio version: %d, " "reported version: %d", VFIO_API_VERSION, ret); - goto close_fd_exit; + goto fail; } container = vfio_create_container(fd, group, errp); if (!container) { - goto close_fd_exit; + goto fail; } + new_container = true; bcontainer = &container->bcontainer; - if (!vfio_cpr_register_container(bcontainer, errp)) { - goto free_container_exit; - } - - ret = vfio_ram_block_discard_disable(container, true); - if (ret) { - error_setg_errno(errp, -ret, "Cannot set discarding of RAM broken"); - goto unregister_container_exit; + if (!vfio_legacy_cpr_register_container(container, errp)) { + goto fail; } vioc = VFIO_IOMMU_GET_CLASS(bcontainer); assert(vioc->setup); if (!vioc->setup(bcontainer, errp)) { - goto enable_discards_exit; + goto fail; } - vfio_kvm_device_add_group(group); - vfio_address_space_insert(space, bcontainer); - group->container = container; - QLIST_INSERT_HEAD(&container->group_list, group, container_next); - - bcontainer->listener = vfio_memory_listener; - memory_listener_register(&bcontainer->listener, bcontainer->space->as); + if (!vfio_container_group_add(container, group, errp)) { + goto fail; + } + group_was_added = true; - if (bcontainer->error) { - error_propagate_prepend(errp, bcontainer->error, - "memory listener initialization failed: "); - goto listener_release_exit; + /* + * If CPR, register the listener later, after all state that may + * affect regions and mapping boundaries has been cpr load'ed. Later, + * the listener will invoke its callback on each flat section and call + * dma_map to supply the new vaddr, and the calls will match the mappings + * remembered by the kernel. + */ + if (!cpr_is_incoming()) { + if (!vfio_listener_register(bcontainer, errp)) { + goto fail; + } } bcontainer->initialized = true; return true; -listener_release_exit: - QLIST_REMOVE(group, container_next); - vfio_kvm_device_del_group(group); - memory_listener_unregister(&bcontainer->listener); - if (vioc->release) { - vioc->release(bcontainer); - } - -enable_discards_exit: - vfio_ram_block_discard_disable(container, false); - -unregister_container_exit: - vfio_cpr_unregister_container(bcontainer); - -free_container_exit: - object_unref(container); -close_fd_exit: - close(fd); +fail: + if (new_container) { + vfio_listener_unregister(bcontainer); + } -put_space_exit: - vfio_put_address_space(space); + if (group_was_added) { + vfio_container_group_del(container, group); + } + if (vioc && vioc->release) { + vioc->release(bcontainer); + } + if (new_container) { + vfio_legacy_cpr_unregister_container(container); + object_unref(container); + } + if (fd >= 0) { + close(fd); + } + vfio_address_space_put(space); return false; } -static void vfio_disconnect_container(VFIOGroup *group) +static void vfio_container_disconnect(VFIOGroup *group) { VFIOContainer *container = group->container; VFIOContainerBase *bcontainer = &container->bcontainer; @@ -686,6 +740,7 @@ static void vfio_disconnect_container(VFIOGroup *group) QLIST_REMOVE(group, container_next); group->container = NULL; + cpr_delete_fd("vfio_container_for_group", group->groupid); /* * Explicitly release the listener first before unset container, @@ -693,7 +748,7 @@ static void vfio_disconnect_container(VFIOGroup *group) * group. */ if (QLIST_EMPTY(&container->group_list)) { - memory_listener_unregister(&bcontainer->listener); + vfio_listener_unregister(bcontainer); if (vioc->release) { vioc->release(bcontainer); } @@ -707,16 +762,16 @@ static void vfio_disconnect_container(VFIOGroup *group) if (QLIST_EMPTY(&container->group_list)) { VFIOAddressSpace *space = bcontainer->space; - trace_vfio_disconnect_container(container->fd); - vfio_cpr_unregister_container(bcontainer); + trace_vfio_container_disconnect(container->fd); + vfio_legacy_cpr_unregister_container(container); close(container->fd); object_unref(container); - vfio_put_address_space(space); + vfio_address_space_put(space); } } -static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) +static VFIOGroup *vfio_group_get(int groupid, AddressSpace *as, Error **errp) { ERRP_GUARD(); VFIOGroup *group; @@ -739,7 +794,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) group = g_malloc0(sizeof(*group)); snprintf(path, sizeof(path), "/dev/vfio/%d", groupid); - group->fd = qemu_open(path, O_RDWR, errp); + group->fd = cpr_open_fd(path, O_RDWR, "vfio_group", groupid, errp); if (group->fd < 0) { goto free_group_exit; } @@ -760,7 +815,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) group->groupid = groupid; QLIST_INIT(&group->device_list); - if (!vfio_connect_container(group, as, errp)) { + if (!vfio_container_connect(group, as, errp)) { error_prepend(errp, "failed to setup container for group %d: ", groupid); goto close_fd_exit; @@ -771,6 +826,7 @@ static VFIOGroup *vfio_get_group(int groupid, AddressSpace *as, Error **errp) return group; close_fd_exit: + cpr_delete_fd("vfio_group", groupid); close(group->fd); free_group_exit: @@ -779,7 +835,7 @@ free_group_exit: return NULL; } -static void vfio_put_group(VFIOGroup *group) +static void vfio_group_put(VFIOGroup *group) { if (!group || !QLIST_EMPTY(&group->device_list)) { return; @@ -788,21 +844,22 @@ static void vfio_put_group(VFIOGroup *group) if (!group->ram_block_discard_allowed) { vfio_ram_block_discard_disable(group->container, false); } - vfio_kvm_device_del_group(group); - vfio_disconnect_container(group); + vfio_group_del_kvm_device(group); + vfio_container_disconnect(group); QLIST_REMOVE(group, next); - trace_vfio_put_group(group->fd); + trace_vfio_group_put(group->fd); + cpr_delete_fd("vfio_group", group->groupid); close(group->fd); g_free(group); } -static bool vfio_get_device(VFIOGroup *group, const char *name, +static bool vfio_device_get(VFIOGroup *group, const char *name, VFIODevice *vbasedev, Error **errp) { g_autofree struct vfio_device_info *info = NULL; int fd; - fd = ioctl(group->fd, VFIO_GROUP_GET_DEVICE_FD, name); + fd = vfio_cpr_group_get_device_fd(group->fd, name); if (fd < 0) { error_setg_errno(errp, errno, "error getting device from group %d", group->groupid); @@ -815,8 +872,7 @@ static bool vfio_get_device(VFIOGroup *group, const char *name, info = vfio_get_device_info(fd); if (!info) { error_setg_errno(errp, errno, "error getting device info"); - close(fd); - return false; + goto fail; } /* @@ -830,8 +886,7 @@ static bool vfio_get_device(VFIOGroup *group, const char *name, if (!QLIST_EMPTY(&group->device_list)) { error_setg(errp, "Inconsistent setting of support for discarding " "RAM (e.g., balloon) within group"); - close(fd); - return false; + goto fail; } if (!group->ram_block_discard_allowed) { @@ -840,33 +895,35 @@ static bool vfio_get_device(VFIOGroup *group, const char *name, } } + vfio_device_prepare(vbasedev, &group->container->bcontainer, info); + vbasedev->fd = fd; vbasedev->group = group; QLIST_INSERT_HEAD(&group->device_list, vbasedev, next); - vbasedev->num_irqs = info->num_irqs; - vbasedev->num_regions = info->num_regions; - vbasedev->flags = info->flags; - - trace_vfio_get_device(name, info->flags, info->num_regions, info->num_irqs); - - vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET); + trace_vfio_device_get(name, info->flags, info->num_regions, info->num_irqs); return true; + +fail: + close(fd); + cpr_delete_fd(name, 0); + return false; } -static void vfio_put_base_device(VFIODevice *vbasedev) +static void vfio_device_put(VFIODevice *vbasedev) { if (!vbasedev->group) { return; } QLIST_REMOVE(vbasedev, next); vbasedev->group = NULL; - trace_vfio_put_base_device(vbasedev->fd); + trace_vfio_device_put(vbasedev->fd); + cpr_delete_fd(vbasedev->name, 0); close(vbasedev->fd); } -static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp) +static int vfio_device_get_groupid(VFIODevice *vbasedev, Error **errp) { char *tmp, group_path[PATH_MAX]; g_autofree char *group_name = NULL; @@ -894,29 +951,24 @@ static int vfio_device_groupid(VFIODevice *vbasedev, Error **errp) } /* - * vfio_attach_device: attach a device to a security context + * vfio_device_attach: attach a device to a security context * @name and @vbasedev->name are likely to be different depending * on the type of the device, hence the need for passing @name */ static bool vfio_legacy_attach_device(const char *name, VFIODevice *vbasedev, AddressSpace *as, Error **errp) { - int groupid = vfio_device_groupid(vbasedev, errp); + int groupid = vfio_device_get_groupid(vbasedev, errp); VFIODevice *vbasedev_iter; VFIOGroup *group; - VFIOContainerBase *bcontainer; if (groupid < 0) { return false; } - trace_vfio_attach_device(vbasedev->name, groupid); + trace_vfio_device_attach(vbasedev->name, groupid); - if (!vfio_device_hiod_realize(vbasedev, errp)) { - return false; - } - - group = vfio_get_group(groupid, as, errp); + group = vfio_group_get(groupid, as, errp); if (!group) { return false; } @@ -924,33 +976,51 @@ static bool vfio_legacy_attach_device(const char *name, VFIODevice *vbasedev, QLIST_FOREACH(vbasedev_iter, &group->device_list, next) { if (strcmp(vbasedev_iter->name, vbasedev->name) == 0) { error_setg(errp, "device is already attached"); - vfio_put_group(group); - return false; + goto group_put_exit; } } - if (!vfio_get_device(group, name, vbasedev, errp)) { - vfio_put_group(group); - return false; + if (!vfio_device_get(group, name, vbasedev, errp)) { + goto group_put_exit; } - bcontainer = &group->container->bcontainer; - vbasedev->bcontainer = bcontainer; - QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next); - QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next); + if (!vfio_device_hiod_create_and_realize(vbasedev, + TYPE_HOST_IOMMU_DEVICE_LEGACY_VFIO, + errp)) { + goto device_put_exit; + } + + if (vbasedev->mdev) { + error_setg(&vbasedev->cpr.mdev_blocker, + "CPR does not support vfio mdev %s", vbasedev->name); + if (migrate_add_blocker_modes(&vbasedev->cpr.mdev_blocker, errp, + MIG_MODE_CPR_TRANSFER, -1) < 0) { + goto hiod_unref_exit; + } + } return true; + +hiod_unref_exit: + object_unref(vbasedev->hiod); +device_put_exit: + vfio_device_put(vbasedev); +group_put_exit: + vfio_group_put(group); + return false; } static void vfio_legacy_detach_device(VFIODevice *vbasedev) { VFIOGroup *group = vbasedev->group; - QLIST_REMOVE(vbasedev, global_next); - QLIST_REMOVE(vbasedev, container_next); - vbasedev->bcontainer = NULL; - trace_vfio_detach_device(vbasedev->name, group->groupid); - vfio_put_base_device(vbasedev); - vfio_put_group(group); + trace_vfio_device_detach(vbasedev->name, group->groupid); + + vfio_device_unprepare(vbasedev); + + migrate_del_blocker(&vbasedev->cpr.mdev_blocker); + object_unref(vbasedev->hiod); + vfio_device_put(vbasedev); + vfio_group_put(group); } static int vfio_legacy_pci_hot_reset(VFIODevice *vbasedev, bool single) @@ -1121,12 +1191,10 @@ out_single: return ret; } -static void vfio_iommu_legacy_class_init(ObjectClass *klass, void *data) +static void vfio_iommu_legacy_class_init(ObjectClass *klass, const void *data) { VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); - vioc->hiod_typename = TYPE_HOST_IOMMU_DEVICE_LEGACY_VFIO; - vioc->setup = vfio_legacy_setup; vioc->dma_map = vfio_legacy_dma_map; vioc->dma_unmap = vfio_legacy_dma_unmap; @@ -1185,7 +1253,7 @@ static void vfio_iommu_legacy_instance_init(Object *obj) QLIST_INIT(&container->group_list); } -static void hiod_legacy_vfio_class_init(ObjectClass *oc, void *data) +static void hiod_legacy_vfio_class_init(ObjectClass *oc, const void *data) { HostIOMMUDeviceClass *hioc = HOST_IOMMU_DEVICE_CLASS(oc); diff --git a/hw/vfio/cpr-legacy.c b/hw/vfio/cpr-legacy.c new file mode 100644 index 0000000..a84c324 --- /dev/null +++ b/hw/vfio/cpr-legacy.c @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2021-2025 Oracle and/or its affiliates. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include <sys/ioctl.h> +#include <linux/vfio.h> +#include "qemu/osdep.h" +#include "hw/vfio/vfio-container.h" +#include "hw/vfio/vfio-device.h" +#include "hw/vfio/vfio-listener.h" +#include "migration/blocker.h" +#include "migration/cpr.h" +#include "migration/migration.h" +#include "migration/vmstate.h" +#include "qapi/error.h" +#include "qemu/error-report.h" + +static bool vfio_dma_unmap_vaddr_all(VFIOContainer *container, Error **errp) +{ + struct vfio_iommu_type1_dma_unmap unmap = { + .argsz = sizeof(unmap), + .flags = VFIO_DMA_UNMAP_FLAG_VADDR | VFIO_DMA_UNMAP_FLAG_ALL, + .iova = 0, + .size = 0, + }; + if (ioctl(container->fd, VFIO_IOMMU_UNMAP_DMA, &unmap)) { + error_setg_errno(errp, errno, "vfio_dma_unmap_vaddr_all"); + return false; + } + container->cpr.vaddr_unmapped = true; + return true; +} + +/* + * Set the new @vaddr for any mappings registered during cpr load. + * The incoming state is cleared thereafter. + */ +static int vfio_legacy_cpr_dma_map(const VFIOContainerBase *bcontainer, + hwaddr iova, ram_addr_t size, void *vaddr, + bool readonly, MemoryRegion *mr) +{ + const VFIOContainer *container = container_of(bcontainer, VFIOContainer, + bcontainer); + struct vfio_iommu_type1_dma_map map = { + .argsz = sizeof(map), + .flags = VFIO_DMA_MAP_FLAG_VADDR, + .vaddr = (__u64)(uintptr_t)vaddr, + .iova = iova, + .size = size, + }; + + g_assert(cpr_is_incoming()); + + if (ioctl(container->fd, VFIO_IOMMU_MAP_DMA, &map)) { + return -errno; + } + + return 0; +} + +static void vfio_region_remap(MemoryListener *listener, + MemoryRegionSection *section) +{ + VFIOContainer *container = container_of(listener, VFIOContainer, + cpr.remap_listener); + vfio_container_region_add(&container->bcontainer, section, true); +} + +static bool vfio_cpr_supported(VFIOContainer *container, Error **errp) +{ + if (!ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UPDATE_VADDR)) { + error_setg(errp, "VFIO container does not support VFIO_UPDATE_VADDR"); + return false; + + } else if (!ioctl(container->fd, VFIO_CHECK_EXTENSION, VFIO_UNMAP_ALL)) { + error_setg(errp, "VFIO container does not support VFIO_UNMAP_ALL"); + return false; + + } else { + return true; + } +} + +static int vfio_container_pre_save(void *opaque) +{ + VFIOContainer *container = opaque; + Error *local_err = NULL; + + if (!vfio_dma_unmap_vaddr_all(container, &local_err)) { + error_report_err(local_err); + return -1; + } + return 0; +} + +static int vfio_container_post_load(void *opaque, int version_id) +{ + VFIOContainer *container = opaque; + VFIOContainerBase *bcontainer = &container->bcontainer; + VFIOGroup *group; + Error *local_err = NULL; + + if (!vfio_listener_register(bcontainer, &local_err)) { + error_report_err(local_err); + return -1; + } + + QLIST_FOREACH(group, &container->group_list, container_next) { + VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); + + /* Restore original dma_map function */ + vioc->dma_map = container->cpr.saved_dma_map; + } + return 0; +} + +static const VMStateDescription vfio_container_vmstate = { + .name = "vfio-container", + .version_id = 0, + .minimum_version_id = 0, + .priority = MIG_PRI_LOW, /* Must happen after devices and groups */ + .pre_save = vfio_container_pre_save, + .post_load = vfio_container_post_load, + .needed = cpr_incoming_needed, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + } +}; + +static int vfio_cpr_fail_notifier(NotifierWithReturn *notifier, + MigrationEvent *e, Error **errp) +{ + VFIOContainer *container = + container_of(notifier, VFIOContainer, cpr.transfer_notifier); + VFIOContainerBase *bcontainer = &container->bcontainer; + + if (e->type != MIG_EVENT_PRECOPY_FAILED) { + return 0; + } + + if (container->cpr.vaddr_unmapped) { + /* + * Force a call to vfio_region_remap for each mapped section by + * temporarily registering a listener, and temporarily diverting + * dma_map to vfio_legacy_cpr_dma_map. The latter restores vaddr. + */ + + VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); + vioc->dma_map = vfio_legacy_cpr_dma_map; + + container->cpr.remap_listener = (MemoryListener) { + .name = "vfio cpr recover", + .region_add = vfio_region_remap + }; + memory_listener_register(&container->cpr.remap_listener, + bcontainer->space->as); + memory_listener_unregister(&container->cpr.remap_listener); + container->cpr.vaddr_unmapped = false; + vioc->dma_map = container->cpr.saved_dma_map; + } + return 0; +} + +bool vfio_legacy_cpr_register_container(VFIOContainer *container, Error **errp) +{ + VFIOContainerBase *bcontainer = &container->bcontainer; + Error **cpr_blocker = &container->cpr.blocker; + + migration_add_notifier_mode(&bcontainer->cpr_reboot_notifier, + vfio_cpr_reboot_notifier, + MIG_MODE_CPR_REBOOT); + + if (!vfio_cpr_supported(container, cpr_blocker)) { + return migrate_add_blocker_modes(cpr_blocker, errp, + MIG_MODE_CPR_TRANSFER, -1) == 0; + } + + vmstate_register(NULL, -1, &vfio_container_vmstate, container); + + /* During incoming CPR, divert calls to dma_map. */ + if (cpr_is_incoming()) { + VFIOIOMMUClass *vioc = VFIO_IOMMU_GET_CLASS(bcontainer); + container->cpr.saved_dma_map = vioc->dma_map; + vioc->dma_map = vfio_legacy_cpr_dma_map; + } + + migration_add_notifier_mode(&container->cpr.transfer_notifier, + vfio_cpr_fail_notifier, + MIG_MODE_CPR_TRANSFER); + return true; +} + +void vfio_legacy_cpr_unregister_container(VFIOContainer *container) +{ + VFIOContainerBase *bcontainer = &container->bcontainer; + + migration_remove_notifier(&bcontainer->cpr_reboot_notifier); + migrate_del_blocker(&container->cpr.blocker); + vmstate_unregister(NULL, &vfio_container_vmstate, container); + migration_remove_notifier(&container->cpr.transfer_notifier); +} + +/* + * In old QEMU, VFIO_DMA_UNMAP_FLAG_VADDR may fail on some mapping after + * succeeding for others, so the latter have lost their vaddr. Call this + * to restore vaddr for a section with a giommu. + * + * The giommu already exists. Find it and replay it, which calls + * vfio_legacy_cpr_dma_map further down the stack. + */ +void vfio_cpr_giommu_remap(VFIOContainerBase *bcontainer, + MemoryRegionSection *section) +{ + VFIOGuestIOMMU *giommu = NULL; + hwaddr as_offset = section->offset_within_address_space; + hwaddr iommu_offset = as_offset - section->offset_within_region; + + QLIST_FOREACH(giommu, &bcontainer->giommu_list, giommu_next) { + if (giommu->iommu_mr == IOMMU_MEMORY_REGION(section->mr) && + giommu->iommu_offset == iommu_offset) { + break; + } + } + g_assert(giommu); + memory_region_iommu_replay(giommu->iommu_mr, &giommu->n); +} + +/* + * In old QEMU, VFIO_DMA_UNMAP_FLAG_VADDR may fail on some mapping after + * succeeding for others, so the latter have lost their vaddr. Call this + * to restore vaddr for a section with a RamDiscardManager. + * + * The ram discard listener already exists. Call its populate function + * directly, which calls vfio_legacy_cpr_dma_map. + */ +bool vfio_cpr_ram_discard_register_listener(VFIOContainerBase *bcontainer, + MemoryRegionSection *section) +{ + VFIORamDiscardListener *vrdl = + vfio_find_ram_discard_listener(bcontainer, section); + + g_assert(vrdl); + return vrdl->listener.notify_populate(&vrdl->listener, section) == 0; +} + +int vfio_cpr_group_get_device_fd(int d, const char *name) +{ + const int id = 0; + int fd = cpr_find_fd(name, id); + + if (fd < 0) { + fd = ioctl(d, VFIO_GROUP_GET_DEVICE_FD, name); + if (fd >= 0) { + cpr_save_fd(name, id, fd); + } + } + return fd; +} + +static bool same_device(int fd1, int fd2) +{ + struct stat st1, st2; + + return !fstat(fd1, &st1) && !fstat(fd2, &st2) && st1.st_dev == st2.st_dev; +} + +bool vfio_cpr_container_match(VFIOContainer *container, VFIOGroup *group, + int fd) +{ + if (container->fd == fd) { + return true; + } + if (!same_device(container->fd, fd)) { + return false; + } + /* + * Same device, different fd. This occurs when the container fd is + * cpr_save'd multiple times, once for each groupid, so SCM_RIGHTS + * produces duplicates. De-dup it. + */ + cpr_delete_fd("vfio_container_for_group", group->groupid); + close(fd); + cpr_save_fd("vfio_container_for_group", group->groupid, container->fd); + return true; +} diff --git a/hw/vfio/cpr.c b/hw/vfio/cpr.c index 3d1c8d2..fdbb58e 100644 --- a/hw/vfio/cpr.c +++ b/hw/vfio/cpr.c @@ -6,13 +6,15 @@ */ #include "qemu/osdep.h" -#include "hw/vfio/vfio-common.h" -#include "migration/misc.h" +#include "hw/vfio/vfio-device.h" +#include "hw/vfio/vfio-cpr.h" +#include "hw/vfio/pci.h" +#include "migration/cpr.h" #include "qapi/error.h" #include "system/runstate.h" -static int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier, - MigrationEvent *e, Error **errp) +int vfio_cpr_reboot_notifier(NotifierWithReturn *notifier, + MigrationEvent *e, Error **errp) { if (e->type == MIG_EVENT_PRECOPY_SETUP && !runstate_check(RUN_STATE_SUSPENDED) && !vm_get_suspended()) { @@ -37,3 +39,32 @@ void vfio_cpr_unregister_container(VFIOContainerBase *bcontainer) { migration_remove_notifier(&bcontainer->cpr_reboot_notifier); } + +/* + * The kernel may change non-emulated config bits. Exclude them from the + * changed-bits check in get_pci_config_device. + */ +static int vfio_cpr_pci_pre_load(void *opaque) +{ + VFIOPCIDevice *vdev = opaque; + PCIDevice *pdev = &vdev->pdev; + int size = MIN(pci_config_size(pdev), vdev->config_size); + int i; + + for (i = 0; i < size; i++) { + pdev->cmask[i] &= vdev->emulated_config_bits[i]; + } + + return 0; +} + +const VMStateDescription vfio_cpr_pci_vmstate = { + .name = "vfio-cpr-pci", + .version_id = 0, + .minimum_version_id = 0, + .pre_load = vfio_cpr_pci_pre_load, + .needed = cpr_incoming_needed, + .fields = (VMStateField[]) { + VMSTATE_END_OF_LIST() + } +}; diff --git a/hw/vfio/device.c b/hw/vfio/device.c new file mode 100644 index 0000000..d91c695 --- /dev/null +++ b/hw/vfio/device.c @@ -0,0 +1,576 @@ +/* + * VFIO device + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Alex Williamson <alex.williamson@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Based on qemu-kvm device-assignment: + * Adapted for KVM by Qumranet. + * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) + * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) + * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) + * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) + * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) + */ + +#include "qemu/osdep.h" +#include <sys/ioctl.h> + +#include "hw/vfio/vfio-device.h" +#include "hw/vfio/pci.h" +#include "hw/hw.h" +#include "trace.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/units.h" +#include "monitor/monitor.h" +#include "vfio-helpers.h" + +VFIODeviceList vfio_device_list = + QLIST_HEAD_INITIALIZER(vfio_device_list); + +/* + * We want to differentiate hot reset of multiple in-use devices vs + * hot reset of a single in-use device. VFIO_DEVICE_RESET will already + * handle the case of doing hot resets when there is only a single + * device per bus. The in-use here refers to how many VFIODevices are + * affected. A hot reset that affects multiple devices, but only a + * single in-use device, means that we can call it from our bus + * ->reset() callback since the extent is effectively a single + * device. This allows us to make use of it in the hotplug path. When + * there are multiple in-use devices, we can only trigger the hot + * reset during a system reset and thus from our reset handler. We + * separate _one vs _multi here so that we don't overlap and do a + * double reset on the system reset path where both our reset handler + * and ->reset() callback are used. Calling _one() will only do a hot + * reset for the one in-use devices case, calling _multi() will do + * nothing if a _one() would have been sufficient. + */ +void vfio_device_reset_handler(void *opaque) +{ + VFIODevice *vbasedev; + + trace_vfio_device_reset_handler(); + QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { + if (vbasedev->dev->realized) { + vbasedev->ops->vfio_compute_needs_reset(vbasedev); + } + } + + QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { + if (vbasedev->dev->realized && vbasedev->needs_reset) { + vbasedev->ops->vfio_hot_reset_multi(vbasedev); + } + } +} + +/* + * Common VFIO interrupt disable + */ +void vfio_device_irq_disable(VFIODevice *vbasedev, int index) +{ + struct vfio_irq_set irq_set = { + .argsz = sizeof(irq_set), + .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER, + .index = index, + .start = 0, + .count = 0, + }; + + vbasedev->io_ops->set_irqs(vbasedev, &irq_set); +} + +void vfio_device_irq_unmask(VFIODevice *vbasedev, int index) +{ + struct vfio_irq_set irq_set = { + .argsz = sizeof(irq_set), + .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK, + .index = index, + .start = 0, + .count = 1, + }; + + vbasedev->io_ops->set_irqs(vbasedev, &irq_set); +} + +void vfio_device_irq_mask(VFIODevice *vbasedev, int index) +{ + struct vfio_irq_set irq_set = { + .argsz = sizeof(irq_set), + .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK, + .index = index, + .start = 0, + .count = 1, + }; + + vbasedev->io_ops->set_irqs(vbasedev, &irq_set); +} + +static inline const char *action_to_str(int action) +{ + switch (action) { + case VFIO_IRQ_SET_ACTION_MASK: + return "MASK"; + case VFIO_IRQ_SET_ACTION_UNMASK: + return "UNMASK"; + case VFIO_IRQ_SET_ACTION_TRIGGER: + return "TRIGGER"; + default: + return "UNKNOWN ACTION"; + } +} + +static const char *index_to_str(VFIODevice *vbasedev, int index) +{ + if (vbasedev->type != VFIO_DEVICE_TYPE_PCI) { + return NULL; + } + + switch (index) { + case VFIO_PCI_INTX_IRQ_INDEX: + return "INTX"; + case VFIO_PCI_MSI_IRQ_INDEX: + return "MSI"; + case VFIO_PCI_MSIX_IRQ_INDEX: + return "MSIX"; + case VFIO_PCI_ERR_IRQ_INDEX: + return "ERR"; + case VFIO_PCI_REQ_IRQ_INDEX: + return "REQ"; + default: + return NULL; + } +} + +bool vfio_device_irq_set_signaling(VFIODevice *vbasedev, int index, int subindex, + int action, int fd, Error **errp) +{ + ERRP_GUARD(); + g_autofree struct vfio_irq_set *irq_set = NULL; + int argsz; + const char *name; + int32_t *pfd; + + argsz = sizeof(*irq_set) + sizeof(*pfd); + + irq_set = g_malloc0(argsz); + irq_set->argsz = argsz; + irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | action; + irq_set->index = index; + irq_set->start = subindex; + irq_set->count = 1; + pfd = (int32_t *)&irq_set->data; + *pfd = fd; + + if (!vbasedev->io_ops->set_irqs(vbasedev, irq_set)) { + return true; + } + + error_setg_errno(errp, errno, "VFIO_DEVICE_SET_IRQS failure"); + + name = index_to_str(vbasedev, index); + if (name) { + error_prepend(errp, "%s-%d: ", name, subindex); + } else { + error_prepend(errp, "index %d-%d: ", index, subindex); + } + error_prepend(errp, + "Failed to %s %s eventfd signaling for interrupt ", + fd < 0 ? "tear down" : "set up", action_to_str(action)); + return false; +} + +int vfio_device_get_irq_info(VFIODevice *vbasedev, int index, + struct vfio_irq_info *info) +{ + memset(info, 0, sizeof(*info)); + + info->argsz = sizeof(*info); + info->index = index; + + return vbasedev->io_ops->get_irq_info(vbasedev, info); +} + +int vfio_device_get_region_info(VFIODevice *vbasedev, int index, + struct vfio_region_info **info) +{ + size_t argsz = sizeof(struct vfio_region_info); + int fd = -1; + int ret; + + /* check cache */ + if (vbasedev->reginfo[index] != NULL) { + *info = vbasedev->reginfo[index]; + return 0; + } + + *info = g_malloc0(argsz); + + (*info)->index = index; +retry: + (*info)->argsz = argsz; + + ret = vbasedev->io_ops->get_region_info(vbasedev, *info, &fd); + if (ret != 0) { + g_free(*info); + *info = NULL; + return ret; + } + + if ((*info)->argsz > argsz) { + argsz = (*info)->argsz; + *info = g_realloc(*info, argsz); + + if (fd != -1) { + close(fd); + fd = -1; + } + + goto retry; + } + + /* fill cache */ + vbasedev->reginfo[index] = *info; + if (vbasedev->region_fds != NULL) { + vbasedev->region_fds[index] = fd; + } + + return 0; +} + +int vfio_device_get_region_fd(VFIODevice *vbasedev, int index) +{ + return vbasedev->region_fds ? + vbasedev->region_fds[index] : + vbasedev->fd; +} + +int vfio_device_get_region_info_type(VFIODevice *vbasedev, uint32_t type, + uint32_t subtype, struct vfio_region_info **info) +{ + int i; + + for (i = 0; i < vbasedev->num_regions; i++) { + struct vfio_info_cap_header *hdr; + struct vfio_region_info_cap_type *cap_type; + + if (vfio_device_get_region_info(vbasedev, i, info)) { + continue; + } + + hdr = vfio_get_region_info_cap(*info, VFIO_REGION_INFO_CAP_TYPE); + if (!hdr) { + continue; + } + + cap_type = container_of(hdr, struct vfio_region_info_cap_type, header); + + trace_vfio_device_get_region_info_type(vbasedev->name, i, + cap_type->type, cap_type->subtype); + + if (cap_type->type == type && cap_type->subtype == subtype) { + return 0; + } + } + + *info = NULL; + return -ENODEV; +} + +bool vfio_device_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) +{ + struct vfio_region_info *info = NULL; + bool ret = false; + + if (!vfio_device_get_region_info(vbasedev, region, &info)) { + if (vfio_get_region_info_cap(info, cap_type)) { + ret = true; + } + } + + return ret; +} + +bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp) +{ + ERRP_GUARD(); + struct stat st; + + if (vbasedev->fd < 0) { + if (stat(vbasedev->sysfsdev, &st) < 0) { + error_setg_errno(errp, errno, "no such host device"); + error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev); + return false; + } + /* User may specify a name, e.g: VFIO platform device */ + if (!vbasedev->name) { + vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); + } + } else { + if (!vbasedev->iommufd) { + error_setg(errp, "Use FD passing only with iommufd backend"); + return false; + } + /* + * Give a name with fd so any function printing out vbasedev->name + * will not break. + */ + if (!vbasedev->name) { + vbasedev->name = g_strdup_printf("VFIO_FD%d", vbasedev->fd); + } + } + + return true; +} + +void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp) +{ + ERRP_GUARD(); + int fd = monitor_fd_param(monitor_cur(), str, errp); + + if (fd < 0) { + error_prepend(errp, "Could not parse remote object fd %s:", str); + return; + } + vbasedev->fd = fd; +} + +static VFIODeviceIOOps vfio_device_io_ops_ioctl; + +void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, + DeviceState *dev, bool ram_discard) +{ + vbasedev->type = type; + vbasedev->ops = ops; + vbasedev->io_ops = &vfio_device_io_ops_ioctl; + vbasedev->dev = dev; + vbasedev->fd = -1; + vbasedev->use_region_fds = false; + + vbasedev->ram_block_discard_allowed = ram_discard; +} + +int vfio_device_get_aw_bits(VFIODevice *vdev) +{ + /* + * iova_ranges is a sorted list. For old kernels that support + * VFIO but not support query of iova ranges, iova_ranges is NULL, + * in this case HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX(64) is returned. + */ + GList *l = g_list_last(vdev->bcontainer->iova_ranges); + + if (l) { + Range *range = l->data; + return range_get_last_bit(range) + 1; + } + + return HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX; +} + +bool vfio_device_is_mdev(VFIODevice *vbasedev) +{ + g_autofree char *subsys = NULL; + g_autofree char *tmp = NULL; + + if (!vbasedev->sysfsdev) { + return false; + } + + tmp = g_strdup_printf("%s/subsystem", vbasedev->sysfsdev); + subsys = realpath(tmp, NULL); + return subsys && (strcmp(subsys, "/sys/bus/mdev") == 0); +} + +bool vfio_device_hiod_create_and_realize(VFIODevice *vbasedev, + const char *typename, Error **errp) +{ + HostIOMMUDevice *hiod; + + if (vbasedev->mdev) { + return true; + } + + hiod = HOST_IOMMU_DEVICE(object_new(typename)); + + if (!HOST_IOMMU_DEVICE_GET_CLASS(hiod)->realize(hiod, vbasedev, errp)) { + object_unref(hiod); + return false; + } + + vbasedev->hiod = hiod; + return true; +} + +VFIODevice *vfio_get_vfio_device(Object *obj) +{ + if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) { + return &VFIO_PCI_BASE(obj)->vbasedev; + } else { + return NULL; + } +} + +bool vfio_device_attach_by_iommu_type(const char *iommu_type, char *name, + VFIODevice *vbasedev, AddressSpace *as, + Error **errp) +{ + const VFIOIOMMUClass *ops = + VFIO_IOMMU_CLASS(object_class_by_name(iommu_type)); + + assert(ops); + + return ops->attach_device(name, vbasedev, as, errp); +} + +bool vfio_device_attach(char *name, VFIODevice *vbasedev, + AddressSpace *as, Error **errp) +{ + const char *iommu_type = vbasedev->iommufd ? + TYPE_VFIO_IOMMU_IOMMUFD : + TYPE_VFIO_IOMMU_LEGACY; + + return vfio_device_attach_by_iommu_type(iommu_type, name, vbasedev, + as, errp); +} + +void vfio_device_detach(VFIODevice *vbasedev) +{ + if (!vbasedev->bcontainer) { + return; + } + VFIO_IOMMU_GET_CLASS(vbasedev->bcontainer)->detach_device(vbasedev); +} + +void vfio_device_prepare(VFIODevice *vbasedev, VFIOContainerBase *bcontainer, + struct vfio_device_info *info) +{ + vbasedev->num_irqs = info->num_irqs; + vbasedev->num_regions = info->num_regions; + vbasedev->flags = info->flags; + vbasedev->reset_works = !!(info->flags & VFIO_DEVICE_FLAGS_RESET); + + vbasedev->bcontainer = bcontainer; + QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next); + + QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next); + + vbasedev->reginfo = g_new0(struct vfio_region_info *, + vbasedev->num_regions); + if (vbasedev->use_region_fds) { + vbasedev->region_fds = g_new0(int, vbasedev->num_regions); + } +} + +void vfio_device_unprepare(VFIODevice *vbasedev) +{ + int i; + + for (i = 0; i < vbasedev->num_regions; i++) { + g_free(vbasedev->reginfo[i]); + if (vbasedev->region_fds != NULL && vbasedev->region_fds[i] != -1) { + close(vbasedev->region_fds[i]); + } + + } + + g_clear_pointer(&vbasedev->reginfo, g_free); + g_clear_pointer(&vbasedev->region_fds, g_free); + + QLIST_REMOVE(vbasedev, container_next); + QLIST_REMOVE(vbasedev, global_next); + vbasedev->bcontainer = NULL; +} + +/* + * Traditional ioctl() based io + */ + +static int vfio_device_io_device_feature(VFIODevice *vbasedev, + struct vfio_device_feature *feature) +{ + int ret; + + ret = ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature); + + return ret < 0 ? -errno : ret; +} + +static int vfio_device_io_get_region_info(VFIODevice *vbasedev, + struct vfio_region_info *info, + int *fd) +{ + int ret; + + *fd = -1; + + ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, info); + + return ret < 0 ? -errno : ret; +} + +static int vfio_device_io_get_irq_info(VFIODevice *vbasedev, + struct vfio_irq_info *info) +{ + int ret; + + ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, info); + + return ret < 0 ? -errno : ret; +} + +static int vfio_device_io_set_irqs(VFIODevice *vbasedev, + struct vfio_irq_set *irqs) +{ + int ret; + + ret = ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irqs); + + return ret < 0 ? -errno : ret; +} + +static int vfio_device_io_region_read(VFIODevice *vbasedev, uint8_t index, + off_t off, uint32_t size, void *data) +{ + struct vfio_region_info *info; + int ret; + + ret = vfio_device_get_region_info(vbasedev, index, &info); + if (ret != 0) { + return ret; + } + + ret = pread(vbasedev->fd, data, size, info->offset + off); + + return ret < 0 ? -errno : ret; +} + +static int vfio_device_io_region_write(VFIODevice *vbasedev, uint8_t index, + off_t off, uint32_t size, void *data, + bool post) +{ + struct vfio_region_info *info; + int ret; + + ret = vfio_device_get_region_info(vbasedev, index, &info); + if (ret != 0) { + return ret; + } + + ret = pwrite(vbasedev->fd, data, size, info->offset + off); + + return ret < 0 ? -errno : ret; +} + +static VFIODeviceIOOps vfio_device_io_ops_ioctl = { + .device_feature = vfio_device_io_device_feature, + .get_region_info = vfio_device_io_get_region_info, + .get_irq_info = vfio_device_io_get_irq_info, + .set_irqs = vfio_device_io_set_irqs, + .region_read = vfio_device_io_region_read, + .region_write = vfio_device_io_region_write, +}; diff --git a/hw/vfio/display.c b/hw/vfio/display.c index 4fdcef5..9c6f5aa 100644 --- a/hw/vfio/display.c +++ b/hw/vfio/display.c @@ -16,9 +16,9 @@ #include "qemu/error-report.h" #include "hw/display/edid.h" -#include "ui/console.h" #include "qapi/error.h" #include "pci.h" +#include "vfio-display.h" #include "trace.h" #ifndef DRM_PLANE_TYPE_PRIMARY @@ -129,10 +129,10 @@ static bool vfio_display_edid_init(VFIOPCIDevice *vdev, Error **errp) int fd = vdev->vbasedev.fd; int ret; - ret = vfio_get_dev_region_info(&vdev->vbasedev, - VFIO_REGION_TYPE_GFX, - VFIO_REGION_SUBTYPE_GFX_EDID, - &dpy->edid_info); + ret = vfio_device_get_region_info_type(&vdev->vbasedev, + VFIO_REGION_TYPE_GFX, + VFIO_REGION_SUBTYPE_GFX_EDID, + &dpy->edid_info); if (ret) { /* Failed to get GFX edid info, allow to go through without edid. */ return true; @@ -213,6 +213,7 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, struct vfio_device_gfx_plane_info plane; VFIODMABuf *dmabuf; int fd, ret; + uint32_t offset = 0; memset(&plane, 0, sizeof(plane)); plane.argsz = sizeof(plane); @@ -245,10 +246,10 @@ static VFIODMABuf *vfio_display_get_dmabuf(VFIOPCIDevice *vdev, dmabuf = g_new0(VFIODMABuf, 1); dmabuf->dmabuf_id = plane.dmabuf_id; - dmabuf->buf = qemu_dmabuf_new(plane.width, plane.height, - plane.stride, 0, 0, plane.width, + dmabuf->buf = qemu_dmabuf_new(plane.width, plane.height, &offset, + &plane.stride, 0, 0, plane.width, plane.height, plane.drm_format, - plane.drm_format_mod, fd, false, false); + plane.drm_format_mod, &fd, 1, false, false); if (plane_type == DRM_PLANE_TYPE_CURSOR) { vfio_display_update_cursor(dmabuf, &plane); diff --git a/hw/vfio/helpers.c b/hw/vfio/helpers.c index 4b255d4..d0dbab1 100644 --- a/hw/vfio/helpers.c +++ b/hw/vfio/helpers.c @@ -22,242 +22,11 @@ #include "qemu/osdep.h" #include <sys/ioctl.h> -#include "hw/vfio/vfio-common.h" -#include "hw/vfio/pci.h" +#include "system/kvm.h" +#include "hw/vfio/vfio-device.h" #include "hw/hw.h" -#include "trace.h" #include "qapi/error.h" -#include "qemu/error-report.h" -#include "qemu/units.h" -#include "monitor/monitor.h" - -/* - * Common VFIO interrupt disable - */ -void vfio_disable_irqindex(VFIODevice *vbasedev, int index) -{ - struct vfio_irq_set irq_set = { - .argsz = sizeof(irq_set), - .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_TRIGGER, - .index = index, - .start = 0, - .count = 0, - }; - - ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set); -} - -void vfio_unmask_single_irqindex(VFIODevice *vbasedev, int index) -{ - struct vfio_irq_set irq_set = { - .argsz = sizeof(irq_set), - .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_UNMASK, - .index = index, - .start = 0, - .count = 1, - }; - - ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set); -} - -void vfio_mask_single_irqindex(VFIODevice *vbasedev, int index) -{ - struct vfio_irq_set irq_set = { - .argsz = sizeof(irq_set), - .flags = VFIO_IRQ_SET_DATA_NONE | VFIO_IRQ_SET_ACTION_MASK, - .index = index, - .start = 0, - .count = 1, - }; - - ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, &irq_set); -} - -static inline const char *action_to_str(int action) -{ - switch (action) { - case VFIO_IRQ_SET_ACTION_MASK: - return "MASK"; - case VFIO_IRQ_SET_ACTION_UNMASK: - return "UNMASK"; - case VFIO_IRQ_SET_ACTION_TRIGGER: - return "TRIGGER"; - default: - return "UNKNOWN ACTION"; - } -} - -static const char *index_to_str(VFIODevice *vbasedev, int index) -{ - if (vbasedev->type != VFIO_DEVICE_TYPE_PCI) { - return NULL; - } - - switch (index) { - case VFIO_PCI_INTX_IRQ_INDEX: - return "INTX"; - case VFIO_PCI_MSI_IRQ_INDEX: - return "MSI"; - case VFIO_PCI_MSIX_IRQ_INDEX: - return "MSIX"; - case VFIO_PCI_ERR_IRQ_INDEX: - return "ERR"; - case VFIO_PCI_REQ_IRQ_INDEX: - return "REQ"; - default: - return NULL; - } -} - -bool vfio_set_irq_signaling(VFIODevice *vbasedev, int index, int subindex, - int action, int fd, Error **errp) -{ - ERRP_GUARD(); - g_autofree struct vfio_irq_set *irq_set = NULL; - int argsz; - const char *name; - int32_t *pfd; - - argsz = sizeof(*irq_set) + sizeof(*pfd); - - irq_set = g_malloc0(argsz); - irq_set->argsz = argsz; - irq_set->flags = VFIO_IRQ_SET_DATA_EVENTFD | action; - irq_set->index = index; - irq_set->start = subindex; - irq_set->count = 1; - pfd = (int32_t *)&irq_set->data; - *pfd = fd; - - if (!ioctl(vbasedev->fd, VFIO_DEVICE_SET_IRQS, irq_set)) { - return true; - } - - error_setg_errno(errp, errno, "VFIO_DEVICE_SET_IRQS failure"); - - name = index_to_str(vbasedev, index); - if (name) { - error_prepend(errp, "%s-%d: ", name, subindex); - } else { - error_prepend(errp, "index %d-%d: ", index, subindex); - } - error_prepend(errp, - "Failed to %s %s eventfd signaling for interrupt ", - fd < 0 ? "tear down" : "set up", action_to_str(action)); - return false; -} - -/* - * IO Port/MMIO - Beware of the endians, VFIO is always little endian - */ -void vfio_region_write(void *opaque, hwaddr addr, - uint64_t data, unsigned size) -{ - VFIORegion *region = opaque; - VFIODevice *vbasedev = region->vbasedev; - union { - uint8_t byte; - uint16_t word; - uint32_t dword; - uint64_t qword; - } buf; - - switch (size) { - case 1: - buf.byte = data; - break; - case 2: - buf.word = cpu_to_le16(data); - break; - case 4: - buf.dword = cpu_to_le32(data); - break; - case 8: - buf.qword = cpu_to_le64(data); - break; - default: - hw_error("vfio: unsupported write size, %u bytes", size); - break; - } - - if (pwrite(vbasedev->fd, &buf, size, region->fd_offset + addr) != size) { - error_report("%s(%s:region%d+0x%"HWADDR_PRIx", 0x%"PRIx64 - ",%d) failed: %m", - __func__, vbasedev->name, region->nr, - addr, data, size); - } - - trace_vfio_region_write(vbasedev->name, region->nr, addr, data, size); - - /* - * A read or write to a BAR always signals an INTx EOI. This will - * do nothing if not pending (including not in INTx mode). We assume - * that a BAR access is in response to an interrupt and that BAR - * accesses will service the interrupt. Unfortunately, we don't know - * which access will service the interrupt, so we're potentially - * getting quite a few host interrupts per guest interrupt. - */ - vbasedev->ops->vfio_eoi(vbasedev); -} - -uint64_t vfio_region_read(void *opaque, - hwaddr addr, unsigned size) -{ - VFIORegion *region = opaque; - VFIODevice *vbasedev = region->vbasedev; - union { - uint8_t byte; - uint16_t word; - uint32_t dword; - uint64_t qword; - } buf; - uint64_t data = 0; - - if (pread(vbasedev->fd, &buf, size, region->fd_offset + addr) != size) { - error_report("%s(%s:region%d+0x%"HWADDR_PRIx", %d) failed: %m", - __func__, vbasedev->name, region->nr, - addr, size); - return (uint64_t)-1; - } - switch (size) { - case 1: - data = buf.byte; - break; - case 2: - data = le16_to_cpu(buf.word); - break; - case 4: - data = le32_to_cpu(buf.dword); - break; - case 8: - data = le64_to_cpu(buf.qword); - break; - default: - hw_error("vfio: unsupported read size, %u bytes", size); - break; - } - - trace_vfio_region_read(vbasedev->name, region->nr, addr, size, data); - - /* Same as write above */ - vbasedev->ops->vfio_eoi(vbasedev); - - return data; -} - -const MemoryRegionOps vfio_region_ops = { - .read = vfio_region_read, - .write = vfio_region_write, - .endianness = DEVICE_LITTLE_ENDIAN, - .valid = { - .min_access_size = 1, - .max_access_size = 8, - }, - .impl = { - .min_access_size = 1, - .max_access_size = 8, - }, -}; +#include "vfio-helpers.h" int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size) { @@ -306,435 +75,126 @@ vfio_get_device_info_cap(struct vfio_device_info *info, uint16_t id) return vfio_get_cap((void *)info, info->cap_offset, id); } -static int vfio_setup_region_sparse_mmaps(VFIORegion *region, - struct vfio_region_info *info) +struct vfio_info_cap_header * +vfio_get_iommu_type1_info_cap(struct vfio_iommu_type1_info *info, uint16_t id) { - struct vfio_info_cap_header *hdr; - struct vfio_region_info_cap_sparse_mmap *sparse; - int i, j; - - hdr = vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMAP); - if (!hdr) { - return -ENODEV; - } - - sparse = container_of(hdr, struct vfio_region_info_cap_sparse_mmap, header); - - trace_vfio_region_sparse_mmap_header(region->vbasedev->name, - region->nr, sparse->nr_areas); - - region->mmaps = g_new0(VFIOMmap, sparse->nr_areas); - - for (i = 0, j = 0; i < sparse->nr_areas; i++) { - if (sparse->areas[i].size) { - trace_vfio_region_sparse_mmap_entry(i, sparse->areas[i].offset, - sparse->areas[i].offset + - sparse->areas[i].size - 1); - region->mmaps[j].offset = sparse->areas[i].offset; - region->mmaps[j].size = sparse->areas[i].size; - j++; - } + if (!(info->flags & VFIO_IOMMU_INFO_CAPS)) { + return NULL; } - region->nr_mmaps = j; - region->mmaps = g_realloc(region->mmaps, j * sizeof(VFIOMmap)); - - return 0; + return vfio_get_cap((void *)info, info->cap_offset, id); } -int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, - int index, const char *name) +bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, + unsigned int *avail) { - g_autofree struct vfio_region_info *info = NULL; - int ret; + struct vfio_info_cap_header *hdr; + struct vfio_iommu_type1_info_dma_avail *cap; - ret = vfio_get_region_info(vbasedev, index, &info); - if (ret) { - return ret; + /* If the capability cannot be found, assume no DMA limiting */ + hdr = vfio_get_iommu_type1_info_cap(info, + VFIO_IOMMU_TYPE1_INFO_DMA_AVAIL); + if (!hdr) { + return false; } - region->vbasedev = vbasedev; - region->flags = info->flags; - region->size = info->size; - region->fd_offset = info->offset; - region->nr = index; - - if (region->size) { - region->mem = g_new0(MemoryRegion, 1); - memory_region_init_io(region->mem, obj, &vfio_region_ops, - region, name, region->size); - - if (!vbasedev->no_mmap && - region->flags & VFIO_REGION_INFO_FLAG_MMAP) { - - ret = vfio_setup_region_sparse_mmaps(region, info); - - if (ret) { - region->nr_mmaps = 1; - region->mmaps = g_new0(VFIOMmap, region->nr_mmaps); - region->mmaps[0].offset = 0; - region->mmaps[0].size = region->size; - } - } + if (avail != NULL) { + cap = (void *) hdr; + *avail = cap->avail; } - trace_vfio_region_setup(vbasedev->name, index, name, - region->flags, region->fd_offset, region->size); - return 0; + return true; } -static void vfio_subregion_unmap(VFIORegion *region, int index) -{ - trace_vfio_region_unmap(memory_region_name(®ion->mmaps[index].mem), - region->mmaps[index].offset, - region->mmaps[index].offset + - region->mmaps[index].size - 1); - memory_region_del_subregion(region->mem, ®ion->mmaps[index].mem); - munmap(region->mmaps[index].mmap, region->mmaps[index].size); - object_unparent(OBJECT(®ion->mmaps[index].mem)); - region->mmaps[index].mmap = NULL; -} +#ifdef CONFIG_KVM +/* + * We have a single VFIO pseudo device per KVM VM. Once created it lives + * for the life of the VM. Closing the file descriptor only drops our + * reference to it and the device's reference to kvm. Therefore once + * initialized, this file descriptor is only released on QEMU exit and + * we'll re-use it should another vfio device be attached before then. + */ +int vfio_kvm_device_fd = -1; +#endif -int vfio_region_mmap(VFIORegion *region) +int vfio_kvm_device_add_fd(int fd, Error **errp) { - int i, ret, prot = 0; - char *name; +#ifdef CONFIG_KVM + struct kvm_device_attr attr = { + .group = KVM_DEV_VFIO_FILE, + .attr = KVM_DEV_VFIO_FILE_ADD, + .addr = (uint64_t)(unsigned long)&fd, + }; - if (!region->mem) { + if (!kvm_enabled()) { return 0; } - prot |= region->flags & VFIO_REGION_INFO_FLAG_READ ? PROT_READ : 0; - prot |= region->flags & VFIO_REGION_INFO_FLAG_WRITE ? PROT_WRITE : 0; - - for (i = 0; i < region->nr_mmaps; i++) { - size_t align = MIN(1ULL << ctz64(region->mmaps[i].size), 1 * GiB); - void *map_base, *map_align; - - /* - * Align the mmap for more efficient mapping in the kernel. Ideally - * we'd know the PMD and PUD mapping sizes to use as discrete alignment - * intervals, but we don't. As of Linux v6.12, the largest PUD size - * supporting huge pfnmap is 1GiB (ARCH_SUPPORTS_PUD_PFNMAP is only set - * on x86_64). Align by power-of-two size, capped at 1GiB. - * - * NB. qemu_memalign() and friends actually allocate memory, whereas - * the region size here can exceed host memory, therefore we manually - * create an oversized anonymous mapping and clean it up for alignment. - */ - map_base = mmap(0, region->mmaps[i].size + align, PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (map_base == MAP_FAILED) { - ret = -errno; - goto no_mmap; - } + if (vfio_kvm_device_fd < 0) { + struct kvm_create_device cd = { + .type = KVM_DEV_TYPE_VFIO, + }; - map_align = (void *)ROUND_UP((uintptr_t)map_base, (uintptr_t)align); - munmap(map_base, map_align - map_base); - munmap(map_align + region->mmaps[i].size, - align - (map_align - map_base)); - - region->mmaps[i].mmap = mmap(map_align, region->mmaps[i].size, prot, - MAP_SHARED | MAP_FIXED, - region->vbasedev->fd, - region->fd_offset + - region->mmaps[i].offset); - if (region->mmaps[i].mmap == MAP_FAILED) { - ret = -errno; - goto no_mmap; + if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) { + error_setg_errno(errp, errno, "Failed to create KVM VFIO device"); + return -errno; } - name = g_strdup_printf("%s mmaps[%d]", - memory_region_name(region->mem), i); - memory_region_init_ram_device_ptr(®ion->mmaps[i].mem, - memory_region_owner(region->mem), - name, region->mmaps[i].size, - region->mmaps[i].mmap); - g_free(name); - memory_region_add_subregion(region->mem, region->mmaps[i].offset, - ®ion->mmaps[i].mem); - - trace_vfio_region_mmap(memory_region_name(®ion->mmaps[i].mem), - region->mmaps[i].offset, - region->mmaps[i].offset + - region->mmaps[i].size - 1); - } - - return 0; - -no_mmap: - trace_vfio_region_mmap_fault(memory_region_name(region->mem), i, - region->fd_offset + region->mmaps[i].offset, - region->fd_offset + region->mmaps[i].offset + - region->mmaps[i].size - 1, ret); - - region->mmaps[i].mmap = NULL; - - for (i--; i >= 0; i--) { - vfio_subregion_unmap(region, i); - } - - return ret; -} - -void vfio_region_unmap(VFIORegion *region) -{ - int i; - - if (!region->mem) { - return; + vfio_kvm_device_fd = cd.fd; } - for (i = 0; i < region->nr_mmaps; i++) { - if (region->mmaps[i].mmap) { - vfio_subregion_unmap(region, i); - } - } -} - -void vfio_region_exit(VFIORegion *region) -{ - int i; - - if (!region->mem) { - return; - } - - for (i = 0; i < region->nr_mmaps; i++) { - if (region->mmaps[i].mmap) { - memory_region_del_subregion(region->mem, ®ion->mmaps[i].mem); - } - } - - trace_vfio_region_exit(region->vbasedev->name, region->nr); -} - -void vfio_region_finalize(VFIORegion *region) -{ - int i; - - if (!region->mem) { - return; - } - - for (i = 0; i < region->nr_mmaps; i++) { - if (region->mmaps[i].mmap) { - munmap(region->mmaps[i].mmap, region->mmaps[i].size); - object_unparent(OBJECT(®ion->mmaps[i].mem)); - } - } - - object_unparent(OBJECT(region->mem)); - - g_free(region->mem); - g_free(region->mmaps); - - trace_vfio_region_finalize(region->vbasedev->name, region->nr); - - region->mem = NULL; - region->mmaps = NULL; - region->nr_mmaps = 0; - region->size = 0; - region->flags = 0; - region->nr = 0; -} - -void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled) -{ - int i; - - if (!region->mem) { - return; - } - - for (i = 0; i < region->nr_mmaps; i++) { - if (region->mmaps[i].mmap) { - memory_region_set_enabled(®ion->mmaps[i].mem, enabled); - } - } - - trace_vfio_region_mmaps_set_enabled(memory_region_name(region->mem), - enabled); -} - -int vfio_get_region_info(VFIODevice *vbasedev, int index, - struct vfio_region_info **info) -{ - size_t argsz = sizeof(struct vfio_region_info); - - *info = g_malloc0(argsz); - - (*info)->index = index; -retry: - (*info)->argsz = argsz; - - if (ioctl(vbasedev->fd, VFIO_DEVICE_GET_REGION_INFO, *info)) { - g_free(*info); - *info = NULL; + if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) { + error_setg_errno(errp, errno, "Failed to add fd %d to KVM VFIO device", + fd); return -errno; } - - if ((*info)->argsz > argsz) { - argsz = (*info)->argsz; - *info = g_realloc(*info, argsz); - - goto retry; - } - +#endif return 0; } -int vfio_get_dev_region_info(VFIODevice *vbasedev, uint32_t type, - uint32_t subtype, struct vfio_region_info **info) -{ - int i; - - for (i = 0; i < vbasedev->num_regions; i++) { - struct vfio_info_cap_header *hdr; - struct vfio_region_info_cap_type *cap_type; - - if (vfio_get_region_info(vbasedev, i, info)) { - continue; - } - - hdr = vfio_get_region_info_cap(*info, VFIO_REGION_INFO_CAP_TYPE); - if (!hdr) { - g_free(*info); - continue; - } - - cap_type = container_of(hdr, struct vfio_region_info_cap_type, header); - - trace_vfio_get_dev_region(vbasedev->name, i, - cap_type->type, cap_type->subtype); - - if (cap_type->type == type && cap_type->subtype == subtype) { - return 0; - } - - g_free(*info); - } - - *info = NULL; - return -ENODEV; -} - -bool vfio_has_region_cap(VFIODevice *vbasedev, int region, uint16_t cap_type) +int vfio_kvm_device_del_fd(int fd, Error **errp) { - g_autofree struct vfio_region_info *info = NULL; - bool ret = false; - - if (!vfio_get_region_info(vbasedev, region, &info)) { - if (vfio_get_region_info_cap(info, cap_type)) { - ret = true; - } - } - - return ret; -} +#ifdef CONFIG_KVM + struct kvm_device_attr attr = { + .group = KVM_DEV_VFIO_FILE, + .attr = KVM_DEV_VFIO_FILE_DEL, + .addr = (uint64_t)(unsigned long)&fd, + }; -bool vfio_device_get_name(VFIODevice *vbasedev, Error **errp) -{ - ERRP_GUARD(); - struct stat st; - - if (vbasedev->fd < 0) { - if (stat(vbasedev->sysfsdev, &st) < 0) { - error_setg_errno(errp, errno, "no such host device"); - error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->sysfsdev); - return false; - } - /* User may specify a name, e.g: VFIO platform device */ - if (!vbasedev->name) { - vbasedev->name = g_path_get_basename(vbasedev->sysfsdev); - } - } else { - if (!vbasedev->iommufd) { - error_setg(errp, "Use FD passing only with iommufd backend"); - return false; - } - /* - * Give a name with fd so any function printing out vbasedev->name - * will not break. - */ - if (!vbasedev->name) { - vbasedev->name = g_strdup_printf("VFIO_FD%d", vbasedev->fd); - } + if (vfio_kvm_device_fd < 0) { + error_setg(errp, "KVM VFIO device isn't created yet"); + return -EINVAL; } - return true; -} - -void vfio_device_set_fd(VFIODevice *vbasedev, const char *str, Error **errp) -{ - ERRP_GUARD(); - int fd = monitor_fd_param(monitor_cur(), str, errp); - - if (fd < 0) { - error_prepend(errp, "Could not parse remote object fd %s:", str); - return; + if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) { + error_setg_errno(errp, errno, + "Failed to remove fd %d from KVM VFIO device", fd); + return -errno; } - vbasedev->fd = fd; -} - -void vfio_device_init(VFIODevice *vbasedev, int type, VFIODeviceOps *ops, - DeviceState *dev, bool ram_discard) -{ - vbasedev->type = type; - vbasedev->ops = ops; - vbasedev->dev = dev; - vbasedev->fd = -1; - - vbasedev->ram_block_discard_allowed = ram_discard; +#endif + return 0; } -int vfio_device_get_aw_bits(VFIODevice *vdev) +struct vfio_device_info *vfio_get_device_info(int fd) { - /* - * iova_ranges is a sorted list. For old kernels that support - * VFIO but not support query of iova ranges, iova_ranges is NULL, - * in this case HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX(64) is returned. - */ - GList *l = g_list_last(vdev->bcontainer->iova_ranges); - - if (l) { - Range *range = l->data; - return range_get_last_bit(range) + 1; - } + struct vfio_device_info *info; + uint32_t argsz = sizeof(*info); - return HOST_IOMMU_DEVICE_CAP_AW_BITS_MAX; -} + info = g_malloc0(argsz); -bool vfio_device_is_mdev(VFIODevice *vbasedev) -{ - g_autofree char *subsys = NULL; - g_autofree char *tmp = NULL; +retry: + info->argsz = argsz; - if (!vbasedev->sysfsdev) { - return false; + if (ioctl(fd, VFIO_DEVICE_GET_INFO, info)) { + g_free(info); + return NULL; } - tmp = g_strdup_printf("%s/subsystem", vbasedev->sysfsdev); - subsys = realpath(tmp, NULL); - return subsys && (strcmp(subsys, "/sys/bus/mdev") == 0); -} - -bool vfio_device_hiod_realize(VFIODevice *vbasedev, Error **errp) -{ - HostIOMMUDevice *hiod = vbasedev->hiod; - - if (!hiod) { - return true; + if (info->argsz > argsz) { + argsz = info->argsz; + info = g_realloc(info, argsz); + goto retry; } - return HOST_IOMMU_DEVICE_GET_CLASS(hiod)->realize(hiod, vbasedev, errp); -} - -VFIODevice *vfio_get_vfio_device(Object *obj) -{ - if (object_dynamic_cast(obj, TYPE_VFIO_PCI)) { - return &VFIO_PCI(obj)->vbasedev; - } else { - return NULL; - } + return info; } diff --git a/hw/vfio/igd.c b/hw/vfio/igd.c index 265fffc..e7a9d1f 100644 --- a/hw/vfio/igd.c +++ b/hw/vfio/igd.c @@ -103,6 +103,7 @@ static int igd_gen(VFIOPCIDevice *vdev) /* * Unfortunately, Intel changes it's specification quite often. This makes * it impossible to use a suitable default value for unknown devices. + * Return -1 for not applying any generation-specific quirks. */ return -1; } @@ -182,34 +183,25 @@ static bool vfio_pci_igd_opregion_init(VFIOPCIDevice *vdev, trace_vfio_pci_igd_opregion_enabled(vdev->vbasedev.name); - pci_set_long(vdev->pdev.config + IGD_ASLS, 0); - pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0); - pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0); - return true; } -static bool vfio_pci_igd_setup_opregion(VFIOPCIDevice *vdev, Error **errp) +static bool vfio_pci_igd_opregion_detect(VFIOPCIDevice *vdev, + struct vfio_region_info **opregion) { - g_autofree struct vfio_region_info *opregion = NULL; int ret; - /* Hotplugging is not supported for opregion access */ - if (vdev->pdev.qdev.hotplugged) { - error_setg(errp, "IGD OpRegion is not supported on hotplugged device"); - return false; - } - - ret = vfio_get_dev_region_info(&vdev->vbasedev, + ret = vfio_device_get_region_info_type(&vdev->vbasedev, VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL, - VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, &opregion); + VFIO_REGION_SUBTYPE_INTEL_IGD_OPREGION, opregion); if (ret) { - error_setg_errno(errp, -ret, - "Device does not supports IGD OpRegion feature"); return false; } - if (!vfio_pci_igd_opregion_init(vdev, opregion, errp)) { + /* Hotplugging is not supported for opregion access */ + if (vdev->pdev.qdev.hotplugged) { + warn_report("IGD device detected, but OpRegion is not supported " + "on hotplugged device."); return false; } @@ -301,7 +293,8 @@ static void vfio_pci_igd_lpc_bridge_realize(PCIDevice *pdev, Error **errp) } } -static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, void *data) +static void vfio_pci_igd_lpc_bridge_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -317,7 +310,7 @@ static const TypeInfo vfio_pci_igd_lpc_bridge_info = { .name = "vfio-pci-igd-lpc-bridge", .parent = TYPE_PCI_DEVICE, .class_init = vfio_pci_igd_lpc_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, @@ -354,8 +347,8 @@ static int vfio_pci_igd_lpc_init(VFIOPCIDevice *vdev, static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp) { - g_autofree struct vfio_region_info *host = NULL; - g_autofree struct vfio_region_info *lpc = NULL; + struct vfio_region_info *host = NULL; + struct vfio_region_info *lpc = NULL; PCIDevice *lpc_bridge; int ret; @@ -385,7 +378,7 @@ static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp) * Check whether we have all the vfio device specific regions to * support LPC quirk (added in Linux v4.6). */ - ret = vfio_get_dev_region_info(&vdev->vbasedev, + ret = vfio_device_get_region_info_type(&vdev->vbasedev, VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL, VFIO_REGION_SUBTYPE_INTEL_IGD_LPC_CFG, &lpc); if (ret) { @@ -393,7 +386,7 @@ static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp) return false; } - ret = vfio_get_dev_region_info(&vdev->vbasedev, + ret = vfio_device_get_region_info_type(&vdev->vbasedev, VFIO_REGION_TYPE_PCI_VENDOR_TYPE | PCI_VENDOR_ID_INTEL, VFIO_REGION_SUBTYPE_INTEL_IGD_HOST_CFG, &host); if (ret) { @@ -418,6 +411,44 @@ static bool vfio_pci_igd_setup_lpc_bridge(VFIOPCIDevice *vdev, Error **errp) return true; } +static bool vfio_pci_igd_override_gms(int gen, uint32_t gms, uint32_t *gmch) +{ + bool ret = false; + + if (gen == -1) { + error_report("x-igd-gms is not supported on this device"); + } else if (gen < 8) { + if (gms <= 0x10) { + *gmch &= ~(IGD_GMCH_GEN6_GMS_MASK << IGD_GMCH_GEN6_GMS_SHIFT); + *gmch |= gms << IGD_GMCH_GEN6_GMS_SHIFT; + ret = true; + } else { + error_report(QERR_INVALID_PARAMETER_VALUE, "x-igd-gms", "0~0x10"); + } + } else if (gen == 8) { + if (gms <= 0x40) { + *gmch &= ~(IGD_GMCH_GEN8_GMS_MASK << IGD_GMCH_GEN8_GMS_SHIFT); + *gmch |= gms << IGD_GMCH_GEN8_GMS_SHIFT; + ret = true; + } else { + error_report(QERR_INVALID_PARAMETER_VALUE, "x-igd-gms", "0~0x40"); + } + } else { + /* 0x0 to 0x40: 32MB increments starting at 0MB */ + /* 0xf0 to 0xfe: 4MB increments starting at 4MB */ + if ((gms <= 0x40) || (gms >= 0xf0 && gms <= 0xfe)) { + *gmch &= ~(IGD_GMCH_GEN8_GMS_MASK << IGD_GMCH_GEN8_GMS_SHIFT); + *gmch |= gms << IGD_GMCH_GEN8_GMS_SHIFT; + ret = true; + } else { + error_report(QERR_INVALID_PARAMETER_VALUE, + "x-igd-gms", "0~0x40 or 0xf0~0xfe"); + } + } + + return ret; +} + #define IGD_GGC_MMIO_OFFSET 0x108040 #define IGD_BDSM_MMIO_OFFSET 0x1080C0 @@ -427,41 +458,35 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr) VFIOConfigMirrorQuirk *ggc_mirror, *bdsm_mirror; int gen; - /* - * This must be an Intel VGA device at address 00:02.0 for us to even - * consider enabling legacy mode. Some driver have dependencies on the PCI - * bus address. - */ if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) || !vfio_is_vga(vdev) || nr != 0) { return; } - /* - * Only on IGD devices of gen 11 and above, the BDSM register is mirrored - * into MMIO space and read from MMIO space by the Windows driver. - */ + /* Only on IGD Gen6-12 device needs quirks in BAR 0 */ gen = igd_gen(vdev); if (gen < 6) { return; } - ggc_quirk = vfio_quirk_alloc(1); - ggc_mirror = ggc_quirk->data = g_malloc0(sizeof(*ggc_mirror)); - ggc_mirror->mem = ggc_quirk->mem; - ggc_mirror->vdev = vdev; - ggc_mirror->bar = nr; - ggc_mirror->offset = IGD_GGC_MMIO_OFFSET; - ggc_mirror->config_offset = IGD_GMCH; - - memory_region_init_io(ggc_mirror->mem, OBJECT(vdev), - &vfio_generic_mirror_quirk, ggc_mirror, - "vfio-igd-ggc-quirk", 2); - memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, - ggc_mirror->offset, ggc_mirror->mem, - 1); - - QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, ggc_quirk, next); + if (vdev->igd_gms) { + ggc_quirk = vfio_quirk_alloc(1); + ggc_mirror = ggc_quirk->data = g_malloc0(sizeof(*ggc_mirror)); + ggc_mirror->mem = ggc_quirk->mem; + ggc_mirror->vdev = vdev; + ggc_mirror->bar = nr; + ggc_mirror->offset = IGD_GGC_MMIO_OFFSET; + ggc_mirror->config_offset = IGD_GMCH; + + memory_region_init_io(ggc_mirror->mem, OBJECT(vdev), + &vfio_generic_mirror_quirk, ggc_mirror, + "vfio-igd-ggc-quirk", 2); + memory_region_add_subregion_overlap(vdev->bars[nr].region.mem, + ggc_mirror->offset, ggc_mirror->mem, + 1); + + QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, ggc_quirk, next); + } bdsm_quirk = vfio_quirk_alloc(1); bdsm_mirror = bdsm_quirk->data = g_malloc0(sizeof(*bdsm_mirror)); @@ -483,44 +508,37 @@ void vfio_probe_igd_bar0_quirk(VFIOPCIDevice *vdev, int nr) static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) { + struct vfio_region_info *opregion = NULL; int ret, gen; - uint64_t gms_size; + uint64_t gms_size = 0; uint64_t *bdsm_size; uint32_t gmch; bool legacy_mode_enabled = false; Error *err = NULL; - /* - * This must be an Intel VGA device at address 00:02.0 for us to even - * consider enabling legacy mode. The vBIOS has dependencies on the - * PCI bus address. - */ if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) || !vfio_is_vga(vdev)) { return true; } - /* - * IGD is not a standard, they like to change their specs often. We - * only attempt to support back to SandBridge and we hope that newer - * devices maintain compatibility with generation 8. - */ - gen = igd_gen(vdev); - if (gen == -1) { - error_report("IGD device %s is unsupported in legacy mode, " - "try SandyBridge or newer", vdev->vbasedev.name); + /* IGD device always comes with OpRegion */ + if (!vfio_pci_igd_opregion_detect(vdev, &opregion)) { return true; } + info_report("OpRegion detected on Intel display %x.", vdev->device_id); + gen = igd_gen(vdev); gmch = vfio_pci_read_config(&vdev->pdev, IGD_GMCH, 4); /* * For backward compatibility, enable legacy mode when + * - Device geneation is 6 to 9 (including both) * - Machine type is i440fx (pc_piix) * - IGD device is at guest BDF 00:02.0 * - Not manually disabled by x-igd-legacy-mode=off */ if ((vdev->igd_legacy_mode != ON_OFF_AUTO_OFF) && + (gen >= 6 && gen <= 9) && !strcmp(MACHINE_GET_CLASS(qdev_get_machine())->family, "pc_piix") && (&vdev->pdev == pci_find_device(pci_device_root_bus(&vdev->pdev), 0, PCI_DEVFN(0x2, 0)))) { @@ -531,7 +549,7 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) * - OpRegion * - Same LPC bridge and Host bridge VID/DID/SVID/SSID as host */ - g_autofree struct vfio_region_info *rom = NULL; + struct vfio_region_info *rom = NULL; legacy_mode_enabled = true; info_report("IGD legacy mode enabled, " @@ -542,8 +560,8 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) * there's no ROM, there's no point in setting up this quirk. * NB. We only seem to get BIOS ROMs, so UEFI VM would need CSM support. */ - ret = vfio_get_region_info(&vdev->vbasedev, - VFIO_PCI_ROM_REGION_INDEX, &rom); + ret = vfio_device_get_region_info(&vdev->vbasedev, + VFIO_PCI_ROM_REGION_INDEX, &rom); if ((ret || !rom->size) && !vdev->pdev.romfile) { error_setg(&err, "Device has no ROM"); goto error; @@ -565,13 +583,15 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) vdev->features |= VFIO_FEATURE_ENABLE_IGD_LPC; } else if (vdev->igd_legacy_mode == ON_OFF_AUTO_ON) { error_setg(&err, - "Machine is not i440fx or assigned BDF is not 00:02.0"); + "Machine is not i440fx, assigned BDF is not 00:02.0, " + "or device %04x (gen %d) doesn't support legacy mode", + vdev->device_id, gen); goto error; } /* Setup OpRegion access */ if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) && - !vfio_pci_igd_setup_opregion(vdev, errp)) { + !vfio_pci_igd_opregion_init(vdev, opregion, errp)) { goto error; } @@ -579,7 +599,15 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_LPC) && !vfio_pci_igd_setup_lpc_bridge(vdev, errp)) { goto error; - } + } + + /* + * ASLS (OpRegion address) is read-only, emulated + * It contains HPA, guest firmware need to reprogram it with GPA. + */ + pci_set_long(vdev->pdev.config + IGD_ASLS, 0); + pci_set_long(vdev->pdev.wmask + IGD_ASLS, ~0); + pci_set_long(vdev->emulated_config_bits + IGD_ASLS, ~0); /* * Allow user to override dsm size using x-igd-gms option, in multiples of @@ -587,56 +615,44 @@ static bool vfio_pci_igd_config_quirk(VFIOPCIDevice *vdev, Error **errp) * set from DVMT Pre-Allocated option in host BIOS. */ if (vdev->igd_gms) { - if (gen < 8) { - if (vdev->igd_gms <= 0x10) { - gmch &= ~(IGD_GMCH_GEN6_GMS_MASK << IGD_GMCH_GEN6_GMS_SHIFT); - gmch |= vdev->igd_gms << IGD_GMCH_GEN6_GMS_SHIFT; - } else { - error_report(QERR_INVALID_PARAMETER_VALUE, - "x-igd-gms", "0~0x10"); - } - } else { - if (vdev->igd_gms <= 0x40) { - gmch &= ~(IGD_GMCH_GEN8_GMS_MASK << IGD_GMCH_GEN8_GMS_SHIFT); - gmch |= vdev->igd_gms << IGD_GMCH_GEN8_GMS_SHIFT; - } else { - error_report(QERR_INVALID_PARAMETER_VALUE, - "x-igd-gms", "0~0x40"); - } + if (!vfio_pci_igd_override_gms(gen, vdev->igd_gms, &gmch)) { + return false; } + + /* GMCH is read-only, emulated */ + pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); + pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); + pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); } - gms_size = igd_stolen_memory_size(gen, gmch); + if (gen > 0) { + gms_size = igd_stolen_memory_size(gen, gmch); + + /* BDSM is read-write, emulated. BIOS needs to be able to write it */ + if (gen < 11) { + pci_set_long(vdev->pdev.config + IGD_BDSM, 0); + pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0); + pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0); + } else { + pci_set_quad(vdev->pdev.config + IGD_BDSM_GEN11, 0); + pci_set_quad(vdev->pdev.wmask + IGD_BDSM_GEN11, ~0); + pci_set_quad(vdev->emulated_config_bits + IGD_BDSM_GEN11, ~0); + } + } /* * Request reserved memory for stolen memory via fw_cfg. VM firmware * must allocate a 1MB aligned reserved memory region below 4GB with - * the requested size (in bytes) for use by the Intel PCI class VGA - * device at VM address 00:02.0. The base address of this reserved - * memory region must be written to the device BDSM register at PCI - * config offset 0x5C. + * the requested size (in bytes) for use by the IGD device. The base + * address of this reserved memory region must be written to the + * device BDSM register. + * For newer device without BDSM register, this fw_cfg item is 0. */ bdsm_size = g_malloc(sizeof(*bdsm_size)); *bdsm_size = cpu_to_le64(gms_size); fw_cfg_add_file(fw_cfg_find(), "etc/igd-bdsm-size", bdsm_size, sizeof(*bdsm_size)); - /* GMCH is read-only, emulated */ - pci_set_long(vdev->pdev.config + IGD_GMCH, gmch); - pci_set_long(vdev->pdev.wmask + IGD_GMCH, 0); - pci_set_long(vdev->emulated_config_bits + IGD_GMCH, ~0); - - /* BDSM is read-write, emulated. The BIOS needs to be able to write it */ - if (gen < 11) { - pci_set_long(vdev->pdev.config + IGD_BDSM, 0); - pci_set_long(vdev->pdev.wmask + IGD_BDSM, ~0); - pci_set_long(vdev->emulated_config_bits + IGD_BDSM, ~0); - } else { - pci_set_quad(vdev->pdev.config + IGD_BDSM_GEN11, 0); - pci_set_quad(vdev->pdev.wmask + IGD_BDSM_GEN11, ~0); - pci_set_quad(vdev->emulated_config_bits + IGD_BDSM_GEN11, ~0); - } - trace_vfio_pci_igd_bdsm_enabled(vdev->vbasedev.name, (gms_size / MiB)); return true; @@ -663,8 +679,27 @@ error: */ static bool vfio_pci_kvmgt_config_quirk(VFIOPCIDevice *vdev, Error **errp) { + struct vfio_region_info *opregion = NULL; + int gen; + + if (!vfio_pci_is(vdev, PCI_VENDOR_ID_INTEL, PCI_ANY_ID) || + !vfio_is_vga(vdev)) { + return true; + } + + /* FIXME: Cherryview is Gen8, but don't support GVT-g */ + gen = igd_gen(vdev); + if (gen != 8 && gen != 9) { + return true; + } + + if (!vfio_pci_igd_opregion_detect(vdev, &opregion)) { + /* Should never reach here, KVMGT always emulates OpRegion */ + return false; + } + if ((vdev->features & VFIO_FEATURE_ENABLE_IGD_OPREGION) && - !vfio_pci_igd_setup_opregion(vdev, errp)) { + !vfio_pci_igd_opregion_init(vdev, opregion, errp)) { return false; } diff --git a/hw/vfio/iommufd.c b/hw/vfio/iommufd.c index 42c8412..d3efef7 100644 --- a/hw/vfio/iommufd.c +++ b/hw/vfio/iommufd.c @@ -15,19 +15,27 @@ #include <linux/vfio.h> #include <linux/iommufd.h> -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "qemu/error-report.h" #include "trace.h" #include "qapi/error.h" #include "system/iommufd.h" #include "hw/qdev-core.h" +#include "hw/vfio/vfio-cpr.h" #include "system/reset.h" #include "qemu/cutils.h" #include "qemu/chardev_open.h" #include "pci.h" +#include "vfio-iommufd.h" +#include "vfio-helpers.h" +#include "vfio-listener.h" + +#define TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO \ + TYPE_HOST_IOMMU_DEVICE_IOMMUFD "-vfio" static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova, - ram_addr_t size, void *vaddr, bool readonly) + ram_addr_t size, void *vaddr, bool readonly, + MemoryRegion *mr) { const VFIOIOMMUFDContainer *container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); @@ -39,11 +47,28 @@ static int iommufd_cdev_map(const VFIOContainerBase *bcontainer, hwaddr iova, static int iommufd_cdev_unmap(const VFIOContainerBase *bcontainer, hwaddr iova, ram_addr_t size, - IOMMUTLBEntry *iotlb) + IOMMUTLBEntry *iotlb, bool unmap_all) { const VFIOIOMMUFDContainer *container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); + /* unmap in halves */ + if (unmap_all) { + Int128 llsize = int128_rshift(int128_2_64(), 1); + int ret; + + ret = iommufd_backend_unmap_dma(container->be, container->ioas_id, + 0, int128_get64(llsize)); + + if (ret == 0) { + ret = iommufd_backend_unmap_dma(container->be, container->ioas_id, + int128_get64(llsize), + int128_get64(llsize)); + } + + return ret; + } + /* TODO: Handle dma_unmap_bitmap with iotlb args (migration) */ return iommufd_backend_unmap_dma(container->be, container->ioas_id, iova, size); @@ -280,7 +305,8 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev, { ERRP_GUARD(); IOMMUFDBackend *iommufd = vbasedev->iommufd; - uint32_t flags = 0; + uint32_t type, flags = 0; + uint64_t hw_caps; VFIOIOASHwpt *hwpt; uint32_t hwpt_id; int ret; @@ -317,7 +343,12 @@ static bool iommufd_cdev_autodomains_get(VFIODevice *vbasedev, * vfio_migration_realize() may decide to use VF dirty tracking * instead. */ - if (vbasedev->hiod->caps.hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) { + if (!iommufd_backend_get_device_info(vbasedev->iommufd, vbasedev->devid, + &type, NULL, 0, &hw_caps, errp)) { + return false; + } + + if (hw_caps & IOMMU_HW_CAP_DIRTY_TRACKING) { flags = IOMMU_HWPT_ALLOC_DIRTY_TRACKING; } @@ -403,7 +434,8 @@ static void iommufd_cdev_container_destroy(VFIOIOMMUFDContainer *container) if (!QLIST_EMPTY(&bcontainer->device_list)) { return; } - memory_listener_unregister(&bcontainer->listener); + vfio_cpr_unregister_container(bcontainer); + vfio_listener_unregister(bcontainer); iommufd_backend_free_id(container->be, container->ioas_id); object_unref(container); } @@ -485,18 +517,7 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, goto err_connect_bind; } - space = vfio_get_address_space(as); - - /* - * The HostIOMMUDevice data from legacy backend is static and doesn't need - * any information from the (type1-iommu) backend to be initialized. In - * contrast however, the IOMMUFD HostIOMMUDevice data requires the iommufd - * FD to be connected and having a devid to be able to successfully call - * iommufd_backend_get_device_info(). - */ - if (!vfio_device_hiod_realize(vbasedev, errp)) { - goto err_alloc_ioas; - } + space = vfio_address_space_get(as); /* try to attach to an existing container in this space */ QLIST_FOREACH(bcontainer, &space->containers, next) { @@ -555,12 +576,11 @@ static bool iommufd_cdev_attach(const char *name, VFIODevice *vbasedev, bcontainer->pgsizes = qemu_real_host_page_size(); } - bcontainer->listener = vfio_memory_listener; - memory_listener_register(&bcontainer->listener, bcontainer->space->as); + if (!vfio_listener_register(bcontainer, errp)) { + goto err_listener_register; + } - if (bcontainer->error) { - error_propagate_prepend(errp, bcontainer->error, - "memory listener initialization failed: "); + if (!vfio_cpr_register_container(bcontainer, errp)) { goto err_listener_register; } @@ -573,7 +593,12 @@ found_container: goto err_listener_register; } - if (!vfio_cpr_register_container(bcontainer, errp)) { + /* + * Do not move this code before attachment! The nested IOMMU support + * needs device and hwpt id which are generated only after attachment. + */ + if (!vfio_device_hiod_create_and_realize(vbasedev, + TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO, errp)) { goto err_listener_register; } @@ -585,14 +610,7 @@ found_container: iommufd_cdev_ram_block_discard_disable(false); } - vbasedev->group = 0; - vbasedev->num_irqs = dev_info.num_irqs; - vbasedev->num_regions = dev_info.num_regions; - vbasedev->flags = dev_info.flags; - vbasedev->reset_works = !!(dev_info.flags & VFIO_DEVICE_FLAGS_RESET); - vbasedev->bcontainer = bcontainer; - QLIST_INSERT_HEAD(&bcontainer->device_list, vbasedev, container_next); - QLIST_INSERT_HEAD(&vfio_device_list, vbasedev, global_next); + vfio_device_prepare(vbasedev, bcontainer, &dev_info); trace_iommufd_cdev_device_info(vbasedev->name, devfd, vbasedev->num_irqs, vbasedev->num_regions, vbasedev->flags); @@ -605,7 +623,7 @@ err_discard_disable: err_attach_container: iommufd_cdev_container_destroy(container); err_alloc_ioas: - vfio_put_address_space(space); + vfio_address_space_put(space); iommufd_cdev_unbind_and_disconnect(vbasedev); err_connect_bind: close(vbasedev->fd); @@ -619,18 +637,16 @@ static void iommufd_cdev_detach(VFIODevice *vbasedev) VFIOIOMMUFDContainer *container = container_of(bcontainer, VFIOIOMMUFDContainer, bcontainer); - QLIST_REMOVE(vbasedev, global_next); - QLIST_REMOVE(vbasedev, container_next); - vbasedev->bcontainer = NULL; + vfio_device_unprepare(vbasedev); if (!vbasedev->ram_block_discard_allowed) { iommufd_cdev_ram_block_discard_disable(false); } - vfio_cpr_unregister_container(bcontainer); + object_unref(vbasedev->hiod); iommufd_cdev_detach_container(vbasedev, container); iommufd_cdev_container_destroy(container); - vfio_put_address_space(space); + vfio_address_space_put(space); iommufd_cdev_unbind_and_disconnect(vbasedev); close(vbasedev->fd); @@ -786,12 +802,10 @@ out_single: return ret; } -static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data) +static void vfio_iommu_iommufd_class_init(ObjectClass *klass, const void *data) { VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); - vioc->hiod_typename = TYPE_HOST_IOMMU_DEVICE_IOMMUFD_VFIO; - vioc->dma_map = iommufd_cdev_map; vioc->dma_unmap = iommufd_cdev_unmap; vioc->attach_device = iommufd_cdev_attach; @@ -801,21 +815,38 @@ static void vfio_iommu_iommufd_class_init(ObjectClass *klass, void *data) vioc->query_dirty_bitmap = iommufd_query_dirty_bitmap; }; +static bool +host_iommu_device_iommufd_vfio_attach_hwpt(HostIOMMUDeviceIOMMUFD *idev, + uint32_t hwpt_id, Error **errp) +{ + VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent; + + return !iommufd_cdev_attach_ioas_hwpt(vbasedev, hwpt_id, errp); +} + +static bool +host_iommu_device_iommufd_vfio_detach_hwpt(HostIOMMUDeviceIOMMUFD *idev, + Error **errp) +{ + VFIODevice *vbasedev = HOST_IOMMU_DEVICE(idev)->agent; + + return iommufd_cdev_detach_ioas_hwpt(vbasedev, errp); +} + static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque, Error **errp) { VFIODevice *vdev = opaque; + HostIOMMUDeviceIOMMUFD *idev; HostIOMMUDeviceCaps *caps = &hiod->caps; + VendorCaps *vendor_caps = &caps->vendor_caps; enum iommu_hw_info_type type; - union { - struct iommu_hw_info_vtd vtd; - } data; uint64_t hw_caps; hiod->agent = opaque; - if (!iommufd_backend_get_device_info(vdev->iommufd, vdev->devid, - &type, &data, sizeof(data), + if (!iommufd_backend_get_device_info(vdev->iommufd, vdev->devid, &type, + vendor_caps, sizeof(*vendor_caps), &hw_caps, errp)) { return false; } @@ -824,6 +855,11 @@ static bool hiod_iommufd_vfio_realize(HostIOMMUDevice *hiod, void *opaque, caps->type = type; caps->hw_caps = hw_caps; + idev = HOST_IOMMU_DEVICE_IOMMUFD(hiod); + idev->iommufd = vdev->iommufd; + idev->devid = vdev->devid; + idev->hwpt_id = vdev->hwpt->hwpt_id; + return true; } @@ -846,13 +882,17 @@ hiod_iommufd_vfio_get_page_size_mask(HostIOMMUDevice *hiod) } -static void hiod_iommufd_vfio_class_init(ObjectClass *oc, void *data) +static void hiod_iommufd_vfio_class_init(ObjectClass *oc, const void *data) { HostIOMMUDeviceClass *hiodc = HOST_IOMMU_DEVICE_CLASS(oc); + HostIOMMUDeviceIOMMUFDClass *idevc = HOST_IOMMU_DEVICE_IOMMUFD_CLASS(oc); hiodc->realize = hiod_iommufd_vfio_realize; hiodc->get_iova_ranges = hiod_iommufd_vfio_get_iova_ranges; hiodc->get_page_size_mask = hiod_iommufd_vfio_get_page_size_mask; + + idevc->attach_hwpt = host_iommu_device_iommufd_vfio_attach_hwpt; + idevc->detach_hwpt = host_iommu_device_iommufd_vfio_detach_hwpt; }; static const TypeInfo types[] = { diff --git a/hw/vfio/common.c b/hw/vfio/listener.c index d8aad4e..f498e23 100644 --- a/hw/vfio/common.c +++ b/hw/vfio/listener.c @@ -25,12 +25,11 @@ #endif #include <linux/vfio.h> -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "hw/vfio/pci.h" -#include "exec/address-spaces.h" -#include "exec/memory.h" -#include "exec/ram_addr.h" -#include "exec/target_page.h" +#include "system/address-spaces.h" +#include "system/memory.h" +#include "system/ram_addr.h" #include "hw/hw.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" @@ -41,160 +40,23 @@ #include "trace.h" #include "qapi/error.h" #include "migration/misc.h" -#include "migration/blocker.h" #include "migration/qemu-file.h" #include "system/tcg.h" #include "system/tpm.h" - -VFIODeviceList vfio_device_list = - QLIST_HEAD_INITIALIZER(vfio_device_list); -static QLIST_HEAD(, VFIOAddressSpace) vfio_address_spaces = - QLIST_HEAD_INITIALIZER(vfio_address_spaces); - -#ifdef CONFIG_KVM -/* - * We have a single VFIO pseudo device per KVM VM. Once created it lives - * for the life of the VM. Closing the file descriptor only drops our - * reference to it and the device's reference to kvm. Therefore once - * initialized, this file descriptor is only released on QEMU exit and - * we'll re-use it should another vfio device be attached before then. - */ -int vfio_kvm_device_fd = -1; -#endif +#include "vfio-migration-internal.h" +#include "vfio-helpers.h" +#include "vfio-listener.h" /* * Device state interfaces */ -bool vfio_mig_active(void) -{ - VFIODevice *vbasedev; - - if (QLIST_EMPTY(&vfio_device_list)) { - return false; - } - - QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->migration_blocker) { - return false; - } - } - return true; -} - -static Error *multiple_devices_migration_blocker; - -/* - * Multiple devices migration is allowed only if all devices support P2P - * migration. Single device migration is allowed regardless of P2P migration - * support. - */ -static bool vfio_multiple_devices_migration_is_supported(void) -{ - VFIODevice *vbasedev; - unsigned int device_num = 0; - bool all_support_p2p = true; - - QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->migration) { - device_num++; - - if (!(vbasedev->migration->mig_flags & VFIO_MIGRATION_P2P)) { - all_support_p2p = false; - } - } - } - - return all_support_p2p || device_num <= 1; -} - -int vfio_block_multiple_devices_migration(VFIODevice *vbasedev, Error **errp) -{ - if (vfio_multiple_devices_migration_is_supported()) { - return 0; - } - - if (vbasedev->enable_migration == ON_OFF_AUTO_ON) { - error_setg(errp, "Multiple VFIO devices migration is supported only if " - "all of them support P2P migration"); - return -EINVAL; - } - - if (multiple_devices_migration_blocker) { - return 0; - } - - error_setg(&multiple_devices_migration_blocker, - "Multiple VFIO devices migration is supported only if all of " - "them support P2P migration"); - return migrate_add_blocker_normal(&multiple_devices_migration_blocker, - errp); -} - -void vfio_unblock_multiple_devices_migration(void) -{ - if (!multiple_devices_migration_blocker || - !vfio_multiple_devices_migration_is_supported()) { - return; - } - - migrate_del_blocker(&multiple_devices_migration_blocker); -} - -bool vfio_viommu_preset(VFIODevice *vbasedev) -{ - return vbasedev->bcontainer->space->as != &address_space_memory; -} - -static void vfio_set_migration_error(int ret) -{ - if (migration_is_running()) { - migration_file_set_error(ret, NULL); - } -} - -bool vfio_device_state_is_running(VFIODevice *vbasedev) -{ - VFIOMigration *migration = vbasedev->migration; - - return migration->device_state == VFIO_DEVICE_STATE_RUNNING || - migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P; -} - -bool vfio_device_state_is_precopy(VFIODevice *vbasedev) -{ - VFIOMigration *migration = vbasedev->migration; - - return migration->device_state == VFIO_DEVICE_STATE_PRE_COPY || - migration->device_state == VFIO_DEVICE_STATE_PRE_COPY_P2P; -} - -static bool vfio_devices_all_device_dirty_tracking_started( - const VFIOContainerBase *bcontainer) -{ - VFIODevice *vbasedev; - - QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - if (!vbasedev->dirty_tracking) { - return false; - } - } - - return true; -} - -bool vfio_devices_all_dirty_tracking_started( - const VFIOContainerBase *bcontainer) -{ - return vfio_devices_all_device_dirty_tracking_started(bcontainer) || - bcontainer->dirty_pages_started; -} static bool vfio_log_sync_needed(const VFIOContainerBase *bcontainer) { VFIODevice *vbasedev; - if (!vfio_devices_all_dirty_tracking_started(bcontainer)) { + if (!vfio_container_dirty_tracking_is_started(bcontainer)) { return false; } @@ -214,22 +76,6 @@ static bool vfio_log_sync_needed(const VFIOContainerBase *bcontainer) return true; } -bool vfio_devices_all_device_dirty_tracking(const VFIOContainerBase *bcontainer) -{ - VFIODevice *vbasedev; - - QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - if (vbasedev->device_dirty_page_tracking == ON_OFF_AUTO_OFF) { - return false; - } - if (!vbasedev->dirty_pages_supported) { - return false; - } - } - - return true; -} - static bool vfio_listener_skipped_section(MemoryRegionSection *section) { return (!memory_region_is_ram(section->mr) && @@ -244,16 +90,17 @@ static bool vfio_listener_skipped_section(MemoryRegionSection *section) section->offset_within_address_space & (1ULL << 63); } -/* Called with rcu_read_lock held. */ -static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, - ram_addr_t *ram_addr, bool *read_only, - Error **errp) +/* + * Called with rcu_read_lock held. + * The returned MemoryRegion must not be accessed after calling rcu_read_unlock. + */ +static MemoryRegion *vfio_translate_iotlb(IOMMUTLBEntry *iotlb, hwaddr *xlat_p, + Error **errp) { - bool ret, mr_has_discard_manager; + MemoryRegion *mr; - ret = memory_get_xlat_addr(iotlb, vaddr, ram_addr, read_only, - &mr_has_discard_manager, errp); - if (ret && mr_has_discard_manager) { + mr = memory_translate_iotlb(iotlb, xlat_p, errp); + if (mr && memory_region_has_ram_discard_manager(mr)) { /* * Malicious VMs might trigger discarding of IOMMU-mapped memory. The * pages will remain pinned inside vfio until unmapped, resulting in a @@ -272,7 +119,7 @@ static bool vfio_get_xlat_addr(IOMMUTLBEntry *iotlb, void **vaddr, " intended via an IOMMU. It's possible to mitigate " " by setting/adjusting RLIMIT_MEMLOCK."); } - return ret; + return mr; } static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) @@ -280,6 +127,8 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) VFIOGuestIOMMU *giommu = container_of(n, VFIOGuestIOMMU, n); VFIOContainerBase *bcontainer = giommu->bcontainer; hwaddr iova = iotlb->iova + giommu->iommu_offset; + MemoryRegion *mr; + hwaddr xlat; void *vaddr; int ret; Error *local_err = NULL; @@ -288,9 +137,14 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) iova, iova + iotlb->addr_mask); if (iotlb->target_as != &address_space_memory) { - error_report("Wrong target AS \"%s\", only system memory is allowed", - iotlb->target_as->name ? iotlb->target_as->name : "none"); - vfio_set_migration_error(-EINVAL); + error_setg(&local_err, + "Wrong target AS \"%s\", only system memory is allowed", + iotlb->target_as->name ? iotlb->target_as->name : "none"); + if (migration_is_running()) { + migration_file_set_error(-EINVAL, local_err); + } else { + error_report_err(local_err); + } return; } @@ -299,10 +153,14 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) { bool read_only; - if (!vfio_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, &local_err)) { + mr = vfio_translate_iotlb(iotlb, &xlat, &local_err); + if (!mr) { error_report_err(local_err); goto out; } + vaddr = memory_region_get_ram_ptr(mr) + xlat; + read_only = !(iotlb->perm & IOMMU_WO) || mr->readonly; + /* * vaddr is only valid until rcu_read_unlock(). But after * vfio_dma_map has set up the mapping the pages will be @@ -312,7 +170,7 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) */ ret = vfio_container_dma_map(bcontainer, iova, iotlb->addr_mask + 1, vaddr, - read_only); + read_only, mr); if (ret) { error_report("vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx", %p) = %d (%s)", @@ -321,13 +179,18 @@ static void vfio_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) } } else { ret = vfio_container_dma_unmap(bcontainer, iova, - iotlb->addr_mask + 1, iotlb); + iotlb->addr_mask + 1, iotlb, false); if (ret) { - error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", - bcontainer, iova, - iotlb->addr_mask + 1, ret, strerror(-ret)); - vfio_set_migration_error(ret); + error_setg(&local_err, + "vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " + "0x%"HWADDR_PRIx") = %d (%s)", + bcontainer, iova, + iotlb->addr_mask + 1, ret, strerror(-ret)); + if (migration_is_running()) { + migration_file_set_error(ret, local_err); + } else { + error_report_err(local_err); + } } } out: @@ -345,7 +208,7 @@ static void vfio_ram_discard_notify_discard(RamDiscardListener *rdl, int ret; /* Unmap with a single call. */ - ret = vfio_container_dma_unmap(bcontainer, iova, size , NULL); + ret = vfio_container_dma_unmap(bcontainer, iova, size , NULL, false); if (ret) { error_report("%s: vfio_container_dma_unmap() failed: %s", __func__, strerror(-ret)); @@ -377,7 +240,7 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, vaddr = memory_region_get_ram_ptr(section->mr) + start; ret = vfio_container_dma_map(bcontainer, iova, next - start, - vaddr, section->readonly); + vaddr, section->readonly, section->mr); if (ret) { /* Rollback */ vfio_ram_discard_notify_discard(rdl, section); @@ -387,7 +250,7 @@ static int vfio_ram_discard_notify_populate(RamDiscardListener *rdl, return 0; } -static void vfio_register_ram_discard_listener(VFIOContainerBase *bcontainer, +static void vfio_ram_discard_register_listener(VFIOContainerBase *bcontainer, MemoryRegionSection *section) { RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); @@ -462,7 +325,7 @@ static void vfio_register_ram_discard_listener(VFIOContainerBase *bcontainer, } } -static void vfio_unregister_ram_discard_listener(VFIOContainerBase *bcontainer, +static void vfio_ram_discard_unregister_listener(VFIOContainerBase *bcontainer, MemoryRegionSection *section) { RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); @@ -555,6 +418,32 @@ static bool vfio_get_section_iova_range(VFIOContainerBase *bcontainer, return true; } +static void vfio_listener_begin(MemoryListener *listener) +{ + VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, + listener); + void (*listener_begin)(VFIOContainerBase *bcontainer); + + listener_begin = VFIO_IOMMU_GET_CLASS(bcontainer)->listener_begin; + + if (listener_begin) { + listener_begin(bcontainer); + } +} + +static void vfio_listener_commit(MemoryListener *listener) +{ + VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, + listener); + void (*listener_commit)(VFIOContainerBase *bcontainer); + + listener_commit = VFIO_IOMMU_GET_CLASS(bcontainer)->listener_commit; + + if (listener_commit) { + listener_commit(bcontainer); + } +} + static void vfio_device_error_append(VFIODevice *vbasedev, Error **errp) { /* @@ -567,11 +456,38 @@ static void vfio_device_error_append(VFIODevice *vbasedev, Error **errp) } } +VFIORamDiscardListener *vfio_find_ram_discard_listener( + VFIOContainerBase *bcontainer, MemoryRegionSection *section) +{ + VFIORamDiscardListener *vrdl = NULL; + + QLIST_FOREACH(vrdl, &bcontainer->vrdl_list, next) { + if (vrdl->mr == section->mr && + vrdl->offset_within_address_space == + section->offset_within_address_space) { + break; + } + } + + if (!vrdl) { + hw_error("vfio: Trying to sync missing RAM discard listener"); + /* does not return */ + } + return vrdl; +} + static void vfio_listener_region_add(MemoryListener *listener, MemoryRegionSection *section) { VFIOContainerBase *bcontainer = container_of(listener, VFIOContainerBase, listener); + vfio_container_region_add(bcontainer, section, false); +} + +void vfio_container_region_add(VFIOContainerBase *bcontainer, + MemoryRegionSection *section, + bool cpr_remap) +{ hwaddr iova, end; Int128 llend, llsize; void *vaddr; @@ -607,6 +523,11 @@ static void vfio_listener_region_add(MemoryListener *listener, int iommu_idx; trace_vfio_listener_region_add_iommu(section->mr->name, iova, end); + + if (cpr_remap) { + vfio_cpr_giommu_remap(bcontainer, section); + } + /* * FIXME: For VFIO iommu types which have KVM acceleration to * avoid bouncing all map/unmaps through qemu this way, this @@ -649,7 +570,12 @@ static void vfio_listener_region_add(MemoryListener *listener, * about changes. */ if (memory_region_has_ram_discard_manager(section->mr)) { - vfio_register_ram_discard_listener(bcontainer, section); + if (!cpr_remap) { + vfio_ram_discard_register_listener(bcontainer, section); + } else if (!vfio_cpr_ram_discard_register_listener(bcontainer, + section)) { + goto fail; + } return; } @@ -675,7 +601,7 @@ static void vfio_listener_region_add(MemoryListener *listener, } ret = vfio_container_dma_map(bcontainer, iova, int128_get64(llsize), - vaddr, section->readonly); + vaddr, section->readonly, section->mr); if (ret) { error_setg(&err, "vfio_container_dma_map(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx", %p) = %d (%s)", @@ -772,27 +698,20 @@ static void vfio_listener_region_del(MemoryListener *listener, pgmask = (1ULL << ctz64(bcontainer->pgsizes)) - 1; try_unmap = !((iova & pgmask) || (int128_get64(llsize) & pgmask)); } else if (memory_region_has_ram_discard_manager(section->mr)) { - vfio_unregister_ram_discard_listener(bcontainer, section); + vfio_ram_discard_unregister_listener(bcontainer, section); /* Unregistering will trigger an unmap. */ try_unmap = false; } if (try_unmap) { + bool unmap_all = false; + if (int128_eq(llsize, int128_2_64())) { - /* The unmap ioctl doesn't accept a full 64-bit span. */ - llsize = int128_rshift(llsize, 1); - ret = vfio_container_dma_unmap(bcontainer, iova, - int128_get64(llsize), NULL); - if (ret) { - error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " - "0x%"HWADDR_PRIx") = %d (%s)", - bcontainer, iova, int128_get64(llsize), ret, - strerror(-ret)); - } - iova += int128_get64(llsize); + unmap_all = true; + llsize = int128_zero(); } - ret = vfio_container_dma_unmap(bcontainer, iova, - int128_get64(llsize), NULL); + ret = vfio_container_dma_unmap(bcontainer, iova, int128_get64(llsize), + NULL, unmap_all); if (ret) { error_report("vfio_container_dma_unmap(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx") = %d (%s)", @@ -945,13 +864,17 @@ static void vfio_devices_dma_logging_stop(VFIOContainerBase *bcontainer) VFIO_DEVICE_FEATURE_DMA_LOGGING_STOP; QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { + int ret; + if (!vbasedev->dirty_tracking) { continue; } - if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) { + ret = vbasedev->io_ops->device_feature(vbasedev, feature); + + if (ret != 0) { warn_report("%s: Failed to stop DMA logging, err %d (%s)", - vbasedev->name, -errno, strerror(errno)); + vbasedev->name, -ret, strerror(-ret)); } vbasedev->dirty_tracking = false; } @@ -1052,10 +975,9 @@ static bool vfio_devices_dma_logging_start(VFIOContainerBase *bcontainer, continue; } - ret = ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature); + ret = vbasedev->io_ops->device_feature(vbasedev, feature); if (ret) { - ret = -errno; - error_setg_errno(errp, errno, "%s: Failed to start DMA logging", + error_setg_errno(errp, -ret, "%s: Failed to start DMA logging", vbasedev->name); goto out; } @@ -1080,7 +1002,7 @@ static bool vfio_listener_log_global_start(MemoryListener *listener, listener); bool ret; - if (vfio_devices_all_device_dirty_tracking(bcontainer)) { + if (vfio_container_devices_dirty_tracking_is_supported(bcontainer)) { ret = vfio_devices_dma_logging_start(bcontainer, errp); } else { ret = vfio_container_set_dirty_page_tracking(bcontainer, true, errp) == 0; @@ -1099,7 +1021,7 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) Error *local_err = NULL; int ret = 0; - if (vfio_devices_all_device_dirty_tracking(bcontainer)) { + if (vfio_container_devices_dirty_tracking_is_supported(bcontainer)) { vfio_devices_dma_logging_stop(bcontainer); } else { ret = vfio_container_set_dirty_page_tracking(bcontainer, false, @@ -1109,102 +1031,12 @@ static void vfio_listener_log_global_stop(MemoryListener *listener) if (ret) { error_prepend(&local_err, "vfio: Could not stop dirty page tracking - "); - error_report_err(local_err); - vfio_set_migration_error(ret); - } -} - -static int vfio_device_dma_logging_report(VFIODevice *vbasedev, hwaddr iova, - hwaddr size, void *bitmap) -{ - uint64_t buf[DIV_ROUND_UP(sizeof(struct vfio_device_feature) + - sizeof(struct vfio_device_feature_dma_logging_report), - sizeof(uint64_t))] = {}; - struct vfio_device_feature *feature = (struct vfio_device_feature *)buf; - struct vfio_device_feature_dma_logging_report *report = - (struct vfio_device_feature_dma_logging_report *)feature->data; - - report->iova = iova; - report->length = size; - report->page_size = qemu_real_host_page_size(); - report->bitmap = (uintptr_t)bitmap; - - feature->argsz = sizeof(buf); - feature->flags = VFIO_DEVICE_FEATURE_GET | - VFIO_DEVICE_FEATURE_DMA_LOGGING_REPORT; - - if (ioctl(vbasedev->fd, VFIO_DEVICE_FEATURE, feature)) { - return -errno; - } - - return 0; -} - -int vfio_devices_query_dirty_bitmap(const VFIOContainerBase *bcontainer, - VFIOBitmap *vbmap, hwaddr iova, hwaddr size, Error **errp) -{ - VFIODevice *vbasedev; - int ret; - - QLIST_FOREACH(vbasedev, &bcontainer->device_list, container_next) { - ret = vfio_device_dma_logging_report(vbasedev, iova, size, - vbmap->bitmap); - if (ret) { - error_setg_errno(errp, -ret, - "%s: Failed to get DMA logging report, iova: " - "0x%" HWADDR_PRIx ", size: 0x%" HWADDR_PRIx, - vbasedev->name, iova, size); - - return ret; + if (migration_is_running()) { + migration_file_set_error(ret, local_err); + } else { + error_report_err(local_err); } } - - return 0; -} - -int vfio_get_dirty_bitmap(const VFIOContainerBase *bcontainer, uint64_t iova, - uint64_t size, ram_addr_t ram_addr, Error **errp) -{ - bool all_device_dirty_tracking = - vfio_devices_all_device_dirty_tracking(bcontainer); - uint64_t dirty_pages; - VFIOBitmap vbmap; - int ret; - - if (!bcontainer->dirty_pages_supported && !all_device_dirty_tracking) { - cpu_physical_memory_set_dirty_range(ram_addr, size, - tcg_enabled() ? DIRTY_CLIENTS_ALL : - DIRTY_CLIENTS_NOCODE); - return 0; - } - - ret = vfio_bitmap_alloc(&vbmap, size); - if (ret) { - error_setg_errno(errp, -ret, - "Failed to allocate dirty tracking bitmap"); - return ret; - } - - if (all_device_dirty_tracking) { - ret = vfio_devices_query_dirty_bitmap(bcontainer, &vbmap, iova, size, - errp); - } else { - ret = vfio_container_query_dirty_bitmap(bcontainer, &vbmap, iova, size, - errp); - } - - if (ret) { - goto out; - } - - dirty_pages = cpu_physical_memory_set_dirty_lebitmap(vbmap.bitmap, ram_addr, - vbmap.pages); - - trace_vfio_get_dirty_bitmap(iova, size, vbmap.size, ram_addr, dirty_pages); -out: - g_free(vbmap.bitmap); - - return ret; } typedef struct { @@ -1222,29 +1054,32 @@ static void vfio_iommu_map_dirty_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) ram_addr_t translated_addr; Error *local_err = NULL; int ret = -EINVAL; + MemoryRegion *mr; + hwaddr xlat; trace_vfio_iommu_map_dirty_notify(iova, iova + iotlb->addr_mask); if (iotlb->target_as != &address_space_memory) { - error_report("Wrong target AS \"%s\", only system memory is allowed", - iotlb->target_as->name ? iotlb->target_as->name : "none"); + error_setg(&local_err, + "Wrong target AS \"%s\", only system memory is allowed", + iotlb->target_as->name ? iotlb->target_as->name : "none"); goto out; } rcu_read_lock(); - if (!vfio_get_xlat_addr(iotlb, NULL, &translated_addr, NULL, &local_err)) { - error_report_err(local_err); + mr = vfio_translate_iotlb(iotlb, &xlat, &local_err); + if (!mr) { goto out_unlock; } + translated_addr = memory_region_get_ram_addr(mr) + xlat; - ret = vfio_get_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1, + ret = vfio_container_query_dirty_bitmap(bcontainer, iova, iotlb->addr_mask + 1, translated_addr, &local_err); if (ret) { error_prepend(&local_err, "vfio_iommu_map_dirty_notify(%p, 0x%"HWADDR_PRIx", " "0x%"HWADDR_PRIx") failed - ", bcontainer, iova, iotlb->addr_mask + 1); - error_report_err(local_err); } out_unlock: @@ -1252,11 +1087,15 @@ out_unlock: out: if (ret) { - vfio_set_migration_error(ret); + if (migration_is_running()) { + migration_file_set_error(ret, local_err); + } else { + error_report_err(local_err); + } } } -static int vfio_ram_discard_get_dirty_bitmap(MemoryRegionSection *section, +static int vfio_ram_discard_query_dirty_bitmap(MemoryRegionSection *section, void *opaque) { const hwaddr size = int128_get64(section->size); @@ -1271,7 +1110,7 @@ static int vfio_ram_discard_get_dirty_bitmap(MemoryRegionSection *section, * Sync the whole mapped region (spanning multiple individual mappings) * in one go. */ - ret = vfio_get_dirty_bitmap(vrdl->bcontainer, iova, size, ram_addr, + ret = vfio_container_query_dirty_bitmap(vrdl->bcontainer, iova, size, ram_addr, &local_err); if (ret) { error_report_err(local_err); @@ -1284,26 +1123,15 @@ vfio_sync_ram_discard_listener_dirty_bitmap(VFIOContainerBase *bcontainer, MemoryRegionSection *section) { RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr); - VFIORamDiscardListener *vrdl = NULL; - - QLIST_FOREACH(vrdl, &bcontainer->vrdl_list, next) { - if (vrdl->mr == section->mr && - vrdl->offset_within_address_space == - section->offset_within_address_space) { - break; - } - } - - if (!vrdl) { - hw_error("vfio: Trying to sync missing RAM discard listener"); - } + VFIORamDiscardListener *vrdl = + vfio_find_ram_discard_listener(bcontainer, section); /* * We only want/can synchronize the bitmap for actually mapped parts - * which correspond to populated parts. Replay all populated parts. */ return ram_discard_manager_replay_populated(rdm, section, - vfio_ram_discard_get_dirty_bitmap, + vfio_ram_discard_query_dirty_bitmap, &vrdl); } @@ -1365,7 +1193,7 @@ static int vfio_sync_dirty_bitmap(VFIOContainerBase *bcontainer, ram_addr = memory_region_get_ram_addr(section->mr) + section->offset_within_region; - return vfio_get_dirty_bitmap(bcontainer, + return vfio_container_query_dirty_bitmap(bcontainer, REAL_HOST_PAGE_ALIGN(section->offset_within_address_space), int128_get64(section->size), ram_addr, errp); } @@ -1385,14 +1213,19 @@ static void vfio_listener_log_sync(MemoryListener *listener, if (vfio_log_sync_needed(bcontainer)) { ret = vfio_sync_dirty_bitmap(bcontainer, section, &local_err); if (ret) { - error_report_err(local_err); - vfio_set_migration_error(ret); + if (migration_is_running()) { + migration_file_set_error(ret, local_err); + } else { + error_report_err(local_err); + } } } } -const MemoryListener vfio_memory_listener = { +static const MemoryListener vfio_memory_listener = { .name = "vfio", + .begin = vfio_listener_begin, + .commit = vfio_listener_commit, .region_add = vfio_listener_region_add, .region_del = vfio_listener_region_del, .log_global_start = vfio_listener_log_global_start, @@ -1400,184 +1233,21 @@ const MemoryListener vfio_memory_listener = { .log_sync = vfio_listener_log_sync, }; -void vfio_reset_handler(void *opaque) +bool vfio_listener_register(VFIOContainerBase *bcontainer, Error **errp) { - VFIODevice *vbasedev; + bcontainer->listener = vfio_memory_listener; + memory_listener_register(&bcontainer->listener, bcontainer->space->as); - trace_vfio_reset_handler(); - QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->dev->realized) { - vbasedev->ops->vfio_compute_needs_reset(vbasedev); - } - } - - QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { - if (vbasedev->dev->realized && vbasedev->needs_reset) { - vbasedev->ops->vfio_hot_reset_multi(vbasedev); - } - } -} - -int vfio_kvm_device_add_fd(int fd, Error **errp) -{ -#ifdef CONFIG_KVM - struct kvm_device_attr attr = { - .group = KVM_DEV_VFIO_FILE, - .attr = KVM_DEV_VFIO_FILE_ADD, - .addr = (uint64_t)(unsigned long)&fd, - }; - - if (!kvm_enabled()) { - return 0; - } - - if (vfio_kvm_device_fd < 0) { - struct kvm_create_device cd = { - .type = KVM_DEV_TYPE_VFIO, - }; - - if (kvm_vm_ioctl(kvm_state, KVM_CREATE_DEVICE, &cd)) { - error_setg_errno(errp, errno, "Failed to create KVM VFIO device"); - return -errno; - } - - vfio_kvm_device_fd = cd.fd; - } - - if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) { - error_setg_errno(errp, errno, "Failed to add fd %d to KVM VFIO device", - fd); - return -errno; - } -#endif - return 0; -} - -int vfio_kvm_device_del_fd(int fd, Error **errp) -{ -#ifdef CONFIG_KVM - struct kvm_device_attr attr = { - .group = KVM_DEV_VFIO_FILE, - .attr = KVM_DEV_VFIO_FILE_DEL, - .addr = (uint64_t)(unsigned long)&fd, - }; - - if (vfio_kvm_device_fd < 0) { - error_setg(errp, "KVM VFIO device isn't created yet"); - return -EINVAL; - } - - if (ioctl(vfio_kvm_device_fd, KVM_SET_DEVICE_ATTR, &attr)) { - error_setg_errno(errp, errno, - "Failed to remove fd %d from KVM VFIO device", fd); - return -errno; - } -#endif - return 0; -} - -VFIOAddressSpace *vfio_get_address_space(AddressSpace *as) -{ - VFIOAddressSpace *space; - - QLIST_FOREACH(space, &vfio_address_spaces, list) { - if (space->as == as) { - return space; - } - } - - /* No suitable VFIOAddressSpace, create a new one */ - space = g_malloc0(sizeof(*space)); - space->as = as; - QLIST_INIT(&space->containers); - - if (QLIST_EMPTY(&vfio_address_spaces)) { - qemu_register_reset(vfio_reset_handler, NULL); - } - - QLIST_INSERT_HEAD(&vfio_address_spaces, space, list); - - return space; -} - -void vfio_put_address_space(VFIOAddressSpace *space) -{ - if (!QLIST_EMPTY(&space->containers)) { - return; - } - - QLIST_REMOVE(space, list); - g_free(space); - - if (QLIST_EMPTY(&vfio_address_spaces)) { - qemu_unregister_reset(vfio_reset_handler, NULL); - } -} - -void vfio_address_space_insert(VFIOAddressSpace *space, - VFIOContainerBase *bcontainer) -{ - QLIST_INSERT_HEAD(&space->containers, bcontainer, next); - bcontainer->space = space; -} - -struct vfio_device_info *vfio_get_device_info(int fd) -{ - struct vfio_device_info *info; - uint32_t argsz = sizeof(*info); - - info = g_malloc0(argsz); - -retry: - info->argsz = argsz; - - if (ioctl(fd, VFIO_DEVICE_GET_INFO, info)) { - g_free(info); - return NULL; - } - - if (info->argsz > argsz) { - argsz = info->argsz; - info = g_realloc(info, argsz); - goto retry; - } - - return info; -} - -bool vfio_attach_device(char *name, VFIODevice *vbasedev, - AddressSpace *as, Error **errp) -{ - const VFIOIOMMUClass *ops = - VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_LEGACY)); - HostIOMMUDevice *hiod = NULL; - - if (vbasedev->iommufd) { - ops = VFIO_IOMMU_CLASS(object_class_by_name(TYPE_VFIO_IOMMU_IOMMUFD)); - } - - assert(ops); - - - if (!vbasedev->mdev) { - hiod = HOST_IOMMU_DEVICE(object_new(ops->hiod_typename)); - vbasedev->hiod = hiod; - } - - if (!ops->attach_device(name, vbasedev, as, errp)) { - object_unref(hiod); - vbasedev->hiod = NULL; + if (bcontainer->error) { + error_propagate_prepend(errp, bcontainer->error, + "memory listener initialization failed: "); return false; } return true; } -void vfio_detach_device(VFIODevice *vbasedev) +void vfio_listener_unregister(VFIOContainerBase *bcontainer) { - if (!vbasedev->bcontainer) { - return; - } - object_unref(vbasedev->hiod); - VFIO_IOMMU_GET_CLASS(vbasedev->bcontainer)->detach_device(vbasedev); + memory_listener_unregister(&bcontainer->listener); } diff --git a/hw/vfio/meson.build b/hw/vfio/meson.build index a8939c8..63ea393 100644 --- a/hw/vfio/meson.build +++ b/hw/vfio/meson.build @@ -1,7 +1,11 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + vfio_ss = ss.source_set() vfio_ss.add(files( - 'common.c', + 'listener.c', + 'container-base.c', 'container.c', + 'helpers.c', )) vfio_ss.add(when: 'CONFIG_PSERIES', if_true: files('spapr.c')) vfio_ss.add(when: 'CONFIG_VFIO_PCI', if_true: files( @@ -18,11 +22,12 @@ specific_ss.add_all(when: 'CONFIG_VFIO', if_true: vfio_ss) system_ss.add(when: 'CONFIG_VFIO_XGMAC', if_true: files('calxeda-xgmac.c')) system_ss.add(when: 'CONFIG_VFIO_AMD_XGBE', if_true: files('amd-xgbe.c')) system_ss.add(when: 'CONFIG_VFIO', if_true: files( - 'helpers.c', - 'container-base.c', + 'cpr.c', + 'cpr-legacy.c', + 'device.c', 'migration.c', 'migration-multifd.c', - 'cpr.c', + 'region.c', )) system_ss.add(when: ['CONFIG_VFIO', 'CONFIG_IOMMUFD'], if_true: files( 'iommufd.c', diff --git a/hw/vfio/migration-multifd.c b/hw/vfio/migration-multifd.c index 378f6f3..850a319 100644 --- a/hw/vfio/migration-multifd.c +++ b/hw/vfio/migration-multifd.c @@ -10,7 +10,7 @@ */ #include "qemu/osdep.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" #include "migration/misc.h" #include "qapi/error.h" #include "qemu/bswap.h" @@ -21,6 +21,7 @@ #include "io/channel-buffer.h" #include "migration/qemu-file.h" #include "migration-multifd.h" +#include "vfio-migration-internal.h" #include "trace.h" #define VFIO_DEVICE_STATE_CONFIG_STATE (1) @@ -575,7 +576,7 @@ vfio_save_complete_precopy_thread_config_state(VFIODevice *vbasedev, return false; } - vfio_mig_add_bytes_transferred(packet_len); + vfio_migration_add_bytes_transferred(packet_len); return true; } @@ -645,7 +646,7 @@ vfio_multifd_save_complete_precopy_thread(SaveLiveCompletePrecopyThreadData *d, goto thread_exit; } - vfio_mig_add_bytes_transferred(packet_size); + vfio_migration_add_bytes_transferred(packet_size); } if (!vfio_save_complete_precopy_thread_config_state(vbasedev, diff --git a/hw/vfio/migration-multifd.h b/hw/vfio/migration-multifd.h index a664051..0bab632 100644 --- a/hw/vfio/migration-multifd.h +++ b/hw/vfio/migration-multifd.h @@ -12,7 +12,7 @@ #ifndef HW_VFIO_MIGRATION_MULTIFD_H #define HW_VFIO_MIGRATION_MULTIFD_H -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" bool vfio_multifd_setup(VFIODevice *vbasedev, bool alloc_multifd, Error **errp); void vfio_multifd_cleanup(VFIODevice *vbasedev); diff --git a/hw/vfio/migration.c b/hw/vfio/migration.c index fbff46c..b76697bd 100644 --- a/hw/vfio/migration.c +++ b/hw/vfio/migration.c @@ -16,7 +16,8 @@ #include <sys/ioctl.h> #include "system/runstate.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" +#include "hw/vfio/vfio-migration.h" #include "migration/misc.h" #include "migration/savevm.h" #include "migration/vmstate.h" @@ -30,6 +31,7 @@ #include "pci.h" #include "trace.h" #include "hw/hw.h" +#include "vfio-migration-internal.h" /* * This is an arbitrary size based on migration of mlx5 devices, where typically @@ -373,7 +375,7 @@ static ssize_t vfio_save_block(QEMUFile *f, VFIOMigration *migration) qemu_put_be64(f, VFIO_MIG_FLAG_DEV_DATA_STATE); qemu_put_be64(f, data_size); qemu_put_buffer(f, migration->data_buffer, data_size); - vfio_mig_add_bytes_transferred(data_size); + vfio_migration_add_bytes_transferred(data_size); trace_vfio_save_block(migration->vbasedev->name, data_size); @@ -1014,13 +1016,72 @@ static int vfio_migration_init(VFIODevice *vbasedev) vfio_vmstate_change_prepare : NULL; migration->vm_state = qdev_add_vm_change_state_handler_full( - vbasedev->dev, vfio_vmstate_change, prepare_cb, vbasedev); + vbasedev->dev, vfio_vmstate_change, prepare_cb, NULL, vbasedev); migration_add_notifier(&migration->migration_state, vfio_migration_state_notifier); return 0; } +static Error *multiple_devices_migration_blocker; + +/* + * Multiple devices migration is allowed only if all devices support P2P + * migration. Single device migration is allowed regardless of P2P migration + * support. + */ +static bool vfio_multiple_devices_migration_is_supported(void) +{ + VFIODevice *vbasedev; + unsigned int device_num = 0; + bool all_support_p2p = true; + + QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { + if (vbasedev->migration) { + device_num++; + + if (!(vbasedev->migration->mig_flags & VFIO_MIGRATION_P2P)) { + all_support_p2p = false; + } + } + } + + return all_support_p2p || device_num <= 1; +} + +static int vfio_block_multiple_devices_migration(VFIODevice *vbasedev, Error **errp) +{ + if (vfio_multiple_devices_migration_is_supported()) { + return 0; + } + + if (vbasedev->enable_migration == ON_OFF_AUTO_ON) { + error_setg(errp, "Multiple VFIO devices migration is supported only if " + "all of them support P2P migration"); + return -EINVAL; + } + + if (multiple_devices_migration_blocker) { + return 0; + } + + error_setg(&multiple_devices_migration_blocker, + "Multiple VFIO devices migration is supported only if all of " + "them support P2P migration"); + return migrate_add_blocker_normal(&multiple_devices_migration_blocker, + errp); +} + +static void vfio_unblock_multiple_devices_migration(void) +{ + if (!multiple_devices_migration_blocker || + !vfio_multiple_devices_migration_is_supported()) { + return; + } + + migrate_del_blocker(&multiple_devices_migration_blocker); +} + static void vfio_migration_deinit(VFIODevice *vbasedev) { VFIOMigration *migration = vbasedev->migration; @@ -1047,21 +1108,42 @@ static int vfio_block_migration(VFIODevice *vbasedev, Error *err, Error **errp) /* ---------------------------------------------------------------------- */ -int64_t vfio_mig_bytes_transferred(void) +int64_t vfio_migration_bytes_transferred(void) { return MIN(qatomic_read(&bytes_transferred), INT64_MAX); } -void vfio_reset_bytes_transferred(void) +void vfio_migration_reset_bytes_transferred(void) { qatomic_set(&bytes_transferred, 0); } -void vfio_mig_add_bytes_transferred(unsigned long val) +void vfio_migration_add_bytes_transferred(unsigned long val) { qatomic_add(&bytes_transferred, val); } +bool vfio_migration_active(void) +{ + VFIODevice *vbasedev; + + if (QLIST_EMPTY(&vfio_device_list)) { + return false; + } + + QLIST_FOREACH(vbasedev, &vfio_device_list, global_next) { + if (vbasedev->migration_blocker) { + return false; + } + } + return true; +} + +static bool vfio_viommu_preset(VFIODevice *vbasedev) +{ + return vbasedev->bcontainer->space->as != &address_space_memory; +} + /* * Return true when either migration initialized or blocker registered. * Currently only return false when adding blocker fails which will @@ -1138,3 +1220,19 @@ void vfio_migration_exit(VFIODevice *vbasedev) migrate_del_blocker(&vbasedev->migration_blocker); } + +bool vfio_device_state_is_running(VFIODevice *vbasedev) +{ + VFIOMigration *migration = vbasedev->migration; + + return migration->device_state == VFIO_DEVICE_STATE_RUNNING || + migration->device_state == VFIO_DEVICE_STATE_RUNNING_P2P; +} + +bool vfio_device_state_is_precopy(VFIODevice *vbasedev) +{ + VFIOMigration *migration = vbasedev->migration; + + return migration->device_state == VFIO_DEVICE_STATE_PRE_COPY || + migration->device_state == VFIO_DEVICE_STATE_PRE_COPY_P2P; +} diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index f87f3cc..fa25bde 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -30,6 +30,7 @@ #include "hw/qdev-properties.h" #include "hw/qdev-properties-system.h" #include "migration/vmstate.h" +#include "migration/cpr.h" #include "qobject/qdict.h" #include "qemu/error-report.h" #include "qemu/main-loop.h" @@ -44,6 +45,8 @@ #include "migration/blocker.h" #include "migration/qemu-file.h" #include "system/iommufd.h" +#include "vfio-migration-internal.h" +#include "vfio-helpers.h" #define TYPE_VFIO_PCI_NOHOTPLUG "vfio-pci-nohotplug" @@ -54,6 +57,23 @@ static void vfio_disable_interrupts(VFIOPCIDevice *vdev); static void vfio_mmap_set_enabled(VFIOPCIDevice *vdev, bool enabled); static void vfio_msi_disable_common(VFIOPCIDevice *vdev); +static bool vfio_notifier_init(VFIOPCIDevice *vdev, EventNotifier *e, + const char *name, int nr, Error **errp) +{ + int ret = event_notifier_init(e, 0); + + if (ret) { + error_setg_errno(errp, -ret, "vfio_notifier_init %s failed", name); + } + return !ret; +} + +static void vfio_notifier_cleanup(VFIOPCIDevice *vdev, EventNotifier *e, + const char *name, int nr) +{ + event_notifier_cleanup(e); +} + /* * Disabling BAR mmaping can be slow, but toggling it around INTx can * also be a huge overhead. We try to get the best of both worlds by @@ -101,7 +121,7 @@ static void vfio_intx_interrupt(void *opaque) } } -static void vfio_intx_eoi(VFIODevice *vbasedev) +void vfio_pci_intx_eoi(VFIODevice *vbasedev) { VFIOPCIDevice *vdev = container_of(vbasedev, VFIOPCIDevice, vbasedev); @@ -109,11 +129,11 @@ static void vfio_intx_eoi(VFIODevice *vbasedev) return; } - trace_vfio_intx_eoi(vbasedev->name); + trace_vfio_pci_intx_eoi(vbasedev->name); vdev->intx.pending = false; pci_irq_deassert(&vdev->pdev); - vfio_unmask_single_irqindex(vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_unmask(vbasedev, VFIO_PCI_INTX_IRQ_INDEX); } static bool vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp) @@ -129,13 +149,12 @@ static bool vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp) /* Get to a known interrupt state */ qemu_set_fd_handler(irq_fd, NULL, NULL, vdev); - vfio_mask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_mask(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); vdev->intx.pending = false; pci_irq_deassert(&vdev->pdev); /* Get an eventfd for resample/unmask */ - if (event_notifier_init(&vdev->intx.unmask, 0)) { - error_setg(errp, "event_notifier_init failed eoi"); + if (!vfio_notifier_init(vdev, &vdev->intx.unmask, "intx-unmask", 0, errp)) { goto fail; } @@ -147,15 +166,15 @@ static bool vfio_intx_enable_kvm(VFIOPCIDevice *vdev, Error **errp) goto fail_irqfd; } - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX, 0, - VFIO_IRQ_SET_ACTION_UNMASK, - event_notifier_get_fd(&vdev->intx.unmask), - errp)) { + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX, 0, + VFIO_IRQ_SET_ACTION_UNMASK, + event_notifier_get_fd(&vdev->intx.unmask), + errp)) { goto fail_vfio; } /* Let'em rip */ - vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_unmask(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); vdev->intx.kvm_accel = true; @@ -167,10 +186,10 @@ fail_vfio: kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &vdev->intx.interrupt, vdev->intx.route.irq); fail_irqfd: - event_notifier_cleanup(&vdev->intx.unmask); + vfio_notifier_cleanup(vdev, &vdev->intx.unmask, "intx-unmask", 0); fail: qemu_set_fd_handler(irq_fd, vfio_intx_interrupt, NULL, vdev); - vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_unmask(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); return false; #else return true; @@ -188,7 +207,7 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev) * Get to a known state, hardware masked, QEMU ready to accept new * interrupts, QEMU IRQ de-asserted. */ - vfio_mask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_mask(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); vdev->intx.pending = false; pci_irq_deassert(&vdev->pdev); @@ -199,7 +218,7 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev) } /* We only need to close the eventfd for VFIO to cleanup the kernel side */ - event_notifier_cleanup(&vdev->intx.unmask); + vfio_notifier_cleanup(vdev, &vdev->intx.unmask, "intx-unmask", 0); /* QEMU starts listening for interrupt events. */ qemu_set_fd_handler(event_notifier_get_fd(&vdev->intx.interrupt), @@ -208,7 +227,7 @@ static void vfio_intx_disable_kvm(VFIOPCIDevice *vdev) vdev->intx.kvm_accel = false; /* If we've missed an event, let it re-fire through QEMU */ - vfio_unmask_single_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_unmask(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); trace_vfio_intx_disable_kvm(vdev->vbasedev.name); #endif @@ -234,12 +253,12 @@ static void vfio_intx_update(VFIOPCIDevice *vdev, PCIINTxRoute *route) } /* Re-enable the interrupt in cased we missed an EOI */ - vfio_intx_eoi(&vdev->vbasedev); + vfio_pci_intx_eoi(&vdev->vbasedev); } static void vfio_intx_routing_notifier(PCIDevice *pdev) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); PCIINTxRoute route; if (vdev->interrupt != VFIO_INT_INTx) { @@ -266,7 +285,6 @@ static bool vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp) uint8_t pin = vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1); Error *err = NULL; int32_t fd; - int ret; if (!pin) { @@ -289,18 +307,17 @@ static bool vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp) } #endif - ret = event_notifier_init(&vdev->intx.interrupt, 0); - if (ret) { - error_setg_errno(errp, -ret, "event_notifier_init failed"); + if (!vfio_notifier_init(vdev, &vdev->intx.interrupt, "intx-interrupt", 0, + errp)) { return false; } fd = event_notifier_get_fd(&vdev->intx.interrupt); qemu_set_fd_handler(fd, vfio_intx_interrupt, NULL, vdev); - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX, 0, + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX, 0, VFIO_IRQ_SET_ACTION_TRIGGER, fd, errp)) { qemu_set_fd_handler(fd, NULL, NULL, vdev); - event_notifier_cleanup(&vdev->intx.interrupt); + vfio_notifier_cleanup(vdev, &vdev->intx.interrupt, "intx-interrupt", 0); return false; } @@ -320,20 +337,25 @@ static void vfio_intx_disable(VFIOPCIDevice *vdev) timer_del(vdev->intx.mmap_timer); vfio_intx_disable_kvm(vdev); - vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); + vfio_device_irq_disable(&vdev->vbasedev, VFIO_PCI_INTX_IRQ_INDEX); vdev->intx.pending = false; pci_irq_deassert(&vdev->pdev); vfio_mmap_set_enabled(vdev, true); fd = event_notifier_get_fd(&vdev->intx.interrupt); qemu_set_fd_handler(fd, NULL, NULL, vdev); - event_notifier_cleanup(&vdev->intx.interrupt); + vfio_notifier_cleanup(vdev, &vdev->intx.interrupt, "intx-interrupt", 0); vdev->interrupt = VFIO_INT_NONE; trace_vfio_intx_disable(vdev->vbasedev.name); } +bool vfio_pci_intx_enable(VFIOPCIDevice *vdev, Error **errp) +{ + return vfio_intx_enable(vdev, errp); +} + /* * MSI/X */ @@ -379,7 +401,7 @@ static void vfio_msi_interrupt(void *opaque) static int vfio_enable_msix_no_vec(VFIOPCIDevice *vdev) { g_autofree struct vfio_irq_set *irq_set = NULL; - int ret = 0, argsz; + int argsz; int32_t *fd; argsz = sizeof(*irq_set) + sizeof(*fd); @@ -394,9 +416,7 @@ static int vfio_enable_msix_no_vec(VFIOPCIDevice *vdev) fd = (int32_t *)&irq_set->data; *fd = -1; - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set); - - return ret; + return vdev->vbasedev.io_ops->set_irqs(&vdev->vbasedev, irq_set); } static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) @@ -453,15 +473,15 @@ static int vfio_enable_vectors(VFIOPCIDevice *vdev, bool msix) fds[i] = fd; } - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_SET_IRQS, irq_set); + ret = vdev->vbasedev.io_ops->set_irqs(&vdev->vbasedev, irq_set); g_free(irq_set); return ret; } -static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, - int vector_n, bool msix) +void vfio_pci_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, + int vector_n, bool msix) { if ((msix && vdev->no_kvm_msix) || (!msix && vdev->no_kvm_msi)) { return; @@ -471,13 +491,16 @@ static void vfio_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, vector_n, &vdev->pdev); } -static void vfio_connect_kvm_msi_virq(VFIOMSIVector *vector) +static void vfio_connect_kvm_msi_virq(VFIOMSIVector *vector, int nr) { + const char *name = "kvm_interrupt"; + if (vector->virq < 0) { return; } - if (event_notifier_init(&vector->kvm_interrupt, 0)) { + if (!vfio_notifier_init(vector->vdev, &vector->kvm_interrupt, name, nr, + NULL)) { goto fail_notifier; } @@ -489,19 +512,20 @@ static void vfio_connect_kvm_msi_virq(VFIOMSIVector *vector) return; fail_kvm: - event_notifier_cleanup(&vector->kvm_interrupt); + vfio_notifier_cleanup(vector->vdev, &vector->kvm_interrupt, name, nr); fail_notifier: kvm_irqchip_release_virq(kvm_state, vector->virq); vector->virq = -1; } -static void vfio_remove_kvm_msi_virq(VFIOMSIVector *vector) +static void vfio_remove_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, + int nr) { kvm_irqchip_remove_irqfd_notifier_gsi(kvm_state, &vector->kvm_interrupt, vector->virq); kvm_irqchip_release_virq(kvm_state, vector->virq); vector->virq = -1; - event_notifier_cleanup(&vector->kvm_interrupt); + vfio_notifier_cleanup(vdev, &vector->kvm_interrupt, "kvm_interrupt", nr); } static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg, @@ -511,10 +535,47 @@ static void vfio_update_kvm_msi_virq(VFIOMSIVector *vector, MSIMessage msg, kvm_irqchip_commit_routes(kvm_state); } +static void set_irq_signalling(VFIODevice *vbasedev, VFIOMSIVector *vector, + unsigned int nr) +{ + Error *err = NULL; + int32_t fd; + + if (vector->virq >= 0) { + fd = event_notifier_get_fd(&vector->kvm_interrupt); + } else { + fd = event_notifier_get_fd(&vector->interrupt); + } + + if (!vfio_device_irq_set_signaling(vbasedev, VFIO_PCI_MSIX_IRQ_INDEX, nr, + VFIO_IRQ_SET_ACTION_TRIGGER, + fd, &err)) { + error_reportf_err(err, VFIO_MSG_PREFIX, vbasedev->name); + } +} + +void vfio_pci_vector_init(VFIOPCIDevice *vdev, int nr) +{ + VFIOMSIVector *vector = &vdev->msi_vectors[nr]; + PCIDevice *pdev = &vdev->pdev; + Error *local_err = NULL; + + vector->vdev = vdev; + vector->virq = -1; + if (!vfio_notifier_init(vdev, &vector->interrupt, "interrupt", nr, + &local_err)) { + error_report_err(local_err); + } + vector->use = true; + if (vdev->interrupt == VFIO_INT_MSIX) { + msix_vector_use(pdev, nr); + } +} + static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, MSIMessage *msg, IOHandler *handler) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); VFIOMSIVector *vector; int ret; bool resizing = !!(vdev->nr_vectors < nr + 1); @@ -524,13 +585,7 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, vector = &vdev->msi_vectors[nr]; if (!vector->use) { - vector->vdev = vdev; - vector->virq = -1; - if (event_notifier_init(&vector->interrupt, 0)) { - error_report("vfio: Error: event_notifier_init failed"); - } - vector->use = true; - msix_vector_use(pdev, nr); + vfio_pci_vector_init(vdev, nr); } qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), @@ -542,19 +597,19 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, */ if (vector->virq >= 0) { if (!msg) { - vfio_remove_kvm_msi_virq(vector); + vfio_remove_kvm_msi_virq(vdev, vector, nr); } else { vfio_update_kvm_msi_virq(vector, *msg, pdev); } } else { if (msg) { if (vdev->defer_kvm_irq_routing) { - vfio_add_kvm_msi_virq(vdev, vector, nr, true); + vfio_pci_add_kvm_msi_virq(vdev, vector, nr, true); } else { vfio_route_change = kvm_irqchip_begin_route_changes(kvm_state); - vfio_add_kvm_msi_virq(vdev, vector, nr, true); + vfio_pci_add_kvm_msi_virq(vdev, vector, nr, true); kvm_irqchip_commit_route_changes(&vfio_route_change); - vfio_connect_kvm_msi_virq(vector); + vfio_connect_kvm_msi_virq(vector, nr); } } } @@ -576,27 +631,14 @@ static int vfio_msix_vector_do_use(PCIDevice *pdev, unsigned int nr, if (!vdev->defer_kvm_irq_routing) { if (vdev->msix->noresize && resizing) { - vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); + vfio_device_irq_disable(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); ret = vfio_enable_vectors(vdev, true); if (ret) { - error_report("vfio: failed to enable vectors, %d", ret); + error_report("vfio: failed to enable vectors, %s", + strerror(-ret)); } } else { - Error *err = NULL; - int32_t fd; - - if (vector->virq >= 0) { - fd = event_notifier_get_fd(&vector->kvm_interrupt); - } else { - fd = event_notifier_get_fd(&vector->interrupt); - } - - if (!vfio_set_irq_signaling(&vdev->vbasedev, - VFIO_PCI_MSIX_IRQ_INDEX, nr, - VFIO_IRQ_SET_ACTION_TRIGGER, fd, - &err)) { - error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); - } + set_irq_signalling(&vdev->vbasedev, vector, nr); } } @@ -619,7 +661,7 @@ static int vfio_msix_vector_use(PCIDevice *pdev, static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); VFIOMSIVector *vector = &vdev->msi_vectors[nr]; trace_vfio_msix_vector_release(vdev->vbasedev.name, nr); @@ -636,7 +678,7 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr) int32_t fd = event_notifier_get_fd(&vector->interrupt); Error *err = NULL; - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX, + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX, nr, VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); @@ -644,14 +686,14 @@ static void vfio_msix_vector_release(PCIDevice *pdev, unsigned int nr) } } -static void vfio_prepare_kvm_msi_virq_batch(VFIOPCIDevice *vdev) +void vfio_pci_prepare_kvm_msi_virq_batch(VFIOPCIDevice *vdev) { assert(!vdev->defer_kvm_irq_routing); vdev->defer_kvm_irq_routing = true; vfio_route_change = kvm_irqchip_begin_route_changes(kvm_state); } -static void vfio_commit_kvm_msi_virq_batch(VFIOPCIDevice *vdev) +void vfio_pci_commit_kvm_msi_virq_batch(VFIOPCIDevice *vdev) { int i; @@ -661,7 +703,7 @@ static void vfio_commit_kvm_msi_virq_batch(VFIOPCIDevice *vdev) kvm_irqchip_commit_route_changes(&vfio_route_change); for (i = 0; i < vdev->nr_vectors; i++) { - vfio_connect_kvm_msi_virq(&vdev->msi_vectors[i]); + vfio_connect_kvm_msi_virq(&vdev->msi_vectors[i], i); } } @@ -681,19 +723,20 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev) * routes once rather than per vector provides a substantial * performance improvement. */ - vfio_prepare_kvm_msi_virq_batch(vdev); + vfio_pci_prepare_kvm_msi_virq_batch(vdev); if (msix_set_vector_notifiers(&vdev->pdev, vfio_msix_vector_use, vfio_msix_vector_release, NULL)) { error_report("vfio: msix_set_vector_notifiers failed"); } - vfio_commit_kvm_msi_virq_batch(vdev); + vfio_pci_commit_kvm_msi_virq_batch(vdev); if (vdev->nr_vectors) { ret = vfio_enable_vectors(vdev, true); if (ret) { - error_report("vfio: failed to enable vectors, %d", ret); + error_report("vfio: failed to enable vectors, %s", + strerror(-ret)); } } else { /* @@ -710,7 +753,8 @@ static void vfio_msix_enable(VFIOPCIDevice *vdev) */ ret = vfio_enable_msix_no_vec(vdev); if (ret) { - error_report("vfio: failed to enable MSI-X, %d", ret); + error_report("vfio: failed to enable MSI-X, %s", + strerror(-ret)); } } @@ -730,19 +774,21 @@ retry: * Deferring to commit the KVM routes once rather than per vector * provides a substantial performance improvement. */ - vfio_prepare_kvm_msi_virq_batch(vdev); + vfio_pci_prepare_kvm_msi_virq_batch(vdev); vdev->msi_vectors = g_new0(VFIOMSIVector, vdev->nr_vectors); for (i = 0; i < vdev->nr_vectors; i++) { VFIOMSIVector *vector = &vdev->msi_vectors[i]; + Error *local_err = NULL; vector->vdev = vdev; vector->virq = -1; vector->use = true; - if (event_notifier_init(&vector->interrupt, 0)) { - error_report("vfio: Error: event_notifier_init failed"); + if (!vfio_notifier_init(vdev, &vector->interrupt, "interrupt", i, + &local_err)) { + error_report_err(local_err); } qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), @@ -752,10 +798,10 @@ retry: * Attempt to enable route through KVM irqchip, * default to userspace handling if unavailable. */ - vfio_add_kvm_msi_virq(vdev, vector, i, false); + vfio_pci_add_kvm_msi_virq(vdev, vector, i, false); } - vfio_commit_kvm_msi_virq_batch(vdev); + vfio_pci_commit_kvm_msi_virq_batch(vdev); /* Set interrupt type prior to possible interrupts */ vdev->interrupt = VFIO_INT_MSI; @@ -763,7 +809,8 @@ retry: ret = vfio_enable_vectors(vdev, false); if (ret) { if (ret < 0) { - error_report("vfio: Error: Failed to setup MSI fds: %m"); + error_report("vfio: Error: Failed to setup MSI fds: %s", + strerror(-ret)); } else { error_report("vfio: Error: Failed to enable %d " "MSI vectors, retry with %d", vdev->nr_vectors, ret); @@ -797,11 +844,11 @@ static void vfio_msi_disable_common(VFIOPCIDevice *vdev) VFIOMSIVector *vector = &vdev->msi_vectors[i]; if (vdev->msi_vectors[i].use) { if (vector->virq >= 0) { - vfio_remove_kvm_msi_virq(vector); + vfio_remove_kvm_msi_virq(vdev, vector, i); } qemu_set_fd_handler(event_notifier_get_fd(&vector->interrupt), NULL, NULL, NULL); - event_notifier_cleanup(&vector->interrupt); + vfio_notifier_cleanup(vdev, &vector->interrupt, "interrupt", i); } } @@ -833,7 +880,7 @@ static void vfio_msix_disable(VFIOPCIDevice *vdev) * Always clear MSI-X IRQ index. A PF device could have enabled * MSI-X with no vectors. See vfio_msix_enable(). */ - vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); + vfio_device_irq_disable(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX); vfio_msi_disable_common(vdev); if (!vfio_intx_enable(vdev, &err)) { @@ -850,7 +897,7 @@ static void vfio_msi_disable(VFIOPCIDevice *vdev) { Error *err = NULL; - vfio_disable_irqindex(&vdev->vbasedev, VFIO_PCI_MSI_IRQ_INDEX); + vfio_device_irq_disable(&vdev->vbasedev, VFIO_PCI_MSI_IRQ_INDEX); vfio_msi_disable_common(vdev); vfio_intx_enable(vdev, &err); if (err) { @@ -879,18 +926,22 @@ static void vfio_update_msi(VFIOPCIDevice *vdev) static void vfio_pci_load_rom(VFIOPCIDevice *vdev) { - g_autofree struct vfio_region_info *reg_info = NULL; + VFIODevice *vbasedev = &vdev->vbasedev; + struct vfio_region_info *reg_info = NULL; uint64_t size; off_t off = 0; ssize_t bytes; + int ret; - if (vfio_get_region_info(&vdev->vbasedev, - VFIO_PCI_ROM_REGION_INDEX, ®_info)) { - error_report("vfio: Error getting ROM info: %m"); + ret = vfio_device_get_region_info(vbasedev, VFIO_PCI_ROM_REGION_INDEX, + ®_info); + + if (ret != 0) { + error_report("vfio: Error getting ROM info: %s", strerror(-ret)); return; } - trace_vfio_pci_load_rom(vdev->vbasedev.name, (unsigned long)reg_info->size, + trace_vfio_pci_load_rom(vbasedev->name, (unsigned long)reg_info->size, (unsigned long)reg_info->offset, (unsigned long)reg_info->flags); @@ -899,8 +950,7 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev) if (!vdev->rom_size) { vdev->rom_read_failed = true; - error_report("vfio-pci: Cannot read device rom at " - "%s", vdev->vbasedev.name); + error_report("vfio-pci: Cannot read device rom at %s", vbasedev->name); error_printf("Device option ROM contents are probably invalid " "(check dmesg).\nSkip option ROM probe with rombar=0, " "or load from file with romfile=\n"); @@ -911,18 +961,22 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev) memset(vdev->rom, 0xff, size); while (size) { - bytes = pread(vdev->vbasedev.fd, vdev->rom + off, - size, vdev->rom_offset + off); + bytes = vbasedev->io_ops->region_read(vbasedev, + VFIO_PCI_ROM_REGION_INDEX, + off, size, vdev->rom + off); + if (bytes == 0) { break; } else if (bytes > 0) { off += bytes; size -= bytes; } else { - if (errno == EINTR || errno == EAGAIN) { + if (bytes == -EINTR || bytes == -EAGAIN) { continue; } - error_report("vfio: Error reading device ROM: %m"); + error_report("vfio: Error reading device ROM: %s", + strreaderror(bytes)); + break; } } @@ -958,6 +1012,24 @@ static void vfio_pci_load_rom(VFIOPCIDevice *vdev) } } +/* "Raw" read of underlying config space. */ +static int vfio_pci_config_space_read(VFIOPCIDevice *vdev, off_t offset, + uint32_t size, void *data) +{ + return vdev->vbasedev.io_ops->region_read(&vdev->vbasedev, + VFIO_PCI_CONFIG_REGION_INDEX, + offset, size, data); +} + +/* "Raw" write of underlying config space. */ +static int vfio_pci_config_space_write(VFIOPCIDevice *vdev, off_t offset, + uint32_t size, void *data) +{ + return vdev->vbasedev.io_ops->region_write(&vdev->vbasedev, + VFIO_PCI_CONFIG_REGION_INDEX, + offset, size, data, false); +} + static uint64_t vfio_rom_read(void *opaque, hwaddr addr, unsigned size) { VFIOPCIDevice *vdev = opaque; @@ -1010,10 +1082,9 @@ static const MemoryRegionOps vfio_rom_ops = { static void vfio_pci_size_rom(VFIOPCIDevice *vdev) { + VFIODevice *vbasedev = &vdev->vbasedev; uint32_t orig, size = cpu_to_le32((uint32_t)PCI_ROM_ADDRESS_MASK); - off_t offset = vdev->config_offset + PCI_ROM_ADDRESS; char *name; - int fd = vdev->vbasedev.fd; if (vdev->pdev.romfile || !vdev->pdev.rom_bar) { /* Since pci handles romfile, just print a message and return */ @@ -1030,11 +1101,12 @@ static void vfio_pci_size_rom(VFIOPCIDevice *vdev) * Use the same size ROM BAR as the physical device. The contents * will get filled in later when the guest tries to read it. */ - if (pread(fd, &orig, 4, offset) != 4 || - pwrite(fd, &size, 4, offset) != 4 || - pread(fd, &size, 4, offset) != 4 || - pwrite(fd, &orig, 4, offset) != 4) { - error_report("%s(%s) failed: %m", __func__, vdev->vbasedev.name); + if (vfio_pci_config_space_read(vdev, PCI_ROM_ADDRESS, 4, &orig) != 4 || + vfio_pci_config_space_write(vdev, PCI_ROM_ADDRESS, 4, &size) != 4 || + vfio_pci_config_space_read(vdev, PCI_ROM_ADDRESS, 4, &size) != 4 || + vfio_pci_config_space_write(vdev, PCI_ROM_ADDRESS, 4, &orig) != 4) { + + error_report("%s(%s) ROM access failed", __func__, vbasedev->name); return; } @@ -1167,7 +1239,7 @@ static const MemoryRegionOps vfio_vga_ops = { */ static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); VFIORegion *region = &vdev->bars[bar].region; MemoryRegion *mmap_mr, *region_mr, *base_mr; PCIIORegion *r; @@ -1213,7 +1285,8 @@ static void vfio_sub_page_bar_update_mapping(PCIDevice *pdev, int bar) */ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); + VFIODevice *vbasedev = &vdev->vbasedev; uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val; memcpy(&emu_bits, vdev->emulated_config_bits + addr, len); @@ -1226,12 +1299,12 @@ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len) if (~emu_bits & (0xffffffffU >> (32 - len * 8))) { ssize_t ret; - ret = pread(vdev->vbasedev.fd, &phys_val, len, - vdev->config_offset + addr); + ret = vfio_pci_config_space_read(vdev, addr, len, &phys_val); if (ret != len) { - error_report("%s(%s, 0x%x, 0x%x) failed: %m", - __func__, vdev->vbasedev.name, addr, len); - return -errno; + error_report("%s(%s, 0x%x, 0x%x) failed: %s", + __func__, vbasedev->name, addr, len, + strreaderror(ret)); + return -1; } phys_val = le32_to_cpu(phys_val); } @@ -1246,16 +1319,19 @@ uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len) void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr, uint32_t val, int len) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); + VFIODevice *vbasedev = &vdev->vbasedev; uint32_t val_le = cpu_to_le32(val); + int ret; trace_vfio_pci_write_config(vdev->vbasedev.name, addr, val, len); /* Write everything to VFIO, let it filter out what we can't write */ - if (pwrite(vdev->vbasedev.fd, &val_le, len, vdev->config_offset + addr) - != len) { - error_report("%s(%s, 0x%x, 0x%x, 0x%x) failed: %m", - __func__, vdev->vbasedev.name, addr, val, len); + ret = vfio_pci_config_space_write(vdev, addr, len, &val_le); + if (ret != len) { + error_report("%s(%s, 0x%x, 0x%x, 0x%x) failed: %s", + __func__, vbasedev->name, addr, val, len, + strwriteerror(ret)); } /* MSI/MSI-X Enabling/Disabling */ @@ -1343,9 +1419,11 @@ static bool vfio_msi_setup(VFIOPCIDevice *vdev, int pos, Error **errp) int ret, entries; Error *err = NULL; - if (pread(vdev->vbasedev.fd, &ctrl, sizeof(ctrl), - vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) { - error_setg_errno(errp, errno, "failed reading MSI PCI_CAP_FLAGS"); + ret = vfio_pci_config_space_read(vdev, pos + PCI_CAP_FLAGS, + sizeof(ctrl), &ctrl); + if (ret != sizeof(ctrl)) { + error_setg(errp, "failed reading MSI PCI_CAP_FLAGS: %s", + strreaderror(ret)); return false; } ctrl = le16_to_cpu(ctrl); @@ -1378,8 +1456,8 @@ static void vfio_pci_fixup_msix_region(VFIOPCIDevice *vdev) * If the host driver allows mapping of a MSIX data, we are going to * do map the entire BAR and emulate MSIX table on top of that. */ - if (vfio_has_region_cap(&vdev->vbasedev, region->nr, - VFIO_REGION_INFO_CAP_MSIX_MAPPABLE)) { + if (vfio_device_has_region_cap(&vdev->vbasedev, region->nr, + VFIO_REGION_INFO_CAP_MSIX_MAPPABLE)) { return; } @@ -1552,31 +1630,35 @@ static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp) uint8_t pos; uint16_t ctrl; uint32_t table, pba; - int ret, fd = vdev->vbasedev.fd; - struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info), - .index = VFIO_PCI_MSIX_IRQ_INDEX }; + struct vfio_irq_info irq_info; VFIOMSIXInfo *msix; + int ret; pos = pci_find_capability(&vdev->pdev, PCI_CAP_ID_MSIX); if (!pos) { return true; } - if (pread(fd, &ctrl, sizeof(ctrl), - vdev->config_offset + pos + PCI_MSIX_FLAGS) != sizeof(ctrl)) { - error_setg_errno(errp, errno, "failed to read PCI MSIX FLAGS"); + ret = vfio_pci_config_space_read(vdev, pos + PCI_MSIX_FLAGS, + sizeof(ctrl), &ctrl); + if (ret != sizeof(ctrl)) { + error_setg(errp, "failed to read PCI MSIX FLAGS: %s", + strreaderror(ret)); return false; } - if (pread(fd, &table, sizeof(table), - vdev->config_offset + pos + PCI_MSIX_TABLE) != sizeof(table)) { - error_setg_errno(errp, errno, "failed to read PCI MSIX TABLE"); + ret = vfio_pci_config_space_read(vdev, pos + PCI_MSIX_TABLE, + sizeof(table), &table); + if (ret != sizeof(table)) { + error_setg(errp, "failed to read PCI MSIX TABLE: %s", + strreaderror(ret)); return false; } - if (pread(fd, &pba, sizeof(pba), - vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) { - error_setg_errno(errp, errno, "failed to read PCI MSIX PBA"); + ret = vfio_pci_config_space_read(vdev, pos + PCI_MSIX_PBA, + sizeof(pba), &pba); + if (ret != sizeof(pba)) { + error_setg(errp, "failed to read PCI MSIX PBA: %s", strreaderror(ret)); return false; } @@ -1591,7 +1673,8 @@ static bool vfio_msix_early_setup(VFIOPCIDevice *vdev, Error **errp) msix->pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK; msix->entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1; - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info); + ret = vfio_device_get_irq_info(&vdev->vbasedev, VFIO_PCI_MSIX_IRQ_INDEX, + &irq_info); if (ret < 0) { error_setg_errno(errp, -ret, "failed to get MSI-X irq info"); g_free(msix); @@ -1698,7 +1781,7 @@ static bool vfio_msix_setup(VFIOPCIDevice *vdev, int pos, Error **errp) return true; } -static void vfio_teardown_msi(VFIOPCIDevice *vdev) +void vfio_pci_teardown_msi(VFIOPCIDevice *vdev) { msi_uninit(&vdev->pdev); @@ -1735,10 +1818,10 @@ static void vfio_bar_prepare(VFIOPCIDevice *vdev, int nr) } /* Determine what type of BAR this is for registration */ - ret = pread(vdev->vbasedev.fd, &pci_bar, sizeof(pci_bar), - vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr)); + ret = vfio_pci_config_space_read(vdev, PCI_BASE_ADDRESS_0 + (4 * nr), + sizeof(pci_bar), &pci_bar); if (ret != sizeof(pci_bar)) { - error_report("vfio: Failed to read BAR %d (%m)", nr); + error_report("vfio: Failed to read BAR %d: %s", nr, strreaderror(ret)); return; } @@ -1748,6 +1831,9 @@ static void vfio_bar_prepare(VFIOPCIDevice *vdev, int nr) bar->type = pci_bar & (bar->ioport ? ~PCI_BASE_ADDRESS_IO_MASK : ~PCI_BASE_ADDRESS_MEM_MASK); bar->size = bar->region.size; + + /* IO regions are sync, memory can be async */ + bar->region.post_wr = (bar->ioport == 0); } static void vfio_bars_prepare(VFIOPCIDevice *vdev) @@ -1794,7 +1880,7 @@ static void vfio_bars_register(VFIOPCIDevice *vdev) } } -static void vfio_bars_exit(VFIOPCIDevice *vdev) +void vfio_pci_bars_exit(VFIOPCIDevice *vdev) { int i; @@ -2385,7 +2471,7 @@ static void vfio_add_ext_cap(VFIOPCIDevice *vdev) g_free(config); } -static bool vfio_add_capabilities(VFIOPCIDevice *vdev, Error **errp) +bool vfio_pci_add_capabilities(VFIOPCIDevice *vdev, Error **errp) { PCIDevice *pdev = &vdev->pdev; @@ -2441,21 +2527,23 @@ void vfio_pci_pre_reset(VFIOPCIDevice *vdev) void vfio_pci_post_reset(VFIOPCIDevice *vdev) { + VFIODevice *vbasedev = &vdev->vbasedev; Error *err = NULL; - int nr; + int ret, nr; if (!vfio_intx_enable(vdev, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); } for (nr = 0; nr < PCI_NUM_REGIONS - 1; ++nr) { - off_t addr = vdev->config_offset + PCI_BASE_ADDRESS_0 + (4 * nr); + off_t addr = PCI_BASE_ADDRESS_0 + (4 * nr); uint32_t val = 0; uint32_t len = sizeof(val); - if (pwrite(vdev->vbasedev.fd, &val, len, addr) != len) { - error_report("%s(%s) reset bar %d failed: %m", __func__, - vdev->vbasedev.name, nr); + ret = vfio_pci_config_space_write(vdev, addr, len, &val); + if (ret != len) { + error_report("%s(%s) reset bar %d failed: %s", __func__, + vbasedev->name, nr, strwriteerror(ret)); } } @@ -2659,7 +2747,7 @@ static int vfio_pci_load_config(VFIODevice *vbasedev, QEMUFile *f) static VFIODeviceOps vfio_pci_ops = { .vfio_compute_needs_reset = vfio_pci_compute_needs_reset, .vfio_hot_reset_multi = vfio_pci_hot_reset_multi, - .vfio_eoi = vfio_intx_eoi, + .vfio_eoi = vfio_pci_intx_eoi, .vfio_get_object = vfio_pci_get_object, .vfio_save_config = vfio_pci_save_config, .vfio_load_config = vfio_pci_load_config, @@ -2668,10 +2756,10 @@ static VFIODeviceOps vfio_pci_ops = { bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp) { VFIODevice *vbasedev = &vdev->vbasedev; - g_autofree struct vfio_region_info *reg_info = NULL; + struct vfio_region_info *reg_info = NULL; int ret; - ret = vfio_get_region_info(vbasedev, VFIO_PCI_VGA_REGION_INDEX, ®_info); + ret = vfio_device_get_region_info(vbasedev, VFIO_PCI_VGA_REGION_INDEX, ®_info); if (ret) { error_setg_errno(errp, -ret, "failed getting region info for VGA region index %d", @@ -2730,11 +2818,11 @@ bool vfio_populate_vga(VFIOPCIDevice *vdev, Error **errp) return true; } -static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) +bool vfio_pci_populate_device(VFIOPCIDevice *vdev, Error **errp) { VFIODevice *vbasedev = &vdev->vbasedev; - g_autofree struct vfio_region_info *reg_info = NULL; - struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info) }; + struct vfio_region_info *reg_info = NULL; + struct vfio_irq_info irq_info; int i, ret = -1; /* Sanity check device */ @@ -2769,14 +2857,14 @@ static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) QLIST_INIT(&vdev->bars[i].quirks); } - ret = vfio_get_region_info(vbasedev, - VFIO_PCI_CONFIG_REGION_INDEX, ®_info); + ret = vfio_device_get_region_info(vbasedev, + VFIO_PCI_CONFIG_REGION_INDEX, ®_info); if (ret) { error_setg_errno(errp, -ret, "failed to get config info"); return false; } - trace_vfio_populate_device_config(vdev->vbasedev.name, + trace_vfio_pci_populate_device_config(vdev->vbasedev.name, (unsigned long)reg_info->size, (unsigned long)reg_info->offset, (unsigned long)reg_info->flags); @@ -2795,12 +2883,10 @@ static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) } } - irq_info.index = VFIO_PCI_ERR_IRQ_INDEX; - - ret = ioctl(vdev->vbasedev.fd, VFIO_DEVICE_GET_IRQ_INFO, &irq_info); + ret = vfio_device_get_irq_info(vbasedev, VFIO_PCI_ERR_IRQ_INDEX, &irq_info); if (ret) { /* This can fail for an old kernel or legacy PCI dev */ - trace_vfio_populate_device_get_irq_info_failure(strerror(errno)); + trace_vfio_pci_populate_device_get_irq_info_failure(strerror(-ret)); } else if (irq_info.count == 1) { vdev->pci_aer = true; } else { @@ -2812,9 +2898,21 @@ static bool vfio_populate_device(VFIOPCIDevice *vdev, Error **errp) return true; } -static void vfio_pci_put_device(VFIOPCIDevice *vdev) +void vfio_pci_put_device(VFIOPCIDevice *vdev) { - vfio_detach_device(&vdev->vbasedev); + vfio_display_finalize(vdev); + vfio_bars_finalize(vdev); + g_free(vdev->emulated_config_bits); + g_free(vdev->rom); + /* + * XXX Leaking igd_opregion is not an oversight, we can't remove the + * fw_cfg entry therefore leaking this allocation seems like the safest + * option. + * + * g_free(vdev->igd_opregion); + */ + + vfio_device_detach(&vdev->vbasedev); g_free(vdev->vbasedev.name); g_free(vdev->msix); @@ -2848,7 +2946,7 @@ static void vfio_err_notifier_handler(void *opaque) * and continue after disabling error recovery support for the * device. */ -static void vfio_register_err_notifier(VFIOPCIDevice *vdev) +void vfio_pci_register_err_notifier(VFIOPCIDevice *vdev) { Error *err = NULL; int32_t fd; @@ -2857,8 +2955,9 @@ static void vfio_register_err_notifier(VFIOPCIDevice *vdev) return; } - if (event_notifier_init(&vdev->err_notifier, 0)) { - error_report("vfio: Unable to init event notifier for error detection"); + if (!vfio_notifier_init(vdev, &vdev->err_notifier, "err_notifier", 0, + &err)) { + error_report_err(err); vdev->pci_aer = false; return; } @@ -2866,11 +2965,11 @@ static void vfio_register_err_notifier(VFIOPCIDevice *vdev) fd = event_notifier_get_fd(&vdev->err_notifier); qemu_set_fd_handler(fd, vfio_err_notifier_handler, NULL, vdev); - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_ERR_IRQ_INDEX, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_ERR_IRQ_INDEX, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); qemu_set_fd_handler(fd, NULL, NULL, vdev); - event_notifier_cleanup(&vdev->err_notifier); + vfio_notifier_cleanup(vdev, &vdev->err_notifier, "err_notifier", 0); vdev->pci_aer = false; } } @@ -2883,13 +2982,13 @@ static void vfio_unregister_err_notifier(VFIOPCIDevice *vdev) return; } - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_ERR_IRQ_INDEX, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_ERR_IRQ_INDEX, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); } qemu_set_fd_handler(event_notifier_get_fd(&vdev->err_notifier), NULL, NULL, vdev); - event_notifier_cleanup(&vdev->err_notifier); + vfio_notifier_cleanup(vdev, &vdev->err_notifier, "err_notifier", 0); } static void vfio_req_notifier_handler(void *opaque) @@ -2907,35 +3006,37 @@ static void vfio_req_notifier_handler(void *opaque) } } -static void vfio_register_req_notifier(VFIOPCIDevice *vdev) +void vfio_pci_register_req_notifier(VFIOPCIDevice *vdev) { - struct vfio_irq_info irq_info = { .argsz = sizeof(irq_info), - .index = VFIO_PCI_REQ_IRQ_INDEX }; + struct vfio_irq_info irq_info; Error *err = NULL; int32_t fd; + int ret; if (!(vdev->features & VFIO_FEATURE_ENABLE_REQ)) { return; } - if (ioctl(vdev->vbasedev.fd, - VFIO_DEVICE_GET_IRQ_INFO, &irq_info) < 0 || irq_info.count < 1) { + ret = vfio_device_get_irq_info(&vdev->vbasedev, VFIO_PCI_REQ_IRQ_INDEX, + &irq_info); + if (ret < 0 || irq_info.count < 1) { return; } - if (event_notifier_init(&vdev->req_notifier, 0)) { - error_report("vfio: Unable to init event notifier for device request"); + if (!vfio_notifier_init(vdev, &vdev->req_notifier, "req_notifier", 0, + &err)) { + error_report_err(err); return; } fd = event_notifier_get_fd(&vdev->req_notifier); qemu_set_fd_handler(fd, vfio_req_notifier_handler, NULL, vdev); - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_REQ_IRQ_INDEX, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_REQ_IRQ_INDEX, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); qemu_set_fd_handler(fd, NULL, NULL, vdev); - event_notifier_cleanup(&vdev->req_notifier); + vfio_notifier_cleanup(vdev, &vdev->req_notifier, "req_notifier", 0); } else { vdev->req_enabled = true; } @@ -2949,87 +3050,33 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev) return; } - if (!vfio_set_irq_signaling(&vdev->vbasedev, VFIO_PCI_REQ_IRQ_INDEX, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { + if (!vfio_device_irq_set_signaling(&vdev->vbasedev, VFIO_PCI_REQ_IRQ_INDEX, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, -1, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vdev->vbasedev.name); } qemu_set_fd_handler(event_notifier_get_fd(&vdev->req_notifier), NULL, NULL, vdev); - event_notifier_cleanup(&vdev->req_notifier); + vfio_notifier_cleanup(vdev, &vdev->req_notifier, "req_notifier", 0); vdev->req_enabled = false; } -static void vfio_realize(PCIDevice *pdev, Error **errp) +bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp) { - ERRP_GUARD(); - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + PCIDevice *pdev = &vdev->pdev; VFIODevice *vbasedev = &vdev->vbasedev; - int i, ret; - char uuid[UUID_STR_LEN]; - g_autofree char *name = NULL; - - if (vbasedev->fd < 0 && !vbasedev->sysfsdev) { - if (!(~vdev->host.domain || ~vdev->host.bus || - ~vdev->host.slot || ~vdev->host.function)) { - error_setg(errp, "No provided host device"); - error_append_hint(errp, "Use -device vfio-pci,host=DDDD:BB:DD.F " -#ifdef CONFIG_IOMMUFD - "or -device vfio-pci,fd=DEVICE_FD " -#endif - "or -device vfio-pci,sysfsdev=PATH_TO_DEVICE\n"); - return; - } - vbasedev->sysfsdev = - g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%01x", - vdev->host.domain, vdev->host.bus, - vdev->host.slot, vdev->host.function); - } - - if (!vfio_device_get_name(vbasedev, errp)) { - return; - } - - /* - * Mediated devices *might* operate compatibly with discarding of RAM, but - * we cannot know for certain, it depends on whether the mdev vendor driver - * stays in sync with the active working set of the guest driver. Prevent - * the x-balloon-allowed option unless this is minimally an mdev device. - */ - vbasedev->mdev = vfio_device_is_mdev(vbasedev); - - trace_vfio_mdev(vbasedev->name, vbasedev->mdev); - - if (vbasedev->ram_block_discard_allowed && !vbasedev->mdev) { - error_setg(errp, "x-balloon-allowed only potentially compatible " - "with mdev devices"); - goto error; - } - - if (!qemu_uuid_is_null(&vdev->vf_token)) { - qemu_uuid_unparse(&vdev->vf_token, uuid); - name = g_strdup_printf("%s vf_token=%s", vbasedev->name, uuid); - } else { - name = g_strdup(vbasedev->name); - } - - if (!vfio_attach_device(name, vbasedev, - pci_device_iommu_address_space(pdev), errp)) { - goto error; - } + uint32_t config_space_size; + int ret; - if (!vfio_populate_device(vdev, errp)) { - goto error; - } + config_space_size = MIN(pci_config_size(&vdev->pdev), vdev->config_size); /* Get a copy of config space */ - ret = pread(vbasedev->fd, vdev->pdev.config, - MIN(pci_config_size(&vdev->pdev), vdev->config_size), - vdev->config_offset); - if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) { - ret = ret < 0 ? -errno : -EFAULT; - error_setg_errno(errp, -ret, "failed to read device config space"); - goto error; + ret = vfio_pci_config_space_read(vdev, 0, config_space_size, + vdev->pdev.config); + if (ret < (int)config_space_size) { + ret = ret < 0 ? -ret : EFAULT; + error_setg_errno(errp, ret, "failed to read device config space"); + return false; } /* vfio emulates a lot for us, but some bits need extra love */ @@ -3048,7 +3095,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) if (vdev->vendor_id != PCI_ANY_ID) { if (vdev->vendor_id >= 0xffff) { error_setg(errp, "invalid PCI vendor ID provided"); - goto error; + return false; } vfio_add_emulated_word(vdev, PCI_VENDOR_ID, vdev->vendor_id, ~0); trace_vfio_pci_emulated_vendor_id(vbasedev->name, vdev->vendor_id); @@ -3059,7 +3106,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) if (vdev->device_id != PCI_ANY_ID) { if (vdev->device_id > 0xffff) { error_setg(errp, "invalid PCI device ID provided"); - goto error; + return false; } vfio_add_emulated_word(vdev, PCI_DEVICE_ID, vdev->device_id, ~0); trace_vfio_pci_emulated_device_id(vbasedev->name, vdev->device_id); @@ -3070,7 +3117,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) if (vdev->sub_vendor_id != PCI_ANY_ID) { if (vdev->sub_vendor_id > 0xffff) { error_setg(errp, "invalid PCI subsystem vendor ID provided"); - goto error; + return false; } vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_VENDOR_ID, vdev->sub_vendor_id, ~0); @@ -3081,7 +3128,7 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) if (vdev->sub_device_id != PCI_ANY_ID) { if (vdev->sub_device_id > 0xffff) { error_setg(errp, "invalid PCI subsystem device ID provided"); - goto error; + return false; } vfio_add_emulated_word(vdev, PCI_SUBSYSTEM_ID, vdev->sub_device_id, ~0); trace_vfio_pci_emulated_sub_device_id(vbasedev->name, @@ -3112,32 +3159,17 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) vfio_bars_prepare(vdev); if (!vfio_msix_early_setup(vdev, errp)) { - goto error; + return false; } vfio_bars_register(vdev); - if (!vbasedev->mdev && - !pci_device_set_iommu_device(pdev, vbasedev->hiod, errp)) { - error_prepend(errp, "Failed to set vIOMMU: "); - goto out_teardown; - } - - if (!vfio_add_capabilities(vdev, errp)) { - goto out_unset_idev; - } - - if (!vfio_config_quirk_setup(vdev, errp)) { - goto out_unset_idev; - } - - if (vdev->vga) { - vfio_vga_quirk_setup(vdev); - } + return true; +} - for (i = 0; i < PCI_ROM_SLOT; i++) { - vfio_bar_quirk_setup(vdev, i); - } +bool vfio_pci_interrupt_setup(VFIOPCIDevice *vdev, Error **errp) +{ + PCIDevice *pdev = &vdev->pdev; /* QEMU emulates all of MSI & MSIX */ if (pdev->cap_present & QEMU_PCI_CAP_MSIX) { @@ -3152,14 +3184,111 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) { vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, - vfio_intx_mmap_enable, vdev); + vfio_intx_mmap_enable, vdev); pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_intx_routing_notifier); vdev->irqchip_change_notifier.notify = vfio_irqchip_change; kvm_irqchip_add_change_notifier(&vdev->irqchip_change_notifier); if (!vfio_intx_enable(vdev, errp)) { - goto out_deregister; + timer_free(vdev->intx.mmap_timer); + pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); + kvm_irqchip_remove_change_notifier(&vdev->irqchip_change_notifier); + return false; + } + } + return true; +} + +static void vfio_pci_realize(PCIDevice *pdev, Error **errp) +{ + ERRP_GUARD(); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); + VFIODevice *vbasedev = &vdev->vbasedev; + int i; + char uuid[UUID_STR_LEN]; + g_autofree char *name = NULL; + + if (vbasedev->fd < 0 && !vbasedev->sysfsdev) { + if (!(~vdev->host.domain || ~vdev->host.bus || + ~vdev->host.slot || ~vdev->host.function)) { + error_setg(errp, "No provided host device"); + error_append_hint(errp, "Use -device vfio-pci,host=DDDD:BB:DD.F " +#ifdef CONFIG_IOMMUFD + "or -device vfio-pci,fd=DEVICE_FD " +#endif + "or -device vfio-pci,sysfsdev=PATH_TO_DEVICE\n"); + return; } + vbasedev->sysfsdev = + g_strdup_printf("/sys/bus/pci/devices/%04x:%02x:%02x.%01x", + vdev->host.domain, vdev->host.bus, + vdev->host.slot, vdev->host.function); + } + + if (!vfio_device_get_name(vbasedev, errp)) { + return; + } + + /* + * Mediated devices *might* operate compatibly with discarding of RAM, but + * we cannot know for certain, it depends on whether the mdev vendor driver + * stays in sync with the active working set of the guest driver. Prevent + * the x-balloon-allowed option unless this is minimally an mdev device. + */ + vbasedev->mdev = vfio_device_is_mdev(vbasedev); + + trace_vfio_mdev(vbasedev->name, vbasedev->mdev); + + if (vbasedev->ram_block_discard_allowed && !vbasedev->mdev) { + error_setg(errp, "x-balloon-allowed only potentially compatible " + "with mdev devices"); + goto error; + } + + if (!qemu_uuid_is_null(&vdev->vf_token)) { + qemu_uuid_unparse(&vdev->vf_token, uuid); + name = g_strdup_printf("%s vf_token=%s", vbasedev->name, uuid); + } else { + name = g_strdup(vbasedev->name); + } + + if (!vfio_device_attach(name, vbasedev, + pci_device_iommu_address_space(pdev), errp)) { + goto error; + } + + if (!vfio_pci_populate_device(vdev, errp)) { + goto error; + } + + if (!vfio_pci_config_setup(vdev, errp)) { + goto error; + } + + if (!vbasedev->mdev && + !pci_device_set_iommu_device(pdev, vbasedev->hiod, errp)) { + error_prepend(errp, "Failed to set vIOMMU: "); + goto out_teardown; + } + + if (!vfio_pci_add_capabilities(vdev, errp)) { + goto out_unset_idev; + } + + if (!vfio_config_quirk_setup(vdev, errp)) { + goto out_unset_idev; + } + + if (vdev->vga) { + vfio_vga_quirk_setup(vdev); + } + + for (i = 0; i < PCI_ROM_SLOT; i++) { + vfio_bar_quirk_setup(vdev, i); + } + + if (!vfio_pci_interrupt_setup(vdev, errp)) { + goto out_unset_idev; } if (vdev->display != ON_OFF_AUTO_OFF) { @@ -3202,8 +3331,8 @@ static void vfio_realize(PCIDevice *pdev, Error **errp) } } - vfio_register_err_notifier(vdev); - vfio_register_req_notifier(vdev); + vfio_pci_register_err_notifier(vdev); + vfio_pci_register_req_notifier(vdev); vfio_setup_resetfn_quirk(vdev); return; @@ -3224,33 +3353,22 @@ out_unset_idev: pci_device_unset_iommu_device(pdev); } out_teardown: - vfio_teardown_msi(vdev); - vfio_bars_exit(vdev); + vfio_pci_teardown_msi(vdev); + vfio_pci_bars_exit(vdev); error: error_prepend(errp, VFIO_MSG_PREFIX, vbasedev->name); } static void vfio_instance_finalize(Object *obj) { - VFIOPCIDevice *vdev = VFIO_PCI(obj); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); - vfio_display_finalize(vdev); - vfio_bars_finalize(vdev); - g_free(vdev->emulated_config_bits); - g_free(vdev->rom); - /* - * XXX Leaking igd_opregion is not an oversight, we can't remove the - * fw_cfg entry therefore leaking this allocation seems like the safest - * option. - * - * g_free(vdev->igd_opregion); - */ vfio_pci_put_device(vdev); } static void vfio_exitfn(PCIDevice *pdev) { - VFIOPCIDevice *vdev = VFIO_PCI(pdev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(pdev); VFIODevice *vbasedev = &vdev->vbasedev; vfio_unregister_req_notifier(vdev); @@ -3263,9 +3381,9 @@ static void vfio_exitfn(PCIDevice *pdev) if (vdev->intx.mmap_timer) { timer_free(vdev->intx.mmap_timer); } - vfio_teardown_msi(vdev); + vfio_pci_teardown_msi(vdev); vfio_pci_disable_rp_atomics(vdev); - vfio_bars_exit(vdev); + vfio_pci_bars_exit(vdev); vfio_migration_exit(vbasedev); if (!vbasedev->mdev) { pci_device_unset_iommu_device(pdev); @@ -3274,7 +3392,12 @@ static void vfio_exitfn(PCIDevice *pdev) static void vfio_pci_reset(DeviceState *dev) { - VFIOPCIDevice *vdev = VFIO_PCI(dev); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(dev); + + /* Do not reset the device during qemu_system_reset prior to cpr load */ + if (cpr_is_incoming()) { + return; + } trace_vfio_pci_reset(vdev->vbasedev.name); @@ -3314,7 +3437,7 @@ post_reset: static void vfio_instance_init(Object *obj) { PCIDevice *pci_dev = PCI_DEVICE(obj); - VFIOPCIDevice *vdev = VFIO_PCI(obj); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); VFIODevice *vbasedev = &vdev->vbasedev; device_add_bootindex_property(obj, &vdev->bootindex, @@ -3333,8 +3456,40 @@ static void vfio_instance_init(Object *obj) /* QEMU_PCI_CAP_EXPRESS initialization does not depend on QEMU command * line, therefore, no need to wait to realize like other devices */ pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; + + /* + * A device that is resuming for cpr is already configured, so do not + * reset it during qemu_system_reset prior to cpr load, else interrupts + * may be lost. + */ + pci_dev->cap_present |= QEMU_PCI_SKIP_RESET_ON_CPR; +} + +static void vfio_pci_base_dev_class_init(ObjectClass *klass, const void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass); + + dc->desc = "VFIO PCI base device"; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + pdc->exit = vfio_exitfn; + pdc->config_read = vfio_pci_read_config; + pdc->config_write = vfio_pci_write_config; } +static const TypeInfo vfio_pci_base_dev_info = { + .name = TYPE_VFIO_PCI_BASE, + .parent = TYPE_PCI_DEVICE, + .instance_size = sizeof(VFIOPCIDevice), + .abstract = true, + .class_init = vfio_pci_base_dev_class_init, + .interfaces = (const InterfaceInfo[]) { + { INTERFACE_PCIE_DEVICE }, + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { } + }, +}; + static PropertyInfo vfio_pci_migration_multifd_transfer_prop; static const Property vfio_pci_dev_properties[] = { @@ -3358,7 +3513,7 @@ static const Property vfio_pci_dev_properties[] = { DEFINE_PROP_BIT("x-req", VFIOPCIDevice, features, VFIO_FEATURE_ENABLE_REQ_BIT, true), DEFINE_PROP_BIT("x-igd-opregion", VFIOPCIDevice, features, - VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, false), + VFIO_FEATURE_ENABLE_IGD_OPREGION_BIT, true), DEFINE_PROP_BIT("x-igd-lpc", VFIOPCIDevice, features, VFIO_FEATURE_ENABLE_IGD_LPC_BIT, false), DEFINE_PROP_ON_OFF_AUTO("x-igd-legacy-mode", VFIOPCIDevice, @@ -3405,11 +3560,12 @@ static const Property vfio_pci_dev_properties[] = { #ifdef CONFIG_IOMMUFD static void vfio_pci_set_fd(Object *obj, const char *str, Error **errp) { - vfio_device_set_fd(&VFIO_PCI(obj)->vbasedev, str, errp); + VFIOPCIDevice *vdev = VFIO_PCI_BASE(obj); + vfio_device_set_fd(&vdev->vbasedev, str, errp); } #endif -static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) +static void vfio_pci_dev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pdc = PCI_DEVICE_CLASS(klass); @@ -3419,12 +3575,9 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) #ifdef CONFIG_IOMMUFD object_class_property_add_str(klass, "fd", NULL, vfio_pci_set_fd); #endif + dc->vmsd = &vfio_cpr_pci_vmstate; dc->desc = "VFIO-based PCI device assignment"; - set_bit(DEVICE_CATEGORY_MISC, dc->categories); - pdc->realize = vfio_realize; - pdc->exit = vfio_exitfn; - pdc->config_read = vfio_pci_read_config; - pdc->config_write = vfio_pci_write_config; + pdc->realize = vfio_pci_realize; object_class_property_set_description(klass, /* 1.3 */ "host", @@ -3549,16 +3702,10 @@ static void vfio_pci_dev_class_init(ObjectClass *klass, void *data) static const TypeInfo vfio_pci_dev_info = { .name = TYPE_VFIO_PCI, - .parent = TYPE_PCI_DEVICE, - .instance_size = sizeof(VFIOPCIDevice), + .parent = TYPE_VFIO_PCI_BASE, .class_init = vfio_pci_dev_class_init, .instance_init = vfio_instance_init, .instance_finalize = vfio_instance_finalize, - .interfaces = (InterfaceInfo[]) { - { INTERFACE_PCIE_DEVICE }, - { INTERFACE_CONVENTIONAL_PCI_DEVICE }, - { } - }, }; static const Property vfio_pci_dev_nohotplug_properties[] = { @@ -3567,7 +3714,8 @@ static const Property vfio_pci_dev_nohotplug_properties[] = { ON_OFF_AUTO_AUTO), }; -static void vfio_pci_nohotplug_dev_class_init(ObjectClass *klass, void *data) +static void vfio_pci_nohotplug_dev_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -3604,6 +3752,7 @@ static void register_vfio_pci_dev_type(void) vfio_pci_migration_multifd_transfer_prop = qdev_prop_on_off_auto; vfio_pci_migration_multifd_transfer_prop.realized_set_allowed = true; + type_register_static(&vfio_pci_base_dev_info); type_register_static(&vfio_pci_dev_info); type_register_static(&vfio_pci_nohotplug_dev_info); } diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h index d94ecab..5ba7330 100644 --- a/hw/vfio/pci.h +++ b/hw/vfio/pci.h @@ -12,14 +12,16 @@ #ifndef HW_VFIO_VFIO_PCI_H #define HW_VFIO_VFIO_PCI_H -#include "exec/memory.h" +#include "system/memory.h" #include "hw/pci/pci_device.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-device.h" +#include "hw/vfio/vfio-region.h" #include "qemu/event_notifier.h" #include "qemu/queue.h" #include "qemu/timer.h" #include "qom/object.h" #include "system/kvm.h" +#include "vfio-display.h" #define PCI_ANY_ID (~0) @@ -114,10 +116,19 @@ typedef struct VFIOMSIXInfo { uint32_t pba_offset; unsigned long *pending; bool noresize; + MemoryRegion *pba_region; } VFIOMSIXInfo; +/* + * TYPE_VFIO_PCI_BASE is an abstract type used to share code + * between VFIO implementations that use a kernel driver + * with those that use user sockets. + */ +#define TYPE_VFIO_PCI_BASE "vfio-pci-base" +OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI_BASE) + #define TYPE_VFIO_PCI "vfio-pci" -OBJECT_DECLARE_SIMPLE_TYPE(VFIOPCIDevice, VFIO_PCI) +/* TYPE_VFIO_PCI shares struct VFIOPCIDevice. */ struct VFIOPCIDevice { PCIDevice pdev; @@ -200,6 +211,14 @@ static inline bool vfio_is_vga(VFIOPCIDevice *vdev) return class == PCI_CLASS_DISPLAY_VGA; } +/* MSI/MSI-X/INTx */ +void vfio_pci_vector_init(VFIOPCIDevice *vdev, int nr); +void vfio_pci_add_kvm_msi_virq(VFIOPCIDevice *vdev, VFIOMSIVector *vector, + int vector_n, bool msix); +void vfio_pci_prepare_kvm_msi_virq_batch(VFIOPCIDevice *vdev); +void vfio_pci_commit_kvm_msi_virq_batch(VFIOPCIDevice *vdev); +bool vfio_pci_intx_enable(VFIOPCIDevice *vdev, Error **errp); + uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len); void vfio_pci_write_config(PCIDevice *pdev, uint32_t addr, uint32_t val, int len); @@ -238,4 +257,15 @@ void vfio_display_finalize(VFIOPCIDevice *vdev); extern const VMStateDescription vfio_display_vmstate; +void vfio_pci_bars_exit(VFIOPCIDevice *vdev); +bool vfio_pci_add_capabilities(VFIOPCIDevice *vdev, Error **errp); +bool vfio_pci_config_setup(VFIOPCIDevice *vdev, Error **errp); +bool vfio_pci_interrupt_setup(VFIOPCIDevice *vdev, Error **errp); +void vfio_pci_intx_eoi(VFIODevice *vbasedev); +void vfio_pci_put_device(VFIOPCIDevice *vdev); +bool vfio_pci_populate_device(VFIOPCIDevice *vdev, Error **errp); +void vfio_pci_register_err_notifier(VFIOPCIDevice *vdev); +void vfio_pci_register_req_notifier(VFIOPCIDevice *vdev); +void vfio_pci_teardown_msi(VFIOPCIDevice *vdev); + #endif /* HW_VFIO_VFIO_PCI_H */ diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c index 7b4e100..9a21f2e 100644 --- a/hw/vfio/platform.c +++ b/hw/vfio/platform.c @@ -28,8 +28,8 @@ #include "qemu/main-loop.h" #include "qemu/module.h" #include "qemu/range.h" -#include "exec/memory.h" -#include "exec/address-spaces.h" +#include "system/memory.h" +#include "system/address-spaces.h" #include "qemu/queue.h" #include "hw/sysbus.h" #include "trace.h" @@ -37,6 +37,7 @@ #include "hw/platform-bus.h" #include "hw/qdev-properties.h" #include "system/kvm.h" +#include "hw/vfio/vfio-region.h" /* * Functions used whatever the injection method @@ -118,8 +119,8 @@ static int vfio_set_trigger_eventfd(VFIOINTp *intp, qemu_set_fd_handler(fd, (IOHandler *)handler, NULL, intp); - if (!vfio_set_irq_signaling(vbasedev, intp->pin, 0, - VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { + if (!vfio_device_irq_set_signaling(vbasedev, intp->pin, 0, + VFIO_IRQ_SET_ACTION_TRIGGER, fd, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vbasedev->name); qemu_set_fd_handler(fd, NULL, NULL, NULL); return -EINVAL; @@ -300,7 +301,7 @@ static void vfio_platform_eoi(VFIODevice *vbasedev) if (vfio_irq_is_automasked(intp)) { /* unmasks the physical level-sensitive IRQ */ - vfio_unmask_single_irqindex(vbasedev, intp->pin); + vfio_device_irq_unmask(vbasedev, intp->pin); } /* a single IRQ can be active at a time */ @@ -356,8 +357,8 @@ static int vfio_set_resample_eventfd(VFIOINTp *intp) Error *err = NULL; qemu_set_fd_handler(fd, NULL, NULL, NULL); - if (!vfio_set_irq_signaling(vbasedev, intp->pin, 0, - VFIO_IRQ_SET_ACTION_UNMASK, fd, &err)) { + if (!vfio_device_irq_set_signaling(vbasedev, intp->pin, 0, + VFIO_IRQ_SET_ACTION_UNMASK, fd, &err)) { error_reportf_err(err, VFIO_MSG_PREFIX, vbasedev->name); return -EINVAL; } @@ -473,10 +474,10 @@ static bool vfio_populate_device(VFIODevice *vbasedev, Error **errp) QSIMPLEQ_INIT(&vdev->pending_intp_queue); for (i = 0; i < vbasedev->num_irqs; i++) { - struct vfio_irq_info irq = { .argsz = sizeof(irq) }; + struct vfio_irq_info irq; + + ret = vfio_device_get_irq_info(vbasedev, i, &irq); - irq.index = i; - ret = ioctl(vbasedev->fd, VFIO_DEVICE_GET_IRQ_INFO, &irq); if (ret) { error_setg_errno(errp, -ret, "failed to get device irq info"); goto irq_err; @@ -545,7 +546,7 @@ static bool vfio_base_device_init(VFIODevice *vbasedev, Error **errp) return false; } - if (!vfio_attach_device(vbasedev->name, vbasedev, + if (!vfio_device_attach(vbasedev->name, vbasedev, &address_space_memory, errp)) { return false; } @@ -554,7 +555,7 @@ static bool vfio_base_device_init(VFIODevice *vbasedev, Error **errp) return true; } - vfio_detach_device(vbasedev); + vfio_device_detach(vbasedev); return false; } @@ -658,7 +659,7 @@ static void vfio_platform_set_fd(Object *obj, const char *str, Error **errp) } #endif -static void vfio_platform_class_init(ObjectClass *klass, void *data) +static void vfio_platform_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass); diff --git a/hw/vfio/region.c b/hw/vfio/region.c new file mode 100644 index 0000000..d04c57d --- /dev/null +++ b/hw/vfio/region.c @@ -0,0 +1,403 @@ +/* + * VFIO regions + * + * Copyright Red Hat, Inc. 2012 + * + * Authors: + * Alex Williamson <alex.williamson@redhat.com> + * + * This work is licensed under the terms of the GNU GPL, version 2. See + * the COPYING file in the top-level directory. + * + * Based on qemu-kvm device-assignment: + * Adapted for KVM by Qumranet. + * Copyright (c) 2007, Neocleus, Alex Novik (alex@neocleus.com) + * Copyright (c) 2007, Neocleus, Guy Zana (guy@neocleus.com) + * Copyright (C) 2008, Qumranet, Amit Shah (amit.shah@qumranet.com) + * Copyright (C) 2008, Red Hat, Amit Shah (amit.shah@redhat.com) + * Copyright (C) 2008, IBM, Muli Ben-Yehuda (muli@il.ibm.com) + */ + +#include "qemu/osdep.h" +#include <sys/ioctl.h> + +#include "hw/vfio/vfio-region.h" +#include "hw/vfio/vfio-device.h" +#include "hw/hw.h" +#include "trace.h" +#include "qapi/error.h" +#include "qemu/error-report.h" +#include "qemu/units.h" +#include "monitor/monitor.h" +#include "vfio-helpers.h" + +/* + * IO Port/MMIO - Beware of the endians, VFIO is always little endian + */ +void vfio_region_write(void *opaque, hwaddr addr, + uint64_t data, unsigned size) +{ + VFIORegion *region = opaque; + VFIODevice *vbasedev = region->vbasedev; + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + uint64_t qword; + } buf; + int ret; + + switch (size) { + case 1: + buf.byte = data; + break; + case 2: + buf.word = cpu_to_le16(data); + break; + case 4: + buf.dword = cpu_to_le32(data); + break; + case 8: + buf.qword = cpu_to_le64(data); + break; + default: + hw_error("vfio: unsupported write size, %u bytes", size); + break; + } + + ret = vbasedev->io_ops->region_write(vbasedev, region->nr, + addr, size, &buf, region->post_wr); + if (ret != size) { + error_report("%s(%s:region%d+0x%"HWADDR_PRIx", 0x%"PRIx64 + ",%d) failed: %s", + __func__, vbasedev->name, region->nr, + addr, data, size, strwriteerror(ret)); + } + + trace_vfio_region_write(vbasedev->name, region->nr, addr, data, size); + + /* + * A read or write to a BAR always signals an INTx EOI. This will + * do nothing if not pending (including not in INTx mode). We assume + * that a BAR access is in response to an interrupt and that BAR + * accesses will service the interrupt. Unfortunately, we don't know + * which access will service the interrupt, so we're potentially + * getting quite a few host interrupts per guest interrupt. + */ + vbasedev->ops->vfio_eoi(vbasedev); +} + +uint64_t vfio_region_read(void *opaque, + hwaddr addr, unsigned size) +{ + VFIORegion *region = opaque; + VFIODevice *vbasedev = region->vbasedev; + union { + uint8_t byte; + uint16_t word; + uint32_t dword; + uint64_t qword; + } buf; + uint64_t data = 0; + int ret; + + ret = vbasedev->io_ops->region_read(vbasedev, region->nr, addr, size, &buf); + if (ret != size) { + error_report("%s(%s:region%d+0x%"HWADDR_PRIx", %d) failed: %s", + __func__, vbasedev->name, region->nr, + addr, size, strreaderror(ret)); + return (uint64_t)-1; + } + switch (size) { + case 1: + data = buf.byte; + break; + case 2: + data = le16_to_cpu(buf.word); + break; + case 4: + data = le32_to_cpu(buf.dword); + break; + case 8: + data = le64_to_cpu(buf.qword); + break; + default: + hw_error("vfio: unsupported read size, %u bytes", size); + break; + } + + trace_vfio_region_read(vbasedev->name, region->nr, addr, size, data); + + /* Same as write above */ + vbasedev->ops->vfio_eoi(vbasedev); + + return data; +} + +static const MemoryRegionOps vfio_region_ops = { + .read = vfio_region_read, + .write = vfio_region_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 1, + .max_access_size = 8, + }, + .impl = { + .min_access_size = 1, + .max_access_size = 8, + }, +}; + +static int vfio_setup_region_sparse_mmaps(VFIORegion *region, + struct vfio_region_info *info) +{ + struct vfio_info_cap_header *hdr; + struct vfio_region_info_cap_sparse_mmap *sparse; + int i, j; + + hdr = vfio_get_region_info_cap(info, VFIO_REGION_INFO_CAP_SPARSE_MMAP); + if (!hdr) { + return -ENODEV; + } + + sparse = container_of(hdr, struct vfio_region_info_cap_sparse_mmap, header); + + trace_vfio_region_sparse_mmap_header(region->vbasedev->name, + region->nr, sparse->nr_areas); + + region->mmaps = g_new0(VFIOMmap, sparse->nr_areas); + + for (i = 0, j = 0; i < sparse->nr_areas; i++) { + if (sparse->areas[i].size) { + trace_vfio_region_sparse_mmap_entry(i, sparse->areas[i].offset, + sparse->areas[i].offset + + sparse->areas[i].size - 1); + region->mmaps[j].offset = sparse->areas[i].offset; + region->mmaps[j].size = sparse->areas[i].size; + j++; + } + } + + region->nr_mmaps = j; + region->mmaps = g_realloc(region->mmaps, j * sizeof(VFIOMmap)); + + return 0; +} + +int vfio_region_setup(Object *obj, VFIODevice *vbasedev, VFIORegion *region, + int index, const char *name) +{ + struct vfio_region_info *info = NULL; + int ret; + + ret = vfio_device_get_region_info(vbasedev, index, &info); + if (ret) { + return ret; + } + + region->vbasedev = vbasedev; + region->flags = info->flags; + region->size = info->size; + region->fd_offset = info->offset; + region->nr = index; + region->post_wr = false; + + if (region->size) { + region->mem = g_new0(MemoryRegion, 1); + memory_region_init_io(region->mem, obj, &vfio_region_ops, + region, name, region->size); + + if (!vbasedev->no_mmap && + region->flags & VFIO_REGION_INFO_FLAG_MMAP) { + + ret = vfio_setup_region_sparse_mmaps(region, info); + + if (ret) { + region->nr_mmaps = 1; + region->mmaps = g_new0(VFIOMmap, region->nr_mmaps); + region->mmaps[0].offset = 0; + region->mmaps[0].size = region->size; + } + } + } + + trace_vfio_region_setup(vbasedev->name, index, name, + region->flags, region->fd_offset, region->size); + return 0; +} + +static void vfio_subregion_unmap(VFIORegion *region, int index) +{ + trace_vfio_region_unmap(memory_region_name(®ion->mmaps[index].mem), + region->mmaps[index].offset, + region->mmaps[index].offset + + region->mmaps[index].size - 1); + memory_region_del_subregion(region->mem, ®ion->mmaps[index].mem); + munmap(region->mmaps[index].mmap, region->mmaps[index].size); + object_unparent(OBJECT(®ion->mmaps[index].mem)); + region->mmaps[index].mmap = NULL; +} + +int vfio_region_mmap(VFIORegion *region) +{ + int i, ret, prot = 0; + char *name; + int fd; + + if (!region->mem) { + return 0; + } + + prot |= region->flags & VFIO_REGION_INFO_FLAG_READ ? PROT_READ : 0; + prot |= region->flags & VFIO_REGION_INFO_FLAG_WRITE ? PROT_WRITE : 0; + + for (i = 0; i < region->nr_mmaps; i++) { + size_t align = MIN(1ULL << ctz64(region->mmaps[i].size), 1 * GiB); + void *map_base, *map_align; + + /* + * Align the mmap for more efficient mapping in the kernel. Ideally + * we'd know the PMD and PUD mapping sizes to use as discrete alignment + * intervals, but we don't. As of Linux v6.12, the largest PUD size + * supporting huge pfnmap is 1GiB (ARCH_SUPPORTS_PUD_PFNMAP is only set + * on x86_64). Align by power-of-two size, capped at 1GiB. + * + * NB. qemu_memalign() and friends actually allocate memory, whereas + * the region size here can exceed host memory, therefore we manually + * create an oversized anonymous mapping and clean it up for alignment. + */ + map_base = mmap(0, region->mmaps[i].size + align, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + if (map_base == MAP_FAILED) { + ret = -errno; + goto no_mmap; + } + + fd = vfio_device_get_region_fd(region->vbasedev, region->nr); + + map_align = (void *)ROUND_UP((uintptr_t)map_base, (uintptr_t)align); + munmap(map_base, map_align - map_base); + munmap(map_align + region->mmaps[i].size, + align - (map_align - map_base)); + + region->mmaps[i].mmap = mmap(map_align, region->mmaps[i].size, prot, + MAP_SHARED | MAP_FIXED, fd, + region->fd_offset + + region->mmaps[i].offset); + if (region->mmaps[i].mmap == MAP_FAILED) { + ret = -errno; + goto no_mmap; + } + + name = g_strdup_printf("%s mmaps[%d]", + memory_region_name(region->mem), i); + memory_region_init_ram_device_ptr(®ion->mmaps[i].mem, + memory_region_owner(region->mem), + name, region->mmaps[i].size, + region->mmaps[i].mmap); + g_free(name); + memory_region_add_subregion(region->mem, region->mmaps[i].offset, + ®ion->mmaps[i].mem); + + trace_vfio_region_mmap(memory_region_name(®ion->mmaps[i].mem), + region->mmaps[i].offset, + region->mmaps[i].offset + + region->mmaps[i].size - 1); + } + + return 0; + +no_mmap: + trace_vfio_region_mmap_fault(memory_region_name(region->mem), i, + region->fd_offset + region->mmaps[i].offset, + region->fd_offset + region->mmaps[i].offset + + region->mmaps[i].size - 1, ret); + + region->mmaps[i].mmap = NULL; + + for (i--; i >= 0; i--) { + vfio_subregion_unmap(region, i); + } + + return ret; +} + +void vfio_region_unmap(VFIORegion *region) +{ + int i; + + if (!region->mem) { + return; + } + + for (i = 0; i < region->nr_mmaps; i++) { + if (region->mmaps[i].mmap) { + vfio_subregion_unmap(region, i); + } + } +} + +void vfio_region_exit(VFIORegion *region) +{ + int i; + + if (!region->mem) { + return; + } + + for (i = 0; i < region->nr_mmaps; i++) { + if (region->mmaps[i].mmap) { + memory_region_del_subregion(region->mem, ®ion->mmaps[i].mem); + } + } + + trace_vfio_region_exit(region->vbasedev->name, region->nr); +} + +void vfio_region_finalize(VFIORegion *region) +{ + int i; + + if (!region->mem) { + return; + } + + for (i = 0; i < region->nr_mmaps; i++) { + if (region->mmaps[i].mmap) { + munmap(region->mmaps[i].mmap, region->mmaps[i].size); + object_unparent(OBJECT(®ion->mmaps[i].mem)); + } + } + + object_unparent(OBJECT(region->mem)); + + g_free(region->mem); + g_free(region->mmaps); + + trace_vfio_region_finalize(region->vbasedev->name, region->nr); + + region->mem = NULL; + region->mmaps = NULL; + region->nr_mmaps = 0; + region->size = 0; + region->flags = 0; + region->nr = 0; +} + +void vfio_region_mmaps_set_enabled(VFIORegion *region, bool enabled) +{ + int i; + + if (!region->mem) { + return; + } + + for (i = 0; i < region->nr_mmaps; i++) { + if (region->mmaps[i].mmap) { + memory_region_set_enabled(®ion->mmaps[i].mem, enabled); + } + } + + trace_vfio_region_mmaps_set_enabled(memory_region_name(region->mem), + enabled); +} diff --git a/hw/vfio/spapr.c b/hw/vfio/spapr.c index 1a5d161..564b70e 100644 --- a/hw/vfio/spapr.c +++ b/hw/vfio/spapr.c @@ -13,19 +13,28 @@ #include <linux/vfio.h> #include "system/kvm.h" #include "system/hostmem.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" -#include "hw/vfio/vfio-common.h" +#include "hw/vfio/vfio-container.h" #include "hw/hw.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "qemu/error-report.h" #include "qapi/error.h" #include "trace.h" +#include "vfio-helpers.h" + +typedef struct VFIOHostDMAWindow { + hwaddr min_iova; + hwaddr max_iova; + uint64_t iova_pgsizes; + QLIST_ENTRY(VFIOHostDMAWindow) hostwin_next; +} VFIOHostDMAWindow; typedef struct VFIOSpaprContainer { VFIOContainer container; MemoryListener prereg_listener; QLIST_HEAD(, VFIOHostDMAWindow) hostwin_list; + unsigned int levels; } VFIOSpaprContainer; OBJECT_DECLARE_SIMPLE_TYPE(VFIOSpaprContainer, VFIO_IOMMU_SPAPR); @@ -230,15 +239,17 @@ static int vfio_spapr_remove_window(VFIOContainer *container, return 0; } -static int vfio_spapr_create_window(VFIOContainer *container, +static bool vfio_spapr_create_window(VFIOContainer *container, MemoryRegionSection *section, - hwaddr *pgsize) + hwaddr *pgsize, Error **errp) { int ret = 0; VFIOContainerBase *bcontainer = &container->bcontainer; + VFIOSpaprContainer *scontainer = container_of(container, VFIOSpaprContainer, + container); IOMMUMemoryRegion *iommu_mr = IOMMU_MEMORY_REGION(section->mr); uint64_t pagesize = memory_region_iommu_get_min_page_size(iommu_mr), pgmask; - unsigned entries, bits_total, bits_per_level, max_levels; + unsigned entries, bits_total, bits_per_level, max_levels, ddw_levels; struct vfio_iommu_spapr_tce_create create = { .argsz = sizeof(create) }; long rampagesize = qemu_minrampagesize(); @@ -252,11 +263,11 @@ static int vfio_spapr_create_window(VFIOContainer *container, pgmask = bcontainer->pgsizes & (pagesize | (pagesize - 1)); pagesize = pgmask ? (1ULL << (63 - clz64(pgmask))) : 0; if (!pagesize) { - error_report("Host doesn't support page size 0x%"PRIx64 - ", the supported mask is 0x%lx", - memory_region_iommu_get_min_page_size(iommu_mr), - bcontainer->pgsizes); - return -EINVAL; + error_setg_errno(errp, EINVAL, "Host doesn't support page size 0x%"PRIx64 + ", the supported mask is 0x%lx", + memory_region_iommu_get_min_page_size(iommu_mr), + bcontainer->pgsizes); + return false; } /* @@ -291,28 +302,41 @@ static int vfio_spapr_create_window(VFIOContainer *container, */ bits_per_level = ctz64(qemu_real_host_page_size()) + 8; create.levels = bits_total / bits_per_level; - if (bits_total % bits_per_level) { - ++create.levels; - } - max_levels = (64 - create.page_shift) / ctz64(qemu_real_host_page_size()); - for ( ; create.levels <= max_levels; ++create.levels) { - ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create); - if (!ret) { - break; + + ddw_levels = scontainer->levels; + if (ddw_levels > 1) { + if (bits_total % bits_per_level) { + ++create.levels; } + max_levels = (64 - create.page_shift) / ctz64(qemu_real_host_page_size()); + for ( ; create.levels <= max_levels; ++create.levels) { + ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create); + if (!ret) { + break; + } + } + } else { /* ddw_levels == 1 */ + if (create.levels > ddw_levels) { + error_setg_errno(errp, EINVAL, "Host doesn't support multi-level TCE tables" + ". Use larger IO page size. Supported mask is 0x%lx", + bcontainer->pgsizes); + return false; + } + ret = ioctl(container->fd, VFIO_IOMMU_SPAPR_TCE_CREATE, &create); } + if (ret) { - error_report("Failed to create a window, ret = %d (%m)", ret); - return -errno; + error_setg_errno(errp, errno, "Failed to create a window, ret = %d", ret); + return false; } if (create.start_addr != section->offset_within_address_space) { vfio_spapr_remove_window(container, create.start_addr); - error_report("Host doesn't support DMA window at %"HWADDR_PRIx", must be %"PRIx64, - section->offset_within_address_space, - (uint64_t)create.start_addr); - return -EINVAL; + error_setg_errno(errp, EINVAL, "Host doesn't support DMA window at %"HWADDR_PRIx + ", must be %"PRIx64, section->offset_within_address_space, + (uint64_t)create.start_addr); + return false; } trace_vfio_spapr_create_window(create.page_shift, create.levels, @@ -320,7 +344,7 @@ static int vfio_spapr_create_window(VFIOContainer *container, create.start_addr); *pgsize = pagesize; - return 0; + return true; } static bool @@ -377,9 +401,8 @@ vfio_spapr_container_add_section_window(VFIOContainerBase *bcontainer, } } - ret = vfio_spapr_create_window(container, section, &pgsize); - if (ret) { - error_setg_errno(errp, -ret, "Failed to create SPAPR window"); + ret = vfio_spapr_create_window(container, section, &pgsize, errp); + if (!ret) { return false; } @@ -502,6 +525,8 @@ static bool vfio_spapr_container_setup(VFIOContainerBase *bcontainer, goto listener_unregister_exit; } + scontainer->levels = info.ddw.levels; + if (v2) { bcontainer->pgsizes = info.ddw.pgsizes; /* @@ -534,7 +559,7 @@ listener_unregister_exit: return false; } -static void vfio_iommu_spapr_class_init(ObjectClass *klass, void *data) +static void vfio_iommu_spapr_class_init(ObjectClass *klass, const void *data) { VFIOIOMMUClass *vioc = VFIO_IOMMU_CLASS(klass); diff --git a/hw/vfio/trace-events b/hw/vfio/trace-events index 9347e3a..e1728c4 100644 --- a/hw/vfio/trace-events +++ b/hw/vfio/trace-events @@ -1,8 +1,10 @@ # See docs/devel/tracing.rst for syntax documentation. +# +# SPDX-License-Identifier: GPL-2.0-or-later # pci.c vfio_intx_interrupt(const char *name, char line) " (%s) Pin %c" -vfio_intx_eoi(const char *name) " (%s) EOI" +vfio_pci_intx_eoi(const char *name) " (%s) EOI" vfio_intx_enable_kvm(const char *name) " (%s) KVM INTx accel enabled" vfio_intx_disable_kvm(const char *name) " (%s) KVM INTx accel disabled" vfio_intx_update(const char *name, int new_irq, int target_irq) " (%s) IRQ moved %d -> %d" @@ -35,10 +37,8 @@ vfio_pci_hot_reset(const char *name, const char *type) " (%s) %s" vfio_pci_hot_reset_has_dep_devices(const char *name) "%s: hot reset dependent devices:" vfio_pci_hot_reset_dep_devices(int domain, int bus, int slot, int function, int group_id) "\t%04x:%02x:%02x.%x group %d" vfio_pci_hot_reset_result(const char *name, const char *result) "%s hot reset: %s" -vfio_populate_device_config(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device '%s' config: size: 0x%lx, offset: 0x%lx, flags: 0x%lx" -vfio_populate_device_get_irq_info_failure(const char *errstr) "VFIO_DEVICE_GET_IRQ_INFO failure: %s" -vfio_attach_device(const char *name, int group_id) " (%s) group %d" -vfio_detach_device(const char *name, int group_id) " (%s) group %d" +vfio_pci_populate_device_config(const char *name, unsigned long size, unsigned long offset, unsigned long flags) "Device '%s' config: size: 0x%lx, offset: 0x%lx, flags: 0x%lx" +vfio_pci_populate_device_get_irq_info_failure(const char *errstr) "VFIO_DEVICE_GET_IRQ_INFO failure: %s" vfio_mdev(const char *name, bool is_mdev) " (%s) is_mdev %d" vfio_add_ext_cap_dropped(const char *name, uint16_t cap, uint16_t offset) "%s 0x%x@0x%x" vfio_pci_reset(const char *name) " (%s)" @@ -89,9 +89,7 @@ vfio_pci_igd_bdsm_enabled(const char *name, int size) "%s %dMB" vfio_pci_igd_host_bridge_enabled(const char *name) "%s" vfio_pci_igd_lpc_bridge_enabled(const char *name) "%s" -# common.c -vfio_region_write(const char *name, int index, uint64_t addr, uint64_t data, unsigned size) " (%s:region%d+0x%"PRIx64", 0x%"PRIx64 ", %d)" -vfio_region_read(char *name, int index, uint64_t addr, unsigned size, uint64_t data) " (%s:region%d+0x%"PRIx64", %d) = 0x%"PRIx64 +# listener.c vfio_iommu_map_notify(const char *op, uint64_t iova_start, uint64_t iova_end) "iommu %s @ 0x%"PRIx64" - 0x%"PRIx64 vfio_listener_region_skip(const char *name, uint64_t start, uint64_t end) "SKIPPING %s 0x%"PRIx64" - 0x%"PRIx64 vfio_spapr_group_attach(int groupfd, int tablefd) "Attached groupfd %d to liobn fd %d" @@ -103,10 +101,21 @@ vfio_listener_region_add_no_dma_map(const char *name, uint64_t iova, uint64_t si vfio_listener_region_del(uint64_t start, uint64_t end) "region_del 0x%"PRIx64" - 0x%"PRIx64 vfio_device_dirty_tracking_update(uint64_t start, uint64_t end, uint64_t min, uint64_t max) "section 0x%"PRIx64" - 0x%"PRIx64" -> update [0x%"PRIx64" - 0x%"PRIx64"]" vfio_device_dirty_tracking_start(int nr_ranges, uint64_t min32, uint64_t max32, uint64_t min64, uint64_t max64, uint64_t minpci, uint64_t maxpci) "nr_ranges %d 32:[0x%"PRIx64" - 0x%"PRIx64"], 64:[0x%"PRIx64" - 0x%"PRIx64"], pci64:[0x%"PRIx64" - 0x%"PRIx64"]" -vfio_disconnect_container(int fd) "close container->fd=%d" -vfio_put_group(int fd) "close group->fd=%d" -vfio_get_device(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u" -vfio_put_base_device(int fd) "close vdev->fd=%d" +vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu dirty @ 0x%"PRIx64" - 0x%"PRIx64 + +# container-base.c +vfio_container_query_dirty_bitmap(uint64_t iova, uint64_t size, uint64_t bitmap_size, uint64_t start, uint64_t dirty_pages) "iova=0x%"PRIx64" size= 0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64" dirty_pages=%"PRIu64 + +# container.c +vfio_container_disconnect(int fd) "close container->fd=%d" +vfio_group_put(int fd) "close group->fd=%d" +vfio_device_get(const char * name, unsigned int flags, unsigned int num_regions, unsigned int num_irqs) "Device %s flags: %u, regions: %u, irqs: %u" +vfio_device_put(int fd) "close vdev->fd=%d" +vfio_legacy_dma_unmap_overflow_workaround(void) "" + +# region.c +vfio_region_write(const char *name, int index, uint64_t addr, uint64_t data, unsigned size) " (%s:region%d+0x%"PRIx64", 0x%"PRIx64 ", %d)" +vfio_region_read(char *name, int index, uint64_t addr, unsigned size, uint64_t data) " (%s:region%d+0x%"PRIx64", %d) = 0x%"PRIx64 vfio_region_setup(const char *dev, int index, const char *name, unsigned long flags, unsigned long offset, unsigned long size) "Device %s, region %d \"%s\", flags: 0x%lx, offset: 0x%lx, size: 0x%lx" vfio_region_mmap_fault(const char *name, int index, unsigned long offset, unsigned long size, int fault) "Region %s mmaps[%d], [0x%lx - 0x%lx], fault: %d" vfio_region_mmap(const char *name, unsigned long offset, unsigned long end) "Region %s [0x%lx - 0x%lx]" @@ -116,11 +125,6 @@ vfio_region_mmaps_set_enabled(const char *name, bool enabled) "Region %s mmaps e vfio_region_unmap(const char *name, unsigned long offset, unsigned long end) "Region %s unmap [0x%lx - 0x%lx]" vfio_region_sparse_mmap_header(const char *name, int index, int nr_areas) "Device %s region %d: %d sparse mmap entries" vfio_region_sparse_mmap_entry(int i, unsigned long start, unsigned long end) "sparse entry %d [0x%lx - 0x%lx]" -vfio_get_dev_region(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%08x" -vfio_legacy_dma_unmap_overflow_workaround(void) "" -vfio_get_dirty_bitmap(uint64_t iova, uint64_t size, uint64_t bitmap_size, uint64_t start, uint64_t dirty_pages) "iova=0x%"PRIx64" size= 0x%"PRIx64" bitmap_size=0x%"PRIx64" start=0x%"PRIx64" dirty_pages=%"PRIu64 -vfio_iommu_map_dirty_notify(uint64_t iova_start, uint64_t iova_end) "iommu dirty @ 0x%"PRIx64" - 0x%"PRIx64 -vfio_reset_handler(void) "" # platform.c vfio_platform_realize(char *name, char *compat) "vfio device %s, compat = %s" @@ -192,3 +196,9 @@ iommufd_cdev_fail_attach_existing_container(const char *msg) " %s" iommufd_cdev_alloc_ioas(int iommufd, int ioas_id) " [iommufd=%d] new IOMMUFD container with ioasid=%d" iommufd_cdev_device_info(char *name, int devfd, int num_irqs, int num_regions, int flags) " %s (%d) num_irqs=%d num_regions=%d flags=%d" iommufd_cdev_pci_hot_reset_dep_devices(int domain, int bus, int slot, int function, int dev_id) "\t%04x:%02x:%02x.%x devid %d" + +# device.c +vfio_device_get_region_info_type(const char *name, int index, uint32_t type, uint32_t subtype) "%s index %d, %08x/%08x" +vfio_device_reset_handler(void) "" +vfio_device_attach(const char *name, int group_id) " (%s) group %d" +vfio_device_detach(const char *name, int group_id) " (%s) group %d" diff --git a/hw/vfio/trace.h b/hw/vfio/trace.h index 5a343aa..b34b61d 100644 --- a/hw/vfio/trace.h +++ b/hw/vfio/trace.h @@ -1 +1,4 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "trace/trace-hw_vfio.h" diff --git a/hw/vfio/vfio-display.h b/hw/vfio/vfio-display.h new file mode 100644 index 0000000..2606c34 --- /dev/null +++ b/hw/vfio/vfio-display.h @@ -0,0 +1,42 @@ +/* + * VFIO display + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_DISPLAY_H +#define HW_VFIO_VFIO_DISPLAY_H + +#include "ui/console.h" +#include "hw/display/ramfb.h" +#include "hw/vfio/vfio-region.h" + +typedef struct VFIODMABuf { + QemuDmaBuf *buf; + uint32_t pos_x, pos_y, pos_updates; + uint32_t hot_x, hot_y, hot_updates; + int dmabuf_id; + QTAILQ_ENTRY(VFIODMABuf) next; +} VFIODMABuf; + +typedef struct VFIODisplay { + QemuConsole *con; + RAMFBState *ramfb; + struct vfio_region_info *edid_info; + struct vfio_region_gfx_edid *edid_regs; + uint8_t *edid_blob; + QEMUTimer *edid_link_timer; + struct { + VFIORegion buffer; + DisplaySurface *surface; + } region; + struct { + QTAILQ_HEAD(, VFIODMABuf) bufs; + VFIODMABuf *primary; + VFIODMABuf *cursor; + } dmabuf; +} VFIODisplay; + +#endif /* HW_VFIO_VFIO_DISPLAY_H */ diff --git a/hw/vfio/vfio-helpers.h b/hw/vfio/vfio-helpers.h new file mode 100644 index 0000000..54a327f --- /dev/null +++ b/hw/vfio/vfio-helpers.h @@ -0,0 +1,35 @@ +/* + * VFIO helpers + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_HELPERS_H +#define HW_VFIO_VFIO_HELPERS_H + +#ifdef CONFIG_LINUX +#include <linux/vfio.h> + +extern int vfio_kvm_device_fd; + +struct vfio_info_cap_header * +vfio_get_cap(void *ptr, uint32_t cap_offset, uint16_t id); +struct vfio_info_cap_header * +vfio_get_device_info_cap(struct vfio_device_info *info, uint16_t id); +struct vfio_info_cap_header * +vfio_get_region_info_cap(struct vfio_region_info *info, uint16_t id); +struct vfio_info_cap_header * +vfio_get_iommu_type1_info_cap(struct vfio_iommu_type1_info *info, uint16_t id); +bool vfio_get_info_dma_avail(struct vfio_iommu_type1_info *info, + unsigned int *avail); +#endif + +int vfio_bitmap_alloc(VFIOBitmap *vbmap, hwaddr size); +struct vfio_device_info *vfio_get_device_info(int fd); + +int vfio_kvm_device_add_fd(int fd, Error **errp); +int vfio_kvm_device_del_fd(int fd, Error **errp); + +#endif /* HW_VFIO_VFIO_HELPERS_H */ diff --git a/hw/vfio/vfio-iommufd.h b/hw/vfio/vfio-iommufd.h new file mode 100644 index 0000000..07ea0f4 --- /dev/null +++ b/hw/vfio/vfio-iommufd.h @@ -0,0 +1,34 @@ +/* + * VFIO iommufd + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_IOMMUFD_H +#define HW_VFIO_VFIO_IOMMUFD_H + +#include "hw/vfio/vfio-container-base.h" + +typedef struct VFIODevice VFIODevice; + +typedef struct VFIOIOASHwpt { + uint32_t hwpt_id; + uint32_t hwpt_flags; + QLIST_HEAD(, VFIODevice) device_list; + QLIST_ENTRY(VFIOIOASHwpt) next; +} VFIOIOASHwpt; + +typedef struct IOMMUFDBackend IOMMUFDBackend; + +typedef struct VFIOIOMMUFDContainer { + VFIOContainerBase bcontainer; + IOMMUFDBackend *be; + uint32_t ioas_id; + QLIST_HEAD(, VFIOIOASHwpt) hwpt_list; +} VFIOIOMMUFDContainer; + +OBJECT_DECLARE_SIMPLE_TYPE(VFIOIOMMUFDContainer, VFIO_IOMMU_IOMMUFD); + +#endif /* HW_VFIO_VFIO_IOMMUFD_H */ diff --git a/hw/vfio/vfio-listener.h b/hw/vfio/vfio-listener.h new file mode 100644 index 0000000..eb69ddd --- /dev/null +++ b/hw/vfio/vfio-listener.h @@ -0,0 +1,15 @@ +/* + * VFIO MemoryListener services + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_LISTENER_H +#define HW_VFIO_VFIO_LISTENER_H + +bool vfio_listener_register(VFIOContainerBase *bcontainer, Error **errp); +void vfio_listener_unregister(VFIOContainerBase *bcontainer); + +#endif /* HW_VFIO_VFIO_LISTENER_H */ diff --git a/hw/vfio/vfio-migration-internal.h b/hw/vfio/vfio-migration-internal.h new file mode 100644 index 0000000..a8b456b --- /dev/null +++ b/hw/vfio/vfio-migration-internal.h @@ -0,0 +1,74 @@ +/* + * VFIO migration + * + * Copyright Red Hat, Inc. 2025 + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#ifndef HW_VFIO_VFIO_MIGRATION_INTERNAL_H +#define HW_VFIO_VFIO_MIGRATION_INTERNAL_H + +#ifdef CONFIG_LINUX +#include <linux/vfio.h> +#endif + +#include "qemu/typedefs.h" +#include "qemu/notify.h" + +/* + * Flags to be used as unique delimiters for VFIO devices in the migration + * stream. These flags are composed as: + * 0xffffffff => MSB 32-bit all 1s + * 0xef10 => Magic ID, represents emulated (virtual) function IO + * 0x0000 => 16-bits reserved for flags + * + * The beginning of state information is marked by _DEV_CONFIG_STATE, + * _DEV_SETUP_STATE, or _DEV_DATA_STATE, respectively. The end of a + * certain state information is marked by _END_OF_STATE. + */ +#define VFIO_MIG_FLAG_END_OF_STATE (0xffffffffef100001ULL) +#define VFIO_MIG_FLAG_DEV_CONFIG_STATE (0xffffffffef100002ULL) +#define VFIO_MIG_FLAG_DEV_SETUP_STATE (0xffffffffef100003ULL) +#define VFIO_MIG_FLAG_DEV_DATA_STATE (0xffffffffef100004ULL) +#define VFIO_MIG_FLAG_DEV_INIT_DATA_SENT (0xffffffffef100005ULL) + +typedef struct VFIODevice VFIODevice; +typedef struct VFIOMultifd VFIOMultifd; + +typedef struct VFIOMigration { + struct VFIODevice *vbasedev; + VMChangeStateEntry *vm_state; + NotifierWithReturn migration_state; + uint32_t device_state; + int data_fd; + void *data_buffer; + size_t data_buffer_size; + uint64_t mig_flags; + uint64_t precopy_init_size; + uint64_t precopy_dirty_size; + bool multifd_transfer; + VFIOMultifd *multifd; + bool initial_data_sent; + + bool event_save_iterate_started; + bool event_precopy_empty_hit; +} VFIOMigration; + +bool vfio_migration_realize(VFIODevice *vbasedev, Error **errp); +void vfio_migration_exit(VFIODevice *vbasedev); +bool vfio_device_state_is_running(VFIODevice *vbasedev); +bool vfio_device_state_is_precopy(VFIODevice *vbasedev); +int vfio_save_device_config_state(QEMUFile *f, void *opaque, Error **errp); +int vfio_load_device_config_state(QEMUFile *f, void *opaque); + +#ifdef CONFIG_LINUX +int vfio_migration_set_state(VFIODevice *vbasedev, + enum vfio_device_mig_state new_state, + enum vfio_device_mig_state recover_state, + Error **errp); +#endif + +void vfio_migration_add_bytes_transferred(unsigned long val); + +#endif /* HW_VFIO_VFIO_MIGRATION_INTERNAL_H */ diff --git a/hw/virtio/vdpa-dev-pci.c b/hw/virtio/vdpa-dev-pci.c index 7879268..3068112 100644 --- a/hw/virtio/vdpa-dev-pci.c +++ b/hw/virtio/vdpa-dev-pci.c @@ -70,7 +70,8 @@ vhost_vdpa_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(DEVICE(&dev->vdev), BUS(&vpci_dev->bus), errp); } -static void vhost_vdpa_device_pci_class_init(ObjectClass *klass, void *data) +static void vhost_vdpa_device_pci_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vdpa-dev.c b/hw/virtio/vdpa-dev.c index a7e73b1..d1da40a 100644 --- a/hw/virtio/vdpa-dev.c +++ b/hw/virtio/vdpa-dev.c @@ -312,7 +312,7 @@ static void vhost_vdpa_device_stop(VirtIODevice *vdev) vhost_dev_disable_notifiers(&s->dev, vdev); } -static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) { VhostVdpaDevice *s = VHOST_VDPA_DEVICE(vdev); bool should_start = virtio_device_started(vdev, status); @@ -324,7 +324,7 @@ static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) } if (s->started == should_start) { - return; + return 0; } if (should_start) { @@ -335,6 +335,7 @@ static void vhost_vdpa_device_set_status(VirtIODevice *vdev, uint8_t status) } else { vhost_vdpa_device_stop(vdev); } + return 0; } static const Property vhost_vdpa_device_properties[] = { @@ -353,7 +354,7 @@ static const VMStateDescription vmstate_vhost_vdpa_device = { }, }; -static void vhost_vdpa_device_class_init(ObjectClass *klass, void *data) +static void vhost_vdpa_device_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-iova-tree.h b/hw/virtio/vhost-iova-tree.h index 0c4ba5a..08f63b6 100644 --- a/hw/virtio/vhost-iova-tree.h +++ b/hw/virtio/vhost-iova-tree.h @@ -11,7 +11,7 @@ #define HW_VIRTIO_VHOST_IOVA_TREE_H #include "qemu/iova-tree.h" -#include "exec/memory.h" +#include "system/memory.h" typedef struct VhostIOVATree VhostIOVATree; diff --git a/hw/virtio/vhost-scsi-pci.c b/hw/virtio/vhost-scsi-pci.c index 3778f61..7399ace 100644 --- a/hw/virtio/vhost-scsi-pci.c +++ b/hw/virtio/vhost-scsi-pci.c @@ -61,7 +61,7 @@ static void vhost_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_scsi_pci_class_init(ObjectClass *klass, void *data) +static void vhost_scsi_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-base.c b/hw/virtio/vhost-user-base.c index 2bc3423..ff67a02 100644 --- a/hw/virtio/vhost-user-base.c +++ b/hw/virtio/vhost-user-base.c @@ -66,7 +66,7 @@ err_host_notifiers: vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); } -static void vub_stop(VirtIODevice *vdev) +static int vub_stop(VirtIODevice *vdev) { VHostUserBase *vub = VHOST_USER_BASE(vdev); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -74,34 +74,39 @@ static void vub_stop(VirtIODevice *vdev) int ret; if (!k->set_guest_notifiers) { - return; + return 0; } - vhost_dev_stop(&vub->vhost_dev, vdev, true); + ret = vhost_dev_stop(&vub->vhost_dev, vdev, true); - ret = k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, vub->vhost_dev.nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } vhost_dev_disable_notifiers(&vub->vhost_dev, vdev); + return ret; } -static void vub_set_status(VirtIODevice *vdev, uint8_t status) +static int vub_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserBase *vub = VHOST_USER_BASE(vdev); bool should_start = virtio_device_should_start(vdev, status); if (vhost_dev_is_started(&vub->vhost_dev) == should_start) { - return; + return 0; } if (should_start) { vub_start(vdev); } else { - vub_stop(vdev); + int ret; + ret = vub_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } /* @@ -348,7 +353,7 @@ static void vub_device_unrealize(DeviceState *dev) do_vhost_user_cleanup(vdev, vub); } -static void vub_class_init(ObjectClass *klass, void *data) +static void vub_class_init(ObjectClass *klass, const void *data) { VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-user-blk-pci.c b/hw/virtio/vhost-user-blk-pci.c index 1767ef2..904369f 100644 --- a/hw/virtio/vhost-user-blk-pci.c +++ b/hw/virtio/vhost-user-blk-pci.c @@ -65,7 +65,7 @@ static void vhost_user_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_blk_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_blk_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-device-pci.c b/hw/virtio/vhost-user-device-pci.c index efaf55d..f10bac8 100644 --- a/hw/virtio/vhost-user-device-pci.c +++ b/hw/virtio/vhost-user-device-pci.c @@ -31,7 +31,8 @@ static void vhost_user_device_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_device_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_device_pci_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-device.c b/hw/virtio/vhost-user-device.c index 86eba13..3939bdf 100644 --- a/hw/virtio/vhost-user-device.c +++ b/hw/virtio/vhost-user-device.c @@ -37,7 +37,7 @@ static const Property vud_properties[] = { DEFINE_PROP_UINT32("config_size", VHostUserBase, config_size, 0), }; -static void vud_class_init(ObjectClass *klass, void *data) +static void vud_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-user-fs-pci.c b/hw/virtio/vhost-user-fs-pci.c index 116eaab..1490c11 100644 --- a/hw/virtio/vhost-user-fs-pci.c +++ b/hw/virtio/vhost-user-fs-pci.c @@ -47,7 +47,7 @@ static void vhost_user_fs_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_fs_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_fs_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-fs.c b/hw/virtio/vhost-user-fs.c index 0e8d4b3..e77c69e 100644 --- a/hw/virtio/vhost-user-fs.c +++ b/hw/virtio/vhost-user-fs.c @@ -100,7 +100,7 @@ err_host_notifiers: vhost_dev_disable_notifiers(&fs->vhost_dev, vdev); } -static void vuf_stop(VirtIODevice *vdev) +static int vuf_stop(VirtIODevice *vdev) { VHostUserFS *fs = VHOST_USER_FS(vdev); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -108,34 +108,39 @@ static void vuf_stop(VirtIODevice *vdev) int ret; if (!k->set_guest_notifiers) { - return; + return 0; } - vhost_dev_stop(&fs->vhost_dev, vdev, true); + ret = vhost_dev_stop(&fs->vhost_dev, vdev, true); - ret = k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, fs->vhost_dev.nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } vhost_dev_disable_notifiers(&fs->vhost_dev, vdev); + return ret; } -static void vuf_set_status(VirtIODevice *vdev, uint8_t status) +static int vuf_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserFS *fs = VHOST_USER_FS(vdev); bool should_start = virtio_device_should_start(vdev, status); if (vhost_dev_is_started(&fs->vhost_dev) == should_start) { - return; + return 0; } if (should_start) { vuf_start(vdev); } else { - vuf_stop(vdev); + int ret; + ret = vuf_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } static uint64_t vuf_get_features(VirtIODevice *vdev, @@ -418,7 +423,7 @@ static void vuf_instance_init(Object *obj) "/filesystem@0", DEVICE(obj)); } -static void vuf_class_init(ObjectClass *klass, void *data) +static void vuf_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-user-gpio-pci.c b/hw/virtio/vhost-user-gpio-pci.c index b3028a2..9b165b5 100644 --- a/hw/virtio/vhost-user-gpio-pci.c +++ b/hw/virtio/vhost-user-gpio-pci.c @@ -32,7 +32,7 @@ static void vhost_user_gpio_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_gpio_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_gpio_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-gpio.c b/hw/virtio/vhost-user-gpio.c index 4a08814..a7fd49b 100644 --- a/hw/virtio/vhost-user-gpio.c +++ b/hw/virtio/vhost-user-gpio.c @@ -36,7 +36,7 @@ static const VMStateDescription vu_gpio_vmstate = { .unmigratable = 1, }; -static void vu_gpio_class_init(ObjectClass *klass, void *data) +static void vu_gpio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); diff --git a/hw/virtio/vhost-user-i2c-pci.c b/hw/virtio/vhost-user-i2c-pci.c index 00ac109..692cd66 100644 --- a/hw/virtio/vhost-user-i2c-pci.c +++ b/hw/virtio/vhost-user-i2c-pci.c @@ -32,7 +32,7 @@ static void vhost_user_i2c_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_i2c_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_i2c_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-i2c.c b/hw/virtio/vhost-user-i2c.c index 1c7cde5..ae007fe 100644 --- a/hw/virtio/vhost-user-i2c.c +++ b/hw/virtio/vhost-user-i2c.c @@ -36,7 +36,7 @@ static const VMStateDescription vu_i2c_vmstate = { .unmigratable = 1, }; -static void vu_i2c_class_init(ObjectClass *klass, void *data) +static void vu_i2c_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); diff --git a/hw/virtio/vhost-user-input.c b/hw/virtio/vhost-user-input.c index 9174053..5cfc5bb 100644 --- a/hw/virtio/vhost-user-input.c +++ b/hw/virtio/vhost-user-input.c @@ -30,7 +30,7 @@ static const VMStateDescription vmstate_vhost_input = { .unmigratable = 1, }; -static void vhost_input_class_init(ObjectClass *klass, void *data) +static void vhost_input_class_init(ObjectClass *klass, const void *data) { VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-user-rng-pci.c b/hw/virtio/vhost-user-rng-pci.c index a4e6901..9f45fc6 100644 --- a/hw/virtio/vhost-user-rng-pci.c +++ b/hw/virtio/vhost-user-rng-pci.c @@ -40,7 +40,7 @@ static void vhost_user_rng_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_rng_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_rng_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-rng.c b/hw/virtio/vhost-user-rng.c index 5aa432e..61dadcd 100644 --- a/hw/virtio/vhost-user-rng.c +++ b/hw/virtio/vhost-user-rng.c @@ -37,7 +37,7 @@ static void vu_rng_base_realize(DeviceState *dev, Error **errp) vubs->parent_realize(dev, errp); } -static void vu_rng_class_init(ObjectClass *klass, void *data) +static void vu_rng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); diff --git a/hw/virtio/vhost-user-scmi-pci.c b/hw/virtio/vhost-user-scmi-pci.c index 7f53af7..0ab56a5 100644 --- a/hw/virtio/vhost-user-scmi-pci.c +++ b/hw/virtio/vhost-user-scmi-pci.c @@ -31,7 +31,7 @@ static void vhost_user_scmi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_scmi_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_scmi_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-scmi.c b/hw/virtio/vhost-user-scmi.c index 04cd36d..f9264c4 100644 --- a/hw/virtio/vhost-user-scmi.c +++ b/hw/virtio/vhost-user-scmi.c @@ -83,7 +83,7 @@ err_host_notifiers: return ret; } -static void vu_scmi_stop(VirtIODevice *vdev) +static int vu_scmi_stop(VirtIODevice *vdev) { VHostUserSCMI *scmi = VHOST_USER_SCMI(vdev); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -93,41 +93,46 @@ static void vu_scmi_stop(VirtIODevice *vdev) /* vhost_dev_is_started() check in the callers is not fully reliable. */ if (!scmi->started_vu) { - return; + return 0; } scmi->started_vu = false; if (!k->set_guest_notifiers) { - return; + return 0; } - vhost_dev_stop(vhost_dev, vdev, true); + ret = vhost_dev_stop(vhost_dev, vdev, true); - ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } vhost_dev_disable_notifiers(vhost_dev, vdev); + return ret; } -static void vu_scmi_set_status(VirtIODevice *vdev, uint8_t status) +static int vu_scmi_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserSCMI *scmi = VHOST_USER_SCMI(vdev); bool should_start = virtio_device_should_start(vdev, status); if (!scmi->connected) { - return; + return -1; } if (vhost_dev_is_started(&scmi->vhost_dev) == should_start) { - return; + return 0; } if (should_start) { vu_scmi_start(vdev); } else { - vu_scmi_stop(vdev); + int ret; + ret = vu_scmi_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } static uint64_t vu_scmi_get_features(VirtIODevice *vdev, uint64_t features, @@ -279,7 +284,7 @@ static const Property vu_scmi_properties[] = { DEFINE_PROP_CHR("chardev", VHostUserSCMI, chardev), }; -static void vu_scmi_class_init(ObjectClass *klass, void *data) +static void vu_scmi_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-user-scsi-pci.c b/hw/virtio/vhost-user-scsi-pci.c index 4a4128d..994e51a 100644 --- a/hw/virtio/vhost-user-scsi-pci.c +++ b/hw/virtio/vhost-user-scsi-pci.c @@ -67,7 +67,7 @@ static void vhost_user_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_scsi_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_scsi_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-snd-pci.c b/hw/virtio/vhost-user-snd-pci.c index 0cb86b7..f5015fb 100644 --- a/hw/virtio/vhost-user-snd-pci.c +++ b/hw/virtio/vhost-user-snd-pci.c @@ -33,7 +33,7 @@ static void vhost_user_snd_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_snd_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_snd_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-snd.c b/hw/virtio/vhost-user-snd.c index b414c75..732411c 100644 --- a/hw/virtio/vhost-user-snd.c +++ b/hw/virtio/vhost-user-snd.c @@ -54,7 +54,7 @@ static void vu_snd_base_realize(DeviceState *dev, Error **errp) vubs->parent_realize(dev, errp); } -static void vu_snd_class_init(ObjectClass *klass, void *data) +static void vu_snd_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VHostUserBaseClass *vubc = VHOST_USER_BASE_CLASS(klass); diff --git a/hw/virtio/vhost-user-vsock-pci.c b/hw/virtio/vhost-user-vsock-pci.c index f730a05..adb877b 100644 --- a/hw/virtio/vhost-user-vsock-pci.c +++ b/hw/virtio/vhost-user-vsock-pci.c @@ -46,7 +46,8 @@ static void vhost_user_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_user_vsock_pci_class_init(ObjectClass *klass, void *data) +static void vhost_user_vsock_pci_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-user-vsock.c b/hw/virtio/vhost-user-vsock.c index d21cd4b..993c287 100644 --- a/hw/virtio/vhost-user-vsock.c +++ b/hw/virtio/vhost-user-vsock.c @@ -54,23 +54,28 @@ const VhostDevConfigOps vsock_ops = { .vhost_dev_config_notifier = vuv_handle_config_change, }; -static void vuv_set_status(VirtIODevice *vdev, uint8_t status) +static int vuv_set_status(VirtIODevice *vdev, uint8_t status) { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); bool should_start = virtio_device_should_start(vdev, status); + int ret; if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) { - return; + return 0; } if (should_start) { - int ret = vhost_vsock_common_start(vdev); + ret = vhost_vsock_common_start(vdev); if (ret < 0) { - return; + return ret; } } else { - vhost_vsock_common_stop(vdev); + ret = vhost_vsock_common_stop(vdev); + if (ret < 0) { + return ret; + } } + return 0; } static uint64_t vuv_get_features(VirtIODevice *vdev, @@ -151,7 +156,7 @@ static const Property vuv_properties[] = { DEFINE_PROP_CHR("chardev", VHostUserVSock, conf.chardev), }; -static void vuv_class_init(ObjectClass *klass, void *data) +static void vuv_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c index fdc01ab..1e1d6b0 100644 --- a/hw/virtio/vhost-user.c +++ b/hw/virtio/vhost-user.c @@ -28,7 +28,7 @@ #include "system/cryptodev.h" #include "migration/postcopy-ram.h" #include "trace.h" -#include "exec/ramblock.h" +#include "system/ramblock.h" #include <sys/ioctl.h> #include <sys/socket.h> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c index 8b45756..7061b6e 100644 --- a/hw/virtio/vhost-vdpa.c +++ b/hw/virtio/vhost-vdpa.c @@ -20,7 +20,7 @@ #include "hw/virtio/virtio-net.h" #include "hw/virtio/vhost-shadow-virtqueue.h" #include "hw/virtio/vhost-vdpa.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "migration/blocker.h" #include "qemu/cutils.h" #include "qemu/main-loop.h" @@ -209,6 +209,8 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) int ret; Int128 llend; Error *local_err = NULL; + MemoryRegion *mr; + hwaddr xlat; if (iotlb->target_as != &address_space_memory) { error_report("Wrong target AS \"%s\", only system memory is allowed", @@ -228,11 +230,14 @@ static void vhost_vdpa_iommu_map_notify(IOMMUNotifier *n, IOMMUTLBEntry *iotlb) if ((iotlb->perm & IOMMU_RW) != IOMMU_NONE) { bool read_only; - if (!memory_get_xlat_addr(iotlb, &vaddr, NULL, &read_only, NULL, - &local_err)) { + mr = memory_translate_iotlb(iotlb, &xlat, &local_err); + if (!mr) { error_report_err(local_err); return; } + vaddr = memory_region_get_ram_ptr(mr) + xlat; + read_only = !(iotlb->perm & IOMMU_WO) || mr->readonly; + ret = vhost_vdpa_dma_map(s, VHOST_VDPA_GUEST_PA_ASID, iova, iotlb->addr_mask + 1, vaddr, read_only); if (ret) { @@ -594,6 +599,36 @@ static void vhost_vdpa_init_svq(struct vhost_dev *hdev, struct vhost_vdpa *v) v->shadow_vqs = g_steal_pointer(&shadow_vqs); } +static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) +{ + struct vhost_vdpa *v = dev->opaque; + + uint64_t features; + uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 | + 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH | + 0x1ULL << VHOST_BACKEND_F_IOTLB_ASID | + 0x1ULL << VHOST_BACKEND_F_SUSPEND; + int r; + + if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) { + return -EFAULT; + } + + features &= f; + + if (vhost_vdpa_first_dev(dev)) { + r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features); + if (r) { + return -EFAULT; + } + } + + dev->backend_cap = features; + v->shared->backend_cap = features; + + return 0; +} + static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) { struct vhost_vdpa *v = opaque; @@ -603,7 +638,12 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) v->dev = dev; dev->opaque = opaque ; - v->shared->listener = vhost_vdpa_memory_listener; + + ret = vhost_vdpa_set_backend_cap(dev); + if (unlikely(ret != 0)) { + return ret; + } + vhost_vdpa_init_svq(dev, v); error_propagate(&dev->migration_blocker, v->migration_blocker); @@ -639,6 +679,7 @@ static int vhost_vdpa_init(struct vhost_dev *dev, void *opaque, Error **errp) vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER); + v->shared->listener = vhost_vdpa_memory_listener; return 0; } @@ -841,36 +882,6 @@ static int vhost_vdpa_set_features(struct vhost_dev *dev, return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_FEATURES_OK); } -static int vhost_vdpa_set_backend_cap(struct vhost_dev *dev) -{ - struct vhost_vdpa *v = dev->opaque; - - uint64_t features; - uint64_t f = 0x1ULL << VHOST_BACKEND_F_IOTLB_MSG_V2 | - 0x1ULL << VHOST_BACKEND_F_IOTLB_BATCH | - 0x1ULL << VHOST_BACKEND_F_IOTLB_ASID | - 0x1ULL << VHOST_BACKEND_F_SUSPEND; - int r; - - if (vhost_vdpa_call(dev, VHOST_GET_BACKEND_FEATURES, &features)) { - return -EFAULT; - } - - features &= f; - - if (vhost_vdpa_first_dev(dev)) { - r = vhost_vdpa_call(dev, VHOST_SET_BACKEND_FEATURES, &features); - if (r) { - return -EFAULT; - } - } - - dev->backend_cap = features; - v->shared->backend_cap = features; - - return 0; -} - static int vhost_vdpa_get_device_id(struct vhost_dev *dev, uint32_t *device_id) { @@ -888,8 +899,14 @@ static int vhost_vdpa_reset_device(struct vhost_dev *dev) ret = vhost_vdpa_call(dev, VHOST_VDPA_SET_STATUS, &status); trace_vhost_vdpa_reset_device(dev); + if (ret) { + return ret; + } + + memory_listener_unregister(&v->shared->listener); + v->shared->listener_registered = false; v->suspended = false; - return ret; + return 0; } static int vhost_vdpa_get_vq_index(struct vhost_dev *dev, int idx) @@ -1373,7 +1390,15 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) "IOMMU and try again"); return -1; } - memory_listener_register(&v->shared->listener, dev->vdev->dma_as); + if (v->shared->listener_registered && + dev->vdev->dma_as != v->shared->listener.address_space) { + memory_listener_unregister(&v->shared->listener); + v->shared->listener_registered = false; + } + if (!v->shared->listener_registered) { + memory_listener_register(&v->shared->listener, dev->vdev->dma_as); + v->shared->listener_registered = true; + } return vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_DRIVER_OK); } @@ -1383,8 +1408,6 @@ static int vhost_vdpa_dev_start(struct vhost_dev *dev, bool started) static void vhost_vdpa_reset_status(struct vhost_dev *dev) { - struct vhost_vdpa *v = dev->opaque; - if (!vhost_vdpa_last_dev(dev)) { return; } @@ -1392,7 +1415,6 @@ static void vhost_vdpa_reset_status(struct vhost_dev *dev) vhost_vdpa_reset_device(dev); vhost_vdpa_add_status(dev, VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER); - memory_listener_unregister(&v->shared->listener); } static int vhost_vdpa_set_log_base(struct vhost_dev *dev, uint64_t base, @@ -1526,12 +1548,27 @@ static int vhost_vdpa_get_features(struct vhost_dev *dev, static int vhost_vdpa_set_owner(struct vhost_dev *dev) { + int r; + struct vhost_vdpa *v; + if (!vhost_vdpa_first_dev(dev)) { return 0; } trace_vhost_vdpa_set_owner(dev); - return vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL); + r = vhost_vdpa_call(dev, VHOST_SET_OWNER, NULL); + if (unlikely(r < 0)) { + return r; + } + + /* + * Being optimistic and listening address space memory. If the device + * uses vIOMMU, it is changed at vhost_vdpa_dev_start. + */ + v = dev->opaque; + memory_listener_register(&v->shared->listener, &address_space_memory); + v->shared->listener_registered = true; + return 0; } static int vhost_vdpa_vq_get_addr(struct vhost_dev *dev, @@ -1563,7 +1600,6 @@ const VhostOps vdpa_ops = { .vhost_set_vring_kick = vhost_vdpa_set_vring_kick, .vhost_set_vring_call = vhost_vdpa_set_vring_call, .vhost_get_features = vhost_vdpa_get_features, - .vhost_set_backend_cap = vhost_vdpa_set_backend_cap, .vhost_set_owner = vhost_vdpa_set_owner, .vhost_set_vring_endian = NULL, .vhost_backend_memslots_limit = vhost_vdpa_memslots_limit, diff --git a/hw/virtio/vhost-vsock-common.c b/hw/virtio/vhost-vsock-common.c index 9ac587d..c6c44d8 100644 --- a/hw/virtio/vhost-vsock-common.c +++ b/hw/virtio/vhost-vsock-common.c @@ -95,7 +95,7 @@ err_host_notifiers: return ret; } -void vhost_vsock_common_stop(VirtIODevice *vdev) +int vhost_vsock_common_stop(VirtIODevice *vdev) { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); @@ -103,18 +103,18 @@ void vhost_vsock_common_stop(VirtIODevice *vdev) int ret; if (!k->set_guest_notifiers) { - return; + return 0; } - vhost_dev_stop(&vvc->vhost_dev, vdev, true); + ret = vhost_dev_stop(&vvc->vhost_dev, vdev, true); - ret = k->set_guest_notifiers(qbus->parent, vvc->vhost_dev.nvqs, false); - if (ret < 0) { + if (k->set_guest_notifiers(qbus->parent, vvc->vhost_dev.nvqs, false) < 0) { error_report("vhost guest notifier cleanup failed: %d", ret); - return; + return -1; } vhost_dev_disable_notifiers(&vvc->vhost_dev, vdev); + return ret; } @@ -290,7 +290,7 @@ static const Property vhost_vsock_common_properties[] = { ON_OFF_AUTO_AUTO), }; -static void vhost_vsock_common_class_init(ObjectClass *klass, void *data) +static void vhost_vsock_common_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost-vsock-pci.c b/hw/virtio/vhost-vsock-pci.c index 6c618ee..0022a71 100644 --- a/hw/virtio/vhost-vsock-pci.c +++ b/hw/virtio/vhost-vsock-pci.c @@ -56,7 +56,7 @@ static void vhost_vsock_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void vhost_vsock_pci_class_init(ObjectClass *klass, void *data) +static void vhost_vsock_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/vhost-vsock.c b/hw/virtio/vhost-vsock.c index 940b30f..6e40888 100644 --- a/hw/virtio/vhost-vsock.c +++ b/hw/virtio/vhost-vsock.c @@ -67,37 +67,38 @@ static int vhost_vsock_set_running(VirtIODevice *vdev, int start) } -static void vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status) +static int vhost_vsock_set_status(VirtIODevice *vdev, uint8_t status) { VHostVSockCommon *vvc = VHOST_VSOCK_COMMON(vdev); bool should_start = virtio_device_should_start(vdev, status); int ret; if (vhost_dev_is_started(&vvc->vhost_dev) == should_start) { - return; + return 0; } if (should_start) { ret = vhost_vsock_common_start(vdev); if (ret < 0) { - return; + return 0; } ret = vhost_vsock_set_running(vdev, 1); if (ret < 0) { vhost_vsock_common_stop(vdev); error_report("Error starting vhost vsock: %d", -ret); - return; + return 0; } } else { ret = vhost_vsock_set_running(vdev, 0); if (ret < 0) { error_report("vhost vsock set running failed: %d", ret); - return; + return 0; } vhost_vsock_common_stop(vdev); } + return 0; } static uint64_t vhost_vsock_get_features(VirtIODevice *vdev, @@ -210,7 +211,7 @@ static const Property vhost_vsock_properties[] = { DEFINE_PROP_STRING("vhostfd", VHostVSock, conf.vhostfd), }; -static void vhost_vsock_class_init(ObjectClass *klass, void *data) +static void vhost_vsock_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c index 4cae7c1..fc43853 100644 --- a/hw/virtio/vhost.c +++ b/hw/virtio/vhost.c @@ -1367,10 +1367,10 @@ fail_alloc_desc: return r; } -void vhost_virtqueue_stop(struct vhost_dev *dev, - struct VirtIODevice *vdev, - struct vhost_virtqueue *vq, - unsigned idx) +int vhost_virtqueue_stop(struct vhost_dev *dev, + struct VirtIODevice *vdev, + struct vhost_virtqueue *vq, + unsigned idx) { int vhost_vq_index = dev->vhost_ops->vhost_get_vq_index(dev, idx); struct vhost_vring_state state = { @@ -1380,7 +1380,7 @@ void vhost_virtqueue_stop(struct vhost_dev *dev, if (virtio_queue_get_desc_addr(vdev, idx) == 0) { /* Don't stop the virtqueue which might have not been started */ - return; + return 0; } r = dev->vhost_ops->vhost_get_vring_base(dev, &state); @@ -1411,6 +1411,7 @@ void vhost_virtqueue_stop(struct vhost_dev *dev, 0, virtio_queue_get_avail_size(vdev, idx)); vhost_memory_unmap(dev, vq->desc, virtio_queue_get_desc_size(vdev, idx), 0, virtio_queue_get_desc_size(vdev, idx)); + return r; } static int vhost_virtqueue_set_busyloop_timeout(struct vhost_dev *dev, @@ -2135,9 +2136,10 @@ fail_features: } /* Host notifiers must be enabled at this point. */ -void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) +int vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) { int i; + int rc = 0; /* should only be called after backend is connected */ assert(hdev->vhost_ops); @@ -2156,10 +2158,10 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) vhost_dev_set_vring_enable(hdev, false); } for (i = 0; i < hdev->nvqs; ++i) { - vhost_virtqueue_stop(hdev, - vdev, - hdev->vqs + i, - hdev->vq_index + i); + rc |= vhost_virtqueue_stop(hdev, + vdev, + hdev->vqs + i, + hdev->vq_index + i); } if (hdev->vhost_ops->vhost_reset_status) { hdev->vhost_ops->vhost_reset_status(hdev); @@ -2176,6 +2178,7 @@ void vhost_dev_stop(struct vhost_dev *hdev, VirtIODevice *vdev, bool vrings) hdev->started = false; vdev->vhost_started = false; hdev->vdev = NULL; + return rc; } int vhost_net_set_backend(struct vhost_dev *hdev, diff --git a/hw/virtio/virtio-9p-pci.c b/hw/virtio/virtio-9p-pci.c index aa1dce8..594742f 100644 --- a/hw/virtio/virtio-9p-pci.c +++ b/hw/virtio/virtio-9p-pci.c @@ -49,7 +49,7 @@ static const Property virtio_9p_pci_properties[] = { DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), }; -static void virtio_9p_pci_class_init(ObjectClass *klass, void *data) +static void virtio_9p_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-balloon-pci.c b/hw/virtio/virtio-balloon-pci.c index db7e1cb..96e88b6 100644 --- a/hw/virtio/virtio-balloon-pci.c +++ b/hw/virtio/virtio-balloon-pci.c @@ -55,7 +55,7 @@ static void virtio_balloon_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_balloon_pci_class_init(ObjectClass *klass, void *data) +static void virtio_balloon_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 2eb5a14..db787d0 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -24,7 +24,7 @@ #include "hw/boards.h" #include "system/balloon.h" #include "hw/virtio/virtio-balloon.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" #include "qapi/error.h" #include "qapi/qapi-events-machine.h" #include "qapi/visitor.h" @@ -958,7 +958,7 @@ static void virtio_balloon_device_reset(VirtIODevice *vdev) s->poison_val = 0; } -static void virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status) { VirtIOBalloon *s = VIRTIO_BALLOON(vdev); @@ -988,6 +988,7 @@ static void virtio_balloon_set_status(VirtIODevice *vdev, uint8_t status) qemu_mutex_unlock(&s->free_page_lock); } } + return 0; } static ResettableState *virtio_balloon_get_reset_state(Object *obj) @@ -1058,7 +1059,7 @@ static const Property virtio_balloon_properties[] = { IOThread *), }; -static void virtio_balloon_class_init(ObjectClass *klass, void *data) +static void virtio_balloon_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-blk-pci.c b/hw/virtio/virtio-blk-pci.c index fc06cec..fd33bbd 100644 --- a/hw/virtio/virtio-blk-pci.c +++ b/hw/virtio/virtio-blk-pci.c @@ -63,7 +63,7 @@ static void virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_blk_pci_class_init(ObjectClass *klass, void *data) +static void virtio_blk_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c index 896feb3..11adfbf 100644 --- a/hw/virtio/virtio-bus.c +++ b/hw/virtio/virtio-bus.c @@ -28,7 +28,7 @@ #include "qapi/error.h" #include "hw/virtio/virtio-bus.h" #include "hw/virtio/virtio.h" -#include "exec/address-spaces.h" +#include "system/address-spaces.h" /* #define DEBUG_VIRTIO_BUS */ @@ -348,7 +348,7 @@ bool virtio_bus_device_iommu_enabled(VirtIODevice *vdev) return klass->iommu_enabled(qbus->parent); } -static void virtio_bus_class_init(ObjectClass *klass, void *data) +static void virtio_bus_class_init(ObjectClass *klass, const void *data) { BusClass *bus_class = BUS_CLASS(klass); bus_class->get_dev_path = virtio_bus_get_dev_path; diff --git a/hw/virtio/virtio-crypto-pci.c b/hw/virtio/virtio-crypto-pci.c index 8699481..868abc0 100644 --- a/hw/virtio/virtio-crypto-pci.c +++ b/hw/virtio/virtio-crypto-pci.c @@ -59,7 +59,7 @@ static void virtio_crypto_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) } } -static void virtio_crypto_pci_class_init(ObjectClass *klass, void *data) +static void virtio_crypto_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-crypto.c b/hw/virtio/virtio-crypto.c index a1b3c90..517f208 100644 --- a/hw/virtio/virtio-crypto.c +++ b/hw/virtio/virtio-crypto.c @@ -1197,11 +1197,12 @@ static void virtio_crypto_vhost_status(VirtIOCrypto *c, uint8_t status) } } -static void virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_crypto_set_status(VirtIODevice *vdev, uint8_t status) { VirtIOCrypto *vcrypto = VIRTIO_CRYPTO(vdev); virtio_crypto_vhost_status(vcrypto, status); + return 0; } static void virtio_crypto_guest_notifier_mask(VirtIODevice *vdev, int idx, @@ -1264,7 +1265,7 @@ static struct vhost_dev *virtio_crypto_get_vhost(VirtIODevice *vdev) return &vhost_crypto->dev; } -static void virtio_crypto_class_init(ObjectClass *klass, void *data) +static void virtio_crypto_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-input-pci.c b/hw/virtio/virtio-input-pci.c index 9e3c106..3be5358 100644 --- a/hw/virtio/virtio-input-pci.c +++ b/hw/virtio/virtio-input-pci.c @@ -50,7 +50,7 @@ static void virtio_input_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_input_pci_class_init(ObjectClass *klass, void *data) +static void virtio_input_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); @@ -63,7 +63,8 @@ static void virtio_input_pci_class_init(ObjectClass *klass, void *data) pcidev_k->class_id = PCI_CLASS_INPUT_OTHER; } -static void virtio_input_hid_kbd_pci_class_init(ObjectClass *klass, void *data) +static void virtio_input_hid_kbd_pci_class_init(ObjectClass *klass, + const void *data) { PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); @@ -71,7 +72,7 @@ static void virtio_input_hid_kbd_pci_class_init(ObjectClass *klass, void *data) } static void virtio_input_hid_mouse_pci_class_init(ObjectClass *klass, - void *data) + const void *data) { PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-iommu-pci.c b/hw/virtio/virtio-iommu-pci.c index 97e03ce..8123c6f 100644 --- a/hw/virtio/virtio-iommu-pci.c +++ b/hw/virtio/virtio-iommu-pci.c @@ -73,7 +73,7 @@ static void virtio_iommu_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_iommu_pci_class_init(ObjectClass *klass, void *data) +static void virtio_iommu_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-iommu.c b/hw/virtio/virtio-iommu.c index b6e7e01..3500f1b 100644 --- a/hw/virtio/virtio-iommu.c +++ b/hw/virtio/virtio-iommu.c @@ -1522,9 +1522,10 @@ static void virtio_iommu_device_reset_exit(Object *obj, ResetType type) NULL, NULL, virtio_iommu_put_endpoint); } -static void virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_iommu_set_status(VirtIODevice *vdev, uint8_t status) { trace_virtio_iommu_device_status(status); + return 0; } static void virtio_iommu_instance_init(Object *obj) @@ -1664,7 +1665,7 @@ static const Property virtio_iommu_properties[] = { DEFINE_PROP_UINT8("aw-bits", VirtIOIOMMU, aw_bits, 64), }; -static void virtio_iommu_class_init(ObjectClass *klass, void *data) +static void virtio_iommu_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -1690,7 +1691,7 @@ static void virtio_iommu_class_init(ObjectClass *klass, void *data) } static void virtio_iommu_memory_region_class_init(ObjectClass *klass, - void *data) + const void *data) { IOMMUMemoryRegionClass *imrc = IOMMU_MEMORY_REGION_CLASS(klass); diff --git a/hw/virtio/virtio-md-pci.c b/hw/virtio/virtio-md-pci.c index 9ec5067..9278b32 100644 --- a/hw/virtio/virtio-md-pci.c +++ b/hw/virtio/virtio-md-pci.c @@ -138,7 +138,7 @@ static const TypeInfo virtio_md_pci_info = { .instance_size = sizeof(VirtIOMDPCI), .class_size = sizeof(VirtIOMDPCIClass), .abstract = true, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_MEMORY_DEVICE }, { } }, diff --git a/hw/virtio/virtio-mem-pci.c b/hw/virtio/virtio-mem-pci.c index 6cc5f0f..f592eb1 100644 --- a/hw/virtio/virtio-mem-pci.c +++ b/hw/virtio/virtio-mem-pci.c @@ -163,7 +163,7 @@ static const Property virtio_mem_pci_class_properties[] = { DEV_NVECTORS_UNSPECIFIED), }; -static void virtio_mem_pci_class_init(ObjectClass *klass, void *data) +static void virtio_mem_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-mem.c b/hw/virtio/virtio-mem.c index 5f57ecc..c46f6f9 100644 --- a/hw/virtio/virtio-mem.c +++ b/hw/virtio/virtio-mem.c @@ -24,7 +24,7 @@ #include "hw/virtio/virtio-mem.h" #include "qapi/error.h" #include "qapi/visitor.h" -#include "exec/ram_addr.h" +#include "system/ram_addr.h" #include "migration/misc.h" #include "hw/boards.h" #include "hw/qdev-properties.h" @@ -244,28 +244,6 @@ static int virtio_mem_for_each_plugged_range(VirtIOMEM *vmem, void *arg, return ret; } -/* - * Adjust the memory section to cover the intersection with the given range. - * - * Returns false if the intersection is empty, otherwise returns true. - */ -static bool virtio_mem_intersect_memory_section(MemoryRegionSection *s, - uint64_t offset, uint64_t size) -{ - uint64_t start = MAX(s->offset_within_region, offset); - uint64_t end = MIN(s->offset_within_region + int128_get64(s->size), - offset + size); - - if (end <= start) { - return false; - } - - s->offset_within_address_space += start - s->offset_within_region; - s->offset_within_region = start; - s->size = int128_make64(end - start); - return true; -} - typedef int (*virtio_mem_section_cb)(MemoryRegionSection *s, void *arg); static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem, @@ -287,7 +265,7 @@ static int virtio_mem_for_each_plugged_section(const VirtIOMEM *vmem, first_bit + 1) - 1; size = (last_bit - first_bit + 1) * vmem->block_size; - if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { + if (!memory_region_section_intersect_range(&tmp, offset, size)) { break; } ret = cb(&tmp, arg); @@ -319,7 +297,7 @@ static int virtio_mem_for_each_unplugged_section(const VirtIOMEM *vmem, first_bit + 1) - 1; size = (last_bit - first_bit + 1) * vmem->block_size; - if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { + if (!memory_region_section_intersect_range(&tmp, offset, size)) { break; } ret = cb(&tmp, arg); @@ -355,7 +333,7 @@ static void virtio_mem_notify_unplug(VirtIOMEM *vmem, uint64_t offset, QLIST_FOREACH(rdl, &vmem->rdl_list, next) { MemoryRegionSection tmp = *rdl->section; - if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { + if (!memory_region_section_intersect_range(&tmp, offset, size)) { continue; } rdl->notify_discard(rdl, &tmp); @@ -371,7 +349,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset, QLIST_FOREACH(rdl, &vmem->rdl_list, next) { MemoryRegionSection tmp = *rdl->section; - if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { + if (!memory_region_section_intersect_range(&tmp, offset, size)) { continue; } ret = rdl->notify_populate(rdl, &tmp); @@ -388,7 +366,7 @@ static int virtio_mem_notify_plug(VirtIOMEM *vmem, uint64_t offset, if (rdl2 == rdl) { break; } - if (!virtio_mem_intersect_memory_section(&tmp, offset, size)) { + if (!memory_region_section_intersect_range(&tmp, offset, size)) { continue; } rdl2->notify_discard(rdl2, &tmp); @@ -1070,6 +1048,17 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) } /* + * Set ourselves as RamDiscardManager before the plug handler maps the + * memory region and exposes it via an address space. + */ + if (memory_region_set_ram_discard_manager(&vmem->memdev->mr, + RAM_DISCARD_MANAGER(vmem))) { + error_setg(errp, "Failed to set RamDiscardManager"); + ram_block_coordinated_discard_require(false); + return; + } + + /* * We don't know at this point whether shared RAM is migrated using * QEMU or migrated using the file content. "x-ignore-shared" will be * configured after realizing the device. So in case we have an @@ -1083,6 +1072,7 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) ret = ram_block_discard_range(rb, 0, qemu_ram_get_used_length(rb)); if (ret) { error_setg_errno(errp, -ret, "Unexpected error discarding RAM"); + memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); ram_block_coordinated_discard_require(false); return; } @@ -1144,13 +1134,6 @@ static void virtio_mem_device_realize(DeviceState *dev, Error **errp) vmem->system_reset = VIRTIO_MEM_SYSTEM_RESET(obj); vmem->system_reset->vmem = vmem; qemu_register_resettable(obj); - - /* - * Set ourselves as RamDiscardManager before the plug handler maps the - * memory region and exposes it via an address space. - */ - memory_region_set_ram_discard_manager(&vmem->memdev->mr, - RAM_DISCARD_MANAGER(vmem)); } static void virtio_mem_device_unrealize(DeviceState *dev) @@ -1158,12 +1141,6 @@ static void virtio_mem_device_unrealize(DeviceState *dev) VirtIODevice *vdev = VIRTIO_DEVICE(dev); VirtIOMEM *vmem = VIRTIO_MEM(dev); - /* - * The unplug handler unmapped the memory region, it cannot be - * found via an address space anymore. Unset ourselves. - */ - memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); - qemu_unregister_resettable(OBJECT(vmem->system_reset)); object_unref(OBJECT(vmem->system_reset)); @@ -1176,6 +1153,11 @@ static void virtio_mem_device_unrealize(DeviceState *dev) virtio_del_queue(vdev, 0); virtio_cleanup(vdev); g_free(vmem->bitmap); + /* + * The unplug handler unmapped the memory region, it cannot be + * found via an address space anymore. Unset ourselves. + */ + memory_region_set_ram_discard_manager(&vmem->memdev->mr, NULL); ram_block_coordinated_discard_require(false); } @@ -1750,7 +1732,7 @@ static bool virtio_mem_rdm_is_populated(const RamDiscardManager *rdm, } struct VirtIOMEMReplayData { - void *fn; + ReplayRamDiscardState fn; void *opaque; }; @@ -1758,12 +1740,12 @@ static int virtio_mem_rdm_replay_populated_cb(MemoryRegionSection *s, void *arg) { struct VirtIOMEMReplayData *data = arg; - return ((ReplayRamPopulate)data->fn)(s, data->opaque); + return data->fn(s, data->opaque); } static int virtio_mem_rdm_replay_populated(const RamDiscardManager *rdm, MemoryRegionSection *s, - ReplayRamPopulate replay_fn, + ReplayRamDiscardState replay_fn, void *opaque) { const VirtIOMEM *vmem = VIRTIO_MEM(rdm); @@ -1782,14 +1764,13 @@ static int virtio_mem_rdm_replay_discarded_cb(MemoryRegionSection *s, { struct VirtIOMEMReplayData *data = arg; - ((ReplayRamDiscard)data->fn)(s, data->opaque); - return 0; + return data->fn(s, data->opaque); } -static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, - MemoryRegionSection *s, - ReplayRamDiscard replay_fn, - void *opaque) +static int virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, + MemoryRegionSection *s, + ReplayRamDiscardState replay_fn, + void *opaque) { const VirtIOMEM *vmem = VIRTIO_MEM(rdm); struct VirtIOMEMReplayData data = { @@ -1798,8 +1779,8 @@ static void virtio_mem_rdm_replay_discarded(const RamDiscardManager *rdm, }; g_assert(s->mr == &vmem->memdev->mr); - virtio_mem_for_each_unplugged_section(vmem, s, &data, - virtio_mem_rdm_replay_discarded_cb); + return virtio_mem_for_each_unplugged_section(vmem, s, &data, + virtio_mem_rdm_replay_discarded_cb); } static void virtio_mem_rdm_register_listener(RamDiscardManager *rdm, @@ -1865,7 +1846,7 @@ static void virtio_mem_unplug_request_check(VirtIOMEM *vmem, Error **errp) } } -static void virtio_mem_class_init(ObjectClass *klass, void *data) +static void virtio_mem_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -1907,7 +1888,7 @@ static const TypeInfo virtio_mem_info = { .instance_finalize = virtio_mem_instance_finalize, .class_init = virtio_mem_class_init, .class_size = sizeof(VirtIOMEMClass), - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_RAM_DISCARD_MANAGER }, { } }, @@ -1957,7 +1938,8 @@ static void virtio_mem_system_reset_hold(Object *obj, ResetType type) virtio_mem_unplug_all(vmem); } -static void virtio_mem_system_reset_class_init(ObjectClass *klass, void *data) +static void virtio_mem_system_reset_class_init(ObjectClass *klass, + const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c index 0298171..532c671 100644 --- a/hw/virtio/virtio-mmio.c +++ b/hw/virtio/virtio-mmio.c @@ -784,7 +784,7 @@ static void virtio_mmio_realizefn(DeviceState *d, Error **errp) sysbus_init_mmio(sbd, &proxy->iomem); } -static void virtio_mmio_class_init(ObjectClass *klass, void *data) +static void virtio_mmio_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -855,7 +855,7 @@ static void virtio_mmio_vmstate_change(DeviceState *d, bool running) } } -static void virtio_mmio_bus_class_init(ObjectClass *klass, void *data) +static void virtio_mmio_bus_class_init(ObjectClass *klass, const void *data) { BusClass *bus_class = BUS_CLASS(klass); VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); diff --git a/hw/virtio/virtio-net-pci.c b/hw/virtio/virtio-net-pci.c index e18953a..f857a84 100644 --- a/hw/virtio/virtio-net-pci.c +++ b/hw/virtio/virtio-net-pci.c @@ -63,7 +63,7 @@ static void virtio_net_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_net_pci_class_init(ObjectClass *klass, void *data) +static void virtio_net_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -74,6 +74,7 @@ static void virtio_net_pci_class_init(ObjectClass *klass, void *data) k->device_id = PCI_DEVICE_ID_VIRTIO_NET; k->revision = VIRTIO_PCI_ABI_VERSION; k->class_id = PCI_CLASS_NETWORK_ETHERNET; + k->sriov_vf_user_creatable = true; set_bit(DEVICE_CATEGORY_NETWORK, dc->categories); device_class_set_props(dc, virtio_net_properties); vpciklass->realize = virtio_net_pci_realize; diff --git a/hw/virtio/virtio-nsm-pci.c b/hw/virtio/virtio-nsm-pci.c index dca7973..ec24396 100644 --- a/hw/virtio/virtio-nsm-pci.c +++ b/hw/virtio/virtio-nsm-pci.c @@ -40,7 +40,7 @@ static void virtio_nsm_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) } } -static void virtio_nsm_pci_class_init(ObjectClass *klass, void *data) +static void virtio_nsm_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-nsm.c b/hw/virtio/virtio-nsm.c index accf733..3bf5e70 100644 --- a/hw/virtio/virtio-nsm.c +++ b/hw/virtio/virtio-nsm.c @@ -1708,7 +1708,7 @@ static const Property virtio_nsm_properties[] = { DEFINE_PROP_STRING("module-id", VirtIONSM, module_id), }; -static void virtio_nsm_class_init(ObjectClass *klass, void *data) +static void virtio_nsm_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 3ca3f84..fba2372 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -146,9 +146,7 @@ static const VMStateDescription vmstate_virtio_pci = { static bool virtio_pci_has_extra_state(DeviceState *d) { - VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); - - return proxy->flags & VIRTIO_PCI_FLAG_MIGRATE_EXTRA; + return true; } static void virtio_pci_save_extra_state(DeviceState *d, QEMUFile *f) @@ -1215,7 +1213,12 @@ static int virtio_pci_set_guest_notifier(DeviceState *d, int n, bool assign, static bool virtio_pci_query_guest_notifiers(DeviceState *d) { VirtIOPCIProxy *proxy = to_virtio_pci_proxy(d); - return msix_enabled(&proxy->pci_dev); + + if (msix_enabled(&proxy->pci_dev)) { + return true; + } else { + return pci_irq_disabled(&proxy->pci_dev); + } } static int virtio_pci_set_guest_notifiers(DeviceState *d, int nvqs, bool assign) @@ -1962,6 +1965,7 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) uint8_t *config; uint32_t size; VirtIODevice *vdev = virtio_bus_get_device(bus); + int16_t res; /* * Virtio capabilities present without @@ -2109,6 +2113,18 @@ static void virtio_pci_device_plugged(DeviceState *d, Error **errp) pci_register_bar(&proxy->pci_dev, proxy->legacy_io_bar_idx, PCI_BASE_ADDRESS_SPACE_IO, &proxy->bar); } + + if (pci_is_vf(&proxy->pci_dev)) { + pcie_ari_init(&proxy->pci_dev, proxy->last_pcie_cap_offset); + proxy->last_pcie_cap_offset += PCI_ARI_SIZEOF; + } else { + res = pcie_sriov_pf_init_from_user_created_vfs( + &proxy->pci_dev, proxy->last_pcie_cap_offset, errp); + if (res > 0) { + proxy->last_pcie_cap_offset += res; + virtio_add_feature(&vdev->host_features, VIRTIO_F_SR_IOV); + } + } } static void virtio_pci_device_unplugged(DeviceState *d) @@ -2199,7 +2215,7 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) if (pcie_port && pci_is_express(pci_dev)) { int pos; - uint16_t last_pcie_cap_offset = PCI_CONFIG_SPACE_SIZE; + proxy->last_pcie_cap_offset = PCI_CONFIG_SPACE_SIZE; pos = pcie_endpoint_cap_init(pci_dev, 0); assert(pos > 0); @@ -2216,9 +2232,9 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) pci_set_word(pci_dev->config + pos + PCI_PM_PMC, 0x3); if (proxy->flags & VIRTIO_PCI_FLAG_AER) { - pcie_aer_init(pci_dev, PCI_ERR_VER, last_pcie_cap_offset, + pcie_aer_init(pci_dev, PCI_ERR_VER, proxy->last_pcie_cap_offset, PCI_ERR_SIZEOF, NULL); - last_pcie_cap_offset += PCI_ERR_SIZEOF; + proxy->last_pcie_cap_offset += PCI_ERR_SIZEOF; } if (proxy->flags & VIRTIO_PCI_FLAG_INIT_DEVERR) { @@ -2243,9 +2259,9 @@ static void virtio_pci_realize(PCIDevice *pci_dev, Error **errp) } if (proxy->flags & VIRTIO_PCI_FLAG_ATS) { - pcie_ats_init(pci_dev, last_pcie_cap_offset, + pcie_ats_init(pci_dev, proxy->last_pcie_cap_offset, proxy->flags & VIRTIO_PCI_FLAG_ATS_PAGE_ALIGNED); - last_pcie_cap_offset += PCI_EXT_CAP_ATS_SIZEOF; + proxy->last_pcie_cap_offset += PCI_EXT_CAP_ATS_SIZEOF; } if (proxy->flags & VIRTIO_PCI_FLAG_INIT_FLR) { @@ -2273,6 +2289,7 @@ static void virtio_pci_exit(PCIDevice *pci_dev) !pci_bus_is_root(pci_get_bus(pci_dev)); bool modern_pio = proxy->flags & VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY; + pcie_sriov_pf_exit(&proxy->pci_dev); msix_uninit_exclusive_bar(pci_dev); if (proxy->flags & VIRTIO_PCI_FLAG_AER && pcie_port && pci_is_express(pci_dev)) { @@ -2349,12 +2366,8 @@ static void virtio_pci_bus_reset_hold(Object *obj, ResetType type) static const Property virtio_pci_properties[] = { DEFINE_PROP_BIT("virtio-pci-bus-master-bug-migration", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_BUS_MASTER_BUG_MIGRATION_BIT, false), - DEFINE_PROP_BIT("migrate-extra", VirtIOPCIProxy, flags, - VIRTIO_PCI_FLAG_MIGRATE_EXTRA_BIT, true), DEFINE_PROP_BIT("modern-pio-notify", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_MODERN_PIO_NOTIFY_BIT, false), - DEFINE_PROP_BIT("x-disable-pcie", VirtIOPCIProxy, flags, - VIRTIO_PCI_FLAG_DISABLE_PCIE_BIT, false), DEFINE_PROP_BIT("page-per-vq", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_PAGE_PER_VQ_BIT, false), DEFINE_PROP_BOOL("x-ignore-backend-features", VirtIOPCIProxy, @@ -2383,8 +2396,7 @@ static void virtio_pci_dc_realize(DeviceState *qdev, Error **errp) VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev); PCIDevice *pci_dev = &proxy->pci_dev; - if (!(proxy->flags & VIRTIO_PCI_FLAG_DISABLE_PCIE) && - virtio_pci_modern(proxy)) { + if (virtio_pci_modern(proxy)) { pci_dev->cap_present |= QEMU_PCI_CAP_EXPRESS; } @@ -2399,7 +2411,7 @@ static int virtio_pci_sync_config(DeviceState *dev, Error **errp) return qdev_sync_config(DEVICE(vdev), errp); } -static void virtio_pci_class_init(ObjectClass *klass, void *data) +static void virtio_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -2433,7 +2445,7 @@ static const Property virtio_pci_generic_properties[] = { DEFINE_PROP_BOOL("disable-modern", VirtIOPCIProxy, disable_modern, false), }; -static void virtio_pci_base_class_init(ObjectClass *klass, void *data) +static void virtio_pci_base_class_init(ObjectClass *klass, const void *data) { const VirtioPCIDeviceTypeInfo *t = data; if (t->class_init) { @@ -2441,7 +2453,7 @@ static void virtio_pci_base_class_init(ObjectClass *klass, void *data) } } -static void virtio_pci_generic_class_init(ObjectClass *klass, void *data) +static void virtio_pci_generic_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -2481,7 +2493,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) .name = t->generic_name, .parent = base_type_info.name, .class_init = virtio_pci_generic_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } @@ -2497,13 +2509,13 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) generic_type_info.parent = base_name; generic_type_info.class_init = virtio_pci_base_class_init; - generic_type_info.class_data = (void *)t; + generic_type_info.class_data = t; assert(!t->non_transitional_name); assert(!t->transitional_name); } else { base_type_info.class_init = virtio_pci_base_class_init; - base_type_info.class_data = (void *)t; + base_type_info.class_data = t; } type_register_static(&base_type_info); @@ -2516,7 +2528,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) .name = t->non_transitional_name, .parent = base_type_info.name, .instance_init = virtio_pci_non_transitional_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_PCIE_DEVICE }, { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { } @@ -2530,7 +2542,7 @@ void virtio_pci_types_register(const VirtioPCIDeviceTypeInfo *t) .name = t->transitional_name, .parent = base_type_info.name, .instance_init = virtio_pci_transitional_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { /* * Transitional virtio devices work only as Conventional PCI * devices because they require PIO ports. @@ -2586,7 +2598,7 @@ static void virtio_pci_bus_new(VirtioBusState *bus, size_t bus_size, qbus_init(bus, bus_size, TYPE_VIRTIO_PCI_BUS, qdev, virtio_bus_name); } -static void virtio_pci_bus_class_init(ObjectClass *klass, void *data) +static void virtio_pci_bus_class_init(ObjectClass *klass, const void *data) { BusClass *bus_class = BUS_CLASS(klass); VirtioBusClass *k = VIRTIO_BUS_CLASS(klass); diff --git a/hw/virtio/virtio-pmem-pci.c b/hw/virtio/virtio-pmem-pci.c index cfe7f3b..babd91c 100644 --- a/hw/virtio/virtio-pmem-pci.c +++ b/hw/virtio/virtio-pmem-pci.c @@ -80,7 +80,7 @@ static void virtio_pmem_pci_fill_device_info(const MemoryDeviceState *md, info->type = MEMORY_DEVICE_INFO_KIND_VIRTIO_PMEM; } -static void virtio_pmem_pci_class_init(ObjectClass *klass, void *data) +static void virtio_pmem_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-pmem.c b/hw/virtio/virtio-pmem.c index adb3268..3416ea1 100644 --- a/hw/virtio/virtio-pmem.c +++ b/hw/virtio/virtio-pmem.c @@ -161,7 +161,7 @@ static const Property virtio_pmem_properties[] = { TYPE_MEMORY_BACKEND, HostMemoryBackend *), }; -static void virtio_pmem_class_init(ObjectClass *klass, void *data) +static void virtio_pmem_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-rng-pci.c b/hw/virtio/virtio-rng-pci.c index a94ff76..39b6003 100644 --- a/hw/virtio/virtio-rng-pci.c +++ b/hw/virtio/virtio-rng-pci.c @@ -53,7 +53,7 @@ static void virtio_rng_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) } } -static void virtio_rng_pci_class_init(ObjectClass *klass, void *data) +static void virtio_rng_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c index a515fc5..3df5d25 100644 --- a/hw/virtio/virtio-rng.c +++ b/hw/virtio/virtio-rng.c @@ -159,17 +159,18 @@ static void check_rate_limit(void *opaque) vrng->activate_timer = true; } -static void virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) +static int virtio_rng_set_status(VirtIODevice *vdev, uint8_t status) { VirtIORNG *vrng = VIRTIO_RNG(vdev); if (!vdev->vm_running) { - return; + return 0; } vdev->status = status; /* Something changed, try to process buffers */ virtio_rng_process(vrng); + return 0; } static void virtio_rng_device_realize(DeviceState *dev, Error **errp) @@ -260,7 +261,7 @@ static const Property virtio_rng_properties[] = { DEFINE_PROP_LINK("rng", VirtIORNG, conf.rng, TYPE_RNG_BACKEND, RngBackend *), }; -static void virtio_rng_class_init(ObjectClass *klass, void *data) +static void virtio_rng_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/virtio/virtio-scsi-pci.c b/hw/virtio/virtio-scsi-pci.c index d44fd2f..af87759 100644 --- a/hw/virtio/virtio-scsi-pci.c +++ b/hw/virtio/virtio-scsi-pci.c @@ -72,7 +72,7 @@ static void virtio_scsi_pci_realize(VirtIOPCIProxy *vpci_dev, Error **errp) qdev_realize(vdev, BUS(&vpci_dev->bus), errp); } -static void virtio_scsi_pci_class_init(ObjectClass *klass, void *data) +static void virtio_scsi_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio-serial-pci.c b/hw/virtio/virtio-serial-pci.c index b5b77eb..3f212ff 100644 --- a/hw/virtio/virtio-serial-pci.c +++ b/hw/virtio/virtio-serial-pci.c @@ -76,7 +76,7 @@ static const Property virtio_serial_pci_properties[] = { DEFINE_PROP_UINT32("class", VirtIOPCIProxy, class_code, 0), }; -static void virtio_serial_pci_class_init(ObjectClass *klass, void *data) +static void virtio_serial_pci_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c index ffc1263..82a285a 100644 --- a/hw/virtio/virtio.c +++ b/hw/virtio/virtio.c @@ -205,6 +205,15 @@ static const char *virtio_id_to_name(uint16_t device_id) return name; } +static void virtio_check_indirect_feature(VirtIODevice *vdev) +{ + if (!virtio_vdev_has_feature(vdev, VIRTIO_RING_F_INDIRECT_DESC)) { + qemu_log_mask(LOG_GUEST_ERROR, + "Device %s: indirect_desc was not negotiated!\n", + vdev->name); + } +} + /* Called within call_rcu(). */ static void virtio_free_region_cache(VRingMemoryRegionCaches *caches) { @@ -1680,8 +1689,8 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) VirtIODevice *vdev = vq->vdev; VirtQueueElement *elem = NULL; unsigned out_num, in_num, elem_entries; - hwaddr addr[VIRTQUEUE_MAX_SIZE]; - struct iovec iov[VIRTQUEUE_MAX_SIZE]; + hwaddr QEMU_UNINITIALIZED addr[VIRTQUEUE_MAX_SIZE]; + struct iovec QEMU_UNINITIALIZED iov[VIRTQUEUE_MAX_SIZE]; VRingDesc desc; int rc; @@ -1733,6 +1742,7 @@ static void *virtqueue_split_pop(VirtQueue *vq, size_t sz) virtio_error(vdev, "Invalid size for indirect buffer table"); goto done; } + virtio_check_indirect_feature(vdev); /* loop over the indirect descriptor table */ len = address_space_cache_init(&indirect_desc_cache, vdev->dma_as, @@ -1826,8 +1836,8 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) VirtIODevice *vdev = vq->vdev; VirtQueueElement *elem = NULL; unsigned out_num, in_num, elem_entries; - hwaddr addr[VIRTQUEUE_MAX_SIZE]; - struct iovec iov[VIRTQUEUE_MAX_SIZE]; + hwaddr QEMU_UNINITIALIZED addr[VIRTQUEUE_MAX_SIZE]; + struct iovec QEMU_UNINITIALIZED iov[VIRTQUEUE_MAX_SIZE]; VRingPackedDesc desc; uint16_t id; int rc; @@ -1870,6 +1880,7 @@ static void *virtqueue_packed_pop(VirtQueue *vq, size_t sz) virtio_error(vdev, "Invalid size for indirect buffer table"); goto done; } + virtio_check_indirect_feature(vdev); /* loop over the indirect descriptor table */ len = address_space_cache_init(&indirect_desc_cache, vdev->dma_as, @@ -2221,12 +2232,12 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val) { VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); trace_virtio_set_status(vdev, val); + int ret = 0; if (virtio_vdev_has_feature(vdev, VIRTIO_F_VERSION_1)) { if (!(vdev->status & VIRTIO_CONFIG_S_FEATURES_OK) && val & VIRTIO_CONFIG_S_FEATURES_OK) { - int ret = virtio_validate_features(vdev); - + ret = virtio_validate_features(vdev); if (ret) { return ret; } @@ -2239,16 +2250,20 @@ int virtio_set_status(VirtIODevice *vdev, uint8_t val) } if (k->set_status) { - k->set_status(vdev, val); + ret = k->set_status(vdev, val); + if (ret) { + qemu_log("set %s status to %d failed, old status: %d\n", + vdev->name, val, vdev->status); + } } vdev->status = val; - return 0; + return ret; } static enum virtio_device_endian virtio_default_endian(void) { - if (target_words_bigendian()) { + if (target_big_endian()) { return VIRTIO_DEVICE_ENDIAN_BIG; } else { return VIRTIO_DEVICE_ENDIAN_LITTLE; @@ -2316,49 +2331,6 @@ void virtio_queue_enable(VirtIODevice *vdev, uint32_t queue_index) } } -void virtio_reset(void *opaque) -{ - VirtIODevice *vdev = opaque; - VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); - int i; - - virtio_set_status(vdev, 0); - if (current_cpu) { - /* Guest initiated reset */ - vdev->device_endian = virtio_current_cpu_endian(); - } else { - /* System reset */ - vdev->device_endian = virtio_default_endian(); - } - - if (k->get_vhost) { - struct vhost_dev *hdev = k->get_vhost(vdev); - /* Only reset when vhost back-end is connected */ - if (hdev && hdev->vhost_ops) { - vhost_reset_device(hdev); - } - } - - if (k->reset) { - k->reset(vdev); - } - - vdev->start_on_kick = false; - vdev->started = false; - vdev->broken = false; - vdev->guest_features = 0; - vdev->queue_sel = 0; - vdev->status = 0; - vdev->disabled = false; - qatomic_set(&vdev->isr, 0); - vdev->config_vector = VIRTIO_NO_VECTOR; - virtio_notify_vector(vdev, vdev->config_vector); - - for(i = 0; i < VIRTIO_QUEUE_MAX; i++) { - __virtio_queue_reset(vdev, i); - } -} - void virtio_queue_set_addr(VirtIODevice *vdev, int n, hwaddr addr) { if (!vdev->vq[n].vring.num) { @@ -3169,6 +3141,49 @@ int virtio_set_features(VirtIODevice *vdev, uint64_t val) return ret; } +void virtio_reset(void *opaque) +{ + VirtIODevice *vdev = opaque; + VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); + int i; + + virtio_set_status(vdev, 0); + if (current_cpu) { + /* Guest initiated reset */ + vdev->device_endian = virtio_current_cpu_endian(); + } else { + /* System reset */ + vdev->device_endian = virtio_default_endian(); + } + + if (k->get_vhost) { + struct vhost_dev *hdev = k->get_vhost(vdev); + /* Only reset when vhost back-end is connected */ + if (hdev && hdev->vhost_ops) { + vhost_reset_device(hdev); + } + } + + if (k->reset) { + k->reset(vdev); + } + + vdev->start_on_kick = false; + vdev->started = false; + vdev->broken = false; + virtio_set_features_nocheck(vdev, 0); + vdev->queue_sel = 0; + vdev->status = 0; + vdev->disabled = false; + qatomic_set(&vdev->isr, 0); + vdev->config_vector = VIRTIO_NO_VECTOR; + virtio_notify_vector(vdev, vdev->config_vector); + + for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { + __virtio_queue_reset(vdev, i); + } +} + static void virtio_device_check_notification_compatibility(VirtIODevice *vdev, Error **errp) { @@ -3419,7 +3434,7 @@ void virtio_cleanup(VirtIODevice *vdev) qemu_del_vm_change_state_handler(vdev->vmstate); } -static void virtio_vmstate_change(void *opaque, bool running, RunState state) +static int virtio_vmstate_change(void *opaque, bool running, RunState state) { VirtIODevice *vdev = opaque; BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); @@ -3436,8 +3451,12 @@ static void virtio_vmstate_change(void *opaque, bool running, RunState state) } if (!backend_run) { - virtio_set_status(vdev, vdev->status); + int ret = virtio_set_status(vdev, vdev->status); + if (ret) { + return ret; + } } + return 0; } void virtio_instance_init_common(Object *proxy_obj, void *data, @@ -3489,7 +3508,7 @@ void virtio_init(VirtIODevice *vdev, uint16_t device_id, size_t config_size) vdev->config = NULL; } vdev->vmstate = qdev_add_vm_change_state_handler(DEVICE(vdev), - virtio_vmstate_change, vdev); + NULL, virtio_vmstate_change, vdev); vdev->device_endian = virtio_default_endian(); vdev->use_guest_notifier_mask = true; } @@ -4138,7 +4157,7 @@ void virtio_device_release_ioeventfd(VirtIODevice *vdev) virtio_bus_release_ioeventfd(vbus); } -static void virtio_device_class_init(ObjectClass *klass, void *data) +static void virtio_device_class_init(ObjectClass *klass, const void *data) { /* Set the default value here. */ VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); diff --git a/hw/vmapple/aes.c b/hw/vmapple/aes.c index 3a7641a..a4853a9 100644 --- a/hw/vmapple/aes.c +++ b/hw/vmapple/aes.c @@ -558,7 +558,7 @@ static void aes_init(Object *obj) s->as = &address_space_memory; } -static void aes_class_init(ObjectClass *klass, void *data) +static void aes_class_init(ObjectClass *klass, const void *data) { ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/vmapple/bdif.c b/hw/vmapple/bdif.c index 5827dd2..5ccd374 100644 --- a/hw/vmapple/bdif.c +++ b/hw/vmapple/bdif.c @@ -250,7 +250,7 @@ static const Property bdif_properties[] = { DEFINE_PROP_DRIVE("root", VMAppleBdifState, root), }; -static void bdif_class_init(ObjectClass *klass, void *data) +static void bdif_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/vmapple/cfg.c b/hw/vmapple/cfg.c index 63414d8..3d58a29 100644 --- a/hw/vmapple/cfg.c +++ b/hw/vmapple/cfg.c @@ -168,7 +168,7 @@ static const Property vmapple_cfg_properties[] = { DEFINE_PROP_STRING("soc_name", VMAppleCfgState, soc_name), }; -static void vmapple_cfg_class_init(ObjectClass *klass, void *data) +static void vmapple_cfg_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); diff --git a/hw/vmapple/virtio-blk.c b/hw/vmapple/virtio-blk.c index aa3f18c..532b564 100644 --- a/hw/vmapple/virtio-blk.c +++ b/hw/vmapple/virtio-blk.c @@ -82,7 +82,7 @@ static void vmapple_virtio_blk_get_config(VirtIODevice *vdev, uint8_t *config) stl_he_p(&blkcfg->max_secure_erase_sectors, dev->apple_type); } -static void vmapple_virtio_blk_class_init(ObjectClass *klass, void *data) +static void vmapple_virtio_blk_class_init(ObjectClass *klass, const void *data) { VirtIOBlkClass *vbk = VIRTIO_BLK_CLASS(klass); VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass); @@ -165,7 +165,8 @@ static void vmapple_virtio_blk_pci_realize(VirtIOPCIProxy *vpci_dev, Error **err PCI_DEVICE_ID_APPLE_VIRTIO_BLK); } -static void vmapple_virtio_blk_pci_class_init(ObjectClass *klass, void *data) +static void vmapple_virtio_blk_pci_class_init(ObjectClass *klass, + const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass); diff --git a/hw/vmapple/vmapple.c b/hw/vmapple/vmapple.c index fa117bf..16e6110 100644 --- a/hw/vmapple/vmapple.c +++ b/hw/vmapple/vmapple.c @@ -570,7 +570,7 @@ static GlobalProperty vmapple_compat_defaults[] = { { TYPE_XHCI_PCI, "conditional-intr-mapping", "on" }, }; -static void vmapple_machine_class_init(ObjectClass *oc, void *data) +static void vmapple_machine_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/watchdog/allwinner-wdt.c b/hw/watchdog/allwinner-wdt.c index 78f4f9d..8fcd776 100644 --- a/hw/watchdog/allwinner-wdt.c +++ b/hw/watchdog/allwinner-wdt.c @@ -348,7 +348,7 @@ static void allwinner_wdt_realize(DeviceState *dev, Error **errp) ptimer_transaction_commit(s->timer); } -static void allwinner_wdt_class_init(ObjectClass *klass, void *data) +static void allwinner_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); ResettableClass *rc = RESETTABLE_CLASS(klass); @@ -358,7 +358,7 @@ static void allwinner_wdt_class_init(ObjectClass *klass, void *data) dc->vmsd = &allwinner_wdt_vmstate; } -static void allwinner_wdt_sun4i_class_init(ObjectClass *klass, void *data) +static void allwinner_wdt_sun4i_class_init(ObjectClass *klass, const void *data) { AwWdtClass *awc = AW_WDT_CLASS(klass); @@ -371,7 +371,7 @@ static void allwinner_wdt_sun4i_class_init(ObjectClass *klass, void *data) awc->get_intv_value = allwinner_wdt_sun4i_get_intv_value; } -static void allwinner_wdt_sun6i_class_init(ObjectClass *klass, void *data) +static void allwinner_wdt_sun6i_class_init(ObjectClass *klass, const void *data) { AwWdtClass *awc = AW_WDT_CLASS(klass); diff --git a/hw/watchdog/cmsdk-apb-watchdog.c b/hw/watchdog/cmsdk-apb-watchdog.c index a52121d..6a8d07c 100644 --- a/hw/watchdog/cmsdk-apb-watchdog.c +++ b/hw/watchdog/cmsdk-apb-watchdog.c @@ -394,7 +394,7 @@ static const VMStateDescription cmsdk_apb_watchdog_vmstate = { } }; -static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, void *data) +static void cmsdk_apb_watchdog_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/watchdog/sbsa_gwdt.c b/hw/watchdog/sbsa_gwdt.c index 1dd2139..ce84849 100644 --- a/hw/watchdog/sbsa_gwdt.c +++ b/hw/watchdog/sbsa_gwdt.c @@ -271,7 +271,7 @@ static const Property wdt_sbsa_gwdt_props[] = { 62500000), }; -static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, void *data) +static void wdt_sbsa_gwdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/watchdog/spapr_watchdog.c b/hw/watchdog/spapr_watchdog.c index 2bb1d3c..5b3f50d 100644 --- a/hw/watchdog/spapr_watchdog.c +++ b/hw/watchdog/spapr_watchdog.c @@ -249,7 +249,7 @@ static void spapr_wdt_realize(DeviceState *dev, Error **errp) &w->leave_others, OBJ_PROP_FLAG_READ); } -static void spapr_wdt_class_init(ObjectClass *oc, void *data) +static void spapr_wdt_class_init(ObjectClass *oc, const void *data) { DeviceClass *dc = DEVICE_CLASS(oc); diff --git a/hw/watchdog/wdt_aspeed.c b/hw/watchdog/wdt_aspeed.c index a503b2a..3022643 100644 --- a/hw/watchdog/wdt_aspeed.c +++ b/hw/watchdog/wdt_aspeed.c @@ -307,7 +307,7 @@ static const Property aspeed_wdt_properties[] = { AspeedSCUState *), }; -static void aspeed_wdt_class_init(ObjectClass *klass, void *data) +static void aspeed_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -329,7 +329,7 @@ static const TypeInfo aspeed_wdt_info = { .abstract = true, }; -static void aspeed_2400_wdt_class_init(ObjectClass *klass, void *data) +static void aspeed_2400_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass); @@ -366,7 +366,7 @@ static void aspeed_2500_wdt_reset_pulse(AspeedWDTState *s, uint32_t property) } } -static void aspeed_2500_wdt_class_init(ObjectClass *klass, void *data) +static void aspeed_2500_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass); @@ -389,7 +389,7 @@ static const TypeInfo aspeed_2500_wdt_info = { .class_init = aspeed_2500_wdt_class_init, }; -static void aspeed_2600_wdt_class_init(ObjectClass *klass, void *data) +static void aspeed_2600_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass); @@ -412,7 +412,7 @@ static const TypeInfo aspeed_2600_wdt_info = { .class_init = aspeed_2600_wdt_class_init, }; -static void aspeed_1030_wdt_class_init(ObjectClass *klass, void *data) +static void aspeed_1030_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass); @@ -435,7 +435,7 @@ static const TypeInfo aspeed_1030_wdt_info = { .class_init = aspeed_1030_wdt_class_init, }; -static void aspeed_2700_wdt_class_init(ObjectClass *klass, void *data) +static void aspeed_2700_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); AspeedWDTClass *awc = ASPEED_WDT_CLASS(klass); diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c index 39f2894..1275353 100644 --- a/hw/watchdog/wdt_diag288.c +++ b/hw/watchdog/wdt_diag288.c @@ -108,7 +108,7 @@ static void wdt_diag288_unrealize(DeviceState *dev) timer_free(diag288->timer); } -static void wdt_diag288_class_init(ObjectClass *klass, void *data) +static void wdt_diag288_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); DIAG288Class *diag288 = DIAG288_CLASS(klass); diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c index aa1d086..bb8a276 100644 --- a/hw/watchdog/wdt_i6300esb.c +++ b/hw/watchdog/wdt_i6300esb.c @@ -457,7 +457,7 @@ static void i6300esb_exit(PCIDevice *dev) timer_free(d->timer); } -static void i6300esb_class_init(ObjectClass *klass, void *data) +static void i6300esb_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -480,7 +480,7 @@ static const TypeInfo i6300esb_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(I6300State), .class_init = i6300esb_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/watchdog/wdt_ib700.c b/hw/watchdog/wdt_ib700.c index 23519e0..51a26a4 100644 --- a/hw/watchdog/wdt_ib700.c +++ b/hw/watchdog/wdt_ib700.c @@ -128,7 +128,7 @@ static void wdt_ib700_reset(DeviceState *dev) timer_del(s->timer); } -static void wdt_ib700_class_init(ObjectClass *klass, void *data) +static void wdt_ib700_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/watchdog/wdt_imx2.c b/hw/watchdog/wdt_imx2.c index 18e40bd..10151a1 100644 --- a/hw/watchdog/wdt_imx2.c +++ b/hw/watchdog/wdt_imx2.c @@ -286,7 +286,7 @@ static const Property imx2_wdt_properties[] = { false), }; -static void imx2_wdt_class_init(ObjectClass *klass, void *data) +static void imx2_wdt_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); diff --git a/hw/xen/meson.build b/hw/xen/meson.build index 4a486e3..a1850e7 100644 --- a/hw/xen/meson.build +++ b/hw/xen/meson.build @@ -9,6 +9,9 @@ system_ss.add(when: ['CONFIG_XEN_BUS'], if_true: files( system_ss.add(when: ['CONFIG_XEN', xen], if_true: files( 'xen-operations.c', +), +if_false: files( + 'xen_stubs.c', )) xen_specific_ss = ss.source_set() diff --git a/hw/xen/xen-bus.c b/hw/xen/xen-bus.c index f808a01..6bd2e54 100644 --- a/hw/xen/xen-bus.c +++ b/hw/xen/xen-bus.c @@ -380,7 +380,7 @@ static void xen_bus_unplug_request(HotplugHandler *hotplug, xen_device_unplug(xendev, errp); } -static void xen_bus_class_init(ObjectClass *class, void *data) +static void xen_bus_class_init(ObjectClass *class, const void *data) { BusClass *bus_class = BUS_CLASS(class); HotplugHandlerClass *hotplug_class = HOTPLUG_HANDLER_CLASS(class); @@ -399,7 +399,7 @@ static const TypeInfo xen_bus_type_info = { .instance_size = sizeof(XenBus), .class_size = sizeof(XenBusClass), .class_init = xen_bus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } }, @@ -1107,7 +1107,7 @@ static const Property xen_device_props[] = { DOMID_INVALID), }; -static void xen_device_class_init(ObjectClass *class, void *data) +static void xen_device_class_init(ObjectClass *class, const void *data) { DeviceClass *dev_class = DEVICE_CLASS(class); diff --git a/hw/xen/xen-hvm-common.c b/hw/xen/xen-hvm-common.c index 9a677e8..78e0bc8 100644 --- a/hw/xen/xen-hvm-common.c +++ b/hw/xen/xen-hvm-common.c @@ -711,7 +711,7 @@ static int xen_map_ioreq_server(XenIOState *state) /* * If we fail to map the shared page with xenforeignmemory_map_resource() * or if we're using buffered ioreqs, we need xen_get_ioreq_server_info() - * to provide the the addresses to map the shared page and/or to get the + * to provide the addresses to map the shared page and/or to get the * event-channel port for buffered ioreqs. */ if (state->shared_page == NULL || state->has_bufioreq) { diff --git a/hw/xen/xen-legacy-backend.c b/hw/xen/xen-legacy-backend.c index bf58db0..5ed53f8 100644 --- a/hw/xen/xen-legacy-backend.c +++ b/hw/xen/xen-legacy-backend.c @@ -635,7 +635,7 @@ int xen_be_bind_evtchn(struct XenLegacyDevice *xendev) } -static void xendev_class_init(ObjectClass *klass, void *data) +static void xendev_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -650,7 +650,7 @@ static const TypeInfo xendev_type_info = { .instance_size = sizeof(XenLegacyDevice), }; -static void xen_sysbus_class_init(ObjectClass *klass, void *data) +static void xen_sysbus_class_init(ObjectClass *klass, const void *data) { HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(klass); @@ -661,7 +661,7 @@ static const TypeInfo xensysbus_info = { .name = TYPE_XENSYSBUS, .parent = TYPE_BUS, .class_init = xen_sysbus_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { TYPE_HOTPLUG_HANDLER }, { } } diff --git a/hw/xen/xen-mapcache.c b/hw/xen/xen-mapcache.c index 698b5c5..e31d379 100644 --- a/hw/xen/xen-mapcache.c +++ b/hw/xen/xen-mapcache.c @@ -75,7 +75,8 @@ typedef struct MapCache { } MapCache; static MapCache *mapcache; -static MapCache *mapcache_grants; +static MapCache *mapcache_grants_ro; +static MapCache *mapcache_grants_rw; static xengnttab_handle *xen_region_gnttabdev; static inline void mapcache_lock(MapCache *mc) @@ -176,9 +177,12 @@ void xen_map_cache_init(phys_offset_to_gaddr_t f, void *opaque) * Grant mappings must use XC_PAGE_SIZE granularity since we can't * map anything beyond the number of pages granted to us. */ - mapcache_grants = xen_map_cache_init_single(f, opaque, - XC_PAGE_SHIFT, - max_mcache_size); + mapcache_grants_ro = xen_map_cache_init_single(f, opaque, + XC_PAGE_SHIFT, + max_mcache_size); + mapcache_grants_rw = xen_map_cache_init_single(f, opaque, + XC_PAGE_SHIFT, + max_mcache_size); setrlimit(RLIMIT_AS, &rlimit_as); } @@ -376,12 +380,12 @@ tryagain: entry = &mc->entry[address_index % mc->nr_buckets]; - while (entry && (lock || entry->lock) && entry->vaddr_base && - (entry->paddr_index != address_index || entry->size != cache_size || + while (entry && (!entry->vaddr_base || + entry->paddr_index != address_index || entry->size != cache_size || !test_bits(address_offset >> XC_PAGE_SHIFT, test_bit_size >> XC_PAGE_SHIFT, entry->valid_mapping))) { - if (!free_entry && !entry->lock) { + if (!free_entry && (!entry->lock || !entry->vaddr_base)) { free_entry = entry; free_pentry = pentry; } @@ -456,9 +460,13 @@ uint8_t *xen_map_cache(MemoryRegion *mr, bool is_write) { bool grant = xen_mr_is_grants(mr); - MapCache *mc = grant ? mapcache_grants : mapcache; + MapCache *mc = mapcache; uint8_t *p; + if (grant) { + mc = is_write ? mapcache_grants_rw : mapcache_grants_ro; + } + if (grant && !lock) { /* * Grants are only supported via address_space_map(). Anything @@ -523,7 +531,10 @@ ram_addr_t xen_ram_addr_from_mapcache(void *ptr) addr = xen_ram_addr_from_mapcache_single(mapcache, ptr); if (addr == RAM_ADDR_INVALID) { - addr = xen_ram_addr_from_mapcache_single(mapcache_grants, ptr); + addr = xen_ram_addr_from_mapcache_single(mapcache_grants_ro, ptr); + } + if (addr == RAM_ADDR_INVALID) { + addr = xen_ram_addr_from_mapcache_single(mapcache_grants_rw, ptr); } return addr; @@ -626,7 +637,8 @@ static void xen_invalidate_map_cache_entry_single(MapCache *mc, uint8_t *buffer) static void xen_invalidate_map_cache_entry_all(uint8_t *buffer) { xen_invalidate_map_cache_entry_single(mapcache, buffer); - xen_invalidate_map_cache_entry_single(mapcache_grants, buffer); + xen_invalidate_map_cache_entry_single(mapcache_grants_ro, buffer); + xen_invalidate_map_cache_entry_single(mapcache_grants_rw, buffer); } static void xen_invalidate_map_cache_entry_bh(void *opaque) diff --git a/hw/xen/xen-pvh-common.c b/hw/xen/xen-pvh-common.c index d675f7a..b93ff80 100644 --- a/hw/xen/xen-pvh-common.c +++ b/hw/xen/xen-pvh-common.c @@ -369,7 +369,7 @@ do { \ #endif } -static void xen_pvh_class_init(ObjectClass *oc, void *data) +static void xen_pvh_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); diff --git a/hw/xen/xen_pt.c b/hw/xen/xen_pt.c index 9487f68..9d16644 100644 --- a/hw/xen/xen_pt.c +++ b/hw/xen/xen_pt.c @@ -1047,7 +1047,7 @@ static void xen_igd_clear_slot(DeviceState *qdev, Error **errp) xpdc->pci_qdev_realize(qdev, errp); } -static void xen_pci_passthrough_class_init(ObjectClass *klass, void *data) +static void xen_pci_passthrough_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -1079,7 +1079,7 @@ static const TypeInfo xen_pci_passthrough_info = { .class_init = xen_pci_passthrough_class_init, .class_size = sizeof(XenPTDeviceClass), .instance_init = xen_pci_passthrough_instance_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { INTERFACE_PCIE_DEVICE }, { }, diff --git a/hw/xen/xen_pt_graphics.c b/hw/xen/xen_pt_graphics.c index 6c2e3f4..2c0cec9 100644 --- a/hw/xen/xen_pt_graphics.c +++ b/hw/xen/xen_pt_graphics.c @@ -347,7 +347,7 @@ static const IGDDeviceIDInfo igd_combo_id_infos[] = { {0x162D, 0x9cc3, 0x03}, /* BDWGT3SRVR, BDWM_w7 */ }; -static void isa_bridge_class_init(ObjectClass *klass, void *data) +static void isa_bridge_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); @@ -363,7 +363,7 @@ static const TypeInfo isa_bridge_info = { .parent = TYPE_PCI_DEVICE, .instance_size = sizeof(PCIDevice), .class_init = isa_bridge_class_init, - .interfaces = (InterfaceInfo[]) { + .interfaces = (const InterfaceInfo[]) { { INTERFACE_CONVENTIONAL_PCI_DEVICE }, { }, }, diff --git a/hw/xen/xen_stubs.c b/hw/xen/xen_stubs.c new file mode 100644 index 0000000..5e565df --- /dev/null +++ b/hw/xen/xen_stubs.c @@ -0,0 +1,51 @@ +/* + * Various stubs for xen functions + * + * Those functions are used only if xen_enabled(). This file is linked only if + * CONFIG_XEN is not set, so they should never be called. + * + * Copyright (c) 2025 Linaro, Ltd. + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "system/xen.h" +#include "system/xen-mapcache.h" + +void xen_hvm_modified_memory(ram_addr_t start, ram_addr_t length) +{ + g_assert_not_reached(); +} + +void xen_ram_alloc(ram_addr_t ram_addr, ram_addr_t size, + struct MemoryRegion *mr, Error **errp) +{ + g_assert_not_reached(); +} + +bool xen_mr_is_memory(MemoryRegion *mr) +{ + g_assert_not_reached(); +} + +void xen_invalidate_map_cache_entry(uint8_t *buffer) +{ + g_assert_not_reached(); +} + +ram_addr_t xen_ram_addr_from_mapcache(void *ptr) +{ + g_assert_not_reached(); +} + +uint8_t *xen_map_cache(MemoryRegion *mr, + hwaddr phys_addr, + hwaddr size, + ram_addr_t ram_addr_offset, + uint8_t lock, + bool dma, + bool is_write) +{ + g_assert_not_reached(); +} diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c index 8cef88c..e388531 100644 --- a/hw/xtensa/pic_cpu.c +++ b/hw/xtensa/pic_cpu.c @@ -27,6 +27,7 @@ #include "qemu/osdep.h" #include "cpu.h" +#include "exec/cpu-interrupt.h" #include "hw/irq.h" #include "qemu/log.h" #include "qemu/timer.h" diff --git a/hw/xtensa/sim.c b/hw/xtensa/sim.c index 1cea29c..49d17e7 100644 --- a/hw/xtensa/sim.c +++ b/hw/xtensa/sim.c @@ -32,7 +32,7 @@ #include "hw/boards.h" #include "hw/loader.h" #include "elf.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/error-report.h" #include "xtensa_memory.h" #include "xtensa_sim.h" diff --git a/hw/xtensa/virt.c b/hw/xtensa/virt.c index b08404f..b10866c 100644 --- a/hw/xtensa/virt.c +++ b/hw/xtensa/virt.c @@ -33,7 +33,7 @@ #include "hw/pci-host/gpex.h" #include "net/net.h" #include "elf.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/error-report.h" #include "xtensa_memory.h" #include "xtensa_sim.h" diff --git a/hw/xtensa/xtensa_memory.c b/hw/xtensa/xtensa_memory.c index 2c1095f..13a6077 100644 --- a/hw/xtensa/xtensa_memory.c +++ b/hw/xtensa/xtensa_memory.c @@ -27,7 +27,7 @@ #include "qemu/osdep.h" #include "qapi/error.h" -#include "exec/memory.h" +#include "system/memory.h" #include "qemu/error-report.h" #include "xtensa_memory.h" diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c index 3f3677f..6efffae 100644 --- a/hw/xtensa/xtfpga.c +++ b/hw/xtensa/xtfpga.c @@ -34,7 +34,7 @@ #include "hw/loader.h" #include "hw/qdev-properties.h" #include "elf.h" -#include "exec/memory.h" +#include "system/memory.h" #include "exec/tswap.h" #include "hw/char/serial-mm.h" #include "net/net.h" @@ -585,7 +585,7 @@ static void xtfpga_kc705_nommu_init(MachineState *machine) xtfpga_init(&kc705_board, machine); } -static void xtfpga_lx60_class_init(ObjectClass *oc, void *data) +static void xtfpga_lx60_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -602,7 +602,7 @@ static const TypeInfo xtfpga_lx60_type = { .class_init = xtfpga_lx60_class_init, }; -static void xtfpga_lx60_nommu_class_init(ObjectClass *oc, void *data) +static void xtfpga_lx60_nommu_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -619,7 +619,7 @@ static const TypeInfo xtfpga_lx60_nommu_type = { .class_init = xtfpga_lx60_nommu_class_init, }; -static void xtfpga_lx200_class_init(ObjectClass *oc, void *data) +static void xtfpga_lx200_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -636,7 +636,7 @@ static const TypeInfo xtfpga_lx200_type = { .class_init = xtfpga_lx200_class_init, }; -static void xtfpga_lx200_nommu_class_init(ObjectClass *oc, void *data) +static void xtfpga_lx200_nommu_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -653,7 +653,7 @@ static const TypeInfo xtfpga_lx200_nommu_type = { .class_init = xtfpga_lx200_nommu_class_init, }; -static void xtfpga_ml605_class_init(ObjectClass *oc, void *data) +static void xtfpga_ml605_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -670,7 +670,7 @@ static const TypeInfo xtfpga_ml605_type = { .class_init = xtfpga_ml605_class_init, }; -static void xtfpga_ml605_nommu_class_init(ObjectClass *oc, void *data) +static void xtfpga_ml605_nommu_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -687,7 +687,7 @@ static const TypeInfo xtfpga_ml605_nommu_type = { .class_init = xtfpga_ml605_nommu_class_init, }; -static void xtfpga_kc705_class_init(ObjectClass *oc, void *data) +static void xtfpga_kc705_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); @@ -704,7 +704,7 @@ static const TypeInfo xtfpga_kc705_type = { .class_init = xtfpga_kc705_class_init, }; -static void xtfpga_kc705_nommu_class_init(ObjectClass *oc, void *data) +static void xtfpga_kc705_nommu_class_init(ObjectClass *oc, const void *data) { MachineClass *mc = MACHINE_CLASS(oc); |