static void get_tag(AVFormatContext *s, AVIOContext *pb, const char *key, int type, int length)

{

    int buf_size = FFMAX(2*length, LEN_PRETTY_GUID) + 1;

    char *buf = av_malloc(buf_size);

    if (!buf)

        return;

    if (type == 0 && length == 4) {

        snprintf(buf, buf_size, "%"PRIi32, avio_rl32(pb));

    } else if (type == 1) {

        avio_get_str16le(pb, length, buf, buf_size);

        if (!strlen(buf)) {

           av_free(buf);

           return;

        }

    } else if (type == 3 && length == 4) {

        strcpy(buf, avio_rl32(pb) ? "true" : "false");

    } else if (type == 4 && length == 8) {

        int64_t num = avio_rl64(pb);

        if (!strcmp(key, "WM/EncodingTime") ||

            !strcmp(key, "WM/MediaOriginalBroadcastDateTime"))

            filetime_to_iso8601(buf, buf_size, num);

        else if (!strcmp(key, "WM/WMRVEncodeTime") ||

                 !strcmp(key, "WM/WMRVEndTime"))

            crazytime_to_iso8601(buf, buf_size, num);

        else if (!strcmp(key, "WM/WMRVExpirationDate"))

            oledate_to_iso8601(buf, buf_size, num);

        else if (!strcmp(key, "WM/WMRVBitrate"))

            snprintf(buf, buf_size, "%f", av_int2dbl(num));

        else

            snprintf(buf, buf_size, "%"PRIi64, num);

    } else if (type == 5 && length == 2) {

        snprintf(buf, buf_size, "%"PRIi16, avio_rl16(pb));

    } else if (type == 6 && length == 16) {

        ff_asf_guid guid;

        avio_read(pb, guid, 16);

        snprintf(buf, buf_size, PRI_PRETTY_GUID, ARG_PRETTY_GUID(guid));

    } else if (type == 2 && !strcmp(key, "WM/Picture")) {

        get_attachment(s, pb, length);

        av_freep(&buf);

        return;

    } else {

        av_freep(&buf);

        av_log(s, AV_LOG_WARNING, "unsupported metadata entry; key:%s, type:%d, length:0x%x\n", key, type, length);

        avio_skip(pb, length);

        return;

    }

    av_metadata_set2(&s->metadata, key, buf, 0);

    av_freep(&buf);

}


void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,

                          ISADevice **rtc_state,

                          bool create_fdctrl,

                          bool no_vmport,

                          uint32_t hpet_irqs)

{

    int i;

    DriveInfo *fd[MAX_FD];

    DeviceState *hpet = NULL;

    int pit_isa_irq = 0;

    qemu_irq pit_alt_irq = NULL;

    qemu_irq rtc_irq = NULL;

    qemu_irq *a20_line;

    ISADevice *i8042, *port92, *vmmouse, *pit = NULL;

    MemoryRegion *ioport80_io = g_new(MemoryRegion, 1);

    MemoryRegion *ioportF0_io = g_new(MemoryRegion, 1);

    memory_region_init_io(ioport80_io, NULL, &ioport80_io_ops, NULL, "ioport80", 1);

    memory_region_add_subregion(isa_bus->address_space_io, 0x80, ioport80_io);

    memory_region_init_io(ioportF0_io, NULL, &ioportF0_io_ops, NULL, "ioportF0", 1);

    memory_region_add_subregion(isa_bus->address_space_io, 0xf0, ioportF0_io);

    /*

     * Check if an HPET shall be created.

     *

     * Without KVM_CAP_PIT_STATE2, we cannot switch off the in-kernel PIT

     * when the HPET wants to take over. Thus we have to disable the latter.

     */

    if (!no_hpet && (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) {

        /* In order to set property, here not using sysbus_try_create_simple */

        hpet = qdev_try_create(NULL, TYPE_HPET);

        if (hpet) {

            /* For pc-piix-*, hpet's intcap is always IRQ2. For pc-q35-1.7

             * and earlier, use IRQ2 for compat. Otherwise, use IRQ16~23,

             * IRQ8 and IRQ2.

             */

            uint8_t compat = object_property_get_int(OBJECT(hpet),

                    HPET_INTCAP, NULL);

            if (!compat) {

                qdev_prop_set_uint32(hpet, HPET_INTCAP, hpet_irqs);

            }

            qdev_init_nofail(hpet);

            sysbus_mmio_map(SYS_BUS_DEVICE(hpet), 0, HPET_BASE);

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

                sysbus_connect_irq(SYS_BUS_DEVICE(hpet), i, gsi[i]);

            }

            pit_isa_irq = -1;

            pit_alt_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_PIT_INT);

            rtc_irq = qdev_get_gpio_in(hpet, HPET_LEGACY_RTC_INT);

        }

    }

    *rtc_state = rtc_init(isa_bus, 2000, rtc_irq);

    qemu_register_boot_set(pc_boot_set, *rtc_state);

    if (!xen_enabled()) {

        if (kvm_pit_in_kernel()) {

            pit = kvm_pit_init(isa_bus, 0x40);

        } else {

            pit = pit_init(isa_bus, 0x40, pit_isa_irq, pit_alt_irq);

        }

        if (hpet) {

            /* connect PIT to output control line of the HPET */

            qdev_connect_gpio_out(hpet, 0, qdev_get_gpio_in(DEVICE(pit), 0));

        }

        pcspk_init(isa_bus, pit);

    }

    serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS);

    parallel_hds_isa_init(isa_bus, MAX_PARALLEL_PORTS);

    a20_line = qemu_allocate_irqs(handle_a20_line_change, first_cpu, 2);

    i8042 = isa_create_simple(isa_bus, "i8042");

    i8042_setup_a20_line(i8042, a20_line[0]);

    if (!no_vmport) {

        vmport_init(isa_bus);

        vmmouse = isa_try_create(isa_bus, "vmmouse");

    } else {

        vmmouse = NULL;

    }

    if (vmmouse) {

        DeviceState *dev = DEVICE(vmmouse);

        qdev_prop_set_ptr(dev, "ps2_mouse", i8042);

        qdev_init_nofail(dev);

    }

    port92 = isa_create_simple(isa_bus, "port92");

    port92_init(port92, a20_line[1]);

    DMA_init(isa_bus, 0);

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

        fd[i] = drive_get(IF_FLOPPY, 0, i);

        create_fdctrl |= !!fd[i];

    }

    if (create_fdctrl) {

        fdctrl_init_isa(isa_bus, fd);

    }

}


void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values,

                                  uint16_t *y_list, int *flag,

                                  int multiplier, float *out, int samples)

{

    int lx, ly, i;

    lx = 0;

    ly = y_list[0] * multiplier;

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

        int pos = list[i].sort;

        if (flag[pos]) {

            int x1 = list[pos].x;

            int y1 = y_list[pos] * multiplier;

            if (lx < samples)

                render_line(lx, ly, FFMIN(x1,samples), y1, out);

            lx = x1;

            ly = y1;

        }

        if (lx >= samples)

            break;

    }

    if (lx < samples)

        render_line(lx, ly, samples, ly, out);

}


static void channel_weighting(float *su1, float *su2, int *p3)

{

    int band, nsample;

    /* w[x][y] y=0 is left y=1 is right */

    float w[2][2];

    if (p3[1] != 7 || p3[3] != 7) {

        get_channel_weights(p3[1], p3[0], w[0]);

        get_channel_weights(p3[3], p3[2], w[1]);

        for (band = 1; band < 4; band++) {

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

                su1[band * 256 + nsample] *= INTERPOLATE(w[0][0], w[0][1], nsample);

                su2[band * 256 + nsample] *= INTERPOLATE(w[1][0], w[1][1], nsample);

            }

            for(; nsample < 256; nsample++) {

                su1[band * 256  + nsample] *= w[1][0];

                su2[band * 256  + nsample] *= w[1][1];

            }

        }

    }

}


bool bdrv_requests_pending(BlockDriverState *bs)

{

    BdrvChild *child;

    BlockBackendPublic *blkp = bs->blk ? blk_get_public(bs->blk) : NULL;

    if (!QLIST_EMPTY(&bs->tracked_requests)) {

        return true;

    }

    if (blkp && !qemu_co_queue_empty(&blkp->throttled_reqs[0])) {

        return true;

    }

    if (blkp && !qemu_co_queue_empty(&blkp->throttled_reqs[1])) {

        return true;

    }

    QLIST_FOREACH(child, &bs->children, next) {

        if (bdrv_requests_pending(child->bs)) {

            return true;

        }

    }

    return false;

}


static void qvirtio_9p_pci_free(QVirtIO9P *v9p)

{

    qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->alloc);

    pc_alloc_uninit(v9p->alloc);

    qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));

    g_free(v9p->dev);

    qpci_free_pc(v9p->bus);

    g_free(v9p);

}


static int coroutine_fn bdrv_co_do_pwrite_zeroes(BlockDriverState *bs,

    int64_t offset, int count, BdrvRequestFlags flags)

{

    BlockDriver *drv = bs->drv;

    QEMUIOVector qiov;

    struct iovec iov = {0};

    int ret = 0;

    bool need_flush = false;

    int head = 0;

    int tail = 0;

    int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_pwrite_zeroes, INT_MAX);

    int alignment = MAX(bs->bl.pwrite_zeroes_alignment ?: 1,

                        bs->request_alignment);

    assert(is_power_of_2(alignment));

    head = offset & (alignment - 1);

    tail = (offset + count) & (alignment - 1);

    max_write_zeroes &= ~(alignment - 1);

    while (count > 0 && !ret) {

        int num = count;

        /* Align request.  Block drivers can expect the "bulk" of the request

         * to be aligned, and that unaligned requests do not cross cluster

         * boundaries.

         */

        if (head) {

            /* Make a small request up to the first aligned sector.  */

            num = MIN(count, alignment - head);

            head = 0;

        } else if (tail && num > alignment) {

            /* Shorten the request to the last aligned sector.  */

            num -= tail;

        }

        /* limit request size */

        if (num > max_write_zeroes) {

            num = max_write_zeroes;

        }

        ret = -ENOTSUP;

        /* First try the efficient write zeroes operation */

        if (drv->bdrv_co_pwrite_zeroes) {

            ret = drv->bdrv_co_pwrite_zeroes(bs, offset, num,

                                             flags & bs->supported_zero_flags);

            if (ret != -ENOTSUP && (flags & BDRV_REQ_FUA) &&

                !(bs->supported_zero_flags & BDRV_REQ_FUA)) {

                need_flush = true;

            }

        } else {

            assert(!bs->supported_zero_flags);

        }

        if (ret == -ENOTSUP) {

            /* Fall back to bounce buffer if write zeroes is unsupported */

            int max_xfer_len = MIN_NON_ZERO(bs->bl.max_transfer_length,

                                            MAX_WRITE_ZEROES_BOUNCE_BUFFER);

            BdrvRequestFlags write_flags = flags & ~BDRV_REQ_ZERO_WRITE;

            if ((flags & BDRV_REQ_FUA) &&

                !(bs->supported_write_flags & BDRV_REQ_FUA)) {

                /* No need for bdrv_driver_pwrite() to do a fallback

                 * flush on each chunk; use just one at the end */

                write_flags &= ~BDRV_REQ_FUA;

                need_flush = true;

            }

            num = MIN(num, max_xfer_len << BDRV_SECTOR_BITS);

            iov.iov_len = num;

            if (iov.iov_base == NULL) {

                iov.iov_base = qemu_try_blockalign(bs, num);

                if (iov.iov_base == NULL) {

                    ret = -ENOMEM;

                    goto fail;

                }

                memset(iov.iov_base, 0, num);

            }

            qemu_iovec_init_external(&qiov, &iov, 1);

            ret = bdrv_driver_pwritev(bs, offset, num, &qiov, write_flags);

            /* Keep bounce buffer around if it is big enough for all

             * all future requests.

             */

            if (num < max_xfer_len << BDRV_SECTOR_BITS) {

                qemu_vfree(iov.iov_base);

                iov.iov_base = NULL;

            }

        }

        offset += num;

        count -= num;

    }

fail:

    if (ret == 0 && need_flush) {

        ret = bdrv_co_flush(bs);

    }

    qemu_vfree(iov.iov_base);

    return ret;

}


int load_vmstate(const char *name)

{

    BlockDriverState *bs, *bs_vm_state;

    QEMUSnapshotInfo sn;

    QEMUFile *f;

    int ret;

    if (!bdrv_all_can_snapshot(&bs)) {

        error_report("Device '%s' is writable but does not support snapshots.",

                     bdrv_get_device_name(bs));

        return -ENOTSUP;

    }

    bs_vm_state = find_vmstate_bs();

    if (!bs_vm_state) {

        error_report("No block device supports snapshots");

        return -ENOTSUP;

    }

    /* Don't even try to load empty VM states */

    ret = bdrv_snapshot_find(bs_vm_state, &sn, name);

    if (ret < 0) {

        return ret;

    } else if (sn.vm_state_size == 0) {

        error_report("This is a disk-only snapshot. Revert to it offline "

            "using qemu-img.");

        return -EINVAL;

    }

    /* Verify if there is any device that doesn't support snapshots and is

    writable and check if the requested snapshot is available too. */

    bs = NULL;

    while ((bs = bdrv_next(bs))) {

        if (!bdrv_can_snapshot(bs)) {

            continue;

        }

        ret = bdrv_snapshot_find(bs, &sn, name);

        if (ret < 0) {

            error_report("Device '%s' does not have the requested snapshot '%s'",

                           bdrv_get_device_name(bs), name);

            return ret;

        }

    }

    /* Flush all IO requests so they don't interfere with the new state.  */

    bdrv_drain_all();

    ret = bdrv_all_goto_snapshot(name, &bs);

    if (ret < 0) {

        error_report("Error %d while activating snapshot '%s' on '%s'",

                     ret, name, bdrv_get_device_name(bs));

        return ret;

    }

    /* restore the VM state */

    f = qemu_fopen_bdrv(bs_vm_state, 0);

    if (!f) {

        error_report("Could not open VM state file");

        return -EINVAL;

    }

    qemu_system_reset(VMRESET_SILENT);

    migration_incoming_state_new(f);

    ret = qemu_loadvm_state(f);

    qemu_fclose(f);

    migration_incoming_state_destroy();

    if (ret < 0) {

        error_report("Error %d while loading VM state", ret);

        return ret;

    }

    return 0;

}


build_fadt(GArray *table_data, GArray *linker, AcpiPmInfo *pm,

           unsigned facs, unsigned dsdt,

           const char *oem_id, const char *oem_table_id)

{

    AcpiFadtDescriptorRev1 *fadt = acpi_data_push(table_data, sizeof(*fadt));

    fadt->firmware_ctrl = cpu_to_le32(facs);

    /* FACS address to be filled by Guest linker */

    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,

                                   ACPI_BUILD_TABLE_FILE,

                                   table_data, &fadt->firmware_ctrl,

                                   sizeof fadt->firmware_ctrl);

    fadt->dsdt = cpu_to_le32(dsdt);

    /* DSDT address to be filled by Guest linker */

    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,

                                   ACPI_BUILD_TABLE_FILE,

                                   table_data, &fadt->dsdt,

                                   sizeof fadt->dsdt);

    fadt_setup(fadt, pm);

    build_header(linker, table_data,

                 (void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);

}


static void test_visitor_in_bool(TestInputVisitorData *data,

                                 const void *unused)

{

    bool res = false;

    Visitor *v;

    v = visitor_input_test_init(data, "true");

    visit_type_bool(v, NULL, &res, &error_abort);

    g_assert_cmpint(res, ==, true);

}


static void e500plat_init(QEMUMachineInitArgs *args)

{

    ram_addr_t ram_size = args->ram_size;

    const char *boot_device = args->boot_device;

    const char *cpu_model = args->cpu_model;

    const char *kernel_filename = args->kernel_filename;

    const char *kernel_cmdline = args->kernel_cmdline;

    const char *initrd_filename = args->initrd_filename;

    PPCE500Params params = {

        .ram_size = ram_size,

        .boot_device = boot_device,

        .kernel_filename = kernel_filename,

        .kernel_cmdline = kernel_cmdline,

        .initrd_filename = initrd_filename,

        .cpu_model = cpu_model,

        .pci_first_slot = 0x11,

        .pci_nr_slots = 2,

        .fixup_devtree = e500plat_fixup_devtree,

    };

    ppce500_init(&params);

}


static void gdb_read_byte(GDBState *s, int ch)

{

    CPUState *env = s->env;

    int i, csum;

    uint8_t reply;

#ifndef CONFIG_USER_ONLY

    if (s->last_packet_len) {

        /* Waiting for a response to the last packet.  If we see the start

           of a new command then abandon the previous response.  */

        if (ch == '-') {

#ifdef DEBUG_GDB

            printf("Got NACK, retransmitting\n");

#endif

            put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);

        }

#ifdef DEBUG_GDB

        else if (ch == '+')

            printf("Got ACK\n");

        else

            printf("Got '%c' when expecting ACK/NACK\n", ch);

#endif

        if (ch == '+' || ch == '$')

            s->last_packet_len = 0;

        if (ch != '$')

            return;

    }

    if (vm_running) {

        /* when the CPU is running, we cannot do anything except stop

           it when receiving a char */

        vm_stop(EXCP_INTERRUPT);

    } else

#endif

    {

        switch(s->state) {

        case RS_IDLE:

            if (ch == '$') {

                s->line_buf_index = 0;

                s->state = RS_GETLINE;

            }

            break;

        case RS_GETLINE:

            if (ch == '#') {

            s->state = RS_CHKSUM1;

            } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {

                s->state = RS_IDLE;

            } else {

            s->line_buf[s->line_buf_index++] = ch;

            }

            break;

        case RS_CHKSUM1:

            s->line_buf[s->line_buf_index] = '\0';

            s->line_csum = fromhex(ch) << 4;

            s->state = RS_CHKSUM2;

            break;

        case RS_CHKSUM2:

            s->line_csum |= fromhex(ch);

            csum = 0;

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

                csum += s->line_buf[i];

            }

            if (s->line_csum != (csum & 0xff)) {

                reply = '-';

                put_buffer(s, &reply, 1);

                s->state = RS_IDLE;

            } else {

                reply = '+';

                put_buffer(s, &reply, 1);

                s->state = gdb_handle_packet(s, env, s->line_buf);

            }

            break;

        default:

            abort();

        }

    }

}


int ff_hevc_decode_nal_pps(HEVCContext *s)

{

    GetBitContext *gb = &s->HEVClc->gb;

    HEVCSPS      *sps = NULL;

    int pic_area_in_ctbs;

    int log2_diff_ctb_min_tb_size;

    int i, j, x, y, ctb_addr_rs, tile_id;

    int ret = 0;

    unsigned int pps_id = 0;

    AVBufferRef *pps_buf;

    HEVCPPS *pps = av_mallocz(sizeof(*pps));

    if (!pps)

        return AVERROR(ENOMEM);

    pps_buf = av_buffer_create((uint8_t *)pps, sizeof(*pps),

                               hevc_pps_free, NULL, 0);

    if (!pps_buf) {

        av_freep(&pps);

        return AVERROR(ENOMEM);

    }

    av_log(s->avctx, AV_LOG_DEBUG, "Decoding PPS\n");

    // Default values

    pps->loop_filter_across_tiles_enabled_flag = 1;

    pps->num_tile_columns                      = 1;

    pps->num_tile_rows                         = 1;

    pps->uniform_spacing_flag                  = 1;

    pps->disable_dbf                           = 0;

    pps->beta_offset                           = 0;

    pps->tc_offset                             = 0;

    pps->log2_max_transform_skip_block_size    = 2;

    // Coded parameters

    pps_id = get_ue_golomb_long(gb);

    if (pps_id >= MAX_PPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "PPS id out of range: %d\n", pps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->sps_id = get_ue_golomb_long(gb);

    if (pps->sps_id >= MAX_SPS_COUNT) {

        av_log(s->avctx, AV_LOG_ERROR, "SPS id out of range: %d\n", pps->sps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    if (!s->sps_list[pps->sps_id]) {

        av_log(s->avctx, AV_LOG_ERROR, "SPS %u does not exist.\n", pps->sps_id);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    sps = (HEVCSPS *)s->sps_list[pps->sps_id]->data;

    pps->dependent_slice_segments_enabled_flag = get_bits1(gb);

    pps->output_flag_present_flag              = get_bits1(gb);

    pps->num_extra_slice_header_bits           = get_bits(gb, 3);

    pps->sign_data_hiding_flag = get_bits1(gb);

    pps->cabac_init_present_flag = get_bits1(gb);

    pps->num_ref_idx_l0_default_active = get_ue_golomb_long(gb) + 1;

    pps->num_ref_idx_l1_default_active = get_ue_golomb_long(gb) + 1;

    pps->pic_init_qp_minus26 = get_se_golomb(gb);

    pps->constrained_intra_pred_flag = get_bits1(gb);

    pps->transform_skip_enabled_flag = get_bits1(gb);

    pps->cu_qp_delta_enabled_flag = get_bits1(gb);

    pps->diff_cu_qp_delta_depth   = 0;

    if (pps->cu_qp_delta_enabled_flag)

        pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb);

    pps->cb_qp_offset = get_se_golomb(gb);

    if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) {

        av_log(s->avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n",

               pps->cb_qp_offset);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->cr_qp_offset = get_se_golomb(gb);

    if (pps->cr_qp_offset < -12 || pps->cr_qp_offset > 12) {

        av_log(s->avctx, AV_LOG_ERROR, "pps_cr_qp_offset out of range: %d\n",

               pps->cr_qp_offset);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->pic_slice_level_chroma_qp_offsets_present_flag = get_bits1(gb);

    pps->weighted_pred_flag   = get_bits1(gb);

    pps->weighted_bipred_flag = get_bits1(gb);

    pps->transquant_bypass_enable_flag    = get_bits1(gb);

    pps->tiles_enabled_flag               = get_bits1(gb);

    pps->entropy_coding_sync_enabled_flag = get_bits1(gb);

    if (pps->tiles_enabled_flag) {

        pps->num_tile_columns = get_ue_golomb_long(gb) + 1;

        pps->num_tile_rows    = get_ue_golomb_long(gb) + 1;

        if (pps->num_tile_columns == 0 ||

            pps->num_tile_columns >= sps->width) {

            av_log(s->avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n",

                   pps->num_tile_columns - 1);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        if (pps->num_tile_rows == 0 ||

            pps->num_tile_rows >= sps->height) {

            av_log(s->avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n",

                   pps->num_tile_rows - 1);

            ret = AVERROR_INVALIDDATA;

            goto err;

        }

        pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));

        pps->row_height   = av_malloc_array(pps->num_tile_rows,    sizeof(*pps->row_height));

        if (!pps->column_width || !pps->row_height) {

            ret = AVERROR(ENOMEM);

            goto err;

        }

        pps->uniform_spacing_flag = get_bits1(gb);

        if (!pps->uniform_spacing_flag) {

            uint64_t sum = 0;

            for (i = 0; i < pps->num_tile_columns - 1; i++) {

                pps->column_width[i] = get_ue_golomb_long(gb) + 1;

                sum                 += pps->column_width[i];

            }

            if (sum >= sps->ctb_width) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid tile widths.\n");

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            pps->column_width[pps->num_tile_columns - 1] = sps->ctb_width - sum;

            sum = 0;

            for (i = 0; i < pps->num_tile_rows - 1; i++) {

                pps->row_height[i] = get_ue_golomb_long(gb) + 1;

                sum               += pps->row_height[i];

            }

            if (sum >= sps->ctb_height) {

                av_log(s->avctx, AV_LOG_ERROR, "Invalid tile heights.\n");

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            pps->row_height[pps->num_tile_rows - 1] = sps->ctb_height - sum;

        }

        pps->loop_filter_across_tiles_enabled_flag = get_bits1(gb);

    }

    pps->seq_loop_filter_across_slices_enabled_flag = get_bits1(gb);

    pps->deblocking_filter_control_present_flag = get_bits1(gb);

    if (pps->deblocking_filter_control_present_flag) {

        pps->deblocking_filter_override_enabled_flag = get_bits1(gb);

        pps->disable_dbf                             = get_bits1(gb);

        if (!pps->disable_dbf) {

            pps->beta_offset = get_se_golomb(gb) * 2;

            pps->tc_offset = get_se_golomb(gb) * 2;

            if (pps->beta_offset/2 < -6 || pps->beta_offset/2 > 6) {

                av_log(s->avctx, AV_LOG_ERROR, "pps_beta_offset_div2 out of range: %d\n",

                       pps->beta_offset/2);

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

            if (pps->tc_offset/2 < -6 || pps->tc_offset/2 > 6) {

                av_log(s->avctx, AV_LOG_ERROR, "pps_tc_offset_div2 out of range: %d\n",

                       pps->tc_offset/2);

                ret = AVERROR_INVALIDDATA;

                goto err;

            }

        }

    }

    pps->scaling_list_data_present_flag = get_bits1(gb);

    if (pps->scaling_list_data_present_flag) {

        set_default_scaling_list_data(&pps->scaling_list);

        ret = scaling_list_data(s, &pps->scaling_list, sps);

        if (ret < 0)

            goto err;

    }

    pps->lists_modification_present_flag = get_bits1(gb);

    pps->log2_parallel_merge_level       = get_ue_golomb_long(gb) + 2;

    if (pps->log2_parallel_merge_level > sps->log2_ctb_size) {

        av_log(s->avctx, AV_LOG_ERROR, "log2_parallel_merge_level_minus2 out of range: %d\n",

               pps->log2_parallel_merge_level - 2);

        ret = AVERROR_INVALIDDATA;

        goto err;

    }

    pps->slice_header_extension_present_flag = get_bits1(gb);

    if (get_bits1(gb)) { // pps_extension_present_flag

        int pps_range_extensions_flag = get_bits1(gb);

        /* int pps_extension_7bits = */ get_bits(gb, 7);

        if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) {

            pps_range_extensions(s, pps, sps);

        }

    }

    // Inferred parameters

    pps->col_bd   = av_malloc_array(pps->num_tile_columns + 1, sizeof(*pps->col_bd));

    pps->row_bd   = av_malloc_array(pps->num_tile_rows + 1,    sizeof(*pps->row_bd));

    pps->col_idxX = av_malloc_array(sps->ctb_width,    sizeof(*pps->col_idxX));

    if (!pps->col_bd || !pps->row_bd || !pps->col_idxX) {

        ret = AVERROR(ENOMEM);

        goto err;

    }

    if (pps->uniform_spacing_flag) {

        if (!pps->column_width) {

            pps->column_width = av_malloc_array(pps->num_tile_columns, sizeof(*pps->column_width));

            pps->row_height   = av_malloc_array(pps->num_tile_rows,    sizeof(*pps->row_height));

        }

        if (!pps->column_width || !pps->row_height) {

            ret = AVERROR(ENOMEM);

            goto err;

        }

        for (i = 0; i < pps->num_tile_columns; i++) {

            pps->column_width[i] = ((i + 1) * sps->ctb_width) / pps->num_tile_columns -

                                   (i * sps->ctb_width) / pps->num_tile_columns;

        }

        for (i = 0; i < pps->num_tile_rows; i++) {

            pps->row_height[i] = ((i + 1) * sps->ctb_height) / pps->num_tile_rows -

                                 (i * sps->ctb_height) / pps->num_tile_rows;

        }

    }

    pps->col_bd[0] = 0;

    for (i = 0; i < pps->num_tile_columns; i++)

        pps->col_bd[i + 1] = pps->col_bd[i] + pps->column_width[i];

    pps->row_bd[0] = 0;

    for (i = 0; i < pps->num_tile_rows; i++)

        pps->row_bd[i + 1] = pps->row_bd[i] + pps->row_height[i];

    for (i = 0, j = 0; i < sps->ctb_width; i++) {

        if (i > pps->col_bd[j])

            j++;

        pps->col_idxX[i] = j;

    }

    /**

     * 6.5

     */

    pic_area_in_ctbs     = sps->ctb_width    * sps->ctb_height;

    pps->ctb_addr_rs_to_ts = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->ctb_addr_rs_to_ts));

    pps->ctb_addr_ts_to_rs = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->ctb_addr_ts_to_rs));

    pps->tile_id           = av_malloc_array(pic_area_in_ctbs,    sizeof(*pps->tile_id));

    pps->min_tb_addr_zs_tab = av_malloc_array((sps->tb_mask+2) * (sps->tb_mask+2), sizeof(*pps->min_tb_addr_zs_tab));

    if (!pps->ctb_addr_rs_to_ts || !pps->ctb_addr_ts_to_rs ||

        !pps->tile_id || !pps->min_tb_addr_zs_tab) {

        ret = AVERROR(ENOMEM);

        goto err;

    }

    for (ctb_addr_rs = 0; ctb_addr_rs < pic_area_in_ctbs; ctb_addr_rs++) {

        int tb_x   = ctb_addr_rs % sps->ctb_width;

        int tb_y   = ctb_addr_rs / sps->ctb_width;

        int tile_x = 0;

        int tile_y = 0;

        int val    = 0;

        for (i = 0; i < pps->num_tile_columns; i++) {

            if (tb_x < pps->col_bd[i + 1]) {

                tile_x = i;

                break;

            }

        }

        for (i = 0; i < pps->num_tile_rows; i++) {

            if (tb_y < pps->row_bd[i + 1]) {

                tile_y = i;

                break;

            }

        }

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

            val += pps->row_height[tile_y] * pps->column_width[i];

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

            val += sps->ctb_width * pps->row_height[i];

        val += (tb_y - pps->row_bd[tile_y]) * pps->column_width[tile_x] +

               tb_x - pps->col_bd[tile_x];

        pps->ctb_addr_rs_to_ts[ctb_addr_rs] = val;

        pps->ctb_addr_ts_to_rs[val]         = ctb_addr_rs;

    }

    for (j = 0, tile_id = 0; j < pps->num_tile_rows; j++)

        for (i = 0; i < pps->num_tile_columns; i++, tile_id++)

            for (y = pps->row_bd[j]; y < pps->row_bd[j + 1]; y++)

                for (x = pps->col_bd[i]; x < pps->col_bd[i + 1]; x++)

                    pps->tile_id[pps->ctb_addr_rs_to_ts[y * sps->ctb_width + x]] = tile_id;

    pps->tile_pos_rs = av_malloc_array(tile_id, sizeof(*pps->tile_pos_rs));

    if (!pps->tile_pos_rs) {

        ret = AVERROR(ENOMEM);

        goto err;

    }

    for (j = 0; j < pps->num_tile_rows; j++)

        for (i = 0; i < pps->num_tile_columns; i++)

            pps->tile_pos_rs[j * pps->num_tile_columns + i] = pps->row_bd[j] * sps->ctb_width + pps->col_bd[i];

    log2_diff_ctb_min_tb_size = sps->log2_ctb_size - sps->log2_min_tb_size;

    pps->min_tb_addr_zs = &pps->min_tb_addr_zs_tab[1*(sps->tb_mask+2)+1];

    for (y = 0; y < sps->tb_mask+2; y++) {

        pps->min_tb_addr_zs_tab[y*(sps->tb_mask+2)] = -1;

        pps->min_tb_addr_zs_tab[y]    = -1;

    }

    for (y = 0; y < sps->tb_mask+1; y++) {

        for (x = 0; x < sps->tb_mask+1; x++) {

            int tb_x        = x >> log2_diff_ctb_min_tb_size;

            int tb_y        = y >> log2_diff_ctb_min_tb_size;

            int ctb_addr_rs = sps->ctb_width * tb_y + tb_x;

            int val         = pps->ctb_addr_rs_to_ts[ctb_addr_rs] <<

                              (log2_diff_ctb_min_tb_size * 2);

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

                int m = 1 << i;

                val += (m & x ? m * m : 0) + (m & y ? 2 * m * m : 0);

            }

            pps->min_tb_addr_zs[y * (sps->tb_mask+2) + x] = val;

        }

    }

    if (get_bits_left(gb) < 0) {

        av_log(s->avctx, AV_LOG_ERROR,

               "Overread PPS by %d bits\n", -get_bits_left(gb));

        goto err;

    }

    av_buffer_unref(&s->pps_list[pps_id]);

    s->pps_list[pps_id] = pps_buf;

    return 0;

err:

    av_buffer_unref(&pps_buf);

    return ret;

}


static void ide_drive_pre_save(void *opaque)

{

    IDEState *s = opaque;

    s->cur_io_buffer_len = 0;

    if (!(s->status & DRQ_STAT))

        return;

    s->cur_io_buffer_offset = s->data_ptr - s->io_buffer;

    s->cur_io_buffer_len = s->data_end - s->data_ptr;

    s->end_transfer_fn_idx = transfer_end_table_idx(s->end_transfer_func);

    if (s->end_transfer_fn_idx == -1) {

        fprintf(stderr, "%s: invalid end_transfer_func for DRQ_STAT\n",

                        __func__);

        s->end_transfer_fn_idx = 2;

    }

}


static int gdb_breakpoint_remove(CPUState *env, target_ulong addr,

                                 target_ulong len, int type)

{

    switch (type) {

    case GDB_BREAKPOINT_SW:

    case GDB_BREAKPOINT_HW:

        return cpu_breakpoint_remove(env, addr, BP_GDB);

#ifndef CONFIG_USER_ONLY

    case GDB_WATCHPOINT_WRITE:

    case GDB_WATCHPOINT_READ:

    case GDB_WATCHPOINT_ACCESS:

        return cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);

#endif

    default:

        return -ENOSYS;

    }

}


static int unin_main_pci_host_init(PCIDevice *d)

{

    pci_config_set_vendor_id(d->config, PCI_VENDOR_ID_APPLE);

    pci_config_set_device_id(d->config, PCI_DEVICE_ID_APPLE_UNI_N_PCI);

    d->config[0x08] = 0x00; // revision

    pci_config_set_class(d->config, PCI_CLASS_BRIDGE_HOST);

    d->config[0x0C] = 0x08; // cache_line_size

    d->config[0x0D] = 0x10; // latency_timer

    d->config[0x34] = 0x00; // capabilities_pointer

    return 0;

}


VirtIODevice *virtio_serial_init(DeviceState *dev, uint32_t max_nr_ports)

{

    VirtIOSerial *vser;

    VirtIODevice *vdev;

    uint32_t i;

    if (!max_nr_ports)

        return NULL;

    vdev = virtio_common_init("virtio-serial", VIRTIO_ID_CONSOLE,

                              sizeof(struct virtio_console_config),

                              sizeof(VirtIOSerial));

    vser = DO_UPCAST(VirtIOSerial, vdev, vdev);

    /* Spawn a new virtio-serial bus on which the ports will ride as devices */

    vser->bus = virtser_bus_new(dev);

    vser->bus->vser = vser;

    QTAILQ_INIT(&vser->ports);

    vser->bus->max_nr_ports = max_nr_ports;

    vser->ivqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));

    vser->ovqs = qemu_malloc(max_nr_ports * sizeof(VirtQueue *));

    /* Add a queue for host to guest transfers for port 0 (backward compat) */

    vser->ivqs[0] = virtio_add_queue(vdev, 128, handle_input);

    /* Add a queue for guest to host transfers for port 0 (backward compat) */

    vser->ovqs[0] = virtio_add_queue(vdev, 128, handle_output);

    /* control queue: host to guest */

    vser->c_ivq = virtio_add_queue(vdev, 16, control_in);

    /* control queue: guest to host */

    vser->c_ovq = virtio_add_queue(vdev, 16, control_out);

    for (i = 1; i < vser->bus->max_nr_ports; i++) {

        /* Add a per-port queue for host to guest transfers */

        vser->ivqs[i] = virtio_add_queue(vdev, 128, handle_input);

        /* Add a per-per queue for guest to host transfers */

        vser->ovqs[i] = virtio_add_queue(vdev, 128, handle_output);

    }

    vser->config.max_nr_ports = max_nr_ports;

    vser->ports_map = qemu_mallocz(((max_nr_ports + 31) / 32)

        * sizeof(vser->ports_map[0]));

    /*

     * Reserve location 0 for a console port for backward compat

     * (old kernel, new qemu)

     */

    mark_port_added(vser, 0);

    vser->vdev.get_features = get_features;

    vser->vdev.get_config = get_config;

    vser->vdev.set_config = set_config;

    /*

     * Register for the savevm section with the virtio-console name

     * to preserve backward compat

     */

    register_savevm(dev, "virtio-console", -1, 2, virtio_serial_save,

                    virtio_serial_load, vser);

    return vdev;

}


static void pci_vpb_map(SysBusDevice *dev, target_phys_addr_t base)

{

    PCIVPBState *s = (PCIVPBState *)dev;

    /* Selfconfig area.  */

    memory_region_add_subregion(get_system_memory(), base + 0x01000000,

                                &s->mem_config);

    /* Normal config area.  */

    memory_region_add_subregion(get_system_memory(), base + 0x02000000,

                                &s->mem_config2);

    if (s->realview) {

        /* IO memory area.  */

        memory_region_add_subregion(get_system_memory(), base + 0x03000000,

                                    &s->isa);

    }

}


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

                                   size_t size, Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

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

    Error *err = NULL;

    if (obj) {

        *obj = NULL;

    }

    if (!qobj) {

        return;

    }

    if (qobject_type(qobj) != QTYPE_QDICT) {

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

                   "QDict");

        return;

    }

    qmp_input_push(qiv, qobj, obj, &err);

    if (err) {

        error_propagate(errp, err);

        return;

    }

    if (obj) {

        *obj = g_malloc0(size);

    }

}


static int read_packet(ByteIOContext *pb, uint8_t *buf, int raw_packet_size)

{

    int skip, len;

    for(;;) {

        len = get_buffer(pb, buf, TS_PACKET_SIZE);

        if (len != TS_PACKET_SIZE)

            return AVERROR(EIO);

        /* check paquet sync byte */

        if (buf[0] != 0x47) {

            /* find a new packet start */

            url_fseek(pb, -TS_PACKET_SIZE, SEEK_CUR);

            if (mpegts_resync(pb) < 0)

                return AVERROR_INVALIDDATA;

            else

                continue;

        } else {

            skip = raw_packet_size - TS_PACKET_SIZE;

            if (skip > 0)

                url_fskip(pb, skip);

            break;

        }

    }

    return 0;

}


av_cold void ff_fft_init_arm(FFTContext *s)

{

    if (HAVE_NEON) {

        s->fft_permute  = ff_fft_permute_neon;

        s->fft_calc     = ff_fft_calc_neon;

        s->imdct_calc   = ff_imdct_calc_neon;

        s->imdct_half   = ff_imdct_half_neon;

        s->mdct_calc    = ff_mdct_calc_neon;

        s->permutation  = FF_MDCT_PERM_INTERLEAVE;

    }

}


static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,

                                      int nb_sectors, QEMUIOVector *iov,

                                      bool is_write)

{

    CoroutineIOCompletion co = {

        .coroutine = qemu_coroutine_self(),

    };

    BlockDriverAIOCB *acb;

    if (is_write) {

        acb = bdrv_aio_writev(bs, sector_num, iov, nb_sectors,

                              bdrv_co_io_em_complete, &co);

    } else {

        acb = bdrv_aio_readv(bs, sector_num, iov, nb_sectors,

                             bdrv_co_io_em_complete, &co);

    }

    trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);

    if (!acb) {

        return -EIO;

    }

    qemu_coroutine_yield();

    return co.ret;

}


static void v9fs_getlock(void *opaque)

{

    size_t offset = 7;

    struct stat stbuf;

    V9fsFidState *fidp;

    V9fsGetlock *glock;

    int32_t fid, err = 0;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    glock = g_malloc(sizeof(*glock));

    pdu_unmarshal(pdu, offset, "dbqqds", &fid, &glock->type,

                  &glock->start, &glock->length, &glock->proc_id,

                  &glock->client_id);

    trace_v9fs_getlock(pdu->tag, pdu->id, fid,

                       glock->type, glock->start, glock->length);

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        err = -ENOENT;

        goto out_nofid;

    }

    err = v9fs_co_fstat(pdu, fidp, &stbuf);

    if (err < 0) {

        goto out;

    }

    glock->type = P9_LOCK_TYPE_UNLCK;

    offset += pdu_marshal(pdu, offset, "bqqds", glock->type,

                          glock->start, glock->length, glock->proc_id,

                          &glock->client_id);

    err = offset;

    trace_v9fs_getlock_return(pdu->tag, pdu->id, glock->type, glock->start,

                              glock->length, glock->proc_id);

out:

    put_fid(pdu, fidp);

out_nofid:

    complete_pdu(s, pdu, err);

    v9fs_string_free(&glock->client_id);

    g_free(glock);

}


void stb_phys(target_phys_addr_t addr, uint32_t val)

{

    uint8_t v = val;

    cpu_physical_memory_write(addr, &v, 1);

}


void error_set(Error **errp, const char *fmt, ...)

{

    Error *err;

    va_list ap;

    if (errp == NULL) {

        return;

    }

    assert(*errp == NULL);

    err = g_malloc0(sizeof(*err));

    va_start(ap, fmt);

    err->obj = qobject_to_qdict(qobject_from_jsonv(fmt, &ap));

    va_end(ap);

    err->msg = qerror_format(fmt, err->obj);

    *errp = err;

}


static void term_handle_command(const char *cmdline)

{

    const char *p, *pstart, *typestr;

    char *q;

    int c, nb_args, len, i, has_arg;

    term_cmd_t *cmd;

    char cmdname[256];

    char buf[1024];

    void *str_allocated[MAX_ARGS];

    void *args[MAX_ARGS];

#ifdef DEBUG

    term_printf("command='%s'\n", cmdline);

#endif

    /* extract the command name */

    p = cmdline;

    q = cmdname;

    while (isspace(*p))

        p++;

    if (*p == '\0')

        return;

    pstart = p;

    while (*p != '\0' && *p != '/' && !isspace(*p))

        p++;

    len = p - pstart;

    if (len > sizeof(cmdname) - 1)

        len = sizeof(cmdname) - 1;

    memcpy(cmdname, pstart, len);

    cmdname[len] = '\0';

    /* find the command */

    for(cmd = term_cmds; cmd->name != NULL; cmd++) {

        if (compare_cmd(cmdname, cmd->name))

            goto found;

    }

    term_printf("unknown command: '%s'\n", cmdname);

    return;

 found:

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

        str_allocated[i] = NULL;

    /* parse the parameters */

    typestr = cmd->args_type;

    nb_args = 0;

    for(;;) {

        c = *typestr;

        if (c == '\0')

            break;

        typestr++;

        switch(c) {

        case 'F':

        case 'B':

        case 's':

            {

                int ret;

                char *str;

                while (isspace(*p))

                    p++;

                if (*typestr == '?') {

                    typestr++;

                    if (*p == '\0') {

                        /* no optional string: NULL argument */

                        str = NULL;

                        goto add_str;

                    }

                }

                ret = get_str(buf, sizeof(buf), &p);

                if (ret < 0) {

                    switch(c) {

                    case 'F':

                        term_printf("%s: filename expected\n", cmdname);

                        break;

                    case 'B':

                        term_printf("%s: block device name expected\n", cmdname);

                        break;

                    default:

                        term_printf("%s: string expected\n", cmdname);

                        break;

                    }

                    goto fail;

                }

                str = qemu_malloc(strlen(buf) + 1);

                strcpy(str, buf);

                str_allocated[nb_args] = str;

            add_str:

                if (nb_args >= MAX_ARGS) {

                error_args:

                    term_printf("%s: too many arguments\n", cmdname);

                    goto fail;

                }

                args[nb_args++] = str;

            }

            break;

        case '/':

            {

                int count, format, size;

                while (isspace(*p))

                    p++;

                if (*p == '/') {

                    /* format found */

                    p++;

                    count = 1;

                    if (isdigit(*p)) {

                        count = 0;

                        while (isdigit(*p)) {

                            count = count * 10 + (*p - '0');

                            p++;

                        }

                    }

                    size = -1;

                    format = -1;

                    for(;;) {

                        switch(*p) {

                        case 'o':

                        case 'd':

                        case 'u':

                        case 'x':

                        case 'i':

                        case 'c':

                            format = *p++;

                            break;

                        case 'b':

                            size = 1;

                            p++;

                            break;

                        case 'h':

                            size = 2;

                            p++;

                            break;

                        case 'w':

                            size = 4;

                            p++;

                            break;

                        case 'g':

                        case 'L':

                            size = 8;

                            p++;

                            break;

                        default:

                            goto next;

                        }

                    }

                next:

                    if (*p != '\0' && !isspace(*p)) {

                        term_printf("invalid char in format: '%c'\n", *p);

                        goto fail;

                    }

                    if (format < 0)

                        format = default_fmt_format;

                    if (format != 'i') {

                        /* for 'i', not specifying a size gives -1 as size */

                        if (size < 0)

                            size = default_fmt_size;

                    }

                    default_fmt_size = size;

                    default_fmt_format = format;

                } else {

                    count = 1;

                    format = default_fmt_format;

                    if (format != 'i') {

                        size = default_fmt_size;

                    } else {

                        size = -1;

                    }

                }

                if (nb_args + 3 > MAX_ARGS)

                    goto error_args;

                args[nb_args++] = (void*)count;

                args[nb_args++] = (void*)format;

                args[nb_args++] = (void*)size;

            }

            break;

        case 'i':

            {

                int val;

                while (isspace(*p))

                    p++;

                if (*typestr == '?' || *typestr == '.') {

                    typestr++;

                    if (*typestr == '?') {

                        if (*p == '\0')

                            has_arg = 0;

                        else

                            has_arg = 1;

                    } else {

                        if (*p == '.') {

                            p++;

                            while (isspace(*p))

                                p++;

                            has_arg = 1;

                        } else {

                            has_arg = 0;

                        }

                    }

                    if (nb_args >= MAX_ARGS)

                        goto error_args;

                    args[nb_args++] = (void *)has_arg;

                    if (!has_arg) {

                        if (nb_args >= MAX_ARGS)

                            goto error_args;

                        val = -1;

                        goto add_num;

                    }

                }

                if (get_expr(&val, &p))

                    goto fail;

            add_num:

                if (nb_args >= MAX_ARGS)

                    goto error_args;

                args[nb_args++] = (void *)val;

            }

            break;

        case '-':

            {

                int has_option;

                /* option */

                c = *typestr++;

                if (c == '\0')

                    goto bad_type;

                while (isspace(*p))

                    p++;

                has_option = 0;

                if (*p == '-') {

                    p++;

                    if (*p != c) {

                        term_printf("%s: unsupported option -%c\n",

                                    cmdname, *p);

                        goto fail;

                    }

                    p++;

                    has_option = 1;

                }

                if (nb_args >= MAX_ARGS)

                    goto error_args;

                args[nb_args++] = (void *)has_option;

            }

            break;

        default:

        bad_type:

            term_printf("%s: unknown type '%c'\n", cmdname, c);

            goto fail;

        }

    }

    /* check that all arguments were parsed */

    while (isspace(*p))

        p++;

    if (*p != '\0') {

        term_printf("%s: extraneous characters at the end of line\n",

                    cmdname);

        goto fail;

    }

    switch(nb_args) {

    case 0:

        cmd->handler();

        break;

    case 1:

        cmd->handler(args[0]);

        break;

    case 2:

        cmd->handler(args[0], args[1]);

        break;

    case 3:

        cmd->handler(args[0], args[1], args[2]);

        break;

    case 4:

        cmd->handler(args[0], args[1], args[2], args[3]);

        break;

    case 5:

        cmd->handler(args[0], args[1], args[2], args[3], args[4]);

        break;

    case 6:

        cmd->handler(args[0], args[1], args[2], args[3], args[4], args[5]);

        break;

    default:

        term_printf("unsupported number of arguments: %d\n", nb_args);

        goto fail;

    }

 fail:

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

        qemu_free(str_allocated[i]);

    return;

}


static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)

{

    gen_mov_reg_Z(cpu_tmp0, src);

    gen_mov_reg_C(dst, src);

    tcg_gen_or_tl(dst, dst, cpu_tmp0);

}


static void usb_host_auto_check(void *unused)

{

    struct USBHostDevice *s;

    int unconnected = 0;

    usb_host_scan(NULL, usb_host_auto_scan);

    QTAILQ_FOREACH(s, &hostdevs, next) {

        if (s->fd == -1) {

            unconnected++;

        }

    }

    if (unconnected == 0) {

        /* nothing to watch */

        if (usb_auto_timer) {

            qemu_del_timer(usb_auto_timer);

        }

        return;

    }

    if (!usb_auto_timer) {

        usb_auto_timer = qemu_new_timer(rt_clock, usb_host_auto_check, NULL);

        if (!usb_auto_timer) {

            return;

        }

    }

    qemu_mod_timer(usb_auto_timer, qemu_get_clock(rt_clock) + 2000);

}


int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transform, int ilv){

    int i, t = 0;

    uint8_t *zero, *last, *cur;

    JLSState *state;

    int off = 0, stride = 1, width, shift;

    zero = av_mallocz(s->picture.linesize[0]);

    last = zero;

    cur = s->picture.data[0];

    state = av_mallocz(sizeof(JLSState));

    /* initialize JPEG-LS state from JPEG parameters */

    state->near = near;

    state->bpp = (s->bits < 2) ? 2 : s->bits;

    state->maxval = s->maxval;

    state->T1 = s->t1;

    state->T2 = s->t2;

    state->T3 = s->t3;

    state->reset = s->reset;

    ff_jpegls_reset_coding_parameters(state, 0);

    ff_jpegls_init_state(state);

    if(s->bits <= 8)

        shift = point_transform + (8 - s->bits);

    else

        shift = point_transform + (16 - s->bits);

    if (s->avctx->debug & FF_DEBUG_PICT_INFO) {

        av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",

                s->width, s->height, state->near, state->maxval,

                state->T1, state->T2, state->T3,

                state->reset, state->limit, state->qbpp, state->range);

        av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n",

                ilv, point_transform, s->bits, s->cur_scan);

    }

    if(ilv == 0) { /* separate planes */

        stride = (s->nb_components > 1) ? 3 : 1;

        off = av_clip(s->cur_scan - 1, 0, stride);

        width = s->width * stride;

        cur += off;

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

            if(s->bits <= 8){

                ls_decode_line(state, s, last, cur, t, width, stride, off,  8);

                t = last[0];

            }else{

                ls_decode_line(state, s, last, cur, t, width, stride, off, 16);

                t = *((uint16_t*)last);

            }

            last = cur;

            cur += s->picture.linesize[0];

            if (s->restart_interval && !--s->restart_count) {

                align_get_bits(&s->gb);

                skip_bits(&s->gb, 16); /* skip RSTn */

            }

        }

    } else if(ilv == 1) { /* line interleaving */

        int j;

        int Rc[3] = {0, 0, 0};

        stride = (s->nb_components > 1) ? 3 : 1;

        memset(cur, 0, s->picture.linesize[0]);

        width = s->width * stride;

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

            for(j = 0; j < stride; j++) {

                ls_decode_line(state, s, last + j, cur + j, Rc[j], width, stride, j, 8);

                Rc[j] = last[j];

                if (s->restart_interval && !--s->restart_count) {

                    align_get_bits(&s->gb);

                    skip_bits(&s->gb, 16); /* skip RSTn */

                }

            }

            last = cur;

            cur += s->picture.linesize[0];

        }

    } else if(ilv == 2) { /* sample interleaving */

        av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n");

        av_free(state);

        av_free(zero);

        return -1;

    }

    if(shift){ /* we need to do point transform or normalize samples */

        int x, w;

        w = s->width * s->nb_components;

        if(s->bits <= 8){

            uint8_t *src = s->picture.data[0];

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

                for(x = off; x < w; x+= stride){

                    src[x] <<= shift;

                }

                src += s->picture.linesize[0];

            }

        }else{

            uint16_t *src = (uint16_t*) s->picture.data[0];

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

                for(x = 0; x < w; x++){

                    src[x] <<= shift;

                }

                src += s->picture.linesize[0]/2;

            }

        }

    }

    av_free(state);

    av_free(zero);

    return 0;

}


void tcg_gen_brcondi_i32(TCGCond cond, TCGv_i32 arg1, int32_t arg2, int label)

{

    TCGv_i32 t0 = tcg_const_i32(arg2);

    tcg_gen_brcond_i32(cond, arg1, t0, label);

    tcg_temp_free_i32(t0);

}


void s390x_cpu_do_unaligned_access(CPUState *cs, vaddr addr,

                                   MMUAccessType access_type,

                                   int mmu_idx, uintptr_t retaddr)

{

    S390CPU *cpu = S390_CPU(cs);

    CPUS390XState *env = &cpu->env;

    if (retaddr) {

        cpu_restore_state(cs, retaddr);

    }

    program_interrupt(env, PGM_SPECIFICATION, ILEN_LATER);

}


static void q35_host_get_pci_hole_start(Object *obj, Visitor *v,

                                        const char *name, void *opaque,

                                        Error **errp)

{

    Q35PCIHost *s = Q35_HOST_DEVICE(obj);

    uint32_t value = s->mch.pci_hole.begin;

    visit_type_uint32(v, name, &value, errp);

}


static int kvm_max_vcpus(KVMState *s)

{

    int ret;

    /* Find number of supported CPUs using the recommended

     * procedure from the kernel API documentation to cope with

     * older kernels that may be missing capabilities.

     */

    ret = kvm_check_extension(s, KVM_CAP_MAX_VCPUS);

    if (ret) {

        return ret;

    }

    ret = kvm_check_extension(s, KVM_CAP_NR_VCPUS);

    if (ret) {

        return ret;

    }

    return 4;

}


static int cpu_load_old(QEMUFile *f, void *opaque, int version_id)

{

    PowerPCCPU *cpu = opaque;

    CPUPPCState *env = &cpu->env;

    unsigned int i, j;

    target_ulong sdr1;

    uint32_t fpscr;

    target_ulong xer;

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

        qemu_get_betls(f, &env->gpr[i]);

#if !defined(TARGET_PPC64)

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

        qemu_get_betls(f, &env->gprh[i]);

#endif

    qemu_get_betls(f, &env->lr);

    qemu_get_betls(f, &env->ctr);

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

        qemu_get_be32s(f, &env->crf[i]);

    qemu_get_betls(f, &xer);

    cpu_write_xer(env, xer);

    qemu_get_betls(f, &env->reserve_addr);

    qemu_get_betls(f, &env->msr);

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

        qemu_get_betls(f, &env->tgpr[i]);

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

        union {

            float64 d;

            uint64_t l;

        } u;

        u.l = qemu_get_be64(f);

        env->fpr[i] = u.d;

    }

    qemu_get_be32s(f, &fpscr);

    env->fpscr = fpscr;

    qemu_get_sbe32s(f, &env->access_type);

#if defined(TARGET_PPC64)

    qemu_get_betls(f, &env->spr[SPR_ASR]);

    qemu_get_sbe32s(f, &env->slb_nr);

#endif

    qemu_get_betls(f, &sdr1);

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

        qemu_get_betls(f, &env->sr[i]);

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

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

            qemu_get_betls(f, &env->DBAT[i][j]);

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

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

            qemu_get_betls(f, &env->IBAT[i][j]);

    qemu_get_sbe32s(f, &env->nb_tlb);

    qemu_get_sbe32s(f, &env->tlb_per_way);

    qemu_get_sbe32s(f, &env->nb_ways);

    qemu_get_sbe32s(f, &env->last_way);

    qemu_get_sbe32s(f, &env->id_tlbs);

    qemu_get_sbe32s(f, &env->nb_pids);

    if (env->tlb.tlb6) {

        // XXX assumes 6xx

        for (i = 0; i < env->nb_tlb; i++) {

            qemu_get_betls(f, &env->tlb.tlb6[i].pte0);

            qemu_get_betls(f, &env->tlb.tlb6[i].pte1);

            qemu_get_betls(f, &env->tlb.tlb6[i].EPN);

        }

    }

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

        qemu_get_betls(f, &env->pb[i]);

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

        qemu_get_betls(f, &env->spr[i]);

    if (!env->external_htab) {

        ppc_store_sdr1(env, sdr1);

    }

    qemu_get_be32s(f, &env->vscr);

    qemu_get_be64s(f, &env->spe_acc);

    qemu_get_be32s(f, &env->spe_fscr);

    qemu_get_betls(f, &env->msr_mask);

    qemu_get_be32s(f, &env->flags);

    qemu_get_sbe32s(f, &env->error_code);

    qemu_get_be32s(f, &env->pending_interrupts);

    qemu_get_be32s(f, &env->irq_input_state);

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

        qemu_get_betls(f, &env->excp_vectors[i]);

    qemu_get_betls(f, &env->excp_prefix);

    qemu_get_betls(f, &env->ivor_mask);

    qemu_get_betls(f, &env->ivpr_mask);

    qemu_get_betls(f, &env->hreset_vector);

    qemu_get_betls(f, &env->nip);

    qemu_get_betls(f, &env->hflags);

    qemu_get_betls(f, &env->hflags_nmsr);

    qemu_get_sbe32(f); /* Discard unused mmu_idx */

    qemu_get_sbe32(f); /* Discard unused power_mode */

    /* Recompute mmu indices */

    hreg_compute_mem_idx(env);

    return 0;

}


static inline uint32_t get_hwc_address(SM501State *state, int crt)

{

    uint32_t addr = crt ? state->dc_crt_hwc_addr : state->dc_panel_hwc_addr;

    return (addr & 0x03FFFFF0)/* >> 4*/;

}


int do_migrate_cancel(Monitor *mon, const QDict *qdict, QObject **ret_data)

{

    MigrationState *s = current_migration;

    if (s)

        s->cancel(s);

    return 0;

}


int cpu_is_bsp(CPUX86State *env)

{

    /* We hard-wire the BSP to the first CPU. */

    return env->cpu_index == 0;

}


void qerror_report(const char *fmt, ...)

{

    va_list va;

    QError *qerror;

    va_start(va, fmt);

    qerror = qerror_from_info(fmt, &va);

    va_end(va);

    if (monitor_cur_is_qmp()) {

        monitor_set_error(cur_mon, qerror);

    } else {

        qerror_print(qerror);

        QDECREF(qerror);

    }

}


static void change_qscale(MpegEncContext * s, int dquant)

{

    s->qscale += dquant;

    if (s->qscale < 1)

        s->qscale = 1;

    else if (s->qscale > 31)

        s->qscale = 31;

    s->y_dc_scale= s->y_dc_scale_table[ s->qscale ];

    s->c_dc_scale= s->c_dc_scale_table[ s->qscale ];

}


void add_boot_device_path(int32_t bootindex, DeviceState *dev,

                          const char *suffix)

{

    FWBootEntry *node, *i;

    if (bootindex < 0) {

        return;

    }

    assert(dev != NULL || suffix != NULL);

    node = g_malloc0(sizeof(FWBootEntry));

    node->bootindex = bootindex;

    node->suffix = suffix ? g_strdup(suffix) : NULL;

    node->dev = dev;

    QTAILQ_FOREACH(i, &fw_boot_order, link) {

        if (i->bootindex == bootindex) {

            fprintf(stderr, "Two devices with same boot index %d\n", bootindex);

            exit(1);

        } else if (i->bootindex < bootindex) {

            continue;

        }

        QTAILQ_INSERT_BEFORE(i, node, link);

        return;

    }

    QTAILQ_INSERT_TAIL(&fw_boot_order, node, link);

}


QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)

{

    char *cmdline;

    struct QOSState *qs = g_malloc(sizeof(QOSState));

    cmdline = g_strdup_vprintf(cmdline_fmt, ap);

    qs->qts = qtest_start(cmdline);

    qs->ops = ops;

    qtest_irq_intercept_in(global_qtest, "ioapic");

    if (ops && ops->init_allocator) {

        qs->alloc = ops->init_allocator(ALLOC_NO_FLAGS);

    }

    g_free(cmdline);

    return qs;

}


static void gen_dozo(DisasContext *ctx)

{

    int l1 = gen_new_label();

    int l2 = gen_new_label();

    TCGv t0 = tcg_temp_new();

    TCGv t1 = tcg_temp_new();

    TCGv t2 = tcg_temp_new();

    /* Start with XER OV disabled, the most likely case */

    tcg_gen_movi_tl(cpu_ov, 0);

    tcg_gen_brcond_tl(TCG_COND_GE, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], l1);

    tcg_gen_sub_tl(t0, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);

    tcg_gen_xor_tl(t1, cpu_gpr[rB(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);

    tcg_gen_xor_tl(t2, cpu_gpr[rA(ctx->opcode)], t0);

    tcg_gen_andc_tl(t1, t1, t2);

    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);

    tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l2);

    tcg_gen_movi_tl(cpu_ov, 1);

    tcg_gen_movi_tl(cpu_so, 1);

    tcg_gen_br(l2);

    gen_set_label(l1);

    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], 0);

    gen_set_label(l2);

    tcg_temp_free(t0);

    tcg_temp_free(t1);

    tcg_temp_free(t2);

    if (unlikely(Rc(ctx->opcode) != 0))

        gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);

}


static void qdev_prop_cpy(DeviceState *dev, Property *props, void *src)

{

    if (props->info->type == PROP_TYPE_BIT) {

        bool *defval = src;

        bit_prop_set(dev, props, *defval);

    } else {

        char *dst = qdev_get_prop_ptr(dev, props);

        memcpy(dst, src, props->info->size);

    }

}


int qemu_cpu_self(void *_env)

{

    CPUState *env = _env;

    QemuThread this;

    qemu_thread_self(&this);

    return qemu_thread_equal(&this, env->thread);

}


void pstrcpy_targphys(const char *name, target_phys_addr_t dest, int buf_size,

                      const char *source)

{

    const char *nulp;

    char *ptr;

    if (buf_size <= 0) return;

    nulp = memchr(source, 0, buf_size);

    if (nulp) {

        rom_add_blob_fixed(name, source, (nulp - source) + 1, dest);

    } else {

        rom_add_blob_fixed(name, source, buf_size, dest);

        ptr = rom_ptr(dest + buf_size - 1);

        *ptr = 0;

    }

}


static void ioport_write(void *opaque, target_phys_addr_t addr,

                         uint64_t val, unsigned size)

{

    PCIQXLDevice *d = opaque;

    uint32_t io_port = addr;

    qxl_async_io async = QXL_SYNC;

#if SPICE_INTERFACE_QXL_MINOR >= 1

    uint32_t orig_io_port = io_port;

#endif

    switch (io_port) {

    case QXL_IO_RESET:

    case QXL_IO_SET_MODE:

    case QXL_IO_MEMSLOT_ADD:

    case QXL_IO_MEMSLOT_DEL:

    case QXL_IO_CREATE_PRIMARY:

    case QXL_IO_UPDATE_IRQ:

    case QXL_IO_LOG:

#if SPICE_INTERFACE_QXL_MINOR >= 1

    case QXL_IO_MEMSLOT_ADD_ASYNC:

    case QXL_IO_CREATE_PRIMARY_ASYNC:

#endif

        break;

    default:

        if (d->mode != QXL_MODE_VGA) {

            break;

        }

        dprint(d, 1, "%s: unexpected port 0x%x (%s) in vga mode\n",

            __func__, io_port, io_port_to_string(io_port));

#if SPICE_INTERFACE_QXL_MINOR >= 1

        /* be nice to buggy guest drivers */

        if (io_port >= QXL_IO_UPDATE_AREA_ASYNC &&

            io_port <= QXL_IO_DESTROY_ALL_SURFACES_ASYNC) {

            qxl_send_events(d, QXL_INTERRUPT_IO_CMD);

        }

#endif

        return;

    }

#if SPICE_INTERFACE_QXL_MINOR >= 1

    /* we change the io_port to avoid ifdeffery in the main switch */

    orig_io_port = io_port;

    switch (io_port) {

    case QXL_IO_UPDATE_AREA_ASYNC:

        io_port = QXL_IO_UPDATE_AREA;

        goto async_common;

    case QXL_IO_MEMSLOT_ADD_ASYNC:

        io_port = QXL_IO_MEMSLOT_ADD;

        goto async_common;

    case QXL_IO_CREATE_PRIMARY_ASYNC:

        io_port = QXL_IO_CREATE_PRIMARY;

        goto async_common;

    case QXL_IO_DESTROY_PRIMARY_ASYNC:

        io_port = QXL_IO_DESTROY_PRIMARY;

        goto async_common;

    case QXL_IO_DESTROY_SURFACE_ASYNC:

        io_port = QXL_IO_DESTROY_SURFACE_WAIT;

        goto async_common;

    case QXL_IO_DESTROY_ALL_SURFACES_ASYNC:

        io_port = QXL_IO_DESTROY_ALL_SURFACES;

        goto async_common;

    case QXL_IO_FLUSH_SURFACES_ASYNC:

async_common:

        async = QXL_ASYNC;

        qemu_mutex_lock(&d->async_lock);

        if (d->current_async != QXL_UNDEFINED_IO) {

            qxl_guest_bug(d, "%d async started before last (%d) complete",

                io_port, d->current_async);

            qemu_mutex_unlock(&d->async_lock);

            return;

        }

        d->current_async = orig_io_port;

        qemu_mutex_unlock(&d->async_lock);

        dprint(d, 2, "start async %d (%"PRId64")\n", io_port, val);

        break;

    default:

        break;

    }

#endif

    switch (io_port) {

    case QXL_IO_UPDATE_AREA:

    {

        QXLRect update = d->ram->update_area;

        qxl_spice_update_area(d, d->ram->update_surface,

                              &update, NULL, 0, 0, async);

        break;

    }

    case QXL_IO_NOTIFY_CMD:

        qemu_spice_wakeup(&d->ssd);

        break;

    case QXL_IO_NOTIFY_CURSOR:

        qemu_spice_wakeup(&d->ssd);

        break;

    case QXL_IO_UPDATE_IRQ:

        qxl_update_irq(d);

        break;

    case QXL_IO_NOTIFY_OOM:

        if (!SPICE_RING_IS_EMPTY(&d->ram->release_ring)) {

            break;

        }

        d->oom_running = 1;

        qxl_spice_oom(d);

        d->oom_running = 0;

        break;

    case QXL_IO_SET_MODE:

        dprint(d, 1, "QXL_SET_MODE %d\n", (int)val);

        qxl_set_mode(d, val, 0);

        break;

    case QXL_IO_LOG:

        if (d->guestdebug) {

            fprintf(stderr, "qxl/guest-%d: %" PRId64 ": %s", d->id,

                    qemu_get_clock_ns(vm_clock), d->ram->log_buf);

        }

        break;

    case QXL_IO_RESET:

        dprint(d, 1, "QXL_IO_RESET\n");

        qxl_hard_reset(d, 0);

        break;

    case QXL_IO_MEMSLOT_ADD:

        if (val >= NUM_MEMSLOTS) {

            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: val out of range");

            break;

        }

        if (d->guest_slots[val].active) {

            qxl_guest_bug(d, "QXL_IO_MEMSLOT_ADD: memory slot already active");

            break;

        }

        d->guest_slots[val].slot = d->ram->mem_slot;

        qxl_add_memslot(d, val, 0, async);

        break;

    case QXL_IO_MEMSLOT_DEL:

        if (val >= NUM_MEMSLOTS) {

            qxl_guest_bug(d, "QXL_IO_MEMSLOT_DEL: val out of range");

            break;

        }

        qxl_del_memslot(d, val);

        break;

    case QXL_IO_CREATE_PRIMARY:

        if (val != 0) {

            qxl_guest_bug(d, "QXL_IO_CREATE_PRIMARY (async=%d): val != 0",

                          async);

            goto cancel_async;

        }

        dprint(d, 1, "QXL_IO_CREATE_PRIMARY async=%d\n", async);

        d->guest_primary.surface = d->ram->create_surface;

        qxl_create_guest_primary(d, 0, async);

        break;

    case QXL_IO_DESTROY_PRIMARY:

        if (val != 0) {

            qxl_guest_bug(d, "QXL_IO_DESTROY_PRIMARY (async=%d): val != 0",

                          async);

            goto cancel_async;

        }

        dprint(d, 1, "QXL_IO_DESTROY_PRIMARY (async=%d) (%s)\n", async,

               qxl_mode_to_string(d->mode));

        if (!qxl_destroy_primary(d, async)) {

            dprint(d, 1, "QXL_IO_DESTROY_PRIMARY_ASYNC in %s, ignored\n",

                    qxl_mode_to_string(d->mode));

            goto cancel_async;

        }

        break;

    case QXL_IO_DESTROY_SURFACE_WAIT:

        if (val >= NUM_SURFACES) {

            qxl_guest_bug(d, "QXL_IO_DESTROY_SURFACE (async=%d):"

                             "%d >= NUM_SURFACES", async, val);

            goto cancel_async;

        }

        qxl_spice_destroy_surface_wait(d, val, async);

        break;

#if SPICE_INTERFACE_QXL_MINOR >= 1

    case QXL_IO_FLUSH_RELEASE: {

        QXLReleaseRing *ring = &d->ram->release_ring;

        if (ring->prod - ring->cons + 1 == ring->num_items) {

            fprintf(stderr,

                "ERROR: no flush, full release ring [p%d,%dc]\n",

                ring->prod, ring->cons);

        }

        qxl_push_free_res(d, 1 /* flush */);

        dprint(d, 1, "QXL_IO_FLUSH_RELEASE exit (%s, s#=%d, res#=%d,%p)\n",

            qxl_mode_to_string(d->mode), d->guest_surfaces.count,

            d->num_free_res, d->last_release);

        break;

    }

    case QXL_IO_FLUSH_SURFACES_ASYNC:

        dprint(d, 1, "QXL_IO_FLUSH_SURFACES_ASYNC"

                     " (%"PRId64") (%s, s#=%d, res#=%d)\n",

               val, qxl_mode_to_string(d->mode), d->guest_surfaces.count,

               d->num_free_res);

        qxl_spice_flush_surfaces_async(d);

        break;

#endif

    case QXL_IO_DESTROY_ALL_SURFACES:

        d->mode = QXL_MODE_UNDEFINED;

        qxl_spice_destroy_surfaces(d, async);

        break;

    default:

        fprintf(stderr, "%s: ioport=0x%x, abort()\n", __FUNCTION__, io_port);

        abort();

    }

    return;

cancel_async:

#if SPICE_INTERFACE_QXL_MINOR >= 1

    if (async) {

        qxl_send_events(d, QXL_INTERRUPT_IO_CMD);

        qemu_mutex_lock(&d->async_lock);

        d->current_async = QXL_UNDEFINED_IO;

        qemu_mutex_unlock(&d->async_lock);

    }

#else

    return;

#endif

}


void timer_mod_anticipate(QEMUTimer *ts, int64_t expire_time)

{

    timer_mod_anticipate_ns(ts, expire_time * ts->scale);

}


static void musicpal_init(ram_addr_t ram_size,

               const char *boot_device,

               const char *kernel_filename, const char *kernel_cmdline,

               const char *initrd_filename, const char *cpu_model)

{

    CPUState *env;

    qemu_irq *cpu_pic;

    qemu_irq pic[32];

    DeviceState *dev;

    DeviceState *i2c_dev;

    DeviceState *lcd_dev;

    DeviceState *key_dev;

#ifdef HAS_AUDIO

    DeviceState *wm8750_dev;

    SysBusDevice *s;

#endif

    i2c_bus *i2c;

    int i;

    unsigned long flash_size;

    DriveInfo *dinfo;

    ram_addr_t sram_off;

    if (!cpu_model) {

        cpu_model = "arm926";

    }

    env = cpu_init(cpu_model);

    if (!env) {

        fprintf(stderr, "Unable to find CPU definition\n");

        exit(1);

    }

    cpu_pic = arm_pic_init_cpu(env);

    /* For now we use a fixed - the original - RAM size */

    cpu_register_physical_memory(0, MP_RAM_DEFAULT_SIZE,

                                 qemu_ram_alloc(MP_RAM_DEFAULT_SIZE));

    sram_off = qemu_ram_alloc(MP_SRAM_SIZE);

    cpu_register_physical_memory(MP_SRAM_BASE, MP_SRAM_SIZE, sram_off);

    dev = sysbus_create_simple("mv88w8618_pic", MP_PIC_BASE,

                               cpu_pic[ARM_PIC_CPU_IRQ]);

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

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

    }

    sysbus_create_varargs("mv88w8618_pit", MP_PIT_BASE, pic[MP_TIMER1_IRQ],

                          pic[MP_TIMER2_IRQ], pic[MP_TIMER3_IRQ],

                          pic[MP_TIMER4_IRQ], NULL);

    if (serial_hds[0]) {

#ifdef TARGET_WORDS_BIGENDIAN

        serial_mm_init(MP_UART1_BASE, 2, pic[MP_UART1_IRQ], 1825000,

                       serial_hds[0], 1, 1);

#else

        serial_mm_init(MP_UART1_BASE, 2, pic[MP_UART1_IRQ], 1825000,

                       serial_hds[0], 1, 0);

#endif

    }

    if (serial_hds[1]) {

#ifdef TARGET_WORDS_BIGENDIAN

        serial_mm_init(MP_UART2_BASE, 2, pic[MP_UART2_IRQ], 1825000,

                       serial_hds[1], 1, 1);

#else

        serial_mm_init(MP_UART2_BASE, 2, pic[MP_UART2_IRQ], 1825000,

                       serial_hds[1], 1, 0);

#endif

    }

    /* Register flash */

    dinfo = drive_get(IF_PFLASH, 0, 0);

    if (dinfo) {

        flash_size = bdrv_getlength(dinfo->bdrv);

        if (flash_size != 8*1024*1024 && flash_size != 16*1024*1024 &&

            flash_size != 32*1024*1024) {

            fprintf(stderr, "Invalid flash image size\n");

            exit(1);

        }

        /*

         * The original U-Boot accesses the flash at 0xFE000000 instead of

         * 0xFF800000 (if there is 8 MB flash). So remap flash access if the

         * image is smaller than 32 MB.

         */

#ifdef TARGET_WORDS_BIGENDIAN

        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(flash_size),

                              dinfo->bdrv, 0x10000,

                              (flash_size + 0xffff) >> 16,

                              MP_FLASH_SIZE_MAX / flash_size,

                              2, 0x00BF, 0x236D, 0x0000, 0x0000,

                              0x5555, 0x2AAA, 1);

#else

        pflash_cfi02_register(0-MP_FLASH_SIZE_MAX, qemu_ram_alloc(flash_size),

                              dinfo->bdrv, 0x10000,

                              (flash_size + 0xffff) >> 16,

                              MP_FLASH_SIZE_MAX / flash_size,

                              2, 0x00BF, 0x236D, 0x0000, 0x0000,

                              0x5555, 0x2AAA, 0);

#endif

    }

    sysbus_create_simple("mv88w8618_flashcfg", MP_FLASHCFG_BASE, NULL);

    qemu_check_nic_model(&nd_table[0], "mv88w8618");

    dev = qdev_create(NULL, "mv88w8618_eth");

    qdev_set_nic_properties(dev, &nd_table[0]);

    qdev_init_nofail(dev);

    sysbus_mmio_map(sysbus_from_qdev(dev), 0, MP_ETH_BASE);

    sysbus_connect_irq(sysbus_from_qdev(dev), 0, pic[MP_ETH_IRQ]);

    sysbus_create_simple("mv88w8618_wlan", MP_WLAN_BASE, NULL);

    musicpal_misc_init();

    dev = sysbus_create_simple("musicpal_gpio", MP_GPIO_BASE, pic[MP_GPIO_IRQ]);

    i2c_dev = sysbus_create_simple("gpio_i2c", 0, NULL);

    i2c = (i2c_bus *)qdev_get_child_bus(i2c_dev, "i2c");

    lcd_dev = sysbus_create_simple("musicpal_lcd", MP_LCD_BASE, NULL);

    key_dev = sysbus_create_simple("musicpal_key", 0, NULL);

    /* I2C read data */

    qdev_connect_gpio_out(i2c_dev, 0,

                          qdev_get_gpio_in(dev, MP_GPIO_I2C_DATA_BIT));

    /* I2C data */

    qdev_connect_gpio_out(dev, 3, qdev_get_gpio_in(i2c_dev, 0));

    /* I2C clock */

    qdev_connect_gpio_out(dev, 4, qdev_get_gpio_in(i2c_dev, 1));

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

        qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(lcd_dev, i));

    }

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

        qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 8));

    }

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

        qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 15));

    }

#ifdef HAS_AUDIO

    wm8750_dev = i2c_create_slave(i2c, "wm8750", MP_WM_ADDR);

    dev = qdev_create(NULL, "mv88w8618_audio");

    s = sysbus_from_qdev(dev);

    qdev_prop_set_ptr(dev, "wm8750", wm8750_dev);

    qdev_init_nofail(dev);

    sysbus_mmio_map(s, 0, MP_AUDIO_BASE);

    sysbus_connect_irq(s, 0, pic[MP_AUDIO_IRQ]);

#endif

    musicpal_binfo.ram_size = MP_RAM_DEFAULT_SIZE;

    musicpal_binfo.kernel_filename = kernel_filename;

    musicpal_binfo.kernel_cmdline = kernel_cmdline;

    musicpal_binfo.initrd_filename = initrd_filename;

    arm_load_kernel(env, &musicpal_binfo);

}


static void vscsi_inquiry_no_target(VSCSIState *s, vscsi_req *req)

{

    uint8_t *cdb = req->iu.srp.cmd.cdb;

    uint8_t resp_data[36];

    int rc, len, alen;

    /* We dont do EVPD. Also check that page_code is 0 */

    if ((cdb[1] & 0x01) || (cdb[1] & 0x01) || cdb[2] != 0) {

        /* Send INVALID FIELD IN CDB */

        vscsi_makeup_sense(s, req, ILLEGAL_REQUEST, 0x24, 0);

        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);

        return;

    }

    alen = cdb[3];

    alen = (alen << 8) | cdb[4];

    len = MIN(alen, 36);

    /* Fake up inquiry using PQ=3 */

    memset(resp_data, 0, 36);

    resp_data[0] = 0x7f;   /* Not capable of supporting a device here */

    resp_data[2] = 0x06;   /* SPS-4 */

    resp_data[3] = 0x02;   /* Resp data format */

    resp_data[4] = 36 - 5; /* Additional length */

    resp_data[7] = 0x10;   /* Sync transfers */

    memcpy(&resp_data[16], "QEMU EMPTY      ", 16);

    memcpy(&resp_data[8], "QEMU    ", 8);

    req->writing = 0;

    vscsi_preprocess_desc(req);

    rc = vscsi_srp_transfer_data(s, req, 0, resp_data, len);

    if (rc < 0) {

        vscsi_makeup_sense(s, req, HARDWARE_ERROR, 0, 0);

        vscsi_send_rsp(s, req, CHECK_CONDITION, 0, 0);

    } else {

        vscsi_send_rsp(s, req, 0, 36 - rc, 0);

    }

}


static SocketAddress *unix_build_address(const char *path)

{

    SocketAddress *saddr;

    saddr = g_new0(SocketAddress, 1);

    saddr->type = SOCKET_ADDRESS_KIND_UNIX;

    saddr->u.q_unix.data = g_new0(UnixSocketAddress, 1);

    saddr->u.q_unix.data->path = g_strdup(path);

    return saddr;

}


void net_cleanup(void)

{

#if !defined(_WIN32)

    VLANState *vlan;

    /* close network clients */

    for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) {

        VLANClientState *vc;

        for(vc = vlan->first_client; vc != NULL; vc = vc->next) {

            if (vc->fd_read == tap_receive) {

                TAPState *s = vc->opaque;

                if (s->down_script[0])

                    launch_script(s->down_script, s->down_script_arg, s->fd);

            }

#if defined(CONFIG_VDE)

            if (vc->fd_read == vde_from_qemu) {

                VDEState *s = vc->opaque;

                vde_close(s->vde);

            }

#endif

        }

    }

#endif

}


void qmp_transaction(TransactionActionList *dev_list, Error **errp)
{
    TransactionActionList *dev_entry = dev_list;
    BlkTransactionState *state, *next;
    Error *local_err = NULL;
    QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionState) snap_bdrv_states;
    QSIMPLEQ_INIT(&snap_bdrv_states);
    /* drain all i/o before any snapshots */
    bdrv_drain_all();
    /* We don't do anything in this loop that commits us to the snapshot */
    while (NULL != dev_entry) {
        TransactionAction *dev_info = NULL;
        const BdrvActionOps *ops;
        dev_info = dev_entry->value;
        dev_entry = dev_entry->next;
        assert(dev_info->kind < ARRAY_SIZE(actions));
        ops = &actions[dev_info->kind];
        state = g_malloc0(ops->instance_size);
        state->ops = ops;
        state->action = dev_info;
        QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry);
        state->ops->prepare(state, &local_err);
        if (error_is_set(&local_err)) {
            error_propagate(errp, local_err);
            goto delete_and_fail;
        }
    }
    QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) {
        if (state->ops->commit) {
            state->ops->commit(state);
        }
    }
    /* success */
    goto exit;
delete_and_fail:
    /*
    * failure, and it is all-or-none; abandon each new bs, and keep using
    * the original bs for all images
    */
    QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) {
        if (state->ops->abort) {
            state->ops->abort(state);
        }
    }
exit:
    QSIMPLEQ_FOREACH_SAFE(state, &snap_bdrv_states, entry, next) {
        if (state->ops->clean) {
            state->ops->clean(state);
        }
        g_free(state);
    }
}


BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,

                                uint8_t *buf, int nb_sectors,

                                BlockDriverCompletionFunc *cb, void *opaque)

{

    BlockDriver *drv = bs->drv;

    BlockDriverAIOCB *ret;

    if (!drv)

        return NULL;

    if (bdrv_rd_badreq_sectors(bs, sector_num, nb_sectors))

        return NULL;

    /* XXX: we assume that nb_sectors == 0 is suppored by the async read */

    if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {

        memcpy(buf, bs->boot_sector_data, 512);

        sector_num++;

        nb_sectors--;

        buf += 512;

    }

    ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);

    if (ret) {

	/* Update stats even though technically transfer has not happened. */

	bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;

	bs->rd_ops ++;

    }

    return ret;

}


GuestFileRead *qmp_guest_file_read(int64_t handle, bool has_count,

                                   int64_t count, Error **errp)

{

    GuestFileRead *read_data = NULL;

    guchar *buf;

    HANDLE fh;

    bool is_ok;

    DWORD read_count;

    GuestFileHandle *gfh = guest_file_handle_find(handle, errp);

    if (!gfh) {

        return NULL;

    }

    if (!has_count) {

        count = QGA_READ_COUNT_DEFAULT;

    } else if (count < 0) {

        error_setg(errp, "value '%" PRId64

                   "' is invalid for argument count", count);

        return NULL;

    }

    fh = gfh->fh;

    buf = g_malloc0(count+1);

    is_ok = ReadFile(fh, buf, count, &read_count, NULL);

    if (!is_ok) {

        error_setg_win32(errp, GetLastError(), "failed to read file");

        slog("guest-file-read failed, handle %" PRId64, handle);

    } else {

        buf[read_count] = 0;

        read_data = g_malloc0(sizeof(GuestFileRead));

        read_data->count = (size_t)read_count;

        read_data->eof = read_count == 0;

        if (read_count != 0) {

            read_data->buf_b64 = g_base64_encode(buf, read_count);

        }

    }

    g_free(buf);

    return read_data;

}


void av_set_pts_info(AVStream *s, int pts_wrap_bits,

                     unsigned int pts_num, unsigned int pts_den)

{

    unsigned int gcd= av_gcd(pts_num, pts_den);

    s->pts_wrap_bits = pts_wrap_bits;

    s->time_base.num = pts_num/gcd;

    s->time_base.den = pts_den/gcd;

    if(gcd>1)

        av_log(NULL, AV_LOG_DEBUG, "st:%d removing common factor %d from timebase\n", s->index, gcd);

}


static int msvideo1_decode_init(AVCodecContext *avctx)

{

    Msvideo1Context *s = avctx->priv_data;

    s->avctx = avctx;

    /* figure out the colorspace based on the presence of a palette */

    if (s->avctx->palctrl) {

        s->mode_8bit = 1;

        avctx->pix_fmt = PIX_FMT_PAL8;

    } else {

        s->mode_8bit = 0;

        avctx->pix_fmt = PIX_FMT_RGB555;

    }

    dsputil_init(&s->dsp, avctx);

    s->frame.data[0] = NULL;

    return 0;

}


static void convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],

                           const uint16_t *quant_matrix, int bias, int qmin, int qmax)

{

    int qscale;

    for(qscale=qmin; qscale<=qmax; qscale++){

        int i;

        if (dsp->fdct == ff_jpeg_fdct_islow

#ifdef FAAN_POSTSCALE

            || dsp->fdct == ff_faandct

#endif

            ) {

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

                const int j= dsp->idct_permutation[i];

                /* 16 <= qscale * quant_matrix[i] <= 7905 */

                /* 19952         <= aanscales[i] * qscale * quant_matrix[i]           <= 249205026 */

                /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */

                /* 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */

                qmat[qscale][i] = (int)((uint64_t_C(1) << QMAT_SHIFT) /

                                (qscale * quant_matrix[j]));

            }

        } else if (dsp->fdct == fdct_ifast

#ifndef FAAN_POSTSCALE

                   || dsp->fdct == ff_faandct

#endif

                   ) {

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

                const int j= dsp->idct_permutation[i];

                /* 16 <= qscale * quant_matrix[i] <= 7905 */

                /* 19952         <= aanscales[i] * qscale * quant_matrix[i]           <= 249205026 */

                /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */

                /* 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */

                qmat[qscale][i] = (int)((uint64_t_C(1) << (QMAT_SHIFT + 14)) /

                                (aanscales[i] * qscale * quant_matrix[j]));

            }

        } else {

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

                const int j= dsp->idct_permutation[i];

                /* We can safely suppose that 16 <= quant_matrix[i] <= 255

                   So 16           <= qscale * quant_matrix[i]             <= 7905

                   so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905

                   so 32768        >= (1<<19) / (qscale * quant_matrix[i]) >= 67

                */

                qmat[qscale][i] = (int)((uint64_t_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j]));

//                qmat  [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);

                qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);

                if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1;

                qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]);

            }

        }

    }

}


static int encode_dvd_subtitles(uint8_t *outbuf, int outbuf_size,

                                const AVSubtitle *h)

{

    uint8_t *q, *qq;

    int object_id;

    int offset1[20], offset2[20];

    int i, imax, color, alpha, rects = h->num_rects;

    unsigned long hmax;

    unsigned long hist[256];

    int           cmap[256];

    if (rects == 0 || h->rects == NULL)

        return -1;

    if (rects > 20)

        rects = 20;

    // analyze bitmaps, compress to 4 colors

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

        hist[i] = 0;

        cmap[i] = 0;

    }

    for (object_id = 0; object_id < rects; object_id++)

        for (i=0; i<h->rects[object_id]->w*h->rects[object_id]->h; ++i) {

            color = h->rects[object_id]->pict.data[0][i];

            // only count non-transparent pixels

            alpha = ((uint32_t*)h->rects[object_id]->pict.data[1])[color] >> 24;

            hist[color] += alpha;

        }

    for (color=3;; --color) {

        hmax = 0;

        imax = 0;

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

            if (hist[i] > hmax) {

                imax = i;

                hmax = hist[i];

            }

        if (hmax == 0)

            break;

        if (color == 0)

            color = 3;

        av_log(NULL, AV_LOG_DEBUG, "dvd_subtitle hist[%d]=%ld -> col %d\n",

               imax, hist[imax], color);

        cmap[imax] = color;

        hist[imax] = 0;

    }

    // encode data block

    q = outbuf + 4;

    for (object_id = 0; object_id < rects; object_id++) {

        offset1[object_id] = q - outbuf;

        // worst case memory requirement: 1 nibble per pixel..

        if ((q - outbuf) + h->rects[object_id]->w*h->rects[object_id]->h/2

            + 17*rects + 21 > outbuf_size) {

            av_log(NULL, AV_LOG_ERROR, "dvd_subtitle too big\n");

            return -1;

        }

        dvd_encode_rle(&q, h->rects[object_id]->pict.data[0],

                       h->rects[object_id]->w*2,

                       h->rects[object_id]->w, h->rects[object_id]->h >> 1,

                       cmap);

        offset2[object_id] = q - outbuf;

        dvd_encode_rle(&q, h->rects[object_id]->pict.data[0] + h->rects[object_id]->w,

                       h->rects[object_id]->w*2,

                       h->rects[object_id]->w, h->rects[object_id]->h >> 1,

                       cmap);

    }

    // set data packet size

    qq = outbuf + 2;

    bytestream_put_be16(&qq, q - outbuf);

    // send start display command

    bytestream_put_be16(&q, (h->start_display_time*90) >> 10);

    bytestream_put_be16(&q, (q - outbuf) /*- 2 */ + 8 + 12*rects + 2);

    *q++ = 0x03; // palette - 4 nibbles

    *q++ = 0x03; *q++ = 0x7f;

    *q++ = 0x04; // alpha - 4 nibbles

    *q++ = 0xf0; *q++ = 0x00;

    //*q++ = 0x0f; *q++ = 0xff;

    // XXX not sure if more than one rect can really be encoded..

    // 12 bytes per rect

    for (object_id = 0; object_id < rects; object_id++) {

        int x2 = h->rects[object_id]->x + h->rects[object_id]->w - 1;

        int y2 = h->rects[object_id]->y + h->rects[object_id]->h - 1;

        *q++ = 0x05;

        // x1 x2 -> 6 nibbles

        *q++ = h->rects[object_id]->x >> 4;

        *q++ = (h->rects[object_id]->x << 4) | ((x2 >> 8) & 0xf);

        *q++ = x2;

        // y1 y2 -> 6 nibbles

        *q++ = h->rects[object_id]->y >> 4;

        *q++ = (h->rects[object_id]->y << 4) | ((y2 >> 8) & 0xf);

        *q++ = y2;

        *q++ = 0x06;

        // offset1, offset2

        bytestream_put_be16(&q, offset1[object_id]);

        bytestream_put_be16(&q, offset2[object_id]);

    }

    *q++ = 0x01; // start command

    *q++ = 0xff; // terminating command

    // send stop display command last

    bytestream_put_be16(&q, (h->end_display_time*90) >> 10);

    bytestream_put_be16(&q, (q - outbuf) - 2 /*+ 4*/);

    *q++ = 0x02; // set end

    *q++ = 0xff; // terminating command

    qq = outbuf;

    bytestream_put_be16(&qq, q - outbuf);

    av_log(NULL, AV_LOG_DEBUG, "subtitle_packet size=%td\n", q - outbuf);

    return q - outbuf;

}


bool io_mem_write(MemoryRegion *mr, hwaddr addr,

                  uint64_t val, unsigned size)

{

    return memory_region_dispatch_write(mr, addr, val, size);

}


static int bit_allocation(IMCContext *q, IMCChannel *chctx,
                          int stream_format_code, int freebits, int flag)
{
    int i, j;
    const float limit = -1.e20;
    float highest = 0.0;
    int indx;
    int t1 = 0;
    int t2 = 1;
    float summa = 0.0;
    int iacc = 0;
    int summer = 0;
    int rres, cwlen;
    float lowest = 1.e10;
    int low_indx = 0;
    float workT[32];
    int flg;
    int found_indx = 0;
    for (i = 0; i < BANDS; i++)
        highest = FFMAX(highest, chctx->flcoeffs1[i]);
    for (i = 0; i < BANDS - 1; i++)
        chctx->flcoeffs4[i] = chctx->flcoeffs3[i] - log2f(chctx->flcoeffs5[i]);
    chctx->flcoeffs4[BANDS - 1] = limit;
    highest = highest * 0.25;
    for (i = 0; i < BANDS; i++) {
        indx = -1;
        if ((band_tab[i + 1] - band_tab[i]) == chctx->bandWidthT[i])
            indx = 0;
        if ((band_tab[i + 1] - band_tab[i]) > chctx->bandWidthT[i])
            indx = 1;
        if (((band_tab[i + 1] - band_tab[i]) / 2) >= chctx->bandWidthT[i])
            indx = 2;
        if (indx == -1)
        chctx->flcoeffs4[i] += xTab[(indx * 2 + (chctx->flcoeffs1[i] < highest)) * 2 + flag];
    }
    if (stream_format_code & 0x2) {
        chctx->flcoeffs4[0] = limit;
        chctx->flcoeffs4[1] = limit;
        chctx->flcoeffs4[2] = limit;
        chctx->flcoeffs4[3] = limit;
    }
    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS - 1; i++) {
        iacc  += chctx->bandWidthT[i];
        summa += chctx->bandWidthT[i] * chctx->flcoeffs4[i];
    }
    chctx->bandWidthT[BANDS - 1] = 0;
    summa = (summa * 0.5 - freebits) / iacc;
    for (i = 0; i < BANDS / 2; i++) {
        rres = summer - freebits;
        if ((rres >= -8) && (rres <= 8))
            break;
        summer = 0;
        iacc   = 0;
        for (j = (stream_format_code & 0x2) ? 4 : 0; j < BANDS; j++) {
            cwlen = av_clipf(((chctx->flcoeffs4[j] * 0.5) - summa + 0.5), 0, 6);
            chctx->bitsBandT[j] = cwlen;
            summer += chctx->bandWidthT[j] * cwlen;
            if (cwlen > 0)
                iacc += chctx->bandWidthT[j];
        }
        flg = t2;
        t2 = 1;
        if (freebits < summer)
            t2 = -1;
        if (i == 0)
            flg = t2;
        if (flg != t2)
            t1++;
        summa = (float)(summer - freebits) / ((t1 + 1) * iacc) + summa;
    }
    for (i = (stream_format_code & 0x2) ? 4 : 0; i < BANDS; i++) {
        for (j = band_tab[i]; j < band_tab[i + 1]; j++)
            chctx->CWlengthT[j] = chctx->bitsBandT[i];
    }
    if (freebits > summer) {
        for (i = 0; i < BANDS; i++) {
            workT[i] = (chctx->bitsBandT[i] == 6) ? -1.e20
                                              : (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] - 0.415);
        }
        highest = 0.0;
        do {
            if (highest <= -1.e20)
                break;
            found_indx = 0;
            highest = -1.e20;
            for (i = 0; i < BANDS; i++) {
                if (workT[i] > highest) {
                    highest = workT[i];
                    found_indx = i;
                }
            }
            if (highest > -1.e20) {
                workT[found_indx] -= 2.0;
                if (++chctx->bitsBandT[found_indx] == 6)
                    workT[found_indx] = -1.e20;
                for (j = band_tab[found_indx]; j < band_tab[found_indx + 1] && (freebits > summer); j++) {
                    chctx->CWlengthT[j]++;
                    summer++;
                }
            }
        } while (freebits > summer);
    }
    if (freebits < summer) {
        for (i = 0; i < BANDS; i++) {
            workT[i] = chctx->bitsBandT[i] ? (chctx->bitsBandT[i] * -2 + chctx->flcoeffs4[i] + 1.585)
                                       : 1.e20;
        }
        if (stream_format_code & 0x2) {
            workT[0] = 1.e20;
            workT[1] = 1.e20;
            workT[2] = 1.e20;
            workT[3] = 1.e20;
        }
        while (freebits < summer) {
            lowest   = 1.e10;
            low_indx = 0;
            for (i = 0; i < BANDS; i++) {
                if (workT[i] < lowest) {
                    lowest   = workT[i];
                    low_indx = i;
                }
            }
            // if (lowest >= 1.e10)
            //     break;
            workT[low_indx] = lowest + 2.0;
            if (!--chctx->bitsBandT[low_indx])
                workT[low_indx] = 1.e20;
            for (j = band_tab[low_indx]; j < band_tab[low_indx+1] && (freebits < summer); j++) {
                if (chctx->CWlengthT[j] > 0) {
                    chctx->CWlengthT[j]--;
                    summer--;
                }
            }
        }
    }
    return 0;
}


static int sox_read_header(AVFormatContext *s)

{

    AVIOContext *pb = s->pb;

    unsigned header_size, comment_size;

    double sample_rate, sample_rate_frac;

    AVStream *st;

    st = avformat_new_stream(s, NULL);

    if (!st)

        return AVERROR(ENOMEM);

    st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;

    if (avio_rl32(pb) == SOX_TAG) {

        st->codecpar->codec_id = AV_CODEC_ID_PCM_S32LE;

        header_size         = avio_rl32(pb);

        avio_skip(pb, 8); /* sample count */

        sample_rate         = av_int2double(avio_rl64(pb));

        st->codecpar->channels = avio_rl32(pb);

        comment_size        = avio_rl32(pb);

    } else {

        st->codecpar->codec_id = AV_CODEC_ID_PCM_S32BE;

        header_size         = avio_rb32(pb);

        avio_skip(pb, 8); /* sample count */

        sample_rate         = av_int2double(avio_rb64(pb));

        st->codecpar->channels = avio_rb32(pb);

        comment_size        = avio_rb32(pb);

    }

    if (comment_size > 0xFFFFFFFFU - SOX_FIXED_HDR - 4U) {

        av_log(s, AV_LOG_ERROR, "invalid comment size (%u)\n", comment_size);

        return AVERROR_INVALIDDATA;

    }

    if (sample_rate <= 0 || sample_rate > INT_MAX) {

        av_log(s, AV_LOG_ERROR, "invalid sample rate (%f)\n", sample_rate);

        return AVERROR_INVALIDDATA;

    }

    sample_rate_frac = sample_rate - floor(sample_rate);

    if (sample_rate_frac)

        av_log(s, AV_LOG_WARNING,

               "truncating fractional part of sample rate (%f)\n",

               sample_rate_frac);

    if ((header_size + 4) & 7 || header_size < SOX_FIXED_HDR + comment_size

        || st->codecpar->channels > 65535) /* Reserve top 16 bits */ {

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

        return AVERROR_INVALIDDATA;

    }

    if (comment_size && comment_size < UINT_MAX) {

        char *comment = av_malloc(comment_size+1);

        if(!comment)

            return AVERROR(ENOMEM);

        if (avio_read(pb, comment, comment_size) != comment_size) {

            av_freep(&comment);

            return AVERROR(EIO);

        }

        comment[comment_size] = 0;

        av_dict_set(&s->metadata, "comment", comment,

                               AV_DICT_DONT_STRDUP_VAL);

    }

    avio_skip(pb, header_size - SOX_FIXED_HDR - comment_size);

    st->codecpar->sample_rate           = sample_rate;

    st->codecpar->bits_per_coded_sample = 32;

    st->codecpar->bit_rate              = st->codecpar->sample_rate *

                                          st->codecpar->bits_per_coded_sample *

                                          st->codecpar->channels;

    st->codecpar->block_align           = st->codecpar->bits_per_coded_sample *

                                          st->codecpar->channels / 8;

    avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);

    return 0;

}


static void gen_swa(DisasContext *dc, TCGv rb, TCGv ra, int32_t ofs)

{

    TCGv ea, val;

    TCGLabel *lab_fail, *lab_done;

    ea = tcg_temp_new();

    tcg_gen_addi_tl(ea, ra, ofs);

    lab_fail = gen_new_label();

    lab_done = gen_new_label();

    tcg_gen_brcond_tl(TCG_COND_NE, ea, cpu_lock_addr, lab_fail);

    tcg_temp_free(ea);

    val = tcg_temp_new();

    tcg_gen_atomic_cmpxchg_tl(val, cpu_lock_addr, cpu_lock_value,

                              rb, dc->mem_idx, MO_TEUL);

    tcg_gen_setcond_tl(TCG_COND_EQ, cpu_sr_f, val, cpu_lock_value);

    tcg_temp_free(val);

    tcg_gen_br(lab_done);

    gen_set_label(lab_fail);

    tcg_gen_movi_tl(cpu_sr_f, 0);

    gen_set_label(lab_done);

    tcg_gen_movi_tl(cpu_lock_addr, -1);

}


static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)

{

    uint32_t dmalen;

    int target;

    target = s->wregs[ESP_WBUSID] & BUSID_DID;

    if (s->dma) {

        dmalen = s->rregs[ESP_TCLO];

        dmalen |= s->rregs[ESP_TCMID] << 8;

        dmalen |= s->rregs[ESP_TCHI] << 16;

        if (dmalen > buflen) {

        s->dma_memory_read(s->dma_opaque, buf, dmalen);

    } else {

        dmalen = s->ti_size;

        memcpy(buf, s->ti_buf, dmalen);

        buf[0] = buf[2] >> 5;

    trace_esp_get_cmd(dmalen, target);

    s->ti_size = 0;

    s->ti_rptr = 0;

    s->ti_wptr = 0;

    if (s->current_req) {

        /* Started a new command before the old one finished.  Cancel it.  */

        scsi_req_cancel(s->current_req);

        s->async_len = 0;

    s->current_dev = scsi_device_find(&s->bus, 0, target, 0);

    if (!s->current_dev) {

        // No such drive

        s->rregs[ESP_RSTAT] = 0;

        s->rregs[ESP_RINTR] = INTR_DC;

        s->rregs[ESP_RSEQ] = SEQ_0;

        esp_raise_irq(s);

    return dmalen;