static void dequantization_int_97(int x, int y, Jpeg2000Cblk *cblk,

                               Jpeg2000Component *comp,

                               Jpeg2000T1Context *t1, Jpeg2000Band *band)

{

    int i, j;

    int w = cblk->coord[0][1] - cblk->coord[0][0];

    for (j = 0; j < (cblk->coord[1][1] - cblk->coord[1][0]); ++j) {

        int32_t *datap = &comp->i_data[(comp->coord[0][1] - comp->coord[0][0]) * (y + j) + x];

        int *src = t1->data[j];

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

            datap[i] = (src[i] * band->i_stepsize + (1<<14)) >> 15;

    }

}


yuv2rgb_full_1_c_template(SwsContext *c, const int16_t *buf0,

                     const int16_t *ubuf[2], const int16_t *vbuf[2],

                     const int16_t *abuf0, uint8_t *dest, int dstW,

                     int uvalpha, int y, enum AVPixelFormat target,

                     int hasAlpha)

{

    const int16_t *ubuf0 = ubuf[0], *vbuf0 = vbuf[0];

    int i;

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

    int err[4] = {0};

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

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

        step = 1;

    if (uvalpha < 2048) {

        int A = 0; //init to silence warning

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

            int Y = buf0[i] << 2;

            int U = (ubuf0[i] - (128<<7)) << 2;

            int V = (vbuf0[i] - (128<<7)) << 2;

            if (hasAlpha) {

                A = (abuf0[i] + 64) >> 7;

                if (A & 0x100)

                    A = av_clip_uint8(A);

            }

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

            dest += step;

        }

    } else {

        const int16_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1];

        int A = 0; //init to silence warning

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

            int Y = buf0[i] << 2;

            int U = (ubuf0[i] + ubuf1[i] - (128<<8)) << 1;

            int V = (vbuf0[i] + vbuf1[i] - (128<<8)) << 1;

            if (hasAlpha) {

                A = (abuf0[i] + 64) >> 7;

                if (A & 0x100)

                    A = av_clip_uint8(A);

            }

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

            dest += step;

        }

    }

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

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

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

}


void Process(void *ctx, AVPicture *picture, enum PixelFormat pix_fmt, int width, int height, int64_t pts)

{

    int err = 0;

    ContextInfo *ci = (ContextInfo *) ctx;

    AVPicture picture1;

    AVPicture picture2;

    AVPicture *pict = picture;

    int out_width;

    int out_height;

    int i;

    uint8_t *ptr = NULL;

    FILE *in = rwpipe_reader( ci->rw );

    FILE *out = rwpipe_writer( ci->rw );

    /* Check that we have a pipe to talk to. */

    if ( in == NULL || out == NULL )

        err = 1;

    /* Convert to RGB24 if necessary */

    if ( !err && pix_fmt != PIX_FMT_RGB24 )

    {

        int size = avpicture_get_size(PIX_FMT_RGB24, width, height);

        if ( size != ci->size1 )

        {

            av_free( ci->buf1 );

            ci->buf1 = av_malloc(size);

            ci->size1 = size;

            err = ci->buf1 == NULL;

        }

        if ( !err )

        {

            avpicture_fill(&picture1, ci->buf1, PIX_FMT_RGB24, width, height);

            // if we already got a SWS context, let's realloc if is not re-useable

            ci->toRGB_convert_ctx = sws_getCachedContext(ci->toRGB_convert_ctx,

                                        width, height, pix_fmt,

                                        width, height, PIX_FMT_RGB24,

                                        sws_flags, NULL, NULL, NULL);

            if (ci->toRGB_convert_ctx == NULL) {

                av_log(NULL, AV_LOG_ERROR,

                       "Cannot initialize the toRGB conversion context\n");

                return;

            }

// img_convert parameters are          2 first destination, then 4 source

// sws_scale   parameters are context, 4 first source,      then 2 destination

            sws_scale(ci->toRGB_convert_ctx,

                     picture->data, picture->linesize, 0, height,

                     picture1.data, picture1.linesize);

            pict = &picture1;

        }

    }

    /* Write out the PPM */

    if ( !err )

    {

        ptr = pict->data[ 0 ];

        fprintf( out, "P6\n%d %d\n255\n", width, height );

        for ( i = 0; !err && i < height; i ++ )

        {

            err = !fwrite( ptr, width * 3, 1, out );

            ptr += pict->linesize[ 0 ];

        }

        if ( !err )

            err = fflush( out );

    }

    /* Read the PPM returned. */

    if ( !err && !rwpipe_read_ppm_header( ci->rw, &out_width, &out_height ) )

    {

        int size = avpicture_get_size(PIX_FMT_RGB24, out_width, out_height);

        if ( size != ci->size2 )

        {

            av_free( ci->buf2 );

            ci->buf2 = av_malloc(size);

            ci->size2 = size;

            err = ci->buf2 == NULL;

        }

        if ( !err )

        {

            avpicture_fill(&picture2, ci->buf2, PIX_FMT_RGB24, out_width, out_height);

            ptr = picture2.data[ 0 ];

            for ( i = 0; !err && i < out_height; i ++ )

            {

                err = !fread( ptr, out_width * 3, 1, in );

                ptr += picture2.linesize[ 0 ];

            }

        }

    }

    /* Convert the returned PPM back to the input format */

    if ( !err )

    {

        /* The out_width/out_height returned from the PPM

         * filter won't necessarily be the same as width and height

         * but it will be scaled anyway to width/height.

         */

        av_log(NULL, AV_LOG_DEBUG,

                  "PPM vhook: Input dimensions: %d x %d Output dimensions: %d x %d\n",

                  width, height, out_width, out_height);

        ci->fromRGB_convert_ctx = sws_getCachedContext(ci->fromRGB_convert_ctx,

                                        out_width, out_height, PIX_FMT_RGB24,

                                        width,     height,     pix_fmt,

                                        sws_flags, NULL, NULL, NULL);

        if (ci->fromRGB_convert_ctx == NULL) {

            av_log(NULL, AV_LOG_ERROR,

                   "Cannot initialize the fromRGB conversion context\n");

            return;

        }

// img_convert parameters are          2 first destination, then 4 source

// sws_scale   parameters are context, 4 first source,      then 2 destination

        sws_scale(ci->fromRGB_convert_ctx,

                 picture2.data, picture2.linesize, 0, out_height,

                 picture->data, picture->linesize);

    }

}


static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)

{

    struct video_data *s = s1->priv_data;

    struct v4l2_input input;

    struct v4l2_standard standard;

    struct v4l2_streamparm streamparm = { 0 };

    struct v4l2_fract *tpf = &streamparm.parm.capture.timeperframe;

    int i, ret;

    AVRational framerate_q;

    streamparm.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;

    if (s->framerate &&

        (ret = av_parse_video_rate(&framerate_q, s->framerate)) < 0) {

        av_log(s1, AV_LOG_ERROR, "Could not parse framerate '%s'.\n",

               s->framerate);

        return ret;

    }

    /* set tv video input */

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

    input.index = s->channel;

    if (ioctl(s->fd, VIDIOC_ENUMINPUT, &input) < 0) {

        av_log(s1, AV_LOG_ERROR, "The V4L2 driver ioctl enum input failed:\n");

        return AVERROR(EIO);

    }

    av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set input_id: %d, input: %s\n",

            s->channel, input.name);

    if (ioctl(s->fd, VIDIOC_S_INPUT, &input.index) < 0) {

        av_log(s1, AV_LOG_ERROR,

               "The V4L2 driver ioctl set input(%d) failed\n",

                s->channel);

        return AVERROR(EIO);

    }

    if (s->standard) {

        av_log(s1, AV_LOG_DEBUG, "The V4L2 driver set standard: %s\n",

               s->standard);

        /* set tv standard */

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

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

            standard.index = i;

            if (ioctl(s->fd, VIDIOC_ENUMSTD, &standard) < 0) {

                av_log(s1, AV_LOG_ERROR,

                       "The V4L2 driver ioctl set standard(%s) failed\n",

                       s->standard);

                return AVERROR(EIO);

            }

            if (!av_strcasecmp(standard.name, s->standard)) {

                break;

            }

        }

        av_log(s1, AV_LOG_DEBUG,

               "The V4L2 driver set standard: %s, id: %"PRIu64"\n",

               s->standard, (uint64_t)standard.id);

        if (ioctl(s->fd, VIDIOC_S_STD, &standard.id) < 0) {

            av_log(s1, AV_LOG_ERROR,

                   "The V4L2 driver ioctl set standard(%s) failed\n",

                   s->standard);

            return AVERROR(EIO);

        }

    }

    if (framerate_q.num && framerate_q.den) {

        av_log(s1, AV_LOG_DEBUG, "Setting time per frame to %d/%d\n",

               framerate_q.den, framerate_q.num);

        tpf->numerator   = framerate_q.den;

        tpf->denominator = framerate_q.num;

        if (ioctl(s->fd, VIDIOC_S_PARM, &streamparm) != 0) {

            av_log(s1, AV_LOG_ERROR,

                   "ioctl set time per frame(%d/%d) failed\n",

                   framerate_q.den, framerate_q.num);

            return AVERROR(EIO);

        }

        if (framerate_q.num != tpf->denominator ||

            framerate_q.den != tpf->numerator) {

            av_log(s1, AV_LOG_INFO,

                   "The driver changed the time per frame from "

                   "%d/%d to %d/%d\n",

                   framerate_q.den, framerate_q.num,

                   tpf->numerator, tpf->denominator);

        }

    } else {

        if (ioctl(s->fd, VIDIOC_G_PARM, &streamparm) != 0) {

            av_log(s1, AV_LOG_ERROR, "ioctl(VIDIOC_G_PARM): %s\n",

                   strerror(errno));

            return AVERROR(errno);

        }

    }

    s1->streams[0]->codec->time_base.den = tpf->denominator;

    s1->streams[0]->codec->time_base.num = tpf->numerator;

    s->timeout = 100 +

        av_rescale_q(1, s1->streams[0]->codec->time_base,

                        (AVRational){1, 1000});

    return 0;

}


static int mpegts_read_packet(AVFormatContext *s,

                              AVPacket *pkt)

{

    MpegTSContext *ts = s->priv_data;

    if (!ts->mpeg2ts_raw) {

        ts->pkt = pkt;

        return handle_packets(ts, 0);

    } else {

        return mpegts_raw_read_packet(s, pkt);

    }

}


static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,

                               int selector)

{

    SegmentCache *dt;

    int index;

    uint8_t *ptr;

    if (selector & 0x4)

        dt = &env->ldt;

    else

        dt = &env->gdt;

    index = selector & ~7;

    if ((index + 7) > dt->limit)

        return -1;

    ptr = dt->base + index;

    *e1_ptr = ldl_kernel(ptr);

    *e2_ptr = ldl_kernel(ptr + 4);

    return 0;

}


static int start_frame(AVFilterLink *link, AVFilterBufferRef *picref)

{

    AVFilterContext *ctx = link->dst;

    YADIFContext *yadif = ctx->priv;

    if (yadif->frame_pending)

        return_frame(ctx, 1);

    if (yadif->prev)

        avfilter_unref_buffer(yadif->prev);

    yadif->prev = yadif->cur;

    yadif->cur  = yadif->next;

    yadif->next = picref;

    if (!yadif->cur)

        return 0;

    if (yadif->auto_enable && !yadif->cur->video->interlaced) {

        yadif->out  = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);

        avfilter_unref_bufferp(&yadif->prev);

        if (yadif->out->pts != AV_NOPTS_VALUE)

            yadif->out->pts *= 2;

        return ff_start_frame(ctx->outputs[0], yadif->out);

    }

    if (!yadif->prev)

        yadif->prev = avfilter_ref_buffer(yadif->cur, AV_PERM_READ);

    yadif->out = ff_get_video_buffer(ctx->outputs[0], AV_PERM_WRITE | AV_PERM_PRESERVE |

                                     AV_PERM_REUSE, link->w, link->h);

    avfilter_copy_buffer_ref_props(yadif->out, yadif->cur);

    yadif->out->video->interlaced = 0;

    if (yadif->out->pts != AV_NOPTS_VALUE)

        yadif->out->pts *= 2;

    return ff_start_frame(ctx->outputs[0], yadif->out);

}


static void av_always_inline filter_mb_edgeh( uint8_t *pix, int stride, const int16_t bS[4], unsigned int qp, H264Context *h, int intra ) {

    const int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8);

    const unsigned int index_a = qp - qp_bd_offset + h->slice_alpha_c0_offset;

    const int alpha = alpha_table[index_a];

    const int beta  = beta_table[qp - qp_bd_offset + h->slice_beta_offset];

    if (alpha ==0 || beta == 0) return;

    if( bS[0] < 4 || !intra ) {

        int8_t tc[4];

        tc[0] = tc0_table[index_a][bS[0]];

        tc[1] = tc0_table[index_a][bS[1]];

        tc[2] = tc0_table[index_a][bS[2]];

        tc[3] = tc0_table[index_a][bS[3]];

        h->h264dsp.h264_v_loop_filter_luma(pix, stride, alpha, beta, tc);

    } else {

        h->h264dsp.h264_v_loop_filter_luma_intra(pix, stride, alpha, beta);

    }

}


static void calc_thr_3gpp(const FFPsyWindowInfo *wi, const int num_bands, AacPsyChannel *pch,

                          const uint8_t *band_sizes, const float *coefs)

{

    int i, w, g;

    int start = 0;

    for (w = 0; w < wi->num_windows*16; w += 16) {

        for (g = 0; g < num_bands; g++) {

            AacPsyBand *band = &pch->band[w+g];

            float form_factor = 0.0f;

            float Temp;

            band->energy = 0.0f;

            for (i = 0; i < band_sizes[g]; i++) {

                band->energy += coefs[start+i] * coefs[start+i];

                form_factor  += sqrtf(fabs(coefs[start+i]));

            }

            Temp = band->energy > 0 ? sqrtf((float)band_sizes[g] / band->energy) : 0;

            band->thr      = band->energy * 0.001258925f;

            band->nz_lines = form_factor * sqrtf(Temp);

            start += band_sizes[g];

        }

    }

}


void aio_bh_schedule_oneshot(AioContext *ctx, QEMUBHFunc *cb, void *opaque)

{

    QEMUBH *bh;

    bh = g_new(QEMUBH, 1);

    *bh = (QEMUBH){

        .ctx = ctx,

        .cb = cb,

        .opaque = opaque,

    };

    qemu_lockcnt_lock(&ctx->list_lock);

    bh->next = ctx->first_bh;

    bh->scheduled = 1;

    bh->deleted = 1;

    /* Make sure that the members are ready before putting bh into list */

    smp_wmb();

    ctx->first_bh = bh;

    qemu_lockcnt_unlock(&ctx->list_lock);

    aio_notify(ctx);

}


static int32_t virtio_net_flush_tx(VirtIONetQueue *q)

{

    VirtIONet *n = q->n;

    VirtIODevice *vdev = VIRTIO_DEVICE(n);

    VirtQueueElement elem;

    int32_t num_packets = 0;

    int queue_index = vq2q(virtio_get_queue_index(q->tx_vq));

    if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) {

        return num_packets;

    }

    if (q->async_tx.elem.out_num) {

        virtio_queue_set_notification(q->tx_vq, 0);

        return num_packets;

    }

    while (virtqueue_pop(q->tx_vq, &elem)) {

        ssize_t ret;

        unsigned int out_num = elem.out_num;

        struct iovec *out_sg = &elem.out_sg[0];

        struct iovec sg[VIRTQUEUE_MAX_SIZE], sg2[VIRTQUEUE_MAX_SIZE + 1];

        struct virtio_net_hdr_mrg_rxbuf mhdr;

        if (out_num < 1) {

            error_report("virtio-net header not in first element");

            exit(1);

        }

        if (n->has_vnet_hdr) {

            if (iov_to_buf(out_sg, out_num, 0, &mhdr, n->guest_hdr_len) <

                n->guest_hdr_len) {

                error_report("virtio-net header incorrect");

                exit(1);

            }

            if (virtio_needs_swap(vdev)) {

                virtio_net_hdr_swap(vdev, (void *) &mhdr);

                sg2[0].iov_base = &mhdr;

                sg2[0].iov_len = n->guest_hdr_len;

                out_num = iov_copy(&sg2[1], ARRAY_SIZE(sg2) - 1,

                                   out_sg, out_num,

                                   n->guest_hdr_len, -1);

                if (out_num == VIRTQUEUE_MAX_SIZE) {

                    goto drop;

		}

                out_num += 1;

                out_sg = sg2;

	    }

        }

        /*

         * If host wants to see the guest header as is, we can

         * pass it on unchanged. Otherwise, copy just the parts

         * that host is interested in.

         */

        assert(n->host_hdr_len <= n->guest_hdr_len);

        if (n->host_hdr_len != n->guest_hdr_len) {

            unsigned sg_num = iov_copy(sg, ARRAY_SIZE(sg),

                                       out_sg, out_num,

                                       0, n->host_hdr_len);

            sg_num += iov_copy(sg + sg_num, ARRAY_SIZE(sg) - sg_num,

                             out_sg, out_num,

                             n->guest_hdr_len, -1);

            out_num = sg_num;

            out_sg = sg;

        }

        ret = qemu_sendv_packet_async(qemu_get_subqueue(n->nic, queue_index),

                                      out_sg, out_num, virtio_net_tx_complete);

        if (ret == 0) {

            virtio_queue_set_notification(q->tx_vq, 0);

            q->async_tx.elem = elem;

            return -EBUSY;

        }

drop:

        virtqueue_push(q->tx_vq, &elem, 0);

        virtio_notify(vdev, q->tx_vq);

        if (++num_packets >= n->tx_burst) {

            break;

        }

    }

    return num_packets;

}


static void sdhci_data_transfer(void *opaque)

{

    SDHCIState *s = (SDHCIState *)opaque;

    if (s->trnmod & SDHC_TRNS_DMA) {

        switch (SDHC_DMA_TYPE(s->hostctl)) {

        case SDHC_CTRL_SDMA:

            if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {

                sdhci_sdma_transfer_single_block(s);

            } else {

                sdhci_sdma_transfer_multi_blocks(s);

            }

            break;

        case SDHC_CTRL_ADMA1_32:

            if (!(s->capareg & SDHC_CAN_DO_ADMA1)) {

                ERRPRINT("ADMA1 not supported\n");

                break;

            }

            sdhci_do_adma(s);

            break;

        case SDHC_CTRL_ADMA2_32:

            if (!(s->capareg & SDHC_CAN_DO_ADMA2)) {

                ERRPRINT("ADMA2 not supported\n");

                break;

            }

            sdhci_do_adma(s);

            break;

        case SDHC_CTRL_ADMA2_64:

            if (!(s->capareg & SDHC_CAN_DO_ADMA2) ||

                    !(s->capareg & SDHC_64_BIT_BUS_SUPPORT)) {

                ERRPRINT("64 bit ADMA not supported\n");

                break;

            }

            sdhci_do_adma(s);

            break;

        default:

            ERRPRINT("Unsupported DMA type\n");

            break;

        }

    } else {

        if ((s->trnmod & SDHC_TRNS_READ) && sdbus_data_ready(&s->sdbus)) {

            s->prnsts |= SDHC_DOING_READ | SDHC_DATA_INHIBIT |

                    SDHC_DAT_LINE_ACTIVE;

            sdhci_read_block_from_card(s);

        } else {

            s->prnsts |= SDHC_DOING_WRITE | SDHC_DAT_LINE_ACTIVE |

                    SDHC_SPACE_AVAILABLE | SDHC_DATA_INHIBIT;

            sdhci_write_block_to_card(s);

        }

    }

}


void cpu_dump_state(CPUState *env, FILE *f,

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

                    int flags)

{

    int eflags, i, nb;

    char cc_op_name[32];

    static const char *seg_name[6] = { "ES", "CS", "SS", "DS", "FS", "GS" };

    if (kvm_enabled())

        kvm_arch_get_registers(env);

    eflags = env->eflags;

#ifdef TARGET_X86_64

    if (env->hflags & HF_CS64_MASK) {

        cpu_fprintf(f,

                    "RAX=%016" PRIx64 " RBX=%016" PRIx64 " RCX=%016" PRIx64 " RDX=%016" PRIx64 "\n"

                    "RSI=%016" PRIx64 " RDI=%016" PRIx64 " RBP=%016" PRIx64 " RSP=%016" PRIx64 "\n"

                    "R8 =%016" PRIx64 " R9 =%016" PRIx64 " R10=%016" PRIx64 " R11=%016" PRIx64 "\n"

                    "R12=%016" PRIx64 " R13=%016" PRIx64 " R14=%016" PRIx64 " R15=%016" PRIx64 "\n"

                    "RIP=%016" PRIx64 " RFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",

                    env->regs[R_EAX],

                    env->regs[R_EBX],

                    env->regs[R_ECX],

                    env->regs[R_EDX],

                    env->regs[R_ESI],

                    env->regs[R_EDI],

                    env->regs[R_EBP],

                    env->regs[R_ESP],

                    env->regs[8],

                    env->regs[9],

                    env->regs[10],

                    env->regs[11],

                    env->regs[12],

                    env->regs[13],

                    env->regs[14],

                    env->regs[15],

                    env->eip, eflags,

                    eflags & DF_MASK ? 'D' : '-',

                    eflags & CC_O ? 'O' : '-',

                    eflags & CC_S ? 'S' : '-',

                    eflags & CC_Z ? 'Z' : '-',

                    eflags & CC_A ? 'A' : '-',

                    eflags & CC_P ? 'P' : '-',

                    eflags & CC_C ? 'C' : '-',

                    env->hflags & HF_CPL_MASK,

                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,

                    (int)(env->a20_mask >> 20) & 1,

                    (env->hflags >> HF_SMM_SHIFT) & 1,

                    env->halted);

    } else

#endif

    {

        cpu_fprintf(f, "EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"

                    "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"

                    "EIP=%08x EFL=%08x [%c%c%c%c%c%c%c] CPL=%d II=%d A20=%d SMM=%d HLT=%d\n",

                    (uint32_t)env->regs[R_EAX],

                    (uint32_t)env->regs[R_EBX],

                    (uint32_t)env->regs[R_ECX],

                    (uint32_t)env->regs[R_EDX],

                    (uint32_t)env->regs[R_ESI],

                    (uint32_t)env->regs[R_EDI],

                    (uint32_t)env->regs[R_EBP],

                    (uint32_t)env->regs[R_ESP],

                    (uint32_t)env->eip, eflags,

                    eflags & DF_MASK ? 'D' : '-',

                    eflags & CC_O ? 'O' : '-',

                    eflags & CC_S ? 'S' : '-',

                    eflags & CC_Z ? 'Z' : '-',

                    eflags & CC_A ? 'A' : '-',

                    eflags & CC_P ? 'P' : '-',

                    eflags & CC_C ? 'C' : '-',

                    env->hflags & HF_CPL_MASK,

                    (env->hflags >> HF_INHIBIT_IRQ_SHIFT) & 1,

                    (int)(env->a20_mask >> 20) & 1,

                    (env->hflags >> HF_SMM_SHIFT) & 1,

                    env->halted);

    }

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

        cpu_x86_dump_seg_cache(env, f, cpu_fprintf, seg_name[i],

                               &env->segs[i]);

    }

    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "LDT", &env->ldt);

    cpu_x86_dump_seg_cache(env, f, cpu_fprintf, "TR", &env->tr);

#ifdef TARGET_X86_64

    if (env->hflags & HF_LMA_MASK) {

        cpu_fprintf(f, "GDT=     %016" PRIx64 " %08x\n",

                    env->gdt.base, env->gdt.limit);

        cpu_fprintf(f, "IDT=     %016" PRIx64 " %08x\n",

                    env->idt.base, env->idt.limit);

        cpu_fprintf(f, "CR0=%08x CR2=%016" PRIx64 " CR3=%016" PRIx64 " CR4=%08x\n",

                    (uint32_t)env->cr[0],

                    env->cr[2],

                    env->cr[3],

                    (uint32_t)env->cr[4]);

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

            cpu_fprintf(f, "DR%d=%016" PRIx64 " ", i, env->dr[i]);

        cpu_fprintf(f, "\nDR6=%016" PRIx64 " DR7=%016" PRIx64 "\n",

                    env->dr[6], env->dr[7]);

    } else

#endif

    {

        cpu_fprintf(f, "GDT=     %08x %08x\n",

                    (uint32_t)env->gdt.base, env->gdt.limit);

        cpu_fprintf(f, "IDT=     %08x %08x\n",

                    (uint32_t)env->idt.base, env->idt.limit);

        cpu_fprintf(f, "CR0=%08x CR2=%08x CR3=%08x CR4=%08x\n",

                    (uint32_t)env->cr[0],

                    (uint32_t)env->cr[2],

                    (uint32_t)env->cr[3],

                    (uint32_t)env->cr[4]);

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

            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);

        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);

    }

    if (flags & X86_DUMP_CCOP) {

        if ((unsigned)env->cc_op < CC_OP_NB)

            snprintf(cc_op_name, sizeof(cc_op_name), "%s", cc_op_str[env->cc_op]);

        else

            snprintf(cc_op_name, sizeof(cc_op_name), "[%d]", env->cc_op);

#ifdef TARGET_X86_64

        if (env->hflags & HF_CS64_MASK) {

            cpu_fprintf(f, "CCS=%016" PRIx64 " CCD=%016" PRIx64 " CCO=%-8s\n",

                        env->cc_src, env->cc_dst,

                        cc_op_name);

        } else

#endif

        {

            cpu_fprintf(f, "CCS=%08x CCD=%08x CCO=%-8s\n",

                        (uint32_t)env->cc_src, (uint32_t)env->cc_dst,

                        cc_op_name);

        }

    }

    if (flags & X86_DUMP_FPU) {

        int fptag;

        fptag = 0;

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

            fptag |= ((!env->fptags[i]) << i);

        }

        cpu_fprintf(f, "FCW=%04x FSW=%04x [ST=%d] FTW=%02x MXCSR=%08x\n",

                    env->fpuc,

                    (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11,

                    env->fpstt,

                    fptag,

                    env->mxcsr);

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

#if defined(USE_X86LDOUBLE)

            union {

                long double d;

                struct {

                    uint64_t lower;

                    uint16_t upper;

                } l;

            } tmp;

            tmp.d = env->fpregs[i].d;

            cpu_fprintf(f, "FPR%d=%016" PRIx64 " %04x",

                        i, tmp.l.lower, tmp.l.upper);

#else

            cpu_fprintf(f, "FPR%d=%016" PRIx64,

                        i, env->fpregs[i].mmx.q);

#endif

            if ((i & 1) == 1)

                cpu_fprintf(f, "\n");

            else

                cpu_fprintf(f, " ");

        }

        if (env->hflags & HF_CS64_MASK)

            nb = 16;

        else

            nb = 8;

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

            cpu_fprintf(f, "XMM%02d=%08x%08x%08x%08x",

                        i,

                        env->xmm_regs[i].XMM_L(3),

                        env->xmm_regs[i].XMM_L(2),

                        env->xmm_regs[i].XMM_L(1),

                        env->xmm_regs[i].XMM_L(0));

            if ((i & 1) == 1)

                cpu_fprintf(f, "\n");

            else

                cpu_fprintf(f, " ");

        }

    }

}


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

                           uint32_t token, uint32_t nargs,

                           target_ulong args,

                           uint32_t nret, target_ulong rets)

{

    target_ulong id, start, r3;

    PowerPCCPU *cpu;

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

        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);

        return;

    }

    id = rtas_ld(args, 0);

    start = rtas_ld(args, 1);

    r3 = rtas_ld(args, 2);

    cpu = spapr_find_cpu(id);

    if (cpu != NULL) {

        CPUState *cs = CPU(cpu);

        CPUPPCState *env = &cpu->env;

        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);

        Error *local_err = NULL;

        if (!cs->halted) {

            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);

            return;

        }

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

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

         * new cpu enters */

        kvm_cpu_synchronize_state(cs);

        /* Set compatibility mode to match existing cpus */

        ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &local_err);

        if (local_err) {

            error_report_err(local_err);

            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);

            return;

        }

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

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

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

        env->nip = start;

        env->gpr[3] = r3;

        cs->halted = 0;

        spapr_cpu_set_endianness(cpu);

        spapr_cpu_update_tb_offset(cpu);

        qemu_cpu_kick(cs);

        rtas_st(rets, 0, RTAS_OUT_SUCCESS);

        return;

    }

    /* Didn't find a matching cpu */

    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);

}


void net_slirp_redir(Monitor *mon, const char *redir_str, const char *redir_opt2)

{

    struct slirp_config_str *config;

    if (!slirp_inited) {

        if (mon) {

            monitor_printf(mon, "user mode network stack not in use\n");

        } else {

            config = qemu_malloc(sizeof(*config));

            config->str = redir_str;

            config->next = slirp_redirs;

            slirp_redirs = config;

        }

        return;

    }

    if (!strcmp(redir_str, "remove")) {

        net_slirp_redir_rm(mon, redir_opt2);

        return;

    }

    slirp_redirection(mon, redir_str);

}


int ppc_hash64_handle_mmu_fault(PowerPCCPU *cpu, vaddr eaddr,

                                int rwx, int mmu_idx)

{

    CPUState *cs = CPU(cpu);

    CPUPPCState *env = &cpu->env;

    ppc_slb_t *slb;

    unsigned apshift;

    hwaddr ptex;

    ppc_hash_pte64_t pte;

    int pp_prot, amr_prot, prot;

    uint64_t new_pte1, dsisr;

    const int need_prot[] = {PAGE_READ, PAGE_WRITE, PAGE_EXEC};

    hwaddr raddr;

    assert((rwx == 0) || (rwx == 1) || (rwx == 2));

    /* Note on LPCR usage: 970 uses HID4, but our special variant

     * of store_spr copies relevant fields into env->spr[SPR_LPCR].

     * Similarily we filter unimplemented bits when storing into

     * LPCR depending on the MMU version. This code can thus just

     * use the LPCR "as-is".

     */

    /* 1. Handle real mode accesses */

    if (((rwx == 2) && (msr_ir == 0)) || ((rwx != 2) && (msr_dr == 0))) {

        /* Translation is supposedly "off"  */

        /* In real mode the top 4 effective address bits are (mostly) ignored */

        raddr = eaddr & 0x0FFFFFFFFFFFFFFFULL;

        /* In HV mode, add HRMOR if top EA bit is clear */

        if (msr_hv || !env->has_hv_mode) {

            if (!(eaddr >> 63)) {

                raddr |= env->spr[SPR_HRMOR];

            }

        } else {

            /* Otherwise, check VPM for RMA vs VRMA */

            if (env->spr[SPR_LPCR] & LPCR_VPM0) {

                slb = &env->vrma_slb;

                if (slb->sps) {

                    goto skip_slb_search;

                }

                /* Not much else to do here */

                cs->exception_index = POWERPC_EXCP_MCHECK;

                env->error_code = 0;

                return 1;

            } else if (raddr < env->rmls) {

                /* RMA. Check bounds in RMLS */

                raddr |= env->spr[SPR_RMOR];

            } else {

                /* The access failed, generate the approriate interrupt */

                if (rwx == 2) {

                    ppc_hash64_set_isi(cs, env, 0x08000000);

                } else {

                    dsisr = 0x08000000;

                    if (rwx == 1) {

                        dsisr |= 0x02000000;

                    }

                    ppc_hash64_set_dsi(cs, env, eaddr, dsisr);

                }

                return 1;

            }

        }

        tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,

                     PAGE_READ | PAGE_WRITE | PAGE_EXEC, mmu_idx,

                     TARGET_PAGE_SIZE);

        return 0;

    }

    /* 2. Translation is on, so look up the SLB */

    slb = slb_lookup(cpu, eaddr);

    if (!slb) {

        /* No entry found, check if in-memory segment tables are in use */

        if ((env->mmu_model & POWERPC_MMU_V3) && ppc64_use_proc_tbl(cpu)) {

            /* TODO - Unsupported */

            error_report("Segment Table Support Unimplemented");

            exit(1);

        }

        /* Segment still not found, generate the appropriate interrupt */

        if (rwx == 2) {

            cs->exception_index = POWERPC_EXCP_ISEG;

            env->error_code = 0;

        } else {

            cs->exception_index = POWERPC_EXCP_DSEG;

            env->error_code = 0;

            env->spr[SPR_DAR] = eaddr;

        }

        return 1;

    }

skip_slb_search:

    /* 3. Check for segment level no-execute violation */

    if ((rwx == 2) && (slb->vsid & SLB_VSID_N)) {

        ppc_hash64_set_isi(cs, env, 0x10000000);

        return 1;

    }

    /* 4. Locate the PTE in the hash table */

    ptex = ppc_hash64_htab_lookup(cpu, slb, eaddr, &pte, &apshift);

    if (ptex == -1) {

        dsisr = 0x40000000;

        if (rwx == 2) {

            ppc_hash64_set_isi(cs, env, dsisr);

        } else {

            if (rwx == 1) {

                dsisr |= 0x02000000;

            }

            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);

        }

        return 1;

    }

    qemu_log_mask(CPU_LOG_MMU,

                  "found PTE at index %08" HWADDR_PRIx "\n", ptex);

    /* 5. Check access permissions */

    pp_prot = ppc_hash64_pte_prot(cpu, slb, pte);

    amr_prot = ppc_hash64_amr_prot(cpu, pte);

    prot = pp_prot & amr_prot;

    if ((need_prot[rwx] & ~prot) != 0) {

        /* Access right violation */

        qemu_log_mask(CPU_LOG_MMU, "PTE access rejected\n");

        if (rwx == 2) {

            ppc_hash64_set_isi(cs, env, 0x08000000);

        } else {

            dsisr = 0;

            if (need_prot[rwx] & ~pp_prot) {

                dsisr |= 0x08000000;

            }

            if (rwx == 1) {

                dsisr |= 0x02000000;

            }

            if (need_prot[rwx] & ~amr_prot) {

                dsisr |= 0x00200000;

            }

            ppc_hash64_set_dsi(cs, env, eaddr, dsisr);

        }

        return 1;

    }

    qemu_log_mask(CPU_LOG_MMU, "PTE access granted !\n");

    /* 6. Update PTE referenced and changed bits if necessary */

    new_pte1 = pte.pte1 | HPTE64_R_R; /* set referenced bit */

    if (rwx == 1) {

        new_pte1 |= HPTE64_R_C; /* set changed (dirty) bit */

    } else {

        /* Treat the page as read-only for now, so that a later write

         * will pass through this function again to set the C bit */

        prot &= ~PAGE_WRITE;

    }

    if (new_pte1 != pte.pte1) {

        ppc_hash64_store_hpte(cpu, ptex, pte.pte0, new_pte1);

    }

    /* 7. Determine the real address from the PTE */

    raddr = deposit64(pte.pte1 & HPTE64_R_RPN, 0, apshift, eaddr);

    tlb_set_page(cs, eaddr & TARGET_PAGE_MASK, raddr & TARGET_PAGE_MASK,

                 prot, mmu_idx, 1ULL << apshift);

    return 0;

}


static void qxl_reset_surfaces(PCIQXLDevice *d)

{

    dprint(d, 1, "%s:\n", __FUNCTION__);

    d->mode = QXL_MODE_UNDEFINED;

    qemu_mutex_unlock_iothread();

    d->ssd.worker->destroy_surfaces(d->ssd.worker);

    qemu_mutex_lock_iothread();

    memset(&d->guest_surfaces.cmds, 0, sizeof(d->guest_surfaces.cmds));

}