static void spapr_populate_cpu_dt(CPUState *cs, void *fdt, int offset,

                                  sPAPRMachineState *spapr)

{

    PowerPCCPU *cpu = POWERPC_CPU(cs);

    CPUPPCState *env = &cpu->env;

    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);

    int index = ppc_get_vcpu_dt_id(cpu);

    uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40),

                       0xffffffff, 0xffffffff};

    uint32_t tbfreq = kvm_enabled() ? kvmppc_get_tbfreq()

        : SPAPR_TIMEBASE_FREQ;

    uint32_t cpufreq = kvm_enabled() ? kvmppc_get_clockfreq() : 1000000000;

    uint32_t page_sizes_prop[64];

    size_t page_sizes_prop_size;

    uint32_t vcpus_per_socket = smp_threads * smp_cores;

    uint32_t pft_size_prop[] = {0, cpu_to_be32(spapr->htab_shift)};

    int compat_smt = MIN(smp_threads, ppc_compat_max_threads(cpu));

    sPAPRDRConnector *drc;

    sPAPRDRConnectorClass *drck;

    int drc_index;

    uint32_t radix_AP_encodings[PPC_PAGE_SIZES_MAX_SZ];

    int i;

    drc = spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, index);

    if (drc) {

        drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

        drc_index = drck->get_index(drc);

        _FDT((fdt_setprop_cell(fdt, offset, "ibm,my-drc-index", drc_index)));

    }

    _FDT((fdt_setprop_cell(fdt, offset, "reg", index)));

    _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu")));

    _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR])));

    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size",

                           env->dcache_line_size)));

    _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size",

                           env->dcache_line_size)));

    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size",

                           env->icache_line_size)));

    _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size",

                           env->icache_line_size)));

    if (pcc->l1_dcache_size) {

        _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size",

                               pcc->l1_dcache_size)));

    } else {

        error_report("Warning: Unknown L1 dcache size for cpu");

    }

    if (pcc->l1_icache_size) {

        _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size",

                               pcc->l1_icache_size)));

    } else {

        error_report("Warning: Unknown L1 icache size for cpu");

    }

    _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq)));

    _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq)));

    _FDT((fdt_setprop_cell(fdt, offset, "slb-size", env->slb_nr)));

    _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr)));

    _FDT((fdt_setprop_string(fdt, offset, "status", "okay")));

    _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0)));

    if (env->spr_cb[SPR_PURR].oea_read) {

        _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0)));

    }

    if (env->mmu_model & POWERPC_MMU_1TSEG) {

        _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes",

                          segs, sizeof(segs))));

    }

    /* Advertise VMX/VSX (vector extensions) if available

     *   0 / no property == no vector extensions

     *   1               == VMX / Altivec available

     *   2               == VSX available */

    if (env->insns_flags & PPC_ALTIVEC) {

        uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1;

        _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx)));

    }

    /* Advertise DFP (Decimal Floating Point) if available

     *   0 / no property == no DFP

     *   1               == DFP available */

    if (env->insns_flags2 & PPC2_DFP) {

        _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1)));

    }

    page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop,

                                                  sizeof(page_sizes_prop));

    if (page_sizes_prop_size) {

        _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes",

                          page_sizes_prop, page_sizes_prop_size)));

    }

    spapr_populate_pa_features(env, fdt, offset);

    _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id",

                           cs->cpu_index / vcpus_per_socket)));

    _FDT((fdt_setprop(fdt, offset, "ibm,pft-size",

                      pft_size_prop, sizeof(pft_size_prop))));

    _FDT(spapr_fixup_cpu_numa_dt(fdt, offset, cs));

    _FDT(spapr_fixup_cpu_smt_dt(fdt, offset, cpu, compat_smt));

    if (pcc->radix_page_info) {

        for (i = 0; i < pcc->radix_page_info->count; i++) {

            radix_AP_encodings[i] =

                cpu_to_be32(pcc->radix_page_info->entries[i]);

        }

        _FDT((fdt_setprop(fdt, offset, "ibm,processor-radix-AP-encodings",

                          radix_AP_encodings,

                          pcc->radix_page_info->count *

                          sizeof(radix_AP_encodings[0]))));

    }

}


static void test_function(const TestStruct test_sample)

{

    int ret, i;

    void **output_data  = NULL;

    AVAudioFifo *afifo  = av_audio_fifo_alloc(test_sample.format, test_sample.nb_ch,

                                            test_sample.nb_samples_pch);

    if (!afifo) {

        ERROR("ERROR: av_audio_fifo_alloc returned NULL!");

    }

    ret = write_samples_to_audio_fifo(afifo, test_sample, test_sample.nb_samples_pch, 0);

    if (ret < 0){

        ERROR("ERROR: av_audio_fifo_write failed!");

    }

    printf("written: %d\n", ret);

    ret = write_samples_to_audio_fifo(afifo, test_sample, test_sample.nb_samples_pch, 0);

    if (ret < 0){

        ERROR("ERROR: av_audio_fifo_write failed!");

    }

    printf("written: %d\n", ret);

    printf("remaining samples in audio_fifo: %d\n\n", av_audio_fifo_size(afifo));

    ret = read_samples_from_audio_fifo(afifo, &output_data, test_sample.nb_samples_pch);

    if (ret < 0){

        ERROR("ERROR: av_audio_fifo_read failed!");

    }

    printf("read: %d\n", ret);

    print_audio_bytes(&test_sample, output_data, ret);

    printf("remaining samples in audio_fifo: %d\n\n", av_audio_fifo_size(afifo));

    /* test av_audio_fifo_peek */

    ret = av_audio_fifo_peek(afifo, output_data, afifo->nb_samples);

    if (ret < 0){

        ERROR("ERROR: av_audio_fifo_peek failed!");

    }

    printf("peek:\n");

    print_audio_bytes(&test_sample, output_data, ret);

    printf("\n");

    /* test av_audio_fifo_peek_at */

    printf("peek_at:\n");

    for (i = 0; i < afifo->nb_samples; ++i){

        ret = av_audio_fifo_peek_at(afifo, output_data, 1, i);

        if (ret < 0){

            ERROR("ERROR: av_audio_fifo_peek_at failed!");

        }

        printf("%d:\n", i);

        print_audio_bytes(&test_sample, output_data, ret);

    }

    printf("\n");

    /* test av_audio_fifo_drain */

    ret = av_audio_fifo_drain(afifo, afifo->nb_samples);

    if (ret < 0){

        ERROR("ERROR: av_audio_fifo_drain failed!");

    }

    if (afifo->nb_samples){

        ERROR("drain failed to flush all samples in audio_fifo!");

    }

    /* deallocate */

    for (i = 0; i < afifo->nb_buffers; ++i){

        av_freep(&output_data[i]);

    }

    av_freep(&output_data);

    av_audio_fifo_free(afifo);

}


static void ff_wmv2_idct_put_c(uint8_t *dest, int line_size, DCTELEM *block)

{

    ff_wmv2_idct_c(block);

    put_pixels_clamped_c(block, dest, line_size);

}


static void decode_interframe_v4(AVCodecContext *avctx, uint8_t *src, uint32_t size)

{

    Hnm4VideoContext *hnm = avctx->priv_data;

    GetByteContext gb;

    uint32_t writeoffset = 0, count, left, offset;

    uint8_t tag, previous, backline, backward, swap;

    bytestream2_init(&gb, src, size);

    while (bytestream2_tell(&gb) < size) {

        count = bytestream2_peek_byte(&gb) & 0x1F;

        if (count == 0) {

            tag = bytestream2_get_byte(&gb) & 0xE0;

            tag = tag >> 5;

            if (tag == 0) {

                hnm->current[writeoffset++] = bytestream2_get_byte(&gb);

                hnm->current[writeoffset++] = bytestream2_get_byte(&gb);

            } else if (tag == 1) {

                writeoffset += bytestream2_get_byte(&gb) * 2;

            } else if (tag == 2) {

                count = bytestream2_get_le16(&gb);

                count *= 2;

                writeoffset += count;

            } else if (tag == 3) {

                count = bytestream2_get_byte(&gb) * 2;

                while (count > 0) {

                    hnm->current[writeoffset++] = bytestream2_peek_byte(&gb);

                    count--;

                }

                bytestream2_skip(&gb, 1);

            } else {

                break;

            }

        } else {

            previous = bytestream2_peek_byte(&gb) & 0x20;

            backline = bytestream2_peek_byte(&gb) & 0x40;

            backward = bytestream2_peek_byte(&gb) & 0x80;

            bytestream2_skip(&gb, 1);

            swap   = bytestream2_peek_byte(&gb) & 0x01;

            offset = bytestream2_get_le16(&gb);

            offset = (offset >> 1) & 0x7FFF;

            offset = writeoffset + (offset * 2) - 0x8000;

            left = count;

            if (!backward && offset + count >= hnm->width * hnm->height) {

                av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");

                break;

            } else if (backward && offset >= hnm->width * hnm->height) {

                av_log(avctx, AV_LOG_ERROR, "Attempting to read out of bounds");

                break;

            } else if (writeoffset + count >= hnm->width * hnm->height) {

                av_log(avctx, AV_LOG_ERROR,

                       "Attempting to write out of bounds");

                break;

            }

            if (previous) {

                while (left > 0) {

                    if (backline) {

                        hnm->current[writeoffset++] = hnm->previous[offset - (2 * hnm->width) + 1];

                        hnm->current[writeoffset++] = hnm->previous[offset++];

                        offset++;

                    } else {

                        hnm->current[writeoffset++] = hnm->previous[offset++];

                        hnm->current[writeoffset++] = hnm->previous[offset++];

                    }

                    if (backward)

                        offset -= 4;

                    left--;

                }

            } else {

                while (left > 0) {

                    if (backline) {

                        hnm->current[writeoffset++] = hnm->current[offset - (2 * hnm->width) + 1];

                        hnm->current[writeoffset++] = hnm->current[offset++];

                        offset++;

                    } else {

                        hnm->current[writeoffset++] = hnm->current[offset++];

                        hnm->current[writeoffset++] = hnm->current[offset++];

                    }

                    if (backward)

                        offset -= 4;

                    left--;

                }

            }

            if (swap) {

                left         = count;

                writeoffset -= count * 2;

                while (left > 0) {

                    swap = hnm->current[writeoffset];

                    hnm->current[writeoffset] = hnm->current[writeoffset + 1];

                    hnm->current[writeoffset + 1] = swap;

                    left--;

                    writeoffset += 2;

                }

            }

        }

    }

}


static void setup_frame(int sig, struct emulated_sigaction *ka,

			target_sigset_t *set, CPUX86State *env)

{

	struct sigframe *frame;

	int err = 0;

	frame = get_sigframe(ka, env, sizeof(*frame));

#if 0

	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))

		goto give_sigsegv;

#endif

	err |= __put_user((/*current->exec_domain

		           && current->exec_domain->signal_invmap

		           && sig < 32

		           ? current->exec_domain->signal_invmap[sig]

		           : */ sig),

		          &frame->sig);

	if (err)

		goto give_sigsegv;

	setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);

	if (err)

		goto give_sigsegv;

	if (TARGET_NSIG_WORDS > 1) {

		err |= __copy_to_user(frame->extramask, &set->sig[1],

				      sizeof(frame->extramask));

	}

	if (err)

		goto give_sigsegv;

	/* Set up to return from userspace.  If provided, use a stub

	   already in userspace.  */

	if (ka->sa.sa_flags & TARGET_SA_RESTORER) {

		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);

	} else {

		err |= __put_user(frame->retcode, &frame->pretcode);

		/* This is popl %eax ; movl $,%eax ; int $0x80 */

		err |= __put_user(0xb858, (short *)(frame->retcode+0));

		err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));

		err |= __put_user(0x80cd, (short *)(frame->retcode+6));

	}

	if (err)

		goto give_sigsegv;

	/* Set up registers for signal handler */

	env->regs[R_ESP] = (unsigned long) frame;

	env->eip = (unsigned long) ka->sa._sa_handler;

        cpu_x86_load_seg(env, R_DS, __USER_DS);

        cpu_x86_load_seg(env, R_ES, __USER_DS);

        cpu_x86_load_seg(env, R_SS, __USER_DS);

        cpu_x86_load_seg(env, R_CS, __USER_CS);

	env->eflags &= ~TF_MASK;

	return;

give_sigsegv:

	if (sig == TARGET_SIGSEGV)

		ka->sa._sa_handler = TARGET_SIG_DFL;

	force_sig(TARGET_SIGSEGV /* , current */);

}


static void write_target_close(BlockDriverState *bs) {

    BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);

    bdrv_delete(s->qcow);

    free(s->qcow_filename);

}


static int aiff_read_packet(AVFormatContext *s,
                            AVPacket *pkt)
{
    AVStream *st = s->streams[0];
    AIFFInputContext *aiff = s->priv_data;
    int64_t max_size;
    int res, size;
    /* calculate size of remaining data */
    max_size = aiff->data_end - avio_tell(s->pb);
    if (max_size <= 0)
        return AVERROR_EOF;
    /* Now for that packet */
    switch (st->codecpar->codec_id) {
    case AV_CODEC_ID_ADPCM_IMA_QT:
    case AV_CODEC_ID_GSM:
    case AV_CODEC_ID_QDM2:
    case AV_CODEC_ID_QCELP:
        size = st->codecpar->block_align;
        break;
    default:
        size = st->codecpar->block_align ? (MAX_SIZE / st->codecpar->block_align) * st->codecpar->block_align : MAX_SIZE;
    size = FFMIN(max_size, size);
    res = av_get_packet(s->pb, pkt, size);
    if (res < 0)
        return res;
    if (size >= st->codecpar->block_align)
        pkt->flags &= ~AV_PKT_FLAG_CORRUPT;
    /* Only one stream in an AIFF file */
    pkt->stream_index = 0;
    pkt->duration     = (res / st->codecpar->block_align) * aiff->block_duration;
    return 0;


uint64_t helper_fnmsub (uint64_t arg1, uint64_t arg2, uint64_t arg3)

{

    CPU_DoubleU farg1, farg2, farg3;

    farg1.ll = arg1;

    farg2.ll = arg2;

    farg3.ll = arg3;

    if (unlikely(float64_is_signaling_nan(farg1.d) ||

                 float64_is_signaling_nan(farg2.d) ||

                 float64_is_signaling_nan(farg3.d))) {

        /* sNaN operation */

        farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN);

    } else if (unlikely((float64_is_infinity(farg1.d) && float64_is_zero(farg2.d)) ||

                        (float64_is_zero(farg1.d) && float64_is_infinity(farg2.d)))) {

        /* Multiplication of zero by infinity */

        farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXIMZ);

    } else {

#if USE_PRECISE_EMULATION

#ifdef FLOAT128

        /* This is the way the PowerPC specification defines it */

        float128 ft0_128, ft1_128;

        ft0_128 = float64_to_float128(farg1.d, &env->fp_status);

        ft1_128 = float64_to_float128(farg2.d, &env->fp_status);

        ft0_128 = float128_mul(ft0_128, ft1_128, &env->fp_status);

        if (unlikely(float128_is_infinity(ft0_128) && float64_is_infinity(farg3.d) &&

                     float128_is_neg(ft0_128) == float64_is_neg(farg3.d))) {

            /* Magnitude subtraction of infinities */

            farg1.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXISI);

        } else {

            ft1_128 = float64_to_float128(farg3.d, &env->fp_status);

            ft0_128 = float128_sub(ft0_128, ft1_128, &env->fp_status);

            farg1.d = float128_to_float64(ft0_128, &env->fp_status);

        }

#else

        /* This is OK on x86 hosts */

        farg1.d = (farg1.d * farg2.d) - farg3.d;

#endif

#else

        farg1.d = float64_mul(farg1.d, farg2.d, &env->fp_status);

        farg1.d = float64_sub(farg1.d, farg3.d, &env->fp_status);

#endif

        if (likely(!float64_is_nan(farg1.d)))

            farg1.d = float64_chs(farg1.d);

    }

    return farg1.ll;

}


static void dec_modu(DisasContext *dc)

{

    int l1;

    LOG_DIS("modu r%d, r%d, %d\n", dc->r2, dc->r0, dc->r1);

    if (!(dc->features & LM32_FEATURE_DIVIDE)) {

        qemu_log_mask(LOG_GUEST_ERROR, "hardware divider is not available\n");

        t_gen_illegal_insn(dc);

        return;

    }

    l1 = gen_new_label();

    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[dc->r1], 0, l1);

    tcg_gen_movi_tl(cpu_pc, dc->pc);

    t_gen_raise_exception(dc, EXCP_DIVIDE_BY_ZERO);

    gen_set_label(l1);

    tcg_gen_remu_tl(cpu_R[dc->r2], cpu_R[dc->r0], cpu_R[dc->r1]);

}


static void omap_l4_io_writeb(void *opaque, target_phys_addr_t addr,

                uint32_t value)

{

    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;

    return omap_l4_io_writeb_fn[i](omap_l4_io_opaque[i], addr, value);

}


static void v9fs_create_post_lstat(V9fsState *s, V9fsCreateState *vs, int err)

{

    if (err == 0 || errno != ENOENT) {

        err = -errno;

        goto out;

    }

    if (vs->perm & P9_STAT_MODE_DIR) {

        err = v9fs_do_mkdir(s, vs);

        v9fs_create_post_mkdir(s, vs, err);

    } else if (vs->perm & P9_STAT_MODE_SYMLINK) {

        err = v9fs_do_symlink(s, vs);

        v9fs_create_post_perms(s, vs, err);

    } else if (vs->perm & P9_STAT_MODE_LINK) {

        int32_t nfid = atoi(vs->extension.data);

        V9fsFidState *nfidp = lookup_fid(s, nfid);

        if (nfidp == NULL) {

            err = -errno;

            v9fs_post_create(s, vs, err);

        }

        err = v9fs_do_link(s, &nfidp->path, &vs->fullname);

        v9fs_create_post_perms(s, vs, err);

    } else if (vs->perm & P9_STAT_MODE_DEVICE) {

        char ctype;

        uint32_t major, minor;

        mode_t nmode = 0;

        if (sscanf(vs->extension.data, "%c %u %u", &ctype, &major,

                                        &minor) != 3) {

            err = -errno;

            v9fs_post_create(s, vs, err);

        }

        switch (ctype) {

        case 'c':

            nmode = S_IFCHR;

            break;

        case 'b':

            nmode = S_IFBLK;

            break;

        default:

            err = -EIO;

            v9fs_post_create(s, vs, err);

        }

        nmode |= vs->perm & 0777;

        err = v9fs_do_mknod(s, vs, nmode, makedev(major, minor));

        v9fs_create_post_perms(s, vs, err);

    } else if (vs->perm & P9_STAT_MODE_NAMED_PIPE) {

        err = v9fs_do_mknod(s, vs, S_IFIFO | (vs->perm & 0777), 0);

        v9fs_post_create(s, vs, err);

    } else if (vs->perm & P9_STAT_MODE_SOCKET) {

        err = v9fs_do_mksock(s, &vs->fullname);

        v9fs_create_post_mksock(s, vs, err);

    } else {

        vs->fidp->fd = v9fs_do_open2(s, vs);

        v9fs_create_post_open2(s, vs, err);

    }

    return;

out:

    v9fs_post_create(s, vs, err);

}


target_ulong spapr_rtas_call(sPAPREnvironment *spapr,

                             uint32_t token, uint32_t nargs, target_ulong args,

                             uint32_t nret, target_ulong rets)

{

    if ((token >= TOKEN_BASE)

        && ((token - TOKEN_BASE) < TOKEN_MAX)) {

        struct rtas_call *call = rtas_table + (token - TOKEN_BASE);

        if (call->fn) {

            call->fn(spapr, token, nargs, args, nret, rets);

            return H_SUCCESS;

        }

    }

    /* HACK: Some Linux early debug code uses RTAS display-character,

     * but assumes the token value is 0xa (which it is on some real

     * machines) without looking it up in the device tree.  This

     * special case makes this work */

    if (token == 0xa) {

        rtas_display_character(spapr, 0xa, nargs, args, nret, rets);

        return H_SUCCESS;

    }

    hcall_dprintf("Unknown RTAS token 0x%x\n", token);

    rtas_st(rets, 0, -3);

    return H_PARAMETER;

}


static void apply_tns_filter(float *out, float *in, int order, int direction,

                             float *tns_coefs, int ltp_used, int w, int filt,

                             int start_i, int len)

{

    int i, j, inc, start = start_i;

    float tmp[TNS_MAX_ORDER+1];

    if (direction) {

        inc = -1;

        start = (start + len) - 1;

    } else {

        inc = 1;

    }

    if (!ltp_used) {    /* AR filter */

        for (i = 0; i < len; i++, start += inc)

            out[i] = in[start];

            for (j = 1; j <= FFMIN(i, order); j++)

                out[i] += tns_coefs[j]*in[start - j*inc];

    } else {            /* MA filter */

        for (i = 0; i < len; i++, start += inc) {

            tmp[0] = out[i] = in[start];

            for (j = 1; j <= FFMIN(i, order); j++)

                out[i] += tmp[j]*tns_coefs[j];

            for (j = order; j > 0; j--)

                tmp[j] = tmp[j - 1];

        }

    }

}


static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb,

                                AVPacket *pkt)

{

    MatroskaMuxContext *mkv = s->priv_data;

    int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size;

    uint8_t *start, *end, *data = pkt->data;

    ebml_master blockgroup;

    char buffer[2048];

    while (data_size) {

        int duration = ass_get_duration(data);

        max_duration = FFMAX(duration, max_duration);

        end          = memchr(data, '\n', data_size);

        size         = line_size = end ? end - data + 1 : data_size;

        size        -= end ? (end[-1] == '\r') + 1 : 0;

        start        = data;

        for (i = 0; i < 3; i++, start++)

            if (!(start = memchr(start, ',', size - (start - data))))

                return max_duration;

        size -= start - data;

        sscanf(data, "Dialogue: %d,", &layer);

        i = snprintf(buffer, sizeof(buffer), "%" PRId64 ",%d,",

                     s->streams[pkt->stream_index]->nb_frames, layer);

        size = FFMIN(i + size, sizeof(buffer));

        memcpy(buffer + i, start, size - i);

        av_log(s, AV_LOG_DEBUG,

               "Writing block at offset %" PRIu64 ", size %d, "

               "pts %" PRId64 ", duration %d\n",

               avio_tell(pb), size, pkt->pts, duration);

        blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP,

                                       mkv_blockgroup_size(size));

        put_ebml_id(pb, MATROSKA_ID_BLOCK);

        put_ebml_num(pb, size + 4, 0);

        // this assumes stream_index is less than 126

        avio_w8(pb, 0x80 | (pkt->stream_index + 1));

        avio_wb16(pb, pkt->pts - mkv->cluster_pts);

        avio_w8(pb, 0);

        avio_write(pb, buffer, size);

        put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);

        end_ebml_master(pb, blockgroup);

        data      += line_size;

        data_size -= line_size;

    }

    return max_duration;

}


static int ram_block_enable_notify(const char *block_name, void *host_addr,

                                   ram_addr_t offset, ram_addr_t length,

                                   void *opaque)

{

    MigrationIncomingState *mis = opaque;

    struct uffdio_register reg_struct;

    reg_struct.range.start = (uintptr_t)host_addr;

    reg_struct.range.len = length;

    reg_struct.mode = UFFDIO_REGISTER_MODE_MISSING;

    /* Now tell our userfault_fd that it's responsible for this area */

    if (ioctl(mis->userfault_fd, UFFDIO_REGISTER, &reg_struct)) {

        error_report("%s userfault register: %s", __func__, strerror(errno));

    return 0;


static void draw_bar_yuv(AVFrame *out, const float *h, const float *rcp_h,

                         const ColorFloat *c, int bar_h)

{

    int x, y, yh, w = out->width;

    float mul, ht, rcp_bar_h = 1.0f / bar_h;

    uint8_t *vy = out->data[0], *vu = out->data[1], *vv = out->data[2];

    uint8_t *lpy, *lpu, *lpv;

    int lsy = out->linesize[0], lsu = out->linesize[1], lsv = out->linesize[2];

    int fmt = out->format;

    for (y = 0; y < bar_h; y += 2) {

        yh = (fmt == AV_PIX_FMT_YUV420P) ? y / 2 : y;

        ht = (bar_h - y) * rcp_bar_h;

        lpy = vy + y * lsy;

        lpu = vu + yh * lsu;

        lpv = vv + yh * lsv;

        for (x = 0; x < w; x += 2) {

            if (h[x] <= ht) {

                *lpy++ = 16;

                *lpu++ = 128;

                *lpv++ = 128;

            } else {

                mul = (h[x] - ht) * rcp_h[x];

                *lpy++ = mul * c[x].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                *lpu++ = mul * c[x].yuv.u + (1.0f - mul) * 128.0f + 0.5f;

                *lpv++ = mul * c[x].yuv.v + (1.0f - mul) * 128.0f + 0.5f;

            }

            /* u and v are skipped on yuv422p and yuv420p */

            if (fmt == AV_PIX_FMT_YUV444P) {

                if (h[x+1] <= ht) {

                    *lpy++ = 16;

                    *lpu++ = 128;

                    *lpv++ = 128;

                } else {

                    mul = (h[x+1] - ht) * rcp_h[x+1];

                    *lpy++ = mul * c[x+1].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                    *lpu++ = mul * c[x+1].yuv.u + (1.0f - mul) * 128.0f + 0.5f;

                    *lpv++ = mul * c[x+1].yuv.v + (1.0f - mul) * 128.0f + 0.5f;

                }

            } else {

                if (h[x+1] <= ht) {

                    *lpy++ = 16;

                } else {

                    mul = (h[x+1] - ht) * rcp_h[x+1];

                    *lpy++ = mul * c[x+1].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                }

            }

        }

        ht = (bar_h - (y+1)) * rcp_bar_h;

        lpy = vy + (y+1) * lsy;

        lpu = vu + (y+1) * lsu;

        lpv = vv + (y+1) * lsv;

        for (x = 0; x < w; x += 2) {

            /* u and v are skipped on yuv420p */

            if (fmt != AV_PIX_FMT_YUV420P) {

                if (h[x] <= ht) {

                    *lpy++ = 16;

                    *lpu++ = 128;

                    *lpv++ = 128;

                } else {

                    mul = (h[x] - ht) * rcp_h[x];

                    *lpy++ = mul * c[x].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                    *lpu++ = mul * c[x].yuv.u + (1.0f - mul) * 128.0f + 0.5f;

                    *lpv++ = mul * c[x].yuv.v + (1.0f - mul) * 128.0f + 0.5f;

                }

            } else {

                if (h[x] <= ht) {

                    *lpy++ = 16;

                } else {

                    mul = (h[x] - ht) * rcp_h[x];

                    *lpy++ = mul * c[x].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                }

            }

            /* u and v are skipped on yuv422p and yuv420p */

            if (out->format == AV_PIX_FMT_YUV444P) {

                if (h[x+1] <= ht) {

                    *lpy++ = 16;

                    *lpu++ = 128;

                    *lpv++ = 128;

                } else {

                    mul = (h[x+1] - ht) * rcp_h[x+1];

                    *lpy++ = mul * c[x+1].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                    *lpu++ = mul * c[x+1].yuv.u + (1.0f - mul) * 128.0f + 0.5f;

                    *lpv++ = mul * c[x+1].yuv.v + (1.0f - mul) * 128.0f + 0.5f;

                }

            } else {

                if (h[x+1] <= ht) {

                    *lpy++ = 16;

                } else {

                    mul = (h[x+1] - ht) * rcp_h[x+1];

                    *lpy++ = mul * c[x+1].yuv.y + (1.0f - mul) * 16.0f + 0.5f;

                }

            }

        }

    }

}


static int qemu_chr_open_win_file_out(QemuOpts *opts, CharDriverState **_chr)

{

    const char *file_out = qemu_opt_get(opts, "path");

    HANDLE fd_out;

    fd_out = CreateFile(file_out, GENERIC_WRITE, FILE_SHARE_READ, NULL,

                        OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

    if (fd_out == INVALID_HANDLE_VALUE) {

        return -EIO;

    }

    return qemu_chr_open_win_file(fd_out, _chr);

}


int ff_h264_fill_default_ref_list(H264Context *h, H264SliceContext *sl)

{

    int i, len;

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {

        H264Picture *sorted[32];

        int cur_poc, list;

        int lens[2];

        if (FIELD_PICTURE(h))

            cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure == PICT_BOTTOM_FIELD];

        else

            cur_poc = h->cur_pic_ptr->poc;

        for (list = 0; list < 2; list++) {

            len  = add_sorted(sorted,       h->short_ref, h->short_ref_count, cur_poc, 1 ^ list);

            len += add_sorted(sorted + len, h->short_ref, h->short_ref_count, cur_poc, 0 ^ list);

            av_assert0(len <= 32);

            len  = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]),

                                  sorted, len, 0, h->picture_structure);

            len += build_def_list(h->default_ref_list[list] + len,

                                  FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,

                                  h->long_ref, 16, 1, h->picture_structure);

            av_assert0(len <= 32);

            if (len < sl->ref_count[list])

                memset(&h->default_ref_list[list][len], 0, sizeof(H264Ref) * (sl->ref_count[list] - len));

            lens[list] = len;

        }

        if (lens[0] == lens[1] && lens[1] > 1) {

            for (i = 0; i < lens[0] &&

                        h->default_ref_list[0][i].parent->f.buf[0]->buffer ==

                        h->default_ref_list[1][i].parent->f.buf[0]->buffer; i++);

            if (i == lens[0]) {

                FFSWAP(H264Ref, h->default_ref_list[1][0], h->default_ref_list[1][1]);

            }

        }

    } else {

        len  = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]),

                              h->short_ref, h->short_ref_count, 0, h->picture_structure);

        len += build_def_list(h->default_ref_list[0] + len,

                              FF_ARRAY_ELEMS(h->default_ref_list[0]) - len,

                              h-> long_ref, 16, 1, h->picture_structure);

        av_assert0(len <= 32);

        if (len < sl->ref_count[0])

            memset(&h->default_ref_list[0][len], 0, sizeof(H264Ref) * (sl->ref_count[0] - len));

    }

#ifdef TRACE

    for (i = 0; i < sl->ref_count[0]; i++) {

        tprintf(h->avctx, "List0: %s fn:%d 0x%p\n",

                (h->default_ref_list[0][i].parent->long_ref ? "LT" : "ST"),

                h->default_ref_list[0][i].pic_id,

                h->default_ref_list[0][i].parent->f.data[0]);

    }

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {

        for (i = 0; i < sl->ref_count[1]; i++) {

            tprintf(h->avctx, "List1: %s fn:%d 0x%p\n",

                    (h->default_ref_list[1][i].parent->long_ref ? "LT" : "ST"),

                    h->default_ref_list[1][i].pic_id,

                    h->default_ref_list[1][i].parent->f.data[0]);

        }

    }

#endif

    return 0;

}


static void vtd_init(IntelIOMMUState *s)

{

    X86IOMMUState *x86_iommu = X86_IOMMU_DEVICE(s);

    memset(s->csr, 0, DMAR_REG_SIZE);

    memset(s->wmask, 0, DMAR_REG_SIZE);

    memset(s->w1cmask, 0, DMAR_REG_SIZE);

    memset(s->womask, 0, DMAR_REG_SIZE);

    s->iommu_ops.translate = vtd_iommu_translate;

    s->iommu_ops.notify_started = vtd_iommu_notify_started;

    s->root = 0;

    s->root_extended = false;

    s->dmar_enabled = false;

    s->iq_head = 0;

    s->iq_tail = 0;

    s->iq = 0;

    s->iq_size = 0;

    s->qi_enabled = false;

    s->iq_last_desc_type = VTD_INV_DESC_NONE;

    s->next_frcd_reg = 0;

    s->cap = VTD_CAP_FRO | VTD_CAP_NFR | VTD_CAP_ND | VTD_CAP_MGAW |

             VTD_CAP_SAGAW | VTD_CAP_MAMV | VTD_CAP_PSI | VTD_CAP_SLLPS;

    s->ecap = VTD_ECAP_QI | VTD_ECAP_IRO;

    if (x86_iommu->intr_supported) {

        s->ecap |= VTD_ECAP_IR | VTD_ECAP_EIM;

    }

    vtd_reset_context_cache(s);

    vtd_reset_iotlb(s);

    /* Define registers with default values and bit semantics */

    vtd_define_long(s, DMAR_VER_REG, 0x10UL, 0, 0);

    vtd_define_quad(s, DMAR_CAP_REG, s->cap, 0, 0);

    vtd_define_quad(s, DMAR_ECAP_REG, s->ecap, 0, 0);

    vtd_define_long(s, DMAR_GCMD_REG, 0, 0xff800000UL, 0);

    vtd_define_long_wo(s, DMAR_GCMD_REG, 0xff800000UL);

    vtd_define_long(s, DMAR_GSTS_REG, 0, 0, 0);

    vtd_define_quad(s, DMAR_RTADDR_REG, 0, 0xfffffffffffff000ULL, 0);

    vtd_define_quad(s, DMAR_CCMD_REG, 0, 0xe0000003ffffffffULL, 0);

    vtd_define_quad_wo(s, DMAR_CCMD_REG, 0x3ffff0000ULL);

    /* Advanced Fault Logging not supported */

    vtd_define_long(s, DMAR_FSTS_REG, 0, 0, 0x11UL);

    vtd_define_long(s, DMAR_FECTL_REG, 0x80000000UL, 0x80000000UL, 0);

    vtd_define_long(s, DMAR_FEDATA_REG, 0, 0x0000ffffUL, 0);

    vtd_define_long(s, DMAR_FEADDR_REG, 0, 0xfffffffcUL, 0);

    /* Treated as RsvdZ when EIM in ECAP_REG is not supported

     * vtd_define_long(s, DMAR_FEUADDR_REG, 0, 0xffffffffUL, 0);

     */

    vtd_define_long(s, DMAR_FEUADDR_REG, 0, 0, 0);

    /* Treated as RO for implementations that PLMR and PHMR fields reported

     * as Clear in the CAP_REG.

     * vtd_define_long(s, DMAR_PMEN_REG, 0, 0x80000000UL, 0);

     */

    vtd_define_long(s, DMAR_PMEN_REG, 0, 0, 0);

    vtd_define_quad(s, DMAR_IQH_REG, 0, 0, 0);

    vtd_define_quad(s, DMAR_IQT_REG, 0, 0x7fff0ULL, 0);

    vtd_define_quad(s, DMAR_IQA_REG, 0, 0xfffffffffffff007ULL, 0);

    vtd_define_long(s, DMAR_ICS_REG, 0, 0, 0x1UL);

    vtd_define_long(s, DMAR_IECTL_REG, 0x80000000UL, 0x80000000UL, 0);

    vtd_define_long(s, DMAR_IEDATA_REG, 0, 0xffffffffUL, 0);

    vtd_define_long(s, DMAR_IEADDR_REG, 0, 0xfffffffcUL, 0);

    /* Treadted as RsvdZ when EIM in ECAP_REG is not supported */

    vtd_define_long(s, DMAR_IEUADDR_REG, 0, 0, 0);

    /* IOTLB registers */

    vtd_define_quad(s, DMAR_IOTLB_REG, 0, 0Xb003ffff00000000ULL, 0);

    vtd_define_quad(s, DMAR_IVA_REG, 0, 0xfffffffffffff07fULL, 0);

    vtd_define_quad_wo(s, DMAR_IVA_REG, 0xfffffffffffff07fULL);

    /* Fault Recording Registers, 128-bit */

    vtd_define_quad(s, DMAR_FRCD_REG_0_0, 0, 0, 0);

    vtd_define_quad(s, DMAR_FRCD_REG_0_2, 0, 0, 0x8000000000000000ULL);

    /*

     * Interrupt remapping registers.

     */

    vtd_define_quad(s, DMAR_IRTA_REG, 0, 0xfffffffffffff80fULL, 0);

}


const uint8_t *ff_h263_find_resync_marker(const uint8_t *av_restrict p, const uint8_t *av_restrict end)

{

    av_assert2(p < end);

    end-=2;

    p++;

    for(;p<end; p+=2){

        if(!*p){

            if     (!p[-1] && p[1]) return p - 1;

            else if(!p[ 1] && p[2]) return p;

        }

    }

    return end+2;

}


void helper_ctc1(CPUMIPSState *env, target_ulong arg1, uint32_t reg)

{

    switch(reg) {

    case 25:

        if (arg1 & 0xffffff00)

            return;

        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0x017fffff) | ((arg1 & 0xfe) << 24) |

                     ((arg1 & 0x1) << 23);

        break;

    case 26:

        if (arg1 & 0x007c0000)

            return;

        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfffc0f83) | (arg1 & 0x0003f07c);

        break;

    case 28:

        if (arg1 & 0x007c0000)

            return;

        env->active_fpu.fcr31 = (env->active_fpu.fcr31 & 0xfefff07c) | (arg1 & 0x00000f83) |

                     ((arg1 & 0x4) << 22);

        break;

    case 31:

        if (arg1 & 0x007c0000)

            return;

        env->active_fpu.fcr31 = arg1;

        break;

    default:

        return;

    }

    /* set rounding mode */

    restore_rounding_mode(env);

    /* set flush-to-zero mode */

    restore_flush_mode(env);

    set_float_exception_flags(0, &env->active_fpu.fp_status);

    if ((GET_FP_ENABLE(env->active_fpu.fcr31) | 0x20) & GET_FP_CAUSE(env->active_fpu.fcr31))

        do_raise_exception(env, EXCP_FPE, GETPC());

}


static void cpu_set_irq(void *opaque, int irq, int level)

{

    CPUState *env = opaque;

    if (level) {

        CPUIRQ_DPRINTF("Raise CPU IRQ %d\n", irq);

        env->halted = 0;

        env->pil_in |= 1 << irq;

        cpu_check_irqs(env);

    } else {

        CPUIRQ_DPRINTF("Lower CPU IRQ %d\n", irq);

        env->pil_in &= ~(1 << irq);

        cpu_check_irqs(env);

    }

}


static int get_stream_blocksize(BlockDriverState *bdrv)

{

    uint8_t cmd[6];

    uint8_t buf[12];

    uint8_t sensebuf[8];

    sg_io_hdr_t io_header;

    int ret;

    memset(cmd, 0, sizeof(cmd));

    memset(buf, 0, sizeof(buf));

    cmd[0] = MODE_SENSE;

    cmd[4] = sizeof(buf);

    memset(&io_header, 0, sizeof(io_header));

    io_header.interface_id = 'S';

    io_header.dxfer_direction = SG_DXFER_FROM_DEV;

    io_header.dxfer_len = sizeof(buf);

    io_header.dxferp = buf;

    io_header.cmdp = cmd;

    io_header.cmd_len = sizeof(cmd);

    io_header.mx_sb_len = sizeof(sensebuf);

    io_header.sbp = sensebuf;

    io_header.timeout = 6000; /* XXX */

    ret = bdrv_ioctl(bdrv, SG_IO, &io_header);

    if (ret < 0 || io_header.driver_status || io_header.host_status) {

        return -1;

    }

    return (buf[9] << 16) | (buf[10] << 8) | buf[11];

}


int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,

                                  int64_t size)

{

    int ret = qcow2_check_metadata_overlap(bs, ign, offset, size);

    if (ret < 0) {

        return ret;

    } else if (ret > 0) {

        int metadata_ol_bitnr = ffs(ret) - 1;

        assert(metadata_ol_bitnr < QCOW2_OL_MAX_BITNR);

        qcow2_signal_corruption(bs, true, offset, size, "Preventing invalid "

                                "write on metadata (overlaps with %s)",

                                metadata_ol_names[metadata_ol_bitnr]);

        return -EIO;

    }

    return 0;

}


int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)

{

    int i, ret;

    Picture *pic;

    s->mb_skipped = 0;

    if (!ff_thread_can_start_frame(avctx)) {

        av_log(avctx, AV_LOG_ERROR, "Attempt to start a frame outside SETUP state\n");

        return -1;

    }

    /* 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, s->last_picture_ptr);

    }

    /* release forgotten pictures */

    /* if (mpeg124/h263) */

    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) {

            if (!(avctx->active_thread_type & FF_THREAD_FRAME))

                av_log(avctx, AV_LOG_ERROR,

                       "releasing zombie picture\n");

            ff_mpeg_unref_picture(s, &s->picture[i]);

        }

    }

    ff_mpeg_unref_picture(s, &s->current_picture);

    release_unused_pictures(s);

    if (s->current_picture_ptr &&

        s->current_picture_ptr->f.buf[0] == NULL) {

        // 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, 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 (ff_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->flags && 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, &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;

    }

    av_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 == NULL ||

         s->last_picture_ptr->f.buf[0] == NULL) &&

        (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_B && s->next_picture_ptr && s->next_picture_ptr->f.buf[0])

            av_log(avctx, AV_LOG_DEBUG,

                   "allocating dummy last picture for B frame\n");

        else 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_DEBUG,

                   "allocate dummy last picture for field based first keyframe\n");

        /* Allocate a dummy frame */

        i = ff_find_unused_picture(s, 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.key_frame = 0;

        s->last_picture_ptr->f.pict_type = AV_PICTURE_TYPE_P;

        if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) {

            s->last_picture_ptr = NULL;

            return -1;

        }

        memset(s->last_picture_ptr->f.data[0], 0x80,

               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]);

        if(s->codec_id == AV_CODEC_ID_FLV1 || s->codec_id == AV_CODEC_ID_H263){

            for(i=0; i<avctx->height; i++)

            memset(s->last_picture_ptr->f.data[0] + s->last_picture_ptr->f.linesize[0]*i, 16, avctx->width);

        }

        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 == NULL ||

         s->next_picture_ptr->f.buf[0] == NULL) &&

        s->pict_type == AV_PICTURE_TYPE_B) {

        /* Allocate a dummy frame */

        i = ff_find_unused_picture(s, 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.key_frame = 0;

        s->next_picture_ptr->f.pict_type = AV_PICTURE_TYPE_P;

        if (ff_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 0 // BUFREF-FIXME

    memset(s->last_picture.f.data, 0, sizeof(s->last_picture.f.data));

    memset(s->next_picture.f.data, 0, sizeof(s->next_picture.f.data));

#endif

    if (s->last_picture_ptr) {

        ff_mpeg_unref_picture(s, &s->last_picture);

        if (s->last_picture_ptr->f.buf[0] &&

            (ret = ff_mpeg_ref_picture(s, &s->last_picture,

                                       s->last_picture_ptr)) < 0)

            return ret;

    }

    if (s->next_picture_ptr) {

        ff_mpeg_unref_picture(s, &s->next_picture);

        if (s->next_picture_ptr->f.buf[0] &&

            (ret = ff_mpeg_ref_picture(s, &s->next_picture,

                                       s->next_picture_ptr)) < 0)

            return ret;

    }

    av_assert0(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr &&

                                                 s->last_picture_ptr->f.buf[0]));

    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;

        }

    }

    s->err_recognition = avctx->err_recognition;

    /* set dequantizer, we can't do it during init as

     * it might change for mpeg4 and we can't do it in the header

     * decode as init is not called for mpeg4 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;

    }

    return 0;

}


static void co_write_request(void *opaque)

{

    BDRVSheepdogState *s = opaque;

    qemu_coroutine_enter(s->co_send, NULL);

}


static int decode_frame_ilbm(AVCodecContext *avctx,

                            void *data, int *data_size,

                            AVPacket *avpkt)

{

    IffContext *s = avctx->priv_data;

    const uint8_t *buf = avpkt->size >= 2 ? avpkt->data + AV_RB16(avpkt->data) : NULL;

    const int buf_size = avpkt->size >= 2 ? avpkt->size - AV_RB16(avpkt->data) : 0;

    const uint8_t *buf_end = buf+buf_size;

    int y, plane, res;

    if ((res = extract_header(avctx, avpkt)) < 0)

        return res;

    if (s->init) {

        if ((res = avctx->reget_buffer(avctx, &s->frame)) < 0) {

            av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n");

            return res;

        }

    } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return res;

    } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) {

        if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0)

            return res;

    }

    s->init = 1;

    if (avctx->codec_tag == MKTAG('A','C','B','M')) {

        if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {

            memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);

            for (plane = 0; plane < s->bpp; plane++) {

                for(y = 0; y < avctx->height && buf < buf_end; y++ ) {

                    uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];

                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);

                    buf += s->planesize;

                }

            }

        } else if (s->ham) { // HAM to PIX_FMT_BGR32

            memset(s->frame.data[0], 0, avctx->height * s->frame.linesize[0]);

            for(y = 0; y < avctx->height; y++) {

                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];

                memset(s->ham_buf, 0, s->planesize * 8);

                for (plane = 0; plane < s->bpp; plane++) {

                    const uint8_t * start = buf + (plane * avctx->height + y) * s->planesize;

                    if (start >= buf_end)

                        break;

                    decodeplane8(s->ham_buf, start, FFMIN(s->planesize, buf_end - start), plane);

                }

                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);

            }

        }

    } else if (avctx->codec_tag == MKTAG('D','E','E','P')) {

        int raw_width = avctx->width * (av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]) >> 3);

        int x;

        for(y = 0; y < avctx->height && buf < buf_end; y++ ) {

            uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];

            memcpy(row, buf, FFMIN(raw_width, buf_end - buf));

            buf += raw_width;

            if (avctx->pix_fmt == PIX_FMT_BGR32) {

                for(x = 0; x < avctx->width; x++)

                    row[4 * x + 3] = row[4 * x + 3] & 0xF0 | (row[4 * x + 3] >> 4);

            }

        }

    } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved

        if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {

            for(y = 0; y < avctx->height; y++ ) {

                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];

                memset(row, 0, avctx->width);

                for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {

                    decodeplane8(row, buf, FFMIN(s->planesize, buf_end - buf), plane);

                    buf += s->planesize;

                }

            }

        } else if (s->ham) { // HAM to PIX_FMT_BGR32

            for (y = 0; y < avctx->height; y++) {

                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];

                memset(s->ham_buf, 0, s->planesize * 8);

                for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {

                    decodeplane8(s->ham_buf, buf, FFMIN(s->planesize, buf_end - buf), plane);

                    buf += s->planesize;

                }

                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);

            }

        } else { // PIX_FMT_BGR32

            for(y = 0; y < avctx->height; y++ ) {

                uint8_t *row = &s->frame.data[0][y*s->frame.linesize[0]];

                memset(row, 0, avctx->width << 2);

                for (plane = 0; plane < s->bpp && buf < buf_end; plane++) {

                    decodeplane32((uint32_t *) row, buf, FFMIN(s->planesize, buf_end - buf), plane);

                    buf += s->planesize;

                }

            }

        }

    } else if (avctx->codec_tag == MKTAG('P','B','M',' ')) { // IFF-PBM

        if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) {

            for(y = 0; y < avctx->height; y++ ) {

                uint8_t *row = &s->frame.data[0][y * s->frame.linesize[0]];

                memcpy(row, buf, FFMIN(avctx->width, buf_end - buf));

                buf += avctx->width + (avctx->width % 2); // padding if odd

            }

        } else if (s->ham) { // IFF-PBM: HAM to PIX_FMT_BGR32

            for (y = 0; y < avctx->height; y++) {

                uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ];

                memcpy(s->ham_buf, buf, FFMIN(avctx->width, buf_end - buf));

                buf += avctx->width + (avctx->width & 1); // padding if odd

                decode_ham_plane32((uint32_t *) row, s->ham_buf, s->ham_palbuf, s->planesize);

            }

        } else {

            av_log_ask_for_sample(avctx, "unsupported bpp\n");

            return AVERROR_INVALIDDATA;

        }

    }

    *data_size = sizeof(AVFrame);

    *(AVFrame*)data = s->frame;

    return buf_size;

}


udp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr,

           u_int lport, int flags)

{

	struct sockaddr_in addr;

	struct socket *so;

	socklen_t addrlen = sizeof(struct sockaddr_in), opt = 1;

	so = socreate(slirp);

	if (!so) {

	    return NULL;

	}

	so->s = socket(AF_INET,SOCK_DGRAM,0);

	so->so_expire = curtime + SO_EXPIRE;

	insque(so, &slirp->udb);

	addr.sin_family = AF_INET;

	addr.sin_addr.s_addr = haddr;

	addr.sin_port = hport;

	if (bind(so->s,(struct sockaddr *)&addr, addrlen) < 0) {

		udp_detach(so);

		return NULL;

	}

	setsockopt(so->s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int));

	getsockname(so->s,(struct sockaddr *)&addr,&addrlen);

	so->so_fport = addr.sin_port;

	if (addr.sin_addr.s_addr == 0 ||

	    addr.sin_addr.s_addr == loopback_addr.s_addr) {

	   so->so_faddr = slirp->vhost_addr;

	} else {

	   so->so_faddr = addr.sin_addr;

	}

	so->so_lport = lport;

	so->so_laddr.s_addr = laddr;

	if (flags != SS_FACCEPTONCE)

	   so->so_expire = 0;

	so->so_state &= SS_PERSISTENT_MASK;

	so->so_state |= SS_ISFCONNECTED | flags;

	return so;

}


static uint32_t grlib_irqmp_readl(void *opaque, target_phys_addr_t addr)

{

    IRQMP      *irqmp = opaque;

    IRQMPState *state;

    assert(irqmp != NULL);

    state = irqmp->state;

    assert(state != NULL);

    addr &= 0xff;

    /* global registers */

    switch (addr) {

    case LEVEL_OFFSET:

        return state->level;

    case PENDING_OFFSET:

        return state->pending;

    case FORCE0_OFFSET:

        /* This register is an "alias" for the force register of CPU 0 */

        return state->force[0];

    case CLEAR_OFFSET:

    case MP_STATUS_OFFSET:

        /* Always read as 0 */

        return 0;

    case BROADCAST_OFFSET:

        return state->broadcast;

    default:

        break;

    }

    /* mask registers */

    if (addr >= MASK_OFFSET && addr < FORCE_OFFSET) {

        int cpu = (addr - MASK_OFFSET) / 4;

        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);

        return state->mask[cpu];

    }

    /* force registers */

    if (addr >= FORCE_OFFSET && addr < EXTENDED_OFFSET) {

        int cpu = (addr - FORCE_OFFSET) / 4;

        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);

        return state->force[cpu];

    }

    /* extended (not supported) */

    if (addr >= EXTENDED_OFFSET && addr < IRQMP_REG_SIZE) {

        int cpu = (addr - EXTENDED_OFFSET) / 4;

        assert(cpu >= 0 && cpu < IRQMP_MAX_CPU);

        return state->extended[cpu];

    }

    trace_grlib_irqmp_unknown_register("read", addr);

    return 0;

}


void qemu_sglist_destroy(QEMUSGList *qsg)

{

    g_free(qsg->sg);

}


static int virtio_9p_device_init(VirtIODevice *vdev)

{

    V9fsState *s = VIRTIO_9P(vdev);

    int i, len;

    struct stat stat;

    FsDriverEntry *fse;

    V9fsPath path;

    virtio_init(VIRTIO_DEVICE(s), "virtio-9p", VIRTIO_ID_9P,

                sizeof(struct virtio_9p_config) + MAX_TAG_LEN);

    /* initialize pdu allocator */

    QLIST_INIT(&s->free_list);

    QLIST_INIT(&s->active_list);

    for (i = 0; i < (MAX_REQ - 1); i++) {

        QLIST_INSERT_HEAD(&s->free_list, &s->pdus[i], next);

    }

    s->vq = virtio_add_queue(vdev, MAX_REQ, handle_9p_output);

    fse = get_fsdev_fsentry(s->fsconf.fsdev_id);

    if (!fse) {

        /* We don't have a fsdev identified by fsdev_id */

        fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "

                "id = %s\n",

                s->fsconf.fsdev_id ? s->fsconf.fsdev_id : "NULL");

        goto out;

    }

    if (!s->fsconf.tag) {

        /* we haven't specified a mount_tag */

        fprintf(stderr, "fsdev with id %s needs mount_tag arguments\n",

                s->fsconf.fsdev_id);

        goto out;

    }

    s->ctx.export_flags = fse->export_flags;

    s->ctx.fs_root = g_strdup(fse->path);

    s->ctx.exops.get_st_gen = NULL;

    len = strlen(s->fsconf.tag);

    if (len > MAX_TAG_LEN - 1) {

        fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "

                "maximum (%d bytes)", s->fsconf.tag, len, MAX_TAG_LEN - 1);

        goto out;

    }

    s->tag = g_strdup(s->fsconf.tag);

    s->ctx.uid = -1;

    s->ops = fse->ops;

    s->config_size = sizeof(struct virtio_9p_config) + len;

    s->fid_list = NULL;

    qemu_co_rwlock_init(&s->rename_lock);

    if (s->ops->init(&s->ctx) < 0) {

        fprintf(stderr, "Virtio-9p Failed to initialize fs-driver with id:%s"

                " and export path:%s\n", s->fsconf.fsdev_id, s->ctx.fs_root);

        goto out;

    }

    if (v9fs_init_worker_threads() < 0) {

        fprintf(stderr, "worker thread initialization failed\n");

        goto out;

    }

    /*

     * Check details of export path, We need to use fs driver

     * call back to do that. Since we are in the init path, we don't

     * use co-routines here.

     */

    v9fs_path_init(&path);

    if (s->ops->name_to_path(&s->ctx, NULL, "/", &path) < 0) {

        fprintf(stderr,

                "error in converting name to path %s", strerror(errno));

        goto out;

    }

    if (s->ops->lstat(&s->ctx, &path, &stat)) {

        fprintf(stderr, "share path %s does not exist\n", fse->path);

        goto out;

    } else if (!S_ISDIR(stat.st_mode)) {

        fprintf(stderr, "share path %s is not a directory\n", fse->path);

        goto out;

    }

    v9fs_path_free(&path);

    return 0;

out:

    g_free(s->ctx.fs_root);

    g_free(s->tag);

    virtio_cleanup(vdev);

    v9fs_path_free(&path);

    return -1;

}


static int v9fs_request(V9fsProxy *proxy, int type,

                        void *response, const char *fmt, ...)

{

    dev_t rdev;

    va_list ap;

    int size = 0;

    int retval = 0;

    uint64_t offset;

    ProxyHeader header = { 0, 0};

    struct timespec spec[2];

    int flags, mode, uid, gid;

    V9fsString *name, *value;

    V9fsString *path, *oldpath;

    struct iovec *iovec = NULL, *reply = NULL;

    qemu_mutex_lock(&proxy->mutex);

    if (proxy->sockfd == -1) {

        retval = -EIO;

        goto err_out;

    }

    iovec = &proxy->out_iovec;

    reply = &proxy->in_iovec;

    va_start(ap, fmt);

    switch (type) {

    case T_OPEN:

        path = va_arg(ap, V9fsString *);

        flags = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sd", path, flags);

        if (retval > 0) {

            header.size = retval;

            header.type = T_OPEN;

        }

        break;

    case T_CREATE:

        path = va_arg(ap, V9fsString *);

        flags = va_arg(ap, int);

        mode = va_arg(ap, int);

        uid = va_arg(ap, int);

        gid = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sdddd", path,

                                    flags, mode, uid, gid);

        if (retval > 0) {

            header.size = retval;

            header.type = T_CREATE;

        }

        break;

    case T_MKNOD:

        path = va_arg(ap, V9fsString *);

        mode = va_arg(ap, int);

        rdev = va_arg(ap, long int);

        uid = va_arg(ap, int);

        gid = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ddsdq",

                                    uid, gid, path, mode, rdev);

        if (retval > 0) {

            header.size = retval;

            header.type = T_MKNOD;

        }

        break;

    case T_MKDIR:

        path = va_arg(ap, V9fsString *);

        mode = va_arg(ap, int);

        uid = va_arg(ap, int);

        gid = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ddsd",

                                    uid, gid, path, mode);

        if (retval > 0) {

            header.size = retval;

            header.type = T_MKDIR;

        }

        break;

    case T_SYMLINK:

        oldpath = va_arg(ap, V9fsString *);

        path = va_arg(ap, V9fsString *);

        uid = va_arg(ap, int);

        gid = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ddss",

                                    uid, gid, oldpath, path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_SYMLINK;

        }

        break;

    case T_LINK:

        oldpath = va_arg(ap, V9fsString *);

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ss",

                                    oldpath, path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_LINK;

        }

        break;

    case T_LSTAT:

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "s", path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_LSTAT;

        }

        break;

    case T_READLINK:

        path = va_arg(ap, V9fsString *);

        size = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sd", path, size);

        if (retval > 0) {

            header.size = retval;

            header.type = T_READLINK;

        }

        break;

    case T_STATFS:

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "s", path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_STATFS;

        }

        break;

    case T_CHMOD:

        path = va_arg(ap, V9fsString *);

        mode = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sd", path, mode);

        if (retval > 0) {

            header.size = retval;

            header.type = T_CHMOD;

        }

        break;

    case T_CHOWN:

        path = va_arg(ap, V9fsString *);

        uid = va_arg(ap, int);

        gid = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sdd", path, uid, gid);

        if (retval > 0) {

            header.size = retval;

            header.type = T_CHOWN;

        }

        break;

    case T_TRUNCATE:

        path = va_arg(ap, V9fsString *);

        offset = va_arg(ap, uint64_t);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sq", path, offset);

        if (retval > 0) {

            header.size = retval;

            header.type = T_TRUNCATE;

        }

        break;

    case T_UTIME:

        path = va_arg(ap, V9fsString *);

        spec[0].tv_sec = va_arg(ap, long);

        spec[0].tv_nsec = va_arg(ap, long);

        spec[1].tv_sec = va_arg(ap, long);

        spec[1].tv_nsec = va_arg(ap, long);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sqqqq", path,

                                    spec[0].tv_sec, spec[1].tv_nsec,

                                    spec[1].tv_sec, spec[1].tv_nsec);

        if (retval > 0) {

            header.size = retval;

            header.type = T_UTIME;

        }

        break;

    case T_RENAME:

        oldpath = va_arg(ap, V9fsString *);

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ss", oldpath, path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_RENAME;

        }

        break;

    case T_REMOVE:

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "s", path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_REMOVE;

        }

        break;

    case T_LGETXATTR:

        size = va_arg(ap, int);

        path = va_arg(ap, V9fsString *);

        name = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ,

                                    "dss", size, path, name);

        if (retval > 0) {

            header.size = retval;

            header.type = T_LGETXATTR;

        }

        break;

    case T_LLISTXATTR:

        size = va_arg(ap, int);

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ds", size, path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_LLISTXATTR;

        }

        break;

    case T_LSETXATTR:

        path = va_arg(ap, V9fsString *);

        name = va_arg(ap, V9fsString *);

        value = va_arg(ap, V9fsString *);

        size = va_arg(ap, int);

        flags = va_arg(ap, int);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "sssdd",

                                    path, name, value, size, flags);

        if (retval > 0) {

            header.size = retval;

            header.type = T_LSETXATTR;

        }

        break;

    case T_LREMOVEXATTR:

        path = va_arg(ap, V9fsString *);

        name = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "ss", path, name);

        if (retval > 0) {

            header.size = retval;

            header.type = T_LREMOVEXATTR;

        }

        break;

    case T_GETVERSION:

        path = va_arg(ap, V9fsString *);

        retval = proxy_marshal(iovec, PROXY_HDR_SZ, "s", path);

        if (retval > 0) {

            header.size = retval;

            header.type = T_GETVERSION;

        }

        break;

    default:

        error_report("Invalid type %d", type);

        retval = -EINVAL;

        break;

    }

    va_end(ap);

    if (retval < 0) {

        goto err_out;

    }

    /* marshal the header details */

    proxy_marshal(iovec, 0, "dd", header.type, header.size);

    header.size += PROXY_HDR_SZ;

    retval = qemu_write_full(proxy->sockfd, iovec->iov_base, header.size);

    if (retval != header.size) {

        goto close_error;

    }

    switch (type) {

    case T_OPEN:

    case T_CREATE:

        /*

         * A file descriptor is returned as response for

         * T_OPEN,T_CREATE on success

         */

        if (v9fs_receivefd(proxy->sockfd, &retval) < 0) {

            goto close_error;

        }

        break;

    case T_MKNOD:

    case T_MKDIR:

    case T_SYMLINK:

    case T_LINK:

    case T_CHMOD:

    case T_CHOWN:

    case T_RENAME:

    case T_TRUNCATE:

    case T_UTIME:

    case T_REMOVE:

    case T_LSETXATTR:

    case T_LREMOVEXATTR:

        if (v9fs_receive_status(proxy, reply, &retval) < 0) {

            goto close_error;

        }

        break;

    case T_LSTAT:

    case T_READLINK:

    case T_STATFS:

    case T_GETVERSION:

        if (v9fs_receive_response(proxy, type, &retval, response) < 0) {

            goto close_error;

        }

        break;

    case T_LGETXATTR:

    case T_LLISTXATTR:

        if (!size) {

            if (v9fs_receive_status(proxy, reply, &retval) < 0) {

                goto close_error;

            }

        } else {

            if (v9fs_receive_response(proxy, type, &retval, response) < 0) {

                goto close_error;

            }

        }

        break;

    }

err_out:

    qemu_mutex_unlock(&proxy->mutex);

    return retval;

close_error:

    close(proxy->sockfd);

    proxy->sockfd = -1;

    qemu_mutex_unlock(&proxy->mutex);

    return -EIO;

}


static void scsi_req_set_status(SCSIDiskReq *r, int status, int sense_code)

{

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    r->req.status = status;

    scsi_disk_set_sense(s, sense_code);

}


static inline void sdhci_blkgap_write(SDHCIState *s, uint8_t value)

{

    if ((value & SDHC_STOP_AT_GAP_REQ) && (s->blkgap & SDHC_STOP_AT_GAP_REQ)) {

        return;

    }

    s->blkgap = value & SDHC_STOP_AT_GAP_REQ;

    if ((value & SDHC_CONTINUE_REQ) && s->stopped_state &&

            (s->blkgap & SDHC_STOP_AT_GAP_REQ) == 0) {

        if (s->stopped_state == sdhc_gap_read) {

            s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_READ;

            SDHCI_GET_CLASS(s)->read_block_from_card(s);

        } else {

            s->prnsts |= SDHC_DAT_LINE_ACTIVE | SDHC_DOING_WRITE;

            SDHCI_GET_CLASS(s)->write_block_to_card(s);

        }

        s->stopped_state = sdhc_not_stopped;

    } else if (!s->stopped_state && (value & SDHC_STOP_AT_GAP_REQ)) {

        if (s->prnsts & SDHC_DOING_READ) {

            s->stopped_state = sdhc_gap_read;

        } else if (s->prnsts & SDHC_DOING_WRITE) {

            s->stopped_state = sdhc_gap_write;

        }

    }

}


static void qemu_chr_parse_vc(QemuOpts *opts, ChardevBackend *backend,

                              Error **errp)

{

    int val;

    backend->vc = g_new0(ChardevVC, 1);

    val = qemu_opt_get_number(opts, "width", 0);

    if (val != 0) {

        backend->vc->has_width = true;

        backend->vc->width = val;

    }

    val = qemu_opt_get_number(opts, "height", 0);

    if (val != 0) {

        backend->vc->has_height = true;

        backend->vc->height = val;

    }

    val = qemu_opt_get_number(opts, "cols", 0);

    if (val != 0) {

        backend->vc->has_cols = true;

        backend->vc->cols = val;

    }

    val = qemu_opt_get_number(opts, "rows", 0);

    if (val != 0) {

        backend->vc->has_rows = true;

        backend->vc->rows = val;

    }

}


static unsigned int find_best(struct vf_instance *vf){

  int is_format_okay = vf->next->query_format(vf->next, IMGFMT_YV12);

  if ((is_format_okay & VFCAP_CSP_SUPPORTED_BY_HW) || (is_format_okay & VFCAP_CSP_SUPPORTED))

    return IMGFMT_YV12;

  else

    return 0;

}


void helper_idivl_EAX_T0(void)

{

    int den, q, r;

    int64_t num;

    num = ((uint32_t)EAX) | ((uint64_t)((uint32_t)EDX) << 32);

    den = T0;

    if (den == 0) {

        raise_exception(EXCP00_DIVZ);

    }

#ifdef BUGGY_GCC_DIV64

    r = idiv32(&q, num, den);

#else

    q = (num / den);

    r = (num % den);

#endif

    EAX = (uint32_t)q;

    EDX = (uint32_t)r;

}


static int fourxm_probe(AVProbeData *p)

{

    if (p->buf_size < 12)

        return 0;

    if ((AV_RL32(&p->buf[0]) != RIFF_TAG) ||

        (AV_RL32(&p->buf[8]) != _4XMV_TAG))

        return 0;

    return AVPROBE_SCORE_MAX;

}


static void jpeg_table_header(AVCodecContext *avctx, PutBitContext *p,

                              ScanTable *intra_scantable,

                              uint16_t luma_intra_matrix[64],

                              uint16_t chroma_intra_matrix[64],

                              int hsample[3])

{

    int i, j, size;

    uint8_t *ptr;

    MpegEncContext *s = avctx->priv_data;

    if (avctx->codec_id != AV_CODEC_ID_LJPEG) {

        int matrix_count = 1 + !!memcmp(luma_intra_matrix,

                                        chroma_intra_matrix,

                                        sizeof(luma_intra_matrix[0]) * 64);

    if (s->force_duplicated_matrix)

        matrix_count = 2;

    /* quant matrixes */

    put_marker(p, DQT);

    put_bits(p, 16, 2 + matrix_count * (1 + 64));

    put_bits(p, 4, 0); /* 8 bit precision */

    put_bits(p, 4, 0); /* table 0 */

    for(i=0;i<64;i++) {

        j = intra_scantable->permutated[i];

        put_bits(p, 8, luma_intra_matrix[j]);

    }

        if (matrix_count > 1) {

            put_bits(p, 4, 0); /* 8 bit precision */

            put_bits(p, 4, 1); /* table 1 */

            for(i=0;i<64;i++) {

                j = intra_scantable->permutated[i];

                put_bits(p, 8, chroma_intra_matrix[j]);

            }

        }

    }

    if(avctx->active_thread_type & FF_THREAD_SLICE){

        put_marker(p, DRI);

        put_bits(p, 16, 4);

        put_bits(p, 16, (avctx->width-1)/(8*hsample[0]) + 1);

    }

    /* huffman table */

    put_marker(p, DHT);

    flush_put_bits(p);

    ptr = put_bits_ptr(p);

    put_bits(p, 16, 0); /* patched later */

    size = 2;

    // Only MJPEG can have a variable Huffman variable. All other

    // formats use the default Huffman table.

    if (s->out_format == FMT_MJPEG && s->huffman == HUFFMAN_TABLE_OPTIMAL) {

        size += put_huffman_table(p, 0, 0, s->mjpeg_ctx->bits_dc_luminance,

                                  s->mjpeg_ctx->val_dc_luminance);

        size += put_huffman_table(p, 0, 1, s->mjpeg_ctx->bits_dc_chrominance,

                                  s->mjpeg_ctx->val_dc_chrominance);

        size += put_huffman_table(p, 1, 0, s->mjpeg_ctx->bits_ac_luminance,

                                  s->mjpeg_ctx->val_ac_luminance);

        size += put_huffman_table(p, 1, 1, s->mjpeg_ctx->bits_ac_chrominance,

                                  s->mjpeg_ctx->val_ac_chrominance);

    } else {

        size += put_huffman_table(p, 0, 0, avpriv_mjpeg_bits_dc_luminance,

                                  avpriv_mjpeg_val_dc);

        size += put_huffman_table(p, 0, 1, avpriv_mjpeg_bits_dc_chrominance,

                                  avpriv_mjpeg_val_dc);

        size += put_huffman_table(p, 1, 0, avpriv_mjpeg_bits_ac_luminance,

                                  avpriv_mjpeg_val_ac_luminance);

        size += put_huffman_table(p, 1, 1, avpriv_mjpeg_bits_ac_chrominance,

                                  avpriv_mjpeg_val_ac_chrominance);

    }

    AV_WB16(ptr, size);

}


static void ppc_spapr_init(MachineState *machine)

{

    sPAPRMachineState *spapr = SPAPR_MACHINE(machine);

    sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(machine);

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    PowerPCCPU *cpu;

    PCIHostState *phb;

    int i;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *rma_region;

    void *rma = NULL;

    hwaddr rma_alloc_size;

    hwaddr node0_size = spapr_node0_size();

    uint32_t initrd_base = 0;

    long kernel_size = 0, initrd_size = 0;

    long load_limit, fw_size;

    bool kernel_le = false;

    char *filename;

    msi_supported = true;

    QLIST_INIT(&spapr->phbs);

    cpu_ppc_hypercall = emulate_spapr_hypercall;

    /* Allocate RMA if necessary */

    rma_alloc_size = kvmppc_alloc_rma(&rma);

    if (rma_alloc_size == -1) {

        error_report("Unable to create RMA");

        exit(1);

    }

    if (rma_alloc_size && (rma_alloc_size < node0_size)) {

        spapr->rma_size = rma_alloc_size;

    } else {

        spapr->rma_size = node0_size;

        /* With KVM, we don't actually know whether KVM supports an

         * unbounded RMA (PR KVM) or is limited by the hash table size

         * (HV KVM using VRMA), so we always assume the latter

         *

         * In that case, we also limit the initial allocations for RTAS

         * etc... to 256M since we have no way to know what the VRMA size

         * is going to be as it depends on the size of the hash table

         * isn't determined yet.

         */

        if (kvm_enabled()) {

            spapr->vrma_adjust = 1;

            spapr->rma_size = MIN(spapr->rma_size, 0x10000000);

        }

    }

    if (spapr->rma_size > node0_size) {

        error_report("Numa node 0 has to span the RMA (%#08"HWADDR_PRIx")",

                     spapr->rma_size);

        exit(1);

    }

    /* Setup a load limit for the ramdisk leaving room for SLOF and FDT */

    load_limit = MIN(spapr->rma_size, RTAS_MAX_ADDR) - FW_OVERHEAD;

    /* We aim for a hash table of size 1/128 the size of RAM.  The

     * normal rule of thumb is 1/64 the size of RAM, but that's much

     * more than needed for the Linux guests we support. */

    spapr->htab_shift = 18; /* Minimum architected size */

    while (spapr->htab_shift <= 46) {

        if ((1ULL << (spapr->htab_shift + 7)) >= machine->maxram_size) {

            break;

        }

        spapr->htab_shift++;

    }

    spapr_alloc_htab(spapr);

    /* Set up Interrupt Controller before we create the VCPUs */

    spapr->icp = xics_system_init(machine,

                                  DIV_ROUND_UP(max_cpus * kvmppc_smt_threads(),

                                               smp_threads),

                                  XICS_IRQS, &error_fatal);

    if (smc->dr_lmb_enabled) {

        spapr_validate_node_memory(machine, &error_fatal);

    }

    /* init CPUs */

    if (machine->cpu_model == NULL) {

        machine->cpu_model = kvm_enabled() ? "host" : "POWER7";

    }

    for (i = 0; i < smp_cpus; i++) {

        cpu = cpu_ppc_init(machine->cpu_model);

        if (cpu == NULL) {

            error_report("Unable to find PowerPC CPU definition");

            exit(1);

        }

        spapr_cpu_init(spapr, cpu, &error_fatal);

    }

    if (kvm_enabled()) {

        /* Enable H_LOGICAL_CI_* so SLOF can talk to in-kernel devices */

        kvmppc_enable_logical_ci_hcalls();

        kvmppc_enable_set_mode_hcall();

    }

    /* allocate RAM */

    memory_region_allocate_system_memory(ram, NULL, "ppc_spapr.ram",

                                         machine->ram_size);

    memory_region_add_subregion(sysmem, 0, ram);

    if (rma_alloc_size && rma) {

        rma_region = g_new(MemoryRegion, 1);

        memory_region_init_ram_ptr(rma_region, NULL, "ppc_spapr.rma",

                                   rma_alloc_size, rma);

        vmstate_register_ram_global(rma_region);

        memory_region_add_subregion(sysmem, 0, rma_region);

    }

    /* initialize hotplug memory address space */

    if (machine->ram_size < machine->maxram_size) {

        ram_addr_t hotplug_mem_size = machine->maxram_size - machine->ram_size;

        if (machine->ram_slots > SPAPR_MAX_RAM_SLOTS) {

            error_report("Specified number of memory slots %"

                         PRIu64" exceeds max supported %d",

                         machine->ram_slots, SPAPR_MAX_RAM_SLOTS);

            exit(1);

        }

        spapr->hotplug_memory.base = ROUND_UP(machine->ram_size,

                                              SPAPR_HOTPLUG_MEM_ALIGN);

        memory_region_init(&spapr->hotplug_memory.mr, OBJECT(spapr),

                           "hotplug-memory", hotplug_mem_size);

        memory_region_add_subregion(sysmem, spapr->hotplug_memory.base,

                                    &spapr->hotplug_memory.mr);

    }

    if (smc->dr_lmb_enabled) {

        spapr_create_lmb_dr_connectors(spapr);

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");

    if (!filename) {

        error_report("Could not find LPAR rtas '%s'", "spapr-rtas.bin");

        exit(1);

    }

    spapr->rtas_size = get_image_size(filename);

    spapr->rtas_blob = g_malloc(spapr->rtas_size);

    if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {

        error_report("Could not load LPAR rtas '%s'", filename);

        exit(1);

    }

    if (spapr->rtas_size > RTAS_MAX_SIZE) {

        error_report("RTAS too big ! 0x%zx bytes (max is 0x%x)",

                     (size_t)spapr->rtas_size, RTAS_MAX_SIZE);

        exit(1);

    }

    g_free(filename);

    /* Set up EPOW events infrastructure */

    spapr_events_init(spapr);

    /* Set up the RTC RTAS interfaces */

    spapr_rtc_create(spapr);

    /* Set up VIO bus */

    spapr->vio_bus = spapr_vio_bus_init();

    for (i = 0; i < MAX_SERIAL_PORTS; i++) {

        if (serial_hds[i]) {

            spapr_vty_create(spapr->vio_bus, serial_hds[i]);

        }

    }

    /* We always have at least the nvram device on VIO */

    spapr_create_nvram(spapr);

    /* Set up PCI */

    spapr_pci_rtas_init();

    phb = spapr_create_phb(spapr, 0);

    for (i = 0; i < nb_nics; i++) {

        NICInfo *nd = &nd_table[i];

        if (!nd->model) {

            nd->model = g_strdup("ibmveth");

        }

        if (strcmp(nd->model, "ibmveth") == 0) {

            spapr_vlan_create(spapr->vio_bus, nd);

        } else {

            pci_nic_init_nofail(&nd_table[i], phb->bus, nd->model, NULL);

        }

    }

    for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {

        spapr_vscsi_create(spapr->vio_bus);

    }

    /* Graphics */

    if (spapr_vga_init(phb->bus, &error_fatal)) {

        spapr->has_graphics = true;

        machine->usb |= defaults_enabled() && !machine->usb_disabled;

    }

    if (machine->usb) {

        if (smc->use_ohci_by_default) {

            pci_create_simple(phb->bus, -1, "pci-ohci");

        } else {

            pci_create_simple(phb->bus, -1, "nec-usb-xhci");

        }

        if (spapr->has_graphics) {

            USBBus *usb_bus = usb_bus_find(-1);

            usb_create_simple(usb_bus, "usb-kbd");

            usb_create_simple(usb_bus, "usb-mouse");

        }

    }

    if (spapr->rma_size < (MIN_RMA_SLOF << 20)) {

        error_report(

            "pSeries SLOF firmware requires >= %ldM guest RMA (Real Mode Area memory)",

            MIN_RMA_SLOF);

        exit(1);

    }

    if (kernel_filename) {

        uint64_t lowaddr = 0;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,

                               NULL, &lowaddr, NULL, 1, PPC_ELF_MACHINE, 0);

        if (kernel_size == ELF_LOAD_WRONG_ENDIAN) {

            kernel_size = load_elf(kernel_filename,

                                   translate_kernel_address, NULL,

                                   NULL, &lowaddr, NULL, 0, PPC_ELF_MACHINE, 0);

            kernel_le = kernel_size > 0;

        }

        if (kernel_size < 0) {

            error_report("error loading %s: %s",

                         kernel_filename, load_elf_strerror(kernel_size));

            exit(1);

        }

        /* load initrd */

        if (initrd_filename) {

            /* Try to locate the initrd in the gap between the kernel

             * and the firmware. Add a bit of space just in case

             */

            initrd_base = (KERNEL_LOAD_ADDR + kernel_size + 0x1ffff) & ~0xffff;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              load_limit - initrd_base);

            if (initrd_size < 0) {

                error_report("could not load initial ram disk '%s'",

                             initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

    }

    if (bios_name == NULL) {

        bios_name = FW_FILE_NAME;

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    if (!filename) {

        error_report("Could not find LPAR firmware '%s'", bios_name);

        exit(1);

    }

    fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);

    if (fw_size <= 0) {

        error_report("Could not load LPAR firmware '%s'", filename);

        exit(1);

    }

    g_free(filename);

    /* FIXME: Should register things through the MachineState's qdev

     * interface, this is a legacy from the sPAPREnvironment structure

     * which predated MachineState but had a similar function */

    vmstate_register(NULL, 0, &vmstate_spapr, spapr);

    register_savevm_live(NULL, "spapr/htab", -1, 1,

                         &savevm_htab_handlers, spapr);

    /* Prepare the device tree */

    spapr->fdt_skel = spapr_create_fdt_skel(initrd_base, initrd_size,

                                            kernel_size, kernel_le,

                                            kernel_cmdline,

                                            spapr->check_exception_irq);

    assert(spapr->fdt_skel != NULL);

    /* used by RTAS */

    QTAILQ_INIT(&spapr->ccs_list);

    qemu_register_reset(spapr_ccs_reset_hook, spapr);

    qemu_register_boot_set(spapr_boot_set, spapr);

}


static void n8x0_nand_setup(struct n800_s *s)

{

    char *otp_region;

    DriveInfo *dinfo;

    s->nand = qdev_create(NULL, "onenand");

    qdev_prop_set_uint16(s->nand, "manufacturer_id", NAND_MFR_SAMSUNG);

    /* Either 0x40 or 0x48 are OK for the device ID */

    qdev_prop_set_uint16(s->nand, "device_id", 0x48);

    qdev_prop_set_uint16(s->nand, "version_id", 0);

    qdev_prop_set_int32(s->nand, "shift", 1);

    dinfo = drive_get(IF_MTD, 0, 0);

    if (dinfo) {

        qdev_prop_set_drive_nofail(s->nand, "drive",

                                   blk_bs(blk_by_legacy_dinfo(dinfo)));

    }

    qdev_init_nofail(s->nand);

    sysbus_connect_irq(SYS_BUS_DEVICE(s->nand), 0,

                       qdev_get_gpio_in(s->mpu->gpio, N8X0_ONENAND_GPIO));

    omap_gpmc_attach(s->mpu->gpmc, N8X0_ONENAND_CS,

                     sysbus_mmio_get_region(SYS_BUS_DEVICE(s->nand), 0));

    otp_region = onenand_raw_otp(s->nand);

    memcpy(otp_region + 0x000, n8x0_cal_wlan_mac, sizeof(n8x0_cal_wlan_mac));

    memcpy(otp_region + 0x800, n8x0_cal_bt_id, sizeof(n8x0_cal_bt_id));

    /* XXX: in theory should also update the OOB for both pages */

}


void cpu_dump_state (CPUState *env, FILE *f,

                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),

                     int flags)

{

    uint32_t c0_status;

    int i;

    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",

                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);

    for (i = 0; i < 32; i++) {

        if ((i & 3) == 0)

            cpu_fprintf(f, "GPR%02d:", i);

        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);

        if ((i & 3) == 3)

            cpu_fprintf(f, "\n");

    }

    c0_status = env->CP0_Status;

    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",

                c0_status, env->CP0_Cause, env->CP0_EPC);

    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",

                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);

    if (c0_status & (1 << CP0St_CU1))

        fpu_dump_state(env, f, cpu_fprintf, flags);

#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)

    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);

#endif

}


static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info,

        int *need_next_header, int *new_frame_start)

{

    GetBitContext bits;

    AACADTSHeaderInfo hdr;

    int size;

    union {

        uint64_t u64;

        uint8_t  u8[8];

    } tmp;

    tmp.u64 = av_be2ne64(state);

    init_get_bits(&bits, tmp.u8+8-AAC_ADTS_HEADER_SIZE, AAC_ADTS_HEADER_SIZE * 8);

    if ((size = avpriv_aac_parse_header(&bits, &hdr)) < 0)

        return 0;

    *need_next_header = 0;

    *new_frame_start  = 1;

    hdr_info->sample_rate = hdr.sample_rate;

    hdr_info->channels    = ff_mpeg4audio_channels[hdr.chan_config];

    hdr_info->samples     = hdr.samples;

    hdr_info->bit_rate    = hdr.bit_rate;

    return size;

}


uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,

                       int sign)

{

    uint64_t ret = 0;

#if defined(DEBUG_ASI)

    target_ulong last_addr = addr;

#endif

    if (asi < 0x80) {

        helper_raise_exception(env, TT_PRIV_ACT);

    }

    helper_check_align(env, addr, size - 1);

    addr = asi_address_mask(env, asi, addr);

    switch (asi) {

    case 0x82: /* Primary no-fault */

    case 0x8a: /* Primary no-fault LE */

        if (page_check_range(addr, size, PAGE_READ) == -1) {

#ifdef DEBUG_ASI

            dump_asi("read ", last_addr, asi, size, ret);

#endif

            return 0;

        }

        /* Fall through */

    case 0x80: /* Primary */

    case 0x88: /* Primary LE */

        {

            switch (size) {

            case 1:

                ret = ldub_raw(addr);

                break;

            case 2:

                ret = lduw_raw(addr);

                break;

            case 4:

                ret = ldl_raw(addr);

                break;

            default:

            case 8:

                ret = ldq_raw(addr);

                break;

            }

        }

        break;

    case 0x83: /* Secondary no-fault */

    case 0x8b: /* Secondary no-fault LE */

        if (page_check_range(addr, size, PAGE_READ) == -1) {

#ifdef DEBUG_ASI

            dump_asi("read ", last_addr, asi, size, ret);

#endif

            return 0;

        }

        /* Fall through */

    case 0x81: /* Secondary */

    case 0x89: /* Secondary LE */

        /* XXX */

        break;

    default:

        break;

    }

    /* Convert from little endian */

    switch (asi) {

    case 0x88: /* Primary LE */

    case 0x89: /* Secondary LE */

    case 0x8a: /* Primary no-fault LE */

    case 0x8b: /* Secondary no-fault LE */

        switch (size) {

        case 2:

            ret = bswap16(ret);

            break;

        case 4:

            ret = bswap32(ret);

            break;

        case 8:

            ret = bswap64(ret);

            break;

        default:

            break;

        }

    default:

        break;

    }

    /* Convert to signed number */

    if (sign) {

        switch (size) {

        case 1:

            ret = (int8_t) ret;

            break;

        case 2:

            ret = (int16_t) ret;

            break;

        case 4:

            ret = (int32_t) ret;

            break;

        default:

            break;

        }

    }

#ifdef DEBUG_ASI

    dump_asi("read ", last_addr, asi, size, ret);

#endif

    return ret;

}


static av_cold int vc2_encode_init(AVCodecContext *avctx)

{

    Plane *p;

    SubBand *b;

    int i, j, level, o, shift, ret;

    const AVPixFmtDescriptor *fmt = av_pix_fmt_desc_get(avctx->pix_fmt);

    const int depth = fmt->comp[0].depth;

    VC2EncContext *s = avctx->priv_data;

    s->picture_number = 0;

    /* Total allowed quantization range */

    s->q_ceil    = DIRAC_MAX_QUANT_INDEX;

    s->ver.major = 2;

    s->ver.minor = 0;

    s->profile   = 3;

    s->level     = 3;

    s->base_vf   = -1;

    s->strict_compliance = 1;

    s->q_avg = 0;

    s->slice_max_bytes = 0;

    s->slice_min_bytes = 0;

    /* Mark unknown as progressive */

    s->interlaced = !((avctx->field_order == AV_FIELD_UNKNOWN) ||

                      (avctx->field_order == AV_FIELD_PROGRESSIVE));

    for (i = 0; i < base_video_fmts_len; i++) {

        const VC2BaseVideoFormat *fmt = &base_video_fmts[i];

        if (avctx->pix_fmt != fmt->pix_fmt)

            continue;

        if (avctx->time_base.num != fmt->time_base.num)

            continue;

        if (avctx->time_base.den != fmt->time_base.den)

            continue;

        if (avctx->width != fmt->width)

            continue;

        if (avctx->height != fmt->height)

            continue;

        if (s->interlaced != fmt->interlaced)

            continue;

        s->base_vf = i;

        s->level   = base_video_fmts[i].level;

        break;

    }

    if (s->interlaced)

        av_log(avctx, AV_LOG_WARNING, "Interlacing enabled!\n");

    if ((s->slice_width  & (s->slice_width  - 1)) ||

        (s->slice_height & (s->slice_height - 1))) {

        av_log(avctx, AV_LOG_ERROR, "Slice size is not a power of two!\n");

        return AVERROR_UNKNOWN;

    }

    if ((s->slice_width > avctx->width) ||

        (s->slice_height > avctx->height)) {

        av_log(avctx, AV_LOG_ERROR, "Slice size is bigger than the image!\n");

        return AVERROR_UNKNOWN;

    }

    if (s->base_vf <= 0) {

        if (avctx->strict_std_compliance < FF_COMPLIANCE_STRICT) {

            s->strict_compliance = s->base_vf = 0;

            av_log(avctx, AV_LOG_WARNING, "Format does not strictly comply with VC2 specs\n");

        } else {

            av_log(avctx, AV_LOG_WARNING, "Given format does not strictly comply with "

                   "the specifications, decrease strictness to use it.\n");

            return AVERROR_UNKNOWN;

        }

    } else {

        av_log(avctx, AV_LOG_INFO, "Selected base video format = %i (%s)\n",

               s->base_vf, base_video_fmts[s->base_vf].name);

    }

    /* Chroma subsampling */

    ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift);

    if (ret)

        return ret;

    /* Bit depth and color range index */

    if (depth == 8 && avctx->color_range == AVCOL_RANGE_JPEG) {

        s->bpp = 1;

        s->bpp_idx = 1;

        s->diff_offset = 128;

    } else if (depth == 8 && (avctx->color_range == AVCOL_RANGE_MPEG ||

               avctx->color_range == AVCOL_RANGE_UNSPECIFIED)) {

        s->bpp = 1;

        s->bpp_idx = 2;

        s->diff_offset = 128;

    } else if (depth == 10) {

        s->bpp = 2;

        s->bpp_idx = 3;

        s->diff_offset = 512;

    } else {

        s->bpp = 2;

        s->bpp_idx = 4;

        s->diff_offset = 2048;

    }

    /* Planes initialization */

    for (i = 0; i < 3; i++) {

        int w, h;

        p = &s->plane[i];

        p->width      = avctx->width  >> (i ? s->chroma_x_shift : 0);

        p->height     = avctx->height >> (i ? s->chroma_y_shift : 0);

        if (s->interlaced)

            p->height >>= 1;

        p->dwt_width  = w = FFALIGN(p->width,  (1 << s->wavelet_depth));

        p->dwt_height = h = FFALIGN(p->height, (1 << s->wavelet_depth));

        p->coef_stride = FFALIGN(p->dwt_width, 32);

        p->coef_buf = av_malloc(p->coef_stride*p->dwt_height*sizeof(dwtcoef));

        if (!p->coef_buf)

            goto alloc_fail;

        for (level = s->wavelet_depth-1; level >= 0; level--) {

            w = w >> 1;

            h = h >> 1;

            for (o = 0; o < 4; o++) {

                b = &p->band[level][o];

                b->width  = w;

                b->height = h;

                b->stride = p->coef_stride;

                shift = (o > 1)*b->height*b->stride + (o & 1)*b->width;

                b->buf = p->coef_buf + shift;

            }

        }

        /* DWT init */

        if (ff_vc2enc_init_transforms(&s->transform_args[i].t,

                                      s->plane[i].coef_stride,

                                      s->plane[i].dwt_height))

            goto alloc_fail;

    }

    /* Slices */

    s->num_x = s->plane[0].dwt_width/s->slice_width;

    s->num_y = s->plane[0].dwt_height/s->slice_height;

    s->slice_args = av_calloc(s->num_x*s->num_y, sizeof(SliceArgs));

    if (!s->slice_args)

        goto alloc_fail;

    /* Lookup tables */

    s->coef_lut_len = av_malloc(COEF_LUT_TAB*(s->q_ceil+1)*sizeof(*s->coef_lut_len));

    if (!s->coef_lut_len)

        goto alloc_fail;

    s->coef_lut_val = av_malloc(COEF_LUT_TAB*(s->q_ceil+1)*sizeof(*s->coef_lut_val));

    if (!s->coef_lut_val)

        goto alloc_fail;

    for (i = 0; i < s->q_ceil; i++) {

        uint8_t  *len_lut = &s->coef_lut_len[i*COEF_LUT_TAB];

        uint32_t *val_lut = &s->coef_lut_val[i*COEF_LUT_TAB];

        for (j = 0; j < COEF_LUT_TAB; j++) {

            get_vc2_ue_uint(QUANT(j, ff_dirac_qscale_tab[i]),

                            &len_lut[j], &val_lut[j]);

            if (len_lut[j] != 1) {

                len_lut[j] += 1;

                val_lut[j] <<= 1;

            } else {

                val_lut[j] = 1;

            }

        }

    }

    return 0;

alloc_fail:

    vc2_encode_end(avctx);

    av_log(avctx, AV_LOG_ERROR, "Unable to allocate memory!\n");

    return AVERROR(ENOMEM);

}


static av_cold int rv40_decode_init(AVCodecContext *avctx)

{

    RV34DecContext *r = avctx->priv_data;

    r->rv30 = 0;

    ff_rv34_decode_init(avctx);

    if(!aic_top_vlc.bits)

        rv40_init_tables();

    r->parse_slice_header = rv40_parse_slice_header;

    r->decode_intra_types = rv40_decode_intra_types;

    r->decode_mb_info     = rv40_decode_mb_info;

    r->loop_filter        = rv40_loop_filter;

    r->luma_dc_quant_i = rv40_luma_dc_quant[0];

    r->luma_dc_quant_p = rv40_luma_dc_quant[1];

    return 0;

}


static void spr_write_dbatu_h (void *opaque, int sprn)

{

    DisasContext *ctx = opaque;

    gen_op_store_dbatu((sprn - SPR_DBAT4U) / 2);

    RET_STOP(ctx);

}


sprintf_len(char *string, const char *format, ...)

#else

sprintf_len(va_alist) va_dcl

#endif

{

	va_list args;

#ifdef __STDC__

	va_start(args, format);

#else

	char *string;

	char *format;

	va_start(args);

	string = va_arg(args, char *);

	format = va_arg(args, char *);

#endif

	vsprintf(string, format, args);

	return strlen(string);

}