static void tcx_screen_dump(void *opaque, const char *filename, bool cswitch,

                            Error **errp)

{

    TCXState *s = opaque;

    FILE *f;

    uint8_t *d, *d1, v;

    int ret, y, x;

    f = fopen(filename, "wb");

    if (!f) {

        error_setg(errp, "failed to open file '%s': %s", filename,

                   strerror(errno));

        return;

    }

    ret = fprintf(f, "P6\n%d %d\n%d\n", s->width, s->height, 255);

    if (ret < 0) {

        goto write_err;

    }

    d1 = s->vram;

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

        d = d1;

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

            v = *d;

            ret = fputc(s->r[v], f);

            if (ret == EOF) {

                goto write_err;

            }

            ret = fputc(s->g[v], f);

            if (ret == EOF) {

                goto write_err;

            }

            ret = fputc(s->b[v], f);

            if (ret == EOF) {

                goto write_err;

            }

            d++;

        }

        d1 += MAXX;

    }

out:

    fclose(f);

    return;

write_err:

    error_setg(errp, "failed to write to file '%s': %s", filename,

               strerror(errno));

    unlink(filename);

    goto out;

}


static void icp_pic_write(void *opaque, target_phys_addr_t offset,

                          uint64_t value, unsigned size)

{

    icp_pic_state *s = (icp_pic_state *)opaque;

    switch (offset >> 2) {

    case 2: /* IRQ_ENABLESET */

        s->irq_enabled |= value;

        break;

    case 3: /* IRQ_ENABLECLR */

        s->irq_enabled &= ~value;

        break;

    case 4: /* INT_SOFTSET */

        if (value & 1)

            icp_pic_set_irq(s, 0, 1);

        break;

    case 5: /* INT_SOFTCLR */

        if (value & 1)

            icp_pic_set_irq(s, 0, 0);

        break;

    case 10: /* FRQ_ENABLESET */

        s->fiq_enabled |= value;

        break;

    case 11: /* FRQ_ENABLECLR */

        s->fiq_enabled &= ~value;

        break;

    case 0: /* IRQ_STATUS */

    case 1: /* IRQ_RAWSTAT */

    case 8: /* FRQ_STATUS */

    case 9: /* FRQ_RAWSTAT */

    default:

        printf ("icp_pic_write: Bad register offset 0x%x\n", (int)offset);

        return;

    }

    icp_pic_update(s);

}


static void monitor_readline_cb(void *opaque, const char *input)

{

    pstrcpy(monitor_readline_buf, monitor_readline_buf_size, input);

    monitor_readline_started = 0;

}


static void fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *ctx, const H264Context *h,

                                    DXVA_PicParams_H264 *pp)

{

    const H264Picture *current_picture = h->cur_pic_ptr;

    const SPS *sps = h->ps.sps;

    const PPS *pps = h->ps.pps;

    int i, j;

    memset(pp, 0, sizeof(*pp));

    /* Configure current picture */

    fill_picture_entry(&pp->CurrPic,

                       ff_dxva2_get_surface_index(avctx, ctx, current_picture->f),

                       h->picture_structure == PICT_BOTTOM_FIELD);

    /* Configure the set of references */

    pp->UsedForReferenceFlags  = 0;

    pp->NonExistingFrameFlags  = 0;

    for (i = 0, j = 0; i < FF_ARRAY_ELEMS(pp->RefFrameList); i++) {

        const H264Picture *r;

        if (j < h->short_ref_count) {

            r = h->short_ref[j++];

        } else {

            r = NULL;

            while (!r && j < h->short_ref_count + 16)

                r = h->long_ref[j++ - h->short_ref_count];

        }

        if (r) {

            fill_picture_entry(&pp->RefFrameList[i],

                               ff_dxva2_get_surface_index(avctx, ctx, r->f),

                               r->long_ref != 0);

            if ((r->reference & PICT_TOP_FIELD) && r->field_poc[0] != INT_MAX)

                pp->FieldOrderCntList[i][0] = r->field_poc[0];

            if ((r->reference & PICT_BOTTOM_FIELD) && r->field_poc[1] != INT_MAX)

                pp->FieldOrderCntList[i][1] = r->field_poc[1];

            pp->FrameNumList[i] = r->long_ref ? r->pic_id : r->frame_num;

            if (r->reference & PICT_TOP_FIELD)

                pp->UsedForReferenceFlags |= 1 << (2*i + 0);

            if (r->reference & PICT_BOTTOM_FIELD)

                pp->UsedForReferenceFlags |= 1 << (2*i + 1);

        } else {

            pp->RefFrameList[i].bPicEntry = 0xff;

            pp->FieldOrderCntList[i][0]   = 0;

            pp->FieldOrderCntList[i][1]   = 0;

            pp->FrameNumList[i]           = 0;

        }

    }

    pp->wFrameWidthInMbsMinus1        = h->mb_width  - 1;

    pp->wFrameHeightInMbsMinus1       = h->mb_height - 1;

    pp->num_ref_frames                = sps->ref_frame_count;

    pp->wBitFields                    = ((h->picture_structure != PICT_FRAME) <<  0) |

                                        ((sps->mb_aff &&

                                        (h->picture_structure == PICT_FRAME)) <<  1) |

                                        (sps->residual_color_transform_flag   <<  2) |

                                        /* sp_for_switch_flag (not implemented by Libav) */

                                        (0                                    <<  3) |

                                        (sps->chroma_format_idc               <<  4) |

                                        ((h->nal_ref_idc != 0)                <<  6) |

                                        (pps->constrained_intra_pred          <<  7) |

                                        (pps->weighted_pred                   <<  8) |

                                        (pps->weighted_bipred_idc             <<  9) |

                                        /* MbsConsecutiveFlag */

                                        (1                                    << 11) |

                                        (sps->frame_mbs_only_flag             << 12) |

                                        (pps->transform_8x8_mode              << 13) |

                                        ((sps->level_idc >= 31)               << 14) |

                                        /* IntraPicFlag (Modified if we detect a non

                                         * intra slice in dxva2_h264_decode_slice) */

                                        (1                                    << 15);

    pp->bit_depth_luma_minus8         = sps->bit_depth_luma - 8;

    pp->bit_depth_chroma_minus8       = sps->bit_depth_chroma - 8;

    if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_SCALING_LIST_ZIGZAG)

        pp->Reserved16Bits            = 0;

    else if (DXVA_CONTEXT_WORKAROUND(avctx, ctx) & FF_DXVA2_WORKAROUND_INTEL_CLEARVIDEO)

        pp->Reserved16Bits            = 0x34c;

    else

        pp->Reserved16Bits            = 3; /* FIXME is there a way to detect the right mode ? */

    pp->StatusReportFeedbackNumber    = 1 + DXVA_CONTEXT_REPORT_ID(avctx, ctx)++;

    pp->CurrFieldOrderCnt[0] = 0;

    if ((h->picture_structure & PICT_TOP_FIELD) &&

        current_picture->field_poc[0] != INT_MAX)

        pp->CurrFieldOrderCnt[0] = current_picture->field_poc[0];

    pp->CurrFieldOrderCnt[1] = 0;

    if ((h->picture_structure & PICT_BOTTOM_FIELD) &&

        current_picture->field_poc[1] != INT_MAX)

        pp->CurrFieldOrderCnt[1] = current_picture->field_poc[1];

    pp->pic_init_qs_minus26           = pps->init_qs - 26;

    pp->chroma_qp_index_offset        = pps->chroma_qp_index_offset[0];

    pp->second_chroma_qp_index_offset = pps->chroma_qp_index_offset[1];

    pp->ContinuationFlag              = 1;

    pp->pic_init_qp_minus26           = pps->init_qp - 26;

    pp->num_ref_idx_l0_active_minus1  = pps->ref_count[0] - 1;

    pp->num_ref_idx_l1_active_minus1  = pps->ref_count[1] - 1;

    pp->Reserved8BitsA                = 0;

    pp->frame_num                     = h->frame_num;

    pp->log2_max_frame_num_minus4     = sps->log2_max_frame_num - 4;

    pp->pic_order_cnt_type            = sps->poc_type;

    if (sps->poc_type == 0)

        pp->log2_max_pic_order_cnt_lsb_minus4 = sps->log2_max_poc_lsb - 4;

    else if (sps->poc_type == 1)

        pp->delta_pic_order_always_zero_flag = sps->delta_pic_order_always_zero_flag;

    pp->direct_8x8_inference_flag     = sps->direct_8x8_inference_flag;

    pp->entropy_coding_mode_flag      = pps->cabac;

    pp->pic_order_present_flag        = pps->pic_order_present;

    pp->num_slice_groups_minus1       = pps->slice_group_count - 1;

    pp->slice_group_map_type          = pps->mb_slice_group_map_type;

    pp->deblocking_filter_control_present_flag = pps->deblocking_filter_parameters_present;

    pp->redundant_pic_cnt_present_flag= pps->redundant_pic_cnt_present;

    pp->Reserved8BitsB                = 0;

    pp->slice_group_change_rate_minus1= 0;  /* XXX not implemented by Libav */

    //pp->SliceGroupMap[810];               /* XXX not implemented by Libav */

}


static int reg_irqs(CPUS390XState *env, S390PCIBusDevice *pbdev, ZpciFib fib)

{

    int ret, len;

    ret = css_register_io_adapter(S390_PCIPT_ADAPTER,

                                  FIB_DATA_ISC(ldl_p(&fib.data)), true, false,

                                  &pbdev->routes.adapter.adapter_id);

    assert(ret == 0);

    pbdev->summary_ind = get_indicator(ldq_p(&fib.aisb), sizeof(uint64_t));

    len = BITS_TO_LONGS(FIB_DATA_NOI(ldl_p(&fib.data))) * sizeof(unsigned long);

    pbdev->indicator = get_indicator(ldq_p(&fib.aibv), len);

    map_indicator(&pbdev->routes.adapter, pbdev->summary_ind);

    map_indicator(&pbdev->routes.adapter, pbdev->indicator);

    pbdev->routes.adapter.summary_addr = ldq_p(&fib.aisb);

    pbdev->routes.adapter.summary_offset = FIB_DATA_AISBO(ldl_p(&fib.data));

    pbdev->routes.adapter.ind_addr = ldq_p(&fib.aibv);

    pbdev->routes.adapter.ind_offset = FIB_DATA_AIBVO(ldl_p(&fib.data));

    pbdev->isc = FIB_DATA_ISC(ldl_p(&fib.data));

    pbdev->noi = FIB_DATA_NOI(ldl_p(&fib.data));

    pbdev->sum = FIB_DATA_SUM(ldl_p(&fib.data));

    DPRINTF("reg_irqs adapter id %d\n", pbdev->routes.adapter.adapter_id);

    return 0;

}


static void finish_write_pci_config(sPAPREnvironment *spapr, uint64_t buid,

                                    uint32_t addr, uint32_t size,

                                    uint32_t val, target_ulong rets)

{

    PCIDevice *pci_dev;

    if ((size != 1) && (size != 2) && (size != 4)) {

        /* access must be 1, 2 or 4 bytes */

        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);

        return;

    }

    pci_dev = find_dev(spapr, buid, addr);

    addr = rtas_pci_cfgaddr(addr);

    if (!pci_dev || (addr % size) || (addr >= pci_config_size(pci_dev))) {

        /* Access must be to a valid device, within bounds and

         * naturally aligned */

        rtas_st(rets, 0, RTAS_OUT_HW_ERROR);

        return;

    }

    pci_host_config_write_common(pci_dev, addr, pci_config_size(pci_dev),

                                 val, size);

    rtas_st(rets, 0, RTAS_OUT_SUCCESS);

}


static int mpc8544_load_device_tree(CPUPPCState *env,

                                    target_phys_addr_t addr,

                                    target_phys_addr_t ramsize,

                                    target_phys_addr_t initrd_base,

                                    target_phys_addr_t initrd_size,

                                    const char *kernel_cmdline)

{

    int ret = -1;

    uint32_t mem_reg_property[] = {0, cpu_to_be32(ramsize)};

    int fdt_size;

    void *fdt;

    uint8_t hypercall[16];

    uint32_t clock_freq = 400000000;

    uint32_t tb_freq = 400000000;

    int i;

    char compatible[] = "MPC8544DS\0MPC85xxDS";

    char model[] = "MPC8544DS";

    char soc[128];

    char ser0[128];

    char ser1[128];

    char mpic[128];

    uint32_t mpic_ph;

    char gutil[128];

    char pci[128];

    uint32_t pci_map[7 * 8];

    uint32_t pci_ranges[12] = { 0x2000000, 0x0, 0xc0000000, 0xc0000000, 0x0,

                                0x20000000, 0x1000000, 0x0, 0x0, 0xe1000000,

                                0x0, 0x10000 };

    QemuOpts *machine_opts;

    const char *dumpdtb = NULL;

    fdt = create_device_tree(&fdt_size);

    if (fdt == NULL) {

        goto out;

    }

    /* Manipulate device tree in memory. */

    qemu_devtree_setprop_string(fdt, "/", "model", model);

    qemu_devtree_setprop(fdt, "/", "compatible", compatible,

                         sizeof(compatible));

    qemu_devtree_setprop_cell(fdt, "/", "#address-cells", 1);

    qemu_devtree_setprop_cell(fdt, "/", "#size-cells", 1);

    qemu_devtree_add_subnode(fdt, "/memory");

    qemu_devtree_setprop_string(fdt, "/memory", "device_type", "memory");

    qemu_devtree_setprop(fdt, "/memory", "reg", mem_reg_property,

                         sizeof(mem_reg_property));

    qemu_devtree_add_subnode(fdt, "/chosen");

    if (initrd_size) {

        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start",

                                        initrd_base);

        if (ret < 0) {

            fprintf(stderr, "couldn't set /chosen/linux,initrd-start\n");

        }

        ret = qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end",

                                        (initrd_base + initrd_size));

        if (ret < 0) {

            fprintf(stderr, "couldn't set /chosen/linux,initrd-end\n");

        }

    }

    ret = qemu_devtree_setprop_string(fdt, "/chosen", "bootargs",

                                      kernel_cmdline);

    if (ret < 0)

        fprintf(stderr, "couldn't set /chosen/bootargs\n");

    if (kvm_enabled()) {

        /* Read out host's frequencies */

        clock_freq = kvmppc_get_clockfreq();

        tb_freq = kvmppc_get_tbfreq();

        /* indicate KVM hypercall interface */

        qemu_devtree_add_subnode(fdt, "/hypervisor");

        qemu_devtree_setprop_string(fdt, "/hypervisor", "compatible",

                                    "linux,kvm");

        kvmppc_get_hypercall(env, hypercall, sizeof(hypercall));

        qemu_devtree_setprop(fdt, "/hypervisor", "hcall-instructions",

                             hypercall, sizeof(hypercall));

    }

    /* Create CPU nodes */

    qemu_devtree_add_subnode(fdt, "/cpus");

    qemu_devtree_setprop_cell(fdt, "/cpus", "#address-cells", 1);

    qemu_devtree_setprop_cell(fdt, "/cpus", "#size-cells", 0);

    /* We need to generate the cpu nodes in reverse order, so Linux can pick

       the first node as boot node and be happy */

    for (i = smp_cpus - 1; i >= 0; i--) {

        char cpu_name[128];

        uint64_t cpu_release_addr = MPC8544_SPIN_BASE + (i * 0x20);

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

            if (env->cpu_index == i) {

                break;

            }

        }

        if (!env) {

            continue;

        }

        snprintf(cpu_name, sizeof(cpu_name), "/cpus/PowerPC,8544@%x", env->cpu_index);

        qemu_devtree_add_subnode(fdt, cpu_name);

        qemu_devtree_setprop_cell(fdt, cpu_name, "clock-frequency", clock_freq);

        qemu_devtree_setprop_cell(fdt, cpu_name, "timebase-frequency", tb_freq);

        qemu_devtree_setprop_string(fdt, cpu_name, "device_type", "cpu");

        qemu_devtree_setprop_cell(fdt, cpu_name, "reg", env->cpu_index);

        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-line-size",

                                  env->dcache_line_size);

        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-line-size",

                                  env->icache_line_size);

        qemu_devtree_setprop_cell(fdt, cpu_name, "d-cache-size", 0x8000);

        qemu_devtree_setprop_cell(fdt, cpu_name, "i-cache-size", 0x8000);

        qemu_devtree_setprop_cell(fdt, cpu_name, "bus-frequency", 0);

        if (env->cpu_index) {

            qemu_devtree_setprop_string(fdt, cpu_name, "status", "disabled");

            qemu_devtree_setprop_string(fdt, cpu_name, "enable-method", "spin-table");

            qemu_devtree_setprop_u64(fdt, cpu_name, "cpu-release-addr",

                                     cpu_release_addr);

        } else {

            qemu_devtree_setprop_string(fdt, cpu_name, "status", "okay");

        }

    }

    qemu_devtree_add_subnode(fdt, "/aliases");

    /* XXX These should go into their respective devices' code */

    snprintf(soc, sizeof(soc), "/soc8544@%x", MPC8544_CCSRBAR_BASE);

    qemu_devtree_add_subnode(fdt, soc);

    qemu_devtree_setprop_string(fdt, soc, "device_type", "soc");

    qemu_devtree_setprop_string(fdt, soc, "compatible", "simple-bus");

    qemu_devtree_setprop_cell(fdt, soc, "#address-cells", 1);

    qemu_devtree_setprop_cell(fdt, soc, "#size-cells", 1);

    qemu_devtree_setprop_cells(fdt, soc, "ranges", 0x0, MPC8544_CCSRBAR_BASE,

                               MPC8544_CCSRBAR_SIZE);

    qemu_devtree_setprop_cells(fdt, soc, "reg", MPC8544_CCSRBAR_BASE,

                               MPC8544_CCSRBAR_REGSIZE);

    /* XXX should contain a reasonable value */

    qemu_devtree_setprop_cell(fdt, soc, "bus-frequency", 0);

    snprintf(mpic, sizeof(mpic), "%s/pic@%x", soc,

             MPC8544_MPIC_REGS_BASE - MPC8544_CCSRBAR_BASE);

    qemu_devtree_add_subnode(fdt, mpic);

    qemu_devtree_setprop_string(fdt, mpic, "device_type", "open-pic");

    qemu_devtree_setprop_string(fdt, mpic, "compatible", "chrp,open-pic");

    qemu_devtree_setprop_cells(fdt, mpic, "reg", MPC8544_MPIC_REGS_BASE -

                               MPC8544_CCSRBAR_BASE, 0x40000);

    qemu_devtree_setprop_cell(fdt, mpic, "#address-cells", 0);

    qemu_devtree_setprop_cell(fdt, mpic, "#interrupt-cells", 2);

    mpic_ph = qemu_devtree_alloc_phandle(fdt);

    qemu_devtree_setprop_cell(fdt, mpic, "phandle", mpic_ph);

    qemu_devtree_setprop_cell(fdt, mpic, "linux,phandle", mpic_ph);

    qemu_devtree_setprop(fdt, mpic, "interrupt-controller", NULL, 0);

    /*

     * We have to generate ser1 first, because Linux takes the first

     * device it finds in the dt as serial output device. And we generate

     * devices in reverse order to the dt.

     */

    snprintf(ser1, sizeof(ser1), "%s/serial@%x", soc,

             MPC8544_SERIAL1_REGS_BASE - MPC8544_CCSRBAR_BASE);

    qemu_devtree_add_subnode(fdt, ser1);

    qemu_devtree_setprop_string(fdt, ser1, "device_type", "serial");

    qemu_devtree_setprop_string(fdt, ser1, "compatible", "ns16550");

    qemu_devtree_setprop_cells(fdt, ser1, "reg", MPC8544_SERIAL1_REGS_BASE -

                               MPC8544_CCSRBAR_BASE, 0x100);

    qemu_devtree_setprop_cell(fdt, ser1, "cell-index", 1);

    qemu_devtree_setprop_cell(fdt, ser1, "clock-frequency", 0);

    qemu_devtree_setprop_cells(fdt, ser1, "interrupts", 42, 2);

    qemu_devtree_setprop_phandle(fdt, ser1, "interrupt-parent", mpic);

    qemu_devtree_setprop_string(fdt, "/aliases", "serial1", ser1);

    snprintf(ser0, sizeof(ser0), "%s/serial@%x", soc,

             MPC8544_SERIAL0_REGS_BASE - MPC8544_CCSRBAR_BASE);

    qemu_devtree_add_subnode(fdt, ser0);

    qemu_devtree_setprop_string(fdt, ser0, "device_type", "serial");

    qemu_devtree_setprop_string(fdt, ser0, "compatible", "ns16550");

    qemu_devtree_setprop_cells(fdt, ser0, "reg", MPC8544_SERIAL0_REGS_BASE -

                               MPC8544_CCSRBAR_BASE, 0x100);

    qemu_devtree_setprop_cell(fdt, ser0, "cell-index", 0);

    qemu_devtree_setprop_cell(fdt, ser0, "clock-frequency", 0);

    qemu_devtree_setprop_cells(fdt, ser0, "interrupts", 42, 2);

    qemu_devtree_setprop_phandle(fdt, ser0, "interrupt-parent", mpic);

    qemu_devtree_setprop_string(fdt, "/aliases", "serial0", ser0);

    qemu_devtree_setprop_string(fdt, "/chosen", "linux,stdout-path", ser0);

    snprintf(gutil, sizeof(gutil), "%s/global-utilities@%x", soc,

             MPC8544_UTIL_BASE - MPC8544_CCSRBAR_BASE);

    qemu_devtree_add_subnode(fdt, gutil);

    qemu_devtree_setprop_string(fdt, gutil, "compatible", "fsl,mpc8544-guts");

    qemu_devtree_setprop_cells(fdt, gutil, "reg", MPC8544_UTIL_BASE -

                               MPC8544_CCSRBAR_BASE, 0x1000);

    qemu_devtree_setprop(fdt, gutil, "fsl,has-rstcr", NULL, 0);

    snprintf(pci, sizeof(pci), "/pci@%x", MPC8544_PCI_REGS_BASE);

    qemu_devtree_add_subnode(fdt, pci);

    qemu_devtree_setprop_cell(fdt, pci, "cell-index", 0);

    qemu_devtree_setprop_string(fdt, pci, "compatible", "fsl,mpc8540-pci");

    qemu_devtree_setprop_string(fdt, pci, "device_type", "pci");

    qemu_devtree_setprop_cells(fdt, pci, "interrupt-map-mask", 0xf800, 0x0,

                               0x0, 0x7);

    pci_map_create(fdt, pci_map, qemu_devtree_get_phandle(fdt, mpic));

    qemu_devtree_setprop(fdt, pci, "interrupt-map", pci_map, sizeof(pci_map));

    qemu_devtree_setprop_phandle(fdt, pci, "interrupt-parent", mpic);

    qemu_devtree_setprop_cells(fdt, pci, "interrupts", 24, 2);

    qemu_devtree_setprop_cells(fdt, pci, "bus-range", 0, 255);

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

        pci_ranges[i] = cpu_to_be32(pci_ranges[i]);

    }

    qemu_devtree_setprop(fdt, pci, "ranges", pci_ranges, sizeof(pci_ranges));

    qemu_devtree_setprop_cells(fdt, pci, "reg", MPC8544_PCI_REGS_BASE,

                               0x1000);

    qemu_devtree_setprop_cell(fdt, pci, "clock-frequency", 66666666);

    qemu_devtree_setprop_cell(fdt, pci, "#interrupt-cells", 1);

    qemu_devtree_setprop_cell(fdt, pci, "#size-cells", 2);

    qemu_devtree_setprop_cell(fdt, pci, "#address-cells", 3);

    qemu_devtree_setprop_string(fdt, "/aliases", "pci0", pci);

    machine_opts = qemu_opts_find(qemu_find_opts("machine"), 0);

    if (machine_opts) {

        dumpdtb = qemu_opt_get(machine_opts, "dumpdtb");

    }

    if (dumpdtb) {

        /* Dump the dtb to a file and quit */

        FILE *f = fopen(dumpdtb, "wb");

        size_t len;

        len = fwrite(fdt, fdt_size, 1, f);

        fclose(f);

        if (len != fdt_size) {

            exit(1);

        }

        exit(0);

    }

    ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);

    if (ret < 0) {

        goto out;

    }

    g_free(fdt);

    ret = fdt_size;

out:

    return ret;

}


static void format_string(StringOutputVisitor *sov, Range *r, bool next,

                          bool human)

{

    if (r->end - r->begin > 1) {

        if (human) {

            g_string_append_printf(sov->string, "0x%" PRIx64 "-0x%" PRIx64,

                                   r->begin, r->end - 1);

        } else {

            g_string_append_printf(sov->string, "%" PRId64 "-%" PRId64,

                                   r->begin, r->end - 1);

        }

    } else {

        if (human) {

            g_string_append_printf(sov->string, "0x%" PRIx64, r->begin);

        } else {

            g_string_append_printf(sov->string, "%" PRId64, r->begin);

        }

    }

    if (next) {

        g_string_append(sov->string, ",");

    }

}


static void v9fs_setattr(void *opaque)

{

    int err = 0;

    int32_t fid;

    V9fsFidState *fidp;

    size_t offset = 7;

    V9fsIattr v9iattr;

    V9fsPDU *pdu = opaque;

    V9fsState *s = pdu->s;

    pdu_unmarshal(pdu, offset, "dI", &fid, &v9iattr);

    fidp = get_fid(pdu, fid);

    if (fidp == NULL) {

        err = -EINVAL;

        goto out_nofid;

    }

    if (v9iattr.valid & P9_ATTR_MODE) {

        err = v9fs_co_chmod(pdu, &fidp->path, v9iattr.mode);

        if (err < 0) {

            goto out;

        }

    }

    if (v9iattr.valid & (P9_ATTR_ATIME | P9_ATTR_MTIME)) {

        struct timespec times[2];

        if (v9iattr.valid & P9_ATTR_ATIME) {

            if (v9iattr.valid & P9_ATTR_ATIME_SET) {

                times[0].tv_sec = v9iattr.atime_sec;

                times[0].tv_nsec = v9iattr.atime_nsec;

            } else {

                times[0].tv_nsec = UTIME_NOW;

            }

        } else {

            times[0].tv_nsec = UTIME_OMIT;

        }

        if (v9iattr.valid & P9_ATTR_MTIME) {

            if (v9iattr.valid & P9_ATTR_MTIME_SET) {

                times[1].tv_sec = v9iattr.mtime_sec;

                times[1].tv_nsec = v9iattr.mtime_nsec;

            } else {

                times[1].tv_nsec = UTIME_NOW;

            }

        } else {

            times[1].tv_nsec = UTIME_OMIT;

        }

        err = v9fs_co_utimensat(pdu, &fidp->path, times);

        if (err < 0) {

            goto out;

        }

    }

    /*

     * If the only valid entry in iattr is ctime we can call

     * chown(-1,-1) to update the ctime of the file

     */

    if ((v9iattr.valid & (P9_ATTR_UID | P9_ATTR_GID)) ||

        ((v9iattr.valid & P9_ATTR_CTIME)

         && !((v9iattr.valid & P9_ATTR_MASK) & ~P9_ATTR_CTIME))) {

        if (!(v9iattr.valid & P9_ATTR_UID)) {

            v9iattr.uid = -1;

        }

        if (!(v9iattr.valid & P9_ATTR_GID)) {

            v9iattr.gid = -1;

        }

        err = v9fs_co_chown(pdu, &fidp->path, v9iattr.uid,

                            v9iattr.gid);

        if (err < 0) {

            goto out;

        }

    }

    if (v9iattr.valid & (P9_ATTR_SIZE)) {

        err = v9fs_co_truncate(pdu, &fidp->path, v9iattr.size);

        if (err < 0) {

            goto out;

        }

    }

    err = offset;

out:

    put_fid(pdu, fidp);

out_nofid:

    complete_pdu(s, pdu, err);

}


static inline void iwmmxt_load_reg(TCGv var, int reg)

{

    tcg_gen_ld_i64(var, cpu_env, offsetof(CPUState, iwmmxt.regs[reg]));

}


static void process_command(GAState *s, QDict *req)

{

    QObject *rsp = NULL;

    int ret;

    g_assert(req);

    g_debug("processing command");

    rsp = qmp_dispatch(QOBJECT(req));

    if (rsp) {

        ret = send_response(s, rsp);

        if (ret) {

            g_warning("error sending response: %s", strerror(ret));

        }

        qobject_decref(rsp);

    } else {

        g_warning("error getting response");

    }

}


static void qemu_file_set_error(QEMUFile *f, int ret)

{

    if (f->last_error == 0) {

        f->last_error = ret;

    }

}


int split_commandline(OptionParseContext *octx, int argc, char *argv[],

                      const OptionDef *options,

                      const OptionGroupDef *groups)

{

    int optindex = 1;

    /* perform system-dependent conversions for arguments list */

    prepare_app_arguments(&argc, &argv);

    init_parse_context(octx, groups);

    av_log(NULL, AV_LOG_DEBUG, "Splitting the commandline.\n");

    while (optindex < argc) {

        const char *opt = argv[optindex++], *arg;

        const OptionDef *po;

        int ret;

        av_log(NULL, AV_LOG_DEBUG, "Reading option '%s' ...", opt);

        /* unnamed group separators, e.g. output filename */

        if (opt[0] != '-' || !opt[1]) {

            finish_group(octx, 0, opt);

            av_log(NULL, AV_LOG_DEBUG, " matched as %s.\n", groups[0].name);

            continue;

        }

        opt++;

#define GET_ARG(arg)                                                           \

do {                                                                           \

    arg = argv[optindex++];                                                    \

    if (!arg) {                                                                \

        av_log(NULL, AV_LOG_ERROR, "Missing argument for option '%s'.\n", opt);\

        return AVERROR(EINVAL);                                                \

    }                                                                          \

} while (0)

        /* named group separators, e.g. -i */

        if ((ret = match_group_separator(groups, opt)) >= 0) {

            GET_ARG(arg);

            finish_group(octx, ret, arg);

            av_log(NULL, AV_LOG_DEBUG, " matched as %s with argument '%s'.\n",

                   groups[ret].name, arg);

            continue;

        }

        /* normal options */

        po = find_option(options, opt);

        if (po->name) {

            if (po->flags & OPT_EXIT) {

                /* optional argument, e.g. -h */

                arg = argv[optindex++];

            } else if (po->flags & HAS_ARG) {

                GET_ARG(arg);

            } else {

                arg = "1";

            }

            add_opt(octx, po, opt, arg);

            av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "

                   "argument '%s'.\n", po->name, po->help, arg);

            continue;

        }

        /* AVOptions */

        if (argv[optindex]) {

            ret = opt_default(NULL, opt, argv[optindex]);

            if (ret >= 0) {

                av_log(NULL, AV_LOG_DEBUG, " matched as AVOption '%s' with "

                       "argument '%s'.\n", opt, argv[optindex]);

                optindex++;

                continue;

            } else if (ret != AVERROR_OPTION_NOT_FOUND) {

                av_log(NULL, AV_LOG_ERROR, "Error parsing option '%s' "

                       "with argument '%s'.\n", opt, argv[optindex]);

                return ret;

            }

        }

        /* boolean -nofoo options */

        if (opt[0] == 'n' && opt[1] == 'o' &&

            (po = find_option(options, opt + 2)) &&

            po->name && po->flags & OPT_BOOL) {

            add_opt(octx, po, opt, "0");

            av_log(NULL, AV_LOG_DEBUG, " matched as option '%s' (%s) with "

                   "argument 0.\n", po->name, po->help);

            continue;

        }

        av_log(NULL, AV_LOG_ERROR, "Unrecognized option '%s'.\n", opt);

        return AVERROR_OPTION_NOT_FOUND;

    }

    if (octx->cur_group.nb_opts || codec_opts || format_opts)

        av_log(NULL, AV_LOG_WARNING, "Trailing options were found on the "

               "commandline.\n");

    av_log(NULL, AV_LOG_DEBUG, "Finished splitting the commandline.\n");

    return 0;

}


static target_ulong h_get_term_char(CPUState *env, sPAPREnvironment *spapr,

                                    target_ulong opcode, target_ulong *args)

{

    target_ulong reg = args[0];

    target_ulong *len = args + 0;

    target_ulong *char0_7 = args + 1;

    target_ulong *char8_15 = args + 2;

    VIOsPAPRDevice *sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);

    uint8_t buf[16];

    if (!sdev) {

        return H_PARAMETER;

    }

    *len = vty_getchars(sdev, buf, sizeof(buf));

    if (*len < 16) {

        memset(buf + *len, 0, 16 - *len);

    }

    *char0_7 = be64_to_cpu(*((uint64_t *)buf));

    *char8_15 = be64_to_cpu(*((uint64_t *)buf + 1));

    return H_SUCCESS;

}


static void qdev_print_devinfo(ObjectClass *klass, void *opaque)

{

    DeviceClass *dc;

    bool *show_no_user = opaque;

    dc = (DeviceClass *)object_class_dynamic_cast(klass, TYPE_DEVICE);

    if (!dc || (show_no_user && !*show_no_user && dc->no_user)) {

        return;

    }

    error_printf("name \"%s\"", object_class_get_name(klass));

    if (dc->bus_info) {

        error_printf(", bus %s", dc->bus_info->name);

    }

    if (dc->alias) {

        error_printf(", alias \"%s\"", dc->alias);

    }

    if (dc->desc) {

        error_printf(", desc \"%s\"", dc->desc);

    }

    if (dc->no_user) {

        error_printf(", no-user");

    }

    error_printf("\n");

}


static void keyword_literal(void)

{

    QObject *obj;

    QBool *qbool;

    QObject *null;

    QString *str;

    obj = qobject_from_json("true");

    g_assert(obj != NULL);

    g_assert(qobject_type(obj) == QTYPE_QBOOL);

    qbool = qobject_to_qbool(obj);

    g_assert(qbool_get_bool(qbool) == true);

    str = qobject_to_json(obj);

    g_assert(strcmp(qstring_get_str(str), "true") == 0);

    QDECREF(str);

    QDECREF(qbool);

    obj = qobject_from_json("false");

    g_assert(obj != NULL);

    g_assert(qobject_type(obj) == QTYPE_QBOOL);

    qbool = qobject_to_qbool(obj);

    g_assert(qbool_get_bool(qbool) == false);

    str = qobject_to_json(obj);

    g_assert(strcmp(qstring_get_str(str), "false") == 0);

    QDECREF(str);

    QDECREF(qbool);

    obj = qobject_from_jsonf("%i", false);

    g_assert(obj != NULL);

    g_assert(qobject_type(obj) == QTYPE_QBOOL);

    qbool = qobject_to_qbool(obj);

    g_assert(qbool_get_bool(qbool) == false);

    QDECREF(qbool);

    /* Test that non-zero values other than 1 get collapsed to true */

    obj = qobject_from_jsonf("%i", 2);

    g_assert(obj != NULL);

    g_assert(qobject_type(obj) == QTYPE_QBOOL);

    qbool = qobject_to_qbool(obj);

    g_assert(qbool_get_bool(qbool) == true);

    QDECREF(qbool);

    obj = qobject_from_json("null");

    g_assert(obj != NULL);

    g_assert(qobject_type(obj) == QTYPE_QNULL);

    null = qnull();

    g_assert(null == obj);

    qobject_decref(obj);

    qobject_decref(null);

}


int audio_available(void)

{

#ifdef HAS_AUDIO

    return 1;

#else

    return 0;

#endif

}


int kvm_irqchip_remove_irq_notifier(KVMState *s, EventNotifier *n, int virq)

{

    return kvm_irqchip_remove_irqfd(s, event_notifier_get_fd(n), virq);

}


static void vapic_reset(DeviceState *dev)

{

    VAPICROMState *s = VAPIC(dev);

    if (s->state == VAPIC_ACTIVE) {

        s->state = VAPIC_STANDBY;

    }

    vapic_enable_tpr_reporting(false);

}


static int kvm_get_sregs(CPUState *env)

{

    struct kvm_sregs sregs;

    uint32_t hflags;

    int bit, i, ret;

    ret = kvm_vcpu_ioctl(env, KVM_GET_SREGS, &sregs);

    if (ret < 0)

        return ret;

    /* There can only be one pending IRQ set in the bitmap at a time, so try

       to find it and save its number instead (-1 for none). */

    env->interrupt_injected = -1;

    for (i = 0; i < ARRAY_SIZE(sregs.interrupt_bitmap); i++) {

        if (sregs.interrupt_bitmap[i]) {

            bit = ctz64(sregs.interrupt_bitmap[i]);

            env->interrupt_injected = i * 64 + bit;

            break;

        }

    }

    get_seg(&env->segs[R_CS], &sregs.cs);

    get_seg(&env->segs[R_DS], &sregs.ds);

    get_seg(&env->segs[R_ES], &sregs.es);

    get_seg(&env->segs[R_FS], &sregs.fs);

    get_seg(&env->segs[R_GS], &sregs.gs);

    get_seg(&env->segs[R_SS], &sregs.ss);

    get_seg(&env->tr, &sregs.tr);

    get_seg(&env->ldt, &sregs.ldt);

    env->idt.limit = sregs.idt.limit;

    env->idt.base = sregs.idt.base;

    env->gdt.limit = sregs.gdt.limit;

    env->gdt.base = sregs.gdt.base;

    env->cr[0] = sregs.cr0;

    env->cr[2] = sregs.cr2;

    env->cr[3] = sregs.cr3;

    env->cr[4] = sregs.cr4;

    cpu_set_apic_base(env->apic_state, sregs.apic_base);

    env->efer = sregs.efer;

    //cpu_set_apic_tpr(env->apic_state, sregs.cr8);

#define HFLAG_COPY_MASK ~( \

			HF_CPL_MASK | HF_PE_MASK | HF_MP_MASK | HF_EM_MASK | \

			HF_TS_MASK | HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK | \

			HF_OSFXSR_MASK | HF_LMA_MASK | HF_CS32_MASK | \

			HF_SS32_MASK | HF_CS64_MASK | HF_ADDSEG_MASK)

    hflags = (env->segs[R_CS].flags >> DESC_DPL_SHIFT) & HF_CPL_MASK;

    hflags |= (env->cr[0] & CR0_PE_MASK) << (HF_PE_SHIFT - CR0_PE_SHIFT);

    hflags |= (env->cr[0] << (HF_MP_SHIFT - CR0_MP_SHIFT)) &

	    (HF_MP_MASK | HF_EM_MASK | HF_TS_MASK);

    hflags |= (env->eflags & (HF_TF_MASK | HF_VM_MASK | HF_IOPL_MASK));

    hflags |= (env->cr[4] & CR4_OSFXSR_MASK) <<

	    (HF_OSFXSR_SHIFT - CR4_OSFXSR_SHIFT);

    if (env->efer & MSR_EFER_LMA) {

        hflags |= HF_LMA_MASK;

    }

    if ((hflags & HF_LMA_MASK) && (env->segs[R_CS].flags & DESC_L_MASK)) {

        hflags |= HF_CS32_MASK | HF_SS32_MASK | HF_CS64_MASK;

    } else {

        hflags |= (env->segs[R_CS].flags & DESC_B_MASK) >>

		(DESC_B_SHIFT - HF_CS32_SHIFT);

        hflags |= (env->segs[R_SS].flags & DESC_B_MASK) >>

		(DESC_B_SHIFT - HF_SS32_SHIFT);

        if (!(env->cr[0] & CR0_PE_MASK) ||

                   (env->eflags & VM_MASK) ||

                   !(hflags & HF_CS32_MASK)) {

                hflags |= HF_ADDSEG_MASK;

            } else {

                hflags |= ((env->segs[R_DS].base |

                                env->segs[R_ES].base |

                                env->segs[R_SS].base) != 0) <<

                    HF_ADDSEG_SHIFT;

            }

    }

    env->hflags = (env->hflags & HFLAG_COPY_MASK) | hflags;

    return 0;

}


static void tm_get(QEMUFile *f, struct tm *tm) {

    tm->tm_sec = qemu_get_be16(f);

    tm->tm_min = qemu_get_be16(f);

    tm->tm_hour = qemu_get_be16(f);

    tm->tm_mday = qemu_get_be16(f);

    tm->tm_min = qemu_get_be16(f);

    tm->tm_year = qemu_get_be16(f);

}


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

                   NetClientState *peer)

{

    return net_vhost_user_init(peer, "vhost_user", 0, 0, 0);

}


static void net_socket_send(void *opaque)

{

    NetSocketState *s = opaque;

    int size, err;

    unsigned l;

    uint8_t buf1[NET_BUFSIZE];

    const uint8_t *buf;

    size = qemu_recv(s->fd, buf1, sizeof(buf1), 0);

    if (size < 0) {

        err = socket_error();

        if (err != EWOULDBLOCK)

            goto eoc;

    } else if (size == 0) {

        /* end of connection */

    eoc:

        net_socket_read_poll(s, false);

        net_socket_write_poll(s, false);

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

            qemu_set_fd_handler(s->listen_fd, net_socket_accept, NULL, s);

        }

        closesocket(s->fd);

        s->fd = -1;

        s->state = 0;

        s->index = 0;

        s->packet_len = 0;

        s->nc.link_down = true;

        memset(s->buf, 0, sizeof(s->buf));

        memset(s->nc.info_str, 0, sizeof(s->nc.info_str));

        return;

    }

    buf = buf1;

    while (size > 0) {

        /* reassemble a packet from the network */

        switch(s->state) {

        case 0:

            l = 4 - s->index;

            if (l > size)

                l = size;

            memcpy(s->buf + s->index, buf, l);

            buf += l;

            size -= l;

            s->index += l;

            if (s->index == 4) {

                /* got length */

                s->packet_len = ntohl(*(uint32_t *)s->buf);

                s->index = 0;

                s->state = 1;

            }

            break;

        case 1:

            l = s->packet_len - s->index;

            if (l > size)

                l = size;

            if (s->index + l <= sizeof(s->buf)) {

                memcpy(s->buf + s->index, buf, l);

            } else {

                fprintf(stderr, "serious error: oversized packet received,"

                    "connection terminated.\n");

                s->state = 0;

                goto eoc;

            }

            s->index += l;

            buf += l;

            size -= l;

            if (s->index >= s->packet_len) {

                qemu_send_packet(&s->nc, s->buf, s->packet_len);

                s->index = 0;

                s->state = 0;

            }

            break;

        }

    }

}


void spapr_tce_table_enable(sPAPRTCETable *tcet,

                            uint32_t page_shift, uint64_t bus_offset,

                            uint32_t nb_table)

{

    if (tcet->nb_table) {

        error_report("Warning: trying to enable already enabled TCE table");

        return;

    }

    tcet->bus_offset = bus_offset;

    tcet->page_shift = page_shift;

    tcet->nb_table = nb_table;

    tcet->table = spapr_tce_alloc_table(tcet->liobn,

                                        tcet->page_shift,

                                        tcet->bus_offset,

                                        tcet->nb_table,

                                        &tcet->fd,

                                        tcet->need_vfio);

    memory_region_set_size(&tcet->iommu,

                           (uint64_t)tcet->nb_table << tcet->page_shift);

    memory_region_add_subregion(&tcet->root, tcet->bus_offset, &tcet->iommu);

}


static void lcd_refresh(void *opaque)

{

    musicpal_lcd_state *s = opaque;

    int x, y;

    for (x = 0; x < 128; x++)

        for (y = 0; y < 64; y++)

            if (s->video_ram[x + (y/8)*128] & (1 << (y % 8)))

                set_lcd_pixel(s, x, y, MP_LCD_TEXTCOLOR);

            else

                set_lcd_pixel(s, x, y, 0);

    dpy_update(s->ds, 0, 0, 128*3, 64*3);

}


static inline int fs_channel(target_phys_addr_t addr)

{

	/* Every channel has a 0x2000 ctrl register map.  */

	return addr >> 13;

}


static int ffm_write_packet(AVFormatContext *s, int stream_index,

                            UINT8 *buf, int size, int force_pts)

{

    AVStream *st = s->streams[stream_index];

    FFMStream *fst = st->priv_data;

    INT64 pts;

    UINT8 header[FRAME_HEADER_SIZE];

    int duration;

    if (st->codec.codec_type == CODEC_TYPE_AUDIO) {

        duration = ((float)st->codec.frame_size / st->codec.sample_rate * 1000000.0);

    } else {

        duration = (1000000.0 * FRAME_RATE_BASE / (float)st->codec.frame_rate);

    }

    pts = fst->pts;

    /* packet size & key_frame */

    header[0] = stream_index;

    header[1] = 0;

    if (st->codec.coded_picture->key_frame)

        header[1] |= FLAG_KEY_FRAME;

    header[2] = (size >> 16) & 0xff;

    header[3] = (size >> 8) & 0xff;

    header[4] = size & 0xff;

    header[5] = (duration >> 16) & 0xff;

    header[6] = (duration >> 8) & 0xff;

    header[7] = duration & 0xff;

    ffm_write_data(s, header, FRAME_HEADER_SIZE, pts, 1);

    ffm_write_data(s, buf, size, pts, 0);

    fst->pts += duration;

    return 0;

}


static void v9fs_lock(void *opaque)
{
    int8_t status;
    V9fsFlock *flock;
    size_t offset = 7;
    struct stat stbuf;
    V9fsFidState *fidp;
    int32_t fid, err = 0;
    V9fsPDU *pdu = opaque;
    V9fsState *s = pdu->s;
    flock = g_malloc(sizeof(*flock));
    pdu_unmarshal(pdu, offset, "dbdqqds", &fid, &flock->type,
                  &flock->flags, &flock->start, &flock->length,
                  &flock->proc_id, &flock->client_id);
    status = P9_LOCK_ERROR;
    /* We support only block flag now (that too ignored currently) */
    if (flock->flags & ~P9_LOCK_FLAGS_BLOCK) {
        err = -EINVAL;
        goto out_nofid;
    }
    fidp = get_fid(pdu, fid);
    if (fidp == NULL) {
        err = -ENOENT;
        goto out_nofid;
    }
    err = v9fs_co_fstat(pdu, fidp->fs.fd, &stbuf);
    if (err < 0) {
        goto out;
    }
    status = P9_LOCK_SUCCESS;
out:
    put_fid(pdu, fidp);
out_nofid:
    err = offset;
    err += pdu_marshal(pdu, offset, "b", status);
    trace_v9fs_lock_return(pdu->tag, pdu->id, status);
    complete_pdu(s, pdu, err);
    v9fs_string_free(&flock->client_id);
    g_free(flock);
}


static int get_last_needed_nal(H264Context *h)

{

    int nals_needed = 0;

    int i;

    for (i = 0; i < h->pkt.nb_nals; i++) {

        H2645NAL *nal = &h->pkt.nals[i];

        GetBitContext gb;

        /* packets can sometimes contain multiple PPS/SPS,

         * e.g. two PAFF field pictures in one packet, or a demuxer

         * which splits NALs strangely if so, when frame threading we

         * can't start the next thread until we've read all of them */

        switch (nal->type) {

        case H264_NAL_SPS:

        case H264_NAL_PPS:

            nals_needed = i;

            break;

        case H264_NAL_DPA:

        case H264_NAL_IDR_SLICE:

        case H264_NAL_SLICE:

            init_get_bits(&gb, nal->data + 1, (nal->size - 1) * 8);

            if (!get_ue_golomb(&gb))

                nals_needed = i;

        }

    }

    return nals_needed;

}


int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx)

{

    int i;

    Picture *pic;

    s->mb_skipped = 0;

    assert(s->last_picture_ptr==NULL || s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3);

    /* mark&release old frames */

    if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && s->last_picture_ptr != s->next_picture_ptr && s->last_picture_ptr->f.data[0]) {

      if(s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3){

          free_frame_buffer(s, s->last_picture_ptr);

        /* release forgotten pictures */

        /* if(mpeg124/h263) */

        if(!s->encoding){

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

                if (s->picture[i].f.data[0] && &s->picture[i] != s->next_picture_ptr && s->picture[i].f.reference) {

                    av_log(avctx, AV_LOG_ERROR, "releasing zombie picture\n");

                    free_frame_buffer(s, &s->picture[i]);

                }

            }

        }

      }

    }

    if(!s->encoding){

        ff_release_unused_pictures(s, 1);

        if (s->current_picture_ptr && s->current_picture_ptr->f.data[0] == NULL)

            pic= s->current_picture_ptr; //we already have a unused image (maybe it was set before reading the header)

        else{

            i= ff_find_unused_picture(s, 0);

            pic= &s->picture[i];

        }

        pic->f.reference = 0;

        if (!s->dropable){

            if (s->codec_id == CODEC_ID_H264)

                pic->f.reference = s->picture_structure;

            else if (s->pict_type != AV_PICTURE_TYPE_B)

                pic->f.reference = 3;

        }

        pic->f.coded_picture_number = s->coded_picture_number++;

        if(ff_alloc_picture(s, pic, 0) < 0)

            return -1;

        s->current_picture_ptr= pic;

        //FIXME use only the vars from current_pic

        s->current_picture_ptr->f.top_field_first = s->top_field_first;

        if(s->codec_id == CODEC_ID_MPEG1VIDEO || s->codec_id == CODEC_ID_MPEG2VIDEO) {

            if(s->picture_structure != PICT_FRAME)

                s->current_picture_ptr->f.top_field_first = (s->picture_structure == PICT_TOP_FIELD) == s->first_field;

        }

        s->current_picture_ptr->f.interlaced_frame = !s->progressive_frame && !s->progressive_sequence;

        s->current_picture_ptr->field_picture = s->picture_structure != PICT_FRAME;

    }

    s->current_picture_ptr->f.pict_type = s->pict_type;

//    if(s->flags && CODEC_FLAG_QSCALE)

  //      s->current_picture_ptr->quality= s->new_picture_ptr->quality;

    s->current_picture_ptr->f.key_frame = s->pict_type == AV_PICTURE_TYPE_I;

    ff_copy_picture(&s->current_picture, s->current_picture_ptr);

    if (s->pict_type != AV_PICTURE_TYPE_B) {

        s->last_picture_ptr= s->next_picture_ptr;

        if(!s->dropable)

            s->next_picture_ptr= s->current_picture_ptr;

    }

/*    av_log(s->avctx, AV_LOG_DEBUG, "L%p N%p C%p L%p N%p C%p type:%d drop:%d\n", s->last_picture_ptr, s->next_picture_ptr,s->current_picture_ptr,

        s->last_picture_ptr    ? s->last_picture_ptr->f.data[0]    : NULL,

        s->next_picture_ptr    ? s->next_picture_ptr->f.data[0]    : NULL,

        s->current_picture_ptr ? s->current_picture_ptr->f.data[0] : NULL,

        s->pict_type, s->dropable);*/

    if(s->codec_id != CODEC_ID_H264){

        if ((s->last_picture_ptr == NULL || s->last_picture_ptr->f.data[0] == NULL) &&

           (s->pict_type!=AV_PICTURE_TYPE_I || s->picture_structure != PICT_FRAME)){

            if (s->pict_type != AV_PICTURE_TYPE_I)

                av_log(avctx, AV_LOG_ERROR, "warning: first frame is no keyframe\n");

            else if (s->picture_structure != PICT_FRAME)

                av_log(avctx, AV_LOG_INFO, "allocate dummy last picture for field based first keyframe\n");

            /* Allocate a dummy frame */

            i= ff_find_unused_picture(s, 0);

            s->last_picture_ptr= &s->picture[i];

            if(ff_alloc_picture(s, s->last_picture_ptr, 0) < 0)

                return -1;

            ff_thread_report_progress((AVFrame*)s->last_picture_ptr, INT_MAX, 0);

            ff_thread_report_progress((AVFrame*)s->last_picture_ptr, INT_MAX, 1);

        }

        if ((s->next_picture_ptr == NULL || s->next_picture_ptr->f.data[0] == NULL) && s->pict_type == AV_PICTURE_TYPE_B) {

            /* Allocate a dummy frame */

            i= ff_find_unused_picture(s, 0);

            s->next_picture_ptr= &s->picture[i];

            if(ff_alloc_picture(s, s->next_picture_ptr, 0) < 0)

                return -1;

            ff_thread_report_progress((AVFrame*)s->next_picture_ptr, INT_MAX, 0);

            ff_thread_report_progress((AVFrame*)s->next_picture_ptr, INT_MAX, 1);

        }

    }

    if(s->last_picture_ptr) ff_copy_picture(&s->last_picture, s->last_picture_ptr);

    if(s->next_picture_ptr) ff_copy_picture(&s->next_picture, s->next_picture_ptr);

    assert(s->pict_type == AV_PICTURE_TYPE_I || (s->last_picture_ptr && s->last_picture_ptr->f.data[0]));

    if(s->picture_structure!=PICT_FRAME && s->out_format != FMT_H264){

        int i;

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

            if(s->picture_structure == PICT_BOTTOM_FIELD){

                 s->current_picture.f.data[i] += s->current_picture.f.linesize[i];

            }

            s->current_picture.f.linesize[i] *= 2;

            s->last_picture.f.linesize[i]    *= 2;

            s->next_picture.f.linesize[i]    *= 2;

        }

    }

    s->error_recognition= avctx->error_recognition;

    /* set dequantizer, we can't do it during init as it might change for mpeg4

       and we can't do it in the header decode as init is not called for mpeg4 there yet */

    if(s->mpeg_quant || s->codec_id == CODEC_ID_MPEG2VIDEO){

        s->dct_unquantize_intra = s->dct_unquantize_mpeg2_intra;

        s->dct_unquantize_inter = s->dct_unquantize_mpeg2_inter;

    }else if(s->out_format == FMT_H263 || s->out_format == FMT_H261){

        s->dct_unquantize_intra = s->dct_unquantize_h263_intra;

        s->dct_unquantize_inter = s->dct_unquantize_h263_inter;

    }else{

        s->dct_unquantize_intra = s->dct_unquantize_mpeg1_intra;

        s->dct_unquantize_inter = s->dct_unquantize_mpeg1_inter;

    }

    if(s->dct_error_sum){

        assert(s->avctx->noise_reduction && s->encoding);

        update_noise_reduction(s);

    }

    if(CONFIG_MPEG_XVMC_DECODER && s->avctx->xvmc_acceleration)

        return ff_xvmc_field_start(s, avctx);

    return 0;

}


long vnc_client_write_sasl(VncState *vs)

{

    long ret;

    VNC_DEBUG("Write SASL: Pending output %p size %zd offset %zd "

              "Encoded: %p size %d offset %d\n",

              vs->output.buffer, vs->output.capacity, vs->output.offset,

              vs->sasl.encoded, vs->sasl.encodedLength, vs->sasl.encodedOffset);

    if (!vs->sasl.encoded) {

        int err;

        err = sasl_encode(vs->sasl.conn,

                          (char *)vs->output.buffer,

                          vs->output.offset,

                          (const char **)&vs->sasl.encoded,

                          &vs->sasl.encodedLength);

        if (err != SASL_OK)

            return vnc_client_io_error(vs, -1, NULL);

        vs->sasl.encodedRawLength = vs->output.offset;

        vs->sasl.encodedOffset = 0;

    ret = vnc_client_write_buf(vs,

                               vs->sasl.encoded + vs->sasl.encodedOffset,

                               vs->sasl.encodedLength - vs->sasl.encodedOffset);

    if (!ret)

        return 0;

    vs->sasl.encodedOffset += ret;

    if (vs->sasl.encodedOffset == vs->sasl.encodedLength) {

        vs->output.offset -= vs->sasl.encodedRawLength;

        vs->sasl.encoded = NULL;

        vs->sasl.encodedOffset = vs->sasl.encodedLength = 0;

    /* Can't merge this block with one above, because

     * someone might have written more unencrypted

     * data in vs->output while we were processing

     * SASL encoded output

     */

    if (vs->output.offset == 0) {

        if (vs->ioc_tag) {

            g_source_remove(vs->ioc_tag);

        vs->ioc_tag = qio_channel_add_watch(

            vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);

    return ret;


static void unassigned_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)

{

#ifdef DEBUG_UNASSIGNED

    printf("Unassigned mem write " TARGET_FMT_plx " = 0x%x\n", addr, val);

#endif

#if defined(TARGET_ALPHA) || defined(TARGET_SPARC) || defined(TARGET_MICROBLAZE)

    do_unassigned_access(addr, 1, 0, 0, 1);

#endif

}


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

{

    DeviceClass *dc = DEVICE_CLASS(klass);

    dc->realize = virtio_mmio_realizefn;

    dc->reset = virtio_mmio_reset;

    set_bit(DEVICE_CATEGORY_MISC, dc->categories);

    dc->props = virtio_mmio_properties;

}


void prepare_play(void)

{

    AVOutputFormat *ofmt;

    ofmt = guess_format("audio_device", NULL, NULL);

    if (!ofmt) {

        fprintf(stderr, "Could not find audio device\n");

        exit(1);

    }

    opt_output_file(audio_device);

}


static bool get_queued_page(RAMState *rs, PageSearchStatus *pss,

                            ram_addr_t *ram_addr_abs)

{

    RAMBlock  *block;

    ram_addr_t offset;

    bool dirty;

    do {

        block = unqueue_page(rs, &offset, ram_addr_abs);

        /*

         * We're sending this page, and since it's postcopy nothing else

         * will dirty it, and we must make sure it doesn't get sent again

         * even if this queue request was received after the background

         * search already sent it.

         */

        if (block) {

            unsigned long *bitmap;

            bitmap = atomic_rcu_read(&rs->ram_bitmap)->bmap;

            dirty = test_bit(*ram_addr_abs >> TARGET_PAGE_BITS, bitmap);

            if (!dirty) {

                trace_get_queued_page_not_dirty(

                    block->idstr, (uint64_t)offset,

                    (uint64_t)*ram_addr_abs,

                    test_bit(*ram_addr_abs >> TARGET_PAGE_BITS,

                         atomic_rcu_read(&rs->ram_bitmap)->unsentmap));

            } else {

                trace_get_queued_page(block->idstr,

                                      (uint64_t)offset,

                                      (uint64_t)*ram_addr_abs);

            }

        }

    } while (block && !dirty);

    if (block) {

        /*

         * As soon as we start servicing pages out of order, then we have

         * to kill the bulk stage, since the bulk stage assumes

         * in (migration_bitmap_find_and_reset_dirty) that every page is

         * dirty, that's no longer true.

         */

        rs->ram_bulk_stage = false;

        /*

         * We want the background search to continue from the queued page

         * since the guest is likely to want other pages near to the page

         * it just requested.

         */

        pss->block = block;

        pss->offset = offset;

    }

    return !!block;

}


static int sp5x_decode_frame(AVCodecContext *avctx,

                              void *data, int *data_size,

                              AVPacket *avpkt)

{

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    AVPacket avpkt_recoded;

    const int qscale = 5;

    const uint8_t *buf_ptr;

    uint8_t *recoded;

    int i = 0, j = 0;

    if (!avctx->width || !avctx->height)

        return -1;

    buf_ptr = buf;

    recoded = av_mallocz(buf_size + 1024);

    if (!recoded)

        return -1;

    /* SOI */

    recoded[j++] = 0xFF;

    recoded[j++] = 0xD8;

    memcpy(recoded+j, &sp5x_data_dqt[0], sizeof(sp5x_data_dqt));

    memcpy(recoded+j+5, &sp5x_quant_table[qscale * 2], 64);

    memcpy(recoded+j+70, &sp5x_quant_table[(qscale * 2) + 1], 64);

    j += sizeof(sp5x_data_dqt);

    memcpy(recoded+j, &sp5x_data_dht[0], sizeof(sp5x_data_dht));

    j += sizeof(sp5x_data_dht);

    memcpy(recoded+j, &sp5x_data_sof[0], sizeof(sp5x_data_sof));

    AV_WB16(recoded+j+5, avctx->coded_height);

    AV_WB16(recoded+j+7, avctx->coded_width);

    j += sizeof(sp5x_data_sof);

    memcpy(recoded+j, &sp5x_data_sos[0], sizeof(sp5x_data_sos));

    j += sizeof(sp5x_data_sos);

    if(avctx->codec_id==CODEC_ID_AMV)

        for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++)

            recoded[j++] = buf[i];

    else

    for (i = 14; i < buf_size && j < buf_size+1024-2; i++)

    {

        recoded[j++] = buf[i];

        if (buf[i] == 0xff)

            recoded[j++] = 0;

    }

    /* EOI */

    recoded[j++] = 0xFF;

    recoded[j++] = 0xD9;

    avctx->flags &= ~CODEC_FLAG_EMU_EDGE;

    av_init_packet(&avpkt_recoded);

    avpkt_recoded.data = recoded;

    avpkt_recoded.size = j;

    i = ff_mjpeg_decode_frame(avctx, data, data_size, &avpkt_recoded);

    av_free(recoded);

    return i;

}


int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
                                int vector, PCIDevice *dev)
{
    static bool notify_list_inited = false;
    MSIRouteEntry *entry;
    if (!dev) {
        /* These are (possibly) IOAPIC routes only used for split
         * kernel irqchip mode, while what we are housekeeping are
         * PCI devices only. */
        return 0;
    entry = g_new0(MSIRouteEntry, 1);
    entry->dev = dev;
    entry->vector = vector;
    entry->virq = route->gsi;
    QLIST_INSERT_HEAD(&msi_route_list, entry, list);
    trace_kvm_x86_add_msi_route(route->gsi);
    return 0;


static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) {

    GetBitContext *gb=&vc->gb;

    uint_fast8_t i;

    vc->mode_count=get_bits(gb, 6)+1;

    vc->modes=av_mallocz(vc->mode_count * sizeof(vorbis_mode));

    AV_DEBUG(" There are %d modes.\n", vc->mode_count);

    for(i=0;i<vc->mode_count;++i) {

        vorbis_mode *mode_setup=&vc->modes[i];

        mode_setup->blockflag=get_bits1(gb);

        mode_setup->windowtype=get_bits(gb, 16); //FIXME check

        mode_setup->transformtype=get_bits(gb, 16); //FIXME check

        mode_setup->mapping=get_bits(gb, 8); //FIXME check

        AV_DEBUG(" %d mode: blockflag %d, windowtype %d, transformtype %d, mapping %d \n", i, mode_setup->blockflag, mode_setup->windowtype, mode_setup->transformtype, mode_setup->mapping);

    }

    return 0;

}


static int smka_decode_frame(AVCodecContext *avctx, void *data,

                             int *got_frame_ptr, AVPacket *avpkt)

{

    AVFrame *frame     = data;

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    GetBitContext gb;

    HuffContext h[4] = { { 0 } };

    VLC vlc[4]       = { { 0 } };

    int16_t *samples;

    uint8_t *samples8;

    int val;

    int i, res, ret;

    int unp_size;

    int bits, stereo;

    int pred[2] = {0, 0};

    if (buf_size <= 4) {

        av_log(avctx, AV_LOG_ERROR, "packet is too small\n");

        return AVERROR(EINVAL);

    }

    unp_size = AV_RL32(buf);

    init_get_bits(&gb, buf + 4, (buf_size - 4) * 8);

    if(!get_bits1(&gb)){

        av_log(avctx, AV_LOG_INFO, "Sound: no data\n");

        *got_frame_ptr = 0;

        return 1;

    }

    stereo = get_bits1(&gb);

    bits = get_bits1(&gb);

    if (stereo ^ (avctx->channels != 1)) {

        av_log(avctx, AV_LOG_ERROR, "channels mismatch\n");

        return AVERROR(EINVAL);

    }

    if (bits && avctx->sample_fmt == AV_SAMPLE_FMT_U8) {

        av_log(avctx, AV_LOG_ERROR, "sample format mismatch\n");

        return AVERROR(EINVAL);

    }

    /* get output buffer */

    frame->nb_samples = unp_size / (avctx->channels * (bits + 1));

    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");

        return ret;

    }

    samples  = (int16_t *)frame->data[0];

    samples8 =            frame->data[0];

    // Initialize

    for(i = 0; i < (1 << (bits + stereo)); i++) {

        h[i].length = 256;

        h[i].maxlength = 0;

        h[i].current = 0;

        h[i].bits = av_mallocz(256 * 4);

        h[i].lengths = av_mallocz(256 * sizeof(int));

        h[i].values = av_mallocz(256 * sizeof(int));

        skip_bits1(&gb);

        smacker_decode_tree(&gb, &h[i], 0, 0);

        skip_bits1(&gb);

        if(h[i].current > 1) {

            res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length,

                    h[i].lengths, sizeof(int), sizeof(int),

                    h[i].bits, sizeof(uint32_t), sizeof(uint32_t), INIT_VLC_LE);

            if(res < 0) {

                av_log(avctx, AV_LOG_ERROR, "Cannot build VLC table\n");

                return -1;

            }

        }

    }

    /* this codec relies on wraparound instead of clipping audio */

    if(bits) { //decode 16-bit data

        for(i = stereo; i >= 0; i--)

            pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16);

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

            *samples++ = pred[i];

        for(; i < unp_size / 2; i++) {

            if(i & stereo) {

                if(vlc[2].table)

                    res = get_vlc2(&gb, vlc[2].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val  = h[2].values[res];

                if(vlc[3].table)

                    res = get_vlc2(&gb, vlc[3].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val |= h[3].values[res] << 8;

                pred[1] += sign_extend(val, 16);

                *samples++ = pred[1];

            } else {

                if(vlc[0].table)

                    res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val  = h[0].values[res];

                if(vlc[1].table)

                    res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                val |= h[1].values[res] << 8;

                pred[0] += sign_extend(val, 16);

                *samples++ = pred[0];

            }

        }

    } else { //8-bit data

        for(i = stereo; i >= 0; i--)

            pred[i] = get_bits(&gb, 8);

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

            *samples8++ = pred[i];

        for(; i < unp_size; i++) {

            if(i & stereo){

                if(vlc[1].table)

                    res = get_vlc2(&gb, vlc[1].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                pred[1] += sign_extend(h[1].values[res], 8);

                *samples8++ = pred[1];

            } else {

                if(vlc[0].table)

                    res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3);

                else

                    res = 0;

                pred[0] += sign_extend(h[0].values[res], 8);

                *samples8++ = pred[0];

            }

        }

    }

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

        if(vlc[i].table)

            ff_free_vlc(&vlc[i]);

        av_free(h[i].bits);

        av_free(h[i].lengths);

        av_free(h[i].values);

    }

    *got_frame_ptr = 1;

    return buf_size;

}


static void ppc_hw_interrupt(CPUPPCState *env)

{

    PowerPCCPU *cpu = ppc_env_get_cpu(env);

    int hdice;

#if 0

    CPUState *cs = CPU(cpu);

    qemu_log_mask(CPU_LOG_INT, "%s: %p pending %08x req %08x me %d ee %d\n",

                  __func__, env, env->pending_interrupts,

                  cs->interrupt_request, (int)msr_me, (int)msr_ee);

#endif

    /* External reset */

    if (env->pending_interrupts & (1 << PPC_INTERRUPT_RESET)) {

        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_RESET);

        powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_RESET);

        return;

    }

    /* Machine check exception */

    if (env->pending_interrupts & (1 << PPC_INTERRUPT_MCK)) {

        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_MCK);

        powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_MCHECK);

        return;

    }

#if 0 /* TODO */

    /* External debug exception */

    if (env->pending_interrupts & (1 << PPC_INTERRUPT_DEBUG)) {

        env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DEBUG);

        powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DEBUG);

        return;

    }

#endif

    if (0) {

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

        hdice = env->spr[SPR_LPCR] & 1;

    } else {

        hdice = 0;

    }

    if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) {

        /* Hypervisor decrementer exception */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) {

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR);

            return;

        }

    }

    if (msr_ce != 0) {

        /* External critical interrupt */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CEXT)) {

            /* Taking a critical external interrupt does not clear the external

             * critical interrupt status

             */

#if 0

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CEXT);

#endif

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_CRITICAL);

            return;

        }

    }

    if (msr_ee != 0) {

        /* Watchdog timer on embedded PowerPC */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_WDT)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_WDT);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_WDT);

            return;

        }

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORCI);

            return;

        }

        /* Fixed interval timer on embedded PowerPC */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_FIT);

            return;

        }

        /* Programmable interval timer on embedded PowerPC */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PIT)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PIT);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PIT);

            return;

        }

        /* Decrementer exception */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) {

            if (ppc_decr_clear_on_delivery(env)) {

                env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR);

            }

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR);

            return;

        }

        /* External interrupt */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {

            /* Taking an external interrupt does not clear the external

             * interrupt status

             */

#if 0

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);

#endif

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_EXTERNAL);

            return;

        }

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DOORI);

            return;

        }

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_PERFM);

            return;

        }

        /* Thermal interrupt */

        if (env->pending_interrupts & (1 << PPC_INTERRUPT_THERM)) {

            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_THERM);

            powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_THERM);

            return;

        }

    }

}


static void dct_error(const struct algo *dct, int test, int is_idct, int speed)

{

    int it, i, scale;

    int err_inf, v;

    int64_t err2, ti, ti1, it1;

    int64_t sysErr[64], sysErrMax = 0;

    int maxout = 0;

    int blockSumErrMax = 0, blockSumErr;

    AVLFG prng;

    av_lfg_init(&prng, 1);

    err_inf = 0;

    err2 = 0;

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

        sysErr[i] = 0;

    for (it = 0; it < NB_ITS; it++) {

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

            block1[i] = 0;

        switch (test) {

        case 0:

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

                block1[i] = (av_lfg_get(&prng) % 512) - 256;

            if (is_idct) {

                ff_ref_fdct(block1);

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

                    block1[i] >>= 3;

            }

            break;

        case 1: {

                int num = av_lfg_get(&prng) % 10 + 1;

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

                    block1[av_lfg_get(&prng) % 64] =

                        av_lfg_get(&prng) % 512 - 256;

            }

            break;

        case 2:

            block1[0] = av_lfg_get(&prng) % 4096 - 2048;

            block1[63] = (block1[0] & 1) ^ 1;

            break;

        }

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

            block_org[i] = block1[i];

        if (dct->format == MMX_PERM) {

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

                block[idct_mmx_perm[i]] = block1[i];

        } else if (dct->format == MMX_SIMPLE_PERM) {

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

                block[idct_simple_mmx_perm[i]] = block1[i];

        } else if (dct->format == SSE2_PERM) {

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

                block[(i & 0x38) | idct_sse2_row_perm[i & 7]] = block1[i];

        } else if (dct->format == PARTTRANS_PERM) {

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

                block[(i & 0x24) | ((i & 3) << 3) | ((i >> 3) & 3)] = block1[i];

        } else {

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

                block[i] = block1[i];

        }

        dct->func(block);

        mmx_emms();

        if (dct->format == SCALE_PERM) {

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

                scale = 8 * (1 << (AANSCALE_BITS + 11)) / ff_aanscales[i];

                block[i] = (block[i] * scale) >> AANSCALE_BITS;

            }

        }

        dct->ref(block1);

        blockSumErr = 0;

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

            v = abs(block[i] - block1[i]);

            if (v > err_inf)

                err_inf = v;

            err2 += v * v;

            sysErr[i] += block[i] - block1[i];

            blockSumErr += v;

            if (abs(block[i]) > maxout)

                maxout = abs(block[i]);

        }

        if (blockSumErrMax < blockSumErr)

            blockSumErrMax = blockSumErr;

    }

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

        sysErrMax = FFMAX(sysErrMax, FFABS(sysErr[i]));

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

        if (i % 8 == 0)

            printf("\n");

        printf("%7d ", (int) sysErr[i]);

    }

    printf("\n");

    printf("%s %s: err_inf=%d err2=%0.8f syserr=%0.8f maxout=%d blockSumErr=%d\n",

           is_idct ? "IDCT" : "DCT", dct->name, err_inf,

           (double) err2 / NB_ITS / 64.0, (double) sysErrMax / NB_ITS,

           maxout, blockSumErrMax);

    if (!speed)

        return;

    /* speed test */

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

        block1[i] = 0;

    switch (test) {

    case 0:

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

            block1[i] = av_lfg_get(&prng) % 512 - 256;

        if (is_idct) {

            ff_ref_fdct(block1);

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

                block1[i] >>= 3;

        }

        break;

    case 1:

    case 2:

        block1[0] = av_lfg_get(&prng) % 512 - 256;

        block1[1] = av_lfg_get(&prng) % 512 - 256;

        block1[2] = av_lfg_get(&prng) % 512 - 256;

        block1[3] = av_lfg_get(&prng) % 512 - 256;

        break;

    }

    if (dct->format == MMX_PERM) {

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

            block[idct_mmx_perm[i]] = block1[i];

    } else if (dct->format == MMX_SIMPLE_PERM) {

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

            block[idct_simple_mmx_perm[i]] = block1[i];

    } else {

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

            block[i] = block1[i];

    }

    ti = gettime();

    it1 = 0;

    do {

        for (it = 0; it < NB_ITS_SPEED; it++) {

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

                block[i] = block1[i];

            dct->func(block);

        }

        it1 += NB_ITS_SPEED;

        ti1 = gettime() - ti;

    } while (ti1 < 1000000);

    mmx_emms();

    printf("%s %s: %0.1f kdct/s\n", is_idct ? "IDCT" : "DCT", dct->name,

           (double) it1 * 1000.0 / (double) ti1);

}


static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic,

                                   int depth, GetByteContext *gb)

{

    uint8_t *output, *output_end;

    int p1, p2, line=avctx->height - 1, pos=0, i;

    uint16_t pix16;

    uint32_t pix32;

    unsigned int width= FFABS(pic->linesize[0]) / (depth >> 3);

    output     = pic->data[0] + (avctx->height - 1) * pic->linesize[0];

    output_end = pic->data[0] +  avctx->height      * pic->linesize[0];

    while (bytestream2_get_bytes_left(gb) > 0) {

        p1 = bytestream2_get_byteu(gb);

        if(p1 == 0) { //Escape code

            p2 = bytestream2_get_byte(gb);

            if(p2 == 0) { //End-of-line

                output = pic->data[0] + (--line) * pic->linesize[0];

                if (line < 0) {

                    if (bytestream2_get_be16(gb) == 1) { // end-of-picture

                        return 0;

                    } else {

                        av_log(avctx, AV_LOG_ERROR,

                               "Next line is beyond picture bounds (%d bytes left)\n",

                               bytestream2_get_bytes_left(gb));

                        return AVERROR_INVALIDDATA;

                    }

                }

                pos = 0;

                continue;

            } else if(p2 == 1) { //End-of-picture

                return 0;

            } else if(p2 == 2) { //Skip

                p1 = bytestream2_get_byte(gb);

                p2 = bytestream2_get_byte(gb);

                line -= p2;

                pos += p1;

                if (line < 0 || pos >= width){

                    av_log(avctx, AV_LOG_ERROR, "Skip beyond picture bounds\n");

                    return -1;

                }

                output = pic->data[0] + line * pic->linesize[0] + pos * (depth >> 3);

                continue;

            }

            // Copy data

            if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) ||

                (pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) {

                bytestream2_skip(gb, 2 * (depth >> 3));

                continue;

            } else if (bytestream2_get_bytes_left(gb) < p2 * (depth >> 3)) {

                av_log(avctx, AV_LOG_ERROR, "bytestream overrun\n");

                return AVERROR_INVALIDDATA;

            }

            if ((depth == 8) || (depth == 24)) {

                for(i = 0; i < p2 * (depth >> 3); i++) {

                    *output++ = bytestream2_get_byteu(gb);

                }

                // RLE8 copy is actually padded - and runs are not!

                if(depth == 8 && (p2 & 1)) {

                    bytestream2_skip(gb, 1);

                }

            } else if (depth == 16) {

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

                    *(uint16_t*)output = bytestream2_get_le16u(gb);

                    output += 2;

                }

            } else if (depth == 32) {

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

                    *(uint32_t*)output = bytestream2_get_le32u(gb);

                    output += 4;

                }

            }

            pos += p2;

        } else { //run of pixels

            uint8_t pix[3]; //original pixel

            if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) ||

                (pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end))

                continue;

            switch(depth){

            case  8: pix[0] = bytestream2_get_byte(gb);

                     break;

            case 16: pix16  = bytestream2_get_le16(gb);

                     break;

            case 24: pix[0] = bytestream2_get_byte(gb);

                     pix[1] = bytestream2_get_byte(gb);

                     pix[2] = bytestream2_get_byte(gb);

                     break;

            case 32: pix32  = bytestream2_get_le32(gb);

                     break;

            }

            switch(depth){

            case  8:

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

                        *output++ = pix[0];

                break;

            case 16:

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

                        *(uint16_t*)output = pix16;

                        output += 2;

                }

                break;

            case 24:

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

                        *output++ = pix[0];

                        *output++ = pix[1];

                        *output++ = pix[2];

                }

                break;

            case 32:

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

                        *(uint32_t*)output = pix32;

                        output += 4;

                }

                break;

            }

            pos += p1;

        }

    }

    av_log(avctx, AV_LOG_WARNING, "MS RLE warning: no end-of-picture code\n");

    return 0;

}


static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,

                                        DeviceState *dev, Error **errp)

{

    sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);

    Error *local_err = NULL;

    PCDIMMDevice *dimm = PC_DIMM(dev);

    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);

    MemoryRegion *mr = ddc->get_memory_region(dimm);

    uint64_t size = memory_region_size(mr);

    uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;

    uint64_t addr_start, addr;

    int i;

    sPAPRDRConnector *drc;

    addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,

                                         &local_err);

    if (local_err) {

        goto out;

    }

    spapr_pending_dimm_unplugs_add(spapr, nr_lmbs, dimm);

    addr = addr_start;

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

        drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,

                              addr / SPAPR_MEMORY_BLOCK_SIZE);

        g_assert(drc);

        spapr_drc_detach(drc);

        addr += SPAPR_MEMORY_BLOCK_SIZE;

    }

    drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB,

                          addr_start / SPAPR_MEMORY_BLOCK_SIZE);

    spapr_hotplug_req_remove_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB,

                                              nr_lmbs, spapr_drc_index(drc));

out:

    error_propagate(errp, local_err);

}


av_cold void ff_cavsdsp_init_x86(CAVSDSPContext *c, AVCodecContext *avctx)

{

    int cpu_flags = av_get_cpu_flags();

    cavsdsp_init_mmx(c, avctx);

#if HAVE_AMD3DNOW_INLINE

    if (INLINE_AMD3DNOW(cpu_flags))

        cavsdsp_init_3dnow(c, avctx);

#endif /* HAVE_AMD3DNOW_INLINE */

#if HAVE_MMXEXT_INLINE

    if (INLINE_MMXEXT(cpu_flags)) {

        DSPFUNC(put, 0, 16, mmxext);

        DSPFUNC(put, 1,  8, mmxext);

        DSPFUNC(avg, 0, 16, mmxext);

        DSPFUNC(avg, 1,  8, mmxext);

    }

#endif

#if HAVE_MMX_EXTERNAL

    if (EXTERNAL_MMXEXT(cpu_flags)) {

        c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_mmxext;

        c->avg_cavs_qpel_pixels_tab[1][0] = avg_cavs_qpel8_mc00_mmxext;

    }

#endif

#if HAVE_SSE2_EXTERNAL

    if (EXTERNAL_SSE2(cpu_flags)) {

        c->put_cavs_qpel_pixels_tab[0][0] = put_cavs_qpel16_mc00_sse2;

        c->avg_cavs_qpel_pixels_tab[0][0] = avg_cavs_qpel16_mc00_sse2;

    }

#endif

}


static int finish_frame(AVCodecContext *avctx, AVFrame *pict)

{

    RV34DecContext *r = avctx->priv_data;

    MpegEncContext *s = &r->s;

    int got_picture = 0, ret;

    ff_er_frame_end(&s->er);

    ff_mpv_frame_end(s);

    s->mb_num_left = 0;

    if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))

        ff_thread_report_progress(&s->current_picture_ptr->tf, INT_MAX, 0);

    if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) {

        if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0)

            return ret;

        ff_print_debug_info(s, s->current_picture_ptr);

        got_picture = 1;

    } else if (s->last_picture_ptr != NULL) {

        if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0)

            return ret;

        ff_print_debug_info(s, s->last_picture_ptr);

        got_picture = 1;

    }

    return got_picture;

}


static void init_parse_context(OptionParseContext *octx,

                               const OptionGroupDef *groups)

{

    static const OptionGroupDef global_group = { "global" };

    const OptionGroupDef *g = groups;

    int i;

    memset(octx, 0, sizeof(*octx));

    while (g->name)

        g++;

    octx->nb_groups = g - groups;

    octx->groups    = av_mallocz(sizeof(*octx->groups) * octx->nb_groups);

    if (!octx->groups)

        exit(1);

    for (i = 0; i < octx->nb_groups; i++)

        octx->groups[i].group_def = &groups[i];

    octx->global_opts.group_def = &global_group;

    octx->global_opts.arg       = "";

    init_opts();

}


void timerlist_notify(QEMUTimerList *timer_list)

{

    if (timer_list->notify_cb) {

        timer_list->notify_cb(timer_list->notify_opaque);

    } else {

        qemu_notify_event();

    }

}


static char *isabus_get_fw_dev_path(DeviceState *dev)

{

    ISADevice *d = (ISADevice*)dev;

    char path[40];

    int off;

    off = snprintf(path, sizeof(path), "%s", qdev_fw_name(dev));

    if (d->ioport_id) {

        snprintf(path + off, sizeof(path) - off, "@%04x", d->ioport_id);

    }

    return strdup(path);

}


static void sigp_cpu_reset(void *arg)

{

    CPUState *cpu = arg;

    S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);

    cpu_synchronize_state(cpu);

    scc->cpu_reset(cpu);

    cpu_synchronize_post_reset(cpu);

}


ram_addr_t qemu_ram_alloc_from_ptr(DeviceState *dev, const char *name,

                                   ram_addr_t size, void *host)

{

    RAMBlock *new_block, *block;

    size = TARGET_PAGE_ALIGN(size);

    new_block = qemu_mallocz(sizeof(*new_block));

    if (dev && dev->parent_bus && dev->parent_bus->info->get_dev_path) {

        char *id = dev->parent_bus->info->get_dev_path(dev);

        if (id) {

            snprintf(new_block->idstr, sizeof(new_block->idstr), "%s/", id);

            qemu_free(id);

        }

    }

    pstrcat(new_block->idstr, sizeof(new_block->idstr), name);

    QLIST_FOREACH(block, &ram_list.blocks, next) {

        if (!strcmp(block->idstr, new_block->idstr)) {

            fprintf(stderr, "RAMBlock \"%s\" already registered, abort!\n",

                    new_block->idstr);

            abort();

        }

    }

    new_block->offset = find_ram_offset(size);

    if (host) {

        new_block->host = host;

        new_block->flags |= RAM_PREALLOC_MASK;

    } else {

        if (mem_path) {

#if defined (__linux__) && !defined(TARGET_S390X)

            new_block->host = file_ram_alloc(new_block, size, mem_path);

            if (!new_block->host) {

                new_block->host = qemu_vmalloc(size);

                qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);

            }

#else

            fprintf(stderr, "-mem-path option unsupported\n");

            exit(1);

#endif

        } else {

#if defined(TARGET_S390X) && defined(CONFIG_KVM)

            /* XXX S390 KVM requires the topmost vma of the RAM to be < 256GB */

            new_block->host = mmap((void*)0x1000000, size,

                                   PROT_EXEC|PROT_READ|PROT_WRITE,

                                   MAP_SHARED | MAP_ANONYMOUS, -1, 0);

#else

            if (xen_mapcache_enabled()) {

                xen_ram_alloc(new_block->offset, size);

            } else {

                new_block->host = qemu_vmalloc(size);

            }

#endif

            qemu_madvise(new_block->host, size, QEMU_MADV_MERGEABLE);

        }

    }

    new_block->length = size;

    QLIST_INSERT_HEAD(&ram_list.blocks, new_block, next);

    ram_list.phys_dirty = qemu_realloc(ram_list.phys_dirty,

                                       last_ram_offset() >> TARGET_PAGE_BITS);

    memset(ram_list.phys_dirty + (new_block->offset >> TARGET_PAGE_BITS),

           0xff, size >> TARGET_PAGE_BITS);

    if (kvm_enabled())

        kvm_setup_guest_memory(new_block->host, size);

    return new_block->offset;

}


static void usb_host_handle_control(USBDevice *udev, USBPacket *p,

                                    int request, int value, int index,

                                    int length, uint8_t *data)

{

    USBHostDevice *s = USB_HOST_DEVICE(udev);

    USBHostRequest *r;

    int rc;

    trace_usb_host_req_control(s->bus_num, s->addr, p, request, value, index);

    if (s->dh == NULL) {

        p->status = USB_RET_NODEV;

        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);

        return;

    }

    switch (request) {

    case DeviceOutRequest | USB_REQ_SET_ADDRESS:

        usb_host_set_address(s, value);

        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);

        return;

    case DeviceOutRequest | USB_REQ_SET_CONFIGURATION:

        usb_host_set_config(s, value & 0xff, p);

        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);

        return;

    case InterfaceOutRequest | USB_REQ_SET_INTERFACE:

        usb_host_set_interface(s, index, value, p);

        trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);

        return;

    case EndpointOutRequest | USB_REQ_CLEAR_FEATURE:

        if (value == 0) { /* clear halt */

            int pid = (index & USB_DIR_IN) ? USB_TOKEN_IN : USB_TOKEN_OUT;

            libusb_clear_halt(s->dh, index);

            usb_ep_set_halted(udev, pid, index & 0x0f, 0);

            trace_usb_host_req_emulated(s->bus_num, s->addr, p, p->status);

            return;

        }

    }

    r = usb_host_req_alloc(s, p, (request >> 8) & USB_DIR_IN, length + 8);

    r->cbuf = data;

    r->clen = length;

    memcpy(r->buffer, udev->setup_buf, 8);

    if (!r->in) {

        memcpy(r->buffer + 8, r->cbuf, r->clen);

    }

    /* Fix up USB-3 ep0 maxpacket size to allow superspeed connected devices

     * to work redirected to a not superspeed capable hcd */

    if (udev->speed == USB_SPEED_SUPER &&

        !(udev->port->speedmask & USB_SPEED_MASK_SUPER) &&

        request == 0x8006 && value == 0x100 && index == 0) {

        r->usb3ep0quirk = true;

    }

    libusb_fill_control_transfer(r->xfer, s->dh, r->buffer,

                                 usb_host_req_complete_ctrl, r,

                                 CONTROL_TIMEOUT);

    rc = libusb_submit_transfer(r->xfer);

    if (rc != 0) {

        p->status = USB_RET_NODEV;

        trace_usb_host_req_complete(s->bus_num, s->addr, p,

                                    p->status, p->actual_length);

        if (rc == LIBUSB_ERROR_NO_DEVICE) {

            usb_host_nodev(s);

        }

        return;

    }

    p->status = USB_RET_ASYNC;

}


float32 helper_fabs_FT(float32 t0)

{

    return float32_abs(t0);

}


static int i440fx_pcihost_initfn(SysBusDevice *dev)

{

    I440FXState *s = FROM_SYSBUS(I440FXState, dev);

    register_ioport_write(0xcf8, 4, 4, i440fx_addr_writel, s);

    register_ioport_read(0xcf8, 4, 4, i440fx_addr_readl, s);

    register_ioport_write(0xcfc, 4, 1, pci_host_data_writeb, s);

    register_ioport_write(0xcfc, 4, 2, pci_host_data_writew, s);

    register_ioport_write(0xcfc, 4, 4, pci_host_data_writel, s);

    register_ioport_read(0xcfc, 4, 1, pci_host_data_readb, s);

    register_ioport_read(0xcfc, 4, 2, pci_host_data_readw, s);

    register_ioport_read(0xcfc, 4, 4, pci_host_data_readl, s);

    return 0;

}


static void tcg_out_br(TCGContext *s, int label_index)

{

    TCGLabel *l = &s->labels[label_index];

    uint64_t imm;

    /* We pay attention here to not modify the branch target by reading

       the existing value and using it again. This ensure that caches and

       memory are kept coherent during retranslation. */

    if (l->has_value) {

        imm = l->u.value_ptr -  s->code_ptr;

    } else {

        imm = get_reloc_pcrel21b_slot2(s->code_ptr);

        tcg_out_reloc(s, s->code_ptr, R_IA64_PCREL21B, label_index, 0);

    }

    tcg_out_bundle(s, mmB,

                   INSN_NOP_M,

                   INSN_NOP_M,

                   tcg_opc_b1(TCG_REG_P0, OPC_BR_SPTK_MANY_B1, imm));

}


static uint32_t virtio_blk_get_features(VirtIODevice *vdev, uint32_t features)

{

    VirtIOBlock *s = to_virtio_blk(vdev);

    features |= (1 << VIRTIO_BLK_F_SEG_MAX);

    features |= (1 << VIRTIO_BLK_F_GEOMETRY);

    features |= (1 << VIRTIO_BLK_F_TOPOLOGY);

    features |= (1 << VIRTIO_BLK_F_BLK_SIZE);

    features |= (1 << VIRTIO_BLK_F_SCSI);

    features |= (1 << VIRTIO_BLK_F_CONFIG_WCE);

    if (bdrv_enable_write_cache(s->bs))

        features |= (1 << VIRTIO_BLK_F_WCE);

    if (bdrv_is_read_only(s->bs))

        features |= 1 << VIRTIO_BLK_F_RO;

    return features;

}


static inline void write_back_non_zero_count(H264Context *h){

    MpegEncContext * const s = &h->s;

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

    int n;

    for( n = 0; n < 16+4+4; n++ )

        h->non_zero_count[mb_xy][n] = h->non_zero_count_cache[scan8[n]];

}


static void lm32_evr_init(MachineState *machine)

{

    const char *cpu_model = machine->cpu_model;

    const char *kernel_filename = machine->kernel_filename;

    LM32CPU *cpu;

    CPULM32State *env;

    DriveInfo *dinfo;

    MemoryRegion *address_space_mem =  get_system_memory();

    MemoryRegion *phys_ram = g_new(MemoryRegion, 1);

    qemu_irq *cpu_irq, irq[32];

    ResetInfo *reset_info;

    int i;

    /* memory map */

    hwaddr flash_base  = 0x04000000;

    size_t flash_sector_size       = 256 * 1024;

    size_t flash_size              = 32 * 1024 * 1024;

    hwaddr ram_base    = 0x08000000;

    size_t ram_size                = 64 * 1024 * 1024;

    hwaddr timer0_base = 0x80002000;

    hwaddr uart0_base  = 0x80006000;

    hwaddr timer1_base = 0x8000a000;

    int uart0_irq                  = 0;

    int timer0_irq                 = 1;

    int timer1_irq                 = 3;

    reset_info = g_malloc0(sizeof(ResetInfo));

    if (cpu_model == NULL) {

        cpu_model = "lm32-full";

    }

    cpu = cpu_lm32_init(cpu_model);

    if (cpu == NULL) {

        fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model);

        exit(1);

    }

    env = &cpu->env;

    reset_info->cpu = cpu;

    reset_info->flash_base = flash_base;

    memory_region_init_ram(phys_ram, NULL, "lm32_evr.sdram", ram_size,

                           &error_abort);

    vmstate_register_ram_global(phys_ram);

    memory_region_add_subregion(address_space_mem, ram_base, phys_ram);

    dinfo = drive_get(IF_PFLASH, 0, 0);

    /* Spansion S29NS128P */

    pflash_cfi02_register(flash_base, NULL, "lm32_evr.flash", flash_size,

                          dinfo ? blk_bs(blk_by_legacy_dinfo(dinfo)) : NULL,

                          flash_sector_size, flash_size / flash_sector_size,

                          1, 2, 0x01, 0x7e, 0x43, 0x00, 0x555, 0x2aa, 1);

    /* create irq lines */

    cpu_irq = qemu_allocate_irqs(cpu_irq_handler, cpu, 1);

    env->pic_state = lm32_pic_init(*cpu_irq);

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

        irq[i] = qdev_get_gpio_in(env->pic_state, i);

    }

    sysbus_create_simple("lm32-uart", uart0_base, irq[uart0_irq]);

    sysbus_create_simple("lm32-timer", timer0_base, irq[timer0_irq]);

    sysbus_create_simple("lm32-timer", timer1_base, irq[timer1_irq]);

    /* make sure juart isn't the first chardev */

    env->juart_state = lm32_juart_init();

    reset_info->bootstrap_pc = flash_base;

    if (kernel_filename) {

        uint64_t entry;

        int kernel_size;

        kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL,

                               1, ELF_MACHINE, 0);

        reset_info->bootstrap_pc = entry;

        if (kernel_size < 0) {

            kernel_size = load_image_targphys(kernel_filename, ram_base,

                                              ram_size);

            reset_info->bootstrap_pc = ram_base;

        }

        if (kernel_size < 0) {

            fprintf(stderr, "qemu: could not load kernel '%s'\n",

                    kernel_filename);

            exit(1);

        }

    }

    qemu_register_reset(main_cpu_reset, reset_info);

}


static void test_qemu_strtosz_trailing(void)

{

    const char *str;

    char *endptr = NULL;

    int64_t res;

    str = "123xxx";

    res = qemu_strtosz_MiB(str, &endptr);

    g_assert_cmpint(res, ==, 123 * M_BYTE);

    g_assert(endptr == str + 3);

    res = qemu_strtosz(str, NULL);

    g_assert_cmpint(res, ==, -EINVAL);

    str = "1kiB";

    res = qemu_strtosz(str, &endptr);

    g_assert_cmpint(res, ==, 1024);

    g_assert(endptr == str + 2);

    res = qemu_strtosz(str, NULL);

    g_assert_cmpint(res, ==, -EINVAL);

}


build_header(BIOSLinker *linker, GArray *table_data,

             AcpiTableHeader *h, const char *sig, int len, uint8_t rev,

             const char *oem_id, const char *oem_table_id)

{

    memcpy(&h->signature, sig, 4);

    h->length = cpu_to_le32(len);

    h->revision = rev;

    if (oem_id) {

        strncpy((char *)h->oem_id, oem_id, sizeof h->oem_id);

    } else {

        memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);

    }

    if (oem_table_id) {

        strncpy((char *)h->oem_table_id, oem_table_id, sizeof(h->oem_table_id));

    } else {

        memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);

        memcpy(h->oem_table_id + 4, sig, 4);

    }

    h->oem_revision = cpu_to_le32(1);

    memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);

    h->asl_compiler_revision = cpu_to_le32(1);

    h->checksum = 0;

    /* Checksum to be filled in by Guest linker */

    bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,

                                    h, len, &h->checksum);

}