static void test_visitor_in_native_list_number(TestInputVisitorData *data,

                                               const void *unused)

{

    UserDefNativeListUnion *cvalue = NULL;

    numberList *elem = NULL;

    Error *err = NULL;

    Visitor *v;

    GString *gstr_list = g_string_new("");

    GString *gstr_union = g_string_new("");

    int i;

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

        g_string_append_printf(gstr_list, "%f", (double)i / 3);

        if (i != 31) {

            g_string_append(gstr_list, ", ");

        }

    }

    g_string_append_printf(gstr_union,  "{ 'type': 'number', 'data': [ %s ] }",

                           gstr_list->str);

    v = visitor_input_test_init_raw(data,  gstr_union->str);

    visit_type_UserDefNativeListUnion(v, &cvalue, NULL, &err);

    g_assert(err == NULL);

    g_assert(cvalue != NULL);

    g_assert_cmpint(cvalue->type, ==, USER_DEF_NATIVE_LIST_UNION_KIND_NUMBER);

    for (i = 0, elem = cvalue->u.number; elem; elem = elem->next, i++) {

        GString *double_expected = g_string_new("");

        GString *double_actual = g_string_new("");

        g_string_printf(double_expected, "%.6f", (double)i / 3);

        g_string_printf(double_actual, "%.6f", elem->value);

        g_assert_cmpstr(double_expected->str, ==, double_actual->str);

        g_string_free(double_expected, true);

        g_string_free(double_actual, true);

    }

    g_string_free(gstr_union, true);

    g_string_free(gstr_list, true);

    qapi_free_UserDefNativeListUnion(cvalue);

}


static int mpegps_probe(AVProbeData *p)

{

    uint32_t code= -1;

    int sys=0, pspack=0, priv1=0, vid=0, audio=0, invalid=0;

    int i;

    int score=0;

    for(i=0; i<p->buf_size; i++){

        code = (code<<8) + p->buf[i];

        if ((code & 0xffffff00) == 0x100) {

            int len= p->buf[i+1] << 8 | p->buf[i+2];

            int pes= check_pes(p->buf+i, p->buf+p->buf_size);

            if(code == SYSTEM_HEADER_START_CODE) sys++;

            else if(code == PACK_START_CODE)     pspack++;

            else if((code & 0xf0) == VIDEO_ID &&  pes) vid++;

            // skip pes payload to avoid start code emulation for private

            // and audio streams

            else if((code & 0xe0) == AUDIO_ID &&  pes) {audio++; i+=len;}

            else if(code == PRIVATE_STREAM_1  &&  pes) {priv1++; i+=len;}

            else if((code & 0xf0) == VIDEO_ID && !pes) invalid++;

            else if((code & 0xe0) == AUDIO_ID && !pes) invalid++;

            else if(code == PRIVATE_STREAM_1  && !pes) invalid++;

        }

    }

    if(vid+audio > invalid)     /* invalid VDR files nd short PES streams */

        score= AVPROBE_SCORE_MAX/4;

//av_log(NULL, AV_LOG_ERROR, "%d %d %d %d %d %d len:%d\n", sys, priv1, pspack,vid, audio, invalid, p->buf_size);

    if(sys>invalid && sys*9 <= pspack*10)

        return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg

    if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)

        return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg

    if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */

        return (audio > 12 || vid > 3) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4;

    //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1

    //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6

    return score;

}


static void migrate_fd_cleanup(MigrationState *s)

{

    int ret = 0;

    if (s->file) {

        DPRINTF("closing file\n");

        ret = qemu_fclose(s->file);

        s->file = NULL;

    }

    assert(s->fd == -1);

    if (ret < 0 && s->state == MIG_STATE_ACTIVE) {

        s->state = MIG_STATE_ERROR;

    }

    if (s->state != MIG_STATE_ACTIVE) {

        qemu_savevm_state_cancel();

    }

}


unsigned long init_guest_space(unsigned long host_start,

                               unsigned long host_size,

                               unsigned long guest_start,

                               bool fixed)

{

    unsigned long current_start, real_start;

    int flags;

    assert(host_start || host_size);

    /* If just a starting address is given, then just verify that

     * address.  */

    if (host_start && !host_size) {

        if (guest_validate_base(host_start)) {

            return host_start;

        } else {

            return (unsigned long)-1;

        }

    }

    /* Setup the initial flags and start address.  */

    current_start = host_start & qemu_host_page_mask;

    flags = MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE;

    if (fixed) {

        flags |= MAP_FIXED;

    }

    /* Otherwise, a non-zero size region of memory needs to be mapped

     * and validated.  */

    while (1) {

        /* Do not use mmap_find_vma here because that is limited to the

         * guest address space.  We are going to make the

         * guest address space fit whatever we're given.

         */

        real_start = (unsigned long)

            mmap((void *)current_start, host_size, PROT_NONE, flags, -1, 0);

        if (real_start == (unsigned long)-1) {

            return (unsigned long)-1;

        }

        if ((real_start == current_start)

            && guest_validate_base(real_start - guest_start)) {

            break;

        }

        /* That address didn't work.  Unmap and try a different one.

         * The address the host picked because is typically right at

         * the top of the host address space and leaves the guest with

         * no usable address space.  Resort to a linear search.  We

         * already compensated for mmap_min_addr, so this should not

         * happen often.  Probably means we got unlucky and host

         * address space randomization put a shared library somewhere

         * inconvenient.

         */

        munmap((void *)real_start, host_size);

        current_start += qemu_host_page_size;

        if (host_start == current_start) {

            /* Theoretically possible if host doesn't have any suitably

             * aligned areas.  Normally the first mmap will fail.

             */

            return (unsigned long)-1;

        }

    }

    return real_start;

}


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

                                   size_t size, Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

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

    Error *err = NULL;

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

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

                   "QDict");

        return;

    qmp_input_push(qiv, qobj, &err);

    if (err) {

        error_propagate(errp, err);

        return;

        *obj = g_malloc0(size);


static void ehci_advance_state(EHCIState *ehci,

                               int async)

{

    EHCIQueue *q = NULL;

    int again;

    int iter = 0;

    do {

        if (ehci_get_state(ehci, async) == EST_FETCHQH) {

            iter++;

            /* if we are roaming a lot of QH without executing a qTD

             * something is wrong with the linked list. TO-DO: why is

             * this hack needed?

             */

            assert(iter < MAX_ITERATIONS);

#if 0

            if (iter > MAX_ITERATIONS) {

                DPRINTF("\n*** advance_state: bailing on MAX ITERATIONS***\n");

                ehci_set_state(ehci, async, EST_ACTIVE);

                break;

            }

#endif

        }

        switch(ehci_get_state(ehci, async)) {

        case EST_WAITLISTHEAD:

            again = ehci_state_waitlisthead(ehci, async);

            break;

        case EST_FETCHENTRY:

            again = ehci_state_fetchentry(ehci, async);

            break;

        case EST_FETCHQH:

            q = ehci_state_fetchqh(ehci, async);

            again = q ? 1 : 0;

            break;

        case EST_FETCHITD:

            again = ehci_state_fetchitd(ehci, async);

            break;

        case EST_FETCHSITD:

            again = ehci_state_fetchsitd(ehci, async);

            break;

        case EST_ADVANCEQUEUE:

            again = ehci_state_advqueue(q, async);

            break;

        case EST_FETCHQTD:

            again = ehci_state_fetchqtd(q, async);

            break;

        case EST_HORIZONTALQH:

            again = ehci_state_horizqh(q, async);

            break;

        case EST_EXECUTE:

            iter = 0;

            again = ehci_state_execute(q, async);

            break;

        case EST_EXECUTING:

            assert(q != NULL);

            again = ehci_state_executing(q, async);

            break;

        case EST_WRITEBACK:

            assert(q != NULL);

            again = ehci_state_writeback(q, async);

            break;

        default:

            fprintf(stderr, "Bad state!\n");

            again = -1;

            assert(0);

            break;

        }

        if (again < 0) {

            fprintf(stderr, "processing error - resetting ehci HC\n");

            ehci_reset(ehci);

            again = 0;

            assert(0);

        }

    }

    while (again);

    ehci_commit_interrupt(ehci);

}


void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)

{

    GArray *table_offsets;

    unsigned facs, ssdt, dsdt, rsdt;

    AcpiCpuInfo cpu;

    AcpiPmInfo pm;

    AcpiMiscInfo misc;

    AcpiMcfgInfo mcfg;

    PcPciInfo pci;

    uint8_t *u;

    size_t aml_len = 0;

    acpi_get_cpu_info(&cpu);

    acpi_get_pm_info(&pm);

    acpi_get_dsdt(&misc);

    acpi_get_misc_info(&misc);

    acpi_get_pci_info(&pci);

    table_offsets = g_array_new(false, true /* clear */,

                                        sizeof(uint32_t));

    ACPI_BUILD_DPRINTF(3, "init ACPI tables\n");

    bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,

                             64 /* Ensure FACS is aligned */,

                             false /* high memory */);

    /*

     * FACS is pointed to by FADT.

     * We place it first since it's the only table that has alignment

     * requirements.

     */

    facs = tables->table_data->len;

    build_facs(tables->table_data, tables->linker, guest_info);

    /* DSDT is pointed to by FADT */

    dsdt = tables->table_data->len;

    build_dsdt(tables->table_data, tables->linker, &misc);

    /* Count the size of the DSDT and SSDT, we will need it for legacy

     * sizing of ACPI tables.

     */

    aml_len += tables->table_data->len - dsdt;

    /* ACPI tables pointed to by RSDT */

    acpi_add_table(table_offsets, tables->table_data);

    build_fadt(tables->table_data, tables->linker, &pm, facs, dsdt);

    ssdt = tables->table_data->len;

    acpi_add_table(table_offsets, tables->table_data);

    build_ssdt(tables->table_data, tables->linker, &cpu, &pm, &misc, &pci,

               guest_info);

    aml_len += tables->table_data->len - ssdt;

    acpi_add_table(table_offsets, tables->table_data);

    build_madt(tables->table_data, tables->linker, &cpu, guest_info);

    if (misc.has_hpet) {

        acpi_add_table(table_offsets, tables->table_data);

        build_hpet(tables->table_data, tables->linker);

    }

    if (guest_info->numa_nodes) {

        acpi_add_table(table_offsets, tables->table_data);

        build_srat(tables->table_data, tables->linker, &cpu, guest_info);

    }

    if (acpi_get_mcfg(&mcfg)) {

        acpi_add_table(table_offsets, tables->table_data);

        build_mcfg_q35(tables->table_data, tables->linker, &mcfg);

    }

    /* Add tables supplied by user (if any) */

    for (u = acpi_table_first(); u; u = acpi_table_next(u)) {

        unsigned len = acpi_table_len(u);

        acpi_add_table(table_offsets, tables->table_data);

        g_array_append_vals(tables->table_data, u, len);

    }

    /* RSDT is pointed to by RSDP */

    rsdt = tables->table_data->len;

    build_rsdt(tables->table_data, tables->linker, table_offsets);

    /* RSDP is in FSEG memory, so allocate it separately */

    build_rsdp(tables->rsdp, tables->linker, rsdt);

    /* We'll expose it all to Guest so we want to reduce

     * chance of size changes.

     * RSDP is small so it's easy to keep it immutable, no need to

     * bother with alignment.

     *

     * We used to align the tables to 4k, but of course this would

     * too simple to be enough.  4k turned out to be too small an

     * alignment very soon, and in fact it is almost impossible to

     * keep the table size stable for all (max_cpus, max_memory_slots)

     * combinations.  So the table size is always 64k for pc-i440fx-2.1

     * and we give an error if the table grows beyond that limit.

     *

     * We still have the problem of migrating from "-M pc-i440fx-2.0".  For

     * that, we exploit the fact that QEMU 2.1 generates _smaller_ tables

     * than 2.0 and we can always pad the smaller tables with zeros.  We can

     * then use the exact size of the 2.0 tables.

     *

     * All this is for PIIX4, since QEMU 2.0 didn't support Q35 migration.

     */

    if (guest_info->legacy_acpi_table_size) {

        /* Subtracting aml_len gives the size of fixed tables.  Then add the

         * size of the PIIX4 DSDT/SSDT in QEMU 2.0.

         */

        int legacy_aml_len =

            guest_info->legacy_acpi_table_size +

            ACPI_BUILD_LEGACY_CPU_AML_SIZE * max_cpus;

        int legacy_table_size =

            ROUND_UP(tables->table_data->len - aml_len + legacy_aml_len,

                     ACPI_BUILD_ALIGN_SIZE);

        if (tables->table_data->len > legacy_table_size) {

            /* Should happen only with PCI bridges and -M pc-i440fx-2.0.  */

            error_report("Warning: migration to QEMU 2.0 may not work.");

        }

        g_array_set_size(tables->table_data, legacy_table_size);

    } else {

        if (tables->table_data->len > ACPI_BUILD_TABLE_SIZE) {

            /* As of QEMU 2.1, this fires with 160 VCPUs and 255 memory slots.  */

            error_report("ACPI tables are larger than 64k.  Please remove");

            error_report("CPUs, NUMA nodes, memory slots or PCI bridges.");

            exit(1);

        }

        g_array_set_size(tables->table_data, ACPI_BUILD_TABLE_SIZE);

    }

    acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);

    /* Cleanup memory that's no longer used. */

    g_array_free(table_offsets, true);

}


int l4_register_io_memory(CPUReadMemoryFunc * const *mem_read,

                CPUWriteMemoryFunc * const *mem_write, void *opaque)

{

    omap_l4_io_entry[omap_l4_io_entries].mem_read = mem_read;

    omap_l4_io_entry[omap_l4_io_entries].mem_write = mem_write;

    omap_l4_io_entry[omap_l4_io_entries].opaque = opaque;

    return omap_l4_io_entries ++;

}


static int vhdx_create_new_headers(BlockDriverState *bs, uint64_t image_size,

                                   uint32_t log_size)

{

    int ret = 0;

    VHDXHeader *hdr = NULL;

    hdr = g_new0(VHDXHeader, 1);

    hdr->signature       = VHDX_HEADER_SIGNATURE;

    hdr->sequence_number = g_random_int();

    hdr->log_version     = 0;

    hdr->version         = 1;

    hdr->log_length      = log_size;

    hdr->log_offset      = VHDX_HEADER_SECTION_END;

    vhdx_guid_generate(&hdr->file_write_guid);

    vhdx_guid_generate(&hdr->data_write_guid);

    ret = vhdx_write_header(bs, hdr, VHDX_HEADER1_OFFSET, false);

    if (ret < 0) {

        goto exit;

    }

    hdr->sequence_number++;

    ret = vhdx_write_header(bs, hdr, VHDX_HEADER2_OFFSET, false);

    if (ret < 0) {

        goto exit;

    }

exit:

    g_free(hdr);

    return ret;

}


static int usb_net_handle_data(USBDevice *dev, USBPacket *p)

{

    USBNetState *s = (USBNetState *) dev;

    int ret = 0;

    switch(p->pid) {

    case USB_TOKEN_IN:

        switch (p->devep) {

        case 1:

            ret = usb_net_handle_statusin(s, p);

            break;

        case 2:

            ret = usb_net_handle_datain(s, p);

            break;

        default:

            goto fail;

        }

        break;

    case USB_TOKEN_OUT:

        switch (p->devep) {

        case 2:

            ret = usb_net_handle_dataout(s, p);

            break;

        default:

            goto fail;

        }

        break;

    default:

    fail:

        ret = USB_RET_STALL;

        break;

    }

    if (ret == USB_RET_STALL)

        fprintf(stderr, "usbnet: failed data transaction: "

                        "pid 0x%x ep 0x%x len 0x%zx\n",

                        p->pid, p->devep, p->iov.size);

    return ret;

}


static void migrate_fd_monitor_suspend(MigrationState *s, Monitor *mon)

{

    if (monitor_suspend(mon) == 0) {

        DPRINTF("suspending monitor\n");

    } else {

        monitor_printf(mon, "terminal does not allow synchronous "

                       "migration, continuing detached\n");

    }

}


static inline void vmsvga_update_rect(struct vmsvga_state_s *s,

                int x, int y, int w, int h)

{

    int line;

    int bypl;

    int width;

    int start;

    uint8_t *src;

    uint8_t *dst;

    if (x + w > s->width) {

        fprintf(stderr, "%s: update width too large x: %d, w: %d\n",

                        __FUNCTION__, x, w);

        x = MIN(x, s->width);

        w = s->width - x;

    }

    if (y + h > s->height) {

        fprintf(stderr, "%s: update height too large y: %d, h: %d\n",

                        __FUNCTION__, y, h);

        y = MIN(y, s->height);

        h = s->height - y;

    }

    line = h;

    bypl = s->bypp * s->width;

    width = s->bypp * w;

    start = s->bypp * x + bypl * y;

    src = s->vga.vram_ptr + start;

    dst = ds_get_data(s->vga.ds) + start;

    for (; line > 0; line --, src += bypl, dst += bypl)

        memcpy(dst, src, width);

    dpy_gfx_update(s->vga.ds, x, y, w, h);

}


static void qemu_tcg_init_vcpu(void *_env)

{

    CPUState *env = _env;

    /* share a single thread for all cpus with TCG */

    if (!tcg_cpu_thread) {

        env->thread = qemu_mallocz(sizeof(QemuThread));

        env->halt_cond = qemu_mallocz(sizeof(QemuCond));

        qemu_cond_init(env->halt_cond);

        qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env);

        while (env->created == 0)

            qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100);

        tcg_cpu_thread = env->thread;

        tcg_halt_cond = env->halt_cond;

    } else {

        env->thread = tcg_cpu_thread;

        env->halt_cond = tcg_halt_cond;

    }

}


static int64_t http_seek(URLContext *h, int64_t off, int whence)

{

    HTTPContext *s = h->priv_data;

    URLContext *old_hd = s->hd;

    int64_t old_off = s->off;

    uint8_t old_buf[BUFFER_SIZE];

    int old_buf_size;

    AVDictionary *options = NULL;

    if (whence == AVSEEK_SIZE)

        return s->filesize;

    else if ((whence == SEEK_CUR && off == 0) || (whence == SEEK_SET && off == s->off))

        return s->off;

    else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed)

        return -1;

    /* we save the old context in case the seek fails */

    old_buf_size = s->buf_end - s->buf_ptr;

    memcpy(old_buf, s->buf_ptr, old_buf_size);

    s->hd = NULL;

    if (whence == SEEK_CUR)

        off += s->off;

    else if (whence == SEEK_END)

        off += s->filesize;

    s->off = off;

    /* if it fails, continue on old connection */

    av_dict_copy(&options, s->chained_options, 0);

    if (http_open_cnx(h, &options) < 0) {

        av_dict_free(&options);

        memcpy(s->buffer, old_buf, old_buf_size);

        s->buf_ptr = s->buffer;

        s->buf_end = s->buffer + old_buf_size;

        s->hd = old_hd;

        s->off = old_off;

        return -1;

    }

    av_dict_free(&options);

    ffurl_close(old_hd);

    return off;

}


void qdict_del(QDict *qdict, const char *key)

{

    QDictEntry *entry;

    entry = qdict_find(qdict, key, tdb_hash(key) % QDICT_HASH_SIZE);

    if (entry) {

        LIST_REMOVE(entry, next);

        qentry_destroy(entry);

        qdict->size--;

    }

}


static void migration_bitmap_sync_range(ram_addr_t start, ram_addr_t length)

{

    migration_dirty_pages +=

        cpu_physical_memory_sync_dirty_bitmap(migration_bitmap, start, length);

}


static void xhci_port_write(void *ptr, hwaddr reg,

                            uint64_t val, unsigned size)

{

    XHCIPort *port = ptr;

    uint32_t portsc, notify;

    trace_usb_xhci_port_write(port->portnr, reg, val);

    switch (reg) {

    case 0x00: /* PORTSC */

        /* write-1-to-start bits */

        if (val & PORTSC_PR) {

            xhci_port_reset(port);

            break;

        }

        portsc = port->portsc;

        notify = 0;

        /* write-1-to-clear bits*/

        portsc &= ~(val & (PORTSC_CSC|PORTSC_PEC|PORTSC_WRC|PORTSC_OCC|

                           PORTSC_PRC|PORTSC_PLC|PORTSC_CEC));

        if (val & PORTSC_LWS) {

            /* overwrite PLS only when LWS=1 */

            uint32_t old_pls = get_field(port->portsc, PORTSC_PLS);

            uint32_t new_pls = get_field(val, PORTSC_PLS);

            switch (new_pls) {

            case PLS_U0:

                if (old_pls != PLS_U0) {

                    set_field(&portsc, new_pls, PORTSC_PLS);

                    trace_usb_xhci_port_link(port->portnr, new_pls);

                    notify = PORTSC_PLC;

                }

                break;

            case PLS_U3:

                if (old_pls < PLS_U3) {

                    set_field(&portsc, new_pls, PORTSC_PLS);

                    trace_usb_xhci_port_link(port->portnr, new_pls);

                }

                break;

            case PLS_RESUME:

                /* windows does this for some reason, don't spam stderr */

                break;

            default:

                fprintf(stderr, "%s: ignore pls write (old %d, new %d)\n",

                        __func__, old_pls, new_pls);

                break;

            }

        }

        /* read/write bits */

        portsc &= ~(PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE);

        portsc |= (val & (PORTSC_PP|PORTSC_WCE|PORTSC_WDE|PORTSC_WOE));

        port->portsc = portsc;

        if (notify) {

            xhci_port_notify(port, notify);

        }

        break;

    case 0x04: /* PORTPMSC */

    case 0x08: /* PORTLI */

    default:

        trace_usb_xhci_unimplemented("port write", reg);

    }

}


static int pci_unin_map_irq(PCIDevice *pci_dev, int irq_num)

{

    int retval;

    int devfn = pci_dev->devfn & 0x00FFFFFF;

    retval = (((devfn >> 11) & 0x1F) + irq_num) & 3;

    return retval;

}


static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,

                              void **refcount_table,

                              int64_t *refcount_table_size, int64_t l2_offset,

                              int flags)

{

    BDRVQcow2State *s = bs->opaque;

    uint64_t *l2_table, l2_entry;

    uint64_t next_contiguous_offset = 0;

    int i, l2_size, nb_csectors, ret;

    /* Read L2 table from disk */

    l2_size = s->l2_size * sizeof(uint64_t);

    l2_table = g_malloc(l2_size);

    ret = bdrv_pread(bs->file, l2_offset, l2_table, l2_size);

    if (ret < 0) {

        fprintf(stderr, "ERROR: I/O error in check_refcounts_l2\n");

        res->check_errors++;

        goto fail;

    }

    /* Do the actual checks */

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

        l2_entry = be64_to_cpu(l2_table[i]);

        switch (qcow2_get_cluster_type(l2_entry)) {

        case QCOW2_CLUSTER_COMPRESSED:

            /* Compressed clusters don't have QCOW_OFLAG_COPIED */

            if (l2_entry & QCOW_OFLAG_COPIED) {

                fprintf(stderr, "ERROR: cluster %" PRId64 ": "

                    "copied flag must never be set for compressed "

                    "clusters\n", l2_entry >> s->cluster_bits);

                l2_entry &= ~QCOW_OFLAG_COPIED;

                res->corruptions++;

            }

            /* Mark cluster as used */

            nb_csectors = ((l2_entry >> s->csize_shift) &

                           s->csize_mask) + 1;

            l2_entry &= s->cluster_offset_mask;

            ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,

                                l2_entry & ~511, nb_csectors * 512);

            if (ret < 0) {

                goto fail;

            }

            if (flags & CHECK_FRAG_INFO) {

                res->bfi.allocated_clusters++;

                res->bfi.compressed_clusters++;

                /* Compressed clusters are fragmented by nature.  Since they

                 * take up sub-sector space but we only have sector granularity

                 * I/O we need to re-read the same sectors even for adjacent

                 * compressed clusters.

                 */

                res->bfi.fragmented_clusters++;

            }

            break;

        case QCOW2_CLUSTER_ZERO:

            if ((l2_entry & L2E_OFFSET_MASK) == 0) {

                break;

            }

            /* fall through */

        case QCOW2_CLUSTER_NORMAL:

        {

            uint64_t offset = l2_entry & L2E_OFFSET_MASK;

            if (flags & CHECK_FRAG_INFO) {

                res->bfi.allocated_clusters++;

                if (next_contiguous_offset &&

                    offset != next_contiguous_offset) {

                    res->bfi.fragmented_clusters++;

                }

                next_contiguous_offset = offset + s->cluster_size;

            }

            /* Mark cluster as used */

            ret = inc_refcounts(bs, res, refcount_table, refcount_table_size,

                                offset, s->cluster_size);

            if (ret < 0) {

                goto fail;

            }

            /* Correct offsets are cluster aligned */

            if (offset_into_cluster(s, offset)) {

                fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "

                    "properly aligned; L2 entry corrupted.\n", offset);

                res->corruptions++;

            }

            break;

        }

        case QCOW2_CLUSTER_UNALLOCATED:

            break;

        default:

            abort();

        }

    }

    g_free(l2_table);

    return 0;

fail:

    g_free(l2_table);

    return ret;

}


static int opus_packet(AVFormatContext *avf, int idx)

{

    struct ogg *ogg              = avf->priv_data;

    struct ogg_stream *os        = &ogg->streams[idx];

    AVStream *st                 = avf->streams[idx];

    struct oggopus_private *priv = os->private;

    uint8_t *packet              = os->buf + os->pstart;

    if (!os->psize)

        return AVERROR_INVALIDDATA;

    if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) {

        int seg, d;

        int duration;

        uint8_t *last_pkt  = os->buf + os->pstart;

        uint8_t *next_pkt  = last_pkt;

        duration = 0;

        seg = os->segp;

        d = opus_duration(last_pkt, os->psize);

        if (d < 0) {

            os->pflags |= AV_PKT_FLAG_CORRUPT;

            return 0;

        }

        duration += d;

        last_pkt = next_pkt =  next_pkt + os->psize;

        for (; seg < os->nsegs; seg++) {

            if (os->segments[seg] < 255) {

                int d = opus_duration(last_pkt, os->segments[seg]);

                if (d < 0) {

                    duration = os->granule;

                    break;

                }

                duration += d;

                last_pkt  = next_pkt + os->segments[seg];

            }

            next_pkt += os->segments[seg];

        }

        os->lastpts                 =

        os->lastdts                 = os->granule - duration;

    }

    os->pduration = opus_duration(packet, os->psize);

    if (os->lastpts != AV_NOPTS_VALUE) {

        if (st->start_time == AV_NOPTS_VALUE)

            st->start_time = os->lastpts;

        priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip;

    }

    priv->cur_dts += os->pduration;

    if ((os->flags & OGG_FLAG_EOS)) {

        int64_t skip = priv->cur_dts - os->granule + priv->pre_skip;

        skip = FFMIN(skip, os->pduration);

        if (skip > 0) {

            os->pduration = skip < os->pduration ? os->pduration - skip : 1;

            os->end_trimming = skip;

            av_log(avf, AV_LOG_DEBUG,

                   "Last packet was truncated to %d due to end trimming.\n",

                   os->pduration);

        }

    }

    return 0;

}


static int nsv_read_chunk(AVFormatContext *s, int fill_header)

{

    NSVContext *nsv = s->priv_data;

    AVIOContext *pb = s->pb;

    AVStream *st[2] = {NULL, NULL};

    NSVStream *nst;

    AVPacket *pkt;

    int i, err = 0;

    uint8_t auxcount; /* number of aux metadata, also 4 bits of vsize */

    uint32_t vsize;

    uint16_t asize;

    uint16_t auxsize;

    av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header);

    if (nsv->ahead[0].data || nsv->ahead[1].data)

        return 0; //-1; /* hey! eat what you've in your plate first! */

null_chunk_retry:

    if (avio_feof(pb))

        return -1;

    for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++)

        err = nsv_resync(s);

    if (err < 0)

        return err;

    if (nsv->state == NSV_FOUND_NSVS)

        err = nsv_parse_NSVs_header(s);

    if (err < 0)

        return err;

    if (nsv->state != NSV_HAS_READ_NSVS && nsv->state != NSV_FOUND_BEEF)

        return -1;

    auxcount = avio_r8(pb);

    vsize = avio_rl16(pb);

    asize = avio_rl16(pb);

    vsize = (vsize << 4) | (auxcount >> 4);

    auxcount &= 0x0f;

    av_dlog(s, "NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize);

    /* skip aux stuff */

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

        uint32_t av_unused auxtag;

        auxsize = avio_rl16(pb);

        auxtag = avio_rl32(pb);

        av_dlog(s, "NSV aux data: '%c%c%c%c', %d bytes\n",

              (auxtag & 0x0ff),

              ((auxtag >> 8) & 0x0ff),

              ((auxtag >> 16) & 0x0ff),

              ((auxtag >> 24) & 0x0ff),

              auxsize);

        avio_skip(pb, auxsize);

        vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */

    }

    if (avio_feof(pb))

        return -1;

    if (!vsize && !asize) {

        nsv->state = NSV_UNSYNC;

        goto null_chunk_retry;

    }

    /* map back streams to v,a */

    if (s->nb_streams > 0)

        st[s->streams[0]->id] = s->streams[0];

    if (s->nb_streams > 1)

        st[s->streams[1]->id] = s->streams[1];

    if (vsize && st[NSV_ST_VIDEO]) {

        int ret;

        nst = st[NSV_ST_VIDEO]->priv_data;

        pkt = &nsv->ahead[NSV_ST_VIDEO];

        if ((ret = av_get_packet(pb, pkt, vsize)) < 0)

            return ret;

        pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO;

        pkt->dts = nst->frame_offset;

        pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */

        for (i = 0; i < FFMIN(8, vsize); i++)

            av_dlog(s, "NSV video: [%d] = %02x\n", i, pkt->data[i]);

    }

    if(st[NSV_ST_VIDEO])

        ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++;

    if (asize && st[NSV_ST_AUDIO]) {

        nst = st[NSV_ST_AUDIO]->priv_data;

        pkt = &nsv->ahead[NSV_ST_AUDIO];

        /* read raw audio specific header on the first audio chunk... */

        /* on ALL audio chunks ?? seems so! */

        if (asize && st[NSV_ST_AUDIO]->codec->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) {

            uint8_t bps;

            uint8_t channels;

            uint16_t samplerate;

            bps = avio_r8(pb);

            channels = avio_r8(pb);

            samplerate = avio_rl16(pb);

            asize-=4;

            av_dlog(s, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);

            if (fill_header) {

                st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */

                if (bps != 16) {

                    av_dlog(s, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps);

                }

                if(channels)

                    bps /= channels; // ???

                else

                    av_log(s, AV_LOG_WARNING, "Channels is 0\n");

                if (bps == 8)

                    st[NSV_ST_AUDIO]->codec->codec_id = AV_CODEC_ID_PCM_U8;

                samplerate /= 4;/* UGH ??? XXX */

                channels = 1;

                st[NSV_ST_AUDIO]->codec->channels = channels;

                st[NSV_ST_AUDIO]->codec->sample_rate = samplerate;

                av_dlog(s, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate);

            }

        }

        av_get_packet(pb, pkt, asize);

        pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO;

        pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */

        if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) {

            /* on a nsvs frame we have new information on a/v sync */

            pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1);

            pkt->dts *= (int64_t)1000        * nsv->framerate.den;

            pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num;

            av_dlog(s, "NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts);

        }

        nst->frame_offset++;

    }

    nsv->state = NSV_UNSYNC;

    return 0;

}


static void virtio_pci_common_write(void *opaque, hwaddr addr,

                                    uint64_t val, unsigned size)

{

    VirtIOPCIProxy *proxy = opaque;

    VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);

    switch (addr) {

    case VIRTIO_PCI_COMMON_DFSELECT:

        proxy->dfselect = val;

        break;

    case VIRTIO_PCI_COMMON_GFSELECT:

        proxy->gfselect = val;

        break;

    case VIRTIO_PCI_COMMON_GF:

        if (proxy->gfselect <= ARRAY_SIZE(proxy->guest_features)) {

            proxy->guest_features[proxy->gfselect] = val;

            virtio_set_features(vdev,

                                (((uint64_t)proxy->guest_features[1]) << 32) |

                                proxy->guest_features[0]);

        }

        break;

    case VIRTIO_PCI_COMMON_MSIX:

        msix_vector_unuse(&proxy->pci_dev, vdev->config_vector);

        /* Make it possible for guest to discover an error took place. */

        if (msix_vector_use(&proxy->pci_dev, val) < 0) {

            val = VIRTIO_NO_VECTOR;

        }

        vdev->config_vector = val;

        break;

    case VIRTIO_PCI_COMMON_STATUS:

        if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) {

            virtio_pci_stop_ioeventfd(proxy);

        }

        virtio_set_status(vdev, val & 0xFF);

        if (val & VIRTIO_CONFIG_S_DRIVER_OK) {

            virtio_pci_start_ioeventfd(proxy);

        }

        if (vdev->status == 0) {

            virtio_reset(vdev);

            msix_unuse_all_vectors(&proxy->pci_dev);

        }

        break;

    case VIRTIO_PCI_COMMON_Q_SELECT:

        if (val < VIRTIO_QUEUE_MAX) {

            vdev->queue_sel = val;

        }

        break;

    case VIRTIO_PCI_COMMON_Q_SIZE:

        proxy->vqs[vdev->queue_sel].num = val;

        break;

    case VIRTIO_PCI_COMMON_Q_MSIX:

        msix_vector_unuse(&proxy->pci_dev,

                          virtio_queue_vector(vdev, vdev->queue_sel));

        /* Make it possible for guest to discover an error took place. */

        if (msix_vector_use(&proxy->pci_dev, val) < 0) {

            val = VIRTIO_NO_VECTOR;

        }

        virtio_queue_set_vector(vdev, vdev->queue_sel, val);

        break;

    case VIRTIO_PCI_COMMON_Q_ENABLE:

        /* TODO: need a way to put num back on reset. */

        virtio_queue_set_num(vdev, vdev->queue_sel,

                             proxy->vqs[vdev->queue_sel].num);

        virtio_queue_set_rings(vdev, vdev->queue_sel,

                       ((uint64_t)proxy->vqs[vdev->queue_sel].desc[1]) << 32 |

                       proxy->vqs[vdev->queue_sel].desc[0],

                       ((uint64_t)proxy->vqs[vdev->queue_sel].avail[1]) << 32 |

                       proxy->vqs[vdev->queue_sel].avail[0],

                       ((uint64_t)proxy->vqs[vdev->queue_sel].used[1]) << 32 |

                       proxy->vqs[vdev->queue_sel].used[0]);

        break;

    case VIRTIO_PCI_COMMON_Q_DESCLO:

        proxy->vqs[vdev->queue_sel].desc[0] = val;

        break;

    case VIRTIO_PCI_COMMON_Q_DESCHI:

        proxy->vqs[vdev->queue_sel].desc[1] = val;

        break;

    case VIRTIO_PCI_COMMON_Q_AVAILLO:

        proxy->vqs[vdev->queue_sel].avail[0] = val;

        break;

    case VIRTIO_PCI_COMMON_Q_AVAILHI:

        proxy->vqs[vdev->queue_sel].avail[1] = val;

        break;

    case VIRTIO_PCI_COMMON_Q_USEDLO:

        proxy->vqs[vdev->queue_sel].used[0] = val;

        break;

    case VIRTIO_PCI_COMMON_Q_USEDHI:

        proxy->vqs[vdev->queue_sel].used[1] = val;

        break;

    default:

        break;

    }

}


void tcp_start_outgoing_migration(MigrationState *s,

                                  const char *host_port,

                                  Error **errp)

{

    Error *err = NULL;

    SocketAddress *saddr = tcp_build_address(host_port, &err);

    if (!err) {

        socket_start_outgoing_migration(s, saddr, &err);

    }

    error_propagate(errp, err);

}


static int ast2400_rambits(AspeedSDMCState *s)

{

    switch (s->ram_size >> 20) {

    case 64:

        return ASPEED_SDMC_DRAM_64MB;

    case 128:

        return ASPEED_SDMC_DRAM_128MB;

    case 256:

        return ASPEED_SDMC_DRAM_256MB;

    case 512:

        return ASPEED_SDMC_DRAM_512MB;

    default:

        break;

    }

    /* use a common default */

    error_report("warning: Invalid RAM size 0x%" PRIx64

                 ". Using default 256M", s->ram_size);

    s->ram_size = 256 << 20;

    return ASPEED_SDMC_DRAM_256MB;

}


static int decode_slice(MpegEncContext *s){

    const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;

    const int mb_size= 16>>s->avctx->lowres;

    int ret;

    s->last_resync_gb= s->gb;

    s->first_slice_line= 1;

    s->resync_mb_x= s->mb_x;

    s->resync_mb_y= s->mb_y;

    ff_set_qscale(s, s->qscale);

    if (s->avctx->hwaccel) {

        const uint8_t *start= s->gb.buffer + get_bits_count(&s->gb)/8;

        const uint8_t *end  = ff_h263_find_resync_marker(start + 1, s->gb.buffer_end);

        skip_bits_long(&s->gb, 8*(end - start));

        return s->avctx->hwaccel->decode_slice(s->avctx, start, end - start);

    }

    if(s->partitioned_frame){

        const int qscale= s->qscale;

        if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){

            if ((ret = ff_mpeg4_decode_partitions(s)) < 0)

                return ret;

        }

        /* restore variables which were modified */

        s->first_slice_line=1;

        s->mb_x= s->resync_mb_x;

        s->mb_y= s->resync_mb_y;

        ff_set_qscale(s, qscale);

    }

    for(; s->mb_y < s->mb_height; s->mb_y++) {

        /* per-row end of slice checks */

        if(s->msmpeg4_version){

            if(s->resync_mb_y + s->slice_height == s->mb_y){

                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);

                return 0;

            }

        }

        if(s->msmpeg4_version==1){

            s->last_dc[0]=

            s->last_dc[1]=

            s->last_dc[2]= 128;

        }

        ff_init_block_index(s);

        for(; s->mb_x < s->mb_width; s->mb_x++) {

            int ret;

            ff_update_block_index(s);

            if(s->resync_mb_x == s->mb_x && s->resync_mb_y+1 == s->mb_y){

                s->first_slice_line=0;

            }

            /* DCT & quantize */

            s->mv_dir = MV_DIR_FORWARD;

            s->mv_type = MV_TYPE_16X16;

//            s->mb_skipped = 0;

            av_dlog(s, "%d %d %06X\n",

                    ret, get_bits_count(&s->gb), show_bits(&s->gb, 24));

            ret= s->decode_mb(s, s->block);

            if (s->pict_type!=AV_PICTURE_TYPE_B)

                ff_h263_update_motion_val(s);

            if(ret<0){

                const int xy= s->mb_x + s->mb_y*s->mb_stride;

                if(ret==SLICE_END){

                    ff_MPV_decode_mb(s, s->block);

                    if(s->loop_filter)

                        ff_h263_loop_filter(s);

                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);

                    s->padding_bug_score--;

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

                        s->mb_x=0;

                        ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);

                        ff_MPV_report_decode_progress(s);

                        s->mb_y++;

                    }

                    return 0;

                }else if(ret==SLICE_NOEND){

                    av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);

                    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);

                    return AVERROR_INVALIDDATA;

                }

                av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);

                ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);

                return AVERROR_INVALIDDATA;

            }

            ff_MPV_decode_mb(s, s->block);

            if(s->loop_filter)

                ff_h263_loop_filter(s);

        }

        ff_draw_horiz_band(s, s->mb_y*mb_size, mb_size);

        ff_MPV_report_decode_progress(s);

        s->mb_x= 0;

    }

    assert(s->mb_x==0 && s->mb_y==s->mb_height);

    if(s->codec_id==AV_CODEC_ID_MPEG4

       && (s->workaround_bugs&FF_BUG_AUTODETECT)

       && get_bits_left(&s->gb) >= 48

       && show_bits(&s->gb, 24)==0x4010

       && !s->data_partitioning)

        s->padding_bug_score+=32;

    /* try to detect the padding bug */

    if(      s->codec_id==AV_CODEC_ID_MPEG4

       &&   (s->workaround_bugs&FF_BUG_AUTODETECT)

       &&    get_bits_left(&s->gb) >=0

       &&    get_bits_left(&s->gb) < 137

//       &&   !s->resync_marker

       &&   !s->data_partitioning){

        const int bits_count= get_bits_count(&s->gb);

        const int bits_left = s->gb.size_in_bits - bits_count;

        if(bits_left==0){

            s->padding_bug_score+=16;

        } else if(bits_left != 1){

            int v= show_bits(&s->gb, 8);

            v|= 0x7F >> (7-(bits_count&7));

            if(v==0x7F && bits_left<=8)

                s->padding_bug_score--;

            else if(v==0x7F && ((get_bits_count(&s->gb)+8)&8) && bits_left<=16)

                s->padding_bug_score+= 4;

            else

                s->padding_bug_score++;

        }

    }

    if(s->workaround_bugs&FF_BUG_AUTODETECT){

        if(s->padding_bug_score > -2 && !s->data_partitioning /*&& (s->divx_version>=0 || !s->resync_marker)*/)

            s->workaround_bugs |=  FF_BUG_NO_PADDING;

        else

            s->workaround_bugs &= ~FF_BUG_NO_PADDING;

    }

    // handle formats which don't have unique end markers

    if(s->msmpeg4_version || (s->workaround_bugs&FF_BUG_NO_PADDING)){ //FIXME perhaps solve this more cleanly

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

        int max_extra=7;

        /* no markers in M$ crap */

        if(s->msmpeg4_version && s->pict_type==AV_PICTURE_TYPE_I)

            max_extra+= 17;

        /* buggy padding but the frame should still end approximately at the bitstream end */

        if((s->workaround_bugs&FF_BUG_NO_PADDING) && (s->err_recognition&(AV_EF_BUFFER|AV_EF_AGGRESSIVE)))

            max_extra+= 48;

        else if((s->workaround_bugs&FF_BUG_NO_PADDING))

            max_extra+= 256*256*256*64;

        if(left>max_extra){

            av_log(s->avctx, AV_LOG_ERROR, "discarding %d junk bits at end, next would be %X\n", left, show_bits(&s->gb, 24));

        }

        else if(left<0){

            av_log(s->avctx, AV_LOG_ERROR, "overreading %d bits\n", -left);

        }else

            ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END);

        return 0;

    }

    av_log(s->avctx, AV_LOG_ERROR, "slice end not reached but screenspace end (%d left %06X, score= %d)\n",

            get_bits_left(&s->gb),

            show_bits(&s->gb, 24), s->padding_bug_score);

    ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);

    return AVERROR_INVALIDDATA;

}


static void get_fcb_param(FCBParam *optim, int16_t *impulse_resp,

                          int16_t *buf, int pulse_cnt, int pitch_lag)

{

    FCBParam param;

    int16_t impulse_r[SUBFRAME_LEN];

    int16_t temp_corr[SUBFRAME_LEN];

    int16_t impulse_corr[SUBFRAME_LEN];

    int ccr1[SUBFRAME_LEN];

    int ccr2[SUBFRAME_LEN];

    int amp, err, max, max_amp_index, min, scale, i, j, k, l;

    int64_t temp;

    /* Update impulse response */

    memcpy(impulse_r, impulse_resp, sizeof(int16_t) * SUBFRAME_LEN);

    param.dirac_train = 0;

    if (pitch_lag < SUBFRAME_LEN - 2) {

        param.dirac_train = 1;

        gen_dirac_train(impulse_r, pitch_lag);

    }

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

        temp_corr[i] = impulse_r[i] >> 1;

    /* Compute impulse response autocorrelation */

    temp = dot_product(temp_corr, temp_corr, SUBFRAME_LEN);

    scale = normalize_bits_int32(temp);

    impulse_corr[0] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16;

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

        temp = dot_product(temp_corr + i, temp_corr, SUBFRAME_LEN - i);

        impulse_corr[i] = av_clipl_int32((temp << scale) + (1 << 15)) >> 16;

    }

    /* Compute crosscorrelation of impulse response with residual signal */

    scale -= 4;

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

        temp = dot_product(buf + i, impulse_r, SUBFRAME_LEN - i);

        if (scale < 0)

            ccr1[i] = temp >> -scale;

        else

            ccr1[i] = av_clipl_int32(temp << scale);

    }

    /* Search loop */

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

        /* Maximize the crosscorrelation */

        max = 0;

        for (j = i; j < SUBFRAME_LEN; j += GRID_SIZE) {

            temp = FFABS(ccr1[j]);

            if (temp >= max) {

                max = temp;

                param.pulse_pos[0] = j;

            }

        }

        /* Quantize the gain (max crosscorrelation/impulse_corr[0]) */

        amp = max;

        min = 1 << 30;

        max_amp_index = GAIN_LEVELS - 2;

        for (j = max_amp_index; j >= 2; j--) {

            temp = av_clipl_int32((int64_t)fixed_cb_gain[j] *

                                  impulse_corr[0] << 1);

            temp = FFABS(temp - amp);

            if (temp < min) {

                min = temp;

                max_amp_index = j;

            }

        }

        max_amp_index--;

        /* Select additional gain values */

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

            for (k = i; k < SUBFRAME_LEN; k += GRID_SIZE) {

                temp_corr[k] = 0;

                ccr2[k]      = ccr1[k];

            }

            param.amp_index = max_amp_index + j - 2;

            amp = fixed_cb_gain[param.amp_index];

            param.pulse_sign[0] = (ccr2[param.pulse_pos[0]] < 0) ? -amp : amp;

            temp_corr[param.pulse_pos[0]] = 1;

            for (k = 1; k < pulse_cnt; k++) {

                max = -1 << 30;

                for (l = i; l < SUBFRAME_LEN; l += GRID_SIZE) {

                    if (temp_corr[l])

                        continue;

                    temp = impulse_corr[FFABS(l - param.pulse_pos[k - 1])];

                    temp = av_clipl_int32((int64_t)temp *

                                          param.pulse_sign[k - 1] << 1);

                    ccr2[l] -= temp;

                    temp = FFABS(ccr2[l]);

                    if (temp > max) {

                        max = temp;

                        param.pulse_pos[k] = l;

                    }

                }

                param.pulse_sign[k] = (ccr2[param.pulse_pos[k]] < 0) ?

                                      -amp : amp;

                temp_corr[param.pulse_pos[k]] = 1;

            }

            /* Create the error vector */

            memset(temp_corr, 0, sizeof(int16_t) * SUBFRAME_LEN);

            for (k = 0; k < pulse_cnt; k++)

                temp_corr[param.pulse_pos[k]] = param.pulse_sign[k];

            for (k = SUBFRAME_LEN - 1; k >= 0; k--) {

                temp = 0;

                for (l = 0; l <= k; l++) {

                    int prod = av_clipl_int32((int64_t)temp_corr[l] *

                                              impulse_r[k - l] << 1);

                    temp     = av_clipl_int32(temp + prod);

                }

                temp_corr[k] = temp << 2 >> 16;

            }

            /* Compute square of error */

            err = 0;

            for (k = 0; k < SUBFRAME_LEN; k++) {

                int64_t prod;

                prod = av_clipl_int32((int64_t)buf[k] * temp_corr[k] << 1);

                err  = av_clipl_int32(err - prod);

                prod = av_clipl_int32((int64_t)temp_corr[k] * temp_corr[k]);

                err  = av_clipl_int32(err + prod);

            }

            /* Minimize */

            if (err < optim->min_err) {

                optim->min_err     = err;

                optim->grid_index  = i;

                optim->amp_index   = param.amp_index;

                optim->dirac_train = param.dirac_train;

                for (k = 0; k < pulse_cnt; k++) {

                    optim->pulse_sign[k] = param.pulse_sign[k];

                    optim->pulse_pos[k]  = param.pulse_pos[k];

                }

            }

        }

    }

}


static ssize_t proxy_readlink(FsContext *fs_ctx, V9fsPath *fs_path,

                              char *buf, size_t bufsz)

{

    int retval;

    retval = v9fs_request(fs_ctx->private, T_READLINK, buf, "sd",

                          fs_path, bufsz);

    if (retval < 0) {

        errno = -retval;

        return -1;

    }

    return strlen(buf);

}


static void gt64120_writel (void *opaque, target_phys_addr_t addr,

                            uint32_t val)

{

    GT64120State *s = opaque;

    uint32_t saddr;

#ifdef TARGET_WORDS_BIGENDIAN

    val = bswap32(val);

#endif

    saddr = (addr & 0xfff) >> 2;

    switch (saddr) {

    /* CPU Configuration */

    case GT_CPU:

        s->regs[GT_CPU] = val;

        break;

    case GT_MULTI:

	/* Read-only register as only one GT64xxx is present on the CPU bus */

        break;

    /* CPU Address Decode */

    case GT_PCI0IOLD:

        s->regs[GT_PCI0IOLD]    = val & 0x00007fff;

        s->regs[GT_PCI0IOREMAP] = val & 0x000007ff;

        gt64120_pci_mapping(s);

        break;

    case GT_PCI0M0LD:

        s->regs[GT_PCI0M0LD]    = val & 0x00007fff;

        s->regs[GT_PCI0M0REMAP] = val & 0x000007ff;

        break;

    case GT_PCI0M1LD:

        s->regs[GT_PCI0M1LD]    = val & 0x00007fff;

        s->regs[GT_PCI0M1REMAP] = val & 0x000007ff;

        break;

    case GT_PCI1IOLD:

        s->regs[GT_PCI1IOLD]    = val & 0x00007fff;

        s->regs[GT_PCI1IOREMAP] = val & 0x000007ff;

        break;

    case GT_PCI1M0LD:

        s->regs[GT_PCI1M0LD]    = val & 0x00007fff;

        s->regs[GT_PCI1M0REMAP] = val & 0x000007ff;

        break;

    case GT_PCI1M1LD:

        s->regs[GT_PCI1M1LD]    = val & 0x00007fff;

        s->regs[GT_PCI1M1REMAP] = val & 0x000007ff;

        break;

    case GT_PCI0IOHD:

        s->regs[saddr] = val & 0x0000007f;

        gt64120_pci_mapping(s);

        break;

    case GT_PCI0M0HD:

    case GT_PCI0M1HD:

    case GT_PCI1IOHD:

    case GT_PCI1M0HD:

    case GT_PCI1M1HD:

        s->regs[saddr] = val & 0x0000007f;

        break;

    case GT_ISD:

        s->regs[saddr] = val & 0x00007fff;

        gt64120_isd_mapping(s);

        break;

    case GT_PCI0IOREMAP:

    case GT_PCI0M0REMAP:

    case GT_PCI0M1REMAP:

    case GT_PCI1IOREMAP:

    case GT_PCI1M0REMAP:

    case GT_PCI1M1REMAP:

        s->regs[saddr] = val & 0x000007ff;

        break;

    /* CPU Error Report */

    case GT_CPUERR_ADDRLO:

    case GT_CPUERR_ADDRHI:

    case GT_CPUERR_DATALO:

    case GT_CPUERR_DATAHI:

    case GT_CPUERR_PARITY:

	/* Read-only registers, do nothing */

        break;

    /* CPU Sync Barrier */

    case GT_PCI0SYNC:

    case GT_PCI1SYNC:

	/* Read-only registers, do nothing */

        break;

    /* SDRAM and Device Address Decode */

    case GT_SCS0LD:

    case GT_SCS0HD:

    case GT_SCS1LD:

    case GT_SCS1HD:

    case GT_SCS2LD:

    case GT_SCS2HD:

    case GT_SCS3LD:

    case GT_SCS3HD:

    case GT_CS0LD:

    case GT_CS0HD:

    case GT_CS1LD:

    case GT_CS1HD:

    case GT_CS2LD:

    case GT_CS2HD:

    case GT_CS3LD:

    case GT_CS3HD:

    case GT_BOOTLD:

    case GT_BOOTHD:

    case GT_ADERR:

    /* SDRAM Configuration */

    case GT_SDRAM_CFG:

    case GT_SDRAM_OPMODE:

    case GT_SDRAM_BM:

    case GT_SDRAM_ADDRDECODE:

        /* Accept and ignore SDRAM interleave configuration */

        s->regs[saddr] = val;

        break;

    /* Device Parameters */

    case GT_DEV_B0:

    case GT_DEV_B1:

    case GT_DEV_B2:

    case GT_DEV_B3:

    case GT_DEV_BOOT:

        /* Not implemented */

        dprintf ("Unimplemented device register offset 0x%x\n", saddr << 2);

        break;

    /* ECC */

    case GT_ECC_ERRDATALO:

    case GT_ECC_ERRDATAHI:

    case GT_ECC_MEM:

    case GT_ECC_CALC:

    case GT_ECC_ERRADDR:

        /* Read-only registers, do nothing */

        break;

    /* DMA Record */

    case GT_DMA0_CNT:

    case GT_DMA1_CNT:

    case GT_DMA2_CNT:

    case GT_DMA3_CNT:

    case GT_DMA0_SA:

    case GT_DMA1_SA:

    case GT_DMA2_SA:

    case GT_DMA3_SA:

    case GT_DMA0_DA:

    case GT_DMA1_DA:

    case GT_DMA2_DA:

    case GT_DMA3_DA:

    case GT_DMA0_NEXT:

    case GT_DMA1_NEXT:

    case GT_DMA2_NEXT:

    case GT_DMA3_NEXT:

    case GT_DMA0_CUR:

    case GT_DMA1_CUR:

    case GT_DMA2_CUR:

    case GT_DMA3_CUR:

        /* Not implemented */

        dprintf ("Unimplemented DMA register offset 0x%x\n", saddr << 2);

        break;

    /* DMA Channel Control */

    case GT_DMA0_CTRL:

    case GT_DMA1_CTRL:

    case GT_DMA2_CTRL:

    case GT_DMA3_CTRL:

        /* Not implemented */

        dprintf ("Unimplemented DMA register offset 0x%x\n", saddr << 2);

        break;

    /* DMA Arbiter */

    case GT_DMA_ARB:

        /* Not implemented */

        dprintf ("Unimplemented DMA register offset 0x%x\n", saddr << 2);

        break;

    /* Timer/Counter */

    case GT_TC0:

    case GT_TC1:

    case GT_TC2:

    case GT_TC3:

    case GT_TC_CONTROL:

        /* Not implemented */

        dprintf ("Unimplemented timer register offset 0x%x\n", saddr << 2);

        break;

    /* PCI Internal */

    case GT_PCI0_CMD:

    case GT_PCI1_CMD:

        s->regs[saddr] = val & 0x0401fc0f;

        break;

    case GT_PCI0_TOR:

    case GT_PCI0_BS_SCS10:

    case GT_PCI0_BS_SCS32:

    case GT_PCI0_BS_CS20:

    case GT_PCI0_BS_CS3BT:

    case GT_PCI1_IACK:

    case GT_PCI0_IACK:

    case GT_PCI0_BARE:

    case GT_PCI0_PREFMBR:

    case GT_PCI0_SCS10_BAR:

    case GT_PCI0_SCS32_BAR:

    case GT_PCI0_CS20_BAR:

    case GT_PCI0_CS3BT_BAR:

    case GT_PCI0_SSCS10_BAR:

    case GT_PCI0_SSCS32_BAR:

    case GT_PCI0_SCS3BT_BAR:

    case GT_PCI1_TOR:

    case GT_PCI1_BS_SCS10:

    case GT_PCI1_BS_SCS32:

    case GT_PCI1_BS_CS20:

    case GT_PCI1_BS_CS3BT:

    case GT_PCI1_BARE:

    case GT_PCI1_PREFMBR:

    case GT_PCI1_SCS10_BAR:

    case GT_PCI1_SCS32_BAR:

    case GT_PCI1_CS20_BAR:

    case GT_PCI1_CS3BT_BAR:

    case GT_PCI1_SSCS10_BAR:

    case GT_PCI1_SSCS32_BAR:

    case GT_PCI1_SCS3BT_BAR:

    case GT_PCI1_CFGADDR:

    case GT_PCI1_CFGDATA:

        /* not implemented */

        break;

    case GT_PCI0_CFGADDR:

        s->pci->config_reg = val & 0x80fffffc;

        break;

    case GT_PCI0_CFGDATA:

        if (s->pci->config_reg & (1u << 31))

            pci_host_data_writel(s->pci, 0, val);

        break;

    /* Interrupts */

    case GT_INTRCAUSE:

        /* not really implemented */

        s->regs[saddr] = ~(~(s->regs[saddr]) | ~(val & 0xfffffffe));

        s->regs[saddr] |= !!(s->regs[saddr] & 0xfffffffe);

        dprintf("INTRCAUSE %x\n", val);

        break;

    case GT_INTRMASK:

        s->regs[saddr] = val & 0x3c3ffffe;

        dprintf("INTRMASK %x\n", val);

        break;

    case GT_PCI0_ICMASK:

        s->regs[saddr] = val & 0x03fffffe;

        dprintf("ICMASK %x\n", val);

        break;

    case GT_PCI0_SERR0MASK:

        s->regs[saddr] = val & 0x0000003f;

        dprintf("SERR0MASK %x\n", val);

        break;

    /* Reserved when only PCI_0 is configured. */

    case GT_HINTRCAUSE:

    case GT_CPU_INTSEL:

    case GT_PCI0_INTSEL:

    case GT_HINTRMASK:

    case GT_PCI0_HICMASK:

    case GT_PCI1_SERR1MASK:

        /* not implemented */

        break;

    /* SDRAM Parameters */

    case GT_SDRAM_B0:

    case GT_SDRAM_B1:

    case GT_SDRAM_B2:

    case GT_SDRAM_B3:

        /* We don't simulate electrical parameters of the SDRAM.

           Accept, but ignore the values. */

        s->regs[saddr] = val;

        break;

    default:

        dprintf ("Bad register offset 0x%x\n", (int)addr);

        break;

    }

}


static void buffer_reset(Buffer *buffer)

{

	buffer->offset = 0;

}


static int vp9_decode_update_thread_context(AVCodecContext *dst, const AVCodecContext *src)

{

    int i, res;

    VP9Context *s = dst->priv_data, *ssrc = src->priv_data;

    // FIXME scalability, size, etc.

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

        if (s->frames[i].tf.f->data[0])

            vp9_unref_frame(dst, &s->frames[i]);

        if (ssrc->frames[i].tf.f->data[0]) {

            if ((res = vp9_ref_frame(dst, &s->frames[i], &ssrc->frames[i])) < 0)

                return res;

        }

    }

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

        if (s->refs[i].f->data[0])

            ff_thread_release_buffer(dst, &s->refs[i]);

        if (ssrc->next_refs[i].f->data[0]) {

            if ((res = ff_thread_ref_frame(&s->refs[i], &ssrc->next_refs[i])) < 0)

                return res;

        }

    }

    s->invisible = ssrc->invisible;

    s->keyframe = ssrc->keyframe;

    s->uses_2pass = ssrc->uses_2pass;

    memcpy(&s->prob_ctx, &ssrc->prob_ctx, sizeof(s->prob_ctx));

    memcpy(&s->lf_delta, &ssrc->lf_delta, sizeof(s->lf_delta));

    if (ssrc->segmentation.enabled) {

        memcpy(&s->segmentation.feat, &ssrc->segmentation.feat,

               sizeof(s->segmentation.feat));

    }

    return 0;

}


static void test_hash_speed(const void *opaque)

{

    size_t chunk_size = (size_t)opaque;

    uint8_t *in = NULL, *out = NULL;

    size_t out_len = 0;

    double total = 0.0;

    struct iovec iov;

    int ret;

    in = g_new0(uint8_t, chunk_size);

    memset(in, g_test_rand_int(), chunk_size);

    iov.iov_base = (char *)in;

    iov.iov_len = chunk_size;

    g_test_timer_start();

    do {

        ret = qcrypto_hash_bytesv(QCRYPTO_HASH_ALG_SHA256,

                                  &iov, 1, &out, &out_len,

                                  NULL);

        g_assert(ret == 0);

        total += chunk_size;

    } while (g_test_timer_elapsed() < 5.0);

    total /= 1024 * 1024; /* to MB */

    g_print("sha256: ");

    g_print("Testing chunk_size %ld bytes ", chunk_size);

    g_print("done: %.2f MB in %.2f secs: ", total, g_test_timer_last());

    g_print("%.2f MB/sec\n", total / g_test_timer_last());

    g_free(out);

    g_free(in);

}


static int vhost_kernel_memslots_limit(struct vhost_dev *dev)

{

    int limit = 64;

    char *s;

    if (g_file_get_contents("/sys/module/vhost/parameters/max_mem_regions",

                            &s, NULL, NULL)) {

        uint64_t val = g_ascii_strtoull(s, NULL, 10);

        if (!((val == G_MAXUINT64 || !val) && errno)) {

            return val;

        }

        error_report("ignoring invalid max_mem_regions value in vhost module:"

                     " %s", s);

    }

    return limit;

}


static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift)

{

    MotionEstContext * const c= &s->me;

    const int size= 1;

    const int h=8;

    int block;

    int P[10][2];

    int dmin_sum=0, mx4_sum=0, my4_sum=0;

    int same=1;

    const int stride= c->stride;

    uint8_t *mv_penalty= c->current_mv_penalty;

    init_mv4_ref(c);

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

        int mx4, my4;

        int pred_x4, pred_y4;

        int dmin4;

        static const int off[4]= {2, 1, 1, -1};

        const int mot_stride = s->b8_stride;

        const int mot_xy = s->block_index[block];

        P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0];

        P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1];

        if(P_LEFT[0]       > (c->xmax<<shift)) P_LEFT[0]       = (c->xmax<<shift);

        /* special case for first line */

        if (s->first_slice_line && block<2) {

            c->pred_x= pred_x4= P_LEFT[0];

            c->pred_y= pred_y4= P_LEFT[1];

        } else {

            P_TOP[0]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][0];

            P_TOP[1]      = s->current_picture.motion_val[0][mot_xy - mot_stride             ][1];

            P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0];

            P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1];

            if(P_TOP[1]      > (c->ymax<<shift)) P_TOP[1]     = (c->ymax<<shift);

            if(P_TOPRIGHT[0] < (c->xmin<<shift)) P_TOPRIGHT[0]= (c->xmin<<shift);

            if(P_TOPRIGHT[0] > (c->xmax<<shift)) P_TOPRIGHT[0]= (c->xmax<<shift);

            if(P_TOPRIGHT[1] > (c->ymax<<shift)) P_TOPRIGHT[1]= (c->ymax<<shift);

            P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]);

            P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]);

            c->pred_x= pred_x4 = P_MEDIAN[0];

            c->pred_y= pred_y4 = P_MEDIAN[1];

        }

        P_MV1[0]= mx;

        P_MV1[1]= my;

        dmin4 = epzs_motion_search4(s, &mx4, &my4, P, block, block, s->p_mv_table, (1<<16)>>shift);

        dmin4= c->sub_motion_search(s, &mx4, &my4, dmin4, block, block, size, h);

        if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){

            int dxy;

            const int offset= ((block&1) + (block>>1)*stride)*8;

            uint8_t *dest_y = c->scratchpad + offset;

            if(s->quarter_sample){

                uint8_t *ref= c->ref[block][0] + (mx4>>2) + (my4>>2)*stride;

                dxy = ((my4 & 3) << 2) | (mx4 & 3);

                if(s->no_rounding)

                    s->dsp.put_no_rnd_qpel_pixels_tab[1][dxy](dest_y   , ref    , stride);

                else

                    s->dsp.put_qpel_pixels_tab       [1][dxy](dest_y   , ref    , stride);

            }else{

                uint8_t *ref= c->ref[block][0] + (mx4>>1) + (my4>>1)*stride;

                dxy = ((my4 & 1) << 1) | (mx4 & 1);

                if(s->no_rounding)

                    s->hdsp.put_no_rnd_pixels_tab[1][dxy](dest_y    , ref    , stride, h);

                else

                    s->hdsp.put_pixels_tab       [1][dxy](dest_y    , ref    , stride, h);

            }

            dmin_sum+= (mv_penalty[mx4-pred_x4] + mv_penalty[my4-pred_y4])*c->mb_penalty_factor;

        }else

            dmin_sum+= dmin4;

        if(s->quarter_sample){

            mx4_sum+= mx4/2;

            my4_sum+= my4/2;

        }else{

            mx4_sum+= mx4;

            my4_sum+= my4;

        }

        s->current_picture.motion_val[0][s->block_index[block]][0] = mx4;

        s->current_picture.motion_val[0][s->block_index[block]][1] = my4;

        if(mx4 != mx || my4 != my) same=0;

    }

    if(same)

        return INT_MAX;

    if(s->dsp.me_sub_cmp[0] != s->dsp.mb_cmp[0]){

        dmin_sum += s->dsp.mb_cmp[0](s, s->new_picture.f.data[0] + s->mb_x*16 + s->mb_y*16*stride, c->scratchpad, stride, 16);

    }

    if(c->avctx->mb_cmp&FF_CMP_CHROMA){

        int dxy;

        int mx, my;

        int offset;

        mx= ff_h263_round_chroma(mx4_sum);

        my= ff_h263_round_chroma(my4_sum);

        dxy = ((my & 1) << 1) | (mx & 1);

        offset= (s->mb_x*8 + (mx>>1)) + (s->mb_y*8 + (my>>1))*s->uvlinesize;

        if(s->no_rounding){

            s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad    , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);

            s->hdsp.put_no_rnd_pixels_tab[1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);

        }else{

            s->hdsp.put_pixels_tab       [1][dxy](c->scratchpad    , s->last_picture.f.data[1] + offset, s->uvlinesize, 8);

            s->hdsp.put_pixels_tab       [1][dxy](c->scratchpad + 8, s->last_picture.f.data[2] + offset, s->uvlinesize, 8);

        }

        dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.f.data[1] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad  , s->uvlinesize, 8);

        dmin_sum += s->dsp.mb_cmp[1](s, s->new_picture.f.data[2] + s->mb_x*8 + s->mb_y*8*s->uvlinesize, c->scratchpad+8, s->uvlinesize, 8);

    }

    c->pred_x= mx;

    c->pred_y= my;

    switch(c->avctx->mb_cmp&0xFF){

    /*case FF_CMP_SSE:

        return dmin_sum+ 32*s->qscale*s->qscale;*/

    case FF_CMP_RD:

        return dmin_sum;

    default:

        return dmin_sum+ 11*c->mb_penalty_factor;

    }

}


static inline void powerpc_excp(CPUState *env, int excp_model, int excp)

{

    target_ulong msr, new_msr, vector;

    int srr0, srr1, asrr0, asrr1;

    int lpes0, lpes1, lev;

    if (0) {

        /* XXX: find a suitable condition to enable the hypervisor mode */

        lpes0 = (env->spr[SPR_LPCR] >> 1) & 1;

        lpes1 = (env->spr[SPR_LPCR] >> 2) & 1;

    } else {

        /* Those values ensure we won't enter the hypervisor mode */

        lpes0 = 0;

        lpes1 = 1;

    }

    qemu_log_mask(CPU_LOG_INT, "Raise exception at " TARGET_FMT_lx

                  " => %08x (%02x)\n", env->nip, excp, env->error_code);

    /* new srr1 value excluding must-be-zero bits */

    msr = env->msr & ~0x783f0000ULL;

    /* new interrupt handler msr */

    new_msr = env->msr & ((target_ulong)1 << MSR_ME);

    /* target registers */

    srr0 = SPR_SRR0;

    srr1 = SPR_SRR1;

    asrr0 = -1;

    asrr1 = -1;

    switch (excp) {

    case POWERPC_EXCP_NONE:

        /* Should never happen */

        return;

    case POWERPC_EXCP_CRITICAL:    /* Critical input                         */

        switch (excp_model) {

        case POWERPC_EXCP_40x:

            srr0 = SPR_40x_SRR2;

            srr1 = SPR_40x_SRR3;

            break;

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        case POWERPC_EXCP_G2:

            break;

        default:

            goto excp_invalid;

        }

        goto store_next;

    case POWERPC_EXCP_MCHECK:    /* Machine check exception                  */

        if (msr_me == 0) {

            /* Machine check exception is not enabled.

             * Enter checkstop state.

             */

            if (qemu_log_enabled()) {

                qemu_log("Machine check while not allowed. "

                        "Entering checkstop state\n");

            } else {

                fprintf(stderr, "Machine check while not allowed. "

                        "Entering checkstop state\n");

            }

            env->halted = 1;

            env->interrupt_request |= CPU_INTERRUPT_EXITTB;

        }

        if (0) {

            /* XXX: find a suitable condition to enable the hypervisor mode */

            new_msr |= (target_ulong)MSR_HVB;

        }

        /* machine check exceptions don't have ME set */

        new_msr &= ~((target_ulong)1 << MSR_ME);

        /* XXX: should also have something loaded in DAR / DSISR */

        switch (excp_model) {

        case POWERPC_EXCP_40x:

            srr0 = SPR_40x_SRR2;

            srr1 = SPR_40x_SRR3;

            break;

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_MCSRR0;

            srr1 = SPR_BOOKE_MCSRR1;

            asrr0 = SPR_BOOKE_CSRR0;

            asrr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        goto store_next;

    case POWERPC_EXCP_DSI:       /* Data storage exception                   */

        LOG_EXCP("DSI exception: DSISR=" TARGET_FMT_lx" DAR=" TARGET_FMT_lx

                 "\n", env->spr[SPR_DSISR], env->spr[SPR_DAR]);

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_ISI:       /* Instruction storage exception            */

        LOG_EXCP("ISI exception: msr=" TARGET_FMT_lx ", nip=" TARGET_FMT_lx

                 "\n", msr, env->nip);

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        msr |= env->error_code;

        goto store_next;

    case POWERPC_EXCP_EXTERNAL:  /* External input                           */

        if (lpes0 == 1)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_ALIGN:     /* Alignment exception                      */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        /* XXX: this is false */

        /* Get rS/rD and rA from faulting opcode */

        env->spr[SPR_DSISR] |= (ldl_code((env->nip - 4)) & 0x03FF0000) >> 16;

        goto store_current;

    case POWERPC_EXCP_PROGRAM:   /* Program exception                        */

        switch (env->error_code & ~0xF) {

        case POWERPC_EXCP_FP:

            if ((msr_fe0 == 0 && msr_fe1 == 0) || msr_fp == 0) {

                LOG_EXCP("Ignore floating point exception\n");

                env->exception_index = POWERPC_EXCP_NONE;

                env->error_code = 0;

                return;

            }

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00100000;

            if (msr_fe0 == msr_fe1)

                goto store_next;

            msr |= 0x00010000;

            break;

        case POWERPC_EXCP_INVAL:

            LOG_EXCP("Invalid instruction at " TARGET_FMT_lx "\n", env->nip);

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00080000;

            break;

        case POWERPC_EXCP_PRIV:

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00040000;

            break;

        case POWERPC_EXCP_TRAP:

            if (lpes1 == 0)

                new_msr |= (target_ulong)MSR_HVB;

            msr |= 0x00020000;

            break;

        default:

            /* Should never occur */

            cpu_abort(env, "Invalid program exception %d. Aborting\n",

                      env->error_code);

            break;

        }

        goto store_current;

    case POWERPC_EXCP_FPU:       /* Floating-point unavailable exception     */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_current;

    case POWERPC_EXCP_SYSCALL:   /* System call exception                    */

        /* NOTE: this is a temporary hack to support graphics OSI

           calls from the MOL driver */

        /* XXX: To be removed */

        if (env->gpr[3] == 0x113724fa && env->gpr[4] == 0x77810f9b &&

            env->osi_call) {

            if (env->osi_call(env) != 0) {

                env->exception_index = POWERPC_EXCP_NONE;

                env->error_code = 0;

                return;

            }

        }

        dump_syscall(env);

        lev = env->error_code;

        if (lev == 1 || (lpes0 == 0 && lpes1 == 0))

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_APU:       /* Auxiliary processor unavailable          */

        goto store_current;

    case POWERPC_EXCP_DECR:      /* Decrementer exception                    */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_FIT:       /* Fixed-interval timer interrupt           */

        /* FIT on 4xx */

        LOG_EXCP("FIT exception\n");

        goto store_next;

    case POWERPC_EXCP_WDT:       /* Watchdog timer interrupt                 */

        LOG_EXCP("WDT exception\n");

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        goto store_next;

    case POWERPC_EXCP_DTLB:      /* Data TLB error                           */

        goto store_next;

    case POWERPC_EXCP_ITLB:      /* Instruction TLB error                    */

        goto store_next;

    case POWERPC_EXCP_DEBUG:     /* Debug interrupt                          */

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_DSRR0;

            srr1 = SPR_BOOKE_DSRR1;

            asrr0 = SPR_BOOKE_CSRR0;

            asrr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        /* XXX: TODO */

        cpu_abort(env, "Debug exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */

        goto store_current;

    case POWERPC_EXCP_EFPDI:     /* Embedded floating-point data interrupt   */

        /* XXX: TODO */

        cpu_abort(env, "Embedded floating point data exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_EFPRI:     /* Embedded floating-point round interrupt  */

        /* XXX: TODO */

        cpu_abort(env, "Embedded floating point round exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_EPERFM:    /* Embedded performance monitor interrupt   */

        /* XXX: TODO */

        cpu_abort(env,

                  "Performance counter exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DOORI:     /* Embedded doorbell interrupt              */

        /* XXX: TODO */

        cpu_abort(env,

                  "Embedded doorbell interrupt is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DOORCI:    /* Embedded doorbell critical interrupt     */

        switch (excp_model) {

        case POWERPC_EXCP_BOOKE:

            srr0 = SPR_BOOKE_CSRR0;

            srr1 = SPR_BOOKE_CSRR1;

            break;

        default:

            break;

        }

        /* XXX: TODO */

        cpu_abort(env, "Embedded doorbell critical interrupt "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_RESET:     /* System reset exception                   */

        if (msr_pow) {

            /* indicate that we resumed from power save mode */

            msr |= 0x10000;

        } else {

            new_msr &= ~((target_ulong)1 << MSR_ME);

        }

        if (0) {

            /* XXX: find a suitable condition to enable the hypervisor mode */

            new_msr |= (target_ulong)MSR_HVB;

        }

        goto store_next;

    case POWERPC_EXCP_DSEG:      /* Data segment exception                   */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_ISEG:      /* Instruction segment exception            */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_HDECR:     /* Hypervisor decrementer exception         */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_TRACE:     /* Trace exception                          */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_next;

    case POWERPC_EXCP_HDSI:      /* Hypervisor data storage exception        */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HISI:      /* Hypervisor instruction storage exception */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HDSEG:     /* Hypervisor data segment exception        */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_HISEG:     /* Hypervisor instruction segment exception */

        srr0 = SPR_HSRR0;

        srr1 = SPR_HSRR1;

        new_msr |= (target_ulong)MSR_HVB;

        new_msr |= env->msr & ((target_ulong)1 << MSR_RI);

        goto store_next;

    case POWERPC_EXCP_VPU:       /* Vector unavailable exception             */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        goto store_current;

    case POWERPC_EXCP_PIT:       /* Programmable interval timer interrupt    */

        LOG_EXCP("PIT exception\n");

        goto store_next;

    case POWERPC_EXCP_IO:        /* IO error exception                       */

        /* XXX: TODO */

        cpu_abort(env, "601 IO error exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_RUNM:      /* Run mode exception                       */

        /* XXX: TODO */

        cpu_abort(env, "601 run mode exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_EMUL:      /* Emulation trap exception                 */

        /* XXX: TODO */

        cpu_abort(env, "602 emulation trap exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_IFTLB:     /* Instruction fetch TLB error              */

        if (lpes1 == 0) /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

            goto tlb_miss_tgpr;

        case POWERPC_EXCP_7x5:

            goto tlb_miss;

        case POWERPC_EXCP_74xx:

            goto tlb_miss_74xx;

        default:

            cpu_abort(env, "Invalid instruction TLB miss exception\n");

            break;

        }

        break;

    case POWERPC_EXCP_DLTLB:     /* Data load TLB miss                       */

        if (lpes1 == 0) /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

            goto tlb_miss_tgpr;

        case POWERPC_EXCP_7x5:

            goto tlb_miss;

        case POWERPC_EXCP_74xx:

            goto tlb_miss_74xx;

        default:

            cpu_abort(env, "Invalid data load TLB miss exception\n");

            break;

        }

        break;

    case POWERPC_EXCP_DSTLB:     /* Data store TLB miss                      */

        if (lpes1 == 0) /* XXX: check this */

            new_msr |= (target_ulong)MSR_HVB;

        switch (excp_model) {

        case POWERPC_EXCP_602:

        case POWERPC_EXCP_603:

        case POWERPC_EXCP_603E:

        case POWERPC_EXCP_G2:

        tlb_miss_tgpr:

            /* Swap temporary saved registers with GPRs */

            if (!(new_msr & ((target_ulong)1 << MSR_TGPR))) {

                new_msr |= (target_ulong)1 << MSR_TGPR;

                hreg_swap_gpr_tgpr(env);

            }

            goto tlb_miss;

        case POWERPC_EXCP_7x5:

        tlb_miss:

#if defined (DEBUG_SOFTWARE_TLB)

            if (qemu_log_enabled()) {

                const char *es;

                target_ulong *miss, *cmp;

                int en;

                if (excp == POWERPC_EXCP_IFTLB) {

                    es = "I";

                    en = 'I';

                    miss = &env->spr[SPR_IMISS];

                    cmp = &env->spr[SPR_ICMP];

                } else {

                    if (excp == POWERPC_EXCP_DLTLB)

                        es = "DL";

                    else

                        es = "DS";

                    en = 'D';

                    miss = &env->spr[SPR_DMISS];

                    cmp = &env->spr[SPR_DCMP];

                }

                qemu_log("6xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "

                         TARGET_FMT_lx " H1 " TARGET_FMT_lx " H2 "

                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,

                         env->spr[SPR_HASH1], env->spr[SPR_HASH2],

                         env->error_code);

            }

#endif

            msr |= env->crf[0] << 28;

            msr |= env->error_code; /* key, D/I, S/L bits */

            /* Set way using a LRU mechanism */

            msr |= ((env->last_way + 1) & (env->nb_ways - 1)) << 17;

            break;

        case POWERPC_EXCP_74xx:

        tlb_miss_74xx:

#if defined (DEBUG_SOFTWARE_TLB)

            if (qemu_log_enabled()) {

                const char *es;

                target_ulong *miss, *cmp;

                int en;

                if (excp == POWERPC_EXCP_IFTLB) {

                    es = "I";

                    en = 'I';

                    miss = &env->spr[SPR_TLBMISS];

                    cmp = &env->spr[SPR_PTEHI];

                } else {

                    if (excp == POWERPC_EXCP_DLTLB)

                        es = "DL";

                    else

                        es = "DS";

                    en = 'D';

                    miss = &env->spr[SPR_TLBMISS];

                    cmp = &env->spr[SPR_PTEHI];

                }

                qemu_log("74xx %sTLB miss: %cM " TARGET_FMT_lx " %cC "

                         TARGET_FMT_lx " %08x\n", es, en, *miss, en, *cmp,

                         env->error_code);

            }

#endif

            msr |= env->error_code; /* key bit */

            break;

        default:

            cpu_abort(env, "Invalid data store TLB miss exception\n");

            break;

        }

        goto store_next;

    case POWERPC_EXCP_FPA:       /* Floating-point assist exception          */

        /* XXX: TODO */

        cpu_abort(env, "Floating point assist exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_DABR:      /* Data address breakpoint                  */

        /* XXX: TODO */

        cpu_abort(env, "DABR exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_IABR:      /* Instruction address breakpoint           */

        /* XXX: TODO */

        cpu_abort(env, "IABR exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SMI:       /* System management interrupt              */

        /* XXX: TODO */

        cpu_abort(env, "SMI exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_THERM:     /* Thermal interrupt                        */

        /* XXX: TODO */

        cpu_abort(env, "Thermal management exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_PERFM:     /* Embedded performance monitor interrupt   */

        if (lpes1 == 0)

            new_msr |= (target_ulong)MSR_HVB;

        /* XXX: TODO */

        cpu_abort(env,

                  "Performance counter exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_VPUA:      /* Vector assist exception                  */

        /* XXX: TODO */

        cpu_abort(env, "VPU assist exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_SOFTP:     /* Soft patch exception                     */

        /* XXX: TODO */

        cpu_abort(env,

                  "970 soft-patch exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_MAINT:     /* Maintenance exception                    */

        /* XXX: TODO */

        cpu_abort(env,

                  "970 maintenance exception is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_MEXTBR:    /* Maskable external breakpoint             */

        /* XXX: TODO */

        cpu_abort(env, "Maskable external exception "

                  "is not implemented yet !\n");

        goto store_next;

    case POWERPC_EXCP_NMEXTBR:   /* Non maskable external breakpoint         */

        /* XXX: TODO */

        cpu_abort(env, "Non maskable external exception "

                  "is not implemented yet !\n");

        goto store_next;

    default:

    excp_invalid:

        cpu_abort(env, "Invalid PowerPC exception %d. Aborting\n", excp);

        break;

    store_current:

        /* save current instruction location */

        env->spr[srr0] = env->nip - 4;

        break;

    store_next:

        /* save next instruction location */

        env->spr[srr0] = env->nip;

        break;

    }

    /* Save MSR */

    env->spr[srr1] = msr;

    /* If any alternate SRR register are defined, duplicate saved values */

    if (asrr0 != -1)

        env->spr[asrr0] = env->spr[srr0];

    if (asrr1 != -1)

        env->spr[asrr1] = env->spr[srr1];

    /* If we disactivated any translation, flush TLBs */

    if (new_msr & ((1 << MSR_IR) | (1 << MSR_DR)))

        tlb_flush(env, 1);

    if (msr_ile) {

        new_msr |= (target_ulong)1 << MSR_LE;

    }

    /* Jump to handler */

    vector = env->excp_vectors[excp];

    if (vector == (target_ulong)-1ULL) {

        cpu_abort(env, "Raised an exception without defined vector %d\n",

                  excp);

    }

    vector |= env->excp_prefix;

#if defined(TARGET_PPC64)

    if (excp_model == POWERPC_EXCP_BOOKE) {

        if (!msr_icm) {

            vector = (uint32_t)vector;

        } else {

            new_msr |= (target_ulong)1 << MSR_CM;

        }

    } else {

        if (!msr_isf && !(env->mmu_model & POWERPC_MMU_64)) {

            vector = (uint32_t)vector;

        } else {

            new_msr |= (target_ulong)1 << MSR_SF;

        }

    }

#endif

    /* XXX: we don't use hreg_store_msr here as already have treated

     *      any special case that could occur. Just store MSR and update hflags

     */

    env->msr = new_msr & env->msr_mask;

    hreg_compute_hflags(env);

    env->nip = vector;

    /* Reset exception state */

    env->exception_index = POWERPC_EXCP_NONE;

    env->error_code = 0;

    if (env->mmu_model == POWERPC_MMU_BOOKE) {

        /* XXX: The BookE changes address space when switching modes,

                we should probably implement that as different MMU indexes,

                but for the moment we do it the slow way and flush all.  */

        tlb_flush(env, 1);

    }

}


static bool coroutine_fn wait_serialising_requests(BdrvTrackedRequest *self)

{

    BlockDriverState *bs = self->bs;

    BdrvTrackedRequest *req;

    bool retry;

    bool waited = false;

    if (!bs->serialising_in_flight) {

        return false;

    }

    do {

        retry = false;

        QLIST_FOREACH(req, &bs->tracked_requests, list) {

            if (req == self || (!req->serialising && !self->serialising)) {

                continue;

            }

            if (tracked_request_overlaps(req, self->overlap_offset,

                                         self->overlap_bytes))

            {

                /* Hitting this means there was a reentrant request, for

                 * example, a block driver issuing nested requests.  This must

                 * never happen since it means deadlock.

                 */

                assert(qemu_coroutine_self() != req->co);

                /* If the request is already (indirectly) waiting for us, or

                 * will wait for us as soon as it wakes up, then just go on

                 * (instead of producing a deadlock in the former case). */

                if (!req->waiting_for) {

                    self->waiting_for = req;

                    qemu_co_queue_wait(&req->wait_queue);

                    self->waiting_for = NULL;

                    retry = true;

                    waited = true;

                    break;

                }

            }

        }

    } while (retry);

    return waited;

}


static int usb_device_init(USBDevice *dev)

{

    USBDeviceClass *klass = USB_DEVICE_GET_CLASS(dev);

    if (klass->init) {

        return klass->init(dev);

    }

    return 0;

}


static int url_alloc_for_protocol(URLContext **puc, struct URLProtocol *up,

                                  const char *filename, int flags,

                                  const AVIOInterruptCB *int_cb)

{

    URLContext *uc;

    int err;

#if CONFIG_NETWORK

    if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())

        return AVERROR(EIO);

#endif

    uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);

    if (!uc) {

        err = AVERROR(ENOMEM);

        goto fail;

    }

    uc->av_class = &ffurl_context_class;

    uc->filename = (char *)&uc[1];

    strcpy(uc->filename, filename);

    uc->prot            = up;

    uc->flags           = flags;

    uc->is_streamed     = 0; /* default = not streamed */

    uc->max_packet_size = 0; /* default: stream file */

    if (up->priv_data_size) {

        uc->priv_data = av_mallocz(up->priv_data_size);

        if (!uc->priv_data) {

            err = AVERROR(ENOMEM);

            goto fail;

        }

        if (up->priv_data_class) {

            *(const AVClass **)uc->priv_data = up->priv_data_class;

            av_opt_set_defaults(uc->priv_data);

        }

    }

    if (int_cb)

        uc->interrupt_callback = *int_cb;

    *puc = uc;

    return 0;

fail:

    *puc = NULL;

    if (uc)

        av_freep(&uc->priv_data);

    av_freep(&uc);

#if CONFIG_NETWORK

    if (up->flags & URL_PROTOCOL_FLAG_NETWORK)

        ff_network_close();

#endif

    return err;

}


static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf,

                              int buf_size, int buf_size2)

{

    RVDecContext *rv = avctx->priv_data;

    MpegEncContext *s = &rv->m;

    int mb_count, mb_pos, left, start_mb_x, active_bits_size, ret;

    active_bits_size = buf_size * 8;

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

    if (s->codec_id == AV_CODEC_ID_RV10)

        mb_count = rv10_decode_picture_header(s);

    else

        mb_count = rv20_decode_picture_header(rv);

    if (mb_count < 0) {

        av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n");

        return AVERROR_INVALIDDATA;

    }

    if (s->mb_x >= s->mb_width ||

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

        av_log(s->avctx, AV_LOG_ERROR, "POS ERROR %d %d\n", s->mb_x, s->mb_y);

        return AVERROR_INVALIDDATA;

    }

    mb_pos = s->mb_y * s->mb_width + s->mb_x;

    left   = s->mb_width * s->mb_height - mb_pos;

    if (mb_count > left) {

        av_log(s->avctx, AV_LOG_ERROR, "COUNT ERROR\n");

        return AVERROR_INVALIDDATA;

    }

    if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr == NULL) {

        // FIXME write parser so we always have complete frames?

        if (s->current_picture_ptr) {

            ff_er_frame_end(&s->er);

            ff_mpv_frame_end(s);

            s->mb_x = s->mb_y = s->resync_mb_x = s->resync_mb_y = 0;

        }

        if ((ret = ff_mpv_frame_start(s, avctx)) < 0)

            return ret;

        ff_mpeg_er_frame_start(s);

    } else {

        if (s->current_picture_ptr->f->pict_type != s->pict_type) {

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

            return AVERROR_INVALIDDATA;

        }

    }

    av_dlog(avctx, "qscale=%d\n", s->qscale);

    /* default quantization values */

    if (s->codec_id == AV_CODEC_ID_RV10) {

        if (s->mb_y == 0)

            s->first_slice_line = 1;

    } else {

        s->first_slice_line = 1;

        s->resync_mb_x      = s->mb_x;

    }

    start_mb_x     = s->mb_x;

    s->resync_mb_y = s->mb_y;

    if (s->h263_aic) {

        s->y_dc_scale_table =

        s->c_dc_scale_table = ff_aic_dc_scale_table;

    } else {

        s->y_dc_scale_table =

        s->c_dc_scale_table = ff_mpeg1_dc_scale_table;

    }

    if (s->modified_quant)

        s->chroma_qscale_table = ff_h263_chroma_qscale_table;

    ff_set_qscale(s, s->qscale);

    s->rv10_first_dc_coded[0] = 0;

    s->rv10_first_dc_coded[1] = 0;

    s->rv10_first_dc_coded[2] = 0;

    s->block_wrap[0] =

    s->block_wrap[1] =

    s->block_wrap[2] =

    s->block_wrap[3] = s->b8_stride;

    s->block_wrap[4] =

    s->block_wrap[5] = s->mb_stride;

    ff_init_block_index(s);

    /* decode each macroblock */

    for (s->mb_num_left = mb_count; s->mb_num_left > 0; s->mb_num_left--) {

        int ret;

        ff_update_block_index(s);

        av_dlog(avctx, "**mb x=%d y=%d\n", s->mb_x, s->mb_y);

        s->mv_dir  = MV_DIR_FORWARD;

        s->mv_type = MV_TYPE_16X16;

        ret = ff_h263_decode_mb(s, s->block);

        // Repeat the slice end check from ff_h263_decode_mb with our active

        // bitstream size

        if (ret != SLICE_ERROR) {

            int v = show_bits(&s->gb, 16);

            if (get_bits_count(&s->gb) + 16 > active_bits_size)

                v >>= get_bits_count(&s->gb) + 16 - active_bits_size;

            if (!v)

                ret = SLICE_END;

        }

        if (ret != SLICE_ERROR && active_bits_size < get_bits_count(&s->gb) &&

            8 * buf_size2 >= get_bits_count(&s->gb)) {

            active_bits_size = buf_size2 * 8;

            av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n",

                   8 * buf_size, active_bits_size);

            ret = SLICE_OK;

        }

        if (ret == SLICE_ERROR || active_bits_size < get_bits_count(&s->gb)) {

            av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x,

                   s->mb_y);

            return AVERROR_INVALIDDATA;

        }

        if (s->pict_type != AV_PICTURE_TYPE_B)

            ff_h263_update_motion_val(s);

        ff_mpv_decode_mb(s, s->block);

        if (s->loop_filter)

            ff_h263_loop_filter(s);

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

            s->mb_x = 0;

            s->mb_y++;

            ff_init_block_index(s);

        }

        if (s->mb_x == s->resync_mb_x)

            s->first_slice_line = 0;

        if (ret == SLICE_END)

            break;

    }

    ff_er_add_slice(&s->er, start_mb_x, s->resync_mb_y, s->mb_x - 1, s->mb_y,

                    ER_MB_END);

    return active_bits_size;

}


int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)

{

    BdrvIoctlCoData data = {

        .bs = bs,

        .req = req,

        .buf = buf,

        .ret = -EINPROGRESS,

    };

    if (qemu_in_coroutine()) {

        /* Fast-path if already in coroutine context */

        bdrv_co_ioctl_entry(&data);

    } else {

        Coroutine *co = qemu_coroutine_create(bdrv_co_ioctl_entry);

        qemu_coroutine_enter(co, &data);

        while (data.ret == -EINPROGRESS) {

            aio_poll(bdrv_get_aio_context(bs), true);

        }

    }

    return data.ret;

}