static int decode_mips16_opc (CPUState *env, DisasContext *ctx, int *is_branch) { int rx, ry; int sa; int op, cnvt_op, op1, offset; int funct; int n_bytes; op = (ctx->opcode >> 11) & 0x1f; sa = (ctx->opcode >> 2) & 0x7; sa = sa == 0 ? 8 : sa; rx = xlat((ctx->opcode >> 8) & 0x7); cnvt_op = (ctx->opcode >> 5) & 0x7; ry = xlat((ctx->opcode >> 5) & 0x7); op1 = offset = ctx->opcode & 0x1f; n_bytes = 2; switch (op) { case M16_OPC_ADDIUSP: { int16_t imm = ((uint8_t) ctx->opcode) << 2; gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm); } break; case M16_OPC_ADDIUPC: gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0); break; case M16_OPC_B: offset = (ctx->opcode & 0x7ff) << 1; offset = (int16_t)(offset << 4) >> 4; gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset); /* No delay slot, so just process as a normal instruction */ break; case M16_OPC_JAL: offset = lduw_code(ctx->pc + 2); offset = (((ctx->opcode & 0x1f) << 21) | ((ctx->opcode >> 5) & 0x1f) << 16 | offset) << 2; op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL; gen_compute_branch(ctx, op, 4, rx, ry, offset); n_bytes = 4; *is_branch = 1; break; case M16_OPC_BEQZ: gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1); /* No delay slot, so just process as a normal instruction */ break; case M16_OPC_BNEQZ: gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1); /* No delay slot, so just process as a normal instruction */ break; case M16_OPC_SHIFT: switch (ctx->opcode & 0x3) { case 0x0: gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa); break; case 0x1: #if defined(TARGET_MIPS64) check_mips_64(ctx); gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa); #else generate_exception(ctx, EXCP_RI); #endif break; case 0x2: gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa); break; case 0x3: gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa); break; } break; #if defined(TARGET_MIPS64) case M16_OPC_LD: check_mips_64(ctx); gen_ldst(ctx, OPC_LD, ry, rx, offset << 3); break; #endif case M16_OPC_RRIA: { int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4; if ((ctx->opcode >> 4) & 1) { #if defined(TARGET_MIPS64) check_mips_64(ctx); gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm); #else generate_exception(ctx, EXCP_RI); #endif } else { gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm); } } break; case M16_OPC_ADDIU8: { int16_t imm = (int8_t) ctx->opcode; gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm); } break; case M16_OPC_SLTI: { int16_t imm = (uint8_t) ctx->opcode; gen_slt_imm(env, OPC_SLTI, 24, rx, imm); } break; case M16_OPC_SLTIU: { int16_t imm = (uint8_t) ctx->opcode; gen_slt_imm(env, OPC_SLTIU, 24, rx, imm); } break; case M16_OPC_I8: { int reg32; funct = (ctx->opcode >> 8) & 0x7; switch (funct) { case I8_BTEQZ: gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0, ((int8_t)ctx->opcode) << 1); break; case I8_BTNEZ: gen_compute_branch(ctx, OPC_BNE, 2, 24, 0, ((int8_t)ctx->opcode) << 1); break; case I8_SWRASP: gen_ldst(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2); break; case I8_ADJSP: gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, ((int8_t)ctx->opcode) << 3); break; case I8_SVRS: { int do_ra = ctx->opcode & (1 << 6); int do_s0 = ctx->opcode & (1 << 5); int do_s1 = ctx->opcode & (1 << 4); int framesize = ctx->opcode & 0xf; if (framesize == 0) { framesize = 128; } else { framesize = framesize << 3; } if (ctx->opcode & (1 << 7)) { gen_mips16_save(ctx, 0, 0, do_ra, do_s0, do_s1, framesize); } else { gen_mips16_restore(ctx, 0, 0, do_ra, do_s0, do_s1, framesize); } } break; case I8_MOV32R: { int rz = xlat(ctx->opcode & 0x7); reg32 = (((ctx->opcode >> 3) & 0x3) << 3) | ((ctx->opcode >> 5) & 0x7); gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0); } break; case I8_MOVR32: reg32 = ctx->opcode & 0x1f; gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0); break; default: generate_exception(ctx, EXCP_RI); break; } } break; case M16_OPC_LI: { int16_t imm = (uint8_t) ctx->opcode; gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm); } break; case M16_OPC_CMPI: { int16_t imm = (uint8_t) ctx->opcode; gen_logic_imm(env, OPC_XORI, 24, rx, imm); } break; #if defined(TARGET_MIPS64) case M16_OPC_SD: check_mips_64(ctx); gen_ldst(ctx, OPC_SD, ry, rx, offset << 3); break; #endif case M16_OPC_LB: gen_ldst(ctx, OPC_LB, ry, rx, offset); break; case M16_OPC_LH: gen_ldst(ctx, OPC_LH, ry, rx, offset << 1); break; case M16_OPC_LWSP: gen_ldst(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2); break; case M16_OPC_LW: gen_ldst(ctx, OPC_LW, ry, rx, offset << 2); break; case M16_OPC_LBU: gen_ldst(ctx, OPC_LBU, ry, rx, offset); break; case M16_OPC_LHU: gen_ldst(ctx, OPC_LHU, ry, rx, offset << 1); break; case M16_OPC_LWPC: gen_ldst(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2); break; #if defined (TARGET_MIPS64) case M16_OPC_LWU: check_mips_64(ctx); gen_ldst(ctx, OPC_LWU, ry, rx, offset << 2); break; #endif case M16_OPC_SB: gen_ldst(ctx, OPC_SB, ry, rx, offset); break; case M16_OPC_SH: gen_ldst(ctx, OPC_SH, ry, rx, offset << 1); break; case M16_OPC_SWSP: gen_ldst(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2); break; case M16_OPC_SW: gen_ldst(ctx, OPC_SW, ry, rx, offset << 2); break; case M16_OPC_RRR: { int rz = xlat((ctx->opcode >> 2) & 0x7); int mips32_op; switch (ctx->opcode & 0x3) { case RRR_ADDU: mips32_op = OPC_ADDU; break; case RRR_SUBU: mips32_op = OPC_SUBU; break; #if defined(TARGET_MIPS64) case RRR_DADDU: mips32_op = OPC_DADDU; check_mips_64(ctx); break; case RRR_DSUBU: mips32_op = OPC_DSUBU; check_mips_64(ctx); break; #endif default: generate_exception(ctx, EXCP_RI); goto done; } gen_arith(env, ctx, mips32_op, rz, rx, ry); done: ; } break; case M16_OPC_RR: switch (op1) { case RR_JR: { int nd = (ctx->opcode >> 7) & 0x1; int link = (ctx->opcode >> 6) & 0x1; int ra = (ctx->opcode >> 5) & 0x1; if (link) { op = nd ? OPC_JALRC : OPC_JALR; } else { op = OPC_JR; } gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0); if (!nd) { *is_branch = 1; } } break; case RR_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); } break; case RR_SLT: gen_slt(env, OPC_SLT, 24, rx, ry); break; case RR_SLTU: gen_slt(env, OPC_SLTU, 24, rx, ry); break; case RR_BREAK: generate_exception(ctx, EXCP_BREAK); break; case RR_SLLV: gen_shift(env, ctx, OPC_SLLV, ry, rx, ry); break; case RR_SRLV: gen_shift(env, ctx, OPC_SRLV, ry, rx, ry); break; case RR_SRAV: gen_shift(env, ctx, OPC_SRAV, ry, rx, ry); break; #if defined (TARGET_MIPS64) case RR_DSRL: check_mips_64(ctx); gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa); break; #endif case RR_CMP: gen_logic(env, OPC_XOR, 24, rx, ry); break; case RR_NEG: gen_arith(env, ctx, OPC_SUBU, rx, 0, ry); break; case RR_AND: gen_logic(env, OPC_AND, rx, rx, ry); break; case RR_OR: gen_logic(env, OPC_OR, rx, rx, ry); break; case RR_XOR: gen_logic(env, OPC_XOR, rx, rx, ry); break; case RR_NOT: gen_logic(env, OPC_NOR, rx, ry, 0); break; case RR_MFHI: gen_HILO(ctx, OPC_MFHI, rx); break; case RR_CNVT: switch (cnvt_op) { case RR_RY_CNVT_ZEB: tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]); break; case RR_RY_CNVT_ZEH: tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]); break; case RR_RY_CNVT_SEB: tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]); break; case RR_RY_CNVT_SEH: tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]); break; #if defined (TARGET_MIPS64) case RR_RY_CNVT_ZEW: check_mips_64(ctx); tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]); break; case RR_RY_CNVT_SEW: check_mips_64(ctx); tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]); break; #endif default: generate_exception(ctx, EXCP_RI); break; } break; case RR_MFLO: gen_HILO(ctx, OPC_MFLO, rx); break; #if defined (TARGET_MIPS64) case RR_DSRA: check_mips_64(ctx); gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa); break; case RR_DSLLV: check_mips_64(ctx); gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry); break; case RR_DSRLV: check_mips_64(ctx); gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry); break; case RR_DSRAV: check_mips_64(ctx); gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry); break; #endif case RR_MULT: gen_muldiv(ctx, OPC_MULT, rx, ry); break; case RR_MULTU: gen_muldiv(ctx, OPC_MULTU, rx, ry); break; case RR_DIV: gen_muldiv(ctx, OPC_DIV, rx, ry); break; case RR_DIVU: gen_muldiv(ctx, OPC_DIVU, rx, ry); break; #if defined (TARGET_MIPS64) case RR_DMULT: check_mips_64(ctx); gen_muldiv(ctx, OPC_DMULT, rx, ry); break; case RR_DMULTU: check_mips_64(ctx); gen_muldiv(ctx, OPC_DMULTU, rx, ry); break; case RR_DDIV: check_mips_64(ctx); gen_muldiv(ctx, OPC_DDIV, rx, ry); break; case RR_DDIVU: check_mips_64(ctx); gen_muldiv(ctx, OPC_DDIVU, rx, ry); break; #endif default: generate_exception(ctx, EXCP_RI); break; } break; case M16_OPC_EXTEND: decode_extended_mips16_opc(env, ctx, is_branch); n_bytes = 4; break; #if defined(TARGET_MIPS64) case M16_OPC_I64: funct = (ctx->opcode >> 8) & 0x7; decode_i64_mips16(env, ctx, ry, funct, offset, 0); break; #endif default: generate_exception(ctx, EXCP_RI); break; } return n_bytes; }


static int smc_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; SmcContext *s = avctx->priv_data; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); int ret; bytestream2_init(&s->gb, buf, buf_size); if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (pal) { s->frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } smc_decode_stream(s); *got_frame = 1; if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; /* always report that the buffer was completely consumed */ return buf_size; }


static void proxy_seekdir(FsContext *ctx, V9fsFidOpenState *fs, off_t off) { seekdir(fs->dir, off); }


void virtio_notify(VirtIODevice *vdev, VirtQueue *vq) { /* Always notify when queue is empty */ if ((vq->inuse || vring_avail_idx(vq) != vq->last_avail_idx) && (vring_avail_flags(vq) & VRING_AVAIL_F_NO_INTERRUPT)) return; vdev->isr |= 0x01; virtio_update_irq(vdev); }


static int64_t allocate_cluster(BlockDriverState *bs, int64_t sector_num) { BDRVParallelsState *s = bs->opaque; uint32_t idx, offset, tmp; int64_t pos; int ret; idx = sector_num / s->tracks; offset = sector_num % s->tracks; if (idx >= s->catalog_size) { return -EINVAL; } if (s->catalog_bitmap[idx] != 0) { return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset; } pos = bdrv_getlength(bs->file) >> BDRV_SECTOR_BITS; if (s->has_truncate) { ret = bdrv_truncate(bs->file, (pos + s->tracks) << BDRV_SECTOR_BITS); } else { ret = bdrv_write_zeroes(bs->file, pos, s->tracks, 0); } if (ret < 0) { return ret; } s->catalog_bitmap[idx] = pos / s->off_multiplier; tmp = cpu_to_le32(s->catalog_bitmap[idx]); ret = bdrv_pwrite(bs->file, sizeof(ParallelsHeader) + idx * sizeof(tmp), &tmp, sizeof(tmp)); if (ret < 0) { s->catalog_bitmap[idx] = 0; return ret; } return (uint64_t)s->catalog_bitmap[idx] * s->off_multiplier + offset; }


static int vdi_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVVdiState *s = bs->opaque; VdiHeader header; size_t bmap_size; int ret; logout("\n"); ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1); if (ret < 0) { goto fail; } vdi_header_to_cpu(&header); #if defined(CONFIG_VDI_DEBUG) vdi_header_print(&header); #endif if (header.disk_size % SECTOR_SIZE != 0) { /* 'VBoxManage convertfromraw' can create images with odd disk sizes. We accept them but round the disk size to the next multiple of SECTOR_SIZE. */ logout("odd disk size %" PRIu64 " B, round up\n", header.disk_size); header.disk_size += SECTOR_SIZE - 1; header.disk_size &= ~(SECTOR_SIZE - 1); } if (header.signature != VDI_SIGNATURE) { logout("bad vdi signature %08x\n", header.signature); ret = -EMEDIUMTYPE; goto fail; } else if (header.version != VDI_VERSION_1_1) { logout("unsupported version %u.%u\n", header.version >> 16, header.version & 0xffff); ret = -ENOTSUP; goto fail; } else if (header.offset_bmap % SECTOR_SIZE != 0) { /* We only support block maps which start on a sector boundary. */ logout("unsupported block map offset 0x%x B\n", header.offset_bmap); ret = -ENOTSUP; goto fail; } else if (header.offset_data % SECTOR_SIZE != 0) { /* We only support data blocks which start on a sector boundary. */ logout("unsupported data offset 0x%x B\n", header.offset_data); ret = -ENOTSUP; goto fail; } else if (header.sector_size != SECTOR_SIZE) { logout("unsupported sector size %u B\n", header.sector_size); ret = -ENOTSUP; goto fail; } else if (header.block_size != 1 * MiB) { logout("unsupported block size %u B\n", header.block_size); ret = -ENOTSUP; goto fail; } else if (header.disk_size > (uint64_t)header.blocks_in_image * header.block_size) { logout("unsupported disk size %" PRIu64 " B\n", header.disk_size); ret = -ENOTSUP; goto fail; } else if (!uuid_is_null(header.uuid_link)) { logout("link uuid != 0, unsupported\n"); ret = -ENOTSUP; goto fail; } else if (!uuid_is_null(header.uuid_parent)) { logout("parent uuid != 0, unsupported\n"); ret = -ENOTSUP; goto fail; } bs->total_sectors = header.disk_size / SECTOR_SIZE; s->block_size = header.block_size; s->block_sectors = header.block_size / SECTOR_SIZE; s->bmap_sector = header.offset_bmap / SECTOR_SIZE; s->header = header; bmap_size = header.blocks_in_image * sizeof(uint32_t); bmap_size = (bmap_size + SECTOR_SIZE - 1) / SECTOR_SIZE; s->bmap = g_malloc(bmap_size * SECTOR_SIZE); ret = bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap, bmap_size); if (ret < 0) { goto fail_free_bmap; } /* Disable migration when vdi images are used */ error_set(&s->migration_blocker, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, "vdi", bs->device_name, "live migration"); migrate_add_blocker(s->migration_blocker); return 0; fail_free_bmap: g_free(s->bmap); fail: return ret; }


ThreadPool *aio_get_thread_pool(AioContext *ctx) { if (!ctx->thread_pool) { ctx->thread_pool = thread_pool_new(ctx); } return ctx->thread_pool; }


static void string_serialize(void *native_in, void **datap, VisitorFunc visit, Error **errp) { StringSerializeData *d = g_malloc0(sizeof(*d)); d->sov = string_output_visitor_new(false); visit(string_output_get_visitor(d->sov), &native_in, errp); *datap = d; }


void cpu_x86_update_cr3(CPUX86State *env) { if (env->cr[0] & CR0_PG_MASK) { #if defined(DEBUG_MMU) printf("CR3 update: CR3=%08x\n", env->cr[3]); #endif tlb_flush(env); } }


static inline void apply_8x8(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int dir, uint8_t **ref_picture, qpel_mc_func (*qpix_op)[16], op_pixels_func (*pix_op)[4]) { int dxy, mx, my, src_x, src_y; int i; int mb_x = s->mb_x; int mb_y = s->mb_y; uint8_t *ptr, *dest; mx = 0; my = 0; if (s->quarter_sample) { for (i = 0; i < 4; i++) { int motion_x = s->mv[dir][i][0]; int motion_y = s->mv[dir][i][1]; dxy = ((motion_y & 3) << 2) | (motion_x & 3); src_x = mb_x * 16 + (motion_x >> 2) + (i & 1) * 8; src_y = mb_y * 16 + (motion_y >> 2) + (i >> 1) * 8; /* WARNING: do no forget half pels */ src_x = av_clip(src_x, -16, s->width); if (src_x == s->width) dxy &= ~3; src_y = av_clip(src_y, -16, s->height); if (src_y == s->height) dxy &= ~12; ptr = ref_picture[0] + (src_y * s->linesize) + (src_x); if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 3) - 8, 0) || (unsigned)src_y > FFMAX(s->v_edge_pos - (motion_y & 3) - 8, 0)) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->linesize, s->linesize, 9, 9, src_x, src_y, s->h_edge_pos, s->v_edge_pos); ptr = s->edge_emu_buffer; } dest = dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize; qpix_op[1][dxy](dest, ptr, s->linesize); mx += s->mv[dir][i][0] / 2; my += s->mv[dir][i][1] / 2; } } else { for (i = 0; i < 4; i++) { hpel_motion(s, dest_y + ((i & 1) * 8) + (i >> 1) * 8 * s->linesize, ref_picture[0], mb_x * 16 + (i & 1) * 8, mb_y * 16 + (i >> 1) * 8, pix_op[1], s->mv[dir][i][0], s->mv[dir][i][1]); mx += s->mv[dir][i][0]; my += s->mv[dir][i][1]; } } if (!CONFIG_GRAY || !(s->flags & CODEC_FLAG_GRAY)) chroma_4mv_motion(s, dest_cb, dest_cr, ref_picture, pix_op[1], mx, my); }


void mpeg_motion_internal(MpegEncContext *s, uint8_t *dest_y, uint8_t *dest_cb, uint8_t *dest_cr, int field_based, int bottom_field, int field_select, uint8_t **ref_picture, op_pixels_func (*pix_op)[4], int motion_x, int motion_y, int h, int is_mpeg12, int mb_y) { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int dxy, uvdxy, mx, my, src_x, src_y, uvsrc_x, uvsrc_y, v_edge_pos; ptrdiff_t uvlinesize, linesize; #if 0 if (s->quarter_sample) { motion_x >>= 1; motion_y >>= 1; } #endif v_edge_pos = s->v_edge_pos >> field_based; linesize = s->current_picture.f->linesize[0] << field_based; uvlinesize = s->current_picture.f->linesize[1] << field_based; dxy = ((motion_y & 1) << 1) | (motion_x & 1); src_x = s->mb_x * 16 + (motion_x >> 1); src_y = (mb_y << (4 - field_based)) + (motion_y >> 1); if (!is_mpeg12 && s->out_format == FMT_H263) { if ((s->workaround_bugs & FF_BUG_HPEL_CHROMA) && field_based) { mx = (motion_x >> 1) | (motion_x & 1); my = motion_y >> 1; uvdxy = ((my & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); } else { uvdxy = dxy | (motion_y & 2) | ((motion_x & 2) >> 1); uvsrc_x = src_x >> 1; uvsrc_y = src_y >> 1; } // Even chroma mv's are full pel in H261 } else if (!is_mpeg12 && s->out_format == FMT_H261) { mx = motion_x / 4; my = motion_y / 4; uvdxy = 0; uvsrc_x = s->mb_x * 8 + mx; uvsrc_y = mb_y * 8 + my; } else { if (s->chroma_y_shift) { mx = motion_x / 2; my = motion_y / 2; uvdxy = ((my & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = (mb_y << (3 - field_based)) + (my >> 1); } else { if (s->chroma_x_shift) { // Chroma422 mx = motion_x / 2; uvdxy = ((motion_y & 1) << 1) | (mx & 1); uvsrc_x = s->mb_x * 8 + (mx >> 1); uvsrc_y = src_y; } else { // Chroma444 uvdxy = dxy; uvsrc_x = src_x; uvsrc_y = src_y; } } } ptr_y = ref_picture[0] + src_y * linesize + src_x; ptr_cb = ref_picture[1] + uvsrc_y * uvlinesize + uvsrc_x; ptr_cr = ref_picture[2] + uvsrc_y * uvlinesize + uvsrc_x; if ((unsigned)src_x > FFMAX(s->h_edge_pos - (motion_x & 1) - 16, 0) || (unsigned)src_y > FFMAX(v_edge_pos - (motion_y & 1) - h, 0)) { if (is_mpeg12 || s->codec_id == AV_CODEC_ID_MPEG2VIDEO || s->codec_id == AV_CODEC_ID_MPEG1VIDEO) { av_log(s->avctx, AV_LOG_DEBUG, "MPEG motion vector out of boundary (%d %d)\n", src_x, src_y); return; } s->vdsp.emulated_edge_mc(s->sc.edge_emu_buffer, ptr_y, s->linesize, s->linesize, 17, 17 + field_based, src_x, src_y << field_based, s->h_edge_pos, s->v_edge_pos); ptr_y = s->sc.edge_emu_buffer; if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { uint8_t *uvbuf = s->sc.edge_emu_buffer + 18 * s->linesize; s->vdsp.emulated_edge_mc(uvbuf, ptr_cb, s->uvlinesize, s->uvlinesize, 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, s->h_edge_pos >> 1, s->v_edge_pos >> 1); s->vdsp.emulated_edge_mc(uvbuf + 16, ptr_cr, s->uvlinesize, s->uvlinesize, 9, 9 + field_based, uvsrc_x, uvsrc_y << field_based, s->h_edge_pos >> 1, s->v_edge_pos >> 1); ptr_cb = uvbuf; ptr_cr = uvbuf + 16; } } /* FIXME use this for field pix too instead of the obnoxious hack which * changes picture.data */ if (bottom_field) { dest_y += s->linesize; dest_cb += s->uvlinesize; dest_cr += s->uvlinesize; } if (field_select) { ptr_y += s->linesize; ptr_cb += s->uvlinesize; ptr_cr += s->uvlinesize; } pix_op[0][dxy](dest_y, ptr_y, linesize, h); if (!CONFIG_GRAY || !(s->avctx->flags & AV_CODEC_FLAG_GRAY)) { pix_op[s->chroma_x_shift][uvdxy] (dest_cb, ptr_cb, uvlinesize, h >> s->chroma_y_shift); pix_op[s->chroma_x_shift][uvdxy] (dest_cr, ptr_cr, uvlinesize, h >> s->chroma_y_shift); } if (!is_mpeg12 && (CONFIG_H261_ENCODER || CONFIG_H261_DECODER) && s->out_format == FMT_H261) { ff_h261_loop_filter(s); } }


static void parse_palette_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { PGSSubContext *ctx = avctx->priv_data; const uint8_t *buf_end = buf + buf_size; const uint8_t *cm = ff_crop_tab + MAX_NEG_CROP; int color_id; int y, cb, cr, alpha; int r, g, b, r_add, g_add, b_add; /* Skip two null bytes */ buf += 2; while (buf < buf_end) { color_id = bytestream_get_byte(&buf); y = bytestream_get_byte(&buf); cr = bytestream_get_byte(&buf); cb = bytestream_get_byte(&buf); alpha = bytestream_get_byte(&buf); YUV_TO_RGB1(cb, cr); YUV_TO_RGB2(r, g, b, y); av_dlog(avctx, "Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha); /* Store color in palette */ ctx->clut[color_id] = RGBA(r,g,b,alpha); } }


static int transcode(OutputFile *output_files, int nb_output_files, InputFile *input_files, int nb_input_files) { int ret, i; AVFormatContext *is, *os; OutputStream *ost; InputStream *ist; uint8_t *no_packet; int no_packet_count = 0; int64_t timer_start; int key; if (!(no_packet = av_mallocz(nb_input_files))) exit_program(1); ret = transcode_init(output_files, nb_output_files, input_files, nb_input_files); if (ret < 0) goto fail; if (!using_stdin) { av_log(NULL, AV_LOG_INFO, "Press [q] to stop, [?] for help\n"); } timer_start = av_gettime(); for (; received_sigterm == 0;) { int file_index, ist_index; AVPacket pkt; int64_t ipts_min; double opts_min; int64_t cur_time= av_gettime(); ipts_min = INT64_MAX; opts_min = 1e100; /* if 'q' pressed, exits */ if (!using_stdin) { static int64_t last_time; if (received_nb_signals) break; /* read_key() returns 0 on EOF */ if(cur_time - last_time >= 100000 && !run_as_daemon){ key = read_key(); last_time = cur_time; }else key = -1; if (key == 'q') break; if (key == '+') av_log_set_level(av_log_get_level()+10); if (key == '-') av_log_set_level(av_log_get_level()-10); if (key == 's') qp_hist ^= 1; if (key == 'h'){ if (do_hex_dump){ do_hex_dump = do_pkt_dump = 0; } else if(do_pkt_dump){ do_hex_dump = 1; } else do_pkt_dump = 1; av_log_set_level(AV_LOG_DEBUG); } #if CONFIG_AVFILTER if (key == 'c' || key == 'C'){ char buf[4096], target[64], command[256], arg[256] = {0}; double time; int k, n = 0; fprintf(stderr, "\nEnter command: <target> <time> <command>[ <argument>]\n"); i = 0; while ((k = read_key()) != '\n' && k != '\r' && i < sizeof(buf)-1) if (k > 0) buf[i++] = k; buf[i] = 0; if (k > 0 && (n = sscanf(buf, "%63[^ ] %lf %255[^ ] %255[^\n]", target, &time, command, arg)) >= 3) { av_log(NULL, AV_LOG_DEBUG, "Processing command target:%s time:%f command:%s arg:%s", target, time, command, arg); for (i = 0; i < nb_output_streams; i++) { ost = &output_streams[i]; if (ost->graph) { if (time < 0) { ret = avfilter_graph_send_command(ost->graph, target, command, arg, buf, sizeof(buf), key == 'c' ? AVFILTER_CMD_FLAG_ONE : 0); fprintf(stderr, "Command reply for stream %d: ret:%d res:%s\n", i, ret, buf); } else { ret = avfilter_graph_queue_command(ost->graph, target, command, arg, 0, time); } } } } else { av_log(NULL, AV_LOG_ERROR, "Parse error, at least 3 arguments were expected, " "only %d given in string '%s'\n", n, buf); } } #endif if (key == 'd' || key == 'D'){ int debug=0; if(key == 'D') { debug = input_streams[0].st->codec->debug<<1; if(!debug) debug = 1; while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash debug += debug; }else if(scanf("%d", &debug)!=1) fprintf(stderr,"error parsing debug value\n"); for(i=0;i<nb_input_streams;i++) { input_streams[i].st->codec->debug = debug; } for(i=0;i<nb_output_streams;i++) { ost = &output_streams[i]; ost->st->codec->debug = debug; } if(debug) av_log_set_level(AV_LOG_DEBUG); fprintf(stderr,"debug=%d\n", debug); } if (key == '?'){ fprintf(stderr, "key function\n" "? show this help\n" "+ increase verbosity\n" "- decrease verbosity\n" "c Send command to filtergraph\n" "D cycle through available debug modes\n" "h dump packets/hex press to cycle through the 3 states\n" "q quit\n" "s Show QP histogram\n" ); } } /* select the stream that we must read now by looking at the smallest output pts */ file_index = -1; for (i = 0; i < nb_output_streams; i++) { OutputFile *of; int64_t ipts; double opts; ost = &output_streams[i]; of = &output_files[ost->file_index]; os = output_files[ost->file_index].ctx; ist = &input_streams[ost->source_index]; if (ost->is_past_recording_time || no_packet[ist->file_index] || (os->pb && avio_tell(os->pb) >= of->limit_filesize)) continue; opts = ost->st->pts.val * av_q2d(ost->st->time_base); ipts = ist->pts; if (!input_files[ist->file_index].eof_reached) { if (ipts < ipts_min) { ipts_min = ipts; if (input_sync) file_index = ist->file_index; } if (opts < opts_min) { opts_min = opts; if (!input_sync) file_index = ist->file_index; } } if (ost->frame_number >= ost->max_frames) { int j; for (j = 0; j < of->ctx->nb_streams; j++) output_streams[of->ost_index + j].is_past_recording_time = 1; continue; } } /* if none, if is finished */ if (file_index < 0) { if (no_packet_count) { no_packet_count = 0; memset(no_packet, 0, nb_input_files); usleep(10000); continue; } break; } /* read a frame from it and output it in the fifo */ is = input_files[file_index].ctx; ret = av_read_frame(is, &pkt); if (ret == AVERROR(EAGAIN)) { no_packet[file_index] = 1; no_packet_count++; continue; } if (ret < 0) { input_files[file_index].eof_reached = 1; if (opt_shortest) break; else continue; } no_packet_count = 0; memset(no_packet, 0, nb_input_files); if (do_pkt_dump) { av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump, is->streams[pkt.stream_index]); } /* the following test is needed in case new streams appear dynamically in stream : we ignore them */ if (pkt.stream_index >= input_files[file_index].nb_streams) goto discard_packet; ist_index = input_files[file_index].ist_index + pkt.stream_index; ist = &input_streams[ist_index]; if (ist->discard) goto discard_packet; if (pkt.dts != AV_NOPTS_VALUE) pkt.dts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base); if (pkt.pts != AV_NOPTS_VALUE) pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base); if (pkt.pts != AV_NOPTS_VALUE) pkt.pts *= ist->ts_scale; if (pkt.dts != AV_NOPTS_VALUE) pkt.dts *= ist->ts_scale; //fprintf(stderr, "next:%"PRId64" dts:%"PRId64"/%"PRId64" off:%"PRId64" %d\n", // ist->next_dts, // ist->dts, av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q), input_files[ist->file_index].ts_offset, // ist->st->codec->codec_type); if (pkt.dts != AV_NOPTS_VALUE && ist->next_dts != AV_NOPTS_VALUE && (is->iformat->flags & AVFMT_TS_DISCONT)) { int64_t pkt_dts = av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q); int64_t delta = pkt_dts - ist->next_dts; if((delta < -1LL*dts_delta_threshold*AV_TIME_BASE || (delta > 1LL*dts_delta_threshold*AV_TIME_BASE && ist->st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) || pkt_dts+1<ist->pts)&& !copy_ts){ input_files[ist->file_index].ts_offset -= delta; av_log(NULL, AV_LOG_DEBUG, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n", delta, input_files[ist->file_index].ts_offset); pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); if (pkt.pts != AV_NOPTS_VALUE) pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base); } } // fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size); if (output_packet(ist, output_streams, nb_output_streams, &pkt) < 0) { av_log(NULL, AV_LOG_ERROR, "Error while decoding stream #%d:%d\n", ist->file_index, ist->st->index); if (exit_on_error) exit_program(1); av_free_packet(&pkt); continue; } discard_packet: av_free_packet(&pkt); /* dump report by using the output first video and audio streams */ print_report(output_files, output_streams, nb_output_streams, 0, timer_start, cur_time); } /* at the end of stream, we must flush the decoder buffers */ for (i = 0; i < nb_input_streams; i++) { ist = &input_streams[i]; if (ist->decoding_needed) { output_packet(ist, output_streams, nb_output_streams, NULL); } } flush_encoders(output_streams, nb_output_streams); term_exit(); /* write the trailer if needed and close file */ for (i = 0; i < nb_output_files; i++) { os = output_files[i].ctx; av_write_trailer(os); } /* dump report by using the first video and audio streams */ print_report(output_files, output_streams, nb_output_streams, 1, timer_start, av_gettime()); /* close each encoder */ for (i = 0; i < nb_output_streams; i++) { ost = &output_streams[i]; if (ost->encoding_needed) { av_freep(&ost->st->codec->stats_in); avcodec_close(ost->st->codec); } #if CONFIG_AVFILTER avfilter_graph_free(&ost->graph); #endif } /* close each decoder */ for (i = 0; i < nb_input_streams; i++) { ist = &input_streams[i]; if (ist->decoding_needed) { avcodec_close(ist->st->codec); } } /* finished ! */ ret = 0; fail: av_freep(&no_packet); if (output_streams) { for (i = 0; i < nb_output_streams; i++) { ost = &output_streams[i]; if (ost) { if (ost->stream_copy) av_freep(&ost->st->codec->extradata); if (ost->logfile) { fclose(ost->logfile); ost->logfile = NULL; } av_fifo_free(ost->fifo); /* works even if fifo is not initialized but set to zero */ av_freep(&ost->st->codec->subtitle_header); av_free(ost->resample_frame.data[0]); av_free(ost->forced_kf_pts); if (ost->video_resample) sws_freeContext(ost->img_resample_ctx); swr_free(&ost->swr); av_dict_free(&ost->opts); } } } return ret; }


void *av_realloc(void *ptr, size_t size) { #if CONFIG_MEMALIGN_HACK int diff; #endif /* let's disallow possible ambiguous cases */ if (size > (MAX_MALLOC_SIZE-16)) return NULL; #if CONFIG_MEMALIGN_HACK //FIXME this isn't aligned correctly, though it probably isn't needed if(!ptr) return av_malloc(size); diff= ((char*)ptr)[-1]; return (char*)realloc((char*)ptr - diff, size + diff) + diff; #else return realloc(ptr, size + !size); #endif }


static av_cold int raw_close_decoder(AVCodecContext *avctx) { RawVideoContext *context = avctx->priv_data; av_freep(&context->buffer); return 0; }


static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5], int x, int y, int ref, int plane) { Plane *p = &s->plane[plane]; uint8_t **ref_hpel = s->ref_pics[ref]->hpel[plane]; int motion_x = block->u.mv[ref][0]; int motion_y = block->u.mv[ref][1]; int mx, my, i, epel, nplanes = 0; if (plane) { motion_x >>= s->chroma_x_shift; motion_y >>= s->chroma_y_shift; } mx = motion_x & ~(-1 << s->mv_precision); my = motion_y & ~(-1 << s->mv_precision); motion_x >>= s->mv_precision; motion_y >>= s->mv_precision; /* normalize subpel coordinates to epel */ /* TODO: template this function? */ mx <<= 3 - s->mv_precision; my <<= 3 - s->mv_precision; x += motion_x; y += motion_y; epel = (mx|my)&1; /* hpel position */ if (!((mx|my)&3)) { nplanes = 1; src[0] = ref_hpel[(my>>1)+(mx>>2)] + y*p->stride + x; } else { /* qpel or epel */ nplanes = 4; for (i = 0; i < 4; i++) src[i] = ref_hpel[i] + y*p->stride + x; /* if we're interpolating in the right/bottom halves, adjust the planes as needed we increment x/y because the edge changes for half of the pixels */ if (mx > 4) { src[0] += 1; src[2] += 1; x++; } if (my > 4) { src[0] += p->stride; src[1] += p->stride; y++; } /* hpel planes are: [0]: F [1]: H [2]: V [3]: C */ if (!epel) { /* check if we really only need 2 planes since either mx or my is a hpel position. (epel weights of 0 handle this there) */ if (!(mx&3)) { /* mx == 0: average [0] and [2] mx == 4: average [1] and [3] */ src[!mx] = src[2 + !!mx]; nplanes = 2; } else if (!(my&3)) { src[0] = src[(my>>1) ]; src[1] = src[(my>>1)+1]; nplanes = 2; } } else { /* adjust the ordering if needed so the weights work */ if (mx > 4) { FFSWAP(const uint8_t *, src[0], src[1]); FFSWAP(const uint8_t *, src[2], src[3]); } if (my > 4) { FFSWAP(const uint8_t *, src[0], src[2]); FFSWAP(const uint8_t *, src[1], src[3]); } src[4] = epel_weights[my&3][mx&3]; } } /* fixme: v/h _edge_pos */ if (x + p->xblen > p->width +EDGE_WIDTH/2 || y + p->yblen > p->height+EDGE_WIDTH/2 || x < 0 || y < 0) { for (i = 0; i < nplanes; i++) { ff_emulated_edge_mc(s->edge_emu_buffer[i], src[i], p->stride, p->stride, p->xblen, p->yblen, x, y, p->width+EDGE_WIDTH/2, p->height+EDGE_WIDTH/2); src[i] = s->edge_emu_buffer[i]; } } return (nplanes>>1) + epel; }


int kvm_arch_init_vcpu(CPUState *cs) { struct { struct kvm_cpuid2 cpuid; struct kvm_cpuid_entry2 entries[KVM_MAX_CPUID_ENTRIES]; } QEMU_PACKED cpuid_data; X86CPU *cpu = X86_CPU(cs); CPUX86State *env = &cpu->env; uint32_t limit, i, j, cpuid_i; uint32_t unused; struct kvm_cpuid_entry2 *c; uint32_t signature[3]; int r; cpuid_i = 0; /* Paravirtualization CPUIDs */ c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_SIGNATURE; if (!hyperv_enabled(cpu)) { memcpy(signature, "KVMKVMKVM\0\0\0", 12); c->eax = 0; } else { memcpy(signature, "Microsoft Hv", 12); c->eax = HYPERV_CPUID_MIN; } c->ebx = signature[0]; c->ecx = signature[1]; c->edx = signature[2]; c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_FEATURES; c->eax = env->features[FEAT_KVM]; if (hyperv_enabled(cpu)) { memcpy(signature, "Hv#1\0\0\0\0\0\0\0\0", 12); c->eax = signature[0]; c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_VERSION; c->eax = 0x00001bbc; c->ebx = 0x00060001; c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_FEATURES; if (cpu->hyperv_relaxed_timing) { c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; } if (cpu->hyperv_vapic) { c->eax |= HV_X64_MSR_HYPERCALL_AVAILABLE; c->eax |= HV_X64_MSR_APIC_ACCESS_AVAILABLE; } c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_ENLIGHTMENT_INFO; if (cpu->hyperv_relaxed_timing) { c->eax |= HV_X64_RELAXED_TIMING_RECOMMENDED; } if (cpu->hyperv_vapic) { c->eax |= HV_X64_APIC_ACCESS_RECOMMENDED; } c->ebx = cpu->hyperv_spinlock_attempts; c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = HYPERV_CPUID_IMPLEMENT_LIMITS; c->eax = 0x40; c->ebx = 0x40; c = &cpuid_data.entries[cpuid_i++]; memset(c, 0, sizeof(*c)); c->function = KVM_CPUID_SIGNATURE_NEXT; memcpy(signature, "KVMKVMKVM\0\0\0", 12); c->eax = 0; c->ebx = signature[0]; c->ecx = signature[1]; c->edx = signature[2]; } has_msr_async_pf_en = c->eax & (1 << KVM_FEATURE_ASYNC_PF); has_msr_pv_eoi_en = c->eax & (1 << KVM_FEATURE_PV_EOI); has_msr_kvm_steal_time = c->eax & (1 << KVM_FEATURE_STEAL_TIME); cpu_x86_cpuid(env, 0, 0, &limit, &unused, &unused, &unused); for (i = 0; i <= limit; i++) { if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { fprintf(stderr, "unsupported level value: 0x%x\n", limit); abort(); } c = &cpuid_data.entries[cpuid_i++]; switch (i) { case 2: { /* Keep reading function 2 till all the input is received */ int times; c->function = i; c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC | KVM_CPUID_FLAG_STATE_READ_NEXT; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); times = c->eax & 0xff; for (j = 1; j < times; ++j) { if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { fprintf(stderr, "cpuid_data is full, no space for " "cpuid(eax:2):eax & 0xf = 0x%x\n", times); abort(); } c = &cpuid_data.entries[cpuid_i++]; c->function = i; c->flags = KVM_CPUID_FLAG_STATEFUL_FUNC; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); } break; } case 4: case 0xb: case 0xd: for (j = 0; ; j++) { if (i == 0xd && j == 64) { break; } c->function = i; c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX; c->index = j; cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx); if (i == 4 && c->eax == 0) { break; } if (i == 0xb && !(c->ecx & 0xff00)) { break; } if (i == 0xd && c->eax == 0) { continue; } if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { fprintf(stderr, "cpuid_data is full, no space for " "cpuid(eax:0x%x,ecx:0x%x)\n", i, j); abort(); } c = &cpuid_data.entries[cpuid_i++]; } break; default: c->function = i; c->flags = 0; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); break; } } if (limit >= 0x0a) { uint32_t ver; cpu_x86_cpuid(env, 0x0a, 0, &ver, &unused, &unused, &unused); if ((ver & 0xff) > 0) { has_msr_architectural_pmu = true; num_architectural_pmu_counters = (ver & 0xff00) >> 8; /* Shouldn't be more than 32, since that's the number of bits * available in EBX to tell us _which_ counters are available. * Play it safe. */ if (num_architectural_pmu_counters > MAX_GP_COUNTERS) { num_architectural_pmu_counters = MAX_GP_COUNTERS; } } } cpu_x86_cpuid(env, 0x80000000, 0, &limit, &unused, &unused, &unused); for (i = 0x80000000; i <= limit; i++) { if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { fprintf(stderr, "unsupported xlevel value: 0x%x\n", limit); abort(); } c = &cpuid_data.entries[cpuid_i++]; c->function = i; c->flags = 0; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); } /* Call Centaur's CPUID instructions they are supported. */ if (env->cpuid_xlevel2 > 0) { cpu_x86_cpuid(env, 0xC0000000, 0, &limit, &unused, &unused, &unused); for (i = 0xC0000000; i <= limit; i++) { if (cpuid_i == KVM_MAX_CPUID_ENTRIES) { fprintf(stderr, "unsupported xlevel2 value: 0x%x\n", limit); abort(); } c = &cpuid_data.entries[cpuid_i++]; c->function = i; c->flags = 0; cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx); } } cpuid_data.cpuid.nent = cpuid_i; if (((env->cpuid_version >> 8)&0xF) >= 6 && (env->features[FEAT_1_EDX] & (CPUID_MCE | CPUID_MCA)) == (CPUID_MCE | CPUID_MCA) && kvm_check_extension(cs->kvm_state, KVM_CAP_MCE) > 0) { uint64_t mcg_cap; int banks; int ret; ret = kvm_get_mce_cap_supported(cs->kvm_state, &mcg_cap, &banks); if (ret < 0) { fprintf(stderr, "kvm_get_mce_cap_supported: %s", strerror(-ret)); return ret; } if (banks > MCE_BANKS_DEF) { banks = MCE_BANKS_DEF; } mcg_cap &= MCE_CAP_DEF; mcg_cap |= banks; ret = kvm_vcpu_ioctl(cs, KVM_X86_SETUP_MCE, &mcg_cap); if (ret < 0) { fprintf(stderr, "KVM_X86_SETUP_MCE: %s", strerror(-ret)); return ret; } env->mcg_cap = mcg_cap; } qemu_add_vm_change_state_handler(cpu_update_state, env); c = cpuid_find_entry(&cpuid_data.cpuid, 1, 0); if (c) { has_msr_feature_control = !!(c->ecx & CPUID_EXT_VMX) || !!(c->ecx & CPUID_EXT_SMX); } cpuid_data.cpuid.padding = 0; r = kvm_vcpu_ioctl(cs, KVM_SET_CPUID2, &cpuid_data); if (r) { return r; } r = kvm_check_extension(cs->kvm_state, KVM_CAP_TSC_CONTROL); if (r && env->tsc_khz) { r = kvm_vcpu_ioctl(cs, KVM_SET_TSC_KHZ, env->tsc_khz); if (r < 0) { fprintf(stderr, "KVM_SET_TSC_KHZ failed\n"); return r; } } if (kvm_has_xsave()) { env->kvm_xsave_buf = qemu_memalign(4096, sizeof(struct kvm_xsave)); } return 0; }


static QObject *pci_get_dev_dict(PCIDevice *dev, PCIBus *bus, int bus_num) { int class; QObject *obj; obj = qobject_from_jsonf("{ 'bus': %d, 'slot': %d, 'function': %d," "'class_info': %p, 'id': %p, 'regions': %p," " 'qdev_id': %s }", bus_num, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn), pci_get_dev_class(dev), pci_get_dev_id(dev), pci_get_regions_list(dev), dev->qdev.id ? dev->qdev.id : ""); if (dev->config[PCI_INTERRUPT_PIN] != 0) { QDict *qdict = qobject_to_qdict(obj); qdict_put(qdict, "irq", qint_from_int(dev->config[PCI_INTERRUPT_LINE])); } class = pci_get_word(dev->config + PCI_CLASS_DEVICE); if (class == PCI_CLASS_BRIDGE_HOST || class == PCI_CLASS_BRIDGE_PCI) { QDict *qdict; QObject *pci_bridge; pci_bridge = qobject_from_jsonf("{ 'bus': " "{ 'number': %d, 'secondary': %d, 'subordinate': %d }, " "'io_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "}, " "'memory_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "}, " "'prefetchable_range': { 'base': %" PRId64 ", 'limit': %" PRId64 "} }", dev->config[PCI_PRIMARY_BUS], dev->config[PCI_SECONDARY_BUS], dev->config[PCI_SUBORDINATE_BUS], pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_IO), pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_IO), pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY), pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY), pci_bridge_get_base(dev, PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_PREFETCH), pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_PREFETCH)); if (dev->config[PCI_SECONDARY_BUS] != 0) { PCIBus *child_bus = pci_find_bus(bus, dev->config[PCI_SECONDARY_BUS]); if (child_bus) { qdict = qobject_to_qdict(pci_bridge); qdict_put_obj(qdict, "devices", pci_get_devices_list(child_bus, dev->config[PCI_SECONDARY_BUS])); } } qdict = qobject_to_qdict(obj); qdict_put_obj(qdict, "pci_bridge", pci_bridge); } return obj; }


static int decode_block_progressive(MJpegDecodeContext *s, int16_t *block, uint8_t *last_nnz, int ac_index, int16_t *quant_matrix, int ss, int se, int Al, int *EOBRUN) { int code, i, j, level, val, run; if (*EOBRUN) { (*EOBRUN)--; return 0; } { OPEN_READER(re, &s->gb); for (i = ss; ; i++) { UPDATE_CACHE(re, &s->gb); GET_VLC(code, re, &s->gb, s->vlcs[2][ac_index].table, 9, 2); run = ((unsigned) code) >> 4; code &= 0xF; if (code) { i += run; if (code > MIN_CACHE_BITS - 16) UPDATE_CACHE(re, &s->gb); { int cache = GET_CACHE(re, &s->gb); int sign = (~cache) >> 31; level = (NEG_USR32(sign ^ cache,code) ^ sign) - sign; } LAST_SKIP_BITS(re, &s->gb, code); if (i >= se) { if (i == se) { j = s->scantable.permutated[se]; block[j] = level * quant_matrix[j] << Al; break; } av_log(s->avctx, AV_LOG_ERROR, "error count: %d\n", i); return AVERROR_INVALIDDATA; } j = s->scantable.permutated[i]; block[j] = level * quant_matrix[j] << Al; } else { if (run == 0xF) {// ZRL - skip 15 coefficients i += 15; if (i >= se) { av_log(s->avctx, AV_LOG_ERROR, "ZRL overflow: %d\n", i); return AVERROR_INVALIDDATA; } } else { val = (1 << run); if (run) { UPDATE_CACHE(re, &s->gb); val += NEG_USR32(GET_CACHE(re, &s->gb), run); LAST_SKIP_BITS(re, &s->gb, run); } *EOBRUN = val - 1; break; } } } CLOSE_READER(re, &s->gb); } if (i > *last_nnz) *last_nnz = i; return 0; }


static void *bsd_vmalloc(size_t size) { void *p; mmap_lock(); /* Use map and mark the pages as used. */ p = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); if (h2g_valid(p)) { /* Allocated region overlaps guest address space. This may recurse. */ abi_ulong addr = h2g(p); page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size), PAGE_RESERVED); } mmap_unlock(); return p; }


void rgb32tobgr24(const uint8_t *src, uint8_t *dst, long src_size) { long i; long num_pixels = src_size >> 2; for(i=0; i<num_pixels; i++) { #ifdef WORDS_BIGENDIAN /* RGB32 (= A,B,G,R) -> BGR24 (= B,G,R) */ dst[3*i + 0] = src[4*i + 1]; dst[3*i + 1] = src[4*i + 2]; dst[3*i + 2] = src[4*i + 3]; #else dst[3*i + 0] = src[4*i + 2]; dst[3*i + 1] = src[4*i + 1]; dst[3*i + 2] = src[4*i + 0]; #endif } }


static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags, SwsVector *srcFilter, SwsVector *dstFilter, double param[2], int is_horizontal) { int i; int filterSize; int filter2Size; int minFilterSize; int64_t *filter=NULL; int64_t *filter2=NULL; const int64_t fone= 1LL<<54; int ret= -1; emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions) // NOTE: the +3 is for the MMX(+1)/SSE(+3) scaler which reads over the end FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+3)*sizeof(int16_t), fail); if (FFABS(xInc - 0x10000) <10) { // unscaled int i; filterSize= 1; FF_ALLOCZ_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); for (i=0; i<dstW; i++) { filter[i*filterSize]= fone; (*filterPos)[i]=i; } } else if (flags&SWS_POINT) { // lame looking point sampling mode int i; int xDstInSrc; filterSize= 1; FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc/2 - 0x8000; for (i=0; i<dstW; i++) { int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16; (*filterPos)[i]= xx; filter[i]= fone; xDstInSrc+= xInc; } } else if ((xInc <= (1<<16) && (flags&SWS_AREA)) || (flags&SWS_FAST_BILINEAR)) { // bilinear upscale int i; int xDstInSrc; filterSize= 2; FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc/2 - 0x8000; for (i=0; i<dstW; i++) { int xx= (xDstInSrc - ((filterSize-1)<<15) + (1<<15))>>16; int j; (*filterPos)[i]= xx; //bilinear upscale / linear interpolate / area averaging for (j=0; j<filterSize; j++) { int64_t coeff= fone - FFABS((xx<<16) - xDstInSrc)*(fone>>16); if (coeff<0) coeff=0; filter[i*filterSize + j]= coeff; xx++; } xDstInSrc+= xInc; } } else { int xDstInSrc; int sizeFactor; if (flags&SWS_BICUBIC) sizeFactor= 4; else if (flags&SWS_X) sizeFactor= 8; else if (flags&SWS_AREA) sizeFactor= 1; //downscale only, for upscale it is bilinear else if (flags&SWS_GAUSS) sizeFactor= 8; // infinite ;) else if (flags&SWS_LANCZOS) sizeFactor= param[0] != SWS_PARAM_DEFAULT ? ceil(2*param[0]) : 6; else if (flags&SWS_SINC) sizeFactor= 20; // infinite ;) else if (flags&SWS_SPLINE) sizeFactor= 20; // infinite ;) else if (flags&SWS_BILINEAR) sizeFactor= 2; else { sizeFactor= 0; //GCC warning killer assert(0); } if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW; if (filterSize > srcW-2) filterSize=srcW-2; FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc - 0x10000; for (i=0; i<dstW; i++) { int xx= (xDstInSrc - ((filterSize-2)<<16)) / (1<<17); int j; (*filterPos)[i]= xx; for (j=0; j<filterSize; j++) { int64_t d= ((int64_t)FFABS((xx<<17) - xDstInSrc))<<13; double floatd; int64_t coeff; if (xInc > 1<<16) d= d*dstW/srcW; floatd= d * (1.0/(1<<30)); if (flags & SWS_BICUBIC) { int64_t B= (param[0] != SWS_PARAM_DEFAULT ? param[0] : 0) * (1<<24); int64_t C= (param[1] != SWS_PARAM_DEFAULT ? param[1] : 0.6) * (1<<24); if (d >= 1LL<<31) { coeff = 0.0; } else { int64_t dd = (d * d) >> 30; int64_t ddd = (dd * d) >> 30; if (d < 1LL<<30) coeff = (12*(1<<24)-9*B-6*C)*ddd + (-18*(1<<24)+12*B+6*C)*dd + (6*(1<<24)-2*B)*(1<<30); else coeff = (-B-6*C)*ddd + (6*B+30*C)*dd + (-12*B-48*C)*d + (8*B+24*C)*(1<<30); } coeff *= fone>>(30+24); } /* else if (flags & SWS_X) { double p= param ? param*0.01 : 0.3; coeff = d ? sin(d*M_PI)/(d*M_PI) : 1.0; coeff*= pow(2.0, - p*d*d); }*/ else if (flags & SWS_X) { double A= param[0] != SWS_PARAM_DEFAULT ? param[0] : 1.0; double c; if (floatd<1.0) c = cos(floatd*M_PI); else c=-1.0; if (c<0.0) c= -pow(-c, A); else c= pow( c, A); coeff= (c*0.5 + 0.5)*fone; } else if (flags & SWS_AREA) { int64_t d2= d - (1<<29); if (d2*xInc < -(1LL<<(29+16))) coeff= 1.0 * (1LL<<(30+16)); else if (d2*xInc < (1LL<<(29+16))) coeff= -d2*xInc + (1LL<<(29+16)); else coeff=0.0; coeff *= fone>>(30+16); } else if (flags & SWS_GAUSS) { double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0; coeff = (pow(2.0, - p*floatd*floatd))*fone; } else if (flags & SWS_SINC) { coeff = (d ? sin(floatd*M_PI)/(floatd*M_PI) : 1.0)*fone; } else if (flags & SWS_LANCZOS) { double p= param[0] != SWS_PARAM_DEFAULT ? param[0] : 3.0; coeff = (d ? sin(floatd*M_PI)*sin(floatd*M_PI/p)/(floatd*floatd*M_PI*M_PI/p) : 1.0)*fone; if (floatd>p) coeff=0; } else if (flags & SWS_BILINEAR) { coeff= (1<<30) - d; if (coeff<0) coeff=0; coeff *= fone >> 30; } else if (flags & SWS_SPLINE) { double p=-2.196152422706632; coeff = getSplineCoeff(1.0, 0.0, p, -p-1.0, floatd) * fone; } else { coeff= 0.0; //GCC warning killer assert(0); } filter[i*filterSize + j]= coeff; xx++; } xDstInSrc+= 2*xInc; } } /* apply src & dst Filter to filter -> filter2 av_free(filter); */ assert(filterSize>0); filter2Size= filterSize; if (srcFilter) filter2Size+= srcFilter->length - 1; if (dstFilter) filter2Size+= dstFilter->length - 1; assert(filter2Size>0); FF_ALLOCZ_OR_GOTO(NULL, filter2, filter2Size*dstW*sizeof(*filter2), fail); for (i=0; i<dstW; i++) { int j, k; if(srcFilter) { for (k=0; k<srcFilter->length; k++) { for (j=0; j<filterSize; j++) filter2[i*filter2Size + k + j] += srcFilter->coeff[k]*filter[i*filterSize + j]; } } else { for (j=0; j<filterSize; j++) filter2[i*filter2Size + j]= filter[i*filterSize + j]; } //FIXME dstFilter (*filterPos)[i]+= (filterSize-1)/2 - (filter2Size-1)/2; } av_freep(&filter); /* try to reduce the filter-size (step1 find size and shift left) */ // Assume it is near normalized (*0.5 or *2.0 is OK but * 0.001 is not). minFilterSize= 0; for (i=dstW-1; i>=0; i--) { int min= filter2Size; int j; int64_t cutOff=0.0; /* get rid of near zero elements on the left by shifting left */ for (j=0; j<filter2Size; j++) { int k; cutOff += FFABS(filter2[i*filter2Size]); if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break; /* preserve monotonicity because the core can't handle the filter otherwise */ if (i<dstW-1 && (*filterPos)[i] >= (*filterPos)[i+1]) break; // move filter coefficients left for (k=1; k<filter2Size; k++) filter2[i*filter2Size + k - 1]= filter2[i*filter2Size + k]; filter2[i*filter2Size + k - 1]= 0; (*filterPos)[i]++; } cutOff=0; /* count near zeros on the right */ for (j=filter2Size-1; j>0; j--) { cutOff += FFABS(filter2[i*filter2Size + j]); if (cutOff > SWS_MAX_REDUCE_CUTOFF*fone) break; min--; } if (min>minFilterSize) minFilterSize= min; } if (HAVE_ALTIVEC && cpu_flags & AV_CPU_FLAG_ALTIVEC) { // we can handle the special case 4, // so we don't want to go to the full 8 if (minFilterSize < 5) filterAlign = 4; // We really don't want to waste our time // doing useless computation, so fall back on // the scalar C code for very small filters. // Vectorizing is worth it only if you have a // decent-sized vector. if (minFilterSize < 3) filterAlign = 1; } if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { // special case for unscaled vertical filtering if (minFilterSize == 1 && filterAlign == 2) filterAlign= 1; } assert(minFilterSize > 0); filterSize= (minFilterSize +(filterAlign-1)) & (~(filterAlign-1)); assert(filterSize > 0); filter= av_malloc(filterSize*dstW*sizeof(*filter)); if (filterSize >= MAX_FILTER_SIZE*16/((flags&SWS_ACCURATE_RND) ? APCK_SIZE : 16) || !filter) goto fail; *outFilterSize= filterSize; if (flags&SWS_PRINT_INFO) av_log(NULL, AV_LOG_VERBOSE, "SwScaler: reducing / aligning filtersize %d -> %d\n", filter2Size, filterSize); /* try to reduce the filter-size (step2 reduce it) */ for (i=0; i<dstW; i++) { int j; for (j=0; j<filterSize; j++) { if (j>=filter2Size) filter[i*filterSize + j]= 0; else filter[i*filterSize + j]= filter2[i*filter2Size + j]; if((flags & SWS_BITEXACT) && j>=minFilterSize) filter[i*filterSize + j]= 0; } } //FIXME try to align filterPos if possible //fix borders if (is_horizontal) { for (i = 0; i < dstW; i++) { int j; if ((*filterPos)[i] < 0) { // move filter coefficients left to compensate for filterPos for (j = 1; j < filterSize; j++) { int left = FFMAX(j + (*filterPos)[i], 0); filter[i * filterSize + left] += filter[i * filterSize + j]; filter[i * filterSize + j ] = 0; } (*filterPos)[i] = 0; } if ((*filterPos)[i] + filterSize > srcW) { int shift = (*filterPos)[i] + filterSize - srcW; // move filter coefficients right to compensate for filterPos for (j = filterSize - 2; j >= 0; j--) { int right = FFMIN(j + shift, filterSize - 1); filter[i * filterSize + right] += filter[i * filterSize + j]; filter[i * filterSize + j ] = 0; } (*filterPos)[i] = srcW - filterSize; } } } // Note the +1 is for the MMX scaler which reads over the end /* align at 16 for AltiVec (needed by hScale_altivec_real) */ FF_ALLOCZ_OR_GOTO(NULL, *outFilter, *outFilterSize*(dstW+3)*sizeof(int16_t), fail); /* normalize & store in outFilter */ for (i=0; i<dstW; i++) { int j; int64_t error=0; int64_t sum=0; for (j=0; j<filterSize; j++) { sum+= filter[i*filterSize + j]; } sum= (sum + one/2)/ one; for (j=0; j<*outFilterSize; j++) { int64_t v= filter[i*filterSize + j] + error; int intV= ROUNDED_DIV(v, sum); (*outFilter)[i*(*outFilterSize) + j]= intV; error= v - intV*sum; } } (*filterPos)[dstW+0] = (*filterPos)[dstW+1] = (*filterPos)[dstW+2] = (*filterPos)[dstW-1]; // the MMX/SSE scaler will read over the end for (i=0; i<*outFilterSize; i++) { int k= (dstW - 1) * (*outFilterSize) + i; (*outFilter)[k + 1 * (*outFilterSize)] = (*outFilter)[k + 2 * (*outFilterSize)] = (*outFilter)[k + 3 * (*outFilterSize)] = (*outFilter)[k]; } ret=0; fail: av_free(filter); av_free(filter2); return ret; }


static ssize_t usbnet_receive(VLANClientState *nc, const uint8_t *buf, size_t size) { USBNetState *s = DO_UPCAST(NICState, nc, nc)->opaque; struct rndis_packet_msg_type *msg; if (is_rndis(s)) { msg = (struct rndis_packet_msg_type *) s->in_buf; if (!s->rndis_state == RNDIS_DATA_INITIALIZED) return -1; if (size + sizeof(struct rndis_packet_msg_type) > sizeof(s->in_buf)) return -1; memset(msg, 0, sizeof(struct rndis_packet_msg_type)); msg->MessageType = cpu_to_le32(RNDIS_PACKET_MSG); msg->MessageLength = cpu_to_le32(size + sizeof(struct rndis_packet_msg_type)); msg->DataOffset = cpu_to_le32(sizeof(struct rndis_packet_msg_type) - 8); msg->DataLength = cpu_to_le32(size); /* msg->OOBDataOffset; * msg->OOBDataLength; * msg->NumOOBDataElements; * msg->PerPacketInfoOffset; * msg->PerPacketInfoLength; * msg->VcHandle; * msg->Reserved; */ memcpy(msg + 1, buf, size); s->in_len = size + sizeof(struct rndis_packet_msg_type); } else { if (size > sizeof(s->in_buf)) return -1; memcpy(s->in_buf, buf, size); s->in_len = size; } s->in_ptr = 0; return size; }


int unix_connect(const char *path) { QemuOpts *opts; int sock; opts = qemu_opts_create(&dummy_opts, NULL, 0); qemu_opt_set(opts, "path", path); sock = unix_connect_opts(opts); qemu_opts_del(opts); return sock; }


static inline bool regime_translation_disabled(CPUARMState *env, ARMMMUIdx mmu_idx) { if (arm_feature(env, ARM_FEATURE_M)) { switch (env->v7m.mpu_ctrl[regime_is_secure(env, mmu_idx)] & (R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK)) { case R_V7M_MPU_CTRL_ENABLE_MASK: /* Enabled, but not for HardFault and NMI */ return mmu_idx == ARMMMUIdx_MNegPri || mmu_idx == ARMMMUIdx_MSNegPri; case R_V7M_MPU_CTRL_ENABLE_MASK | R_V7M_MPU_CTRL_HFNMIENA_MASK: /* Enabled for all cases */ return false; case 0: default: /* HFNMIENA set and ENABLE clear is UNPREDICTABLE, but * we warned about that in armv7m_nvic.c when the guest set it. */ return true; } } if (mmu_idx == ARMMMUIdx_S2NS) { return (env->cp15.hcr_el2 & HCR_VM) == 0; } return (regime_sctlr(env, mmu_idx) & SCTLR_M) == 0; }


static void migration_instance_init(Object *obj) { MigrationState *ms = MIGRATION_OBJ(obj); ms->state = MIGRATION_STATUS_NONE; ms->xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE; ms->mbps = -1; ms->parameters.tls_creds = g_strdup(""); ms->parameters.tls_hostname = g_strdup(""); }


static void do_stop_capture(Monitor *mon, const QDict *qdict) { int i; int n = qdict_get_int(qdict, "n"); CaptureState *s; for (s = capture_head.lh_first, i = 0; s; s = s->entries.le_next, ++i) { if (i == n) { s->ops.destroy (s->opaque); LIST_REMOVE (s, entries); qemu_free (s); return; } } }


static void nbd_refresh_filename(BlockDriverState *bs) { QDict *opts = qdict_new(); const char *path = qdict_get_try_str(bs->options, "path"); const char *host = qdict_get_try_str(bs->options, "host"); const char *port = qdict_get_try_str(bs->options, "port"); const char *export = qdict_get_try_str(bs->options, "export"); qdict_put_obj(opts, "driver", QOBJECT(qstring_from_str("nbd"))); if (path && export) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nbd+unix:///%s?socket=%s", export, path); } else if (path && !export) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nbd+unix://?socket=%s", path); } else if (!path && export && port) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nbd://%s:%s/%s", host, port, export); } else if (!path && export && !port) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nbd://%s/%s", host, export); } else if (!path && !export && port) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nbd://%s:%s", host, port); } else if (!path && !export && !port) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nbd://%s", host); } if (path) { qdict_put_obj(opts, "path", QOBJECT(qstring_from_str(path))); } else if (port) { qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host))); qdict_put_obj(opts, "port", QOBJECT(qstring_from_str(port))); } else { qdict_put_obj(opts, "host", QOBJECT(qstring_from_str(host))); } if (export) { qdict_put_obj(opts, "export", QOBJECT(qstring_from_str(export))); } bs->full_open_options = opts; }


static int select_input_picture(MpegEncContext *s) { int i, ret; for (i = 1; i < MAX_PICTURE_COUNT; i++) s->reordered_input_picture[i - 1] = s->reordered_input_picture[i]; s->reordered_input_picture[MAX_PICTURE_COUNT - 1] = NULL; /* set next picture type & ordering */ if (!s->reordered_input_picture[0] && s->input_picture[0]) { if (/*s->picture_in_gop_number >= s->gop_size ||*/ !s->next_picture_ptr || s->intra_only) { s->reordered_input_picture[0] = s->input_picture[0]; s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_I; s->reordered_input_picture[0]->f->coded_picture_number = s->coded_picture_number++; } else { int b_frames; if (s->avctx->frame_skip_threshold || s->avctx->frame_skip_factor) { if (s->picture_in_gop_number < s->gop_size && skip_check(s, s->input_picture[0], s->next_picture_ptr)) { // FIXME check that te gop check above is +-1 correct av_frame_unref(s->input_picture[0]->f); emms_c(); ff_vbv_update(s, 0); goto no_output_pic; } } if (s->avctx->flags & AV_CODEC_FLAG_PASS2) { for (i = 0; i < s->max_b_frames + 1; i++) { int pict_num = s->input_picture[0]->f->display_picture_number + i; if (pict_num >= s->rc_context.num_entries) break; if (!s->input_picture[i]) { s->rc_context.entry[pict_num - 1].new_pict_type = AV_PICTURE_TYPE_P; break; } s->input_picture[i]->f->pict_type = s->rc_context.entry[pict_num].new_pict_type; } } if (s->avctx->b_frame_strategy == 0) { b_frames = s->max_b_frames; while (b_frames && !s->input_picture[b_frames]) b_frames--; } else if (s->avctx->b_frame_strategy == 1) { for (i = 1; i < s->max_b_frames + 1; i++) { if (s->input_picture[i] && s->input_picture[i]->b_frame_score == 0) { s->input_picture[i]->b_frame_score = get_intra_count(s, s->input_picture[i ]->f->data[0], s->input_picture[i - 1]->f->data[0], s->linesize) + 1; } } for (i = 0; i < s->max_b_frames + 1; i++) { if (!s->input_picture[i] || s->input_picture[i]->b_frame_score - 1 > s->mb_num / s->avctx->b_sensitivity) break; } b_frames = FFMAX(0, i - 1); /* reset scores */ for (i = 0; i < b_frames + 1; i++) { s->input_picture[i]->b_frame_score = 0; } } else if (s->avctx->b_frame_strategy == 2) { b_frames = estimate_best_b_count(s); } else { av_log(s->avctx, AV_LOG_ERROR, "illegal b frame strategy\n"); b_frames = 0; } emms_c(); for (i = b_frames - 1; i >= 0; i--) { int type = s->input_picture[i]->f->pict_type; if (type && type != AV_PICTURE_TYPE_B) b_frames = i; } if (s->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_B && b_frames == s->max_b_frames) { av_log(s->avctx, AV_LOG_ERROR, "warning, too many b frames in a row\n"); } if (s->picture_in_gop_number + b_frames >= s->gop_size) { if ((s->mpv_flags & FF_MPV_FLAG_STRICT_GOP) && s->gop_size > s->picture_in_gop_number) { b_frames = s->gop_size - s->picture_in_gop_number - 1; } else { if (s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) b_frames = 0; s->input_picture[b_frames]->f->pict_type = AV_PICTURE_TYPE_I; } } if ((s->avctx->flags & AV_CODEC_FLAG_CLOSED_GOP) && b_frames && s->input_picture[b_frames]->f->pict_type == AV_PICTURE_TYPE_I) b_frames--; s->reordered_input_picture[0] = s->input_picture[b_frames]; if (s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_I) s->reordered_input_picture[0]->f->pict_type = AV_PICTURE_TYPE_P; s->reordered_input_picture[0]->f->coded_picture_number = s->coded_picture_number++; for (i = 0; i < b_frames; i++) { s->reordered_input_picture[i + 1] = s->input_picture[i]; s->reordered_input_picture[i + 1]->f->pict_type = AV_PICTURE_TYPE_B; s->reordered_input_picture[i + 1]->f->coded_picture_number = s->coded_picture_number++; } } } no_output_pic: ff_mpeg_unref_picture(s->avctx, &s->new_picture); if (s->reordered_input_picture[0]) { s->reordered_input_picture[0]->reference = s->reordered_input_picture[0]->f->pict_type != AV_PICTURE_TYPE_B ? 3 : 0; if ((ret = ff_mpeg_ref_picture(s->avctx, &s->new_picture, s->reordered_input_picture[0]))) return ret; if (s->reordered_input_picture[0]->shared || s->avctx->rc_buffer_size) { // input is a shared pix, so we can't modifiy it -> alloc a new // one & ensure that the shared one is reuseable Picture *pic; int i = ff_find_unused_picture(s->avctx, s->picture, 0); if (i < 0) return i; pic = &s->picture[i]; pic->reference = s->reordered_input_picture[0]->reference; if (alloc_picture(s, pic, 0) < 0) { return -1; } ret = av_frame_copy_props(pic->f, s->reordered_input_picture[0]->f); if (ret < 0) return ret; /* mark us unused / free shared pic */ av_frame_unref(s->reordered_input_picture[0]->f); s->reordered_input_picture[0]->shared = 0; s->current_picture_ptr = pic; } else { // input is not a shared pix -> reuse buffer for current_pix s->current_picture_ptr = s->reordered_input_picture[0]; for (i = 0; i < 4; i++) { s->new_picture.f->data[i] += INPLACE_OFFSET; } } ff_mpeg_unref_picture(s->avctx, &s->current_picture); if ((ret = ff_mpeg_ref_picture(s->avctx, &s->current_picture, s->current_picture_ptr)) < 0) return ret; s->picture_number = s->new_picture.f->display_picture_number; } return 0; }


static inline void iwmmxt_store_reg(TCGv var, int reg) { tcg_gen_st_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg])); }


static int msix_is_masked(PCIDevice *dev, int vector) { unsigned offset = vector * MSIX_ENTRY_SIZE + MSIX_VECTOR_CTRL; return dev->msix_table_page[offset] & MSIX_VECTOR_MASK; }


static void qed_aio_next_io(QEDAIOCB *acb) { BDRVQEDState *s = acb_to_s(acb); uint64_t offset; size_t len; int ret; trace_qed_aio_next_io(s, acb, 0, acb->cur_pos + acb->cur_qiov.size); if (acb->backing_qiov) { qemu_iovec_destroy(acb->backing_qiov); g_free(acb->backing_qiov); acb->backing_qiov = NULL; } acb->qiov_offset += acb->cur_qiov.size; acb->cur_pos += acb->cur_qiov.size; qemu_iovec_reset(&acb->cur_qiov); /* Complete request */ if (acb->cur_pos >= acb->end_pos) { qed_aio_complete(acb, 0); return; } /* Find next cluster and start I/O */ len = acb->end_pos - acb->cur_pos; ret = qed_find_cluster(s, &acb->request, acb->cur_pos, &len, &offset); if (ret < 0) { qed_aio_complete(acb, ret); return; } if (acb->flags & QED_AIOCB_WRITE) { ret = qed_aio_write_data(acb, ret, offset, len); } else { ret = qed_aio_read_data(acb, ret, offset, len); } if (ret < 0) { if (ret != -EINPROGRESS) { qed_aio_complete(acb, ret); } return; } qed_aio_next_io(acb); }


writev_f(int argc, char **argv) { struct timeval t1, t2; int Cflag = 0, qflag = 0; int c, cnt; char *buf; int64_t offset; int total; int nr_iov; int pattern = 0xcd; QEMUIOVector qiov; while ((c = getopt(argc, argv, "CqP:")) != EOF) { switch (c) { case 'C': Cflag = 1; break; case 'q': qflag = 1; break; case 'P': pattern = atoi(optarg); break; default: return command_usage(&writev_cmd); } } if (optind > argc - 2) return command_usage(&writev_cmd); offset = cvtnum(argv[optind]); if (offset < 0) { printf("non-numeric length argument -- %s\n", argv[optind]); return 0; } optind++; if (offset & 0x1ff) { printf("offset %lld is not sector aligned\n", (long long)offset); return 0; } nr_iov = argc - optind; buf = create_iovec(&qiov, &argv[optind], nr_iov, pattern); gettimeofday(&t1, NULL); cnt = do_aio_writev(&qiov, offset, &total); gettimeofday(&t2, NULL); if (cnt < 0) { printf("writev 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, qiov.size, total, cnt, Cflag); out: qemu_io_free(buf); return 0; }


static void test_qemu_strtoull_decimal(void) { const char *str = "0123"; char f = 'X'; const char *endptr = &f; uint64_t res = 999; int err; err = qemu_strtoull(str, &endptr, 10, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); g_assert(endptr == str + strlen(str)); str = "123"; endptr = &f; res = 999; err = qemu_strtoull(str, &endptr, 0, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 123); g_assert(endptr == str + strlen(str)); }


static uint64_t imx_timerp_read(void *opaque, target_phys_addr_t offset, unsigned size) { IMXTimerPState *s = (IMXTimerPState *)opaque; DPRINTF("p-read(offset=%x)", offset >> 2); switch (offset >> 2) { case 0: /* Control Register */ DPRINTF("cr %x\n", s->cr); return s->cr; case 1: /* Status Register */ DPRINTF("int_level %x\n", s->int_level); return s->int_level; case 2: /* LR - ticks*/ DPRINTF("lr %x\n", s->lr); return s->lr; case 3: /* CMP */ DPRINTF("cmp %x\n", s->cmp); return s->cmp; case 4: /* CNT */ return ptimer_get_count(s->timer); } IPRINTF("imx_timerp_read: Bad offset %x\n", (int)offset >> 2); return 0; }


static void tcg_out_brcond2(TCGContext *s, TCGCond cond, TCGReg al, TCGReg ah, TCGReg bl, TCGReg bh, int label_index) { TCGCond b_cond = TCG_COND_NE; TCGReg tmp = TCG_TMP1; /* With branches, we emit between 4 and 9 insns with 2 or 3 branches. With setcond, we emit between 3 and 10 insns and only 1 branch, which ought to get better branch prediction. */ switch (cond) { case TCG_COND_EQ: case TCG_COND_NE: b_cond = cond; tmp = tcg_out_reduce_eq2(s, TCG_TMP0, TCG_TMP1, al, ah, bl, bh); break; default: /* Minimize code size by preferring a compare not requiring INV. */ if (mips_cmp_map[cond] & MIPS_CMP_INV) { cond = tcg_invert_cond(cond); b_cond = TCG_COND_EQ; } tcg_out_setcond2(s, cond, tmp, al, ah, bl, bh); break; } tcg_out_brcond(s, b_cond, tmp, TCG_REG_ZERO, label_index); }


static void legacy_mouse_event(DeviceState *dev, QemuConsole *src, InputEvent *evt) { static const int bmap[INPUT_BUTTON__MAX] = { [INPUT_BUTTON_LEFT] = MOUSE_EVENT_LBUTTON, [INPUT_BUTTON_MIDDLE] = MOUSE_EVENT_MBUTTON, [INPUT_BUTTON_RIGHT] = MOUSE_EVENT_RBUTTON, }; QEMUPutMouseEntry *s = (QEMUPutMouseEntry *)dev; InputBtnEvent *btn; InputMoveEvent *move; switch (evt->type) { case INPUT_EVENT_KIND_BTN: btn = evt->u.btn; if (btn->down) { s->buttons |= bmap[btn->button]; } else { s->buttons &= ~bmap[btn->button]; } if (btn->down && btn->button == INPUT_BUTTON_WHEEL_UP) { s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_Y], -1, s->buttons); } if (btn->down && btn->button == INPUT_BUTTON_WHEEL_DOWN) { s->qemu_put_mouse_event(s->qemu_put_mouse_event_opaque, s->axis[INPUT_AXIS_X], s->axis[INPUT_AXIS_Y], 1, s->buttons); } break; case INPUT_EVENT_KIND_ABS: move = evt->u.abs; s->axis[move->axis] = move->value; break; case INPUT_EVENT_KIND_REL: move = evt->u.rel; s->axis[move->axis] += move->value; break; default: break; } }


static int h264_slice_header_init(H264Context *h) { int nb_slices = (HAVE_THREADS && h->avctx->active_thread_type & FF_THREAD_SLICE) ? h->avctx->thread_count : 1; int i, ret; ff_set_sar(h->avctx, h->sps.sar); av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, &h->chroma_x_shift, &h->chroma_y_shift); if (h->sps.timing_info_present_flag) { int64_t den = h->sps.time_scale; if (h->x264_build < 44U) den *= 2; av_reduce(&h->avctx->framerate.den, &h->avctx->framerate.num, h->sps.num_units_in_tick, den, 1 << 30); } ff_h264_free_tables(h); h->first_field = 0; h->prev_interlaced_frame = 1; init_scan_tables(h); ret = ff_h264_alloc_tables(h); if (ret < 0) { av_log(h->avctx, AV_LOG_ERROR, "Could not allocate memory\n"); return ret; } if (h->sps.bit_depth_luma < 8 || h->sps.bit_depth_luma > 10) { av_log(h->avctx, AV_LOG_ERROR, "Unsupported bit depth %d\n", h->sps.bit_depth_luma); return AVERROR_INVALIDDATA; } h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma; h->pixel_shift = h->sps.bit_depth_luma > 8; h->chroma_format_idc = h->sps.chroma_format_idc; h->bit_depth_luma = h->sps.bit_depth_luma; ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, h->sps.chroma_format_idc); ff_h264chroma_init(&h->h264chroma, h->sps.bit_depth_chroma); ff_h264qpel_init(&h->h264qpel, h->sps.bit_depth_luma); ff_h264_pred_init(&h->hpc, h->avctx->codec_id, h->sps.bit_depth_luma, h->sps.chroma_format_idc); ff_videodsp_init(&h->vdsp, h->sps.bit_depth_luma); if (nb_slices > H264_MAX_THREADS || (nb_slices > h->mb_height && h->mb_height)) { int max_slices; if (h->mb_height) max_slices = FFMIN(H264_MAX_THREADS, h->mb_height); else max_slices = H264_MAX_THREADS; av_log(h->avctx, AV_LOG_WARNING, "too many threads/slices %d," " reducing to %d\n", nb_slices, max_slices); nb_slices = max_slices; } h->slice_context_count = nb_slices; if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) { ret = ff_h264_slice_context_init(h, &h->slice_ctx[0]); if (ret < 0) { av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n"); return ret; } } else { for (i = 0; i < h->slice_context_count; i++) { H264SliceContext *sl = &h->slice_ctx[i]; sl->h264 = h; sl->intra4x4_pred_mode = h->intra4x4_pred_mode + i * 8 * 2 * h->mb_stride; sl->mvd_table[0] = h->mvd_table[0] + i * 8 * 2 * h->mb_stride; sl->mvd_table[1] = h->mvd_table[1] + i * 8 * 2 * h->mb_stride; if ((ret = ff_h264_slice_context_init(h, sl)) < 0) { av_log(h->avctx, AV_LOG_ERROR, "context_init() failed.\n"); return ret; } } } h->context_initialized = 1; return 0; }


int ff_mpv_frame_start(MpegEncContext *s, AVCodecContext *avctx) { int i, ret; Picture *pic; s->mb_skipped = 0; /* mark & release old frames */ if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->f->buf[0]) { ff_mpeg_unref_picture(s->avctx, s->last_picture_ptr); } /* release forgotten pictures */ /* if (MPEG-124 / H.263) */ for (i = 0; i < MAX_PICTURE_COUNT; i++) { if (&s->picture[i] != s->last_picture_ptr && &s->picture[i] != s->next_picture_ptr && s->picture[i].reference && !s->picture[i].needs_realloc) { ff_mpeg_unref_picture(s->avctx, &s->picture[i]); } } ff_mpeg_unref_picture(s->avctx, &s->current_picture); /* release non reference frames */ for (i = 0; i < MAX_PICTURE_COUNT; i++) { if (!s->picture[i].reference) ff_mpeg_unref_picture(s->avctx, &s->picture[i]); } if (s->current_picture_ptr && !s->current_picture_ptr->f->buf[0]) { // we already have a unused image // (maybe it was set before reading the header) pic = s->current_picture_ptr; } else { i = ff_find_unused_picture(s->avctx, s->picture, 0); if (i < 0) { av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n"); return i; } pic = &s->picture[i]; } pic->reference = 0; if (!s->droppable) { if (s->pict_type != AV_PICTURE_TYPE_B) pic->reference = 3; } pic->f->coded_picture_number = s->coded_picture_number++; if (alloc_picture(s, pic, 0) < 0) return -1; s->current_picture_ptr = pic; // FIXME use only the vars from current_pic s->current_picture_ptr->f->top_field_first = s->top_field_first; if (s->codec_id == AV_CODEC_ID_MPEG1VIDEO || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { if (s->picture_structure != PICT_FRAME) s->current_picture_ptr->f->top_field_first = (s->picture_structure == PICT_TOP_FIELD) == s->first_field; } s->current_picture_ptr->f->interlaced_frame = !s->progressive_frame && !s->progressive_sequence; s->current_picture_ptr->field_picture = s->picture_structure != PICT_FRAME; s->current_picture_ptr->f->pict_type = s->pict_type; // if (s->avctx->flags && AV_CODEC_FLAG_QSCALE) // s->current_picture_ptr->quality = s->new_picture_ptr->quality; s->current_picture_ptr->f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; if ((ret = ff_mpeg_ref_picture(s->avctx, &s->current_picture, s->current_picture_ptr)) < 0) return ret; if (s->pict_type != AV_PICTURE_TYPE_B) { s->last_picture_ptr = s->next_picture_ptr; if (!s->droppable) s->next_picture_ptr = s->current_picture_ptr; } ff_dlog(s->avctx, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n", s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr, s->last_picture_ptr ? s->last_picture_ptr->f->data[0] : NULL, s->next_picture_ptr ? s->next_picture_ptr->f->data[0] : NULL, s->current_picture_ptr ? s->current_picture_ptr->f->data[0] : NULL, s->pict_type, s->droppable); if ((!s->last_picture_ptr || !s->last_picture_ptr->f->buf[0]) && (s->pict_type != AV_PICTURE_TYPE_I || s->picture_structure != PICT_FRAME)) { int h_chroma_shift, v_chroma_shift; av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &h_chroma_shift, &v_chroma_shift); if (s->pict_type != AV_PICTURE_TYPE_I) av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n"); else if (s->picture_structure != PICT_FRAME) av_log(avctx, AV_LOG_INFO, "allocate dummy last picture for field based first keyframe\n"); /* Allocate a dummy frame */ i = ff_find_unused_picture(s->avctx, s->picture, 0); if (i < 0) { av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n"); return i; } s->last_picture_ptr = &s->picture[i]; s->last_picture_ptr->reference = 3; s->last_picture_ptr->f->pict_type = AV_PICTURE_TYPE_I; if (alloc_picture(s, s->last_picture_ptr, 0) < 0) { s->last_picture_ptr = NULL; return -1; } memset(s->last_picture_ptr->f->data[0], 0, avctx->height * s->last_picture_ptr->f->linesize[0]); memset(s->last_picture_ptr->f->data[1], 0x80, (avctx->height >> v_chroma_shift) * s->last_picture_ptr->f->linesize[1]); memset(s->last_picture_ptr->f->data[2], 0x80, (avctx->height >> v_chroma_shift) * s->last_picture_ptr->f->linesize[2]); ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&s->last_picture_ptr->tf, INT_MAX, 1); } if ((!s->next_picture_ptr || !s->next_picture_ptr->f->buf[0]) && s->pict_type == AV_PICTURE_TYPE_B) { /* Allocate a dummy frame */ i = ff_find_unused_picture(s->avctx, s->picture, 0); if (i < 0) { av_log(s->avctx, AV_LOG_ERROR, "no frame buffer available\n"); return i; } s->next_picture_ptr = &s->picture[i]; s->next_picture_ptr->reference = 3; s->next_picture_ptr->f->pict_type = AV_PICTURE_TYPE_I; if (alloc_picture(s, s->next_picture_ptr, 0) < 0) { s->next_picture_ptr = NULL; return -1; } ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 0); ff_thread_report_progress(&s->next_picture_ptr->tf, INT_MAX, 1); } if (s->last_picture_ptr) { ff_mpeg_unref_picture(s->avctx, &s->last_picture); if (s->last_picture_ptr->f->buf[0] && (ret = ff_mpeg_ref_picture(s->avctx, &s->last_picture, s->last_picture_ptr)) < 0) return ret; } if (s->next_picture_ptr) { ff_mpeg_unref_picture(s->avctx, &s->next_picture); if (s->next_picture_ptr->f->buf[0] && (ret = ff_mpeg_ref_picture(s->avctx, &s->next_picture, s->next_picture_ptr)) < 0) return ret; } if (s->pict_type != AV_PICTURE_TYPE_I && !(s->last_picture_ptr && s->last_picture_ptr->f->buf[0])) { av_log(s, AV_LOG_ERROR, "Non-reference picture received and no reference available\n"); return AVERROR_INVALIDDATA; } if (s->picture_structure!= PICT_FRAME) { int i; for (i = 0; i < 4; i++) { if (s->picture_structure == PICT_BOTTOM_FIELD) { s->current_picture.f->data[i] += s->current_picture.f->linesize[i]; } s->current_picture.f->linesize[i] *= 2; s->last_picture.f->linesize[i] *= 2; s->next_picture.f->linesize[i] *= 2; } } /* set dequantizer, we can't do it during init as * it might change for MPEG-4 and we can't do it in the header * decode as init is not called for MPEG-4 there yet */ if (s->mpeg_quant || s->codec_id == AV_CODEC_ID_MPEG2VIDEO) { s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra; s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter; } else if (s->out_format == FMT_H263 || s->out_format == FMT_H261) { s->dct_unquantize_intra = s->dct_unquantize_h263_intra; s->dct_unquantize_inter = s->dct_unquantize_h263_inter; } else { s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra; s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter; } #if FF_API_XVMC FF_DISABLE_DEPRECATION_WARNINGS if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration) return ff_xvmc_field_start(s, avctx); FF_ENABLE_DEPRECATION_WARNINGS #endif /* FF_API_XVMC */ return 0; }


static guint io_add_watch_poll(GIOChannel *channel, IOCanReadHandler *fd_can_read, GIOFunc fd_read, gpointer user_data) { IOWatchPoll *iwp; iwp = (IOWatchPoll *) g_source_new(&io_watch_poll_funcs, sizeof(IOWatchPoll)); iwp->fd_can_read = fd_can_read; iwp->opaque = user_data; iwp->src = g_io_create_watch(channel, G_IO_IN | G_IO_ERR | G_IO_HUP); g_source_set_callback(iwp->src, (GSourceFunc)fd_read, user_data, NULL); return g_source_attach(&iwp->parent, NULL); }


int qio_channel_socket_dgram_sync(QIOChannelSocket *ioc, SocketAddress *localAddr, SocketAddress *remoteAddr, Error **errp) { int fd; trace_qio_channel_socket_dgram_sync(ioc, localAddr, remoteAddr); fd = socket_dgram(remoteAddr, localAddr, errp); if (fd < 0) { trace_qio_channel_socket_dgram_fail(ioc); return -1; } trace_qio_channel_socket_dgram_complete(ioc, fd); if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) { close(fd); return -1; } return 0; }


int ff_init_me(MpegEncContext *s){ MotionEstContext * const c= &s->me; int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<<ME_MAP_SHIFT); int dia_size= FFMAX(FFABS(s->avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255); if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -ME_MAP_SIZE){ av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n"); return -1; } //special case of snow is needed because snow uses its own iterative ME code if(s->me_method!=ME_ZERO && s->me_method!=ME_EPZS && s->me_method!=ME_X1 && s->avctx->codec_id != AV_CODEC_ID_SNOW){ av_log(s->avctx, AV_LOG_ERROR, "me_method is only allowed to be set to zero and epzs; for hex,umh,full and others see dia_size\n"); return -1; } c->avctx= s->avctx; if(cache_size < 2*dia_size && !c->stride){ av_log(s->avctx, AV_LOG_INFO, "ME_MAP size may be a little small for the selected diamond size\n"); } ff_set_cmp(&s->dsp, s->dsp.me_pre_cmp, c->avctx->me_pre_cmp); ff_set_cmp(&s->dsp, s->dsp.me_cmp, c->avctx->me_cmp); ff_set_cmp(&s->dsp, s->dsp.me_sub_cmp, c->avctx->me_sub_cmp); ff_set_cmp(&s->dsp, s->dsp.mb_cmp, c->avctx->mb_cmp); c->flags = get_flags(c, 0, c->avctx->me_cmp &FF_CMP_CHROMA); c->sub_flags= get_flags(c, 0, c->avctx->me_sub_cmp&FF_CMP_CHROMA); c->mb_flags = get_flags(c, 0, c->avctx->mb_cmp &FF_CMP_CHROMA); /*FIXME s->no_rounding b_type*/ if(s->flags&CODEC_FLAG_QPEL){ c->sub_motion_search= qpel_motion_search; c->qpel_avg= s->dsp.avg_qpel_pixels_tab; if(s->no_rounding) c->qpel_put= s->dsp.put_no_rnd_qpel_pixels_tab; else c->qpel_put= s->dsp.put_qpel_pixels_tab; }else{ if(c->avctx->me_sub_cmp&FF_CMP_CHROMA) c->sub_motion_search= hpel_motion_search; else if( c->avctx->me_sub_cmp == FF_CMP_SAD && c->avctx-> me_cmp == FF_CMP_SAD && c->avctx-> mb_cmp == FF_CMP_SAD) c->sub_motion_search= sad_hpel_motion_search; // 2050 vs. 2450 cycles else c->sub_motion_search= hpel_motion_search; } c->hpel_avg= s->dsp.avg_pixels_tab; if(s->no_rounding) c->hpel_put= s->dsp.put_no_rnd_pixels_tab; else c->hpel_put= s->dsp.put_pixels_tab; if(s->linesize){ c->stride = s->linesize; c->uvstride= s->uvlinesize; }else{ c->stride = 16*s->mb_width + 32; c->uvstride= 8*s->mb_width + 16; } /* 8x8 fullpel search would need a 4x4 chroma compare, which we do * not have yet, and even if we had, the motion estimation code * does not expect it. */ if(s->codec_id != AV_CODEC_ID_SNOW){ if((c->avctx->me_cmp&FF_CMP_CHROMA)/* && !s->dsp.me_cmp[2]*/){ s->dsp.me_cmp[2]= zero_cmp; } if((c->avctx->me_sub_cmp&FF_CMP_CHROMA) && !s->dsp.me_sub_cmp[2]){ s->dsp.me_sub_cmp[2]= zero_cmp; } c->hpel_put[2][0]= c->hpel_put[2][1]= c->hpel_put[2][2]= c->hpel_put[2][3]= zero_hpel; } if(s->codec_id == AV_CODEC_ID_H261){ c->sub_motion_search= no_sub_motion_search; } return 0; }


float32 float32_scalbn( float32 a, int n STATUS_PARAM ) { flag aSign; int16 aExp; uint32_t aSig; a = float32_squash_input_denormal(a STATUS_VAR); aSig = extractFloat32Frac( a ); aExp = extractFloat32Exp( a ); aSign = extractFloat32Sign( a ); if ( aExp == 0xFF ) { return a; } if ( aExp != 0 ) aSig |= 0x00800000; else if ( aSig == 0 ) return a; aExp += n - 1; aSig <<= 7; return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR ); }


void net_check_clients(void) { VLANState *vlan; VLANClientState *vc; int has_nic, has_host_dev; QTAILQ_FOREACH(vlan, &vlans, next) { QTAILQ_FOREACH(vc, &vlan->clients, next) { switch (vc->info->type) { case NET_CLIENT_TYPE_NIC: has_nic = 1; break; case NET_CLIENT_TYPE_SLIRP: case NET_CLIENT_TYPE_TAP: case NET_CLIENT_TYPE_SOCKET: case NET_CLIENT_TYPE_VDE: has_host_dev = 1; break; default: ; } } if (has_host_dev && !has_nic) fprintf(stderr, "Warning: vlan %d with no nics\n", vlan->id); if (has_nic && !has_host_dev) fprintf(stderr, "Warning: vlan %d is not connected to host network\n", vlan->id); } QTAILQ_FOREACH(vc, &non_vlan_clients, next) { if (!vc->peer) { fprintf(stderr, "Warning: %s %s has no peer\n", vc->info->type == NET_CLIENT_TYPE_NIC ? "nic" : "netdev", vc->name); } } }


static uint32_t hpet_time_after64(uint64_t a, uint64_t b) { return ((int64_t)(b) - (int64_t)(a) < 0); }


static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) { GICv3State *s = KVM_ARM_GICV3(dev); KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s); Error *local_err = NULL; DPRINTF("kvm_arm_gicv3_realize\n"); kgc->parent_realize(dev, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (s->security_extn) { error_setg(errp, "the in-kernel VGICv3 does not implement the " "security extensions"); return; } gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL); /* Try to create the device via the device control API */ s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V3, false); if (s->dev_fd < 0) { error_setg_errno(errp, -s->dev_fd, "error creating in-kernel VGIC"); return; } kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, &s->num_irq, true); /* Tell the kernel to complete VGIC initialization now */ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true); kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd); kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd); /* Block migration of a KVM GICv3 device: the API for saving and restoring * the state in the kernel is not yet finalised in the kernel or * implemented in QEMU. */ error_setg(&s->migration_blocker, "vGICv3 migration is not implemented"); migrate_add_blocker(s->migration_blocker); if (kvm_has_gsi_routing()) { /* set up irq routing */ kvm_init_irq_routing(kvm_state); for (i = 0; i < s->num_irq - GIC_INTERNAL; ++i) { kvm_irqchip_add_irq_route(kvm_state, i, 0, i); } kvm_gsi_routing_allowed = true; kvm_irqchip_commit_routes(kvm_state); } }


static TypeImpl *type_register_internal(const TypeInfo *info) { TypeImpl *ti = g_malloc0(sizeof(*ti)); int i; g_assert(info->name != NULL); if (type_table_lookup(info->name) != NULL) { fprintf(stderr, "Registering `%s' which already exists\n", info->name); abort(); } ti->name = g_strdup(info->name); ti->parent = g_strdup(info->parent); ti->class_size = info->class_size; ti->instance_size = info->instance_size; ti->class_init = info->class_init; ti->class_base_init = info->class_base_init; ti->class_finalize = info->class_finalize; ti->class_data = info->class_data; ti->instance_init = info->instance_init; ti->instance_post_init = info->instance_post_init; ti->instance_finalize = info->instance_finalize; ti->abstract = info->abstract; for (i = 0; info->interfaces && info->interfaces[i].type; i++) { ti->interfaces[i].typename = g_strdup(info->interfaces[i].type); } ti->num_interfaces = i; type_table_add(ti); return ti; }


static int disas_vfp_insn(CPUState * env, DisasContext *s, uint32_t insn) { uint32_t rd, rn, rm, op, i, n, offset, delta_d, delta_m, bank_mask; int dp, veclen; TCGv addr; TCGv tmp; TCGv tmp2; if (!arm_feature(env, ARM_FEATURE_VFP)) return 1; if (!vfp_enabled(env)) { /* VFP disabled. Only allow fmxr/fmrx to/from some control regs. */ if ((insn & 0x0fe00fff) != 0x0ee00a10) return 1; rn = (insn >> 16) & 0xf; if (rn != ARM_VFP_FPSID && rn != ARM_VFP_FPEXC && rn != ARM_VFP_MVFR1 && rn != ARM_VFP_MVFR0) return 1; } dp = ((insn & 0xf00) == 0xb00); switch ((insn >> 24) & 0xf) { case 0xe: if (insn & (1 << 4)) { /* single register transfer */ rd = (insn >> 12) & 0xf; if (dp) { int size; int pass; VFP_DREG_N(rn, insn); if (insn & 0xf) return 1; if (insn & 0x00c00060 && !arm_feature(env, ARM_FEATURE_NEON)) return 1; pass = (insn >> 21) & 1; if (insn & (1 << 22)) { size = 0; offset = ((insn >> 5) & 3) * 8; } else if (insn & (1 << 5)) { size = 1; offset = (insn & (1 << 6)) ? 16 : 0; } else { size = 2; offset = 0; } if (insn & ARM_CP_RW_BIT) { /* vfp->arm */ tmp = neon_load_reg(rn, pass); switch (size) { case 0: if (offset) tcg_gen_shri_i32(tmp, tmp, offset); if (insn & (1 << 23)) gen_uxtb(tmp); else gen_sxtb(tmp); break; case 1: if (insn & (1 << 23)) { if (offset) { tcg_gen_shri_i32(tmp, tmp, 16); } else { gen_uxth(tmp); } } else { if (offset) { tcg_gen_sari_i32(tmp, tmp, 16); } else { gen_sxth(tmp); } } break; case 2: break; } store_reg(s, rd, tmp); } else { /* arm->vfp */ tmp = load_reg(s, rd); if (insn & (1 << 23)) { /* VDUP */ if (size == 0) { gen_neon_dup_u8(tmp, 0); } else if (size == 1) { gen_neon_dup_low16(tmp); } for (n = 0; n <= pass * 2; n++) { tmp2 = new_tmp(); tcg_gen_mov_i32(tmp2, tmp); neon_store_reg(rn, n, tmp2); } neon_store_reg(rn, n, tmp); } else { /* VMOV */ switch (size) { case 0: tmp2 = neon_load_reg(rn, pass); gen_bfi(tmp, tmp2, tmp, offset, 0xff); dead_tmp(tmp2); break; case 1: tmp2 = neon_load_reg(rn, pass); gen_bfi(tmp, tmp2, tmp, offset, 0xffff); dead_tmp(tmp2); break; case 2: break; } neon_store_reg(rn, pass, tmp); } } } else { /* !dp */ if ((insn & 0x6f) != 0x00) return 1; rn = VFP_SREG_N(insn); if (insn & ARM_CP_RW_BIT) { /* vfp->arm */ if (insn & (1 << 21)) { /* system register */ rn >>= 1; switch (rn) { case ARM_VFP_FPSID: /* VFP2 allows access to FSID from userspace. VFP3 restricts all id registers to privileged accesses. */ if (IS_USER(s) && arm_feature(env, ARM_FEATURE_VFP3)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; case ARM_VFP_FPEXC: if (IS_USER(s)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; case ARM_VFP_FPINST: case ARM_VFP_FPINST2: /* Not present in VFP3. */ if (IS_USER(s) || arm_feature(env, ARM_FEATURE_VFP3)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; case ARM_VFP_FPSCR: if (rd == 15) { tmp = load_cpu_field(vfp.xregs[ARM_VFP_FPSCR]); tcg_gen_andi_i32(tmp, tmp, 0xf0000000); } else { tmp = new_tmp(); gen_helper_vfp_get_fpscr(tmp, cpu_env); } break; case ARM_VFP_MVFR0: case ARM_VFP_MVFR1: if (IS_USER(s) || !arm_feature(env, ARM_FEATURE_VFP3)) return 1; tmp = load_cpu_field(vfp.xregs[rn]); break; default: return 1; } } else { gen_mov_F0_vreg(0, rn); tmp = gen_vfp_mrs(); } if (rd == 15) { /* Set the 4 flag bits in the CPSR. */ gen_set_nzcv(tmp); dead_tmp(tmp); } else { store_reg(s, rd, tmp); } } else { /* arm->vfp */ tmp = load_reg(s, rd); if (insn & (1 << 21)) { rn >>= 1; /* system register */ switch (rn) { case ARM_VFP_FPSID: case ARM_VFP_MVFR0: case ARM_VFP_MVFR1: /* Writes are ignored. */ break; case ARM_VFP_FPSCR: gen_helper_vfp_set_fpscr(cpu_env, tmp); dead_tmp(tmp); gen_lookup_tb(s); break; case ARM_VFP_FPEXC: if (IS_USER(s)) return 1; store_cpu_field(tmp, vfp.xregs[rn]); gen_lookup_tb(s); break; case ARM_VFP_FPINST: case ARM_VFP_FPINST2: store_cpu_field(tmp, vfp.xregs[rn]); break; default: return 1; } } else { gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rn); } } } } else { /* data processing */ /* The opcode is in bits 23, 21, 20 and 6. */ op = ((insn >> 20) & 8) | ((insn >> 19) & 6) | ((insn >> 6) & 1); if (dp) { if (op == 15) { /* rn is opcode */ rn = ((insn >> 15) & 0x1e) | ((insn >> 7) & 1); } else { /* rn is register number */ VFP_DREG_N(rn, insn); } if (op == 15 && (rn == 15 || rn > 17)) { /* Integer or single precision destination. */ rd = VFP_SREG_D(insn); } else { VFP_DREG_D(rd, insn); } if (op == 15 && (rn == 16 || rn == 17)) { /* Integer source. */ rm = ((insn << 1) & 0x1e) | ((insn >> 5) & 1); } else { VFP_DREG_M(rm, insn); } } else { rn = VFP_SREG_N(insn); if (op == 15 && rn == 15) { /* Double precision destination. */ VFP_DREG_D(rd, insn); } else { rd = VFP_SREG_D(insn); } rm = VFP_SREG_M(insn); } veclen = env->vfp.vec_len; if (op == 15 && rn > 3) veclen = 0; /* Shut up compiler warnings. */ delta_m = 0; delta_d = 0; bank_mask = 0; if (veclen > 0) { if (dp) bank_mask = 0xc; else bank_mask = 0x18; /* Figure out what type of vector operation this is. */ if ((rd & bank_mask) == 0) { /* scalar */ veclen = 0; } else { if (dp) delta_d = (env->vfp.vec_stride >> 1) + 1; else delta_d = env->vfp.vec_stride + 1; if ((rm & bank_mask) == 0) { /* mixed scalar/vector */ delta_m = 0; } else { /* vector */ delta_m = delta_d; } } } /* Load the initial operands. */ if (op == 15) { switch (rn) { case 16: case 17: /* Integer source */ gen_mov_F0_vreg(0, rm); break; case 8: case 9: /* Compare */ gen_mov_F0_vreg(dp, rd); gen_mov_F1_vreg(dp, rm); break; case 10: case 11: /* Compare with zero */ gen_mov_F0_vreg(dp, rd); gen_vfp_F1_ld0(dp); break; case 20: case 21: case 22: case 23: case 28: case 29: case 30: case 31: /* Source and destination the same. */ gen_mov_F0_vreg(dp, rd); break; default: /* One source operand. */ gen_mov_F0_vreg(dp, rm); break; } } else { /* Two source operands. */ gen_mov_F0_vreg(dp, rn); gen_mov_F1_vreg(dp, rm); } for (;;) { /* Perform the calculation. */ switch (op) { case 0: /* mac: fd + (fn * fm) */ gen_vfp_mul(dp); gen_mov_F1_vreg(dp, rd); gen_vfp_add(dp); break; case 1: /* nmac: fd - (fn * fm) */ gen_vfp_mul(dp); gen_vfp_neg(dp); gen_mov_F1_vreg(dp, rd); gen_vfp_add(dp); break; case 2: /* msc: -fd + (fn * fm) */ gen_vfp_mul(dp); gen_mov_F1_vreg(dp, rd); gen_vfp_sub(dp); break; case 3: /* nmsc: -fd - (fn * fm) */ gen_vfp_mul(dp); gen_vfp_neg(dp); gen_mov_F1_vreg(dp, rd); gen_vfp_sub(dp); break; case 4: /* mul: fn * fm */ gen_vfp_mul(dp); break; case 5: /* nmul: -(fn * fm) */ gen_vfp_mul(dp); gen_vfp_neg(dp); break; case 6: /* add: fn + fm */ gen_vfp_add(dp); break; case 7: /* sub: fn - fm */ gen_vfp_sub(dp); break; case 8: /* div: fn / fm */ gen_vfp_div(dp); break; case 14: /* fconst */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; n = (insn << 12) & 0x80000000; i = ((insn >> 12) & 0x70) | (insn & 0xf); if (dp) { if (i & 0x40) i |= 0x3f80; else i |= 0x4000; n |= i << 16; tcg_gen_movi_i64(cpu_F0d, ((uint64_t)n) << 32); } else { if (i & 0x40) i |= 0x780; else i |= 0x800; n |= i << 19; tcg_gen_movi_i32(cpu_F0s, n); } break; case 15: /* extension space */ switch (rn) { case 0: /* cpy */ /* no-op */ break; case 1: /* abs */ gen_vfp_abs(dp); break; case 2: /* neg */ gen_vfp_neg(dp); break; case 3: /* sqrt */ gen_vfp_sqrt(dp); break; case 8: /* cmp */ gen_vfp_cmp(dp); break; case 9: /* cmpe */ gen_vfp_cmpe(dp); break; case 10: /* cmpz */ gen_vfp_cmp(dp); break; case 11: /* cmpez */ gen_vfp_F1_ld0(dp); gen_vfp_cmpe(dp); break; case 15: /* single<->double conversion */ if (dp) gen_helper_vfp_fcvtsd(cpu_F0s, cpu_F0d, cpu_env); else gen_helper_vfp_fcvtds(cpu_F0d, cpu_F0s, cpu_env); break; case 16: /* fuito */ gen_vfp_uito(dp); break; case 17: /* fsito */ gen_vfp_sito(dp); break; case 20: /* fshto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_shto(dp, 16 - rm); break; case 21: /* fslto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_slto(dp, 32 - rm); break; case 22: /* fuhto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_uhto(dp, 16 - rm); break; case 23: /* fulto */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_ulto(dp, 32 - rm); break; case 24: /* ftoui */ gen_vfp_toui(dp); break; case 25: /* ftouiz */ gen_vfp_touiz(dp); break; case 26: /* ftosi */ gen_vfp_tosi(dp); break; case 27: /* ftosiz */ gen_vfp_tosiz(dp); break; case 28: /* ftosh */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_tosh(dp, 16 - rm); break; case 29: /* ftosl */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_tosl(dp, 32 - rm); break; case 30: /* ftouh */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_touh(dp, 16 - rm); break; case 31: /* ftoul */ if (!arm_feature(env, ARM_FEATURE_VFP3)) return 1; gen_vfp_toul(dp, 32 - rm); break; default: /* undefined */ printf ("rn:%d\n", rn); return 1; } break; default: /* undefined */ printf ("op:%d\n", op); return 1; } /* Write back the result. */ if (op == 15 && (rn >= 8 && rn <= 11)) ; /* Comparison, do nothing. */ else if (op == 15 && rn > 17) /* Integer result. */ gen_mov_vreg_F0(0, rd); else if (op == 15 && rn == 15) /* conversion */ gen_mov_vreg_F0(!dp, rd); else gen_mov_vreg_F0(dp, rd); /* break out of the loop if we have finished */ if (veclen == 0) break; if (op == 15 && delta_m == 0) { /* single source one-many */ while (veclen--) { rd = ((rd + delta_d) & (bank_mask - 1)) | (rd & bank_mask); gen_mov_vreg_F0(dp, rd); } break; } /* Setup the next operands. */ veclen--; rd = ((rd + delta_d) & (bank_mask - 1)) | (rd & bank_mask); if (op == 15) { /* One source operand. */ rm = ((rm + delta_m) & (bank_mask - 1)) | (rm & bank_mask); gen_mov_F0_vreg(dp, rm); } else { /* Two source operands. */ rn = ((rn + delta_d) & (bank_mask - 1)) | (rn & bank_mask); gen_mov_F0_vreg(dp, rn); if (delta_m) { rm = ((rm + delta_m) & (bank_mask - 1)) | (rm & bank_mask); gen_mov_F1_vreg(dp, rm); } } } } break; case 0xc: case 0xd: if (dp && (insn & 0x03e00000) == 0x00400000) { /* two-register transfer */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; if (dp) { VFP_DREG_M(rm, insn); } else { rm = VFP_SREG_M(insn); } if (insn & ARM_CP_RW_BIT) { /* vfp->arm */ if (dp) { gen_mov_F0_vreg(0, rm * 2); tmp = gen_vfp_mrs(); store_reg(s, rd, tmp); gen_mov_F0_vreg(0, rm * 2 + 1); tmp = gen_vfp_mrs(); store_reg(s, rn, tmp); } else { gen_mov_F0_vreg(0, rm); tmp = gen_vfp_mrs(); store_reg(s, rn, tmp); gen_mov_F0_vreg(0, rm + 1); tmp = gen_vfp_mrs(); store_reg(s, rd, tmp); } } else { /* arm->vfp */ if (dp) { tmp = load_reg(s, rd); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm * 2); tmp = load_reg(s, rn); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm * 2 + 1); } else { tmp = load_reg(s, rn); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm); tmp = load_reg(s, rd); gen_vfp_msr(tmp); gen_mov_vreg_F0(0, rm + 1); } } } else { /* Load/store */ rn = (insn >> 16) & 0xf; if (dp) VFP_DREG_D(rd, insn); else rd = VFP_SREG_D(insn); if (s->thumb && rn == 15) { addr = new_tmp(); tcg_gen_movi_i32(addr, s->pc & ~2); } else { addr = load_reg(s, rn); } if ((insn & 0x01200000) == 0x01000000) { /* Single load/store */ offset = (insn & 0xff) << 2; if ((insn & (1 << 23)) == 0) offset = -offset; tcg_gen_addi_i32(addr, addr, offset); if (insn & (1 << 20)) { gen_vfp_ld(s, dp, addr); gen_mov_vreg_F0(dp, rd); } else { gen_mov_F0_vreg(dp, rd); gen_vfp_st(s, dp, addr); } dead_tmp(addr); } else { /* load/store multiple */ if (dp) n = (insn >> 1) & 0x7f; else n = insn & 0xff; if (insn & (1 << 24)) /* pre-decrement */ tcg_gen_addi_i32(addr, addr, -((insn & 0xff) << 2)); if (dp) offset = 8; else offset = 4; for (i = 0; i < n; i++) { if (insn & ARM_CP_RW_BIT) { /* load */ gen_vfp_ld(s, dp, addr); gen_mov_vreg_F0(dp, rd + i); } else { /* store */ gen_mov_F0_vreg(dp, rd + i); gen_vfp_st(s, dp, addr); } tcg_gen_addi_i32(addr, addr, offset); } if (insn & (1 << 21)) { /* writeback */ if (insn & (1 << 24)) offset = -offset * n; else if (dp && (insn & 1)) offset = 4; else offset = 0; if (offset != 0) tcg_gen_addi_i32(addr, addr, offset); store_reg(s, rn, addr); } else { dead_tmp(addr); } } } break; default: /* Should never happen. */ return 1; } return 0; }


void drive_hot_add(Monitor *mon, const QDict *qdict) { int dom, pci_bus; unsigned slot; int type, bus; PCIDevice *dev; DriveInfo *dinfo = NULL; const char *pci_addr = qdict_get_str(qdict, "pci_addr"); const char *opts = qdict_get_str(qdict, "opts"); BusState *scsibus; dinfo = add_init_drive(opts); if (!dinfo) goto err; if (dinfo->devaddr) { monitor_printf(mon, "Parameter addr not supported\n"); goto err; } type = dinfo->type; bus = drive_get_max_bus (type); switch (type) { case IF_SCSI: if (pci_read_devaddr(mon, pci_addr, &dom, &pci_bus, &slot)) { goto err; } dev = pci_find_device(pci_bus, slot, 0); if (!dev) { monitor_printf(mon, "no pci device with address %s\n", pci_addr); goto err; } scsibus = QLIST_FIRST(&dev->qdev.child_bus); scsi_bus_legacy_add_drive(DO_UPCAST(SCSIBus, qbus, scsibus), dinfo, dinfo->unit); monitor_printf(mon, "OK bus %d, unit %d\n", dinfo->bus, dinfo->unit); break; case IF_NONE: monitor_printf(mon, "OK\n"); break; default: monitor_printf(mon, "Can't hot-add drive to type %d\n", type); goto err; } return; err: if (dinfo) drive_uninit(dinfo); return; }