diff options
Diffstat (limited to 'hw')
47 files changed, 443 insertions, 172 deletions
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c index 612fec03ee..77e1126f8f 100644 --- a/hw/acpi/pcihp.c +++ b/hw/acpi/pcihp.c @@ -120,7 +120,7 @@ static bool acpi_pcihp_pc_no_hotplug(AcpiPciHpState *s, PCIDevice *dev) static void acpi_pcihp_eject_slot(AcpiPciHpState *s, unsigned bsel, unsigned slots) { BusChild *kid, *next; - int slot = ffs(slots) - 1; + int slot = ctz32(slots); PCIBus *bus = acpi_pcihp_find_hotplug_bus(s, bsel); if (!bus) { diff --git a/hw/alpha/dp264.c b/hw/alpha/dp264.c index e82d61d28c..9fe7e8b5cb 100644 --- a/hw/alpha/dp264.c +++ b/hw/alpha/dp264.c @@ -157,9 +157,12 @@ static void clipper_init(MachineState *machine) load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); - stq_phys(&address_space_memory, - param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL); - stq_phys(&address_space_memory, param_offset + 0x108, initrd_size); + address_space_stq(&address_space_memory, param_offset + 0x100, + initrd_base + 0xfffffc0000000000ULL, + MEMTXATTRS_UNSPECIFIED, + NULL); + address_space_stq(&address_space_memory, param_offset + 0x108, + initrd_size, MEMTXATTRS_UNSPECIFIED, NULL); } } } diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c index a6044f28c3..7df842dff7 100644 --- a/hw/alpha/typhoon.c +++ b/hw/alpha/typhoon.c @@ -613,7 +613,8 @@ static bool make_iommu_tlbe(hwaddr taddr, hwaddr mask, IOMMUTLBEntry *ret) translation, given the address of the PTE. */ static bool pte_translate(hwaddr pte_addr, IOMMUTLBEntry *ret) { - uint64_t pte = ldq_phys(&address_space_memory, pte_addr); + uint64_t pte = address_space_ldq(&address_space_memory, pte_addr, + MEMTXATTRS_UNSPECIFIED, NULL); /* Check valid bit. */ if ((pte & 1) == 0) { diff --git a/hw/arm/boot.c b/hw/arm/boot.c index a48d1b28d4..fa6950352c 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -170,7 +170,8 @@ static void default_reset_secondary(ARMCPU *cpu, { CPUARMState *env = &cpu->env; - stl_phys_notdirty(&address_space_memory, info->smp_bootreg_addr, 0); + address_space_stl_notdirty(&address_space_memory, info->smp_bootreg_addr, + 0, MEMTXATTRS_UNSPECIFIED, NULL); env->regs[15] = info->smp_loader_start; } @@ -180,7 +181,8 @@ static inline bool have_dtb(const struct arm_boot_info *info) } #define WRITE_WORD(p, value) do { \ - stl_phys_notdirty(&address_space_memory, p, value); \ + address_space_stl_notdirty(&address_space_memory, p, value, \ + MEMTXATTRS_UNSPECIFIED, NULL); \ p += 4; \ } while (0) diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c index dd2a67bcf0..b2d048b911 100644 --- a/hw/arm/highbank.c +++ b/hw/arm/highbank.c @@ -69,11 +69,17 @@ static void hb_reset_secondary(ARMCPU *cpu, const struct arm_boot_info *info) switch (info->nb_cpus) { case 4: - stl_phys_notdirty(&address_space_memory, SMP_BOOT_REG + 0x30, 0); + address_space_stl_notdirty(&address_space_memory, + SMP_BOOT_REG + 0x30, 0, + MEMTXATTRS_UNSPECIFIED, NULL); case 3: - stl_phys_notdirty(&address_space_memory, SMP_BOOT_REG + 0x20, 0); + address_space_stl_notdirty(&address_space_memory, + SMP_BOOT_REG + 0x20, 0, + MEMTXATTRS_UNSPECIFIED, NULL); case 2: - stl_phys_notdirty(&address_space_memory, SMP_BOOT_REG + 0x10, 0); + address_space_stl_notdirty(&address_space_memory, + SMP_BOOT_REG + 0x10, 0, + MEMTXATTRS_UNSPECIFIED, NULL); env->regs[15] = SMP_BOOT_ADDR; break; default: diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c index 2a5406d98d..d243159664 100644 --- a/hw/arm/nseries.c +++ b/hw/arm/nseries.c @@ -579,7 +579,10 @@ static uint32_t mipid_txrx(void *opaque, uint32_t cmd, int len) case 0x26: /* GAMSET */ if (!s->pm) { - s->gamma = ffs(s->param[0] & 0xf) - 1; + s->gamma = ctz32(s->param[0] & 0xf); + if (s->gamma == 32) { + s->gamma = -1; /* XXX: should this be 0? */ + } } else if (s->pm < 0) { s->pm = 1; } diff --git a/hw/arm/omap1.c b/hw/arm/omap1.c index 91ffb589e5..de2b289257 100644 --- a/hw/arm/omap1.c +++ b/hw/arm/omap1.c @@ -2004,8 +2004,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr, case 0x04: /* OUTPUT_REG */ diff = (s->outputs ^ value) & ~s->dir; s->outputs = value; - while ((ln = ffs(diff))) { - ln --; + while ((ln = ctz32(diff)) != 32) { if (s->handler[ln]) qemu_set_irq(s->handler[ln], (value >> ln) & 1); diff &= ~(1 << ln); @@ -2017,8 +2016,7 @@ static void omap_mpuio_write(void *opaque, hwaddr addr, s->dir = value; value = s->outputs & ~s->dir; - while ((ln = ffs(diff))) { - ln --; + while ((ln = ctz32(diff)) != 32) { if (s->handler[ln]) qemu_set_irq(s->handler[ln], (value >> ln) & 1); diff &= ~(1 << ln); diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c index 165ba2a169..f921a5680c 100644 --- a/hw/arm/pxa2xx.c +++ b/hw/arm/pxa2xx.c @@ -274,7 +274,7 @@ static void pxa2xx_pwrmode_write(CPUARMState *env, const ARMCPRegInfo *ri, s->cpu->env.uncached_cpsr = ARM_CPU_MODE_SVC; s->cpu->env.daif = PSTATE_A | PSTATE_F | PSTATE_I; s->cpu->env.cp15.sctlr_ns = 0; - s->cpu->env.cp15.c1_coproc = 0; + s->cpu->env.cp15.cpacr_el1 = 0; s->cpu->env.cp15.ttbr0_el[1] = 0; s->cpu->env.cp15.dacr_ns = 0; s->pm_regs[PSSR >> 2] |= 0x8; /* Set STS */ diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c index 354ccf1ea1..c89c8045c3 100644 --- a/hw/arm/pxa2xx_gpio.c +++ b/hw/arm/pxa2xx_gpio.c @@ -137,7 +137,7 @@ static void pxa2xx_gpio_handler_update(PXA2xxGPIOInfo *s) { level = s->olevel[i] & s->dir[i]; for (diff = s->prev_level[i] ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; + bit = ctz32(diff); line = bit + 32 * i; qemu_set_irq(s->handler[line], (level >> bit) & 1); } diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index 1ddea6d89c..da9fc1d51b 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -528,7 +528,7 @@ static void strongarm_gpio_handler_update(StrongARMGPIOInfo *s) level = s->olevel & s->dir; for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; + bit = ctz32(diff); qemu_set_irq(s->handler[bit], (level >> bit) & 1); } @@ -745,7 +745,7 @@ static void strongarm_ppc_handler_update(StrongARMPPCInfo *s) level = s->olevel & s->dir; for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; + bit = ctz32(diff); qemu_set_irq(s->handler[bit], (level >> bit) & 1); } diff --git a/hw/block/fdc.c b/hw/block/fdc.c index 2bf87c9eea..f72a392163 100644 --- a/hw/block/fdc.c +++ b/hw/block/fdc.c @@ -535,8 +535,6 @@ struct FDCtrl { uint8_t pwrd; /* Floppy drives */ uint8_t num_floppies; - /* Sun4m quirks? */ - int sun4m; FDrive drives[MAX_FD]; int reset_sensei; uint32_t check_media_rate; @@ -885,13 +883,6 @@ static void fdctrl_reset_irq(FDCtrl *fdctrl) static void fdctrl_raise_irq(FDCtrl *fdctrl) { - /* Sparc mutation */ - if (fdctrl->sun4m && (fdctrl->msr & FD_MSR_CMDBUSY)) { - /* XXX: not sure */ - fdctrl->msr &= ~FD_MSR_CMDBUSY; - fdctrl->msr |= FD_MSR_RQM | FD_MSR_DIO; - return; - } if (!(fdctrl->sra & FD_SRA_INTPEND)) { qemu_set_irq(fdctrl->irq, 1); fdctrl->sra |= FD_SRA_INTPEND; @@ -1080,12 +1071,6 @@ static uint32_t fdctrl_read_main_status(FDCtrl *fdctrl) fdctrl->dsr &= ~FD_DSR_PWRDOWN; fdctrl->dor |= FD_DOR_nRESET; - /* Sparc mutation */ - if (fdctrl->sun4m) { - retval |= FD_MSR_DIO; - fdctrl_reset_irq(fdctrl); - }; - FLOPPY_DPRINTF("main status register: 0x%02x\n", retval); return retval; @@ -2241,8 +2226,6 @@ static void sun4m_fdc_initfn(Object *obj) FDCtrlSysBus *sys = SYSBUS_FDC(obj); FDCtrl *fdctrl = &sys->state; - fdctrl->sun4m = 1; - memory_region_init_io(&fdctrl->iomem, obj, &fdctrl_mem_strict_ops, fdctrl, "fdctrl", 0x08); sysbus_init_mmio(sbd, &fdctrl->iomem); diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c index afe243b811..efc43dde6a 100644 --- a/hw/block/m25p80.c +++ b/hw/block/m25p80.c @@ -621,7 +621,6 @@ static int m25p80_init(SSISlave *ss) s->size = s->pi->sector_size * s->pi->n_sectors; s->dirty_page = -1; - s->storage = blk_blockalign(s->blk, s->size); /* FIXME use a qdev drive property instead of drive_get_next() */ dinfo = drive_get_next(IF_MTD); @@ -629,6 +628,9 @@ static int m25p80_init(SSISlave *ss) if (dinfo) { DB_PRINT_L(0, "Binding to IF_MTD drive\n"); s->blk = blk_by_legacy_dinfo(dinfo); + blk_attach_dev_nofail(s->blk, s); + + s->storage = blk_blockalign(s->blk, s->size); /* FIXME: Move to late init */ if (blk_read(s->blk, 0, s->storage, @@ -638,6 +640,7 @@ static int m25p80_init(SSISlave *ss) } } else { DB_PRINT_L(0, "No BDRV - binding to RAM\n"); + s->storage = blk_blockalign(NULL, s->size); memset(s->storage, 0xFF, s->size); } diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c index 218e075df7..c903747952 100644 --- a/hw/bt/sdp.c +++ b/hw/bt/sdp.c @@ -707,7 +707,7 @@ static void sdp_service_record_build(struct sdp_service_record_s *record, len += sdp_attr_max_size(&def->attributes[record->attributes ++].data, &record->uuids); } - record->uuids = 1 << ffs(record->uuids - 1); + record->uuids = pow2ceil(record->uuids); record->attribute_list = g_malloc0(record->attributes * sizeof(*record->attribute_list)); record->uuid = diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c index e336bdb4a9..6e2ad8221b 100644 --- a/hw/char/virtio-serial-bus.c +++ b/hw/char/virtio-serial-bus.c @@ -814,12 +814,12 @@ static uint32_t find_free_port_id(VirtIOSerial *vser) max_nr_ports = vser->serial.max_virtserial_ports; for (i = 0; i < (max_nr_ports + 31) / 32; i++) { - uint32_t map, bit; + uint32_t map, zeroes; map = vser->ports_map[i]; - bit = ffs(~map); - if (bit) { - return (bit - 1) + i * 32; + zeroes = ctz32(~map); + if (zeroes != 32) { + return zeroes + i * 32; } } return VIRTIO_CONSOLE_BAD_ID; diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c index 4306adc959..66b7ade8da 100644 --- a/hw/display/tc6393xb.c +++ b/hw/display/tc6393xb.c @@ -171,7 +171,7 @@ static void tc6393xb_gpio_handler_update(TC6393xbState *s) level = s->gpio_level & s->gpio_dir; for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; + bit = ctz32(diff); qemu_set_irq(s->handler[bit], (level >> bit) & 1); } diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c index 741dd20d31..b89b4744f7 100644 --- a/hw/dma/pl080.c +++ b/hw/dma/pl080.c @@ -205,10 +205,22 @@ again: if (size == 0) { /* Transfer complete. */ if (ch->lli) { - ch->src = ldl_le_phys(&address_space_memory, ch->lli); - ch->dest = ldl_le_phys(&address_space_memory, ch->lli + 4); - ch->ctrl = ldl_le_phys(&address_space_memory, ch->lli + 12); - ch->lli = ldl_le_phys(&address_space_memory, ch->lli + 8); + ch->src = address_space_ldl_le(&address_space_memory, + ch->lli, + MEMTXATTRS_UNSPECIFIED, + NULL); + ch->dest = address_space_ldl_le(&address_space_memory, + ch->lli + 4, + MEMTXATTRS_UNSPECIFIED, + NULL); + ch->ctrl = address_space_ldl_le(&address_space_memory, + ch->lli + 12, + MEMTXATTRS_UNSPECIFIED, + NULL); + ch->lli = address_space_ldl_le(&address_space_memory, + ch->lli + 8, + MEMTXATTRS_UNSPECIFIED, + NULL); } else { ch->conf &= ~PL080_CCONF_E; } diff --git a/hw/dma/sun4m_iommu.c b/hw/dma/sun4m_iommu.c index ec7c2efcd9..9a488bc9b7 100644 --- a/hw/dma/sun4m_iommu.c +++ b/hw/dma/sun4m_iommu.c @@ -263,7 +263,8 @@ static uint32_t iommu_page_get_flags(IOMMUState *s, hwaddr addr) iopte = s->regs[IOMMU_BASE] << 4; addr &= ~s->iostart; iopte += (addr >> (IOMMU_PAGE_SHIFT - 2)) & ~3; - ret = ldl_be_phys(&address_space_memory, iopte); + ret = address_space_ldl_be(&address_space_memory, iopte, + MEMTXATTRS_UNSPECIFIED, NULL); trace_sun4m_iommu_page_get_flags(pa, iopte, ret); return ret; } diff --git a/hw/gpio/max7310.c b/hw/gpio/max7310.c index 7fbf313ce8..2f59b134ee 100644 --- a/hw/gpio/max7310.c +++ b/hw/gpio/max7310.c @@ -96,7 +96,7 @@ static int max7310_tx(I2CSlave *i2c, uint8_t data) case 0x01: /* Output port */ for (diff = (data ^ s->level) & ~s->direction; diff; diff &= ~(1 << line)) { - line = ffs(diff) - 1; + line = ctz32(diff); if (s->handler[line]) qemu_set_irq(s->handler[line], (data >> line) & 1); } diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c index 9a43486890..d92f8cfbae 100644 --- a/hw/gpio/omap_gpio.c +++ b/hw/gpio/omap_gpio.c @@ -125,8 +125,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr, case 0x04: /* DATA_OUTPUT */ diff = (s->outputs ^ value) & ~s->dir; s->outputs = value; - while ((ln = ffs(diff))) { - ln --; + while ((ln = ctz32(diff)) != 32) { if (s->handler[ln]) qemu_set_irq(s->handler[ln], (value >> ln) & 1); diff &= ~(1 << ln); @@ -138,8 +137,7 @@ static void omap_gpio_write(void *opaque, hwaddr addr, s->dir = value; value = s->outputs & ~s->dir; - while ((ln = ffs(diff))) { - ln --; + while ((ln = ctz32(diff)) != 32) { if (s->handler[ln]) qemu_set_irq(s->handler[ln], (value >> ln) & 1); diff &= ~(1 << ln); @@ -253,8 +251,7 @@ static inline void omap2_gpio_module_out_update(struct omap2_gpio_s *s, s->outputs ^= diff; diff &= ~s->dir; - while ((ln = ffs(diff))) { - ln --; + while ((ln = ctz32(diff)) != 32) { qemu_set_irq(s->handler[ln], (s->outputs >> ln) & 1); diff &= ~(1 << ln); } @@ -442,8 +439,8 @@ static void omap2_gpio_module_write(void *opaque, hwaddr addr, s->dir = value; value = s->outputs & ~s->dir; - while ((ln = ffs(diff))) { - diff &= ~(1 <<-- ln); + while ((ln = ctz32(diff)) != 32) { + diff &= ~(1 << ln); qemu_set_irq(s->handler[ln], (value >> ln) & 1); } diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c index 94083424f8..24a77272d7 100644 --- a/hw/gpio/zaurus.c +++ b/hw/gpio/zaurus.c @@ -65,7 +65,7 @@ static inline void scoop_gpio_handler_update(ScoopInfo *s) { level = s->gpio_level & s->gpio_dir; for (diff = s->prev_level ^ level; diff; diff ^= 1 << bit) { - bit = ffs(diff) - 1; + bit = ctz32(diff); qemu_set_irq(s->handler[bit], (level >> bit) & 1); } diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c index d63278dbde..b6f544a221 100644 --- a/hw/i2c/omap_i2c.c +++ b/hw/i2c/omap_i2c.c @@ -171,9 +171,13 @@ static uint32_t omap_i2c_read(void *opaque, hwaddr addr) case 0x0c: /* I2C_IV */ if (s->revision >= OMAP2_INTR_REV) break; - ret = ffs(s->stat & s->mask); - if (ret) - s->stat ^= 1 << (ret - 1); + ret = ctz32(s->stat & s->mask); + if (ret != 32) { + s->stat ^= 1 << ret; + ret++; + } else { + ret = 0; + } omap_i2c_interrupts_update(s); return ret; diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c index 7da70ff349..08055a8d8a 100644 --- a/hw/i386/intel_iommu.c +++ b/hw/i386/intel_iommu.c @@ -246,7 +246,8 @@ static void vtd_generate_interrupt(IntelIOMMUState *s, hwaddr mesg_addr_reg, data = vtd_get_long_raw(s, mesg_data_reg); VTD_DPRINTF(FLOG, "msi: addr 0x%"PRIx64 " data 0x%"PRIx32, addr, data); - stl_le_phys(&address_space_memory, addr, data); + address_space_stl_le(&address_space_memory, addr, data, + MEMTXATTRS_UNSPECIFIED, NULL); } /* Generate a fault event to software via MSI if conditions are met. diff --git a/hw/intc/allwinner-a10-pic.c b/hw/intc/allwinner-a10-pic.c index de820b9723..eed7621f13 100644 --- a/hw/intc/allwinner-a10-pic.c +++ b/hw/intc/allwinner-a10-pic.c @@ -23,7 +23,7 @@ static void aw_a10_pic_update(AwA10PICState *s) { uint8_t i; - int irq = 0, fiq = 0, pending; + int irq = 0, fiq = 0, zeroes; s->vector = 0; @@ -32,9 +32,9 @@ static void aw_a10_pic_update(AwA10PICState *s) fiq |= s->select[i] & s->irq_pending[i] & ~s->mask[i]; if (!s->vector) { - pending = ffs(s->irq_pending[i] & ~s->mask[i]); - if (pending) { - s->vector = (i * 32 + pending - 1) * 4; + zeroes = ctz32(s->irq_pending[i] & ~s->mask[i]); + if (zeroes != 32) { + s->vector = (i * 32 + zeroes) * 4; } } } diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c index ad3931c112..e9b38a3c63 100644 --- a/hw/intc/omap_intc.c +++ b/hw/intc/omap_intc.c @@ -60,7 +60,7 @@ struct omap_intr_handler_s { static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq) { - int i, j, sir_intr, p_intr, p, f; + int i, j, sir_intr, p_intr, p; uint32_t level; sir_intr = 0; p_intr = 255; @@ -72,14 +72,15 @@ static void omap_inth_sir_update(struct omap_intr_handler_s *s, int is_fiq) for (j = 0; j < s->nbanks; ++j) { level = s->bank[j].irqs & ~s->bank[j].mask & (is_fiq ? s->bank[j].fiq : ~s->bank[j].fiq); - for (f = ffs(level), i = f - 1, level >>= f - 1; f; i += f, - level >>= f) { + + while (level != 0) { + i = ctz32(level); p = s->bank[j].priority[i]; if (p <= p_intr) { p_intr = p; sir_intr = 32 * j + i; } - f = ffs(level >> 1); + level &= level - 1; } } s->sir_intr[is_fiq] = sir_intr; diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c index 07f3c270d4..2c153e092f 100644 --- a/hw/mips/mips_jazz.c +++ b/hw/mips/mips_jazz.c @@ -61,7 +61,8 @@ static void main_cpu_reset(void *opaque) static uint64_t rtc_read(void *opaque, hwaddr addr, unsigned size) { uint8_t val; - address_space_read(&address_space_memory, 0x90000071, &val, 1); + address_space_read(&address_space_memory, 0x90000071, + MEMTXATTRS_UNSPECIFIED, &val, 1); return val; } @@ -69,7 +70,8 @@ static void rtc_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { uint8_t buf = val & 0xff; - address_space_write(&address_space_memory, 0x90000071, &buf, 1); + address_space_write(&address_space_memory, 0x90000071, + MEMTXATTRS_UNSPECIFIED, &buf, 1); } static const MemoryRegionOps rtc_ops = { diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c index 312fa703c6..599768e2d9 100644 --- a/hw/pci-host/apb.c +++ b/hw/pci-host/apb.c @@ -289,7 +289,8 @@ static IOMMUTLBEntry pbm_translate_iommu(MemoryRegion *iommu, hwaddr addr, } } - tte = ldq_be_phys(&address_space_memory, baseaddr + offset); + tte = address_space_ldq_be(&address_space_memory, baseaddr + offset, + MEMTXATTRS_UNSPECIFIED, NULL); if (!(tte & IOMMU_TTE_DATA_V)) { /* Invalid mapping */ diff --git a/hw/pci-host/bonito.c b/hw/pci-host/bonito.c index 8134d0bcd0..3a731fe18d 100644 --- a/hw/pci-host/bonito.c +++ b/hw/pci-host/bonito.c @@ -427,7 +427,7 @@ static uint32_t bonito_sbridge_pciaddr(void *opaque, hwaddr addr) cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16; idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET; - devno = ffs(idsel) - 1; + devno = ctz32(idsel); funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET; regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET; diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c index 6cea6ffebb..c63f45d217 100644 --- a/hw/pci-host/prep.c +++ b/hw/pci-host/prep.c @@ -140,7 +140,8 @@ static uint64_t raven_io_read(void *opaque, hwaddr addr, uint8_t buf[4]; addr = raven_io_address(s, addr); - address_space_read(&s->pci_io_as, addr + 0x80000000, buf, size); + address_space_read(&s->pci_io_as, addr + 0x80000000, + MEMTXATTRS_UNSPECIFIED, buf, size); if (size == 1) { return buf[0]; @@ -171,7 +172,8 @@ static void raven_io_write(void *opaque, hwaddr addr, g_assert_not_reached(); } - address_space_write(&s->pci_io_as, addr + 0x80000000, buf, size); + address_space_write(&s->pci_io_as, addr + 0x80000000, + MEMTXATTRS_UNSPECIFIED, buf, size); } static const MemoryRegionOps raven_io_ops = { diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c index 53f2b59ae8..f0144eb7b0 100644 --- a/hw/pci-host/uninorth.c +++ b/hw/pci-host/uninorth.c @@ -92,7 +92,10 @@ static uint32_t unin_get_config_reg(uint32_t reg, uint32_t addr) uint32_t slot, func; /* Grab CFA0 style values */ - slot = ffs(reg & 0xfffff800) - 1; + slot = ctz32(reg & 0xfffff800); + if (slot == 32) { + slot = -1; /* XXX: should this be 0? */ + } func = (reg >> 8) & 7; /* ... and then convert them to x86 format */ diff --git a/hw/pci/msi.c b/hw/pci/msi.c index 52d23130d9..2949938223 100644 --- a/hw/pci/msi.c +++ b/hw/pci/msi.c @@ -72,7 +72,7 @@ static inline uint8_t msi_cap_sizeof(uint16_t flags) static inline unsigned int msi_nr_vectors(uint16_t flags) { return 1U << - ((flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1)); + ((flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE)); } static inline uint8_t msi_flags_off(const PCIDevice* dev) @@ -175,9 +175,9 @@ int msi_init(struct PCIDevice *dev, uint8_t offset, assert(nr_vectors > 0); assert(nr_vectors <= PCI_MSI_VECTORS_MAX); /* the nr of MSI vectors is up to 32 */ - vectors_order = ffs(nr_vectors) - 1; + vectors_order = ctz32(nr_vectors); - flags = vectors_order << (ffs(PCI_MSI_FLAGS_QMASK) - 1); + flags = vectors_order << ctz32(PCI_MSI_FLAGS_QMASK); if (msi64bit) { flags |= PCI_MSI_FLAGS_64BIT; } @@ -291,7 +291,8 @@ void msi_notify(PCIDevice *dev, unsigned int vector) "notify vector 0x%x" " address: 0x%"PRIx64" data: 0x%"PRIx32"\n", vector, msg.address, msg.data); - stl_le_phys(&dev->bus_master_as, msg.address, msg.data); + address_space_stl_le(&dev->bus_master_as, msg.address, msg.data, + MEMTXATTRS_UNSPECIFIED, NULL); } /* Normally called by pci_default_write_config(). */ @@ -354,12 +355,12 @@ void msi_write_config(PCIDevice *dev, uint32_t addr, uint32_t val, int len) * just don't crash the host */ log_num_vecs = - (flags & PCI_MSI_FLAGS_QSIZE) >> (ffs(PCI_MSI_FLAGS_QSIZE) - 1); + (flags & PCI_MSI_FLAGS_QSIZE) >> ctz32(PCI_MSI_FLAGS_QSIZE); log_max_vecs = - (flags & PCI_MSI_FLAGS_QMASK) >> (ffs(PCI_MSI_FLAGS_QMASK) - 1); + (flags & PCI_MSI_FLAGS_QMASK) >> ctz32(PCI_MSI_FLAGS_QMASK); if (log_num_vecs > log_max_vecs) { flags &= ~PCI_MSI_FLAGS_QSIZE; - flags |= log_max_vecs << (ffs(PCI_MSI_FLAGS_QSIZE) - 1); + flags |= log_max_vecs << ctz32(PCI_MSI_FLAGS_QSIZE); pci_set_word(dev->config + msi_flags_off(dev), flags); } diff --git a/hw/pci/msix.c b/hw/pci/msix.c index 24de2605fb..031eaabca9 100644 --- a/hw/pci/msix.c +++ b/hw/pci/msix.c @@ -435,7 +435,8 @@ void msix_notify(PCIDevice *dev, unsigned vector) msg = msix_get_message(dev, vector); - stl_le_phys(&dev->bus_master_as, msg.address, msg.data); + address_space_stl_le(&dev->bus_master_as, msg.address, msg.data, + MEMTXATTRS_UNSPECIFIED, NULL); } void msix_reset(PCIDevice *dev) diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c index eaa3e6ea94..b48c09cd11 100644 --- a/hw/pci/pcie_aer.c +++ b/hw/pci/pcie_aer.c @@ -410,7 +410,7 @@ static void pcie_aer_msg(PCIDevice *dev, const PCIEAERMsg *msg) static void pcie_aer_update_log(PCIDevice *dev, const PCIEAERErr *err) { uint8_t *aer_cap = dev->config + dev->exp.aer_cap; - uint8_t first_bit = ffs(err->status) - 1; + uint8_t first_bit = ctz32(err->status); uint32_t errcap = pci_get_long(aer_cap + PCI_ERR_CAP); int i; diff --git a/hw/pci/shpc.c b/hw/pci/shpc.c index 759910f79a..a706486394 100644 --- a/hw/pci/shpc.c +++ b/hw/pci/shpc.c @@ -61,7 +61,7 @@ /* Same slot state masks are used for command and status registers */ #define SHPC_SLOT_STATE_MASK 0x03 #define SHPC_SLOT_STATE_SHIFT \ - (ffs(SHPC_SLOT_STATE_MASK) - 1) + ctz32(SHPC_SLOT_STATE_MASK) #define SHPC_STATE_NO 0x0 #define SHPC_STATE_PWRONLY 0x1 @@ -70,10 +70,10 @@ #define SHPC_SLOT_PWR_LED_MASK 0xC #define SHPC_SLOT_PWR_LED_SHIFT \ - (ffs(SHPC_SLOT_PWR_LED_MASK) - 1) + ctz32(SHPC_SLOT_PWR_LED_MASK) #define SHPC_SLOT_ATTN_LED_MASK 0x30 #define SHPC_SLOT_ATTN_LED_SHIFT \ - (ffs(SHPC_SLOT_ATTN_LED_MASK) - 1) + ctz32(SHPC_SLOT_ATTN_LED_MASK) #define SHPC_LED_NO 0x0 #define SHPC_LED_ON 0x1 @@ -136,7 +136,7 @@ static int roundup_pow_of_two(int x) static uint16_t shpc_get_status(SHPCDevice *shpc, int slot, uint16_t msk) { uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot); - return (pci_get_word(status) & msk) >> (ffs(msk) - 1); + return (pci_get_word(status) & msk) >> ctz32(msk); } static void shpc_set_status(SHPCDevice *shpc, @@ -144,7 +144,7 @@ static void shpc_set_status(SHPCDevice *shpc, { uint8_t *status = shpc->config + SHPC_SLOT_STATUS(slot); pci_word_test_and_clear_mask(status, msk); - pci_word_test_and_set_mask(status, value << (ffs(msk) - 1)); + pci_word_test_and_set_mask(status, value << ctz32(msk)); } static void shpc_interrupt_update(PCIDevice *d) diff --git a/hw/pci/slotid_cap.c b/hw/pci/slotid_cap.c index 62f7bae2f1..1c01d346c9 100644 --- a/hw/pci/slotid_cap.c +++ b/hw/pci/slotid_cap.c @@ -3,7 +3,7 @@ #include "qemu/error-report.h" #define SLOTID_CAP_LENGTH 4 -#define SLOTID_NSLOTS_SHIFT (ffs(PCI_SID_ESR_NSLOTS) - 1) +#define SLOTID_NSLOTS_SHIFT ctz32(PCI_SID_ESR_NSLOTS) int slotid_cap_init(PCIDevice *d, int nslots, uint8_t chassis, diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c index d49f2b8803..a99f7b0397 100644 --- a/hw/ppc/ppce500_spin.c +++ b/hw/ppc/ppce500_spin.c @@ -74,7 +74,7 @@ static void spin_reset(void *opaque) /* Create -kernel TLB entries for BookE, linearly spanning 256MB. */ static inline hwaddr booke206_page_size_to_tlb(uint64_t size) { - return (ffs(size >> 10) - 1) >> 1; + return ctz32(size >> 10) >> 1; } static void mmubooke_create_initial_mapping(CPUPPCState *env, diff --git a/hw/s390x/css.c b/hw/s390x/css.c index 9a13b006dd..5561d807dc 100644 --- a/hw/s390x/css.c +++ b/hw/s390x/css.c @@ -745,20 +745,27 @@ static void css_update_chnmon(SubchDev *sch) /* Format 1, per-subchannel area. */ uint32_t count; - count = ldl_phys(&address_space_memory, sch->curr_status.mba); + count = address_space_ldl(&address_space_memory, + sch->curr_status.mba, + MEMTXATTRS_UNSPECIFIED, + NULL); count++; - stl_phys(&address_space_memory, sch->curr_status.mba, count); + address_space_stl(&address_space_memory, sch->curr_status.mba, count, + MEMTXATTRS_UNSPECIFIED, NULL); } else { /* Format 0, global area. */ uint32_t offset; uint16_t count; offset = sch->curr_status.pmcw.mbi << 5; - count = lduw_phys(&address_space_memory, - channel_subsys->chnmon_area + offset); + count = address_space_lduw(&address_space_memory, + channel_subsys->chnmon_area + offset, + MEMTXATTRS_UNSPECIFIED, + NULL); count++; - stw_phys(&address_space_memory, - channel_subsys->chnmon_area + offset, count); + address_space_stw(&address_space_memory, + channel_subsys->chnmon_area + offset, count, + MEMTXATTRS_UNSPECIFIED, NULL); } } diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c index 3c086f6155..560b66a501 100644 --- a/hw/s390x/s390-pci-bus.c +++ b/hw/s390x/s390-pci-bus.c @@ -278,7 +278,8 @@ static uint64_t s390_guest_io_table_walk(uint64_t guest_iota, px = calc_px(guest_dma_address); sto_a = guest_iota + rtx * sizeof(uint64_t); - sto = ldq_phys(&address_space_memory, sto_a); + sto = address_space_ldq(&address_space_memory, sto_a, + MEMTXATTRS_UNSPECIFIED, NULL); sto = get_rt_sto(sto); if (!sto) { pte = 0; @@ -286,7 +287,8 @@ static uint64_t s390_guest_io_table_walk(uint64_t guest_iota, } pto_a = sto + sx * sizeof(uint64_t); - pto = ldq_phys(&address_space_memory, pto_a); + pto = address_space_ldq(&address_space_memory, pto_a, + MEMTXATTRS_UNSPECIFIED, NULL); pto = get_st_pto(pto); if (!pto) { pte = 0; @@ -294,7 +296,8 @@ static uint64_t s390_guest_io_table_walk(uint64_t guest_iota, } px_a = pto + px * sizeof(uint64_t); - pte = ldq_phys(&address_space_memory, px_a); + pte = address_space_ldq(&address_space_memory, px_a, + MEMTXATTRS_UNSPECIFIED, NULL); out: return pte; diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c index 08d8aa6b4b..8f7288fadf 100644 --- a/hw/s390x/s390-pci-inst.c +++ b/hw/s390x/s390-pci-inst.c @@ -331,7 +331,8 @@ int pcilg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) return 0; } MemoryRegion *mr = pbdev->pdev->io_regions[pcias].memory; - io_mem_read(mr, offset, &data, len); + memory_region_dispatch_read(mr, offset, &data, len, + MEMTXATTRS_UNSPECIFIED); } else if (pcias == 15) { if ((4 - (offset & 0x3)) < len) { program_interrupt(env, PGM_OPERAND, 4); @@ -456,7 +457,8 @@ int pcistg_service_call(S390CPU *cpu, uint8_t r1, uint8_t r2) mr = pbdev->pdev->io_regions[pcias].memory; } - io_mem_write(mr, offset, data, len); + memory_region_dispatch_write(mr, offset, data, len, + MEMTXATTRS_UNSPECIFIED); } else if (pcias == 15) { if ((4 - (offset & 0x3)) < len) { program_interrupt(env, PGM_OPERAND, 4); @@ -606,7 +608,9 @@ int pcistb_service_call(S390CPU *cpu, uint8_t r1, uint8_t r3, uint64_t gaddr) } for (i = 0; i < len / 8; i++) { - io_mem_write(mr, env->regs[r3] + i * 8, ldq_p(buffer + i * 8), 8); + memory_region_dispatch_write(mr, env->regs[r3] + i * 8, + ldq_p(buffer + i * 8), 8, + MEMTXATTRS_UNSPECIFIED); } setcc(cpu, ZPCI_PCI_LS_OK); diff --git a/hw/s390x/s390-virtio-bus.c b/hw/s390x/s390-virtio-bus.c index 047c963698..0f93a644a2 100644 --- a/hw/s390x/s390-virtio-bus.c +++ b/hw/s390x/s390-virtio-bus.c @@ -75,10 +75,12 @@ void s390_virtio_reset_idx(VirtIOS390Device *dev) for (i = 0; i < num_vq; i++) { idx_addr = virtio_queue_get_avail_addr(dev->vdev, i) + VIRTIO_VRING_AVAIL_IDX_OFFS; - stw_phys(&address_space_memory, idx_addr, 0); + address_space_stw(&address_space_memory, idx_addr, 0, + MEMTXATTRS_UNSPECIFIED, NULL); idx_addr = virtio_queue_get_used_addr(dev->vdev, i) + VIRTIO_VRING_USED_IDX_OFFS; - stw_phys(&address_space_memory, idx_addr, 0); + address_space_stw(&address_space_memory, idx_addr, 0, + MEMTXATTRS_UNSPECIFIED, NULL); } } @@ -336,7 +338,8 @@ static uint64_t s390_virtio_device_vq_token(VirtIOS390Device *dev, int vq) (vq * VIRTIO_VQCONFIG_LEN) + VIRTIO_VQCONFIG_OFFS_TOKEN; - return ldq_be_phys(&address_space_memory, token_off); + return address_space_ldq_be(&address_space_memory, token_off, + MEMTXATTRS_UNSPECIFIED, NULL); } static ram_addr_t s390_virtio_device_num_vq(VirtIOS390Device *dev) @@ -371,21 +374,33 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) virtio_reset(dev->vdev); /* Sync dev space */ - stb_phys(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, dev->vdev->device_id); - - stb_phys(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, - s390_virtio_device_num_vq(dev)); - stb_phys(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, dev->feat_len); - - stb_phys(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, dev->vdev->config_len); + address_space_stb(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_TYPE, + dev->vdev->device_id, + MEMTXATTRS_UNSPECIFIED, + NULL); + + address_space_stb(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, + s390_virtio_device_num_vq(dev), + MEMTXATTRS_UNSPECIFIED, + NULL); + address_space_stb(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_FEATURE_LEN, + dev->feat_len, + MEMTXATTRS_UNSPECIFIED, + NULL); + + address_space_stb(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_CONFIG_LEN, + dev->vdev->config_len, + MEMTXATTRS_UNSPECIFIED, + NULL); num_vq = s390_virtio_device_num_vq(dev); - stb_phys(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq); + address_space_stb(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_NUM_VQ, num_vq, + MEMTXATTRS_UNSPECIFIED, NULL); /* Sync virtqueues */ for (i = 0; i < num_vq; i++) { @@ -396,11 +411,14 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) vring = s390_virtio_next_ring(bus); virtio_queue_set_addr(dev->vdev, i, vring); virtio_queue_set_vector(dev->vdev, i, i); - stq_be_phys(&address_space_memory, - vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring); - stw_be_phys(&address_space_memory, - vq + VIRTIO_VQCONFIG_OFFS_NUM, - virtio_queue_get_num(dev->vdev, i)); + address_space_stq_be(&address_space_memory, + vq + VIRTIO_VQCONFIG_OFFS_ADDRESS, vring, + MEMTXATTRS_UNSPECIFIED, NULL); + address_space_stw_be(&address_space_memory, + vq + VIRTIO_VQCONFIG_OFFS_NUM, + virtio_queue_get_num(dev->vdev, i), + MEMTXATTRS_UNSPECIFIED, + NULL); } cur_offs = dev->dev_offs; @@ -408,7 +426,8 @@ void s390_virtio_device_sync(VirtIOS390Device *dev) cur_offs += num_vq * VIRTIO_VQCONFIG_LEN; /* Sync feature bitmap */ - stl_le_phys(&address_space_memory, cur_offs, dev->host_features); + address_space_stl_le(&address_space_memory, cur_offs, dev->host_features, + MEMTXATTRS_UNSPECIFIED, NULL); dev->feat_offs = cur_offs + dev->feat_len; cur_offs += dev->feat_len * 2; @@ -426,12 +445,16 @@ void s390_virtio_device_update_status(VirtIOS390Device *dev) VirtIODevice *vdev = dev->vdev; uint32_t features; - virtio_set_status(vdev, ldub_phys(&address_space_memory, - dev->dev_offs + VIRTIO_DEV_OFFS_STATUS)); + virtio_set_status(vdev, + address_space_ldub(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, + MEMTXATTRS_UNSPECIFIED, NULL)); /* Update guest supported feature bitmap */ - features = bswap32(ldl_be_phys(&address_space_memory, dev->feat_offs)); + features = bswap32(address_space_ldl_be(&address_space_memory, + dev->feat_offs, + MEMTXATTRS_UNSPECIFIED, NULL)); virtio_set_features(vdev, features); } diff --git a/hw/s390x/s390-virtio.c b/hw/s390x/s390-virtio.c index bdb538859f..3a1b9ee2d0 100644 --- a/hw/s390x/s390-virtio.c +++ b/hw/s390x/s390-virtio.c @@ -97,7 +97,9 @@ static int s390_virtio_hcall_reset(const uint64_t *args) return -EINVAL; } virtio_reset(dev->vdev); - stb_phys(&address_space_memory, dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0); + address_space_stb(&address_space_memory, + dev->dev_offs + VIRTIO_DEV_OFFS_STATUS, 0, + MEMTXATTRS_UNSPECIFIED, NULL); s390_virtio_device_sync(dev); s390_virtio_reset_idx(dev); diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c index d32ecafe98..ed75c638bc 100644 --- a/hw/s390x/virtio-ccw.c +++ b/hw/s390x/virtio-ccw.c @@ -335,16 +335,23 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - info.queue = ldq_phys(&address_space_memory, ccw.cda); - info.align = ldl_phys(&address_space_memory, - ccw.cda + sizeof(info.queue)); - info.index = lduw_phys(&address_space_memory, - ccw.cda + sizeof(info.queue) - + sizeof(info.align)); - info.num = lduw_phys(&address_space_memory, - ccw.cda + sizeof(info.queue) - + sizeof(info.align) - + sizeof(info.index)); + info.queue = address_space_ldq(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); + info.align = address_space_ldl(&address_space_memory, + ccw.cda + sizeof(info.queue), + MEMTXATTRS_UNSPECIFIED, + NULL); + info.index = address_space_lduw(&address_space_memory, + ccw.cda + sizeof(info.queue) + + sizeof(info.align), + MEMTXATTRS_UNSPECIFIED, + NULL); + info.num = address_space_lduw(&address_space_memory, + ccw.cda + sizeof(info.queue) + + sizeof(info.align) + + sizeof(info.index), + MEMTXATTRS_UNSPECIFIED, + NULL); ret = virtio_ccw_set_vqs(sch, info.queue, info.align, info.index, info.num); sch->curr_status.scsw.count = 0; @@ -369,15 +376,20 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - features.index = ldub_phys(&address_space_memory, - ccw.cda + sizeof(features.features)); + features.index = address_space_ldub(&address_space_memory, + ccw.cda + + sizeof(features.features), + MEMTXATTRS_UNSPECIFIED, + NULL); if (features.index < ARRAY_SIZE(dev->host_features)) { features.features = dev->host_features[features.index]; } else { /* Return zeroes if the guest supports more feature bits. */ features.features = 0; } - stl_le_phys(&address_space_memory, ccw.cda, features.features); + address_space_stl_le(&address_space_memory, ccw.cda, + features.features, MEMTXATTRS_UNSPECIFIED, + NULL); sch->curr_status.scsw.count = ccw.count - sizeof(features); ret = 0; } @@ -396,9 +408,15 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - features.index = ldub_phys(&address_space_memory, - ccw.cda + sizeof(features.features)); - features.features = ldl_le_phys(&address_space_memory, ccw.cda); + features.index = address_space_ldub(&address_space_memory, + ccw.cda + + sizeof(features.features), + MEMTXATTRS_UNSPECIFIED, + NULL); + features.features = address_space_ldl_le(&address_space_memory, + ccw.cda, + MEMTXATTRS_UNSPECIFIED, + NULL); if (features.index < ARRAY_SIZE(dev->host_features)) { virtio_set_features(vdev, features.features); } else { @@ -474,7 +492,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - status = ldub_phys(&address_space_memory, ccw.cda); + status = address_space_ldub(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) { virtio_ccw_stop_ioeventfd(dev); } @@ -508,7 +527,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - indicators = ldq_be_phys(&address_space_memory, ccw.cda); + indicators = address_space_ldq_be(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); dev->indicators = get_indicator(indicators, sizeof(uint64_t)); sch->curr_status.scsw.count = ccw.count - sizeof(indicators); ret = 0; @@ -528,7 +548,8 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - indicators = ldq_be_phys(&address_space_memory, ccw.cda); + indicators = address_space_ldq_be(&address_space_memory, ccw.cda, + MEMTXATTRS_UNSPECIFIED, NULL); dev->indicators2 = get_indicator(indicators, sizeof(uint64_t)); sch->curr_status.scsw.count = ccw.count - sizeof(indicators); ret = 0; @@ -548,15 +569,21 @@ static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw) if (!ccw.cda) { ret = -EFAULT; } else { - vq_config.index = lduw_be_phys(&address_space_memory, ccw.cda); + vq_config.index = address_space_lduw_be(&address_space_memory, + ccw.cda, + MEMTXATTRS_UNSPECIFIED, + NULL); if (vq_config.index >= VIRTIO_PCI_QUEUE_MAX) { ret = -EINVAL; break; } vq_config.num_max = virtio_queue_get_num(vdev, vq_config.index); - stw_be_phys(&address_space_memory, - ccw.cda + sizeof(vq_config.index), vq_config.num_max); + address_space_stw_be(&address_space_memory, + ccw.cda + sizeof(vq_config.index), + vq_config.num_max, + MEMTXATTRS_UNSPECIFIED, + NULL); sch->curr_status.scsw.count = ccw.count - sizeof(vq_config); ret = 0; } @@ -1068,9 +1095,13 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) css_adapter_interrupt(dev->thinint_isc); } } else { - indicators = ldq_phys(&address_space_memory, dev->indicators->addr); + indicators = address_space_ldq(&address_space_memory, + dev->indicators->addr, + MEMTXATTRS_UNSPECIFIED, + NULL); indicators |= 1ULL << vector; - stq_phys(&address_space_memory, dev->indicators->addr, indicators); + address_space_stq(&address_space_memory, dev->indicators->addr, + indicators, MEMTXATTRS_UNSPECIFIED, NULL); css_conditional_io_interrupt(sch); } } else { @@ -1078,9 +1109,13 @@ static void virtio_ccw_notify(DeviceState *d, uint16_t vector) return; } vector = 0; - indicators = ldq_phys(&address_space_memory, dev->indicators2->addr); + indicators = address_space_ldq(&address_space_memory, + dev->indicators2->addr, + MEMTXATTRS_UNSPECIFIED, + NULL); indicators |= 1ULL << vector; - stq_phys(&address_space_memory, dev->indicators2->addr, indicators); + address_space_stq(&address_space_memory, dev->indicators2->addr, + indicators, MEMTXATTRS_UNSPECIFIED, NULL); css_conditional_io_interrupt(sch); } } diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index ad7317bfe9..91a5d97c73 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -804,7 +804,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd) MFI_INFO_LDOPS_READ_POLICY); info.max_strips_per_io = cpu_to_le16(s->fw_sge); info.stripe_sz_ops.min = 3; - info.stripe_sz_ops.max = ffs(MEGASAS_MAX_SECTORS + 1) - 1; + info.stripe_sz_ops.max = ctz32(MEGASAS_MAX_SECTORS + 1); info.properties.pred_fail_poll_interval = cpu_to_le16(300); info.properties.intr_throttle_cnt = cpu_to_le16(16); info.properties.intr_throttle_timeout = cpu_to_le16(50); diff --git a/hw/sd/sd.c b/hw/sd/sd.c index f955265f74..8abf0c9e31 100644 --- a/hw/sd/sd.c +++ b/hw/sd/sd.c @@ -796,8 +796,9 @@ static sd_rsp_type_t sd_normal_command(SDState *sd, sd->vhs = 0; /* No response if not exactly one VHS bit is set. */ - if (!(req.arg >> 8) || (req.arg >> ffs(req.arg & ~0xff))) + if (!(req.arg >> 8) || (req.arg >> (ctz32(req.arg & ~0xff) + 1))) { return sd->spi ? sd_r7 : sd_r0; + } /* Accept. */ sd->vhs = req.arg; diff --git a/hw/sh4/r2d.c b/hw/sh4/r2d.c index d1d0847ba2..4221060308 100644 --- a/hw/sh4/r2d.c +++ b/hw/sh4/r2d.c @@ -318,8 +318,10 @@ static void r2d_init(MachineState *machine) } /* initialization which should be done by firmware */ - stl_phys(&address_space_memory, SH7750_BCR1, 1<<3); /* cs3 SDRAM */ - stw_phys(&address_space_memory, SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */ + address_space_stl(&address_space_memory, SH7750_BCR1, 1 << 3, + MEMTXATTRS_UNSPECIFIED, NULL); /* cs3 SDRAM */ + address_space_stw(&address_space_memory, SH7750_BCR2, 3 << (3 * 2), + MEMTXATTRS_UNSPECIFIED, NULL); /* cs3 32bit */ reset_info->vector = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */ } diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c index 78d86be91c..b6b8a2063d 100644 --- a/hw/timer/hpet.c +++ b/hw/timer/hpet.c @@ -206,8 +206,9 @@ static void update_irq(struct HPETTimer *timer, int set) } } } else if (timer_fsb_route(timer)) { - stl_le_phys(&address_space_memory, - timer->fsb >> 32, timer->fsb & 0xffffffff); + address_space_stl_le(&address_space_memory, timer->fsb >> 32, + timer->fsb & 0xffffffff, MEMTXATTRS_UNSPECIFIED, + NULL); } else if (timer->config & HPET_TN_TYPE_LEVEL) { s->isr |= mask; /* fold the ICH PIRQ# pin's internal inversion logic into hpet */ diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index 6b80539c1f..e0e339a534 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -154,6 +154,7 @@ typedef struct VFIOPCIDevice { PCIHostDeviceAddress host; EventNotifier err_notifier; EventNotifier req_notifier; + int (*resetfn)(struct VFIOPCIDevice *); uint32_t features; #define VFIO_FEATURE_ENABLE_VGA_BIT 0 #define VFIO_FEATURE_ENABLE_VGA (1 << VFIO_FEATURE_ENABLE_VGA_BIT) @@ -1531,9 +1532,12 @@ static uint64_t vfio_rtl8168_window_quirk_read(void *opaque, return 0; } - io_mem_read(&vdev->pdev.msix_table_mmio, - (hwaddr)(quirk->data.address_match & 0xfff), - &val, size); + memory_region_dispatch_read(&vdev->pdev.msix_table_mmio, + (hwaddr)(quirk->data.address_match + & 0xfff), + &val, + size, + MEMTXATTRS_UNSPECIFIED); return val; } } @@ -1561,9 +1565,12 @@ static void vfio_rtl8168_window_quirk_write(void *opaque, hwaddr addr, memory_region_name(&quirk->mem), vdev->vbasedev.name); - io_mem_write(&vdev->pdev.msix_table_mmio, - (hwaddr)(quirk->data.address_match & 0xfff), - data, size); + memory_region_dispatch_write(&vdev->pdev.msix_table_mmio, + (hwaddr)(quirk->data.address_match + & 0xfff), + data, + size, + MEMTXATTRS_UNSPECIFIED); } quirk->data.flags = 1; @@ -2394,7 +2401,7 @@ static void vfio_map_bar(VFIOPCIDevice *vdev, int nr) if (vdev->msix && vdev->msix->table_bar == nr) { uint64_t start; - start = HOST_PAGE_ALIGN(vdev->msix->table_offset + + start = HOST_PAGE_ALIGN((uint64_t)vdev->msix->table_offset + (vdev->msix->entries * PCI_MSIX_ENTRY_SIZE)); size = start < bar->region.size ? bar->region.size - start : 0; @@ -3319,6 +3326,162 @@ static void vfio_unregister_req_notifier(VFIOPCIDevice *vdev) vdev->req_enabled = false; } +/* + * AMD Radeon PCI config reset, based on Linux: + * drivers/gpu/drm/radeon/ci_smc.c:ci_is_smc_running() + * drivers/gpu/drm/radeon/radeon_device.c:radeon_pci_config_reset + * drivers/gpu/drm/radeon/ci_smc.c:ci_reset_smc() + * drivers/gpu/drm/radeon/ci_smc.c:ci_stop_smc_clock() + * IDs: include/drm/drm_pciids.h + * Registers: http://cgit.freedesktop.org/~agd5f/linux/commit/?id=4e2aa447f6f0 + * + * Bonaire and Hawaii GPUs do not respond to a bus reset. This is a bug in the + * hardware that should be fixed on future ASICs. The symptom of this is that + * once the accerlated driver loads, Windows guests will bsod on subsequent + * attmpts to load the driver, such as after VM reset or shutdown/restart. To + * work around this, we do an AMD specific PCI config reset, followed by an SMC + * reset. The PCI config reset only works if SMC firmware is running, so we + * have a dependency on the state of the device as to whether this reset will + * be effective. There are still cases where we won't be able to kick the + * device into working, but this greatly improves the usability overall. The + * config reset magic is relatively common on AMD GPUs, but the setup and SMC + * poking is largely ASIC specific. + */ +static bool vfio_radeon_smc_is_running(VFIOPCIDevice *vdev) +{ + uint32_t clk, pc_c; + + /* + * Registers 200h and 204h are index and data registers for acessing + * indirect configuration registers within the device. + */ + vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000004, 4); + clk = vfio_region_read(&vdev->bars[5].region, 0x204, 4); + vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000370, 4); + pc_c = vfio_region_read(&vdev->bars[5].region, 0x204, 4); + + return (!(clk & 1) && (0x20100 <= pc_c)); +} + +/* + * The scope of a config reset is controlled by a mode bit in the misc register + * and a fuse, exposed as a bit in another register. The fuse is the default + * (0 = GFX, 1 = whole GPU), the misc bit is a toggle, with the forumula + * scope = !(misc ^ fuse), where the resulting scope is defined the same as + * the fuse. A truth table therefore tells us that if misc == fuse, we need + * to flip the value of the bit in the misc register. + */ +static void vfio_radeon_set_gfx_only_reset(VFIOPCIDevice *vdev) +{ + uint32_t misc, fuse; + bool a, b; + + vfio_region_write(&vdev->bars[5].region, 0x200, 0xc00c0000, 4); + fuse = vfio_region_read(&vdev->bars[5].region, 0x204, 4); + b = fuse & 64; + + vfio_region_write(&vdev->bars[5].region, 0x200, 0xc0000010, 4); + misc = vfio_region_read(&vdev->bars[5].region, 0x204, 4); + a = misc & 2; + + if (a == b) { + vfio_region_write(&vdev->bars[5].region, 0x204, misc ^ 2, 4); + vfio_region_read(&vdev->bars[5].region, 0x204, 4); /* flush */ + } +} + +static int vfio_radeon_reset(VFIOPCIDevice *vdev) +{ + PCIDevice *pdev = &vdev->pdev; + int i, ret = 0; + uint32_t data; + + /* Defer to a kernel implemented reset */ + if (vdev->vbasedev.reset_works) { + return -ENODEV; + } + + /* Enable only memory BAR access */ + vfio_pci_write_config(pdev, PCI_COMMAND, PCI_COMMAND_MEMORY, 2); + + /* Reset only works if SMC firmware is loaded and running */ + if (!vfio_radeon_smc_is_running(vdev)) { + ret = -EINVAL; + goto out; + } + + /* Make sure only the GFX function is reset */ + vfio_radeon_set_gfx_only_reset(vdev); + + /* AMD PCI config reset */ + vfio_pci_write_config(pdev, 0x7c, 0x39d5e86b, 4); + usleep(100); + + /* Read back the memory size to make sure we're out of reset */ + for (i = 0; i < 100000; i++) { + if (vfio_region_read(&vdev->bars[5].region, 0x5428, 4) != 0xffffffff) { + break; + } + usleep(1); + } + + /* Reset SMC */ + vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000000, 4); + data = vfio_region_read(&vdev->bars[5].region, 0x204, 4); + data |= 1; + vfio_region_write(&vdev->bars[5].region, 0x204, data, 4); + + /* Disable SMC clock */ + vfio_region_write(&vdev->bars[5].region, 0x200, 0x80000004, 4); + data = vfio_region_read(&vdev->bars[5].region, 0x204, 4); + data |= 1; + vfio_region_write(&vdev->bars[5].region, 0x204, data, 4); + +out: + /* Restore PCI command register */ + vfio_pci_write_config(pdev, PCI_COMMAND, 0, 2); + + return ret; +} + +static void vfio_setup_resetfn(VFIOPCIDevice *vdev) +{ + PCIDevice *pdev = &vdev->pdev; + uint16_t vendor, device; + + vendor = pci_get_word(pdev->config + PCI_VENDOR_ID); + device = pci_get_word(pdev->config + PCI_DEVICE_ID); + + switch (vendor) { + case 0x1002: + switch (device) { + /* Bonaire */ + case 0x6649: /* Bonaire [FirePro W5100] */ + case 0x6650: + case 0x6651: + case 0x6658: /* Bonaire XTX [Radeon R7 260X] */ + case 0x665c: /* Bonaire XT [Radeon HD 7790/8770 / R9 260 OEM] */ + case 0x665d: /* Bonaire [Radeon R7 200 Series] */ + /* Hawaii */ + case 0x67A0: /* Hawaii XT GL [FirePro W9100] */ + case 0x67A1: /* Hawaii PRO GL [FirePro W8100] */ + case 0x67A2: + case 0x67A8: + case 0x67A9: + case 0x67AA: + case 0x67B0: /* Hawaii XT [Radeon R9 290X] */ + case 0x67B1: /* Hawaii PRO [Radeon R9 290] */ + case 0x67B8: + case 0x67B9: + case 0x67BA: + case 0x67BE: + vdev->resetfn = vfio_radeon_reset; + break; + } + break; + } +} + static int vfio_initfn(PCIDevice *pdev) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); @@ -3352,7 +3515,7 @@ static int vfio_initfn(PCIDevice *pdev) len = readlink(path, iommu_group_path, sizeof(path)); if (len <= 0 || len >= sizeof(path)) { error_report("vfio: error no iommu_group for device"); - return len < 0 ? -errno : ENAMETOOLONG; + return len < 0 ? -errno : -ENAMETOOLONG; } iommu_group_path[len] = 0; @@ -3467,6 +3630,7 @@ static int vfio_initfn(PCIDevice *pdev) vfio_register_err_notifier(vdev); vfio_register_req_notifier(vdev); + vfio_setup_resetfn(vdev); return 0; @@ -3514,6 +3678,10 @@ static void vfio_pci_reset(DeviceState *dev) vfio_pci_pre_reset(vdev); + if (vdev->resetfn && !vdev->resetfn(vdev)) { + goto post_reset; + } + if (vdev->vbasedev.reset_works && (vdev->has_flr || !vdev->has_pm_reset) && !ioctl(vdev->vbasedev.fd, VFIO_DEVICE_RESET)) { diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c index 95b0643448..484c3c333c 100644 --- a/hw/virtio/virtio-balloon.c +++ b/hw/virtio/virtio-balloon.c @@ -383,7 +383,7 @@ static void virtio_balloon_device_realize(DeviceState *dev, Error **errp) virtio_balloon_stat, s); if (ret < 0) { - error_setg(errp, "Adding balloon handler failed"); + error_setg(errp, "Only one balloon device is supported"); virtio_cleanup(vdev); return; } |