static void parse_numa_node(NumaNodeOptions *node, QemuOpts *opts, Error **errp)

{

    uint16_t nodenr;

    uint16List *cpus = NULL;

    if (node->has_nodeid) {

        nodenr = node->nodeid;

    } else {

        nodenr = nb_numa_nodes;

    }

    if (nodenr >= MAX_NODES) {

        error_setg(errp, "Max number of NUMA nodes reached: %"

                   PRIu16 "", nodenr);

        return;

    }

    if (numa_info[nodenr].present) {

        error_setg(errp, "Duplicate NUMA nodeid: %" PRIu16, nodenr);

        return;

    }

    for (cpus = node->cpus; cpus; cpus = cpus->next) {

        if (cpus->value >= max_cpus) {

            error_setg(errp,

                       "CPU index (%" PRIu16 ")"

                       " should be smaller than maxcpus (%d)",

                       cpus->value, max_cpus);

            return;

        }

        bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1);

    }

    if (node->has_mem && node->has_memdev) {

        error_setg(errp, "qemu: cannot specify both mem= and memdev=");

        return;

    }

    if (have_memdevs == -1) {

        have_memdevs = node->has_memdev;

    }

    if (node->has_memdev != have_memdevs) {

        error_setg(errp, "qemu: memdev option must be specified for either "

                   "all or no nodes");

        return;

    }

    if (node->has_mem) {

        uint64_t mem_size = node->mem;

        const char *mem_str = qemu_opt_get(opts, "mem");

        /* Fix up legacy suffix-less format */

        if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) {

            mem_size <<= 20;

        }

        numa_info[nodenr].node_mem = mem_size;

    }

    if (node->has_memdev) {

        Object *o;

        o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL);

        if (!o) {

            error_setg(errp, "memdev=%s is ambiguous", node->memdev);

            return;

        }

        object_ref(o);

        numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL);

        numa_info[nodenr].node_memdev = MEMORY_BACKEND(o);

    }

    numa_info[nodenr].present = true;

    max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1);

}


static void nested_struct_cleanup(UserDefNested *udnp)

{

    qapi_free_UserDefNested(udnp);

}


static void hl_decode_mb(H264Context *h){

    MpegEncContext * const s = &h->s;

    const int mb_xy= h->mb_xy;

    const int mb_type= s->current_picture.mb_type[mb_xy];

    int is_complex = h->is_complex || IS_INTRA_PCM(mb_type) || s->qscale == 0;

    if(ENABLE_H264_ENCODER && !s->decode)

        return;

    if (is_complex)

        hl_decode_mb_complex(h);

    else hl_decode_mb_simple(h);

}


static int query_format(struct vf_instance *vf, unsigned int fmt)

{

        /* FIXME - really any YUV 4:2:0 input format should work */

        switch (fmt) {

        case IMGFMT_YV12:

        case IMGFMT_IYUV:

        case IMGFMT_I420:

                return ff_vf_next_query_format(vf, IMGFMT_YV12);

        }

        return 0;

}


void ff_jref_idct_add(uint8_t *dest, ptrdiff_t line_size, int16_t *block)

{

    ff_j_rev_dct(block);

    ff_add_pixels_clamped(block, dest, line_size);

}


static void get_id3_tag(AVFormatContext *s, int len)

{

    ID3v2ExtraMeta *id3v2_extra_meta = NULL;

    ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta);

    if (id3v2_extra_meta)

        ff_id3v2_parse_apic(s, &id3v2_extra_meta);

    ff_id3v2_free_extra_meta(&id3v2_extra_meta);

}


static void test_qga_fsfreeze_and_thaw(gconstpointer fix)

{

    const TestFixture *fixture = fix;

    QDict *ret;

    const gchar *status;

    ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-freeze'}");

    g_assert_nonnull(ret);

    qmp_assert_no_error(ret);

    QDECREF(ret);

    ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-status'}");

    g_assert_nonnull(ret);

    qmp_assert_no_error(ret);

    status = qdict_get_try_str(ret, "return");

    g_assert_cmpstr(status, ==, "frozen");

    QDECREF(ret);

    ret = qmp_fd(fixture->fd, "{'execute': 'guest-fsfreeze-thaw'}");

    g_assert_nonnull(ret);

    qmp_assert_no_error(ret);

    QDECREF(ret);

}


static void flush_buffer(ByteIOContext *s)

{

    if (s->buf_ptr > s->buffer) {

        if (s->write_packet)

            s->write_packet(s->opaque, s->buffer, s->buf_ptr - s->buffer);

        if(s->checksum_ptr){

            s->checksum= s->update_checksum(s->checksum, s->checksum_ptr, s->buf_ptr - s->checksum_ptr);

            s->checksum_ptr= s->buffer;

        }

        s->pos += s->buf_ptr - s->buffer;

    }

    s->buf_ptr = s->buffer;

}


int net_init_slirp(QemuOpts *opts, const char *name, VLANState *vlan)

{

    struct slirp_config_str *config;

    const char *vhost;

    const char *vhostname;

    const char *vdhcp_start;

    const char *vnamesrv;

    const char *tftp_export;

    const char *bootfile;

    const char *smb_export;

    const char *vsmbsrv;

    const char *restrict_opt;

    char *vnet = NULL;

    int restricted = 0;

    int ret;

    vhost       = qemu_opt_get(opts, "host");

    vhostname   = qemu_opt_get(opts, "hostname");

    vdhcp_start = qemu_opt_get(opts, "dhcpstart");

    vnamesrv    = qemu_opt_get(opts, "dns");

    tftp_export = qemu_opt_get(opts, "tftp");

    bootfile    = qemu_opt_get(opts, "bootfile");

    smb_export  = qemu_opt_get(opts, "smb");

    vsmbsrv     = qemu_opt_get(opts, "smbserver");

    restrict_opt = qemu_opt_get(opts, "restrict");

    if (restrict_opt) {

        if (!strcmp(restrict_opt, "on") ||

            !strcmp(restrict_opt, "yes") || !strcmp(restrict_opt, "y")) {

            restricted = 1;

        } else if (strcmp(restrict_opt, "off") &&

            strcmp(restrict_opt, "no") && strcmp(restrict_opt, "n")) {

            error_report("invalid option: 'restrict=%s'", restrict_opt);

            return -1;

        }

    }

    if (qemu_opt_get(opts, "ip")) {

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

        int l = strlen(ip) + strlen("/24") + 1;

        vnet = g_malloc(l);

        /* emulate legacy ip= parameter */

        pstrcpy(vnet, l, ip);

        pstrcat(vnet, l, "/24");

    }

    if (qemu_opt_get(opts, "net")) {

        if (vnet) {

            g_free(vnet);

        }

        vnet = g_strdup(qemu_opt_get(opts, "net"));

    }

    qemu_opt_foreach(opts, net_init_slirp_configs, NULL, 0);

    ret = net_slirp_init(vlan, "user", name, restricted, vnet, vhost,

                         vhostname, tftp_export, bootfile, vdhcp_start,

                         vnamesrv, smb_export, vsmbsrv);

    while (slirp_configs) {

        config = slirp_configs;

        slirp_configs = config->next;

        g_free(config);

    }

    g_free(vnet);

    return ret;

}


static int daala_packet(AVFormatContext *s, int idx)

{

    int seg, duration = 1;

    struct ogg *ogg = s->priv_data;

    struct ogg_stream *os = ogg->streams + idx;

    /*

     * first packet handling: here we parse the duration of each packet in the

     * first page and compare the total duration to the page granule to find the

     * encoder delay and set the first timestamp

     */

    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {

        for (seg = os->segp; seg < os->nsegs; seg++)

            if (os->segments[seg] < 255)

                duration++;

        os->lastpts = os->lastdts = daala_gptopts(s, idx, os->granule, NULL) - duration;

        if(s->streams[idx]->start_time == AV_NOPTS_VALUE) {

            s->streams[idx]->start_time = os->lastpts;

            if (s->streams[idx]->duration)

                s->streams[idx]->duration -= s->streams[idx]->start_time;

        }

    }

    /* parse packet duration */

    if (os->psize > 0)

        os->pduration = 1;

    return 0;

}


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

                            int *got_frame, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    CLVContext *c = avctx->priv_data;

    GetByteContext gb;

    uint32_t frame_type;

    int i, j;

    int ret;

    int mb_ret = 0;

    bytestream2_init(&gb, buf, buf_size);

    if (avctx->codec_tag == MKTAG('C','L','V','1')) {

        int skip = bytestream2_get_byte(&gb);

        bytestream2_skip(&gb, (skip + 1) * 8);

    }

    frame_type = bytestream2_get_byte(&gb);

    if ((ret = ff_reget_buffer(avctx, c->pic)) < 0)

        return ret;

    c->pic->key_frame = frame_type & 0x20 ? 1 : 0;

    c->pic->pict_type = frame_type & 0x20 ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;

    if (frame_type & 0x2) {

        if (buf_size < c->mb_width * c->mb_height) {

            av_log(avctx, AV_LOG_ERROR, "Packet too small\n");

            return AVERROR_INVALIDDATA;

        }

        bytestream2_get_be32(&gb); // frame size;

        c->ac_quant        = bytestream2_get_byte(&gb);

        c->luma_dc_quant   = 32;

        c->chroma_dc_quant = 32;

        if ((ret = init_get_bits8(&c->gb, buf + bytestream2_tell(&gb),

                                  (buf_size - bytestream2_tell(&gb)))) < 0)

            return ret;

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

            c->top_dc[i] = 32;

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

            c->left_dc[i] = 32;

        for (j = 0; j < c->mb_height; j++) {

            for (i = 0; i < c->mb_width; i++) {

                ret = decode_mb(c, i, j);

                if (ret < 0)

                    mb_ret = ret;

            }

        }

    } else {

    }

    if ((ret = av_frame_ref(data, c->pic)) < 0)

        return ret;

    *got_frame = 1;

    return mb_ret < 0 ? mb_ret : buf_size;

}


static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt,

                      uint8_t block_type, AVFormatContext *s)

{

    uint8_t * vidbuf_start = NULL;

    int vidbuf_nbytes = 0;

    int code;

    int bytes_copied = 0;

    int position, duration, npixels;

    unsigned int vidbuf_capacity;

    int ret = 0;

    AVStream *st;

    if (vid->video_index < 0) {

        st = avformat_new_stream(s, NULL);

        if (!st)

            return AVERROR(ENOMEM);

        vid->video_index = st->index;

        if (vid->audio_index < 0) {

            av_log_ask_for_sample(s, "No audio packet before first video "

                                  "packet. Using default video time base.\n");

        }

        avpriv_set_pts_info(st, 64, 185, vid->sample_rate);

        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

        st->codec->codec_id   = AV_CODEC_ID_BETHSOFTVID;

        st->codec->width      = vid->width;

        st->codec->height     = vid->height;

    }

    st      = s->streams[vid->video_index];

    npixels = st->codec->width * st->codec->height;

    vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE);

    if(!vidbuf_start)

        return AVERROR(ENOMEM);

    // save the file position for the packet, include block type

    position = avio_tell(pb) - 1;

    vidbuf_start[vidbuf_nbytes++] = block_type;

    // get the current packet duration

    duration = vid->bethsoft_global_delay + avio_rl16(pb);

    // set the y offset if it exists (decoder header data should be in data section)

    if(block_type == VIDEO_YOFF_P_FRAME){

        if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) {

            ret = AVERROR(EIO);

            goto fail;

        }

        vidbuf_nbytes += 2;

    }

    do{

        vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE);

        if(!vidbuf_start)

            return AVERROR(ENOMEM);

        code = avio_r8(pb);

        vidbuf_start[vidbuf_nbytes++] = code;

        if(code >= 0x80){ // rle sequence

            if(block_type == VIDEO_I_FRAME)

                vidbuf_start[vidbuf_nbytes++] = avio_r8(pb);

        } else if(code){ // plain sequence

            if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) {

                ret = AVERROR(EIO);

                goto fail;

            }

            vidbuf_nbytes += code;

        }

        bytes_copied += code & 0x7F;

        if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied

            // may contain a 0 byte even if read all pixels

            if(avio_r8(pb))

                avio_seek(pb, -1, SEEK_CUR);

            break;

        }

        if (bytes_copied > npixels) {

            ret = AVERROR_INVALIDDATA;

            goto fail;

        }

    } while(code);

    // copy data into packet

    if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0)

        goto fail;

    memcpy(pkt->data, vidbuf_start, vidbuf_nbytes);

    av_free(vidbuf_start);

    pkt->pos = position;

    pkt->stream_index = vid->video_index;

    pkt->duration = duration;

    if (block_type == VIDEO_I_FRAME)

        pkt->flags |= AV_PKT_FLAG_KEY;

    /* if there is a new palette available, add it to packet side data */

    if (vid->palette) {

        uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE,

                                                 BVID_PALETTE_SIZE);

        memcpy(pdata, vid->palette, BVID_PALETTE_SIZE);

        av_freep(&vid->palette);

    }

    vid->nframes--;  // used to check if all the frames were read

    return 0;

fail:

    av_free(vidbuf_start);

    return ret;

}


static int stdio_pclose(void *opaque)

{

    QEMUFileStdio *s = opaque;

    int ret;

    ret = pclose(s->stdio_file);

    if (ret == -1) {

        ret = -errno;

    } else if (!WIFEXITED(ret) || WEXITSTATUS(ret) != 0) {

        /* close succeeded, but non-zero exit code: */

        ret = -EIO; /* fake errno value */

    }

    g_free(s);

    return ret;

}


static int nvdec_vp8_start_frame(AVCodecContext *avctx, const uint8_t *buffer, uint32_t size)

{

    VP8Context *h = avctx->priv_data;

    NVDECContext      *ctx = avctx->internal->hwaccel_priv_data;

    CUVIDPICPARAMS     *pp = &ctx->pic_params;

    FrameDecodeData *fdd;

    NVDECFrame *cf;

    AVFrame *cur_frame = h->framep[VP56_FRAME_CURRENT]->tf.f;

    int ret;

    ret = ff_nvdec_start_frame(avctx, cur_frame);

    if (ret < 0)

        return ret;

    fdd = (FrameDecodeData*)cur_frame->private_ref->data;

    cf  = (NVDECFrame*)fdd->hwaccel_priv;

    *pp = (CUVIDPICPARAMS) {

        .PicWidthInMbs     = (cur_frame->width  + 15) / 16,

        .FrameHeightInMbs  = (cur_frame->height + 15) / 16,

        .CurrPicIdx        = cf->idx,

        .CodecSpecific.vp8 = {

            .width                       = cur_frame->width,

            .height                      = cur_frame->height,

            .first_partition_size        = h->header_partition_size,

            .LastRefIdx                  = safe_get_ref_idx(h->framep[VP56_FRAME_PREVIOUS]),

            .GoldenRefIdx                = safe_get_ref_idx(h->framep[VP56_FRAME_GOLDEN]),

            .AltRefIdx                   = safe_get_ref_idx(h->framep[VP56_FRAME_GOLDEN2]),

            .frame_type                  = !h->keyframe,

            .version                     = h->profile,

            .show_frame                  = !h->invisible,

            .update_mb_segmentation_data = h->segmentation.enabled ? h->segmentation.update_feature_data : 0,

       }

    };

    return 0;

}


static void ahci_irq_lower(AHCIState *s, AHCIDevice *dev)

{

    AHCIPCIState *d = container_of(s, AHCIPCIState, ahci);

    DPRINTF(0, "lower irq\n");

    if (!msi_enabled(PCI_DEVICE(d))) {

        qemu_irq_lower(s->irq);

    }

}


static void adb_mouse_realizefn(DeviceState *dev, Error **errp)

{

    MouseState *s = ADB_MOUSE(dev);

    ADBMouseClass *amc = ADB_MOUSE_GET_CLASS(dev);

    amc->parent_realize(dev, errp);

    qemu_add_mouse_event_handler(adb_mouse_event, s, 0, "QEMU ADB Mouse");

}


int msmpeg4_decode_mb(MpegEncContext *s,

                      DCTELEM block[6][64])

{

    int cbp, code, i;

    int pred, val;

    UINT8 *coded_val;

    /* special slice handling */

    if (s->mb_x == 0) {

        if ((s->mb_y % s->slice_height) == 0) {

            int wrap;

            /* reset DC pred (set previous line to 1024) */

            wrap = 2 * s->mb_width + 2;

            memsetw(&s->dc_val[0][(1) + (2 * s->mb_y) * wrap],

                    1024, 2 * s->mb_width);

            wrap = s->mb_width + 2;

            memsetw(&s->dc_val[1][(1) + (s->mb_y) * wrap],

                    1024, s->mb_width);

            memsetw(&s->dc_val[2][(1) + (s->mb_y) * wrap],

                    1024, s->mb_width);

            s->first_slice_line = 1;

        } else {

            s->first_slice_line = 0;

        }

    }

    if (s->pict_type == P_TYPE) {

        set_stat(ST_INTER_MB);

        if (s->use_skip_mb_code) {

            if (get_bits1(&s->gb)) {

                /* skip mb */

                s->mb_intra = 0;

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

                    s->block_last_index[i] = -1;

                s->mv_dir = MV_DIR_FORWARD;

                s->mv_type = MV_TYPE_16X16;

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

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

                s->mb_skiped = 1;

                return 0;

            }

        }

        code = get_vlc(&s->gb, &mb_non_intra_vlc);

        if (code < 0)

            return -1;

        if (code & 0x40)

            s->mb_intra = 0;

        else

            s->mb_intra = 1;

        cbp = code & 0x3f;

    } else {

        set_stat(ST_INTRA_MB);

        s->mb_intra = 1;

        code = get_vlc(&s->gb, &mb_intra_vlc);

        if (code < 0)

            return -1;

        /* predict coded block pattern */

        cbp = 0;

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

            val = ((code >> (5 - i)) & 1);

            if (i < 4) {

                pred = coded_block_pred(s, i, &coded_val);

                val = val ^ pred;

                *coded_val = val;

            }

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

        }

    }

    if (!s->mb_intra) {

        int mx, my;

        set_stat(ST_MV);

        h263_pred_motion(s, 0, &mx, &my);

        if (msmpeg4_decode_motion(s, &mx, &my) < 0)

            return -1;

        s->mv_dir = MV_DIR_FORWARD;

        s->mv_type = MV_TYPE_16X16;

        s->mv[0][0][0] = mx;

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

    } else {

        set_stat(ST_INTRA_MB);

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

    }

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

        if (msmpeg4_decode_block(s, block[i], i, (cbp >> (5 - i)) & 1) < 0)

            return -1;

    }

    return 0;

}


static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data,

                                int size, int64_t pos, uint64_t cluster_time,

                                uint64_t duration, int is_keyframe,

                                int64_t cluster_pos)

{

    uint64_t timecode = AV_NOPTS_VALUE;

    MatroskaTrack *track;

    int res = 0;

    AVStream *st;

    AVPacket *pkt;

    int16_t block_time;

    uint32_t *lace_size = NULL;

    int n, flags, laces = 0;

    uint64_t num;

    if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) {

        av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n");

        return res;

    }

    data += n;

    size -= n;

    track = matroska_find_track_by_num(matroska, num);

    if (size <= 3 || !track || !track->stream) {

        av_log(matroska->ctx, AV_LOG_INFO,

               "Invalid stream %"PRIu64" or size %u\n", num, size);

        return res;

    }

    st = track->stream;

    if (st->discard >= AVDISCARD_ALL)

        return res;

    if (duration == AV_NOPTS_VALUE)

        duration = track->default_duration / matroska->time_scale;

    block_time = AV_RB16(data);

    data += 2;

    flags = *data++;

    size -= 3;

    if (is_keyframe == -1)

        is_keyframe = flags & 0x80 ? PKT_FLAG_KEY : 0;

    if (cluster_time != (uint64_t)-1

        && (block_time >= 0 || cluster_time >= -block_time)) {

        timecode = cluster_time + block_time;

        if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE

            && timecode < track->end_timecode)

            is_keyframe = 0;  /* overlapping subtitles are not key frame */

        if (is_keyframe)

            av_add_index_entry(st, cluster_pos, timecode, 0,0,AVINDEX_KEYFRAME);

        track->end_timecode = FFMAX(track->end_timecode, timecode+duration);

    }

    if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) {

        if (!is_keyframe || timecode < matroska->skip_to_timecode)

            return res;

        matroska->skip_to_keyframe = 0;

    }

    switch ((flags & 0x06) >> 1) {

        case 0x0: /* no lacing */

            laces = 1;

            lace_size = av_mallocz(sizeof(int));

            lace_size[0] = size;

            break;

        case 0x1: /* Xiph lacing */

        case 0x2: /* fixed-size lacing */

        case 0x3: /* EBML lacing */

            assert(size>0); // size <=3 is checked before size-=3 above

            laces = (*data) + 1;

            data += 1;

            size -= 1;

            lace_size = av_mallocz(laces * sizeof(int));

            switch ((flags & 0x06) >> 1) {

                case 0x1: /* Xiph lacing */ {

                    uint8_t temp;

                    uint32_t total = 0;

                    for (n = 0; res == 0 && n < laces - 1; n++) {

                        while (1) {

                            if (size == 0) {

                                res = -1;

                                break;

                            }

                            temp = *data;

                            lace_size[n] += temp;

                            data += 1;

                            size -= 1;

                            if (temp != 0xff)

                                break;

                        }

                        total += lace_size[n];

                    }

                    lace_size[n] = size - total;

                    break;

                }

                case 0x2: /* fixed-size lacing */

                    for (n = 0; n < laces; n++)

                        lace_size[n] = size / laces;

                    break;

                case 0x3: /* EBML lacing */ {

                    uint32_t total;

                    n = matroska_ebmlnum_uint(matroska, data, size, &num);

                    if (n < 0) {

                        av_log(matroska->ctx, AV_LOG_INFO,

                               "EBML block data error\n");

                        break;

                    }

                    data += n;

                    size -= n;

                    total = lace_size[0] = num;

                    for (n = 1; res == 0 && n < laces - 1; n++) {

                        int64_t snum;

                        int r;

                        r = matroska_ebmlnum_sint(matroska, data, size, &snum);

                        if (r < 0) {

                            av_log(matroska->ctx, AV_LOG_INFO,

                                   "EBML block data error\n");

                            break;

                        }

                        data += r;

                        size -= r;

                        lace_size[n] = lace_size[n - 1] + snum;

                        total += lace_size[n];

                    }

                    lace_size[n] = size - total;

                    break;

                }

            }

            break;

    }

    if (res == 0) {

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

            if (st->codec->codec_id == CODEC_ID_RA_288 ||

                st->codec->codec_id == CODEC_ID_COOK ||

                st->codec->codec_id == CODEC_ID_ATRAC3) {

                int a = st->codec->block_align;

                int sps = track->audio.sub_packet_size;

                int cfs = track->audio.coded_framesize;

                int h = track->audio.sub_packet_h;

                int y = track->audio.sub_packet_cnt;

                int w = track->audio.frame_size;

                int x;

                if (!track->audio.pkt_cnt) {

                    if (st->codec->codec_id == CODEC_ID_RA_288)

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

                            memcpy(track->audio.buf+x*2*w+y*cfs,

                                   data+x*cfs, cfs);

                    else

                        for (x=0; x<w/sps; x++)

                            memcpy(track->audio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps);

                    if (++track->audio.sub_packet_cnt >= h) {

                        track->audio.sub_packet_cnt = 0;

                        track->audio.pkt_cnt = h*w / a;

                    }

                }

                while (track->audio.pkt_cnt) {

                    pkt = av_mallocz(sizeof(AVPacket));

                    av_new_packet(pkt, a);

                    memcpy(pkt->data, track->audio.buf

                           + a * (h*w / a - track->audio.pkt_cnt--), a);

                    pkt->pos = pos;

                    pkt->stream_index = st->index;

                    dynarray_add(&matroska->packets,&matroska->num_packets,pkt);

                }

            } else {

                MatroskaTrackEncoding *encodings = track->encodings.elem;

                int offset = 0, pkt_size = lace_size[n];

                uint8_t *pkt_data = data;

                if (encodings && encodings->scope & 1) {

                    offset = matroska_decode_buffer(&pkt_data,&pkt_size, track);

                    if (offset < 0)

                        continue;

                }

                pkt = av_mallocz(sizeof(AVPacket));

                /* XXX: prevent data copy... */

                if (av_new_packet(pkt, pkt_size+offset) < 0) {

                    av_free(pkt);

                    res = AVERROR(ENOMEM);

                    break;

                }

                if (offset)

                    memcpy (pkt->data, encodings->compression.settings.data, offset);

                memcpy (pkt->data+offset, pkt_data, pkt_size);

                if (pkt_data != data)

                    av_free(pkt_data);

                if (n == 0)

                    pkt->flags = is_keyframe;

                pkt->stream_index = st->index;

                pkt->pts = timecode;

                pkt->pos = pos;

                if (st->codec->codec_id == CODEC_ID_TEXT)

                    pkt->convergence_duration = duration;

                else if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE)

                    pkt->duration = duration;

                if (st->codec->codec_id == CODEC_ID_SSA)

                    matroska_fix_ass_packet(matroska, pkt, duration);

                if (matroska->prev_pkt &&

                    timecode != AV_NOPTS_VALUE &&

                    matroska->prev_pkt->pts == timecode &&

                    matroska->prev_pkt->stream_index == st->index)

                    matroska_merge_packets(matroska->prev_pkt, pkt);

                else {

                    dynarray_add(&matroska->packets,&matroska->num_packets,pkt);

                    matroska->prev_pkt = pkt;

                }

            }

            if (timecode != AV_NOPTS_VALUE)

                timecode = duration ? timecode + duration : AV_NOPTS_VALUE;

            data += lace_size[n];

        }

    }

    av_free(lace_size);

    return res;

}


static int coroutine_fn backup_do_cow(BlockDriverState *bs,

                                      int64_t sector_num, int nb_sectors,

                                      bool *error_is_read,

                                      bool is_write_notifier)

{

    BackupBlockJob *job = (BackupBlockJob *)bs->job;

    CowRequest cow_request;

    struct iovec iov;

    QEMUIOVector bounce_qiov;

    void *bounce_buffer = NULL;

    int ret = 0;

    int64_t sectors_per_cluster = cluster_size_sectors(job);

    int64_t start, end;

    int n;

    qemu_co_rwlock_rdlock(&job->flush_rwlock);

    start = sector_num / sectors_per_cluster;

    end = DIV_ROUND_UP(sector_num + nb_sectors, sectors_per_cluster);

    trace_backup_do_cow_enter(job, start, sector_num, nb_sectors);

    wait_for_overlapping_requests(job, start, end);

    cow_request_begin(&cow_request, job, start, end);

    for (; start < end; start++) {

        if (hbitmap_get(job->bitmap, start)) {

            trace_backup_do_cow_skip(job, start);

            continue; /* already copied */

        }

        trace_backup_do_cow_process(job, start);

        n = MIN(sectors_per_cluster,

                job->common.len / BDRV_SECTOR_SIZE -

                start * sectors_per_cluster);

        if (!bounce_buffer) {

            bounce_buffer = qemu_blockalign(bs, job->cluster_size);

        }

        iov.iov_base = bounce_buffer;

        iov.iov_len = n * BDRV_SECTOR_SIZE;

        qemu_iovec_init_external(&bounce_qiov, &iov, 1);

        if (is_write_notifier) {

            ret = bdrv_co_readv_no_serialising(bs,

                                           start * sectors_per_cluster,

                                           n, &bounce_qiov);

        } else {

            ret = bdrv_co_readv(bs, start * sectors_per_cluster, n,

                                &bounce_qiov);

        }

        if (ret < 0) {

            trace_backup_do_cow_read_fail(job, start, ret);

            if (error_is_read) {

                *error_is_read = true;

            }

            goto out;

        }

        if (buffer_is_zero(iov.iov_base, iov.iov_len)) {

            ret = bdrv_co_write_zeroes(job->target,

                                       start * sectors_per_cluster,

                                       n, BDRV_REQ_MAY_UNMAP);

        } else {

            ret = bdrv_co_writev(job->target,

                                 start * sectors_per_cluster, n,

                                 &bounce_qiov);

        }

        if (ret < 0) {

            trace_backup_do_cow_write_fail(job, start, ret);

            if (error_is_read) {

                *error_is_read = false;

            }

            goto out;

        }

        hbitmap_set(job->bitmap, start, 1);

        /* Publish progress, guest I/O counts as progress too.  Note that the

         * offset field is an opaque progress value, it is not a disk offset.

         */

        job->sectors_read += n;

        job->common.offset += n * BDRV_SECTOR_SIZE;

    }

out:

    if (bounce_buffer) {

        qemu_vfree(bounce_buffer);

    }

    cow_request_end(&cow_request);

    trace_backup_do_cow_return(job, sector_num, nb_sectors, ret);

    qemu_co_rwlock_unlock(&job->flush_rwlock);

    return ret;

}


static void gen_dcbz(DisasContext *ctx)

{

    TCGv tcgv_addr;

    TCGv_i32 tcgv_is_dcbzl;

    int is_dcbzl = ctx->opcode & 0x00200000 ? 1 : 0;

    gen_set_access_type(ctx, ACCESS_CACHE);

    tcgv_addr = tcg_temp_new();

    tcgv_is_dcbzl = tcg_const_i32(is_dcbzl);

    gen_addr_reg_index(ctx, tcgv_addr);

    gen_helper_dcbz(cpu_env, tcgv_addr, tcgv_is_dcbzl);

    tcg_temp_free(tcgv_addr);

    tcg_temp_free_i32(tcgv_is_dcbzl);

}


static void rtsp_cmd_pause(HTTPContext *c, const char *url, RTSPHeader *h)

{

    HTTPContext *rtp_c;

    rtp_c = find_rtp_session_with_url(url, h->session_id);

    if (!rtp_c) {

        rtsp_reply_error(c, RTSP_STATUS_SESSION);

        return;

    }

    if (rtp_c->state != HTTPSTATE_SEND_DATA &&

        rtp_c->state != HTTPSTATE_WAIT_FEED) {

        rtsp_reply_error(c, RTSP_STATUS_STATE);

        return;

    }

    rtp_c->state = HTTPSTATE_READY;

    /* now everything is OK, so we can send the connection parameters */

    rtsp_reply_header(c, RTSP_STATUS_OK);

    /* session ID */

    url_fprintf(c->pb, "Session: %s\r\n", rtp_c->session_id);

    url_fprintf(c->pb, "\r\n");

}


static void spapr_vio_quiesce_one(VIOsPAPRDevice *dev)

{

    if (dev->tcet) {

        spapr_tce_reset(dev->tcet);

    }

    free_crq(dev);

}


PXA2xxMMCIState *pxa2xx_mmci_init(MemoryRegion *sysmem,

                hwaddr base,

                BlockDriverState *bd, qemu_irq irq,

                qemu_irq rx_dma, qemu_irq tx_dma)

{

    PXA2xxMMCIState *s;

    s = (PXA2xxMMCIState *) g_malloc0(sizeof(PXA2xxMMCIState));

    s->irq = irq;

    s->rx_dma = rx_dma;

    s->tx_dma = tx_dma;

    memory_region_init_io(&s->iomem, NULL, &pxa2xx_mmci_ops, s,

                          "pxa2xx-mmci", 0x00100000);

    memory_region_add_subregion(sysmem, base, &s->iomem);

    /* Instantiate the actual storage */

    s->card = sd_init(bd, false);

    if (s->card == NULL) {

        exit(1);

    }

    register_savevm(NULL, "pxa2xx_mmci", 0, 0,

                    pxa2xx_mmci_save, pxa2xx_mmci_load, s);

    return s;

}


int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)

{

    int64_t delta;

    if (!timer_list->clock->enabled || !timer_list->active_timers) {

        return -1;

    }

    delta = timer_list->active_timers->expire_time -

        qemu_clock_get_ns(timer_list->clock->type);

    if (delta <= 0) {

        return 0;

    }

    return delta;

}


void *qemu_mallocz(size_t size)

{

    void *ptr;

    ptr = qemu_malloc(size);

    if (!ptr)

        return NULL;

    memset(ptr, 0, size);

    return ptr;

}


sosendoob(struct socket *so)

{

	struct sbuf *sb = &so->so_rcv;

	char buff[2048]; /* XXX Shouldn't be sending more oob data than this */

	int n, len;

	DEBUG_CALL("sosendoob");

	DEBUG_ARG("so = %p", so);

	DEBUG_ARG("sb->sb_cc = %d", sb->sb_cc);

	if (so->so_urgc > 2048)

	   so->so_urgc = 2048; /* XXXX */

	if (sb->sb_rptr < sb->sb_wptr) {

		/* We can send it directly */

		n = slirp_send(so, sb->sb_rptr, so->so_urgc, (MSG_OOB)); /* |MSG_DONTWAIT)); */

		so->so_urgc -= n;

		DEBUG_MISC((dfd, " --- sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));

	} else {

		/*

		 * Since there's no sendv or sendtov like writev,

		 * we must copy all data to a linear buffer then

		 * send it all

		 */

		len = (sb->sb_data + sb->sb_datalen) - sb->sb_rptr;

		if (len > so->so_urgc) len = so->so_urgc;

		memcpy(buff, sb->sb_rptr, len);

		so->so_urgc -= len;

		if (so->so_urgc) {

			n = sb->sb_wptr - sb->sb_data;

			if (n > so->so_urgc) n = so->so_urgc;

			memcpy((buff + len), sb->sb_data, n);

			so->so_urgc -= n;

			len += n;

		}

		n = slirp_send(so, buff, len, (MSG_OOB)); /* |MSG_DONTWAIT)); */

#ifdef DEBUG

		if (n != len)

		   DEBUG_ERROR((dfd, "Didn't send all data urgently XXXXX\n"));

#endif

		DEBUG_MISC((dfd, " ---2 sent %d bytes urgent data, %d urgent bytes left\n", n, so->so_urgc));

	}

	sb->sb_cc -= n;

	sb->sb_rptr += n;

	if (sb->sb_rptr >= (sb->sb_data + sb->sb_datalen))

		sb->sb_rptr -= sb->sb_datalen;

	return n;

}


AVParserState *ff_store_parser_state(AVFormatContext *s)

{

    int i;

    AVStream *st;

    AVParserStreamState *ss;

    AVParserState *state = av_malloc(sizeof(AVParserState));

    if (!state)

        return NULL;

    state->stream_states = av_malloc(sizeof(AVParserStreamState) * s->nb_streams);

    if (!state->stream_states) {

        av_free(state);

        return NULL;

    }

    state->fpos = avio_tell(s->pb);

    // copy context structures

    state->cur_st                           = s->cur_st;

    state->packet_buffer                    = s->packet_buffer;

    state->raw_packet_buffer                = s->raw_packet_buffer;

    state->raw_packet_buffer_remaining_size = s->raw_packet_buffer_remaining_size;

    s->cur_st                               = NULL;

    s->packet_buffer                        = NULL;

    s->raw_packet_buffer                    = NULL;

    s->raw_packet_buffer_remaining_size     = RAW_PACKET_BUFFER_SIZE;

    // copy stream structures

    state->nb_streams = s->nb_streams;

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

        st = s->streams[i];

        ss = &state->stream_states[i];

        ss->parser        = st->parser;

        ss->last_IP_pts   = st->last_IP_pts;

        ss->cur_dts       = st->cur_dts;

        ss->reference_dts = st->reference_dts;

        ss->cur_ptr       = st->cur_ptr;

        ss->cur_len       = st->cur_len;

        ss->probe_packets = st->probe_packets;

        ss->cur_pkt       = st->cur_pkt;

        st->parser        = NULL;

        st->last_IP_pts   = AV_NOPTS_VALUE;

        st->cur_dts       = AV_NOPTS_VALUE;

        st->reference_dts = AV_NOPTS_VALUE;

        st->cur_ptr       = NULL;

        st->cur_len       = 0;

        st->probe_packets = MAX_PROBE_PACKETS;

        av_init_packet(&st->cur_pkt);

    }

    return state;

}


void ff_mpegts_parse_close(MpegTSContext *ts)

{

    int i;

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

        av_free(ts->pids[i]);

    av_free(ts);

}


static void gen_tlbiel(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);

#endif

}


static int config_input(AVFilterLink *inlink)

{

    AVFilterContext *ctx = inlink->dst;

    PadContext *s = ctx->priv;

    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);

    uint8_t rgba_color[4];

    int ret, is_packed_rgba;

    double var_values[VARS_NB], res;

    char *expr;

    s->hsub = pix_desc->log2_chroma_w;

    s->vsub = pix_desc->log2_chroma_h;

    var_values[VAR_PI]    = M_PI;

    var_values[VAR_PHI]   = M_PHI;

    var_values[VAR_E]     = M_E;

    var_values[VAR_IN_W]  = var_values[VAR_IW] = inlink->w;

    var_values[VAR_IN_H]  = var_values[VAR_IH] = inlink->h;

    var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN;

    var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN;

    var_values[VAR_A]     = (double) inlink->w / inlink->h;

    var_values[VAR_HSUB]  = 1<<s->hsub;

    var_values[VAR_VSUB]  = 1<<s->vsub;

    /* evaluate width and height */

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto eval_fail;

    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->h_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto eval_fail;

    s->h = var_values[VAR_OUT_H] = var_values[VAR_OH] = res;

    /* evaluate the width again, as it may depend on the evaluated output height */

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->w_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto eval_fail;

    s->w = var_values[VAR_OUT_W] = var_values[VAR_OW] = res;

    /* evaluate x and y */

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto eval_fail;

    s->x = var_values[VAR_X] = res;

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->y_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto eval_fail;

    s->y = var_values[VAR_Y] = res;

    /* evaluate x again, as it may depend on the evaluated y value */

    if ((ret = av_expr_parse_and_eval(&res, (expr = s->x_expr),

                                      var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto eval_fail;

    s->x = var_values[VAR_X] = res;

    /* sanity check params */

    if (s->w < 0 || s->h < 0 || s->x < 0 || s->y < 0) {

        av_log(ctx, AV_LOG_ERROR, "Negative values are not acceptable.\n");

        return AVERROR(EINVAL);

    }

    if (!s->w)

        s->w = inlink->w;

    if (!s->h)

        s->h = inlink->h;

    s->w &= ~((1 << s->hsub) - 1);

    s->h &= ~((1 << s->vsub) - 1);

    s->x &= ~((1 << s->hsub) - 1);

    s->y &= ~((1 << s->vsub) - 1);

    s->in_w = inlink->w & ~((1 << s->hsub) - 1);

    s->in_h = inlink->h & ~((1 << s->vsub) - 1);

    memcpy(rgba_color, s->color, sizeof(rgba_color));

    ff_fill_line_with_color(s->line, s->line_step, s->w, s->color,

                            inlink->format, rgba_color, &is_packed_rgba, NULL);

    av_log(ctx, AV_LOG_VERBOSE, "w:%d h:%d -> w:%d h:%d x:%d y:%d color:0x%02X%02X%02X%02X[%s]\n",

           inlink->w, inlink->h, s->w, s->h, s->x, s->y,

           s->color[0], s->color[1], s->color[2], s->color[3],

           is_packed_rgba ? "rgba" : "yuva");

    if (s->x <  0 || s->y <  0                      ||

        s->w <= 0 || s->h <= 0                      ||

        (unsigned)s->x + (unsigned)inlink->w > s->w ||

        (unsigned)s->y + (unsigned)inlink->h > s->h) {

        av_log(ctx, AV_LOG_ERROR,

               "Input area %d:%d:%d:%d not within the padded area 0:0:%d:%d or zero-sized\n",

               s->x, s->y, s->x + inlink->w, s->y + inlink->h, s->w, s->h);

        return AVERROR(EINVAL);

    }

    return 0;

eval_fail:

    av_log(NULL, AV_LOG_ERROR,

           "Error when evaluating the expression '%s'\n", expr);

    return ret;

}


static void local_mapped_file_attr(FsContext *ctx, const char *path,

                                   struct stat *stbuf)

{

    FILE *fp;

    char buf[ATTR_MAX];

    char *attr_path;

    attr_path = local_mapped_attr_path(ctx, path);

    fp = local_fopen(attr_path, "r");

    g_free(attr_path);

    if (!fp) {

        return;

    }

    memset(buf, 0, ATTR_MAX);

    while (fgets(buf, ATTR_MAX, fp)) {

        if (!strncmp(buf, "virtfs.uid", 10)) {

            stbuf->st_uid = atoi(buf+11);

        } else if (!strncmp(buf, "virtfs.gid", 10)) {

            stbuf->st_gid = atoi(buf+11);

        } else if (!strncmp(buf, "virtfs.mode", 11)) {

            stbuf->st_mode = atoi(buf+12);

        } else if (!strncmp(buf, "virtfs.rdev", 11)) {

            stbuf->st_rdev = atoi(buf+12);

        }

        memset(buf, 0, ATTR_MAX);

    }

    fclose(fp);

}


AVRational av_guess_frame_rate(AVFormatContext *format, AVStream *st, AVFrame *frame)

{

    AVRational fr = st->r_frame_rate;

    AVRational codec_fr = st->codec->framerate;

    AVRational   avg_fr = st->avg_frame_rate;

    if (avg_fr.num > 0 && avg_fr.den > 0 && fr.num > 0 && fr.den > 0 &&

        av_q2d(avg_fr) < 70 && av_q2d(fr) > 210) {

        fr = avg_fr;

    }

    if (st->codec->ticks_per_frame > 1) {

        if (   codec_fr.num > 0 && codec_fr.den > 0 && av_q2d(codec_fr) < av_q2d(fr)*0.7

            && fabs(1.0 - av_q2d(av_div_q(avg_fr, fr))) > 0.1)

            fr = codec_fr;

    }

    return fr;

}


static void apply_mid_side_stereo(ChannelElement *cpe)

{

    int w, w2, g, i;

    IndividualChannelStream *ics = &cpe->ch[0].ics;

    if (!cpe->common_window)

        return;

    for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {

        for (w2 =  0; w2 < ics->group_len[w]; w2++) {

            int start = (w+w2) * 128;

            for (g = 0; g < ics->num_swb; g++) {

                if (!cpe->ms_mask[w*16 + g]) {

                    start += ics->swb_sizes[g];

                    continue;

                }

                for (i = 0; i < ics->swb_sizes[g]; i++) {

                    float L = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) * 0.5f;

                    float R = L - cpe->ch[1].coeffs[start+i];

                    cpe->ch[0].coeffs[start+i] = L;

                    cpe->ch[1].coeffs[start+i] = R;

                }

                start += ics->swb_sizes[g];

            }

        }

    }

}


static int ea_read_header(AVFormatContext *s,

                          AVFormatParameters *ap)

{

    EaDemuxContext *ea = s->priv_data;

    AVStream *st;

    if (!process_ea_header(s))

        return AVERROR(EIO);

    if (ea->time_base.num && ea->time_base.den) {

        /* initialize the video decoder stream */

        st = av_new_stream(s, 0);

        if (!st)

            return AVERROR(ENOMEM);

        ea->video_stream_index = st->index;

        st->codec->codec_type = CODEC_TYPE_VIDEO;

        st->codec->codec_id = ea->video_codec;

        st->codec->codec_tag = 0;  /* no fourcc */

        st->codec->time_base = ea->time_base;

    }

    if (ea->audio_codec) {

        /* initialize the audio decoder stream */

        st = av_new_stream(s, 0);

        if (!st)

            return AVERROR(ENOMEM);

        av_set_pts_info(st, 33, 1, ea->sample_rate);

        st->codec->codec_type = CODEC_TYPE_AUDIO;

        st->codec->codec_id = ea->audio_codec;

        st->codec->codec_tag = 0;  /* no tag */

        st->codec->channels = ea->num_channels;

        st->codec->sample_rate = ea->sample_rate;

        st->codec->bits_per_sample = ea->bytes * 8;

        st->codec->bit_rate = st->codec->channels * st->codec->sample_rate *

            st->codec->bits_per_sample / 4;

        st->codec->block_align = st->codec->channels*st->codec->bits_per_sample;

        ea->audio_stream_index = st->index;

        ea->audio_frame_counter = 0;

    }

    return 1;

}


static int ppc_hash32_get_bat(CPUPPCState *env, struct mmu_ctx_hash32 *ctx,

                              target_ulong virtual, int rwx)

{

    target_ulong *BATlt, *BATut;

    target_ulong BEPIl, BEPIu, bl;

    int i, valid, prot;

    int ret = -1;

    LOG_BATS("%s: %cBAT v " TARGET_FMT_lx "\n", __func__,

             rwx == 2 ? 'I' : 'D', virtual);

    if (rwx == 2) {

        BATlt = env->IBAT[1];

        BATut = env->IBAT[0];

    } else {

        BATlt = env->DBAT[1];

        BATut = env->DBAT[0];

    }

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

        target_ulong batu = BATut[i];

        target_ulong batl = BATlt[i];

        BEPIu = batu & BATU32_BEPIU;

        BEPIl = batu & BATU32_BEPIL;

        if (unlikely(env->mmu_model == POWERPC_MMU_601)) {

            hash32_bat_601_size(env, &bl, &valid, batu, batl);

            prot = hash32_bat_601_prot(env, batu, batl);

        } else {

            hash32_bat_size(env, &bl, &valid, batu, batl);

            prot = hash32_bat_prot(env, batu, batl);

        }

        LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx

                 " BATl " TARGET_FMT_lx "\n", __func__,

                 type == ACCESS_CODE ? 'I' : 'D', i, virtual, batu, batl);

        if ((virtual & BATU32_BEPIU) == BEPIu &&

            ((virtual & BATU32_BEPIL) & ~bl) == BEPIl) {

            /* BAT matches */

            if (valid != 0) {

                /* Get physical address */

                ctx->raddr = (batl & BATL32_BRPNU) |

                    ((virtual & BATU32_BEPIL & bl) | (batl & BATL32_BRPNL)) |

                    (virtual & 0x0001F000);

                /* Compute access rights */

                ctx->prot = prot;

                ret = ppc_hash32_check_prot(ctx->prot, rwx);

                if (ret == 0) {

                    LOG_BATS("BAT %d match: r " TARGET_FMT_plx " prot=%c%c\n",

                             i, ctx->raddr, ctx->prot & PAGE_READ ? 'R' : '-',

                             ctx->prot & PAGE_WRITE ? 'W' : '-');

                }

                break;

            }

        }

    }

    if (ret < 0) {

#if defined(DEBUG_BATS)

        if (qemu_log_enabled()) {

            LOG_BATS("no BAT match for " TARGET_FMT_lx ":\n", virtual);

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

                BATu = &BATut[i];

                BATl = &BATlt[i];

                BEPIu = *BATu & BATU32_BEPIU;

                BEPIl = *BATu & BATU32_BEPIL;

                bl = (*BATu & 0x00001FFC) << 15;

                LOG_BATS("%s: %cBAT%d v " TARGET_FMT_lx " BATu " TARGET_FMT_lx

                         " BATl " TARGET_FMT_lx "\n\t" TARGET_FMT_lx " "

                         TARGET_FMT_lx " " TARGET_FMT_lx "\n",

                         __func__, type == ACCESS_CODE ? 'I' : 'D', i, virtual,

                         *BATu, *BATl, BEPIu, BEPIl, bl);

            }

        }

#endif

    }

    /* No hit */

    return ret;

}


static QOSState *qvirtio_scsi_start(const char *extra_opts)

{

    const char *cmd = "-drive id=drv0,if=none,file=/dev/null,format=raw "

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

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

    return qtest_pc_boot(cmd, extra_opts ? : "");

}


int fread_targphys_ok(target_phys_addr_t dst_addr, size_t nbytes, FILE *f)

{

    return fread_targphys(dst_addr, nbytes, f) == nbytes;

}


static int set_format(void *obj, const char *name, int fmt, int search_flags,

                      enum AVOptionType type, const char *desc, int max)

{

    void *target_obj;

    const AVOption *o = av_opt_find2(obj, name, NULL, 0,

                                     search_flags, &target_obj);

    if (!o || !target_obj)

        return AVERROR_OPTION_NOT_FOUND;

    if (o->type != type) {

        av_log(obj, AV_LOG_ERROR,

               "The value set by option '%s' is not a %s format", name, desc);

        return AVERROR(EINVAL);

    }

    if (fmt < -1 || fmt > max) {

        av_log(obj, AV_LOG_ERROR,

               "Value %d for parameter '%s' out of %s format range [-1 - %d]\n",

               fmt, name, desc, max);

        return AVERROR(ERANGE);

    }

    *(int *)(((uint8_t *)target_obj) + o->offset) = fmt;

    return 0;

}


static CharDriverState *qemu_chr_open_stdio(const char *id,

                                            ChardevBackend *backend,

                                            ChardevReturn *ret,

                                            Error **errp)

{

    ChardevStdio *opts = backend->u.stdio.data;

    CharDriverState *chr;

    struct sigaction act;

    ChardevCommon *common = qapi_ChardevStdio_base(opts);

    if (is_daemonized()) {

        error_setg(errp, "cannot use stdio with -daemonize");

    if (stdio_in_use) {

        error_setg(errp, "cannot use stdio by multiple character devices");

    stdio_in_use = true;

    old_fd0_flags = fcntl(0, F_GETFL);

    tcgetattr(0, &oldtty);

    qemu_set_nonblock(0);

    atexit(term_exit);

    memset(&act, 0, sizeof(act));

    act.sa_handler = term_stdio_handler;

    sigaction(SIGCONT, &act, NULL);

    chr = qemu_chr_open_fd(0, 1, common, errp);

    chr->chr_close = qemu_chr_close_stdio;

    chr->chr_set_echo = qemu_chr_set_echo_stdio;

    if (opts->has_signal) {

        stdio_allow_signal = opts->signal;

    qemu_chr_fe_set_echo(chr, false);

    return chr;


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

{

    int ret;

    int nblocks;

    APEContext *ape = s->priv_data;

    uint32_t extra_size = 8;

    if (url_feof(s->pb))

        return AVERROR_EOF;

    if (ape->currentframe >= ape->totalframes)

        return AVERROR_EOF;

    if (avio_seek(s->pb, ape->frames[ape->currentframe].pos, SEEK_SET) < 0)

        return AVERROR(EIO);

    /* Calculate how many blocks there are in this frame */

    if (ape->currentframe == (ape->totalframes - 1))

        nblocks = ape->finalframeblocks;

    else

        nblocks = ape->blocksperframe;

    if (ape->frames[ape->currentframe].size <= 0 ||

        ape->frames[ape->currentframe].size > INT_MAX - extra_size) {

        av_log(s, AV_LOG_ERROR, "invalid packet size: %d\n",

               ape->frames[ape->currentframe].size);

        ape->currentframe++;

        return AVERROR(EIO);

    }

    if (av_new_packet(pkt,  ape->frames[ape->currentframe].size + extra_size) < 0)

        return AVERROR(ENOMEM);

    AV_WL32(pkt->data    , nblocks);

    AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip);

    ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size);

    pkt->pts = ape->frames[ape->currentframe].pts;

    pkt->stream_index = 0;

    /* note: we need to modify the packet size here to handle the last

       packet */

    pkt->size = ret + extra_size;

    ape->currentframe++;

    return 0;

}


static GSList *nvdimm_get_plugged_device_list(void)

{

    GSList *list = NULL;

    object_child_foreach(qdev_get_machine(), nvdimm_plugged_device_list,

                         &list);

    return list;

}


void ide_dma_cancel(BMDMAState *bm)

{

    if (bm->status & BM_STATUS_DMAING) {

        bm->status &= ~BM_STATUS_DMAING;

        /* cancel DMA request */

        bm->unit = -1;

        bm->dma_cb = NULL;

        if (bm->aiocb) {

#ifdef DEBUG_AIO

            printf("aio_cancel\n");

#endif

            bdrv_aio_cancel(bm->aiocb);

            bm->aiocb = NULL;

        }

    }

}


uint64_t helper_fre(CPUPPCState *env, uint64_t arg)

{

    CPU_DoubleU farg;

    farg.ll = arg;

    if (unlikely(float64_is_signaling_nan(farg.d))) {

        /* sNaN reciprocal */

        fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN);

    }

    farg.d = float64_div(float64_one, farg.d, &env->fp_status);

    return farg.d;

}


PCIBus *i440fx_init(PCII440FXState **pi440fx_state,

                    int *piix3_devfn,

                    ISABus **isa_bus, qemu_irq *pic,

                    MemoryRegion *address_space_mem,

                    MemoryRegion *address_space_io,

                    ram_addr_t ram_size,

                    hwaddr pci_hole_start,

                    hwaddr pci_hole_size,

                    hwaddr pci_hole64_start,

                    hwaddr pci_hole64_size,

                    MemoryRegion *pci_address_space,

                    MemoryRegion *ram_memory)

{

    DeviceState *dev;

    PCIBus *b;

    PCIDevice *d;

    PCIHostState *s;

    PIIX3State *piix3;

    PCII440FXState *f;

    unsigned i;

    dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);

    s = PCI_HOST_BRIDGE(dev);

    b = pci_bus_new(dev, NULL, pci_address_space,

                    address_space_io, 0, TYPE_PCI_BUS);

    s->bus = b;

    object_property_add_child(qdev_get_machine(), "i440fx", OBJECT(dev), NULL);

    qdev_init_nofail(dev);

    d = pci_create_simple(b, 0, TYPE_I440FX_PCI_DEVICE);

    *pi440fx_state = I440FX_PCI_DEVICE(d);

    f = *pi440fx_state;

    f->system_memory = address_space_mem;

    f->pci_address_space = pci_address_space;

    f->ram_memory = ram_memory;

    memory_region_init_alias(&f->pci_hole, OBJECT(d), "pci-hole", f->pci_address_space,

                             pci_hole_start, pci_hole_size);

    memory_region_add_subregion(f->system_memory, pci_hole_start, &f->pci_hole);

    memory_region_init_alias(&f->pci_hole_64bit, OBJECT(d), "pci-hole64",

                             f->pci_address_space,

                             pci_hole64_start, pci_hole64_size);

    if (pci_hole64_size) {

        memory_region_add_subregion(f->system_memory, pci_hole64_start,

                                    &f->pci_hole_64bit);

    }

    memory_region_init_alias(&f->smram_region, OBJECT(d), "smram-region",

                             f->pci_address_space, 0xa0000, 0x20000);

    memory_region_add_subregion_overlap(f->system_memory, 0xa0000,

                                        &f->smram_region, 1);

    memory_region_set_enabled(&f->smram_region, false);

    init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,

             &f->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE);

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

        init_pam(dev, f->ram_memory, f->system_memory, f->pci_address_space,

                 &f->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE,

                 PAM_EXPAN_SIZE);

    }

    /* Xen supports additional interrupt routes from the PCI devices to

     * the IOAPIC: the four pins of each PCI device on the bus are also

     * connected to the IOAPIC directly.

     * These additional routes can be discovered through ACPI. */

    if (xen_enabled()) {

        piix3 = DO_UPCAST(PIIX3State, dev,

                pci_create_simple_multifunction(b, -1, true, "PIIX3-xen"));

        pci_bus_irqs(b, xen_piix3_set_irq, xen_pci_slot_get_pirq,

                piix3, XEN_PIIX_NUM_PIRQS);

    } else {

        piix3 = DO_UPCAST(PIIX3State, dev,

                pci_create_simple_multifunction(b, -1, true, "PIIX3"));

        pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3,

                PIIX_NUM_PIRQS);

        pci_bus_set_route_irq_fn(b, piix3_route_intx_pin_to_irq);

    }

    piix3->pic = pic;

    *isa_bus = ISA_BUS(qdev_get_child_bus(DEVICE(piix3), "isa.0"));

    *piix3_devfn = piix3->dev.devfn;

    ram_size = ram_size / 8 / 1024 / 1024;

    if (ram_size > 255) {

        ram_size = 255;

    }

    d->config[0x57] = ram_size;

    i440fx_update_memory_mappings(f);

    return b;

}


static int virtio_rng_device_exit(DeviceState *qdev)

{

    VirtIORNG *vrng = VIRTIO_RNG(qdev);

    VirtIODevice *vdev = VIRTIO_DEVICE(qdev);

    timer_del(vrng->rate_limit_timer);

    timer_free(vrng->rate_limit_timer);

    unregister_savevm(qdev, "virtio-rng", vrng);

    virtio_cleanup(vdev);

    return 0;

}


static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame)

{

    SVQ1Context *s = avctx->priv_data;

    GetBitContext *bitbuf = &s->gb;

    int frame_size_code;

    int width  = s->width;

    int height = s->height;

    skip_bits(bitbuf, 8); /* temporal_reference */

    /* frame type */

    s->nonref = 0;

    switch (get_bits(bitbuf, 2)) {

    case 0:

        frame->pict_type = AV_PICTURE_TYPE_I;

        break;

    case 2:

        s->nonref = 1;

    case 1:

        frame->pict_type = AV_PICTURE_TYPE_P;

        break;

    default:

        av_log(avctx, AV_LOG_ERROR, "Invalid frame type.\n");

        return AVERROR_INVALIDDATA;

    }

    if (frame->pict_type == AV_PICTURE_TYPE_I) {

        /* unknown fields */

        if (s->frame_code == 0x50 || s->frame_code == 0x60) {

            int csum = get_bits(bitbuf, 16);

            csum = ff_svq1_packet_checksum(bitbuf->buffer,

                                           bitbuf->size_in_bits >> 3,

                                           csum);

            av_dlog(avctx, "%s checksum (%02x) for packet data\n",

                    (csum == 0) ? "correct" : "incorrect", csum);

        }

        if ((s->frame_code ^ 0x10) >= 0x50) {

            uint8_t msg[256];

            svq1_parse_string(bitbuf, msg);

            av_log(avctx, AV_LOG_INFO,

                   "embedded message:\n%s\n", (char *)msg);

        }

        skip_bits(bitbuf, 2);

        skip_bits(bitbuf, 2);

        skip_bits1(bitbuf);

        /* load frame size */

        frame_size_code = get_bits(bitbuf, 3);

        if (frame_size_code == 7) {

            /* load width, height (12 bits each) */

            width  = get_bits(bitbuf, 12);

            height = get_bits(bitbuf, 12);

            if (!width || !height)

                return AVERROR_INVALIDDATA;

        } else {

            /* get width, height from table */

            width  = ff_svq1_frame_size_table[frame_size_code][0];

            height = ff_svq1_frame_size_table[frame_size_code][1];

        }

    }

    /* unknown fields */

    if (get_bits1(bitbuf)) {

        skip_bits1(bitbuf);    /* use packet checksum if (1) */

        skip_bits1(bitbuf);    /* component checksums after image data if (1) */

        if (get_bits(bitbuf, 2) != 0)

            return AVERROR_INVALIDDATA;

    }

    if (get_bits1(bitbuf)) {

        skip_bits1(bitbuf);

        skip_bits(bitbuf, 4);

        skip_bits1(bitbuf);

        skip_bits(bitbuf, 2);

        if (skip_1stop_8data_bits(bitbuf) < 0)

            return AVERROR_INVALIDDATA;

    }

    s->width  = width;

    s->height = height;

    return 0;

}


static struct pathelem *add_entry(struct pathelem *root, const char *name,

                                  unsigned type)

{

    struct pathelem **e;

    root->num_entries++;

    root = realloc(root, sizeof(*root)

                   + sizeof(root->entries[0])*root->num_entries);

    e = &root->entries[root->num_entries-1];

    *e = new_entry(root->pathname, root, name);

    if (is_dir_maybe(type)) {

        *e = add_dir_maybe(*e);

    }

    return root;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    dc->exit = virtio_balloon_device_exit;

    dc->props = virtio_balloon_properties;

    set_bit(DEVICE_CATEGORY_MISC, dc->categories);

    vdc->init = virtio_balloon_device_init;

    vdc->get_config = virtio_balloon_get_config;

    vdc->set_config = virtio_balloon_set_config;

    vdc->get_features = virtio_balloon_get_features;

}


static KeyValue *copy_key_value(KeyValue *src)

{

    KeyValue *dst = g_new(KeyValue, 1);

    memcpy(dst, src, sizeof(*src));

    return dst;


target_ulong helper_sub_suov(CPUTriCoreState *env, target_ulong r1,

                             target_ulong r2)

{

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

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

    int64_t result = t1 - t2;

    return suov32(env, result);

}


static uint64_t icp_pit_read(void *opaque, target_phys_addr_t offset,

                             unsigned size)

{

    icp_pit_state *s = (icp_pit_state *)opaque;

    int n;

    /* ??? Don't know the PrimeCell ID for this device.  */

    n = offset >> 8;

    if (n > 2) {

        hw_error("%s: Bad timer %d\n", __func__, n);

    }

    return arm_timer_read(s->timer[n], offset & 0xff);

}


static void v9fs_synth_direntry(V9fsSynthNode *node,

                                struct dirent *entry, off_t off)

{

    strcpy(entry->d_name, node->name);

    entry->d_ino = node->attr->inode;

    entry->d_off = off + 1;

}


static void gen_nop_hint(DisasContext *s, int val)

{

    switch (val) {

    case 1: /* yield */

        if (!parallel_cpus) {

            gen_set_pc_im(s, s->pc);

            s->base.is_jmp = DISAS_YIELD;

        }

        break;

    case 3: /* wfi */

        gen_set_pc_im(s, s->pc);

        s->base.is_jmp = DISAS_WFI;

        break;

    case 2: /* wfe */

        if (!parallel_cpus) {

            gen_set_pc_im(s, s->pc);

            s->base.is_jmp = DISAS_WFE;

        }

        break;

    case 4: /* sev */

    case 5: /* sevl */

        /* TODO: Implement SEV, SEVL and WFE.  May help SMP performance.  */

    default: /* nop */

        break;

    }

}


static void vnc_dpy_setdata(DisplayState *ds)

{

    /* We don't have to do anything */

}


static int64_t ftp_seek(URLContext *h, int64_t pos, int whence)

{

    FTPContext *s = h->priv_data;

    int err;

    int64_t new_pos, fake_pos;

    av_dlog(h, "ftp protocol seek %"PRId64" %d\n", pos, whence);

    switch(whence) {

    case AVSEEK_SIZE:

        return s->filesize;

    case SEEK_SET:

        new_pos = pos;

        break;

    case SEEK_CUR:

        new_pos = s->position + pos;

        break;

    case SEEK_END:

        if (s->filesize < 0)

            return AVERROR(EIO);

        new_pos = s->filesize + pos;

        break;

    default:

        return AVERROR(EINVAL);

    }

    if (h->is_streamed)

        return AVERROR(EIO);

    if (new_pos < 0) {

        av_log(h, AV_LOG_ERROR, "Seeking to nagative position.\n");

        return AVERROR(EINVAL);

    }

    fake_pos = s->filesize != -1 ? FFMIN(new_pos, s->filesize) : new_pos;

    if (fake_pos != s->position) {

        if ((err = ftp_abort(h)) < 0)

            return err;

        s->position = fake_pos;

    }

    return new_pos;

}


struct vhost_net *vhost_net_init(NetClientState *backend, int devfd,

                                 bool force)

{

    int r;

    struct vhost_net *net = g_malloc(sizeof *net);

    if (!backend) {

        fprintf(stderr, "vhost-net requires backend to be setup\n");

        goto fail;

    }

    r = vhost_net_get_fd(backend);

    if (r < 0) {

        goto fail;

    }

    net->nc = backend;

    net->dev.backend_features = tap_has_vnet_hdr(backend) ? 0 :

        (1 << VHOST_NET_F_VIRTIO_NET_HDR);

    net->backend = r;

    net->dev.nvqs = 2;

    net->dev.vqs = net->vqs;

    r = vhost_dev_init(&net->dev, devfd, "/dev/vhost-net", force);

    if (r < 0) {

        goto fail;

    }

    if (!tap_has_vnet_hdr_len(backend,

                              sizeof(struct virtio_net_hdr_mrg_rxbuf))) {

        net->dev.features &= ~(1 << VIRTIO_NET_F_MRG_RXBUF);

    }

    if (~net->dev.features & net->dev.backend_features) {

        fprintf(stderr, "vhost lacks feature mask %" PRIu64 " for backend\n",

                (uint64_t)(~net->dev.features & net->dev.backend_features));

        vhost_dev_cleanup(&net->dev);

        goto fail;

    }

    /* Set sane init value. Override when guest acks. */

    vhost_net_ack_features(net, 0);

    return net;

fail:

    g_free(net);

    return NULL;

}


static int encode_superframe(AVCodecContext *avctx, AVPacket *avpkt,

                             const AVFrame *frame, int *got_packet_ptr)

{

    WMACodecContext *s = avctx->priv_data;

    int i, total_gain, ret, error;

    s->block_len_bits= s->frame_len_bits; //required by non variable block len

    s->block_len = 1 << s->block_len_bits;

    apply_window_and_mdct(avctx, frame);

    if (s->ms_stereo) {

        float a, b;

        int i;

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

            a = s->coefs[0][i]*0.5;

            b = s->coefs[1][i]*0.5;

            s->coefs[0][i] = a + b;

            s->coefs[1][i] = a - b;

        }

    }

    if ((ret = ff_alloc_packet2(avctx, avpkt, 2 * MAX_CODED_SUPERFRAME_SIZE)))

        return ret;

    total_gain= 128;

    for(i=64; i; i>>=1){

        error = encode_frame(s, s->coefs, avpkt->data, avpkt->size,

                                 total_gain - i);

        if(error<=0)

            total_gain-= i;

    }

    while(total_gain <= 128 && error > 0)

        error = encode_frame(s, s->coefs, avpkt->data, avpkt->size, total_gain++);

    av_assert0((put_bits_count(&s->pb) & 7) == 0);

    i= avctx->block_align - (put_bits_count(&s->pb)+7)/8;

    av_assert0(i>=0);

    while(i--)

        put_bits(&s->pb, 8, 'N');

    flush_put_bits(&s->pb);

    av_assert0(put_bits_ptr(&s->pb) - s->pb.buf == avctx->block_align);

    if (frame->pts != AV_NOPTS_VALUE)

        avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);

    avpkt->size = avctx->block_align;

    *got_packet_ptr = 1;

    return 0;

}


static int qcow_create(const char *filename, int64_t total_size,

                      const char *backing_file, int flags)

{

    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;

    QCowHeader header;

    uint64_t tmp, offset;

    QCowCreateState s1, *s = &s1;

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

    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);

    if (fd < 0)

        return -1;

    memset(&header, 0, sizeof(header));

    header.magic = cpu_to_be32(QCOW_MAGIC);

    header.version = cpu_to_be32(QCOW_VERSION);

    header.size = cpu_to_be64(total_size * 512);

    header_size = sizeof(header);

    backing_filename_len = 0;

    if (backing_file) {

        header.backing_file_offset = cpu_to_be64(header_size);

        backing_filename_len = strlen(backing_file);

        header.backing_file_size = cpu_to_be32(backing_filename_len);

        header_size += backing_filename_len;

    }

    s->cluster_bits = 12;  /* 4 KB clusters */

    s->cluster_size = 1 << s->cluster_bits;

    header.cluster_bits = cpu_to_be32(s->cluster_bits);

    header_size = (header_size + 7) & ~7;

    if (flags & BLOCK_FLAG_ENCRYPT) {

        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);

    } else {

        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);

    }

    l2_bits = s->cluster_bits - 3;

    shift = s->cluster_bits + l2_bits;

    l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);

    offset = align_offset(header_size, s->cluster_size);

    s->l1_table_offset = offset;

    header.l1_table_offset = cpu_to_be64(s->l1_table_offset);

    header.l1_size = cpu_to_be32(l1_size);

    offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);

    s->refcount_table = qemu_mallocz(s->cluster_size);

    s->refcount_block = qemu_mallocz(s->cluster_size);

    s->refcount_table_offset = offset;

    header.refcount_table_offset = cpu_to_be64(offset);

    header.refcount_table_clusters = cpu_to_be32(1);

    offset += s->cluster_size;

    s->refcount_table[0] = cpu_to_be64(offset);

    s->refcount_block_offset = offset;

    offset += s->cluster_size;

    /* update refcounts */

    create_refcount_update(s, 0, header_size);

    create_refcount_update(s, s->l1_table_offset, l1_size * sizeof(uint64_t));

    create_refcount_update(s, s->refcount_table_offset, s->cluster_size);

    create_refcount_update(s, s->refcount_block_offset, s->cluster_size);

    /* write all the data */

    write(fd, &header, sizeof(header));

    if (backing_file) {

        write(fd, backing_file, backing_filename_len);

    }

    lseek(fd, s->l1_table_offset, SEEK_SET);

    tmp = 0;

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

        write(fd, &tmp, sizeof(tmp));

    }

    lseek(fd, s->refcount_table_offset, SEEK_SET);

    write(fd, s->refcount_table, s->cluster_size);

    lseek(fd, s->refcount_block_offset, SEEK_SET);

    write(fd, s->refcount_block, s->cluster_size);

    qemu_free(s->refcount_table);

    qemu_free(s->refcount_block);

    close(fd);

    return 0;

}


static void scsi_read_data(SCSIRequest *req)

{

    SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);

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

    uint32_t n;

    if (r->sector_count == (uint32_t)-1) {

        DPRINTF("Read buf_len=%zd\n", r->iov.iov_len);

        r->sector_count = 0;

        scsi_req_data(&r->req, r->iov.iov_len);

        return;

    }

    DPRINTF("Read sector_count=%d\n", r->sector_count);

    if (r->sector_count == 0) {

        scsi_command_complete(r, GOOD, NO_SENSE);

        return;

    }

    /* No data transfer may already be in progress */

    assert(r->req.aiocb == NULL);

    n = r->sector_count;

    if (n > SCSI_DMA_BUF_SIZE / 512)

        n = SCSI_DMA_BUF_SIZE / 512;

    r->iov.iov_len = n * 512;

    qemu_iovec_init_external(&r->qiov, &r->iov, 1);

    r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n,

                              scsi_read_complete, r);

    if (r->req.aiocb == NULL) {

        scsi_read_complete(r, -EIO);

    }

}


static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
                             const char *replaces,
                             int64_t speed, uint32_t granularity,
                             int64_t buf_size,
                             BlockdevOnError on_source_error,
                             BlockdevOnError on_target_error,
                             bool unmap,
                             BlockCompletionFunc *cb,
                             void *opaque, Error **errp,
                             const BlockJobDriver *driver,
                             bool is_none_mode, BlockDriverState *base)
{
    MirrorBlockJob *s;
    BlockDriverState *replaced_bs;
    if (granularity == 0) {
        granularity = bdrv_get_default_bitmap_granularity(target);
    assert ((granularity & (granularity - 1)) == 0);
    if ((on_source_error == BLOCKDEV_ON_ERROR_STOP ||
         on_source_error == BLOCKDEV_ON_ERROR_ENOSPC) &&
        (!bs->blk || !blk_iostatus_is_enabled(bs->blk))) {
        error_setg(errp, QERR_INVALID_PARAMETER, "on-source-error");
    if (buf_size < 0) {
        error_setg(errp, "Invalid parameter 'buf-size'");
    if (buf_size == 0) {
        buf_size = DEFAULT_MIRROR_BUF_SIZE;
    s = block_job_create(driver, bs, speed, cb, opaque, errp);
    if (!s) {
    s->replaces = g_strdup(replaces);
    s->on_source_error = on_source_error;
    s->on_target_error = on_target_error;
    s->target = target;
    s->is_none_mode = is_none_mode;
    s->base = base;
    s->granularity = granularity;
    s->buf_size = ROUND_UP(buf_size, granularity);
    s->unmap = unmap;
    s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
    if (!s->dirty_bitmap) {
        g_free(s->replaces);
        block_job_unref(&s->common);
    bdrv_op_block_all(s->target, s->common.blocker);
    bdrv_set_enable_write_cache(s->target, true);
    if (s->target->blk) {
        blk_set_on_error(s->target->blk, on_target_error, on_target_error);
        blk_iostatus_enable(s->target->blk);
    s->common.co = qemu_coroutine_create(mirror_run);
    trace_mirror_start(bs, s, s->common.co, opaque);
    qemu_coroutine_enter(s->common.co, s);


static void qemu_kvm_start_vcpu(CPUState *env)

{

    env->thread = g_malloc0(sizeof(QemuThread));

    env->halt_cond = g_malloc0(sizeof(QemuCond));

    qemu_cond_init(env->halt_cond);

    qemu_thread_create(env->thread, qemu_kvm_cpu_thread_fn, env,

                       QEMU_THREAD_DETACHED);

    while (env->created == 0) {

        qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);

    }

}


static MemTxResult address_space_write_continue(AddressSpace *as, hwaddr addr,

                                                MemTxAttrs attrs,

                                                const uint8_t *buf,

                                                int len, hwaddr addr1,

                                                hwaddr l, MemoryRegion *mr)

{

    uint8_t *ptr;

    uint64_t val;

    MemTxResult result = MEMTX_OK;

    bool release_lock = false;

    for (;;) {

        if (!memory_access_is_direct(mr, true)) {

            release_lock |= prepare_mmio_access(mr);

            l = memory_access_size(mr, l, addr1);

            /* XXX: could force current_cpu to NULL to avoid

               potential bugs */

            switch (l) {

            case 8:

                /* 64 bit write access */

                val = ldq_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 8,

                                                       attrs);

                break;

            case 4:

                /* 32 bit write access */

                val = (uint32_t)ldl_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 4,

                                                       attrs);

                break;

            case 2:

                /* 16 bit write access */

                val = lduw_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 2,

                                                       attrs);

                break;

            case 1:

                /* 8 bit write access */

                val = ldub_p(buf);

                result |= memory_region_dispatch_write(mr, addr1, val, 1,

                                                       attrs);

                break;

            default:

                abort();

            }

        } else {

            /* RAM case */

            ptr = qemu_map_ram_ptr(mr->ram_block, addr1);

            memcpy(ptr, buf, l);

            invalidate_and_set_dirty(mr, addr1, l);

        }

        if (release_lock) {

            qemu_mutex_unlock_iothread();

            release_lock = false;

        }

        len -= l;

        buf += l;

        addr += l;

        if (!len) {

            break;

        }

        l = len;

        mr = address_space_translate(as, addr, &addr1, &l, true);

    }

    return result;

}


static int g729_parse(AVCodecParserContext *s1, AVCodecContext *avctx,

                     const uint8_t **poutbuf, int *poutbuf_size,

                     const uint8_t *buf, int buf_size)

{

    G729ParseContext *s = s1->priv_data;

    ParseContext *pc = &s->pc;

    int next;

    if (!s->block_size) {

        switch (avctx->codec_id) {

        case AV_CODEC_ID_G729:

            /* FIXME: replace this heuristic block_size with more precise estimate */

            s->block_size = (avctx->bit_rate < 8000) ? G729D_6K4_BLOCK_SIZE : G729_8K_BLOCK_SIZE;

            s->duration   = avctx->frame_size;

            break;

        default:

            *poutbuf      = buf;

            *poutbuf_size = buf_size;

            av_log(avctx, AV_LOG_ERROR, "Invalid codec_id\n");

            return buf_size;

        }

    }

    if (!s->remaining)

        s->remaining = s->block_size;

    if (s->remaining <= buf_size) {

        next = s->remaining;

        s->remaining = 0;

    } else {

        next = END_NOT_FOUND;

        s->remaining -= buf_size;

    }

    if (ff_combine_frame(pc, next, &buf, &buf_size) < 0 || !buf_size) {

        *poutbuf      = NULL;

        *poutbuf_size = 0;

        return buf_size;

    }

    s1->duration = s->duration;

    *poutbuf      = buf;

    *poutbuf_size = buf_size;

    return next;

}


static uint64_t timerblock_read(void *opaque, target_phys_addr_t addr,

                                unsigned size)

{

    timerblock *tb = (timerblock *)opaque;

    int64_t val;

    switch (addr) {

    case 0: /* Load */

        return tb->load;

    case 4: /* Counter.  */

        if (((tb->control & 1) == 0) || (tb->count == 0)) {

            return 0;

        }

        /* Slow and ugly, but hopefully won't happen too often.  */

        val = tb->tick - qemu_get_clock_ns(vm_clock);

        val /= timerblock_scale(tb);

        if (val < 0) {

            val = 0;

        }

        return val;

    case 8: /* Control.  */

        return tb->control;

    case 12: /* Interrupt status.  */

        return tb->status;

    default:

        return 0;

    }

}


static int decode_audio_block(AC3DecodeContext *s, int blk)

{

    int fbw_channels = s->fbw_channels;

    int channel_mode = s->channel_mode;

    int i, bnd, seg, ch;

    int different_transforms;

    int downmix_output;

    int cpl_in_use;

    GetBitContext *gbc = &s->gbc;

    uint8_t bit_alloc_stages[AC3_MAX_CHANNELS];

    memset(bit_alloc_stages, 0, AC3_MAX_CHANNELS);

    /* block switch flags */

    different_transforms = 0;

    if (s->block_switch_syntax) {

        for (ch = 1; ch <= fbw_channels; ch++) {

            s->block_switch[ch] = get_bits1(gbc);

            if(ch > 1 && s->block_switch[ch] != s->block_switch[1])

                different_transforms = 1;

        }

    }

    /* dithering flags */

    if (s->dither_flag_syntax) {

        for (ch = 1; ch <= fbw_channels; ch++) {

            s->dither_flag[ch] = get_bits1(gbc);

        }

    }

    /* dynamic range */

    i = !(s->channel_mode);

    do {

        if(get_bits1(gbc)) {

            s->dynamic_range[i] = ((dynamic_range_tab[get_bits(gbc, 8)]-1.0) *

                                  s->avctx->drc_scale)+1.0;

        } else if(blk == 0) {

            s->dynamic_range[i] = 1.0f;

        }

    } while(i--);

    /* spectral extension strategy */

    if (s->eac3 && (!blk || get_bits1(gbc))) {

        if (get_bits1(gbc)) {

            av_log_missing_feature(s->avctx, "Spectral extension", 1);

            return -1;

        }

        /* TODO: parse spectral extension strategy info */

    }

    /* TODO: spectral extension coordinates */

    /* coupling strategy */

    if (s->eac3 ? s->cpl_strategy_exists[blk] : get_bits1(gbc)) {

        memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);

        if (!s->eac3)

            s->cpl_in_use[blk] = get_bits1(gbc);

        if (s->cpl_in_use[blk]) {

            /* coupling in use */

            int cpl_start_subband, cpl_end_subband;

            if (channel_mode < AC3_CHMODE_STEREO) {

                av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n");

                return -1;

            }

            /* check for enhanced coupling */

            if (s->eac3 && get_bits1(gbc)) {

                /* TODO: parse enhanced coupling strategy info */

                av_log_missing_feature(s->avctx, "Enhanced coupling", 1);

                return -1;

            }

            /* determine which channels are coupled */

            if (s->eac3 && s->channel_mode == AC3_CHMODE_STEREO) {

                s->channel_in_cpl[1] = 1;

                s->channel_in_cpl[2] = 1;

            } else {

                for (ch = 1; ch <= fbw_channels; ch++)

                    s->channel_in_cpl[ch] = get_bits1(gbc);

            }

            /* phase flags in use */

            if (channel_mode == AC3_CHMODE_STEREO)

                s->phase_flags_in_use = get_bits1(gbc);

            /* coupling frequency range */

            /* TODO: modify coupling end freq if spectral extension is used */

            cpl_start_subband = get_bits(gbc, 4);

            cpl_end_subband   = get_bits(gbc, 4) + 3;

            s->num_cpl_subbands = cpl_end_subband - cpl_start_subband;

            if (s->num_cpl_subbands < 0) {

                av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d > %d)\n",

                       cpl_start_subband, cpl_end_subband);

                return -1;

            }

            s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37;

            s->end_freq[CPL_CH]   = cpl_end_subband   * 12 + 37;

           decode_band_structure(gbc, blk, s->eac3, 0,

                                 cpl_start_subband, cpl_end_subband,

                                 ff_eac3_default_cpl_band_struct,

                                 s->cpl_band_struct, &s->num_cpl_subbands,

                                 &s->num_cpl_bands, NULL);

        } else {

            /* coupling not in use */

            for (ch = 1; ch <= fbw_channels; ch++) {

                s->channel_in_cpl[ch] = 0;

                s->first_cpl_coords[ch] = 1;

            }

            s->first_cpl_leak = s->eac3;

            s->phase_flags_in_use = 0;

        }

    } else if (!s->eac3) {

        if(!blk) {

            av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must be present in block 0\n");

            return -1;

        } else {

            s->cpl_in_use[blk] = s->cpl_in_use[blk-1];

        }

    }

    cpl_in_use = s->cpl_in_use[blk];

    /* coupling coordinates */

    if (cpl_in_use) {

        int cpl_coords_exist = 0;

        for (ch = 1; ch <= fbw_channels; ch++) {

            if (s->channel_in_cpl[ch]) {

                if ((s->eac3 && s->first_cpl_coords[ch]) || get_bits1(gbc)) {

                    int master_cpl_coord, cpl_coord_exp, cpl_coord_mant;

                    s->first_cpl_coords[ch] = 0;

                    cpl_coords_exist = 1;

                    master_cpl_coord = 3 * get_bits(gbc, 2);

                    for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {

                        cpl_coord_exp = get_bits(gbc, 4);

                        cpl_coord_mant = get_bits(gbc, 4);

                        if (cpl_coord_exp == 15)

                            s->cpl_coords[ch][bnd] = cpl_coord_mant << 22;

                        else

                            s->cpl_coords[ch][bnd] = (cpl_coord_mant + 16) << 21;

                        s->cpl_coords[ch][bnd] >>= (cpl_coord_exp + master_cpl_coord);

                    }

                } else if (!blk) {

                    av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must be present in block 0\n");

                    return -1;

                }

            } else {

                /* channel not in coupling */

                s->first_cpl_coords[ch] = 1;

            }

        }

        /* phase flags */

        if (channel_mode == AC3_CHMODE_STEREO && cpl_coords_exist) {

            for (bnd = 0; bnd < s->num_cpl_bands; bnd++) {

                s->phase_flags[bnd] = s->phase_flags_in_use? get_bits1(gbc) : 0;

            }

        }

    }

    /* stereo rematrixing strategy and band structure */

    if (channel_mode == AC3_CHMODE_STEREO) {

        if ((s->eac3 && !blk) || get_bits1(gbc)) {

            s->num_rematrixing_bands = 4;

            if(cpl_in_use && s->start_freq[CPL_CH] <= 61)

                s->num_rematrixing_bands -= 1 + (s->start_freq[CPL_CH] == 37);

            for(bnd=0; bnd<s->num_rematrixing_bands; bnd++)

                s->rematrixing_flags[bnd] = get_bits1(gbc);

        } else if (!blk) {

            av_log(s->avctx, AV_LOG_ERROR, "new rematrixing strategy must be present in block 0\n");

            return -1;

        }

    }

    /* exponent strategies for each channel */

    for (ch = !cpl_in_use; ch <= s->channels; ch++) {

        if (!s->eac3)

            s->exp_strategy[blk][ch] = get_bits(gbc, 2 - (ch == s->lfe_ch));

        if(s->exp_strategy[blk][ch] != EXP_REUSE)

            bit_alloc_stages[ch] = 3;

    }

    /* channel bandwidth */

    for (ch = 1; ch <= fbw_channels; ch++) {

        s->start_freq[ch] = 0;

        if (s->exp_strategy[blk][ch] != EXP_REUSE) {

            int group_size;

            int prev = s->end_freq[ch];

            if (s->channel_in_cpl[ch])

                s->end_freq[ch] = s->start_freq[CPL_CH];

            else {

                int bandwidth_code = get_bits(gbc, 6);

                if (bandwidth_code > 60) {

                    av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code);

                    return -1;

                }

                s->end_freq[ch] = bandwidth_code * 3 + 73;

            }

            group_size = 3 << (s->exp_strategy[blk][ch] - 1);

            s->num_exp_groups[ch] = (s->end_freq[ch]+group_size-4) / group_size;

            if(blk > 0 && s->end_freq[ch] != prev)

                memset(bit_alloc_stages, 3, AC3_MAX_CHANNELS);

        }

    }

    if (cpl_in_use && s->exp_strategy[blk][CPL_CH] != EXP_REUSE) {

        s->num_exp_groups[CPL_CH] = (s->end_freq[CPL_CH] - s->start_freq[CPL_CH]) /

                                    (3 << (s->exp_strategy[blk][CPL_CH] - 1));

    }

    /* decode exponents for each channel */

    for (ch = !cpl_in_use; ch <= s->channels; ch++) {

        if (s->exp_strategy[blk][ch] != EXP_REUSE) {

            s->dexps[ch][0] = get_bits(gbc, 4) << !ch;

            if (decode_exponents(gbc, s->exp_strategy[blk][ch],

                                 s->num_exp_groups[ch], s->dexps[ch][0],

                                 &s->dexps[ch][s->start_freq[ch]+!!ch])) {

                av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n");

                return -1;

            }

            if(ch != CPL_CH && ch != s->lfe_ch)

                skip_bits(gbc, 2); /* skip gainrng */

        }

    }

    /* bit allocation information */

    if (s->bit_allocation_syntax) {

        if (get_bits1(gbc)) {

            s->bit_alloc_params.slow_decay = ff_ac3_slow_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;

            s->bit_alloc_params.fast_decay = ff_ac3_fast_decay_tab[get_bits(gbc, 2)] >> s->bit_alloc_params.sr_shift;

            s->bit_alloc_params.slow_gain  = ff_ac3_slow_gain_tab[get_bits(gbc, 2)];

            s->bit_alloc_params.db_per_bit = ff_ac3_db_per_bit_tab[get_bits(gbc, 2)];

            s->bit_alloc_params.floor  = ff_ac3_floor_tab[get_bits(gbc, 3)];

            for(ch=!cpl_in_use; ch<=s->channels; ch++)

                bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);

        } else if (!blk) {

            av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must be present in block 0\n");

            return -1;

        }

    }

    /* signal-to-noise ratio offsets and fast gains (signal-to-mask ratios) */

    if(!s->eac3 || !blk){

        if(s->snr_offset_strategy && get_bits1(gbc)) {

            int snr = 0;

            int csnr;

            csnr = (get_bits(gbc, 6) - 15) << 4;

            for (i = ch = !cpl_in_use; ch <= s->channels; ch++) {

                /* snr offset */

                if (ch == i || s->snr_offset_strategy == 2)

                    snr = (csnr + get_bits(gbc, 4)) << 2;

                /* run at least last bit allocation stage if snr offset changes */

                if(blk && s->snr_offset[ch] != snr) {

                    bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 1);

                }

                s->snr_offset[ch] = snr;

                /* fast gain (normal AC-3 only) */

                if (!s->eac3) {

                    int prev = s->fast_gain[ch];

                    s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];

                    /* run last 2 bit allocation stages if fast gain changes */

                    if(blk && prev != s->fast_gain[ch])

                        bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);

                }

            }

        } else if (!s->eac3 && !blk) {

            av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n");

            return -1;

        }

    }

    /* fast gain (E-AC-3 only) */

    if (s->fast_gain_syntax && get_bits1(gbc)) {

        for (ch = !cpl_in_use; ch <= s->channels; ch++) {

            int prev = s->fast_gain[ch];

            s->fast_gain[ch] = ff_ac3_fast_gain_tab[get_bits(gbc, 3)];

            /* run last 2 bit allocation stages if fast gain changes */

            if(blk && prev != s->fast_gain[ch])

                bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);

        }

    } else if (s->eac3 && !blk) {

        for (ch = !cpl_in_use; ch <= s->channels; ch++)

            s->fast_gain[ch] = ff_ac3_fast_gain_tab[4];

    }

    /* E-AC-3 to AC-3 converter SNR offset */

    if (s->frame_type == EAC3_FRAME_TYPE_INDEPENDENT && get_bits1(gbc)) {

        skip_bits(gbc, 10); // skip converter snr offset

    }

    /* coupling leak information */

    if (cpl_in_use) {

        if (s->first_cpl_leak || get_bits1(gbc)) {

            int fl = get_bits(gbc, 3);

            int sl = get_bits(gbc, 3);

            /* run last 2 bit allocation stages for coupling channel if

               coupling leak changes */

            if(blk && (fl != s->bit_alloc_params.cpl_fast_leak ||

                       sl != s->bit_alloc_params.cpl_slow_leak)) {

                bit_alloc_stages[CPL_CH] = FFMAX(bit_alloc_stages[CPL_CH], 2);

            }

            s->bit_alloc_params.cpl_fast_leak = fl;

            s->bit_alloc_params.cpl_slow_leak = sl;

        } else if (!s->eac3 && !blk) {

            av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must be present in block 0\n");

            return -1;

        }

        s->first_cpl_leak = 0;

    }

    /* delta bit allocation information */

    if (s->dba_syntax && get_bits1(gbc)) {

        /* delta bit allocation exists (strategy) */

        for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {

            s->dba_mode[ch] = get_bits(gbc, 2);

            if (s->dba_mode[ch] == DBA_RESERVED) {

                av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n");

                return -1;

            }

            bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);

        }

        /* channel delta offset, len and bit allocation */

        for (ch = !cpl_in_use; ch <= fbw_channels; ch++) {

            if (s->dba_mode[ch] == DBA_NEW) {

                s->dba_nsegs[ch] = get_bits(gbc, 3);

                for (seg = 0; seg <= s->dba_nsegs[ch]; seg++) {

                    s->dba_offsets[ch][seg] = get_bits(gbc, 5);

                    s->dba_lengths[ch][seg] = get_bits(gbc, 4);

                    s->dba_values[ch][seg] = get_bits(gbc, 3);

                }

                /* run last 2 bit allocation stages if new dba values */

                bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2);

            }

        }

    } else if(blk == 0) {

        for(ch=0; ch<=s->channels; ch++) {

            s->dba_mode[ch] = DBA_NONE;

        }

    }

    /* Bit allocation */

    for(ch=!cpl_in_use; ch<=s->channels; ch++) {

        if(bit_alloc_stages[ch] > 2) {

            /* Exponent mapping into PSD and PSD integration */

            ff_ac3_bit_alloc_calc_psd(s->dexps[ch],

                                      s->start_freq[ch], s->end_freq[ch],

                                      s->psd[ch], s->band_psd[ch]);

        }

        if(bit_alloc_stages[ch] > 1) {

            /* Compute excitation function, Compute masking curve, and

               Apply delta bit allocation */

            ff_ac3_bit_alloc_calc_mask(&s->bit_alloc_params, s->band_psd[ch],

                                       s->start_freq[ch], s->end_freq[ch],

                                       s->fast_gain[ch], (ch == s->lfe_ch),

                                       s->dba_mode[ch], s->dba_nsegs[ch],

                                       s->dba_offsets[ch], s->dba_lengths[ch],

                                       s->dba_values[ch], s->mask[ch]);

        }

        if(bit_alloc_stages[ch] > 0) {

            /* Compute bit allocation */

            const uint8_t *bap_tab = s->channel_uses_aht[ch] ?

                                     ff_eac3_hebap_tab : ff_ac3_bap_tab;

            ff_ac3_bit_alloc_calc_bap(s->mask[ch], s->psd[ch],

                                      s->start_freq[ch], s->end_freq[ch],

                                      s->snr_offset[ch],

                                      s->bit_alloc_params.floor,

                                      bap_tab, s->bap[ch]);

        }

    }

    /* unused dummy data */

    if (s->skip_syntax && get_bits1(gbc)) {

        int skipl = get_bits(gbc, 9);

        while(skipl--)

            skip_bits(gbc, 8);

    }

    /* unpack the transform coefficients

       this also uncouples channels if coupling is in use. */

    decode_transform_coeffs(s, blk);

    /* TODO: generate enhanced coupling coordinates and uncouple */

    /* TODO: apply spectral extension */

    /* recover coefficients if rematrixing is in use */

    if(s->channel_mode == AC3_CHMODE_STEREO)

        do_rematrixing(s);

    /* apply scaling to coefficients (headroom, dynrng) */

    for(ch=1; ch<=s->channels; ch++) {

        float gain = s->mul_bias / 4194304.0f;

        if(s->channel_mode == AC3_CHMODE_DUALMONO) {

            gain *= s->dynamic_range[ch-1];

        } else {

            gain *= s->dynamic_range[0];

        }

        s->dsp.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256);

    }

    /* downmix and MDCT. order depends on whether block switching is used for

       any channel in this block. this is because coefficients for the long

       and short transforms cannot be mixed. */

    downmix_output = s->channels != s->out_channels &&

                     !((s->output_mode & AC3_OUTPUT_LFEON) &&

                     s->fbw_channels == s->out_channels);

    if(different_transforms) {

        /* the delay samples have already been downmixed, so we upmix the delay

           samples in order to reconstruct all channels before downmixing. */

        if(s->downmixed) {

            s->downmixed = 0;

            ac3_upmix_delay(s);

        }

        do_imdct(s, s->channels);

        if(downmix_output) {

            s->dsp.ac3_downmix(s->output, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256);

        }

    } else {

        if(downmix_output) {

            s->dsp.ac3_downmix(s->transform_coeffs+1, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256);

        }

        if(downmix_output && !s->downmixed) {

            s->downmixed = 1;

            s->dsp.ac3_downmix(s->delay, s->downmix_coeffs, s->out_channels, s->fbw_channels, 128);

        }

        do_imdct(s, s->out_channels);

    }

    return 0;

}


setup_return(CPUARMState *env, struct target_sigaction *ka,

	     abi_ulong *rc, abi_ulong frame_addr, int usig, abi_ulong rc_addr)

{

	abi_ulong handler = ka->_sa_handler;

	abi_ulong retcode;

	int thumb = handler & 1;

	uint32_t cpsr = cpsr_read(env);

	cpsr &= ~CPSR_IT;

	if (thumb) {

		cpsr |= CPSR_T;

	} else {

		cpsr &= ~CPSR_T;

	}

	if (ka->sa_flags & TARGET_SA_RESTORER) {

		retcode = ka->sa_restorer;

	} else {

		unsigned int idx = thumb;

		if (ka->sa_flags & TARGET_SA_SIGINFO)

			idx += 2;

        __put_user(retcodes[idx], rc);

		retcode = rc_addr + thumb;

	}

	env->regs[0] = usig;

	env->regs[13] = frame_addr;

	env->regs[14] = retcode;

	env->regs[15] = handler & (thumb ? ~1 : ~3);

        cpsr_write(env, cpsr, 0xffffffff, CPSRWriteByInstr);

}


static void tcg_exec_all(void)

{

    int r;

    /* Account partial waits to QEMU_CLOCK_VIRTUAL.  */

    qemu_clock_warp(QEMU_CLOCK_VIRTUAL);

    if (next_cpu == NULL) {

        next_cpu = first_cpu;

    }

    for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) {

        CPUState *cpu = next_cpu;

        qemu_clock_enable(QEMU_CLOCK_VIRTUAL,

                          (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);

        if (cpu_can_run(cpu)) {

            r = tcg_cpu_exec(cpu);

            if (r == EXCP_DEBUG) {

                cpu_handle_guest_debug(cpu);

                break;

            }

        } else if (cpu->stop || cpu->stopped) {

            break;

        }

    }

    /* Pairs with smp_wmb in qemu_cpu_kick.  */

    atomic_mb_set(&exit_request, 0);

}


static int get_keycode(const char *key)

{

    const KeyDef *p;

    char *endp;

    int ret;

    for(p = key_defs; p->name != NULL; p++) {

        if (!strcmp(key, p->name))

            return p->keycode;

    }

    if (strstart(key, "0x", NULL)) {

        ret = strtoul(key, &endp, 0);

        if (*endp == '\0' && ret >= 0x01 && ret <= 0xff)

            return ret;

    }

    return -1;

}