static void test_tco1_status_bits(void)

{

    TestData d;

    uint16_t ticks = 8;

    uint16_t val;

    int ret;

    d.args = NULL;

    d.noreboot = true;

    test_init(&d);

    stop_tco(&d);

    clear_tco_status(&d);

    reset_on_second_timeout(false);

    set_tco_timeout(&d, ticks);

    load_tco(&d);

    start_tco(&d);

    clock_step(ticks * TCO_TICK_NSEC);

    qpci_io_writeb(d.dev, d.tco_io_base + TCO_DAT_IN, 0);

    qpci_io_writeb(d.dev, d.tco_io_base + TCO_DAT_OUT, 0);

    val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS);

    ret = val & (TCO_TIMEOUT | SW_TCO_SMI | TCO_INT_STS) ? 1 : 0;

    g_assert(ret == 1);

    qpci_io_writew(d.dev, d.tco_io_base + TCO1_STS, val);

    g_assert_cmpint(qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS), ==, 0);

    qtest_end();

}


block_crypto_create_opts_init(QCryptoBlockFormat format,

                              QemuOpts *opts,

                              Error **errp)

{

    OptsVisitor *ov;

    QCryptoBlockCreateOptions *ret = NULL;

    Error *local_err = NULL;

    ret = g_new0(QCryptoBlockCreateOptions, 1);

    ret->format = format;

    ov = opts_visitor_new(opts);

    visit_start_struct(opts_get_visitor(ov),

                       NULL, NULL, 0, &local_err);

    if (local_err) {

        goto out;

    }

    switch (format) {

    case Q_CRYPTO_BLOCK_FORMAT_LUKS:

        visit_type_QCryptoBlockCreateOptionsLUKS_members(

            opts_get_visitor(ov), &ret->u.luks, &local_err);

        break;

    default:

        error_setg(&local_err, "Unsupported block format %d", format);

        break;

    }

    error_propagate(errp, local_err);

    local_err = NULL;

    visit_end_struct(opts_get_visitor(ov), &local_err);

 out:

    if (local_err) {

        error_propagate(errp, local_err);

        qapi_free_QCryptoBlockCreateOptions(ret);

        ret = NULL;

    }

    opts_visitor_cleanup(ov);

    return ret;

}


static void RENAME(yuv2yuvX)(SwsContext *c, const int16_t *lumFilter,

                             const int16_t **lumSrc, int lumFilterSize,

                             const int16_t *chrFilter, const int16_t **chrUSrc,

                             const int16_t **chrVSrc,

                             int chrFilterSize, const int16_t **alpSrc,

                             uint8_t *dest, uint8_t *uDest, uint8_t *vDest,

                             uint8_t *aDest, int dstW, int chrDstW)

{

    if (uDest) {

        x86_reg uv_off = c->uv_off;

        YSCALEYUV2YV12X(CHR_MMX_FILTER_OFFSET, uDest, chrDstW, 0)

        YSCALEYUV2YV12X(CHR_MMX_FILTER_OFFSET, vDest - uv_off, chrDstW + uv_off, uv_off)

    }

    if (CONFIG_SWSCALE_ALPHA && aDest) {

        YSCALEYUV2YV12X(ALP_MMX_FILTER_OFFSET, aDest, dstW, 0)

    }

    YSCALEYUV2YV12X(LUM_MMX_FILTER_OFFSET, dest, dstW, 0)

}


static void add_cpreg_to_list(gpointer key, gpointer opaque)

{

    ARMCPU *cpu = opaque;

    uint64_t regidx;

    const ARMCPRegInfo *ri;

    regidx = *(uint32_t *)key;

    ri = get_arm_cp_reginfo(cpu->cp_regs, regidx);

    if (!(ri->type & ARM_CP_NO_MIGRATE)) {

        cpu->cpreg_indexes[cpu->cpreg_array_len] = cpreg_to_kvm_id(regidx);

        /* The value array need not be initialized at this point */

        cpu->cpreg_array_len++;

    }

}


static int xan_huffman_decode(unsigned char *dest, unsigned char *src)

{

    unsigned char byte = *src++;

    unsigned char ival = byte + 0x16;

    unsigned char * ptr = src + byte*2;

    unsigned char val = ival;

    int counter = 0;

    unsigned char bits = *ptr++;

    while ( val != 0x16 ) {

        if ( (1 << counter) & bits )

            val = src[byte + val - 0x17];

        else

            val = src[val - 0x17];

        if ( val < 0x16 ) {

            *dest++ = val;

            val = ival;

        }

        if (counter++ == 7) {

            counter = 0;

            bits = *ptr++;

        }

    }

    return 0;

}


static inline int alarm_has_dynticks(struct qemu_alarm_timer *t)

{

    return t && t->rearm;

}


static int iff_read_header(AVFormatContext *s)

{

    IffDemuxContext *iff = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st;

    uint8_t *buf;

    uint32_t chunk_id, data_size;

    uint32_t screenmode = 0, num, den;

    unsigned transparency = 0;

    unsigned masking = 0; // no mask

    uint8_t fmt[16];

    int fmt_size;

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codec->channels = 1;

    st->codec->channel_layout = AV_CH_LAYOUT_MONO;

    avio_skip(pb, 8);

    // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content

    st->codec->codec_tag = avio_rl32(pb);

    iff->bitmap_compression = -1;

    iff->svx8_compression = -1;

    iff->maud_bits = -1;

    iff->maud_compression = -1;

    while(!url_feof(pb)) {

        uint64_t orig_pos;

        int res;

        const char *metadata_tag = NULL;

        chunk_id = avio_rl32(pb);

        data_size = avio_rb32(pb);

        orig_pos = avio_tell(pb);

        switch(chunk_id) {

        case ID_VHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            if (data_size < 14)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 12);

            st->codec->sample_rate = avio_rb16(pb);

            if (data_size >= 16) {

                avio_skip(pb, 1);

                iff->svx8_compression = avio_r8(pb);

            }

            break;

        case ID_MHDR:

            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;

            if (data_size < 32)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 4);

            iff->maud_bits = avio_rb16(pb);

            avio_skip(pb, 2);

            num = avio_rb32(pb);

            den = avio_rb16(pb);

            if (!den)

                return AVERROR_INVALIDDATA;

            avio_skip(pb, 2);

            st->codec->sample_rate = num / den;

            st->codec->channels = avio_rb16(pb);

            iff->maud_compression = avio_rb16(pb);

            if (st->codec->channels == 1)

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            else if (st->codec->channels == 2)

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            break;

        case ID_ABIT:

        case ID_BODY:

        case ID_DBOD:

        case ID_MDAT:

            iff->body_pos = avio_tell(pb);

            iff->body_end = iff->body_pos + data_size;

            iff->body_size = data_size;

            break;

        case ID_CHAN:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            if (avio_rb32(pb) < 6) {

                st->codec->channels       = 1;

                st->codec->channel_layout = AV_CH_LAYOUT_MONO;

            } else {

                st->codec->channels       = 2;

                st->codec->channel_layout = AV_CH_LAYOUT_STEREO;

            }

            break;

        case ID_CAMG:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            screenmode                = avio_rb32(pb);

            break;

        case ID_CMAP:

            if (data_size > INT_MAX - IFF_EXTRA_VIDEO_SIZE - FF_INPUT_BUFFER_PADDING_SIZE)

                return AVERROR_INVALIDDATA;

            st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

            if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0)

                return AVERROR(EIO);

            break;

        case ID_BMHD:

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size <= 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            avio_skip(pb, 4); // x, y offset

            st->codec->bits_per_coded_sample = avio_r8(pb);

            if (data_size >= 10)

                masking                      = avio_r8(pb);

            if (data_size >= 11)

                iff->bitmap_compression      = avio_r8(pb);

            if (data_size >= 14) {

                avio_skip(pb, 1); // padding

                transparency                 = avio_rb16(pb);

            }

            if (data_size >= 16) {

                st->sample_aspect_ratio.num  = avio_r8(pb);

                st->sample_aspect_ratio.den  = avio_r8(pb);

            }

            break;

        case ID_DPEL:

            if (data_size < 4 || (data_size & 3))

                return AVERROR_INVALIDDATA;

            if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0)

                return fmt_size;

            if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24)))

                st->codec->pix_fmt = AV_PIX_FMT_RGB24;

            else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba)))

                st->codec->pix_fmt = AV_PIX_FMT_RGBA;

            else if (fmt_size == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra)))

                st->codec->pix_fmt = AV_PIX_FMT_BGRA;

            else if (fmt_size == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb)))

                st->codec->pix_fmt = AV_PIX_FMT_ARGB;

            else if (fmt_size == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr)))

                st->codec->pix_fmt = AV_PIX_FMT_ABGR;

            else {

                av_log_ask_for_sample(s, "unsupported color format\n");

                return AVERROR_PATCHWELCOME;

            }

            break;

        case ID_DGBL:

            st->codec->codec_type            = AVMEDIA_TYPE_VIDEO;

            if (data_size < 8)

                return AVERROR_INVALIDDATA;

            st->codec->width                 = avio_rb16(pb);

            st->codec->height                = avio_rb16(pb);

            iff->bitmap_compression          = avio_rb16(pb);

            st->sample_aspect_ratio.num      = avio_r8(pb);

            st->sample_aspect_ratio.den      = avio_r8(pb);

            st->codec->bits_per_coded_sample = 24;

            break;

        case ID_DLOC:

            if (data_size < 4)

                return AVERROR_INVALIDDATA;

            st->codec->width  = avio_rb16(pb);

            st->codec->height = avio_rb16(pb);

            break;

        case ID_TVDC:

            if (data_size < sizeof(iff->tvdc))

                return AVERROR_INVALIDDATA;

            res = avio_read(pb, iff->tvdc, sizeof(iff->tvdc));

            if (res < 0)

                return res;

            break;

        case ID_ANNO:

        case ID_TEXT:      metadata_tag = "comment";   break;

        case ID_AUTH:      metadata_tag = "artist";    break;

        case ID_COPYRIGHT: metadata_tag = "copyright"; break;

        case ID_NAME:      metadata_tag = "title";     break;

        }

        if (metadata_tag) {

            if ((res = get_metadata(s, metadata_tag, data_size)) < 0) {

                av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag);

                return res;

            }

        }

        avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1));

    }

    avio_seek(pb, iff->body_pos, SEEK_SET);

    switch(st->codec->codec_type) {

    case AVMEDIA_TYPE_AUDIO:

        avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate);

        if (st->codec->codec_tag == ID_16SV)

            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR;

        else if (st->codec->codec_tag == ID_MAUD) {

            if (iff->maud_bits == 8 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_U8;

            } else if (iff->maud_bits == 16 && !iff->maud_compression) {

                st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 2) {

                st->codec->codec_id = AV_CODEC_ID_PCM_ALAW;

            } else if (iff->maud_bits ==  8 && iff->maud_compression == 3) {

                st->codec->codec_id = AV_CODEC_ID_PCM_MULAW;

            } else {

                av_log_ask_for_sample(s, "unsupported compression %d and bit depth %d\n", iff->maud_compression, iff->maud_bits);

                return AVERROR_PATCHWELCOME;

            }

            st->codec->bits_per_coded_sample =

                av_get_bits_per_sample(st->codec->codec_id);

            st->codec->block_align =

                st->codec->bits_per_coded_sample * st->codec->channels / 8;

        } else {

        switch (iff->svx8_compression) {

        case COMP_NONE:

            st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR;

            break;

        case COMP_FIB:

            st->codec->codec_id = AV_CODEC_ID_8SVX_FIB;

            break;

        case COMP_EXP:

            st->codec->codec_id = AV_CODEC_ID_8SVX_EXP;

            break;

        default:

            av_log(s, AV_LOG_ERROR,

                   "Unknown SVX8 compression method '%d'\n", iff->svx8_compression);

            return -1;

        }

        }

        st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id);

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

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

        break;

    case AVMEDIA_TYPE_VIDEO:

        iff->bpp          = st->codec->bits_per_coded_sample;

        if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) {

            iff->ham      = iff->bpp > 6 ? 6 : 4;

            st->codec->bits_per_coded_sample = 24;

        }

        iff->flags        = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8;

        iff->masking      = masking;

        iff->transparency = transparency;

        if (!st->codec->extradata) {

            st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE;

            st->codec->extradata      = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);

            if (!st->codec->extradata)

                return AVERROR(ENOMEM);

        }

        buf = st->codec->extradata;

        bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE);

        bytestream_put_byte(&buf, iff->bitmap_compression);

        bytestream_put_byte(&buf, iff->bpp);

        bytestream_put_byte(&buf, iff->ham);

        bytestream_put_byte(&buf, iff->flags);

        bytestream_put_be16(&buf, iff->transparency);

        bytestream_put_byte(&buf, iff->masking);

        bytestream_put_buffer(&buf, iff->tvdc, sizeof(iff->tvdc));

        st->codec->codec_id = AV_CODEC_ID_IFF_ILBM;

        break;

    default:

        return -1;

    }

    return 0;

}


static int ftp_status(FTPContext *s, char **line, const int response_codes[])

{

    int err, i, dash = 0, result = 0, code_found = 0;

    char buf[CONTROL_BUFFER_SIZE];

    AVBPrint line_buffer;

    if (line)

        av_bprint_init(&line_buffer, 0, AV_BPRINT_SIZE_AUTOMATIC);

    while (!code_found || dash) {

        if ((err = ftp_get_line(s, buf, sizeof(buf))) < 0) {

            av_bprint_finalize(&line_buffer, NULL);

            return err;

        }

        av_log(s, AV_LOG_DEBUG, "%s\n", buf);

        if (strlen(buf) < 4)

            continue;

        err = 0;

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

            if (buf[i] < '0' || buf[i] > '9')

                continue;

            err *= 10;

            err += buf[i] - '0';

        }

        dash = !!(buf[3] == '-');

        for (i = 0; response_codes[i]; ++i) {

            if (err == response_codes[i]) {

                if (line)

                    av_bprintf(&line_buffer, "%s", buf);

                code_found = 1;

                result = err;

                break;

            }

        }

    }

    if (line)

        av_bprint_finalize(&line_buffer, line);

    return result;

}


static uint32_t arm_sysctl_read(void *opaque, target_phys_addr_t offset)

{

    arm_sysctl_state *s = (arm_sysctl_state *)opaque;

    switch (offset) {

    case 0x00: /* ID */

        return s->sys_id;

    case 0x04: /* SW */

        /* General purpose hardware switches.

           We don't have a useful way of exposing these to the user.  */

        return 0;

    case 0x08: /* LED */

        return s->leds;

    case 0x20: /* LOCK */

        return s->lockval;

    case 0x0c: /* OSC0 */

    case 0x10: /* OSC1 */

    case 0x14: /* OSC2 */

    case 0x18: /* OSC3 */

    case 0x1c: /* OSC4 */

    case 0x24: /* 100HZ */

        /* ??? Implement these.  */

        return 0;

    case 0x28: /* CFGDATA1 */

        return s->cfgdata1;

    case 0x2c: /* CFGDATA2 */

        return s->cfgdata2;

    case 0x30: /* FLAGS */

        return s->flags;

    case 0x38: /* NVFLAGS */

        return s->nvflags;

    case 0x40: /* RESETCTL */

        return s->resetlevel;

    case 0x44: /* PCICTL */

        return 1;

    case 0x48: /* MCI */

        return 0;

    case 0x4c: /* FLASH */

        return 0;

    case 0x50: /* CLCD */

        return 0x1000;

    case 0x54: /* CLCDSER */

        return 0;

    case 0x58: /* BOOTCS */

        return 0;

    case 0x5c: /* 24MHz */

        return muldiv64(qemu_get_clock(vm_clock), 24000000, get_ticks_per_sec());

    case 0x60: /* MISC */

        return 0;

    case 0x84: /* PROCID0 */

        /* ??? Don't know what the proper value for the core tile ID is.  */

        return 0x02000000;

    case 0x88: /* PROCID1 */

        return 0xff000000;

    case 0x64: /* DMAPSR0 */

    case 0x68: /* DMAPSR1 */

    case 0x6c: /* DMAPSR2 */

    case 0x70: /* IOSEL */

    case 0x74: /* PLDCTL */

    case 0x80: /* BUSID */

    case 0x8c: /* OSCRESET0 */

    case 0x90: /* OSCRESET1 */

    case 0x94: /* OSCRESET2 */

    case 0x98: /* OSCRESET3 */

    case 0x9c: /* OSCRESET4 */

    case 0xc0: /* SYS_TEST_OSC0 */

    case 0xc4: /* SYS_TEST_OSC1 */

    case 0xc8: /* SYS_TEST_OSC2 */

    case 0xcc: /* SYS_TEST_OSC3 */

    case 0xd0: /* SYS_TEST_OSC4 */

        return 0;

    default:

        printf ("arm_sysctl_read: Bad register offset 0x%x\n", (int)offset);

        return 0;

    }

}


void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)

{

    struct qemu_work_item wi;

    if (qemu_cpu_is_self(cpu)) {

        func(data);

        return;

    }

    wi.func = func;

    wi.data = data;

    wi.free = false;

    if (cpu->queued_work_first == NULL) {

        cpu->queued_work_first = &wi;

    } else {

        cpu->queued_work_last->next = &wi;

    }

    cpu->queued_work_last = &wi;

    wi.next = NULL;

    wi.done = false;

    qemu_cpu_kick(cpu);

    while (!wi.done) {

        CPUState *self_cpu = current_cpu;

        qemu_cond_wait(&qemu_work_cond, &qemu_global_mutex);

        current_cpu = self_cpu;

    }

}


double avpriv_strtod(char *restrict nptr, char **restrict endptr)

{

    char *end;

    double res;

    /* Skip leading spaces */

    while (isspace(*nptr))

        nptr++;

    if (!av_strncasecmp(nptr, "infinity", 8)) {

        end = nptr + 8;

        res = INFINITY;

    } else if (!av_strncasecmp(nptr, "inf", 3)) {

        end = nptr + 3;

        res = INFINITY;

    } else if (!av_strncasecmp(nptr, "+infinity", 9)) {

        end = nptr + 9;

        res = INFINITY;

    } else if (!av_strncasecmp(nptr, "+inf", 4)) {

        end = nptr + 4;

        res = INFINITY;

    } else if (!av_strncasecmp(nptr, "-infinity", 9)) {

        end = nptr + 9;

        res = -INFINITY;

    } else if (!av_strncasecmp(nptr, "-inf", 4)) {

        end = nptr + 4;

        res = -INFINITY;

    } else if (!av_strncasecmp(nptr, "nan", 3)) {

        end = check_nan_suffix(nptr + 3);

        res = NAN;

    } else if (!av_strncasecmp(nptr, "+nan", 4) ||

               !av_strncasecmp(nptr, "-nan", 4)) {

        end = check_nan_suffix(nptr + 4);

        res = NAN;

    } else if (!av_strncasecmp(nptr, "0x", 2) ||

               !av_strncasecmp(nptr, "-0x", 3) ||

               !av_strncasecmp(nptr, "+0x", 3)) {

        /* FIXME this doesn't handle exponents, non-integers (float/double)

         * and numbers too large for long long */

        res = strtoll(nptr, &end, 16);

    } else {

        res = strtod(nptr, &end);

    }

    if (endptr)

        *endptr = end;

    return res;

}


static void update_video_pts(VideoState *is, double pts, int64_t pos, int serial) {

    double time = av_gettime() / 1000000.0;

    /* update current video pts */

    is->video_current_pts = pts;

    is->video_current_pts_drift = is->video_current_pts - time;

    is->video_current_pos = pos;

    is->frame_last_pts = pts;

    check_external_clock_sync(is, is->video_current_pts);

}


open_f(int argc, char **argv)

{

	int flags = 0;

	int readonly = 0;

	int growable = 0;

	int c;

	while ((c = getopt(argc, argv, "snrg")) != EOF) {

		switch (c) {

		case 's':

			flags |= BDRV_O_SNAPSHOT;

			break;

		case 'n':

			flags |= BDRV_O_NOCACHE;

			break;

		case 'r':

			readonly = 1;

			break;

		case 'g':

			growable = 1;

			break;

		default:

			return command_usage(&open_cmd);

		}

	}

	if (!readonly) {

            flags |= BDRV_O_RDWR;

        }

	if (optind != argc - 1)

		return command_usage(&open_cmd);

	return openfile(argv[optind], flags, growable);

}


static unsigned int event_status_media(IDEState *s,

                                       uint8_t *buf)

{

    uint8_t event_code, media_status;

    media_status = 0;

    if (s->tray_open) {

        media_status = MS_TRAY_OPEN;

    } else if (bdrv_is_inserted(s->bs)) {

        media_status = MS_MEDIA_PRESENT;

    }

    /* Event notification descriptor */

    event_code = MEC_NO_CHANGE;

    if (media_status != MS_TRAY_OPEN) {

        if (s->events.new_media) {

            event_code = MEC_NEW_MEDIA;

            s->events.new_media = false;

        } else if (s->events.eject_request) {

            event_code = MEC_EJECT_REQUESTED;

            s->events.eject_request = false;

        }

    }

    buf[4] = event_code;

    buf[5] = media_status;

    /* These fields are reserved, just clear them. */

    buf[6] = 0;

    buf[7] = 0;

    return 8; /* We wrote to 4 extra bytes from the header */

}


static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev,

                                  Error **errp)

{

    VirtIODevice *vdev = VIRTIO_DEVICE(hotplug_dev);

    VirtIOSCSI *s = VIRTIO_SCSI(vdev);

    SCSIDevice *sd = SCSI_DEVICE(dev);

    if ((vdev->guest_features >> VIRTIO_SCSI_F_HOTPLUG) & 1) {

        virtio_scsi_push_event(s, sd,

                               VIRTIO_SCSI_T_TRANSPORT_RESET,

                               VIRTIO_SCSI_EVT_RESET_REMOVED);

    }

    if (s->ctx) {

        blk_op_unblock_all(sd->conf.blk, s->blocker);

    }

    qdev_simple_device_unplug_cb(hotplug_dev, dev, errp);

}


int qio_channel_socket_connect_sync(QIOChannelSocket *ioc,

                                    SocketAddress *addr,

                                    Error **errp)

{

    int fd;

    trace_qio_channel_socket_connect_sync(ioc, addr);

    fd = socket_connect(addr, NULL, NULL, errp);

    if (fd < 0) {

        trace_qio_channel_socket_connect_fail(ioc);

        return -1;

    }

    trace_qio_channel_socket_connect_complete(ioc, fd);

    if (qio_channel_socket_set_fd(ioc, fd, errp) < 0) {

        close(fd);

        return -1;

    }

    return 0;

}


static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
                      int append)
{
    int buflen;
    /** when the frame data does not need to be concatenated, the input buffer
        is resetted and additional bits from the previous frame are copyed
        and skipped later so that a fast byte copy is possible */
    if (!append) {
        s->frame_offset = get_bits_count(gb) & 7;
        s->num_saved_bits = s->frame_offset;
        init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE);
    buflen = (s->num_saved_bits + len + 8) >> 3;
    if (len <= 0 || buflen > MAX_FRAMESIZE) {
        avpriv_request_sample(s->avctx, "Too small input buffer");
    s->num_saved_bits += len;
    if (!append) {
        avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3),
                     s->num_saved_bits);
    } else {
        int align = 8 - (get_bits_count(gb) & 7);
        align = FFMIN(align, len);
        put_bits(&s->pb, align, get_bits(gb, align));
        len -= align;
        avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len);
    skip_bits_long(gb, len);
    {
        PutBitContext tmp = s->pb;
        flush_put_bits(&tmp);
    init_get_bits(&s->gb, s->frame_data, s->num_saved_bits);
    skip_bits(&s->gb, s->frame_offset);


static int read_interval_packets(WriterContext *w, AVFormatContext *fmt_ctx,

                                 const ReadInterval *interval, int64_t *cur_ts)

{

    AVPacket pkt, pkt1;

    AVFrame *frame = NULL;

    int ret = 0, i = 0, frame_count = 0;

    int64_t start = -INT64_MAX, end = interval->end;

    int has_start = 0, has_end = interval->has_end && !interval->end_is_offset;

    av_init_packet(&pkt);

    av_log(NULL, AV_LOG_VERBOSE, "Processing read interval ");

    log_read_interval(interval, NULL, AV_LOG_VERBOSE);

    if (interval->has_start) {

        int64_t target;

        if (interval->start_is_offset) {

            if (*cur_ts == AV_NOPTS_VALUE) {

                av_log(NULL, AV_LOG_ERROR,

                       "Could not seek to relative position since current "

                       "timestamp is not defined\n");

                ret = AVERROR(EINVAL);

            target = *cur_ts + interval->start;

        } else {

            target = interval->start;

        av_log(NULL, AV_LOG_VERBOSE, "Seeking to read interval start point %s\n",

               av_ts2timestr(target, &AV_TIME_BASE_Q));

        if ((ret = avformat_seek_file(fmt_ctx, -1, -INT64_MAX, target, INT64_MAX, 0)) < 0) {

            av_log(NULL, AV_LOG_ERROR, "Could not seek to position %"PRId64": %s\n",

                   interval->start, av_err2str(ret));

    frame = av_frame_alloc();

    while (!av_read_frame(fmt_ctx, &pkt)) {

        if (selected_streams[pkt.stream_index]) {

            AVRational tb = fmt_ctx->streams[pkt.stream_index]->time_base;

            if (pkt.pts != AV_NOPTS_VALUE)

                *cur_ts = av_rescale_q(pkt.pts, tb, AV_TIME_BASE_Q);

            if (!has_start && *cur_ts != AV_NOPTS_VALUE) {

                start = *cur_ts;

                has_start = 1;

            if (has_start && !has_end && interval->end_is_offset) {

                end = start + interval->end;

                has_end = 1;

            if (interval->end_is_offset && interval->duration_frames) {

                if (frame_count >= interval->end)

                    break;

            } else if (has_end && *cur_ts != AV_NOPTS_VALUE && *cur_ts >= end) {

                break;

            frame_count++;

            if (do_read_packets) {

                if (do_show_packets)

                    show_packet(w, fmt_ctx, &pkt, i++);

                nb_streams_packets[pkt.stream_index]++;

            if (do_read_frames) {

                pkt1 = pkt;

                while (pkt1.size && process_frame(w, fmt_ctx, frame, &pkt1) > 0);

        av_free_packet(&pkt);

    av_init_packet(&pkt);

    pkt.data = NULL;

    pkt.size = 0;

    //Flush remaining frames that are cached in the decoder

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

        pkt.stream_index = i;

        if (do_read_frames)

            while (process_frame(w, fmt_ctx, frame, &pkt) > 0);

end:

    av_frame_free(&frame);

    if (ret < 0) {

        av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval ");

        log_read_interval(interval, NULL, AV_LOG_ERROR);

    return ret;


int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx,
                                             uint8_t *buf, int buf_size,
                                             const short *samples)
{
    AVPacket pkt;
    AVFrame *frame;
    int ret, samples_size, got_packet;
    av_init_packet(&pkt);
    pkt.data = buf;
    pkt.size = buf_size;
    if (samples) {
        frame = av_frame_alloc();
        if (!frame)
            return AVERROR(ENOMEM);
        if (avctx->frame_size) {
            frame->nb_samples = avctx->frame_size;
        } else {
            /* if frame_size is not set, the number of samples must be
             * calculated from the buffer size */
            int64_t nb_samples;
            if (!av_get_bits_per_sample(avctx->codec_id)) {
                av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not "
                                            "support this codec\n");
                av_frame_free(&frame);
                return AVERROR(EINVAL);
            }
            nb_samples = (int64_t)buf_size * 8 /
                         (av_get_bits_per_sample(avctx->codec_id) *
                          avctx->channels);
            if (nb_samples >= INT_MAX) {
                av_frame_free(&frame);
                return AVERROR(EINVAL);
            }
            frame->nb_samples = nb_samples;
        }
        /* it is assumed that the samples buffer is large enough based on the
         * relevant parameters */
        samples_size = av_samples_get_buffer_size(NULL, avctx->channels,
                                                  frame->nb_samples,
                                                  avctx->sample_fmt, 1);
        if ((ret = avcodec_fill_audio_frame(frame, avctx->channels,
                                            avctx->sample_fmt,
                                            (const uint8_t *)samples,
                                            samples_size, 1)) < 0) {
            av_frame_free(&frame);
            return ret;
        }
        /* fabricate frame pts from sample count.
         * this is needed because the avcodec_encode_audio() API does not have
         * a way for the user to provide pts */
        if (avctx->sample_rate && avctx->time_base.num)
            frame->pts = ff_samples_to_time_base(avctx,
                                                 avctx->internal->sample_count);
        else
            frame->pts = AV_NOPTS_VALUE;
        avctx->internal->sample_count += frame->nb_samples;
    } else {
        frame = NULL;
    }
    got_packet = 0;
    ret = avcodec_encode_audio2(avctx, &pkt, frame, &got_packet);
    if (!ret && got_packet && avctx->coded_frame) {
        avctx->coded_frame->pts       = pkt.pts;
        avctx->coded_frame->key_frame = !!(pkt.flags & AV_PKT_FLAG_KEY);
    }
    /* free any side data since we cannot return it */
    av_packet_free_side_data(&pkt);
    if (frame && frame->extended_data != frame->data)
        av_freep(&frame->extended_data);
    av_frame_free(&frame);
    return ret ? ret : pkt.size;
}


static void host_cpuid(uint32_t function, uint32_t count,

                       uint32_t *eax, uint32_t *ebx,

                       uint32_t *ecx, uint32_t *edx)

{

#if defined(CONFIG_KVM)

    uint32_t vec[4];

#ifdef __x86_64__

    asm volatile("cpuid"

                 : "=a"(vec[0]), "=b"(vec[1]),

                   "=c"(vec[2]), "=d"(vec[3])

                 : "0"(function), "c"(count) : "cc");

#else

    asm volatile("pusha \n\t"

                 "cpuid \n\t"

                 "mov %%eax, 0(%1) \n\t"

                 "mov %%ebx, 4(%1) \n\t"

                 "mov %%ecx, 8(%1) \n\t"

                 "mov %%edx, 12(%1) \n\t"

                 "popa"

                 : : "a"(function), "c"(count), "S"(vec)

                 : "memory", "cc");

#endif

    if (eax)

	*eax = vec[0];

    if (ebx)

	*ebx = vec[1];

    if (ecx)

	*ecx = vec[2];

    if (edx)

	*edx = vec[3];

#endif

}


static int dxva2_map_frame(AVHWFramesContext *ctx, AVFrame *dst, const AVFrame *src,

                           int flags)

{

    IDirect3DSurface9 *surface = (IDirect3DSurface9*)src->data[3];

    DXVA2Mapping      *map;

    D3DSURFACE_DESC    surfaceDesc;

    D3DLOCKED_RECT     LockedRect;

    HRESULT            hr;

    int i, err, nb_planes;

    int lock_flags = 0;

    nb_planes = av_pix_fmt_count_planes(dst->format);

    hr = IDirect3DSurface9_GetDesc(surface, &surfaceDesc);

    if (FAILED(hr)) {

        av_log(ctx, AV_LOG_ERROR, "Error getting a surface description\n");

        return AVERROR_UNKNOWN;

    }

    if (!(flags & AV_HWFRAME_MAP_WRITE))

        lock_flags |= D3DLOCK_READONLY;

    if (flags & AV_HWFRAME_MAP_OVERWRITE)

        lock_flags |= D3DLOCK_DISCARD;

    hr = IDirect3DSurface9_LockRect(surface, &LockedRect, NULL, lock_flags);

    if (FAILED(hr)) {

        av_log(ctx, AV_LOG_ERROR, "Unable to lock DXVA2 surface\n");

        return AVERROR_UNKNOWN;

    }

    map = av_mallocz(sizeof(*map));

    if (!map)

        goto fail;

    err = ff_hwframe_map_create(src->hw_frames_ctx, dst, src,

                                dxva2_unmap_frame, map);

    if (err < 0) {

        av_freep(&map);

        goto fail;

    }

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

        dst->linesize[i] = LockedRect.Pitch;

    av_image_fill_pointers(dst->data, dst->format, surfaceDesc.Height,

                           (uint8_t*)LockedRect.pBits, dst->linesize);

    if (dst->format == AV_PIX_FMT_PAL8)

        dst->data[1] = (uint8_t*)map->palette_dummy;

    return 0;

fail:

    IDirect3DSurface9_UnlockRect(surface);

    return err;

}


void show_help(void)

{

    const char *prog;

    const OptionDef *po;

    int i, expert;

    prog = do_play ? "ffplay" : "ffmpeg";

    printf("%s version " FFMPEG_VERSION ", Copyright (c) 2000, 2001, 2002 Gerard Lantau\n",

           prog);

    if (!do_play) {

        printf("usage: ffmpeg [[options] -i input_file]... {[options] outfile}...\n"

               "Hyper fast MPEG1/MPEG4/H263/RV and AC3/MPEG audio encoder\n");

    } else {

        printf("usage: ffplay [options] input_file...\n"

               "Simple audio player\n");

    }

    printf("\n"

           "Main options are:\n");

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

        if (i == 1)

            printf("\nAdvanced options are:\n");

        for(po = options; po->name != NULL; po++) {

            char buf[64];

            expert = (po->flags & OPT_EXPERT) != 0;

            if (expert == i) {

                strcpy(buf, po->name);

                if (po->flags & HAS_ARG) {

                    strcat(buf, " ");

                    strcat(buf, po->argname);

                }

                printf("-%-17s  %s\n", buf, po->help);

            }

        }

    }

    exit(1);

}


av_cold int ffv1_common_init(AVCodecContext *avctx)

{

    FFV1Context *s = avctx->priv_data;

    if (!avctx->width || !avctx->height)

        return AVERROR_INVALIDDATA;

    s->avctx = avctx;

    s->flags = avctx->flags;

    s->picture.f = avcodec_alloc_frame();

    s->last_picture.f = av_frame_alloc();

    ff_dsputil_init(&s->dsp, avctx);

    s->width  = avctx->width;

    s->height = avctx->height;

    // defaults

    s->num_h_slices = 1;

    s->num_v_slices = 1;

    return 0;

}


static int vqa_decode_chunk(VqaContext *s)

{

    unsigned int chunk_type;

    unsigned int chunk_size;

    int byte_skip;

    unsigned int index = 0;

    int i;

    unsigned char r, g, b;

    int index_shift;

    int res;

    int cbf0_chunk = -1;

    int cbfz_chunk = -1;

    int cbp0_chunk = -1;

    int cbpz_chunk = -1;

    int cpl0_chunk = -1;

    int cplz_chunk = -1;

    int vptz_chunk = -1;

    int x, y;

    int lines = 0;

    int pixel_ptr;

    int vector_index = 0;

    int lobyte = 0;

    int hibyte = 0;

    int lobytes = 0;

    int hibytes = s->decode_buffer_size / 2;

    /* first, traverse through the frame and find the subchunks */

    while (bytestream2_get_bytes_left(&s->gb) >= 8) {

        chunk_type = bytestream2_get_be32u(&s->gb);

        index      = bytestream2_tell(&s->gb);

        chunk_size = bytestream2_get_be32u(&s->gb);

        switch (chunk_type) {

        case CBF0_TAG:

            cbf0_chunk = index;

            break;

        case CBFZ_TAG:

            cbfz_chunk = index;

            break;

        case CBP0_TAG:

            cbp0_chunk = index;

            break;

        case CBPZ_TAG:

            cbpz_chunk = index;

            break;

        case CPL0_TAG:

            cpl0_chunk = index;

            break;

        case CPLZ_TAG:

            cplz_chunk = index;

            break;

        case VPTZ_TAG:

            vptz_chunk = index;

            break;

        default:

            av_log(s->avctx, AV_LOG_ERROR, "  VQA video: Found unknown chunk type: %c%c%c%c (%08X)\n",

            (chunk_type >> 24) & 0xFF,

            (chunk_type >> 16) & 0xFF,

            (chunk_type >>  8) & 0xFF,

            (chunk_type >>  0) & 0xFF,

            chunk_type);

            break;

        }

        byte_skip = chunk_size & 0x01;

        bytestream2_skip(&s->gb, chunk_size + byte_skip);

    }

    /* next, deal with the palette */

    if ((cpl0_chunk != -1) && (cplz_chunk != -1)) {

        /* a chunk should not have both chunk types */

        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found both CPL0 and CPLZ chunks\n");

        return AVERROR_INVALIDDATA;

    }

    /* decompress the palette chunk */

    if (cplz_chunk != -1) {

/* yet to be handled */

    }

    /* convert the RGB palette into the machine's endian format */

    if (cpl0_chunk != -1) {

        bytestream2_seek(&s->gb, cpl0_chunk, SEEK_SET);

        chunk_size = bytestream2_get_be32(&s->gb);

        /* sanity check the palette size */

        if (chunk_size / 3 > 256 || chunk_size > bytestream2_get_bytes_left(&s->gb)) {

            av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found a palette chunk with %d colors\n",

                chunk_size / 3);

            return AVERROR_INVALIDDATA;

        }

        for (i = 0; i < chunk_size / 3; i++) {

            /* scale by 4 to transform 6-bit palette -> 8-bit */

            r = bytestream2_get_byteu(&s->gb) * 4;

            g = bytestream2_get_byteu(&s->gb) * 4;

            b = bytestream2_get_byteu(&s->gb) * 4;

            s->palette[i] = (r << 16) | (g << 8) | (b);

        }

    }

    /* next, look for a full codebook */

    if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) {

        /* a chunk should not have both chunk types */

        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found both CBF0 and CBFZ chunks\n");

        return AVERROR_INVALIDDATA;

    }

    /* decompress the full codebook chunk */

    if (cbfz_chunk != -1) {

        bytestream2_seek(&s->gb, cbfz_chunk, SEEK_SET);

        chunk_size = bytestream2_get_be32(&s->gb);

        if ((res = decode_format80(&s->gb, chunk_size, s->codebook,

                                   s->codebook_size, 0)) < 0)

            return res;

    }

    /* copy a full codebook */

    if (cbf0_chunk != -1) {

        bytestream2_seek(&s->gb, cbf0_chunk, SEEK_SET);

        chunk_size = bytestream2_get_be32(&s->gb);

        /* sanity check the full codebook size */

        if (chunk_size > MAX_CODEBOOK_SIZE) {

            av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: CBF0 chunk too large (0x%X bytes)\n",

                chunk_size);

            return AVERROR_INVALIDDATA;

        }

        bytestream2_get_buffer(&s->gb, s->codebook, chunk_size);

    }

    /* decode the frame */

    if (vptz_chunk == -1) {

        /* something is wrong if there is no VPTZ chunk */

        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: no VPTZ chunk found\n");

        return AVERROR_INVALIDDATA;

    }

    bytestream2_seek(&s->gb, vptz_chunk, SEEK_SET);

    chunk_size = bytestream2_get_be32(&s->gb);

    if ((res = decode_format80(&s->gb, chunk_size,

                               s->decode_buffer, s->decode_buffer_size, 1)) < 0)

        return res;

    /* render the final PAL8 frame */

    if (s->vector_height == 4)

        index_shift = 4;

    else

        index_shift = 3;

    for (y = 0; y < s->frame.linesize[0] * s->height;

        y += s->frame.linesize[0] * s->vector_height) {

        for (x = y; x < y + s->width; x += 4, lobytes++, hibytes++) {

            pixel_ptr = x;

            /* get the vector index, the method for which varies according to

             * VQA file version */

            switch (s->vqa_version) {

            case 1:

                lobyte = s->decode_buffer[lobytes * 2];

                hibyte = s->decode_buffer[(lobytes * 2) + 1];

                vector_index = ((hibyte << 8) | lobyte) >> 3;

                vector_index <<= index_shift;

                lines = s->vector_height;

                /* uniform color fill - a quick hack */

                if (hibyte == 0xFF) {

                    while (lines--) {

                        s->frame.data[0][pixel_ptr + 0] = 255 - lobyte;

                        s->frame.data[0][pixel_ptr + 1] = 255 - lobyte;

                        s->frame.data[0][pixel_ptr + 2] = 255 - lobyte;

                        s->frame.data[0][pixel_ptr + 3] = 255 - lobyte;

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

                    }

                    lines=0;

                }

                break;

            case 2:

                lobyte = s->decode_buffer[lobytes];

                hibyte = s->decode_buffer[hibytes];

                vector_index = (hibyte << 8) | lobyte;

                vector_index <<= index_shift;

                lines = s->vector_height;

                break;

            case 3:

/* not implemented yet */

                lines = 0;

                break;

            }

            while (lines--) {

                s->frame.data[0][pixel_ptr + 0] = s->codebook[vector_index++];

                s->frame.data[0][pixel_ptr + 1] = s->codebook[vector_index++];

                s->frame.data[0][pixel_ptr + 2] = s->codebook[vector_index++];

                s->frame.data[0][pixel_ptr + 3] = s->codebook[vector_index++];

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

            }

        }

    }

    /* handle partial codebook */

    if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) {

        /* a chunk should not have both chunk types */

        av_log(s->avctx, AV_LOG_ERROR, "  VQA video: problem: found both CBP0 and CBPZ chunks\n");

        return AVERROR_INVALIDDATA;

    }

    if (cbp0_chunk != -1) {

        bytestream2_seek(&s->gb, cbp0_chunk, SEEK_SET);

        chunk_size = bytestream2_get_be32(&s->gb);

        /* accumulate partial codebook */

        bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index],

                               chunk_size);

        s->next_codebook_buffer_index += chunk_size;

        s->partial_countdown--;

        if (s->partial_countdown == 0) {

            /* time to replace codebook */

            memcpy(s->codebook, s->next_codebook_buffer,

                s->next_codebook_buffer_index);

            /* reset accounting */

            s->next_codebook_buffer_index = 0;

            s->partial_countdown = s->partial_count;

        }

    }

    if (cbpz_chunk != -1) {

        bytestream2_seek(&s->gb, cbpz_chunk, SEEK_SET);

        chunk_size = bytestream2_get_be32(&s->gb);

        /* accumulate partial codebook */

        bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index],

                               chunk_size);

        s->next_codebook_buffer_index += chunk_size;

        s->partial_countdown--;

        if (s->partial_countdown == 0) {

            GetByteContext gb;

            bytestream2_init(&gb, s->next_codebook_buffer, s->next_codebook_buffer_index);

            /* decompress codebook */

            if ((res = decode_format80(&gb, s->next_codebook_buffer_index,

                                       s->codebook, s->codebook_size, 0)) < 0)

                return res;

            /* reset accounting */

            s->next_codebook_buffer_index = 0;

            s->partial_countdown = s->partial_count;

        }

    }

    return 0;

}


static void platform_mmio_map(PCIDevice *d, int region_num,

                              pcibus_t addr, pcibus_t size, int type)

{

    int mmio_io_addr;

    mmio_io_addr = cpu_register_io_memory_simple(&platform_mmio_handler,

                                                 DEVICE_NATIVE_ENDIAN);

    cpu_register_physical_memory(addr, size, mmio_io_addr);

}


static void bt_submit_hci(struct HCIInfo *info,

                const uint8_t *data, int length)

{

    struct bt_hci_s *hci = hci_from_info(info);

    uint16_t cmd;

    int paramlen, i;

    if (length < HCI_COMMAND_HDR_SIZE)

        goto short_hci;

    memcpy(&hci->last_cmd, data, 2);

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

    paramlen = data[2];

    if (cmd_opcode_ogf(cmd) == 0 || cmd_opcode_ocf(cmd) == 0)	/* NOP */

        return;

    data += HCI_COMMAND_HDR_SIZE;

    length -= HCI_COMMAND_HDR_SIZE;

    if (paramlen > length)

        return;

#define PARAM(cmd, param)	(((cmd##_cp *) data)->param)

#define PARAM16(cmd, param)	le16_to_cpup(&PARAM(cmd, param))

#define PARAMHANDLE(cmd)	HNDL(PARAM(cmd, handle))

#define LENGTH_CHECK(cmd)	if (length < sizeof(cmd##_cp)) goto short_hci

    /* Note: the supported commands bitmask in bt_hci_read_local_commands_rp

     * needs to be updated every time a command is implemented here!  */

    switch (cmd) {

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY):

        LENGTH_CHECK(inquiry);

        if (PARAM(inquiry, length) < 1) {

            bt_hci_event_complete_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        hci->lm.inquire = 1;

        hci->lm.periodic = 0;

        hci->lm.responses_left = PARAM(inquiry, num_rsp) ?: INT_MAX;

        hci->lm.responses = 0;

        bt_hci_event_status(hci, HCI_SUCCESS);

        bt_hci_inquiry_start(hci, PARAM(inquiry, length));

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_INQUIRY_CANCEL):

        if (!hci->lm.inquire || hci->lm.periodic) {

            fprintf(stderr, "%s: Inquiry Cancel should only be issued after "

                            "the Inquiry command has been issued, a Command "

                            "Status event has been received for the Inquiry "

                            "command, and before the Inquiry Complete event "

                            "occurs", __FUNCTION__);

            bt_hci_event_complete_status(hci, HCI_COMMAND_DISALLOWED);

            break;

        }

        hci->lm.inquire = 0;

        qemu_del_timer(hci->lm.inquiry_done);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_PERIODIC_INQUIRY):

        LENGTH_CHECK(periodic_inquiry);

        if (!(PARAM(periodic_inquiry, length) <

                                PARAM16(periodic_inquiry, min_period) &&

                                PARAM16(periodic_inquiry, min_period) <

                                PARAM16(periodic_inquiry, max_period)) ||

                        PARAM(periodic_inquiry, length) < 1 ||

                        PARAM16(periodic_inquiry, min_period) < 2 ||

                        PARAM16(periodic_inquiry, max_period) < 3) {

            bt_hci_event_complete_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        hci->lm.inquire = 1;

        hci->lm.periodic = 1;

        hci->lm.responses_left = PARAM(periodic_inquiry, num_rsp);

        hci->lm.responses = 0;

        hci->lm.inquiry_period = PARAM16(periodic_inquiry, max_period);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        bt_hci_inquiry_start(hci, PARAM(periodic_inquiry, length));

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_EXIT_PERIODIC_INQUIRY):

        if (!hci->lm.inquire || !hci->lm.periodic) {

            fprintf(stderr, "%s: Inquiry Cancel should only be issued after "

                            "the Inquiry command has been issued, a Command "

                            "Status event has been received for the Inquiry "

                            "command, and before the Inquiry Complete event "

                            "occurs", __FUNCTION__);

            bt_hci_event_complete_status(hci, HCI_COMMAND_DISALLOWED);

            break;

        }

        hci->lm.inquire = 0;

        qemu_del_timer(hci->lm.inquiry_done);

        qemu_del_timer(hci->lm.inquiry_next);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_CREATE_CONN):

        LENGTH_CHECK(create_conn);

        if (hci->lm.connecting >= HCI_HANDLES_MAX) {

            bt_hci_event_status(hci, HCI_REJECTED_LIMITED_RESOURCES);

            break;

        }

        bt_hci_event_status(hci, HCI_SUCCESS);

        if (bt_hci_connect(hci, &PARAM(create_conn, bdaddr)))

            bt_hci_connection_reject_event(hci, &PARAM(create_conn, bdaddr));

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_DISCONNECT):

        LENGTH_CHECK(disconnect);

        if (bt_hci_handle_bad(hci, PARAMHANDLE(disconnect))) {

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

            break;

        }

        bt_hci_event_status(hci, HCI_SUCCESS);

        bt_hci_disconnect(hci, PARAMHANDLE(disconnect),

                        PARAM(disconnect, reason));

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_CREATE_CONN_CANCEL):

        LENGTH_CHECK(create_conn_cancel);

        if (bt_hci_lmp_connection_ready(hci,

                                &PARAM(create_conn_cancel, bdaddr))) {

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

                if (bt_hci_role_master(hci, i) && hci->lm.handle[i].link &&

                                !bacmp(&hci->lm.handle[i].link->slave->bd_addr,

                                        &PARAM(create_conn_cancel, bdaddr)))

                   break;

            bt_hci_event_complete_conn_cancel(hci, i < HCI_HANDLES_MAX ?

                            HCI_ACL_CONNECTION_EXISTS : HCI_NO_CONNECTION,

                            &PARAM(create_conn_cancel, bdaddr));

        } else

            bt_hci_event_complete_conn_cancel(hci, HCI_SUCCESS,

                            &PARAM(create_conn_cancel, bdaddr));

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_ACCEPT_CONN_REQ):

        LENGTH_CHECK(accept_conn_req);

        if (!hci->conn_req_host ||

                        bacmp(&PARAM(accept_conn_req, bdaddr),

                                &hci->conn_req_host->bd_addr)) {

            bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        bt_hci_event_status(hci, HCI_SUCCESS);

        bt_hci_connection_accept(hci, hci->conn_req_host);

        hci->conn_req_host = 0;

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_REJECT_CONN_REQ):

        LENGTH_CHECK(reject_conn_req);

        if (!hci->conn_req_host ||

                        bacmp(&PARAM(reject_conn_req, bdaddr),

                                &hci->conn_req_host->bd_addr)) {

            bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        bt_hci_event_status(hci, HCI_SUCCESS);

        bt_hci_connection_reject(hci, hci->conn_req_host,

                        PARAM(reject_conn_req, reason));

        bt_hci_connection_reject_event(hci, &hci->conn_req_host->bd_addr);

        hci->conn_req_host = 0;

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_AUTH_REQUESTED):

        LENGTH_CHECK(auth_requested);

        if (bt_hci_handle_bad(hci, PARAMHANDLE(auth_requested)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        else {

            bt_hci_event_status(hci, HCI_SUCCESS);

            bt_hci_event_auth_complete(hci, PARAMHANDLE(auth_requested));

        }

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_SET_CONN_ENCRYPT):

        LENGTH_CHECK(set_conn_encrypt);

        if (bt_hci_handle_bad(hci, PARAMHANDLE(set_conn_encrypt)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        else {

            bt_hci_event_status(hci, HCI_SUCCESS);

            bt_hci_event_encrypt_change(hci,

                            PARAMHANDLE(set_conn_encrypt),

                            PARAM(set_conn_encrypt, encrypt));

        }

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_REMOTE_NAME_REQ):

        LENGTH_CHECK(remote_name_req);

        if (bt_hci_name_req(hci, &PARAM(remote_name_req, bdaddr)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_REMOTE_NAME_REQ_CANCEL):

        LENGTH_CHECK(remote_name_req_cancel);

        bt_hci_event_complete_name_cancel(hci,

                        &PARAM(remote_name_req_cancel, bdaddr));

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_READ_REMOTE_FEATURES):

        LENGTH_CHECK(read_remote_features);

        if (bt_hci_features_req(hci, PARAMHANDLE(read_remote_features)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_READ_REMOTE_EXT_FEATURES):

        LENGTH_CHECK(read_remote_ext_features);

        if (bt_hci_handle_bad(hci, PARAMHANDLE(read_remote_ext_features)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        else {

            bt_hci_event_status(hci, HCI_SUCCESS);

            bt_hci_event_read_remote_ext_features(hci,

                            PARAMHANDLE(read_remote_ext_features));

        }

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_READ_REMOTE_VERSION):

        LENGTH_CHECK(read_remote_version);

        if (bt_hci_version_req(hci, PARAMHANDLE(read_remote_version)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_READ_CLOCK_OFFSET):

        LENGTH_CHECK(read_clock_offset);

        if (bt_hci_clkoffset_req(hci, PARAMHANDLE(read_clock_offset)))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_CTL, OCF_READ_LMP_HANDLE):

        LENGTH_CHECK(read_lmp_handle);

        /* TODO: */

        bt_hci_event_complete_lmp_handle(hci, PARAMHANDLE(read_lmp_handle));

        break;

    case cmd_opcode_pack(OGF_LINK_POLICY, OCF_HOLD_MODE):

        LENGTH_CHECK(hold_mode);

        if (PARAM16(hold_mode, min_interval) >

                        PARAM16(hold_mode, max_interval) ||

                        PARAM16(hold_mode, min_interval) < 0x0002 ||

                        PARAM16(hold_mode, max_interval) > 0xff00 ||

                        (PARAM16(hold_mode, min_interval) & 1) ||

                        (PARAM16(hold_mode, max_interval) & 1)) {

            bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        if (bt_hci_mode_change(hci, PARAMHANDLE(hold_mode),

                                PARAM16(hold_mode, max_interval),

                                acl_hold))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_POLICY, OCF_PARK_MODE):

        LENGTH_CHECK(park_mode);

        if (PARAM16(park_mode, min_interval) >

                        PARAM16(park_mode, max_interval) ||

                        PARAM16(park_mode, min_interval) < 0x000e ||

                        (PARAM16(park_mode, min_interval) & 1) ||

                        (PARAM16(park_mode, max_interval) & 1)) {

            bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        if (bt_hci_mode_change(hci, PARAMHANDLE(park_mode),

                                PARAM16(park_mode, max_interval),

                                acl_parked))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_POLICY, OCF_EXIT_PARK_MODE):

        LENGTH_CHECK(exit_park_mode);

        if (bt_hci_mode_cancel(hci, PARAMHANDLE(exit_park_mode),

                                acl_parked))

            bt_hci_event_status(hci, HCI_NO_CONNECTION);

        break;

    case cmd_opcode_pack(OGF_LINK_POLICY, OCF_ROLE_DISCOVERY):

        LENGTH_CHECK(role_discovery);

        if (bt_hci_handle_bad(hci, PARAMHANDLE(role_discovery)))

            bt_hci_event_complete_role_discovery(hci,

                            HCI_NO_CONNECTION, PARAMHANDLE(role_discovery), 0);

        else

            bt_hci_event_complete_role_discovery(hci,

                            HCI_SUCCESS, PARAMHANDLE(role_discovery),

                            bt_hci_role_master(hci,

                                    PARAMHANDLE(role_discovery)));

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_SET_EVENT_MASK):

        LENGTH_CHECK(set_event_mask);

        memcpy(hci->event_mask, PARAM(set_event_mask, mask), 8);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_RESET):

        bt_hci_reset(hci);

        bt_hci_event_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_SET_EVENT_FLT):

        if (length >= 1 && PARAM(set_event_flt, flt_type) == FLT_CLEAR_ALL)

            /* No length check */;

        else

            LENGTH_CHECK(set_event_flt);

        /* Filters are not implemented */

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_FLUSH):

        LENGTH_CHECK(flush);

        if (bt_hci_handle_bad(hci, PARAMHANDLE(flush)))

            bt_hci_event_complete_flush(hci,

                            HCI_NO_CONNECTION, PARAMHANDLE(flush));

        else {

            /* TODO: ordering? */

            bt_hci_event(hci, EVT_FLUSH_OCCURRED,

                            &PARAM(flush, handle),

                            EVT_FLUSH_OCCURRED_SIZE);

            bt_hci_event_complete_flush(hci,

                            HCI_SUCCESS, PARAMHANDLE(flush));

        }

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_CHANGE_LOCAL_NAME):

        LENGTH_CHECK(change_local_name);

        if (hci->device.lmp_name)

            free((void *) hci->device.lmp_name);

        hci->device.lmp_name = strndup(PARAM(change_local_name, name),

                        sizeof(PARAM(change_local_name, name)));

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_LOCAL_NAME):

        bt_hci_event_complete_read_local_name(hci);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_CONN_ACCEPT_TIMEOUT):

        bt_hci_event_complete_read_conn_accept_timeout(hci);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CONN_ACCEPT_TIMEOUT):

        /* TODO */

        LENGTH_CHECK(write_conn_accept_timeout);

        if (PARAM16(write_conn_accept_timeout, timeout) < 0x0001 ||

                        PARAM16(write_conn_accept_timeout, timeout) > 0xb540) {

            bt_hci_event_complete_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        hci->conn_accept_tout = PARAM16(write_conn_accept_timeout, timeout);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_SCAN_ENABLE):

        bt_hci_event_complete_read_scan_enable(hci);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE):

        LENGTH_CHECK(write_scan_enable);

        /* TODO: check that the remaining bits are all 0 */

        hci->device.inquiry_scan =

                !!(PARAM(write_scan_enable, scan_enable) & SCAN_INQUIRY);

        hci->device.page_scan =

                !!(PARAM(write_scan_enable, scan_enable) & SCAN_PAGE);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_CLASS_OF_DEV):

        bt_hci_event_complete_read_local_class(hci);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_CLASS_OF_DEV):

        LENGTH_CHECK(write_class_of_dev);

        memcpy(hci->device.class, PARAM(write_class_of_dev, dev_class),

                        sizeof(PARAM(write_class_of_dev, dev_class)));

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_VOICE_SETTING):

        bt_hci_event_complete_voice_setting(hci);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING):

        LENGTH_CHECK(write_voice_setting);

        hci->voice_setting = PARAM(write_voice_setting, voice_setting);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_HOST_NUMBER_OF_COMPLETED_PACKETS):

        if (length < data[0] * 2 + 1)

            goto short_hci;

        for (i = 0; i < data[0]; i ++)

            if (bt_hci_handle_bad(hci,

                                    data[i * 2 + 1] | (data[i * 2 + 2] << 8)))

                bt_hci_event_complete_status(hci, HCI_INVALID_PARAMETERS);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_READ_INQUIRY_MODE):

        /* Only if (local_features[3] & 0x40) && (local_commands[12] & 0x40)

         * else

         *     goto unknown_command */

        bt_hci_event_complete_read_inquiry_mode(hci);

        break;

    case cmd_opcode_pack(OGF_HOST_CTL, OCF_WRITE_INQUIRY_MODE):

        /* Only if (local_features[3] & 0x40) && (local_commands[12] & 0x80)

         * else

         *     goto unknown_command */

        LENGTH_CHECK(write_inquiry_mode);

        if (PARAM(write_inquiry_mode, mode) > 0x01) {

            bt_hci_event_complete_status(hci, HCI_INVALID_PARAMETERS);

            break;

        }

        hci->lm.inquiry_mode = PARAM(write_inquiry_mode, mode);

        bt_hci_event_complete_status(hci, HCI_SUCCESS);

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_VERSION):

        bt_hci_read_local_version_rp(hci);

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_COMMANDS):

        bt_hci_read_local_commands_rp(hci);

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_FEATURES):

        bt_hci_read_local_features_rp(hci);

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_LOCAL_EXT_FEATURES):

        LENGTH_CHECK(read_local_ext_features);

        bt_hci_read_local_ext_features_rp(hci,

                        PARAM(read_local_ext_features, page_num));

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BUFFER_SIZE):

        bt_hci_read_buffer_size_rp(hci);

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_COUNTRY_CODE):

        bt_hci_read_country_code_rp(hci);

        break;

    case cmd_opcode_pack(OGF_INFO_PARAM, OCF_READ_BD_ADDR):

        bt_hci_read_bd_addr_rp(hci);

        break;

    case cmd_opcode_pack(OGF_STATUS_PARAM, OCF_READ_LINK_QUALITY):

        LENGTH_CHECK(read_link_quality);

        bt_hci_link_quality_rp(hci, PARAMHANDLE(read_link_quality));

        break;

    default:

        bt_hci_event_status(hci, HCI_UNKNOWN_COMMAND);

        break;

    short_hci:

        fprintf(stderr, "%s: HCI packet too short (%iB)\n",

                        __FUNCTION__, length);

        bt_hci_event_status(hci, HCI_INVALID_PARAMETERS);

        break;

    }

}


static int kvm_s390_register_io_adapter(S390FLICState *fs, uint32_t id,

                                        uint8_t isc, bool swap,

                                        bool is_maskable)

{

    struct kvm_s390_io_adapter adapter = {

        .id = id,

        .isc = isc,

        .maskable = is_maskable,

        .swap = swap,

    };

    KVMS390FLICState *flic = KVM_S390_FLIC(fs);

    int r, ret;

    struct kvm_device_attr attr = {

        .group = KVM_DEV_FLIC_ADAPTER_REGISTER,

        .addr = (uint64_t)&adapter,

    };

    if (!kvm_check_extension(kvm_state, KVM_CAP_IRQ_ROUTING)) {

        /* nothing to do */

        return 0;

    }

    r = ioctl(flic->fd, KVM_SET_DEVICE_ATTR, &attr);

    ret = r ? -errno : 0;

    return ret;

}


static void dec_calc(DisasContext *dc, uint32_t insn)

{

    uint32_t op0, op1, op2;

    uint32_t ra, rb, rd;

    op0 = extract32(insn, 0, 4);

    op1 = extract32(insn, 8, 2);

    op2 = extract32(insn, 6, 2);

    ra = extract32(insn, 16, 5);

    rb = extract32(insn, 11, 5);

    rd = extract32(insn, 21, 5);

    switch (op0) {

    case 0x0000:

        switch (op1) {

        case 0x00:    /* l.add */

            LOG_DIS("l.add r%d, r%d, r%d\n", rd, ra, rb);

            {

                int lab = gen_new_label();

                TCGv_i64 ta = tcg_temp_new_i64();

                TCGv_i64 tb = tcg_temp_new_i64();

                TCGv_i64 td = tcg_temp_local_new_i64();

                TCGv_i32 res = tcg_temp_local_new_i32();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);

                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);

                tcg_gen_add_i64(td, ta, tb);

                tcg_gen_trunc_i64_i32(res, td);

                tcg_gen_shri_i64(td, td, 31);

                tcg_gen_andi_i64(td, td, 0x3);

                /* Jump to lab when no overflow.  */

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);

                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_gen_mov_i32(cpu_R[rd], res);

                tcg_temp_free_i64(ta);

                tcg_temp_free_i64(tb);

                tcg_temp_free_i64(td);

                tcg_temp_free_i32(res);

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0001:    /* l.addc */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.addc r%d, r%d, r%d\n", rd, ra, rb);

            {

                int lab = gen_new_label();

                TCGv_i64 ta = tcg_temp_new_i64();

                TCGv_i64 tb = tcg_temp_new_i64();

                TCGv_i64 tcy = tcg_temp_local_new_i64();

                TCGv_i64 td = tcg_temp_local_new_i64();

                TCGv_i32 res = tcg_temp_local_new_i32();

                TCGv_i32 sr_cy = tcg_temp_local_new_i32();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);

                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);

                tcg_gen_andi_i32(sr_cy, cpu_sr, SR_CY);

                tcg_gen_extu_i32_i64(tcy, sr_cy);

                tcg_gen_shri_i64(tcy, tcy, 10);

                tcg_gen_add_i64(td, ta, tb);

                tcg_gen_add_i64(td, td, tcy);

                tcg_gen_trunc_i64_i32(res, td);

                tcg_gen_shri_i64(td, td, 32);

                tcg_gen_andi_i64(td, td, 0x3);

                /* Jump to lab when no overflow.  */

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);

                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_gen_mov_i32(cpu_R[rd], res);

                tcg_temp_free_i64(ta);

                tcg_temp_free_i64(tb);

                tcg_temp_free_i64(tcy);

                tcg_temp_free_i64(td);

                tcg_temp_free_i32(res);

                tcg_temp_free_i32(sr_cy);

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0002:    /* l.sub */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.sub r%d, r%d, r%d\n", rd, ra, rb);

            {

                int lab = gen_new_label();

                TCGv_i64 ta = tcg_temp_new_i64();

                TCGv_i64 tb = tcg_temp_new_i64();

                TCGv_i64 td = tcg_temp_local_new_i64();

                TCGv_i32 res = tcg_temp_local_new_i32();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                tcg_gen_extu_i32_i64(ta, cpu_R[ra]);

                tcg_gen_extu_i32_i64(tb, cpu_R[rb]);

                tcg_gen_sub_i64(td, ta, tb);

                tcg_gen_trunc_i64_i32(res, td);

                tcg_gen_shri_i64(td, td, 31);

                tcg_gen_andi_i64(td, td, 0x3);

                /* Jump to lab when no overflow.  */

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x0, lab);

                tcg_gen_brcondi_i64(TCG_COND_EQ, td, 0x3, lab);

                tcg_gen_ori_i32(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_i32(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_i32(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_gen_mov_i32(cpu_R[rd], res);

                tcg_temp_free_i64(ta);

                tcg_temp_free_i64(tb);

                tcg_temp_free_i64(td);

                tcg_temp_free_i32(res);

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0003:    /* l.and */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.and r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_and_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0004:    /* l.or */

        switch (op1) {

        case 0x00:

            LOG_DIS("l.or r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_or_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0005:

        switch (op1) {

        case 0x00:    /* l.xor */

            LOG_DIS("l.xor r%d, r%d, r%d\n", rd, ra, rb);

            tcg_gen_xor_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0006:

        switch (op1) {

        case 0x03:    /* l.mul */

            LOG_DIS("l.mul r%d, r%d, r%d\n", rd, ra, rb);

            if (ra != 0 && rb != 0) {

                gen_helper_mul32(cpu_R[rd], cpu_env, cpu_R[ra], cpu_R[rb]);

            } else {

                tcg_gen_movi_tl(cpu_R[rd], 0x0);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0009:

        switch (op1) {

        case 0x03:    /* l.div */

            LOG_DIS("l.div r%d, r%d, r%d\n", rd, ra, rb);

            {

                int lab0 = gen_new_label();

                int lab1 = gen_new_label();

                int lab2 = gen_new_label();

                int lab3 = gen_new_label();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                if (rb == 0) {

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab0);

                } else {

                    tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[rb],

                                       0x00000000, lab1);

                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[ra],

                                       0x80000000, lab2);

                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],

                                       0xffffffff, lab2);

                    gen_set_label(lab1);

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab3);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab2);

                    tcg_gen_div_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                    gen_set_label(lab3);

                }

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000a:

        switch (op1) {

        case 0x03:    /* l.divu */

            LOG_DIS("l.divu r%d, r%d, r%d\n", rd, ra, rb);

            {

                int lab0 = gen_new_label();

                int lab1 = gen_new_label();

                int lab2 = gen_new_label();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                if (rb == 0) {

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab0);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab0);

                } else {

                    tcg_gen_brcondi_tl(TCG_COND_NE, cpu_R[rb],

                                       0x00000000, lab1);

                    tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                    tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                    tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab2);

                    gen_exception(dc, EXCP_RANGE);

                    gen_set_label(lab1);

                    tcg_gen_divu_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                    gen_set_label(lab2);

                }

                tcg_temp_free_i32(sr_ove);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000b:

        switch (op1) {

        case 0x03:    /* l.mulu */

            LOG_DIS("l.mulu r%d, r%d, r%d\n", rd, ra, rb);

            if (rb != 0 && ra != 0) {

                TCGv_i64 result = tcg_temp_local_new_i64();

                TCGv_i64 tra = tcg_temp_local_new_i64();

                TCGv_i64 trb = tcg_temp_local_new_i64();

                TCGv_i64 high = tcg_temp_new_i64();

                TCGv_i32 sr_ove = tcg_temp_local_new_i32();

                int lab = gen_new_label();

                /* Calculate each result. */

                tcg_gen_extu_i32_i64(tra, cpu_R[ra]);

                tcg_gen_extu_i32_i64(trb, cpu_R[rb]);

                tcg_gen_mul_i64(result, tra, trb);

                tcg_temp_free_i64(tra);

                tcg_temp_free_i64(trb);

                tcg_gen_shri_i64(high, result, TARGET_LONG_BITS);

                /* Overflow or not. */

                tcg_gen_brcondi_i64(TCG_COND_EQ, high, 0x00000000, lab);

                tcg_gen_ori_tl(cpu_sr, cpu_sr, (SR_OV | SR_CY));

                tcg_gen_andi_tl(sr_ove, cpu_sr, SR_OVE);

                tcg_gen_brcondi_tl(TCG_COND_NE, sr_ove, SR_OVE, lab);

                gen_exception(dc, EXCP_RANGE);

                gen_set_label(lab);

                tcg_temp_free_i64(high);

                tcg_gen_trunc_i64_tl(cpu_R[rd], result);

                tcg_temp_free_i64(result);

                tcg_temp_free_i32(sr_ove);

            } else {

                tcg_gen_movi_tl(cpu_R[rd], 0);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000e:

        switch (op1) {

        case 0x00:    /* l.cmov */

            LOG_DIS("l.cmov r%d, r%d, r%d\n", rd, ra, rb);

            {

                int lab = gen_new_label();

                TCGv res = tcg_temp_local_new();

                TCGv sr_f = tcg_temp_new();

                tcg_gen_andi_tl(sr_f, cpu_sr, SR_F);

                tcg_gen_mov_tl(res, cpu_R[rb]);

                tcg_gen_brcondi_tl(TCG_COND_NE, sr_f, SR_F, lab);

                tcg_gen_mov_tl(res, cpu_R[ra]);

                gen_set_label(lab);

                tcg_gen_mov_tl(cpu_R[rd], res);

                tcg_temp_free(sr_f);

                tcg_temp_free(res);

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000f:

        switch (op1) {

        case 0x00:    /* l.ff1 */

            LOG_DIS("l.ff1 r%d, r%d, r%d\n", rd, ra, rb);

            gen_helper_ff1(cpu_R[rd], cpu_R[ra]);

            break;

        case 0x01:    /* l.fl1 */

            LOG_DIS("l.fl1 r%d, r%d, r%d\n", rd, ra, rb);

            gen_helper_fl1(cpu_R[rd], cpu_R[ra]);

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x0008:

        switch (op1) {

        case 0x00:

            switch (op2) {

            case 0x00:    /* l.sll */

                LOG_DIS("l.sll r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_shl_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            case 0x01:    /* l.srl */

                LOG_DIS("l.srl r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_shr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            case 0x02:    /* l.sra */

                LOG_DIS("l.sra r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_sar_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            case 0x03:    /* l.ror */

                LOG_DIS("l.ror r%d, r%d, r%d\n", rd, ra, rb);

                tcg_gen_rotr_tl(cpu_R[rd], cpu_R[ra], cpu_R[rb]);

                break;

            default:

                gen_illegal_exception(dc);

                break;

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000c:

        switch (op1) {

        case 0x00:

            switch (op2) {

            case 0x00:    /* l.exths */

                LOG_DIS("l.exths r%d, r%d\n", rd, ra);

                tcg_gen_ext16s_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x01:    /* l.extbs */

                LOG_DIS("l.extbs r%d, r%d\n", rd, ra);

                tcg_gen_ext8s_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x02:    /* l.exthz */

                LOG_DIS("l.exthz r%d, r%d\n", rd, ra);

                tcg_gen_ext16u_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x03:    /* l.extbz */

                LOG_DIS("l.extbz r%d, r%d\n", rd, ra);

                tcg_gen_ext8u_tl(cpu_R[rd], cpu_R[ra]);

                break;

            default:

                gen_illegal_exception(dc);

                break;

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    case 0x000d:

        switch (op1) {

        case 0x00:

            switch (op2) {

            case 0x00:    /* l.extws */

                LOG_DIS("l.extws r%d, r%d\n", rd, ra);

                tcg_gen_ext32s_tl(cpu_R[rd], cpu_R[ra]);

                break;

            case 0x01:    /* l.extwz */

                LOG_DIS("l.extwz r%d, r%d\n", rd, ra);

                tcg_gen_ext32u_tl(cpu_R[rd], cpu_R[ra]);

                break;

            default:

                gen_illegal_exception(dc);

                break;

            }

            break;

        default:

            gen_illegal_exception(dc);

            break;

        }

        break;

    default:

        gen_illegal_exception(dc);

        break;

    }

}


QEMUClockType timerlist_get_clock(QEMUTimerList *timer_list)

{

    return timer_list->clock->type;

}


void palette8tobgr16(const uint8_t *src, uint8_t *dst, long num_pixels, const uint8_t *palette)

{

	long i;

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

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

}


static void qio_channel_command_finalize(Object *obj)

{

    QIOChannelCommand *ioc = QIO_CHANNEL_COMMAND(obj);

    if (ioc->readfd != -1) {

        close(ioc->readfd);

        ioc->readfd = -1;

    }

    if (ioc->writefd != -1) {

        close(ioc->writefd);

        ioc->writefd = -1;

    }

    if (ioc->pid > 0) {

#ifndef WIN32

        qio_channel_command_abort(ioc, NULL);

#endif

    }

}


static int read_gab2_sub(AVStream *st, AVPacket *pkt) {

    if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {

        uint8_t desc[256];

        int score = AVPROBE_SCORE_MAX / 2, ret;

        AVIStream *ast = st->priv_data;

        AVInputFormat *sub_demuxer;

        AVRational time_base;

        AVIOContext *pb = avio_alloc_context( pkt->data + 7,

                                              pkt->size - 7,

                                              0, NULL, NULL, NULL, NULL);

        AVProbeData pd;

        unsigned int desc_len = avio_rl32(pb);

        if (desc_len > pb->buf_end - pb->buf_ptr)

            goto error;

        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));

        avio_skip(pb, desc_len - ret);

        if (*desc)

            av_dict_set(&st->metadata, "title", desc, 0);

        avio_rl16(pb);   /* flags? */

        avio_rl32(pb);   /* data size */

        pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };

        if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))

            goto error;

        if (!(ast->sub_ctx = avformat_alloc_context()))

            goto error;

        ast->sub_ctx->pb      = pb;

        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {

            ff_read_packet(ast->sub_ctx, &ast->sub_pkt);

            *st->codec = *ast->sub_ctx->streams[0]->codec;

            ast->sub_ctx->streams[0]->codec->extradata = NULL;

            time_base = ast->sub_ctx->streams[0]->time_base;

            avpriv_set_pts_info(st, 64, time_base.num, time_base.den);

        }

        ast->sub_buffer = pkt->data;

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

        return 1;

error:

        av_freep(&pb);

    }

    return 0;

}


int av_set_string3(void *obj, const char *name, const char *val, int alloc, const AVOption **o_out)

{

    int ret;

    const AVOption *o = av_opt_find(obj, name, NULL, 0, 0);

    if (o_out)

        *o_out = o;

    if (!o)

        return AVERROR_OPTION_NOT_FOUND;

    if (!val || o->offset<=0)

        return AVERROR(EINVAL);

    if (o->type == FF_OPT_TYPE_BINARY) {

        uint8_t **dst = (uint8_t **)(((uint8_t*)obj) + o->offset);

        int *lendst = (int *)(dst + 1);

        uint8_t *bin, *ptr;

        int len = strlen(val);

        av_freep(dst);

        *lendst = 0;

        if (len & 1) return AVERROR(EINVAL);

        len /= 2;

        ptr = bin = av_malloc(len);

        while (*val) {

            int a = hexchar2int(*val++);

            int b = hexchar2int(*val++);

            if (a < 0 || b < 0) {

                av_free(bin);

                return AVERROR(EINVAL);

            }

            *ptr++ = (a << 4) | b;

        }

        *dst = bin;

        *lendst = len;

        return 0;

    }

    if (o->type != FF_OPT_TYPE_STRING) {

        int notfirst=0;

        for (;;) {

            int i;

            char buf[256];

            int cmd=0;

            double d;

            if (*val == '+' || *val == '-')

                cmd= *(val++);

            for (i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+' && val[i]!='-'; i++)

                buf[i]= val[i];

            buf[i]=0;

            {

                const AVOption *o_named = av_opt_find(obj, buf, o->unit, 0, 0);

                if (o_named && o_named->type == FF_OPT_TYPE_CONST)

                    d= o_named->default_val.dbl;

                else if (!strcmp(buf, "default")) d= o->default_val.dbl;

                else if (!strcmp(buf, "max"    )) d= o->max;

                else if (!strcmp(buf, "min"    )) d= o->min;

                else if (!strcmp(buf, "none"   )) d= 0;

                else if (!strcmp(buf, "all"    )) d= ~0;

                else {

                    int res = av_expr_parse_and_eval(&d, buf, const_names, const_values, NULL, NULL, NULL, NULL, NULL, 0, obj);

                    if (res < 0) {

                        av_log(obj, AV_LOG_ERROR, "Unable to parse option value \"%s\"\n", val);

                        return res;

                    }

                }

            }

            if (o->type == FF_OPT_TYPE_FLAGS) {

                if      (cmd=='+') d= av_get_int(obj, name, NULL) | (int64_t)d;

                else if (cmd=='-') d= av_get_int(obj, name, NULL) &~(int64_t)d;

            } else {

                if      (cmd=='+') d= notfirst*av_get_double(obj, name, NULL) + d;

                else if (cmd=='-') d= notfirst*av_get_double(obj, name, NULL) - d;

            }

            if ((ret = av_set_number2(obj, name, d, 1, 1, o_out)) < 0)

                return ret;

            val+= i;

            if (!*val)

                return 0;

            notfirst=1;

        }

        return AVERROR(EINVAL);

    }

    if (alloc) {

        av_free(*(void**)(((uint8_t*)obj) + o->offset));

        val= av_strdup(val);

    }

    memcpy(((uint8_t*)obj) + o->offset, &val, sizeof(val));

    return 0;

}


void ff_h264_h_lpf_chroma_inter_msa(uint8_t *data, int img_width,

                                    int alpha, int beta, int8_t *tc)

{

    uint8_t bs0 = 1;

    uint8_t bs1 = 1;

    uint8_t bs2 = 1;

    uint8_t bs3 = 1;

    if (tc[0] < 0)

        bs0 = 0;

    if (tc[1] < 0)

        bs1 = 0;

    if (tc[2] < 0)

        bs2 = 0;

    if (tc[3] < 0)

        bs3 = 0;

    avc_loopfilter_cb_or_cr_inter_edge_ver_msa(data,

                                               bs0, bs1, bs2, bs3,

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

                                               alpha, beta,

                                               img_width);

}


void slirp_select_poll(fd_set *readfds, fd_set *writefds, fd_set *xfds,

                       int select_error)

{

    Slirp *slirp;

    struct socket *so, *so_next;

    int ret;

    if (QTAILQ_EMPTY(&slirp_instances)) {

        return;

    }

    global_readfds = readfds;

    global_writefds = writefds;

    global_xfds = xfds;

    curtime = qemu_get_clock_ms(rt_clock);

    QTAILQ_FOREACH(slirp, &slirp_instances, entry) {

	/*

	 * See if anything has timed out

	 */

		if (time_fasttimo && ((curtime - time_fasttimo) >= 2)) {

			tcp_fasttimo(slirp);

			time_fasttimo = 0;

		}

		if (do_slowtimo && ((curtime - last_slowtimo) >= 499)) {

			ip_slowtimo(slirp);

			tcp_slowtimo(slirp);

			last_slowtimo = curtime;

		}

	/*

	 * Check sockets

	 */

	if (!select_error) {

		/*

		 * Check TCP sockets

		 */

		for (so = slirp->tcb.so_next; so != &slirp->tcb;

		     so = so_next) {

			so_next = so->so_next;

			/*

			 * FD_ISSET is meaningless on these sockets

			 * (and they can crash the program)

			 */

			if (so->so_state & SS_NOFDREF || so->s == -1)

			   continue;

			/*

			 * Check for URG data

			 * This will soread as well, so no need to

			 * test for readfds below if this succeeds

			 */

			if (FD_ISSET(so->s, xfds))

			   sorecvoob(so);

			/*

			 * Check sockets for reading

			 */

			else if (FD_ISSET(so->s, readfds)) {

				/*

				 * Check for incoming connections

				 */

				if (so->so_state & SS_FACCEPTCONN) {

					tcp_connect(so);

					continue;

				} /* else */

				ret = soread(so);

				/* Output it if we read something */

				if (ret > 0)

				   tcp_output(sototcpcb(so));

			}

			/*

			 * Check sockets for writing

			 */

			if (FD_ISSET(so->s, writefds)) {

			  /*

			   * Check for non-blocking, still-connecting sockets

			   */

			  if (so->so_state & SS_ISFCONNECTING) {

			    /* Connected */

			    so->so_state &= ~SS_ISFCONNECTING;

			    ret = send(so->s, (const void *) &ret, 0, 0);

			    if (ret < 0) {

			      /* XXXXX Must fix, zero bytes is a NOP */

			      if (errno == EAGAIN || errno == EWOULDBLOCK ||

				  errno == EINPROGRESS || errno == ENOTCONN)

				continue;

			      /* else failed */

			      so->so_state &= SS_PERSISTENT_MASK;

			      so->so_state |= SS_NOFDREF;

			    }

			    /* else so->so_state &= ~SS_ISFCONNECTING; */

			    /*

			     * Continue tcp_input

			     */

			    tcp_input((struct mbuf *)NULL, sizeof(struct ip), so);

			    /* continue; */

			  } else

			    ret = sowrite(so);

			  /*

			   * XXXXX If we wrote something (a lot), there

			   * could be a need for a window update.

			   * In the worst case, the remote will send

			   * a window probe to get things going again

			   */

			}

			/*

			 * Probe a still-connecting, non-blocking socket

			 * to check if it's still alive

	 	 	 */

#ifdef PROBE_CONN

			if (so->so_state & SS_ISFCONNECTING) {

                          ret = qemu_recv(so->s, &ret, 0,0);

			  if (ret < 0) {

			    /* XXX */

			    if (errno == EAGAIN || errno == EWOULDBLOCK ||

				errno == EINPROGRESS || errno == ENOTCONN)

			      continue; /* Still connecting, continue */

			    /* else failed */

			    so->so_state &= SS_PERSISTENT_MASK;

			    so->so_state |= SS_NOFDREF;

			    /* tcp_input will take care of it */

			  } else {

			    ret = send(so->s, &ret, 0,0);

			    if (ret < 0) {

			      /* XXX */

			      if (errno == EAGAIN || errno == EWOULDBLOCK ||

				  errno == EINPROGRESS || errno == ENOTCONN)

				continue;

			      /* else failed */

			      so->so_state &= SS_PERSISTENT_MASK;

			      so->so_state |= SS_NOFDREF;

			    } else

			      so->so_state &= ~SS_ISFCONNECTING;

			  }

			  tcp_input((struct mbuf *)NULL, sizeof(struct ip),so);

			} /* SS_ISFCONNECTING */

#endif

		}

		/*

		 * Now UDP sockets.

		 * Incoming packets are sent straight away, they're not buffered.

		 * Incoming UDP data isn't buffered either.

		 */

		for (so = slirp->udb.so_next; so != &slirp->udb;

		     so = so_next) {

			so_next = so->so_next;

			if (so->s != -1 && FD_ISSET(so->s, readfds)) {

                            sorecvfrom(so);

                        }

		}

                /*

                 * Check incoming ICMP relies.

                 */

                for (so = slirp->icmp.so_next; so != &slirp->icmp;

                     so = so_next) {

                     so_next = so->so_next;

                    if (so->s != -1 && FD_ISSET(so->s, readfds)) {

                        icmp_receive(so);

                    }

                }

	}

	/*

	 * See if we can start outputting

	 */

	if (slirp->if_queued) {

	    if_start(slirp);

	}

    }

	/* clear global file descriptor sets.

	 * these reside on the stack in vl.c

	 * so they're unusable if we're not in

	 * slirp_select_fill or slirp_select_poll.

	 */

	 global_readfds = NULL;

	 global_writefds = NULL;

	 global_xfds = NULL;

}


uint64_t helper_cmpbge (uint64_t op1, uint64_t op2)

{

    uint8_t opa, opb, res;

    int i;

    res = 0;

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

        opa = op1 >> (i * 8);

        opb = op2 >> (i * 8);

        if (opa >= opb)

            res |= 1 << i;

    }

    return res;

}


static int s390_ipl_init(SysBusDevice *dev)

{

    S390IPLState *ipl = S390_IPL(dev);

    uint64_t pentry = KERN_IMAGE_START;

    int kernel_size;

    int bios_size;

    char *bios_filename;

    /*

     * Always load the bios if it was enforced,

     * even if an external kernel has been defined.

     */

    if (!ipl->kernel || ipl->enforce_bios) {

        uint64_t fwbase = (MIN(ram_size, 0x80000000U) - 0x200000) & ~0xffffUL;

        if (bios_name == NULL) {

            bios_name = ipl->firmware;

        }

        bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);

        if (bios_filename == NULL) {

            hw_error("could not find stage1 bootloader\n");

        }

        bios_size = load_elf(bios_filename, bios_translate_addr, &fwbase,

                             &ipl->bios_start_addr, NULL, NULL, 1,

                             ELF_MACHINE, 0);

        if (bios_size > 0) {

            /* Adjust ELF start address to final location */

            ipl->bios_start_addr += fwbase;

        } else {

            /* Try to load non-ELF file (e.g. s390-zipl.rom) */

            bios_size = load_image_targphys(bios_filename, ZIPL_IMAGE_START,

                                            4096);

            ipl->bios_start_addr = ZIPL_IMAGE_START;

            if (bios_size > 4096) {

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

            }

        }

        g_free(bios_filename);

        if (bios_size == -1) {

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

        }

        /* default boot target is the bios */

        ipl->start_addr = ipl->bios_start_addr;

    }

    if (ipl->kernel) {

        kernel_size = load_elf(ipl->kernel, NULL, NULL, &pentry, NULL,

                               NULL, 1, ELF_MACHINE, 0);

        if (kernel_size < 0) {

            kernel_size = load_image_targphys(ipl->kernel, 0, ram_size);

        }

        if (kernel_size < 0) {

            fprintf(stderr, "could not load kernel '%s'\n", ipl->kernel);

            return -1;

        }

        /*

         * Is it a Linux kernel (starting at 0x10000)? If yes, we fill in the

         * kernel parameters here as well. Note: For old kernels (up to 3.2)

         * we can not rely on the ELF entry point - it was 0x800 (the SALIPL

         * loader) and it won't work. For this case we force it to 0x10000, too.

         */

        if (pentry == KERN_IMAGE_START || pentry == 0x800) {

            ipl->start_addr = KERN_IMAGE_START;

            /* Overwrite parameters in the kernel image, which are "rom" */

            strcpy(rom_ptr(KERN_PARM_AREA), ipl->cmdline);

        } else {

            ipl->start_addr = pentry;

        }

        if (ipl->initrd) {

            ram_addr_t initrd_offset;

            int initrd_size;

            initrd_offset = INITRD_START;

            while (kernel_size + 0x100000 > initrd_offset) {

                initrd_offset += 0x100000;

            }

            initrd_size = load_image_targphys(ipl->initrd, initrd_offset,

                                              ram_size - initrd_offset);

            if (initrd_size == -1) {

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

                        ipl->initrd);

                exit(1);

            }

            /*

             * we have to overwrite values in the kernel image,

             * which are "rom"

             */

            stq_p(rom_ptr(INITRD_PARM_START), initrd_offset);

            stq_p(rom_ptr(INITRD_PARM_SIZE), initrd_size);

        }

    }

    return 0;

}


static int virtcon_parse(const char *devname)

{

    QemuOptsList *device = qemu_find_opts("device");

    static int index = 0;

    char label[32];

    QemuOpts *bus_opts, *dev_opts;

    if (strcmp(devname, "none") == 0)

        return 0;

    if (index == MAX_VIRTIO_CONSOLES) {

        fprintf(stderr, "qemu: too many virtio consoles\n");

        exit(1);

    }

    bus_opts = qemu_opts_create(device, NULL, 0);

    if (arch_type == QEMU_ARCH_S390X) {

        qemu_opt_set(bus_opts, "driver", "virtio-serial-s390");

    } else {

        qemu_opt_set(bus_opts, "driver", "virtio-serial-pci");

    }

    dev_opts = qemu_opts_create(device, NULL, 0);

    qemu_opt_set(dev_opts, "driver", "virtconsole");

    snprintf(label, sizeof(label), "virtcon%d", index);

    virtcon_hds[index] = qemu_chr_new(label, devname, NULL);

    if (!virtcon_hds[index]) {

        fprintf(stderr, "qemu: could not open virtio console '%s': %s\n",

                devname, strerror(errno));

        return -1;

    }

    qemu_opt_set(dev_opts, "chardev", label);

    index++;

    return 0;

}


static void monitor_puts(Monitor *mon, const char *str)

{

    char c;

    for(;;) {

        c = *str++;

        if (c == '\0')

            break;

        if (c == '\n') {

            qstring_append_chr(mon->outbuf, '\r');

        }

        qstring_append_chr(mon->outbuf, c);

        if (c == '\n') {

            monitor_flush(mon);

        }

    }

}


static void gen_movl_seg_T0(DisasContext *s, int seg_reg)

{

    if (s->pe && !s->vm86) {

        tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T0);

        gen_helper_load_seg(cpu_env, tcg_const_i32(seg_reg), cpu_tmp2_i32);

        /* abort translation because the addseg value may change or

           because ss32 may change. For R_SS, translation must always

           stop as a special handling must be done to disable hardware

           interrupts for the next instruction */

        if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))

            s->is_jmp = DISAS_TB_JUMP;

    } else {

        gen_op_movl_seg_T0_vm(seg_reg);

        if (seg_reg == R_SS)

            s->is_jmp = DISAS_TB_JUMP;

    }

}