static OutputStream *new_output_stream(OptionsContext *o, AVFormatContext *oc, enum AVMediaType type)

{

    OutputStream *ost;

    AVStream *st = avformat_new_stream(oc, NULL);

    int idx      = oc->nb_streams - 1, ret = 0;

    char *bsf = NULL, *next, *codec_tag = NULL;

    AVBitStreamFilterContext *bsfc, *bsfc_prev = NULL;

    double qscale = -1;

    char *buf = NULL, *arg = NULL, *preset = NULL;

    AVIOContext *s = NULL;

    if (!st) {

        av_log(NULL, AV_LOG_FATAL, "Could not alloc stream.\n");

        exit(1);

    }

    if (oc->nb_streams - 1 < o->nb_streamid_map)

        st->id = o->streamid_map[oc->nb_streams - 1];

    output_streams = grow_array(output_streams, sizeof(*output_streams), &nb_output_streams,

                                nb_output_streams + 1);

    if (!(ost = av_mallocz(sizeof(*ost))))

        exit(1);

    output_streams[nb_output_streams - 1] = ost;

    ost->file_index = nb_output_files;

    ost->index      = idx;

    ost->st         = st;

    st->codec->codec_type = type;

    choose_encoder(o, oc, ost);

    if (ost->enc) {

        ost->opts  = filter_codec_opts(codec_opts, ost->enc->id, oc, st, ost->enc);

    }

    avcodec_get_context_defaults3(st->codec, ost->enc);

    st->codec->codec_type = type; // XXX hack, avcodec_get_context_defaults2() sets type to unknown for stream copy

    MATCH_PER_STREAM_OPT(presets, str, preset, oc, st);

    if (preset && (!(ret = get_preset_file_2(preset, ost->enc->name, &s)))) {

        do  {

            buf = get_line(s);

            if (!buf[0] || buf[0] == '#') {

                av_free(buf);

                continue;

            }

            if (!(arg = strchr(buf, '='))) {

                av_log(NULL, AV_LOG_FATAL, "Invalid line found in the preset file.\n");

                exit(1);

            }

            *arg++ = 0;

            av_dict_set(&ost->opts, buf, arg, AV_DICT_DONT_OVERWRITE);

            av_free(buf);

        } while (!s->eof_reached);

        avio_close(s);

    }

    if (ret) {

        av_log(NULL, AV_LOG_FATAL,

               "Preset %s specified for stream %d:%d, but could not be opened.\n",

               preset, ost->file_index, ost->index);

        exit(1);

    }

    ost->max_frames = INT64_MAX;

    MATCH_PER_STREAM_OPT(max_frames, i64, ost->max_frames, oc, st);

    MATCH_PER_STREAM_OPT(bitstream_filters, str, bsf, oc, st);

    while (bsf) {

        if (next = strchr(bsf, ','))

            *next++ = 0;

        if (!(bsfc = av_bitstream_filter_init(bsf))) {

            av_log(NULL, AV_LOG_FATAL, "Unknown bitstream filter %s\n", bsf);

            exit(1);

        }

        if (bsfc_prev)

            bsfc_prev->next = bsfc;

        else

            ost->bitstream_filters = bsfc;

        bsfc_prev = bsfc;

        bsf       = next;

    }

    MATCH_PER_STREAM_OPT(codec_tags, str, codec_tag, oc, st);

    if (codec_tag) {

        uint32_t tag = strtol(codec_tag, &next, 0);

        if (*next)

            tag = AV_RL32(codec_tag);

        st->codec->codec_tag = tag;

    }

    MATCH_PER_STREAM_OPT(qscale, dbl, qscale, oc, st);

    if (qscale >= 0) {

        st->codec->flags |= CODEC_FLAG_QSCALE;

        st->codec->global_quality = FF_QP2LAMBDA * qscale;

    }

    if (oc->oformat->flags & AVFMT_GLOBALHEADER)

        st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

    av_opt_get_int(sws_opts, "sws_flags", 0, &ost->sws_flags);

    ost->pix_fmts[0] = ost->pix_fmts[1] = AV_PIX_FMT_NONE;

    return ost;

}


static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count)

{

    pthread_cond_wait(&c->last_job_cond, &c->current_job_lock);

    pthread_mutex_unlock(&c->current_job_lock);

}


static int xan_decode_frame_type1(AVCodecContext *avctx, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    XanContext *s = avctx->priv_data;

    uint8_t *ybuf, *src = s->scratch_buffer;

    int cur, last;

    int i, j;

    int ret;

    if ((ret = xan_decode_chroma(avctx, avpkt)) != 0)

        return ret;

    ret = xan_unpack_luma(buf + 16, avpkt->size - 16, src,

                          s->buffer_size >> 1);

    if (ret) {

        av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n");

        return ret;

    }

    ybuf = s->y_buffer;

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

        last = (ybuf[0] + (*src++ << 1)) & 0x3F;

        ybuf[0] = last;

        for (j = 1; j < avctx->width - 1; j += 2) {

            cur = (ybuf[j + 1] + (*src++ << 1)) & 0x3F;

            ybuf[j]   = (last + cur) >> 1;

            ybuf[j+1] = cur;

            last = cur;

        }

        ybuf[j] = last;

        ybuf += avctx->width;

    }

    src = s->y_buffer;

    ybuf = s->pic.data[0];

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

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

            ybuf[i] = (src[i] << 2) | (src[i] >> 3);

        src  += avctx->width;

        ybuf += s->pic.linesize[0];

    }

    return 0;

}


void ff_compute_frame_duration(AVFormatContext *s, int *pnum, int *pden, AVStream *st,

                               AVCodecParserContext *pc, AVPacket *pkt)

{

    AVRational codec_framerate = s->iformat ? st->codec->framerate :

                                              av_inv_q(st->codec->time_base);

    int frame_size;

    *pnum = 0;

    *pden = 0;

    switch (st->codec->codec_type) {

    case AVMEDIA_TYPE_VIDEO:

        if (st->r_frame_rate.num && !pc) {

            *pnum = st->r_frame_rate.den;

            *pden = st->r_frame_rate.num;

        } else if (st->time_base.num * 1000LL > st->time_base.den) {

            *pnum = st->time_base.num;

            *pden = st->time_base.den;

        } else if (codec_framerate.den * 1000LL > codec_framerate.num) {

            *pnum = codec_framerate.den;

            *pden = codec_framerate.num;

            *pden *= st->codec->ticks_per_frame;

            av_assert0(st->codec->ticks_per_frame);

            if (pc && pc->repeat_pict) {

                av_assert0(s->iformat); // this may be wrong for interlaced encoding but its not used for that case

                if (*pnum > INT_MAX / (1 + pc->repeat_pict))

                    *pden /= 1 + pc->repeat_pict;

                else

                    *pnum *= 1 + pc->repeat_pict;

            }

            /* If this codec can be interlaced or progressive then we need

             * a parser to compute duration of a packet. Thus if we have

             * no parser in such case leave duration undefined. */

            if (st->codec->ticks_per_frame > 1 && !pc)

                *pnum = *pden = 0;

        }

        break;

    case AVMEDIA_TYPE_AUDIO:

        frame_size = av_get_audio_frame_duration(st->codec, pkt->size);

        if (frame_size <= 0 || st->codec->sample_rate <= 0)

            break;

        *pnum = frame_size;

        *pden = st->codec->sample_rate;

        break;

    default:

        break;

    }

}


static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)

{

    int idx = 0;

    BlockBackend *new_blk = NULL;

    Error *local_err = NULL;

    char *desc = NULL;

    int64_t total_size = 0, filesize;

    char *adapter_type = NULL;

    char *backing_file = NULL;

    char *hw_version = NULL;

    char *fmt = NULL;

    int ret = 0;

    bool flat, split, compress;

    GString *ext_desc_lines;

    char *path = g_malloc0(PATH_MAX);

    char *prefix = g_malloc0(PATH_MAX);

    char *postfix = g_malloc0(PATH_MAX);

    char *desc_line = g_malloc0(BUF_SIZE);

    char *ext_filename = g_malloc0(PATH_MAX);

    char *desc_filename = g_malloc0(PATH_MAX);

    const int64_t split_size = 0x80000000;  /* VMDK has constant split size */

    const char *desc_extent_line;

    char *parent_desc_line = g_malloc0(BUF_SIZE);

    uint32_t parent_cid = 0xffffffff;

    uint32_t number_heads = 16;

    bool zeroed_grain = false;

    uint32_t desc_offset = 0, desc_len;

    const char desc_template[] =

        "# Disk DescriptorFile\n"

        "version=1\n"

        "CID=%" PRIx32 "\n"

        "parentCID=%" PRIx32 "\n"

        "createType=\"%s\"\n"

        "%s"

        "\n"

        "# Extent description\n"

        "%s"

        "\n"

        "# The Disk Data Base\n"

        "#DDB\n"

        "\n"

        "ddb.virtualHWVersion = \"%s\"\n"

        "ddb.geometry.cylinders = \"%" PRId64 "\"\n"

        "ddb.geometry.heads = \"%" PRIu32 "\"\n"

        "ddb.geometry.sectors = \"63\"\n"

        "ddb.adapterType = \"%s\"\n";

    ext_desc_lines = g_string_new(NULL);

    if (filename_decompose(filename, path, prefix, postfix, PATH_MAX, errp)) {

        ret = -EINVAL;

        goto exit;

    }

    /* Read out options */

    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),

                          BDRV_SECTOR_SIZE);

    adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);

    backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION);

    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false)) {

        if (strcmp(hw_version, "undefined")) {

            error_setg(errp,

                       "compat6 cannot be enabled with hwversion set");

            ret = -EINVAL;

            goto exit;

        }

        g_free(hw_version);

        hw_version = g_strdup("6");

    }

    if (strcmp(hw_version, "undefined") == 0) {

        g_free(hw_version);

        hw_version = g_strdup("4");

    }

    fmt = qemu_opt_get_del(opts, BLOCK_OPT_SUBFMT);

    if (qemu_opt_get_bool_del(opts, BLOCK_OPT_ZEROED_GRAIN, false)) {

        zeroed_grain = true;

    }

    if (!adapter_type) {

        adapter_type = g_strdup("ide");

    } else if (strcmp(adapter_type, "ide") &&

               strcmp(adapter_type, "buslogic") &&

               strcmp(adapter_type, "lsilogic") &&

               strcmp(adapter_type, "legacyESX")) {

        error_setg(errp, "Unknown adapter type: '%s'", adapter_type);

        ret = -EINVAL;

        goto exit;

    }

    if (strcmp(adapter_type, "ide") != 0) {

        /* that's the number of heads with which vmware operates when

           creating, exporting, etc. vmdk files with a non-ide adapter type */

        number_heads = 255;

    }

    if (!fmt) {

        /* Default format to monolithicSparse */

        fmt = g_strdup("monolithicSparse");

    } else if (strcmp(fmt, "monolithicFlat") &&

               strcmp(fmt, "monolithicSparse") &&

               strcmp(fmt, "twoGbMaxExtentSparse") &&

               strcmp(fmt, "twoGbMaxExtentFlat") &&

               strcmp(fmt, "streamOptimized")) {

        error_setg(errp, "Unknown subformat: '%s'", fmt);

        ret = -EINVAL;

        goto exit;

    }

    split = !(strcmp(fmt, "twoGbMaxExtentFlat") &&

              strcmp(fmt, "twoGbMaxExtentSparse"));

    flat = !(strcmp(fmt, "monolithicFlat") &&

             strcmp(fmt, "twoGbMaxExtentFlat"));

    compress = !strcmp(fmt, "streamOptimized");

    if (flat) {

        desc_extent_line = "RW %" PRId64 " FLAT \"%s\" 0\n";

    } else {

        desc_extent_line = "RW %" PRId64 " SPARSE \"%s\"\n";

    }

    if (flat && backing_file) {

        error_setg(errp, "Flat image can't have backing file");

        ret = -ENOTSUP;

        goto exit;

    }

    if (flat && zeroed_grain) {

        error_setg(errp, "Flat image can't enable zeroed grain");

        ret = -ENOTSUP;

        goto exit;

    }

    if (backing_file) {

        BlockBackend *blk;

        char *full_backing = g_new0(char, PATH_MAX);

        bdrv_get_full_backing_filename_from_filename(filename, backing_file,

                                                     full_backing, PATH_MAX,

                                                     &local_err);

        if (local_err) {

            g_free(full_backing);

            error_propagate(errp, local_err);

            ret = -ENOENT;

            goto exit;

        }

        blk = blk_new_open(full_backing, NULL, NULL,

                           BDRV_O_NO_BACKING, errp);

        g_free(full_backing);

        if (blk == NULL) {

            ret = -EIO;

            goto exit;

        }

        if (strcmp(blk_bs(blk)->drv->format_name, "vmdk")) {

            blk_unref(blk);

            ret = -EINVAL;

            goto exit;

        }

        parent_cid = vmdk_read_cid(blk_bs(blk), 0);

        blk_unref(blk);

        snprintf(parent_desc_line, BUF_SIZE,

                "parentFileNameHint=\"%s\"", backing_file);

    }

    /* Create extents */

    filesize = total_size;

    while (filesize > 0) {

        int64_t size = filesize;

        if (split && size > split_size) {

            size = split_size;

        }

        if (split) {

            snprintf(desc_filename, PATH_MAX, "%s-%c%03d%s",

                    prefix, flat ? 'f' : 's', ++idx, postfix);

        } else if (flat) {

            snprintf(desc_filename, PATH_MAX, "%s-flat%s", prefix, postfix);

        } else {

            snprintf(desc_filename, PATH_MAX, "%s%s", prefix, postfix);

        }

        snprintf(ext_filename, PATH_MAX, "%s%s", path, desc_filename);

        if (vmdk_create_extent(ext_filename, size,

                               flat, compress, zeroed_grain, opts, errp)) {

            ret = -EINVAL;

            goto exit;

        }

        filesize -= size;

        /* Format description line */

        snprintf(desc_line, BUF_SIZE,

                    desc_extent_line, size / BDRV_SECTOR_SIZE, desc_filename);

        g_string_append(ext_desc_lines, desc_line);

    }

    /* generate descriptor file */

    desc = g_strdup_printf(desc_template,

                           g_random_int(),

                           parent_cid,

                           fmt,

                           parent_desc_line,

                           ext_desc_lines->str,

                           hw_version,

                           total_size /

                               (int64_t)(63 * number_heads * BDRV_SECTOR_SIZE),

                           number_heads,

                           adapter_type);

    desc_len = strlen(desc);

    /* the descriptor offset = 0x200 */

    if (!split && !flat) {

        desc_offset = 0x200;

    } else {

        ret = bdrv_create_file(filename, opts, &local_err);

        if (ret < 0) {

            error_propagate(errp, local_err);

            goto exit;

        }

    }

    new_blk = blk_new_open(filename, NULL, NULL,

                           BDRV_O_RDWR | BDRV_O_RESIZE | BDRV_O_PROTOCOL,

                           &local_err);

    if (new_blk == NULL) {

        error_propagate(errp, local_err);

        ret = -EIO;

        goto exit;

    }

    blk_set_allow_write_beyond_eof(new_blk, true);

    ret = blk_pwrite(new_blk, desc_offset, desc, desc_len, 0);

    if (ret < 0) {

        error_setg_errno(errp, -ret, "Could not write description");

        goto exit;

    }

    /* bdrv_pwrite write padding zeros to align to sector, we don't need that

     * for description file */

    if (desc_offset == 0) {

        ret = blk_truncate(new_blk, desc_len, PREALLOC_MODE_OFF, errp);

    }

exit:

    if (new_blk) {

        blk_unref(new_blk);

    }

    g_free(adapter_type);

    g_free(backing_file);

    g_free(hw_version);

    g_free(fmt);

    g_free(desc);

    g_free(path);

    g_free(prefix);

    g_free(postfix);

    g_free(desc_line);

    g_free(ext_filename);

    g_free(desc_filename);

    g_free(parent_desc_line);

    g_string_free(ext_desc_lines, true);

    return ret;

}


static inline void RENAME(rgb24to16)(const uint8_t *src, uint8_t *dst, unsigned src_size)

{

	const uint8_t *s = src;

	const uint8_t *end;

#ifdef HAVE_MMX

	const uint8_t *mm_end;

#endif

	uint16_t *d = (uint16_t *)dst;

	end = s + src_size;

#ifdef HAVE_MMX

	__asm __volatile(PREFETCH"	%0"::"m"(*src):"memory");

	__asm __volatile(

	    "movq	%0, %%mm7\n\t"

	    "movq	%1, %%mm6\n\t"

	    ::"m"(red_16mask),"m"(green_16mask));

	mm_end = end - 11;

	while(s < mm_end)

	{

	    __asm __volatile(

		PREFETCH" 32%1\n\t"

		"movd	%1, %%mm0\n\t"

		"movd	3%1, %%mm3\n\t"

		"punpckldq 6%1, %%mm0\n\t"

		"punpckldq 9%1, %%mm3\n\t"

		"movq	%%mm0, %%mm1\n\t"

		"movq	%%mm0, %%mm2\n\t"

		"movq	%%mm3, %%mm4\n\t"

		"movq	%%mm3, %%mm5\n\t"

		"psrlq	$3, %%mm0\n\t"

		"psrlq	$3, %%mm3\n\t"

		"pand	%2, %%mm0\n\t"

		"pand	%2, %%mm3\n\t"

		"psrlq	$5, %%mm1\n\t"

		"psrlq	$5, %%mm4\n\t"

		"pand	%%mm6, %%mm1\n\t"

		"pand	%%mm6, %%mm4\n\t"

		"psrlq	$8, %%mm2\n\t"

		"psrlq	$8, %%mm5\n\t"

		"pand	%%mm7, %%mm2\n\t"

		"pand	%%mm7, %%mm5\n\t"

		"por	%%mm1, %%mm0\n\t"

		"por	%%mm4, %%mm3\n\t"

		"por	%%mm2, %%mm0\n\t"

		"por	%%mm5, %%mm3\n\t"

		"psllq	$16, %%mm3\n\t"

		"por	%%mm3, %%mm0\n\t"

		MOVNTQ"	%%mm0, %0\n\t"

		:"=m"(*d):"m"(*s),"m"(blue_16mask):"memory");

		d += 4;

		s += 12;

	}

	__asm __volatile(SFENCE:::"memory");

	__asm __volatile(EMMS:::"memory");

#endif

	while(s < end)

	{

		const int b= *s++;

		const int g= *s++;

		const int r= *s++;

		*d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);

	}

}


static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt)

{

    int stream_index = pkt->stream_index;

    int size         = pkt->size;

    uint8_t *buf     = pkt->data;

    MpegMuxContext *s = ctx->priv_data;

    AVStream *st      = ctx->streams[stream_index];

    StreamInfo *stream = st->priv_data;

    int64_t pts, dts;

    PacketDesc *pkt_desc;

    int preload;

    const int is_iframe = st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO &&

                          (pkt->flags & AV_PKT_FLAG_KEY);

    preload = av_rescale(s->preload, 90000, AV_TIME_BASE);

    pts = pkt->pts;

    dts = pkt->dts;

    if (s->last_scr == AV_NOPTS_VALUE) {

        if (dts == AV_NOPTS_VALUE || (dts < preload && ctx->avoid_negative_ts) || s->is_dvd) {

            if (dts != AV_NOPTS_VALUE)

                s->preload += av_rescale(-dts, AV_TIME_BASE, 90000);

            s->last_scr = 0;

        } else {

            s->last_scr = dts - preload;

            s->preload = 0;

        }

        preload = av_rescale(s->preload, 90000, AV_TIME_BASE);

        av_log(ctx, AV_LOG_DEBUG, "First SCR: %"PRId64" First DTS: %"PRId64"\n", s->last_scr, dts + preload);

    }

    if (dts != AV_NOPTS_VALUE) dts += preload;

    if (pts != AV_NOPTS_VALUE) pts += preload;

    av_log(ctx, AV_LOG_TRACE, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n",

            dts / 90000.0, pts / 90000.0, pkt->flags,

            pkt->stream_index, pts != AV_NOPTS_VALUE);

    if (!stream->premux_packet)

        stream->next_packet = &stream->premux_packet;

    *stream->next_packet     =

    pkt_desc                 = av_mallocz(sizeof(PacketDesc));

    pkt_desc->pts            = pts;

    pkt_desc->dts            = dts;

    pkt_desc->unwritten_size =

    pkt_desc->size           = size;

    if (!stream->predecode_packet)

        stream->predecode_packet = pkt_desc;

    stream->next_packet = &pkt_desc->next;

    if (av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size) < 0)

        return -1;

    if (s->is_dvd) {

        // min VOBU length 0.4 seconds (mpucoder)

        if (is_iframe &&

            (s->packet_number == 0 ||

             (pts - stream->vobu_start_pts >= 36000))) {

            stream->bytes_to_iframe = av_fifo_size(stream->fifo);

            stream->align_iframe    = 1;

            stream->vobu_start_pts  = pts;

        }

    }

    av_fifo_generic_write(stream->fifo, buf, size, NULL);

    for (;;) {

        int ret = output_packet(ctx, 0);

        if (ret <= 0)

            return ret;

    }

}


static int image_probe(AVProbeData *p)

{

    if (av_str2id(img_tags, p->filename)) {

        if (av_filename_number_test(p->filename))

            return AVPROBE_SCORE_MAX;

        else

            return AVPROBE_SCORE_MAX/2;

    }

    return 0;

}


uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size)

{

    AVDictionaryEntry *t = NULL;

    uint8_t *data = NULL;

    *size = 0;

    if (!dict)

        return NULL;

    while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) {

        const int keylen = strlen(t->key);

        const int valuelen = strlen(t->value);

        const size_t new_size = *size + keylen + 1 + valuelen + 1;

        uint8_t *const new_data = av_realloc(data, new_size);

        if (!new_data)

            goto fail;

        data = new_data;

        memcpy(data + *size, t->key, keylen + 1);

        memcpy(data + *size + keylen + 1, t->value, valuelen + 1);

        *size = new_size;

    }

    return data;

fail:

    av_freep(&data);

    *size = 0;

    return NULL;

}


int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs,

                                const int16_t *in, int buffer_length,

                                int filter_length, int stop_on_overflow,

                                int shift, int rounder)

{

    int i,n;

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

        int sum = -rounder, sum1;

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

            sum += filter_coeffs[i-1] * out[n-i];

        sum1 = ((-sum >> 12) + in[n]) >> shift;

        sum  = av_clip_int16(sum1);

        if (stop_on_overflow && sum != sum1)

            return 1;

        out[n] = sum;

    }

    return 0;

}


uint32_t ide_data_readw(void *opaque, uint32_t addr)

{

    IDEBus *bus = opaque;

    IDEState *s = idebus_active_if(bus);

    uint8_t *p;

    int ret;

    /* PIO data access allowed only when DRQ bit is set. The result of a read

     * during PIO in is indeterminate, return 0 and don't move forward. */

    if (!(s->status & DRQ_STAT) || !ide_is_pio_out(s)) {

        return 0;

    }

    p = s->data_ptr;

    if (p + 2 > s->data_end) {

        return 0;

    }

    ret = cpu_to_le16(*(uint16_t *)p);

    p += 2;

    s->data_ptr = p;

    if (p >= s->data_end)

        s->end_transfer_func(s);

    return ret;

}


int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp)

{

    char backing_filename[PATH_MAX];

    int back_flags, ret;

    BlockDriver *back_drv = NULL;

    Error *local_err = NULL;

    if (bs->backing_hd != NULL) {

        QDECREF(options);

        return 0;

    }

    /* NULL means an empty set of options */

    if (options == NULL) {

        options = qdict_new();

    }

    bs->open_flags &= ~BDRV_O_NO_BACKING;

    if (qdict_haskey(options, "file.filename")) {

        backing_filename[0] = '\0';

    } else if (bs->backing_file[0] == '\0' && qdict_size(options) == 0) {

        QDECREF(options);

        return 0;

    } else {

        bdrv_get_full_backing_filename(bs, backing_filename,

                                       sizeof(backing_filename));

    }

    bs->backing_hd = bdrv_new("");

    if (bs->backing_format[0] != '\0') {

        back_drv = bdrv_find_format(bs->backing_format);

    }

    /* backing files always opened read-only */

    back_flags = bs->open_flags & ~(BDRV_O_RDWR | BDRV_O_SNAPSHOT);

    ret = bdrv_open(bs->backing_hd,

                    *backing_filename ? backing_filename : NULL, options,

                    back_flags, back_drv, &local_err);

    pstrcpy(bs->backing_file, sizeof(bs->backing_file),

            bs->backing_hd->file->filename);

    if (ret < 0) {

        bdrv_unref(bs->backing_hd);

        bs->backing_hd = NULL;

        bs->open_flags |= BDRV_O_NO_BACKING;

        error_propagate(errp, local_err);

        return ret;

    }

    return 0;

}


static int do_readlink(struct iovec *iovec, struct iovec *out_iovec)

{

    char *buffer;

    int size, retval;

    V9fsString target, path;

    v9fs_string_init(&path);

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

    if (retval < 0) {

        v9fs_string_free(&path);

        return retval;

    }

    buffer = g_malloc(size);

    v9fs_string_init(&target);

    retval = readlink(path.data, buffer, size);

    if (retval > 0) {

        buffer[retval] = '\0';

        v9fs_string_sprintf(&target, "%s", buffer);

        retval = proxy_marshal(out_iovec, PROXY_HDR_SZ, "s", &target);

    } else {

        retval = -errno;

    }

    g_free(buffer);

    v9fs_string_free(&target);

    v9fs_string_free(&path);

    return retval;

}


static int build_table(VLC *vlc, int table_nb_bits,

                       int nb_codes,

                       const void *bits, int bits_wrap, int bits_size,

                       const void *codes, int codes_wrap, int codes_size,

                       const void *symbols, int symbols_wrap, int symbols_size,

                       uint32_t code_prefix, int n_prefix, int flags)

{

    int i, j, k, n, table_size, table_index, nb, n1, index, code_prefix2, symbol;

    uint32_t code;

    VLC_TYPE (*table)[2];

    table_size = 1 << table_nb_bits;

    table_index = alloc_table(vlc, table_size, flags & INIT_VLC_USE_NEW_STATIC);

#ifdef DEBUG_VLC

    av_log(NULL,AV_LOG_DEBUG,"new table index=%d size=%d code_prefix=%x n=%d\n",

           table_index, table_size, code_prefix, n_prefix);

#endif

    if (table_index < 0)

        return -1;

    table = &vlc->table[table_index];

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

        table[i][1] = 0; //bits

        table[i][0] = -1; //codes

    }

    /* first pass: map codes and compute auxillary table sizes */

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

        GET_DATA(n, bits, i, bits_wrap, bits_size);

        GET_DATA(code, codes, i, codes_wrap, codes_size);

        /* we accept tables with holes */

        if (n <= 0)

            continue;

        if (!symbols)

            symbol = i;

        else

            GET_DATA(symbol, symbols, i, symbols_wrap, symbols_size);

#if defined(DEBUG_VLC) && 0

        av_log(NULL,AV_LOG_DEBUG,"i=%d n=%d code=0x%x\n", i, n, code);

#endif

        /* if code matches the prefix, it is in the table */

        n -= n_prefix;

        if(flags & INIT_VLC_LE)

            code_prefix2= code & (n_prefix>=32 ? 0xffffffff : (1 << n_prefix)-1);

        else

            code_prefix2= code >> n;

        if (n > 0 && code_prefix2 == code_prefix) {

            if (n <= table_nb_bits) {

                /* no need to add another table */

                j = (code << (table_nb_bits - n)) & (table_size - 1);

                nb = 1 << (table_nb_bits - n);

                for(k=0;k<nb;k++) {

                    if(flags & INIT_VLC_LE)

                        j = (code >> n_prefix) + (k<<n);

#ifdef DEBUG_VLC

                    av_log(NULL, AV_LOG_DEBUG, "%4x: code=%d n=%d\n",

                           j, i, n);

#endif

                    if (table[j][1] /*bits*/ != 0) {

                        av_log(NULL, AV_LOG_ERROR, "incorrect codes\n");

                        return -1;

                    }

                    table[j][1] = n; //bits

                    table[j][0] = symbol;

                    j++;

                }

            } else {

                n -= table_nb_bits;

                j = (code >> ((flags & INIT_VLC_LE) ? n_prefix : n)) & ((1 << table_nb_bits) - 1);

#ifdef DEBUG_VLC

                av_log(NULL,AV_LOG_DEBUG,"%4x: n=%d (subtable)\n",

                       j, n);

#endif

                /* compute table size */

                n1 = -table[j][1]; //bits

                if (n > n1)

                    n1 = n;

                table[j][1] = -n1; //bits

            }

        }

    }

    /* second pass : fill auxillary tables recursively */

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

        n = table[i][1]; //bits

        if (n < 0) {

            n = -n;

            if (n > table_nb_bits) {

                n = table_nb_bits;

                table[i][1] = -n; //bits

            }

            index = build_table(vlc, n, nb_codes,

                                bits, bits_wrap, bits_size,

                                codes, codes_wrap, codes_size,

                                symbols, symbols_wrap, symbols_size,

                                (flags & INIT_VLC_LE) ? (code_prefix | (i << n_prefix)) : ((code_prefix << table_nb_bits) | i),

                                n_prefix + table_nb_bits, flags);

            if (index < 0)

                return -1;

            /* note: realloc has been done, so reload tables */

            table = &vlc->table[table_index];

            table[i][0] = index; //code

        }

    }

    return table_index;

}


static int mp_decode_layer3(MPADecodeContext *s)

{

    int nb_granules, main_data_begin;

    int gr, ch, blocksplit_flag, i, j, k, n, bits_pos;

    GranuleDef *g;

    int16_t exponents[576]; //FIXME try INTFLOAT

    /* read side info */

    if (s->lsf) {

        main_data_begin = get_bits(&s->gb, 8);

        skip_bits(&s->gb, s->nb_channels);

        nb_granules = 1;

    } else {

        main_data_begin = get_bits(&s->gb, 9);

        if (s->nb_channels == 2)

            skip_bits(&s->gb, 3);

        else

            skip_bits(&s->gb, 5);

        nb_granules = 2;

        for (ch = 0; ch < s->nb_channels; ch++) {

            s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */

            s->granules[ch][1].scfsi = get_bits(&s->gb, 4);

        }

    }

    for (gr = 0; gr < nb_granules; gr++) {

        for (ch = 0; ch < s->nb_channels; ch++) {

            av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch);

            g = &s->granules[ch][gr];

            g->part2_3_length = get_bits(&s->gb, 12);

            g->big_values     = get_bits(&s->gb,  9);

            if (g->big_values > 288) {

                av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n");

                return AVERROR_INVALIDDATA;

            }

            g->global_gain = get_bits(&s->gb, 8);

            /* if MS stereo only is selected, we precompute the

               1/sqrt(2) renormalization factor */

            if ((s->mode_ext & (MODE_EXT_MS_STEREO | MODE_EXT_I_STEREO)) ==

                MODE_EXT_MS_STEREO)

                g->global_gain -= 2;

            if (s->lsf)

                g->scalefac_compress = get_bits(&s->gb, 9);

            else

                g->scalefac_compress = get_bits(&s->gb, 4);

            blocksplit_flag = get_bits1(&s->gb);

            if (blocksplit_flag) {

                g->block_type = get_bits(&s->gb, 2);

                if (g->block_type == 0) {

                    av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n");

                    return AVERROR_INVALIDDATA;

                }

                g->switch_point = get_bits1(&s->gb);

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

                    g->table_select[i] = get_bits(&s->gb, 5);

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

                    g->subblock_gain[i] = get_bits(&s->gb, 3);

                ff_init_short_region(s, g);

            } else {

                int region_address1, region_address2;

                g->block_type = 0;

                g->switch_point = 0;

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

                    g->table_select[i] = get_bits(&s->gb, 5);

                /* compute huffman coded region sizes */

                region_address1 = get_bits(&s->gb, 4);

                region_address2 = get_bits(&s->gb, 3);

                av_dlog(s->avctx, "region1=%d region2=%d\n",

                        region_address1, region_address2);

                ff_init_long_region(s, g, region_address1, region_address2);

            }

            ff_region_offset2size(g);

            ff_compute_band_indexes(s, g);

            g->preflag = 0;

            if (!s->lsf)

                g->preflag = get_bits1(&s->gb);

            g->scalefac_scale     = get_bits1(&s->gb);

            g->count1table_select = get_bits1(&s->gb);

            av_dlog(s->avctx, "block_type=%d switch_point=%d\n",

                    g->block_type, g->switch_point);

        }

    }

    if (!s->adu_mode) {

        const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3);

        assert((get_bits_count(&s->gb) & 7) == 0);

        /* now we get bits from the main_data_begin offset */

        av_dlog(s->avctx, "seekback: %d\n", main_data_begin);

    //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size);

        memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES);

        s->in_gb = s->gb;

        init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8);

#if !UNCHECKED_BITSTREAM_READER

        s->gb.size_in_bits_plus8 += EXTRABYTES * 8;

#endif

        s->last_buf_size <<= 3;

        for (gr = 0, ch = 0; gr < nb_granules && (s->last_buf_size >> 3) < main_data_begin; gr++, ch = 0) {

            for (; ch < s->nb_channels && (s->last_buf_size >> 3) < main_data_begin; ch++) {

                g = &s->granules[ch][gr];

                s->last_buf_size += g->part2_3_length;

                memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid));

            }

        }

        skip_bits_long(&s->gb, s->last_buf_size - 8 * main_data_begin);

        if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) {

            skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits);

            s->gb           = s->in_gb;

            s->in_gb.buffer = NULL;

        }

    } else {

        gr = ch = 0;

    }

    for (; gr < nb_granules; gr++, ch = 0) {

        for (; ch < s->nb_channels; ch++) {

            g = &s->granules[ch][gr];

            bits_pos = get_bits_count(&s->gb);

            if (!s->lsf) {

                uint8_t *sc;

                int slen, slen1, slen2;

                /* MPEG1 scale factors */

                slen1 = slen_table[0][g->scalefac_compress];

                slen2 = slen_table[1][g->scalefac_compress];

                av_dlog(s->avctx, "slen1=%d slen2=%d\n", slen1, slen2);

                if (g->block_type == 2) {

                    n = g->switch_point ? 17 : 18;

                    j = 0;

                    if (slen1) {

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

                            g->scale_factors[j++] = get_bits(&s->gb, slen1);

                    } else {

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

                            g->scale_factors[j++] = 0;

                    }

                    if (slen2) {

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

                            g->scale_factors[j++] = get_bits(&s->gb, slen2);

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

                            g->scale_factors[j++] = 0;

                    } else {

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

                            g->scale_factors[j++] = 0;

                    }

                } else {

                    sc = s->granules[ch][0].scale_factors;

                    j = 0;

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

                        n = k == 0 ? 6 : 5;

                        if ((g->scfsi & (0x8 >> k)) == 0) {

                            slen = (k < 2) ? slen1 : slen2;

                            if (slen) {

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

                                    g->scale_factors[j++] = get_bits(&s->gb, slen);

                            } else {

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

                                    g->scale_factors[j++] = 0;

                            }

                        } else {

                            /* simply copy from last granule */

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

                                g->scale_factors[j] = sc[j];

                                j++;

                            }

                        }

                    }

                    g->scale_factors[j++] = 0;

                }

            } else {

                int tindex, tindex2, slen[4], sl, sf;

                /* LSF scale factors */

                if (g->block_type == 2)

                    tindex = g->switch_point ? 2 : 1;

                else

                    tindex = 0;

                sf = g->scalefac_compress;

                if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) {

                    /* intensity stereo case */

                    sf >>= 1;

                    if (sf < 180) {

                        lsf_sf_expand(slen, sf, 6, 6, 0);

                        tindex2 = 3;

                    } else if (sf < 244) {

                        lsf_sf_expand(slen, sf - 180, 4, 4, 0);

                        tindex2 = 4;

                    } else {

                        lsf_sf_expand(slen, sf - 244, 3, 0, 0);

                        tindex2 = 5;

                    }

                } else {

                    /* normal case */

                    if (sf < 400) {

                        lsf_sf_expand(slen, sf, 5, 4, 4);

                        tindex2 = 0;

                    } else if (sf < 500) {

                        lsf_sf_expand(slen, sf - 400, 5, 4, 0);

                        tindex2 = 1;

                    } else {

                        lsf_sf_expand(slen, sf - 500, 3, 0, 0);

                        tindex2 = 2;

                        g->preflag = 1;

                    }

                }

                j = 0;

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

                    n  = lsf_nsf_table[tindex2][tindex][k];

                    sl = slen[k];

                    if (sl) {

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

                            g->scale_factors[j++] = get_bits(&s->gb, sl);

                    } else {

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

                            g->scale_factors[j++] = 0;

                    }

                }

                /* XXX: should compute exact size */

                for (; j < 40; j++)

                    g->scale_factors[j] = 0;

            }

            exponents_from_scale_factors(s, g, exponents);

            /* read Huffman coded residue */

            huffman_decode(s, g, exponents, bits_pos + g->part2_3_length);

        } /* ch */

        if (s->nb_channels == 2)

            compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]);

        for (ch = 0; ch < s->nb_channels; ch++) {

            g = &s->granules[ch][gr];

            reorder_block(s, g);

            compute_antialias(s, g);

            compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]);

        }

    } /* gr */

    if (get_bits_count(&s->gb) < 0)

        skip_bits_long(&s->gb, -get_bits_count(&s->gb));

    return nb_granules * 18;

}


static inline void RENAME(yuy2ToY)(uint8_t *dst, uint8_t *src, long width)

{

#ifdef HAVE_MMX

	asm volatile(

		"movq "MANGLE(bm01010101)", %%mm2\n\t"

		"mov %0, %%"REG_a"		\n\t"

		"1:				\n\t"

		"movq (%1, %%"REG_a",2), %%mm0	\n\t"

		"movq 8(%1, %%"REG_a",2), %%mm1	\n\t"

		"pand %%mm2, %%mm0		\n\t"

		"pand %%mm2, %%mm1		\n\t"

		"packuswb %%mm1, %%mm0		\n\t"

		"movq %%mm0, (%2, %%"REG_a")	\n\t"

		"add $8, %%"REG_a"		\n\t"

		" js 1b				\n\t"

		: : "g" (-width), "r" (src+width*2), "r" (dst+width)

		: "%"REG_a

	);

#else

	int i;

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

		dst[i]= src[2*i];

#endif

}


BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity,

                                          Error **errp)

{

    int64_t bitmap_size;

    BdrvDirtyBitmap *bitmap;

    assert((granularity & (granularity - 1)) == 0);

    granularity >>= BDRV_SECTOR_BITS;

    assert(granularity);

    bitmap_size = bdrv_nb_sectors(bs);

    if (bitmap_size < 0) {

        error_setg_errno(errp, -bitmap_size, "could not get length of device");

        errno = -bitmap_size;

        return NULL;

    }

    bitmap = g_malloc0(sizeof(BdrvDirtyBitmap));

    bitmap->bitmap = hbitmap_alloc(bitmap_size, ffs(granularity) - 1);

    QLIST_INSERT_HEAD(&bs->dirty_bitmaps, bitmap, list);

    return bitmap;

}


static void FUNC(put_hevc_pel_bi_w_pixels)(uint8_t *_dst, ptrdiff_t _dststride, uint8_t *_src, ptrdiff_t _srcstride,

                                           int16_t *src2,

                                           int height, int denom, int wx0, int wx1,

                                           int ox0, int ox1, intptr_t mx, intptr_t my, int width)

{

    int x, y;

    pixel *src          = (pixel *)_src;

    ptrdiff_t srcstride = _srcstride / sizeof(pixel);

    pixel *dst          = (pixel *)_dst;

    ptrdiff_t dststride = _dststride / sizeof(pixel);

    int shift = 14  + 1 - BIT_DEPTH;

    int log2Wd = denom + shift - 1;

    ox0     = ox0 * (1 << (BIT_DEPTH - 8));

    ox1     = ox1 * (1 << (BIT_DEPTH - 8));

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

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

            dst[x] = av_clip_pixel(( (src[x] << (14 - BIT_DEPTH)) * wx1 + src2[x] * wx0 + ((ox0 + ox1 + 1) << log2Wd)) >> (log2Wd + 1));

        }

        src  += srcstride;

        dst  += dststride;

        src2 += MAX_PB_SIZE;

    }

}


static int compat_decode(AVCodecContext *avctx, AVFrame *frame,

                         int *got_frame, const AVPacket *pkt)

{

    AVCodecInternal *avci = avctx->internal;

    int ret;

    av_assert0(avci->compat_decode_consumed == 0);

    *got_frame = 0;

    avci->compat_decode = 1;

    if (avci->compat_decode_partial_size > 0 &&

        avci->compat_decode_partial_size != pkt->size) {

        av_log(avctx, AV_LOG_ERROR,

               "Got unexpected packet size after a partial decode\n");

        ret = AVERROR(EINVAL);

        goto finish;

    }

    if (!avci->compat_decode_partial_size) {

        ret = avcodec_send_packet(avctx, pkt);

        if (ret == AVERROR_EOF)

            ret = 0;

        else if (ret == AVERROR(EAGAIN)) {

            /* we fully drain all the output in each decode call, so this should not

             * ever happen */

            ret = AVERROR_BUG;

            goto finish;

        } else if (ret < 0)

            goto finish;

    }

    while (ret >= 0) {

        ret = avcodec_receive_frame(avctx, frame);

        if (ret < 0) {

            if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)

                ret = 0;

            goto finish;

        }

        if (frame != avci->compat_decode_frame) {

            if (!avctx->refcounted_frames) {

                ret = unrefcount_frame(avci, frame);

                if (ret < 0)

                    goto finish;

            }

            *got_frame = 1;

            frame = avci->compat_decode_frame;

        } else {

            if (!avci->compat_decode_warned) {

                av_log(avctx, AV_LOG_WARNING, "The deprecated avcodec_decode_* "

                       "API cannot return all the frames for this decoder. "

                       "Some frames will be dropped. Update your code to the "

                       "new decoding API to fix this.\n");

                avci->compat_decode_warned = 1;

            }

        }

        if (avci->draining || (!avctx->codec->bsfs && avci->compat_decode_consumed < pkt->size))

            break;

    }

finish:

    if (ret == 0) {

        /* if there are any bsfs then assume full packet is always consumed */

        if (avctx->codec->bsfs)

            ret = pkt->size;

        else

            ret = FFMIN(avci->compat_decode_consumed, pkt->size);

    }

    avci->compat_decode_consumed = 0;

    avci->compat_decode_partial_size = (ret >= 0) ? pkt->size - ret : 0;

    return ret;

}


static av_cold void common_init(MpegEncContext * s)

{

    static int initialized=0;

    switch(s->msmpeg4_version){

    case 1:

    case 2:

        s->y_dc_scale_table=

        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;

        break;

    case 3:

        if(s->workaround_bugs){

            s->y_dc_scale_table= old_ff_y_dc_scale_table;

            s->c_dc_scale_table= wmv1_c_dc_scale_table;

        } else{

            s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;

            s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;

        }

        break;

    case 4:

    case 5:

        s->y_dc_scale_table= wmv1_y_dc_scale_table;

        s->c_dc_scale_table= wmv1_c_dc_scale_table;

        break;

#if CONFIG_WMV3_DECODER || CONFIG_VC1_DECODER

    case 6:

        s->y_dc_scale_table= wmv3_dc_scale_table;

        s->c_dc_scale_table= wmv3_dc_scale_table;

        break;

#endif

    }

    if(s->msmpeg4_version>=4){

        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , wmv1_scantable[1]);

        ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, wmv1_scantable[2]);

        ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, wmv1_scantable[3]);

        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , wmv1_scantable[0]);

    }

    //Note the default tables are set in common_init in mpegvideo.c

    if(!initialized){

        initialized=1;

        init_h263_dc_for_msmpeg4();

    }

}


LF_FUNC (h,  luma,         sse2)

LF_IFUNC(h,  luma_intra,   sse2)

LF_FUNC (v,  luma,         sse2)

LF_IFUNC(v,  luma_intra,   sse2)

/***********************************/

/* weighted prediction */

#define H264_WEIGHT(W, H, OPT) \

void ff_h264_weight_ ## W ## x ## H ## _ ## OPT(uint8_t *dst, \

    int stride, int log2_denom, int weight, int offset);

#define H264_BIWEIGHT(W, H, OPT) \

void ff_h264_biweight_ ## W ## x ## H ## _ ## OPT(uint8_t *dst, \

    uint8_t *src, int stride, int log2_denom, int weightd, \

    int weights, int offset);

#define H264_BIWEIGHT_MMX(W,H) \

H264_WEIGHT  (W, H, mmx2) \

H264_BIWEIGHT(W, H, mmx2)

#define H264_BIWEIGHT_MMX_SSE(W,H) \

H264_BIWEIGHT_MMX(W, H) \

H264_WEIGHT      (W, H, sse2) \

H264_BIWEIGHT    (W, H, sse2) \

H264_BIWEIGHT    (W, H, ssse3)

H264_BIWEIGHT_MMX_SSE(16, 16)

H264_BIWEIGHT_MMX_SSE(16,  8)

H264_BIWEIGHT_MMX_SSE( 8, 16)

H264_BIWEIGHT_MMX_SSE( 8,  8)

H264_BIWEIGHT_MMX_SSE( 8,  4)

H264_BIWEIGHT_MMX    ( 4,  8)

H264_BIWEIGHT_MMX    ( 4,  4)

H264_BIWEIGHT_MMX    ( 4,  2)

void ff_h264dsp_init_x86(H264DSPContext *c)

{

    int mm_flags = av_get_cpu_flags();

    if (mm_flags & AV_CPU_FLAG_MMX) {

        c->h264_idct_dc_add=

        c->h264_idct_add= ff_h264_idct_add_mmx;

        c->h264_idct8_dc_add=

        c->h264_idct8_add= ff_h264_idct8_add_mmx;

        c->h264_idct_add16     = ff_h264_idct_add16_mmx;

        c->h264_idct8_add4     = ff_h264_idct8_add4_mmx;

        c->h264_idct_add8      = ff_h264_idct_add8_mmx;

        c->h264_idct_add16intra= ff_h264_idct_add16intra_mmx;

        if (mm_flags & AV_CPU_FLAG_MMX2) {

            c->h264_idct_dc_add= ff_h264_idct_dc_add_mmx2;

            c->h264_idct8_dc_add= ff_h264_idct8_dc_add_mmx2;

            c->h264_idct_add16     = ff_h264_idct_add16_mmx2;

            c->h264_idct8_add4     = ff_h264_idct8_add4_mmx2;

            c->h264_idct_add8      = ff_h264_idct_add8_mmx2;

            c->h264_idct_add16intra= ff_h264_idct_add16intra_mmx2;

            c->h264_loop_filter_strength= h264_loop_filter_strength_mmx2;

        }

        if(mm_flags & AV_CPU_FLAG_SSE2){

            c->h264_idct8_add = ff_h264_idct8_add_sse2;

            c->h264_idct8_add4= ff_h264_idct8_add4_sse2;

        }

#if HAVE_YASM

        if (mm_flags & AV_CPU_FLAG_MMX2){

            c->h264_v_loop_filter_chroma= ff_x264_deblock_v_chroma_mmxext;

            c->h264_h_loop_filter_chroma= ff_x264_deblock_h_chroma_mmxext;

            c->h264_v_loop_filter_chroma_intra= ff_x264_deblock_v_chroma_intra_mmxext;

            c->h264_h_loop_filter_chroma_intra= ff_x264_deblock_h_chroma_intra_mmxext;

#if ARCH_X86_32

            c->h264_v_loop_filter_luma= ff_x264_deblock_v_luma_mmxext;

            c->h264_h_loop_filter_luma= ff_x264_deblock_h_luma_mmxext;

            c->h264_v_loop_filter_luma_intra = ff_x264_deblock_v_luma_intra_mmxext;

            c->h264_h_loop_filter_luma_intra = ff_x264_deblock_h_luma_intra_mmxext;

#endif

            c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_mmx2;

            c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_mmx2;

            c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_mmx2;

            c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_mmx2;

            c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_mmx2;

            c->weight_h264_pixels_tab[5]= ff_h264_weight_4x8_mmx2;

            c->weight_h264_pixels_tab[6]= ff_h264_weight_4x4_mmx2;

            c->weight_h264_pixels_tab[7]= ff_h264_weight_4x2_mmx2;

            c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_mmx2;

            c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_mmx2;

            c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_mmx2;

            c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_mmx2;

            c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_mmx2;

            c->biweight_h264_pixels_tab[5]= ff_h264_biweight_4x8_mmx2;

            c->biweight_h264_pixels_tab[6]= ff_h264_biweight_4x4_mmx2;

            c->biweight_h264_pixels_tab[7]= ff_h264_biweight_4x2_mmx2;

            if (mm_flags&AV_CPU_FLAG_SSE2) {

                c->weight_h264_pixels_tab[0]= ff_h264_weight_16x16_sse2;

                c->weight_h264_pixels_tab[1]= ff_h264_weight_16x8_sse2;

                c->weight_h264_pixels_tab[2]= ff_h264_weight_8x16_sse2;

                c->weight_h264_pixels_tab[3]= ff_h264_weight_8x8_sse2;

                c->weight_h264_pixels_tab[4]= ff_h264_weight_8x4_sse2;

                c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_sse2;

                c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_sse2;

                c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_sse2;

                c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_sse2;

                c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_sse2;

#if ARCH_X86_64 || !defined(__ICC) || __ICC > 1110

                c->h264_v_loop_filter_luma = ff_x264_deblock_v_luma_sse2;

                c->h264_h_loop_filter_luma = ff_x264_deblock_h_luma_sse2;

                c->h264_v_loop_filter_luma_intra = ff_x264_deblock_v_luma_intra_sse2;

                c->h264_h_loop_filter_luma_intra = ff_x264_deblock_h_luma_intra_sse2;

#endif

                c->h264_idct_add16 = ff_h264_idct_add16_sse2;

                c->h264_idct_add8  = ff_h264_idct_add8_sse2;

                c->h264_idct_add16intra = ff_h264_idct_add16intra_sse2;

            }

            if (mm_flags&AV_CPU_FLAG_SSSE3) {

                c->biweight_h264_pixels_tab[0]= ff_h264_biweight_16x16_ssse3;

                c->biweight_h264_pixels_tab[1]= ff_h264_biweight_16x8_ssse3;

                c->biweight_h264_pixels_tab[2]= ff_h264_biweight_8x16_ssse3;

                c->biweight_h264_pixels_tab[3]= ff_h264_biweight_8x8_ssse3;

                c->biweight_h264_pixels_tab[4]= ff_h264_biweight_8x4_ssse3;

            }

        }

#endif

    }

}


static av_cold int libwebp_anim_encode_init(AVCodecContext *avctx)

{

    int ret = ff_libwebp_encode_init_common(avctx);

    if (!ret) {

        LibWebPAnimContext *s = avctx->priv_data;

        WebPAnimEncoderOptions enc_options;

        WebPAnimEncoderOptionsInit(&enc_options);

        // TODO(urvang): Expose some options on command-line perhaps.

        s->enc = WebPAnimEncoderNew(avctx->width, avctx->height, &enc_options);

        if (!s->enc)

            return AVERROR(EINVAL);

        s->prev_frame_pts = -1;

        s->done = 0;

    }

    return ret;

}


static int sls_flag_use_localtime_filename(AVFormatContext *oc, HLSContext *c, VariantStream *vs)

{

    if (c->flags & HLS_SECOND_LEVEL_SEGMENT_INDEX) {

        char * filename = av_strdup(oc->filename);  // %%d will be %d after strftime

        if (!filename)

            return AVERROR(ENOMEM);

        if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename),

#if FF_API_HLS_WRAP

            filename, 'd', c->wrap ? vs->sequence % c->wrap : vs->sequence) < 1) {

#else

            filename, 'd', vs->sequence) < 1) {

#endif

            av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "

                    "you can try to remove second_level_segment_index flag\n",

                   filename);

            av_free(filename);

            return AVERROR(EINVAL);

        }

        av_free(filename);

    }

    if (c->flags & (HLS_SECOND_LEVEL_SEGMENT_SIZE | HLS_SECOND_LEVEL_SEGMENT_DURATION)) {

        av_strlcpy(vs->current_segment_final_filename_fmt, oc->filename,

                   sizeof(vs->current_segment_final_filename_fmt));

        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_SIZE) {

            char * filename = av_strdup(oc->filename);  // %%s will be %s after strftime

            if (!filename)

                return AVERROR(ENOMEM);

            if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 's', 0) < 1) {

                av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "

                        "you can try to remove second_level_segment_size flag\n",

                       filename);

                av_free(filename);

                return AVERROR(EINVAL);

            }

            av_free(filename);

        }

        if (c->flags & HLS_SECOND_LEVEL_SEGMENT_DURATION) {

            char * filename = av_strdup(oc->filename);  // %%t will be %t after strftime

            if (!filename)

                return AVERROR(ENOMEM);

            if (replace_int_data_in_filename(oc->filename, sizeof(oc->filename), filename, 't', 0) < 1) {

                av_log(c, AV_LOG_ERROR, "Invalid second level segment filename template '%s', "

                        "you can try to remove second_level_segment_time flag\n",

                       filename);

                av_free(filename);

                return AVERROR(EINVAL);

            }

            av_free(filename);

        }

    }

    return 0;

}


static bool e1000_full_mac_needed(void *opaque)

{

    E1000State *s = opaque;

    return s->compat_flags & E1000_FLAG_MAC;

}


void qemu_bh_delete(QEMUBH *bh)

{

    qemu_free(bh);

}


static void net_socket_receive(void *opaque, const uint8_t *buf, size_t size)

{

    NetSocketState *s = opaque;

    uint32_t len;

    len = htonl(size);

    send_all(s->fd, (const uint8_t *)&len, sizeof(len));

    send_all(s->fd, buf, size);

}


static void *rcu_read_stress_test(void *arg)

{

    int i;

    int itercnt = 0;

    struct rcu_stress *p;

    int pc;

    long long n_reads_local = 0;

    volatile int garbage = 0;

    rcu_register_thread();

    *(struct rcu_reader_data **)arg = &rcu_reader;

    while (goflag == GOFLAG_INIT) {

        g_usleep(1000);

    }

    while (goflag == GOFLAG_RUN) {

        rcu_read_lock();

        p = atomic_rcu_read(&rcu_stress_current);

        if (p->mbtest == 0) {

            n_mberror++;

        }

        rcu_read_lock();

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

            garbage++;

        }

        rcu_read_unlock();

        pc = p->pipe_count;

        rcu_read_unlock();

        if ((pc > RCU_STRESS_PIPE_LEN) || (pc < 0)) {

            pc = RCU_STRESS_PIPE_LEN;

        }

        atomic_inc(&rcu_stress_count[pc]);

        n_reads_local++;

        if ((++itercnt % 0x1000) == 0) {

            synchronize_rcu();

        }

    }

    atomic_add(&n_reads, n_reads_local);

    rcu_unregister_thread();

    return NULL;

}


static void rtc_realizefn(DeviceState *dev, Error **errp)

{

    ISADevice *isadev = ISA_DEVICE(dev);

    RTCState *s = MC146818_RTC(dev);

    int base = 0x70;

    s->cmos_data[RTC_REG_A] = 0x26;

    s->cmos_data[RTC_REG_B] = 0x02;

    s->cmos_data[RTC_REG_C] = 0x00;

    s->cmos_data[RTC_REG_D] = 0x80;

    /* This is for historical reasons.  The default base year qdev property

     * was set to 2000 for most machine types before the century byte was

     * implemented.

     *

     * This if statement means that the century byte will be always 0

     * (at least until 2079...) for base_year = 1980, but will be set

     * correctly for base_year = 2000.

     */

    if (s->base_year == 2000) {

        s->base_year = 0;

    }

    rtc_set_date_from_host(isadev);

#ifdef TARGET_I386

    switch (s->lost_tick_policy) {

    case LOST_TICK_POLICY_SLEW:

        s->coalesced_timer =

            timer_new_ns(rtc_clock, rtc_coalesced_timer, s);

        break;

    case LOST_TICK_POLICY_DISCARD:

        break;

    default:

        error_setg(errp, "Invalid lost tick policy.");

        return;

    }

#endif

    s->periodic_timer = timer_new_ns(rtc_clock, rtc_periodic_timer, s);

    s->update_timer = timer_new_ns(rtc_clock, rtc_update_timer, s);

    check_update_timer(s);

    s->clock_reset_notifier.notify = rtc_notify_clock_reset;

    qemu_clock_register_reset_notifier(rtc_clock,

                                       &s->clock_reset_notifier);

    s->suspend_notifier.notify = rtc_notify_suspend;

    qemu_register_suspend_notifier(&s->suspend_notifier);

    memory_region_init_io(&s->io, OBJECT(s), &cmos_ops, s, "rtc", 2);

    isa_register_ioport(isadev, &s->io, base);

    qdev_set_legacy_instance_id(dev, base, 3);

    qemu_register_reset(rtc_reset, s);

    object_property_add(OBJECT(s), "date", "struct tm",

                        rtc_get_date, NULL, NULL, s, NULL);

    object_property_add_alias(qdev_get_machine(), "rtc-time",

                              OBJECT(s), "date", NULL);

}


static int decode_init(AVCodecContext *avctx)

{

    HYuvContext *s = avctx->priv_data;

    int width, height;

    s->avctx= avctx;

    s->flags= avctx->flags;

    dsputil_init(&s->dsp, avctx);

    memset(s->vlc, 0, 3*sizeof(VLC));

    width= s->width= avctx->width;

    height= s->height= avctx->height;

    avctx->coded_frame= &s->picture;

s->bgr32=1;

    assert(width && height);

//if(avctx->extradata)

//  printf("extradata:%X, extradata_size:%d\n", *(uint32_t*)avctx->extradata, avctx->extradata_size);

    if(avctx->extradata_size){

        if((avctx->bits_per_sample&7) && avctx->bits_per_sample != 12)

            s->version=1; // do such files exist at all?

        else

            s->version=2;

    }else

        s->version=0;

    if(s->version==2){

        int method;

        method= ((uint8_t*)avctx->extradata)[0];

        s->decorrelate= method&64 ? 1 : 0;

        s->predictor= method&63;

        s->bitstream_bpp= ((uint8_t*)avctx->extradata)[1];

        if(s->bitstream_bpp==0)

            s->bitstream_bpp= avctx->bits_per_sample&~7;

        s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0;

        if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0)

            return -1;

    }else{

        switch(avctx->bits_per_sample&7){

        case 1:

            s->predictor= LEFT;

            s->decorrelate= 0;

            break;

        case 2:

            s->predictor= LEFT;

            s->decorrelate= 1;

            break;

        case 3:

            s->predictor= PLANE;

            s->decorrelate= avctx->bits_per_sample >= 24;

            break;

        case 4:

            s->predictor= MEDIAN;

            s->decorrelate= 0;

            break;

        default:

            s->predictor= LEFT; //OLD

            s->decorrelate= 0;

            break;

        }

        s->bitstream_bpp= avctx->bits_per_sample & ~7;

        s->context= 0;

        if(read_old_huffman_tables(s) < 0)

            return -1;

    }

    if(((uint8_t*)avctx->extradata)[2] & 0x20)

	s->interlaced= ((uint8_t*)avctx->extradata)[2] & 0x10 ? 1 : 0;

    else

	s->interlaced= height > 288;

    switch(s->bitstream_bpp){

    case 12:

        avctx->pix_fmt = PIX_FMT_YUV420P;

        break;

    case 16:

        if(s->yuy2){

            avctx->pix_fmt = PIX_FMT_YUV422;

        }else{

            avctx->pix_fmt = PIX_FMT_YUV422P;

        }

        break;

    case 24:

    case 32:

        if(s->bgr32){

            avctx->pix_fmt = PIX_FMT_RGBA32;

        }else{

            avctx->pix_fmt = PIX_FMT_BGR24;

        }

        break;

    default:

        assert(0);

    }

//    av_log(NULL, AV_LOG_DEBUG, "pred:%d bpp:%d hbpp:%d il:%d\n", s->predictor, s->bitstream_bpp, avctx->bits_per_sample, s->interlaced);

    return 0;

}


static void palmte_init(ram_addr_t ram_size, int vga_ram_size,

                const char *boot_device,

                const char *kernel_filename, const char *kernel_cmdline,

                const char *initrd_filename, const char *cpu_model)

{

    struct omap_mpu_state_s *cpu;

    int flash_size = 0x00800000;

    int sdram_size = palmte_binfo.ram_size;

    int io;

    static uint32_t cs0val = 0xffffffff;

    static uint32_t cs1val = 0x0000e1a0;

    static uint32_t cs2val = 0x0000e1a0;

    static uint32_t cs3val = 0xe1a0e1a0;

    ram_addr_t phys_flash;

    int rom_size, rom_loaded = 0;

    DisplayState *ds = get_displaystate();

    if (ram_size < flash_size + sdram_size + OMAP15XX_SRAM_SIZE) {

        fprintf(stderr, "This architecture uses %i bytes of memory\n",

                        flash_size + sdram_size + OMAP15XX_SRAM_SIZE);

        exit(1);

    }

    cpu = omap310_mpu_init(sdram_size, cpu_model);

    /* External Flash (EMIFS) */

    cpu_register_physical_memory(OMAP_CS0_BASE, flash_size,

                    (phys_flash = qemu_ram_alloc(flash_size)) | IO_MEM_ROM);

    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs0val);

    cpu_register_physical_memory(OMAP_CS0_BASE + flash_size,

                    OMAP_CS0_SIZE - flash_size, io);

    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs1val);

    cpu_register_physical_memory(OMAP_CS1_BASE, OMAP_CS1_SIZE, io);

    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs2val);

    cpu_register_physical_memory(OMAP_CS2_BASE, OMAP_CS2_SIZE, io);

    io = cpu_register_io_memory(0, static_readfn, static_writefn, &cs3val);

    cpu_register_physical_memory(OMAP_CS3_BASE, OMAP_CS3_SIZE, io);

    palmte_microwire_setup(cpu);

    qemu_add_kbd_event_handler(palmte_button_event, cpu);

    palmte_gpio_setup(cpu);

    /* Setup initial (reset) machine state */

    if (nb_option_roms) {

        rom_size = get_image_size(option_rom[0]);

        if (rom_size > flash_size) {

            fprintf(stderr, "%s: ROM image too big (%x > %x)\n",

                            __FUNCTION__, rom_size, flash_size);

            rom_size = 0;

        }

        if (rom_size > 0) {

            rom_size = load_image_targphys(option_rom[0], OMAP_CS0_BASE,

                                           flash_size);

            rom_loaded = 1;

            cpu->env->regs[15] = 0x00000000;

        }

        if (rom_size < 0) {

            fprintf(stderr, "%s: error loading '%s'\n",

                            __FUNCTION__, option_rom[0]);

        }

    }

    if (!rom_loaded && !kernel_filename) {

        fprintf(stderr, "Kernel or ROM image must be specified\n");

        exit(1);

    }

    /* Load the kernel.  */

    if (kernel_filename) {

        /* Start at bootloader.  */

        cpu->env->regs[15] = palmte_binfo.loader_start;

        palmte_binfo.kernel_filename = kernel_filename;

        palmte_binfo.kernel_cmdline = kernel_cmdline;

        palmte_binfo.initrd_filename = initrd_filename;

        arm_load_kernel(cpu->env, &palmte_binfo);

    }

    /* FIXME: We shouldn't really be doing this here.  The LCD controller

       will set the size once configured, so this just sets an initial

       size until the guest activates the display.  */

    ds->surface = qemu_resize_displaysurface(ds, 320, 320);

    dpy_resize(ds);

}


static void menelaus_save(QEMUFile *f, void *opaque)

{

    MenelausState *s = (MenelausState *) opaque;

    qemu_put_be32(f, s->firstbyte);

    qemu_put_8s(f, &s->reg);

    qemu_put_8s(f, &s->vcore[0]);

    qemu_put_8s(f, &s->vcore[1]);

    qemu_put_8s(f, &s->vcore[2]);

    qemu_put_8s(f, &s->vcore[3]);

    qemu_put_8s(f, &s->vcore[4]);

    qemu_put_8s(f, &s->dcdc[0]);

    qemu_put_8s(f, &s->dcdc[1]);

    qemu_put_8s(f, &s->dcdc[2]);

    qemu_put_8s(f, &s->ldo[0]);

    qemu_put_8s(f, &s->ldo[1]);

    qemu_put_8s(f, &s->ldo[2]);

    qemu_put_8s(f, &s->ldo[3]);

    qemu_put_8s(f, &s->ldo[4]);

    qemu_put_8s(f, &s->ldo[5]);

    qemu_put_8s(f, &s->ldo[6]);

    qemu_put_8s(f, &s->ldo[7]);

    qemu_put_8s(f, &s->sleep[0]);

    qemu_put_8s(f, &s->sleep[1]);

    qemu_put_8s(f, &s->osc);

    qemu_put_8s(f, &s->detect);

    qemu_put_be16s(f, &s->mask);

    qemu_put_be16s(f, &s->status);

    qemu_put_8s(f, &s->dir);

    qemu_put_8s(f, &s->inputs);

    qemu_put_8s(f, &s->outputs);

    qemu_put_8s(f, &s->bbsms);

    qemu_put_8s(f, &s->pull[0]);

    qemu_put_8s(f, &s->pull[1]);

    qemu_put_8s(f, &s->pull[2]);

    qemu_put_8s(f, &s->pull[3]);

    qemu_put_8s(f, &s->mmc_ctrl[0]);

    qemu_put_8s(f, &s->mmc_ctrl[1]);

    qemu_put_8s(f, &s->mmc_ctrl[2]);

    qemu_put_8s(f, &s->mmc_debounce);

    qemu_put_8s(f, &s->rtc.ctrl);

    qemu_put_be16s(f, &s->rtc.comp);

    /* Should be <= 1000 */

    qemu_put_be16(f, s->rtc.next - qemu_get_clock(rt_clock));

    tm_put(f, &s->rtc.new);

    tm_put(f, &s->rtc.alm);

    qemu_put_byte(f, s->pwrbtn_state);

    i2c_slave_save(f, &s->i2c);

}


static void pc_machine_class_init(ObjectClass *oc, void *data)

{

    MachineClass *mc = MACHINE_CLASS(oc);

    PCMachineClass *pcmc = PC_MACHINE_CLASS(oc);

    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);

    NMIClass *nc = NMI_CLASS(oc);

    pcmc->get_hotplug_handler = mc->get_hotplug_handler;

    pcmc->pci_enabled = true;

    pcmc->has_acpi_build = true;

    pcmc->rsdp_in_ram = true;

    pcmc->smbios_defaults = true;

    pcmc->smbios_uuid_encoded = true;

    pcmc->gigabyte_align = true;

    pcmc->has_reserved_memory = true;

    pcmc->kvmclock_enabled = true;

    pcmc->enforce_aligned_dimm = true;

    /* BIOS ACPI tables: 128K. Other BIOS datastructures: less than 4K reported

     * to be used at the moment, 32K should be enough for a while.  */

    pcmc->acpi_data_size = 0x20000 + 0x8000;

    pcmc->save_tsc_khz = true;

    mc->get_hotplug_handler = pc_get_hotpug_handler;

    mc->cpu_index_to_socket_id = pc_cpu_index_to_socket_id;

    mc->possible_cpu_arch_ids = pc_possible_cpu_arch_ids;

    mc->query_hotpluggable_cpus = pc_query_hotpluggable_cpus;

    mc->default_boot_order = "cad";

    mc->hot_add_cpu = pc_hot_add_cpu;

    mc->max_cpus = 255;

    mc->reset = pc_machine_reset;

    hc->pre_plug = pc_machine_device_pre_plug_cb;

    hc->plug = pc_machine_device_plug_cb;

    hc->post_plug = pc_machine_device_post_plug_cb;

    hc->unplug_request = pc_machine_device_unplug_request_cb;

    hc->unplug = pc_machine_device_unplug_cb;

    nc->nmi_monitor_handler = x86_nmi;

    object_class_property_add(oc, PC_MACHINE_MEMHP_REGION_SIZE, "int",

        pc_machine_get_hotplug_memory_region_size, NULL,

        NULL, NULL, &error_abort);

    object_class_property_add(oc, PC_MACHINE_MAX_RAM_BELOW_4G, "size",

        pc_machine_get_max_ram_below_4g, pc_machine_set_max_ram_below_4g,

        NULL, NULL, &error_abort);

    object_class_property_set_description(oc, PC_MACHINE_MAX_RAM_BELOW_4G,

        "Maximum ram below the 4G boundary (32bit boundary)", &error_abort);

    object_class_property_add(oc, PC_MACHINE_SMM, "OnOffAuto",

        pc_machine_get_smm, pc_machine_set_smm,

        NULL, NULL, &error_abort);

    object_class_property_set_description(oc, PC_MACHINE_SMM,

        "Enable SMM (pc & q35)", &error_abort);

    object_class_property_add(oc, PC_MACHINE_VMPORT, "OnOffAuto",

        pc_machine_get_vmport, pc_machine_set_vmport,

        NULL, NULL, &error_abort);

    object_class_property_set_description(oc, PC_MACHINE_VMPORT,

        "Enable vmport (pc & q35)", &error_abort);

    object_class_property_add_bool(oc, PC_MACHINE_NVDIMM,

        pc_machine_get_nvdimm, pc_machine_set_nvdimm, &error_abort);

}


static uint64_t mips_qemu_read (void *opaque, target_phys_addr_t addr,

                                unsigned size)

{

    return 0;

}


int vfio_mmap_region(Object *obj, VFIORegion *region,

                     MemoryRegion *mem, MemoryRegion *submem,

                     void **map, size_t size, off_t offset,

                     const char *name)

{

    int ret = 0;

    VFIODevice *vbasedev = region->vbasedev;

    if (vbasedev->allow_mmap && size && region->flags &

        VFIO_REGION_INFO_FLAG_MMAP) {

        int prot = 0;

        if (region->flags & VFIO_REGION_INFO_FLAG_READ) {

            prot |= PROT_READ;

        }

        if (region->flags & VFIO_REGION_INFO_FLAG_WRITE) {

            prot |= PROT_WRITE;

        }

        *map = mmap(NULL, size, prot, MAP_SHARED,

                    vbasedev->fd,

                    region->fd_offset + offset);

        if (*map == MAP_FAILED) {

            *map = NULL;

            ret = -errno;

            goto empty_region;

        }

        memory_region_init_ram_ptr(submem, obj, name, size, *map);

        memory_region_set_skip_dump(submem);

    } else {

empty_region:

        /* Create a zero sized sub-region to make cleanup easy. */

        memory_region_init(submem, obj, name, 0);

    }

    memory_region_add_subregion(mem, offset, submem);

    return ret;

}


read_insn_microblaze (bfd_vma memaddr,

		      struct disassemble_info *info,

		      struct op_code_struct **opr)

{

  unsigned char       ibytes[4];

  int                 status;

  struct op_code_struct * op;

  unsigned long inst;

  status = info->read_memory_func (memaddr, ibytes, 4, info);

  if (status != 0)

    {

      info->memory_error_func (status, memaddr, info);

      return 0;

    }

  if (info->endian == BFD_ENDIAN_BIG)

    inst = (ibytes[0] << 24) | (ibytes[1] << 16) | (ibytes[2] << 8) | ibytes[3];

  else if (info->endian == BFD_ENDIAN_LITTLE)

    inst = (ibytes[3] << 24) | (ibytes[2] << 16) | (ibytes[1] << 8) | ibytes[0];

  else

    abort ();

  /* Just a linear search of the table.  */

  for (op = opcodes; op->name != 0; op ++)

    if (op->bit_sequence == (inst & op->opcode_mask))

      break;

  *opr = op;

  return inst;

}


bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)

{

    int i;

    size_t alignment = bdrv_opt_mem_align(bs);

    for (i = 0; i < qiov->niov; i++) {

        if ((uintptr_t) qiov->iov[i].iov_base % alignment) {

            return false;

        }

        if (qiov->iov[i].iov_len % alignment) {

            return false;

        }

    }

    return true;

}


iscsi_process_write(void *arg)

{

    IscsiLun *iscsilun = arg;

    struct iscsi_context *iscsi = iscsilun->iscsi;

    aio_context_acquire(iscsilun->aio_context);

    iscsi_service(iscsi, POLLOUT);

    iscsi_set_events(iscsilun);

    aio_context_release(iscsilun->aio_context);

}


static void vc1_decode_b_mb(VC1Context *v)

{

    MpegEncContext *s = &v->s;

    GetBitContext *gb = &s->gb;

    int i, j;

    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;

    int cbp = 0; /* cbp decoding stuff */

    int mqdiff, mquant; /* MB quantization */

    int ttmb = v->ttfrm; /* MB Transform type */

    int mb_has_coeffs = 0; /* last_flag */

    int index, index1; /* LUT indexes */

    int val, sign; /* temp values */

    int first_block = 1;

    int dst_idx, off;

    int skipped, direct;

    int dmv_x[2], dmv_y[2];

    int bmvtype = BMV_TYPE_BACKWARD;

    mquant = v->pq; /* Loosy initialization */

    s->mb_intra = 0;

    if (v->dmb_is_raw)

        direct = get_bits1(gb);

    else

        direct = v->direct_mb_plane[mb_pos];

    if (v->skip_is_raw)

        skipped = get_bits1(gb);

    else

        skipped = v->s.mbskip_table[mb_pos];

    dmv_x[0] = dmv_x[1] = dmv_y[0] = dmv_y[1] = 0;

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

        v->mb_type[0][s->block_index[i]] = 0;

        s->dc_val[0][s->block_index[i]] = 0;

    }

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

    if (!direct) {

        if (!skipped) {

            GET_MVDATA(dmv_x[0], dmv_y[0]);

            dmv_x[1] = dmv_x[0];

            dmv_y[1] = dmv_y[0];

        }

        if(skipped || !s->mb_intra) {

            bmvtype = decode012(gb);

            switch(bmvtype) {

            case 0:

                bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_BACKWARD : BMV_TYPE_FORWARD;

                break;

            case 1:

                bmvtype = (v->bfraction >= (B_FRACTION_DEN/2)) ? BMV_TYPE_FORWARD : BMV_TYPE_BACKWARD;

                break;

            case 2:

                bmvtype = BMV_TYPE_INTERPOLATED;

                dmv_x[0] = dmv_y[0] = 0;

            }

        }

    }

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

        v->mb_type[0][s->block_index[i]] = s->mb_intra;

    if (skipped) {

        if(direct) bmvtype = BMV_TYPE_INTERPOLATED;

        vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);

        vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);

        return;

    }

    if (direct) {

        cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);

        GET_MQUANT();

        s->mb_intra = 0;

        s->current_picture.qscale_table[mb_pos] = mquant;

        if(!v->ttmbf)

            ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);

        dmv_x[0] = dmv_y[0] = dmv_x[1] = dmv_y[1] = 0;

        vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);

        vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);

    } else {

        if(!mb_has_coeffs && !s->mb_intra) {

            /* no coded blocks - effectively skipped */

            vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);

            vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);

            return;

        }

        if(s->mb_intra && !mb_has_coeffs) {

            GET_MQUANT();

            s->current_picture.qscale_table[mb_pos] = mquant;

            s->ac_pred = get_bits1(gb);

            cbp = 0;

            vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);

        } else {

            if(bmvtype == BMV_TYPE_INTERPOLATED) {

                GET_MVDATA(dmv_x[0], dmv_y[0]);

                if(!mb_has_coeffs) {

                    /* interpolated skipped block */

                    vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);

                    vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);

                    return;

                }

            }

            vc1_pred_b_mv(v, dmv_x, dmv_y, direct, bmvtype);

            if(!s->mb_intra) {

                vc1_b_mc(v, dmv_x, dmv_y, direct, bmvtype);

            }

            if(s->mb_intra)

                s->ac_pred = get_bits1(gb);

            cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);

            GET_MQUANT();

            s->current_picture.qscale_table[mb_pos] = mquant;

            if(!v->ttmbf && !s->mb_intra && mb_has_coeffs)

                ttmb = get_vlc2(gb, ff_vc1_ttmb_vlc[v->tt_index].table, VC1_TTMB_VLC_BITS, 2);

        }

    }

    dst_idx = 0;

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

    {

        s->dc_val[0][s->block_index[i]] = 0;

        dst_idx += i >> 2;

        val = ((cbp >> (5 - i)) & 1);

        off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);

        v->mb_type[0][s->block_index[i]] = s->mb_intra;

        if(s->mb_intra) {

            /* check if prediction blocks A and C are available */

            v->a_avail = v->c_avail = 0;

            if(i == 2 || i == 3 || !s->first_slice_line)

                v->a_avail = v->mb_type[0][s->block_index[i] - s->block_wrap[i]];

            if(i == 1 || i == 3 || s->mb_x)

                v->c_avail = v->mb_type[0][s->block_index[i] - 1];

            vc1_decode_intra_block(v, s->block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);

            if((i>3) && (s->flags & CODEC_FLAG_GRAY)) continue;

            v->vc1dsp.vc1_inv_trans_8x8(s->block[i]);

            if(v->rangeredfrm) for(j = 0; j < 64; j++) s->block[i][j] <<= 1;

            s->dsp.put_signed_pixels_clamped(s->block[i], s->dest[dst_idx] + off, i & 4 ? s->uvlinesize : s->linesize);

        } else if(val) {

            vc1_decode_p_block(v, s->block[i], i, mquant, ttmb, first_block, s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize, (i&4) && (s->flags & CODEC_FLAG_GRAY), 0, 0, 0);

            if(!v->ttmbf && ttmb < 8) ttmb = -1;

            first_block = 0;

        }

    }

}


static void openpic_update_irq(OpenPICState *opp, int n_IRQ)

{

    IRQSource *src;

    bool active, was_active;

    int i;

    src = &opp->src[n_IRQ];

    active = src->pending;

    if ((src->ivpr & IVPR_MASK_MASK) && !src->nomask) {

        /* Interrupt source is disabled */

        DPRINTF("%s: IRQ %d is disabled\n", __func__, n_IRQ);

        active = false;

    }

    was_active = !!(src->ivpr & IVPR_ACTIVITY_MASK);

    /*

     * We don't have a similar check for already-active because

     * ctpr may have changed and we need to withdraw the interrupt.

     */

    if (!active && !was_active) {

        DPRINTF("%s: IRQ %d is already inactive\n", __func__, n_IRQ);

        return;

    }

    if (active) {

        src->ivpr |= IVPR_ACTIVITY_MASK;

    } else {

        src->ivpr &= ~IVPR_ACTIVITY_MASK;

    }

    if (src->idr == 0) {

        /* No target */

        DPRINTF("%s: IRQ %d has no target\n", __func__, n_IRQ);

        return;

    }

    if (src->idr == (1 << src->last_cpu)) {

        /* Only one CPU is allowed to receive this IRQ */

        IRQ_local_pipe(opp, src->last_cpu, n_IRQ, active, was_active);

    } else if (!(src->ivpr & IVPR_MODE_MASK)) {

        /* Directed delivery mode */

        for (i = 0; i < opp->nb_cpus; i++) {

            if (src->destmask & (1 << i)) {

                IRQ_local_pipe(opp, i, n_IRQ, active, was_active);

            }

        }

    } else {

        /* Distributed delivery mode */

        for (i = src->last_cpu + 1; i != src->last_cpu; i++) {

            if (i == opp->nb_cpus) {

                i = 0;

            }

            if (src->destmask & (1 << i)) {

                IRQ_local_pipe(opp, i, n_IRQ, active, was_active);

                src->last_cpu = i;

                break;

            }

        }

    }

}


void dpy_gfx_update_dirty(QemuConsole *con,

                          MemoryRegion *address_space,

                          hwaddr base,

                          bool invalidate)

{

    DisplaySurface *ds = qemu_console_surface(con);

    int width = surface_stride(ds);

    int height = surface_height(ds);

    hwaddr size = width * height;

    MemoryRegionSection mem_section;

    MemoryRegion *mem;

    ram_addr_t addr;

    int first, last, i;

    bool dirty;

    mem_section = memory_region_find(address_space, base, size);

    mem = mem_section.mr;

    if (int128_get64(mem_section.size) != size ||

        !memory_region_is_ram(mem_section.mr)) {

        goto out;

    }

    assert(mem);

    memory_region_sync_dirty_bitmap(mem);

    addr = mem_section.offset_within_region;

    first = -1;

    last = -1;

    for (i = 0; i < height; i++, addr += width) {

        dirty = invalidate ||

            memory_region_get_dirty(mem, addr, width, DIRTY_MEMORY_VGA);

        if (dirty) {

            if (first == -1) {

                first = i;

            }

            last = i;

        }

        if (first != -1 && !dirty) {

            assert(last != -1 && last >= first);

            dpy_gfx_update(con, 0, first, surface_width(ds),

                           last - first + 1);

            first = -1;

        }

    }

    if (first != -1) {

        assert(last != -1 && last >= first);

        dpy_gfx_update(con, 0, first, surface_width(ds),

                       last - first + 1);

    }

    memory_region_reset_dirty(mem, mem_section.offset_within_region, size,

                              DIRTY_MEMORY_VGA);

out:

    memory_region_unref(mem);

}


static void pci_dev_get_w64(PCIBus *b, PCIDevice *dev, void *opaque)

{

    Range *range = opaque;

    PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev);

    uint16_t cmd = pci_get_word(dev->config + PCI_COMMAND);

    int i;

    if (!(cmd & PCI_COMMAND_MEMORY)) {

        return;

    }

    if (pc->is_bridge) {

        pcibus_t base = pci_bridge_get_base(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);

        pcibus_t limit = pci_bridge_get_limit(dev, PCI_BASE_ADDRESS_MEM_PREFETCH);

        base = MAX(base, 0x1ULL << 32);

        if (limit >= base) {

            Range pref_range;

            pref_range.begin = base;

            pref_range.end = limit + 1;

            range_extend(range, &pref_range);

        }

    }

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

        PCIIORegion *r = &dev->io_regions[i];

        Range region_range;

        if (!r->size ||

            (r->type & PCI_BASE_ADDRESS_SPACE_IO) ||

            !(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64)) {

            continue;

        }

        region_range.begin = pci_bar_address(dev, i, r->type, r->size);

        region_range.end = region_range.begin + r->size;

        if (region_range.begin == PCI_BAR_UNMAPPED) {

            continue;

        }

        region_range.begin = MAX(region_range.begin, 0x1ULL << 32);

        if (region_range.end - 1 >= region_range.begin) {

            range_extend(range, &region_range);

        }

    }

}


cryptodev_builtin_get_aes_algo(uint32_t key_len, Error **errp)

{

    int algo;

    if (key_len == 128 / 8) {

        algo = QCRYPTO_CIPHER_ALG_AES_128;

    } else if (key_len == 192 / 8) {

        algo = QCRYPTO_CIPHER_ALG_AES_192;

    } else if (key_len == 256 / 8) {

        algo = QCRYPTO_CIPHER_ALG_AES_256;

    } else {

        error_setg(errp, "Unsupported key length :%u", key_len);

        return -1;

    }

    return algo;

}


static int sd_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)

{

    BDRVSheepdogState *s = bs->opaque;

    SheepdogReq req;

    int fd, nr = 1024, ret, max = BITS_TO_LONGS(SD_NR_VDIS) * sizeof(long);

    QEMUSnapshotInfo *sn_tab = NULL;

    unsigned wlen, rlen;

    int found = 0;

    static SheepdogInode inode;

    unsigned long *vdi_inuse;

    unsigned int start_nr;

    uint64_t hval;

    uint32_t vid;

    vdi_inuse = g_malloc(max);

    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        ret = fd;

        goto out;

    }

    rlen = max;

    wlen = 0;

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

    req.opcode = SD_OP_READ_VDIS;

    req.data_length = max;

    ret = do_req(fd, (SheepdogReq *)&req, vdi_inuse, &wlen, &rlen);

    closesocket(fd);

    if (ret) {

        goto out;

    }

    sn_tab = g_malloc0(nr * sizeof(*sn_tab));

    /* calculate a vdi id with hash function */

    hval = fnv_64a_buf(s->name, strlen(s->name), FNV1A_64_INIT);

    start_nr = hval & (SD_NR_VDIS - 1);

    fd = connect_to_sdog(s->addr, s->port);

    if (fd < 0) {

        error_report("failed to connect");

        ret = fd;

        goto out;

    }

    for (vid = start_nr; found < nr; vid = (vid + 1) % SD_NR_VDIS) {

        if (!test_bit(vid, vdi_inuse)) {

            break;

        }

        /* we don't need to read entire object */

        ret = read_object(fd, (char *)&inode, vid_to_vdi_oid(vid),

                          0, SD_INODE_SIZE - sizeof(inode.data_vdi_id), 0,

                          s->cache_enabled);

        if (ret) {

            continue;

        }

        if (!strcmp(inode.name, s->name) && is_snapshot(&inode)) {

            sn_tab[found].date_sec = inode.snap_ctime >> 32;

            sn_tab[found].date_nsec = inode.snap_ctime & 0xffffffff;

            sn_tab[found].vm_state_size = inode.vm_state_size;

            sn_tab[found].vm_clock_nsec = inode.vm_clock_nsec;

            snprintf(sn_tab[found].id_str, sizeof(sn_tab[found].id_str), "%u",

                     inode.snap_id);

            pstrcpy(sn_tab[found].name,

                    MIN(sizeof(sn_tab[found].name), sizeof(inode.tag)),

                    inode.tag);

            found++;

        }

    }

    closesocket(fd);

out:

    *psn_tab = sn_tab;

    g_free(vdi_inuse);

    if (ret < 0) {

        return ret;

    }

    return found;

}


static void versatile_init(MachineState *machine, int board_id)

{

    ARMCPU *cpu;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    qemu_irq pic[32];

    qemu_irq sic[32];

    DeviceState *dev, *sysctl;

    SysBusDevice *busdev;

    DeviceState *pl041;

    PCIBus *pci_bus;

    NICInfo *nd;

    I2CBus *i2c;

    int n;

    int done_smc = 0;

    DriveInfo *dinfo;

    if (!machine->cpu_model) {

        machine->cpu_model = "arm926";

    }

    cpu = cpu_arm_init(machine->cpu_model);

    if (!cpu) {

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

        exit(1);

    }

    memory_region_init_ram(ram, NULL, "versatile.ram", machine->ram_size,

                           &error_abort);

    vmstate_register_ram_global(ram);

    /* ??? RAM should repeat to fill physical memory space.  */

    /* SDRAM at address zero.  */

    memory_region_add_subregion(sysmem, 0, ram);

    sysctl = qdev_create(NULL, "realview_sysctl");

    qdev_prop_set_uint32(sysctl, "sys_id", 0x41007004);

    qdev_prop_set_uint32(sysctl, "proc_id", 0x02000000);

    qdev_init_nofail(sysctl);

    sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);

    dev = sysbus_create_varargs("pl190", 0x10140000,

                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ),

                                qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ),

                                NULL);

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

        pic[n] = qdev_get_gpio_in(dev, n);

    }

    dev = sysbus_create_simple(TYPE_VERSATILE_PB_SIC, 0x10003000, NULL);

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

        sysbus_connect_irq(SYS_BUS_DEVICE(dev), n, pic[n]);

        sic[n] = qdev_get_gpio_in(dev, n);

    }

    sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]);

    sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]);

    dev = qdev_create(NULL, "versatile_pci");

    busdev = SYS_BUS_DEVICE(dev);

    qdev_init_nofail(dev);

    sysbus_mmio_map(busdev, 0, 0x10001000); /* PCI controller regs */

    sysbus_mmio_map(busdev, 1, 0x41000000); /* PCI self-config */

    sysbus_mmio_map(busdev, 2, 0x42000000); /* PCI config */

    sysbus_mmio_map(busdev, 3, 0x43000000); /* PCI I/O */

    sysbus_mmio_map(busdev, 4, 0x44000000); /* PCI memory window 1 */

    sysbus_mmio_map(busdev, 5, 0x50000000); /* PCI memory window 2 */

    sysbus_mmio_map(busdev, 6, 0x60000000); /* PCI memory window 3 */

    sysbus_connect_irq(busdev, 0, sic[27]);

    sysbus_connect_irq(busdev, 1, sic[28]);

    sysbus_connect_irq(busdev, 2, sic[29]);

    sysbus_connect_irq(busdev, 3, sic[30]);

    pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");

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

        nd = &nd_table[n];

        if (!done_smc && (!nd->model || strcmp(nd->model, "smc91c111") == 0)) {

            smc91c111_init(nd, 0x10010000, sic[25]);

            done_smc = 1;

        } else {

            pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);

        }

    }

    if (usb_enabled(false)) {

        pci_create_simple(pci_bus, -1, "pci-ohci");

    }

    n = drive_get_max_bus(IF_SCSI);

    while (n >= 0) {

        pci_create_simple(pci_bus, -1, "lsi53c895a");

        n--;

    }

    sysbus_create_simple("pl011", 0x101f1000, pic[12]);

    sysbus_create_simple("pl011", 0x101f2000, pic[13]);

    sysbus_create_simple("pl011", 0x101f3000, pic[14]);

    sysbus_create_simple("pl011", 0x10009000, sic[6]);

    sysbus_create_simple("pl080", 0x10130000, pic[17]);

    sysbus_create_simple("sp804", 0x101e2000, pic[4]);

    sysbus_create_simple("sp804", 0x101e3000, pic[5]);

    sysbus_create_simple("pl061", 0x101e4000, pic[6]);

    sysbus_create_simple("pl061", 0x101e5000, pic[7]);

    sysbus_create_simple("pl061", 0x101e6000, pic[8]);

    sysbus_create_simple("pl061", 0x101e7000, pic[9]);

    /* The versatile/PB actually has a modified Color LCD controller

       that includes hardware cursor support from the PL111.  */

    dev = sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]);

    /* Wire up the mux control signals from the SYS_CLCD register */

    qdev_connect_gpio_out(sysctl, 0, qdev_get_gpio_in(dev, 0));

    sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL);

    sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL);

    /* Add PL031 Real Time Clock. */

    sysbus_create_simple("pl031", 0x101e8000, pic[10]);

    dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);

    i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");

    i2c_create_slave(i2c, "ds1338", 0x68);

    /* Add PL041 AACI Interface to the LM4549 codec */

    pl041 = qdev_create(NULL, "pl041");

    qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);

    qdev_init_nofail(pl041);

    sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);

    sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, sic[24]);

    /* Memory map for Versatile/PB:  */

    /* 0x10000000 System registers.  */

    /* 0x10001000 PCI controller config registers.  */

    /* 0x10002000 Serial bus interface.  */

    /*  0x10003000 Secondary interrupt controller.  */

    /* 0x10004000 AACI (audio).  */

    /*  0x10005000 MMCI0.  */

    /*  0x10006000 KMI0 (keyboard).  */

    /*  0x10007000 KMI1 (mouse).  */

    /* 0x10008000 Character LCD Interface.  */

    /*  0x10009000 UART3.  */

    /* 0x1000a000 Smart card 1.  */

    /*  0x1000b000 MMCI1.  */

    /*  0x10010000 Ethernet.  */

    /* 0x10020000 USB.  */

    /* 0x10100000 SSMC.  */

    /* 0x10110000 MPMC.  */

    /*  0x10120000 CLCD Controller.  */

    /*  0x10130000 DMA Controller.  */

    /*  0x10140000 Vectored interrupt controller.  */

    /* 0x101d0000 AHB Monitor Interface.  */

    /* 0x101e0000 System Controller.  */

    /* 0x101e1000 Watchdog Interface.  */

    /* 0x101e2000 Timer 0/1.  */

    /* 0x101e3000 Timer 2/3.  */

    /* 0x101e4000 GPIO port 0.  */

    /* 0x101e5000 GPIO port 1.  */

    /* 0x101e6000 GPIO port 2.  */

    /* 0x101e7000 GPIO port 3.  */

    /* 0x101e8000 RTC.  */

    /* 0x101f0000 Smart card 0.  */

    /*  0x101f1000 UART0.  */

    /*  0x101f2000 UART1.  */

    /*  0x101f3000 UART2.  */

    /* 0x101f4000 SSPI.  */

    /* 0x34000000 NOR Flash */

    dinfo = drive_get(IF_PFLASH, 0, 0);

    if (!pflash_cfi01_register(VERSATILE_FLASH_ADDR, NULL, "versatile.flash",

                          VERSATILE_FLASH_SIZE,

                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,

                          VERSATILE_FLASH_SECT_SIZE,

                          VERSATILE_FLASH_SIZE / VERSATILE_FLASH_SECT_SIZE,

                          4, 0x0089, 0x0018, 0x0000, 0x0, 0)) {

        fprintf(stderr, "qemu: Error registering flash memory.\n");

    }

    versatile_binfo.ram_size = machine->ram_size;

    versatile_binfo.kernel_filename = machine->kernel_filename;

    versatile_binfo.kernel_cmdline = machine->kernel_cmdline;

    versatile_binfo.initrd_filename = machine->initrd_filename;

    versatile_binfo.board_id = board_id;

    arm_load_kernel(cpu, &versatile_binfo);

}


size_t qemu_file_set_rate_limit(QEMUFile *f, size_t new_rate)

{

    /* any failed or completed migration keeps its state to allow probing of

     * migration data, but has no associated file anymore */

    if (f && f->set_rate_limit)

        return f->set_rate_limit(f->opaque, new_rate);

    return 0;

}


static uint64_t apb_config_readl (void *opaque,

                                  target_phys_addr_t addr, unsigned size)

{

    APBState *s = opaque;

    uint32_t val;

    switch (addr & 0xffff) {

    case 0x30 ... 0x4f: /* DMA error registers */

        val = 0;

        /* XXX: not implemented yet */

        break;

    case 0x200 ... 0x20b: /* IOMMU */

        val = s->iommu[(addr & 0xf) >> 2];

        break;

    case 0x20c ... 0x3ff: /* IOMMU flush */

        val = 0;

        break;

    case 0xc00 ... 0xc3f: /* PCI interrupt control */

        if (addr & 4) {

            val = s->pci_irq_map[(addr & 0x3f) >> 3];

        } else {

            val = 0;

        }

        break;

    case 0x1000 ... 0x1080: /* OBIO interrupt control */

        if (addr & 4) {

            val = s->obio_irq_map[(addr & 0xff) >> 3];

        } else {

            val = 0;

        }

        break;

    case 0x2000 ... 0x202f: /* PCI control */

        val = s->pci_control[(addr & 0x3f) >> 2];

        break;

    case 0xf020 ... 0xf027: /* Reset control */

        if (addr & 4) {

            val = s->reset_control;

        } else {

            val = 0;

        }

        break;

    case 0x5000 ... 0x51cf: /* PIO/DMA diagnostics */

    case 0xa400 ... 0xa67f: /* IOMMU diagnostics */

    case 0xa800 ... 0xa80f: /* Interrupt diagnostics */

    case 0xf000 ... 0xf01f: /* FFB config, memory control */

        /* we don't care */

    default:

        val = 0;

        break;

    }

    APB_DPRINTF("%s: addr " TARGET_FMT_lx " -> %x\n", __func__, addr, val);

    return val;

}


static int kvm_put_sregs(CPUState *env)

{

    struct kvm_sregs sregs;

    memset(sregs.interrupt_bitmap, 0, sizeof(sregs.interrupt_bitmap));

    if (env->interrupt_injected >= 0) {

        sregs.interrupt_bitmap[env->interrupt_injected / 64] |=

                (uint64_t)1 << (env->interrupt_injected % 64);

    }

    if ((env->eflags & VM_MASK)) {

        set_v8086_seg(&sregs.cs, &env->segs[R_CS]);

        set_v8086_seg(&sregs.ds, &env->segs[R_DS]);

        set_v8086_seg(&sregs.es, &env->segs[R_ES]);

        set_v8086_seg(&sregs.fs, &env->segs[R_FS]);

        set_v8086_seg(&sregs.gs, &env->segs[R_GS]);

        set_v8086_seg(&sregs.ss, &env->segs[R_SS]);

    } else {

        set_seg(&sregs.cs, &env->segs[R_CS]);

        set_seg(&sregs.ds, &env->segs[R_DS]);

        set_seg(&sregs.es, &env->segs[R_ES]);

        set_seg(&sregs.fs, &env->segs[R_FS]);

        set_seg(&sregs.gs, &env->segs[R_GS]);

        set_seg(&sregs.ss, &env->segs[R_SS]);

    }

    set_seg(&sregs.tr, &env->tr);

    set_seg(&sregs.ldt, &env->ldt);

    sregs.idt.limit = env->idt.limit;

    sregs.idt.base = env->idt.base;

    sregs.gdt.limit = env->gdt.limit;

    sregs.gdt.base = env->gdt.base;

    sregs.cr0 = env->cr[0];

    sregs.cr2 = env->cr[2];

    sregs.cr3 = env->cr[3];

    sregs.cr4 = env->cr[4];

    sregs.cr8 = cpu_get_apic_tpr(env->apic_state);

    sregs.apic_base = cpu_get_apic_base(env->apic_state);

    sregs.efer = env->efer;

    return kvm_vcpu_ioctl(env, KVM_SET_SREGS, &sregs);

}


write_f(int argc, char **argv)

{

	struct timeval t1, t2;

	int Cflag = 0, pflag = 0, qflag = 0;

	int c, cnt;

	char *buf;

	int64_t offset;

	int count;

        /* Some compilers get confused and warn if this is not initialized.  */

        int total = 0;

	int pattern = 0xcd;

	while ((c = getopt(argc, argv, "CpP:q")) != EOF) {

		switch (c) {

		case 'C':

			Cflag = 1;

			break;

		case 'p':

			pflag = 1;

			break;

		case 'P':

			pattern = atoi(optarg);

			break;

		case 'q':

			qflag = 1;

			break;

		default:

			return command_usage(&write_cmd);

		}

	}

	if (optind != argc - 2)

		return command_usage(&write_cmd);

	offset = cvtnum(argv[optind]);

	if (offset < 0) {

		printf("non-numeric length argument -- %s\n", argv[optind]);

		return 0;

	}

	optind++;

	count = cvtnum(argv[optind]);

	if (count < 0) {

		printf("non-numeric length argument -- %s\n", argv[optind]);

		return 0;

	}

	if (!pflag) {

		if (offset & 0x1ff) {

			printf("offset %lld is not sector aligned\n",

				(long long)offset);

			return 0;

		}

		if (count & 0x1ff) {

			printf("count %d is not sector aligned\n",

				count);

			return 0;

		}

	}

	buf = qemu_io_alloc(count, pattern);

	gettimeofday(&t1, NULL);

	if (pflag)

		cnt = do_pwrite(buf, offset, count, &total);

	else

		cnt = do_write(buf, offset, count, &total);

	gettimeofday(&t2, NULL);

	if (cnt < 0) {

		printf("write failed: %s\n", strerror(-cnt));

		return 0;

	}

	if (qflag)

		return 0;

	/* Finally, report back -- -C gives a parsable format */

	t2 = tsub(t2, t1);

	print_report("wrote", &t2, offset, count, total, cnt, Cflag);

	qemu_io_free(buf);

	return 0;

}


static int cpu_post_load(void *opaque, int version_id)

{

    PowerPCCPU *cpu = opaque;

    CPUPPCState *env = &cpu->env;

    int i;

    target_ulong msr;

    /*

     * If we're operating in compat mode, we should be ok as long as

     * the destination supports the same compatiblity mode.

     *

     * Otherwise, however, we require that the destination has exactly

     * the same CPU model as the source.

     */

#if defined(TARGET_PPC64)

    if (cpu->compat_pvr) {

        Error *local_err = NULL;

        ppc_set_compat(cpu, cpu->compat_pvr, &local_err);

        if (local_err) {

            error_report_err(local_err);

            error_free(local_err);

            return -1;

        }

    } else

#endif

    {

        if (!pvr_match(cpu, env->spr[SPR_PVR])) {

            return -1;

        }

    }

    env->lr = env->spr[SPR_LR];

    env->ctr = env->spr[SPR_CTR];

    cpu_write_xer(env, env->spr[SPR_XER]);

#if defined(TARGET_PPC64)

    env->cfar = env->spr[SPR_CFAR];

#endif

    env->spe_fscr = env->spr[SPR_BOOKE_SPEFSCR];

    for (i = 0; (i < 4) && (i < env->nb_BATs); i++) {

        env->DBAT[0][i] = env->spr[SPR_DBAT0U + 2*i];

        env->DBAT[1][i] = env->spr[SPR_DBAT0U + 2*i + 1];

        env->IBAT[0][i] = env->spr[SPR_IBAT0U + 2*i];

        env->IBAT[1][i] = env->spr[SPR_IBAT0U + 2*i + 1];

    }

    for (i = 0; (i < 4) && ((i+4) < env->nb_BATs); i++) {

        env->DBAT[0][i+4] = env->spr[SPR_DBAT4U + 2*i];

        env->DBAT[1][i+4] = env->spr[SPR_DBAT4U + 2*i + 1];

        env->IBAT[0][i+4] = env->spr[SPR_IBAT4U + 2*i];

        env->IBAT[1][i+4] = env->spr[SPR_IBAT4U + 2*i + 1];

    }

    if (!cpu->vhyp) {

        ppc_store_sdr1(env, env->spr[SPR_SDR1]);

    }

    /* Invalidate all msr bits except MSR_TGPR/MSR_HVB before restoring */

    msr = env->msr;

    env->msr ^= ~((1ULL << MSR_TGPR) | MSR_HVB);

    ppc_store_msr(env, msr);

    hreg_compute_mem_idx(env);

    return 0;

}


static inline void t_gen_mov_TN_preg(TCGv tn, int r)

{

    if (r < 0 || r > 15) {

        fprintf(stderr, "wrong register read $p%d\n", r);

    }

    if (r == PR_BZ || r == PR_WZ || r == PR_DZ) {

        tcg_gen_mov_tl(tn, tcg_const_tl(0));

    } else if (r == PR_VR) {

        tcg_gen_mov_tl(tn, tcg_const_tl(32));

    } else {

        tcg_gen_mov_tl(tn, cpu_PR[r]);

    }

}


int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num,

                                   int nb_sectors, int *pnum)

{

    int64_t ret = bdrv_get_block_status(bs, sector_num, nb_sectors, pnum);

    if (ret < 0) {

        return ret;

    }

    return (ret & BDRV_BLOCK_ALLOCATED);

}