static int commit_one_file(BDRVVVFATState* s,

	int dir_index, uint32_t offset)

{

    direntry_t* direntry = array_get(&(s->directory), dir_index);

    uint32_t c = begin_of_direntry(direntry);

    uint32_t first_cluster = c;

    mapping_t* mapping = find_mapping_for_cluster(s, c);

    uint32_t size = filesize_of_direntry(direntry);

    char* cluster = g_malloc(s->cluster_size);

    uint32_t i;

    int fd = 0;

    assert(offset < size);

    assert((offset % s->cluster_size) == 0);

    for (i = s->cluster_size; i < offset; i += s->cluster_size)

	c = modified_fat_get(s, c);

    fd = open(mapping->path, O_RDWR | O_CREAT | O_BINARY, 0666);

    if (fd < 0) {

	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,

		strerror(errno), errno);

	return fd;

    }

    if (offset > 0)

	if (lseek(fd, offset, SEEK_SET) != offset)

	    return -3;

    while (offset < size) {

	uint32_t c1;

	int rest_size = (size - offset > s->cluster_size ?

		s->cluster_size : size - offset);

	int ret;

	c1 = modified_fat_get(s, c);

	assert((size - offset == 0 && fat_eof(s, c)) ||

		(size > offset && c >=2 && !fat_eof(s, c)));

	ret = vvfat_read(s->bs, cluster2sector(s, c),

	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);

	if (ret < 0)

	    return ret;

	if (write(fd, cluster, rest_size) < 0)

	    return -2;

	offset += rest_size;

	c = c1;

    }

    if (ftruncate(fd, size)) {

        perror("ftruncate()");

        close(fd);

        return -4;

    }

    close(fd);

    return commit_mappings(s, first_cluster, dir_index);

}


static int vhost_user_read(struct vhost_dev *dev, VhostUserMsg *msg)

{

    CharDriverState *chr = dev->opaque;

    uint8_t *p = (uint8_t *) msg;

    int r, size = VHOST_USER_HDR_SIZE;

    r = qemu_chr_fe_read_all(chr, p, size);

    if (r != size) {

        error_report("Failed to read msg header. Read %d instead of %d.", r,

                size);

        goto fail;

    }

    /* validate received flags */

    if (msg->flags != (VHOST_USER_REPLY_MASK | VHOST_USER_VERSION)) {

        error_report("Failed to read msg header."

                " Flags 0x%x instead of 0x%x.", msg->flags,

                VHOST_USER_REPLY_MASK | VHOST_USER_VERSION);

        goto fail;

    }

    /* validate message size is sane */

    if (msg->size > VHOST_USER_PAYLOAD_SIZE) {

        error_report("Failed to read msg header."

                " Size %d exceeds the maximum %zu.", msg->size,

                VHOST_USER_PAYLOAD_SIZE);

        goto fail;

    }

    if (msg->size) {

        p += VHOST_USER_HDR_SIZE;

        size = msg->size;

        r = qemu_chr_fe_read_all(chr, p, size);

        if (r != size) {

            error_report("Failed to read msg payload."

                         " Read %d instead of %d.", r, msg->size);

            goto fail;

        }

    }

    return 0;

fail:

    return -1;

}


av_cold void ff_vp9dsp_init_x86(VP9DSPContext *dsp, int bpp)

{

#if HAVE_YASM

    int cpu_flags;

    if (bpp != 8) return;

    cpu_flags = av_get_cpu_flags();

#define init_fpel(idx1, idx2, sz, type, opt) \

    dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][0][0] = \

    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][0][0] = \

    dsp->mc[idx1][FILTER_8TAP_SHARP  ][idx2][0][0] = \

    dsp->mc[idx1][FILTER_BILINEAR    ][idx2][0][0] = ff_vp9_##type##sz##_##opt

#define init_subpel1(idx1, idx2, idxh, idxv, sz, dir, type, opt) \

    dsp->mc[idx1][FILTER_8TAP_SMOOTH ][idx2][idxh][idxv] = type##_8tap_smooth_##sz##dir##_##opt; \

    dsp->mc[idx1][FILTER_8TAP_REGULAR][idx2][idxh][idxv] = type##_8tap_regular_##sz##dir##_##opt; \

    dsp->mc[idx1][FILTER_8TAP_SHARP  ][idx2][idxh][idxv] = type##_8tap_sharp_##sz##dir##_##opt

#define init_subpel2(idx1, idx2, sz, type, opt) \

    init_subpel1(idx1, idx2, 1, 1, sz, hv, type, opt); \

    init_subpel1(idx1, idx2, 0, 1, sz, v,  type, opt); \

    init_subpel1(idx1, idx2, 1, 0, sz, h,  type, opt)

#define init_subpel3_32_64(idx, type, opt) \

    init_subpel2(0, idx, 64, type, opt); \

    init_subpel2(1, idx, 32, type, opt)

#define init_subpel3_8to64(idx, type, opt) \

    init_subpel3_32_64(idx, type, opt); \

    init_subpel2(2, idx, 16, type, opt); \

    init_subpel2(3, idx,  8, type, opt)

#define init_subpel3(idx, type, opt) \

    init_subpel3_8to64(idx, type, opt); \

    init_subpel2(4, idx,  4, type, opt)

#define init_lpf(opt) do { \

    dsp->loop_filter_16[0] = ff_vp9_loop_filter_h_16_16_##opt; \

    dsp->loop_filter_16[1] = ff_vp9_loop_filter_v_16_16_##opt; \

    dsp->loop_filter_mix2[0][0][0] = ff_vp9_loop_filter_h_44_16_##opt; \

    dsp->loop_filter_mix2[0][0][1] = ff_vp9_loop_filter_v_44_16_##opt; \

    dsp->loop_filter_mix2[0][1][0] = ff_vp9_loop_filter_h_48_16_##opt; \

    dsp->loop_filter_mix2[0][1][1] = ff_vp9_loop_filter_v_48_16_##opt; \

    dsp->loop_filter_mix2[1][0][0] = ff_vp9_loop_filter_h_84_16_##opt; \

    dsp->loop_filter_mix2[1][0][1] = ff_vp9_loop_filter_v_84_16_##opt; \

    dsp->loop_filter_mix2[1][1][0] = ff_vp9_loop_filter_h_88_16_##opt; \

    dsp->loop_filter_mix2[1][1][1] = ff_vp9_loop_filter_v_88_16_##opt; \

} while (0)

#define init_ipred(sz, opt, t, e) \

    dsp->intra_pred[TX_##sz##X##sz][e##_PRED] = ff_vp9_ipred_##t##_##sz##x##sz##_##opt

#define ff_vp9_ipred_hd_4x4_ssse3 ff_vp9_ipred_hd_4x4_mmxext

#define ff_vp9_ipred_vl_4x4_ssse3 ff_vp9_ipred_vl_4x4_mmxext

#define init_dir_tm_ipred(sz, opt) do { \

    init_ipred(sz, opt, dl, DIAG_DOWN_LEFT); \

    init_ipred(sz, opt, dr, DIAG_DOWN_RIGHT); \

    init_ipred(sz, opt, hd, HOR_DOWN); \

    init_ipred(sz, opt, vl, VERT_LEFT); \

    init_ipred(sz, opt, hu, HOR_UP); \

    init_ipred(sz, opt, tm, TM_VP8); \

    init_ipred(sz, opt, vr, VERT_RIGHT); \

} while (0)

#define init_dir_tm_h_ipred(sz, opt) do { \

    init_dir_tm_ipred(sz, opt); \

    init_ipred(sz, opt, h,  HOR); \

} while (0)

#define init_dc_ipred(sz, opt) do { \

    init_ipred(sz, opt, dc,      DC); \

    init_ipred(sz, opt, dc_left, LEFT_DC); \

    init_ipred(sz, opt, dc_top,  TOP_DC); \

} while (0)

#define init_all_ipred(sz, opt) do { \

    init_dc_ipred(sz, opt); \

    init_dir_tm_h_ipred(sz, opt); \

} while (0)

    if (EXTERNAL_MMX(cpu_flags)) {

        init_fpel(4, 0,  4, put, mmx);

        init_fpel(3, 0,  8, put, mmx);

        dsp->itxfm_add[4 /* lossless */][DCT_DCT] =

        dsp->itxfm_add[4 /* lossless */][ADST_DCT] =

        dsp->itxfm_add[4 /* lossless */][DCT_ADST] =

        dsp->itxfm_add[4 /* lossless */][ADST_ADST] = ff_vp9_iwht_iwht_4x4_add_mmx;

        init_ipred(8, mmx, v, VERT);

    }

    if (EXTERNAL_MMXEXT(cpu_flags)) {

        init_subpel2(4, 0, 4, put, mmxext);

        init_subpel2(4, 1, 4, avg, mmxext);

        init_fpel(4, 1,  4, avg, mmxext);

        init_fpel(3, 1,  8, avg, mmxext);

        dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_mmxext;

        init_dc_ipred(4, mmxext);

        init_dc_ipred(8, mmxext);

        init_dir_tm_ipred(4, mmxext);

    }

    if (EXTERNAL_SSE(cpu_flags)) {

        init_fpel(2, 0, 16, put, sse);

        init_fpel(1, 0, 32, put, sse);

        init_fpel(0, 0, 64, put, sse);

        init_ipred(16, sse, v, VERT);

        init_ipred(32, sse, v, VERT);

    }

    if (EXTERNAL_SSE2(cpu_flags)) {

        init_subpel3_8to64(0, put, sse2);

        init_subpel3_8to64(1, avg, sse2);

        init_fpel(2, 1, 16, avg, sse2);

        init_fpel(1, 1, 32, avg, sse2);

        init_fpel(0, 1, 64, avg, sse2);

        init_lpf(sse2);

        dsp->itxfm_add[TX_4X4][ADST_DCT]  = ff_vp9_idct_iadst_4x4_add_sse2;

        dsp->itxfm_add[TX_4X4][DCT_ADST]  = ff_vp9_iadst_idct_4x4_add_sse2;

        dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_sse2;

        dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_sse2;

        dsp->itxfm_add[TX_8X8][ADST_DCT]  = ff_vp9_idct_iadst_8x8_add_sse2;

        dsp->itxfm_add[TX_8X8][DCT_ADST]  = ff_vp9_iadst_idct_8x8_add_sse2;

        dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_sse2;

        dsp->itxfm_add[TX_16X16][DCT_DCT]   = ff_vp9_idct_idct_16x16_add_sse2;

        dsp->itxfm_add[TX_16X16][ADST_DCT]  = ff_vp9_idct_iadst_16x16_add_sse2;

        dsp->itxfm_add[TX_16X16][DCT_ADST]  = ff_vp9_iadst_idct_16x16_add_sse2;

        dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_sse2;

        dsp->itxfm_add[TX_32X32][ADST_ADST] =

        dsp->itxfm_add[TX_32X32][ADST_DCT] =

        dsp->itxfm_add[TX_32X32][DCT_ADST] =

        dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_sse2;

        init_dc_ipred(16, sse2);

        init_dc_ipred(32, sse2);

        init_dir_tm_h_ipred(8, sse2);

        init_dir_tm_h_ipred(16, sse2);

        init_dir_tm_h_ipred(32, sse2);

        init_ipred(4, sse2, h, HOR);

    }

    if (EXTERNAL_SSSE3(cpu_flags)) {

        init_subpel3(0, put, ssse3);

        init_subpel3(1, avg, ssse3);

        dsp->itxfm_add[TX_4X4][DCT_DCT] = ff_vp9_idct_idct_4x4_add_ssse3;

        dsp->itxfm_add[TX_4X4][ADST_DCT]  = ff_vp9_idct_iadst_4x4_add_ssse3;

        dsp->itxfm_add[TX_4X4][DCT_ADST]  = ff_vp9_iadst_idct_4x4_add_ssse3;

        dsp->itxfm_add[TX_4X4][ADST_ADST] = ff_vp9_iadst_iadst_4x4_add_ssse3;

        dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_ssse3;

        dsp->itxfm_add[TX_8X8][ADST_DCT]  = ff_vp9_idct_iadst_8x8_add_ssse3;

        dsp->itxfm_add[TX_8X8][DCT_ADST]  = ff_vp9_iadst_idct_8x8_add_ssse3;

        dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_ssse3;

        dsp->itxfm_add[TX_16X16][DCT_DCT]   = ff_vp9_idct_idct_16x16_add_ssse3;

        dsp->itxfm_add[TX_16X16][ADST_DCT]  = ff_vp9_idct_iadst_16x16_add_ssse3;

        dsp->itxfm_add[TX_16X16][DCT_ADST]  = ff_vp9_iadst_idct_16x16_add_ssse3;

        dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_ssse3;

        dsp->itxfm_add[TX_32X32][ADST_ADST] =

        dsp->itxfm_add[TX_32X32][ADST_DCT] =

        dsp->itxfm_add[TX_32X32][DCT_ADST] =

        dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_ssse3;

        init_lpf(ssse3);

        init_all_ipred(4, ssse3);

        init_all_ipred(8, ssse3);

        init_all_ipred(16, ssse3);

        init_all_ipred(32, ssse3);

    }

    if (EXTERNAL_AVX(cpu_flags)) {

        dsp->itxfm_add[TX_8X8][DCT_DCT] = ff_vp9_idct_idct_8x8_add_avx;

        dsp->itxfm_add[TX_8X8][ADST_DCT]  = ff_vp9_idct_iadst_8x8_add_avx;

        dsp->itxfm_add[TX_8X8][DCT_ADST]  = ff_vp9_iadst_idct_8x8_add_avx;

        dsp->itxfm_add[TX_8X8][ADST_ADST] = ff_vp9_iadst_iadst_8x8_add_avx;

        dsp->itxfm_add[TX_16X16][DCT_DCT] = ff_vp9_idct_idct_16x16_add_avx;

        dsp->itxfm_add[TX_16X16][ADST_DCT]  = ff_vp9_idct_iadst_16x16_add_avx;

        dsp->itxfm_add[TX_16X16][DCT_ADST]  = ff_vp9_iadst_idct_16x16_add_avx;

        dsp->itxfm_add[TX_16X16][ADST_ADST] = ff_vp9_iadst_iadst_16x16_add_avx;

        dsp->itxfm_add[TX_32X32][ADST_ADST] =

        dsp->itxfm_add[TX_32X32][ADST_DCT] =

        dsp->itxfm_add[TX_32X32][DCT_ADST] =

        dsp->itxfm_add[TX_32X32][DCT_DCT] = ff_vp9_idct_idct_32x32_add_avx;

        init_lpf(avx);

        init_dir_tm_h_ipred(8, avx);

        init_dir_tm_h_ipred(16, avx);

        init_dir_tm_h_ipred(32, avx);

    }

    if (EXTERNAL_AVX_FAST(cpu_flags)) {

        init_fpel(1, 0, 32, put, avx);

        init_fpel(0, 0, 64, put, avx);

        init_ipred(32, avx, v, VERT);

    }

    if (EXTERNAL_AVX2(cpu_flags)) {

        init_fpel(1, 1, 32, avg, avx2);

        init_fpel(0, 1, 64, avg, avx2);

        if (ARCH_X86_64) {

#if ARCH_X86_64 && HAVE_AVX2_EXTERNAL

            init_subpel3_32_64(0, put, avx2);

            init_subpel3_32_64(1, avg, avx2);

#endif

        }

        init_dc_ipred(32, avx2);

        init_ipred(32, avx2, h,  HOR);

        init_ipred(32, avx2, tm, TM_VP8);

    }

#undef init_fpel

#undef init_subpel1

#undef init_subpel2

#undef init_subpel3

#endif /* HAVE_YASM */

}


MemdevList *qmp_query_memdev(Error **errp)

{

    Object *obj;

    MemdevList *list = NULL;

    obj = object_get_objects_root();

    if (obj == NULL) {

        return NULL;

    }

    if (object_child_foreach(obj, query_memdev, &list) != 0) {

        goto error;

    }

    return list;

error:

    qapi_free_MemdevList(list);

    return NULL;

}


static void create_cpu_without_cps(const char *cpu_model,

                                   qemu_irq *cbus_irq, qemu_irq *i8259_irq)

{

    CPUMIPSState *env;

    MIPSCPU *cpu;

    int i;

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

        cpu = cpu_mips_init(cpu_model);

        if (cpu == NULL) {

            fprintf(stderr, "Unable to find CPU definition\n");

            exit(1);

        }

        /* Init internal devices */

        cpu_mips_irq_init_cpu(cpu);

        cpu_mips_clock_init(cpu);

        qemu_register_reset(main_cpu_reset, cpu);

    }

    cpu = MIPS_CPU(first_cpu);

    env = &cpu->env;

    *i8259_irq = env->irq[2];

    *cbus_irq = env->irq[4];

}


static void qmf_32_subbands(DCAContext * s, int chans,

                            float samples_in[32][8], float *samples_out,

                            float scale)

{

    const float *prCoeff;

    int i;

    int sb_act = s->subband_activity[chans];

    int subindex;

    scale *= sqrt(1/8.0);

    /* Select filter */

    if (!s->multirate_inter)    /* Non-perfect reconstruction */

        prCoeff = fir_32bands_nonperfect;

    else                        /* Perfect reconstruction */

        prCoeff = fir_32bands_perfect;

    for (i = sb_act; i < 32; i++)

        s->raXin[i] = 0.0;

    /* Reconstructed channel sample index */

    for (subindex = 0; subindex < 8; subindex++) {

        /* Load in one sample from each subband and clear inactive subbands */

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

            uint32_t v = AV_RN32A(&samples_in[i][subindex]) ^ ((i-1)&2)<<30;

            AV_WN32A(&s->raXin[i], v);

        }

        s->synth.synth_filter_float(&s->imdct,

                              s->subband_fir_hist[chans], &s->hist_index[chans],

                              s->subband_fir_noidea[chans], prCoeff,

                              samples_out, s->raXin, scale);

        samples_out+= 32;

    }

}


static int filter_frame(AVFilterLink *inlink, AVFrame *inpicref)

{

    AVFilterContext *ctx = inlink->dst;

    SeparateFieldsContext *sf = ctx->priv;

    AVFilterLink *outlink = ctx->outputs[0];

    AVFrame *second;

    int i, ret;

    inpicref->height = outlink->h;

    inpicref->interlaced_frame = 0;

    second = av_frame_clone(inpicref);

    if (!second)

        return AVERROR(ENOMEM);

    for (i = 0; i < sf->nb_planes; i++) {

        if (!inpicref->top_field_first)

            inpicref->data[i] = inpicref->data[i] + inpicref->linesize[i];

        else

            second->data[i] = second->data[i] + second->linesize[i];

        inpicref->linesize[i] *= 2;

        second->linesize[i]   *= 2;

    }

    inpicref->pts = outlink->frame_count * sf->ts_unit;

    ret = ff_filter_frame(outlink, inpicref);

    if (ret < 0)

        return ret;

    second->pts = outlink->frame_count * sf->ts_unit;

    return ff_filter_frame(outlink, second);

}


int nbd_receive_reply(int csock, struct nbd_reply *reply)

{

    uint8_t buf[NBD_REPLY_SIZE];

    uint32_t magic;

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

    if (read_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {

        LOG("read failed");

        errno = EINVAL;

        return -1;

    }

    /* Reply

       [ 0 ..  3]    magic   (NBD_REPLY_MAGIC)

       [ 4 ..  7]    error   (0 == no error)

       [ 7 .. 15]    handle

     */

    magic = be32_to_cpup((uint32_t*)buf);

    reply->error  = be32_to_cpup((uint32_t*)(buf + 4));

    reply->handle = be64_to_cpup((uint64_t*)(buf + 8));

    TRACE("Got reply: "

          "{ magic = 0x%x, .error = %d, handle = %" PRIu64" }",

          magic, reply->error, reply->handle);

    if (magic != NBD_REPLY_MAGIC) {

        LOG("invalid magic (got 0x%x)", magic);

        errno = EINVAL;

        return -1;

    }

    return 0;

}


static int file_write(URLContext *h, const unsigned char *buf, int size)

{

    FileContext *c = h->priv_data;

    int r = write(c->fd, buf, size);

    return (-1 == r)?AVERROR(errno):r;

}


static void calc_transform_coeffs_cpl(AC3DecodeContext *s)

{

    int bin, band, ch, band_end;

    bin = s->start_freq[CPL_CH];

    for (band = 0; band < s->num_cpl_bands; band++) {

        band_end = bin + s->cpl_band_sizes[band];

        for (; bin < band_end; bin++) {

            for (ch = 1; ch <= s->fbw_channels; ch++) {

                if (s->channel_in_cpl[ch]) {

                    s->fixed_coeffs[ch][bin] = ((int64_t)s->fixed_coeffs[CPL_CH][bin] *

                                                (int64_t)s->cpl_coords[ch][band]) >> 23;

                    if (ch == 2 && s->phase_flags[band])

                        s->fixed_coeffs[ch][bin] = -s->fixed_coeffs[ch][bin];

                }

            }

        }

    }

}


int ff_dirac_golomb_read_16bit(DiracGolombLUT *lut_ctx, const uint8_t *buf,

                               int bytes, uint8_t *_dst, int coeffs)

{

    int i, b, c_idx = 0;

    int16_t *dst = (int16_t *)_dst;

    DiracGolombLUT *future[4], *l = &lut_ctx[2*LUT_SIZE + buf[0]];

    INIT_RESIDUE(res);

    for (b = 1; b <= bytes; b++) {

        future[0] = &lut_ctx[buf[b]];

        future[1] = future[0] + 1*LUT_SIZE;

        future[2] = future[0] + 2*LUT_SIZE;

        future[3] = future[0] + 3*LUT_SIZE;

        if ((c_idx + 1) > coeffs)

            return c_idx;

        if (res_bits && l->sign) {

            int32_t coeff = 1;

            APPEND_RESIDUE(res, l->preamble);

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

                coeff <<= 1;

                coeff |= (res >> (RSIZE_BITS - 2*i - 2)) & 1;

            }

            dst[c_idx++] = l->sign * (coeff - 1);

            SET_RESIDUE(res, 0, 0);

        }

        for (i = 0; i < LUT_BITS; i++)

            dst[c_idx + i] = l->ready[i];

        c_idx += l->ready_num;

        APPEND_RESIDUE(res, l->leftover);

        l = future[l->need_s ? 3 : !res_bits ? 2 : res_bits & 1];

    }

    return c_idx;

}


void ff_celt_quant_bands(CeltFrame *f, OpusRangeCoder *rc)

{

    float lowband_scratch[8 * 22];

    float norm1[2 * 8 * 100];

    float *norm2 = norm1 + 8 * 100;

    int totalbits = (f->framebits << 3) - f->anticollapse_needed;

    int update_lowband = 1;

    int lowband_offset = 0;

    int i, j;

    for (i = f->start_band; i < f->end_band; i++) {

        uint32_t cm[2] = { (1 << f->blocks) - 1, (1 << f->blocks) - 1 };

        int band_offset = ff_celt_freq_bands[i] << f->size;

        int band_size   = ff_celt_freq_range[i] << f->size;

        float *X = f->block[0].coeffs + band_offset;

        float *Y = (f->channels == 2) ? f->block[1].coeffs + band_offset : NULL;

        float *norm_loc1, *norm_loc2;

        int consumed = opus_rc_tell_frac(rc);

        int effective_lowband = -1;

        int b = 0;

        /* Compute how many bits we want to allocate to this band */

        if (i != f->start_band)

            f->remaining -= consumed;

        f->remaining2 = totalbits - consumed - 1;

        if (i <= f->coded_bands - 1) {

            int curr_balance = f->remaining / FFMIN(3, f->coded_bands-i);

            b = av_clip_uintp2(FFMIN(f->remaining2 + 1, f->pulses[i] + curr_balance), 14);

        }

        if ((ff_celt_freq_bands[i] - ff_celt_freq_range[i] >= ff_celt_freq_bands[f->start_band] ||

            i == f->start_band + 1) && (update_lowband || lowband_offset == 0))

            lowband_offset = i;

        if (i == f->start_band + 1) {

            /* Special Hybrid Folding (RFC 8251 section 9). Copy the first band into

            the second to ensure the second band never has to use the LCG. */

            int offset = 8 * ff_celt_freq_bands[i];

            int count = 8 * (ff_celt_freq_range[i] - ff_celt_freq_range[i-1]);

            memcpy(&norm1[offset], &norm1[offset - count], count * sizeof(float));

            if (f->channels == 2)

                memcpy(&norm2[offset], &norm2[offset - count], count * sizeof(float));

        }

        /* Get a conservative estimate of the collapse_mask's for the bands we're

           going to be folding from. */

        if (lowband_offset != 0 && (f->spread != CELT_SPREAD_AGGRESSIVE ||

                                    f->blocks > 1 || f->tf_change[i] < 0)) {

            int foldstart, foldend;

            /* This ensures we never repeat spectral content within one band */

            effective_lowband = FFMAX(ff_celt_freq_bands[f->start_band],

                                      ff_celt_freq_bands[lowband_offset] - ff_celt_freq_range[i]);

            foldstart = lowband_offset;

            while (ff_celt_freq_bands[--foldstart] > effective_lowband);

            foldend = lowband_offset - 1;

            while (++foldend < i && ff_celt_freq_bands[foldend] < effective_lowband + ff_celt_freq_range[i]);

            cm[0] = cm[1] = 0;

            for (j = foldstart; j < foldend; j++) {

                cm[0] |= f->block[0].collapse_masks[j];

                cm[1] |= f->block[f->channels - 1].collapse_masks[j];

            }

        }

        if (f->dual_stereo && i == f->intensity_stereo) {

            /* Switch off dual stereo to do intensity */

            f->dual_stereo = 0;

            for (j = ff_celt_freq_bands[f->start_band] << f->size; j < band_offset; j++)

                norm1[j] = (norm1[j] + norm2[j]) / 2;

        }

        norm_loc1 = effective_lowband != -1 ? norm1 + (effective_lowband << f->size) : NULL;

        norm_loc2 = effective_lowband != -1 ? norm2 + (effective_lowband << f->size) : NULL;

        if (f->dual_stereo) {

            cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X, NULL, band_size, b >> 1,

                                       f->blocks, norm_loc1, f->size,

                                       norm1 + band_offset, 0, 1.0f,

                                       lowband_scratch, cm[0]);

            cm[1] = f->pvq->quant_band(f->pvq, f, rc, i, Y, NULL, band_size, b >> 1,

                                       f->blocks, norm_loc2, f->size,

                                       norm2 + band_offset, 0, 1.0f,

                                       lowband_scratch, cm[1]);

        } else {

            cm[0] = f->pvq->quant_band(f->pvq, f, rc, i, X,    Y, band_size, b >> 0,

                                       f->blocks, norm_loc1, f->size,

                                       norm1 + band_offset, 0, 1.0f,

                                       lowband_scratch, cm[0] | cm[1]);

            cm[1] = cm[0];

        }

        f->block[0].collapse_masks[i]               = (uint8_t)cm[0];

        f->block[f->channels - 1].collapse_masks[i] = (uint8_t)cm[1];

        f->remaining += f->pulses[i] + consumed;

        /* Update the folding position only as long as we have 1 bit/sample depth */

        update_lowband = (b > band_size << 3);

    }

}


MigrationCapabilityStatusList *qmp_query_migrate_capabilities(Error **errp)

{

    MigrationCapabilityStatusList *head = NULL;

    MigrationCapabilityStatusList *caps;

    MigrationState *s = migrate_get_current();

    int i;

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

        if (head == NULL) {

            head = g_malloc0(sizeof(*caps));

            caps = head;

        } else {

            caps->next = g_malloc0(sizeof(*caps));

            caps = caps->next;

        }

        caps->value =

            g_malloc(sizeof(*caps->value));

        caps->value->capability = i;

        caps->value->state = s->enabled_capabilities[i];

    }

    return head;

}


static void armv7m_nvic_class_init(ObjectClass *klass, void *data)

{

    NVICClass *nc = NVIC_CLASS(klass);

    DeviceClass *dc = DEVICE_CLASS(klass);

    SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);

    nc->parent_reset = dc->reset;

    nc->parent_init = sdc->init;

    sdc->init = armv7m_nvic_init;

    dc->vmsd  = &vmstate_nvic;

    dc->reset = armv7m_nvic_reset;

}


static void ide_sector_write_cb(void *opaque, int ret)

{

    IDEState *s = opaque;

    int n;

    if (ret == -ECANCELED) {

        return;

    }

    block_acct_done(blk_get_stats(s->blk), &s->acct);

    s->pio_aiocb = NULL;

    s->status &= ~BUSY_STAT;

    if (ret != 0) {

        if (ide_handle_rw_error(s, -ret, IDE_RETRY_PIO)) {

            return;

        }

    }

    n = s->nsector;

    if (n > s->req_nb_sectors) {

        n = s->req_nb_sectors;

    }

    s->nsector -= n;

    ide_set_sector(s, ide_get_sector(s) + n);

    if (s->nsector == 0) {

        /* no more sectors to write */

        ide_transfer_stop(s);

    } else {

        int n1 = s->nsector;

        if (n1 > s->req_nb_sectors) {

            n1 = s->req_nb_sectors;

        }

        ide_transfer_start(s, s->io_buffer, n1 * BDRV_SECTOR_SIZE,

                           ide_sector_write);

    }

    if (win2k_install_hack && ((++s->irq_count % 16) == 0)) {

        /* It seems there is a bug in the Windows 2000 installer HDD

           IDE driver which fills the disk with empty logs when the

           IDE write IRQ comes too early. This hack tries to correct

           that at the expense of slower write performances. Use this

           option _only_ to install Windows 2000. You must disable it

           for normal use. */

        timer_mod(s->sector_write_timer,

                       qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + (get_ticks_per_sec() / 1000));

    } else {

        ide_set_irq(s->bus);

    }

}


static int init_ralf_vlc(VLC *vlc, const uint8_t *data, int elems)

{

    uint8_t  lens[MAX_ELEMS];

    uint16_t codes[MAX_ELEMS];

    int counts[17], prefixes[18];

    int i, cur_len;

    int max_bits = 0;

    GetBitContext gb;

    init_get_bits(&gb, data, elems * 4);

    for (i = 0; i <= 16; i++)

        counts[i] = 0;

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

        cur_len  = get_bits(&gb, 4) + 1;

        counts[cur_len]++;

        max_bits = FFMAX(max_bits, cur_len);

        lens[i]  = cur_len;

    }

    prefixes[1] = 0;

    for (i = 1; i <= 16; i++)

        prefixes[i + 1] = (prefixes[i] + counts[i]) << 1;

    for (i = 0; i < elems; i++)

        codes[i] = prefixes[lens[i]]++;

    return ff_init_vlc_sparse(vlc, FFMIN(max_bits, 9), elems,

                              lens, 1, 1, codes, 2, 2, NULL, 0, 0, 0);

}


static int ioreq_runio_qemu_sync(struct ioreq *ioreq)

{

    struct XenBlkDev *blkdev = ioreq->blkdev;

    int i, rc, len = 0;

    off_t pos;

    if (ioreq->req.nr_segments && ioreq_map(ioreq) == -1)

	goto err;

    if (ioreq->presync)

	bdrv_flush(blkdev->bs);

    switch (ioreq->req.operation) {

    case BLKIF_OP_READ:

	pos = ioreq->start;

	for (i = 0; i < ioreq->v.niov; i++) {

	    rc = bdrv_read(blkdev->bs, pos / BLOCK_SIZE,

			   ioreq->v.iov[i].iov_base,

			   ioreq->v.iov[i].iov_len / BLOCK_SIZE);

	    if (rc != 0) {

		xen_be_printf(&blkdev->xendev, 0, "rd I/O error (%p, len %zd)\n",

			      ioreq->v.iov[i].iov_base,

			      ioreq->v.iov[i].iov_len);

		goto err;

	    }

	    len += ioreq->v.iov[i].iov_len;

	    pos += ioreq->v.iov[i].iov_len;

	}

	break;

    case BLKIF_OP_WRITE:

    case BLKIF_OP_WRITE_BARRIER:

        if (!ioreq->req.nr_segments)

            break;

	pos = ioreq->start;

	for (i = 0; i < ioreq->v.niov; i++) {

	    rc = bdrv_write(blkdev->bs, pos / BLOCK_SIZE,

			    ioreq->v.iov[i].iov_base,

			    ioreq->v.iov[i].iov_len / BLOCK_SIZE);

	    if (rc != 0) {

		xen_be_printf(&blkdev->xendev, 0, "wr I/O error (%p, len %zd)\n",

			      ioreq->v.iov[i].iov_base,

			      ioreq->v.iov[i].iov_len);

		goto err;

	    }

	    len += ioreq->v.iov[i].iov_len;

	    pos += ioreq->v.iov[i].iov_len;

	}

	break;

    default:

	/* unknown operation (shouldn't happen -- parse catches this) */

	goto err;

    }

    if (ioreq->postsync)

	bdrv_flush(blkdev->bs);

    ioreq->status = BLKIF_RSP_OKAY;

    ioreq_unmap(ioreq);

    ioreq_finish(ioreq);

    return 0;

err:

    ioreq->status = BLKIF_RSP_ERROR;

    return -1;

}


static int vaapi_encode_h264_init_sequence_params(AVCodecContext *avctx)

{

    VAAPIEncodeContext                 *ctx = avctx->priv_data;

    VAEncSequenceParameterBufferH264  *vseq = ctx->codec_sequence_params;

    VAEncPictureParameterBufferH264   *vpic = ctx->codec_picture_params;

    VAAPIEncodeH264Context            *priv = ctx->priv_data;

    VAAPIEncodeH264MiscSequenceParams *mseq = &priv->misc_sequence_params;

    int i;

    {

        vseq->seq_parameter_set_id = 0;

        vseq->level_idc = avctx->level;

        vseq->max_num_ref_frames = 1 + (avctx->max_b_frames > 0);

        vseq->picture_width_in_mbs  = priv->mb_width;

        vseq->picture_height_in_mbs = priv->mb_height;

        vseq->seq_fields.bits.chroma_format_idc = 1;

        vseq->seq_fields.bits.frame_mbs_only_flag = 1;

        vseq->seq_fields.bits.direct_8x8_inference_flag = 1;

        vseq->seq_fields.bits.log2_max_frame_num_minus4 = 4;

        vseq->seq_fields.bits.pic_order_cnt_type = 0;

        if (avctx->width  != ctx->surface_width ||

            avctx->height != ctx->surface_height) {

            vseq->frame_cropping_flag = 1;

            vseq->frame_crop_left_offset   = 0;

            vseq->frame_crop_right_offset  =

                (ctx->surface_width - avctx->width) / 2;

            vseq->frame_crop_top_offset    = 0;

            vseq->frame_crop_bottom_offset =

                (ctx->surface_height - avctx->height) / 2;

        } else {

            vseq->frame_cropping_flag = 0;

        }

        vseq->vui_parameters_present_flag = 1;

        if (avctx->sample_aspect_ratio.num != 0) {

            vseq->vui_fields.bits.aspect_ratio_info_present_flag = 1;

            // There is a large enum of these which we could support

            // individually rather than using the generic X/Y form?

            if (avctx->sample_aspect_ratio.num ==

                avctx->sample_aspect_ratio.den) {

                vseq->aspect_ratio_idc = 1;

            } else {

                vseq->aspect_ratio_idc = 255; // Extended SAR.

                vseq->sar_width  = avctx->sample_aspect_ratio.num;

                vseq->sar_height = avctx->sample_aspect_ratio.den;

            }

        }

        if (avctx->color_primaries != AVCOL_PRI_UNSPECIFIED ||

            avctx->color_trc       != AVCOL_TRC_UNSPECIFIED ||

            avctx->colorspace      != AVCOL_SPC_UNSPECIFIED) {

            mseq->video_signal_type_present_flag = 1;

            mseq->video_format             = 5; // Unspecified.

            mseq->video_full_range_flag    = 0;

            mseq->colour_description_present_flag = 1;

            // These enums are derived from the standard and hence

            // we can just use the values directly.

            mseq->colour_primaries         = avctx->color_primaries;

            mseq->transfer_characteristics = avctx->color_trc;

            mseq->matrix_coefficients      = avctx->colorspace;

        }

        vseq->vui_fields.bits.bitstream_restriction_flag = 1;

        mseq->motion_vectors_over_pic_boundaries_flag = 1;

        mseq->max_bytes_per_pic_denom = 0;

        mseq->max_bits_per_mb_denom   = 0;

        vseq->vui_fields.bits.log2_max_mv_length_horizontal = 16;

        vseq->vui_fields.bits.log2_max_mv_length_vertical   = 16;

        mseq->max_num_reorder_frames = (avctx->max_b_frames > 0);

        mseq->max_dec_pic_buffering  = vseq->max_num_ref_frames;

        vseq->bits_per_second = avctx->bit_rate;

        vseq->vui_fields.bits.timing_info_present_flag = 1;

        if (avctx->framerate.num > 0 && avctx->framerate.den > 0) {

            vseq->num_units_in_tick = avctx->framerate.den;

            vseq->time_scale        = 2 * avctx->framerate.num;

            mseq->fixed_frame_rate_flag = 1;

        } else {

            vseq->num_units_in_tick = avctx->time_base.num;

            vseq->time_scale        = 2 * avctx->time_base.den;

            mseq->fixed_frame_rate_flag = 0;

        }

        if (ctx->va_rc_mode == VA_RC_CBR) {

            priv->send_timing_sei = 1;

            mseq->nal_hrd_parameters_present_flag = 1;

            mseq->cpb_cnt_minus1 = 0;

            // Try to scale these to a sensible range so that the

            // golomb encode of the value is not overlong.

            mseq->bit_rate_scale =

                av_clip_uintp2(av_log2(avctx->bit_rate) - 15 - 6, 4);

            mseq->bit_rate_value_minus1[0] =

                (avctx->bit_rate >> mseq->bit_rate_scale + 6) - 1;

            mseq->cpb_size_scale =

                av_clip_uintp2(av_log2(ctx->hrd_params.hrd.buffer_size) - 15 - 4, 4);

            mseq->cpb_size_value_minus1[0] =

                (ctx->hrd_params.hrd.buffer_size >> mseq->cpb_size_scale + 4) - 1;

            // CBR mode isn't actually available here, despite naming.

            mseq->cbr_flag[0] = 0;

            mseq->initial_cpb_removal_delay_length_minus1 = 23;

            mseq->cpb_removal_delay_length_minus1         = 23;

            mseq->dpb_output_delay_length_minus1          = 7;

            mseq->time_offset_length = 0;

            // This calculation can easily overflow 32 bits.

            mseq->initial_cpb_removal_delay = 90000 *

                (uint64_t)ctx->hrd_params.hrd.initial_buffer_fullness /

                ctx->hrd_params.hrd.buffer_size;

            mseq->initial_cpb_removal_delay_offset = 0;

        } else {

            priv->send_timing_sei = 0;

            mseq->nal_hrd_parameters_present_flag = 0;

        }

        vseq->intra_period     = ctx->p_per_i * (ctx->b_per_p + 1);

        vseq->intra_idr_period = vseq->intra_period;

        vseq->ip_period        = ctx->b_per_p + 1;

    }

    {

        vpic->CurrPic.picture_id = VA_INVALID_ID;

        vpic->CurrPic.flags      = VA_PICTURE_H264_INVALID;

        for (i = 0; i < FF_ARRAY_ELEMS(vpic->ReferenceFrames); i++) {

            vpic->ReferenceFrames[i].picture_id = VA_INVALID_ID;

            vpic->ReferenceFrames[i].flags      = VA_PICTURE_H264_INVALID;

        }

        vpic->coded_buf = VA_INVALID_ID;

        vpic->pic_parameter_set_id = 0;

        vpic->seq_parameter_set_id = 0;

        vpic->num_ref_idx_l0_active_minus1 = 0;

        vpic->num_ref_idx_l1_active_minus1 = 0;

        vpic->pic_fields.bits.entropy_coding_mode_flag =

            ((avctx->profile & 0xff) != 66);

        vpic->pic_fields.bits.weighted_pred_flag = 0;

        vpic->pic_fields.bits.weighted_bipred_idc = 0;

        vpic->pic_fields.bits.transform_8x8_mode_flag =

            ((avctx->profile & 0xff) >= 100);

        vpic->pic_init_qp = priv->fixed_qp_idr;

    }

    {

        mseq->profile_idc = avctx->profile & 0xff;

        if (avctx->profile & FF_PROFILE_H264_CONSTRAINED)

            mseq->constraint_set1_flag = 1;

        if (avctx->profile & FF_PROFILE_H264_INTRA)

            mseq->constraint_set3_flag = 1;

    }

    return 0;

}


static void socket_start_outgoing_migration(MigrationState *s,

                                            SocketAddress *saddr,

                                            Error **errp)

{

    QIOChannelSocket *sioc = qio_channel_socket_new();

    qio_channel_socket_connect_async(sioc,

                                     saddr,

                                     socket_outgoing_migration,

                                     s,

                                     NULL);

    qapi_free_SocketAddress(saddr);

}


void qdist_bin__internal(struct qdist *to, const struct qdist *from, size_t n)

{

    double xmin, xmax;

    double step;

    size_t i, j;

    qdist_init(to);

    if (from->n == 0) {

        return;

    }

    if (n == 0 || from->n == 1) {

        n = from->n;

    }

    /* set equally-sized bins between @from's left and right */

    xmin = qdist_xmin(from);

    xmax = qdist_xmax(from);

    step = (xmax - xmin) / n;

    if (n == from->n) {

        /* if @from's entries are equally spaced, no need to re-bin */

        for (i = 0; i < from->n; i++) {

            if (from->entries[i].x != xmin + i * step) {

                goto rebin;

            }

        }

        /* they're equally spaced, so copy the dist and bail out */

        to->entries = g_new(struct qdist_entry, from->n);

        to->n = from->n;

        memcpy(to->entries, from->entries, sizeof(*to->entries) * to->n);

        return;

    }

 rebin:

    j = 0;

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

        double x;

        double left, right;

        left = xmin + i * step;

        right = xmin + (i + 1) * step;

        /* Add x, even if it might not get any counts later */

        x = left;

        qdist_add(to, x, 0);

        /*

         * To avoid double-counting we capture [left, right) ranges, except for

         * the righmost bin, which captures a [left, right] range.

         */

        while (j < from->n && (from->entries[j].x < right || i == n - 1)) {

            struct qdist_entry *o = &from->entries[j];

            qdist_add(to, x, o->count);

            j++;

        }

    }

}


static inline void asv2_put_level(PutBitContext *pb, int level)

{

    unsigned int index = level + 31;

    if (index <= 62) {

        put_bits(pb, ff_asv2_level_tab[index][1], ff_asv2_level_tab[index][0]);

    } else {

        put_bits(pb, ff_asv2_level_tab[31][1], ff_asv2_level_tab[31][0]);

        asv2_put_bits(pb, 8, level & 0xFF);

    }

}


int net_init_l2tpv3(const NetClientOptions *opts,

                    const char *name,

                    NetClientState *peer)

{

    const NetdevL2TPv3Options *l2tpv3;

    NetL2TPV3State *s;

    NetClientState *nc;

    int fd = -1, gairet;

    struct addrinfo hints;

    struct addrinfo *result = NULL;

    char *srcport, *dstport;

    nc = qemu_new_net_client(&net_l2tpv3_info, peer, "l2tpv3", name);

    s = DO_UPCAST(NetL2TPV3State, nc, nc);

    s->queue_head = 0;

    s->queue_tail = 0;

    s->header_mismatch = false;

    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_L2TPV3);

    l2tpv3 = opts->l2tpv3;

    if (l2tpv3->has_ipv6 && l2tpv3->ipv6) {

        s->ipv6 = l2tpv3->ipv6;

    } else {

        s->ipv6 = false;

    }

    if ((l2tpv3->has_offset) && (l2tpv3->offset > 256)) {

        error_report("l2tpv3_open : offset must be less than 256 bytes");

        goto outerr;

    }

    if (l2tpv3->has_rxcookie || l2tpv3->has_txcookie) {

        if (l2tpv3->has_rxcookie && l2tpv3->has_txcookie) {

            s->cookie = true;

        } else {

            goto outerr;

        }

    } else {

        s->cookie = false;

    }

    if (l2tpv3->has_cookie64 || l2tpv3->cookie64) {

        s->cookie_is_64  = true;

    } else {

        s->cookie_is_64  = false;

    }

    if (l2tpv3->has_udp && l2tpv3->udp) {

        s->udp = true;

        if (!(l2tpv3->has_srcport && l2tpv3->has_dstport)) {

            error_report("l2tpv3_open : need both src and dst port for udp");

            goto outerr;

        } else {

            srcport = l2tpv3->srcport;

            dstport = l2tpv3->dstport;

        }

    } else {

        s->udp = false;

        srcport = NULL;

        dstport = NULL;

    }

    s->offset = 4;

    s->session_offset = 0;

    s->cookie_offset = 4;

    s->counter_offset = 4;

    s->tx_session = l2tpv3->txsession;

    if (l2tpv3->has_rxsession) {

        s->rx_session = l2tpv3->rxsession;

    } else {

        s->rx_session = s->tx_session;

    }

    if (s->cookie) {

        s->rx_cookie = l2tpv3->rxcookie;

        s->tx_cookie = l2tpv3->txcookie;

        if (s->cookie_is_64 == true) {

            /* 64 bit cookie */

            s->offset += 8;

            s->counter_offset += 8;

        } else {

            /* 32 bit cookie */

            s->offset += 4;

            s->counter_offset += 4;

        }

    }

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

    if (s->ipv6) {

        hints.ai_family = AF_INET6;

    } else {

        hints.ai_family = AF_INET;

    }

    if (s->udp) {

        hints.ai_socktype = SOCK_DGRAM;

        hints.ai_protocol = 0;

        s->offset += 4;

        s->counter_offset += 4;

        s->session_offset += 4;

        s->cookie_offset += 4;

    } else {

        hints.ai_socktype = SOCK_RAW;

        hints.ai_protocol = IPPROTO_L2TP;

    }

    gairet = getaddrinfo(l2tpv3->src, srcport, &hints, &result);

    if ((gairet != 0) || (result == NULL)) {

        error_report(

            "l2tpv3_open : could not resolve src, errno = %s",

            gai_strerror(gairet)

        );

        goto outerr;

    }

    fd = socket(result->ai_family, result->ai_socktype, result->ai_protocol);

    if (fd == -1) {

        fd = -errno;

        error_report("l2tpv3_open : socket creation failed, errno = %d", -fd);

        goto outerr;

    }

    if (bind(fd, (struct sockaddr *) result->ai_addr, result->ai_addrlen)) {

        error_report("l2tpv3_open :  could not bind socket err=%i", errno);

        goto outerr;

    }

    if (result) {

        freeaddrinfo(result);

    }

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

    if (s->ipv6) {

        hints.ai_family = AF_INET6;

    } else {

        hints.ai_family = AF_INET;

    }

    if (s->udp) {

        hints.ai_socktype = SOCK_DGRAM;

        hints.ai_protocol = 0;

    } else {

        hints.ai_socktype = SOCK_RAW;

        hints.ai_protocol = IPPROTO_L2TP;

    }

    result = NULL;

    gairet = getaddrinfo(l2tpv3->dst, dstport, &hints, &result);

    if ((gairet != 0) || (result == NULL)) {

        error_report(

            "l2tpv3_open : could not resolve dst, error = %s",

            gai_strerror(gairet)

        );

        goto outerr;

    }

    s->dgram_dst = g_malloc(sizeof(struct sockaddr_storage));

    memset(s->dgram_dst, '\0' , sizeof(struct sockaddr_storage));

    memcpy(s->dgram_dst, result->ai_addr, result->ai_addrlen);

    s->dst_size = result->ai_addrlen;

    if (result) {

        freeaddrinfo(result);

    }

    if (l2tpv3->has_counter && l2tpv3->counter) {

        s->has_counter = true;

        s->offset += 4;

    } else {

        s->has_counter = false;

    }

    if (l2tpv3->has_pincounter && l2tpv3->pincounter) {

        s->has_counter = true;  /* pin counter implies that there is counter */

        s->pin_counter = true;

    } else {

        s->pin_counter = false;

    }

    if (l2tpv3->has_offset) {

        /* extra offset */

        s->offset += l2tpv3->offset;

    }

    if ((s->ipv6) || (s->udp)) {

        s->header_size = s->offset;

    } else {

        s->header_size = s->offset + sizeof(struct iphdr);

    }

    s->msgvec = build_l2tpv3_vector(s, MAX_L2TPV3_MSGCNT);

    s->vec = g_malloc(sizeof(struct iovec) * MAX_L2TPV3_IOVCNT);

    s->header_buf = g_malloc(s->header_size);

    qemu_set_nonblock(fd);

    s->fd = fd;

    s->counter = 0;

    l2tpv3_read_poll(s, true);

    snprintf(s->nc.info_str, sizeof(s->nc.info_str),

             "l2tpv3: connected");

    return 0;

outerr:

    qemu_del_net_client(nc);

    if (fd > 0) {

        close(fd);

    }

    if (result) {

        freeaddrinfo(result);

    }

    return -1;

}


static int subtitle_thread(void *arg)

{

    VideoState *is = arg;

    Frame *sp;

    int got_subtitle;

    double pts;

    int i, j;

    int r, g, b, y, u, v, a;

    for (;;) {

        while (is->paused && !is->subtitleq.abort_request) {

            SDL_Delay(10);

        }

        if (!(sp = frame_queue_peek_writable(&is->subpq)))

            return 0;

        if ((got_subtitle = decoder_decode_frame(&is->subdec, &sp->sub)) < 0)

            break;

        pts = 0;

        if (got_subtitle && sp->sub.format == 0) {

            if (sp->sub.pts != AV_NOPTS_VALUE)

                pts = sp->sub.pts / (double)AV_TIME_BASE;

            sp->pts = pts;

            sp->serial = is->subdec.pkt_serial;

            for (i = 0; i < sp->sub.num_rects; i++)

            {

                for (j = 0; j < sp->sub.rects[i]->nb_colors; j++)

                {

                    RGBA_IN(r, g, b, a, (uint32_t*)sp->sub.rects[i]->pict.data[1] + j);

                    y = RGB_TO_Y_CCIR(r, g, b);

                    u = RGB_TO_U_CCIR(r, g, b, 0);

                    v = RGB_TO_V_CCIR(r, g, b, 0);

                    YUVA_OUT((uint32_t*)sp->sub.rects[i]->pict.data[1] + j, y, u, v, a);

                }

            }

            /* now we can update the picture count */

            frame_queue_push(&is->subpq);

        } else if (got_subtitle) {

            avsubtitle_free(&sp->sub);

        }

    }

    return 0;

}


static av_cold int avisynth_load_library(void)

{

    avs_library.library = LoadLibrary(AVISYNTH_LIB);

    if (!avs_library.library)

        return AVERROR_UNKNOWN;

#define LOAD_AVS_FUNC(name, continue_on_fail)                          \

        avs_library.name =                                             \

            (void *)GetProcAddress(avs_library.library, #name);        \

        if (!continue_on_fail && !avs_library.name)                    \

            goto fail;

    LOAD_AVS_FUNC(avs_bit_blt, 0);

    LOAD_AVS_FUNC(avs_clip_get_error, 0);

    LOAD_AVS_FUNC(avs_create_script_environment, 0);

    LOAD_AVS_FUNC(avs_delete_script_environment, 0);

    LOAD_AVS_FUNC(avs_get_audio, 0);

    LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6

    LOAD_AVS_FUNC(avs_get_frame, 0);

    LOAD_AVS_FUNC(avs_get_version, 0);

    LOAD_AVS_FUNC(avs_get_video_info, 0);

    LOAD_AVS_FUNC(avs_invoke, 0);

    LOAD_AVS_FUNC(avs_release_clip, 0);

    LOAD_AVS_FUNC(avs_release_value, 0);

    LOAD_AVS_FUNC(avs_release_video_frame, 0);

    LOAD_AVS_FUNC(avs_take_clip, 0);

#ifdef USING_AVISYNTH

    LOAD_AVS_FUNC(avs_bits_per_pixel, 1);

    LOAD_AVS_FUNC(avs_get_height_p, 1);

    LOAD_AVS_FUNC(avs_get_pitch_p, 1);

    LOAD_AVS_FUNC(avs_get_read_ptr_p, 1);

    LOAD_AVS_FUNC(avs_get_row_size_p, 1);

    LOAD_AVS_FUNC(avs_is_yv24, 1);

    LOAD_AVS_FUNC(avs_is_yv16, 1);

    LOAD_AVS_FUNC(avs_is_yv411, 1);

    LOAD_AVS_FUNC(avs_is_y8, 1);

#endif

#undef LOAD_AVS_FUNC

    atexit(avisynth_atexit_handler);

    return 0;

fail:

    FreeLibrary(avs_library.library);

    return AVERROR_UNKNOWN;

}


static int decode_chunks(AVCodecContext *avctx,

                             AVFrame *picture, int *data_size,

                             const uint8_t *buf, int buf_size)

{

    Mpeg1Context *s = avctx->priv_data;

    MpegEncContext *s2 = &s->mpeg_enc_ctx;

    const uint8_t *buf_ptr = buf;

    const uint8_t *buf_end = buf + buf_size;

    int ret, input_size;

    int last_code= 0;

    for(;;) {

        /* find next start code */

        uint32_t start_code = -1;

        buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code);

        if (start_code > 0x1ff){

            if(s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT){

                if(avctx->thread_count > 1){

                    int i;

                    avctx->execute(avctx, slice_decode_thread,  &s2->thread_context[0], NULL, s->slice_count, sizeof(void*));

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

                        s2->error_count += s2->thread_context[i]->error_count;

                }

                if (CONFIG_MPEG_VDPAU_DECODER && avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU)

                    ff_vdpau_mpeg_picture_complete(s2, buf, buf_size, s->slice_count);

                if (slice_end(avctx, picture)) {

                    if(s2->last_picture_ptr || s2->low_delay) //FIXME merge with the stuff in mpeg_decode_slice

                        *data_size = sizeof(AVPicture);

                }

            }

            s2->pict_type= 0;

            return FFMAX(0, buf_ptr - buf - s2->parse_context.last_index);

        }

        input_size = buf_end - buf_ptr;

        if(avctx->debug & FF_DEBUG_STARTCODE){

            av_log(avctx, AV_LOG_DEBUG, "%3X at %td left %d\n", start_code, buf_ptr-buf, input_size);

        }

        /* prepare data for next start code */

        switch(start_code) {

        case SEQ_START_CODE:

            if(last_code == 0){

            mpeg1_decode_sequence(avctx, buf_ptr,

                                    input_size);

                s->sync=1;

            }else{

                av_log(avctx, AV_LOG_ERROR, "ignoring SEQ_START_CODE after %X\n", last_code);

            }

            break;

        case PICTURE_START_CODE:

            if (HAVE_THREADS && (avctx->active_thread_type&FF_THREAD_SLICE) && s->slice_count) {

                int i;

                avctx->execute(avctx, slice_decode_thread,

                               s2->thread_context, NULL,

                               s->slice_count, sizeof(void*));

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

                    s2->error_count += s2->thread_context[i]->error_count;

                s->slice_count = 0;

            }

            if(last_code == 0 || last_code == SLICE_MIN_START_CODE){

            if(mpeg_decode_postinit(avctx) < 0){

                av_log(avctx, AV_LOG_ERROR, "mpeg_decode_postinit() failure\n");

                return -1;

            }

            /* we have a complete image: we try to decompress it */

            if(mpeg1_decode_picture(avctx,

                                    buf_ptr, input_size) < 0)

                s2->pict_type=0;

                s2->first_slice = 1;

            last_code= PICTURE_START_CODE;

            }else{

                av_log(avctx, AV_LOG_ERROR, "ignoring pic after %X\n", last_code);

            }

            break;

        case EXT_START_CODE:

            init_get_bits(&s2->gb, buf_ptr, input_size*8);

            switch(get_bits(&s2->gb, 4)) {

            case 0x1:

                if(last_code == 0){

                mpeg_decode_sequence_extension(s);

                }else{

                    av_log(avctx, AV_LOG_ERROR, "ignoring seq ext after %X\n", last_code);

                }

                break;

            case 0x2:

                mpeg_decode_sequence_display_extension(s);

                break;

            case 0x3:

                mpeg_decode_quant_matrix_extension(s2);

                break;

            case 0x7:

                mpeg_decode_picture_display_extension(s);

                break;

            case 0x8:

                if(last_code == PICTURE_START_CODE){

                mpeg_decode_picture_coding_extension(s);

                }else{

                    av_log(avctx, AV_LOG_ERROR, "ignoring pic cod ext after %X\n", last_code);

                }

                break;

            }

            break;

        case USER_START_CODE:

            mpeg_decode_user_data(avctx,

                                    buf_ptr, input_size);

            break;

        case GOP_START_CODE:

            if(last_code == 0){

            s2->first_field=0;

            mpeg_decode_gop(avctx,

                                    buf_ptr, input_size);

                s->sync=1;

            }else{

                av_log(avctx, AV_LOG_ERROR, "ignoring GOP_START_CODE after %X\n", last_code);

            }

            break;

        default:

            if (start_code >= SLICE_MIN_START_CODE &&

                start_code <= SLICE_MAX_START_CODE && last_code!=0) {

                const int field_pic= s2->picture_structure != PICT_FRAME;

                int mb_y= (start_code - SLICE_MIN_START_CODE) << field_pic;

                last_code= SLICE_MIN_START_CODE;

                if(s2->picture_structure == PICT_BOTTOM_FIELD)

                    mb_y++;

                if (mb_y >= s2->mb_height){

                    av_log(s2->avctx, AV_LOG_ERROR, "slice below image (%d >= %d)\n", mb_y, s2->mb_height);

                    return -1;

                }

                if(s2->last_picture_ptr==NULL){

                /* Skip B-frames if we do not have reference frames and gop is not closed */

                    if(s2->pict_type==AV_PICTURE_TYPE_B){

                        if(!s2->closed_gop)

                            break;

                    }

                }

                if(s2->pict_type==AV_PICTURE_TYPE_I)

                    s->sync=1;

                if(s2->next_picture_ptr==NULL){

                /* Skip P-frames if we do not have a reference frame or we have an invalid header. */

                    if(s2->pict_type==AV_PICTURE_TYPE_P && !s->sync) break;

                }

                if(  (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==AV_PICTURE_TYPE_B)

                    ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=AV_PICTURE_TYPE_I)

                    || avctx->skip_frame >= AVDISCARD_ALL)

                    break;

                if (!s->mpeg_enc_ctx_allocated) break;

                if(s2->codec_id == CODEC_ID_MPEG2VIDEO){

                    if(mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)

                        break;

                }

                if(!s2->pict_type){

                    av_log(avctx, AV_LOG_ERROR, "Missing picture start code\n");

                    break;

                }

                if(s2->first_slice){

                    s2->first_slice=0;

                    if(mpeg_field_start(s2, buf, buf_size) < 0)

                        return -1;

                }

                if(!s2->current_picture_ptr){

                    av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");

                    return -1;

                }

                if (avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) {

                    s->slice_count++;

                    break;

                }

                if(avctx->thread_count > 1){

                    int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;

                    if(threshold <= mb_y){

                        MpegEncContext *thread_context= s2->thread_context[s->slice_count];

                        thread_context->start_mb_y= mb_y;

                        thread_context->end_mb_y  = s2->mb_height;

                        if(s->slice_count){

                            s2->thread_context[s->slice_count-1]->end_mb_y= mb_y;

                            ff_update_duplicate_context(thread_context, s2);

                        }

                        init_get_bits(&thread_context->gb, buf_ptr, input_size*8);

                        s->slice_count++;

                    }

                    buf_ptr += 2; //FIXME add minimum number of bytes per slice

                }else{

                    ret = mpeg_decode_slice(s, mb_y, &buf_ptr, input_size);

                    emms_c();

                    if(ret < 0){

                        if(s2->resync_mb_x>=0 && s2->resync_mb_y>=0)

                            ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);

                    }else{

                        ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, AC_END|DC_END|MV_END);

                    }

                }

            }

            break;

        }

    }

}


void cpu_ppc_store_decr (CPUState *env, uint32_t value)

{

    /* TO FIX */

}


static void do_closefd(Monitor *mon, const QDict *qdict)

{

    const char *fdname = qdict_get_str(qdict, "fdname");

    mon_fd_t *monfd;

    LIST_FOREACH(monfd, &mon->fds, next) {

        if (strcmp(monfd->name, fdname) != 0) {

            continue;

        }

        LIST_REMOVE(monfd, next);

        close(monfd->fd);

        qemu_free(monfd->name);

        qemu_free(monfd);

        return;

    }

    monitor_printf(mon, "Failed to find file descriptor named %s\n",

                   fdname);

}


int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,

                   const char *version, const char *serial, const char *model,

                   uint64_t wwn,

                   uint32_t cylinders, uint32_t heads, uint32_t secs,

                   int chs_trans)

{

    uint64_t nb_sectors;

    s->bs = bs;

    s->drive_kind = kind;

    bdrv_get_geometry(bs, &nb_sectors);

    if (cylinders < 1 || cylinders > 16383) {

        error_report("cyls must be between 1 and 16383");

        return -1;

    }

    if (heads < 1 || heads > 16) {

        error_report("heads must be between 1 and 16");

        return -1;

    }

    if (secs < 1 || secs > 63) {

        error_report("secs must be between 1 and 63");

        return -1;

    }

    s->cylinders = cylinders;

    s->heads = heads;

    s->sectors = secs;

    s->chs_trans = chs_trans;

    s->nb_sectors = nb_sectors;

    s->wwn = wwn;

    /* The SMART values should be preserved across power cycles

       but they aren't.  */

    s->smart_enabled = 1;

    s->smart_autosave = 1;

    s->smart_errors = 0;

    s->smart_selftest_count = 0;

    if (kind == IDE_CD) {

        bdrv_set_dev_ops(bs, &ide_cd_block_ops, s);

        bdrv_set_buffer_alignment(bs, 2048);

    } else {

        if (!bdrv_is_inserted(s->bs)) {

            error_report("Device needs media, but drive is empty");

            return -1;

        }

        if (bdrv_is_read_only(bs)) {

            error_report("Can't use a read-only drive");

            return -1;

        }

    }

    if (serial) {

        pstrcpy(s->drive_serial_str, sizeof(s->drive_serial_str), serial);

    } else {

        snprintf(s->drive_serial_str, sizeof(s->drive_serial_str),

                 "QM%05d", s->drive_serial);

    }

    if (model) {

        pstrcpy(s->drive_model_str, sizeof(s->drive_model_str), model);

    } else {

        switch (kind) {

        case IDE_CD:

            strcpy(s->drive_model_str, "QEMU DVD-ROM");

            break;

        case IDE_CFATA:

            strcpy(s->drive_model_str, "QEMU MICRODRIVE");

            break;

        default:

            strcpy(s->drive_model_str, "QEMU HARDDISK");

            break;

        }

    }

    if (version) {

        pstrcpy(s->version, sizeof(s->version), version);

    } else {

        pstrcpy(s->version, sizeof(s->version), qemu_get_version());

    }

    ide_reset(s);

    bdrv_iostatus_enable(bs);

    return 0;

}


static int decode_mb_cabac(H264Context *h) {

    MpegEncContext * const s = &h->s;

    const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;

    int mb_type, partition_count, cbp = 0;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    s->dsp.clear_blocks(h->mb); //FIXME avoid if already clear (move after skip handlong?)

    tprintf("pic:%d mb:%d/%d\n", h->frame_num, s->mb_x, s->mb_y);

    if( h->slice_type != I_TYPE && h->slice_type != SI_TYPE ) {

        int skip;

        /* a skipped mb needs the aff flag from the following mb */

        if( FRAME_MBAFF && s->mb_x==0 && (s->mb_y&1)==0 )

            predict_field_decoding_flag(h);

        if( FRAME_MBAFF && (s->mb_y&1)==1 && h->prev_mb_skipped )

            skip = h->next_mb_skipped;

        else

            skip = decode_cabac_mb_skip( h, s->mb_x, s->mb_y );

        /* read skip flags */

        if( skip ) {

            if( FRAME_MBAFF && (s->mb_y&1)==0 ){

                s->current_picture.mb_type[mb_xy] = MB_TYPE_SKIP;

                h->next_mb_skipped = decode_cabac_mb_skip( h, s->mb_x, s->mb_y+1 );

                if(h->next_mb_skipped)

                    predict_field_decoding_flag(h);

                else

                    h->mb_mbaff = h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);

            }

            decode_mb_skip(h);

            h->cbp_table[mb_xy] = 0;

            h->chroma_pred_mode_table[mb_xy] = 0;

            h->last_qscale_diff = 0;

            return 0;

        }

    }

    if(FRAME_MBAFF){

        if( (s->mb_y&1) == 0 )

            h->mb_mbaff =

            h->mb_field_decoding_flag = decode_cabac_field_decoding_flag(h);

    }else

        h->mb_field_decoding_flag= (s->picture_structure!=PICT_FRAME);

    h->prev_mb_skipped = 0;

    compute_mb_neighbors(h);

    if( ( mb_type = decode_cabac_mb_type( h ) ) < 0 ) {

        av_log( h->s.avctx, AV_LOG_ERROR, "decode_cabac_mb_type failed\n" );

        return -1;

    }

    if( h->slice_type == B_TYPE ) {

        if( mb_type < 23 ){

            partition_count= b_mb_type_info[mb_type].partition_count;

            mb_type=         b_mb_type_info[mb_type].type;

        }else{

            mb_type -= 23;

            goto decode_intra_mb;

        }

    } else if( h->slice_type == P_TYPE ) {

        if( mb_type < 5) {

            partition_count= p_mb_type_info[mb_type].partition_count;

            mb_type=         p_mb_type_info[mb_type].type;

        } else {

            mb_type -= 5;

            goto decode_intra_mb;

        }

    } else {

       assert(h->slice_type == I_TYPE);

decode_intra_mb:

        partition_count = 0;

        cbp= i_mb_type_info[mb_type].cbp;

        h->intra16x16_pred_mode= i_mb_type_info[mb_type].pred_mode;

        mb_type= i_mb_type_info[mb_type].type;

    }

    if(MB_FIELD)

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[ mb_xy ]= h->slice_num;

    if(IS_INTRA_PCM(mb_type)) {

        const uint8_t *ptr;

        unsigned int x, y;

        // We assume these blocks are very rare so we dont optimize it.

        // FIXME The two following lines get the bitstream position in the cabac

        // decode, I think it should be done by a function in cabac.h (or cabac.c).

        ptr= h->cabac.bytestream;

        if(h->cabac.low&0x1) ptr--;

        if(CABAC_BITS==16){

            if(h->cabac.low&0x1FF) ptr--;

        }

        // The pixels are stored in the same order as levels in h->mb array.

        for(y=0; y<16; y++){

            const int index= 4*(y&3) + 32*((y>>2)&1) + 128*(y>>3);

            for(x=0; x<16; x++){

                tprintf("LUMA ICPM LEVEL (%3d)\n", *ptr);

                h->mb[index + (x&3) + 16*((x>>2)&1) + 64*(x>>3)]= *ptr++;

            }

        }

        for(y=0; y<8; y++){

            const int index= 256 + 4*(y&3) + 32*(y>>2);

            for(x=0; x<8; x++){

                tprintf("CHROMA U ICPM LEVEL (%3d)\n", *ptr);

                h->mb[index + (x&3) + 16*(x>>2)]= *ptr++;

            }

        }

        for(y=0; y<8; y++){

            const int index= 256 + 64 + 4*(y&3) + 32*(y>>2);

            for(x=0; x<8; x++){

                tprintf("CHROMA V ICPM LEVEL (%3d)\n", *ptr);

                h->mb[index + (x&3) + 16*(x>>2)]= *ptr++;

            }

        }

        ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr);

        // All blocks are present

        h->cbp_table[mb_xy] = 0x1ef;

        h->chroma_pred_mode_table[mb_xy] = 0;

        // In deblocking, the quantizer is 0

        s->current_picture.qscale_table[mb_xy]= 0;

        h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, 0);

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 16);

        s->current_picture.mb_type[mb_xy]= mb_type;

        return 0;

    }

    if(MB_MBAFF){

        h->ref_count[0] <<= 1;

        h->ref_count[1] <<= 1;

    }

    fill_caches(h, mb_type, 0);

    if( IS_INTRA( mb_type ) ) {

        int i, pred_mode;

        if( IS_INTRA4x4( mb_type ) ) {

            if( dct8x8_allowed && decode_cabac_mb_transform_size( h ) ) {

                mb_type |= MB_TYPE_8x8DCT;

                for( i = 0; i < 16; i+=4 ) {

                    int pred = pred_intra_mode( h, i );

                    int mode = decode_cabac_mb_intra4x4_pred_mode( h, pred );

                    fill_rectangle( &h->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1 );

                }

            } else {

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

                    int pred = pred_intra_mode( h, i );

                    h->intra4x4_pred_mode_cache[ scan8[i] ] = decode_cabac_mb_intra4x4_pred_mode( h, pred );

                //av_log( s->avctx, AV_LOG_ERROR, "i4x4 pred=%d mode=%d\n", pred, h->intra4x4_pred_mode_cache[ scan8[i] ] );

                }

            }

            write_back_intra_pred_mode(h);

            if( check_intra4x4_pred_mode(h) < 0 ) return -1;

        } else {

            h->intra16x16_pred_mode= check_intra_pred_mode( h, h->intra16x16_pred_mode );

            if( h->intra16x16_pred_mode < 0 ) return -1;

        }

        h->chroma_pred_mode_table[mb_xy] =

        pred_mode                        = decode_cabac_mb_chroma_pre_mode( h );

        pred_mode= check_intra_pred_mode( h, pred_mode );

        if( pred_mode < 0 ) return -1;

        h->chroma_pred_mode= pred_mode;

    } else if( partition_count == 4 ) {

        int i, j, sub_partition_count[4], list, ref[2][4];

        if( h->slice_type == B_TYPE ) {

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

                h->sub_mb_type[i] = decode_cabac_b_mb_sub_type( h );

                sub_partition_count[i]= b_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      b_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

            if( IS_DIRECT(h->sub_mb_type[0] | h->sub_mb_type[1] |

                          h->sub_mb_type[2] | h->sub_mb_type[3]) ) {

                pred_direct_motion(h, &mb_type);

                if( h->ref_count[0] > 1 || h->ref_count[1] > 1 ) {

                    for( i = 0; i < 4; i++ )

                        if( IS_DIRECT(h->sub_mb_type[i]) )

                            fill_rectangle( &h->direct_cache[scan8[4*i]], 2, 2, 8, 1, 1 );

                }

            }

        } else {

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

                h->sub_mb_type[i] = decode_cabac_p_mb_sub_type( h );

                sub_partition_count[i]= p_sub_mb_type_info[ h->sub_mb_type[i] ].partition_count;

                h->sub_mb_type[i]=      p_sub_mb_type_info[ h->sub_mb_type[i] ].type;

            }

        }

        for( list = 0; list < h->list_count; list++ ) {

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

                    if(IS_DIRECT(h->sub_mb_type[i])) continue;

                    if(IS_DIR(h->sub_mb_type[i], 0, list)){

                        if( h->ref_count[list] > 1 )

                            ref[list][i] = decode_cabac_mb_ref( h, list, 4*i );

                        else

                            ref[list][i] = 0;

                    } else {

                        ref[list][i] = -1;

                    }

                                                       h->ref_cache[list][ scan8[4*i]+1 ]=

                    h->ref_cache[list][ scan8[4*i]+8 ]=h->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];

                }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h);

        for(list=0; list<h->list_count; list++){

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

                if(IS_DIRECT(h->sub_mb_type[i])){

                    fill_rectangle(h->mvd_cache[list][scan8[4*i]], 2, 2, 8, 0, 4);

                    continue;

                }

                h->ref_cache[list][ scan8[4*i]   ]=h->ref_cache[list][ scan8[4*i]+1 ];

                if(IS_DIR(h->sub_mb_type[i], 0, list) && !IS_DIRECT(h->sub_mb_type[i])){

                    const int sub_mb_type= h->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mpx, mpy;

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2]= &h->mv_cache[list][ scan8[index] ];

                        int16_t (* mvd_cache)[2]= &h->mvd_cache[list][ scan8[index] ];

                        pred_motion(h, index, block_width, list, h->ref_cache[list][ scan8[index] ], &mpx, &mpy);

                        mx = mpx + decode_cabac_mb_mvd( h, list, index, 0 );

                        my = mpy + decode_cabac_mb_mvd( h, list, index, 1 );

                        tprintf("final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                            mvd_cache[ 1 ][0]=

                            mvd_cache[ 8 ][0]= mvd_cache[ 9 ][0]= mx - mpx;

                            mvd_cache[ 1 ][1]=

                            mvd_cache[ 8 ][1]= mvd_cache[ 9 ][1]= my - mpy;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                            mvd_cache[ 1 ][0]= mx - mpx;

                            mvd_cache[ 1 ][1]= my - mpy;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                            mvd_cache[ 8 ][0]= mx - mpx;

                            mvd_cache[ 8 ][1]= my - mpy;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                        mvd_cache[ 0 ][0]= mx - mpx;

                        mvd_cache[ 0 ][1]= my - mpy;

                    }

                }else{

                    uint32_t *p= (uint32_t *)&h->mv_cache[list][ scan8[4*i] ][0];

                    uint32_t *pd= (uint32_t *)&h->mvd_cache[list][ scan8[4*i] ][0];

                    p[0] = p[1] = p[8] = p[9] = 0;

                    pd[0]= pd[1]= pd[8]= pd[9]= 0;

                }

            }

        }

    } else if( IS_DIRECT(mb_type) ) {

        pred_direct_motion(h, &mb_type);

        fill_rectangle(h->mvd_cache[0][scan8[0]], 4, 4, 8, 0, 4);

        fill_rectangle(h->mvd_cache[1][scan8[0]], 4, 4, 8, 0, 4);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    } else {

        int list, mx, my, i, mpx, mpy;

        if(IS_16X16(mb_type)){

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

                if(IS_DIR(mb_type, 0, list)){

                    if(h->ref_count[list] > 0 ){

                        const int ref = h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 0 ) : 0;

                        fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, ref, 1);

                    }

                }else

                    fill_rectangle(&h->ref_cache[list][ scan8[0] ], 4, 4, 8, (uint8_t)LIST_NOT_USED, 1);

            }

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

                if(IS_DIR(mb_type, 0, list)){

                    pred_motion(h, 0, 4, list, h->ref_cache[list][ scan8[0] ], &mpx, &mpy);

                    mx = mpx + decode_cabac_mb_mvd( h, list, 0, 0 );

                    my = mpy + decode_cabac_mb_mvd( h, list, 0, 1 );

                    tprintf("final mv:%d %d\n", mx, my);

                    fill_rectangle(h->mvd_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx-mpx,my-mpy), 4);

                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);

                }else

                    fill_rectangle(h->mv_cache[list][ scan8[0] ], 4, 4, 8, 0, 4);

            }

        }

        else if(IS_16X8(mb_type)){

            for(list=0; list<h->list_count; list++){

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

                        if(IS_DIR(mb_type, i, list)){

                            const int ref= h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 8*i ) : 0;

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, ref, 1);

                        }else

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    if(IS_DIR(mb_type, i, list)){

                        pred_16x8_motion(h, 8*i, list, h->ref_cache[list][scan8[0] + 16*i], &mpx, &mpy);

                        mx = mpx + decode_cabac_mb_mvd( h, list, 8*i, 0 );

                        my = mpy + decode_cabac_mb_mvd( h, list, 8*i, 1 );

                        tprintf("final mv:%d %d\n", mx, my);

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx-mpx,my-mpy), 4);

                        fill_rectangle(h->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);

                        fill_rectangle(h-> mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, 0, 4);

                    }

                }

            }

        }else{

            assert(IS_8X16(mb_type));

            for(list=0; list<h->list_count; list++){

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

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            const int ref= h->ref_count[list] > 1 ? decode_cabac_mb_ref( h, list, 4*i ) : 0;

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, ref, 1);

                        }else

                            fill_rectangle(&h->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, (LIST_NOT_USED&0xFF), 1);

                    }

            }

            for(list=0; list<h->list_count; list++){

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

                    if(IS_DIR(mb_type, i, list)){

                        pred_8x16_motion(h, i*4, list, h->ref_cache[list][ scan8[0] + 2*i ], &mpx, &mpy);

                        mx = mpx + decode_cabac_mb_mvd( h, list, 4*i, 0 );

                        my = mpy + decode_cabac_mb_mvd( h, list, 4*i, 1 );

                        tprintf("final mv:%d %d\n", mx, my);

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx-mpx,my-mpy), 4);

                        fill_rectangle(h->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, pack16to32(mx,my), 4);

                    }else{

                        fill_rectangle(h->mvd_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);

                        fill_rectangle(h-> mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, 0, 4);

                    }

                }

            }

        }

    }

   if( IS_INTER( mb_type ) ) {

        h->chroma_pred_mode_table[mb_xy] = 0;

        write_back_motion( h, mb_type );

   }

    if( !IS_INTRA16x16( mb_type ) ) {

        cbp  = decode_cabac_mb_cbp_luma( h );

        cbp |= decode_cabac_mb_cbp_chroma( h ) << 4;

    }

    h->cbp_table[mb_xy] = h->cbp = cbp;

    if( dct8x8_allowed && (cbp&15) && !IS_INTRA( mb_type ) ) {

        if( decode_cabac_mb_transform_size( h ) )

            mb_type |= MB_TYPE_8x8DCT;

    }

    s->current_picture.mb_type[mb_xy]= mb_type;

    if( cbp || IS_INTRA16x16( mb_type ) ) {

        const uint8_t *scan, *scan8x8, *dc_scan;

        int dqp;

        if(IS_INTERLACED(mb_type)){

            scan8x8= s->qscale ? h->field_scan8x8 : h->field_scan8x8_q0;

            scan= s->qscale ? h->field_scan : h->field_scan_q0;

            dc_scan= luma_dc_field_scan;

        }else{

            scan8x8= s->qscale ? h->zigzag_scan8x8 : h->zigzag_scan8x8_q0;

            scan= s->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

            dc_scan= luma_dc_zigzag_scan;

        }

        h->last_qscale_diff = dqp = decode_cabac_mb_dqp( h );

        if( dqp == INT_MIN ){

            av_log(h->s.avctx, AV_LOG_ERROR, "cabac decode of qscale diff failed at %d %d\n", s->mb_x, s->mb_y);

            return -1;

        }

        s->qscale += dqp;

        if(((unsigned)s->qscale) > 51){

            if(s->qscale<0) s->qscale+= 52;

            else            s->qscale-= 52;

        }

        h->chroma_qp = get_chroma_qp(h->pps.chroma_qp_index_offset, s->qscale);

        if( IS_INTRA16x16( mb_type ) ) {

            int i;

            //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 DC\n" );

            if( decode_cabac_residual( h, h->mb, 0, 0, dc_scan, NULL, 16) < 0)

                return -1;

            if( cbp&15 ) {

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

                    //av_log( s->avctx, AV_LOG_ERROR, "INTRA16x16 AC:%d\n", i );

                    if( decode_cabac_residual(h, h->mb + 16*i, 1, i, scan + 1, h->dequant4_coeff[0][s->qscale], 15) < 0 )

                        return -1;

                }

            } else {

                fill_rectangle(&h->non_zero_count_cache[scan8[0]], 4, 4, 8, 0, 1);

            }

        } else {

            int i8x8, i4x4;

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

                if( cbp & (1<<i8x8) ) {

                    if( IS_8x8DCT(mb_type) ) {

                        if( decode_cabac_residual(h, h->mb + 64*i8x8, 5, 4*i8x8,

                            scan8x8, h->dequant8_coeff[IS_INTRA( mb_type ) ? 0:1][s->qscale], 64) < 0 )

                            return -1;

                    } else

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

                        const int index = 4*i8x8 + i4x4;

                        //av_log( s->avctx, AV_LOG_ERROR, "Luma4x4: %d\n", index );

//START_TIMER

                        if( decode_cabac_residual(h, h->mb + 16*index, 2, index, scan, h->dequant4_coeff[IS_INTRA( mb_type ) ? 0:3][s->qscale], 16) < 0 )

                            return -1;

//STOP_TIMER("decode_residual")

                    }

                } else {

                    uint8_t * const nnz= &h->non_zero_count_cache[ scan8[4*i8x8] ];

                    nnz[0] = nnz[1] = nnz[8] = nnz[9] = 0;

                }

            }

        }

        if( cbp&0x30 ){

            int c;

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

                //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-DC\n",c );

                if( decode_cabac_residual(h, h->mb + 256 + 16*4*c, 3, c, chroma_dc_scan, NULL, 4) < 0)

                    return -1;

            }

        }

        if( cbp&0x20 ) {

            int c, i;

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

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

                    const int index = 16 + 4 * c + i;

                    //av_log( s->avctx, AV_LOG_ERROR, "INTRA C%d-AC %d\n",c, index - 16 );

                    if( decode_cabac_residual(h, h->mb + 16*index, 4, index - 16, scan + 1, h->dequant4_coeff[c+1+(IS_INTRA( mb_type ) ? 0:3)][h->chroma_qp], 15) < 0)

                        return -1;

                }

            }

        } else {

            uint8_t * const nnz= &h->non_zero_count_cache[0];

            nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =

            nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;

        }

    } else {

        uint8_t * const nnz= &h->non_zero_count_cache[0];

        fill_rectangle(&nnz[scan8[0]], 4, 4, 8, 0, 1);

        nnz[ scan8[16]+0 ] = nnz[ scan8[16]+1 ] =nnz[ scan8[16]+8 ] =nnz[ scan8[16]+9 ] =

        nnz[ scan8[20]+0 ] = nnz[ scan8[20]+1 ] =nnz[ scan8[20]+8 ] =nnz[ scan8[20]+9 ] = 0;

        h->last_qscale_diff = 0;

    }

    s->current_picture.qscale_table[mb_xy]= s->qscale;

    write_back_non_zero_count(h);

    if(MB_MBAFF){

        h->ref_count[0] >>= 1;

        h->ref_count[1] >>= 1;

    }

    return 0;

}


static inline int get_phys_addr(CPUState *env, uint32_t address,

                                int access_type, int is_user,

                                uint32_t *phys_ptr, int *prot)

{

    /* Fast Context Switch Extension.  */

    if (address < 0x02000000)

        address += env->cp15.c13_fcse;

    if ((env->cp15.c1_sys & 1) == 0) {

        /* MMU/MPU disabled.  */

        *phys_ptr = address;

        *prot = PAGE_READ | PAGE_WRITE;

        return 0;

    } else if (arm_feature(env, ARM_FEATURE_MPU)) {

	return get_phys_addr_mpu(env, address, access_type, is_user, phys_ptr,

				 prot);

    } else if (env->cp15.c1_sys & (1 << 23)) {

        return get_phys_addr_v6(env, address, access_type, is_user, phys_ptr,

                                prot);

    } else {

        return get_phys_addr_v5(env, address, access_type, is_user, phys_ptr,

                                prot);

    }

}


static void conditional_interrupt(DBDMA_channel *ch)

{

    dbdma_cmd *current = &ch->current;

    uint16_t intr;

    uint16_t sel_mask, sel_value;

    uint32_t status;

    int cond;

    DBDMA_DPRINTF("conditional_interrupt\n");

    intr = le16_to_cpu(current->command) & INTR_MASK;

    switch(intr) {

    case INTR_NEVER:  /* don't interrupt */

        return;

    case INTR_ALWAYS: /* always interrupt */

        qemu_irq_raise(ch->irq);

        return;

    }

    status = be32_to_cpu(ch->regs[DBDMA_STATUS]) & DEVSTAT;

    sel_mask = (be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) >> 16) & 0x0f;

    sel_value = be32_to_cpu(ch->regs[DBDMA_INTR_SEL]) & 0x0f;

    cond = (status & sel_mask) == (sel_value & sel_mask);

    switch(intr) {

    case INTR_IFSET:  /* intr if condition bit is 1 */

        if (cond)

            qemu_irq_raise(ch->irq);

        return;

    case INTR_IFCLR:  /* intr if condition bit is 0 */

        if (!cond)

            qemu_irq_raise(ch->irq);

        return;

    }

}


static int cloop_open(BlockDriverState *bs, QDict *options, int flags,

                      Error **errp)

{

    BDRVCloopState *s = bs->opaque;

    uint32_t offsets_size, max_compressed_block_size = 1, i;

    int ret;

    bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,

                               false, errp);

    if (!bs->file) {

        return -EINVAL;

    }

    bdrv_set_read_only(bs, true);

    /* read header */

    ret = bdrv_pread(bs->file, 128, &s->block_size, 4);

    if (ret < 0) {

        return ret;

    }

    s->block_size = be32_to_cpu(s->block_size);

    if (s->block_size % 512) {

        error_setg(errp, "block_size %" PRIu32 " must be a multiple of 512",

                   s->block_size);

        return -EINVAL;

    }

    if (s->block_size == 0) {

        error_setg(errp, "block_size cannot be zero");

        return -EINVAL;

    }

    /* cloop's create_compressed_fs.c warns about block sizes beyond 256 KB but

     * we can accept more.  Prevent ridiculous values like 4 GB - 1 since we

     * need a buffer this big.

     */

    if (s->block_size > MAX_BLOCK_SIZE) {

        error_setg(errp, "block_size %" PRIu32 " must be %u MB or less",

                   s->block_size,

                   MAX_BLOCK_SIZE / (1024 * 1024));

        return -EINVAL;

    }

    ret = bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4);

    if (ret < 0) {

        return ret;

    }

    s->n_blocks = be32_to_cpu(s->n_blocks);

    /* read offsets */

    if (s->n_blocks > (UINT32_MAX - 1) / sizeof(uint64_t)) {

        /* Prevent integer overflow */

        error_setg(errp, "n_blocks %" PRIu32 " must be %zu or less",

                   s->n_blocks,

                   (UINT32_MAX - 1) / sizeof(uint64_t));

        return -EINVAL;

    }

    offsets_size = (s->n_blocks + 1) * sizeof(uint64_t);

    if (offsets_size > 512 * 1024 * 1024) {

        /* Prevent ridiculous offsets_size which causes memory allocation to

         * fail or overflows bdrv_pread() size.  In practice the 512 MB

         * offsets[] limit supports 16 TB images at 256 KB block size.

         */

        error_setg(errp, "image requires too many offsets, "

                   "try increasing block size");

        return -EINVAL;

    }

    s->offsets = g_try_malloc(offsets_size);

    if (s->offsets == NULL) {

        error_setg(errp, "Could not allocate offsets table");

        return -ENOMEM;

    }

    ret = bdrv_pread(bs->file, 128 + 4 + 4, s->offsets, offsets_size);

    if (ret < 0) {

        goto fail;

    }

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

        uint64_t size;

        s->offsets[i] = be64_to_cpu(s->offsets[i]);

        if (i == 0) {

            continue;

        }

        if (s->offsets[i] < s->offsets[i - 1]) {

            error_setg(errp, "offsets not monotonically increasing at "

                       "index %" PRIu32 ", image file is corrupt", i);

            ret = -EINVAL;

            goto fail;

        }

        size = s->offsets[i] - s->offsets[i - 1];

        /* Compressed blocks should be smaller than the uncompressed block size

         * but maybe compression performed poorly so the compressed block is

         * actually bigger.  Clamp down on unrealistic values to prevent

         * ridiculous s->compressed_block allocation.

         */

        if (size > 2 * MAX_BLOCK_SIZE) {

            error_setg(errp, "invalid compressed block size at index %" PRIu32

                       ", image file is corrupt", i);

            ret = -EINVAL;

            goto fail;

        }

        if (size > max_compressed_block_size) {

            max_compressed_block_size = size;

        }

    }

    /* initialize zlib engine */

    s->compressed_block = g_try_malloc(max_compressed_block_size + 1);

    if (s->compressed_block == NULL) {

        error_setg(errp, "Could not allocate compressed_block");

        ret = -ENOMEM;

        goto fail;

    }

    s->uncompressed_block = g_try_malloc(s->block_size);

    if (s->uncompressed_block == NULL) {

        error_setg(errp, "Could not allocate uncompressed_block");

        ret = -ENOMEM;

        goto fail;

    }

    if (inflateInit(&s->zstream) != Z_OK) {

        ret = -EINVAL;

        goto fail;

    }

    s->current_block = s->n_blocks;

    s->sectors_per_block = s->block_size/512;

    bs->total_sectors = s->n_blocks * s->sectors_per_block;

    qemu_co_mutex_init(&s->lock);

    return 0;

fail:

    g_free(s->offsets);

    g_free(s->compressed_block);

    g_free(s->uncompressed_block);

    return ret;

}


static uint32_t sm501_palette_read(void *opaque, target_phys_addr_t addr)

{

    SM501State * s = (SM501State *)opaque;

    SM501_DPRINTF("sm501 palette read addr=%x\n", (int)addr);

    /* TODO : consider BYTE/WORD access */

    /* TODO : consider endian */

    assert(0 <= addr && addr < 0x400 * 3);

    return *(uint32_t*)&s->dc_palette[addr];

}


static void gen_spr_amr (CPUPPCState *env)

{

#ifndef CONFIG_USER_ONLY

    /* Virtual Page Class Key protection */

    /* The AMR is accessible either via SPR 13 or SPR 29.  13 is

     * userspace accessible, 29 is privileged.  So we only need to set

     * the kvm ONE_REG id on one of them, we use 29 */

    spr_register(env, SPR_UAMR, "UAMR",

                 &spr_read_uamr, &spr_write_uamr_pr,

                 &spr_read_uamr, &spr_write_uamr,

                 0);

    spr_register_kvm(env, SPR_AMR, "AMR",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_AMR, 0xffffffffffffffffULL);

    spr_register_kvm(env, SPR_UAMOR, "UAMOR",

                     SPR_NOACCESS, SPR_NOACCESS,

                     &spr_read_generic, &spr_write_generic,

                     KVM_REG_PPC_UAMOR, 0);

#endif /* !CONFIG_USER_ONLY */

}


static void set_kernel_args(const struct arm_boot_info *info)

{

    int initrd_size = info->initrd_size;

    target_phys_addr_t base = info->loader_start;

    target_phys_addr_t p;

    p = base + KERNEL_ARGS_ADDR;

    /* ATAG_CORE */

    WRITE_WORD(p, 5);

    WRITE_WORD(p, 0x54410001);

    WRITE_WORD(p, 1);

    WRITE_WORD(p, 0x1000);

    WRITE_WORD(p, 0);

    /* ATAG_MEM */

    /* TODO: handle multiple chips on one ATAG list */

    WRITE_WORD(p, 4);

    WRITE_WORD(p, 0x54410002);

    WRITE_WORD(p, info->ram_size);

    WRITE_WORD(p, info->loader_start);

    if (initrd_size) {

        /* ATAG_INITRD2 */

        WRITE_WORD(p, 4);

        WRITE_WORD(p, 0x54420005);

        WRITE_WORD(p, info->loader_start + INITRD_LOAD_ADDR);

        WRITE_WORD(p, initrd_size);

    }

    if (info->kernel_cmdline && *info->kernel_cmdline) {

        /* ATAG_CMDLINE */

        int cmdline_size;

        cmdline_size = strlen(info->kernel_cmdline);

        cpu_physical_memory_write(p + 8, (void *)info->kernel_cmdline,

                                  cmdline_size + 1);

        cmdline_size = (cmdline_size >> 2) + 1;

        WRITE_WORD(p, cmdline_size + 2);

        WRITE_WORD(p, 0x54410009);

        p += cmdline_size * 4;

    }

    if (info->atag_board) {

        /* ATAG_BOARD */

        int atag_board_len;

        uint8_t atag_board_buf[0x1000];

        atag_board_len = (info->atag_board(info, atag_board_buf) + 3) & ~3;

        WRITE_WORD(p, (atag_board_len + 8) >> 2);

        WRITE_WORD(p, 0x414f4d50);

        cpu_physical_memory_write(p, atag_board_buf, atag_board_len);

        p += atag_board_len;

    }

    /* ATAG_END */

    WRITE_WORD(p, 0);

    WRITE_WORD(p, 0);

}


static void ppc_powernv_init(MachineState *machine)

{

    PnvMachineState *pnv = POWERNV_MACHINE(machine);

    MemoryRegion *ram;

    char *fw_filename;

    long fw_size;

    int i;

    char *chip_typename;

    /* allocate RAM */

    if (machine->ram_size < (1 * G_BYTE)) {

        error_report("Warning: skiboot may not work with < 1GB of RAM");

    }

    ram = g_new(MemoryRegion, 1);

    memory_region_allocate_system_memory(ram, NULL, "ppc_powernv.ram",

                                         machine->ram_size);

    memory_region_add_subregion(get_system_memory(), 0, ram);

    /* load skiboot firmware  */

    if (bios_name == NULL) {

        bios_name = FW_FILE_NAME;

    }

    fw_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    fw_size = load_image_targphys(fw_filename, FW_LOAD_ADDR, FW_MAX_SIZE);

    if (fw_size < 0) {

        error_report("Could not load OPAL '%s'", fw_filename);

        exit(1);

    }

    g_free(fw_filename);

    /* load kernel */

    if (machine->kernel_filename) {

        long kernel_size;

        kernel_size = load_image_targphys(machine->kernel_filename,

                                          KERNEL_LOAD_ADDR, 0x2000000);

        if (kernel_size < 0) {

            error_report("Could not load kernel '%s'",

                         machine->kernel_filename);

            exit(1);

        }

    }

    /* load initrd */

    if (machine->initrd_filename) {

        pnv->initrd_base = INITRD_LOAD_ADDR;

        pnv->initrd_size = load_image_targphys(machine->initrd_filename,

                                  pnv->initrd_base, 0x10000000); /* 128MB max */

        if (pnv->initrd_size < 0) {

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

                         machine->initrd_filename);

            exit(1);

        }

    }

    /* We need some cpu model to instantiate the PnvChip class */

    if (machine->cpu_model == NULL) {

        machine->cpu_model = "POWER8";

    }

    /* Create the processor chips */

    chip_typename = g_strdup_printf(TYPE_PNV_CHIP "-%s", machine->cpu_model);

    if (!object_class_by_name(chip_typename)) {

        error_report("invalid CPU model '%s' for %s machine",

                     machine->cpu_model, MACHINE_GET_CLASS(machine)->name);

        exit(1);

    }

    pnv->chips = g_new0(PnvChip *, pnv->num_chips);

    for (i = 0; i < pnv->num_chips; i++) {

        char chip_name[32];

        Object *chip = object_new(chip_typename);

        pnv->chips[i] = PNV_CHIP(chip);

        /* TODO: put all the memory in one node on chip 0 until we find a

         * way to specify different ranges for each chip

         */

        if (i == 0) {

            object_property_set_int(chip, machine->ram_size, "ram-size",

                                    &error_fatal);

        }

        snprintf(chip_name, sizeof(chip_name), "chip[%d]", PNV_CHIP_HWID(i));

        object_property_add_child(OBJECT(pnv), chip_name, chip, &error_fatal);

        object_property_set_int(chip, PNV_CHIP_HWID(i), "chip-id",

                                &error_fatal);

        object_property_set_int(chip, smp_cores, "nr-cores", &error_fatal);

        object_property_set_bool(chip, true, "realized", &error_fatal);

    }

    g_free(chip_typename);

    /* Instantiate ISA bus on chip 0 */

    pnv->isa_bus = pnv_isa_create(pnv->chips[0]);

    /* Create serial port */

    serial_hds_isa_init(pnv->isa_bus, 0, MAX_SERIAL_PORTS);

    /* Create an RTC ISA device too */

    rtc_init(pnv->isa_bus, 2000, NULL);

    /* OpenPOWER systems use a IPMI SEL Event message to notify the

     * host to powerdown */

    pnv->powerdown_notifier.notify = pnv_powerdown_notify;

    qemu_register_powerdown_notifier(&pnv->powerdown_notifier);

}


static int proxy_remove(FsContext *ctx, const char *path)

{

    int retval;

    V9fsString name;

    v9fs_string_init(&name);

    v9fs_string_sprintf(&name, "%s", path);

    retval = v9fs_request(ctx->private, T_REMOVE, NULL, "s", &name);

    v9fs_string_free(&name);

    if (retval < 0) {

        errno = -retval;

    }

    return retval;

}


static uint64_t pxa2xx_ssp_read(void *opaque, hwaddr addr,

                                unsigned size)

{

    PXA2xxSSPState *s = (PXA2xxSSPState *) opaque;

    uint32_t retval;

    switch (addr) {

    case SSCR0:

        return s->sscr[0];

    case SSCR1:

        return s->sscr[1];

    case SSPSP:

        return s->sspsp;

    case SSTO:

        return s->ssto;

    case SSITR:

        return s->ssitr;

    case SSSR:

        return s->sssr | s->ssitr;

    case SSDR:

        if (!s->enable)

            return 0xffffffff;

        if (s->rx_level < 1) {

            printf("%s: SSP Rx Underrun\n", __FUNCTION__);

            return 0xffffffff;

        }

        s->rx_level --;

        retval = s->rx_fifo[s->rx_start ++];

        s->rx_start &= 0xf;

        pxa2xx_ssp_fifo_update(s);

        return retval;

    case SSTSA:

        return s->sstsa;

    case SSRSA:

        return s->ssrsa;

    case SSTSS:

        return 0;

    case SSACD:

        return s->ssacd;

    default:

        printf("%s: Bad register " REG_FMT "\n", __FUNCTION__, addr);

        break;

    }

    return 0;

}