static void build_chunks(MOVTrack *trk)

{

    int i;

    MOVIentry *chunk= &trk->cluster[0];

    uint64_t chunkSize = chunk->size;

    chunk->chunkNum= 1;

    trk->chunkCount= 1;

    for(i=1; i<trk->entry; i++){

        if(chunk->pos + chunkSize == trk->cluster[i].pos){

            chunkSize             += trk->cluster[i].size;

            chunk->samplesInChunk += trk->cluster[i].entries;

        }else{

            trk->cluster[i].chunkNum = chunk->chunkNum+1;

            chunk=&trk->cluster[i];

            chunkSize = chunk->size;

            trk->chunkCount++;

        }

    }

}


static int encode_frame(AVCodecContext *avctx, AVPacket *pkt,

                        const AVFrame *pic, int *got_packet)

{

    ProresContext *ctx = avctx->priv_data;

    uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp;

    uint8_t *picture_size_pos;

    PutBitContext pb;

    int x, y, i, mb, q = 0;

    int sizes[4] = { 0 };

    int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1);

    int frame_size, picture_size, slice_size;

    int pkt_size, ret;

    uint8_t frame_flags;

    *avctx->coded_frame           = *pic;

    avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I;

    avctx->coded_frame->key_frame = 1;

    pkt_size = ctx->frame_size_upper_bound;

    if ((ret = ff_alloc_packet(pkt, pkt_size + FF_MIN_BUFFER_SIZE)) < 0) {

        av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n");

        return ret;

    }

    orig_buf = pkt->data;

    // frame atom

    orig_buf += 4;                              // frame size

    bytestream_put_be32  (&orig_buf, FRAME_ID); // frame container ID

    buf = orig_buf;

    // frame header

    tmp = buf;

    buf += 2;                                   // frame header size will be stored here

    bytestream_put_be16  (&buf, 0);             // version 1

    bytestream_put_buffer(&buf, ctx->vendor, 4);

    bytestream_put_be16  (&buf, avctx->width);

    bytestream_put_be16  (&buf, avctx->height);

    frame_flags = ctx->chroma_factor << 6;

    if (avctx->flags & CODEC_FLAG_INTERLACED_DCT)

        frame_flags |= pic->top_field_first ? 0x04 : 0x08;

    bytestream_put_byte  (&buf, frame_flags);

    bytestream_put_byte  (&buf, 0);             // reserved

    bytestream_put_byte  (&buf, avctx->color_primaries);

    bytestream_put_byte  (&buf, avctx->color_trc);

    bytestream_put_byte  (&buf, avctx->colorspace);

    bytestream_put_byte  (&buf, 0x40 | (ctx->alpha_bits >> 3));

    bytestream_put_byte  (&buf, 0);             // reserved

    if (ctx->quant_sel != QUANT_MAT_DEFAULT) {

        bytestream_put_byte  (&buf, 0x03);      // matrix flags - both matrices are present

        // luma quantisation matrix

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

            bytestream_put_byte(&buf, ctx->quant_mat[i]);

        // chroma quantisation matrix

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

            bytestream_put_byte(&buf, ctx->quant_mat[i]);

    } else {

        bytestream_put_byte  (&buf, 0x00);      // matrix flags - default matrices are used

    }

    bytestream_put_be16  (&tmp, buf - orig_buf); // write back frame header size

    for (ctx->cur_picture_idx = 0;

         ctx->cur_picture_idx < ctx->pictures_per_frame;

         ctx->cur_picture_idx++) {

        // picture header

        picture_size_pos = buf + 1;

        bytestream_put_byte  (&buf, 0x40);          // picture header size (in bits)

        buf += 4;                                   // picture data size will be stored here

        bytestream_put_be16  (&buf, ctx->slices_per_picture);

        bytestream_put_byte  (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs

        // seek table - will be filled during slice encoding

        slice_sizes = buf;

        buf += ctx->slices_per_picture * 2;

        // slices

        if (!ctx->force_quant) {

            ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL,

                                  ctx->mb_height);

            if (ret)

                return ret;

        }

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

            int mbs_per_slice = ctx->mbs_per_slice;

            for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) {

                q = ctx->force_quant ? ctx->force_quant

                                     : ctx->slice_q[mb + y * ctx->slices_width];

                while (ctx->mb_width - x < mbs_per_slice)

                    mbs_per_slice >>= 1;

                bytestream_put_byte(&buf, slice_hdr_size << 3);

                slice_hdr = buf;

                buf += slice_hdr_size - 1;

                init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8);

                ret = encode_slice(avctx, pic, &pb, sizes, x, y, q,

                                   mbs_per_slice);

                if (ret < 0)

                    return ret;

                bytestream_put_byte(&slice_hdr, q);

                slice_size = slice_hdr_size + sizes[ctx->num_planes - 1];

                for (i = 0; i < ctx->num_planes - 1; i++) {

                    bytestream_put_be16(&slice_hdr, sizes[i]);

                    slice_size += sizes[i];

                }

                bytestream_put_be16(&slice_sizes, slice_size);

                buf += slice_size - slice_hdr_size;

            }

        }

        if (ctx->pictures_per_frame == 1)

            picture_size = buf - picture_size_pos - 6;

        else

            picture_size = buf - picture_size_pos + 1;

        bytestream_put_be32(&picture_size_pos, picture_size);

    }

    orig_buf -= 8;

    frame_size = buf - orig_buf;

    bytestream_put_be32(&orig_buf, frame_size);

    pkt->size   = frame_size;

    pkt->flags |= AV_PKT_FLAG_KEY;

    *got_packet = 1;

    return 0;

}


void ff_lag_rac_init(lag_rac *l, GetBitContext *gb, int length)

{

    int i, j;

    /* According to reference decoder "1st byte is garbage",

     * however, it gets skipped by the call to align_get_bits()

     */

    align_get_bits(gb);

    l->bytestream_start =

    l->bytestream       = gb->buffer + get_bits_count(gb) / 8;

    l->bytestream_end   = l->bytestream_start + length;

    l->range        = 0x80;

    l->low          = *l->bytestream >> 1;

    l->hash_shift   = FFMAX(l->scale - 8, 0);

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

        unsigned r = i << l->hash_shift;

        while (l->prob[j + 1] <= r)

            j++;

        l->range_hash[i] = j;

    }

    /* Add conversion factor to hash_shift so we don't have to in lag_get_rac. */

    l->hash_shift += 23;

}


void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd,

                        void *opaque)

{

    SaveStateEntry *se, *new_se;

    QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) {

        if (se->vmsd == vmsd && se->opaque == opaque) {

            QTAILQ_REMOVE(&savevm_handlers, se, entry);

            qemu_free(se);


void iothread_stop_all(void)

{

    Object *container = object_get_objects_root();

    BlockDriverState *bs;

    BdrvNextIterator it;

    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {

        AioContext *ctx = bdrv_get_aio_context(bs);

        if (ctx == qemu_get_aio_context()) {

            continue;

        }

        aio_context_acquire(ctx);

        bdrv_set_aio_context(bs, qemu_get_aio_context());

        aio_context_release(ctx);

    }

    object_child_foreach(container, iothread_stop, NULL);

}


int apic_get_interrupt(DeviceState *d)

{

    APICState *s = DO_UPCAST(APICState, busdev.qdev, d);

    int intno;

    /* if the APIC is installed or enabled, we let the 8259 handle the

       IRQs */

    if (!s)

        return -1;

    if (!(s->spurious_vec & APIC_SV_ENABLE))

        return -1;

    /* XXX: spurious IRQ handling */

    intno = get_highest_priority_int(s->irr);

    if (intno < 0)

        return -1;

    if (s->tpr && intno <= s->tpr)

        return s->spurious_vec & 0xff;

    reset_bit(s->irr, intno);

    set_bit(s->isr, intno);

    apic_update_irq(s);

    return intno;

}


static inline void decode_residual_inter(AVSContext *h) {

    int block;

    /* get coded block pattern */

    h->cbp = cbp_tab[get_ue_golomb(&h->s.gb)][1];

    /* get quantizer */

    if(h->cbp && !h->qp_fixed)

        h->qp += get_se_golomb(&h->s.gb);

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

        if(h->cbp & (1<<block))

            decode_residual_block(h,&h->s.gb,inter_2dvlc,0,h->qp,

                                  h->cy + h->luma_scan[block], h->l_stride);

    decode_residual_chroma(h);

}


static void pfpu_write(void *opaque, target_phys_addr_t addr, uint64_t value,

                       unsigned size)

{

    MilkymistPFPUState *s = opaque;

    trace_milkymist_pfpu_memory_write(addr, value);

    addr >>= 2;

    switch (addr) {

    case R_CTL:

        if (value & CTL_START_BUSY) {

            pfpu_start(s);

        }

        break;

    case R_MESHBASE:

    case R_HMESHLAST:

    case R_VMESHLAST:

    case R_CODEPAGE:

    case R_VERTICES:

    case R_COLLISIONS:

    case R_STRAYWRITES:

    case R_LASTDMA:

    case R_PC:

    case R_DREGBASE:

    case R_CODEBASE:

        s->regs[addr] = value;

        break;

    case GPR_BEGIN ...  GPR_END:

        s->gp_regs[addr - GPR_BEGIN] = value;

        break;

    case MICROCODE_BEGIN ...  MICROCODE_END:

        s->microcode[get_microcode_address(s, addr)] = value;

        break;

    default:

        error_report("milkymist_pfpu: write access to unknown register 0x"

                TARGET_FMT_plx, addr << 2);

        break;

    }

}


uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len)

{

    VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev);

    uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val;

    memcpy(&emu_bits, vdev->emulated_config_bits + addr, len);

    emu_bits = le32_to_cpu(emu_bits);

    if (emu_bits) {

        emu_val = pci_default_read_config(pdev, addr, len);

    }

    if (~emu_bits & (0xffffffffU >> (32 - len * 8))) {

        ssize_t ret;

        ret = pread(vdev->vbasedev.fd, &phys_val, len,

                    vdev->config_offset + addr);

        if (ret != len) {

            error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x) failed: %m",

                         __func__, vdev->host.domain, vdev->host.bus,

                         vdev->host.slot, vdev->host.function, addr, len);

            return -errno;

        }

        phys_val = le32_to_cpu(phys_val);

    }

    val = (emu_val & emu_bits) | (phys_val & ~emu_bits);

    trace_vfio_pci_read_config(vdev->vbasedev.name, addr, len, val);

    return val;

}


static void pci_device_reset(PCIDevice *dev)

{

    int r;

    dev->irq_state = 0;

    pci_update_irq_status(dev);

    /* Clear all writeable bits */

    pci_word_test_and_clear_mask(dev->config + PCI_COMMAND,

                                 pci_get_word(dev->wmask + PCI_COMMAND));

    dev->config[PCI_CACHE_LINE_SIZE] = 0x0;

    dev->config[PCI_INTERRUPT_LINE] = 0x0;

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

        PCIIORegion *region = &dev->io_regions[r];

        if (!region->size) {

            continue;

        }

        if (!(region->type & PCI_BASE_ADDRESS_SPACE_IO) &&

            region->type & PCI_BASE_ADDRESS_MEM_TYPE_64) {

            pci_set_quad(dev->config + pci_bar(dev, r), region->type);

        } else {

            pci_set_long(dev->config + pci_bar(dev, r), region->type);

        }

    }

    pci_update_mappings(dev);

}


static void xen_set_memory(struct MemoryListener *listener,

                           MemoryRegionSection *section,

                           bool add)

{

    XenIOState *state = container_of(listener, XenIOState, memory_listener);

    hwaddr start_addr = section->offset_within_address_space;

    ram_addr_t size = int128_get64(section->size);

    bool log_dirty = memory_region_is_logging(section->mr);

    hvmmem_type_t mem_type;

    if (section->mr == &ram_memory) {

        return;

    } else {

        if (add) {

            xen_map_memory_section(xen_xc, xen_domid, state->ioservid,

                                   section);

        } else {

            xen_unmap_memory_section(xen_xc, xen_domid, state->ioservid,

                                     section);

        }

    }

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

        return;

    }

    if (log_dirty != add) {

        return;

    }

    trace_xen_client_set_memory(start_addr, size, log_dirty);

    start_addr &= TARGET_PAGE_MASK;

    size = TARGET_PAGE_ALIGN(size);

    if (add) {

        if (!memory_region_is_rom(section->mr)) {

            xen_add_to_physmap(state, start_addr, size,

                               section->mr, section->offset_within_region);

        } else {

            mem_type = HVMMEM_ram_ro;

            if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type,

                                    start_addr >> TARGET_PAGE_BITS,

                                    size >> TARGET_PAGE_BITS)) {

                DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n",

                        start_addr);

            }

        }

    } else {

        if (xen_remove_from_physmap(state, start_addr, size) < 0) {

            DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr);

        }

    }

}


static void hmp_mouse_move(Monitor *mon, const QDict *qdict)

{

    int dx, dy, dz, button;

    const char *dx_str = qdict_get_str(qdict, "dx_str");

    const char *dy_str = qdict_get_str(qdict, "dy_str");

    const char *dz_str = qdict_get_try_str(qdict, "dz_str");

    dx = strtol(dx_str, NULL, 0);

    dy = strtol(dy_str, NULL, 0);

    qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx);

    qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy);

    if (dz_str) {

        dz = strtol(dz_str, NULL, 0);

        if (dz != 0) {

            button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN;

            qemu_input_queue_btn(NULL, button, true);

            qemu_input_event_sync();

            qemu_input_queue_btn(NULL, button, false);

        }

    }

    qemu_input_event_sync();

}


static void realview_init(ram_addr_t ram_size,

                     const char *boot_device,

                     const char *kernel_filename, const char *kernel_cmdline,

                     const char *initrd_filename, const char *cpu_model,

                     enum realview_board_type board_type)

{

    CPUState *env = NULL;

    ram_addr_t ram_offset;

    DeviceState *dev, *sysctl, *gpio2;

    SysBusDevice *busdev;

    qemu_irq *irqp;

    qemu_irq pic[64];

    qemu_irq mmc_irq[2];

    PCIBus *pci_bus;

    NICInfo *nd;

    i2c_bus *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;

    switch (board_type) {

    case BOARD_EB:

        break;

    case BOARD_EB_MPCORE:

        is_mpcore = 1;

        break;

    case BOARD_PB_A8:

        is_pb = 1;

        break;

    case BOARD_PBX_A9:

        is_mpcore = 1;

        is_pb = 1;

        break;

    }

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

        env = cpu_init(cpu_model);

        if (!env) {

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

            exit(1);

        }

        irqp = arm_pic_init_cpu(env);

        cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ];

    }

    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;

        ram_offset = qemu_ram_alloc(NULL, "realview.lowmem", low_ram_size);

        cpu_register_physical_memory(0x20000000, low_ram_size,

                                     ram_offset | IO_MEM_RAM);

    }

    ram_offset = qemu_ram_alloc(NULL, "realview.highmem", ram_size);

    low_ram_size = ram_size;

    if (low_ram_size > 0x10000000)

      low_ram_size = 0x10000000;

    /* SDRAM at address zero.  */

    cpu_register_physical_memory(0, low_ram_size, ram_offset | IO_MEM_RAM);

    if (is_pb) {

        /* And again at a high address.  */

        cpu_register_physical_memory(0x70000000, ram_size,

                                     ram_offset | IO_MEM_RAM);

    } 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_init_nofail(sysctl);

    qdev_prop_set_uint32(sysctl, "proc_id", proc_id);

    sysbus_mmio_map(sysbus_from_qdev(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 = sysbus_from_qdev(dev);

        if (is_pb) {

            realview_binfo.smp_priv_base = 0x1f000000;

        } else {

            realview_binfo.smp_priv_base = 0x10100000;

        }

        sysbus_mmio_map(busdev, 0, realview_binfo.smp_priv_base);

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

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

        }

    } 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);

    }

    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 = sysbus_create_varargs("realview_pci", 0x60000000,

                                    pic[48], pic[49], pic[50], pic[51], NULL);

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

        if (usb_enabled) {

            usb_ohci_init_pci(pci_bus, -1);

        }

        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 {

            pci_nic_init_nofail(nd, "rtl8139", NULL);

        }

    }

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

    i2c = (i2c_bus *)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.  */

    /* 0x61000000 PCI Self Config.  */

    /* 0x62000000 PCI Config.  */

    /* 0x63000000 PCI IO.  */

    /* 0x64000000 PCI mem 0.  */

    /* 0x68000000 PCI mem 1.  */

    /* 0x6c000000 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.  */

    ram_offset = qemu_ram_alloc(NULL, "realview.hack", 0x1000);

    cpu_register_physical_memory(SMP_BOOT_ADDR, 0x1000,

                                 ram_offset | IO_MEM_RAM);

    realview_binfo.ram_size = ram_size;

    realview_binfo.kernel_filename = kernel_filename;

    realview_binfo.kernel_cmdline = kernel_cmdline;

    realview_binfo.initrd_filename = 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(first_cpu, &realview_binfo);

}


static int intel_hda_post_load(void *opaque, int version)

{

    IntelHDAState* d = opaque;

    int i;

    dprint(d, 1, "%s\n", __FUNCTION__);

    for (i = 0; i < ARRAY_SIZE(d->st); i++) {

        if (d->st[i].ctl & 0x02) {

            intel_hda_parse_bdl(d, &d->st[i]);

        }

    }

    intel_hda_update_irq(d);

    return 0;

}


int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr,

                             int is_write1, int mmu_idx, int is_softmmu)

{

    uint64_t ptep, pte;

    target_ulong pde_addr, pte_addr;

    int error_code, is_dirty, prot, page_size, ret, is_write, is_user;

    target_phys_addr_t paddr;

    uint32_t page_offset;

    target_ulong vaddr, virt_addr;

    is_user = mmu_idx == MMU_USER_IDX;

#if defined(DEBUG_MMU)

    printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n",

           addr, is_write1, is_user, env->eip);

#endif

    is_write = is_write1 & 1;

    if (!(env->cr[0] & CR0_PG_MASK)) {

        pte = addr;

        virt_addr = addr & TARGET_PAGE_MASK;

        prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC;

        page_size = 4096;

        goto do_mapping;

    }

    if (env->cr[4] & CR4_PAE_MASK) {

        uint64_t pde, pdpe;

        target_ulong pdpe_addr;

#ifdef TARGET_X86_64

        if (env->hflags & HF_LMA_MASK) {

            uint64_t pml4e_addr, pml4e;

            int32_t sext;

            /* test virtual address sign extension */

            sext = (int64_t)addr >> 47;

            if (sext != 0 && sext != -1) {

                env->error_code = 0;

                env->exception_index = EXCP0D_GPF;

                return 1;

            }

            pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) &

                env->a20_mask;

            pml4e = ldq_phys(pml4e_addr);

            if (!(pml4e & PG_PRESENT_MASK)) {

                error_code = 0;

                goto do_fault;

            }

            if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) {

                error_code = PG_ERROR_RSVD_MASK;

                goto do_fault;

            }

            if (!(pml4e & PG_ACCESSED_MASK)) {

                pml4e |= PG_ACCESSED_MASK;

                stl_phys_notdirty(pml4e_addr, pml4e);

            }

            ptep = pml4e ^ PG_NX_MASK;

            pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) &

                env->a20_mask;

            pdpe = ldq_phys(pdpe_addr);

            if (!(pdpe & PG_PRESENT_MASK)) {

                error_code = 0;

                goto do_fault;

            }

            if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) {

                error_code = PG_ERROR_RSVD_MASK;

                goto do_fault;

            }

            ptep &= pdpe ^ PG_NX_MASK;

            if (!(pdpe & PG_ACCESSED_MASK)) {

                pdpe |= PG_ACCESSED_MASK;

                stl_phys_notdirty(pdpe_addr, pdpe);

            }

        } else

#endif

        {

            /* XXX: load them when cr3 is loaded ? */

            pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) &

                env->a20_mask;

            pdpe = ldq_phys(pdpe_addr);

            if (!(pdpe & PG_PRESENT_MASK)) {

                error_code = 0;

                goto do_fault;

            }

            ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK;

        }

        pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) &

            env->a20_mask;

        pde = ldq_phys(pde_addr);

        if (!(pde & PG_PRESENT_MASK)) {

            error_code = 0;

            goto do_fault;

        }

        if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) {

            error_code = PG_ERROR_RSVD_MASK;

            goto do_fault;

        }

        ptep &= pde ^ PG_NX_MASK;

        if (pde & PG_PSE_MASK) {

            /* 2 MB page */

            page_size = 2048 * 1024;

            ptep ^= PG_NX_MASK;

            if ((ptep & PG_NX_MASK) && is_write1 == 2)

                goto do_fault_protect;

            if (is_user) {

                if (!(ptep & PG_USER_MASK))

                    goto do_fault_protect;

                if (is_write && !(ptep & PG_RW_MASK))

                    goto do_fault_protect;

            } else {

                if ((env->cr[0] & CR0_WP_MASK) &&

                    is_write && !(ptep & PG_RW_MASK))

                    goto do_fault_protect;

            }

            is_dirty = is_write && !(pde & PG_DIRTY_MASK);

            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {

                pde |= PG_ACCESSED_MASK;

                if (is_dirty)

                    pde |= PG_DIRTY_MASK;

                stl_phys_notdirty(pde_addr, pde);

            }

            /* align to page_size */

            pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff);

            virt_addr = addr & ~(page_size - 1);

        } else {

            /* 4 KB page */

            if (!(pde & PG_ACCESSED_MASK)) {

                pde |= PG_ACCESSED_MASK;

                stl_phys_notdirty(pde_addr, pde);

            }

            pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) &

                env->a20_mask;

            pte = ldq_phys(pte_addr);

            if (!(pte & PG_PRESENT_MASK)) {

                error_code = 0;

                goto do_fault;

            }

            if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) {

                error_code = PG_ERROR_RSVD_MASK;

                goto do_fault;

            }

            /* combine pde and pte nx, user and rw protections */

            ptep &= pte ^ PG_NX_MASK;

            ptep ^= PG_NX_MASK;

            if ((ptep & PG_NX_MASK) && is_write1 == 2)

                goto do_fault_protect;

            if (is_user) {

                if (!(ptep & PG_USER_MASK))

                    goto do_fault_protect;

                if (is_write && !(ptep & PG_RW_MASK))

                    goto do_fault_protect;

            } else {

                if ((env->cr[0] & CR0_WP_MASK) &&

                    is_write && !(ptep & PG_RW_MASK))

                    goto do_fault_protect;

            }

            is_dirty = is_write && !(pte & PG_DIRTY_MASK);

            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {

                pte |= PG_ACCESSED_MASK;

                if (is_dirty)

                    pte |= PG_DIRTY_MASK;

                stl_phys_notdirty(pte_addr, pte);

            }

            page_size = 4096;

            virt_addr = addr & ~0xfff;

            pte = pte & (PHYS_ADDR_MASK | 0xfff);

        }

    } else {

        uint32_t pde;

        /* page directory entry */

        pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) &

            env->a20_mask;

        pde = ldl_phys(pde_addr);

        if (!(pde & PG_PRESENT_MASK)) {

            error_code = 0;

            goto do_fault;

        }

        /* if PSE bit is set, then we use a 4MB page */

        if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {

            page_size = 4096 * 1024;

            if (is_user) {

                if (!(pde & PG_USER_MASK))

                    goto do_fault_protect;

                if (is_write && !(pde & PG_RW_MASK))

                    goto do_fault_protect;

            } else {

                if ((env->cr[0] & CR0_WP_MASK) &&

                    is_write && !(pde & PG_RW_MASK))

                    goto do_fault_protect;

            }

            is_dirty = is_write && !(pde & PG_DIRTY_MASK);

            if (!(pde & PG_ACCESSED_MASK) || is_dirty) {

                pde |= PG_ACCESSED_MASK;

                if (is_dirty)

                    pde |= PG_DIRTY_MASK;

                stl_phys_notdirty(pde_addr, pde);

            }

            pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */

            ptep = pte;

            virt_addr = addr & ~(page_size - 1);

        } else {

            if (!(pde & PG_ACCESSED_MASK)) {

                pde |= PG_ACCESSED_MASK;

                stl_phys_notdirty(pde_addr, pde);

            }

            /* page directory entry */

            pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) &

                env->a20_mask;

            pte = ldl_phys(pte_addr);

            if (!(pte & PG_PRESENT_MASK)) {

                error_code = 0;

                goto do_fault;

            }

            /* combine pde and pte user and rw protections */

            ptep = pte & pde;

            if (is_user) {

                if (!(ptep & PG_USER_MASK))

                    goto do_fault_protect;

                if (is_write && !(ptep & PG_RW_MASK))

                    goto do_fault_protect;

            } else {

                if ((env->cr[0] & CR0_WP_MASK) &&

                    is_write && !(ptep & PG_RW_MASK))

                    goto do_fault_protect;

            }

            is_dirty = is_write && !(pte & PG_DIRTY_MASK);

            if (!(pte & PG_ACCESSED_MASK) || is_dirty) {

                pte |= PG_ACCESSED_MASK;

                if (is_dirty)

                    pte |= PG_DIRTY_MASK;

                stl_phys_notdirty(pte_addr, pte);

            }

            page_size = 4096;

            virt_addr = addr & ~0xfff;

        }

    }

    /* the page can be put in the TLB */

    prot = PAGE_READ;

    if (!(ptep & PG_NX_MASK))

        prot |= PAGE_EXEC;

    if (pte & PG_DIRTY_MASK) {

        /* only set write access if already dirty... otherwise wait

           for dirty access */

        if (is_user) {

            if (ptep & PG_RW_MASK)

                prot |= PAGE_WRITE;

        } else {

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

                (ptep & PG_RW_MASK))

                prot |= PAGE_WRITE;

        }

    }

 do_mapping:

    pte = pte & env->a20_mask;

    /* Even if 4MB pages, we map only one 4KB page in the cache to

       avoid filling it too fast */

    page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1);

    paddr = (pte & TARGET_PAGE_MASK) + page_offset;

    vaddr = virt_addr + page_offset;

    ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu);

    return ret;

 do_fault_protect:

    error_code = PG_ERROR_P_MASK;

 do_fault:

    error_code |= (is_write << PG_ERROR_W_BIT);

    if (is_user)

        error_code |= PG_ERROR_U_MASK;

    if (is_write1 == 2 &&

        (env->efer & MSR_EFER_NXE) &&

        (env->cr[4] & CR4_PAE_MASK))

        error_code |= PG_ERROR_I_D_MASK;

    if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) {

        /* cr2 is not modified in case of exceptions */

        stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2),

                 addr);

    } else {

        env->cr[2] = addr;

    }

    env->error_code = error_code;

    env->exception_index = EXCP0E_PAGE;

    return 1;

}


static CharDriverState *qemu_chr_open_ringbuf(const char *id,

                                              ChardevBackend *backend,

                                              ChardevReturn *ret,

                                              Error **errp)

{

    ChardevRingbuf *opts = backend->u.ringbuf;

    CharDriverState *chr;

    RingBufCharDriver *d;

    chr = qemu_chr_alloc();

    d = g_malloc(sizeof(*d));

    d->size = opts->has_size ? opts->size : 65536;

    /* The size must be power of 2 */

    if (d->size & (d->size - 1)) {

        error_setg(errp, "size of ringbuf chardev must be power of two");

        goto fail;

    }

    d->prod = 0;

    d->cons = 0;

    d->cbuf = g_malloc0(d->size);

    chr->opaque = d;

    chr->chr_write = ringbuf_chr_write;

    chr->chr_close = ringbuf_chr_close;

    return chr;

fail:

    g_free(d);

    g_free(chr);

    return NULL;

}


int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate)

{

    MPADecodeHeader s1, *s = &s1;

    if (ff_mpa_check_header(head) != 0)

        return -1;

    if (avpriv_mpegaudio_decode_header(s, head) != 0) {

        return -1;

    }

    switch(s->layer) {

    case 1:

        avctx->codec_id = AV_CODEC_ID_MP1;

        *frame_size = 384;

        break;

    case 2:

        avctx->codec_id = AV_CODEC_ID_MP2;

        *frame_size = 1152;

        break;

    default:

    case 3:

        if (avctx->codec_id != AV_CODEC_ID_MP3ADU)

            avctx->codec_id = AV_CODEC_ID_MP3;

        if (s->lsf)

            *frame_size = 576;

        else

            *frame_size = 1152;

        break;

    }

    *sample_rate = s->sample_rate;

    *channels = s->nb_channels;

    *bit_rate = s->bit_rate;

    return s->frame_size;

}


static inline void gen_speundef (DisasContext *ctx)

{

    RET_INVAL(ctx);

}


int kqemu_init(CPUState *env)

{

    struct kqemu_init kinit;

    int ret, version;

#ifdef _WIN32

    DWORD temp;

#endif

    if (!kqemu_allowed)

        return -1;

#ifdef _WIN32

    kqemu_fd = CreateFile(KQEMU_DEVICE, GENERIC_WRITE | GENERIC_READ,

                          FILE_SHARE_READ | FILE_SHARE_WRITE,

                          NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,

                          NULL);

    if (kqemu_fd == KQEMU_INVALID_FD) {

        fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n",

                KQEMU_DEVICE, GetLastError());

        return -1;

    }

#else

    kqemu_fd = open(KQEMU_DEVICE, O_RDWR);

    if (kqemu_fd == KQEMU_INVALID_FD) {

        fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n",

                KQEMU_DEVICE, strerror(errno));

        return -1;

    }

#endif

    version = 0;

#ifdef _WIN32

    DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0,

                    &version, sizeof(version), &temp, NULL);

#else

    ioctl(kqemu_fd, KQEMU_GET_VERSION, &version);

#endif

    if (version != KQEMU_VERSION) {

        fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n",

                version, KQEMU_VERSION);

        goto fail;

    }

    pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH *

                                  sizeof(uint64_t));

    if (!pages_to_flush)

        goto fail;

    ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE *

                                       sizeof(uint64_t));

    if (!ram_pages_to_update)

        goto fail;

    modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES *

                                      sizeof(uint64_t));

    if (!modified_ram_pages)

        goto fail;

    modified_ram_pages_table =

        qemu_mallocz(kqemu_phys_ram_size >> TARGET_PAGE_BITS);

    if (!modified_ram_pages_table)

        goto fail;

    memset(&kinit, 0, sizeof(kinit)); /* set the paddings to zero */

    kinit.ram_base = kqemu_phys_ram_base;

    kinit.ram_size = kqemu_phys_ram_size;

    kinit.ram_dirty = phys_ram_dirty;

    kinit.pages_to_flush = pages_to_flush;

    kinit.ram_pages_to_update = ram_pages_to_update;

    kinit.modified_ram_pages = modified_ram_pages;

#ifdef _WIN32

    ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &kinit, sizeof(kinit),

                          NULL, 0, &temp, NULL) == TRUE ? 0 : -1;

#else

    ret = ioctl(kqemu_fd, KQEMU_INIT, &kinit);

#endif

    if (ret < 0) {

        fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret);

    fail:

        kqemu_closefd(kqemu_fd);

        kqemu_fd = KQEMU_INVALID_FD;

        return -1;

    }

    kqemu_update_cpuid(env);

    env->kqemu_enabled = kqemu_allowed;

    nb_pages_to_flush = 0;

    nb_ram_pages_to_update = 0;

    qpi_init();

    return 0;

}


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

{

    DeviceClass *dc = DEVICE_CLASS(oc);

    PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc);

    dc->fw_name = "PowerPC,POWER9";

    dc->desc = "POWER9";

    dc->props = powerpc_servercpu_properties;

    pcc->pvr_match = ppc_pvr_match_power9;

    pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07;

    pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 |

                         PCR_COMPAT_2_05;

    pcc->init_proc = init_proc_POWER9;

    pcc->check_pow = check_pow_nocheck;

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

                       PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES |

                       PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE |

                       PPC_FLOAT_FRSQRTES |

                       PPC_FLOAT_STFIWX |

                       PPC_FLOAT_EXT |

                       PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ |

                       PPC_MEM_SYNC | PPC_MEM_EIEIO |

                       PPC_MEM_TLBIE | PPC_MEM_TLBSYNC |

                       PPC_64B | PPC_64BX | PPC_ALTIVEC |

                       PPC_SEGMENT_64B | PPC_SLBI |

                       PPC_POPCNTB | PPC_POPCNTWD |

                       PPC_CILDST;

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

                        PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 |

                        PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 |

                        PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 |

                        PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |

                        PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 |

                        PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300;

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

                    (1ull << MSR_TM) |

                    (1ull << MSR_VR) |

                    (1ull << MSR_VSX) |

                    (1ull << MSR_EE) |

                    (1ull << MSR_PR) |

                    (1ull << MSR_FP) |

                    (1ull << MSR_ME) |

                    (1ull << MSR_FE0) |

                    (1ull << MSR_SE) |

                    (1ull << MSR_DE) |

                    (1ull << MSR_FE1) |

                    (1ull << MSR_IR) |

                    (1ull << MSR_DR) |

                    (1ull << MSR_PMM) |

                    (1ull << MSR_RI) |

                    (1ull << MSR_LE);

    pcc->mmu_model = POWERPC_MMU_3_00;

#if defined(CONFIG_SOFTMMU)

    pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault;

    /* segment page size remain the same */

    pcc->sps = &POWER7_POWER8_sps;

#endif

    pcc->excp_model = POWERPC_EXCP_POWER8;

    pcc->bus_model = PPC_FLAGS_INPUT_POWER7;

    pcc->bfd_mach = bfd_mach_ppc64;

    pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE |

                 POWERPC_FLAG_BE | POWERPC_FLAG_PMM |

                 POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR |

                 POWERPC_FLAG_VSX | POWERPC_FLAG_TM;

    pcc->l1_dcache_size = 0x8000;

    pcc->l1_icache_size = 0x8000;

    pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr;

}


int cpu_get_dump_info(ArchDumpInfo *info,

                      const GuestPhysBlockList *guest_phys_blocks)

{

    bool lma = false;

    GuestPhysBlock *block;

#ifdef TARGET_X86_64

    X86CPU *first_x86_cpu = X86_CPU(first_cpu);

    lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK);

#endif

    if (lma) {

        info->d_machine = EM_X86_64;

    } else {

        info->d_machine = EM_386;

    }

    info->d_endian = ELFDATA2LSB;

    if (lma) {

        info->d_class = ELFCLASS64;

    } else {

        info->d_class = ELFCLASS32;

        QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) {

            if (block->target_end > UINT_MAX) {

                /* The memory size is greater than 4G */

                info->d_class = ELFCLASS64;

                break;

            }

        }

    }

    return 0;

}


static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret)

{

    if (ret && !monitor_has_error(mon)) {

        /*

         * If it returns failure, it must have passed on error.

         *

         * Action: Report an internal error to the client if in QMP.

         */

        if (monitor_ctrl_mode(mon)) {

            qerror_report(QERR_UNDEFINED_ERROR);

        }

        MON_DEBUG("command '%s' returned failure but did not pass an error\n",

                  cmd->name);

    }

#ifdef CONFIG_DEBUG_MONITOR

    if (!ret && monitor_has_error(mon)) {

        /*

         * If it returns success, it must not have passed an error.

         *

         * Action: Report the passed error to the client.

         */

        MON_DEBUG("command '%s' returned success but passed an error\n",

                  cmd->name);

    }

    if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) {

        /*

         * Handlers should not call Monitor print functions.

         *

         * Action: Ignore them in QMP.

         *

         * (XXX: we don't check any 'info' or 'query' command here

         * because the user print function _is_ called by do_info(), hence

         * we will trigger this check. This problem will go away when we

         * make 'query' commands real and kill do_info())

         */

        MON_DEBUG("command '%s' called print functions %d time(s)\n",

                  cmd->name, mon_print_count_get(mon));

    }

#endif

}


char* qdev_get_fw_dev_path(DeviceState *dev)

{

    char path[128];

    int l;

    l = qdev_get_fw_dev_path_helper(dev, path, 128);

    path[l-1] = '\0';

    return strdup(path);

}


static ssize_t drop_sync(QIOChannel *ioc, size_t size)

{

    ssize_t ret, dropped = size;

    char small[1024];

    char *buffer;

    buffer = sizeof(small) < size ? small : g_malloc(MIN(65536, size));

    while (size > 0) {

        ret = read_sync(ioc, buffer, MIN(65536, size));

        if (ret < 0) {

            goto cleanup;

        }

        assert(ret <= size);

        size -= ret;

    }

    ret = dropped;

 cleanup:

    if (buffer != small) {

        g_free(buffer);

    }

    return ret;

}


static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,

        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,

        BlockCompletionFunc *cb, void *opaque)

{

    return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0);

}


static int seek_frame_generic(AVFormatContext *s,

                                 int stream_index, int64_t timestamp, int flags)

{

    int index;

    int64_t ret;

    AVStream *st;

    AVIndexEntry *ie;

    st = s->streams[stream_index];

    index = av_index_search_timestamp(st, timestamp, flags);

    if(index < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)

        return -1;

    if(index < 0 || index==st->nb_index_entries-1){

        AVPacket pkt;

        int nonkey=0;

        if(st->nb_index_entries){

            assert(st->index_entries);

            ie= &st->index_entries[st->nb_index_entries-1];

            if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)

                return ret;

            ff_update_cur_dts(s, st, ie->timestamp);

        }else{

            if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0)

                return ret;

        }

        for (;;) {

            int read_status;

            do{

                read_status = av_read_frame(s, &pkt);

            } while (read_status == AVERROR(EAGAIN));

            if (read_status < 0)

                break;

            av_free_packet(&pkt);

            if(stream_index == pkt.stream_index && pkt.dts > timestamp){

                if(pkt.flags & AV_PKT_FLAG_KEY)

                    break;

                if(nonkey++ > 1000){

                    av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey);

                    break;

                }

            }

        }

        index = av_index_search_timestamp(st, timestamp, flags);

    }

    if (index < 0)

        return -1;

    ff_read_frame_flush(s);

    AV_NOWARN_DEPRECATED(

    if (s->iformat->read_seek){

        if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0)

            return 0;

    }

    )

    ie = &st->index_entries[index];

    if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0)

        return ret;

    ff_update_cur_dts(s, st, ie->timestamp);

    return 0;

}


static void dvbsub_parse_page_segment(AVCodecContext *avctx,

                                        const uint8_t *buf, int buf_size)

{

    DVBSubContext *ctx = avctx->priv_data;

    DVBSubRegionDisplay *display;

    DVBSubRegionDisplay *tmp_display_list, **tmp_ptr;

    const uint8_t *buf_end = buf + buf_size;

    int region_id;

    int page_state;

    if (buf_size < 1)

        return;

    ctx->time_out = *buf++;

    page_state = ((*buf++) >> 2) & 3;

    av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state);

    if (page_state == 2) {

        delete_state(ctx);

    }

    tmp_display_list = ctx->display_list;

    ctx->display_list = NULL;

    ctx->display_list_size = 0;

    while (buf + 5 < buf_end) {

        region_id = *buf++;

        buf += 1;

        display = tmp_display_list;

        tmp_ptr = &tmp_display_list;

        while (display && display->region_id != region_id) {

            tmp_ptr = &display->next;

            display = display->next;

        }

        if (!display)

            display = av_mallocz(sizeof(DVBSubRegionDisplay));

        display->region_id = region_id;

        display->x_pos = AV_RB16(buf);

        buf += 2;

        display->y_pos = AV_RB16(buf);

        buf += 2;

        *tmp_ptr = display->next;

        display->next = ctx->display_list;

        ctx->display_list = display;

        ctx->display_list_size++;

        av_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos);

    }

    while (tmp_display_list) {

        display = tmp_display_list;

        tmp_display_list = display->next;

        av_free(display);

    }

}


static void test_qemu_strtoul_negative(void)

{

    const char *str = "  \t -321";

    char f = 'X';

    const char *endptr = &f;

    unsigned long res = 999;

    int err;

    err = qemu_strtoul(str, &endptr, 0, &res);

    g_assert_cmpint(err, ==, 0);

    g_assert_cmpint(res, ==, -321ul);

    g_assert(endptr == str + strlen(str));

}


static int is_cpuid_supported(void)

{

    return 1;

}


void vnc_display_init(const char *id)

{

    VncDisplay *vs;

    if (vnc_display_find(id) != NULL) {

        return;

    }

    vs = g_malloc0(sizeof(*vs));

    vs->id = strdup(id);

    QTAILQ_INSERT_TAIL(&vnc_displays, vs, next);

    vs->lsock = -1;

#ifdef CONFIG_VNC_WS

    vs->lwebsock = -1;

#endif

    QTAILQ_INIT(&vs->clients);

    vs->expires = TIME_MAX;

    if (keyboard_layout) {

        trace_vnc_key_map_init(keyboard_layout);

        vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout);

    } else {

        vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us");

    }

    if (!vs->kbd_layout)

        exit(1);

    qemu_mutex_init(&vs->mutex);

    vnc_start_worker_thread();

    vs->dcl.ops = &dcl_ops;

    register_displaychangelistener(&vs->dcl);

}


static int get_key(const char **ropts, const char *delim, char *key, unsigned key_size)

{

    unsigned key_pos = 0;

    const char *opts = *ropts;

    opts += strspn(opts, WHITESPACES);

    while (is_key_char(*opts)) {

        key[key_pos++] = *opts;

        if (key_pos == key_size)

            key_pos--;

        (opts)++;

    }

    opts += strspn(opts, WHITESPACES);

    if (!*opts || !strchr(delim, *opts))

        return AVERROR(EINVAL);

    opts++;

    key[key_pos++] = 0;

    if (key_pos == key_size)

        key[key_pos - 4] = key[key_pos - 3] = key[key_pos - 2] = '.';

    *ropts = opts;

    return 0;

}


static void expand_timestamps(void *log, struct sbg_script *s)

{

    int i, nb_rel = 0;

    int64_t now, cur_ts, delta = 0;

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

        nb_rel += s->tseq[i].ts.type == 'N';

    if (nb_rel == s->nb_tseq) {

        /* All ts are relative to NOW: consider NOW = 0 */

        now = 0;

        if (s->start_ts != AV_NOPTS_VALUE)

            av_log(log, AV_LOG_WARNING,

                   "Start time ignored in a purely relative script.\n");

    } else if (nb_rel == 0 && s->start_ts != AV_NOPTS_VALUE ||

               s->opt_start_at_first) {

        /* All ts are absolute and start time is specified */

        if (s->start_ts == AV_NOPTS_VALUE)

            s->start_ts = s->tseq[0].ts.t;

        now = s->start_ts;

    } else {

        /* Mixed relative/absolute ts: expand */

        time_t now0;

        struct tm *tm, tmpbuf;

        av_log(log, AV_LOG_WARNING,

               "Scripts with mixed absolute and relative timestamps can give "

               "unexpected results (pause, seeking, time zone change).\n");

#undef time

        time(&now0);

        tm = localtime_r(&now0, &tmpbuf);

        now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec :

                   now0 % DAY;

        av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n",

               (int)(now / 3600), (int)(now / 60) % 60, (int)now % 60);

        now *= AV_TIME_BASE;

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

            if (s->tseq[i].ts.type == 'N') {

                s->tseq[i].ts.t += now;

                s->tseq[i].ts.type = 'T'; /* not necessary */

            }

        }

    }

    if (s->start_ts == AV_NOPTS_VALUE)

        s->start_ts = s->opt_start_at_first ? s->tseq[0].ts.t : now;

    s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration :

                AV_NOPTS_VALUE; /* may be overridden later by -E option */

    cur_ts = now;

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

        if (s->tseq[i].ts.t + delta < cur_ts)

            delta += DAY_TS;

        cur_ts = s->tseq[i].ts.t += delta;

    }

}


static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){

    heap_elem_t h[size];

    int up[2*size];

    int len[2*size];

    int offset, i, next;

    for(offset=1; ; offset<<=1){

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

            h[i].name = i;

            h[i].val = (stats[i] << 8) + offset;

        }

        for(i=size/2-1; i>=0; i--)

            heap_sift(h, i, size);

        for(next=size; next<size*2-1; next++){

            // merge the two smallest entries, and put it back in the heap

            uint64_t min1v = h[0].val;

            up[h[0].name] = next;

            h[0].val = INT64_MAX;

            heap_sift(h, 0, size);

            up[h[0].name] = next;

            h[0].name = next;

            h[0].val += min1v;

            heap_sift(h, 0, size);

        }

        len[2*size-2] = 0;

        for(i=2*size-3; i>=size; i--)

            len[i] = len[up[i]] + 1;

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

            dst[i] = len[up[i]] + 1;

            if(dst[i] > 32) break;

        }

        if(i==size) break;

    }

}


static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame)

{

    AVFilterContext *avctx = inlink->dst;

    AVFilterLink *outlink = avctx->outputs[0];

    ScaleVAAPIContext *ctx = avctx->priv;

    AVFrame *output_frame = NULL;

    VASurfaceID input_surface, output_surface;

    VAProcPipelineParameterBuffer params;

    VABufferID params_id;

    VAStatus vas;

    int err;

    av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n",

           av_get_pix_fmt_name(input_frame->format),

           input_frame->width, input_frame->height, input_frame->pts);

    if (ctx->va_context == VA_INVALID_ID)

        return AVERROR(EINVAL);

    input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3];

    av_log(ctx, AV_LOG_DEBUG, "Using surface %#x for scale input.\n",

           input_surface);

    output_frame = av_frame_alloc();

    if (!output_frame) {

        av_log(ctx, AV_LOG_ERROR, "Failed to allocate output frame.");

        err = AVERROR(ENOMEM);

        goto fail;

    }

    err = av_hwframe_get_buffer(ctx->output_frames_ref, output_frame, 0);

    if (err < 0) {

        av_log(ctx, AV_LOG_ERROR, "Failed to get surface for "

               "output: %d\n.", err);

    }

    output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3];

    av_log(ctx, AV_LOG_DEBUG, "Using surface %#x for scale output.\n",

           output_surface);

    memset(&params, 0, sizeof(params));

    params.surface = input_surface;

    params.surface_region = 0;

    params.surface_color_standard =

        vaapi_proc_colour_standard(input_frame->colorspace);

    params.output_region = 0;

    params.output_background_color = 0xff000000;

    params.output_color_standard = params.surface_color_standard;

    params.pipeline_flags = 0;

    params.filter_flags = VA_FILTER_SCALING_HQ;

    vas = vaBeginPicture(ctx->hwctx->display,

                         ctx->va_context, output_surface);

    if (vas != VA_STATUS_SUCCESS) {

        av_log(ctx, AV_LOG_ERROR, "Failed to attach new picture: "

               "%d (%s).\n", vas, vaErrorStr(vas));

        err = AVERROR(EIO);

        goto fail;

    }

    vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context,

                         VAProcPipelineParameterBufferType,

                         sizeof(params), 1, &params, &params_id);

    if (vas != VA_STATUS_SUCCESS) {

        av_log(ctx, AV_LOG_ERROR, "Failed to create parameter buffer: "

               "%d (%s).\n", vas, vaErrorStr(vas));

        err = AVERROR(EIO);

        goto fail_after_begin;

    }

    av_log(ctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n",

           params_id);

    vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context,

                          &params_id, 1);

    if (vas != VA_STATUS_SUCCESS) {

        av_log(ctx, AV_LOG_ERROR, "Failed to render parameter buffer: "

               "%d (%s).\n", vas, vaErrorStr(vas));

        err = AVERROR(EIO);

        goto fail_after_begin;

    }

    vas = vaEndPicture(ctx->hwctx->display, ctx->va_context);

    if (vas != VA_STATUS_SUCCESS) {

        av_log(ctx, AV_LOG_ERROR, "Failed to start picture processing: "

               "%d (%s).\n", vas, vaErrorStr(vas));

        err = AVERROR(EIO);

        goto fail_after_render;

    }

    if (ctx->hwctx->driver_quirks &

        AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) {

        vas = vaDestroyBuffer(ctx->hwctx->display, params_id);

        if (vas != VA_STATUS_SUCCESS) {

            av_log(ctx, AV_LOG_ERROR, "Failed to free parameter buffer: "

                   "%d (%s).\n", vas, vaErrorStr(vas));

            // And ignore.

        }

    }

    av_frame_copy_props(output_frame, input_frame);

    av_frame_free(&input_frame);

    av_log(ctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n",

           av_get_pix_fmt_name(output_frame->format),

           output_frame->width, output_frame->height, output_frame->pts);

    return ff_filter_frame(outlink, output_frame);

    // We want to make sure that if vaBeginPicture has been called, we also

    // call vaRenderPicture and vaEndPicture.  These calls may well fail or

    // do something else nasty, but once we're in this failure case there

    // isn't much else we can do.

fail_after_begin:

    vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_id, 1);

fail_after_render:

    vaEndPicture(ctx->hwctx->display, ctx->va_context);

fail:

    av_frame_free(&input_frame);

    av_frame_free(&output_frame);

    return err;

}


static int get_packet(URLContext *s, int for_header)

{

    RTMPContext *rt = s->priv_data;

    int ret;

    uint8_t *p;

    const uint8_t *next;

    uint32_t data_size;

    uint32_t ts, cts, pts=0;

    if (rt->state == STATE_STOPPED)

        return AVERROR_EOF;

    for (;;) {

        RTMPPacket rpkt = { 0 };

        if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt,

                                       rt->chunk_size, rt->prev_pkt[0])) <= 0) {

            if (ret == 0) {

                return AVERROR(EAGAIN);

            } else {

                return AVERROR(EIO);

            }

        }

        rt->bytes_read += ret;

        if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) {

            av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n");

            gen_bytes_read(s, rt, rpkt.timestamp + 1);

            rt->last_bytes_read = rt->bytes_read;

        }

        ret = rtmp_parse_result(s, rt, &rpkt);

        if (ret < 0) {//serious error in current packet

            ff_rtmp_packet_destroy(&rpkt);

            return -1;

        }

        if (rt->state == STATE_STOPPED) {

            ff_rtmp_packet_destroy(&rpkt);

            return AVERROR_EOF;

        }

        if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) {

            ff_rtmp_packet_destroy(&rpkt);

            return 0;

        }

        if (!rpkt.data_size || !rt->is_input) {

            ff_rtmp_packet_destroy(&rpkt);

            continue;

        }

        if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO ||

           (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) {

            ts = rpkt.timestamp;

            // generate packet header and put data into buffer for FLV demuxer

            rt->flv_off  = 0;

            rt->flv_size = rpkt.data_size + 15;

            rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size);

            bytestream_put_byte(&p, rpkt.type);

            bytestream_put_be24(&p, rpkt.data_size);

            bytestream_put_be24(&p, ts);

            bytestream_put_byte(&p, ts >> 24);

            bytestream_put_be24(&p, 0);

            bytestream_put_buffer(&p, rpkt.data, rpkt.data_size);

            bytestream_put_be32(&p, 0);

            ff_rtmp_packet_destroy(&rpkt);

            return 0;

        } else if (rpkt.type == RTMP_PT_METADATA) {

            // we got raw FLV data, make it available for FLV demuxer

            rt->flv_off  = 0;

            rt->flv_size = rpkt.data_size;

            rt->flv_data = av_realloc(rt->flv_data, rt->flv_size);

            /* rewrite timestamps */

            next = rpkt.data;

            ts = rpkt.timestamp;

            while (next - rpkt.data < rpkt.data_size - 11) {

                next++;

                data_size = bytestream_get_be24(&next);

                p=next;

                cts = bytestream_get_be24(&next);

                cts |= bytestream_get_byte(&next) << 24;

                if (pts==0)

                    pts=cts;

                ts += cts - pts;

                pts = cts;

                bytestream_put_be24(&p, ts);

                bytestream_put_byte(&p, ts >> 24);

                next += data_size + 3 + 4;

            }

            memcpy(rt->flv_data, rpkt.data, rpkt.data_size);

            ff_rtmp_packet_destroy(&rpkt);

            return 0;

        }

        ff_rtmp_packet_destroy(&rpkt);

    }

}


static void save_display_set(DVBSubContext *ctx)
{
    DVBSubRegion *region;
    DVBSubRegionDisplay *display;
    DVBSubCLUT *clut;
    uint32_t *clut_table;
    int x_pos, y_pos, width, height;
    int x, y, y_off, x_off;
    uint32_t *pbuf;
    char filename[32];
    static int fileno_index = 0;
    x_pos = -1;
    y_pos = -1;
    width = 0;
    height = 0;
    for (display = ctx->display_list; display; display = display->next) {
        region = get_region(ctx, display->region_id);
        if (x_pos == -1) {
            x_pos = display->x_pos;
            y_pos = display->y_pos;
            width = region->width;
            height = region->height;
        } else {
            if (display->x_pos < x_pos) {
                width += (x_pos - display->x_pos);
                x_pos = display->x_pos;
            }
            if (display->y_pos < y_pos) {
                height += (y_pos - display->y_pos);
                y_pos = display->y_pos;
            }
            if (display->x_pos + region->width > x_pos + width) {
                width = display->x_pos + region->width - x_pos;
            }
            if (display->y_pos + region->height > y_pos + height) {
                height = display->y_pos + region->height - y_pos;
            }
        }
    }
    if (x_pos >= 0) {
        pbuf = av_malloc(width * height * 4);
        for (display = ctx->display_list; display; display = display->next) {
            region = get_region(ctx, display->region_id);
            x_off = display->x_pos - x_pos;
            y_off = display->y_pos - y_pos;
            clut = get_clut(ctx, region->clut);
            if (!clut)
                clut = &default_clut;
            switch (region->depth) {
            case 2:
                clut_table = clut->clut4;
                break;
            case 8:
                clut_table = clut->clut256;
                break;
            case 4:
            default:
                clut_table = clut->clut16;
                break;
            }
            for (y = 0; y < region->height; y++) {
                for (x = 0; x < region->width; x++) {
                    pbuf[((y + y_off) * width) + x_off + x] =
                        clut_table[region->pbuf[y * region->width + x]];
                }
            }
        }
        snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index);
        png_save2(filename, pbuf, width, height);
        av_freep(&pbuf);
    }
    fileno_index++;
}


int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,

                   void *log_ctx)

{

    char *tail, color_string2[128];

    const ColorEntry *entry;

    int len, hex_offset = 0;

    if (color_string[0] == '#') {

        hex_offset = 1;

    } else if (!strncmp(color_string, "0x", 2))

        hex_offset = 2;

    if (slen < 0)

        slen = strlen(color_string);

    av_strlcpy(color_string2, color_string + hex_offset,

               FFMIN(slen-hex_offset+1, sizeof(color_string2)));

    if ((tail = strchr(color_string2, ALPHA_SEP)))

        *tail++ = 0;

    len = strlen(color_string2);

    rgba_color[3] = 255;

    if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {

        int rgba = av_get_random_seed();

        rgba_color[0] = rgba >> 24;

        rgba_color[1] = rgba >> 16;

        rgba_color[2] = rgba >> 8;

        rgba_color[3] = rgba;

    } else if (hex_offset ||

               strspn(color_string2, "0123456789ABCDEFabcdef") == len) {

        char *tail;

        unsigned int rgba = strtoul(color_string2, &tail, 16);

        if (*tail || (len != 6 && len != 8)) {

            av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2);

            return AVERROR(EINVAL);

        }

        if (len == 8) {

            rgba_color[3] = rgba;

            rgba >>= 8;

        }

        rgba_color[0] = rgba >> 16;

        rgba_color[1] = rgba >> 8;

        rgba_color[2] = rgba;

    } else {

        entry = bsearch(color_string2,

                        color_table,

                        FF_ARRAY_ELEMS(color_table),

                        sizeof(ColorEntry),

                        color_table_compare);

        if (!entry) {

            av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2);

            return AVERROR(EINVAL);

        }

        memcpy(rgba_color, entry->rgb_color, 3);

    }

    if (tail) {

        unsigned long int alpha;

        const char *alpha_string = tail;

        if (!strncmp(alpha_string, "0x", 2)) {

            alpha = strtoul(alpha_string, &tail, 16);

        } else {

            alpha = 255 * strtod(alpha_string, &tail);

        }

        if (tail == alpha_string || *tail || alpha > 255) {

            av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n",

                   alpha_string, color_string);

            return AVERROR(EINVAL);

        }

        rgba_color[3] = alpha;

    }

    return 0;

}


int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv)

{

    BusChild *kid;

    I2CSlaveClass *sc;

    I2CNode *node;

    if (address == 0x00) {

        /*

         * This is a broadcast, the current_devs will be all the devices of the

         * bus.

         */

        bus->broadcast = true;

    }

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

        DeviceState *qdev = kid->child;

        I2CSlave *candidate = I2C_SLAVE(qdev);

        if ((candidate->address == address) || (bus->broadcast)) {

            node = g_malloc(sizeof(struct I2CNode));

            node->elt = candidate;

            QLIST_INSERT_HEAD(&bus->current_devs, node, next);

            if (!bus->broadcast) {

                break;

            }

        }

    }

    if (QLIST_EMPTY(&bus->current_devs)) {

        return 1;

    }

    QLIST_FOREACH(node, &bus->current_devs, next) {

        sc = I2C_SLAVE_GET_CLASS(node->elt);

        /* If the bus is already busy, assume this is a repeated

           start condition.  */

        if (sc->event) {

            sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND);

        }

    }

    return 0;

}


void ff_MPV_encode_init_x86(MpegEncContext *s)

{

    int mm_flags = av_get_cpu_flags();

    const int dct_algo = s->avctx->dct_algo;

    if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) {

#if HAVE_MMX_INLINE

        if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX)

            s->dct_quantize = dct_quantize_MMX;

#endif

#if HAVE_MMXEXT_INLINE

        if (mm_flags & AV_CPU_FLAG_MMXEXT && HAVE_MMXEXT)

            s->dct_quantize = dct_quantize_MMX2;

#endif

#if HAVE_SSE2_INLINE

        if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE2)

            s->dct_quantize = dct_quantize_SSE2;

#endif

#if HAVE_SSSE3_INLINE

        if (mm_flags & AV_CPU_FLAG_SSSE3)

            s->dct_quantize = dct_quantize_SSSE3;

#endif

    }

}


static void smbios_build_type_1_fields(void)

{

    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str),

                         type1.manufacturer);

    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str),

                         type1.product);

    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str),

                         type1.version);

    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str),

                         type1.serial);

    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str),

                         type1.sku);

    smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str),

                         type1.family);

    if (qemu_uuid_set) {

        /* We don't encode the UUID in the "wire format" here because this

         * function is for legacy mode and needs to keep the guest ABI, and

         * because we don't know what's the SMBIOS version advertised by the

         * BIOS.

         */

        smbios_add_field(1, offsetof(struct smbios_type_1, uuid),

                         qemu_uuid, 16);

    }

}


static inline int mirror_clip_sectors(MirrorBlockJob *s,

                                      int64_t sector_num,

                                      int nb_sectors)

{

    return MIN(nb_sectors,

               s->bdev_length / BDRV_SECTOR_SIZE - sector_num);

}


static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value)

{

    uint32_t tag;

    uint32_t bufsize;

    uint32_t tot_len;

    size_t resplen;

    uint32_t tmp;

    value &= ~0xf;

    s->addr = value;

    tot_len = ldl_phys(&s->dma_as, value);

    /* @(addr + 4) : Buffer response code */

    value = s->addr + 8;

    while (value + 8 <= s->addr + tot_len) {

        tag = ldl_phys(&s->dma_as, value);

        bufsize = ldl_phys(&s->dma_as, value + 4);

        /* @(value + 8) : Request/response indicator */

        resplen = 0;

        switch (tag) {

        case 0x00000000: /* End tag */

            break;

        case 0x00000001: /* Get firmware revision */

            stl_phys(&s->dma_as, value + 12, 346337);

            resplen = 4;

            break;

        case 0x00010001: /* Get board model */

            qemu_log_mask(LOG_UNIMP,

                          "bcm2835_property: %x get board model NYI\n", tag);

            resplen = 4;

            break;

        case 0x00010002: /* Get board revision */

            qemu_log_mask(LOG_UNIMP,

                          "bcm2835_property: %x get board revision NYI\n", tag);

            resplen = 4;

            break;

        case 0x00010003: /* Get board MAC address */

            resplen = sizeof(s->macaddr.a);

            dma_memory_write(&s->dma_as, value + 12, s->macaddr.a, resplen);

            break;

        case 0x00010004: /* Get board serial */

            qemu_log_mask(LOG_UNIMP,

                          "bcm2835_property: %x get board serial NYI\n", tag);

            resplen = 8;

            break;

        case 0x00010005: /* Get ARM memory */

            /* base */

            stl_phys(&s->dma_as, value + 12, 0);

            /* size */

            stl_phys(&s->dma_as, value + 16, s->ram_size);

            resplen = 8;

            break;

        case 0x00028001: /* Set power state */

            /* Assume that whatever device they asked for exists,

             * and we'll just claim we set it to the desired state

             */

            tmp = ldl_phys(&s->dma_as, value + 16);

            stl_phys(&s->dma_as, value + 16, (tmp & 1));

            resplen = 8;

            break;

        /* Clocks */

        case 0x00030001: /* Get clock state */

            stl_phys(&s->dma_as, value + 16, 0x1);

            resplen = 8;

            break;

        case 0x00038001: /* Set clock state */

            qemu_log_mask(LOG_UNIMP,

                          "bcm2835_property: %x set clock state NYI\n", tag);

            resplen = 8;

            break;

        case 0x00030002: /* Get clock rate */

        case 0x00030004: /* Get max clock rate */

        case 0x00030007: /* Get min clock rate */

            switch (ldl_phys(&s->dma_as, value + 12)) {

            case 1: /* EMMC */

                stl_phys(&s->dma_as, value + 16, 50000000);

                break;

            case 2: /* UART */

                stl_phys(&s->dma_as, value + 16, 3000000);

                break;

            default:

                stl_phys(&s->dma_as, value + 16, 700000000);

                break;

            }

            resplen = 8;

            break;

        case 0x00038002: /* Set clock rate */

        case 0x00038004: /* Set max clock rate */

        case 0x00038007: /* Set min clock rate */

            qemu_log_mask(LOG_UNIMP,

                          "bcm2835_property: %x set clock rates NYI\n", tag);

            resplen = 8;

            break;

        /* Temperature */

        case 0x00030006: /* Get temperature */

            stl_phys(&s->dma_as, value + 16, 25000);

            resplen = 8;

            break;

        case 0x0003000A: /* Get max temperature */

            stl_phys(&s->dma_as, value + 16, 99000);

            resplen = 8;

            break;

        case 0x00060001: /* Get DMA channels */

            /* channels 2-5 */

            stl_phys(&s->dma_as, value + 12, 0x003C);

            resplen = 4;

            break;

        case 0x00050001: /* Get command line */

            resplen = 0;

            break;

        default:

            qemu_log_mask(LOG_GUEST_ERROR,

                          "bcm2835_property: unhandled tag %08x\n", tag);

            break;

        }

        if (tag == 0) {

            break;

        }

        stl_phys(&s->dma_as, value + 8, (1 << 31) | resplen);

        value += bufsize + 12;

    }

    /* Buffer response code */

    stl_phys(&s->dma_as, s->addr + 4, (1 << 31));

}


ObjectClass *object_class_dynamic_cast(ObjectClass *class,

                                       const char *typename)

{

    TypeImpl *target_type = type_get_by_name(typename);

    TypeImpl *type = class->type;

    ObjectClass *ret = NULL;

    if (type->num_interfaces && type_is_ancestor(target_type, type_interface)) {

        int found = 0;

        GSList *i;

        for (i = class->interfaces; i; i = i->next) {

            ObjectClass *target_class = i->data;

            if (type_is_ancestor(target_class->type, target_type)) {

                ret = target_class;

                found++;

            }

         }

        /* The match was ambiguous, don't allow a cast */

        if (found > 1) {

            ret = NULL;

        }

    } else if (type_is_ancestor(type, target_type)) {

        ret = class;

    }

    return ret;

}


static void sdhci_send_command(SDHCIState *s)

{

    SDRequest request;

    uint8_t response[16];

    int rlen;

    s->errintsts = 0;

    s->acmd12errsts = 0;

    request.cmd = s->cmdreg >> 8;

    request.arg = s->argument;

    DPRINT_L1("sending CMD%u ARG[0x%08x]\n", request.cmd, request.arg);

    rlen = sd_do_command(s->card, &request, response);

    if (s->cmdreg & SDHC_CMD_RESPONSE) {

        if (rlen == 4) {

            s->rspreg[0] = (response[0] << 24) | (response[1] << 16) |

                           (response[2] << 8)  |  response[3];

            s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0;

            DPRINT_L1("Response: RSPREG[31..0]=0x%08x\n", s->rspreg[0]);

        } else if (rlen == 16) {

            s->rspreg[0] = (response[11] << 24) | (response[12] << 16) |

                           (response[13] << 8) |  response[14];

            s->rspreg[1] = (response[7] << 24) | (response[8] << 16) |

                           (response[9] << 8)  |  response[10];

            s->rspreg[2] = (response[3] << 24) | (response[4] << 16) |

                           (response[5] << 8)  |  response[6];

            s->rspreg[3] = (response[0] << 16) | (response[1] << 8) |

                            response[2];

            DPRINT_L1("Response received:\n RSPREG[127..96]=0x%08x, RSPREG[95.."

                  "64]=0x%08x,\n RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x\n",

                  s->rspreg[3], s->rspreg[2], s->rspreg[1], s->rspreg[0]);

        } else {

            ERRPRINT("Timeout waiting for command response\n");

            if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) {

                s->errintsts |= SDHC_EIS_CMDTIMEOUT;

                s->norintsts |= SDHC_NIS_ERR;

            }

        }

        if ((s->norintstsen & SDHC_NISEN_TRSCMP) &&

            (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) {

            s->norintsts |= SDHC_NIS_TRSCMP;

        }

    } else if (rlen != 0 && (s->errintstsen & SDHC_EISEN_CMDIDX)) {

        s->errintsts |= SDHC_EIS_CMDIDX;

        s->norintsts |= SDHC_NIS_ERR;

    }

    if (s->norintstsen & SDHC_NISEN_CMDCMP) {

        s->norintsts |= SDHC_NIS_CMDCMP;

    }

    sdhci_update_irq(s);

    if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) {

        s->data_count = 0;

        sdhci_do_data_transfer(s);

    }

}


static void ss5_init(int ram_size, int vga_ram_size, int boot_device,

                       DisplayState *ds, const char **fd_filename, int snapshot,

                       const char *kernel_filename, const char *kernel_cmdline,

                       const char *initrd_filename, const char *cpu_model)

{

    if (cpu_model == NULL)

        cpu_model = "Fujitsu MB86904";

    sun4m_common_init(ram_size, boot_device, ds, kernel_filename,

                      kernel_cmdline, initrd_filename, cpu_model,

                      0);

}


const char *qemu_opt_get(QemuOpts *opts, const char *name)

{

    QemuOpt *opt = qemu_opt_find(opts, name);

    if (!opt) {

        const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name);

        if (desc && desc->def_value_str) {

            return desc->def_value_str;

        }

    }

    return opt ? opt->str : NULL;

}


void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)

{

    QEMUTimer **pt, *t;

    qemu_del_timer(ts);

    /* add the timer in the sorted list */

    /* NOTE: this code must be signal safe because

       qemu_timer_expired() can be called from a signal. */

    pt = &active_timers[ts->clock->type];

    for(;;) {

        t = *pt;

        if (!t)

            break;

        if (t->expire_time > expire_time)

            break;

        pt = &t->next;

    }

    ts->expire_time = expire_time;

    ts->next = *pt;

    *pt = ts;

    /* Rearm if necessary  */

    if (pt == &active_timers[ts->clock->type]) {

        if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) {

            qemu_rearm_alarm_timer(alarm_timer);

        }

        /* Interrupt execution to force deadline recalculation.  */

        if (use_icount)

            qemu_notify_event();

    }

}


static void qemu_system_suspend(void)

{

    pause_all_vcpus();

    notifier_list_notify(&suspend_notifiers, NULL);

    runstate_set(RUN_STATE_SUSPENDED);

    monitor_protocol_event(QEVENT_SUSPEND, NULL);

    is_suspended = true;

}


static void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0,

                                 const uint16_t *ubuf0, const uint16_t *ubuf1,

                                 const uint16_t *vbuf0, const uint16_t *vbuf1,

                                 const uint16_t *abuf0, uint8_t *dest,

                                 int dstW, int uvalpha, enum PixelFormat dstFormat,

                                 int flags, int y)

{

    const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1

    if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster

        __asm__ volatile(

            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

            "mov        %4, %%"REG_b"               \n\t"

            "push %%"REG_BP"                        \n\t"

            YSCALEYUV2RGB1(%%REGBP, %5)

            "pxor    %%mm7, %%mm7                   \n\t"

            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

            "paddusb "BLUE_DITHER"(%5), %%mm2      \n\t"

            "paddusb "GREEN_DITHER"(%5), %%mm4      \n\t"

            "paddusb "RED_DITHER"(%5), %%mm5      \n\t"

#endif

            WRITERGB16(%%REGb, 8280(%5), %%REGBP)

            "pop %%"REG_BP"                         \n\t"

            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

            :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

               "a" (&c->redDither)

        );

    } else {

        __asm__ volatile(

            "mov %%"REG_b", "ESP_OFFSET"(%5)        \n\t"

            "mov        %4, %%"REG_b"               \n\t"

            "push %%"REG_BP"                        \n\t"

            YSCALEYUV2RGB1b(%%REGBP, %5)

            "pxor    %%mm7, %%mm7                   \n\t"

            /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */

#ifdef DITHER1XBPP

            "paddusb "BLUE_DITHER"(%5), %%mm2      \n\t"

            "paddusb "GREEN_DITHER"(%5), %%mm4      \n\t"

            "paddusb "RED_DITHER"(%5), %%mm5      \n\t"

#endif

            WRITERGB16(%%REGb, 8280(%5), %%REGBP)

            "pop %%"REG_BP"                         \n\t"

            "mov "ESP_OFFSET"(%5), %%"REG_b"        \n\t"

            :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest),

               "a" (&c->redDither)

        );

    }

}


static void numa_node_parse_cpus(int nodenr, const char *cpus)

{

    char *endptr;

    unsigned long long value, endvalue;

    value = strtoull(cpus, &endptr, 10);

    if (*endptr == '-') {

        endvalue = strtoull(endptr+1, &endptr, 10);

    } else {

        endvalue = value;

    }

    if (!(endvalue < MAX_CPUMASK_BITS)) {

        endvalue = MAX_CPUMASK_BITS - 1;

        fprintf(stderr,

            "A max of %d CPUs are supported in a guest\n",

             MAX_CPUMASK_BITS);

    }

    bitmap_set(node_cpumask[nodenr], value, endvalue-value+1);

}


static void icount_dummy_timer(void *opaque)

{

    (void)opaque;

}


static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n)

{

    if (n < 32) {

        env->fpr[n] = ldfq_p(mem_buf);

        return 8;

    }

    if (n == 32) {

        /* FPSCR not implemented  */

        return 4;

    }

    return 0;

}


static inline void decode(DisasContext *dc)

{

    uint32_t ir;

    int i;

    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) {

        tcg_gen_debug_insn_start(dc->pc);

    }

    dc->ir = ir = ldl_code(dc->pc);

    LOG_DIS("%8.8x\t", dc->ir);

    /* try guessing 'empty' instruction memory, although it may be a valid

     * instruction sequence (eg. srui r0, r0, 0) */

    if (dc->ir) {

        dc->nr_nops = 0;

    } else {

        LOG_DIS("nr_nops=%d\t", dc->nr_nops);

        dc->nr_nops++;

        if (dc->nr_nops > 4) {

            cpu_abort(dc->env, "fetching nop sequence\n");

        }

    }

    dc->opcode = EXTRACT_FIELD(ir, 26, 31);

    dc->imm5 = EXTRACT_FIELD(ir, 0, 4);

    dc->imm16 = EXTRACT_FIELD(ir, 0, 15);

    dc->imm26 = EXTRACT_FIELD(ir, 0, 25);

    dc->csr = EXTRACT_FIELD(ir, 21, 25);

    dc->r0 = EXTRACT_FIELD(ir, 21, 25);

    dc->r1 = EXTRACT_FIELD(ir, 16, 20);

    dc->r2 = EXTRACT_FIELD(ir, 11, 15);

    /* bit 31 seems to indicate insn type.  */

    if (ir & (1 << 31)) {

        dc->format = OP_FMT_RR;

    } else {

        dc->format = OP_FMT_RI;

    }

    /* Large switch for all insns.  */

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

        if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) {

            decinfo[i].dec(dc);

            return;

        }

    }

    cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode);

}


void memory_region_init_iommu(MemoryRegion *mr,

                              Object *owner,

                              const MemoryRegionIOMMUOps *ops,

                              const char *name,

                              uint64_t size)

{

    memory_region_init(mr, owner, name, size);

    mr->iommu_ops = ops,

    mr->terminates = true;  /* then re-forwards */

    notifier_list_init(&mr->iommu_notify);

}


void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0)

{

#ifndef CONFIG_USER_ONLY

    if (reg < 4) {

        if (hw_breakpoint_enabled(env->dr[7], reg)

            && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) {

            hw_breakpoint_remove(env, reg);

            env->dr[reg] = t0;

            hw_breakpoint_insert(env, reg);

        } else {

            env->dr[reg] = t0;

        }

    } else if (reg == 7) {

        cpu_x86_update_dr7(env, t0);

    } else {

        env->dr[reg] = t0;

    }

#endif

}


QDict *qdict_new(void)

{

    QDict *qdict;

    qdict = g_malloc0(sizeof(*qdict));

    QOBJECT_INIT(qdict, &qdict_type);

    return qdict;

}


int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,

                             unsigned int *bytes, uint64_t *cluster_offset)

{

    BDRVQcow2State *s = bs->opaque;

    unsigned int l2_index;

    uint64_t l1_index, l2_offset, *l2_table;

    int l1_bits, c;

    unsigned int offset_in_cluster;

    uint64_t bytes_available, bytes_needed, nb_clusters;

    int ret;

    offset_in_cluster = offset_into_cluster(s, offset);

    bytes_needed = (uint64_t) *bytes + offset_in_cluster;

    l1_bits = s->l2_bits + s->cluster_bits;

    /* compute how many bytes there are between the start of the cluster

     * containing offset and the end of the l1 entry */

    bytes_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1))

                    + offset_in_cluster;

    if (bytes_needed > bytes_available) {

        bytes_needed = bytes_available;

    }

    *cluster_offset = 0;

    /* seek to the l2 offset in the l1 table */

    l1_index = offset >> l1_bits;

    if (l1_index >= s->l1_size) {

        ret = QCOW2_CLUSTER_UNALLOCATED;

        goto out;

    }

    l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK;

    if (!l2_offset) {

        ret = QCOW2_CLUSTER_UNALLOCATED;

        goto out;

    }

    if (offset_into_cluster(s, l2_offset)) {

        qcow2_signal_corruption(bs, true, -1, -1, "L2 table offset %#" PRIx64

                                " unaligned (L1 index: %#" PRIx64 ")",

                                l2_offset, l1_index);

        return -EIO;

    }

    /* load the l2 table in memory */

    ret = l2_load(bs, l2_offset, &l2_table);

    if (ret < 0) {

        return ret;

    }

    /* find the cluster offset for the given disk offset */

    l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1);

    *cluster_offset = be64_to_cpu(l2_table[l2_index]);

    nb_clusters = size_to_clusters(s, bytes_needed);

    /* bytes_needed <= *bytes + offset_in_cluster, both of which are unsigned

     * integers; the minimum cluster size is 512, so this assertion is always

     * true */

    assert(nb_clusters <= INT_MAX);

    ret = qcow2_get_cluster_type(*cluster_offset);

    switch (ret) {

    case QCOW2_CLUSTER_COMPRESSED:

        /* Compressed clusters can only be processed one by one */

        c = 1;

        *cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK;

        break;

    case QCOW2_CLUSTER_ZERO:

        if (s->qcow_version < 3) {

            qcow2_signal_corruption(bs, true, -1, -1, "Zero cluster entry found"

                                    " in pre-v3 image (L2 offset: %#" PRIx64

                                    ", L2 index: %#x)", l2_offset, l2_index);

            ret = -EIO;

            goto fail;

        }

        c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index],

                                              QCOW2_CLUSTER_ZERO);

        *cluster_offset = 0;

        break;

    case QCOW2_CLUSTER_UNALLOCATED:

        /* how many empty clusters ? */

        c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index],

                                              QCOW2_CLUSTER_UNALLOCATED);

        *cluster_offset = 0;

        break;

    case QCOW2_CLUSTER_NORMAL:

        /* how many allocated clusters ? */

        c = count_contiguous_clusters(nb_clusters, s->cluster_size,

                &l2_table[l2_index], QCOW_OFLAG_ZERO);

        *cluster_offset &= L2E_OFFSET_MASK;

        if (offset_into_cluster(s, *cluster_offset)) {

            qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset %#"

                                    PRIx64 " unaligned (L2 offset: %#" PRIx64

                                    ", L2 index: %#x)", *cluster_offset,

                                    l2_offset, l2_index);

            ret = -EIO;

            goto fail;

        }

        break;

    default:

        abort();

    }

    qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);

    bytes_available = (int64_t)c * s->cluster_size;

out:

    if (bytes_available > bytes_needed) {

        bytes_available = bytes_needed;

    }

    /* bytes_available <= bytes_needed <= *bytes + offset_in_cluster;

     * subtracting offset_in_cluster will therefore definitely yield something

     * not exceeding UINT_MAX */

    assert(bytes_available - offset_in_cluster <= UINT_MAX);

    *bytes = bytes_available - offset_in_cluster;

    return ret;

fail:

    qcow2_cache_put(bs, s->l2_table_cache, (void **)&l2_table);

    return ret;

}


mips_mipssim_init (ram_addr_t ram_size, int vga_ram_size,

                   const char *boot_device, DisplayState *ds,

                   const char *kernel_filename, const char *kernel_cmdline,

                   const char *initrd_filename, const char *cpu_model)

{

    char buf[1024];

    unsigned long bios_offset;

    CPUState *env;

    int bios_size;

    /* Init CPUs. */

    if (cpu_model == NULL) {

#ifdef TARGET_MIPS64

        cpu_model = "5Kf";

#else

        cpu_model = "24Kf";

#endif

    }

    env = cpu_init(cpu_model);

    if (!env) {

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

        exit(1);

    }

    qemu_register_reset(main_cpu_reset, env);

    /* Allocate RAM. */

    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);

    /* Load a BIOS / boot exception handler image. */

    bios_offset = ram_size + vga_ram_size;

    if (bios_name == NULL)

        bios_name = BIOS_FILENAME;

    snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);

    bios_size = load_image(buf, phys_ram_base + bios_offset);

    if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {

        /* Bail out if we have neither a kernel image nor boot vector code. */

        fprintf(stderr,

                "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",

                buf);

        exit(1);

    } else {

        /* Map the BIOS / boot exception handler. */

        cpu_register_physical_memory(0x1fc00000LL,

                                     bios_size, bios_offset | IO_MEM_ROM);

        /* We have a boot vector start address. */

        env->active_tc.PC = (target_long)(int32_t)0xbfc00000;

    }

    if (kernel_filename) {

        loaderparams.ram_size = ram_size;

        loaderparams.kernel_filename = kernel_filename;

        loaderparams.kernel_cmdline = kernel_cmdline;

        loaderparams.initrd_filename = initrd_filename;

        load_kernel(env);

    }

    /* Init CPU internal devices. */

    cpu_mips_irq_init_cpu(env);

    cpu_mips_clock_init(env);

    /* Register 64 KB of ISA IO space at 0x1fd00000. */

    isa_mmio_init(0x1fd00000, 0x00010000);

    /* A single 16450 sits at offset 0x3f8. It is attached to

       MIPS CPU INT2, which is interrupt 4. */

    if (serial_hds[0])

        serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]);

    if (nd_table[0].vlan) {

        if (nd_table[0].model == NULL

            || strcmp(nd_table[0].model, "mipsnet") == 0) {

            /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */

            mipsnet_init(0x4200, env->irq[2], &nd_table[0]);

        } else if (strcmp(nd_table[0].model, "?") == 0) {

            fprintf(stderr, "qemu: Supported NICs: mipsnet\n");

            exit (1);

        } else {

            fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model);

            exit (1);

        }

    }

}


static inline void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused)

{

#if COMPILE_TEMPLATE_MMX

    __asm__ volatile(

        "mov                    %0, %%"REG_a"       \n\t"

        "1:                                         \n\t"

        "movq    (%1, %%"REG_a",2), %%mm0           \n\t"

        "movq   8(%1, %%"REG_a",2), %%mm1           \n\t"

        "movq    (%2, %%"REG_a",2), %%mm2           \n\t"

        "movq   8(%2, %%"REG_a",2), %%mm3           \n\t"

        "psrlw                  $8, %%mm0           \n\t"

        "psrlw                  $8, %%mm1           \n\t"

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

        "psrlw                  $8, %%mm3           \n\t"

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

        "packuswb            %%mm3, %%mm2           \n\t"

        "movq                %%mm0, (%3, %%"REG_a") \n\t"

        "movq                %%mm2, (%4, %%"REG_a") \n\t"

        "add                    $8, %%"REG_a"       \n\t"

        " js                    1b                  \n\t"

        : : "g" ((x86_reg)-width), "r" (src1+width*2), "r" (src2+width*2), "r" (dstU+width), "r" (dstV+width)

        : "%"REG_a

    );

#else

    int i;

    // FIXME I don't think this code is right for YUV444/422, since then h is not subsampled so

    // we need to skip each second pixel. Same for BEToUV.

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

        dstU[i]= src1[2*i + 1];

        dstV[i]= src2[2*i + 1];

    }

#endif

}


static target_phys_addr_t intel_hda_addr(uint32_t lbase, uint32_t ubase)

{

    target_phys_addr_t addr;

    addr = ((uint64_t)ubase << 32) | lbase;

    return addr;

}