static int elf_core_dump(int signr, const CPUState *env)

{

    const TaskState *ts = (const TaskState *)env->opaque;

    struct vm_area_struct *vma = NULL;

    char corefile[PATH_MAX];

    struct elf_note_info info;

    struct elfhdr elf;

    struct elf_phdr phdr;

    struct rlimit dumpsize;

    struct mm_struct *mm = NULL;

    off_t offset = 0, data_offset = 0;

    int segs = 0;

    int fd = -1;

    errno = 0;

    getrlimit(RLIMIT_CORE, &dumpsize);

    if (dumpsize.rlim_cur == 0)

        return 0;

    if (core_dump_filename(ts, corefile, sizeof (corefile)) < 0)

        return (-errno);

    if ((fd = open(corefile, O_WRONLY | O_CREAT,

                   S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)

        return (-errno);

    /*

     * Walk through target process memory mappings and

     * set up structure containing this information.  After

     * this point vma_xxx functions can be used.

     */

    if ((mm = vma_init()) == NULL)

        goto out;

    walk_memory_regions(mm, vma_walker);

    segs = vma_get_mapping_count(mm);

    /*

     * Construct valid coredump ELF header.  We also

     * add one more segment for notes.

     */

    fill_elf_header(&elf, segs + 1, ELF_MACHINE, 0);

    if (dump_write(fd, &elf, sizeof (elf)) != 0)

        goto out;

    /* fill in in-memory version of notes */

    if (fill_note_info(&info, signr, env) < 0)

        goto out;

    offset += sizeof (elf);                             /* elf header */

    offset += (segs + 1) * sizeof (struct elf_phdr);    /* program headers */

    /* write out notes program header */

    fill_elf_note_phdr(&phdr, info.notes_size, offset);

    offset += info.notes_size;

    if (dump_write(fd, &phdr, sizeof (phdr)) != 0)

        goto out;

    /*

     * ELF specification wants data to start at page boundary so

     * we align it here.

     */

    offset = roundup(offset, ELF_EXEC_PAGESIZE);

    /*

     * Write program headers for memory regions mapped in

     * the target process.

     */

    for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {

        (void) memset(&phdr, 0, sizeof (phdr));

        phdr.p_type = PT_LOAD;

        phdr.p_offset = offset;

        phdr.p_vaddr = vma->vma_start;

        phdr.p_paddr = 0;

        phdr.p_filesz = vma_dump_size(vma);

        offset += phdr.p_filesz;

        phdr.p_memsz = vma->vma_end - vma->vma_start;

        phdr.p_flags = vma->vma_flags & PROT_READ ? PF_R : 0;

        if (vma->vma_flags & PROT_WRITE)

            phdr.p_flags |= PF_W;

        if (vma->vma_flags & PROT_EXEC)

            phdr.p_flags |= PF_X;

        phdr.p_align = ELF_EXEC_PAGESIZE;

        dump_write(fd, &phdr, sizeof (phdr));

    }

    /*

     * Next we write notes just after program headers.  No

     * alignment needed here.

     */

    if (write_note_info(&info, fd) < 0)

        goto out;

    /* align data to page boundary */

    data_offset = lseek(fd, 0, SEEK_CUR);

    data_offset = TARGET_PAGE_ALIGN(data_offset);

    if (lseek(fd, data_offset, SEEK_SET) != data_offset)

        goto out;

    /*

     * Finally we can dump process memory into corefile as well.

     */

    for (vma = vma_first(mm); vma != NULL; vma = vma_next(vma)) {

        abi_ulong addr;

        abi_ulong end;

        end = vma->vma_start + vma_dump_size(vma);

        for (addr = vma->vma_start; addr < end;

             addr += TARGET_PAGE_SIZE) {

            char page[TARGET_PAGE_SIZE];

            int error;

            /*

             *  Read in page from target process memory and

             *  write it to coredump file.

             */

            error = copy_from_user(page, addr, sizeof (page));

            if (error != 0) {

                (void) fprintf(stderr, "unable to dump " TARGET_ABI_FMT_lx "\n",

                               addr);

                errno = -error;

                goto out;

            }

            if (dump_write(fd, page, TARGET_PAGE_SIZE) < 0)

                goto out;

        }

    }

 out:

    free_note_info(&info);

    if (mm != NULL)

        vma_delete(mm);

    (void) close(fd);

    if (errno != 0)

        return (-errno);

    return (0);

}


int net_init_vhost_user(const NetClientOptions *opts, const char *name,

                        NetClientState *peer, Error **errp)

{

    const NetdevVhostUserOptions *vhost_user_opts;

    CharDriverState *chr;

    assert(opts->kind == NET_CLIENT_OPTIONS_KIND_VHOST_USER);

    vhost_user_opts = opts->vhost_user;

    chr = net_vhost_parse_chardev(vhost_user_opts, errp);

    if (!chr) {

        return -1;

    }

    /* verify net frontend */

    if (qemu_opts_foreach(qemu_find_opts("device"), net_vhost_check_net,

                          (char *)name, errp)) {

        return -1;

    }

    return net_vhost_user_init(peer, "vhost_user", name, chr);

}


static void *tcg_cpu_thread_fn(void *arg)

{

    CPUState *env = arg;

    qemu_tcg_init_cpu_signals();

    qemu_thread_self(env->thread);

    /* signal CPU creation */

    qemu_mutex_lock(&qemu_global_mutex);

    for (env = first_cpu; env != NULL; env = env->next_cpu)

        env->created = 1;

    qemu_cond_signal(&qemu_cpu_cond);

    /* and wait for machine initialization */

    while (!qemu_system_ready)

        qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100);

    while (1) {

        cpu_exec_all();

        qemu_tcg_wait_io_event();

    }

    return NULL;

}


static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)

{

    TCGv r_temp, zero;

    r_temp = tcg_temp_new();

    /* old op:

    if (!(env->y & 1))

        T1 = 0;

    */

    zero = tcg_const_tl(0);

    tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);

    tcg_gen_andi_tl(r_temp, cpu_y, 0x1);

    tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);

    tcg_gen_movcond_tl(TCG_COND_EQ, cpu_cc_src2, r_temp, zero,

                       zero, cpu_cc_src2);

    tcg_temp_free(zero);

    // b2 = T0 & 1;

    // env->y = (b2 << 31) | (env->y >> 1);

    tcg_gen_andi_tl(r_temp, cpu_cc_src, 0x1);

    tcg_gen_shli_tl(r_temp, r_temp, 31);

    tcg_gen_shri_tl(cpu_tmp0, cpu_y, 1);

    tcg_gen_andi_tl(cpu_tmp0, cpu_tmp0, 0x7fffffff);

    tcg_gen_or_tl(cpu_tmp0, cpu_tmp0, r_temp);

    tcg_gen_andi_tl(cpu_y, cpu_tmp0, 0xffffffff);

    // b1 = N ^ V;

    gen_mov_reg_N(cpu_tmp0, cpu_psr);

    gen_mov_reg_V(r_temp, cpu_psr);

    tcg_gen_xor_tl(cpu_tmp0, cpu_tmp0, r_temp);

    tcg_temp_free(r_temp);

    // T0 = (b1 << 31) | (T0 >> 1);

    // src1 = T0;

    tcg_gen_shli_tl(cpu_tmp0, cpu_tmp0, 31);

    tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);

    tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_tmp0);

    tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);

    tcg_gen_mov_tl(dst, cpu_cc_dst);

}


dshow_cycle_pins(AVFormatContext *avctx, enum dshowDeviceType devtype,

                 IBaseFilter *device_filter, IPin **ppin)

{

    IEnumPins *pins = 0;

    IPin *device_pin = NULL;

    IPin *pin;

    int r;

    const GUID *mediatype[2] = { &MEDIATYPE_Video, &MEDIATYPE_Audio };

    const char *devtypename = (devtype == VideoDevice) ? "video" : "audio";

    r = IBaseFilter_EnumPins(device_filter, &pins);

    if (r != S_OK) {

        av_log(avctx, AV_LOG_ERROR, "Could not enumerate pins.\n");

        return AVERROR(EIO);

    }

    while (IEnumPins_Next(pins, 1, &pin, NULL) == S_OK && !device_pin) {

        IKsPropertySet *p = NULL;

        IEnumMediaTypes *types;

        PIN_INFO info = {0};

        AM_MEDIA_TYPE *type;

        GUID category;

        DWORD r2;

        IPin_QueryPinInfo(pin, &info);

        IBaseFilter_Release(info.pFilter);

        if (info.dir != PINDIR_OUTPUT)

            goto next;

        if (IPin_QueryInterface(pin, &IID_IKsPropertySet, (void **) &p) != S_OK)

            goto next;

        if (IKsPropertySet_Get(p, &AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY,

                               NULL, 0, &category, sizeof(GUID), &r2) != S_OK)

            goto next;

        if (!IsEqualGUID(&category, &PIN_CATEGORY_CAPTURE))

            goto next;

        if (IPin_EnumMediaTypes(pin, &types) != S_OK)

            goto next;

        IEnumMediaTypes_Reset(types);

        while (IEnumMediaTypes_Next(types, 1, &type, NULL) == S_OK && !device_pin) {

            if (IsEqualGUID(&type->majortype, mediatype[devtype])) {

                device_pin = pin;

                goto next;

            }

            CoTaskMemFree(type);

        }

next:

        if (types)

            IEnumMediaTypes_Release(types);

        if (p)

            IKsPropertySet_Release(p);

        if (device_pin != pin)

            IPin_Release(pin);

    }

    IEnumPins_Release(pins);

    if (!device_pin) {

        av_log(avctx, AV_LOG_ERROR,

               "Could not find output pin from %s capture device.\n", devtypename);

        return AVERROR(EIO);

    }

    *ppin = device_pin;

    return 0;

}


static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,

    int64_t offset, int count, BdrvRequestFlags flags)

{

    uint64_t reqid = request_id++;

    int ret = bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags);

    block_request_create(reqid, bs, qemu_coroutine_self());

    qemu_coroutine_yield();

    return ret;

}


static void tcg_target_qemu_prologue (TCGContext *s)

{

    int i, frame_size;

#ifndef __APPLE__

    uint64_t addr;

#endif

    frame_size = 0

        + 8                     /* back chain */

        + 8                     /* CR */

        + 8                     /* LR */

        + 8                     /* compiler doubleword */

        + 8                     /* link editor doubleword */

        + 8                     /* TOC save area */

        + TCG_STATIC_CALL_ARGS_SIZE

        + ARRAY_SIZE (tcg_target_callee_save_regs) * 8

        ;

    frame_size = (frame_size + 15) & ~15;

#ifndef __APPLE__

    /* First emit adhoc function descriptor */

    addr = (uint64_t) s->code_ptr + 24;

    tcg_out32 (s, addr >> 32); tcg_out32 (s, addr); /* entry point */

    s->code_ptr += 16;          /* skip TOC and environment pointer */

#endif

    /* Prologue */

    tcg_out32 (s, MFSPR | RT (0) | LR);

    tcg_out32 (s, STDU | RS (1) | RA (1) | (-frame_size & 0xffff));

    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)

        tcg_out32 (s, (STD

                       | RS (tcg_target_callee_save_regs[i])

                       | RA (1)

                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)

                       )

            );

    tcg_out32 (s, STD | RS (0) | RA (1) | (frame_size + 16));

#ifdef CONFIG_USE_GUEST_BASE

    if (GUEST_BASE) {

        tcg_out_movi (s, TCG_TYPE_I64, TCG_GUEST_BASE_REG, GUEST_BASE);

        tcg_regset_set_reg(s->reserved_regs, TCG_GUEST_BASE_REG);

    }

#endif

    tcg_out32 (s, MTSPR | RS (3) | CTR);

    tcg_out32 (s, BCCTR | BO_ALWAYS);

    /* Epilogue */

    tb_ret_addr = s->code_ptr;

    for (i = 0; i < ARRAY_SIZE (tcg_target_callee_save_regs); ++i)

        tcg_out32 (s, (LD

                       | RT (tcg_target_callee_save_regs[i])

                       | RA (1)

                       | (i * 8 + 48 + TCG_STATIC_CALL_ARGS_SIZE)

                       )

            );

    tcg_out32 (s, LD | RT (0) | RA (1) | (frame_size + 16));

    tcg_out32 (s, MTSPR | RS (0) | LR);

    tcg_out32 (s, ADDI | RT (1) | RA (1) | frame_size);

    tcg_out32 (s, BCLR | BO_ALWAYS);

}


int blk_co_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)

{

    int ret = blk_check_request(blk, sector_num, nb_sectors);

    if (ret < 0) {

        return ret;

    }

    return bdrv_co_discard(blk_bs(blk), sector_num, nb_sectors);

}


GList *range_list_insert(GList *list, Range *data)

{

    GList *l;

    /* Range lists require no empty ranges */

    assert(data->begin < data->end || (data->begin && !data->end));

    /* Skip all list elements strictly less than data */

    for (l = list; l && range_compare(l->data, data) < 0; l = l->next) {

    }

    if (!l || range_compare(l->data, data) > 0) {

        /* Rest of the list (if any) is strictly greater than @data */

        return g_list_insert_before(list, l, data);

    }

    /* Current list element overlaps @data, merge the two */

    range_extend(l->data, data);

    g_free(data);

    /* Merge any subsequent list elements that now also overlap */

    while (l->next && range_compare(l->data, l->next->data) == 0) {

        GList *new_l;

        range_extend(l->data, l->next->data);

        g_free(l->next->data);

        new_l = g_list_delete_link(list, l->next);

        assert(new_l == list);

    }

    return list;

}


SCSIRequest *scsi_req_new(SCSIDevice *d, uint32_t tag, uint32_t lun,

                          void *hba_private)

{

    return d->info->alloc_req(d, tag, lun, hba_private);

}


static int nbd_send_negotiate(int csock, off_t size, uint32_t flags)

{

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

    /* Negotiate

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

        [ 8 ..  15]   magic    (0x00420281861253)

        [16 ..  23]   size

        [24 ..  27]   flags

        [28 .. 151]   reserved (0)

     */

    TRACE("Beginning negotiation.");

    memcpy(buf, "NBDMAGIC", 8);

    cpu_to_be64w((uint64_t*)(buf + 8), 0x00420281861253LL);

    cpu_to_be64w((uint64_t*)(buf + 16), size);

    cpu_to_be32w((uint32_t*)(buf + 24),

                 flags | NBD_FLAG_HAS_FLAGS | NBD_FLAG_SEND_TRIM |

                 NBD_FLAG_SEND_FLUSH | NBD_FLAG_SEND_FUA);

    memset(buf + 28, 0, 124);

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

        LOG("write failed");

        errno = EINVAL;

        return -1;

    }

    TRACE("Negotiation succeeded.");

    return 0;

}


static int find_pte32(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, int h,

                      int rw, int type, int target_page_bits)

{

    hwaddr pteg_off;

    target_ulong pte0, pte1;

    int i, good = -1;

    int ret, r;

    ret = -1; /* No entry found */

    pteg_off = get_pteg_offset32(env, ctx->hash[h]);

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

        pte0 = ppc_hash32_load_hpte0(env, pteg_off + i*HASH_PTE_SIZE_32);

        pte1 = ppc_hash32_load_hpte1(env, pteg_off + i*HASH_PTE_SIZE_32);

        r = pte_check_hash32(ctx, pte0, pte1, h, rw, type);

        LOG_MMU("Load pte from %08" HWADDR_PRIx " => " TARGET_FMT_lx " "

                TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n",

                pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h,

                (int)((pte0 >> 6) & 1), ctx->ptem);

        switch (r) {

        case -3:

            /* PTE inconsistency */

            return -1;

        case -2:

            /* Access violation */

            ret = -2;

            good = i;

            break;

        case -1:

        default:

            /* No PTE match */

            break;

        case 0:

            /* access granted */

            /* XXX: we should go on looping to check all PTEs consistency

             *      but if we can speed-up the whole thing as the

             *      result would be undefined if PTEs are not consistent.

             */

            ret = 0;

            good = i;

            goto done;

        }

    }

    if (good != -1) {

    done:

        LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n",

                ctx->raddr, ctx->prot, ret);

        /* Update page flags */

        pte1 = ctx->raddr;

        if (ppc_hash32_pte_update_flags(ctx, &pte1, ret, rw) == 1) {

            ppc_hash32_store_hpte1(env, pteg_off + good * HASH_PTE_SIZE_32,

                                   pte1);

        }

    }

    /* We have a TLB that saves 4K pages, so let's

     * split a huge page to 4k chunks */

    if (target_page_bits != TARGET_PAGE_BITS) {

        ctx->raddr |= (ctx->eaddr & ((1 << target_page_bits) - 1))

                      & TARGET_PAGE_MASK;

    }

    return ret;

}


static void __attribute__((constructor)) coroutine_pool_init(void)

{

    qemu_mutex_init(&pool_lock);

}


static void nvdimm_dsm_root(NvdimmDsmIn *in, hwaddr dsm_mem_addr)

{

    /*

     * function 0 is called to inquire which functions are supported by

     * OSPM

     */

    if (!in->function) {

        nvdimm_dsm_function0(0 /* No function supported other than

                                  function 0 */, dsm_mem_addr);

        return;

    }

    /* No function except function 0 is supported yet. */

    nvdimm_dsm_no_payload(1 /* Not Supported */, dsm_mem_addr);

}


static int spapr_phb_vfio_eeh_set_option(sPAPRPHBState *sphb,

                                         unsigned int addr, int option)

{

    sPAPRPHBVFIOState *svphb = SPAPR_PCI_VFIO_HOST_BRIDGE(sphb);

    struct vfio_eeh_pe_op op = { .argsz = sizeof(op) };

    int ret;

    switch (option) {

    case RTAS_EEH_DISABLE:

        op.op = VFIO_EEH_PE_DISABLE;

        break;

    case RTAS_EEH_ENABLE: {

        PCIHostState *phb;

        PCIDevice *pdev;

        /*

         * The EEH functionality is enabled on basis of PCI device,

         * instead of PE. We need check the validity of the PCI

         * device address.

         */

        phb = PCI_HOST_BRIDGE(sphb);

        pdev = pci_find_device(phb->bus,

                               (addr >> 16) & 0xFF, (addr >> 8) & 0xFF);

        if (!pdev) {

            return RTAS_OUT_PARAM_ERROR;

        }

        op.op = VFIO_EEH_PE_ENABLE;

        break;

    }

    case RTAS_EEH_THAW_IO:

        op.op = VFIO_EEH_PE_UNFREEZE_IO;

        break;

    case RTAS_EEH_THAW_DMA:

        op.op = VFIO_EEH_PE_UNFREEZE_DMA;

        break;

    default:

        return RTAS_OUT_PARAM_ERROR;

    }

    ret = vfio_container_ioctl(&svphb->phb.iommu_as, svphb->iommugroupid,

                               VFIO_EEH_PE_OP, &op);

    if (ret < 0) {

        return RTAS_OUT_HW_ERROR;

    }

    return RTAS_OUT_SUCCESS;

}


static int vaapi_h264_start_frame(AVCodecContext          *avctx,

                                  av_unused const uint8_t *buffer,

                                  av_unused uint32_t       size)

{

    H264Context * const h = avctx->priv_data;

    struct vaapi_context * const vactx = avctx->hwaccel_context;

    VAPictureParameterBufferH264 *pic_param;

    VAIQMatrixBufferH264 *iq_matrix;

    ff_dlog(avctx, "vaapi_h264_start_frame()\n");

    vactx->slice_param_size = sizeof(VASliceParameterBufferH264);

    /* Fill in VAPictureParameterBufferH264. */

    pic_param = ff_vaapi_alloc_pic_param(vactx, sizeof(VAPictureParameterBufferH264));

    if (!pic_param)

        return -1;

    fill_vaapi_pic(&pic_param->CurrPic, h->cur_pic_ptr, h->picture_structure);

    if (fill_vaapi_ReferenceFrames(pic_param, h) < 0)

        return -1;

    pic_param->picture_width_in_mbs_minus1                      = h->mb_width - 1;

    pic_param->picture_height_in_mbs_minus1                     = h->mb_height - 1;

    pic_param->bit_depth_luma_minus8                            = h->sps.bit_depth_luma - 8;

    pic_param->bit_depth_chroma_minus8                          = h->sps.bit_depth_chroma - 8;

    pic_param->num_ref_frames                                   = h->sps.ref_frame_count;

    pic_param->seq_fields.value                                 = 0; /* reset all bits */

    pic_param->seq_fields.bits.chroma_format_idc                = h->sps.chroma_format_idc;

    pic_param->seq_fields.bits.residual_colour_transform_flag   = h->sps.residual_color_transform_flag; /* XXX: only for 4:4:4 high profile? */

    pic_param->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = h->sps.gaps_in_frame_num_allowed_flag;

    pic_param->seq_fields.bits.frame_mbs_only_flag              = h->sps.frame_mbs_only_flag;

    pic_param->seq_fields.bits.mb_adaptive_frame_field_flag     = h->sps.mb_aff;

    pic_param->seq_fields.bits.direct_8x8_inference_flag        = h->sps.direct_8x8_inference_flag;

    pic_param->seq_fields.bits.MinLumaBiPredSize8x8             = h->sps.level_idc >= 31; /* A.3.3.2 */

    pic_param->seq_fields.bits.log2_max_frame_num_minus4        = h->sps.log2_max_frame_num - 4;

    pic_param->seq_fields.bits.pic_order_cnt_type               = h->sps.poc_type;

    pic_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = h->sps.log2_max_poc_lsb - 4;

    pic_param->seq_fields.bits.delta_pic_order_always_zero_flag = h->sps.delta_pic_order_always_zero_flag;

    pic_param->num_slice_groups_minus1                          = h->pps.slice_group_count - 1;

    pic_param->slice_group_map_type                             = h->pps.mb_slice_group_map_type;

    pic_param->slice_group_change_rate_minus1                   = 0; /* XXX: unimplemented in Libav */

    pic_param->pic_init_qp_minus26                              = h->pps.init_qp - 26;

    pic_param->pic_init_qs_minus26                              = h->pps.init_qs - 26;

    pic_param->chroma_qp_index_offset                           = h->pps.chroma_qp_index_offset[0];

    pic_param->second_chroma_qp_index_offset                    = h->pps.chroma_qp_index_offset[1];

    pic_param->pic_fields.value                                 = 0; /* reset all bits */

    pic_param->pic_fields.bits.entropy_coding_mode_flag         = h->pps.cabac;

    pic_param->pic_fields.bits.weighted_pred_flag               = h->pps.weighted_pred;

    pic_param->pic_fields.bits.weighted_bipred_idc              = h->pps.weighted_bipred_idc;

    pic_param->pic_fields.bits.transform_8x8_mode_flag          = h->pps.transform_8x8_mode;

    pic_param->pic_fields.bits.field_pic_flag                   = h->picture_structure != PICT_FRAME;

    pic_param->pic_fields.bits.constrained_intra_pred_flag      = h->pps.constrained_intra_pred;

    pic_param->pic_fields.bits.pic_order_present_flag           = h->pps.pic_order_present;

    pic_param->pic_fields.bits.deblocking_filter_control_present_flag = h->pps.deblocking_filter_parameters_present;

    pic_param->pic_fields.bits.redundant_pic_cnt_present_flag   = h->pps.redundant_pic_cnt_present;

    pic_param->pic_fields.bits.reference_pic_flag               = h->nal_ref_idc != 0;

    pic_param->frame_num                                        = h->frame_num;

    /* Fill in VAIQMatrixBufferH264. */

    iq_matrix = ff_vaapi_alloc_iq_matrix(vactx, sizeof(VAIQMatrixBufferH264));

    if (!iq_matrix)

        return -1;

    memcpy(iq_matrix->ScalingList4x4, h->pps.scaling_matrix4, sizeof(iq_matrix->ScalingList4x4));

    memcpy(iq_matrix->ScalingList8x8[0], h->pps.scaling_matrix8[0], sizeof(iq_matrix->ScalingList8x8[0]));

    memcpy(iq_matrix->ScalingList8x8[1], h->pps.scaling_matrix8[3], sizeof(iq_matrix->ScalingList8x8[0]));

    return 0;

}


void cpu_outb(pio_addr_t addr, uint8_t val)

{

    LOG_IOPORT("outb: %04"FMT_pioaddr" %02"PRIx8"\n", addr, val);

    trace_cpu_out(addr, val);

    ioport_write(0, addr, val);

}


static unsigned int dec_addu_r(DisasContext *dc)

{

	TCGv t0;

	int size = memsize_z(dc);

	DIS(fprintf (logfile, "addu.%c $r%u, $r%u\n",

		    memsize_char(size),

		    dc->op1, dc->op2));

	cris_cc_mask(dc, CC_MASK_NZVC);

	t0 = tcg_temp_new(TCG_TYPE_TL);

	/* Size can only be qi or hi.  */

	t_gen_zext(t0, cpu_R[dc->op1], size);

	cris_alu(dc, CC_OP_ADD,

		    cpu_R[dc->op2], cpu_R[dc->op2], t0, 4);

	tcg_temp_free(t0);

	return 2;

}


static void net_rx_packet(void *opaque, const uint8_t *buf, size_t size)

{

    struct XenNetDev *netdev = opaque;

    netif_rx_request_t rxreq;

    RING_IDX rc, rp;

    void *page;

    if (netdev->xendev.be_state != XenbusStateConnected)

	return;

    rc = netdev->rx_ring.req_cons;

    rp = netdev->rx_ring.sring->req_prod;

    xen_rmb(); /* Ensure we see queued requests up to 'rp'. */

    if (rc == rp || RING_REQUEST_CONS_OVERFLOW(&netdev->rx_ring, rc)) {

	xen_be_printf(&netdev->xendev, 2, "no buffer, drop packet\n");

	return;

    }

    if (size > XC_PAGE_SIZE - NET_IP_ALIGN) {

	xen_be_printf(&netdev->xendev, 0, "packet too big (%lu > %ld)",

		      (unsigned long)size, XC_PAGE_SIZE - NET_IP_ALIGN);

	return;

    }

    memcpy(&rxreq, RING_GET_REQUEST(&netdev->rx_ring, rc), sizeof(rxreq));

    netdev->rx_ring.req_cons = ++rc;

    page = xc_gnttab_map_grant_ref(netdev->xendev.gnttabdev,

				   netdev->xendev.dom,

				   rxreq.gref, PROT_WRITE);

    if (page == NULL) {

	xen_be_printf(&netdev->xendev, 0, "error: rx gref dereference failed (%d)\n",

                      rxreq.gref);

	net_rx_response(netdev, &rxreq, NETIF_RSP_ERROR, 0, 0, 0);

	return;

    }

    memcpy(page + NET_IP_ALIGN, buf, size);

    xc_gnttab_munmap(netdev->xendev.gnttabdev, page, 1);

    net_rx_response(netdev, &rxreq, NETIF_RSP_OKAY, NET_IP_ALIGN, size, 0);

}


static void mcf_fec_receive(void *opaque, const uint8_t *buf, size_t size)

{

    mcf_fec_state *s = (mcf_fec_state *)opaque;

    mcf_fec_bd bd;

    uint32_t flags = 0;

    uint32_t addr;

    uint32_t crc;

    uint32_t buf_addr;

    uint8_t *crc_ptr;

    unsigned int buf_len;

    DPRINTF("do_rx len %d\n", size);

    if (!s->rx_enabled) {

        fprintf(stderr, "mcf_fec_receive: Unexpected packet\n");

    }

    /* 4 bytes for the CRC.  */

    size += 4;

    crc = cpu_to_be32(crc32(~0, buf, size));

    crc_ptr = (uint8_t *)&crc;

    /* Huge frames are truncted.  */

    if (size > FEC_MAX_FRAME_SIZE) {

        size = FEC_MAX_FRAME_SIZE;

        flags |= FEC_BD_TR | FEC_BD_LG;

    }

    /* Frames larger than the user limit just set error flags.  */

    if (size > (s->rcr >> 16)) {

        flags |= FEC_BD_LG;

    }

    addr = s->rx_descriptor;

    while (size > 0) {

        mcf_fec_read_bd(&bd, addr);

        if ((bd.flags & FEC_BD_E) == 0) {

            /* No descriptors available.  Bail out.  */

            /* FIXME: This is wrong.  We should probably either save the

               remainder for when more RX buffers are available, or

               flag an error.  */

            fprintf(stderr, "mcf_fec: Lost end of frame\n");

            break;

        }

        buf_len = (size <= s->emrbr) ? size: s->emrbr;

        bd.length = buf_len;

        size -= buf_len;

        DPRINTF("rx_bd %x length %d\n", addr, bd.length);

        /* The last 4 bytes are the CRC.  */

        if (size < 4)

            buf_len += size - 4;

        buf_addr = bd.data;

        cpu_physical_memory_write(buf_addr, buf, buf_len);

        buf += buf_len;

        if (size < 4) {

            cpu_physical_memory_write(buf_addr + buf_len, crc_ptr, 4 - size);

            crc_ptr += 4 - size;

        }

        bd.flags &= ~FEC_BD_E;

        if (size == 0) {

            /* Last buffer in frame.  */

            bd.flags |= flags | FEC_BD_L;

            DPRINTF("rx frame flags %04x\n", bd.flags);

            s->eir |= FEC_INT_RXF;

        } else {

            s->eir |= FEC_INT_RXB;

        }

        mcf_fec_write_bd(&bd, addr);

        /* Advance to the next descriptor.  */

        if ((bd.flags & FEC_BD_W) != 0) {

            addr = s->erdsr;

        } else {

            addr += 8;

        }

    }

    s->rx_descriptor = addr;

    mcf_fec_enable_rx(s);

    mcf_fec_update(s);

}


static BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd,

        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,

        BlockDriverCompletionFunc *cb, void *opaque, int type)

{

    RawPosixAIOData *acb = g_slice_new(RawPosixAIOData);

    acb->bs = bs;

    acb->aio_type = type;

    acb->aio_fildes = fd;

    if (qiov) {

        acb->aio_iov = qiov->iov;

        acb->aio_niov = qiov->niov;

    }

    acb->aio_nbytes = nb_sectors * 512;

    acb->aio_offset = sector_num * 512;

    trace_paio_submit(acb, opaque, sector_num, nb_sectors, type);

    return thread_pool_submit_aio(aio_worker, acb, cb, opaque);

}


static void fdt_add_pmu_nodes(const VirtMachineState *vms)

{

    CPUState *cpu;

    ARMCPU *armcpu;

    uint32_t irqflags = GIC_FDT_IRQ_FLAGS_LEVEL_HI;

    CPU_FOREACH(cpu) {

        armcpu = ARM_CPU(cpu);

        if (!arm_feature(&armcpu->env, ARM_FEATURE_PMU) ||

            !kvm_arm_pmu_create(cpu, PPI(VIRTUAL_PMU_IRQ))) {

            return;

        }

    }

    if (vms->gic_version == 2) {

        irqflags = deposit32(irqflags, GIC_FDT_IRQ_PPI_CPU_START,

                             GIC_FDT_IRQ_PPI_CPU_WIDTH,

                             (1 << vms->smp_cpus) - 1);

    }

    armcpu = ARM_CPU(qemu_get_cpu(0));

    qemu_fdt_add_subnode(vms->fdt, "/pmu");

    if (arm_feature(&armcpu->env, ARM_FEATURE_V8)) {

        const char compat[] = "arm,armv8-pmuv3";

        qemu_fdt_setprop(vms->fdt, "/pmu", "compatible",

                         compat, sizeof(compat));

        qemu_fdt_setprop_cells(vms->fdt, "/pmu", "interrupts",

                               GIC_FDT_IRQ_TYPE_PPI, VIRTUAL_PMU_IRQ, irqflags);

    }

}


static int usb_ohci_initfn_pci(struct PCIDevice *dev)

{

    OHCIPCIState *ohci = DO_UPCAST(OHCIPCIState, pci_dev, dev);

    int num_ports = 3;

    pci_config_set_vendor_id(ohci->pci_dev.config, PCI_VENDOR_ID_APPLE);

    pci_config_set_device_id(ohci->pci_dev.config,

                             PCI_DEVICE_ID_APPLE_IPID_USB);

    ohci->pci_dev.config[PCI_CLASS_PROG] = 0x10; /* OHCI */

    pci_config_set_class(ohci->pci_dev.config, PCI_CLASS_SERIAL_USB);

    /* TODO: RST# value should be 0. */

    ohci->pci_dev.config[PCI_INTERRUPT_PIN] = 0x01; /* interrupt pin 1 */

    usb_ohci_init(&ohci->state, &dev->qdev, num_ports, 0);

    ohci->state.irq = ohci->pci_dev.irq[0];

    /* TODO: avoid cast below by using dev */

    pci_register_bar_simple(&ohci->pci_dev, 0, 256, 0, ohci->state.mem);

    return 0;

}


static int nbd_negotiate_read(QIOChannel *ioc, void *buffer, size_t size)

{

    ssize_t ret;

    guint watch;

    assert(qemu_in_coroutine());

    /* Negotiation are always in main loop. */

    watch = qio_channel_add_watch(ioc,

                                  G_IO_IN,

                                  nbd_negotiate_continue,

                                  qemu_coroutine_self(),

                                  NULL);

    ret = read_sync(ioc, buffer, size, NULL);

    g_source_remove(watch);

    return ret;

}


static inline void sdhci_reset_write(SDHCIState *s, uint8_t value)

{

    switch (value) {

    case SDHC_RESET_ALL:

        DEVICE_GET_CLASS(s)->reset(DEVICE(s));

        break;

    case SDHC_RESET_CMD:

        s->prnsts &= ~SDHC_CMD_INHIBIT;

        s->norintsts &= ~SDHC_NIS_CMDCMP;

        break;

    case SDHC_RESET_DATA:

        s->data_count = 0;

        s->prnsts &= ~(SDHC_SPACE_AVAILABLE | SDHC_DATA_AVAILABLE |

                SDHC_DOING_READ | SDHC_DOING_WRITE |

                SDHC_DATA_INHIBIT | SDHC_DAT_LINE_ACTIVE);

        s->blkgap &= ~(SDHC_STOP_AT_GAP_REQ | SDHC_CONTINUE_REQ);

        s->stopped_state = sdhc_not_stopped;

        s->norintsts &= ~(SDHC_NIS_WBUFRDY | SDHC_NIS_RBUFRDY |

                SDHC_NIS_DMA | SDHC_NIS_TRSCMP | SDHC_NIS_BLKGAP);

        break;

    }

}


static void print_report(OutputFile *output_files,

                         OutputStream *ost_table, int nb_ostreams,

                         int is_last_report, int64_t timer_start)

{

    char buf[1024];

    OutputStream *ost;

    AVFormatContext *oc;

    int64_t total_size;

    AVCodecContext *enc;

    int frame_number, vid, i;

    double bitrate;

    int64_t pts = INT64_MAX;

    static int64_t last_time = -1;

    static int qp_histogram[52];

    int hours, mins, secs, us;

    if (!is_last_report) {

        int64_t cur_time;

        /* display the report every 0.5 seconds */

        cur_time = av_gettime();

        if (last_time == -1) {

            last_time = cur_time;

            return;

        }

        if ((cur_time - last_time) < 500000)

            return;

        last_time = cur_time;

    }

    oc = output_files[0].ctx;

    total_size = avio_size(oc->pb);

    if(total_size<0) // FIXME improve avio_size() so it works with non seekable output too

        total_size= avio_tell(oc->pb);

    buf[0] = '\0';

    vid = 0;

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

        float q = -1;

        ost = &ost_table[i];

        enc = ost->st->codec;

        if (!ost->st->stream_copy && enc->coded_frame)

            q = enc->coded_frame->quality/(float)FF_QP2LAMBDA;

        if (vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {

            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "q=%2.1f ", q);

        }

        if (!vid && enc->codec_type == AVMEDIA_TYPE_VIDEO) {

            float t = (av_gettime()-timer_start) / 1000000.0;

            frame_number = ost->frame_number;

            snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "frame=%5d fps=%3d q=%3.1f ",

                     frame_number, (t>1)?(int)(frame_number/t+0.5) : 0, q);

            if(is_last_report)

                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "L");

            if(qp_hist){

                int j;

                int qp = lrintf(q);

                if(qp>=0 && qp<FF_ARRAY_ELEMS(qp_histogram))

                    qp_histogram[qp]++;

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

                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%X", (int)lrintf(log(qp_histogram[j]+1)/log(2)));

            }

            if (enc->flags&CODEC_FLAG_PSNR){

                int j;

                double error, error_sum=0;

                double scale, scale_sum=0;

                char type[3]= {'Y','U','V'};

                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "PSNR=");

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

                    if(is_last_report){

                        error= enc->error[j];

                        scale= enc->width*enc->height*255.0*255.0*frame_number;

                    }else{

                        error= enc->coded_frame->error[j];

                        scale= enc->width*enc->height*255.0*255.0;

                    }

                    if(j) scale/=4;

                    error_sum += error;

                    scale_sum += scale;

                    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "%c:%2.2f ", type[j], psnr(error/scale));

                }

                snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "*:%2.2f ", psnr(error_sum/scale_sum));

            }

            vid = 1;

        }

        /* compute min output value */

        pts = FFMIN(pts, av_rescale_q(ost->st->pts.val,

                                      ost->st->time_base, AV_TIME_BASE_Q));

    }

    secs = pts / AV_TIME_BASE;

    us = pts % AV_TIME_BASE;

    mins = secs / 60;

    secs %= 60;

    hours = mins / 60;

    mins %= 60;

    bitrate = pts ? total_size * 8 / (pts / 1000.0) : 0;

    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),

             "size=%8.0fkB time=", total_size / 1024.0);

    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),

             "%02d:%02d:%02d.%02d ", hours, mins, secs,

             (100 * us) / AV_TIME_BASE);

    snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf),

             "bitrate=%6.1fkbits/s", bitrate);

    if (nb_frames_dup || nb_frames_drop)

        snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), " dup=%d drop=%d",

                nb_frames_dup, nb_frames_drop);

    av_log(NULL, is_last_report ? AV_LOG_WARNING : AV_LOG_INFO, "%s    \r", buf);

    fflush(stderr);

    if (is_last_report) {

        int64_t raw= audio_size + video_size + extra_size;

        av_log(NULL, AV_LOG_INFO, "\n");

        av_log(NULL, AV_LOG_INFO, "video:%1.0fkB audio:%1.0fkB global headers:%1.0fkB muxing overhead %f%%\n",

               video_size/1024.0,

               audio_size/1024.0,

               extra_size/1024.0,

               100.0*(total_size - raw)/raw

        );

    }

}


static int ohci_bus_start(OHCIState *ohci)

{

    ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,

                    ohci_frame_boundary,

                    ohci);

    if (ohci->eof_timer == NULL) {

        trace_usb_ohci_bus_eof_timer_failed(ohci->name);

        ohci_die(ohci);

        return 0;

    }

    trace_usb_ohci_start(ohci->name);

    ohci_sof(ohci);

    return 1;

}


static void arm_thistimer_write(void *opaque, target_phys_addr_t addr,

                                uint64_t value, unsigned size)

{

    arm_mptimer_state *s = (arm_mptimer_state *)opaque;

    int id = get_current_cpu(s);

    timerblock_write(&s->timerblock[id * 2], addr, value, size);

}


long do_rt_sigreturn(CPUX86State *env)

{

        abi_ulong frame_addr;

	struct rt_sigframe *frame;

        sigset_t set;

	int eax;

        frame_addr = env->regs[R_ESP] - 4;

        if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))

                goto badframe;

        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);

        sigprocmask(SIG_SETMASK, &set, NULL);

	if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))

		goto badframe;

	if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,

                           get_sp_from_cpustate(env)) == -EFAULT)

		goto badframe;

        unlock_user_struct(frame, frame_addr, 0);

	return eax;

badframe:

        unlock_user_struct(frame, frame_addr, 0);

        force_sig(TARGET_SIGSEGV);

	return 0;

}


int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src)

{

    const AVCodec *orig_codec = dest->codec;

    uint8_t *orig_priv_data = dest->priv_data;

    if (avcodec_is_open(dest)) { // check that the dest context is uninitialized

        av_log(dest, AV_LOG_ERROR,

               "Tried to copy AVCodecContext %p into already-initialized %p\n",

               src, dest);

        return AVERROR(EINVAL);

    }

    av_opt_free(dest);

    av_free(dest->priv_data);

    memcpy(dest, src, sizeof(*dest));

    dest->priv_data       = orig_priv_data;

    dest->codec           = orig_codec;

    /* set values specific to opened codecs back to their default state */

    dest->slice_offset    = NULL;

    dest->hwaccel         = NULL;

    dest->internal        = NULL;

    /* reallocate values that should be allocated separately */

    dest->rc_eq           = NULL;

    dest->extradata       = NULL;

    dest->intra_matrix    = NULL;

    dest->inter_matrix    = NULL;

    dest->rc_override     = NULL;

    dest->subtitle_header = NULL;

    if (src->rc_eq) {

        dest->rc_eq = av_strdup(src->rc_eq);

        if (!dest->rc_eq)

            return AVERROR(ENOMEM);

    }

#define alloc_and_copy_or_fail(obj, size, pad) \

    if (src->obj && size > 0) { \

        dest->obj = av_malloc(size + pad); \

        if (!dest->obj) \

            goto fail; \

        memcpy(dest->obj, src->obj, size); \

        if (pad) \

            memset(((uint8_t *) dest->obj) + size, 0, pad); \

    }

    alloc_and_copy_or_fail(extradata,    src->extradata_size,

                           FF_INPUT_BUFFER_PADDING_SIZE);

    alloc_and_copy_or_fail(intra_matrix, 64 * sizeof(int16_t), 0);

    alloc_and_copy_or_fail(inter_matrix, 64 * sizeof(int16_t), 0);

    alloc_and_copy_or_fail(rc_override,  src->rc_override_count * sizeof(*src->rc_override), 0);

    alloc_and_copy_or_fail(subtitle_header, src->subtitle_header_size, 1);

    dest->subtitle_header_size = src->subtitle_header_size;

#undef alloc_and_copy_or_fail

    return 0;

fail:

    av_freep(&dest->rc_override);

    av_freep(&dest->intra_matrix);

    av_freep(&dest->inter_matrix);

    av_freep(&dest->extradata);

    av_freep(&dest->rc_eq);

    return AVERROR(ENOMEM);

}


target_ulong helper_rdhwr_synci_step(CPUMIPSState *env)

{

    if ((env->hflags & MIPS_HFLAG_CP0) ||

        (env->CP0_HWREna & (1 << 1)))

        return env->SYNCI_Step;

    else

        do_raise_exception(env, EXCP_RI, GETPC());

    return 0;

}


static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)

{

    BlockDriverAIOCBCoroutine *acb = opaque;

    BlockDriverState *bs = acb->common.bs;

    acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);

    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);

    qemu_bh_schedule(acb->bh);

}


POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);

    dc->fw_name = "PowerPC,POWER7";

    dc->desc = "POWER7";

    dc->props = powerpc_servercpu_properties;

    pcc->pvr_match = ppc_pvr_match_power7;

    pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06;

    pcc->init_proc = init_proc_POWER7;

    pcc->check_pow = check_pow_nocheck;

    pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB |

                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |

                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |

                       PPC_FLOAT_FRSQRTES |

                       PPC_FLOAT_STFIWX |

                       PPC_FLOAT_EXT |

                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |

                       PPC_MEM_SYNC | PPC_MEM_EIEIO |

                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |

                       PPC_64B | PPC_64H | PPC_64BX | PPC_ALTIVEC |

                       PPC_SEGMENT_64B | PPC_SLBI |

                       PPC_POPCNTB | PPC_POPCNTWD;

    pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 |

                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |

                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |

                        PPC2_FP_TST_ISA206 | PPC2_FP_CVT_S64;

    pcc->msr_mask = (1ull << MSR_SF) |

                    (1ull << MSR_VR) |

                    (1ull << MSR_VSX) |

                    (1ull << MSR_EE) |

                    (1ull << MSR_PR) |

                    (1ull << MSR_FP) |

                    (1ull << MSR_ME) |

                    (1ull << MSR_FE0) |

                    (1ull << MSR_SE) |

                    (1ull << MSR_DE) |

                    (1ull << MSR_FE1) |

                    (1ull << MSR_IR) |

                    (1ull << MSR_DR) |

                    (1ull << MSR_PMM) |

                    (1ull << MSR_RI) |

                    (1ull << MSR_LE);

    pcc->mmu_model = POWERPC_MMU_2_06;

#if defined(CONFIG_SOFTMMU)

    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;

    pcc->sps = &POWER7_POWER8_sps;

#endif

    pcc->excp_model = POWERPC_EXCP_POWER7;

    pcc->bus_model = PPC_FLAGS_INPUT_POWER7;

    pcc->bfd_mach = bfd_mach_ppc64;

    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |

                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |

                 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |

                 POWERPC_FLAG_VSX;

    pcc->l1_dcache_size = 0x8000;

    pcc->l1_icache_size = 0x8000;

    pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;

}


static void configure_rtc(QemuOpts *opts)

{

    const char *value;

    value = qemu_opt_get(opts, "base");

    if (value) {

        if (!strcmp(value, "utc")) {

            rtc_utc = 1;

        } else if (!strcmp(value, "localtime")) {

            rtc_utc = 0;

        } else {

            configure_rtc_date_offset(value, 0);

        }

    }

    value = qemu_opt_get(opts, "clock");

    if (value) {

        if (!strcmp(value, "host")) {

            rtc_clock = QEMU_CLOCK_HOST;

        } else if (!strcmp(value, "rt")) {

            rtc_clock = QEMU_CLOCK_REALTIME;

        } else if (!strcmp(value, "vm")) {

            rtc_clock = QEMU_CLOCK_VIRTUAL;

        } else {

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

            exit(1);

        }

    }

    value = qemu_opt_get(opts, "driftfix");

    if (value) {

        if (!strcmp(value, "slew")) {

            static GlobalProperty slew_lost_ticks[] = {

                {

                    .driver   = "mc146818rtc",

                    .property = "lost_tick_policy",

                    .value    = "slew",

                },

                { /* end of list */ }

            };

            qdev_prop_register_global_list(slew_lost_ticks);

        } else if (!strcmp(value, "none")) {

            /* discard is default */

        } else {

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

            exit(1);

        }

    }

}


static inline void t_gen_zext(TCGv d, TCGv s, int size)

{

	if (size == 1)

		tcg_gen_ext8u_i32(d, s);

	else if (size == 2)

		tcg_gen_ext16u_i32(d, s);

	else if (GET_TCGV(d) != GET_TCGV(s))

		tcg_gen_mov_tl(d, s);

}


static ssize_t virtio_net_receive(VLANClientState *nc, const uint8_t *buf, size_t size)

{

    VirtIONet *n = DO_UPCAST(NICState, nc, nc)->opaque;

    struct virtio_net_hdr_mrg_rxbuf *mhdr = NULL;

    size_t hdr_len, offset, i;

    if (!virtio_net_can_receive(&n->nic->nc))

        return -1;

    /* hdr_len refers to the header we supply to the guest */

    hdr_len = n->mergeable_rx_bufs ?

        sizeof(struct virtio_net_hdr_mrg_rxbuf) : sizeof(struct virtio_net_hdr);

    if (!virtio_net_has_buffers(n, size + hdr_len))

        return 0;

    if (!receive_filter(n, buf, size))

        return size;

    offset = i = 0;

    while (offset < size) {

        VirtQueueElement elem;

        int len, total;

        struct iovec sg[VIRTQUEUE_MAX_SIZE];

        total = 0;

        if ((i != 0 && !n->mergeable_rx_bufs) ||

            virtqueue_pop(n->rx_vq, &elem) == 0) {

            if (i == 0)

                return -1;

            fprintf(stderr, "virtio-net truncating packet: "

                    "offset %zd, size %zd, hdr_len %zd\n",

                    offset, size, hdr_len);

            exit(1);

        }

        if (elem.in_num < 1) {

            fprintf(stderr, "virtio-net receive queue contains no in buffers\n");

            exit(1);

        }

        if (!n->mergeable_rx_bufs && elem.in_sg[0].iov_len != hdr_len) {

            fprintf(stderr, "virtio-net header not in first element\n");

            exit(1);

        }

        memcpy(&sg, &elem.in_sg[0], sizeof(sg[0]) * elem.in_num);

        if (i == 0) {

            if (n->mergeable_rx_bufs)

                mhdr = (struct virtio_net_hdr_mrg_rxbuf *)sg[0].iov_base;

            offset += receive_header(n, sg, elem.in_num,

                                     buf + offset, size - offset, hdr_len);

            total += hdr_len;

        }

        /* copy in packet.  ugh */

        len = iov_from_buf(sg, elem.in_num,

                           buf + offset, size - offset);

        total += len;

        /* signal other side */

        virtqueue_fill(n->rx_vq, &elem, total, i++);

        offset += len;

    }

    if (mhdr)

        mhdr->num_buffers = i;

    virtqueue_flush(n->rx_vq, i);

    virtio_notify(&n->vdev, n->rx_vq);

    return size;

}


static InputEvent *qapi_clone_InputEvent(InputEvent *src)

{

    QmpOutputVisitor *qov;

    QmpInputVisitor *qiv;

    Visitor *ov, *iv;

    QObject *obj;

    InputEvent *dst = NULL;

    qov = qmp_output_visitor_new();

    ov = qmp_output_get_visitor(qov);

    visit_type_InputEvent(ov, NULL, &src, &error_abort);

    obj = qmp_output_get_qobject(qov);

    qmp_output_visitor_cleanup(qov);

    if (!obj) {

        return NULL;

    }

    qiv = qmp_input_visitor_new(obj, false);

    iv = qmp_input_get_visitor(qiv);

    visit_type_InputEvent(iv, NULL, &dst, &error_abort);

    qmp_input_visitor_cleanup(qiv);

    qobject_decref(obj);

    return dst;

}


static void stop(DBDMA_channel *ch)

{

    ch->regs[DBDMA_STATUS] &= cpu_to_be32(~(ACTIVE|DEAD|FLUSH));

    /* the stop command does not increment command pointer */

}


void qmp_drive_mirror(const char *device, const char *target,

                      bool has_format, const char *format,

                      enum MirrorSyncMode sync,

                      bool has_mode, enum NewImageMode mode,

                      bool has_speed, int64_t speed,

                      bool has_granularity, uint32_t granularity,

                      bool has_buf_size, int64_t buf_size,

                      bool has_on_source_error, BlockdevOnError on_source_error,

                      bool has_on_target_error, BlockdevOnError on_target_error,

                      Error **errp)

{

    BlockDriverState *bs;

    BlockDriverState *source, *target_bs;

    BlockDriver *proto_drv;

    BlockDriver *drv = NULL;

    Error *local_err = NULL;

    int flags;

    uint64_t size;

    int ret;

    if (!has_speed) {

        speed = 0;

    }

    if (!has_on_source_error) {

        on_source_error = BLOCKDEV_ON_ERROR_REPORT;

    }

    if (!has_on_target_error) {

        on_target_error = BLOCKDEV_ON_ERROR_REPORT;

    }

    if (!has_mode) {

        mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;

    }

    if (!has_granularity) {

        granularity = 0;

    }

    if (!has_buf_size) {

        buf_size = DEFAULT_MIRROR_BUF_SIZE;

    }

    if (granularity != 0 && (granularity < 512 || granularity > 1048576 * 64)) {

        error_set(errp, QERR_INVALID_PARAMETER, device);

        return;

    }

    if (granularity & (granularity - 1)) {

        error_set(errp, QERR_INVALID_PARAMETER, device);

        return;

    }

    bs = bdrv_find(device);

    if (!bs) {

        error_set(errp, QERR_DEVICE_NOT_FOUND, device);

        return;

    }

    if (!bdrv_is_inserted(bs)) {

        error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);

        return;

    }

    if (!has_format) {

        format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs->drv->format_name;

    }

    if (format) {

        drv = bdrv_find_format(format);

        if (!drv) {

            error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

            return;

        }

    }

    if (bdrv_in_use(bs)) {

        error_set(errp, QERR_DEVICE_IN_USE, device);

        return;

    }

    flags = bs->open_flags | BDRV_O_RDWR;

    source = bs->backing_hd;

    if (!source && sync == MIRROR_SYNC_MODE_TOP) {

        sync = MIRROR_SYNC_MODE_FULL;

    }

    proto_drv = bdrv_find_protocol(target);

    if (!proto_drv) {

        error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);

        return;

    }

    bdrv_get_geometry(bs, &size);

    size *= 512;

    if (sync == MIRROR_SYNC_MODE_FULL && mode != NEW_IMAGE_MODE_EXISTING) {

        /* create new image w/o backing file */

        assert(format && drv);

        bdrv_img_create(target, format,

                        NULL, NULL, NULL, size, flags, &local_err, false);

    } else {

        switch (mode) {

        case NEW_IMAGE_MODE_EXISTING:

            ret = 0;

            break;

        case NEW_IMAGE_MODE_ABSOLUTE_PATHS:

            /* create new image with backing file */

            bdrv_img_create(target, format,

                            source->filename,

                            source->drv->format_name,

                            NULL, size, flags, &local_err, false);

            break;

        default:

            abort();

        }

    }

    if (error_is_set(&local_err)) {

        error_propagate(errp, local_err);

        return;

    }

    /* Mirroring takes care of copy-on-write using the source's backing

     * file.

     */

    target_bs = bdrv_new("");

    ret = bdrv_open(target_bs, target, NULL, flags | BDRV_O_NO_BACKING, drv);

    if (ret < 0) {

        bdrv_delete(target_bs);

        error_setg_file_open(errp, -ret, target);

        return;

    }

    mirror_start(bs, target_bs, speed, granularity, buf_size, sync,

                 on_source_error, on_target_error,

                 block_job_cb, bs, &local_err);

    if (local_err != NULL) {

        bdrv_delete(target_bs);

        error_propagate(errp, local_err);

        return;

    }

    /* Grab a reference so hotplug does not delete the BlockDriverState from

     * underneath us.

     */

    drive_get_ref(drive_get_by_blockdev(bs));

}


static void gen_delayed_conditional_jump(DisasContext * ctx)

{

    int l1;

    TCGv ds;

    l1 = gen_new_label();

    ds = tcg_temp_new();

    tcg_gen_andi_i32(ds, cpu_flags, DELAY_SLOT_TRUE);

    tcg_gen_brcondi_i32(TCG_COND_NE, ds, 0, l1);

    gen_goto_tb(ctx, 1, ctx->pc + 2);

    gen_set_label(l1);

    tcg_gen_andi_i32(cpu_flags, cpu_flags, ~DELAY_SLOT_TRUE);

    gen_jump(ctx);

}


static void qmp_input_type_number(Visitor *v, const char *name, double *obj,

                                  Error **errp)

{

    QmpInputVisitor *qiv = to_qiv(v);

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

    QInt *qint;

    QFloat *qfloat;

    if (!qobj) {

        return;

    }

    qint = qobject_to_qint(qobj);

    if (qint) {

        *obj = qint_get_int(qobject_to_qint(qobj));

        return;

    }

    qfloat = qobject_to_qfloat(qobj);

    if (qfloat) {

        *obj = qfloat_get_double(qobject_to_qfloat(qobj));

        return;

    }

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

               "number");

}


static void test_dynamic_globalprop(void)

{

    g_test_trap_subprocess("/qdev/properties/dynamic/global/subprocess", 0, 0);

    g_test_trap_assert_passed();

    g_test_trap_assert_stderr_unmatched("*prop1*");

    g_test_trap_assert_stderr_unmatched("*prop2*");

    g_test_trap_assert_stderr("*Warning: \"-global dynamic-prop-type-bad.prop3=103\" not used\n*");

    g_test_trap_assert_stderr_unmatched("*prop4*");

    g_test_trap_assert_stderr("*Warning: \"-global nohotplug-type.prop5=105\" not used\n*");

    g_test_trap_assert_stderr("*Warning: \"-global nondevice-type.prop6=106\" not used\n*");

    g_test_trap_assert_stdout("");

}


static void audio_init (void)

{

    size_t i;

    int done = 0;

    const char *drvname;

    VMChangeStateEntry *e;

    AudioState *s = &glob_audio_state;

    if (s->drv) {

        return;

    }

    QLIST_INIT (&s->hw_head_out);

    QLIST_INIT (&s->hw_head_in);

    QLIST_INIT (&s->cap_head);

    atexit (audio_atexit);

    s->ts = qemu_new_timer (vm_clock, audio_timer, s);

    if (!s->ts) {

        hw_error("Could not create audio timer\n");

    }

    audio_process_options ("AUDIO", audio_options);

    s->nb_hw_voices_out = conf.fixed_out.nb_voices;

    s->nb_hw_voices_in = conf.fixed_in.nb_voices;

    if (s->nb_hw_voices_out <= 0) {

        dolog ("Bogus number of playback voices %d, setting to 1\n",

               s->nb_hw_voices_out);

        s->nb_hw_voices_out = 1;

    }

    if (s->nb_hw_voices_in <= 0) {

        dolog ("Bogus number of capture voices %d, setting to 0\n",

               s->nb_hw_voices_in);

        s->nb_hw_voices_in = 0;

    }

    {

        int def;

        drvname = audio_get_conf_str ("QEMU_AUDIO_DRV", NULL, &def);

    }

    if (drvname) {

        int found = 0;

        for (i = 0; i < ARRAY_SIZE (drvtab); i++) {

            if (!strcmp (drvname, drvtab[i]->name)) {

                done = !audio_driver_init (s, drvtab[i]);

                found = 1;

                break;

            }

        }

        if (!found) {

            dolog ("Unknown audio driver `%s'\n", drvname);

            dolog ("Run with -audio-help to list available drivers\n");

        }

    }

    if (!done) {

        for (i = 0; !done && i < ARRAY_SIZE (drvtab); i++) {

            if (drvtab[i]->can_be_default) {

                done = !audio_driver_init (s, drvtab[i]);

            }

        }

    }

    if (!done) {

        done = !audio_driver_init (s, &no_audio_driver);

        if (!done) {

            hw_error("Could not initialize audio subsystem\n");

        }

        else {

            dolog ("warning: Using timer based audio emulation\n");

        }

    }

    if (conf.period.hertz <= 0) {

        if (conf.period.hertz < 0) {

            dolog ("warning: Timer period is negative - %d "

                   "treating as zero\n",

                   conf.period.hertz);

        }

        conf.period.ticks = 1;

    } else {

        conf.period.ticks =

            muldiv64 (1, get_ticks_per_sec (), conf.period.hertz);

    }

    e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);

    if (!e) {

        dolog ("warning: Could not register change state handler\n"

               "(Audio can continue looping even after stopping the VM)\n");

    }

    QLIST_INIT (&s->card_head);

    vmstate_register (NULL, 0, &vmstate_audio, s);

}


void build_memory_hotplug_aml(Aml *table, uint32_t nr_mem,

                              uint16_t io_base, uint16_t io_len,

                              const char *res_root,

                              const char *event_handler_method)

{

    int i;

    Aml *ifctx;

    Aml *method;

    Aml *sb_scope;

    Aml *mem_ctrl_dev;

    char *scan_path;

    char *mhp_res_path = g_strdup_printf("%s." MEMORY_HOTPLUG_DEVICE, res_root);

    mem_ctrl_dev = aml_device("%s", mhp_res_path);

    {

        Aml *crs;

        Aml *field;

        Aml *one = aml_int(1);

        Aml *zero = aml_int(0);

        Aml *ret_val = aml_local(0);

        Aml *slot_arg0 = aml_arg(0);

        Aml *slots_nr = aml_name(MEMORY_SLOTS_NUMBER);

        Aml *ctrl_lock = aml_name(MEMORY_SLOT_LOCK);

        Aml *slot_selector = aml_name(MEMORY_SLOT_SLECTOR);

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

        aml_append(mem_ctrl_dev,

            aml_name_decl("_UID", aml_string("Memory hotplug resources")));

        assert(nr_mem <= ACPI_MAX_RAM_SLOTS);

        aml_append(mem_ctrl_dev,

            aml_name_decl(MEMORY_SLOTS_NUMBER, aml_int(nr_mem))

        );

        crs = aml_resource_template();

        aml_append(crs,

            aml_io(AML_DECODE16, io_base, io_base, 0, io_len)

        );

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

        aml_append(mem_ctrl_dev, aml_operation_region(

            MEMORY_HOTPLUG_IO_REGION, AML_SYSTEM_IO,

            aml_int(io_base), io_len)

        );

        field = aml_field(MEMORY_HOTPLUG_IO_REGION, AML_DWORD_ACC,

                          AML_NOLOCK, AML_PRESERVE);

        aml_append(field, /* read only */

            aml_named_field(MEMORY_SLOT_ADDR_LOW, 32));

        aml_append(field, /* read only */

            aml_named_field(MEMORY_SLOT_ADDR_HIGH, 32));

        aml_append(field, /* read only */

            aml_named_field(MEMORY_SLOT_SIZE_LOW, 32));

        aml_append(field, /* read only */

            aml_named_field(MEMORY_SLOT_SIZE_HIGH, 32));

        aml_append(field, /* read only */

            aml_named_field(MEMORY_SLOT_PROXIMITY, 32));

        aml_append(mem_ctrl_dev, field);

        field = aml_field(MEMORY_HOTPLUG_IO_REGION, AML_BYTE_ACC,

                          AML_NOLOCK, AML_WRITE_AS_ZEROS);

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

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

            aml_named_field(MEMORY_SLOT_ENABLED, 1));

        aml_append(field,

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

            aml_named_field(MEMORY_SLOT_INSERT_EVENT, 1));

        aml_append(field,

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

            aml_named_field(MEMORY_SLOT_REMOVE_EVENT, 1));

        aml_append(field,

            /* initiates device eject, write only */

            aml_named_field(MEMORY_SLOT_EJECT, 1));

        aml_append(mem_ctrl_dev, field);

        field = aml_field(MEMORY_HOTPLUG_IO_REGION, AML_DWORD_ACC,

                          AML_NOLOCK, AML_PRESERVE);

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

            aml_named_field(MEMORY_SLOT_SLECTOR, 32));

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

            aml_named_field(MEMORY_SLOT_OST_EVENT, 32));

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

            aml_named_field(MEMORY_SLOT_OST_STATUS, 32));

        aml_append(mem_ctrl_dev, field);

        method = aml_method("_STA", 0, AML_NOTSERIALIZED);

        ifctx = aml_if(aml_equal(slots_nr, zero));

        {

            aml_append(ifctx, aml_return(zero));

        }

        aml_append(method, ifctx);

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

        aml_append(method, aml_return(aml_int(0xB)));

        aml_append(mem_ctrl_dev, method);

        aml_append(mem_ctrl_dev, aml_mutex(MEMORY_SLOT_LOCK, 0));

        method = aml_method(MEMORY_SLOT_SCAN_METHOD, 0, AML_NOTSERIALIZED);

        {

            Aml *else_ctx;

            Aml *while_ctx;

            Aml *idx = aml_local(0);

            Aml *eject_req = aml_int(3);

            Aml *dev_chk = aml_int(1);

            ifctx = aml_if(aml_equal(slots_nr, zero));

            {

                aml_append(ifctx, aml_return(zero));

            }

            aml_append(method, ifctx);

            aml_append(method, aml_store(zero, idx));

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));

            /* build AML that:

             * loops over all slots and Notifies DIMMs with

             * Device Check or Eject Request notifications if

             * slot has corresponding status bit set and clears

             * slot status.

             */

            while_ctx = aml_while(aml_lless(idx, slots_nr));

            {

                Aml *ins_evt = aml_name(MEMORY_SLOT_INSERT_EVENT);

                Aml *rm_evt = aml_name(MEMORY_SLOT_REMOVE_EVENT);

                aml_append(while_ctx, aml_store(idx, slot_selector));

                ifctx = aml_if(aml_equal(ins_evt, one));

                {

                    aml_append(ifctx,

                               aml_call2(MEMORY_SLOT_NOTIFY_METHOD,

                                         idx, dev_chk));

                    aml_append(ifctx, aml_store(one, ins_evt));

                }

                aml_append(while_ctx, ifctx);

                else_ctx = aml_else();

                ifctx = aml_if(aml_equal(rm_evt, one));

                {

                    aml_append(ifctx,

                        aml_call2(MEMORY_SLOT_NOTIFY_METHOD,

                                  idx, eject_req));

                    aml_append(ifctx, aml_store(one, rm_evt));

                }

                aml_append(else_ctx, ifctx);

                aml_append(while_ctx, else_ctx);

                aml_append(while_ctx, aml_add(idx, one, idx));

            }

            aml_append(method, while_ctx);

            aml_append(method, aml_release(ctrl_lock));

            aml_append(method, aml_return(one));

        }

        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_STATUS_METHOD, 1, AML_NOTSERIALIZED);

        {

            Aml *slot_enabled = aml_name(MEMORY_SLOT_ENABLED);

            aml_append(method, aml_store(zero, ret_val));

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));

            aml_append(method,

                aml_store(aml_to_integer(slot_arg0), slot_selector));

            ifctx = aml_if(aml_equal(slot_enabled, one));

            {

                aml_append(ifctx, aml_store(aml_int(0xF), ret_val));

            }

            aml_append(method, ifctx);

            aml_append(method, aml_release(ctrl_lock));

            aml_append(method, aml_return(ret_val));

        }

        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_CRS_METHOD, 1, AML_SERIALIZED);

        {

            Aml *mr64 = aml_name("MR64");

            Aml *mr32 = aml_name("MR32");

            Aml *crs_tmpl = aml_resource_template();

            Aml *minl = aml_name("MINL");

            Aml *minh = aml_name("MINH");

            Aml *maxl =  aml_name("MAXL");

            Aml *maxh =  aml_name("MAXH");

            Aml *lenl = aml_name("LENL");

            Aml *lenh = aml_name("LENH");

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));

            aml_append(method, aml_store(aml_to_integer(slot_arg0),

                                         slot_selector));

            aml_append(crs_tmpl,

                aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,

                                 AML_CACHEABLE, AML_READ_WRITE,

                                 0, 0x0, 0xFFFFFFFFFFFFFFFEULL, 0,

                                 0xFFFFFFFFFFFFFFFFULL));

            aml_append(method, aml_name_decl("MR64", crs_tmpl));

            aml_append(method,

                aml_create_dword_field(mr64, aml_int(14), "MINL"));

            aml_append(method,

                aml_create_dword_field(mr64, aml_int(18), "MINH"));

            aml_append(method,

                aml_create_dword_field(mr64, aml_int(38), "LENL"));

            aml_append(method,

                aml_create_dword_field(mr64, aml_int(42), "LENH"));

            aml_append(method,

                aml_create_dword_field(mr64, aml_int(22), "MAXL"));

            aml_append(method,

                aml_create_dword_field(mr64, aml_int(26), "MAXH"));

            aml_append(method,

                aml_store(aml_name(MEMORY_SLOT_ADDR_HIGH), minh));

            aml_append(method,

                aml_store(aml_name(MEMORY_SLOT_ADDR_LOW), minl));

            aml_append(method,

                aml_store(aml_name(MEMORY_SLOT_SIZE_HIGH), lenh));

            aml_append(method,

                aml_store(aml_name(MEMORY_SLOT_SIZE_LOW), lenl));

            /* 64-bit math: MAX = MIN + LEN - 1 */

            aml_append(method, aml_add(minl, lenl, maxl));

            aml_append(method, aml_add(minh, lenh, maxh));

            ifctx = aml_if(aml_lless(maxl, minl));

            {

                aml_append(ifctx, aml_add(maxh, one, maxh));

            }

            aml_append(method, ifctx);

            ifctx = aml_if(aml_lless(maxl, one));

            {

                aml_append(ifctx, aml_subtract(maxh, one, maxh));

            }

            aml_append(method, ifctx);

            aml_append(method, aml_subtract(maxl, one, maxl));

            /* return 32-bit _CRS if addr/size is in low mem */

            /* TODO: remove it since all hotplugged DIMMs are in high mem */

            ifctx = aml_if(aml_equal(maxh, zero));

            {

                crs_tmpl = aml_resource_template();

                aml_append(crs_tmpl,

                    aml_dword_memory(AML_POS_DECODE, AML_MIN_FIXED,

                                     AML_MAX_FIXED, AML_CACHEABLE,

                                     AML_READ_WRITE,

                                     0, 0x0, 0xFFFFFFFE, 0,

                                     0xFFFFFFFF));

                aml_append(ifctx, aml_name_decl("MR32", crs_tmpl));

                aml_append(ifctx,

                    aml_create_dword_field(mr32, aml_int(10), "MIN"));

                aml_append(ifctx,

                    aml_create_dword_field(mr32, aml_int(14), "MAX"));

                aml_append(ifctx,

                    aml_create_dword_field(mr32, aml_int(22), "LEN"));

                aml_append(ifctx, aml_store(minl, aml_name("MIN")));

                aml_append(ifctx, aml_store(maxl, aml_name("MAX")));

                aml_append(ifctx, aml_store(lenl, aml_name("LEN")));

                aml_append(ifctx, aml_release(ctrl_lock));

                aml_append(ifctx, aml_return(mr32));

            }

            aml_append(method, ifctx);

            aml_append(method, aml_release(ctrl_lock));

            aml_append(method, aml_return(mr64));

        }

        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_PROXIMITY_METHOD, 1,

                            AML_NOTSERIALIZED);

        {

            Aml *proximity = aml_name(MEMORY_SLOT_PROXIMITY);

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));

            aml_append(method, aml_store(aml_to_integer(slot_arg0),

                                         slot_selector));

            aml_append(method, aml_store(proximity, ret_val));

            aml_append(method, aml_release(ctrl_lock));

            aml_append(method, aml_return(ret_val));

        }

        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_OST_METHOD, 4, AML_NOTSERIALIZED);

        {

            Aml *ost_evt = aml_name(MEMORY_SLOT_OST_EVENT);

            Aml *ost_status = aml_name(MEMORY_SLOT_OST_STATUS);

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));

            aml_append(method, aml_store(aml_to_integer(slot_arg0),

                                         slot_selector));

            aml_append(method, aml_store(aml_arg(1), ost_evt));

            aml_append(method, aml_store(aml_arg(2), ost_status));

            aml_append(method, aml_release(ctrl_lock));

        }

        aml_append(mem_ctrl_dev, method);

        method = aml_method(MEMORY_SLOT_EJECT_METHOD, 2, AML_NOTSERIALIZED);

        {

            Aml *eject = aml_name(MEMORY_SLOT_EJECT);

            aml_append(method, aml_acquire(ctrl_lock, 0xFFFF));

            aml_append(method, aml_store(aml_to_integer(slot_arg0),

                                         slot_selector));

            aml_append(method, aml_store(one, eject));

            aml_append(method, aml_release(ctrl_lock));

        }

        aml_append(mem_ctrl_dev, method);

    }

    aml_append(table, mem_ctrl_dev);

    sb_scope = aml_scope("_SB");

    /* build memory devices */

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

        Aml *dev;

        char *s;

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

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

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

        method = aml_method("_CRS", 0, AML_NOTSERIALIZED);

        s = g_strdup_printf("%s.%s", mhp_res_path, MEMORY_SLOT_CRS_METHOD);

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

        g_free(s);

        aml_append(dev, method);

        method = aml_method("_STA", 0, AML_NOTSERIALIZED);

        s = g_strdup_printf("%s.%s", mhp_res_path, MEMORY_SLOT_STATUS_METHOD);

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

        g_free(s);

        aml_append(dev, method);

        method = aml_method("_PXM", 0, AML_NOTSERIALIZED);

        s = g_strdup_printf("%s.%s", mhp_res_path,

                            MEMORY_SLOT_PROXIMITY_METHOD);

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

        g_free(s);

        aml_append(dev, method);

        method = aml_method("_OST", 3, AML_NOTSERIALIZED);

        s = g_strdup_printf("%s.%s", mhp_res_path, MEMORY_SLOT_OST_METHOD);

        aml_append(method, aml_return(aml_call4(

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

        )));

        g_free(s);

        aml_append(dev, method);

        method = aml_method("_EJ0", 1, AML_NOTSERIALIZED);

        s = g_strdup_printf("%s.%s", mhp_res_path, MEMORY_SLOT_EJECT_METHOD);

        aml_append(method, aml_return(aml_call2(

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

        g_free(s);

        aml_append(dev, method);

        aml_append(sb_scope, dev);

    }

    /* build Method(MEMORY_SLOT_NOTIFY_METHOD, 2) {

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

     */

    method = aml_method(MEMORY_SLOT_NOTIFY_METHOD, 2, AML_NOTSERIALIZED);

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

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

        aml_append(ifctx,

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

        );

        aml_append(method, ifctx);

    }

    aml_append(sb_scope, method);

    aml_append(table, sb_scope);

    method = aml_method(event_handler_method, 0, AML_NOTSERIALIZED);

    scan_path = g_strdup_printf("%s.%s", mhp_res_path, MEMORY_SLOT_SCAN_METHOD);

    aml_append(method, aml_call0(scan_path));

    g_free(scan_path);

    aml_append(table, method);

    g_free(mhp_res_path);

}


char *g_strdup_printf(const char *format, ...)

{

    char ch, *s;

    size_t len;

    __coverity_string_null_sink__(format);

    __coverity_string_size_sink__(format);

    ch = *format;

    s = __coverity_alloc_nosize__();

    __coverity_writeall__(s);

    __coverity_mark_as_afm_allocated__(s, AFM_free);

    return s;

}


static int check_features_against_host(x86_def_t *guest_def)

{

    x86_def_t host_def;

    uint32_t mask;

    int rv, i;

    struct model_features_t ft[] = {

        {&guest_def->features, &host_def.features,

            ~0, feature_name, 0x00000000},

        {&guest_def->ext_features, &host_def.ext_features,

            ~CPUID_EXT_HYPERVISOR, ext_feature_name, 0x00000001},

        {&guest_def->ext2_features, &host_def.ext2_features,

            ~PPRO_FEATURES, ext2_feature_name, 0x80000000},

        {&guest_def->ext3_features, &host_def.ext3_features,

            ~CPUID_EXT3_SVM, ext3_feature_name, 0x80000001}};

    cpu_x86_fill_host(&host_def);

    for (rv = 0, i = 0; i < ARRAY_SIZE(ft); ++i)

        for (mask = 1; mask; mask <<= 1)

            if (ft[i].check_feat & mask && *ft[i].guest_feat & mask &&

                !(*ft[i].host_feat & mask)) {

                    unavailable_host_feature(&ft[i], mask);

                    rv = 1;

                }

    return rv;

}


static int rkmpp_retrieve_frame(AVCodecContext *avctx, AVFrame *frame)

{

    RKMPPDecodeContext *rk_context = avctx->priv_data;

    RKMPPDecoder *decoder = (RKMPPDecoder *)rk_context->decoder_ref->data;

    RKMPPFrameContext *framecontext = NULL;

    AVBufferRef *framecontextref = NULL;

    int ret;

    MppFrame mppframe = NULL;

    MppBuffer buffer = NULL;

    AVDRMFrameDescriptor *desc = NULL;

    AVDRMLayerDescriptor *layer = NULL;

    int retrycount = 0;

    int mode;

    MppFrameFormat mppformat;

    uint32_t drmformat;

    // on start of decoding, MPP can return -1, which is supposed to be expected

    // this is due to some internal MPP init which is not completed, that will

    // only happen in the first few frames queries, but should not be interpreted

    // as an error, Therefore we need to retry a couple times when we get -1

    // in order to let it time to complete it's init, then we sleep a bit between retries.

retry_get_frame:

    ret = decoder->mpi->decode_get_frame(decoder->ctx, &mppframe);

    if (ret != MPP_OK && ret != MPP_ERR_TIMEOUT && !decoder->first_frame) {

        if (retrycount < 5) {

            av_log(avctx, AV_LOG_DEBUG, "Failed to get a frame, retrying (code = %d, retrycount = %d)\n", ret, retrycount);

            usleep(10000);

            retrycount++;

            goto retry_get_frame;

        } else {

            av_log(avctx, AV_LOG_ERROR, "Failed to get a frame from MPP (code = %d)\n", ret);

            goto fail;

        }

    }

    if (mppframe) {

        // Check wether we have a special frame or not

        if (mpp_frame_get_info_change(mppframe)) {

            AVHWFramesContext *hwframes;

            av_log(avctx, AV_LOG_INFO, "Decoder noticed an info change (%dx%d), format=%d\n",

                                        (int)mpp_frame_get_width(mppframe), (int)mpp_frame_get_height(mppframe),

                                        (int)mpp_frame_get_fmt(mppframe));

            avctx->width = mpp_frame_get_width(mppframe);

            avctx->height = mpp_frame_get_height(mppframe);

            decoder->mpi->control(decoder->ctx, MPP_DEC_SET_INFO_CHANGE_READY, NULL);

            decoder->first_frame = 1;

            av_buffer_unref(&decoder->frames_ref);

            decoder->frames_ref = av_hwframe_ctx_alloc(decoder->device_ref);

            if (!decoder->frames_ref) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            mppformat = mpp_frame_get_fmt(mppframe);

            drmformat = rkmpp_get_frameformat(mppformat);

            hwframes = (AVHWFramesContext*)decoder->frames_ref->data;

            hwframes->format    = AV_PIX_FMT_DRM_PRIME;

            hwframes->sw_format = drmformat == DRM_FORMAT_NV12 ? AV_PIX_FMT_NV12 : AV_PIX_FMT_NONE;

            hwframes->width     = avctx->width;

            hwframes->height    = avctx->height;

            ret = av_hwframe_ctx_init(decoder->frames_ref);

            if (ret < 0)

                goto fail;

            // here decoder is fully initialized, we need to feed it again with data

            ret = AVERROR(EAGAIN);

            goto fail;

        } else if (mpp_frame_get_eos(mppframe)) {

            av_log(avctx, AV_LOG_DEBUG, "Received a EOS frame.\n");

            decoder->eos_reached = 1;

            ret = AVERROR_EOF;

            goto fail;

        } else if (mpp_frame_get_discard(mppframe)) {

            av_log(avctx, AV_LOG_DEBUG, "Received a discard frame.\n");

            ret = AVERROR(EAGAIN);

            goto fail;

        } else if (mpp_frame_get_errinfo(mppframe)) {

            av_log(avctx, AV_LOG_ERROR, "Received a errinfo frame.\n");

            ret = AVERROR_UNKNOWN;

            goto fail;

        }

        // here we should have a valid frame

        av_log(avctx, AV_LOG_DEBUG, "Received a frame.\n");

        // setup general frame fields

        frame->format           = AV_PIX_FMT_DRM_PRIME;

        frame->width            = mpp_frame_get_width(mppframe);

        frame->height           = mpp_frame_get_height(mppframe);

        frame->pts              = mpp_frame_get_pts(mppframe);

        frame->color_range      = mpp_frame_get_color_range(mppframe);

        frame->color_primaries  = mpp_frame_get_color_primaries(mppframe);

        frame->color_trc        = mpp_frame_get_color_trc(mppframe);

        frame->colorspace       = mpp_frame_get_colorspace(mppframe);

        mode = mpp_frame_get_mode(mppframe);

        frame->interlaced_frame = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_DEINTERLACED);

        frame->top_field_first  = ((mode & MPP_FRAME_FLAG_FIELD_ORDER_MASK) == MPP_FRAME_FLAG_TOP_FIRST);

        mppformat = mpp_frame_get_fmt(mppframe);

        drmformat = rkmpp_get_frameformat(mppformat);

        // now setup the frame buffer info

        buffer = mpp_frame_get_buffer(mppframe);

        if (buffer) {

            desc = av_mallocz(sizeof(AVDRMFrameDescriptor));

            if (!desc) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            desc->nb_objects = 1;

            desc->objects[0].fd = mpp_buffer_get_fd(buffer);

            desc->objects[0].size = mpp_buffer_get_size(buffer);

            desc->nb_layers = 1;

            layer = &desc->layers[0];

            layer->format = drmformat;

            layer->nb_planes = 2;

            layer->planes[0].object_index = 0;

            layer->planes[0].offset = 0;

            layer->planes[0].pitch = mpp_frame_get_hor_stride(mppframe);

            layer->planes[1].object_index = 0;

            layer->planes[1].offset = layer->planes[0].pitch * mpp_frame_get_ver_stride(mppframe);

            layer->planes[1].pitch = layer->planes[0].pitch;

            // we also allocate a struct in buf[0] that will allow to hold additionnal information

            // for releasing properly MPP frames and decoder

            framecontextref = av_buffer_allocz(sizeof(*framecontext));

            if (!framecontextref) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            // MPP decoder needs to be closed only when all frames have been released.

            framecontext = (RKMPPFrameContext *)framecontextref->data;

            framecontext->decoder_ref = av_buffer_ref(rk_context->decoder_ref);

            framecontext->frame = mppframe;

            frame->data[0]  = (uint8_t *)desc;

            frame->buf[0]   = av_buffer_create((uint8_t *)desc, sizeof(*desc), rkmpp_release_frame,

                                               framecontextref, AV_BUFFER_FLAG_READONLY);

            if (!frame->buf[0]) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            frame->hw_frames_ctx = av_buffer_ref(decoder->frames_ref);

            if (!frame->hw_frames_ctx) {

                ret = AVERROR(ENOMEM);

                goto fail;

            }

            decoder->first_frame = 0;

            return 0;

        } else {

            av_log(avctx, AV_LOG_ERROR, "Failed to retrieve the frame buffer, frame is dropped (code = %d)\n", ret);

            mpp_frame_deinit(&mppframe);

        }

    } else if (decoder->eos_reached) {

        return AVERROR_EOF;

    } else if (ret == MPP_ERR_TIMEOUT) {

        av_log(avctx, AV_LOG_DEBUG, "Timeout when trying to get a frame from MPP\n");

    }

    return AVERROR(EAGAIN);

fail:

    if (mppframe)

        mpp_frame_deinit(&mppframe);

    if (framecontext)

        av_buffer_unref(&framecontext->decoder_ref);

    if (framecontextref)

        av_buffer_unref(&framecontextref);

    if (desc)

        av_free(desc);

    return ret;

}


START_TEST(qfloat_from_double_test)

{

    QFloat *qf;

    const double value = -42.23423;

    qf = qfloat_from_double(value);

    fail_unless(qf != NULL);

    fail_unless(qf->value == value);

    fail_unless(qf->base.refcnt == 1);

    fail_unless(qobject_type(QOBJECT(qf)) == QTYPE_QFLOAT);

    // destroy doesn't exit yet

    g_free(qf);

}


static int vnc_start_vencrypt_handshake(struct VncState *vs) {

    int ret;

    if ((ret = gnutls_handshake(vs->tls.session)) < 0) {

       if (!gnutls_error_is_fatal(ret)) {

           VNC_DEBUG("Handshake interrupted (blocking)\n");

           if (!gnutls_record_get_direction(vs->tls.session))

               qemu_set_fd_handler(vs->csock, vnc_tls_handshake_io, NULL, vs);

           else

               qemu_set_fd_handler(vs->csock, NULL, vnc_tls_handshake_io, vs);

           return 0;

       }

       VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret));

       vnc_client_error(vs);

       return -1;

    }

    if (vs->vd->tls.x509verify) {

        if (vnc_tls_validate_certificate(vs) < 0) {

            VNC_DEBUG("Client verification failed\n");

            vnc_client_error(vs);

            return -1;

        } else {

            VNC_DEBUG("Client verification passed\n");

        }

    }

    VNC_DEBUG("Handshake done, switching to TLS data mode\n");

    qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs);

    start_auth_vencrypt_subauth(vs);

    return 0;

}


static void spapr_powerdown_req(Notifier *n, void *opaque)

{

    sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());

    struct rtas_error_log *hdr;

    struct rtas_event_log_v6 *v6hdr;

    struct rtas_event_log_v6_maina *maina;

    struct rtas_event_log_v6_mainb *mainb;

    struct rtas_event_log_v6_epow *epow;

    struct epow_log_full *new_epow;

    new_epow = g_malloc0(sizeof(*new_epow));

    hdr = &new_epow->hdr;

    v6hdr = &new_epow->v6hdr;

    maina = &new_epow->maina;

    mainb = &new_epow->mainb;

    epow = &new_epow->epow;

    hdr->summary = cpu_to_be32(RTAS_LOG_VERSION_6

                               | RTAS_LOG_SEVERITY_EVENT

                               | RTAS_LOG_DISPOSITION_NOT_RECOVERED

                               | RTAS_LOG_OPTIONAL_PART_PRESENT

                               | RTAS_LOG_TYPE_EPOW);

    hdr->extended_length = cpu_to_be32(sizeof(*new_epow)

                                       - sizeof(new_epow->hdr));

    spapr_init_v6hdr(v6hdr);

    spapr_init_maina(maina, 3 /* Main-A, Main-B and EPOW */);

    mainb->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_MAINB);

    mainb->hdr.section_length = cpu_to_be16(sizeof(*mainb));

    /* FIXME: section version, subtype and creator id? */

    mainb->subsystem_id = 0xa0; /* External environment */

    mainb->event_severity = 0x00; /* Informational / non-error */

    mainb->event_subtype = 0xd0; /* Normal shutdown */

    epow->hdr.section_id = cpu_to_be16(RTAS_LOG_V6_SECTION_ID_EPOW);

    epow->hdr.section_length = cpu_to_be16(sizeof(*epow));

    epow->hdr.section_version = 2; /* includes extended modifier */

    /* FIXME: section subtype and creator id? */

    epow->sensor_value = RTAS_LOG_V6_EPOW_ACTION_SYSTEM_SHUTDOWN;

    epow->event_modifier = RTAS_LOG_V6_EPOW_MODIFIER_NORMAL;

    epow->extended_modifier = RTAS_LOG_V6_EPOW_XMODIFIER_PARTITION_SPECIFIC;

    rtas_event_log_queue(RTAS_LOG_TYPE_EPOW, new_epow);

    qemu_irq_pulse(xics_get_qirq(XICS_FABRIC(spapr),

                                 rtas_event_log_to_irq(spapr,

                                                       RTAS_LOG_TYPE_EPOW)));

}


static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file,

    QDict *options, int flags, BlockDriver *drv, Error **errp)

{

    int ret, open_flags;

    const char *filename;

    const char *node_name = NULL;

    Error *local_err = NULL;

    assert(drv != NULL);

    assert(bs->file == NULL);

    assert(options != NULL && bs->options != options);

    if (file != NULL) {

        filename = file->filename;

    } else {

        filename = qdict_get_try_str(options, "filename");

    }

    if (drv->bdrv_needs_filename && !filename) {

        error_setg(errp, "The '%s' block driver requires a file name",

                   drv->format_name);

        return -EINVAL;

    }

    trace_bdrv_open_common(bs, filename ?: "", flags, drv->format_name);

    node_name = qdict_get_try_str(options, "node-name");

    bdrv_assign_node_name(bs, node_name, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        return -EINVAL;

    }

    qdict_del(options, "node-name");

    /* bdrv_open() with directly using a protocol as drv. This layer is already

     * opened, so assign it to bs (while file becomes a closed BlockDriverState)

     * and return immediately. */

    if (file != NULL && drv->bdrv_file_open) {

        bdrv_swap(file, bs);

        return 0;

    }

    bs->open_flags = flags;

    bs->guest_block_size = 512;

    bs->request_alignment = 512;

    bs->zero_beyond_eof = true;

    open_flags = bdrv_open_flags(bs, flags);

    bs->read_only = !(open_flags & BDRV_O_RDWR);

    if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, bs->read_only)) {

        error_setg(errp,

                   !bs->read_only && bdrv_is_whitelisted(drv, true)

                        ? "Driver '%s' can only be used for read-only devices"

                        : "Driver '%s' is not whitelisted",

                   drv->format_name);

        return -ENOTSUP;

    }

    assert(bs->copy_on_read == 0); /* bdrv_new() and bdrv_close() make it so */

    if (flags & BDRV_O_COPY_ON_READ) {

        if (!bs->read_only) {

            bdrv_enable_copy_on_read(bs);

        } else {

            error_setg(errp, "Can't use copy-on-read on read-only device");

            return -EINVAL;

        }

    }

    if (filename != NULL) {

        pstrcpy(bs->filename, sizeof(bs->filename), filename);

    } else {

        bs->filename[0] = '\0';

    }

    pstrcpy(bs->exact_filename, sizeof(bs->exact_filename), bs->filename);

    bs->drv = drv;

    bs->opaque = g_malloc0(drv->instance_size);

    bs->enable_write_cache = !!(flags & BDRV_O_CACHE_WB);

    /* Open the image, either directly or using a protocol */

    if (drv->bdrv_file_open) {

        assert(file == NULL);

        assert(!drv->bdrv_needs_filename || filename != NULL);

        ret = drv->bdrv_file_open(bs, options, open_flags, &local_err);

    } else {

        if (file == NULL) {

            error_setg(errp, "Can't use '%s' as a block driver for the "

                       "protocol level", drv->format_name);

            ret = -EINVAL;

            goto free_and_fail;

        }

        bs->file = file;

        ret = drv->bdrv_open(bs, options, open_flags, &local_err);

    }

    if (ret < 0) {

        if (local_err) {

            error_propagate(errp, local_err);

        } else if (bs->filename[0]) {

            error_setg_errno(errp, -ret, "Could not open '%s'", bs->filename);

        } else {

            error_setg_errno(errp, -ret, "Could not open image");

        }

        goto free_and_fail;

    }

    if (bs->encrypted) {

        error_report("Encrypted images are deprecated");

        error_printf("Support for them will be removed in a future release.\n"

                     "You can use 'qemu-img convert' to convert your image"

                     " to an unencrypted one.\n");

    }

    ret = refresh_total_sectors(bs, bs->total_sectors);

    if (ret < 0) {

        error_setg_errno(errp, -ret, "Could not refresh total sector count");

        goto free_and_fail;

    }

    bdrv_refresh_limits(bs, &local_err);

    if (local_err) {

        error_propagate(errp, local_err);

        ret = -EINVAL;

        goto free_and_fail;

    }

    assert(bdrv_opt_mem_align(bs) != 0);

    assert(bdrv_min_mem_align(bs) != 0);

    assert((bs->request_alignment != 0) || bs->sg);

    return 0;

free_and_fail:

    bs->file = NULL;

    g_free(bs->opaque);

    bs->opaque = NULL;

    bs->drv = NULL;

    return ret;

}


static uint32_t bonito_spciconf_readl(void *opaque, target_phys_addr_t addr)

{

    PCIBonitoState *s = opaque;

    PCIDevice *d = PCI_DEVICE(s);

    PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost);

    uint32_t pciaddr;

    uint16_t status;

    DPRINTF("bonito_spciconf_readl "TARGET_FMT_plx"\n", addr);

    assert((addr & 0x3) == 0);

    pciaddr = bonito_sbridge_pciaddr(s, addr);

    if (pciaddr == 0xffffffff) {

        return 0xffffffff;

    }

    /* set the pci address in s->config_reg */

    phb->config_reg = (pciaddr) | (1u << 31);

    /* clear PCI_STATUS_REC_MASTER_ABORT and PCI_STATUS_REC_TARGET_ABORT */

    status = pci_get_word(d->config + PCI_STATUS);

    status &= ~(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT);

    pci_set_word(d->config + PCI_STATUS, status);

    return pci_data_read(phb->bus, phb->config_reg, 4);

}


static VirtIOSerialPort *find_port_by_name(char *name)

{

    VirtIOSerial *vser;

    QLIST_FOREACH(vser, &vserdevices.devices, next) {

        VirtIOSerialPort *port;

        QTAILQ_FOREACH(port, &vser->ports, next) {

            if (!strcmp(port->name, name)) {

                return port;

            }

        }

    }

    return NULL;

}


void op_mtc0_status (void)

{

    uint32_t val, old;

    uint32_t mask = env->Status_rw_bitmask;

    /* No reverse endianness, no MDMX/DSP, no 64bit ops

       implemented. */

    val = T0 & mask;

    old = env->CP0_Status;

    if (!(val & (1 << CP0St_EXL)) &&

        !(val & (1 << CP0St_ERL)) &&

        !(env->hflags & MIPS_HFLAG_DM) &&

        (val & (1 << CP0St_UM)))

        env->hflags |= MIPS_HFLAG_UM;

#ifdef TARGET_MIPS64

    if ((env->hflags & MIPS_HFLAG_UM) &&

        !(val & (1 << CP0St_PX)) &&

        !(val & (1 << CP0St_UX)))

        env->hflags &= ~MIPS_HFLAG_64;

#endif

    env->CP0_Status = (env->CP0_Status & ~mask) | val;

    if (loglevel & CPU_LOG_EXEC)

        CALL_FROM_TB2(do_mtc0_status_debug, old, val);

    CALL_FROM_TB1(cpu_mips_update_irq, env);

    RETURN();

}


static inline uint32_t ldl_phys_internal(target_phys_addr_t addr,

                                         enum device_endian endian)

{

    uint8_t *ptr;

    uint32_t val;

    MemoryRegionSection *section;

    section = phys_page_find(address_space_memory.dispatch, addr >> TARGET_PAGE_BITS);

    if (!(memory_region_is_ram(section->mr) ||

          memory_region_is_romd(section->mr))) {

        /* I/O case */

        addr = memory_region_section_addr(section, addr);

        val = io_mem_read(section->mr, addr, 4);

#if defined(TARGET_WORDS_BIGENDIAN)

        if (endian == DEVICE_LITTLE_ENDIAN) {

            val = bswap32(val);

        }

#else

        if (endian == DEVICE_BIG_ENDIAN) {

            val = bswap32(val);

        }

#endif

    } else {

        /* RAM case */

        ptr = qemu_get_ram_ptr((memory_region_get_ram_addr(section->mr)

                                & TARGET_PAGE_MASK)

                               + memory_region_section_addr(section, addr));

        switch (endian) {

        case DEVICE_LITTLE_ENDIAN:

            val = ldl_le_p(ptr);

            break;

        case DEVICE_BIG_ENDIAN:

            val = ldl_be_p(ptr);

            break;

        default:

            val = ldl_p(ptr);

            break;

        }

    }

    return val;

}


static int vtd_irte_get(IntelIOMMUState *iommu, uint16_t index,

                        VTD_IRTE *entry)

{

    dma_addr_t addr = 0x00;

    addr = iommu->intr_root + index * sizeof(*entry);

    if (dma_memory_read(&address_space_memory, addr, entry,

                        sizeof(*entry))) {

        VTD_DPRINTF(GENERAL, "error: fail to access IR root at 0x%"PRIx64

                    " + %"PRIu16, iommu->intr_root, index);

        return -VTD_FR_IR_ROOT_INVAL;

    }

    if (!entry->present) {

        VTD_DPRINTF(GENERAL, "error: present flag not set in IRTE"

                    " entry index %u value 0x%"PRIx64 " 0x%"PRIx64,

                    index, le64_to_cpu(entry->data[1]),

                    le64_to_cpu(entry->data[0]));

        return -VTD_FR_IR_ENTRY_P;

    }

    if (entry->__reserved_0 || entry->__reserved_1 || \

        entry->__reserved_2) {

        VTD_DPRINTF(GENERAL, "error: IRTE entry index %"PRIu16

                    " reserved fields non-zero: 0x%"PRIx64 " 0x%"PRIx64,

                    index, le64_to_cpu(entry->data[1]),

                    le64_to_cpu(entry->data[0]));

        return -VTD_FR_IR_IRTE_RSVD;

    }

    /*

     * TODO: Check Source-ID corresponds to SVT (Source Validation

     * Type) bits

     */

    return 0;

}


static CharDriverState *qemu_chr_open_pty(void)

{

    struct termios tty;

    int master_fd, slave_fd;

    if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) < 0) {

        return NULL;

    }

    /* Set raw attributes on the pty. */

    cfmakeraw(&tty);

    tcsetattr(slave_fd, TCSAFLUSH, &tty);

    fprintf(stderr, "char device redirected to %s\n", ptsname(master_fd));

    return qemu_chr_open_fd(master_fd, master_fd);

}


static int xen_pt_long_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry,

                                uint32_t *value, uint32_t valid_mask)

{

    XenPTRegInfo *reg = cfg_entry->reg;

    uint32_t valid_emu_mask = 0;

    /* emulate long register */

    valid_emu_mask = reg->emu_mask & valid_mask;

    *value = XEN_PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask);

    return 0;

}


static void tgen_setcond(TCGContext *s, TCGType type, TCGCond cond,

                         TCGReg dest, TCGReg c1, TCGArg c2, int c2const)

{

    int cc;

    switch (cond) {

    case TCG_COND_GTU:

    case TCG_COND_GT:

    do_greater:

        /* The result of a compare has CC=2 for GT and CC=3 unused.

           ADD LOGICAL WITH CARRY considers (CC & 2) the carry bit.  */

        tgen_cmp(s, type, cond, c1, c2, c2const, true);

        tcg_out_movi(s, type, dest, 0);

        tcg_out_insn(s, RRE, ALCGR, dest, dest);

        return;

    case TCG_COND_GEU:

    do_geu:

        /* We need "real" carry semantics, so use SUBTRACT LOGICAL

           instead of COMPARE LOGICAL.  This needs an extra move.  */

        tcg_out_mov(s, type, TCG_TMP0, c1);

        if (c2const) {

            tcg_out_movi(s, TCG_TYPE_I64, dest, 0);

            if (type == TCG_TYPE_I32) {

                tcg_out_insn(s, RIL, SLFI, TCG_TMP0, c2);

            } else {

                tcg_out_insn(s, RIL, SLGFI, TCG_TMP0, c2);

            }

        } else {

            if (type == TCG_TYPE_I32) {

                tcg_out_insn(s, RR, SLR, TCG_TMP0, c2);

            } else {

                tcg_out_insn(s, RRE, SLGR, TCG_TMP0, c2);

            }

            tcg_out_movi(s, TCG_TYPE_I64, dest, 0);

        }

        tcg_out_insn(s, RRE, ALCGR, dest, dest);

        return;

    case TCG_COND_LEU:

    case TCG_COND_LTU:

    case TCG_COND_LT:

        /* Swap operands so that we can use GEU/GTU/GT.  */

        if (c2const) {

            tcg_out_movi(s, type, TCG_TMP0, c2);

            c2 = c1;

            c2const = 0;

            c1 = TCG_TMP0;

        } else {

            TCGReg t = c1;

            c1 = c2;

            c2 = t;

        }

        if (cond == TCG_COND_LEU) {

            goto do_geu;

        }

        cond = tcg_swap_cond(cond);

        goto do_greater;

    case TCG_COND_NE:

        /* X != 0 is X > 0.  */

        if (c2const && c2 == 0) {

            cond = TCG_COND_GTU;

            goto do_greater;

        }

        break;

    case TCG_COND_EQ:

        /* X == 0 is X <= 0 is 0 >= X.  */

        if (c2const && c2 == 0) {

            tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 0);

            c2 = c1;

            c2const = 0;

            c1 = TCG_TMP0;

            goto do_geu;

        }

        break;

    default:

        break;

    }

    cc = tgen_cmp(s, type, cond, c1, c2, c2const, false);

    if (facilities & FACILITY_LOAD_ON_COND) {

        /* Emit: d = 0, t = 1, d = (cc ? t : d).  */

        tcg_out_movi(s, TCG_TYPE_I64, dest, 0);

        tcg_out_movi(s, TCG_TYPE_I64, TCG_TMP0, 1);

        tcg_out_insn(s, RRF, LOCGR, dest, TCG_TMP0, cc);

    } else {

        /* Emit: d = 1; if (cc) goto over; d = 0; over:  */

        tcg_out_movi(s, type, dest, 1);

        tcg_out_insn(s, RI, BRC, cc, (4 + 4) >> 1);

        tcg_out_movi(s, type, dest, 0);

    }

}


static CharDriverState *qemu_chr_open_pty(const char *id,

                                          ChardevReturn *ret)

{

    CharDriverState *chr;

    PtyCharDriver *s;

    int master_fd, slave_fd;

    char pty_name[PATH_MAX];

    master_fd = qemu_openpty_raw(&slave_fd, pty_name);

    if (master_fd < 0) {

        return NULL;

    }

    close(slave_fd);

    chr = g_malloc0(sizeof(CharDriverState));

    chr->filename = g_strdup_printf("pty:%s", pty_name);

    ret->pty = g_strdup(pty_name);

    ret->has_pty = true;

    fprintf(stderr, "char device redirected to %s (label %s)\n",

            pty_name, id);

    s = g_malloc0(sizeof(PtyCharDriver));

    chr->opaque = s;

    chr->chr_write = pty_chr_write;

    chr->chr_update_read_handler = pty_chr_update_read_handler;

    chr->chr_close = pty_chr_close;

    chr->chr_add_watch = pty_chr_add_watch;

    chr->explicit_be_open = true;

    s->fd = io_channel_from_fd(master_fd);

    s->timer_tag = 0;

    return chr;

}


static target_ulong h_set_dabr(PowerPCCPU *cpu, sPAPRMachineState *spapr,

                               target_ulong opcode, target_ulong *args)

{

    /* FIXME: actually implement this */

    return H_HARDWARE;

}