diff options
Diffstat (limited to 'hw/misc')
| -rw-r--r-- | hw/misc/edu.c | 1 | ||||
| -rw-r--r-- | hw/misc/ivshmem.c | 210 | ||||
| -rw-r--r-- | hw/misc/mips_itu.c | 73 |
3 files changed, 72 insertions, 212 deletions
diff --git a/hw/misc/edu.c b/hw/misc/edu.c index cdcf550dd7..ceaf688bfb 100644 --- a/hw/misc/edu.c +++ b/hw/misc/edu.c @@ -377,6 +377,7 @@ static void pci_edu_uninit(PCIDevice *pdev) qemu_mutex_destroy(&edu->thr_mutex); timer_del(&edu->dma_timer); + msi_uninit(pdev); } static void edu_obj_uint64(Object *obj, Visitor *v, const char *name, diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 8213659602..c7b6bbc974 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -112,13 +112,6 @@ typedef struct IVShmemState { /* migration stuff */ OnOffAuto master; Error *migration_blocker; - - /* legacy cruft */ - char *role; - char *shmobj; - char *sizearg; - size_t legacy_size; - uint32_t not_legacy_32bit; } IVShmemState; /* registers for the Inter-VM shared memory device */ @@ -529,17 +522,6 @@ static void process_msg_shmem(IVShmemState *s, int fd, Error **errp) size = buf.st_size; - /* Legacy cruft */ - if (s->legacy_size != SIZE_MAX) { - if (size < s->legacy_size) { - error_setg(errp, "server sent only %zd bytes of shared memory", - (size_t)buf.st_size); - close(fd); - return; - } - size = s->legacy_size; - } - /* mmap the region and map into the BAR2 */ memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), "ivshmem.bar2", size, true, fd, &local_err); @@ -882,8 +864,6 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) IVShmemState *s = IVSHMEM_COMMON(dev); Error *err = NULL; uint8_t *pci_conf; - uint8_t attr = PCI_BASE_ADDRESS_SPACE_MEMORY | - PCI_BASE_ADDRESS_MEM_PREFETCH; Error *local_err = NULL; /* IRQFD requires MSI */ @@ -903,10 +883,6 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) pci_register_bar(dev, 0, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->ivshmem_mmio); - if (s->not_legacy_32bit) { - attr |= PCI_BASE_ADDRESS_MEM_TYPE_64; - } - if (s->hostmem != NULL) { IVSHMEM_DPRINTF("using hostmem\n"); @@ -964,7 +940,11 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp) } vmstate_register_ram(s->ivshmem_bar2, DEVICE(s)); - pci_register_bar(PCI_DEVICE(s), 2, attr, s->ivshmem_bar2); + pci_register_bar(PCI_DEVICE(s), 2, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_PREFETCH | + PCI_BASE_ADDRESS_MEM_TYPE_64, + s->ivshmem_bar2); } static void ivshmem_exit(PCIDevice *dev) @@ -1084,13 +1064,6 @@ static Property ivshmem_plain_properties[] = { DEFINE_PROP_END_OF_LIST(), }; -static void ivshmem_plain_init(Object *obj) -{ - IVShmemState *s = IVSHMEM_PLAIN(obj); - - s->not_legacy_32bit = 1; -} - static void ivshmem_plain_realize(PCIDevice *dev, Error **errp) { IVShmemState *s = IVSHMEM_COMMON(dev); @@ -1122,7 +1095,6 @@ static const TypeInfo ivshmem_plain_info = { .name = TYPE_IVSHMEM_PLAIN, .parent = TYPE_IVSHMEM_COMMON, .instance_size = sizeof(IVShmemState), - .instance_init = ivshmem_plain_init, .class_init = ivshmem_plain_class_init, }; @@ -1155,8 +1127,6 @@ static void ivshmem_doorbell_init(Object *obj) IVShmemState *s = IVSHMEM_DOORBELL(obj); s->features |= (1 << IVSHMEM_MSI); - s->legacy_size = SIZE_MAX; /* whatever the server sends */ - s->not_legacy_32bit = 1; } static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp) @@ -1189,181 +1159,11 @@ static const TypeInfo ivshmem_doorbell_info = { .class_init = ivshmem_doorbell_class_init, }; -static int ivshmem_load_old(QEMUFile *f, void *opaque, int version_id) -{ - IVShmemState *s = opaque; - PCIDevice *pdev = PCI_DEVICE(s); - int ret; - - IVSHMEM_DPRINTF("ivshmem_load_old\n"); - - if (version_id != 0) { - return -EINVAL; - } - - ret = ivshmem_pre_load(s); - if (ret) { - return ret; - } - - ret = pci_device_load(pdev, f); - if (ret) { - return ret; - } - - if (ivshmem_has_feature(s, IVSHMEM_MSI)) { - msix_load(pdev, f); - ivshmem_msix_vector_use(s); - } else { - s->intrstatus = qemu_get_be32(f); - s->intrmask = qemu_get_be32(f); - } - - return 0; -} - -static bool test_msix(void *opaque, int version_id) -{ - IVShmemState *s = opaque; - - return ivshmem_has_feature(s, IVSHMEM_MSI); -} - -static bool test_no_msix(void *opaque, int version_id) -{ - return !test_msix(opaque, version_id); -} - -static const VMStateDescription ivshmem_vmsd = { - .name = "ivshmem", - .version_id = 1, - .minimum_version_id = 1, - .pre_load = ivshmem_pre_load, - .post_load = ivshmem_post_load, - .fields = (VMStateField[]) { - VMSTATE_PCI_DEVICE(parent_obj, IVShmemState), - - VMSTATE_MSIX_TEST(parent_obj, IVShmemState, test_msix), - VMSTATE_UINT32_TEST(intrstatus, IVShmemState, test_no_msix), - VMSTATE_UINT32_TEST(intrmask, IVShmemState, test_no_msix), - - VMSTATE_END_OF_LIST() - }, - .load_state_old = ivshmem_load_old, - .minimum_version_id_old = 0 -}; - -static Property ivshmem_properties[] = { - DEFINE_PROP_CHR("chardev", IVShmemState, server_chr), - DEFINE_PROP_STRING("size", IVShmemState, sizearg), - DEFINE_PROP_UINT32("vectors", IVShmemState, vectors, 1), - DEFINE_PROP_BIT("ioeventfd", IVShmemState, features, IVSHMEM_IOEVENTFD, - false), - DEFINE_PROP_BIT("msi", IVShmemState, features, IVSHMEM_MSI, true), - DEFINE_PROP_STRING("shm", IVShmemState, shmobj), - DEFINE_PROP_STRING("role", IVShmemState, role), - DEFINE_PROP_UINT32("use64", IVShmemState, not_legacy_32bit, 1), - DEFINE_PROP_END_OF_LIST(), -}; - -static void desugar_shm(IVShmemState *s) -{ - Object *obj; - char *path; - - obj = object_new("memory-backend-file"); - path = g_strdup_printf("/dev/shm/%s", s->shmobj); - object_property_set_str(obj, path, "mem-path", &error_abort); - g_free(path); - object_property_set_int(obj, s->legacy_size, "size", &error_abort); - object_property_set_bool(obj, true, "share", &error_abort); - object_property_add_child(OBJECT(s), "internal-shm-backend", obj, - &error_abort); - object_unref(obj); - user_creatable_complete(USER_CREATABLE(obj), &error_abort); - s->hostmem = MEMORY_BACKEND(obj); -} - -static void ivshmem_realize(PCIDevice *dev, Error **errp) -{ - IVShmemState *s = IVSHMEM_COMMON(dev); - - if (!qtest_enabled()) { - warn_report("ivshmem is deprecated, please use ivshmem-plain" - " or ivshmem-doorbell instead"); - } - - if (qemu_chr_fe_backend_connected(&s->server_chr) + !!s->shmobj != 1) { - error_setg(errp, "You must specify either 'shm' or 'chardev'"); - return; - } - - if (s->sizearg == NULL) { - s->legacy_size = 4 * MiB; /* 4 MB default */ - } else { - int ret; - uint64_t size; - - ret = qemu_strtosz_MiB(s->sizearg, NULL, &size); - if (ret < 0 || (size_t)size != size || !is_power_of_2(size)) { - error_setg(errp, "Invalid size %s", s->sizearg); - return; - } - s->legacy_size = size; - } - - /* check that role is reasonable */ - if (s->role) { - if (strncmp(s->role, "peer", 5) == 0) { - s->master = ON_OFF_AUTO_OFF; - } else if (strncmp(s->role, "master", 7) == 0) { - s->master = ON_OFF_AUTO_ON; - } else { - error_setg(errp, "'role' must be 'peer' or 'master'"); - return; - } - } else { - s->master = ON_OFF_AUTO_AUTO; - } - - if (s->shmobj) { - desugar_shm(s); - } - - /* - * Note: we don't use INTx with IVSHMEM_MSI at all, so this is a - * bald-faced lie then. But it's a backwards compatible lie. - */ - pci_config_set_interrupt_pin(dev->config, 1); - - ivshmem_common_realize(dev, errp); -} - -static void ivshmem_class_init(ObjectClass *klass, void *data) -{ - DeviceClass *dc = DEVICE_CLASS(klass); - PCIDeviceClass *k = PCI_DEVICE_CLASS(klass); - - k->realize = ivshmem_realize; - k->revision = 0; - dc->desc = "Inter-VM shared memory (legacy)"; - dc->props = ivshmem_properties; - dc->vmsd = &ivshmem_vmsd; -} - -static const TypeInfo ivshmem_info = { - .name = TYPE_IVSHMEM, - .parent = TYPE_IVSHMEM_COMMON, - .instance_size = sizeof(IVShmemState), - .class_init = ivshmem_class_init, -}; - static void ivshmem_register_types(void) { type_register_static(&ivshmem_common_info); type_register_static(&ivshmem_plain_info); type_register_static(&ivshmem_doorbell_info); - type_register_static(&ivshmem_info); } type_init(ivshmem_register_types) diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c index 43bbec46cf..1257d8fce6 100644 --- a/hw/misc/mips_itu.c +++ b/hw/misc/mips_itu.c @@ -55,9 +55,17 @@ typedef enum ITCView { ITCVIEW_EF_SYNC = 2, ITCVIEW_EF_TRY = 3, ITCVIEW_PV_SYNC = 4, - ITCVIEW_PV_TRY = 5 + ITCVIEW_PV_TRY = 5, + ITCVIEW_PV_ICR0 = 15, } ITCView; +#define ITC_ICR0_CELL_NUM 16 +#define ITC_ICR0_BLK_GRAIN 8 +#define ITC_ICR0_BLK_GRAIN_MASK 0x7 +#define ITC_ICR0_ERR_AXI 2 +#define ITC_ICR0_ERR_PARITY 1 +#define ITC_ICR0_ERR_EXEC 0 + MemoryRegion *mips_itu_get_tag_region(MIPSITUState *itu) { return &itu->tag_io; @@ -76,7 +84,7 @@ static uint64_t itc_tag_read(void *opaque, hwaddr addr, unsigned size) return tag->ITCAddressMap[index]; } -static void itc_reconfigure(MIPSITUState *tag) +void itc_reconfigure(MIPSITUState *tag) { uint64_t *am = &tag->ITCAddressMap[0]; MemoryRegion *mr = &tag->storage_io; @@ -84,6 +92,12 @@ static void itc_reconfigure(MIPSITUState *tag) uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK); bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0; + if (tag->saar_present) { + address = ((*(uint64_t *) tag->saar) & 0xFFFFFFFFE000ULL) << 4; + size = 1 << ((*(uint64_t *) tag->saar >> 1) & 0x1f); + is_enabled = *(uint64_t *) tag->saar & 1; + } + memory_region_transaction_begin(); if (!(size & (size - 1))) { memory_region_set_size(mr, size); @@ -142,7 +156,12 @@ static inline ITCView get_itc_view(hwaddr addr) static inline int get_cell_stride_shift(const MIPSITUState *s) { /* Minimum interval (for EntryGain = 0) is 128 B */ - return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK); + if (s->saar_present) { + return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) & + ITC_ICR0_BLK_GRAIN_MASK); + } else { + return 7 + (s->ITCAddressMap[1] & ITC_AM1_ENTRY_GRAIN_MASK); + } } static inline ITCStorageCell *get_cell(MIPSITUState *s, @@ -356,6 +375,12 @@ static void view_pv_try_write(ITCStorageCell *c) view_pv_common_write(c); } +static void raise_exception(int excp) +{ + current_cpu->exception_index = excp; + cpu_loop_exit(current_cpu); +} + static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size) { MIPSITUState *s = (MIPSITUState *)opaque; @@ -363,6 +388,14 @@ static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size) ITCView view = get_itc_view(addr); uint64_t ret = -1; + switch (size) { + case 1: + case 2: + s->icr0 |= 1 << ITC_ICR0_ERR_AXI; + raise_exception(EXCP_DBE); + return 0; + } + switch (view) { case ITCVIEW_BYPASS: ret = view_bypass_read(cell); @@ -382,6 +415,9 @@ static uint64_t itc_storage_read(void *opaque, hwaddr addr, unsigned size) case ITCVIEW_PV_TRY: ret = view_pv_try_read(cell); break; + case ITCVIEW_PV_ICR0: + ret = s->icr0; + break; default: qemu_log_mask(LOG_GUEST_ERROR, "itc_storage_read: Bad ITC View %d\n", (int)view); @@ -398,6 +434,14 @@ static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data, ITCStorageCell *cell = get_cell(s, addr); ITCView view = get_itc_view(addr); + switch (size) { + case 1: + case 2: + s->icr0 |= 1 << ITC_ICR0_ERR_AXI; + raise_exception(EXCP_DBE); + return; + } + switch (view) { case ITCVIEW_BYPASS: view_bypass_write(cell, data); @@ -417,6 +461,15 @@ static void itc_storage_write(void *opaque, hwaddr addr, uint64_t data, case ITCVIEW_PV_TRY: view_pv_try_write(cell); break; + case ITCVIEW_PV_ICR0: + if (data & 0x7) { + /* clear ERROR bits */ + s->icr0 &= ~(data & 0x7); + } + /* set BLK_GRAIN */ + s->icr0 &= ~0x700; + s->icr0 |= data & 0x700; + break; default: qemu_log_mask(LOG_GUEST_ERROR, "itc_storage_write: Bad ITC View %d\n", (int)view); @@ -479,10 +532,15 @@ static void mips_itu_reset(DeviceState *dev) { MIPSITUState *s = MIPS_ITU(dev); - s->ITCAddressMap[0] = 0; - s->ITCAddressMap[1] = - ((ITC_STORAGE_ADDRSPACE_SZ - 1) & ITC_AM1_ADDR_MASK_MASK) | - (get_num_cells(s) << ITC_AM1_NUMENTRIES_OFS); + if (s->saar_present) { + *(uint64_t *) s->saar = 0x11 << 1; + s->icr0 = get_num_cells(s) << ITC_ICR0_CELL_NUM; + } else { + s->ITCAddressMap[0] = 0; + s->ITCAddressMap[1] = + ((ITC_STORAGE_ADDRSPACE_SZ - 1) & ITC_AM1_ADDR_MASK_MASK) | + (get_num_cells(s) << ITC_AM1_NUMENTRIES_OFS); + } itc_reconfigure(s); itc_reset_cells(s); @@ -493,6 +551,7 @@ static Property mips_itu_properties[] = { ITC_FIFO_NUM_MAX), DEFINE_PROP_INT32("num-semaphores", MIPSITUState, num_semaphores, ITC_SEMAPH_NUM_MAX), + DEFINE_PROP_BOOL("saar-present", MIPSITUState, saar_present, false), DEFINE_PROP_END_OF_LIST(), }; |
