build_ssdt(GArray *table_data, GArray *linker,

           AcpiCpuInfo *cpu, AcpiPmInfo *pm, AcpiMiscInfo *misc,

           PcPciInfo *pci, PcGuestInfo *guest_info)

{

    MachineState *machine = MACHINE(qdev_get_machine());

    uint32_t nr_mem = machine->ram_slots;

    unsigned acpi_cpus = guest_info->apic_id_limit;

    Aml *ssdt, *sb_scope, *scope, *pkg, *dev, *method, *crs, *field, *ifctx;

    PCIBus *bus = NULL;

    GPtrArray *io_ranges = g_ptr_array_new_with_free_func(crs_range_free);

    GPtrArray *mem_ranges = g_ptr_array_new_with_free_func(crs_range_free);

    CrsRangeEntry *entry;

    int root_bus_limit = 0xFF;

    int i;

    ssdt = init_aml_allocator();

    /* The current AML generator can cover the APIC ID range [0..255],

     * inclusive, for VCPU hotplug. */

    QEMU_BUILD_BUG_ON(ACPI_CPU_HOTPLUG_ID_LIMIT > 256);

    g_assert(acpi_cpus <= ACPI_CPU_HOTPLUG_ID_LIMIT);

    /* Reserve space for header */

    acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader));

    /* Extra PCI root buses are implemented  only for i440fx */

    bus = find_i440fx();

    if (bus) {

        QLIST_FOREACH(bus, &bus->child, sibling) {

            uint8_t bus_num = pci_bus_num(bus);

            uint8_t numa_node = pci_bus_numa_node(bus);

            /* look only for expander root buses */

            if (!pci_bus_is_root(bus)) {

                continue;

            }

            if (bus_num < root_bus_limit) {

                root_bus_limit = bus_num - 1;

            }

            scope = aml_scope("\\_SB");

            dev = aml_device("PC%.02X", bus_num);

            aml_append(dev, aml_name_decl("_UID", aml_int(bus_num)));

            aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03")));

            aml_append(dev, aml_name_decl("_BBN", aml_int(bus_num)));

            if (numa_node != NUMA_NODE_UNASSIGNED) {

                aml_append(dev, aml_name_decl("_PXM", aml_int(numa_node)));

            }

            aml_append(dev, build_prt());

            crs = build_crs(PCI_HOST_BRIDGE(BUS(bus)->parent),

                            io_ranges, mem_ranges);

            aml_append(dev, aml_name_decl("_CRS", crs));

            aml_append(scope, dev);

            aml_append(ssdt, scope);

        }

    }

    scope = aml_scope("\\_SB.PCI0");

    /* build PCI0._CRS */

    crs = aml_resource_template();

    aml_append(crs,

        aml_word_bus_number(AML_MIN_FIXED, AML_MAX_FIXED, AML_POS_DECODE,

                            0x0000, 0x0, root_bus_limit,

                            0x0000, root_bus_limit + 1));

    aml_append(crs, aml_io(AML_DECODE16, 0x0CF8, 0x0CF8, 0x01, 0x08));

    aml_append(crs,

        aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,

                    AML_POS_DECODE, AML_ENTIRE_RANGE,

                    0x0000, 0x0000, 0x0CF7, 0x0000, 0x0CF8));

    crs_replace_with_free_ranges(io_ranges, 0x0D00, 0xFFFF);

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

        entry = g_ptr_array_index(io_ranges, i);

        aml_append(crs,

            aml_word_io(AML_MIN_FIXED, AML_MAX_FIXED,

                        AML_POS_DECODE, AML_ENTIRE_RANGE,

                        0x0000, entry->base, entry->limit,

                        0x0000, entry->limit - entry->base + 1));

    }

    aml_append(crs,

        aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,

                         AML_CACHEABLE, AML_READ_WRITE,

                         0, 0x000A0000, 0x000BFFFF, 0, 0x00020000));

    crs_replace_with_free_ranges(mem_ranges, pci->w32.begin, pci->w32.end - 1);

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

        entry = g_ptr_array_index(mem_ranges, i);

        aml_append(crs,

            aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,

                             AML_NON_CACHEABLE, AML_READ_WRITE,

                             0, entry->base, entry->limit,

                             0, entry->limit - entry->base + 1));

    }

    if (pci->w64.begin) {

        aml_append(crs,

            aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,

                             AML_CACHEABLE, AML_READ_WRITE,

                             0, pci->w64.begin, pci->w64.end - 1, 0,

                             pci->w64.end - pci->w64.begin));

    }

    aml_append(scope, aml_name_decl("_CRS", crs));

    /* reserve GPE0 block resources */

    dev = aml_device("GPE0");

    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));

    aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources")));

    /* device present, functioning, decoding, not shown in UI */

    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

    crs = aml_resource_template();

    aml_append(crs,

        aml_io(AML_DECODE16, pm->gpe0_blk, pm->gpe0_blk, 1, pm->gpe0_blk_len)

    );

    aml_append(dev, aml_name_decl("_CRS", crs));

    aml_append(scope, dev);

    g_ptr_array_free(io_ranges, true);

    g_ptr_array_free(mem_ranges, true);

    /* reserve PCIHP resources */

    if (pm->pcihp_io_len) {

        dev = aml_device("PHPR");

        aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));

        aml_append(dev,

            aml_name_decl("_UID", aml_string("PCI Hotplug resources")));

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, pm->pcihp_io_base, pm->pcihp_io_base, 1,

                   pm->pcihp_io_len)

        );

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(scope, dev);

    }

    aml_append(ssdt, scope);

    /*  create S3_ / S4_ / S5_ packages if necessary */

    scope = aml_scope("\\");

    if (!pm->s3_disabled) {

        pkg = aml_package(4);

        aml_append(pkg, aml_int(1)); /* PM1a_CNT.SLP_TYP */

        aml_append(pkg, aml_int(1)); /* PM1b_CNT.SLP_TYP, FIXME: not impl. */

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(scope, aml_name_decl("_S3", pkg));

    }

    if (!pm->s4_disabled) {

        pkg = aml_package(4);

        aml_append(pkg, aml_int(pm->s4_val)); /* PM1a_CNT.SLP_TYP */

        /* PM1b_CNT.SLP_TYP, FIXME: not impl. */

        aml_append(pkg, aml_int(pm->s4_val));

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(pkg, aml_int(0)); /* reserved */

        aml_append(scope, aml_name_decl("_S4", pkg));

    }

    pkg = aml_package(4);

    aml_append(pkg, aml_int(0)); /* PM1a_CNT.SLP_TYP */

    aml_append(pkg, aml_int(0)); /* PM1b_CNT.SLP_TYP not impl. */

    aml_append(pkg, aml_int(0)); /* reserved */

    aml_append(pkg, aml_int(0)); /* reserved */

    aml_append(scope, aml_name_decl("_S5", pkg));

    aml_append(ssdt, scope);

    if (misc->applesmc_io_base) {

        scope = aml_scope("\\_SB.PCI0.ISA");

        dev = aml_device("SMC");

        aml_append(dev, aml_name_decl("_HID", aml_eisaid("APP0001")));

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, misc->applesmc_io_base, misc->applesmc_io_base,

                   0x01, APPLESMC_MAX_DATA_LENGTH)

        );

        aml_append(crs, aml_irq_no_flags(6));

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(scope, dev);

        aml_append(ssdt, scope);

    }

    if (misc->pvpanic_port) {

        scope = aml_scope("\\_SB.PCI0.ISA");

        dev = aml_device("PEVT");

        aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0001")));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, misc->pvpanic_port, misc->pvpanic_port, 1, 1)

        );

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(dev, aml_operation_region("PEOR", AML_SYSTEM_IO,

                                              misc->pvpanic_port, 1));

        field = aml_field("PEOR", AML_BYTE_ACC, AML_PRESERVE);

        aml_append(field, aml_named_field("PEPT", 8));

        aml_append(dev, field);

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        method = aml_method("RDPT", 0);

        aml_append(method, aml_store(aml_name("PEPT"), aml_local(0)));

        aml_append(method, aml_return(aml_local(0)));

        aml_append(dev, method);

        method = aml_method("WRPT", 1);

        aml_append(method, aml_store(aml_arg(0), aml_name("PEPT")));

        aml_append(dev, method);

        aml_append(scope, dev);

        aml_append(ssdt, scope);

    }

    sb_scope = aml_scope("\\_SB");

    {

        /* create PCI0.PRES device and its _CRS to reserve CPU hotplug MMIO */

        dev = aml_device("PCI0." stringify(CPU_HOTPLUG_RESOURCE_DEVICE));

        aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));

        aml_append(dev,

            aml_name_decl("_UID", aml_string("CPU Hotplug resources"))

        );

        /* device present, functioning, decoding, not shown in UI */

        aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, pm->cpu_hp_io_base, pm->cpu_hp_io_base, 1,

                   pm->cpu_hp_io_len)

        );

        aml_append(dev, aml_name_decl("_CRS", crs));

        aml_append(sb_scope, dev);

        /* declare CPU hotplug MMIO region and PRS field to access it */

        aml_append(sb_scope, aml_operation_region(

            "PRST", AML_SYSTEM_IO, pm->cpu_hp_io_base, pm->cpu_hp_io_len));

        field = aml_field("PRST", AML_BYTE_ACC, AML_PRESERVE);

        aml_append(field, aml_named_field("PRS", 256));

        aml_append(sb_scope, field);

        /* build Processor object for each processor */

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

            dev = aml_processor(i, 0, 0, "CP%.02X", i);

            method = aml_method("_MAT", 0);

            aml_append(method, aml_return(aml_call1("CPMA", aml_int(i))));

            aml_append(dev, method);

            method = aml_method("_STA", 0);

            aml_append(method, aml_return(aml_call1("CPST", aml_int(i))));

            aml_append(dev, method);

            method = aml_method("_EJ0", 1);

            aml_append(method,

                aml_return(aml_call2("CPEJ", aml_int(i), aml_arg(0)))

            );

            aml_append(dev, method);

            aml_append(sb_scope, dev);

        }

        /* build this code:

         *   Method(NTFY, 2) {If (LEqual(Arg0, 0x00)) {Notify(CP00, Arg1)} ...}

         */

        /* Arg0 = Processor ID = APIC ID */

        method = aml_method("NTFY", 2);

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

            ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));

            aml_append(ifctx,

                aml_notify(aml_name("CP%.02X", i), aml_arg(1))

            );

            aml_append(method, ifctx);

        }

        aml_append(sb_scope, method);

        /* build "Name(CPON, Package() { One, One, ..., Zero, Zero, ... })"

         *

         * Note: The ability to create variable-sized packages was first

         * introduced in ACPI 2.0. ACPI 1.0 only allowed fixed-size packages

         * ith up to 255 elements. Windows guests up to win2k8 fail when

         * VarPackageOp is used.

         */

        pkg = acpi_cpus <= 255 ? aml_package(acpi_cpus) :

                                 aml_varpackage(acpi_cpus);

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

            uint8_t b = test_bit(i, cpu->found_cpus) ? 0x01 : 0x00;

            aml_append(pkg, aml_int(b));

        }

        aml_append(sb_scope, aml_name_decl("CPON", pkg));

        /* build memory devices */

        assert(nr_mem <= ACPI_MAX_RAM_SLOTS);

        scope = aml_scope("\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE));

        aml_append(scope,

            aml_name_decl(stringify(MEMORY_SLOTS_NUMBER), aml_int(nr_mem))

        );

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, pm->mem_hp_io_base, pm->mem_hp_io_base, 0,

                   pm->mem_hp_io_len)

        );

        aml_append(scope, aml_name_decl("_CRS", crs));

        aml_append(scope, aml_operation_region(

            stringify(MEMORY_HOTPLUG_IO_REGION), AML_SYSTEM_IO,

            pm->mem_hp_io_base, pm->mem_hp_io_len)

        );

        field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), AML_DWORD_ACC,

                          AML_PRESERVE);

        aml_append(field, /* read only */

            aml_named_field(stringify(MEMORY_SLOT_ADDR_LOW), 32));

        aml_append(field, /* read only */

            aml_named_field(stringify(MEMORY_SLOT_ADDR_HIGH), 32));

        aml_append(field, /* read only */

            aml_named_field(stringify(MEMORY_SLOT_SIZE_LOW), 32));

        aml_append(field, /* read only */

            aml_named_field(stringify(MEMORY_SLOT_SIZE_HIGH), 32));

        aml_append(field, /* read only */

            aml_named_field(stringify(MEMORY_SLOT_PROXIMITY), 32));

        aml_append(scope, field);

        field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), AML_BYTE_ACC,

                          AML_WRITE_AS_ZEROS);

        aml_append(field, aml_reserved_field(160 /* bits, Offset(20) */));

        aml_append(field, /* 1 if enabled, read only */

            aml_named_field(stringify(MEMORY_SLOT_ENABLED), 1));

        aml_append(field,

            /*(read) 1 if has a insert event. (write) 1 to clear event */

            aml_named_field(stringify(MEMORY_SLOT_INSERT_EVENT), 1));

        aml_append(field,

            /* (read) 1 if has a remove event. (write) 1 to clear event */

            aml_named_field(stringify(MEMORY_SLOT_REMOVE_EVENT), 1));

        aml_append(field,

            /* initiates device eject, write only */

            aml_named_field(stringify(MEMORY_SLOT_EJECT), 1));

        aml_append(scope, field);

        field = aml_field(stringify(MEMORY_HOTPLUG_IO_REGION), AML_DWORD_ACC,

                          AML_PRESERVE);

        aml_append(field, /* DIMM selector, write only */

            aml_named_field(stringify(MEMORY_SLOT_SLECTOR), 32));

        aml_append(field, /* _OST event code, write only */

            aml_named_field(stringify(MEMORY_SLOT_OST_EVENT), 32));

        aml_append(field, /* _OST status code, write only */

            aml_named_field(stringify(MEMORY_SLOT_OST_STATUS), 32));

        aml_append(scope, field);

        aml_append(sb_scope, scope);

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

            #define BASEPATH "\\_SB.PCI0." stringify(MEMORY_HOTPLUG_DEVICE) "."

            const char *s;

            dev = aml_device("MP%02X", i);

            aml_append(dev, aml_name_decl("_UID", aml_string("0x%02X", i)));

            aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C80")));

            method = aml_method("_CRS", 0);

            s = BASEPATH stringify(MEMORY_SLOT_CRS_METHOD);

            aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));

            aml_append(dev, method);

            method = aml_method("_STA", 0);

            s = BASEPATH stringify(MEMORY_SLOT_STATUS_METHOD);

            aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));

            aml_append(dev, method);

            method = aml_method("_PXM", 0);

            s = BASEPATH stringify(MEMORY_SLOT_PROXIMITY_METHOD);

            aml_append(method, aml_return(aml_call1(s, aml_name("_UID"))));

            aml_append(dev, method);

            method = aml_method("_OST", 3);

            s = BASEPATH stringify(MEMORY_SLOT_OST_METHOD);

            aml_append(method, aml_return(aml_call4(

                s, aml_name("_UID"), aml_arg(0), aml_arg(1), aml_arg(2)

            )));

            aml_append(dev, method);

            method = aml_method("_EJ0", 1);

            s = BASEPATH stringify(MEMORY_SLOT_EJECT_METHOD);

            aml_append(method, aml_return(aml_call2(

                       s, aml_name("_UID"), aml_arg(0))));

            aml_append(dev, method);

            aml_append(sb_scope, dev);

        }

        /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {

         *     If (LEqual(Arg0, 0x00)) {Notify(MP00, Arg1)} ... }

         */

        method = aml_method(stringify(MEMORY_SLOT_NOTIFY_METHOD), 2);

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

            ifctx = aml_if(aml_equal(aml_arg(0), aml_int(i)));

            aml_append(ifctx,

                aml_notify(aml_name("MP%.02X", i), aml_arg(1))

            );

            aml_append(method, ifctx);

        }

        aml_append(sb_scope, method);

        {

            Object *pci_host;

            PCIBus *bus = NULL;

            pci_host = acpi_get_i386_pci_host();

            if (pci_host) {

                bus = PCI_HOST_BRIDGE(pci_host)->bus;

            }

            if (bus) {

                Aml *scope = aml_scope("PCI0");

                /* Scan all PCI buses. Generate tables to support hotplug. */

                build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en);

                if (misc->tpm_version != TPM_VERSION_UNSPEC) {

                    dev = aml_device("ISA.TPM");

                    aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31")));

                    aml_append(dev, aml_name_decl("_STA", aml_int(0xF)));

                    crs = aml_resource_template();

                    aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,

                               TPM_TIS_ADDR_SIZE, AML_READ_WRITE));

                    aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ));

                    aml_append(dev, aml_name_decl("_CRS", crs));

                    aml_append(scope, dev);

                }

                aml_append(sb_scope, scope);

            }

        }

        aml_append(ssdt, sb_scope);

    }

    /* copy AML table into ACPI tables blob and patch header there */

    g_array_append_vals(table_data, ssdt->buf->data, ssdt->buf->len);

    build_header(linker, table_data,

        (void *)(table_data->data + table_data->len - ssdt->buf->len),

        "SSDT", ssdt->buf->len, 1);

    free_aml_allocator();

}


static void release_delayed_buffers(PerThreadContext *p)

{

    FrameThreadContext *fctx = p->parent;

    while (p->num_released_buffers > 0) {

        AVFrame *f = &p->released_buffers[--p->num_released_buffers];

        pthread_mutex_lock(&fctx->buffer_mutex);

        free_progress(f);

        f->thread_opaque = NULL;

        f->owner->release_buffer(f->owner, f);

        pthread_mutex_unlock(&fctx->buffer_mutex);

    }

}


double ff_lpc_calc_ref_coefs_f(LPCContext *s, const float *samples, int len,

                               int order, double *ref)

{

    int i;

    double signal = 0.0f, avg_err = 0.0f;

    double autoc[MAX_LPC_ORDER+1] = {0}, error[MAX_LPC_ORDER+1] = {0};

    const double a = 0.5f, b = 1.0f - a;

    /* Apply windowing */

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

        double weight = a - b*cos((2*M_PI*i)/(len - 1));

        s->windowed_samples[i] = weight*samples[i];

    }

    s->lpc_compute_autocorr(s->windowed_samples, len, order, autoc);

    signal = autoc[0];

    compute_ref_coefs(autoc, order, ref, error);

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

        avg_err = (avg_err + error[i])/2.0f;

    return signal/avg_err;

}


int av_write_trailer(AVFormatContext *s)

{

    int ret, i;

    for (;; ) {

        AVPacket pkt;

        ret = interleave_packet(s, &pkt, NULL, 1);

        if (ret < 0) //FIXME cleanup needed for ret<0 ?

            goto fail;

        if (!ret)

            break;

        ret = s->oformat->write_packet(s, &pkt);

        if (ret >= 0)

            s->streams[pkt.stream_index]->nb_frames++;

        av_free_packet(&pkt);

        if (ret < 0)

            goto fail;

    }

    if (s->oformat->write_trailer)

        ret = s->oformat->write_trailer(s);

    if (!(s->oformat->flags & AVFMT_NOFILE))

        avio_flush(s->pb);

fail:

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

        av_freep(&s->streams[i]->priv_data);

        av_freep(&s->streams[i]->index_entries);

    }

    if (s->oformat->priv_class)

        av_opt_free(s->priv_data);

    av_freep(&s->priv_data);

    return ret;

}


int av_dict_set(AVDictionary **pm, const char *key, const char *value,

                int flags)

{

    AVDictionary *m = *pm;

    AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags);

    char *oldval = NULL;

    if (!m)

        m = *pm = av_mallocz(sizeof(*m));

    if (tag) {

        if (flags & AV_DICT_DONT_OVERWRITE)

            return 0;

        if (flags & AV_DICT_APPEND)

            oldval = tag->value;

        else

            av_free(tag->value);

        av_free(tag->key);

        *tag = m->elems[--m->count];

    } else {

        AVDictionaryEntry *tmp = av_realloc(m->elems,

                                            (m->count + 1) * sizeof(*m->elems));

        if (tmp)

            m->elems = tmp;

        else

            return AVERROR(ENOMEM);

    }

    if (value) {

        if (flags & AV_DICT_DONT_STRDUP_KEY)

            m->elems[m->count].key = key;

        else

            m->elems[m->count].key = av_strdup(key);

        if (flags & AV_DICT_DONT_STRDUP_VAL) {

            m->elems[m->count].value = value;

        } else if (oldval && flags & AV_DICT_APPEND) {

            int len = strlen(oldval) + strlen(value) + 1;

            if (!(oldval = av_realloc(oldval, len)))

                return AVERROR(ENOMEM);

            av_strlcat(oldval, value, len);

            m->elems[m->count].value = oldval;

        } else

            m->elems[m->count].value = av_strdup(value);

        m->count++;

    }

    if (!m->count) {

        av_free(m->elems);

        av_freep(pm);

    }

    return 0;

}


static void s390_virtio_rng_instance_init(Object *obj)

{

    VirtIORNGS390 *dev = VIRTIO_RNG_S390(obj);

    object_initialize(&dev->vdev, sizeof(dev->vdev), TYPE_VIRTIO_RNG);

    object_property_add_child(obj, "virtio-backend", OBJECT(&dev->vdev), NULL);

    object_property_add_link(obj, "rng", TYPE_RNG_BACKEND,

                             (Object **)&dev->vdev.conf.rng,

                             OBJ_PROP_LINK_UNREF_ON_RELEASE, NULL);

}


static struct omap_sti_s *omap_sti_init(struct omap_target_agent_s *ta,

                MemoryRegion *sysmem,

                hwaddr channel_base, qemu_irq irq, omap_clk clk,

                CharDriverState *chr)

{

    struct omap_sti_s *s = (struct omap_sti_s *)

            g_malloc0(sizeof(struct omap_sti_s));

    s->irq = irq;

    omap_sti_reset(s);

    s->chr = chr ?: qemu_chr_new("null", "null", NULL);

    memory_region_init_io(&s->iomem, NULL, &omap_sti_ops, s, "omap.sti",

                          omap_l4_region_size(ta, 0));

    omap_l4_attach(ta, 0, &s->iomem);

    memory_region_init_io(&s->iomem_fifo, NULL, &omap_sti_fifo_ops, s,

                          "omap.sti.fifo", 0x10000);

    memory_region_add_subregion(sysmem, channel_base, &s->iomem_fifo);

    return s;

}


void cpu_interrupt(CPUArchState *env, int mask)

{

    CPUState *cpu = ENV_GET_CPU(env);

    env->interrupt_request |= mask;

    cpu_unlink_tb(cpu);

}


static inline int read_huff_channels(MLPDecodeContext *m, GetBitContext *gbp,

                                     unsigned int substr, unsigned int pos)

{

    SubStream *s = &m->substream[substr];

    unsigned int mat, channel;

    for (mat = 0; mat < s->num_primitive_matrices; mat++)

        if (s->lsb_bypass[mat])

            m->bypassed_lsbs[pos + s->blockpos][mat] = get_bits1(gbp);

    for (channel = s->min_channel; channel <= s->max_channel; channel++) {

        ChannelParams *cp = &s->channel_params[channel];

        int codebook = cp->codebook;

        int quant_step_size = s->quant_step_size[channel];

        int lsb_bits = cp->huff_lsbs - quant_step_size;

        int result = 0;

        if (codebook > 0)

            result = get_vlc2(gbp, huff_vlc[codebook-1].table,

                            VLC_BITS, (9 + VLC_BITS - 1) / VLC_BITS);

        if (result < 0)

            return AVERROR_INVALIDDATA;

        if (lsb_bits > 0)

            result = (result << lsb_bits) + get_bits(gbp, lsb_bits);

        result  += cp->sign_huff_offset;

        result <<= quant_step_size;

        m->sample_buffer[pos + s->blockpos][channel] = result;

    }

    return 0;

}


static void superh_cpu_initfn(Object *obj)

{

    CPUState *cs = CPU(obj);

    SuperHCPU *cpu = SUPERH_CPU(obj);

    CPUSH4State *env = &cpu->env;

    cs->env_ptr = env;

    cpu_exec_init(cs, &error_abort);

    env->movcal_backup_tail = &(env->movcal_backup);

    if (tcg_enabled()) {

        sh4_translate_init();

    }

}


void ff_estimate_b_frame_motion(MpegEncContext * s,

                             int mb_x, int mb_y)

{

    MotionEstContext * const c= &s->me;

    const int penalty_factor= c->mb_penalty_factor;

    int fmin, bmin, dmin, fbmin, bimin, fimin;

    int type=0;

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

    init_ref(c, s->new_picture.f.data, s->last_picture.f.data,

             s->next_picture.f.data, 16 * mb_x, 16 * mb_y, 2);

    get_limits(s, 16*mb_x, 16*mb_y);

    c->skip=0;

    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->next_picture.mbskip_table[xy]) {

        int score= direct_search(s, mb_x, mb_y); //FIXME just check 0,0

        score= ((unsigned)(score*score + 128*256))>>16;

        c->mc_mb_var_sum_temp += score;

        s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE

        s->mb_type[mb_y*s->mb_stride + mb_x]= CANDIDATE_MB_TYPE_DIRECT0;

        return;

    }

    if (s->codec_id == AV_CODEC_ID_MPEG4)

        dmin= direct_search(s, mb_x, mb_y);

    else

        dmin= INT_MAX;

//FIXME penalty stuff for non mpeg4

    c->skip=0;

    fmin = estimate_motion_b(s, mb_x, mb_y, s->b_forw_mv_table, 0, s->f_code) +

           3 * penalty_factor;

    c->skip=0;

    bmin = estimate_motion_b(s, mb_x, mb_y, s->b_back_mv_table, 2, s->b_code) +

           2 * penalty_factor;

    av_dlog(s, " %d %d ", s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1]);

    c->skip=0;

    fbmin= bidir_refine(s, mb_x, mb_y) + penalty_factor;

    av_dlog(s, "%d %d %d %d\n", dmin, fmin, bmin, fbmin);

    if(s->flags & CODEC_FLAG_INTERLACED_ME){

//FIXME mb type penalty

        c->skip=0;

        c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV;

        fimin= interlaced_search(s, 0,

                                 s->b_field_mv_table[0], s->b_field_select_table[0],

                                 s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0);

        c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV;

        bimin= interlaced_search(s, 2,

                                 s->b_field_mv_table[1], s->b_field_select_table[1],

                                 s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0);

    }else

        fimin= bimin= INT_MAX;

    {

        int score= fmin;

        type = CANDIDATE_MB_TYPE_FORWARD;

        if (dmin <= score){

            score = dmin;

            type = CANDIDATE_MB_TYPE_DIRECT;

        }

        if(bmin<score){

            score=bmin;

            type= CANDIDATE_MB_TYPE_BACKWARD;

        }

        if(fbmin<score){

            score=fbmin;

            type= CANDIDATE_MB_TYPE_BIDIR;

        }

        if(fimin<score){

            score=fimin;

            type= CANDIDATE_MB_TYPE_FORWARD_I;

        }

        if(bimin<score){

            score=bimin;

            type= CANDIDATE_MB_TYPE_BACKWARD_I;

        }

        score= ((unsigned)(score*score + 128*256))>>16;

        c->mc_mb_var_sum_temp += score;

        s->current_picture.mc_mb_var[mb_y*s->mb_stride + mb_x] = score; //FIXME use SSE

    }

    if(c->avctx->mb_decision > FF_MB_DECISION_SIMPLE){

        type= CANDIDATE_MB_TYPE_FORWARD | CANDIDATE_MB_TYPE_BACKWARD | CANDIDATE_MB_TYPE_BIDIR | CANDIDATE_MB_TYPE_DIRECT;

        if(fimin < INT_MAX)

            type |= CANDIDATE_MB_TYPE_FORWARD_I;

        if(bimin < INT_MAX)

            type |= CANDIDATE_MB_TYPE_BACKWARD_I;

        if(fimin < INT_MAX && bimin < INT_MAX){

            type |= CANDIDATE_MB_TYPE_BIDIR_I;

        }

         //FIXME something smarter

        if(dmin>256*256*16) type&= ~CANDIDATE_MB_TYPE_DIRECT; //do not try direct mode if it is invalid for this MB

        if(s->codec_id == AV_CODEC_ID_MPEG4 && type&CANDIDATE_MB_TYPE_DIRECT && s->flags&CODEC_FLAG_MV0 && *(uint32_t*)s->b_direct_mv_table[xy])

            type |= CANDIDATE_MB_TYPE_DIRECT0;

    }

    s->mb_type[mb_y*s->mb_stride + mb_x]= type;

}


xmit_seg(E1000State *s)

{

    uint16_t len, *sp;

    unsigned int frames = s->tx.tso_frames, css, sofar, n;

    struct e1000_tx *tp = &s->tx;

    if (tp->tse && tp->cptse) {

        css = tp->ipcss;

        DBGOUT(TXSUM, "frames %d size %d ipcss %d\n",

               frames, tp->size, css);

        if (tp->ip) {		// IPv4

            cpu_to_be16wu((uint16_t *)(tp->data+css+2),

                          tp->size - css);

            cpu_to_be16wu((uint16_t *)(tp->data+css+4),

                          be16_to_cpup((uint16_t *)(tp->data+css+4))+frames);

        } else			// IPv6

            cpu_to_be16wu((uint16_t *)(tp->data+css+4),

                          tp->size - css);

        css = tp->tucss;

        len = tp->size - css;

        DBGOUT(TXSUM, "tcp %d tucss %d len %d\n", tp->tcp, css, len);

        if (tp->tcp) {

            sofar = frames * tp->mss;

            cpu_to_be32wu((uint32_t *)(tp->data+css+4),	// seq

                be32_to_cpupu((uint32_t *)(tp->data+css+4))+sofar);

            if (tp->paylen - sofar > tp->mss)

                tp->data[css + 13] &= ~9;		// PSH, FIN

        } else	// UDP

            cpu_to_be16wu((uint16_t *)(tp->data+css+4), len);

        if (tp->sum_needed & E1000_TXD_POPTS_TXSM) {

            // add pseudo-header length before checksum calculation

            sp = (uint16_t *)(tp->data + tp->tucso);

            cpu_to_be16wu(sp, be16_to_cpup(sp) + len);

        }

        tp->tso_frames++;

    }

    if (tp->sum_needed & E1000_TXD_POPTS_TXSM)

        putsum(tp->data, tp->size, tp->tucso, tp->tucss, tp->tucse);

    if (tp->sum_needed & E1000_TXD_POPTS_IXSM)

        putsum(tp->data, tp->size, tp->ipcso, tp->ipcss, tp->ipcse);

    if (tp->vlan_needed) {

        memmove(tp->vlan, tp->data, 4);

        memmove(tp->data, tp->data + 4, 8);

        memcpy(tp->data + 8, tp->vlan_header, 4);

        qemu_send_packet(&s->nic->nc, tp->vlan, tp->size + 4);

    } else

        qemu_send_packet(&s->nic->nc, tp->data, tp->size);

    s->mac_reg[TPT]++;

    s->mac_reg[GPTC]++;

    n = s->mac_reg[TOTL];

    if ((s->mac_reg[TOTL] += s->tx.size) < n)

        s->mac_reg[TOTH]++;

}


static void omap_timer_clk_setup(struct omap_mpu_timer_s *timer)

{

    omap_clk_adduser(timer->clk,

                    qemu_allocate_irqs(omap_timer_clk_update, timer, 1)[0]);

    timer->rate = omap_clk_getrate(timer->clk);

}


static int drive_init(struct drive_opt *arg, int snapshot,

                      QEMUMachine *machine)

{

    char buf[128];

    char file[1024];

    char devname[128];

    char serial[21];

    const char *mediastr = "";

    BlockInterfaceType type;

    enum { MEDIA_DISK, MEDIA_CDROM } media;

    int bus_id, unit_id;

    int cyls, heads, secs, translation;

    BlockDriverState *bdrv;

    BlockDriver *drv = NULL;

    int max_devs;

    int index;

    int cache;

    int bdrv_flags, onerror;

    int drives_table_idx;

    char *str = arg->opt;

    static const char * const params[] = { "bus", "unit", "if", "index",

                                           "cyls", "heads", "secs", "trans",

                                           "media", "snapshot", "file",

                                           "cache", "format", "serial", "werror",

                                           NULL };

    if (check_params(buf, sizeof(buf), params, str) < 0) {

         fprintf(stderr, "qemu: unknown parameter '%s' in '%s'\n",

                         buf, str);

         return -1;

    }

    file[0] = 0;

    cyls = heads = secs = 0;

    bus_id = 0;

    unit_id = -1;

    translation = BIOS_ATA_TRANSLATION_AUTO;

    index = -1;

    cache = 3;

    if (machine->use_scsi) {

        type = IF_SCSI;

        max_devs = MAX_SCSI_DEVS;

        pstrcpy(devname, sizeof(devname), "scsi");

    } else {

        type = IF_IDE;

        max_devs = MAX_IDE_DEVS;

        pstrcpy(devname, sizeof(devname), "ide");

    }

    media = MEDIA_DISK;

    /* extract parameters */

    if (get_param_value(buf, sizeof(buf), "bus", str)) {

        bus_id = strtol(buf, NULL, 0);

	if (bus_id < 0) {

	    fprintf(stderr, "qemu: '%s' invalid bus id\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "unit", str)) {

        unit_id = strtol(buf, NULL, 0);

	if (unit_id < 0) {

	    fprintf(stderr, "qemu: '%s' invalid unit id\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "if", str)) {

        pstrcpy(devname, sizeof(devname), buf);

        if (!strcmp(buf, "ide")) {

	    type = IF_IDE;

            max_devs = MAX_IDE_DEVS;

        } else if (!strcmp(buf, "scsi")) {

	    type = IF_SCSI;

            max_devs = MAX_SCSI_DEVS;

        } else if (!strcmp(buf, "floppy")) {

	    type = IF_FLOPPY;

            max_devs = 0;

        } else if (!strcmp(buf, "pflash")) {

	    type = IF_PFLASH;

            max_devs = 0;

	} else if (!strcmp(buf, "mtd")) {

	    type = IF_MTD;

            max_devs = 0;

	} else if (!strcmp(buf, "sd")) {

	    type = IF_SD;

            max_devs = 0;

        } else if (!strcmp(buf, "virtio")) {

            type = IF_VIRTIO;

            max_devs = 0;

        } else {

            fprintf(stderr, "qemu: '%s' unsupported bus type '%s'\n", str, buf);

            return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "index", str)) {

        index = strtol(buf, NULL, 0);

	if (index < 0) {

	    fprintf(stderr, "qemu: '%s' invalid index\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "cyls", str)) {

        cyls = strtol(buf, NULL, 0);

    }

    if (get_param_value(buf, sizeof(buf), "heads", str)) {

        heads = strtol(buf, NULL, 0);

    }

    if (get_param_value(buf, sizeof(buf), "secs", str)) {

        secs = strtol(buf, NULL, 0);

    }

    if (cyls || heads || secs) {

        if (cyls < 1 || cyls > 16383) {

            fprintf(stderr, "qemu: '%s' invalid physical cyls number\n", str);

	    return -1;

	}

        if (heads < 1 || heads > 16) {

            fprintf(stderr, "qemu: '%s' invalid physical heads number\n", str);

	    return -1;

	}

        if (secs < 1 || secs > 63) {

            fprintf(stderr, "qemu: '%s' invalid physical secs number\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "trans", str)) {

        if (!cyls) {

            fprintf(stderr,

                    "qemu: '%s' trans must be used with cyls,heads and secs\n",

                    str);

            return -1;

        }

        if (!strcmp(buf, "none"))

            translation = BIOS_ATA_TRANSLATION_NONE;

        else if (!strcmp(buf, "lba"))

            translation = BIOS_ATA_TRANSLATION_LBA;

        else if (!strcmp(buf, "auto"))

            translation = BIOS_ATA_TRANSLATION_AUTO;

	else {

            fprintf(stderr, "qemu: '%s' invalid translation type\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "media", str)) {

        if (!strcmp(buf, "disk")) {

	    media = MEDIA_DISK;

	} else if (!strcmp(buf, "cdrom")) {

            if (cyls || secs || heads) {

                fprintf(stderr,

                        "qemu: '%s' invalid physical CHS format\n", str);

	        return -1;

            }

	    media = MEDIA_CDROM;

	} else {

	    fprintf(stderr, "qemu: '%s' invalid media\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "snapshot", str)) {

        if (!strcmp(buf, "on"))

	    snapshot = 1;

        else if (!strcmp(buf, "off"))

	    snapshot = 0;

	else {

	    fprintf(stderr, "qemu: '%s' invalid snapshot option\n", str);

	    return -1;

	}

    }

    if (get_param_value(buf, sizeof(buf), "cache", str)) {

        if (!strcmp(buf, "off") || !strcmp(buf, "none"))

            cache = 0;

        else if (!strcmp(buf, "writethrough"))

            cache = 1;

        else if (!strcmp(buf, "writeback"))

            cache = 2;

        else {

           fprintf(stderr, "qemu: invalid cache option\n");

           return -1;

        }

    }

    if (get_param_value(buf, sizeof(buf), "format", str)) {

       if (strcmp(buf, "?") == 0) {

            fprintf(stderr, "qemu: Supported formats:");

            bdrv_iterate_format(bdrv_format_print, NULL);

            fprintf(stderr, "\n");

	    return -1;

        }

        drv = bdrv_find_format(buf);

        if (!drv) {

            fprintf(stderr, "qemu: '%s' invalid format\n", buf);

            return -1;

        }

    }

    if (arg->file == NULL)

        get_param_value(file, sizeof(file), "file", str);

    else

        pstrcpy(file, sizeof(file), arg->file);

    if (!get_param_value(serial, sizeof(serial), "serial", str))

	    memset(serial, 0,  sizeof(serial));

    onerror = BLOCK_ERR_REPORT;

    if (get_param_value(buf, sizeof(serial), "werror", str)) {

        if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO) {

            fprintf(stderr, "werror is no supported by this format\n");

            return -1;

        }

        if (!strcmp(buf, "ignore"))

            onerror = BLOCK_ERR_IGNORE;

        else if (!strcmp(buf, "enospc"))

            onerror = BLOCK_ERR_STOP_ENOSPC;

        else if (!strcmp(buf, "stop"))

            onerror = BLOCK_ERR_STOP_ANY;

        else if (!strcmp(buf, "report"))

            onerror = BLOCK_ERR_REPORT;

        else {

            fprintf(stderr, "qemu: '%s' invalid write error action\n", buf);

            return -1;

        }

    }

    /* compute bus and unit according index */

    if (index != -1) {

        if (bus_id != 0 || unit_id != -1) {

            fprintf(stderr,

                    "qemu: '%s' index cannot be used with bus and unit\n", str);

            return -1;

        }

        if (max_devs == 0)

        {

            unit_id = index;

            bus_id = 0;

        } else {

            unit_id = index % max_devs;

            bus_id = index / max_devs;

        }

    }

    /* if user doesn't specify a unit_id,

     * try to find the first free

     */

    if (unit_id == -1) {

       unit_id = 0;

       while (drive_get_index(type, bus_id, unit_id) != -1) {

           unit_id++;

           if (max_devs && unit_id >= max_devs) {

               unit_id -= max_devs;

               bus_id++;

           }

       }

    }

    /* check unit id */

    if (max_devs && unit_id >= max_devs) {

        fprintf(stderr, "qemu: '%s' unit %d too big (max is %d)\n",

                        str, unit_id, max_devs - 1);

        return -1;

    }

    /*

     * ignore multiple definitions

     */

    if (drive_get_index(type, bus_id, unit_id) != -1)

        return 0;

    /* init */

    if (type == IF_IDE || type == IF_SCSI)

        mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd";

    if (max_devs)

        snprintf(buf, sizeof(buf), "%s%i%s%i",

                 devname, bus_id, mediastr, unit_id);

    else

        snprintf(buf, sizeof(buf), "%s%s%i",

                 devname, mediastr, unit_id);

    bdrv = bdrv_new(buf);

    drives_table_idx = drive_get_free_idx();

    drives_table[drives_table_idx].bdrv = bdrv;

    drives_table[drives_table_idx].type = type;

    drives_table[drives_table_idx].bus = bus_id;

    drives_table[drives_table_idx].unit = unit_id;

    drives_table[drives_table_idx].onerror = onerror;

    drives_table[drives_table_idx].drive_opt_idx = arg - drives_opt;

    strncpy(drives_table[nb_drives].serial, serial, sizeof(serial));

    nb_drives++;

    switch(type) {

    case IF_IDE:

    case IF_SCSI:

        switch(media) {

	case MEDIA_DISK:

            if (cyls != 0) {

                bdrv_set_geometry_hint(bdrv, cyls, heads, secs);

                bdrv_set_translation_hint(bdrv, translation);

            }

	    break;

	case MEDIA_CDROM:

            bdrv_set_type_hint(bdrv, BDRV_TYPE_CDROM);

	    break;

	}

        break;

    case IF_SD:

        /* FIXME: This isn't really a floppy, but it's a reasonable

           approximation.  */

    case IF_FLOPPY:

        bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);

        break;

    case IF_PFLASH:

    case IF_MTD:

    case IF_VIRTIO:

        break;

    }

    if (!file[0])

        return 0;

    bdrv_flags = 0;

    if (snapshot) {

        bdrv_flags |= BDRV_O_SNAPSHOT;

        cache = 2; /* always use write-back with snapshot */

    }

    if (cache == 0) /* no caching */

        bdrv_flags |= BDRV_O_NOCACHE;

    else if (cache == 2) /* write-back */

        bdrv_flags |= BDRV_O_CACHE_WB;

    else if (cache == 3) /* not specified */

        bdrv_flags |= BDRV_O_CACHE_DEF;

    if (bdrv_open2(bdrv, file, bdrv_flags, drv) < 0 || qemu_key_check(bdrv, file)) {

        fprintf(stderr, "qemu: could not open disk image %s\n",

                        file);

        return -1;

    }

    return 0;

}


static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)

{

    QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;

    qpci_io_writeb(dev->pdev, dev->addr + VIRTIO_PCI_STATUS, status);

}


static void test_acpi_piix4_tcg_cphp(void)

{

    test_data data;

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

    data.machine = MACHINE_PC;

    data.variant = ".cphp";

    test_acpi_one("-smp 2,cores=3,sockets=2,maxcpus=6",

                  &data);

    free_test_data(&data);

}


void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,

                               int64_t bps_wr,

                               int64_t iops,

                               int64_t iops_rd,

                               int64_t iops_wr,

                               bool has_bps_max,

                               int64_t bps_max,

                               bool has_bps_rd_max,

                               int64_t bps_rd_max,

                               bool has_bps_wr_max,

                               int64_t bps_wr_max,

                               bool has_iops_max,

                               int64_t iops_max,

                               bool has_iops_rd_max,

                               int64_t iops_rd_max,

                               bool has_iops_wr_max,

                               int64_t iops_wr_max,

                               bool has_iops_size,

                               int64_t iops_size, Error **errp)

{

    ThrottleConfig cfg;

    BlockDriverState *bs;

    bs = bdrv_find(device);

    if (!bs) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, device);

        return;

    }

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

    cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps;

    cfg.buckets[THROTTLE_BPS_READ].avg  = bps_rd;

    cfg.buckets[THROTTLE_BPS_WRITE].avg = bps_wr;

    cfg.buckets[THROTTLE_OPS_TOTAL].avg = iops;

    cfg.buckets[THROTTLE_OPS_READ].avg  = iops_rd;

    cfg.buckets[THROTTLE_OPS_WRITE].avg = iops_wr;

    if (has_bps_max) {

        cfg.buckets[THROTTLE_BPS_TOTAL].max = bps_max;

    }

    if (has_bps_rd_max) {

        cfg.buckets[THROTTLE_BPS_READ].max = bps_rd_max;

    }

    if (has_bps_wr_max) {

        cfg.buckets[THROTTLE_BPS_WRITE].max = bps_wr_max;

    }

    if (has_iops_max) {

        cfg.buckets[THROTTLE_OPS_TOTAL].max = iops_max;

    }

    if (has_iops_rd_max) {

        cfg.buckets[THROTTLE_OPS_READ].max = iops_rd_max;

    }

    if (has_iops_wr_max) {

        cfg.buckets[THROTTLE_OPS_WRITE].max = iops_wr_max;

    }

    if (has_iops_size) {

        cfg.op_size = iops_size;

    }

    if (!check_throttle_config(&cfg, errp)) {

        return;

    }

    aio_context = bdrv_get_aio_context(bs);

    aio_context_acquire(aio_context);

    if (!bs->io_limits_enabled && throttle_enabled(&cfg)) {

        bdrv_io_limits_enable(bs);

    } else if (bs->io_limits_enabled && !throttle_enabled(&cfg)) {

        bdrv_io_limits_disable(bs);

    }

    if (bs->io_limits_enabled) {

        bdrv_set_io_limits(bs, &cfg);

    }

    aio_context_release(aio_context);

}


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

                        target_sigset_t *set, CPUM68KState *env)

{

    struct target_sigframe *frame;

    abi_ulong frame_addr;

    abi_ulong retcode_addr;

    abi_ulong sc_addr;

    int err = 0;

    int i;

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

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

	goto give_sigsegv;

    __put_user(sig, &frame->sig);

    sc_addr = frame_addr + offsetof(struct target_sigframe, sc);

    __put_user(sc_addr, &frame->psc);

    err |= setup_sigcontext(&frame->sc, env, set->sig[0]);

    if (err)

	goto give_sigsegv;

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

        if (__put_user(set->sig[i], &frame->extramask[i - 1]))

            goto give_sigsegv;

    }

    /* Set up to return from userspace.  */

    retcode_addr = frame_addr + offsetof(struct target_sigframe, retcode);

    __put_user(retcode_addr, &frame->pretcode);

    /* moveq #,d0; trap #0 */

    __put_user(0x70004e40 + (TARGET_NR_sigreturn << 16),

                      (long *)(frame->retcode));

    if (err)

        goto give_sigsegv;

    /* Set up to return from userspace */

    env->aregs[7] = frame_addr;

    env->pc = ka->_sa_handler;

    unlock_user_struct(frame, frame_addr, 1);

    return;

give_sigsegv:

    unlock_user_struct(frame, frame_addr, 1);

    force_sig(TARGET_SIGSEGV);

}


do_socket_read(GIOChannel *source,

               GIOCondition condition,

               gpointer data)

{

    int rv;

    int dwSendLength;

    int dwRecvLength;

    uint8_t pbRecvBuffer[APDUBufSize];

    static uint8_t pbSendBuffer[APDUBufSize];

    VReaderStatus reader_status;

    VReader *reader = NULL;

    static VSCMsgHeader mhHeader;

    VSCMsgError *error_msg;

    GError *err = NULL;

    static gchar *buf;

    static gsize br, to_read;

    static int state = STATE_HEADER;

    if (state == STATE_HEADER && to_read == 0) {

        buf = (gchar *)&mhHeader;

        to_read = sizeof(mhHeader);

    }

    if (to_read > 0) {

        g_io_channel_read_chars(source, (gchar *)buf, to_read, &br, &err);

        if (err != NULL) {

            g_error("error while reading: %s", err->message);

        }

        buf += br;

        to_read -= br;

        if (to_read != 0) {

            return TRUE;

        }

    }

    if (state == STATE_HEADER) {

        mhHeader.type = ntohl(mhHeader.type);

        mhHeader.reader_id = ntohl(mhHeader.reader_id);

        mhHeader.length = ntohl(mhHeader.length);

        if (verbose) {

            printf("Header: type=%d, reader_id=%u length=%d (0x%x)\n",

                   mhHeader.type, mhHeader.reader_id, mhHeader.length,

                   mhHeader.length);

        }

        switch (mhHeader.type) {

        case VSC_APDU:

        case VSC_Flush:

        case VSC_Error:

        case VSC_Init:

            buf = (gchar *)pbSendBuffer;

            to_read = mhHeader.length;

            state = STATE_MESSAGE;

            return TRUE;

        default:

            fprintf(stderr, "Unexpected message of type 0x%X\n", mhHeader.type);

            return FALSE;

        }

    }

    if (state == STATE_MESSAGE) {

        switch (mhHeader.type) {

        case VSC_APDU:

            if (verbose) {

                printf(" recv APDU: ");

                print_byte_array(pbSendBuffer, mhHeader.length);

            }

            /* Transmit received APDU */

            dwSendLength = mhHeader.length;

            dwRecvLength = sizeof(pbRecvBuffer);

            reader = vreader_get_reader_by_id(mhHeader.reader_id);

            reader_status = vreader_xfr_bytes(reader,

                                              pbSendBuffer, dwSendLength,

                                              pbRecvBuffer, &dwRecvLength);

            if (reader_status == VREADER_OK) {

                mhHeader.length = dwRecvLength;

                if (verbose) {

                    printf(" send response: ");

                    print_byte_array(pbRecvBuffer, mhHeader.length);

                }

                send_msg(VSC_APDU, mhHeader.reader_id,

                         pbRecvBuffer, dwRecvLength);

            } else {

                rv = reader_status; /* warning: not meaningful */

                send_msg(VSC_Error, mhHeader.reader_id, &rv, sizeof(uint32_t));

            }

            vreader_free(reader);

            reader = NULL; /* we've freed it, don't use it by accident

                              again */

            break;

        case VSC_Flush:

            /* TODO: actually flush */

            send_msg(VSC_FlushComplete, mhHeader.reader_id, NULL, 0);

            break;

        case VSC_Error:

            error_msg = (VSCMsgError *) pbSendBuffer;

            if (error_msg->code == VSC_SUCCESS) {

                qemu_mutex_lock(&pending_reader_lock);

                if (pending_reader) {

                    vreader_set_id(pending_reader, mhHeader.reader_id);

                    vreader_free(pending_reader);

                    pending_reader = NULL;

                    qemu_cond_signal(&pending_reader_condition);

                }

                qemu_mutex_unlock(&pending_reader_lock);

                break;

            }

            printf("warning: qemu refused to add reader\n");

            if (error_msg->code == VSC_CANNOT_ADD_MORE_READERS) {

                /* clear pending reader, qemu can't handle any more */

                qemu_mutex_lock(&pending_reader_lock);

                if (pending_reader) {

                    pending_reader = NULL;

                    /* make sure the event loop doesn't hang */

                    qemu_cond_signal(&pending_reader_condition);

                }

                qemu_mutex_unlock(&pending_reader_lock);

            }

            break;

        case VSC_Init:

            if (on_host_init(&mhHeader, (VSCMsgInit *)pbSendBuffer) < 0) {

                return FALSE;

            }

            break;

        default:

            g_assert_not_reached();

            return FALSE;

        }

        state = STATE_HEADER;

    }

    return TRUE;

}


static size_t buffered_get_rate_limit(void *opaque)

{

    QEMUFileBuffered *s = opaque;

    return s->xfer_limit;

}


static void check_time(int wiggle)

{

    struct tm start, date[4], end;

    struct tm *datep;

    time_t ts;

    /*

     * This check assumes a few things.  First, we cannot guarantee that we get

     * a consistent reading from the wall clock because we may hit an edge of

     * the clock while reading.  To work around this, we read four clock readings

     * such that at least two of them should match.  We need to assume that one

     * reading is corrupt so we need four readings to ensure that we have at

     * least two consecutive identical readings

     *

     * It's also possible that we'll cross an edge reading the host clock so

     * simply check to make sure that the clock reading is within the period of

     * when we expect it to be.

     */

    ts = time(NULL);

    gmtime_r(&ts, &start);

    cmos_get_date_time(&date[0]);

    cmos_get_date_time(&date[1]);

    cmos_get_date_time(&date[2]);

    cmos_get_date_time(&date[3]);

    ts = time(NULL);

    gmtime_r(&ts, &end);

    if (tm_cmp(&date[0], &date[1]) == 0) {

        datep = &date[0];

    } else if (tm_cmp(&date[1], &date[2]) == 0) {

        datep = &date[1];

    } else if (tm_cmp(&date[2], &date[3]) == 0) {

        datep = &date[2];

    } else {

        g_assert_not_reached();

    }

    if (!(tm_cmp(&start, datep) <= 0 && tm_cmp(datep, &end) <= 0)) {

        time_t t, s;

        start.tm_isdst = datep->tm_isdst;

        t = mktime(datep);

        s = mktime(&start);

        if (t < s) {

            g_test_message("RTC is %ld second(s) behind wall-clock\n", (s - t));

        } else {

            g_test_message("RTC is %ld second(s) ahead of wall-clock\n", (t - s));

        }

        g_assert_cmpint(ABS(t - s), <=, wiggle);

    }

}


aio_ctx_finalize(GSource     *source)

{

    AioContext *ctx = (AioContext *) source;

    thread_pool_free(ctx->thread_pool);

#ifdef CONFIG_LINUX_AIO

    if (ctx->linux_aio) {

        laio_detach_aio_context(ctx->linux_aio, ctx);

        laio_cleanup(ctx->linux_aio);

        ctx->linux_aio = NULL;

    }

#endif

    qemu_lockcnt_lock(&ctx->list_lock);

    assert(!qemu_lockcnt_count(&ctx->list_lock));

    while (ctx->first_bh) {

        QEMUBH *next = ctx->first_bh->next;

        /* qemu_bh_delete() must have been called on BHs in this AioContext */

        assert(ctx->first_bh->deleted);

        g_free(ctx->first_bh);

        ctx->first_bh = next;

    }

    qemu_lockcnt_unlock(&ctx->list_lock);

    aio_set_event_notifier(ctx, &ctx->notifier, false, NULL, NULL);

    event_notifier_cleanup(&ctx->notifier);

    qemu_rec_mutex_destroy(&ctx->lock);

    qemu_lockcnt_destroy(&ctx->list_lock);

    timerlistgroup_deinit(&ctx->tlg);

}


static void bdrv_stats_iter(QObject *data, void *opaque)

{

    QDict *qdict;

    Monitor *mon = opaque;

    qdict = qobject_to_qdict(data);

    monitor_printf(mon, "%s:", qdict_get_str(qdict, "device"));

    qdict = qobject_to_qdict(qdict_get(qdict, "stats"));

    monitor_printf(mon, " rd_bytes=%" PRId64

                        " wr_bytes=%" PRId64

                        " rd_operations=%" PRId64

                        " wr_operations=%" PRId64

                        " flush_operations=%" PRId64

                        "\n",

                        qdict_get_int(qdict, "rd_bytes"),

                        qdict_get_int(qdict, "wr_bytes"),

                        qdict_get_int(qdict, "rd_operations"),

                        qdict_get_int(qdict, "wr_operations"),

                        qdict_get_int(qdict, "flush_operations"));

}


static int nbd_send_negotiate(NBDClient *client)

{

    int csock = client->sock;

    char buf[8 + 8 + 8 + 128];

    int rc;

    const int myflags = (NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |

                         NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);

    /* Negotiation header without options:

        [ 0 ..   7]   passwd       ("NBDMAGIC")

        [ 8 ..  15]   magic        (NBD_CLIENT_MAGIC)

        [16 ..  23]   size

        [24 ..  25]   server flags (0)

        [26 ..  27]   export flags

        [28 .. 151]   reserved     (0)

       Negotiation header with options, part 1:

        [ 0 ..   7]   passwd       ("NBDMAGIC")

        [ 8 ..  15]   magic        (NBD_OPTS_MAGIC)

        [16 ..  17]   server flags (0)

       part 2 (after options are sent):

        [18 ..  25]   size

        [26 ..  27]   export flags

        [28 .. 151]   reserved     (0)

     */

    qemu_set_block(csock);

    rc = -EINVAL;

    TRACE("Beginning negotiation.");

    memset(buf, 0, sizeof(buf));

    memcpy(buf, "NBDMAGIC", 8);

    if (client->exp) {

        assert ((client->exp->nbdflags & ~65535) == 0);

        cpu_to_be64w((uint64_t*)(buf + 8), NBD_CLIENT_MAGIC);

        cpu_to_be64w((uint64_t*)(buf + 16), client->exp->size);

        cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);

    } else {

        cpu_to_be64w((uint64_t*)(buf + 8), NBD_OPTS_MAGIC);

        cpu_to_be16w((uint16_t *)(buf + 16), NBD_FLAG_FIXED_NEWSTYLE);

    }

    if (client->exp) {

        if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) {

            LOG("write failed");

            goto fail;

        }

    } else {

        if (write_sync(csock, buf, 18) != 18) {

            LOG("write failed");

            goto fail;

        }

        rc = nbd_receive_options(client);

        if (rc != 0) {

            LOG("option negotiation failed");

            goto fail;

        }

        assert ((client->exp->nbdflags & ~65535) == 0);

        cpu_to_be64w((uint64_t*)(buf + 18), client->exp->size);

        cpu_to_be16w((uint16_t*)(buf + 26), client->exp->nbdflags | myflags);

        if (write_sync(csock, buf + 18, sizeof(buf) - 18) != sizeof(buf) - 18) {

            LOG("write failed");

            goto fail;

        }

    }

    TRACE("Negotiation succeeded.");

    rc = 0;

fail:

    qemu_set_nonblock(csock);

    return rc;

}


void tcg_gen_mb(TCGBar mb_type)

{

    if (parallel_cpus) {

        tcg_gen_op1(INDEX_op_mb, mb_type);

    }

}


void *virtqueue_alloc_element(size_t sz, unsigned out_num, unsigned in_num)

{

    VirtQueueElement *elem;

    size_t in_addr_ofs = QEMU_ALIGN_UP(sz, __alignof__(elem->in_addr[0]));

    size_t out_addr_ofs = in_addr_ofs + in_num * sizeof(elem->in_addr[0]);

    size_t out_addr_end = out_addr_ofs + out_num * sizeof(elem->out_addr[0]);

    size_t in_sg_ofs = QEMU_ALIGN_UP(out_addr_end, __alignof__(elem->in_sg[0]));

    size_t out_sg_ofs = in_sg_ofs + in_num * sizeof(elem->in_sg[0]);

    size_t out_sg_end = out_sg_ofs + out_num * sizeof(elem->out_sg[0]);

    assert(sz >= sizeof(VirtQueueElement));

    elem = g_malloc(out_sg_end);

    elem->out_num = out_num;

    elem->in_num = in_num;

    elem->in_addr = (void *)elem + in_addr_ofs;

    elem->out_addr = (void *)elem + out_addr_ofs;

    elem->in_sg = (void *)elem + in_sg_ofs;

    elem->out_sg = (void *)elem + out_sg_ofs;

    return elem;

}


static int usb_serial_initfn(USBDevice *dev)

{

    USBSerialState *s = DO_UPCAST(USBSerialState, dev, dev);

    s->dev.speed = USB_SPEED_FULL;

    if (!s->cs) {

        error_report("Property chardev is required");

        return -1;

    }

    qemu_chr_add_handlers(s->cs, usb_serial_can_read, usb_serial_read,

                          usb_serial_event, s);

    usb_serial_handle_reset(dev);

    return 0;

}


DeviceState *nand_init(BlockDriverState *bdrv, int manf_id, int chip_id)

{

    DeviceState *dev;

    if (nand_flash_ids[chip_id].size == 0) {

        hw_error("%s: Unsupported NAND chip ID.\n", __FUNCTION__);

    }

    dev = DEVICE(object_new(TYPE_NAND));

    qdev_prop_set_uint8(dev, "manufacturer_id", manf_id);

    qdev_prop_set_uint8(dev, "chip_id", chip_id);

    if (bdrv) {

        qdev_prop_set_drive_nofail(dev, "drive", bdrv);

    }

    qdev_init_nofail(dev);

    return dev;

}


static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg,

                                        DWORD_PTR dwUser, DWORD_PTR dw1,

                                        DWORD_PTR dw2)

#else

static void host_alarm_handler(int host_signum)

#endif

{

#if 0

#define DISP_FREQ 1000

    {

        static int64_t delta_min = INT64_MAX;

        static int64_t delta_max, delta_cum, last_clock, delta, ti;

        static int count;

        ti = qemu_get_clock(vm_clock);

        if (last_clock != 0) {

            delta = ti - last_clock;

            if (delta < delta_min)

                delta_min = delta;

            if (delta > delta_max)

                delta_max = delta;

            delta_cum += delta;

            if (++count == DISP_FREQ) {

                printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n",

                       muldiv64(delta_min, 1000000, ticks_per_sec),

                       muldiv64(delta_max, 1000000, ticks_per_sec),

                       muldiv64(delta_cum, 1000000 / DISP_FREQ, ticks_per_sec),

                       (double)ticks_per_sec / ((double)delta_cum / DISP_FREQ));

                count = 0;

                delta_min = INT64_MAX;

                delta_max = 0;

                delta_cum = 0;

            }

        }

        last_clock = ti;

    }

#endif

    if (alarm_has_dynticks(alarm_timer) ||

        (!use_icount &&

            qemu_timer_expired(active_timers[QEMU_TIMER_VIRTUAL],

                               qemu_get_clock(vm_clock))) ||

        qemu_timer_expired(active_timers[QEMU_TIMER_REALTIME],

                           qemu_get_clock(rt_clock))) {

        qemu_event_increment();

        alarm_timer->flags |= ALARM_FLAG_EXPIRED;

#ifndef CONFIG_IOTHREAD

        if (next_cpu) {

            /* stop the currently executing cpu because a timer occured */

            cpu_exit(next_cpu);

#ifdef CONFIG_KQEMU

            if (next_cpu->kqemu_enabled) {

                kqemu_cpu_interrupt(next_cpu);

            }

#endif

        }

#endif

        timer_alarm_pending = 1;

        qemu_notify_event();

    }

}


static bool get_phys_addr_lpae(CPUARMState *env, target_ulong address,

                               int access_type, ARMMMUIdx mmu_idx,

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

                               target_ulong *page_size_ptr, uint32_t *fsr)

{

    ARMCPU *cpu = arm_env_get_cpu(env);

    CPUState *cs = CPU(cpu);

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

    MMUFaultType fault_type = translation_fault;

    uint32_t level = 1;

    uint32_t epd = 0;

    int32_t t0sz, t1sz;

    uint32_t tg;

    uint64_t ttbr;

    int ttbr_select;

    hwaddr descaddr, descmask;

    uint32_t tableattrs;

    target_ulong page_size;

    uint32_t attrs;

    int32_t stride = 9;

    int32_t va_size = 32;

    int inputsize;

    int32_t tbi = 0;

    TCR *tcr = regime_tcr(env, mmu_idx);

    int ap, ns, xn, pxn;

    uint32_t el = regime_el(env, mmu_idx);

    bool ttbr1_valid = true;

    /* TODO:

     * This code does not handle the different format TCR for VTCR_EL2.

     * This code also does not support shareability levels.

     * Attribute and permission bit handling should also be checked when adding

     * support for those page table walks.

     */

    if (arm_el_is_aa64(env, el)) {

        va_size = 64;

        if (el > 1) {

            if (mmu_idx != ARMMMUIdx_S2NS) {

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

            }

        } else {

            if (extract64(address, 55, 1)) {

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

            } else {

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

            }

        }

        tbi *= 8;

        /* If we are in 64-bit EL2 or EL3 then there is no TTBR1, so mark it

         * invalid.

         */

        if (el > 1) {

            ttbr1_valid = false;

        }

    } else {

        /* There is no TTBR1 for EL2 */

        if (el == 2) {

            ttbr1_valid = false;

        }

    }

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

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

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

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

     */

    if (va_size == 64) {

        /* AArch64 translation.  */

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

        t0sz = MIN(t0sz, 39);

        t0sz = MAX(t0sz, 16);

    } else if (mmu_idx != ARMMMUIdx_S2NS) {

        /* AArch32 stage 1 translation.  */

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

    } else {

        /* AArch32 stage 2 translation.  */

        bool sext = extract32(tcr->raw_tcr, 4, 1);

        bool sign = extract32(tcr->raw_tcr, 3, 1);

        t0sz = sextract32(tcr->raw_tcr, 0, 4);

        /* If the sign-extend bit is not the same as t0sz[3], the result

         * is unpredictable. Flag this as a guest error.  */

        if (sign != sext) {

            qemu_log_mask(LOG_GUEST_ERROR,

                          "AArch32: VTCR.S / VTCR.T0SZ[3] missmatch\n");

        }

    }

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

    if (va_size == 64) {

        t1sz = MIN(t1sz, 39);

        t1sz = MAX(t1sz, 16);

    }

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

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

        ttbr_select = 0;

    } else if (ttbr1_valid && t1sz &&

               !extract64(~address, va_size - t1sz, t1sz - tbi)) {

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

        ttbr_select = 1;

    } else if (!t0sz) {

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

        ttbr_select = 0;

    } else if (!t1sz && ttbr1_valid) {

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

        ttbr_select = 1;

    } else {

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

        fault_type = translation_fault;

        goto do_fault;

    }

    /* Note that QEMU ignores shareability and cacheability attributes,

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

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

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

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

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

     */

    if (ttbr_select == 0) {

        ttbr = regime_ttbr(env, mmu_idx, 0);

        if (el < 2) {

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

        }

        inputsize = va_size - t0sz;

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

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

            stride = 13;

        }

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

            stride = 11;

        }

    } else {

        /* We should only be here if TTBR1 is valid */

        assert(ttbr1_valid);

        ttbr = regime_ttbr(env, mmu_idx, 1);

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

        inputsize = va_size - t1sz;

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

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

            stride = 13;

        }

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

            stride = 11;

        }

    }

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

     * va_size, inputsize, ttbr, epd, stride, tbi

     */

    if (epd) {

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

         * Note: This is always 0 on 64-bit EL2 and EL3.

         */

        goto do_fault;

    }

    if (mmu_idx != ARMMMUIdx_S2NS) {

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

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

         * the number of strides (stride bits at a time) needed to

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

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

         * where their 'inputsize' is our 'inputsize', 'grainsize' is

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

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

         * = 4 - (inputsize - stride - 3 + stride - 1) / stride

         * = 4 - (inputsize - 4) / stride;

         */

        level = 4 - (inputsize - 4) / stride;

    } else {

        /* For stage 2 translations the starting level is specified by the

         * VTCR_EL2.SL0 field (whose interpretation depends on the page size)

         */

        int startlevel = extract32(tcr->raw_tcr, 6, 2);

        bool ok;

        if (va_size == 32 || stride == 9) {

            /* AArch32 or 4KB pages */

            level = 2 - startlevel;

        } else {

            /* 16KB or 64KB pages */

            level = 3 - startlevel;

        }

        /* Check that the starting level is valid. */

        ok = check_s2_startlevel(cpu, va_size == 64, level,

                                 inputsize, stride);

        if (!ok) {

            /* AArch64 reports these as level 0 faults.

             * AArch32 reports these as level 1 faults.

             */

            level = va_size == 64 ? 0 : 1;

            fault_type = translation_fault;

            goto do_fault;

        }

    }

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

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

     * first descriptor address.

     */

    if (va_size != inputsize) {

        address &= (1ULL << inputsize) - 1;

    }

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

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

    descaddr = extract64(ttbr, 0, 48);

    descaddr &= ~((1ULL << (inputsize - (stride * (4 - level)))) - 1);

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

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

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

     * bits at each step.

     */

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

    for (;;) {

        uint64_t descriptor;

        bool nstable;

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

        descaddr &= ~7ULL;

        nstable = extract32(tableattrs, 4, 1);

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

        if (!(descriptor & 1) ||

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

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

            goto do_fault;

        }

        descaddr = descriptor & 0xfffffff000ULL;

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

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

             * propagate down through lower levels of the table (and

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

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

             */

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

            level++;

            continue;

        }

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

         * These are basically the same thing, although the number

         * of bits we pull in from the vaddr varies.

         */

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

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

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

        attrs = extract64(descriptor, 2, 10)

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

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

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

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

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

         */

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

            attrs &= ~(1 << 4);

        }

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

        break;

    }

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

     * are all in attrs.

     */

    fault_type = access_fault;

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

        /* Access flag */

        goto do_fault;

    }

    ap = extract32(attrs, 4, 2);

    ns = extract32(attrs, 3, 1);

    xn = extract32(attrs, 12, 1);

    pxn = extract32(attrs, 11, 1);

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

    fault_type = permission_fault;

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

        goto do_fault;

    }

    if (ns) {

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

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

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

         */

        txattrs->secure = false;

    }

    *phys_ptr = descaddr;

    *page_size_ptr = page_size;

    return false;

do_fault:

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

    *fsr = (1 << 9) | (fault_type << 2) | level;

    return true;

}


static int openfile(char *name, int flags, int growable)

{

	if (bs) {

		fprintf(stderr, "file open already, try 'help close'\n");

		return 1;

	}

	bs = bdrv_new("hda");

	if (!bs)

		return 1;

	if (growable) {

		flags |= BDRV_O_FILE;

	}

	if (bdrv_open(bs, name, flags) == -1) {

		fprintf(stderr, "%s: can't open device %s\n", progname, name);

		bs = NULL;

		return 1;

	}

	if (growable) {

		bs->growable = 1;

	}

	return 0;

}


static void visit_nested_struct(Visitor *v, void **native, Error **errp)

{

    visit_type_UserDefNested(v, (UserDefNested **)native, NULL, errp);

}


static uint64_t bmdma_read(void *opaque, target_phys_addr_t addr, unsigned size)

{

    BMDMAState *bm = opaque;

    uint32_t val;

    if (size != 1) {

        return ((uint64_t)1 << (size * 8)) - 1;

    }

    switch(addr & 3) {

    case 0:

        val = bm->cmd;

        break;

    case 2:

        val = bm->status;

        break;

    default:

        val = 0xff;

        break;

    }

#ifdef DEBUG_IDE

    printf("bmdma: readb 0x%02x : 0x%02x\n", (uint8_t)addr, val);

#endif

    return val;

}


static void palmte_init(MachineState *machine)

{

    const char *kernel_filename = machine->kernel_filename;

    const char *kernel_cmdline = machine->kernel_cmdline;

    const char *initrd_filename = machine->initrd_filename;

    MemoryRegion *address_space_mem = get_system_memory();

    struct omap_mpu_state_s *mpu;

    int flash_size = 0x00800000;

    int sdram_size = palmte_binfo.ram_size;

    static uint32_t cs0val = 0xffffffff;

    static uint32_t cs1val = 0x0000e1a0;

    static uint32_t cs2val = 0x0000e1a0;

    static uint32_t cs3val = 0xe1a0e1a0;

    int rom_size, rom_loaded = 0;

    MemoryRegion *flash = g_new(MemoryRegion, 1);

    MemoryRegion *cs = g_new(MemoryRegion, 4);

    mpu = omap310_mpu_init(address_space_mem, sdram_size, machine->cpu_type);

    /* External Flash (EMIFS) */

    memory_region_init_ram(flash, NULL, "palmte.flash", flash_size,

                           &error_fatal);

    memory_region_set_readonly(flash, true);

    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE, flash);

    memory_region_init_io(&cs[0], NULL, &static_ops, &cs0val, "palmte-cs0",

                          OMAP_CS0_SIZE - flash_size);

    memory_region_add_subregion(address_space_mem, OMAP_CS0_BASE + flash_size,

                                &cs[0]);

    memory_region_init_io(&cs[1], NULL, &static_ops, &cs1val, "palmte-cs1",

                          OMAP_CS1_SIZE);

    memory_region_add_subregion(address_space_mem, OMAP_CS1_BASE, &cs[1]);

    memory_region_init_io(&cs[2], NULL, &static_ops, &cs2val, "palmte-cs2",

                          OMAP_CS2_SIZE);

    memory_region_add_subregion(address_space_mem, OMAP_CS2_BASE, &cs[2]);

    memory_region_init_io(&cs[3], NULL, &static_ops, &cs3val, "palmte-cs3",

                          OMAP_CS3_SIZE);

    memory_region_add_subregion(address_space_mem, OMAP_CS3_BASE, &cs[3]);

    palmte_microwire_setup(mpu);

    qemu_add_kbd_event_handler(palmte_button_event, mpu);

    palmte_gpio_setup(mpu);

    /* Setup initial (reset) machine state */

    if (nb_option_roms) {

        rom_size = get_image_size(option_rom[0].name);

        if (rom_size > flash_size) {

            fprintf(stderr, "%s: ROM image too big (%x > %x)\n",

                            __FUNCTION__, rom_size, flash_size);

            rom_size = 0;

        }

        if (rom_size > 0) {

            rom_size = load_image_targphys(option_rom[0].name, OMAP_CS0_BASE,

                                           flash_size);

            rom_loaded = 1;

        }

        if (rom_size < 0) {

            fprintf(stderr, "%s: error loading '%s'\n",

                            __FUNCTION__, option_rom[0].name);

        }

    }

    if (!rom_loaded && !kernel_filename && !qtest_enabled()) {

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

        exit(1);

    }

    /* Load the kernel.  */

    palmte_binfo.kernel_filename = kernel_filename;

    palmte_binfo.kernel_cmdline = kernel_cmdline;

    palmte_binfo.initrd_filename = initrd_filename;

    arm_load_kernel(mpu->cpu, &palmte_binfo);

}


void configure_icount(const char *option)

{

    vmstate_register(NULL, 0, &vmstate_timers, &timers_state);

    if (!option)

        return;

    if (strcmp(option, "auto") != 0) {

        icount_time_shift = strtol(option, NULL, 0);

        use_icount = 1;

        return;

    }

    use_icount = 2;

    /* 125MIPS seems a reasonable initial guess at the guest speed.

       It will be corrected fairly quickly anyway.  */

    icount_time_shift = 3;

    /* Have both realtime and virtual time triggers for speed adjustment.

       The realtime trigger catches emulated time passing too slowly,

       the virtual time trigger catches emulated time passing too fast.

       Realtime triggers occur even when idle, so use them less frequently

       than VM triggers.  */

    icount_rt_timer = qemu_new_timer(rt_clock, icount_adjust_rt, NULL);

    qemu_mod_timer(icount_rt_timer,

                   qemu_get_clock(rt_clock) + 1000);

    icount_vm_timer = qemu_new_timer(vm_clock, icount_adjust_vm, NULL);

    qemu_mod_timer(icount_vm_timer,

                   qemu_get_clock(vm_clock) + get_ticks_per_sec() / 10);

}


struct omap_mmc_s *omap_mmc_init(hwaddr base,

                MemoryRegion *sysmem,

                BlockDriverState *bd,

                qemu_irq irq, qemu_irq dma[], omap_clk clk)

{

    struct omap_mmc_s *s = (struct omap_mmc_s *)

            g_malloc0(sizeof(struct omap_mmc_s));

    s->irq = irq;

    s->dma = dma;

    s->clk = clk;

    s->lines = 1;	/* TODO: needs to be settable per-board */

    s->rev = 1;

    omap_mmc_reset(s);

    memory_region_init_io(&s->iomem, NULL, &omap_mmc_ops, s, "omap.mmc", 0x800);

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

    /* Instantiate the storage */

    s->card = sd_init(bd, false);

    if (s->card == NULL) {

        exit(1);

    }

    return s;

}


static int v9fs_synth_utimensat(FsContext *fs_ctx, V9fsPath *path,

                                const struct timespec *buf)

{

    errno = EPERM;

    return 0;

}


static int monitor_fprintf(FILE *stream, const char *fmt, ...)

{

    va_list ap;

    va_start(ap, fmt);

    monitor_vprintf((Monitor *)stream, fmt, ap);

    va_end(ap);

    return 0;

}


static void hls_transform_unit(HEVCContext *s, int x0, int y0,

                               int xBase, int yBase, int cb_xBase, int cb_yBase,

                               int log2_cb_size, int log2_trafo_size,

                               int trafo_depth, int blk_idx)

{

    HEVCLocalContext *lc = &s->HEVClc;

    if (lc->cu.pred_mode == MODE_INTRA) {

        int trafo_size = 1 << log2_trafo_size;

        ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);

        s->hpc.intra_pred(s, x0, y0, log2_trafo_size, 0);

        if (log2_trafo_size > 2) {

            trafo_size = trafo_size << (s->sps->hshift[1] - 1);

            ff_hevc_set_neighbour_available(s, x0, y0, trafo_size, trafo_size);

            s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 1);

            s->hpc.intra_pred(s, x0, y0, log2_trafo_size - 1, 2);

        } else if (blk_idx == 3) {

            trafo_size = trafo_size << s->sps->hshift[1];

            ff_hevc_set_neighbour_available(s, xBase, yBase,

                                            trafo_size, trafo_size);

            s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 1);

            s->hpc.intra_pred(s, xBase, yBase, log2_trafo_size, 2);

        }

    }

    if (lc->tt.cbf_luma ||

        SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) ||

        SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0)) {

        int scan_idx   = SCAN_DIAG;

        int scan_idx_c = SCAN_DIAG;

        if (s->pps->cu_qp_delta_enabled_flag && !lc->tu.is_cu_qp_delta_coded) {

            lc->tu.cu_qp_delta = ff_hevc_cu_qp_delta_abs(s);

            if (lc->tu.cu_qp_delta != 0)

                if (ff_hevc_cu_qp_delta_sign_flag(s) == 1)

                    lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta;

            lc->tu.is_cu_qp_delta_coded = 1;

            ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size);

        }

        if (lc->cu.pred_mode == MODE_INTRA && log2_trafo_size < 4) {

            if (lc->tu.cur_intra_pred_mode >= 6 &&

                lc->tu.cur_intra_pred_mode <= 14) {

                scan_idx = SCAN_VERT;

            } else if (lc->tu.cur_intra_pred_mode >= 22 &&

                       lc->tu.cur_intra_pred_mode <= 30) {

                scan_idx = SCAN_HORIZ;

            }

            if (lc->pu.intra_pred_mode_c >=  6 &&

                lc->pu.intra_pred_mode_c <= 14) {

                scan_idx_c = SCAN_VERT;

            } else if (lc->pu.intra_pred_mode_c >= 22 &&

                       lc->pu.intra_pred_mode_c <= 30) {

                scan_idx_c = SCAN_HORIZ;

            }

        }

        if (lc->tt.cbf_luma)

            hls_residual_coding(s, x0, y0, log2_trafo_size, scan_idx, 0);

        if (log2_trafo_size > 2) {

            if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0))

                hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 1);

            if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], x0, y0))

                hls_residual_coding(s, x0, y0, log2_trafo_size - 1, scan_idx_c, 2);

        } else if (blk_idx == 3) {

            if (SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], xBase, yBase))

                hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 1);

            if (SAMPLE_CBF(lc->tt.cbf_cr[trafo_depth], xBase, yBase))

                hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2);

        }

    }

}


static int tgv_decode_inter(TgvContext *s, AVFrame *frame,

                            const uint8_t *buf, const uint8_t *buf_end)

{

    int num_mvs;

    int num_blocks_raw;

    int num_blocks_packed;

    int vector_bits;

    int i,j,x,y;

    GetBitContext gb;

    int mvbits;

    const uint8_t *blocks_raw;

    if(buf_end - buf < 12)

        return AVERROR_INVALIDDATA;

    num_mvs           = AV_RL16(&buf[0]);

    num_blocks_raw    = AV_RL16(&buf[2]);

    num_blocks_packed = AV_RL16(&buf[4]);

    vector_bits       = AV_RL16(&buf[6]);

    buf += 12;

    if (vector_bits > MIN_CACHE_BITS || !vector_bits) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Invalid value for motion vector bits: %d\n", vector_bits);

        return AVERROR_INVALIDDATA;

    }

    /* allocate codebook buffers as necessary */

    if (num_mvs > s->num_mvs) {

        s->mv_codebook = av_realloc(s->mv_codebook, num_mvs*2*sizeof(int));

        s->num_mvs = num_mvs;

    }

    if (num_blocks_packed > s->num_blocks_packed) {

        s->block_codebook = av_realloc(s->block_codebook, num_blocks_packed*16);

        s->num_blocks_packed = num_blocks_packed;

    }

    /* read motion vectors */

    mvbits = (num_mvs * 2 * 10 + 31) & ~31;

    if (buf_end - buf < (mvbits>>3) + 16*num_blocks_raw + 8*num_blocks_packed)

        return AVERROR_INVALIDDATA;

    init_get_bits(&gb, buf, mvbits);

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

        s->mv_codebook[i][0] = get_sbits(&gb, 10);

        s->mv_codebook[i][1] = get_sbits(&gb, 10);

    }

    buf += mvbits >> 3;

    /* note ptr to uncompressed blocks */

    blocks_raw = buf;

    buf       += num_blocks_raw * 16;

    /* read compressed blocks */

    init_get_bits(&gb, buf, (buf_end - buf) << 3);

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

        int tmp[4];

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

            tmp[j] = get_bits(&gb, 8);

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

            s->block_codebook[i][15-j] = tmp[get_bits(&gb, 2)];

    }

    if (get_bits_left(&gb) < vector_bits *

        (s->avctx->height / 4) * (s->avctx->width / 4))

        return AVERROR_INVALIDDATA;

    /* read vectors and build frame */

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

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

            unsigned int vector = get_bits(&gb, vector_bits);

            const uint8_t *src;

            int src_stride;

            if (vector < num_mvs) {

                int mx = x * 4 + s->mv_codebook[vector][0];

                int my = y * 4 + s->mv_codebook[vector][1];

                if (mx < 0 || mx + 4 > s->avctx->width ||

                    my < 0 || my + 4 > s->avctx->height) {

                    av_log(s->avctx, AV_LOG_ERROR, "MV %d %d out of picture\n", mx, my);

                    continue;

                }

                src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0];

                src_stride = s->last_frame.linesize[0];

            } else {

                int offset = vector - num_mvs;

                if (offset < num_blocks_raw)

                    src = blocks_raw + 16*offset;

                else if (offset - num_blocks_raw < num_blocks_packed)

                    src = s->block_codebook[offset - num_blocks_raw];

                else

                    continue;

                src_stride = 4;

            }

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

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

                    frame->data[0][(y * 4 + j) * frame->linesize[0] + (x * 4 + i)] =

                        src[j * src_stride + i];

    }

    return 0;

}


void FUNCC(ff_h264_luma_dc_dequant_idct)(int16_t *_output, int16_t *_input, int qmul){

#define stride 16

    int i;

    int temp[16];

    static const uint8_t x_offset[4]={0, 2*stride, 8*stride, 10*stride};

    dctcoef *input = (dctcoef*)_input;

    dctcoef *output = (dctcoef*)_output;

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

        const int z0= input[4*i+0] + input[4*i+1];

        const int z1= input[4*i+0] - input[4*i+1];

        const int z2= input[4*i+2] - input[4*i+3];

        const int z3= input[4*i+2] + input[4*i+3];

        temp[4*i+0]= z0+z3;

        temp[4*i+1]= z0-z3;

        temp[4*i+2]= z1-z2;

        temp[4*i+3]= z1+z2;

    }

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

        const int offset= x_offset[i];

        const int z0= temp[4*0+i] + temp[4*2+i];

        const int z1= temp[4*0+i] - temp[4*2+i];

        const int z2= temp[4*1+i] - temp[4*3+i];

        const int z3= temp[4*1+i] + temp[4*3+i];

        output[stride* 0+offset]= ((((z0 + z3)*qmul + 128 ) >> 8));

        output[stride* 1+offset]= ((((z1 + z2)*qmul + 128 ) >> 8));

        output[stride* 4+offset]= ((((z1 - z2)*qmul + 128 ) >> 8));

        output[stride* 5+offset]= ((((z0 - z3)*qmul + 128 ) >> 8));

    }

#undef stride

}


static uint64_t qemu_rdma_make_wrid(uint64_t wr_id, uint64_t index,

                                         uint64_t chunk)

{

    uint64_t result = wr_id & RDMA_WRID_TYPE_MASK;

    result |= (index << RDMA_WRID_BLOCK_SHIFT);

    result |= (chunk << RDMA_WRID_CHUNK_SHIFT);

    return result;

}


static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs,

                                       Error **errp)

{

    Error *local_err = NULL;

    BlockMeasureInfo *info;

    uint64_t required = 0; /* bytes that contribute to required size */

    uint64_t virtual_size; /* disk size as seen by guest */

    uint64_t refcount_bits;

    uint64_t l2_tables;

    size_t cluster_size;

    int version;

    char *optstr;

    PreallocMode prealloc;

    bool has_backing_file;

    /* Parse image creation options */

    cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err);

    if (local_err) {

        goto err;

    }

    version = qcow2_opt_get_version_del(opts, &local_err);

    if (local_err) {

        goto err;

    }

    refcount_bits = qcow2_opt_get_refcount_bits_del(opts, version, &local_err);

    if (local_err) {

        goto err;

    }

    optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC);

    prealloc = qapi_enum_parse(PreallocMode_lookup, optstr,

                               PREALLOC_MODE__MAX, PREALLOC_MODE_OFF,

                               &local_err);

    g_free(optstr);

    if (local_err) {

        goto err;

    }

    optstr = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);

    has_backing_file = !!optstr;

    g_free(optstr);

    virtual_size = align_offset(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0),

                                cluster_size);

    /* Check that virtual disk size is valid */

    l2_tables = DIV_ROUND_UP(virtual_size / cluster_size,

                             cluster_size / sizeof(uint64_t));

    if (l2_tables * sizeof(uint64_t) > QCOW_MAX_L1_SIZE) {

        error_setg(&local_err, "The image size is too large "

                               "(try using a larger cluster size)");

        goto err;

    }

    /* Account for input image */

    if (in_bs) {

        int64_t ssize = bdrv_getlength(in_bs);

        if (ssize < 0) {

            error_setg_errno(&local_err, -ssize,

                             "Unable to get image virtual_size");

            goto err;

        }

        virtual_size = align_offset(ssize, cluster_size);

        if (has_backing_file) {

            /* We don't how much of the backing chain is shared by the input

             * image and the new image file.  In the worst case the new image's

             * backing file has nothing in common with the input image.  Be

             * conservative and assume all clusters need to be written.

             */

            required = virtual_size;

        } else {

            int cluster_sectors = cluster_size / BDRV_SECTOR_SIZE;

            int64_t sector_num;

            int pnum = 0;

            for (sector_num = 0;

                 sector_num < ssize / BDRV_SECTOR_SIZE;

                 sector_num += pnum) {

                int nb_sectors = MAX(ssize / BDRV_SECTOR_SIZE - sector_num,

                                     INT_MAX);

                BlockDriverState *file;

                int64_t ret;

                ret = bdrv_get_block_status_above(in_bs, NULL,

                                                  sector_num, nb_sectors,

                                                  &pnum, &file);

                if (ret < 0) {

                    error_setg_errno(&local_err, -ret,

                                     "Unable to get block status");

                    goto err;

                }

                if (ret & BDRV_BLOCK_ZERO) {

                    /* Skip zero regions (safe with no backing file) */

                } else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) ==

                           (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) {

                    /* Extend pnum to end of cluster for next iteration */

                    pnum = ROUND_UP(sector_num + pnum, cluster_sectors) -

                           sector_num;

                    /* Count clusters we've seen */

                    required += (sector_num % cluster_sectors + pnum) *

                                BDRV_SECTOR_SIZE;

                }

            }

        }

    }

    /* Take into account preallocation.  Nothing special is needed for

     * PREALLOC_MODE_METADATA since metadata is always counted.

     */

    if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {

        required = virtual_size;

    }

    info = g_new(BlockMeasureInfo, 1);

    info->fully_allocated =

        qcow2_calc_prealloc_size(virtual_size, cluster_size,

                                 ctz32(refcount_bits));

    /* Remove data clusters that are not required.  This overestimates the

     * required size because metadata needed for the fully allocated file is

     * still counted.

     */

    info->required = info->fully_allocated - virtual_size + required;

    return info;

err:

    error_propagate(errp, local_err);

    return NULL;

}