static int open_input(struct variant *var)

{

    struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no];

    if (seg->key_type == KEY_NONE) {

        return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ,

                          &var->parent->interrupt_callback, NULL);

    } else if (seg->key_type == KEY_AES_128) {

        char iv[33], key[33], url[MAX_URL_SIZE];

        int ret;

        if (strcmp(seg->key, var->key_url)) {

            URLContext *uc;

            if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ,

                           &var->parent->interrupt_callback, NULL) == 0) {

                if (ffurl_read_complete(uc, var->key, sizeof(var->key))

                    != sizeof(var->key)) {

                    av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n",

                           seg->key);

                }

                ffurl_close(uc);

            } else {

                av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n",

                       seg->key);

            }

            av_strlcpy(var->key_url, seg->key, sizeof(var->key_url));

        }

        ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0);

        ff_data_to_hex(key, var->key, sizeof(var->key), 0);

        iv[32] = key[32] = '\0';

        if (strstr(seg->url, "://"))

            snprintf(url, sizeof(url), "crypto+%s", seg->url);

        else

            snprintf(url, sizeof(url), "crypto:%s", seg->url);

        if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ,

                               &var->parent->interrupt_callback)) < 0)

            return ret;

        av_opt_set(var->input->priv_data, "key", key, 0);

        av_opt_set(var->input->priv_data, "iv", iv, 0);

        if ((ret = ffurl_connect(var->input, NULL)) < 0) {

            ffurl_close(var->input);

            var->input = NULL;

            return ret;

        }

        return 0;

    }

    return AVERROR(ENOSYS);

}


static void process_ncq_command(AHCIState *s, int port, uint8_t *cmd_fis,

                                int slot)

{

    AHCIDevice *ad = &s->dev[port];

    IDEState *ide_state = &ad->port.ifs[0];

    NCQFrame *ncq_fis = (NCQFrame*)cmd_fis;

    uint8_t tag = ncq_fis->tag >> 3;

    NCQTransferState *ncq_tfs = &ad->ncq_tfs[tag];

    if (ncq_tfs->used) {

        /* error - already in use */

        fprintf(stderr, "%s: tag %d already used\n", __FUNCTION__, tag);

        return;

    }

    ncq_tfs->used = 1;

    ncq_tfs->drive = ad;

    ncq_tfs->slot = slot;

    ncq_tfs->lba = ((uint64_t)ncq_fis->lba5 << 40) |

                   ((uint64_t)ncq_fis->lba4 << 32) |

                   ((uint64_t)ncq_fis->lba3 << 24) |

                   ((uint64_t)ncq_fis->lba2 << 16) |

                   ((uint64_t)ncq_fis->lba1 << 8) |

                   (uint64_t)ncq_fis->lba0;

    /* Note: We calculate the sector count, but don't currently rely on it.

     * The total size of the DMA buffer tells us the transfer size instead. */

    ncq_tfs->sector_count = ((uint16_t)ncq_fis->sector_count_high << 8) |

                                ncq_fis->sector_count_low;

    DPRINTF(port, "NCQ transfer LBA from %"PRId64" to %"PRId64", "

            "drive max %"PRId64"\n",

            ncq_tfs->lba, ncq_tfs->lba + ncq_tfs->sector_count - 2,

            ide_state->nb_sectors - 1);

    ahci_populate_sglist(ad, &ncq_tfs->sglist, 0);

    ncq_tfs->tag = tag;

    switch(ncq_fis->command) {

        case READ_FPDMA_QUEUED:

            DPRINTF(port, "NCQ reading %d sectors from LBA %"PRId64", "

                    "tag %d\n",

                    ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);

            DPRINTF(port, "tag %d aio read %"PRId64"\n",

                    ncq_tfs->tag, ncq_tfs->lba);

            dma_acct_start(ide_state->blk, &ncq_tfs->acct,

                           &ncq_tfs->sglist, BLOCK_ACCT_READ);

            ncq_tfs->aiocb = dma_blk_read(ide_state->blk,

                                          &ncq_tfs->sglist, ncq_tfs->lba,

                                          ncq_cb, ncq_tfs);

            break;

        case WRITE_FPDMA_QUEUED:

            DPRINTF(port, "NCQ writing %d sectors to LBA %"PRId64", tag %d\n",

                    ncq_tfs->sector_count-1, ncq_tfs->lba, ncq_tfs->tag);

            DPRINTF(port, "tag %d aio write %"PRId64"\n",

                    ncq_tfs->tag, ncq_tfs->lba);

            dma_acct_start(ide_state->blk, &ncq_tfs->acct,

                           &ncq_tfs->sglist, BLOCK_ACCT_WRITE);

            ncq_tfs->aiocb = dma_blk_write(ide_state->blk,

                                           &ncq_tfs->sglist, ncq_tfs->lba,

                                           ncq_cb, ncq_tfs);

            break;

        default:

            if (is_ncq(cmd_fis[2])) {

                DPRINTF(port,

                        "error: unsupported NCQ command (0x%02x) received\n",

                        cmd_fis[2]);

            } else {

                DPRINTF(port,

                        "error: tried to process non-NCQ command as NCQ\n");

            }

            qemu_sglist_destroy(&ncq_tfs->sglist);

    }

}


static void pl190_class_init(ObjectClass *klass, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);

    k->init = pl190_init;

    dc->no_user = 1;

    dc->reset = pl190_reset;

    dc->vmsd = &vmstate_pl190;

}


static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                        AVPacket *avpkt)
{
    AVFrame *frame = data;
    const uint8_t *buf = avpkt->data;
    const uint8_t *buf_end = buf + avpkt->size;
    KgvContext * const c = avctx->priv_data;
    int offsets[8];
    uint8_t *out, *prev;
    int outcnt = 0, maxcnt;
    int w, h, i, res;
    if (avpkt->size < 2)
    w = (buf[0] + 1) * 8;
    h = (buf[1] + 1) * 8;
    buf += 2;
    if (w != avctx->width || h != avctx->height) {
        av_freep(&c->frame_buffer);
        av_freep(&c->last_frame_buffer);
        if ((res = ff_set_dimensions(avctx, w, h)) < 0)
            return res;
    }
    if (!c->frame_buffer) {
        c->frame_buffer      = av_mallocz(avctx->width * avctx->height * 2);
        c->last_frame_buffer = av_mallocz(avctx->width * avctx->height * 2);
        if (!c->frame_buffer || !c->last_frame_buffer) {
            decode_flush(avctx);
            return AVERROR(ENOMEM);
        }
    }
    maxcnt = w * h;
    if ((res = ff_get_buffer(avctx, frame, 0)) < 0)
        return res;
    out  = (uint8_t*)c->frame_buffer;
    prev = (uint8_t*)c->last_frame_buffer;
    for (i = 0; i < 8; i++)
        offsets[i] = -1;
    while (outcnt < maxcnt && buf_end - 2 >= buf) {
        int code = AV_RL16(buf);
        buf += 2;
        if (!(code & 0x8000)) {
            AV_WN16A(&out[2 * outcnt], code); // rgb555 pixel coded directly
            outcnt++;
        } else {
            int count;
            if ((code & 0x6000) == 0x6000) {
                // copy from previous frame
                int oidx = (code >> 10) & 7;
                int start;
                count = (code & 0x3FF) + 3;
                if (offsets[oidx] < 0) {
                    if (buf_end - 3 < buf)
                        break;
                    offsets[oidx] = AV_RL24(buf);
                    buf += 3;
                }
                start = (outcnt + offsets[oidx]) % maxcnt;
                if (maxcnt - start < count || maxcnt - outcnt < count)
                    break;
                if (!prev) {
                    av_log(avctx, AV_LOG_ERROR,
                           "Frame reference does not exist\n");
                    break;
                }
                memcpy(out + 2 * outcnt, prev + 2 * start, 2 * count);
            } else {
                // copy from earlier in this frame
                int offset = (code & 0x1FFF) + 1;
                if (!(code & 0x6000)) {
                    count = 2;
                } else if ((code & 0x6000) == 0x2000) {
                    count = 3;
                } else {
                    if (buf_end - 1 < buf)
                        break;
                    count = 4 + *buf++;
                }
                if (outcnt < offset || maxcnt - outcnt < count)
                    break;
                av_memcpy_backptr(out + 2 * outcnt, 2 * offset, 2 * count);
            }
            outcnt += count;
        }
    }
    if (outcnt - maxcnt)
        av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt);
    av_image_copy_plane(frame->data[0], frame->linesize[0],
                        (const uint8_t*)c->frame_buffer,  avctx->width * 2,
                        avctx->width * 2, avctx->height);
    FFSWAP(uint16_t *, c->frame_buffer, c->last_frame_buffer);
    *got_frame = 1;
    return avpkt->size;
}


static void spapr_finalize_fdt(sPAPREnvironment *spapr,

                               hwaddr fdt_addr,

                               hwaddr rtas_addr,

                               hwaddr rtas_size)

{

    int ret, i;

    size_t cb = 0;

    char *bootlist;

    void *fdt;

    sPAPRPHBState *phb;

    fdt = g_malloc(FDT_MAX_SIZE);

    /* open out the base tree into a temp buffer for the final tweaks */

    _FDT((fdt_open_into(spapr->fdt_skel, fdt, FDT_MAX_SIZE)));

    ret = spapr_populate_memory(spapr, fdt);

    if (ret < 0) {

        fprintf(stderr, "couldn't setup memory nodes in fdt\n");

        exit(1);

    }

    ret = spapr_populate_vdevice(spapr->vio_bus, fdt);

    if (ret < 0) {

        fprintf(stderr, "couldn't setup vio devices in fdt\n");

        exit(1);

    }

    QLIST_FOREACH(phb, &spapr->phbs, list) {

        ret = spapr_populate_pci_dt(phb, PHANDLE_XICP, fdt);

    }

    if (ret < 0) {

        fprintf(stderr, "couldn't setup PCI devices in fdt\n");

        exit(1);

    }

    /* RTAS */

    ret = spapr_rtas_device_tree_setup(fdt, rtas_addr, rtas_size);

    if (ret < 0) {

        fprintf(stderr, "Couldn't set up RTAS device tree properties\n");

    }

    /* Advertise NUMA via ibm,associativity */

    ret = spapr_fixup_cpu_dt(fdt, spapr);

    if (ret < 0) {

        fprintf(stderr, "Couldn't finalize CPU device tree properties\n");

    }

    bootlist = get_boot_devices_list(&cb, true);

    if (cb && bootlist) {

        int offset = fdt_path_offset(fdt, "/chosen");

        if (offset < 0) {

            exit(1);

        }

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

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

                bootlist[i] = ' ';

            }

        }

        ret = fdt_setprop_string(fdt, offset, "qemu,boot-list", bootlist);

    }

    if (!spapr->has_graphics) {

        spapr_populate_chosen_stdout(fdt, spapr->vio_bus);

    }

    _FDT((fdt_pack(fdt)));

    if (fdt_totalsize(fdt) > FDT_MAX_SIZE) {

        hw_error("FDT too big ! 0x%x bytes (max is 0x%x)\n",

                 fdt_totalsize(fdt), FDT_MAX_SIZE);

        exit(1);

    }

    cpu_physical_memory_write(fdt_addr, fdt, fdt_totalsize(fdt));

    g_free(fdt);

}


void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src)

{

    dst->x = av_clip(src->x, s->mv_min.x, s->mv_max.x);

    dst->y = av_clip(src->y, s->mv_min.y, s->mv_max.y);

}


static void pxa2xx_gpio_write(void *opaque, hwaddr offset,

                              uint64_t value, unsigned size)

{

    PXA2xxGPIOInfo *s = (PXA2xxGPIOInfo *) opaque;

    int bank;

    if (offset >= 0x200)

        return;

    bank = pxa2xx_gpio_regs[offset].bank;

    switch (pxa2xx_gpio_regs[offset].reg) {

    case GPDR:		/* GPIO Pin-Direction registers */

        s->dir[bank] = value;

        pxa2xx_gpio_handler_update(s);

        break;

    case GPSR:		/* GPIO Pin-Output Set registers */

        s->olevel[bank] |= value;

        pxa2xx_gpio_handler_update(s);

        s->gpsr[bank] = value;

        break;

    case GPCR:		/* GPIO Pin-Output Clear registers */

        s->olevel[bank] &= ~value;

        pxa2xx_gpio_handler_update(s);

        break;

    case GRER:		/* GPIO Rising-Edge Detect Enable registers */

        s->rising[bank] = value;

        break;

    case GFER:		/* GPIO Falling-Edge Detect Enable registers */

        s->falling[bank] = value;

        break;

    case GAFR_L:	/* GPIO Alternate Function registers */

        s->gafr[bank * 2] = value;

        break;

    case GAFR_U:	/* GPIO Alternate Function registers */

        s->gafr[bank * 2 + 1] = value;

        break;

    case GEDR:		/* GPIO Edge Detect Status registers */

        s->status[bank] &= ~value;

        pxa2xx_gpio_irq_update(s);

        break;

    default:

        hw_error("%s: Bad offset " REG_FMT "\n", __FUNCTION__, offset);

    }

}


AVFilterBufferRef *avfilter_default_get_audio_buffer(AVFilterLink *link, int perms,

                                                     int nb_samples)

{

    AVFilterBufferRef *samplesref = NULL;

    int linesize[8];

    uint8_t *data[8];

    int nb_channels = av_get_channel_layout_nb_channels(link->channel_layout);

    /* Calculate total buffer size, round to multiple of 16 to be SIMD friendly */

    if (av_samples_alloc(data, linesize,

                         nb_channels, nb_samples, link->format,

                         16) < 0)

        return NULL;

    samplesref =

        avfilter_get_audio_buffer_ref_from_arrays(data, linesize, perms,

                                                  nb_samples, link->format,

                                                  link->channel_layout, link->planar);

    if (!samplesref) {

        av_free(data[0]);

        return NULL;

    }

    return samplesref;

}


opts_check_struct(Visitor *v, Error **errp)

{

    OptsVisitor *ov = to_ov(v);

    GHashTableIter iter;

    GQueue *any;

    if (ov->depth > 0) {

        return;

    }

    /* we should have processed all (distinct) QemuOpt instances */

    g_hash_table_iter_init(&iter, ov->unprocessed_opts);

    if (g_hash_table_iter_next(&iter, NULL, (void **)&any)) {

        const QemuOpt *first;

        first = g_queue_peek_head(any);

        error_setg(errp, QERR_INVALID_PARAMETER, first->name);

    }

}


static int parse_chr(DeviceState *dev, Property *prop, const char *str)

{

    CharDriverState **ptr = qdev_get_prop_ptr(dev, prop);

    *ptr = qemu_chr_find(str);

    if (*ptr == NULL) {

        return -ENOENT;

    }

    if ((*ptr)->assigned) {

        return -EEXIST;

    }

    (*ptr)->assigned = 1;

    return 0;

}


int load_uimage(const char *filename, target_phys_addr_t *ep,

                target_phys_addr_t *loadaddr, int *is_linux)

{

    int fd;

    int size;

    uboot_image_header_t h;

    uboot_image_header_t *hdr = &h;

    uint8_t *data = NULL;

    int ret = -1;

    fd = open(filename, O_RDONLY | O_BINARY);

    if (fd < 0)

        return -1;

    size = read(fd, hdr, sizeof(uboot_image_header_t));

    if (size < 0)

        goto out;

    bswap_uboot_header(hdr);

    if (hdr->ih_magic != IH_MAGIC)

        goto out;

    /* TODO: Implement other image types.  */

    if (hdr->ih_type != IH_TYPE_KERNEL) {

        fprintf(stderr, "Can only load u-boot image type \"kernel\"\n");

        goto out;

    }

    switch (hdr->ih_comp) {

    case IH_COMP_NONE:

    case IH_COMP_GZIP:

        break;

    default:

        fprintf(stderr,

                "Unable to load u-boot images with compression type %d\n",

                hdr->ih_comp);

        goto out;

    }

    /* TODO: Check CPU type.  */

    if (is_linux) {

        if (hdr->ih_os == IH_OS_LINUX)

            *is_linux = 1;

        else

            *is_linux = 0;

    }

    *ep = hdr->ih_ep;

    data = qemu_malloc(hdr->ih_size);

    if (read(fd, data, hdr->ih_size) != hdr->ih_size) {

        fprintf(stderr, "Error reading file\n");

        goto out;

    }

    if (hdr->ih_comp == IH_COMP_GZIP) {

        uint8_t *compressed_data;

        size_t max_bytes;

        ssize_t bytes;

        compressed_data = data;

        max_bytes = UBOOT_MAX_GUNZIP_BYTES;

        data = qemu_malloc(max_bytes);

        bytes = gunzip(data, max_bytes, compressed_data, hdr->ih_size);

        qemu_free(compressed_data);

        if (bytes < 0) {

            fprintf(stderr, "Unable to decompress gzipped image!\n");

            goto out;

        }

        hdr->ih_size = bytes;

    }

    cpu_physical_memory_write_rom(hdr->ih_load, data, hdr->ih_size);

    if (loadaddr)

        *loadaddr = hdr->ih_load;

    ret = hdr->ih_size;

out:

    if (data)

        qemu_free(data);

    close(fd);

    return ret;

}


static int aic_decode_coeffs(GetBitContext *gb, int16_t *dst,

                             int band, int slice_width)

{

    int has_skips, coeff_type, coeff_bits, skip_type, skip_bits;

    const int num_coeffs = aic_num_band_coeffs[band];

    const uint8_t *scan = aic_scan[band];

    int mb, idx, val;

    has_skips  = get_bits1(gb);

    coeff_type = get_bits1(gb);

    coeff_bits = get_bits(gb, 3);

    if (has_skips) {

        skip_type = get_bits1(gb);

        skip_bits = get_bits(gb, 3);

        for (mb = 0; mb < slice_width; mb++) {

            idx = -1;

            do {

                GET_CODE(val, skip_type, skip_bits);

                idx += val + 1;

                if (idx >= num_coeffs)

                    break;

                GET_CODE(val, coeff_type, coeff_bits);

                val++;

                if (val >= 0x10000)

                    return AVERROR_INVALIDDATA;

                dst[scan[idx]] = val;

            } while (idx < num_coeffs - 1);

            dst += num_coeffs;

        }

    } else {

        for (mb = 0; mb < slice_width; mb++) {

            for (idx = 0; idx < num_coeffs; idx++) {

                GET_CODE(val, coeff_type, coeff_bits);

                if (val >= 0x10000)

                    return AVERROR_INVALIDDATA;

                dst[scan[idx]] = val;

            }

            dst += num_coeffs;

        }

    }

    return 0;

}


void fpu_dump_state(CPUState *env, FILE *f,

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

                    int flags)

{

    int i;

    int is_fpu64 = !!(env->CP0_Status & (1 << CP0St_FR));

#define printfpr(fp)                                                        \

    do {                                                                    \

        if (is_fpu64)                                                       \

            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \

                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \

                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \

        else {                                                              \

            fpr_t tmp;                                                      \

            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \

            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \

            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \

                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \

                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \

        }                                                                   \

    } while(0)

    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",

                env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));

    fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);

    fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);

    fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);

    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {

        fpu_fprintf(f, "%3s: ", fregnames[i]);

        printfpr(&env->fpr[i]);

    }

#undef printfpr

}


static int sdp_probe(AVProbeData *p1)

{

    const char *p = p1->buf, *p_end = p1->buf + p1->buf_size;

    /* we look for a line beginning "c=IN IP4" */

    while (p < p_end && *p != '\0') {

        if (p + sizeof("c=IN IP4") - 1 < p_end && av_strstart(p, "c=IN IP4", NULL))

            return AVPROBE_SCORE_MAX / 2;

        while(p < p_end - 1 && *p != '\n') p++;

        if (++p >= p_end)

            break;

        if (*p == '\r')

            p++;

    }

    return 0;

}


uint32_t HELPER(mvcos)(CPUS390XState *env, uint64_t dest, uint64_t src,

                       uint64_t len)

{

    const uint8_t psw_key = (env->psw.mask & PSW_MASK_KEY) >> PSW_SHIFT_KEY;

    const uint8_t psw_as = (env->psw.mask & PSW_MASK_ASC) >> PSW_SHIFT_ASC;

    const uint64_t r0 = env->regs[0];

    const uintptr_t ra = GETPC();

    CPUState *cs = CPU(s390_env_get_cpu(env));

    uint8_t dest_key, dest_as, dest_k, dest_a;

    uint8_t src_key, src_as, src_k, src_a;

    uint64_t val;

    int cc = 0;

    HELPER_LOG("%s dest %" PRIx64 ", src %" PRIx64 ", len %" PRIx64 "\n",

               __func__, dest, src, len);

    if (!(env->psw.mask & PSW_MASK_DAT)) {

        cpu_restore_state(cs, ra);

        program_interrupt(env, PGM_SPECIAL_OP, 6);

    }

    /* OAC (operand access control) for the first operand -> dest */

    val = (r0 & 0xffff0000ULL) >> 16;

    dest_key = (val >> 12) & 0xf;

    dest_as = (val >> 6) & 0x3;

    dest_k = (val >> 1) & 0x1;

    dest_a = val & 0x1;

    /* OAC (operand access control) for the second operand -> src */

    val = (r0 & 0x0000ffffULL);

    src_key = (val >> 12) & 0xf;

    src_as = (val >> 6) & 0x3;

    src_k = (val >> 1) & 0x1;

    src_a = val & 0x1;

    if (!dest_k) {

        dest_key = psw_key;

    }

    if (!src_k) {

        src_key = psw_key;

    }

    if (!dest_a) {

        dest_as = psw_as;

    }

    if (!src_a) {

        src_as = psw_as;

    }

    if (dest_a && dest_as == AS_HOME && (env->psw.mask & PSW_MASK_PSTATE)) {

        cpu_restore_state(cs, ra);

        program_interrupt(env, PGM_SPECIAL_OP, 6);

    }

    if (!(env->cregs[0] & CR0_SECONDARY) &&

        (dest_as == AS_SECONDARY || src_as == AS_SECONDARY)) {

        cpu_restore_state(cs, ra);

        program_interrupt(env, PGM_SPECIAL_OP, 6);

    }

    if (!psw_key_valid(env, dest_key) || !psw_key_valid(env, src_key)) {

        cpu_restore_state(cs, ra);

        program_interrupt(env, PGM_PRIVILEGED, 6);

    }

    len = wrap_length(env, len);

    if (len > 4096) {

        cc = 3;

        len = 4096;

    }

    /* FIXME: AR-mode and proper problem state mode (using PSW keys) missing */

    if (src_as == AS_ACCREG || dest_as == AS_ACCREG ||

        (env->psw.mask & PSW_MASK_PSTATE)) {

        qemu_log_mask(LOG_UNIMP, "%s: AR-mode and PSTATE support missing\n",

                      __func__);

        cpu_restore_state(cs, ra);

        program_interrupt(env, PGM_ADDRESSING, 6);

    }

    /* FIXME: a) LAP

     *        b) Access using correct keys

     *        c) AR-mode

     */

#ifdef CONFIG_USER_ONLY

    /* psw keys are never valid in user mode, we will never reach this */

    g_assert_not_reached();

#else

    fast_memmove_as(env, dest, src, len, dest_as, src_as, ra);

#endif

    return cc;

}


static void unrealize(DeviceState *d, Error **errp)

{

    sPAPRDRConnector *drc = SPAPR_DR_CONNECTOR(d);

    Object *root_container;

    char name[256];

    Error *err = NULL;

    trace_spapr_drc_unrealize(spapr_drc_index(drc));

    root_container = container_get(object_get_root(), DRC_CONTAINER_PATH);

    snprintf(name, sizeof(name), "%x", spapr_drc_index(drc));

    object_property_del(root_container, name, &err);

    if (err) {

        error_report_err(err);

        object_unref(OBJECT(drc));

    }

}


static void nbd_co_receive_reply(NBDClientSession *s,

                                 NBDRequest *request,

                                 NBDReply *reply,

                                 QEMUIOVector *qiov)

{

    int ret;

    /* Wait until we're woken up by nbd_read_reply_entry.  */

    qemu_coroutine_yield();

    *reply = s->reply;

    if (reply->handle != request->handle ||

        !s->ioc) {

        reply->error = EIO;

    } else {

        if (qiov && reply->error == 0) {

            ret = nbd_wr_syncv(s->ioc, qiov->iov, qiov->niov, request->len,

                               true, NULL);

            if (ret != request->len) {

                reply->error = EIO;

            }

        }

        /* Tell the read handler to read another header.  */

        s->reply.handle = 0;

    }

}


void decode_mvs(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y)

{

    VP8Macroblock *mb_edge[3] = { mb + 2 /* top */,

                                  mb - 1 /* left */,

                                  mb + 1 /* top-left */ };

    enum { CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV };

    enum { EDGE_TOP, EDGE_LEFT, EDGE_TOPLEFT };

    int idx = CNT_ZERO;

    int cur_sign_bias = s->sign_bias[mb->ref_frame];

    int *sign_bias = s->sign_bias;

    VP56mv near_mv[4];

    uint8_t cnt[4] = { 0 };

    VP56RangeCoder *c = &s->c;

    AV_ZERO32(&near_mv[0]);

    AV_ZERO32(&near_mv[1]);

    AV_ZERO32(&near_mv[2]);

    /* Process MB on top, left and top-left */

    #define MV_EDGE_CHECK(n)\

    {\

        VP8Macroblock *edge = mb_edge[n];\

        int edge_ref = edge->ref_frame;\

        if (edge_ref != VP56_FRAME_CURRENT) {\

            uint32_t mv = AV_RN32A(&edge->mv);\

            if (mv) {\

                if (cur_sign_bias != sign_bias[edge_ref]) {\

                    /* SWAR negate of the values in mv. */\

                    mv = ~mv;\

                    mv = ((mv&0x7fff7fff) + 0x00010001) ^ (mv&0x80008000);\

                }\

                if (!n || mv != AV_RN32A(&near_mv[idx]))\

                    AV_WN32A(&near_mv[++idx], mv);\

                cnt[idx]      += 1 + (n != 2);\

            } else\

                cnt[CNT_ZERO] += 1 + (n != 2);\

        }\

    }

    MV_EDGE_CHECK(0)

    MV_EDGE_CHECK(1)

    MV_EDGE_CHECK(2)

    mb->partitioning = VP8_SPLITMVMODE_NONE;

    if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_ZERO]][0])) {

        mb->mode = VP8_MVMODE_MV;

        /* If we have three distinct MVs, merge first and last if they're the same */

        if (cnt[CNT_SPLITMV] && AV_RN32A(&near_mv[1+EDGE_TOP]) == AV_RN32A(&near_mv[1+EDGE_TOPLEFT]))

            cnt[CNT_NEAREST] += 1;

        /* Swap near and nearest if necessary */

        if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) {

            FFSWAP(uint8_t,     cnt[CNT_NEAREST],     cnt[CNT_NEAR]);

            FFSWAP( VP56mv, near_mv[CNT_NEAREST], near_mv[CNT_NEAR]);

        }

        if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAREST]][1])) {

            if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_NEAR]][2])) {

                /* Choose the best mv out of 0,0 and the nearest mv */

                clamp_mv(s, &mb->mv, &near_mv[CNT_ZERO + (cnt[CNT_NEAREST] >= cnt[CNT_ZERO])]);

                cnt[CNT_SPLITMV] = ((mb_edge[EDGE_LEFT]->mode    == VP8_MVMODE_SPLIT) +

                                    (mb_edge[EDGE_TOP]->mode     == VP8_MVMODE_SPLIT)) * 2 +

                                    (mb_edge[EDGE_TOPLEFT]->mode == VP8_MVMODE_SPLIT);

                if (vp56_rac_get_prob_branchy(c, vp8_mode_contexts[cnt[CNT_SPLITMV]][3])) {

                    mb->mode = VP8_MVMODE_SPLIT;

                    mb->mv = mb->bmv[decode_splitmvs(s, c, mb) - 1];

                } else {

                    mb->mv.y += read_mv_component(c, s->prob->mvc[0]);

                    mb->mv.x += read_mv_component(c, s->prob->mvc[1]);

                    mb->bmv[0] = mb->mv;

                }

            } else {

                clamp_mv(s, &mb->mv, &near_mv[CNT_NEAR]);

                mb->bmv[0] = mb->mv;

            }

        } else {

            clamp_mv(s, &mb->mv, &near_mv[CNT_NEAREST]);

            mb->bmv[0] = mb->mv;

        }

    } else {

        mb->mode = VP8_MVMODE_ZERO;

        AV_ZERO32(&mb->mv);

        mb->bmv[0] = mb->mv;

    }

}


int ff_h264_alloc_tables(H264Context *h){

    MpegEncContext * const s = &h->s;

    const int big_mb_num= s->mb_stride * (s->mb_height+1);

    int x,y;

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->intra4x4_pred_mode, big_mb_num * 8  * sizeof(uint8_t), fail)

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->non_zero_count    , big_mb_num * 16 * sizeof(uint8_t), fail)

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->slice_table_base  , (big_mb_num+s->mb_stride) * sizeof(*h->slice_table_base), fail)

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->cbp_table, big_mb_num * sizeof(uint16_t), fail)

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t), fail)

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t), fail);

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t), fail);

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->direct_table, 32*big_mb_num * sizeof(uint8_t) , fail);

    memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride)  * sizeof(*h->slice_table_base));

    h->slice_table= h->slice_table_base + s->mb_stride*2 + 1;

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b_xy  , big_mb_num * sizeof(uint32_t), fail);

    FF_ALLOCZ_OR_GOTO(h->s.avctx, h->mb2b8_xy , big_mb_num * sizeof(uint32_t), fail);

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

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

            const int mb_xy= x + y*s->mb_stride;

            const int b_xy = 4*x + 4*y*h->b_stride;

            const int b8_xy= 2*x + 2*y*h->b8_stride;

            h->mb2b_xy [mb_xy]= b_xy;

            h->mb2b8_xy[mb_xy]= b8_xy;

        }

    }

    s->obmc_scratchpad = NULL;

    if(!h->dequant4_coeff[0])

        init_dequant_tables(h);

    return 0;

fail:

    free_tables(h);

    return -1;

}


void pcie_cap_slot_hotplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev,

                              Error **errp)

{

    uint8_t *exp_cap;

    PCIDevice *pci_dev = PCI_DEVICE(dev);

    pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp);

    /* Don't send event when device is enabled during qemu machine creation:

     * it is present on boot, no hotplug event is necessary. We do send an

     * event when the device is disabled later. */

    if (!dev->hotplugged) {

        pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,

                                   PCI_EXP_SLTSTA_PDS);

        return;

    }

    /* TODO: multifunction hot-plug.

     * Right now, only a device of function = 0 is allowed to be

     * hot plugged/unplugged.

     */

    assert(PCI_FUNC(pci_dev->devfn) == 0);

    pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA,

                               PCI_EXP_SLTSTA_PDS);

    pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC);

}


void do_info_snapshots(Monitor *mon)

{

    DriveInfo *dinfo;

    BlockDriverState *bs, *bs1;

    QEMUSnapshotInfo *sn_tab, *sn;

    int nb_sns, i;

    char buf[256];

    bs = get_bs_snapshots();

    if (!bs) {

        monitor_printf(mon, "No available block device supports snapshots\n");

        return;

    }

    monitor_printf(mon, "Snapshot devices:");

    TAILQ_FOREACH(dinfo, &drives, next) {

        bs1 = dinfo->bdrv;

        if (bdrv_has_snapshot(bs1)) {

            if (bs == bs1)

                monitor_printf(mon, " %s", bdrv_get_device_name(bs1));

        }

    }

    monitor_printf(mon, "\n");

    nb_sns = bdrv_snapshot_list(bs, &sn_tab);

    if (nb_sns < 0) {

        monitor_printf(mon, "bdrv_snapshot_list: error %d\n", nb_sns);

        return;

    }

    monitor_printf(mon, "Snapshot list (from %s):\n",

                   bdrv_get_device_name(bs));

    monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), NULL));

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

        sn = &sn_tab[i];

        monitor_printf(mon, "%s\n", bdrv_snapshot_dump(buf, sizeof(buf), sn));

    }

    qemu_free(sn_tab);

}


static SCSIRequest *scsi_block_new_request(SCSIDevice *d, uint32_t tag,

                                           uint32_t lun, uint8_t *buf,

                                           void *hba_private)

{

    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d);

    switch (buf[0]) {

    case READ_6:

    case READ_10:

    case READ_12:

    case READ_16:

    case VERIFY_10:

    case VERIFY_12:

    case VERIFY_16:

    case WRITE_6:

    case WRITE_10:

    case WRITE_12:

    case WRITE_16:

    case WRITE_VERIFY_10:

    case WRITE_VERIFY_12:

    case WRITE_VERIFY_16:

        /* If we are not using O_DIRECT, we might read stale data from the

	 * host cache if writes were made using other commands than these

	 * ones (such as WRITE SAME or EXTENDED COPY, etc.).  So, without

	 * O_DIRECT everything must go through SG_IO.

         */

        if (bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE) {

            break;

        }

        /* MMC writing cannot be done via pread/pwrite, because it sometimes

         * involves writing beyond the maximum LBA or to negative LBA (lead-in).

         * And once you do these writes, reading from the block device is

         * unreliable, too.  It is even possible that reads deliver random data

         * from the host page cache (this is probably a Linux bug).

         *

         * We might use scsi_disk_reqops as long as no writing commands are

         * seen, but performance usually isn't paramount on optical media.  So,

         * just make scsi-block operate the same as scsi-generic for them.

         */

        if (s->qdev.type == TYPE_ROM) {

            break;

	}

        return scsi_req_alloc(&scsi_disk_reqops, &s->qdev, tag, lun,

                              hba_private);

    }

    return scsi_req_alloc(&scsi_generic_req_ops, &s->qdev, tag, lun,

                          hba_private);

}


static void init_excp_4xx_softmmu (CPUPPCState *env)

{

#if !defined(CONFIG_USER_ONLY)

    env->excp_vectors[POWERPC_EXCP_CRITICAL] = 0x00000100;

    env->excp_vectors[POWERPC_EXCP_MCHECK]   = 0x00000200;

    env->excp_vectors[POWERPC_EXCP_DSI]      = 0x00000300;

    env->excp_vectors[POWERPC_EXCP_ISI]      = 0x00000400;

    env->excp_vectors[POWERPC_EXCP_EXTERNAL] = 0x00000500;

    env->excp_vectors[POWERPC_EXCP_ALIGN]    = 0x00000600;

    env->excp_vectors[POWERPC_EXCP_PROGRAM]  = 0x00000700;

    env->excp_vectors[POWERPC_EXCP_SYSCALL]  = 0x00000C00;

    env->excp_vectors[POWERPC_EXCP_PIT]      = 0x00001000;

    env->excp_vectors[POWERPC_EXCP_FIT]      = 0x00001010;

    env->excp_vectors[POWERPC_EXCP_WDT]      = 0x00001020;

    env->excp_vectors[POWERPC_EXCP_DTLB]     = 0x00001100;

    env->excp_vectors[POWERPC_EXCP_ITLB]     = 0x00001200;

    env->excp_vectors[POWERPC_EXCP_DEBUG]    = 0x00002000;

    env->excp_prefix = 0x00000000;

    env->ivor_mask = 0x0000FFF0;

    env->ivpr_mask = 0xFFFF0000;

    /* Hardware reset vector */

    env->hreset_vector = 0xFFFFFFFCUL;

#endif

}


static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt)

{

    KLVPacket klv;

    while (!s->pb->eof_reached) {

        if (klv_read_packet(&klv, s->pb) < 0)

            return -1;

        PRINT_KEY(s, "read packet", klv.key);

        av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset);

        if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) {

            int res = mxf_decrypt_triplet(s, pkt, &klv);

            if (res < 0) {

                av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n");

                return -1;

            }

            return 0;

        }

        if (IS_KLV_KEY(klv.key, mxf_essence_element_key)) {

            int index = mxf_get_stream_index(s, &klv);

            if (index < 0) {

                av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12));

                goto skip;

            }

            if (s->streams[index]->discard == AVDISCARD_ALL)

                goto skip;

            /* check for 8 channels AES3 element */

            if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) {

                if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) {

                    av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n");

                    return -1;

                }

            } else

                av_get_packet(s->pb, pkt, klv.length);

            pkt->stream_index = index;

            pkt->pos = klv.offset;

            return 0;

        } else

        skip:

            avio_skip(s->pb, klv.length);

    }

    return AVERROR_EOF;

}


int cpu_get_dump_info(ArchDumpInfo *info)

{

    return -1;

}


void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst,

                           const int dst_pitch, const int num_bands)

{

    int             x, y, indx, b0, b1, b2, b3, p0, p1, p2, p3;

    const IDWTELEM *b0_ptr, *b1_ptr, *b2_ptr, *b3_ptr;

    int32_t         pitch;

    /* all bands should have the same pitch */

    pitch = plane->bands[0].pitch;

    /* get pointers to the wavelet bands */

    b0_ptr = plane->bands[0].buf;

    b1_ptr = plane->bands[1].buf;

    b2_ptr = plane->bands[2].buf;

    b3_ptr = plane->bands[3].buf;

    for (y = 0; y < plane->height; y += 2) {

        for (x = 0, indx = 0; x < plane->width; x += 2, indx++) {

            /* load coefficients */

            b0 = b0_ptr[indx]; //should be: b0 = (num_bands > 0) ? b0_ptr[indx] : 0;

            b1 = b1_ptr[indx]; //should be: b1 = (num_bands > 1) ? b1_ptr[indx] : 0;

            b2 = b2_ptr[indx]; //should be: b2 = (num_bands > 2) ? b2_ptr[indx] : 0;

            b3 = b3_ptr[indx]; //should be: b3 = (num_bands > 3) ? b3_ptr[indx] : 0;

            /* haar wavelet recomposition */

            p0 = (b0 + b1 + b2 + b3 + 2) >> 2;

            p1 = (b0 + b1 - b2 - b3 + 2) >> 2;

            p2 = (b0 - b1 + b2 - b3 + 2) >> 2;

            p3 = (b0 - b1 - b2 + b3 + 2) >> 2;

            /* bias, convert and output four pixels */

            dst[x]                 = av_clip_uint8(p0 + 128);

            dst[x + 1]             = av_clip_uint8(p1 + 128);

            dst[dst_pitch + x]     = av_clip_uint8(p2 + 128);

            dst[dst_pitch + x + 1] = av_clip_uint8(p3 + 128);

        }// for x

        dst += dst_pitch << 1;

        b0_ptr += pitch;

        b1_ptr += pitch;

        b2_ptr += pitch;

        b3_ptr += pitch;

    }// for y

}


void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,

                   int asi, int size)

{

#ifdef DEBUG_ASI

    dump_asi("write", addr, asi, size, val);

#endif

    if (asi < 0x80) {

        helper_raise_exception(env, TT_PRIV_ACT);

    }

    helper_check_align(env, addr, size - 1);

    addr = asi_address_mask(env, asi, addr);

    /* Convert to little endian */

    switch (asi) {

    case 0x88: /* Primary LE */

    case 0x89: /* Secondary LE */

        switch (size) {

        case 2:

            val = bswap16(val);

            break;

        case 4:

            val = bswap32(val);

            break;

        case 8:

            val = bswap64(val);

            break;

        default:

            break;

        }

    default:

        break;

    }

    switch (asi) {

    case 0x80: /* Primary */

    case 0x88: /* Primary LE */

        {

            switch (size) {

            case 1:

                stb_raw(addr, val);

                break;

            case 2:

                stw_raw(addr, val);

                break;

            case 4:

                stl_raw(addr, val);

                break;

            case 8:

            default:

                stq_raw(addr, val);

                break;

            }

        }

        break;

    case 0x81: /* Secondary */

    case 0x89: /* Secondary LE */

        /* XXX */

        return;

    case 0x82: /* Primary no-fault, RO */

    case 0x83: /* Secondary no-fault, RO */

    case 0x8a: /* Primary no-fault LE, RO */

    case 0x8b: /* Secondary no-fault LE, RO */

    default:

        helper_raise_exception(env, TT_DATA_ACCESS);

        return;

    }

}


static ssize_t sdp_svc_search_attr_get(struct bt_l2cap_sdp_state_s *sdp,

                uint8_t *rsp, const uint8_t *req, ssize_t len)

{

    ssize_t seqlen;

    int i, j, start, end, max;

    struct sdp_service_record_s *record;

    uint8_t *lst;

    /* Perform the search */

    for (i = 0; i < sdp->services; i ++) {

        sdp->service_list[i].match = 0;

            for (j = 0; j < sdp->service_list[i].attributes; j ++)

                sdp->service_list[i].attribute_list[j].match = 0;

    }

    if (len < 1)

        return -SDP_INVALID_SYNTAX;

    if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {

        seqlen = sdp_datalen(&req, &len);

        if (seqlen < 3 || len < seqlen)

            return -SDP_INVALID_SYNTAX;

        len -= seqlen;

        while (seqlen)

            if (sdp_svc_match(sdp, &req, &seqlen))

                return -SDP_INVALID_SYNTAX;

    } else if (sdp_svc_match(sdp, &req, &seqlen))

        return -SDP_INVALID_SYNTAX;

    if (len < 3)

        return -SDP_INVALID_SYNTAX;

    max = (req[0] << 8) | req[1];

    req += 2;

    len -= 2;

    if (max < 0x0007)

        return -SDP_INVALID_SYNTAX;

    if ((*req & ~SDP_DSIZE_MASK) == SDP_DTYPE_SEQ) {

        seqlen = sdp_datalen(&req, &len);

        if (seqlen < 3 || len < seqlen)

            return -SDP_INVALID_SYNTAX;

        len -= seqlen;

        while (seqlen)

            if (sdp_svc_attr_match(sdp, &req, &seqlen))

                return -SDP_INVALID_SYNTAX;

    } else if (sdp_svc_attr_match(sdp, &req, &seqlen))

        return -SDP_INVALID_SYNTAX;

    if (len < 1)

        return -SDP_INVALID_SYNTAX;

    if (*req) {

        if (len <= sizeof(int))

            return -SDP_INVALID_SYNTAX;

        len -= sizeof(int);

        memcpy(&start, req + 1, sizeof(int));

    } else

        start = 0;

    if (len > 1)

        return -SDP_INVALID_SYNTAX;

    /* Output the results */

    /* This assumes empty attribute lists are never to be returned even

     * for matching Service Records.  In practice this shouldn't happen

     * as the requestor will usually include the always present

     * ServiceRecordHandle AttributeID in AttributeIDList.  */

    lst = rsp + 2;

    max = MIN(max, MAX_RSP_PARAM_SIZE);

    len = 3 - start;

    end = 0;

    for (i = 0; i < sdp->services; i ++)

        if ((record = &sdp->service_list[i])->match) {

            len += 3;

            seqlen = len;

            for (j = 0; j < record->attributes; j ++)

                if (record->attribute_list[j].match) {

                    if (len >= 0)

                        if (len + record->attribute_list[j].len < max) {

                            memcpy(lst + len, record->attribute_list[j].pair,

                                            record->attribute_list[j].len);

                            end = len + record->attribute_list[j].len;

                        }

                    len += record->attribute_list[j].len;

                }

            if (seqlen == len)

                len -= 3;

            else if (seqlen >= 3 && seqlen < max) {

                lst[seqlen - 3] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;

                lst[seqlen - 2] = (len - seqlen) >> 8;

                lst[seqlen - 1] = (len - seqlen) & 0xff;

            }

        }

    if (len == 3 - start)

        len -= 3;

    else if (0 >= start) {

       lst[0] = SDP_DTYPE_SEQ | SDP_DSIZE_NEXT2;

       lst[1] = (len + start - 3) >> 8;

       lst[2] = (len + start - 3) & 0xff;

    }

    rsp[0] = end >> 8;

    rsp[1] = end & 0xff;

    if (end < len) {

        len = end + start;

        lst[end ++] = sizeof(int);

        memcpy(lst + end, &len, sizeof(int));

        end += sizeof(int);

    } else

        lst[end ++] = 0;

    return end + 2;

}


static void mcf_intc_write(void *opaque, target_phys_addr_t addr,

                           uint64_t val, unsigned size)

{

    int offset;

    mcf_intc_state *s = (mcf_intc_state *)opaque;

    offset = addr & 0xff;

    if (offset >= 0x40 && offset < 0x80) {

        int n = offset - 0x40;

        s->icr[n] = val;

        if (val == 0)

            s->enabled &= ~(1ull << n);

        else

            s->enabled |= (1ull << n);

        mcf_intc_update(s);

        return;

    }

    switch (offset) {

    case 0x00: case 0x04:

        /* Ignore IPR writes.  */

        return;

    case 0x08:

        s->imr = (s->imr & 0xffffffff) | ((uint64_t)val << 32);

        break;

    case 0x0c:

        s->imr = (s->imr & 0xffffffff00000000ull) | (uint32_t)val;

        break;

    default:

        hw_error("mcf_intc_write: Bad write offset %d\n", offset);

        break;

    }

    mcf_intc_update(s);

}


static int cow_write(BlockDriverState *bs, int64_t sector_num,

                     const uint8_t *buf, int nb_sectors)

{

    BDRVCowState *s = bs->opaque;

    int ret;

    ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512,

                      buf, nb_sectors * 512);

    if (ret < 0) {

        return ret;

    }

    return cow_update_bitmap(bs, sector_num, nb_sectors);

}


static int find_smallest_bounding_rectangle(AVSubtitle *s)

{

    uint8_t transp_color[256] = { 0 };

    int y1, y2, x1, x2, y, w, h, i;

    uint8_t *bitmap;

    if (s->num_rects == 0 || s->rects == NULL || s->rects[0]->w <= 0 || s->rects[0]->h <= 0)

        return 0;

    for(i = 0; i < s->rects[0]->nb_colors; i++) {

        if ((((uint32_t*)s->rects[0]->pict.data[1])[i] >> 24) == 0)

            transp_color[i] = 1;

    }

    y1 = 0;

    while (y1 < s->rects[0]->h && is_transp(s->rects[0]->pict.data[0] + y1 * s->rects[0]->pict.linesize[0],

                                  1, s->rects[0]->w, transp_color))

        y1++;

    if (y1 == s->rects[0]->h) {

        av_freep(&s->rects[0]->pict.data[0]);

        s->rects[0]->w = s->rects[0]->h = 0;

        return 0;

    }

    y2 = s->rects[0]->h - 1;

    while (y2 > 0 && is_transp(s->rects[0]->pict.data[0] + y2 * s->rects[0]->pict.linesize[0], 1,

                               s->rects[0]->w, transp_color))

        y2--;

    x1 = 0;

    while (x1 < (s->rects[0]->w - 1) && is_transp(s->rects[0]->pict.data[0] + x1, s->rects[0]->pict.linesize[0],

                                        s->rects[0]->h, transp_color))

        x1++;

    x2 = s->rects[0]->w - 1;

    while (x2 > 0 && is_transp(s->rects[0]->pict.data[0] + x2, s->rects[0]->pict.linesize[0], s->rects[0]->h,

                                  transp_color))

        x2--;

    w = x2 - x1 + 1;

    h = y2 - y1 + 1;

    bitmap = av_malloc(w * h);

    if (!bitmap)

        return 1;

    for(y = 0; y < h; y++) {

        memcpy(bitmap + w * y, s->rects[0]->pict.data[0] + x1 + (y1 + y) * s->rects[0]->pict.linesize[0], w);

    }

    av_freep(&s->rects[0]->pict.data[0]);

    s->rects[0]->pict.data[0] = bitmap;

    s->rects[0]->pict.linesize[0] = w;

    s->rects[0]->w = w;

    s->rects[0]->h = h;

    s->rects[0]->x += x1;

    s->rects[0]->y += y1;

    return 1;

}


QemuConsole *qemu_console_lookup_by_device(DeviceState *dev, uint32_t head)

{

    Error *local_err = NULL;

    Object *obj;

    uint32_t h;

    int i;

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

        if (!consoles[i]) {

            continue;

        }

        obj = object_property_get_link(OBJECT(consoles[i]),

                                       "device", &local_err);

        if (DEVICE(obj) != dev) {

            continue;

        }

        h = object_property_get_int(OBJECT(consoles[i]),

                                    "head", &local_err);

        if (h != head) {

            continue;

        }

        return consoles[i];

    }

    return NULL;

}


int qemu_file_get_error(QEMUFile *f)

{

    return f->last_error;

}


static av_cold int allocate_buffers(AVCodecContext *avctx)

{

    int blk, ch;

    AC3EncodeContext *s = avctx->priv_data;

    int channels = s->channels + 1; /* includes coupling channel */

    FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples),

                     alloc_fail);

    for (ch = 0; ch < s->channels; ch++) {

        FF_ALLOCZ_OR_GOTO(avctx, s->planar_samples[ch],

                          (AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),

                          alloc_fail);

    }

    FF_ALLOC_OR_GOTO(avctx, s->bap_buffer,  AC3_MAX_BLOCKS * channels *

                     AC3_MAX_COEFS * sizeof(*s->bap_buffer),  alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * channels *

                     AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * channels *

                     AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * channels *

                     AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * channels *

                     128 * sizeof(*s->grouped_exp_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * channels *

                     AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * channels *

                     64 * sizeof(*s->band_psd_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * channels *

                     64 * sizeof(*s->mask_buffer), alloc_fail);

    FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * channels *

                     AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail);

    if (s->cpl_enabled) {

        FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_exp_buffer, AC3_MAX_BLOCKS * channels *

                         16 * sizeof(*s->cpl_coord_exp_buffer), alloc_fail);

        FF_ALLOC_OR_GOTO(avctx, s->cpl_coord_mant_buffer, AC3_MAX_BLOCKS * channels *

                         16 * sizeof(*s->cpl_coord_mant_buffer), alloc_fail);

    }

    for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {

        AC3Block *block = &s->blocks[blk];

        FF_ALLOC_OR_GOTO(avctx, block->bap, channels * sizeof(*block->bap),

                         alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, channels * sizeof(*block->mdct_coef),

                          alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->exp, channels * sizeof(*block->exp),

                          alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->grouped_exp, channels * sizeof(*block->grouped_exp),

                          alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->psd, channels * sizeof(*block->psd),

                          alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->band_psd, channels * sizeof(*block->band_psd),

                          alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->mask, channels * sizeof(*block->mask),

                          alloc_fail);

        FF_ALLOCZ_OR_GOTO(avctx, block->qmant, channels * sizeof(*block->qmant),

                          alloc_fail);

        if (s->cpl_enabled) {

            FF_ALLOCZ_OR_GOTO(avctx, block->cpl_coord_exp, channels * sizeof(*block->cpl_coord_exp),

                              alloc_fail);

            FF_ALLOCZ_OR_GOTO(avctx, block->cpl_coord_mant, channels * sizeof(*block->cpl_coord_mant),

                              alloc_fail);

        }

        for (ch = 0; ch < channels; ch++) {

            /* arrangement: block, channel, coeff */

            block->bap[ch]         = &s->bap_buffer        [AC3_MAX_COEFS * (blk * channels + ch)];

            block->grouped_exp[ch] = &s->grouped_exp_buffer[128           * (blk * channels + ch)];

            block->psd[ch]         = &s->psd_buffer        [AC3_MAX_COEFS * (blk * channels + ch)];

            block->band_psd[ch]    = &s->band_psd_buffer   [64            * (blk * channels + ch)];

            block->mask[ch]        = &s->mask_buffer       [64            * (blk * channels + ch)];

            block->qmant[ch]       = &s->qmant_buffer      [AC3_MAX_COEFS * (blk * channels + ch)];

            if (s->cpl_enabled) {

                block->cpl_coord_exp[ch]  = &s->cpl_coord_exp_buffer [16  * (blk * channels + ch)];

                block->cpl_coord_mant[ch] = &s->cpl_coord_mant_buffer[16  * (blk * channels + ch)];

            }

            /* arrangement: channel, block, coeff */

            block->exp[ch]         = &s->exp_buffer        [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];

            block->mdct_coef[ch]   = &s->mdct_coef_buffer  [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];

        }

    }

    if (CONFIG_AC3ENC_FLOAT) {

        FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * channels *

                         AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail);

        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {

            AC3Block *block = &s->blocks[blk];

            FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels *

                              sizeof(*block->fixed_coef), alloc_fail);

            for (ch = 0; ch < channels; ch++)

                block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)];

        }

    } else {

        for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {

            AC3Block *block = &s->blocks[blk];

            FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, channels *

                              sizeof(*block->fixed_coef), alloc_fail);

            for (ch = 0; ch < channels; ch++)

                block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch];

        }

    }

    return 0;

alloc_fail:

    return AVERROR(ENOMEM);

}


static void platform_fixed_ioport_init(PCIXenPlatformState* s)

{

    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 4, platform_fixed_ioport_writel, s);

    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_writew, s);

    register_ioport_write(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_writeb, s);

    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 2, platform_fixed_ioport_readw, s);

    register_ioport_read(XEN_PLATFORM_IOPORT, 16, 1, platform_fixed_ioport_readb, s);

}


uint64_t helper_fctidz(CPUPPCState *env, uint64_t arg)

{

    CPU_DoubleU farg;

    farg.ll = arg;

    if (unlikely(float64_is_signaling_nan(farg.d))) {

        /* sNaN conversion */

        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN |

                                        POWERPC_EXCP_FP_VXCVI);

    } else if (unlikely(float64_is_quiet_nan(farg.d) ||

                        float64_is_infinity(farg.d))) {

        /* qNan / infinity conversion */

        farg.ll = fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI);

    } else {

        farg.ll = float64_to_int64_round_to_zero(farg.d, &env->fp_status);

    }

    return farg.ll;

}


void g_free(void *ptr)

{

    __coverity_free__(ptr);

    __coverity_mark_as_afm_freed__(ptr, AFM_free);

}


static int load_multiboot(void *fw_cfg,

                          FILE *f,

                          const char *kernel_filename,

                          const char *initrd_filename,

                          const char *kernel_cmdline,

                          uint8_t *header)

{

    int i, t, is_multiboot = 0;

    uint32_t flags = 0;

    uint32_t mh_entry_addr;

    uint32_t mh_load_addr;

    uint32_t mb_kernel_size;

    uint32_t mmap_addr = MULTIBOOT_STRUCT_ADDR;

    uint32_t mb_bootinfo = MULTIBOOT_STRUCT_ADDR + 0x500;

    uint32_t mb_cmdline = mb_bootinfo + 0x200;

    uint32_t mb_mod_end;

    /* Ok, let's see if it is a multiboot image.

       The header is 12x32bit long, so the latest entry may be 8192 - 48. */

    for (i = 0; i < (8192 - 48); i += 4) {

        if (ldl_p(header+i) == 0x1BADB002) {

            uint32_t checksum = ldl_p(header+i+8);

            flags = ldl_p(header+i+4);

            checksum += flags;

            checksum += (uint32_t)0x1BADB002;

            if (!checksum) {

                is_multiboot = 1;

                break;

            }

        }

    }

    if (!is_multiboot)

        return 0; /* no multiboot */

#ifdef DEBUG_MULTIBOOT

    fprintf(stderr, "qemu: I believe we found a multiboot image!\n");

#endif

    if (flags & 0x00000004) { /* MULTIBOOT_HEADER_HAS_VBE */

        fprintf(stderr, "qemu: multiboot knows VBE. we don't.\n");

    }

    if (!(flags & 0x00010000)) { /* MULTIBOOT_HEADER_HAS_ADDR */

        uint64_t elf_entry;

        int kernel_size;

        fclose(f);

        kernel_size = load_elf(kernel_filename, 0, &elf_entry, NULL, NULL,

                               0, ELF_MACHINE, 0);

        if (kernel_size < 0) {

            fprintf(stderr, "Error while loading elf kernel\n");

            exit(1);

        }

        mh_load_addr = mh_entry_addr = elf_entry;

        mb_kernel_size = kernel_size;

#ifdef DEBUG_MULTIBOOT

        fprintf(stderr, "qemu: loading multiboot-elf kernel (%#x bytes) with entry %#zx\n",

                mb_kernel_size, (size_t)mh_entry_addr);

#endif

    } else {

        /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_ADDR. */

        uint32_t mh_header_addr = ldl_p(header+i+12);

        mh_load_addr = ldl_p(header+i+16);

#ifdef DEBUG_MULTIBOOT

        uint32_t mh_load_end_addr = ldl_p(header+i+20);

        uint32_t mh_bss_end_addr = ldl_p(header+i+24);

#endif

        uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);

        mh_entry_addr = ldl_p(header+i+28);

        mb_kernel_size = get_file_size(f) - mb_kernel_text_offset;

        /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE.

        uint32_t mh_mode_type = ldl_p(header+i+32);

        uint32_t mh_width = ldl_p(header+i+36);

        uint32_t mh_height = ldl_p(header+i+40);

        uint32_t mh_depth = ldl_p(header+i+44); */

#ifdef DEBUG_MULTIBOOT

        fprintf(stderr, "multiboot: mh_header_addr = %#x\n", mh_header_addr);

        fprintf(stderr, "multiboot: mh_load_addr = %#x\n", mh_load_addr);

        fprintf(stderr, "multiboot: mh_load_end_addr = %#x\n", mh_load_end_addr);

        fprintf(stderr, "multiboot: mh_bss_end_addr = %#x\n", mh_bss_end_addr);

#endif

        fseek(f, mb_kernel_text_offset, SEEK_SET);

#ifdef DEBUG_MULTIBOOT

        fprintf(stderr, "qemu: loading multiboot kernel (%#x bytes) at %#x\n",

                mb_kernel_size, mh_load_addr);

#endif

        if (!fread_targphys_ok(mh_load_addr, mb_kernel_size, f)) {

            fprintf(stderr, "qemu: read error on multiboot kernel '%s' (%#x)\n",

                    kernel_filename, mb_kernel_size);

            exit(1);

        }

        fclose(f);

    }

    /* blob size is only the kernel for now */

    mb_mod_end = mh_load_addr + mb_kernel_size;

    /* load modules */

    stl_phys(mb_bootinfo + 20, 0x0); /* mods_count */

    if (initrd_filename) {

        uint32_t mb_mod_info = mb_bootinfo + 0x100;

        uint32_t mb_mod_cmdline = mb_bootinfo + 0x300;

        uint32_t mb_mod_start = mh_load_addr;

        uint32_t mb_mod_length = mb_kernel_size;

        char *next_initrd;

        char *next_space;

        int mb_mod_count = 0;

        do {

            next_initrd = strchr(initrd_filename, ',');

            if (next_initrd)

                *next_initrd = '\0';

            /* if a space comes after the module filename, treat everything

               after that as parameters */

            cpu_physical_memory_write(mb_mod_cmdline, (uint8_t*)initrd_filename,

                                      strlen(initrd_filename) + 1);

            stl_phys(mb_mod_info + 8, mb_mod_cmdline); /* string */

            mb_mod_cmdline += strlen(initrd_filename) + 1;

            if ((next_space = strchr(initrd_filename, ' ')))

                *next_space = '\0';

#ifdef DEBUG_MULTIBOOT

            printf("multiboot loading module: %s\n", initrd_filename);

#endif

            f = fopen(initrd_filename, "rb");

            if (f) {

                mb_mod_start = (mb_mod_start + mb_mod_length + (TARGET_PAGE_SIZE - 1))

                             & (TARGET_PAGE_MASK);

                mb_mod_length = get_file_size(f);

                mb_mod_end = mb_mod_start + mb_mod_length;

                if (!fread_targphys_ok(mb_mod_start, mb_mod_length, f)) {

                    fprintf(stderr, "qemu: read error on multiboot module '%s' (%#x)\n",

                            initrd_filename, mb_mod_length);

                    exit(1);

                }

                mb_mod_count++;

                stl_phys(mb_mod_info + 0, mb_mod_start);

                stl_phys(mb_mod_info + 4, mb_mod_start + mb_mod_length);

#ifdef DEBUG_MULTIBOOT

                printf("mod_start: %#x\nmod_end:   %#x\n", mb_mod_start,

                       mb_mod_start + mb_mod_length);

#endif

                stl_phys(mb_mod_info + 12, 0x0); /* reserved */

            }

            initrd_filename = next_initrd+1;

            mb_mod_info += 16;

        } while (next_initrd);

        stl_phys(mb_bootinfo + 20, mb_mod_count); /* mods_count */

        stl_phys(mb_bootinfo + 24, mb_bootinfo + 0x100); /* mods_addr */

    }

    /* Make sure we're getting kernel + modules back after reset */

    option_rom_setup_reset(mh_load_addr, mb_mod_end - mh_load_addr);

    /* Commandline support */

    stl_phys(mb_bootinfo + 16, mb_cmdline);

    t = strlen(kernel_filename);

    cpu_physical_memory_write(mb_cmdline, (uint8_t*)kernel_filename, t);

    mb_cmdline += t;

    stb_phys(mb_cmdline++, ' ');

    t = strlen(kernel_cmdline) + 1;

    cpu_physical_memory_write(mb_cmdline, (uint8_t*)kernel_cmdline, t);

    /* the kernel is where we want it to be now */

#define MULTIBOOT_FLAGS_MEMORY (1 << 0)

#define MULTIBOOT_FLAGS_BOOT_DEVICE (1 << 1)

#define MULTIBOOT_FLAGS_CMDLINE (1 << 2)

#define MULTIBOOT_FLAGS_MODULES (1 << 3)

#define MULTIBOOT_FLAGS_MMAP (1 << 6)

    stl_phys(mb_bootinfo, MULTIBOOT_FLAGS_MEMORY

                        | MULTIBOOT_FLAGS_BOOT_DEVICE

                        | MULTIBOOT_FLAGS_CMDLINE

                        | MULTIBOOT_FLAGS_MODULES

                        | MULTIBOOT_FLAGS_MMAP);

    stl_phys(mb_bootinfo + 4, 640); /* mem_lower */

    stl_phys(mb_bootinfo + 8, ram_size / 1024); /* mem_upper */

    stl_phys(mb_bootinfo + 12, 0x8001ffff); /* XXX: use the -boot switch? */

    stl_phys(mb_bootinfo + 48, mmap_addr); /* mmap_addr */

#ifdef DEBUG_MULTIBOOT

    fprintf(stderr, "multiboot: mh_entry_addr = %#x\n", mh_entry_addr);

#endif

    /* Pass variables to option rom */

    fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, mh_entry_addr);

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, mb_bootinfo);

    fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, mmap_addr);

    /* Make sure we're getting the config space back after reset */

    option_rom_setup_reset(mb_bootinfo, 0x500);

    option_rom[nb_option_roms] = "multiboot.bin";

    nb_option_roms++;

    return 1; /* yes, we are multiboot */

}


iscsi_aio_writev(BlockDriverState *bs, int64_t sector_num,

                 QEMUIOVector *qiov, int nb_sectors,

                 BlockDriverCompletionFunc *cb,

                 void *opaque)

{

    IscsiLun *iscsilun = bs->opaque;

    struct iscsi_context *iscsi = iscsilun->iscsi;

    IscsiAIOCB *acb;

    size_t size;

    uint32_t num_sectors;

    uint64_t lba;

    struct iscsi_data data;

    acb = qemu_aio_get(&iscsi_aiocb_info, bs, cb, opaque);

    trace_iscsi_aio_writev(iscsi, sector_num, nb_sectors, opaque, acb);

    acb->iscsilun = iscsilun;

    acb->qiov     = qiov;

    acb->canceled   = 0;

    acb->bh         = NULL;

    acb->status     = -EINPROGRESS;

    /* XXX we should pass the iovec to write16 to avoid the extra copy */

    /* this will allow us to get rid of 'buf' completely */

    size = nb_sectors * BDRV_SECTOR_SIZE;

    data.size = MIN(size, acb->qiov->size);

    /* if the iovec only contains one buffer we can pass it directly */

    if (acb->qiov->niov == 1) {

        acb->buf = NULL;

        data.data = acb->qiov->iov[0].iov_base;

    } else {

        acb->buf = g_malloc(data.size);

        qemu_iovec_to_buf(acb->qiov, 0, acb->buf, data.size);

        data.data = acb->buf;

    }

    acb->task = malloc(sizeof(struct scsi_task));

    if (acb->task == NULL) {

        error_report("iSCSI: Failed to allocate task for scsi WRITE16 "

                     "command. %s", iscsi_get_error(iscsi));

        qemu_aio_release(acb);

        return NULL;

    }

    memset(acb->task, 0, sizeof(struct scsi_task));

    acb->task->xfer_dir = SCSI_XFER_WRITE;

    acb->task->cdb_size = 16;

    acb->task->cdb[0] = 0x8a;

    lba = sector_qemu2lun(sector_num, iscsilun);

    *(uint32_t *)&acb->task->cdb[2]  = htonl(lba >> 32);

    *(uint32_t *)&acb->task->cdb[6]  = htonl(lba & 0xffffffff);

    num_sectors = size / iscsilun->block_size;

    *(uint32_t *)&acb->task->cdb[10] = htonl(num_sectors);

    acb->task->expxferlen = size;

    if (iscsi_scsi_command_async(iscsi, iscsilun->lun, acb->task,

                                 iscsi_aio_write16_cb,

                                 &data,

                                 acb) != 0) {

        scsi_free_scsi_task(acb->task);

        g_free(acb->buf);

        qemu_aio_release(acb);

        return NULL;

    }

    iscsi_set_events(iscsilun);

    return &acb->common;

}


static void build_file_streams(void)

{

    FFServerStream *stream, *stream_next;

    int i, ret;

    /* gather all streams */

    for(stream = config.first_stream; stream; stream = stream_next) {

        AVFormatContext *infile = NULL;

        stream_next = stream->next;

        if (stream->stream_type == STREAM_TYPE_LIVE &&

            !stream->feed) {

            /* the stream comes from a file */

            /* try to open the file */

            /* open stream */

            if (stream->fmt && !strcmp(stream->fmt->name, "rtp")) {

                /* specific case : if transport stream output to RTP,

                   we use a raw transport stream reader */

                av_dict_set(&stream->in_opts, "mpeg2ts_compute_pcr", "1", 0);

            }

            if (!stream->feed_filename[0]) {

                http_log("Unspecified feed file for stream '%s'\n",

                         stream->filename);

                goto fail;

            }

            http_log("Opening feed file '%s' for stream '%s'\n",

                     stream->feed_filename, stream->filename);

            if ((ret = avformat_open_input(&infile, stream->feed_filename, stream->ifmt, &stream->in_opts)) < 0) {

                http_log("Could not open '%s': %s\n", stream->feed_filename,

                         av_err2str(ret));

                /* remove stream (no need to spend more time on it) */

            fail:

                remove_stream(stream);

            } else {

                /* find all the AVStreams inside and reference them in

                   'stream' */

                if (avformat_find_stream_info(infile, NULL) < 0) {

                    http_log("Could not find codec parameters from '%s'\n",

                             stream->feed_filename);

                    avformat_close_input(&infile);

                    goto fail;

                }

                extract_mpeg4_header(infile);

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

                    add_av_stream1(stream, infile->streams[i]->codec, 1);

                avformat_close_input(&infile);

            }

        }

    }

}


int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
{
    int ret, flush = 0;
    if (pkt) {
        AVStream *st = s->streams[pkt->stream_index];
        //FIXME/XXX/HACK drop zero sized packets
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0)
            return 0;
        av_dlog(s, "av_interleaved_write_frame size:%d dts:%" PRId64 " pts:%" PRId64 "\n",
                pkt->size, pkt->dts, pkt->pts);
        if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
        if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS))
            return AVERROR(EINVAL);
    } else {
        av_dlog(s, "av_interleaved_write_frame FLUSH\n");
        flush = 1;
    }
    for (;; ) {
        AVPacket opkt;
        int ret = interleave_packet(s, &opkt, pkt, flush);
        if (ret <= 0) //FIXME cleanup needed for ret<0 ?
        ret = write_packet(s, &opkt);
        if (ret >= 0)
            s->streams[opkt.stream_index]->nb_frames++;
        av_free_packet(&opkt);
        pkt = NULL;
    }
}


static void unref_buffer(InputStream *ist, FrameBuffer *buf)

{

    av_assert0(buf->refcount);

    buf->refcount--;

    if (!buf->refcount) {

        buf->next = ist->buffer_pool;

        ist->buffer_pool = buf;

    }

}


static void loop_filter(const H264Context *h, H264SliceContext *sl, int start_x, int end_x)

{

    uint8_t *dest_y, *dest_cb, *dest_cr;

    int linesize, uvlinesize, mb_x, mb_y;

    const int end_mb_y       = sl->mb_y + FRAME_MBAFF(h);

    const int old_slice_type = sl->slice_type;

    const int pixel_shift    = h->pixel_shift;

    const int block_h        = 16 >> h->chroma_y_shift;

    if (h->postpone_filter)

        return;

    if (sl->deblocking_filter) {

        for (mb_x = start_x; mb_x < end_x; mb_x++)

            for (mb_y = end_mb_y - FRAME_MBAFF(h); mb_y <= end_mb_y; mb_y++) {

                int mb_xy, mb_type;

                mb_xy         = sl->mb_xy = mb_x + mb_y * h->mb_stride;

                sl->slice_num = h->slice_table[mb_xy];

                mb_type       = h->cur_pic.mb_type[mb_xy];

                sl->list_count = h->list_counts[mb_xy];

                if (FRAME_MBAFF(h))

                    sl->mb_mbaff               =

                    sl->mb_field_decoding_flag = !!IS_INTERLACED(mb_type);

                sl->mb_x = mb_x;

                sl->mb_y = mb_y;

                dest_y  = h->cur_pic.f->data[0] +

                          ((mb_x << pixel_shift) + mb_y * sl->linesize) * 16;

                dest_cb = h->cur_pic.f->data[1] +

                          (mb_x << pixel_shift) * (8 << CHROMA444(h)) +

                          mb_y * sl->uvlinesize * block_h;

                dest_cr = h->cur_pic.f->data[2] +

                          (mb_x << pixel_shift) * (8 << CHROMA444(h)) +

                          mb_y * sl->uvlinesize * block_h;

                // FIXME simplify above

                if (MB_FIELD(sl)) {

                    linesize   = sl->mb_linesize   = sl->linesize   * 2;

                    uvlinesize = sl->mb_uvlinesize = sl->uvlinesize * 2;

                    if (mb_y & 1) { // FIXME move out of this function?

                        dest_y  -= sl->linesize   * 15;

                        dest_cb -= sl->uvlinesize * (block_h - 1);

                        dest_cr -= sl->uvlinesize * (block_h - 1);

                    }

                } else {

                    linesize   = sl->mb_linesize   = sl->linesize;

                    uvlinesize = sl->mb_uvlinesize = sl->uvlinesize;

                }

                backup_mb_border(h, sl, dest_y, dest_cb, dest_cr, linesize,

                                 uvlinesize, 0);

                if (fill_filter_caches(h, sl, mb_type))

                    continue;

                sl->chroma_qp[0] = get_chroma_qp(h, 0, h->cur_pic.qscale_table[mb_xy]);

                sl->chroma_qp[1] = get_chroma_qp(h, 1, h->cur_pic.qscale_table[mb_xy]);

                if (FRAME_MBAFF(h)) {

                    ff_h264_filter_mb(h, sl, mb_x, mb_y, dest_y, dest_cb, dest_cr,

                                      linesize, uvlinesize);

                } else {

                    ff_h264_filter_mb_fast(h, sl, mb_x, mb_y, dest_y, dest_cb,

                                           dest_cr, linesize, uvlinesize);

                }

            }

    }

    sl->slice_type  = old_slice_type;

    sl->mb_x         = end_x;

    sl->mb_y         = end_mb_y - FRAME_MBAFF(h);

    sl->chroma_qp[0] = get_chroma_qp(h, 0, sl->qscale);

    sl->chroma_qp[1] = get_chroma_qp(h, 1, sl->qscale);

}


static int get_buffer(QEMUFile *f, void *pv, size_t size)

{

    uint8_t *v = pv;

    qemu_get_buffer(f, v, size);

    return 0;

}


static av_cold int flashsv_decode_init(AVCodecContext *avctx)

{

    FlashSVContext *s = avctx->priv_data;

    int zret; // Zlib return code

    s->avctx          = avctx;

    s->zstream.zalloc = Z_NULL;

    s->zstream.zfree  = Z_NULL;

    s->zstream.opaque = Z_NULL;

    zret = inflateInit(&s->zstream);

    if (zret != Z_OK) {

        av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret);

        return 1;

    }

    avctx->pix_fmt = AV_PIX_FMT_BGR24;

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

    return 0;

}


static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov,

                              MOVTrack *track, AVStream *st)

{

    int64_t pos = avio_tell(pb);

    avio_wb32(pb, 0); /* size */

    ffio_wfourcc(pb, "trak");

    mov_write_tkhd_tag(pb, mov, track, st);

    if (track->mode == MODE_PSP || track->flags & MOV_TRACK_CTTS ||

        (track->entry && track->cluster[0].dts) ||

        is_clcp_track(track)) {

        if (mov->use_editlist)

            mov_write_edts_tag(pb, mov, track);  // PSP Movies require edts box

        else if ((track->entry && track->cluster[0].dts) || track->mode == MODE_PSP || is_clcp_track(track))

            av_log(mov->fc, AV_LOG_WARNING,

                   "Not writing any edit list even though one would have been required\n");

    }

    if (track->tref_tag)

        mov_write_tref_tag(pb, track);

    mov_write_mdia_tag(pb, mov, track);

    if (track->mode == MODE_PSP)

        mov_write_uuid_tag_psp(pb, track); // PSP Movies require this uuid box

    if (track->tag == MKTAG('r','t','p',' '))

        mov_write_udta_sdp(pb, track);

    if (track->mode == MODE_MOV) {

        if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) {

            double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio);

            if ((0.0 != sample_aspect_ratio && 1.0 != sample_aspect_ratio)) {

                mov_write_tapt_tag(pb, track);

            }

        }

        if (is_clcp_track(track)) {

            mov_write_tapt_tag(pb, track);

        }

    }

    mov_write_track_udta_tag(pb, mov, st);

    return update_size(pb, pos);

}


const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){

    int i, si, di;

    uint8_t *dst;

    int bufidx;

//    src[0]&0x80;                //forbidden bit

    h->nal_ref_idc= src[0]>>5;

    h->nal_unit_type= src[0]&0x1F;

    src++; length--;

#if HAVE_FAST_UNALIGNED

# if HAVE_FAST_64BIT

#   define RS 7

    for(i=0; i+1<length; i+=9){

        if(!((~AV_RN64A(src+i) & (AV_RN64A(src+i) - 0x0100010001000101ULL)) & 0x8000800080008080ULL))

# else

#   define RS 3

    for(i=0; i+1<length; i+=5){

        if(!((~AV_RN32A(src+i) & (AV_RN32A(src+i) - 0x01000101U)) & 0x80008080U))

# endif

            continue;

        if(i>0 && !src[i]) i--;

        while(src[i]) i++;

#else

#   define RS 0

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

        if(src[i]) continue;

        if(i>0 && src[i-1]==0) i--;

#endif

        if(i+2<length && src[i+1]==0 && src[i+2]<=3){

            if(src[i+2]!=3){

                /* startcode, so we must be past the end */

                length=i;

            }

            break;

        }

        i-= RS;

    }

    if(i>=length-1){ //no escaped 0

        *dst_length= length;

        *consumed= length+1; //+1 for the header

        return src;

    }

    bufidx = h->nal_unit_type == NAL_DPC ? 1 : 0; // use second escape buffer for inter data

    av_fast_malloc(&h->rbsp_buffer[bufidx], &h->rbsp_buffer_size[bufidx], length+FF_INPUT_BUFFER_PADDING_SIZE);

    dst= h->rbsp_buffer[bufidx];

    if (dst == NULL){

        return NULL;

    }

//printf("decoding esc\n");

    memcpy(dst, src, i);

    si=di=i;

    while(si+2<length){

        //remove escapes (very rare 1:2^22)

        if(src[si+2]>3){

            dst[di++]= src[si++];

            dst[di++]= src[si++];

        }else if(src[si]==0 && src[si+1]==0){

            if(src[si+2]==3){ //escape

                dst[di++]= 0;

                dst[di++]= 0;

                si+=3;

                continue;

            }else //next start code

                goto nsc;

        }

        dst[di++]= src[si++];

    }

    while(si<length)

        dst[di++]= src[si++];

nsc:

    memset(dst+di, 0, FF_INPUT_BUFFER_PADDING_SIZE);

    *dst_length= di;

    *consumed= si + 1;//+1 for the header

//FIXME store exact number of bits in the getbitcontext (it is needed for decoding)

    return dst;

}


static void quit_handler(int sig)
{
    /* if we're frozen, don't exit unless we're absolutely forced to,
     * because it's basically impossible for graceful exit to complete
     * unless all log/pid files are on unfreezable filesystems. there's
     * also a very likely chance killing the agent before unfreezing
     * the filesystems is a mistake (or will be viewed as one later).
     */
    if (ga_is_frozen(ga_state)) {
        return;
    g_debug("received signal num %d, quitting", sig);
    if (g_main_loop_is_running(ga_state->main_loop)) {
        g_main_loop_quit(ga_state->main_loop);


static int tcp_close(MigrationState *s)

{

    DPRINTF("tcp_close\n");

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

        close(s->fd);

        s->fd = -1;

    }

    return 0;

}


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

                                            int nPbW, int nPbH,

                                            int log2_cb_size,

                                            int singleMCLFlag, int part_idx,

                                            int merge_idx,

                                            struct MvField mergecandlist[])

{

    HEVCLocalContext *lc   = &s->HEVClc;

    RefPicList *refPicList = s->ref->refPicList;

    MvField *tab_mvf       = s->ref->tab_mvf;

    const int min_pu_width = s->sps->min_pu_width;

    const int cand_bottom_left = lc->na.cand_bottom_left;

    const int cand_left        = lc->na.cand_left;

    const int cand_up_left     = lc->na.cand_up_left;

    const int cand_up          = lc->na.cand_up;

    const int cand_up_right    = lc->na.cand_up_right_sap;

    const int xA1    = x0 - 1;

    const int yA1    = y0 + nPbH - 1;

    const int xA1_pu = xA1 >> s->sps->log2_min_pu_size;

    const int yA1_pu = yA1 >> s->sps->log2_min_pu_size;

    const int xB1    = x0 + nPbW - 1;

    const int yB1    = y0 - 1;

    const int xB1_pu = xB1 >> s->sps->log2_min_pu_size;

    const int yB1_pu = yB1 >> s->sps->log2_min_pu_size;

    const int xB0    = x0 + nPbW;

    const int yB0    = y0 - 1;

    const int xB0_pu = xB0 >> s->sps->log2_min_pu_size;

    const int yB0_pu = yB0 >> s->sps->log2_min_pu_size;

    const int xA0    = x0 - 1;

    const int yA0    = y0 + nPbH;

    const int xA0_pu = xA0 >> s->sps->log2_min_pu_size;

    const int yA0_pu = yA0 >> s->sps->log2_min_pu_size;

    const int xB2    = x0 - 1;

    const int yB2    = y0 - 1;

    const int xB2_pu = xB2 >> s->sps->log2_min_pu_size;

    const int yB2_pu = yB2 >> s->sps->log2_min_pu_size;

    const int nb_refs = (s->sh.slice_type == P_SLICE) ?

                        s->sh.nb_refs[0] : FFMIN(s->sh.nb_refs[0], s->sh.nb_refs[1]);

    int check_MER   = 1;

    int check_MER_1 = 1;

    int zero_idx = 0;

    int nb_merge_cand = 0;

    int nb_orig_merge_cand = 0;

    int is_available_a0;

    int is_available_a1;

    int is_available_b0;

    int is_available_b1;

    int is_available_b2;

    int check_B0;

    int check_A0;

    //first left spatial merge candidate

    is_available_a1 = AVAILABLE(cand_left, A1);

    if (!singleMCLFlag && part_idx == 1 &&

        (lc->cu.part_mode == PART_Nx2N ||

         lc->cu.part_mode == PART_nLx2N ||

         lc->cu.part_mode == PART_nRx2N) ||

        isDiffMER(s, xA1, yA1, x0, y0)) {

        is_available_a1 = 0;

    }

    if (is_available_a1) {

        mergecandlist[0] = TAB_MVF_PU(A1);

        if (merge_idx == 0)

            return;

        nb_merge_cand++;

    }

    // above spatial merge candidate

    is_available_b1 = AVAILABLE(cand_up, B1);

    if (!singleMCLFlag && part_idx == 1 &&

        (lc->cu.part_mode == PART_2NxN ||

         lc->cu.part_mode == PART_2NxnU ||

         lc->cu.part_mode == PART_2NxnD) ||

        isDiffMER(s, xB1, yB1, x0, y0)) {

        is_available_b1 = 0;

    }

    if (is_available_a1 && is_available_b1)

        check_MER = !COMPARE_MV_REFIDX(B1, A1);

    if (is_available_b1 && check_MER)

        mergecandlist[nb_merge_cand++] = TAB_MVF_PU(B1);

    // above right spatial merge candidate

    check_MER = 1;

    check_B0  = PRED_BLOCK_AVAILABLE(B0);

    is_available_b0 = check_B0 && AVAILABLE(cand_up_right, B0);

    if (isDiffMER(s, xB0, yB0, x0, y0))

        is_available_b0 = 0;

    if (is_available_b1 && is_available_b0)

        check_MER = !COMPARE_MV_REFIDX(B0, B1);

    if (is_available_b0 && check_MER) {

        mergecandlist[nb_merge_cand] = TAB_MVF_PU(B0);

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

    }

    // left bottom spatial merge candidate

    check_MER = 1;

    check_A0  = PRED_BLOCK_AVAILABLE(A0);

    is_available_a0 = check_A0 && AVAILABLE(cand_bottom_left, A0);

    if (isDiffMER(s, xA0, yA0, x0, y0))

        is_available_a0 = 0;

    if (is_available_a1 && is_available_a0)

        check_MER = !COMPARE_MV_REFIDX(A0, A1);

    if (is_available_a0 && check_MER) {

        mergecandlist[nb_merge_cand] = TAB_MVF_PU(A0);

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

    }

    // above left spatial merge candidate

    check_MER = 1;

    is_available_b2 = AVAILABLE(cand_up_left, B2);

    if (isDiffMER(s, xB2, yB2, x0, y0))

        is_available_b2 = 0;

    if (is_available_a1 && is_available_b2)

        check_MER = !COMPARE_MV_REFIDX(B2, A1);

    if (is_available_b1 && is_available_b2)

        check_MER_1 = !COMPARE_MV_REFIDX(B2, B1);

    if (is_available_b2 && check_MER && check_MER_1 && nb_merge_cand != 4) {

        mergecandlist[nb_merge_cand] = TAB_MVF_PU(B2);

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

    }

    // temporal motion vector candidate

    if (s->sh.slice_temporal_mvp_enabled_flag &&

        nb_merge_cand < s->sh.max_num_merge_cand) {

        Mv mv_l0_col, mv_l1_col;

        int available_l0 = temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,

                                                       0, &mv_l0_col, 0);

        int available_l1 = (s->sh.slice_type == B_SLICE) ?

                           temporal_luma_motion_vector(s, x0, y0, nPbW, nPbH,

                                                       0, &mv_l1_col, 1) : 0;

        if (available_l0 || available_l1) {

            mergecandlist[nb_merge_cand].is_intra     = 0;

            mergecandlist[nb_merge_cand].pred_flag[0] = available_l0;

            mergecandlist[nb_merge_cand].pred_flag[1] = available_l1;

            if (available_l0) {

                mergecandlist[nb_merge_cand].mv[0]      = mv_l0_col;

                mergecandlist[nb_merge_cand].ref_idx[0] = 0;

            }

            if (available_l1) {

                mergecandlist[nb_merge_cand].mv[1]      = mv_l1_col;

                mergecandlist[nb_merge_cand].ref_idx[1] = 0;

            }

            if (merge_idx == nb_merge_cand)

                return;

            nb_merge_cand++;

        }

    }

    nb_orig_merge_cand = nb_merge_cand;

    // combined bi-predictive merge candidates  (applies for B slices)

    if (s->sh.slice_type == B_SLICE && nb_orig_merge_cand > 1 &&

        nb_orig_merge_cand < s->sh.max_num_merge_cand) {

        int comb_idx;

        for (comb_idx = 0; nb_merge_cand < s->sh.max_num_merge_cand &&

                           comb_idx < nb_orig_merge_cand * (nb_orig_merge_cand - 1); comb_idx++) {

            int l0_cand_idx = l0_l1_cand_idx[comb_idx][0];

            int l1_cand_idx = l0_l1_cand_idx[comb_idx][1];

            MvField l0_cand = mergecandlist[l0_cand_idx];

            MvField l1_cand = mergecandlist[l1_cand_idx];

            if (l0_cand.pred_flag[0] && l1_cand.pred_flag[1] &&

                (refPicList[0].list[l0_cand.ref_idx[0]] !=

                 refPicList[1].list[l1_cand.ref_idx[1]] ||

                 AV_RN32A(&l0_cand.mv[0]) != AV_RN32A(&l1_cand.mv[1]))) {

                mergecandlist[nb_merge_cand].ref_idx[0]   = l0_cand.ref_idx[0];

                mergecandlist[nb_merge_cand].ref_idx[1]   = l1_cand.ref_idx[1];

                mergecandlist[nb_merge_cand].pred_flag[0] = 1;

                mergecandlist[nb_merge_cand].pred_flag[1] = 1;

                AV_COPY32(&mergecandlist[nb_merge_cand].mv[0], &l0_cand.mv[0]);

                AV_COPY32(&mergecandlist[nb_merge_cand].mv[1], &l1_cand.mv[1]);

                mergecandlist[nb_merge_cand].is_intra     = 0;

                if (merge_idx == nb_merge_cand)

                    return;

                nb_merge_cand++;

            }

        }

    }

    // append Zero motion vector candidates

    while (nb_merge_cand < s->sh.max_num_merge_cand) {

        mergecandlist[nb_merge_cand].pred_flag[0] = 1;

        mergecandlist[nb_merge_cand].pred_flag[1] = s->sh.slice_type == B_SLICE;

        AV_ZERO32(mergecandlist[nb_merge_cand].mv + 0);

        AV_ZERO32(mergecandlist[nb_merge_cand].mv + 1);

        mergecandlist[nb_merge_cand].is_intra     = 0;

        mergecandlist[nb_merge_cand].ref_idx[0]   = zero_idx < nb_refs ? zero_idx : 0;

        mergecandlist[nb_merge_cand].ref_idx[1]   = zero_idx < nb_refs ? zero_idx : 0;

        if (merge_idx == nb_merge_cand)

            return;

        nb_merge_cand++;

        zero_idx++;

    }

}


int spapr_populate_pci_devices(sPAPRPHBState *phb,

                               uint32_t xics_phandle,

                               void *fdt)

{

    PCIBus *bus = phb->host_state.bus;

    int bus_off, node_off = 0, devid, fn, i, n, devices;

    DeviceState *qdev;

    char nodename[256];

    struct {

        uint32_t hi;

        uint64_t addr;

        uint64_t size;

    } __attribute__((packed)) reg[PCI_NUM_REGIONS + 1],

          assigned_addresses[PCI_NUM_REGIONS];

    uint32_t bus_range[] = { cpu_to_be32(0), cpu_to_be32(0xff) };

    struct {

        uint32_t hi;

        uint64_t child;

        uint64_t parent;

        uint64_t size;

    } __attribute__((packed)) ranges[] = {

        {

            cpu_to_be32(b_ss(1)), cpu_to_be64(0),

            cpu_to_be64(phb->io_win_addr),

            cpu_to_be64(memory_region_size(&phb->iospace)),

        },

        {

            cpu_to_be32(b_ss(2)), cpu_to_be64(SPAPR_PCI_MEM_WIN_BUS_OFFSET),

            cpu_to_be64(phb->mem_win_addr),

            cpu_to_be64(memory_region_size(&phb->memwindow)),

        },

    };

    uint64_t bus_reg[] = { cpu_to_be64(phb->buid), 0 };

    uint32_t interrupt_map_mask[] = {

        cpu_to_be32(b_ddddd(-1)|b_fff(-1)), 0x0, 0x0, 0x0};

    uint32_t interrupt_map[bus->nirq][7];

    /* Start populating the FDT */

    sprintf(nodename, "pci@%" PRIx64, phb->buid);

    bus_off = fdt_add_subnode(fdt, 0, nodename);

    if (bus_off < 0) {

        return bus_off;

    }

#define _FDT(exp) \

    do { \

        int ret = (exp);                                           \

        if (ret < 0) {                                             \

            return ret;                                            \

        }                                                          \

    } while (0)

    /* Write PHB properties */

    _FDT(fdt_setprop_string(fdt, bus_off, "device_type", "pci"));

    _FDT(fdt_setprop_string(fdt, bus_off, "compatible", "IBM,Logical_PHB"));

    _FDT(fdt_setprop_cell(fdt, bus_off, "#address-cells", 0x3));

    _FDT(fdt_setprop_cell(fdt, bus_off, "#size-cells", 0x2));

    _FDT(fdt_setprop_cell(fdt, bus_off, "#interrupt-cells", 0x1));

    _FDT(fdt_setprop(fdt, bus_off, "used-by-rtas", NULL, 0));

    _FDT(fdt_setprop(fdt, bus_off, "bus-range", &bus_range, sizeof(bus_range)));

    _FDT(fdt_setprop(fdt, bus_off, "ranges", &ranges, sizeof(ranges)));

    _FDT(fdt_setprop(fdt, bus_off, "reg", &bus_reg, sizeof(bus_reg)));

    _FDT(fdt_setprop(fdt, bus_off, "interrupt-map-mask",

                     &interrupt_map_mask, sizeof(interrupt_map_mask)));

    /* Populate PCI devices and allocate IRQs */

    devices = 0;

    QTAILQ_FOREACH(qdev, &bus->qbus.children, sibling) {

        PCIDevice *dev = DO_UPCAST(PCIDevice, qdev, qdev);

        int irq_index = pci_spapr_map_irq(dev, 0);

        uint32_t *irqmap = interrupt_map[devices];

        uint8_t *config = dev->config;

        devid = dev->devfn >> 3;

        fn = dev->devfn & 7;

        sprintf(nodename, "pci@%u,%u", devid, fn);

        /* Allocate interrupt from the map */

        if (devid > bus->nirq)  {

            printf("Unexpected behaviour in spapr_populate_pci_devices,"

                    "wrong devid %u\n", devid);

            exit(-1);

        }

        irqmap[0] = cpu_to_be32(b_ddddd(devid)|b_fff(fn));

        irqmap[1] = 0;

        irqmap[2] = 0;

        irqmap[3] = 0;

        irqmap[4] = cpu_to_be32(xics_phandle);

        irqmap[5] = cpu_to_be32(phb->lsi_table[irq_index].dt_irq);

        irqmap[6] = cpu_to_be32(0x8);

        /* Add node to FDT */

        node_off = fdt_add_subnode(fdt, bus_off, nodename);

        if (node_off < 0) {

            return node_off;

        }

        _FDT(fdt_setprop_cell(fdt, node_off, "vendor-id",

                              pci_get_word(&config[PCI_VENDOR_ID])));

        _FDT(fdt_setprop_cell(fdt, node_off, "device-id",

                              pci_get_word(&config[PCI_DEVICE_ID])));

        _FDT(fdt_setprop_cell(fdt, node_off, "revision-id",

                              pci_get_byte(&config[PCI_REVISION_ID])));

        _FDT(fdt_setprop_cell(fdt, node_off, "class-code",

                              pci_get_long(&config[PCI_CLASS_REVISION]) >> 8));

        _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-id",

                              pci_get_word(&config[PCI_SUBSYSTEM_ID])));

        _FDT(fdt_setprop_cell(fdt, node_off, "subsystem-vendor-id",

                              pci_get_word(&config[PCI_SUBSYSTEM_VENDOR_ID])));

        /* Config space region comes first */

        reg[0].hi = cpu_to_be32(

            b_n(0) |

            b_p(0) |

            b_t(0) |

            b_ss(0/*config*/) |

            b_bbbbbbbb(0) |

            b_ddddd(devid) |

            b_fff(fn));

        reg[0].addr = 0;

        reg[0].size = 0;

        n = 0;

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

            if (0 == dev->io_regions[i].size) {

                continue;

            }

            reg[n+1].hi = cpu_to_be32(

                b_n(0) |

                b_p(0) |

                b_t(0) |

                b_ss(regtype_to_ss(dev->io_regions[i].type)) |

                b_bbbbbbbb(0) |

                b_ddddd(devid) |

                b_fff(fn) |

                b_rrrrrrrr(bars[i]));

            reg[n+1].addr = 0;

            reg[n+1].size = cpu_to_be64(dev->io_regions[i].size);

            assigned_addresses[n].hi = cpu_to_be32(

                b_n(1) |

                b_p(0) |

                b_t(0) |

                b_ss(regtype_to_ss(dev->io_regions[i].type)) |

                b_bbbbbbbb(0) |

                b_ddddd(devid) |

                b_fff(fn) |

                b_rrrrrrrr(bars[i]));

            /*

             * Writing zeroes to assigned_addresses causes the guest kernel to

             * reassign BARs

             */

            assigned_addresses[n].addr = cpu_to_be64(dev->io_regions[i].addr);

            assigned_addresses[n].size = reg[n+1].size;

            ++n;

        }

        _FDT(fdt_setprop(fdt, node_off, "reg", reg, sizeof(reg[0])*(n+1)));

        _FDT(fdt_setprop(fdt, node_off, "assigned-addresses",

                         assigned_addresses,

                         sizeof(assigned_addresses[0])*(n)));

        _FDT(fdt_setprop_cell(fdt, node_off, "interrupts",

                              pci_get_byte(&config[PCI_INTERRUPT_PIN])));

        ++devices;

    }

    /* Write interrupt map */

    _FDT(fdt_setprop(fdt, bus_off, "interrupt-map", &interrupt_map,

                     devices * sizeof(interrupt_map[0])));

    return 0;

}


static abi_long do_ioctl_rt(const IOCTLEntry *ie, uint8_t *buf_temp,

                                int fd, int cmd, abi_long arg)

{

    const argtype *arg_type = ie->arg_type;

    const StructEntry *se;

    const argtype *field_types;

    const int *dst_offsets, *src_offsets;

    int target_size;

    void *argptr;

    abi_ulong *target_rt_dev_ptr;

    unsigned long *host_rt_dev_ptr;

    abi_long ret;

    int i;

    assert(ie->access == IOC_W);

    assert(*arg_type == TYPE_PTR);

    arg_type++;

    assert(*arg_type == TYPE_STRUCT);

    target_size = thunk_type_size(arg_type, 0);

    argptr = lock_user(VERIFY_READ, arg, target_size, 1);

    if (!argptr) {

        return -TARGET_EFAULT;

    }

    arg_type++;

    assert(*arg_type == (int)STRUCT_rtentry);

    se = struct_entries + *arg_type++;

    assert(se->convert[0] == NULL);

    /* convert struct here to be able to catch rt_dev string */

    field_types = se->field_types;

    dst_offsets = se->field_offsets[THUNK_HOST];

    src_offsets = se->field_offsets[THUNK_TARGET];

    for (i = 0; i < se->nb_fields; i++) {

        if (dst_offsets[i] == offsetof(struct rtentry, rt_dev)) {

            assert(*field_types == TYPE_PTRVOID);

            target_rt_dev_ptr = (abi_ulong *)(argptr + src_offsets[i]);

            host_rt_dev_ptr = (unsigned long *)(buf_temp + dst_offsets[i]);

            if (*target_rt_dev_ptr != 0) {

                *host_rt_dev_ptr = (unsigned long)lock_user_string(

                                                  tswapal(*target_rt_dev_ptr));

                if (!*host_rt_dev_ptr) {

                    unlock_user(argptr, arg, 0);

                    return -TARGET_EFAULT;

                }

            } else {

                *host_rt_dev_ptr = 0;

            }

            field_types++;

            continue;

        }

        field_types = thunk_convert(buf_temp + dst_offsets[i],

                                    argptr + src_offsets[i],

                                    field_types, THUNK_HOST);

    }

    unlock_user(argptr, arg, 0);

    assert(host_rt_dev_ptr);

    ret = get_errno(safe_ioctl(fd, ie->host_cmd, buf_temp));

    if (*host_rt_dev_ptr != 0) {

        unlock_user((void *)*host_rt_dev_ptr,

                    *target_rt_dev_ptr, 0);

    }

    return ret;

}


void cpu_breakpoint_remove_by_ref(CPUState *env, CPUBreakpoint *breakpoint)

{

#if defined(TARGET_HAS_ICE)

    TAILQ_REMOVE(&env->breakpoints, breakpoint, entry);

    breakpoint_invalidate(env, breakpoint->pc);

    qemu_free(breakpoint);

#endif

}


static void gen_conditional_store(DisasContext *ctx, TCGv EA,

                                  int reg, int size)

{

    int l1;

    tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_so);

    l1 = gen_new_label();

    tcg_gen_brcond_tl(TCG_COND_NE, EA, cpu_reserve, l1);

    tcg_gen_ori_i32(cpu_crf[0], cpu_crf[0], 1 << CRF_EQ);

#if defined(TARGET_PPC64)

    if (size == 8) {

        gen_qemu_st64(ctx, cpu_gpr[reg], EA);

    } else

#endif

    if (size == 4) {

        gen_qemu_st32(ctx, cpu_gpr[reg], EA);

    } else if (size == 2) {

        gen_qemu_st16(ctx, cpu_gpr[reg], EA);

#if defined(TARGET_PPC64)

    } else if (size == 16) {

        TCGv gpr1, gpr2 , EA8;

        if (unlikely(ctx->le_mode)) {

            gpr1 = cpu_gpr[reg+1];

            gpr2 = cpu_gpr[reg];

        } else {

            gpr1 = cpu_gpr[reg];

            gpr2 = cpu_gpr[reg+1];

        }

        gen_qemu_st64(ctx, gpr1, EA);

        EA8 = tcg_temp_local_new();

        gen_addr_add(ctx, EA8, EA, 8);

        gen_qemu_st64(ctx, gpr2, EA8);

        tcg_temp_free(EA8);

#endif

    } else {

        gen_qemu_st8(ctx, cpu_gpr[reg], EA);

    }

    gen_set_label(l1);

    tcg_gen_movi_tl(cpu_reserve, -1);

}


static uint64_t cirrus_linear_bitblt_read(void *opaque,

                                          target_phys_addr_t addr,

                                          unsigned size)

{

    CirrusVGAState *s = opaque;

    uint32_t ret;

    /* XXX handle bitblt */

    (void)s;

    ret = 0xff;

    return ret;

}


bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,

                QEMUIOVector *qiov, int flags)

{

    BDRVBochsState *s = bs->opaque;

    uint64_t sector_num = offset >> BDRV_SECTOR_BITS;

    int nb_sectors = bytes >> BDRV_SECTOR_BITS;

    uint64_t bytes_done = 0;

    QEMUIOVector local_qiov;

    int ret;

    assert((offset & (BDRV_SECTOR_SIZE - 1)) == 0);

    assert((bytes & (BDRV_SECTOR_SIZE - 1)) == 0);

    qemu_iovec_init(&local_qiov, qiov->niov);

    qemu_co_mutex_lock(&s->lock);

    while (nb_sectors > 0) {

        int64_t block_offset = seek_to_sector(bs, sector_num);

        if (block_offset < 0) {

            ret = block_offset;

            goto fail;

        }

        qemu_iovec_reset(&local_qiov);

        qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512);

        if (block_offset > 0) {

            ret = bdrv_co_preadv(bs->file->bs, block_offset, 512,

                                 &local_qiov, 0);

            if (ret < 0) {

                goto fail;

            }

        } else {

            qemu_iovec_memset(&local_qiov, 0, 0, 512);

        }

        nb_sectors--;

        sector_num++;

        bytes_done += 512;

    }

    ret = 0;

fail:

    qemu_co_mutex_unlock(&s->lock);

    qemu_iovec_destroy(&local_qiov);

    return ret;

}