static void *source_return_path_thread(void *opaque)

{

    MigrationState *ms = opaque;

    QEMUFile *rp = ms->rp_state.from_dst_file;

    uint16_t header_len, header_type;

    const int max_len = 512;

    uint8_t buf[max_len];

    uint32_t tmp32, sibling_error;

    ram_addr_t start = 0; /* =0 to silence warning */

    size_t  len = 0, expected_len;

    int res;

    trace_source_return_path_thread_entry();

    while (!ms->rp_state.error && !qemu_file_get_error(rp) &&

           migration_is_setup_or_active(ms->state)) {

        trace_source_return_path_thread_loop_top();

        header_type = qemu_get_be16(rp);

        header_len = qemu_get_be16(rp);

        if (header_type >= MIG_RP_MSG_MAX ||

            header_type == MIG_RP_MSG_INVALID) {

            error_report("RP: Received invalid message 0x%04x length 0x%04x",

                    header_type, header_len);

            mark_source_rp_bad(ms);

            goto out;

        }

        if ((rp_cmd_args[header_type].len != -1 &&

            header_len != rp_cmd_args[header_type].len) ||

            header_len > max_len) {

            error_report("RP: Received '%s' message (0x%04x) with"

                    "incorrect length %d expecting %zu",

                    rp_cmd_args[header_type].name, header_type, header_len,

                    (size_t)rp_cmd_args[header_type].len);

            mark_source_rp_bad(ms);

            goto out;

        }

        /* We know we've got a valid header by this point */

        res = qemu_get_buffer(rp, buf, header_len);

        if (res != header_len) {

            error_report("RP: Failed reading data for message 0x%04x"

                         " read %d expected %d",

                         header_type, res, header_len);

            mark_source_rp_bad(ms);

            goto out;

        }

        /* OK, we have the message and the data */

        switch (header_type) {

        case MIG_RP_MSG_SHUT:

            sibling_error = be32_to_cpup((uint32_t *)buf);

            trace_source_return_path_thread_shut(sibling_error);

            if (sibling_error) {

                error_report("RP: Sibling indicated error %d", sibling_error);

                mark_source_rp_bad(ms);

            }

            /*

             * We'll let the main thread deal with closing the RP

             * we could do a shutdown(2) on it, but we're the only user

             * anyway, so there's nothing gained.

             */

            goto out;

        case MIG_RP_MSG_PONG:

            tmp32 = be32_to_cpup((uint32_t *)buf);

            trace_source_return_path_thread_pong(tmp32);

            break;

        case MIG_RP_MSG_REQ_PAGES:

            start = be64_to_cpup((uint64_t *)buf);

            len = be32_to_cpup((uint32_t *)(buf + 8));

            migrate_handle_rp_req_pages(ms, NULL, start, len);

            break;

        case MIG_RP_MSG_REQ_PAGES_ID:

            expected_len = 12 + 1; /* header + termination */

            if (header_len >= expected_len) {

                start = be64_to_cpup((uint64_t *)buf);

                len = be32_to_cpup((uint32_t *)(buf + 8));

                /* Now we expect an idstr */

                tmp32 = buf[12]; /* Length of the following idstr */

                buf[13 + tmp32] = '\0';

                expected_len += tmp32;

            }

            if (header_len != expected_len) {

                error_report("RP: Req_Page_id with length %d expecting %zd",

                        header_len, expected_len);

                mark_source_rp_bad(ms);

                goto out;

            }

            migrate_handle_rp_req_pages(ms, (char *)&buf[13], start, len);

            break;

        default:

            break;

        }

    }

    if (rp && qemu_file_get_error(rp)) {

        trace_source_return_path_thread_bad_end();

        mark_source_rp_bad(ms);

    }

    trace_source_return_path_thread_end();

out:

    ms->rp_state.from_dst_file = NULL;

    qemu_fclose(rp);

    return NULL;

}


static int bdrv_qed_do_open(BlockDriverState *bs, QDict *options, int flags,

                            Error **errp)

{

    BDRVQEDState *s = bs->opaque;

    QEDHeader le_header;

    int64_t file_size;

    int ret;

    s->bs = bs;

    qemu_co_queue_init(&s->allocating_write_reqs);

    ret = bdrv_pread(bs->file, 0, &le_header, sizeof(le_header));

    if (ret < 0) {

        return ret;

    }

    qed_header_le_to_cpu(&le_header, &s->header);

    if (s->header.magic != QED_MAGIC) {

        error_setg(errp, "Image not in QED format");

        return -EINVAL;

    }

    if (s->header.features & ~QED_FEATURE_MASK) {

        /* image uses unsupported feature bits */

        error_setg(errp, "Unsupported QED features: %" PRIx64,

                   s->header.features & ~QED_FEATURE_MASK);

        return -ENOTSUP;

    }

    if (!qed_is_cluster_size_valid(s->header.cluster_size)) {

        return -EINVAL;

    }

    /* Round down file size to the last cluster */

    file_size = bdrv_getlength(bs->file->bs);

    if (file_size < 0) {

        return file_size;

    }

    s->file_size = qed_start_of_cluster(s, file_size);

    if (!qed_is_table_size_valid(s->header.table_size)) {

        return -EINVAL;

    }

    if (!qed_is_image_size_valid(s->header.image_size,

                                 s->header.cluster_size,

                                 s->header.table_size)) {

        return -EINVAL;

    }

    if (!qed_check_table_offset(s, s->header.l1_table_offset)) {

        return -EINVAL;

    }

    s->table_nelems = (s->header.cluster_size * s->header.table_size) /

                      sizeof(uint64_t);

    s->l2_shift = ctz32(s->header.cluster_size);

    s->l2_mask = s->table_nelems - 1;

    s->l1_shift = s->l2_shift + ctz32(s->table_nelems);

    /* Header size calculation must not overflow uint32_t */

    if (s->header.header_size > UINT32_MAX / s->header.cluster_size) {

        return -EINVAL;

    }

    if ((s->header.features & QED_F_BACKING_FILE)) {

        if ((uint64_t)s->header.backing_filename_offset +

            s->header.backing_filename_size >

            s->header.cluster_size * s->header.header_size) {

            return -EINVAL;

        }

        ret = qed_read_string(bs->file, s->header.backing_filename_offset,

                              s->header.backing_filename_size, bs->backing_file,

                              sizeof(bs->backing_file));

        if (ret < 0) {

            return ret;

        }

        if (s->header.features & QED_F_BACKING_FORMAT_NO_PROBE) {

            pstrcpy(bs->backing_format, sizeof(bs->backing_format), "raw");

        }

    }

    /* Reset unknown autoclear feature bits.  This is a backwards

     * compatibility mechanism that allows images to be opened by older

     * programs, which "knock out" unknown feature bits.  When an image is

     * opened by a newer program again it can detect that the autoclear

     * feature is no longer valid.

     */

    if ((s->header.autoclear_features & ~QED_AUTOCLEAR_FEATURE_MASK) != 0 &&

        !bdrv_is_read_only(bs->file->bs) && !(flags & BDRV_O_INACTIVE)) {

        s->header.autoclear_features &= QED_AUTOCLEAR_FEATURE_MASK;

        ret = qed_write_header_sync(s);

        if (ret) {

            return ret;

        }

        /* From here on only known autoclear feature bits are valid */

        bdrv_flush(bs->file->bs);

    }

    s->l1_table = qed_alloc_table(s);

    qed_init_l2_cache(&s->l2_cache);

    ret = qed_read_l1_table_sync(s);

    if (ret) {

        goto out;

    }

    /* If image was not closed cleanly, check consistency */

    if (!(flags & BDRV_O_CHECK) && (s->header.features & QED_F_NEED_CHECK)) {

        /* Read-only images cannot be fixed.  There is no risk of corruption

         * since write operations are not possible.  Therefore, allow

         * potentially inconsistent images to be opened read-only.  This can

         * aid data recovery from an otherwise inconsistent image.

         */

        if (!bdrv_is_read_only(bs->file->bs) &&

            !(flags & BDRV_O_INACTIVE)) {

            BdrvCheckResult result = {0};

            ret = qed_check(s, &result, true);

            if (ret) {

                goto out;

            }

        }

    }

    bdrv_qed_attach_aio_context(bs, bdrv_get_aio_context(bs));

out:

    if (ret) {

        qed_free_l2_cache(&s->l2_cache);

        qemu_vfree(s->l1_table);

    }

    return ret;

}


static void put_pixels_x2_mmx(UINT8 *block, const UINT8 *pixels, int line_size, int h)

{

#if 0

  UINT8 *p;

  const UINT8 *pix;

  p = block;

  pix = pixels;

  MOVQ_ZERO(mm7);

  MOVQ_WONE(mm4);

  JUMPALIGN();

  do {

      __asm __volatile(

	"movq	%1, %%mm0\n\t"

	"movq	1%1, %%mm1\n\t"

	"movq	%%mm0, %%mm2\n\t"

	"movq	%%mm1, %%mm3\n\t"

	"punpcklbw %%mm7, %%mm0\n\t"

	"punpcklbw %%mm7, %%mm1\n\t"

	"punpckhbw %%mm7, %%mm2\n\t"

	"punpckhbw %%mm7, %%mm3\n\t"

	"paddusw %%mm1, %%mm0\n\t"

	"paddusw %%mm3, %%mm2\n\t"

	"paddusw %%mm4, %%mm0\n\t"

	"paddusw %%mm4, %%mm2\n\t"

	"psrlw	$1, %%mm0\n\t"

	"psrlw	$1, %%mm2\n\t"

	"packuswb  %%mm2, %%mm0\n\t"

	"movq	%%mm0, %0\n\t"

	:"=m"(*p)

	:"m"(*pix)

		       :"memory");

   pix += line_size; p += line_size;

  } while (--h);

#else

  __asm __volatile(

  	MOVQ_BFE(%%mm7)

	"lea (%3, %3), %%eax	\n\t"

	".balign 8     		\n\t"

	"1:			\n\t"

	"movq (%1), %%mm0	\n\t"

	"movq (%1, %3), %%mm2	\n\t"

	"movq 1(%1), %%mm1	\n\t"

	"movq 1(%1, %3), %%mm3	\n\t"

	PAVG_MMX(%%mm0, %%mm1)

	"movq %%mm6, (%2)	\n\t"

	PAVG_MMX(%%mm2, %%mm3)

	"movq %%mm6, (%2, %3)	\n\t"

	"addl %%eax, %1		\n\t"

	"addl %%eax, %2		\n\t"

#if LONG_UNROLL

	"movq (%1), %%mm0	\n\t"

	"movq (%1, %3), %%mm2	\n\t"

	"movq 1(%1), %%mm1	\n\t"

	"movq 1(%1, %3), %%mm3	\n\t"

	PAVG_MMX(%%mm0, %%mm1)

	"movq %%mm6, (%2)	\n\t"

	PAVG_MMX(%%mm2, %%mm3)

	"movq %%mm6, (%2, %3)	\n\t"

	"addl %%eax, %1		\n\t"

	"addl %%eax, %2		\n\t"

	"subl $4, %0		\n\t"

#else

	"subl $2, %0		\n\t"

#endif

	"jnz 1b			\n\t"

	:"+g"(h), "+S"(pixels), "+D"(block)

	:"r"(line_size)

	:"eax", "memory");

#endif

}


static void pc_dimm_post_plug(HotplugHandler *hotplug_dev,

                              DeviceState *dev, Error **errp)

{

    PCMachineState *pcms = PC_MACHINE(hotplug_dev);

    if (object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM)) {

        nvdimm_acpi_hotplug(&pcms->acpi_nvdimm_state);

    }

}


static VFIOINTp *vfio_init_intp(VFIODevice *vbasedev,

                                struct vfio_irq_info info)

{

    int ret;

    VFIOPlatformDevice *vdev =

        container_of(vbasedev, VFIOPlatformDevice, vbasedev);

    SysBusDevice *sbdev = SYS_BUS_DEVICE(vdev);

    VFIOINTp *intp;

    intp = g_malloc0(sizeof(*intp));

    intp->vdev = vdev;

    intp->pin = info.index;

    intp->flags = info.flags;

    intp->state = VFIO_IRQ_INACTIVE;

    intp->kvm_accel = false;

    sysbus_init_irq(sbdev, &intp->qemuirq);

    /* Get an eventfd for trigger */

    ret = event_notifier_init(&intp->interrupt, 0);

    if (ret) {

        g_free(intp);

        error_report("vfio: Error: trigger event_notifier_init failed ");

        return NULL;

    }

    /* Get an eventfd for resample/unmask */

    ret = event_notifier_init(&intp->unmask, 0);

    if (ret) {

        g_free(intp);

        error_report("vfio: Error: resamplefd event_notifier_init failed");

        return NULL;

    }

    QLIST_INSERT_HEAD(&vdev->intp_list, intp, next);

    return intp;

}


static void set_guest_connected(VirtIOSerialPort *port, int guest_connected)

{

    VirtConsole *vcon = VIRTIO_CONSOLE(port);

    if (!vcon->chr) {

        return;

    }

    qemu_chr_fe_set_open(vcon->chr, guest_connected);

}


static int raw_probe_geometry(BlockDriverState *bs, HDGeometry *geo)

{

    BDRVRawState *s = bs->opaque;

    if (s->offset || s->has_size) {

        return -ENOTSUP;

    }

    return bdrv_probe_geometry(bs->file->bs, geo);

}


static void empty_slot_write(void *opaque, target_phys_addr_t addr,

                             uint64_t val, unsigned size)

{

    DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr);

}


static int nbd_co_readv_1(NbdClientSession *client, int64_t sector_num,

                          int nb_sectors, QEMUIOVector *qiov,

                          int offset)

{

    struct nbd_request request = { .type = NBD_CMD_READ };

    struct nbd_reply reply;

    ssize_t ret;

    request.from = sector_num * 512;

    request.len = nb_sectors * 512;

    nbd_coroutine_start(client, &request);

    ret = nbd_co_send_request(client, &request, NULL, 0);

    if (ret < 0) {

        reply.error = -ret;

    } else {

        nbd_co_receive_reply(client, &request, &reply, qiov, offset);

    }

    nbd_coroutine_end(client, &request);

    return -reply.error;

}


static void *legacy_s390_alloc(size_t size)

{

    void *mem;

    mem = mmap((void *) 0x800000000ULL, size,

               PROT_EXEC|PROT_READ|PROT_WRITE,

               MAP_SHARED | MAP_ANONYMOUS | MAP_FIXED, -1, 0);

    return mem == MAP_FAILED ? NULL : mem;

}


static CharDriverState *chr_open(const char *subtype,

    void (*set_fe_open)(struct CharDriverState *, int))

{

    CharDriverState *chr;

    SpiceCharDriver *s;

    chr = g_malloc0(sizeof(CharDriverState));

    s = g_malloc0(sizeof(SpiceCharDriver));

    s->chr = chr;

    s->active = false;

    s->sin.subtype = g_strdup(subtype);

    chr->opaque = s;

    chr->chr_write = spice_chr_write;

    chr->chr_add_watch = spice_chr_add_watch;

    chr->chr_close = spice_chr_close;

    chr->chr_set_fe_open = set_fe_open;

    chr->explicit_be_open = true;

    chr->chr_fe_event = spice_chr_fe_event;

    QLIST_INSERT_HEAD(&spice_chars, s, next);

    return chr;

}


static void do_drive_backup(const char *job_id, const char *device,

                            const char *target, bool has_format,

                            const char *format, enum MirrorSyncMode sync,

                            bool has_mode, enum NewImageMode mode,

                            bool has_speed, int64_t speed,

                            bool has_bitmap, const char *bitmap,

                            bool has_on_source_error,

                            BlockdevOnError on_source_error,

                            bool has_on_target_error,

                            BlockdevOnError on_target_error,

                            BlockJobTxn *txn, Error **errp)

{

    BlockBackend *blk;

    BlockDriverState *bs;

    BlockDriverState *target_bs;

    BlockDriverState *source = NULL;

    BdrvDirtyBitmap *bmap = NULL;

    AioContext *aio_context;

    QDict *options = NULL;

    Error *local_err = NULL;

    int flags;

    int64_t size;

    if (!has_speed) {

        speed = 0;

    }

    if (!has_on_source_error) {

        on_source_error = BLOCKDEV_ON_ERROR_REPORT;

    }

    if (!has_on_target_error) {

        on_target_error = BLOCKDEV_ON_ERROR_REPORT;

    }

    if (!has_mode) {

        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

    }

    blk = blk_by_name(device);

    if (!blk) {

        error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,

                  "Device '%s' not found", device);

        return;

    }

    aio_context = blk_get_aio_context(blk);

    aio_context_acquire(aio_context);

    /* Although backup_run has this check too, we need to use bs->drv below, so

     * do an early check redundantly. */

    if (!blk_is_available(blk)) {

        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);

        goto out;

    }

    bs = blk_bs(blk);

    if (!has_format) {

        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;

    }

    /* Early check to avoid creating target */

    if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {

        goto out;

    }

    flags = bs->open_flags | BDRV_O_RDWR;

    /* See if we have a backing HD we can use to create our new image

     * on top of. */

    if (sync == MIRROR_SYNC_MODE_TOP) {

        source = backing_bs(bs);

        if (!source) {

            sync = MIRROR_SYNC_MODE_FULL;

        }

    }

    if (sync == MIRROR_SYNC_MODE_NONE) {

        source = bs;

    }

    size = bdrv_getlength(bs);

    if (size < 0) {

        error_setg_errno(errp, -size, "bdrv_getlength failed");

        goto out;

    }

    if (mode != NEW_IMAGE_MODE_EXISTING) {

        assert(format);

        if (source) {

            bdrv_img_create(target, format, source->filename,

                            source->drv->format_name, NULL,

                            size, flags, &local_err, false);

        } else {

            bdrv_img_create(target, format, NULL, NULL, NULL,

                            size, flags, &local_err, false);

        }

    }

    if (local_err) {

        error_propagate(errp, local_err);

        goto out;

    }

    if (format) {

        options = qdict_new();

        qdict_put(options, "driver", qstring_from_str(format));

    }

    target_bs = bdrv_open(target, NULL, options, flags, errp);

    if (!target_bs) {

        goto out;

    }

    bdrv_set_aio_context(target_bs, aio_context);

    if (has_bitmap) {

        bmap = bdrv_find_dirty_bitmap(bs, bitmap);

        if (!bmap) {

            error_setg(errp, "Bitmap '%s' could not be found", bitmap);

            bdrv_unref(target_bs);

            goto out;

        }

    }

    backup_start(job_id, bs, target_bs, speed, sync, bmap,

                 on_source_error, on_target_error,

                 block_job_cb, bs, txn, &local_err);

    bdrv_unref(target_bs);

    if (local_err != NULL) {

        error_propagate(errp, local_err);

        goto out;

    }

out:

    aio_context_release(aio_context);

}


static int advanced_decode_i_mbs(VC9Context *v)

{

  int i, x, y, cbpcy, mqdiff, absmq, mquant, ac_pred, condover,

    current_mb = 0, over_flags_mb = 0;

    for (y=0; y<v->height_mb; y++)

    {

        for (x=0; x<v->width_mb; x++)

        {

            if (v->ac_pred_plane[i])

                ac_pred = get_bits(&v->gb, 1);

            if (condover == 3 && v->over_flags_plane)

                over_flags_mb = get_bits(&v->gb, 1);

            GET_MQUANT();

        }

        current_mb++;

    }

    return 0;

}


static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num,

                                 uint8_t *buf, int nb_sectors)

{

    BDRVCowState *s = bs->opaque;

    int ret, n;

    while (nb_sectors > 0) {

        ret = cow_co_is_allocated(bs, sector_num, nb_sectors, &n);

        if (ret < 0) {

            return ret;

        }

        if (ret) {

            ret = bdrv_pread(bs->file,

                        s->cow_sectors_offset + sector_num * 512,

                        buf, n * 512);

            if (ret < 0) {

                return ret;

            }

        } else {

            if (bs->backing_hd) {

                /* read from the base image */

                ret = bdrv_read(bs->backing_hd, sector_num, buf, n);

                if (ret < 0) {

                    return ret;

                }

            } else {

                memset(buf, 0, n * 512);

            }

        }

        nb_sectors -= n;

        sector_num += n;

        buf += n * 512;

    }

    return 0;

}


static void migration_end(void)

{

    if (migration_bitmap) {

        memory_global_dirty_log_stop();

        g_free(migration_bitmap);

        migration_bitmap = NULL;

    }

    XBZRLE_cache_lock();

    if (XBZRLE.cache) {

        cache_fini(XBZRLE.cache);

        g_free(XBZRLE.encoded_buf);

        g_free(XBZRLE.current_buf);

        XBZRLE.cache = NULL;

        XBZRLE.encoded_buf = NULL;

        XBZRLE.current_buf = NULL;

    }

    XBZRLE_cache_unlock();

}


static unsigned int dec_btst_r(DisasContext *dc)

{

	TCGv l0;

	DIS(fprintf (logfile, "btst $r%u, $r%u\n",

		    dc->op1, dc->op2));

	cris_cc_mask(dc, CC_MASK_NZ);

	l0 = tcg_temp_local_new(TCG_TYPE_TL);

	cris_alu(dc, CC_OP_BTST, l0, cpu_R[dc->op2], cpu_R[dc->op1], 4);

	cris_update_cc_op(dc, CC_OP_FLAGS, 4);

	t_gen_mov_preg_TN(dc, PR_CCS, l0);

	dc->flags_uptodate = 1;

	tcg_temp_free(l0);

	return 2;

}


event_thread(void *arg)

{

    unsigned char atr[MAX_ATR_LEN];

    int atr_len = MAX_ATR_LEN;

    VEvent *event = NULL;

    unsigned int reader_id;

    while (1) {

        const char *reader_name;

        event = vevent_wait_next_vevent();

        if (event == NULL) {

            break;

        }

        reader_id = vreader_get_id(event->reader);

        if (reader_id == VSCARD_UNDEFINED_READER_ID &&

            event->type != VEVENT_READER_INSERT) {

            /* ignore events from readers qemu has rejected */

            /* if qemu is still deciding on this reader, wait to see if need to

             * forward this event */

            qemu_mutex_lock(&pending_reader_lock);

            if (!pending_reader || (pending_reader != event->reader)) {

                /* wasn't for a pending reader, this reader has already been

                 * rejected by qemu */

                qemu_mutex_unlock(&pending_reader_lock);

                vevent_delete(event);

                continue;

            }

            /* this reader hasn't been told its status from qemu yet, wait for

             * that status */

            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            qemu_mutex_unlock(&pending_reader_lock);

            /* now recheck the id */

            reader_id = vreader_get_id(event->reader);

            if (reader_id == VSCARD_UNDEFINED_READER_ID) {

                /* this reader was rejected */

                vevent_delete(event);

                continue;

            }

            /* reader was accepted, now forward the event */

        }

        switch (event->type) {

        case VEVENT_READER_INSERT:

            /* tell qemu to insert a new CCID reader */

            /* wait until qemu has responded to our first reader insert

             * before we send a second. That way we won't confuse the responses

             * */

            qemu_mutex_lock(&pending_reader_lock);

            while (pending_reader != NULL) {

                qemu_cond_wait(&pending_reader_condition, &pending_reader_lock);

            }

            pending_reader = vreader_reference(event->reader);

            qemu_mutex_unlock(&pending_reader_lock);

            reader_name = vreader_get_name(event->reader);

            if (verbose > 10) {

                printf(" READER INSERT: %s\n", reader_name);

            }

            send_msg(VSC_ReaderAdd,

                reader_id, /* currerntly VSCARD_UNDEFINED_READER_ID */

                NULL, 0 /* TODO reader_name, strlen(reader_name) */);

            break;

        case VEVENT_READER_REMOVE:

            /* future, tell qemu that an old CCID reader has been removed */

            if (verbose > 10) {

                printf(" READER REMOVE: %u\n", reader_id);

            }

            send_msg(VSC_ReaderRemove, reader_id, NULL, 0);

            break;

        case VEVENT_CARD_INSERT:

            /* get the ATR (intended as a response to a power on from the

             * reader */

            atr_len = MAX_ATR_LEN;

            vreader_power_on(event->reader, atr, &atr_len);

            /* ATR call functions as a Card Insert event */

            if (verbose > 10) {

                printf(" CARD INSERT %u: ", reader_id);

                print_byte_array(atr, atr_len);

            }

            send_msg(VSC_ATR, reader_id, atr, atr_len);

            break;

        case VEVENT_CARD_REMOVE:

            /* Card removed */

            if (verbose > 10) {

                printf(" CARD REMOVE %u:\n", reader_id);

            }

            send_msg(VSC_CardRemove, reader_id, NULL, 0);

            break;

        default:

            break;

        }

        vevent_delete(event);

    }

    return NULL;

}


int qcow2_alloc_clusters_at(BlockDriverState *bs, uint64_t offset,

    int nb_clusters)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t cluster_index, refcount;

    uint64_t i;

    int ret;

    assert(nb_clusters >= 0);

    if (nb_clusters == 0) {

        return 0;

    }

    do {

        /* Check how many clusters there are free */

        cluster_index = offset >> s->cluster_bits;

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

            ret = qcow2_get_refcount(bs, cluster_index++, &refcount);

            if (ret < 0) {

                return ret;

            } else if (refcount != 0) {

                break;

            }

        }

        /* And then allocate them */

        ret = update_refcount(bs, offset, i << s->cluster_bits, 1, false,

                              QCOW2_DISCARD_NEVER);

    } while (ret == -EAGAIN);

    if (ret < 0) {

        return ret;

    }

    return i;

}


static int bochs_open(BlockDriverState *bs, const char *filename, int flags)

{

    BDRVBochsState *s = bs->opaque;

    int fd, i;

    struct bochs_header bochs;

    struct bochs_header_v1 header_v1;

    fd = open(filename, O_RDWR | O_BINARY);

    if (fd < 0) {

        fd = open(filename, O_RDONLY | O_BINARY);

        if (fd < 0)

            return -1;

    }

    bs->read_only = 1; // no write support yet

    s->fd = fd;

    if (read(fd, &bochs, sizeof(bochs)) != sizeof(bochs)) {

        goto fail;

    }

    if (strcmp(bochs.magic, HEADER_MAGIC) ||

        strcmp(bochs.type, REDOLOG_TYPE) ||

        strcmp(bochs.subtype, GROWING_TYPE) ||

	((le32_to_cpu(bochs.version) != HEADER_VERSION) &&

	(le32_to_cpu(bochs.version) != HEADER_V1))) {

        goto fail;

    }

    if (le32_to_cpu(bochs.version) == HEADER_V1) {

      memcpy(&header_v1, &bochs, sizeof(bochs));

      bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;

    } else {

      bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;

    }

    lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);

    s->catalog_size = le32_to_cpu(bochs.extra.redolog.catalog);

    s->catalog_bitmap = qemu_malloc(s->catalog_size * 4);

    if (read(s->fd, s->catalog_bitmap, s->catalog_size * 4) !=

	s->catalog_size * 4)

	goto fail;

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

	le32_to_cpus(&s->catalog_bitmap[i]);

    s->data_offset = le32_to_cpu(bochs.header) + (s->catalog_size * 4);

    s->bitmap_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.bitmap) - 1) / 512;

    s->extent_blocks = 1 + (le32_to_cpu(bochs.extra.redolog.extent) - 1) / 512;

    s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);

    return 0;

 fail:

    close(fd);

    return -1;

}


build_rsdp(GArray *rsdp_table, GArray *linker, unsigned rsdt)

{

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

    bios_linker_loader_alloc(linker, ACPI_BUILD_RSDP_FILE, 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;

    /* Point to RSDT */

    rsdp->rsdt_physical_address = cpu_to_le32(rsdt);

    /* Address to be filled by Guest linker */

    bios_linker_loader_add_pointer(linker, ACPI_BUILD_RSDP_FILE,

                                   ACPI_BUILD_TABLE_FILE,

                                   rsdp_table, &rsdp->rsdt_physical_address,

                                   sizeof rsdp->rsdt_physical_address);

    rsdp->checksum = 0;

    /* Checksum to be filled by Guest linker */

    bios_linker_loader_add_checksum(linker, ACPI_BUILD_RSDP_FILE,

                                    rsdp, rsdp, sizeof *rsdp, &rsdp->checksum);

    return rsdp_table;

}


static void kqemu_record_pc(unsigned long pc)

{

    unsigned long h;

    PCRecord **pr, *r;

    h = pc / PC_REC_SIZE;

    h = h ^ (h >> PC_REC_HASH_BITS);

    h &= (PC_REC_HASH_SIZE - 1);

    pr = &pc_rec_hash[h];

    for(;;) {

        r = *pr;

        if (r == NULL)

            break;

        if (r->pc == pc) {

            r->count++;

            return;

        }

        pr = &r->next;

    }

    r = malloc(sizeof(PCRecord));

    r->count = 1;

    r->pc = pc;

    r->next = NULL;

    *pr = r;

    nb_pc_records++;

}


int bdrv_has_zero_init_1(BlockDriverState *bs)

{

    return 1;

}


int ff_h264_decode_mb_cavlc(const H264Context *h, H264SliceContext *sl)

{

    int mb_xy;

    int partition_count;

    unsigned int mb_type, cbp;

    int dct8x8_allowed= h->pps.transform_8x8_mode;

    int decode_chroma = h->sps.chroma_format_idc == 1 || h->sps.chroma_format_idc == 2;

    const int pixel_shift = h->pixel_shift;

    mb_xy = sl->mb_xy = sl->mb_x + sl->mb_y*h->mb_stride;

    ff_tlog(h->avctx, "pic:%d mb:%d/%d\n", h->frame_num, sl->mb_x, sl->mb_y);

    cbp = 0; /* avoid warning. FIXME: find a solution without slowing

                down the code */

    if (sl->slice_type_nos != AV_PICTURE_TYPE_I) {

        if (sl->mb_skip_run == -1)

            sl->mb_skip_run = get_ue_golomb(&sl->gb);

        if (sl->mb_skip_run--) {

            if (FRAME_MBAFF(h) && (sl->mb_y & 1) == 0) {

                if (sl->mb_skip_run == 0)

                    sl->mb_mbaff = sl->mb_field_decoding_flag = get_bits1(&sl->gb);

            }

            decode_mb_skip(h, sl);

            return 0;

        }

    }

    if (FRAME_MBAFF(h)) {

        if ((sl->mb_y & 1) == 0)

            sl->mb_mbaff = sl->mb_field_decoding_flag = get_bits1(&sl->gb);

    }

    sl->prev_mb_skipped = 0;

    mb_type= get_ue_golomb(&sl->gb);

    if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {

        if(mb_type < 23){

            partition_count = ff_h264_b_mb_type_info[mb_type].partition_count;

            mb_type         = ff_h264_b_mb_type_info[mb_type].type;

        }else{

            mb_type -= 23;

            goto decode_intra_mb;

        }

    } else if (sl->slice_type_nos == AV_PICTURE_TYPE_P) {

        if(mb_type < 5){

            partition_count = ff_h264_p_mb_type_info[mb_type].partition_count;

            mb_type         = ff_h264_p_mb_type_info[mb_type].type;

        }else{

            mb_type -= 5;

            goto decode_intra_mb;

        }

    }else{

       assert(sl->slice_type_nos == AV_PICTURE_TYPE_I);

        if (sl->slice_type == AV_PICTURE_TYPE_SI && mb_type)

            mb_type--;

decode_intra_mb:

        if(mb_type > 25){

            av_log(h->avctx, AV_LOG_ERROR, "mb_type %d in %c slice too large at %d %d\n", mb_type, av_get_picture_type_char(sl->slice_type), sl->mb_x, sl->mb_y);

            return -1;

        }

        partition_count=0;

        cbp                      = ff_h264_i_mb_type_info[mb_type].cbp;

        sl->intra16x16_pred_mode = ff_h264_i_mb_type_info[mb_type].pred_mode;

        mb_type                  = ff_h264_i_mb_type_info[mb_type].type;

    }

    if (MB_FIELD(sl))

        mb_type |= MB_TYPE_INTERLACED;

    h->slice_table[mb_xy] = sl->slice_num;

    if(IS_INTRA_PCM(mb_type)){

        const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] *

                            h->sps.bit_depth_luma;

        // We assume these blocks are very rare so we do not optimize it.

        sl->intra_pcm_ptr = align_get_bits(&sl->gb);

        if (get_bits_left(&sl->gb) < mb_size) {

            av_log(h->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n");

            return AVERROR_INVALIDDATA;

        }

        skip_bits_long(&sl->gb, mb_size);

        // In deblocking, the quantizer is 0

        h->cur_pic.qscale_table[mb_xy] = 0;

        // All coeffs are present

        memset(h->non_zero_count[mb_xy], 16, 48);

        h->cur_pic.mb_type[mb_xy] = mb_type;

        return 0;

    }

    fill_decode_neighbors(h, sl, mb_type);

    fill_decode_caches(h, sl, mb_type);

    //mb_pred

    if(IS_INTRA(mb_type)){

        int pred_mode;

//            init_top_left_availability(h);

        if(IS_INTRA4x4(mb_type)){

            int i;

            int di = 1;

            if(dct8x8_allowed && get_bits1(&sl->gb)){

                mb_type |= MB_TYPE_8x8DCT;

                di = 4;

            }

//                fill_intra4x4_pred_table(h);

            for(i=0; i<16; i+=di){

                int mode = pred_intra_mode(h, sl, i);

                if(!get_bits1(&sl->gb)){

                    const int rem_mode= get_bits(&sl->gb, 3);

                    mode = rem_mode + (rem_mode >= mode);

                }

                if(di==4)

                    fill_rectangle(&sl->intra4x4_pred_mode_cache[ scan8[i] ], 2, 2, 8, mode, 1);

                else

                    sl->intra4x4_pred_mode_cache[scan8[i]] = mode;

            }

            write_back_intra_pred_mode(h, sl);

            if (ff_h264_check_intra4x4_pred_mode(sl->intra4x4_pred_mode_cache, h->avctx,

                                                 sl->top_samples_available, sl->left_samples_available) < 0)

                return -1;

        }else{

            sl->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h->avctx, sl->top_samples_available,

                                                                     sl->left_samples_available, sl->intra16x16_pred_mode, 0);

            if (sl->intra16x16_pred_mode < 0)

                return -1;

        }

        if(decode_chroma){

            pred_mode= ff_h264_check_intra_pred_mode(h->avctx, sl->top_samples_available,

                                                     sl->left_samples_available, get_ue_golomb_31(&sl->gb), 1);

            if(pred_mode < 0)

                return -1;

            sl->chroma_pred_mode = pred_mode;

        } else {

            sl->chroma_pred_mode = DC_128_PRED8x8;

        }

    }else if(partition_count==4){

        int i, j, sub_partition_count[4], list, ref[2][4];

        if (sl->slice_type_nos == AV_PICTURE_TYPE_B) {

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

                sl->sub_mb_type[i]= get_ue_golomb_31(&sl->gb);

                if(sl->sub_mb_type[i] >=13){

                    av_log(h->avctx, AV_LOG_ERROR, "B sub_mb_type %u out of range at %d %d\n", sl->sub_mb_type[i], sl->mb_x, sl->mb_y);

                    return -1;

                }

                sub_partition_count[i] = ff_h264_b_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;

                sl->sub_mb_type[i]     = ff_h264_b_sub_mb_type_info[sl->sub_mb_type[i]].type;

            }

            if( IS_DIRECT(sl->sub_mb_type[0]|sl->sub_mb_type[1]|sl->sub_mb_type[2]|sl->sub_mb_type[3])) {

                ff_h264_pred_direct_motion(h, sl, &mb_type);

                sl->ref_cache[0][scan8[4]] =

                sl->ref_cache[1][scan8[4]] =

                sl->ref_cache[0][scan8[12]] =

                sl->ref_cache[1][scan8[12]] = PART_NOT_AVAILABLE;

            }

        }else{

            assert(sl->slice_type_nos == AV_PICTURE_TYPE_P); //FIXME SP correct ?

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

                sl->sub_mb_type[i]= get_ue_golomb_31(&sl->gb);

                if(sl->sub_mb_type[i] >=4){

                    av_log(h->avctx, AV_LOG_ERROR, "P sub_mb_type %u out of range at %d %d\n", sl->sub_mb_type[i], sl->mb_x, sl->mb_y);

                    return -1;

                }

                sub_partition_count[i] = ff_h264_p_sub_mb_type_info[sl->sub_mb_type[i]].partition_count;

                sl->sub_mb_type[i]     = ff_h264_p_sub_mb_type_info[sl->sub_mb_type[i]].type;

            }

        }

        for (list = 0; list < sl->list_count; list++) {

            int ref_count = IS_REF0(mb_type) ? 1 : sl->ref_count[list] << MB_MBAFF(sl);

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

                if(IS_DIRECT(sl->sub_mb_type[i])) continue;

                if(IS_DIR(sl->sub_mb_type[i], 0, list)){

                    unsigned int tmp;

                    if(ref_count == 1){

                        tmp= 0;

                    }else if(ref_count == 2){

                        tmp= get_bits1(&sl->gb)^1;

                    }else{

                        tmp= get_ue_golomb_31(&sl->gb);

                        if(tmp>=ref_count){

                            av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", tmp);

                            return -1;

                        }

                    }

                    ref[list][i]= tmp;

                }else{

                 //FIXME

                    ref[list][i] = -1;

                }

            }

        }

        if(dct8x8_allowed)

            dct8x8_allowed = get_dct8x8_allowed(h, sl);

        for (list = 0; list < sl->list_count; list++) {

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

                if(IS_DIRECT(sl->sub_mb_type[i])) {

                    sl->ref_cache[list][ scan8[4*i] ] = sl->ref_cache[list][ scan8[4*i]+1 ];

                    continue;

                }

                sl->ref_cache[list][ scan8[4*i]   ]=sl->ref_cache[list][ scan8[4*i]+1 ]=

                sl->ref_cache[list][ scan8[4*i]+8 ]=sl->ref_cache[list][ scan8[4*i]+9 ]= ref[list][i];

                if(IS_DIR(sl->sub_mb_type[i], 0, list)){

                    const int sub_mb_type= sl->sub_mb_type[i];

                    const int block_width= (sub_mb_type & (MB_TYPE_16x16|MB_TYPE_16x8)) ? 2 : 1;

                    for(j=0; j<sub_partition_count[i]; j++){

                        int mx, my;

                        const int index= 4*i + block_width*j;

                        int16_t (* mv_cache)[2]= &sl->mv_cache[list][ scan8[index] ];

                        pred_motion(h, sl, index, block_width, list, sl->ref_cache[list][ scan8[index] ], &mx, &my);

                        mx += get_se_golomb(&sl->gb);

                        my += get_se_golomb(&sl->gb);

                        ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                        if(IS_SUB_8X8(sub_mb_type)){

                            mv_cache[ 1 ][0]=

                            mv_cache[ 8 ][0]= mv_cache[ 9 ][0]= mx;

                            mv_cache[ 1 ][1]=

                            mv_cache[ 8 ][1]= mv_cache[ 9 ][1]= my;

                        }else if(IS_SUB_8X4(sub_mb_type)){

                            mv_cache[ 1 ][0]= mx;

                            mv_cache[ 1 ][1]= my;

                        }else if(IS_SUB_4X8(sub_mb_type)){

                            mv_cache[ 8 ][0]= mx;

                            mv_cache[ 8 ][1]= my;

                        }

                        mv_cache[ 0 ][0]= mx;

                        mv_cache[ 0 ][1]= my;

                    }

                }else{

                    uint32_t *p= (uint32_t *)&sl->mv_cache[list][ scan8[4*i] ][0];

                    p[0] = p[1]=

                    p[8] = p[9]= 0;

                }

            }

        }

    }else if(IS_DIRECT(mb_type)){

        ff_h264_pred_direct_motion(h, sl, &mb_type);

        dct8x8_allowed &= h->sps.direct_8x8_inference_flag;

    }else{

        int list, mx, my, i;

         //FIXME we should set ref_idx_l? to 0 if we use that later ...

        if(IS_16X16(mb_type)){

            for (list = 0; list < sl->list_count; list++) {

                    unsigned int val;

                    if(IS_DIR(mb_type, 0, list)){

                        int rc = sl->ref_count[list] << MB_MBAFF(sl);

                        if (rc == 1) {

                            val= 0;

                        } else if (rc == 2) {

                            val= get_bits1(&sl->gb)^1;

                        }else{

                            val= get_ue_golomb_31(&sl->gb);

                            if (val >= rc) {

                                av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                return -1;

                            }

                        }

                    fill_rectangle(&sl->ref_cache[list][ scan8[0] ], 4, 4, 8, val, 1);

                    }

            }

            for (list = 0; list < sl->list_count; list++) {

                if(IS_DIR(mb_type, 0, list)){

                    pred_motion(h, sl, 0, 4, list, sl->ref_cache[list][ scan8[0] ], &mx, &my);

                    mx += get_se_golomb(&sl->gb);

                    my += get_se_golomb(&sl->gb);

                    ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                    fill_rectangle(sl->mv_cache[list][ scan8[0] ], 4, 4, 8, pack16to32(mx,my), 4);

                }

            }

        }

        else if(IS_16X8(mb_type)){

            for (list = 0; list < sl->list_count; list++) {

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

                        unsigned int val;

                        if(IS_DIR(mb_type, i, list)){

                            int rc = sl->ref_count[list] << MB_MBAFF(sl);

                            if (rc == 1) {

                                val= 0;

                            } else if (rc == 2) {

                                val= get_bits1(&sl->gb)^1;

                            }else{

                                val= get_ue_golomb_31(&sl->gb);

                                if (val >= rc) {

                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                    return -1;

                                }

                            }

                        }else

                            val= LIST_NOT_USED&0xFF;

                        fill_rectangle(&sl->ref_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 1);

                    }

            }

            for (list = 0; list < sl->list_count; list++) {

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

                    unsigned int val;

                    if(IS_DIR(mb_type, i, list)){

                        pred_16x8_motion(h, sl, 8*i, list, sl->ref_cache[list][scan8[0] + 16*i], &mx, &my);

                        mx += get_se_golomb(&sl->gb);

                        my += get_se_golomb(&sl->gb);

                        ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                        val= pack16to32(mx,my);

                    }else

                        val=0;

                    fill_rectangle(sl->mv_cache[list][ scan8[0] + 16*i ], 4, 2, 8, val, 4);

                }

            }

        }else{

            assert(IS_8X16(mb_type));

            for (list = 0; list < sl->list_count; list++) {

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

                        unsigned int val;

                        if(IS_DIR(mb_type, i, list)){ //FIXME optimize

                            int rc = sl->ref_count[list] << MB_MBAFF(sl);

                            if (rc == 1) {

                                val= 0;

                            } else if (rc == 2) {

                                val= get_bits1(&sl->gb)^1;

                            }else{

                                val= get_ue_golomb_31(&sl->gb);

                                if (val >= rc) {

                                    av_log(h->avctx, AV_LOG_ERROR, "ref %u overflow\n", val);

                                    return -1;

                                }

                            }

                        }else

                            val= LIST_NOT_USED&0xFF;

                        fill_rectangle(&sl->ref_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 1);

                    }

            }

            for (list = 0; list < sl->list_count; list++) {

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

                    unsigned int val;

                    if(IS_DIR(mb_type, i, list)){

                        pred_8x16_motion(h, sl, i*4, list, sl->ref_cache[list][ scan8[0] + 2*i ], &mx, &my);

                        mx += get_se_golomb(&sl->gb);

                        my += get_se_golomb(&sl->gb);

                        ff_tlog(h->avctx, "final mv:%d %d\n", mx, my);

                        val= pack16to32(mx,my);

                    }else

                        val=0;

                    fill_rectangle(sl->mv_cache[list][ scan8[0] + 2*i ], 2, 4, 8, val, 4);

                }

            }

        }

    }

    if(IS_INTER(mb_type))

        write_back_motion(h, sl, mb_type);

    if(!IS_INTRA16x16(mb_type)){

        cbp= get_ue_golomb(&sl->gb);

        if(decode_chroma){

            if(cbp > 47){

                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, sl->mb_x, sl->mb_y);

                return -1;

            }

            if (IS_INTRA4x4(mb_type))

                cbp = ff_h264_golomb_to_intra4x4_cbp[cbp];

            else

                cbp = ff_h264_golomb_to_inter_cbp[cbp];

        }else{

            if(cbp > 15){

                av_log(h->avctx, AV_LOG_ERROR, "cbp too large (%u) at %d %d\n", cbp, sl->mb_x, sl->mb_y);

                return -1;

            }

            if(IS_INTRA4x4(mb_type)) cbp= golomb_to_intra4x4_cbp_gray[cbp];

            else                     cbp= golomb_to_inter_cbp_gray[cbp];

        }

    }

    if(dct8x8_allowed && (cbp&15) && !IS_INTRA(mb_type)){

        mb_type |= MB_TYPE_8x8DCT*get_bits1(&sl->gb);

    }

    sl->cbp=

    h->cbp_table[mb_xy]= cbp;

    h->cur_pic.mb_type[mb_xy] = mb_type;

    if(cbp || IS_INTRA16x16(mb_type)){

        int i4x4, i8x8, chroma_idx;

        int dquant;

        int ret;

        GetBitContext *gb = &sl->gb;

        const uint8_t *scan, *scan8x8;

        const int max_qp = 51 + 6*(h->sps.bit_depth_luma-8);

        if(IS_INTERLACED(mb_type)){

            scan8x8 = sl->qscale ? h->field_scan8x8_cavlc : h->field_scan8x8_cavlc_q0;

            scan    = sl->qscale ? h->field_scan : h->field_scan_q0;

        }else{

            scan8x8 = sl->qscale ? h->zigzag_scan8x8_cavlc : h->zigzag_scan8x8_cavlc_q0;

            scan    = sl->qscale ? h->zigzag_scan : h->zigzag_scan_q0;

        }

        dquant= get_se_golomb(&sl->gb);

        sl->qscale += dquant;

        if (((unsigned)sl->qscale) > max_qp){

            if (sl->qscale < 0) sl->qscale += max_qp + 1;

            else                sl->qscale -= max_qp+1;

            if (((unsigned)sl->qscale) > max_qp){

                av_log(h->avctx, AV_LOG_ERROR, "dquant out of range (%d) at %d %d\n", dquant, sl->mb_x, sl->mb_y);

                return -1;

            }

        }

        sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);

        sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);

        if ((ret = decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 0)) < 0 ) {

            return -1;

        }

        h->cbp_table[mb_xy] |= ret << 12;

        if (CHROMA444(h)) {

            if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 1) < 0 ) {

                return -1;

            }

            if (decode_luma_residual(h, sl, gb, scan, scan8x8, pixel_shift, mb_type, cbp, 2) < 0 ) {

                return -1;

            }

        } else if (CHROMA422(h)) {

            if(cbp&0x30){

                for(chroma_idx=0; chroma_idx<2; chroma_idx++)

                    if (decode_residual(h, sl, gb, sl->mb + ((256 + 16*16*chroma_idx) << pixel_shift),

                                        CHROMA_DC_BLOCK_INDEX + chroma_idx, ff_h264_chroma422_dc_scan,

                                        NULL, 8) < 0) {

                        return -1;

                    }

            }

            if(cbp&0x20){

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

                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[chroma_idx]];

                    int16_t *mb = sl->mb + (16*(16 + 16*chroma_idx) << pixel_shift);

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

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

                            const int index = 16 + 16*chroma_idx + 8*i8x8 + i4x4;

                            if (decode_residual(h, sl, gb, mb, index, scan + 1, qmul, 15) < 0)

                                return -1;

                            mb += 16 << pixel_shift;

                        }

                    }

                }

            }else{

                fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

                fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

            }

        } else /* yuv420 */ {

            if(cbp&0x30){

                for(chroma_idx=0; chroma_idx<2; chroma_idx++)

                    if (decode_residual(h, sl, gb, sl->mb + ((256 + 16 * 16 * chroma_idx) << pixel_shift),

                                        CHROMA_DC_BLOCK_INDEX + chroma_idx, ff_h264_chroma_dc_scan, NULL, 4) < 0) {

                        return -1;

                    }

            }

            if(cbp&0x20){

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

                    const uint32_t *qmul = h->dequant4_coeff[chroma_idx+1+(IS_INTRA( mb_type ) ? 0:3)][sl->chroma_qp[chroma_idx]];

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

                        const int index= 16 + 16*chroma_idx + i4x4;

                        if( decode_residual(h, sl, gb, sl->mb + (16*index << pixel_shift), index, scan + 1, qmul, 15) < 0){

                            return -1;

                        }

                    }

                }

            }else{

                fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

                fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

            }

        }

    }else{

        fill_rectangle(&sl->non_zero_count_cache[scan8[ 0]], 4, 4, 8, 0, 1);

        fill_rectangle(&sl->non_zero_count_cache[scan8[16]], 4, 4, 8, 0, 1);

        fill_rectangle(&sl->non_zero_count_cache[scan8[32]], 4, 4, 8, 0, 1);

    }

    h->cur_pic.qscale_table[mb_xy] = sl->qscale;

    write_back_non_zero_count(h, sl);

    return 0;

}


static uint64_t xilinx_spips_read(void *opaque, hwaddr addr,

                                                        unsigned size)

{

    XilinxSPIPS *s = opaque;

    uint32_t mask = ~0;

    uint32_t ret;

    addr >>= 2;

    switch (addr) {

    case R_CONFIG:

        mask = 0x0002FFFF;

        break;

    case R_INTR_STATUS:

        ret = s->regs[addr] & IXR_ALL;

        s->regs[addr] = 0;

        DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);

        return ret;

    case R_INTR_MASK:

        mask = IXR_ALL;

        break;

    case  R_EN:

        mask = 0x1;

        break;

    case R_SLAVE_IDLE_COUNT:

        mask = 0xFF;

        break;

    case R_MOD_ID:

        mask = 0x01FFFFFF;

        break;

    case R_INTR_EN:

    case R_INTR_DIS:

    case R_TX_DATA:

        mask = 0;

        break;

    case R_RX_DATA:

        rx_data_bytes(s, &ret, s->num_txrx_bytes);

        DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, ret);

        xilinx_spips_update_ixr(s);

        return ret;

    }

    DB_PRINT("addr=" TARGET_FMT_plx " = %x\n", addr * 4, s->regs[addr] & mask);

    return s->regs[addr] & mask;

}


struct omap_intr_handler_s *omap2_inth_init(target_phys_addr_t base,

                int size, int nbanks, qemu_irq **pins,

                qemu_irq parent_irq, qemu_irq parent_fiq,

                omap_clk fclk, omap_clk iclk)

{

    struct omap_intr_handler_s *s = (struct omap_intr_handler_s *)

            g_malloc0(sizeof(struct omap_intr_handler_s) +

                            sizeof(struct omap_intr_handler_bank_s) * nbanks);

    s->parent_intr[0] = parent_irq;

    s->parent_intr[1] = parent_fiq;

    s->nbanks = nbanks;

    s->level_only = 1;

    s->pins = qemu_allocate_irqs(omap_set_intr_noedge, s, nbanks * 32);

    if (pins)

        *pins = s->pins;

    memory_region_init_io(&s->mmio, &omap2_inth_mem_ops, s, "omap2-intc", size);

    memory_region_add_subregion(get_system_memory(), base, &s->mmio);

    omap_inth_reset(s);

    return s;

}


static int microblaze_load_dtb(target_phys_addr_t addr,

                                      uint32_t ramsize,

                                      const char *kernel_cmdline,

                                      const char *dtb_filename)

{

    int fdt_size;

#ifdef CONFIG_FDT

    void *fdt = NULL;

    int r;

    if (dtb_filename) {

        fdt = load_device_tree(dtb_filename, &fdt_size);

    }

    if (!fdt) {

        return 0;

    }

    if (kernel_cmdline) {

        r = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",

                                                        kernel_cmdline);

        if (r < 0) {

            fprintf(stderr, "couldn't set /chosen/bootargs\n");

        }

    }

    cpu_physical_memory_write(addr, (void *)fdt, fdt_size);

#else

    /* We lack libfdt so we cannot manipulate the fdt. Just pass on the blob

       to the kernel.  */

    if (dtb_filename) {

        fdt_size = load_image_targphys(dtb_filename, addr, 0x10000);

    }

    if (kernel_cmdline) {

        fprintf(stderr,

                "Warning: missing libfdt, cannot pass cmdline to kernel!\n");

    }

#endif

    return fdt_size;

}


static int delta_decode(int8_t *dst, const uint8_t *src, int src_size,

                        int8_t val, const int8_t *table)

{

    int n = src_size;

    int8_t *dst0 = dst;

    while (n--) {

        uint8_t d = *src++;

        val = av_clip(val + table[d & 0x0f], -127, 128);

        *dst++ = val;

        val = av_clip(val + table[d >> 4]  , -127, 128);

        *dst++ = val;

    }

    return dst-dst0;

}


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

{

    VirtIODevice *vdev = VIRTIO_DEVICE(dev);

    VirtIORNG *vrng = VIRTIO_RNG(dev);

    Error *local_err = NULL;

    if (!vrng->conf.period_ms > 0) {

        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "period",

                  "a positive number");

        return;

    }

    if (vrng->conf.rng == NULL) {

        vrng->conf.default_backend = RNG_RANDOM(object_new(TYPE_RNG_RANDOM));

        user_creatable_complete(OBJECT(vrng->conf.default_backend),

                                &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            object_unref(OBJECT(vrng->conf.default_backend));

            return;

        }

        object_property_add_child(OBJECT(dev),

                                  "default-backend",

                                  OBJECT(vrng->conf.default_backend),

                                  NULL);

        /* The child property took a reference, we can safely drop ours now */

        object_unref(OBJECT(vrng->conf.default_backend));

        object_property_set_link(OBJECT(dev),

                                 OBJECT(vrng->conf.default_backend),

                                 "rng", NULL);

    }

    virtio_init(vdev, "virtio-rng", VIRTIO_ID_RNG, 0);

    vrng->rng = vrng->conf.rng;

    if (vrng->rng == NULL) {

        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "rng", "a valid object");

        return;

    }

    vrng->vq = virtio_add_queue(vdev, 8, handle_input);

    /* Workaround: Property parsing does not enforce unsigned integers,

     * So this is a hack to reject such numbers. */

    if (vrng->conf.max_bytes > INT64_MAX) {

        error_set(errp, QERR_INVALID_PARAMETER_VALUE, "max-bytes",

                  "a non-negative integer below 2^63");

        return;

    }

    vrng->quota_remaining = vrng->conf.max_bytes;

    vrng->rate_limit_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL,

                                               check_rate_limit, vrng);

    timer_mod(vrng->rate_limit_timer,

                   qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL) + vrng->conf.period_ms);

    register_savevm(dev, "virtio-rng", -1, 1, virtio_rng_save,

                    virtio_rng_load, vrng);

}


static void tmu2_start(MilkymistTMU2State *s)

{

    int pbuffer_attrib[6] = {

        GLX_PBUFFER_WIDTH,

        0,

        GLX_PBUFFER_HEIGHT,

        0,

        GLX_PRESERVED_CONTENTS,

        True

    };

    GLXPbuffer pbuffer;

    GLuint texture;

    void *fb;

    hwaddr fb_len;

    void *mesh;

    hwaddr mesh_len;

    float m;

    trace_milkymist_tmu2_start();

    /* Create and set up a suitable OpenGL context */

    pbuffer_attrib[1] = s->regs[R_DSTHRES];

    pbuffer_attrib[3] = s->regs[R_DSTVRES];

    pbuffer = glXCreatePbuffer(s->dpy, s->glx_fb_config, pbuffer_attrib);

    glXMakeContextCurrent(s->dpy, pbuffer, pbuffer, s->glx_context);

    /* Fixup endianness. TODO: would it work on BE hosts? */

    glPixelStorei(GL_UNPACK_SWAP_BYTES, 1);

    glPixelStorei(GL_PACK_SWAP_BYTES, 1);

    /* Row alignment */

    glPixelStorei(GL_UNPACK_ALIGNMENT, 2);

    glPixelStorei(GL_PACK_ALIGNMENT, 2);

    /* Read the QEMU source framebuffer into an OpenGL texture */

    glGenTextures(1, &texture);

    glBindTexture(GL_TEXTURE_2D, texture);

    fb_len = 2ULL * s->regs[R_TEXHRES] * s->regs[R_TEXVRES];

    fb = cpu_physical_memory_map(s->regs[R_TEXFBUF], &fb_len, 0);

    if (fb == NULL) {

        glDeleteTextures(1, &texture);

        glXMakeContextCurrent(s->dpy, None, None, NULL);

        glXDestroyPbuffer(s->dpy, pbuffer);

        return;

    }

    glTexImage2D(GL_TEXTURE_2D, 0, 3, s->regs[R_TEXHRES], s->regs[R_TEXVRES],

            0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, fb);

    cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);

    /* Set up texturing options */

    /* WARNING:

     * Many cases of TMU2 masking are not supported by OpenGL.

     * We only implement the most common ones:

     *  - full bilinear filtering vs. nearest texel

     *  - texture clamping vs. texture wrapping

     */

    if ((s->regs[R_TEXHMASK] & 0x3f) > 0x20) {

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    } else {

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

    }

    if ((s->regs[R_TEXHMASK] >> 6) & s->regs[R_TEXHRES]) {

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);

    } else {

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

    }

    if ((s->regs[R_TEXVMASK] >> 6) & s->regs[R_TEXVRES]) {

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);

    } else {

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    }

    /* Translucency and decay */

    glEnable(GL_BLEND);

    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    m = (float)(s->regs[R_BRIGHTNESS] + 1) / 64.0f;

    glColor4f(m, m, m, (float)(s->regs[R_ALPHA] + 1) / 64.0f);

    /* Read the QEMU dest. framebuffer into the OpenGL framebuffer */

    fb_len = 2ULL * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];

    fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, 0);

    if (fb == NULL) {

        glDeleteTextures(1, &texture);

        glXMakeContextCurrent(s->dpy, None, None, NULL);

        glXDestroyPbuffer(s->dpy, pbuffer);

        return;

    }

    glDrawPixels(s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,

            GL_UNSIGNED_SHORT_5_6_5, fb);

    cpu_physical_memory_unmap(fb, fb_len, 0, fb_len);

    glViewport(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES]);

    glMatrixMode(GL_PROJECTION);

    glLoadIdentity();

    glOrtho(0.0, s->regs[R_DSTHRES], 0.0, s->regs[R_DSTVRES], -1.0, 1.0);

    glMatrixMode(GL_MODELVIEW);

    /* Map the texture */

    mesh_len = MESH_MAXSIZE*MESH_MAXSIZE*sizeof(struct vertex);

    mesh = cpu_physical_memory_map(s->regs[R_VERTICESADDR], &mesh_len, 0);

    if (mesh == NULL) {

        glDeleteTextures(1, &texture);

        glXMakeContextCurrent(s->dpy, None, None, NULL);

        glXDestroyPbuffer(s->dpy, pbuffer);

        return;

    }

    tmu2_gl_map((struct vertex *)mesh,

        s->regs[R_TEXHRES], s->regs[R_TEXVRES],

        s->regs[R_HMESHLAST], s->regs[R_VMESHLAST],

        s->regs[R_DSTHOFFSET], s->regs[R_DSTVOFFSET],

        s->regs[R_DSTSQUAREW], s->regs[R_DSTSQUAREH]);

    cpu_physical_memory_unmap(mesh, mesh_len, 0, mesh_len);

    /* Write back the OpenGL framebuffer to the QEMU framebuffer */

    fb_len = 2 * s->regs[R_DSTHRES] * s->regs[R_DSTVRES];

    fb = cpu_physical_memory_map(s->regs[R_DSTFBUF], &fb_len, 1);

    if (fb == NULL) {

        glDeleteTextures(1, &texture);

        glXMakeContextCurrent(s->dpy, None, None, NULL);

        glXDestroyPbuffer(s->dpy, pbuffer);

        return;

    }

    glReadPixels(0, 0, s->regs[R_DSTHRES], s->regs[R_DSTVRES], GL_RGB,

            GL_UNSIGNED_SHORT_5_6_5, fb);

    cpu_physical_memory_unmap(fb, fb_len, 1, fb_len);

    /* Free OpenGL allocs */

    glDeleteTextures(1, &texture);

    glXMakeContextCurrent(s->dpy, None, None, NULL);

    glXDestroyPbuffer(s->dpy, pbuffer);

    s->regs[R_CTL] &= ~CTL_START_BUSY;

    trace_milkymist_tmu2_pulse_irq();

    qemu_irq_pulse(s->irq);

}


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

{

    ff_j_rev_dct(block);

    ff_put_pixels_clamped(block, dest, line_size);

}


static void e1000_reset(void *opaque)

{

    E1000State *d = opaque;

    qemu_del_timer(d->autoneg_timer);

    memset(d->phy_reg, 0, sizeof d->phy_reg);

    memmove(d->phy_reg, phy_reg_init, sizeof phy_reg_init);

    memset(d->mac_reg, 0, sizeof d->mac_reg);

    memmove(d->mac_reg, mac_reg_init, sizeof mac_reg_init);

    d->rxbuf_min_shift = 1;

    memset(&d->tx, 0, sizeof d->tx);

    if (d->nic->nc.link_down) {

        e1000_link_down(d);

    }

    /* Some guests expect pre-initialized RAH/RAL (AddrValid flag + MACaddr) */

    d->mac_reg[RA] = 0;

    d->mac_reg[RA + 1] = E1000_RAH_AV;

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

        d->mac_reg[RA] |= macaddr[i] << (8 * i);

        d->mac_reg[RA + 1] |= (i < 2) ? macaddr[i + 4] << (8 * i) : 0;

    }

}


void qtest_add_func(const char *str, void (*fn))

{

    gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str);

    g_test_add_func(path, fn);

}


void palette8torgb16(const uint8_t *src, uint8_t *dst, unsigned num_pixels, const uint8_t *palette)

{

	unsigned i;

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

		((uint16_t *)dst)[i] = ((uint16_t *)palette)[ src[i] ];

}


static void ppc_spapr_init(ram_addr_t ram_size,

                           const char *boot_device,

                           const char *kernel_filename,

                           const char *kernel_cmdline,

                           const char *initrd_filename,

                           const char *cpu_model)

{

    CPUState *env;

    int i;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram = g_new(MemoryRegion, 1);

    target_phys_addr_t rma_alloc_size, rma_size;

    uint32_t initrd_base;

    long kernel_size, initrd_size, fw_size;

    long pteg_shift = 17;

    char *filename;

    spapr = g_malloc0(sizeof(*spapr));

    QLIST_INIT(&spapr->phbs);

    cpu_ppc_hypercall = emulate_spapr_hypercall;

    /* Allocate RMA if necessary */

    rma_alloc_size = kvmppc_alloc_rma("ppc_spapr.rma", sysmem);

    if (rma_alloc_size == -1) {

        hw_error("qemu: Unable to create RMA\n");

        exit(1);

    }

    if (rma_alloc_size && (rma_alloc_size < ram_size)) {

        rma_size = rma_alloc_size;

    } else {

        rma_size = ram_size;

    }

    /* We place the device tree just below either the top of the RMA,

     * or just below 2GB, whichever is lowere, so that it can be

     * processed with 32-bit real mode code if necessary */

    spapr->fdt_addr = MIN(rma_size, 0x80000000) - FDT_MAX_SIZE;

    spapr->rtas_addr = spapr->fdt_addr - RTAS_MAX_SIZE;

    /* init CPUs */

    if (cpu_model == NULL) {

        cpu_model = kvm_enabled() ? "host" : "POWER7";

    }

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

        env = cpu_init(cpu_model);

        if (!env) {

            fprintf(stderr, "Unable to find PowerPC CPU definition\n");

            exit(1);

        }

        /* Set time-base frequency to 512 MHz */

        cpu_ppc_tb_init(env, TIMEBASE_FREQ);

        qemu_register_reset((QEMUResetHandler *)&cpu_reset, env);

        env->hreset_vector = 0x60;

        env->hreset_excp_prefix = 0;

        env->gpr[3] = env->cpu_index;

    }

    /* allocate RAM */

    spapr->ram_limit = ram_size;

    if (spapr->ram_limit > rma_alloc_size) {

        ram_addr_t nonrma_base = rma_alloc_size;

        ram_addr_t nonrma_size = spapr->ram_limit - rma_alloc_size;

        memory_region_init_ram(ram, "ppc_spapr.ram", nonrma_size);

        vmstate_register_ram_global(ram);

        memory_region_add_subregion(sysmem, nonrma_base, ram);

    }

    /* allocate hash page table.  For now we always make this 16mb,

     * later we should probably make it scale to the size of guest

     * RAM */

    spapr->htab_size = 1ULL << (pteg_shift + 7);

    spapr->htab = qemu_memalign(spapr->htab_size, spapr->htab_size);

    for (env = first_cpu; env != NULL; env = env->next_cpu) {

        env->external_htab = spapr->htab;

        env->htab_base = -1;

        env->htab_mask = spapr->htab_size - 1;

        /* Tell KVM that we're in PAPR mode */

        env->spr[SPR_SDR1] = (unsigned long)spapr->htab |

                             ((pteg_shift + 7) - 18);

        env->spr[SPR_HIOR] = 0;

        if (kvm_enabled()) {

            kvmppc_set_papr(env);

        }

    }

    filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, "spapr-rtas.bin");

    spapr->rtas_size = load_image_targphys(filename, spapr->rtas_addr,

                                           ram_size - spapr->rtas_addr);

    if (spapr->rtas_size < 0) {

        hw_error("qemu: could not load LPAR rtas '%s'\n", filename);

        exit(1);

    }

    g_free(filename);

    /* Set up Interrupt Controller */

    spapr->icp = xics_system_init(XICS_IRQS);

    spapr->next_irq = 16;

    /* Set up VIO bus */

    spapr->vio_bus = spapr_vio_bus_init();

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

        if (serial_hds[i]) {

            spapr_vty_create(spapr->vio_bus, SPAPR_VTY_BASE_ADDRESS + i,

                             serial_hds[i]);

        }

    }

    /* Set up PCI */

    spapr_create_phb(spapr, "pci", SPAPR_PCI_BUID,

                     SPAPR_PCI_MEM_WIN_ADDR,

                     SPAPR_PCI_MEM_WIN_SIZE,

                     SPAPR_PCI_IO_WIN_ADDR);

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

        NICInfo *nd = &nd_table[i];

        if (!nd->model) {

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

        }

        if (strcmp(nd->model, "ibmveth") == 0) {

            spapr_vlan_create(spapr->vio_bus, 0x1000 + i, nd);

        } else {

            pci_nic_init_nofail(&nd_table[i], nd->model, NULL);

        }

    }

    for (i = 0; i <= drive_get_max_bus(IF_SCSI); i++) {

        spapr_vscsi_create(spapr->vio_bus, 0x2000 + i);

    }

    if (kernel_filename) {

        uint64_t lowaddr = 0;

        kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL,

                               NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0);

        if (kernel_size < 0) {

            kernel_size = load_image_targphys(kernel_filename,

                                              KERNEL_LOAD_ADDR,

                                              ram_size - KERNEL_LOAD_ADDR);

        }

        if (kernel_size < 0) {

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

                    kernel_filename);

            exit(1);

        }

        /* load initrd */

        if (initrd_filename) {

            initrd_base = INITRD_LOAD_ADDR;

            initrd_size = load_image_targphys(initrd_filename, initrd_base,

                                              ram_size - initrd_base);

            if (initrd_size < 0) {

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

                        initrd_filename);

                exit(1);

            }

        } else {

            initrd_base = 0;

            initrd_size = 0;

        }

        spapr->entry_point = KERNEL_LOAD_ADDR;

    } else {

        if (rma_size < (MIN_RMA_SLOF << 20)) {

            fprintf(stderr, "qemu: pSeries SLOF firmware requires >= "

                    "%ldM guest RMA (Real Mode Area memory)\n", MIN_RMA_SLOF);

            exit(1);

        }

        filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, FW_FILE_NAME);

        fw_size = load_image_targphys(filename, 0, FW_MAX_SIZE);

        if (fw_size < 0) {

            hw_error("qemu: could not load LPAR rtas '%s'\n", filename);

            exit(1);

        }

        g_free(filename);

        spapr->entry_point = 0x100;

        initrd_base = 0;

        initrd_size = 0;

        /* SLOF will startup the secondary CPUs using RTAS,

           rather than expecting a kexec() style entry */

        for (env = first_cpu; env != NULL; env = env->next_cpu) {

            env->halted = 1;

        }

    }

    /* Prepare the device tree */

    spapr->fdt_skel = spapr_create_fdt_skel(cpu_model, rma_size,

                                            initrd_base, initrd_size,

                                            boot_device, kernel_cmdline,

                                            pteg_shift + 7);

    assert(spapr->fdt_skel != NULL);

    qemu_register_reset(spapr_reset, spapr);

}


void fd_start_outgoing_migration(MigrationState *s, const char *fdname, Error **errp)

{

    int fd = monitor_get_fd(cur_mon, fdname, errp);

    if (fd == -1) {

        return;

    }

    s->file = qemu_fdopen(fd, "wb");

    migrate_fd_connect(s);

}


static int dvvideo_init(AVCodecContext *avctx)

{

    DVVideoContext *s = avctx->priv_data;

    DSPContext dsp;

    static int done=0;

    int i, j;

    if (!done) {

        VLC dv_vlc;

        uint16_t new_dv_vlc_bits[NB_DV_VLC*2];

        uint8_t new_dv_vlc_len[NB_DV_VLC*2];

        uint8_t new_dv_vlc_run[NB_DV_VLC*2];

        int16_t new_dv_vlc_level[NB_DV_VLC*2];

        done = 1;

        dv_vlc_map = av_mallocz_static(DV_VLC_MAP_LEV_SIZE*DV_VLC_MAP_RUN_SIZE*sizeof(struct dv_vlc_pair));

        if (!dv_vlc_map)

            return -ENOMEM;

        /* dv_anchor lets each thread know its Id */

        dv_anchor = av_malloc(12*27*sizeof(void*));

        if (!dv_anchor) {

            return -ENOMEM;

        }

        for (i=0; i<12*27; i++)

            dv_anchor[i] = (void*)(size_t)i;

        /* it's faster to include sign bit in a generic VLC parsing scheme */

        for (i=0, j=0; i<NB_DV_VLC; i++, j++) {

            new_dv_vlc_bits[j] = dv_vlc_bits[i];

            new_dv_vlc_len[j] = dv_vlc_len[i];

            new_dv_vlc_run[j] = dv_vlc_run[i];

            new_dv_vlc_level[j] = dv_vlc_level[i];

            if (dv_vlc_level[i]) {

                new_dv_vlc_bits[j] <<= 1;

                new_dv_vlc_len[j]++;

                j++;

                new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;

                new_dv_vlc_len[j] = dv_vlc_len[i] + 1;

                new_dv_vlc_run[j] = dv_vlc_run[i];

                new_dv_vlc_level[j] = -dv_vlc_level[i];

            }

        }

        /* NOTE: as a trick, we use the fact the no codes are unused

           to accelerate the parsing of partial codes */

        init_vlc(&dv_vlc, TEX_VLC_BITS, j,

                 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);

        dv_rl_vlc = av_malloc(dv_vlc.table_size * sizeof(RL_VLC_ELEM));

        if (!dv_rl_vlc) {

            av_free(dv_anchor);

            return -ENOMEM;

        }

        for(i = 0; i < dv_vlc.table_size; i++){

            int code= dv_vlc.table[i][0];

            int len = dv_vlc.table[i][1];

            int level, run;

            if(len<0){ //more bits needed

                run= 0;

                level= code;

            } else {

                run=   new_dv_vlc_run[code] + 1;

                level= new_dv_vlc_level[code];

            }

            dv_rl_vlc[i].len = len;

            dv_rl_vlc[i].level = level;

            dv_rl_vlc[i].run = run;

        }

        free_vlc(&dv_vlc);

        for (i = 0; i < NB_DV_VLC - 1; i++) {

           if (dv_vlc_run[i] >= DV_VLC_MAP_RUN_SIZE)

               continue;

#ifdef DV_CODEC_TINY_TARGET

           if (dv_vlc_level[i] >= DV_VLC_MAP_LEV_SIZE)

               continue;

#endif

           if (dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size != 0)

               continue;

           dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].vlc = dv_vlc_bits[i] <<

                                                            (!!dv_vlc_level[i]);

           dv_vlc_map[dv_vlc_run[i]][dv_vlc_level[i]].size = dv_vlc_len[i] +

                                                             (!!dv_vlc_level[i]);

        }

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

#ifdef DV_CODEC_TINY_TARGET

           for (j = 1; j < DV_VLC_MAP_LEV_SIZE; j++) {

              if (dv_vlc_map[i][j].size == 0) {

                  dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |

                            (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size));

                  dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size +

                                          dv_vlc_map[0][j].size;

              }

           }

#else

           for (j = 1; j < DV_VLC_MAP_LEV_SIZE/2; j++) {

              if (dv_vlc_map[i][j].size == 0) {

                  dv_vlc_map[i][j].vlc = dv_vlc_map[0][j].vlc |

                            (dv_vlc_map[i-1][0].vlc << (dv_vlc_map[0][j].size));

                  dv_vlc_map[i][j].size = dv_vlc_map[i-1][0].size +

                                          dv_vlc_map[0][j].size;

              }

              dv_vlc_map[i][((uint16_t)(-j))&0x1ff].vlc =

                                            dv_vlc_map[i][j].vlc | 1;

              dv_vlc_map[i][((uint16_t)(-j))&0x1ff].size =

                                            dv_vlc_map[i][j].size;

           }

#endif

        }

    }

    /* Generic DSP setup */

    dsputil_init(&dsp, avctx);

    s->get_pixels = dsp.get_pixels;

    /* 88DCT setup */

    s->fdct[0] = dsp.fdct;

    s->idct_put[0] = dsp.idct_put;

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

       s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];

    /* 248DCT setup */

    s->fdct[1] = dsp.fdct248;

    s->idct_put[1] = simple_idct248_put;  // FIXME: need to add it to DSP

    if(avctx->lowres){

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

            int j= ff_zigzag248_direct[i];

            s->dv_zigzag[1][i] = dsp.idct_permutation[(j&7) + (j&8)*4 + (j&48)/2];

        }

    }else

        memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);

    /* XXX: do it only for constant case */

    dv_build_unquantize_tables(s, dsp.idct_permutation);

    /* FIXME: I really don't think this should be here */

    if (dv_codec_profile(avctx))

        avctx->pix_fmt = dv_codec_profile(avctx)->pix_fmt;

    avctx->coded_frame = &s->picture;

    s->avctx= avctx;

    return 0;

}


static uint64_t memory_region_dispatch_read1(MemoryRegion *mr,

                                             hwaddr addr,

                                             unsigned size)

{

    uint64_t data = 0;

    if (!memory_region_access_valid(mr, addr, size, false)) {

        return -1U; /* FIXME: better signalling */

    }

    if (!mr->ops->read) {

        return mr->ops->old_mmio.read[bitops_ffsl(size)](mr->opaque, addr);

    }

    /* FIXME: support unaligned access */

    access_with_adjusted_size(addr, &data, size,

                              mr->ops->impl.min_access_size,

                              mr->ops->impl.max_access_size,

                              memory_region_read_accessor, mr);

    return data;

}


static int cine_read_header(AVFormatContext *avctx)

{

    AVIOContext *pb = avctx->pb;

    AVStream *st;

    unsigned int version, compression, offImageHeader, offSetup, offImageOffsets, biBitCount, length, CFA;

    int vflip;

    char *description;

    uint64_t i;

    st = avformat_new_stream(avctx, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codecpar->codec_id   = AV_CODEC_ID_RAWVIDEO;

    st->codecpar->codec_tag  = 0;

    /* CINEFILEHEADER structure */

    avio_skip(pb, 4); // Type, Headersize

    compression = avio_rl16(pb);

    version     = avio_rl16(pb);

    if (version != 1) {

        avpriv_request_sample(avctx, "unknown version %i", version);

        return AVERROR_INVALIDDATA;

    }

    avio_skip(pb, 12); // FirstMovieImage, TotalImageCount, FirstImageNumber

    st->duration    = avio_rl32(pb);

    offImageHeader  = avio_rl32(pb);

    offSetup        = avio_rl32(pb);

    offImageOffsets = avio_rl32(pb);

    avio_skip(pb, 8); // TriggerTime

    /* BITMAPINFOHEADER structure */

    avio_seek(pb, offImageHeader, SEEK_SET);

    avio_skip(pb, 4); //biSize

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

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

    if (avio_rl16(pb) != 1) // biPlanes

        return AVERROR_INVALIDDATA;

    biBitCount = avio_rl16(pb);

    if (biBitCount != 8 && biBitCount != 16 && biBitCount != 24 && biBitCount != 48) {

        avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount);

        return AVERROR_INVALIDDATA;

    }

    switch (avio_rl32(pb)) {

    case BMP_RGB:

        vflip = 0;

        break;

    case 0x100: /* BI_PACKED */

        st->codecpar->codec_tag = MKTAG('B', 'I', 'T', 0);

        vflip = 1;

        break;

    default:

        avpriv_request_sample(avctx, "unknown bitmap compression");

        return AVERROR_INVALIDDATA;

    }

    avio_skip(pb, 4); // biSizeImage

    /* parse SETUP structure */

    avio_seek(pb, offSetup, SEEK_SET);

    avio_skip(pb, 140); // FrameRatae16 .. descriptionOld

    if (avio_rl16(pb) != 0x5453)

        return AVERROR_INVALIDDATA;

    length = avio_rl16(pb);

    if (length < 0x163C) {

        avpriv_request_sample(avctx, "short SETUP header");

        return AVERROR_INVALIDDATA;

    }

    avio_skip(pb, 616); // Binning .. bFlipH

    if (!avio_rl32(pb) ^ vflip) {

        st->codecpar->extradata  = av_strdup("BottomUp");

        st->codecpar->extradata_size  = 9;

    }

    avio_skip(pb, 4); // Grid

    avpriv_set_pts_info(st, 64, 1, avio_rl32(pb));

    avio_skip(pb, 20); // Shutter .. bEnableColor

    set_metadata_int(&st->metadata, "camera_version", avio_rl32(pb), 0);

    set_metadata_int(&st->metadata, "firmware_version", avio_rl32(pb), 0);

    set_metadata_int(&st->metadata, "software_version", avio_rl32(pb), 0);

    set_metadata_int(&st->metadata, "recording_timezone", avio_rl32(pb), 0);

    CFA = avio_rl32(pb);

    set_metadata_int(&st->metadata, "brightness", avio_rl32(pb), 1);

    set_metadata_int(&st->metadata, "contrast", avio_rl32(pb), 1);

    set_metadata_int(&st->metadata, "gamma", avio_rl32(pb), 1);

    avio_skip(pb, 12 + 16); // Reserved1 .. AutoExpRect

    set_metadata_float(&st->metadata, "wbgain[0].r", av_int2float(avio_rl32(pb)), 1);

    set_metadata_float(&st->metadata, "wbgain[0].b", av_int2float(avio_rl32(pb)), 1);

    avio_skip(pb, 36); // WBGain[1].. WBView

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

    if (compression == CC_RGB) {

        if (biBitCount == 8) {

            st->codecpar->format = AV_PIX_FMT_GRAY8;

        } else if (biBitCount == 16) {

            st->codecpar->format = AV_PIX_FMT_GRAY16LE;

        } else if (biBitCount == 24) {

            st->codecpar->format = AV_PIX_FMT_BGR24;

        } else if (biBitCount == 48) {

            st->codecpar->format = AV_PIX_FMT_BGR48LE;

        } else {

            avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount);

            return AVERROR_INVALIDDATA;

        }

    } else if (compression == CC_UNINT) {

        switch (CFA & 0xFFFFFF) {

        case CFA_BAYER:

            if (biBitCount == 8) {

                st->codecpar->format = AV_PIX_FMT_BAYER_GBRG8;

            } else if (biBitCount == 16) {

                st->codecpar->format = AV_PIX_FMT_BAYER_GBRG16LE;

            } else {

                avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount);

                return AVERROR_INVALIDDATA;

            }

            break;

        case CFA_BAYERFLIP:

            if (biBitCount == 8) {

                st->codecpar->format = AV_PIX_FMT_BAYER_RGGB8;

            } else if (biBitCount == 16) {

                st->codecpar->format = AV_PIX_FMT_BAYER_RGGB16LE;

            } else {

                avpriv_request_sample(avctx, "unsupported biBitCount %i", biBitCount);

                return AVERROR_INVALIDDATA;

            }

            break;

        default:

           avpriv_request_sample(avctx, "unsupported Color Field Array (CFA) %i", CFA & 0xFFFFFF);

            return AVERROR_INVALIDDATA;

        }

    } else { //CC_LEAD

        avpriv_request_sample(avctx, "unsupported compression %i", compression);

        return AVERROR_INVALIDDATA;

    }

    avio_skip(pb, 668); // Conv8Min ... Sensor

    set_metadata_int(&st->metadata, "shutter_ns", avio_rl32(pb), 0);

    avio_skip(pb, 24); // EDRShutterNs ... ImHeightAcq

#define DESCRIPTION_SIZE 4096

    description = av_malloc(DESCRIPTION_SIZE + 1);

    if (!description)

        return AVERROR(ENOMEM);

    i = avio_get_str(pb, DESCRIPTION_SIZE, description, DESCRIPTION_SIZE + 1);

    if (i < DESCRIPTION_SIZE)

        avio_skip(pb, DESCRIPTION_SIZE - i);

    if (description[0])

        av_dict_set(&st->metadata, "description", description, AV_DICT_DONT_STRDUP_VAL);

    else

        av_free(description);

    avio_skip(pb, 1176); // RisingEdge ... cmUser

    set_metadata_int(&st->metadata, "enable_crop", avio_rl32(pb), 1);

    set_metadata_int(&st->metadata, "crop_left", avio_rl32(pb), 1);

    set_metadata_int(&st->metadata, "crop_top", avio_rl32(pb), 1);

    set_metadata_int(&st->metadata, "crop_right", avio_rl32(pb), 1);

    set_metadata_int(&st->metadata, "crop_bottom", avio_rl32(pb), 1);

    /* parse image offsets */

    avio_seek(pb, offImageOffsets, SEEK_SET);

    for (i = 0; i < st->duration; i++)

        av_add_index_entry(st, avio_rl64(pb), i, 0, 0, AVINDEX_KEYFRAME);

    return 0;

}


QDict *qtest_qmpv(QTestState *s, const char *fmt, va_list ap)

{

    /* Send QMP request */

    socket_sendf(s->qmp_fd, fmt, ap);

    /* Receive reply */

    return qtest_qmp_receive(s);

}


static void handle_arg_log_filename(const char *arg)

{

    qemu_set_log_filename(arg);

}


static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf)

{

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

    switch (buf[0]) {

    case REPORT_LUNS:

        if (!scsi_target_emulate_report_luns(r)) {

            goto illegal_request;

        }

        break;

    case INQUIRY:

        if (!scsi_target_emulate_inquiry(r)) {

            goto illegal_request;

        }

        break;

    case REQUEST_SENSE:

        r->len = scsi_device_get_sense(r->req.dev, r->buf,

                                       MIN(req->cmd.xfer, sizeof r->buf),

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

        if (r->req.dev->sense_is_ua) {

            scsi_device_unit_attention_reported(req->dev);

            r->req.dev->sense_len = 0;

            r->req.dev->sense_is_ua = false;

        }

        break;

    default:

        scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED));

        scsi_req_complete(req, CHECK_CONDITION);

        return 0;

    illegal_request:

        scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD));

        scsi_req_complete(req, CHECK_CONDITION);

        return 0;

    }

    if (!r->len) {

        scsi_req_complete(req, GOOD);

    }

    return r->len;

}


static int CUDAAPI cuvid_handle_video_sequence(void *opaque, CUVIDEOFORMAT* format)
{
    AVCodecContext *avctx = opaque;
    CuvidContext *ctx = avctx->priv_data;
    AVHWFramesContext *hwframe_ctx = (AVHWFramesContext*)ctx->hwframe->data;
    CUVIDDECODECREATEINFO cuinfo;
    av_log(avctx, AV_LOG_TRACE, "pfnSequenceCallback\n");
    ctx->internal_error = 0;
    avctx->width = format->display_area.right;
    avctx->height = format->display_area.bottom;
    ff_set_sar(avctx, av_div_q(
        (AVRational){ format->display_aspect_ratio.x, format->display_aspect_ratio.y },
        (AVRational){ avctx->width, avctx->height }));
    if (!format->progressive_sequence)
        avctx->flags |= AV_CODEC_FLAG_INTERLACED_DCT;
    else
        avctx->flags &= ~AV_CODEC_FLAG_INTERLACED_DCT;
    if (format->video_signal_description.video_full_range_flag)
        avctx->color_range = AVCOL_RANGE_JPEG;
    else
        avctx->color_range = AVCOL_RANGE_MPEG;
    avctx->color_primaries = format->video_signal_description.color_primaries;
    avctx->color_trc = format->video_signal_description.transfer_characteristics;
    avctx->colorspace = format->video_signal_description.matrix_coefficients;
    if (format->bitrate)
        avctx->bit_rate = format->bitrate;
    if (format->frame_rate.numerator && format->frame_rate.denominator) {
        avctx->framerate.num = format->frame_rate.numerator;
        avctx->framerate.den = format->frame_rate.denominator;
    if (ctx->cudecoder
            && avctx->coded_width == format->coded_width
            && avctx->coded_height == format->coded_height
            && ctx->chroma_format == format->chroma_format
            && ctx->codec_type == format->codec)
        return 1;
    if (ctx->cudecoder) {
        av_log(avctx, AV_LOG_ERROR, "re-initializing decoder is not supported\n");
    if (hwframe_ctx->pool && !ctx->ever_flushed) {
        av_log(avctx, AV_LOG_ERROR, "AVHWFramesContext is already initialized\n");
    avctx->coded_width = format->coded_width;
    avctx->coded_height = format->coded_height;
    ctx->chroma_format = format->chroma_format;
    memset(&cuinfo, 0, sizeof(cuinfo));
    cuinfo.CodecType = ctx->codec_type = format->codec;
    cuinfo.ChromaFormat = format->chroma_format;
    cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12;
    cuinfo.ulWidth = avctx->coded_width;
    cuinfo.ulHeight = avctx->coded_height;
    cuinfo.ulTargetWidth = cuinfo.ulWidth;
    cuinfo.ulTargetHeight = cuinfo.ulHeight;
    cuinfo.target_rect.left = 0;
    cuinfo.target_rect.top = 0;
    cuinfo.target_rect.right = cuinfo.ulWidth;
    cuinfo.target_rect.bottom = cuinfo.ulHeight;
    cuinfo.ulNumDecodeSurfaces = MAX_FRAME_COUNT;
    cuinfo.ulNumOutputSurfaces = 1;
    cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID;
    cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave;
    ctx->internal_error = CHECK_CU(cuvidCreateDecoder(&ctx->cudecoder, &cuinfo));
    if (ctx->internal_error < 0)
    if (!hwframe_ctx->pool) {
        hwframe_ctx->format = AV_PIX_FMT_CUDA;
        hwframe_ctx->sw_format = AV_PIX_FMT_NV12;
        hwframe_ctx->width = FFALIGN(avctx->coded_width, 32);
        hwframe_ctx->height = FFALIGN(avctx->coded_height, 32);
        if ((ctx->internal_error = av_hwframe_ctx_init(ctx->hwframe)) < 0) {
            av_log(avctx, AV_LOG_ERROR, "av_hwframe_ctx_init failed\n");
    return 1;


static void test_leak_bucket(void)
{
    throttle_config_init(&cfg);
    bkt = cfg.buckets[THROTTLE_BPS_TOTAL];
    /* set initial value */
    bkt.avg = 150;
    bkt.max = 15;
    bkt.level = 1.5;
    /* leak an op work of time */
    throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150);
    g_assert(bkt.avg == 150);
    g_assert(bkt.max == 15);
    g_assert(double_cmp(bkt.level, 0.5));
    /* leak again emptying the bucket */
    throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150);
    g_assert(bkt.avg == 150);
    g_assert(bkt.max == 15);
    g_assert(double_cmp(bkt.level, 0));
    /* check that the bucket level won't go lower */
    throttle_leak_bucket(&bkt, NANOSECONDS_PER_SECOND / 150);
    g_assert(bkt.avg == 150);
    g_assert(bkt.max == 15);
    g_assert(double_cmp(bkt.level, 0));
}


static BlockAIOCB *blkverify_aio_readv(BlockDriverState *bs,

        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,

        BlockCompletionFunc *cb, void *opaque)

{

    BDRVBlkverifyState *s = bs->opaque;

    BlkverifyAIOCB *acb = blkverify_aio_get(bs, false, sector_num, qiov,

                                            nb_sectors, cb, opaque);

    acb->verify = blkverify_verify_readv;

    acb->buf = qemu_blockalign(bs->file->bs, qiov->size);

    qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov);

    qemu_iovec_clone(&acb->raw_qiov, qiov, acb->buf);

    bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors,

                   blkverify_aio_cb, acb);

    bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors,

                   blkverify_aio_cb, acb);

    return &acb->common;

}


void ff_put_pixels_clamped_mmx(const DCTELEM *block, uint8_t *pixels,

                               int line_size)

{

    const DCTELEM *p;

    uint8_t *pix;

    /* read the pixels */

    p   = block;

    pix = pixels;

    /* unrolled loop */

    __asm__ volatile (

        "movq        %3, %%mm0          \n\t"

        "movq       8%3, %%mm1          \n\t"

        "movq      16%3, %%mm2          \n\t"

        "movq      24%3, %%mm3          \n\t"

        "movq      32%3, %%mm4          \n\t"

        "movq      40%3, %%mm5          \n\t"

        "movq      48%3, %%mm6          \n\t"

        "movq      56%3, %%mm7          \n\t"

        "packuswb %%mm1, %%mm0          \n\t"

        "packuswb %%mm3, %%mm2          \n\t"

        "packuswb %%mm5, %%mm4          \n\t"

        "packuswb %%mm7, %%mm6          \n\t"

        "movq     %%mm0, (%0)           \n\t"

        "movq     %%mm2, (%0, %1)       \n\t"

        "movq     %%mm4, (%0, %1, 2)    \n\t"

        "movq     %%mm6, (%0, %2)       \n\t"

        :: "r"(pix), "r"((x86_reg)line_size), "r"((x86_reg)line_size * 3),

           "m"(*p)

        : "memory");

    pix += line_size * 4;

    p   += 32;

    // if here would be an exact copy of the code above

    // compiler would generate some very strange code

    // thus using "r"

    __asm__ volatile (

        "movq       (%3), %%mm0         \n\t"

        "movq      8(%3), %%mm1         \n\t"

        "movq     16(%3), %%mm2         \n\t"

        "movq     24(%3), %%mm3         \n\t"

        "movq     32(%3), %%mm4         \n\t"

        "movq     40(%3), %%mm5         \n\t"

        "movq     48(%3), %%mm6         \n\t"

        "movq     56(%3), %%mm7         \n\t"

        "packuswb  %%mm1, %%mm0         \n\t"

        "packuswb  %%mm3, %%mm2         \n\t"

        "packuswb  %%mm5, %%mm4         \n\t"

        "packuswb  %%mm7, %%mm6         \n\t"

        "movq      %%mm0, (%0)          \n\t"

        "movq      %%mm2, (%0, %1)      \n\t"

        "movq      %%mm4, (%0, %1, 2)   \n\t"

        "movq      %%mm6, (%0, %2)      \n\t"

        :: "r"(pix), "r"((x86_reg)line_size), "r"((x86_reg)line_size * 3), "r"(p)

        : "memory");

}


static target_ulong h_enter(CPUPPCState *env, sPAPREnvironment *spapr,

                            target_ulong opcode, target_ulong *args)

{

    target_ulong flags = args[0];

    target_ulong pte_index = args[1];

    target_ulong pteh = args[2];

    target_ulong ptel = args[3];

    target_ulong page_shift = 12;

    target_ulong raddr;

    target_ulong i;

    uint8_t *hpte;

    /* only handle 4k and 16M pages for now */

    if (pteh & HPTE_V_LARGE) {

#if 0 /* We don't support 64k pages yet */

        if ((ptel & 0xf000) == 0x1000) {

            /* 64k page */

        } else

#endif

        if ((ptel & 0xff000) == 0) {

            /* 16M page */

            page_shift = 24;

            /* lowest AVA bit must be 0 for 16M pages */

            if (pteh & 0x80) {

                return H_PARAMETER;

            }

        } else {

            return H_PARAMETER;

        }

    }

    raddr = (ptel & HPTE_R_RPN) & ~((1ULL << page_shift) - 1);

    if (raddr < spapr->ram_limit) {

        /* Regular RAM - should have WIMG=0010 */

        if ((ptel & HPTE_R_WIMG) != HPTE_R_M) {

            return H_PARAMETER;

        }

    } else {

        /* Looks like an IO address */

        /* FIXME: What WIMG combinations could be sensible for IO?

         * For now we allow WIMG=010x, but are there others? */

        /* FIXME: Should we check against registered IO addresses? */

        if ((ptel & (HPTE_R_W | HPTE_R_I | HPTE_R_M)) != HPTE_R_I) {

            return H_PARAMETER;

        }

    }

    pteh &= ~0x60ULL;

    if ((pte_index * HASH_PTE_SIZE_64) & ~env->htab_mask) {

        return H_PARAMETER;

    }

    if (likely((flags & H_EXACT) == 0)) {

        pte_index &= ~7ULL;

        hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);

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

            if (i == 8) {

                return H_PTEG_FULL;

            }

            if (((ldq_p(hpte) & HPTE_V_VALID) == 0) &&

                lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID)) {

                break;

            }

            hpte += HASH_PTE_SIZE_64;

        }

    } else {

        i = 0;

        hpte = env->external_htab + (pte_index * HASH_PTE_SIZE_64);

        if (!lock_hpte(hpte, HPTE_V_HVLOCK | HPTE_V_VALID)) {

            return H_PTEG_FULL;

        }

    }

    stq_p(hpte + (HASH_PTE_SIZE_64/2), ptel);

    /* eieio();  FIXME: need some sort of barrier for smp? */

    stq_p(hpte, pteh);

    assert(!(ldq_p(hpte) & HPTE_V_HVLOCK));

    args[0] = pte_index + i;

    return H_SUCCESS;

}


static void exynos4210_gic_init(Object *obj)

{

    DeviceState *dev = DEVICE(obj);

    Exynos4210GicState *s = EXYNOS4210_GIC(obj);

    SysBusDevice *sbd = SYS_BUS_DEVICE(obj);

    uint32_t i;

    const char cpu_prefix[] = "exynos4210-gic-alias_cpu";

    const char dist_prefix[] = "exynos4210-gic-alias_dist";

    char cpu_alias_name[sizeof(cpu_prefix) + 3];

    char dist_alias_name[sizeof(cpu_prefix) + 3];

    SysBusDevice *busdev;

    s->gic = qdev_create(NULL, "arm_gic");

    qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu);

    qdev_prop_set_uint32(s->gic, "num-irq", EXYNOS4210_GIC_NIRQ);

    qdev_init_nofail(s->gic);

    busdev = SYS_BUS_DEVICE(s->gic);

    /* Pass through outbound IRQ lines from the GIC */

    sysbus_pass_irq(sbd, busdev);

    /* Pass through inbound GPIO lines to the GIC */

    qdev_init_gpio_in(dev, exynos4210_gic_set_irq,

                      EXYNOS4210_GIC_NIRQ - 32);

    memory_region_init(&s->cpu_container, obj, "exynos4210-cpu-container",

            EXYNOS4210_EXT_GIC_CPU_REGION_SIZE);

    memory_region_init(&s->dist_container, obj, "exynos4210-dist-container",

            EXYNOS4210_EXT_GIC_DIST_REGION_SIZE);

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

        /* Map CPU interface per SMP Core */

        sprintf(cpu_alias_name, "%s%x", cpu_prefix, i);

        memory_region_init_alias(&s->cpu_alias[i], obj,

                                 cpu_alias_name,

                                 sysbus_mmio_get_region(busdev, 1),

                                 0,

                                 EXYNOS4210_GIC_CPU_REGION_SIZE);

        memory_region_add_subregion(&s->cpu_container,

                EXYNOS4210_EXT_GIC_CPU_GET_OFFSET(i), &s->cpu_alias[i]);

        /* Map Distributor per SMP Core */

        sprintf(dist_alias_name, "%s%x", dist_prefix, i);

        memory_region_init_alias(&s->dist_alias[i], obj,

                                 dist_alias_name,

                                 sysbus_mmio_get_region(busdev, 0),

                                 0,

                                 EXYNOS4210_GIC_DIST_REGION_SIZE);

        memory_region_add_subregion(&s->dist_container,

                EXYNOS4210_EXT_GIC_DIST_GET_OFFSET(i), &s->dist_alias[i]);

    }

    sysbus_init_mmio(sbd, &s->cpu_container);

    sysbus_init_mmio(sbd, &s->dist_container);

}


static av_cold void compute_alpha_vlcs(void)

{

    uint16_t run_code[129], level_code[256];

    uint8_t run_bits[129], level_bits[256];

    int run, level;

    for (run = 0; run < 128; run++) {

        if (!run) {

            /* 0 -> 0. */

            run_code[run] = 0;

            run_bits[run] = 1;

        } else if (run <= 4) {

            /* 10xx -> xx plus 1. */

            run_code[run] = ((run - 1) << 2) | 1;

            run_bits[run] = 4;

        } else {

            /* 111xxxxxxx -> xxxxxxxx. */

            run_code[run] = (run << 3) | 7;

            run_bits[run] = 10;

        }

    }

    /* 110 -> EOB. */

    run_code[128] = 3;

    run_bits[128] = 3;

    INIT_LE_VLC_STATIC(&ff_dc_alpha_run_vlc_le, ALPHA_VLC_BITS, 129,

                       run_bits, 1, 1,

                       run_code, 2, 2, 160);

    for (level = 0; level < 256; level++) {

        int8_t signed_level = (int8_t)level;

        int abs_signed_level = abs(signed_level);

        int sign = (signed_level < 0) ? 1 : 0;

        if (abs_signed_level == 1) {

            /* 1s -> -1 or +1 (depending on sign bit). */

            level_code[level] = (sign << 1) | 1;

            level_bits[level] = 2;

        } else if (abs_signed_level >= 2 && abs_signed_level <= 5) {

            /* 01sxx -> xx plus 2 (2..5 or -2..-5, depending on sign bit). */

            level_code[level] = ((abs_signed_level - 2) << 3) | (sign << 2) | 2;

            level_bits[level] = 5;

        } else {

            /*

             * 00xxxxxxxx -> xxxxxxxx, in two's complement. 0 is technically an

             * illegal code (that would be encoded by increasing run), but it

             * doesn't hurt and simplifies indexing.

             */

            level_code[level] = level << 2;

            level_bits[level] = 10;

        }

    }

    INIT_LE_VLC_STATIC(&ff_dc_alpha_level_vlc_le, ALPHA_VLC_BITS, 256,

                       level_bits, 1, 1,

                       level_code, 2, 2, 288);

}