build_madt(GArray *table_data, GArray *linker, PCMachineState *pcms)

{

    MachineClass *mc = MACHINE_GET_CLASS(pcms);

    CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(pcms));

    int madt_start = table_data->len;

    AcpiMultipleApicTable *madt;

    AcpiMadtIoApic *io_apic;

    AcpiMadtIntsrcovr *intsrcovr;

    AcpiMadtLocalNmi *local_nmi;

    int i;

    madt = acpi_data_push(table_data, sizeof *madt);

    madt->local_apic_address = cpu_to_le32(APIC_DEFAULT_ADDRESS);

    madt->flags = cpu_to_le32(1);

    for (i = 0; i < apic_ids->len; i++) {

        AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);

        int apic_id = apic_ids->cpus[i].arch_id;

        apic->type = ACPI_APIC_PROCESSOR;

        apic->length = sizeof(*apic);

        apic->processor_id = i;

        apic->local_apic_id = apic_id;

        if (apic_ids->cpus[i].cpu != NULL) {

            apic->flags = cpu_to_le32(1);

        } else {

            /* ACPI spec says that LAPIC entry for non present

             * CPU may be omitted from MADT or it must be marked

             * as disabled. However omitting non present CPU from

             * MADT breaks hotplug on linux. So possible CPUs

             * should be put in MADT but kept disabled.

             */

            apic->flags = cpu_to_le32(0);

        }

    }

    g_free(apic_ids);

    io_apic = acpi_data_push(table_data, sizeof *io_apic);

    io_apic->type = ACPI_APIC_IO;

    io_apic->length = sizeof(*io_apic);

#define ACPI_BUILD_IOAPIC_ID 0x0

    io_apic->io_apic_id = ACPI_BUILD_IOAPIC_ID;

    io_apic->address = cpu_to_le32(IO_APIC_DEFAULT_ADDRESS);

    io_apic->interrupt = cpu_to_le32(0);

    if (pcms->apic_xrupt_override) {

        intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);

        intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;

        intsrcovr->length = sizeof(*intsrcovr);

        intsrcovr->source = 0;

        intsrcovr->gsi    = cpu_to_le32(2);

        intsrcovr->flags  = cpu_to_le16(0); /* conforms to bus specifications */

    }

    for (i = 1; i < 16; i++) {

#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))

        if (!(ACPI_BUILD_PCI_IRQS & (1 << i))) {

            /* No need for a INT source override structure. */

            continue;

        }

        intsrcovr = acpi_data_push(table_data, sizeof *intsrcovr);

        intsrcovr->type   = ACPI_APIC_XRUPT_OVERRIDE;

        intsrcovr->length = sizeof(*intsrcovr);

        intsrcovr->source = i;

        intsrcovr->gsi    = cpu_to_le32(i);

        intsrcovr->flags  = cpu_to_le16(0xd); /* active high, level triggered */

    }

    local_nmi = acpi_data_push(table_data, sizeof *local_nmi);

    local_nmi->type         = ACPI_APIC_LOCAL_NMI;

    local_nmi->length       = sizeof(*local_nmi);

    local_nmi->processor_id = 0xff; /* all processors */

    local_nmi->flags        = cpu_to_le16(0);

    local_nmi->lint         = 1; /* ACPI_LINT1 */

    build_header(linker, table_data,

                 (void *)(table_data->data + madt_start), "APIC",

                 table_data->len - madt_start, 1, NULL, NULL);

}


static int ftp_write(URLContext *h, const unsigned char *buf, int size)

{

    int err;

    FTPContext *s = h->priv_data;

    int written;

    av_dlog(h, "ftp protocol write %d bytes\n", size);

    if (s->state == DISCONNECTED) {

        if ((err = ftp_connect_data_connection(h)) < 0)

            return err;

    }

    if (s->state == READY) {

        if ((err = ftp_store(s)) < 0)

            return err;

    }

    if (s->conn_data && s->state == UPLOADING) {

        written = ffurl_write(s->conn_data, buf, size);

        if (written > 0) {

            s->position += written;

            s->filesize = FFMAX(s->filesize, s->position);

        }

        return written;

    }

    av_log(h, AV_LOG_ERROR, "FTP write failed\n");

    return AVERROR(EIO);

}


static void integratorcm_write(void *opaque, target_phys_addr_t offset,

                               uint64_t value, unsigned size)

{

    integratorcm_state *s = (integratorcm_state *)opaque;

    switch (offset >> 2) {

    case 2: /* CM_OSC */

        if (s->cm_lock == 0xa05f)

            s->cm_osc = value;

        break;

    case 3: /* CM_CTRL */

        integratorcm_set_ctrl(s, value);

        break;

    case 5: /* CM_LOCK */

        s->cm_lock = value & 0xffff;

        break;

    case 7: /* CM_AUXOSC */

        if (s->cm_lock == 0xa05f)

            s->cm_auxosc = value;

        break;

    case 8: /* CM_SDRAM */

        s->cm_sdram = value;

        break;

    case 9: /* CM_INIT */

        /* ??? This can change the memory bus frequency.  */

        s->cm_init = value;

        break;

    case 12: /* CM_FLAGSS */

        s->cm_flags |= value;

        break;

    case 13: /* CM_FLAGSC */

        s->cm_flags &= ~value;

        break;

    case 14: /* CM_NVFLAGSS */

        s->cm_nvflags |= value;

        break;

    case 15: /* CM_NVFLAGSS */

        s->cm_nvflags &= ~value;

        break;

    case 18: /* CM_IRQ_ENSET */

        s->irq_enabled |= value;

        integratorcm_update(s);

        break;

    case 19: /* CM_IRQ_ENCLR */

        s->irq_enabled &= ~value;

        integratorcm_update(s);

        break;

    case 20: /* CM_SOFT_INTSET */

        s->int_level |= (value & 1);

        integratorcm_update(s);

        break;

    case 21: /* CM_SOFT_INTCLR */

        s->int_level &= ~(value & 1);

        integratorcm_update(s);

        break;

    case 26: /* CM_FIQ_ENSET */

        s->fiq_enabled |= value;

        integratorcm_update(s);

        break;

    case 27: /* CM_FIQ_ENCLR */

        s->fiq_enabled &= ~value;

        integratorcm_update(s);

        break;

    case 32: /* CM_VOLTAGE_CTL0 */

    case 33: /* CM_VOLTAGE_CTL1 */

    case 34: /* CM_VOLTAGE_CTL2 */

    case 35: /* CM_VOLTAGE_CTL3 */

        /* ??? Voltage control unimplemented.  */

        break;

    default:

        hw_error("integratorcm_write: Unimplemented offset 0x%x\n",

                 (int)offset);

        break;

    }

}


static int pci_vpb_map_irq(PCIDevice *d, int irq_num)

{

    PCIVPBState *s = container_of(d->bus, PCIVPBState, pci_bus);

    if (s->irq_mapping == PCI_VPB_IRQMAP_BROKEN) {

        /* Legacy broken IRQ mapping for compatibility with old and

         * buggy Linux guests

         */

        return irq_num;

    }

    /* Slot to IRQ mapping for RealView Platform Baseboard 926 backplane

     *      name    slot    IntA    IntB    IntC    IntD

     *      A       31      IRQ28   IRQ29   IRQ30   IRQ27

     *      B       30      IRQ27   IRQ28   IRQ29   IRQ30

     *      C       29      IRQ30   IRQ27   IRQ28   IRQ29

     * Slot C is for the host bridge; A and B the peripherals.

     * Our output irqs 0..3 correspond to the baseboard's 27..30.

     *

     * This mapping function takes account of an oddity in the PB926

     * board wiring, where the FPGA's P_nINTA input is connected to

     * the INTB connection on the board PCI edge connector, P_nINTB

     * is connected to INTC, and so on, so everything is one number

     * further round from where you might expect.

     */

    return pci_swizzle_map_irq_fn(d, irq_num + 2);

}


static uint32_t omap_l4_io_readh(void *opaque, target_phys_addr_t addr)

{

    unsigned int i = (addr - OMAP2_L4_BASE) >> TARGET_PAGE_BITS;

    return omap_l4_io_readh_fn[i](omap_l4_io_opaque[i], addr);

}


static void test_keyval_parse_list(void)

{

    Error *err = NULL;

    QDict *qdict, *sub_qdict;

    /* Root can't be a list */

    qdict = keyval_parse("0=1", NULL, &err);

    error_free_or_abort(&err);

    g_assert(!qdict);

    /* List elements need not be in order */

    qdict = keyval_parse("list.0=null,list.2=zwei,list.1=eins",

                         NULL, &error_abort);

    g_assert_cmpint(qdict_size(qdict), ==, 1);

    check_list012(qdict_get_qlist(qdict, "list"));

    QDECREF(qdict);

    /* Multiple indexes, last one wins */

    qdict = keyval_parse("list.1=goner,list.0=null,list.1=eins,list.2=zwei",

                         NULL, &error_abort);

    g_assert_cmpint(qdict_size(qdict), ==, 1);

    check_list012(qdict_get_qlist(qdict, "list"));

    QDECREF(qdict);

    /* List at deeper nesting */

    qdict = keyval_parse("a.list.1=eins,a.list.0=null,a.list.2=zwei",

                         NULL, &error_abort);

    g_assert_cmpint(qdict_size(qdict), ==, 1);

    sub_qdict = qdict_get_qdict(qdict, "a");

    g_assert_cmpint(qdict_size(sub_qdict), ==, 1);

    check_list012(qdict_get_qlist(sub_qdict, "list"));

    QDECREF(qdict);

    /* Inconsistent dotted keys: both list and dictionary */

    qdict = keyval_parse("a.b.c=1,a.b.0=2", NULL, &err);

    error_free_or_abort(&err);

    g_assert(!qdict);

    qdict = keyval_parse("a.0.c=1,a.b.c=2", NULL, &err);

    error_free_or_abort(&err);

    g_assert(!qdict);

    /* Missing list indexes */

    qdict = keyval_parse("list.2=lonely", NULL, &err);

    error_free_or_abort(&err);

    g_assert(!qdict);

    qdict = keyval_parse("list.0=null,list.2=eins,list.02=zwei", NULL, &err);

    error_free_or_abort(&err);

    g_assert(!qdict);

}


static int ds1338_recv(I2CSlave *i2c)

{

    DS1338State *s = FROM_I2C_SLAVE(DS1338State, i2c);

    uint8_t res;

    res  = s->nvram[s->ptr];

    s->ptr = (s->ptr + 1) & 0xff;

    return res;

}


size_t qsb_get_length(const QEMUSizedBuffer *qsb)

{

    return qsb->used;

}


static int udp_write(URLContext *h, const uint8_t *buf, int size)

{

    UDPContext *s = h->priv_data;

    int ret;

#if HAVE_PTHREAD_CANCEL

    if (s->fifo) {

        uint8_t tmp[4];

        pthread_mutex_lock(&s->mutex);

        /*

          Return error if last tx failed.

          Here we can't know on which packet error was, but it needs to know that error exists.

        */

        if (s->circular_buffer_error<0) {

            int err=s->circular_buffer_error;

            s->circular_buffer_error=0;

            pthread_mutex_unlock(&s->mutex);

            return err;

        }

        if(av_fifo_space(s->fifo) < size + 4) {

            /* What about a partial packet tx ? */

            pthread_mutex_unlock(&s->mutex);

            return AVERROR(ENOMEM);

        }

        AV_WL32(tmp, size);

        av_fifo_generic_write(s->fifo, tmp, 4, NULL); /* size of packet */

        av_fifo_generic_write(s->fifo, (uint8_t *)buf, size, NULL); /* the data */

        pthread_cond_signal(&s->cond);

        pthread_mutex_unlock(&s->mutex);

        return size;

    }

#endif

    if (!(h->flags & AVIO_FLAG_NONBLOCK)) {

        ret = ff_network_wait_fd(s->udp_fd, 1);

        if (ret < 0)

            return ret;

    }

    if (!s->is_connected) {

        ret = sendto (s->udp_fd, buf, size, 0,

                      (struct sockaddr *) &s->dest_addr,

                      s->dest_addr_len);

    } else

        ret = send(s->udp_fd, buf, size, 0);

    return ret < 0 ? ff_neterrno() : ret;

}


static void compute_frame_duration(int *pnum, int *pden, AVStream *st,

                                   AVCodecParserContext *pc, AVPacket *pkt)

{

    int frame_size;

    *pnum = 0;

    *pden = 0;

    switch(st->codec->codec_type) {

    case AVMEDIA_TYPE_VIDEO:

        if (st->r_frame_rate.num) {

            *pnum = st->r_frame_rate.den;

            *pden = st->r_frame_rate.num;

        } else if(st->time_base.num*1000LL > st->time_base.den) {

            *pnum = st->time_base.num;

            *pden = st->time_base.den;

        }else if(st->codec->time_base.num*1000LL > st->codec->time_base.den){

            *pnum = st->codec->time_base.num;

            *pden = st->codec->time_base.den;

            if (pc && pc->repeat_pict) {

                *pnum = (*pnum) * (1 + pc->repeat_pict);

            }

            //If this codec can be interlaced or progressive then we need a parser to compute duration of a packet

            //Thus if we have no parser in such case leave duration undefined.

            if(st->codec->ticks_per_frame>1 && !pc){

                *pnum = *pden = 0;

            }

        }

        break;

    case AVMEDIA_TYPE_AUDIO:

        frame_size = get_audio_frame_size(st->codec, pkt->size, 0);

        if (frame_size <= 0 || st->codec->sample_rate <= 0)

            break;

        *pnum = frame_size;

        *pden = st->codec->sample_rate;

        break;

    default:

        break;

    }

}


static int ram_save_live(Monitor *mon, QEMUFile *f, int stage, void *opaque)

{

    ram_addr_t addr;

    uint64_t bytes_transferred_last;

    double bwidth = 0;

    uint64_t expected_time = 0;

    if (stage < 0) {

        cpu_physical_memory_set_dirty_tracking(0);

        return 0;

    }

    if (cpu_physical_sync_dirty_bitmap(0, TARGET_PHYS_ADDR_MAX) != 0) {

        qemu_file_set_error(f);

        return 0;

    }

    if (stage == 1) {

        bytes_transferred = 0;

        /* Make sure all dirty bits are set */

        for (addr = 0; addr < last_ram_offset; addr += TARGET_PAGE_SIZE) {

            if (!cpu_physical_memory_get_dirty(addr, MIGRATION_DIRTY_FLAG))

                cpu_physical_memory_set_dirty(addr);

        }

        /* Enable dirty memory tracking */

        cpu_physical_memory_set_dirty_tracking(1);

        qemu_put_be64(f, last_ram_offset | RAM_SAVE_FLAG_MEM_SIZE);

    }

    bytes_transferred_last = bytes_transferred;

    bwidth = qemu_get_clock_ns(rt_clock);

    while (!qemu_file_rate_limit(f)) {

        int ret;

        ret = ram_save_block(f);

        bytes_transferred += ret * TARGET_PAGE_SIZE;

        if (ret == 0) /* no more blocks */

            break;

    }

    bwidth = qemu_get_clock_ns(rt_clock) - bwidth;

    bwidth = (bytes_transferred - bytes_transferred_last) / bwidth;

    /* if we haven't transferred anything this round, force expected_time to a

     * a very high value, but without crashing */

    if (bwidth == 0)

        bwidth = 0.000001;

    /* try transferring iterative blocks of memory */

    if (stage == 3) {

        /* flush all remaining blocks regardless of rate limiting */

        while (ram_save_block(f) != 0) {

            bytes_transferred += TARGET_PAGE_SIZE;

        }

        cpu_physical_memory_set_dirty_tracking(0);

    }

    qemu_put_be64(f, RAM_SAVE_FLAG_EOS);

    expected_time = ram_save_remaining() * TARGET_PAGE_SIZE / bwidth;

    return (stage == 2) && (expected_time <= migrate_max_downtime());

}


static int zerocodec_decode_frame(AVCodecContext *avctx, void *data,

                                  int *data_size, AVPacket *avpkt)

{

    ZeroCodecContext *zc = avctx->priv_data;

    AVFrame *pic         = avctx->coded_frame;

    AVFrame *prev_pic    = &zc->previous_frame;

    z_stream *zstream    = &zc->zstream;

    uint8_t *prev, *dst;

    int i, j, zret;

    pic->reference = 3;

    if (avctx->get_buffer(avctx, pic) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n");

        return AVERROR(ENOMEM);

    }

    zret = inflateReset(zstream);

    if (zret != Z_OK) {

        av_log(avctx, AV_LOG_ERROR, "Could not reset inflate: %d\n", zret);

        return AVERROR(EINVAL);

    }

    zstream->next_in  = avpkt->data;

    zstream->avail_in = avpkt->size;

    prev = prev_pic->data[0];

    dst  = pic->data[0];

    /**

     * ZeroCodec has very simple interframe compression. If a value

     * is the same as the previous frame, set it to 0.

     */

    if (avpkt->flags & AV_PKT_FLAG_KEY) {

        pic->key_frame = 1;

        pic->pict_type = AV_PICTURE_TYPE_I;

        for (i = 0; i < avctx->height; i++) {

            zstream->next_out  = dst;

            zstream->avail_out = avctx->width << 1;

            zret = inflate(zstream, Z_SYNC_FLUSH);

            if (zret != Z_OK && zret != Z_STREAM_END) {

                av_log(avctx, AV_LOG_ERROR,

                       "Inflate failed with return code: %d\n", zret);

                return AVERROR(EINVAL);

            }

            dst += pic->linesize[0];

        }

    } else {

        pic->key_frame = 0;

        pic->pict_type = AV_PICTURE_TYPE_P;

        for (i = 0; i < avctx->height; i++) {

            zstream->next_out  = dst;

            zstream->avail_out = avctx->width << 1;

            zret = inflate(zstream, Z_SYNC_FLUSH);

            if (zret != Z_OK && zret != Z_STREAM_END) {

                av_log(avctx, AV_LOG_ERROR,

                       "Inflate failed with return code: %d\n", zret);

                return AVERROR(EINVAL);

            }

            for (j = 0; j < avctx->width << 1; j++)

                dst[j] += prev[j] & -!dst[j];

            prev += prev_pic->linesize[0];

            dst  += pic->linesize[0];

        }

    }

    /* Release the previous buffer if need be */

    if (prev_pic->data[0])

        avctx->release_buffer(avctx, prev_pic);

    /* Store the previouse frame for use later */

    *prev_pic = *pic;

    *data_size       = sizeof(AVFrame);

    *(AVFrame *)data = *pic;

    return avpkt->size;

}


static void g364fb_screen_dump(void *opaque, const char *filename, bool cswitch,

                               Error **errp)

{

    G364State *s = opaque;

    int ret, y, x;

    uint8_t index;

    uint8_t *data_buffer;

    FILE *f;

    qemu_flush_coalesced_mmio_buffer();

    if (s->depth != 8) {

        error_setg(errp, "g364: unknown guest depth %d", s->depth);

        return;

    }

    f = fopen(filename, "wb");

    if (!f) {

        error_setg(errp, "failed to open file '%s': %s", filename,

                   strerror(errno));

        return;

    }

    if (s->ctla & CTLA_FORCE_BLANK) {

        /* blank screen */

        ret = fprintf(f, "P4\n%d %d\n", s->width, s->height);

        if (ret < 0) {

            goto write_err;

        }

        for (y = 0; y < s->height; y++)

            for (x = 0; x < s->width; x++) {

                ret = fputc(0, f);

                if (ret == EOF) {

                    goto write_err;

                }

            }

    } else {

        data_buffer = s->vram + s->top_of_screen;

        ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);

        if (ret < 0) {

            goto write_err;

        }

        for (y = 0; y < s->height; y++)

            for (x = 0; x < s->width; x++, data_buffer++) {

                index = *data_buffer;

                ret = fputc(s->color_palette[index][0], f);

                if (ret == EOF) {

                    goto write_err;

                }

                ret = fputc(s->color_palette[index][1], f);

                if (ret == EOF) {

                    goto write_err;

                }

                ret = fputc(s->color_palette[index][2], f);

                if (ret == EOF) {

                    goto write_err;

                }

        }

    }

out:

    fclose(f);

    return;

write_err:

    error_setg(errp, "failed to write to file '%s': %s", filename,

               strerror(errno));

    unlink(filename);

    goto out;

}


float64 helper_fsmuld(CPUSPARCState *env, float32 src1, float32 src2)

{

    float64 ret;

    clear_float_exceptions(env);

    ret = float64_mul(float32_to_float64(src1, &env->fp_status),

                      float32_to_float64(src2, &env->fp_status),

                      &env->fp_status);

    check_ieee_exceptions(env);

    return ret;

}


target_phys_addr_t omap_l4_attach(struct omap_target_agent_s *ta, int region,

                int iotype)

{

    target_phys_addr_t base;

    ssize_t size;

#ifdef L4_MUX_HACK

    int i;

#endif

    if (region < 0 || region >= ta->regions) {

        fprintf(stderr, "%s: bad io region (%i)\n", __FUNCTION__, region);

        exit(-1);

    }

    base = ta->bus->base + ta->start[region].offset;

    size = ta->start[region].size;

    if (iotype) {

#ifndef L4_MUX_HACK

        cpu_register_physical_memory(base, size, iotype);

#else

        cpu_register_physical_memory(base, size, omap_cpu_io_entry);

        i = (base - ta->bus->base) / TARGET_PAGE_SIZE;

        for (; size > 0; size -= TARGET_PAGE_SIZE, i ++) {

            omap_l4_io_readb_fn[i] = omap_l4_io_entry[iotype].mem_read[0];

            omap_l4_io_readh_fn[i] = omap_l4_io_entry[iotype].mem_read[1];

            omap_l4_io_readw_fn[i] = omap_l4_io_entry[iotype].mem_read[2];

            omap_l4_io_writeb_fn[i] = omap_l4_io_entry[iotype].mem_write[0];

            omap_l4_io_writeh_fn[i] = omap_l4_io_entry[iotype].mem_write[1];

            omap_l4_io_writew_fn[i] = omap_l4_io_entry[iotype].mem_write[2];

            omap_l4_io_opaque[i] = omap_l4_io_entry[iotype].opaque;

        }

#endif

    }

    return base;

}


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

                        target_sigset_t *set, CPUMIPSState *regs)

{

    struct sigframe *frame;

    abi_ulong frame_addr;

    int i;

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

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

	goto give_sigsegv;

    install_sigtramp(frame->sf_code, TARGET_NR_sigreturn);

    setup_sigcontext(regs, &frame->sf_sc);

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

	if(__put_user(set->sig[i], &frame->sf_mask.sig[i]))

	    goto give_sigsegv;

    }

    /*

    * Arguments to signal handler:

    *

    *   a0 = signal number

    *   a1 = 0 (should be cause)

    *   a2 = pointer to struct sigcontext

    *

    * $25 and PC point to the signal handler, $29 points to the

    * struct sigframe.

    */

    regs->active_tc.gpr[ 4] = sig;

    regs->active_tc.gpr[ 5] = 0;

    regs->active_tc.gpr[ 6] = frame_addr + offsetof(struct sigframe, sf_sc);

    regs->active_tc.gpr[29] = frame_addr;

    regs->active_tc.gpr[31] = frame_addr + offsetof(struct sigframe, sf_code);

    /* The original kernel code sets CP0_EPC to the handler

    * since it returns to userland using eret

    * we cannot do this here, and we must set PC directly */

    regs->active_tc.PC = regs->active_tc.gpr[25] = ka->_sa_handler;

    mips_set_hflags_isa_mode_from_pc(regs);

    unlock_user_struct(frame, frame_addr, 1);

    return;

give_sigsegv:

    unlock_user_struct(frame, frame_addr, 1);

    force_sig(TARGET_SIGSEGV/*, current*/);

}


int update_dimensions(VP8Context *s, int width, int height, int is_vp7)

{

    AVCodecContext *avctx = s->avctx;

    int i, ret;

    if (width  != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||

        height != s->avctx->height) {

        vp8_decode_flush_impl(s->avctx, 1);

        ret = ff_set_dimensions(s->avctx, width, height);

        if (ret < 0)

            return ret;

    }

    s->mb_width  = (s->avctx->coded_width  + 15) / 16;

    s->mb_height = (s->avctx->coded_height + 15) / 16;

    s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE &&

                   FFMIN(s->num_coeff_partitions, avctx->thread_count) > 1;

    if (!s->mb_layout) { // Frame threading and one thread

        s->macroblocks_base       = av_mallocz((s->mb_width + s->mb_height * 2 + 1) *

                                               sizeof(*s->macroblocks));

        s->intra4x4_pred_mode_top = av_mallocz(s->mb_width * 4);

    } else // Sliced threading

        s->macroblocks_base = av_mallocz((s->mb_width + 2) * (s->mb_height + 2) *

                                         sizeof(*s->macroblocks));

    s->top_nnz     = av_mallocz(s->mb_width * sizeof(*s->top_nnz));

    s->top_border  = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border));

    s->thread_data = av_mallocz(MAX_THREADS * sizeof(VP8ThreadData));

    if (!s->macroblocks_base || !s->top_nnz || !s->top_border ||

        !s->thread_data || (!s->intra4x4_pred_mode_top && !s->mb_layout)) {

        free_buffers(s);

        return AVERROR(ENOMEM);

    }

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

        s->thread_data[i].filter_strength =

            av_mallocz(s->mb_width * sizeof(*s->thread_data[0].filter_strength));

        if (!s->thread_data[i].filter_strength) {

            free_buffers(s);

            return AVERROR(ENOMEM);

        }

#if HAVE_THREADS

        pthread_mutex_init(&s->thread_data[i].lock, NULL);

        pthread_cond_init(&s->thread_data[i].cond, NULL);

#endif

    }

    s->macroblocks = s->macroblocks_base + 1;

    return 0;

}


static int mpeg_decode_frame(AVCodecContext *avctx,

                             void *data, int *data_size,

                             uint8_t *buf, int buf_size)

{

    Mpeg1Context *s = avctx->priv_data;

    const uint8_t *buf_end;

    const uint8_t *buf_ptr;

    uint32_t start_code;

    int ret, input_size;

    AVFrame *picture = data;

    MpegEncContext *s2 = &s->mpeg_enc_ctx;

    dprintf(avctx, "fill_buffer\n");

    if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) {

        /* special case for last picture */

        if (s2->low_delay==0 && s2->next_picture_ptr) {

            *picture= *(AVFrame*)s2->next_picture_ptr;

            s2->next_picture_ptr= NULL;

            *data_size = sizeof(AVFrame);

        }

        return 0;

    }

    if(s2->flags&CODEC_FLAG_TRUNCATED){

        int next= ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size);

        if( ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )

            return buf_size;

    }

    buf_ptr = buf;

    buf_end = buf + buf_size;

#if 0

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

        s->repeat_field++;

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

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

        if (avctx->flags & CODEC_FLAG_REPEAT_FIELD) {

            *data_size = sizeof(AVPicture);

            goto the_end;

        }

    }

#endif

    if(s->mpeg_enc_ctx_allocated==0 && avctx->codec_tag == ff_get_fourcc("VCR2"))

        vcr2_init_sequence(avctx);

    s->slice_count= 0;

    for(;;) {

        /* find start next code */

        start_code = -1;

        buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code);

        if (start_code > 0x1ff){

            if(s2->pict_type != B_TYPE || avctx->skip_frame <= AVDISCARD_DEFAULT){

                if(avctx->thread_count > 1){

                    int i;

                    avctx->execute(avctx, slice_decode_thread,  (void**)&(s2->thread_context[0]), NULL, s->slice_count);

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

                        s2->error_count += s2->thread_context[i]->error_count;

                }

                if (slice_end(avctx, picture)) {

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

                        *data_size = sizeof(AVPicture);

                }

            }

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

        }

        input_size = buf_end - buf_ptr;

        if(avctx->debug & FF_DEBUG_STARTCODE){

            av_log(avctx, AV_LOG_DEBUG, "%3X at %zd left %d\n", start_code, buf_ptr-buf, input_size);

        }

        /* prepare data for next start code */

        switch(start_code) {

        case SEQ_START_CODE:

            mpeg1_decode_sequence(avctx, buf_ptr,

                                    input_size);

            break;

        case PICTURE_START_CODE:

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

            mpeg1_decode_picture(avctx,

                                    buf_ptr, input_size);

            break;

        case EXT_START_CODE:

            mpeg_decode_extension(avctx,

                                    buf_ptr, input_size);

            break;

        case USER_START_CODE:

            mpeg_decode_user_data(avctx,

                                    buf_ptr, input_size);

            break;

        case GOP_START_CODE:

            s2->first_field=0;

            mpeg_decode_gop(avctx,

                                    buf_ptr, input_size);

            break;

        default:

            if (start_code >= SLICE_MIN_START_CODE &&

                start_code <= SLICE_MAX_START_CODE) {

                int mb_y= start_code - SLICE_MIN_START_CODE;

                if(s2->last_picture_ptr==NULL){

                /* Skip B-frames if we do not have reference frames. */

                    if(s2->pict_type==B_TYPE) break;

                /* Skip P-frames if we do not have reference frame no valid header. */

//                    if(s2->pict_type==P_TYPE && s2->first_field && !s2->first_slice) break;

                }

                /* Skip B-frames if we are in a hurry. */

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

                if(  (avctx->skip_frame >= AVDISCARD_NONREF && s2->pict_type==B_TYPE)

                    ||(avctx->skip_frame >= AVDISCARD_NONKEY && s2->pict_type!=I_TYPE)

                    || avctx->skip_frame >= AVDISCARD_ALL)

                    break;

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

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

                if (!s->mpeg_enc_ctx_allocated) break;

                if(s2->codec_id == CODEC_ID_MPEG2VIDEO){

                    if(mb_y < avctx->skip_top || mb_y >= s2->mb_height - avctx->skip_bottom)

                        break;

                }

                if(s2->first_slice){

                    s2->first_slice=0;

                            if(mpeg_field_start(s2) < 0)

                        return -1;

                    }

                if(!s2->current_picture_ptr){

                    av_log(avctx, AV_LOG_ERROR, "current_picture not initialized\n");

                    return -1;

                }

                if(avctx->thread_count > 1){

                    int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count;

                    if(threshold <= mb_y){

                        MpegEncContext *thread_context= s2->thread_context[s->slice_count];

                        thread_context->start_mb_y= mb_y;

                        thread_context->end_mb_y  = s2->mb_height;

                        if(s->slice_count){

                            s2->thread_context[s->slice_count-1]->end_mb_y= mb_y;

                            ff_update_duplicate_context(thread_context, s2);

                        }

                        init_get_bits(&thread_context->gb, buf_ptr, input_size*8);

                        s->slice_count++;

                    }

                    buf_ptr += 2; //FIXME add minimum num of bytes per slice

                }else{

                    ret = mpeg_decode_slice(s, mb_y, &buf_ptr, input_size);

                    emms_c();

                    if(ret < 0){

                        if(s2->resync_mb_x>=0 && s2->resync_mb_y>=0)

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

                    }else{

                        ff_er_add_slice(s2, s2->resync_mb_x, s2->resync_mb_y, s2->mb_x-1, s2->mb_y, AC_END|DC_END|MV_END);

                    }

                }

            }

            break;

        }

    }

}


static void pci_msix_write(void *opaque, hwaddr addr,

                           uint64_t val, unsigned size)

{

    XenPCIPassthroughState *s = opaque;

    XenPTMSIX *msix = s->msix;

    XenPTMSIXEntry *entry;

    int entry_nr, offset;

    entry_nr = addr / PCI_MSIX_ENTRY_SIZE;

    if (entry_nr < 0 || entry_nr >= msix->total_entries) {

        XEN_PT_ERR(&s->dev, "asked MSI-X entry '%i' invalid!\n", entry_nr);

        return;

    }

    entry = &msix->msix_entry[entry_nr];

    offset = addr % PCI_MSIX_ENTRY_SIZE;

    if (offset != PCI_MSIX_ENTRY_VECTOR_CTRL) {

        const volatile uint32_t *vec_ctrl;

        if (get_entry_value(entry, offset) == val

            && entry->pirq != XEN_PT_UNASSIGNED_PIRQ) {

            return;

        }

        /*

         * If Xen intercepts the mask bit access, entry->vec_ctrl may not be

         * up-to-date. Read from hardware directly.

         */

        vec_ctrl = s->msix->phys_iomem_base + entry_nr * PCI_MSIX_ENTRY_SIZE

            + PCI_MSIX_ENTRY_VECTOR_CTRL;

        if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {

            XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is"

                       " already enabled.\n", entry_nr);

            return;

        }

        entry->updated = true;

    }

    set_entry_value(entry, offset, val);

    if (offset == PCI_MSIX_ENTRY_VECTOR_CTRL) {

        if (msix->enabled && !(val & PCI_MSIX_ENTRY_CTRL_MASKBIT)) {

            xen_pt_msix_update_one(s, entry_nr);

        }

    }

}


static void seg_free_context(SegmentContext *seg)

{

    avio_closep(&seg->pb);

    avformat_free_context(seg->avf);

    seg->avf = NULL;

}


static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output)

{

    AVSubtitle subtitle;

    int i, ret = avcodec_decode_subtitle2(ist->dec_ctx,

                                          &subtitle, got_output, pkt);

    check_decode_result(got_output, ret);

    if (ret < 0 || !*got_output) {

        if (!pkt->size)

            sub2video_flush(ist);

        return ret;

    }

    if (ist->fix_sub_duration) {

        int end = 1;

        if (ist->prev_sub.got_output) {

            end = av_rescale(subtitle.pts - ist->prev_sub.subtitle.pts,

                             1000, AV_TIME_BASE);

            if (end < ist->prev_sub.subtitle.end_display_time) {

                av_log(ist->dec_ctx, AV_LOG_DEBUG,

                       "Subtitle duration reduced from %d to %d%s\n",

                       ist->prev_sub.subtitle.end_display_time, end,

                       end <= 0 ? ", dropping it" : "");

                ist->prev_sub.subtitle.end_display_time = end;

            }

        }

        FFSWAP(int,        *got_output, ist->prev_sub.got_output);

        FFSWAP(int,        ret,         ist->prev_sub.ret);

        FFSWAP(AVSubtitle, subtitle,    ist->prev_sub.subtitle);

        if (end <= 0)

            goto out;

    }

    if (!*got_output)

        return ret;

    sub2video_update(ist, &subtitle);

    if (!subtitle.num_rects)

        goto out;

    ist->frames_decoded++;

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

        OutputStream *ost = output_streams[i];

        if (!check_output_constraints(ist, ost) || !ost->encoding_needed

            || ost->enc->type != AVMEDIA_TYPE_SUBTITLE)

            continue;

        do_subtitle_out(output_files[ost->file_index]->ctx, ost, ist, &subtitle);

    }

out:

    avsubtitle_free(&subtitle);

    return ret;

}


static void tap_set_sndbuf(TAPState *s, const char *sndbuf_str, Monitor *mon)

{

    if (sndbuf_str) {

        config_error(mon, "No '-net tap,sndbuf=<nbytes>' support available\n");

    }

}


static uint64_t error_mem_read(void *opaque, hwaddr addr,

                               unsigned size)

{

    abort();

}


static int yuv4_read_header(AVFormatContext *s, AVFormatParameters *ap)

{

    char header[MAX_YUV4_HEADER+10];  // Include headroom for the longest option

    char *tokstart,*tokend,*header_end;

    int i;

    ByteIOContext *pb = s->pb;

    int width=-1, height=-1, raten=0, rated=0, aspectn=0, aspectd=0;

    enum PixelFormat pix_fmt=PIX_FMT_NONE,alt_pix_fmt=PIX_FMT_NONE;

    enum AVChromaLocation chroma_sample_location = AVCHROMA_LOC_UNSPECIFIED;

    AVStream *st;

    struct frame_attributes *s1 = s->priv_data;

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

        header[i] = get_byte(pb);

        if (header[i] == '\n') {

            header[i+1] = 0x20;  // Add a space after last option. Makes parsing "444" vs "444alpha" easier.

            header[i+2] = 0;

            break;

        }

    }

    if (i == MAX_YUV4_HEADER) return -1;

    if (strncmp(header, Y4M_MAGIC, strlen(Y4M_MAGIC))) return -1;

    s1->interlaced_frame = 0;

    s1->top_field_first = 0;

    header_end = &header[i+1]; // Include space

    for(tokstart = &header[strlen(Y4M_MAGIC) + 1]; tokstart < header_end; tokstart++) {

        if (*tokstart==0x20) continue;

        switch (*tokstart++) {

        case 'W': // Width. Required.

            width = strtol(tokstart, &tokend, 10);

            tokstart=tokend;

            break;

        case 'H': // Height. Required.

            height = strtol(tokstart, &tokend, 10);

            tokstart=tokend;

            break;

        case 'C': // Color space

            if (strncmp("420jpeg",tokstart,7)==0) {

                pix_fmt = PIX_FMT_YUV420P;

                chroma_sample_location = AVCHROMA_LOC_CENTER;

            } else if (strncmp("420mpeg2",tokstart,8)==0) {

                pix_fmt = PIX_FMT_YUV420P;

                chroma_sample_location = AVCHROMA_LOC_LEFT;

            } else if (strncmp("420paldv", tokstart, 8)==0) {

                pix_fmt = PIX_FMT_YUV420P;

                chroma_sample_location = AVCHROMA_LOC_TOPLEFT;

            } else if (strncmp("411", tokstart, 3)==0)

                pix_fmt = PIX_FMT_YUV411P;

            else if (strncmp("422", tokstart, 3)==0)

                pix_fmt = PIX_FMT_YUV422P;

            else if (strncmp("444alpha", tokstart, 8)==0) {

                av_log(s, AV_LOG_ERROR, "Cannot handle 4:4:4:4 YUV4MPEG stream.\n");

                return -1;

            } else if (strncmp("444", tokstart, 3)==0)

                pix_fmt = PIX_FMT_YUV444P;

            else if (strncmp("mono",tokstart, 4)==0) {

                pix_fmt = PIX_FMT_GRAY8;

            } else {

                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains an unknown pixel format.\n");

                return -1;

            }

            while(tokstart<header_end&&*tokstart!=0x20) tokstart++;

            break;

        case 'I': // Interlace type

            switch (*tokstart++){

            case '?':

                break;

            case 'p':

                s1->interlaced_frame=0;

                break;

            case 't':

                s1->interlaced_frame=1;

                s1->top_field_first=1;

                break;

            case 'b':

                s1->interlaced_frame=1;

                s1->top_field_first=0;

                break;

            case 'm':

                av_log(s, AV_LOG_ERROR, "YUV4MPEG stream contains mixed interlaced and non-interlaced frames.\n");

                return -1;

            default:

                av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");

                return -1;

            }

            break;

        case 'F': // Frame rate

            sscanf(tokstart,"%d:%d",&raten,&rated); // 0:0 if unknown

            while(tokstart<header_end&&*tokstart!=0x20) tokstart++;

            break;

        case 'A': // Pixel aspect

            sscanf(tokstart,"%d:%d",&aspectn,&aspectd); // 0:0 if unknown

            while(tokstart<header_end&&*tokstart!=0x20) tokstart++;

            break;

        case 'X': // Vendor extensions

            if (strncmp("YSCSS=",tokstart,6)==0) {

                // Older nonstandard pixel format representation

                tokstart+=6;

                if (strncmp("420JPEG",tokstart,7)==0)

                    alt_pix_fmt=PIX_FMT_YUV420P;

                else if (strncmp("420MPEG2",tokstart,8)==0)

                    alt_pix_fmt=PIX_FMT_YUV420P;

                else if (strncmp("420PALDV",tokstart,8)==0)

                    alt_pix_fmt=PIX_FMT_YUV420P;

                else if (strncmp("411",tokstart,3)==0)

                    alt_pix_fmt=PIX_FMT_YUV411P;

                else if (strncmp("422",tokstart,3)==0)

                    alt_pix_fmt=PIX_FMT_YUV422P;

                else if (strncmp("444",tokstart,3)==0)

                    alt_pix_fmt=PIX_FMT_YUV444P;

            }

            while(tokstart<header_end&&*tokstart!=0x20) tokstart++;

            break;

        }

    }

    if ((width == -1) || (height == -1)) {

        av_log(s, AV_LOG_ERROR, "YUV4MPEG has invalid header.\n");

        return -1;

    }

    if (pix_fmt == PIX_FMT_NONE) {

        if (alt_pix_fmt == PIX_FMT_NONE)

            pix_fmt = PIX_FMT_YUV420P;

        else

            pix_fmt = alt_pix_fmt;

    }

    if (raten == 0 && rated == 0) {

        // Frame rate unknown

        raten = 25;

        rated = 1;

    }

    if (aspectn == 0 && aspectd == 0) {

        // Pixel aspect unknown

        aspectd = 1;

    }

    st = av_new_stream(s, 0);

    if(!st)

        return AVERROR(ENOMEM);

    st->codec->width = width;

    st->codec->height = height;

    av_reduce(&raten, &rated, raten, rated, (1UL<<31)-1);

    av_set_pts_info(st, 64, rated, raten);

    st->codec->pix_fmt = pix_fmt;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;

    st->codec->codec_id = CODEC_ID_RAWVIDEO;

    st->sample_aspect_ratio= (AVRational){aspectn, aspectd};

    st->codec->chroma_sample_location = chroma_sample_location;

    return 0;

}


static void timer_del_locked(QEMUTimerList *timer_list, QEMUTimer *ts)

{

    QEMUTimer **pt, *t;

    ts->expire_time = -1;

    pt = &timer_list->active_timers;

    for(;;) {

        t = *pt;

        if (!t)

            break;

        if (t == ts) {

            *pt = t->next;

            break;

        }

        pt = &t->next;

    }

}


static void handle_sys(DisasContext *s, uint32_t insn, unsigned int l,

                       unsigned int op1, unsigned int op2,

                       unsigned int crn, unsigned int crm, unsigned int rt)

{

    unsupported_encoding(s, insn);

}


void axisdev88_init(MachineState *machine)

{

    ram_addr_t ram_size = machine->ram_size;

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    CRISCPU *cpu;

    CPUCRISState *env;

    DeviceState *dev;

    SysBusDevice *s;

    DriveInfo *nand;

    qemu_irq irq[30], nmi[2];

    void *etraxfs_dmac;

    struct etraxfs_dma_client *dma_eth;

    int i;

    MemoryRegion *address_space_mem = get_system_memory();

    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);

    MemoryRegion *phys_intmem = g_new(MemoryRegion, 1);

    /* init CPUs */

    if (cpu_model == NULL) {

        cpu_model = "crisv32";

    }

    cpu = cpu_cris_init(cpu_model);

    env = &cpu->env;

    /* allocate RAM */

    memory_region_init_ram(phys_ram, NULL, "axisdev88.ram", ram_size,

                           &error_abort);

    vmstate_register_ram_global(phys_ram);

    memory_region_add_subregion(address_space_mem, 0x40000000, phys_ram);

    /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the

       internal memory.  */

    memory_region_init_ram(phys_intmem, NULL, "axisdev88.chipram", INTMEM_SIZE,

                           &error_abort);

    vmstate_register_ram_global(phys_intmem);

    memory_region_add_subregion(address_space_mem, 0x38000000, phys_intmem);

      /* Attach a NAND flash to CS1.  */

    nand = drive_get(IF_MTD, 0, 0);

    nand_state.nand = nand_init(nand ? blk_bs(blk_by_legacy_dinfo(nand)) : NULL,

                                NAND_MFR_STMICRO, 0x39);

    memory_region_init_io(&nand_state.iomem, NULL, &nand_ops, &nand_state,

                          "nand", 0x05000000);

    memory_region_add_subregion(address_space_mem, 0x10000000,

                                &nand_state.iomem);

    gpio_state.nand = &nand_state;

    memory_region_init_io(&gpio_state.iomem, NULL, &gpio_ops, &gpio_state,

                          "gpio", 0x5c);

    memory_region_add_subregion(address_space_mem, 0x3001a000,

                                &gpio_state.iomem);

    dev = qdev_create(NULL, "etraxfs,pic");

    /* FIXME: Is there a proper way to signal vectors to the CPU core?  */

    qdev_prop_set_ptr(dev, "interrupt_vector", &env->interrupt_vector);

    qdev_init_nofail(dev);

    s = SYS_BUS_DEVICE(dev);

    sysbus_mmio_map(s, 0, 0x3001c000);

    sysbus_connect_irq(s, 0, qdev_get_gpio_in(DEVICE(cpu), CRIS_CPU_IRQ));

    sysbus_connect_irq(s, 1, qdev_get_gpio_in(DEVICE(cpu), CRIS_CPU_NMI));

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

        irq[i] = qdev_get_gpio_in(dev, i);

    }

    nmi[0] = qdev_get_gpio_in(dev, 30);

    nmi[1] = qdev_get_gpio_in(dev, 31);

    etraxfs_dmac = etraxfs_dmac_init(0x30000000, 10);

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

        /* On ETRAX, odd numbered channels are inputs.  */

        etraxfs_dmac_connect(etraxfs_dmac, i, irq + 7 + i, i & 1);

    }

    /* Add the two ethernet blocks.  */

    dma_eth = g_malloc0(sizeof dma_eth[0] * 4); /* Allocate 4 channels.  */

    etraxfs_eth_init(&nd_table[0], 0x30034000, 1, &dma_eth[0], &dma_eth[1]);

    if (nb_nics > 1) {

        etraxfs_eth_init(&nd_table[1], 0x30036000, 2, &dma_eth[2], &dma_eth[3]);

    }

    /* The DMA Connector block is missing, hardwire things for now.  */

    etraxfs_dmac_connect_client(etraxfs_dmac, 0, &dma_eth[0]);

    etraxfs_dmac_connect_client(etraxfs_dmac, 1, &dma_eth[1]);

    if (nb_nics > 1) {

        etraxfs_dmac_connect_client(etraxfs_dmac, 6, &dma_eth[2]);

        etraxfs_dmac_connect_client(etraxfs_dmac, 7, &dma_eth[3]);

    }

    /* 2 timers.  */

    sysbus_create_varargs("etraxfs,timer", 0x3001e000, irq[0x1b], nmi[1], NULL);

    sysbus_create_varargs("etraxfs,timer", 0x3005e000, irq[0x1b], nmi[1], NULL);

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

        sysbus_create_simple("etraxfs,serial", 0x30026000 + i * 0x2000,

                             irq[0x14 + i]);

    }

    if (kernel_filename) {

        li.image_filename = kernel_filename;

        li.cmdline = kernel_cmdline;

        cris_load_image(cpu, &li);

    } else if (!qtest_enabled()) {

        fprintf(stderr, "Kernel image must be specified\n");

        exit(1);

    }

}


static CharDriverState *qemu_chr_open_pp_fd(int fd)

{

    CharDriverState *chr;

    ParallelCharDriver *drv;

    if (ioctl(fd, PPCLAIM) < 0) {

        close(fd);

        return NULL;

    }

    drv = g_malloc0(sizeof(ParallelCharDriver));

    drv->fd = fd;

    drv->mode = IEEE1284_MODE_COMPAT;

    chr = g_malloc0(sizeof(CharDriverState));

    chr->chr_write = null_chr_write;

    chr->chr_ioctl = pp_ioctl;

    chr->chr_close = pp_close;

    chr->opaque = drv;

    return chr;

}


const char *bdrv_get_device_or_node_name(const BlockDriverState *bs)

{

    return bs->blk ? blk_name(bs->blk) : bs->node_name;

}


static QObject *qmp_output_pop(QmpOutputVisitor *qov, void *qapi)

{

    QStackEntry *e = QSLIST_FIRST(&qov->stack);

    QObject *value;

    assert(e);

    assert(e->qapi == qapi);

    QSLIST_REMOVE_HEAD(&qov->stack, node);

    value = e->value;

    assert(value);

    g_free(e);

    return value;

}


static int get_coc(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *c,

                   uint8_t *properties)

{

    int compno;

    if (s->buf_end - s->buf < 2)

        return AVERROR_INVALIDDATA;

    compno = bytestream_get_byte(&s->buf);

    c      += compno;

    c->csty = bytestream_get_byte(&s->buf);

    get_cox(s, c);

    properties[compno] |= HAD_COC;

    return 0;

}


int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t offset,

                                   int64_t bytes, int64_t *pnum)

{

    BlockDriverState *file;

    int64_t sector_num = offset >> BDRV_SECTOR_BITS;

    int nb_sectors = bytes >> BDRV_SECTOR_BITS;

    int64_t ret;

    int psectors;

    assert(QEMU_IS_ALIGNED(offset, BDRV_SECTOR_SIZE));

    assert(QEMU_IS_ALIGNED(bytes, BDRV_SECTOR_SIZE) && bytes < INT_MAX);

    ret = bdrv_get_block_status(bs, sector_num, nb_sectors, &psectors,

                                &file);

    if (ret < 0) {

        return ret;

    }

    if (pnum) {

        *pnum = psectors * BDRV_SECTOR_SIZE;

    }

    return !!(ret & BDRV_BLOCK_ALLOCATED);

}


static int rtl8139_cplus_transmit_one(RTL8139State *s)

{

    if (!rtl8139_transmitter_enabled(s))

    {

        DPRINTF("+++ C+ mode: transmitter disabled\n");

        return 0;

    }

    if (!rtl8139_cp_transmitter_enabled(s))

    {

        DPRINTF("+++ C+ mode: C+ transmitter disabled\n");

        return 0 ;

    }

    int descriptor = s->currCPlusTxDesc;

    target_phys_addr_t cplus_tx_ring_desc =

        rtl8139_addr64(s->TxAddr[0], s->TxAddr[1]);

    /* Normal priority ring */

    cplus_tx_ring_desc += 16 * descriptor;

    DPRINTF("+++ C+ mode reading TX descriptor %d from host memory at "

        "%08x0x%08x = 0x"TARGET_FMT_plx"\n", descriptor, s->TxAddr[1],

        s->TxAddr[0], cplus_tx_ring_desc);

    uint32_t val, txdw0,txdw1,txbufLO,txbufHI;

    cpu_physical_memory_read(cplus_tx_ring_desc,    (uint8_t *)&val, 4);

    txdw0 = le32_to_cpu(val);

    cpu_physical_memory_read(cplus_tx_ring_desc+4,  (uint8_t *)&val, 4);

    txdw1 = le32_to_cpu(val);

    cpu_physical_memory_read(cplus_tx_ring_desc+8,  (uint8_t *)&val, 4);

    txbufLO = le32_to_cpu(val);

    cpu_physical_memory_read(cplus_tx_ring_desc+12, (uint8_t *)&val, 4);

    txbufHI = le32_to_cpu(val);

    DPRINTF("+++ C+ mode TX descriptor %d %08x %08x %08x %08x\n", descriptor,

        txdw0, txdw1, txbufLO, txbufHI);

/* w0 ownership flag */

#define CP_TX_OWN (1<<31)

/* w0 end of ring flag */

#define CP_TX_EOR (1<<30)

/* first segment of received packet flag */

#define CP_TX_FS (1<<29)

/* last segment of received packet flag */

#define CP_TX_LS (1<<28)

/* large send packet flag */

#define CP_TX_LGSEN (1<<27)

/* large send MSS mask, bits 16...25 */

#define CP_TC_LGSEN_MSS_MASK ((1 << 12) - 1)

/* IP checksum offload flag */

#define CP_TX_IPCS (1<<18)

/* UDP checksum offload flag */

#define CP_TX_UDPCS (1<<17)

/* TCP checksum offload flag */

#define CP_TX_TCPCS (1<<16)

/* w0 bits 0...15 : buffer size */

#define CP_TX_BUFFER_SIZE (1<<16)

#define CP_TX_BUFFER_SIZE_MASK (CP_TX_BUFFER_SIZE - 1)

/* w1 add tag flag */

#define CP_TX_TAGC (1<<17)

/* w1 bits 0...15 : VLAN tag (big endian) */

#define CP_TX_VLAN_TAG_MASK ((1<<16) - 1)

/* w2 low  32bit of Rx buffer ptr */

/* w3 high 32bit of Rx buffer ptr */

/* set after transmission */

/* FIFO underrun flag */

#define CP_TX_STATUS_UNF (1<<25)

/* transmit error summary flag, valid if set any of three below */

#define CP_TX_STATUS_TES (1<<23)

/* out-of-window collision flag */

#define CP_TX_STATUS_OWC (1<<22)

/* link failure flag */

#define CP_TX_STATUS_LNKF (1<<21)

/* excessive collisions flag */

#define CP_TX_STATUS_EXC (1<<20)

    if (!(txdw0 & CP_TX_OWN))

    {

        DPRINTF("C+ Tx mode : descriptor %d is owned by host\n", descriptor);

        return 0 ;

    }

    DPRINTF("+++ C+ Tx mode : transmitting from descriptor %d\n", descriptor);

    if (txdw0 & CP_TX_FS)

    {

        DPRINTF("+++ C+ Tx mode : descriptor %d is first segment "

            "descriptor\n", descriptor);

        /* reset internal buffer offset */

        s->cplus_txbuffer_offset = 0;

    }

    int txsize = txdw0 & CP_TX_BUFFER_SIZE_MASK;

    target_phys_addr_t tx_addr = rtl8139_addr64(txbufLO, txbufHI);

    /* make sure we have enough space to assemble the packet */

    if (!s->cplus_txbuffer)

    {

        s->cplus_txbuffer_len = CP_TX_BUFFER_SIZE;

        s->cplus_txbuffer = qemu_malloc(s->cplus_txbuffer_len);

        s->cplus_txbuffer_offset = 0;

        DPRINTF("+++ C+ mode transmission buffer allocated space %d\n",

            s->cplus_txbuffer_len);

    }

    while (s->cplus_txbuffer && s->cplus_txbuffer_offset + txsize >= s->cplus_txbuffer_len)

    {

        s->cplus_txbuffer_len += CP_TX_BUFFER_SIZE;

        s->cplus_txbuffer = qemu_realloc(s->cplus_txbuffer, s->cplus_txbuffer_len);

        DPRINTF("+++ C+ mode transmission buffer space changed to %d\n",

            s->cplus_txbuffer_len);

    }

    if (!s->cplus_txbuffer)

    {

        /* out of memory */

        DPRINTF("+++ C+ mode transmiter failed to reallocate %d bytes\n",

            s->cplus_txbuffer_len);

        /* update tally counter */

        ++s->tally_counters.TxERR;

        ++s->tally_counters.TxAbt;

        return 0;

    }

    /* append more data to the packet */

    DPRINTF("+++ C+ mode transmit reading %d bytes from host memory at "

        TARGET_FMT_plx" to offset %d\n", txsize, tx_addr,

        s->cplus_txbuffer_offset);

    cpu_physical_memory_read(tx_addr, s->cplus_txbuffer + s->cplus_txbuffer_offset, txsize);

    s->cplus_txbuffer_offset += txsize;

    /* seek to next Rx descriptor */

    if (txdw0 & CP_TX_EOR)

    {

        s->currCPlusTxDesc = 0;

    }

    else

    {

        ++s->currCPlusTxDesc;

        if (s->currCPlusTxDesc >= 64)

            s->currCPlusTxDesc = 0;

    }

    /* transfer ownership to target */

    txdw0 &= ~CP_RX_OWN;

    /* reset error indicator bits */

    txdw0 &= ~CP_TX_STATUS_UNF;

    txdw0 &= ~CP_TX_STATUS_TES;

    txdw0 &= ~CP_TX_STATUS_OWC;

    txdw0 &= ~CP_TX_STATUS_LNKF;

    txdw0 &= ~CP_TX_STATUS_EXC;

    /* update ring data */

    val = cpu_to_le32(txdw0);

    cpu_physical_memory_write(cplus_tx_ring_desc,    (uint8_t *)&val, 4);

    /* Now decide if descriptor being processed is holding the last segment of packet */

    if (txdw0 & CP_TX_LS)

    {

        uint8_t dot1q_buffer_space[VLAN_HLEN];

        uint16_t *dot1q_buffer;

        DPRINTF("+++ C+ Tx mode : descriptor %d is last segment descriptor\n",

            descriptor);

        /* can transfer fully assembled packet */

        uint8_t *saved_buffer  = s->cplus_txbuffer;

        int      saved_size    = s->cplus_txbuffer_offset;

        int      saved_buffer_len = s->cplus_txbuffer_len;

        /* create vlan tag */

        if (txdw1 & CP_TX_TAGC) {

            /* the vlan tag is in BE byte order in the descriptor

             * BE + le_to_cpu() + ~swap()~ = cpu */

            DPRINTF("+++ C+ Tx mode : inserting vlan tag with ""tci: %u\n",

                bswap16(txdw1 & CP_TX_VLAN_TAG_MASK));

            dot1q_buffer = (uint16_t *) dot1q_buffer_space;

            dot1q_buffer[0] = cpu_to_be16(ETH_P_8021Q);

            /* BE + le_to_cpu() + ~cpu_to_le()~ = BE */

            dot1q_buffer[1] = cpu_to_le16(txdw1 & CP_TX_VLAN_TAG_MASK);

        } else {

            dot1q_buffer = NULL;

        }

        /* reset the card space to protect from recursive call */

        s->cplus_txbuffer = NULL;

        s->cplus_txbuffer_offset = 0;

        s->cplus_txbuffer_len = 0;

        if (txdw0 & (CP_TX_IPCS | CP_TX_UDPCS | CP_TX_TCPCS | CP_TX_LGSEN))

        {

            DPRINTF("+++ C+ mode offloaded task checksum\n");

            /* ip packet header */

            ip_header *ip = NULL;

            int hlen = 0;

            uint8_t  ip_protocol = 0;

            uint16_t ip_data_len = 0;

            uint8_t *eth_payload_data = NULL;

            size_t   eth_payload_len  = 0;

            int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12));

            if (proto == ETH_P_IP)

            {

                DPRINTF("+++ C+ mode has IP packet\n");

                /* not aligned */

                eth_payload_data = saved_buffer + ETH_HLEN;

                eth_payload_len  = saved_size   - ETH_HLEN;

                ip = (ip_header*)eth_payload_data;

                if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) {

                    DPRINTF("+++ C+ mode packet has bad IP version %d "

                        "expected %d\n", IP_HEADER_VERSION(ip),

                        IP_HEADER_VERSION_4);

                    ip = NULL;

                } else {

                    hlen = IP_HEADER_LENGTH(ip);

                    ip_protocol = ip->ip_p;

                    ip_data_len = be16_to_cpu(ip->ip_len) - hlen;

                }

            }

            if (ip)

            {

                if (txdw0 & CP_TX_IPCS)

                {

                    DPRINTF("+++ C+ mode need IP checksum\n");

                    if (hlen<sizeof(ip_header) || hlen>eth_payload_len) {/* min header length */

                        /* bad packet header len */

                        /* or packet too short */

                    }

                    else

                    {

                        ip->ip_sum = 0;

                        ip->ip_sum = ip_checksum(ip, hlen);

                        DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n",

                            hlen, ip->ip_sum);

                    }

                }

                if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP)

                {

#if defined (DEBUG_RTL8139)

                    int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK;

#endif

                    DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d "

                        "frame data %d specified MSS=%d\n", ETH_MTU,

                        ip_data_len, saved_size - ETH_HLEN, large_send_mss);

                    int tcp_send_offset = 0;

                    int send_count = 0;

                    /* maximum IP header length is 60 bytes */

                    uint8_t saved_ip_header[60];

                    /* save IP header template; data area is used in tcp checksum calculation */

                    memcpy(saved_ip_header, eth_payload_data, hlen);

                    /* a placeholder for checksum calculation routine in tcp case */

                    uint8_t *data_to_checksum     = eth_payload_data + hlen - 12;

                    //                    size_t   data_to_checksum_len = eth_payload_len  - hlen + 12;

                    /* pointer to TCP header */

                    tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen);

                    int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr);

                    /* ETH_MTU = ip header len + tcp header len + payload */

                    int tcp_data_len = ip_data_len - tcp_hlen;

                    int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen;

                    DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP "

                        "data len %d TCP chunk size %d\n", ip_data_len,

                        tcp_hlen, tcp_data_len, tcp_chunk_size);

                    /* note the cycle below overwrites IP header data,

                       but restores it from saved_ip_header before sending packet */

                    int is_last_frame = 0;

                    for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size)

                    {

                        uint16_t chunk_size = tcp_chunk_size;

                        /* check if this is the last frame */

                        if (tcp_send_offset + tcp_chunk_size >= tcp_data_len)

                        {

                            is_last_frame = 1;

                            chunk_size = tcp_data_len - tcp_send_offset;

                        }

                        DPRINTF("+++ C+ mode TSO TCP seqno %08x\n",

                            be32_to_cpu(p_tcp_hdr->th_seq));

                        /* add 4 TCP pseudoheader fields */

                        /* copy IP source and destination fields */

                        memcpy(data_to_checksum, saved_ip_header + 12, 8);

                        DPRINTF("+++ C+ mode TSO calculating TCP checksum for "

                            "packet with %d bytes data\n", tcp_hlen +

                            chunk_size);

                        if (tcp_send_offset)

                        {

                            memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size);

                        }

                        /* keep PUSH and FIN flags only for the last frame */

                        if (!is_last_frame)

                        {

                            TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN);

                        }

                        /* recalculate TCP checksum */

                        ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;

                        p_tcpip_hdr->zeros      = 0;

                        p_tcpip_hdr->ip_proto   = IP_PROTO_TCP;

                        p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size);

                        p_tcp_hdr->th_sum = 0;

                        int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12);

                        DPRINTF("+++ C+ mode TSO TCP checksum %04x\n",

                            tcp_checksum);

                        p_tcp_hdr->th_sum = tcp_checksum;

                        /* restore IP header */

                        memcpy(eth_payload_data, saved_ip_header, hlen);

                        /* set IP data length and recalculate IP checksum */

                        ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size);

                        /* increment IP id for subsequent frames */

                        ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id));

                        ip->ip_sum = 0;

                        ip->ip_sum = ip_checksum(eth_payload_data, hlen);

                        DPRINTF("+++ C+ mode TSO IP header len=%d "

                            "checksum=%04x\n", hlen, ip->ip_sum);

                        int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size;

                        DPRINTF("+++ C+ mode TSO transferring packet size "

                            "%d\n", tso_send_size);

                        rtl8139_transfer_frame(s, saved_buffer, tso_send_size,

                            0, (uint8_t *) dot1q_buffer);

                        /* add transferred count to TCP sequence number */

                        p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq));

                        ++send_count;

                    }

                    /* Stop sending this frame */

                    saved_size = 0;

                }

                else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS))

                {

                    DPRINTF("+++ C+ mode need TCP or UDP checksum\n");

                    /* maximum IP header length is 60 bytes */

                    uint8_t saved_ip_header[60];

                    memcpy(saved_ip_header, eth_payload_data, hlen);

                    uint8_t *data_to_checksum     = eth_payload_data + hlen - 12;

                    //                    size_t   data_to_checksum_len = eth_payload_len  - hlen + 12;

                    /* add 4 TCP pseudoheader fields */

                    /* copy IP source and destination fields */

                    memcpy(data_to_checksum, saved_ip_header + 12, 8);

                    if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP)

                    {

                        DPRINTF("+++ C+ mode calculating TCP checksum for "

                            "packet with %d bytes data\n", ip_data_len);

                        ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum;

                        p_tcpip_hdr->zeros      = 0;

                        p_tcpip_hdr->ip_proto   = IP_PROTO_TCP;

                        p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len);

                        tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12);

                        p_tcp_hdr->th_sum = 0;

                        int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);

                        DPRINTF("+++ C+ mode TCP checksum %04x\n",

                            tcp_checksum);

                        p_tcp_hdr->th_sum = tcp_checksum;

                    }

                    else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP)

                    {

                        DPRINTF("+++ C+ mode calculating UDP checksum for "

                            "packet with %d bytes data\n", ip_data_len);

                        ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum;

                        p_udpip_hdr->zeros      = 0;

                        p_udpip_hdr->ip_proto   = IP_PROTO_UDP;

                        p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len);

                        udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12);

                        p_udp_hdr->uh_sum = 0;

                        int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12);

                        DPRINTF("+++ C+ mode UDP checksum %04x\n",

                            udp_checksum);

                        p_udp_hdr->uh_sum = udp_checksum;

                    }

                    /* restore IP header */

                    memcpy(eth_payload_data, saved_ip_header, hlen);

                }

            }

        }

        /* update tally counter */

        ++s->tally_counters.TxOk;

        DPRINTF("+++ C+ mode transmitting %d bytes packet\n", saved_size);

        rtl8139_transfer_frame(s, saved_buffer, saved_size, 1,

            (uint8_t *) dot1q_buffer);

        /* restore card space if there was no recursion and reset offset */

        if (!s->cplus_txbuffer)

        {

            s->cplus_txbuffer        = saved_buffer;

            s->cplus_txbuffer_len    = saved_buffer_len;

            s->cplus_txbuffer_offset = 0;

        }

        else

        {

            qemu_free(saved_buffer);

        }

    }

    else

    {

        DPRINTF("+++ C+ mode transmission continue to next descriptor\n");

    }

    return 1;

}


static void object_set_link_property(Object *obj, Visitor *v, void *opaque,

                                     const char *name, Error **errp)

{

    Object **child = opaque;

    bool ambiguous = false;

    const char *type;

    char *path;

    type = object_property_get_type(obj, name, NULL);

    visit_type_str(v, &path, name, errp);

    if (*child) {

        object_unref(*child);

    }

    if (strcmp(path, "") != 0) {

        Object *target;

        target = object_resolve_path(path, &ambiguous);

        if (target) {

            gchar *target_type;

            target_type = g_strdup_printf("link<%s>",

                                          object_get_typename(OBJECT(target)));

            if (strcmp(target_type, type) == 0) {

                *child = target;

                object_ref(target);

            } else {

                error_set(errp, QERR_INVALID_PARAMETER_TYPE, name, type);

            }

            g_free(target_type);

        } else {

            error_set(errp, QERR_DEVICE_NOT_FOUND, path);

        }

    } else {

        *child = NULL;

    }

    g_free(path);

}


static int decode_frame_packing_arrangement(H264Context *h)

{

    h->sei_fpa.frame_packing_arrangement_id          = get_ue_golomb(&h->gb);

    h->sei_fpa.frame_packing_arrangement_cancel_flag = get_bits1(&h->gb);

    h->sei_frame_packing_present = !h->sei_fpa.frame_packing_arrangement_cancel_flag;

    if (h->sei_frame_packing_present) {

        h->sei_fpa.frame_packing_arrangement_type =

        h->frame_packing_arrangement_type = get_bits(&h->gb, 7);

        h->sei_fpa.quincunx_sampling_flag         =

        h->quincunx_subsampling           = get_bits1(&h->gb);

        h->sei_fpa.content_interpretation_type    =

        h->content_interpretation_type    = get_bits(&h->gb, 6);

        // the following skips: spatial_flipping_flag, frame0_flipped_flag,

        // field_views_flag, current_frame_is_frame0_flag,

        // frame0_self_contained_flag, frame1_self_contained_flag

        skip_bits(&h->gb, 6);

        if (!h->quincunx_subsampling && h->frame_packing_arrangement_type != 5)

            skip_bits(&h->gb, 16);      // frame[01]_grid_position_[xy]

        skip_bits(&h->gb, 8);           // frame_packing_arrangement_reserved_byte

        h->sei_fpa.frame_packing_arrangement_repetition_period = get_ue_golomb(&h->gb) /* frame_packing_arrangement_repetition_period */;

    }

    skip_bits1(&h->gb);                 // frame_packing_arrangement_extension_flag

    if (h->avctx->debug & FF_DEBUG_PICT_INFO)

        av_log(h->avctx, AV_LOG_DEBUG, "SEI FPA %d %d %d %d %d %d\n",

                                       h->sei_fpa.frame_packing_arrangement_id,

                                       h->sei_fpa.frame_packing_arrangement_cancel_flag,

                                       h->sei_fpa.frame_packing_arrangement_type,

                                       h->sei_fpa.quincunx_sampling_flag,

                                       h->sei_fpa.content_interpretation_type,

                                       h->sei_fpa.frame_packing_arrangement_repetition_period);

    return 0;

}


static void do_info_trace(Monitor *mon)

{

    st_print_trace((FILE *)mon, &monitor_fprintf);

}


static int save_xbzrle_page(QEMUFile *f, uint8_t **current_data,

                            ram_addr_t current_addr, RAMBlock *block,

                            ram_addr_t offset, int cont, bool last_stage)

{

    int encoded_len = 0, bytes_sent = -1;

    uint8_t *prev_cached_page;

    if (!cache_is_cached(XBZRLE.cache, current_addr)) {

        acct_info.xbzrle_cache_miss++;

        if (!last_stage) {

            if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) {

                return -1;

            } else {

                /* update *current_data when the page has been

                   inserted into cache */

                *current_data = get_cached_data(XBZRLE.cache, current_addr);

            }

        }

        return -1;

    }

    prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);

    /* save current buffer into memory */

    memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE);

    /* XBZRLE encoding (if there is no overflow) */

    encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,

                                       TARGET_PAGE_SIZE, XBZRLE.encoded_buf,

                                       TARGET_PAGE_SIZE);

    if (encoded_len == 0) {

        DPRINTF("Skipping unmodified page\n");

        return 0;

    } else if (encoded_len == -1) {

        DPRINTF("Overflow\n");

        acct_info.xbzrle_overflows++;

        /* update data in the cache */

        if (!last_stage) {

            memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE);

            *current_data = prev_cached_page;

        }

        return -1;

    }

    /* we need to update the data in the cache, in order to get the same data */

    if (!last_stage) {

        memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);

    }

    /* Send XBZRLE based compressed page */

    bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);

    qemu_put_byte(f, ENCODING_FLAG_XBZRLE);

    qemu_put_be16(f, encoded_len);

    qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);

    bytes_sent += encoded_len + 1 + 2;

    acct_info.xbzrle_pages++;

    acct_info.xbzrle_bytes += bytes_sent;

    return bytes_sent;

}


static void scsi_unmap_complete(void *opaque, int ret)

{

    UnmapCBData *data = opaque;

    SCSIDiskReq *r = data->r;

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);

    uint64_t sector_num;

    uint32_t nb_sectors;

    r->req.aiocb = NULL;

    if (ret < 0) {

        if (scsi_handle_rw_error(r, -ret)) {

            goto done;

        }

    }

    if (data->count > 0 && !r->req.io_canceled) {

        sector_num = ldq_be_p(&data->inbuf[0]);

        nb_sectors = ldl_be_p(&data->inbuf[8]) & 0xffffffffULL;

        if (sector_num > sector_num + nb_sectors ||

            sector_num + nb_sectors - 1 > s->qdev.max_lba) {

            scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE));

            goto done;

        }

        r->req.aiocb = bdrv_aio_discard(s->qdev.conf.bs,

                                        sector_num * (s->qdev.blocksize / 512),

                                        nb_sectors * (s->qdev.blocksize / 512),

                                        scsi_unmap_complete, data);

        data->count--;

        data->inbuf += 16;

        return;

    }

done:

    if (data->count == 0) {

        scsi_req_complete(&r->req, GOOD);

    }

    if (!r->req.io_canceled) {

        scsi_req_unref(&r->req);

    }

    g_free(data);

}


int qcrypto_hash_bytesv(QCryptoHashAlgorithm alg,

                        const struct iovec *iov,

                        size_t niov,

                        uint8_t **result,

                        size_t *resultlen,

                        Error **errp)

{

#ifdef CONFIG_AF_ALG

    int ret;

    ret = qcrypto_hash_afalg_driver.hash_bytesv(alg, iov, niov,

                                                result, resultlen,

                                                errp);

    if (ret == 0) {

        return ret;

    }

    /*

     * TODO:

     * Maybe we should treat some afalg errors as fatal

     */

    error_free(*errp);

#endif

    return qcrypto_hash_lib_driver.hash_bytesv(alg, iov, niov,

                                               result, resultlen,

                                               errp);

}


int net_init_slirp(const Netdev *netdev, const char *name,

                   NetClientState *peer, Error **errp)

{

    /* FIXME error_setg(errp, ...) on failure */

    struct slirp_config_str *config;

    char *vnet;

    int ret;

    const NetdevUserOptions *user;

    const char **dnssearch;

    bool ipv4 = true, ipv6 = true;

    assert(netdev->type == NET_CLIENT_DRIVER_USER);

    user = &netdev->u.user;

    if ((user->has_ipv6 && user->ipv6 && !user->has_ipv4) ||

        (user->has_ipv4 && !user->ipv4)) {

        ipv4 = 0;

    }

    if ((user->has_ipv4 && user->ipv4 && !user->has_ipv6) ||

        (user->has_ipv6 && !user->ipv6)) {

        ipv6 = 0;

    }

    vnet = user->has_net ? g_strdup(user->net) :

           user->has_ip  ? g_strdup_printf("%s/24", user->ip) :

           NULL;

    dnssearch = slirp_dnssearch(user->dnssearch);

    /* all optional fields are initialized to "all bits zero" */

    net_init_slirp_configs(user->hostfwd, SLIRP_CFG_HOSTFWD);

    net_init_slirp_configs(user->guestfwd, 0);

    ret = net_slirp_init(peer, "user", name, user->q_restrict,

                         ipv4, vnet, user->host,

                         ipv6, user->ipv6_prefix, user->ipv6_prefixlen,

                         user->ipv6_host, user->hostname, user->tftp,

                         user->bootfile, user->dhcpstart,

                         user->dns, user->ipv6_dns, user->smb,

                         user->smbserver, dnssearch);

    while (slirp_configs) {

        config = slirp_configs;

        slirp_configs = config->next;

        g_free(config);

    }

    g_free(vnet);

    g_free(dnssearch);

    return ret;

}