static int hevc_handle_packet(AVFormatContext *ctx, PayloadContext *rtp_hevc_ctx,

                              AVStream *st, AVPacket *pkt, uint32_t *timestamp,

                              const uint8_t *buf, int len, uint16_t seq,

                              int flags)

{

    const uint8_t *rtp_pl = buf;

    int tid, lid, nal_type;

    int first_fragment, last_fragment, fu_type;

    uint8_t new_nal_header[2];

    int res = 0;

    /* sanity check for size of input packet: 1 byte payload at least */

    if (len < RTP_HEVC_PAYLOAD_HEADER_SIZE + 1) {

        av_log(ctx, AV_LOG_ERROR, "Too short RTP/HEVC packet, got %d bytes\n", len);

        return AVERROR_INVALIDDATA;

    }

    /*

      decode the HEVC payload header according to section 4 of draft version 6:

         0                   1

         0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5

        +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

        |F|   Type    |  LayerId  | TID |

        +-------------+-----------------+

           Forbidden zero (F): 1 bit

           NAL unit type (Type): 6 bits

           NUH layer ID (LayerId): 6 bits

           NUH temporal ID plus 1 (TID): 3 bits

    */

    nal_type =  (buf[0] >> 1) & 0x3f;

    lid  = ((buf[0] << 5) & 0x20) | ((buf[1] >> 3) & 0x1f);

    tid  =   buf[1] & 0x07;

    /* sanity check for correct layer ID */

    if (lid) {

        /* future scalable or 3D video coding extensions */

        avpriv_report_missing_feature(ctx, "Multi-layer HEVC coding\n");

        return AVERROR_PATCHWELCOME;

    }

    /* sanity check for correct temporal ID */

    if (!tid) {

        av_log(ctx, AV_LOG_ERROR, "Illegal temporal ID in RTP/HEVC packet\n");

        return AVERROR_INVALIDDATA;

    }

    /* sanity check for correct NAL unit type */

    if (nal_type > 50) {

        av_log(ctx, AV_LOG_ERROR, "Unsupported (HEVC) NAL type (%d)\n", nal_type);

        return AVERROR_INVALIDDATA;

    }

    switch (nal_type) {

    /* aggregated packets (AP) */

    case 48:

        /* pass the HEVC payload header */

        buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;

        /* pass the HEVC DONL field */

        if (rtp_hevc_ctx->using_donl_field) {

            buf += RTP_HEVC_DONL_FIELD_SIZE;

            len -= RTP_HEVC_DONL_FIELD_SIZE;

        }

        /* fall-through */

    /* video parameter set (VPS) */

    case 32:

    /* sequence parameter set (SPS) */

    case 33:

    /* picture parameter set (PPS) */

    case 34:

    /*  supplemental enhancement information (SEI) */

    case 39:

    /* single NAL unit packet */

    default:

        /* sanity check for size of input packet: 1 byte payload at least */

        if (len < 1) {

            av_log(ctx, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   len, nal_type);

            return AVERROR_INVALIDDATA;

        }

        /* create A/V packet */

        if ((res = av_new_packet(pkt, sizeof(start_sequence) + len)) < 0)

            return res;

        /* A/V packet: copy start sequence */

        memcpy(pkt->data, start_sequence, sizeof(start_sequence));

        /* A/V packet: copy NAL unit data */

        memcpy(pkt->data + sizeof(start_sequence), buf, len);

        break;

    /* fragmentation unit (FU) */

    case 49:

        /* pass the HEVC payload header */

        buf += RTP_HEVC_PAYLOAD_HEADER_SIZE;

        len -= RTP_HEVC_PAYLOAD_HEADER_SIZE;

        if (len < 1)

            return AVERROR_INVALIDDATA;

        /*

             decode the FU header

              0 1 2 3 4 5 6 7

             +-+-+-+-+-+-+-+-+

             |S|E|  FuType   |

             +---------------+

                Start fragment (S): 1 bit

                End fragment (E): 1 bit

                FuType: 6 bits

        */

        first_fragment = buf[0] & 0x80;

        last_fragment  = buf[0] & 0x40;

        fu_type        = buf[0] & 0x3f;

        /* pass the HEVC FU header */

        buf += RTP_HEVC_FU_HEADER_SIZE;

        len -= RTP_HEVC_FU_HEADER_SIZE;

        /* pass the HEVC DONL field */

        if (rtp_hevc_ctx->using_donl_field) {

            buf += RTP_HEVC_DONL_FIELD_SIZE;

            len -= RTP_HEVC_DONL_FIELD_SIZE;

        }

        av_dlog(ctx, " FU type %d with %d bytes\n", fu_type, len);

        if (len > 0) {

            new_nal_header[0] = (rtp_pl[0] & 0x81) | (fu_type << 1);

            new_nal_header[1] = rtp_pl[1];

            /* start fragment vs. subsequent fragments */

            if (first_fragment) {

                if (!last_fragment) {

                    /* create A/V packet which is big enough */

                    if ((res = av_new_packet(pkt, sizeof(start_sequence) + sizeof(new_nal_header) + len)) < 0)

                        return res;

                    /* A/V packet: copy start sequence */

                    memcpy(pkt->data, start_sequence, sizeof(start_sequence));

                    /* A/V packet: copy new NAL header */

                    memcpy(pkt->data + sizeof(start_sequence), new_nal_header, sizeof(new_nal_header));

                    /* A/V packet: copy NAL unit data */

                    memcpy(pkt->data + sizeof(start_sequence) + sizeof(new_nal_header), buf, len);

                } else {

                    av_log(ctx, AV_LOG_ERROR, "Illegal combination of S and E bit in RTP/HEVC packet\n");

                    res = AVERROR_INVALIDDATA;

                }

            } else {

                /* create A/V packet */

                if ((res = av_new_packet(pkt, len)) < 0)

                    return res;

                /* A/V packet: copy NAL unit data */

                memcpy(pkt->data, buf, len);

            }

        } else {

            /* sanity check for size of input packet: 1 byte payload at least */

            av_log(ctx, AV_LOG_ERROR,

                   "Too short RTP/HEVC packet, got %d bytes of NAL unit type %d\n",

                   len, nal_type);

            res = AVERROR_INVALIDDATA;

        }

        break;

    /* PACI packet */

    case 50:

        /* Temporal scalability control information (TSCI) */

        avpriv_report_missing_feature(ctx, "PACI packets for RTP/HEVC\n");

        res = AVERROR_PATCHWELCOME;

        break;

    }

    pkt->stream_index = st->index;

    return res;

}


static void openpic_cpu_write_internal(void *opaque, hwaddr addr,

                                       uint32_t val, int idx)

{

    OpenPICState *opp = opaque;

    IRQ_src_t *src;

    IRQ_dst_t *dst;

    int s_IRQ, n_IRQ;

    DPRINTF("%s: cpu %d addr " TARGET_FMT_plx " <= %08x\n", __func__, idx,

            addr, val);

    if (idx < 0) {

        return;

    }

    if (addr & 0xF)

        return;

    dst = &opp->dst[idx];

    addr &= 0xFF0;

    switch (addr) {

    case 0x40: /* IPIDR */

    case 0x50:

    case 0x60:

    case 0x70:

        idx = (addr - 0x40) >> 4;

        /* we use IDE as mask which CPUs to deliver the IPI to still. */

        write_IRQreg_ide(opp, opp->irq_ipi0 + idx,

                         opp->src[opp->irq_ipi0 + idx].ide | val);

        openpic_set_irq(opp, opp->irq_ipi0 + idx, 1);

        openpic_set_irq(opp, opp->irq_ipi0 + idx, 0);

        break;

    case 0x80: /* PCTP */

        dst->pctp = val & 0x0000000F;

        break;

    case 0x90: /* WHOAMI */

        /* Read-only register */

        break;

    case 0xA0: /* PIAC */

        /* Read-only register */

        break;

    case 0xB0: /* PEOI */

        DPRINTF("PEOI\n");

        s_IRQ = IRQ_get_next(opp, &dst->servicing);

        IRQ_resetbit(&dst->servicing, s_IRQ);

        dst->servicing.next = -1;

        /* Set up next servicing IRQ */

        s_IRQ = IRQ_get_next(opp, &dst->servicing);

        /* Check queued interrupts. */

        n_IRQ = IRQ_get_next(opp, &dst->raised);

        src = &opp->src[n_IRQ];

        if (n_IRQ != -1 &&

            (s_IRQ == -1 ||

             IPVP_PRIORITY(src->ipvp) > dst->servicing.priority)) {

            DPRINTF("Raise OpenPIC INT output cpu %d irq %d\n",

                    idx, n_IRQ);

            openpic_irq_raise(opp, idx, src);

        }

        break;

    default:

        break;

    }

}


int kvm_init(void)

{

    static const char upgrade_note[] =

        "Please upgrade to at least kernel 2.6.29 or recent kvm-kmod\n"

        "(see http://sourceforge.net/projects/kvm).\n";

    KVMState *s;

    const KVMCapabilityInfo *missing_cap;

    int ret;

    int i;

    s = g_malloc0(sizeof(KVMState));

#ifdef KVM_CAP_SET_GUEST_DEBUG

    QTAILQ_INIT(&s->kvm_sw_breakpoints);

#endif

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

        s->slots[i].slot = i;

    }

    s->vmfd = -1;

    s->fd = qemu_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) {

        if (ret > 0) {

            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) {

#ifdef TARGET_S390X

        fprintf(stderr, "Please add the 'switch_amode' kernel parameter to "

                        "your host kernel command line\n");

#endif

        ret = s->vmfd;

        goto err;

    }

    missing_cap = kvm_check_extension_list(s, kvm_required_capabilites);

    if (!missing_cap) {

        missing_cap =

            kvm_check_extension_list(s, kvm_arch_required_capabilities);

    }

    if (missing_cap) {

        ret = -EINVAL;

        fprintf(stderr, "kvm does not support %s\n%s",

                missing_cap->name, upgrade_note);

        goto err;

    }

    s->coalesced_mmio = kvm_check_extension(s, KVM_CAP_COALESCED_MMIO);

    s->broken_set_mem_region = 1;

    ret = kvm_check_extension(s, KVM_CAP_JOIN_MEMORY_REGIONS_WORKS);

    if (ret > 0) {

        s->broken_set_mem_region = 0;

    }

#ifdef KVM_CAP_VCPU_EVENTS

    s->vcpu_events = kvm_check_extension(s, KVM_CAP_VCPU_EVENTS);

#endif

    s->robust_singlestep =

        kvm_check_extension(s, KVM_CAP_X86_ROBUST_SINGLESTEP);

#ifdef KVM_CAP_DEBUGREGS

    s->debugregs = kvm_check_extension(s, KVM_CAP_DEBUGREGS);

#endif

#ifdef KVM_CAP_XSAVE

    s->xsave = kvm_check_extension(s, KVM_CAP_XSAVE);

#endif

#ifdef KVM_CAP_XCRS

    s->xcrs = kvm_check_extension(s, KVM_CAP_XCRS);

#endif

    ret = kvm_arch_init(s);

    if (ret < 0) {

        goto err;

    }

    kvm_state = s;

    cpu_register_phys_memory_client(&kvm_cpu_phys_memory_client);

    s->many_ioeventfds = kvm_check_many_ioeventfds();

    cpu_interrupt_handler = kvm_handle_interrupt;

    return 0;

err:

    if (s) {

        if (s->vmfd >= 0) {

            close(s->vmfd);

        }

        if (s->fd != -1) {

            close(s->fd);

        }

    }

    g_free(s);

    return ret;

}


static int process_line(URLContext *h, char *line, int line_count,

                        int *new_location)

{

    HTTPContext *s = h->priv_data;

    char *tag, *p, *end;

    /* end of header */

    if (line[0] == '\0') {

        s->end_header = 1;

        return 0;

    }

    p = line;

    if (line_count == 0) {

        while (!isspace(*p) && *p != '\0')

            p++;

        while (isspace(*p))

            p++;

        s->http_code = strtol(p, &end, 10);

        av_dlog(NULL, "http_code=%d\n", s->http_code);

        /* error codes are 4xx and 5xx, but regard 401 as a success, so we

         * don't abort until all headers have been parsed. */

        if (s->http_code >= 400 && s->http_code < 600 && (s->http_code != 401

            || s->auth_state.auth_type != HTTP_AUTH_NONE) &&

            (s->http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) {

            end += strspn(end, SPACE_CHARS);

            av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n",

                   s->http_code, end);

            return -1;

        }

    } else {

        while (*p != '\0' && *p != ':')

            p++;

        if (*p != ':')

            return 1;

        *p = '\0';

        tag = line;

        p++;

        while (isspace(*p))

            p++;

        if (!av_strcasecmp(tag, "Location")) {

            av_strlcpy(s->location, p, sizeof(s->location));

            *new_location = 1;

        } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {

            s->filesize = strtoll(p, NULL, 10);

        } else if (!av_strcasecmp (tag, "Content-Range")) {

            /* "bytes $from-$to/$document_size" */

            const char *slash;

            if (!strncmp (p, "bytes ", 6)) {

                p += 6;

                s->off = strtoll(p, NULL, 10);

                if ((slash = strchr(p, '/')) && strlen(slash) > 0)

                    s->filesize = strtoll(slash+1, NULL, 10);

            }

            if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))

                h->is_streamed = 0; /* we _can_ in fact seek */

        } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5) && s->seekable == -1) {

            h->is_streamed = 0;

        } else if (!av_strcasecmp (tag, "Transfer-Encoding") && !av_strncasecmp(p, "chunked", 7)) {

            s->filesize = -1;

            s->chunksize = 0;

        } else if (!av_strcasecmp (tag, "WWW-Authenticate")) {

            ff_http_auth_handle_header(&s->auth_state, tag, p);

        } else if (!av_strcasecmp (tag, "Authentication-Info")) {

            ff_http_auth_handle_header(&s->auth_state, tag, p);

        } else if (!av_strcasecmp (tag, "Proxy-Authenticate")) {

            ff_http_auth_handle_header(&s->proxy_auth_state, tag, p);

        } else if (!av_strcasecmp (tag, "Connection")) {

            if (!strcmp(p, "close"))

                s->willclose = 1;

        } else if (!av_strcasecmp (tag, "Server") && !av_strcasecmp (p, "AkamaiGHost")) {

            s->is_akamai = 1;

        } else if (!av_strcasecmp (tag, "Content-Type") && p) {

            av_free(s->mime_type); s->mime_type = av_strdup(p);

        }

    }

    return 1;

}


g_malloc(size_t n_bytes)

{

    void *mem;

    __coverity_negative_sink__(n_bytes);

    mem = malloc(n_bytes == 0 ? 1 : n_bytes);

    if (!mem) __coverity_panic__();

    return mem;

}


void qemu_get_timedate(struct tm *tm, int offset)

{

    time_t ti;

    time(&ti);

    ti += offset;

    if (rtc_date_offset == -1) {

        if (rtc_utc)

            gmtime_r(&ti, tm);

        else

            localtime_r(&ti, tm);

    } else {

        ti -= rtc_date_offset;

        gmtime_r(&ti, tm);

    }

}


static uint64_t omap_lpg_read(void *opaque, target_phys_addr_t addr,

                              unsigned size)

{

    struct omap_lpg_s *s = (struct omap_lpg_s *) opaque;

    int offset = addr & OMAP_MPUI_REG_MASK;

    if (size != 1) {

        return omap_badwidth_read8(opaque, addr);

    }

    switch (offset) {

    case 0x00:	/* LCR */

        return s->control;

    case 0x04:	/* PMR */

        return s->power;

    }

    OMAP_BAD_REG(addr);

    return 0;

}


static int gif_encode_frame(AVCodecContext *avctx, unsigned char *outbuf, int buf_size, void *data)

{

    GIFContext *s = avctx->priv_data;

    AVFrame *pict = data;

    AVFrame *const p = (AVFrame *)&s->picture;

    uint8_t *outbuf_ptr = outbuf;

    *p = *pict;

    p->pict_type = FF_I_TYPE;

    p->key_frame = 1;

    gif_image_write_header(&outbuf_ptr, avctx->width, avctx->height, -1, (uint32_t *)pict->data[1]);

    gif_image_write_image(&outbuf_ptr, 0, 0, avctx->width, avctx->height, pict->data[0], pict->linesize[0], PIX_FMT_PAL8);

    return outbuf_ptr - outbuf;

}


static int local_mksock(FsContext *ctx2, const char *path)

{

    struct sockaddr_un addr;

    int s;

    addr.sun_family = AF_UNIX;

    snprintf(addr.sun_path, 108, "%s", rpath(ctx2, path));

    s = socket(PF_UNIX, SOCK_STREAM, 0);

    if (s == -1) {

        return -1;

    }

    if (bind(s, (struct sockaddr *)&addr, sizeof(addr))) {

        close(s);

        return -1;

    }

    close(s);

    return 0;

}


av_cold int avcodec_close(AVCodecContext *avctx)

{

    int ret = ff_lock_avcodec(avctx);

    if (ret < 0)

        return ret;

    if (avcodec_is_open(avctx)) {

        FramePool *pool = avctx->internal->pool;

        int i;

        if (HAVE_THREADS && avctx->internal->frame_thread_encoder && avctx->thread_count > 1) {

            ff_unlock_avcodec();

            ff_frame_thread_encoder_free(avctx);

            ff_lock_avcodec(avctx);

        }

        if (HAVE_THREADS && avctx->thread_opaque)

            ff_thread_free(avctx);

        if (avctx->codec && avctx->codec->close)

            avctx->codec->close(avctx);

        avctx->coded_frame = NULL;

        avctx->internal->byte_buffer_size = 0;

        av_freep(&avctx->internal->byte_buffer);

        if (!avctx->refcounted_frames)

            av_frame_unref(&avctx->internal->to_free);

        for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++)

            av_buffer_pool_uninit(&pool->pools[i]);

        av_freep(&avctx->internal->pool);

        av_freep(&avctx->internal);

    }

    if (avctx->priv_data && avctx->codec && avctx->codec->priv_class)

        av_opt_free(avctx->priv_data);

    av_opt_free(avctx);

    av_freep(&avctx->priv_data);

    if (av_codec_is_encoder(avctx->codec))

        av_freep(&avctx->extradata);

    avctx->codec = NULL;

    avctx->active_thread_type = 0;

    ff_unlock_avcodec();

    return 0;

}


static void virtio_device_free_virtqueues(VirtIODevice *vdev)

{

    int i;

    if (!vdev->vq) {

        return;

    }

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

        VRingMemoryRegionCaches *caches;

        if (vdev->vq[i].vring.num == 0) {

            break;

        }

        caches = atomic_read(&vdev->vq[i].vring.caches);

        atomic_set(&vdev->vq[i].vring.caches, NULL);

        virtio_free_region_cache(caches);

    }

    g_free(vdev->vq);

}


static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1)

{

    MpegEncContext *s = &s1->mpeg_enc_ctx;

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

    s->mpeg_f_code[0][0] = get_bits(&s->gb, 4);

    s->mpeg_f_code[0][1] = get_bits(&s->gb, 4);

    s->mpeg_f_code[1][0] = get_bits(&s->gb, 4);

    s->mpeg_f_code[1][1] = get_bits(&s->gb, 4);

    if (!s->pict_type && s1->mpeg_enc_ctx_allocated) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Missing picture start code, guessing missing values\n");

        if (s->mpeg_f_code[1][0] == 15 && s->mpeg_f_code[1][1] == 15) {

            if (s->mpeg_f_code[0][0] == 15 && s->mpeg_f_code[0][1] == 15)

                s->pict_type = AV_PICTURE_TYPE_I;

            else

                s->pict_type = AV_PICTURE_TYPE_P;

        } else

            s->pict_type = AV_PICTURE_TYPE_B;

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

        s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I;

    }

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

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

    s->top_field_first            = get_bits1(&s->gb);

    s->frame_pred_frame_dct       = get_bits1(&s->gb);

    s->concealment_motion_vectors = get_bits1(&s->gb);

    s->q_scale_type               = get_bits1(&s->gb);

    s->intra_vlc_format           = get_bits1(&s->gb);

    s->alternate_scan             = get_bits1(&s->gb);

    s->repeat_first_field         = get_bits1(&s->gb);

    s->chroma_420_type            = get_bits1(&s->gb);

    s->progressive_frame          = get_bits1(&s->gb);

    if (s->progressive_sequence && !s->progressive_frame) {

        s->progressive_frame = 1;

        av_log(s->avctx, AV_LOG_ERROR,

               "interlaced frame in progressive sequence, ignoring\n");

    }

    if (s->picture_structure == 0 ||

        (s->progressive_frame && s->picture_structure != PICT_FRAME)) {

        av_log(s->avctx, AV_LOG_ERROR,

               "picture_structure %d invalid, ignoring\n",

               s->picture_structure);

        s->picture_structure = PICT_FRAME;

    }

    if (s->progressive_sequence && !s->frame_pred_frame_dct)

        av_log(s->avctx, AV_LOG_WARNING, "invalid frame_pred_frame_dct\n");

    if (s->picture_structure == PICT_FRAME) {

        s->first_field = 0;

        s->v_edge_pos  = 16 * s->mb_height;

    } else {

        s->first_field ^= 1;

        s->v_edge_pos   = 8 * s->mb_height;

        memset(s->mbskip_table, 0, s->mb_stride * s->mb_height);

    }

    if (s->alternate_scan) {

        ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_alternate_vertical_scan);

        ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_alternate_vertical_scan);

    } else {

        ff_init_scantable(s->idsp.idct_permutation, &s->inter_scantable, ff_zigzag_direct);

        ff_init_scantable(s->idsp.idct_permutation, &s->intra_scantable, ff_zigzag_direct);

    }

    /* composite display not parsed */

    ff_dlog(s->avctx, "intra_dc_precision=%d\n", s->intra_dc_precision);

    ff_dlog(s->avctx, "picture_structure=%d\n", s->picture_structure);

    ff_dlog(s->avctx, "top field first=%d\n", s->top_field_first);

    ff_dlog(s->avctx, "repeat first field=%d\n", s->repeat_first_field);

    ff_dlog(s->avctx, "conceal=%d\n", s->concealment_motion_vectors);

    ff_dlog(s->avctx, "intra_vlc_format=%d\n", s->intra_vlc_format);

    ff_dlog(s->avctx, "alternate_scan=%d\n", s->alternate_scan);

    ff_dlog(s->avctx, "frame_pred_frame_dct=%d\n", s->frame_pred_frame_dct);

    ff_dlog(s->avctx, "progressive_frame=%d\n", s->progressive_frame);

}


static av_always_inline void mc_dir_part(H264Context *h, Picture *pic,

                                         int n, int square, int height,

                                         int delta, int list,

                                         uint8_t *dest_y, uint8_t *dest_cb,

                                         uint8_t *dest_cr,

                                         int src_x_offset, int src_y_offset,

                                         qpel_mc_func *qpix_op,

                                         h264_chroma_mc_func chroma_op,

                                         int pixel_shift, int chroma_idc)

{

    const int mx      = h->mv_cache[list][scan8[n]][0] + src_x_offset * 8;

    int my            = h->mv_cache[list][scan8[n]][1] + src_y_offset * 8;

    const int luma_xy = (mx & 3) + ((my & 3) << 2);

    int offset        = ((mx >> 2) << pixel_shift) + (my >> 2) * h->mb_linesize;

    uint8_t *src_y    = pic->f.data[0] + offset;

    uint8_t *src_cb, *src_cr;

    int extra_width  = 0;

    int extra_height = 0;

    int emu = 0;

    const int full_mx    = mx >> 2;

    const int full_my    = my >> 2;

    const int pic_width  = 16 * h->mb_width;

    const int pic_height = 16 * h->mb_height >> MB_FIELD(h);

    int ysh;

    if (mx & 7)

        extra_width -= 3;

    if (my & 7)

        extra_height -= 3;

    if (full_mx                <          0 - extra_width  ||

        full_my                <          0 - extra_height ||

        full_mx + 16 /*FIXME*/ > pic_width  + extra_width  ||

        full_my + 16 /*FIXME*/ > pic_height + extra_height) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer,

                                 src_y - (2 << pixel_shift) - 2 * h->mb_linesize,

                                 h->mb_linesize,

                                 16 + 5, 16 + 5 /*FIXME*/, full_mx - 2,

                                 full_my - 2, pic_width, pic_height);

        src_y = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        emu   = 1;

    }

    qpix_op[luma_xy](dest_y, src_y, h->mb_linesize); // FIXME try variable height perhaps?

    if (!square)

        qpix_op[luma_xy](dest_y + delta, src_y + delta, h->mb_linesize);

    if (CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY)

        return;

    if (chroma_idc == 3 /* yuv444 */) {

        src_cb = pic->f.data[1] + offset;

        if (emu) {

            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,

                                     src_cb - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 /*FIXME*/,

                                     full_mx - 2, full_my - 2,

                                     pic_width, pic_height);

            src_cb = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[luma_xy](dest_cb, src_cb, h->mb_linesize); // FIXME try variable height perhaps?

        if (!square)

            qpix_op[luma_xy](dest_cb + delta, src_cb + delta, h->mb_linesize);

        src_cr = pic->f.data[2] + offset;

        if (emu) {

            h->vdsp.emulated_edge_mc(h->edge_emu_buffer,

                                     src_cr - (2 << pixel_shift) - 2 * h->mb_linesize,

                                     h->mb_linesize,

                                     16 + 5, 16 + 5 /*FIXME*/,

                                     full_mx - 2, full_my - 2,

                                     pic_width, pic_height);

            src_cr = h->edge_emu_buffer + (2 << pixel_shift) + 2 * h->mb_linesize;

        }

        qpix_op[luma_xy](dest_cr, src_cr, h->mb_linesize); // FIXME try variable height perhaps?

        if (!square)

            qpix_op[luma_xy](dest_cr + delta, src_cr + delta, h->mb_linesize);

        return;

    }

    ysh = 3 - (chroma_idc == 2 /* yuv422 */);

    if (chroma_idc == 1 /* yuv420 */ && MB_FIELD(h)) {

        // chroma offset when predicting from a field of opposite parity

        my  += 2 * ((h->mb_y & 1) - (pic->reference - 1));

        emu |= (my >> 3) < 0 || (my >> 3) + 8 >= (pic_height >> 1);

    }

    src_cb = pic->f.data[1] + ((mx >> 3) << pixel_shift) +

             (my >> ysh) * h->mb_uvlinesize;

    src_cr = pic->f.data[2] + ((mx >> 3) << pixel_shift) +

             (my >> ysh) * h->mb_uvlinesize;

    if (emu) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cb, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),

                                 pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));

        src_cb = h->edge_emu_buffer;

    }

    chroma_op(dest_cb, src_cb, h->mb_uvlinesize,

              height >> (chroma_idc == 1 /* yuv420 */),

              mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);

    if (emu) {

        h->vdsp.emulated_edge_mc(h->edge_emu_buffer, src_cr, h->mb_uvlinesize,

                                 9, 8 * chroma_idc + 1, (mx >> 3), (my >> ysh),

                                 pic_width >> 1, pic_height >> (chroma_idc == 1 /* yuv420 */));

        src_cr = h->edge_emu_buffer;

    }

    chroma_op(dest_cr, src_cr, h->mb_uvlinesize, height >> (chroma_idc == 1 /* yuv420 */),

              mx & 7, (my << (chroma_idc == 2 /* yuv422 */)) & 7);

}


static int av_cold libopus_encode_init(AVCodecContext *avctx)

{

    LibopusEncContext *opus = avctx->priv_data;

    const uint8_t *channel_mapping;

    OpusMSEncoder *enc;

    int ret = OPUS_OK;

    int coupled_stream_count, header_size, frame_size;

    coupled_stream_count = opus_coupled_streams[avctx->channels - 1];

    opus->stream_count   = avctx->channels - coupled_stream_count;

    channel_mapping      = libav_libopus_channel_map[avctx->channels - 1];

    /* FIXME: Opus can handle up to 255 channels. However, the mapping for

     * anything greater than 8 is undefined. */

    if (avctx->channels > 8)

        av_log(avctx, AV_LOG_WARNING,

               "Channel layout undefined for %d channels.\n", avctx->channels);

    if (!avctx->bit_rate) {

        /* Sane default copied from opusenc */

        avctx->bit_rate = 64000 * opus->stream_count +

                          32000 * coupled_stream_count;

        av_log(avctx, AV_LOG_WARNING,

               "No bit rate set. Defaulting to %d bps.\n", avctx->bit_rate);

    }

    if (avctx->bit_rate < 500 || avctx->bit_rate > 256000 * avctx->channels) {

        av_log(avctx, AV_LOG_ERROR, "The bit rate %d bps is unsupported. "

               "Please choose a value between 500 and %d.\n", avctx->bit_rate,

               256000 * avctx->channels);

        return AVERROR(EINVAL);

    }

    frame_size = opus->opts.frame_duration * 48000 / 1000;

    switch (frame_size) {

    case 120:

    case 240:

        if (opus->opts.application != OPUS_APPLICATION_RESTRICTED_LOWDELAY)

            av_log(avctx, AV_LOG_WARNING,

                   "LPC mode cannot be used with a frame duration of less "

                   "than 10ms. Enabling restricted low-delay mode.\n"

                   "Use a longer frame duration if this is not what you want.\n");

        /* Frame sizes less than 10 ms can only use MDCT mode, so switching to

         * RESTRICTED_LOWDELAY avoids an unnecessary extra 2.5ms lookahead. */

        opus->opts.application = OPUS_APPLICATION_RESTRICTED_LOWDELAY;

    case 480:

    case 960:

    case 1920:

    case 2880:

        opus->opts.packet_size =

        avctx->frame_size      = frame_size * avctx->sample_rate / 48000;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Invalid frame duration: %g.\n"

               "Frame duration must be exactly one of: 2.5, 5, 10, 20, 40 or 60.\n",

               opus->opts.frame_duration);

        return AVERROR(EINVAL);

    }

    if (avctx->compression_level < 0 || avctx->compression_level > 10) {

        av_log(avctx, AV_LOG_WARNING,

               "Compression level must be in the range 0 to 10. "

               "Defaulting to 10.\n");

        opus->opts.complexity = 10;

    } else {

        opus->opts.complexity = avctx->compression_level;

    }

    if (avctx->cutoff) {

        switch (avctx->cutoff) {

        case  4000:

            opus->opts.max_bandwidth = OPUS_BANDWIDTH_NARROWBAND;

            break;

        case  6000:

            opus->opts.max_bandwidth = OPUS_BANDWIDTH_MEDIUMBAND;

            break;

        case  8000:

            opus->opts.max_bandwidth = OPUS_BANDWIDTH_WIDEBAND;

            break;

        case 12000:

            opus->opts.max_bandwidth = OPUS_BANDWIDTH_SUPERWIDEBAND;

            break;

        case 20000:

            opus->opts.max_bandwidth = OPUS_BANDWIDTH_FULLBAND;

            break;

        default:

            av_log(avctx, AV_LOG_WARNING,

                   "Invalid frequency cutoff: %d. Using default maximum bandwidth.\n"

                   "Cutoff frequency must be exactly one of: 4000, 6000, 8000, 12000 or 20000.\n",

                   avctx->cutoff);

            avctx->cutoff = 0;

        }

    }

    enc = opus_multistream_encoder_create(avctx->sample_rate, avctx->channels,

                                          opus->stream_count,

                                          coupled_stream_count,

                                          channel_mapping,

                                          opus->opts.application, &ret);

    if (ret != OPUS_OK) {

        av_log(avctx, AV_LOG_ERROR,

               "Failed to create encoder: %s\n", opus_strerror(ret));

        return ff_opus_error_to_averror(ret);

    }

    ret = libopus_configure_encoder(avctx, enc, &opus->opts);

    if (ret != OPUS_OK) {

        ret = ff_opus_error_to_averror(ret);

        goto fail;

    }

    header_size = 19 + (avctx->channels > 2 ? 2 + avctx->channels : 0);

    avctx->extradata = av_malloc(header_size + FF_INPUT_BUFFER_PADDING_SIZE);

    if (!avctx->extradata) {

        av_log(avctx, AV_LOG_ERROR, "Failed to allocate extradata.\n");

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    avctx->extradata_size = header_size;

    opus->samples = av_mallocz(frame_size * avctx->channels *

                               av_get_bytes_per_sample(avctx->sample_fmt));

    if (!opus->samples) {

        av_log(avctx, AV_LOG_ERROR, "Failed to allocate samples buffer.\n");

        ret = AVERROR(ENOMEM);

        goto fail;

    }

    ret = opus_multistream_encoder_ctl(enc, OPUS_GET_LOOKAHEAD(&avctx->initial_padding));

    if (ret != OPUS_OK)

        av_log(avctx, AV_LOG_WARNING,

               "Unable to get number of lookahead samples: %s\n",

               opus_strerror(ret));

    libopus_write_header(avctx, opus->stream_count, coupled_stream_count,

                         opus_vorbis_channel_map[avctx->channels - 1]);

    ff_af_queue_init(avctx, &opus->afq);

    opus->enc = enc;

    return 0;

fail:

    opus_multistream_encoder_destroy(enc);

    av_freep(&avctx->extradata);

    return ret;

}


static int common_end(HYuvContext *s)

{

    int i;

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

        av_freep(&s->temp[i]);

    }

    return 0;

}


static int coroutine_fn raw_co_write_zeroes(

    BlockDriverState *bs, int64_t sector_num,

    int nb_sectors, BdrvRequestFlags flags)

{

    BDRVRawState *s = bs->opaque;

    if (!(flags & BDRV_REQ_MAY_UNMAP)) {

        return -ENOTSUP;

    }

    if (!s->discard_zeroes) {

        return -ENOTSUP;

    }

    return paio_submit_co(bs, s->fd, sector_num, NULL, nb_sectors,

                          QEMU_AIO_DISCARD);

}


static always_inline int dv_rl2vlc(int run, int l, uint32_t* vlc)

{

    *vlc = dv_vlc_map[run][((uint16_t)l)&0x1ff].vlc;

    return dv_vlc_map[run][((uint16_t)l)&0x1ff].size;

}


static int dma_buf_prepare(BMDMAState *bm, int is_write)

{

    IDEState *s = bmdma_active_if(bm);

    struct {

        uint32_t addr;

        uint32_t size;

    } prd;

    int l, len;

    qemu_sglist_init(&s->sg, s->nsector / (TARGET_PAGE_SIZE/512) + 1);

    s->io_buffer_size = 0;

    for(;;) {

        if (bm->cur_prd_len == 0) {

            /* end of table (with a fail safe of one page) */

            if (bm->cur_prd_last ||

                (bm->cur_addr - bm->addr) >= 4096)

                return s->io_buffer_size != 0;

            cpu_physical_memory_read(bm->cur_addr, (uint8_t *)&prd, 8);

            bm->cur_addr += 8;

            prd.addr = le32_to_cpu(prd.addr);

            prd.size = le32_to_cpu(prd.size);

            len = prd.size & 0xfffe;

            if (len == 0)

                len = 0x10000;

            bm->cur_prd_len = len;

            bm->cur_prd_addr = prd.addr;

            bm->cur_prd_last = (prd.size & 0x80000000);

        }

        l = bm->cur_prd_len;

        if (l > 0) {

            qemu_sglist_add(&s->sg, bm->cur_prd_addr, l);

            bm->cur_prd_addr += l;

            bm->cur_prd_len -= l;

            s->io_buffer_size += l;

        }

    }

    return 1;

}


static int usb_host_claim_interfaces(USBHostDevice *s, int configuration)

{

    USBDevice *udev = USB_DEVICE(s);

    struct libusb_config_descriptor *conf;

    int rc, i;

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

        udev->altsetting[i] = 0;

    }

    udev->ninterfaces   = 0;

    udev->configuration = 0;

    if (configuration == 0) {

        /* address state - ignore */

        return USB_RET_SUCCESS;

    }

    usb_host_detach_kernel(s);

    rc = libusb_get_active_config_descriptor(s->dev, &conf);

    if (rc != 0) {

        return USB_RET_STALL;

    }

    for (i = 0; i < conf->bNumInterfaces; i++) {

        trace_usb_host_claim_interface(s->bus_num, s->addr, configuration, i);

        rc = libusb_claim_interface(s->dh, i);

        usb_host_libusb_error("libusb_claim_interface", rc);

        if (rc != 0) {

            return USB_RET_STALL;

        }

        s->ifs[i].claimed = true;

    }

    udev->ninterfaces   = conf->bNumInterfaces;

    udev->configuration = configuration;

    libusb_free_config_descriptor(conf);

    return USB_RET_SUCCESS;

}


static void term_completion(void)

{

    int len, i, j, max_width, nb_cols;

    char *cmdline;

    nb_completions = 0;

    cmdline = qemu_malloc(term_cmd_buf_index + 1);

    if (!cmdline)

        return;

    memcpy(cmdline, term_cmd_buf, term_cmd_buf_index);

    cmdline[term_cmd_buf_index] = '\0';

    find_completion(cmdline);

    qemu_free(cmdline);

    /* no completion found */

    if (nb_completions <= 0)

        return;

    if (nb_completions == 1) {

        len = strlen(completions[0]);

        for(i = completion_index; i < len; i++) {

            term_insert_char(completions[0][i]);

        }

        /* extra space for next argument. XXX: make it more generic */

        if (len > 0 && completions[0][len - 1] != '/')

            term_insert_char(' ');

    } else {

        term_printf("\n");

        max_width = 0;

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

            len = strlen(completions[i]);

            if (len > max_width)

                max_width = len;

        }

        max_width += 2;

        if (max_width < 10)

            max_width = 10;

        else if (max_width > 80)

            max_width = 80;

        nb_cols = 80 / max_width;

        j = 0;

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

            term_printf("%-*s", max_width, completions[i]);

            if (++j == nb_cols || i == (nb_completions - 1)) {

                term_printf("\n");

                j = 0;

            }

        }

        term_show_prompt2();

    }

}


static int parse_vdiname(BDRVSheepdogState *s, const char *filename,

                         char *vdi, uint32_t *snapid, char *tag)

{

    char *p, *q, *uri;

    const char *host_spec, *vdi_spec;

    int nr_sep, ret;

    strstart(filename, "sheepdog:", &filename);

    p = q = g_strdup(filename);

    /* count the number of separators */

    nr_sep = 0;

    while (*p) {

        if (*p == ':') {

            nr_sep++;

        }

        p++;

    }

    p = q;

    /* use the first two tokens as host_spec. */

    if (nr_sep >= 2) {

        host_spec = p;

        p = strchr(p, ':');

        p++;

        p = strchr(p, ':');

        *p++ = '\0';

    } else {

        host_spec = "";

    }

    vdi_spec = p;

    p = strchr(vdi_spec, ':');

    if (p) {

        *p++ = '#';

    }

    uri = g_strdup_printf("sheepdog://%s/%s", host_spec, vdi_spec);

    ret = sd_parse_uri(s, uri, vdi, snapid, tag);

    g_free(q);

    g_free(uri);

    return ret;

}


static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){

    int x, y, x2, y2;

    const int width= f->avctx->width;

    const int height= f->avctx->height;

    uint16_t *dst= (uint16_t*)f->current_picture.data[0];

    const int stride= f->current_picture.linesize[0]>>1;

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

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

            unsigned int color[4], bits;

            memset(color, 0, sizeof(color));

//warning following is purely guessed ...

            color[0]= bytestream_get_le16(&buf);

            color[1]= bytestream_get_le16(&buf);

            if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n");

            if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n");

            color[2]= mix(color[0], color[1]);

            color[3]= mix(color[1], color[0]);

            bits= bytestream_get_le32(&buf);

            for(y2=0; y2<16; y2++){

                for(x2=0; x2<16; x2++){

                    int index= 2*(x2>>2) + 8*(y2>>2);

                    dst[y2*stride+x2]= color[(bits>>index)&3];

                }

            }

            dst+=16;

        }

        dst += 16 * stride - x;

    }

    return 0;

}


static int apc_read_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    AVStream *st;

    avio_rl32(pb); /* CRYO */

    avio_rl32(pb); /* _APC */

    avio_rl32(pb); /* 1.20 */

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;

    st->codecpar->codec_id = AV_CODEC_ID_ADPCM_IMA_APC;

    avio_rl32(pb); /* number of samples */

    st->codecpar->sample_rate = avio_rl32(pb);

    /* initial predictor values for adpcm decoder */

    if (ff_get_extradata(s, st->codecpar, pb, 2 * 4) < 0)

        return AVERROR(ENOMEM);

    if (avio_rl32(pb)) {

        st->codecpar->channels       = 2;

        st->codecpar->channel_layout = AV_CH_LAYOUT_STEREO;

    } else {

        st->codecpar->channels       = 1;

        st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;

    }

    st->codecpar->bits_per_coded_sample = 4;

    st->codecpar->bit_rate = st->codecpar->bits_per_coded_sample * st->codecpar->channels

                          * st->codecpar->sample_rate;

    st->codecpar->block_align = 1;

    return 0;

}


static inline uint16_t vring_avail_idx(VirtQueue *vq)

{

    hwaddr pa;

    pa = vq->vring.avail + offsetof(VRingAvail, idx);

    return virtio_lduw_phys(vq->vdev, pa);

}


void cpu_x86_update_cr0(CPUX86State *env)

{

    int pg_state, pe_state;

#if defined(DEBUG_MMU)

    printf("CR0 update: CR0=0x%08x\n", env->cr[0]);

#endif

    pg_state = env->cr[0] & CR0_PG_MASK;

    if (pg_state != last_pg_state) {

        tlb_flush(env);

        last_pg_state = pg_state;

    }

    /* update PE flag in hidden flags */

    pe_state = (env->cr[0] & CR0_PE_MASK);

    env->hflags = (env->hflags & ~HF_PE_MASK) | (pe_state << HF_PE_SHIFT);

    /* ensure that ADDSEG is always set in real mode */

    env->hflags |= ((pe_state ^ 1) << HF_ADDSEG_SHIFT);

}


static void branch(DBDMA_channel *ch)

{

    dbdma_cmd *current = &ch->current;

    ch->regs[DBDMA_CMDPTR_LO] = current->cmd_dep;

    ch->regs[DBDMA_STATUS] |= cpu_to_be32(BT);

    dbdma_cmdptr_load(ch);

}


void *ff_png_zalloc(void *opaque, unsigned int items, unsigned int size)

{

    if(items >= UINT_MAX / size)

        return NULL;

    return av_malloc(items * size);

}


static int scsi_get_configuration(SCSIDiskState *s, uint8_t *outbuf)

{

    int current;

    if (s->qdev.type != TYPE_ROM) {

        return -1;

    }

    current = media_is_dvd(s) ? MMC_PROFILE_DVD_ROM : MMC_PROFILE_CD_ROM;

    memset(outbuf, 0, 40);

    stl_be_p(&outbuf[0], 36); /* Bytes after the data length field */

    stw_be_p(&outbuf[6], current);

    /* outbuf[8] - outbuf[19]: Feature 0 - Profile list */

    outbuf[10] = 0x03; /* persistent, current */

    outbuf[11] = 8; /* two profiles */

    stw_be_p(&outbuf[12], MMC_PROFILE_DVD_ROM);

    outbuf[14] = (current == MMC_PROFILE_DVD_ROM);

    stw_be_p(&outbuf[16], MMC_PROFILE_CD_ROM);

    outbuf[18] = (current == MMC_PROFILE_CD_ROM);

    /* outbuf[20] - outbuf[31]: Feature 1 - Core feature */

    stw_be_p(&outbuf[20], 1);

    outbuf[22] = 0x08 | 0x03; /* version 2, persistent, current */

    outbuf[23] = 8;

    stl_be_p(&outbuf[24], 1); /* SCSI */

    outbuf[28] = 1; /* DBE = 1, mandatory */

    /* outbuf[32] - outbuf[39]: Feature 3 - Removable media feature */

    stw_be_p(&outbuf[32], 3);

    outbuf[34] = 0x08 | 0x03; /* version 2, persistent, current */

    outbuf[35] = 4;

    outbuf[36] = 0x39; /* tray, load=1, eject=1, unlocked at powerup, lock=1 */

    /* TODO: Random readable, CD read, DVD read, drive serial number,

       power management */

    return 40;

}


static void rx_stop_cont_test(const QVirtioBus *bus, QVirtioDevice *dev,

                              QGuestAllocator *alloc, QVirtQueue *vq,

                              int socket)

{

    uint64_t req_addr;

    uint32_t free_head;

    char test[] = "TEST";

    char buffer[64];

    int len = htonl(sizeof(test));

    struct iovec iov[] = {

        {

            .iov_base = &len,

            .iov_len = sizeof(len),

        }, {

            .iov_base = test,

            .iov_len = sizeof(test),

        },

    };

    int ret;

    req_addr = guest_alloc(alloc, 64);

    free_head = qvirtqueue_add(vq, req_addr, 64, true, false);

    qvirtqueue_kick(bus, dev, vq, free_head);

    qmp("{ 'execute' : 'stop'}");

    ret = iov_send(socket, iov, 2, 0, sizeof(len) + sizeof(test));

    g_assert_cmpint(ret, ==, sizeof(test) + sizeof(len));

    /* We could check the status, but this command is more importantly to

     * ensure the packet data gets queued in QEMU, before we do 'cont'.

     */

    qmp("{ 'execute' : 'query-status'}");

    qmp("{ 'execute' : 'cont'}");

    qvirtio_wait_queue_isr(bus, dev, vq, QVIRTIO_NET_TIMEOUT_US);

    memread(req_addr + VNET_HDR_SIZE, buffer, sizeof(test));

    g_assert_cmpstr(buffer, ==, "TEST");

    guest_free(alloc, req_addr);

}


static inline void fill_caches(H264Context *h, int mb_type){

    MpegEncContext * const s = &h->s;

    const int mb_xy= s->mb_x + s->mb_y*s->mb_stride;

    int topleft_xy, top_xy, topright_xy, left_xy[2];

    int topleft_type, top_type, topright_type, left_type[2];

    int left_block[4];

    int i;

    //wow what a mess, why didnt they simplify the interlacing&intra stuff, i cant imagine that these complex rules are worth it

    if(h->sps.mb_aff){

    //FIXME

        topleft_xy = 0; /* avoid warning */

        top_xy = 0; /* avoid warning */

        topright_xy = 0; /* avoid warning */

    }else{

        topleft_xy = mb_xy-1 - s->mb_stride;

        top_xy     = mb_xy   - s->mb_stride;

        topright_xy= mb_xy+1 - s->mb_stride;

        left_xy[0]   = mb_xy-1;

        left_xy[1]   = mb_xy-1;

        left_block[0]= 0;

        left_block[1]= 1;

        left_block[2]= 2;

        left_block[3]= 3;

    }

    topleft_type = h->slice_table[topleft_xy ] == h->slice_num ? s->current_picture.mb_type[topleft_xy] : 0;

    top_type     = h->slice_table[top_xy     ] == h->slice_num ? s->current_picture.mb_type[top_xy]     : 0;

    topright_type= h->slice_table[topright_xy] == h->slice_num ? s->current_picture.mb_type[topright_xy]: 0;

    left_type[0] = h->slice_table[left_xy[0] ] == h->slice_num ? s->current_picture.mb_type[left_xy[0]] : 0;

    left_type[1] = h->slice_table[left_xy[1] ] == h->slice_num ? s->current_picture.mb_type[left_xy[1]] : 0;

    if(IS_INTRA(mb_type)){

        h->topleft_samples_available=

        h->top_samples_available=

        h->left_samples_available= 0xFFFF;

        h->topright_samples_available= 0xEEEA;

        if(!IS_INTRA(top_type) && (top_type==0 || h->pps.constrained_intra_pred)){

            h->topleft_samples_available= 0xB3FF;

            h->top_samples_available= 0x33FF;

            h->topright_samples_available= 0x26EA;

        }

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

            if(!IS_INTRA(left_type[i]) && (left_type[i]==0 || h->pps.constrained_intra_pred)){

                h->topleft_samples_available&= 0xDF5F;

                h->left_samples_available&= 0x5F5F;

            }

        }

        if(!IS_INTRA(topleft_type) && (topleft_type==0 || h->pps.constrained_intra_pred))

            h->topleft_samples_available&= 0x7FFF;

        if(!IS_INTRA(topright_type) && (topright_type==0 || h->pps.constrained_intra_pred))

            h->topright_samples_available&= 0xFBFF;

        if(IS_INTRA4x4(mb_type)){

            if(IS_INTRA4x4(top_type)){

                h->intra4x4_pred_mode_cache[4+8*0]= h->intra4x4_pred_mode[top_xy][4];

                h->intra4x4_pred_mode_cache[5+8*0]= h->intra4x4_pred_mode[top_xy][5];

                h->intra4x4_pred_mode_cache[6+8*0]= h->intra4x4_pred_mode[top_xy][6];

                h->intra4x4_pred_mode_cache[7+8*0]= h->intra4x4_pred_mode[top_xy][3];

            }else{

                int pred;

                if(IS_INTRA16x16(top_type) || (IS_INTER(top_type) && !h->pps.constrained_intra_pred))

                    pred= 2;

                else{

                    pred= -1;

                }

                h->intra4x4_pred_mode_cache[4+8*0]=

                h->intra4x4_pred_mode_cache[5+8*0]=

                h->intra4x4_pred_mode_cache[6+8*0]=

                h->intra4x4_pred_mode_cache[7+8*0]= pred;

            }

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

                if(IS_INTRA4x4(left_type[i])){

                    h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[0+2*i]];

                    h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= h->intra4x4_pred_mode[left_xy[i]][left_block[1+2*i]];

                }else{

                    int pred;

                    if(IS_INTRA16x16(left_type[i]) || (IS_INTER(left_type[i]) && !h->pps.constrained_intra_pred))

                        pred= 2;

                    else{

                        pred= -1;

                    }

                    h->intra4x4_pred_mode_cache[3+8*1 + 2*8*i]=

                    h->intra4x4_pred_mode_cache[3+8*2 + 2*8*i]= pred;

                }

            }

        }

    }

/*

0 . T T. T T T T

1 L . .L . . . .

2 L . .L . . . .

3 . T TL . . . .

4 L . .L . . . .

5 L . .. . . . .

*/

//FIXME constraint_intra_pred & partitioning & nnz (lets hope this is just a typo in the spec)

    if(top_type){

        h->non_zero_count_cache[4+8*0]= h->non_zero_count[top_xy][10];

        h->non_zero_count_cache[5+8*0]= h->non_zero_count[top_xy][11];

        h->non_zero_count_cache[6+8*0]= h->non_zero_count[top_xy][14];

        h->non_zero_count_cache[7+8*0]= h->non_zero_count[top_xy][15];

        h->non_zero_count_cache[1+8*0]= h->non_zero_count[top_xy][18];

        h->non_zero_count_cache[2+8*0]= h->non_zero_count[top_xy][19];

        h->non_zero_count_cache[1+8*3]= h->non_zero_count[top_xy][22];

        h->non_zero_count_cache[2+8*3]= h->non_zero_count[top_xy][23];

    }else{

        h->non_zero_count_cache[4+8*0]=

        h->non_zero_count_cache[5+8*0]=

        h->non_zero_count_cache[6+8*0]=

        h->non_zero_count_cache[7+8*0]=

        h->non_zero_count_cache[1+8*0]=

        h->non_zero_count_cache[2+8*0]=

        h->non_zero_count_cache[1+8*3]=

        h->non_zero_count_cache[2+8*3]= 64;

    }

    if(left_type[0]){

        h->non_zero_count_cache[3+8*1]= h->non_zero_count[left_xy[0]][5];

        h->non_zero_count_cache[3+8*2]= h->non_zero_count[left_xy[0]][7];

        h->non_zero_count_cache[0+8*1]= h->non_zero_count[left_xy[0]][17]; //FIXME left_block

        h->non_zero_count_cache[0+8*4]= h->non_zero_count[left_xy[0]][21];

    }else{

        h->non_zero_count_cache[3+8*1]=

        h->non_zero_count_cache[3+8*2]=

        h->non_zero_count_cache[0+8*1]=

        h->non_zero_count_cache[0+8*4]= 64;

    }

    if(left_type[1]){

        h->non_zero_count_cache[3+8*3]= h->non_zero_count[left_xy[1]][13];

        h->non_zero_count_cache[3+8*4]= h->non_zero_count[left_xy[1]][15];

        h->non_zero_count_cache[0+8*2]= h->non_zero_count[left_xy[1]][19];

        h->non_zero_count_cache[0+8*5]= h->non_zero_count[left_xy[1]][23];

    }else{

        h->non_zero_count_cache[3+8*3]=

        h->non_zero_count_cache[3+8*4]=

        h->non_zero_count_cache[0+8*2]=

        h->non_zero_count_cache[0+8*5]= 64;

    }

#if 1

    if(IS_INTER(mb_type)){

        int list;

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

            if((!IS_8X8(mb_type)) && !USES_LIST(mb_type, list)){

                /*if(!h->mv_cache_clean[list]){

                    memset(h->mv_cache [list],  0, 8*5*2*sizeof(int16_t)); //FIXME clean only input? clean at all?

                    memset(h->ref_cache[list], PART_NOT_AVAILABLE, 8*5*sizeof(int8_t));

                    h->mv_cache_clean[list]= 1;

                }*/

                continue; //FIXME direct mode ...

            }

            h->mv_cache_clean[list]= 0;

            if(IS_INTER(topleft_type)){

                const int b_xy = h->mb2b_xy[topleft_xy] + 3 + 3*h->b_stride;

                const int b8_xy= h->mb2b8_xy[topleft_xy] + 1 + h->b8_stride;

                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy];

                h->ref_cache[list][scan8[0] - 1 - 1*8]= s->current_picture.ref_index[list][b8_xy];

            }else{

                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 - 1*8]= 0;

                h->ref_cache[list][scan8[0] - 1 - 1*8]= topleft_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;

            }

            if(IS_INTER(top_type)){

                const int b_xy= h->mb2b_xy[top_xy] + 3*h->b_stride;

                const int b8_xy= h->mb2b8_xy[top_xy] + h->b8_stride;

                *(uint32_t*)h->mv_cache[list][scan8[0] + 0 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 0];

                *(uint32_t*)h->mv_cache[list][scan8[0] + 1 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 1];

                *(uint32_t*)h->mv_cache[list][scan8[0] + 2 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 2];

                *(uint32_t*)h->mv_cache[list][scan8[0] + 3 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + 3];

                h->ref_cache[list][scan8[0] + 0 - 1*8]=

                h->ref_cache[list][scan8[0] + 1 - 1*8]= s->current_picture.ref_index[list][b8_xy + 0];

                h->ref_cache[list][scan8[0] + 2 - 1*8]=

                h->ref_cache[list][scan8[0] + 3 - 1*8]= s->current_picture.ref_index[list][b8_xy + 1];

            }else{

                *(uint32_t*)h->mv_cache [list][scan8[0] + 0 - 1*8]=

                *(uint32_t*)h->mv_cache [list][scan8[0] + 1 - 1*8]=

                *(uint32_t*)h->mv_cache [list][scan8[0] + 2 - 1*8]=

                *(uint32_t*)h->mv_cache [list][scan8[0] + 3 - 1*8]= 0;

                *(uint32_t*)&h->ref_cache[list][scan8[0] + 0 - 1*8]= ((top_type ? LIST_NOT_USED : PART_NOT_AVAILABLE)&0xFF)*0x01010101;

            }

            if(IS_INTER(topright_type)){

                const int b_xy= h->mb2b_xy[topright_xy] + 3*h->b_stride;

                const int b8_xy= h->mb2b8_xy[topright_xy] + h->b8_stride;

                *(uint32_t*)h->mv_cache[list][scan8[0] + 4 - 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy];

                h->ref_cache[list][scan8[0] + 4 - 1*8]= s->current_picture.ref_index[list][b8_xy];

            }else{

                *(uint32_t*)h->mv_cache [list][scan8[0] + 4 - 1*8]= 0;

                h->ref_cache[list][scan8[0] + 4 - 1*8]= topright_type ? LIST_NOT_USED : PART_NOT_AVAILABLE;

            }

            //FIXME unify cleanup or sth

            if(IS_INTER(left_type[0])){

                const int b_xy= h->mb2b_xy[left_xy[0]] + 3;

                const int b8_xy= h->mb2b8_xy[left_xy[0]] + 1;

                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 0*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[0]];

                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 1*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[1]];

                h->ref_cache[list][scan8[0] - 1 + 0*8]=

                h->ref_cache[list][scan8[0] - 1 + 1*8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[0]>>1)];

            }else{

                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 0*8]=

                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 1*8]= 0;

                h->ref_cache[list][scan8[0] - 1 + 0*8]=

                h->ref_cache[list][scan8[0] - 1 + 1*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE;

            }

            if(IS_INTER(left_type[1])){

                const int b_xy= h->mb2b_xy[left_xy[1]] + 3;

                const int b8_xy= h->mb2b8_xy[left_xy[1]] + 1;

                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 2*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[2]];

                *(uint32_t*)h->mv_cache[list][scan8[0] - 1 + 3*8]= *(uint32_t*)s->current_picture.motion_val[list][b_xy + h->b_stride*left_block[3]];

                h->ref_cache[list][scan8[0] - 1 + 2*8]=

                h->ref_cache[list][scan8[0] - 1 + 3*8]= s->current_picture.ref_index[list][b8_xy + h->b8_stride*(left_block[2]>>1)];

            }else{

                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 2*8]=

                *(uint32_t*)h->mv_cache [list][scan8[0] - 1 + 3*8]= 0;

                h->ref_cache[list][scan8[0] - 1 + 2*8]=

                h->ref_cache[list][scan8[0] - 1 + 3*8]= left_type[0] ? LIST_NOT_USED : PART_NOT_AVAILABLE;

            }

            h->ref_cache[list][scan8[5 ]+1] =

            h->ref_cache[list][scan8[7 ]+1] =

            h->ref_cache[list][scan8[13]+1] =  //FIXME remove past 3 (init somewher else)

            h->ref_cache[list][scan8[4 ]] =

            h->ref_cache[list][scan8[12]] = PART_NOT_AVAILABLE;

            *(uint32_t*)h->mv_cache [list][scan8[5 ]+1]=

            *(uint32_t*)h->mv_cache [list][scan8[7 ]+1]=

            *(uint32_t*)h->mv_cache [list][scan8[13]+1]= //FIXME remove past 3 (init somewher else)

            *(uint32_t*)h->mv_cache [list][scan8[4 ]]=

            *(uint32_t*)h->mv_cache [list][scan8[12]]= 0;

        }

//FIXME

    }

#endif

}


static void nbd_read(void *opaque)

{

    NBDClient *client = opaque;

    if (client->recv_coroutine) {

        qemu_coroutine_enter(client->recv_coroutine, NULL);

    } else {

        qemu_coroutine_enter(qemu_coroutine_create(nbd_trip), client);

    }

}


int qemu_eventfd(int *fds)

{

#if defined(SYS_eventfd)

    int ret;

    ret = syscall(SYS_eventfd, 0);

    if (ret >= 0) {

        fds[0] = fds[1] = ret;

        return 0;

    } else if (!(ret == -1 && errno == ENOSYS))

        return ret;

#endif

    return pipe(fds);

}


int64_t ga_get_fd_handle(GAState *s, Error **errp)

{

    int64_t handle;

    g_assert(s->pstate_filepath);

    /* we blacklist commands and avoid operations that potentially require

     * writing to disk when we're in a frozen state. this includes opening

     * new files, so we should never get here in that situation

     */

    g_assert(!ga_is_frozen(s));

    handle = s->pstate.fd_counter++;

    if (s->pstate.fd_counter < 0) {

        s->pstate.fd_counter = 0;

    }

    if (!write_persistent_state(&s->pstate, s->pstate_filepath)) {

        error_setg(errp, "failed to commit persistent state to disk");

    }

    return handle;

}


static void opt_input_file(const char *filename)

{

    AVFormatContext *ic;

    AVFormatParameters params, *ap = &params;

    AVInputFormat *file_iformat = NULL;

    int err, i, ret, rfps, rfps_base;

    int64_t timestamp;

    if (last_asked_format) {

        if (!(file_iformat = av_find_input_format(last_asked_format))) {

            fprintf(stderr, "Unknown input format: '%s'\n", last_asked_format);

            ffmpeg_exit(1);

        }

        last_asked_format = NULL;

    }

    if (!strcmp(filename, "-"))

        filename = "pipe:";

    using_stdin |= !strncmp(filename, "pipe:", 5) ||

                    !strcmp(filename, "/dev/stdin");

    /* get default parameters from command line */

    ic = avformat_alloc_context();

    if (!ic) {

        print_error(filename, AVERROR(ENOMEM));

        ffmpeg_exit(1);

    }

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

    ap->prealloced_context = 1;

    ap->sample_rate = audio_sample_rate;

    ap->channels = audio_channels;

    ap->time_base.den = frame_rate.num;

    ap->time_base.num = frame_rate.den;

    ap->width = frame_width;

    ap->height = frame_height;

    ap->pix_fmt = frame_pix_fmt;

   // ap->sample_fmt = audio_sample_fmt; //FIXME:not implemented in libavformat

    ap->channel = video_channel;

    ap->standard = video_standard;

    set_context_opts(ic, avformat_opts, AV_OPT_FLAG_DECODING_PARAM, NULL);

    ic->video_codec_id   =

        find_codec_or_die(video_codec_name   , AVMEDIA_TYPE_VIDEO   , 0,

                          avcodec_opts[AVMEDIA_TYPE_VIDEO   ]->strict_std_compliance);

    ic->audio_codec_id   =

        find_codec_or_die(audio_codec_name   , AVMEDIA_TYPE_AUDIO   , 0,

                          avcodec_opts[AVMEDIA_TYPE_AUDIO   ]->strict_std_compliance);

    ic->subtitle_codec_id=

        find_codec_or_die(subtitle_codec_name, AVMEDIA_TYPE_SUBTITLE, 0,

                          avcodec_opts[AVMEDIA_TYPE_SUBTITLE]->strict_std_compliance);

    ic->flags |= AVFMT_FLAG_NONBLOCK;

    if(pgmyuv_compatibility_hack)

        ic->video_codec_id= CODEC_ID_PGMYUV;

    /* open the input file with generic libav function */

    err = av_open_input_file(&ic, filename, file_iformat, 0, ap);

    if (err < 0) {

        print_error(filename, err);

        ffmpeg_exit(1);

    }

    if(opt_programid) {

        int i, j;

        int found=0;

        for(i=0; i<ic->nb_streams; i++){

            ic->streams[i]->discard= AVDISCARD_ALL;

        }

        for(i=0; i<ic->nb_programs; i++){

            AVProgram *p= ic->programs[i];

            if(p->id != opt_programid){

                p->discard = AVDISCARD_ALL;

            }else{

                found=1;

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

                    ic->streams[p->stream_index[j]]->discard= AVDISCARD_DEFAULT;

                }

            }

        }

        if(!found){

            fprintf(stderr, "Specified program id not found\n");

            ffmpeg_exit(1);

        }

        opt_programid=0;

    }

    ic->loop_input = loop_input;

    /* If not enough info to get the stream parameters, we decode the

       first frames to get it. (used in mpeg case for example) */

    ret = av_find_stream_info(ic);

    if (ret < 0 && verbose >= 0) {

        fprintf(stderr, "%s: could not find codec parameters\n", filename);

        av_close_input_file(ic);

        ffmpeg_exit(1);

    }

    timestamp = start_time;

    /* add the stream start time */

    if (ic->start_time != AV_NOPTS_VALUE)

        timestamp += ic->start_time;

    /* if seeking requested, we execute it */

    if (start_time != 0) {

        ret = av_seek_frame(ic, -1, timestamp, AVSEEK_FLAG_BACKWARD);

        if (ret < 0) {

            fprintf(stderr, "%s: could not seek to position %0.3f\n",

                    filename, (double)timestamp / AV_TIME_BASE);

        }

        /* reset seek info */

        start_time = 0;

    }

    /* update the current parameters so that they match the one of the input stream */

    for(i=0;i<ic->nb_streams;i++) {

        AVStream *st = ic->streams[i];

        AVCodecContext *dec = st->codec;

        avcodec_thread_init(dec, thread_count);

        input_codecs = grow_array(input_codecs, sizeof(*input_codecs), &nb_input_codecs, nb_input_codecs + 1);

        switch (dec->codec_type) {

        case AVMEDIA_TYPE_AUDIO:

            input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(audio_codec_name);

            set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_AUDIO], AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);

            //fprintf(stderr, "\nInput Audio channels: %d", dec->channels);

            channel_layout    = dec->channel_layout;

            audio_channels    = dec->channels;

            audio_sample_rate = dec->sample_rate;

            audio_sample_fmt  = dec->sample_fmt;

            if(audio_disable)

                st->discard= AVDISCARD_ALL;

            /* Note that av_find_stream_info can add more streams, and we

             * currently have no chance of setting up lowres decoding

             * early enough for them. */

            if (dec->lowres)

                audio_sample_rate >>= dec->lowres;

            break;

        case AVMEDIA_TYPE_VIDEO:

            input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(video_codec_name);

            set_context_opts(dec, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM, input_codecs[nb_input_codecs-1]);

            frame_height = dec->height;

            frame_width  = dec->width;

            if(ic->streams[i]->sample_aspect_ratio.num)

                frame_aspect_ratio=av_q2d(ic->streams[i]->sample_aspect_ratio);

            else

                frame_aspect_ratio=av_q2d(dec->sample_aspect_ratio);

            frame_aspect_ratio *= (float) dec->width / dec->height;

            frame_pix_fmt = dec->pix_fmt;

            rfps      = ic->streams[i]->r_frame_rate.num;

            rfps_base = ic->streams[i]->r_frame_rate.den;

            if (dec->lowres) {

                dec->flags |= CODEC_FLAG_EMU_EDGE;

                frame_height >>= dec->lowres;

                frame_width  >>= dec->lowres;

            }

            if(me_threshold)

                dec->debug |= FF_DEBUG_MV;

            if (dec->time_base.den != rfps*dec->ticks_per_frame || dec->time_base.num != rfps_base) {

                if (verbose >= 0)

                    fprintf(stderr,"\nSeems stream %d codec frame rate differs from container frame rate: %2.2f (%d/%d) -> %2.2f (%d/%d)\n",

                            i, (float)dec->time_base.den / dec->time_base.num, dec->time_base.den, dec->time_base.num,

                    (float)rfps / rfps_base, rfps, rfps_base);

            }

            /* update the current frame rate to match the stream frame rate */

            frame_rate.num = rfps;

            frame_rate.den = rfps_base;

            if(video_disable)

                st->discard= AVDISCARD_ALL;

            else if(video_discard)

                st->discard= video_discard;

            break;

        case AVMEDIA_TYPE_DATA:

            break;

        case AVMEDIA_TYPE_SUBTITLE:

            input_codecs[nb_input_codecs-1] = avcodec_find_decoder_by_name(subtitle_codec_name);

            if(subtitle_disable)

                st->discard = AVDISCARD_ALL;

            break;

        case AVMEDIA_TYPE_ATTACHMENT:

        case AVMEDIA_TYPE_UNKNOWN:

            break;

        default:

            abort();

        }

    }

    input_files[nb_input_files] = ic;

    input_files_ts_offset[nb_input_files] = input_ts_offset - (copy_ts ? 0 : timestamp);

    /* dump the file content */

    if (verbose >= 0)

        dump_format(ic, nb_input_files, filename, 0);

    nb_input_files++;

    video_channel = 0;

    av_freep(&video_codec_name);

    av_freep(&audio_codec_name);

    av_freep(&subtitle_codec_name);

}


static void gen_load_fpr32h(TCGv_i32 t, int reg)

{

    TCGv_i64 t64 = tcg_temp_new_i64();

    tcg_gen_shri_i64(t64, fpu_f64[reg], 32);

    tcg_gen_trunc_i64_i32(t, t64);

    tcg_temp_free_i64(t64);

}


void block_job_completed(BlockJob *job, int ret)

{

    BlockDriverState *bs = job->bs;

    assert(bs->job == job);

    job->cb(job->opaque, ret);

    bs->job = NULL;

    g_free(job);

    bdrv_set_in_use(bs, 0);

}


static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)

{

    int r;

    if (s->avctx->hwaccel) {

        assert(!pic->hwaccel_data_private);

        if (s->avctx->hwaccel->priv_data_size) {

            pic->hwaccel_data_private = av_malloc(s->avctx->hwaccel->priv_data_size);

            if (!pic->hwaccel_data_private) {

                av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");

                return -1;

            }

        }

    }

    r = s->avctx->get_buffer(s->avctx, (AVFrame*)pic);

    if (r<0 || !pic->age || !pic->type || !pic->data[0]) {

        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]);

        av_freep(&pic->hwaccel_data_private);

        return -1;

    }

    if (s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])) {

        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n");

        free_frame_buffer(s, pic);

        return -1;

    }

    if (pic->linesize[1] != pic->linesize[2]) {

        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n");

        free_frame_buffer(s, pic);

        return -1;

    }

    return 0;

}


static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt)

{

    ASFContext *asf   = s->priv_data;

    ASFStream *asf_st = 0;

    for (;;) {

        int ret;

        if (avio_feof(pb))

            return AVERROR_EOF;

        if (asf->packet_size_left < FRAME_HEADER_SIZE ||

            asf->packet_segments < 1 && asf->packet_time_start == 0) {

            int ret = asf->packet_size_left + asf->packet_padsize;

            assert(ret >= 0);

            /* fail safe */

            avio_skip(pb, ret);

            asf->packet_pos = avio_tell(pb);

            if (asf->data_object_size != (uint64_t)-1 &&

                (asf->packet_pos - asf->data_object_offset >= asf->data_object_size))

                return AVERROR_EOF;  /* Do not exceed the size of the data object */

            return 1;

        }

        if (asf->packet_time_start == 0) {

            if (asf_read_frame_header(s, pb) < 0) {

                asf->packet_time_start = asf->packet_segments = 0;

                continue;

            }

            if (asf->stream_index < 0 ||

                s->streams[asf->stream_index]->discard >= AVDISCARD_ALL ||

                (!asf->packet_key_frame &&

                 (s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY || asf->streams[s->streams[asf->stream_index]->id].skip_to_key))) {

                asf->packet_time_start = 0;

                /* unhandled packet (should not happen) */

                avio_skip(pb, asf->packet_frag_size);

                asf->packet_size_left -= asf->packet_frag_size;

                if (asf->stream_index < 0)

                    av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n",

                           asf->packet_frag_size);

                continue;

            }

            asf->asf_st = &asf->streams[s->streams[asf->stream_index]->id];

            asf->asf_st->skip_to_key = 0;

        }

        asf_st = asf->asf_st;

        av_assert0(asf_st);

        if (!asf_st->frag_offset && asf->packet_frag_offset) {

            av_dlog(s, "skipping asf data pkt with fragment offset for "

                    "stream:%d, expected:%d but got %d from pkt)\n",

                    asf->stream_index, asf_st->frag_offset,

                    asf->packet_frag_offset);

            avio_skip(pb, asf->packet_frag_size);

            asf->packet_size_left -= asf->packet_frag_size;

            continue;

        }

        if (asf->packet_replic_size == 1) {

            // frag_offset is here used as the beginning timestamp

            asf->packet_frag_timestamp = asf->packet_time_start;

            asf->packet_time_start    += asf->packet_time_delta;

            asf_st->packet_obj_size    = asf->packet_frag_size = avio_r8(pb);

            asf->packet_size_left--;

            asf->packet_multi_size--;

            if (asf->packet_multi_size < asf_st->packet_obj_size) {

                asf->packet_time_start = 0;

                avio_skip(pb, asf->packet_multi_size);

                asf->packet_size_left -= asf->packet_multi_size;

                continue;

            }

            asf->packet_multi_size -= asf_st->packet_obj_size;

        }

        if (asf_st->pkt.size != asf_st->packet_obj_size ||

            // FIXME is this condition sufficient?

            asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) {

            if (asf_st->pkt.data) {

                av_log(s, AV_LOG_INFO,

                       "freeing incomplete packet size %d, new %d\n",

                       asf_st->pkt.size, asf_st->packet_obj_size);

                asf_st->frag_offset = 0;

                av_free_packet(&asf_st->pkt);

            }

            /* new packet */

            av_new_packet(&asf_st->pkt, asf_st->packet_obj_size);

            asf_st->seq              = asf->packet_seq;

            if (asf->ts_is_pts) {

                asf_st->pkt.pts          = asf->packet_frag_timestamp - asf->hdr.preroll;

            } else

                asf_st->pkt.dts          = asf->packet_frag_timestamp - asf->hdr.preroll;

            asf_st->pkt.stream_index = asf->stream_index;

            asf_st->pkt.pos          = asf_st->packet_pos = asf->packet_pos;

            asf_st->pkt_clean        = 0;

            if (asf_st->pkt.data && asf_st->palette_changed) {

                uint8_t *pal;

                pal = av_packet_new_side_data(&asf_st->pkt, AV_PKT_DATA_PALETTE,

                                              AVPALETTE_SIZE);

                if (!pal) {

                    av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n");

                } else {

                    memcpy(pal, asf_st->palette, AVPALETTE_SIZE);

                    asf_st->palette_changed = 0;

                }

            }

            av_dlog(asf, "new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n",

                    asf->stream_index, asf->packet_key_frame,

                    asf_st->pkt.flags & AV_PKT_FLAG_KEY,

                    s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO,

                    asf_st->packet_obj_size);

            if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO)

                asf->packet_key_frame = 1;

            if (asf->packet_key_frame)

                asf_st->pkt.flags |= AV_PKT_FLAG_KEY;

        }

        /* read data */

        av_dlog(asf, "READ PACKET s:%d  os:%d  o:%d,%d  l:%d   DATA:%p\n",

                s->packet_size, asf_st->pkt.size, asf->packet_frag_offset,

                asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data);

        asf->packet_size_left -= asf->packet_frag_size;

        if (asf->packet_size_left < 0)

            continue;

        if (asf->packet_frag_offset >= asf_st->pkt.size ||

            asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset) {

            av_log(s, AV_LOG_ERROR,

                   "packet fragment position invalid %u,%u not in %u\n",

                   asf->packet_frag_offset, asf->packet_frag_size,

                   asf_st->pkt.size);

            continue;

        }

        if (asf->packet_frag_offset != asf_st->frag_offset && !asf_st->pkt_clean) {

            memset(asf_st->pkt.data + asf_st->frag_offset, 0, asf_st->pkt.size - asf_st->frag_offset);

            asf_st->pkt_clean = 1;

        }

        ret = avio_read(pb, asf_st->pkt.data + asf->packet_frag_offset,

                        asf->packet_frag_size);

        if (ret != asf->packet_frag_size) {

            if (ret < 0 || asf->packet_frag_offset + ret == 0)

                return ret < 0 ? ret : AVERROR_EOF;

            if (asf_st->ds_span > 1) {

                // scrambling, we can either drop it completely or fill the remainder

                // TODO: should we fill the whole packet instead of just the current

                // fragment?

                memset(asf_st->pkt.data + asf->packet_frag_offset + ret, 0,

                       asf->packet_frag_size - ret);

                ret = asf->packet_frag_size;

            } else {

                // no scrambling, so we can return partial packets

                av_shrink_packet(&asf_st->pkt, asf->packet_frag_offset + ret);

            }

        }

        if (s->key && s->keylen == 20)

            ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset,

                            ret);

        asf_st->frag_offset += ret;

        /* test if whole packet is read */

        if (asf_st->frag_offset == asf_st->pkt.size) {

            // workaround for macroshit radio DVR-MS files

            if (s->streams[asf->stream_index]->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO &&

                asf_st->pkt.size > 100) {

                int i;

                for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++)

                    ;

                if (i == asf_st->pkt.size) {

                    av_log(s, AV_LOG_DEBUG, "discarding ms fart\n");

                    asf_st->frag_offset = 0;

                    av_free_packet(&asf_st->pkt);

                    continue;

                }

            }

            /* return packet */

            if (asf_st->ds_span > 1) {

                if (asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) {

                    av_log(s, AV_LOG_ERROR,

                           "pkt.size != ds_packet_size * ds_span (%d %d %d)\n",

                           asf_st->pkt.size, asf_st->ds_packet_size,

                           asf_st->ds_span);

                } else {

                    /* packet descrambling */

                    AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size +

                                                       FF_INPUT_BUFFER_PADDING_SIZE);

                    if (buf) {

                        uint8_t *newdata = buf->data;

                        int offset = 0;

                        memset(newdata + asf_st->pkt.size, 0,

                               FF_INPUT_BUFFER_PADDING_SIZE);

                        while (offset < asf_st->pkt.size) {

                            int off = offset / asf_st->ds_chunk_size;

                            int row = off / asf_st->ds_span;

                            int col = off % asf_st->ds_span;

                            int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size;

                            assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size);

                            assert(idx + 1 <= asf_st->pkt.size / asf_st->ds_chunk_size);

                            memcpy(newdata + offset,

                                   asf_st->pkt.data + idx * asf_st->ds_chunk_size,

                                   asf_st->ds_chunk_size);

                            offset += asf_st->ds_chunk_size;

                        }

                        av_buffer_unref(&asf_st->pkt.buf);

                        asf_st->pkt.buf  = buf;

                        asf_st->pkt.data = buf->data;

                    }

                }

            }

            asf_st->frag_offset         = 0;

            *pkt                        = asf_st->pkt;

#if FF_API_DESTRUCT_PACKET

FF_DISABLE_DEPRECATION_WARNINGS

            asf_st->pkt.destruct        = NULL;

FF_ENABLE_DEPRECATION_WARNINGS

#endif

            asf_st->pkt.buf             = 0;

            asf_st->pkt.size            = 0;

            asf_st->pkt.data            = 0;

            asf_st->pkt.side_data_elems = 0;

            asf_st->pkt.side_data       = NULL;

            break; // packet completed

        }

    }

    return 0;

}


static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread)

{

    HEVCContext *s  = avctxt->priv_data;

    int ctb_size    = 1 << s->ps.sps->log2_ctb_size;

    int more_data   = 1;

    int x_ctb       = 0;

    int y_ctb       = 0;

    int ctb_addr_ts = s->ps.pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs];

    if (!ctb_addr_ts && s->sh.dependent_slice_segment_flag) {

        av_log(s->avctx, AV_LOG_ERROR, "Impossible initial tile.\n");

        return AVERROR_INVALIDDATA;

    }

    if (s->sh.dependent_slice_segment_flag) {

        int prev_rs = s->ps.pps->ctb_addr_ts_to_rs[ctb_addr_ts - 1];

        if (s->tab_slice_address[prev_rs] != s->sh.slice_addr) {

            av_log(s->avctx, AV_LOG_ERROR, "Previous slice segment missing\n");

            return AVERROR_INVALIDDATA;

        }

    }

    while (more_data && ctb_addr_ts < s->ps.sps->ctb_size) {

        int ctb_addr_rs = s->ps.pps->ctb_addr_ts_to_rs[ctb_addr_ts];

        x_ctb = (ctb_addr_rs % ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size;

        y_ctb = (ctb_addr_rs / ((s->ps.sps->width + ctb_size - 1) >> s->ps.sps->log2_ctb_size)) << s->ps.sps->log2_ctb_size;

        hls_decode_neighbour(s, x_ctb, y_ctb, ctb_addr_ts);

        ff_hevc_cabac_init(s, ctb_addr_ts);

        hls_sao_param(s, x_ctb >> s->ps.sps->log2_ctb_size, y_ctb >> s->ps.sps->log2_ctb_size);

        s->deblock[ctb_addr_rs].beta_offset = s->sh.beta_offset;

        s->deblock[ctb_addr_rs].tc_offset   = s->sh.tc_offset;

        s->filter_slice_edges[ctb_addr_rs]  = s->sh.slice_loop_filter_across_slices_enabled_flag;

        more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->ps.sps->log2_ctb_size, 0);

        if (more_data < 0) {

            s->tab_slice_address[ctb_addr_rs] = -1;

            return more_data;

        }

        ctb_addr_ts++;

        ff_hevc_save_states(s, ctb_addr_ts);

        ff_hevc_hls_filters(s, x_ctb, y_ctb, ctb_size);

    }

    if (x_ctb + ctb_size >= s->ps.sps->width &&

        y_ctb + ctb_size >= s->ps.sps->height)

        ff_hevc_hls_filter(s, x_ctb, y_ctb, ctb_size);

    return ctb_addr_ts;

}


static void reset_packet_state(AVFormatContext *s)

{

    ASFContext *asf        = s->priv_data;

    int i;

    asf->state             = PARSE_PACKET_HEADER;

    asf->offset            = 0;

    asf->return_subpayload = 0;

    asf->sub_left          = 0;

    asf->sub_header_offset = 0;

    asf->packet_offset     = asf->first_packet_offset;

    asf->pad_len           = 0;

    asf->rep_data_len      = 0;

    asf->dts_delta         = 0;

    asf->mult_sub_len      = 0;

    asf->nb_mult_left      = 0;

    asf->nb_sub            = 0;

    asf->prop_flags        = 0;

    asf->sub_dts           = 0;

    asf->dts               = 0;

    for (i = 0; i < asf->nb_streams; i++) {

        ASFPacket *pkt = &asf->asf_st[i]->pkt;

        pkt->size_left = 0;

        pkt->data_size = 0;

        pkt->duration  = 0;

        pkt->flags     = 0;

        pkt->dts       = 0;

        pkt->duration  = 0;

        av_free_packet(&pkt->avpkt);

        av_init_packet(&pkt->avpkt);

    }

}


static int nbd_parse_offset_hole_payload(NBDStructuredReplyChunk *chunk,

                                         uint8_t *payload, uint64_t orig_offset,

                                         QEMUIOVector *qiov, Error **errp)

{

    uint64_t offset;

    uint32_t hole_size;

    if (chunk->length != sizeof(offset) + sizeof(hole_size)) {

        error_setg(errp, "Protocol error: invalid payload for "

                         "NBD_REPLY_TYPE_OFFSET_HOLE");

        return -EINVAL;

    }

    offset = payload_advance64(&payload);

    hole_size = payload_advance32(&payload);

    if (offset < orig_offset || hole_size > qiov->size ||

        offset > orig_offset + qiov->size - hole_size) {

        error_setg(errp, "Protocol error: server sent chunk exceeding requested"

                         " region");

        return -EINVAL;

    }

    qemu_iovec_memset(qiov, offset - orig_offset, 0, hole_size);

    return 0;

}


static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,

                             const uint8_t * buf, int buf_size) {

    AVSContext *h = avctx->priv_data;

    MpegEncContext *s = &h->s;

    int input_size;

    const uint8_t *buf_end;

    const uint8_t *buf_ptr;

    AVFrame *picture = data;

    uint32_t stc = -1;

    s->avctx = avctx;

    if (buf_size == 0) {

        if(!s->low_delay && h->DPB[0].data[0]) {

            *data_size = sizeof(AVPicture);

            *picture = *(AVFrame *) &h->DPB[0];

        }

        return 0;

    }

    buf_ptr = buf;

    buf_end = buf + buf_size;

    for(;;) {

        buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc);

        if(stc & 0xFFFFFE00)

            return FFMAX(0, buf_ptr - buf - s->parse_context.last_index);

        input_size = (buf_end - buf_ptr)*8;

        switch(stc) {

        case CAVS_START_CODE:

            init_get_bits(&s->gb, buf_ptr, input_size);

            decode_seq_header(h);

            break;

        case PIC_I_START_CODE:

            if(!h->got_keyframe) {

                if(h->DPB[0].data[0])

                    avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]);

                if(h->DPB[1].data[0])

                    avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]);

                h->got_keyframe = 1;

            }

        case PIC_PB_START_CODE:

            *data_size = 0;

            if(!h->got_keyframe)

                break;

            init_get_bits(&s->gb, buf_ptr, input_size);

            h->stc = stc;

            if(decode_pic(h))

                break;

            *data_size = sizeof(AVPicture);

            if(h->pic_type != FF_B_TYPE) {

                if(h->DPB[1].data[0]) {

                    *picture = *(AVFrame *) &h->DPB[1];

                } else {

                    *data_size = 0;

                }

            } else

                *picture = *(AVFrame *) &h->picture;

            break;

        case EXT_START_CODE:

            //mpeg_decode_extension(avctx,buf_ptr, input_size);

            break;

        case USER_START_CODE:

            //mpeg_decode_user_data(avctx,buf_ptr, input_size);

            break;

        default:

            if (stc >= SLICE_MIN_START_CODE &&

                stc <= SLICE_MAX_START_CODE) {

                init_get_bits(&s->gb, buf_ptr, input_size);

                decode_slice_header(h, &s->gb);

            }

            break;

        }

    }

}


AVEvalExpr * ff_parse(const char *s, const char * const *const_name,

               double (**func1)(void *, double), const char **func1_name,

               double (**func2)(void *, double, double), const char **func2_name,

               const char **error){

    Parser p;

    AVEvalExpr * e;

    char w[strlen(s) + 1], * wp = w;

    while (*s)

        if (!isspace(*s++)) *wp++ = s[-1];

    *wp++ = 0;

    p.stack_index=100;

    p.s= w;

    p.const_name = const_name;

    p.func1      = func1;

    p.func1_name = func1_name;

    p.func2      = func2;

    p.func2_name = func2_name;

    p.error= error;

    e = parse_expr(&p);

    if (!verify_expr(e)) {

        ff_eval_free(e);

        return NULL;

    }

    return e;

}


static int qemu_rdma_post_send_control(RDMAContext *rdma, uint8_t *buf,

                                       RDMAControlHeader *head)

{

    int ret = 0;

    RDMAWorkRequestData *wr = &rdma->wr_data[RDMA_WRID_CONTROL];

    struct ibv_send_wr *bad_wr;

    struct ibv_sge sge = {

                           .addr = (uint64_t)(wr->control),

                           .length = head->len + sizeof(RDMAControlHeader),

                           .lkey = wr->control_mr->lkey,

                         };

    struct ibv_send_wr send_wr = {

                                   .wr_id = RDMA_WRID_SEND_CONTROL,

                                   .opcode = IBV_WR_SEND,

                                   .send_flags = IBV_SEND_SIGNALED,

                                   .sg_list = &sge,

                                   .num_sge = 1,

                                };

    DDDPRINTF("CONTROL: sending %s..\n", control_desc[head->type]);

    /*

     * We don't actually need to do a memcpy() in here if we used

     * the "sge" properly, but since we're only sending control messages

     * (not RAM in a performance-critical path), then its OK for now.

     *

     * The copy makes the RDMAControlHeader simpler to manipulate

     * for the time being.

     */

    assert(head->len <= RDMA_CONTROL_MAX_BUFFER - sizeof(*head));

    memcpy(wr->control, head, sizeof(RDMAControlHeader));

    control_to_network((void *) wr->control);

    if (buf) {

        memcpy(wr->control + sizeof(RDMAControlHeader), buf, head->len);

    }

    ret = ibv_post_send(rdma->qp, &send_wr, &bad_wr);

    if (ret > 0) {

        fprintf(stderr, "Failed to use post IB SEND for control!\n");

        return -ret;

    }

    ret = qemu_rdma_block_for_wrid(rdma, RDMA_WRID_SEND_CONTROL, NULL);

    if (ret < 0) {

        fprintf(stderr, "rdma migration: send polling control error!\n");

    }

    return ret;

}


static void pci_ich9_ahci_realize(PCIDevice *dev, Error **errp)

{

    struct AHCIPCIState *d;

    int sata_cap_offset;

    uint8_t *sata_cap;

    d = ICH_AHCI(dev);

    ahci_realize(&d->ahci, DEVICE(dev), pci_get_address_space(dev), 6);

    pci_config_set_prog_interface(dev->config, AHCI_PROGMODE_MAJOR_REV_1);

    dev->config[PCI_CACHE_LINE_SIZE] = 0x08;  /* Cache line size */

    dev->config[PCI_LATENCY_TIMER]   = 0x00;  /* Latency timer */

    pci_config_set_interrupt_pin(dev->config, 1);

    /* XXX Software should program this register */

    dev->config[0x90]   = 1 << 6; /* Address Map Register - AHCI mode */

    d->ahci.irq = pci_allocate_irq(dev);

    pci_register_bar(dev, ICH9_IDP_BAR, PCI_BASE_ADDRESS_SPACE_IO,

                     &d->ahci.idp);

    pci_register_bar(dev, ICH9_MEM_BAR, PCI_BASE_ADDRESS_SPACE_MEMORY,

                     &d->ahci.mem);

    sata_cap_offset = pci_add_capability2(dev, PCI_CAP_ID_SATA,

                                          ICH9_SATA_CAP_OFFSET, SATA_CAP_SIZE,

                                          errp);

    if (sata_cap_offset < 0) {

        return;

    }

    sata_cap = dev->config + sata_cap_offset;

    pci_set_word(sata_cap + SATA_CAP_REV, 0x10);

    pci_set_long(sata_cap + SATA_CAP_BAR,

                 (ICH9_IDP_BAR + 0x4) | (ICH9_IDP_INDEX_LOG2 << 4));

    d->ahci.idp_offset = ICH9_IDP_INDEX;

    /* Although the AHCI 1.3 specification states that the first capability

     * should be PMCAP, the Intel ICH9 data sheet specifies that the ICH9

     * AHCI device puts the MSI capability first, pointing to 0x80. */

    msi_init(dev, ICH9_MSI_CAP_OFFSET, 1, true, false);

}


static void parse_cmdline(const char *cmdline,

                          int *pnb_args, char **args)

{

    const char *p;

    int nb_args, ret;

    char buf[1024];

    p = cmdline;

    nb_args = 0;

    for (;;) {

        while (qemu_isspace(*p)) {

            p++;

        }

        if (*p == '\0') {

            break;

        }

        if (nb_args >= MAX_ARGS) {

            break;

        }

        ret = get_str(buf, sizeof(buf), &p);

        args[nb_args] = g_strdup(buf);

        nb_args++;

        if (ret < 0) {

            break;

        }

    }

    *pnb_args = nb_args;

}


static void mpc8544ds_init(ram_addr_t ram_size,

                         const char *boot_device,

                         const char *kernel_filename,

                         const char *kernel_cmdline,

                         const char *initrd_filename,

                         const char *cpu_model)

{

    PCIBus *pci_bus;

    CPUState *env;

    uint64_t elf_entry;

    uint64_t elf_lowaddr;

    target_phys_addr_t entry=0;

    target_phys_addr_t loadaddr=UIMAGE_LOAD_BASE;

    target_long kernel_size=0;

    target_ulong dt_base=DTB_LOAD_BASE;

    target_ulong initrd_base=INITRD_LOAD_BASE;

    target_long initrd_size=0;

    void *fdt;

    int i=0;

    unsigned int pci_irq_nrs[4] = {1, 2, 3, 4};

    qemu_irq *irqs, *mpic, *pci_irqs;

    SerialState * serial[2];

    /* Setup CPU */

    env = cpu_ppc_init("e500v2_v30");

    if (!env) {

        fprintf(stderr, "Unable to initialize CPU!\n");

        exit(1);

    }

    /* Fixup Memory size on a alignment boundary */

    ram_size &= ~(RAM_SIZES_ALIGN - 1);

    /* Register Memory */

    cpu_register_physical_memory(0, ram_size, qemu_ram_alloc(ram_size));

    /* MPIC */

    irqs = qemu_mallocz(sizeof(qemu_irq) * OPENPIC_OUTPUT_NB);

    irqs[OPENPIC_OUTPUT_INT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_INT];

    irqs[OPENPIC_OUTPUT_CINT] = ((qemu_irq *)env->irq_inputs)[PPCE500_INPUT_CINT];

    mpic = mpic_init(MPC8544_MPIC_REGS_BASE, 1, &irqs, NULL);

    /* Serial */

    if (serial_hds[0])

        serial[0] = serial_mm_init(MPC8544_SERIAL0_REGS_BASE,

                               0, mpic[12+26], 399193,

                        serial_hds[0], 1);

    if (serial_hds[1])

        serial[0] = serial_mm_init(MPC8544_SERIAL1_REGS_BASE,

                        0, mpic[12+26], 399193,

                        serial_hds[0], 1);

    /* PCI */

    pci_irqs = qemu_malloc(sizeof(qemu_irq) * 4);

    pci_irqs[0] = mpic[pci_irq_nrs[0]];

    pci_irqs[1] = mpic[pci_irq_nrs[1]];

    pci_irqs[2] = mpic[pci_irq_nrs[2]];

    pci_irqs[3] = mpic[pci_irq_nrs[3]];

    pci_bus = ppce500_pci_init(pci_irqs, MPC8544_PCI_REGS_BASE);

    if (!pci_bus)

        printf("couldn't create PCI controller!\n");

    isa_mmio_init(MPC8544_PCI_IO, MPC8544_PCI_IOLEN);

    if (pci_bus) {

        /* Register network interfaces. */

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

            pci_nic_init(&nd_table[i], "virtio", NULL);

        }

    }

    /* Load kernel. */

    if (kernel_filename) {

        kernel_size = load_uimage(kernel_filename, &entry, &loadaddr, NULL);

        if (kernel_size < 0) {

            kernel_size = load_elf(kernel_filename, 0, &elf_entry, &elf_lowaddr,

                                   NULL, 1, ELF_MACHINE, 0);

            entry = elf_entry;

            loadaddr = elf_lowaddr;

        }

        /* XXX try again as binary */

        if (kernel_size < 0) {

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

                    kernel_filename);

            exit(1);

        }

    }

    /* Load initrd. */

    if (initrd_filename) {

        initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                          ram_size - initrd_base);

        if (initrd_size < 0) {

            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",

                    initrd_filename);

            exit(1);

        }

    }

    /* If we're loading a kernel directly, we must load the device tree too. */

    if (kernel_filename) {

        fdt = mpc8544_load_device_tree(dt_base, ram_size,

                                      initrd_base, initrd_size, kernel_cmdline);

        if (fdt == NULL) {

            fprintf(stderr, "couldn't load device tree\n");

            exit(1);

        }

        /* Set initial guest state. */

        env->gpr[1] = (16<<20) - 8;

        env->gpr[3] = dt_base;

        env->nip = entry;

        /* XXX we currently depend on KVM to create some initial TLB entries. */

    }

    if (kvm_enabled())

        kvmppc_init();

    return;

}


static void read_packets(WriterContext *w, AVFormatContext *fmt_ctx)

{

    int i, ret = 0;

    int64_t cur_ts = fmt_ctx->start_time;

    if (read_intervals_nb == 0) {

        ReadInterval interval = (ReadInterval) { .has_start = 0, .has_end = 0 };

        ret = read_interval_packets(w, fmt_ctx, &interval, &cur_ts);

    } else {

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

            ret = read_interval_packets(w, fmt_ctx, &read_intervals[i], &cur_ts);

            if (ret < 0)

                break;

        }

    }

}


static void vga_update_memory_access(VGACommonState *s)

{

    hwaddr base, offset, size;

    if (s->legacy_address_space == NULL) {

        return;

    }

    if (s->has_chain4_alias) {

        memory_region_del_subregion(s->legacy_address_space, &s->chain4_alias);

        object_unparent(OBJECT(&s->chain4_alias));

        s->has_chain4_alias = false;

        s->plane_updated = 0xf;

    }

    if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==

        VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) {

        offset = 0;

        switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) {

        case 0:

            base = 0xa0000;

            size = 0x20000;

            break;

        case 1:

            base = 0xa0000;

            size = 0x10000;

            offset = s->bank_offset;

            break;

        case 2:

            base = 0xb0000;

            size = 0x8000;

            break;

        case 3:

        default:

            base = 0xb8000;

            size = 0x8000;

            break;

        }

        assert(offset + size <= s->vram_size);

        memory_region_init_alias(&s->chain4_alias, memory_region_owner(&s->vram),

                                 "vga.chain4", &s->vram, offset, size);

        memory_region_add_subregion_overlap(s->legacy_address_space, base,

                                            &s->chain4_alias, 2);

        s->has_chain4_alias = true;

    }

}


int av_opt_set_from_string(void *ctx, const char *opts,

                           const char *const *shorthand,

                           const char *key_val_sep, const char *pairs_sep)

{

    int ret, count = 0;

    const char *dummy_shorthand = NULL;

    char key_buf[68], *value;

    const char *key;

    if (!opts)

        return 0;

    if (!shorthand)

        shorthand = &dummy_shorthand;

    while (*opts) {

        if ((ret = get_key(&opts, key_val_sep, key_buf, sizeof(key_buf))) < 0) {

            if (*shorthand) {

                key = *(shorthand++);

            } else {

                av_log(ctx, AV_LOG_ERROR, "No option name near '%s'\n", opts);

                return AVERROR(EINVAL);

            }

        } else {

            key = key_buf;

            while (*shorthand) /* discard all remaining shorthand */

                shorthand++;

        }

        if (!(value = av_get_token(&opts, pairs_sep)))

            return AVERROR(ENOMEM);

        if (*opts && strchr(pairs_sep, *opts))

            opts++;

        av_log(ctx, AV_LOG_DEBUG, "Setting '%s' to value '%s'\n", key, value);

        if ((ret = av_opt_set(ctx, key, value, 0)) < 0) {

            if (ret == AVERROR_OPTION_NOT_FOUND)

                av_log(ctx, AV_LOG_ERROR, "Option '%s' not found\n", key);

            av_free(value);

            return ret;

        }

        av_free(value);

        count++;

    }

    return count;

}


void helper_sysexit(void)

{

    int cpl;

    cpl = env->hflags & HF_CPL_MASK;

    if (env->sysenter_cs == 0 || cpl != 0) {

        raise_exception_err(EXCP0D_GPF, 0);

    }

    cpu_x86_set_cpl(env, 3);

    cpu_x86_load_seg_cache(env, R_CS, ((env->sysenter_cs + 16) & 0xfffc) | 3,

                           0, 0xffffffff,

                           DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |

                           DESC_S_MASK | (3 << DESC_DPL_SHIFT) |

                           DESC_CS_MASK | DESC_R_MASK | DESC_A_MASK);

    cpu_x86_load_seg_cache(env, R_SS, ((env->sysenter_cs + 24) & 0xfffc) | 3,

                           0, 0xffffffff,

                           DESC_G_MASK | DESC_B_MASK | DESC_P_MASK |

                           DESC_S_MASK | (3 << DESC_DPL_SHIFT) |

                           DESC_W_MASK | DESC_A_MASK);

    ESP = ECX;

    EIP = EDX;

#ifdef USE_KQEMU

    if (kqemu_is_ok(env)) {

        env->exception_index = -1;

        cpu_loop_exit();

    }

#endif

}


static inline void gen_efsnabs(DisasContext *ctx)

{

    if (unlikely(!ctx->spe_enabled)) {

        gen_exception(ctx, POWERPC_EXCP_APU);

        return;

    }

    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);

}