static int hax_get_fpu(CPUArchState *env) { struct fx_layout fpu; int i, ret; ret = hax_sync_fpu(env, &fpu, 0); if (ret < 0) { return ret; } env->fpstt = (fpu.fsw >> 11) & 7; env->fpus = fpu.fsw; env->fpuc = fpu.fcw; for (i = 0; i < 8; ++i) { env->fptags[i] = !((fpu.ftw >> i) & 1); } memcpy(env->fpregs, fpu.st_mm, sizeof(env->fpregs)); for (i = 0; i < 8; i++) { env->xmm_regs[i].ZMM_Q(0) = ldq_p(&fpu.mmx_1[i][0]); env->xmm_regs[i].ZMM_Q(1) = ldq_p(&fpu.mmx_1[i][8]); if (CPU_NB_REGS > 8) { env->xmm_regs[i + 8].ZMM_Q(0) = ldq_p(&fpu.mmx_2[i][0]); env->xmm_regs[i + 8].ZMM_Q(1) = ldq_p(&fpu.mmx_2[i][8]); } } env->mxcsr = fpu.mxcsr; return 0; }
static void spin_kick(void *data) { SpinKick *kick = data; CPUState *cpu = CPU(kick->cpu); CPUPPCState *env = &kick->cpu->env; SpinInfo *curspin = kick->spin; hwaddr map_size = 64 * 1024 * 1024; hwaddr map_start; cpu_synchronize_state(cpu); stl_p(&curspin->pir, env->spr[SPR_PIR]); env->nip = ldq_p(&curspin->addr) & (map_size - 1); env->gpr[3] = ldq_p(&curspin->r3); env->gpr[4] = 0; env->gpr[5] = 0; env->gpr[6] = 0; env->gpr[7] = map_size; env->gpr[8] = 0; env->gpr[9] = 0; map_start = ldq_p(&curspin->addr) & ~(map_size - 1); mmubooke_create_initial_mapping(env, 0, map_start, map_size); cpu->halted = 0; env->exception_index = -1; cpu->stopped = false; qemu_cpu_kick(cpu); }
static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) { BlockRequest *blkreq; uint64_t sector; sector = ldq_p(&req->out->sector); trace_virtio_blk_handle_write(req, sector, req->qiov.size / 512); if (sector & req->dev->sector_mask) { virtio_blk_rw_complete(req, -EIO); return; } if (mrb->num_writes == 32) { virtio_submit_multiwrite(req->dev->bs, mrb); } blkreq = &mrb->blkreq[mrb->num_writes]; blkreq->sector = sector; blkreq->nb_sectors = req->qiov.size / BDRV_SECTOR_SIZE; blkreq->qiov = &req->qiov; blkreq->cb = virtio_blk_rw_complete; blkreq->opaque = req; blkreq->error = 0; mrb->num_writes++; }
int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; uint64_t tmp; tmp = ldq_p(mem_buf); if (n < 31) { /* Core integer register. */ env->xregs[n] = tmp; return 8; } switch (n) { case 31: env->xregs[31] = tmp; return 8; case 32: env->pc = tmp; return 8; case 33: /* CPSR */ pstate_write(env, tmp); return 4; } /* Unknown register. */ return 0; }
static void virtio_blk_handle_read(VirtIOBlockReq *req) { BlockDriverAIOCB *acb; uint64_t sector; sector = ldq_p(&req->out->sector); bdrv_acct_start(req->dev->bs, &req->acct, req->qiov.size, BDRV_ACCT_READ); if (sector & req->dev->sector_mask) { virtio_blk_rw_complete(req, -EIO); return; } if (req->qiov.size % req->dev->conf->logical_block_size) { virtio_blk_rw_complete(req, -EIO); return; } acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov, req->qiov.size / BDRV_SECTOR_SIZE, virtio_blk_rw_complete, req); if (!acb) { virtio_blk_rw_complete(req, -EIO); } }
/* warning: addr must be aligned */ static inline uint64_t glue(address_space_ldq_internal, SUFFIX)(ARG1_DECL, hwaddr addr, MemTxAttrs attrs, MemTxResult *result, enum device_endian endian) { uint8_t *ptr; uint64_t val; MemoryRegion *mr; hwaddr l = 8; hwaddr addr1; MemTxResult r; bool release_lock = false; RCU_READ_LOCK(); mr = TRANSLATE(addr, &addr1, &l, false); if (l < 8 || !IS_DIRECT(mr, false)) { release_lock |= prepare_mmio_access(mr); /* I/O case */ r = memory_region_dispatch_read(mr, addr1, &val, 8, attrs); #if defined(TARGET_WORDS_BIGENDIAN) if (endian == DEVICE_LITTLE_ENDIAN) { val = bswap64(val); } #else if (endian == DEVICE_BIG_ENDIAN) { val = bswap64(val); } #endif } else { /* RAM case */ ptr = MAP_RAM(mr, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: val = ldq_le_p(ptr); break; case DEVICE_BIG_ENDIAN: val = ldq_be_p(ptr); break; default: val = ldq_p(ptr); break; } r = MEMTX_OK; } if (result) { *result = r; } if (release_lock) { qemu_mutex_unlock_iothread(); } RCU_READ_UNLOCK(); return val; }
static inline int lock_hpte(void *hpte, target_ulong bits) { uint64_t pteh; pteh = ldq_p(hpte); /* We're protected by qemu's global lock here */ if (pteh & bits) { return 0; } stq_p(hpte, pteh | HPTE_V_HVLOCK); return 1; }
int ppc_cpu_gdb_write_register_apple(CPUState *cs, uint8_t *mem_buf, int n) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; int r = ppc_gdb_register_len_apple(n); if (!r) { return r; } if (msr_le) { /* If cpu is in LE mode, convert memory contents to LE. */ ppc_gdb_swap_register(mem_buf, n, r); } if (n < 32) { /* gprs */ env->gpr[n] = ldq_p(mem_buf); } else if (n < 64) { /* fprs */ env->fpr[n-32] = ldfq_p(mem_buf); } else { switch (n) { case 64 + 32: env->nip = ldq_p(mem_buf); break; case 65 + 32: ppc_store_msr(env, ldq_p(mem_buf)); break; case 66 + 32: { uint32_t cr = ldl_p(mem_buf); int i; for (i = 0; i < 8; i++) { env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF; } break; } case 67 + 32: env->lr = ldq_p(mem_buf); break; case 68 + 32: env->ctr = ldq_p(mem_buf); break; case 69 + 32: env->xer = ldq_p(mem_buf); break; case 70 + 32: /* fpscr */ store_fpscr(env, ldq_p(mem_buf), 0xffffffff); break; } } return r; }
static void spin_write(void *opaque, hwaddr addr, uint64_t value, unsigned len) { SpinState *s = opaque; int env_idx = addr / sizeof(SpinInfo); CPUPPCState *env; SpinInfo *curspin = &s->spin[env_idx]; uint8_t *curspin_p = (uint8_t*)curspin; for (env = first_cpu; env != NULL; env = env->next_cpu) { if (env->cpu_index == env_idx) { break; } } if (!env) { /* Unknown CPU */ return; } if (!env->cpu_index) { /* primary CPU doesn't spin */ return; } curspin_p = &curspin_p[addr % sizeof(SpinInfo)]; switch (len) { case 1: stb_p(curspin_p, value); break; case 2: stw_p(curspin_p, value); break; case 4: stl_p(curspin_p, value); break; } if (!(ldq_p(&curspin->addr) & 1)) { /* run CPU */ SpinKick kick = { .cpu = ppc_env_get_cpu(env), .spin = curspin, }; run_on_cpu(CPU(kick.cpu), spin_kick, &kick); }
int handle_frontend_syscall(HTIFState *htifstate, uint64_t payload) { uint64_t mm[8]; int i; void * base = htifstate->main_mem_ram_ptr + (uintptr_t)payload; for (i = 0; i < 8; i++) { mm[i] = ldq_p((void*)(base + i*8)); } #ifdef DEBUG_FRONTEND_RISCV for (i = 0; i < 8; i++) { fprintf(stderr, "elem %d, val 0x%016lx\n", i, mm[i]); } #endif uint64_t retval = -1; switch(mm[0]) { case RV_FSYSCALL_sys_openat: retval = sys_openat(htifstate, mm[1], mm[2], mm[3], mm[4], mm[5]); break; case RV_FSYSCALL_sys_close: retval = sys_close(htifstate, mm[1]); break; case RV_FSYSCALL_sys_write: retval = sys_write(htifstate, mm[1], mm[2], mm[3]); break; case RV_FSYSCALL_sys_pread: retval = sys_pread(htifstate, mm[1], mm[2], mm[3], mm[4]); break; case RV_FSYSCALL_sys_exit: retval = sys_exit(htifstate, mm[1]); break; case RV_FSYSCALL_sys_getmainvars: retval = sys_getmainvars(htifstate, mm[1], mm[2]); break; default: fprintf(stderr, "FRONTEND SYSCALL %ld NOT IMPLEMENTED\n", mm[0]); exit(1); } // write retval to mm stq_p((void*)base, retval); return 1; }
static void virtio_blk_handle_read(VirtIOBlockReq *req) { BlockDriverAIOCB *acb; uint64_t sector; sector = ldq_p(&req->out->sector); if (sector & req->dev->sector_mask) { virtio_blk_rw_complete(req, -EIO); return; } acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov, req->qiov.size / BDRV_SECTOR_SIZE, virtio_blk_rw_complete, req); if (!acb) { virtio_blk_rw_complete(req, -EIO); } }
static void spin_write(void *opaque, hwaddr addr, uint64_t value, unsigned len) { SpinState *s = opaque; int env_idx = addr / sizeof(SpinInfo); CPUState *cpu; SpinInfo *curspin = &s->spin[env_idx]; uint8_t *curspin_p = (uint8_t*)curspin; cpu = qemu_get_cpu(env_idx); if (cpu == NULL) { /* Unknown CPU */ return; } if (cpu->cpu_index == 0) { /* primary CPU doesn't spin */ return; } curspin_p = &curspin_p[addr % sizeof(SpinInfo)]; switch (len) { case 1: stb_p(curspin_p, value); break; case 2: stw_p(curspin_p, value); break; case 4: stl_p(curspin_p, value); break; } if (!(ldq_p(&curspin->addr) & 1)) { /* run CPU */ SpinKick kick = { .cpu = POWERPC_CPU(cpu), .spin = curspin, }; run_on_cpu(cpu, spin_kick, &kick); }
int x86_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; uint32_t tmp; if (n < CPU_NB_REGS) { if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { env->regs[gpr_map[n]] = ldtul_p(mem_buf); return sizeof(target_ulong); } else if (n < CPU_NB_REGS32) { n = gpr_map32[n]; env->regs[n] &= ~0xffffffffUL; env->regs[n] |= (uint32_t)ldl_p(mem_buf); return 4; } } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { #ifdef USE_X86LDOUBLE /* FIXME: byteswap float values - after fixing fpregs layout. */ memcpy(&env->fpregs[n - IDX_FP_REGS], mem_buf, 10); #endif return 10; } else if (n >= IDX_XMM_REGS && n < IDX_XMM_REGS + CPU_NB_REGS) { n -= IDX_XMM_REGS; if (n < CPU_NB_REGS32 || (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK)) { env->xmm_regs[n].XMM_Q(0) = ldq_p(mem_buf); env->xmm_regs[n].XMM_Q(1) = ldq_p(mem_buf + 8); return 16; } } else { switch (n) { case IDX_IP_REG: if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { env->eip = ldq_p(mem_buf); return 8; } else { env->eip &= ~0xffffffffUL; env->eip |= (uint32_t)ldl_p(mem_buf); return 4; } case IDX_FLAGS_REG: env->eflags = ldl_p(mem_buf); return 4; case IDX_SEG_REGS: return x86_cpu_gdb_load_seg(cpu, R_CS, mem_buf); case IDX_SEG_REGS + 1: return x86_cpu_gdb_load_seg(cpu, R_SS, mem_buf); case IDX_SEG_REGS + 2: return x86_cpu_gdb_load_seg(cpu, R_DS, mem_buf); case IDX_SEG_REGS + 3: return x86_cpu_gdb_load_seg(cpu, R_ES, mem_buf); case IDX_SEG_REGS + 4: return x86_cpu_gdb_load_seg(cpu, R_FS, mem_buf); case IDX_SEG_REGS + 5: return x86_cpu_gdb_load_seg(cpu, R_GS, mem_buf); case IDX_FP_REGS + 8: cpu_set_fpuc(env, ldl_p(mem_buf)); return 4; case IDX_FP_REGS + 9: tmp = ldl_p(mem_buf); env->fpstt = (tmp >> 11) & 7; env->fpus = tmp & ~0x3800; return 4; case IDX_FP_REGS + 10: /* ftag */ return 4; case IDX_FP_REGS + 11: /* fiseg */ return 4; case IDX_FP_REGS + 12: /* fioff */ return 4; case IDX_FP_REGS + 13: /* foseg */ return 4; case IDX_FP_REGS + 14: /* fooff */ return 4; case IDX_FP_REGS + 15: /* fop */ return 4; case IDX_MXCSR_REG: cpu_set_mxcsr(env, ldl_p(mem_buf)); return 4; } } /* Unrecognised register. */ return 0; }
int aarch64_cpu_gdb_write_register(CPUState *cs, uint8_t *mem_buf, int n) { ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; uint64_t tmp; int rlen = 0; #ifndef CONFIG_USER_ONLY if (!is_a64(env)) { map_a32_to_a64_regs(env); } #endif tmp = ldq_p(mem_buf); if (n < 31) { /* Core integer register. */ env->xregs[n] = tmp; rlen = 8; } switch (n) { case 31: { unsigned int cur_el = arm_current_el(env); aarch64_save_sp(env, cur_el); switch (env->debug_ctx) { case DEBUG_EL0: env->sp_el[0] = tmp; break; case DEBUG_EL1: env->sp_el[1] = tmp; break; case DEBUG_EL2: env->sp_el[2] = tmp; break; case DEBUG_EL3: env->sp_el[3] = tmp; break; default: env->xregs[31] = tmp; break; } aarch64_restore_sp(env, cur_el); rlen = 8; break; } case 32: env->pc = tmp; rlen = 8; break; case 33: /* CPSR */ pstate_write(env, tmp); rlen = 4; break; } #ifndef CONFIG_USER_ONLY if (!is_a64(env)) { map_a64_to_a32_regs(env); } #endif /* Unknown register. */ return rlen; }