PCIDevice *pci_nic_init(NICInfo *nd, const char *default_model, const char *default_devaddr) { const char *devaddr = nd->devaddr ? nd->devaddr : default_devaddr; PCIBus *bus; int devfn; PCIDevice *pci_dev; DeviceState *dev; int i; i = qemu_find_nic_model(nd, pci_nic_models, default_model); if (i < 0) return NULL; bus = pci_get_bus_devfn(&devfn, devaddr); if (!bus) { error_report("Invalid PCI device address %s for device %s", devaddr, pci_nic_names[i]); return NULL; } pci_dev = pci_create(bus, devfn, pci_nic_names[i]); dev = &pci_dev->qdev; if (nd->name) dev->id = qemu_strdup(nd->name); qdev_set_nic_properties(dev, nd); if (qdev_init(dev) < 0) return NULL; return pci_dev; }


static const char *local_mapped_attr_path(FsContext *ctx, const char *path, char *buffer) { char *dir_name; char *tmp_path = g_strdup(path); char *base_name = basename(tmp_path); /* NULL terminate the directory */ dir_name = tmp_path; *(base_name - 1) = '\0'; snprintf(buffer, PATH_MAX, "%s/%s/%s/%s", ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name); g_free(tmp_path); return buffer; }


RxFilterInfoList *qmp_query_rx_filter(bool has_name, const char *name, Error **errp) { NetClientState *nc; RxFilterInfoList *filter_list = NULL, *last_entry = NULL; QTAILQ_FOREACH(nc, &net_clients, next) { RxFilterInfoList *entry; RxFilterInfo *info; if (has_name && strcmp(nc->name, name) != 0) { continue; } /* only query rx-filter information of NIC */ if (nc->info->type != NET_CLIENT_OPTIONS_KIND_NIC) { if (has_name) { error_setg(errp, "net client(%s) isn't a NIC", name); break; } continue; } if (nc->info->query_rx_filter) { info = nc->info->query_rx_filter(nc); entry = g_malloc0(sizeof(*entry)); entry->value = info; if (!filter_list) { filter_list = entry; } else { last_entry->next = entry; } last_entry = entry; } else if (has_name) { error_setg(errp, "net client(%s) doesn't support" " rx-filter querying", name); break; } if (has_name) { break; } } if (filter_list == NULL && !error_is_set(errp) && has_name) { error_setg(errp, "invalid net client name: %s", name); } return filter_list; }


write_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, pflag = 0, qflag = 0, bflag = 0; int c, cnt; char *buf; int64_t offset; int count; /* Some compilers get confused and warn if this is not initialized. */ int total = 0; int pattern = 0xcd; while ((c = getopt(argc, argv, "bCpP:q")) != EOF) { switch (c) { case 'b': bflag = 1; break; case 'C': Cflag = 1; break; case 'p': pflag = 1; break; case 'P': pattern = atoi(optarg); break; case 'q': qflag = 1; break; default: return command_usage(&write_cmd); } } if (optind != argc - 2) return command_usage(&write_cmd); if (bflag && pflag) { printf("-b and -p cannot be specified at the same time\n"); return 0; } offset = cvtnum(argv[optind]); if (offset < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } optind++; count = cvtnum(argv[optind]); if (count < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } if (!pflag) { if (offset & 0x1ff) { printf("offset %lld is not sector aligned\n", (long long)offset); return 0; } if (count & 0x1ff) { printf("count %d is not sector aligned\n", count); return 0; } } buf = qemu_io_alloc(count, pattern); gettimeofday(&t1, NULL); if (pflag) cnt = do_pwrite(buf, offset, count, &total); else if (bflag) cnt = do_save_vmstate(buf, offset, count, &total); else cnt = do_write(buf, offset, count, &total); gettimeofday(&t2, NULL); if (cnt < 0) { printf("write failed: %s\n", strerror(-cnt)); goto out; } if (qflag) goto out; /* Finally, report back -- -C gives a parsable format */ t2 = tsub(t2, t1); print_report("wrote", &t2, offset, count, total, cnt, Cflag); out: qemu_io_free(buf); return 0; }


void framebuffer_update_display( DisplaySurface *ds, MemoryRegion *address_space, hwaddr base, int cols, /* Width in pixels. */ int rows, /* Height in pixels. */ int src_width, /* Length of source line, in bytes. */ int dest_row_pitch, /* Bytes between adjacent horizontal output pixels. */ int dest_col_pitch, /* Bytes between adjacent vertical output pixels. */ int invalidate, /* nonzero to redraw the whole image. */ drawfn fn, void *opaque, int *first_row, /* Input and output. */ int *last_row /* Output only */) { hwaddr src_len; uint8_t *dest; uint8_t *src; uint8_t *src_base; int first, last = 0; int dirty; int i; ram_addr_t addr; MemoryRegionSection mem_section; MemoryRegion *mem; i = *first_row; *first_row = -1; src_len = src_width * rows; mem_section = memory_region_find(address_space, base, src_len); if (int128_get64(mem_section.size) != src_len || !memory_region_is_ram(mem_section.mr)) { return; } mem = mem_section.mr; assert(mem); assert(mem_section.offset_within_address_space == base); memory_region_sync_dirty_bitmap(mem); src_base = cpu_physical_memory_map(base, &src_len, 0); /* If we can't map the framebuffer then bail. We could try harder, but it's not really worth it as dirty flag tracking will probably already have failed above. */ if (!src_base) return; if (src_len != src_width * rows) { cpu_physical_memory_unmap(src_base, src_len, 0, 0); return; } src = src_base; dest = surface_data(ds); if (dest_col_pitch < 0) dest -= dest_col_pitch * (cols - 1); if (dest_row_pitch < 0) { dest -= dest_row_pitch * (rows - 1); } first = -1; addr = mem_section.offset_within_region; addr += i * src_width; src += i * src_width; dest += i * dest_row_pitch; for (; i < rows; i++) { dirty = memory_region_get_dirty(mem, addr, src_width, DIRTY_MEMORY_VGA); if (dirty || invalidate) { fn(opaque, dest, src, cols, dest_col_pitch); if (first == -1) first = i; last = i; } addr += src_width; src += src_width; dest += dest_row_pitch; } cpu_physical_memory_unmap(src_base, src_len, 0, 0); if (first < 0) { return; } memory_region_reset_dirty(mem, mem_section.offset_within_region, src_len, DIRTY_MEMORY_VGA); *first_row = first; *last_row = last; }


void tcg_region_reset_all(void) { unsigned int i; qemu_mutex_lock(&region.lock); region.current = 0; region.agg_size_full = 0; for (i = 0; i < n_tcg_ctxs; i++) { bool err = tcg_region_initial_alloc__locked(tcg_ctxs[i]); g_assert(!err); } qemu_mutex_unlock(&region.lock); }


static int parse_args(int argc, char **argv) { const char *r; int optind; struct qemu_argument *arginfo; for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { if (arginfo->env == NULL) { continue; } r = getenv(arginfo->env); if (r != NULL) { arginfo->handle_opt(r); } } optind = 1; for (;;) { if (optind >= argc) { break; } r = argv[optind]; if (r[0] != '-') { break; } optind++; r++; if (!strcmp(r, "-")) { break; } for (arginfo = arg_table; arginfo->handle_opt != NULL; arginfo++) { if (!strcmp(r, arginfo->argv)) { if (optind >= argc) { usage(); } arginfo->handle_opt(argv[optind]); if (arginfo->has_arg) { optind++; } break; } } /* no option matched the current argv */ if (arginfo->handle_opt == NULL) { usage(); } } if (optind >= argc) { usage(); } filename = argv[optind]; exec_path = argv[optind]; return optind; }


void cpu_loop(CPUOpenRISCState *env) { CPUState *cs = CPU(openrisc_env_get_cpu(env)); int trapnr, gdbsig; for (;;) { cpu_exec_start(cs); trapnr = cpu_openrisc_exec(cs); cpu_exec_end(cs); gdbsig = 0; switch (trapnr) { case EXCP_RESET: qemu_log("\nReset request, exit, pc is %#x\n", env->pc); exit(EXIT_FAILURE); break; case EXCP_BUSERR: qemu_log("\nBus error, exit, pc is %#x\n", env->pc); gdbsig = TARGET_SIGBUS; break; case EXCP_DPF: case EXCP_IPF: cpu_dump_state(cs, stderr, fprintf, 0); gdbsig = TARGET_SIGSEGV; break; case EXCP_TICK: qemu_log("\nTick time interrupt pc is %#x\n", env->pc); break; case EXCP_ALIGN: qemu_log("\nAlignment pc is %#x\n", env->pc); gdbsig = TARGET_SIGBUS; break; case EXCP_ILLEGAL: qemu_log("\nIllegal instructionpc is %#x\n", env->pc); gdbsig = TARGET_SIGILL; break; case EXCP_INT: qemu_log("\nExternal interruptpc is %#x\n", env->pc); break; case EXCP_DTLBMISS: case EXCP_ITLBMISS: qemu_log("\nTLB miss\n"); break; case EXCP_RANGE: qemu_log("\nRange\n"); gdbsig = TARGET_SIGSEGV; break; case EXCP_SYSCALL: env->pc += 4; /* 0xc00; */ env->gpr[11] = do_syscall(env, env->gpr[11], /* return value */ env->gpr[3], /* r3 - r7 are params */ env->gpr[4], env->gpr[5], env->gpr[6], env->gpr[7], env->gpr[8], 0, 0); break; case EXCP_FPE: qemu_log("\nFloating point error\n"); break; case EXCP_TRAP: qemu_log("\nTrap\n"); gdbsig = TARGET_SIGTRAP; break; case EXCP_NR: qemu_log("\nNR\n"); break; default: qemu_log("\nqemu: unhandled CPU exception %#x - aborting\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); gdbsig = TARGET_SIGILL; break; } if (gdbsig) { gdb_handlesig(cs, gdbsig); if (gdbsig != TARGET_SIGTRAP) { exit(EXIT_FAILURE); } } process_pending_signals(env); } }


void msix_save(PCIDevice *dev, QEMUFile *f) { unsigned n = dev->msix_entries_nr; if (!(dev->cap_present & QEMU_PCI_CAP_MSIX)) { return; } qemu_put_buffer(f, dev->msix_table_page, n * PCI_MSIX_ENTRY_SIZE); qemu_put_buffer(f, dev->msix_table_page + MSIX_PAGE_PENDING, (n + 7) / 8); }


int qsv_init(AVCodecContext *s) { InputStream *ist = s->opaque; QSVContext *qsv = ist->hwaccel_ctx; AVQSVContext *hwctx_dec; int ret; if (!qsv) { av_log(NULL, AV_LOG_ERROR, "QSV transcoding is not initialized. " "-hwaccel qsv should only be used for one-to-one QSV transcoding " "with no filters.\n"); return AVERROR_BUG; } ret = init_opaque_surf(qsv); if (ret < 0) return ret; hwctx_dec = av_qsv_alloc_context(); if (!hwctx_dec) return AVERROR(ENOMEM); hwctx_dec->session = qsv->session; hwctx_dec->iopattern = MFX_IOPATTERN_OUT_OPAQUE_MEMORY; hwctx_dec->ext_buffers = qsv->ext_buffers; hwctx_dec->nb_ext_buffers = FF_ARRAY_ELEMS(qsv->ext_buffers); av_freep(&s->hwaccel_context); s->hwaccel_context = hwctx_dec; ist->hwaccel_get_buffer = qsv_get_buffer; ist->hwaccel_uninit = qsv_uninit; return 0; }


static void default_drive(int enable, int snapshot, int use_scsi, BlockInterfaceType type, int index, const char *optstr) { QemuOpts *opts; if (type == IF_DEFAULT) { type = use_scsi ? IF_SCSI : IF_IDE; } if (!enable || drive_get_by_index(type, index)) { return; } opts = drive_add(type, index, NULL, optstr); if (snapshot) { drive_enable_snapshot(opts, NULL); } if (!drive_init(opts, use_scsi)) { exit(1); } }


void css_generate_css_crws(uint8_t cssid) { if (!channel_subsys.sei_pending) { css_queue_crw(CRW_RSC_CSS, CRW_ERC_EVENT, 0, cssid); } channel_subsys.sei_pending = true; }


int qemu_add_wait_object(HANDLE handle, WaitObjectFunc *func, void *opaque) { WaitObjects *w = &wait_objects; if (w->num >= MAXIMUM_WAIT_OBJECTS) return -1; w->events[w->num] = handle; w->func[w->num] = func; w->opaque[w->num] = opaque; w->num++; return 0; }


static void scsi_device_unrealize(SCSIDevice *s, Error **errp) { SCSIDeviceClass *sc = SCSI_DEVICE_GET_CLASS(s); if (sc->unrealize) { sc->unrealize(s, errp); } }


void disas(FILE *out, void *code, unsigned long size) { unsigned long pc; int count; struct disassemble_info disasm_info; int (*print_insn)(bfd_vma pc, disassemble_info *info); INIT_DISASSEMBLE_INFO(disasm_info, out, fprintf); disasm_info.buffer = code; disasm_info.buffer_vma = (unsigned long)code; disasm_info.buffer_length = size; #ifdef HOST_WORDS_BIGENDIAN disasm_info.endian = BFD_ENDIAN_BIG; #else disasm_info.endian = BFD_ENDIAN_LITTLE; #endif #if defined(__i386__) disasm_info.mach = bfd_mach_i386_i386; print_insn = print_insn_i386; #elif defined(__x86_64__) disasm_info.mach = bfd_mach_x86_64; print_insn = print_insn_i386; #elif defined(_ARCH_PPC) print_insn = print_insn_ppc; #elif defined(__alpha__) print_insn = print_insn_alpha; #elif defined(__sparc__) print_insn = print_insn_sparc; #if defined(__sparc_v8plus__) || defined(__sparc_v8plusa__) || defined(__sparc_v9__) disasm_info.mach = bfd_mach_sparc_v9b; #endif #elif defined(__arm__) print_insn = print_insn_arm; #elif defined(__MIPSEB__) print_insn = print_insn_big_mips; #elif defined(__MIPSEL__) print_insn = print_insn_little_mips; #elif defined(__m68k__) print_insn = print_insn_m68k; #elif defined(__s390__) print_insn = print_insn_s390; #elif defined(__hppa__) print_insn = print_insn_hppa; #elif defined(__ia64__) print_insn = print_insn_ia64; #else fprintf(out, "0x%lx: Asm output not supported on this arch\n", (long) code); return; #endif for (pc = (unsigned long)code; size > 0; pc += count, size -= count) { fprintf(out, "0x%08lx: ", pc); #ifdef __arm__ /* since data is included in the code, it is better to display code data too */ fprintf(out, "%08x ", (int)bfd_getl32((const bfd_byte *)pc)); #endif count = print_insn(pc, &disasm_info); fprintf(out, "\n"); if (count < 0) break; } }


void bdrv_add_key(BlockDriverState *bs, const char *key, Error **errp) { if (key) { if (!bdrv_is_encrypted(bs)) { error_setg(errp, "Node '%s' is not encrypted", bdrv_get_device_or_node_name(bs)); } else if (bdrv_set_key(bs, key) < 0) { error_set(errp, QERR_INVALID_PASSWORD); } } else { if (bdrv_key_required(bs)) { error_set(errp, ERROR_CLASS_DEVICE_ENCRYPTED, "'%s' (%s) is encrypted", bdrv_get_device_or_node_name(bs), bdrv_get_encrypted_filename(bs)); } } }


static void armv7m_nvic_reset(DeviceState *dev) { nvic_state *s = NVIC(dev); NVICClass *nc = NVIC_GET_CLASS(s); nc->parent_reset(dev); /* Common GIC reset resets to disabled; the NVIC doesn't have * per-CPU interfaces so mark our non-existent CPU interface * as enabled by default, and with a priority mask which allows * all interrupts through. */ s->gic.cpu_enabled[0] = true; s->gic.priority_mask[0] = 0x100; /* The NVIC as a whole is always enabled. */ s->gic.enabled = true; systick_reset(s); }


static void float_to_int16_sse(int16_t *dst, const float *src, long len){ int i; for(i=0; i<len; i+=4) { asm volatile( "cvtps2pi %1, %%mm0 \n\t" "cvtps2pi %2, %%mm1 \n\t" "packssdw %%mm1, %%mm0 \n\t" "movq %%mm0, %0 \n\t" :"=m"(dst[i]) :"m"(src[i]), "m"(src[i+2]) ); } asm volatile("emms"); }


static int migration_rate_limit(void *opaque) { MigrationState *s = opaque; int ret; ret = qemu_file_get_error(s->file); if (ret) { return ret; } if (s->bytes_xfer >= s->xfer_limit) { return 1; } return 0; }


void cpu_interrupt(CPUState *env, int mask) { int old_mask; old_mask = env->interrupt_request; env->interrupt_request |= mask; #ifndef CONFIG_USER_ONLY /* * If called from iothread context, wake the target cpu in * case its halted. */ if (!qemu_cpu_self(env)) { qemu_cpu_kick(env); return; } #endif if (use_icount) { env->icount_decr.u16.high = 0xffff; #ifndef CONFIG_USER_ONLY if (!can_do_io(env) && (mask & ~old_mask) != 0) { cpu_abort(env, "Raised interrupt while not in I/O function"); } #endif } else { cpu_unlink_tb(env); } }


static inline void tcg_out_tlb_load(TCGContext *s, TCGReg addrlo, TCGReg addrhi, int mem_index, TCGMemOp s_bits, tcg_insn_unit **label_ptr, int which) { const TCGReg r0 = TCG_REG_L0; const TCGReg r1 = TCG_REG_L1; TCGType ttype = TCG_TYPE_I32; TCGType htype = TCG_TYPE_I32; int trexw = 0, hrexw = 0; if (TCG_TARGET_REG_BITS == 64) { if (TARGET_LONG_BITS == 64) { ttype = TCG_TYPE_I64; trexw = P_REXW; } if (TCG_TYPE_PTR == TCG_TYPE_I64) { htype = TCG_TYPE_I64; hrexw = P_REXW; } } tcg_out_mov(s, htype, r0, addrlo); tcg_out_mov(s, ttype, r1, addrlo); tcg_out_shifti(s, SHIFT_SHR + hrexw, r0, TARGET_PAGE_BITS - CPU_TLB_ENTRY_BITS); tgen_arithi(s, ARITH_AND + trexw, r1, TARGET_PAGE_MASK | ((1 << s_bits) - 1), 0); tgen_arithi(s, ARITH_AND + hrexw, r0, (CPU_TLB_SIZE - 1) << CPU_TLB_ENTRY_BITS, 0); tcg_out_modrm_sib_offset(s, OPC_LEA + hrexw, r0, TCG_AREG0, r0, 0, offsetof(CPUArchState, tlb_table[mem_index][0]) + which); /* cmp 0(r0), r1 */ tcg_out_modrm_offset(s, OPC_CMP_GvEv + trexw, r1, r0, 0); /* Prepare for both the fast path add of the tlb addend, and the slow path function argument setup. There are two cases worth note: For 32-bit guest and x86_64 host, MOVL zero-extends the guest address before the fastpath ADDQ below. For 64-bit guest and x32 host, MOVQ copies the entire guest address for the slow path, while truncation for the 32-bit host happens with the fastpath ADDL below. */ tcg_out_mov(s, ttype, r1, addrlo); /* jne slow_path */ tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0); label_ptr[0] = s->code_ptr; s->code_ptr += 4; if (TARGET_LONG_BITS > TCG_TARGET_REG_BITS) { /* cmp 4(r0), addrhi */ tcg_out_modrm_offset(s, OPC_CMP_GvEv, addrhi, r0, 4); /* jne slow_path */ tcg_out_opc(s, OPC_JCC_long + JCC_JNE, 0, 0, 0); label_ptr[1] = s->code_ptr; s->code_ptr += 4; } /* TLB Hit. */ /* add addend(r0), r1 */ tcg_out_modrm_offset(s, OPC_ADD_GvEv + hrexw, r1, r0, offsetof(CPUTLBEntry, addend) - which); }


static inline void t_gen_sext(TCGv d, TCGv s, int size) { if (size == 1) tcg_gen_ext8s_i32(d, s); else if (size == 2) tcg_gen_ext16s_i32(d, s); else if(GET_TCGV(d) != GET_TCGV(s)) tcg_gen_mov_tl(d, s); }


static int vio_make_devnode(VIOsPAPRDevice *dev, void *fdt) { VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qdev_get_info(&dev->qdev); int vdevice_off, node_off, ret; char *dt_name; vdevice_off = fdt_path_offset(fdt, "/vdevice"); if (vdevice_off < 0) { return vdevice_off; } dt_name = vio_format_dev_name(dev); if (!dt_name) { return -ENOMEM; } node_off = fdt_add_subnode(fdt, vdevice_off, dt_name); free(dt_name); if (node_off < 0) { return node_off; } ret = fdt_setprop_cell(fdt, node_off, "reg", dev->reg); if (ret < 0) { return ret; } if (info->dt_type) { ret = fdt_setprop_string(fdt, node_off, "device_type", info->dt_type); if (ret < 0) { return ret; } } if (info->dt_compatible) { ret = fdt_setprop_string(fdt, node_off, "compatible", info->dt_compatible); if (ret < 0) { return ret; } } if (dev->qirq) { uint32_t ints_prop[] = {cpu_to_be32(dev->vio_irq_num), 0}; ret = fdt_setprop(fdt, node_off, "interrupts", ints_prop, sizeof(ints_prop)); if (ret < 0) { return ret; } } if (dev->rtce_window_size) { uint32_t dma_prop[] = {cpu_to_be32(dev->reg), 0, 0, 0, cpu_to_be32(dev->rtce_window_size)}; ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-address-cells", 2); if (ret < 0) { return ret; } ret = fdt_setprop_cell(fdt, node_off, "ibm,#dma-size-cells", 2); if (ret < 0) { return ret; } ret = fdt_setprop(fdt, node_off, "ibm,my-dma-window", dma_prop, sizeof(dma_prop)); if (ret < 0) { return ret; } } if (info->devnode) { ret = (info->devnode)(dev, fdt, node_off); if (ret < 0) { return ret; } } return node_off; }


void mkimg(const char *file, const char *fmt, unsigned size_mb) { gchar *cli; bool ret; int rc; GError *err = NULL; char *qemu_img_path; gchar *out, *out2; char *abs_path; qemu_img_path = getenv("QTEST_QEMU_IMG"); abs_path = realpath(qemu_img_path, NULL); assert(qemu_img_path); cli = g_strdup_printf("%s create -f %s %s %uM", abs_path, fmt, file, size_mb); ret = g_spawn_command_line_sync(cli, &out, &out2, &rc, &err); if (err) { fprintf(stderr, "%s\n", err->message); g_error_free(err); } g_assert(ret && !err); /* In glib 2.34, we have g_spawn_check_exit_status. in 2.12, we don't. * glib 2.43.91 implementation assumes that any non-zero is an error for * windows, but uses extra precautions for Linux. However, * 0 is only possible if the program exited normally, so that should be * sufficient for our purposes on all platforms, here. */ if (rc) { fprintf(stderr, "qemu-img returned status code %d\n", rc); } g_assert(!rc); g_free(out); g_free(out2); g_free(cli); free(abs_path); }


static inline void RENAME(rgb32tobgr15)(const uint8_t *src, uint8_t *dst, long src_size) { const uint8_t *s = src; const uint8_t *end; #if COMPILE_TEMPLATE_MMX const uint8_t *mm_end; #endif uint16_t *d = (uint16_t *)dst; end = s + src_size; #if COMPILE_TEMPLATE_MMX __asm__ volatile(PREFETCH" %0"::"m"(*src):"memory"); __asm__ volatile( "movq %0, %%mm7 \n\t" "movq %1, %%mm6 \n\t" ::"m"(red_15mask),"m"(green_15mask)); mm_end = end - 15; while (s < mm_end) { __asm__ volatile( PREFETCH" 32%1 \n\t" "movd %1, %%mm0 \n\t" "movd 4%1, %%mm3 \n\t" "punpckldq 8%1, %%mm0 \n\t" "punpckldq 12%1, %%mm3 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm0, %%mm2 \n\t" "movq %%mm3, %%mm4 \n\t" "movq %%mm3, %%mm5 \n\t" "psllq $7, %%mm0 \n\t" "psllq $7, %%mm3 \n\t" "pand %%mm7, %%mm0 \n\t" "pand %%mm7, %%mm3 \n\t" "psrlq $6, %%mm1 \n\t" "psrlq $6, %%mm4 \n\t" "pand %%mm6, %%mm1 \n\t" "pand %%mm6, %%mm4 \n\t" "psrlq $19, %%mm2 \n\t" "psrlq $19, %%mm5 \n\t" "pand %2, %%mm2 \n\t" "pand %2, %%mm5 \n\t" "por %%mm1, %%mm0 \n\t" "por %%mm4, %%mm3 \n\t" "por %%mm2, %%mm0 \n\t" "por %%mm5, %%mm3 \n\t" "psllq $16, %%mm3 \n\t" "por %%mm3, %%mm0 \n\t" MOVNTQ" %%mm0, %0 \n\t" :"=m"(*d):"m"(*s),"m"(blue_15mask):"memory"); d += 4; s += 16; } __asm__ volatile(SFENCE:::"memory"); __asm__ volatile(EMMS:::"memory"); #endif while (s < end) { register int rgb = *(const uint32_t*)s; s += 4; *d++ = ((rgb&0xF8)<<7) + ((rgb&0xF800)>>6) + ((rgb&0xF80000)>>19); } }


static void cris_alu_op_exec(DisasContext *dc, int op, TCGv dst, TCGv a, TCGv b, int size) { /* Emit the ALU insns. */ switch (op) { case CC_OP_ADD: tcg_gen_add_tl(dst, a, b); /* Extended arithmetics. */ t_gen_addx_carry(dc, dst); break; case CC_OP_ADDC: tcg_gen_add_tl(dst, a, b); t_gen_add_flag(dst, 0); /* C_FLAG. */ break; case CC_OP_MCP: tcg_gen_add_tl(dst, a, b); t_gen_add_flag(dst, 8); /* R_FLAG. */ break; case CC_OP_SUB: tcg_gen_sub_tl(dst, a, b); /* Extended arithmetics. */ t_gen_subx_carry(dc, dst); break; case CC_OP_MOVE: tcg_gen_mov_tl(dst, b); break; case CC_OP_OR: tcg_gen_or_tl(dst, a, b); break; case CC_OP_AND: tcg_gen_and_tl(dst, a, b); break; case CC_OP_XOR: tcg_gen_xor_tl(dst, a, b); break; case CC_OP_LSL: t_gen_lsl(dst, a, b); break; case CC_OP_LSR: t_gen_lsr(dst, a, b); break; case CC_OP_ASR: t_gen_asr(dst, a, b); break; case CC_OP_NEG: tcg_gen_neg_tl(dst, b); /* Extended arithmetics. */ t_gen_subx_carry(dc, dst); break; case CC_OP_LZ: gen_helper_lz(dst, b); break; case CC_OP_MULS: tcg_gen_muls2_tl(dst, cpu_PR[PR_MOF], a, b); break; case CC_OP_MULU: tcg_gen_mulu2_tl(dst, cpu_PR[PR_MOF], a, b); break; case CC_OP_DSTEP: t_gen_cris_dstep(dst, a, b); break; case CC_OP_MSTEP: t_gen_cris_mstep(dst, a, b, cpu_PR[PR_CCS]); break; case CC_OP_BOUND: { int l1; l1 = gen_new_label(); tcg_gen_mov_tl(dst, a); tcg_gen_brcond_tl(TCG_COND_LEU, a, b, l1); tcg_gen_mov_tl(dst, b); gen_set_label(l1); } break; case CC_OP_CMP: tcg_gen_sub_tl(dst, a, b); /* Extended arithmetics. */ t_gen_subx_carry(dc, dst); break; default: qemu_log("illegal ALU op.\n"); BUG(); break; } if (size == 1) { tcg_gen_andi_tl(dst, dst, 0xff); } else if (size == 2) { tcg_gen_andi_tl(dst, dst, 0xffff); } }


static void blockdev_backup_prepare(BlkTransactionState *common, Error **errp) { BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, common); BlockdevBackup *backup; BlockBackend *blk, *target; Error *local_err = NULL; assert(common->action->kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP); backup = common->action->blockdev_backup; blk = blk_by_name(backup->device); if (!blk) { error_setg(errp, "Device '%s' not found", backup->device); return; } if (!blk_is_available(blk)) { error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, backup->device); return; } target = blk_by_name(backup->target); if (!target) { error_setg(errp, "Device '%s' not found", backup->target); return; } /* AioContext is released in .clean() */ state->aio_context = blk_get_aio_context(blk); if (state->aio_context != blk_get_aio_context(target)) { state->aio_context = NULL; error_setg(errp, "Backup between two IO threads is not implemented"); return; } aio_context_acquire(state->aio_context); state->bs = blk_bs(blk); bdrv_drained_begin(state->bs); qmp_blockdev_backup(backup->device, backup->target, backup->sync, backup->has_speed, backup->speed, backup->has_on_source_error, backup->on_source_error, backup->has_on_target_error, backup->on_target_error, &local_err); if (local_err) { error_propagate(errp, local_err); return; } state->job = state->bs->job; }


static int zipl_magic(uint8_t *ptr) { uint32_t *p = (void*)ptr; uint32_t *z = (void*)ZIPL_MAGIC; if (*p != *z) { debug_print_int("invalid magic", *p); virtio_panic("invalid magic"); } return 1; }


static void bt_hid_interrupt_sdu(void *opaque, const uint8_t *data, int len) { struct bt_hid_device_s *hid = opaque; if (len > BT_HID_MTU || len < 1) goto bad; if ((data[0] & 3) != BT_DATA_OUTPUT) goto bad; if ((data[0] >> 4) == BT_DATA) { if (hid->intr_state) goto bad; hid->data_type = BT_DATA_OUTPUT; hid->intrdataout.len = 0; } else if ((data[0] >> 4) == BT_DATC) { if (!hid->intr_state) goto bad; } else goto bad; memcpy(hid->intrdataout.buffer + hid->intrdataout.len, data + 1, len - 1); hid->intrdataout.len += len - 1; hid->intr_state = (len == BT_HID_MTU); if (!hid->intr_state) { memcpy(hid->dataout.buffer, hid->intrdataout.buffer, hid->dataout.len = hid->intrdataout.len); bt_hid_out(hid); } return; bad: fprintf(stderr, "%s: bad transaction on Interrupt channel.\n", __func__); }


static void decode_opc (CPUState *env, DisasContext *ctx) { int32_t offset; int rs, rt, rd, sa; uint32_t op, op1, op2; int16_t imm; /* make sure instructions are on a word boundary */ if (ctx->pc & 0x3) { env->CP0_BadVAddr = ctx->pc; generate_exception(ctx, EXCP_AdEL); return; } if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) { int l1; /* Handle blikely not taken case */ MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4); l1 = gen_new_label(); gen_op_jnz_T2(l1); gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK); gen_goto_tb(ctx, 1, ctx->pc + 4); gen_set_label(l1); } op = MASK_OP_MAJOR(ctx->opcode); rs = (ctx->opcode >> 21) & 0x1f; rt = (ctx->opcode >> 16) & 0x1f; rd = (ctx->opcode >> 11) & 0x1f; sa = (ctx->opcode >> 6) & 0x1f; imm = (int16_t)ctx->opcode; switch (op) { case OPC_SPECIAL: op1 = MASK_SPECIAL(ctx->opcode); switch (op1) { case OPC_SLL: /* Arithmetic with immediate */ case OPC_SRL ... OPC_SRA: gen_arith_imm(env, ctx, op1, rd, rt, sa); break; case OPC_MOVZ ... OPC_MOVN: check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); case OPC_SLLV: /* Arithmetic */ case OPC_SRLV ... OPC_SRAV: case OPC_ADD ... OPC_NOR: case OPC_SLT ... OPC_SLTU: gen_arith(env, ctx, op1, rd, rs, rt); break; case OPC_MULT ... OPC_DIVU: gen_muldiv(ctx, op1, rs, rt); break; case OPC_JR ... OPC_JALR: gen_compute_branch(ctx, op1, rs, rd, sa); return; case OPC_TGE ... OPC_TEQ: /* Traps */ case OPC_TNE: gen_trap(ctx, op1, rs, rt, -1); break; case OPC_MFHI: /* Move from HI/LO */ case OPC_MFLO: gen_HILO(ctx, op1, rd); break; case OPC_MTHI: case OPC_MTLO: /* Move to HI/LO */ gen_HILO(ctx, op1, rs); break; case OPC_PMON: /* Pmon entry point, also R4010 selsl */ #ifdef MIPS_STRICT_STANDARD MIPS_INVAL("PMON / selsl"); generate_exception(ctx, EXCP_RI); #else gen_op_pmon(sa); #endif break; case OPC_SYSCALL: generate_exception(ctx, EXCP_SYSCALL); break; case OPC_BREAK: generate_exception(ctx, EXCP_BREAK); break; case OPC_SPIM: #ifdef MIPS_STRICT_STANDARD MIPS_INVAL("SPIM"); generate_exception(ctx, EXCP_RI); #else /* Implemented as RI exception for now. */ MIPS_INVAL("spim (unofficial)"); generate_exception(ctx, EXCP_RI); #endif break; case OPC_SYNC: /* Treat as NOP. */ break; case OPC_MOVCI: check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); check_cp1_enabled(ctx); gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7, (ctx->opcode >> 16) & 1); } else { generate_exception_err(ctx, EXCP_CpU, 1); } break; #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) /* MIPS64 specific opcodes */ case OPC_DSLL: case OPC_DSRL ... OPC_DSRA: case OPC_DSLL32: case OPC_DSRL32 ... OPC_DSRA32: check_insn(env, ctx, ISA_MIPS3); check_mips_64(ctx); gen_arith_imm(env, ctx, op1, rd, rt, sa); break; case OPC_DSLLV: case OPC_DSRLV ... OPC_DSRAV: case OPC_DADD ... OPC_DSUBU: check_insn(env, ctx, ISA_MIPS3); check_mips_64(ctx); gen_arith(env, ctx, op1, rd, rs, rt); break; case OPC_DMULT ... OPC_DDIVU: check_insn(env, ctx, ISA_MIPS3); check_mips_64(ctx); gen_muldiv(ctx, op1, rs, rt); break; #endif default: /* Invalid */ MIPS_INVAL("special"); generate_exception(ctx, EXCP_RI); break; } break; case OPC_SPECIAL2: op1 = MASK_SPECIAL2(ctx->opcode); switch (op1) { case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */ case OPC_MSUB ... OPC_MSUBU: check_insn(env, ctx, ISA_MIPS32); gen_muldiv(ctx, op1, rs, rt); break; case OPC_MUL: gen_arith(env, ctx, op1, rd, rs, rt); break; case OPC_CLZ ... OPC_CLO: check_insn(env, ctx, ISA_MIPS32); gen_cl(ctx, op1, rd, rs); break; case OPC_SDBBP: /* XXX: not clear which exception should be raised * when in debug mode... */ check_insn(env, ctx, ISA_MIPS32); if (!(ctx->hflags & MIPS_HFLAG_DM)) { generate_exception(ctx, EXCP_DBp); } else { generate_exception(ctx, EXCP_DBp); } /* Treat as NOP. */ break; #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) case OPC_DCLZ ... OPC_DCLO: check_insn(env, ctx, ISA_MIPS64); check_mips_64(ctx); gen_cl(ctx, op1, rd, rs); break; #endif default: /* Invalid */ MIPS_INVAL("special2"); generate_exception(ctx, EXCP_RI); break; } break; case OPC_SPECIAL3: op1 = MASK_SPECIAL3(ctx->opcode); switch (op1) { case OPC_EXT: case OPC_INS: check_insn(env, ctx, ISA_MIPS32R2); gen_bitops(ctx, op1, rt, rs, sa, rd); break; case OPC_BSHFL: check_insn(env, ctx, ISA_MIPS32R2); op2 = MASK_BSHFL(ctx->opcode); switch (op2) { case OPC_WSBH: GEN_LOAD_REG_TN(T1, rt); gen_op_wsbh(); break; case OPC_SEB: GEN_LOAD_REG_TN(T1, rt); gen_op_seb(); break; case OPC_SEH: GEN_LOAD_REG_TN(T1, rt); gen_op_seh(); break; default: /* Invalid */ MIPS_INVAL("bshfl"); generate_exception(ctx, EXCP_RI); break; } GEN_STORE_TN_REG(rd, T0); break; case OPC_RDHWR: check_insn(env, ctx, ISA_MIPS32R2); switch (rd) { case 0: save_cpu_state(ctx, 1); gen_op_rdhwr_cpunum(); break; case 1: save_cpu_state(ctx, 1); gen_op_rdhwr_synci_step(); break; case 2: save_cpu_state(ctx, 1); gen_op_rdhwr_cc(); break; case 3: save_cpu_state(ctx, 1); gen_op_rdhwr_ccres(); break; case 29: #if defined (CONFIG_USER_ONLY) gen_op_tls_value(); break; #endif default: /* Invalid */ MIPS_INVAL("rdhwr"); generate_exception(ctx, EXCP_RI); break; } GEN_STORE_TN_REG(rt, T0); break; case OPC_FORK: check_mips_mt(env, ctx); GEN_LOAD_REG_TN(T0, rt); GEN_LOAD_REG_TN(T1, rs); gen_op_fork(); break; case OPC_YIELD: check_mips_mt(env, ctx); GEN_LOAD_REG_TN(T0, rs); gen_op_yield(); GEN_STORE_TN_REG(rd, T0); break; #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) case OPC_DEXTM ... OPC_DEXT: case OPC_DINSM ... OPC_DINS: check_insn(env, ctx, ISA_MIPS64R2); check_mips_64(ctx); gen_bitops(ctx, op1, rt, rs, sa, rd); break; case OPC_DBSHFL: check_insn(env, ctx, ISA_MIPS64R2); check_mips_64(ctx); op2 = MASK_DBSHFL(ctx->opcode); switch (op2) { case OPC_DSBH: GEN_LOAD_REG_TN(T1, rt); gen_op_dsbh(); break; case OPC_DSHD: GEN_LOAD_REG_TN(T1, rt); gen_op_dshd(); break; default: /* Invalid */ MIPS_INVAL("dbshfl"); generate_exception(ctx, EXCP_RI); break; } GEN_STORE_TN_REG(rd, T0); #endif default: /* Invalid */ MIPS_INVAL("special3"); generate_exception(ctx, EXCP_RI); break; } break; case OPC_REGIMM: op1 = MASK_REGIMM(ctx->opcode); switch (op1) { case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */ case OPC_BLTZAL ... OPC_BGEZALL: gen_compute_branch(ctx, op1, rs, -1, imm << 2); return; case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */ case OPC_TNEI: gen_trap(ctx, op1, rs, -1, imm); break; case OPC_SYNCI: check_insn(env, ctx, ISA_MIPS32R2); /* Treat as NOP. */ break; default: /* Invalid */ MIPS_INVAL("regimm"); generate_exception(ctx, EXCP_RI); break; } break; case OPC_CP0: check_cp0_enabled(ctx); op1 = MASK_CP0(ctx->opcode); switch (op1) { case OPC_MFC0: case OPC_MTC0: case OPC_MFTR: case OPC_MTTR: #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) case OPC_DMFC0: case OPC_DMTC0: #endif gen_cp0(env, ctx, op1, rt, rd); break; case OPC_C0_FIRST ... OPC_C0_LAST: gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd); break; case OPC_MFMC0: op2 = MASK_MFMC0(ctx->opcode); switch (op2) { case OPC_DMT: check_mips_mt(env, ctx); gen_op_dmt(); break; case OPC_EMT: check_mips_mt(env, ctx); gen_op_emt(); break; case OPC_DVPE: check_mips_mt(env, ctx); gen_op_dvpe(); break; case OPC_EVPE: check_mips_mt(env, ctx); gen_op_evpe(); break; case OPC_DI: check_insn(env, ctx, ISA_MIPS32R2); save_cpu_state(ctx, 1); gen_op_di(); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case OPC_EI: check_insn(env, ctx, ISA_MIPS32R2); save_cpu_state(ctx, 1); gen_op_ei(); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; default: /* Invalid */ MIPS_INVAL("mfmc0"); generate_exception(ctx, EXCP_RI); break; } GEN_STORE_TN_REG(rt, T0); break; case OPC_RDPGPR: check_insn(env, ctx, ISA_MIPS32R2); GEN_LOAD_SRSREG_TN(T0, rt); GEN_STORE_TN_REG(rd, T0); break; case OPC_WRPGPR: check_insn(env, ctx, ISA_MIPS32R2); GEN_LOAD_REG_TN(T0, rt); GEN_STORE_TN_SRSREG(rd, T0); break; default: MIPS_INVAL("cp0"); generate_exception(ctx, EXCP_RI); break; } break; case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */ gen_arith_imm(env, ctx, op, rt, rs, imm); break; case OPC_J ... OPC_JAL: /* Jump */ offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2; gen_compute_branch(ctx, op, rs, rt, offset); return; case OPC_BEQ ... OPC_BGTZ: /* Branch */ case OPC_BEQL ... OPC_BGTZL: gen_compute_branch(ctx, op, rs, rt, imm << 2); return; case OPC_LB ... OPC_LWR: /* Load and stores */ case OPC_SB ... OPC_SW: case OPC_SWR: case OPC_LL: case OPC_SC: gen_ldst(ctx, op, rt, rs, imm); break; case OPC_CACHE: check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32); /* Treat as NOP. */ break; case OPC_PREF: check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32); /* Treat as NOP. */ break; /* Floating point (COP1). */ case OPC_LWC1: case OPC_LDC1: case OPC_SWC1: case OPC_SDC1: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); check_cp1_enabled(ctx); gen_flt_ldst(ctx, op, rt, rs, imm); } else { generate_exception_err(ctx, EXCP_CpU, 1); } break; case OPC_CP1: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); check_cp1_enabled(ctx); op1 = MASK_CP1(ctx->opcode); switch (op1) { case OPC_MFHC1: case OPC_MTHC1: check_insn(env, ctx, ISA_MIPS32R2); case OPC_MFC1: case OPC_CFC1: case OPC_MTC1: case OPC_CTC1: gen_cp1(ctx, op1, rt, rd); break; #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) case OPC_DMFC1: case OPC_DMTC1: check_insn(env, ctx, ISA_MIPS3); gen_cp1(ctx, op1, rt, rd); break; #endif case OPC_BC1ANY2: case OPC_BC1ANY4: check_cp1_3d(env, ctx); /* fall through */ case OPC_BC1: gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode), (rt >> 2) & 0x7, imm << 2); return; case OPC_S_FMT: case OPC_D_FMT: case OPC_W_FMT: case OPC_L_FMT: case OPC_PS_FMT: gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa, (imm >> 8) & 0x7); break; default: MIPS_INVAL("cp1"); generate_exception (ctx, EXCP_RI); break; } } else { generate_exception_err(ctx, EXCP_CpU, 1); } break; /* COP2. */ case OPC_LWC2: case OPC_LDC2: case OPC_SWC2: case OPC_SDC2: case OPC_CP2: /* COP2: Not implemented. */ generate_exception_err(ctx, EXCP_CpU, 2); break; case OPC_CP3: if (env->CP0_Config1 & (1 << CP0C1_FP)) { save_cpu_state(ctx, 1); check_cp1_enabled(ctx); op1 = MASK_CP3(ctx->opcode); switch (op1) { case OPC_LWXC1: case OPC_LDXC1: case OPC_LUXC1: case OPC_SWXC1: case OPC_SDXC1: case OPC_SUXC1: gen_flt3_ldst(ctx, op1, sa, rd, rs, rt); break; case OPC_PREFX: /* Treat as NOP. */ break; case OPC_ALNV_PS: case OPC_MADD_S: case OPC_MADD_D: case OPC_MADD_PS: case OPC_MSUB_S: case OPC_MSUB_D: case OPC_MSUB_PS: case OPC_NMADD_S: case OPC_NMADD_D: case OPC_NMADD_PS: case OPC_NMSUB_S: case OPC_NMSUB_D: case OPC_NMSUB_PS: gen_flt3_arith(ctx, op1, sa, rs, rd, rt); break; default: MIPS_INVAL("cp3"); generate_exception (ctx, EXCP_RI); break; } } else { generate_exception_err(ctx, EXCP_CpU, 1); } break; #if defined(TARGET_MIPSN32) || defined(TARGET_MIPS64) /* MIPS64 opcodes */ case OPC_LWU: case OPC_LDL ... OPC_LDR: case OPC_SDL ... OPC_SDR: case OPC_LLD: case OPC_LD: case OPC_SCD: case OPC_SD: check_insn(env, ctx, ISA_MIPS3); check_mips_64(ctx); gen_ldst(ctx, op, rt, rs, imm); break; case OPC_DADDI ... OPC_DADDIU: check_insn(env, ctx, ISA_MIPS3); check_mips_64(ctx); gen_arith_imm(env, ctx, op, rt, rs, imm); break; #endif case OPC_JALX: check_insn(env, ctx, ASE_MIPS16); /* MIPS16: Not implemented. */ case OPC_MDMX: check_insn(env, ctx, ASE_MDMX); /* MDMX: Not implemented. */ default: /* Invalid */ MIPS_INVAL("major opcode"); generate_exception(ctx, EXCP_RI); break; } if (ctx->hflags & MIPS_HFLAG_BMASK) { int hflags = ctx->hflags & MIPS_HFLAG_BMASK; /* Branches completion */ ctx->hflags &= ~MIPS_HFLAG_BMASK; ctx->bstate = BS_BRANCH; save_cpu_state(ctx, 0); switch (hflags) { case MIPS_HFLAG_B: /* unconditional branch */ MIPS_DEBUG("unconditional branch"); gen_goto_tb(ctx, 0, ctx->btarget); break; case MIPS_HFLAG_BL: /* blikely taken case */ MIPS_DEBUG("blikely branch taken"); gen_goto_tb(ctx, 0, ctx->btarget); break; case MIPS_HFLAG_BC: /* Conditional branch */ MIPS_DEBUG("conditional branch"); { int l1; l1 = gen_new_label(); gen_op_jnz_T2(l1); gen_goto_tb(ctx, 1, ctx->pc + 4); gen_set_label(l1); gen_goto_tb(ctx, 0, ctx->btarget); } break; case MIPS_HFLAG_BR: /* unconditional branch to register */ MIPS_DEBUG("branch to register"); gen_op_breg(); gen_op_reset_T0(); gen_op_exit_tb(); break; default: MIPS_DEBUG("unknown branch"); break; } } }


static void port92_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { Port92State *s = opaque; int oldval = s->outport; DPRINTF("port92: write 0x%02" PRIx64 "\n", val); s->outport = val; qemu_set_irq(*s->a20_out, (val >> 1) & 1); if ((val & 1) && !(oldval & 1)) { qemu_system_reset_request(); } }


static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s) { BlockDriverState *source = blk_bs(s->common.blk); int64_t sector_num, first_chunk; uint64_t delay_ns = 0; /* At least the first dirty chunk is mirrored in one iteration. */ int nb_chunks = 1; int64_t end = s->bdev_length / BDRV_SECTOR_SIZE; int sectors_per_chunk = s->granularity >> BDRV_SECTOR_BITS; bool write_zeroes_ok = bdrv_can_write_zeroes_with_unmap(blk_bs(s->target)); sector_num = hbitmap_iter_next(&s->hbi); if (sector_num < 0) { bdrv_dirty_iter_init(s->dirty_bitmap, &s->hbi); sector_num = hbitmap_iter_next(&s->hbi); trace_mirror_restart_iter(s, bdrv_get_dirty_count(s->dirty_bitmap)); assert(sector_num >= 0); } first_chunk = sector_num / sectors_per_chunk; while (test_bit(first_chunk, s->in_flight_bitmap)) { trace_mirror_yield_in_flight(s, sector_num, s->in_flight); mirror_wait_for_io(s); } block_job_pause_point(&s->common); /* Find the number of consective dirty chunks following the first dirty * one, and wait for in flight requests in them. */ while (nb_chunks * sectors_per_chunk < (s->buf_size >> BDRV_SECTOR_BITS)) { int64_t hbitmap_next; int64_t next_sector = sector_num + nb_chunks * sectors_per_chunk; int64_t next_chunk = next_sector / sectors_per_chunk; if (next_sector >= end || !bdrv_get_dirty(source, s->dirty_bitmap, next_sector)) { break; } if (test_bit(next_chunk, s->in_flight_bitmap)) { break; } hbitmap_next = hbitmap_iter_next(&s->hbi); if (hbitmap_next > next_sector || hbitmap_next < 0) { /* The bitmap iterator's cache is stale, refresh it */ bdrv_set_dirty_iter(&s->hbi, next_sector); hbitmap_next = hbitmap_iter_next(&s->hbi); } assert(hbitmap_next == next_sector); nb_chunks++; } /* Clear dirty bits before querying the block status, because * calling bdrv_get_block_status_above could yield - if some blocks are * marked dirty in this window, we need to know. */ bdrv_reset_dirty_bitmap(s->dirty_bitmap, sector_num, nb_chunks * sectors_per_chunk); bitmap_set(s->in_flight_bitmap, sector_num / sectors_per_chunk, nb_chunks); while (nb_chunks > 0 && sector_num < end) { int ret; int io_sectors, io_sectors_acct; BlockDriverState *file; enum MirrorMethod { MIRROR_METHOD_COPY, MIRROR_METHOD_ZERO, MIRROR_METHOD_DISCARD } mirror_method = MIRROR_METHOD_COPY; assert(!(sector_num % sectors_per_chunk)); ret = bdrv_get_block_status_above(source, NULL, sector_num, nb_chunks * sectors_per_chunk, &io_sectors, &file); if (ret < 0) { io_sectors = nb_chunks * sectors_per_chunk; } io_sectors -= io_sectors % sectors_per_chunk; if (io_sectors < sectors_per_chunk) { io_sectors = sectors_per_chunk; } else if (ret >= 0 && !(ret & BDRV_BLOCK_DATA)) { int64_t target_sector_num; int target_nb_sectors; bdrv_round_sectors_to_clusters(blk_bs(s->target), sector_num, io_sectors, &target_sector_num, &target_nb_sectors); if (target_sector_num == sector_num && target_nb_sectors == io_sectors) { mirror_method = ret & BDRV_BLOCK_ZERO ? MIRROR_METHOD_ZERO : MIRROR_METHOD_DISCARD; } } while (s->in_flight >= MAX_IN_FLIGHT) { trace_mirror_yield_in_flight(s, sector_num, s->in_flight); mirror_wait_for_io(s); } mirror_clip_sectors(s, sector_num, &io_sectors); switch (mirror_method) { case MIRROR_METHOD_COPY: io_sectors = mirror_do_read(s, sector_num, io_sectors); io_sectors_acct = io_sectors; break; case MIRROR_METHOD_ZERO: case MIRROR_METHOD_DISCARD: mirror_do_zero_or_discard(s, sector_num, io_sectors, mirror_method == MIRROR_METHOD_DISCARD); if (write_zeroes_ok) { io_sectors_acct = 0; } else { io_sectors_acct = io_sectors; } break; default: abort(); } assert(io_sectors); sector_num += io_sectors; nb_chunks -= DIV_ROUND_UP(io_sectors, sectors_per_chunk); if (s->common.speed) { delay_ns = ratelimit_calculate_delay(&s->limit, io_sectors_acct); } } return delay_ns; }


static void flush_encoders(void) { int i, ret; for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; AVCodecContext *enc = ost->enc_ctx; AVFormatContext *os = output_files[ost->file_index]->ctx; int stop_encoding = 0; if (!ost->encoding_needed) continue; if (enc->codec_type == AVMEDIA_TYPE_AUDIO && enc->frame_size <= 1) continue; if (enc->codec_type != AVMEDIA_TYPE_VIDEO && enc->codec_type != AVMEDIA_TYPE_AUDIO) continue; avcodec_send_frame(enc, NULL); for (;;) { const char *desc = NULL; switch (enc->codec_type) { case AVMEDIA_TYPE_AUDIO: desc = "Audio"; break; case AVMEDIA_TYPE_VIDEO: desc = "Video"; break; default: av_assert0(0); } if (1) { AVPacket pkt; av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; ret = avcodec_receive_packet(enc, &pkt); if (ret < 0 && ret != AVERROR_EOF) { av_log(NULL, AV_LOG_FATAL, "%s encoding failed\n", desc); exit_program(1); } if (ost->logfile && enc->stats_out) { fprintf(ost->logfile, "%s", enc->stats_out); } if (ret == AVERROR_EOF) { stop_encoding = 1; break; } av_packet_rescale_ts(&pkt, enc->time_base, ost->st->time_base); output_packet(os, &pkt, ost); } if (stop_encoding) break; } } }


AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, URLContext *handle, int packet_size) { AVFormatContext *rtpctx; int ret; AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); if (!rtp_format) return NULL; /* Allocate an AVFormatContext for each output stream */ rtpctx = avformat_alloc_context(); if (!rtpctx) return NULL; rtpctx->oformat = rtp_format; if (!av_new_stream(rtpctx, 0)) { av_free(rtpctx); return NULL; } /* Copy the max delay setting; the rtp muxer reads this. */ rtpctx->max_delay = s->max_delay; /* Copy other stream parameters. */ rtpctx->streams[0]->sample_aspect_ratio = st->sample_aspect_ratio; /* Set the synchronized start time. */ rtpctx->start_time_realtime = s->start_time_realtime; avcodec_copy_context(rtpctx->streams[0]->codec, st->codec); if (handle) { url_fdopen(&rtpctx->pb, handle); } else url_open_dyn_packet_buf(&rtpctx->pb, packet_size); ret = av_write_header(rtpctx); if (ret) { if (handle) { avio_close(rtpctx->pb); } else { uint8_t *ptr; avio_close_dyn_buf(rtpctx->pb, &ptr); av_free(ptr); } avformat_free_context(rtpctx); return NULL; } return rtpctx; }


static av_cold int avs_decode_init(AVCodecContext * avctx) { AvsContext *s = avctx->priv_data; s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); avctx->pix_fmt = AV_PIX_FMT_PAL8; ff_set_dimensions(avctx, 318, 198); return 0; }


static av_cold int raw_encode_close(AVCodecContext *avctx) { av_frame_free(&avctx->coded_frame); return 0; }


int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) { DynBuffer *d; int size; static const char padbuf[AV_INPUT_BUFFER_PADDING_SIZE] = {0}; int padding = 0; if (!s) { *pbuffer = NULL; return 0; } /* don't attempt to pad fixed-size packet buffers */ if (!s->max_packet_size) { avio_write(s, padbuf, sizeof(padbuf)); padding = AV_INPUT_BUFFER_PADDING_SIZE; } avio_flush(s); d = s->opaque; *pbuffer = d->buffer; size = d->size; av_free(d); av_free(s); return size - padding; }


void pcie_port_init_reg(PCIDevice *d) { /* Unlike pci bridge, 66MHz and fast back to back don't apply to pci express port. */ pci_set_word(d->config + PCI_STATUS, 0); pci_set_word(d->config + PCI_SEC_STATUS, 0); /* Unlike conventional pci bridge, some bits are hardwired to 0. */ #define PCI_BRIDGE_CTL_VGA_16BIT 0x10 /* VGA 16-bit decode */ pci_set_word(d->wmask + PCI_BRIDGE_CONTROL, PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_ISA | PCI_BRIDGE_CTL_VGA | PCI_BRIDGE_CTL_VGA_16BIT | /* Req, but no alias support yet */ PCI_BRIDGE_CTL_SERR | PCI_BRIDGE_CTL_BUS_RESET); }


static void get_slice_data(ProresContext *ctx, const uint16_t *src, int linesize, int x, int y, int w, int h, DCTELEM *blocks, uint16_t *emu_buf, int mbs_per_slice, int blocks_per_mb, int is_chroma) { const uint16_t *esrc; const int mb_width = 4 * blocks_per_mb; int elinesize; int i, j, k; for (i = 0; i < mbs_per_slice; i++, src += mb_width) { if (x >= w) { memset(blocks, 0, 64 * (mbs_per_slice - i) * blocks_per_mb * sizeof(*blocks)); return; } if (x + mb_width <= w && y + 16 <= h) { esrc = src; elinesize = linesize; } else { int bw, bh, pix; esrc = emu_buf; elinesize = 16 * sizeof(*emu_buf); bw = FFMIN(w - x, mb_width); bh = FFMIN(h - y, 16); for (j = 0; j < bh; j++) { memcpy(emu_buf + j * 16, (const uint8_t*)src + j * linesize, bw * sizeof(*src)); pix = emu_buf[j * 16 + bw - 1]; for (k = bw; k < mb_width; k++) emu_buf[j * 16 + k] = pix; } for (; j < 16; j++) memcpy(emu_buf + j * 16, emu_buf + (bh - 1) * 16, mb_width * sizeof(*emu_buf)); } if (!is_chroma) { ctx->dsp.fdct(esrc, elinesize, blocks); blocks += 64; if (blocks_per_mb > 2) { ctx->dsp.fdct(src + 8, linesize, blocks); blocks += 64; } ctx->dsp.fdct(src + linesize * 4, linesize, blocks); blocks += 64; if (blocks_per_mb > 2) { ctx->dsp.fdct(src + linesize * 4 + 8, linesize, blocks); blocks += 64; } } else { ctx->dsp.fdct(esrc, elinesize, blocks); blocks += 64; ctx->dsp.fdct(src + linesize * 4, linesize, blocks); blocks += 64; if (blocks_per_mb > 2) { ctx->dsp.fdct(src + 8, linesize, blocks); blocks += 64; ctx->dsp.fdct(src + linesize * 4 + 8, linesize, blocks); blocks += 64; } } x += mb_width; } }


static always_inline void gen_farith3 (void *helper, int ra, int rb, int rc) { if (unlikely(rc == 31)) return; if (ra != 31) { if (rb != 31) tcg_gen_helper_1_2(helper, cpu_fir[rc], cpu_fir[ra], cpu_fir[rb]); else { TCGv tmp = tcg_const_i64(0); tcg_gen_helper_1_2(helper, cpu_fir[rc], cpu_fir[ra], tmp); tcg_temp_free(tmp); } } else { TCGv tmp = tcg_const_i64(0); if (rb != 31) tcg_gen_helper_1_2(helper, cpu_fir[rc], tmp, cpu_fir[rb]); else tcg_gen_helper_1_2(helper, cpu_fir[rc], tmp, tmp); tcg_temp_free(tmp); } }


static bool vfio_prereg_listener_skipped_section(MemoryRegionSection *section) { if (memory_region_is_iommu(section->mr)) { hw_error("Cannot possibly preregister IOMMU memory"); } return !memory_region_is_ram(section->mr) || memory_region_is_skip_dump(section->mr); }


static void gen_mtc0 (DisasContext *ctx, int reg, int sel) { const char *rn = "invalid"; switch (reg) { case 0: switch (sel) { case 0: gen_op_mtc0_index(); rn = "Index"; break; case 1: // gen_op_mtc0_mvpcontrol(); /* MT ASE */ rn = "MVPControl"; // break; case 2: // gen_op_mtc0_mvpconf0(); /* MT ASE */ rn = "MVPConf0"; // break; case 3: // gen_op_mtc0_mvpconf1(); /* MT ASE */ rn = "MVPConf1"; // break; default: goto die; } break; case 1: switch (sel) { case 0: /* ignored */ rn = "Random"; break; case 1: // gen_op_mtc0_vpecontrol(); /* MT ASE */ rn = "VPEControl"; // break; case 2: // gen_op_mtc0_vpeconf0(); /* MT ASE */ rn = "VPEConf0"; // break; case 3: // gen_op_mtc0_vpeconf1(); /* MT ASE */ rn = "VPEConf1"; // break; case 4: // gen_op_mtc0_YQMask(); /* MT ASE */ rn = "YQMask"; // break; case 5: // gen_op_mtc0_vpeschedule(); /* MT ASE */ rn = "VPESchedule"; // break; case 6: // gen_op_mtc0_vpeschefback(); /* MT ASE */ rn = "VPEScheFBack"; // break; case 7: // gen_op_mtc0_vpeopt(); /* MT ASE */ rn = "VPEOpt"; // break; default: goto die; } break; case 2: switch (sel) { case 0: gen_op_mtc0_entrylo0(); rn = "EntryLo0"; break; case 1: // gen_op_mtc0_tcstatus(); /* MT ASE */ rn = "TCStatus"; // break; case 2: // gen_op_mtc0_tcbind(); /* MT ASE */ rn = "TCBind"; // break; case 3: // gen_op_mtc0_tcrestart(); /* MT ASE */ rn = "TCRestart"; // break; case 4: // gen_op_mtc0_tchalt(); /* MT ASE */ rn = "TCHalt"; // break; case 5: // gen_op_mtc0_tccontext(); /* MT ASE */ rn = "TCContext"; // break; case 6: // gen_op_mtc0_tcschedule(); /* MT ASE */ rn = "TCSchedule"; // break; case 7: // gen_op_mtc0_tcschefback(); /* MT ASE */ rn = "TCScheFBack"; // break; default: goto die; } break; case 3: switch (sel) { case 0: gen_op_mtc0_entrylo1(); rn = "EntryLo1"; break; default: goto die; } break; case 4: switch (sel) { case 0: gen_op_mtc0_context(); rn = "Context"; break; case 1: // gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */ rn = "ContextConfig"; // break; default: goto die; } break; case 5: switch (sel) { case 0: gen_op_mtc0_pagemask(); rn = "PageMask"; break; case 1: gen_op_mtc0_pagegrain(); rn = "PageGrain"; break; default: goto die; } break; case 6: switch (sel) { case 0: gen_op_mtc0_wired(); rn = "Wired"; break; case 1: // gen_op_mtc0_srsconf0(); /* shadow registers */ rn = "SRSConf0"; // break; case 2: // gen_op_mtc0_srsconf1(); /* shadow registers */ rn = "SRSConf1"; // break; case 3: // gen_op_mtc0_srsconf2(); /* shadow registers */ rn = "SRSConf2"; // break; case 4: // gen_op_mtc0_srsconf3(); /* shadow registers */ rn = "SRSConf3"; // break; case 5: // gen_op_mtc0_srsconf4(); /* shadow registers */ rn = "SRSConf4"; // break; default: goto die; } break; case 7: switch (sel) { case 0: gen_op_mtc0_hwrena(); rn = "HWREna"; break; default: goto die; } break; case 8: /* ignored */ rn = "BadVaddr"; break; case 9: switch (sel) { case 0: gen_op_mtc0_count(); rn = "Count"; break; /* 6,7 are implementation dependent */ default: goto die; } /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case 10: switch (sel) { case 0: gen_op_mtc0_entryhi(); rn = "EntryHi"; break; default: goto die; } break; case 11: switch (sel) { case 0: gen_op_mtc0_compare(); rn = "Compare"; break; /* 6,7 are implementation dependent */ default: goto die; } /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case 12: switch (sel) { case 0: gen_op_mtc0_status(); /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Status"; break; case 1: gen_op_mtc0_intctl(); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "IntCtl"; break; case 2: gen_op_mtc0_srsctl(); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSCtl"; break; case 3: gen_op_mtc0_srsmap(); /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "SRSMap"; break; default: goto die; } break; case 13: switch (sel) { case 0: gen_op_mtc0_cause(); rn = "Cause"; break; default: goto die; } /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case 14: switch (sel) { case 0: gen_op_mtc0_epc(); rn = "EPC"; break; default: goto die; } break; case 15: switch (sel) { case 0: /* ignored */ rn = "PRid"; break; case 1: gen_op_mtc0_ebase(); rn = "EBase"; break; default: goto die; } break; case 16: switch (sel) { case 0: gen_op_mtc0_config0(); rn = "Config"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case 1: /* ignored, read only */ rn = "Config1"; break; case 2: gen_op_mtc0_config2(); rn = "Config2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; case 3: /* ignored, read only */ rn = "Config3"; break; /* 4,5 are reserved */ /* 6,7 are implementation dependent */ case 6: /* ignored */ rn = "Config6"; break; case 7: /* ignored */ rn = "Config7"; break; default: rn = "Invalid config selector"; goto die; } break; case 17: switch (sel) { case 0: /* ignored */ rn = "LLAddr"; break; default: goto die; } break; case 18: switch (sel) { case 0 ... 7: gen_op_mtc0_watchlo(sel); rn = "WatchLo"; break; default: goto die; } break; case 19: switch (sel) { case 0 ... 7: gen_op_mtc0_watchhi(sel); rn = "WatchHi"; break; default: goto die; } break; case 20: switch (sel) { case 0: #ifdef TARGET_MIPS64 gen_op_mtc0_xcontext(); rn = "XContext"; break; #endif default: goto die; } break; case 21: /* Officially reserved, but sel 0 is used for R1x000 framemask */ switch (sel) { case 0: gen_op_mtc0_framemask(); rn = "Framemask"; break; default: goto die; } break; case 22: /* ignored */ rn = "Diagnostic"; /* implementation dependent */ break; case 23: switch (sel) { case 0: gen_op_mtc0_debug(); /* EJTAG support */ /* BS_STOP isn't good enough here, hflags may have changed. */ gen_save_pc(ctx->pc + 4); ctx->bstate = BS_EXCP; rn = "Debug"; break; case 1: // gen_op_mtc0_tracecontrol(); /* PDtrace support */ rn = "TraceControl"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 2: // gen_op_mtc0_tracecontrol2(); /* PDtrace support */ rn = "TraceControl2"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 3: /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // gen_op_mtc0_usertracedata(); /* PDtrace support */ rn = "UserTraceData"; /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; // break; case 4: // gen_op_mtc0_debug(); /* PDtrace support */ /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; rn = "TraceBPC"; // break; default: goto die; } break; case 24: switch (sel) { case 0: gen_op_mtc0_depc(); /* EJTAG support */ rn = "DEPC"; break; default: goto die; } break; case 25: switch (sel) { case 0: gen_op_mtc0_performance0(); rn = "Performance0"; break; case 1: // gen_op_mtc0_performance1(); rn = "Performance1"; // break; case 2: // gen_op_mtc0_performance2(); rn = "Performance2"; // break; case 3: // gen_op_mtc0_performance3(); rn = "Performance3"; // break; case 4: // gen_op_mtc0_performance4(); rn = "Performance4"; // break; case 5: // gen_op_mtc0_performance5(); rn = "Performance5"; // break; case 6: // gen_op_mtc0_performance6(); rn = "Performance6"; // break; case 7: // gen_op_mtc0_performance7(); rn = "Performance7"; // break; default: goto die; } break; case 26: /* ignored */ rn = "ECC"; break; case 27: switch (sel) { case 0 ... 3: /* ignored */ rn = "CacheErr"; break; default: goto die; } break; case 28: switch (sel) { case 0: case 2: case 4: case 6: gen_op_mtc0_taglo(); rn = "TagLo"; break; case 1: case 3: case 5: case 7: gen_op_mtc0_datalo(); rn = "DataLo"; break; default: goto die; } break; case 29: switch (sel) { case 0: case 2: case 4: case 6: gen_op_mtc0_taghi(); rn = "TagHi"; break; case 1: case 3: case 5: case 7: gen_op_mtc0_datahi(); rn = "DataHi"; break; default: rn = "invalid sel"; goto die; } break; case 30: switch (sel) { case 0: gen_op_mtc0_errorepc(); rn = "ErrorEPC"; break; default: goto die; } break; case 31: switch (sel) { case 0: gen_op_mtc0_desave(); /* EJTAG support */ rn = "DESAVE"; break; default: goto die; } /* Stop translation as we may have switched the execution mode */ ctx->bstate = BS_STOP; break; default: goto die; } #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel); } #endif return; die: #if defined MIPS_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel); } #endif generate_exception(ctx, EXCP_RI); }


static void test_native_list_integer_helper(TestInputVisitorData *data, const void *unused, UserDefNativeListUnionKind kind) { UserDefNativeListUnion *cvalue = NULL; Visitor *v; GString *gstr_list = g_string_new(""); GString *gstr_union = g_string_new(""); int i; for (i = 0; i < 32; i++) { g_string_append_printf(gstr_list, "%d", i); if (i != 31) { g_string_append(gstr_list, ", "); } } g_string_append_printf(gstr_union, "{ 'type': '%s', 'data': [ %s ] }", UserDefNativeListUnionKind_lookup[kind], gstr_list->str); v = visitor_input_test_init_raw(data, gstr_union->str); visit_type_UserDefNativeListUnion(v, NULL, &cvalue, &error_abort); g_assert(cvalue != NULL); g_assert_cmpint(cvalue->type, ==, kind); switch (kind) { case USER_DEF_NATIVE_LIST_UNION_KIND_INTEGER: { intList *elem = NULL; for (i = 0, elem = cvalue->u.integer.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_S8: { int8List *elem = NULL; for (i = 0, elem = cvalue->u.s8.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_S16: { int16List *elem = NULL; for (i = 0, elem = cvalue->u.s16.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_S32: { int32List *elem = NULL; for (i = 0, elem = cvalue->u.s32.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_S64: { int64List *elem = NULL; for (i = 0, elem = cvalue->u.s64.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_U8: { uint8List *elem = NULL; for (i = 0, elem = cvalue->u.u8.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_U16: { uint16List *elem = NULL; for (i = 0, elem = cvalue->u.u16.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_U32: { uint32List *elem = NULL; for (i = 0, elem = cvalue->u.u32.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } case USER_DEF_NATIVE_LIST_UNION_KIND_U64: { uint64List *elem = NULL; for (i = 0, elem = cvalue->u.u64.data; elem; elem = elem->next, i++) { g_assert_cmpint(elem->value, ==, i); } break; } default: g_assert_not_reached(); } g_string_free(gstr_union, true); g_string_free(gstr_list, true); qapi_free_UserDefNativeListUnion(cvalue); }


pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri) { int i; uint32_t txr_len_log2, rxr_len_log2; uint32_t req_ring_size, cmp_ring_size; m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT; if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) || (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) { return -1; } req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE; cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE; txr_len_log2 = pvscsi_log2(req_ring_size - 1); rxr_len_log2 = pvscsi_log2(cmp_ring_size - 1); m->txr_len_mask = MASK(txr_len_log2); m->rxr_len_mask = MASK(rxr_len_log2); m->consumed_ptr = 0; m->filled_cmp_ptr = 0; for (i = 0; i < ri->reqRingNumPages; i++) { m->req_ring_pages_pa[i] = ri->reqRingPPNs[i] << VMW_PAGE_SHIFT; } for (i = 0; i < ri->cmpRingNumPages; i++) { m->cmp_ring_pages_pa[i] = ri->cmpRingPPNs[i] << VMW_PAGE_SHIFT; } RS_SET_FIELD(m, reqProdIdx, 0); RS_SET_FIELD(m, reqConsIdx, 0); RS_SET_FIELD(m, reqNumEntriesLog2, txr_len_log2); RS_SET_FIELD(m, cmpProdIdx, 0); RS_SET_FIELD(m, cmpConsIdx, 0); RS_SET_FIELD(m, cmpNumEntriesLog2, rxr_len_log2); trace_pvscsi_ring_init_data(txr_len_log2, rxr_len_log2); /* Flush ring state page changes */ smp_wmb(); return 0; }


static bool check_overlapping_aiocb(BDRVSheepdogState *s, SheepdogAIOCB *aiocb) { SheepdogAIOCB *cb; QLIST_FOREACH(cb, &s->inflight_aiocb_head, aiocb_siblings) { if (AIOCBOverlapping(aiocb, cb)) { return true; } } QLIST_INSERT_HEAD(&s->inflight_aiocb_head, aiocb, aiocb_siblings); return false; }


static void qio_channel_websock_finalize(Object *obj) { QIOChannelWebsock *ioc = QIO_CHANNEL_WEBSOCK(obj); buffer_free(&ioc->encinput); buffer_free(&ioc->encoutput); buffer_free(&ioc->rawinput); buffer_free(&ioc->rawoutput); object_unref(OBJECT(ioc->master)); if (ioc->io_tag) { g_source_remove(ioc->io_tag); } if (ioc->io_err) { error_free(ioc->io_err); } }


static av_cold int vaapi_encode_h265_init_internal(AVCodecContext *avctx) { static const VAConfigAttrib default_config_attributes[] = { { .type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420 }, { .type = VAConfigAttribEncPackedHeaders, .value = (VA_ENC_PACKED_HEADER_SEQUENCE | VA_ENC_PACKED_HEADER_SLICE) }, }; VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeH265Context *priv = ctx->priv_data; int i, err; switch (avctx->profile) { case FF_PROFILE_HEVC_MAIN: case FF_PROFILE_UNKNOWN: ctx->va_profile = VAProfileHEVCMain; break; case FF_PROFILE_HEVC_MAIN_10: av_log(avctx, AV_LOG_ERROR, "H.265 main 10-bit profile " "is not supported.\n"); return AVERROR_PATCHWELCOME; default: av_log(avctx, AV_LOG_ERROR, "Unknown H.265 profile %d.\n", avctx->profile); return AVERROR(EINVAL); } ctx->va_entrypoint = VAEntrypointEncSlice; ctx->input_width = avctx->width; ctx->input_height = avctx->height; ctx->aligned_width = FFALIGN(ctx->input_width, 16); ctx->aligned_height = FFALIGN(ctx->input_height, 16); priv->ctu_width = FFALIGN(ctx->aligned_width, 32) / 32; priv->ctu_height = FFALIGN(ctx->aligned_height, 32) / 32; av_log(avctx, AV_LOG_VERBOSE, "Input %ux%u -> Aligned %ux%u -> CTU %ux%u.\n", ctx->input_width, ctx->input_height, ctx->aligned_width, ctx->aligned_height, priv->ctu_width, priv->ctu_height); for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { ctx->config_attributes[ctx->nb_config_attributes++] = default_config_attributes[i]; } if (avctx->bit_rate > 0) { ctx->va_rc_mode = VA_RC_CBR; err = vaapi_encode_h265_init_constant_bitrate(avctx); } else { ctx->va_rc_mode = VA_RC_CQP; err = vaapi_encode_h265_init_fixed_qp(avctx); } if (err < 0) return err; ctx->config_attributes[ctx->nb_config_attributes++] = (VAConfigAttrib) { .type = VAConfigAttribRateControl, .value = ctx->va_rc_mode, }; ctx->nb_recon_frames = 20; return 0; }


void qmp_migrate_set_downtime(double value, Error **errp) { value *= 1e9; value = MAX(0, MIN(UINT64_MAX, value)); max_downtime = (uint64_t)value; }


static void qemu_cpu_kick_thread(CPUState *env) { #ifndef _WIN32 int err; err = pthread_kill(env->thread->thread, SIG_IPI); if (err) { fprintf(stderr, "qemu:%s: %s", __func__, strerror(err)); exit(1); } #else /* _WIN32 */ if (!qemu_cpu_is_self(env)) { SuspendThread(env->thread->thread); cpu_signal(0); ResumeThread(env->thread->thread); } #endif }


void helper_evaluate_flags_alu_4(void) { uint32_t src; uint32_t dst; uint32_t res; uint32_t flags = 0; src = env->cc_src; dst = env->cc_dest; /* Reconstruct the result. */ switch (env->cc_op) { case CC_OP_SUB: res = dst - src; break; case CC_OP_ADD: res = dst + src; break; default: res = env->cc_result; break; } if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP) src = ~src; if ((res & 0x80000000L) != 0L) { flags |= N_FLAG; if (((src & 0x80000000L) == 0L) && ((dst & 0x80000000L) == 0L)) { flags |= V_FLAG; } else if (((src & 0x80000000L) != 0L) && ((dst & 0x80000000L) != 0L)) { flags |= C_FLAG; } } else { if (res == 0L) flags |= Z_FLAG; if (((src & 0x80000000L) != 0L) && ((dst & 0x80000000L) != 0L)) flags |= V_FLAG; if ((dst & 0x80000000L) != 0L || (src & 0x80000000L) != 0L) flags |= C_FLAG; } if (env->cc_op == CC_OP_SUB || env->cc_op == CC_OP_CMP) { flags ^= C_FLAG; } evaluate_flags_writeback(flags); }


static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) { DBDMA_io *io = opaque; MACIOIDEState *m = io->opaque; IDEState *s = idebus_active_if(&m->bus); int unaligned; if (ret < 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); ide_atapi_io_error(s, ret); io->remainder_len = 0; goto done; } if (!m->dma_active) { MACIO_DPRINTF("waiting for data (%#x - %#x - %x)\n", s->nsector, io->len, s->status); /* data not ready yet, wait for the channel to get restarted */ io->processing = false; return; } MACIO_DPRINTF("io_buffer_size = %#x\n", s->io_buffer_size); if (s->io_buffer_size > 0) { m->aiocb = NULL; qemu_sglist_destroy(&s->sg); s->packet_transfer_size -= s->io_buffer_size; s->io_buffer_index += s->io_buffer_size; s->lba += s->io_buffer_index >> 11; s->io_buffer_index &= 0x7ff; } s->io_buffer_size = MIN(io->len, s->packet_transfer_size); MACIO_DPRINTF("remainder: %d io->len: %d size: %d\n", io->remainder_len, io->len, s->packet_transfer_size); if (io->remainder_len && io->len) { /* guest wants the rest of its previous transfer */ int remainder_len = MIN(io->remainder_len, io->len); MACIO_DPRINTF("copying remainder %d bytes\n", remainder_len); cpu_physical_memory_write(io->addr, io->remainder + 0x200 - remainder_len, remainder_len); io->addr += remainder_len; io->len -= remainder_len; s->io_buffer_size = remainder_len; io->remainder_len -= remainder_len; /* treat remainder as individual transfer, start again */ qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, &address_space_memory); pmac_ide_atapi_transfer_cb(opaque, 0); return; } if (!s->packet_transfer_size) { MACIO_DPRINTF("end of transfer\n"); ide_atapi_cmd_ok(s); m->dma_active = false; } if (io->len == 0) { MACIO_DPRINTF("end of DMA\n"); goto done; } /* launch next transfer */ /* handle unaligned accesses first, get them over with and only do the remaining bulk transfer using our async DMA helpers */ unaligned = io->len & 0x1ff; if (unaligned) { int sector_num = (s->lba << 2) + (s->io_buffer_index >> 9); int nsector = io->len >> 9; MACIO_DPRINTF("precopying unaligned %d bytes to %#" HWADDR_PRIx "\n", unaligned, io->addr + io->len - unaligned); bdrv_read(s->bs, sector_num + nsector, io->remainder, 1); cpu_physical_memory_write(io->addr + io->len - unaligned, io->remainder, unaligned); io->len -= unaligned; } MACIO_DPRINTF("io->len = %#x\n", io->len); qemu_sglist_init(&s->sg, DEVICE(m), io->len / MACIO_PAGE_SIZE + 1, &address_space_memory); qemu_sglist_add(&s->sg, io->addr, io->len); io->addr += s->io_buffer_size; io->remainder_len = MIN(s->packet_transfer_size - s->io_buffer_size, (0x200 - unaligned) & 0x1ff); MACIO_DPRINTF("set remainder to: %d\n", io->remainder_len); /* We would read no data from the block layer, thus not get a callback. Just fake completion manually. */ if (!io->len) { pmac_ide_atapi_transfer_cb(opaque, 0); return; } io->len = 0; MACIO_DPRINTF("sector_num=%d size=%d, cmd_cmd=%d\n", (s->lba << 2) + (s->io_buffer_index >> 9), s->packet_transfer_size, s->dma_cmd); m->aiocb = dma_bdrv_read(s->bs, &s->sg, (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), pmac_ide_atapi_transfer_cb, io); return; done: MACIO_DPRINTF("done DMA\n"); block_acct_done(bdrv_get_stats(s->bs), &s->acct); io->dma_end(opaque); }


static void pit_reset(void *opaque) { PITState *pit = opaque; PITChannelState *s; int i; for(i = 0;i < 3; i++) { s = &pit->channels[i]; s->mode = 3; s->gate = (i != 2); pit_load_count(s, 0); } }


static void vmsvga_init(struct vmsvga_state_s *s, MemoryRegion *address_space, MemoryRegion *io) { s->scratch_size = SVGA_SCRATCH_SIZE; s->scratch = g_malloc(s->scratch_size * 4); s->vga.con = graphic_console_init(vmsvga_update_display, vmsvga_invalidate_display, vmsvga_screen_dump, vmsvga_text_update, s); s->fifo_size = SVGA_FIFO_SIZE; memory_region_init_ram(&s->fifo_ram, "vmsvga.fifo", s->fifo_size); vmstate_register_ram_global(&s->fifo_ram); s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); vga_common_init(&s->vga); vga_init(&s->vga, address_space, io, true); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); s->new_depth = 32; }


static int local_set_mapped_file_attr(FsContext *ctx, const char *path, FsCred *credp) { FILE *fp; int ret = 0; char buf[ATTR_MAX]; char attr_path[PATH_MAX]; int uid = -1, gid = -1, mode = -1, rdev = -1; fp = local_fopen(local_mapped_attr_path(ctx, path, attr_path), "r"); if (!fp) { goto create_map_file; } memset(buf, 0, ATTR_MAX); while (fgets(buf, ATTR_MAX, fp)) { if (!strncmp(buf, "virtfs.uid", 10)) { uid = atoi(buf+11); } else if (!strncmp(buf, "virtfs.gid", 10)) { gid = atoi(buf+11); } else if (!strncmp(buf, "virtfs.mode", 11)) { mode = atoi(buf+12); } else if (!strncmp(buf, "virtfs.rdev", 11)) { rdev = atoi(buf+12); } memset(buf, 0, ATTR_MAX); } fclose(fp); goto update_map_file; create_map_file: ret = local_create_mapped_attr_dir(ctx, path); if (ret < 0) { goto err_out; } update_map_file: fp = local_fopen(attr_path, "w"); if (!fp) { ret = -1; goto err_out; } if (credp->fc_uid != -1) { uid = credp->fc_uid; } if (credp->fc_gid != -1) { gid = credp->fc_gid; } if (credp->fc_mode != -1) { mode = credp->fc_mode; } if (credp->fc_rdev != -1) { rdev = credp->fc_rdev; } if (uid != -1) { fprintf(fp, "virtfs.uid=%d\n", uid); } if (gid != -1) { fprintf(fp, "virtfs.gid=%d\n", gid); } if (mode != -1) { fprintf(fp, "virtfs.mode=%d\n", mode); } if (rdev != -1) { fprintf(fp, "virtfs.rdev=%d\n", rdev); } fclose(fp); err_out: return ret; }


static int64_t qemu_next_alarm_deadline(void) { int64_t delta; int64_t rtdelta; if (!use_icount && vm_clock->active_timers) { delta = vm_clock->active_timers->expire_time - qemu_get_clock_ns(vm_clock); } else { delta = INT32_MAX; } if (host_clock->active_timers) { int64_t hdelta = host_clock->active_timers->expire_time - qemu_get_clock_ns(host_clock); if (hdelta < delta) { delta = hdelta; } } if (rt_clock->active_timers) { rtdelta = (rt_clock->active_timers->expire_time - qemu_get_clock_ns(rt_clock)); if (rtdelta < delta) { delta = rtdelta; } } return delta; }


static int decode_motion_vector (bit_buffer_t *bitbuf, svq1_pmv_t *mv, svq1_pmv_t **pmv) { uint32_t bit_cache; vlc_code_t *vlc; int diff, sign; int i; for (i=0; i < 2; i++) { /* get motion code */ bit_cache = get_bit_cache (bitbuf); if (!(bit_cache & 0xFFE00000)) return -1; /* invalid vlc code */ if (bit_cache & 0x80000000) { diff = 0; /* flush bit */ skip_bits(bitbuf,1); } else { if (bit_cache >= 0x06000000) { vlc = &motion_table_0[(bit_cache >> (32 - 7)) - 3]; } else { vlc = &motion_table_1[(bit_cache >> (32 - 12)) - 2]; } /* decode motion vector differential */ sign = (int) (bit_cache << (vlc->length - 1)) >> 31; diff = (vlc->value ^ sign) - sign; /* flush bits */ skip_bits(bitbuf,vlc->length); } /* add median of motion vector predictors and clip result */ if (i == 1) mv->y = ((diff + MEDIAN(pmv[0]->y, pmv[1]->y, pmv[2]->y)) << 26) >> 26; else mv->x = ((diff + MEDIAN(pmv[0]->x, pmv[1]->x, pmv[2]->x)) << 26) >> 26; } return 0; }


static void drive_backup_prepare(BlkActionState *common, Error **errp) { DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common); BlockBackend *blk; DriveBackup *backup; Error *local_err = NULL; assert(common->action->type == TRANSACTION_ACTION_KIND_DRIVE_BACKUP); backup = common->action->u.drive_backup.data; blk = blk_by_name(backup->device); if (!blk) { error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND, "Device '%s' not found", backup->device); return; } if (!blk_is_available(blk)) { error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, backup->device); return; } /* AioContext is released in .clean() */ state->aio_context = blk_get_aio_context(blk); aio_context_acquire(state->aio_context); bdrv_drained_begin(blk_bs(blk)); state->bs = blk_bs(blk); do_drive_backup(backup->has_job_id ? backup->job_id : NULL, backup->device, backup->target, backup->has_format, backup->format, backup->sync, backup->has_mode, backup->mode, backup->has_speed, backup->speed, backup->has_bitmap, backup->bitmap, backup->has_on_source_error, backup->on_source_error, backup->has_on_target_error, backup->on_target_error, common->block_job_txn, &local_err); if (local_err) { error_propagate(errp, local_err); return; } state->job = state->bs->job; }


void ssi_register_slave(SSISlaveInfo *info) { assert(info->qdev.size >= sizeof(SSISlave)); info->qdev.init = ssi_slave_init; info->qdev.bus_type = BUS_TYPE_SSI; qdev_register(&info->qdev); }


uint64_t bdrv_dirty_bitmap_serialization_align(const BdrvDirtyBitmap *bitmap) { return hbitmap_serialization_align(bitmap->bitmap); }


static void parse_drive(DeviceState *dev, const char *str, void **ptr, const char *propname, Error **errp) { BlockBackend *blk; blk = blk_by_name(str); if (!blk) { error_setg(errp, "Property '%s.%s' can't find value '%s'", object_get_typename(OBJECT(dev)), propname, str); return; } if (blk_attach_dev(blk, dev) < 0) { DriveInfo *dinfo = blk_legacy_dinfo(blk); if (dinfo->type != IF_NONE) { error_setg(errp, "Drive '%s' is already in use because " "it has been automatically connected to another " "device (did you need 'if=none' in the drive options?)", str); } else { error_setg(errp, "Drive '%s' is already in use by another device", str); } return; } *ptr = blk; }


static int get_segment (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw, int type) { target_phys_addr_t sdr, hash, mask, sdr_mask, htab_mask; target_ulong sr, vsid, vsid_mask, pgidx, page_mask; #if defined(TARGET_PPC64) int attr; #endif int ds, nx, vsid_sh, sdr_sh; int ret, ret2; #if defined(TARGET_PPC64) if (env->mmu_model == POWERPC_MMU_64B) { #if defined (DEBUG_MMU) if (loglevel != 0) { fprintf(logfile, "Check SLBs\n"); } #endif ret = slb_lookup(env, eaddr, &vsid, &page_mask, &attr); if (ret < 0) return ret; ctx->key = ((attr & 0x40) && msr_pr == 1) || ((attr & 0x80) && msr_pr == 0) ? 1 : 0; ds = 0; nx = attr & 0x20 ? 1 : 0; vsid_mask = 0x00003FFFFFFFFF80ULL; vsid_sh = 7; sdr_sh = 18; sdr_mask = 0x3FF80; } else #endif /* defined(TARGET_PPC64) */ { sr = env->sr[eaddr >> 28]; page_mask = 0x0FFFFFFF; ctx->key = (((sr & 0x20000000) && msr_pr == 1) || ((sr & 0x40000000) && msr_pr == 0)) ? 1 : 0; ds = sr & 0x80000000 ? 1 : 0; nx = sr & 0x10000000 ? 1 : 0; vsid = sr & 0x00FFFFFF; vsid_mask = 0x01FFFFC0; vsid_sh = 6; sdr_sh = 16; sdr_mask = 0xFFC0; #if defined (DEBUG_MMU) if (loglevel != 0) { fprintf(logfile, "Check segment v=0x" ADDRX " %d 0x" ADDRX " nip=0x" ADDRX " lr=0x" ADDRX " ir=%d dr=%d pr=%d %d t=%d\n", eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, msr_ir, msr_dr, msr_pr, rw, type); } #endif } #if defined (DEBUG_MMU) if (loglevel != 0) { fprintf(logfile, "pte segment: key=%d ds %d nx %d vsid " ADDRX "\n", ctx->key, ds, nx, vsid); } #endif ret = -1; if (!ds) { /* Check if instruction fetch is allowed, if needed */ if (type != ACCESS_CODE || nx == 0) { /* Page address translation */ /* Primary table address */ sdr = env->sdr1; pgidx = (eaddr & page_mask) >> TARGET_PAGE_BITS; #if defined(TARGET_PPC64) if (env->mmu_model == POWERPC_MMU_64B) { htab_mask = 0x0FFFFFFF >> (28 - (sdr & 0x1F)); /* XXX: this is false for 1 TB segments */ hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; } else #endif { htab_mask = sdr & 0x000001FF; hash = ((vsid ^ pgidx) << vsid_sh) & vsid_mask; } mask = (htab_mask << sdr_sh) | sdr_mask; #if defined (DEBUG_MMU) if (loglevel != 0) { fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX " mask " PADDRX " " ADDRX "\n", sdr, sdr_sh, hash, mask, page_mask); } #endif ctx->pg_addr[0] = get_pgaddr(sdr, sdr_sh, hash, mask); /* Secondary table address */ hash = (~hash) & vsid_mask; #if defined (DEBUG_MMU) if (loglevel != 0) { fprintf(logfile, "sdr " PADDRX " sh %d hash " PADDRX " mask " PADDRX "\n", sdr, sdr_sh, hash, mask); } #endif ctx->pg_addr[1] = get_pgaddr(sdr, sdr_sh, hash, mask); #if defined(TARGET_PPC64) if (env->mmu_model == POWERPC_MMU_64B) { /* Only 5 bits of the page index are used in the AVPN */ ctx->ptem = (vsid << 12) | ((pgidx >> 4) & 0x0F80); } else #endif { ctx->ptem = (vsid << 7) | (pgidx >> 10); } /* Initialize real address with an invalid value */ ctx->raddr = (target_ulong)-1; if (unlikely(env->mmu_model == POWERPC_MMU_SOFT_6xx || env->mmu_model == POWERPC_MMU_SOFT_74xx)) { /* Software TLB search */ ret = ppc6xx_tlb_check(env, ctx, eaddr, rw, type); } else { #if defined (DEBUG_MMU) if (loglevel != 0) { fprintf(logfile, "0 sdr1=0x" PADDRX " vsid=0x%06x " "api=0x%04x hash=0x%07x pg_addr=0x" PADDRX "\n", sdr, (uint32_t)vsid, (uint32_t)pgidx, (uint32_t)hash, ctx->pg_addr[0]); } #endif /* Primary table lookup */ ret = find_pte(env, ctx, 0, rw); if (ret < 0) { /* Secondary table lookup */ #if defined (DEBUG_MMU) if (eaddr != 0xEFFFFFFF && loglevel != 0) { fprintf(logfile, "1 sdr1=0x" PADDRX " vsid=0x%06x api=0x%04x " "hash=0x%05x pg_addr=0x" PADDRX "\n", sdr, (uint32_t)vsid, (uint32_t)pgidx, (uint32_t)hash, ctx->pg_addr[1]); } #endif ret2 = find_pte(env, ctx, 1, rw); if (ret2 != -1) ret = ret2; } } #if defined (DEBUG_MMU) if (loglevel != 0) { target_phys_addr_t curaddr; uint32_t a0, a1, a2, a3; fprintf(logfile, "Page table: " PADDRX " len " PADDRX "\n", sdr, mask + 0x80); for (curaddr = sdr; curaddr < (sdr + mask + 0x80); curaddr += 16) { a0 = ldl_phys(curaddr); a1 = ldl_phys(curaddr + 4); a2 = ldl_phys(curaddr + 8); a3 = ldl_phys(curaddr + 12); if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { fprintf(logfile, PADDRX ": %08x %08x %08x %08x\n", curaddr, a0, a1, a2, a3); } } } #endif } else { #if defined (DEBUG_MMU) if (loglevel != 0) fprintf(logfile, "No access allowed\n"); #endif ret = -3; } } else { #if defined (DEBUG_MMU) if (loglevel != 0) fprintf(logfile, "direct store...\n"); #endif /* Direct-store segment : absolutely *BUGGY* for now */ switch (type) { case ACCESS_INT: /* Integer load/store : only access allowed */ break; case ACCESS_CODE: /* No code fetch is allowed in direct-store areas */ return -4; case ACCESS_FLOAT: /* Floating point load/store */ return -4; case ACCESS_RES: /* lwarx, ldarx or srwcx. */ return -4; case ACCESS_CACHE: /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */ /* Should make the instruction do no-op. * As it already do no-op, it's quite easy :-) */ ctx->raddr = eaddr; return 0; case ACCESS_EXT: /* eciwx or ecowx */ return -4; default: if (logfile) { fprintf(logfile, "ERROR: instruction should not need " "address translation\n"); } return -4; } if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) { ctx->raddr = eaddr; ret = 2; } else { ret = -2; } } return ret; }


static void arm_gic_realize(DeviceState *dev, Error **errp) { /* Device instance realize function for the GIC sysbus device */ GICv3State *s = ARM_GICV3(dev); ARMGICv3Class *agc = ARM_GICV3_GET_CLASS(s); Error *local_err = NULL; agc->parent_realize(dev, &local_err); if (local_err) { error_propagate(errp, local_err); return; } gicv3_init_irqs_and_mmio(s, gicv3_set_irq, NULL); }


static void build_append_notify_target(GArray *method, GArray *target_name, uint32_t value, int size) { GArray *notify = build_alloc_array(); uint8_t op = 0xA0; /* IfOp */ build_append_byte(notify, 0x93); /* LEqualOp */ build_append_byte(notify, 0x68); /* Arg0Op */ build_append_value(notify, value, size); build_append_byte(notify, 0x86); /* NotifyOp */ build_append_array(notify, target_name); build_append_byte(notify, 0x69); /* Arg1Op */ /* Pack it up */ build_package(notify, op, 1); build_append_array(method, notify); build_free_array(notify); }


static void contextidr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { ARMCPU *cpu = arm_env_get_cpu(env); if (env->cp15.contextidr_el1 != value && !arm_feature(env, ARM_FEATURE_MPU) && !extended_addresses_enabled(env)) { /* For VMSA (when not using the LPAE long descriptor page table * format) this register includes the ASID, so do a TLB flush. * For PMSA it is purely a process ID and no action is needed. */ tlb_flush(CPU(cpu), 1); } env->cp15.contextidr_el1 = value; }


static ram_addr_t qxl_rom_size(void) { uint32_t required_rom_size = sizeof(QXLRom) + sizeof(QXLModes) + sizeof(qxl_modes); uint32_t rom_size = 8192; /* two pages */ QEMU_BUILD_BUG_ON(required_rom_size > rom_size); return rom_size; }


static NetSocketState *net_socket_fd_init(NetClientState *peer, const char *model, const char *name, int fd, int is_connected) { int so_type = -1, optlen=sizeof(so_type); if(getsockopt(fd, SOL_SOCKET, SO_TYPE, (char *)&so_type, (socklen_t *)&optlen)< 0) { fprintf(stderr, "qemu: error: getsockopt(SO_TYPE) for fd=%d failed\n", fd); closesocket(fd); return NULL; } switch(so_type) { case SOCK_DGRAM: return net_socket_fd_init_dgram(peer, model, name, fd, is_connected); case SOCK_STREAM: return net_socket_fd_init_stream(peer, model, name, fd, is_connected); default: /* who knows ... this could be a eg. a pty, do warn and continue as stream */ fprintf(stderr, "qemu: warning: socket type=%d for fd=%d is not SOCK_DGRAM or SOCK_STREAM\n", so_type, fd); return net_socket_fd_init_stream(peer, model, name, fd, is_connected); } return NULL; }


static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix, uint16_t **refcount_table, int64_t *nb_clusters) { BDRVQcowState *s = bs->opaque; int64_t i; QCowSnapshot *sn; int ret; if (!*refcount_table) { *refcount_table = g_try_new0(uint16_t, *nb_clusters); if (*nb_clusters && *refcount_table == NULL) { res->check_errors++; return -ENOMEM; } } /* header */ ret = inc_refcounts(bs, res, refcount_table, nb_clusters, 0, s->cluster_size); if (ret < 0) { return ret; } /* current L1 table */ ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO); if (ret < 0) { return ret; } /* snapshots */ for (i = 0; i < s->nb_snapshots; i++) { sn = s->snapshots + i; ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters, sn->l1_table_offset, sn->l1_size, 0); if (ret < 0) { return ret; } } ret = inc_refcounts(bs, res, refcount_table, nb_clusters, s->snapshots_offset, s->snapshots_size); if (ret < 0) { return ret; } /* refcount data */ ret = inc_refcounts(bs, res, refcount_table, nb_clusters, s->refcount_table_offset, s->refcount_table_size * sizeof(uint64_t)); if (ret < 0) { return ret; } return check_refblocks(bs, res, fix, refcount_table, nb_clusters); }


long check_dcbzl_effect(void) { register char *fakedata = (char*)av_malloc(1024); register char *fakedata_middle; register long zero = 0; register long i = 0; long count = 0; if (!fakedata) { return 0L; } fakedata_middle = (fakedata + 512); memset(fakedata, 0xFF, 1024); /* below the constraint "b" seems to mean "Address base register" in gcc-3.3 / RS/6000 speaks. seems to avoid using r0, so.... */ asm volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero)); for (i = 0; i < 1024 ; i ++) { if (fakedata[i] == (char)0) count++; } av_free(fakedata); return count; }


static void vga_update_display(void *opaque) { VGACommonState *s = opaque; int full_update, graphic_mode; qemu_flush_coalesced_mmio_buffer(); if (ds_get_bits_per_pixel(s->ds) == 0) { /* nothing to do */ } else { full_update = 0; if (!(s->ar_index & 0x20)) { graphic_mode = GMODE_BLANK; } else { graphic_mode = s->gr[VGA_GFX_MISC] & VGA_GR06_GRAPHICS_MODE; } if (graphic_mode != s->graphic_mode) { s->graphic_mode = graphic_mode; s->cursor_blink_time = qemu_get_clock_ms(vm_clock); full_update = 1; } switch(graphic_mode) { case GMODE_TEXT: vga_draw_text(s, full_update); break; case GMODE_GRAPH: vga_draw_graphic(s, full_update); break; case GMODE_BLANK: default: vga_draw_blank(s, full_update); break; } } }


static inline void comp_block(MadContext *t, int mb_x, int mb_y, int j, int mv_x, int mv_y, int add) { MpegEncContext *s = &t->s; if (j < 4) { comp(t->frame.data[0] + (mb_y*16 + ((j&2)<<2))*t->frame.linesize[0] + mb_x*16 + ((j&1)<<3), t->frame.linesize[0], t->last_frame.data[0] + (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x, t->last_frame.linesize[0], add); } else if (!(s->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; comp(t->frame.data[index] + (mb_y*8)*t->frame.linesize[index] + mb_x * 8, t->frame.linesize[index], t->last_frame.data[index] + (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2), t->last_frame.linesize[index], add); } }


static inline int gen_intermediate_code_internal(CPUState *env, TranslationBlock *tb, int search_pc) { DisasContext dc1, *dc = &dc1; uint16_t *gen_opc_end; int j, lj; target_ulong pc_start; uint32_t next_page_start; /* generate intermediate code */ pc_start = tb->pc; dc->tb = tb; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; dc->singlestep_enabled = env->singlestep_enabled; dc->condjmp = 0; dc->thumb = env->thumb; dc->is_mem = 0; #if !defined(CONFIG_USER_ONLY) dc->user = (env->uncached_cpsr & 0x1f) == ARM_CPU_MODE_USR; #endif next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; nb_gen_labels = 0; lj = -1; do { if (env->nb_breakpoints > 0) { for(j = 0; j < env->nb_breakpoints; j++) { if (env->breakpoints[j] == dc->pc) { gen_op_movl_T0_im((long)dc->pc); gen_op_movl_reg_TN[0][15](); gen_op_debug(); dc->is_jmp = DISAS_JUMP; } } } if (search_pc) { j = gen_opc_ptr - gen_opc_buf; if (lj < j) { lj++; while (lj < j) gen_opc_instr_start[lj++] = 0; } gen_opc_pc[lj] = dc->pc; gen_opc_instr_start[lj] = 1; } if (env->thumb) disas_thumb_insn(dc); else disas_arm_insn(env, dc); if (dc->condjmp && !dc->is_jmp) { gen_set_label(dc->condlabel); dc->condjmp = 0; } /* Translation stops when a conditional branch is enoutered. * Otherwise the subsequent code could get translated several times. * Also stop translation when a page boundary is reached. This * ensures prefech aborts occur at the right place. */ } while (!dc->is_jmp && gen_opc_ptr < gen_opc_end && !env->singlestep_enabled && dc->pc < next_page_start); /* At this stage dc->condjmp will only be set when the skipped * instruction was a conditional branch, and the PC has already been * written. */ if (__builtin_expect(env->singlestep_enabled, 0)) { /* Make sure the pc is updated, and raise a debug exception. */ if (dc->condjmp) { gen_op_debug(); gen_set_label(dc->condlabel); } if (dc->condjmp || !dc->is_jmp) { gen_op_movl_T0_im((long)dc->pc); gen_op_movl_reg_TN[0][15](); dc->condjmp = 0; } gen_op_debug(); } else { switch(dc->is_jmp) { case DISAS_NEXT: gen_goto_tb(dc, 1, dc->pc); default: case DISAS_JUMP: case DISAS_UPDATE: /* indicate that the hash table must be used to find the next TB */ gen_op_movl_T0_0(); gen_op_exit_tb(); case DISAS_TB_JUMP: /* nothing more to generate */ } if (dc->condjmp) { gen_set_label(dc->condlabel); gen_goto_tb(dc, 1, dc->pc); dc->condjmp = 0; } } *gen_opc_ptr = INDEX_op_end; #ifdef DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "----------------\n"); fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start)); target_disas(logfile, pc_start, dc->pc - pc_start, env->thumb); fprintf(logfile, "\n"); if (loglevel & (CPU_LOG_TB_OP)) { fprintf(logfile, "OP:\n"); dump_ops(gen_opc_buf, gen_opparam_buf); fprintf(logfile, "\n"); } } #endif if (search_pc) { j = gen_opc_ptr - gen_opc_buf; lj++; while (lj <= j) gen_opc_instr_start[lj++] = 0; tb->size = 0; } else { tb->size = dc->pc - pc_start; } return 0; }


static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1, TCGv arg2, int add_ca, int compute_ca, int compute_ov) { TCGv t0, t1; if ((!compute_ca && !compute_ov) || (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2))) { t0 = ret; t0 = tcg_temp_local_new(); } if (add_ca) { t1 = tcg_temp_local_new(); tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA)); tcg_gen_shri_tl(t1, t1, XER_CA); } if (compute_ca && compute_ov) { /* Start with XER CA and OV disabled, the most likely case */ tcg_gen_andi_tl(cpu_xer, cpu_xer, ~((1 << XER_CA) | (1 << XER_OV))); } else if (compute_ca) { /* Start with XER CA disabled, the most likely case */ tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA)); } else if (compute_ov) { /* Start with XER OV disabled, the most likely case */ tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV)); } if (add_ca) { tcg_gen_not_tl(t0, arg1); tcg_gen_add_tl(t0, t0, arg2); gen_op_arith_compute_ca(ctx, t0, arg2, 0); tcg_gen_add_tl(t0, t0, t1); gen_op_arith_compute_ca(ctx, t0, t1, 0); tcg_temp_free(t1); tcg_gen_sub_tl(t0, arg2, arg1); if (compute_ca) { gen_op_arith_compute_ca(ctx, t0, arg2, 1); } } if (compute_ov) { gen_op_arith_compute_ov(ctx, t0, arg1, arg2, 1); } if (unlikely(Rc(ctx->opcode) != 0)) gen_set_Rc0(ctx, t0); if (!TCGV_EQUAL(t0, ret)) { tcg_gen_mov_tl(ret, t0); tcg_temp_free(t0); } }


static uint64_t imx_ccm_read(void *opaque, target_phys_addr_t offset, unsigned size) { IMXCCMState *s = (IMXCCMState *)opaque; DPRINTF("read(offset=%x)", offset >> 2); switch (offset >> 2) { case 0: /* CCMR */ DPRINTF(" ccmr = 0x%x\n", s->ccmr); return s->ccmr; case 1: DPRINTF(" pdr0 = 0x%x\n", s->pdr0); return s->pdr0; case 2: DPRINTF(" pdr1 = 0x%x\n", s->pdr1); return s->pdr1; case 4: DPRINTF(" mpctl = 0x%x\n", s->mpctl); return s->mpctl; case 6: DPRINTF(" spctl = 0x%x\n", s->spctl); return s->spctl; case 8: DPRINTF(" cgr0 = 0x%x\n", s->cgr[0]); return s->cgr[0]; case 9: DPRINTF(" cgr1 = 0x%x\n", s->cgr[1]); return s->cgr[1]; case 10: DPRINTF(" cgr2 = 0x%x\n", s->cgr[2]); return s->cgr[2]; case 18: /* LTR1 */ return 0x00004040; case 23: DPRINTF(" pcmr0 = 0x%x\n", s->pmcr0); return s->pmcr0; } DPRINTF(" return 0\n"); return 0; }


static void ne2000_receive(void *opaque, const uint8_t *buf, size_t size) { NE2000State *s = opaque; uint8_t *p; unsigned int total_len, next, avail, len, index, mcast_idx; uint8_t buf1[60]; static const uint8_t broadcast_macaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; #if defined(DEBUG_NE2000) printf("NE2000: received len=%d\n", size); #endif if (s->cmd & E8390_STOP || ne2000_buffer_full(s)) return; /* XXX: check this */ if (s->rxcr & 0x10) { /* promiscuous: receive all */ } else { if (!memcmp(buf, broadcast_macaddr, 6)) { /* broadcast address */ if (!(s->rxcr & 0x04)) return; } else if (buf[0] & 0x01) { /* multicast */ if (!(s->rxcr & 0x08)) return; mcast_idx = compute_mcast_idx(buf); if (!(s->mult[mcast_idx >> 3] & (1 << (mcast_idx & 7)))) return; } else if (s->mem[0] == buf[0] && s->mem[2] == buf[1] && s->mem[4] == buf[2] && s->mem[6] == buf[3] && s->mem[8] == buf[4] && s->mem[10] == buf[5]) { /* match */ } else { return; } } /* if too small buffer, then expand it */ if (size < MIN_BUF_SIZE) { memcpy(buf1, buf, size); memset(buf1 + size, 0, MIN_BUF_SIZE - size); buf = buf1; size = MIN_BUF_SIZE; } index = s->curpag << 8; /* 4 bytes for header */ total_len = size + 4; /* address for next packet (4 bytes for CRC) */ next = index + ((total_len + 4 + 255) & ~0xff); if (next >= s->stop) next -= (s->stop - s->start); /* prepare packet header */ p = s->mem + index; s->rsr = ENRSR_RXOK; /* receive status */ /* XXX: check this */ if (buf[0] & 0x01) s->rsr |= ENRSR_PHY; p[0] = s->rsr; p[1] = next >> 8; p[2] = total_len; p[3] = total_len >> 8; index += 4; /* write packet data */ while (size > 0) { if (index <= s->stop) avail = s->stop - index; else avail = 0; len = size; if (len > avail) len = avail; memcpy(s->mem + index, buf, len); buf += len; index += len; if (index == s->stop) index = s->start; size -= len; } s->curpag = next >> 8; /* now we can signal we have received something */ s->isr |= ENISR_RX; ne2000_update_irq(s); }


int kvm_init(void) { static const char upgrade_note[] = "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n" "(see http://sourceforge.net/projects/kvm).\n"; KVMState *s; const KVMCapabilityInfo *missing_cap; int ret; int i; int max_vcpus; s = g_malloc0(sizeof(KVMState)); /* * On systems where the kernel can support different base page * sizes, host page size may be different from TARGET_PAGE_SIZE, * even with KVM. TARGET_PAGE_SIZE is assumed to be the minimum * page size for the system though. */ assert(TARGET_PAGE_SIZE <= getpagesize()); #ifdef KVM_CAP_SET_GUEST_DEBUG QTAILQ_INIT(&s->kvm_sw_breakpoints); #endif for (i = 0; i < ARRAY_SIZE(s->slots); i++) { s->slots[i].slot = i; } s->vmfd = -1; s->fd = qemu_open("/dev/kvm", O_RDWR); if (s->fd == -1) { fprintf(stderr, "Could not access KVM kernel module: %m\n"); ret = -errno; goto err; } ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0); if (ret < KVM_API_VERSION) { if (ret > 0) { ret = -EINVAL; } fprintf(stderr, "kvm version too old\n"); goto err; } if (ret > KVM_API_VERSION) { ret = -EINVAL; fprintf(stderr, "kvm version not supported\n"); goto err; } max_vcpus = kvm_max_vcpus(s); if (smp_cpus > max_vcpus) { ret = -EINVAL; fprintf(stderr, "Number of SMP cpus requested (%d) exceeds max cpus " "supported by KVM (%d)\n", smp_cpus, max_vcpus); goto err; } if (max_cpus > max_vcpus) { ret = -EINVAL; fprintf(stderr, "Number of hotpluggable cpus requested (%d) exceeds max cpus " "supported by KVM (%d)\n", max_cpus, max_vcpus); goto err; } s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0); if (s->vmfd < 0) { #ifdef TARGET_S390X fprintf(stderr, "Please add the 'switch_amode' kernel parameter to " "your host kernel command line\n"); #endif ret = s->vmfd; goto err; } missing_cap = kvm_check_extension_list(s, kvm_required_capabilites); if (!missing_cap) { missing_cap = kvm_check_extension_list(s, kvm_arch_required_capabilities); } if (missing_cap) { ret = -EINVAL; fprintf(stderr, "kvm does not support %s\n%s", missing_cap->name, upgrade_note); goto err; } s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO); s->broken_set_mem_region = 1; ret = kvm_check_extension(s, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS); if (ret > 0) { s->broken_set_mem_region = 0; } #ifdef KVM_CAP_VCPU_EVENTS s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS); #endif s->robust_singlestep = kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP); #ifdef KVM_CAP_DEBUGREGS s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS); #endif #ifdef KVM_CAP_XSAVE s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE); #endif #ifdef KVM_CAP_XCRS s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS); #endif #ifdef KVM_CAP_PIT_STATE2 s->pit_state2 = kvm_check_extension(s, KVM_CAP_PIT_STATE2); #endif #ifdef KVM_CAP_IRQ_ROUTING s->direct_msi = (kvm_check_extension(s, KVM_CAP_SIGNAL_MSI) > 0); #endif s->intx_set_mask = kvm_check_extension(s, KVM_CAP_PCI_2_3); s->irq_set_ioctl = KVM_IRQ_LINE; if (kvm_check_extension(s, KVM_CAP_IRQ_INJECT_STATUS)) { s->irq_set_ioctl = KVM_IRQ_LINE_STATUS; } #ifdef KVM_CAP_READONLY_MEM kvm_readonly_mem_allowed = (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0); #endif ret = kvm_arch_init(s); if (ret < 0) { goto err; } ret = kvm_irqchip_create(s); if (ret < 0) { goto err; } kvm_state = s; memory_listener_register(&kvm_memory_listener, &address_space_memory); memory_listener_register(&kvm_io_listener, &address_space_io); s->many_ioeventfds = kvm_check_many_ioeventfds(); cpu_interrupt_handler = kvm_handle_interrupt; return 0; err: if (s->vmfd >= 0) { close(s->vmfd); } if (s->fd != -1) { close(s->fd); } g_free(s); return ret; }


static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref, AVIOInterruptCB *int_cb) { /* try relative path, we do not try the absolute because it can leak information about our system to an attacker */ if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { char filename[1024]; char *src_path; int i, l; /* find a source dir */ src_path = strrchr(src, '/'); if (src_path) src_path++; else src_path = src; /* find a next level down to target */ for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--) if (ref->path[l] == '/') { if (i == ref->nlvl_to - 1) break; else i++; } /* compose filename if next level down to target was found */ if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) { memcpy(filename, src, src_path - src); filename[src_path - src] = 0; for (i = 1; i < ref->nlvl_from; i++) av_strlcat(filename, "../", 1024); av_strlcat(filename, ref->path + l + 1, 1024); if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL)) return 0; } } return AVERROR(ENOENT); }


static int mmu_translate_asce(CPUS390XState *env, target_ulong vaddr, uint64_t asc, uint64_t asce, int level, target_ulong *raddr, int *flags, int rw) { CPUState *cs = CPU(s390_env_get_cpu(env)); uint64_t offs = 0; uint64_t origin; uint64_t new_asce; PTE_DPRINTF("%s: 0x%" PRIx64 "\n", __func__, asce); if (((level != _ASCE_TYPE_SEGMENT) && (asce & _REGION_ENTRY_INV)) || ((level == _ASCE_TYPE_SEGMENT) && (asce & _SEGMENT_ENTRY_INV))) { /* XXX different regions have different faults */ DPRINTF("%s: invalid region\n", __func__); trigger_page_fault(env, vaddr, PGM_SEGMENT_TRANS, asc, rw); return -1; } if ((level <= _ASCE_TYPE_MASK) && ((asce & _ASCE_TYPE_MASK) != level)) { trigger_page_fault(env, vaddr, PGM_TRANS_SPEC, asc, rw); return -1; } if (asce & _ASCE_REAL_SPACE) { /* direct mapping */ *raddr = vaddr; return 0; } origin = asce & _ASCE_ORIGIN; switch (level) { case _ASCE_TYPE_REGION1 + 4: offs = (vaddr >> 50) & 0x3ff8; break; case _ASCE_TYPE_REGION1: offs = (vaddr >> 39) & 0x3ff8; break; case _ASCE_TYPE_REGION2: offs = (vaddr >> 28) & 0x3ff8; break; case _ASCE_TYPE_REGION3: offs = (vaddr >> 17) & 0x3ff8; break; case _ASCE_TYPE_SEGMENT: offs = (vaddr >> 9) & 0x07f8; origin = asce & _SEGMENT_ENTRY_ORIGIN; break; } /* XXX region protection flags */ /* *flags &= ~PAGE_WRITE */ new_asce = ldq_phys(cs->as, origin + offs); PTE_DPRINTF("%s: 0x%" PRIx64 " + 0x%" PRIx64 " => 0x%016" PRIx64 "\n", __func__, origin, offs, new_asce); if (level == _ASCE_TYPE_SEGMENT) { /* 4KB page */ return mmu_translate_pte(env, vaddr, asc, new_asce, raddr, flags, rw); } else if (level - 4 == _ASCE_TYPE_SEGMENT && (new_asce & _SEGMENT_ENTRY_FC) && (env->cregs[0] & CR0_EDAT)) { /* 1MB page */ return mmu_translate_sfaa(env, vaddr, asc, new_asce, raddr, flags, rw); } else { /* yet another region */ return mmu_translate_asce(env, vaddr, asc, new_asce, level - 4, raddr, flags, rw); } }


bool iommu_dma_memory_valid(DMAContext *dma, dma_addr_t addr, dma_addr_t len, DMADirection dir) { target_phys_addr_t paddr, plen; #ifdef DEBUG_IOMMU fprintf(stderr, "dma_memory_check context=%p addr=0x" DMA_ADDR_FMT " len=0x" DMA_ADDR_FMT " dir=%d\n", dma, addr, len, dir); #endif while (len) { if (dma->translate(dma, addr, &paddr, &plen, dir) != 0) { return false; } /* The translation might be valid for larger regions. */ if (plen > len) { plen = len; } len -= plen; addr += plen; } return true; }


static void tm_put(QEMUFile *f, struct tm *tm) { qemu_put_be16(f, tm->tm_sec); qemu_put_be16(f, tm->tm_min); qemu_put_be16(f, tm->tm_hour); qemu_put_be16(f, tm->tm_mday); qemu_put_be16(f, tm->tm_min); qemu_put_be16(f, tm->tm_year); }


uint64_t helper_fsqrt(CPUPPCState *env, uint64_t arg) { CPU_DoubleU farg; farg.ll = arg; if (unlikely(float64_is_neg(farg.d) && !float64_is_zero(farg.d))) { /* Square root of a negative nonzero number */ farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT); } else { if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN square root */ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN); } farg.d = float64_sqrt(farg.d, &env->fp_status); } return farg.ll; }


static int kvm_handle_internal_error(CPUState *env, struct kvm_run *run) { fprintf(stderr, "KVM internal error."); if (kvm_check_extension(kvm_state, KVM_CAP_INTERNAL_ERROR_DATA)) { int i; fprintf(stderr, " Suberror: %d\n", run->internal.suberror); for (i = 0; i < run->internal.ndata; ++i) { fprintf(stderr, "extra data[%d]: %"PRIx64"\n", i, (uint64_t)run->internal.data[i]); } } else { fprintf(stderr, "\n"); } if (run->internal.suberror == KVM_INTERNAL_ERROR_EMULATION) { fprintf(stderr, "emulation failure\n"); if (!kvm_arch_stop_on_emulation_error(env)) { cpu_dump_state(env, stderr, fprintf, CPU_DUMP_CODE); return 0; } } /* FIXME: Should trigger a qmp message to let management know * something went wrong. */ return -1; }


int virtio_get_block_size(void) { return blk_cfg.blk_size; }