static void vtd_do_iommu_translate(IntelIOMMUState *s, uint8_t bus_num,

                                   uint8_t devfn, hwaddr addr, bool is_write,

                                   IOMMUTLBEntry *entry)

{

    VTDContextEntry ce;

    uint64_t slpte;

    uint32_t level;

    uint16_t source_id = vtd_make_source_id(bus_num, devfn);

    int ret_fr;

    bool is_fpd_set = false;

    bool reads = true;

    bool writes = true;

    /* Check if the request is in interrupt address range */

    if (vtd_is_interrupt_addr(addr)) {

        if (is_write) {

            /* FIXME: since we don't know the length of the access here, we

             * treat Non-DWORD length write requests without PASID as

             * interrupt requests, too. Withoud interrupt remapping support,

             * we just use 1:1 mapping.

             */

            VTD_DPRINTF(MMU, "write request to interrupt address "

                        "gpa 0x%"PRIx64, addr);

            entry->iova = addr & VTD_PAGE_MASK_4K;

            entry->translated_addr = addr & VTD_PAGE_MASK_4K;

            entry->addr_mask = ~VTD_PAGE_MASK_4K;

            entry->perm = IOMMU_WO;

            return;

        } else {

            VTD_DPRINTF(GENERAL, "error: read request from interrupt address "

                        "gpa 0x%"PRIx64, addr);

            vtd_report_dmar_fault(s, source_id, addr, VTD_FR_READ, is_write);

            return;

        }

    }

    ret_fr = vtd_dev_to_context_entry(s, bus_num, devfn, &ce);

    is_fpd_set = ce.lo & VTD_CONTEXT_ENTRY_FPD;

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }

    ret_fr = vtd_gpa_to_slpte(&ce, addr, is_write, &slpte, &level,

                              &reads, &writes);

    if (ret_fr) {

        ret_fr = -ret_fr;

        if (is_fpd_set && vtd_is_qualified_fault(ret_fr)) {

            VTD_DPRINTF(FLOG, "fault processing is disabled for DMA requests "

                        "through this context-entry (with FPD Set)");

        } else {

            vtd_report_dmar_fault(s, source_id, addr, ret_fr, is_write);

        }

        return;

    }

    entry->iova = addr & VTD_PAGE_MASK_4K;

    entry->translated_addr = vtd_get_slpte_addr(slpte) & VTD_PAGE_MASK_4K;

    entry->addr_mask = ~VTD_PAGE_MASK_4K;

    entry->perm = (writes ? 2 : 0) + (reads ? 1 : 0);

}


bool qht_reset_size(struct qht *ht, size_t n_elems)

{

    struct qht_map *new;

    struct qht_map *map;

    size_t n_buckets;

    bool resize = false;

    n_buckets = qht_elems_to_buckets(n_elems);

    qemu_mutex_lock(&ht->lock);

    map = ht->map;

    if (n_buckets != map->n_buckets) {

        new = qht_map_create(n_buckets);

        resize = true;

    }

    qht_map_lock_buckets(map);

    qht_map_reset__all_locked(map);

    if (resize) {

        qht_do_resize(ht, new);

    }

    qht_map_unlock_buckets(map);

    qemu_mutex_unlock(&ht->lock);

    return resize;

}


ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,

                        void *value, size_t vsize)

{

    ssize_t size = 0;

    char buffer[PATH_MAX];

    void *ovalue = value;

    XattrOperations *xops;

    char *orig_value, *orig_value_start;

    ssize_t xattr_len, parsed_len = 0, attr_len;

    /* Get the actual len */

    xattr_len = llistxattr(rpath(ctx, path, buffer), value, 0);

    if (xattr_len <= 0) {

        return xattr_len;

    }

    /* Now fetch the xattr and find the actual size */

    orig_value = g_malloc(xattr_len);

    xattr_len = llistxattr(rpath(ctx, path, buffer), orig_value, xattr_len);

    /* store the orig pointer */

    orig_value_start = orig_value;

    while (xattr_len > parsed_len) {

        xops = get_xattr_operations(ctx->xops, orig_value);

        if (!xops) {

            goto next_entry;

        }

        if (!value) {

            size += xops->listxattr(ctx, path, orig_value, value, vsize);

        } else {

            size = xops->listxattr(ctx, path, orig_value, value, vsize);

            if (size < 0) {

                goto err_out;

            }

            value += size;

            vsize -= size;

        }

next_entry:

        /* Got the next entry */

        attr_len = strlen(orig_value) + 1;

        parsed_len += attr_len;

        orig_value += attr_len;

    }

    if (value) {

        size = value - ovalue;

    }

err_out:

    g_free(orig_value_start);

    return size;

}


static int synth_superframe(AVCodecContext *ctx,

                            float *samples, int *data_size)

{

    WMAVoiceContext *s = ctx->priv_data;

    GetBitContext *gb = &s->gb, s_gb;

    int n, res, n_samples = 480;

    double lsps[MAX_FRAMES][MAX_LSPS];

    const double *mean_lsf = s->lsps == 16 ?

        wmavoice_mean_lsf16[s->lsp_def_mode] : wmavoice_mean_lsf10[s->lsp_def_mode];

    float excitation[MAX_SIGNAL_HISTORY + MAX_SFRAMESIZE + 12];

    float synth[MAX_LSPS + MAX_SFRAMESIZE];

    memcpy(synth,      s->synth_history,

           s->lsps             * sizeof(*synth));

    memcpy(excitation, s->excitation_history,

           s->history_nsamples * sizeof(*excitation));

    if (s->sframe_cache_size > 0) {

        gb = &s_gb;

        init_get_bits(gb, s->sframe_cache, s->sframe_cache_size);

        s->sframe_cache_size = 0;

    }

    if ((res = check_bits_for_superframe(gb, s)) == 1) {

        *data_size = 0;

        return 1;

    }

    /* First bit is speech/music bit, it differentiates between WMAVoice

     * speech samples (the actual codec) and WMAVoice music samples, which

     * are really WMAPro-in-WMAVoice-superframes. I've never seen those in

     * the wild yet. */

    if (!get_bits1(gb)) {

        av_log_missing_feature(ctx, "WMAPro-in-WMAVoice support", 1);

        return -1;

    }

    /* (optional) nr. of samples in superframe; always <= 480 and >= 0 */

    if (get_bits1(gb)) {

        if ((n_samples = get_bits(gb, 12)) > 480) {

            av_log(ctx, AV_LOG_ERROR,

                   "Superframe encodes >480 samples (%d), not allowed\n",

                   n_samples);

            return -1;

        }

    }

    /* Parse LSPs, if global for the superframe (can also be per-frame). */

    if (s->has_residual_lsps) {

        double prev_lsps[MAX_LSPS], a1[MAX_LSPS * 2], a2[MAX_LSPS * 2];

        for (n = 0; n < s->lsps; n++)

            prev_lsps[n] = s->prev_lsps[n] - mean_lsf[n];

        if (s->lsps == 10) {

            dequant_lsp10r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode);

        } else /* s->lsps == 16 */

            dequant_lsp16r(gb, lsps[2], prev_lsps, a1, a2, s->lsp_q_mode);

        for (n = 0; n < s->lsps; n++) {

            lsps[0][n]  = mean_lsf[n] + (a1[n]           - a2[n * 2]);

            lsps[1][n]  = mean_lsf[n] + (a1[s->lsps + n] - a2[n * 2 + 1]);

            lsps[2][n] += mean_lsf[n];

        }

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

            stabilize_lsps(lsps[n], s->lsps);

    }

    /* Parse frames, optionally preceeded by per-frame (independent) LSPs. */

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

        if (!s->has_residual_lsps) {

            int m;

            if (s->lsps == 10) {

                dequant_lsp10i(gb, lsps[n]);

            } else /* s->lsps == 16 */

                dequant_lsp16i(gb, lsps[n]);

            for (m = 0; m < s->lsps; m++)

                lsps[n][m] += mean_lsf[m];

            stabilize_lsps(lsps[n], s->lsps);

        }

        if ((res = synth_frame(ctx, gb, n,

                               &samples[n * MAX_FRAMESIZE],

                               lsps[n], n == 0 ? s->prev_lsps : lsps[n - 1],

                               &excitation[s->history_nsamples + n * MAX_FRAMESIZE],

                               &synth[s->lsps + n * MAX_FRAMESIZE]))) {

            *data_size = 0;

            return res;

        }

    }

    /* Statistics? FIXME - we don't check for length, a slight overrun

     * will be caught by internal buffer padding, and anything else

     * will be skipped, not read. */

    if (get_bits1(gb)) {

        res = get_bits(gb, 4);

        skip_bits(gb, 10 * (res + 1));

    }

    /* Specify nr. of output samples */

    *data_size = n_samples * sizeof(float);

    /* Update history */

    memcpy(s->prev_lsps,           lsps[2],

           s->lsps             * sizeof(*s->prev_lsps));

    memcpy(s->synth_history,      &synth[MAX_SFRAMESIZE],

           s->lsps             * sizeof(*synth));

    memcpy(s->excitation_history, &excitation[MAX_SFRAMESIZE],

           s->history_nsamples * sizeof(*excitation));

    if (s->do_apf)

        memmove(s->zero_exc_pf,       &s->zero_exc_pf[MAX_SFRAMESIZE],

                s->history_nsamples * sizeof(*s->zero_exc_pf));

    return 0;

}


int float64_lt( float64 a, float64 b STATUS_PARAM )

{

    flag aSign, bSign;

    if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )

         || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )

       ) {

        float_raise( float_flag_invalid STATUS_VAR);

        return 0;

    }

    aSign = extractFloat64Sign( a );

    bSign = extractFloat64Sign( b );

    if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );

    return ( a != b ) && ( aSign ^ ( a < b ) );

}


void bdrv_set_enable_write_cache(BlockDriverState *bs, bool wce)

{

    bs->enable_write_cache = wce;

    /* so a reopen() will preserve wce */

    if (wce) {

        bs->open_flags |= BDRV_O_CACHE_WB;

    } else {

        bs->open_flags &= ~BDRV_O_CACHE_WB;

    }

}


QEMUClock *qemu_clock_ptr(QEMUClockType type)

{

    return &qemu_clocks[type];

}


int do_subchannel_work_passthrough(SubchDev *sch)

{

    int ret;

    SCSW *s = &sch->curr_status.scsw;

    if (s->ctrl & SCSW_FCTL_CLEAR_FUNC) {

        /* TODO: Clear handling */

        sch_handle_clear_func(sch);

        ret = 0;

    } else if (s->ctrl & SCSW_FCTL_HALT_FUNC) {

        /* TODO: Halt handling */

        sch_handle_halt_func(sch);

        ret = 0;

    } else if (s->ctrl & SCSW_FCTL_START_FUNC) {

        ret = sch_handle_start_func_passthrough(sch);

    } else {

        /* Cannot happen. */

        return -ENODEV;

    }

    return ret;

}


void ff_h264_v_lpf_luma_inter_msa(uint8_t *data, int img_width,

                                  int alpha, int beta, int8_t *tc)

{

    uint8_t bs0 = 1;

    uint8_t bs1 = 1;

    uint8_t bs2 = 1;

    uint8_t bs3 = 1;

    if (tc[0] < 0)

        bs0 = 0;

    if (tc[1] < 0)

        bs1 = 0;

    if (tc[2] < 0)

        bs2 = 0;

    if (tc[3] < 0)

        bs3 = 0;

    avc_loopfilter_luma_inter_edge_hor_msa(data,

                                           bs0, bs1, bs2, bs3,

                                           tc[0], tc[1], tc[2], tc[3],

                                           alpha, beta, img_width);

}


static av_always_inline void FUNC(row_fdct)(int16_t *data)

{

  int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;

  int tmp10, tmp11, tmp12, tmp13;

  int z1, z2, z3, z4, z5;

  int16_t *dataptr;

  int ctr;

  /* Pass 1: process rows. */

  /* Note results are scaled up by sqrt(8) compared to a true DCT; */

  /* furthermore, we scale the results by 2**PASS1_BITS. */

  dataptr = data;

  for (ctr = DCTSIZE-1; ctr >= 0; ctr--) {

    tmp0 = dataptr[0] + dataptr[7];

    tmp7 = dataptr[0] - dataptr[7];

    tmp1 = dataptr[1] + dataptr[6];

    tmp6 = dataptr[1] - dataptr[6];

    tmp2 = dataptr[2] + dataptr[5];

    tmp5 = dataptr[2] - dataptr[5];

    tmp3 = dataptr[3] + dataptr[4];

    tmp4 = dataptr[3] - dataptr[4];

    /* Even part per LL&M figure 1 --- note that published figure is faulty;

     * rotator "sqrt(2)*c1" should be "sqrt(2)*c6".

     */

    tmp10 = tmp0 + tmp3;

    tmp13 = tmp0 - tmp3;

    tmp11 = tmp1 + tmp2;

    tmp12 = tmp1 - tmp2;

    dataptr[0] = (int16_t) ((tmp10 + tmp11) << PASS1_BITS);

    dataptr[4] = (int16_t) ((tmp10 - tmp11) << PASS1_BITS);

    z1 = MULTIPLY(tmp12 + tmp13, FIX_0_541196100);

    dataptr[2] = (int16_t) DESCALE(z1 + MULTIPLY(tmp13, FIX_0_765366865),

                                   CONST_BITS-PASS1_BITS);

    dataptr[6] = (int16_t) DESCALE(z1 + MULTIPLY(tmp12, - FIX_1_847759065),

                                   CONST_BITS-PASS1_BITS);

    /* Odd part per figure 8 --- note paper omits factor of sqrt(2).

     * cK represents cos(K*pi/16).

     * i0..i3 in the paper are tmp4..tmp7 here.

     */

    z1 = tmp4 + tmp7;

    z2 = tmp5 + tmp6;

    z3 = tmp4 + tmp6;

    z4 = tmp5 + tmp7;

    z5 = MULTIPLY(z3 + z4, FIX_1_175875602); /* sqrt(2) * c3 */

    tmp4 = MULTIPLY(tmp4, FIX_0_298631336); /* sqrt(2) * (-c1+c3+c5-c7) */

    tmp5 = MULTIPLY(tmp5, FIX_2_053119869); /* sqrt(2) * ( c1+c3-c5+c7) */

    tmp6 = MULTIPLY(tmp6, FIX_3_072711026); /* sqrt(2) * ( c1+c3+c5-c7) */

    tmp7 = MULTIPLY(tmp7, FIX_1_501321110); /* sqrt(2) * ( c1+c3-c5-c7) */

    z1 = MULTIPLY(z1, - FIX_0_899976223); /* sqrt(2) * (c7-c3) */

    z2 = MULTIPLY(z2, - FIX_2_562915447); /* sqrt(2) * (-c1-c3) */

    z3 = MULTIPLY(z3, - FIX_1_961570560); /* sqrt(2) * (-c3-c5) */

    z4 = MULTIPLY(z4, - FIX_0_390180644); /* sqrt(2) * (c5-c3) */

    z3 += z5;

    z4 += z5;

    dataptr[7] = (int16_t) DESCALE(tmp4 + z1 + z3, CONST_BITS-PASS1_BITS);

    dataptr[5] = (int16_t) DESCALE(tmp5 + z2 + z4, CONST_BITS-PASS1_BITS);

    dataptr[3] = (int16_t) DESCALE(tmp6 + z2 + z3, CONST_BITS-PASS1_BITS);

    dataptr[1] = (int16_t) DESCALE(tmp7 + z1 + z4, CONST_BITS-PASS1_BITS);

    dataptr += DCTSIZE;         /* advance pointer to next row */

  }

}


static int decode_type2(GetByteContext *gb, PutByteContext *pb)

{

    unsigned repeat = 0, first = 1, opcode;

    int i, len, pos;

    while (bytestream2_get_bytes_left(gb) > 0) {

        GetByteContext gbc;

        while (bytestream2_get_bytes_left(gb) > 0) {

            if (first) {

                first = 0;

                if (bytestream2_peek_byte(gb) > 17) {

                    len = bytestream2_get_byte(gb) - 17;

                    if (len < 4) {

                        do {

                            bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                            --len;

                        } while (len);

                        opcode = bytestream2_peek_byte(gb);

                        continue;

                    } else {

                        do {

                            bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                            --len;

                        } while (len);

                        opcode = bytestream2_peek_byte(gb);

                        if (opcode < 0x10) {

                            bytestream2_skip(gb, 1);

                            pos = - (opcode >> 2) - 4 * bytestream2_get_byte(gb) - 2049;

                            bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);

                            bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);

                            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                            len = opcode & 3;

                            if (!len) {

                                repeat = 1;

                            } else {

                                do {

                                    bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                                    --len;

                                } while (len);

                                opcode = bytestream2_peek_byte(gb);

                            }

                            continue;

                        }

                    }

                    repeat = 0;

                }

                repeat = 1;

            }

            if (repeat) {

                repeat = 0;

                opcode = bytestream2_peek_byte(gb);

                if (opcode < 0x10) {

                    bytestream2_skip(gb, 1);

                    if (!opcode) {

                        if (!bytestream2_peek_byte(gb)) {

                            do {

                                bytestream2_skip(gb, 1);

                                opcode += 255;

                            } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);

                        }

                        opcode += bytestream2_get_byte(gb) + 15;

                    }

                    bytestream2_put_le32(pb, bytestream2_get_le32(gb));

                    for (i = opcode - 1; i > 0; --i)

                        bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                    opcode = bytestream2_peek_byte(gb);

                    if (opcode < 0x10) {

                        bytestream2_skip(gb, 1);

                        pos = - (opcode >> 2) - 4 * bytestream2_get_byte(gb) - 2049;

                        bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);

                        bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);

                        bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                        bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                        bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                        len = opcode & 3;

                        if (!len) {

                            repeat = 1;

                        } else {

                            do {

                                bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                                --len;

                            } while (len);

                            opcode = bytestream2_peek_byte(gb);

                        }

                        continue;

                    }

                }

            }

            if (opcode >= 0x40) {

                bytestream2_skip(gb, 1);

                pos = - ((opcode >> 2) & 7) - 1 - 8 * bytestream2_get_byte(gb);

                len = (opcode >> 5) - 1;

                bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);

                bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);

                bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                do {

                    bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                    --len;

                } while (len);

                len = opcode & 3;

                if (!len) {

                    repeat = 1;

                } else {

                    do {

                        bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                        --len;

                    } while (len);

                    opcode = bytestream2_peek_byte(gb);

                }

                continue;

            } else if (opcode < 0x20) {

                break;

            }

            len = opcode & 0x1F;

            bytestream2_skip(gb, 1);

            if (!len) {

                if (!bytestream2_peek_byte(gb)) {

                    do {

                        bytestream2_skip(gb, 1);

                        len += 255;

                    } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);

                }

                len += bytestream2_get_byte(gb) + 31;

            }

            i = bytestream2_get_le16(gb);

            pos = - (i >> 2) - 1;

            bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);

            bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);

            if (len < 6 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {

                bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                do {

                    bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                    --len;

                } while (len);

            } else {

                bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));

                for (len = len - 2; len; --len)

                    bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

            }

            len = i & 3;

            if (!len) {

                repeat = 1;

            } else {

                do {

                    bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                    --len;

                } while (len);

                opcode = bytestream2_peek_byte(gb);

            }

        }

        bytestream2_skip(gb, 1);

        if (opcode < 0x10) {

            pos = -(opcode >> 2) - 1 - 4 * bytestream2_get_byte(gb);

            bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);

            bytestream2_seek(&gbc, bytestream2_tell_p(pb) + pos, SEEK_SET);

            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

            len = opcode & 3;

            if (!len) {

                repeat = 1;

            } else {

                do {

                    bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                    --len;

                } while (len);

                opcode = bytestream2_peek_byte(gb);

            }

            continue;

        }

        len = opcode & 7;

        if (!len) {

            if (!bytestream2_peek_byte(gb)) {

                do {

                    bytestream2_skip(gb, 1);

                    len += 255;

                } while (!bytestream2_peek_byte(gb) && bytestream2_get_bytes_left(gb) > 0);

            }

            len += bytestream2_get_byte(gb) + 7;

        }

        i = bytestream2_get_le16(gb);

        pos = bytestream2_tell_p(pb) - 2048 * (opcode & 8);

        pos = pos - (i >> 2);

        if (pos == bytestream2_tell_p(pb))

            break;

        pos = pos - 0x4000;

        bytestream2_init(&gbc, pb->buffer_start, pb->buffer_end - pb->buffer_start);

        bytestream2_seek(&gbc, pos, SEEK_SET);

        if (len < 6 || bytestream2_tell_p(pb) - bytestream2_tell(&gbc) < 4) {

            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

            bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

            do {

                bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

                --len;

            } while (len);

        } else {

            bytestream2_put_le32(pb, bytestream2_get_le32(&gbc));

            for (len = len - 2; len; --len)

                bytestream2_put_byte(pb, bytestream2_get_byte(&gbc));

        }

        len = i & 3;

        if (!len) {

            repeat = 1;

        } else {

            do {

                bytestream2_put_byte(pb, bytestream2_get_byte(gb));

                --len;

            } while (len);

            opcode = bytestream2_peek_byte(gb);

        }

    }

    return 0;

}


static int device_open(AVFormatContext *ctx, uint32_t *capabilities)

{

    struct v4l2_capability cap;

    int fd;

    int res, err;

    int flags = O_RDWR;

    if (ctx->flags & AVFMT_FLAG_NONBLOCK) {

        flags |= O_NONBLOCK;

    }

    fd = open(ctx->filename, flags, 0);

    if (fd < 0) {

        av_log(ctx, AV_LOG_ERROR, "Cannot open video device %s : %s\n",

               ctx->filename, strerror(errno));

        return AVERROR(errno);

    }

    res = ioctl(fd, VIDIOC_QUERYCAP, &cap);

    // ENOIOCTLCMD definition only availble on __KERNEL__

    if (res < 0 && ((err = errno) == 515)) {

        av_log(ctx, AV_LOG_ERROR,

               "QUERYCAP not implemented, probably V4L device but "

               "not supporting V4L2\n");

        close(fd);

        return AVERROR(515);

    }

    if (res < 0) {

        av_log(ctx, AV_LOG_ERROR, "ioctl(VIDIOC_QUERYCAP): %s\n",

                 strerror(errno));

        close(fd);

        return AVERROR(err);

    }

    if ((cap.capabilities & V4L2_CAP_VIDEO_CAPTURE) == 0) {

        av_log(ctx, AV_LOG_ERROR, "Not a video capture device\n");

        close(fd);

        return AVERROR(ENODEV);

    }

    *capabilities = cap.capabilities;

    return fd;

}


static void get_default_channel_layouts(OutputStream *ost, InputStream *ist)

{

    char layout_name[256];

    AVCodecContext *enc = ost->st->codec;

    AVCodecContext *dec = ist->st->codec;

    if (!dec->channel_layout) {

        if (enc->channel_layout && dec->channels == enc->channels) {

            dec->channel_layout = enc->channel_layout;

        } else {

            dec->channel_layout = av_get_default_channel_layout(dec->channels);

            if (!dec->channel_layout) {

                av_log(NULL, AV_LOG_FATAL, "Unable to find default channel "

                       "layout for Input Stream #%d.%d\n", ist->file_index,

                       ist->st->index);

                exit_program(1);

            }

        }

        av_get_channel_layout_string(layout_name, sizeof(layout_name),

                                     dec->channels, dec->channel_layout);

        av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for  Input Stream "

               "#%d.%d : %s\n", ist->file_index, ist->st->index, layout_name);

    }

    if (!enc->channel_layout) {

        if (dec->channels == enc->channels) {

            enc->channel_layout = dec->channel_layout;

            return;

        } else {

            enc->channel_layout = av_get_default_channel_layout(enc->channels);

        }

        if (!enc->channel_layout) {

            av_log(NULL, AV_LOG_FATAL, "Unable to find default channel layout "

                   "for Output Stream #%d.%d\n", ost->file_index,

                   ost->st->index);

            exit_program(1);

        }

        av_get_channel_layout_string(layout_name, sizeof(layout_name),

                                     enc->channels, enc->channel_layout);

        av_log(NULL, AV_LOG_WARNING, "Guessed Channel Layout for Output Stream "

               "#%d.%d : %s\n", ost->file_index, ost->st->index, layout_name);

    }

}


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

                                 const AVFrame *frame, int *got_packet_ptr)

{

    int i, stereo, data_size, ret;

    const int16_t *in = frame ? (const int16_t *)frame->data[0] : NULL;

    uint8_t *out;

    ROQDPCMContext *context = avctx->priv_data;

    stereo = (avctx->channels == 2);

    if (!in && context->input_frames >= 8)

        return 0;

    if (in && context->input_frames < 8) {

        memcpy(&context->frame_buffer[context->buffered_samples * avctx->channels],

               in, avctx->frame_size * avctx->channels * sizeof(*in));

        context->buffered_samples += avctx->frame_size;

        if (context->input_frames == 0)

            context->first_pts = frame->pts;

        if (context->input_frames < 7) {

            context->input_frames++;

            return 0;

        }

    }

    if (context->input_frames < 8) {

        in = context->frame_buffer;

    }

    if (stereo) {

        context->lastSample[0] &= 0xFF00;

        context->lastSample[1] &= 0xFF00;

    }

    if (context->input_frames == 7)

        data_size = avctx->channels * context->buffered_samples;

    else

        data_size = avctx->channels * avctx->frame_size;

    if ((ret = ff_alloc_packet2(avctx, avpkt, ROQ_HEADER_SIZE + data_size)))

        return ret;

    out = avpkt->data;

    bytestream_put_byte(&out, stereo ? 0x21 : 0x20);

    bytestream_put_byte(&out, 0x10);

    bytestream_put_le32(&out, data_size);

    if (stereo) {

        bytestream_put_byte(&out, (context->lastSample[1])>>8);

        bytestream_put_byte(&out, (context->lastSample[0])>>8);

    } else

        bytestream_put_le16(&out, context->lastSample[0]);

    /* Write the actual samples */

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

        *out++ = dpcm_predict(&context->lastSample[i & 1], *in++);

    avpkt->pts      = context->input_frames <= 7 ? context->first_pts : frame->pts;

    avpkt->duration = data_size / avctx->channels;

    context->input_frames++;

    if (!in)

        context->input_frames = FFMAX(context->input_frames, 8);

    *got_packet_ptr = 1;

    return 0;

}


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

                             int *data_size, AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    TwinContext *tctx = avctx->priv_data;

    GetBitContext gb;

    const ModeTab *mtab = tctx->mtab;

    float *out = data;

    enum FrameType ftype;

    int window_type;

    static const enum FrameType wtype_to_ftype_table[] = {

        FT_LONG,   FT_LONG, FT_SHORT, FT_LONG,

        FT_MEDIUM, FT_LONG, FT_LONG,  FT_MEDIUM, FT_MEDIUM

    };

    if (buf_size*8 < avctx->bit_rate*mtab->size/avctx->sample_rate + 8) {

        av_log(avctx, AV_LOG_ERROR,

               "Frame too small (%d bytes). Truncated file?\n", buf_size);

        return AVERROR(EINVAL);

    }

    init_get_bits(&gb, buf, buf_size * 8);

    skip_bits(&gb, get_bits(&gb, 8));

    window_type = get_bits(&gb, WINDOW_TYPE_BITS);

    if (window_type > 8) {

        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");

        return -1;

    }

    ftype = wtype_to_ftype_table[window_type];

    read_and_decode_spectrum(tctx, &gb, tctx->spectrum, ftype);

    imdct_output(tctx, ftype, window_type, out);

    FFSWAP(float*, tctx->curr_frame, tctx->prev_frame);

    if (tctx->avctx->frame_number < 2) {

        *data_size=0;

        return buf_size;

    }

    *data_size = mtab->size*avctx->channels*4;

    return buf_size;

}


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

                     int64_t pos, uint64_t cluster_time,

                     int is_keyframe, int is_bframe,

                     int *ptrack, AVPacket **ppkt)

{

    int res = 0;

    int track;

    AVPacket *pkt;

    uint8_t *origdata = data;

    int16_t block_time;

    uint32_t *lace_size = NULL;

    int n, flags, laces = 0;

    uint64_t num;

    /* first byte(s): tracknum */

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

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

        av_free(origdata);

        return res;

    }

    data += n;

    size -= n;

    /* fetch track from num */

    track = matroska_find_track_by_num(matroska, num);

    if (ptrack)  *ptrack = track;

    if (size <= 3 || track < 0 || track >= matroska->num_tracks) {

        av_log(matroska->ctx, AV_LOG_INFO,

               "Invalid stream %d or size %u\n", track, size);

        av_free(origdata);

        return res;

    }

    if(matroska->ctx->streams[ matroska->tracks[track]->stream_index ]->discard >= AVDISCARD_ALL){

        av_free(origdata);

        return res;

    }

    /* block_time (relative to cluster time) */

    block_time = (data[0] << 8) | data[1];

    data += 2;

    size -= 2;

    flags = *data;

    data += 1;

    size -= 1;

    if (is_keyframe == -1)

        is_keyframe = flags & 1 ? PKT_FLAG_KEY : 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 */

            if (size == 0) {

                res = -1;

                break;

            }

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

        int real_v = matroska->tracks[track]->flags & MATROSKA_TRACK_REAL_V;

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

            uint64_t timecode = AV_NOPTS_VALUE;

            int slice, slices = 1;

            if (real_v) {

                slices = *data++ + 1;

                lace_size[n]--;

            }

            if (cluster_time != (uint64_t)-1 && n == 0) {

                if (cluster_time + block_time >= 0)

                    timecode = cluster_time + block_time;

            }

            /* FIXME: duration */

            for (slice=0; slice<slices; slice++) {

                int slice_size, slice_offset = 0;

                if (real_v)

                    slice_offset = rv_offset(data, slice, slices);

                if (slice+1 == slices)

                    slice_size = lace_size[n] - slice_offset;

                else

                    slice_size = rv_offset(data, slice+1, slices) - slice_offset;

                pkt = av_mallocz(sizeof(AVPacket));

                if (ppkt)  *ppkt = pkt;

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

                if (av_new_packet(pkt, slice_size) < 0) {

                    res = AVERROR_NOMEM;

                    n = laces-1;

                    break;

                }

                memcpy (pkt->data, data+slice_offset, slice_size);

                if (n == 0)

                    pkt->flags = is_keyframe;

                pkt->stream_index = matroska->tracks[track]->stream_index;

                pkt->pts = timecode;

                pkt->pos = pos;

                if (matroska->tracks[track]->flags & MATROSKA_TRACK_REORDER)

                    matroska_queue_packet_reordered(matroska, pkt, is_bframe);

                else

                    matroska_queue_packet(matroska, pkt);

            }

            data += lace_size[n];

        }

    }

    av_free(lace_size);

    av_free(origdata);

    return res;

}


static void clipper_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    AlphaCPU *cpus[4];

    PCIBus *pci_bus;

    ISABus *isa_bus;

    qemu_irq rtc_irq;

    long size, i;

    char *palcode_filename;

    uint64_t palcode_entry, palcode_low, palcode_high;

    uint64_t kernel_entry, kernel_low, kernel_high;

    /* Create up to 4 cpus.  */

    memset(cpus, 0, sizeof(cpus));

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

        cpus[i] = cpu_alpha_init(cpu_model ? cpu_model : "ev67");

    }

    cpus[0]->env.trap_arg0 = ram_size;

    cpus[0]->env.trap_arg1 = 0;

    cpus[0]->env.trap_arg2 = smp_cpus;

    /* Init the chipset.  */

    pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus,

                           clipper_pci_map_irq);

    /* Since we have an SRM-compatible PALcode, use the SRM epoch.  */

    rtc_init(isa_bus, 1900, rtc_irq);

    pit_init(isa_bus, 0x40, 0, NULL);

    isa_create_simple(isa_bus, "i8042");

    /* VGA setup.  Don't bother loading the bios.  */

    pci_vga_init(pci_bus);

    /* Serial code setup.  */

    serial_hds_isa_init(isa_bus, 0, MAX_SERIAL_PORTS);

    /* Network setup.  e1000 is good enough, failing Tulip support.  */

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

        pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL);

    }

    /* IDE disk setup.  */

    {

        DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];

        ide_drive_get(hd, ARRAY_SIZE(hd));

        pci_cmd646_ide_init(pci_bus, hd, 0);

    }

    /* Load PALcode.  Given that this is not "real" cpu palcode,

       but one explicitly written for the emulation, we might as

       well load it directly from and ELF image.  */

    palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS,

                                bios_name ? bios_name : "palcode-clipper");

    if (palcode_filename == NULL) {

        error_report("no palcode provided");

        exit(1);

    }

    size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys,

                    NULL, &palcode_entry, &palcode_low, &palcode_high,

                    0, EM_ALPHA, 0, 0);

    if (size < 0) {

        error_report("could not load palcode '%s'", palcode_filename);

        exit(1);

    }

    g_free(palcode_filename);

    /* Start all cpus at the PALcode RESET entry point.  */

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

        cpus[i]->env.pc = palcode_entry;

        cpus[i]->env.palbr = palcode_entry;

    }

    /* Load a kernel.  */

    if (kernel_filename) {

        uint64_t param_offset;

        size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys,

                        NULL, &kernel_entry, &kernel_low, &kernel_high,

                        0, EM_ALPHA, 0, 0);

        if (size < 0) {

            error_report("could not load kernel '%s'", kernel_filename);

            exit(1);

        }

        cpus[0]->env.trap_arg1 = kernel_entry;

        param_offset = kernel_low - 0x6000;

        if (kernel_cmdline) {

            pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline);

        }

        if (initrd_filename) {

            long initrd_base, initrd_size;

            initrd_size = get_image_size(initrd_filename);

            if (initrd_size < 0) {

                error_report("could not load initial ram disk '%s'",

                             initrd_filename);

                exit(1);

            }

            /* Put the initrd image as high in memory as possible.  */

            initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK;

            load_image_targphys(initrd_filename, initrd_base,

                                ram_size - initrd_base);

            address_space_stq(&address_space_memory, param_offset + 0x100,

                              initrd_base + 0xfffffc0000000000ULL,

                              MEMTXATTRS_UNSPECIFIED,

                              NULL);

            address_space_stq(&address_space_memory, param_offset + 0x108,

                              initrd_size, MEMTXATTRS_UNSPECIFIED, NULL);

        }

    }

}


void ff_thread_flush(AVCodecContext *avctx)

{

    FrameThreadContext *fctx = avctx->thread_opaque;

    if (!avctx->thread_opaque) return;

    park_frame_worker_threads(fctx, avctx->thread_count);

    if (fctx->prev_thread) {

        if (fctx->prev_thread != &fctx->threads[0])

            update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0);

        if (avctx->codec->flush)

            avctx->codec->flush(fctx->threads[0].avctx);

    }

    fctx->next_decoding = fctx->next_finished = 0;

    fctx->delaying = 1;

    fctx->prev_thread = NULL;

    // Make sure decode flush calls with size=0 won't return old frames

    for (int i = 0; i < avctx->thread_count; i++)

        fctx->threads[i].got_frame = 0;

}


static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,

                                      int l1_size, int64_t *visited_l1_entries,

                                      int64_t l1_entries,

                                      BlockDriverAmendStatusCB *status_cb,

                                      void *cb_opaque)

{

    BDRVQcow2State *s = bs->opaque;

    bool is_active_l1 = (l1_table == s->l1_table);

    uint64_t *l2_table = NULL;

    int ret;

    int i, j;

    if (!is_active_l1) {

        /* inactive L2 tables require a buffer to be stored in when loading

         * them from disk */

        l2_table = qemu_try_blockalign(bs->file->bs, s->cluster_size);

        if (l2_table == NULL) {

            return -ENOMEM;

        }

    }

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

        uint64_t l2_offset = l1_table[i] & L1E_OFFSET_MASK;

        bool l2_dirty = false;

        uint64_t l2_refcount;

        if (!l2_offset) {

            /* unallocated */

            (*visited_l1_entries)++;

            if (status_cb) {

                status_cb(bs, *visited_l1_entries, l1_entries, cb_opaque);

            }

            continue;

        }

        if (offset_into_cluster(s, l2_offset)) {

            qcow2_signal_corruption(bs, true, -1, -1, "L2 table offset %#"

                                    PRIx64 " unaligned (L1 index: %#x)",

                                    l2_offset, i);

            ret = -EIO;

            goto fail;

        }

        if (is_active_l1) {

            /* get active L2 tables from cache */

            ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,

                    (void **)&l2_table);

        } else {

            /* load inactive L2 tables from disk */

            ret = bdrv_read(bs->file, l2_offset / BDRV_SECTOR_SIZE,

                            (void *)l2_table, s->cluster_sectors);

        }

        if (ret < 0) {

            goto fail;

        }

        ret = qcow2_get_refcount(bs, l2_offset >> s->cluster_bits,

                                 &l2_refcount);

        if (ret < 0) {

            goto fail;

        }

        for (j = 0; j < s->l2_size; j++) {

            uint64_t l2_entry = be64_to_cpu(l2_table[j]);

            int64_t offset = l2_entry & L2E_OFFSET_MASK;

            QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);

            bool preallocated = offset != 0;

            if (cluster_type != QCOW2_CLUSTER_ZERO) {

                continue;

            }

            if (!preallocated) {

                if (!bs->backing) {

                    /* not backed; therefore we can simply deallocate the

                     * cluster */

                    l2_table[j] = 0;

                    l2_dirty = true;

                    continue;

                }

                offset = qcow2_alloc_clusters(bs, s->cluster_size);

                if (offset < 0) {

                    ret = offset;

                    goto fail;

                }

                if (l2_refcount > 1) {

                    /* For shared L2 tables, set the refcount accordingly (it is

                     * already 1 and needs to be l2_refcount) */

                    ret = qcow2_update_cluster_refcount(bs,

                            offset >> s->cluster_bits,

                            refcount_diff(1, l2_refcount), false,

                            QCOW2_DISCARD_OTHER);

                    if (ret < 0) {

                        qcow2_free_clusters(bs, offset, s->cluster_size,

                                            QCOW2_DISCARD_OTHER);

                        goto fail;

                    }

                }

            }

            if (offset_into_cluster(s, offset)) {

                qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset "

                                        "%#" PRIx64 " unaligned (L2 offset: %#"

                                        PRIx64 ", L2 index: %#x)", offset,

                                        l2_offset, j);

                if (!preallocated) {

                    qcow2_free_clusters(bs, offset, s->cluster_size,

                                        QCOW2_DISCARD_ALWAYS);

                }

                ret = -EIO;

                goto fail;

            }

            ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);

            if (ret < 0) {

                if (!preallocated) {

                    qcow2_free_clusters(bs, offset, s->cluster_size,

                                        QCOW2_DISCARD_ALWAYS);

                }

                goto fail;

            }

            ret = bdrv_pwrite_zeroes(bs->file, offset, s->cluster_size, 0);

            if (ret < 0) {

                if (!preallocated) {

                    qcow2_free_clusters(bs, offset, s->cluster_size,

                                        QCOW2_DISCARD_ALWAYS);

                }

                goto fail;

            }

            if (l2_refcount == 1) {

                l2_table[j] = cpu_to_be64(offset | QCOW_OFLAG_COPIED);

            } else {

                l2_table[j] = cpu_to_be64(offset);

            }

            l2_dirty = true;

        }

        if (is_active_l1) {

            if (l2_dirty) {

                qcow2_cache_entry_mark_dirty(bs, s->l2_table_cache, l2_table);

                qcow2_cache_depends_on_flush(s->l2_table_cache);

            }

            qcow2_cache_put(bs, s->l2_table_cache, (void **) &l2_table);

        } else {

            if (l2_dirty) {

                ret = qcow2_pre_write_overlap_check(bs,

                        QCOW2_OL_INACTIVE_L2 | QCOW2_OL_ACTIVE_L2, l2_offset,

                        s->cluster_size);

                if (ret < 0) {

                    goto fail;

                }

                ret = bdrv_write(bs->file, l2_offset / BDRV_SECTOR_SIZE,

                                 (void *)l2_table, s->cluster_sectors);

                if (ret < 0) {

                    goto fail;

                }

            }

        }

        (*visited_l1_entries)++;

        if (status_cb) {

            status_cb(bs, *visited_l1_entries, l1_entries, cb_opaque);

        }

    }

    ret = 0;

fail:

    if (l2_table) {

        if (!is_active_l1) {

            qemu_vfree(l2_table);

        } else {

            qcow2_cache_put(bs, s->l2_table_cache, (void **) &l2_table);

        }

    }

    return ret;

}


static void wait_for_aio(void)

{

    while (aio_poll(ctx, true)) {

        /* Do nothing */

    }

}


static VTDIOTLBEntry *vtd_lookup_iotlb(IntelIOMMUState *s, uint16_t source_id,

                                       hwaddr addr)

{

    uint64_t key;

    key = (addr >> VTD_PAGE_SHIFT_4K) |

           ((uint64_t)(source_id) << VTD_IOTLB_SID_SHIFT);

    return g_hash_table_lookup(s->iotlb, &key);

}


BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int error)

{

    BlockdevOnError on_err = is_read ? bs->on_read_error : bs->on_write_error;

    switch (on_err) {

    case BLOCKDEV_ON_ERROR_ENOSPC:

        return (error == ENOSPC) ?

               BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;

    case BLOCKDEV_ON_ERROR_STOP:

        return BLOCK_ERROR_ACTION_STOP;

    case BLOCKDEV_ON_ERROR_REPORT:

        return BLOCK_ERROR_ACTION_REPORT;

    case BLOCKDEV_ON_ERROR_IGNORE:

        return BLOCK_ERROR_ACTION_IGNORE;

    default:

        abort();

    }

}


gboolean qcrypto_hash_supports(QCryptoHashAlgorithm alg G_GNUC_UNUSED)

{

    return false;

}


static void xen_io_add(MemoryListener *listener,

                       MemoryRegionSection *section)

{

    XenIOState *state = container_of(listener, XenIOState, io_listener);

    memory_region_ref(section->mr);

    xen_map_io_section(xen_xc, xen_domid, state->ioservid, section);

}


static void opt_mb_qmin(const char *arg)

{

    video_mb_qmin = atoi(arg);

    if (video_mb_qmin < 0 ||

        video_mb_qmin > 31) {

        fprintf(stderr, "qmin must be >= 1 and <= 31\n");

        exit(1);

    }

}


static void handle_windowevent(SDL_Event *ev)

{

    struct sdl2_console *scon = get_scon_from_window(ev->window.windowID);

    if (!scon) {

        return;

    }

    switch (ev->window.event) {

    case SDL_WINDOWEVENT_RESIZED:

        {

            QemuUIInfo info;

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

            info.width = ev->window.data1;

            info.height = ev->window.data2;

            dpy_set_ui_info(scon->dcl.con, &info);

        }

        sdl2_redraw(scon);

        break;

    case SDL_WINDOWEVENT_EXPOSED:

        sdl2_redraw(scon);

        break;

    case SDL_WINDOWEVENT_FOCUS_GAINED:

    case SDL_WINDOWEVENT_ENTER:

        if (!gui_grab && (qemu_input_is_absolute() || absolute_enabled)) {

            absolute_mouse_grab(scon);

        }

        break;

    case SDL_WINDOWEVENT_FOCUS_LOST:

        if (gui_grab && !gui_fullscreen) {

            sdl_grab_end(scon);

        }

        break;

    case SDL_WINDOWEVENT_RESTORED:

        update_displaychangelistener(&scon->dcl, GUI_REFRESH_INTERVAL_DEFAULT);

        break;

    case SDL_WINDOWEVENT_MINIMIZED:

        update_displaychangelistener(&scon->dcl, 500);

        break;

    case SDL_WINDOWEVENT_CLOSE:

        if (qemu_console_is_graphic(scon->dcl.con)) {

            if (!no_quit) {

                no_shutdown = 0;

                qemu_system_shutdown_request(SHUTDOWN_CAUSE_HOST_UI);

            }

        } else {

            SDL_HideWindow(scon->real_window);

            scon->hidden = true;

        }

        break;

    case SDL_WINDOWEVENT_SHOWN:

        if (scon->hidden) {

            SDL_HideWindow(scon->real_window);

        }

        break;

    case SDL_WINDOWEVENT_HIDDEN:

        if (!scon->hidden) {

            SDL_ShowWindow(scon->real_window);

        }

        break;

    }

}


static void kvm_supported_msrs(CPUState *env)

{

    static int kvm_supported_msrs;

    int ret;

    /* first time */

    if (kvm_supported_msrs == 0) {

        struct kvm_msr_list msr_list, *kvm_msr_list;

        kvm_supported_msrs = -1;

        /* Obtain MSR list from KVM.  These are the MSRs that we must

         * save/restore */

        msr_list.nmsrs = 0;

        ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);

        if (ret < 0 && ret != -E2BIG) {

            return;

        }

        /* Old kernel modules had a bug and could write beyond the provided

           memory. Allocate at least a safe amount of 1K. */

        kvm_msr_list = qemu_mallocz(MAX(1024, sizeof(msr_list) +

                                              msr_list.nmsrs *

                                              sizeof(msr_list.indices[0])));

        kvm_msr_list->nmsrs = msr_list.nmsrs;

        ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, kvm_msr_list);

        if (ret >= 0) {

            int i;

            for (i = 0; i < kvm_msr_list->nmsrs; i++) {

                if (kvm_msr_list->indices[i] == MSR_STAR) {

                    has_msr_star = 1;

                    continue;

                }

                if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {

                    has_msr_hsave_pa = 1;

                    continue;

                }

            }

        }

        free(kvm_msr_list);

    }

    return;

}


static void spapr_lmb_release(DeviceState *dev, void *opaque)

{

    HotplugHandler *hotplug_ctrl = qdev_get_hotplug_handler(dev);

    sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_ctrl);

    sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));

    if (--ds->nr_lmbs) {

        return;

    }

    spapr_pending_dimm_unplugs_remove(spapr, ds);

    /*

     * Now that all the LMBs have been removed by the guest, call the

     * pc-dimm unplug handler to cleanup up the pc-dimm device.

     */

    hotplug_handler_unplug(hotplug_ctrl, dev, &error_abort);

}


static void monitor_readline_printf(void *opaque, const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    monitor_vprintf(opaque, fmt, ap);

    va_end(ap);

}


static int op_to_mov(int op)

{

    switch (op_bits(op)) {

    case 32:

        return INDEX_op_mov_i32;

#if TCG_TARGET_REG_BITS == 64

    case 64:

        return INDEX_op_mov_i64;

#endif

    default:

        fprintf(stderr, "op_to_mov: unexpected return value of "

                "function op_bits.\n");

        tcg_abort();

    }

}


void object_property_get_uint16List(Object *obj, const char *name,

                                    uint16List **list, Error **errp)

{

    Error *err = NULL;

    StringOutputVisitor *ov;

    Visitor *v;

    char *str;

    ov = string_output_visitor_new(false);

    object_property_get(obj, string_output_get_visitor(ov),

                        name, &err);

    if (err) {

        error_propagate(errp, err);

        goto out;

    }

    str = string_output_get_string(ov);

    v = string_input_visitor_new(str);

    visit_type_uint16List(v, NULL, list, errp);

    g_free(str);

    visit_free(v);

out:

    string_output_visitor_cleanup(ov);

}


static void chroma_4mv_motion(MpegEncContext *s,

                              uint8_t *dest_cb, uint8_t *dest_cr,

                              uint8_t **ref_picture,

                              op_pixels_func *pix_op,

                              int mx, int my)

{

    uint8_t *ptr;

    int src_x, src_y, dxy, emu = 0;

    ptrdiff_t offset;

    /* In case of 8X8, we construct a single chroma motion vector

     * with a special rounding */

    mx = ff_h263_round_chroma(mx);

    my = ff_h263_round_chroma(my);

    dxy  = ((my & 1) << 1) | (mx & 1);

    mx >>= 1;

    my >>= 1;

    src_x = s->mb_x * 8 + mx;

    src_y = s->mb_y * 8 + my;

    src_x = av_clip(src_x, -8, (s->width >> 1));

    if (src_x == (s->width >> 1))

        dxy &= ~1;

    src_y = av_clip(src_y, -8, (s->height >> 1));

    if (src_y == (s->height >> 1))

        dxy &= ~2;

    offset = src_y * s->uvlinesize + src_x;

    ptr    = ref_picture[1] + offset;

    if ((unsigned)src_x > FFMAX((s->h_edge_pos >> 1) - (dxy & 1) - 8, 0) ||

        (unsigned)src_y > FFMAX((s->v_edge_pos >> 1) - (dxy >> 1) - 8, 0)) {

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,

                                 s->uvlinesize, s->uvlinesize,

                                 9, 9, src_x, src_y,

                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);

        ptr = s->edge_emu_buffer;

        emu = 1;

    }

    pix_op[dxy](dest_cb, ptr, s->uvlinesize, 8);

    ptr = ref_picture[2] + offset;

    if (emu) {

        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr,

                                 s->uvlinesize, s->uvlinesize,

                                 9, 9, src_x, src_y,

                                 s->h_edge_pos >> 1, s->v_edge_pos >> 1);

        ptr = s->edge_emu_buffer;

    }

    pix_op[dxy](dest_cr, ptr, s->uvlinesize, 8);

}


static inline void tcg_out_op(TCGContext *s, TCGOpcode opc,

                const TCGArg *args, const int *const_args)

{

    int c;

    switch (opc) {

    case INDEX_op_exit_tb:

        {

            uint8_t *ld_ptr = s->code_ptr;

            if (args[0] >> 8)

                tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);

            else

                tcg_out_dat_imm(s, COND_AL, ARITH_MOV, TCG_REG_R0, 0, args[0]);

            tcg_out_goto(s, COND_AL, (tcg_target_ulong) tb_ret_addr);

            if (args[0] >> 8) {

                *ld_ptr = (uint8_t) (s->code_ptr - ld_ptr) - 8;

                tcg_out32(s, args[0]);

            }

        }

        break;

    case INDEX_op_goto_tb:

        if (s->tb_jmp_offset) {

            /* Direct jump method */

#if defined(USE_DIRECT_JUMP)

            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;

            tcg_out_b_noaddr(s, COND_AL);

#else

            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, -4);

            s->tb_jmp_offset[args[0]] = s->code_ptr - s->code_buf;

            tcg_out32(s, 0);

#endif

        } else {

            /* Indirect jump method */

#if 1

            c = (int) (s->tb_next + args[0]) - ((int) s->code_ptr + 8);

            if (c > 0xfff || c < -0xfff) {

                tcg_out_movi32(s, COND_AL, TCG_REG_R0,

                                (tcg_target_long) (s->tb_next + args[0]));

                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);

            } else

                tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_PC, c);

#else

            tcg_out_ld32_12(s, COND_AL, TCG_REG_R0, TCG_REG_PC, 0);

            tcg_out_ld32_12(s, COND_AL, TCG_REG_PC, TCG_REG_R0, 0);

            tcg_out32(s, (tcg_target_long) (s->tb_next + args[0]));

#endif

        }

        s->tb_next_offset[args[0]] = s->code_ptr - s->code_buf;

        break;

    case INDEX_op_call:

        if (const_args[0])

            tcg_out_call(s, args[0]);

        else

            tcg_out_callr(s, COND_AL, args[0]);

        break;

    case INDEX_op_br:

        tcg_out_goto_label(s, COND_AL, args[0]);

        break;

    case INDEX_op_ld8u_i32:

        tcg_out_ld8u(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_ld8s_i32:

        tcg_out_ld8s(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_ld16u_i32:

        tcg_out_ld16u(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_ld16s_i32:

        tcg_out_ld16s(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_ld_i32:

        tcg_out_ld32u(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_st8_i32:

        tcg_out_st8(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_st16_i32:

        tcg_out_st16(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_st_i32:

        tcg_out_st32(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_mov_i32:

        tcg_out_dat_reg(s, COND_AL, ARITH_MOV,

                        args[0], 0, args[1], SHIFT_IMM_LSL(0));

        break;

    case INDEX_op_movi_i32:

        tcg_out_movi32(s, COND_AL, args[0], args[1]);

        break;

    case INDEX_op_movcond_i32:

        /* Constraints mean that v2 is always in the same register as dest,

         * so we only need to do "if condition passed, move v1 to dest".

         */

        tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0,

                       args[1], args[2], const_args[2]);

        tcg_out_dat_rI(s, tcg_cond_to_arm_cond[args[5]],

                       ARITH_MOV, args[0], 0, args[3], const_args[3]);

        break;

    case INDEX_op_add_i32:

        c = ARITH_ADD;

        goto gen_arith;

    case INDEX_op_sub_i32:

        c = ARITH_SUB;

        goto gen_arith;

    case INDEX_op_and_i32:

        tcg_out_dat_rIK(s, COND_AL, ARITH_AND, ARITH_BIC,

                        args[0], args[1], args[2], const_args[2]);

        break;

    case INDEX_op_andc_i32:

        tcg_out_dat_rIK(s, COND_AL, ARITH_BIC, ARITH_AND,

                        args[0], args[1], args[2], const_args[2]);

        break;

    case INDEX_op_or_i32:

        c = ARITH_ORR;

        goto gen_arith;

    case INDEX_op_xor_i32:

        c = ARITH_EOR;

        /* Fall through.  */

    gen_arith:

        tcg_out_dat_rI(s, COND_AL, c, args[0], args[1], args[2], const_args[2]);

        break;

    case INDEX_op_add2_i32:

        tcg_out_dat_reg2(s, COND_AL, ARITH_ADD, ARITH_ADC,

                        args[0], args[1], args[2], args[3],

                        args[4], args[5], SHIFT_IMM_LSL(0));

        break;

    case INDEX_op_sub2_i32:

        tcg_out_dat_reg2(s, COND_AL, ARITH_SUB, ARITH_SBC,

                        args[0], args[1], args[2], args[3],

                        args[4], args[5], SHIFT_IMM_LSL(0));

        break;

    case INDEX_op_neg_i32:

        tcg_out_dat_imm(s, COND_AL, ARITH_RSB, args[0], args[1], 0);

        break;

    case INDEX_op_not_i32:

        tcg_out_dat_reg(s, COND_AL,

                        ARITH_MVN, args[0], 0, args[1], SHIFT_IMM_LSL(0));

        break;

    case INDEX_op_mul_i32:

        tcg_out_mul32(s, COND_AL, args[0], args[1], args[2]);

        break;

    case INDEX_op_mulu2_i32:

        tcg_out_umull32(s, COND_AL, args[0], args[1], args[2], args[3]);

        break;

    case INDEX_op_muls2_i32:

        tcg_out_smull32(s, COND_AL, args[0], args[1], args[2], args[3]);

        break;

    /* XXX: Perhaps args[2] & 0x1f is wrong */

    case INDEX_op_shl_i32:

        c = const_args[2] ?

                SHIFT_IMM_LSL(args[2] & 0x1f) : SHIFT_REG_LSL(args[2]);

        goto gen_shift32;

    case INDEX_op_shr_i32:

        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_LSR(args[2] & 0x1f) :

                SHIFT_IMM_LSL(0) : SHIFT_REG_LSR(args[2]);

        goto gen_shift32;

    case INDEX_op_sar_i32:

        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ASR(args[2] & 0x1f) :

                SHIFT_IMM_LSL(0) : SHIFT_REG_ASR(args[2]);

        goto gen_shift32;

    case INDEX_op_rotr_i32:

        c = const_args[2] ? (args[2] & 0x1f) ? SHIFT_IMM_ROR(args[2] & 0x1f) :

                SHIFT_IMM_LSL(0) : SHIFT_REG_ROR(args[2]);

        /* Fall through.  */

    gen_shift32:

        tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1], c);

        break;

    case INDEX_op_rotl_i32:

        if (const_args[2]) {

            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],

                            ((0x20 - args[2]) & 0x1f) ?

                            SHIFT_IMM_ROR((0x20 - args[2]) & 0x1f) :

                            SHIFT_IMM_LSL(0));

        } else {

            tcg_out_dat_imm(s, COND_AL, ARITH_RSB, TCG_REG_R8, args[1], 0x20);

            tcg_out_dat_reg(s, COND_AL, ARITH_MOV, args[0], 0, args[1],

                            SHIFT_REG_ROR(TCG_REG_R8));

        }

        break;

    case INDEX_op_brcond_i32:

        tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0,

                       args[0], args[1], const_args[1]);

        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[2]], args[3]);

        break;

    case INDEX_op_brcond2_i32:

        /* The resulting conditions are:

         * TCG_COND_EQ    -->  a0 == a2 && a1 == a3,

         * TCG_COND_NE    --> (a0 != a2 && a1 == a3) ||  a1 != a3,

         * TCG_COND_LT(U) --> (a0 <  a2 && a1 == a3) ||  a1 <  a3,

         * TCG_COND_GE(U) --> (a0 >= a2 && a1 == a3) || (a1 >= a3 && a1 != a3),

         * TCG_COND_LE(U) --> (a0 <= a2 && a1 == a3) || (a1 <= a3 && a1 != a3),

         * TCG_COND_GT(U) --> (a0 >  a2 && a1 == a3) ||  a1 >  a3,

         */

        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,

                        args[1], args[3], SHIFT_IMM_LSL(0));

        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,

                        args[0], args[2], SHIFT_IMM_LSL(0));

        tcg_out_goto_label(s, tcg_cond_to_arm_cond[args[4]], args[5]);

        break;

    case INDEX_op_setcond_i32:

        tcg_out_dat_rI(s, COND_AL, ARITH_CMP, 0,

                       args[1], args[2], const_args[2]);

        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[3]],

                        ARITH_MOV, args[0], 0, 1);

        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[3])],

                        ARITH_MOV, args[0], 0, 0);

        break;

    case INDEX_op_setcond2_i32:

        /* See brcond2_i32 comment */

        tcg_out_dat_reg(s, COND_AL, ARITH_CMP, 0,

                        args[2], args[4], SHIFT_IMM_LSL(0));

        tcg_out_dat_reg(s, COND_EQ, ARITH_CMP, 0,

                        args[1], args[3], SHIFT_IMM_LSL(0));

        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[args[5]],

                        ARITH_MOV, args[0], 0, 1);

        tcg_out_dat_imm(s, tcg_cond_to_arm_cond[tcg_invert_cond(args[5])],

                        ARITH_MOV, args[0], 0, 0);

        break;

    case INDEX_op_qemu_ld8u:

        tcg_out_qemu_ld(s, args, 0);

        break;

    case INDEX_op_qemu_ld8s:

        tcg_out_qemu_ld(s, args, 0 | 4);

        break;

    case INDEX_op_qemu_ld16u:

        tcg_out_qemu_ld(s, args, 1);

        break;

    case INDEX_op_qemu_ld16s:

        tcg_out_qemu_ld(s, args, 1 | 4);

        break;

    case INDEX_op_qemu_ld32:

        tcg_out_qemu_ld(s, args, 2);

        break;

    case INDEX_op_qemu_ld64:

        tcg_out_qemu_ld(s, args, 3);

        break;

    case INDEX_op_qemu_st8:

        tcg_out_qemu_st(s, args, 0);

        break;

    case INDEX_op_qemu_st16:

        tcg_out_qemu_st(s, args, 1);

        break;

    case INDEX_op_qemu_st32:

        tcg_out_qemu_st(s, args, 2);

        break;

    case INDEX_op_qemu_st64:

        tcg_out_qemu_st(s, args, 3);

        break;

    case INDEX_op_bswap16_i32:

        tcg_out_bswap16(s, COND_AL, args[0], args[1]);

        break;

    case INDEX_op_bswap32_i32:

        tcg_out_bswap32(s, COND_AL, args[0], args[1]);

        break;

    case INDEX_op_ext8s_i32:

        tcg_out_ext8s(s, COND_AL, args[0], args[1]);

        break;

    case INDEX_op_ext16s_i32:

        tcg_out_ext16s(s, COND_AL, args[0], args[1]);

        break;

    case INDEX_op_ext16u_i32:

        tcg_out_ext16u(s, COND_AL, args[0], args[1]);

        break;

    default:

        tcg_abort();

    }

}


void hmp_info_vnc(Monitor *mon, const QDict *qdict)

{

    VncInfo *info;

    Error *err = NULL;

    VncClientInfoList *client;

    info = qmp_query_vnc(&err);

    if (err) {

        monitor_printf(mon, "%s\n", error_get_pretty(err));

        error_free(err);

        return;

    }

    if (!info->enabled) {

        monitor_printf(mon, "Server: disabled\n");

        goto out;

    }

    monitor_printf(mon, "Server:\n");

    if (info->has_host && info->has_service) {

        monitor_printf(mon, "     address: %s:%s\n", info->host, info->service);

    }

    if (info->has_auth) {

        monitor_printf(mon, "        auth: %s\n", info->auth);

    }

    if (!info->has_clients || info->clients == NULL) {

        monitor_printf(mon, "Client: none\n");

    } else {

        for (client = info->clients; client; client = client->next) {

            monitor_printf(mon, "Client:\n");

            monitor_printf(mon, "     address: %s:%s\n",

                           client->value->base->host,

                           client->value->base->service);

            monitor_printf(mon, "  x509_dname: %s\n",

                           client->value->x509_dname ?

                           client->value->x509_dname : "none");

            monitor_printf(mon, "    username: %s\n",

                           client->value->has_sasl_username ?

                           client->value->sasl_username : "none");

        }

    }

out:

    qapi_free_VncInfo(info);

}


static void cmos_init(int ram_size, const char *boot_device, BlockDriverState **hd_table)

{

    RTCState *s = rtc_state;

    int val;

    int fd0, fd1, nb;

    int i;

    /* various important CMOS locations needed by PC/Bochs bios */

    /* memory size */

    val = 640; /* base memory in K */

    rtc_set_memory(s, 0x15, val);

    rtc_set_memory(s, 0x16, val >> 8);

    val = (ram_size / 1024) - 1024;

    if (val > 65535)

        val = 65535;

    rtc_set_memory(s, 0x17, val);

    rtc_set_memory(s, 0x18, val >> 8);

    rtc_set_memory(s, 0x30, val);

    rtc_set_memory(s, 0x31, val >> 8);

    if (ram_size > (16 * 1024 * 1024))

        val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);

    else

        val = 0;

    if (val > 65535)

        val = 65535;

    rtc_set_memory(s, 0x34, val);

    rtc_set_memory(s, 0x35, val >> 8);

    /* set boot devices, and disable floppy signature check if requested */

    rtc_set_memory(s, 0x3d,

            boot_device2nibble(boot_device[1]) << 4 |

            boot_device2nibble(boot_device[0]) );

    rtc_set_memory(s, 0x38,

            boot_device2nibble(boot_device[2]) << 4 | (fd_bootchk ?  0x0 : 0x1));

    /* floppy type */

    fd0 = fdctrl_get_drive_type(floppy_controller, 0);

    fd1 = fdctrl_get_drive_type(floppy_controller, 1);

    val = (cmos_get_fd_drive_type(fd0) << 4) | cmos_get_fd_drive_type(fd1);

    rtc_set_memory(s, 0x10, val);

    val = 0;

    nb = 0;

    if (fd0 < 3)

        nb++;

    if (fd1 < 3)

        nb++;

    switch (nb) {

    case 0:

        break;

    case 1:

        val |= 0x01; /* 1 drive, ready for boot */

        break;

    case 2:

        val |= 0x41; /* 2 drives, ready for boot */

        break;

    }

    val |= 0x02; /* FPU is there */

    val |= 0x04; /* PS/2 mouse installed */

    rtc_set_memory(s, REG_EQUIPMENT_BYTE, val);

    /* hard drives */

    rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0));

    if (hd_table[0])

        cmos_init_hd(0x19, 0x1b, hd_table[0]);

    if (hd_table[1])

        cmos_init_hd(0x1a, 0x24, hd_table[1]);

    val = 0;

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

        if (hd_table[i]) {

            int cylinders, heads, sectors, translation;

            /* NOTE: bdrv_get_geometry_hint() returns the physical

                geometry.  It is always such that: 1 <= sects <= 63, 1

                <= heads <= 16, 1 <= cylinders <= 16383. The BIOS

                geometry can be different if a translation is done. */

            translation = bdrv_get_translation_hint(hd_table[i]);

            if (translation == BIOS_ATA_TRANSLATION_AUTO) {

                bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);

                if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {

                    /* No translation. */

                    translation = 0;

                } else {

                    /* LBA translation. */

                    translation = 1;

                }

            } else {

                translation--;

            }

            val |= translation << (i * 2);

        }

    }

    rtc_set_memory(s, 0x39, val);

}


static int nbd_parse_uri(const char *filename, QDict *options)

{

    URI *uri;

    const char *p;

    QueryParams *qp = NULL;

    int ret = 0;

    bool is_unix;

    uri = uri_parse(filename);

    if (!uri) {

        return -EINVAL;

    }

    /* transport */

    if (!strcmp(uri->scheme, "nbd")) {

        is_unix = false;

    } else if (!strcmp(uri->scheme, "nbd+tcp")) {

        is_unix = false;

    } else if (!strcmp(uri->scheme, "nbd+unix")) {

        is_unix = true;

    } else {

        ret = -EINVAL;

        goto out;

    }

    p = uri->path ? uri->path : "/";

    p += strspn(p, "/");

    if (p[0]) {

        qdict_put(options, "export", qstring_from_str(p));

    }

    qp = query_params_parse(uri->query);

    if (qp->n > 1 || (is_unix && !qp->n) || (!is_unix && qp->n)) {

        ret = -EINVAL;

        goto out;

    }

    if (is_unix) {

        /* nbd+unix:///export?socket=path */

        if (uri->server || uri->port || strcmp(qp->p[0].name, "socket")) {

            ret = -EINVAL;

            goto out;

        }

        qdict_put(options, "server.type", qstring_from_str("unix"));

        qdict_put(options, "server.data.path",

                  qstring_from_str(qp->p[0].value));

    } else {

        QString *host;

        char *port_str;

        /* nbd[+tcp]://host[:port]/export */

        if (!uri->server) {

            ret = -EINVAL;

            goto out;

        }

        /* strip braces from literal IPv6 address */

        if (uri->server[0] == '[') {

            host = qstring_from_substr(uri->server, 1,

                                       strlen(uri->server) - 2);

        } else {

            host = qstring_from_str(uri->server);

        }

        qdict_put(options, "server.type", qstring_from_str("inet"));

        qdict_put(options, "server.data.host", host);

        port_str = g_strdup_printf("%d", uri->port ?: NBD_DEFAULT_PORT);

        qdict_put(options, "server.data.port", qstring_from_str(port_str));

        g_free(port_str);

    }

out:

    if (qp) {

        query_params_free(qp);

    }

    uri_free(uri);

    return ret;

}


static void disas_ldst_excl(DisasContext *s, uint32_t insn)

{

    int rt = extract32(insn, 0, 5);

    int rn = extract32(insn, 5, 5);

    int rt2 = extract32(insn, 10, 5);

    int is_lasr = extract32(insn, 15, 1);

    int rs = extract32(insn, 16, 5);

    int is_pair = extract32(insn, 21, 1);

    int is_store = !extract32(insn, 22, 1);

    int is_excl = !extract32(insn, 23, 1);

    int size = extract32(insn, 30, 2);

    TCGv_i64 tcg_addr;

    if ((!is_excl && !is_lasr) ||

        (is_pair && size < 2)) {

        unallocated_encoding(s);

        return;

    }

    if (rn == 31) {

        gen_check_sp_alignment(s);

    }

    tcg_addr = read_cpu_reg_sp(s, rn, 1);

    /* Note that since TCG is single threaded load-acquire/store-release

     * semantics require no extra if (is_lasr) { ... } handling.

     */

    if (is_excl) {

        if (!is_store) {

            s->is_ldex = true;

            gen_load_exclusive(s, rt, rt2, tcg_addr, size, is_pair);

        } else {

            gen_store_exclusive(s, rs, rt, rt2, tcg_addr, size, is_pair);

        }

    } else {

        TCGv_i64 tcg_rt = cpu_reg(s, rt);

        if (is_store) {

            do_gpr_st(s, tcg_rt, tcg_addr, size);

        } else {

            do_gpr_ld(s, tcg_rt, tcg_addr, size, false, false);

        }

        if (is_pair) {

            TCGv_i64 tcg_rt2 = cpu_reg(s, rt);

            tcg_gen_addi_i64(tcg_addr, tcg_addr, 1 << size);

            if (is_store) {

                do_gpr_st(s, tcg_rt2, tcg_addr, size);

            } else {

                do_gpr_ld(s, tcg_rt2, tcg_addr, size, false, false);

            }

        }

    }

}


static void do_info_uuid(Monitor *mon)

{

    monitor_printf(mon, UUID_FMT "\n", qemu_uuid[0], qemu_uuid[1],

                   qemu_uuid[2], qemu_uuid[3], qemu_uuid[4], qemu_uuid[5],

                   qemu_uuid[6], qemu_uuid[7], qemu_uuid[8], qemu_uuid[9],

                   qemu_uuid[10], qemu_uuid[11], qemu_uuid[12], qemu_uuid[13],

                   qemu_uuid[14], qemu_uuid[15]);

}


void kvm_setup_guest_memory(void *start, size_t size)

{

#ifdef CONFIG_VALGRIND_H

    VALGRIND_MAKE_MEM_DEFINED(start, size);

#endif

    if (!kvm_has_sync_mmu()) {

        int ret = qemu_madvise(start, size, QEMU_MADV_DONTFORK);

        if (ret) {

            perror("qemu_madvise");

            fprintf(stderr,

                    "Need MADV_DONTFORK in absence of synchronous KVM MMU\n");

            exit(1);

        }

    }

}


build_facs(GArray *table_data, GArray *linker)

{

    AcpiFacsDescriptorRev1 *facs = acpi_data_push(table_data, sizeof *facs);

    memcpy(&facs->signature, "FACS", 4);

    facs->length = cpu_to_le32(sizeof(*facs));

}


bool bdrv_debug_is_suspended(BlockDriverState *bs, const char *tag)

{

    while (bs && bs->drv && !bs->drv->bdrv_debug_is_suspended) {

        bs = bs->file;

    }

    if (bs && bs->drv && bs->drv->bdrv_debug_is_suspended) {

        return bs->drv->bdrv_debug_is_suspended(bs, tag);

    }

    return false;

}


AioContext *aio_context_new(void)

{

    AioContext *ctx;

    ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext));

    ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD));

    ctx->thread_pool = NULL;

    qemu_mutex_init(&ctx->bh_lock);

    rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx);

    event_notifier_init(&ctx->notifier, false);

    aio_set_event_notifier(ctx, &ctx->notifier,

                           (EventNotifierHandler *)

                           event_notifier_test_and_clear);

    timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx);

    return ctx;

}


void bdrv_query_info(BlockDriverState *bs,
                     BlockInfo **p_info,
                     Error **errp)
{
    BlockInfo *info = g_malloc0(sizeof(*info));
    BlockDriverState *bs0;
    ImageInfo **p_image_info;
    Error *local_err = NULL;
    info->device = g_strdup(bs->device_name);
    info->type = g_strdup("unknown");
    info->locked = bdrv_dev_is_medium_locked(bs);
    info->removable = bdrv_dev_has_removable_media(bs);
    if (bdrv_dev_has_removable_media(bs)) {
        info->has_tray_open = true;
        info->tray_open = bdrv_dev_is_tray_open(bs);
    }
    if (bdrv_iostatus_is_enabled(bs)) {
        info->has_io_status = true;
        info->io_status = bs->iostatus;
    }
    if (bs->dirty_bitmap) {
        info->has_dirty = true;
        info->dirty = g_malloc0(sizeof(*info->dirty));
        info->dirty->count = bdrv_get_dirty_count(bs) * BDRV_SECTOR_SIZE;
        info->dirty->granularity =
         ((int64_t) BDRV_SECTOR_SIZE << hbitmap_granularity(bs->dirty_bitmap));
    }
    if (bs->drv) {
        info->has_inserted = true;
        info->inserted = g_malloc0(sizeof(*info->inserted));
        info->inserted->file = g_strdup(bs->filename);
        info->inserted->ro = bs->read_only;
        info->inserted->drv = g_strdup(bs->drv->format_name);
        info->inserted->encrypted = bs->encrypted;
        info->inserted->encryption_key_missing = bdrv_key_required(bs);
        if (bs->backing_file[0]) {
            info->inserted->has_backing_file = true;
            info->inserted->backing_file = g_strdup(bs->backing_file);
        }
        info->inserted->backing_file_depth = bdrv_get_backing_file_depth(bs);
        if (bs->io_limits_enabled) {
            ThrottleConfig cfg;
            throttle_get_config(&bs->throttle_state, &cfg);
            info->inserted->bps     = cfg.buckets[THROTTLE_BPS_TOTAL].avg;
            info->inserted->bps_rd  = cfg.buckets[THROTTLE_BPS_READ].avg;
            info->inserted->bps_wr  = cfg.buckets[THROTTLE_BPS_WRITE].avg;
            info->inserted->iops    = cfg.buckets[THROTTLE_OPS_TOTAL].avg;
            info->inserted->iops_rd = cfg.buckets[THROTTLE_OPS_READ].avg;
            info->inserted->iops_wr = cfg.buckets[THROTTLE_OPS_WRITE].avg;
        }
        bs0 = bs;
        p_image_info = &info->inserted->image;
        while (1) {
            bdrv_query_image_info(bs0, p_image_info, &local_err);
            if (error_is_set(&local_err)) {
                error_propagate(errp, local_err);
                goto err;
            }
            if (bs0->drv && bs0->backing_hd) {
                bs0 = bs0->backing_hd;
                (*p_image_info)->has_backing_image = true;
                p_image_info = &((*p_image_info)->backing_image);
            } else {
                break;
            }
        }
    }
    *p_info = info;
    return;
 err:
    qapi_free_BlockInfo(info);
}


static void s390_init(ram_addr_t my_ram_size,

                      const char *boot_device,

                      const char *kernel_filename,

                      const char *kernel_cmdline,

                      const char *initrd_filename,

                      const char *cpu_model)

{

    CPUState *env = NULL;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    ram_addr_t kernel_size = 0;

    ram_addr_t initrd_offset;

    ram_addr_t initrd_size = 0;

    int shift = 0;

    uint8_t *storage_keys;

    void *virtio_region;

    target_phys_addr_t virtio_region_len;

    target_phys_addr_t virtio_region_start;

    int i;

    /* s390x ram size detection needs a 16bit multiplier + an increment. So

       guests > 64GB can be specified in 2MB steps etc. */

    while ((my_ram_size >> (20 + shift)) > 65535) {

        shift++;

    }

    my_ram_size = my_ram_size >> (20 + shift) << (20 + shift);

    /* lets propagate the changed ram size into the global variable. */

    ram_size = my_ram_size;

    /* get a BUS */

    s390_bus = s390_virtio_bus_init(&my_ram_size);

    /* allocate RAM */

    memory_region_init_ram(ram, "s390.ram", my_ram_size);

    vmstate_register_ram_global(ram);

    memory_region_add_subregion(sysmem, 0, ram);

    /* clear virtio region */

    virtio_region_len = my_ram_size - ram_size;

    virtio_region_start = ram_size;

    virtio_region = cpu_physical_memory_map(virtio_region_start,

                                            &virtio_region_len, true);

    memset(virtio_region, 0, virtio_region_len);

    cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1,

                              virtio_region_len);

    /* allocate storage keys */

    storage_keys = g_malloc0(my_ram_size / TARGET_PAGE_SIZE);

    /* init CPUs */

    if (cpu_model == NULL) {

        cpu_model = "host";

    }

    ipi_states = g_malloc(sizeof(CPUState *) * smp_cpus);

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

        CPUState *tmp_env;

        tmp_env = cpu_init(cpu_model);

        if (!env) {

            env = tmp_env;

        }

        ipi_states[i] = tmp_env;

        tmp_env->halted = 1;

        tmp_env->exception_index = EXCP_HLT;

        tmp_env->storage_keys = storage_keys;

    }

    /* One CPU has to run */

    s390_add_running_cpu(env);

    if (kernel_filename) {

        kernel_size = load_image(kernel_filename, qemu_get_ram_ptr(0));

        if (lduw_be_phys(KERN_IMAGE_START) != 0x0dd0) {

            fprintf(stderr, "Specified image is not an s390 boot image\n");

            exit(1);

        }

        env->psw.addr = KERN_IMAGE_START;

        env->psw.mask = 0x0000000180000000ULL;

    } else {

        ram_addr_t bios_size = 0;

        char *bios_filename;

        /* Load zipl bootloader */

        if (bios_name == NULL) {

            bios_name = ZIPL_FILENAME;

        }

        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

        bios_size = load_image(bios_filename, qemu_get_ram_ptr(ZIPL_LOAD_ADDR));

        g_free(bios_filename);

        if ((long)bios_size < 0) {

            hw_error("could not load bootloader '%s'\n", bios_name);

        }

        if (bios_size > 4096) {

            hw_error("stage1 bootloader is > 4k\n");

        }

        env->psw.addr = ZIPL_START;

        env->psw.mask = 0x0000000180000000ULL;

    }

    if (initrd_filename) {

        initrd_offset = INITRD_START;

        while (kernel_size + 0x100000 > initrd_offset) {

            initrd_offset += 0x100000;

        }

        initrd_size = load_image(initrd_filename, qemu_get_ram_ptr(initrd_offset));

        stq_be_phys(INITRD_PARM_START, initrd_offset);

        stq_be_phys(INITRD_PARM_SIZE, initrd_size);

    }

    if (kernel_cmdline) {

        cpu_physical_memory_write(KERN_PARM_AREA, kernel_cmdline,

                                  strlen(kernel_cmdline) + 1);

    }

    /* Create VirtIO network adapters */

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

        NICInfo *nd = &nd_table[i];

        DeviceState *dev;

        if (!nd->model) {

            nd->model = g_strdup("virtio");

        }

        if (strcmp(nd->model, "virtio")) {

            fprintf(stderr, "S390 only supports VirtIO nics\n");

            exit(1);

        }

        dev = qdev_create((BusState *)s390_bus, "virtio-net-s390");

        qdev_set_nic_properties(dev, nd);

        qdev_init_nofail(dev);

    }

    /* Create VirtIO disk drives */

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

        DriveInfo *dinfo;

        DeviceState *dev;

        dinfo = drive_get(IF_IDE, 0, i);

        if (!dinfo) {

            continue;

        }

        dev = qdev_create((BusState *)s390_bus, "virtio-blk-s390");

        qdev_prop_set_drive_nofail(dev, "drive", dinfo->bdrv);

        qdev_init_nofail(dev);

    }

}


static int do_break(CPUMIPSState *env, target_siginfo_t *info,

                    unsigned int code)

{

    int ret = -1;

    switch (code) {

    case BRK_OVERFLOW:

    case BRK_DIVZERO:

        info->si_signo = TARGET_SIGFPE;

        info->si_code = (code == BRK_OVERFLOW) ? FPE_INTOVF : FPE_INTDIV;

        break;

    default:

        break;

    }

    return ret;

}


static uint16_t qpci_pc_config_readw(QPCIBus *bus, int devfn, uint8_t offset)

{

    outl(0xcf8, (1 << 31) | (devfn << 8) | offset);

    return inw(0xcfc);

}


int kvm_arch_put_registers(CPUState *env, int level)

{

    int ret;

    assert(cpu_is_stopped(env) || qemu_cpu_is_self(env));

    ret = kvm_getput_regs(env, 1);

    ret = kvm_put_xsave(env);

    ret = kvm_put_xcrs(env);

    ret = kvm_put_sregs(env);

    ret = kvm_put_msrs(env, level);

    if (level >= KVM_PUT_RESET_STATE) {

        ret = kvm_put_mp_state(env);

    ret = kvm_put_vcpu_events(env, level);

    ret = kvm_put_debugregs(env);

    /* must be last */

    ret = kvm_guest_debug_workarounds(env);

    return 0;


static QObject *get_stats_qobject(VirtIOBalloon *dev)

{

    QDict *dict = qdict_new();

    uint32_t actual = ram_size - (dev->actual << VIRTIO_BALLOON_PFN_SHIFT);

    stat_put(dict, "actual", actual);

    stat_put(dict, "mem_swapped_in", dev->stats[VIRTIO_BALLOON_S_SWAP_IN]);

    stat_put(dict, "mem_swapped_out", dev->stats[VIRTIO_BALLOON_S_SWAP_OUT]);

    stat_put(dict, "major_page_faults", dev->stats[VIRTIO_BALLOON_S_MAJFLT]);

    stat_put(dict, "minor_page_faults", dev->stats[VIRTIO_BALLOON_S_MINFLT]);

    stat_put(dict, "free_mem", dev->stats[VIRTIO_BALLOON_S_MEMFREE]);

    stat_put(dict, "total_mem", dev->stats[VIRTIO_BALLOON_S_MEMTOT]);

    return QOBJECT(dict);

}


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

                                const AVFrame *frame, int *got_packet_ptr)

{

    TWOLAMEContext *s = avctx->priv_data;

    int ret;

    if ((ret = ff_alloc_packet(avpkt, MPA_MAX_CODED_FRAME_SIZE)) < 0)

        return ret;

    if (frame) {

        switch (avctx->sample_fmt) {

        case AV_SAMPLE_FMT_FLT:

            ret = twolame_encode_buffer_float32_interleaved(s->glopts,

                                                            (const float *)frame->data[0],

                                                            frame->nb_samples,

                                                            avpkt->data,

                                                            avpkt->size);

            break;

        case AV_SAMPLE_FMT_FLTP:

            ret = twolame_encode_buffer_float32(s->glopts,

                                                (const float *)frame->data[0],

                                                (const float *)frame->data[1],

                                                frame->nb_samples,

                                                avpkt->data, avpkt->size);

            break;

        case AV_SAMPLE_FMT_S16:

            ret = twolame_encode_buffer_interleaved(s->glopts,

                                                    (const short int *)frame->data[0],

                                                    frame->nb_samples,

                                                    avpkt->data, avpkt->size);

            break;

        case AV_SAMPLE_FMT_S16P:

            ret = twolame_encode_buffer(s->glopts,

                                        (const short int *)frame->data[0],

                                        (const short int *)frame->data[1],

                                        frame->nb_samples,

                                        avpkt->data, avpkt->size);

            break;

        default:

            av_log(avctx, AV_LOG_ERROR,

                   "Unsupported sample format %d.\n", avctx->sample_fmt);

            return AVERROR_BUG;

        }

    } else {

        ret = twolame_encode_flush(s->glopts, avpkt->data, avpkt->size);

    }

    if (!ret)     // no bytes written

        return 0;

    if (ret < 0)  // twolame error

        return AVERROR_UNKNOWN;

    avpkt->duration = ff_samples_to_time_base(avctx, frame->nb_samples);

    if (frame) {

        if (frame->pts != AV_NOPTS_VALUE)

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

    } else {

        avpkt->pts = s->next_pts;

    }

    // this is for setting pts for flushed packet(s).

    if (avpkt->pts != AV_NOPTS_VALUE)

        s->next_pts = avpkt->pts + avpkt->duration;

    av_shrink_packet(avpkt, ret);

    *got_packet_ptr = 1;

    return 0;

}


yuv2rgb_full_X_c_template(SwsContext *c, const int16_t *lumFilter,

                          const int16_t **lumSrc, int lumFilterSize,

                          const int16_t *chrFilter, const int16_t **chrUSrc,

                          const int16_t **chrVSrc, int chrFilterSize,

                          const int16_t **alpSrc, uint8_t *dest,

                          int dstW, int y, enum AVPixelFormat target, int hasAlpha)

{

    int i;

    int step = (target == AV_PIX_FMT_RGB24 || target == AV_PIX_FMT_BGR24) ? 3 : 4;

    int err[4] = {0};

    if(   target == AV_PIX_FMT_BGR4_BYTE || target == AV_PIX_FMT_RGB4_BYTE

       || target == AV_PIX_FMT_BGR8      || target == AV_PIX_FMT_RGB8)

        step = 1;

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

        int j;

        int Y = 1<<9;

        int U = (1<<9)-(128 << 19);

        int V = (1<<9)-(128 << 19);

        int A;

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

            Y += lumSrc[j][i] * lumFilter[j];

        }

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

            U += chrUSrc[j][i] * chrFilter[j];

            V += chrVSrc[j][i] * chrFilter[j];

        }

        Y >>= 10;

        U >>= 10;

        V >>= 10;

        if (hasAlpha) {

            A = 1 << 18;

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

                A += alpSrc[j][i] * lumFilter[j];

            }

            A >>= 19;

            if (A & 0x100)

                A = av_clip_uint8(A);

        }

        yuv2rgb_write_full(c, dest, i, Y, A, U, V, y, target, hasAlpha, err);

        dest += step;

    }

    c->dither_error[0][i] = err[0];

    c->dither_error[1][i] = err[1];

    c->dither_error[2][i] = err[2];

}