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)) { return; } /* When set, EDGE_SEL overrides the ICR config */ if (extract32(s->edge_sel, line, 1)) { /* we detect interrupt on rising and falling edge */ if (extract32(s->psr, line, 1) != level) { /* level changed */ s->isr = deposit32(s->isr, line, 1, 1); } } else if (extract64(s->icr, 2*line + 1, 1)) { /* interrupt is edge sensitive */ if (extract32(s->psr, line, 1) != level) { /* level changed */ if (extract64(s->icr, 2*line, 1) != level) { s->isr = deposit32(s->isr, line, 1, 1); } } } else { /* interrupt is level sensitive */ if (extract64(s->icr, 2*line, 1) == level) { s->isr = deposit32(s->isr, line, 1, 1); } } }
uint64_t HELPER(simd_tbl)(CPUARMState *env, uint64_t result, uint64_t indices, uint32_t rn, uint32_t numregs) { /* Helper function for SIMD TBL and TBX. We have to do the table * lookup part for the 64 bits worth of indices we're passed in. * result is the initial results vector (either zeroes for TBL * or some guest values for TBX), rn the register number where * the table starts, and numregs the number of registers in the table. * We return the results of the lookups. */ int shift; for (shift = 0; shift < 64; shift += 8) { int index = extract64(indices, shift, 8); if (index < 16 * numregs) { /* Convert index (a byte offset into the virtual table * which is a series of 128-bit vectors concatenated) * into the correct vfp.regs[] element plus a bit offset * into that element, bearing in mind that the table * can wrap around from V31 to V0. */ int elt = (rn * 2 + (index >> 3)) % 64; int bitidx = (index & 7) * 8; uint64_t val = extract64(env->vfp.regs[elt], bitidx, 8); result = deposit64(result, shift, 8, val); } }
static uint64_t imx_gpio_read(void *opaque, hwaddr offset, unsigned size) { IMXGPIOState *s = IMX_GPIO(opaque); uint32_t reg_value = 0; switch (offset) { case DR_ADDR: /* * depending on the "line" configuration, the bit values * are coming either from DR or PSR */ reg_value = (s->dr & s->gdir) | (s->psr & ~s->gdir); break; case GDIR_ADDR: reg_value = s->gdir; break; case PSR_ADDR: reg_value = s->psr & ~s->gdir; break; case ICR1_ADDR: reg_value = extract64(s->icr, 0, 32); break; case ICR2_ADDR: reg_value = extract64(s->icr, 32, 32); break; case IMR_ADDR: reg_value = s->imr; break; case ISR_ADDR: reg_value = s->isr; break; case EDGE_SEL_ADDR: if (s->has_edge_sel) { reg_value = s->edge_sel; } else { qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: EDGE_SEL register not " "present on this version of GPIO device\n", TYPE_IMX_GPIO, __func__); } break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s[%s]: Bad register at offset %d\n", TYPE_IMX_GPIO, __func__, (int)offset); break; } DPRINTF("(%s) = 0x%"PRIx32"\n", imx_gpio_reg_name(offset), reg_value); return reg_value; }
uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size) { RegisterInfoArray *reg_array = opaque; RegisterInfo *reg = NULL; uint64_t read_val; int i; for (i = 0; i < reg_array->num_elements; i++) { if (reg_array->r[i]->access->addr == addr) { reg = reg_array->r[i]; break; } } if (!reg) { qemu_log_mask(LOG_GUEST_ERROR, "Read to unimplemented register at " \ "address: %#" PRIx64 "\n", addr); return 0; } read_val = register_read(reg, size * 8, reg_array->prefix, reg_array->debug); return extract64(read_val, 0, size * 8); }
void HELPER(gvec_fcaddd)(void *vd, void *vn, void *vm, void *vfpst, uint32_t desc) { uintptr_t opr_sz = simd_oprsz(desc); float64 *d = vd; float64 *n = vn; float64 *m = vm; float_status *fpst = vfpst; uint64_t neg_real = extract64(desc, SIMD_DATA_SHIFT, 1); uint64_t neg_imag = neg_real ^ 1; uintptr_t i; /* Shift boolean to the sign bit so we can xor to negate. */ neg_real <<= 63; neg_imag <<= 63; for (i = 0; i < opr_sz / 8; i += 2) { float64 e0 = n[i]; float64 e1 = m[i + 1] ^ neg_imag; float64 e2 = n[i + 1]; float64 e3 = m[i] ^ neg_real; d[i] = float64_add(e0, e1, fpst); d[i + 1] = float64_add(e2, e3, fpst); } clear_tail(d, opr_sz, simd_maxsz(desc)); }
inline void extract(const std::vector<unsigned char> &vec, size_t &offset, unsigned long long &target) { target = extract64(vec, offset); offset += 8; }
uint64_t register_read_memory(void *opaque, hwaddr addr, unsigned size) { RegisterInfoArray *reg_array = opaque; RegisterInfo *reg = NULL; uint64_t read_val; uint64_t re; int i; for (i = 0; i < reg_array->num_elements; i++) { if (reg_array->r[i]->access->addr == addr) { reg = reg_array->r[i]; break; } } if (!reg) { qemu_log_mask(LOG_GUEST_ERROR, "%s: read to unimplemented register " \ "at address: %#" PRIx64 "\n", reg_array->prefix, addr); return 0; } /* Generate appropriate read enable mask */ re = register_enabled_mask(reg->data_size, size); read_val = register_read(reg, re, reg_array->prefix, reg_array->debug); return extract64(read_val, 0, size * 8); }
static uint64_t bcm2835_ic_read(void *opaque, hwaddr offset, unsigned size) { BCM2835ICState *s = opaque; uint32_t res = 0; uint64_t gpu_pending = s->gpu_irq_level & s->gpu_irq_enable; int i; switch (offset) { case IRQ_PENDING_BASIC: /* bits 0-7: ARM irqs */ res = s->arm_irq_level & s->arm_irq_enable; /* bits 8 & 9: pending registers 1 & 2 */ res |= (((uint32_t)gpu_pending) != 0) << 8; res |= ((gpu_pending >> 32) != 0) << 9; /* bits 10-20: selected GPU IRQs */ for (i = 0; i < ARRAY_SIZE(irq_dups); i++) { res |= extract64(gpu_pending, irq_dups[i], 1) << (i + 10); } break; case IRQ_PENDING_1: res = gpu_pending; break; case IRQ_PENDING_2: res = gpu_pending >> 32; break; case FIQ_CONTROL: res = (s->fiq_enable << 7) | s->fiq_select; break; case IRQ_ENABLE_1: res = s->gpu_irq_enable; break; case IRQ_ENABLE_2: res = s->gpu_irq_enable >> 32; break; case IRQ_ENABLE_BASIC: res = s->arm_irq_enable; break; case IRQ_DISABLE_1: res = ~s->gpu_irq_enable; break; case IRQ_DISABLE_2: res = ~s->gpu_irq_enable >> 32; break; case IRQ_DISABLE_BASIC: res = ~s->arm_irq_enable; break; default: qemu_log_mask(LOG_GUEST_ERROR, "%s: Bad offset %"HWADDR_PRIx"\n", __func__, offset); return 0; } return res; }
static uint64_t lookup_bte64(CPUX86State *env, uint64_t base, uintptr_t ra) { uint64_t bndcsr, bde, bt; if ((env->hflags & HF_CPL_MASK) == 3) { bndcsr = env->bndcs_regs.cfgu; } else { bndcsr = env->msr_bndcfgs; } bde = (extract64(base, 20, 28) << 3) + (extract64(bndcsr, 20, 44) << 12); bt = cpu_ldq_data_ra(env, bde, ra); if ((bt & 1) == 0) { env->bndcs_regs.sts = bde | 2; raise_exception_ra(env, EXCP05_BOUND, ra); } return (extract64(base, 3, 17) << 5) + (bt & ~7); }
static void ronaldo_sdhci_slottype_handler(void *opaque, int n, int level) { SDHCIState *ss = SYSBUS_SDHCI(opaque); RonaldoSDHCIState *s = RONALDO_SDHCI(opaque); assert(n == 0); ss->capareg = deposit64(ss->capareg, 30, 2, level); ss->card = extract64(ss->capareg, 30, 2) ? s->mmc_card : s->sd_card; sd_set_cb(ss->card, ss->ro_cb, ss->eject_cb); }
static int kvm_its_send_msi(GICv3ITSState *s, uint32_t value, uint16_t devid) { struct kvm_msi msi; if (unlikely(!s->translater_gpa_known)) { MemoryRegion *mr = &s->iomem_its_translation; MemoryRegionSection mrs; mrs = memory_region_find(mr, 0, 1); memory_region_unref(mrs.mr); s->gits_translater_gpa = mrs.offset_within_address_space + 0x40; s->translater_gpa_known = true; } msi.address_lo = extract64(s->gits_translater_gpa, 0, 32); msi.address_hi = extract64(s->gits_translater_gpa, 32, 32); msi.data = le32_to_cpu(value); msi.flags = KVM_MSI_VALID_DEVID; msi.devid = devid; memset(msi.pad, 0, sizeof(msi.pad)); return kvm_vm_ioctl(kvm_state, KVM_SIGNAL_MSI, &msi); }
/* Update interrupts. */ static void bcm2835_ic_update(BCM2835ICState *s) { bool set = false; if (s->fiq_enable) { if (s->fiq_select >= GPU_IRQS) { /* ARM IRQ */ set = extract32(s->arm_irq_level, s->fiq_select - GPU_IRQS, 1); } else { set = extract64(s->gpu_irq_level, s->fiq_select, 1); } } qemu_set_irq(s->fiq, set); set = (s->gpu_irq_level & s->gpu_irq_enable) || (s->arm_irq_level & s->arm_irq_enable); qemu_set_irq(s->irq, set); }
static void s390_vec_shl(S390Vector *d, const S390Vector *a, uint64_t count) { uint64_t tmp; g_assert(count < 128); if (count == 0) { d->doubleword[0] = a->doubleword[0]; d->doubleword[1] = a->doubleword[1]; } else if (count == 64) { d->doubleword[0] = a->doubleword[1]; d->doubleword[1] = 0; } else if (count < 64) { tmp = extract64(a->doubleword[1], 64 - count, count); d->doubleword[1] = a->doubleword[1] << count; d->doubleword[0] = (a->doubleword[0] << count) | tmp; } else { d->doubleword[0] = a->doubleword[1] << (count - 64); d->doubleword[1] = 0; } }
int s390_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { S390CPU *cpu = S390_CPU(cs); CPUS390XState *env = &cpu->env; target_ulong tmpl = ldtul_p(mem_buf); switch (n) { case S390_PSWM_REGNUM: env->psw.mask = tmpl; if (tcg_enabled()) { env->cc_op = extract64(tmpl, 44, 2); } break; case S390_PSWA_REGNUM: env->psw.addr = tmpl; break; case S390_R0_REGNUM ... S390_R15_REGNUM: env->regs[n - S390_R0_REGNUM] = tmpl; break; default: return 0; } return 8; }