static void realview_init(MachineState *machine,

                          enum realview_board_type board_type)

{

    ARMCPU *cpu = NULL;

    CPUARMState *env;

    ObjectClass *cpu_oc;

    MemoryRegion *sysmem = get_system_memory();

    MemoryRegion *ram_lo = g_new(MemoryRegion, 1);

    MemoryRegion *ram_hi = g_new(MemoryRegion, 1);

    MemoryRegion *ram_alias = g_new(MemoryRegion, 1);

    MemoryRegion *ram_hack = g_new(MemoryRegion, 1);

    DeviceState *dev, *sysctl, *gpio2, *pl041;

    SysBusDevice *busdev;

    qemu_irq pic[64];

    qemu_irq mmc_irq[2];

    PCIBus *pci_bus = NULL;

    NICInfo *nd;

    I2CBus *i2c;

    int n;

    int done_nic = 0;

    qemu_irq cpu_irq[4];

    int is_mpcore = 0;

    int is_pb = 0;

    uint32_t proc_id = 0;

    uint32_t sys_id;

    ram_addr_t low_ram_size;

    ram_addr_t ram_size = machine->ram_size;

    hwaddr periphbase = 0;

    switch (board_type) {

    case BOARD_EB:

        break;

    case BOARD_EB_MPCORE:

        is_mpcore = 1;

        periphbase = 0x10100000;

        break;

    case BOARD_PB_A8:

        is_pb = 1;

        break;

    case BOARD_PBX_A9:

        is_mpcore = 1;

        is_pb = 1;

        periphbase = 0x1f000000;

        break;

    }

    cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model);

    if (!cpu_oc) {

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

        exit(1);

    }

    for (n = 0; n < smp_cpus; n++) {

        Object *cpuobj = object_new(object_class_get_name(cpu_oc));

        Error *err = NULL;

        if (is_pb && is_mpcore) {

            object_property_set_int(cpuobj, periphbase, "reset-cbar", &err);

            if (err) {

                error_report("%s", error_get_pretty(err));

                exit(1);

            }

        }

        object_property_set_bool(cpuobj, true, "realized", &err);

        if (err) {

            error_report("%s", error_get_pretty(err));

            exit(1);

        }

        cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ);

    }

    cpu = ARM_CPU(first_cpu);

    env = &cpu->env;

    if (arm_feature(env, ARM_FEATURE_V7)) {

        if (is_mpcore) {

            proc_id = 0x0c000000;

        } else {

            proc_id = 0x0e000000;

        }

    } else if (arm_feature(env, ARM_FEATURE_V6K)) {

        proc_id = 0x06000000;

    } else if (arm_feature(env, ARM_FEATURE_V6)) {

        proc_id = 0x04000000;

    } else {

        proc_id = 0x02000000;

    }

    if (is_pb && ram_size > 0x20000000) {

        /* Core tile RAM.  */

        low_ram_size = ram_size - 0x20000000;

        ram_size = 0x20000000;

        memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size,

                               &error_abort);

        vmstate_register_ram_global(ram_lo);

        memory_region_add_subregion(sysmem, 0x20000000, ram_lo);

    }

    memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size,

                           &error_abort);

    vmstate_register_ram_global(ram_hi);

    low_ram_size = ram_size;

    if (low_ram_size > 0x10000000)

      low_ram_size = 0x10000000;

    /* SDRAM at address zero.  */

    memory_region_init_alias(ram_alias, NULL, "realview.alias",

                             ram_hi, 0, low_ram_size);

    memory_region_add_subregion(sysmem, 0, ram_alias);

    if (is_pb) {

        /* And again at a high address.  */

        memory_region_add_subregion(sysmem, 0x70000000, ram_hi);

    } else {

        ram_size = low_ram_size;

    }

    sys_id = is_pb ? 0x01780500 : 0xc1400400;

    sysctl = qdev_create(NULL, "realview_sysctl");

    qdev_prop_set_uint32(sysctl, "sys_id", sys_id);

    qdev_prop_set_uint32(sysctl, "proc_id", proc_id);

    qdev_init_nofail(sysctl);

    sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000);

    if (is_mpcore) {

        dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore");

        qdev_prop_set_uint32(dev, "num-cpu", smp_cpus);

        qdev_init_nofail(dev);

        busdev = SYS_BUS_DEVICE(dev);

        sysbus_mmio_map(busdev, 0, periphbase);

        for (n = 0; n < smp_cpus; n++) {

            sysbus_connect_irq(busdev, n, cpu_irq[n]);

        }

        sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL);

        /* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */

        realview_binfo.gic_cpu_if_addr = periphbase + 0x100;

    } else {

        uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000;

        /* For now just create the nIRQ GIC, and ignore the others.  */

        dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]);

    }

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

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

    }

    pl041 = qdev_create(NULL, "pl041");

    qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);

    qdev_init_nofail(pl041);

    sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);

    sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[19]);

    sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]);

    sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]);

    sysbus_create_simple("pl011", 0x10009000, pic[12]);

    sysbus_create_simple("pl011", 0x1000a000, pic[13]);

    sysbus_create_simple("pl011", 0x1000b000, pic[14]);

    sysbus_create_simple("pl011", 0x1000c000, pic[15]);

    /* DMA controller is optional, apparently.  */

    sysbus_create_simple("pl081", 0x10030000, pic[24]);

    sysbus_create_simple("sp804", 0x10011000, pic[4]);

    sysbus_create_simple("sp804", 0x10012000, pic[5]);

    sysbus_create_simple("pl061", 0x10013000, pic[6]);

    sysbus_create_simple("pl061", 0x10014000, pic[7]);

    gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]);

    sysbus_create_simple("pl111", 0x10020000, pic[23]);

    dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL);

    /* Wire up MMC card detect and read-only signals. These have

     * to go to both the PL061 GPIO and the sysctl register.

     * Note that the PL181 orders these lines (readonly,inserted)

     * and the PL061 has them the other way about. Also the card

     * detect line is inverted.

     */

    mmc_irq[0] = qemu_irq_split(

        qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT),

        qdev_get_gpio_in(gpio2, 1));

    mmc_irq[1] = qemu_irq_split(

        qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN),

        qemu_irq_invert(qdev_get_gpio_in(gpio2, 0)));

    qdev_connect_gpio_out(dev, 0, mmc_irq[0]);

    qdev_connect_gpio_out(dev, 1, mmc_irq[1]);

    sysbus_create_simple("pl031", 0x10017000, pic[10]);

    if (!is_pb) {

        dev = qdev_create(NULL, "realview_pci");

        busdev = SYS_BUS_DEVICE(dev);

        qdev_init_nofail(dev);

        sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */

        sysbus_mmio_map(busdev, 1, 0x60000000); /* PCI self-config */

        sysbus_mmio_map(busdev, 2, 0x61000000); /* PCI config */

        sysbus_mmio_map(busdev, 3, 0x62000000); /* PCI I/O */

        sysbus_mmio_map(busdev, 4, 0x63000000); /* PCI memory window 1 */

        sysbus_mmio_map(busdev, 5, 0x64000000); /* PCI memory window 2 */

        sysbus_mmio_map(busdev, 6, 0x68000000); /* PCI memory window 3 */

        sysbus_connect_irq(busdev, 0, pic[48]);

        sysbus_connect_irq(busdev, 1, pic[49]);

        sysbus_connect_irq(busdev, 2, pic[50]);

        sysbus_connect_irq(busdev, 3, pic[51]);

        pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci");

        if (usb_enabled(false)) {

            pci_create_simple(pci_bus, -1, "pci-ohci");

        }

        n = drive_get_max_bus(IF_SCSI);

        while (n >= 0) {

            pci_create_simple(pci_bus, -1, "lsi53c895a");

            n--;

        }

    }

    for(n = 0; n < nb_nics; n++) {

        nd = &nd_table[n];

        if (!done_nic && (!nd->model ||

                    strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) {

            if (is_pb) {

                lan9118_init(nd, 0x4e000000, pic[28]);

            } else {

                smc91c111_init(nd, 0x4e000000, pic[28]);

            }

            done_nic = 1;

        } else {

            if (pci_bus) {

                pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL);

            }

        }

    }

    dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL);

    i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c");

    i2c_create_slave(i2c, "ds1338", 0x68);

    /* Memory map for RealView Emulation Baseboard:  */

    /* 0x10000000 System registers.  */

    /*  0x10001000 System controller.  */

    /* 0x10002000 Two-Wire Serial Bus.  */

    /* 0x10003000 Reserved.  */

    /*  0x10004000 AACI.  */

    /*  0x10005000 MCI.  */

    /* 0x10006000 KMI0.  */

    /* 0x10007000 KMI1.  */

    /*  0x10008000 Character LCD. (EB) */

    /* 0x10009000 UART0.  */

    /* 0x1000a000 UART1.  */

    /* 0x1000b000 UART2.  */

    /* 0x1000c000 UART3.  */

    /*  0x1000d000 SSPI.  */

    /*  0x1000e000 SCI.  */

    /* 0x1000f000 Reserved.  */

    /*  0x10010000 Watchdog.  */

    /* 0x10011000 Timer 0+1.  */

    /* 0x10012000 Timer 2+3.  */

    /*  0x10013000 GPIO 0.  */

    /*  0x10014000 GPIO 1.  */

    /*  0x10015000 GPIO 2.  */

    /*  0x10002000 Two-Wire Serial Bus - DVI. (PB) */

    /* 0x10017000 RTC.  */

    /*  0x10018000 DMC.  */

    /*  0x10019000 PCI controller config.  */

    /*  0x10020000 CLCD.  */

    /* 0x10030000 DMA Controller.  */

    /* 0x10040000 GIC1. (EB) */

    /*  0x10050000 GIC2. (EB) */

    /*  0x10060000 GIC3. (EB) */

    /*  0x10070000 GIC4. (EB) */

    /*  0x10080000 SMC.  */

    /* 0x1e000000 GIC1. (PB) */

    /*  0x1e001000 GIC2. (PB) */

    /*  0x1e002000 GIC3. (PB) */

    /*  0x1e003000 GIC4. (PB) */

    /*  0x40000000 NOR flash.  */

    /*  0x44000000 DoC flash.  */

    /*  0x48000000 SRAM.  */

    /*  0x4c000000 Configuration flash.  */

    /* 0x4e000000 Ethernet.  */

    /*  0x4f000000 USB.  */

    /*  0x50000000 PISMO.  */

    /*  0x54000000 PISMO.  */

    /*  0x58000000 PISMO.  */

    /*  0x5c000000 PISMO.  */

    /* 0x60000000 PCI.  */

    /* 0x60000000 PCI Self Config.  */

    /* 0x61000000 PCI Config.  */

    /* 0x62000000 PCI IO.  */

    /* 0x63000000 PCI mem 0.  */

    /* 0x64000000 PCI mem 1.  */

    /* 0x68000000 PCI mem 2.  */

    /* ??? Hack to map an additional page of ram for the secondary CPU

       startup code.  I guess this works on real hardware because the

       BootROM happens to be in ROM/flash or in memory that isn't clobbered

       until after Linux boots the secondary CPUs.  */

    memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000,

                           &error_abort);

    vmstate_register_ram_global(ram_hack);

    memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack);

    realview_binfo.ram_size = ram_size;

    realview_binfo.kernel_filename = machine->kernel_filename;

    realview_binfo.kernel_cmdline = machine->kernel_cmdline;

    realview_binfo.initrd_filename = machine->initrd_filename;

    realview_binfo.nb_cpus = smp_cpus;

    realview_binfo.board_id = realview_board_id[board_type];

    realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0);

    arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo);

}


static void gen_tlbie(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr || !ctx->hv)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    if (NARROW_MODE(ctx)) {

        TCGv t0 = tcg_temp_new();

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

        gen_helper_tlbie(cpu_env, t0);

        tcg_temp_free(t0);

    } else {

        gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]);

    }

#endif

}


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

                                int *got_frame, AVPacket *avpkt)

{

    int buf_size       = avpkt->size;

    FlashSVContext *s  = avctx->priv_data;

    int h_blocks, v_blocks, h_part, v_part, i, j;

    GetBitContext gb;

    /* no supplementary picture */

    if (buf_size == 0)

        return 0;

    if (buf_size < 4)

        return -1;

    init_get_bits(&gb, avpkt->data, buf_size * 8);

    /* start to parse the bitstream */

    s->block_width  = 16 * (get_bits(&gb,  4) + 1);

    s->image_width  =       get_bits(&gb, 12);

    s->block_height = 16 * (get_bits(&gb,  4) + 1);

    s->image_height =       get_bits(&gb, 12);

    if (s->ver == 2) {

        skip_bits(&gb, 6);

        if (get_bits1(&gb)) {

            av_log_missing_feature(avctx, "iframe", 1);

            return AVERROR_PATCHWELCOME;

        }

        if (get_bits1(&gb)) {

            av_log_missing_feature(avctx, "Custom palette", 1);

            return AVERROR_PATCHWELCOME;

        }

    }

    /* calculate number of blocks and size of border (partial) blocks */

    h_blocks = s->image_width  / s->block_width;

    h_part   = s->image_width  % s->block_width;

    v_blocks = s->image_height / s->block_height;

    v_part   = s->image_height % s->block_height;

    /* the block size could change between frames, make sure the buffer

     * is large enough, if not, get a larger one */

    if (s->block_size < s->block_width * s->block_height) {

        int tmpblock_size = 3 * s->block_width * s->block_height;

        s->tmpblock = av_realloc(s->tmpblock, tmpblock_size);

        if (!s->tmpblock) {

            av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n");

            return AVERROR(ENOMEM);

        }

        if (s->ver == 2) {

            s->deflate_block_size = calc_deflate_block_size(tmpblock_size);

            if (s->deflate_block_size <= 0) {

                av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n");

                return -1;

            }

            s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size);

            if (!s->deflate_block) {

                av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n");

                return AVERROR(ENOMEM);

            }

        }

    }

    s->block_size = s->block_width * s->block_height;

    /* initialize the image size once */

    if (avctx->width == 0 && avctx->height == 0) {

        avcodec_set_dimensions(avctx, s->image_width, s->image_height);

    }

    /* check for changes of image width and image height */

    if (avctx->width != s->image_width || avctx->height != s->image_height) {

        av_log(avctx, AV_LOG_ERROR,

               "Frame width or height differs from first frame!\n");

        av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d  vs  ch = %d, cv = %d\n",

               avctx->height, avctx->width, s->image_height, s->image_width);

        return AVERROR_INVALIDDATA;

    }

    /* we care for keyframes only in Screen Video v2 */

    s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2);

    if (s->is_keyframe) {

        s->keyframedata = av_realloc(s->keyframedata, avpkt->size);

        memcpy(s->keyframedata, avpkt->data, avpkt->size);

    }

    if(s->ver == 2)

        s->blocks = av_realloc(s->blocks,

                                (v_blocks + !!v_part) * (h_blocks + !!h_part)

                                * sizeof(s->blocks[0]));

    av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n",

            s->image_width, s->image_height, s->block_width, s->block_height,

            h_blocks, v_blocks, h_part, v_part);

    s->frame.reference    = 3;

    s->frame.buffer_hints = FF_BUFFER_HINTS_VALID    |

                            FF_BUFFER_HINTS_PRESERVE |

                            FF_BUFFER_HINTS_REUSABLE;

    if (avctx->reget_buffer(avctx, &s->frame) < 0) {

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

        return -1;

    }

    /* loop over all block columns */

    for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) {

        int y_pos  = j * s->block_height; // vertical position in frame

        int cur_blk_height = (j < v_blocks) ? s->block_height : v_part;

        /* loop over all block rows */

        for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) {

            int x_pos = i * s->block_width; // horizontal position in frame

            int cur_blk_width = (i < h_blocks) ? s->block_width : h_part;

            int has_diff = 0;

            /* get the size of the compressed zlib chunk */

            int size = get_bits(&gb, 16);

            s->color_depth    = 0;

            s->zlibprime_curr = 0;

            s->zlibprime_prev = 0;

            s->diff_start     = 0;

            s->diff_height    = cur_blk_height;

            if (8 * size > get_bits_left(&gb)) {

                avctx->release_buffer(avctx, &s->frame);

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

                return AVERROR_INVALIDDATA;

            }

            if (s->ver == 2 && size) {

                skip_bits(&gb, 3);

                s->color_depth    = get_bits(&gb, 2);

                has_diff          = get_bits1(&gb);

                s->zlibprime_curr = get_bits1(&gb);

                s->zlibprime_prev = get_bits1(&gb);

                if (s->color_depth != 0 && s->color_depth != 2) {

                    av_log(avctx, AV_LOG_ERROR,

                           "%dx%d invalid color depth %d\n", i, j, s->color_depth);

                    return AVERROR_INVALIDDATA;

                }

                if (has_diff) {

                    if (!s->keyframe) {

                        av_log(avctx, AV_LOG_ERROR,

                               "inter frame without keyframe\n");

                        return AVERROR_INVALIDDATA;

                    }

                    s->diff_start  = get_bits(&gb, 8);

                    s->diff_height = get_bits(&gb, 8);

                    av_log(avctx, AV_LOG_DEBUG,

                           "%dx%d diff start %d height %d\n",

                           i, j, s->diff_start, s->diff_height);

                    size -= 2;

                }

                if (s->zlibprime_prev)

                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j);

                if (s->zlibprime_curr) {

                    int col = get_bits(&gb, 8);

                    int row = get_bits(&gb, 8);

                    av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row);

                    size -= 2;

                    av_log_missing_feature(avctx, "zlibprime_curr", 1);

                    return AVERROR_PATCHWELCOME;

                }

                if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) {

                    av_log(avctx, AV_LOG_ERROR, "no data available for zlib "

                           "priming\n");

                    return AVERROR_INVALIDDATA;

                }

                size--; // account for flags byte

            }

            if (has_diff) {

                int k;

                int off = (s->image_height - y_pos - 1) * s->frame.linesize[0];

                for (k = 0; k < cur_blk_height; k++)

                    memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3,

                           s->keyframe + off - k*s->frame.linesize[0] + x_pos*3,

                           cur_blk_width * 3);

            }

            /* skip unchanged blocks, which have size 0 */

            if (size) {

                if (flashsv_decode_block(avctx, avpkt, &gb, size,

                                         cur_blk_width, cur_blk_height,

                                         x_pos, y_pos,

                                         i + j * (h_blocks + !!h_part)))

                    av_log(avctx, AV_LOG_ERROR,

                           "error in decompression of block %dx%d\n", i, j);

            }

        }

    }

    if (s->is_keyframe && s->ver == 2) {

        if (!s->keyframe) {

            s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height);

            if (!s->keyframe) {

                av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n");

                return AVERROR(ENOMEM);

            }

        }

        memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height);

    }

    *got_frame = 1;

    *(AVFrame*)data = s->frame;

    if ((get_bits_count(&gb) / 8) != buf_size)

        av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n",

               buf_size, (get_bits_count(&gb) / 8));

    /* report that the buffer was completely consumed */

    return buf_size;

}


static void decode_subband(DiracContext *s, GetBitContext *gb, int quant,

                           int slice_x, int slice_y, int bits_end,

                           SubBand *b1, SubBand *b2)

{

    int left   = b1->width  * slice_x    / s->num_x;

    int right  = b1->width  *(slice_x+1) / s->num_x;

    int top    = b1->height * slice_y    / s->num_y;

    int bottom = b1->height *(slice_y+1) / s->num_y;

    int qfactor, qoffset;

    uint8_t *buf1 =      b1->ibuf + top * b1->stride;

    uint8_t *buf2 = b2 ? b2->ibuf + top * b2->stride: NULL;

    int x, y;

    if (quant > 115) {

        av_log(s->avctx, AV_LOG_ERROR, "Unsupported quant %d\n", quant);

        return;

    }

    qfactor = ff_dirac_qscale_tab[quant & 0x7f];

    qoffset = ff_dirac_qoffset_intra_tab[quant & 0x7f] + 2;

    /* we have to constantly check for overread since the spec explicitly

       requires this, with the meaning that all remaining coeffs are set to 0 */

    if (get_bits_count(gb) >= bits_end)

        return;

    if (s->pshift) {

        for (y = top; y < bottom; y++) {

            for (x = left; x < right; x++) {

                PARSE_VALUES(int32_t, x, gb, bits_end, buf1, buf2);

            }

            buf1 += b1->stride;

            if (buf2)

                buf2 += b2->stride;

        }

    }

    else {

        for (y = top; y < bottom; y++) {

            for (x = left; x < right; x++) {

                PARSE_VALUES(int16_t, x, gb, bits_end, buf1, buf2);

            }

            buf1 += b1->stride;

            if (buf2)

                buf2 += b2->stride;

        }

    }

}


void qga_vss_fsfreeze(int *nr_volume, Error **errp, bool freeze)

{

    const char *func_name = freeze ? "requester_freeze" : "requester_thaw";

    QGAVSSRequesterFunc func;

    ErrorSet errset = {

        .error_setg_win32 = error_setg_win32,

        .errp = errp,

    };

    g_assert(errp);             /* requester.cpp requires it */

    func = (QGAVSSRequesterFunc)GetProcAddress(provider_lib, func_name);

    if (!func) {

        error_setg_win32(errp, GetLastError(), "failed to load %s from %s",

                         func_name, QGA_VSS_DLL);

        return;

    }

    func(nr_volume, &errset);

}


static void do_change_block(const char *device, const char *filename)

{

    BlockDriverState *bs;

    bs = bdrv_find(device);

    if (!bs) {

        term_printf("device not found\n");

        return;

    }

    if (eject_device(bs, 0) < 0)

        return;

    bdrv_open(bs, filename, 0);

    qemu_key_check(bs, filename);

}


static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src,

                          int log2w, int log2h, int stride)

{

    const int index = size2index[log2h][log2w];

    const int h     = 1 << log2h;

    int code        = get_vlc2(&f->gb,

                               block_type_vlc[1 - (f->version > 1)][index].table,

                               BLOCK_TYPE_VLC_BITS, 1);

    uint16_t *start = (uint16_t *)f->last_picture->data[0];

    uint16_t *end   = start + stride * (f->avctx->height - h + 1) - (1 << log2w);

    int ret;

    if (code < 0 || code > 6 || log2w < 0)

        return AVERROR_INVALIDDATA;

    if (code == 0) {

        src += f->mv[bytestream2_get_byte(&f->g)];

        if (start > src || src > end) {

            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");

            return AVERROR_INVALIDDATA;

        }

        mcdc(dst, src, log2w, h, stride, 1, 0);

    } else if (code == 1) {

        log2h--;

        if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0)

            return ret;

        if ((ret = decode_p_block(f, dst + (stride << log2h),

                                  src + (stride << log2h),

                                  log2w, log2h, stride)) < 0)

            return ret;

    } else if (code == 2) {

        log2w--;

        if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0)

            return ret;

        if ((ret = decode_p_block(f, dst + (1 << log2w),

                                  src + (1 << log2w),

                                  log2w, log2h, stride)) < 0)

            return ret;

    } else if (code == 3 && f->version < 2) {

        if (start > src || src > end) {

            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");

            return AVERROR_INVALIDDATA;

        }

        mcdc(dst, src, log2w, h, stride, 1, 0);

    } else if (code == 4) {

        src += f->mv[bytestream2_get_byte(&f->g)];

        if (start > src || src > end) {

            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");

            return AVERROR_INVALIDDATA;

        }

        mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2));

    } else if (code == 5) {

        if (start > src || src > end) {

            av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");

            return AVERROR_INVALIDDATA;

        }

        mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2));

    } else if (code == 6) {

        if (log2w) {

            dst[0]      = bytestream2_get_le16(&f->g2);

            dst[1]      = bytestream2_get_le16(&f->g2);

        } else {

            dst[0]      = bytestream2_get_le16(&f->g2);

            dst[stride] = bytestream2_get_le16(&f->g2);

        }

    }

    return 0;

}


static NFSServer *nfs_config(QDict *options, Error **errp)

{

    NFSServer *server = NULL;

    QDict *addr = NULL;

    QObject *crumpled_addr = NULL;

    Visitor *iv = NULL;

    Error *local_error = NULL;

    qdict_extract_subqdict(options, &addr, "server.");

    if (!qdict_size(addr)) {

        error_setg(errp, "NFS server address missing");

        goto out;

    }

    crumpled_addr = qdict_crumple(addr, errp);

    if (!crumpled_addr) {

        goto out;

    }

    iv = qobject_input_visitor_new(crumpled_addr);

    visit_type_NFSServer(iv, NULL, &server, &local_error);

    if (local_error) {

        error_propagate(errp, local_error);

        goto out;

    }

out:

    QDECREF(addr);

    qobject_decref(crumpled_addr);

    visit_free(iv);

    return server;

}


static void gen_rfmci(DisasContext *ctx)

{

#if defined(CONFIG_USER_ONLY)

    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

#else

    if (unlikely(ctx->pr)) {

        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);

        return;

    }

    /* Restore CPU state */

    gen_helper_rfmci(cpu_env);

    gen_sync_exception(ctx);

#endif

}


static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void *dst, const int type)

{

    int i, j, count = 0;

    int last, t;

    int A, S, T;

    int pos = s->pos;

    uint32_t crc = s->sc.crc;

    uint32_t crc_extra_bits = s->extra_sc.crc;

    int16_t *dst16 = dst;

    int32_t *dst32 = dst;

    float   *dstfl = dst;

    const int channel_stride = s->avctx->channels;

    if(s->samples_left == s->samples)

        s->one = s->zero = s->zeroes = 0;

    do{

        T = wv_get_value(s, gb, 0, &last);

        S = 0;

        if(last) break;

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

            t = s->decorr[i].value;

            if(t > 8){

                if(t & 1)

                    A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1];

                else

                    A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1;

                s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0];

                j = 0;

            }else{

                A = s->decorr[i].samplesA[pos];

                j = (pos + t) & 7;

            }

            if(type != AV_SAMPLE_FMT_S16)

                S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10);

            else

                S = T + ((s->decorr[i].weightA * A + 512) >> 10);

            if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta;

            s->decorr[i].samplesA[j] = T = S;

        }

        pos = (pos + 1) & 7;

        crc = crc * 3 + S;

        if(type == AV_SAMPLE_FMT_FLT){

            *dstfl = wv_get_value_float(s, &crc_extra_bits, S);

            dstfl += channel_stride;

        }else if(type == AV_SAMPLE_FMT_S32){

            *dst32 = wv_get_value_integer(s, &crc_extra_bits, S);

            dst32 += channel_stride;

        }else{

            *dst16 = wv_get_value_integer(s, &crc_extra_bits, S);

            dst16 += channel_stride;

        }

        count++;

    }while(!last && count < s->max_samples);

    s->samples_left -= count;

    if(!s->samples_left){

        wv_reset_saved_context(s);

        if(crc != s->CRC){

            av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");

            return -1;

        }

        if(s->got_extra_bits && crc_extra_bits != s->crc_extra_bits){

            av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");

            return -1;

        }

    }else{

        s->pos = pos;

        s->sc.crc = crc;

        s->sc.bits_used = get_bits_count(&s->gb);

        if(s->got_extra_bits){

            s->extra_sc.crc = crc_extra_bits;

            s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits);

        }

    }

    return count;

}


void memory_region_transaction_commit(void)
{
    AddressSpace *as;
    assert(memory_region_transaction_depth);
    --memory_region_transaction_depth;
    if (!memory_region_transaction_depth) {
        if (memory_region_update_pending) {
            MEMORY_LISTENER_CALL_GLOBAL(begin, Forward);
            QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
                address_space_update_topology(as);
            }
            MEMORY_LISTENER_CALL_GLOBAL(commit, Forward);
        } else if (ioeventfd_update_pending) {
            QTAILQ_FOREACH(as, &address_spaces, address_spaces_link) {
                address_space_update_ioeventfds(as);
            }
        }
        memory_region_clear_pending();
   }
}


static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size)

{

    /* Estimate pending number of bytes to send */

    uint64_t pending;

    qemu_mutex_lock_iothread();

    blk_mig_lock();

    pending = get_remaining_dirty() +

                       block_mig_state.submitted * BLOCK_SIZE +

                       block_mig_state.read_done * BLOCK_SIZE;

    /* Report at least one block pending during bulk phase */

    if (pending == 0 && !block_mig_state.bulk_completed) {

        pending = BLOCK_SIZE;

    }

    blk_mig_unlock();

    qemu_mutex_unlock_iothread();

    DPRINTF("Enter save live pending  %" PRIu64 "\n", pending);

    return pending;

}


PPC_OP(cmpli)

{

    if (T0 < PARAM(1)) {

        T0 = 0x08;

    } else if (T0 > PARAM(1)) {

        T0 = 0x04;

    } else {

        T0 = 0x02;

    }

    RETURN();

}


static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix,

                                        ptrdiff_t _xstride, ptrdiff_t _ystride,

                                        int *_beta, int *_tc,

                                        uint8_t *_no_p, uint8_t *_no_q)

{

    int d, j;

    pixel *pix        = (pixel *)_pix;

    ptrdiff_t xstride = _xstride / sizeof(pixel);

    ptrdiff_t ystride = _ystride / sizeof(pixel);

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

        const int dp0  = abs(P2  - 2 * P1  + P0);

        const int dq0  = abs(Q2  - 2 * Q1  + Q0);

        const int dp3  = abs(TP2 - 2 * TP1 + TP0);

        const int dq3  = abs(TQ2 - 2 * TQ1 + TQ0);

        const int d0   = dp0 + dq0;

        const int d3   = dp3 + dq3;

        const int beta = _beta[j] << (BIT_DEPTH - 8);

        const int tc   = _tc[j]   << (BIT_DEPTH - 8);

        const int no_p = _no_p[j];

        const int no_q = _no_q[j];

        if (d0 + d3 >= beta) {

            pix += 4 * ystride;

            continue;

        } else {

            const int beta_3 = beta >> 3;

            const int beta_2 = beta >> 2;

            const int tc25   = ((tc * 5 + 1) >> 1);

            if (abs(P3  -  P0) + abs(Q3  -  Q0) < beta_3 && abs(P0  -  Q0) < tc25 &&

                abs(TP3 - TP0) + abs(TQ3 - TQ0) < beta_3 && abs(TP0 - TQ0) < tc25 &&

                                      (d0 << 1) < beta_2 &&      (d3 << 1) < beta_2) {

                // strong filtering

                const int tc2 = tc << 1;

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

                    const int p3 = P3;

                    const int p2 = P2;

                    const int p1 = P1;

                    const int p0 = P0;

                    const int q0 = Q0;

                    const int q1 = Q1;

                    const int q2 = Q2;

                    const int q3 = Q3;

                    if (!no_p) {

                        P0 = p0 + av_clip(((p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4) >> 3) - p0, -tc2, tc2);

                        P1 = p1 + av_clip(((p2 + p1 + p0 + q0 + 2) >> 2) - p1, -tc2, tc2);

                        P2 = p2 + av_clip(((2 * p3 + 3 * p2 + p1 + p0 + q0 + 4) >> 3) - p2, -tc2, tc2);

                    }

                    if (!no_q) {

                        Q0 = q0 + av_clip(((p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4) >> 3) - q0, -tc2, tc2);

                        Q1 = q1 + av_clip(((p0 + q0 + q1 + q2 + 2) >> 2) - q1, -tc2, tc2);

                        Q2 = q2 + av_clip(((2 * q3 + 3 * q2 + q1 + q0 + p0 + 4) >> 3) - q2, -tc2, tc2);

                    }

                    pix += ystride;

                }

            } else { // normal filtering

                int nd_p = 1;

                int nd_q = 1;

                const int tc_2 = tc >> 1;

                if (dp0 + dp3 < ((beta + (beta >> 1)) >> 3))

                    nd_p = 2;

                if (dq0 + dq3 < ((beta + (beta >> 1)) >> 3))

                    nd_q = 2;

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

                    const int p2 = P2;

                    const int p1 = P1;

                    const int p0 = P0;

                    const int q0 = Q0;

                    const int q1 = Q1;

                    const int q2 = Q2;

                    int delta0   = (9 * (q0 - p0) - 3 * (q1 - p1) + 8) >> 4;

                    if (abs(delta0) < 10 * tc) {

                        delta0 = av_clip(delta0, -tc, tc);

                        if (!no_p)

                            P0 = av_clip_pixel(p0 + delta0);

                        if (!no_q)

                            Q0 = av_clip_pixel(q0 - delta0);

                        if (!no_p && nd_p > 1) {

                            const int deltap1 = av_clip((((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1, -tc_2, tc_2);

                            P1 = av_clip_pixel(p1 + deltap1);

                        }

                        if (!no_q && nd_q > 1) {

                            const int deltaq1 = av_clip((((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1, -tc_2, tc_2);

                            Q1 = av_clip_pixel(q1 + deltaq1);

                        }

                    }

                    pix += ystride;

                }

            }

        }

    }

}


bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value)

{

    QObject *obj;

    obj = qdict_get(qdict, key);

    if (!obj || qobject_type(obj) != QTYPE_QBOOL)

        return def_value;

    return qbool_get_bool(qobject_to_qbool(obj));

}


static void qemu_rdma_dump_id(const char *who, struct ibv_context *verbs)

{

    struct ibv_port_attr port;

    if (ibv_query_port(verbs, 1, &port)) {

        fprintf(stderr, "FAILED TO QUERY PORT INFORMATION!\n");

        return;

    }

    printf("%s RDMA Device opened: kernel name %s "

           "uverbs device name %s, "

           "infiniband_verbs class device path %s, "

           "infiniband class device path %s, "

           "transport: (%d) %s\n",

                who,

                verbs->device->name,

                verbs->device->dev_name,

                verbs->device->dev_path,

                verbs->device->ibdev_path,

                port.link_layer,

                (port.link_layer == IBV_LINK_LAYER_INFINIBAND) ? "Infiniband" :

                 ((port.link_layer == IBV_LINK_LAYER_ETHERNET)

                    ? "Ethernet" : "Unknown"));

}


static inline void RENAME(rgb24to16)(const uint8_t *src, uint8_t *dst, long src_size)

{

	const uint8_t *s = src;

	const uint8_t *end;

#ifdef HAVE_MMX

	const uint8_t *mm_end;

#endif

	uint16_t *d = (uint16_t *)dst;

	end = s + src_size;

#ifdef HAVE_MMX

	__asm __volatile(PREFETCH"	%0"::"m"(*src):"memory");

	__asm __volatile(

	    "movq	%0, %%mm7\n\t"

	    "movq	%1, %%mm6\n\t"

	    ::"m"(red_16mask),"m"(green_16mask));

	mm_end = end - 11;

	while(s < mm_end)

	{

	    __asm __volatile(

		PREFETCH" 32%1\n\t"

		"movd	%1, %%mm0\n\t"

		"movd	3%1, %%mm3\n\t"

		"punpckldq 6%1, %%mm0\n\t"

		"punpckldq 9%1, %%mm3\n\t"

		"movq	%%mm0, %%mm1\n\t"

		"movq	%%mm0, %%mm2\n\t"

		"movq	%%mm3, %%mm4\n\t"

		"movq	%%mm3, %%mm5\n\t"

		"psrlq	$3, %%mm0\n\t"

		"psrlq	$3, %%mm3\n\t"

		"pand	%2, %%mm0\n\t"

		"pand	%2, %%mm3\n\t"

		"psrlq	$5, %%mm1\n\t"

		"psrlq	$5, %%mm4\n\t"

		"pand	%%mm6, %%mm1\n\t"

		"pand	%%mm6, %%mm4\n\t"

		"psrlq	$8, %%mm2\n\t"

		"psrlq	$8, %%mm5\n\t"

		"pand	%%mm7, %%mm2\n\t"

		"pand	%%mm7, %%mm5\n\t"

		"por	%%mm1, %%mm0\n\t"

		"por	%%mm4, %%mm3\n\t"

		"por	%%mm2, %%mm0\n\t"

		"por	%%mm5, %%mm3\n\t"

		"psllq	$16, %%mm3\n\t"

		"por	%%mm3, %%mm0\n\t"

		MOVNTQ"	%%mm0, %0\n\t"

		:"=m"(*d):"m"(*s),"m"(blue_16mask):"memory");

		d += 4;

		s += 12;

	}

	__asm __volatile(SFENCE:::"memory");

	__asm __volatile(EMMS:::"memory");

#endif

	while(s < end)

	{

		const int b= *s++;

		const int g= *s++;

		const int r= *s++;

		*d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8);

	}

}


static int mp3_read_probe(AVProbeData *p)

{

    int max_frames, first_frames = 0;

    int fsize, frames, sample_rate;

    uint32_t header;

    uint8_t *buf, *buf2, *end;

    AVCodecContext avctx;

    if(id3v2_match(p->buf))

        return AVPROBE_SCORE_MAX/2+1; // this must be less than mpeg-ps because some retards put id3v2 tags before mpeg-ps files

    max_frames = 0;

    buf = p->buf;

    end = buf + p->buf_size - sizeof(uint32_t);

    for(; buf < end; buf= buf2+1) {

        buf2 = buf;

        for(frames = 0; buf2 < end; frames++) {

            header = AV_RB32(buf2);

            fsize = ff_mpa_decode_header(&avctx, header, &sample_rate);

            if(fsize < 0)

                break;

            buf2 += fsize;

        }

        max_frames = FFMAX(max_frames, frames);

        if(buf == p->buf)

            first_frames= frames;

    }

    if   (first_frames>=3) return AVPROBE_SCORE_MAX/2+1;

    else if(max_frames>500)return AVPROBE_SCORE_MAX/2;

    else if(max_frames>=3) return AVPROBE_SCORE_MAX/4;

    else if(max_frames>=1) return 1;

    else                   return 0;

}


static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb,

                            const AVFrame *frame)

{

    const int predictor = avctx->prediction_method + 1;

    LJpegEncContext *s  = avctx->priv_data;

    const int mb_width  = (avctx->width  + s->hsample[0] - 1) / s->hsample[0];

    const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0];

    int mb_x, mb_y;

    for (mb_y = 0; mb_y < mb_height; mb_y++) {

        if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) <

            mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) {

            av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n");

            return -1;

        }

        for (mb_x = 0; mb_x < mb_width; mb_x++)

            ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y);

    }

    return 0;

}


static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial,

                                                Error **errp)

{

#ifdef HAVE_CHARDEV_TTY

    int fd;

    fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp);

    if (error_is_set(errp)) {

        return NULL;

    }

    qemu_set_nonblock(fd);

    return qemu_chr_open_tty_fd(fd);

#else

    error_setg(errp, "character device backend type 'serial' not supported");

    return NULL;

#endif

}


static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)

{

    TCGv sr_ov = tcg_temp_new();

    TCGv t0 = tcg_temp_new();

    tcg_gen_muls2_tl(dest, sr_ov, srca, srcb);

    tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1);

    tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0);

    tcg_temp_free(t0);

    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);

    gen_ove_ov(dc, sr_ov);

    tcg_temp_free(sr_ov);

}


static av_cold int ra144_decode_init(AVCodecContext * avctx)
{
    RA144Context *ractx = avctx->priv_data;
    ractx->avctx = avctx;
    ractx->lpc_coef[0] = ractx->lpc_tables[0];
    ractx->lpc_coef[1] = ractx->lpc_tables[1];
    avctx->channels       = 1;
    avctx->channel_layout = AV_CH_LAYOUT_MONO;
    avctx->sample_fmt     = AV_SAMPLE_FMT_S16;
    return 0;
}


static void rtas_start_cpu(PowerPCCPU *cpu_, sPAPRMachineState *spapr,
                           uint32_t token, uint32_t nargs,
                           target_ulong args,
                           uint32_t nret, target_ulong rets)
{
    target_ulong id, start, r3;
    PowerPCCPU *cpu;
    if (nargs != 3 || nret != 1) {
        rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
        return;
    }
    id = rtas_ld(args, 0);
    start = rtas_ld(args, 1);
    r3 = rtas_ld(args, 2);
    cpu = spapr_find_cpu(id);
    if (cpu != NULL) {
        CPUState *cs = CPU(cpu);
        CPUPPCState *env = &cpu->env;
        PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
        if (!cs->halted) {
            rtas_st(rets, 0, RTAS_OUT_HW_ERROR);
            return;
        }
        /* This will make sure qemu state is up to date with kvm, and
         * mark it dirty so our changes get flushed back before the
         * new cpu enters */
        kvm_cpu_synchronize_state(cs);
        env->msr = (1ULL << MSR_SF) | (1ULL << MSR_ME);
        env->nip = start;
        env->gpr[3] = r3;
        cs->halted = 0;
        spapr_cpu_set_endianness(cpu);
        spapr_cpu_update_tb_offset(cpu);
        qemu_cpu_kick(cs);
        rtas_st(rets, 0, RTAS_OUT_SUCCESS);
        return;
    }
    /* Didn't find a matching cpu */
    rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR);
}


void ide_flush_cache(IDEState *s)

{

    if (s->bs == NULL) {

        ide_flush_cb(s, 0);

        return;

    }

    bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH);

    bdrv_aio_flush(s->bs, ide_flush_cb, s);

}


static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler,

                                       DeviceState *plugged_dev, Error **errp)

{

    sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler));

    PCIDevice *pdev = PCI_DEVICE(plugged_dev);

    sPAPRDRConnectorClass *drck;

    sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev);

    Error *local_err = NULL;

    if (!phb->dr_enabled) {

        error_setg(errp, QERR_BUS_NO_HOTPLUG,

                   object_get_typename(OBJECT(phb)));

        return;

    }

    g_assert(drc);

    drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc);

    if (!drck->release_pending(drc)) {

        spapr_phb_remove_pci_device(drc, phb, pdev, &local_err);

        if (local_err) {

            error_propagate(errp, local_err);

            return;

        }

        spapr_hotplug_req_remove_by_index(drc);

    }

}


int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)

{

    if (bs->drv->bdrv_check == NULL) {

        return -ENOTSUP;

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

    return bs->drv->bdrv_check(bs, res, fix);


static void map_linear_vram(CirrusVGAState *s)

{

    if (!s->map_addr && s->lfb_addr && s->lfb_end) {

        s->map_addr = s->lfb_addr;

        s->map_end = s->lfb_end;

        cpu_register_physical_memory(s->map_addr, s->map_end - s->map_addr, s->vram_offset);

    }

    if (!s->map_addr)

        return;

    s->lfb_vram_mapped = 0;

    if (!(s->cirrus_srcptr != s->cirrus_srcptr_end)

        && !((s->sr[0x07] & 0x01) == 0)

        && !((s->gr[0x0B] & 0x14) == 0x14)

        && !(s->gr[0x0B] & 0x02)) {

                                    (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM);

                                    (s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM);

        s->lfb_vram_mapped = 1;

    }

    else {

        cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000,

                                     s->vga_io_memory);

    }

    vga_dirty_log_start((VGAState *)s);

}


static int alloc_tables(H264Context *h){

    MpegEncContext * const s = &h->s;

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

    int x,y;

    CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8  * sizeof(uint8_t))

    CHECKED_ALLOCZ(h->non_zero_count    , big_mb_num * 16 * sizeof(uint8_t))

    CHECKED_ALLOCZ(h->slice_table_base  , (big_mb_num+s->mb_stride) * sizeof(uint8_t))

    CHECKED_ALLOCZ(h->cbp_table, big_mb_num * sizeof(uint16_t))

    if( h->pps.cabac ) {

        CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t))

        CHECKED_ALLOCZ(h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t));

        CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t));

        CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t));

    }

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

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

    CHECKED_ALLOCZ(h->mb2b_xy  , big_mb_num * sizeof(uint32_t));

    CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint32_t));

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

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

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

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

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

            h->mb2b_xy [mb_xy]= b_xy;

            h->mb2b8_xy[mb_xy]= b8_xy;

        }

    }

    s->obmc_scratchpad = NULL;

    if(!h->dequant4_coeff[0])

        init_dequant_tables(h);

    return 0;

fail:

    free_tables(h);

    return -1;

}


static void RENAME(swScale)(SwsContext *c, uint8_t* srcParam[], int srcStrideParam[], int srcSliceY,

             int srcSliceH, uint8_t* dstParam[], int dstStrideParam[]){

	/* load a few things into local vars to make the code more readable? and faster */

	const int srcW= c->srcW;

	const int dstW= c->dstW;

	const int dstH= c->dstH;

	const int chrDstW= c->chrDstW;

	const int lumXInc= c->lumXInc;

	const int chrXInc= c->chrXInc;

	const int dstFormat= c->dstFormat;

	const int flags= c->flags;

	const int canMMX2BeUsed= c->canMMX2BeUsed;

	int16_t *vLumFilterPos= c->vLumFilterPos;

	int16_t *vChrFilterPos= c->vChrFilterPos;

	int16_t *hLumFilterPos= c->hLumFilterPos;

	int16_t *hChrFilterPos= c->hChrFilterPos;

	int16_t *vLumFilter= c->vLumFilter;

	int16_t *vChrFilter= c->vChrFilter;

	int16_t *hLumFilter= c->hLumFilter;

	int16_t *hChrFilter= c->hChrFilter;

	int16_t *lumMmxFilter= c->lumMmxFilter;

	int16_t *chrMmxFilter= c->chrMmxFilter;

	const int vLumFilterSize= c->vLumFilterSize;

	const int vChrFilterSize= c->vChrFilterSize;

	const int hLumFilterSize= c->hLumFilterSize;

	const int hChrFilterSize= c->hChrFilterSize;

	int16_t **lumPixBuf= c->lumPixBuf;

	int16_t **chrPixBuf= c->chrPixBuf;

	const int vLumBufSize= c->vLumBufSize;

	const int vChrBufSize= c->vChrBufSize;

	uint8_t *funnyYCode= c->funnyYCode;

	uint8_t *funnyUVCode= c->funnyUVCode;

	uint8_t *formatConvBuffer= c->formatConvBuffer;

	/* vars whch will change and which we need to storw back in the context */

	int dstY= c->dstY;

	int lumBufIndex= c->lumBufIndex;

	int chrBufIndex= c->chrBufIndex;

	int lastInLumBuf= c->lastInLumBuf;

	int lastInChrBuf= c->lastInChrBuf;

	int srcStride[3];

	int dstStride[3];

	uint8_t *src[3];

	uint8_t *dst[3];

	if(c->srcFormat == IMGFMT_I420){

		src[0]= srcParam[0];

		src[1]= srcParam[2];

		src[2]= srcParam[1];

		srcStride[0]= srcStrideParam[0];

		srcStride[1]= srcStrideParam[2];

		srcStride[2]= srcStrideParam[1];

	}

	else if(c->srcFormat==IMGFMT_YV12){

		src[0]= srcParam[0];

		src[1]= srcParam[1];

		src[2]= srcParam[2];

		srcStride[0]= srcStrideParam[0];

		srcStride[1]= srcStrideParam[1];

		srcStride[2]= srcStrideParam[2];

	}

	else if(isPacked(c->srcFormat)){

		src[0]=

		src[1]=

		src[2]= srcParam[0];

		srcStride[0]= srcStrideParam[0];

		srcStride[1]=

		srcStride[2]= srcStrideParam[0]<<1;

	}

	else if(isGray(c->srcFormat)){

		src[0]= srcParam[0];

		src[1]=

		src[2]= NULL;

		srcStride[0]= srcStrideParam[0];

		srcStride[1]=

		srcStride[2]= 0;

	}

	if(dstFormat == IMGFMT_I420){

		dst[0]= dstParam[0];

		dst[1]= dstParam[2];

		dst[2]= dstParam[1];

		dstStride[0]= dstStrideParam[0];

		dstStride[1]= dstStrideParam[2];

		dstStride[2]= dstStrideParam[1];

	}else{

		dst[0]= dstParam[0];

		dst[1]= dstParam[1];

		dst[2]= dstParam[2];

		dstStride[0]= dstStrideParam[0];

		dstStride[1]= dstStrideParam[1];

		dstStride[2]= dstStrideParam[2];

	}

//printf("sws Strides:%d %d %d -> %d %d %d\n", srcStride[0],srcStride[1],srcStride[2],

//dstStride[0],dstStride[1],dstStride[2]);

	if(dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0)

	{

		static int firstTime=1; //FIXME move this into the context perhaps

		if(flags & SWS_PRINT_INFO && firstTime)

		{

			fprintf(stderr, "SwScaler: Warning: dstStride is not aligned!\n"

					"SwScaler:          ->cannot do aligned memory acesses anymore\n");

			firstTime=0;

		}

	}

	/* Note the user might start scaling the picture in the middle so this will not get executed

	   this is not really intended but works currently, so ppl might do it */

	if(srcSliceY ==0){

		lumBufIndex=0;

		chrBufIndex=0;

		dstY=0;

		lastInLumBuf= -1;

		lastInChrBuf= -1;

	}

	for(;dstY < dstH; dstY++){

		unsigned char *dest =dst[0]+dstStride[0]*dstY;

		unsigned char *uDest=dst[1]+dstStride[1]*(dstY>>1);

		unsigned char *vDest=dst[2]+dstStride[2]*(dstY>>1);

		const int chrDstY= isHalfChrV(dstFormat) ? (dstY>>1) : dstY;

		const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input

		const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input

		const int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input

		const int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input

		//handle holes (FAST_BILINEAR & weird filters)

		if(firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1;

		if(firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1;

//printf("%d %d %d\n", firstChrSrcY, lastInChrBuf, vChrBufSize);

		ASSERT(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1)

		ASSERT(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1)

		// Do we have enough lines in this slice to output the dstY line

		if(lastLumSrcY < srcSliceY + srcSliceH && lastChrSrcY < ((srcSliceY + srcSliceH + 1)>>1))

		{

			//Do horizontal scaling

			while(lastInLumBuf < lastLumSrcY)

			{

				uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];

				lumBufIndex++;

//				printf("%d %d %d %d\n", lumBufIndex, vLumBufSize, lastInLumBuf,  lastLumSrcY);

				ASSERT(lumBufIndex < 2*vLumBufSize)

				ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH)

				ASSERT(lastInLumBuf + 1 - srcSliceY >= 0)

//				printf("%d %d\n", lumBufIndex, vLumBufSize);

				RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc,

						flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize,

						funnyYCode, c->srcFormat, formatConvBuffer);

				lastInLumBuf++;

			}

			while(lastInChrBuf < lastChrSrcY)

			{

				uint8_t *src1= src[1]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[1];

				uint8_t *src2= src[2]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[2];

				chrBufIndex++;

				ASSERT(chrBufIndex < 2*vChrBufSize)

				ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) < ((srcSliceH+1)>>1))

				ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) >= 0)

				//FIXME replace parameters through context struct (some at least)

				RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc,

						flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize,

						funnyUVCode, c->srcFormat, formatConvBuffer);

				lastInChrBuf++;

			}

			//wrap buf index around to stay inside the ring buffer

			if(lumBufIndex >= vLumBufSize ) lumBufIndex-= vLumBufSize;

			if(chrBufIndex >= vChrBufSize ) chrBufIndex-= vChrBufSize;

		}

		else // not enough lines left in this slice -> load the rest in the buffer

		{

/*		printf("%d %d Last:%d %d LastInBuf:%d %d Index:%d %d Y:%d FSize: %d %d BSize: %d %d\n",

			firstChrSrcY,firstLumSrcY,lastChrSrcY,lastLumSrcY,

			lastInChrBuf,lastInLumBuf,chrBufIndex,lumBufIndex,dstY,vChrFilterSize,vLumFilterSize,

			vChrBufSize, vLumBufSize);

*/

			//Do horizontal scaling

			while(lastInLumBuf+1 < srcSliceY + srcSliceH)

			{

				uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0];

				lumBufIndex++;

				ASSERT(lumBufIndex < 2*vLumBufSize)

				ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH)

				ASSERT(lastInLumBuf + 1 - srcSliceY >= 0)

				RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc,

						flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize,

						funnyYCode, c->srcFormat, formatConvBuffer);

				lastInLumBuf++;

			}

			while(lastInChrBuf+1 < ((srcSliceY + srcSliceH)>>1))

			{

				uint8_t *src1= src[1]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[1];

				uint8_t *src2= src[2]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[2];

				chrBufIndex++;

				ASSERT(chrBufIndex < 2*vChrBufSize)

				ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) < ((srcSliceH+1)>>1))

				ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) >= 0)

				RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc,

						flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize,

						funnyUVCode, c->srcFormat, formatConvBuffer);

				lastInChrBuf++;

			}

			//wrap buf index around to stay inside the ring buffer

			if(lumBufIndex >= vLumBufSize ) lumBufIndex-= vLumBufSize;

			if(chrBufIndex >= vChrBufSize ) chrBufIndex-= vChrBufSize;

			break; //we cant output a dstY line so lets try with the next slice

		}

#ifdef HAVE_MMX

		b5Dither= dither8[dstY&1];

		g6Dither= dither4[dstY&1];

		g5Dither= dither8[dstY&1];

		r5Dither= dither8[(dstY+1)&1];

#endif

	    if(dstY < dstH-2)

	    {

		if(isPlanarYUV(dstFormat)) //YV12 like

		{

			if(dstY&1) uDest=vDest= NULL; //FIXME split functions in lumi / chromi

			if(vLumFilterSize == 1 && vChrFilterSize == 1) // Unscaled YV12

			{

				int16_t *lumBuf = lumPixBuf[0];

				int16_t *chrBuf= chrPixBuf[0];

				RENAME(yuv2yuv1)(lumBuf, chrBuf, dest, uDest, vDest, dstW);

			}

			else //General YV12

			{

				int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;

				int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;

				RENAME(yuv2yuvX)(

					vLumFilter+dstY*vLumFilterSize     , lumSrcPtr, vLumFilterSize,

					vChrFilter+(dstY>>1)*vChrFilterSize, chrSrcPtr, vChrFilterSize,

					dest, uDest, vDest, dstW,

					lumMmxFilter+dstY*vLumFilterSize*4, chrMmxFilter+(dstY>>1)*vChrFilterSize*4);

			}

		}

		else

		{

			int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;

			int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;

			ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);

			ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);

			if(vLumFilterSize == 1 && vChrFilterSize == 2) //Unscaled RGB

			{

				int chrAlpha= vChrFilter[2*dstY+1];

				RENAME(yuv2rgb1)(*lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1),

						 dest, dstW, chrAlpha, dstFormat, flags);

			}

			else if(vLumFilterSize == 2 && vChrFilterSize == 2) //BiLinear Upscale RGB

			{

				int lumAlpha= vLumFilter[2*dstY+1];

				int chrAlpha= vChrFilter[2*dstY+1];

				RENAME(yuv2rgb2)(*lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1),

						 dest, dstW, lumAlpha, chrAlpha, dstFormat, flags);

			}

			else //General RGB

			{

				RENAME(yuv2rgbX)(

					vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,

					vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,

					dest, dstW, dstFormat,

					lumMmxFilter+dstY*vLumFilterSize*4, chrMmxFilter+dstY*vChrFilterSize*4);

			}

		}

            }

	    else // hmm looks like we cant use MMX here without overwriting this arrays tail

	    {

		int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize;

		int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize;

		if(isPlanarYUV(dstFormat)) //YV12

		{

			if(dstY&1) uDest=vDest= NULL; //FIXME split functions in lumi / chromi

			yuv2yuvXinC(

				vLumFilter+dstY*vLumFilterSize     , lumSrcPtr, vLumFilterSize,

				vChrFilter+(dstY>>1)*vChrFilterSize, chrSrcPtr, vChrFilterSize,

				dest, uDest, vDest, dstW);

		}

		else

		{

			ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2);

			ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2);

			yuv2rgbXinC(

				vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize,

				vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize,

				dest, dstW, dstFormat);

		}

	    }

	}

#ifdef HAVE_MMX

	__asm __volatile(SFENCE:::"memory");

	__asm __volatile(EMMS:::"memory");

#endif

	/* store changed local vars back in the context */

	c->dstY= dstY;

	c->lumBufIndex= lumBufIndex;

	c->chrBufIndex= chrBufIndex;

	c->lastInLumBuf= lastInLumBuf;

	c->lastInChrBuf= lastInChrBuf;

}


static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
                                   Error **errp)
{
    const char *buf;
    int bdrv_flags = 0;
    int on_read_error, on_write_error;
    bool account_invalid, account_failed;
    BlockBackend *blk;
    BlockDriverState *bs;
    ThrottleConfig cfg;
    int snapshot = 0;
    Error *error = NULL;
    QemuOpts *opts;
    const char *id;
    bool has_driver_specific_opts;
    BlockdevDetectZeroesOptions detect_zeroes =
        BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
    const char *throttling_group = NULL;
    /* Check common options by copying from bs_opts to opts, all other options
     * stay in bs_opts for processing by bdrv_open(). */
    id = qdict_get_try_str(bs_opts, "id");
    opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error);
    if (error) {
        error_propagate(errp, error);
        goto err_no_opts;
    }
    qemu_opts_absorb_qdict(opts, bs_opts, &error);
    if (error) {
        error_propagate(errp, error);
        goto early_err;
    }
    if (id) {
        qdict_del(bs_opts, "id");
    }
    has_driver_specific_opts = !!qdict_size(bs_opts);
    /* extract parameters */
    snapshot = qemu_opt_get_bool(opts, "snapshot", 0);
    extract_common_blockdev_options(opts, &bdrv_flags, &throttling_group, &cfg,
                                    &detect_zeroes, &error);
    if (error) {
        error_propagate(errp, error);
        goto early_err;
    }
    if ((buf = qemu_opt_get(opts, "format")) != NULL) {
        if (is_help_option(buf)) {
            error_printf("Supported formats:");
            bdrv_iterate_format(bdrv_format_print, NULL);
            error_printf("\n");
            goto early_err;
        }
        if (qdict_haskey(bs_opts, "driver")) {
            error_setg(errp, "Cannot specify both 'driver' and 'format'");
            goto early_err;
        }
        qdict_put(bs_opts, "driver", qstring_from_str(buf));
    }
    on_write_error = BLOCKDEV_ON_ERROR_ENOSPC;
    if ((buf = qemu_opt_get(opts, "werror")) != NULL) {
        on_write_error = parse_block_error_action(buf, 0, &error);
        if (error) {
            error_propagate(errp, error);
            goto early_err;
        }
    }
    on_read_error = BLOCKDEV_ON_ERROR_REPORT;
    if ((buf = qemu_opt_get(opts, "rerror")) != NULL) {
        on_read_error = parse_block_error_action(buf, 1, &error);
        if (error) {
            error_propagate(errp, error);
            goto early_err;
        }
    }
    if (snapshot) {
        /* always use cache=unsafe with snapshot */
        bdrv_flags &= ~BDRV_O_CACHE_MASK;
        bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
    }
    /* init */
    if ((!file || !*file) && !has_driver_specific_opts) {
        BlockBackendRootState *blk_rs;
        blk = blk_new(qemu_opts_id(opts), errp);
        if (!blk) {
            goto early_err;
        }
        blk_rs = blk_get_root_state(blk);
        blk_rs->open_flags    = bdrv_flags;
        blk_rs->read_only     = !(bdrv_flags & BDRV_O_RDWR);
        blk_rs->detect_zeroes = detect_zeroes;
        if (throttle_enabled(&cfg)) {
            if (!throttling_group) {
                throttling_group = blk_name(blk);
            }
            blk_rs->throttle_group = g_strdup(throttling_group);
            blk_rs->throttle_state = throttle_group_incref(throttling_group);
            blk_rs->throttle_state->cfg = cfg;
        }
        QDECREF(bs_opts);
    } else {
        if (file && !*file) {
            file = NULL;
        }
        blk = blk_new_open(qemu_opts_id(opts), file, NULL, bs_opts, bdrv_flags,
                           errp);
        if (!blk) {
            goto err_no_bs_opts;
        }
        bs = blk_bs(blk);
        bs->detect_zeroes = detect_zeroes;
        /* disk I/O throttling */
        if (throttle_enabled(&cfg)) {
            if (!throttling_group) {
                throttling_group = blk_name(blk);
            }
            bdrv_io_limits_enable(bs, throttling_group);
            bdrv_set_io_limits(bs, &cfg);
        }
        if (bdrv_key_required(bs)) {
            autostart = 0;
        }
        block_acct_init(blk_get_stats(blk), account_invalid, account_failed);
    }
    blk_set_on_error(blk, on_read_error, on_write_error);
err_no_bs_opts:
    qemu_opts_del(opts);
    return blk;
early_err:
    qemu_opts_del(opts);
err_no_opts:
    QDECREF(bs_opts);
    return NULL;
}


static void escc_mem_write(void *opaque, hwaddr addr,

                           uint64_t val, unsigned size)

{

    ESCCState *serial = opaque;

    ChannelState *s;

    uint32_t saddr;

    int newreg, channel;

    val &= 0xff;

    saddr = (addr >> serial->it_shift) & 1;

    channel = (addr >> (serial->it_shift + 1)) & 1;

    s = &serial->chn[channel];

    switch (saddr) {

    case SERIAL_CTRL:

        trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff);

        newreg = 0;

        switch (s->reg) {

        case W_CMD:

            newreg = val & CMD_PTR_MASK;

            val &= CMD_CMD_MASK;

            switch (val) {

            case CMD_HI:

                newreg |= CMD_HI;

                break;

            case CMD_CLR_TXINT:

                clr_txint(s);

                break;

            case CMD_CLR_IUS:

                if (s->rxint_under_svc) {

                    s->rxint_under_svc = 0;

                    if (s->txint) {

                        set_txint(s);

                    }

                } else if (s->txint_under_svc) {

                    s->txint_under_svc = 0;

                }

                escc_update_irq(s);

                break;

            default:

                break;

            }

            break;

        case W_INTR ... W_RXCTRL:

        case W_SYNC1 ... W_TXBUF:

        case W_MISC1 ... W_CLOCK:

        case W_MISC2 ... W_EXTINT:

            s->wregs[s->reg] = val;

            break;

        case W_TXCTRL1:

        case W_TXCTRL2:

            s->wregs[s->reg] = val;

            escc_update_parameters(s);

            break;

        case W_BRGLO:

        case W_BRGHI:

            s->wregs[s->reg] = val;

            s->rregs[s->reg] = val;

            escc_update_parameters(s);

            break;

        case W_MINTR:

            switch (val & MINTR_RST_MASK) {

            case 0:

            default:

                break;

            case MINTR_RST_B:

                escc_reset_chn(&serial->chn[0]);

                return;

            case MINTR_RST_A:

                escc_reset_chn(&serial->chn[1]);

                return;

            case MINTR_RST_ALL:

                escc_reset(DEVICE(serial));

                return;

            }

            break;

        default:

            break;

        }

        if (s->reg == 0)

            s->reg = newreg;

        else

            s->reg = 0;

        break;

    case SERIAL_DATA:

        trace_escc_mem_writeb_data(CHN_C(s), val);

        s->tx = val;

        if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled

            if (s->chr)

                qemu_chr_fe_write(s->chr, &s->tx, 1);

            else if (s->type == kbd && !s->disabled) {

                handle_kbd_command(s, val);

            }

        }

        s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty

        s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent

        set_txint(s);

        break;

    default:

        break;

    }

}


static int vmdaudio_decode_init(AVCodecContext *avctx)

{

    VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;

    int i;

    s->channels = avctx->channels;

    s->bits = avctx->bits_per_sample;

    s->block_align = avctx->block_align;

printf ("  %d channels, %d bits/sample, block align = %d\n",

  s->channels, s->bits, s->block_align);

    /* set up the steps8 and steps16 tables */

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

        if (i < 4)

            s->steps8[i] = i;

        else

            s->steps8[i] = s->steps8[i - 1] + i - 1;

        if (i == 0)

            s->steps16[i] = 0;

        else if (i == 1)

            s->steps16[i] = 4;

        else if (i == 2)

            s->steps16[i] = 16;

        else

            s->steps16[i] = 1 << (i + 4);

    }

    /* set up the step128 table */

    s->steps128[0] = 0;

    s->steps128[1] = 8;

    for (i = 0x02; i <= 0x20; i++)

        s->steps128[i] = (i - 1) << 4;

    for (i = 0x21; i <= 0x60; i++)

        s->steps128[i] = (i + 0x1F) << 3;

    for (i = 0x61; i <= 0x70; i++)

        s->steps128[i] = (i - 0x51) << 6;

    for (i = 0x71; i <= 0x78; i++)

        s->steps128[i] = (i - 0x69) << 8;

    for (i = 0x79; i <= 0x7D; i++)

        s->steps128[i] = (i - 0x75) << 10;

    s->steps128[0x7E] = 0x3000;

    s->steps128[0x7F] = 0x4000;

    /* set up the negative half of each table */

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

        s->steps8[i + 8] = -s->steps8[i];

        s->steps16[i + 8] = -s->steps16[i];

    }

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

      s->steps128[i + 128] = -s->steps128[i];

    return 0;

}


static int adb_kbd_request(ADBDevice *d, uint8_t *obuf,

                           const uint8_t *buf, int len)

{

    KBDState *s = ADB_KEYBOARD(d);

    int cmd, reg, olen;

    if ((buf[0] & 0x0f) == ADB_FLUSH) {

        /* flush keyboard fifo */

        s->wptr = s->rptr = s->count = 0;

        return 0;

    }

    cmd = buf[0] & 0xc;

    reg = buf[0] & 0x3;

    olen = 0;

    switch(cmd) {

    case ADB_WRITEREG:

        switch(reg) {

        case 2:

            /* LED status */

            break;

        case 3:

            switch(buf[2]) {

            case ADB_CMD_SELF_TEST:

                break;

            case ADB_CMD_CHANGE_ID:

            case ADB_CMD_CHANGE_ID_AND_ACT:

            case ADB_CMD_CHANGE_ID_AND_ENABLE:

                d->devaddr = buf[1] & 0xf;

                break;

            default:

                d->devaddr = buf[1] & 0xf;

                /* we support handlers:

                 * 1: Apple Standard Keyboard

                 * 2: Apple Extended Keyboard (LShift = RShift)

                 * 3: Apple Extended Keyboard (LShift != RShift)

                 */

                if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) {

                    d->handler = buf[2];

                }

                break;

            }

        }

        break;

    case ADB_READREG:

        switch(reg) {

        case 0:

            olen = adb_kbd_poll(d, obuf);

            break;

        case 1:

            break;

        case 2:

            obuf[0] = 0x00; /* XXX: check this */

            obuf[1] = 0x07; /* led status */

            olen = 2;

            break;

        case 3:

            obuf[0] = d->handler;

            obuf[1] = d->devaddr;

            olen = 2;

            break;

        }

        break;

    }

    return olen;

}


static int decode_slice(AVCodecContext *c, void *arg)

{

    FFV1Context *fs   = *(void **)arg;

    FFV1Context *f    = fs->avctx->priv_data;

    int width, height, x, y, ret;

    const int ps      = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step;

    AVFrame * const p = f->cur;

    int i, si;

    for( si=0; fs != f->slice_context[si]; si ++)

        ;

    if(f->fsrc && !p->key_frame)

        ff_thread_await_progress(&f->last_picture, si, 0);

    if(f->fsrc && !p->key_frame) {

        FFV1Context *fssrc = f->fsrc->slice_context[si];

        FFV1Context *fsdst = f->slice_context[si];

        av_assert1(fsdst->plane_count == fssrc->plane_count);

        av_assert1(fsdst == fs);

        if (!p->key_frame)

            fsdst->slice_damaged |= fssrc->slice_damaged;

        for (i = 0; i < f->plane_count; i++) {

            PlaneContext *psrc = &fssrc->plane[i];

            PlaneContext *pdst = &fsdst->plane[i];

            av_free(pdst->state);

            av_free(pdst->vlc_state);

            memcpy(pdst, psrc, sizeof(*pdst));

            pdst->state = NULL;

            pdst->vlc_state = NULL;

            if (fssrc->ac) {

                pdst->state = av_malloc_array(CONTEXT_SIZE,  psrc->context_count);

                memcpy(pdst->state, psrc->state, CONTEXT_SIZE * psrc->context_count);

            } else {

                pdst->vlc_state = av_malloc_array(sizeof(*pdst->vlc_state), psrc->context_count);

                memcpy(pdst->vlc_state, psrc->vlc_state, sizeof(*pdst->vlc_state) * psrc->context_count);

            }

        }

    }

    fs->slice_rct_by_coef = 1;

    fs->slice_rct_ry_coef = 1;

    if (f->version > 2) {

        if (ff_ffv1_init_slice_state(f, fs) < 0)

            return AVERROR(ENOMEM);

        if (decode_slice_header(f, fs) < 0) {

            fs->slice_damaged = 1;

            return AVERROR_INVALIDDATA;

        }

    }

    if ((ret = ff_ffv1_init_slice_state(f, fs)) < 0)

        return ret;

    if (f->cur->key_frame || fs->slice_reset_contexts)

        ff_ffv1_clear_slice_state(f, fs);

    width  = fs->slice_width;

    height = fs->slice_height;

    x      = fs->slice_x;

    y      = fs->slice_y;

    if (!fs->ac) {

        if (f->version == 3 && f->micro_version > 1 || f->version > 3)

            get_rac(&fs->c, (uint8_t[]) { 129 });

        fs->ac_byte_count = f->version > 2 || (!x && !y) ? fs->c.bytestream - fs->c.bytestream_start - 1 : 0;

        init_get_bits(&fs->gb,

                      fs->c.bytestream_start + fs->ac_byte_count,

                      (fs->c.bytestream_end - fs->c.bytestream_start - fs->ac_byte_count) * 8);

    }

    av_assert1(width && height);

    if (f->colorspace == 0) {

        const int chroma_width  = FF_CEIL_RSHIFT(width,  f->chroma_h_shift);

        const int chroma_height = FF_CEIL_RSHIFT(height, f->chroma_v_shift);

        const int cx            = x >> f->chroma_h_shift;

        const int cy            = y >> f->chroma_v_shift;

        decode_plane(fs, p->data[0] + ps*x + y*p->linesize[0], width, height, p->linesize[0], 0);

        if (f->chroma_planes) {

            decode_plane(fs, p->data[1] + ps*cx+cy*p->linesize[1], chroma_width, chroma_height, p->linesize[1], 1);

            decode_plane(fs, p->data[2] + ps*cx+cy*p->linesize[2], chroma_width, chroma_height, p->linesize[2], 1);

        }

        if (fs->transparency)

            decode_plane(fs, p->data[3] + ps*x + y*p->linesize[3], width, height, p->linesize[3], (f->version >= 4 && !f->chroma_planes) ? 1 : 2);

    } else {

        uint8_t *planes[3] = { p->data[0] + ps * x + y * p->linesize[0],

                               p->data[1] + ps * x + y * p->linesize[1],

                               p->data[2] + ps * x + y * p->linesize[2] };

        decode_rgb_frame(fs, planes, width, height, p->linesize);

    }

    if (fs->ac && f->version > 2) {

        int v;

        get_rac(&fs->c, (uint8_t[]) { 129 });

        v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*f->ec;

        if (v) {

            av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v);

            fs->slice_damaged = 1;

        }

    }

    emms_c();

    ff_thread_report_progress(&f->picture, si, 0);

    return 0;

}


static av_cold int bmv_aud_decode_init(AVCodecContext *avctx)

{

    BMVAudioDecContext *c = avctx->priv_data;

    if (avctx->channels != 2) {

        av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");

        return AVERROR(EINVAL);

    }

    avctx->sample_fmt = AV_SAMPLE_FMT_S16;

    avcodec_get_frame_defaults(&c->frame);

    avctx->coded_frame = &c->frame;

    return 0;

}


static int cdrom_open(BlockDriverState *bs, QDict *options, int flags,

                      Error **errp)

{

    BDRVRawState *s = bs->opaque;

    int ret;

    s->type = FTYPE_CD;

    /* open will not fail even if no CD is inserted, so add O_NONBLOCK */

    ret = raw_open_common(bs, options, flags, O_NONBLOCK, errp);

    return ret;

}


void imx_serial_create(int uart, const target_phys_addr_t addr, qemu_irq irq)

{

    DeviceState *dev;

    SysBusDevice *bus;

    CharDriverState *chr;

    const char chr_name[] = "serial";

    char label[ARRAY_SIZE(chr_name) + 1];

    dev = qdev_create(NULL, "imx-serial");

    if (uart >= MAX_SERIAL_PORTS) {

        hw_error("Cannot assign uart %d: QEMU supports only %d ports\n",

                 uart, MAX_SERIAL_PORTS);

    }

    chr = serial_hds[uart];

    if (!chr) {

        snprintf(label, ARRAY_SIZE(label), "%s%d", chr_name, uart);

        chr = qemu_chr_new(label, "null", NULL);

        if (!(chr)) {

            hw_error("Can't assign serial port to imx-uart%d.\n", uart);

        }

    }

    qdev_prop_set_chr(dev, "chardev", chr);

    bus = sysbus_from_qdev(dev);

    qdev_init_nofail(dev);

    if (addr != (target_phys_addr_t)-1) {

        sysbus_mmio_map(bus, 0, addr);

    }

    sysbus_connect_irq(bus, 0, irq);

}


static KVMMSIRoute *kvm_lookup_msi_route(KVMState *s, MSIMessage msg)

{

    unsigned int hash = kvm_hash_msi(msg.data);

    KVMMSIRoute *route;

    QTAILQ_FOREACH(route, &s->msi_hashtab[hash], entry) {

        if (route->kroute.u.msi.address_lo == (uint32_t)msg.address &&

            route->kroute.u.msi.address_hi == (msg.address >> 32) &&

            route->kroute.u.msi.data == msg.data) {

            return route;

        }

    }

    return NULL;

}


static int pxb_bus_num(PCIBus *bus)

{

    PXBDev *pxb = PXB_DEV(bus->parent_dev);

    return pxb->bus_nr;

}


static void dec_user(DisasContext *dc)

{

    LOG_DIS("user");

    cpu_abort(dc->env, "user insn undefined\n");

}


target_ulong helper_load_slb_esid(CPUPPCState *env, target_ulong rb)

{

    target_ulong rt;

    if (ppc_load_slb_esid(env, rb, &rt) < 0) {

        helper_raise_exception_err(env, POWERPC_EXCP_PROGRAM,

                                   POWERPC_EXCP_INVAL);

    }

    return rt;

}


void hmp_pci_del(Monitor *mon, const QDict *qdict)

{

    pci_device_hot_remove(mon, qdict_get_str(qdict, "pci_addr"));

}


QEMUPutMouseEntry *qemu_add_mouse_event_handler(QEMUPutMouseEvent *func,

                                                void *opaque, int absolute,

                                                const char *name)

{

    QEMUPutMouseEntry *s;

    s = g_malloc0(sizeof(QEMUPutMouseEntry));

    s->qemu_put_mouse_event = func;

    s->qemu_put_mouse_event_opaque = opaque;

    s->qemu_put_mouse_event_absolute = absolute;

    s->h.name = name;

    s->h.mask = INPUT_EVENT_MASK_BTN |

        (absolute ? INPUT_EVENT_MASK_ABS : INPUT_EVENT_MASK_REL);

    s->h.event = legacy_mouse_event;

    s->h.sync = legacy_mouse_sync;

    s->s = qemu_input_handler_register((DeviceState *)s,

                                       &s->h);

    return s;

}


static int build_filter(ResampleContext *c, void *filter, double factor, int tap_count, int alloc, int phase_count, int scale,

                        int filter_type, double kaiser_beta){

    int ph, i;

    double x, y, w, t, s;

    double *tab = av_malloc_array(tap_count+1,  sizeof(*tab));

    double *sin_lut = av_malloc_array(phase_count / 2 + 1, sizeof(*sin_lut));

    const int center= (tap_count-1)/2;

    if (!tab || !sin_lut)

        goto fail;

    /* if upsampling, only need to interpolate, no filter */

    if (factor > 1.0)

        factor = 1.0;

    av_assert0(phase_count == 1 || phase_count % 2 == 0);

    if (factor == 1.0) {

        for (ph = 0; ph <= phase_count / 2; ph++)

            sin_lut[ph] = sin(M_PI * ph / phase_count);

    }

    for(ph = 0; ph <= phase_count / 2; ph++) {

        double norm = 0;

        s = sin_lut[ph];

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

            x = M_PI * ((double)(i - center) - (double)ph / phase_count) * factor;

            if (x == 0) y = 1.0;

            else if (factor == 1.0)

                y = s / x;

            else

                y = sin(x) / x;

            switch(filter_type){

            case SWR_FILTER_TYPE_CUBIC:{

                const float d= -0.5; //first order derivative = -0.5

                x = fabs(((double)(i - center) - (double)ph / phase_count) * factor);

                if(x<1.0) y= 1 - 3*x*x + 2*x*x*x + d*(            -x*x + x*x*x);

                else      y=                       d*(-4 + 8*x - 5*x*x + x*x*x);

                break;}

            case SWR_FILTER_TYPE_BLACKMAN_NUTTALL:

                w = 2.0*x / (factor*tap_count);

                t = -cos(w);

                y *= 0.3635819 - 0.4891775 * t + 0.1365995 * (2*t*t-1) - 0.0106411 * (4*t*t*t - 3*t);

                break;

            case SWR_FILTER_TYPE_KAISER:

                w = 2.0*x / (factor*tap_count*M_PI);

                y *= bessel(kaiser_beta*sqrt(FFMAX(1-w*w, 0)));

                break;

            default:

                av_assert0(0);

            }

            tab[i] = y;

            s = -s;

            if (i < tap_count)

                norm += y;

        }

        /* normalize so that an uniform color remains the same */

        switch(c->format){

        case AV_SAMPLE_FMT_S16P:

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

                ((int16_t*)filter)[ph * alloc + i] = av_clip_int16(lrintf(tab[i] * scale / norm));

            if (tap_count % 2 == 0) {

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

                    ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int16_t*)filter)[ph * alloc + i];

            }

            else {

                for (i = 1; i <= tap_count; i++)

                    ((int16_t*)filter)[(phase_count-ph) * alloc + tap_count-i] =

                        av_clip_int16(lrintf(tab[i] * scale / (norm - tab[0] + tab[tap_count])));

            }

            break;

        case AV_SAMPLE_FMT_S32P:

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

                ((int32_t*)filter)[ph * alloc + i] = av_clipl_int32(llrint(tab[i] * scale / norm));

            if (tap_count % 2 == 0) {

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

                    ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((int32_t*)filter)[ph * alloc + i];

            }

            else {

                for (i = 1; i <= tap_count; i++)

                    ((int32_t*)filter)[(phase_count-ph) * alloc + tap_count-i] =

                        av_clipl_int32(llrint(tab[i] * scale / (norm - tab[0] + tab[tap_count])));

            }

            break;

        case AV_SAMPLE_FMT_FLTP:

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

                ((float*)filter)[ph * alloc + i] = tab[i] * scale / norm;

            if (tap_count % 2 == 0) {

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

                    ((float*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((float*)filter)[ph * alloc + i];

            }

            else {

                for (i = 1; i <= tap_count; i++)

                    ((float*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]);

            }

            break;

        case AV_SAMPLE_FMT_DBLP:

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

                ((double*)filter)[ph * alloc + i] = tab[i] * scale / norm;

            if (tap_count % 2 == 0) {

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

                    ((double*)filter)[(phase_count-ph) * alloc + tap_count-1-i] = ((double*)filter)[ph * alloc + i];

            }

            else {

                for (i = 1; i <= tap_count; i++)

                    ((double*)filter)[(phase_count-ph) * alloc + tap_count-i] = tab[i] * scale / (norm - tab[0] + tab[tap_count]);

            }

            break;

        }

    }

#if 0

    {

#define LEN 1024

        int j,k;

        double sine[LEN + tap_count];

        double filtered[LEN];

        double maxff=-2, minff=2, maxsf=-2, minsf=2;

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

            double ss=0, sf=0, ff=0;

            for(j=0; j<LEN+tap_count; j++)

                sine[j]= cos(i*j*M_PI/LEN);

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

                double sum=0;

                ph=0;

                for(k=0; k<tap_count; k++)

                    sum += filter[ph * tap_count + k] * sine[k+j];

                filtered[j]= sum / (1<<FILTER_SHIFT);

                ss+= sine[j + center] * sine[j + center];

                ff+= filtered[j] * filtered[j];

                sf+= sine[j + center] * filtered[j];

            }

            ss= sqrt(2*ss/LEN);

            ff= sqrt(2*ff/LEN);

            sf= 2*sf/LEN;

            maxff= FFMAX(maxff, ff);

            minff= FFMIN(minff, ff);

            maxsf= FFMAX(maxsf, sf);

            minsf= FFMIN(minsf, sf);

            if(i%11==0){

                av_log(NULL, AV_LOG_ERROR, "i:%4d ss:%f ff:%13.6e-%13.6e sf:%13.6e-%13.6e\n", i, ss, maxff, minff, maxsf, minsf);

                minff=minsf= 2;

                maxff=maxsf= -2;

            }

        }

    }

#endif

fail:

    av_free(tab);

    av_free(sin_lut);

    return 0;

}


static void gen_add(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb)

{

    TCGv t0 = tcg_const_tl(0);

    TCGv res = tcg_temp_new();

    TCGv sr_cy = tcg_temp_new();

    TCGv sr_ov = tcg_temp_new();

    tcg_gen_add2_tl(res, sr_cy, srca, t0, srcb, t0);

    tcg_gen_xor_tl(sr_ov, srca, srcb);

    tcg_gen_xor_tl(t0, res, srcb);

    tcg_gen_andc_tl(sr_ov, t0, sr_ov);

    tcg_temp_free(t0);

    tcg_gen_mov_tl(dest, res);

    tcg_temp_free(res);

    tcg_gen_shri_tl(sr_ov, sr_ov, TARGET_LONG_BITS - 1);

    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_cy, ctz32(SR_CY), 1);

    tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1);

    gen_ove_cyov(dc, sr_ov, sr_cy);

    tcg_temp_free(sr_ov);

    tcg_temp_free(sr_cy);

}


int av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],

                         const uint8_t *src,

                         enum AVPixelFormat pix_fmt, int width, int height, int align)

{

    int ret, i;

    if ((ret = av_image_check_size(width, height, 0, NULL)) < 0)

        return ret;

    if ((ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width)) < 0)

        return ret;

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

        dst_linesize[i] = FFALIGN(dst_linesize[i], align);

    if ((ret = av_image_fill_pointers(dst_data, pix_fmt, width, NULL, dst_linesize)) < 0)

        return ret;

    return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);

}


static void pc_q35_init(QEMUMachineInitArgs *args)

{

    ram_addr_t below_4g_mem_size, above_4g_mem_size;

    Q35PCIHost *q35_host;

    PCIHostState *phb;

    PCIBus *host_bus;

    PCIDevice *lpc;

    BusState *idebus[MAX_SATA_PORTS];

    ISADevice *rtc_state;

    ISADevice *floppy;

    MemoryRegion *pci_memory;

    MemoryRegion *rom_memory;

    MemoryRegion *ram_memory;

    GSIState *gsi_state;

    ISABus *isa_bus;

    int pci_enabled = 1;

    qemu_irq *cpu_irq;

    qemu_irq *gsi;

    qemu_irq *i8259;

    int i;

    ICH9LPCState *ich9_lpc;

    PCIDevice *ahci;

    DeviceState *icc_bridge;

    PcGuestInfo *guest_info;

    if (xen_enabled() && xen_hvm_init(&ram_memory) != 0) {

        fprintf(stderr, "xen hardware virtual machine initialisation failed\n");

        exit(1);

    }

    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);

    object_property_add_child(qdev_get_machine(), "icc-bridge",

                              OBJECT(icc_bridge), NULL);

    pc_cpus_init(args->cpu_model, icc_bridge);

    pc_acpi_init("q35-acpi-dsdt.aml");

    kvmclock_create();

    if (args->ram_size >= 0xb0000000) {

        above_4g_mem_size = args->ram_size - 0xb0000000;

        below_4g_mem_size = 0xb0000000;

    } else {

        above_4g_mem_size = 0;

        below_4g_mem_size = args->ram_size;

    }

    /* pci enabled */

    if (pci_enabled) {

        pci_memory = g_new(MemoryRegion, 1);

        memory_region_init(pci_memory, NULL, "pci", INT64_MAX);

        rom_memory = pci_memory;

    } else {

        pci_memory = NULL;

        rom_memory = get_system_memory();

    }

    guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);

    guest_info->has_pci_info = has_pci_info;

    guest_info->isapc_ram_fw = false;

    guest_info->has_acpi_build = has_acpi_build;

    /* allocate ram and load rom/bios */

    if (!xen_enabled()) {

        pc_memory_init(get_system_memory(),

                       args->kernel_filename, args->kernel_cmdline,

                       args->initrd_filename,

                       below_4g_mem_size, above_4g_mem_size,

                       rom_memory, &ram_memory, guest_info);

    }

    /* irq lines */

    gsi_state = g_malloc0(sizeof(*gsi_state));

    if (kvm_irqchip_in_kernel()) {

        kvm_pc_setup_irq_routing(pci_enabled);

        gsi = qemu_allocate_irqs(kvm_pc_gsi_handler, gsi_state,

                                 GSI_NUM_PINS);

    } else {

        gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);

    }

    /* create pci host bus */

    q35_host = Q35_HOST_DEVICE(qdev_create(NULL, TYPE_Q35_HOST_DEVICE));

    object_property_add_child(qdev_get_machine(), "q35", OBJECT(q35_host), NULL);

    q35_host->mch.ram_memory = ram_memory;

    q35_host->mch.pci_address_space = pci_memory;

    q35_host->mch.system_memory = get_system_memory();

    q35_host->mch.address_space_io = get_system_io();

    q35_host->mch.below_4g_mem_size = below_4g_mem_size;

    q35_host->mch.above_4g_mem_size = above_4g_mem_size;

    q35_host->mch.guest_info = guest_info;

    /* pci */

    qdev_init_nofail(DEVICE(q35_host));

    phb = PCI_HOST_BRIDGE(q35_host);

    host_bus = phb->bus;

    /* create ISA bus */

    lpc = pci_create_simple_multifunction(host_bus, PCI_DEVFN(ICH9_LPC_DEV,

                                          ICH9_LPC_FUNC), true,

                                          TYPE_ICH9_LPC_DEVICE);

    ich9_lpc = ICH9_LPC_DEVICE(lpc);

    ich9_lpc->pic = gsi;

    ich9_lpc->ioapic = gsi_state->ioapic_irq;

    pci_bus_irqs(host_bus, ich9_lpc_set_irq, ich9_lpc_map_irq, ich9_lpc,

                 ICH9_LPC_NB_PIRQS);

    pci_bus_set_route_irq_fn(host_bus, ich9_route_intx_pin_to_irq);

    isa_bus = ich9_lpc->isa_bus;

    /*end early*/

    isa_bus_irqs(isa_bus, gsi);

    if (kvm_irqchip_in_kernel()) {

        i8259 = kvm_i8259_init(isa_bus);

    } else if (xen_enabled()) {

        i8259 = xen_interrupt_controller_init();

    } else {

        cpu_irq = pc_allocate_cpu_irq();

        i8259 = i8259_init(isa_bus, cpu_irq[0]);

    }

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

        gsi_state->i8259_irq[i] = i8259[i];

    }

    if (pci_enabled) {

        ioapic_init_gsi(gsi_state, NULL);

    }

    qdev_init_nofail(icc_bridge);

    pc_register_ferr_irq(gsi[13]);

    /* init basic PC hardware */

    pc_basic_device_init(isa_bus, gsi, &rtc_state, &floppy, false);

    /* connect pm stuff to lpc */

    ich9_lpc_pm_init(lpc);

    /* ahci and SATA device, for q35 1 ahci controller is built-in */

    ahci = pci_create_simple_multifunction(host_bus,

                                           PCI_DEVFN(ICH9_SATA1_DEV,

                                                     ICH9_SATA1_FUNC),

                                           true, "ich9-ahci");

    idebus[0] = qdev_get_child_bus(&ahci->qdev, "ide.0");

    idebus[1] = qdev_get_child_bus(&ahci->qdev, "ide.1");

    if (usb_enabled(false)) {

        /* Should we create 6 UHCI according to ich9 spec? */

        ehci_create_ich9_with_companions(host_bus, 0x1d);

    }

    /* TODO: Populate SPD eeprom data.  */

    smbus_eeprom_init(ich9_smb_init(host_bus,

                                    PCI_DEVFN(ICH9_SMB_DEV, ICH9_SMB_FUNC),

                                    0xb100),

                      8, NULL, 0);

    pc_cmos_init(below_4g_mem_size, above_4g_mem_size, args->boot_order,

                 floppy, idebus[0], idebus[1], rtc_state);

    /* the rest devices to which pci devfn is automatically assigned */

    pc_vga_init(isa_bus, host_bus);

    pc_nic_init(isa_bus, host_bus);

    if (pci_enabled) {

        pc_pci_device_init(host_bus);

    }

    if (has_pvpanic) {

        pvpanic_init(isa_bus);

    }

}


static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOVAtom atom)

{

    AVStream *st = c->fc->streams[c->fc->nb_streams-1];

    uint64_t size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;

    uint8_t *buf;

    if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)

        return -1;

    buf= av_realloc(st->codec->extradata, size);

    if(!buf)

        return -1;

    st->codec->extradata= buf;

    buf+= st->codec->extradata_size;

    st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;

    AV_WB32(       buf    , atom.size + 8);

    AV_WL32(       buf + 4, atom.type);

    get_buffer(pb, buf + 8, atom.size);

    return 0;

}


int tap_open(char *ifname, int ifname_size, int *vnet_hdr,

             int vnet_hdr_required, int mq_required, Error **errp)

{

    /* FIXME error_setg(errp, ...) on failure */

    char  dev[10]="";

    int fd;

    if( (fd = tap_alloc(dev, sizeof(dev))) < 0 ){

       fprintf(stderr, "Cannot allocate TAP device\n");

       return -1;

    }

    pstrcpy(ifname, ifname_size, dev);

    if (*vnet_hdr) {

        /* Solaris doesn't have IFF_VNET_HDR */

        *vnet_hdr = 0;

        if (vnet_hdr_required && !*vnet_hdr) {

            error_report("vnet_hdr=1 requested, but no kernel "

                         "support for IFF_VNET_HDR available");

            close(fd);

            return -1;

        }

    }

    fcntl(fd, F_SETFL, O_NONBLOCK);

    return fd;

}


static void av_estimate_timings(AVFormatContext *ic)

{

    int64_t file_size;

    /* get the file size, if possible */

    if (ic->iformat->flags & AVFMT_NOFILE) {

        file_size = 0;

    } else {

        file_size = url_fsize(&ic->pb);

        if (file_size < 0)

            file_size = 0;

    }

    ic->file_size = file_size;

    if ((!strcmp(ic->iformat->name, "mpeg") ||

         !strcmp(ic->iformat->name, "mpegts")) &&

        file_size && !ic->pb.is_streamed) {

        /* get accurate estimate from the PTSes */

        av_estimate_timings_from_pts(ic);

    } else if (av_has_timings(ic)) {

        /* at least one components has timings - we use them for all

           the components */

        fill_all_stream_timings(ic);

    } else {

        /* less precise: use bit rate info */

        av_estimate_timings_from_bit_rate(ic);

    }

    av_update_stream_timings(ic);

#if 0

    {

        int i;

        AVStream *st;

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

            st = ic->streams[i];

        printf("%d: start_time: %0.3f duration: %0.3f\n",

               i, (double)st->start_time / AV_TIME_BASE,

               (double)st->duration / AV_TIME_BASE);

        }

        printf("stream: start_time: %0.3f duration: %0.3f bitrate=%d kb/s\n",

               (double)ic->start_time / AV_TIME_BASE,

               (double)ic->duration / AV_TIME_BASE,

               ic->bit_rate / 1000);

    }

#endif

}


static av_cold int ac3_encode_init(AVCodecContext *avctx)

{

    int freq = avctx->sample_rate;

    int bitrate = avctx->bit_rate;

    AC3EncodeContext *s = avctx->priv_data;

    int i, j, ch;

    int bw_code;

    avctx->frame_size = AC3_FRAME_SIZE;

    ac3_common_init();

    if (!avctx->channel_layout) {

        av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "

                                      "encoder will guess the layout, but it "

                                      "might be incorrect.\n");

    }

    if (set_channel_info(s, avctx->channels, &avctx->channel_layout)) {

        av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n");

        return -1;

    }

    /* frequency */

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

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

            if ((ff_ac3_sample_rate_tab[j] >> i) == freq)

                goto found;

    }

    return -1;

 found:

    s->sample_rate        = freq;

    s->bit_alloc.sr_shift = i;

    s->bit_alloc.sr_code  = j;

    s->bitstream_id       = 8 + s->bit_alloc.sr_shift;

    s->bitstream_mode     = 0; /* complete main audio service */

    /* bitrate & frame size */

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

        if ((ff_ac3_bitrate_tab[i] >> s->bit_alloc.sr_shift)*1000 == bitrate)

            break;

    }

    if (i == 19)

        return -1;

    s->bit_rate        = bitrate;

    s->frame_size_code = i << 1;

    s->frame_size_min  = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];

    s->bits_written    = 0;

    s->samples_written = 0;

    s->frame_size      = s->frame_size_min;

    /* set bandwidth */

    if (avctx->cutoff) {

        /* calculate bandwidth based on user-specified cutoff frequency */

        int cutoff     = av_clip(avctx->cutoff, 1, s->sample_rate >> 1);

        int fbw_coeffs = cutoff * 2 * AC3_MAX_COEFS / s->sample_rate;

        bw_code        = av_clip((fbw_coeffs - 73) / 3, 0, 60);

    } else {

        /* use default bandwidth setting */

        /* XXX: should compute the bandwidth according to the frame

           size, so that we avoid annoying high frequency artifacts */

        bw_code = 50;

    }

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

        /* bandwidth for each channel */

        s->bandwidth_code[ch] = bw_code;

        s->nb_coefs[ch]       = bw_code * 3 + 73;

    }

    if (s->lfe_on)

        s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */

    /* initial snr offset */

    s->coarse_snr_offset = 40;

    mdct_init(9);

    avctx->coded_frame= avcodec_alloc_frame();

    avctx->coded_frame->key_frame= 1;

    return 0;

}


static void gen_connect(URLContext *s, RTMPContext *rt)

{

    RTMPPacket pkt;

    uint8_t ver[64], *p;

    ff_rtmp_packet_create(&pkt, RTMP_SYSTEM_CHANNEL, RTMP_PT_INVOKE, 0, 4096);

    p = pkt.data;

    ff_amf_write_string(&p, "connect");

    ff_amf_write_number(&p, ++rt->nb_invokes);

    ff_amf_write_object_start(&p);

    ff_amf_write_field_name(&p, "app");

    ff_amf_write_string(&p, rt->app);

    if (rt->is_input) {

        snprintf(ver, sizeof(ver), "%s %d,%d,%d,%d", RTMP_CLIENT_PLATFORM, RTMP_CLIENT_VER1,

                 RTMP_CLIENT_VER2, RTMP_CLIENT_VER3, RTMP_CLIENT_VER4);

    } else {

        snprintf(ver, sizeof(ver), "FMLE/3.0 (compatible; %s)", LIBAVFORMAT_IDENT);

        ff_amf_write_field_name(&p, "type");

        ff_amf_write_string(&p, "nonprivate");

    }

    ff_amf_write_field_name(&p, "flashVer");

    ff_amf_write_string(&p, ver);

    ff_amf_write_field_name(&p, "tcUrl");

    ff_amf_write_string(&p, rt->tcurl);

    if (rt->is_input) {

        ff_amf_write_field_name(&p, "fpad");

        ff_amf_write_bool(&p, 0);

        ff_amf_write_field_name(&p, "capabilities");

        ff_amf_write_number(&p, 15.0);

        /* Tell the server we support all the audio codecs except

         * SUPPORT_SND_INTEL (0x0008) and SUPPORT_SND_UNUSED (0x0010)

         * which are unused in the RTMP protocol implementation. */

        ff_amf_write_field_name(&p, "audioCodecs");

        ff_amf_write_number(&p, 4071.0);

        ff_amf_write_field_name(&p, "videoCodecs");

        ff_amf_write_number(&p, 252.0);

        ff_amf_write_field_name(&p, "videoFunction");

        ff_amf_write_number(&p, 1.0);

    }

    ff_amf_write_object_end(&p);

    pkt.data_size = p - pkt.data;

    ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]);

    ff_rtmp_packet_destroy(&pkt);

}


static void pc_dimm_plug(HotplugHandler *hotplug_dev,

                         DeviceState *dev, Error **errp)

{

    HotplugHandlerClass *hhc;

    Error *local_err = NULL;

    PCMachineState *pcms = PC_MACHINE(hotplug_dev);

    PCDIMMDevice *dimm = PC_DIMM(dev);

    PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);

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

    uint64_t align = TARGET_PAGE_SIZE;

    if (memory_region_get_alignment(mr) && pcms->enforce_aligned_dimm) {

        align = memory_region_get_alignment(mr);

    }

    if (!pcms->acpi_dev) {

        error_setg(&local_err,

                   "memory hotplug is not enabled: missing acpi device");

        goto out;

    }

    pc_dimm_memory_plug(dev, &pcms->hotplug_memory, mr, align, &local_err);

    if (local_err) {

        goto out;

    }

    hhc = HOTPLUG_HANDLER_GET_CLASS(pcms->acpi_dev);

    hhc->plug(HOTPLUG_HANDLER(pcms->acpi_dev), dev, &error_abort);

out:

    error_propagate(errp, local_err);

}


static void cmd_test_unit_ready(IDEState *s, uint8_t *buf)

{

    if (bdrv_is_inserted(s->bs)) {

        ide_atapi_cmd_ok(s);

    } else {

        ide_atapi_cmd_error(s, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);

    }

}