static int transcode(AVFormatContext **output_files,

                     int nb_output_files,

                     InputFile *input_files,

                     int nb_input_files,

                     StreamMap *stream_maps, int nb_stream_maps)

{

    int ret = 0, i, j, k, n, nb_ostreams = 0, step;

    AVFormatContext *is, *os;

    AVCodecContext *codec, *icodec;

    OutputStream *ost, **ost_table = NULL;

    InputStream *ist;

    char error[1024];

    int key;

    int want_sdp = 1;

    uint8_t no_packet[MAX_FILES]={0};

    int no_packet_count=0;

    int nb_frame_threshold[AVMEDIA_TYPE_NB]={0};

    int nb_streams[AVMEDIA_TYPE_NB]={0};

    if (rate_emu)

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

            input_streams[i].start = av_gettime();

    /* output stream init */

    nb_ostreams = 0;

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

        os = output_files[i];

        if (!os->nb_streams && !(os->oformat->flags & AVFMT_NOSTREAMS)) {

            av_dump_format(output_files[i], i, output_files[i]->filename, 1);

            fprintf(stderr, "Output file #%d does not contain any stream\n", i);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        nb_ostreams += os->nb_streams;

    }

    if (nb_stream_maps > 0 && nb_stream_maps != nb_ostreams) {

        fprintf(stderr, "Number of stream maps must match number of output streams\n");

        ret = AVERROR(EINVAL);

        goto fail;

    }

    /* Sanity check the mapping args -- do the input files & streams exist? */

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

        int fi = stream_maps[i].file_index;

        int si = stream_maps[i].stream_index;

        if (fi < 0 || fi > nb_input_files - 1 ||

            si < 0 || si > input_files[fi].ctx->nb_streams - 1) {

            fprintf(stderr,"Could not find input stream #%d.%d\n", fi, si);

            ret = AVERROR(EINVAL);

            goto fail;

        }

        fi = stream_maps[i].sync_file_index;

        si = stream_maps[i].sync_stream_index;

        if (fi < 0 || fi > nb_input_files - 1 ||

            si < 0 || si > input_files[fi].ctx->nb_streams - 1) {

            fprintf(stderr,"Could not find sync stream #%d.%d\n", fi, si);

            ret = AVERROR(EINVAL);

            goto fail;

        }

    }

    ost_table = av_mallocz(sizeof(OutputStream *) * nb_ostreams);

    if (!ost_table)

        goto fail;

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

        os = output_files[k];

        for(i=0;i<os->nb_streams;i++,n++) {

            nb_streams[os->streams[i]->codec->codec_type]++;

        }

    }

    for(step=1<<30; step; step>>=1){

        int found_streams[AVMEDIA_TYPE_NB]={0};

        for(j=0; j<AVMEDIA_TYPE_NB; j++)

            nb_frame_threshold[j] += step;

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

            int skip=0;

            ist = &input_streams[j];

            if(opt_programid){

                int pi,si;

                AVFormatContext *f= input_files[ ist->file_index ].ctx;

                skip=1;

                for(pi=0; pi<f->nb_programs; pi++){

                    AVProgram *p= f->programs[pi];

                    if(p->id == opt_programid)

                        for(si=0; si<p->nb_stream_indexes; si++){

                            if(f->streams[ p->stream_index[si] ] == ist->st)

                                skip=0;

                        }

                }

            }

            if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip

                && nb_frame_threshold[ist->st->codec->codec_type] <= ist->st->codec_info_nb_frames){

                found_streams[ist->st->codec->codec_type]++;

            }

        }

        for(j=0; j<AVMEDIA_TYPE_NB; j++)

            if(found_streams[j] < nb_streams[j])

                nb_frame_threshold[j] -= step;

    }

    n = 0;

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

        os = output_files[k];

        for(i=0;i<os->nb_streams;i++,n++) {

            int found;

            ost = ost_table[n] = output_streams_for_file[k][i];

            if (nb_stream_maps > 0) {

                ost->source_index = input_files[stream_maps[n].file_index].ist_index +

                    stream_maps[n].stream_index;

                /* Sanity check that the stream types match */

                if (input_streams[ost->source_index].st->codec->codec_type != ost->st->codec->codec_type) {

                    int i= ost->file_index;

                    av_dump_format(output_files[i], i, output_files[i]->filename, 1);

                    fprintf(stderr, "Codec type mismatch for mapping #%d.%d -> #%d.%d\n",

                        stream_maps[n].file_index, stream_maps[n].stream_index,

                        ost->file_index, ost->index);

                    ffmpeg_exit(1);

                }

            } else {

                /* get corresponding input stream index : we select the first one with the right type */

                found = 0;

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

                    int skip=0;

                    ist = &input_streams[j];

                    if(opt_programid){

                        int pi,si;

                        AVFormatContext *f = input_files[ist->file_index].ctx;

                        skip=1;

                        for(pi=0; pi<f->nb_programs; pi++){

                            AVProgram *p= f->programs[pi];

                            if(p->id == opt_programid)

                                for(si=0; si<p->nb_stream_indexes; si++){

                                    if(f->streams[ p->stream_index[si] ] == ist->st)

                                        skip=0;

                                }

                        }

                    }

                    if (ist->discard && ist->st->discard != AVDISCARD_ALL && !skip &&

                        ist->st->codec->codec_type == ost->st->codec->codec_type &&

                        nb_frame_threshold[ist->st->codec->codec_type] <= ist->st->codec_info_nb_frames) {

                            ost->source_index = j;

                            found = 1;

                            break;

                    }

                }

                if (!found) {

                    if(! opt_programid) {

                        /* try again and reuse existing stream */

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

                            ist = &input_streams[j];

                            if (   ist->st->codec->codec_type == ost->st->codec->codec_type

                                && ist->st->discard != AVDISCARD_ALL) {

                                ost->source_index = j;

                                found = 1;

                            }

                        }

                    }

                    if (!found) {

                        int i= ost->file_index;

                        av_dump_format(output_files[i], i, output_files[i]->filename, 1);

                        fprintf(stderr, "Could not find input stream matching output stream #%d.%d\n",

                                ost->file_index, ost->index);

                        ffmpeg_exit(1);

                    }

                }

            }

            ist = &input_streams[ost->source_index];

            ist->discard = 0;

            ost->sync_ist = (nb_stream_maps > 0) ?

                &input_streams[input_files[stream_maps[n].sync_file_index].ist_index +

                         stream_maps[n].sync_stream_index] : ist;

        }

    }

    /* for each output stream, we compute the right encoding parameters */

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

        ost = ost_table[i];

        os = output_files[ost->file_index];

        ist = &input_streams[ost->source_index];

        codec = ost->st->codec;

        icodec = ist->st->codec;

        if (metadata_streams_autocopy)

            av_dict_copy(&ost->st->metadata, ist->st->metadata,

                         AV_DICT_DONT_OVERWRITE);

        ost->st->disposition = ist->st->disposition;

        codec->bits_per_raw_sample= icodec->bits_per_raw_sample;

        codec->chroma_sample_location = icodec->chroma_sample_location;

        if (ost->st->stream_copy) {

            uint64_t extra_size = (uint64_t)icodec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE;

            if (extra_size > INT_MAX)

                goto fail;

            /* if stream_copy is selected, no need to decode or encode */

            codec->codec_id = icodec->codec_id;

            codec->codec_type = icodec->codec_type;

            if(!codec->codec_tag){

                if(   !os->oformat->codec_tag

                   || av_codec_get_id (os->oformat->codec_tag, icodec->codec_tag) == codec->codec_id

                   || av_codec_get_tag(os->oformat->codec_tag, icodec->codec_id) <= 0)

                    codec->codec_tag = icodec->codec_tag;

            }

            codec->bit_rate = icodec->bit_rate;

            codec->rc_max_rate    = icodec->rc_max_rate;

            codec->rc_buffer_size = icodec->rc_buffer_size;

            codec->extradata= av_mallocz(extra_size);

            if (!codec->extradata)

                goto fail;

            memcpy(codec->extradata, icodec->extradata, icodec->extradata_size);

            codec->extradata_size= icodec->extradata_size;

            codec->time_base = ist->st->time_base;

            if(!strcmp(os->oformat->name, "avi")) {

                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > 2*av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){

                    codec->time_base = icodec->time_base;

                    codec->time_base.num *= icodec->ticks_per_frame;

                    codec->time_base.den *= 2;

                }

            } else if(!(os->oformat->flags & AVFMT_VARIABLE_FPS)) {

                if(!copy_tb && av_q2d(icodec->time_base)*icodec->ticks_per_frame > av_q2d(ist->st->time_base) && av_q2d(ist->st->time_base) < 1.0/500){

                    codec->time_base = icodec->time_base;

                    codec->time_base.num *= icodec->ticks_per_frame;

                }

            }

            av_reduce(&codec->time_base.num, &codec->time_base.den,

                        codec->time_base.num, codec->time_base.den, INT_MAX);

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                if(audio_volume != 256) {

                    fprintf(stderr,"-acodec copy and -vol are incompatible (frames are not decoded)\n");

                    ffmpeg_exit(1);

                }

                codec->channel_layout = icodec->channel_layout;

                codec->sample_rate = icodec->sample_rate;

                codec->channels = icodec->channels;

                codec->frame_size = icodec->frame_size;

                codec->audio_service_type = icodec->audio_service_type;

                codec->block_align= icodec->block_align;

                if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3)

                    codec->block_align= 0;

                if(codec->codec_id == CODEC_ID_AC3)

                    codec->block_align= 0;

                break;

            case AVMEDIA_TYPE_VIDEO:

                codec->pix_fmt = icodec->pix_fmt;

                codec->width = icodec->width;

                codec->height = icodec->height;

                codec->has_b_frames = icodec->has_b_frames;

                if (!codec->sample_aspect_ratio.num) {

                    codec->sample_aspect_ratio =

                    ost->st->sample_aspect_ratio =

                        ist->st->sample_aspect_ratio.num ? ist->st->sample_aspect_ratio :

                        ist->st->codec->sample_aspect_ratio.num ?

                        ist->st->codec->sample_aspect_ratio : (AVRational){0, 1};

                }

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                codec->width = icodec->width;

                codec->height = icodec->height;

                break;

            case AVMEDIA_TYPE_DATA:

                break;

            default:

                abort();

            }

        } else {

            if (!ost->enc)

                ost->enc = avcodec_find_encoder(ost->st->codec->codec_id);

            switch(codec->codec_type) {

            case AVMEDIA_TYPE_AUDIO:

                ost->fifo= av_fifo_alloc(1024);

                if(!ost->fifo)

                    goto fail;

                ost->reformat_pair = MAKE_SFMT_PAIR(AV_SAMPLE_FMT_NONE,AV_SAMPLE_FMT_NONE);

                if (!codec->sample_rate) {

                    codec->sample_rate = icodec->sample_rate;

                }

                choose_sample_rate(ost->st, ost->enc);

                codec->time_base = (AVRational){1, codec->sample_rate};

                if (codec->sample_fmt == AV_SAMPLE_FMT_NONE)

                    codec->sample_fmt = icodec->sample_fmt;

                choose_sample_fmt(ost->st, ost->enc);

                if (!codec->channels) {

                    codec->channels = icodec->channels;

                    codec->channel_layout = icodec->channel_layout;

                }

                if (av_get_channel_layout_nb_channels(codec->channel_layout) != codec->channels)

                    codec->channel_layout = 0;

                ost->audio_resample = codec->sample_rate != icodec->sample_rate || audio_sync_method > 1;

                icodec->request_channels = codec->channels;

                ist->decoding_needed = 1;

                ost->encoding_needed = 1;

                ost->resample_sample_fmt  = icodec->sample_fmt;

                ost->resample_sample_rate = icodec->sample_rate;

                ost->resample_channels    = icodec->channels;

                break;

            case AVMEDIA_TYPE_VIDEO:

                if (codec->pix_fmt == PIX_FMT_NONE)

                    codec->pix_fmt = icodec->pix_fmt;

                choose_pixel_fmt(ost->st, ost->enc);

                if (ost->st->codec->pix_fmt == PIX_FMT_NONE) {

                    fprintf(stderr, "Video pixel format is unknown, stream cannot be encoded\n");

                    ffmpeg_exit(1);

                }

                if (!codec->width || !codec->height) {

                    codec->width  = icodec->width;

                    codec->height = icodec->height;

                }

                ost->video_resample = codec->width   != icodec->width  ||

                                      codec->height  != icodec->height ||

                                      codec->pix_fmt != icodec->pix_fmt;

                if (ost->video_resample) {

                    codec->bits_per_raw_sample= frame_bits_per_raw_sample;

                }

                ost->resample_height = icodec->height;

                ost->resample_width  = icodec->width;

                ost->resample_pix_fmt= icodec->pix_fmt;

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                if (!ost->frame_rate.num)

                    ost->frame_rate = ist->st->r_frame_rate.num ? ist->st->r_frame_rate : (AVRational){25,1};

                if (ost->enc && ost->enc->supported_framerates && !force_fps) {

                    int idx = av_find_nearest_q_idx(ost->frame_rate, ost->enc->supported_framerates);

                    ost->frame_rate = ost->enc->supported_framerates[idx];

                }

                codec->time_base = (AVRational){ost->frame_rate.den, ost->frame_rate.num};

                if(   av_q2d(codec->time_base) < 0.001 && video_sync_method

                   && (video_sync_method==1 || (video_sync_method<0 && !(os->oformat->flags & AVFMT_VARIABLE_FPS)))){

                    av_log(os, AV_LOG_WARNING, "Frame rate very high for a muxer not effciciently supporting it.\n"

                                               "Please consider specifiying a lower framerate, a different muxer or -vsync 2\n");

                }

#if CONFIG_AVFILTER

                if (configure_video_filters(ist, ost)) {

                    fprintf(stderr, "Error opening filters!\n");

                    exit(1);

                }

#endif

                break;

            case AVMEDIA_TYPE_SUBTITLE:

                ost->encoding_needed = 1;

                ist->decoding_needed = 1;

                break;

            default:

                abort();

                break;

            }

            /* two pass mode */

            if (ost->encoding_needed && codec->codec_id != CODEC_ID_H264 &&

                (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {

                char logfilename[1024];

                FILE *f;

                snprintf(logfilename, sizeof(logfilename), "%s-%d.log",

                         pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX,

                         i);

                if (codec->flags & CODEC_FLAG_PASS1) {

                    f = fopen(logfilename, "wb");

                    if (!f) {

                        fprintf(stderr, "Cannot write log file '%s' for pass-1 encoding: %s\n", logfilename, strerror(errno));

                        ffmpeg_exit(1);

                    }

                    ost->logfile = f;

                } else {

                    char  *logbuffer;

                    size_t logbuffer_size;

                    if (read_file(logfilename, &logbuffer, &logbuffer_size) < 0) {

                        fprintf(stderr, "Error reading log file '%s' for pass-2 encoding\n", logfilename);

                        ffmpeg_exit(1);

                    }

                    codec->stats_in = logbuffer;

                }

            }

        }

        if(codec->codec_type == AVMEDIA_TYPE_VIDEO){

            /* maximum video buffer size is 6-bytes per pixel, plus DPX header size */

            int size= codec->width * codec->height;

            bit_buffer_size= FFMAX(bit_buffer_size, 6*size + 1664);

        }

    }

    if (!bit_buffer)

        bit_buffer = av_malloc(bit_buffer_size);

    if (!bit_buffer) {

        fprintf(stderr, "Cannot allocate %d bytes output buffer\n",

                bit_buffer_size);

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    /* open each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            AVCodec *codec = ost->enc;

            AVCodecContext *dec = input_streams[ost->source_index].st->codec;

            if (!codec) {

                snprintf(error, sizeof(error), "Encoder (codec id %d) not found for output stream #%d.%d",

                         ost->st->codec->codec_id, ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            if (dec->subtitle_header) {

                ost->st->codec->subtitle_header = av_malloc(dec->subtitle_header_size);

                if (!ost->st->codec->subtitle_header) {

                    ret = AVERROR(ENOMEM);

                    goto dump_format;

                }

                memcpy(ost->st->codec->subtitle_header, dec->subtitle_header, dec->subtitle_header_size);

                ost->st->codec->subtitle_header_size = dec->subtitle_header_size;

            }

            if (avcodec_open2(ost->st->codec, codec, &ost->opts) < 0) {

                snprintf(error, sizeof(error), "Error while opening encoder for output stream #%d.%d - maybe incorrect parameters such as bit_rate, rate, width or height",

                        ost->file_index, ost->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            assert_codec_experimental(ost->st->codec, 1);

            assert_avoptions(ost->opts);

            if (ost->st->codec->bit_rate && ost->st->codec->bit_rate < 1000)

                av_log(NULL, AV_LOG_WARNING, "The bitrate parameter is set too low."

                                             "It takes bits/s as argument, not kbits/s\n");

            extra_size += ost->st->codec->extradata_size;

        }

    }

    /* open each decoder */

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

        ist = &input_streams[i];

        if (ist->decoding_needed) {

            AVCodec *codec = ist->dec;

            if (!codec)

                codec = avcodec_find_decoder(ist->st->codec->codec_id);

            if (!codec) {

                snprintf(error, sizeof(error), "Decoder (codec id %d) not found for input stream #%d.%d",

                        ist->st->codec->codec_id, ist->file_index, ist->st->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            if (avcodec_open2(ist->st->codec, codec, &ist->opts) < 0) {

                snprintf(error, sizeof(error), "Error while opening decoder for input stream #%d.%d",

                        ist->file_index, ist->st->index);

                ret = AVERROR(EINVAL);

                goto dump_format;

            }

            assert_codec_experimental(ist->st->codec, 0);

            assert_avoptions(ost->opts);

            //if (ist->st->codec->codec_type == AVMEDIA_TYPE_VIDEO)

            //    ist->st->codec->flags |= CODEC_FLAG_REPEAT_FIELD;

        }

    }

    /* init pts */

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

        AVStream *st;

        ist = &input_streams[i];

        st= ist->st;

        ist->pts = st->avg_frame_rate.num ? - st->codec->has_b_frames*AV_TIME_BASE / av_q2d(st->avg_frame_rate) : 0;

        ist->next_pts = AV_NOPTS_VALUE;

        ist->is_start = 1;

    }

    /* set meta data information from input file if required */

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

        AVFormatContext *files[2];

        AVDictionary    **meta[2];

        int j;

#define METADATA_CHECK_INDEX(index, nb_elems, desc)\

        if ((index) < 0 || (index) >= (nb_elems)) {\

            snprintf(error, sizeof(error), "Invalid %s index %d while processing metadata maps\n",\

                     (desc), (index));\

            ret = AVERROR(EINVAL);\

            goto dump_format;\

        }

        int out_file_index = meta_data_maps[i][0].file;

        int in_file_index = meta_data_maps[i][1].file;

        if (in_file_index < 0 || out_file_index < 0)

            continue;

        METADATA_CHECK_INDEX(out_file_index, nb_output_files, "output file")

        METADATA_CHECK_INDEX(in_file_index, nb_input_files, "input file")

        files[0] = output_files[out_file_index];

        files[1] = input_files[in_file_index].ctx;

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

            MetadataMap *map = &meta_data_maps[i][j];

            switch (map->type) {

            case 'g':

                meta[j] = &files[j]->metadata;

                break;

            case 's':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_streams, "stream")

                meta[j] = &files[j]->streams[map->index]->metadata;

                break;

            case 'c':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_chapters, "chapter")

                meta[j] = &files[j]->chapters[map->index]->metadata;

                break;

            case 'p':

                METADATA_CHECK_INDEX(map->index, files[j]->nb_programs, "program")

                meta[j] = &files[j]->programs[map->index]->metadata;

                break;

            }

        }

        av_dict_copy(meta[0], *meta[1], AV_DICT_DONT_OVERWRITE);

    }

    /* copy global metadata by default */

    if (metadata_global_autocopy) {

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

            av_dict_copy(&output_files[i]->metadata, input_files[0].ctx->metadata,

                         AV_DICT_DONT_OVERWRITE);

    }

    /* copy chapters according to chapter maps */

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

        int infile  = chapter_maps[i].in_file;

        int outfile = chapter_maps[i].out_file;

        if (infile < 0 || outfile < 0)

            continue;

        if (infile >= nb_input_files) {

            snprintf(error, sizeof(error), "Invalid input file index %d in chapter mapping.\n", infile);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        if (outfile >= nb_output_files) {

            snprintf(error, sizeof(error), "Invalid output file index %d in chapter mapping.\n",outfile);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

        copy_chapters(infile, outfile);

    }

    /* copy chapters from the first input file that has them*/

    if (!nb_chapter_maps)

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

            if (!input_files[i].ctx->nb_chapters)

                continue;

            for (j = 0; j < nb_output_files; j++)

                if ((ret = copy_chapters(i, j)) < 0)

                    goto dump_format;

            break;

        }

    /* open files and write file headers */

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

        os = output_files[i];

        if (avformat_write_header(os, &output_opts[i]) < 0) {

            snprintf(error, sizeof(error), "Could not write header for output file #%d (incorrect codec parameters ?)", i);

            ret = AVERROR(EINVAL);

            goto dump_format;

        }

//        assert_avoptions(output_opts[i]);

        if (strcmp(output_files[i]->oformat->name, "rtp")) {

            want_sdp = 0;

        }

    }

 dump_format:

    /* dump the file output parameters - cannot be done before in case

       of stream copy */

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

        av_dump_format(output_files[i], i, output_files[i]->filename, 1);

    }

    /* dump the stream mapping */

    if (verbose >= 0) {

        fprintf(stderr, "Stream mapping:\n");

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

            ost = ost_table[i];

            fprintf(stderr, "  Stream #%d.%d -> #%d.%d",

                    input_streams[ost->source_index].file_index,

                    input_streams[ost->source_index].st->index,

                    ost->file_index,

                    ost->index);

            if (ost->sync_ist != &input_streams[ost->source_index])

                fprintf(stderr, " [sync #%d.%d]",

                        ost->sync_ist->file_index,

                        ost->sync_ist->st->index);

            fprintf(stderr, "\n");

        }

    }

    if (ret) {

        fprintf(stderr, "%s\n", error);

        goto fail;

    }

    if (want_sdp) {

        print_sdp(output_files, nb_output_files);

    }

    if (!using_stdin) {

        if(verbose >= 0)

            fprintf(stderr, "Press [q] to stop, [?] for help\n");

        avio_set_interrupt_cb(decode_interrupt_cb);

    }

    term_init();

    timer_start = av_gettime();

    for(; received_sigterm == 0;) {

        int file_index, ist_index;

        AVPacket pkt;

        double ipts_min;

        double opts_min;

    redo:

        ipts_min= 1e100;

        opts_min= 1e100;

        /* if 'q' pressed, exits */

        if (!using_stdin) {

            if (q_pressed)

                break;

            /* read_key() returns 0 on EOF */

            key = read_key();

            if (key == 'q')

                break;

            if (key == '+') verbose++;

            if (key == '-') verbose--;

            if (key == 's') qp_hist     ^= 1;

            if (key == 'h'){

                if (do_hex_dump){

                    do_hex_dump = do_pkt_dump = 0;

                } else if(do_pkt_dump){

                    do_hex_dump = 1;

                } else

                    do_pkt_dump = 1;

                av_log_set_level(AV_LOG_DEBUG);

            }

            if (key == 'd' || key == 'D'){

                int debug=0;

                if(key == 'D') {

                    debug = input_streams[0].st->codec->debug<<1;

                    if(!debug) debug = 1;

                    while(debug & (FF_DEBUG_DCT_COEFF|FF_DEBUG_VIS_QP|FF_DEBUG_VIS_MB_TYPE)) //unsupported, would just crash

                        debug += debug;

                }else

                    scanf("%d", &debug);

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

                    input_streams[i].st->codec->debug = debug;

                }

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

                    ost = ost_table[i];

                    ost->st->codec->debug = debug;

                }

                if(debug) av_log_set_level(AV_LOG_DEBUG);

                fprintf(stderr,"debug=%d\n", debug);

            }

            if (key == '?'){

                fprintf(stderr, "key    function\n"

                                "?      show this help\n"

                                "+      increase verbosity\n"

                                "-      decrease verbosity\n"

                                "D      cycle through available debug modes\n"

                                "h      dump packets/hex press to cycle through the 3 states\n"

                                "q      quit\n"

                                "s      Show QP histogram\n"

                );

            }

        }

        /* select the stream that we must read now by looking at the

           smallest output pts */

        file_index = -1;

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

            double ipts, opts;

            ost = ost_table[i];

            os = output_files[ost->file_index];

            ist = &input_streams[ost->source_index];

            if(ist->is_past_recording_time || no_packet[ist->file_index])

                continue;

                opts = ost->st->pts.val * av_q2d(ost->st->time_base);

            ipts = (double)ist->pts;

            if (!input_files[ist->file_index].eof_reached){

                if(ipts < ipts_min) {

                    ipts_min = ipts;

                    if(input_sync ) file_index = ist->file_index;

                }

                if(opts < opts_min) {

                    opts_min = opts;

                    if(!input_sync) file_index = ist->file_index;

                }

            }

            if(ost->frame_number >= max_frames[ost->st->codec->codec_type]){

                file_index= -1;

                break;

            }

        }

        /* if none, if is finished */

        if (file_index < 0) {

            if(no_packet_count){

                no_packet_count=0;

                memset(no_packet, 0, sizeof(no_packet));

                usleep(10000);

                continue;

            }

            break;

        }

        /* finish if limit size exhausted */

        if (limit_filesize != 0 && limit_filesize <= avio_tell(output_files[0]->pb))

            break;

        /* read a frame from it and output it in the fifo */

        is = input_files[file_index].ctx;

        ret= av_read_frame(is, &pkt);

        if(ret == AVERROR(EAGAIN)){

            no_packet[file_index]=1;

            no_packet_count++;

            continue;

        }

        if (ret < 0) {

            input_files[file_index].eof_reached = 1;

            if (opt_shortest)

                break;

            else

                continue;

        }

        no_packet_count=0;

        memset(no_packet, 0, sizeof(no_packet));

        if (do_pkt_dump) {

            av_pkt_dump_log2(NULL, AV_LOG_DEBUG, &pkt, do_hex_dump,

                             is->streams[pkt.stream_index]);

        }

        /* the following test is needed in case new streams appear

           dynamically in stream : we ignore them */

        if (pkt.stream_index >= input_files[file_index].ctx->nb_streams)

            goto discard_packet;

        ist_index = input_files[file_index].ist_index + pkt.stream_index;

        ist = &input_streams[ist_index];

        if (ist->discard)

            goto discard_packet;

        if (pkt.dts != AV_NOPTS_VALUE)

            pkt.dts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);

        if (pkt.pts != AV_NOPTS_VALUE)

            pkt.pts += av_rescale_q(input_files[ist->file_index].ts_offset, AV_TIME_BASE_Q, ist->st->time_base);

        if (ist->ts_scale) {

            if(pkt.pts != AV_NOPTS_VALUE)

                pkt.pts *= ist->ts_scale;

            if(pkt.dts != AV_NOPTS_VALUE)

                pkt.dts *= ist->ts_scale;

        }

//        fprintf(stderr, "next:%"PRId64" dts:%"PRId64" off:%"PRId64" %d\n", ist->next_pts, pkt.dts, input_files[ist->file_index].ts_offset, ist->st->codec->codec_type);

        if (pkt.dts != AV_NOPTS_VALUE && ist->next_pts != AV_NOPTS_VALUE

            && (is->iformat->flags & AVFMT_TS_DISCONT)) {

            int64_t pkt_dts= av_rescale_q(pkt.dts, ist->st->time_base, AV_TIME_BASE_Q);

            int64_t delta= pkt_dts - ist->next_pts;

            if((FFABS(delta) > 1LL*dts_delta_threshold*AV_TIME_BASE || pkt_dts+1<ist->pts)&& !copy_ts){

                input_files[ist->file_index].ts_offset -= delta;

                if (verbose > 2)

                    fprintf(stderr, "timestamp discontinuity %"PRId64", new offset= %"PRId64"\n",

                            delta, input_files[ist->file_index].ts_offset);

                pkt.dts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

                if(pkt.pts != AV_NOPTS_VALUE)

                    pkt.pts-= av_rescale_q(delta, AV_TIME_BASE_Q, ist->st->time_base);

            }

        }

        /* finish if recording time exhausted */

        if (recording_time != INT64_MAX &&

            (pkt.pts != AV_NOPTS_VALUE ?

                av_compare_ts(pkt.pts, ist->st->time_base, recording_time + start_time, (AVRational){1, 1000000})

                    :

                av_compare_ts(ist->pts, AV_TIME_BASE_Q, recording_time + start_time, (AVRational){1, 1000000})

            )>= 0) {

            ist->is_past_recording_time = 1;

            goto discard_packet;

        }

        //fprintf(stderr,"read #%d.%d size=%d\n", ist->file_index, ist->st->index, pkt.size);

        if (output_packet(ist, ist_index, ost_table, nb_ostreams, &pkt) < 0) {

            if (verbose >= 0)

                fprintf(stderr, "Error while decoding stream #%d.%d\n",

                        ist->file_index, ist->st->index);

            if (exit_on_error)

                ffmpeg_exit(1);

            av_free_packet(&pkt);

            goto redo;

        }

    discard_packet:

        av_free_packet(&pkt);

        /* dump report by using the output first video and audio streams */

        print_report(output_files, ost_table, nb_ostreams, 0);

    }

    /* at the end of stream, we must flush the decoder buffers */

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

        ist = &input_streams[i];

        if (ist->decoding_needed) {

            output_packet(ist, i, ost_table, nb_ostreams, NULL);

        }

    }

    term_exit();

    /* write the trailer if needed and close file */

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

        os = output_files[i];

        av_write_trailer(os);

    }

    /* dump report by using the first video and audio streams */

    print_report(output_files, ost_table, nb_ostreams, 1);

    /* close each encoder */

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

        ost = ost_table[i];

        if (ost->encoding_needed) {

            av_freep(&ost->st->codec->stats_in);

            avcodec_close(ost->st->codec);

        }

#if CONFIG_AVFILTER

        avfilter_graph_free(&ost->graph);

#endif

    }

    /* close each decoder */

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

        ist = &input_streams[i];

        if (ist->decoding_needed) {

            avcodec_close(ist->st->codec);

        }

    }

    /* finished ! */

    ret = 0;

 fail:

    av_freep(&bit_buffer);

    if (ost_table) {

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

            ost = ost_table[i];

            if (ost) {

                if (ost->st->stream_copy)

                    av_freep(&ost->st->codec->extradata);

                if (ost->logfile) {

                    fclose(ost->logfile);

                    ost->logfile = NULL;

                }

                av_fifo_free(ost->fifo); /* works even if fifo is not

                                             initialized but set to zero */

                av_freep(&ost->st->codec->subtitle_header);

                av_free(ost->resample_frame.data[0]);

                av_free(ost->forced_kf_pts);

                if (ost->video_resample)

                    sws_freeContext(ost->img_resample_ctx);

                if (ost->resample)

                    audio_resample_close(ost->resample);

                if (ost->reformat_ctx)

                    av_audio_convert_free(ost->reformat_ctx);

                av_dict_free(&ost->opts);

                av_free(ost);

            }

        }

        av_free(ost_table);

    }

    return ret;

}


static int qemu_event_init(void)

{

    int err;

    int fds[2];

    err = pipe(fds);

    if (err == -1)

        return -errno;

    err = fcntl_setfl(fds[0], O_NONBLOCK);

    if (err < 0)

        goto fail;

    err = fcntl_setfl(fds[1], O_NONBLOCK);

    if (err < 0)

        goto fail;

    qemu_set_fd_handler2(fds[0], NULL, qemu_event_read, NULL,

                         (void *)(unsigned long)fds[0]);

    io_thread_fd = fds[1];

    return 0;

fail:

    close(fds[0]);

    close(fds[1]);

    return err;

}


static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt,

                              const AVFrame *pic_arg, int *got_packet)

{

    MpegEncContext *s = avctx->priv_data;

    AVFrame *pic;

    int i, ret;

    int chroma_h_shift, chroma_v_shift;

    av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &chroma_h_shift, &chroma_v_shift);

    //CODEC_FLAG_EMU_EDGE have to be cleared

    if(s->avctx->flags & CODEC_FLAG_EMU_EDGE)

        return AVERROR(EINVAL);

    if (avctx->height & 15) {

        av_log(avctx, AV_LOG_ERROR,

               "Height must be a multiple of 16, also note, "

               "if you have a AMV sample thats mod 16 != 0, please contact us\n");

        return AVERROR(EINVAL);

    }

    pic = av_frame_clone(pic_arg);

    if (!pic)

        return AVERROR(ENOMEM);

    //picture should be flipped upside-down

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

        int vsample = i ? 2 >> chroma_v_shift : 2;

        pic->data[i] += (pic->linesize[i] * (vsample * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 ));

        pic->linesize[i] *= -1;

    }

    ret = ff_MPV_encode_picture(avctx, pkt, pic, got_packet);

    av_frame_free(&pic);

    return ret;

}


static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv val2,

                         int insn, int rd)

{

    TCGv val1 = gen_load_gpr(dc, rd);

    TCGv dst = gen_dest_gpr(dc, rd);

    TCGv_i32 r_asi = gen_get_asi(dc, insn);

    gen_helper_casx_asi(dst, cpu_env, addr, val1, val2, r_asi);

    tcg_temp_free_i32(r_asi);

    gen_store_gpr(dc, rd, dst);

}


static void bt_vhci_add(int vlan_id)

{

    struct bt_scatternet_s *vlan = qemu_find_bt_vlan(vlan_id);

    if (!vlan->slave)

        fprintf(stderr, "qemu: warning: adding a VHCI to "

                        "an empty scatternet %i\n", vlan_id);

    bt_vhci_init(bt_new_hci(vlan));

}


e1000_autoneg_timer(void *opaque)

{

    E1000State *s = opaque;

    if (!qemu_get_queue(s->nic)->link_down) {

        e1000_link_up(s);

    }

    s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;

    DBGOUT(PHY, "Auto negotiation is completed\n");

}


static inline void halfpel_motion_search4(MpegEncContext * s,

				  int *mx_ptr, int *my_ptr, int dmin,

				  int xmin, int ymin, int xmax, int ymax,

                                  int pred_x, int pred_y, int block_x, int block_y,

                                  uint8_t *ref_picture)

{

    UINT16 *mv_penalty= s->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame

    const int quant= s->qscale;

    int pen_x, pen_y;

    int mx, my, mx1, my1, d, xx, yy, dminh;

    UINT8 *pix, *ptr;

    xx = 8 * block_x;

    yy = 8 * block_y;

    pix =  s->new_picture[0] + (yy * s->linesize) + xx;

    mx = *mx_ptr;

    my = *my_ptr;

    ptr = ref_picture + ((yy+my) * s->linesize) + xx + mx;

    dminh = dmin;

    if (mx > xmin && mx < xmax &&

        my > ymin && my < ymax) {

        mx= mx1= 2*mx;

        my= my1= 2*my;

        if(dmin < Z_THRESHOLD && mx==0 && my==0){

            *mx_ptr = 0;

            *my_ptr = 0;

            return;

        }

        pen_x= pred_x + mx;

        pen_y= pred_y + my;

        ptr-= s->linesize;

        CHECK_HALF_MV4(xy2, -1, -1)

        CHECK_HALF_MV4(y2 ,  0, -1)

        CHECK_HALF_MV4(xy2, +1, -1)

        ptr+= s->linesize;

        CHECK_HALF_MV4(x2 , -1,  0)

        CHECK_HALF_MV4(x2 , +1,  0)

        CHECK_HALF_MV4(xy2, -1, +1)

        CHECK_HALF_MV4(y2 ,  0, +1)

        CHECK_HALF_MV4(xy2, +1, +1)

    }else{

        mx*=2;

        my*=2;

    }

    *mx_ptr = mx;

    *my_ptr = my;

}


void cpu_loop(CPUCRISState *env)

{

    CPUState *cs = CPU(cris_env_get_cpu(env));

    int trapnr, ret;

    target_siginfo_t info;

    while (1) {

        cpu_exec_start(cs);

        trapnr = cpu_cris_exec(cs);

        cpu_exec_end(cs);

        switch (trapnr) {

        case 0xaa:

            {

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                /* XXX: check env->error_code */

                info.si_code = TARGET_SEGV_MAPERR;

                info._sifields._sigfault._addr = env->pregs[PR_EDA];

                queue_signal(env, info.si_signo, &info);

            }

            break;

	case EXCP_INTERRUPT:

	  /* just indicate that signals should be handled asap */

	  break;

        case EXCP_BREAK:

            ret = do_syscall(env,

                             env->regs[9],

                             env->regs[10],

                             env->regs[11],

                             env->regs[12],

                             env->regs[13],

                             env->pregs[7],

                             env->pregs[11],

                             0, 0);

            env->regs[10] = ret;

            break;

        case EXCP_DEBUG:

            {

                int sig;

                sig = gdb_handlesig(cs, TARGET_SIGTRAP);

                if (sig)

                  {

                    info.si_signo = sig;

                    info.si_errno = 0;

                    info.si_code = TARGET_TRAP_BRKPT;

                    queue_signal(env, info.si_signo, &info);

                  }

            }

            break;

        default:

            printf ("Unhandled trap: 0x%x\n", trapnr);

            cpu_dump_state(cs, stderr, fprintf, 0);

            exit(EXIT_FAILURE);

        }

        process_pending_signals (env);

    }

}


static void tlb_info_32(Monitor *mon, CPUState *env)

{

    int l1, l2;

    uint32_t pgd, pde, pte;

    pgd = env->cr[3] & ~0xfff;

    for(l1 = 0; l1 < 1024; l1++) {

        cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);

        pde = le32_to_cpu(pde);

        if (pde & PG_PRESENT_MASK) {

            if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {

                /* 4M pages */

                print_pte(mon, (l1 << 22), pde, ~((1 << 21) - 1));

            } else {

                for(l2 = 0; l2 < 1024; l2++) {

                    cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);

                    pte = le32_to_cpu(pte);

                    if (pte & PG_PRESENT_MASK) {

                        print_pte(mon, (l1 << 22) + (l2 << 12),

                                  pte & ~PG_PSE_MASK,

                                  ~0xfff);

                    }

                }

            }

        }

    }

}


void parse_option_size(const char *name, const char *value,

                       uint64_t *ret, Error **errp)

{

    uint64_t size;

    int err;

    err = qemu_strtosz(value, NULL, &size);

    if (err == -ERANGE) {

        error_setg(errp, "Value '%s' is too large for parameter '%s'",

                   value, name);

        return;

    }

    if (err) {

        error_setg(errp, QERR_INVALID_PARAMETER_VALUE, name,

                   "a non-negative number below 2^64");

        error_append_hint(errp, "Optional suffix k, M, G, T, P or E means"

                          " kilo-, mega-, giga-, tera-, peta-\n"

                          "and exabytes, respectively.\n");

        return;

    }

    *ret = size;

}


static int get_physical_addr_mmu(CPUXtensaState *env, bool update_tlb,

        uint32_t vaddr, int is_write, int mmu_idx,

        uint32_t *paddr, uint32_t *page_size, unsigned *access,

        bool may_lookup_pt)

{

    bool dtlb = is_write != 2;

    uint32_t wi;

    uint32_t ei;

    uint8_t ring;

    uint32_t vpn;

    uint32_t pte;

    const xtensa_tlb_entry *entry = NULL;

    xtensa_tlb_entry tmp_entry;

    int ret = xtensa_tlb_lookup(env, vaddr, dtlb, &wi, &ei, &ring);

    if ((ret == INST_TLB_MISS_CAUSE || ret == LOAD_STORE_TLB_MISS_CAUSE) &&

            may_lookup_pt && get_pte(env, vaddr, &pte) == 0) {

        ring = (pte >> 4) & 0x3;

        wi = 0;

        split_tlb_entry_spec_way(env, vaddr, dtlb, &vpn, wi, &ei);

        if (update_tlb) {

            wi = ++env->autorefill_idx & 0x3;

            xtensa_tlb_set_entry(env, dtlb, wi, ei, vpn, pte);

            env->sregs[EXCVADDR] = vaddr;

            qemu_log("%s: autorefill(%08x): %08x -> %08x\n",

                    __func__, vaddr, vpn, pte);

        } else {

            xtensa_tlb_set_entry_mmu(env, &tmp_entry, dtlb, wi, ei, vpn, pte);

            entry = &tmp_entry;

        }

        ret = 0;

    }

    if (ret != 0) {

        return ret;

    }

    if (entry == NULL) {

        entry = xtensa_tlb_get_entry(env, dtlb, wi, ei);

    }

    if (ring < mmu_idx) {

        return dtlb ?

            LOAD_STORE_PRIVILEGE_CAUSE :

            INST_FETCH_PRIVILEGE_CAUSE;

    }

    *access = mmu_attr_to_access(entry->attr);

    if (!is_access_granted(*access, is_write)) {

        return dtlb ?

            (is_write ?

             STORE_PROHIBITED_CAUSE :

             LOAD_PROHIBITED_CAUSE) :

            INST_FETCH_PROHIBITED_CAUSE;

    }

    *paddr = entry->paddr | (vaddr & ~xtensa_tlb_get_addr_mask(env, dtlb, wi));

    *page_size = ~xtensa_tlb_get_addr_mask(env, dtlb, wi) + 1;

    return 0;

}


e1000e_intrmgr_delay_rx_causes(E1000ECore *core, uint32_t *causes)

{

    uint32_t delayable_causes;

    uint32_t rdtr = core->mac[RDTR];

    uint32_t radv = core->mac[RADV];

    uint32_t raid = core->mac[RAID];

    if (msix_enabled(core->owner)) {

        return false;

    }

    delayable_causes = E1000_ICR_RXQ0 |

                       E1000_ICR_RXQ1 |

                       E1000_ICR_RXT0;

    if (!(core->mac[RFCTL] & E1000_RFCTL_ACK_DIS)) {

        delayable_causes |= E1000_ICR_ACK;

    }

    /* Clean up all causes that may be delayed */

    core->delayed_causes |= *causes & delayable_causes;

    *causes &= ~delayable_causes;

    /* Check if delayed RX interrupts disabled by client

       or if there are causes that cannot be delayed */

    if ((rdtr == 0) || (causes != 0)) {

        return false;

    }

    /* Check if delayed RX ACK interrupts disabled by client

       and there is an ACK packet received */

    if ((raid == 0) && (core->delayed_causes & E1000_ICR_ACK)) {

        return false;

    }

    /* All causes delayed */

    e1000e_intrmgr_rearm_timer(&core->rdtr);

    if (!core->radv.running && (radv != 0)) {

        e1000e_intrmgr_rearm_timer(&core->radv);

    }

    if (!core->raid.running && (core->delayed_causes & E1000_ICR_ACK)) {

        e1000e_intrmgr_rearm_timer(&core->raid);

    }

    return true;

}


static int virtio_ccw_cb(SubchDev *sch, CCW1 ccw)

{

    int ret;

    VirtioRevInfo revinfo;

    uint8_t status;

    VirtioFeatDesc features;

    void *config;

    hwaddr indicators;

    VqConfigBlock vq_config;

    VirtioCcwDevice *dev = sch->driver_data;

    VirtIODevice *vdev = virtio_ccw_get_vdev(sch);

    bool check_len;

    int len;

    hwaddr hw_len;

    VirtioThinintInfo *thinint;

    if (!dev) {

        return -EINVAL;

    }

    trace_virtio_ccw_interpret_ccw(sch->cssid, sch->ssid, sch->schid,

                                   ccw.cmd_code);

    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));

    if (dev->force_revision_1 && dev->revision < 0 &&

        ccw.cmd_code != CCW_CMD_SET_VIRTIO_REV) {

        /*

         * virtio-1 drivers must start with negotiating to a revision >= 1,

         * so post a command reject for all other commands

         */

        return -ENOSYS;

    }

    /* Look at the command. */

    switch (ccw.cmd_code) {

    case CCW_CMD_SET_VQ:

        ret = virtio_ccw_handle_set_vq(sch, ccw, check_len, dev->revision < 1);

        break;

    case CCW_CMD_VDEV_RESET:

        virtio_ccw_reset_virtio(dev, vdev);

        ret = 0;

        break;

    case CCW_CMD_READ_FEAT:

        if (check_len) {

            if (ccw.count != sizeof(features)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(features)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            VirtioDeviceClass *vdc = VIRTIO_DEVICE_GET_CLASS(vdev);

            features.index = address_space_ldub(&address_space_memory,

                                                ccw.cda

                                                + sizeof(features.features),

                                                MEMTXATTRS_UNSPECIFIED,

                                                NULL);

            if (features.index == 0) {

                if (dev->revision >= 1) {

                    /* Don't offer legacy features for modern devices. */

                    features.features = (uint32_t)

                        (vdev->host_features & ~vdc->legacy_features);

                } else {

                    features.features = (uint32_t)vdev->host_features;

                }

            } else if ((features.index == 1) && (dev->revision >= 1)) {

                /*

                 * Only offer feature bits beyond 31 if the guest has

                 * negotiated at least revision 1.

                 */

                features.features = (uint32_t)(vdev->host_features >> 32);

            } else {

                /* Return zeroes if the guest supports more feature bits. */

                features.features = 0;

            }

            address_space_stl_le(&address_space_memory, ccw.cda,

                                 features.features, MEMTXATTRS_UNSPECIFIED,

                                 NULL);

            sch->curr_status.scsw.count = ccw.count - sizeof(features);

            ret = 0;

        }

        break;

    case CCW_CMD_WRITE_FEAT:

        if (check_len) {

            if (ccw.count != sizeof(features)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(features)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            features.index = address_space_ldub(&address_space_memory,

                                                ccw.cda

                                                + sizeof(features.features),

                                                MEMTXATTRS_UNSPECIFIED,

                                                NULL);

            features.features = address_space_ldl_le(&address_space_memory,

                                                     ccw.cda,

                                                     MEMTXATTRS_UNSPECIFIED,

                                                     NULL);

            if (features.index == 0) {

                virtio_set_features(vdev,

                                    (vdev->guest_features & 0xffffffff00000000ULL) |

                                    features.features);

            } else if ((features.index == 1) && (dev->revision >= 1)) {

                /*

                 * If the guest did not negotiate at least revision 1,

                 * we did not offer it any feature bits beyond 31. Such a

                 * guest passing us any bit here is therefore buggy.

                 */

                virtio_set_features(vdev,

                                    (vdev->guest_features & 0x00000000ffffffffULL) |

                                    ((uint64_t)features.features << 32));

            } else {

                /*

                 * If the guest supports more feature bits, assert that it

                 * passes us zeroes for those we don't support.

                 */

                if (features.features) {

                    fprintf(stderr, "Guest bug: features[%i]=%x (expected 0)\n",

                            features.index, features.features);

                    /* XXX: do a unit check here? */

                }

            }

            sch->curr_status.scsw.count = ccw.count - sizeof(features);

            ret = 0;

        }

        break;

    case CCW_CMD_READ_CONF:

        if (check_len) {

            if (ccw.count > vdev->config_len) {

                ret = -EINVAL;

                break;

            }

        }

        len = MIN(ccw.count, vdev->config_len);

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            virtio_bus_get_vdev_config(&dev->bus, vdev->config);

            cpu_physical_memory_write(ccw.cda, vdev->config, len);

            sch->curr_status.scsw.count = ccw.count - len;

            ret = 0;

        }

        break;

    case CCW_CMD_WRITE_CONF:

        if (check_len) {

            if (ccw.count > vdev->config_len) {

                ret = -EINVAL;

                break;

            }

        }

        len = MIN(ccw.count, vdev->config_len);

        hw_len = len;

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            config = cpu_physical_memory_map(ccw.cda, &hw_len, 0);

            if (!config) {

                ret = -EFAULT;

            } else {

                len = hw_len;

                memcpy(vdev->config, config, len);

                cpu_physical_memory_unmap(config, hw_len, 0, hw_len);

                virtio_bus_set_vdev_config(&dev->bus, vdev->config);

                sch->curr_status.scsw.count = ccw.count - len;

                ret = 0;

            }

        }

        break;

    case CCW_CMD_READ_STATUS:

        if (check_len) {

            if (ccw.count != sizeof(status)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(status)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            address_space_stb(&address_space_memory, ccw.cda, vdev->status,

                                        MEMTXATTRS_UNSPECIFIED, NULL);

            sch->curr_status.scsw.count = ccw.count - sizeof(vdev->status);;

            ret = 0;

        }

        break;

    case CCW_CMD_WRITE_STATUS:

        if (check_len) {

            if (ccw.count != sizeof(status)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(status)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            status = address_space_ldub(&address_space_memory, ccw.cda,

                                        MEMTXATTRS_UNSPECIFIED, NULL);

            if (!(status & VIRTIO_CONFIG_S_DRIVER_OK)) {

                virtio_ccw_stop_ioeventfd(dev);

            }

            if (virtio_set_status(vdev, status) == 0) {

                if (vdev->status == 0) {

                    virtio_ccw_reset_virtio(dev, vdev);

                }

                if (status & VIRTIO_CONFIG_S_DRIVER_OK) {

                    virtio_ccw_start_ioeventfd(dev);

                }

                sch->curr_status.scsw.count = ccw.count - sizeof(status);

                ret = 0;

            } else {

                /* Trigger a command reject. */

                ret = -ENOSYS;

            }

        }

        break;

    case CCW_CMD_SET_IND:

        if (check_len) {

            if (ccw.count != sizeof(indicators)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(indicators)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (sch->thinint_active) {

            /* Trigger a command reject. */

            ret = -ENOSYS;

            break;

        }

        if (virtio_get_num_queues(vdev) > NR_CLASSIC_INDICATOR_BITS) {

            /* More queues than indicator bits --> trigger a reject */

            ret = -ENOSYS;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            indicators = address_space_ldq_be(&address_space_memory, ccw.cda,

                                              MEMTXATTRS_UNSPECIFIED, NULL);

            dev->indicators = get_indicator(indicators, sizeof(uint64_t));

            sch->curr_status.scsw.count = ccw.count - sizeof(indicators);

            ret = 0;

        }

        break;

    case CCW_CMD_SET_CONF_IND:

        if (check_len) {

            if (ccw.count != sizeof(indicators)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(indicators)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            indicators = address_space_ldq_be(&address_space_memory, ccw.cda,

                                              MEMTXATTRS_UNSPECIFIED, NULL);

            dev->indicators2 = get_indicator(indicators, sizeof(uint64_t));

            sch->curr_status.scsw.count = ccw.count - sizeof(indicators);

            ret = 0;

        }

        break;

    case CCW_CMD_READ_VQ_CONF:

        if (check_len) {

            if (ccw.count != sizeof(vq_config)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(vq_config)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

        } else {

            vq_config.index = address_space_lduw_be(&address_space_memory,

                                                    ccw.cda,

                                                    MEMTXATTRS_UNSPECIFIED,

                                                    NULL);

            if (vq_config.index >= VIRTIO_QUEUE_MAX) {

                ret = -EINVAL;

                break;

            }

            vq_config.num_max = virtio_queue_get_num(vdev,

                                                     vq_config.index);

            address_space_stw_be(&address_space_memory,

                                 ccw.cda + sizeof(vq_config.index),

                                 vq_config.num_max,

                                 MEMTXATTRS_UNSPECIFIED,

                                 NULL);

            sch->curr_status.scsw.count = ccw.count - sizeof(vq_config);

            ret = 0;

        }

        break;

    case CCW_CMD_SET_IND_ADAPTER:

        if (check_len) {

            if (ccw.count != sizeof(*thinint)) {

                ret = -EINVAL;

                break;

            }

        } else if (ccw.count < sizeof(*thinint)) {

            /* Can't execute command. */

            ret = -EINVAL;

            break;

        }

        len = sizeof(*thinint);

        hw_len = len;

        if (!ccw.cda) {

            ret = -EFAULT;

        } else if (dev->indicators && !sch->thinint_active) {

            /* Trigger a command reject. */

            ret = -ENOSYS;

        } else {

            thinint = cpu_physical_memory_map(ccw.cda, &hw_len, 0);

            if (!thinint) {

                ret = -EFAULT;

            } else {

                uint64_t ind_bit = ldq_be_p(&thinint->ind_bit);

                len = hw_len;

                dev->summary_indicator =

                    get_indicator(ldq_be_p(&thinint->summary_indicator),

                                  sizeof(uint8_t));

                dev->indicators =

                    get_indicator(ldq_be_p(&thinint->device_indicator),

                                  ind_bit / 8 + 1);

                dev->thinint_isc = thinint->isc;

                dev->routes.adapter.ind_offset = ind_bit;

                dev->routes.adapter.summary_offset = 7;

                cpu_physical_memory_unmap(thinint, hw_len, 0, hw_len);

                dev->routes.adapter.adapter_id = css_get_adapter_id(

                                                 CSS_IO_ADAPTER_VIRTIO,

                                                 dev->thinint_isc);

                sch->thinint_active = ((dev->indicators != NULL) &&

                                       (dev->summary_indicator != NULL));

                sch->curr_status.scsw.count = ccw.count - len;

                ret = 0;

            }

        }

        break;

    case CCW_CMD_SET_VIRTIO_REV:

        len = sizeof(revinfo);

        if (ccw.count < len) {

            ret = -EINVAL;

            break;

        }

        if (!ccw.cda) {

            ret = -EFAULT;

            break;

        }

        revinfo.revision =

            address_space_lduw_be(&address_space_memory, ccw.cda,

                                  MEMTXATTRS_UNSPECIFIED, NULL);

        revinfo.length =

            address_space_lduw_be(&address_space_memory,

                                  ccw.cda + sizeof(revinfo.revision),

                                  MEMTXATTRS_UNSPECIFIED, NULL);

        if (ccw.count < len + revinfo.length ||

            (check_len && ccw.count > len + revinfo.length)) {

            ret = -EINVAL;

            break;

        }

        /*

         * Once we start to support revisions with additional data, we'll

         * need to fetch it here. Nothing to do for now, though.

         */

        if (dev->revision >= 0 ||

            revinfo.revision > virtio_ccw_rev_max(dev) ||

            (dev->force_revision_1 && !revinfo.revision)) {

            ret = -ENOSYS;

            break;

        }

        ret = 0;

        dev->revision = revinfo.revision;

        break;

    default:

        ret = -ENOSYS;

        break;

    }

    return ret;

}


AioContext *aio_context_new(Error **errp)

{

    int ret;

    AioContext *ctx;

    ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));

    aio_context_setup(ctx);

    ret = event_notifier_init(&ctx->notifier, false);

    if (ret < 0) {

        error_setg_errno(errp, -ret, "Failed to initialize event notifier");

        goto fail;

    }

    g_source_set_can_recurse(&ctx->source, true);

    qemu_lockcnt_init(&ctx->list_lock);

    aio_set_event_notifier(ctx, &ctx->notifier,

                           false,

                           (EventNotifierHandler *)

                           event_notifier_dummy_cb,

                           event_notifier_poll);

#ifdef CONFIG_LINUX_AIO

    ctx->linux_aio = NULL;

#endif

    ctx->thread_pool = NULL;

    qemu_rec_mutex_init(&ctx->lock);

    timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);

    ctx->poll_ns = 0;

    ctx->poll_max_ns = 0;

    ctx->poll_grow = 0;

    ctx->poll_shrink = 0;

    return ctx;

fail:

    g_source_destroy(&ctx->source);

    return NULL;

}


static TCGArg do_constant_folding_2(int op, TCGArg x, TCGArg y)

{

    switch (op) {

    CASE_OP_32_64(add):

        return x + y;

    CASE_OP_32_64(sub):

        return x - y;

    CASE_OP_32_64(mul):

        return x * y;

    CASE_OP_32_64(and):

        return x & y;

    CASE_OP_32_64(or):

        return x | y;

    CASE_OP_32_64(xor):

        return x ^ y;

    case INDEX_op_shl_i32:

        return (uint32_t)x << (uint32_t)y;

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_shl_i64:

        return (uint64_t)x << (uint64_t)y;

#endif

    case INDEX_op_shr_i32:

        return (uint32_t)x >> (uint32_t)y;

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_shr_i64:

        return (uint64_t)x >> (uint64_t)y;

#endif

    case INDEX_op_sar_i32:

        return (int32_t)x >> (int32_t)y;

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_sar_i64:

        return (int64_t)x >> (int64_t)y;

#endif

#ifdef TCG_TARGET_HAS_rot_i32

    case INDEX_op_rotr_i32:

#if TCG_TARGET_REG_BITS == 64

        x &= 0xffffffff;

        y &= 0xffffffff;

#endif

        x = (x << (32 - y)) | (x >> y);

        return x;

#endif

#ifdef TCG_TARGET_HAS_rot_i64

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_rotr_i64:

        x = (x << (64 - y)) | (x >> y);

        return x;

#endif

#endif

#ifdef TCG_TARGET_HAS_rot_i32

    case INDEX_op_rotl_i32:

#if TCG_TARGET_REG_BITS == 64

        x &= 0xffffffff;

        y &= 0xffffffff;

#endif

        x = (x << y) | (x >> (32 - y));

        return x;

#endif

#ifdef TCG_TARGET_HAS_rot_i64

#if TCG_TARGET_REG_BITS == 64

    case INDEX_op_rotl_i64:

        x = (x << y) | (x >> (64 - y));

        return x;

#endif

#endif

#if defined(TCG_TARGET_HAS_not_i32) || defined(TCG_TARGET_HAS_not_i64)

#ifdef TCG_TARGET_HAS_not_i32

    case INDEX_op_not_i32:

#endif

#ifdef TCG_TARGET_HAS_not_i64

    case INDEX_op_not_i64:

#endif

        return ~x;

#endif

#if defined(TCG_TARGET_HAS_ext8s_i32) || defined(TCG_TARGET_HAS_ext8s_i64)

#ifdef TCG_TARGET_HAS_ext8s_i32

    case INDEX_op_ext8s_i32:

#endif

#ifdef TCG_TARGET_HAS_ext8s_i64

    case INDEX_op_ext8s_i64:

#endif

        return (int8_t)x;

#endif

#if defined(TCG_TARGET_HAS_ext16s_i32) || defined(TCG_TARGET_HAS_ext16s_i64)

#ifdef TCG_TARGET_HAS_ext16s_i32

    case INDEX_op_ext16s_i32:

#endif

#ifdef TCG_TARGET_HAS_ext16s_i64

    case INDEX_op_ext16s_i64:

#endif

        return (int16_t)x;

#endif

#if defined(TCG_TARGET_HAS_ext8u_i32) || defined(TCG_TARGET_HAS_ext8u_i64)

#ifdef TCG_TARGET_HAS_ext8u_i32

    case INDEX_op_ext8u_i32:

#endif

#ifdef TCG_TARGET_HAS_ext8u_i64

    case INDEX_op_ext8u_i64:

#endif

        return (uint8_t)x;

#endif

#if defined(TCG_TARGET_HAS_ext16u_i32) || defined(TCG_TARGET_HAS_ext16u_i64)

#ifdef TCG_TARGET_HAS_ext16u_i32

    case INDEX_op_ext16u_i32:

#endif

#ifdef TCG_TARGET_HAS_ext16u_i64

    case INDEX_op_ext16u_i64:

#endif

        return (uint16_t)x;

#endif

#if TCG_TARGET_REG_BITS == 64

#ifdef TCG_TARGET_HAS_ext32s_i64

    case INDEX_op_ext32s_i64:

        return (int32_t)x;

#endif

#ifdef TCG_TARGET_HAS_ext32u_i64

    case INDEX_op_ext32u_i64:

        return (uint32_t)x;

#endif

#endif

    default:

        fprintf(stderr,

                "Unrecognized operation %d in do_constant_folding.\n", op);

        tcg_abort();

    }

}


static int mpegts_raw_read_packet(AVFormatContext *s,

                                  AVPacket *pkt)

{

    MpegTSContext *ts = s->priv_data;

    int ret, i;

    int64_t pcr_h, next_pcr_h, pos;

    int pcr_l, next_pcr_l;

    uint8_t pcr_buf[12];

    if (av_new_packet(pkt, TS_PACKET_SIZE) < 0)

        return AVERROR(ENOMEM);

    pkt->pos= url_ftell(s->pb);

    ret = read_packet(s->pb, pkt->data, ts->raw_packet_size);

    if (ret < 0) {

        av_free_packet(pkt);

        return ret;

    }

    if (ts->mpeg2ts_compute_pcr) {

        /* compute exact PCR for each packet */

        if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) {

            /* we read the next PCR (XXX: optimize it by using a bigger buffer */

            pos = url_ftell(s->pb);

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

                url_fseek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET);

                get_buffer(s->pb, pcr_buf, 12);

                if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) {

                    /* XXX: not precise enough */

                    ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) /

                        (i + 1);

                    break;

                }

            }

            url_fseek(s->pb, pos, SEEK_SET);

            /* no next PCR found: we use previous increment */

            ts->cur_pcr = pcr_h * 300 + pcr_l;

        }

        pkt->pts = ts->cur_pcr;

        pkt->duration = ts->pcr_incr;

        ts->cur_pcr += ts->pcr_incr;

    }

    pkt->stream_index = 0;

    return 0;

}


static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,

                            void *value, size_t size, int flags)

{

    char buffer[PATH_MAX];

    if (strncmp(name, "user.virtfs.", 12) == 0) {

        /*

         * Don't allow fetch of user.virtfs namesapce

         * in case of mapped security

         */

        errno = EACCES;

        return -1;

    }

    return lsetxattr(rpath(ctx, path, buffer), name, value, size, flags);

}


static int openpic_init(SysBusDevice *dev)

{

    OpenPICState *opp = FROM_SYSBUS(typeof (*opp), dev);

    int i, j;

    MemReg list_le[] = {

        {"glb", &openpic_glb_ops_le, true,

                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},

        {"tmr", &openpic_tmr_ops_le, true,

                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},

        {"msi", &openpic_msi_ops_le, true,

                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},

        {"src", &openpic_src_ops_le, true,

                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},

        {"cpu", &openpic_cpu_ops_le, true,

                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},

    };

    MemReg list_be[] = {

        {"glb", &openpic_glb_ops_be, true,

                OPENPIC_GLB_REG_START, OPENPIC_GLB_REG_SIZE},

        {"tmr", &openpic_tmr_ops_be, true,

                OPENPIC_TMR_REG_START, OPENPIC_TMR_REG_SIZE},

        {"msi", &openpic_msi_ops_be, true,

                OPENPIC_MSI_REG_START, OPENPIC_MSI_REG_SIZE},

        {"src", &openpic_src_ops_be, true,

                OPENPIC_SRC_REG_START, OPENPIC_SRC_REG_SIZE},

        {"cpu", &openpic_cpu_ops_be, true,

                OPENPIC_CPU_REG_START, OPENPIC_CPU_REG_SIZE},

    };

    MemReg *list;

    switch (opp->model) {

    case OPENPIC_MODEL_FSL_MPIC_20:

    default:

        opp->flags |= OPENPIC_FLAG_IDR_CRIT;

        opp->nb_irqs = 80;

        opp->vid = VID_REVISION_1_2;

        opp->vir = VIR_GENERIC;

        opp->vector_mask = 0xFFFF;

        opp->tfrr_reset = 0;

        opp->ivpr_reset = IVPR_MASK_MASK;

        opp->idr_reset = 1 << 0;

        opp->max_irq = FSL_MPIC_20_MAX_IRQ;

        opp->irq_ipi0 = FSL_MPIC_20_IPI_IRQ;

        opp->irq_tim0 = FSL_MPIC_20_TMR_IRQ;

        opp->irq_msi = FSL_MPIC_20_MSI_IRQ;

        opp->brr1 = FSL_BRR1_IPID | FSL_BRR1_IPMJ | FSL_BRR1_IPMN;

        /* XXX really only available as of MPIC 4.0 */

        opp->mpic_mode_mask = GCR_MODE_PROXY;

        msi_supported = true;

        list = list_be;

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

            opp->src[i].level = false;

        }

        /* Internal interrupts, including message and MSI */

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

            opp->src[i].type = IRQ_TYPE_FSLINT;

            opp->src[i].level = true;

        }

        /* timers and IPIs */

        for (i = MAX_SRC; i < MAX_IRQ; i++) {

            opp->src[i].type = IRQ_TYPE_FSLSPECIAL;

            opp->src[i].level = false;

        }

        break;

    case OPENPIC_MODEL_RAVEN:

        opp->nb_irqs = RAVEN_MAX_EXT;

        opp->vid = VID_REVISION_1_3;

        opp->vir = VIR_GENERIC;

        opp->vector_mask = 0xFF;

        opp->tfrr_reset = 4160000;

        opp->ivpr_reset = IVPR_MASK_MASK | IVPR_MODE_MASK;

        opp->idr_reset = 0;

        opp->max_irq = RAVEN_MAX_IRQ;

        opp->irq_ipi0 = RAVEN_IPI_IRQ;

        opp->irq_tim0 = RAVEN_TMR_IRQ;

        opp->brr1 = -1;

        opp->mpic_mode_mask = GCR_MODE_MIXED;

        list = list_le;

        /* Don't map MSI region */

        list[2].map = false;

        /* Only UP supported today */

        if (opp->nb_cpus != 1) {

            return -EINVAL;

        }

        break;

    }

    memory_region_init(&opp->mem, "openpic", 0x40000);

    for (i = 0; i < ARRAY_SIZE(list_le); i++) {

        if (!list[i].map) {

            continue;

        }

        memory_region_init_io(&opp->sub_io_mem[i], list[i].ops, opp,

                              list[i].name, list[i].size);

        memory_region_add_subregion(&opp->mem, list[i].start_addr,

                                    &opp->sub_io_mem[i]);

    }

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

        opp->dst[i].irqs = g_new(qemu_irq, OPENPIC_OUTPUT_NB);

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

            sysbus_init_irq(dev, &opp->dst[i].irqs[j]);

        }

    }

    register_savevm(&opp->busdev.qdev, "openpic", 0, 2,

                    openpic_save, openpic_load, opp);

    sysbus_init_mmio(dev, &opp->mem);

    qdev_init_gpio_in(&dev->qdev, openpic_set_irq, opp->max_irq);

    return 0;

}


static void do_info_profile(Monitor *mon)

{

    int64_t total;

    total = qemu_time;

    if (total == 0)

        total = 1;

    monitor_printf(mon, "async time  %" PRId64 " (%0.3f)\n",

                   dev_time, dev_time / (double)ticks_per_sec);

    monitor_printf(mon, "qemu time   %" PRId64 " (%0.3f)\n",

                   qemu_time, qemu_time / (double)ticks_per_sec);

    monitor_printf(mon, "kqemu time  %" PRId64 " (%0.3f %0.1f%%) count=%"

                        PRId64 " int=%" PRId64 " excp=%" PRId64 " intr=%"

                        PRId64 "\n",

                   kqemu_time, kqemu_time / (double)ticks_per_sec,

                   kqemu_time / (double)total * 100.0,

                   kqemu_exec_count,

                   kqemu_ret_int_count,

                   kqemu_ret_excp_count,

                   kqemu_ret_intr_count);

    qemu_time = 0;

    kqemu_time = 0;

    kqemu_exec_count = 0;

    dev_time = 0;

    kqemu_ret_int_count = 0;

    kqemu_ret_excp_count = 0;

    kqemu_ret_intr_count = 0;

#ifdef CONFIG_KQEMU

    kqemu_record_dump();

#endif

}


void qemu_savevm_state_header(QEMUFile *f)

{

    trace_savevm_state_header();

    qemu_put_be32(f, QEMU_VM_FILE_MAGIC);

    qemu_put_be32(f, QEMU_VM_FILE_VERSION);

    if (migrate_get_current()->send_configuration ||

        enforce_config_section()) {

        qemu_put_byte(f, QEMU_VM_CONFIGURATION);

        vmstate_save_state(f, &vmstate_configuration, &savevm_state, 0);

    }

}


static void rtas_event_log_queue(int log_type, void *data)

{

    sPAPREventLogEntry *entry = g_new(sPAPREventLogEntry, 1);

    g_assert(data);

    entry->log_type = log_type;

    entry->data = data;

    QTAILQ_INSERT_TAIL(&spapr->pending_events, entry, next);

}


int avio_open2(AVIOContext **s, const char *filename, int flags,

               const AVIOInterruptCB *int_cb, AVDictionary **options)

{

    URLContext *h;

    int err;

    err = ffurl_open(&h, filename, flags, int_cb, options);

    if (err < 0)

        return err;

    err = ffio_fdopen(s, h);

    if (err < 0) {

        ffurl_close(h);

        return err;

    }

    return 0;

}


static void virtio_crypto_initfn(Object *obj)

{

    VirtIOCryptoPCI *dev = VIRTIO_CRYPTO_PCI(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),

                                TYPE_VIRTIO_CRYPTO);

    object_property_add_alias(obj, "cryptodev", OBJECT(&dev->vdev),

                              "cryptodev", &error_abort);

}


static void gen_spr_ne_601 (CPUPPCState *env)

{

    /* Exception processing */

    spr_register(env, SPR_DSISR, "DSISR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    spr_register(env, SPR_DAR, "DAR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_generic, &spr_write_generic,

                 0x00000000);

    /* Timer */

    spr_register(env, SPR_DECR, "DECR",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_decr, &spr_write_decr,

                 0x00000000);

    /* Memory management */

    spr_register(env, SPR_SDR1, "SDR1",

                 SPR_NOACCESS, SPR_NOACCESS,

                 &spr_read_sdr1, &spr_write_sdr1,

                 0x00000000);

}


static void grlib_irqmp_write(void *opaque, target_phys_addr_t addr,

                              uint64_t value, unsigned size)

{

    IRQMP      *irqmp = opaque;

    IRQMPState *state;

    assert(irqmp != NULL);

    state = irqmp->state;

    assert(state != NULL);

    addr &= 0xff;

    /* global registers */

    switch (addr) {

    case LEVEL_OFFSET:

        value &= 0xFFFF << 1; /* clean up the value */

        state->level = value;

        return;

    case PENDING_OFFSET:

        /* Read Only */

        return;

    case FORCE0_OFFSET:

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

        value &= 0xFFFE; /* clean up the value */

        state->force[0] = value;

        grlib_irqmp_check_irqs(irqmp->state);

        return;

    case CLEAR_OFFSET:

        value &= ~1; /* clean up the value */

        state->pending &= ~value;

        return;

    case MP_STATUS_OFFSET:

        /* Read Only (no SMP support) */

        return;

    case BROADCAST_OFFSET:

        value &= 0xFFFE; /* clean up the value */

        state->broadcast = value;

        return;

    default:

        break;

    }

    /* mask registers */

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

        int cpu = (addr - MASK_OFFSET) / 4;

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

        value &= ~1; /* clean up the value */

        state->mask[cpu] = value;

        grlib_irqmp_check_irqs(irqmp->state);

        return;

    }

    /* force registers */

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

        int cpu = (addr - FORCE_OFFSET) / 4;

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

        uint32_t force = value & 0xFFFE;

        uint32_t clear = (value >> 16) & 0xFFFE;

        uint32_t old   = state->force[cpu];

        state->force[cpu] = (old | force) & ~clear;

        grlib_irqmp_check_irqs(irqmp->state);

        return;

    }

    /* extended (not supported) */

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

        int cpu = (addr - EXTENDED_OFFSET) / 4;

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

        value &= 0xF; /* clean up the value */

        state->extended[cpu] = value;

        return;

    }

    trace_grlib_irqmp_writel_unknown(addr, value);

}


static void tss_load_seg(CPUX86State *env, int seg_reg, int selector)

{

    uint32_t e1, e2;

    int rpl, dpl, cpl;

    if ((selector & 0xfffc) != 0) {

        if (load_segment(env, &e1, &e2, selector) != 0) {

            raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

        }

        if (!(e2 & DESC_S_MASK)) {

            raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

        }

        rpl = selector & 3;

        dpl = (e2 >> DESC_DPL_SHIFT) & 3;

        cpl = env->hflags & HF_CPL_MASK;

        if (seg_reg == R_CS) {

            if (!(e2 & DESC_CS_MASK)) {

                raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

            }

            /* XXX: is it correct? */

            if (dpl != rpl) {

                raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

            }

            if ((e2 & DESC_C_MASK) && dpl > rpl) {

                raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

            }

        } else if (seg_reg == R_SS) {

            /* SS must be writable data */

            if ((e2 & DESC_CS_MASK) || !(e2 & DESC_W_MASK)) {

                raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

            }

            if (dpl != cpl || dpl != rpl) {

                raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

            }

        } else {

            /* not readable code */

            if ((e2 & DESC_CS_MASK) && !(e2 & DESC_R_MASK)) {

                raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

            }

            /* if data or non conforming code, checks the rights */

            if (((e2 >> DESC_TYPE_SHIFT) & 0xf) < 12) {

                if (dpl < cpl || dpl < rpl) {

                    raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

                }

            }

        }

        if (!(e2 & DESC_P_MASK)) {

            raise_exception_err(env, EXCP0B_NOSEG, selector & 0xfffc);

        }

        cpu_x86_load_seg_cache(env, seg_reg, selector,

                               get_seg_base(e1, e2),

                               get_seg_limit(e1, e2),

                               e2);

    } else {

        if (seg_reg == R_SS || seg_reg == R_CS) {

            raise_exception_err(env, EXCP0A_TSS, selector & 0xfffc);

        }

    }

}


static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms,

                                        int w, int h)

{

    FlipContext *flip = link->dst->priv;

    int i;

    AVFilterBufferRef *picref = avfilter_get_video_buffer(link->dst->outputs[0],

                                                       perms, w, h);

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

        int vsub = i == 1 || i == 2 ? flip->vsub : 0;

        if (picref->data[i]) {

            picref->data[i] += ((h >> vsub)-1) * picref->linesize[i];

            picref->linesize[i] = -picref->linesize[i];

        }

    }

    return picref;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);

    NVDIMMClass *nvc = NVDIMM_CLASS(oc);

    /* nvdimm hotplug has not been supported yet. */

    dc->hotpluggable = false;

    ddc->realize = nvdimm_realize;

    ddc->get_memory_region = nvdimm_get_memory_region;

    ddc->get_vmstate_memory_region = nvdimm_get_vmstate_memory_region;

    nvc->read_label_data = nvdimm_read_label_data;

    nvc->write_label_data = nvdimm_write_label_data;

}


QEMUFile *qemu_fopen_ops(void *opaque, const QEMUFileOps *ops)

{

    QEMUFile *f;

    f = g_malloc0(sizeof(QEMUFile));

    f->opaque = opaque;

    f->ops = ops;

    f->is_write = 0;

    return f;

}


QmpOutputVisitor *qmp_output_visitor_new(void)

{

    QmpOutputVisitor *v;

    v = g_malloc0(sizeof(*v));

    v->visitor.type = VISITOR_OUTPUT;

    v->visitor.start_struct = qmp_output_start_struct;

    v->visitor.end_struct = qmp_output_end_struct;

    v->visitor.start_list = qmp_output_start_list;

    v->visitor.next_list = qmp_output_next_list;

    v->visitor.end_list = qmp_output_end_list;

    v->visitor.type_int64 = qmp_output_type_int64;

    v->visitor.type_uint64 = qmp_output_type_uint64;

    v->visitor.type_bool = qmp_output_type_bool;

    v->visitor.type_str = qmp_output_type_str;

    v->visitor.type_number = qmp_output_type_number;

    v->visitor.type_any = qmp_output_type_any;

    v->visitor.type_null = qmp_output_type_null;

    v->visitor.free = qmp_output_free;

    QTAILQ_INIT(&v->stack);

    return v;

}


static void arm_cpu_do_interrupt_aarch32(CPUState *cs)

{

    ARMCPU *cpu = ARM_CPU(cs);

    CPUARMState *env = &cpu->env;

    uint32_t addr;

    uint32_t mask;

    int new_mode;

    uint32_t offset;

    uint32_t moe;

    /* If this is a debug exception we must update the DBGDSCR.MOE bits */

    switch (env->exception.syndrome >> ARM_EL_EC_SHIFT) {

    case EC_BREAKPOINT:

    case EC_BREAKPOINT_SAME_EL:

        moe = 1;

        break;

    case EC_WATCHPOINT:

    case EC_WATCHPOINT_SAME_EL:

        moe = 10;

        break;

    case EC_AA32_BKPT:

        moe = 3;

        break;

    case EC_VECTORCATCH:

        moe = 5;

        break;

    default:

        moe = 0;

        break;

    }

    if (moe) {

        env->cp15.mdscr_el1 = deposit64(env->cp15.mdscr_el1, 2, 4, moe);

    }

    /* TODO: Vectored interrupt controller.  */

    switch (cs->exception_index) {

    case EXCP_UDEF:

        new_mode = ARM_CPU_MODE_UND;

        addr = 0x04;

        mask = CPSR_I;

        if (env->thumb)

            offset = 2;

        else

            offset = 4;

        break;

    case EXCP_SWI:

        new_mode = ARM_CPU_MODE_SVC;

        addr = 0x08;

        mask = CPSR_I;

        /* The PC already points to the next instruction.  */

        offset = 0;

        break;

    case EXCP_BKPT:

        env->exception.fsr = 2;

        /* Fall through to prefetch abort.  */

    case EXCP_PREFETCH_ABORT:

        A32_BANKED_CURRENT_REG_SET(env, ifsr, env->exception.fsr);

        A32_BANKED_CURRENT_REG_SET(env, ifar, env->exception.vaddress);

        qemu_log_mask(CPU_LOG_INT, "...with IFSR 0x%x IFAR 0x%x\n",

                      env->exception.fsr, (uint32_t)env->exception.vaddress);

        new_mode = ARM_CPU_MODE_ABT;

        addr = 0x0c;

        mask = CPSR_A | CPSR_I;

        offset = 4;

        break;

    case EXCP_DATA_ABORT:

        A32_BANKED_CURRENT_REG_SET(env, dfsr, env->exception.fsr);

        A32_BANKED_CURRENT_REG_SET(env, dfar, env->exception.vaddress);

        qemu_log_mask(CPU_LOG_INT, "...with DFSR 0x%x DFAR 0x%x\n",

                      env->exception.fsr,

                      (uint32_t)env->exception.vaddress);

        new_mode = ARM_CPU_MODE_ABT;

        addr = 0x10;

        mask = CPSR_A | CPSR_I;

        offset = 8;

        break;

    case EXCP_IRQ:

        new_mode = ARM_CPU_MODE_IRQ;

        addr = 0x18;

        /* Disable IRQ and imprecise data aborts.  */

        mask = CPSR_A | CPSR_I;

        offset = 4;

        if (env->cp15.scr_el3 & SCR_IRQ) {

            /* IRQ routed to monitor mode */

            new_mode = ARM_CPU_MODE_MON;

            mask |= CPSR_F;

        }

        break;

    case EXCP_FIQ:

        new_mode = ARM_CPU_MODE_FIQ;

        addr = 0x1c;

        /* Disable FIQ, IRQ and imprecise data aborts.  */

        mask = CPSR_A | CPSR_I | CPSR_F;

        if (env->cp15.scr_el3 & SCR_FIQ) {

            /* FIQ routed to monitor mode */

            new_mode = ARM_CPU_MODE_MON;

        }

        offset = 4;

        break;

    case EXCP_SMC:

        new_mode = ARM_CPU_MODE_MON;

        addr = 0x08;

        mask = CPSR_A | CPSR_I | CPSR_F;

        offset = 0;

        break;

    default:

        cpu_abort(cs, "Unhandled exception 0x%x\n", cs->exception_index);

        return; /* Never happens.  Keep compiler happy.  */

    }

    if (new_mode == ARM_CPU_MODE_MON) {

        addr += env->cp15.mvbar;

    } else if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {

        /* High vectors. When enabled, base address cannot be remapped. */

        addr += 0xffff0000;

    } else {

        /* ARM v7 architectures provide a vector base address register to remap

         * the interrupt vector table.

         * This register is only followed in non-monitor mode, and is banked.

         * Note: only bits 31:5 are valid.

         */

        addr += A32_BANKED_CURRENT_REG_GET(env, vbar);

    }

    if ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_MON) {

        env->cp15.scr_el3 &= ~SCR_NS;

    }

    switch_mode (env, new_mode);

    /* For exceptions taken to AArch32 we must clear the SS bit in both

     * PSTATE and in the old-state value we save to SPSR_<mode>, so zero it now.

     */

    env->uncached_cpsr &= ~PSTATE_SS;

    env->spsr = cpsr_read(env);

    /* Clear IT bits.  */

    env->condexec_bits = 0;

    /* Switch to the new mode, and to the correct instruction set.  */

    env->uncached_cpsr = (env->uncached_cpsr & ~CPSR_M) | new_mode;

    /* Set new mode endianness */

    env->uncached_cpsr &= ~CPSR_E;

    if (env->cp15.sctlr_el[arm_current_el(env)] & SCTLR_EE) {

        env->uncached_cpsr |= ~CPSR_E;

    }

    env->daif |= mask;

    /* this is a lie, as the was no c1_sys on V4T/V5, but who cares

     * and we should just guard the thumb mode on V4 */

    if (arm_feature(env, ARM_FEATURE_V4T)) {

        env->thumb = (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_TE) != 0;

    }

    env->regs[14] = env->regs[15] + offset;

    env->regs[15] = addr;

}


static void simple_list(void)

{

    int i;

    struct {

        const char *encoded;

        LiteralQObject decoded;

    } test_cases[] = {

        {

            .encoded = "[43,42]",

            .decoded = QLIT_QLIST(((LiteralQObject[]){

                        QLIT_QINT(43),

                        QLIT_QINT(42),

                        { }

                    })),

        },

        {

            .encoded = "[43]",

            .decoded = QLIT_QLIST(((LiteralQObject[]){

                        QLIT_QINT(43),

                        { }

                    })),

        },

        {

            .encoded = "[]",

            .decoded = QLIT_QLIST(((LiteralQObject[]){

                        { }

                    })),

        },

        {

            .encoded = "[{}]",

            .decoded = QLIT_QLIST(((LiteralQObject[]){

                        QLIT_QDICT(((LiteralQDictEntry[]){

                                    {},

                                        })),

                        {},

                            })),

        },

        { }

    };

    for (i = 0; test_cases[i].encoded; i++) {

        QObject *obj;

        QString *str;

        obj = qobject_from_json(test_cases[i].encoded);

        g_assert(obj != NULL);

        g_assert(qobject_type(obj) == QTYPE_QLIST);

        g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);

        str = qobject_to_json(obj);

        qobject_decref(obj);

        obj = qobject_from_json(qstring_get_str(str));

        g_assert(obj != NULL);

        g_assert(qobject_type(obj) == QTYPE_QLIST);

        g_assert(compare_litqobj_to_qobj(&test_cases[i].decoded, obj) == 1);

        qobject_decref(obj);

        QDECREF(str);

    }

}


static uint64_t m5208_timer_read(void *opaque, target_phys_addr_t addr,

                                 unsigned size)

{

    m5208_timer_state *s = (m5208_timer_state *)opaque;

    switch (addr) {

    case 0:

        return s->pcsr;

    case 2:

        return s->pmr;

    case 4:

        return ptimer_get_count(s->timer);

    default:

        hw_error("m5208_timer_read: Bad offset 0x%x\n", (int)addr);

        return 0;

    }

}


static inline void gen_cmps(DisasContext *s, int ot)

{

    gen_string_movl_A0_ESI(s);

    gen_op_ld_T0_A0(ot + s->mem_index);

    gen_string_movl_A0_EDI(s);

    gen_op_ld_T1_A0(ot + s->mem_index);

    gen_op_cmpl_T0_T1_cc();

    gen_op_movl_T0_Dshift[ot]();

#ifdef TARGET_X86_64

    if (s->aflag == 2) {

        gen_op_addq_ESI_T0();

        gen_op_addq_EDI_T0();

    } else

#endif

    if (s->aflag) {

        gen_op_addl_ESI_T0();

        gen_op_addl_EDI_T0();

    } else {

        gen_op_addw_ESI_T0();

        gen_op_addw_EDI_T0();

    }

}


static int set_pix_fmt(AVCodecContext *avctx, vpx_codec_caps_t codec_caps,

                       struct vpx_codec_enc_cfg *enccfg, vpx_codec_flags_t *flags,

                       vpx_img_fmt_t *img_fmt)

{

    VPxContext av_unused *ctx = avctx->priv_data;

#ifdef VPX_IMG_FMT_HIGHBITDEPTH

    enccfg->g_bit_depth = enccfg->g_input_bit_depth = 8;

#endif

    switch (avctx->pix_fmt) {

    case AV_PIX_FMT_YUV420P:

    case AV_PIX_FMT_YUVA420P:

        enccfg->g_profile = 0;

        *img_fmt = VPX_IMG_FMT_I420;

        return 0;

    case AV_PIX_FMT_YUV422P:

        enccfg->g_profile = 1;

        *img_fmt = VPX_IMG_FMT_I422;

        return 0;

#if VPX_IMAGE_ABI_VERSION >= 3

    case AV_PIX_FMT_YUV440P:

        enccfg->g_profile = 1;

        *img_fmt = VPX_IMG_FMT_I440;

        return 0;

    case AV_PIX_FMT_GBRP:

        ctx->vpx_cs = VPX_CS_SRGB;

#endif

    case AV_PIX_FMT_YUV444P:

        enccfg->g_profile = 1;

        *img_fmt = VPX_IMG_FMT_I444;

        return 0;

#ifdef VPX_IMG_FMT_HIGHBITDEPTH

    case AV_PIX_FMT_YUV420P10:

    case AV_PIX_FMT_YUV420P12:

        if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) {

            enccfg->g_bit_depth = enccfg->g_input_bit_depth =

                avctx->pix_fmt == AV_PIX_FMT_YUV420P10 ? 10 : 12;

            enccfg->g_profile = 2;

            *img_fmt = VPX_IMG_FMT_I42016;

            *flags |= VPX_CODEC_USE_HIGHBITDEPTH;

            return 0;

        }

        break;

    case AV_PIX_FMT_YUV422P10:

    case AV_PIX_FMT_YUV422P12:

        if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) {

            enccfg->g_bit_depth = enccfg->g_input_bit_depth =

                avctx->pix_fmt == AV_PIX_FMT_YUV422P10 ? 10 : 12;

            enccfg->g_profile = 3;

            *img_fmt = VPX_IMG_FMT_I42216;

            *flags |= VPX_CODEC_USE_HIGHBITDEPTH;

            return 0;

        }

        break;

#if VPX_IMAGE_ABI_VERSION >= 3

    case AV_PIX_FMT_YUV440P10:

    case AV_PIX_FMT_YUV440P12:

        if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) {

            enccfg->g_bit_depth = enccfg->g_input_bit_depth =

                avctx->pix_fmt == AV_PIX_FMT_YUV440P10 ? 10 : 12;

            enccfg->g_profile = 3;

            *img_fmt = VPX_IMG_FMT_I44016;

            *flags |= VPX_CODEC_USE_HIGHBITDEPTH;

            return 0;

        }

        break;

    case AV_PIX_FMT_GBRP10:

    case AV_PIX_FMT_GBRP12:

        ctx->vpx_cs = VPX_CS_SRGB;

#endif

    case AV_PIX_FMT_YUV444P10:

    case AV_PIX_FMT_YUV444P12:

        if (codec_caps & VPX_CODEC_CAP_HIGHBITDEPTH) {

            enccfg->g_bit_depth = enccfg->g_input_bit_depth =

                avctx->pix_fmt == AV_PIX_FMT_YUV444P10 ||

                avctx->pix_fmt == AV_PIX_FMT_GBRP10 ? 10 : 12;

            enccfg->g_profile = 3;

            *img_fmt = VPX_IMG_FMT_I44416;

            *flags |= VPX_CODEC_USE_HIGHBITDEPTH;

            return 0;

        }

        break;

#endif

    default:

        break;

    }

    av_log(avctx, AV_LOG_ERROR, "Unsupported pixel format.\n");

    return AVERROR_INVALIDDATA;

}


static CURLState *curl_init_state(BlockDriverState *bs, BDRVCURLState *s)

{

    CURLState *state = NULL;

    int i, j;

    do {

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

            for (j=0; j<CURL_NUM_ACB; j++)

                if (s->states[i].acb[j])

                    continue;

            if (s->states[i].in_use)

                continue;

            state = &s->states[i];

            state->in_use = 1;

            break;

        }

        if (!state) {

            aio_poll(bdrv_get_aio_context(bs), true);

        }

    } while(!state);

    if (!state->curl) {

        state->curl = curl_easy_init();

        if (!state->curl) {

            return NULL;

        }

        curl_easy_setopt(state->curl, CURLOPT_URL, s->url);

        curl_easy_setopt(state->curl, CURLOPT_SSL_VERIFYPEER,

                         (long) s->sslverify);

        if (s->cookie) {

            curl_easy_setopt(state->curl, CURLOPT_COOKIE, s->cookie);

        }

        curl_easy_setopt(state->curl, CURLOPT_TIMEOUT, s->timeout);

        curl_easy_setopt(state->curl, CURLOPT_WRITEFUNCTION,

                         (void *)curl_read_cb);

        curl_easy_setopt(state->curl, CURLOPT_WRITEDATA, (void *)state);

        curl_easy_setopt(state->curl, CURLOPT_PRIVATE, (void *)state);

        curl_easy_setopt(state->curl, CURLOPT_AUTOREFERER, 1);

        curl_easy_setopt(state->curl, CURLOPT_FOLLOWLOCATION, 1);

        curl_easy_setopt(state->curl, CURLOPT_NOSIGNAL, 1);

        curl_easy_setopt(state->curl, CURLOPT_ERRORBUFFER, state->errmsg);

        curl_easy_setopt(state->curl, CURLOPT_FAILONERROR, 1);

        /* Restrict supported protocols to avoid security issues in the more

         * obscure protocols.  For example, do not allow POP3/SMTP/IMAP see

         * CVE-2013-0249.

         *

         * Restricting protocols is only supported from 7.19.4 upwards.

         */

#if LIBCURL_VERSION_NUM >= 0x071304

        curl_easy_setopt(state->curl, CURLOPT_PROTOCOLS, PROTOCOLS);

        curl_easy_setopt(state->curl, CURLOPT_REDIR_PROTOCOLS, PROTOCOLS);

#endif

#ifdef DEBUG_VERBOSE

        curl_easy_setopt(state->curl, CURLOPT_VERBOSE, 1);

#endif

    }

    state->s = s;

    return state;

}


static bool elf_check_ehdr(struct elfhdr *ehdr)

{

    return (elf_check_arch(ehdr->e_machine)

            && ehdr->e_ehsize == sizeof(struct elfhdr)

            && ehdr->e_phentsize == sizeof(struct elf_phdr)

            && ehdr->e_shentsize == sizeof(struct elf_shdr)

            && (ehdr->e_type == ET_EXEC || ehdr->e_type == ET_DYN));

}


static void tcg_out_dat_rIN(TCGContext *s, int cond, int opc, int opneg,

                            TCGArg dst, TCGArg lhs, TCGArg rhs,

                            bool rhs_is_const)

{

    /* Emit either the reg,imm or reg,reg form of a data-processing insn.

     * rhs must satisfy the "rIN" constraint.

     */

    if (rhs_is_const) {

        int rot = encode_imm(rhs);

        if (rot < 0) {

            rhs = -rhs;

            rot = encode_imm(rhs);

            assert(rot >= 0);

            opc = opneg;

        }

        tcg_out_dat_imm(s, cond, opc, dst, lhs, rotl(rhs, rot) | (rot << 7));

    } else {

        tcg_out_dat_reg(s, cond, opc, dst, lhs, rhs, SHIFT_IMM_LSL(0));

    }

}


static void add_completion(const char *str)

{

    if (nb_completions < NB_COMPLETIONS_MAX) {

        completions[nb_completions++] = qemu_strdup(str);

    }

}


static void raw_lock_medium(BlockDriverState *bs, bool locked)

{

    bdrv_lock_medium(bs->file->bs, locked);

}


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

{

    struct xlx_pic *p = opaque;

    if (!(p->regs[R_MER] & 2)) {

        qemu_irq_lower(p->parent_irq);

        return;

    }

    /* edge triggered interrupt */

    if (p->c_kind_of_intr & (1 << irq) && p->regs[R_MER] & 2) {

        p->regs[R_ISR] |= (level << irq);

    }

    p->irq_pin_state &= ~(1 << irq);

    p->irq_pin_state |= level << irq;

    update_irq(p);

}


void net_slirp_smb(const char *exported_dir)

{

    if (slirp_smb_export) {

        fprintf(stderr, "-smb given twice\n");

        exit(1);

    }

    slirp_smb_export = exported_dir;

    if (slirp_inited) {

        slirp_smb(exported_dir);

    }

}