void qmp_block_commit(const char *device,

                      bool has_base, const char *base,

                      bool has_top, const char *top,

                      bool has_backing_file, const char *backing_file,

                      bool has_speed, int64_t speed,

                      Error **errp)

{

    BlockDriverState *bs;

    BlockDriverState *base_bs, *top_bs;

    AioContext *aio_context;

    Error *local_err = NULL;

    /* This will be part of the QMP command, if/when the

     * BlockdevOnError change for blkmirror makes it in

     */

    BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT;

    if (!has_speed) {

        speed = 0;

    }

    /* Important Note:

     *  libvirt relies on the DeviceNotFound error class in order to probe for

     *  live commit feature versions; for this to work, we must make sure to

     *  perform the device lookup before any generic errors that may occur in a

     *  scenario in which all optional arguments are omitted. */

    bs = bdrv_find(device);

    if (!bs) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, device);

        return;

    }

    aio_context = bdrv_get_aio_context(bs);

    aio_context_acquire(aio_context);

    /* drain all i/o before commits */

    bdrv_drain_all();

    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_COMMIT, errp)) {

        goto out;

    }

    /* default top_bs is the active layer */

    top_bs = bs;

    if (has_top && top) {

        if (strcmp(bs->filename, top) != 0) {

            top_bs = bdrv_find_backing_image(bs, top);

        }

    }

    if (top_bs == NULL) {

        error_setg(errp, "Top image file %s not found", top ? top : "NULL");

        goto out;

    }

    assert(bdrv_get_aio_context(top_bs) == aio_context);

    if (has_base && base) {

        base_bs = bdrv_find_backing_image(top_bs, base);

    } else {

        base_bs = bdrv_find_base(top_bs);

    }

    if (base_bs == NULL) {

        error_set(errp, QERR_BASE_NOT_FOUND, base ? base : "NULL");

        goto out;

    }

    assert(bdrv_get_aio_context(base_bs) == aio_context);

    /* Do not allow attempts to commit an image into itself */

    if (top_bs == base_bs) {

        error_setg(errp, "cannot commit an image into itself");

        goto out;

    }

    if (top_bs == bs) {

        if (has_backing_file) {

            error_setg(errp, "'backing-file' specified,"

                             " but 'top' is the active layer");

            goto out;

        }

        commit_active_start(bs, base_bs, speed, on_error, block_job_cb,

                            bs, &local_err);

    } else {

        commit_start(bs, base_bs, top_bs, speed, on_error, block_job_cb, bs,

                     has_backing_file ? backing_file : NULL, &local_err);

    }

    if (local_err != NULL) {

        error_propagate(errp, local_err);

        goto out;

    }

out:

    aio_context_release(aio_context);

}


static target_ulong compute_tlbie_rb(target_ulong v, target_ulong r,

                                     target_ulong pte_index)

{

    target_ulong rb, va_low;

    rb = (v & ~0x7fULL) << 16; /* AVA field */

    va_low = pte_index >> 3;

    if (v & HPTE64_V_SECONDARY) {

        va_low = ~va_low;

    }

    /* xor vsid from AVA */

    if (!(v & HPTE64_V_1TB_SEG)) {

        va_low ^= v >> 12;

    } else {

        va_low ^= v >> 24;

    }

    va_low &= 0x7ff;

    if (v & HPTE64_V_LARGE) {

        rb |= 1;                         /* L field */

#if 0 /* Disable that P7 specific bit for now */

        if (r & 0xff000) {

            /* non-16MB large page, must be 64k */

            /* (masks depend on page size) */

            rb |= 0x1000;                /* page encoding in LP field */

            rb |= (va_low & 0x7f) << 16; /* 7b of VA in AVA/LP field */

            rb |= (va_low & 0xfe);       /* AVAL field */

        }

#endif

    } else {

        /* 4kB page */

        rb |= (va_low & 0x7ff) << 12;   /* remaining 11b of AVA */

    }

    rb |= (v >> 54) & 0x300;            /* B field */

    return rb;

}


static void toright(unsigned char *dst[3], unsigned char *src[3],

                    int dststride[3], int srcstride[3],

                    int w, int h, struct vf_priv_s* p)

{

        int k;

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

                unsigned char* fromL = src[k];

                unsigned char* fromR = src[k];

                unsigned char* to = dst[k];

                int src = srcstride[k];

                int dst = dststride[k];

                int ss;

                unsigned int dd;

                int i;

                if (k > 0) {

                        i = h / 4 - p->skipline / 2;

                        ss = src * (h / 4 + p->skipline / 2);

                        dd = w / 4;

                } else {

                        i = h / 2 - p->skipline;

                        ss = src * (h / 2 + p->skipline);

                        dd = w / 2;

                }

                fromR += ss;

                for ( ; i > 0; i--) {

                        int j;

                        unsigned char* t = to;

                        unsigned char* sL = fromL;

                        unsigned char* sR = fromR;

                        if (p->scalew == 1) {

                                for (j = dd; j > 0; j--) {

                                        *t++ = (sL[0] + sL[1]) / 2;

                                        sL+=2;

                                }

                                for (j = dd ; j > 0; j--) {

                                        *t++ = (sR[0] + sR[1]) / 2;

                                        sR+=2;

                                }

                        } else {

                                for (j = dd * 2 ; j > 0; j--)

                                        *t++ = *sL++;

                                for (j = dd * 2 ; j > 0; j--)

                                        *t++ = *sR++;

                        }

                        if (p->scaleh == 1) {

                                fast_memcpy(to + dst, to, dst);

                                to += dst;

                        }

                        to += dst;

                        fromL += src;

                        fromR += src;

                }

                //printf("K %d  %d   %d   %d  %d \n", k, w, h,  src, dst);

        }

}


static int xan_huffman_decode(uint8_t *dest, int dest_len,

                              const uint8_t *src, int src_len)

{

    uint8_t byte = *src++;

    uint8_t ival = byte + 0x16;

    const uint8_t * ptr = src + byte*2;

    int ptr_len = src_len - 1 - byte*2;

    uint8_t val = ival;

    uint8_t *dest_end = dest + dest_len;

    uint8_t *dest_start = dest;

    int ret;

    GetBitContext gb;

    if ((ret = init_get_bits8(&gb, ptr, ptr_len)) < 0)

        return ret;

    while (val != 0x16) {

        unsigned idx = val - 0x17 + get_bits1(&gb) * byte;

        if (idx >= 2 * byte)

            return AVERROR_INVALIDDATA;

        val = src[idx];

        if (val < 0x16) {

            if (dest >= dest_end)

                return dest_len;

            *dest++ = val;

            val = ival;

        }

    }

    return dest - dest_start;

}


static int ram_load(QEMUFile *f, void *opaque, int version_id)

{

    int flags = 0, ret = 0, invalid_flags = 0;

    static uint64_t seq_iter;

    int len = 0;

    /*

     * If system is running in postcopy mode, page inserts to host memory must

     * be atomic

     */

    bool postcopy_running = postcopy_state_get() >= POSTCOPY_INCOMING_LISTENING;

    /* ADVISE is earlier, it shows the source has the postcopy capability on */

    bool postcopy_advised = postcopy_state_get() >= POSTCOPY_INCOMING_ADVISE;

    seq_iter++;

    if (version_id != 4) {

        ret = -EINVAL;

    }

    if (!migrate_use_compression()) {

        invalid_flags |= RAM_SAVE_FLAG_COMPRESS_PAGE;

    }

    /* This RCU critical section can be very long running.

     * When RCU reclaims in the code start to become numerous,

     * it will be necessary to reduce the granularity of this

     * critical section.

     */

    rcu_read_lock();

    if (postcopy_running) {

        ret = ram_load_postcopy(f);

    }

    while (!postcopy_running && !ret && !(flags & RAM_SAVE_FLAG_EOS)) {

        ram_addr_t addr, total_ram_bytes;

        void *host = NULL;

        uint8_t ch;

        addr = qemu_get_be64(f);

        flags = addr & ~TARGET_PAGE_MASK;

        addr &= TARGET_PAGE_MASK;

        if (flags & invalid_flags) {

            if (flags & invalid_flags & RAM_SAVE_FLAG_COMPRESS_PAGE) {

                error_report("Received an unexpected compressed page");

            }

            ret = -EINVAL;

            break;

        }

        if (flags & (RAM_SAVE_FLAG_ZERO | RAM_SAVE_FLAG_PAGE |

                     RAM_SAVE_FLAG_COMPRESS_PAGE | RAM_SAVE_FLAG_XBZRLE)) {

            RAMBlock *block = ram_block_from_stream(f, flags);

            host = host_from_ram_block_offset(block, addr);

            if (!host) {

                error_report("Illegal RAM offset " RAM_ADDR_FMT, addr);

                ret = -EINVAL;

                break;

            }

            ramblock_recv_bitmap_set(block, host);

            trace_ram_load_loop(block->idstr, (uint64_t)addr, flags, host);

        }

        switch (flags & ~RAM_SAVE_FLAG_CONTINUE) {

        case RAM_SAVE_FLAG_MEM_SIZE:

            /* Synchronize RAM block list */

            total_ram_bytes = addr;

            while (!ret && total_ram_bytes) {

                RAMBlock *block;

                char id[256];

                ram_addr_t length;

                len = qemu_get_byte(f);

                qemu_get_buffer(f, (uint8_t *)id, len);

                id[len] = 0;

                length = qemu_get_be64(f);

                block = qemu_ram_block_by_name(id);

                if (block) {

                    if (length != block->used_length) {

                        Error *local_err = NULL;

                        ret = qemu_ram_resize(block, length,

                                              &local_err);

                        if (local_err) {

                            error_report_err(local_err);

                        }

                    }

                    /* For postcopy we need to check hugepage sizes match */

                    if (postcopy_advised &&

                        block->page_size != qemu_host_page_size) {

                        uint64_t remote_page_size = qemu_get_be64(f);

                        if (remote_page_size != block->page_size) {

                            error_report("Mismatched RAM page size %s "

                                         "(local) %zd != %" PRId64,

                                         id, block->page_size,

                                         remote_page_size);

                            ret = -EINVAL;

                        }

                    }

                    ram_control_load_hook(f, RAM_CONTROL_BLOCK_REG,

                                          block->idstr);

                } else {

                    error_report("Unknown ramblock \"%s\", cannot "

                                 "accept migration", id);

                    ret = -EINVAL;

                }

                total_ram_bytes -= length;

            }

            break;

        case RAM_SAVE_FLAG_ZERO:

            ch = qemu_get_byte(f);

            ram_handle_compressed(host, ch, TARGET_PAGE_SIZE);

            break;

        case RAM_SAVE_FLAG_PAGE:

            qemu_get_buffer(f, host, TARGET_PAGE_SIZE);

            break;

        case RAM_SAVE_FLAG_COMPRESS_PAGE:

            len = qemu_get_be32(f);

            if (len < 0 || len > compressBound(TARGET_PAGE_SIZE)) {

                error_report("Invalid compressed data length: %d", len);

                ret = -EINVAL;

                break;

            }

            decompress_data_with_multi_threads(f, host, len);

            break;

        case RAM_SAVE_FLAG_XBZRLE:

            if (load_xbzrle(f, addr, host) < 0) {

                error_report("Failed to decompress XBZRLE page at "

                             RAM_ADDR_FMT, addr);

                ret = -EINVAL;

                break;

            }

            break;

        case RAM_SAVE_FLAG_EOS:

            /* normal exit */

            break;

        default:

            if (flags & RAM_SAVE_FLAG_HOOK) {

                ram_control_load_hook(f, RAM_CONTROL_HOOK, NULL);

            } else {

                error_report("Unknown combination of migration flags: %#x",

                             flags);

                ret = -EINVAL;

            }

        }

        if (!ret) {

            ret = qemu_file_get_error(f);

        }

    }

    wait_for_decompress_done();

    rcu_read_unlock();

    trace_ram_load_complete(ret, seq_iter);

    return ret;

}


static int tak_decode_frame(AVCodecContext *avctx, void *data,

                            int *got_frame_ptr, AVPacket *pkt)

{

    TAKDecContext *s  = avctx->priv_data;

    AVFrame *frame    = data;

    ThreadFrame tframe = { .f = data };

    GetBitContext *gb = &s->gb;

    int chan, i, ret, hsize;

    if (pkt->size < TAK_MIN_FRAME_HEADER_BYTES)

        return AVERROR_INVALIDDATA;

    if ((ret = init_get_bits8(gb, pkt->data, pkt->size)) < 0)

        return ret;

    if ((ret = ff_tak_decode_frame_header(avctx, gb, &s->ti, 0)) < 0)

        return ret;

    if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_COMPLIANT)) {

        hsize = get_bits_count(gb) / 8;

        if (ff_tak_check_crc(pkt->data, hsize)) {

            av_log(avctx, AV_LOG_ERROR, "CRC error\n");

            if (avctx->err_recognition & AV_EF_EXPLODE)

                return AVERROR_INVALIDDATA;

        }

    }

    if (s->ti.codec != TAK_CODEC_MONO_STEREO &&

        s->ti.codec != TAK_CODEC_MULTICHANNEL) {

        av_log(avctx, AV_LOG_ERROR, "unsupported codec: %d\n", s->ti.codec);

        return AVERROR_PATCHWELCOME;

    }

    if (s->ti.data_type) {

        av_log(avctx, AV_LOG_ERROR,

               "unsupported data type: %d\n", s->ti.data_type);

        return AVERROR_INVALIDDATA;

    }

    if (s->ti.codec == TAK_CODEC_MONO_STEREO && s->ti.channels > 2) {

        av_log(avctx, AV_LOG_ERROR,

               "invalid number of channels: %d\n", s->ti.channels);

        return AVERROR_INVALIDDATA;

    }

    if (s->ti.channels > 6) {

        av_log(avctx, AV_LOG_ERROR,

               "unsupported number of channels: %d\n", s->ti.channels);

        return AVERROR_INVALIDDATA;

    }

    if (s->ti.frame_samples <= 0) {

        av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of samples\n");

        return AVERROR_INVALIDDATA;

    }

    if (s->ti.bps != avctx->bits_per_raw_sample) {

        avctx->bits_per_raw_sample = s->ti.bps;

        if ((ret = set_bps_params(avctx)) < 0)

            return ret;

    }

    if (s->ti.sample_rate != avctx->sample_rate) {

        avctx->sample_rate = s->ti.sample_rate;

        set_sample_rate_params(avctx);

    }

    if (s->ti.ch_layout)

        avctx->channel_layout = s->ti.ch_layout;

    avctx->channels = s->ti.channels;

    s->nb_samples = s->ti.last_frame_samples ? s->ti.last_frame_samples

                                             : s->ti.frame_samples;

    frame->nb_samples = s->nb_samples;

    if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0)

        return ret;

    ff_thread_finish_setup(avctx);

    if (avctx->bits_per_raw_sample <= 16) {

        int buf_size = av_samples_get_buffer_size(NULL, avctx->channels,

                                                  s->nb_samples,

                                                  AV_SAMPLE_FMT_S32P, 0);

        av_fast_malloc(&s->decode_buffer, &s->decode_buffer_size, buf_size);

        if (!s->decode_buffer)

            return AVERROR(ENOMEM);

        ret = av_samples_fill_arrays((uint8_t **)s->decoded, NULL,

                                     s->decode_buffer, avctx->channels,

                                     s->nb_samples, AV_SAMPLE_FMT_S32P, 0);

        if (ret < 0)

            return ret;

    } else {

        for (chan = 0; chan < avctx->channels; chan++)

            s->decoded[chan] = (int32_t *)frame->extended_data[chan];

    }

    if (s->nb_samples < 16) {

        for (chan = 0; chan < avctx->channels; chan++) {

            int32_t *decoded = s->decoded[chan];

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

                decoded[i] = get_sbits(gb, avctx->bits_per_raw_sample);

        }

    } else {

        if (s->ti.codec == TAK_CODEC_MONO_STEREO) {

            for (chan = 0; chan < avctx->channels; chan++)

                if (ret = decode_channel(s, chan))

                    return ret;

            if (avctx->channels == 2) {

                s->nb_subframes = get_bits(gb, 1) + 1;

                if (s->nb_subframes > 1) {

                    s->subframe_len[1] = get_bits(gb, 6);

                }

                s->dmode = get_bits(gb, 3);

                if (ret = decorrelate(s, 0, 1, s->nb_samples - 1))

                    return ret;

            }

        } else if (s->ti.codec == TAK_CODEC_MULTICHANNEL) {

            if (get_bits1(gb)) {

                int ch_mask = 0;

                chan = get_bits(gb, 4) + 1;

                if (chan > avctx->channels)

                    return AVERROR_INVALIDDATA;

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

                    int nbit = get_bits(gb, 4);

                    if (nbit >= avctx->channels)

                        return AVERROR_INVALIDDATA;

                    if (ch_mask & 1 << nbit)

                        return AVERROR_INVALIDDATA;

                    s->mcdparams[i].present = get_bits1(gb);

                    if (s->mcdparams[i].present) {

                        s->mcdparams[i].index = get_bits(gb, 2);

                        s->mcdparams[i].chan2 = get_bits(gb, 4);

                        if (s->mcdparams[i].index == 1) {

                            if ((nbit == s->mcdparams[i].chan2) ||

                                (ch_mask & 1 << s->mcdparams[i].chan2))

                                return AVERROR_INVALIDDATA;

                            ch_mask |= 1 << s->mcdparams[i].chan2;

                        } else if (!(ch_mask & 1 << s->mcdparams[i].chan2)) {

                            return AVERROR_INVALIDDATA;

                        }

                    }

                    s->mcdparams[i].chan1 = nbit;

                    ch_mask |= 1 << nbit;

                }

            } else {

                chan = avctx->channels;

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

                    s->mcdparams[i].present = 0;

                    s->mcdparams[i].chan1   = i;

                }

            }

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

                if (s->mcdparams[i].present && s->mcdparams[i].index == 1)

                    if (ret = decode_channel(s, s->mcdparams[i].chan2))

                        return ret;

                if (ret = decode_channel(s, s->mcdparams[i].chan1))

                    return ret;

                if (s->mcdparams[i].present) {

                    s->dmode = mc_dmodes[s->mcdparams[i].index];

                    if (ret = decorrelate(s,

                                          s->mcdparams[i].chan2,

                                          s->mcdparams[i].chan1,

                                          s->nb_samples - 1))

                        return ret;

                }

            }

        }

        for (chan = 0; chan < avctx->channels; chan++) {

            int32_t *decoded = s->decoded[chan];

            if (s->lpc_mode[chan])

                decode_lpc(decoded, s->lpc_mode[chan], s->nb_samples);

            if (s->sample_shift[chan] > 0)

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

                    decoded[i] <<= s->sample_shift[chan];

        }

    }

    align_get_bits(gb);

    skip_bits(gb, 24);

    if (get_bits_left(gb) < 0)

        av_log(avctx, AV_LOG_DEBUG, "overread\n");

    else if (get_bits_left(gb) > 0)

        av_log(avctx, AV_LOG_DEBUG, "underread\n");

    if (avctx->err_recognition & (AV_EF_CRCCHECK | AV_EF_COMPLIANT)) {

        if (ff_tak_check_crc(pkt->data + hsize,

                             get_bits_count(gb) / 8 - hsize)) {

            av_log(avctx, AV_LOG_ERROR, "CRC error\n");

            if (avctx->err_recognition & AV_EF_EXPLODE)

                return AVERROR_INVALIDDATA;

        }

    }

    /* convert to output buffer */

    switch (avctx->sample_fmt) {

    case AV_SAMPLE_FMT_U8P:

        for (chan = 0; chan < avctx->channels; chan++) {

            uint8_t *samples = (uint8_t *)frame->extended_data[chan];

            int32_t *decoded = s->decoded[chan];

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

                samples[i] = decoded[i] + 0x80;

        }

        break;

    case AV_SAMPLE_FMT_S16P:

        for (chan = 0; chan < avctx->channels; chan++) {

            int16_t *samples = (int16_t *)frame->extended_data[chan];

            int32_t *decoded = s->decoded[chan];

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

                samples[i] = decoded[i];

        }

        break;

    case AV_SAMPLE_FMT_S32P:

        for (chan = 0; chan < avctx->channels; chan++) {

            int32_t *samples = (int32_t *)frame->extended_data[chan];

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

                samples[i] <<= 8;

        }

        break;

    }

    *got_frame_ptr = 1;

    return pkt->size;

}


static BlockBackend *img_open_opts(const char *optstr,

                                   QemuOpts *opts, int flags, bool writethrough,

                                   bool quiet, bool force_share)

{

    QDict *options;

    Error *local_err = NULL;

    BlockBackend *blk;

    options = qemu_opts_to_qdict(opts, NULL);

    if (force_share) {

        if (qdict_haskey(options, BDRV_OPT_FORCE_SHARE)

            && !qdict_get_bool(options, BDRV_OPT_FORCE_SHARE)) {

            error_report("--force-share/-U conflicts with image options");

            return NULL;

        }

        qdict_put(options, BDRV_OPT_FORCE_SHARE, qbool_from_bool(true));

    }

    blk = blk_new_open(NULL, NULL, options, flags, &local_err);

    if (!blk) {

        error_reportf_err(local_err, "Could not open '%s': ", optstr);

        return NULL;

    }

    blk_set_enable_write_cache(blk, !writethrough);

    if (img_open_password(blk, optstr, flags, quiet) < 0) {

        blk_unref(blk);

        return NULL;

    }

    return blk;

}


static void qmp_input_type_bool(Visitor *v, bool *obj, const char *name,

                                Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

    QObject *qobj = qmp_input_get_object(qiv, name, true);

    if (!qobj || qobject_type(qobj) != QTYPE_QBOOL) {

        error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                   "boolean");

        return;

    }

    *obj = qbool_get_bool(qobject_to_qbool(qobj));

}


static int create_vorbis_context(vorbis_enc_context *venc,

                                 AVCodecContext *avccontext)

{

    vorbis_enc_floor   *fc;

    vorbis_enc_residue *rc;

    vorbis_enc_mapping *mc;

    int i, book, ret;

    venc->channels    = avccontext->channels;

    venc->sample_rate = avccontext->sample_rate;

    venc->log2_blocksize[0] = venc->log2_blocksize[1] = 11;

    venc->ncodebooks = FF_ARRAY_ELEMS(cvectors);

    venc->codebooks  = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks);

    if (!venc->codebooks)

        return AVERROR(ENOMEM);

    // codebook 0..14 - floor1 book, values 0..255

    // codebook 15 residue masterbook

    // codebook 16..29 residue

    for (book = 0; book < venc->ncodebooks; book++) {

        vorbis_enc_codebook *cb = &venc->codebooks[book];

        int vals;

        cb->ndimensions = cvectors[book].dim;

        cb->nentries    = cvectors[book].real_len;

        cb->min         = cvectors[book].min;

        cb->delta       = cvectors[book].delta;

        cb->lookup      = cvectors[book].lookup;

        cb->seq_p       = 0;

        cb->lens      = av_malloc(sizeof(uint8_t)  * cb->nentries);

        cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries);

        if (!cb->lens || !cb->codewords)

            return AVERROR(ENOMEM);

        memcpy(cb->lens, cvectors[book].clens, cvectors[book].len);

        memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len);

        if (cb->lookup) {

            vals = cb_lookup_vals(cb->lookup, cb->ndimensions, cb->nentries);

            cb->quantlist = av_malloc(sizeof(int) * vals);

            if (!cb->quantlist)

                return AVERROR(ENOMEM);

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

                cb->quantlist[i] = cvectors[book].quant[i];

        } else {

            cb->quantlist = NULL;

        }

        if ((ret = ready_codebook(cb)) < 0)

            return ret;

    }

    venc->nfloors = 1;

    venc->floors  = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors);

    if (!venc->floors)

        return AVERROR(ENOMEM);

    // just 1 floor

    fc = &venc->floors[0];

    fc->partitions         = NUM_FLOOR_PARTITIONS;

    fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions);

    if (!fc->partition_to_class)

        return AVERROR(ENOMEM);

    fc->nclasses           = 0;

    for (i = 0; i < fc->partitions; i++) {

        static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4};

        fc->partition_to_class[i] = a[i];

        fc->nclasses = FFMAX(fc->nclasses, fc->partition_to_class[i]);

    }

    fc->nclasses++;

    fc->classes = av_malloc(sizeof(vorbis_enc_floor_class) * fc->nclasses);

    if (!fc->classes)

        return AVERROR(ENOMEM);

    for (i = 0; i < fc->nclasses; i++) {

        vorbis_enc_floor_class * c = &fc->classes[i];

        int j, books;

        c->dim        = floor_classes[i].dim;

        c->subclass   = floor_classes[i].subclass;

        c->masterbook = floor_classes[i].masterbook;

        books         = (1 << c->subclass);

        c->books      = av_malloc(sizeof(int) * books);

        if (!c->books)

            return AVERROR(ENOMEM);

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

            c->books[j] = floor_classes[i].nbooks[j];

    }

    fc->multiplier = 2;

    fc->rangebits  = venc->log2_blocksize[0] - 1;

    fc->values = 2;

    for (i = 0; i < fc->partitions; i++)

        fc->values += fc->classes[fc->partition_to_class[i]].dim;

    fc->list = av_malloc(sizeof(vorbis_floor1_entry) * fc->values);

    if (!fc->list)

        return AVERROR(ENOMEM);

    fc->list[0].x = 0;

    fc->list[1].x = 1 << fc->rangebits;

    for (i = 2; i < fc->values; i++) {

        static const int a[] = {

             93, 23,372,  6, 46,186,750, 14, 33, 65,

            130,260,556,  3, 10, 18, 28, 39, 55, 79,

            111,158,220,312,464,650,850

        };

        fc->list[i].x = a[i - 2];

    }

    ff_vorbis_ready_floor1_list(fc->list, fc->values);

    venc->nresidues = 1;

    venc->residues  = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues);

    if (!venc->residues)

        return AVERROR(ENOMEM);

    // single residue

    rc = &venc->residues[0];

    rc->type            = 2;

    rc->begin           = 0;

    rc->end             = 1600;

    rc->partition_size  = 32;

    rc->classifications = 10;

    rc->classbook       = 15;

    rc->books           = av_malloc(sizeof(*rc->books) * rc->classifications);

    if (!rc->books)

        return AVERROR(ENOMEM);

    {

        static const int8_t a[10][8] = {

            { -1, -1, -1, -1, -1, -1, -1, -1, },

            { -1, -1, 16, -1, -1, -1, -1, -1, },

            { -1, -1, 17, -1, -1, -1, -1, -1, },

            { -1, -1, 18, -1, -1, -1, -1, -1, },

            { -1, -1, 19, -1, -1, -1, -1, -1, },

            { -1, -1, 20, -1, -1, -1, -1, -1, },

            { -1, -1, 21, -1, -1, -1, -1, -1, },

            { 22, 23, -1, -1, -1, -1, -1, -1, },

            { 24, 25, -1, -1, -1, -1, -1, -1, },

            { 26, 27, 28, -1, -1, -1, -1, -1, },

        };

        memcpy(rc->books, a, sizeof a);

    }

    if ((ret = ready_residue(rc, venc)) < 0)

        return ret;

    venc->nmappings = 1;

    venc->mappings  = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings);

    if (!venc->mappings)

        return AVERROR(ENOMEM);

    // single mapping

    mc = &venc->mappings[0];

    mc->submaps = 1;

    mc->mux     = av_malloc(sizeof(int) * venc->channels);

    if (!mc->mux)

        return AVERROR(ENOMEM);

    for (i = 0; i < venc->channels; i++)

        mc->mux[i] = 0;

    mc->floor   = av_malloc(sizeof(int) * mc->submaps);

    mc->residue = av_malloc(sizeof(int) * mc->submaps);

    if (!mc->floor || !mc->residue)

        return AVERROR(ENOMEM);

    for (i = 0; i < mc->submaps; i++) {

        mc->floor[i]   = 0;

        mc->residue[i] = 0;

    }

    mc->coupling_steps = venc->channels == 2 ? 1 : 0;

    mc->magnitude      = av_malloc(sizeof(int) * mc->coupling_steps);

    mc->angle          = av_malloc(sizeof(int) * mc->coupling_steps);

    if (!mc->magnitude || !mc->angle)

        return AVERROR(ENOMEM);

    if (mc->coupling_steps) {

        mc->magnitude[0] = 0;

        mc->angle[0]     = 1;

    }

    venc->nmodes = 1;

    venc->modes  = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes);

    if (!venc->modes)

        return AVERROR(ENOMEM);

    // single mode

    venc->modes[0].blockflag = 0;

    venc->modes[0].mapping   = 0;

    venc->have_saved = 0;

    venc->saved      = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);

    venc->samples    = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]));

    venc->floor      = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);

    venc->coeffs     = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2);

    if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs)

        return AVERROR(ENOMEM);

    venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6];

    venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6];

    if ((ret = ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0)) < 0)

        return ret;

    if ((ret = ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0)) < 0)

        return ret;

    return 0;

}


set_phy_ctrl(E1000State *s, int index, uint16_t val)

{

    if ((val & MII_CR_AUTO_NEG_EN) && (val & MII_CR_RESTART_AUTO_NEG)) {

        qemu_get_queue(s->nic)->link_down = true;

        e1000_link_down(s);

        s->phy_reg[PHY_STATUS] &= ~MII_SR_AUTONEG_COMPLETE;

        DBGOUT(PHY, "Start link auto negotiation\n");

        qemu_mod_timer(s->autoneg_timer, qemu_get_clock_ms(vm_clock) + 500);

    }

}


PCIBus *i440fx_init(PCII440FXState **pi440fx_state, int *piix3_devfn, qemu_irq *pic)

{

    DeviceState *dev;

    PCIBus *b;

    PCIDevice *d;

    I440FXState *s;

    PIIX3State *piix3;

    dev = qdev_create(NULL, "i440FX-pcihost");

    s = FROM_SYSBUS(I440FXState, sysbus_from_qdev(dev));

    b = pci_bus_new(&s->busdev.qdev, NULL, 0);

    s->bus = b;

    qdev_init(dev);

    d = pci_create_simple(b, 0, "i440FX");

    *pi440fx_state = DO_UPCAST(PCII440FXState, dev, d);

    piix3 = DO_UPCAST(PIIX3State, dev,

                                 pci_create_simple(b, -1, "PIIX3"));

    piix3->pic = pic;

    pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, 4);

    (*pi440fx_state)->piix3 = piix3;

    *piix3_devfn = piix3->dev.devfn;

    return b;

}


static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)

{

    int64_t start;

    int i, nb_chapters, str_len, version;

    char str[256+1];

    if ((atom.size -= 5) < 0)

        return 0;

    version = avio_r8(pb);

    avio_rb24(pb);

    if (version)

        avio_rb32(pb); // ???

    nb_chapters = avio_r8(pb);

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

        if (atom.size < 9)

            return 0;

        start = avio_rb64(pb);

        str_len = avio_r8(pb);

        if ((atom.size -= 9+str_len) < 0)

            return 0;

        avio_read(pb, str, str_len);

        str[str_len] = 0;

        avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);

    }

    return 0;

}


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

{

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

    int has_freq = qdict_haskey(qdict, "freq");

    int freq = qdict_get_try_int(qdict, "freq", -1);

    int has_bits = qdict_haskey(qdict, "bits");

    int bits = qdict_get_try_int(qdict, "bits", -1);

    int has_channels = qdict_haskey(qdict, "nchannels");

    int nchannels = qdict_get_try_int(qdict, "nchannels", -1);

    CaptureState *s;

    s = qemu_mallocz (sizeof (*s));

    freq = has_freq ? freq : 44100;

    bits = has_bits ? bits : 16;

    nchannels = has_channels ? nchannels : 2;

    if (wav_start_capture (s, path, freq, bits, nchannels)) {

        monitor_printf(mon, "Faied to add wave capture\n");

        qemu_free (s);

    }

    QLIST_INSERT_HEAD (&capture_head, s, entries);

}


static int old_codec47(SANMVideoContext *ctx, int top,

                       int left, int width, int height)

{

    int i, j, seq, compr, new_rot, tbl_pos, skip;

    int stride     = ctx->pitch;

    uint8_t *dst   = ((uint8_t*)ctx->frm0) + left + top * stride;

    uint8_t *prev1 = (uint8_t*)ctx->frm1;

    uint8_t *prev2 = (uint8_t*)ctx->frm2;

    uint32_t decoded_size;

    tbl_pos = bytestream2_tell(&ctx->gb);

    seq     = bytestream2_get_le16(&ctx->gb);

    compr   = bytestream2_get_byte(&ctx->gb);

    new_rot = bytestream2_get_byte(&ctx->gb);

    skip    = bytestream2_get_byte(&ctx->gb);

    bytestream2_skip(&ctx->gb, 9);

    decoded_size = bytestream2_get_le32(&ctx->gb);

    bytestream2_skip(&ctx->gb, 8);

    if (decoded_size > height * stride - left - top * stride) {

        decoded_size = height * stride - left - top * stride;

        av_log(ctx->avctx, AV_LOG_WARNING, "decoded size is too large\n");

    }

    if (skip & 1)

        bytestream2_skip(&ctx->gb, 0x8080);

    if (!seq) {

        ctx->prev_seq = -1;

        memset(prev1, 0, ctx->height * stride);

        memset(prev2, 0, ctx->height * stride);

    }

    av_dlog(ctx->avctx, "compression %d\n", compr);

    switch (compr) {

    case 0:

        if (bytestream2_get_bytes_left(&ctx->gb) < width * height)

            return AVERROR_INVALIDDATA;

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

            bytestream2_get_bufferu(&ctx->gb, dst, width);

            dst += stride;

        }

        break;

    case 1:

        if (bytestream2_get_bytes_left(&ctx->gb) < ((width + 1) >> 1) * ((height + 1) >> 1))

            return AVERROR_INVALIDDATA;

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

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

                dst[i] = dst[i + 1] =

                dst[stride + i] = dst[stride + i + 1] = bytestream2_get_byteu(&ctx->gb);

            }

            dst += stride * 2;

        }

        break;

    case 2:

        if (seq == ctx->prev_seq + 1) {

            for (j = 0; j < height; j += 8) {

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

                    if (process_block(ctx, dst + i, prev1 + i, prev2 + i, stride,

                                      tbl_pos + 8, 8))

                        return AVERROR_INVALIDDATA;

                }

                dst   += stride * 8;

                prev1 += stride * 8;

                prev2 += stride * 8;

            }

        }

        break;

    case 3:

        memcpy(ctx->frm0, ctx->frm2, ctx->pitch * ctx->height);

        break;

    case 4:

        memcpy(ctx->frm0, ctx->frm1, ctx->pitch * ctx->height);

        break;

    case 5:

        if (rle_decode(ctx, dst, decoded_size))

            return AVERROR_INVALIDDATA;

        break;

    default:

        av_log(ctx->avctx, AV_LOG_ERROR,

               "subcodec 47 compression %d not implemented\n", compr);

        return AVERROR_PATCHWELCOME;

    }

    if (seq == ctx->prev_seq + 1)

        ctx->rotate_code = new_rot;

    else

        ctx->rotate_code = 0;

    ctx->prev_seq = seq;

    return 0;

}


static av_cold int vtenc_close(AVCodecContext *avctx)

{

    VTEncContext *vtctx = avctx->priv_data;

    if(!vtctx->session) return 0;

    VTCompressionSessionInvalidate(vtctx->session);

    pthread_cond_destroy(&vtctx->cv_sample_sent);

    pthread_mutex_destroy(&vtctx->lock);

    CFRelease(vtctx->session);

    vtctx->session = NULL;

    return 0;

}


static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track)

{

    int tag = track->par->codec_tag;

    int interlaced = track->par->field_order > AV_FIELD_PROGRESSIVE;

    AVStream *st = track->st;

    int rate = av_q2d(find_fps(s, st));

    if (!tag)

        tag = MKTAG('m', '2', 'v', '1'); //fallback tag

    if (track->par->format == AV_PIX_FMT_YUV420P) {

        if (track->par->width == 1280 && track->par->height == 720) {

            if (!interlaced) {

                if      (rate == 24) tag = MKTAG('x','d','v','4');

                else if (rate == 25) tag = MKTAG('x','d','v','5');

                else if (rate == 30) tag = MKTAG('x','d','v','1');

                else if (rate == 50) tag = MKTAG('x','d','v','a');

                else if (rate == 60) tag = MKTAG('x','d','v','9');

            }

        } else if (track->par->width == 1440 && track->par->height == 1080) {

            if (!interlaced) {

                if      (rate == 24) tag = MKTAG('x','d','v','6');

                else if (rate == 25) tag = MKTAG('x','d','v','7');

                else if (rate == 30) tag = MKTAG('x','d','v','8');

            } else {

                if      (rate == 25) tag = MKTAG('x','d','v','3');

                else if (rate == 30) tag = MKTAG('x','d','v','2');

            }

        } else if (track->par->width == 1920 && track->par->height == 1080) {

            if (!interlaced) {

                if      (rate == 24) tag = MKTAG('x','d','v','d');

                else if (rate == 25) tag = MKTAG('x','d','v','e');

                else if (rate == 30) tag = MKTAG('x','d','v','f');

            } else {

                if      (rate == 25) tag = MKTAG('x','d','v','c');

                else if (rate == 30) tag = MKTAG('x','d','v','b');

            }

        }

    } else if (track->par->format == AV_PIX_FMT_YUV422P) {

        if (track->par->width == 1280 && track->par->height == 720) {

            if (!interlaced) {

                if      (rate == 24) tag = MKTAG('x','d','5','4');

                else if (rate == 25) tag = MKTAG('x','d','5','5');

                else if (rate == 30) tag = MKTAG('x','d','5','1');

                else if (rate == 50) tag = MKTAG('x','d','5','a');

                else if (rate == 60) tag = MKTAG('x','d','5','9');

            }

        } else if (track->par->width == 1920 && track->par->height == 1080) {

            if (!interlaced) {

                if      (rate == 24) tag = MKTAG('x','d','5','d');

                else if (rate == 25) tag = MKTAG('x','d','5','e');

                else if (rate == 30) tag = MKTAG('x','d','5','f');

            } else {

                if      (rate == 25) tag = MKTAG('x','d','5','c');

                else if (rate == 30) tag = MKTAG('x','d','5','b');

            }

        }

    }

    return tag;

}


static int apply_color_indexing_transform(WebPContext *s)

{

    ImageContext *img;

    ImageContext *pal;

    int i, x, y;

    uint8_t *p, *pi;

    img = &s->image[IMAGE_ROLE_ARGB];

    pal = &s->image[IMAGE_ROLE_COLOR_INDEXING];

    if (pal->size_reduction > 0) {

        GetBitContext gb_g;

        uint8_t *line;

        int pixel_bits = 8 >> pal->size_reduction;

        line = av_malloc(img->frame->linesize[0]);

        if (!line)

            return AVERROR(ENOMEM);

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

            p = GET_PIXEL(img->frame, 0, y);

            memcpy(line, p, img->frame->linesize[0]);

            init_get_bits(&gb_g, line, img->frame->linesize[0] * 8);

            skip_bits(&gb_g, 16);

            i = 0;

            for (x = 0; x < img->frame->width; x++) {

                p    = GET_PIXEL(img->frame, x, y);

                p[2] = get_bits(&gb_g, pixel_bits);

                i++;

                if (i == 1 << pal->size_reduction) {

                    skip_bits(&gb_g, 24);

                    i = 0;

                }

            }

        }

        av_free(line);

    }

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

        for (x = 0; x < img->frame->width; x++) {

            p = GET_PIXEL(img->frame, x, y);

            i = p[2];

            if (i >= pal->frame->width) {

                av_log(s->avctx, AV_LOG_ERROR, "invalid palette index %d\n", i);

                return AVERROR_INVALIDDATA;

            }

            pi = GET_PIXEL(pal->frame, i, 0);

            AV_COPY32(p, pi);

        }

    }

    return 0;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    PnvChipClass *k = PNV_CHIP_CLASS(klass);

    k->cpu_model = "POWER8E";

    k->chip_type = PNV_CHIP_POWER8E;

    k->chip_cfam_id = 0x221ef04980000000ull;  /* P8 Murano DD2.1 */

    k->cores_mask = POWER8E_CORE_MASK;

    k->core_pir = pnv_chip_core_pir_p8;

    dc->desc = "PowerNV Chip POWER8E";

}


void uhci_port_test(struct qhc *hc, int port, uint16_t expect)

{

    void *addr = hc->base + 0x10 + 2 * port;

    uint16_t value = qpci_io_readw(hc->dev, addr);

    uint16_t mask = ~(UHCI_PORT_WRITE_CLEAR | UHCI_PORT_RSVD1);

    g_assert((value & mask) == (expect & mask));

}


GuestLogicalProcessorList *qmp_guest_get_vcpus(Error **errp)

{

    PSYSTEM_LOGICAL_PROCESSOR_INFORMATION pslpi, ptr;

    DWORD length;

    GuestLogicalProcessorList *head, **link;

    Error *local_err = NULL;

    int64_t current;

    ptr = pslpi = NULL;

    length = 0;

    current = 0;

    head = NULL;

    link = &head;

    if ((GetLogicalProcessorInformation(pslpi, &length) == FALSE) &&

        (GetLastError() == ERROR_INSUFFICIENT_BUFFER) &&

        (length > sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION))) {

        ptr = pslpi = g_malloc0(length);

        if (GetLogicalProcessorInformation(pslpi, &length) == FALSE) {

            error_setg(&local_err, "Failed to get processor information: %d",

                       (int)GetLastError());

        }

    } else {

        error_setg(&local_err,

                   "Failed to get processor information buffer length: %d",

                   (int)GetLastError());

    }

    while ((local_err == NULL) && (length > 0)) {

        if (pslpi->Relationship == RelationProcessorCore) {

            ULONG_PTR cpu_bits = pslpi->ProcessorMask;

            while (cpu_bits > 0) {

                if (!!(cpu_bits & 1)) {

                    GuestLogicalProcessor *vcpu;

                    GuestLogicalProcessorList *entry;

                    vcpu = g_malloc0(sizeof *vcpu);

                    vcpu->logical_id = current++;

                    vcpu->online = true;

                    vcpu->has_can_offline = false;

                    entry = g_malloc0(sizeof *entry);

                    entry->value = vcpu;

                    *link = entry;

                    link = &entry->next;

                }

                cpu_bits >>= 1;

            }

        }

        length -= sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);

        pslpi++; /* next entry */

    }

    g_free(ptr);

    if (local_err == NULL) {

        if (head != NULL) {

            return head;

        }

        /* there's no guest with zero VCPUs */

        error_setg(&local_err, "Guest reported zero VCPUs");

    }

    qapi_free_GuestLogicalProcessorList(head);

    error_propagate(errp, local_err);

    return NULL;

}


static bool bdrv_drain_poll(BlockDriverState *bs)

{

    bool waited = false;

    while (atomic_read(&bs->in_flight) > 0) {

        aio_poll(bdrv_get_aio_context(bs), true);

        waited = true;

    }

    return waited;

}


static void cpu_exec_step(CPUState *cpu)

{

    CPUClass *cc = CPU_GET_CLASS(cpu);

    TranslationBlock *tb;

    target_ulong cs_base, pc;

    uint32_t flags;

    uint32_t cflags = 1 | CF_IGNORE_ICOUNT;

    if (sigsetjmp(cpu->jmp_env, 0) == 0) {

        tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags,

                                  cflags & CF_HASH_MASK);

        if (tb == NULL) {

            mmap_lock();

            tb_lock();

            tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);

            tb_unlock();

            mmap_unlock();

        }

        cc->cpu_exec_enter(cpu);

        /* execute the generated code */

        trace_exec_tb(tb, pc);

        cpu_tb_exec(cpu, tb);

        cc->cpu_exec_exit(cpu);

    } else {

        /* We may have exited due to another problem here, so we need

         * to reset any tb_locks we may have taken but didn't release.

         * The mmap_lock is dropped by tb_gen_code if it runs out of

         * memory.

         */

#ifndef CONFIG_SOFTMMU

        tcg_debug_assert(!have_mmap_lock());

#endif

        tb_lock_reset();

    }

}


static bool intel_hda_xfer(HDACodecDevice *dev, uint32_t stnr, bool output,

                           uint8_t *buf, uint32_t len)

{

    HDACodecBus *bus = DO_UPCAST(HDACodecBus, qbus, dev->qdev.parent_bus);

    IntelHDAState *d = container_of(bus, IntelHDAState, codecs);

    target_phys_addr_t addr;

    uint32_t s, copy, left;

    IntelHDAStream *st;

    bool irq = false;

    st = output ? d->st + 4 : d->st;

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

        if (stnr == ((st[s].ctl >> 20) & 0x0f)) {

            st = st + s;

            break;

        }

    }

    if (s == 4) {

        return false;

    }

    if (st->bpl == NULL) {

        return false;

    }

    if (st->ctl & (1 << 26)) {

        /*

         * Wait with the next DMA xfer until the guest

         * has acked the buffer completion interrupt

         */

        return false;

    }

    left = len;

    while (left > 0) {

        copy = left;

        if (copy > st->bsize - st->lpib)

            copy = st->bsize - st->lpib;

        if (copy > st->bpl[st->be].len - st->bp)

            copy = st->bpl[st->be].len - st->bp;

        dprint(d, 3, "dma: entry %d, pos %d/%d, copy %d\n",

               st->be, st->bp, st->bpl[st->be].len, copy);

        pci_dma_rw(&d->pci, st->bpl[st->be].addr + st->bp, buf, copy, !output);

        st->lpib += copy;

        st->bp += copy;

        buf += copy;

        left -= copy;

        if (st->bpl[st->be].len == st->bp) {

            /* bpl entry filled */

            if (st->bpl[st->be].flags & 0x01) {

                irq = true;

            }

            st->bp = 0;

            st->be++;

            if (st->be == st->bentries) {

                /* bpl wrap around */

                st->be = 0;

                st->lpib = 0;

            }

        }

    }

    if (d->dp_lbase & 0x01) {

        addr = intel_hda_addr(d->dp_lbase & ~0x01, d->dp_ubase);

        stl_le_pci_dma(&d->pci, addr + 8*s, st->lpib);

    }

    dprint(d, 3, "dma: --\n");

    if (irq) {

        st->ctl |= (1 << 26); /* buffer completion interrupt */

        intel_hda_update_irq(d);

    }

    return true;

}


int64_t qmp_guest_get_time(Error **errp)

{

   int ret;

   qemu_timeval tq;

   int64_t time_ns;

   ret = qemu_gettimeofday(&tq);

   if (ret < 0) {

       error_setg_errno(errp, errno, "Failed to get time");

       return -1;

   }

   time_ns = tq.tv_sec * 1000000000LL + tq.tv_usec * 1000;

   return time_ns;

}


static int check_strtox_error(const char *nptr, char *ep,

                              const char **endptr, int libc_errno)

{

    if (libc_errno == 0 && ep == nptr) {

        libc_errno = EINVAL;

    }

    if (!endptr && *ep) {

        return -EINVAL;

    }

    if (endptr) {

        *endptr = ep;

    }

    return -libc_errno;

}


static void ncq_cb(void *opaque, int ret)

{

    NCQTransferState *ncq_tfs = (NCQTransferState *)opaque;

    IDEState *ide_state = &ncq_tfs->drive->port.ifs[0];

    if (ret == -ECANCELED) {

        return;

    }

    /* Clear bit for this tag in SActive */

    ncq_tfs->drive->port_regs.scr_act &= ~(1 << ncq_tfs->tag);

    if (ret < 0) {

        /* error */

        ide_state->error = ABRT_ERR;

        ide_state->status = READY_STAT | ERR_STAT;

        ncq_tfs->drive->port_regs.scr_err |= (1 << ncq_tfs->tag);

    } else {

        ide_state->status = READY_STAT | SEEK_STAT;

    }

    ahci_write_fis_sdb(ncq_tfs->drive->hba, ncq_tfs->drive->port_no,

                       (1 << ncq_tfs->tag));

    DPRINTF(ncq_tfs->drive->port_no, "NCQ transfer tag %d finished\n",

            ncq_tfs->tag);

    block_acct_done(bdrv_get_stats(ncq_tfs->drive->port.ifs[0].bs),

                    &ncq_tfs->acct);

    qemu_sglist_destroy(&ncq_tfs->sglist);

    ncq_tfs->used = 0;

}


static bool aio_dispatch_handlers(AioContext *ctx)

{

    AioHandler *node, *tmp;

    bool progress = false;

    /*

     * We have to walk very carefully in case aio_set_fd_handler is

     * called while we're walking.

     */

    qemu_lockcnt_inc(&ctx->list_lock);

    QLIST_FOREACH_SAFE_RCU(node, &ctx->aio_handlers, node, tmp) {

        int revents;

        revents = node->pfd.revents & node->pfd.events;

        node->pfd.revents = 0;

        if (!node->deleted &&

            (revents & (G_IO_IN | G_IO_HUP | G_IO_ERR)) &&

            aio_node_check(ctx, node->is_external) &&

            node->io_read) {

            node->io_read(node->opaque);

            /* aio_notify() does not count as progress */

            if (node->opaque != &ctx->notifier) {

                progress = true;

            }

        }

        if (!node->deleted &&

            (revents & (G_IO_OUT | G_IO_ERR)) &&

            aio_node_check(ctx, node->is_external) &&

            node->io_write) {

            node->io_write(node->opaque);

            progress = true;

        }

        if (node->deleted) {

            if (qemu_lockcnt_dec_if_lock(&ctx->list_lock)) {

                QLIST_REMOVE(node, node);

                g_free(node);

                qemu_lockcnt_inc_and_unlock(&ctx->list_lock);

            }

        }

    }

    qemu_lockcnt_dec(&ctx->list_lock);

    return progress;

}


static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)

{

    int rs, rt, rd, sa;

    uint32_t op1, op2;

    rs = (ctx->opcode >> 21) & 0x1f;

    rt = (ctx->opcode >> 16) & 0x1f;

    rd = (ctx->opcode >> 11) & 0x1f;

    sa = (ctx->opcode >> 6) & 0x1f;

    op1 = MASK_SPECIAL3(ctx->opcode);

    switch (op1) {

    case OPC_EXT:

    case OPC_INS:

        check_insn(ctx, ISA_MIPS32R2);

        gen_bitops(ctx, op1, rt, rs, sa, rd);

        break;

    case OPC_BSHFL:

        op2 = MASK_BSHFL(ctx->opcode);

        switch (op2) {

        case OPC_ALIGN ... OPC_ALIGN_END:

        case OPC_BITSWAP:

            check_insn(ctx, ISA_MIPS32R6);

            decode_opc_special3_r6(env, ctx);

            break;

        default:

            check_insn(ctx, ISA_MIPS32R2);

            gen_bshfl(ctx, op2, rt, rd);

            break;

        }

        break;

#if defined(TARGET_MIPS64)

    case OPC_DEXTM ... OPC_DEXT:

    case OPC_DINSM ... OPC_DINS:

        check_insn(ctx, ISA_MIPS64R2);

        check_mips_64(ctx);

        gen_bitops(ctx, op1, rt, rs, sa, rd);

        break;

    case OPC_DBSHFL:

        op2 = MASK_DBSHFL(ctx->opcode);

        switch (op2) {

        case OPC_DALIGN ... OPC_DALIGN_END:

        case OPC_DBITSWAP:

            check_insn(ctx, ISA_MIPS32R6);

            decode_opc_special3_r6(env, ctx);

            break;

        default:

            check_insn(ctx, ISA_MIPS64R2);

            check_mips_64(ctx);

            op2 = MASK_DBSHFL(ctx->opcode);

            gen_bshfl(ctx, op2, rt, rd);

            break;

        }

        break;

#endif

    case OPC_RDHWR:

        gen_rdhwr(ctx, rt, rd);

        break;

    case OPC_FORK:

        check_insn(ctx, ASE_MT);

        {

            TCGv t0 = tcg_temp_new();

            TCGv t1 = tcg_temp_new();

            gen_load_gpr(t0, rt);

            gen_load_gpr(t1, rs);

            gen_helper_fork(t0, t1);

            tcg_temp_free(t0);

            tcg_temp_free(t1);

        }

        break;

    case OPC_YIELD:

        check_insn(ctx, ASE_MT);

        {

            TCGv t0 = tcg_temp_new();

            gen_load_gpr(t0, rs);

            gen_helper_yield(t0, cpu_env, t0);

            gen_store_gpr(t0, rd);

            tcg_temp_free(t0);

        }

        break;

    default:

        if (ctx->insn_flags & ISA_MIPS32R6) {

            decode_opc_special3_r6(env, ctx);

        } else {

            decode_opc_special3_legacy(env, ctx);

        }

    }

}


static void scsi_dma_complete(void *opaque, int ret)

{

    SCSIDiskReq *r = (SCSIDiskReq *)opaque;

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

    bdrv_acct_done(s->qdev.conf.bs, &r->acct);

    if (ret) {

        if (scsi_handle_rw_error(r, -ret)) {

            goto done;

        }

    }

    r->sector += r->sector_count;

    r->sector_count = 0;

    scsi_req_complete(&r->req, GOOD);

done:

    if (!r->req.io_canceled) {

        scsi_req_unref(&r->req);

    }

}


static void dump_sprs (CPUPPCState *env)

{

    ppc_spr_t *spr;

    uint32_t pvr = env->spr[SPR_PVR];

    uint32_t sr, sw, ur, uw;

    int i, j, n;

    printf("* SPRs for PVR=%08x\n", pvr);

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

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

            n = (i << 5) | j;

            spr = &env->spr_cb[n];

#if !defined(CONFIG_USER_ONLY)

            sw = spr->oea_write != NULL && spr->oea_write != SPR_NOACCESS;

            sr = spr->oea_read != NULL && spr->oea_read != SPR_NOACCESS;

#else

            sw = 0;

            sr = 0;

#endif

            uw = spr->uea_write != NULL && spr->uea_write != SPR_NOACCESS;

            ur = spr->uea_read != NULL && spr->uea_read != SPR_NOACCESS;

            if (sw || sr || uw || ur) {

                printf("%4d (%03x) %8s s%c%c u%c%c\n",

                       (i << 5) | j, (i << 5) | j, spr->name,

                       sw ? 'w' : '-', sr ? 'r' : '-',

                       uw ? 'w' : '-', ur ? 'r' : '-');

            }

        }

    }

    fflush(stdout);

    fflush(stderr);

}


void pc_cpus_init(PCMachineState *pcms)

{

    int i;

    CPUClass *cc;

    ObjectClass *oc;

    const char *typename;

    gchar **model_pieces;

    X86CPU *cpu = NULL;

    MachineState *machine = MACHINE(pcms);

    /* init CPUs */

    if (machine->cpu_model == NULL) {

#ifdef TARGET_X86_64

        machine->cpu_model = "qemu64";

#else

        machine->cpu_model = "qemu32";

#endif

    }

    model_pieces = g_strsplit(machine->cpu_model, ",", 2);

    if (!model_pieces[0]) {

        error_report("Invalid/empty CPU model name");

        exit(1);

    }

    oc = cpu_class_by_name(TYPE_X86_CPU, model_pieces[0]);

    if (oc == NULL) {

        error_report("Unable to find CPU definition: %s", model_pieces[0]);

        exit(1);

    }

    typename = object_class_get_name(oc);

    cc = CPU_CLASS(oc);

    cc->parse_features(typename, model_pieces[1], &error_fatal);

    g_strfreev(model_pieces);

    /* Calculates the limit to CPU APIC ID values

     *

     * Limit for the APIC ID value, so that all

     * CPU APIC IDs are < pcms->apic_id_limit.

     *

     * This is used for FW_CFG_MAX_CPUS. See comments on bochs_bios_init().

     */

    pcms->apic_id_limit = x86_cpu_apic_id_from_index(max_cpus - 1) + 1;

    if (pcms->apic_id_limit > ACPI_CPU_HOTPLUG_ID_LIMIT) {

        error_report("max_cpus is too large. APIC ID of last CPU is %u",

                     pcms->apic_id_limit - 1);

        exit(1);

    }

    pcms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +

                                    sizeof(CPUArchId) * max_cpus);

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

        pcms->possible_cpus->cpus[i].arch_id = x86_cpu_apic_id_from_index(i);

        pcms->possible_cpus->len++;

        if (i < smp_cpus) {

            cpu = pc_new_cpu(typename, x86_cpu_apic_id_from_index(i),

                             &error_fatal);

            object_unref(OBJECT(cpu));

        }

    }

    /* tell smbios about cpuid version and features */

    smbios_set_cpuid(cpu->env.cpuid_version, cpu->env.features[FEAT_1_EDX]);

}


static void destroy_all_mappings(void)

{

    destroy_l2_mapping(&phys_map, P_L2_LEVELS - 1);

    phys_map_nodes_reset();

}


static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,

                                      const uint8_t *data_in,

                                      size_t data_in_len,

                                      uint8_t *data_out, size_t data_out_len,

                                      struct virtio_scsi_cmd_resp *resp_out)

{

    QVirtQueue *vq;

    struct virtio_scsi_cmd_req req = { { 0 } };

    struct virtio_scsi_cmd_resp resp = { .response = 0xff, .status = 0xff };

    uint64_t req_addr, resp_addr, data_in_addr = 0, data_out_addr = 0;

    uint8_t response;

    uint32_t free_head;

    vq = vs->vq[2];

    req.lun[0] = 1; /* Select LUN */

    req.lun[1] = 1; /* Select target 1 */

    memcpy(req.cdb, cdb, VIRTIO_SCSI_CDB_SIZE);

    /* XXX: Fix endian if any multi-byte field in req/resp is used */

    /* Add request header */

    req_addr = qvirtio_scsi_alloc(vs, sizeof(req), &req);

    free_head = qvirtqueue_add(vq, req_addr, sizeof(req), false, true);

    if (data_out_len) {

        data_out_addr = qvirtio_scsi_alloc(vs, data_out_len, data_out);

        qvirtqueue_add(vq, data_out_addr, data_out_len, false, true);

    }

    /* Add response header */

    resp_addr = qvirtio_scsi_alloc(vs, sizeof(resp), &resp);

    qvirtqueue_add(vq, resp_addr, sizeof(resp), true, !!data_in_len);

    if (data_in_len) {

        data_in_addr = qvirtio_scsi_alloc(vs, data_in_len, data_in);

        qvirtqueue_add(vq, data_in_addr, data_in_len, true, false);

    }

    qvirtqueue_kick(vs->dev, vq, free_head);

    qvirtio_wait_queue_isr(vs->dev, vq, QVIRTIO_SCSI_TIMEOUT_US);

    response = readb(resp_addr +

                     offsetof(struct virtio_scsi_cmd_resp, response));

    if (resp_out) {

        memread(resp_addr, resp_out, sizeof(*resp_out));

    }

    guest_free(vs->alloc, req_addr);

    guest_free(vs->alloc, resp_addr);

    guest_free(vs->alloc, data_in_addr);

    guest_free(vs->alloc, data_out_addr);

    return response;

}


int bdrv_make_zero(BlockDriverState *bs, BdrvRequestFlags flags)

{

    int64_t target_sectors, ret, nb_sectors, sector_num = 0;

    int n;

    target_sectors = bdrv_nb_sectors(bs);

    if (target_sectors < 0) {

        return target_sectors;

    }

    for (;;) {

        nb_sectors = target_sectors - sector_num;

        if (nb_sectors <= 0) {

            return 0;

        }

        if (nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {

            nb_sectors = INT_MAX / BDRV_SECTOR_SIZE;

        }

        ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &n);

        if (ret < 0) {

            error_report("error getting block status at sector %" PRId64 ": %s",

                         sector_num, strerror(-ret));

            return ret;

        }

        if (ret & BDRV_BLOCK_ZERO) {

            sector_num += n;

            continue;

        }

        ret = bdrv_write_zeroes(bs, sector_num, n, flags);

        if (ret < 0) {

            error_report("error writing zeroes at sector %" PRId64 ": %s",

                         sector_num, strerror(-ret));

            return ret;

        }

        sector_num += n;

    }

}


raw_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,

                    QEMUIOVector *qiov, int flags)

{

    void *buf = NULL;

    BlockDriver *drv;

    QEMUIOVector local_qiov;

    int ret;

    if (bs->probed && sector_num == 0) {

        /* As long as these conditions are true, we can't get partial writes to

         * the probe buffer and can just directly check the request. */

        QEMU_BUILD_BUG_ON(BLOCK_PROBE_BUF_SIZE != 512);

        QEMU_BUILD_BUG_ON(BDRV_SECTOR_SIZE != 512);

        if (nb_sectors == 0) {

            /* qemu_iovec_to_buf() would fail, but we want to return success

             * instead of -EINVAL in this case. */

            return 0;

        }

        buf = qemu_try_blockalign(bs->file->bs, 512);

        if (!buf) {

            ret = -ENOMEM;

            goto fail;

        }

        ret = qemu_iovec_to_buf(qiov, 0, buf, 512);

        if (ret != 512) {

            ret = -EINVAL;

            goto fail;

        }

        drv = bdrv_probe_all(buf, 512, NULL);

        if (drv != bs->drv) {

            ret = -EPERM;

            goto fail;

        }

        /* Use the checked buffer, a malicious guest might be overwriting its

         * original buffer in the background. */

        qemu_iovec_init(&local_qiov, qiov->niov + 1);

        qemu_iovec_add(&local_qiov, buf, 512);

        qemu_iovec_concat(&local_qiov, qiov, 512, qiov->size - 512);

        qiov = &local_qiov;

    }

    BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);

    ret = bdrv_co_pwritev(bs->file->bs, sector_num * BDRV_SECTOR_SIZE,

                          nb_sectors * BDRV_SECTOR_SIZE, qiov, flags);

fail:

    if (qiov == &local_qiov) {

        qemu_iovec_destroy(&local_qiov);

    }

    qemu_vfree(buf);

    return ret;

}


void helper_stq_raw(uint64_t t0, uint64_t t1)

{

    stq_raw(t1, t0);

}


static void pc_machine_device_post_plug_cb(HotplugHandler *hotplug_dev,

                                           DeviceState *dev, Error **errp)

{

    if (object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM)) {

        pc_dimm_post_plug(hotplug_dev, dev, errp);

    }

}


static void create_gic(VirtBoardInfo *vbi, qemu_irq *pic, int type, bool secure)

{

    /* We create a standalone GIC */

    DeviceState *gicdev;

    SysBusDevice *gicbusdev;

    const char *gictype;

    int i;

    gictype = (type == 3) ? gicv3_class_name() : gic_class_name();

    gicdev = qdev_create(NULL, gictype);

    qdev_prop_set_uint32(gicdev, "revision", type);

    qdev_prop_set_uint32(gicdev, "num-cpu", smp_cpus);

    /* Note that the num-irq property counts both internal and external

     * interrupts; there are always 32 of the former (mandated by GIC spec).

     */

    qdev_prop_set_uint32(gicdev, "num-irq", NUM_IRQS + 32);

    if (!kvm_irqchip_in_kernel()) {

        qdev_prop_set_bit(gicdev, "has-security-extensions", secure);

    }

    qdev_init_nofail(gicdev);

    gicbusdev = SYS_BUS_DEVICE(gicdev);

    sysbus_mmio_map(gicbusdev, 0, vbi->memmap[VIRT_GIC_DIST].base);

    if (type == 3) {

        sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_REDIST].base);

    } else {

        sysbus_mmio_map(gicbusdev, 1, vbi->memmap[VIRT_GIC_CPU].base);

    }

    /* Wire the outputs from each CPU's generic timer to the

     * appropriate GIC PPI inputs, and the GIC's IRQ output to

     * the CPU's IRQ input.

     */

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

        DeviceState *cpudev = DEVICE(qemu_get_cpu(i));

        int ppibase = NUM_IRQS + i * GIC_INTERNAL + GIC_NR_SGIS;

        int irq;

        /* Mapping from the output timer irq lines from the CPU to the

         * GIC PPI inputs we use for the virt board.

         */

        const int timer_irq[] = {

            [GTIMER_PHYS] = ARCH_TIMER_NS_EL1_IRQ,

            [GTIMER_VIRT] = ARCH_TIMER_VIRT_IRQ,

            [GTIMER_HYP]  = ARCH_TIMER_NS_EL2_IRQ,

            [GTIMER_SEC]  = ARCH_TIMER_S_EL1_IRQ,

        };

        for (irq = 0; irq < ARRAY_SIZE(timer_irq); irq++) {

            qdev_connect_gpio_out(cpudev, irq,

                                  qdev_get_gpio_in(gicdev,

                                                   ppibase + timer_irq[irq]));

        }

        sysbus_connect_irq(gicbusdev, i, qdev_get_gpio_in(cpudev, ARM_CPU_IRQ));

        sysbus_connect_irq(gicbusdev, i + smp_cpus,

                           qdev_get_gpio_in(cpudev, ARM_CPU_FIQ));

    }

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

        pic[i] = qdev_get_gpio_in(gicdev, i);

    }

    fdt_add_gic_node(vbi, type);

    if (type == 3) {

        create_its(vbi, gicdev);

    } else {

        create_v2m(vbi, pic);

    }

}


static void pci_change_irq_level(PCIDevice *pci_dev, int irq_num, int change)

{

    PCIBus *bus;

    for (;;) {

        bus = pci_dev->bus;

        irq_num = bus->map_irq(pci_dev, irq_num);

        if (bus->set_irq)

            break;

        pci_dev = bus->parent_dev;

    }

    bus->irq_count[irq_num] += change;

    bus->set_irq(bus->irq_opaque, irq_num, bus->irq_count[irq_num] != 0);

}


static void qemu_chr_parse_common(QemuOpts *opts, ChardevCommon *backend)

{

    const char *logfile = qemu_opt_get(opts, "logfile");

    backend->has_logfile = logfile != NULL;

    backend->logfile = logfile ? g_strdup(logfile) : NULL;

    backend->has_logappend = true;

    backend->logappend = qemu_opt_get_bool(opts, "logappend", false);

}


static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)

{

    int num;

    if (!s->config || !s->enable)

        return 0;

    num = CMD(next_cmd) - CMD(stop);

    if (num < 0)

        num += CMD(max) - CMD(min);

    return num >> 2;

}


PageCache *cache_init(size_t num_pages, size_t page_size)

{

    int64_t i;

    PageCache *cache;

    if (num_pages <= 0) {

        DPRINTF("invalid number of pages\n");

        return NULL;

    }

    /* We prefer not to abort if there is no memory */

    cache = g_try_malloc(sizeof(*cache));

    if (!cache) {

        DPRINTF("Failed to allocate cache\n");

        return NULL;

    }

    /* round down to the nearest power of 2 */

    if (!is_power_of_2(num_pages)) {

        num_pages = pow2floor(num_pages);

        DPRINTF("rounding down to %" PRId64 "\n", num_pages);

    }

    cache->page_size = page_size;

    cache->num_items = 0;

    cache->max_num_items = num_pages;

    DPRINTF("Setting cache buckets to %" PRId64 "\n", cache->max_num_items);

    /* We prefer not to abort if there is no memory */

    cache->page_cache = g_try_malloc((cache->max_num_items) *

                                     sizeof(*cache->page_cache));

    if (!cache->page_cache) {

        DPRINTF("Failed to allocate cache->page_cache\n");

        g_free(cache);

        return NULL;

    }

    for (i = 0; i < cache->max_num_items; i++) {

        cache->page_cache[i].it_data = NULL;

        cache->page_cache[i].it_age = 0;

        cache->page_cache[i].it_addr = -1;

    }

    return cache;

}


void pit_set_gate(PITState *pit, int channel, int val)

{

    PITChannelState *s = &pit->channels[channel];

    switch(s->mode) {

    default:

    case 0:

    case 4:

        /* XXX: just disable/enable counting */

        break;

    case 1:

    case 5:

        if (s->gate < val) {

            /* restart counting on rising edge */

            s->count_load_time = qemu_get_clock(vm_clock);

            pit_irq_timer_update(s, s->count_load_time);

        }

        break;

    case 2:

    case 3:

        if (s->gate < val) {

            /* restart counting on rising edge */

            s->count_load_time = qemu_get_clock(vm_clock);

            pit_irq_timer_update(s, s->count_load_time);

        }

        /* XXX: disable/enable counting */

        break;

    }

    s->gate = val;

}


static int xhci_ep_nuke_one_xfer(XHCITransfer *t, TRBCCode report)

{

    int killed = 0;

    if (report && (t->running_async || t->running_retry)) {

        t->status = report;

        xhci_xfer_report(t);

    }

    if (t->running_async) {

        usb_cancel_packet(&t->packet);

        t->running_async = 0;

        killed = 1;

    }

    if (t->running_retry) {

        XHCIEPContext *epctx = t->xhci->slots[t->slotid-1].eps[t->epid-1];

        if (epctx) {

            epctx->retry = NULL;

            timer_del(epctx->kick_timer);

        }

        t->running_retry = 0;

        killed = 1;

    }

    g_free(t->trbs);

    t->trbs = NULL;

    t->trb_count = t->trb_alloced = 0;

    return killed;

}


static int kvm_mce_in_progress(CPUState *env)

{

    struct kvm_msr_entry msr_mcg_status = {

        .index = MSR_MCG_STATUS,

    };

    int r;

    r = kvm_get_msr(env, &msr_mcg_status, 1);

    if (r == -1 || r == 0) {

        fprintf(stderr, "Failed to get MCE status\n");

        return 0;

    }

    return !!(msr_mcg_status.data & MCG_STATUS_MCIP);

}


static int encode_picture(MpegEncContext *s, int picture_number)

{

    int i;

    int bits;

    s->picture_number = picture_number;

    /* Reset the average MB variance */

    s->me.mb_var_sum_temp    =

    s->me.mc_mb_var_sum_temp = 0;

    /* we need to initialize some time vars before we can encode b-frames */

    // RAL: Condition added for MPEG1VIDEO

    if (s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO || (s->h263_pred && !s->h263_msmpeg4))

        set_frame_distances(s);

    if(ENABLE_MPEG4_ENCODER && s->codec_id == CODEC_ID_MPEG4)

        ff_set_mpeg4_time(s);

    s->me.scene_change_score=0;

//    s->lambda= s->current_picture_ptr->quality; //FIXME qscale / ... stuff for ME rate distortion

    if(s->pict_type==FF_I_TYPE){

        if(s->msmpeg4_version >= 3) s->no_rounding=1;

        else                        s->no_rounding=0;

    }else if(s->pict_type!=FF_B_TYPE){

        if(s->flipflop_rounding || s->codec_id == CODEC_ID_H263P || s->codec_id == CODEC_ID_MPEG4)

            s->no_rounding ^= 1;

    }

    if(s->flags & CODEC_FLAG_PASS2){

        if (estimate_qp(s,1) < 0)

            return -1;

        ff_get_2pass_fcode(s);

    }else if(!(s->flags & CODEC_FLAG_QSCALE)){

        if(s->pict_type==FF_B_TYPE)

            s->lambda= s->last_lambda_for[s->pict_type];

        else

            s->lambda= s->last_lambda_for[s->last_non_b_pict_type];

        update_qscale(s);

    }

    s->mb_intra=0; //for the rate distortion & bit compare functions

    for(i=1; i<s->avctx->thread_count; i++){

        ff_update_duplicate_context(s->thread_context[i], s);

    }

    ff_init_me(s);

    /* Estimate motion for every MB */

    if(s->pict_type != FF_I_TYPE){

        s->lambda = (s->lambda * s->avctx->me_penalty_compensation + 128)>>8;

        s->lambda2= (s->lambda2* (int64_t)s->avctx->me_penalty_compensation + 128)>>8;

        if(s->pict_type != FF_B_TYPE && s->avctx->me_threshold==0){

            if((s->avctx->pre_me && s->last_non_b_pict_type==FF_I_TYPE) || s->avctx->pre_me==2){

                s->avctx->execute(s->avctx, pre_estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count);

            }

        }

        s->avctx->execute(s->avctx, estimate_motion_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count);

    }else /* if(s->pict_type == FF_I_TYPE) */{

        /* I-Frame */

        for(i=0; i<s->mb_stride*s->mb_height; i++)

            s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;

        if(!s->fixed_qscale){

            /* finding spatial complexity for I-frame rate control */

            s->avctx->execute(s->avctx, mb_var_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count);

        }

    }

    for(i=1; i<s->avctx->thread_count; i++){

        merge_context_after_me(s, s->thread_context[i]);

    }

    s->current_picture.mc_mb_var_sum= s->current_picture_ptr->mc_mb_var_sum= s->me.mc_mb_var_sum_temp;

    s->current_picture.   mb_var_sum= s->current_picture_ptr->   mb_var_sum= s->me.   mb_var_sum_temp;

    emms_c();

    if(s->me.scene_change_score > s->avctx->scenechange_threshold && s->pict_type == FF_P_TYPE){

        s->pict_type= FF_I_TYPE;

        for(i=0; i<s->mb_stride*s->mb_height; i++)

            s->mb_type[i]= CANDIDATE_MB_TYPE_INTRA;

//printf("Scene change detected, encoding as I Frame %d %d\n", s->current_picture.mb_var_sum, s->current_picture.mc_mb_var_sum);

    }

    if(!s->umvplus){

        if(s->pict_type==FF_P_TYPE || s->pict_type==FF_S_TYPE) {

            s->f_code= ff_get_best_fcode(s, s->p_mv_table, CANDIDATE_MB_TYPE_INTER);

            if(s->flags & CODEC_FLAG_INTERLACED_ME){

                int a,b;

                a= ff_get_best_fcode(s, s->p_field_mv_table[0][0], CANDIDATE_MB_TYPE_INTER_I); //FIXME field_select

                b= ff_get_best_fcode(s, s->p_field_mv_table[1][1], CANDIDATE_MB_TYPE_INTER_I);

                s->f_code= FFMAX3(s->f_code, a, b);

            }

            ff_fix_long_p_mvs(s);

            ff_fix_long_mvs(s, NULL, 0, s->p_mv_table, s->f_code, CANDIDATE_MB_TYPE_INTER, 0);

            if(s->flags & CODEC_FLAG_INTERLACED_ME){

                int j;

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

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

                        ff_fix_long_mvs(s, s->p_field_select_table[i], j,

                                        s->p_field_mv_table[i][j], s->f_code, CANDIDATE_MB_TYPE_INTER_I, 0);

                }

            }

        }

        if(s->pict_type==FF_B_TYPE){

            int a, b;

            a = ff_get_best_fcode(s, s->b_forw_mv_table, CANDIDATE_MB_TYPE_FORWARD);

            b = ff_get_best_fcode(s, s->b_bidir_forw_mv_table, CANDIDATE_MB_TYPE_BIDIR);

            s->f_code = FFMAX(a, b);

            a = ff_get_best_fcode(s, s->b_back_mv_table, CANDIDATE_MB_TYPE_BACKWARD);

            b = ff_get_best_fcode(s, s->b_bidir_back_mv_table, CANDIDATE_MB_TYPE_BIDIR);

            s->b_code = FFMAX(a, b);

            ff_fix_long_mvs(s, NULL, 0, s->b_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_FORWARD, 1);

            ff_fix_long_mvs(s, NULL, 0, s->b_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BACKWARD, 1);

            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_forw_mv_table, s->f_code, CANDIDATE_MB_TYPE_BIDIR, 1);

            ff_fix_long_mvs(s, NULL, 0, s->b_bidir_back_mv_table, s->b_code, CANDIDATE_MB_TYPE_BIDIR, 1);

            if(s->flags & CODEC_FLAG_INTERLACED_ME){

                int dir, j;

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

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

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

                            int type= dir ? (CANDIDATE_MB_TYPE_BACKWARD_I|CANDIDATE_MB_TYPE_BIDIR_I)

                                          : (CANDIDATE_MB_TYPE_FORWARD_I |CANDIDATE_MB_TYPE_BIDIR_I);

                            ff_fix_long_mvs(s, s->b_field_select_table[dir][i], j,

                                            s->b_field_mv_table[dir][i][j], dir ? s->b_code : s->f_code, type, 1);

                        }

                    }

                }

            }

        }

    }

    if (estimate_qp(s, 0) < 0)

        return -1;

    if(s->qscale < 3 && s->max_qcoeff<=128 && s->pict_type==FF_I_TYPE && !(s->flags & CODEC_FLAG_QSCALE))

        s->qscale= 3; //reduce clipping problems

    if (s->out_format == FMT_MJPEG) {

        /* for mjpeg, we do include qscale in the matrix */

        s->intra_matrix[0] = ff_mpeg1_default_intra_matrix[0];

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

            int j= s->dsp.idct_permutation[i];

            s->intra_matrix[j] = av_clip_uint8((ff_mpeg1_default_intra_matrix[i] * s->qscale) >> 3);

        }

        ff_convert_matrix(&s->dsp, s->q_intra_matrix, s->q_intra_matrix16,

                       s->intra_matrix, s->intra_quant_bias, 8, 8, 1);

        s->qscale= 8;

    }

    //FIXME var duplication

    s->current_picture_ptr->key_frame=

    s->current_picture.key_frame= s->pict_type == FF_I_TYPE; //FIXME pic_ptr

    s->current_picture_ptr->pict_type=

    s->current_picture.pict_type= s->pict_type;

    if(s->current_picture.key_frame)

        s->picture_in_gop_number=0;

    s->last_bits= put_bits_count(&s->pb);

    switch(s->out_format) {

    case FMT_MJPEG:

        if (ENABLE_MJPEG_ENCODER)

            ff_mjpeg_encode_picture_header(s);

        break;

    case FMT_H261:

        if (ENABLE_H261_ENCODER)

            ff_h261_encode_picture_header(s, picture_number);

        break;

    case FMT_H263:

        if (ENABLE_WMV2_ENCODER && s->codec_id == CODEC_ID_WMV2)

            ff_wmv2_encode_picture_header(s, picture_number);

        else if (ENABLE_MSMPEG4_ENCODER && s->h263_msmpeg4)

            msmpeg4_encode_picture_header(s, picture_number);

        else if (ENABLE_MPEG4_ENCODER && s->h263_pred)

            mpeg4_encode_picture_header(s, picture_number);

        else if (ENABLE_RV10_ENCODER && s->codec_id == CODEC_ID_RV10)

            rv10_encode_picture_header(s, picture_number);

        else if (ENABLE_RV20_ENCODER && s->codec_id == CODEC_ID_RV20)

            rv20_encode_picture_header(s, picture_number);

        else if (ENABLE_FLV_ENCODER && s->codec_id == CODEC_ID_FLV1)

            ff_flv_encode_picture_header(s, picture_number);

        else if (ENABLE_ANY_H263_ENCODER)

            h263_encode_picture_header(s, picture_number);

        break;

    case FMT_MPEG1:

        if (ENABLE_MPEG1VIDEO_ENCODER || ENABLE_MPEG2VIDEO_ENCODER)

            mpeg1_encode_picture_header(s, picture_number);

        break;

    case FMT_H264:

        break;

    default:

        assert(0);

    }

    bits= put_bits_count(&s->pb);

    s->header_bits= bits - s->last_bits;

    for(i=1; i<s->avctx->thread_count; i++){

        update_duplicate_context_after_me(s->thread_context[i], s);

    }

    s->avctx->execute(s->avctx, encode_thread, (void**)&(s->thread_context[0]), NULL, s->avctx->thread_count);

    for(i=1; i<s->avctx->thread_count; i++){

        merge_context_after_encode(s, s->thread_context[i]);

    }

    emms_c();

    return 0;

}


static void stellaris_enet_cleanup(NetClientState *nc)

{

    stellaris_enet_state *s = qemu_get_nic_opaque(nc);

    s->nic = NULL;

}


DISAS_INSN(scc)

{

    int l1;

    int cond;

    TCGv reg;

    l1 = gen_new_label();

    cond = (insn >> 8) & 0xf;

    reg = DREG(insn, 0);

    tcg_gen_andi_i32(reg, reg, 0xffffff00);

    /* This is safe because we modify the reg directly, with no other values

       live.  */

    gen_jmpcc(s, cond ^ 1, l1);

    tcg_gen_ori_i32(reg, reg, 0xff);

    gen_set_label(l1);

}


static int usb_host_scan(void *opaque, USBScanFunc *func)

{

    Monitor *mon = cur_mon;

    FILE *f = NULL;

    DIR *dir = NULL;

    int ret = 0;

    const char *fs_type[] = {"unknown", "proc", "dev", "sys"};

    char devpath[PATH_MAX];

    /* only check the host once */

    if (!usb_fs_type) {

        dir = opendir(USBSYSBUS_PATH "/devices");

        if (dir) {

            /* devices found in /dev/bus/usb/ (yes - not a mistake!) */

            strcpy(devpath, USBDEVBUS_PATH);

            usb_fs_type = USB_FS_SYS;

            closedir(dir);

            dprintf(USBDBG_DEVOPENED, USBSYSBUS_PATH);

            goto found_devices;

        }

        f = fopen(USBPROCBUS_PATH "/devices", "r");

        if (f) {

            /* devices found in /proc/bus/usb/ */

            strcpy(devpath, USBPROCBUS_PATH);

            usb_fs_type = USB_FS_PROC;

            fclose(f);

            dprintf(USBDBG_DEVOPENED, USBPROCBUS_PATH);

            goto found_devices;

        }

        /* try additional methods if an access method hasn't been found yet */

        f = fopen(USBDEVBUS_PATH "/devices", "r");

        if (f) {

            /* devices found in /dev/bus/usb/ */

            strcpy(devpath, USBDEVBUS_PATH);

            usb_fs_type = USB_FS_DEV;

            fclose(f);

            dprintf(USBDBG_DEVOPENED, USBDEVBUS_PATH);

            goto found_devices;

        }

    found_devices:

        if (!usb_fs_type) {

            monitor_printf(mon, "husb: unable to access USB devices\n");

            return -ENOENT;

        }

        /* the module setting (used later for opening devices) */

        usb_host_device_path = qemu_mallocz(strlen(devpath)+1);

        strcpy(usb_host_device_path, devpath);

        monitor_printf(mon, "husb: using %s file-system with %s\n",

                       fs_type[usb_fs_type], usb_host_device_path);

    }

    switch (usb_fs_type) {

    case USB_FS_PROC:

    case USB_FS_DEV:

        ret = usb_host_scan_dev(opaque, func);

        break;

    case USB_FS_SYS:

        ret = usb_host_scan_sys(opaque, func);

        break;

    default:

        ret = -EINVAL;

        break;

    }

    return ret;

}


static int scsi_cd_initfn(SCSIDevice *dev)

{

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);

    s->qdev.blocksize = 2048;

    s->qdev.type = TYPE_ROM;

    s->features |= 1 << SCSI_DISK_F_REMOVABLE;

    if (!s->product) {

        s->product = g_strdup("QEMU CD-ROM");

    }

    return scsi_initfn(&s->qdev);

}


static void msix_table_mmio_write(void *opaque, target_phys_addr_t addr,

                                  uint64_t val, unsigned size)

{

    PCIDevice *dev = opaque;

    int vector = addr / PCI_MSIX_ENTRY_SIZE;

    bool was_masked;

    was_masked = msix_is_masked(dev, vector);

    pci_set_long(dev->msix_table + addr, val);

    msix_handle_mask_update(dev, vector, was_masked);

}


static void encrypted_bdrv_it(void *opaque, BlockDriverState *bs)

{

    Error **errp = opaque;

    if (!error_is_set(errp) && bdrv_key_required(bs)) {

        error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs),

                  bdrv_get_encrypted_filename(bs));

    }

}


void virtio_scsi_dataplane_stop(VirtIOSCSI *s)

{

    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(s)));

    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);

    VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s);

    int i;

    /* Better luck next time. */

    if (s->dataplane_fenced) {

        s->dataplane_fenced = false;

        return;

    }

    if (!s->dataplane_started || s->dataplane_stopping) {

        return;

    }

    s->dataplane_stopping = true;

    assert(s->ctx == iothread_get_aio_context(vs->conf.iothread));

    aio_context_acquire(s->ctx);

    aio_set_event_notifier(s->ctx, &s->ctrl_vring->host_notifier,

                           false, NULL);

    aio_set_event_notifier(s->ctx, &s->event_vring->host_notifier,

                           false, NULL);

    for (i = 0; i < vs->conf.num_queues; i++) {

        aio_set_event_notifier(s->ctx, &s->cmd_vrings[i]->host_notifier,

                               false, NULL);

    }

    blk_drain_all(); /* ensure there are no in-flight requests */

    aio_context_release(s->ctx);

    /* Sync vring state back to virtqueue so that non-dataplane request

     * processing can continue when we disable the host notifier below.

     */

    virtio_scsi_vring_teardown(s);

    for (i = 0; i < vs->conf.num_queues + 2; i++) {

        k->set_host_notifier(qbus->parent, i, false);

    }

    /* Clean up guest notifier (irq) */

    k->set_guest_notifiers(qbus->parent, vs->conf.num_queues + 2, false);

    s->dataplane_stopping = false;

    s->dataplane_started = false;

}


static void spitz_common_init(int ram_size, int vga_ram_size,

                DisplayState *ds, const char *kernel_filename,

                const char *kernel_cmdline, const char *initrd_filename,

                enum spitz_model_e model, int arm_id)

{

    uint32_t spitz_ram = 0x04000000;

    uint32_t spitz_rom = 0x00800000;

    struct pxa2xx_state_s *cpu;

    struct scoop_info_s *scp;

    cpu = pxa270_init(ds, (model == terrier) ? "c5" : "c0");

    /* Setup memory */

    if (ram_size < spitz_ram + spitz_rom) {

        fprintf(stderr, "This platform requires %i bytes of memory\n",

                        spitz_ram + spitz_rom);

        exit(1);

    }

    cpu_register_physical_memory(PXA2XX_RAM_BASE, spitz_ram, IO_MEM_RAM);

    sl_flash_register(cpu, (model == spitz) ? FLASH_128M : FLASH_1024M);

    cpu_register_physical_memory(0, spitz_rom, spitz_ram | IO_MEM_ROM);

    /* Setup peripherals */

    spitz_keyboard_register(cpu);

    spitz_ssp_attach(cpu);

    scp = spitz_scoop_init(cpu, (model == akita) ? 1 : 2);

    spitz_scoop_gpio_setup(cpu, scp, (model == akita) ? 1 : 2);

    spitz_gpio_setup(cpu, (model == akita) ? 1 : 2);

    if (model == terrier)

        /* A 6.0 GB microdrive is permanently sitting in CF slot 0.  */

        spitz_microdrive_attach(cpu);

    else if (model != akita)

        /* A 4.0 GB microdrive is permanently sitting in CF slot 0.  */

        spitz_microdrive_attach(cpu);

    /* Setup initial (reset) machine state */

    cpu->env->regs[15] = PXA2XX_RAM_BASE;

    arm_load_kernel(cpu->env, ram_size, kernel_filename, kernel_cmdline,

                    initrd_filename, arm_id, PXA2XX_RAM_BASE);

    sl_bootparam_write(SL_PXA_PARAM_BASE - PXA2XX_RAM_BASE);

}


static void run_test(void)

{

    unsigned int remaining;

    int i;

    while (atomic_read(&n_ready_threads) != n_rw_threads + n_rz_threads) {

        cpu_relax();

    }

    atomic_mb_set(&test_start, true);

    do {

        remaining = sleep(duration);

    } while (remaining);

    atomic_mb_set(&test_stop, true);

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

        qemu_thread_join(&rw_threads[i]);

    }

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

        qemu_thread_join(&rz_threads[i]);

    }

}


static void leon3_generic_hw_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    SPARCCPU *cpu;

    CPUSPARCState   *env;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    MemoryRegion *prom = g_new(MemoryRegion, 1);

    int         ret;

    char       *filename;

    qemu_irq   *cpu_irqs = NULL;

    int         bios_size;

    int         prom_size;

    ResetData  *reset_info;

    /* Init CPU */

    if (!cpu_model) {

        cpu_model = "LEON3";

    }

    cpu = cpu_sparc_init(cpu_model);

    if (cpu == NULL) {

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

        exit(1);

    }

    env = &cpu->env;

    cpu_sparc_set_id(env, 0);

    /* Reset data */

    reset_info        = g_malloc0(sizeof(ResetData));

    reset_info->cpu   = cpu;

    reset_info->sp    = 0x40000000 + ram_size;

    qemu_register_reset(main_cpu_reset, reset_info);

    /* Allocate IRQ manager */

    grlib_irqmp_create(0x80000200, env, &cpu_irqs, MAX_PILS, &leon3_set_pil_in);

    env->qemu_irq_ack = leon3_irq_manager;

    /* Allocate RAM */

    if ((uint64_t)ram_size > (1UL << 30)) {

        fprintf(stderr,

                "qemu: Too much memory for this machine: %d, maximum 1G\n",

                (unsigned int)(ram_size / (1024 * 1024)));

        exit(1);

    }

    memory_region_init_ram(ram, NULL, "leon3.ram", ram_size, &error_abort);

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(address_space_mem, 0x40000000, ram);

    /* Allocate BIOS */

    prom_size = 8 * 1024 * 1024; /* 8Mb */

    memory_region_init_ram(prom, NULL, "Leon3.bios", prom_size, &error_abort);

    vmstate_register_ram_global(prom);

    memory_region_set_readonly(prom, true);

    memory_region_add_subregion(address_space_mem, 0x00000000, prom);

    /* Load boot prom */

    if (bios_name == NULL) {

        bios_name = PROM_FILENAME;

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

    bios_size = get_image_size(filename);

    if (bios_size > prom_size) {

        fprintf(stderr, "qemu: could not load prom '%s': file too big\n",

                filename);

        exit(1);

    }

    if (bios_size > 0) {

        ret = load_image_targphys(filename, 0x00000000, bios_size);

        if (ret < 0 || ret > prom_size) {

            fprintf(stderr, "qemu: could not load prom '%s'\n", filename);

            exit(1);

        }

    } else if (kernel_filename == NULL && !qtest_enabled()) {

        fprintf(stderr, "Can't read bios image %s\n", filename);

        exit(1);

    }

    /* Can directly load an application. */

    if (kernel_filename != NULL) {

        long     kernel_size;

        uint64_t entry;

        kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,

                               1 /* big endian */, ELF_MACHINE, 0);

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    kernel_filename);

            exit(1);

        }

        if (bios_size <= 0) {

            /* If there is no bios/monitor, start the application.  */

            env->pc = entry;

            env->npc = entry + 4;

            reset_info->entry = entry;

        }

    }

    /* Allocate timers */

    grlib_gptimer_create(0x80000300, 2, CPU_CLK, cpu_irqs, 6);

    /* Allocate uart */

    if (serial_hds[0]) {

        grlib_apbuart_create(0x80000100, serial_hds[0], cpu_irqs[3]);

    }

}


static int assign_intx(AssignedDevice *dev, Error **errp)

{

    AssignedIRQType new_type;

    PCIINTxRoute intx_route;

    bool intx_host_msi;

    int r;

    Error *local_err = NULL;

    /* Interrupt PIN 0 means don't use INTx */

    if (assigned_dev_pci_read_byte(&dev->dev, PCI_INTERRUPT_PIN) == 0) {

        pci_device_set_intx_routing_notifier(&dev->dev, NULL);

        return 0;

    }

    verify_irqchip_in_kernel(&local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return -ENOTSUP;

    }

    pci_device_set_intx_routing_notifier(&dev->dev,

                                         assigned_dev_update_irq_routing);

    intx_route = pci_device_route_intx_to_irq(&dev->dev, dev->intpin);

    assert(intx_route.mode != PCI_INTX_INVERTED);

    if (!pci_intx_route_changed(&dev->intx_route, &intx_route)) {

        return 0;

    }

    switch (dev->assigned_irq_type) {

    case ASSIGNED_IRQ_INTX_HOST_INTX:

    case ASSIGNED_IRQ_INTX_HOST_MSI:

        intx_host_msi = dev->assigned_irq_type == ASSIGNED_IRQ_INTX_HOST_MSI;

        r = kvm_device_intx_deassign(kvm_state, dev->dev_id, intx_host_msi);

        break;

    case ASSIGNED_IRQ_MSI:

        r = kvm_device_msi_deassign(kvm_state, dev->dev_id);

        break;

    case ASSIGNED_IRQ_MSIX:

        r = kvm_device_msix_deassign(kvm_state, dev->dev_id);

        break;

    default:

        r = 0;

        break;

    }

    if (r) {

        perror("assign_intx: deassignment of previous interrupt failed");

    }

    dev->assigned_irq_type = ASSIGNED_IRQ_NONE;

    if (intx_route.mode == PCI_INTX_DISABLED) {

        dev->intx_route = intx_route;

        return 0;

    }

retry:

    if (dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK &&

        dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) {

        intx_host_msi = true;

        new_type = ASSIGNED_IRQ_INTX_HOST_MSI;

    } else {

        intx_host_msi = false;

        new_type = ASSIGNED_IRQ_INTX_HOST_INTX;

    }

    r = kvm_device_intx_assign(kvm_state, dev->dev_id, intx_host_msi,

                               intx_route.irq);

    if (r < 0) {

        if (r == -EIO && !(dev->features & ASSIGNED_DEVICE_PREFER_MSI_MASK) &&

            dev->cap.available & ASSIGNED_DEVICE_CAP_MSI) {

            /* Retry with host-side MSI. There might be an IRQ conflict and

             * either the kernel or the device doesn't support sharing. */

            error_report("Host-side INTx sharing not supported, "

                         "using MSI instead");

            error_printf("Some devices do not work properly in this mode.\n");

            dev->features |= ASSIGNED_DEVICE_PREFER_MSI_MASK;

            goto retry;

        }

        error_setg_errno(errp, -r, "Failed to assign irq for \"%s\"",

                         dev->dev.qdev.id);

        error_append_hint(errp, "Perhaps you are assigning a device "

                          "that shares an IRQ with another device?\n");

        return r;

    }

    dev->intx_route = intx_route;

    dev->assigned_irq_type = new_type;

    return r;

}


static void gen_tlbwe_40x(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    switch (rB(ctx->opcode)) {

    case 0:

        gen_helper_4xx_tlbwe_hi(cpu_env, cpu_gpr[rA(ctx->opcode)],

                                cpu_gpr[rS(ctx->opcode)]);

        break;

    case 1:

        gen_helper_4xx_tlbwe_lo(cpu_env, cpu_gpr[rA(ctx->opcode)],

                                cpu_gpr[rS(ctx->opcode)]);

        break;

    default:

        gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);

        break;

    }

#endif

}


int qemu_sem_timedwait(QemuSemaphore *sem, int ms)

{

    int rc;

    struct timespec ts;

#if defined(__APPLE__) || defined(__NetBSD__)

    compute_abs_deadline(&ts, ms);

    pthread_mutex_lock(&sem->lock);

    --sem->count;

    while (sem->count < 0) {

        rc = pthread_cond_timedwait(&sem->cond, &sem->lock, &ts);

        if (rc == ETIMEDOUT) {

            break;

        }

        if (rc != 0) {

            error_exit(rc, __func__);

        }

    }

    pthread_mutex_unlock(&sem->lock);

    return (rc == ETIMEDOUT ? -1 : 0);

#else

    if (ms <= 0) {

        /* This is cheaper than sem_timedwait.  */

        do {

            rc = sem_trywait(&sem->sem);

        } while (rc == -1 && errno == EINTR);

        if (rc == -1 && errno == EAGAIN) {

            return -1;

        }

    } else {

        compute_abs_deadline(&ts, ms);

        do {

            rc = sem_timedwait(&sem->sem, &ts);

        } while (rc == -1 && errno == EINTR);

        if (rc == -1 && errno == ETIMEDOUT) {

            return -1;

        }

    }

    if (rc < 0) {

        error_exit(errno, __func__);

    }

    return 0;

#endif

}


static void spatial_compose97i_dy(dwt_compose_t *cs, DWTELEM *buffer, int width, int height, int stride){

    int y = cs->y;

    DWTELEM *b0= cs->b0;

    DWTELEM *b1= cs->b1;

    DWTELEM *b2= cs->b2;

    DWTELEM *b3= cs->b3;

    DWTELEM *b4= buffer + mirror(y+3, height-1)*stride;

    DWTELEM *b5= buffer + mirror(y+4, height-1)*stride;

        if(stride == width && y+4 < height && 0){

            int x;

            for(x=0; x<width/2; x++)

                b5[x] += 64*2;

            for(; x<width; x++)

                b5[x] += 169*2;

        }

{START_TIMER

        if(b3 <= b5) vertical_compose97iL1(b3, b4, b5, width);

        if(b2 <= b4) vertical_compose97iH1(b2, b3, b4, width);

        if(b1 <= b3) vertical_compose97iL0(b1, b2, b3, width);

        if(b0 <= b2) vertical_compose97iH0(b0, b1, b2, width);

if(width>400){

STOP_TIMER("vertical_compose97i")}}

{START_TIMER

        if(y-1>=  0) horizontal_compose97i(b0, width);

        if(b0 <= b2) horizontal_compose97i(b1, width);

if(width>400 && b0 <= b2){

STOP_TIMER("horizontal_compose97i")}}

    cs->b0=b2;

    cs->b1=b3;

    cs->b2=b4;

    cs->b3=b5;

    cs->y += 2;

}


static int nbd_co_receive_request(NBDRequestData *req, NBDRequest *request,

                                  Error **errp)

{

    NBDClient *client = req->client;

    int valid_flags;

    g_assert(qemu_in_coroutine());

    assert(client->recv_coroutine == qemu_coroutine_self());

    if (nbd_receive_request(client->ioc, request, errp) < 0) {

        return -EIO;

    }

    trace_nbd_co_receive_request_decode_type(request->handle, request->type,

                                             nbd_cmd_lookup(request->type));

    if (request->type != NBD_CMD_WRITE) {

        /* No payload, we are ready to read the next request.  */

        req->complete = true;

    }

    if (request->type == NBD_CMD_DISC) {

        /* Special case: we're going to disconnect without a reply,

         * whether or not flags, from, or len are bogus */

        return -EIO;

    }

    /* Check for sanity in the parameters, part 1.  Defer as many

     * checks as possible until after reading any NBD_CMD_WRITE

     * payload, so we can try and keep the connection alive.  */

    if ((request->from + request->len) < request->from) {

        error_setg(errp,

                   "integer overflow detected, you're probably being attacked");

        return -EINVAL;

    }

    if (request->type == NBD_CMD_READ || request->type == NBD_CMD_WRITE) {

        if (request->len > NBD_MAX_BUFFER_SIZE) {

            error_setg(errp, "len (%" PRIu32" ) is larger than max len (%u)",

                       request->len, NBD_MAX_BUFFER_SIZE);

            return -EINVAL;

        }

        req->data = blk_try_blockalign(client->exp->blk, request->len);

        if (req->data == NULL) {

            error_setg(errp, "No memory");

            return -ENOMEM;

        }

    }

    if (request->type == NBD_CMD_WRITE) {

        if (nbd_read(client->ioc, req->data, request->len, errp) < 0) {

            error_prepend(errp, "reading from socket failed: ");

            return -EIO;

        }

        req->complete = true;

        trace_nbd_co_receive_request_payload_received(request->handle,

                                                      request->len);

    }

    /* Sanity checks, part 2. */

    if (request->from + request->len > client->exp->size) {

        error_setg(errp, "operation past EOF; From: %" PRIu64 ", Len: %" PRIu32

                   ", Size: %" PRIu64, request->from, request->len,

                   (uint64_t)client->exp->size);

        return request->type == NBD_CMD_WRITE ? -ENOSPC : -EINVAL;

    }

    valid_flags = NBD_CMD_FLAG_FUA;

    if (request->type == NBD_CMD_READ && client->structured_reply) {

        valid_flags |= NBD_CMD_FLAG_DF;

    } else if (request->type == NBD_CMD_WRITE_ZEROES) {

        valid_flags |= NBD_CMD_FLAG_NO_HOLE;

    }

    if (request->flags & ~valid_flags) {

        error_setg(errp, "unsupported flags for command %s (got 0x%x)",

                   nbd_cmd_lookup(request->type), request->flags);

        return -EINVAL;

    }

    return 0;

}