static coroutine_fn int qcow2_co_pdiscard(BlockDriverState *bs,

                                          int64_t offset, int count)

{

    int ret;

    BDRVQcow2State *s = bs->opaque;

    if (!QEMU_IS_ALIGNED(offset | count, s->cluster_size)) {

        assert(count < s->cluster_size);

        return -ENOTSUP;

    }

    qemu_co_mutex_lock(&s->lock);

    ret = qcow2_discard_clusters(bs, offset, count >> BDRV_SECTOR_BITS,

                                 QCOW2_DISCARD_REQUEST, false);

    qemu_co_mutex_unlock(&s->lock);

    return ret;

}


void stb_tce(VIOsPAPRDevice *dev, uint64_t taddr, uint8_t val)

{

    spapr_tce_dma_write(dev, taddr, &val, sizeof(val));

}


static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest)

{

    int blockx, blocky, x, y;

    int luma = 0;

    int height = FFMIN(avctx->height, C64YRES);

    int width  = FFMIN(avctx->width , C64XRES);

    uint8_t *src = p->data[0];

    for (blocky = 0; blocky < C64YRES; blocky += 8) {

        for (blockx = 0; blockx < C64XRES; blockx += 8) {

            for (y = blocky; y < blocky + 8 && y < C64YRES; y++) {

                for (x = blockx; x < blockx + 8 && x < C64XRES; x += 2) {

                    if(x < width && y < height) {

                        /* build average over 2 pixels */

                        luma = (src[(x + 0 + y * p->linesize[0])] +

                                src[(x + 1 + y * p->linesize[0])]) / 2;

                        /* write blocks as linear data now so they are suitable for elbg */

                        dest[0] = luma;

                    }

                    dest++;

                }

            }

        }

    }

}


static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt)

{

    KLVPacket klv;

    MXFContext *mxf = s->priv_data;

    int ret;

    while ((ret = klv_read_packet(&klv, s->pb)) == 0) {

        PRINT_KEY(s, "read packet", klv.key);

        av_log(s, AV_LOG_TRACE, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);

        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {

            ret = mxf_decrypt_triplet(s, pkt, &klv);

            if (ret < 0) {

                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");

                return ret;

            }

            return 0;

        }

        if (IS_KLV_KEY(klv.key, mxf_essence_element_key) ||

            IS_KLV_KEY(klv.key, mxf_canopus_essence_element_key) ||

            IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) {

            int index = mxf_get_stream_index(s, &klv);

            int64_t next_ofs, next_klv;

            AVStream *st;

            MXFTrack *track;

            AVCodecParameters *par;

            if (index < 0) {

                av_log(s, AV_LOG_ERROR,

                       "error getting stream index %"PRIu32"\n",

                       AV_RB32(klv.key + 12));

                goto skip;

            }

            st = s->streams[index];

            track = st->priv_data;

            if (s->streams[index]->discard == AVDISCARD_ALL)

                goto skip;

            next_klv = avio_tell(s->pb) + klv.length;

            next_ofs = mxf_set_current_edit_unit(mxf, klv.offset);

            if (next_ofs >= 0 && next_klv > next_ofs) {

                /* if this check is hit then it's possible OPAtom was treated as OP1a

                 * truncate the packet since it's probably very large (>2 GiB is common) */

                avpriv_request_sample(s,

                                      "OPAtom misinterpreted as OP1a? "

                                      "KLV for edit unit %i extending into "

                                      "next edit unit",

                                      mxf->current_edit_unit);

                klv.length = next_ofs - avio_tell(s->pb);

            }

            /* check for 8 channels AES3 element */

            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {

                ret = mxf_get_d10_aes3_packet(s->pb, s->streams[index],

                                              pkt, klv.length);

                if (ret < 0) {

                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");

                    return ret;

                }

            } else {

                ret = av_get_packet(s->pb, pkt, klv.length);

                if (ret < 0)

                    return ret;

            }

            pkt->stream_index = index;

            pkt->pos = klv.offset;

            par = st->codecpar;

            if (par->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) {

                /* mxf->current_edit_unit good - see if we have an

                 * index table to derive timestamps from */

                MXFIndexTable *t = &mxf->index_tables[0];

                if (mxf->nb_index_tables >= 1 && mxf->current_edit_unit < t->nb_ptses) {

                    pkt->dts = mxf->current_edit_unit + t->first_dts;

                    pkt->pts = t->ptses[mxf->current_edit_unit];

                } else if (track->intra_only) {

                    /* intra-only -> PTS = EditUnit.

                     * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */

                    pkt->pts = mxf->current_edit_unit;

                }

            } else if (par->codec_type == AVMEDIA_TYPE_AUDIO) {

                ret = mxf_set_audio_pts(mxf, par, pkt);

                if (ret < 0)

                    return ret;

            }

            /* seek for truncated packets */

            avio_seek(s->pb, next_klv, SEEK_SET);

            return 0;

        } else

        skip:

            avio_skip(s->pb, klv.length);

    }

    return avio_feof(s->pb) ? AVERROR_EOF : ret;

}


static int vorbis_floor1_decode(vorbis_context *vc,

                                vorbis_floor_data *vfu, float *vec)

{

    vorbis_floor1 *vf = &vfu->t1;

    GetBitContext *gb = &vc->gb;

    uint16_t range_v[4] = { 256, 128, 86, 64 };

    unsigned range = range_v[vf->multiplier - 1];

    uint16_t floor1_Y[258];

    uint16_t floor1_Y_final[258];

    int floor1_flag[258];

    unsigned partition_class, cdim, cbits, csub, cval, offset, i, j;

    int book, adx, ady, dy, off, predicted, err;

    if (!get_bits1(gb)) // silence

        return 1;

// Read values (or differences) for the floor's points

    floor1_Y[0] = get_bits(gb, ilog(range - 1));

    floor1_Y[1] = get_bits(gb, ilog(range - 1));

    av_dlog(NULL, "floor 0 Y %d floor 1 Y %d \n", floor1_Y[0], floor1_Y[1]);

    offset = 2;

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

        partition_class = vf->partition_class[i];

        cdim   = vf->class_dimensions[partition_class];

        cbits  = vf->class_subclasses[partition_class];

        csub = (1 << cbits) - 1;

        cval = 0;

        av_dlog(NULL, "Cbits %u\n", cbits);

        if (cbits) // this reads all subclasses for this partition's class

            cval = get_vlc2(gb, vc->codebooks[vf->class_masterbook[partition_class]].vlc.table,

                            vc->codebooks[vf->class_masterbook[partition_class]].nb_bits, 3);

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

            book = vf->subclass_books[partition_class][cval & csub];

            av_dlog(NULL, "book %d Cbits %u cval %u  bits:%d\n",

                    book, cbits, cval, get_bits_count(gb));

            cval = cval >> cbits;

            if (book > -1) {

                floor1_Y[offset+j] = get_vlc2(gb, vc->codebooks[book].vlc.table,

                vc->codebooks[book].nb_bits, 3);

            } else {

                floor1_Y[offset+j] = 0;

            }

            av_dlog(NULL, " floor(%d) = %d \n",

                    vf->list[offset+j].x, floor1_Y[offset+j]);

        }

        offset+=cdim;

    }

// Amplitude calculation from the differences

    floor1_flag[0] = 1;

    floor1_flag[1] = 1;

    floor1_Y_final[0] = floor1_Y[0];

    floor1_Y_final[1] = floor1_Y[1];

    for (i = 2; i < vf->x_list_dim; ++i) {

        unsigned val, highroom, lowroom, room, high_neigh_offs, low_neigh_offs;

        low_neigh_offs  = vf->list[i].low;

        high_neigh_offs = vf->list[i].high;

        dy  = floor1_Y_final[high_neigh_offs] - floor1_Y_final[low_neigh_offs];  // render_point begin

        adx = vf->list[high_neigh_offs].x - vf->list[low_neigh_offs].x;

        ady = FFABS(dy);

        err = ady * (vf->list[i].x - vf->list[low_neigh_offs].x);

        off = err / adx;

        if (dy < 0) {

            predicted = floor1_Y_final[low_neigh_offs] - off;

        } else {

            predicted = floor1_Y_final[low_neigh_offs] + off;

        } // render_point end

        val = floor1_Y[i];

        highroom = range-predicted;

        lowroom  = predicted;

        if (highroom < lowroom) {

            room = highroom * 2;

        } else {

            room = lowroom * 2;   // SPEC misspelling

        }

        if (val) {

            floor1_flag[low_neigh_offs]  = 1;

            floor1_flag[high_neigh_offs] = 1;

            floor1_flag[i]               = 1;

            if (val >= room) {

                if (highroom > lowroom) {

                    floor1_Y_final[i] = av_clip_uint16(val - lowroom + predicted);

                } else {

                    floor1_Y_final[i] = av_clip_uint16(predicted - val + highroom - 1);

                }

            } else {

                if (val & 1) {

                    floor1_Y_final[i] = av_clip_uint16(predicted - (val + 1) / 2);

                } else {

                    floor1_Y_final[i] = av_clip_uint16(predicted + val / 2);

                }

            }

        } else {

            floor1_flag[i]    = 0;

            floor1_Y_final[i] = av_clip_uint16(predicted);

        }

        av_dlog(NULL, " Decoded floor(%d) = %u / val %u\n",

                vf->list[i].x, floor1_Y_final[i], val);

    }

// Curve synth - connect the calculated dots and convert from dB scale FIXME optimize ?

    ff_vorbis_floor1_render_list(vf->list, vf->x_list_dim, floor1_Y_final, floor1_flag, vf->multiplier, vec, vf->list[1].x);

    av_dlog(NULL, " Floor decoded\n");

    return 0;

}


static int doTest(uint8_t *ref[4], int refStride[4], int w, int h,

                  enum PixelFormat srcFormat, enum PixelFormat dstFormat,

                  int srcW, int srcH, int dstW, int dstH, int flags)

{

    static enum PixelFormat cur_srcFormat;

    static int cur_srcW, cur_srcH;

    static uint8_t *src[4];

    static int srcStride[4];

    uint8_t *dst[4] = {0};

    uint8_t *out[4] = {0};

    int dstStride[4];

    int i;

    uint64_t ssdY, ssdU=0, ssdV=0, ssdA=0;

    struct SwsContext *dstContext = NULL, *outContext = NULL;

    uint32_t crc = 0;

    int res = 0;

    if (cur_srcFormat != srcFormat || cur_srcW != srcW || cur_srcH != srcH) {

        struct SwsContext *srcContext = NULL;

        int p;

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

            if (src[p])

                av_freep(&src[p]);

        av_image_fill_linesizes(srcStride, srcFormat, srcW);

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

            if (srcStride[p])

                src[p] = av_mallocz(srcStride[p]*srcH+16);

            if (srcStride[p] && !src[p]) {

                perror("Malloc");

                res = -1;

                goto end;

            }

        }

        srcContext = sws_getContext(w, h, PIX_FMT_YUVA420P, srcW, srcH,

                                    srcFormat, SWS_BILINEAR, NULL, NULL, NULL);

        if (!srcContext) {

            fprintf(stderr, "Failed to get %s ---> %s\n",

                    av_pix_fmt_descriptors[PIX_FMT_YUVA420P].name,

                    av_pix_fmt_descriptors[srcFormat].name);

            res = -1;

            goto end;

        }

        sws_scale(srcContext, ref, refStride, 0, h, src, srcStride);

        sws_freeContext(srcContext);

        cur_srcFormat = srcFormat;

        cur_srcW = srcW;

        cur_srcH = srcH;

    }

    av_image_fill_linesizes(dstStride, dstFormat, dstW);

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

        /* Image buffers passed into libswscale can be allocated any way you

         * prefer, as long as they're aligned enough for the architecture, and

         * they're freed appropriately (such as using av_free for buffers

         * allocated with av_malloc). */

        /* An extra 16 bytes is being allocated because some scalers may write

         * out of bounds. */

        if (dstStride[i])

            dst[i]= av_mallocz(dstStride[i]*dstH+16);

        if (refStride[i])

            out[i]= av_mallocz(refStride[i]*h);

        if ((dstStride[i] && !dst[i]) || (refStride[i] && !out[i])) {

            perror("Malloc");

            res = -1;

            goto end;

        }

    }

    dstContext= sws_getContext(srcW, srcH, srcFormat, dstW, dstH, dstFormat, flags, NULL, NULL, NULL);

    if (!dstContext) {

        fprintf(stderr, "Failed to get %s ---> %s\n",

                av_pix_fmt_descriptors[srcFormat].name,

                av_pix_fmt_descriptors[dstFormat].name);

        res = -1;

        goto end;

    }

    outContext= sws_getContext(dstW, dstH, dstFormat, w, h, PIX_FMT_YUVA420P, flags, NULL, NULL, NULL);

    if (!outContext) {

        fprintf(stderr, "Failed to get %s ---> %s\n",

                av_pix_fmt_descriptors[dstFormat].name,

                av_pix_fmt_descriptors[PIX_FMT_YUVA420P].name);

        res = -1;

        goto end;

    }

//    printf("test %X %X %X -> %X %X %X\n", (int)ref[0], (int)ref[1], (int)ref[2],

//        (int)src[0], (int)src[1], (int)src[2]);

    printf(" %s %dx%d -> %s %3dx%3d flags=%2d",

           av_pix_fmt_descriptors[srcFormat].name, srcW, srcH,

           av_pix_fmt_descriptors[dstFormat].name, dstW, dstH,

           flags);

    fflush(stdout);

    sws_scale(dstContext, src, srcStride, 0, srcH, dst, dstStride);

    sws_scale(outContext, dst, dstStride, 0, dstH, out, refStride);

    for (i = 0; i < 4 && dstStride[i]; i++) {

        crc = av_crc(av_crc_get_table(AV_CRC_32_IEEE), crc, dst[i], dstStride[i] * dstH);

    }

    ssdY= getSSD(ref[0], out[0], refStride[0], refStride[0], w, h);

    if (hasChroma(srcFormat) && hasChroma(dstFormat)) {

        //FIXME check that output is really gray

        ssdU= getSSD(ref[1], out[1], refStride[1], refStride[1], (w+1)>>1, (h+1)>>1);

        ssdV= getSSD(ref[2], out[2], refStride[2], refStride[2], (w+1)>>1, (h+1)>>1);

    }

    if (isALPHA(srcFormat) && isALPHA(dstFormat))

        ssdA= getSSD(ref[3], out[3], refStride[3], refStride[3], w, h);

    ssdY/= w*h;

    ssdU/= w*h/4;

    ssdV/= w*h/4;

    ssdA/= w*h;

    printf(" CRC=%08x SSD=%5"PRId64",%5"PRId64",%5"PRId64",%5"PRId64"\n",

           crc, ssdY, ssdU, ssdV, ssdA);

end:

    sws_freeContext(dstContext);

    sws_freeContext(outContext);

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

        if (dstStride[i])

            av_free(dst[i]);

        if (refStride[i])

            av_free(out[i]);

    }

    return res;

}


static uint64_t pl061_read(void *opaque, hwaddr offset,

                           unsigned size)

{

    PL061State *s = (PL061State *)opaque;

    if (offset >= 0xfd0 && offset < 0x1000) {

        return s->id[(offset - 0xfd0) >> 2];

    }

    if (offset < 0x400) {

        return s->data & (offset >> 2);

    }

    switch (offset) {

    case 0x400: /* Direction */

        return s->dir;

    case 0x404: /* Interrupt sense */

        return s->isense;

    case 0x408: /* Interrupt both edges */

        return s->ibe;

    case 0x40c: /* Interrupt event */

        return s->iev;

    case 0x410: /* Interrupt mask */

        return s->im;

    case 0x414: /* Raw interrupt status */

        return s->istate;

    case 0x418: /* Masked interrupt status */

        return s->istate & s->im;

    case 0x420: /* Alternate function select */

        return s->afsel;

    case 0x500: /* 2mA drive */

        return s->dr2r;

    case 0x504: /* 4mA drive */

        return s->dr4r;

    case 0x508: /* 8mA drive */

        return s->dr8r;

    case 0x50c: /* Open drain */

        return s->odr;

    case 0x510: /* Pull-up */

        return s->pur;

    case 0x514: /* Pull-down */

        return s->pdr;

    case 0x518: /* Slew rate control */

        return s->slr;

    case 0x51c: /* Digital enable */

        return s->den;

    case 0x520: /* Lock */

        return s->locked;

    case 0x524: /* Commit */

        return s->cr;

    case 0x528: /* Analog mode select */

        return s->amsel;

    default:

        qemu_log_mask(LOG_GUEST_ERROR,

                      "pl061_read: Bad offset %x\n", (int)offset);

        return 0;

    }

}


void address_space_unmap(AddressSpace *as, void *buffer, hwaddr len,

                         int is_write, hwaddr access_len)

{

    if (buffer != bounce.buffer) {

        MemoryRegion *mr;

        ram_addr_t addr1;

        mr = qemu_ram_addr_from_host(buffer, &addr1);

        assert(mr != NULL);

        if (is_write) {

            while (access_len) {

                unsigned l;

                l = TARGET_PAGE_SIZE;

                if (l > access_len)

                    l = access_len;

                invalidate_and_set_dirty(addr1, l);

                addr1 += l;

                access_len -= l;

            }

        }

        if (xen_enabled()) {

            xen_invalidate_map_cache_entry(buffer);

        }

        memory_region_unref(mr);

        return;

    }

    if (is_write) {

        address_space_write(as, bounce.addr, bounce.buffer, access_len);

    }

    qemu_vfree(bounce.buffer);

    bounce.buffer = NULL;

    memory_region_unref(bounce.mr);

    cpu_notify_map_clients();

}


int qemu_savevm_state_complete(Monitor *mon, QEMUFile *f)

{

    SaveStateEntry *se;

    cpu_synchronize_all_states();

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {

        if (se->save_live_state == NULL)

            continue;

        /* Section type */

        qemu_put_byte(f, QEMU_VM_SECTION_END);

        qemu_put_be32(f, se->section_id);

        se->save_live_state(mon, f, QEMU_VM_SECTION_END, se->opaque);

    }

    QTAILQ_FOREACH(se, &savevm_handlers, entry) {

        int len;

	if (se->save_state == NULL && se->vmsd == NULL)

	    continue;

        /* Section type */

        qemu_put_byte(f, QEMU_VM_SECTION_FULL);

        qemu_put_be32(f, se->section_id);

        /* ID string */

        len = strlen(se->idstr);

        qemu_put_byte(f, len);

        qemu_put_buffer(f, (uint8_t *)se->idstr, len);

        qemu_put_be32(f, se->instance_id);

        qemu_put_be32(f, se->version_id);

        vmstate_save(f, se);

    }

    qemu_put_byte(f, QEMU_VM_EOF);

    return qemu_file_get_error(f);

}


clk_setup_cb cpu_ppc_tb_init (CPUState *env, uint32_t freq)

{

    ppc_tb_t *tb_env;

    tb_env = qemu_mallocz(sizeof(ppc_tb_t));

    if (tb_env == NULL)

        return NULL;

    env->tb_env = tb_env;

    /* Create new timer */

    tb_env->decr_timer = qemu_new_timer(vm_clock, &cpu_ppc_decr_cb, env);

#if defined(TARGET_PPC64H)

    tb_env->hdecr_timer = qemu_new_timer(vm_clock, &cpu_ppc_hdecr_cb, env);

#endif /* defined(TARGET_PPC64H) */

    cpu_ppc_set_tb_clk(env, freq);

    return &cpu_ppc_set_tb_clk;

}


bool qemu_clock_has_timers(QEMUClockType type)

{

    return timerlist_has_timers(

        main_loop_tlg.tl[type]);

}


static uint64_t pxa2xx_i2c_read(void *opaque, hwaddr addr,

                                unsigned size)

{

    PXA2xxI2CState *s = (PXA2xxI2CState *) opaque;

    I2CSlave *slave;

    addr -= s->offset;

    switch (addr) {

    case ICR:

        return s->control;

    case ISR:

        return s->status | (i2c_bus_busy(s->bus) << 2);

    case ISAR:

        slave = I2C_SLAVE(s->slave);

        return slave->address;

    case IDBR:

        return s->data;

    case IBMR:

        if (s->status & (1 << 2))

            s->ibmr ^= 3;	/* Fake SCL and SDA pin changes */

        else

            s->ibmr = 0;

        return s->ibmr;

    default:

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

        break;

    }

    return 0;

}


uint32_t ide_ioport_read(void *opaque, uint32_t addr1)

{

    IDEBus *bus = opaque;

    IDEState *s = idebus_active_if(bus);

    uint32_t addr;

    int ret, hob;

    addr = addr1 & 7;

    /* FIXME: HOB readback uses bit 7, but it's always set right now */

    //hob = s->select & (1 << 7);

    hob = 0;

    switch(addr) {

    case 0:

        ret = 0xff;

        break;

    case 1:

        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||

            (s != bus->ifs && !s->bs))

            ret = 0;

        else if (!hob)

            ret = s->error;

	else

	    ret = s->hob_feature;

        break;

    case 2:

        if (!bus->ifs[0].bs && !bus->ifs[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->nsector & 0xff;

	else

	    ret = s->hob_nsector;

        break;

    case 3:

        if (!bus->ifs[0].bs && !bus->ifs[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->sector;

	else

	    ret = s->hob_sector;

        break;

    case 4:

        if (!bus->ifs[0].bs && !bus->ifs[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->lcyl;

	else

	    ret = s->hob_lcyl;

        break;

    case 5:

        if (!bus->ifs[0].bs && !bus->ifs[1].bs)

            ret = 0;

        else if (!hob)

            ret = s->hcyl;

	else

	    ret = s->hob_hcyl;

        break;

    case 6:

        if (!bus->ifs[0].bs && !bus->ifs[1].bs)

            ret = 0;

        else

            ret = s->select;

        break;

    default:

    case 7:

        if ((!bus->ifs[0].bs && !bus->ifs[1].bs) ||

            (s != bus->ifs && !s->bs))

            ret = 0;

        else

            ret = s->status;

        qemu_irq_lower(bus->irq);

        break;

    }

#ifdef DEBUG_IDE

    printf("ide: read addr=0x%x val=%02x\n", addr1, ret);

#endif

    return ret;

}


static void disas_fp_2src(DisasContext *s, uint32_t insn)

{

    unsupported_encoding(s, insn);

}


static const char *io_port_to_string(uint32_t io_port)

{

    if (io_port >= QXL_IO_RANGE_SIZE) {

        return "out of range";

    }

    static const char *io_port_to_string[QXL_IO_RANGE_SIZE + 1] = {

        [QXL_IO_NOTIFY_CMD]             = "QXL_IO_NOTIFY_CMD",

        [QXL_IO_NOTIFY_CURSOR]          = "QXL_IO_NOTIFY_CURSOR",

        [QXL_IO_UPDATE_AREA]            = "QXL_IO_UPDATE_AREA",

        [QXL_IO_UPDATE_IRQ]             = "QXL_IO_UPDATE_IRQ",

        [QXL_IO_NOTIFY_OOM]             = "QXL_IO_NOTIFY_OOM",

        [QXL_IO_RESET]                  = "QXL_IO_RESET",

        [QXL_IO_SET_MODE]               = "QXL_IO_SET_MODE",

        [QXL_IO_LOG]                    = "QXL_IO_LOG",

        [QXL_IO_MEMSLOT_ADD]            = "QXL_IO_MEMSLOT_ADD",

        [QXL_IO_MEMSLOT_DEL]            = "QXL_IO_MEMSLOT_DEL",

        [QXL_IO_DETACH_PRIMARY]         = "QXL_IO_DETACH_PRIMARY",

        [QXL_IO_ATTACH_PRIMARY]         = "QXL_IO_ATTACH_PRIMARY",

        [QXL_IO_CREATE_PRIMARY]         = "QXL_IO_CREATE_PRIMARY",

        [QXL_IO_DESTROY_PRIMARY]        = "QXL_IO_DESTROY_PRIMARY",

        [QXL_IO_DESTROY_SURFACE_WAIT]   = "QXL_IO_DESTROY_SURFACE_WAIT",

        [QXL_IO_DESTROY_ALL_SURFACES]   = "QXL_IO_DESTROY_ALL_SURFACES",

#if SPICE_INTERFACE_QXL_MINOR >= 1

        [QXL_IO_UPDATE_AREA_ASYNC]      = "QXL_IO_UPDATE_AREA_ASYNC",

        [QXL_IO_MEMSLOT_ADD_ASYNC]      = "QXL_IO_MEMSLOT_ADD_ASYNC",

        [QXL_IO_CREATE_PRIMARY_ASYNC]   = "QXL_IO_CREATE_PRIMARY_ASYNC",

        [QXL_IO_DESTROY_PRIMARY_ASYNC]  = "QXL_IO_DESTROY_PRIMARY_ASYNC",

        [QXL_IO_DESTROY_SURFACE_ASYNC]  = "QXL_IO_DESTROY_SURFACE_ASYNC",

        [QXL_IO_DESTROY_ALL_SURFACES_ASYNC]

                                        = "QXL_IO_DESTROY_ALL_SURFACES_ASYNC",

        [QXL_IO_FLUSH_SURFACES_ASYNC]   = "QXL_IO_FLUSH_SURFACES_ASYNC",

        [QXL_IO_FLUSH_RELEASE]          = "QXL_IO_FLUSH_RELEASE",

#endif

    };

    return io_port_to_string[io_port];

}


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

{

    if (version_id != 1 && version_id != 2)

        return -EINVAL;

    if (cpu_ticks_enabled) {

        return -EINVAL;

    }

    cpu_ticks_offset=qemu_get_be64(f);

    ticks_per_sec=qemu_get_be64(f);

    if (version_id == 2) {

        cpu_clock_offset=qemu_get_be64(f);

    }

    return 0;

}


void omap_uwire_attach(struct omap_uwire_s *s,

                uWireSlave *slave, int chipselect)

{

    if (chipselect < 0 || chipselect > 3) {

        fprintf(stderr, "%s: Bad chipselect %i\n", __FUNCTION__, chipselect);

        exit(-1);

    }

    s->chip[chipselect] = slave;

}


int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max){

    AVRational a0={0,1}, a1={1,0};

    int sign= (num<0) ^ (den<0);

    int64_t gcd= av_gcd(FFABS(num), FFABS(den));

    if(gcd){

        num = FFABS(num)/gcd;

        den = FFABS(den)/gcd;

    }

    if(num<=max && den<=max){

        a1= (AVRational){num, den};

        den=0;

    }

    while(den){

        uint64_t x      = num / den;

        int64_t next_den= num - den*x;

        int64_t a2n= x*a1.num + a0.num;

        int64_t a2d= x*a1.den + a0.den;

        if(a2n > max || a2d > max){

            if(a1.num) x= (max - a0.num) / a1.num;

            if(a1.den) x= FFMIN(x, (max - a0.den) / a1.den);

            if (den*(2*x*a1.den + a0.den) > num*a1.den)

                a1 = (AVRational){x*a1.num + a0.num, x*a1.den + a0.den};

            break;

        }

        a0= a1;

        a1= (AVRational){a2n, a2d};

        num= den;

        den= next_den;

    }

    assert(av_gcd(a1.num, a1.den) <= 1U);

    *dst_num = sign ? -a1.num : a1.num;

    *dst_den = a1.den;

    return den==0;

}


static void sigp_cpu_restart(void *arg)

{

    CPUState *cs = arg;

    S390CPU *cpu = S390_CPU(cs);

    struct kvm_s390_irq irq = {

        .type = KVM_S390_RESTART,

    };

    kvm_s390_vcpu_interrupt(cpu, &irq);

    s390_cpu_set_state(CPU_STATE_OPERATING, cpu);

}


print_insn_arg (const char *d,

		unsigned char *buffer,

		unsigned char *p0,

		bfd_vma addr,

		disassemble_info *info)

{

  int val = 0;

  int place = d[1];

  unsigned char *p = p0;

  int regno;

  const char *regname;

  unsigned char *p1;

  double flval;

  int flt_p;

  bfd_signed_vma disp;

  unsigned int uval;

  switch (*d)

    {

    case 'c':		/* Cache identifier.  */

      {

        static const char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };

        val = fetch_arg (buffer, place, 2, info);

        (*info->fprintf_func) (info->stream, cacheFieldName[val]);

        break;

      }

    case 'a':		/* Address register indirect only. Cf. case '+'.  */

      {

        (*info->fprintf_func)

	  (info->stream,

	   "%s@",

	   reg_names[fetch_arg (buffer, place, 3, info) + 8]);

        break;

      }

    case '_':		/* 32-bit absolute address for move16.  */

      {

        uval = NEXTULONG (p);

	(*info->print_address_func) (uval, info);

        break;

      }

    case 'C':

      (*info->fprintf_func) (info->stream, "%%ccr");

      break;

    case 'S':

      (*info->fprintf_func) (info->stream, "%%sr");

      break;

    case 'U':

      (*info->fprintf_func) (info->stream, "%%usp");

      break;

    case 'E':

      (*info->fprintf_func) (info->stream, "%%acc");

      break;

    case 'G':

      (*info->fprintf_func) (info->stream, "%%macsr");

      break;

    case 'H':

      (*info->fprintf_func) (info->stream, "%%mask");

      break;

    case 'J':

      {

	/* FIXME: There's a problem here, different m68k processors call the

	   same address different names. This table can't get it right

	   because it doesn't know which processor it's disassembling for.  */

	static const struct { const char *name; int value; } names[]

	  = {{"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},

	     {"%tc",  0x003}, {"%itt0",0x004}, {"%itt1", 0x005},

             {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},

	     {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},

	     {"%msp", 0x803}, {"%isp", 0x804},

	     {"%flashbar", 0xc04}, {"%rambar", 0xc05}, /* mcf528x added these.  */

	     /* Should we be calling this psr like we do in case 'Y'?  */

	     {"%mmusr",0x805},

             {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808}};

	val = fetch_arg (buffer, place, 12, info);

	for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)

	  if (names[regno].value == val)

	    {

	      (*info->fprintf_func) (info->stream, "%s", names[regno].name);

	      break;

	    }

	if (regno < 0)

	  (*info->fprintf_func) (info->stream, "%d", val);

      }

      break;

    case 'Q':

      val = fetch_arg (buffer, place, 3, info);

      /* 0 means 8, except for the bkpt instruction... */

      if (val == 0 && d[1] != 's')

	val = 8;

      (*info->fprintf_func) (info->stream, "#%d", val);

      break;

    case 'x':

      val = fetch_arg (buffer, place, 3, info);

      /* 0 means -1.  */

      if (val == 0)

	val = -1;

      (*info->fprintf_func) (info->stream, "#%d", val);

      break;

    case 'M':

      if (place == 'h')

	{

	  static const char *const scalefactor_name[] = { "<<", ">>" };

	  val = fetch_arg (buffer, place, 1, info);

	  (*info->fprintf_func) (info->stream, scalefactor_name[val]);

	}

      else

	{

	  val = fetch_arg (buffer, place, 8, info);

	  if (val & 0x80)

	    val = val - 0x100;

	  (*info->fprintf_func) (info->stream, "#%d", val);

	}

      break;

    case 'T':

      val = fetch_arg (buffer, place, 4, info);

      (*info->fprintf_func) (info->stream, "#%d", val);

      break;

    case 'D':

      (*info->fprintf_func) (info->stream, "%s",

			     reg_names[fetch_arg (buffer, place, 3, info)]);

      break;

    case 'A':

      (*info->fprintf_func)

	(info->stream, "%s",

	 reg_names[fetch_arg (buffer, place, 3, info) + 010]);

      break;

    case 'R':

      (*info->fprintf_func)

	(info->stream, "%s",

	 reg_names[fetch_arg (buffer, place, 4, info)]);

      break;

    case 'r':

      regno = fetch_arg (buffer, place, 4, info);

      if (regno > 7)

	(*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);

      else

	(*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);

      break;

    case 'F':

      (*info->fprintf_func)

	(info->stream, "%%fp%d",

	 fetch_arg (buffer, place, 3, info));

      break;

    case 'O':

      val = fetch_arg (buffer, place, 6, info);

      if (val & 0x20)

	(*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);

      else

	(*info->fprintf_func) (info->stream, "%d", val);

      break;

    case '+':

      (*info->fprintf_func)

	(info->stream, "%s@+",

	 reg_names[fetch_arg (buffer, place, 3, info) + 8]);

      break;

    case '-':

      (*info->fprintf_func)

	(info->stream, "%s@-",

	 reg_names[fetch_arg (buffer, place, 3, info) + 8]);

      break;

    case 'k':

      if (place == 'k')

	(*info->fprintf_func)

	  (info->stream, "{%s}",

	   reg_names[fetch_arg (buffer, place, 3, info)]);

      else if (place == 'C')

	{

	  val = fetch_arg (buffer, place, 7, info);

	  if (val > 63)		/* This is a signed constant.  */

	    val -= 128;

	  (*info->fprintf_func) (info->stream, "{#%d}", val);

	}

      else

	return -2;

      break;

    case '#':

    case '^':

      p1 = buffer + (*d == '#' ? 2 : 4);

      if (place == 's')

	val = fetch_arg (buffer, place, 4, info);

      else if (place == 'C')

	val = fetch_arg (buffer, place, 7, info);

      else if (place == '8')

	val = fetch_arg (buffer, place, 3, info);

      else if (place == '3')

	val = fetch_arg (buffer, place, 8, info);

      else if (place == 'b')

	val = NEXTBYTE (p1);

      else if (place == 'w' || place == 'W')

	val = NEXTWORD (p1);

      else if (place == 'l')

	val = NEXTLONG (p1);

      else

	return -2;

      (*info->fprintf_func) (info->stream, "#%d", val);

      break;

    case 'B':

      if (place == 'b')

	disp = NEXTBYTE (p);

      else if (place == 'B')

	disp = COERCE_SIGNED_CHAR (buffer[1]);

      else if (place == 'w' || place == 'W')

	disp = NEXTWORD (p);

      else if (place == 'l' || place == 'L' || place == 'C')

	disp = NEXTLONG (p);

      else if (place == 'g')

	{

	  disp = NEXTBYTE (buffer);

	  if (disp == 0)

	    disp = NEXTWORD (p);

	  else if (disp == -1)

	    disp = NEXTLONG (p);

	}

      else if (place == 'c')

	{

	  if (buffer[1] & 0x40)		/* If bit six is one, long offset.  */

	    disp = NEXTLONG (p);

	  else

	    disp = NEXTWORD (p);

	}

      else

	return -2;

      (*info->print_address_func) (addr + disp, info);

      break;

    case 'd':

      val = NEXTWORD (p);

      (*info->fprintf_func)

	(info->stream, "%s@(%d)",

	 reg_names[fetch_arg (buffer, place, 3, info) + 8], val);

      break;

    case 's':

      (*info->fprintf_func) (info->stream, "%s",

			     fpcr_names[fetch_arg (buffer, place, 3, info)]);

      break;

    case 'e':

      val = fetch_arg(buffer, place, 2, info);

      (*info->fprintf_func) (info->stream, "%%acc%d", val);

      break;

    case 'g':

      val = fetch_arg(buffer, place, 1, info);

      (*info->fprintf_func) (info->stream, "%%accext%s", val==0 ? "01" : "23");

      break;

    case 'i':

      val = fetch_arg(buffer, place, 2, info);

      if (val == 1)

	(*info->fprintf_func) (info->stream, "<<");

      else if (val == 3)

	(*info->fprintf_func) (info->stream, ">>");

      else

	return -1;

      break;

    case 'I':

      /* Get coprocessor ID... */

      val = fetch_arg (buffer, 'd', 3, info);

      if (val != 1)				/* Unusual coprocessor ID?  */

	(*info->fprintf_func) (info->stream, "(cpid=%d) ", val);

      break;

    case '4':

    case '*':

    case '~':

    case '%':

    case ';':

    case '@':

    case '!':

    case '$':

    case '?':

    case '/':

    case '&':

    case '|':

    case '<':

    case '>':

    case 'm':

    case 'n':

    case 'o':

    case 'p':

    case 'q':

    case 'v':

    case 'b':

    case 'w':

    case 'y':

    case 'z':

      if (place == 'd')

	{

	  val = fetch_arg (buffer, 'x', 6, info);

	  val = ((val & 7) << 3) + ((val >> 3) & 7);

	}

      else

	val = fetch_arg (buffer, 's', 6, info);

      /* If the <ea> is invalid for *d, then reject this match.  */

      if (!m68k_valid_ea (*d, val))

	return -1;

      /* Get register number assuming address register.  */

      regno = (val & 7) + 8;

      regname = reg_names[regno];

      switch (val >> 3)

	{

	case 0:

	  (*info->fprintf_func) (info->stream, "%s", reg_names[val]);

	  break;

	case 1:

	  (*info->fprintf_func) (info->stream, "%s", regname);

	  break;

	case 2:

	  (*info->fprintf_func) (info->stream, "%s@", regname);

	  break;

	case 3:

	  (*info->fprintf_func) (info->stream, "%s@+", regname);

	  break;

	case 4:

	  (*info->fprintf_func) (info->stream, "%s@-", regname);

	  break;

	case 5:

	  val = NEXTWORD (p);

	  (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);

	  break;

	case 6:

	  p = print_indexed (regno, p, addr, info);

	  break;

	case 7:

	  switch (val & 7)

	    {

	    case 0:

	      val = NEXTWORD (p);

	      (*info->print_address_func) (val, info);

	      break;

	    case 1:

	      uval = NEXTULONG (p);

	      (*info->print_address_func) (uval, info);

	      break;

	    case 2:

	      val = NEXTWORD (p);

	      (*info->fprintf_func) (info->stream, "%%pc@(");

	      (*info->print_address_func) (addr + val, info);

	      (*info->fprintf_func) (info->stream, ")");

	      break;

	    case 3:

	      p = print_indexed (-1, p, addr, info);

	      break;

	    case 4:

	      flt_p = 1;	/* Assume it's a float... */

	      switch (place)

	      {

		case 'b':

		  val = NEXTBYTE (p);

		  flt_p = 0;

		  break;

		case 'w':

		  val = NEXTWORD (p);

		  flt_p = 0;

		  break;

		case 'l':

		  val = NEXTLONG (p);

		  flt_p = 0;

		  break;

		case 'f':

		  NEXTSINGLE (flval, p);

		  break;

		case 'F':

		  NEXTDOUBLE (flval, p);

		  break;

		case 'x':

		  NEXTEXTEND (flval, p);

		  break;

		case 'p':

		  flval = NEXTPACKED (p);

		  break;

		default:

		  return -1;

	      }

	      if (flt_p)	/* Print a float? */

		(*info->fprintf_func) (info->stream, "#%g", flval);

	      else

		(*info->fprintf_func) (info->stream, "#%d", val);

	      break;

	    default:

	      return -1;

	    }

	}

      /* If place is '/', then this is the case of the mask bit for

	 mac/emac loads. Now that the arg has been printed, grab the

	 mask bit and if set, add a '&' to the arg.  */

      if (place == '/')

	{

	  val = fetch_arg (buffer, place, 1, info);

	  if (val)

	    info->fprintf_func (info->stream, "&");

	}

      break;

    case 'L':

    case 'l':

	if (place == 'w')

	  {

	    char doneany;

	    p1 = buffer + 2;

	    val = NEXTWORD (p1);

	    /* Move the pointer ahead if this point is farther ahead

	       than the last.  */

	    p = p1 > p ? p1 : p;

	    if (val == 0)

	      {

		(*info->fprintf_func) (info->stream, "#0");

		break;

	      }

	    if (*d == 'l')

	      {

		int newval = 0;

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

		  if (val & (0x8000 >> regno))

		    newval |= 1 << regno;

		val = newval;

	      }

	    val &= 0xffff;

	    doneany = 0;

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

	      if (val & (1 << regno))

		{

		  int first_regno;

		  if (doneany)

		    (*info->fprintf_func) (info->stream, "/");

		  doneany = 1;

		  (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);

		  first_regno = regno;

		  while (val & (1 << (regno + 1)))

		    ++regno;

		  if (regno > first_regno)

		    (*info->fprintf_func) (info->stream, "-%s",

					   reg_names[regno]);

		}

	  }

	else if (place == '3')

	  {

	    /* `fmovem' insn.  */

	    char doneany;

	    val = fetch_arg (buffer, place, 8, info);

	    if (val == 0)

	      {

		(*info->fprintf_func) (info->stream, "#0");

		break;

	      }

	    if (*d == 'l')

	      {

		int newval = 0;

		for (regno = 0; regno < 8; ++regno)

		  if (val & (0x80 >> regno))

		    newval |= 1 << regno;

		val = newval;

	      }

	    val &= 0xff;

	    doneany = 0;

	    for (regno = 0; regno < 8; ++regno)

	      if (val & (1 << regno))

		{

		  int first_regno;

		  if (doneany)

		    (*info->fprintf_func) (info->stream, "/");

		  doneany = 1;

		  (*info->fprintf_func) (info->stream, "%%fp%d", regno);

		  first_regno = regno;

		  while (val & (1 << (regno + 1)))

		    ++regno;

		  if (regno > first_regno)

		    (*info->fprintf_func) (info->stream, "-%%fp%d", regno);

		}

	  }

	else if (place == '8')

	  {

	    /* fmoveml for FP status registers.  */

	    (*info->fprintf_func) (info->stream, "%s",

				   fpcr_names[fetch_arg (buffer, place, 3,

							 info)]);

	  }

	else

	  return -2;

      break;

    case 'X':

      place = '8';

    case 'Y':

    case 'Z':

    case 'W':

    case '0':

    case '1':

    case '2':

    case '3':

      {

	int val = fetch_arg (buffer, place, 5, info);

        const char *name = 0;

	switch (val)

	  {

	  case 2: name = "%tt0"; break;

	  case 3: name = "%tt1"; break;

	  case 0x10: name = "%tc"; break;

	  case 0x11: name = "%drp"; break;

	  case 0x12: name = "%srp"; break;

	  case 0x13: name = "%crp"; break;

	  case 0x14: name = "%cal"; break;

	  case 0x15: name = "%val"; break;

	  case 0x16: name = "%scc"; break;

	  case 0x17: name = "%ac"; break;

 	  case 0x18: name = "%psr"; break;

	  case 0x19: name = "%pcsr"; break;

	  case 0x1c:

	  case 0x1d:

	    {

	      int break_reg = ((buffer[3] >> 2) & 7);

	      (*info->fprintf_func)

		(info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",

		 break_reg);

	    }

	    break;

	  default:

	    (*info->fprintf_func) (info->stream, "<mmu register %d>", val);

	  }

	if (name)

	  (*info->fprintf_func) (info->stream, "%s", name);

      }

      break;

    case 'f':

      {

	int fc = fetch_arg (buffer, place, 5, info);

	if (fc == 1)

	  (*info->fprintf_func) (info->stream, "%%dfc");

	else if (fc == 0)

	  (*info->fprintf_func) (info->stream, "%%sfc");

	else

	  /* xgettext:c-format */

	  (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);

      }

      break;

    case 'V':

      (*info->fprintf_func) (info->stream, "%%val");

      break;

    case 't':

      {

	int level = fetch_arg (buffer, place, 3, info);

	(*info->fprintf_func) (info->stream, "%d", level);

      }

      break;

    case 'u':

      {

	short is_upper = 0;

	int reg = fetch_arg (buffer, place, 5, info);

	if (reg & 0x10)

	  {

	    is_upper = 1;

	    reg &= 0xf;

	  }

	(*info->fprintf_func) (info->stream, "%s%s",

			       reg_half_names[reg],

			       is_upper ? "u" : "l");

      }

      break;

    default:

      return -2;

    }

  return p - p0;

}


static bool migration_object_check(MigrationState *ms, Error **errp)

{

    if (!migrate_params_check(&ms->parameters, errp)) {

        return false;

    }

    return true;

}


static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc)

{

    MigrationState *s = migrate_get_current();

    int64_t bandwidth_limit = s->bandwidth_limit;

    memset(s, 0, sizeof(*s));

    s->bandwidth_limit = bandwidth_limit;

    s->blk = blk;

    s->shared = inc;

    /* s->mon is used for two things:

       - pass fd in fd migration

       - suspend/resume monitor for not detached migration

    */

    s->mon = mon;

    s->bandwidth_limit = bandwidth_limit;

    s->state = MIG_STATE_SETUP;

    if (!detach) {

        migrate_fd_monitor_suspend(s, mon);

    }

    return s;

}


static int find_pte64(CPUPPCState *env, mmu_ctx_t *ctx, int h,

                      int rw, int type, int target_page_bits)

{

    hwaddr pteg_off;

    target_ulong pte0, pte1;

    int i, good = -1;

    int ret, r;

    ret = -1; /* No entry found */

    pteg_off = get_pteg_offset(env, ctx->hash[h], HASH_PTE_SIZE_64);

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

        if (env->external_htab) {

            pte0 = ldq_p(env->external_htab + pteg_off + (i * 16));

            pte1 = ldq_p(env->external_htab + pteg_off + (i * 16) + 8);

        } else {

            pte0 = ldq_phys(env->htab_base + pteg_off + (i * 16));

            pte1 = ldq_phys(env->htab_base + pteg_off + (i * 16) + 8);

        }

        r = pte64_check(ctx, pte0, pte1, h, rw, type);

        LOG_MMU("Load pte from %016" HWADDR_PRIx " => " TARGET_FMT_lx " "

                TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",

                pteg_off + (i * 16), pte0, pte1, (int)(pte0 & 1), h,

                (int)((pte0 >> 1) & 1), ctx->ptem);

        switch (r) {

        case -3:

            /* PTE inconsistency */

            return -1;

        case -2:

            /* Access violation */

            ret = -2;

            good = i;

            break;

        case -1:

        default:

            /* No PTE match */

            break;

        case 0:

            /* access granted */

            /* XXX: we should go on looping to check all PTEs consistency

             *      but if we can speed-up the whole thing as the

             *      result would be undefined if PTEs are not consistent.

             */

            ret = 0;

            good = i;

            goto done;

        }

    }

    if (good != -1) {

    done:

        LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n",

                ctx->raddr, ctx->prot, ret);

        /* Update page flags */

        pte1 = ctx->raddr;

        if (pte_update_flags(ctx, &pte1, ret, rw) == 1) {

            if (env->external_htab) {

                stq_p(env->external_htab + pteg_off + (good * 16) + 8,

                      pte1);

            } else {

                stq_phys_notdirty(env->htab_base + pteg_off +

                                  (good * 16) + 8, pte1);

            }

        }

    }

    /* We have a TLB that saves 4K pages, so let's

     * split a huge page to 4k chunks */

    if (target_page_bits != TARGET_PAGE_BITS) {

        ctx->raddr |= (ctx->eaddr & ((1 << target_page_bits) - 1))

                      & TARGET_PAGE_MASK;

    }

    return ret;

}


static int qcow2_mark_dirty(BlockDriverState *bs)

{

    BDRVQcowState *s = bs->opaque;

    uint64_t val;

    int ret;

    assert(s->qcow_version >= 3);

    if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) {

        return 0; /* already dirty */

    }

    val = cpu_to_be64(s->incompatible_features | QCOW2_INCOMPAT_DIRTY);

    ret = bdrv_pwrite(bs->file, offsetof(QCowHeader, incompatible_features),

                      &val, sizeof(val));

    if (ret < 0) {

        return ret;

    }

    ret = bdrv_flush(bs->file);

    if (ret < 0) {

        return ret;

    }

    /* Only treat image as dirty if the header was updated successfully */

    s->incompatible_features |= QCOW2_INCOMPAT_DIRTY;

    return 0;

}


static void decode_sigpass(Jpeg2000T1Context *t1, int width, int height,

                           int bpno, int bandno)

{

    int mask = 3 << (bpno - 1), y0, x, y;

    for (y0 = 0; y0 < height; y0 += 4)

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

            for (y = y0; y < height && y < y0 + 4; y++)

                if ((t1->flags[y + 1][x + 1] & JPEG2000_T1_SIG_NB)

                    && !(t1->flags[y + 1][x + 1] & (JPEG2000_T1_SIG | JPEG2000_T1_VIS))) {

                    if (ff_mqc_decode(&t1->mqc,

                                      t1->mqc.cx_states +

                                      ff_jpeg2000_getsigctxno(t1->flags[y + 1][x + 1],

                                                             bandno))) {

                        int xorbit, ctxno = ff_jpeg2000_getsgnctxno(t1->flags[y + 1][x + 1],

                                                                    &xorbit);

                        t1->data[y][x] =

                            (ff_mqc_decode(&t1->mqc,

                                           t1->mqc.cx_states + ctxno) ^ xorbit)

                            ? -mask : mask;

                        ff_jpeg2000_set_significance(t1, x, y,

                                                     t1->data[y][x] < 0);

                    }

                    t1->flags[y + 1][x + 1] |= JPEG2000_T1_VIS;

                }

}


static uint8_t get_tlm(Jpeg2000DecoderContext *s, int n)

{

    uint8_t Stlm, ST, SP, tile_tlm, i;

    bytestream_get_byte(&s->buf);               /* Ztlm: skipped */

    Stlm = bytestream_get_byte(&s->buf);

    // too complex ? ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);

    ST = (Stlm >> 4) & 0x03;

    // TODO: Manage case of ST = 0b11 --> raise error

    SP       = (Stlm >> 6) & 0x01;

    tile_tlm = (n - 4) / ((SP + 1) * 2 + ST);

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

        switch (ST) {

        case 0:

            break;

        case 1:

            bytestream_get_byte(&s->buf);

            break;

        case 2:

            bytestream_get_be16(&s->buf);

            break;

        case 3:

            bytestream_get_be32(&s->buf);

            break;

        }

        if (SP == 0) {

            bytestream_get_be16(&s->buf);

        } else {

            bytestream_get_be32(&s->buf);

        }

    }

    return 0;

}


static void esp_pci_io_write(void *opaque, target_phys_addr_t addr,

                             uint64_t val, unsigned int size)

{

    PCIESPState *pci = opaque;

    if (size < 4 || addr & 3) {

        /* need to upgrade request: we only support 4-bytes accesses */

        uint32_t current = 0, mask;

        int shift;

        if (addr < 0x40) {

            current = pci->esp.wregs[addr >> 2];

        } else if (addr < 0x60) {

            current = pci->dma_regs[(addr - 0x40) >> 2];

        } else if (addr < 0x74) {

            current = pci->sbac;

        }

        shift = (4 - size) * 8;

        mask = (~(uint32_t)0 << shift) >> shift;

        shift = ((4 - (addr & 3)) & 3) * 8;

        val <<= shift;

        val |= current & ~(mask << shift);

        addr &= ~3;

        size = 4;

    }

    if (addr < 0x40) {

        /* SCSI core reg */

        esp_reg_write(&pci->esp, addr >> 2, val);

    } else if (addr < 0x60) {

        /* PCI DMA CCB */

        esp_pci_dma_write(pci, (addr - 0x40) >> 2, val);

    } else if (addr == 0x70) {

        /* DMA SCSI Bus and control */

        trace_esp_pci_sbac_write(pci->sbac, val);

        pci->sbac = val;

    } else {

        trace_esp_pci_error_invalid_write((int)addr);

    }

}


static void spice_update_buttons(QemuSpicePointer *pointer,

                                 int wheel, uint32_t button_mask)

{

    static uint32_t bmap[INPUT_BUTTON__MAX] = {

        [INPUT_BUTTON_LEFT]        = 0x01,

        [INPUT_BUTTON_MIDDLE]      = 0x04,

        [INPUT_BUTTON_RIGHT]       = 0x02,

        [INPUT_BUTTON_WHEEL_UP]    = 0x10,

        [INPUT_BUTTON_WHEEL_DOWN]  = 0x20,

    };

    if (wheel < 0) {

        button_mask |= 0x10;

    }

    if (wheel > 0) {

        button_mask |= 0x20;

    }

    if (pointer->last_bmask == button_mask) {

        return;

    }

    qemu_input_update_buttons(NULL, bmap, pointer->last_bmask, button_mask);

    pointer->last_bmask = button_mask;

}


Slirp *slirp_init(int restricted, struct in_addr vnetwork,

                  struct in_addr vnetmask, struct in_addr vhost,

                  const char *vhostname, const char *tftp_path,

                  const char *bootfile, struct in_addr vdhcp_start,

                  struct in_addr vnameserver, void *opaque)

{

    Slirp *slirp = qemu_mallocz(sizeof(Slirp));

    slirp_init_once();

    slirp->restricted = restricted;

    if_init(slirp);

    ip_init(slirp);

    /* Initialise mbufs *after* setting the MTU */

    m_init(slirp);

    slirp->vnetwork_addr = vnetwork;

    slirp->vnetwork_mask = vnetmask;

    slirp->vhost_addr = vhost;

    if (vhostname) {

        pstrcpy(slirp->client_hostname, sizeof(slirp->client_hostname),

                vhostname);

    }

    if (tftp_path) {

        slirp->tftp_prefix = qemu_strdup(tftp_path);

    }

    if (bootfile) {

        slirp->bootp_filename = qemu_strdup(bootfile);

    }

    slirp->vdhcp_startaddr = vdhcp_start;

    slirp->vnameserver_addr = vnameserver;

    slirp->opaque = opaque;

    register_savevm("slirp", 0, 3, slirp_state_save, slirp_state_load, slirp);

    TAILQ_INSERT_TAIL(&slirp_instances, slirp, entry);

    return slirp;

}


BdrvDirtyBitmap *bdrv_create_dirty_bitmap(BlockDriverState *bs, int granularity,

                                          Error **errp)

{

    int64_t bitmap_size;

    BdrvDirtyBitmap *bitmap;

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

    granularity >>= BDRV_SECTOR_BITS;

    assert(granularity);

    bitmap_size = bdrv_nb_sectors(bs);

    if (bitmap_size < 0) {

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

        errno = -bitmap_size;

        return NULL;

    }

    bitmap = g_new0(BdrvDirtyBitmap, 1);

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

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

    return bitmap;

}


static void mch_update_pciexbar(MCHPCIState *mch)

{

    PCIDevice *pci_dev = PCI_DEVICE(mch);

    BusState *bus = qdev_get_parent_bus(DEVICE(mch));

    PCIExpressHost *pehb = PCIE_HOST_BRIDGE(bus->parent);

    uint64_t pciexbar;

    int enable;

    uint64_t addr;

    uint64_t addr_mask;

    uint32_t length;

    pciexbar = pci_get_quad(pci_dev->config + MCH_HOST_BRIDGE_PCIEXBAR);

    enable = pciexbar & MCH_HOST_BRIDGE_PCIEXBAREN;

    addr_mask = MCH_HOST_BRIDGE_PCIEXBAR_ADMSK;

    switch (pciexbar & MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_MASK) {

    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_256M:

        length = 256 * 1024 * 1024;

        break;

    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_128M:

        length = 128 * 1024 * 1024;

        addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK |

            MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;

        break;

    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_64M:

        length = 64 * 1024 * 1024;

        addr_mask |= MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK;

        break;

    case MCH_HOST_BRIDGE_PCIEXBAR_LENGTH_RVD:

    default:

        enable = 0;

        length = 0;

        abort();

        break;

    }

    addr = pciexbar & addr_mask;

    pcie_host_mmcfg_update(pehb, enable, addr, length);

    /* Leave enough space for the MCFG BAR */

    /*

     * TODO: this matches current bios behaviour, but it's not a power of two,

     * which means an MTRR can't cover it exactly.

     */

    if (enable) {

        mch->pci_hole.begin = addr + length;

    } else {

        mch->pci_hole.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT;

    }

}


static int get_cluster_duration(MOVTrack *track, int cluster_idx)

{

    int64_t next_dts;

    if (cluster_idx >= track->entry)

        return 0;

    if (cluster_idx + 1 == track->entry)

        next_dts = track->track_duration + track->start_dts;

    else

        next_dts = track->cluster[cluster_idx + 1].dts;

    return next_dts - track->cluster[cluster_idx].dts;

}


static inline int tcg_temp_new_internal(TCGType type, int temp_local)

{

    TCGContext *s = &tcg_ctx;

    TCGTemp *ts;

    int idx, k;

    k = type + (temp_local ? TCG_TYPE_COUNT : 0);

    idx = find_first_bit(s->free_temps[k].l, TCG_MAX_TEMPS);

    if (idx < TCG_MAX_TEMPS) {

        /* There is already an available temp with the right type.  */

        clear_bit(idx, s->free_temps[k].l);

        ts = &s->temps[idx];

        ts->temp_allocated = 1;

        assert(ts->base_type == type);

        assert(ts->temp_local == temp_local);

    } else {

        idx = s->nb_temps;

#if TCG_TARGET_REG_BITS == 32

        if (type == TCG_TYPE_I64) {

            tcg_temp_alloc(s, s->nb_temps + 2);

            ts = &s->temps[s->nb_temps];

            ts->base_type = type;

            ts->type = TCG_TYPE_I32;

            ts->temp_allocated = 1;

            ts->temp_local = temp_local;

            ts->name = NULL;

            ts++;

            ts->base_type = TCG_TYPE_I32;

            ts->type = TCG_TYPE_I32;

            ts->temp_allocated = 1;

            ts->temp_local = temp_local;

            ts->name = NULL;

            s->nb_temps += 2;

        } else

#endif

        {

            tcg_temp_alloc(s, s->nb_temps + 1);

            ts = &s->temps[s->nb_temps];

            ts->base_type = type;

            ts->type = type;

            ts->temp_allocated = 1;

            ts->temp_local = temp_local;

            ts->name = NULL;

            s->nb_temps++;

        }

    }

#if defined(CONFIG_DEBUG_TCG)

    s->temps_in_use++;

#endif

    return idx;

}


static void tcg_out_r(TCGContext *s, TCGArg t0)

{

    assert(t0 < TCG_TARGET_NB_REGS);

    tcg_out8(s, t0);

}


ISADevice *pc_find_fdc0(void)

{

    int i;

    Object *container;

    CheckFdcState state = { 0 };

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

        container = container_get(qdev_get_machine(), fdc_container_path[i]);

        object_child_foreach(container, check_fdc, &state);

    }

    if (state.multiple) {

        error_report("warning: multiple floppy disk controllers with "

                     "iobase=0x3f0 have been found");

        error_printf("the one being picked for CMOS setup might not reflect "

                     "your intent\n");

    }

    return state.floppy;

}


static void qvirtio_scsi_start(const char *extra_opts)

{

    char *cmdline;

    cmdline = g_strdup_printf(

                "-drive id=drv0,if=none,file=/dev/null,format=raw "

                "-device virtio-scsi-pci,id=vs0 "

                "-device scsi-hd,bus=vs0.0,drive=drv0 %s",

                extra_opts ? : "");

    qtest_start(cmdline);

    g_free(cmdline);

}


static int kvm_s390_io_adapter_map(S390FLICState *fs, uint32_t id,

                                   uint64_t map_addr, bool do_map)

{

    struct kvm_s390_io_adapter_req req = {

        .id = id,

        .type = do_map ? KVM_S390_IO_ADAPTER_MAP : KVM_S390_IO_ADAPTER_UNMAP,

        .addr = map_addr,

    };

    struct kvm_device_attr attr = {

        .group = KVM_DEV_FLIC_ADAPTER_MODIFY,

        .addr = (uint64_t)&req,

    };

    KVMS390FLICState *flic = KVM_S390_FLIC(fs);

    int r;

    if (!kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING)) {

        /* nothing to do */

        return 0;

    }

    r = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);

    return r ? -errno : 0;

}


uint32_t HELPER(get_r13_banked)(CPUState *env, uint32_t mode)

{

    return env->banked_r13[bank_number(mode)];

}


static void usb_msd_set_bootindex(Object *obj, Visitor *v, const char *name,

                                  void *opaque, Error **errp)

{

    USBDevice *dev = USB_DEVICE(obj);

    MSDState *s = USB_STORAGE_DEV(dev);

    int32_t boot_index;

    Error *local_err = NULL;

    visit_type_int32(v, name, &boot_index, &local_err);

    if (local_err) {

        goto out;

    }

    /* check whether bootindex is present in fw_boot_order list  */

    check_boot_index(boot_index, &local_err);

    if (local_err) {

        goto out;

    }

    /* change bootindex to a new one */

    s->conf.bootindex = boot_index;

    if (s->scsi_dev) {

        object_property_set_int(OBJECT(s->scsi_dev), boot_index, "bootindex",

                                &error_abort);

    }

out:

    if (local_err) {

        error_propagate(errp, local_err);

    }

}


static void e100_pci_reset(EEPRO100State * s, E100PCIDeviceInfo *e100_device)

{

    uint32_t device = s->device;

    uint8_t *pci_conf = s->dev.config;

    TRACE(OTHER, logout("%p\n", s));

    /* PCI Vendor ID */

    pci_config_set_vendor_id(pci_conf, PCI_VENDOR_ID_INTEL);

    /* PCI Device ID */

    pci_config_set_device_id(pci_conf, e100_device->device_id);

    /* PCI Status */

    pci_set_word(pci_conf + PCI_STATUS, PCI_STATUS_DEVSEL_MEDIUM |

                                        PCI_STATUS_FAST_BACK);

    /* PCI Revision ID */

    pci_config_set_revision(pci_conf, e100_device->revision);

    pci_config_set_class(pci_conf, PCI_CLASS_NETWORK_ETHERNET);

    /* PCI Latency Timer */

    pci_set_byte(pci_conf + PCI_LATENCY_TIMER, 0x20);   /* latency timer = 32 clocks */

    /* Capability Pointer is set by PCI framework. */

    /* Interrupt Line */

    /* Interrupt Pin */

    pci_set_byte(pci_conf + PCI_INTERRUPT_PIN, 1);      /* interrupt pin A */

    /* Minimum Grant */

    pci_set_byte(pci_conf + PCI_MIN_GNT, 0x08);

    /* Maximum Latency */

    pci_set_byte(pci_conf + PCI_MAX_LAT, 0x18);

    s->stats_size = e100_device->stats_size;

    s->has_extended_tcb_support = e100_device->has_extended_tcb_support;

    switch (device) {

    case i82550:

    case i82551:

    case i82557A:

    case i82557B:

    case i82557C:

    case i82558A:

    case i82558B:

    case i82559A:

    case i82559B:

    case i82559ER:

    case i82562:

    case i82801:

        break;

    case i82559C:

#if EEPROM_SIZE > 0

        pci_set_word(pci_conf + PCI_SUBSYSTEM_VENDOR_ID, PCI_VENDOR_ID_INTEL);

        pci_set_word(pci_conf + PCI_SUBSYSTEM_ID, 0x0040);

#endif

        break;

    default:

        logout("Device %X is undefined!\n", device);

    }

    /* Standard TxCB. */

    s->configuration[6] |= BIT(4);

    /* Standard statistical counters. */

    s->configuration[6] |= BIT(5);

    if (s->stats_size == 80) {

        /* TODO: check TCO Statistical Counters bit. Documentation not clear. */

        if (s->configuration[6] & BIT(2)) {

            /* TCO statistical counters. */

            assert(s->configuration[6] & BIT(5));

        } else {

            if (s->configuration[6] & BIT(5)) {

                /* No extended statistical counters, i82557 compatible. */

                s->stats_size = 64;

            } else {

                /* i82558 compatible. */

                s->stats_size = 76;

            }

        }

    } else {

        if (s->configuration[6] & BIT(5)) {

            /* No extended statistical counters. */

            s->stats_size = 64;

        }

    }

    assert(s->stats_size > 0 && s->stats_size <= sizeof(s->statistics));

    if (e100_device->power_management) {

        /* Power Management Capabilities */

        int cfg_offset = 0xdc;

        int r = pci_add_capability(&s->dev, PCI_CAP_ID_PM,

                                   cfg_offset, PCI_PM_SIZEOF);

        assert(r >= 0);

        pci_set_word(pci_conf + cfg_offset + PCI_PM_PMC, 0x7e21);

#if 0 /* TODO: replace dummy code for power management emulation. */

        /* TODO: Power Management Control / Status. */

        pci_set_word(pci_conf + cfg_offset + PCI_PM_CTRL, 0x0000);

        /* TODO: Ethernet Power Consumption Registers (i82559 and later). */

        pci_set_byte(pci_conf + cfg_offset + PCI_PM_PPB_EXTENSIONS, 0x0000);

#endif

    }

#if EEPROM_SIZE > 0

    if (device == i82557C || device == i82558B || device == i82559C) {

        /*

        TODO: get vendor id from EEPROM for i82557C or later.

        TODO: get device id from EEPROM for i82557C or later.

        TODO: status bit 4 can be disabled by EEPROM for i82558, i82559.

        TODO: header type is determined by EEPROM for i82559.

        TODO: get subsystem id from EEPROM for i82557C or later.

        TODO: get subsystem vendor id from EEPROM for i82557C or later.

        TODO: exp. rom baddr depends on a bit in EEPROM for i82558 or later.

        TODO: capability pointer depends on EEPROM for i82558.

        */

        logout("Get device id and revision from EEPROM!!!\n");

    }

#endif /* EEPROM_SIZE > 0 */

}


int net_init_bridge(const NetClientOptions *opts, const char *name,

                    NetClientState *peer, Error **errp)

{

    /* FIXME error_setg(errp, ...) on failure */

    const NetdevBridgeOptions *bridge;

    const char *helper, *br;

    TAPState *s;

    int fd, vnet_hdr;

    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_BRIDGE);

    bridge = opts->bridge;

    helper = bridge->has_helper ? bridge->helper : DEFAULT_BRIDGE_HELPER;

    br     = bridge->has_br     ? bridge->br     : DEFAULT_BRIDGE_INTERFACE;

    fd = net_bridge_run_helper(helper, br);

    if (fd == -1) {

        return -1;

    }

    fcntl(fd, F_SETFL, O_NONBLOCK);

    vnet_hdr = tap_probe_vnet_hdr(fd);

    s = net_tap_fd_init(peer, "bridge", name, fd, vnet_hdr);

    snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s,br=%s", helper,

             br);

    return 0;

}


static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah,

                             int Al, const uint8_t *mb_bitmask,

                             int mb_bitmask_size,

                             const AVFrame *reference)

{

    int i, mb_x, mb_y;

    uint8_t *data[MAX_COMPONENTS];

    const uint8_t *reference_data[MAX_COMPONENTS];

    int linesize[MAX_COMPONENTS];

    GetBitContext mb_bitmask_gb = {0}; // initialize to silence gcc warning

    int bytes_per_pixel = 1 + (s->bits > 8);

    if (mb_bitmask) {

        if (mb_bitmask_size != (s->mb_width * s->mb_height + 7)>>3) {

            av_log(s->avctx, AV_LOG_ERROR, "mb_bitmask_size mismatches\n");

            return AVERROR_INVALIDDATA;

        }

        init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height);

    }

    s->restart_count = 0;

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

        int c   = s->comp_index[i];

        data[c] = s->picture_ptr->data[c];

        reference_data[c] = reference ? reference->data[c] : NULL;

        linesize[c] = s->linesize[c];

        s->coefs_finished[c] |= 1;

    }

    for (mb_y = 0; mb_y < s->mb_height; mb_y++) {

        for (mb_x = 0; mb_x < s->mb_width; mb_x++) {

            const int copy_mb = mb_bitmask && !get_bits1(&mb_bitmask_gb);

            if (s->restart_interval && !s->restart_count)

                s->restart_count = s->restart_interval;

            if (get_bits_left(&s->gb) < 0) {

                av_log(s->avctx, AV_LOG_ERROR, "overread %d\n",

                       -get_bits_left(&s->gb));

                return AVERROR_INVALIDDATA;

            }

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

                uint8_t *ptr;

                int n, h, v, x, y, c, j;

                int block_offset;

                n = s->nb_blocks[i];

                c = s->comp_index[i];

                h = s->h_scount[i];

                v = s->v_scount[i];

                x = 0;

                y = 0;

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

                    block_offset = (((linesize[c] * (v * mb_y + y) * 8) +

                                     (h * mb_x + x) * 8 * bytes_per_pixel) >> s->avctx->lowres);

                    if (s->interlaced && s->bottom_field)

                        block_offset += linesize[c] >> 1;

                    ptr = data[c] + block_offset;

                    if (!s->progressive) {

                        if (copy_mb)

                            mjpeg_copy_block(s, ptr, reference_data[c] + block_offset,

                                             linesize[c], s->avctx->lowres);

                        else {

                            s->bdsp.clear_block(s->block);

                            if (decode_block(s, s->block, i,

                                             s->dc_index[i], s->ac_index[i],

                                             s->quant_matrixes[s->quant_sindex[i]]) < 0) {

                                av_log(s->avctx, AV_LOG_ERROR,

                                       "error y=%d x=%d\n", mb_y, mb_x);

                                return AVERROR_INVALIDDATA;

                            }

                            s->idsp.idct_put(ptr, linesize[c], s->block);

                            if (s->bits & 7)

                                shift_output(s, ptr, linesize[c]);

                        }

                    } else {

                        int block_idx  = s->block_stride[c] * (v * mb_y + y) +

                                         (h * mb_x + x);

                        int16_t *block = s->blocks[c][block_idx];

                        if (Ah)

                            block[0] += get_bits1(&s->gb) *

                                        s->quant_matrixes[s->quant_sindex[i]][0] << Al;

                        else if (decode_dc_progressive(s, block, i, s->dc_index[i],

                                                       s->quant_matrixes[s->quant_sindex[i]],

                                                       Al) < 0) {

                            av_log(s->avctx, AV_LOG_ERROR,

                                   "error y=%d x=%d\n", mb_y, mb_x);

                            return AVERROR_INVALIDDATA;

                        }

                    }

                    av_dlog(s->avctx, "mb: %d %d processed\n", mb_y, mb_x);

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

                            mb_x, mb_y, x, y, c, s->bottom_field,

                            (v * mb_y + y) * 8, (h * mb_x + x) * 8);

                    if (++x == h) {

                        x = 0;

                        y++;

                    }

                }

            }

            handle_rstn(s, nb_components);

        }

    }

    return 0;

}


int kvm_cpu_exec(CPUState *cpu)

{

    struct kvm_run *run = cpu->kvm_run;

    int ret, run_ret;

    DPRINTF("kvm_cpu_exec()\n");

    if (kvm_arch_process_async_events(cpu)) {

        cpu->exit_request = 0;

        return EXCP_HLT;

    }

    qemu_mutex_unlock_iothread();

    do {

        MemTxAttrs attrs;

        if (cpu->kvm_vcpu_dirty) {

            kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);

            cpu->kvm_vcpu_dirty = false;

        }

        kvm_arch_pre_run(cpu, run);

        if (cpu->exit_request) {

            DPRINTF("interrupt exit requested\n");

            /*

             * KVM requires us to reenter the kernel after IO exits to complete

             * instruction emulation. This self-signal will ensure that we

             * leave ASAP again.

             */

            qemu_cpu_kick_self();

        }

        run_ret = kvm_vcpu_ioctl(cpu, KVM_RUN, 0);

        attrs = kvm_arch_post_run(cpu, run);

        if (run_ret < 0) {

            if (run_ret == -EINTR || run_ret == -EAGAIN) {

                DPRINTF("io window exit\n");

                ret = EXCP_INTERRUPT;

                break;

            }

            fprintf(stderr, "error: kvm run failed %s\n",

                    strerror(-run_ret));

#ifdef TARGET_PPC

            if (run_ret == -EBUSY) {

                fprintf(stderr,

                        "This is probably because your SMT is enabled.\n"

                        "VCPU can only run on primary threads with all "

                        "secondary threads offline.\n");

            }

#endif

            ret = -1;

            break;

        }

        trace_kvm_run_exit(cpu->cpu_index, run->exit_reason);

        switch (run->exit_reason) {

        case KVM_EXIT_IO:

            DPRINTF("handle_io\n");

            /* Called outside BQL */

            kvm_handle_io(run->io.port, attrs,

                          (uint8_t *)run + run->io.data_offset,

                          run->io.direction,

                          run->io.size,

                          run->io.count);

            ret = 0;

            break;

        case KVM_EXIT_MMIO:

            DPRINTF("handle_mmio\n");

            /* Called outside BQL */

            address_space_rw(&address_space_memory,

                             run->mmio.phys_addr, attrs,

                             run->mmio.data,

                             run->mmio.len,

                             run->mmio.is_write);

            ret = 0;

            break;

        case KVM_EXIT_IRQ_WINDOW_OPEN:

            DPRINTF("irq_window_open\n");

            ret = EXCP_INTERRUPT;

            break;

        case KVM_EXIT_SHUTDOWN:

            DPRINTF("shutdown\n");

            qemu_system_reset_request();

            ret = EXCP_INTERRUPT;

            break;

        case KVM_EXIT_UNKNOWN:

            fprintf(stderr, "KVM: unknown exit, hardware reason %" PRIx64 "\n",

                    (uint64_t)run->hw.hardware_exit_reason);

            ret = -1;

            break;

        case KVM_EXIT_INTERNAL_ERROR:

            ret = kvm_handle_internal_error(cpu, run);

            break;

        case KVM_EXIT_SYSTEM_EVENT:

            switch (run->system_event.type) {

            case KVM_SYSTEM_EVENT_SHUTDOWN:

                qemu_system_shutdown_request();

                ret = EXCP_INTERRUPT;

                break;

            case KVM_SYSTEM_EVENT_RESET:

                qemu_system_reset_request();

                ret = EXCP_INTERRUPT;

                break;

            case KVM_SYSTEM_EVENT_CRASH:

                qemu_mutex_lock_iothread();

                qemu_system_guest_panicked();

                qemu_mutex_unlock_iothread();

                ret = 0;

                break;

            default:

                DPRINTF("kvm_arch_handle_exit\n");

                ret = kvm_arch_handle_exit(cpu, run);

                break;

            }

            break;

        default:

            DPRINTF("kvm_arch_handle_exit\n");

            ret = kvm_arch_handle_exit(cpu, run);

            break;

        }

    } while (ret == 0);

    qemu_mutex_lock_iothread();

    if (ret < 0) {

        cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_CODE);

        vm_stop(RUN_STATE_INTERNAL_ERROR);

    }

    cpu->exit_request = 0;

    return ret;

}


static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt)

{

    MatroskaMuxContext *mkv = s->priv_data;

    AVIOContext *pb = s->pb;

    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;

    int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY);

    int duration = pkt->duration;

    int ret;

    int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts;

    if (ts == AV_NOPTS_VALUE) {

        av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n");

        return AVERROR(EINVAL);

    }

    if (!s->pb->seekable) {

        if (!mkv->dyn_bc)

            avio_open_dyn_buf(&mkv->dyn_bc);

        pb = mkv->dyn_bc;

    }

    if (mkv->cluster_pos == -1) {

        mkv->cluster_pos = avio_tell(s->pb);

        mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0);

        put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts));

        mkv->cluster_pts = FFMAX(0, ts);

    }

    if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) {

        mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7);

    } else if (codec->codec_id == AV_CODEC_ID_SSA) {

        duration = mkv_write_ass_blocks(s, pb, pkt);

    } else if (codec->codec_id == AV_CODEC_ID_SRT) {

        duration = mkv_write_srt_blocks(s, pb, pkt);

    } else {

        ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size));

        /* For backward compatibility, prefer convergence_duration. */

        if (pkt->convergence_duration > 0) {

            duration = pkt->convergence_duration;

        }

        mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0);

        put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration);

        end_ebml_master(pb, blockgroup);

    }

    if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) {

        ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos);

        if (ret < 0) return ret;

    }

    mkv->duration = FFMAX(mkv->duration, ts + duration);

    return 0;

}


static int adpcm_decode_frame(AVCodecContext *avctx,

			    void *data, int *data_size,

			    uint8_t *buf, int buf_size)

{

    ADPCMContext *c = avctx->priv_data;

    ADPCMChannelStatus *cs;

    int n, m, channel, i;

    int block_predictor[2];

    short *samples;

    uint8_t *src;

    int st; /* stereo */

    /* DK3 ADPCM accounting variables */

    unsigned char last_byte = 0;

    unsigned char nibble;

    int decode_top_nibble_next = 0;

    int diff_channel;

    samples = data;

    src = buf;

    st = avctx->channels == 2;

    switch(avctx->codec->id) {

    case CODEC_ID_ADPCM_IMA_QT:

        n = (buf_size - 2);/* >> 2*avctx->channels;*/

        channel = c->channel;

        cs = &(c->status[channel]);

        /* (pppppp) (piiiiiii) */

        /* Bits 15-7 are the _top_ 9 bits of the 16-bit initial predictor value */

        cs->predictor = (*src++) << 8;

        cs->predictor |= (*src & 0x80);

        cs->predictor &= 0xFF80;

        /* sign extension */

        if(cs->predictor & 0x8000)

            cs->predictor -= 0x10000;

        CLAMP_TO_SHORT(cs->predictor);

        cs->step_index = (*src++) & 0x7F;

        if (cs->step_index > 88) fprintf(stderr, "ERROR: step_index = %i\n", cs->step_index);

        if (cs->step_index > 88) cs->step_index = 88;

        cs->step = step_table[cs->step_index];

        if (st && channel)

            samples++;

        *samples++ = cs->predictor;

        samples += st;

        for(m=32; n>0 && m>0; n--, m--) { /* in QuickTime, IMA is encoded by chuncks of 34 bytes (=64 samples) */

            *samples = adpcm_ima_expand_nibble(cs, src[0] & 0x0F);

            samples += avctx->channels;

            *samples = adpcm_ima_expand_nibble(cs, (src[0] >> 4) & 0x0F);

            samples += avctx->channels;

            src ++;

        }

        if(st) { /* handle stereo interlacing */

            c->channel = (channel + 1) % 2; /* we get one packet for left, then one for right data */

            if(channel == 0) { /* wait for the other packet before outputing anything */

                *data_size = 0;

                return src - buf;

            }

        }

        break;

    case CODEC_ID_ADPCM_IMA_WAV:

        if (avctx->block_align != 0 && buf_size > avctx->block_align)

            buf_size = avctx->block_align;

	// XXX: do as per-channel loop

        cs = &(c->status[0]);

        cs->predictor = (*src++) & 0x0FF;

        cs->predictor |= ((*src++) << 8) & 0x0FF00;

        if(cs->predictor & 0x8000)

            cs->predictor -= 0x10000;

        CLAMP_TO_SHORT(cs->predictor);

	// XXX: is this correct ??: *samples++ = cs->predictor;

	cs->step_index = *src++;

        if (cs->step_index < 0) cs->step_index = 0;

        if (cs->step_index > 88) cs->step_index = 88;

        if (*src++) fprintf(stderr, "unused byte should be null !!\n"); /* unused */

        if (st) {

            cs = &(c->status[1]);

            cs->predictor = (*src++) & 0x0FF;

            cs->predictor |= ((*src++) << 8) & 0x0FF00;

            if(cs->predictor & 0x8000)

                cs->predictor -= 0x10000;

            CLAMP_TO_SHORT(cs->predictor);

	    // XXX: is this correct ??: *samples++ = cs->predictor;

	    cs->step_index = *src++;

            if (cs->step_index < 0) cs->step_index = 0;

            if (cs->step_index > 88) cs->step_index = 88;

            src++; /* if != 0  -> out-of-sync */

        }

        for(m=4; src < (buf + buf_size);) {

	    *samples++ = adpcm_ima_expand_nibble(&c->status[0], src[0] & 0x0F);

            if (st)

                *samples++ = adpcm_ima_expand_nibble(&c->status[1], src[4] & 0x0F);

            *samples++ = adpcm_ima_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F);

	    if (st) {

                *samples++ = adpcm_ima_expand_nibble(&c->status[1], (src[4] >> 4) & 0x0F);

		if (!--m) {

		    m=4;

		    src+=4;

		}

	    }

	    src++;

	}

        break;

    case CODEC_ID_ADPCM_4XM:

        cs = &(c->status[0]);

        c->status[0].predictor= (int16_t)(src[0] + (src[1]<<8)); src+=2;

        if(st){

            c->status[1].predictor= (int16_t)(src[0] + (src[1]<<8)); src+=2;

        }

        c->status[0].step_index= (int16_t)(src[0] + (src[1]<<8)); src+=2;

        if(st){

            c->status[1].step_index= (int16_t)(src[0] + (src[1]<<8)); src+=2;

        }

//            if (cs->step_index < 0) cs->step_index = 0;

//            if (cs->step_index > 88) cs->step_index = 88;

        m= (buf_size - (src - buf))>>st;

//printf("%d %d %d %d\n", st, m, c->status[0].predictor, c->status[0].step_index);

        //FIXME / XXX decode chanels individual & interleave samples

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

	    *samples++ = adpcm_4xa_expand_nibble(&c->status[0], src[i] & 0x0F);

            if (st)

                *samples++ = adpcm_4xa_expand_nibble(&c->status[1], src[i+m] & 0x0F);

            *samples++ = adpcm_4xa_expand_nibble(&c->status[0], src[i] >> 4);

	    if (st)

                *samples++ = adpcm_4xa_expand_nibble(&c->status[1], src[i+m] >> 4);

	}

        src += m<<st;

        break;

    case CODEC_ID_ADPCM_MS:

        if (avctx->block_align != 0 && buf_size > avctx->block_align)

            buf_size = avctx->block_align;

        n = buf_size - 7 * avctx->channels;

        if (n < 0)

            return -1;

        block_predictor[0] = (*src++); /* should be bound */

        block_predictor[0] = (block_predictor[0] < 0)?(0):((block_predictor[0] > 7)?(7):(block_predictor[0]));

        block_predictor[1] = 0;

        if (st)

            block_predictor[1] = (*src++);

        block_predictor[1] = (block_predictor[1] < 0)?(0):((block_predictor[1] > 7)?(7):(block_predictor[1]));

        c->status[0].idelta = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));

        if (c->status[0].idelta & 0x08000)

            c->status[0].idelta -= 0x10000;

        src+=2;

        if (st)

            c->status[1].idelta = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));

        if (st && c->status[1].idelta & 0x08000)

            c->status[1].idelta |= 0xFFFF0000;

        if (st)

            src+=2;

        c->status[0].coeff1 = AdaptCoeff1[block_predictor[0]];

        c->status[0].coeff2 = AdaptCoeff2[block_predictor[0]];

        c->status[1].coeff1 = AdaptCoeff1[block_predictor[1]];

        c->status[1].coeff2 = AdaptCoeff2[block_predictor[1]];

        c->status[0].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));

        src+=2;

        if (st) c->status[1].sample1 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));

        if (st) src+=2;

        c->status[0].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));

        src+=2;

        if (st) c->status[1].sample2 = ((*src & 0xFF) | ((src[1] << 8) & 0xFF00));

        if (st) src+=2;

        *samples++ = c->status[0].sample1;

        if (st) *samples++ = c->status[1].sample1;

        *samples++ = c->status[0].sample2;

        if (st) *samples++ = c->status[1].sample2;

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

            *samples++ = adpcm_ms_expand_nibble(&c->status[0], (src[0] >> 4) & 0x0F);

            *samples++ = adpcm_ms_expand_nibble(&c->status[st], src[0] & 0x0F);

            src ++;

        }

        break;

    case CODEC_ID_ADPCM_IMA_DK4:

        if (buf_size > BLKSIZE) {

            if (avctx->block_align != 0)

                buf_size = avctx->block_align;

            else

                buf_size = BLKSIZE;

        }

        c->status[0].predictor = (src[0] | (src[1] << 8));

        c->status[0].step_index = src[2];

        src += 4;

        if(c->status[0].predictor & 0x8000)

            c->status[0].predictor -= 0x10000;

        *samples++ = c->status[0].predictor;

        if (st) {

            c->status[1].predictor = (src[0] | (src[1] << 8));

            c->status[1].step_index = src[2];

            src += 4;

            if(c->status[1].predictor & 0x8000)

                c->status[1].predictor -= 0x10000;

            *samples++ = c->status[1].predictor;

        }

        while (src < buf + buf_size) {

            /* take care of the top nibble (always left or mono channel) */

            *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                (src[0] >> 4) & 0x0F);

            /* take care of the bottom nibble, which is right sample for

             * stereo, or another mono sample */

            if (st)

                *samples++ = adpcm_ima_expand_nibble(&c->status[1],

                    src[0] & 0x0F);

            else

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] & 0x0F);

            src++;

        }

        break;

    case CODEC_ID_ADPCM_IMA_DK3:

        if (buf_size > BLKSIZE) {

            if (avctx->block_align != 0)

                buf_size = avctx->block_align;

            else

                buf_size = BLKSIZE;

        }

        c->status[0].predictor = (src[10] | (src[11] << 8));

        c->status[1].predictor = (src[12] | (src[13] << 8));

        c->status[0].step_index = src[14];

        c->status[1].step_index = src[15];

        /* sign extend the predictors */

        if(c->status[0].predictor & 0x8000)

            c->status[0].predictor -= 0x10000;

        if(c->status[1].predictor & 0x8000)

            c->status[1].predictor -= 0x10000;

        src += 16;

        diff_channel = c->status[1].predictor;

        /* the DK3_GET_NEXT_NIBBLE macro issues the break statement when

         * the buffer is consumed */

        while (1) {

            /* for this algorithm, c->status[0] is the sum channel and

             * c->status[1] is the diff channel */

            /* process the first predictor of the sum channel */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[0], nibble);

            /* process the diff channel predictor */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[1], nibble);

            /* process the first pair of stereo PCM samples */

            diff_channel = (diff_channel + c->status[1].predictor) / 2;

            *samples++ = c->status[0].predictor + c->status[1].predictor;

            *samples++ = c->status[0].predictor - c->status[1].predictor;

            /* process the second predictor of the sum channel */

            DK3_GET_NEXT_NIBBLE();

            adpcm_ima_expand_nibble(&c->status[0], nibble);

            /* process the second pair of stereo PCM samples */

            diff_channel = (diff_channel + c->status[1].predictor) / 2;

            *samples++ = c->status[0].predictor + c->status[1].predictor;

            *samples++ = c->status[0].predictor - c->status[1].predictor;

        }

        break;

    case CODEC_ID_ADPCM_IMA_WS:

        /* no per-block initialization; just start decoding the data */

        while (src < buf + buf_size) {

            if (st) {

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    (src[0] >> 4) & 0x0F);

                *samples++ = adpcm_ima_expand_nibble(&c->status[1],

                    src[0] & 0x0F);

            } else {

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    (src[0] >> 4) & 0x0F);

                *samples++ = adpcm_ima_expand_nibble(&c->status[0],

                    src[0] & 0x0F);

            }

            src++;

        }

        break;

    case CODEC_ID_ADPCM_XA:

        c->status[0].sample1 = c->status[0].sample2 =

        c->status[1].sample1 = c->status[1].sample2 = 0;

        while (buf_size >= 128) {

            xa_decode(samples, src, &c->status[0], &c->status[1],

                avctx->channels);

            src += 128;

            samples += 28 * 8;

            buf_size -= 128;

        }

        break;

    default:

        *data_size = 0;

        return -1;

    }

    *data_size = (uint8_t *)samples - (uint8_t *)data;

    return src - buf;

}


static int jp2_find_codestream(Jpeg2000DecoderContext *s)

{

    int32_t atom_size;

    int found_codestream = 0, search_range = 10;

    // Skip JPEG 2000 signature atom.

    s->buf += 12;

    while (!found_codestream && search_range) {

        atom_size = AV_RB32(s->buf);

        if (AV_RB32(s->buf + 4) == JP2_CODESTREAM) {

            found_codestream = 1;

            s->buf += 8;

        } else {

            s->buf += atom_size;

            search_range--;

        }

    }

    if (found_codestream)

        return 1;

    return 0;

}


parallel_ioport_write_sw(void *opaque, uint32_t addr, uint32_t val)

{

    ParallelState *s = opaque;

    pdebug("write addr=0x%02x val=0x%02x\n", addr, val);

    addr &= 7;

    switch(addr) {

    case PARA_REG_DATA:

        s->dataw = val;

        parallel_update_irq(s);

        break;

    case PARA_REG_CTR:

        val |= 0xc0;

        if ((val & PARA_CTR_INIT) == 0 ) {

            s->status = PARA_STS_BUSY;

            s->status |= PARA_STS_ACK;

            s->status |= PARA_STS_ONLINE;

            s->status |= PARA_STS_ERROR;

        }

        else if (val & PARA_CTR_SELECT) {

            if (val & PARA_CTR_STROBE) {

                s->status &= ~PARA_STS_BUSY;

                if ((s->control & PARA_CTR_STROBE) == 0)

                    qemu_chr_fe_write(s->chr, &s->dataw, 1);

            } else {

                if (s->control & PARA_CTR_INTEN) {

                    s->irq_pending = 1;

                }

            }

        }

        parallel_update_irq(s);

        s->control = val;

        break;

    }

}


static inline int get_chroma_qp(int chroma_qp_index_offset, int qscale){

    return chroma_qp[av_clip(qscale + chroma_qp_index_offset, 0, 51)];

}


static int coroutine_fn iscsi_co_flush(BlockDriverState *bs)

{

    IscsiLun *iscsilun = bs->opaque;

    struct IscsiTask iTask;

    if (bdrv_is_sg(bs)) {

        return 0;

    }

    if (!iscsilun->force_next_flush) {

        return 0;

    }

    iscsilun->force_next_flush = false;

    iscsi_co_init_iscsitask(iscsilun, &iTask);

retry:

    if (iscsi_synchronizecache10_task(iscsilun->iscsi, iscsilun->lun, 0, 0, 0,

                                      0, iscsi_co_generic_cb, &iTask) == NULL) {

        return -ENOMEM;

    }

    while (!iTask.complete) {

        iscsi_set_events(iscsilun);

        qemu_coroutine_yield();

    }

    if (iTask.task != NULL) {

        scsi_free_scsi_task(iTask.task);

        iTask.task = NULL;

    }

    if (iTask.do_retry) {

        iTask.complete = 0;

        goto retry;

    }

    if (iTask.status != SCSI_STATUS_GOOD) {

        return -EIO;

    }

    return 0;

}


static void mch_update_smram(MCHPCIState *mch)

{

    PCIDevice *pd = PCI_DEVICE(mch);

    bool h_smrame = (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_H_SMRAME);

    uint32_t tseg_size;

    /* implement SMRAM.D_LCK */

    if (pd->config[MCH_HOST_BRIDGE_SMRAM] & MCH_HOST_BRIDGE_SMRAM_D_LCK) {

        pd->config[MCH_HOST_BRIDGE_SMRAM] &= ~MCH_HOST_BRIDGE_SMRAM_D_OPEN;

        pd->wmask[MCH_HOST_BRIDGE_SMRAM] = MCH_HOST_BRIDGE_SMRAM_WMASK_LCK;

        pd->wmask[MCH_HOST_BRIDGE_ESMRAMC] = MCH_HOST_BRIDGE_ESMRAMC_WMASK_LCK;

    }

    memory_region_transaction_begin();

    if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_D_OPEN) {

        /* Hide (!) low SMRAM if H_SMRAME = 1 */

        memory_region_set_enabled(&mch->smram_region, h_smrame);

        /* Show high SMRAM if H_SMRAME = 1 */

        memory_region_set_enabled(&mch->open_high_smram, h_smrame);

    } else {

        /* Hide high SMRAM and low SMRAM */

        memory_region_set_enabled(&mch->smram_region, true);

        memory_region_set_enabled(&mch->open_high_smram, false);

    }

    if (pd->config[MCH_HOST_BRIDGE_SMRAM] & SMRAM_G_SMRAME) {

        memory_region_set_enabled(&mch->low_smram, !h_smrame);

        memory_region_set_enabled(&mch->high_smram, h_smrame);

    } else {

        memory_region_set_enabled(&mch->low_smram, false);

        memory_region_set_enabled(&mch->high_smram, false);

    }

    if (pd->config[MCH_HOST_BRIDGE_ESMRAMC] & MCH_HOST_BRIDGE_ESMRAMC_T_EN) {

        switch (pd->config[MCH_HOST_BRIDGE_ESMRAMC] &

                MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_MASK) {

        case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_1MB:

            tseg_size = 1024 * 1024;

            break;

        case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_2MB:

            tseg_size = 1024 * 1024 * 2;

            break;

        case MCH_HOST_BRIDGE_ESMRAMC_TSEG_SZ_8MB:

            tseg_size = 1024 * 1024 * 8;

            break;

        default:

            tseg_size = 0;

            break;

        }

    } else {

        tseg_size = 0;

    }

    memory_region_del_subregion(mch->system_memory, &mch->tseg_blackhole);

    memory_region_set_enabled(&mch->tseg_blackhole, tseg_size);

    memory_region_set_size(&mch->tseg_blackhole, tseg_size);

    memory_region_add_subregion_overlap(mch->system_memory,

                                        mch->below_4g_mem_size - tseg_size,

                                        &mch->tseg_blackhole, 1);

    memory_region_set_enabled(&mch->tseg_window, tseg_size);

    memory_region_set_size(&mch->tseg_window, tseg_size);

    memory_region_set_address(&mch->tseg_window,

                              mch->below_4g_mem_size - tseg_size);

    memory_region_set_alias_offset(&mch->tseg_window,

                                   mch->below_4g_mem_size - tseg_size);

    memory_region_transaction_commit();

}


int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask,
                        int mb_bitmask_size, const AVFrame *reference)
{
    int len, nb_components, i, h, v, predictor, point_transform;
    int index, id, ret;
    const int block_size = s->lossless ? 1 : 8;
    int ilv, prev_shift;
    if (!s->got_picture) {
        av_log(s->avctx, AV_LOG_WARNING,
                "Can not process SOS before SOF, skipping\n");
        return -1;
    av_assert0(s->picture_ptr->data[0]);
    /* XXX: verify len field validity */
    len = get_bits(&s->gb, 16);
    nb_components = get_bits(&s->gb, 8);
    if (nb_components == 0 || nb_components > MAX_COMPONENTS) {
        avpriv_report_missing_feature(s->avctx,
                                      "decode_sos: nb_components (%d)",
                                      nb_components);
        return AVERROR_PATCHWELCOME;
    if (len != 6 + 2 * nb_components) {
        av_log(s->avctx, AV_LOG_ERROR, "decode_sos: invalid len (%d)\n", len);
    for (i = 0; i < nb_components; i++) {
        id = get_bits(&s->gb, 8) - 1;
        av_log(s->avctx, AV_LOG_DEBUG, "component: %d\n", id);
        /* find component index */
        for (index = 0; index < s->nb_components; index++)
            if (id == s->component_id[index])
                break;
        if (index == s->nb_components) {
            av_log(s->avctx, AV_LOG_ERROR,
                   "decode_sos: index(%d) out of components\n", index);
        /* Metasoft MJPEG codec has Cb and Cr swapped */
        if (s->avctx->codec_tag == MKTAG('M', 'T', 'S', 'J')
            && nb_components == 3 && s->nb_components == 3 && i)
            index = 3 - i;
        s->quant_sindex[i] = s->quant_index[index];
        s->nb_blocks[i] = s->h_count[index] * s->v_count[index];
        s->h_scount[i]  = s->h_count[index];
        s->v_scount[i]  = s->v_count[index];
        if(nb_components == 3 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
            index = (i+2)%3;
        if(nb_components == 1 && s->nb_components == 3 && s->avctx->pix_fmt == AV_PIX_FMT_GBR24P)
            index = (index+2)%3;
        s->comp_index[i] = index;
        s->dc_index[i] = get_bits(&s->gb, 4);
        s->ac_index[i] = get_bits(&s->gb, 4);
        if (s->dc_index[i] <  0 || s->ac_index[i] < 0 ||
            s->dc_index[i] >= 4 || s->ac_index[i] >= 4)
            goto out_of_range;
        if (!s->vlcs[0][s->dc_index[i]].table || !(s->progressive ? s->vlcs[2][s->ac_index[0]].table : s->vlcs[1][s->ac_index[i]].table))
            goto out_of_range;
    predictor = get_bits(&s->gb, 8);       /* JPEG Ss / lossless JPEG predictor /JPEG-LS NEAR */
    ilv = get_bits(&s->gb, 8);             /* JPEG Se / JPEG-LS ILV */
    if(s->avctx->codec_tag != AV_RL32("CJPG")){
        prev_shift      = get_bits(&s->gb, 4); /* Ah */
        point_transform = get_bits(&s->gb, 4); /* Al */
    }else
        prev_shift = point_transform = 0;
    if (nb_components > 1) {
        /* interleaved stream */
        s->mb_width  = (s->width  + s->h_max * block_size - 1) / (s->h_max * block_size);
        s->mb_height = (s->height + s->v_max * block_size - 1) / (s->v_max * block_size);
    } else if (!s->ls) { /* skip this for JPEG-LS */
        h = s->h_max / s->h_scount[0];
        v = s->v_max / s->v_scount[0];
        s->mb_width     = (s->width  + h * block_size - 1) / (h * block_size);
        s->mb_height    = (s->height + v * block_size - 1) / (v * block_size);
        s->nb_blocks[0] = 1;
        s->h_scount[0]  = 1;
        s->v_scount[0]  = 1;
    if (s->avctx->debug & FF_DEBUG_PICT_INFO)
        av_log(s->avctx, AV_LOG_DEBUG, "%s %s p:%d >>:%d ilv:%d bits:%d skip:%d %s comp:%d\n",
               s->lossless ? "lossless" : "sequential DCT", s->rgb ? "RGB" : "",
               predictor, point_transform, ilv, s->bits, s->mjpb_skiptosod,
               s->pegasus_rct ? "PRCT" : (s->rct ? "RCT" : ""), nb_components);
    /* mjpeg-b can have padding bytes between sos and image data, skip them */
    for (i = s->mjpb_skiptosod; i > 0; i--)
        skip_bits(&s->gb, 8);
next_field:
    for (i = 0; i < nb_components; i++)
        s->last_dc[i] = (4 << s->bits);
    if (s->lossless) {
        av_assert0(s->picture_ptr == s->picture);
        if (CONFIG_JPEGLS_DECODER && s->ls) {
//            for () {
//            reset_ls_coding_parameters(s, 0);
            if ((ret = ff_jpegls_decode_picture(s, predictor,
                                                point_transform, ilv)) < 0)
                return ret;
        } else {
            if (s->rgb) {
                if ((ret = ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform)) < 0)
                    return ret;
            } else {
                if ((ret = ljpeg_decode_yuv_scan(s, predictor,
                                                 point_transform,
                                                 nb_components)) < 0)
                    return ret;
    } else {
        if (s->progressive && predictor) {
            av_assert0(s->picture_ptr == s->picture);
            if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor,
                                                        ilv, prev_shift,
                                                        point_transform)) < 0)
                return ret;
        } else {
            if ((ret = mjpeg_decode_scan(s, nb_components,
                                         prev_shift, point_transform,
                                         mb_bitmask, mb_bitmask_size, reference)) < 0)
                return ret;
    if (s->interlaced &&
        get_bits_left(&s->gb) > 32 &&
        show_bits(&s->gb, 8) == 0xFF) {
        GetBitContext bak = s->gb;
        align_get_bits(&bak);
        if (show_bits(&bak, 16) == 0xFFD1) {
            av_log(s->avctx, AV_LOG_DEBUG, "AVRn interlaced picture marker found\n");
            s->gb = bak;
            skip_bits(&s->gb, 16);
            s->bottom_field ^= 1;
            goto next_field;
    emms_c();
    return 0;
 out_of_range:
    av_log(s->avctx, AV_LOG_ERROR, "decode_sos: ac/dc index out of range\n");