diff options
Diffstat (limited to 'hw/misc')
-rw-r--r-- | hw/misc/Makefile.objs | 1 | ||||
-rw-r--r-- | hw/misc/edu.c | 1 | ||||
-rw-r--r-- | hw/misc/ivshmem.c | 210 | ||||
-rw-r--r-- | hw/misc/macio/mac_dbdma.c | 1 | ||||
-rw-r--r-- | hw/misc/max111x.c | 6 | ||||
-rw-r--r-- | hw/misc/milkymist-hpdmc.c | 9 | ||||
-rw-r--r-- | hw/misc/milkymist-pfpu.c | 12 | ||||
-rw-r--r-- | hw/misc/mips_itu.c | 73 | ||||
-rw-r--r-- | hw/misc/nrf51_rng.c | 262 | ||||
-rw-r--r-- | hw/misc/omap_l4.c | 4 | ||||
-rw-r--r-- | hw/misc/puv3_pm.c | 10 | ||||
-rw-r--r-- | hw/misc/tmp105.c | 2 | ||||
-rw-r--r-- | hw/misc/tmp421.c | 2 | ||||
-rw-r--r-- | hw/misc/tz-mpc.c | 4 |
14 files changed, 356 insertions, 241 deletions
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index 680350b3c3..04f3bfa516 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -74,3 +74,4 @@ obj-$(CONFIG_PVPANIC) += pvpanic.o obj-$(CONFIG_AUX) += auxbus.o obj-$(CONFIG_ASPEED_SOC) += aspeed_scu.o aspeed_sdmc.o obj-$(CONFIG_MSF2) += msf2-sysreg.o +obj-$(CONFIG_NRF51_SOC) += nrf51_rng.o 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 ecfd10a29a..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(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/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c index 87ae246d37..e5917d8f2e 100644 --- a/hw/misc/macio/mac_dbdma.c +++ b/hw/misc/macio/mac_dbdma.c @@ -38,7 +38,6 @@ */ #include "qemu/osdep.h" #include "hw/hw.h" -#include "hw/isa/isa.h" #include "hw/ppc/mac_dbdma.h" #include "qemu/main-loop.h" #include "qemu/log.h" diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c index 6dbdc03677..ac6d35a81d 100644 --- a/hw/misc/max111x.c +++ b/hw/misc/max111x.c @@ -43,9 +43,9 @@ typedef struct { #define CB_START (1 << 7) #define CHANNEL_NUM(v, b0, b1, b2) \ - ((((v) >> (2 + (b0))) & 4) | \ - (((v) >> (3 + (b1))) & 2) | \ - (((v) >> (4 + (b2))) & 1)) + ((((v) >> (2 + (b0))) & 4) | \ + (((v) >> (3 + (b1))) & 2) | \ + (((v) >> (4 + (b2))) & 1)) static uint32_t max111x_read(MAX111xState *s) { diff --git a/hw/misc/milkymist-hpdmc.c b/hw/misc/milkymist-hpdmc.c index e6140eec6b..44dc0698ec 100644 --- a/hw/misc/milkymist-hpdmc.c +++ b/hw/misc/milkymist-hpdmc.c @@ -129,15 +129,13 @@ static void milkymist_hpdmc_reset(DeviceState *d) | IODELAY_PLL2_LOCKED; } -static int milkymist_hpdmc_init(SysBusDevice *dev) +static void milkymist_hpdmc_realize(DeviceState *dev, Error **errp) { MilkymistHpdmcState *s = MILKYMIST_HPDMC(dev); memory_region_init_io(&s->regs_region, OBJECT(dev), &hpdmc_mmio_ops, s, "milkymist-hpdmc", R_MAX * 4); - sysbus_init_mmio(dev, &s->regs_region); - - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->regs_region); } static const VMStateDescription vmstate_milkymist_hpdmc = { @@ -153,9 +151,8 @@ static const VMStateDescription vmstate_milkymist_hpdmc = { static void milkymist_hpdmc_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_hpdmc_init; + dc->realize = milkymist_hpdmc_realize; dc->reset = milkymist_hpdmc_reset; dc->vmsd = &vmstate_milkymist_hpdmc; } diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c index 86f5e383b0..4a03c7ee63 100644 --- a/hw/misc/milkymist-pfpu.c +++ b/hw/misc/milkymist-pfpu.c @@ -497,17 +497,16 @@ static void milkymist_pfpu_reset(DeviceState *d) } } -static int milkymist_pfpu_init(SysBusDevice *dev) +static void milkymist_pfpu_realize(DeviceState *dev, Error **errp) { MilkymistPFPUState *s = MILKYMIST_PFPU(dev); + SysBusDevice *sbd = SYS_BUS_DEVICE(dev); - sysbus_init_irq(dev, &s->irq); + sysbus_init_irq(sbd, &s->irq); memory_region_init_io(&s->regs_region, OBJECT(dev), &pfpu_mmio_ops, s, "milkymist-pfpu", MICROCODE_END * 4); - sysbus_init_mmio(dev, &s->regs_region); - - return 0; + sysbus_init_mmio(sbd, &s->regs_region); } static const VMStateDescription vmstate_milkymist_pfpu = { @@ -527,9 +526,8 @@ static const VMStateDescription vmstate_milkymist_pfpu = { static void milkymist_pfpu_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = milkymist_pfpu_init; + dc->realize = milkymist_pfpu_realize; dc->reset = milkymist_pfpu_reset; dc->vmsd = &vmstate_milkymist_pfpu; } 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(), }; diff --git a/hw/misc/nrf51_rng.c b/hw/misc/nrf51_rng.c new file mode 100644 index 0000000000..d188f044f4 --- /dev/null +++ b/hw/misc/nrf51_rng.c @@ -0,0 +1,262 @@ +/* + * nRF51 Random Number Generator + * + * Reference Manual: http://infocenter.nordicsemi.com/pdf/nRF51_RM_v3.0.1.pdf + * + * Copyright 2018 Steffen Görtz <contrib@steffen-goertz.de> + * + * This code is licensed under the GPL version 2 or later. See + * the COPYING file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qemu/log.h" +#include "qapi/error.h" +#include "hw/arm/nrf51.h" +#include "hw/misc/nrf51_rng.h" +#include "crypto/random.h" + +static void update_irq(NRF51RNGState *s) +{ + bool irq = s->interrupt_enabled && s->event_valrdy; + qemu_set_irq(s->irq, irq); +} + +static uint64_t rng_read(void *opaque, hwaddr offset, unsigned int size) +{ + NRF51RNGState *s = NRF51_RNG(opaque); + uint64_t r = 0; + + switch (offset) { + case NRF51_RNG_EVENT_VALRDY: + r = s->event_valrdy; + break; + case NRF51_RNG_REG_SHORTS: + r = s->shortcut_stop_on_valrdy; + break; + case NRF51_RNG_REG_INTEN: + case NRF51_RNG_REG_INTENSET: + case NRF51_RNG_REG_INTENCLR: + r = s->interrupt_enabled; + break; + case NRF51_RNG_REG_CONFIG: + r = s->filter_enabled; + break; + case NRF51_RNG_REG_VALUE: + r = s->value; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: bad read offset 0x%" HWADDR_PRIx "\n", + __func__, offset); + } + + return r; +} + +static int64_t calc_next_timeout(NRF51RNGState *s) +{ + int64_t timeout = qemu_clock_get_us(QEMU_CLOCK_VIRTUAL); + if (s->filter_enabled) { + timeout += s->period_filtered_us; + } else { + timeout += s->period_unfiltered_us; + } + + return timeout; +} + + +static void rng_update_timer(NRF51RNGState *s) +{ + if (s->active) { + timer_mod(&s->timer, calc_next_timeout(s)); + } else { + timer_del(&s->timer); + } +} + + +static void rng_write(void *opaque, hwaddr offset, + uint64_t value, unsigned int size) +{ + NRF51RNGState *s = NRF51_RNG(opaque); + + switch (offset) { + case NRF51_RNG_TASK_START: + if (value == NRF51_TRIGGER_TASK) { + s->active = 1; + rng_update_timer(s); + } + break; + case NRF51_RNG_TASK_STOP: + if (value == NRF51_TRIGGER_TASK) { + s->active = 0; + rng_update_timer(s); + } + break; + case NRF51_RNG_EVENT_VALRDY: + if (value == NRF51_EVENT_CLEAR) { + s->event_valrdy = 0; + } + break; + case NRF51_RNG_REG_SHORTS: + s->shortcut_stop_on_valrdy = + (value & BIT_MASK(NRF51_RNG_REG_SHORTS_VALRDY_STOP)) ? 1 : 0; + break; + case NRF51_RNG_REG_INTEN: + s->interrupt_enabled = + (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) ? 1 : 0; + break; + case NRF51_RNG_REG_INTENSET: + if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) { + s->interrupt_enabled = 1; + } + break; + case NRF51_RNG_REG_INTENCLR: + if (value & BIT_MASK(NRF51_RNG_REG_INTEN_VALRDY)) { + s->interrupt_enabled = 0; + } + break; + case NRF51_RNG_REG_CONFIG: + s->filter_enabled = + (value & BIT_MASK(NRF51_RNG_REG_CONFIG_DECEN)) ? 1 : 0; + break; + + default: + qemu_log_mask(LOG_GUEST_ERROR, + "%s: bad write offset 0x%" HWADDR_PRIx "\n", + __func__, offset); + } + + update_irq(s); +} + +static const MemoryRegionOps rng_ops = { + .read = rng_read, + .write = rng_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .impl.min_access_size = 4, + .impl.max_access_size = 4 +}; + +static void nrf51_rng_timer_expire(void *opaque) +{ + NRF51RNGState *s = NRF51_RNG(opaque); + + qcrypto_random_bytes(&s->value, 1, &error_abort); + + s->event_valrdy = 1; + qemu_set_irq(s->eep_valrdy, 1); + + if (s->shortcut_stop_on_valrdy) { + s->active = 0; + } + + rng_update_timer(s); + update_irq(s); +} + +static void nrf51_rng_tep_start(void *opaque, int n, int level) +{ + NRF51RNGState *s = NRF51_RNG(opaque); + + if (level) { + s->active = 1; + rng_update_timer(s); + } +} + +static void nrf51_rng_tep_stop(void *opaque, int n, int level) +{ + NRF51RNGState *s = NRF51_RNG(opaque); + + if (level) { + s->active = 0; + rng_update_timer(s); + } +} + + +static void nrf51_rng_init(Object *obj) +{ + NRF51RNGState *s = NRF51_RNG(obj); + SysBusDevice *sbd = SYS_BUS_DEVICE(obj); + + memory_region_init_io(&s->mmio, obj, &rng_ops, s, + TYPE_NRF51_RNG, NRF51_RNG_SIZE); + sysbus_init_mmio(sbd, &s->mmio); + + timer_init_us(&s->timer, QEMU_CLOCK_VIRTUAL, nrf51_rng_timer_expire, s); + + sysbus_init_irq(sbd, &s->irq); + + /* Tasks */ + qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_start, "tep_start", 1); + qdev_init_gpio_in_named(DEVICE(s), nrf51_rng_tep_stop, "tep_stop", 1); + + /* Events */ + qdev_init_gpio_out_named(DEVICE(s), &s->eep_valrdy, "eep_valrdy", 1); +} + +static void nrf51_rng_reset(DeviceState *dev) +{ + NRF51RNGState *s = NRF51_RNG(dev); + + s->value = 0; + s->active = 0; + s->event_valrdy = 0; + s->shortcut_stop_on_valrdy = 0; + s->interrupt_enabled = 0; + s->filter_enabled = 0; + + rng_update_timer(s); +} + + +static Property nrf51_rng_properties[] = { + DEFINE_PROP_UINT16("period_unfiltered_us", NRF51RNGState, + period_unfiltered_us, 167), + DEFINE_PROP_UINT16("period_filtered_us", NRF51RNGState, + period_filtered_us, 660), + DEFINE_PROP_END_OF_LIST(), +}; + +static const VMStateDescription vmstate_rng = { + .name = "nrf51_soc.rng", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT32(active, NRF51RNGState), + VMSTATE_UINT32(event_valrdy, NRF51RNGState), + VMSTATE_UINT32(shortcut_stop_on_valrdy, NRF51RNGState), + VMSTATE_UINT32(interrupt_enabled, NRF51RNGState), + VMSTATE_UINT32(filter_enabled, NRF51RNGState), + VMSTATE_END_OF_LIST() + } +}; + +static void nrf51_rng_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc = DEVICE_CLASS(klass); + + dc->props = nrf51_rng_properties; + dc->vmsd = &vmstate_rng; + dc->reset = nrf51_rng_reset; +} + +static const TypeInfo nrf51_rng_info = { + .name = TYPE_NRF51_RNG, + .parent = TYPE_SYS_BUS_DEVICE, + .instance_size = sizeof(NRF51RNGState), + .instance_init = nrf51_rng_init, + .class_init = nrf51_rng_class_init +}; + +static void nrf51_rng_register_types(void) +{ + type_register_static(&nrf51_rng_info); +} + +type_init(nrf51_rng_register_types) diff --git a/hw/misc/omap_l4.c b/hw/misc/omap_l4.c index 96fc057b4e..c217728c78 100644 --- a/hw/misc/omap_l4.c +++ b/hw/misc/omap_l4.c @@ -112,8 +112,8 @@ static const MemoryRegionOps omap_l4ta_ops = { struct omap_target_agent_s *omap_l4ta_get(struct omap_l4_s *bus, const struct omap_l4_region_s *regions, - const struct omap_l4_agent_info_s *agents, - int cs) + const struct omap_l4_agent_info_s *agents, + int cs) { int i; struct omap_target_agent_s *ta = NULL; diff --git a/hw/misc/puv3_pm.c b/hw/misc/puv3_pm.c index 577cebaac7..afe191fbe1 100644 --- a/hw/misc/puv3_pm.c +++ b/hw/misc/puv3_pm.c @@ -119,7 +119,7 @@ static const MemoryRegionOps puv3_pm_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static int puv3_pm_init(SysBusDevice *dev) +static void puv3_pm_realize(DeviceState *dev, Error **errp) { PUV3PMState *s = PUV3_PM(dev); @@ -127,16 +127,14 @@ static int puv3_pm_init(SysBusDevice *dev) memory_region_init_io(&s->iomem, OBJECT(s), &puv3_pm_ops, s, "puv3_pm", PUV3_REGS_OFFSET); - sysbus_init_mmio(dev, &s->iomem); - - return 0; + sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->iomem); } static void puv3_pm_class_init(ObjectClass *klass, void *data) { - SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass); + DeviceClass *dc = DEVICE_CLASS(klass); - sdc->init = puv3_pm_init; + dc->realize = puv3_pm_realize; } static const TypeInfo puv3_pm_info = { diff --git a/hw/misc/tmp105.c b/hw/misc/tmp105.c index 0918f3a6ea..f6d7163273 100644 --- a/hw/misc/tmp105.c +++ b/hw/misc/tmp105.c @@ -79,7 +79,7 @@ static void tmp105_set_temperature(Object *obj, Visitor *v, const char *name, return; } if (temp >= 128000 || temp < -128000) { - error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range", + error_setg(errp, "value %" PRId64 ".%03" PRIu64 " C is out of range", temp / 1000, temp % 1000); return; } diff --git a/hw/misc/tmp421.c b/hw/misc/tmp421.c index c234044305..eeb11000f0 100644 --- a/hw/misc/tmp421.c +++ b/hw/misc/tmp421.c @@ -153,7 +153,7 @@ static void tmp421_set_temperature(Object *obj, Visitor *v, const char *name, } if (temp >= maxs[ext_range] || temp < mins[ext_range]) { - error_setg(errp, "value %" PRId64 ".%03" PRIu64 " °C is out of range", + error_setg(errp, "value %" PRId64 ".%03" PRIu64 " C is out of range", temp / 1000, temp % 1000); return; } diff --git a/hw/misc/tz-mpc.c b/hw/misc/tz-mpc.c index e0c58ba37e..9a84be75ed 100644 --- a/hw/misc/tz-mpc.c +++ b/hw/misc/tz-mpc.c @@ -150,7 +150,7 @@ static MemTxResult tz_mpc_reg_read(void *opaque, hwaddr addr, r = s->ctrl; break; case A_BLK_MAX: - r = s->blk_max; + r = s->blk_max - 1; break; case A_BLK_CFG: /* We are never in "init in progress state", so this just indicates @@ -448,7 +448,7 @@ static int tz_mpc_attrs_to_index(IOMMUMemoryRegion *iommu, MemTxAttrs attrs) { /* We treat unspecified attributes like secure. Transactions with * unspecified attributes come from places like - * cpu_physical_memory_write_rom() for initial image load, and we want + * rom_reset() for initial image load, and we want * those to pass through the from-reset "everything is secure" config. * All the real during-emulation transactions from the CPU will * specify attributes. |