mp_image_t* vf_get_image(vf_instance_t* vf, unsigned int outfmt, int mp_imgtype, int mp_imgflag, int w, int h){

    MPContext *m= (MPContext*)(((uint8_t*)vf) - offsetof(MPContext, next_vf));

  mp_image_t* mpi=NULL;

  int w2;

  int number = mp_imgtype >> 16;

  av_assert0(vf->next == NULL); // all existing filters call this just on next

  //vf_dint needs these as it calls vf_get_image() before configuring the output

  if(vf->w==0 && w>0) vf->w=w;

  if(vf->h==0 && h>0) vf->h=h;

  av_assert0(w == -1 || w >= vf->w);

  av_assert0(h == -1 || h >= vf->h);

  av_assert0(vf->w > 0);

  av_assert0(vf->h > 0);

  av_log(m->avfctx, AV_LOG_DEBUG, "get_image: %d:%d, vf: %d:%d\n", w,h,vf->w,vf->h);

  if (w == -1) w = vf->w;

  if (h == -1) h = vf->h;

  w2=(mp_imgflag&MP_IMGFLAG_ACCEPT_ALIGNED_STRIDE)?((w+15)&(~15)):w;

  // Note: we should call libvo first to check if it supports direct rendering

  // and if not, then fallback to software buffers:

  switch(mp_imgtype & 0xff){

  case MP_IMGTYPE_EXPORT:

    if(!vf->imgctx.export_images[0]) vf->imgctx.export_images[0]=new_mp_image(w2,h);

    mpi=vf->imgctx.export_images[0];

    break;

  case MP_IMGTYPE_STATIC:

    if(!vf->imgctx.static_images[0]) vf->imgctx.static_images[0]=new_mp_image(w2,h);

    mpi=vf->imgctx.static_images[0];

    break;

  case MP_IMGTYPE_TEMP:

    if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h);

    mpi=vf->imgctx.temp_images[0];

    break;

  case MP_IMGTYPE_IPB:

    if(!(mp_imgflag&MP_IMGFLAG_READABLE)){ // B frame:

      if(!vf->imgctx.temp_images[0]) vf->imgctx.temp_images[0]=new_mp_image(w2,h);

      mpi=vf->imgctx.temp_images[0];

      break;

    }

  case MP_IMGTYPE_IP:

    if(!vf->imgctx.static_images[vf->imgctx.static_idx]) vf->imgctx.static_images[vf->imgctx.static_idx]=new_mp_image(w2,h);

    mpi=vf->imgctx.static_images[vf->imgctx.static_idx];

    vf->imgctx.static_idx^=1;

    break;

  case MP_IMGTYPE_NUMBERED:

    if (number == -1) {

      int i;

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

        if (!vf->imgctx.numbered_images[i] || !vf->imgctx.numbered_images[i]->usage_count)

          break;

      number = i;

    }

    if (number < 0 || number >= NUM_NUMBERED_MPI) return NULL;

    if (!vf->imgctx.numbered_images[number]) vf->imgctx.numbered_images[number] = new_mp_image(w2,h);

    mpi = vf->imgctx.numbered_images[number];

    mpi->number = number;

    break;

  }

  if(mpi){

    mpi->type=mp_imgtype;

    mpi->w=vf->w; mpi->h=vf->h;

    // keep buffer allocation status & color flags only:

//    mpi->flags&=~(MP_IMGFLAG_PRESERVE|MP_IMGFLAG_READABLE|MP_IMGFLAG_DIRECT);

    mpi->flags&=MP_IMGFLAG_ALLOCATED|MP_IMGFLAG_TYPE_DISPLAYED|MP_IMGFLAGMASK_COLORS;

    // accept restrictions, draw_slice and palette flags only:

    mpi->flags|=mp_imgflag&(MP_IMGFLAGMASK_RESTRICTIONS|MP_IMGFLAG_DRAW_CALLBACK|MP_IMGFLAG_RGB_PALETTE);

    if(!vf->draw_slice) mpi->flags&=~MP_IMGFLAG_DRAW_CALLBACK;

    if(mpi->width!=w2 || mpi->height!=h){

//      printf("vf.c: MPI parameters changed!  %dx%d -> %dx%d   \n", mpi->width,mpi->height,w2,h);

        if(mpi->flags&MP_IMGFLAG_ALLOCATED){

            if(mpi->width<w2 || mpi->height<h){

                // need to re-allocate buffer memory:

                av_free(mpi->planes[0]);

                mpi->flags&=~MP_IMGFLAG_ALLOCATED;

                mp_msg(MSGT_VFILTER,MSGL_V,"vf.c: have to REALLOCATE buffer memory :(\n");

            }

//      } else {

        } {

            mpi->width=w2; mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;

            mpi->height=h; mpi->chroma_height=(h + (1<<mpi->chroma_y_shift) - 1)>>mpi->chroma_y_shift;

        }

    }

    if(!mpi->bpp) mp_image_setfmt(mpi,outfmt);

    if(!(mpi->flags&MP_IMGFLAG_ALLOCATED) && mpi->type>MP_IMGTYPE_EXPORT){

        av_assert0(!vf->get_image);

        // check libvo first!

        if(vf->get_image) vf->get_image(vf,mpi);

        if(!(mpi->flags&MP_IMGFLAG_DIRECT)){

          // non-direct and not yet allocated image. allocate it!

          if (!mpi->bpp) { // no way we can allocate this

              mp_msg(MSGT_DECVIDEO, MSGL_FATAL,

                     "vf_get_image: Tried to allocate a format that can not be allocated!\n");

              return NULL;

          }

          // check if codec prefer aligned stride:

          if(mp_imgflag&MP_IMGFLAG_PREFER_ALIGNED_STRIDE){

              int align=(mpi->flags&MP_IMGFLAG_PLANAR &&

                         mpi->flags&MP_IMGFLAG_YUV) ?

                         (8<<mpi->chroma_x_shift)-1 : 15; // -- maybe FIXME

              w2=((w+align)&(~align));

              if(mpi->width!=w2){

#if 0

                  // we have to change width... check if we CAN co it:

                  int flags=vf->query_format(vf,outfmt); // should not fail

                  if(!(flags&3)) mp_msg(MSGT_DECVIDEO,MSGL_WARN,"??? vf_get_image{vf->query_format(outfmt)} failed!\n");

//                printf("query -> 0x%X    \n",flags);

                  if(flags&VFCAP_ACCEPT_STRIDE){

#endif

                      mpi->width=w2;

                      mpi->chroma_width=(w2 + (1<<mpi->chroma_x_shift) - 1)>>mpi->chroma_x_shift;

//                  }

              }

          }

          mp_image_alloc_planes(mpi);

//        printf("clearing img!\n");

          vf_mpi_clear(mpi,0,0,mpi->width,mpi->height);

        }

    }

    av_assert0(!vf->start_slice);

    if(mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)

        if(vf->start_slice) vf->start_slice(vf,mpi);

    if(!(mpi->flags&MP_IMGFLAG_TYPE_DISPLAYED)){

            mp_msg(MSGT_DECVIDEO,MSGL_V,"*** [%s] %s%s mp_image_t, %dx%dx%dbpp %s %s, %d bytes\n",

                  "NULL"/*vf->info->name*/,

                  (mpi->type==MP_IMGTYPE_EXPORT)?"Exporting":

                  ((mpi->flags&MP_IMGFLAG_DIRECT)?"Direct Rendering":"Allocating"),

                  (mpi->flags&MP_IMGFLAG_DRAW_CALLBACK)?" (slices)":"",

                  mpi->width,mpi->height,mpi->bpp,

                  (mpi->flags&MP_IMGFLAG_YUV)?"YUV":((mpi->flags&MP_IMGFLAG_SWAPPED)?"BGR":"RGB"),

                  (mpi->flags&MP_IMGFLAG_PLANAR)?"planar":"packed",

                  mpi->bpp*mpi->width*mpi->height/8);

            mp_msg(MSGT_DECVIDEO,MSGL_DBG2,"(imgfmt: %x, planes: %p,%p,%p strides: %d,%d,%d, chroma: %dx%d, shift: h:%d,v:%d)\n",

                mpi->imgfmt, mpi->planes[0], mpi->planes[1], mpi->planes[2],

                mpi->stride[0], mpi->stride[1], mpi->stride[2],

                mpi->chroma_width, mpi->chroma_height, mpi->chroma_x_shift, mpi->chroma_y_shift);

            mpi->flags|=MP_IMGFLAG_TYPE_DISPLAYED;

    }

  mpi->qscale = NULL;

  }

  mpi->usage_count++;

//    printf("\rVF_MPI: %p %p %p %d %d %d    \n",

//      mpi->planes[0],mpi->planes[1],mpi->planes[2],

//      mpi->stride[0],mpi->stride[1],mpi->stride[2]);

  return mpi;

}


static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len)

{

    Mp4Descr *descr = d->active_descr;

    int predefined;

    if (!descr)

        return -1;

    predefined = avio_r8(&d->pb);

    if (!predefined) {

        int lengths;

        int flags = avio_r8(&d->pb);

        descr->sl.use_au_start       = !!(flags & 0x80);

        descr->sl.use_au_end         = !!(flags & 0x40);

        descr->sl.use_rand_acc_pt    = !!(flags & 0x20);

        descr->sl.use_padding        = !!(flags & 0x08);

        descr->sl.use_timestamps     = !!(flags & 0x04);

        descr->sl.use_idle           = !!(flags & 0x02);

        descr->sl.timestamp_res      = avio_rb32(&d->pb);

                                       avio_rb32(&d->pb);

        descr->sl.timestamp_len      = avio_r8(&d->pb);

        descr->sl.ocr_len            = avio_r8(&d->pb);

        descr->sl.au_len             = avio_r8(&d->pb);

        descr->sl.inst_bitrate_len   = avio_r8(&d->pb);

        lengths                      = avio_rb16(&d->pb);

        descr->sl.degr_prior_len     = lengths >> 12;

        descr->sl.au_seq_num_len     = (lengths >> 7) & 0x1f;

        descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f;

    } else {

        avpriv_report_missing_feature(d->s, "Predefined SLConfigDescriptor");

    return 0;


target_ulong helper_mul_suov(CPUTriCoreState *env, target_ulong r1,

                             target_ulong r2)

{

    int64_t t1 = extract64(r1, 0, 32);

    int64_t t2 = extract64(r2, 0, 32);

    int64_t result = t1 * t2;

    return suov32(env, result);

}


static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_ptr)

{

    WtvContext *wtv = s->priv_data;

    AVIOContext *pb = wtv->pb;

    while (!url_feof(pb)) {

        ff_asf_guid g;

        int len, sid, consumed;

        ff_get_guid(pb, &g);

        len = avio_rl32(pb);

        if (len < 32)

            break;

        sid = avio_rl32(pb) & 0x7FFF;

        avio_skip(pb, 8);

        consumed = 32;

        if (!ff_guidcmp(g, ff_SBE2_STREAM_DESC_EVENT)) {

            if (ff_find_stream_index(s, sid) < 0) {

                ff_asf_guid mediatype, subtype, formattype;

                int size;

                avio_skip(pb, 28);

                ff_get_guid(pb, &mediatype);

                ff_get_guid(pb, &subtype);

                avio_skip(pb, 12);

                ff_get_guid(pb, &formattype);

                size = avio_rl32(pb);

                parse_media_type(s, 0, sid, mediatype, subtype, formattype, size);

                consumed += 92 + size;

            }

        } else if (!ff_guidcmp(g, ff_stream2_guid)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0 && !((WtvStream*)s->streams[stream_index]->priv_data)->seen_data) {

                ff_asf_guid mediatype, subtype, formattype;

                int size;

                avio_skip(pb, 12);

                ff_get_guid(pb, &mediatype);

                ff_get_guid(pb, &subtype);

                avio_skip(pb, 12);

                ff_get_guid(pb, &formattype);

                size = avio_rl32(pb);

                parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size);

                consumed += 76 + size;

            }

        } else if (!ff_guidcmp(g, EVENTID_AudioDescriptorSpanningEvent) ||

                   !ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||

                   !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent) ||

                   !ff_guidcmp(g, EVENTID_StreamIDSpanningEvent) ||

                   !ff_guidcmp(g, EVENTID_SubtitleSpanningEvent) ||

                   !ff_guidcmp(g, EVENTID_TeletextSpanningEvent)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0) {

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

                uint8_t buf[258];

                const uint8_t *pbuf = buf;

                int buf_size;

                avio_skip(pb, 8);

                consumed += 8;

                if (!ff_guidcmp(g, EVENTID_CtxADescriptorSpanningEvent) ||

                    !ff_guidcmp(g, EVENTID_CSDescriptorSpanningEvent)) {

                    avio_skip(pb, 6);

                    consumed += 6;

                }

                buf_size = FFMIN(len - consumed, sizeof(buf));

                avio_read(pb, buf, buf_size);

                consumed += buf_size;

                ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL);

            }

        } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0) {

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

                int audio_type;

                avio_skip(pb, 8);

                audio_type = avio_r8(pb);

                if (audio_type == 2)

                    st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED;

                else if (audio_type == 3)

                    st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;

                consumed += 9;

            }

        } else if (!ff_guidcmp(g, EVENTID_DVBScramblingControlSpanningEvent)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0) {

                avio_skip(pb, 12);

                if (avio_rl32(pb))

                    av_log(s, AV_LOG_WARNING, "DVB scrambled stream detected (st:%d), decoding will likely fail\n", stream_index);

                consumed += 16;

            }

        } else if (!ff_guidcmp(g, EVENTID_LanguageSpanningEvent)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0) {

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

                uint8_t language[4];

                avio_skip(pb, 12);

                avio_read(pb, language, 3);

                if (language[0]) {

                    language[3] = 0;

                    av_dict_set(&st->metadata, "language", language, 0);

                    if (!strcmp(language, "nar") || !strcmp(language, "NAR"))

                        st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED;

                }

                consumed += 15;

            }

        } else if (!ff_guidcmp(g, ff_timestamp_guid)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0) {

                avio_skip(pb, 8);

                wtv->pts = avio_rl64(pb);

                consumed += 16;

                if (wtv->pts == -1)

                    wtv->pts = AV_NOPTS_VALUE;

                else {

                    wtv->last_valid_pts = wtv->pts;

                    if (wtv->epoch == AV_NOPTS_VALUE || wtv->pts < wtv->epoch)

                        wtv->epoch = wtv->pts;

                if (mode == SEEK_TO_PTS && wtv->pts >= seekts) {

                    avio_skip(pb, WTV_PAD8(len) - consumed);

                    return 0;

                }

                }

            }

        } else if (!ff_guidcmp(g, ff_data_guid)) {

            int stream_index = ff_find_stream_index(s, sid);

            if (mode == SEEK_TO_DATA && stream_index >= 0 && len > 32 && s->streams[stream_index]->priv_data) {

                WtvStream *wst = s->streams[stream_index]->priv_data;

                wst->seen_data = 1;

                if (len_ptr) {

                    *len_ptr = len;

                }

                return stream_index;

            }

        } else if (!ff_guidcmp(g, /* DSATTRIB_WMDRMProtectionInfo */ (const ff_asf_guid){0x83,0x95,0x74,0x40,0x9D,0x6B,0xEC,0x4E,0xB4,0x3C,0x67,0xA1,0x80,0x1E,0x1A,0x9B})) {

            int stream_index = ff_find_stream_index(s, sid);

            if (stream_index >= 0)

                av_log(s, AV_LOG_WARNING, "encrypted stream detected (st:%d), decoding will likely fail\n", stream_index);

        } else if (

            !ff_guidcmp(g, /* DSATTRIB_CAPTURE_STREAMTIME */ (const ff_asf_guid){0x14,0x56,0x1A,0x0C,0xCD,0x30,0x40,0x4F,0xBC,0xBF,0xD0,0x3E,0x52,0x30,0x62,0x07}) ||

            !ff_guidcmp(g, /* DSATTRIB_PBDATAG_ATTRIBUTE */ (const ff_asf_guid){0x79,0x66,0xB5,0xE0,0xB9,0x12,0xCC,0x43,0xB7,0xDF,0x57,0x8C,0xAA,0x5A,0x7B,0x63}) ||

            !ff_guidcmp(g, /* DSATTRIB_PicSampleSeq */ (const ff_asf_guid){0x02,0xAE,0x5B,0x2F,0x8F,0x7B,0x60,0x4F,0x82,0xD6,0xE4,0xEA,0x2F,0x1F,0x4C,0x99}) ||

            !ff_guidcmp(g, /* DSATTRIB_TRANSPORT_PROPERTIES */ ff_DSATTRIB_TRANSPORT_PROPERTIES) ||

            !ff_guidcmp(g, /* dvr_ms_vid_frame_rep_data */ (const ff_asf_guid){0xCC,0x32,0x64,0xDD,0x29,0xE2,0xDB,0x40,0x80,0xF6,0xD2,0x63,0x28,0xD2,0x76,0x1F}) ||

            !ff_guidcmp(g, /* EVENTID_ChannelChangeSpanningEvent */ (const ff_asf_guid){0xE5,0xC5,0x67,0x90,0x5C,0x4C,0x05,0x42,0x86,0xC8,0x7A,0xFE,0x20,0xFE,0x1E,0xFA}) ||

            !ff_guidcmp(g, /* EVENTID_ChannelInfoSpanningEvent */ (const ff_asf_guid){0x80,0x6D,0xF3,0x41,0x32,0x41,0xC2,0x4C,0xB1,0x21,0x01,0xA4,0x32,0x19,0xD8,0x1B}) ||

            !ff_guidcmp(g, /* EVENTID_ChannelTypeSpanningEvent */ (const ff_asf_guid){0x51,0x1D,0xAB,0x72,0xD2,0x87,0x9B,0x48,0xBA,0x11,0x0E,0x08,0xDC,0x21,0x02,0x43}) ||

            !ff_guidcmp(g, /* EVENTID_PIDListSpanningEvent */ (const ff_asf_guid){0x65,0x8F,0xFC,0x47,0xBB,0xE2,0x34,0x46,0x9C,0xEF,0xFD,0xBF,0xE6,0x26,0x1D,0x5C}) ||

            !ff_guidcmp(g, /* EVENTID_SignalAndServiceStatusSpanningEvent */ (const ff_asf_guid){0xCB,0xC5,0x68,0x80,0x04,0x3C,0x2B,0x49,0xB4,0x7D,0x03,0x08,0x82,0x0D,0xCE,0x51}) ||

            !ff_guidcmp(g, /* EVENTID_StreamTypeSpanningEvent */ (const ff_asf_guid){0xBC,0x2E,0xAF,0x82,0xA6,0x30,0x64,0x42,0xA8,0x0B,0xAD,0x2E,0x13,0x72,0xAC,0x60}) ||

            !ff_guidcmp(g, (const ff_asf_guid){0x1E,0xBE,0xC3,0xC5,0x43,0x92,0xDC,0x11,0x85,0xE5,0x00,0x12,0x3F,0x6F,0x73,0xB9}) ||

            !ff_guidcmp(g, (const ff_asf_guid){0x3B,0x86,0xA2,0xB1,0xEB,0x1E,0xC3,0x44,0x8C,0x88,0x1C,0xA3,0xFF,0xE3,0xE7,0x6A}) ||

            !ff_guidcmp(g, (const ff_asf_guid){0x4E,0x7F,0x4C,0x5B,0xC4,0xD0,0x38,0x4B,0xA8,0x3E,0x21,0x7F,0x7B,0xBF,0x52,0xE7}) ||

            !ff_guidcmp(g, (const ff_asf_guid){0x63,0x36,0xEB,0xFE,0xA1,0x7E,0xD9,0x11,0x83,0x08,0x00,0x07,0xE9,0x5E,0xAD,0x8D}) ||

            !ff_guidcmp(g, (const ff_asf_guid){0x70,0xE9,0xF1,0xF8,0x89,0xA4,0x4C,0x4D,0x83,0x73,0xB8,0x12,0xE0,0xD5,0xF8,0x1E}) ||

            !ff_guidcmp(g, ff_index_guid) ||

            !ff_guidcmp(g, ff_sync_guid) ||

            !ff_guidcmp(g, ff_stream1_guid) ||

            !ff_guidcmp(g, (const ff_asf_guid){0xF7,0x10,0x02,0xB9,0xEE,0x7C,0xED,0x4E,0xBD,0x7F,0x05,0x40,0x35,0x86,0x18,0xA1})) {

            //ignore known guids

        } else

            av_log(s, AV_LOG_WARNING, "unsupported chunk:"FF_PRI_GUID"\n", FF_ARG_GUID(g));

        avio_skip(pb, WTV_PAD8(len) - consumed);

    }

    return AVERROR_EOF;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    dc->props = virtio_rng_properties;

    set_bit(DEVICE_CATEGORY_MISC, dc->categories);

    vdc->realize = virtio_rng_device_realize;

    vdc->unrealize = virtio_rng_device_unrealize;

    vdc->get_features = get_features;

    vdc->load = virtio_rng_load_device;

}


int kvm_init(int smp_cpus)
{
    KVMState *s;
    int ret;
    int i;
    if (smp_cpus > 1)
        return -EINVAL;
    s = qemu_mallocz(sizeof(KVMState));
    if (s == NULL)
        return -ENOMEM;
    for (i = 0; i < ARRAY_SIZE(s->slots); i++)
        s->slots[i].slot = i;
    s->vmfd = -1;
    s->fd = open("/dev/kvm", O_RDWR);
    if (s->fd == -1) {
        fprintf(stderr, "Could not access KVM kernel module: %m\n");
        ret = -errno;
        goto err;
    }
    ret = kvm_ioctl(s, KVM_GET_API_VERSION, 0);
    if (ret < KVM_API_VERSION) {
            ret = -EINVAL;
        fprintf(stderr, "kvm version too old\n");
        goto err;
    }
    if (ret > KVM_API_VERSION) {
        ret = -EINVAL;
        fprintf(stderr, "kvm version not supported\n");
        goto err;
    }
    s->vmfd = kvm_ioctl(s, KVM_CREATE_VM, 0);
    if (s->vmfd < 0)
        goto err;
    /* initially, KVM allocated its own memory and we had to jump through
     * hooks to make phys_ram_base point to this.  Modern versions of KVM
     * just use a user allocated buffer so we can use phys_ram_base
     * unmodified.  Make sure we have a sufficiently modern version of KVM.
     */
    ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_USER_MEMORY);
    if (ret <= 0) {
        if (ret == 0)
            ret = -EINVAL;
        fprintf(stderr, "kvm does not support KVM_CAP_USER_MEMORY\n");
        goto err;
    }
    /* There was a nasty bug in < kvm-80 that prevents memory slots from being
     * destroyed properly.  Since we rely on this capability, refuse to work
     * with any kernel without this capability. */
    ret = kvm_ioctl(s, KVM_CHECK_EXTENSION,
                    KVM_CAP_DESTROY_MEMORY_REGION_WORKS);
    if (ret <= 0) {
        if (ret == 0)
            ret = -EINVAL;
        fprintf(stderr,
                "KVM kernel module broken (DESTROY_MEMORY_REGION)\n"
                "Please upgrade to at least kvm-81.\n");
        goto err;
    }
    ret = kvm_arch_init(s, smp_cpus);
    if (ret < 0)
        goto err;
    kvm_state = s;
    return 0;
err:
    if (s) {
        if (s->vmfd != -1)
            close(s->vmfd);
        if (s->fd != -1)
            close(s->fd);
    }
    qemu_free(s);
    return ret;
}


static int64_t nfs_client_open(NFSClient *client, const char *filename,

                               int flags, Error **errp)

{

    int ret = -EINVAL, i;

    struct stat st;

    URI *uri;

    QueryParams *qp = NULL;

    char *file = NULL, *strp = NULL;

    uri = uri_parse(filename);

    if (!uri) {

        error_setg(errp, "Invalid URL specified");

        goto fail;

    }

    if (!uri->server) {

        error_setg(errp, "Invalid URL specified");

        goto fail;

    }

    strp = strrchr(uri->path, '/');

    if (strp == NULL) {

        error_setg(errp, "Invalid URL specified");

        goto fail;

    }

    file = g_strdup(strp);

    *strp = 0;

    client->context = nfs_init_context();

    if (client->context == NULL) {

        error_setg(errp, "Failed to init NFS context");

        goto fail;

    }

    qp = query_params_parse(uri->query);

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

        if (!qp->p[i].value) {

            error_setg(errp, "Value for NFS parameter expected: %s",

                       qp->p[i].name);

            goto fail;

        }

        if (!strncmp(qp->p[i].name, "uid", 3)) {

            nfs_set_uid(client->context, atoi(qp->p[i].value));

        } else if (!strncmp(qp->p[i].name, "gid", 3)) {

            nfs_set_gid(client->context, atoi(qp->p[i].value));

        } else if (!strncmp(qp->p[i].name, "tcp-syncnt", 10)) {

            nfs_set_tcp_syncnt(client->context, atoi(qp->p[i].value));

        } else {

            error_setg(errp, "Unknown NFS parameter name: %s",

                       qp->p[i].name);

            goto fail;

        }

    }

    ret = nfs_mount(client->context, uri->server, uri->path);

    if (ret < 0) {

        error_setg(errp, "Failed to mount nfs share: %s",

                   nfs_get_error(client->context));

        goto fail;

    }

    if (flags & O_CREAT) {

        ret = nfs_creat(client->context, file, 0600, &client->fh);

        if (ret < 0) {

            error_setg(errp, "Failed to create file: %s",

                       nfs_get_error(client->context));

            goto fail;

        }

    } else {

        ret = nfs_open(client->context, file, flags, &client->fh);

        if (ret < 0) {

            error_setg(errp, "Failed to open file : %s",

                       nfs_get_error(client->context));

            goto fail;

        }

    }

    ret = nfs_fstat(client->context, client->fh, &st);

    if (ret < 0) {

        error_setg(errp, "Failed to fstat file: %s",

                   nfs_get_error(client->context));

        goto fail;

    }

    ret = DIV_ROUND_UP(st.st_size, BDRV_SECTOR_SIZE);

    client->has_zero_init = S_ISREG(st.st_mode);

    goto out;

fail:

    nfs_client_close(client);

out:

    if (qp) {

        query_params_free(qp);

    }

    uri_free(uri);

    g_free(file);

    return ret;

}


static int nut_read_header(AVFormatContext * avf, AVFormatParameters * ap) {

    NUTContext * priv = avf->priv_data;

    AVIOContext * bc = avf->pb;

    nut_demuxer_opts_tt dopts = {

        .input = {

            .priv = bc,

            .seek = av_seek,

            .read = av_read,

            .eof = NULL,

            .file_pos = 0,

        },

        .alloc = { av_malloc, av_realloc, av_free },

        .read_index = 1,

        .cache_syncpoints = 1,

    };

    nut_context_tt * nut = priv->nut = nut_demuxer_init(&dopts);

    nut_stream_header_tt * s;

    int ret, i;

    if ((ret = nut_read_headers(nut, &s, NULL))) {

        av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret));

        return -1;

    priv->s = s;

    for (i = 0; s[i].type != -1 && i < 2; i++) {

        AVStream * st = avformat_new_stream(avf, NULL);

        int j;

        for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8);

        st->codec->has_b_frames = s[i].decode_delay;

        st->codec->extradata_size = s[i].codec_specific_len;

        if (st->codec->extradata_size) {

            st->codec->extradata = av_mallocz(st->codec->extradata_size);

            memcpy(st->codec->extradata, s[i].codec_specific, st->codec->extradata_size);

        avpriv_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den);

        st->start_time = 0;

        st->duration = s[i].max_pts;

        st->codec->codec_id = ff_codec_get_id(nut_tags, st->codec->codec_tag);

        switch(s[i].type) {

        case NUT_AUDIO_CLASS:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, st->codec->codec_tag);

            st->codec->channels = s[i].channel_count;

            st->codec->sample_rate = s[i].samplerate_num / s[i].samplerate_denom;

            break;

        case NUT_VIDEO_CLASS:

            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

            if (st->codec->codec_id == CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag);

            st->codec->width = s[i].width;

            st->codec->height = s[i].height;

            st->sample_aspect_ratio.num = s[i].sample_width;

            st->sample_aspect_ratio.den = s[i].sample_height;

            break;

        if (st->codec->codec_id == CODEC_ID_NONE) av_log(avf, AV_LOG_ERROR, "Unknown codec?!\n");

    return 0;


static void ppc_cpu_realizefn(DeviceState *dev, Error **errp)
{
    CPUState *cs = CPU(dev);
    PowerPCCPU *cpu = POWERPC_CPU(dev);
    PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
    Error *local_err = NULL;
#if !defined(CONFIG_USER_ONLY)
    int max_smt = kvm_enabled() ? kvmppc_smt_threads() : 1;
#endif
#if !defined(CONFIG_USER_ONLY)
    if (smp_threads > max_smt) {
        error_setg(errp, "Cannot support more than %d threads on PPC with %s",
                   max_smt, kvm_enabled() ? "KVM" : "TCG");
    if (!is_power_of_2(smp_threads)) {
        error_setg(errp, "Cannot support %d threads on PPC with %s, "
                   "threads count must be a power of 2.",
                   smp_threads, kvm_enabled() ? "KVM" : "TCG");
#endif
    cpu_exec_init(cs, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
#if !defined(CONFIG_USER_ONLY)
    cpu->cpu_dt_id = (cs->cpu_index / smp_threads) * max_smt
        + (cs->cpu_index % smp_threads);
#endif
    if (tcg_enabled()) {
        if (ppc_fixup_cpu(cpu) != 0) {
            error_setg(errp, "Unable to emulate selected CPU with TCG");
#if defined(TARGET_PPCEMB)
    if (!ppc_cpu_is_valid(pcc)) {
        error_setg(errp, "CPU does not possess a BookE or 4xx MMU. "
                   "Please use qemu-system-ppc or qemu-system-ppc64 instead "
                   "or choose another CPU model.");
#endif
    create_ppc_opcodes(cpu, &local_err);
    if (local_err != NULL) {
        error_propagate(errp, local_err);
    init_ppc_proc(cpu);
    if (pcc->insns_flags & PPC_FLOAT) {
        gdb_register_coprocessor(cs, gdb_get_float_reg, gdb_set_float_reg,
                                 33, "power-fpu.xml", 0);
    if (pcc->insns_flags & PPC_ALTIVEC) {
        gdb_register_coprocessor(cs, gdb_get_avr_reg, gdb_set_avr_reg,
                                 34, "power-altivec.xml", 0);
    if (pcc->insns_flags & PPC_SPE) {
        gdb_register_coprocessor(cs, gdb_get_spe_reg, gdb_set_spe_reg,
                                 34, "power-spe.xml", 0);
    if (pcc->insns_flags2 & PPC2_VSX) {
        gdb_register_coprocessor(cs, gdb_get_vsx_reg, gdb_set_vsx_reg,
                                 32, "power-vsx.xml", 0);
    qemu_init_vcpu(cs);
    pcc->parent_realize(dev, errp);
#if defined(PPC_DUMP_CPU)
    {
        CPUPPCState *env = &cpu->env;
        const char *mmu_model, *excp_model, *bus_model;
        switch (env->mmu_model) {
        case POWERPC_MMU_32B:
            mmu_model = "PowerPC 32";
            break;
        case POWERPC_MMU_SOFT_6xx:
            mmu_model = "PowerPC 6xx/7xx with software driven TLBs";
            break;
        case POWERPC_MMU_SOFT_74xx:
            mmu_model = "PowerPC 74xx with software driven TLBs";
            break;
        case POWERPC_MMU_SOFT_4xx:
            mmu_model = "PowerPC 4xx with software driven TLBs";
            break;
        case POWERPC_MMU_SOFT_4xx_Z:
            mmu_model = "PowerPC 4xx with software driven TLBs "
                "and zones protections";
            break;
        case POWERPC_MMU_REAL:
            mmu_model = "PowerPC real mode only";
            break;
        case POWERPC_MMU_MPC8xx:
            mmu_model = "PowerPC MPC8xx";
            break;
        case POWERPC_MMU_BOOKE:
            mmu_model = "PowerPC BookE";
            break;
        case POWERPC_MMU_BOOKE206:
            mmu_model = "PowerPC BookE 2.06";
            break;
        case POWERPC_MMU_601:
            mmu_model = "PowerPC 601";
            break;
#if defined (TARGET_PPC64)
        case POWERPC_MMU_64B:
            mmu_model = "PowerPC 64";
            break;
#endif
        default:
            mmu_model = "Unknown or invalid";
            break;
        switch (env->excp_model) {
        case POWERPC_EXCP_STD:
            excp_model = "PowerPC";
            break;
        case POWERPC_EXCP_40x:
            excp_model = "PowerPC 40x";
            break;
        case POWERPC_EXCP_601:
            excp_model = "PowerPC 601";
            break;
        case POWERPC_EXCP_602:
            excp_model = "PowerPC 602";
            break;
        case POWERPC_EXCP_603:
            excp_model = "PowerPC 603";
            break;
        case POWERPC_EXCP_603E:
            excp_model = "PowerPC 603e";
            break;
        case POWERPC_EXCP_604:
            excp_model = "PowerPC 604";
            break;
        case POWERPC_EXCP_7x0:
            excp_model = "PowerPC 740/750";
            break;
        case POWERPC_EXCP_7x5:
            excp_model = "PowerPC 745/755";
            break;
        case POWERPC_EXCP_74xx:
            excp_model = "PowerPC 74xx";
            break;
        case POWERPC_EXCP_BOOKE:
            excp_model = "PowerPC BookE";
            break;
#if defined (TARGET_PPC64)
        case POWERPC_EXCP_970:
            excp_model = "PowerPC 970";
            break;
#endif
        default:
            excp_model = "Unknown or invalid";
            break;
        switch (env->bus_model) {
        case PPC_FLAGS_INPUT_6xx:
            bus_model = "PowerPC 6xx";
            break;
        case PPC_FLAGS_INPUT_BookE:
            bus_model = "PowerPC BookE";
            break;
        case PPC_FLAGS_INPUT_405:
            bus_model = "PowerPC 405";
            break;
        case PPC_FLAGS_INPUT_401:
            bus_model = "PowerPC 401/403";
            break;
        case PPC_FLAGS_INPUT_RCPU:
            bus_model = "RCPU / MPC8xx";
            break;
#if defined (TARGET_PPC64)
        case PPC_FLAGS_INPUT_970:
            bus_model = "PowerPC 970";
            break;
#endif
        default:
            bus_model = "Unknown or invalid";
            break;
        printf("PowerPC %-12s : PVR %08x MSR %016" PRIx64 "\n"
               "    MMU model        : %s\n",
               object_class_get_name(OBJECT_CLASS(pcc)),
               pcc->pvr, pcc->msr_mask, mmu_model);
#if !defined(CONFIG_USER_ONLY)
        if (env->tlb.tlb6) {
            printf("                       %d %s TLB in %d ways\n",
                   env->nb_tlb, env->id_tlbs ? "splitted" : "merged",
                   env->nb_ways);
#endif
        printf("    Exceptions model : %s\n"
               "    Bus model        : %s\n",
               excp_model, bus_model);
        printf("    MSR features     :\n");
        if (env->flags & POWERPC_FLAG_SPE)
            printf("                        signal processing engine enable"
                   "\n");
        else if (env->flags & POWERPC_FLAG_VRE)
            printf("                        vector processor enable\n");
        if (env->flags & POWERPC_FLAG_TGPR)
            printf("                        temporary GPRs\n");
        else if (env->flags & POWERPC_FLAG_CE)
            printf("                        critical input enable\n");
        if (env->flags & POWERPC_FLAG_SE)
            printf("                        single-step trace mode\n");
        else if (env->flags & POWERPC_FLAG_DWE)
            printf("                        debug wait enable\n");
        else if (env->flags & POWERPC_FLAG_UBLE)
            printf("                        user BTB lock enable\n");
        if (env->flags & POWERPC_FLAG_BE)
            printf("                        branch-step trace mode\n");
        else if (env->flags & POWERPC_FLAG_DE)
            printf("                        debug interrupt enable\n");
        if (env->flags & POWERPC_FLAG_PX)
            printf("                        inclusive protection\n");
        else if (env->flags & POWERPC_FLAG_PMM)
            printf("                        performance monitor mark\n");
        if (env->flags == POWERPC_FLAG_NONE)
            printf("                        none\n");
        printf("    Time-base/decrementer clock source: %s\n",
               env->flags & POWERPC_FLAG_RTC_CLK ? "RTC clock" : "bus clock");
        dump_ppc_insns(env);
        dump_ppc_sprs(env);
        fflush(stdout);
#endif


static void ram_init(target_phys_addr_t addr, ram_addr_t RAM_size)

{

    DeviceState *dev;

    SysBusDevice *s;

    RamDevice *d;

    /* allocate RAM */

    dev = qdev_create(NULL, "memory");

    s = sysbus_from_qdev(dev);

    d = FROM_SYSBUS(RamDevice, s);

    d->size = RAM_size;

    qdev_init(dev);

    sysbus_mmio_map(s, 0, addr);

}


QemuOpts *qemu_chr_parse_compat(const char *label, const char *filename)

{

    char host[65], port[33], width[8], height[8];

    int pos;

    const char *p;

    QemuOpts *opts;

    Error *local_err = NULL;

    opts = qemu_opts_create(qemu_find_opts("chardev"), label, 1, &local_err);

    if (error_is_set(&local_err)) {

        qerror_report_err(local_err);

        error_free(local_err);

        return NULL;

    }

    if (strstart(filename, "mon:", &p)) {

        filename = p;

        qemu_opt_set(opts, "mux", "on");

        if (strcmp(filename, "stdio") == 0) {

            /* Monitor is muxed to stdio: do not exit on Ctrl+C by default

             * but pass it to the guest.  Handle this only for compat syntax,

             * for -chardev syntax we have special option for this.

             * This is what -nographic did, redirecting+muxing serial+monitor

             * to stdio causing Ctrl+C to be passed to guest. */

            qemu_opt_set(opts, "signal", "off");

        }

    }

    if (strcmp(filename, "null")    == 0 ||

        strcmp(filename, "pty")     == 0 ||

        strcmp(filename, "msmouse") == 0 ||

        strcmp(filename, "braille") == 0 ||

        strcmp(filename, "stdio")   == 0) {

        qemu_opt_set(opts, "backend", filename);

        return opts;

    }

    if (strstart(filename, "vc", &p)) {

        qemu_opt_set(opts, "backend", "vc");

        if (*p == ':') {

            if (sscanf(p+1, "%8[0-9]x%8[0-9]", width, height) == 2) {

                /* pixels */

                qemu_opt_set(opts, "width", width);

                qemu_opt_set(opts, "height", height);

            } else if (sscanf(p+1, "%8[0-9]Cx%8[0-9]C", width, height) == 2) {

                /* chars */

                qemu_opt_set(opts, "cols", width);

                qemu_opt_set(opts, "rows", height);

            } else {

                goto fail;

            }

        }

        return opts;

    }

    if (strcmp(filename, "con:") == 0) {

        qemu_opt_set(opts, "backend", "console");

        return opts;

    }

    if (strstart(filename, "COM", NULL)) {

        qemu_opt_set(opts, "backend", "serial");

        qemu_opt_set(opts, "path", filename);

        return opts;

    }

    if (strstart(filename, "file:", &p)) {

        qemu_opt_set(opts, "backend", "file");

        qemu_opt_set(opts, "path", p);

        return opts;

    }

    if (strstart(filename, "pipe:", &p)) {

        qemu_opt_set(opts, "backend", "pipe");

        qemu_opt_set(opts, "path", p);

        return opts;

    }

    if (strstart(filename, "tcp:", &p) ||

        strstart(filename, "telnet:", &p)) {

        if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {

            host[0] = 0;

            if (sscanf(p, ":%32[^,]%n", port, &pos) < 1)

                goto fail;

        }

        qemu_opt_set(opts, "backend", "socket");

        qemu_opt_set(opts, "host", host);

        qemu_opt_set(opts, "port", port);

        if (p[pos] == ',') {

            if (qemu_opts_do_parse(opts, p+pos+1, NULL) != 0)

                goto fail;

        }

        if (strstart(filename, "telnet:", &p))

            qemu_opt_set(opts, "telnet", "on");

        return opts;

    }

    if (strstart(filename, "udp:", &p)) {

        qemu_opt_set(opts, "backend", "udp");

        if (sscanf(p, "%64[^:]:%32[^@,]%n", host, port, &pos) < 2) {

            host[0] = 0;

            if (sscanf(p, ":%32[^@,]%n", port, &pos) < 1) {

                goto fail;

            }

        }

        qemu_opt_set(opts, "host", host);

        qemu_opt_set(opts, "port", port);

        if (p[pos] == '@') {

            p += pos + 1;

            if (sscanf(p, "%64[^:]:%32[^,]%n", host, port, &pos) < 2) {

                host[0] = 0;

                if (sscanf(p, ":%32[^,]%n", port, &pos) < 1) {

                    goto fail;

                }

            }

            qemu_opt_set(opts, "localaddr", host);

            qemu_opt_set(opts, "localport", port);

        }

        return opts;

    }

    if (strstart(filename, "unix:", &p)) {

        qemu_opt_set(opts, "backend", "socket");

        if (qemu_opts_do_parse(opts, p, "path") != 0)

            goto fail;

        return opts;

    }

    if (strstart(filename, "/dev/parport", NULL) ||

        strstart(filename, "/dev/ppi", NULL)) {

        qemu_opt_set(opts, "backend", "parport");

        qemu_opt_set(opts, "path", filename);

        return opts;

    }

    if (strstart(filename, "/dev/", NULL)) {

        qemu_opt_set(opts, "backend", "tty");

        qemu_opt_set(opts, "path", filename);

        return opts;

    }

fail:

    qemu_opts_del(opts);

    return NULL;

}


POWERPC_FAMILY(POWER8)(ObjectClass *oc, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);

    dc->fw_name = "PowerPC,POWER8";

    dc->desc = "POWER8";

    pcc->pvr = CPU_POWERPC_POWER8_BASE;

    pcc->pvr_mask = CPU_POWERPC_POWER8_MASK;

    pcc->init_proc = init_proc_POWER7;

    pcc->check_pow = check_pow_nocheck;

    pcc->insns_flags = PPC_INSNS_BASE | PPC_STRING | PPC_MFTB |

                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |

                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |

                       PPC_FLOAT_STFIWX |

                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |

                       PPC_MEM_SYNC | PPC_MEM_EIEIO |

                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |

                       PPC_64B | PPC_ALTIVEC |

                       PPC_SEGMENT_64B | PPC_SLBI |

                       PPC_POPCNTB | PPC_POPCNTWD;

    pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX |

                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |

                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206;

    pcc->msr_mask = 0x800000000284FF36ULL;

    pcc->mmu_model = POWERPC_MMU_2_06;

#if defined(CONFIG_SOFTMMU)

    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;

#endif

    pcc->excp_model = POWERPC_EXCP_POWER7;

    pcc->bus_model = PPC_FLAGS_INPUT_POWER7;

    pcc->bfd_mach = bfd_mach_ppc64;

    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |

                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |

                 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |

                 POWERPC_FLAG_VSX;

    pcc->l1_dcache_size = 0x8000;

    pcc->l1_icache_size = 0x8000;

}


static int parse_object_segment(AVCodecContext *avctx,

                                  const uint8_t *buf, int buf_size)

{

    PGSSubContext *ctx = avctx->priv_data;

    PGSSubObject *object;

    uint8_t sequence_desc;

    unsigned int rle_bitmap_len, width, height;

    int id;

    if (buf_size <= 4)

        return AVERROR_INVALIDDATA;

    buf_size -= 4;

    id = bytestream_get_be16(&buf);

    object = find_object(id, &ctx->objects);

    if (!object) {

        if (ctx->objects.count >= MAX_EPOCH_OBJECTS) {

            av_log(avctx, AV_LOG_ERROR, "Too many objects in epoch\n");

            return AVERROR_INVALIDDATA;

        }

        object = &ctx->objects.object[ctx->objects.count++];

        object->id = id;

    }

    /* skip object version number */

    buf += 1;

    /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */

    sequence_desc = bytestream_get_byte(&buf);

    if (!(sequence_desc & 0x80)) {

        /* Additional RLE data */

        if (buf_size > object->rle_remaining_len)

            return AVERROR_INVALIDDATA;

        memcpy(object->rle + object->rle_data_len, buf, buf_size);

        object->rle_data_len += buf_size;

        object->rle_remaining_len -= buf_size;

        return 0;

    }

    if (buf_size <= 7)

        return AVERROR_INVALIDDATA;

    buf_size -= 7;

    /* Decode rle bitmap length, stored size includes width/height data */

    rle_bitmap_len = bytestream_get_be24(&buf) - 2*2;

    if (buf_size > rle_bitmap_len) {

        av_log(avctx, AV_LOG_ERROR,

               "Buffer dimension %d larger than the expected RLE data %d\n",

               buf_size, rle_bitmap_len);

        return AVERROR_INVALIDDATA;

    }

    /* Get bitmap dimensions from data */

    width  = bytestream_get_be16(&buf);

    height = bytestream_get_be16(&buf);

    /* Make sure the bitmap is not too large */

    if (avctx->width < width || avctx->height < height || !width || !height) {

        av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions (%dx%d) invalid.\n", width, height);

        return AVERROR_INVALIDDATA;

    }

    object->w = width;

    object->h = height;

    av_fast_padded_malloc(&object->rle, &object->rle_buffer_size, rle_bitmap_len);

    if (!object->rle)

        return AVERROR(ENOMEM);

    memcpy(object->rle, buf, buf_size);

    object->rle_data_len = buf_size;

    object->rle_remaining_len = rle_bitmap_len - buf_size;

    return 0;

}


static int qemu_rdma_register_and_get_keys(RDMAContext *rdma,

        RDMALocalBlock *block, uintptr_t host_addr,

        uint32_t *lkey, uint32_t *rkey, int chunk,

        uint8_t *chunk_start, uint8_t *chunk_end)

{

    if (block->mr) {

        if (lkey) {

            *lkey = block->mr->lkey;

        }

        if (rkey) {

            *rkey = block->mr->rkey;

        }

        return 0;

    }

    /* allocate memory to store chunk MRs */

    if (!block->pmr) {

        block->pmr = g_malloc0(block->nb_chunks * sizeof(struct ibv_mr *));

    }

    /*

     * If 'rkey', then we're the destination, so grant access to the source.

     *

     * If 'lkey', then we're the source VM, so grant access only to ourselves.

     */

    if (!block->pmr[chunk]) {

        uint64_t len = chunk_end - chunk_start;

        trace_qemu_rdma_register_and_get_keys(len, chunk_start);

        block->pmr[chunk] = ibv_reg_mr(rdma->pd,

                chunk_start, len,

                (rkey ? (IBV_ACCESS_LOCAL_WRITE |

                        IBV_ACCESS_REMOTE_WRITE) : 0));

        if (!block->pmr[chunk]) {

            perror("Failed to register chunk!");

            fprintf(stderr, "Chunk details: block: %d chunk index %d"

                            " start %" PRIuPTR " end %" PRIuPTR

                            " host %" PRIuPTR

                            " local %" PRIuPTR " registrations: %d\n",

                            block->index, chunk, (uintptr_t)chunk_start,

                            (uintptr_t)chunk_end, host_addr,

                            (uintptr_t)block->local_host_addr,

                            rdma->total_registrations);

            return -1;

        }

        rdma->total_registrations++;

    }

    if (lkey) {

        *lkey = block->pmr[chunk]->lkey;

    }

    if (rkey) {

        *rkey = block->pmr[chunk]->rkey;

    }

    return 0;

}


static void vga_draw_graphic(VGAState *s, int full_update)

{

    int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth;

    int width, height, shift_control, line_offset, page0, page1, bwidth, bits;

    int disp_width, multi_scan, multi_run;

    uint8_t *d;

    uint32_t v, addr1, addr;

    vga_draw_line_func *vga_draw_line;

    full_update |= update_basic_params(s);

    if (!full_update)

        vga_sync_dirty_bitmap(s);

    s->get_resolution(s, &width, &height);

    disp_width = width;

    shift_control = (s->gr[0x05] >> 5) & 3;

    double_scan = (s->cr[0x09] >> 7);

    if (shift_control != 1) {

        multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1;

    } else {

        /* in CGA modes, multi_scan is ignored */

        /* XXX: is it correct ? */

        multi_scan = double_scan;

    }

    multi_run = multi_scan;

    if (shift_control != s->shift_control ||

        double_scan != s->double_scan) {

        full_update = 1;

        s->shift_control = shift_control;

        s->double_scan = double_scan;

    }

    if (shift_control == 0) {

        full_update |= update_palette16(s);

        if (s->sr[0x01] & 8) {

            v = VGA_DRAW_LINE4D2;

            disp_width <<= 1;

        } else {

            v = VGA_DRAW_LINE4;

        }

        bits = 4;

    } else if (shift_control == 1) {

        full_update |= update_palette16(s);

        if (s->sr[0x01] & 8) {

            v = VGA_DRAW_LINE2D2;

            disp_width <<= 1;

        } else {

            v = VGA_DRAW_LINE2;

        }

        bits = 4;

    } else {

        switch(s->get_bpp(s)) {

        default:

        case 0:

            full_update |= update_palette256(s);

            v = VGA_DRAW_LINE8D2;

            bits = 4;

            break;

        case 8:

            full_update |= update_palette256(s);

            v = VGA_DRAW_LINE8;

            bits = 8;

            break;

        case 15:

            v = VGA_DRAW_LINE15;

            bits = 16;

            break;

        case 16:

            v = VGA_DRAW_LINE16;

            bits = 16;

            break;

        case 24:

            v = VGA_DRAW_LINE24;

            bits = 24;

            break;

        case 32:

            v = VGA_DRAW_LINE32;

            bits = 32;

            break;

        }

    }

    vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)];

    depth = s->get_bpp(s);

    if (s->line_offset != s->last_line_offset ||

        disp_width != s->last_width ||

        height != s->last_height ||

        s->last_depth != depth) {

        if (depth == 16 || depth == 32) {

            if (is_graphic_console()) {

                qemu_free_displaysurface(s->ds->surface);

                s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth,

                                                               s->line_offset,

                                                               s->vram_ptr + (s->start_addr * 4));

                dpy_resize(s->ds);

            } else {

                qemu_console_resize(s->ds, disp_width, height);

            }

        } else {

            qemu_console_resize(s->ds, disp_width, height);

        }

        s->last_scr_width = disp_width;

        s->last_scr_height = height;

        s->last_width = disp_width;

        s->last_height = height;

        s->last_line_offset = s->line_offset;

        s->last_depth = depth;

        full_update = 1;

    } else if (is_graphic_console() && is_buffer_shared(s->ds->surface) &&

               (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) {

        s->ds->surface->data = s->vram_ptr + (s->start_addr * 4);

        dpy_setdata(s->ds);

    }

    s->rgb_to_pixel =

        rgb_to_pixel_dup_table[get_depth_index(s->ds)];

    if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate)

        s->cursor_invalidate(s);

    line_offset = s->line_offset;

#if 0

    printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n",

           width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]);

#endif

    addr1 = (s->start_addr * 4);

    bwidth = (width * bits + 7) / 8;

    y_start = -1;

    page_min = 0x7fffffff;

    page_max = -1;

    d = ds_get_data(s->ds);

    linesize = ds_get_linesize(s->ds);

    y1 = 0;

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

        addr = addr1;

        if (!(s->cr[0x17] & 1)) {

            int shift;

            /* CGA compatibility handling */

            shift = 14 + ((s->cr[0x17] >> 6) & 1);

            addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift);

        }

        if (!(s->cr[0x17] & 2)) {

            addr = (addr & ~0x8000) | ((y1 & 2) << 14);

        }

        page0 = s->vram_offset + (addr & TARGET_PAGE_MASK);

        page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK);

        update = full_update |

            cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) |

            cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG);

        if ((page1 - page0) > TARGET_PAGE_SIZE) {

            /* if wide line, can use another page */

            update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE,

                                                    VGA_DIRTY_FLAG);

        }

        /* explicit invalidation for the hardware cursor */

        update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1;

        if (update) {

            if (y_start < 0)

                y_start = y;

            if (page0 < page_min)

                page_min = page0;

            if (page1 > page_max)

                page_max = page1;

            if (!(is_buffer_shared(s->ds->surface))) {

                vga_draw_line(s, d, s->vram_ptr + addr, width);

                if (s->cursor_draw_line)

                    s->cursor_draw_line(s, d, y);

            }

        } else {

            if (y_start >= 0) {

                /* flush to display */

                dpy_update(s->ds, 0, y_start,

                           disp_width, y - y_start);

                y_start = -1;

            }

        }

        if (!multi_run) {

            mask = (s->cr[0x17] & 3) ^ 3;

            if ((y1 & mask) == mask)

                addr1 += line_offset;

            y1++;

            multi_run = multi_scan;

        } else {

            multi_run--;

        }

        /* line compare acts on the displayed lines */

        if (y == s->line_compare)

            addr1 = 0;

        d += linesize;

    }

    if (y_start >= 0) {

        /* flush to display */

        dpy_update(s->ds, 0, y_start,

                   disp_width, y - y_start);

    }

    /* reset modified pages */

    if (page_max != -1) {

        cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE,

                                        VGA_DIRTY_FLAG);

    }

    memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4);

}


static int qemu_signalfd_compat(const sigset_t *mask)

{

    pthread_attr_t attr;

    pthread_t tid;

    struct sigfd_compat_info *info;

    int fds[2];

    info = malloc(sizeof(*info));

    if (info == NULL) {

        errno = ENOMEM;

        return -1;

    }

    if (pipe(fds) == -1) {

        free(info);

        return -1;

    }

    memcpy(&info->mask, mask, sizeof(*mask));

    info->fd = fds[1];

    pthread_attr_init(&attr);

    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

    pthread_create(&tid, &attr, sigwait_compat, info);

    pthread_attr_destroy(&attr);

    return fds[0];

}


static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size_t len)

{

    uint32_t startlen = read_u32(data, 0);

    VNC_DEBUG("Got client start len %d\n", startlen);

    if (startlen > SASL_DATA_MAX_LEN) {

        VNC_DEBUG("Too much SASL data %d\n", startlen);

        vnc_client_error(vs);

        return -1;

    }

    if (startlen == 0)

        return protocol_client_auth_sasl_start(vs, NULL, 0);

    vnc_read_when(vs, protocol_client_auth_sasl_start, startlen);

    return 0;

}


static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw,

                                  cavs_vector *col_mv)

{

    cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS;

    int den = h->direct_den[col_mv->ref];

    int m = FF_SIGNBIT(col_mv->x);

    pmv_fw->dist = h->dist[1];

    pmv_bw->dist = h->dist[0];

    pmv_fw->ref = 1;

    pmv_bw->ref = 0;

    /* scale the co-located motion vector according to its temporal span */

    pmv_fw->x =     (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;

    pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);

    m = FF_SIGNBIT(col_mv->y);

    pmv_fw->y =     (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m;

    pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m);

}


static inline void h264_deblock_q1(register vector unsigned char p0,

                                                   register vector unsigned char p1,

                                                   register vector unsigned char p2,

                                                   register vector unsigned char q0,

                                                   register vector unsigned char tc0) {

    register vector unsigned char average = vec_avg(p0, q0);

    register vector unsigned char temp;

    register vector unsigned char uncliped;

    register vector unsigned char ones;

    register vector unsigned char max;

    register vector unsigned char min;

    temp = vec_xor(average, p2);

    average = vec_avg(average, p2);     /*avg(p2, avg(p0, q0)) */

    ones = vec_splat_u8(1);

    temp = vec_and(temp, ones);         /*(p2^avg(p0, q0)) & 1 */

    uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */

    max = vec_adds(p1, tc0);

    min = vec_subs(p1, tc0);

    p1 = vec_max(min, uncliped);

    p1 = vec_min(max, p1);

}


static inline void gen_branch_a(DisasContext *dc, target_ulong pc1,

                                target_ulong pc2, TCGv r_cond)

{

    int l1;

    l1 = gen_new_label();

    tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1);

    gen_goto_tb(dc, 0, pc2, pc1);

    gen_set_label(l1);

    gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);

}


uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs,

                                    uint64_t offset,

                                    int n_start, int n_end,

                                    int *num, QCowL2Meta *m)

{

    BDRVQcowState *s = bs->opaque;

    int l2_index, ret;

    uint64_t l2_offset, *l2_table, cluster_offset;

    int nb_clusters, i = 0;

    QCowL2Meta *old_alloc;

    ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index);

    if (ret == 0)

        return 0;

    nb_clusters = size_to_clusters(s, n_end << 9);

    nb_clusters = MIN(nb_clusters, s->l2_size - l2_index);

    cluster_offset = be64_to_cpu(l2_table[l2_index]);

    /* We keep all QCOW_OFLAG_COPIED clusters */

    if (cluster_offset & QCOW_OFLAG_COPIED) {

        nb_clusters = count_contiguous_clusters(nb_clusters, s->cluster_size,

                &l2_table[l2_index], 0, 0);

        cluster_offset &= ~QCOW_OFLAG_COPIED;

        m->nb_clusters = 0;

        goto out;

    }

    /* for the moment, multiple compressed clusters are not managed */

    if (cluster_offset & QCOW_OFLAG_COMPRESSED)

        nb_clusters = 1;

    /* how many available clusters ? */

    while (i < nb_clusters) {

        i += count_contiguous_clusters(nb_clusters - i, s->cluster_size,

                &l2_table[l2_index], i, 0);

        if(be64_to_cpu(l2_table[l2_index + i]))

            break;

        i += count_contiguous_free_clusters(nb_clusters - i,

                &l2_table[l2_index + i]);

        cluster_offset = be64_to_cpu(l2_table[l2_index + i]);

        if ((cluster_offset & QCOW_OFLAG_COPIED) ||

                (cluster_offset & QCOW_OFLAG_COMPRESSED))

            break;

    }

    nb_clusters = i;

    /*

     * Check if there already is an AIO write request in flight which allocates

     * the same cluster. In this case we need to wait until the previous

     * request has completed and updated the L2 table accordingly.

     */

    LIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) {

        uint64_t end_offset = offset + nb_clusters * s->cluster_size;

        uint64_t old_offset = old_alloc->offset;

        uint64_t old_end_offset = old_alloc->offset +

            old_alloc->nb_clusters * s->cluster_size;

        if (end_offset < old_offset || offset > old_end_offset) {

            /* No intersection */

        } else {

            if (offset < old_offset) {

                /* Stop at the start of a running allocation */

                nb_clusters = (old_offset - offset) >> s->cluster_bits;

            } else {

                nb_clusters = 0;

            }

            if (nb_clusters == 0) {

                /* Set dependency and wait for a callback */

                m->depends_on = old_alloc;

                m->nb_clusters = 0;

                *num = 0;

                return 0;

            }

        }

    }

    if (!nb_clusters) {

        abort();

    }

    LIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight);

    /* allocate a new cluster */

    cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size);

    /* save info needed for meta data update */

    m->offset = offset;

    m->n_start = n_start;

    m->nb_clusters = nb_clusters;

out:

    m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end);

    *num = m->nb_available - n_start;

    return cluster_offset;

}


static int tx_consume(Rocker *r, DescInfo *info)

{

    PCIDevice *dev = PCI_DEVICE(r);

    char *buf = desc_get_buf(info, true);

    RockerTlv *tlv_frag;

    RockerTlv *tlvs[ROCKER_TLV_TX_MAX + 1];

    struct iovec iov[ROCKER_TX_FRAGS_MAX] = { { 0, }, };

    uint32_t pport;

    uint32_t port;

    uint16_t tx_offload = ROCKER_TX_OFFLOAD_NONE;

    uint16_t tx_l3_csum_off = 0;

    uint16_t tx_tso_mss = 0;

    uint16_t tx_tso_hdr_len = 0;

    int iovcnt = 0;

    int err = ROCKER_OK;

    int rem;

    int i;

    if (!buf) {

        return -ROCKER_ENXIO;

    }

    rocker_tlv_parse(tlvs, ROCKER_TLV_TX_MAX, buf, desc_tlv_size(info));

    if (!tlvs[ROCKER_TLV_TX_FRAGS]) {

        return -ROCKER_EINVAL;

    }

    pport = rocker_get_pport_by_tx_ring(r, desc_get_ring(info));

    if (!fp_port_from_pport(pport, &port)) {

        return -ROCKER_EINVAL;

    }

    if (tlvs[ROCKER_TLV_TX_OFFLOAD]) {

        tx_offload = rocker_tlv_get_u8(tlvs[ROCKER_TLV_TX_OFFLOAD]);

    }

    switch (tx_offload) {

    case ROCKER_TX_OFFLOAD_L3_CSUM:

        if (!tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

            return -ROCKER_EINVAL;

        }

        break;

    case ROCKER_TX_OFFLOAD_TSO:

        if (!tlvs[ROCKER_TLV_TX_TSO_MSS] ||

            !tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

            return -ROCKER_EINVAL;

        }

        break;

    }

    if (tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) {

        tx_l3_csum_off = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]);

    }

    if (tlvs[ROCKER_TLV_TX_TSO_MSS]) {

        tx_tso_mss = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_MSS]);

    }

    if (tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) {

        tx_tso_hdr_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]);

    }

    rocker_tlv_for_each_nested(tlv_frag, tlvs[ROCKER_TLV_TX_FRAGS], rem) {

        hwaddr frag_addr;

        uint16_t frag_len;

        if (rocker_tlv_type(tlv_frag) != ROCKER_TLV_TX_FRAG) {

            err = -ROCKER_EINVAL;

            goto err_bad_attr;

        }

        rocker_tlv_parse_nested(tlvs, ROCKER_TLV_TX_FRAG_ATTR_MAX, tlv_frag);

        if (!tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR] ||

            !tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]) {

            err = -ROCKER_EINVAL;

            goto err_bad_attr;

        }

        frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]);

        frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]);

        iov[iovcnt].iov_len = frag_len;

        iov[iovcnt].iov_base = g_malloc(frag_len);

        if (!iov[iovcnt].iov_base) {

            err = -ROCKER_ENOMEM;

            goto err_no_mem;

        }

        if (pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base,

                     iov[iovcnt].iov_len)) {

            err = -ROCKER_ENXIO;

            goto err_bad_io;

        }

        if (++iovcnt > ROCKER_TX_FRAGS_MAX) {

            goto err_too_many_frags;

        }

    }

    if (iovcnt) {

        /* XXX perform Tx offloads */

        /* XXX   silence compiler for now */

        tx_l3_csum_off += tx_tso_mss = tx_tso_hdr_len = 0;

    }

    err = fp_port_eg(r->fp_port[port], iov, iovcnt);

err_too_many_frags:

err_bad_io:

err_no_mem:

err_bad_attr:

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

        if (iov[i].iov_base) {

            g_free(iov[i].iov_base);

        }

    }

    return err;

}


AVFilterFormats *avfilter_all_colorspaces(void)

{

    return avfilter_make_format_list(35,

                PIX_FMT_YUV444P,  PIX_FMT_YUV422P,  PIX_FMT_YUV420P,

                PIX_FMT_YUV411P,  PIX_FMT_YUV410P,

                PIX_FMT_YUYV422,  PIX_FMT_UYVY422,  PIX_FMT_UYYVYY411,

                PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P,

                PIX_FMT_YUV440P,  PIX_FMT_YUVJ440P,

                PIX_FMT_RGB32,    PIX_FMT_BGR32,

                PIX_FMT_RGB32_1,  PIX_FMT_BGR32_1,

                PIX_FMT_RGB24,    PIX_FMT_BGR24,

                PIX_FMT_RGB565,   PIX_FMT_BGR565,

                PIX_FMT_RGB555,   PIX_FMT_BGR555,

                PIX_FMT_RGB8,     PIX_FMT_BGR8,

                PIX_FMT_RGB4_BYTE,PIX_FMT_BGR4_BYTE,

                PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE,

                PIX_FMT_GRAY8,    PIX_FMT_PAL8,

                PIX_FMT_MONOWHITE,PIX_FMT_MONOBLACK

                PIX_FMT_NV12,     PIX_FMT_NV21);

}


MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB,

              CharDriverState *chrA, CharDriverState *chrB,

              int clock, int it_shift)

{

    DeviceState *dev;

    SysBusDevice *s;

    SerialState *d;

    dev = qdev_create(NULL, "escc");

    qdev_prop_set_uint32(dev, "disabled", 0);

    qdev_prop_set_uint32(dev, "frequency", clock);

    qdev_prop_set_uint32(dev, "it_shift", it_shift);

    qdev_prop_set_chr(dev, "chrB", chrB);

    qdev_prop_set_chr(dev, "chrA", chrA);

    qdev_prop_set_uint32(dev, "chnBtype", ser);

    qdev_prop_set_uint32(dev, "chnAtype", ser);

    qdev_init_nofail(dev);

    s = sysbus_from_qdev(dev);

    sysbus_connect_irq(s, 0, irqB);

    sysbus_connect_irq(s, 1, irqA);

    if (base) {

        sysbus_mmio_map(s, 0, base);

    }

    d = FROM_SYSBUS(SerialState, s);

    return &d->mmio;

}


static void free_geotags(TiffContext *const s)

{

    int i;

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

        if (s->geotags[i].val)

            av_freep(&s->geotags[i].val);

    }

    av_freep(&s->geotags);

}


void ff_bink_idct_c(DCTELEM *block)

{

    int i;

    DCTELEM temp[64];

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

        bink_idct_col(&temp[i], &block[i]);

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

        IDCT_ROW( (&block[8*i]), (&temp[8*i]) );

    }

}


PCIBus *pci_pmac_init(qemu_irq *pic)

{

    DeviceState *dev;

    SysBusDevice *s;

    UNINState *d;

    /* Use values found on a real PowerMac */

    /* Uninorth main bus */

    dev = qdev_create(NULL, "Uni-north main");

    qdev_init_nofail(dev);

    s = sysbus_from_qdev(dev);

    d = FROM_SYSBUS(UNINState, s);

    d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci",

                                         pci_unin_set_irq, pci_unin_map_irq,

                                         pic, 11 << 3, 4);

    pci_create_simple(d->host_state.bus, 11 << 3, "Uni-north main");

    sysbus_mmio_map(s, 0, 0xf2800000);

    sysbus_mmio_map(s, 1, 0xf2c00000);

    /* DEC 21154 bridge */

#if 0

    /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */

    pci_create_simple(d->host_state.bus, 12 << 3, "DEC 21154");

#endif

    /* Uninorth AGP bus */

    pci_create_simple(d->host_state.bus, 13 << 3, "Uni-north AGP");

    /* Uninorth internal bus */

#if 0

    /* XXX: not needed for now */

    pci_create_simple(d->host_state.bus, 14 << 3, "Uni-north internal");

#endif

    return d->host_state.bus;

}


static void json_message_process_token(JSONLexer *lexer, GString *input,

                                       JSONTokenType type, int x, int y)

{

    JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer);

    QDict *dict;

    switch (type) {

    case JSON_LCURLY:

        parser->brace_count++;

        break;

    case JSON_RCURLY:

        parser->brace_count--;

        break;

    case JSON_LSQUARE:

        parser->bracket_count++;

        break;

    case JSON_RSQUARE:

        parser->bracket_count--;

        break;

    default:

        break;

    }

    dict = qdict_new();

    qdict_put(dict, "type", qint_from_int(type));

    qdict_put(dict, "token", qstring_from_str(input->str));

    qdict_put(dict, "x", qint_from_int(x));

    qdict_put(dict, "y", qint_from_int(y));

    parser->token_size += input->len;

    g_queue_push_tail(parser->tokens, dict);

    if (type == JSON_ERROR) {

        goto out_emit_bad;

    } else if (parser->brace_count < 0 ||

        parser->bracket_count < 0 ||

        (parser->brace_count == 0 &&

         parser->bracket_count == 0)) {

        goto out_emit;

    } else if (parser->token_size > MAX_TOKEN_SIZE ||

               parser->bracket_count + parser->brace_count > MAX_NESTING) {

        /* Security consideration, we limit total memory allocated per object

         * and the maximum recursion depth that a message can force.

         */

        goto out_emit_bad;

    }

    return;

out_emit_bad:

    /*

     * Clear out token list and tell the parser to emit an error

     * indication by passing it a NULL list

     */

    json_message_free_tokens(parser);

out_emit:

    /* send current list of tokens to parser and reset tokenizer */

    parser->brace_count = 0;

    parser->bracket_count = 0;

    /* parser->emit takes ownership of parser->tokens.  */

    parser->emit(parser, parser->tokens);

    parser->tokens = g_queue_new();

    parser->token_size = 0;

}


static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env,

                                              target_ulong eaddr, uint32_t pid)

{

#if !defined(FLUSH_ALL_TLBS)

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

    ppcemb_tlb_t *tlb;

    hwaddr raddr;

    target_ulong page, end;

    int i;

    for (i = 0; i < env->nb_tlb; i++) {

        tlb = &env->tlb.tlbe[i];

        if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) {

            end = tlb->EPN + tlb->size;

            for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) {

                tlb_flush_page(cs, page);

            }

            tlb->prot &= ~PAGE_VALID;

            break;

        }

    }

#else

    ppc4xx_tlb_invalidate_all(env);

#endif

}


void pci_bridge_initfn(PCIDevice *dev, const char *typename)

{

    PCIBus *parent = dev->bus;

    PCIBridge *br = PCI_BRIDGE(dev);

    PCIBus *sec_bus = &br->sec_bus;

    pci_word_test_and_set_mask(dev->config + PCI_STATUS,

                               PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);

    /*

     * TODO: We implement VGA Enable in the Bridge Control Register

     * therefore per the PCI to PCI bridge spec we must also implement

     * VGA Palette Snooping.  When done, set this bit writable:

     *

     * pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND,

     *                            PCI_COMMAND_VGA_PALETTE);

     */

    pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI);

    dev->config[PCI_HEADER_TYPE] =

        (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) |

        PCI_HEADER_TYPE_BRIDGE;

    pci_set_word(dev->config + PCI_SEC_STATUS,

                 PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK);

    /*

     * If we don't specify the name, the bus will be addressed as <id>.0, where

     * id is the device id.

     * Since PCI Bridge devices have a single bus each, we don't need the index:

     * let users address the bus using the device name.

     */

    if (!br->bus_name && dev->qdev.id && *dev->qdev.id) {

	    br->bus_name = dev->qdev.id;

    }

    qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev),

                        br->bus_name);

    sec_bus->parent_dev = dev;

    sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn;

    sec_bus->address_space_mem = &br->address_space_mem;

    memory_region_init(&br->address_space_mem, OBJECT(br), "pci_bridge_pci", UINT64_MAX);

    sec_bus->address_space_io = &br->address_space_io;

    memory_region_init(&br->address_space_io, OBJECT(br), "pci_bridge_io", 65536);

    br->windows = pci_bridge_region_init(br);

    QLIST_INIT(&sec_bus->child);

    QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling);

}


void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb,

                              int width, int y)

{

    pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf,

                           0, y, 0, 0, 0, 0, width, 1);

}


static inline abi_long target_to_host_cmsg(struct msghdr *msgh,

                                           struct target_msghdr *target_msgh)

{

    struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh);

    abi_long msg_controllen;

    abi_ulong target_cmsg_addr;

    struct target_cmsghdr *target_cmsg;

    socklen_t space = 0;

    msg_controllen = tswapal(target_msgh->msg_controllen);

    if (msg_controllen < sizeof (struct target_cmsghdr))

        goto the_end;

    target_cmsg_addr = tswapal(target_msgh->msg_control);

    target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1);

    if (!target_cmsg)

        return -TARGET_EFAULT;

    while (cmsg && target_cmsg) {

        void *data = CMSG_DATA(cmsg);

        void *target_data = TARGET_CMSG_DATA(target_cmsg);

        int len = tswapal(target_cmsg->cmsg_len)

                  - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr));

        space += CMSG_SPACE(len);

        if (space > msgh->msg_controllen) {

            space -= CMSG_SPACE(len);

            gemu_log("Host cmsg overflow\n");

            break;

        }

        if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) {

            cmsg->cmsg_level = SOL_SOCKET;

        } else {

            cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level);

        }

        cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type);

        cmsg->cmsg_len = CMSG_LEN(len);

        if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) {

            gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type);

            memcpy(data, target_data, len);

        } else {

            int *fd = (int *)data;

            int *target_fd = (int *)target_data;

            int i, numfds = len / sizeof(int);

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

                fd[i] = tswap32(target_fd[i]);

        }

        cmsg = CMSG_NXTHDR(msgh, cmsg);

        target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg);

    }

    unlock_user(target_cmsg, target_cmsg_addr, 0);

 the_end:

    msgh->msg_controllen = space;

    return 0;

}


static bool ga_open_pidfile(const char *pidfile)

{

    int pidfd;

    char pidstr[32];

    pidfd = open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);

    if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) {

        g_critical("Cannot lock pid file, %s", strerror(errno));

        if (pidfd != -1) {

            close(pidfd);

        }

        return false;

    }

    if (ftruncate(pidfd, 0) || lseek(pidfd, 0, SEEK_SET)) {

        g_critical("Failed to truncate pid file");

        goto fail;

    }

    sprintf(pidstr, "%d", getpid());

    if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) {

        g_critical("Failed to write pid file");

        goto fail;

    }

    return true;

fail:

    unlink(pidfile);

    return false;

}


static void handle_pending_signal(CPUArchState *cpu_env, int sig)

{

    CPUState *cpu = ENV_GET_CPU(cpu_env);

    abi_ulong handler;

    sigset_t set, old_set;

    target_sigset_t target_old_set;

    struct target_sigaction *sa;

    struct sigqueue *q;

    TaskState *ts = cpu->opaque;

    struct emulated_sigtable *k = &ts->sigtab[sig - 1];

    trace_user_handle_signal(cpu_env, sig);

    /* dequeue signal */

    q = k->first;

    k->first = q->next;

    if (!k->first)

        k->pending = 0;

    sig = gdb_handlesig(cpu, sig);

    if (!sig) {

        sa = NULL;

        handler = TARGET_SIG_IGN;

    } else {

        sa = &sigact_table[sig - 1];

        handler = sa->_sa_handler;

    }

    if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) {

        /* Guest has blocked SIGSEGV but we got one anyway. Assume this

         * is a forced SIGSEGV (ie one the kernel handles via force_sig_info

         * because it got a real MMU fault), and treat as if default handler.

         */

        handler = TARGET_SIG_DFL;

    }

    if (handler == TARGET_SIG_DFL) {

        /* default handler : ignore some signal. The other are job control or fatal */

        if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) {

            kill(getpid(),SIGSTOP);

        } else if (sig != TARGET_SIGCHLD &&

                   sig != TARGET_SIGURG &&

                   sig != TARGET_SIGWINCH &&

                   sig != TARGET_SIGCONT) {

            force_sig(sig);

        }

    } else if (handler == TARGET_SIG_IGN) {

        /* ignore sig */

    } else if (handler == TARGET_SIG_ERR) {

        force_sig(sig);

    } else {

        /* compute the blocked signals during the handler execution */

        target_to_host_sigset(&set, &sa->sa_mask);

        /* SA_NODEFER indicates that the current signal should not be

           blocked during the handler */

        if (!(sa->sa_flags & TARGET_SA_NODEFER))

            sigaddset(&set, target_to_host_signal(sig));

        /* block signals in the handler using Linux */

        do_sigprocmask(SIG_BLOCK, &set, &old_set);

        /* save the previous blocked signal state to restore it at the

           end of the signal execution (see do_sigreturn) */

        host_to_target_sigset_internal(&target_old_set, &old_set);

        /* if the CPU is in VM86 mode, we restore the 32 bit values */

#if defined(TARGET_I386) && !defined(TARGET_X86_64)

        {

            CPUX86State *env = cpu_env;

            if (env->eflags & VM_MASK)

                save_v86_state(env);

        }

#endif

        /* prepare the stack frame of the virtual CPU */

#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \

    || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX)

        /* These targets do not have traditional signals.  */

        setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);

#else

        if (sa->sa_flags & TARGET_SA_SIGINFO)

            setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env);

        else

            setup_frame(sig, sa, &target_old_set, cpu_env);

#endif

        if (sa->sa_flags & TARGET_SA_RESETHAND) {

            sa->_sa_handler = TARGET_SIG_DFL;

        }

    }

    if (q != &k->info)

        free_sigqueue(cpu_env, q);

}


static void pcie_pci_bridge_write_config(PCIDevice *d,

        uint32_t address, uint32_t val, int len)

{

    pci_bridge_write_config(d, address, val, len);

    msi_write_config(d, address, val, len);

    shpc_cap_write_config(d, address, val, len);

}


static ram_addr_t find_ram_offset(ram_addr_t size)

{

    RAMBlock *block, *next_block;

    ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX;

    assert(size != 0); /* it would hand out same offset multiple times */

    if (QTAILQ_EMPTY(&ram_list.blocks))

        return 0;

    QTAILQ_FOREACH(block, &ram_list.blocks, next) {

        ram_addr_t end, next = RAM_ADDR_MAX;

        end = block->offset + block->length;

        QTAILQ_FOREACH(next_block, &ram_list.blocks, next) {

            if (next_block->offset >= end) {

                next = MIN(next, next_block->offset);

            }

        }

        if (next - end >= size && next - end < mingap) {

            offset = end;

            mingap = next - end;

        }

    }

    if (offset == RAM_ADDR_MAX) {

        fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n",

                (uint64_t)size);

        abort();

    }

    return offset;

}


CharDriverState *qemu_chr_alloc(void)

{

    CharDriverState *chr = g_malloc0(sizeof(CharDriverState));

    qemu_mutex_init(&chr->chr_write_lock);

    return chr;

}


static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf)

{

    SCSIRequest *req = &r->req;

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

    uint64_t nb_sectors;

    int buflen = 0;

    int ret;

    switch (req->cmd.buf[0]) {

    case TEST_UNIT_READY:

        if (!bdrv_is_inserted(s->bs))

            goto not_ready;

        break;

    case REQUEST_SENSE:

        if (req->cmd.xfer < 4)

            goto illegal_request;

        buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer,

                                       (req->cmd.buf[1] & 1) == 0);

        break;

    case INQUIRY:

        buflen = scsi_disk_emulate_inquiry(req, outbuf);

        if (buflen < 0)

            goto illegal_request;

        break;

    case MODE_SENSE:

    case MODE_SENSE_10:

        buflen = scsi_disk_emulate_mode_sense(req, outbuf);

        if (buflen < 0)

            goto illegal_request;

        break;

    case READ_TOC:

        buflen = scsi_disk_emulate_read_toc(req, outbuf);

        if (buflen < 0)

            goto illegal_request;

        break;

    case RESERVE:

        if (req->cmd.buf[1] & 1)

            goto illegal_request;

        break;

    case RESERVE_10:

        if (req->cmd.buf[1] & 3)

            goto illegal_request;

        break;

    case RELEASE:

        if (req->cmd.buf[1] & 1)

            goto illegal_request;

        break;

    case RELEASE_10:

        if (req->cmd.buf[1] & 3)

            goto illegal_request;

        break;

    case START_STOP:

        if (s->qdev.type == TYPE_ROM && (req->cmd.buf[4] & 2)) {

            /* load/eject medium */

            bdrv_eject(s->bs, !(req->cmd.buf[4] & 1));

        }

        break;

    case ALLOW_MEDIUM_REMOVAL:

        bdrv_set_locked(s->bs, req->cmd.buf[4] & 1);

        break;

    case READ_CAPACITY_10:

        /* The normal LEN field for this command is zero.  */

        memset(outbuf, 0, 8);

        bdrv_get_geometry(s->bs, &nb_sectors);

        if (!nb_sectors)

            goto not_ready;

        nb_sectors /= s->cluster_size;

        /* Returned value is the address of the last sector.  */

        nb_sectors--;

        /* Remember the new size for read/write sanity checking. */

        s->max_lba = nb_sectors;

        /* Clip to 2TB, instead of returning capacity modulo 2TB. */

        if (nb_sectors > UINT32_MAX)

            nb_sectors = UINT32_MAX;

        outbuf[0] = (nb_sectors >> 24) & 0xff;

        outbuf[1] = (nb_sectors >> 16) & 0xff;

        outbuf[2] = (nb_sectors >> 8) & 0xff;

        outbuf[3] = nb_sectors & 0xff;

        outbuf[4] = 0;

        outbuf[5] = 0;

        outbuf[6] = s->cluster_size * 2;

        outbuf[7] = 0;

        buflen = 8;

        break;

    case SYNCHRONIZE_CACHE:

        ret = bdrv_flush(s->bs);

        if (ret < 0) {

            if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) {

                return -1;

            }

        }

        break;

    case GET_CONFIGURATION:

        memset(outbuf, 0, 8);

        /* ??? This should probably return much more information.  For now

           just return the basic header indicating the CD-ROM profile.  */

        outbuf[7] = 8; // CD-ROM

        buflen = 8;

        break;

    case SERVICE_ACTION_IN:

        /* Service Action In subcommands. */

        if ((req->cmd.buf[1] & 31) == 0x10) {

            DPRINTF("SAI READ CAPACITY(16)\n");

            memset(outbuf, 0, req->cmd.xfer);

            bdrv_get_geometry(s->bs, &nb_sectors);

            if (!nb_sectors)

                goto not_ready;

            nb_sectors /= s->cluster_size;

            /* Returned value is the address of the last sector.  */

            nb_sectors--;

            /* Remember the new size for read/write sanity checking. */

            s->max_lba = nb_sectors;

            outbuf[0] = (nb_sectors >> 56) & 0xff;

            outbuf[1] = (nb_sectors >> 48) & 0xff;

            outbuf[2] = (nb_sectors >> 40) & 0xff;

            outbuf[3] = (nb_sectors >> 32) & 0xff;

            outbuf[4] = (nb_sectors >> 24) & 0xff;

            outbuf[5] = (nb_sectors >> 16) & 0xff;

            outbuf[6] = (nb_sectors >> 8) & 0xff;

            outbuf[7] = nb_sectors & 0xff;

            outbuf[8] = 0;

            outbuf[9] = 0;

            outbuf[10] = s->cluster_size * 2;

            outbuf[11] = 0;

            outbuf[12] = 0;

            outbuf[13] = get_physical_block_exp(&s->qdev.conf);

            /* set TPE bit if the format supports discard */

            if (s->qdev.conf.discard_granularity) {

                outbuf[14] = 0x80;

            }

            /* Protection, exponent and lowest lba field left blank. */

            buflen = req->cmd.xfer;

            break;

        }

        DPRINTF("Unsupported Service Action In\n");

        goto illegal_request;

    case REPORT_LUNS:

        if (req->cmd.xfer < 16)

            goto illegal_request;

        memset(outbuf, 0, 16);

        outbuf[3] = 8;

        buflen = 16;

        break;

    case VERIFY_10:

        break;

    default:

        scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE));

        return -1;

    }

    return buflen;

not_ready:

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

        scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));

    } else {

        scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY));

    }

    return -1;

illegal_request:

    scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));

    return -1;

}


static void flush_queued_work(CPUState *cpu)

{

    struct qemu_work_item *wi;

    if (cpu->queued_work_first == NULL) {

        return;

    }

    while ((wi = cpu->queued_work_first)) {

        cpu->queued_work_first = wi->next;

        wi->func(wi->data);

        wi->done = true;

        if (wi->free) {

            g_free(wi);

        }

    }

    cpu->queued_work_last = NULL;

    qemu_cond_broadcast(&qemu_work_cond);

}


static int validate_guest_space(unsigned long guest_base,

                                unsigned long guest_size)

{

    unsigned long real_start, test_page_addr;

    /* We need to check that we can force a fault on access to the

     * commpage at 0xffff0fxx

     */

    test_page_addr = guest_base + (0xffff0f00 & qemu_host_page_mask);

    /* If the commpage lies within the already allocated guest space,

     * then there is no way we can allocate it.

     */

    if (test_page_addr >= guest_base

        && test_page_addr <= (guest_base + guest_size)) {

        return -1;

    }

    /* Note it needs to be writeable to let us initialise it */

    real_start = (unsigned long)

                 mmap((void *)test_page_addr, qemu_host_page_size,

                     PROT_READ | PROT_WRITE,

                     MAP_ANONYMOUS | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

    /* If we can't map it then try another address */

    if (real_start == -1ul) {

        return 0;

    }

    if (real_start != test_page_addr) {

        /* OS didn't put the page where we asked - unmap and reject */

        munmap((void *)real_start, qemu_host_page_size);

        return 0;

    }

    /* Leave the page mapped

     * Populate it (mmap should have left it all 0'd)

     */

    /* Kernel helper versions */

    __put_user(5, (uint32_t *)g2h(0xffff0ffcul));

    /* Now it's populated make it RO */

    if (mprotect((void *)test_page_addr, qemu_host_page_size, PROT_READ)) {

        perror("Protecting guest commpage");

        exit(-1);

    }

    return 1; /* All good */

}


long do_sigreturn(CPUCRISState *env)

{

	struct target_signal_frame *frame;

	abi_ulong frame_addr;

	target_sigset_t target_set;

	sigset_t set;

	int i;

	frame_addr = env->regs[R_SP];

	/* Make sure the guest isn't playing games.  */

	if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1))

		goto badframe;

	/* Restore blocked signals */

	if (__get_user(target_set.sig[0], &frame->sc.oldmask))

		goto badframe;

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

		if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))

			goto badframe;

	}

	target_to_host_sigset_internal(&set, &target_set);

        do_sigprocmask(SIG_SETMASK, &set, NULL);

	restore_sigcontext(&frame->sc, env);

	unlock_user_struct(frame, frame_addr, 0);

	return env->regs[10];

  badframe:

	unlock_user_struct(frame, frame_addr, 0);

	force_sig(TARGET_SIGSEGV);

}


static void usbredir_interrupt_packet(void *priv, uint32_t id,

    struct usb_redir_interrupt_packet_header *interrupt_packet,

    uint8_t *data, int data_len)

{

    USBRedirDevice *dev = priv;

    uint8_t ep = interrupt_packet->endpoint;

    DPRINTF("interrupt-in status %d ep %02X len %d id %u\n",

            interrupt_packet->status, ep, data_len, id);

    if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) {

        ERROR("received int packet for non interrupt endpoint %02X\n", ep);

        free(data);

        return;

    }

    if (ep & USB_DIR_IN) {

        if (dev->endpoint[EP2I(ep)].interrupt_started == 0) {

            DPRINTF("received int packet while not started ep %02X\n", ep);

            free(data);

            return;

        }

        /* bufp_alloc also adds the packet to the ep queue */

        bufp_alloc(dev, data, data_len, interrupt_packet->status, ep);

    } else {

        int len = interrupt_packet->length;

        AsyncURB *aurb = async_find(dev, id);

        if (!aurb) {

            return;

        }

        if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) {

            ERROR("return int packet mismatch, please report this!\n");

            len = USB_RET_NAK;

        }

        if (aurb->packet) {

            aurb->packet->len = usbredir_handle_status(dev,

                                               interrupt_packet->status, len);

            usb_packet_complete(&dev->dev, aurb->packet);

        }

        async_free(dev, aurb);

    }

}


void mpeg1_encode_mb(MpegEncContext *s,

                     DCTELEM block[6][64],

                     int motion_x, int motion_y)

{

    int i, cbp;

    const int mb_x = s->mb_x;

    const int mb_y = s->mb_y;

    const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y;

    /* compute cbp */

    cbp = 0;

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

        if (s->block_last_index[i] >= 0)

            cbp |= 1 << (5 - i);

    }

    if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) &&

        ((s->pict_type == P_TYPE && s->mv_type == MV_TYPE_16X16 && (motion_x | motion_y) == 0) ||

        (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) |

        ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) {

        s->mb_skip_run++;

        s->qscale -= s->dquant;

        s->skip_count++;

        s->misc_bits++;

        s->last_bits++;

        if(s->pict_type == P_TYPE){

            s->last_mv[0][1][0]= s->last_mv[0][0][0]=

            s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0;

        }

    } else {

        if(first_mb){

            assert(s->mb_skip_run == 0);

            encode_mb_skip_run(s, s->mb_x);

        }else{

            encode_mb_skip_run(s, s->mb_skip_run);

        }

        if (s->pict_type == I_TYPE) {

            if(s->dquant && cbp){

                put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */

                put_bits(&s->pb, 5, s->qscale);

            }else{

                put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */

                s->qscale -= s->dquant;

            }

            s->misc_bits+= get_bits_diff(s);

            s->i_count++;

        } else if (s->mb_intra) {

            if(s->dquant && cbp){

                put_mb_modes(s, 6, 0x01, 0, 0);

                put_bits(&s->pb, 5, s->qscale);

            }else{

                put_mb_modes(s, 5, 0x03, 0, 0);

                s->qscale -= s->dquant;

            }

            s->misc_bits+= get_bits_diff(s);

            s->i_count++;

            memset(s->last_mv, 0, sizeof(s->last_mv));

        } else if (s->pict_type == P_TYPE) {

            if(s->mv_type == MV_TYPE_16X16){

                if (cbp != 0) {

                    if ((motion_x|motion_y) == 0) {

                        if(s->dquant){

                            put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */

                            put_bits(&s->pb, 5, s->qscale);

                        }else{

                            put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */

                        }

                        s->misc_bits+= get_bits_diff(s);

                    } else {

                        if(s->dquant){

                            put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */

                            put_bits(&s->pb, 5, s->qscale);

                        }else{

                            put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */

                        }

                        s->misc_bits+= get_bits_diff(s);

                        mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);    // RAL: f_code parameter added

                        mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);    // RAL: f_code parameter added

                        s->mv_bits+= get_bits_diff(s);

                    }

                } else {

                    put_bits(&s->pb, 3, 1); /* motion only */

                    if (!s->frame_pred_frame_dct)

                        put_bits(&s->pb, 2, 2); /* motion_type: frame */

                    s->misc_bits+= get_bits_diff(s);

                    mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code);    // RAL: f_code parameter added

                    mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code);    // RAL: f_code parameter added

                    s->qscale -= s->dquant;

                    s->mv_bits+= get_bits_diff(s);

                }

                s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x;

                s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y;

            }else{

                assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD);

                if (cbp) {

                    if(s->dquant){

                        put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */

                        put_bits(&s->pb, 5, s->qscale);

                    }else{

                        put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */

                    }

                } else {

                    put_bits(&s->pb, 3, 1); /* motion only */

                    put_bits(&s->pb, 2, 1); /* motion_type: field */

                    s->qscale -= s->dquant;

                }

                s->misc_bits+= get_bits_diff(s);

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

                    put_bits(&s->pb, 1, s->field_select[0][i]);

                    mpeg1_encode_motion(s, s->mv[0][i][0] -  s->last_mv[0][i][0]    , s->f_code);

                    mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);

                    s->last_mv[0][i][0]=   s->mv[0][i][0];

                    s->last_mv[0][i][1]= 2*s->mv[0][i][1];

                }

                s->mv_bits+= get_bits_diff(s);

            }

            if(cbp)

                put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);

            s->f_count++;

        } else{

            static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi

            if(s->mv_type == MV_TYPE_16X16){

                if (cbp){    // With coded bloc pattern

                    if (s->dquant) {

                        if(s->mv_dir == MV_DIR_FORWARD)

                            put_mb_modes(s, 6, 3, 1, 0);

                        else

                            put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0);

                        put_bits(&s->pb, 5, s->qscale);

                    } else {

                        put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0);

                    }

                }else{    // No coded bloc pattern

                    put_bits(&s->pb, mb_type_len[s->mv_dir], 2);

                    if (!s->frame_pred_frame_dct)

                        put_bits(&s->pb, 2, 2); /* motion_type: frame */

                    s->qscale -= s->dquant;

                }

                s->misc_bits += get_bits_diff(s);

                if (s->mv_dir&MV_DIR_FORWARD){

                    mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code);

                    mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code);

                    s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0];

                    s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1];

                    s->f_count++;

                }

                if (s->mv_dir&MV_DIR_BACKWARD){

                    mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code);

                    mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code);

                    s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0];

                    s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1];

                    s->b_count++;

                }

            }else{

                assert(s->mv_type == MV_TYPE_FIELD);

                assert(!s->frame_pred_frame_dct);

                if (cbp){    // With coded bloc pattern

                    if (s->dquant) {

                        if(s->mv_dir == MV_DIR_FORWARD)

                            put_mb_modes(s, 6, 3, 1, 1);

                        else

                            put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1);

                        put_bits(&s->pb, 5, s->qscale);

                    } else {

                        put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1);

                    }

                }else{    // No coded bloc pattern

                    put_bits(&s->pb, mb_type_len[s->mv_dir], 2);

                    put_bits(&s->pb, 2, 1); /* motion_type: field */

                    s->qscale -= s->dquant;

                }

                s->misc_bits += get_bits_diff(s);

                if (s->mv_dir&MV_DIR_FORWARD){

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

                        put_bits(&s->pb, 1, s->field_select[0][i]);

                        mpeg1_encode_motion(s, s->mv[0][i][0] -  s->last_mv[0][i][0]    , s->f_code);

                        mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code);

                        s->last_mv[0][i][0]=   s->mv[0][i][0];

                        s->last_mv[0][i][1]= 2*s->mv[0][i][1];

                    }

                    s->f_count++;

                }

                if (s->mv_dir&MV_DIR_BACKWARD){

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

                        put_bits(&s->pb, 1, s->field_select[1][i]);

                        mpeg1_encode_motion(s, s->mv[1][i][0] -  s->last_mv[1][i][0]    , s->b_code);

                        mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code);

                        s->last_mv[1][i][0]=   s->mv[1][i][0];

                        s->last_mv[1][i][1]= 2*s->mv[1][i][1];

                    }

                    s->b_count++;

                }

            }

            s->mv_bits += get_bits_diff(s);

            if(cbp)

                put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]);

        }

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

            if (cbp & (1 << (5 - i))) {

                mpeg1_encode_block(s, block[i], i);

            }

        }

        s->mb_skip_run = 0;

        if(s->mb_intra)

            s->i_tex_bits+= get_bits_diff(s);

        else

            s->p_tex_bits+= get_bits_diff(s);

    }

}