static uint32_t arm_timer_read(void *opaque, target_phys_addr_t offset)

{

    arm_timer_state *s = (arm_timer_state *)opaque;

    switch (offset >> 2) {

    case 0: /* TimerLoad */

    case 6: /* TimerBGLoad */

        return s->limit;

    case 1: /* TimerValue */

        return ptimer_get_count(s->timer);

    case 2: /* TimerControl */

        return s->control;

    case 4: /* TimerRIS */

        return s->int_level;

    case 5: /* TimerMIS */

        if ((s->control & TIMER_CTRL_IE) == 0)

            return 0;

        return s->int_level;

    default:

        hw_error("%s: Bad offset %x\n", __func__, (int)offset);

        return 0;

    }

}


char *string_output_get_string(StringOutputVisitor *sov)

{

    char *string = g_string_free(sov->string, false);

    sov->string = NULL;

    return string;

}


static void css_init(void)

{

    QTAILQ_INIT(&channel_subsys.pending_crws);

    channel_subsys.sei_pending = false;

    channel_subsys.do_crw_mchk = true;

    channel_subsys.crws_lost = false;

    channel_subsys.chnmon_active = false;

    QTAILQ_INIT(&channel_subsys.io_adapters);

    QTAILQ_INIT(&channel_subsys.indicator_addresses);

}


static void test_validate_struct(TestInputVisitorData *data,

                                  const void *unused)

{

    TestStruct *p = NULL;

    Visitor *v;

    v = validate_test_init(data, "{ 'integer': -42, 'boolean': true, 'string': 'foo' }");

    visit_type_TestStruct(v, NULL, &p, &error_abort);

    g_free(p->string);

    g_free(p);

}


static uint32_t ecc_mem_readw(void *opaque, target_phys_addr_t addr)

{

    printf("ECC: Unsupported read 0x" TARGET_FMT_plx " 0000\n", addr);

    return 0;

}


static av_cold int libssh_authentication(LIBSSHContext *libssh, const char *user, const char *password)

{

    int authorized = 0;

    int auth_methods;

    if (user)

        ssh_options_set(libssh->session, SSH_OPTIONS_USER, user);

    if (ssh_userauth_none(libssh->session, NULL) == SSH_AUTH_SUCCESS)

        return 0;

    auth_methods = ssh_userauth_list(libssh->session, NULL);

    if (auth_methods & SSH_AUTH_METHOD_PUBLICKEY) {

        if (libssh->priv_key) {

            ssh_string pub_key;

            ssh_private_key priv_key;

            int type;

            if (!ssh_try_publickey_from_file(libssh->session, libssh->priv_key, &pub_key, &type)) {

                priv_key = privatekey_from_file(libssh->session, libssh->priv_key, type, password);

                if (ssh_userauth_pubkey(libssh->session, NULL, pub_key, priv_key) == SSH_AUTH_SUCCESS) {

                    av_log(libssh, AV_LOG_DEBUG, "Authentication successful with selected private key.\n");

                    authorized = 1;

                }

            } else {

                av_log(libssh, AV_LOG_DEBUG, "Invalid key is provided.\n");

                return AVERROR(EACCES);

            }

        } else if (ssh_userauth_autopubkey(libssh->session, password) == SSH_AUTH_SUCCESS) {

            av_log(libssh, AV_LOG_DEBUG, "Authentication successful with auto selected key.\n");

            authorized = 1;

        }

    }

    if (!authorized && (auth_methods & SSH_AUTH_METHOD_PASSWORD)) {

        if (ssh_userauth_password(libssh->session, NULL, password) == SSH_AUTH_SUCCESS) {

            av_log(libssh, AV_LOG_DEBUG, "Authentication successful with password.\n");

            authorized = 1;

        }

    }

    if (!authorized) {

        av_log(libssh, AV_LOG_ERROR, "Authentication failed.\n");

        return AVERROR(EACCES);

    }

    return 0;

}


int gif_write(ByteIOContext *pb, AVImageInfo *info)

{

    gif_image_write_header(pb, info->width, info->height,

                           (uint32_t *)info->pict.data[1]);

    gif_image_write_image(pb, 0, 0, info->width, info->height,

                          info->pict.data[0], info->pict.linesize[0],

                          PIX_FMT_PAL8);

    put_byte(pb, 0x3b);

    put_flush_packet(pb);

    return 0;

}


void monitor_init(CharDriverState *chr, int flags)

{

    static int is_first_init = 1;

    Monitor *mon;

    if (is_first_init) {

        key_timer = qemu_new_timer(vm_clock, release_keys, NULL);

        is_first_init = 0;

    }

    mon = qemu_mallocz(sizeof(*mon));

    mon->chr = chr;

    mon->flags = flags;

    if (flags & MONITOR_USE_READLINE) {

        mon->rs = readline_init(mon, monitor_find_completion);

        monitor_read_command(mon, 0);

    }

    qemu_chr_add_handlers(chr, monitor_can_read, monitor_read, monitor_event,

                          mon);

    LIST_INSERT_HEAD(&mon_list, mon, entry);

    if (!cur_mon || (flags & MONITOR_IS_DEFAULT))

        cur_mon = mon;

}


static void dsound_write_sample (HWVoiceOut *hw, uint8_t *dst, int dst_len)

{

    int src_len1 = dst_len;

    int src_len2 = 0;

    int pos = hw->rpos + dst_len;

    st_sample_t *src1 = hw->mix_buf + hw->rpos;

    st_sample_t *src2 = NULL;

    if (pos > hw->samples) {

        src_len1 = hw->samples - hw->rpos;

        src2 = hw->mix_buf;

        src_len2 = dst_len - src_len1;

        pos = src_len2;

    }

    if (src_len1) {

        hw->clip (dst, src1, src_len1);

    }

    if (src_len2) {

        dst = advance (dst, src_len1 << hw->info.shift);

        hw->clip (dst, src2, src_len2);

    }

    hw->rpos = pos % hw->samples;

}


static void n8x0_init(QEMUMachineInitArgs *args,

                      struct arm_boot_info *binfo, int model)

{

    MemoryRegion *sysmem = get_system_memory();

    struct n800_s *s = (struct n800_s *) g_malloc0(sizeof(*s));

    int sdram_size = binfo->ram_size;

    s->mpu = omap2420_mpu_init(sysmem, sdram_size, args->cpu_model);

    /* Setup peripherals

     *

     * Believed external peripherals layout in the N810:

     * (spi bus 1)

     *   tsc2005

     *   lcd_mipid

     * (spi bus 2)

     *   Conexant cx3110x (WLAN)

     *   optional: pc2400m (WiMAX)

     * (i2c bus 0)

     *   TLV320AIC33 (audio codec)

     *   TCM825x (camera by Toshiba)

     *   lp5521 (clever LEDs)

     *   tsl2563 (light sensor, hwmon, model 7, rev. 0)

     *   lm8323 (keypad, manf 00, rev 04)

     * (i2c bus 1)

     *   tmp105 (temperature sensor, hwmon)

     *   menelaus (pm)

     * (somewhere on i2c - maybe N800-only)

     *   tea5761 (FM tuner)

     * (serial 0)

     *   GPS

     * (some serial port)

     *   csr41814 (Bluetooth)

     */

    n8x0_gpio_setup(s);

    n8x0_nand_setup(s);

    n8x0_i2c_setup(s);

    if (model == 800)

        n800_tsc_kbd_setup(s);

    else if (model == 810) {

        n810_tsc_setup(s);

        n810_kbd_setup(s);

    }

    n8x0_spi_setup(s);

    n8x0_dss_setup(s);

    n8x0_cbus_setup(s);

    n8x0_uart_setup(s);

    if (usb_enabled(false)) {

        n8x0_usb_setup(s);

    }

    if (args->kernel_filename) {

        /* Or at the linux loader.  */

        binfo->kernel_filename = args->kernel_filename;

        binfo->kernel_cmdline = args->kernel_cmdline;

        binfo->initrd_filename = args->initrd_filename;

        arm_load_kernel(s->mpu->cpu, binfo);

        qemu_register_reset(n8x0_boot_init, s);

    }

    if (option_rom[0].name &&

        (args->boot_device[0] == 'n' || !args->kernel_filename)) {

        uint8_t nolo_tags[0x10000];

        /* No, wait, better start at the ROM.  */

        s->mpu->cpu->env.regs[15] = OMAP2_Q2_BASE + 0x400000;

        /* This is intended for loading the `secondary.bin' program from

         * Nokia images (the NOLO bootloader).  The entry point seems

         * to be at OMAP2_Q2_BASE + 0x400000.

         *

         * The `2nd.bin' files contain some kind of earlier boot code and

         * for them the entry point needs to be set to OMAP2_SRAM_BASE.

         *

         * The code above is for loading the `zImage' file from Nokia

         * images.  */

        load_image_targphys(option_rom[0].name,

                            OMAP2_Q2_BASE + 0x400000,

                            sdram_size - 0x400000);

        n800_setup_nolo_tags(nolo_tags);

        cpu_physical_memory_write(OMAP2_SRAM_BASE, nolo_tags, 0x10000);

    }

}


build_fadt(GArray *table_data, GArray *linker, unsigned dsdt)

{

    AcpiFadtDescriptorRev5_1 *fadt = acpi_data_push(table_data, sizeof(*fadt));

    /* Hardware Reduced = 1 and use PSCI 0.2+ and with HVC */

    fadt->flags = cpu_to_le32(1 << ACPI_FADT_F_HW_REDUCED_ACPI);

    fadt->arm_boot_flags = cpu_to_le16((1 << ACPI_FADT_ARM_USE_PSCI_G_0_2) |

                                       (1 << ACPI_FADT_ARM_PSCI_USE_HVC));

    /* ACPI v5.1 (fadt->revision.fadt->minor_revision) */

    fadt->minor_revision = 0x1;

    fadt->dsdt = cpu_to_le32(dsdt);

    /* DSDT address to be filled by Guest linker */

    bios_linker_loader_add_pointer(linker, ACPI_BUILD_TABLE_FILE,

                                   ACPI_BUILD_TABLE_FILE,

                                   table_data, &fadt->dsdt,

                                   sizeof fadt->dsdt);

    build_header(linker, table_data,

                 (void *)fadt, "FACP", sizeof(*fadt), 5, NULL, NULL);

}


static int config_input_overlay(AVFilterLink *inlink)

{

    AVFilterContext *ctx  = inlink->dst;

    OverlayContext  *over = inlink->dst->priv;

    char *expr;

    double var_values[VAR_VARS_NB], res;

    int ret;

    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(inlink->format);

    av_image_fill_max_pixsteps(over->overlay_pix_step, NULL, pix_desc);

    /* Finish the configuration by evaluating the expressions

       now when both inputs are configured. */

    var_values[VAR_MAIN_W   ] = var_values[VAR_MW] = ctx->inputs[MAIN   ]->w;

    var_values[VAR_MAIN_H   ] = var_values[VAR_MH] = ctx->inputs[MAIN   ]->h;

    var_values[VAR_OVERLAY_W] = var_values[VAR_OW] = ctx->inputs[OVERLAY]->w;

    var_values[VAR_OVERLAY_H] = var_values[VAR_OH] = ctx->inputs[OVERLAY]->h;

    if ((ret = av_expr_parse_and_eval(&res, (expr = over->x_expr), var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto fail;

    over->x = res;

    if ((ret = av_expr_parse_and_eval(&res, (expr = over->y_expr), var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)))

        goto fail;

    over->y = res;

    /* x may depend on y */

    if ((ret = av_expr_parse_and_eval(&res, (expr = over->x_expr), var_names, var_values,

                                      NULL, NULL, NULL, NULL, NULL, 0, ctx)) < 0)

        goto fail;

    over->x = res;

    over->overlay_is_packed_rgb =

        ff_fill_rgba_map(over->overlay_rgba_map, inlink->format) >= 0;

    over->overlay_has_alpha = ff_fmt_is_in(inlink->format, alpha_pix_fmts);

    av_log(ctx, AV_LOG_VERBOSE,

           "main w:%d h:%d fmt:%s overlay x:%d y:%d w:%d h:%d fmt:%s\n",

           ctx->inputs[MAIN]->w, ctx->inputs[MAIN]->h,

           av_get_pix_fmt_name(ctx->inputs[MAIN]->format),

           over->x, over->y,

           ctx->inputs[OVERLAY]->w, ctx->inputs[OVERLAY]->h,

           av_get_pix_fmt_name(ctx->inputs[OVERLAY]->format));

    if (over->x < 0 || over->y < 0 ||

        over->x + var_values[VAR_OVERLAY_W] > var_values[VAR_MAIN_W] ||

        over->y + var_values[VAR_OVERLAY_H] > var_values[VAR_MAIN_H]) {

        av_log(ctx, AV_LOG_ERROR,

               "Overlay area (%d,%d)<->(%d,%d) not within the main area (0,0)<->(%d,%d) or zero-sized\n",

               over->x, over->y,

               (int)(over->x + var_values[VAR_OVERLAY_W]),

               (int)(over->y + var_values[VAR_OVERLAY_H]),

               (int)var_values[VAR_MAIN_W], (int)var_values[VAR_MAIN_H]);

        return AVERROR(EINVAL);

    }

    return 0;

fail:

    av_log(NULL, AV_LOG_ERROR,

           "Error when evaluating the expression '%s'\n", expr);

    return ret;

}


static int dvdsub_decode(AVCodecContext *avctx,

                         void *data, int *data_size,

                         AVPacket *avpkt)

{

    DVDSubContext *ctx = avctx->priv_data;

    const uint8_t *buf = avpkt->data;

    int buf_size = avpkt->size;

    AVSubtitle *sub = data;

    int is_menu;

    if (ctx->buf_size) {

        int ret = append_to_cached_buf(avctx, buf, buf_size);

        if (ret < 0) {

            *data_size = 0;

            return ret;

        }

        buf = ctx->buf;

        buf_size = ctx->buf_size;

    }

    is_menu = decode_dvd_subtitles(ctx, sub, buf, buf_size);

    if (is_menu == AVERROR(EAGAIN)) {

        *data_size = 0;

        return append_to_cached_buf(avctx, buf, buf_size);

    }

    if (is_menu < 0) {

    no_subtitle:

        reset_rects(sub);

        *data_size = 0;

        return buf_size;

    }

    if (!is_menu && find_smallest_bounding_rectangle(sub) == 0)

        goto no_subtitle;

    if (ctx->forced_subs_only && !(sub->rects[0]->flags & AV_SUBTITLE_FLAG_FORCED))

        goto no_subtitle;

#if defined(DEBUG)

    {

    char ppm_name[32];

    snprintf(ppm_name, sizeof(ppm_name), "/tmp/%05d.ppm", ctx->sub_id++);

    ff_dlog(NULL, "start=%d ms end =%d ms\n",

            sub->start_display_time,

            sub->end_display_time);

    ppm_save(ppm_name, sub->rects[0]->pict.data[0],

             sub->rects[0]->w, sub->rects[0]->h, (uint32_t*) sub->rects[0]->pict.data[1]);

    }

#endif

    ctx->buf_size = 0;

    *data_size = 1;

    return buf_size;

}


static int mov_write_moov_tag(ByteIOContext *pb, MOVContext *mov,

                              AVFormatContext *s)

{

    int i;

    offset_t pos = url_ftell(pb);

    put_be32(pb, 0); /* size placeholder*/

    put_tag(pb, "moov");

    mov->timescale = globalTimescale;

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

        if(mov->tracks[i].entry <= 0) continue;

        if(mov->tracks[i].enc->codec_type == CODEC_TYPE_VIDEO) {

            mov->tracks[i].timescale = mov->tracks[i].enc->time_base.den;

            mov->tracks[i].sampleDuration = mov->tracks[i].enc->time_base.num;

        } else if(mov->tracks[i].enc->codec_type == CODEC_TYPE_AUDIO) {

            mov->tracks[i].timescale = mov->tracks[i].enc->sample_rate;

            mov->tracks[i].sampleDuration = mov->tracks[i].enc->frame_size;

        }

        mov->tracks[i].trackDuration =

            (int64_t)mov->tracks[i].sampleCount * mov->tracks[i].sampleDuration;

        mov->tracks[i].time = mov->time;

        mov->tracks[i].trackID = i+1;

    }

    mov_write_mvhd_tag(pb, mov);

    //mov_write_iods_tag(pb, mov);

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

        if(mov->tracks[i].entry > 0) {

            mov_write_trak_tag(pb, &(mov->tracks[i]));

        }

    }

    if (mov->mode == MODE_PSP)

        mov_write_uuidusmt_tag(pb, s);

    else

    mov_write_udta_tag(pb, mov, s);

    return updateSize(pb, pos);

}


int vncws_decode_frame(Buffer *input, uint8_t **payload,

                           size_t *payload_size, size_t *frame_size)

{

    unsigned char opcode = 0, fin = 0, has_mask = 0;

    size_t header_size = 0;

    uint32_t *payload32;

    WsHeader *header = (WsHeader *)input->buffer;

    WsMask mask;

    int i;

    if (input->offset < WS_HEAD_MIN_LEN + 4) {

        /* header not complete */

        return 0;

    }

    fin = (header->b0 & 0x80) >> 7;

    opcode = header->b0 & 0x0f;

    has_mask = (header->b1 & 0x80) >> 7;

    *payload_size = header->b1 & 0x7f;

    if (opcode == WS_OPCODE_CLOSE) {

        /* disconnect */

        return -1;

    }

    /* Websocket frame sanity check:

     * * Websocket fragmentation is not supported.

     * * All  websockets frames sent by a client have to be masked.

     * * Only binary encoding is supported.

     */

    if (!fin || !has_mask || opcode != WS_OPCODE_BINARY_FRAME) {

        VNC_DEBUG("Received faulty/unsupported Websocket frame\n");

        return -2;

    }

    if (*payload_size < 126) {

        header_size = 6;

        mask = header->u.m;

    } else if (*payload_size == 126 && input->offset >= 8) {

        *payload_size = be16_to_cpu(header->u.s16.l16);

        header_size = 8;

        mask = header->u.s16.m16;

    } else if (*payload_size == 127 && input->offset >= 14) {

        *payload_size = be64_to_cpu(header->u.s64.l64);

        header_size = 14;

        mask = header->u.s64.m64;

    } else {

        /* header not complete */

        return 0;

    }

    *frame_size = header_size + *payload_size;

    if (input->offset < *frame_size) {

        /* frame not complete */

        return 0;

    }

    *payload = input->buffer + header_size;

    /* unmask frame */

    /* process 1 frame (32 bit op) */

    payload32 = (uint32_t *)(*payload);

    for (i = 0; i < *payload_size / 4; i++) {

        payload32[i] ^= mask.u;

    }

    /* process the remaining bytes (if any) */

    for (i *= 4; i < *payload_size; i++) {

        (*payload)[i] ^= mask.c[i % 4];

    }

    return 1;

}


static void send_framebuffer_update_raw(VncState *vs, int x, int y, int w, int h)

{

    int i;

    uint8_t *row;

    row = ds_get_data(vs->ds) + y * ds_get_linesize(vs->ds) + x * ds_get_bytes_per_pixel(vs->ds);

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

        vs->write_pixels(vs, row, w * ds_get_bytes_per_pixel(vs->ds));

        row += ds_get_linesize(vs->ds);

    }

}


static int alloc_frame_buffer(MpegEncContext *s, Picture *pic)

{

    int r;

    if (s->avctx->hwaccel) {

        assert(!pic->f.hwaccel_picture_private);

        if (s->avctx->hwaccel->priv_data_size) {

            pic->f.hwaccel_picture_private = av_mallocz(s->avctx->hwaccel->priv_data_size);

            if (!pic->f.hwaccel_picture_private) {

                av_log(s->avctx, AV_LOG_ERROR, "alloc_frame_buffer() failed (hwaccel private data allocation)\n");

                return -1;

            }

        }

    }

    if (s->codec_id != AV_CODEC_ID_WMV3IMAGE &&

        s->codec_id != AV_CODEC_ID_VC1IMAGE  &&

        s->codec_id != AV_CODEC_ID_MSS2)

        r = ff_thread_get_buffer(s->avctx, &pic->f);

    else

        r = avcodec_default_get_buffer(s->avctx, &pic->f);

    if (r < 0 || !pic->f.type || !pic->f.data[0]) {

        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n",

               r, pic->f.type, pic->f.data[0]);

        av_freep(&pic->f.hwaccel_picture_private);

        return -1;

    }

    if (s->linesize && (s->linesize   != pic->f.linesize[0] ||

                        s->uvlinesize != pic->f.linesize[1])) {

        av_log(s->avctx, AV_LOG_ERROR,

               "get_buffer() failed (stride changed)\n");

        free_frame_buffer(s, pic);

        return -1;

    }

    if (pic->f.linesize[1] != pic->f.linesize[2]) {

        av_log(s->avctx, AV_LOG_ERROR,

               "get_buffer() failed (uv stride mismatch)\n");

        free_frame_buffer(s, pic);

        return -1;

    }

    return 0;

}


static void pflash_write (pflash_t *pfl, target_ulong offset, uint32_t value,

                          int width)

{

    target_ulong boff;

    uint8_t *p;

    uint8_t cmd;

    /* WARNING: when the memory area is in ROMD mode, the offset is a

       ram offset, not a physical address */

    if (pfl->wcycle == 0)

        offset -= (target_ulong)(long)pfl->storage;

    else

        offset -= pfl->base;

    cmd = value;

    DPRINTF("%s: offset " TARGET_FMT_lx " %08x %d\n", __func__,

            offset, value, width);

    if (pfl->cmd != 0xA0 && cmd == 0xF0) {

        DPRINTF("%s: flash reset asked (%02x %02x)\n",

                __func__, pfl->cmd, cmd);

        goto reset_flash;

    }

    /* Set the device in I/O access mode */

    cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);

    boff = offset & (pfl->sector_len - 1);

    if (pfl->width == 2)

        boff = boff >> 1;

    else if (pfl->width == 4)

        boff = boff >> 2;

    switch (pfl->wcycle) {

    case 0:

        /* We're in read mode */

    check_unlock0:

        if (boff == 0x55 && cmd == 0x98) {

        enter_CFI_mode:

            /* Enter CFI query mode */

            pfl->wcycle = 7;

            pfl->cmd = 0x98;

            return;

        }

        if (boff != 0x555 || cmd != 0xAA) {

            DPRINTF("%s: unlock0 failed " TARGET_FMT_lx " %02x %04x\n",

                    __func__, boff, cmd, 0x555);

            goto reset_flash;

        }

        DPRINTF("%s: unlock sequence started\n", __func__);

        break;

    case 1:

        /* We started an unlock sequence */

    check_unlock1:

        if (boff != 0x2AA || cmd != 0x55) {

            DPRINTF("%s: unlock1 failed " TARGET_FMT_lx " %02x\n", __func__,

                    boff, cmd);

            goto reset_flash;

        }

        DPRINTF("%s: unlock sequence done\n", __func__);

        break;

    case 2:

        /* We finished an unlock sequence */

        if (!pfl->bypass && boff != 0x555) {

            DPRINTF("%s: command failed " TARGET_FMT_lx " %02x\n", __func__,

                    boff, cmd);

            goto reset_flash;

        }

        switch (cmd) {

        case 0x20:

            pfl->bypass = 1;

            goto do_bypass;

        case 0x80:

        case 0x90:

        case 0xA0:

            pfl->cmd = cmd;

            DPRINTF("%s: starting command %02x\n", __func__, cmd);

            break;

        default:

            DPRINTF("%s: unknown command %02x\n", __func__, cmd);

            goto reset_flash;

        }

        break;

    case 3:

        switch (pfl->cmd) {

        case 0x80:

            /* We need another unlock sequence */

            goto check_unlock0;

        case 0xA0:

            DPRINTF("%s: write data offset " TARGET_FMT_lx " %08x %d\n",

                    __func__, offset, value, width);

            p = pfl->storage;

            switch (width) {

            case 1:

                p[offset] &= value;

                pflash_update(pfl, offset, 1);

                break;

            case 2:

#if defined(TARGET_WORDS_BIGENDIAN)

                p[offset] &= value >> 8;

                p[offset + 1] &= value;

#else

                p[offset] &= value;

                p[offset + 1] &= value >> 8;

#endif

                pflash_update(pfl, offset, 2);

                break;

            case 4:

#if defined(TARGET_WORDS_BIGENDIAN)

                p[offset] &= value >> 24;

                p[offset + 1] &= value >> 16;

                p[offset + 2] &= value >> 8;

                p[offset + 3] &= value;

#else

                p[offset] &= value;

                p[offset + 1] &= value >> 8;

                p[offset + 2] &= value >> 16;

                p[offset + 3] &= value >> 24;

#endif

                pflash_update(pfl, offset, 4);

                break;

            }

            pfl->status = 0x00 | ~(value & 0x80);

            /* Let's pretend write is immediate */

            if (pfl->bypass)

                goto do_bypass;

            goto reset_flash;

        case 0x90:

            if (pfl->bypass && cmd == 0x00) {

                /* Unlock bypass reset */

                goto reset_flash;

            }

            /* We can enter CFI query mode from autoselect mode */

            if (boff == 0x55 && cmd == 0x98)

                goto enter_CFI_mode;

            /* No break here */

        default:

            DPRINTF("%s: invalid write for command %02x\n",

                    __func__, pfl->cmd);

            goto reset_flash;

        }

    case 4:

        switch (pfl->cmd) {

        case 0xA0:

            /* Ignore writes while flash data write is occuring */

            /* As we suppose write is immediate, this should never happen */

            return;

        case 0x80:

            goto check_unlock1;

        default:

            /* Should never happen */

            DPRINTF("%s: invalid command state %02x (wc 4)\n",

                    __func__, pfl->cmd);

            goto reset_flash;

        }

        break;

    case 5:

        switch (cmd) {

        case 0x10:

            if (boff != 0x555) {

                DPRINTF("%s: chip erase: invalid address " TARGET_FMT_lx "\n",

                        __func__, offset);

                goto reset_flash;

            }

            /* Chip erase */

            DPRINTF("%s: start chip erase\n", __func__);

            memset(pfl->storage, 0xFF, pfl->total_len);

            pfl->status = 0x00;

            pflash_update(pfl, 0, pfl->total_len);

            /* Let's wait 5 seconds before chip erase is done */

            qemu_mod_timer(pfl->timer,

                           qemu_get_clock(vm_clock) + (ticks_per_sec * 5));

            break;

        case 0x30:

            /* Sector erase */

            p = pfl->storage;

            offset &= ~(pfl->sector_len - 1);

            DPRINTF("%s: start sector erase at " TARGET_FMT_lx "\n", __func__,

                    offset);

            memset(p + offset, 0xFF, pfl->sector_len);

            pflash_update(pfl, offset, pfl->sector_len);

            pfl->status = 0x00;

            /* Let's wait 1/2 second before sector erase is done */

            qemu_mod_timer(pfl->timer,

                           qemu_get_clock(vm_clock) + (ticks_per_sec / 2));

            break;

        default:

            DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);

            goto reset_flash;

        }

        pfl->cmd = cmd;

        break;

    case 6:

        switch (pfl->cmd) {

        case 0x10:

            /* Ignore writes during chip erase */

            return;

        case 0x30:

            /* Ignore writes during sector erase */

            return;

        default:

            /* Should never happen */

            DPRINTF("%s: invalid command state %02x (wc 6)\n",

                    __func__, pfl->cmd);

            goto reset_flash;

        }

        break;

    case 7: /* Special value for CFI queries */

        DPRINTF("%s: invalid write in CFI query mode\n", __func__);

        goto reset_flash;

    default:

        /* Should never happen */

        DPRINTF("%s: invalid write state (wc 7)\n",  __func__);

        goto reset_flash;

    }

    pfl->wcycle++;

    return;

    /* Reset flash */

 reset_flash:

    if (pfl->wcycle != 0) {

        cpu_register_physical_memory(pfl->base, pfl->total_len,

                                     pfl->off | IO_MEM_ROMD | pfl->fl_mem);

    }

    pfl->bypass = 0;

    pfl->wcycle = 0;

    pfl->cmd = 0;

    return;

 do_bypass:

    pfl->wcycle = 2;

    pfl->cmd = 0;

    return;

}


void cpu_loop(CPUPPCState *env)

{

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

    target_siginfo_t info;

    int trapnr;

    target_ulong ret;

    for(;;) {

        cpu_exec_start(cs);

        trapnr = cpu_ppc_exec(cs);

        cpu_exec_end(cs);

        switch(trapnr) {

        case POWERPC_EXCP_NONE:

            /* Just go on */

            break;

        case POWERPC_EXCP_CRITICAL: /* Critical input                        */

            cpu_abort(cs, "Critical interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_MCHECK:   /* Machine check exception               */

            cpu_abort(cs, "Machine check exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_DSI:      /* Data storage exception                */

            EXCP_DUMP(env, "Invalid data memory access: 0x" TARGET_FMT_lx "\n",

                      env->spr[SPR_DAR]);

            /* XXX: check this. Seems bugged */

            switch (env->error_code & 0xFF000000) {

            case 0x40000000:

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SEGV_MAPERR;

                break;

            case 0x04000000:

                info.si_signo = TARGET_SIGILL;

                info.si_errno = 0;

                info.si_code = TARGET_ILL_ILLADR;

                break;

            case 0x08000000:

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SEGV_ACCERR;

                break;

            default:

                /* Let's send a regular segfault... */

                EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",

                          env->error_code);

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SEGV_MAPERR;

                break;

            }

            info._sifields._sigfault._addr = env->nip;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_ISI:      /* Instruction storage exception         */

            EXCP_DUMP(env, "Invalid instruction fetch: 0x\n" TARGET_FMT_lx

                      "\n", env->spr[SPR_SRR0]);

            /* XXX: check this */

            switch (env->error_code & 0xFF000000) {

            case 0x40000000:

                info.si_signo = TARGET_SIGSEGV;

            info.si_errno = 0;

                info.si_code = TARGET_SEGV_MAPERR;

                break;

            case 0x10000000:

            case 0x08000000:

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SEGV_ACCERR;

                break;

            default:

                /* Let's send a regular segfault... */

                EXCP_DUMP(env, "Invalid segfault errno (%02x)\n",

                          env->error_code);

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SEGV_MAPERR;

                break;

            }

            info._sifields._sigfault._addr = env->nip - 4;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_EXTERNAL: /* External input                        */

            cpu_abort(cs, "External interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_ALIGN:    /* Alignment exception                   */

            EXCP_DUMP(env, "Unaligned memory access\n");

            /* XXX: check this */

            info.si_signo = TARGET_SIGBUS;

            info.si_errno = 0;

            info.si_code = TARGET_BUS_ADRALN;

            info._sifields._sigfault._addr = env->nip;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_PROGRAM:  /* Program exception                     */

            /* XXX: check this */

            switch (env->error_code & ~0xF) {

            case POWERPC_EXCP_FP:

                EXCP_DUMP(env, "Floating point program exception\n");

                info.si_signo = TARGET_SIGFPE;

                info.si_errno = 0;

                switch (env->error_code & 0xF) {

                case POWERPC_EXCP_FP_OX:

                    info.si_code = TARGET_FPE_FLTOVF;

                    break;

                case POWERPC_EXCP_FP_UX:

                    info.si_code = TARGET_FPE_FLTUND;

                    break;

                case POWERPC_EXCP_FP_ZX:

                case POWERPC_EXCP_FP_VXZDZ:

                    info.si_code = TARGET_FPE_FLTDIV;

                    break;

                case POWERPC_EXCP_FP_XX:

                    info.si_code = TARGET_FPE_FLTRES;

                    break;

                case POWERPC_EXCP_FP_VXSOFT:

                    info.si_code = TARGET_FPE_FLTINV;

                    break;

                case POWERPC_EXCP_FP_VXSNAN:

                case POWERPC_EXCP_FP_VXISI:

                case POWERPC_EXCP_FP_VXIDI:

                case POWERPC_EXCP_FP_VXIMZ:

                case POWERPC_EXCP_FP_VXVC:

                case POWERPC_EXCP_FP_VXSQRT:

                case POWERPC_EXCP_FP_VXCVI:

                    info.si_code = TARGET_FPE_FLTSUB;

                    break;

                default:

                    EXCP_DUMP(env, "Unknown floating point exception (%02x)\n",

                              env->error_code);

                    break;

                }

                break;

            case POWERPC_EXCP_INVAL:

                EXCP_DUMP(env, "Invalid instruction\n");

                info.si_signo = TARGET_SIGILL;

                info.si_errno = 0;

                switch (env->error_code & 0xF) {

                case POWERPC_EXCP_INVAL_INVAL:

                    info.si_code = TARGET_ILL_ILLOPC;

                    break;

                case POWERPC_EXCP_INVAL_LSWX:

                    info.si_code = TARGET_ILL_ILLOPN;

                    break;

                case POWERPC_EXCP_INVAL_SPR:

                    info.si_code = TARGET_ILL_PRVREG;

                    break;

                case POWERPC_EXCP_INVAL_FP:

                    info.si_code = TARGET_ILL_COPROC;

                    break;

                default:

                    EXCP_DUMP(env, "Unknown invalid operation (%02x)\n",

                              env->error_code & 0xF);

                    info.si_code = TARGET_ILL_ILLADR;

                    break;

                }

                break;

            case POWERPC_EXCP_PRIV:

                EXCP_DUMP(env, "Privilege violation\n");

                info.si_signo = TARGET_SIGILL;

                info.si_errno = 0;

                switch (env->error_code & 0xF) {

                case POWERPC_EXCP_PRIV_OPC:

                    info.si_code = TARGET_ILL_PRVOPC;

                    break;

                case POWERPC_EXCP_PRIV_REG:

                    info.si_code = TARGET_ILL_PRVREG;

                    break;

                default:

                    EXCP_DUMP(env, "Unknown privilege violation (%02x)\n",

                              env->error_code & 0xF);

                    info.si_code = TARGET_ILL_PRVOPC;

                    break;

                }

                break;

            case POWERPC_EXCP_TRAP:

                cpu_abort(cs, "Tried to call a TRAP\n");

                break;

            default:

                /* Should not happen ! */

                cpu_abort(cs, "Unknown program exception (%02x)\n",

                          env->error_code);

                break;

            }

            info._sifields._sigfault._addr = env->nip - 4;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_FPU:      /* Floating-point unavailable exception  */

            EXCP_DUMP(env, "No floating point allowed\n");

            info.si_signo = TARGET_SIGILL;

            info.si_errno = 0;

            info.si_code = TARGET_ILL_COPROC;

            info._sifields._sigfault._addr = env->nip - 4;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_SYSCALL:  /* System call exception                 */

            cpu_abort(cs, "Syscall exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_APU:      /* Auxiliary processor unavailable       */

            EXCP_DUMP(env, "No APU instruction allowed\n");

            info.si_signo = TARGET_SIGILL;

            info.si_errno = 0;

            info.si_code = TARGET_ILL_COPROC;

            info._sifields._sigfault._addr = env->nip - 4;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_DECR:     /* Decrementer exception                 */

            cpu_abort(cs, "Decrementer interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_FIT:      /* Fixed-interval timer interrupt        */

            cpu_abort(cs, "Fix interval timer interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_WDT:      /* Watchdog timer interrupt              */

            cpu_abort(cs, "Watchdog timer interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_DTLB:     /* Data TLB error                        */

            cpu_abort(cs, "Data TLB exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_ITLB:     /* Instruction TLB error                 */

            cpu_abort(cs, "Instruction TLB exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */

            EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");

            info.si_signo = TARGET_SIGILL;

            info.si_errno = 0;

            info.si_code = TARGET_ILL_COPROC;

            info._sifields._sigfault._addr = env->nip - 4;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_EFPDI:    /* Embedded floating-point data IRQ      */

            cpu_abort(cs, "Embedded floating-point data IRQ not handled\n");

            break;

        case POWERPC_EXCP_EFPRI:    /* Embedded floating-point round IRQ     */

            cpu_abort(cs, "Embedded floating-point round IRQ not handled\n");

            break;

        case POWERPC_EXCP_EPERFM:   /* Embedded performance monitor IRQ      */

            cpu_abort(cs, "Performance monitor exception not handled\n");

            break;

        case POWERPC_EXCP_DOORI:    /* Embedded doorbell interrupt           */

            cpu_abort(cs, "Doorbell interrupt while in user mode. "

                       "Aborting\n");

            break;

        case POWERPC_EXCP_DOORCI:   /* Embedded doorbell critical interrupt  */

            cpu_abort(cs, "Doorbell critical interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_RESET:    /* System reset exception                */

            cpu_abort(cs, "Reset interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_DSEG:     /* Data segment exception                */

            cpu_abort(cs, "Data segment exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_ISEG:     /* Instruction segment exception         */

            cpu_abort(cs, "Instruction segment exception "

                      "while in user mode. Aborting\n");

            break;

        /* PowerPC 64 with hypervisor mode support */

        case POWERPC_EXCP_HDECR:    /* Hypervisor decrementer exception      */

            cpu_abort(cs, "Hypervisor decrementer interrupt "

                      "while in user mode. Aborting\n");

            break;

        case POWERPC_EXCP_TRACE:    /* Trace exception                       */

            /* Nothing to do:

             * we use this exception to emulate step-by-step execution mode.

             */

            break;

        /* PowerPC 64 with hypervisor mode support */

        case POWERPC_EXCP_HDSI:     /* Hypervisor data storage exception     */

            cpu_abort(cs, "Hypervisor data storage exception "

                      "while in user mode. Aborting\n");

            break;

        case POWERPC_EXCP_HISI:     /* Hypervisor instruction storage excp   */

            cpu_abort(cs, "Hypervisor instruction storage exception "

                      "while in user mode. Aborting\n");

            break;

        case POWERPC_EXCP_HDSEG:    /* Hypervisor data segment exception     */

            cpu_abort(cs, "Hypervisor data segment exception "

                      "while in user mode. Aborting\n");

            break;

        case POWERPC_EXCP_HISEG:    /* Hypervisor instruction segment excp   */

            cpu_abort(cs, "Hypervisor instruction segment exception "

                      "while in user mode. Aborting\n");

            break;

        case POWERPC_EXCP_VPU:      /* Vector unavailable exception          */

            EXCP_DUMP(env, "No Altivec instructions allowed\n");

            info.si_signo = TARGET_SIGILL;

            info.si_errno = 0;

            info.si_code = TARGET_ILL_COPROC;

            info._sifields._sigfault._addr = env->nip - 4;

            queue_signal(env, info.si_signo, &info);

            break;

        case POWERPC_EXCP_PIT:      /* Programmable interval timer IRQ       */

            cpu_abort(cs, "Programmable interval timer interrupt "

                      "while in user mode. Aborting\n");

            break;

        case POWERPC_EXCP_IO:       /* IO error exception                    */

            cpu_abort(cs, "IO error exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_RUNM:     /* Run mode exception                    */

            cpu_abort(cs, "Run mode exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_EMUL:     /* Emulation trap exception              */

            cpu_abort(cs, "Emulation trap exception not handled\n");

            break;

        case POWERPC_EXCP_IFTLB:    /* Instruction fetch TLB error           */

            cpu_abort(cs, "Instruction fetch TLB exception "

                      "while in user-mode. Aborting");

            break;

        case POWERPC_EXCP_DLTLB:    /* Data load TLB miss                    */

            cpu_abort(cs, "Data load TLB exception while in user-mode. "

                      "Aborting");

            break;

        case POWERPC_EXCP_DSTLB:    /* Data store TLB miss                   */

            cpu_abort(cs, "Data store TLB exception while in user-mode. "

                      "Aborting");

            break;

        case POWERPC_EXCP_FPA:      /* Floating-point assist exception       */

            cpu_abort(cs, "Floating-point assist exception not handled\n");

            break;

        case POWERPC_EXCP_IABR:     /* Instruction address breakpoint        */

            cpu_abort(cs, "Instruction address breakpoint exception "

                      "not handled\n");

            break;

        case POWERPC_EXCP_SMI:      /* System management interrupt           */

            cpu_abort(cs, "System management interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_THERM:    /* Thermal interrupt                     */

            cpu_abort(cs, "Thermal interrupt interrupt while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_PERFM:   /* Embedded performance monitor IRQ      */

            cpu_abort(cs, "Performance monitor exception not handled\n");

            break;

        case POWERPC_EXCP_VPUA:     /* Vector assist exception               */

            cpu_abort(cs, "Vector assist exception not handled\n");

            break;

        case POWERPC_EXCP_SOFTP:    /* Soft patch exception                  */

            cpu_abort(cs, "Soft patch exception not handled\n");

            break;

        case POWERPC_EXCP_MAINT:    /* Maintenance exception                 */

            cpu_abort(cs, "Maintenance exception while in user mode. "

                      "Aborting\n");

            break;

        case POWERPC_EXCP_STOP:     /* stop translation                      */

            /* We did invalidate the instruction cache. Go on */

            break;

        case POWERPC_EXCP_BRANCH:   /* branch instruction:                   */

            /* We just stopped because of a branch. Go on */

            break;

        case POWERPC_EXCP_SYSCALL_USER:

            /* system call in user-mode emulation */

            /* WARNING:

             * PPC ABI uses overflow flag in cr0 to signal an error

             * in syscalls.

             */

            env->crf[0] &= ~0x1;

            ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],

                             env->gpr[5], env->gpr[6], env->gpr[7],

                             env->gpr[8], 0, 0);

            if (ret == -TARGET_ERESTARTSYS) {

                env->nip -= 4;

                break;

            }

            if (ret == (target_ulong)(-TARGET_QEMU_ESIGRETURN)) {

                /* Returning from a successful sigreturn syscall.

                   Avoid corrupting register state.  */

                break;

            }

            if (ret > (target_ulong)(-515)) {

                env->crf[0] |= 0x1;

                ret = -ret;

            }

            env->gpr[3] = ret;

            break;

        case POWERPC_EXCP_STCX:

            if (do_store_exclusive(env)) {

                info.si_signo = TARGET_SIGSEGV;

                info.si_errno = 0;

                info.si_code = TARGET_SEGV_MAPERR;

                info._sifields._sigfault._addr = env->nip;

                queue_signal(env, info.si_signo, &info);

            }

            break;

        case EXCP_DEBUG:

            {

                int sig;

                sig = gdb_handlesig(cs, TARGET_SIGTRAP);

                if (sig) {

                    info.si_signo = sig;

                    info.si_errno = 0;

                    info.si_code = TARGET_TRAP_BRKPT;

                    queue_signal(env, info.si_signo, &info);

                  }

            }

            break;

        case EXCP_INTERRUPT:

            /* just indicate that signals should be handled asap */

            break;

        default:

            cpu_abort(cs, "Unknown exception 0x%d. Aborting\n", trapnr);

            break;

        }

        process_pending_signals(env);

    }

}


static int check_video_codec_tag(int codec_tag) {

    if (codec_tag <= 0 || codec_tag > 15) {

        return AVERROR(ENOSYS);

    } else

        return 0;

}


static int announce_self_create(uint8_t *buf,

				uint8_t *mac_addr)

{

    uint32_t magic = EXPERIMENTAL_MAGIC;

    uint16_t proto = htons(ETH_P_EXPERIMENTAL);

    /* FIXME: should we send a different packet (arp/rarp/ping)? */

    memset(buf, 0, 64);

    memset(buf, 0xff, 6);         /* h_dst */

    memcpy(buf + 6, mac_addr, 6); /* h_src */

    memcpy(buf + 12, &proto, 2);  /* h_proto */

    memcpy(buf + 14, &magic, 4);  /* magic */

    return 64; /* len */

}


static int slirp_hostfwd(SlirpState *s, const char *redir_str,

                         int legacy_format, Error **errp)

{

    struct in_addr host_addr = { .s_addr = INADDR_ANY };

    struct in_addr guest_addr = { .s_addr = 0 };

    int host_port, guest_port;

    const char *p;

    char buf[256];

    int is_udp;

    char *end;

    p = redir_str;

    if (!p || get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

        goto fail_syntax;

    }

    if (!strcmp(buf, "tcp") || buf[0] == '\0') {

        is_udp = 0;

    } else if (!strcmp(buf, "udp")) {

        is_udp = 1;

    } else {

        goto fail_syntax;

    }

    if (!legacy_format) {

        if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

            goto fail_syntax;

        }

        if (buf[0] != '\0' && !inet_aton(buf, &host_addr)) {

            goto fail_syntax;

        }

    }

    if (get_str_sep(buf, sizeof(buf), &p, legacy_format ? ':' : '-') < 0) {

        goto fail_syntax;

    }

    host_port = strtol(buf, &end, 0);

    if (*end != '\0' || host_port < 0 || host_port > 65535) {

        goto fail_syntax;

    }

    if (get_str_sep(buf, sizeof(buf), &p, ':') < 0) {

        goto fail_syntax;

    }

    if (buf[0] != '\0' && !inet_aton(buf, &guest_addr)) {

        goto fail_syntax;

    }

    guest_port = strtol(p, &end, 0);

    if (*end != '\0' || guest_port < 1 || guest_port > 65535) {

        goto fail_syntax;

    }

    if (slirp_add_hostfwd(s->slirp, is_udp, host_addr, host_port, guest_addr,

                          guest_port) < 0) {

        error_setg(errp, "Could not set up host forwarding rule '%s'",

                   redir_str);

        return -1;

    }

    return 0;

 fail_syntax:

    error_setg(errp, "Invalid host forwarding rule '%s'", redir_str);

    return -1;

}


void RENAME(interleaveBytes)(uint8_t *src1, uint8_t *src2, uint8_t *dest,

			    long width, long height, long src1Stride,

			    long src2Stride, long dstStride){

	long h;

	for(h=0; h < height; h++)

	{

		long w;

#ifdef HAVE_MMX

#ifdef HAVE_SSE2

		asm(

			"xor %%"REG_a", %%"REG_a"	\n\t"

			"1:				\n\t"

			PREFETCH" 64(%1, %%"REG_a")	\n\t"

			PREFETCH" 64(%2, %%"REG_a")	\n\t"

			"movdqa (%1, %%"REG_a"), %%xmm0	\n\t"

			"movdqa (%1, %%"REG_a"), %%xmm1	\n\t"

			"movdqa (%2, %%"REG_a"), %%xmm2	\n\t"

			"punpcklbw %%xmm2, %%xmm0	\n\t"

			"punpckhbw %%xmm2, %%xmm1	\n\t"

			"movntdq %%xmm0, (%0, %%"REG_a", 2)\n\t"

			"movntdq %%xmm1, 16(%0, %%"REG_a", 2)\n\t"

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

			"cmp %3, %%"REG_a"		\n\t"

			" jb 1b				\n\t"

			::"r"(dest), "r"(src1), "r"(src2), "r" (width-15)

			: "memory", "%"REG_a""

		);

#else

		asm(

			"xor %%"REG_a", %%"REG_a"	\n\t"

			"1:				\n\t"

			PREFETCH" 64(%1, %%"REG_a")	\n\t"

			PREFETCH" 64(%2, %%"REG_a")	\n\t"

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

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

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

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

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

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

			"punpcklbw %%mm4, %%mm0		\n\t"

			"punpckhbw %%mm4, %%mm1		\n\t"

			"punpcklbw %%mm5, %%mm2		\n\t"

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

			MOVNTQ" %%mm0, (%0, %%"REG_a", 2)\n\t"

			MOVNTQ" %%mm1, 8(%0, %%"REG_a", 2)\n\t"

			MOVNTQ" %%mm2, 16(%0, %%"REG_a", 2)\n\t"

			MOVNTQ" %%mm3, 24(%0, %%"REG_a", 2)\n\t"

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

			"cmp %3, %%"REG_a"		\n\t"

			" jb 1b				\n\t"

			::"r"(dest), "r"(src1), "r"(src2), "r" (width-15)

			: "memory", "%"REG_a

		);

#endif

		for(w= (width&(~15)); w < width; w++)

		{

			dest[2*w+0] = src1[w];

			dest[2*w+1] = src2[w];

		}

#else

		for(w=0; w < width; w++)

		{

			dest[2*w+0] = src1[w];

			dest[2*w+1] = src2[w];

		}

#endif

		dest += dstStride;

                src1 += src1Stride;

                src2 += src2Stride;

	}

#ifdef HAVE_MMX

	asm(

		EMMS" \n\t"

		SFENCE" \n\t"

		::: "memory"

		);

#endif

}


static inline void RENAME(yuv2rgb555_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)

{

    x86_reg uv_off = c->uv_off << 1;

    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, %6)

            "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

            WRITERGB15(%%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), "m"(uv_off)

        );

    } 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, %6)

            "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

            WRITERGB15(%%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), "m"(uv_off)

        );

    }

}


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

                     Error **errp)

{

    BDRVVHDXState *s = bs->opaque;

    int ret = 0;

    uint32_t i;

    uint64_t signature;

    bool log_flushed = false;

    s->bat = NULL;

    s->first_visible_write = true;

    qemu_co_mutex_init(&s->lock);

    QLIST_INIT(&s->regions);

    /* validate the file signature */

    ret = bdrv_pread(bs->file, 0, &signature, sizeof(uint64_t));

    if (ret < 0) {

        goto fail;

    }

    if (memcmp(&signature, "vhdxfile", 8)) {

        ret = -EINVAL;

        goto fail;

    }

    /* This is used for any header updates, for the file_write_guid.

     * The spec dictates that a new value should be used for the first

     * header update */

    vhdx_guid_generate(&s->session_guid);

    ret = vhdx_parse_header(bs, s);

    if (ret < 0) {

        goto fail;

    }

    ret = vhdx_parse_log(bs, s, &log_flushed);

    if (ret < 0) {

        goto fail;

    }

    ret = vhdx_open_region_tables(bs, s);

    if (ret < 0) {

        goto fail;

    }

    ret = vhdx_parse_metadata(bs, s);

    if (ret < 0) {

        goto fail;

    }

    s->block_size = s->params.block_size;

    /* the VHDX spec dictates that virtual_disk_size is always a multiple of

     * logical_sector_size */

    bs->total_sectors = s->virtual_disk_size >> s->logical_sector_size_bits;

    vhdx_calc_bat_entries(s);

    s->bat_offset = s->bat_rt.file_offset;

    if (s->bat_entries > s->bat_rt.length / sizeof(VHDXBatEntry)) {

        /* BAT allocation is not large enough for all entries */

        ret = -EINVAL;

        goto fail;

    }

    /* s->bat is freed in vhdx_close() */

    s->bat = qemu_blockalign(bs, s->bat_rt.length);

    ret = bdrv_pread(bs->file, s->bat_offset, s->bat, s->bat_rt.length);

    if (ret < 0) {

        goto fail;

    }

    uint64_t payblocks = s->chunk_ratio;

    /* endian convert, and verify populated BAT field file offsets against

     * region table and log entries */

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

        le64_to_cpus(&s->bat[i]);

        if (payblocks--) {

            /* payload bat entries */

            if ((s->bat[i] & VHDX_BAT_STATE_BIT_MASK) ==

                    PAYLOAD_BLOCK_FULLY_PRESENT) {

                ret = vhdx_region_check(s, s->bat[i] & VHDX_BAT_FILE_OFF_MASK,

                                        s->block_size);

                if (ret < 0) {

                    goto fail;

                }

            }

        } else {

            payblocks = s->chunk_ratio;

            /* Once differencing files are supported, verify sector bitmap

             * blocks here */

        }

    }

    if (flags & BDRV_O_RDWR) {

        ret = vhdx_update_headers(bs, s, false, NULL);

        if (ret < 0) {

            goto fail;

        }

    }

    /* TODO: differencing files */

    /* Disable migration when VHDX images are used */

    error_set(&s->migration_blocker,

            QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,

            "vhdx", bs->device_name, "live migration");

    migrate_add_blocker(s->migration_blocker);

    return 0;

fail:

    vhdx_close(bs);

    return ret;

}


FFAMediaCodec* ff_AMediaCodec_createEncoderByType(const char *mime)

{

    JNIEnv *env = NULL;

    FFAMediaCodec *codec = NULL;

    jstring mime_type = NULL;

    codec = av_mallocz(sizeof(FFAMediaCodec));

    if (!codec) {

        return NULL;

    }

    codec->class = &amediacodec_class;

    env = ff_jni_get_env(codec);

    if (!env) {

        av_freep(&codec);

        return NULL;

    }

    if (ff_jni_init_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec) < 0) {

        goto fail;

    }

    mime_type = ff_jni_utf_chars_to_jstring(env, mime, codec);

    if (!mime_type) {

        goto fail;

    }

    codec->object = (*env)->CallStaticObjectMethod(env, codec->jfields.mediacodec_class, codec->jfields.create_encoder_by_type_id, mime_type);

    if (ff_jni_exception_check(env, 1, codec) < 0) {

        goto fail;

    }

    codec->object = (*env)->NewGlobalRef(env, codec->object);

    if (!codec->object) {

        goto fail;

    }

    if (codec_init_static_fields(codec) < 0) {

        goto fail;

    }

    if (codec->jfields.get_input_buffer_id && codec->jfields.get_output_buffer_id) {

        codec->has_get_i_o_buffer = 1;

    }

    return codec;

fail:

    ff_jni_reset_jfields(env, &codec->jfields, jni_amediacodec_mapping, 1, codec);

    if (mime_type) {

        (*env)->DeleteLocalRef(env, mime_type);

    }

    av_freep(&codec);

    return NULL;

}


static int mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s)

{

    AVStream       *video_st    = s->streams[0];

    AVCodecParameters *video_par = s->streams[0]->codecpar;

    AVCodecParameters *audio_par = s->streams[1]->codecpar;

    int audio_rate = audio_par->sample_rate;

    int64_t frame_rate = (video_st->avg_frame_rate.num * 0x10000LL) / video_st->avg_frame_rate.den;

    int audio_kbitrate = audio_par->bit_rate / 1000;

    int video_kbitrate = FFMIN(video_par->bit_rate / 1000, 800 - audio_kbitrate);

    if (frame_rate < 0 || frame_rate > INT32_MAX) {

        av_log(s, AV_LOG_ERROR, "Frame rate %f outside supported range\n", frame_rate / (double)0x10000);

        return AVERROR(EINVAL);

    }

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

    ffio_wfourcc(pb, "uuid");

    ffio_wfourcc(pb, "PROF");

    avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */

    avio_wb32(pb, 0xbb88695c);

    avio_wb32(pb, 0xfac9c740);

    avio_wb32(pb, 0x0);  /* ? */

    avio_wb32(pb, 0x3);  /* 3 sections ? */

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

    ffio_wfourcc(pb, "FPRF");

    avio_wb32(pb, 0x0);  /* ? */

    avio_wb32(pb, 0x0);  /* ? */

    avio_wb32(pb, 0x0);  /* ? */

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

    ffio_wfourcc(pb, "APRF"); /* audio */

    avio_wb32(pb, 0x0);

    avio_wb32(pb, 0x2);   /* TrackID */

    ffio_wfourcc(pb, "mp4a");

    avio_wb32(pb, 0x20f);

    avio_wb32(pb, 0x0);

    avio_wb32(pb, audio_kbitrate);

    avio_wb32(pb, audio_kbitrate);

    avio_wb32(pb, audio_rate);

    avio_wb32(pb, audio_par->channels);

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

    ffio_wfourcc(pb, "VPRF");   /* video */

    avio_wb32(pb, 0x0);

    avio_wb32(pb, 0x1);    /* TrackID */

    if (video_par->codec_id == AV_CODEC_ID_H264) {

        ffio_wfourcc(pb, "avc1");

        avio_wb16(pb, 0x014D);

        avio_wb16(pb, 0x0015);

    } else {

        ffio_wfourcc(pb, "mp4v");

        avio_wb16(pb, 0x0000);

        avio_wb16(pb, 0x0103);

    }

    avio_wb32(pb, 0x0);

    avio_wb32(pb, video_kbitrate);

    avio_wb32(pb, video_kbitrate);

    avio_wb32(pb, frame_rate);

    avio_wb32(pb, frame_rate);

    avio_wb16(pb, video_par->width);

    avio_wb16(pb, video_par->height);

    avio_wb32(pb, 0x010001); /* ? */

    return 0;

}


void av_thread_message_queue_free(AVThreadMessageQueue **mq)

{

#if HAVE_THREADS

    if (*mq) {

        av_thread_message_flush(*mq);

        av_fifo_freep(&(*mq)->fifo);

        pthread_cond_destroy(&(*mq)->cond);

        pthread_mutex_destroy(&(*mq)->lock);

        av_freep(mq);

    }

#endif

}


static void vhdx_parse_header(BlockDriverState *bs, BDRVVHDXState *s,

                              Error **errp)

{

    int ret;

    VHDXHeader *header1;

    VHDXHeader *header2;

    bool h1_valid = false;

    bool h2_valid = false;

    uint64_t h1_seq = 0;

    uint64_t h2_seq = 0;

    uint8_t *buffer;

    /* header1 & header2 are freed in vhdx_close() */

    header1 = qemu_blockalign(bs, sizeof(VHDXHeader));

    header2 = qemu_blockalign(bs, sizeof(VHDXHeader));

    buffer = qemu_blockalign(bs, VHDX_HEADER_SIZE);

    s->headers[0] = header1;

    s->headers[1] = header2;

    /* We have to read the whole VHDX_HEADER_SIZE instead of

     * sizeof(VHDXHeader), because the checksum is over the whole

     * region */

    ret = bdrv_pread(bs->file, VHDX_HEADER1_OFFSET, buffer, VHDX_HEADER_SIZE);

    if (ret < 0) {

        goto fail;

    }

    /* copy over just the relevant portion that we need */

    memcpy(header1, buffer, sizeof(VHDXHeader));

    vhdx_header_le_import(header1);

    if (vhdx_checksum_is_valid(buffer, VHDX_HEADER_SIZE, 4) &&

        !memcmp(&header1->signature, "head", 4)             &&

        header1->version == 1) {

        h1_seq = header1->sequence_number;

        h1_valid = true;

    }

    ret = bdrv_pread(bs->file, VHDX_HEADER2_OFFSET, buffer, VHDX_HEADER_SIZE);

    if (ret < 0) {

        goto fail;

    }

    /* copy over just the relevant portion that we need */

    memcpy(header2, buffer, sizeof(VHDXHeader));

    vhdx_header_le_import(header2);

    if (vhdx_checksum_is_valid(buffer, VHDX_HEADER_SIZE, 4) &&

        !memcmp(&header2->signature, "head", 4)             &&

        header2->version == 1) {

        h2_seq = header2->sequence_number;

        h2_valid = true;

    }

    /* If there is only 1 valid header (or no valid headers), we

     * don't care what the sequence numbers are */

    if (h1_valid && !h2_valid) {

        s->curr_header = 0;

    } else if (!h1_valid && h2_valid) {

        s->curr_header = 1;

    } else if (!h1_valid && !h2_valid) {

        goto fail;

    } else {

        /* If both headers are valid, then we choose the active one by the

         * highest sequence number.  If the sequence numbers are equal, that is

         * invalid */

        if (h1_seq > h2_seq) {

            s->curr_header = 0;

        } else if (h2_seq > h1_seq) {

            s->curr_header = 1;

        } else {

            goto fail;

        }

    }

    vhdx_region_register(s, s->headers[s->curr_header]->log_offset,

                            s->headers[s->curr_header]->log_length);

    goto exit;

fail:

    error_setg_errno(errp, -ret, "No valid VHDX header found");

    qemu_vfree(header1);

    qemu_vfree(header2);

    s->headers[0] = NULL;

    s->headers[1] = NULL;

exit:

    qemu_vfree(buffer);

}


int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,

                             int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))

{

    int ret;

    AVPacketList **next_point, *this_pktl;

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

    int chunked    = s->max_chunk_size || s->max_chunk_duration;

    this_pktl      = av_mallocz(sizeof(AVPacketList));

    if (!this_pktl)

        return AVERROR(ENOMEM);

    if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {

        av_assert0(pkt->size == UNCODED_FRAME_PACKET_SIZE);

        av_assert0(((AVFrame *)pkt->data)->buf);

    }

    if ((ret = av_packet_ref(&this_pktl->pkt, pkt)) < 0) {

        av_free(this_pktl);

        return ret;

    }

    if (s->streams[pkt->stream_index]->last_in_packet_buffer) {

        next_point = &(st->last_in_packet_buffer->next);

    } else {

        next_point = &s->internal->packet_buffer;

    }

    if (chunked) {

        uint64_t max= av_rescale_q_rnd(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base, AV_ROUND_UP);

        st->interleaver_chunk_size     += pkt->size;

        st->interleaver_chunk_duration += pkt->duration;

        if (   (s->max_chunk_size && st->interleaver_chunk_size > s->max_chunk_size)

            || (max && st->interleaver_chunk_duration           > max)) {

            st->interleaver_chunk_size      = 0;

            this_pktl->pkt.flags |= CHUNK_START;

            if (max && st->interleaver_chunk_duration > max) {

                int64_t syncoffset = (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)*max/2;

                int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset;

                st->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max;

            } else

                st->interleaver_chunk_duration = 0;

        }

    }

    if (*next_point) {

        if (chunked && !(this_pktl->pkt.flags & CHUNK_START))

            goto next_non_null;

        if (compare(s, &s->internal->packet_buffer_end->pkt, pkt)) {

            while (   *next_point

                   && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))

                       || !compare(s, &(*next_point)->pkt, pkt)))

                next_point = &(*next_point)->next;

            if (*next_point)

                goto next_non_null;

        } else {

            next_point = &(s->internal->packet_buffer_end->next);

        }

    }

    av_assert1(!*next_point);

    s->internal->packet_buffer_end = this_pktl;

next_non_null:

    this_pktl->next = *next_point;

    s->streams[pkt->stream_index]->last_in_packet_buffer =

        *next_point                                      = this_pktl;

    av_packet_unref(pkt);

    return 0;

}


static void x8_init_block_index(MpegEncContext *s){ //FIXME maybe merge with ff_*

//not s->linesize as this would be wrong for field pics

//not that IntraX8 has interlacing support ;)

    const int linesize   = s->current_picture.f.linesize[0];

    const int uvlinesize = s->current_picture.f.linesize[1];

    s->dest[0] = s->current_picture.f.data[0];

    s->dest[1] = s->current_picture.f.data[1];

    s->dest[2] = s->current_picture.f.data[2];

    s->dest[0] +=   s->mb_y        *   linesize << 3;

    s->dest[1] += ( s->mb_y&(~1) ) * uvlinesize << 2;//chroma blocks are on add rows

    s->dest[2] += ( s->mb_y&(~1) ) * uvlinesize << 2;

}


static int qemu_rdma_search_ram_block(RDMAContext *rdma,

                                      uint64_t block_offset,

                                      uint64_t offset,

                                      uint64_t length,

                                      uint64_t *block_index,

                                      uint64_t *chunk_index)

{

    uint64_t current_addr = block_offset + offset;

    RDMALocalBlock *block = g_hash_table_lookup(rdma->blockmap,

                                                (void *) block_offset);

    assert(block);

    assert(current_addr >= block->offset);

    assert((current_addr + length) <= (block->offset + block->length));

    *block_index = block->index;

    *chunk_index = ram_chunk_index(block->local_host_addr,

                block->local_host_addr + (current_addr - block->offset));

    return 0;

}


static int decode_update_thread_context(AVCodecContext *dst,

                                        const AVCodecContext *src)

{

    H264Context *h = dst->priv_data, *h1 = src->priv_data;

    int inited = h->context_initialized, err = 0;

    int context_reinitialized = 0;

    int i, ret;

    if (dst == src)

        return 0;

    if (inited &&

        (h->width                 != h1->width                 ||

         h->height                != h1->height                ||

         h->mb_width              != h1->mb_width              ||

         h->mb_height             != h1->mb_height             ||

         h->sps.bit_depth_luma    != h1->sps.bit_depth_luma    ||

         h->sps.chroma_format_idc != h1->sps.chroma_format_idc ||

         h->sps.colorspace        != h1->sps.colorspace)) {

        /* set bits_per_raw_sample to the previous value. the check for changed

         * bit depth in h264_set_parameter_from_sps() uses it and sets it to

         * the current value */

        h->avctx->bits_per_raw_sample = h->sps.bit_depth_luma;

        av_freep(&h->bipred_scratchpad);

        h->width     = h1->width;

        h->height    = h1->height;

        h->mb_height = h1->mb_height;

        h->mb_width  = h1->mb_width;

        h->mb_num    = h1->mb_num;

        h->mb_stride = h1->mb_stride;

        h->b_stride  = h1->b_stride;

        // SPS/PPS

        copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,

                        MAX_SPS_COUNT, sizeof(SPS));

        h->sps = h1->sps;

        copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,

                        MAX_PPS_COUNT, sizeof(PPS));

        h->pps = h1->pps;

        if ((err = h264_slice_header_init(h, 1)) < 0) {

            av_log(h->avctx, AV_LOG_ERROR, "h264_slice_header_init() failed");

            return err;

        }

        context_reinitialized = 1;

#if 0

        h264_set_parameter_from_sps(h);

        //Note we set context_reinitialized which will cause h264_set_parameter_from_sps to be reexecuted

        h->cur_chroma_format_idc = h1->cur_chroma_format_idc;

#endif

    }

    /* update linesize on resize for h264. The h264 decoder doesn't

     * necessarily call ff_MPV_frame_start in the new thread */

    h->linesize   = h1->linesize;

    h->uvlinesize = h1->uvlinesize;

    /* copy block_offset since frame_start may not be called */

    memcpy(h->block_offset, h1->block_offset, sizeof(h->block_offset));

    if (!inited) {

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

            av_freep(h->sps_buffers + i);

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

            av_freep(h->pps_buffers + i);

        memcpy(h, h1, offsetof(H264Context, intra_pcm_ptr));

        memcpy(&h->cabac, &h1->cabac,

               sizeof(H264Context) - offsetof(H264Context, cabac));

        av_assert0((void*)&h->cabac == &h->mb_padding + 1);

        memset(h->sps_buffers, 0, sizeof(h->sps_buffers));

        memset(h->pps_buffers, 0, sizeof(h->pps_buffers));

        memset(&h->er, 0, sizeof(h->er));

        memset(&h->me, 0, sizeof(h->me));

        memset(&h->mb, 0, sizeof(h->mb));

        memset(&h->mb_luma_dc, 0, sizeof(h->mb_luma_dc));

        memset(&h->mb_padding, 0, sizeof(h->mb_padding));

        h->avctx             = dst;

        h->DPB               = NULL;

        h->qscale_table_pool = NULL;

        h->mb_type_pool      = NULL;

        h->ref_index_pool    = NULL;

        h->motion_val_pool   = NULL;

        if (h1->context_initialized) {

        h->context_initialized = 0;

        memset(&h->cur_pic, 0, sizeof(h->cur_pic));

        avcodec_get_frame_defaults(&h->cur_pic.f);

        h->cur_pic.tf.f = &h->cur_pic.f;

        ret = ff_h264_alloc_tables(h);

        if (ret < 0) {

            av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n");

            return ret;

        }

        ret = context_init(h);

        if (ret < 0) {

            av_log(dst, AV_LOG_ERROR, "context_init() failed.\n");

            return ret;

        }

        }

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

            h->rbsp_buffer[i]      = NULL;

            h->rbsp_buffer_size[i] = 0;

        }

        h->bipred_scratchpad = NULL;

        h->edge_emu_buffer   = NULL;

        h->thread_context[0] = h;

        h->context_initialized = h1->context_initialized;

    }

    h->avctx->coded_height  = h1->avctx->coded_height;

    h->avctx->coded_width   = h1->avctx->coded_width;

    h->avctx->width         = h1->avctx->width;

    h->avctx->height        = h1->avctx->height;

    h->coded_picture_number = h1->coded_picture_number;

    h->first_field          = h1->first_field;

    h->picture_structure    = h1->picture_structure;

    h->qscale               = h1->qscale;

    h->droppable            = h1->droppable;

    h->data_partitioning    = h1->data_partitioning;

    h->low_delay            = h1->low_delay;

    for (i = 0; h->DPB && i < MAX_PICTURE_COUNT; i++) {

        unref_picture(h, &h->DPB[i]);

        if (h1->DPB[i].f.data[0] &&

            (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0)

            return ret;

    }

    h->cur_pic_ptr = REBASE_PICTURE(h1->cur_pic_ptr, h, h1);

    unref_picture(h, &h->cur_pic);

    if (h1->cur_pic.f.buf[0] && (ret = ref_picture(h, &h->cur_pic, &h1->cur_pic)) < 0)

        return ret;

    h->workaround_bugs = h1->workaround_bugs;

    h->low_delay       = h1->low_delay;

    h->droppable       = h1->droppable;

    // extradata/NAL handling

    h->is_avc = h1->is_avc;

    // SPS/PPS

    copy_parameter_set((void **)h->sps_buffers, (void **)h1->sps_buffers,

                       MAX_SPS_COUNT, sizeof(SPS));

    h->sps = h1->sps;

    copy_parameter_set((void **)h->pps_buffers, (void **)h1->pps_buffers,

                       MAX_PPS_COUNT, sizeof(PPS));

    h->pps = h1->pps;

    // Dequantization matrices

    // FIXME these are big - can they be only copied when PPS changes?

    copy_fields(h, h1, dequant4_buffer, dequant4_coeff);

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

        h->dequant4_coeff[i] = h->dequant4_buffer[0] +

                               (h1->dequant4_coeff[i] - h1->dequant4_buffer[0]);

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

        h->dequant8_coeff[i] = h->dequant8_buffer[0] +

                               (h1->dequant8_coeff[i] - h1->dequant8_buffer[0]);

    h->dequant_coeff_pps = h1->dequant_coeff_pps;

    // POC timing

    copy_fields(h, h1, poc_lsb, redundant_pic_count);

    // reference lists

    copy_fields(h, h1, short_ref, cabac_init_idc);

    copy_picture_range(h->short_ref, h1->short_ref, 32, h, h1);

    copy_picture_range(h->long_ref, h1->long_ref, 32, h, h1);

    copy_picture_range(h->delayed_pic, h1->delayed_pic,

                       MAX_DELAYED_PIC_COUNT + 2, h, h1);

    h->sync            = h1->sync;

    if (context_reinitialized)

        h264_set_parameter_from_sps(h);

    if (!h->cur_pic_ptr)

        return 0;

    if (!h->droppable) {

        err = ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index);

        h->prev_poc_msb = h->poc_msb;

        h->prev_poc_lsb = h->poc_lsb;

    }

    h->prev_frame_num_offset = h->frame_num_offset;

    h->prev_frame_num        = h->frame_num;

    h->outputed_poc          = h->next_outputed_poc;

    return err;

}


static bool use_exit_tb(DisasContext *ctx)

{

    return ((ctx->base.tb->cflags & CF_LAST_IO)

            || ctx->base.singlestep_enabled

            || singlestep);

}


static int register_insn (opc_handler_t **ppc_opcodes, opcode_t *insn)

{

    if (insn->opc2 != 0xFF) {

        if (insn->opc3 != 0xFF) {

            if (register_dblind_insn(ppc_opcodes, insn->opc1, insn->opc2,

                                     insn->opc3, &insn->handler) < 0)

                return -1;

        } else {

            if (register_ind_insn(ppc_opcodes, insn->opc1,

                                  insn->opc2, &insn->handler) < 0)

                return -1;

        }

    } else {

        if (register_direct_insn(ppc_opcodes, insn->opc1, &insn->handler) < 0)

            return -1;

    }

    return 0;

}


static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, size_t size)

{

    stellaris_enet_state *s = qemu_get_nic_opaque(nc);

    int n;

    uint8_t *p;

    uint32_t crc;

    if ((s->rctl & SE_RCTL_RXEN) == 0)

        return -1;

    if (s->np >= 31) {

        return 0;

    }

    DPRINTF("Received packet len=%zu\n", size);

    n = s->next_packet + s->np;

    if (n >= 31)

        n -= 31;

    s->np++;

    s->rx[n].len = size + 6;

    p = s->rx[n].data;

    *(p++) = (size + 6);

    *(p++) = (size + 6) >> 8;

    memcpy (p, buf, size);

    p += size;

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

    *(p++) = crc;

    *(p++) = crc >> 8;

    *(p++) = crc >> 16;

    *(p++) = crc >> 24;

    /* Clear the remaining bytes in the last word.  */

    if ((size & 3) != 2) {

        memset(p, 0, (6 - size) & 3);

    }

    s->ris |= SE_INT_RX;

    stellaris_enet_update(s);

    return size;

}


int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb)

{

    int len, tag;

    int object_type_id = avio_r8(pb);

    avio_r8(pb); /* stream type */

    avio_rb24(pb); /* buffer size db */

    avio_rb32(pb); /* max bitrate */

    avio_rb32(pb); /* avg bitrate */

    if(avcodec_is_open(st->codec)) {

        av_log(fc, AV_LOG_DEBUG, "codec open in read_dec_config_descr\n");

        return -1;

    }

    st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);

    av_dlog(fc, "esds object type id 0x%02x\n", object_type_id);

    len = ff_mp4_read_descr(fc, pb, &tag);

    if (tag == MP4DecSpecificDescrTag) {

        av_dlog(fc, "Specific MPEG4 header len=%d\n", len);

        if (!len || (uint64_t)len > (1<<30))

            return -1;

        av_free(st->codec->extradata);

        if (ff_alloc_extradata(st->codec, len))

            return AVERROR(ENOMEM);

        avio_read(pb, st->codec->extradata, len);

        if (st->codec->codec_id == AV_CODEC_ID_AAC) {

            MPEG4AudioConfig cfg = {0};

            avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata,

                                         st->codec->extradata_size * 8, 1);

            st->codec->channels = cfg.channels;

            if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4

                st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index];

            else if (cfg.ext_sample_rate)

                st->codec->sample_rate = cfg.ext_sample_rate;

            else

                st->codec->sample_rate = cfg.sample_rate;

            av_dlog(fc, "mp4a config channels %d obj %d ext obj %d "

                    "sample rate %d ext sample rate %d\n", st->codec->channels,

                    cfg.object_type, cfg.ext_object_type,

                    cfg.sample_rate, cfg.ext_sample_rate);

            if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,

                                                        cfg.object_type)))

                st->codec->codec_id = AV_CODEC_ID_AAC;

        }

    }

    return 0;

}


static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_count,

                                                      AudioData *in , int  in_count){

    AudioData *postin, *midbuf, *preout;

    int ret/*, in_max*/;

    AudioData preout_tmp, midbuf_tmp;

    if(s->full_convert){

        av_assert0(!s->resample);

        swri_audio_convert(s->full_convert, out, in, in_count);

        return out_count;

    }

//     in_max= out_count*(int64_t)s->in_sample_rate / s->out_sample_rate + resample_filter_taps;

//     in_count= FFMIN(in_count, in_in + 2 - s->hist_buffer_count);

    if((ret=swri_realloc_audio(&s->postin, in_count))<0)

        return ret;

    if(s->resample_first){

        av_assert0(s->midbuf.ch_count == s->used_ch_count);

        if((ret=swri_realloc_audio(&s->midbuf, out_count))<0)

            return ret;

    }else{

        av_assert0(s->midbuf.ch_count ==  s->out.ch_count);

        if((ret=swri_realloc_audio(&s->midbuf,  in_count))<0)

            return ret;

    }

    if((ret=swri_realloc_audio(&s->preout, out_count))<0)

        return ret;

    postin= &s->postin;

    midbuf_tmp= s->midbuf;

    midbuf= &midbuf_tmp;

    preout_tmp= s->preout;

    preout= &preout_tmp;

    if(s->int_sample_fmt == s-> in_sample_fmt && s->in.planar && !s->channel_map)

        postin= in;

    if(s->resample_first ? !s->resample : !s->rematrix)

        midbuf= postin;

    if(s->resample_first ? !s->rematrix : !s->resample)

        preout= midbuf;

    if(s->int_sample_fmt == s->out_sample_fmt && s->out.planar

       && !(s->out_sample_fmt==AV_SAMPLE_FMT_S32P && (s->dither.output_sample_bits&31))){

        if(preout==in){

            out_count= FFMIN(out_count, in_count); //TODO check at the end if this is needed or redundant

            av_assert0(s->in.planar); //we only support planar internally so it has to be, we support copying non planar though

            copy(out, in, out_count);

            return out_count;

        }

        else if(preout==postin) preout= midbuf= postin= out;

        else if(preout==midbuf) preout= midbuf= out;

        else                    preout= out;

    }

    if(in != postin){

        swri_audio_convert(s->in_convert, postin, in, in_count);

    }

    if(s->resample_first){

        if(postin != midbuf)

            out_count= resample(s, midbuf, out_count, postin, in_count);

        if(midbuf != preout)

            swri_rematrix(s, preout, midbuf, out_count, preout==out);

    }else{

        if(postin != midbuf)

            swri_rematrix(s, midbuf, postin, in_count, midbuf==out);

        if(midbuf != preout)

            out_count= resample(s, preout, out_count, midbuf, in_count);

    }

    if(preout != out && out_count){

        AudioData *conv_src = preout;

        if(s->dither.method){

            int ch;

            int dither_count= FFMAX(out_count, 1<<16);

            if (preout == in) {

                conv_src = &s->dither.temp;

                if((ret=swri_realloc_audio(&s->dither.temp, dither_count))<0)

                    return ret;

            }

            if((ret=swri_realloc_audio(&s->dither.noise, dither_count))<0)

                return ret;

            if(ret)

                for(ch=0; ch<s->dither.noise.ch_count; ch++)

                    if((ret=swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, 12345678913579<<ch, s->dither.noise.fmt))<0)

                        return ret;

            av_assert0(s->dither.noise.ch_count == preout->ch_count);

            if(s->dither.noise_pos + out_count > s->dither.noise.count)

                s->dither.noise_pos = 0;

            if (s->dither.method < SWR_DITHER_NS){

                if (s->mix_2_1_simd) {

                    int len1= out_count&~15;

                    int off = len1 * preout->bps;

                    if(len1)

                        for(ch=0; ch<preout->ch_count; ch++)

                            s->mix_2_1_simd(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_simd_one, 0, 0, len1);

                    if(out_count != len1)

                        for(ch=0; ch<preout->ch_count; ch++)

                            s->mix_2_1_f(conv_src->ch[ch] + off, preout->ch[ch] + off, s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos + off + len1, s->native_one, 0, 0, out_count - len1);

                } else {

                    for(ch=0; ch<preout->ch_count; ch++)

                        s->mix_2_1_f(conv_src->ch[ch], preout->ch[ch], s->dither.noise.ch[ch] + s->dither.noise.bps * s->dither.noise_pos, s->native_one, 0, 0, out_count);

                }

            } else {

                switch(s->int_sample_fmt) {

                case AV_SAMPLE_FMT_S16P :swri_noise_shaping_int16(s, conv_src, preout, &s->dither.noise, out_count); break;

                case AV_SAMPLE_FMT_S32P :swri_noise_shaping_int32(s, conv_src, preout, &s->dither.noise, out_count); break;

                case AV_SAMPLE_FMT_FLTP :swri_noise_shaping_float(s, conv_src, preout, &s->dither.noise, out_count); break;

                case AV_SAMPLE_FMT_DBLP :swri_noise_shaping_double(s,conv_src, preout, &s->dither.noise, out_count); break;

                }

            }

            s->dither.noise_pos += out_count;

        }

//FIXME packed doesn't need more than 1 chan here!

        swri_audio_convert(s->out_convert, out, conv_src, out_count);

    }

    return out_count;

}


int ff_probe_input_buffer(ByteIOContext **pb, AVInputFormat **fmt,

                          const char *filename, void *logctx,

                          unsigned int offset, unsigned int max_probe_size)

{

    AVProbeData pd = { filename ? filename : "", NULL, -offset };

    unsigned char *buf = NULL;

    int ret = 0, probe_size;

    if (!max_probe_size) {

        max_probe_size = PROBE_BUF_MAX;

    } else if (max_probe_size > PROBE_BUF_MAX) {

        max_probe_size = PROBE_BUF_MAX;

    } else if (max_probe_size < PROBE_BUF_MIN) {

        return AVERROR(EINVAL);

    }

    if (offset >= max_probe_size) {

        return AVERROR(EINVAL);

    }

    for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt && ret >= 0; probe_size<<=1){

        int ret, score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0;

        int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1;

        if (probe_size < offset) {

            continue;

        }

        /* read probe data */

        buf = av_realloc(buf, probe_size + AVPROBE_PADDING_SIZE);

        if ((ret = get_buffer(*pb, buf + buf_offset, probe_size - buf_offset)) < 0) {

            /* fail if error was not end of file, otherwise, lower score */

            if (ret != AVERROR_EOF) {

                av_free(buf);

                return ret;

            }

            score = 0;

            ret = 0;            /* error was end of file, nothing read */

        }

        pd.buf_size += ret;

        pd.buf = &buf[offset];

        memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE);

        /* guess file format */

        *fmt = av_probe_input_format2(&pd, 1, &score);

        if(*fmt){

            if(score <= AVPROBE_SCORE_MAX/4){ //this can only be true in the last iteration

                av_log(logctx, AV_LOG_WARNING, "Format detected only with low score of %d, misdetection possible!\n", score);

            }else

                av_log(logctx, AV_LOG_DEBUG, "Probed with size=%d and score=%d\n", probe_size, score);

        }

    }

    av_free(buf);

    if (url_fseek(*pb, 0, SEEK_SET) < 0) {

        url_fclose(*pb);

        if (url_fopen(pb, filename, URL_RDONLY) < 0)

            return AVERROR(EIO);

    }

    return 0;

}


static int metasound_read_bitstream(AVCodecContext *avctx, TwinVQContext *tctx,

                                    const uint8_t *buf, int buf_size)

{

    TwinVQFrameData     *bits = &tctx->bits;

    const TwinVQModeTab *mtab = tctx->mtab;

    int channels              = tctx->avctx->channels;

    int sub;

    GetBitContext gb;

    int i, j, k;

    if (buf_size * 8 < avctx->bit_rate * mtab->size / avctx->sample_rate) {

        av_log(avctx, AV_LOG_ERROR,

               "Frame too small (%d bytes). Truncated file?\n", buf_size);

        return AVERROR(EINVAL);

    }

    init_get_bits(&gb, buf, buf_size * 8);

    bits->window_type = get_bits(&gb, TWINVQ_WINDOW_TYPE_BITS);

    if (bits->window_type > 8) {

        av_log(avctx, AV_LOG_ERROR, "Invalid window type, broken sample?\n");

        return AVERROR_INVALIDDATA;

    }

    bits->ftype = ff_twinvq_wtype_to_ftype_table[tctx->bits.window_type];

    sub = mtab->fmode[bits->ftype].sub;

    if (bits->ftype != TWINVQ_FT_SHORT)

        get_bits(&gb, 2);

    read_cb_data(tctx, &gb, bits->main_coeffs, bits->ftype);

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

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

            for (k = 0; k < mtab->fmode[bits->ftype].bark_n_coef; k++)

                bits->bark1[i][j][k] =

                    get_bits(&gb, mtab->fmode[bits->ftype].bark_n_bit);

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

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

            bits->bark_use_hist[i][j] = get_bits1(&gb);

    if (bits->ftype == TWINVQ_FT_LONG) {

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

            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);

    } else {

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

            bits->gain_bits[i] = get_bits(&gb, TWINVQ_GAIN_BITS);

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

                bits->sub_gain_bits[i * sub + j] =

                    get_bits(&gb, TWINVQ_SUB_GAIN_BITS);

        }

    }

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

        bits->lpc_hist_idx[i] = get_bits(&gb, mtab->lsp_bit0);

        bits->lpc_idx1[i]     = get_bits(&gb, mtab->lsp_bit1);

        for (j = 0; j < mtab->lsp_split; j++)

            bits->lpc_idx2[i][j] = get_bits(&gb, mtab->lsp_bit2);

    }

    if (bits->ftype == TWINVQ_FT_LONG) {

        read_cb_data(tctx, &gb, bits->ppc_coeffs, 3);

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

            bits->p_coef[i] = get_bits(&gb, mtab->ppc_period_bit);

            bits->g_coef[i] = get_bits(&gb, mtab->pgain_bit);

        }

    }

    return 0;

}


static inline void yuv2packedXinC(SwsContext *c, int16_t *lumFilter, int16_t **lumSrc, int lumFilterSize,

				    int16_t *chrFilter, int16_t **chrSrc, int chrFilterSize,

				    uint8_t *dest, int dstW, int y)

{

	int i;

	switch(c->dstFormat)

	{

	case IMGFMT_RGB32:

	case IMGFMT_BGR32:

		YSCALE_YUV_2_RGBX_C(uint32_t)

			((uint32_t*)dest)[i2+0]= r[Y1] + g[Y1] + b[Y1];

			((uint32_t*)dest)[i2+1]= r[Y2] + g[Y2] + b[Y2];

		}

		break;

	case IMGFMT_RGB24:

		YSCALE_YUV_2_RGBX_C(uint8_t)

			((uint8_t*)dest)[0]= r[Y1];

			((uint8_t*)dest)[1]= g[Y1];

			((uint8_t*)dest)[2]= b[Y1];

			((uint8_t*)dest)[3]= r[Y2];

			((uint8_t*)dest)[4]= g[Y2];

			((uint8_t*)dest)[5]= b[Y2];

			((uint8_t*)dest)+=6;

		}


static int protocol_client_vencrypt_init(VncState *vs, uint8_t *data, size_t len)

{

    if (data[0] != 0 ||

        data[1] != 2) {

        VNC_DEBUG("Unsupported VeNCrypt protocol %d.%d\n", (int)data[0], (int)data[1]);

        vnc_write_u8(vs, 1); /* Reject version */

        vnc_flush(vs);

        vnc_client_error(vs);

    } else {

        VNC_DEBUG("Sending allowed auth %d\n", vs->vd->subauth);

        vnc_write_u8(vs, 0); /* Accept version */

        vnc_write_u8(vs, 1); /* Number of sub-auths */

        vnc_write_u32(vs, vs->vd->subauth); /* The supported auth */

        vnc_flush(vs);

        vnc_read_when(vs, protocol_client_vencrypt_auth, 4);

    }

    return 0;

}


static int qemu_rdma_exchange_send(RDMAContext *rdma, RDMAControlHeader *head,

                                   uint8_t *data, RDMAControlHeader *resp,

                                   int *resp_idx,

                                   int (*callback)(RDMAContext *rdma))

{

    int ret = 0;

    /*

     * Wait until the dest is ready before attempting to deliver the message

     * by waiting for a READY message.

     */

    if (rdma->control_ready_expected) {

        RDMAControlHeader resp;

        ret = qemu_rdma_exchange_get_response(rdma,

                                    &resp, RDMA_CONTROL_READY, RDMA_WRID_READY);

        if (ret < 0) {

            return ret;

        }

    }

    /*

     * If the user is expecting a response, post a WR in anticipation of it.

     */

    if (resp) {

        ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_DATA);

        if (ret) {

            error_report("rdma migration: error posting"

                    " extra control recv for anticipated result!");

            return ret;

        }

    }

    /*

     * Post a WR to replace the one we just consumed for the READY message.

     */

    ret = qemu_rdma_post_recv_control(rdma, RDMA_WRID_READY);

    if (ret) {

        error_report("rdma migration: error posting first control recv!");

        return ret;

    }

    /*

     * Deliver the control message that was requested.

     */

    ret = qemu_rdma_post_send_control(rdma, data, head);

    if (ret < 0) {

        error_report("Failed to send control buffer!");

        return ret;

    }

    /*

     * If we're expecting a response, block and wait for it.

     */

    if (resp) {

        if (callback) {

            trace_qemu_rdma_exchange_send_issue_callback();

            ret = callback(rdma);

            if (ret < 0) {

                return ret;

            }

        }

        trace_qemu_rdma_exchange_send_waiting(control_desc[resp->type]);

        ret = qemu_rdma_exchange_get_response(rdma, resp,

                                              resp->type, RDMA_WRID_DATA);

        if (ret < 0) {

            return ret;

        }

        qemu_rdma_move_header(rdma, RDMA_WRID_DATA, resp);

        if (resp_idx) {

            *resp_idx = RDMA_WRID_DATA;

        }

        trace_qemu_rdma_exchange_send_received(control_desc[resp->type]);

    }

    rdma->control_ready_expected = 1;

    return 0;

}


static void isa_ne2000_set_bootindex(Object *obj, Visitor *v,

                                     const char *name, void *opaque,

                                     Error **errp)

{

    ISANE2000State *isa = ISA_NE2000(obj);

    NE2000State *s = &isa->ne2000;

    int32_t boot_index;

    Error *local_err = NULL;

    visit_type_int32(v, name, &boot_index, &local_err);

    if (local_err) {

        goto out;

    }

    /* check whether bootindex is present in fw_boot_order list  */

    check_boot_index(boot_index, &local_err);

    if (local_err) {

        goto out;

    }

    /* change bootindex to a new one */

    s->c.bootindex = boot_index;

out:

    if (local_err) {

        error_propagate(errp, local_err);

    }

}


static void dynticks_rearm_timer(struct qemu_alarm_timer *t)

{

    timer_t host_timer = (timer_t)(long)t->priv;

    struct itimerspec timeout;

    int64_t nearest_delta_us = INT64_MAX;

    int64_t current_us;

    if (!active_timers[QEMU_TIMER_REALTIME] &&

                !active_timers[QEMU_TIMER_VIRTUAL])

        return;

    nearest_delta_us = qemu_next_deadline_dyntick();

    /* check whether a timer is already running */

    if (timer_gettime(host_timer, &timeout)) {

        perror("gettime");

        fprintf(stderr, "Internal timer error: aborting\n");

        exit(1);

    }

    current_us = timeout.it_value.tv_sec * 1000000 + timeout.it_value.tv_nsec/1000;

    if (current_us && current_us <= nearest_delta_us)

        return;

    timeout.it_interval.tv_sec = 0;

    timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */

    timeout.it_value.tv_sec =  nearest_delta_us / 1000000;

    timeout.it_value.tv_nsec = (nearest_delta_us % 1000000) * 1000;

    if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) {

        perror("settime");

        fprintf(stderr, "Internal timer error: aborting\n");

        exit(1);

    }

}


static int64_t coroutine_fn bdrv_co_get_block_status_above(BlockDriverState *bs,

        BlockDriverState *base,

        int64_t sector_num,

        int nb_sectors,

        int *pnum)

{

    BlockDriverState *p;

    int64_t ret = 0;

    assert(bs != base);

    for (p = bs; p != base; p = backing_bs(p)) {

        ret = bdrv_co_get_block_status(p, sector_num, nb_sectors, pnum);

        if (ret < 0 || ret & BDRV_BLOCK_ALLOCATED) {

            break;

        }

        /* [sector_num, pnum] unallocated on this layer, which could be only

         * the first part of [sector_num, nb_sectors].  */

        nb_sectors = MIN(nb_sectors, *pnum);

    }

    return ret;

}


timer_write(void *opaque, hwaddr addr,

            uint64_t val64, unsigned int size)

{

    struct timerblock *t = opaque;

    struct xlx_timer *xt;

    unsigned int timer;

    uint32_t value = val64;

    addr >>= 2;

    timer = timer_from_addr(addr);

    xt = &t->timers[timer];

    D(fprintf(stderr, "%s addr=%x val=%x (timer=%d off=%d)\n",

             __func__, addr * 4, value, timer, addr & 3));

    /* Further decoding to address a specific timers reg.  */

    addr &= 3;

    switch (addr)

    {

        case R_TCSR:

            if (value & TCSR_TINT)

                value &= ~TCSR_TINT;

            xt->regs[addr] = value;

            if (value & TCSR_ENT)

                timer_enable(xt);

            break;

        default:

            if (addr < ARRAY_SIZE(xt->regs))

                xt->regs[addr] = value;

            break;

    }

    timer_update_irq(t);

}