static int hax_set_fpu(CPUArchState *env) { struct fx_layout fpu; int i; memset(&fpu, 0, sizeof(fpu)); fpu.fsw = env->fpus & ~(7 << 11); fpu.fsw |= (env->fpstt & 7) << 11; fpu.fcw = env->fpuc; for (i = 0; i < 8; ++i) { fpu.ftw |= (!env->fptags[i]) << i; } memcpy(fpu.st_mm, env->fpregs, sizeof(env->fpregs)); for (i = 0; i < 8; i++) { stq_p(&fpu.mmx_1[i][0], env->xmm_regs[i].ZMM_Q(0)); stq_p(&fpu.mmx_1[i][8], env->xmm_regs[i].ZMM_Q(1)); if (CPU_NB_REGS > 8) { stq_p(&fpu.mmx_2[i][0], env->xmm_regs[i + 8].ZMM_Q(0)); stq_p(&fpu.mmx_2[i][8], env->xmm_regs[i + 8].ZMM_Q(1)); } } fpu.mxcsr = env->mxcsr; return hax_sync_fpu(env, &fpu, 1); }
int ppc_cpu_gdb_read_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 (n < 32) { /* gprs */ gdb_get_reg64(mem_buf, env->gpr[n]); } else if (n < 64) { /* fprs */ stfq_p(mem_buf, env->fpr[n-32]); } else if (n < 96) { /* Altivec */ stq_p(mem_buf, n - 64); stq_p(mem_buf + 8, 0); } else { switch (n) { case 64 + 32: gdb_get_reg64(mem_buf, env->nip); break; case 65 + 32: gdb_get_reg64(mem_buf, env->msr); break; case 66 + 32: { uint32_t cr = 0; int i; for (i = 0; i < 8; i++) { cr |= env->crf[i] << (32 - ((i + 1) * 4)); } gdb_get_reg32(mem_buf, cr); break; } case 67 + 32: gdb_get_reg64(mem_buf, env->lr); break; case 68 + 32: gdb_get_reg64(mem_buf, env->ctr); break; case 69 + 32: gdb_get_reg64(mem_buf, env->xer); break; case 70 + 32: gdb_get_reg64(mem_buf, env->fpscr); break; } } if (msr_le) { /* If cpu is in LE mode, convert memory contents to LE. */ ppc_gdb_swap_register(mem_buf, n, r); } return r; }
uint64_t sys_getmainvars(HTIFState * htifstate, uint64_t pbuf, uint64_t limit) { #ifdef DEBUG_FRONTEND_RISCV fprintf(stderr, "%s\n", htifstate->kernel_cmdline); #endif void * base = htifstate->main_mem_ram_ptr + (uintptr_t)pbuf; // assume args are bbl + some kernel for now // later, do the right thing const char * arg0 = "bbl"; const char * arg1 = htifstate->kernel_cmdline; #define WORDS_LEN 5 #define START_ARGS (WORDS_LEN*8) uint64_t words[WORDS_LEN] = {2, START_ARGS+pbuf, START_ARGS+pbuf+4, 0, 0}; int i; for (i = 0; i < WORDS_LEN; i++) { stq_p((void*)(base+i*8), words[i]); } for (i = 0; i < 4; i++) { stb_p((void*)(base + START_ARGS + i), arg0[i]); } for (i = 0; i < strlen(arg1)+1; i++) { stb_p((void*)(base + START_ARGS+4 + i), arg1[i]); } // currently no support for > 2 args return 0; }
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; }
static void glue(address_space_stq_internal, SUFFIX)(ARG1_DECL, hwaddr addr, uint64_t val, MemTxAttrs attrs, MemTxResult *result, enum device_endian endian) { uint8_t *ptr; MemoryRegion *mr; hwaddr l = 8; hwaddr addr1; MemTxResult r; bool release_lock = false; RCU_READ_LOCK(); mr = TRANSLATE(addr, &addr1, &l, true); if (l < 8 || !IS_DIRECT(mr, true)) { release_lock |= prepare_mmio_access(mr); #if defined(TARGET_WORDS_BIGENDIAN) if (endian == DEVICE_LITTLE_ENDIAN) { val = bswap64(val); } #else if (endian == DEVICE_BIG_ENDIAN) { val = bswap64(val); } #endif r = memory_region_dispatch_write(mr, addr1, val, 8, attrs); } else { /* RAM case */ ptr = MAP_RAM(mr, addr1); switch (endian) { case DEVICE_LITTLE_ENDIAN: stq_le_p(ptr, val); break; case DEVICE_BIG_ENDIAN: stq_be_p(ptr, val); break; default: stq_p(ptr, val); break; } INVALIDATE(mr, addr1, 8); r = MEMTX_OK; } if (result) { *result = r; } if (release_lock) { qemu_mutex_unlock_iothread(); } RCU_READ_UNLOCK(); }
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 s390_ipl_realize(DeviceState *dev, Error **errp) { S390IPLState *ipl = S390_IPL(dev); uint64_t pentry = KERN_IMAGE_START; int kernel_size; Error *err = NULL; int bios_size; char *bios_filename; /* * Always load the bios if it was enforced, * even if an external kernel has been defined. */ if (!ipl->kernel || ipl->enforce_bios) { uint64_t fwbase = (MIN(ram_size, 0x80000000U) - 0x200000) & ~0xffffUL; if (bios_name == NULL) { bios_name = ipl->firmware; } bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (bios_filename == NULL) { error_setg(&err, "could not find stage1 bootloader"); goto error; } bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase, &ipl->bios_start_addr, NULL, NULL, 1, EM_S390, 0, 0); if (bios_size > 0) { /* Adjust ELF start address to final location */ ipl->bios_start_addr += fwbase; } else { /* Try to load non-ELF file */ bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096); ipl->bios_start_addr = ZIPL_IMAGE_START; } g_free(bios_filename); if (bios_size == -1) { error_setg(&err, "could not load bootloader '%s'", bios_name); goto error; } /* default boot target is the bios */ ipl->start_addr = ipl->bios_start_addr; } if (ipl->kernel) { kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, NULL, 1, EM_S390, 0, 0); if (kernel_size < 0) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); } if (kernel_size < 0) { error_setg(&err, "could not load kernel '%s'", ipl->kernel); goto error; } /* * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the * kernel parameters here as well. Note: For old kernels (up to 3.2) * we can not rely on the ELF entry point - it was 0x800 (the SALIPL * loader) and it won't work. For this case we force it to 0x10000, too. */ if (pentry == KERN_IMAGE_START || pentry == 0x800) { ipl->start_addr = KERN_IMAGE_START; /* Overwrite parameters in the kernel image, which are "rom" */ strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); } else { ipl->start_addr = pentry; } if (ipl->initrd) { ram_addr_t initrd_offset; int initrd_size; initrd_offset = INITRD_START; while (kernel_size + 0x100000 > initrd_offset) { initrd_offset += 0x100000; } initrd_size = load_image_targphys(ipl->initrd, initrd_offset, ram_size - initrd_offset); if (initrd_size == -1) { error_setg(&err, "could not load initrd '%s'", ipl->initrd); goto error; } /* * we have to overwrite values in the kernel image, * which are "rom" */ stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); } } /* * Don't ever use the migrated values, they could come from a different * BIOS and therefore don't work. But still migrate the values, so * QEMUs relying on it don't break. */ ipl->compat_start_addr = ipl->start_addr; ipl->compat_bios_start_addr = ipl->bios_start_addr; qemu_register_reset(qdev_reset_all_fn, dev); error: error_propagate(errp, err); }
int x86_cpu_gdb_read_register(CPUState *cs, uint8_t *mem_buf, int n) { X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; if (n < CPU_NB_REGS) { if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { return gdb_get_reg64(mem_buf, env->regs[gpr_map[n]]); } else if (n < CPU_NB_REGS32) { return gdb_get_reg32(mem_buf, env->regs[gpr_map32[n]]); } } else if (n >= IDX_FP_REGS && n < IDX_FP_REGS + 8) { #ifdef USE_X86LDOUBLE /* FIXME: byteswap float values - after fixing fpregs layout. */ memcpy(mem_buf, &env->fpregs[n - IDX_FP_REGS], 10); #else memset(mem_buf, 0, 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)) { stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0)); stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1)); return 16; } } else { switch (n) { case IDX_IP_REG: if (TARGET_LONG_BITS == 64 && env->hflags & HF_CS64_MASK) { return gdb_get_reg64(mem_buf, env->eip); } else { return gdb_get_reg32(mem_buf, env->eip); } case IDX_FLAGS_REG: return gdb_get_reg32(mem_buf, env->eflags); case IDX_SEG_REGS: return gdb_get_reg32(mem_buf, env->segs[R_CS].selector); case IDX_SEG_REGS + 1: return gdb_get_reg32(mem_buf, env->segs[R_SS].selector); case IDX_SEG_REGS + 2: return gdb_get_reg32(mem_buf, env->segs[R_DS].selector); case IDX_SEG_REGS + 3: return gdb_get_reg32(mem_buf, env->segs[R_ES].selector); case IDX_SEG_REGS + 4: return gdb_get_reg32(mem_buf, env->segs[R_FS].selector); case IDX_SEG_REGS + 5: return gdb_get_reg32(mem_buf, env->segs[R_GS].selector); case IDX_FP_REGS + 8: return gdb_get_reg32(mem_buf, env->fpuc); case IDX_FP_REGS + 9: return gdb_get_reg32(mem_buf, (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11); case IDX_FP_REGS + 10: return gdb_get_reg32(mem_buf, 0); /* ftag */ case IDX_FP_REGS + 11: return gdb_get_reg32(mem_buf, 0); /* fiseg */ case IDX_FP_REGS + 12: return gdb_get_reg32(mem_buf, 0); /* fioff */ case IDX_FP_REGS + 13: return gdb_get_reg32(mem_buf, 0); /* foseg */ case IDX_FP_REGS + 14: return gdb_get_reg32(mem_buf, 0); /* fooff */ case IDX_FP_REGS + 15: return gdb_get_reg32(mem_buf, 0); /* fop */ case IDX_MXCSR_REG: return gdb_get_reg32(mem_buf, env->mxcsr); } } return 0; }
static int s390_ipl_init(SysBusDevice *dev) { S390IPLState *ipl = S390_IPL(dev); ram_addr_t kernel_size = 0; if (!ipl->kernel) { ram_addr_t bios_size = 0; char *bios_filename; /* Load zipl bootloader */ if (bios_name == NULL) { bios_name = ipl->firmware; } bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL, NULL, 1, ELF_MACHINE, 0); if (bios_size == -1UL) { bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096); ipl->start_addr = ZIPL_IMAGE_START; if (bios_size > 4096) { hw_error("stage1 bootloader is > 4k\n"); } } g_free(bios_filename); if ((long)bios_size < 0) { hw_error("could not load bootloader '%s'\n", bios_name); } return 0; } else { kernel_size = load_elf(ipl->kernel, NULL, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); if (kernel_size == -1UL) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); } if (kernel_size == -1UL) { fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); return -1; } /* we have to overwrite values in the kernel image, which are "rom" */ strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); /* * we can not rely on the ELF entry point, since up to 3.2 this * value was 0x800 (the SALIPL loader) and it wont work. For * all (Linux) cases 0x10000 (KERN_IMAGE_START) should be fine. */ ipl->start_addr = KERN_IMAGE_START; } if (ipl->initrd) { ram_addr_t initrd_offset, initrd_size; initrd_offset = INITRD_START; while (kernel_size + 0x100000 > initrd_offset) { initrd_offset += 0x100000; } initrd_size = load_image_targphys(ipl->initrd, initrd_offset, ram_size - initrd_offset); if (initrd_size == -1UL) { fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd); exit(1); } /* we have to overwrite values in the kernel image, which are "rom" */ stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); } return 0; }
static int s390_ipl_init(SysBusDevice *dev) { S390IPLState *ipl = S390_IPL(dev); int kernel_size; if (!ipl->kernel) { int bios_size; char *bios_filename; /* Load zipl bootloader */ if (bios_name == NULL) { bios_name = ipl->firmware; } bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (bios_filename == NULL) { hw_error("could not find stage1 bootloader\n"); } bios_size = load_elf(bios_filename, NULL, NULL, &ipl->start_addr, NULL, NULL, 1, ELF_MACHINE, 0); if (bios_size < 0) { bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START, 4096); ipl->start_addr = ZIPL_IMAGE_START; if (bios_size > 4096) { hw_error("stage1 bootloader is > 4k\n"); } } g_free(bios_filename); if (bios_size == -1) { hw_error("could not load bootloader '%s'\n", bios_name); } return 0; } else { uint64_t pentry = KERN_IMAGE_START; kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) { kernel_size = load_image_targphys(ipl->kernel, 0, ram_size); } if (kernel_size < 0) { fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel); return -1; } /* * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the * kernel parameters here as well. Note: For old kernels (up to 3.2) * we can not rely on the ELF entry point - it was 0x800 (the SALIPL * loader) and it won't work. For this case we force it to 0x10000, too. */ if (pentry == KERN_IMAGE_START || pentry == 0x800) { ipl->start_addr = KERN_IMAGE_START; /* Overwrite parameters in the kernel image, which are "rom" */ strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline); } else { ipl->start_addr = pentry; } } if (ipl->initrd) { ram_addr_t initrd_offset; int initrd_size; initrd_offset = INITRD_START; while (kernel_size + 0x100000 > initrd_offset) { initrd_offset += 0x100000; } initrd_size = load_image_targphys(ipl->initrd, initrd_offset, ram_size - initrd_offset); if (initrd_size == -1) { fprintf(stderr, "qemu: could not load initrd '%s'\n", ipl->initrd); exit(1); } /* we have to overwrite values in the kernel image, which are "rom" */ stq_p(rom_ptr(INITRD_PARM_START), initrd_offset); stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size); } return 0; }