static int css_interpret_ccw(SubchDev *sch, hwaddr ccw_addr,

                             bool suspend_allowed)

{

    int ret;

    bool check_len;

    int len;

    CCW1 ccw;

    if (!ccw_addr) {

        return -EIO;

    }

    /* Check doubleword aligned and 31 or 24 (fmt 0) bit addressable. */

    if (ccw_addr & (sch->ccw_fmt_1 ? 0x80000007 : 0xff000007)) {

        return -EINVAL;

    }

    /* Translate everything to format-1 ccws - the information is the same. */

    ccw = copy_ccw_from_guest(ccw_addr, sch->ccw_fmt_1);

    /* Check for invalid command codes. */

    if ((ccw.cmd_code & 0x0f) == 0) {

        return -EINVAL;

    }

    if (((ccw.cmd_code & 0x0f) == CCW_CMD_TIC) &&

        ((ccw.cmd_code & 0xf0) != 0)) {

        return -EINVAL;

    }

    if (!sch->ccw_fmt_1 && (ccw.count == 0) &&

        (ccw.cmd_code != CCW_CMD_TIC)) {

        return -EINVAL;

    }

    /* We don't support MIDA. */

    if (ccw.flags & CCW_FLAG_MIDA) {

        return -EINVAL;

    }

    if (ccw.flags & CCW_FLAG_SUSPEND) {

        return suspend_allowed ? -EINPROGRESS : -EINVAL;

    }

    check_len = !((ccw.flags & CCW_FLAG_SLI) && !(ccw.flags & CCW_FLAG_DC));

    if (!ccw.cda) {

        if (sch->ccw_no_data_cnt == 255) {

            return -EINVAL;

        }

        sch->ccw_no_data_cnt++;

    }

    /* Look at the command. */

    switch (ccw.cmd_code) {

    case CCW_CMD_NOOP:

        /* Nothing to do. */

        ret = 0;

        break;

    case CCW_CMD_BASIC_SENSE:

        if (check_len) {

            if (ccw.count != sizeof(sch->sense_data)) {

                ret = -EINVAL;

                break;

            }

        }

        len = MIN(ccw.count, sizeof(sch->sense_data));

        cpu_physical_memory_write(ccw.cda, sch->sense_data, len);

        sch->curr_status.scsw.count = ccw.count - len;

        memset(sch->sense_data, 0, sizeof(sch->sense_data));

        ret = 0;

        break;

    case CCW_CMD_SENSE_ID:

    {

        SenseId sense_id;

        copy_sense_id_to_guest(&sense_id, &sch->id);

        /* Sense ID information is device specific. */

        if (check_len) {

            if (ccw.count != sizeof(sense_id)) {

                ret = -EINVAL;

                break;

            }

        }

        len = MIN(ccw.count, sizeof(sense_id));

        /*

         * Only indicate 0xff in the first sense byte if we actually

         * have enough place to store at least bytes 0-3.

         */

        if (len >= 4) {

            sense_id.reserved = 0xff;

        } else {

            sense_id.reserved = 0;

        }

        cpu_physical_memory_write(ccw.cda, &sense_id, len);

        sch->curr_status.scsw.count = ccw.count - len;

        ret = 0;

        break;

    }

    case CCW_CMD_TIC:

        if (sch->last_cmd_valid && (sch->last_cmd.cmd_code == CCW_CMD_TIC)) {

            ret = -EINVAL;

            break;

        }

        if (ccw.flags & (CCW_FLAG_CC | CCW_FLAG_DC)) {

            ret = -EINVAL;

            break;

        }

        sch->channel_prog = ccw.cda;

        ret = -EAGAIN;

        break;

    default:

        if (sch->ccw_cb) {

            /* Handle device specific commands. */

            ret = sch->ccw_cb(sch, ccw);

        } else {

            ret = -ENOSYS;

        }

        break;

    }

    sch->last_cmd = ccw;

    sch->last_cmd_valid = true;

    if (ret == 0) {

        if (ccw.flags & CCW_FLAG_CC) {

            sch->channel_prog += 8;

            ret = -EAGAIN;

        }

    }

    return ret;

}


static void bdrv_detach_child(BdrvChild *child)

{

    if (child->next.le_prev) {

        QLIST_REMOVE(child, next);

        child->next.le_prev = NULL;

    }

    bdrv_replace_child(child, NULL, false);

    g_free(child->name);

    g_free(child);

}


RTCState *rtc_mm_init(target_phys_addr_t base, int it_shift, qemu_irq irq,

                      int base_year)

{

    RTCState *s;

    int io_memory;

    s = qemu_mallocz(sizeof(RTCState));

    s->irq = irq;

    s->cmos_data[RTC_REG_A] = 0x26;

    s->cmos_data[RTC_REG_B] = 0x02;

    s->cmos_data[RTC_REG_C] = 0x00;

    s->cmos_data[RTC_REG_D] = 0x80;

    s->base_year = base_year;

    rtc_set_date_from_host(s);

    s->periodic_timer = qemu_new_timer(rtc_clock, rtc_periodic_timer, s);

    s->second_timer = qemu_new_timer(rtc_clock, rtc_update_second, s);

    s->second_timer2 = qemu_new_timer(rtc_clock, rtc_update_second2, s);

    s->next_second_time =

        qemu_get_clock(rtc_clock) + (get_ticks_per_sec() * 99) / 100;

    qemu_mod_timer(s->second_timer2, s->next_second_time);

    io_memory = cpu_register_io_memory(rtc_mm_read, rtc_mm_write, s);

    cpu_register_physical_memory(base, 2 << it_shift, io_memory);

    register_savevm("mc146818rtc", base, 1, rtc_save, rtc_load, s);

#ifdef TARGET_I386

    if (rtc_td_hack)

        register_savevm("mc146818rtc-td", base, 1, rtc_save_td, rtc_load_td, s);

#endif

    qemu_register_reset(rtc_reset, s);

    return s;

}


INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )

{

    return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;

}


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

                        const char *backing_file, const char *backing_format,

                        int flags, size_t cluster_size, int prealloc)

{

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

    int ref_clusters, backing_format_len = 0;

    QCowHeader header;

    uint64_t tmp, offset;

    QCowCreateState s1, *s = &s1;

    QCowExtension ext_bf = {0, 0};

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

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

    if (fd < 0)

        return -1;

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

    header.magic = cpu_to_be32(QCOW_MAGIC);

    header.version = cpu_to_be32(QCOW_VERSION);

    header.size = cpu_to_be64(total_size * 512);

    header_size = sizeof(header);

    backing_filename_len = 0;

    if (backing_file) {

        if (backing_format) {

            ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT;

            backing_format_len = strlen(backing_format);

            ext_bf.len = (backing_format_len + 7) & ~7;

            header_size += ((sizeof(ext_bf) + ext_bf.len + 7) & ~7);

        }

        header.backing_file_offset = cpu_to_be64(header_size);

        backing_filename_len = strlen(backing_file);

        header.backing_file_size = cpu_to_be32(backing_filename_len);

        header_size += backing_filename_len;

    }

    /* Cluster size */

    s->cluster_bits = get_bits_from_size(cluster_size);

    if (s->cluster_bits < MIN_CLUSTER_BITS ||

        s->cluster_bits > MAX_CLUSTER_BITS)

    {

        fprintf(stderr, "Cluster size must be a power of two between "

            "%d and %dk\n",

            1 << MIN_CLUSTER_BITS,

            1 << (MAX_CLUSTER_BITS - 10));

        return -EINVAL;

    }

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

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

    header_size = (header_size + 7) & ~7;

    if (flags & BLOCK_FLAG_ENCRYPT) {

        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);

    } else {

        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);

    }

    l2_bits = s->cluster_bits - 3;

    shift = s->cluster_bits + l2_bits;

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

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

    s->l1_table_offset = offset;

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

    header.l1_size = cpu_to_be32(l1_size);

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

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

    s->refcount_table_offset = offset;

    header.refcount_table_offset = cpu_to_be64(offset);

    header.refcount_table_clusters = cpu_to_be32(1);

    offset += s->cluster_size;

    s->refcount_block_offset = offset;

    /* count how many refcount blocks needed */

    tmp = offset >> s->cluster_bits;

    ref_clusters = (tmp >> (s->cluster_bits - REFCOUNT_SHIFT)) + 1;

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

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

        offset += s->cluster_size;

    }

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

    /* update refcounts */

    qcow2_create_refcount_update(s, 0, header_size);

    qcow2_create_refcount_update(s, s->l1_table_offset,

        l1_size * sizeof(uint64_t));

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

    qcow2_create_refcount_update(s, s->refcount_block_offset,

        ref_clusters * s->cluster_size);

    /* write all the data */

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

    if (backing_file) {

        if (backing_format_len) {

            char zero[16];

            int d = ext_bf.len - backing_format_len;

            memset(zero, 0, sizeof(zero));

            cpu_to_be32s(&ext_bf.magic);

            cpu_to_be32s(&ext_bf.len);

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

            write(fd, backing_format, backing_format_len);

            if (d>0) {

                write(fd, zero, d);

            }

        }

        write(fd, backing_file, backing_filename_len);

    }

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

    tmp = 0;

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

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

    }

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

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

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

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

    qemu_free(s->refcount_table);

    qemu_free(s->refcount_block);

    close(fd);

    /* Preallocate metadata */

    if (prealloc) {

        BlockDriverState *bs;

        bs = bdrv_new("");

        bdrv_open(bs, filename, BDRV_O_CACHE_WB);

        preallocate(bs);

        bdrv_close(bs);

    }

    return 0;

}


static void scsi_cd_change_media_cb(void *opaque, bool load)

{

    SCSIDiskState *s = opaque;

    /*

     * When a CD gets changed, we have to report an ejected state and

     * then a loaded state to guests so that they detect tray

     * open/close and media change events.  Guests that do not use

     * GET_EVENT_STATUS_NOTIFICATION to detect such tray open/close

     * states rely on this behavior.

     *

     * media_changed governs the state machine used for unit attention

     * report.  media_event is used by GET EVENT STATUS NOTIFICATION.

     */

    s->media_changed = load;

    s->tray_open = !load;

    s->qdev.unit_attention = SENSE_CODE(UNIT_ATTENTION_NO_MEDIUM);

    s->media_event = true;

    s->eject_request = false;

}


static int check_directory_consistency(BDRVVVFATState *s,

	int cluster_num, const char* path)

{

    int ret = 0;

    unsigned char* cluster = g_malloc(s->cluster_size);

    direntry_t* direntries = (direntry_t*)cluster;

    mapping_t* mapping = find_mapping_for_cluster(s, cluster_num);

    long_file_name lfn;

    int path_len = strlen(path);

    char path2[PATH_MAX];

    assert(path_len < PATH_MAX); /* len was tested before! */

    pstrcpy(path2, sizeof(path2), path);

    path2[path_len] = '/';

    path2[path_len + 1] = '\0';

    if (mapping) {

	const char* basename = get_basename(mapping->path);

	const char* basename2 = get_basename(path);

	assert(mapping->mode & MODE_DIRECTORY);

	assert(mapping->mode & MODE_DELETED);

	mapping->mode &= ~MODE_DELETED;

	if (strcmp(basename, basename2))

	    schedule_rename(s, cluster_num, g_strdup(path));

    } else

	/* new directory */

	schedule_mkdir(s, cluster_num, g_strdup(path));

    lfn_init(&lfn);

    do {

	int i;

	int subret = 0;

	ret++;

	if (s->used_clusters[cluster_num] & USED_ANY) {

	    fprintf(stderr, "cluster %d used more than once\n", (int)cluster_num);

	    return 0;

	}

	s->used_clusters[cluster_num] = USED_DIRECTORY;

DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)cluster2sector(s, cluster_num)));

	subret = vvfat_read(s->bs, cluster2sector(s, cluster_num), cluster,

		s->sectors_per_cluster);

	if (subret) {

	    fprintf(stderr, "Error fetching direntries\n");

	fail:

	    free(cluster);

	    return 0;

	}

	for (i = 0; i < 0x10 * s->sectors_per_cluster; i++) {

	    int cluster_count = 0;

DLOG(fprintf(stderr, "check direntry %d: \n", i); print_direntry(direntries + i));

	    if (is_volume_label(direntries + i) || is_dot(direntries + i) ||

		    is_free(direntries + i))

		continue;

	    subret = parse_long_name(&lfn, direntries + i);

	    if (subret < 0) {

		fprintf(stderr, "Error in long name\n");

		goto fail;

	    }

	    if (subret == 0 || is_free(direntries + i))

		continue;

	    if (fat_chksum(direntries+i) != lfn.checksum) {

		subret = parse_short_name(s, &lfn, direntries + i);

		if (subret < 0) {

		    fprintf(stderr, "Error in short name (%d)\n", subret);

		    goto fail;

		}

		if (subret > 0 || !strcmp((char*)lfn.name, ".")

			|| !strcmp((char*)lfn.name, ".."))

		    continue;

	    }

	    lfn.checksum = 0x100; /* cannot use long name twice */

	    if (path_len + 1 + lfn.len >= PATH_MAX) {

		fprintf(stderr, "Name too long: %s/%s\n", path, lfn.name);

		goto fail;

	    }

            pstrcpy(path2 + path_len + 1, sizeof(path2) - path_len - 1,

                    (char*)lfn.name);

	    if (is_directory(direntries + i)) {

		if (begin_of_direntry(direntries + i) == 0) {

		    DLOG(fprintf(stderr, "invalid begin for directory: %s\n", path2); print_direntry(direntries + i));

		    goto fail;

		}

		cluster_count = check_directory_consistency(s,

			begin_of_direntry(direntries + i), path2);

		if (cluster_count == 0) {

		    DLOG(fprintf(stderr, "problem in directory %s:\n", path2); print_direntry(direntries + i));

		    goto fail;

		}

	    } else if (is_file(direntries + i)) {

		/* check file size with FAT */

		cluster_count = get_cluster_count_for_direntry(s, direntries + i, path2);

		if (cluster_count !=

			(le32_to_cpu(direntries[i].size) + s->cluster_size

			 - 1) / s->cluster_size) {

		    DLOG(fprintf(stderr, "Cluster count mismatch\n"));

		    goto fail;

		}

	    } else

                abort(); /* cluster_count = 0; */

	    ret += cluster_count;

	}

	cluster_num = modified_fat_get(s, cluster_num);

    } while(!fat_eof(s, cluster_num));

    free(cluster);

    return ret;

}


static void scsi_disk_emulate_write_data(SCSIRequest *req)

{

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

    if (r->iov.iov_len) {

        int buflen = r->iov.iov_len;

        DPRINTF("Write buf_len=%zd\n", buflen);

        r->iov.iov_len = 0;

        scsi_req_data(&r->req, buflen);

        return;

    }

    switch (req->cmd.buf[0]) {

    case MODE_SELECT:

    case MODE_SELECT_10:

        /* This also clears the sense buffer for REQUEST SENSE.  */

        scsi_req_complete(&r->req, GOOD);

        break;

    default:

        abort();

    }

}


bool tcg_cpu_exec(void)

{

    int ret = 0;

    if (next_cpu == NULL)

        next_cpu = first_cpu;

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

        CPUState *env = cur_cpu = next_cpu;

        qemu_clock_enable(vm_clock,

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

        if (qemu_alarm_pending())

            break;

        if (cpu_can_run(env))

            ret = qemu_cpu_exec(env);

        else if (env->stop)

            break;

        if (ret == EXCP_DEBUG) {

            gdb_set_stop_cpu(env);

            debug_requested = EXCP_DEBUG;

            break;

        }

    }

    return tcg_has_work();

}


static void memory_region_dispatch_write(MemoryRegion *mr,

                                         hwaddr addr,

                                         uint64_t data,

                                         unsigned size)

{

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

        return; /* FIXME: better signalling */

    }

    adjust_endianness(mr, &data, size);

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

        mr->ops->old_mmio.write[bitops_ctzl(size)](mr->opaque, addr, data);

        return;

    }

    /* 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_write_accessor, mr);

}


int bdrv_eject(BlockDriverState *bs, int eject_flag)

{

    BlockDriver *drv = bs->drv;

    if (bs->locked) {

        return -EBUSY;

    }

    if (drv && drv->bdrv_eject) {

        drv->bdrv_eject(bs, eject_flag);

    }

    bs->tray_open = eject_flag;

    return 0;

}


static struct XenDevice *xen_be_del_xendev(int dom, int dev)

{

    struct XenDevice *xendev, *xnext;

    /*

     * This is pretty much like QTAILQ_FOREACH(xendev, &xendevs, next) but

     * we save the next pointer in xnext because we might free xendev.

     */

    xnext = xendevs.tqh_first;

    while (xnext) {

        xendev = xnext;

        xnext = xendev->next.tqe_next;

        if (xendev->dom != dom) {

            continue;

        }

        if (xendev->dev != dev && dev != -1) {

            continue;

        }

        if (xendev->ops->free) {

            xendev->ops->free(xendev);

        }

        if (xendev->fe) {

            char token[XEN_BUFSIZE];

            snprintf(token, sizeof(token), "fe:%p", xendev);

            xs_unwatch(xenstore, xendev->fe, token);

            g_free(xendev->fe);

        }

        if (xendev->evtchndev != XC_HANDLER_INITIAL_VALUE) {

            xc_evtchn_close(xendev->evtchndev);

        }

        if (xendev->gnttabdev != XC_HANDLER_INITIAL_VALUE) {

            xc_gnttab_close(xendev->gnttabdev);

        }

        QTAILQ_REMOVE(&xendevs, xendev, next);

        g_free(xendev);

    }

    return NULL;

}


static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, unsigned int max_pos, int depth) {

    AVCodecContext *acodec, *vcodec;

    ByteIOContext *ioc;

    AMFDataType amf_type;

    char str_val[256];

    double num_val;

    num_val = 0;

    ioc = s->pb;

    amf_type = get_byte(ioc);

    switch(amf_type) {

        case AMF_DATA_TYPE_NUMBER:

            num_val = av_int2dbl(get_be64(ioc)); break;

        case AMF_DATA_TYPE_BOOL:

            num_val = get_byte(ioc); break;

        case AMF_DATA_TYPE_STRING:

            if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0)

                return -1;

            break;

        case AMF_DATA_TYPE_OBJECT: {

            unsigned int keylen;

            while(url_ftell(ioc) < max_pos - 2 && (keylen = get_be16(ioc))) {

                url_fskip(ioc, keylen); //skip key string

                if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)

                    return -1; //if we couldn't skip, bomb out.

            }

            if(get_byte(ioc) != AMF_END_OF_OBJECT)

                return -1;

        }

            break;

        case AMF_DATA_TYPE_NULL:

        case AMF_DATA_TYPE_UNDEFINED:

        case AMF_DATA_TYPE_UNSUPPORTED:

            break; //these take up no additional space

        case AMF_DATA_TYPE_MIXEDARRAY:

            url_fskip(ioc, 4); //skip 32-bit max array index

            while(url_ftell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) {

                //this is the only case in which we would want a nested parse to not skip over the object

                if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0)

                    return -1;

            }

            if(get_byte(ioc) != AMF_END_OF_OBJECT)

                return -1;

            break;

        case AMF_DATA_TYPE_ARRAY: {

            unsigned int arraylen, i;

            arraylen = get_be32(ioc);

            for(i = 0; i < arraylen && url_ftell(ioc) < max_pos - 1; i++) {

                if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0)

                    return -1; //if we couldn't skip, bomb out.

            }

        }

            break;

        case AMF_DATA_TYPE_DATE:

            url_fskip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16)

            break;

        default: //unsupported type, we couldn't skip

            return -1;

    }

    if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL

        acodec = astream ? astream->codec : NULL;

        vcodec = vstream ? vstream->codec : NULL;

        if(amf_type == AMF_DATA_TYPE_BOOL) {

            if(!strcmp(key, "stereo") && acodec) acodec->channels = num_val > 0 ? 2 : 1;

        } else if(amf_type == AMF_DATA_TYPE_NUMBER) {

            if(!strcmp(key, "duration")) s->duration = num_val * AV_TIME_BASE;

//            else if(!strcmp(key, "width")  && vcodec && num_val > 0) vcodec->width  = num_val;

//            else if(!strcmp(key, "height") && vcodec && num_val > 0) vcodec->height = num_val;

            else if(!strcmp(key, "audiocodecid") && acodec) flv_set_audio_codec(s, astream, (int)num_val << FLV_AUDIO_CODECID_OFFSET);

            else if(!strcmp(key, "videocodecid") && vcodec) flv_set_video_codec(s, vstream, (int)num_val);

            else if(!strcmp(key, "audiosamplesize") && acodec && num_val >= 0) {

                acodec->bits_per_sample = num_val;

                //we may have to rewrite a previously read codecid because FLV only marks PCM endianness.

                if(num_val == 8 && (acodec->codec_id == CODEC_ID_PCM_S16BE || acodec->codec_id == CODEC_ID_PCM_S16LE))

                    acodec->codec_id = CODEC_ID_PCM_S8;

            }

            else if(!strcmp(key, "audiosamplerate") && acodec && num_val >= 0) {

                //some tools, like FLVTool2, write consistently approximate metadata sample rates

                if (!acodec->sample_rate) {

                    switch((int)num_val) {

                        case 44000: acodec->sample_rate = 44100  ; break;

                        case 22000: acodec->sample_rate = 22050  ; break;

                        case 11000: acodec->sample_rate = 11025  ; break;

                        case 5000 : acodec->sample_rate = 5512   ; break;

                        default   : acodec->sample_rate = num_val;

                    }

                }

            }

        }

    }

    return 0;

}


static void kvm_init_irq_routing(KVMState *s)

{

    int gsi_count;

    gsi_count = kvm_check_extension(s, KVM_CAP_IRQ_ROUTING);

    if (gsi_count > 0) {

        unsigned int gsi_bits, i;

        /* Round up so we can search ints using ffs */

        gsi_bits = ALIGN(gsi_count, 32);

        s->used_gsi_bitmap = g_malloc0(gsi_bits / 8);

        s->max_gsi = gsi_bits;

        /* Mark any over-allocated bits as already in use */

        for (i = gsi_count; i < gsi_bits; i++) {

            set_gsi(s, i);

        }

    }

    s->irq_routes = g_malloc0(sizeof(*s->irq_routes));

    s->nr_allocated_irq_routes = 0;

    kvm_arch_init_irq_routing(s);

}


static void uart_read_rx_fifo(UartState *s, uint32_t *c)

{

    if ((s->r[R_CR] & UART_CR_RX_DIS) || !(s->r[R_CR] & UART_CR_RX_EN)) {

        return;

    }

    if (s->rx_count) {

        uint32_t rx_rpos =

                (RX_FIFO_SIZE + s->rx_wpos - s->rx_count) % RX_FIFO_SIZE;

        *c = s->rx_fifo[rx_rpos];

        s->rx_count--;

        qemu_chr_accept_input(s->chr);

    } else {

        *c = 0;

    }

    uart_update_status(s);

}


static void setup_frame(int sig, struct target_sigaction *ka,

                        target_sigset_t *set, CPUAlphaState *env)

{

    abi_ulong frame_addr, r26;

    struct target_sigframe *frame;

    int err = 0;

    frame_addr = get_sigframe(ka, env, sizeof(*frame));

    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {

        goto give_sigsegv;

    }

    err |= setup_sigcontext(&frame->sc, env, frame_addr, set);

    if (ka->sa_restorer) {

        r26 = ka->sa_restorer;

    } else {

        __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);

        __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,

                   &frame->retcode[1]);

        __put_user(INSN_CALLSYS, &frame->retcode[2]);

        /* imb() */

        r26 = frame_addr;

    }

    unlock_user_struct(frame, frame_addr, 1);

    if (err) {

    give_sigsegv:

        if (sig == TARGET_SIGSEGV) {

            ka->_sa_handler = TARGET_SIG_DFL;

        }

        force_sig(TARGET_SIGSEGV);

    }

    env->ir[IR_RA] = r26;

    env->ir[IR_PV] = env->pc = ka->_sa_handler;

    env->ir[IR_A0] = sig;

    env->ir[IR_A1] = 0;

    env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);

    env->ir[IR_SP] = frame_addr;

}


static void spin_kick(void *data)

{

    SpinKick *kick = data;

    CPUState *cpu = CPU(kick->cpu);

    CPUPPCState *env = &kick->cpu->env;

    SpinInfo *curspin = kick->spin;

    hwaddr map_size = 64 * 1024 * 1024;

    hwaddr map_start;

    cpu_synchronize_state(cpu);

    stl_p(&curspin->pir, env->spr[SPR_PIR]);

    env->nip = ldq_p(&curspin->addr) & (map_size - 1);

    env->gpr[3] = ldq_p(&curspin->r3);

    env->gpr[4] = 0;

    env->gpr[5] = 0;

    env->gpr[6] = 0;

    env->gpr[7] = map_size;

    env->gpr[8] = 0;

    env->gpr[9] = 0;

    map_start = ldq_p(&curspin->addr) & ~(map_size - 1);

    mmubooke_create_initial_mapping(env, 0, map_start, map_size);

    cpu->halted = 0;

    cpu->exception_index = -1;

    cpu->stopped = false;

    qemu_cpu_kick(cpu);

}


static void sd_blk_write(SDState *sd, uint64_t addr, uint32_t len)

{

    uint64_t end = addr + len;

    if ((addr & 511) || len < 512)

        if (!sd->bdrv || bdrv_read(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {

            fprintf(stderr, "sd_blk_write: read error on host side\n");

            return;

        }

    if (end > (addr & ~511) + 512) {

        memcpy(sd->buf + (addr & 511), sd->data, 512 - (addr & 511));

        if (bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {

            fprintf(stderr, "sd_blk_write: write error on host side\n");

            return;

        }

        if (bdrv_read(sd->bdrv, end >> 9, sd->buf, 1) < 0) {

            fprintf(stderr, "sd_blk_write: read error on host side\n");

            return;

        }

        memcpy(sd->buf, sd->data + 512 - (addr & 511), end & 511);

        if (bdrv_write(sd->bdrv, end >> 9, sd->buf, 1) < 0) {

            fprintf(stderr, "sd_blk_write: write error on host side\n");

        }

    } else {

        memcpy(sd->buf + (addr & 511), sd->data, len);

        if (!sd->bdrv || bdrv_write(sd->bdrv, addr >> 9, sd->buf, 1) < 0) {

            fprintf(stderr, "sd_blk_write: write error on host side\n");

        }

    }

}


static struct omap_uwire_s *omap_uwire_init(MemoryRegion *system_memory,

                                            target_phys_addr_t base,

                                            qemu_irq txirq, qemu_irq rxirq,

                                            qemu_irq dma,

                                            omap_clk clk)

{

    struct omap_uwire_s *s = (struct omap_uwire_s *)

            g_malloc0(sizeof(struct omap_uwire_s));

    s->txirq = txirq;

    s->rxirq = rxirq;

    s->txdrq = dma;

    omap_uwire_reset(s);

    memory_region_init_io(&s->iomem, &omap_uwire_ops, s, "omap-uwire", 0x800);

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

    return s;

}


static void exception_action(CPUState *cpu)

{

#if defined(TARGET_I386)

    X86CPU *x86_cpu = X86_CPU(cpu);

    CPUX86State *env1 = &x86_cpu->env;

    raise_exception_err(env1, cpu->exception_index, env1->error_code);

#else

    cpu_loop_exit(cpu);

#endif

}


void term_printf(const char *fmt, ...)

{

    char buf[4096];

    va_list ap;

    va_start(ap, fmt);

    vsnprintf(buf, sizeof(buf), fmt, ap);

    qemu_chr_write(monitor_hd, buf, strlen(buf));

    va_end(ap);

}


static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf)

{

    switch (buf[0] >> 5) {

    case 0:

        cmd->xfer = buf[4];

        cmd->len = 6;

        break;

    case 1:

    case 2:

        cmd->xfer = lduw_be_p(&buf[7]);

        cmd->len = 10;

        break;

    case 4:

        cmd->xfer = ldl_be_p(&buf[10]) & 0xffffffffULL;

        cmd->len = 16;

        break;

    case 5:

        cmd->xfer = ldl_be_p(&buf[6]) & 0xffffffffULL;

        cmd->len = 12;

        break;

    default:

        return -1;

    }

    switch (buf[0]) {

    case TEST_UNIT_READY:

    case REWIND:

    case START_STOP:

    case SET_CAPACITY:

    case WRITE_FILEMARKS:

    case WRITE_FILEMARKS_16:

    case SPACE:

    case RESERVE:

    case RELEASE:

    case ERASE:

    case ALLOW_MEDIUM_REMOVAL:

    case VERIFY_10:

    case SEEK_10:

    case SYNCHRONIZE_CACHE:

    case SYNCHRONIZE_CACHE_16:

    case LOCATE_16:

    case LOCK_UNLOCK_CACHE:

    case SET_CD_SPEED:

    case SET_LIMITS:

    case WRITE_LONG_10:

    case MOVE_MEDIUM:

    case UPDATE_BLOCK:

    case RESERVE_TRACK:

    case SET_READ_AHEAD:

    case PRE_FETCH:

    case PRE_FETCH_16:

    case ALLOW_OVERWRITE:

        cmd->xfer = 0;

        break;

    case MODE_SENSE:

        break;

    case WRITE_SAME_10:

    case WRITE_SAME_16:

        cmd->xfer = dev->blocksize;

        break;

    case READ_CAPACITY_10:

        cmd->xfer = 8;

        break;

    case READ_BLOCK_LIMITS:

        cmd->xfer = 6;

        break;

    case SEND_VOLUME_TAG:

        /* GPCMD_SET_STREAMING from multimedia commands.  */

        if (dev->type == TYPE_ROM) {

            cmd->xfer = buf[10] | (buf[9] << 8);

        } else {

            cmd->xfer = buf[9] | (buf[8] << 8);

        }

        break;

    case WRITE_6:

        /* length 0 means 256 blocks */

        if (cmd->xfer == 0) {

            cmd->xfer = 256;

        }

    case WRITE_10:

    case WRITE_VERIFY_10:

    case WRITE_12:

    case WRITE_VERIFY_12:

    case WRITE_16:

    case WRITE_VERIFY_16:

        cmd->xfer *= dev->blocksize;

        break;

    case READ_6:

    case READ_REVERSE:

        /* length 0 means 256 blocks */

        if (cmd->xfer == 0) {

            cmd->xfer = 256;

        }

    case READ_10:

    case RECOVER_BUFFERED_DATA:

    case READ_12:

    case READ_16:

        cmd->xfer *= dev->blocksize;

        break;

    case FORMAT_UNIT:

        /* MMC mandates the parameter list to be 12-bytes long.  Parameters

         * for block devices are restricted to the header right now.  */

        if (dev->type == TYPE_ROM && (buf[1] & 16)) {

            cmd->xfer = 12;

        } else {

            cmd->xfer = (buf[1] & 16) == 0 ? 0 : (buf[1] & 32 ? 8 : 4);

        }

        break;

    case INQUIRY:

    case RECEIVE_DIAGNOSTIC:

    case SEND_DIAGNOSTIC:

        cmd->xfer = buf[4] | (buf[3] << 8);

        break;

    case READ_CD:

    case READ_BUFFER:

    case WRITE_BUFFER:

    case SEND_CUE_SHEET:

        cmd->xfer = buf[8] | (buf[7] << 8) | (buf[6] << 16);

        break;

    case PERSISTENT_RESERVE_OUT:

        cmd->xfer = ldl_be_p(&buf[5]) & 0xffffffffULL;

        break;

    case ERASE_12:

        if (dev->type == TYPE_ROM) {

            /* MMC command GET PERFORMANCE.  */

            cmd->xfer = scsi_get_performance_length(buf[9] | (buf[8] << 8),

                                                    buf[10], buf[1] & 0x1f);

        }

        break;

    case MECHANISM_STATUS:

    case READ_DVD_STRUCTURE:

    case SEND_DVD_STRUCTURE:

    case MAINTENANCE_OUT:

    case MAINTENANCE_IN:

        if (dev->type == TYPE_ROM) {

            /* GPCMD_REPORT_KEY and GPCMD_SEND_KEY from multi media commands */

            cmd->xfer = buf[9] | (buf[8] << 8);

        }

        break;

    }

    return 0;

}


static void draw_slice(AVFilterLink *link, int y, int h)

{

    ScaleContext *scale = link->dst->priv;

    int out_h;

    AVFilterPicRef *cur_pic = link->cur_pic;

    uint8_t *data[4];

    if (!scale->slice_dir) {

        if (y != 0 && y + h != link->h) {

            av_log(scale, AV_LOG_ERROR, "Slices start in the middle!\n");

            return;

        }

        scale->slice_dir = y ?                       -1 : 1;

        scale->slice_y   = y ? link->dst->outputs[0]->h : y;

    }

    data[0] = cur_pic->data[0] +  y               * cur_pic->linesize[0];

    data[1] = scale->input_is_pal ?

              cur_pic->data[1] :

              cur_pic->data[1] + (y>>scale->vsub) * cur_pic->linesize[1];

    data[2] = cur_pic->data[2] + (y>>scale->vsub) * cur_pic->linesize[2];

    data[3] = cur_pic->data[3] +  y               * cur_pic->linesize[3];

    out_h = sws_scale(scale->sws, data, cur_pic->linesize, y, h,

                      link->dst->outputs[0]->outpic->data,

                      link->dst->outputs[0]->outpic->linesize);

    if (scale->slice_dir == -1)

        scale->slice_y -= out_h;

    avfilter_draw_slice(link->dst->outputs[0], scale->slice_y, out_h);

    if (scale->slice_dir == 1)

        scale->slice_y += out_h;

}


static void spapr_phb_finish_realize(sPAPRPHBState *sphb, Error **errp)

{

    sphb->dma_window_start = 0;

    sphb->dma_window_size = 0x40000000;

    sphb->tcet = spapr_tce_new_table(DEVICE(sphb), sphb->dma_liobn,

                                     sphb->dma_window_size);

    if (!sphb->tcet) {

        error_setg(errp, "Unable to create TCE table for %s",

                   sphb->dtbusname);

        return ;

    }

    address_space_init(&sphb->iommu_as, spapr_tce_get_iommu(sphb->tcet),

                       sphb->dtbusname);

}


static void tcx_rblit_writel(void *opaque, hwaddr addr,

                         uint64_t val, unsigned size)

{

    TCXState *s = opaque;

    uint32_t adsr, len;

    int i;

    if (!(addr & 4)) {

        s->tmpblit = val;

    } else {

        addr = (addr >> 3) & 0xfffff;

        adsr = val & 0xffffff;

        len = ((val >> 24) & 0x1f) + 1;

        if (adsr == 0xffffff) {

            memset(&s->vram[addr], s->tmpblit, len);

            if (s->depth == 24) {

                val = s->tmpblit & 0xffffff;

                val = cpu_to_be32(val);

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

                    s->vram24[addr + i] = val;

                    s->cplane[addr + i] = val;

                }

            }

        } else {

            memcpy(&s->vram[addr], &s->vram[adsr], len);

            if (s->depth == 24) {

                memcpy(&s->vram24[addr], &s->vram24[adsr], len * 4);

                memcpy(&s->cplane[addr], &s->cplane[adsr], len * 4);

            }

        }

        memory_region_set_dirty(&s->vram_mem, addr, len);

    }

}


static CharDriverState *qemu_chr_open_mux(const char *id,

                                          ChardevBackend *backend,

                                          ChardevReturn *ret, Error **errp)

{

    ChardevMux *mux = backend->mux;

    CharDriverState *chr, *drv;

    MuxDriver *d;

    drv = qemu_chr_find(mux->chardev);

    if (drv == NULL) {

        error_setg(errp, "mux: base chardev %s not found", mux->chardev);

        return NULL;

    }

    chr = qemu_chr_alloc();

    d = g_new0(MuxDriver, 1);

    chr->opaque = d;

    d->drv = drv;

    d->focus = -1;

    chr->chr_write = mux_chr_write;

    chr->chr_update_read_handler = mux_chr_update_read_handler;

    chr->chr_accept_input = mux_chr_accept_input;

    /* Frontend guest-open / -close notification is not support with muxes */

    chr->chr_set_fe_open = NULL;

    if (drv->chr_add_watch) {

        chr->chr_add_watch = mux_chr_add_watch;

    }

    /* only default to opened state if we've realized the initial

     * set of muxes

     */

    chr->explicit_be_open = muxes_realized ? 0 : 1;

    chr->is_mux = 1;

    return chr;

}


static void pmac_ide_transfer(DBDMA_io *io)

{

    MACIOIDEState *m = io->opaque;

    IDEState *s = idebus_active_if(&m->bus);

    MACIO_DPRINTF("\n");

    s->io_buffer_size = 0;

    if (s->drive_kind == IDE_CD) {

        /* Handle non-block ATAPI DMA transfers */

        if (s->lba == -1) {

            s->io_buffer_size = MIN(io->len, s->packet_transfer_size);

            block_acct_start(bdrv_get_stats(s->bs), &s->acct, s->io_buffer_size,

                             BLOCK_ACCT_READ);

            MACIO_DPRINTF("non-block ATAPI DMA transfer size: %d\n",

                          s->io_buffer_size);

            /* Copy ATAPI buffer directly to RAM and finish */

            cpu_physical_memory_write(io->addr, s->io_buffer,

                                      s->io_buffer_size);

            ide_atapi_cmd_ok(s);

            m->dma_active = false;

            MACIO_DPRINTF("end of non-block ATAPI DMA transfer\n");

            block_acct_done(bdrv_get_stats(s->bs), &s->acct);

            io->dma_end(io);

            return;

        }

        block_acct_start(bdrv_get_stats(s->bs), &s->acct, io->len,

                         BLOCK_ACCT_READ);

        pmac_ide_atapi_transfer_cb(io, 0);

        return;

    }

    switch (s->dma_cmd) {

    case IDE_DMA_READ:

        block_acct_start(bdrv_get_stats(s->bs), &s->acct, io->len,

                         BLOCK_ACCT_READ);

        break;

    case IDE_DMA_WRITE:

        block_acct_start(bdrv_get_stats(s->bs), &s->acct, io->len,

                         BLOCK_ACCT_WRITE);

        break;

    default:

        break;

    }

    io->requests++;

    pmac_ide_transfer_cb(io, 0);

}


static void do_cpu_set(Monitor *mon, const QDict *qdict, QObject **ret_data)

{

    int index = qdict_get_int(qdict, "index");

    if (mon_set_cpu(index) < 0)

        qemu_error_new(QERR_INVALID_CPU_INDEX);

}


static int get_phys_addr_lpae(CPUARMState *env, target_ulong address,

                              int access_type, ARMMMUIdx mmu_idx,

                              hwaddr *phys_ptr, MemTxAttrs *txattrs, int *prot,

                              target_ulong *page_size_ptr)

{

    CPUState *cs = CPU(arm_env_get_cpu(env));

    /* Read an LPAE long-descriptor translation table. */

    MMUFaultType fault_type = translation_fault;

    uint32_t level = 1;

    uint32_t epd;

    int32_t tsz;

    uint32_t tg;

    uint64_t ttbr;

    int ttbr_select;

    hwaddr descaddr, descmask;

    uint32_t tableattrs;

    target_ulong page_size;

    uint32_t attrs;

    int32_t granule_sz = 9;

    int32_t va_size = 32;

    int32_t tbi = 0;

    TCR *tcr = regime_tcr(env, mmu_idx);

    int ap, ns, xn, pxn;

    /* TODO:

     * This code assumes we're either a 64-bit EL1 or a 32-bit PL1;

     * it doesn't handle the different format TCR for TCR_EL2, TCR_EL3,

     * and VTCR_EL2, or the fact that those regimes don't have a split

     * TTBR0/TTBR1. Attribute and permission bit handling should also

     * be checked when adding support for those page table walks.

     */

    if (arm_el_is_aa64(env, regime_el(env, mmu_idx))) {

        va_size = 64;

        if (extract64(address, 55, 1))

            tbi = extract64(tcr->raw_tcr, 38, 1);

        else

            tbi = extract64(tcr->raw_tcr, 37, 1);

        tbi *= 8;

    }

    /* Determine whether this address is in the region controlled by

     * TTBR0 or TTBR1 (or if it is in neither region and should fault).

     * This is a Non-secure PL0/1 stage 1 translation, so controlled by

     * TTBCR/TTBR0/TTBR1 in accordance with ARM ARM DDI0406C table B-32:

     */

    uint32_t t0sz = extract32(tcr->raw_tcr, 0, 6);

    if (va_size == 64) {

        t0sz = MIN(t0sz, 39);

        t0sz = MAX(t0sz, 16);

    }

    uint32_t t1sz = extract32(tcr->raw_tcr, 16, 6);

    if (va_size == 64) {

        t1sz = MIN(t1sz, 39);

        t1sz = MAX(t1sz, 16);

    }

    if (t0sz && !extract64(address, va_size - t0sz, t0sz - tbi)) {

        /* there is a ttbr0 region and we are in it (high bits all zero) */

        ttbr_select = 0;

    } else if (t1sz && !extract64(~address, va_size - t1sz, t1sz - tbi)) {

        /* there is a ttbr1 region and we are in it (high bits all one) */

        ttbr_select = 1;

    } else if (!t0sz) {

        /* ttbr0 region is "everything not in the ttbr1 region" */

        ttbr_select = 0;

    } else if (!t1sz) {

        /* ttbr1 region is "everything not in the ttbr0 region" */

        ttbr_select = 1;

    } else {

        /* in the gap between the two regions, this is a Translation fault */

        fault_type = translation_fault;

        goto do_fault;

    }

    /* Note that QEMU ignores shareability and cacheability attributes,

     * so we don't need to do anything with the SH, ORGN, IRGN fields

     * in the TTBCR.  Similarly, TTBCR:A1 selects whether we get the

     * ASID from TTBR0 or TTBR1, but QEMU's TLB doesn't currently

     * implement any ASID-like capability so we can ignore it (instead

     * we will always flush the TLB any time the ASID is changed).

     */

    if (ttbr_select == 0) {

        ttbr = regime_ttbr(env, mmu_idx, 0);

        epd = extract32(tcr->raw_tcr, 7, 1);

        tsz = t0sz;

        tg = extract32(tcr->raw_tcr, 14, 2);

        if (tg == 1) { /* 64KB pages */

            granule_sz = 13;

        }

        if (tg == 2) { /* 16KB pages */

            granule_sz = 11;

        }

    } else {

        ttbr = regime_ttbr(env, mmu_idx, 1);

        epd = extract32(tcr->raw_tcr, 23, 1);

        tsz = t1sz;

        tg = extract32(tcr->raw_tcr, 30, 2);

        if (tg == 3)  { /* 64KB pages */

            granule_sz = 13;

        }

        if (tg == 1) { /* 16KB pages */

            granule_sz = 11;

        }

    }

    /* Here we should have set up all the parameters for the translation:

     * va_size, ttbr, epd, tsz, granule_sz, tbi

     */

    if (epd) {

        /* Translation table walk disabled => Translation fault on TLB miss */

        goto do_fault;

    }

    /* The starting level depends on the virtual address size (which can be

     * up to 48 bits) and the translation granule size. It indicates the number

     * of strides (granule_sz bits at a time) needed to consume the bits

     * of the input address. In the pseudocode this is:

     *  level = 4 - RoundUp((inputsize - grainsize) / stride)

     * where their 'inputsize' is our 'va_size - tsz', 'grainsize' is

     * our 'granule_sz + 3' and 'stride' is our 'granule_sz'.

     * Applying the usual "rounded up m/n is (m+n-1)/n" and simplifying:

     *     = 4 - (va_size - tsz - granule_sz - 3 + granule_sz - 1) / granule_sz

     *     = 4 - (va_size - tsz - 4) / granule_sz;

     */

    level = 4 - (va_size - tsz - 4) / granule_sz;

    /* Clear the vaddr bits which aren't part of the within-region address,

     * so that we don't have to special case things when calculating the

     * first descriptor address.

     */

    if (tsz) {

        address &= (1ULL << (va_size - tsz)) - 1;

    }

    descmask = (1ULL << (granule_sz + 3)) - 1;

    /* Now we can extract the actual base address from the TTBR */

    descaddr = extract64(ttbr, 0, 48);

    descaddr &= ~((1ULL << (va_size - tsz - (granule_sz * (4 - level)))) - 1);

    /* Secure accesses start with the page table in secure memory and

     * can be downgraded to non-secure at any step. Non-secure accesses

     * remain non-secure. We implement this by just ORing in the NSTable/NS

     * bits at each step.

     */

    tableattrs = regime_is_secure(env, mmu_idx) ? 0 : (1 << 4);

    for (;;) {

        uint64_t descriptor;

        bool nstable;

        descaddr |= (address >> (granule_sz * (4 - level))) & descmask;

        descaddr &= ~7ULL;

        nstable = extract32(tableattrs, 4, 1);

        descriptor = arm_ldq_ptw(cs, descaddr, !nstable);

        if (!(descriptor & 1) ||

            (!(descriptor & 2) && (level == 3))) {

            /* Invalid, or the Reserved level 3 encoding */

            goto do_fault;

        }

        descaddr = descriptor & 0xfffffff000ULL;

        if ((descriptor & 2) && (level < 3)) {

            /* Table entry. The top five bits are attributes which  may

             * propagate down through lower levels of the table (and

             * which are all arranged so that 0 means "no effect", so

             * we can gather them up by ORing in the bits at each level).

             */

            tableattrs |= extract64(descriptor, 59, 5);

            level++;

            continue;

        }

        /* Block entry at level 1 or 2, or page entry at level 3.

         * These are basically the same thing, although the number

         * of bits we pull in from the vaddr varies.

         */

        page_size = (1ULL << ((granule_sz * (4 - level)) + 3));

        descaddr |= (address & (page_size - 1));

        /* Extract attributes from the descriptor and merge with table attrs */

        attrs = extract64(descriptor, 2, 10)

            | (extract64(descriptor, 52, 12) << 10);

        attrs |= extract32(tableattrs, 0, 2) << 11; /* XN, PXN */

        attrs |= extract32(tableattrs, 3, 1) << 5; /* APTable[1] => AP[2] */

        /* The sense of AP[1] vs APTable[0] is reversed, as APTable[0] == 1

         * means "force PL1 access only", which means forcing AP[1] to 0.

         */

        if (extract32(tableattrs, 2, 1)) {

            attrs &= ~(1 << 4);

        }

        attrs |= nstable << 3; /* NS */

        break;

    }

    /* Here descaddr is the final physical address, and attributes

     * are all in attrs.

     */

    fault_type = access_fault;

    if ((attrs & (1 << 8)) == 0) {

        /* Access flag */

        goto do_fault;

    }

    ap = extract32(attrs, 4, 2);

    ns = extract32(attrs, 3, 1);

    xn = extract32(attrs, 12, 1);

    pxn = extract32(attrs, 11, 1);

    *prot = get_S1prot(env, mmu_idx, va_size == 64, ap, ns, xn, pxn);

    fault_type = permission_fault;

    if (!(*prot & (1 << access_type))) {

        goto do_fault;

    }

    if (ns) {

        /* The NS bit will (as required by the architecture) have no effect if

         * the CPU doesn't support TZ or this is a non-secure translation

         * regime, because the attribute will already be non-secure.

         */

        txattrs->secure = false;

    }

    *phys_ptr = descaddr;

    *page_size_ptr = page_size;

    return 0;

do_fault:

    /* Long-descriptor format IFSR/DFSR value */

    return (1 << 9) | (fault_type << 2) | level;

}


static void qmp_input_start_struct(Visitor *v, void **obj, const char *kind,

                                   const char *name, size_t size, Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

    const QObject *qobj = qmp_input_get_object(qiv, name);

    if (!qobj || qobject_type(qobj) != QTYPE_QDICT) {

        error_set(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null",

                  "QDict");

        return;

    }

    qmp_input_push(qiv, qobj, errp);

    if (error_is_set(errp)) {

        return;

    }

    if (obj) {

        *obj = g_malloc0(size);

    }

}


static int join_request_frame(AVFilterLink *outlink)

{

    AVFilterContext *ctx = outlink->src;

    JoinContext *s       = ctx->priv;

    AVFilterBufferRef *buf;

    JoinBufferPriv *priv;

    int linesize   = INT_MAX;

    int perms      = ~0;

    int nb_samples;

    int i, j, ret;

    /* get a frame on each input */

    for (i = 0; i < ctx->nb_inputs; i++) {

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

        if (!s->input_frames[i] &&

            (ret = ff_request_frame(inlink)) < 0)

            return ret;

        /* request the same number of samples on all inputs */

        if (i == 0) {

            nb_samples = s->input_frames[0]->audio->nb_samples;

            for (j = 1; !i && j < ctx->nb_inputs; j++)

                ctx->inputs[j]->request_samples = nb_samples;

        }

    }

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

        ChannelMap *ch = &s->channels[i];

        AVFilterBufferRef *cur_buf = s->input_frames[ch->input];

        s->data[i] = cur_buf->extended_data[ch->in_channel_idx];

        linesize   = FFMIN(linesize, cur_buf->linesize[0]);

        perms     &= cur_buf->perms;

    }

    buf = avfilter_get_audio_buffer_ref_from_arrays(s->data, linesize, perms,

                                                    nb_samples, outlink->format,

                                                    outlink->channel_layout);

    if (!buf)

        return AVERROR(ENOMEM);

    buf->buf->free = join_free_buffer;

    buf->pts       = s->input_frames[0]->pts;

    if (!(priv = av_mallocz(sizeof(*priv))))

        goto fail;

    if (!(priv->in_buffers = av_mallocz(sizeof(*priv->in_buffers) * ctx->nb_inputs)))

        goto fail;

    for (i = 0; i < ctx->nb_inputs; i++)

        priv->in_buffers[i] = s->input_frames[i];

    priv->nb_in_buffers = ctx->nb_inputs;

    buf->buf->priv      = priv;

    ff_filter_samples(outlink, buf);

    memset(s->input_frames, 0, sizeof(*s->input_frames) * ctx->nb_inputs);

    return 0;

fail:

    avfilter_unref_buffer(buf);

    if (priv)

        av_freep(&priv->in_buffers);

    av_freep(&priv);

    return AVERROR(ENOMEM);

}


static inline void yuv2yuvXinC(int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

                               int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

                               uint8_t *dest, uint8_t *uDest, uint8_t *vDest, int dstW, int chrDstW)

{

    //FIXME Optimize (just quickly writen not opti..)

    int i;

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

    {

        int val=1<<18;

        int j;

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

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

        dest[i]= av_clip_uint8(val>>19);

    }

    if (uDest)

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

        {

            int u=1<<18;

            int v=1<<18;

            int j;

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

            {

                u += chrSrc[j][i] * chrFilter[j];

                v += chrSrc[j][i + 2048] * chrFilter[j];

            }

            uDest[i]= av_clip_uint8(u>>19);

            vDest[i]= av_clip_uint8(v>>19);

        }

}


static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,

                           uint32_t token, uint32_t nargs,

                           target_ulong args,

                           uint32_t nret, target_ulong rets)

{

    target_ulong id, start, r3;

    PowerPCCPU *cpu;

    if (nargs != 3 || nret != 1) {

        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);

        return;

    }

    id = rtas_ld(args, 0);

    start = rtas_ld(args, 1);

    r3 = rtas_ld(args, 2);

    cpu = spapr_find_cpu(id);

    if (cpu != NULL) {

        CPUState *cs = CPU(cpu);

        CPUPPCState *env = &cpu->env;

        if (!cs->halted) {

            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);

            return;

        }

        /* This will make sure qemu state is up to date with kvm, and

         * mark it dirty so our changes get flushed back before the

         * new cpu enters */

        kvm_cpu_synchronize_state(cs);

        env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);

        /* Enable Power-saving mode Exit Cause exceptions for the new CPU */

        env->spr[SPR_LPCR] |= pcc->lpcr_pm;

        env->nip = start;

        env->gpr[3] = r3;

        cs->halted = 0;

        spapr_cpu_set_endianness(cpu);

        spapr_cpu_update_tb_offset(cpu);

        qemu_cpu_kick(cs);

        rtas_st(rets, 0, RTAS_OUT_SUCCESS);

        return;

    }

    /* Didn't find a matching cpu */

    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);

}


static void check_decode_result(int *got_output, int ret)

{

    if (*got_output || ret<0)

        decode_error_stat[ret<0] ++;

    if (ret < 0 && exit_on_error)

        exit_program(1);

}


int vmstate_register_with_alias_id(DeviceState *dev, int instance_id,

                                   const VMStateDescription *vmsd,

                                   void *opaque, int alias_id,

                                   int required_for_version,

                                   Error **errp)

{

    SaveStateEntry *se;

    /* If this triggers, alias support can be dropped for the vmsd. */

    assert(alias_id == -1 || required_for_version >= vmsd->minimum_version_id);

    se = g_new0(SaveStateEntry, 1);

    se->version_id = vmsd->version_id;

    se->section_id = savevm_state.global_section_id++;

    se->opaque = opaque;

    se->vmsd = vmsd;

    se->alias_id = alias_id;

    if (dev) {

        char *id = qdev_get_dev_path(dev);

        if (id) {

            if (snprintf(se->idstr, sizeof(se->idstr), "%s/", id) >=

                sizeof(se->idstr)) {

                error_setg(errp, "Path too long for VMState (%s)", id);

                g_free(se);

                return -1;

            }

            se->compat = g_new0(CompatEntry, 1);

            pstrcpy(se->compat->idstr, sizeof(se->compat->idstr), vmsd->name);

            se->compat->instance_id = instance_id == -1 ?

                         calculate_compat_instance_id(vmsd->name) : instance_id;

            instance_id = -1;

        }

    }

    pstrcat(se->idstr, sizeof(se->idstr), vmsd->name);

    if (instance_id == -1) {

        se->instance_id = calculate_new_instance_id(se->idstr);

    } else {

        se->instance_id = instance_id;

    }

    assert(!se->compat || se->instance_id == 0);

    savevm_state_handler_insert(se);

    return 0;

}


static void test_qemu_strtoll_max(void)

{

    const char *str = g_strdup_printf("%lld", LLONG_MAX);

    char f = 'X';

    const char *endptr = &f;

    int64_t res = 999;

    int err;

    err = qemu_strtoll(str, &endptr, 0, &res);

    g_assert_cmpint(err, ==, 0);

    g_assert_cmpint(res, ==, LLONG_MAX);

    g_assert(endptr == str + strlen(str));

}


static int mace_decode_frame(AVCodecContext *avctx, void *data,
                             int *got_frame_ptr, AVPacket *avpkt)
{
    AVFrame *frame     = data;
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;
    int16_t **samples;
    MACEContext *ctx = avctx->priv_data;
    int i, j, k, l, ret;
    int is_mace3 = (avctx->codec_id == AV_CODEC_ID_MACE3);
    /* get output buffer */
    frame->nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels;
    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
        return ret;
    samples = (int16_t **)frame->extended_data;
    for(i = 0; i < avctx->channels; i++) {
        int16_t *output = samples[i];
        for (j=0; j < buf_size / (avctx->channels << is_mace3); j++)
            for (k=0; k < (1 << is_mace3); k++) {
                uint8_t pkt = buf[(i << is_mace3) +
                                  (j*avctx->channels << is_mace3) + k];
                uint8_t val[2][3] = {{pkt >> 5, (pkt >> 3) & 3, pkt & 7 },
                                     {pkt & 7 , (pkt >> 3) & 3, pkt >> 5}};
                for (l=0; l < 3; l++) {
                    if (is_mace3)
                        chomp3(&ctx->chd[i], output, val[1][l], l);
                    else
                        chomp6(&ctx->chd[i], output, val[0][l], l);
                    output += 1 << (1-is_mace3);
    *got_frame_ptr = 1;
    return buf_size;


static av_cold int rv30_decode_init(AVCodecContext *avctx)

{

    RV34DecContext *r = avctx->priv_data;

    int ret;

    r->rv30 = 1;

    if ((ret = ff_rv34_decode_init(avctx)) < 0)

        return ret;

    if(avctx->extradata_size < 2){

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

        return -1;

    r->max_rpr = avctx->extradata[1] & 7;

    r->parse_slice_header = rv30_parse_slice_header;

    r->decode_intra_types = rv30_decode_intra_types;

    r->decode_mb_info     = rv30_decode_mb_info;

    r->loop_filter        = rv30_loop_filter;

    r->luma_dc_quant_i = rv30_luma_dc_quant;

    r->luma_dc_quant_p = rv30_luma_dc_quant;

    return 0;


static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)

{

    unsigned int i;

    x86_def_t *def;

    char *s = g_strdup(cpu_model);

    char *featurestr, *name = strtok(s, ",");

    /* Features to be added*/

    uint32_t plus_features = 0, plus_ext_features = 0;

    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;

    uint32_t plus_kvm_features = 0, plus_svm_features = 0;

    /* Features to be removed */

    uint32_t minus_features = 0, minus_ext_features = 0;

    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;

    uint32_t minus_kvm_features = 0, minus_svm_features = 0;

    uint32_t numvalue;

    for (def = x86_defs; def; def = def->next)

        if (!strcmp(name, def->name))

            break;

    if (kvm_enabled() && strcmp(name, "host") == 0) {

        cpu_x86_fill_host(x86_cpu_def);

    } else if (!def) {

        goto error;

    } else {

        memcpy(x86_cpu_def, def, sizeof(*def));

    }

    plus_kvm_features = ~0; /* not supported bits will be filtered out later */

    add_flagname_to_bitmaps("hypervisor", &plus_features,

        &plus_ext_features, &plus_ext2_features, &plus_ext3_features,

        &plus_kvm_features, &plus_svm_features);

    featurestr = strtok(NULL, ",");

    while (featurestr) {

        char *val;

        if (featurestr[0] == '+') {

            add_flagname_to_bitmaps(featurestr + 1, &plus_features,

                            &plus_ext_features, &plus_ext2_features,

                            &plus_ext3_features, &plus_kvm_features,

                            &plus_svm_features);

        } else if (featurestr[0] == '-') {

            add_flagname_to_bitmaps(featurestr + 1, &minus_features,

                            &minus_ext_features, &minus_ext2_features,

                            &minus_ext3_features, &minus_kvm_features,

                            &minus_svm_features);

        } else if ((val = strchr(featurestr, '='))) {

            *val = 0; val++;

            if (!strcmp(featurestr, "family")) {

                char *err;

                numvalue = strtoul(val, &err, 0);

                if (!*val || *err) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->family = numvalue;

            } else if (!strcmp(featurestr, "model")) {

                char *err;

                numvalue = strtoul(val, &err, 0);

                if (!*val || *err || numvalue > 0xff) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->model = numvalue;

            } else if (!strcmp(featurestr, "stepping")) {

                char *err;

                numvalue = strtoul(val, &err, 0);

                if (!*val || *err || numvalue > 0xf) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->stepping = numvalue ;

            } else if (!strcmp(featurestr, "level")) {

                char *err;

                numvalue = strtoul(val, &err, 0);

                if (!*val || *err) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->level = numvalue;

            } else if (!strcmp(featurestr, "xlevel")) {

                char *err;

                numvalue = strtoul(val, &err, 0);

                if (!*val || *err) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                if (numvalue < 0x80000000) {

                    numvalue += 0x80000000;

                }

                x86_cpu_def->xlevel = numvalue;

            } else if (!strcmp(featurestr, "vendor")) {

                if (strlen(val) != 12) {

                    fprintf(stderr, "vendor string must be 12 chars long\n");

                    goto error;

                }

                x86_cpu_def->vendor1 = 0;

                x86_cpu_def->vendor2 = 0;

                x86_cpu_def->vendor3 = 0;

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

                    x86_cpu_def->vendor1 |= ((uint8_t)val[i    ]) << (8 * i);

                    x86_cpu_def->vendor2 |= ((uint8_t)val[i + 4]) << (8 * i);

                    x86_cpu_def->vendor3 |= ((uint8_t)val[i + 8]) << (8 * i);

                }

                x86_cpu_def->vendor_override = 1;

            } else if (!strcmp(featurestr, "model_id")) {

                pstrcpy(x86_cpu_def->model_id, sizeof(x86_cpu_def->model_id),

                        val);

            } else if (!strcmp(featurestr, "tsc_freq")) {

                int64_t tsc_freq;

                char *err;

                tsc_freq = strtosz_suffix_unit(val, &err,

                                               STRTOSZ_DEFSUFFIX_B, 1000);

                if (!*val || *err) {

                    fprintf(stderr, "bad numerical value %s\n", val);

                    goto error;

                }

                x86_cpu_def->tsc_khz = tsc_freq / 1000;

            } else {

                fprintf(stderr, "unrecognized feature %s\n", featurestr);

                goto error;

            }

        } else if (!strcmp(featurestr, "check")) {

            check_cpuid = 1;

        } else if (!strcmp(featurestr, "enforce")) {

            check_cpuid = enforce_cpuid = 1;

        } else {

            fprintf(stderr, "feature string `%s' not in format (+feature|-feature|feature=xyz)\n", featurestr);

            goto error;

        }

        featurestr = strtok(NULL, ",");

    }

    x86_cpu_def->features |= plus_features;

    x86_cpu_def->ext_features |= plus_ext_features;

    x86_cpu_def->ext2_features |= plus_ext2_features;

    x86_cpu_def->ext3_features |= plus_ext3_features;

    x86_cpu_def->kvm_features |= plus_kvm_features;

    x86_cpu_def->svm_features |= plus_svm_features;

    x86_cpu_def->features &= ~minus_features;

    x86_cpu_def->ext_features &= ~minus_ext_features;

    x86_cpu_def->ext2_features &= ~minus_ext2_features;

    x86_cpu_def->ext3_features &= ~minus_ext3_features;

    x86_cpu_def->kvm_features &= ~minus_kvm_features;

    x86_cpu_def->svm_features &= ~minus_svm_features;

    if (check_cpuid) {

        if (check_features_against_host(x86_cpu_def) && enforce_cpuid)

            goto error;

    }

    g_free(s);

    return 0;

error:

    g_free(s);

    return -1;

}


static int virtio_gpu_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)

{

    VirtIOGPU *g = opaque;

    if (idx > g->conf.max_outputs) {

        return -1;

    }

    g->req_state[idx].x = info->xoff;

    g->req_state[idx].y = info->yoff;

    g->req_state[idx].width = info->width;

    g->req_state[idx].height = info->height;

    if (info->width && info->height) {

        g->enabled_output_bitmask |= (1 << idx);

    } else {

        g->enabled_output_bitmask &= ~(1 << idx);

    }

    /* send event to guest */

    virtio_gpu_notify_event(g, VIRTIO_GPU_EVENT_DISPLAY);

    return 0;

}


void spapr_core_unplug(HotplugHandler *hotplug_dev, DeviceState *dev,

                       Error **errp)

{

    sPAPRCPUCore *core = SPAPR_CPU_CORE(OBJECT(dev));

    PowerPCCPU *cpu = POWERPC_CPU(core->threads);

    int id = ppc_get_vcpu_dt_id(cpu);

    sPAPRDRConnector *drc =

        spapr_dr_connector_by_id(SPAPR_DR_CONNECTOR_TYPE_CPU, id);

    sPAPRDRConnectorClass *drck;

    Error *local_err = NULL;

    g_assert(drc);

    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    drck->detach(drc, dev, spapr_core_release, NULL, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return;

    }

    spapr_hotplug_req_remove_by_index(drc);

}


static void qobject_input_check_struct(Visitor *v, Error **errp)

{

    QObjectInputVisitor *qiv = to_qiv(v);

    StackObject *tos = QSLIST_FIRST(&qiv->stack);

    assert(tos && !tos->entry);

    if (qiv->strict) {

        GHashTable *const top_ht = tos->h;

        if (top_ht) {

            GHashTableIter iter;

            const char *key;

            g_hash_table_iter_init(&iter, top_ht);

            if (g_hash_table_iter_next(&iter, (void **)&key, NULL)) {

                error_setg(errp, "Parameter '%s' is unexpected", key);

            }

        }

    }

}


static int mpeg_decode_slice(MpegEncContext *s, int mb_y,

                             const uint8_t **buf, int buf_size)

{

    AVCodecContext *avctx = s->avctx;

    const int field_pic   = s->picture_structure != PICT_FRAME;

    int ret;

    s->resync_mb_x =

    s->resync_mb_y = -1;

    assert(mb_y < s->mb_height);

    init_get_bits(&s->gb, *buf, buf_size * 8);

    ff_mpeg1_clean_buffers(s);

    s->interlaced_dct = 0;

    s->qscale = get_qscale(s);

    if (s->qscale == 0) {

        av_log(s->avctx, AV_LOG_ERROR, "qscale == 0\n");

        return AVERROR_INVALIDDATA;

    }

    /* extra slice info */

    while (get_bits1(&s->gb) != 0)

        skip_bits(&s->gb, 8);

    s->mb_x = 0;

    if (mb_y == 0 && s->codec_tag == AV_RL32("SLIF")) {

        skip_bits1(&s->gb);

    } else {

        while (get_bits_left(&s->gb) > 0) {

            int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,

                                MBINCR_VLC_BITS, 2);

            if (code < 0) {

                av_log(s->avctx, AV_LOG_ERROR, "first mb_incr damaged\n");

                return AVERROR_INVALIDDATA;

            }

            if (code >= 33) {

                if (code == 33)

                    s->mb_x += 33;

                /* otherwise, stuffing, nothing to do */

            } else {

                s->mb_x += code;

                break;

            }

        }

    }

    if (s->mb_x >= (unsigned) s->mb_width) {

        av_log(s->avctx, AV_LOG_ERROR, "initial skip overflow\n");

        return AVERROR_INVALIDDATA;

    }

    if (avctx->hwaccel) {

        const uint8_t *buf_end, *buf_start = *buf - 4; /* include start_code */

        int start_code = -1;

        buf_end = avpriv_find_start_code(buf_start + 2, *buf + buf_size, &start_code);

        if (buf_end < *buf + buf_size)

            buf_end -= 4;

        s->mb_y = mb_y;

        if (avctx->hwaccel->decode_slice(avctx, buf_start, buf_end - buf_start) < 0)

            return DECODE_SLICE_ERROR;

        *buf = buf_end;

        return DECODE_SLICE_OK;

    }

    s->resync_mb_x = s->mb_x;

    s->resync_mb_y = s->mb_y = mb_y;

    s->mb_skip_run = 0;

    ff_init_block_index(s);

    if (s->mb_y == 0 && s->mb_x == 0 && (s->first_field || s->picture_structure == PICT_FRAME)) {

        if (s->avctx->debug & FF_DEBUG_PICT_INFO) {

            av_log(s->avctx, AV_LOG_DEBUG,

                   "qp:%d fc:%2d%2d%2d%2d %s %s %s %s %s dc:%d pstruct:%d fdct:%d cmv:%d qtype:%d ivlc:%d rff:%d %s\n",

                   s->qscale,

                   s->mpeg_f_code[0][0], s->mpeg_f_code[0][1],

                   s->mpeg_f_code[1][0], s->mpeg_f_code[1][1],

                   s->pict_type  == AV_PICTURE_TYPE_I ? "I" :

                   (s->pict_type == AV_PICTURE_TYPE_P ? "P" :

                   (s->pict_type == AV_PICTURE_TYPE_B ? "B" : "S")),

                   s->progressive_sequence ? "ps"  : "",

                   s->progressive_frame    ? "pf"  : "",

                   s->alternate_scan       ? "alt" : "",

                   s->top_field_first      ? "top" : "",

                   s->intra_dc_precision, s->picture_structure,

                   s->frame_pred_frame_dct, s->concealment_motion_vectors,

                   s->q_scale_type, s->intra_vlc_format,

                   s->repeat_first_field, s->chroma_420_type ? "420" : "");

        }

    }

    for (;;) {

#if FF_API_XVMC

FF_DISABLE_DEPRECATION_WARNINGS

        // If 1, we memcpy blocks in xvmcvideo.

        if (CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration > 1)

            ff_xvmc_init_block(s); // set s->block

FF_ENABLE_DEPRECATION_WARNINGS

#endif /* FF_API_XVMC */

        if ((ret = mpeg_decode_mb(s, s->block)) < 0)

            return ret;

        // Note motion_val is normally NULL unless we want to extract the MVs.

        if (s->current_picture.motion_val[0] && !s->encoding) {

            const int wrap = s->b8_stride;

            int xy         = s->mb_x * 2 + s->mb_y * 2 * wrap;

            int b8_xy      = 4 * (s->mb_x + s->mb_y * s->mb_stride);

            int motion_x, motion_y, dir, i;

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

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

                    if (s->mb_intra ||

                        (dir == 1 && s->pict_type != AV_PICTURE_TYPE_B)) {

                        motion_x = motion_y = 0;

                    } else if (s->mv_type == MV_TYPE_16X16 ||

                               (s->mv_type == MV_TYPE_FIELD && field_pic)) {

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

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

                    } else { /* if ((s->mv_type == MV_TYPE_FIELD) || (s->mv_type == MV_TYPE_16X8)) */

                        motion_x = s->mv[dir][i][0];

                        motion_y = s->mv[dir][i][1];

                    }

                    s->current_picture.motion_val[dir][xy][0]     = motion_x;

                    s->current_picture.motion_val[dir][xy][1]     = motion_y;

                    s->current_picture.motion_val[dir][xy + 1][0] = motion_x;

                    s->current_picture.motion_val[dir][xy + 1][1] = motion_y;

                    s->current_picture.ref_index [dir][b8_xy]     =

                    s->current_picture.ref_index [dir][b8_xy + 1] = s->field_select[dir][i];

                    assert(s->field_select[dir][i] == 0 ||

                           s->field_select[dir][i] == 1);

                }

                xy    += wrap;

                b8_xy += 2;

            }

        }

        s->dest[0] += 16;

        s->dest[1] += 16 >> s->chroma_x_shift;

        s->dest[2] += 16 >> s->chroma_x_shift;

        ff_mpv_decode_mb(s, s->block);

        if (++s->mb_x >= s->mb_width) {

            const int mb_size = 16;

            ff_mpeg_draw_horiz_band(s, mb_size * (s->mb_y >> field_pic), mb_size);

            ff_mpv_report_decode_progress(s);

            s->mb_x  = 0;

            s->mb_y += 1 << field_pic;

            if (s->mb_y >= s->mb_height) {

                int left   = get_bits_left(&s->gb);

                int is_d10 = s->chroma_format == 2 &&

                             s->pict_type == AV_PICTURE_TYPE_I &&

                             avctx->profile == 0 && avctx->level == 5 &&

                             s->intra_dc_precision == 2 &&

                             s->q_scale_type == 1 && s->alternate_scan == 0 &&

                             s->progressive_frame == 0

                             /* vbv_delay == 0xBBB || 0xE10 */;

                if (left < 0 ||

                    (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) ||

                    ((avctx->err_recognition & AV_EF_BUFFER) && left > 8)) {

                    av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n",

                           left, show_bits(&s->gb, FFMIN(left, 23)));

                    return AVERROR_INVALIDDATA;

                } else

                    goto eos;

            }

            ff_init_block_index(s);

        }

        /* skip mb handling */

        if (s->mb_skip_run == -1) {

            /* read increment again */

            s->mb_skip_run = 0;

            for (;;) {

                int code = get_vlc2(&s->gb, ff_mbincr_vlc.table,

                                    MBINCR_VLC_BITS, 2);

                if (code < 0) {

                    av_log(s->avctx, AV_LOG_ERROR, "mb incr damaged\n");

                    return AVERROR_INVALIDDATA;

                }

                if (code >= 33) {

                    if (code == 33) {

                        s->mb_skip_run += 33;

                    } else if (code == 35) {

                        if (s->mb_skip_run != 0 || show_bits(&s->gb, 15) != 0) {

                            av_log(s->avctx, AV_LOG_ERROR, "slice mismatch\n");

                            return AVERROR_INVALIDDATA;

                        }

                        goto eos; /* end of slice */

                    }

                    /* otherwise, stuffing, nothing to do */

                } else {

                    s->mb_skip_run += code;

                    break;

                }

            }

            if (s->mb_skip_run) {

                int i;

                if (s->pict_type == AV_PICTURE_TYPE_I) {

                    av_log(s->avctx, AV_LOG_ERROR,

                           "skipped MB in I-frame at %d %d\n", s->mb_x, s->mb_y);

                    return AVERROR_INVALIDDATA;

                }

                /* skip mb */

                s->mb_intra = 0;

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

                    s->block_last_index[i] = -1;

                if (s->picture_structure == PICT_FRAME)

                    s->mv_type = MV_TYPE_16X16;

                else

                    s->mv_type = MV_TYPE_FIELD;

                if (s->pict_type == AV_PICTURE_TYPE_P) {

                    /* if P type, zero motion vector is implied */

                    s->mv_dir             = MV_DIR_FORWARD;

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

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

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

                    s->field_select[0][0] = (s->picture_structure - 1) & 1;

                } else {

                    /* if B type, reuse previous vectors and directions */

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

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

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

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

                }

            }

        }

    }

eos: // end of slice

    *buf += (get_bits_count(&s->gb) - 1) / 8;

    ff_dlog(s, "y %d %d %d %d\n", s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y);

    return 0;

}


create_iovec(QEMUIOVector *qiov, char **argv, int nr_iov, int pattern)

{

	size_t *sizes = calloc(nr_iov, sizeof(size_t));

	size_t count = 0;

	void *buf, *p;

	int i;

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

		char *arg = argv[i];

		long long len;

		len = cvtnum(arg);

		if (len < 0) {

			printf("non-numeric length argument -- %s\n", arg);

			return NULL;

		}

		/* should be SIZE_T_MAX, but that doesn't exist */

		if (len > UINT_MAX) {

			printf("too large length argument -- %s\n", arg);

			return NULL;

		}

		if (len & 0x1ff) {

			printf("length argument %lld is not sector aligned\n",

				len);

			return NULL;

		}

		sizes[i] = len;

		count += len;

	}

	qemu_iovec_init(qiov, nr_iov);

	buf = p = qemu_io_alloc(count, pattern);

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

		qemu_iovec_add(qiov, p, sizes[i]);

		p += sizes[i];

	}

	free(sizes);

	return buf;

}


static int vid_probe(AVProbeData *p)
{
    // little-endian VID tag, file starts with "VID\0"
    if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0))
        return 0;
    return AVPROBE_SCORE_MAX;
}


void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))

{

    int i;

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

        (*cpu_fprintf)(f, "PowerPC %-16s PVR %08x\n",

                       ppc_defs[i].name, ppc_defs[i].pvr);

        if (strcmp(ppc_defs[i].name, "default") == 0)

            break;

    }

}


void object_delete(Object *obj)

{

    object_unparent(obj);

    g_assert(obj->ref == 1);

    object_unref(obj);

    g_free(obj);

}


static int mpeg_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             uint8_t *buf, int buf_size)

{

    Mpeg1Context *s = avctx->priv_data;

    uint8_t *buf_end, *buf_ptr;

    int ret, start_code, input_size;

    AVFrame *picture = data;

    MpegEncContext *s2 = &s->mpeg_enc_ctx;

    dprintf("fill_buffer\n");

    *data_size = 0;

    /* special case for last picture */

    if (buf_size == 0) {

        if (s2->picture_number > 0) {

            *picture= *(AVFrame*)&s2->next_picture;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    if(s2->flags&CODEC_FLAG_TRUNCATED){

        int next;

        next= mpeg1_find_frame_end(s2, buf, buf_size);

        if( ff_combine_frame(s2, next, &buf, &buf_size) < 0 )

            return buf_size;

    }

    buf_ptr = buf;

    buf_end = buf + buf_size;

#if 0

    if (s->repeat_field % 2 == 1) {

        s->repeat_field++;

        //fprintf(stderr,"\nRepeating last frame: %d -> %d! pict: %d %d", avctx->frame_number-1, avctx->frame_number,

        //        s2->picture_number, s->repeat_field);

        if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) {

            *data_size = sizeof(AVPicture);

            goto the_end;

        }

    }

#endif

    for(;;) {

        /* find start next code */

        start_code = find_start_code(&buf_ptr, buf_end);

        if (start_code < 0){

            printf("missing end of picture\n");

            return FFMAX(1, buf_ptr - buf - s2->parse_context.last_index);

        }

                /* prepare data for next start code */

                input_size = buf_end - buf_ptr;

                switch(start_code) {

                case SEQ_START_CODE:

                    mpeg1_decode_sequence(avctx, buf_ptr,

                                          input_size);

                    break;

                case PICTURE_START_CODE:

                    /* we have a complete image : we try to decompress it */

                    mpeg1_decode_picture(avctx,

                                         buf_ptr, input_size);

                    break;

                case EXT_START_CODE:

                    mpeg_decode_extension(avctx,

                                          buf_ptr, input_size);

                    break;

                case USER_START_CODE:

                    mpeg_decode_user_data(avctx,

                                          buf_ptr, input_size);

                    break;

                default:

                    if (start_code >= SLICE_MIN_START_CODE &&

                        start_code <= SLICE_MAX_START_CODE) {

                        /* skip b frames if we dont have reference frames */

                        if(s2->last_picture_ptr==NULL && s2->pict_type==B_TYPE) break;

                        /* skip b frames if we are in a hurry */

                        if(avctx->hurry_up && s2->pict_type==B_TYPE) break;

                        /* skip everything if we are in a hurry>=5 */

                        if(avctx->hurry_up>=5) break;

                        if (!s->mpeg_enc_ctx_allocated) break;

                        ret = mpeg_decode_slice(avctx, picture,

                                                start_code, &buf_ptr, input_size);

                        if (ret == DECODE_SLICE_EOP) {

                            if(s2->last_picture_ptr) //FIXME merge with the stuff in mpeg_decode_slice

                                *data_size = sizeof(AVPicture);

                            return FFMAX(1, buf_ptr - buf - s2->parse_context.last_index);

                        }else if(ret < 0){

                            if(ret == DECODE_SLICE_ERROR)

                                ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x, s2->mb_y, AC_ERROR|DC_ERROR|MV_ERROR);

                            fprintf(stderr,"Error while decoding slice\n");

			    if(ret==DECODE_SLICE_FATAL_ERROR) return -1;

                        }

                    }

                    break;

                }

    }

}


static struct scsi_task *iscsi_do_inquiry(struct iscsi_context *iscsi, int lun,

                                          int evpd, int pc)

{

    int full_size;

    struct scsi_task *task = NULL;

    task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, 64);

    if (task == NULL || task->status != SCSI_STATUS_GOOD) {

        goto fail;

    }

    full_size = scsi_datain_getfullsize(task);

    if (full_size > task->datain.size) {

        scsi_free_scsi_task(task);

        /* we need more data for the full list */

        task = iscsi_inquiry_sync(iscsi, lun, evpd, pc, full_size);

        if (task == NULL || task->status != SCSI_STATUS_GOOD) {

            goto fail;

        }

    }

    return task;

fail:

    error_report("iSCSI: Inquiry command failed : %s",

                 iscsi_get_error(iscsi));

    if (task) {

        scsi_free_scsi_task(task);

        return NULL;

    }

    return NULL;

}


static target_ulong h_add_logical_lan_buffer(CPUPPCState *env,

                                             sPAPREnvironment *spapr,

                                             target_ulong opcode,

                                             target_ulong *args)

{

    target_ulong reg = args[0];

    target_ulong buf = args[1];

    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);

    VIOsPAPRVLANDevice *dev = (VIOsPAPRVLANDevice *)sdev;

    vlan_bd_t bd;

    dprintf("H_ADD_LOGICAL_LAN_BUFFER(0x" TARGET_FMT_lx

            ", 0x" TARGET_FMT_lx ")\n", reg, buf);

    if (!sdev) {

        hcall_dprintf("Bad device\n");

        return H_PARAMETER;

    }

    if ((check_bd(dev, buf, 4) < 0)

        || (VLAN_BD_LEN(buf) < 16)) {

        hcall_dprintf("Bad buffer enqueued\n");

        return H_PARAMETER;

    }

    if (!dev->isopen || dev->rx_bufs >= VLAN_MAX_BUFS) {

        return H_RESOURCE;

    }

    do {

        dev->add_buf_ptr += 8;

        if (dev->add_buf_ptr >= SPAPR_VIO_TCE_PAGE_SIZE) {

            dev->add_buf_ptr = VLAN_RX_BDS_OFF;

        }

        bd = ldq_tce(sdev, dev->buf_list + dev->add_buf_ptr);

    } while (bd & VLAN_BD_VALID);

    stq_tce(sdev, dev->buf_list + dev->add_buf_ptr, buf);

    dev->rx_bufs++;

    dprintf("h_add_logical_lan_buffer():  Added buf  ptr=%d  rx_bufs=%d"

            " bd=0x%016llx\n", dev->add_buf_ptr, dev->rx_bufs,

            (unsigned long long)buf);

    return H_SUCCESS;

}


static uint32_t unassigned_mem_readw(void *opaque, target_phys_addr_t addr)

{

#ifdef DEBUG_UNASSIGNED

    printf("Unassigned mem read " TARGET_FMT_plx "\n", addr);

#endif

#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)

    do_unassigned_access(addr, 0, 0, 0, 2);

#endif

    return 0;

}


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

                            const AVFrame *frame, int *got_packet_ptr)

{

    int n, c, sample_size, v, ret;

    const short *samples;

    unsigned char *dst;

    const uint8_t *samples_uint8_t;

    const int16_t *samples_int16_t;

    const int32_t *samples_int32_t;

    const int64_t *samples_int64_t;

    const uint16_t *samples_uint16_t;

    const uint32_t *samples_uint32_t;

    sample_size = av_get_bits_per_sample(avctx->codec->id) / 8;

    n           = frame->nb_samples * avctx->channels;

    samples     = (const short *)frame->data[0];

    if ((ret = ff_alloc_packet2(avctx, avpkt, n * sample_size)))

        return ret;

    dst = avpkt->data;

    switch (avctx->codec->id) {

    case AV_CODEC_ID_PCM_U32LE:

        ENCODE(uint32_t, le32, samples, dst, n, 0, 0x80000000)

        break;

    case AV_CODEC_ID_PCM_U32BE:

        ENCODE(uint32_t, be32, samples, dst, n, 0, 0x80000000)

        break;

    case AV_CODEC_ID_PCM_S24LE:

        ENCODE(int32_t, le24, samples, dst, n, 8, 0)

        break;

    case AV_CODEC_ID_PCM_S24LE_PLANAR:

        ENCODE_PLANAR(int32_t, le24, dst, n, 8, 0)

        break;

    case AV_CODEC_ID_PCM_S24BE:

        ENCODE(int32_t, be24, samples, dst, n, 8, 0)

        break;

    case AV_CODEC_ID_PCM_U24LE:

        ENCODE(uint32_t, le24, samples, dst, n, 8, 0x800000)

        break;

    case AV_CODEC_ID_PCM_U24BE:

        ENCODE(uint32_t, be24, samples, dst, n, 8, 0x800000)

        break;

    case AV_CODEC_ID_PCM_S24DAUD:

        for (; n > 0; n--) {

            uint32_t tmp = ff_reverse[(*samples >> 8) & 0xff] +

                           (ff_reverse[*samples & 0xff] << 8);

            tmp <<= 4; // sync flags would go here

            bytestream_put_be24(&dst, tmp);

            samples++;

        }

        break;

    case AV_CODEC_ID_PCM_U16LE:

        ENCODE(uint16_t, le16, samples, dst, n, 0, 0x8000)

        break;

    case AV_CODEC_ID_PCM_U16BE:

        ENCODE(uint16_t, be16, samples, dst, n, 0, 0x8000)

        break;

    case AV_CODEC_ID_PCM_S8:

        ENCODE(uint8_t, byte, samples, dst, n, 0, -128)

        break;

    case AV_CODEC_ID_PCM_S8_PLANAR:

        ENCODE_PLANAR(uint8_t, byte, dst, n, 0, -128)

        break;

#if HAVE_BIGENDIAN

    case AV_CODEC_ID_PCM_F64LE:

        ENCODE(int64_t, le64, samples, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_S32LE:

    case AV_CODEC_ID_PCM_F32LE:

        ENCODE(int32_t, le32, samples, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_S32LE_PLANAR:

        ENCODE_PLANAR(int32_t, le32, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_S16LE:

        ENCODE(int16_t, le16, samples, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_S16LE_PLANAR:

        ENCODE_PLANAR(int16_t, le16, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_F64BE:

    case AV_CODEC_ID_PCM_F32BE:

    case AV_CODEC_ID_PCM_S32BE:

    case AV_CODEC_ID_PCM_S16BE:

#else

    case AV_CODEC_ID_PCM_F64BE:

        ENCODE(int64_t, be64, samples, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_F32BE:

    case AV_CODEC_ID_PCM_S32BE:

        ENCODE(int32_t, be32, samples, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_S16BE:

        ENCODE(int16_t, be16, samples, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_S16BE_PLANAR:

        ENCODE_PLANAR(int16_t, be16, dst, n, 0, 0)

        break;

    case AV_CODEC_ID_PCM_F64LE:

    case AV_CODEC_ID_PCM_F32LE:

    case AV_CODEC_ID_PCM_S32LE:

    case AV_CODEC_ID_PCM_S16LE:

#endif /* HAVE_BIGENDIAN */

    case AV_CODEC_ID_PCM_U8:

        memcpy(dst, samples, n * sample_size);

        break;

#if HAVE_BIGENDIAN

    case AV_CODEC_ID_PCM_S16BE_PLANAR:

#else

    case AV_CODEC_ID_PCM_S16LE_PLANAR:

    case AV_CODEC_ID_PCM_S32LE_PLANAR:

#endif /* HAVE_BIGENDIAN */

        n /= avctx->channels;

        for (c = 0; c < avctx->channels; c++) {

            const uint8_t *src = frame->extended_data[c];

            bytestream_put_buffer(&dst, src, n * sample_size);

        }

        break;

    case AV_CODEC_ID_PCM_ALAW:

        for (; n > 0; n--) {

            v      = *samples++;

            *dst++ = linear_to_alaw[(v + 32768) >> 2];

        }

        break;

    case AV_CODEC_ID_PCM_MULAW:

        for (; n > 0; n--) {

            v      = *samples++;

            *dst++ = linear_to_ulaw[(v + 32768) >> 2];

        }

        break;

    default:

        return -1;

    }

    *got_packet_ptr = 1;

    return 0;

}


static int RENAME(epzs_motion_search)(MpegEncContext * s,

                             int *mx_ptr, int *my_ptr,

                             int P[10][2], int pred_x, int pred_y, uint8_t *src_data[3],

                             uint8_t *ref_data[3], int stride, int uvstride, int16_t (*last_mv)[2],

                             int ref_mv_scale, uint8_t * const mv_penalty)

{

    int best[2]={0, 0};

    int d, dmin;

    const int shift= 1+s->quarter_sample;

    uint32_t *map= s->me.map;

    int map_generation;

    const int penalty_factor= s->me.penalty_factor;

    const int size=0;

    const int h=16;

    const int ref_mv_stride= s->mb_stride; //pass as arg  FIXME

    const int ref_mv_xy= s->mb_x + s->mb_y*ref_mv_stride; //add to last_mv beforepassing FIXME

    me_cmp_func cmp, chroma_cmp;

    LOAD_COMMON

    cmp= s->dsp.me_cmp[size];

    chroma_cmp= s->dsp.me_cmp[size+1];

    map_generation= update_map_generation(s);

    CMP(dmin, 0, 0, size);

    map[0]= map_generation;

    score_map[0]= dmin;

    /* first line */

    if (s->first_slice_line) {

        CHECK_MV(P_LEFT[0]>>shift, P_LEFT[1]>>shift)

        CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,

                        (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)

    }else{

        if(dmin<256 && ( P_LEFT[0]    |P_LEFT[1]

                        |P_TOP[0]     |P_TOP[1]

                        |P_TOPRIGHT[0]|P_TOPRIGHT[1])==0){

            *mx_ptr= 0;

            *my_ptr= 0;

            s->me.skip=1;

            return dmin;

        }

        CHECK_MV(P_MEDIAN[0]>>shift, P_MEDIAN[1]>>shift)

        if(dmin>256*2){

            CHECK_CLIPED_MV((last_mv[ref_mv_xy][0]*ref_mv_scale + (1<<15))>>16,

                            (last_mv[ref_mv_xy][1]*ref_mv_scale + (1<<15))>>16)

            CHECK_MV(P_LEFT[0]    >>shift, P_LEFT[1]    >>shift)

            CHECK_MV(P_TOP[0]     >>shift, P_TOP[1]     >>shift)

            CHECK_MV(P_TOPRIGHT[0]>>shift, P_TOPRIGHT[1]>>shift)

        }

    }

    if(dmin>256*4){

        if(s->me.pre_pass){

            CHECK_CLIPED_MV((last_mv[ref_mv_xy-1][0]*ref_mv_scale + (1<<15))>>16,

                            (last_mv[ref_mv_xy-1][1]*ref_mv_scale + (1<<15))>>16)

            if(!s->first_slice_line)

                CHECK_CLIPED_MV((last_mv[ref_mv_xy-ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,

                                (last_mv[ref_mv_xy-ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)

        }else{

            CHECK_CLIPED_MV((last_mv[ref_mv_xy+1][0]*ref_mv_scale + (1<<15))>>16,

                            (last_mv[ref_mv_xy+1][1]*ref_mv_scale + (1<<15))>>16)

            if(s->end_mb_y == s->mb_height || s->mb_y+1<s->end_mb_y)  //FIXME replace at least with last_slice_line

                CHECK_CLIPED_MV((last_mv[ref_mv_xy+ref_mv_stride][0]*ref_mv_scale + (1<<15))>>16,

                                (last_mv[ref_mv_xy+ref_mv_stride][1]*ref_mv_scale + (1<<15))>>16)

        }

    }

    if(s->avctx->last_predictor_count){

        const int count= s->avctx->last_predictor_count;

        const int xstart= FFMAX(0, s->mb_x - count);

        const int ystart= FFMAX(0, s->mb_y - count);

        const int xend= FFMIN(s->mb_width , s->mb_x + count + 1);

        const int yend= FFMIN(s->mb_height, s->mb_y + count + 1);

        int mb_y;

        for(mb_y=ystart; mb_y<yend; mb_y++){

            int mb_x;

            for(mb_x=xstart; mb_x<xend; mb_x++){

                const int xy= mb_x + 1 + (mb_y + 1)*ref_mv_stride;

                int mx= (last_mv[xy][0]*ref_mv_scale + (1<<15))>>16;

                int my= (last_mv[xy][1]*ref_mv_scale + (1<<15))>>16;

                if(mx>xmax || mx<xmin || my>ymax || my<ymin) continue;

                CHECK_MV(mx,my)

            }

        }

    }

//check(best[0],best[1],0, b0)

    if(s->me.dia_size==-1)

        dmin= RENAME(funny_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,

                                   pred_x, pred_y, penalty_factor,

				   shift, map, map_generation, size, h, mv_penalty);

    else if(s->me.dia_size<-1)

        dmin= RENAME(sab_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,

                                   pred_x, pred_y, penalty_factor,

				   shift, map, map_generation, size, h, mv_penalty);

    else if(s->me.dia_size<2)

        dmin= RENAME(small_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,

                                   pred_x, pred_y, penalty_factor,

				   shift, map, map_generation, size, h, mv_penalty);

    else

        dmin= RENAME(var_diamond_search)(s, best, dmin, src_data, ref_data, stride, uvstride,

                                   pred_x, pred_y, penalty_factor,

				   shift, map, map_generation, size, h, mv_penalty);

//check(best[0],best[1],0, b1)

    *mx_ptr= best[0];

    *my_ptr= best[1];

//    printf("%d %d %d \n", best[0], best[1], dmin);

    return dmin;

}


static void megasas_complete_frame(MegasasState *s, uint64_t context)

{

    PCIDevice *pci_dev = PCI_DEVICE(s);

    int tail, queue_offset;

    /* Decrement busy count */

    s->busy--;

    if (s->reply_queue_pa) {

        /*

         * Put command on the reply queue.

         * Context is opaque, but emulation is running in

         * little endian. So convert it.

         */

        tail = s->reply_queue_head;

        if (megasas_use_queue64(s)) {

            queue_offset = tail * sizeof(uint64_t);

            stq_le_phys(&address_space_memory,

                        s->reply_queue_pa + queue_offset, context);

        } else {

            queue_offset = tail * sizeof(uint32_t);

            stl_le_phys(&address_space_memory,

                        s->reply_queue_pa + queue_offset, context);

        }

        s->reply_queue_head = megasas_next_index(s, tail, s->fw_cmds);

        s->reply_queue_tail = ldl_le_phys(&address_space_memory,

                                          s->consumer_pa);

        trace_megasas_qf_complete(context, s->reply_queue_head,

                                  s->reply_queue_tail, s->busy, s->doorbell);

    }

    if (megasas_intr_enabled(s)) {

        /* Notify HBA */

        s->doorbell++;

        if (s->doorbell == 1) {

            if (msix_enabled(pci_dev)) {

                trace_megasas_msix_raise(0);

                msix_notify(pci_dev, 0);

            } else if (msi_enabled(pci_dev)) {

                trace_megasas_msi_raise(0);

                msi_notify(pci_dev, 0);

            } else {

                trace_megasas_irq_raise();

                pci_irq_assert(pci_dev);

            }

        }

    } else {

        trace_megasas_qf_complete_noirq(context);

    }

}


static int decode_residual_block(AVSContext *h, GetBitContext *gb,

                                 const dec_2dvlc_t *r, int esc_golomb_order,

                                 int qp, uint8_t *dst, int stride) {

    int i, level_code, esc_code, level, run, mask;

    DCTELEM level_buf[64];

    uint8_t run_buf[64];

    DCTELEM *block = h->block;

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

        level_code = get_ue_code(gb,r->golomb_order);

        if(level_code >= ESCAPE_CODE) {

            run = ((level_code - ESCAPE_CODE) >> 1) + 1;

            esc_code = get_ue_code(gb,esc_golomb_order);

            level = esc_code + (run > r->max_run ? 1 : r->level_add[run]);

            while(level > r->inc_limit)

                r++;

            mask = -(level_code & 1);

            level = (level^mask) - mask;

        } else {

            level = r->rltab[level_code][0];

            if(!level) //end of block signal

                break;

            run   = r->rltab[level_code][1];

            r += r->rltab[level_code][2];

        }

        level_buf[i] = level;

        run_buf[i] = run;

    }

    if(dequant(h,level_buf, run_buf, block, ff_cavs_dequant_mul[qp],

               ff_cavs_dequant_shift[qp], i))

        return -1;

    h->s.dsp.cavs_idct8_add(dst,block,stride);

    return 0;

}


int ff_thread_decode_frame(AVCodecContext *avctx,

                           AVFrame *picture, int *got_picture_ptr,

                           AVPacket *avpkt)

{

    FrameThreadContext *fctx = avctx->internal->thread_ctx;

    int finished = fctx->next_finished;

    PerThreadContext *p;

    int err;

    /* release the async lock, permitting blocked hwaccel threads to

     * go forward while we are in this function */

    async_unlock(fctx);

    /*

     * Submit a packet to the next decoding thread.

     */

    p = &fctx->threads[fctx->next_decoding];

    err = update_context_from_user(p->avctx, avctx);

    if (err)

        goto finish;

    err = submit_packet(p, avpkt);

    if (err)

        goto finish;

    /*

     * If we're still receiving the initial packets, don't return a frame.

     */

    if (fctx->next_decoding > (avctx->thread_count-1-(avctx->codec_id == AV_CODEC_ID_FFV1)))

        fctx->delaying = 0;

    if (fctx->delaying) {

        *got_picture_ptr=0;

        if (avpkt->size) {

            err = avpkt->size;

            goto finish;

        }

    }

    /*

     * Return the next available frame from the oldest thread.

     * If we're at the end of the stream, then we have to skip threads that

     * didn't output a frame, because we don't want to accidentally signal

     * EOF (avpkt->size == 0 && *got_picture_ptr == 0).

     */

    do {

        p = &fctx->threads[finished++];

        if (atomic_load(&p->state) != STATE_INPUT_READY) {

            pthread_mutex_lock(&p->progress_mutex);

            while (atomic_load_explicit(&p->state, memory_order_relaxed) != STATE_INPUT_READY)

                pthread_cond_wait(&p->output_cond, &p->progress_mutex);

            pthread_mutex_unlock(&p->progress_mutex);

        }

        av_frame_move_ref(picture, p->frame);

        *got_picture_ptr = p->got_frame;

        picture->pkt_dts = p->avpkt.dts;

        if (p->result < 0)

            err = p->result;

        /*

         * A later call with avkpt->size == 0 may loop over all threads,

         * including this one, searching for a frame to return before being

         * stopped by the "finished != fctx->next_finished" condition.

         * Make sure we don't mistakenly return the same frame again.

         */

        p->got_frame = 0;

        if (finished >= avctx->thread_count) finished = 0;

    } while (!avpkt->size && !*got_picture_ptr && finished != fctx->next_finished);

    update_context_from_thread(avctx, p->avctx, 1);

    if (fctx->next_decoding >= avctx->thread_count) fctx->next_decoding = 0;

    fctx->next_finished = finished;

    /* return the size of the consumed packet if no error occurred */

    if (err >= 0)

        err = avpkt->size;

finish:

    async_lock(fctx);

    return err;

}


static void gen_tlbld_6xx(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

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

#endif

}