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

                             AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    const uint8_t *buf_end = buf + buf_size;

    DPCMContext *s = avctx->priv_data;

    int out = 0;

    int predictor[2];

    int ch = 0;

    int stereo = s->channels - 1;

    int16_t *output_samples = data;

    if (!buf_size)

        return 0;

    /* calculate output size */

    switch(avctx->codec->id) {

    case CODEC_ID_ROQ_DPCM:

        out = buf_size - 8;

        break;

    case CODEC_ID_INTERPLAY_DPCM:

        out = buf_size - 6 - s->channels;

        break;

    case CODEC_ID_XAN_DPCM:

        out = buf_size - 2 * s->channels;

        break;

    case CODEC_ID_SOL_DPCM:

        if (avctx->codec_tag != 3)

            out = buf_size * 2;

        else

            out = buf_size;

        break;

    }

    out *= av_get_bytes_per_sample(avctx->sample_fmt);

    if (out < 0) {

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

        return AVERROR(EINVAL);

    }

    if (*data_size < out) {

        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");

        return AVERROR(EINVAL);

    }

    switch(avctx->codec->id) {

    case CODEC_ID_ROQ_DPCM:

        buf += 6;

        if (stereo) {

            predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8);

            predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8);

        } else {

            predictor[0] = (int16_t)bytestream_get_le16(&buf);

        }

        /* decode the samples */

        while (buf < buf_end) {

            predictor[ch] += s->roq_square_array[*buf++];

            predictor[ch]  = av_clip_int16(predictor[ch]);

            *output_samples++ = predictor[ch];

            /* toggle channel */

            ch ^= stereo;

        }

        break;

    case CODEC_ID_INTERPLAY_DPCM:

        buf += 6;  /* skip over the stream mask and stream length */

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

            predictor[ch] = (int16_t)bytestream_get_le16(&buf);

            *output_samples++ = predictor[ch];

        }

        ch = 0;

        while (buf < buf_end) {

            predictor[ch] += interplay_delta_table[*buf++];

            predictor[ch]  = av_clip_int16(predictor[ch]);

            *output_samples++ = predictor[ch];

            /* toggle channel */

            ch ^= stereo;

        }

        break;

    case CODEC_ID_XAN_DPCM:

    {

        int shift[2] = { 4, 4 };

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

            predictor[ch] = (int16_t)bytestream_get_le16(&buf);

        ch = 0;

        while (buf < buf_end) {

            uint8_t n = *buf++;

            int16_t diff = (n & 0xFC) << 8;

            if ((n & 0x03) == 3)

                shift[ch]++;

            else

                shift[ch] -= (2 * (n & 3));

            /* saturate the shifter to a lower limit of 0 */

            if (shift[ch] < 0)

                shift[ch] = 0;

            diff >>= shift[ch];

            predictor[ch] += diff;

            predictor[ch] = av_clip_int16(predictor[ch]);

            *output_samples++ = predictor[ch];

            /* toggle channel */

            ch ^= stereo;

        }

        break;

    }

    case CODEC_ID_SOL_DPCM:

        if (avctx->codec_tag != 3) {

            uint8_t *output_samples_u8 = data;

            while (buf < buf_end) {

                uint8_t n = *buf++;

                s->sample[0] += s->sol_table[n >> 4];

                s->sample[0]  = av_clip_uint8(s->sample[0]);

                *output_samples_u8++ = s->sample[0];

                s->sample[stereo] += s->sol_table[n & 0x0F];

                s->sample[stereo]  = av_clip_uint8(s->sample[stereo]);

                *output_samples_u8++ = s->sample[stereo];

            }

        } else {

            while (buf < buf_end) {

                uint8_t n = *buf++;

                if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];

                else          s->sample[ch] += sol_table_16[n & 0x7F];

                s->sample[ch] = av_clip_int16(s->sample[ch]);

                *output_samples++ = s->sample[ch];

                /* toggle channel */

                ch ^= stereo;

            }

        }

        break;

    }

    *data_size = out;

    return buf_size;

}


static void gen_logicq_cc(TCGv_i64 val)

{

    TCGv tmp = new_tmp();

    gen_helper_logicq_cc(tmp, val);

    gen_logic_CC(tmp);

    dead_tmp(tmp);

}


static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,

                                         uint64_t bytes, QEMUIOVector *qiov,

                                         int flags)

{

    BDRVQcow2State *s = bs->opaque;

    int offset_in_cluster;

    int ret;

    unsigned int cur_bytes; /* number of sectors in current iteration */

    uint64_t cluster_offset;

    QEMUIOVector hd_qiov;

    uint64_t bytes_done = 0;

    uint8_t *cluster_data = NULL;

    QCowL2Meta *l2meta = NULL;

    trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes);

    qemu_iovec_init(&hd_qiov, qiov->niov);

    s->cluster_cache_offset = -1; /* disable compressed cache */

    qemu_co_mutex_lock(&s->lock);

    while (bytes != 0) {

        l2meta = NULL;

        trace_qcow2_writev_start_part(qemu_coroutine_self());

        offset_in_cluster = offset_into_cluster(s, offset);

        cur_bytes = MIN(bytes, INT_MAX);

        if (bs->encrypted) {

            cur_bytes = MIN(cur_bytes,

                            QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size

                            - offset_in_cluster);

        }

        ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes,

                                         &cluster_offset, &l2meta);

        if (ret < 0) {

            goto fail;

        }

        assert((cluster_offset & 511) == 0);

        qemu_iovec_reset(&hd_qiov);

        qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes);

        if (bs->encrypted) {

            Error *err = NULL;

            assert(s->crypto);

            if (!cluster_data) {

                cluster_data = qemu_try_blockalign(bs->file->bs,

                                                   QCOW_MAX_CRYPT_CLUSTERS

                                                   * s->cluster_size);

                if (cluster_data == NULL) {

                    ret = -ENOMEM;

                    goto fail;

                }

            }

            assert(hd_qiov.size <=

                   QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size);

            qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size);

            if (qcrypto_block_encrypt(s->crypto, offset >> BDRV_SECTOR_BITS,

                                      cluster_data,

                                      cur_bytes, &err) < 0) {

                error_free(err);

                ret = -EIO;

                goto fail;

            }

            qemu_iovec_reset(&hd_qiov);

            qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes);

        }

        ret = qcow2_pre_write_overlap_check(bs, 0,

                cluster_offset + offset_in_cluster, cur_bytes);

        if (ret < 0) {

            goto fail;

        }

        /* If we need to do COW, check if it's possible to merge the

         * writing of the guest data together with that of the COW regions.

         * If it's not possible (or not necessary) then write the

         * guest data now. */

        if (!merge_cow(offset, cur_bytes, &hd_qiov, l2meta)) {

            qemu_co_mutex_unlock(&s->lock);

            BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);

            trace_qcow2_writev_data(qemu_coroutine_self(),

                                    cluster_offset + offset_in_cluster);

            ret = bdrv_co_pwritev(bs->file,

                                  cluster_offset + offset_in_cluster,

                                  cur_bytes, &hd_qiov, 0);

            qemu_co_mutex_lock(&s->lock);

            if (ret < 0) {

                goto fail;

            }

        }

        while (l2meta != NULL) {

            QCowL2Meta *next;

            ret = qcow2_alloc_cluster_link_l2(bs, l2meta);

            if (ret < 0) {

                goto fail;

            }

            /* Take the request off the list of running requests */

            if (l2meta->nb_clusters != 0) {

                QLIST_REMOVE(l2meta, next_in_flight);

            }

            qemu_co_queue_restart_all(&l2meta->dependent_requests);

            next = l2meta->next;

            g_free(l2meta);

            l2meta = next;

        }

        bytes -= cur_bytes;

        offset += cur_bytes;

        bytes_done += cur_bytes;

        trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_bytes);

    }

    ret = 0;

fail:

    qemu_co_mutex_unlock(&s->lock);

    while (l2meta != NULL) {

        QCowL2Meta *next;

        if (l2meta->nb_clusters != 0) {

            QLIST_REMOVE(l2meta, next_in_flight);

        }

        qemu_co_queue_restart_all(&l2meta->dependent_requests);

        next = l2meta->next;

        g_free(l2meta);

        l2meta = next;

    }

    qemu_iovec_destroy(&hd_qiov);

    qemu_vfree(cluster_data);

    trace_qcow2_writev_done_req(qemu_coroutine_self(), ret);

    return ret;

}


static int ape_probe(AVProbeData * p)

{

    if (p->buf[0] == 'M' && p->buf[1] == 'A' && p->buf[2] == 'C' && p->buf[3] == ' ')

        return AVPROBE_SCORE_MAX;

    return 0;

}


static void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *dst2,

                                 int dstWidth, const uint8_t *src1,

                                 const uint8_t *src2, int srcW, int xInc)

{

    int16_t *filterPos = c->hChrFilterPos;

    int16_t *filter    = c->hChrFilter;

    void    *mmx2FilterCode= c->chrMmx2FilterCode;

    int i;

#if defined(PIC)

    DECLARE_ALIGNED(8, uint64_t, ebxsave);

#endif

#if ARCH_X86_64

    DECLARE_ALIGNED(8, uint64_t, retsave);

#endif

    __asm__ volatile(

#if defined(PIC)

        "mov          %%"REG_b", %7         \n\t"

#if ARCH_X86_64

        "mov          -8(%%rsp), %%"REG_a"  \n\t"

        "mov          %%"REG_a", %8         \n\t"

#endif

#else

#if ARCH_X86_64

        "mov          -8(%%rsp), %%"REG_a"  \n\t"

        "mov          %%"REG_a", %7         \n\t"

#endif

#endif

        "pxor             %%mm7, %%mm7      \n\t"

        "mov                 %0, %%"REG_c"  \n\t"

        "mov                 %1, %%"REG_D"  \n\t"

        "mov                 %2, %%"REG_d"  \n\t"

        "mov                 %3, %%"REG_b"  \n\t"

        "xor          %%"REG_a", %%"REG_a"  \n\t" // i

        PREFETCH"   (%%"REG_c")             \n\t"

        PREFETCH" 32(%%"REG_c")             \n\t"

        PREFETCH" 64(%%"REG_c")             \n\t"

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        "xor          %%"REG_a", %%"REG_a"  \n\t" // i

        "mov                 %5, %%"REG_c"  \n\t" // src

        "mov                 %6, %%"REG_D"  \n\t" // buf2

        PREFETCH"   (%%"REG_c")             \n\t"

        PREFETCH" 32(%%"REG_c")             \n\t"

        PREFETCH" 64(%%"REG_c")             \n\t"

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

        CALL_MMX2_FILTER_CODE

#if defined(PIC)

        "mov %7, %%"REG_b"    \n\t"

#if ARCH_X86_64

        "mov                 %8, %%"REG_a"  \n\t"

        "mov          %%"REG_a", -8(%%rsp)  \n\t"

#endif

#else

#if ARCH_X86_64

        "mov                 %7, %%"REG_a"  \n\t"

        "mov          %%"REG_a", -8(%%rsp)  \n\t"

#endif

#endif

        :: "m" (src1), "m" (dst1), "m" (filter), "m" (filterPos),

           "m" (mmx2FilterCode), "m" (src2), "m"(dst2)

#if defined(PIC)

          ,"m" (ebxsave)

#endif

#if ARCH_X86_64

          ,"m"(retsave)

#endif

        : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D

#if !defined(PIC)

         ,"%"REG_b

#endif

    );

    for (i=dstWidth-1; (i*xInc)>>16 >=srcW-1; i--) {

        dst1[i] = src1[srcW-1]*128;

        dst2[i] = src2[srcW-1]*128;

    }

}


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

{

    DeviceClass *k = DEVICE_CLASS(klass);

    k->init = ide_qdev_init;

    set_bit(DEVICE_CATEGORY_STORAGE, k->categories);

    k->bus_type = TYPE_IDE_BUS;

    k->props = ide_props;

}


void memory_region_del_eventfd(MemoryRegion *mr,

                               hwaddr addr,

                               unsigned size,

                               bool match_data,

                               uint64_t data,

                               EventNotifier *e)

{

    MemoryRegionIoeventfd mrfd = {

        .addr.start = int128_make64(addr),

        .addr.size = int128_make64(size),

        .match_data = match_data,

        .data = data,

        .e = e,

    };

    unsigned i;

    adjust_endianness(mr, &mrfd.data, size);

    memory_region_transaction_begin();

    for (i = 0; i < mr->ioeventfd_nb; ++i) {

        if (memory_region_ioeventfd_equal(mrfd, mr->ioeventfds[i])) {

            break;

        }

    }

    assert(i != mr->ioeventfd_nb);

    memmove(&mr->ioeventfds[i], &mr->ioeventfds[i+1],

            sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb - (i+1)));

    --mr->ioeventfd_nb;

    mr->ioeventfds = g_realloc(mr->ioeventfds,

                                  sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1);

    ioeventfd_update_pending |= mr->enabled;

    memory_region_transaction_commit();

}


void pc_system_firmware_init(MemoryRegion *rom_memory)

{

    DriveInfo *pflash_drv;

    PcSysFwDevice *sysfw_dev;

    /*

     * TODO This device exists only so that users can switch between

     * use of flash and ROM for the BIOS.  The ability to switch was

     * created because flash doesn't work with KVM.  Once it does, we

     * should drop this device for new machine types.

     */

    sysfw_dev = (PcSysFwDevice*) qdev_create(NULL, "pc-sysfw");

    qdev_init_nofail(DEVICE(sysfw_dev));

    if (sysfw_dev->rom_only) {

        old_pc_system_rom_init(rom_memory);

        return;

    }

    pflash_drv = drive_get(IF_PFLASH, 0, 0);

    /* Currently KVM cannot execute from device memory.

       Use old rom based firmware initialization for KVM. */

    /*

     * This is a Bad Idea, because it makes enabling/disabling KVM

     * guest-visible.  Do it only in bug-compatibility mode.

     */

    if (pc_sysfw_flash_vs_rom_bug_compatible && kvm_enabled()) {

        if (pflash_drv != NULL) {

            fprintf(stderr, "qemu: pflash cannot be used with kvm enabled\n");

            exit(1);

        } else {

            sysfw_dev->rom_only = 1;

            old_pc_system_rom_init(rom_memory);

            return;

        }

    }

    /* If a pflash drive is not found, then create one using

       the bios filename. */

    if (pflash_drv == NULL) {

        pc_fw_add_pflash_drv();

        pflash_drv = drive_get(IF_PFLASH, 0, 0);

    }

    if (pflash_drv != NULL) {

        pc_system_flash_init(rom_memory, pflash_drv);

    } else {

        fprintf(stderr, "qemu: PC system firmware (pflash) not available\n");

        exit(1);

    }

}


static int32_t scalarproduct_and_madd_int32_c(int16_t *v1, const int32_t *v2,

                                              const int16_t *v3,

                                              int order, int mul)

{

    int res = 0;

    while (order--) {

        res   += *v1 * *v2++;

        *v1++ += mul * *v3++;

    }

    return res;

}


static int spapr_nvram_init(VIOsPAPRDevice *dev)

{

    sPAPRNVRAM *nvram = VIO_SPAPR_NVRAM(dev);

    if (nvram->drive) {

        nvram->size = bdrv_getlength(nvram->drive);

    } else {

        nvram->size = DEFAULT_NVRAM_SIZE;

        nvram->buf = g_malloc0(nvram->size);

    }

    if ((nvram->size < MIN_NVRAM_SIZE) || (nvram->size > MAX_NVRAM_SIZE)) {

        fprintf(stderr, "spapr-nvram must be between %d and %d bytes in size\n",

                MIN_NVRAM_SIZE, MAX_NVRAM_SIZE);

        return -1;

    }

    spapr_rtas_register("nvram-fetch", rtas_nvram_fetch);

    spapr_rtas_register("nvram-store", rtas_nvram_store);

    return 0;

}


static CharDriverState *qemu_chr_open_pp(QemuOpts *opts)

{

    const char *filename = qemu_opt_get(opts, "path");

    CharDriverState *chr;

    int fd;

    fd = open(filename, O_RDWR);

    if (fd < 0)

        return NULL;

    chr = g_malloc0(sizeof(CharDriverState));

    chr->opaque = (void *)(intptr_t)fd;

    chr->chr_write = null_chr_write;

    chr->chr_ioctl = pp_ioctl;

    return chr;

}


static void pvpanic_fw_cfg(ISADevice *dev, FWCfgState *fw_cfg)

{

    PVPanicState *s = ISA_PVPANIC_DEVICE(dev);

    fw_cfg_add_file(fw_cfg, "etc/pvpanic-port",

                    g_memdup(&s->ioport, sizeof(s->ioport)),

                    sizeof(s->ioport));

}


int net_client_init(Monitor *mon, const char *device, const char *p)

{

    char buf[1024];

    int vlan_id, ret;

    VLANState *vlan;

    char *name = NULL;

    vlan_id = 0;

    if (get_param_value(buf, sizeof(buf), "vlan", p)) {

        vlan_id = strtol(buf, NULL, 0);

    }

    vlan = qemu_find_vlan(vlan_id, 1);

    if (get_param_value(buf, sizeof(buf), "name", p)) {

        name = qemu_strdup(buf);

    }

    if (!strcmp(device, "nic")) {

        static const char * const nic_params[] = {

            "vlan", "name", "macaddr", "model", "addr", "id", "vectors", NULL

        };

        NICInfo *nd;

        uint8_t *macaddr;

        int idx = nic_get_free_idx();

        if (check_params(buf, sizeof(buf), nic_params, p) < 0) {

            config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);

            ret = -1;

            goto out;

        }

        if (idx == -1 || nb_nics >= MAX_NICS) {

            config_error(mon, "Too Many NICs\n");

            ret = -1;

            goto out;

        }

        nd = &nd_table[idx];

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

        macaddr = nd->macaddr;

        macaddr[0] = 0x52;

        macaddr[1] = 0x54;

        macaddr[2] = 0x00;

        macaddr[3] = 0x12;

        macaddr[4] = 0x34;

        macaddr[5] = 0x56 + idx;

        if (get_param_value(buf, sizeof(buf), "macaddr", p)) {

            if (parse_macaddr(macaddr, buf) < 0) {

                config_error(mon, "invalid syntax for ethernet address\n");

                ret = -1;

                goto out;

            }

        }

        if (get_param_value(buf, sizeof(buf), "model", p)) {

            nd->model = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "addr", p)) {

            nd->devaddr = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "id", p)) {

            nd->id = qemu_strdup(buf);

        }

        nd->nvectors = NIC_NVECTORS_UNSPECIFIED;

        if (get_param_value(buf, sizeof(buf), "vectors", p)) {

            char *endptr;

            long vectors = strtol(buf, &endptr, 0);

            if (*endptr) {

                config_error(mon, "invalid syntax for # of vectors\n");

                ret = -1;

                goto out;

            }

            if (vectors < 0 || vectors > 0x7ffffff) {

                config_error(mon, "invalid # of vectors\n");

                ret = -1;

                goto out;

            }

            nd->nvectors = vectors;

        }

        nd->vlan = vlan;

        nd->name = name;

        nd->used = 1;

        name = NULL;

        nb_nics++;

        vlan->nb_guest_devs++;

        ret = idx;

    } else

    if (!strcmp(device, "none")) {

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

            config_error(mon, "'none' takes no parameters\n");

            ret = -1;

            goto out;

        }

        /* does nothing. It is needed to signal that no network cards

           are wanted */

        ret = 0;

    } else

#ifdef CONFIG_SLIRP

    if (!strcmp(device, "user")) {

        static const char * const slirp_params[] = {

            "vlan", "name", "hostname", "restrict", "ip", "net", "host",

            "tftp", "bootfile", "dhcpstart", "dns", "smb", "smbserver",

            "hostfwd", "guestfwd", NULL

        };

        struct slirp_config_str *config;

        int restricted = 0;

        char *vnet = NULL;

        char *vhost = NULL;

        char *vhostname = NULL;

        char *tftp_export = NULL;

        char *bootfile = NULL;

        char *vdhcp_start = NULL;

        char *vnamesrv = NULL;

        char *smb_export = NULL;

        char *vsmbsrv = NULL;

        const char *q;

        if (check_params(buf, sizeof(buf), slirp_params, p) < 0) {

            config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);

            ret = -1;

            goto out;

        }

        if (get_param_value(buf, sizeof(buf), "ip", p)) {

            int vnet_buflen = strlen(buf) + strlen("/24") + 1;

            /* emulate legacy parameter */

            vnet = qemu_malloc(vnet_buflen);

            pstrcpy(vnet, vnet_buflen, buf);

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

        }

        if (get_param_value(buf, sizeof(buf), "net", p)) {

            vnet = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "host", p)) {

            vhost = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "hostname", p)) {

            vhostname = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "restrict", p)) {

            restricted = (buf[0] == 'y') ? 1 : 0;

        }

        if (get_param_value(buf, sizeof(buf), "dhcpstart", p)) {

            vdhcp_start = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "dns", p)) {

            vnamesrv = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "tftp", p)) {

            tftp_export = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "bootfile", p)) {

            bootfile = qemu_strdup(buf);

        }

        if (get_param_value(buf, sizeof(buf), "smb", p)) {

            smb_export = qemu_strdup(buf);

            if (get_param_value(buf, sizeof(buf), "smbserver", p)) {

                vsmbsrv = qemu_strdup(buf);

            }

        }

        q = p;

        while (1) {

            config = qemu_malloc(sizeof(*config));

            if (!get_next_param_value(config->str, sizeof(config->str),

                                      "hostfwd", &q)) {

                break;

            }

            config->flags = SLIRP_CFG_HOSTFWD;

            config->next = slirp_configs;

            slirp_configs = config;

            config = NULL;

        }

        q = p;

        while (1) {

            config = qemu_malloc(sizeof(*config));

            if (!get_next_param_value(config->str, sizeof(config->str),

                                      "guestfwd", &q)) {

                break;

            }

            config->flags = 0;

            config->next = slirp_configs;

            slirp_configs = config;

            config = NULL;

        }

        qemu_free(config);

        vlan->nb_host_devs++;

        ret = net_slirp_init(mon, vlan, device, name, restricted, vnet, vhost,

                             vhostname, tftp_export, bootfile, vdhcp_start,

                             vnamesrv, smb_export, vsmbsrv);

        while (slirp_configs) {

            config = slirp_configs;

            slirp_configs = config->next;

            qemu_free(config);

        }

        qemu_free(vnet);

        qemu_free(vhost);

        qemu_free(vhostname);

        qemu_free(tftp_export);

        qemu_free(bootfile);

        qemu_free(vdhcp_start);

        qemu_free(vnamesrv);

        qemu_free(smb_export);

        qemu_free(vsmbsrv);

    } else if (!strcmp(device, "channel")) {

        if (QTAILQ_EMPTY(&slirp_stacks)) {

            struct slirp_config_str *config;

            config = qemu_malloc(sizeof(*config));

            pstrcpy(config->str, sizeof(config->str), p);

            config->flags = SLIRP_CFG_LEGACY;

            config->next = slirp_configs;

            slirp_configs = config;

        } else {

            slirp_guestfwd(QTAILQ_FIRST(&slirp_stacks), mon, p, 1);

        }

        ret = 0;

    } else

#endif

#ifdef _WIN32

    if (!strcmp(device, "tap")) {

        static const char * const tap_params[] = {

            "vlan", "name", "ifname", NULL

        };

        char ifname[64];

        if (check_params(buf, sizeof(buf), tap_params, p) < 0) {

            config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);

            ret = -1;

            goto out;

        }

        if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {

            config_error(mon, "tap: no interface name\n");

            ret = -1;

            goto out;

        }

        vlan->nb_host_devs++;

        ret = tap_win32_init(vlan, device, name, ifname);

    } else

#elif defined (_AIX)

#else

    if (!strcmp(device, "tap")) {

        char ifname[64], chkbuf[64];

        char setup_script[1024], down_script[1024];

        TAPState *s;

        int fd;

        vlan->nb_host_devs++;

        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {

            static const char * const fd_params[] = {

                "vlan", "name", "fd", "sndbuf", NULL

            };

            ret = -1;

            if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {

                config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);

                goto out;

            }

            fd = net_handle_fd_param(mon, buf);

            if (fd == -1) {

                goto out;

            }

            fcntl(fd, F_SETFL, O_NONBLOCK);

            s = net_tap_fd_init(vlan, device, name, fd);

            if (!s) {

                close(fd);

            }

        } else {

            static const char * const tap_params[] = {

                "vlan", "name", "ifname", "script", "downscript", "sndbuf", NULL

            };

            if (check_params(chkbuf, sizeof(chkbuf), tap_params, p) < 0) {

                config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);

                ret = -1;

                goto out;

            }

            if (get_param_value(ifname, sizeof(ifname), "ifname", p) <= 0) {

                ifname[0] = '\0';

            }

            if (get_param_value(setup_script, sizeof(setup_script), "script", p) == 0) {

                pstrcpy(setup_script, sizeof(setup_script), DEFAULT_NETWORK_SCRIPT);

            }

            if (get_param_value(down_script, sizeof(down_script), "downscript", p) == 0) {

                pstrcpy(down_script, sizeof(down_script), DEFAULT_NETWORK_DOWN_SCRIPT);

            }

            s = net_tap_init(vlan, device, name, ifname, setup_script, down_script);

        }

        if (s != NULL) {

            const char *sndbuf_str = NULL;

            if (get_param_value(buf, sizeof(buf), "sndbuf", p)) {

                sndbuf_str = buf;

            }

            tap_set_sndbuf(s, sndbuf_str, mon);

            ret = 0;

        } else {

            ret = -1;

        }

    } else

#endif

    if (!strcmp(device, "socket")) {

        char chkbuf[64];

        if (get_param_value(buf, sizeof(buf), "fd", p) > 0) {

            static const char * const fd_params[] = {

                "vlan", "name", "fd", NULL

            };

            int fd;

            ret = -1;

            if (check_params(chkbuf, sizeof(chkbuf), fd_params, p) < 0) {

                config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);

                goto out;

            }

            fd = net_handle_fd_param(mon, buf);

            if (fd == -1) {

                goto out;

            }

            if (!net_socket_fd_init(vlan, device, name, fd, 1)) {

                close(fd);

                goto out;

            }

            ret = 0;

        } else if (get_param_value(buf, sizeof(buf), "listen", p) > 0) {

            static const char * const listen_params[] = {

                "vlan", "name", "listen", NULL

            };

            if (check_params(chkbuf, sizeof(chkbuf), listen_params, p) < 0) {

                config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);

                ret = -1;

                goto out;

            }

            ret = net_socket_listen_init(vlan, device, name, buf);

        } else if (get_param_value(buf, sizeof(buf), "connect", p) > 0) {

            static const char * const connect_params[] = {

                "vlan", "name", "connect", NULL

            };

            if (check_params(chkbuf, sizeof(chkbuf), connect_params, p) < 0) {

                config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);

                ret = -1;

                goto out;

            }

            ret = net_socket_connect_init(vlan, device, name, buf);

        } else if (get_param_value(buf, sizeof(buf), "mcast", p) > 0) {

            static const char * const mcast_params[] = {

                "vlan", "name", "mcast", NULL

            };

            if (check_params(chkbuf, sizeof(chkbuf), mcast_params, p) < 0) {

                config_error(mon, "invalid parameter '%s' in '%s'\n", chkbuf, p);

                ret = -1;

                goto out;

            }

            ret = net_socket_mcast_init(vlan, device, name, buf);

        } else {

            config_error(mon, "Unknown socket options: %s\n", p);

            ret = -1;

            goto out;

        }

        vlan->nb_host_devs++;

    } else

#ifdef CONFIG_VDE

    if (!strcmp(device, "vde")) {

        static const char * const vde_params[] = {

            "vlan", "name", "sock", "port", "group", "mode", NULL

        };

        char vde_sock[1024], vde_group[512];

	int vde_port, vde_mode;

        if (check_params(buf, sizeof(buf), vde_params, p) < 0) {

            config_error(mon, "invalid parameter '%s' in '%s'\n", buf, p);

            ret = -1;

            goto out;

        }

        vlan->nb_host_devs++;

        if (get_param_value(vde_sock, sizeof(vde_sock), "sock", p) <= 0) {

	    vde_sock[0] = '\0';

	}

	if (get_param_value(buf, sizeof(buf), "port", p) > 0) {

	    vde_port = strtol(buf, NULL, 10);

	} else {

	    vde_port = 0;

	}

	if (get_param_value(vde_group, sizeof(vde_group), "group", p) <= 0) {

	    vde_group[0] = '\0';

	}

	if (get_param_value(buf, sizeof(buf), "mode", p) > 0) {

	    vde_mode = strtol(buf, NULL, 8);

	} else {

	    vde_mode = 0700;

	}

	ret = net_vde_init(vlan, device, name, vde_sock, vde_port, vde_group, vde_mode);

    } else

#endif

    if (!strcmp(device, "dump")) {

        int len = 65536;

        if (get_param_value(buf, sizeof(buf), "len", p) > 0) {

            len = strtol(buf, NULL, 0);

        }

        if (!get_param_value(buf, sizeof(buf), "file", p)) {

            snprintf(buf, sizeof(buf), "qemu-vlan%d.pcap", vlan_id);

        }

        ret = net_dump_init(mon, vlan, device, name, buf, len);

    } else {

        config_error(mon, "Unknown network device: %s\n", device);

        ret = -1;

        goto out;

    }

    if (ret < 0) {

        config_error(mon, "Could not initialize device '%s'\n", device);

    }

out:

    qemu_free(name);

    return ret;

}


static void cmv_decode_intra(CmvContext * s, const uint8_t *buf, const uint8_t *buf_end){

    unsigned char *dst = s->frame.data[0];

    int i;

    for (i=0; i < s->avctx->height && buf+s->avctx->width<=buf_end; i++) {

        memcpy(dst, buf, s->avctx->width);

        dst += s->frame.linesize[0];

        buf += s->avctx->width;

    }

}


int av_buffersink_get_frame_flags(AVFilterContext *ctx, AVFrame *frame, int flags)

{

    BufferSinkContext *buf = ctx->priv;

    AVFilterLink *inlink = ctx->inputs[0];

    int ret;

    AVFrame *cur_frame;

    /* no picref available, fetch it from the filterchain */

    if (!av_fifo_size(buf->fifo)) {

        if (flags & AV_BUFFERSINK_FLAG_NO_REQUEST)

            return AVERROR(EAGAIN);

        if ((ret = ff_request_frame(inlink)) < 0)

            return ret;

    }

    if (!av_fifo_size(buf->fifo))

        return AVERROR(EINVAL);

    if (flags & AV_BUFFERSINK_FLAG_PEEK) {

        cur_frame = *((AVFrame **)av_fifo_peek2(buf->fifo, 0));

        av_frame_ref(frame, cur_frame); /* TODO check failure */

    } else {

        av_fifo_generic_read(buf->fifo, &cur_frame, sizeof(cur_frame), NULL);

        av_frame_move_ref(frame, cur_frame);

        av_frame_free(&cur_frame);

    }

    return 0;

}


static int dump_iterate(DumpState *s)

{

    RAMBlock *block;

    int64_t size;

    int ret;

    while (1) {

        block = s->block;

        size = block->length;

        if (s->has_filter) {

            size -= s->start;

            if (s->begin + s->length < block->offset + block->length) {

                size -= block->offset + block->length - (s->begin + s->length);

            }

        }

        ret = write_memory(s, block, s->start, size);

        if (ret == -1) {

            return ret;

        }

        ret = get_next_block(s, block);

        if (ret == 1) {

            dump_completed(s);

            return 0;

        }

    }

}


static void lsi_reg_writeb(LSIState *s, int offset, uint8_t val)

{

#define CASE_SET_REG24(name, addr) \

    case addr    : s->name &= 0xffffff00; s->name |= val;       break; \

    case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8;  break; \

    case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break;

#define CASE_SET_REG32(name, addr) \

    case addr    : s->name &= 0xffffff00; s->name |= val;       break; \

    case addr + 1: s->name &= 0xffff00ff; s->name |= val << 8;  break; \

    case addr + 2: s->name &= 0xff00ffff; s->name |= val << 16; break; \

    case addr + 3: s->name &= 0x00ffffff; s->name |= val << 24; break;

#ifdef DEBUG_LSI_REG

    DPRINTF("Write reg %x = %02x\n", offset, val);

#endif

    switch (offset) {

    case 0x00: /* SCNTL0 */

        s->scntl0 = val;

        if (val & LSI_SCNTL0_START) {

            BADF("Start sequence not implemented\n");

        }

        break;

    case 0x01: /* SCNTL1 */

        s->scntl1 = val & ~LSI_SCNTL1_SST;

        if (val & LSI_SCNTL1_IARB) {

            BADF("Immediate Arbritration not implemented\n");

        }

        if (val & LSI_SCNTL1_RST) {

            if (!(s->sstat0 & LSI_SSTAT0_RST)) {

                BusChild *kid;

                QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {

                    DeviceState *dev = kid->child;

                    device_reset(dev);

                }

                s->sstat0 |= LSI_SSTAT0_RST;

                lsi_script_scsi_interrupt(s, LSI_SIST0_RST, 0);

            }

        } else {

            s->sstat0 &= ~LSI_SSTAT0_RST;

        }

        break;

    case 0x02: /* SCNTL2 */

        val &= ~(LSI_SCNTL2_WSR | LSI_SCNTL2_WSS);

        s->scntl2 = val;

        break;

    case 0x03: /* SCNTL3 */

        s->scntl3 = val;

        break;

    case 0x04: /* SCID */

        s->scid = val;

        break;

    case 0x05: /* SXFER */

        s->sxfer = val;

        break;

    case 0x06: /* SDID */

        if ((val & 0xf) != (s->ssid & 0xf))

            BADF("Destination ID does not match SSID\n");

        s->sdid = val & 0xf;

        break;

    case 0x07: /* GPREG0 */

        break;

    case 0x08: /* SFBR */

        /* The CPU is not allowed to write to this register.  However the

           SCRIPTS register move instructions are.  */

        s->sfbr = val;

        break;

    case 0x0a: case 0x0b:

        /* Openserver writes to these readonly registers on startup */

	return;

    case 0x0c: case 0x0d: case 0x0e: case 0x0f:

        /* Linux writes to these readonly registers on startup.  */

        return;

    CASE_SET_REG32(dsa, 0x10)

    case 0x14: /* ISTAT0 */

        s->istat0 = (s->istat0 & 0x0f) | (val & 0xf0);

        if (val & LSI_ISTAT0_ABRT) {

            lsi_script_dma_interrupt(s, LSI_DSTAT_ABRT);

        }

        if (val & LSI_ISTAT0_INTF) {

            s->istat0 &= ~LSI_ISTAT0_INTF;

            lsi_update_irq(s);

        }

        if (s->waiting == 1 && val & LSI_ISTAT0_SIGP) {

            DPRINTF("Woken by SIGP\n");

            s->waiting = 0;

            s->dsp = s->dnad;

            lsi_execute_script(s);

        }

        if (val & LSI_ISTAT0_SRST) {

            lsi_soft_reset(s);

        }

        break;

    case 0x16: /* MBOX0 */

        s->mbox0 = val;

        break;

    case 0x17: /* MBOX1 */

        s->mbox1 = val;

        break;

    case 0x1a: /* CTEST2 */

	s->ctest2 = val & LSI_CTEST2_PCICIE;

	break;

    case 0x1b: /* CTEST3 */

        s->ctest3 = val & 0x0f;

        break;

    CASE_SET_REG32(temp, 0x1c)

    case 0x21: /* CTEST4 */

        if (val & 7) {

           BADF("Unimplemented CTEST4-FBL 0x%x\n", val);

        }

        s->ctest4 = val;

        break;

    case 0x22: /* CTEST5 */

        if (val & (LSI_CTEST5_ADCK | LSI_CTEST5_BBCK)) {

            BADF("CTEST5 DMA increment not implemented\n");

        }

        s->ctest5 = val;

        break;

    CASE_SET_REG24(dbc, 0x24)

    CASE_SET_REG32(dnad, 0x28)

    case 0x2c: /* DSP[0:7] */

        s->dsp &= 0xffffff00;

        s->dsp |= val;

        break;

    case 0x2d: /* DSP[8:15] */

        s->dsp &= 0xffff00ff;

        s->dsp |= val << 8;

        break;

    case 0x2e: /* DSP[16:23] */

        s->dsp &= 0xff00ffff;

        s->dsp |= val << 16;

        break;

    case 0x2f: /* DSP[24:31] */

        s->dsp &= 0x00ffffff;

        s->dsp |= val << 24;

        if ((s->dmode & LSI_DMODE_MAN) == 0

            && (s->istat1 & LSI_ISTAT1_SRUN) == 0)

            lsi_execute_script(s);

        break;

    CASE_SET_REG32(dsps, 0x30)

    CASE_SET_REG32(scratch[0], 0x34)

    case 0x38: /* DMODE */

        if (val & (LSI_DMODE_SIOM | LSI_DMODE_DIOM)) {

            BADF("IO mappings not implemented\n");

        }

        s->dmode = val;

        break;

    case 0x39: /* DIEN */

        s->dien = val;

        lsi_update_irq(s);

        break;

    case 0x3a: /* SBR */

        s->sbr = val;

        break;

    case 0x3b: /* DCNTL */

        s->dcntl = val & ~(LSI_DCNTL_PFF | LSI_DCNTL_STD);

        if ((val & LSI_DCNTL_STD) && (s->istat1 & LSI_ISTAT1_SRUN) == 0)

            lsi_execute_script(s);

        break;

    case 0x40: /* SIEN0 */

        s->sien0 = val;

        lsi_update_irq(s);

        break;

    case 0x41: /* SIEN1 */

        s->sien1 = val;

        lsi_update_irq(s);

        break;

    case 0x47: /* GPCNTL0 */

        break;

    case 0x48: /* STIME0 */

        s->stime0 = val;

        break;

    case 0x49: /* STIME1 */

        if (val & 0xf) {

            DPRINTF("General purpose timer not implemented\n");

            /* ??? Raising the interrupt immediately seems to be sufficient

               to keep the FreeBSD driver happy.  */

            lsi_script_scsi_interrupt(s, 0, LSI_SIST1_GEN);

        }

        break;

    case 0x4a: /* RESPID0 */

        s->respid0 = val;

        break;

    case 0x4b: /* RESPID1 */

        s->respid1 = val;

        break;

    case 0x4d: /* STEST1 */

        s->stest1 = val;

        break;

    case 0x4e: /* STEST2 */

        if (val & 1) {

            BADF("Low level mode not implemented\n");

        }

        s->stest2 = val;

        break;

    case 0x4f: /* STEST3 */

        if (val & 0x41) {

            BADF("SCSI FIFO test mode not implemented\n");

        }

        s->stest3 = val;

        break;

    case 0x56: /* CCNTL0 */

        s->ccntl0 = val;

        break;

    case 0x57: /* CCNTL1 */

        s->ccntl1 = val;

        break;

    CASE_SET_REG32(mmrs, 0xa0)

    CASE_SET_REG32(mmws, 0xa4)

    CASE_SET_REG32(sfs, 0xa8)

    CASE_SET_REG32(drs, 0xac)

    CASE_SET_REG32(sbms, 0xb0)

    CASE_SET_REG32(dbms, 0xb4)

    CASE_SET_REG32(dnad64, 0xb8)

    CASE_SET_REG32(pmjad1, 0xc0)

    CASE_SET_REG32(pmjad2, 0xc4)

    CASE_SET_REG32(rbc, 0xc8)

    CASE_SET_REG32(ua, 0xcc)

    CASE_SET_REG32(ia, 0xd4)

    CASE_SET_REG32(sbc, 0xd8)

    CASE_SET_REG32(csbc, 0xdc)

    default:

        if (offset >= 0x5c && offset < 0xa0) {

            int n;

            int shift;

            n = (offset - 0x58) >> 2;

            shift = (offset & 3) * 8;

            s->scratch[n] &= ~(0xff << shift);

            s->scratch[n] |= (val & 0xff) << shift;

        } else {

            BADF("Unhandled writeb 0x%x = 0x%x\n", offset, val);

        }

    }

#undef CASE_SET_REG24

#undef CASE_SET_REG32

}


static inline void tcg_out_op(TCGContext *s, int opc, const TCGArg *args,

                              const int *const_args)

{

    int c;

    switch (opc) {

    case INDEX_op_exit_tb:

        tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I0, args[0]);

        tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I7) |

                  INSN_IMM13(8));

        tcg_out32(s, RESTORE | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_G0) |

                      INSN_RS2(TCG_REG_G0));

        break;

    case INDEX_op_goto_tb:

        if (s->tb_jmp_offset) {

            /* direct jump method */

            if (ABS(args[0] - (unsigned long)s->code_ptr) ==

                (ABS(args[0] - (unsigned long)s->code_ptr) & 0x1fffff)) {

                tcg_out32(s, BA |

                          INSN_OFF22(args[0] - (unsigned long)s->code_ptr));

            } else {

                tcg_out_movi(s, TCG_TYPE_PTR, TCG_REG_I5, args[0]);

                tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |

                          INSN_RS2(TCG_REG_G0));

            }

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

        } else {

            /* indirect jump method */

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

            tcg_out32(s, JMPL | INSN_RD(TCG_REG_G0) | INSN_RS1(TCG_REG_I5) |

                      INSN_RS2(TCG_REG_G0));

        }

        tcg_out_nop(s);

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

        break;

    case INDEX_op_call:

        if (const_args[0]) {

            tcg_out32(s, CALL | ((((tcg_target_ulong)args[0]

                                  - (tcg_target_ulong)s->code_ptr) >> 2)

                                 & 0x3fffffff));

            tcg_out_nop(s);

        } else {

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

            tcg_out32(s, JMPL | INSN_RD(TCG_REG_O7) | INSN_RS1(TCG_REG_O7) |

                      INSN_RS2(TCG_REG_G0));

            tcg_out_nop(s);

        }

        break;

    case INDEX_op_jmp:

        fprintf(stderr, "unimplemented jmp\n");

        break;

    case INDEX_op_br:

        fprintf(stderr, "unimplemented br\n");

        break;

    case INDEX_op_movi_i32:

        tcg_out_movi(s, TCG_TYPE_I32, args[0], (uint32_t)args[1]);

        break;

#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)

#define OP_32_64(x)                             \

        glue(glue(case INDEX_op_, x), _i32:)    \

        glue(glue(case INDEX_op_, x), _i64:)

#else

#define OP_32_64(x)                             \

        glue(glue(case INDEX_op_, x), _i32:)

#endif

        OP_32_64(ld8u);

        tcg_out_ldst(s, args[0], args[1], args[2], LDUB);

        break;

        OP_32_64(ld8s);

        tcg_out_ldst(s, args[0], args[1], args[2], LDSB);

        break;

        OP_32_64(ld16u);

        tcg_out_ldst(s, args[0], args[1], args[2], LDUH);

        break;

        OP_32_64(ld16s);

        tcg_out_ldst(s, args[0], args[1], args[2], LDSH);

        break;

    case INDEX_op_ld_i32:

#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)

    case INDEX_op_ld32u_i64:

#endif

        tcg_out_ldst(s, args[0], args[1], args[2], LDUW);

        break;

        OP_32_64(st8);

        tcg_out_ldst(s, args[0], args[1], args[2], STB);

        break;

        OP_32_64(st16);

        tcg_out_ldst(s, args[0], args[1], args[2], STH);

        break;

    case INDEX_op_st_i32:

#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)

    case INDEX_op_st32_i64:

#endif

        tcg_out_ldst(s, args[0], args[1], args[2], STW);

        break;

        OP_32_64(add);

        c = ARITH_ADD;

        goto gen_arith32;

        OP_32_64(sub);

        c = ARITH_SUB;

        goto gen_arith32;

        OP_32_64(and);

        c = ARITH_AND;

        goto gen_arith32;

        OP_32_64(or);

        c = ARITH_OR;

        goto gen_arith32;

        OP_32_64(xor);

        c = ARITH_XOR;

        goto gen_arith32;

    case INDEX_op_shl_i32:

        c = SHIFT_SLL;

        goto gen_arith32;

    case INDEX_op_shr_i32:

        c = SHIFT_SRL;

        goto gen_arith32;

    case INDEX_op_sar_i32:

        c = SHIFT_SRA;

        goto gen_arith32;

    case INDEX_op_mul_i32:

        c = ARITH_UMUL;

        goto gen_arith32;

    case INDEX_op_div2_i32:

#if defined(__sparc_v9__) || defined(__sparc_v8plus__)

        c = ARITH_SDIVX;

        goto gen_arith32;

#else

        tcg_out_sety(s, 0);

        c = ARITH_SDIV;

        goto gen_arith32;

#endif

    case INDEX_op_divu2_i32:

#if defined(__sparc_v9__) || defined(__sparc_v8plus__)

        c = ARITH_UDIVX;

        goto gen_arith32;

#else

        tcg_out_sety(s, 0);

        c = ARITH_UDIV;

        goto gen_arith32;

#endif

    case INDEX_op_brcond_i32:

        fprintf(stderr, "unimplemented brcond\n");

        break;

    case INDEX_op_qemu_ld8u:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_ld8s:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_ld16u:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_ld16s:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_ld32u:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_ld32s:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_st8:

        fprintf(stderr, "unimplemented qst\n");

        break;

    case INDEX_op_qemu_st16:

        fprintf(stderr, "unimplemented qst\n");

        break;

    case INDEX_op_qemu_st32:

        fprintf(stderr, "unimplemented qst\n");

        break;

#if defined(__sparc_v9__) && !defined(__sparc_v8plus__)

    case INDEX_op_movi_i64:

        tcg_out_movi(s, TCG_TYPE_I64, args[0], args[1]);

        break;

    case INDEX_op_ld32s_i64:

        tcg_out_ldst(s, args[0], args[1], args[2], LDSW);

        break;

    case INDEX_op_ld_i64:

        tcg_out_ldst(s, args[0], args[1], args[2], LDX);

        break;

    case INDEX_op_st_i64:

        tcg_out_ldst(s, args[0], args[1], args[2], STX);

        break;

    case INDEX_op_shl_i64:

        c = SHIFT_SLLX;

        goto gen_arith32;

    case INDEX_op_shr_i64:

        c = SHIFT_SRLX;

        goto gen_arith32;

    case INDEX_op_sar_i64:

        c = SHIFT_SRAX;

        goto gen_arith32;

    case INDEX_op_mul_i64:

        c = ARITH_MULX;

        goto gen_arith32;

    case INDEX_op_div2_i64:

        c = ARITH_SDIVX;

        goto gen_arith32;

    case INDEX_op_divu2_i64:

        c = ARITH_UDIVX;

        goto gen_arith32;

    case INDEX_op_brcond_i64:

        fprintf(stderr, "unimplemented brcond\n");

        break;

    case INDEX_op_qemu_ld64:

        fprintf(stderr, "unimplemented qld\n");

        break;

    case INDEX_op_qemu_st64:

        fprintf(stderr, "unimplemented qst\n");

        break;

#endif

    gen_arith32:

        if (const_args[2]) {

            tcg_out_arithi(s, args[0], args[1], args[2], c);

        } else {

            tcg_out_arith(s, args[0], args[1], args[2], c);

        }

        break;

    default:

        fprintf(stderr, "unknown opcode 0x%x\n", opc);

        tcg_abort();

    }

}


void os_mem_prealloc(int fd, char *area, size_t memory)

{

    int ret;

    struct sigaction act, oldact;

    sigset_t set, oldset;

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

    act.sa_handler = &sigbus_handler;

    act.sa_flags = 0;

    ret = sigaction(SIGBUS, &act, &oldact);

    if (ret) {

        perror("os_mem_prealloc: failed to install signal handler");

        exit(1);

    }

    /* unblock SIGBUS */

    sigemptyset(&set);

    sigaddset(&set, SIGBUS);

    pthread_sigmask(SIG_UNBLOCK, &set, &oldset);

    if (sigsetjmp(sigjump, 1)) {

        fprintf(stderr, "os_mem_prealloc: Insufficient free host memory "

                        "pages available to allocate guest RAM\n");

        exit(1);

    } else {

        int i;

        size_t hpagesize = fd_getpagesize(fd);

        size_t numpages = DIV_ROUND_UP(memory, hpagesize);

        /* MAP_POPULATE silently ignores failures */

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

            memset(area + (hpagesize * i), 0, 1);

        }

        ret = sigaction(SIGBUS, &oldact, NULL);

        if (ret) {

            perror("os_mem_prealloc: failed to reinstall signal handler");

            exit(1);

        }

        pthread_sigmask(SIG_SETMASK, &oldset, NULL);

    }

}


int usb_handle_packet(USBDevice *dev, USBPacket *p)

{

    int ret;

    if (dev == NULL) {

        return USB_RET_NODEV;

    }

    assert(dev->addr == p->devaddr);

    assert(dev->state == USB_STATE_DEFAULT);

    assert(p->state == USB_PACKET_SETUP);

    if (p->devep == 0) {

        /* control pipe */

        switch (p->pid) {

        case USB_TOKEN_SETUP:

            ret = do_token_setup(dev, p);

            break;

        case USB_TOKEN_IN:

            ret = do_token_in(dev, p);

            break;

        case USB_TOKEN_OUT:

            ret = do_token_out(dev, p);

            break;

        default:

            ret = USB_RET_STALL;

            break;

        }

    } else {

        /* data pipe */

        ret = usb_device_handle_data(dev, p);

    }

    if (ret == USB_RET_ASYNC) {

        p->ep = usb_ep_get(dev, p->pid, p->devep);

        p->state = USB_PACKET_ASYNC;

    }

    return ret;

}


build_rsdp(GArray *rsdp_table, BIOSLinker *linker, unsigned rsdt_tbl_offset)

{

    AcpiRsdpDescriptor *rsdp = acpi_data_push(rsdp_table, sizeof *rsdp);

    unsigned rsdt_pa_size = sizeof(rsdp->rsdt_physical_address);

    unsigned rsdt_pa_offset =

        (char *)&rsdp->rsdt_physical_address - rsdp_table->data;

    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, rsdp_table, 16,

                             true /* fseg memory */);

    memcpy(&rsdp->signature, "RSD PTR ", sizeof(rsdp->signature));

    memcpy(rsdp->oem_id, ACPI_BUILD_APPNAME6, sizeof(rsdp->oem_id));

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

    rsdp->revision = 0x02;

    /* Address to be filled by Guest linker */

    bios_linker_loader_add_pointer(linker,

        ACPI_BUILD_RSDP_FILE, rsdt_pa_offset, rsdt_pa_size,

        ACPI_BUILD_TABLE_FILE, rsdt_tbl_offset);

    rsdp->checksum = 0;

    /* Checksum to be filled by Guest linker */

    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,

                                    rsdp, sizeof *rsdp,

                                    &rsdp->checksum);

    return rsdp_table;

}


static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)

{

    uint32_t cmd = s->fifo[CMD(stop) >> 2];

    s->cmd->stop = cpu_to_le32(CMD(stop) + 4);

    if (CMD(stop) >= CMD(max))

        s->cmd->stop = s->cmd->min;

    return cmd;

}


static void rv40_loop_filter(RV34DecContext *r, int row)

{

    MpegEncContext *s = &r->s;

    int mb_pos, mb_x;

    int i, j, k;

    uint8_t *Y, *C;

    int alpha, beta, betaY, betaC;

    int q;

    int mbtype[4];   ///< current macroblock and its neighbours types

    /**

     * flags indicating that macroblock can be filtered with strong filter

     * it is set only for intra coded MB and MB with DCs coded separately

     */

    int mb_strong[4];

    int clip[4];     ///< MB filter clipping value calculated from filtering strength

    /**

     * coded block patterns for luma part of current macroblock and its neighbours

     * Format:

     * LSB corresponds to the top left block,

     * each nibble represents one row of subblocks.

     */

    int cbp[4];

    /**

     * coded block patterns for chroma part of current macroblock and its neighbours

     * Format is the same as for luma with two subblocks in a row.

     */

    int uvcbp[4][2];

    /**

     * This mask represents the pattern of luma subblocks that should be filtered

     * in addition to the coded ones because because they lie at the edge of

     * 8x8 block with different enough motion vectors

     */

    int mvmasks[4];

    mb_pos = row * s->mb_stride;

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

        int mbtype = s->current_picture_ptr->f.mb_type[mb_pos];

        if(IS_INTRA(mbtype) || IS_SEPARATE_DC(mbtype))

            r->cbp_luma  [mb_pos] = r->deblock_coefs[mb_pos] = 0xFFFF;

        if(IS_INTRA(mbtype))

            r->cbp_chroma[mb_pos] = 0xFF;

    }

    mb_pos = row * s->mb_stride;

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

        int y_h_deblock, y_v_deblock;

        int c_v_deblock[2], c_h_deblock[2];

        int clip_left;

        int avail[4];

        int y_to_deblock, c_to_deblock[2];

        q = s->current_picture_ptr->f.qscale_table[mb_pos];

        alpha = rv40_alpha_tab[q];

        beta  = rv40_beta_tab [q];

        betaY = betaC = beta * 3;

        if(s->width * s->height <= 176*144)

            betaY += beta;

        avail[0] = 1;

        avail[1] = row;

        avail[2] = mb_x;

        avail[3] = row < s->mb_height - 1;

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

            if(avail[i]){

                int pos = mb_pos + neighbour_offs_x[i] + neighbour_offs_y[i]*s->mb_stride;

                mvmasks[i] = r->deblock_coefs[pos];

                mbtype [i] = s->current_picture_ptr->f.mb_type[pos];

                cbp    [i] = r->cbp_luma[pos];

                uvcbp[i][0] = r->cbp_chroma[pos] & 0xF;

                uvcbp[i][1] = r->cbp_chroma[pos] >> 4;

            }else{

                mvmasks[i] = 0;

                mbtype [i] = mbtype[0];

                cbp    [i] = 0;

                uvcbp[i][0] = uvcbp[i][1] = 0;

            }

            mb_strong[i] = IS_INTRA(mbtype[i]) || IS_SEPARATE_DC(mbtype[i]);

            clip[i] = rv40_filter_clip_tbl[mb_strong[i] + 1][q];

        }

        y_to_deblock =  mvmasks[POS_CUR]

                     | (mvmasks[POS_BOTTOM] << 16);

        /* This pattern contains bits signalling that horizontal edges of

         * the current block can be filtered.

         * That happens when either of adjacent subblocks is coded or lies on

         * the edge of 8x8 blocks with motion vectors differing by more than

         * 3/4 pel in any component (any edge orientation for some reason).

         */

        y_h_deblock =   y_to_deblock

                    | ((cbp[POS_CUR]                           <<  4) & ~MASK_Y_TOP_ROW)

                    | ((cbp[POS_TOP]        & MASK_Y_LAST_ROW) >> 12);

        /* This pattern contains bits signalling that vertical edges of

         * the current block can be filtered.

         * That happens when either of adjacent subblocks is coded or lies on

         * the edge of 8x8 blocks with motion vectors differing by more than

         * 3/4 pel in any component (any edge orientation for some reason).

         */

        y_v_deblock =   y_to_deblock

                    | ((cbp[POS_CUR]                      << 1) & ~MASK_Y_LEFT_COL)

                    | ((cbp[POS_LEFT] & MASK_Y_RIGHT_COL) >> 3);

        if(!mb_x)

            y_v_deblock &= ~MASK_Y_LEFT_COL;

        if(!row)

            y_h_deblock &= ~MASK_Y_TOP_ROW;

        if(row == s->mb_height - 1 || (mb_strong[POS_CUR] || mb_strong[POS_BOTTOM]))

            y_h_deblock &= ~(MASK_Y_TOP_ROW << 16);

        /* Calculating chroma patterns is similar and easier since there is

         * no motion vector pattern for them.

         */

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

            c_to_deblock[i] = (uvcbp[POS_BOTTOM][i] << 4) | uvcbp[POS_CUR][i];

            c_v_deblock[i] =   c_to_deblock[i]

                           | ((uvcbp[POS_CUR] [i]                       << 1) & ~MASK_C_LEFT_COL)

                           | ((uvcbp[POS_LEFT][i]   & MASK_C_RIGHT_COL) >> 1);

            c_h_deblock[i] =   c_to_deblock[i]

                           | ((uvcbp[POS_TOP][i]    & MASK_C_LAST_ROW)  >> 2)

                           |  (uvcbp[POS_CUR][i]                        << 2);

            if(!mb_x)

                c_v_deblock[i] &= ~MASK_C_LEFT_COL;

            if(!row)

                c_h_deblock[i] &= ~MASK_C_TOP_ROW;

            if(row == s->mb_height - 1 || mb_strong[POS_CUR] || mb_strong[POS_BOTTOM])

                c_h_deblock[i] &= ~(MASK_C_TOP_ROW << 4);

        }

        for(j = 0; j < 16; j += 4){

            Y = s->current_picture_ptr->f.data[0] + mb_x*16 + (row*16 + j) * s->linesize;

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

                int ij = i + j;

                int clip_cur = y_to_deblock & (MASK_CUR << ij) ? clip[POS_CUR] : 0;

                int dither = j ? ij : i*4;

                // if bottom block is coded then we can filter its top edge

                // (or bottom edge of this block, which is the same)

                if(y_h_deblock & (MASK_BOTTOM << ij)){

                    r->rdsp.rv40_h_loop_filter(Y+4*s->linesize, s->linesize, dither,

                                       y_to_deblock & (MASK_BOTTOM << ij) ? clip[POS_CUR] : 0,

                                       clip_cur,

                                       alpha, beta, betaY, 0, 0);

                }

                // filter left block edge in ordinary mode (with low filtering strength)

                if(y_v_deblock & (MASK_CUR << ij) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){

                    if(!i)

                        clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;

                    else

                        clip_left = y_to_deblock & (MASK_CUR << (ij-1)) ? clip[POS_CUR] : 0;

                    r->rdsp.rv40_v_loop_filter(Y, s->linesize, dither,

                                       clip_cur,

                                       clip_left,

                                       alpha, beta, betaY, 0, 0);

                }

                // filter top edge of the current macroblock when filtering strength is high

                if(!j && y_h_deblock & (MASK_CUR << i) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){

                    r->rdsp.rv40_h_loop_filter(Y, s->linesize, dither,

                                       clip_cur,

                                       mvmasks[POS_TOP] & (MASK_TOP << i) ? clip[POS_TOP] : 0,

                                       alpha, beta, betaY, 0, 1);

                }

                // filter left block edge in edge mode (with high filtering strength)

                if(y_v_deblock & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){

                    clip_left = mvmasks[POS_LEFT] & (MASK_RIGHT << j) ? clip[POS_LEFT] : 0;

                    r->rdsp.rv40_v_loop_filter(Y, s->linesize, dither,

                                       clip_cur,

                                       clip_left,

                                       alpha, beta, betaY, 0, 1);

                }

            }

        }

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

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

                C = s->current_picture_ptr->f.data[k + 1] + mb_x*8 + (row*8 + j*4) * s->uvlinesize;

                for(i = 0; i < 2; i++, C += 4){

                    int ij = i + j*2;

                    int clip_cur = c_to_deblock[k] & (MASK_CUR << ij) ? clip[POS_CUR] : 0;

                    if(c_h_deblock[k] & (MASK_CUR << (ij+2))){

                        int clip_bot = c_to_deblock[k] & (MASK_CUR << (ij+2)) ? clip[POS_CUR] : 0;

                        r->rdsp.rv40_h_loop_filter(C+4*s->uvlinesize, s->uvlinesize, i*8,

                                           clip_bot,

                                           clip_cur,

                                           alpha, beta, betaC, 1, 0);

                    }

                    if((c_v_deblock[k] & (MASK_CUR << ij)) && (i || !(mb_strong[POS_CUR] || mb_strong[POS_LEFT]))){

                        if(!i)

                            clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;

                        else

                            clip_left = c_to_deblock[k]    & (MASK_CUR << (ij-1))  ? clip[POS_CUR]  : 0;

                        r->rdsp.rv40_v_loop_filter(C, s->uvlinesize, j*8,

                                           clip_cur,

                                           clip_left,

                                           alpha, beta, betaC, 1, 0);

                    }

                    if(!j && c_h_deblock[k] & (MASK_CUR << ij) && (mb_strong[POS_CUR] || mb_strong[POS_TOP])){

                        int clip_top = uvcbp[POS_TOP][k] & (MASK_CUR << (ij+2)) ? clip[POS_TOP] : 0;

                        r->rdsp.rv40_h_loop_filter(C, s->uvlinesize, i*8,

                                           clip_cur,

                                           clip_top,

                                           alpha, beta, betaC, 1, 1);

                    }

                    if(c_v_deblock[k] & (MASK_CUR << ij) && !i && (mb_strong[POS_CUR] || mb_strong[POS_LEFT])){

                        clip_left = uvcbp[POS_LEFT][k] & (MASK_CUR << (2*j+1)) ? clip[POS_LEFT] : 0;

                        r->rdsp.rv40_v_loop_filter(C, s->uvlinesize, j*8,

                                           clip_cur,

                                           clip_left,

                                           alpha, beta, betaC, 1, 1);

                    }

                }

            }

        }

    }

}


static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)

{

    BlockDriverState *old_bs = child->bs;

    if (old_bs) {

        if (old_bs->quiesce_counter && child->role->drained_end) {

            child->role->drained_end(child);

        }

        QLIST_REMOVE(child, next_parent);

    }

    child->bs = new_bs;

    if (new_bs) {

        QLIST_INSERT_HEAD(&new_bs->parents, child, next_parent);

        if (new_bs->quiesce_counter && child->role->drained_begin) {

            child->role->drained_begin(child);

        }

    }

}


void qemu_ram_free(ram_addr_t addr)

{

    RAMBlock *block;

    /* This assumes the iothread lock is taken here too.  */

    qemu_mutex_lock_ramlist();

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

        if (addr == block->offset) {

            QTAILQ_REMOVE(&ram_list.blocks, block, next);

            ram_list.mru_block = NULL;

            ram_list.version++;

            if (block->flags & RAM_PREALLOC_MASK) {

                ;

            } else if (xen_enabled()) {

                xen_invalidate_map_cache_entry(block->host);

            } else if (mem_path) {

#if defined (__linux__) && !defined(TARGET_S390X)

                if (block->fd) {

                    munmap(block->host, block->length);

                    close(block->fd);

                } else {

                    qemu_anon_ram_free(block->host, block->length);

                }

#else

                abort();

#endif

            } else {

                qemu_anon_ram_free(block->host, block->length);

            }

            g_free(block);

            break;

        }

    }

    qemu_mutex_unlock_ramlist();

}


static int block_job_finish_sync(BlockJob *job,

                                 void (*finish)(BlockJob *, Error **errp),

                                 Error **errp)

{

    BlockDriverState *bs = job->bs;

    Error *local_err = NULL;

    int ret;

    assert(bs->job == job);

    block_job_ref(job);

    finish(job, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        block_job_unref(job);

        return -EBUSY;

    }

    while (!job->completed) {

        aio_poll(bdrv_get_aio_context(bs), true);

    }

    ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;

    block_job_unref(job);

    return ret;

}


static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)

{

    char desc[DESC_SIZE];

    uint32_t cid;

    const char *p_name, *cid_str;

    size_t cid_str_size;

    BDRVVmdkState *s = bs->opaque;

    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {

        return 0;

    }

    if (parent) {

        cid_str = "parentCID";

        cid_str_size = sizeof("parentCID");

    } else {

        cid_str = "CID";

        cid_str_size = sizeof("CID");

    }

    if ((p_name = strstr(desc,cid_str)) != NULL) {

        p_name += cid_str_size;

        sscanf(p_name,"%x",&cid);

    }

    return cid;

}


int qemu_chr_fe_ioctl(CharDriverState *s, int cmd, void *arg)

{

    if (!s->chr_ioctl)

        return -ENOTSUP;

    return s->chr_ioctl(s, cmd, arg);

}


static void e1000_pre_save(void *opaque)

{

    E1000State *s = opaque;

    NetClientState *nc = qemu_get_queue(s->nic);

    /* If the mitigation timer is active, emulate a timeout now. */

    if (s->mit_timer_on) {

        e1000_mit_timer(s);

    }

    /*

     * If link is down and auto-negotiation is supported and ongoing,

     * complete auto-negotiation immediately. This allows us to look

     * at MII_SR_AUTONEG_COMPLETE to infer link status on load.

     */

    if (nc->link_down &&

        s->compat_flags & E1000_FLAG_AUTONEG &&

        s->phy_reg[PHY_CTRL] & MII_CR_AUTO_NEG_EN &&

        s->phy_reg[PHY_CTRL] & MII_CR_RESTART_AUTO_NEG) {

         s->phy_reg[PHY_STATUS] |= MII_SR_AUTONEG_COMPLETE;

    }

}


START_TEST(invalid_array_comma)

{

    QObject *obj = qobject_from_json("[32,}");

    fail_unless(obj == NULL);

}


static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len)

{

    struct VirtIOSerialPort *port;

    struct virtio_console_control cpkt, *gcpkt;

    uint8_t *buffer;

    size_t buffer_len;

    gcpkt = buf;

    if (len < sizeof(cpkt)) {

        /* The guest sent an invalid control packet */

        return;

    }

    cpkt.event = lduw_p(&gcpkt->event);

    cpkt.value = lduw_p(&gcpkt->value);

    port = find_port_by_id(vser, ldl_p(&gcpkt->id));

    if (!port && cpkt.event != VIRTIO_CONSOLE_DEVICE_READY)

        return;

    switch(cpkt.event) {

    case VIRTIO_CONSOLE_DEVICE_READY:

        if (!cpkt.value) {

            error_report("virtio-serial-bus: Guest failure in adding device %s\n",

                         vser->bus.qbus.name);

            break;

        }

        /*

         * The device is up, we can now tell the device about all the

         * ports we have here.

         */

        QTAILQ_FOREACH(port, &vser->ports, next) {

            send_control_event(port, VIRTIO_CONSOLE_PORT_ADD, 1);

        }

        break;

    case VIRTIO_CONSOLE_PORT_READY:

        if (!cpkt.value) {

            error_report("virtio-serial-bus: Guest failure in adding port %u for device %s\n",

                         port->id, vser->bus.qbus.name);

            break;

        }

        /*

         * Now that we know the guest asked for the port name, we're

         * sure the guest has initialised whatever state is necessary

         * for this port. Now's a good time to let the guest know if

         * this port is a console port so that the guest can hook it

         * up to hvc.

         */

        if (port->is_console) {

            send_control_event(port, VIRTIO_CONSOLE_CONSOLE_PORT, 1);

        }

        if (port->name) {

            stw_p(&cpkt.event, VIRTIO_CONSOLE_PORT_NAME);

            stw_p(&cpkt.value, 1);

            buffer_len = sizeof(cpkt) + strlen(port->name) + 1;

            buffer = qemu_malloc(buffer_len);

            memcpy(buffer, &cpkt, sizeof(cpkt));

            memcpy(buffer + sizeof(cpkt), port->name, strlen(port->name));

            buffer[buffer_len - 1] = 0;

            send_control_msg(port, buffer, buffer_len);

            qemu_free(buffer);

        }

        if (port->host_connected) {

            send_control_event(port, VIRTIO_CONSOLE_PORT_OPEN, 1);

        }

        /*

         * When the guest has asked us for this information it means

         * the guest is all setup and has its virtqueues

         * initialised. If some app is interested in knowing about

         * this event, let it know.

         */

        if (port->info->guest_ready) {

            port->info->guest_ready(port);

        }

        break;

    case VIRTIO_CONSOLE_PORT_OPEN:

        port->guest_connected = cpkt.value;

        if (cpkt.value && port->info->guest_open) {

            /* Send the guest opened notification if an app is interested */

            port->info->guest_open(port);

        }

        if (!cpkt.value && port->info->guest_close) {

            /* Send the guest closed notification if an app is interested */

            port->info->guest_close(port);

        }

        break;

    }

}


static int mov_write_stbl_tag(ByteIOContext *pb, MOVTrack* track)

{

    offset_t pos = url_ftell(pb);

    put_be32(pb, 0); /* size */

    put_tag(pb, "stbl");

    mov_write_stsd_tag(pb, track);

    mov_write_stts_tag(pb, track);

    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&

        track->hasKeyframes < track->entry)

        mov_write_stss_tag(pb, track);

    if (track->enc->codec_type == CODEC_TYPE_VIDEO &&

        track->hasBframes)

        mov_write_ctts_tag(pb, track);

    mov_write_stsc_tag(pb, track);

    mov_write_stsz_tag(pb, track);

    mov_write_stco_tag(pb, track);

    return updateSize(pb, pos);

}


static void gen_mtpr(int rb, int regno)

{

    TCGv tmp;

    int data;

    if (rb == 31) {

        tmp = tcg_const_i64(0);

    } else {

        tmp = cpu_ir[rb];

    }

    /* The basic registers are data only, and unknown registers

       are read-zero, write-ignore.  */

    data = cpu_pr_data(regno);

    if (data != 0) {

        if (data & PR_BYTE) {

            tcg_gen_st8_i64(tmp, cpu_env, data & ~PR_BYTE);

        } else if (data & PR_LONG) {

            tcg_gen_st32_i64(tmp, cpu_env, data & ~PR_LONG);

        } else {

            tcg_gen_st_i64(tmp, cpu_env, data);

        }

    }

    if (rb == 31) {

        tcg_temp_free(tmp);

    }

}


void qemu_unregister_reset(QEMUResetHandler *func, void *opaque)

{

    QEMUResetEntry *re;

    TAILQ_FOREACH(re, &reset_handlers, entry) {

        if (re->func == func && re->opaque == opaque) {

            TAILQ_REMOVE(&reset_handlers, re, entry);

            qemu_free(re);

            return;

        }

    }

}


static void blizzard_reg_write(void *opaque, uint8_t reg, uint16_t value)

{

    BlizzardState *s = (BlizzardState *) opaque;

    switch (reg) {

    case 0x04:	/* PLL M-Divider */

        s->pll = (value & 0x3f) + 1;

        break;

    case 0x06:	/* PLL Lock Range Control */

        s->pll_range = value & 3;

        break;

    case 0x08:	/* PLL Lock Synthesis Control 0 */

        s->pll_ctrl &= 0xf00;

        s->pll_ctrl |= (value << 0) & 0x0ff;

        break;

    case 0x0a:	/* PLL Lock Synthesis Control 1 */

        s->pll_ctrl &= 0x0ff;

        s->pll_ctrl |= (value << 8) & 0xf00;

        break;

    case 0x0c:	/* PLL Mode Control 0 */

        s->pll_mode = value & 0x77;

        if ((value & 3) == 0 || (value & 3) == 3)

            fprintf(stderr, "%s: wrong PLL Control bits (%i)\n",

                    __FUNCTION__, value & 3);

        break;

    case 0x0e:	/* Clock-Source Select */

        s->clksel = value & 0xff;

        break;

    case 0x10:	/* Memory Controller Activate */

        s->memenable = value & 1;

        break;

    case 0x14:	/* Memory Controller Bank 0 Status Flag */

        break;

    case 0x18:	/* Auto-Refresh Interval Setting 0 */

        s->memrefresh &= 0xf00;

        s->memrefresh |= (value << 0) & 0x0ff;

        break;

    case 0x1a:	/* Auto-Refresh Interval Setting 1 */

        s->memrefresh &= 0x0ff;

        s->memrefresh |= (value << 8) & 0xf00;

        break;

    case 0x1c:	/* Power-On Sequence Timing Control */

        s->timing[0] = value & 0x7f;

        break;

    case 0x1e:	/* Timing Control 0 */

        s->timing[1] = value & 0x17;

        break;

    case 0x20:	/* Timing Control 1 */

        s->timing[2] = value & 0x35;

        break;

    case 0x24:	/* Arbitration Priority Control */

        s->priority = value & 1;

        break;

    case 0x28:	/* LCD Panel Configuration */

        s->lcd_config = value & 0xff;

        if (value & (1 << 7))

            fprintf(stderr, "%s: data swap not supported!\n", __FUNCTION__);

        break;

    case 0x2a:	/* LCD Horizontal Display Width */

        s->x = value << 3;

        break;

    case 0x2c:	/* LCD Horizontal Non-display Period */

        s->hndp = value & 0xff;

        break;

    case 0x2e:	/* LCD Vertical Display Height 0 */

        s->y &= 0x300;

        s->y |= (value << 0) & 0x0ff;

        break;

    case 0x30:	/* LCD Vertical Display Height 1 */

        s->y &= 0x0ff;

        s->y |= (value << 8) & 0x300;

        break;

    case 0x32:	/* LCD Vertical Non-display Period */

        s->vndp = value & 0xff;

        break;

    case 0x34:	/* LCD HS Pulse-width */

        s->hsync = value & 0xff;

        break;

    case 0x36:	/* LCD HS Pulse Start Position */

        s->skipx = value & 0xff;

        break;

    case 0x38:	/* LCD VS Pulse-width */

        s->vsync = value & 0xbf;

        break;

    case 0x3a:	/* LCD VS Pulse Start Position */

        s->skipy = value & 0xff;

        break;

    case 0x3c:	/* PCLK Polarity */

        s->pclk = value & 0x82;

        /* Affects calculation of s->hndp, s->hsync and s->skipx.  */

        break;

    case 0x3e:	/* High-speed Serial Interface Tx Configuration Port 0 */

        s->hssi_config[0] = value;

        break;

    case 0x40:	/* High-speed Serial Interface Tx Configuration Port 1 */

        s->hssi_config[1] = value;

        if (((value >> 4) & 3) == 3)

            fprintf(stderr, "%s: Illegal active-data-links value\n",

                            __FUNCTION__);

        break;

    case 0x42:	/* High-speed Serial Interface Tx Mode */

        s->hssi_config[2] = value & 0xbd;

        break;

    case 0x44:	/* TV Display Configuration */

        s->tv_config = value & 0xfe;

        break;

    case 0x46 ... 0x4c:	/* TV Vertical Blanking Interval Data bits 0 */

        s->tv_timing[(reg - 0x46) >> 1] = value;

        break;

    case 0x4e:	/* VBI: Closed Caption / XDS Control / Status */

        s->vbi = value;

        break;

    case 0x50:	/* TV Horizontal Start Position */

        s->tv_x = value;

        break;

    case 0x52:	/* TV Vertical Start Position */

        s->tv_y = value & 0x7f;

        break;

    case 0x54:	/* TV Test Pattern Setting */

        s->tv_test = value;

        break;

    case 0x56:	/* TV Filter Setting */

        s->tv_filter_config = value & 0xbf;

        break;

    case 0x58:	/* TV Filter Coefficient Index */

        s->tv_filter_idx = value & 0x1f;

        break;

    case 0x5a:	/* TV Filter Coefficient Data */

        if (s->tv_filter_idx < 0x20)

            s->tv_filter_coeff[s->tv_filter_idx ++] = value;

        break;

    case 0x60:	/* Input YUV/RGB Translate Mode 0 */

        s->yrc[0] = value & 0xb0;

        break;

    case 0x62:	/* Input YUV/RGB Translate Mode 1 */

        s->yrc[1] = value & 0x30;

        break;

    case 0x64:	/* U Data Fix */

        s->u = value & 0xff;

        break;

    case 0x66:	/* V Data Fix */

        s->v = value & 0xff;

        break;

    case 0x68:	/* Display Mode */

        if ((s->mode ^ value) & 3)

            s->invalidate = 1;

        s->mode = value & 0xb7;

        s->enable = value & 1;

        s->blank = (value >> 1) & 1;

        if (value & (1 << 4))

            fprintf(stderr, "%s: Macrovision enable attempt!\n", __FUNCTION__);

        break;

    case 0x6a:	/* Special Effects */

        s->effect = value & 0xfb;

        break;

    case 0x6c:	/* Input Window X Start Position 0 */

        s->ix[0] &= 0x300;

        s->ix[0] |= (value << 0) & 0x0ff;

        break;

    case 0x6e:	/* Input Window X Start Position 1 */

        s->ix[0] &= 0x0ff;

        s->ix[0] |= (value << 8) & 0x300;

        break;

    case 0x70:	/* Input Window Y Start Position 0 */

        s->iy[0] &= 0x300;

        s->iy[0] |= (value << 0) & 0x0ff;

        break;

    case 0x72:	/* Input Window Y Start Position 1 */

        s->iy[0] &= 0x0ff;

        s->iy[0] |= (value << 8) & 0x300;

        break;

    case 0x74:	/* Input Window X End Position 0 */

        s->ix[1] &= 0x300;

        s->ix[1] |= (value << 0) & 0x0ff;

        break;

    case 0x76:	/* Input Window X End Position 1 */

        s->ix[1] &= 0x0ff;

        s->ix[1] |= (value << 8) & 0x300;

        break;

    case 0x78:	/* Input Window Y End Position 0 */

        s->iy[1] &= 0x300;

        s->iy[1] |= (value << 0) & 0x0ff;

        break;

    case 0x7a:	/* Input Window Y End Position 1 */

        s->iy[1] &= 0x0ff;

        s->iy[1] |= (value << 8) & 0x300;

        break;

    case 0x7c:	/* Output Window X Start Position 0 */

        s->ox[0] &= 0x300;

        s->ox[0] |= (value << 0) & 0x0ff;

        break;

    case 0x7e:	/* Output Window X Start Position 1 */

        s->ox[0] &= 0x0ff;

        s->ox[0] |= (value << 8) & 0x300;

        break;

    case 0x80:	/* Output Window Y Start Position 0 */

        s->oy[0] &= 0x300;

        s->oy[0] |= (value << 0) & 0x0ff;

        break;

    case 0x82:	/* Output Window Y Start Position 1 */

        s->oy[0] &= 0x0ff;

        s->oy[0] |= (value << 8) & 0x300;

        break;

    case 0x84:	/* Output Window X End Position 0 */

        s->ox[1] &= 0x300;

        s->ox[1] |= (value << 0) & 0x0ff;

        break;

    case 0x86:	/* Output Window X End Position 1 */

        s->ox[1] &= 0x0ff;

        s->ox[1] |= (value << 8) & 0x300;

        break;

    case 0x88:	/* Output Window Y End Position 0 */

        s->oy[1] &= 0x300;

        s->oy[1] |= (value << 0) & 0x0ff;

        break;

    case 0x8a:	/* Output Window Y End Position 1 */

        s->oy[1] &= 0x0ff;

        s->oy[1] |= (value << 8) & 0x300;

        break;

    case 0x8c:	/* Input Data Format */

        s->iformat = value & 0xf;

        s->bpp = blizzard_iformat_bpp[s->iformat];

        if (!s->bpp)

            fprintf(stderr, "%s: Illegal or unsupported input format %x\n",

                            __FUNCTION__, s->iformat);

        break;

    case 0x8e:	/* Data Source Select */

        s->source = value & 7;

        /* Currently all windows will be "destructive overlays".  */

        if ((!(s->effect & (1 << 3)) && (s->ix[0] != s->ox[0] ||

                                        s->iy[0] != s->oy[0] ||

                                        s->ix[1] != s->ox[1] ||

                                        s->iy[1] != s->oy[1])) ||

                        !((s->ix[1] - s->ix[0]) & (s->iy[1] - s->iy[0]) &

                          (s->ox[1] - s->ox[0]) & (s->oy[1] - s->oy[0]) & 1))

            fprintf(stderr, "%s: Illegal input/output window positions\n",

                            __FUNCTION__);

        blizzard_transfer_setup(s);

        break;

    case 0x90:	/* Display Memory Data Port */

        if (!s->data.len && !blizzard_transfer_setup(s))

            break;

        *s->data.ptr ++ = value;

        if (-- s->data.len == 0)

            blizzard_window(s);

        break;

    case 0xa8:	/* Border Color 0 */

        s->border_r = value;

        break;

    case 0xaa:	/* Border Color 1 */

        s->border_g = value;

        break;

    case 0xac:	/* Border Color 2 */

        s->border_b = value;

        break;

    case 0xb4:	/* Gamma Correction Enable */

        s->gamma_config = value & 0x87;

        break;

    case 0xb6:	/* Gamma Correction Table Index */

        s->gamma_idx = value;

        break;

    case 0xb8:	/* Gamma Correction Table Data */

        s->gamma_lut[s->gamma_idx ++] = value;

        break;

    case 0xba:	/* 3x3 Matrix Enable */

        s->matrix_ena = value & 1;

        break;

    case 0xbc ... 0xde:	/* Coefficient Registers */

        s->matrix_coeff[(reg - 0xbc) >> 1] = value & ((reg & 2) ? 0x80 : 0xff);

        break;

    case 0xe0:	/* 3x3 Matrix Red Offset */

        s->matrix_r = value;

        break;

    case 0xe2:	/* 3x3 Matrix Green Offset */

        s->matrix_g = value;

        break;

    case 0xe4:	/* 3x3 Matrix Blue Offset */

        s->matrix_b = value;

        break;

    case 0xe6:	/* Power-save */

        s->pm = value & 0x83;

        if (value & s->mode & 1)

            fprintf(stderr, "%s: The display must be disabled before entering "

                            "Standby Mode\n", __FUNCTION__);

        break;

    case 0xe8:	/* Non-display Period Control / Status */

        s->status = value & 0x1b;

        break;

    case 0xea:	/* RGB Interface Control */

        s->rgbgpio_dir = value & 0x8f;

        break;

    case 0xec:	/* RGB Interface Status */

        s->rgbgpio = value & 0xcf;

        break;

    case 0xee:	/* General-purpose IO Pins Configuration */

        s->gpio_dir = value;

        break;

    case 0xf0:	/* General-purpose IO Pins Status / Control */

        s->gpio = value;

        break;

    case 0xf2:	/* GPIO Positive Edge Interrupt Trigger */

        s->gpio_edge[0] = value;

        break;

    case 0xf4:	/* GPIO Negative Edge Interrupt Trigger */

        s->gpio_edge[1] = value;

        break;

    case 0xf6:	/* GPIO Interrupt Status */

        s->gpio_irq &= value;

        break;

    case 0xf8:	/* GPIO Pull-down Control */

        s->gpio_pdown = value;

        break;

    default:

        fprintf(stderr, "%s: unknown register %02x\n", __FUNCTION__, reg);

        break;

    }

}


uint64_t qcrypto_pbkdf2_count_iters(QCryptoHashAlgorithm hash,

                                    const uint8_t *key, size_t nkey,

                                    const uint8_t *salt, size_t nsalt,

                                    Error **errp)

{

    uint8_t out[32];

    uint64_t iterations = (1 << 15);

    unsigned long long delta_ms, start_ms, end_ms;

    while (1) {

        if (qcrypto_pbkdf2_get_thread_cpu(&start_ms, errp) < 0) {

            return -1;

        }

        if (qcrypto_pbkdf2(hash,

                           key, nkey,

                           salt, nsalt,

                           iterations,

                           out, sizeof(out),

                           errp) < 0) {

            return -1;

        }

        if (qcrypto_pbkdf2_get_thread_cpu(&end_ms, errp) < 0) {

            return -1;

        }

        delta_ms = end_ms - start_ms;

        if (delta_ms > 500) {

            break;

        } else if (delta_ms < 100) {

            iterations = iterations * 10;

        } else {

            iterations = (iterations * 1000 / delta_ms);

        }

    }

    iterations = iterations * 1000 / delta_ms;

    return iterations;

}


static int pci_device_hot_remove(Monitor *mon, const char *pci_addr)

{

    PCIDevice *d;

    int dom, bus;

    unsigned slot;

    Error *local_err = NULL;

    if (pci_read_devaddr(mon, pci_addr, &dom, &bus, &slot)) {

        return -1;

    }

    d = pci_find_device(pci_find_root_bus(dom), bus, PCI_DEVFN(slot, 0));

    if (!d) {

        monitor_printf(mon, "slot %d empty\n", slot);

        return -1;

    }

    qdev_unplug(&d->qdev, &local_err);

    if (error_is_set(&local_err)) {

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

        error_free(local_err);

        return -1;

    }

    return 0;

}


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

{

    Error *err = NULL;

    MemdevList *memdev_list = qmp_query_memdev(&err);

    MemdevList *m = memdev_list;

    StringOutputVisitor *ov;

    char *str;

    int i = 0;

    while (m) {

        ov = string_output_visitor_new(false);

        visit_type_uint16List(string_output_get_visitor(ov), NULL,

                              &m->value->host_nodes, NULL);

        monitor_printf(mon, "memory backend: %d\n", i);

        monitor_printf(mon, "  size:  %" PRId64 "\n", m->value->size);

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

                       m->value->merge ? "true" : "false");

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

                       m->value->dump ? "true" : "false");

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

                       m->value->prealloc ? "true" : "false");

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

                       HostMemPolicy_lookup[m->value->policy]);

        str = string_output_get_string(ov);

        monitor_printf(mon, "  host nodes: %s\n", str);

        g_free(str);

        string_output_visitor_cleanup(ov);

        m = m->next;

        i++;

    }

    monitor_printf(mon, "\n");

    qapi_free_MemdevList(memdev_list);

}


static void apply_motion_8x8(RoqContext *ri, int x, int y,

    unsigned char mv, signed char mean_x, signed char mean_y)

{

    int mx, my, i, j, hw;

    unsigned char *pa, *pb;

    mx = x + 8 - (mv >> 4) - mean_x;

    my = y + 8 - (mv & 0xf) - mean_y;

    pa = ri->current_frame.data[0] + (y * ri->y_stride) + x;

    pb = ri->last_frame.data[0] + (my * ri->y_stride) + mx;

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

        pa[0] = pb[0];

        pa[1] = pb[1];

        pa[2] = pb[2];

        pa[3] = pb[3];

        pa[4] = pb[4];

        pa[5] = pb[5];

        pa[6] = pb[6];

        pa[7] = pb[7];

        pa += ri->y_stride;

        pb += ri->y_stride;

    }

#if 0

    pa = ri->current_frame.data[1] + (y/2) * (ri->c_stride) + x/2;

    pb = ri->last_frame.data[1] + (my/2) * (ri->c_stride) + (mx + 1)/2;

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

        pa[0] = pb[0];

        pa[1] = pb[1];

        pa[2] = pb[2];

        pa[3] = pb[3];

        pa += ri->c_stride;

        pb += ri->c_stride;

    }

    pa = ri->current_frame.data[2] + (y/2) * (ri->c_stride) + x/2;

    pb = ri->last_frame.data[2] + (my/2) * (ri->c_stride) + (mx + 1)/2;

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

        pa[0] = pb[0];

        pa[1] = pb[1];

        pa[2] = pb[2];

        pa[3] = pb[3];

        pa += ri->c_stride;

        pb += ri->c_stride;

    }

#else

    hw = ri->c_stride;

    pa = ri->current_frame.data[1] + (y * ri->y_stride)/4 + x/2;

    pb = ri->last_frame.data[1] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;

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

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

            switch(((my & 0x01) << 1) | (mx & 0x01)) {

            case 0:

                pa[0] = pb[0];

                pa[1] = pb[1];

                pa[2] = pb[2];

                pa[3] = pb[3];

                break;

            case 1:

                pa[0] = avg2(pb[0], pb[1]);

                pa[1] = avg2(pb[1], pb[2]);

                pa[2] = avg2(pb[2], pb[3]);

                pa[3] = avg2(pb[3], pb[4]);

                break;

            case 2:

                pa[0] = avg2(pb[0], pb[hw]);

                pa[1] = avg2(pb[1], pb[hw+1]);

                pa[2] = avg2(pb[2], pb[hw+2]);

                pa[3] = avg2(pb[3], pb[hw+3]);

                break;

            case 3:

                pa[0] = avg4(pb[0], pb[1], pb[hw], pb[hw+1]);

                pa[1] = avg4(pb[1], pb[2], pb[hw+1], pb[hw+2]);

                pa[2] = avg4(pb[2], pb[3], pb[hw+2], pb[hw+3]);

                pa[3] = avg4(pb[3], pb[4], pb[hw+3], pb[hw+4]);

                break;

            }

            pa += ri->c_stride;

            pb += ri->c_stride;

        }

        pa = ri->current_frame.data[2] + (y * ri->y_stride)/4 + x/2;

        pb = ri->last_frame.data[2] + (my/2) * (ri->y_stride/2) + (mx + 1)/2;

    }

#endif

}


void ff_avg_dirac_pixels16_sse2(uint8_t *dst, const uint8_t *src[5], int stride, int h)

{

    if (h&3)

        ff_avg_dirac_pixels16_c(dst, src, stride, h);

    else

    ff_avg_pixels16_sse2(dst, src[0], stride, h);

}


int ff_ape_write_tag(AVFormatContext *s)

{

    AVDictionaryEntry *e = NULL;

    int64_t start, end;

    int size, count = 0;

    if (!s->pb->seekable)

        return 0;

    start = avio_tell(s->pb);

    // header

    avio_write(s->pb, "APETAGEX", 8);   // id

    avio_wl32 (s->pb, APE_TAG_VERSION); // version

    avio_wl32(s->pb, 0);                // reserve space for size

    avio_wl32(s->pb, 0);                // reserve space for tag count

    // flags

    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER |

                     APE_TAG_FLAG_IS_HEADER);

    ffio_fill(s->pb, 0, 8);             // reserved

    while ((e = av_dict_get(s->metadata, "", e, AV_DICT_IGNORE_SUFFIX))) {

        int val_len = strlen(e->value);

        avio_wl32(s->pb, val_len);            // value length

        avio_wl32(s->pb, 0);                  // item flags

        avio_put_str(s->pb, e->key);          // key

        avio_write(s->pb, e->value, val_len); // value

        count++;

    }

    size = avio_tell(s->pb) - start;

    // footer

    avio_write(s->pb, "APETAGEX", 8);   // id

    avio_wl32 (s->pb, APE_TAG_VERSION); // version

    avio_wl32(s->pb, size);             // size

    avio_wl32(s->pb, count);            // tag count

    // flags

    avio_wl32(s->pb, APE_TAG_FLAG_CONTAINS_HEADER | APE_TAG_FLAG_CONTAINS_FOOTER);

    ffio_fill(s->pb, 0, 8);             // reserved

    // update values in the header

    end = avio_tell(s->pb);

    avio_seek(s->pb, start + 12, SEEK_SET);

    avio_wl32(s->pb, size);

    avio_wl32(s->pb, count);

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

    return 0;

}


static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)

{

    const char *opn = "ldst";

    switch (opc) {

    case OPC_MFC0:

        if (rt == 0) {

            /* Treat as NOP. */

            return;

        }

        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);

        opn = "mfc0";

        break;

    case OPC_MTC0:

        {

            TCGv t0 = tcg_temp_new();

            gen_load_gpr(t0, rt);

            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);

            tcg_temp_free(t0);

        }

        opn = "mtc0";

        break;

#if defined(TARGET_MIPS64)

    case OPC_DMFC0:

        check_insn(env, ctx, ISA_MIPS3);

        if (rt == 0) {

            /* Treat as NOP. */

            return;

        }

        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);

        opn = "dmfc0";

        break;

    case OPC_DMTC0:

        check_insn(env, ctx, ISA_MIPS3);

        {

            TCGv t0 = tcg_temp_new();

            gen_load_gpr(t0, rt);

            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);

            tcg_temp_free(t0);

        }

        opn = "dmtc0";

        break;

#endif

    case OPC_MFTR:

        check_insn(env, ctx, ASE_MT);

        if (rd == 0) {

            /* Treat as NOP. */

            return;

        }

        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,

                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);

        opn = "mftr";

        break;

    case OPC_MTTR:

        check_insn(env, ctx, ASE_MT);

        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,

                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);

        opn = "mttr";

        break;

    case OPC_TLBWI:

        opn = "tlbwi";

        if (!env->tlb->helper_tlbwi)

            goto die;

        gen_helper_tlbwi();

        break;

    case OPC_TLBWR:

        opn = "tlbwr";

        if (!env->tlb->helper_tlbwr)

            goto die;

        gen_helper_tlbwr();

        break;

    case OPC_TLBP:

        opn = "tlbp";

        if (!env->tlb->helper_tlbp)

            goto die;

        gen_helper_tlbp();

        break;

    case OPC_TLBR:

        opn = "tlbr";

        if (!env->tlb->helper_tlbr)

            goto die;

        gen_helper_tlbr();

        break;

    case OPC_ERET:

        opn = "eret";

        check_insn(env, ctx, ISA_MIPS2);

        gen_helper_eret();

        ctx->bstate = BS_EXCP;

        break;

    case OPC_DERET:

        opn = "deret";

        check_insn(env, ctx, ISA_MIPS32);

        if (!(ctx->hflags & MIPS_HFLAG_DM)) {

            MIPS_INVAL(opn);

            generate_exception(ctx, EXCP_RI);

        } else {

            gen_helper_deret();

            ctx->bstate = BS_EXCP;

        }

        break;

    case OPC_WAIT:

        opn = "wait";

        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);

        /* If we get an exception, we want to restart at next instruction */

        ctx->pc += 4;

        save_cpu_state(ctx, 1);

        ctx->pc -= 4;

        gen_helper_wait();

        ctx->bstate = BS_EXCP;

        break;

    default:

 die:

        MIPS_INVAL(opn);

        generate_exception(ctx, EXCP_RI);

        return;

    }

    (void)opn; /* avoid a compiler warning */

    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);

}


static inline uint64_t v4l2_get_pts(V4L2Buffer *avbuf)

{

    V4L2m2mContext *s = buf_to_m2mctx(avbuf);

    AVRational v4l2_timebase = { 1, USEC_PER_SEC };

    int64_t v4l2_pts;

    /* convert pts back to encoder timebase */

    v4l2_pts = avbuf->buf.timestamp.tv_sec * USEC_PER_SEC + avbuf->buf.timestamp.tv_usec;

    return av_rescale_q(v4l2_pts, v4l2_timebase, s->avctx->time_base);

}


static int parallels_create(const char *filename, QemuOpts *opts, Error **errp)

{

    int64_t total_size, cl_size;

    uint8_t tmp[BDRV_SECTOR_SIZE];

    Error *local_err = NULL;

    BlockBackend *file;

    uint32_t bat_entries, bat_sectors;

    ParallelsHeader header;

    int ret;

    total_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),

                          BDRV_SECTOR_SIZE);

    cl_size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE,

                          DEFAULT_CLUSTER_SIZE), BDRV_SECTOR_SIZE);

    ret = bdrv_create_file(filename, opts, &local_err);

    if (ret < 0) {

        return ret;

    file = blk_new_open(filename, NULL, NULL,

                        BDRV_O_RDWR | BDRV_O_PROTOCOL, &local_err);

    if (file == NULL) {

        return -EIO;

    blk_set_allow_write_beyond_eof(file, true);

    ret = blk_truncate(file, 0);

    if (ret < 0) {

        goto exit;

    bat_entries = DIV_ROUND_UP(total_size, cl_size);

    bat_sectors = DIV_ROUND_UP(bat_entry_off(bat_entries), cl_size);

    bat_sectors = (bat_sectors *  cl_size) >> BDRV_SECTOR_BITS;

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

    memcpy(header.magic, HEADER_MAGIC2, sizeof(header.magic));

    header.version = cpu_to_le32(HEADER_VERSION);

    /* don't care much about geometry, it is not used on image level */

    header.heads = cpu_to_le32(16);

    header.cylinders = cpu_to_le32(total_size / BDRV_SECTOR_SIZE / 16 / 32);

    header.tracks = cpu_to_le32(cl_size >> BDRV_SECTOR_BITS);

    header.bat_entries = cpu_to_le32(bat_entries);

    header.nb_sectors = cpu_to_le64(DIV_ROUND_UP(total_size, BDRV_SECTOR_SIZE));

    header.data_off = cpu_to_le32(bat_sectors);

    /* write all the data */

    memset(tmp, 0, sizeof(tmp));

    memcpy(tmp, &header, sizeof(header));

    ret = blk_pwrite(file, 0, tmp, BDRV_SECTOR_SIZE, 0);

    if (ret < 0) {

        goto exit;

    ret = blk_pwrite_zeroes(file, BDRV_SECTOR_SIZE,

                            (bat_sectors - 1) << BDRV_SECTOR_BITS, 0);

    if (ret < 0) {

        goto exit;

    ret = 0;

done:

    blk_unref(file);

    return ret;

exit:

    error_setg_errno(errp, -ret, "Failed to create Parallels image");

    goto done;


static int stdio_put_buffer(void *opaque, const uint8_t *buf, int64_t pos,

                            int size)

{

    QEMUFileStdio *s = opaque;

    return fwrite(buf, 1, size, s->stdio_file);

}


void *address_space_map(AddressSpace *as,

                        hwaddr addr,

                        hwaddr *plen,

                        bool is_write)

{

    hwaddr len = *plen;

    hwaddr done = 0;

    hwaddr l, xlat, base;

    MemoryRegion *mr, *this_mr;

    ram_addr_t raddr;

    if (len == 0) {

        return NULL;

    }

    l = len;

    mr = address_space_translate(as, addr, &xlat, &l, is_write);

    if (!memory_access_is_direct(mr, is_write)) {

        if (bounce.buffer) {

            return NULL;

        }

        /* Avoid unbounded allocations */

        l = MIN(l, TARGET_PAGE_SIZE);

        bounce.buffer = qemu_memalign(TARGET_PAGE_SIZE, l);

        bounce.addr = addr;

        bounce.len = l;

        memory_region_ref(mr);

        bounce.mr = mr;

        if (!is_write) {

            address_space_read(as, addr, bounce.buffer, l);

        }

        *plen = l;

        return bounce.buffer;

    }

    base = xlat;

    raddr = memory_region_get_ram_addr(mr);

    for (;;) {

        len -= l;

        addr += l;

        done += l;

        if (len == 0) {

            break;

        }

        l = len;

        this_mr = address_space_translate(as, addr, &xlat, &l, is_write);

        if (this_mr != mr || xlat != base + done) {

            break;

        }

    }

    memory_region_ref(mr);

    *plen = done;

    return qemu_ram_ptr_length(raddr + base, plen);

}