av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) { int i; ff_check_alignment(); #if CONFIG_ENCODERS if (avctx->bits_per_raw_sample == 10) { c->fdct = ff_jpeg_fdct_islow_10; c->fdct248 = ff_fdct248_islow_10; } else { if(avctx->dct_algo==FF_DCT_FASTINT) { c->fdct = fdct_ifast; c->fdct248 = fdct_ifast248; } else if(avctx->dct_algo==FF_DCT_FAAN) { c->fdct = ff_faandct; c->fdct248 = ff_faandct248; } else { c->fdct = ff_jpeg_fdct_islow_8; //slow/accurate/default c->fdct248 = ff_fdct248_islow_8; } } #endif //CONFIG_ENCODERS if(avctx->lowres==1){ c->idct_put= ff_jref_idct4_put; c->idct_add= ff_jref_idct4_add; c->idct = j_rev_dct4; c->idct_permutation_type= FF_NO_IDCT_PERM; }else if(avctx->lowres==2){ c->idct_put= ff_jref_idct2_put; c->idct_add= ff_jref_idct2_add; c->idct = j_rev_dct2; c->idct_permutation_type= FF_NO_IDCT_PERM; }else if(avctx->lowres==3){ c->idct_put= ff_jref_idct1_put; c->idct_add= ff_jref_idct1_add; c->idct = j_rev_dct1; c->idct_permutation_type= FF_NO_IDCT_PERM; }else{ if (avctx->bits_per_raw_sample == 10) { c->idct_put = ff_simple_idct_put_10; c->idct_add = ff_simple_idct_add_10; c->idct = ff_simple_idct_10; c->idct_permutation_type = FF_NO_IDCT_PERM; } else { if(avctx->idct_algo==FF_IDCT_INT){ c->idct_put= ff_jref_idct_put; c->idct_add= ff_jref_idct_add; c->idct = j_rev_dct; c->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM; }else if((CONFIG_VP3_DECODER || CONFIG_VP5_DECODER || CONFIG_VP6_DECODER ) && avctx->idct_algo==FF_IDCT_VP3){ c->idct_put= ff_vp3_idct_put_c; c->idct_add= ff_vp3_idct_add_c; c->idct = ff_vp3_idct_c; c->idct_permutation_type= FF_NO_IDCT_PERM; }else if(avctx->idct_algo==FF_IDCT_WMV2){ c->idct_put= ff_wmv2_idct_put_c; c->idct_add= ff_wmv2_idct_add_c; c->idct = ff_wmv2_idct_c; c->idct_permutation_type= FF_NO_IDCT_PERM; }else if(avctx->idct_algo==FF_IDCT_FAAN){ c->idct_put= ff_faanidct_put; c->idct_add= ff_faanidct_add; c->idct = ff_faanidct; c->idct_permutation_type= FF_NO_IDCT_PERM; }else if(CONFIG_EATGQ_DECODER && avctx->idct_algo==FF_IDCT_EA) { c->idct_put= ff_ea_idct_put_c; c->idct_permutation_type= FF_NO_IDCT_PERM; }else{ //accurate/default c->idct_put = ff_simple_idct_put_8; c->idct_add = ff_simple_idct_add_8; c->idct = ff_simple_idct_8; c->idct_permutation_type= FF_NO_IDCT_PERM; } } } c->diff_pixels = diff_pixels_c; c->put_pixels_clamped = ff_put_pixels_clamped_c; c->put_signed_pixels_clamped = ff_put_signed_pixels_clamped_c; c->add_pixels_clamped = ff_add_pixels_clamped_c; c->sum_abs_dctelem = sum_abs_dctelem_c; c->gmc1 = gmc1_c; c->gmc = ff_gmc_c; c->pix_sum = pix_sum_c; c->pix_norm1 = pix_norm1_c; c->fill_block_tab[0] = fill_block16_c; c->fill_block_tab[1] = fill_block8_c; /* TODO [0] 16 [1] 8 */ c->pix_abs[0][0] = pix_abs16_c; c->pix_abs[0][1] = pix_abs16_x2_c; c->pix_abs[0][2] = pix_abs16_y2_c; c->pix_abs[0][3] = pix_abs16_xy2_c; c->pix_abs[1][0] = pix_abs8_c; c->pix_abs[1][1] = pix_abs8_x2_c; c->pix_abs[1][2] = pix_abs8_y2_c; c->pix_abs[1][3] = pix_abs8_xy2_c; c->put_tpel_pixels_tab[ 0] = put_tpel_pixels_mc00_c; c->put_tpel_pixels_tab[ 1] = put_tpel_pixels_mc10_c; c->put_tpel_pixels_tab[ 2] = put_tpel_pixels_mc20_c; c->put_tpel_pixels_tab[ 4] = put_tpel_pixels_mc01_c; c->put_tpel_pixels_tab[ 5] = put_tpel_pixels_mc11_c; c->put_tpel_pixels_tab[ 6] = put_tpel_pixels_mc21_c; c->put_tpel_pixels_tab[ 8] = put_tpel_pixels_mc02_c; c->put_tpel_pixels_tab[ 9] = put_tpel_pixels_mc12_c; c->put_tpel_pixels_tab[10] = put_tpel_pixels_mc22_c; c->avg_tpel_pixels_tab[ 0] = avg_tpel_pixels_mc00_c; c->avg_tpel_pixels_tab[ 1] = avg_tpel_pixels_mc10_c; c->avg_tpel_pixels_tab[ 2] = avg_tpel_pixels_mc20_c; c->avg_tpel_pixels_tab[ 4] = avg_tpel_pixels_mc01_c; c->avg_tpel_pixels_tab[ 5] = avg_tpel_pixels_mc11_c; c->avg_tpel_pixels_tab[ 6] = avg_tpel_pixels_mc21_c; c->avg_tpel_pixels_tab[ 8] = avg_tpel_pixels_mc02_c; c->avg_tpel_pixels_tab[ 9] = avg_tpel_pixels_mc12_c; c->avg_tpel_pixels_tab[10] = avg_tpel_pixels_mc22_c; #define dspfunc(PFX, IDX, NUM) \ c->PFX ## _pixels_tab[IDX][ 0] = PFX ## NUM ## _mc00_c; \ c->PFX ## _pixels_tab[IDX][ 1] = PFX ## NUM ## _mc10_c; \ c->PFX ## _pixels_tab[IDX][ 2] = PFX ## NUM ## _mc20_c; \ c->PFX ## _pixels_tab[IDX][ 3] = PFX ## NUM ## _mc30_c; \ c->PFX ## _pixels_tab[IDX][ 4] = PFX ## NUM ## _mc01_c; \ c->PFX ## _pixels_tab[IDX][ 5] = PFX ## NUM ## _mc11_c; \ c->PFX ## _pixels_tab[IDX][ 6] = PFX ## NUM ## _mc21_c; \ c->PFX ## _pixels_tab[IDX][ 7] = PFX ## NUM ## _mc31_c; \ c->PFX ## _pixels_tab[IDX][ 8] = PFX ## NUM ## _mc02_c; \ c->PFX ## _pixels_tab[IDX][ 9] = PFX ## NUM ## _mc12_c; \ c->PFX ## _pixels_tab[IDX][10] = PFX ## NUM ## _mc22_c; \ c->PFX ## _pixels_tab[IDX][11] = PFX ## NUM ## _mc32_c; \ c->PFX ## _pixels_tab[IDX][12] = PFX ## NUM ## _mc03_c; \ c->PFX ## _pixels_tab[IDX][13] = PFX ## NUM ## _mc13_c; \ c->PFX ## _pixels_tab[IDX][14] = PFX ## NUM ## _mc23_c; \ c->PFX ## _pixels_tab[IDX][15] = PFX ## NUM ## _mc33_c dspfunc(put_qpel, 0, 16); dspfunc(put_no_rnd_qpel, 0, 16); dspfunc(avg_qpel, 0, 16); /* dspfunc(avg_no_rnd_qpel, 0, 16); */ dspfunc(put_qpel, 1, 8); dspfunc(put_no_rnd_qpel, 1, 8); dspfunc(avg_qpel, 1, 8); /* dspfunc(avg_no_rnd_qpel, 1, 8); */ #undef dspfunc #if CONFIG_MLP_DECODER || CONFIG_TRUEHD_DECODER ff_mlp_init(c, avctx); #endif #if CONFIG_WMV2_DECODER || CONFIG_VC1_DECODER ff_intrax8dsp_init(c,avctx); #endif c->put_mspel_pixels_tab[0]= ff_put_pixels8x8_c; c->put_mspel_pixels_tab[1]= put_mspel8_mc10_c; c->put_mspel_pixels_tab[2]= put_mspel8_mc20_c; c->put_mspel_pixels_tab[3]= put_mspel8_mc30_c; c->put_mspel_pixels_tab[4]= put_mspel8_mc02_c; c->put_mspel_pixels_tab[5]= put_mspel8_mc12_c; c->put_mspel_pixels_tab[6]= put_mspel8_mc22_c; c->put_mspel_pixels_tab[7]= put_mspel8_mc32_c; #define SET_CMP_FUNC(name) \ c->name[0]= name ## 16_c;\ c->name[1]= name ## 8x8_c; SET_CMP_FUNC(hadamard8_diff) c->hadamard8_diff[4]= hadamard8_intra16_c; c->hadamard8_diff[5]= hadamard8_intra8x8_c; SET_CMP_FUNC(dct_sad) SET_CMP_FUNC(dct_max) #if CONFIG_GPL SET_CMP_FUNC(dct264_sad) #endif c->sad[0]= pix_abs16_c; c->sad[1]= pix_abs8_c; c->sse[0]= sse16_c; c->sse[1]= sse8_c; c->sse[2]= sse4_c; SET_CMP_FUNC(quant_psnr) SET_CMP_FUNC(rd) SET_CMP_FUNC(bit) c->vsad[0]= vsad16_c; c->vsad[4]= vsad_intra16_c; c->vsad[5]= vsad_intra8_c; c->vsse[0]= vsse16_c; c->vsse[4]= vsse_intra16_c; c->vsse[5]= vsse_intra8_c; c->nsse[0]= nsse16_c; c->nsse[1]= nsse8_c; #if CONFIG_DWT ff_dsputil_init_dwt(c); #endif c->ssd_int8_vs_int16 = ssd_int8_vs_int16_c; c->add_bytes= add_bytes_c; c->diff_bytes= diff_bytes_c; c->add_hfyu_median_prediction= add_hfyu_median_prediction_c; c->sub_hfyu_median_prediction= sub_hfyu_median_prediction_c; c->add_hfyu_left_prediction = add_hfyu_left_prediction_c; c->add_hfyu_left_prediction_bgr32 = add_hfyu_left_prediction_bgr32_c; c->bswap_buf= bswap_buf; c->bswap16_buf = bswap16_buf; if (CONFIG_H263_DECODER || CONFIG_H263_ENCODER) { c->h263_h_loop_filter= h263_h_loop_filter_c; c->h263_v_loop_filter= h263_v_loop_filter_c; } if (CONFIG_VP3_DECODER) { c->vp3_h_loop_filter= ff_vp3_h_loop_filter_c; c->vp3_v_loop_filter= ff_vp3_v_loop_filter_c; c->vp3_idct_dc_add= ff_vp3_idct_dc_add_c; } c->h261_loop_filter= h261_loop_filter_c; c->try_8x8basis= try_8x8basis_c; c->add_8x8basis= add_8x8basis_c; #if CONFIG_VORBIS_DECODER c->vorbis_inverse_coupling = vorbis_inverse_coupling; #endif #if CONFIG_AC3_DECODER c->ac3_downmix = ff_ac3_downmix_c; #endif c->vector_fmul = vector_fmul_c; c->vector_fmul_reverse = vector_fmul_reverse_c; c->vector_fmul_add = vector_fmul_add_c; c->vector_fmul_window = vector_fmul_window_c; c->vector_clipf = vector_clipf_c; c->scalarproduct_int16 = scalarproduct_int16_c; c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_c; c->apply_window_int16 = apply_window_int16_c; c->vector_clip_int32 = vector_clip_int32_c; c->scalarproduct_float = scalarproduct_float_c; c->butterflies_float = butterflies_float_c; c->butterflies_float_interleave = butterflies_float_interleave_c; c->vector_fmul_scalar = vector_fmul_scalar_c; c->vector_fmac_scalar = vector_fmac_scalar_c; c->shrink[0]= av_image_copy_plane; c->shrink[1]= ff_shrink22; c->shrink[2]= ff_shrink44; c->shrink[3]= ff_shrink88; c->prefetch= just_return; memset(c->put_2tap_qpel_pixels_tab, 0, sizeof(c->put_2tap_qpel_pixels_tab)); memset(c->avg_2tap_qpel_pixels_tab, 0, sizeof(c->avg_2tap_qpel_pixels_tab)); #undef FUNC #undef FUNCC #define FUNC(f, depth) f ## _ ## depth #define FUNCC(f, depth) f ## _ ## depth ## _c #define dspfunc1(PFX, IDX, NUM, depth)\ c->PFX ## _pixels_tab[IDX][0] = FUNCC(PFX ## _pixels ## NUM , depth);\ c->PFX ## _pixels_tab[IDX][1] = FUNCC(PFX ## _pixels ## NUM ## _x2 , depth);\ c->PFX ## _pixels_tab[IDX][2] = FUNCC(PFX ## _pixels ## NUM ## _y2 , depth);\ c->PFX ## _pixels_tab[IDX][3] = FUNCC(PFX ## _pixels ## NUM ## _xy2, depth) #define dspfunc2(PFX, IDX, NUM, depth)\ c->PFX ## _pixels_tab[IDX][ 0] = FUNCC(PFX ## NUM ## _mc00, depth);\ c->PFX ## _pixels_tab[IDX][ 1] = FUNCC(PFX ## NUM ## _mc10, depth);\ c->PFX ## _pixels_tab[IDX][ 2] = FUNCC(PFX ## NUM ## _mc20, depth);\ c->PFX ## _pixels_tab[IDX][ 3] = FUNCC(PFX ## NUM ## _mc30, depth);\ c->PFX ## _pixels_tab[IDX][ 4] = FUNCC(PFX ## NUM ## _mc01, depth);\ c->PFX ## _pixels_tab[IDX][ 5] = FUNCC(PFX ## NUM ## _mc11, depth);\ c->PFX ## _pixels_tab[IDX][ 6] = FUNCC(PFX ## NUM ## _mc21, depth);\ c->PFX ## _pixels_tab[IDX][ 7] = FUNCC(PFX ## NUM ## _mc31, depth);\ c->PFX ## _pixels_tab[IDX][ 8] = FUNCC(PFX ## NUM ## _mc02, depth);\ c->PFX ## _pixels_tab[IDX][ 9] = FUNCC(PFX ## NUM ## _mc12, depth);\ c->PFX ## _pixels_tab[IDX][10] = FUNCC(PFX ## NUM ## _mc22, depth);\ c->PFX ## _pixels_tab[IDX][11] = FUNCC(PFX ## NUM ## _mc32, depth);\ c->PFX ## _pixels_tab[IDX][12] = FUNCC(PFX ## NUM ## _mc03, depth);\ c->PFX ## _pixels_tab[IDX][13] = FUNCC(PFX ## NUM ## _mc13, depth);\ c->PFX ## _pixels_tab[IDX][14] = FUNCC(PFX ## NUM ## _mc23, depth);\ c->PFX ## _pixels_tab[IDX][15] = FUNCC(PFX ## NUM ## _mc33, depth) #define BIT_DEPTH_FUNCS(depth, dct)\ c->get_pixels = FUNCC(get_pixels ## dct , depth);\ c->draw_edges = FUNCC(draw_edges , depth);\ c->emulated_edge_mc = FUNC (ff_emulated_edge_mc , depth);\ c->clear_block = FUNCC(clear_block ## dct , depth);\ c->clear_blocks = FUNCC(clear_blocks ## dct , depth);\ c->add_pixels8 = FUNCC(add_pixels8 ## dct , depth);\ c->add_pixels4 = FUNCC(add_pixels4 ## dct , depth);\ c->put_no_rnd_pixels_l2[0] = FUNCC(put_no_rnd_pixels16_l2, depth);\ c->put_no_rnd_pixels_l2[1] = FUNCC(put_no_rnd_pixels8_l2 , depth);\ \ c->put_h264_chroma_pixels_tab[0] = FUNCC(put_h264_chroma_mc8 , depth);\ c->put_h264_chroma_pixels_tab[1] = FUNCC(put_h264_chroma_mc4 , depth);\ c->put_h264_chroma_pixels_tab[2] = FUNCC(put_h264_chroma_mc2 , depth);\ c->avg_h264_chroma_pixels_tab[0] = FUNCC(avg_h264_chroma_mc8 , depth);\ c->avg_h264_chroma_pixels_tab[1] = FUNCC(avg_h264_chroma_mc4 , depth);\ c->avg_h264_chroma_pixels_tab[2] = FUNCC(avg_h264_chroma_mc2 , depth);\ \ dspfunc1(put , 0, 16, depth);\ dspfunc1(put , 1, 8, depth);\ dspfunc1(put , 2, 4, depth);\ dspfunc1(put , 3, 2, depth);\ dspfunc1(put_no_rnd, 0, 16, depth);\ dspfunc1(put_no_rnd, 1, 8, depth);\ dspfunc1(avg , 0, 16, depth);\ dspfunc1(avg , 1, 8, depth);\ dspfunc1(avg , 2, 4, depth);\ dspfunc1(avg , 3, 2, depth);\ dspfunc1(avg_no_rnd, 0, 16, depth);\ dspfunc1(avg_no_rnd, 1, 8, depth);\ \ dspfunc2(put_h264_qpel, 0, 16, depth);\ dspfunc2(put_h264_qpel, 1, 8, depth);\ dspfunc2(put_h264_qpel, 2, 4, depth);\ dspfunc2(put_h264_qpel, 3, 2, depth);\ dspfunc2(avg_h264_qpel, 0, 16, depth);\ dspfunc2(avg_h264_qpel, 1, 8, depth);\ dspfunc2(avg_h264_qpel, 2, 4, depth); switch (avctx->bits_per_raw_sample) { case 9: if (c->dct_bits == 32) { BIT_DEPTH_FUNCS(9, _32); } else { BIT_DEPTH_FUNCS(9, _16); } break; case 10: if (c->dct_bits == 32) { BIT_DEPTH_FUNCS(10, _32); } else { BIT_DEPTH_FUNCS(10, _16); } break; default: av_log(avctx, AV_LOG_DEBUG, "Unsupported bit depth: %d\n", avctx->bits_per_raw_sample); case 8: BIT_DEPTH_FUNCS(8, _16); break; } if (HAVE_MMX) dsputil_init_mmx (c, avctx); if (ARCH_ARM) dsputil_init_arm (c, avctx); if (CONFIG_MLIB) dsputil_init_mlib (c, avctx); if (HAVE_VIS) dsputil_init_vis (c, avctx); if (ARCH_ALPHA) dsputil_init_alpha (c, avctx); if (ARCH_PPC) dsputil_init_ppc (c, avctx); if (HAVE_MMI) dsputil_init_mmi (c, avctx); if (ARCH_SH4) dsputil_init_sh4 (c, avctx); if (ARCH_BFIN) dsputil_init_bfin (c, avctx); for(i=0; i<64; i++){ if(!c->put_2tap_qpel_pixels_tab[0][i]) c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; if(!c->avg_2tap_qpel_pixels_tab[0][i]) c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; } ff_init_scantable_permutation(c->idct_permutation, c->idct_permutation_type); }


static void decode(GetByteContext *gb, RangeCoder *rc, unsigned cumFreq, unsigned freq, unsigned total_freq) { rc->code -= cumFreq * rc->range; rc->range *= freq; while (rc->range < TOP && bytestream2_get_bytes_left(gb) > 0) { unsigned byte = bytestream2_get_byte(gb); rc->code = (rc->code << 8) | byte; rc->range <<= 8; } }


int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags) { PerThreadContext *p = avctx->internal->thread_ctx; int err; f->owner = avctx; if (!(avctx->active_thread_type & FF_THREAD_FRAME)) return ff_get_buffer(avctx, f->f, flags); if (atomic_load(&p->state) != STATE_SETTING_UP && (avctx->codec->update_thread_context || !avctx->thread_safe_callbacks)) { av_log(avctx, AV_LOG_ERROR, "get_buffer() cannot be called after ff_thread_finish_setup()\n"); return -1; } if (avctx->internal->allocate_progress) { atomic_int *progress; f->progress = av_buffer_alloc(2 * sizeof(*progress)); if (!f->progress) { return AVERROR(ENOMEM); } progress = (atomic_int*)f->progress->data; atomic_store(&progress[0], -1); atomic_store(&progress[1], -1); } pthread_mutex_lock(&p->parent->buffer_mutex); if (avctx->thread_safe_callbacks || avctx->get_buffer2 == avcodec_default_get_buffer2) { err = ff_get_buffer(avctx, f->f, flags); } else { p->requested_frame = f->f; p->requested_flags = flags; atomic_store_explicit(&p->state, STATE_GET_BUFFER, memory_order_release); pthread_mutex_lock(&p->progress_mutex); pthread_cond_signal(&p->progress_cond); while (atomic_load(&p->state) != STATE_SETTING_UP) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); err = p->result; pthread_mutex_unlock(&p->progress_mutex); } if (!avctx->thread_safe_callbacks && !avctx->codec->update_thread_context) ff_thread_finish_setup(avctx); if (err) av_buffer_unref(&f->progress); pthread_mutex_unlock(&p->parent->buffer_mutex); return err; }


static void nfs_refresh_filename(BlockDriverState *bs, QDict *options) { NFSClient *client = bs->opaque; QDict *opts = qdict_new(); QObject *server_qdict; Visitor *ov; qdict_put(opts, "driver", qstring_from_str("nfs")); if (client->uid && !client->gid) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nfs://%s%s?uid=%" PRId64, client->server->host, client->path, client->uid); } else if (!client->uid && client->gid) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nfs://%s%s?gid=%" PRId64, client->server->host, client->path, client->gid); } else if (client->uid && client->gid) { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nfs://%s%s?uid=%" PRId64 "&gid=%" PRId64, client->server->host, client->path, client->uid, client->gid); } else { snprintf(bs->exact_filename, sizeof(bs->exact_filename), "nfs://%s%s", client->server->host, client->path); } ov = qobject_output_visitor_new(&server_qdict); visit_type_NFSServer(ov, NULL, &client->server, &error_abort); visit_complete(ov, &server_qdict); assert(qobject_type(server_qdict) == QTYPE_QDICT); qdict_put_obj(opts, "server", server_qdict); qdict_put(opts, "path", qstring_from_str(client->path)); if (client->uid) { qdict_put(opts, "user", qint_from_int(client->uid)); } if (client->gid) { qdict_put(opts, "group", qint_from_int(client->gid)); } if (client->tcp_syncnt) { qdict_put(opts, "tcp-syn-cnt", qint_from_int(client->tcp_syncnt)); } if (client->readahead) { qdict_put(opts, "readahead-size", qint_from_int(client->readahead)); } if (client->pagecache) { qdict_put(opts, "page-cache-size", qint_from_int(client->pagecache)); } if (client->debug) { qdict_put(opts, "debug", qint_from_int(client->debug)); } visit_free(ov); qdict_flatten(opts); bs->full_open_options = opts; }


static void pci_basic(gconstpointer data) { QVirtioPCIDevice *dev; QPCIBus *bus; QVirtQueuePCI *tx, *rx; QGuestAllocator *alloc; void (*func) (QVirtioDevice *dev, QGuestAllocator *alloc, QVirtQueue *rvq, QVirtQueue *tvq, int socket) = data; int sv[2], ret; ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv); g_assert_cmpint(ret, !=, -1); bus = pci_test_start(sv[1]); dev = virtio_net_pci_init(bus, PCI_SLOT); alloc = pc_alloc_init(); rx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, alloc, 0); tx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, alloc, 1); driver_init(&dev->vdev); func(&dev->vdev, alloc, &rx->vq, &tx->vq, sv[0]); /* End test */ close(sv[0]); qvirtqueue_cleanup(dev->vdev.bus, &tx->vq, alloc); qvirtqueue_cleanup(dev->vdev.bus, &rx->vq, alloc); pc_alloc_uninit(alloc); qvirtio_pci_device_disable(dev); g_free(dev->pdev); g_free(dev); qpci_free_pc(bus); test_end(); }


static void qmp_input_type_bool(Visitor *v, const char *name, bool *obj, Error **errp) { QmpInputVisitor *qiv = to_qiv(v); QObject *qobj = qmp_input_get_object(qiv, name, true, errp); QBool *qbool; if (!qobj) { return; } qbool = qobject_to_qbool(qobj); if (!qbool) { error_setg(errp, QERR_INVALID_PARAMETER_TYPE, name ? name : "null", "boolean"); return; } *obj = qbool_get_bool(qbool); }


static int spapr_vio_busdev_init(DeviceState *qdev, DeviceInfo *qinfo) { VIOsPAPRDeviceInfo *info = (VIOsPAPRDeviceInfo *)qinfo; VIOsPAPRDevice *dev = (VIOsPAPRDevice *)qdev; char *id; int ret; ret = spapr_vio_check_reg(dev, info); if (ret) { return ret; } /* Don't overwrite ids assigned on the command line */ if (!dev->qdev.id) { id = vio_format_dev_name(dev); if (!id) { return -1; } dev->qdev.id = id; } dev->qirq = spapr_allocate_irq(dev->vio_irq_num, &dev->vio_irq_num); if (!dev->qirq) { return -1; } rtce_init(dev); return info->init(dev); }


static DriveInfo *blockdev_init(QDict *bs_opts, BlockInterfaceType type, DriveMediaType media) { const char *buf; const char *file = NULL; const char *serial; int ro = 0; int bdrv_flags = 0; int on_read_error, on_write_error; DriveInfo *dinfo; ThrottleConfig cfg; int snapshot = 0; bool copy_on_read; int ret; Error *error = NULL; QemuOpts *opts; const char *id; bool has_driver_specific_opts; BlockDriver *drv = NULL; /* Check common options by copying from bs_opts to opts, all other options * stay in bs_opts for processing by bdrv_open(). */ id = qdict_get_try_str(bs_opts, "id"); opts = qemu_opts_create(&qemu_common_drive_opts, id, 1, &error); if (error_is_set(&error)) { qerror_report_err(error); error_free(error); return NULL; } qemu_opts_absorb_qdict(opts, bs_opts, &error); if (error_is_set(&error)) { qerror_report_err(error); error_free(error); return NULL; } if (id) { qdict_del(bs_opts, "id"); } has_driver_specific_opts = !!qdict_size(bs_opts); /* extract parameters */ snapshot = qemu_opt_get_bool(opts, "snapshot", 0); ro = qemu_opt_get_bool(opts, "read-only", 0); copy_on_read = qemu_opt_get_bool(opts, "copy-on-read", false); file = qemu_opt_get(opts, "file"); serial = qemu_opt_get(opts, "serial"); if ((buf = qemu_opt_get(opts, "discard")) != NULL) { if (bdrv_parse_discard_flags(buf, &bdrv_flags) != 0) { error_report("invalid discard option"); return NULL; } } if (qemu_opt_get_bool(opts, "cache.writeback", true)) { bdrv_flags |= BDRV_O_CACHE_WB; } if (qemu_opt_get_bool(opts, "cache.direct", false)) { bdrv_flags |= BDRV_O_NOCACHE; } if (qemu_opt_get_bool(opts, "cache.no-flush", false)) { bdrv_flags |= BDRV_O_NO_FLUSH; } #ifdef CONFIG_LINUX_AIO if ((buf = qemu_opt_get(opts, "aio")) != NULL) { if (!strcmp(buf, "native")) { bdrv_flags |= BDRV_O_NATIVE_AIO; } else if (!strcmp(buf, "threads")) { /* this is the default */ } else { error_report("invalid aio option"); return NULL; } } #endif if ((buf = qemu_opt_get(opts, "format")) != NULL) { if (is_help_option(buf)) { error_printf("Supported formats:"); bdrv_iterate_format(bdrv_format_print, NULL); error_printf("\n"); return NULL; } drv = bdrv_find_format(buf); if (!drv) { error_report("'%s' invalid format", buf); return NULL; } } /* disk I/O throttling */ memset(&cfg, 0, sizeof(cfg)); cfg.buckets[THROTTLE_BPS_TOTAL].avg = qemu_opt_get_number(opts, "throttling.bps-total", 0); cfg.buckets[THROTTLE_BPS_READ].avg = qemu_opt_get_number(opts, "throttling.bps-read", 0); cfg.buckets[THROTTLE_BPS_WRITE].avg = qemu_opt_get_number(opts, "throttling.bps-write", 0); cfg.buckets[THROTTLE_OPS_TOTAL].avg = qemu_opt_get_number(opts, "throttling.iops-total", 0); cfg.buckets[THROTTLE_OPS_READ].avg = qemu_opt_get_number(opts, "throttling.iops-read", 0); cfg.buckets[THROTTLE_OPS_WRITE].avg = qemu_opt_get_number(opts, "throttling.iops-write", 0); cfg.buckets[THROTTLE_BPS_TOTAL].max = qemu_opt_get_number(opts, "throttling.bps-total-max", 0); cfg.buckets[THROTTLE_BPS_READ].max = qemu_opt_get_number(opts, "throttling.bps-read-max", 0); cfg.buckets[THROTTLE_BPS_WRITE].max = qemu_opt_get_number(opts, "throttling.bps-write-max", 0); cfg.buckets[THROTTLE_OPS_TOTAL].max = qemu_opt_get_number(opts, "throttling.iops-total-max", 0); cfg.buckets[THROTTLE_OPS_READ].max = qemu_opt_get_number(opts, "throttling.iops-read-max", 0); cfg.buckets[THROTTLE_OPS_WRITE].max = qemu_opt_get_number(opts, "throttling.iops-write-max", 0); cfg.op_size = qemu_opt_get_number(opts, "throttling.iops-size", 0); if (!check_throttle_config(&cfg, &error)) { error_report("%s", error_get_pretty(error)); error_free(error); return NULL; } on_write_error = BLOCKDEV_ON_ERROR_ENOSPC; if ((buf = qemu_opt_get(opts, "werror")) != NULL) { if (type != IF_IDE && type != IF_SCSI && type != IF_VIRTIO && type != IF_NONE) { error_report("werror is not supported by this bus type"); return NULL; } on_write_error = parse_block_error_action(buf, 0); if (on_write_error < 0) { return NULL; } } on_read_error = BLOCKDEV_ON_ERROR_REPORT; if ((buf = qemu_opt_get(opts, "rerror")) != NULL) { if (type != IF_IDE && type != IF_VIRTIO && type != IF_SCSI && type != IF_NONE) { error_report("rerror is not supported by this bus type"); return NULL; } on_read_error = parse_block_error_action(buf, 1); if (on_read_error < 0) { return NULL; } } /* init */ dinfo = g_malloc0(sizeof(*dinfo)); dinfo->id = g_strdup(qemu_opts_id(opts)); dinfo->bdrv = bdrv_new(dinfo->id); dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0; dinfo->bdrv->read_only = ro; dinfo->type = type; dinfo->refcount = 1; if (serial != NULL) { dinfo->serial = g_strdup(serial); } QTAILQ_INSERT_TAIL(&drives, dinfo, next); bdrv_set_on_error(dinfo->bdrv, on_read_error, on_write_error); /* disk I/O throttling */ if (throttle_enabled(&cfg)) { bdrv_io_limits_enable(dinfo->bdrv); bdrv_set_io_limits(dinfo->bdrv, &cfg); } switch(type) { case IF_IDE: case IF_SCSI: case IF_XEN: case IF_NONE: dinfo->media_cd = media == MEDIA_CDROM; break; case IF_SD: case IF_FLOPPY: case IF_PFLASH: case IF_MTD: case IF_VIRTIO: break; default: abort(); } if (!file || !*file) { if (has_driver_specific_opts) { file = NULL; } else { return dinfo; } } if (snapshot) { /* always use cache=unsafe with snapshot */ bdrv_flags &= ~BDRV_O_CACHE_MASK; bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH); } if (copy_on_read) { bdrv_flags |= BDRV_O_COPY_ON_READ; } if (runstate_check(RUN_STATE_INMIGRATE)) { bdrv_flags |= BDRV_O_INCOMING; } if (media == MEDIA_CDROM) { /* CDROM is fine for any interface, don't check. */ ro = 1; } else if (ro == 1) { if (type != IF_SCSI && type != IF_VIRTIO && type != IF_FLOPPY && type != IF_NONE && type != IF_PFLASH) { error_report("read-only not supported by this bus type"); goto err; } } bdrv_flags |= ro ? 0 : BDRV_O_RDWR; if (ro && copy_on_read) { error_report("warning: disabling copy_on_read on read-only drive"); } QINCREF(bs_opts); ret = bdrv_open(dinfo->bdrv, file, bs_opts, bdrv_flags, drv, &error); if (ret < 0) { error_report("could not open disk image %s: %s", file ?: dinfo->id, error_get_pretty(error)); goto err; } if (bdrv_key_required(dinfo->bdrv)) autostart = 0; QDECREF(bs_opts); qemu_opts_del(opts); return dinfo; err: qemu_opts_del(opts); QDECREF(bs_opts); bdrv_unref(dinfo->bdrv); g_free(dinfo->id); QTAILQ_REMOVE(&drives, dinfo, next); g_free(dinfo); return NULL; }


static void ioq_init(LaioQueue *io_q) { QSIMPLEQ_INIT(&io_q->pending); io_q->plugged = 0; io_q->n = 0; io_q->blocked = false; }


static int sys_utimensat(int dirfd, const char *pathname, const struct timespec times[2], int flags) { return (utimensat(dirfd, pathname, times, flags)); }


void hmp_delvm(Monitor *mon, const QDict *qdict) { BlockDriverState *bs; Error *err; const char *name = qdict_get_str(qdict, "name"); if (!find_vmstate_bs()) { monitor_printf(mon, "No block device supports snapshots\n"); return; } if (bdrv_all_delete_snapshot(name, &bs, &err) < 0) { monitor_printf(mon, "Error while deleting snapshot on device '%s': %s\n", bdrv_get_device_name(bs), error_get_pretty(err)); error_free(err); } }


static inline void RENAME(rgb15tobgr24)(const uint8_t *src, uint8_t *dst, long src_size) { const uint16_t *end; #if COMPILE_TEMPLATE_MMX const uint16_t *mm_end; #endif uint8_t *d = dst; const uint16_t *s = (const uint16_t*)src; end = s + src_size/2; #if COMPILE_TEMPLATE_MMX __asm__ volatile(PREFETCH" %0"::"m"(*s):"memory"); mm_end = end - 7; while (s < mm_end) { __asm__ volatile( PREFETCH" 32%1 \n\t" "movq %1, %%mm0 \n\t" "movq %1, %%mm1 \n\t" "movq %1, %%mm2 \n\t" "pand %2, %%mm0 \n\t" "pand %3, %%mm1 \n\t" "pand %4, %%mm2 \n\t" "psllq $3, %%mm0 \n\t" "psrlq $2, %%mm1 \n\t" "psrlq $7, %%mm2 \n\t" "movq %%mm0, %%mm3 \n\t" "movq %%mm1, %%mm4 \n\t" "movq %%mm2, %%mm5 \n\t" "punpcklwd %5, %%mm0 \n\t" "punpcklwd %5, %%mm1 \n\t" "punpcklwd %5, %%mm2 \n\t" "punpckhwd %5, %%mm3 \n\t" "punpckhwd %5, %%mm4 \n\t" "punpckhwd %5, %%mm5 \n\t" "psllq $8, %%mm1 \n\t" "psllq $16, %%mm2 \n\t" "por %%mm1, %%mm0 \n\t" "por %%mm2, %%mm0 \n\t" "psllq $8, %%mm4 \n\t" "psllq $16, %%mm5 \n\t" "por %%mm4, %%mm3 \n\t" "por %%mm5, %%mm3 \n\t" "movq %%mm0, %%mm6 \n\t" "movq %%mm3, %%mm7 \n\t" "movq 8%1, %%mm0 \n\t" "movq 8%1, %%mm1 \n\t" "movq 8%1, %%mm2 \n\t" "pand %2, %%mm0 \n\t" "pand %3, %%mm1 \n\t" "pand %4, %%mm2 \n\t" "psllq $3, %%mm0 \n\t" "psrlq $2, %%mm1 \n\t" "psrlq $7, %%mm2 \n\t" "movq %%mm0, %%mm3 \n\t" "movq %%mm1, %%mm4 \n\t" "movq %%mm2, %%mm5 \n\t" "punpcklwd %5, %%mm0 \n\t" "punpcklwd %5, %%mm1 \n\t" "punpcklwd %5, %%mm2 \n\t" "punpckhwd %5, %%mm3 \n\t" "punpckhwd %5, %%mm4 \n\t" "punpckhwd %5, %%mm5 \n\t" "psllq $8, %%mm1 \n\t" "psllq $16, %%mm2 \n\t" "por %%mm1, %%mm0 \n\t" "por %%mm2, %%mm0 \n\t" "psllq $8, %%mm4 \n\t" "psllq $16, %%mm5 \n\t" "por %%mm4, %%mm3 \n\t" "por %%mm5, %%mm3 \n\t" :"=m"(*d) :"m"(*s),"m"(mask15b),"m"(mask15g),"m"(mask15r), "m"(mmx_null) :"memory"); /* borrowed 32 to 24 */ __asm__ volatile( "movq %%mm0, %%mm4 \n\t" "movq %%mm3, %%mm5 \n\t" "movq %%mm6, %%mm0 \n\t" "movq %%mm7, %%mm1 \n\t" "movq %%mm4, %%mm6 \n\t" "movq %%mm5, %%mm7 \n\t" "movq %%mm0, %%mm2 \n\t" "movq %%mm1, %%mm3 \n\t" STORE_BGR24_MMX :"=m"(*d) :"m"(*s) :"memory"); d += 24; s += 8; } __asm__ volatile(SFENCE:::"memory"); __asm__ volatile(EMMS:::"memory"); #endif while (s < end) { register uint16_t bgr; bgr = *s++; *d++ = (bgr&0x1F)<<3; *d++ = (bgr&0x3E0)>>2; *d++ = (bgr&0x7C00)>>7; } }


static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret, tcg_target_long sval) { static const S390Opcode lli_insns[4] = { RI_LLILL, RI_LLILH, RI_LLIHL, RI_LLIHH }; tcg_target_ulong uval = sval; int i; if (type == TCG_TYPE_I32) { uval = (uint32_t)sval; sval = (int32_t)sval; } /* Try all 32-bit insns that can load it in one go. */ if (sval >= -0x8000 && sval < 0x8000) { tcg_out_insn(s, RI, LGHI, ret, sval); return; } for (i = 0; i < 4; i++) { tcg_target_long mask = 0xffffull << i*16; if ((uval & mask) == uval) { tcg_out_insn_RI(s, lli_insns[i], ret, uval >> i*16); return; } } /* Try all 48-bit insns that can load it in one go. */ if (facilities & FACILITY_EXT_IMM) { if (sval == (int32_t)sval) { tcg_out_insn(s, RIL, LGFI, ret, sval); return; } if (uval <= 0xffffffff) { tcg_out_insn(s, RIL, LLILF, ret, uval); return; } if ((uval & 0xffffffff) == 0) { tcg_out_insn(s, RIL, LLIHF, ret, uval >> 31 >> 1); return; } } /* Try for PC-relative address load. */ if ((sval & 1) == 0) { ptrdiff_t off = tcg_pcrel_diff(s, (void *)sval) >> 1; if (off == (int32_t)off) { tcg_out_insn(s, RIL, LARL, ret, off); return; } } /* If extended immediates are not present, then we may have to issue several instructions to load the low 32 bits. */ if (!(facilities & FACILITY_EXT_IMM)) { /* A 32-bit unsigned value can be loaded in 2 insns. And given that the lli_insns loop above did not succeed, we know that both insns are required. */ if (uval <= 0xffffffff) { tcg_out_insn(s, RI, LLILL, ret, uval); tcg_out_insn(s, RI, IILH, ret, uval >> 16); return; } /* If all high bits are set, the value can be loaded in 2 or 3 insns. We first want to make sure that all the high bits get set. With luck the low 16-bits can be considered negative to perform that for free, otherwise we load an explicit -1. */ if (sval >> 31 >> 1 == -1) { if (uval & 0x8000) { tcg_out_insn(s, RI, LGHI, ret, uval); } else { tcg_out_insn(s, RI, LGHI, ret, -1); tcg_out_insn(s, RI, IILL, ret, uval); } tcg_out_insn(s, RI, IILH, ret, uval >> 16); return; } } /* If we get here, both the high and low parts have non-zero bits. */ /* Recurse to load the lower 32-bits. */ tcg_out_movi(s, TCG_TYPE_I64, ret, uval & 0xffffffff); /* Insert data into the high 32-bits. */ uval = uval >> 31 >> 1; if (facilities & FACILITY_EXT_IMM) { if (uval < 0x10000) { tcg_out_insn(s, RI, IIHL, ret, uval); } else if ((uval & 0xffff) == 0) { tcg_out_insn(s, RI, IIHH, ret, uval >> 16); } else { tcg_out_insn(s, RIL, IIHF, ret, uval); } } else { if (uval & 0xffff) { tcg_out_insn(s, RI, IIHL, ret, uval); } if (uval & 0xffff0000) { tcg_out_insn(s, RI, IIHH, ret, uval >> 16); } } }


milkymist_init(MachineState *machine) { const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; LM32CPU *cpu; CPULM32State *env; int kernel_size; DriveInfo *dinfo; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *phys_sdram = g_new(MemoryRegion, 1); qemu_irq irq[32]; int i; char *bios_filename; ResetInfo *reset_info; /* memory map */ hwaddr flash_base = 0x00000000; size_t flash_sector_size = 128 * 1024; size_t flash_size = 32 * 1024 * 1024; hwaddr sdram_base = 0x40000000; size_t sdram_size = 128 * 1024 * 1024; hwaddr initrd_base = sdram_base + 0x1002000; hwaddr cmdline_base = sdram_base + 0x1000000; size_t initrd_max = sdram_size - 0x1002000; reset_info = g_malloc0(sizeof(ResetInfo)); if (cpu_model == NULL) { cpu_model = "lm32-full"; } cpu = cpu_lm32_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "qemu: unable to find CPU '%s'\n", cpu_model); exit(1); } env = &cpu->env; reset_info->cpu = cpu; cpu_lm32_set_phys_msb_ignore(env, 1); memory_region_allocate_system_memory(phys_sdram, NULL, "milkymist.sdram", sdram_size); memory_region_add_subregion(address_space_mem, sdram_base, phys_sdram); dinfo = drive_get(IF_PFLASH, 0, 0); /* Numonyx JS28F256J3F105 */ pflash_cfi01_register(flash_base, NULL, "milkymist.flash", flash_size, dinfo ? blk_by_legacy_dinfo(dinfo) : NULL, flash_sector_size, flash_size / flash_sector_size, 2, 0x00, 0x89, 0x00, 0x1d, 1); /* create irq lines */ env->pic_state = lm32_pic_init(qemu_allocate_irq(cpu_irq_handler, cpu, 0)); for (i = 0; i < 32; i++) { irq[i] = qdev_get_gpio_in(env->pic_state, i); } /* load bios rom */ if (bios_name == NULL) { bios_name = BIOS_FILENAME; } bios_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (bios_filename) { load_image_targphys(bios_filename, BIOS_OFFSET, BIOS_SIZE); } reset_info->bootstrap_pc = BIOS_OFFSET; /* if no kernel is given no valid bios rom is a fatal error */ if (!kernel_filename && !dinfo && !bios_filename && !qtest_enabled()) { fprintf(stderr, "qemu: could not load Milkymist One bios '%s'\n", bios_name); exit(1); } g_free(bios_filename); milkymist_uart_create(0x60000000, irq[0]); milkymist_sysctl_create(0x60001000, irq[1], irq[2], irq[3], 80000000, 0x10014d31, 0x0000041f, 0x00000001); milkymist_hpdmc_create(0x60002000); milkymist_vgafb_create(0x60003000, 0x40000000, 0x0fffffff); milkymist_memcard_create(0x60004000); milkymist_ac97_create(0x60005000, irq[4], irq[5], irq[6], irq[7]); milkymist_pfpu_create(0x60006000, irq[8]); milkymist_tmu2_create(0x60007000, irq[9]); milkymist_minimac2_create(0x60008000, 0x30000000, irq[10], irq[11]); milkymist_softusb_create(0x6000f000, irq[15], 0x20000000, 0x1000, 0x20020000, 0x2000); /* make sure juart isn't the first chardev */ env->juart_state = lm32_juart_init(); if (kernel_filename) { uint64_t entry; /* Boots a kernel elf binary. */ kernel_size = load_elf(kernel_filename, NULL, NULL, &entry, NULL, NULL, 1, EM_LATTICEMICO32, 0, 0); reset_info->bootstrap_pc = entry; if (kernel_size < 0) { kernel_size = load_image_targphys(kernel_filename, sdram_base, sdram_size); reset_info->bootstrap_pc = sdram_base; } if (kernel_size < 0) { fprintf(stderr, "qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } } if (kernel_cmdline && strlen(kernel_cmdline)) { pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); reset_info->cmdline_base = (uint32_t)cmdline_base; } if (initrd_filename) { size_t initrd_size; initrd_size = load_image_targphys(initrd_filename, initrd_base, initrd_max); reset_info->initrd_base = (uint32_t)initrd_base; reset_info->initrd_size = (uint32_t)initrd_size; } qemu_register_reset(main_cpu_reset, reset_info); }


static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset, int64_t offset_in_cluster, QEMUIOVector *qiov, uint64_t qiov_offset, uint64_t n_bytes, uint64_t offset) { int ret; VmdkGrainMarker *data = NULL; uLongf buf_len; QEMUIOVector local_qiov; struct iovec iov; int64_t write_offset; int64_t write_end_sector; if (extent->compressed) { void *compressed_data; if (!extent->has_marker) { ret = -EINVAL; goto out; } buf_len = (extent->cluster_sectors << 9) * 2; data = g_malloc(buf_len + sizeof(VmdkGrainMarker)); compressed_data = g_malloc(n_bytes); qemu_iovec_to_buf(qiov, qiov_offset, compressed_data, n_bytes); ret = compress(data->data, &buf_len, compressed_data, n_bytes); g_free(compressed_data); if (ret != Z_OK || buf_len == 0) { ret = -EINVAL; goto out; } data->lba = offset >> BDRV_SECTOR_BITS; data->size = buf_len; n_bytes = buf_len + sizeof(VmdkGrainMarker); iov = (struct iovec) { .iov_base = data, .iov_len = n_bytes, }; qemu_iovec_init_external(&local_qiov, &iov, 1); } else { qemu_iovec_init(&local_qiov, qiov->niov); qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes); } write_offset = cluster_offset + offset_in_cluster, ret = bdrv_co_pwritev(extent->file->bs, write_offset, n_bytes, &local_qiov, 0); write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE); if (extent->compressed) { extent->next_cluster_sector = write_end_sector; } else { extent->next_cluster_sector = MAX(extent->next_cluster_sector, write_end_sector); } if (ret < 0) { goto out; } ret = 0; out: g_free(data); if (!extent->compressed) { qemu_iovec_destroy(&local_qiov); } return ret; }


static int vnc_continue_handshake(struct VncState *vs) { int ret; if ((ret = gnutls_handshake(vs->tls_session)) < 0) { if (!gnutls_error_is_fatal(ret)) { VNC_DEBUG("Handshake interrupted (blocking)\n"); if (!gnutls_record_get_direction(vs->tls_session)) qemu_set_fd_handler(vs->csock, vnc_handshake_io, NULL, vs); else qemu_set_fd_handler(vs->csock, NULL, vnc_handshake_io, vs); return 0; } VNC_DEBUG("Handshake failed %s\n", gnutls_strerror(ret)); vnc_client_error(vs); return -1; } if (vs->vd->x509verify) { if (vnc_validate_certificate(vs) < 0) { VNC_DEBUG("Client verification failed\n"); vnc_client_error(vs); return -1; } else { VNC_DEBUG("Client verification passed\n"); } } VNC_DEBUG("Handshake done, switching to TLS data mode\n"); vs->wiremode = VNC_WIREMODE_TLS; qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs); return start_auth_vencrypt_subauth(vs); }


void cpu_reset (CPUMIPSState *env) { memset(env, 0, offsetof(CPUMIPSState, breakpoints)); tlb_flush(env, 1); /* Minimal init */ #if defined(CONFIG_USER_ONLY) env->hflags = MIPS_HFLAG_UM; #else if (env->hflags & MIPS_HFLAG_BMASK) { /* If the exception was raised from a delay slot, come back to the jump. */ env->CP0_ErrorEPC = env->active_tc.PC - 4; } else { env->CP0_ErrorEPC = env->active_tc.PC; env->active_tc.PC = (int32_t)0xBFC00000; env->CP0_Wired = 0; /* SMP not implemented */ env->CP0_EBase = 0x80000000; env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL); /* vectored interrupts not implemented, timer on int 7, no performance counters. */ env->CP0_IntCtl = 0xe0000000; { int i; for (i = 0; i < 7; i++) { env->CP0_WatchLo[i] = 0; env->CP0_WatchHi[i] = 0x80000000; env->CP0_WatchLo[7] = 0; env->CP0_WatchHi[7] = 0; /* Count register increments in debug mode, EJTAG version 1 */ env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER); env->hflags = MIPS_HFLAG_CP0; #endif env->exception_index = EXCP_NONE; cpu_mips_register(env, env->cpu_model);


static int vmdk_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { char *buf; int ret; BDRVVmdkState *s = bs->opaque; uint32_t magic; Error *local_err = NULL; bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false, errp); if (!bs->file) { return -EINVAL; } buf = vmdk_read_desc(bs->file, 0, errp); if (!buf) { return -EINVAL; } magic = ldl_be_p(buf); switch (magic) { case VMDK3_MAGIC: case VMDK4_MAGIC: ret = vmdk_open_sparse(bs, bs->file, flags, buf, options, errp); s->desc_offset = 0x200; break; default: ret = vmdk_open_desc_file(bs, flags, buf, options, errp); break; } if (ret) { goto fail; } /* try to open parent images, if exist */ ret = vmdk_parent_open(bs); if (ret) { goto fail; } s->cid = vmdk_read_cid(bs, 0); s->parent_cid = vmdk_read_cid(bs, 1); qemu_co_mutex_init(&s->lock); /* Disable migration when VMDK images are used */ error_setg(&s->migration_blocker, "The vmdk format used by node '%s' " "does not support live migration", bdrv_get_device_or_node_name(bs)); ret = migrate_add_blocker(s->migration_blocker, &local_err); if (local_err) { error_propagate(errp, local_err); error_free(s->migration_blocker); goto fail; } g_free(buf); return 0; fail: g_free(buf); g_free(s->create_type); s->create_type = NULL; vmdk_free_extents(bs); return ret; }


static inline void gen_neon_widen(TCGv_i64 dest, TCGv src, int size, int u) { if (u) { switch (size) { case 0: gen_helper_neon_widen_u8(dest, src); break; case 1: gen_helper_neon_widen_u16(dest, src); break; case 2: tcg_gen_extu_i32_i64(dest, src); break; default: abort(); } } else { switch (size) { case 0: gen_helper_neon_widen_s8(dest, src); break; case 1: gen_helper_neon_widen_s16(dest, src); break; case 2: tcg_gen_ext_i32_i64(dest, src); break; default: abort(); } } dead_tmp(src); }


static int rv10_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MpegEncContext *s = avctx->priv_data; int i; AVFrame *pict = data; int slice_count; const uint8_t *slices_hdr = NULL; av_dlog(avctx, "*****frame %d size=%d\n", avctx->frame_number, buf_size); /* no supplementary picture */ if (buf_size == 0) { return 0; } if(!avctx->slice_count){ slice_count = (*buf++) + 1; slices_hdr = buf + 4; buf += 8 * slice_count; }else slice_count = avctx->slice_count; for(i=0; i<slice_count; i++){ int offset= get_slice_offset(avctx, slices_hdr, i); int size, size2; if(i+1 == slice_count) size= buf_size - offset; else size= get_slice_offset(avctx, slices_hdr, i+1) - offset; if(i+2 >= slice_count) size2= buf_size - offset; else size2= get_slice_offset(avctx, slices_hdr, i+2) - offset; if(rv10_decode_packet(avctx, buf+offset, size, size2) > 8*size) i++; } if(s->current_picture_ptr != NULL && s->mb_y>=s->mb_height){ ff_er_frame_end(s); MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { *pict= *(AVFrame*)s->current_picture_ptr; } else if (s->last_picture_ptr != NULL) { *pict= *(AVFrame*)s->last_picture_ptr; } if(s->last_picture_ptr || s->low_delay){ *data_size = sizeof(AVFrame); ff_print_debug_info(s, pict); } s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } return buf_size; }


static void output_client_manifest(struct VideoFiles *files, const char *basename, int split) { char filename[1000]; FILE *out; int i, j; if (split) snprintf(filename, sizeof(filename), "Manifest"); else snprintf(filename, sizeof(filename), "%s.ismc", basename); out = fopen(filename, "w"); if (!out) { perror(filename); return; } fprintf(out, "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"); fprintf(out, "<SmoothStreamingMedia MajorVersion=\"2\" MinorVersion=\"0\" " "Duration=\"%"PRId64 "\">\n", files->duration * 10); if (files->video_file >= 0) { struct VideoFile *vf = files->files[files->video_file]; int index = 0; fprintf(out, "\t<StreamIndex Type=\"video\" QualityLevels=\"%d\" " "Chunks=\"%d\" " "Url=\"QualityLevels({bitrate})/Fragments(video={start time})\">\n", files->nb_video_files, vf->chunks); for (i = 0; i < files->nb_files; i++) { vf = files->files[i]; if (!vf->is_video) continue; fprintf(out, "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" " "FourCC=\"%s\" MaxWidth=\"%d\" MaxHeight=\"%d\" " "CodecPrivateData=\"", index, vf->bitrate, vf->fourcc, vf->width, vf->height); for (j = 0; j < vf->codec_private_size; j++) fprintf(out, "%02X", vf->codec_private[j]); fprintf(out, "\" />\n"); index++; } vf = files->files[files->video_file]; for (i = 0; i < vf->chunks; i++) fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n", i, vf->offsets[i].duration); fprintf(out, "\t</StreamIndex>\n"); } if (files->audio_file >= 0) { struct VideoFile *vf = files->files[files->audio_file]; int index = 0; fprintf(out, "\t<StreamIndex Type=\"audio\" QualityLevels=\"%d\" " "Chunks=\"%d\" " "Url=\"QualityLevels({bitrate})/Fragments(audio={start time})\">\n", files->nb_audio_files, vf->chunks); for (i = 0; i < files->nb_files; i++) { vf = files->files[i]; if (!vf->is_audio) continue; fprintf(out, "\t\t<QualityLevel Index=\"%d\" Bitrate=\"%d\" " "FourCC=\"%s\" SamplingRate=\"%d\" Channels=\"%d\" " "BitsPerSample=\"16\" PacketSize=\"%d\" " "AudioTag=\"%d\" CodecPrivateData=\"", index, vf->bitrate, vf->fourcc, vf->sample_rate, vf->channels, vf->blocksize, vf->tag); for (j = 0; j < vf->codec_private_size; j++) fprintf(out, "%02X", vf->codec_private[j]); fprintf(out, "\" />\n"); index++; } vf = files->files[files->audio_file]; for (i = 0; i < vf->chunks; i++) fprintf(out, "\t\t<c n=\"%d\" d=\"%d\" />\n", i, vf->offsets[i].duration); fprintf(out, "\t</StreamIndex>\n"); } fprintf(out, "</SmoothStreamingMedia>\n"); fclose(out); }


int qdev_unplug(DeviceState *dev) { if (!dev->parent_bus->allow_hotplug) { qemu_error("Bus %s does not support hotplugging\n", dev->parent_bus->name); return -1; } return dev->info->unplug(dev); }


static int aa_read_header(AVFormatContext *s) { int i, j, idx, largest_idx = -1; uint32_t nkey, nval, toc_size, npairs, header_seed, start; char key[128], val[128], codec_name[64] = {0}; uint8_t output[24], dst[8], src[8]; int64_t largest_size = -1, current_size = -1; struct toc_entry { uint32_t offset; uint32_t size; } TOC[MAX_TOC_ENTRIES]; uint32_t header_key_part[4]; uint8_t header_key[16]; AADemuxContext *c = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; /* parse .aa header */ avio_skip(pb, 4); // file size avio_skip(pb, 4); // magic string toc_size = avio_rb32(pb); // TOC size avio_skip(pb, 4); // unidentified integer if (toc_size > MAX_TOC_ENTRIES) return AVERROR_INVALIDDATA; for (i = 0; i < toc_size; i++) { // read TOC avio_skip(pb, 4); // TOC entry index TOC[i].offset = avio_rb32(pb); // block offset TOC[i].size = avio_rb32(pb); // block size } avio_skip(pb, 24); // header termination block (ignored) npairs = avio_rb32(pb); // read dictionary entries if (npairs > MAX_DICTIONARY_ENTRIES) return AVERROR_INVALIDDATA; for (i = 0; i < npairs; i++) { memset(val, 0, sizeof(val)); memset(key, 0, sizeof(key)); avio_skip(pb, 1); // unidentified integer nkey = avio_rb32(pb); // key string length nval = avio_rb32(pb); // value string length if (nkey > sizeof(key)) { avio_skip(pb, nkey); } else { avio_read(pb, key, nkey); // key string } if (nval > sizeof(val)) { avio_skip(pb, nval); } else { avio_read(pb, val, nval); // value string } if (!strcmp(key, "codec")) { av_log(s, AV_LOG_DEBUG, "Codec is <%s>\n", val); strncpy(codec_name, val, sizeof(codec_name) - 1); } if (!strcmp(key, "HeaderSeed")) { av_log(s, AV_LOG_DEBUG, "HeaderSeed is <%s>\n", val); header_seed = atoi(val); } if (!strcmp(key, "HeaderKey")) { // this looks like "1234567890 1234567890 1234567890 1234567890" av_log(s, AV_LOG_DEBUG, "HeaderKey is <%s>\n", val); sscanf(val, "%u%u%u%u", &header_key_part[0], &header_key_part[1], &header_key_part[2], &header_key_part[3]); for (idx = 0; idx < 4; idx++) { AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE! } av_log(s, AV_LOG_DEBUG, "Processed HeaderKey is "); for (i = 0; i < 16; i++) av_log(s, AV_LOG_DEBUG, "%02x", header_key[i]); av_log(s, AV_LOG_DEBUG, "\n"); } } /* verify fixed key */ if (c->aa_fixed_key_len != 16) { av_log(s, AV_LOG_ERROR, "aa_fixed_key value needs to be 16 bytes!\n"); return AVERROR(EINVAL); } /* verify codec */ if ((c->codec_second_size = get_second_size(codec_name)) == -1) { av_log(s, AV_LOG_ERROR, "unknown codec <%s>!\n", codec_name); return AVERROR(EINVAL); } /* decryption key derivation */ c->tea_ctx = av_tea_alloc(); if (!c->tea_ctx) return AVERROR(ENOMEM); av_tea_init(c->tea_ctx, c->aa_fixed_key, 16); output[0] = output[1] = 0; // purely for padding purposes memcpy(output + 2, header_key, 16); idx = 0; for (i = 0; i < 3; i++) { // TEA CBC with weird mixed endianness AV_WB32(src, header_seed); AV_WB32(src + 4, header_seed + 1); header_seed += 2; av_tea_crypt(c->tea_ctx, dst, src, 1, NULL, 0); // TEA ECB encrypt for (j = 0; j < TEA_BLOCK_SIZE && idx < 18; j+=1, idx+=1) { output[idx] = output[idx] ^ dst[j]; } } memcpy(c->file_key, output + 2, 16); // skip first 2 bytes of output av_log(s, AV_LOG_DEBUG, "File key is "); for (i = 0; i < 16; i++) av_log(s, AV_LOG_DEBUG, "%02x", c->file_key[i]); av_log(s, AV_LOG_DEBUG, "\n"); /* decoder setup */ st = avformat_new_stream(s, NULL); if (!st) { av_freep(&c->tea_ctx); return AVERROR(ENOMEM); } st->codec->codec_type = AVMEDIA_TYPE_AUDIO; if (!strcmp(codec_name, "mp332")) { st->codec->codec_id = AV_CODEC_ID_MP3; st->codec->sample_rate = 22050; st->need_parsing = AVSTREAM_PARSE_FULL_RAW; st->start_time = 0; } else if (!strcmp(codec_name, "acelp85")) { st->codec->codec_id = AV_CODEC_ID_SIPR; st->codec->block_align = 19; st->codec->channels = 1; st->codec->sample_rate = 8500; } else if (!strcmp(codec_name, "acelp16")) { st->codec->codec_id = AV_CODEC_ID_SIPR; st->codec->block_align = 20; st->codec->channels = 1; st->codec->sample_rate = 16000; } /* determine, and jump to audio start offset */ for (i = 1; i < toc_size; i++) { // skip the first entry! current_size = TOC[i].size; if (current_size > largest_size) { largest_idx = i; largest_size = current_size; } } start = TOC[largest_idx].offset; avio_seek(pb, start, SEEK_SET); c->current_chapter_size = 0; return 0; }


vorbis_comment(AVFormatContext * as, uint8_t *buf, int size) { const uint8_t *p = buf; const uint8_t *end = buf + size; unsigned s, n, j; if (size < 8) /* must have vendor_length and user_comment_list_length */ return -1; s = bytestream_get_le32(&p); if (end - p < s) return -1; p += s; n = bytestream_get_le32(&p); while (p < end && n > 0) { const char *t, *v; int tl, vl; s = bytestream_get_le32(&p); if (end - p < s) break; t = p; p += s; n--; v = memchr(t, '=', s); if (!v) continue; tl = v - t; vl = s - tl - 1; v++; if (tl && vl) { char *tt, *ct; tt = av_malloc(tl + 1); ct = av_malloc(vl + 1); if (!tt || !ct) { av_freep(&tt); av_freep(&ct); av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n"); continue; } for (j = 0; j < tl; j++) tt[j] = toupper(t[j]); tt[tl] = 0; memcpy(ct, v, vl); ct[vl] = 0; av_metadata_set(&as->metadata, tt, ct); av_freep(&tt); av_freep(&ct); } } if (p != end) av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p); if (n > 0) av_log(as, AV_LOG_INFO, "truncated comment header, %i comments not found\n", n); return 0; }


static float get_band_cost_ESC_mips(struct AACEncContext *s, PutBitContext *pb, const float *in, const float *scaled, int size, int scale_idx, int cb, const float lambda, const float uplim, int *bits) { const float Q34 = ff_aac_pow34sf_tab[POW_SF2_ZERO - scale_idx + SCALE_ONE_POS - SCALE_DIV_512]; const float IQ = ff_aac_pow2sf_tab [POW_SF2_ZERO + scale_idx - SCALE_ONE_POS + SCALE_DIV_512]; const float CLIPPED_ESCAPE = 165140.0f * IQ; int i; float cost = 0; int qc1, qc2, qc3, qc4; int curbits = 0; uint8_t *p_bits = (uint8_t*)ff_aac_spectral_bits[cb-1]; float *p_codes = (float* )ff_aac_codebook_vectors[cb-1]; for (i = 0; i < size; i += 4) { const float *vec, *vec2; int curidx, curidx2; float t1, t2, t3, t4; float di1, di2, di3, di4; int cond0, cond1, cond2, cond3; int c1, c2, c3, c4; int t6, t7; qc1 = scaled[i ] * Q34 + ROUND_STANDARD; qc2 = scaled[i+1] * Q34 + ROUND_STANDARD; qc3 = scaled[i+2] * Q34 + ROUND_STANDARD; qc4 = scaled[i+3] * Q34 + ROUND_STANDARD; __asm__ volatile ( ".set push \n\t" ".set noreorder \n\t" "ori %[t6], $zero, 15 \n\t" "ori %[t7], $zero, 16 \n\t" "shll_s.w %[c1], %[qc1], 18 \n\t" "shll_s.w %[c2], %[qc2], 18 \n\t" "shll_s.w %[c3], %[qc3], 18 \n\t" "shll_s.w %[c4], %[qc4], 18 \n\t" "srl %[c1], %[c1], 18 \n\t" "srl %[c2], %[c2], 18 \n\t" "srl %[c3], %[c3], 18 \n\t" "srl %[c4], %[c4], 18 \n\t" "slt %[cond0], %[t6], %[qc1] \n\t" "slt %[cond1], %[t6], %[qc2] \n\t" "slt %[cond2], %[t6], %[qc3] \n\t" "slt %[cond3], %[t6], %[qc4] \n\t" "movn %[qc1], %[t7], %[cond0] \n\t" "movn %[qc2], %[t7], %[cond1] \n\t" "movn %[qc3], %[t7], %[cond2] \n\t" "movn %[qc4], %[t7], %[cond3] \n\t" ".set pop \n\t" : [qc1]"+r"(qc1), [qc2]"+r"(qc2), [qc3]"+r"(qc3), [qc4]"+r"(qc4), [cond0]"=&r"(cond0), [cond1]"=&r"(cond1), [cond2]"=&r"(cond2), [cond3]"=&r"(cond3), [c1]"=&r"(c1), [c2]"=&r"(c2), [c3]"=&r"(c3), [c4]"=&r"(c4), [t6]"=&r"(t6), [t7]"=&r"(t7) ); curidx = 17 * qc1; curidx += qc2; curidx2 = 17 * qc3; curidx2 += qc4; curbits += p_bits[curidx]; curbits += esc_sign_bits[curidx]; vec = &p_codes[curidx*2]; curbits += p_bits[curidx2]; curbits += esc_sign_bits[curidx2]; vec2 = &p_codes[curidx2*2]; curbits += (av_log2(c1) * 2 - 3) & (-cond0); curbits += (av_log2(c2) * 2 - 3) & (-cond1); curbits += (av_log2(c3) * 2 - 3) & (-cond2); curbits += (av_log2(c4) * 2 - 3) & (-cond3); t1 = fabsf(in[i ]); t2 = fabsf(in[i+1]); t3 = fabsf(in[i+2]); t4 = fabsf(in[i+3]); if (cond0) { if (t1 >= CLIPPED_ESCAPE) { di1 = t1 - CLIPPED_ESCAPE; } else { di1 = t1 - c1 * cbrtf(c1) * IQ; } } else di1 = t1 - vec[0] * IQ; if (cond1) { if (t2 >= CLIPPED_ESCAPE) { di2 = t2 - CLIPPED_ESCAPE; } else { di2 = t2 - c2 * cbrtf(c2) * IQ; } } else di2 = t2 - vec[1] * IQ; if (cond2) { if (t3 >= CLIPPED_ESCAPE) { di3 = t3 - CLIPPED_ESCAPE; } else { di3 = t3 - c3 * cbrtf(c3) * IQ; } } else di3 = t3 - vec2[0] * IQ; if (cond3) { if (t4 >= CLIPPED_ESCAPE) { di4 = t4 - CLIPPED_ESCAPE; } else { di4 = t4 - c4 * cbrtf(c4) * IQ; } } else di4 = t4 - vec2[1]*IQ; cost += di1 * di1 + di2 * di2 + di3 * di3 + di4 * di4; } if (bits) *bits = curbits; return cost * lambda + curbits; }


static PayloadContext *h264_new_context(void) { PayloadContext *data = av_mallocz(sizeof(PayloadContext) + FF_INPUT_BUFFER_PADDING_SIZE); if (data) { data->cookie = MAGIC_COOKIE; } return data; }


int qemu_pipe(int pipefd[2]) { int ret; #ifdef CONFIG_PIPE2 ret = pipe2(pipefd, O_CLOEXEC); #else ret = pipe(pipefd); if (ret == 0) { qemu_set_cloexec(pipefd[0]); qemu_set_cloexec(pipefd[1]); } #endif return ret; }


static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx, const uint8_t *buf, int buf_size) { H264Context *h = s->priv_data; const uint8_t *buf_end = buf + buf_size; unsigned int pps_id; unsigned int slice_type; int state; const uint8_t *ptr; /* set some sane default values */ s->pict_type = FF_I_TYPE; s->key_frame = 0; h->s.avctx= avctx; h->sei_recovery_frame_cnt = -1; h->sei_dpb_output_delay = 0; h->sei_cpb_removal_delay = -1; h->sei_buffering_period_present = 0; for(;;) { int src_length, dst_length, consumed; buf = ff_find_start_code(buf, buf_end, &state); if(buf >= buf_end) break; --buf; src_length = buf_end - buf; switch (state & 0x1f) { case NAL_SLICE: case NAL_IDR_SLICE: // Do not walk the whole buffer just to decode slice header if (src_length > 20) src_length = 20; break; } ptr= ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); if (ptr==NULL || dst_length < 0) break; init_get_bits(&h->s.gb, ptr, 8*dst_length); switch(h->nal_unit_type) { case NAL_SPS: ff_h264_decode_seq_parameter_set(h); break; case NAL_PPS: ff_h264_decode_picture_parameter_set(h, h->s.gb.size_in_bits); break; case NAL_SEI: ff_h264_decode_sei(h); break; case NAL_IDR_SLICE: s->key_frame = 1; /* fall through */ case NAL_SLICE: get_ue_golomb(&h->s.gb); // skip first_mb_in_slice slice_type = get_ue_golomb_31(&h->s.gb); s->pict_type = golomb_to_pict_type[slice_type % 5]; if (h->sei_recovery_frame_cnt >= 0) { /* key frame, since recovery_frame_cnt is set */ s->key_frame = 1; } pps_id= get_ue_golomb(&h->s.gb); if(pps_id>=MAX_PPS_COUNT) { av_log(h->s.avctx, AV_LOG_ERROR, "pps_id out of range\n"); return -1; } if(!h->pps_buffers[pps_id]) { av_log(h->s.avctx, AV_LOG_ERROR, "non-existing PPS referenced\n"); return -1; } h->pps= *h->pps_buffers[pps_id]; if(!h->sps_buffers[h->pps.sps_id]) { av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS referenced\n"); return -1; } h->sps = *h->sps_buffers[h->pps.sps_id]; h->frame_num = get_bits(&h->s.gb, h->sps.log2_max_frame_num); if(h->sps.frame_mbs_only_flag){ h->s.picture_structure= PICT_FRAME; }else{ if(get_bits1(&h->s.gb)) { //field_pic_flag h->s.picture_structure= PICT_TOP_FIELD + get_bits1(&h->s.gb); //bottom_field_flag } else { h->s.picture_structure= PICT_FRAME; } } if(h->sps.pic_struct_present_flag) { switch (h->sei_pic_struct) { case SEI_PIC_STRUCT_TOP_FIELD: case SEI_PIC_STRUCT_BOTTOM_FIELD: s->repeat_pict = 0; break; case SEI_PIC_STRUCT_FRAME: case SEI_PIC_STRUCT_TOP_BOTTOM: case SEI_PIC_STRUCT_BOTTOM_TOP: s->repeat_pict = 1; break; case SEI_PIC_STRUCT_TOP_BOTTOM_TOP: case SEI_PIC_STRUCT_BOTTOM_TOP_BOTTOM: s->repeat_pict = 2; break; case SEI_PIC_STRUCT_FRAME_DOUBLING: s->repeat_pict = 3; break; case SEI_PIC_STRUCT_FRAME_TRIPLING: s->repeat_pict = 5; break; default: s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; break; } } else { s->repeat_pict = h->s.picture_structure == PICT_FRAME ? 1 : 0; } return 0; /* no need to evaluate the rest */ } buf += consumed; } /* didn't find a picture! */ av_log(h->s.avctx, AV_LOG_ERROR, "missing picture in access unit\n"); return -1; }


static inline void write_IRQreg (openpic_t *opp, int n_IRQ, uint32_t reg, uint32_t val) { uint32_t tmp; switch (reg) { case IRQ_IPVP: /* NOTE: not fully accurate for special IRQs, but simple and sufficient */ /* ACTIVITY bit is read-only */ opp->src[n_IRQ].ipvp = (opp->src[n_IRQ].ipvp & 0x40000000) | (val & 0x800F00FF); openpic_update_irq(opp, n_IRQ); DPRINTF("Set IPVP %d to 0x%08x -> 0x%08x\n", n_IRQ, val, opp->src[n_IRQ].ipvp); break; case IRQ_IDE: tmp = val & 0xC0000000; tmp |= val & ((1 << MAX_CPU) - 1); opp->src[n_IRQ].ide = tmp; DPRINTF("Set IDE %d to 0x%08x\n", n_IRQ, opp->src[n_IRQ].ide); break; } }


static void ff_h264_idct_add16_sse2(uint8_t *dst, const int *block_offset, DCTELEM *block, int stride, const uint8_t nnzc[6*8]){ int i; for(i=0; i<16; i+=2) if(nnzc[ scan8[i+0] ]|nnzc[ scan8[i+1] ]) ff_x264_add8x4_idct_sse2 (dst + block_offset[i], block + i*16, stride); }


static void sync_c0_tcstatus(CPUMIPSState *cpu, int tc, target_ulong v) { uint32_t status; uint32_t tcu, tmx, tasid, tksu; uint32_t mask = ((1 << CP0St_CU3) | (1 << CP0St_CU2) | (1 << CP0St_CU1) | (1 << CP0St_CU0) | (1 << CP0St_MX) | (3 << CP0St_KSU)); tcu = (v >> CP0TCSt_TCU0) & 0xf; tmx = (v >> CP0TCSt_TMX) & 0x1; tasid = v & 0xff; tksu = (v >> CP0TCSt_TKSU) & 0x3; status = tcu << CP0St_CU0; status |= tmx << CP0St_MX; status |= tksu << CP0St_KSU; cpu->CP0_Status &= ~mask; cpu->CP0_Status |= status; /* Sync the TASID with EntryHi. */ cpu->CP0_EntryHi &= ~0xff; cpu->CP0_EntryHi = tasid; compute_hflags(cpu); }


static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *gb) { MpegEncContext *s = &ctx->m; int a = 2 << s->sprite_warping_accuracy; int rho = 3 - s->sprite_warping_accuracy; int r = 16 / a; int alpha = 0; int beta = 0; int w = s->width; int h = s->height; int min_ab, i, w2, h2, w3, h3; int sprite_ref[4][2]; int virtual_ref[2][2]; // only true for rectangle shapes const int vop_ref[4][2] = { { 0, 0 }, { s->width, 0 }, { 0, s->height }, { s->width, s->height } }; int d[4][2] = { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } }; if (w <= 0 || h <= 0) return AVERROR_INVALIDDATA; for (i = 0; i < ctx->num_sprite_warping_points; i++) { int length; int x = 0, y = 0; length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); if (length > 0) x = get_xbits(gb, length); if (!(ctx->divx_version == 500 && ctx->divx_build == 413)) check_marker(s->avctx, gb, "before sprite_trajectory"); length = get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); if (length > 0) y = get_xbits(gb, length); check_marker(s->avctx, gb, "after sprite_trajectory"); ctx->sprite_traj[i][0] = d[i][0] = x; ctx->sprite_traj[i][1] = d[i][1] = y; for (; i < 4; i++) ctx->sprite_traj[i][0] = ctx->sprite_traj[i][1] = 0; while ((1 << alpha) < w) alpha++; while ((1 << beta) < h) beta++; /* typo in the MPEG-4 std for the definition of w' and h' */ w2 = 1 << alpha; h2 = 1 << beta; // Note, the 4th point isn't used for GMC if (ctx->divx_version == 500 && ctx->divx_build == 413) { sprite_ref[0][0] = a * vop_ref[0][0] + d[0][0]; sprite_ref[0][1] = a * vop_ref[0][1] + d[0][1]; sprite_ref[1][0] = a * vop_ref[1][0] + d[0][0] + d[1][0]; sprite_ref[1][1] = a * vop_ref[1][1] + d[0][1] + d[1][1]; sprite_ref[2][0] = a * vop_ref[2][0] + d[0][0] + d[2][0]; sprite_ref[2][1] = a * vop_ref[2][1] + d[0][1] + d[2][1]; } else { sprite_ref[0][0] = (a >> 1) * (2 * vop_ref[0][0] + d[0][0]); sprite_ref[0][1] = (a >> 1) * (2 * vop_ref[0][1] + d[0][1]); sprite_ref[1][0] = (a >> 1) * (2 * vop_ref[1][0] + d[0][0] + d[1][0]); sprite_ref[1][1] = (a >> 1) * (2 * vop_ref[1][1] + d[0][1] + d[1][1]); sprite_ref[2][0] = (a >> 1) * (2 * vop_ref[2][0] + d[0][0] + d[2][0]); sprite_ref[2][1] = (a >> 1) * (2 * vop_ref[2][1] + d[0][1] + d[2][1]); /* sprite_ref[3][0] = (a >> 1) * (2 * vop_ref[3][0] + d[0][0] + d[1][0] + d[2][0] + d[3][0]); * sprite_ref[3][1] = (a >> 1) * (2 * vop_ref[3][1] + d[0][1] + d[1][1] + d[2][1] + d[3][1]); */ /* This is mostly identical to the MPEG-4 std (and is totally unreadable * because of that...). Perhaps it should be reordered to be more readable. * The idea behind this virtual_ref mess is to be able to use shifts later * per pixel instead of divides so the distance between points is converted * from w&h based to w2&h2 based which are of the 2^x form. */ virtual_ref[0][0] = 16 * (vop_ref[0][0] + w2) + ROUNDED_DIV(((w - w2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) + w2 * (r * sprite_ref[1][0] - 16 * vop_ref[1][0])), w); virtual_ref[0][1] = 16 * vop_ref[0][1] + ROUNDED_DIV(((w - w2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) + w2 * (r * sprite_ref[1][1] - 16 * vop_ref[1][1])), w); virtual_ref[1][0] = 16 * vop_ref[0][0] + ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][0] - 16 * vop_ref[0][0]) + h2 * (r * sprite_ref[2][0] - 16 * vop_ref[2][0])), h); virtual_ref[1][1] = 16 * (vop_ref[0][1] + h2) + ROUNDED_DIV(((h - h2) * (r * sprite_ref[0][1] - 16 * vop_ref[0][1]) + h2 * (r * sprite_ref[2][1] - 16 * vop_ref[2][1])), h); switch (ctx->num_sprite_warping_points) { case 0: s->sprite_offset[0][0] = s->sprite_offset[0][1] = s->sprite_offset[1][0] = s->sprite_offset[1][1] = 0; s->sprite_delta[0][0] = a; s->sprite_delta[0][1] = s->sprite_delta[1][0] = 0; s->sprite_delta[1][1] = a; ctx->sprite_shift[0] = ctx->sprite_shift[1] = 0; break; case 1: // GMC only s->sprite_offset[0][0] = sprite_ref[0][0] - a * vop_ref[0][0]; s->sprite_offset[0][1] = sprite_ref[0][1] - a * vop_ref[0][1]; s->sprite_offset[1][0] = ((sprite_ref[0][0] >> 1) | (sprite_ref[0][0] & 1)) - a * (vop_ref[0][0] / 2); s->sprite_offset[1][1] = ((sprite_ref[0][1] >> 1) | (sprite_ref[0][1] & 1)) - a * (vop_ref[0][1] / 2); s->sprite_delta[0][0] = a; s->sprite_delta[0][1] = s->sprite_delta[1][0] = 0; s->sprite_delta[1][1] = a; ctx->sprite_shift[0] = ctx->sprite_shift[1] = 0; break; case 2: s->sprite_offset[0][0] = (sprite_ref[0][0] << (alpha + rho)) + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * (-vop_ref[0][0]) + (r * sprite_ref[0][1] - virtual_ref[0][1]) * (-vop_ref[0][1]) + (1 << (alpha + rho - 1)); s->sprite_offset[0][1] = (sprite_ref[0][1] << (alpha + rho)) + (-r * sprite_ref[0][1] + virtual_ref[0][1]) * (-vop_ref[0][0]) + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * (-vop_ref[0][1]) + (1 << (alpha + rho - 1)); s->sprite_offset[1][0] = ((-r * sprite_ref[0][0] + virtual_ref[0][0]) * (-2 * vop_ref[0][0] + 1) + (r * sprite_ref[0][1] - virtual_ref[0][1]) * (-2 * vop_ref[0][1] + 1) + 2 * w2 * r * sprite_ref[0][0] - 16 * w2 + (1 << (alpha + rho + 1))); s->sprite_offset[1][1] = ((-r * sprite_ref[0][1] + virtual_ref[0][1]) * (-2 * vop_ref[0][0] + 1) + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * (-2 * vop_ref[0][1] + 1) + 2 * w2 * r * sprite_ref[0][1] - 16 * w2 + (1 << (alpha + rho + 1))); s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); s->sprite_delta[0][1] = (+r * sprite_ref[0][1] - virtual_ref[0][1]); s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]); s->sprite_delta[1][1] = (-r * sprite_ref[0][0] + virtual_ref[0][0]); ctx->sprite_shift[0] = alpha + rho; ctx->sprite_shift[1] = alpha + rho + 2; break; case 3: min_ab = FFMIN(alpha, beta); w3 = w2 >> min_ab; h3 = h2 >> min_ab; s->sprite_offset[0][0] = (sprite_ref[0][0] * (1<<(alpha + beta + rho - min_ab))) + (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3 * (-vop_ref[0][0]) + (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3 * (-vop_ref[0][1]) + (1 << (alpha + beta + rho - min_ab - 1)); s->sprite_offset[0][1] = (sprite_ref[0][1] * (1 << (alpha + beta + rho - min_ab))) + (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3 * (-vop_ref[0][0]) + (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-vop_ref[0][1]) + (1 << (alpha + beta + rho - min_ab - 1)); s->sprite_offset[1][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3 * (-2 * vop_ref[0][0] + 1) + (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 * r * sprite_ref[0][0] - 16 * w2 * h3 + (1 << (alpha + beta + rho - min_ab + 1)); s->sprite_offset[1][1] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3 * (-2 * vop_ref[0][0] + 1) + (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3 * (-2 * vop_ref[0][1] + 1) + 2 * w2 * h3 * r * sprite_ref[0][1] - 16 * w2 * h3 + (1 << (alpha + beta + rho - min_ab + 1)); s->sprite_delta[0][0] = (-r * sprite_ref[0][0] + virtual_ref[0][0]) * h3; s->sprite_delta[0][1] = (-r * sprite_ref[0][0] + virtual_ref[1][0]) * w3; s->sprite_delta[1][0] = (-r * sprite_ref[0][1] + virtual_ref[0][1]) * h3; s->sprite_delta[1][1] = (-r * sprite_ref[0][1] + virtual_ref[1][1]) * w3; ctx->sprite_shift[0] = alpha + beta + rho - min_ab; ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2; break; /* try to simplify the situation */ if (s->sprite_delta[0][0] == a << ctx->sprite_shift[0] && s->sprite_delta[0][1] == 0 && s->sprite_delta[1][0] == 0 && s->sprite_delta[1][1] == a << ctx->sprite_shift[0]) { s->sprite_offset[0][0] >>= ctx->sprite_shift[0]; s->sprite_offset[0][1] >>= ctx->sprite_shift[0]; s->sprite_offset[1][0] >>= ctx->sprite_shift[1]; s->sprite_offset[1][1] >>= ctx->sprite_shift[1]; s->sprite_delta[0][0] = a; s->sprite_delta[0][1] = 0; s->sprite_delta[1][0] = 0; s->sprite_delta[1][1] = a; ctx->sprite_shift[0] = 0; ctx->sprite_shift[1] = 0; s->real_sprite_warping_points = 1; } else { int shift_y = 16 - ctx->sprite_shift[0]; int shift_c = 16 - ctx->sprite_shift[1]; if (shift_c < 0 || shift_y < 0 || FFABS(s->sprite_offset[0][0]) >= INT_MAX >> shift_y || FFABS(s->sprite_offset[1][0]) >= INT_MAX >> shift_c || FFABS(s->sprite_offset[0][1]) >= INT_MAX >> shift_y || FFABS(s->sprite_offset[1][1]) >= INT_MAX >> shift_c ) { avpriv_request_sample(s->avctx, "Too large sprite shift or offset"); for (i = 0; i < 2; i++) { s->sprite_offset[0][i] *= 1 << shift_y; s->sprite_offset[1][i] *= 1 << shift_c; s->sprite_delta[0][i] *= 1 << shift_y; s->sprite_delta[1][i] *= 1 << shift_y; ctx->sprite_shift[i] = 16; s->real_sprite_warping_points = ctx->num_sprite_warping_points; return 0;


static void gen_add16(TCGv t0, TCGv t1) { TCGv tmp = new_tmp(); tcg_gen_xor_i32(tmp, t0, t1); tcg_gen_andi_i32(tmp, tmp, 0x8000); tcg_gen_andi_i32(t0, t0, ~0x8000); tcg_gen_andi_i32(t1, t1, ~0x8000); tcg_gen_add_i32(t0, t0, t1); tcg_gen_xor_i32(t0, t0, tmp); dead_tmp(tmp); dead_tmp(t1); }


static void do_v7m_exception_exit(ARMCPU *cpu) { CPUARMState *env = &cpu->env; CPUState *cs = CPU(cpu); uint32_t excret; uint32_t xpsr; bool ufault = false; bool sfault = false; bool return_to_sp_process; bool return_to_handler; bool rettobase = false; bool exc_secure = false; bool return_to_secure; /* We can only get here from an EXCP_EXCEPTION_EXIT, and * gen_bx_excret() enforces the architectural rule * that jumps to magic addresses don't have magic behaviour unless * we're in Handler mode (compare pseudocode BXWritePC()). */ assert(arm_v7m_is_handler_mode(env)); /* In the spec pseudocode ExceptionReturn() is called directly * from BXWritePC() and gets the full target PC value including * bit zero. In QEMU's implementation we treat it as a normal * jump-to-register (which is then caught later on), and so split * the target value up between env->regs[15] and env->thumb in * gen_bx(). Reconstitute it. */ excret = env->regs[15]; if (env->thumb) { excret |= 1; } qemu_log_mask(CPU_LOG_INT, "Exception return: magic PC %" PRIx32 " previous exception %d\n", excret, env->v7m.exception); if ((excret & R_V7M_EXCRET_RES1_MASK) != R_V7M_EXCRET_RES1_MASK) { qemu_log_mask(LOG_GUEST_ERROR, "M profile: zero high bits in exception " "exit PC value 0x%" PRIx32 " are UNPREDICTABLE\n", excret); } if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { /* EXC_RETURN.ES validation check (R_SMFL). We must do this before * we pick which FAULTMASK to clear. */ if (!env->v7m.secure && ((excret & R_V7M_EXCRET_ES_MASK) || !(excret & R_V7M_EXCRET_DCRS_MASK))) { sfault = 1; /* For all other purposes, treat ES as 0 (R_HXSR) */ excret &= ~R_V7M_EXCRET_ES_MASK; } } if (env->v7m.exception != ARMV7M_EXCP_NMI) { /* Auto-clear FAULTMASK on return from other than NMI. * If the security extension is implemented then this only * happens if the raw execution priority is >= 0; the * value of the ES bit in the exception return value indicates * which security state's faultmask to clear. (v8M ARM ARM R_KBNF.) */ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) { exc_secure = excret & R_V7M_EXCRET_ES_MASK; if (armv7m_nvic_raw_execution_priority(env->nvic) >= 0) { env->v7m.faultmask[exc_secure] = 0; } } else { env->v7m.faultmask[M_REG_NS] = 0; } } switch (armv7m_nvic_complete_irq(env->nvic, env->v7m.exception, exc_secure)) { case -1: /* attempt to exit an exception that isn't active */ ufault = true; break; case 0: /* still an irq active now */ break; case 1: /* we returned to base exception level, no nesting. * (In the pseudocode this is written using "NestedActivation != 1" * where we have 'rettobase == false'.) */ rettobase = true; break; default: g_assert_not_reached(); } return_to_handler = !(excret & R_V7M_EXCRET_MODE_MASK); return_to_sp_process = excret & R_V7M_EXCRET_SPSEL_MASK; return_to_secure = arm_feature(env, ARM_FEATURE_M_SECURITY) && (excret & R_V7M_EXCRET_S_MASK); if (arm_feature(env, ARM_FEATURE_V8)) { if (!arm_feature(env, ARM_FEATURE_M_SECURITY)) { /* UNPREDICTABLE if S == 1 or DCRS == 0 or ES == 1 (R_XLCP); * we choose to take the UsageFault. */ if ((excret & R_V7M_EXCRET_S_MASK) || (excret & R_V7M_EXCRET_ES_MASK) || !(excret & R_V7M_EXCRET_DCRS_MASK)) { ufault = true; } } if (excret & R_V7M_EXCRET_RES0_MASK) { ufault = true; } } else { /* For v7M we only recognize certain combinations of the low bits */ switch (excret & 0xf) { case 1: /* Return to Handler */ break; case 13: /* Return to Thread using Process stack */ case 9: /* Return to Thread using Main stack */ /* We only need to check NONBASETHRDENA for v7M, because in * v8M this bit does not exist (it is RES1). */ if (!rettobase && !(env->v7m.ccr[env->v7m.secure] & R_V7M_CCR_NONBASETHRDENA_MASK)) { ufault = true; } break; default: ufault = true; } } if (sfault) { env->v7m.sfsr |= R_V7M_SFSR_INVER_MASK; armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false); v7m_exception_taken(cpu, excret); qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing " "stackframe: failed EXC_RETURN.ES validity check\n"); return; } if (ufault) { /* Bad exception return: instead of popping the exception * stack, directly take a usage fault on the current stack. */ env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure); v7m_exception_taken(cpu, excret); qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " "stackframe: failed exception return integrity check\n"); return; } /* Set CONTROL.SPSEL from excret.SPSEL. Since we're still in * Handler mode (and will be until we write the new XPSR.Interrupt * field) this does not switch around the current stack pointer. */ write_v7m_control_spsel_for_secstate(env, return_to_sp_process, exc_secure); switch_v7m_security_state(env, return_to_secure); { /* The stack pointer we should be reading the exception frame from * depends on bits in the magic exception return type value (and * for v8M isn't necessarily the stack pointer we will eventually * end up resuming execution with). Get a pointer to the location * in the CPU state struct where the SP we need is currently being * stored; we will use and modify it in place. * We use this limited C variable scope so we don't accidentally * use 'frame_sp_p' after we do something that makes it invalid. */ uint32_t *frame_sp_p = get_v7m_sp_ptr(env, return_to_secure, !return_to_handler, return_to_sp_process); uint32_t frameptr = *frame_sp_p; if (!QEMU_IS_ALIGNED(frameptr, 8) && arm_feature(env, ARM_FEATURE_V8)) { qemu_log_mask(LOG_GUEST_ERROR, "M profile exception return with non-8-aligned SP " "for destination state is UNPREDICTABLE\n"); } /* Do we need to pop callee-saved registers? */ if (return_to_secure && ((excret & R_V7M_EXCRET_ES_MASK) == 0 || (excret & R_V7M_EXCRET_DCRS_MASK) == 0)) { uint32_t expected_sig = 0xfefa125b; uint32_t actual_sig = ldl_phys(cs->as, frameptr); if (expected_sig != actual_sig) { /* Take a SecureFault on the current stack */ env->v7m.sfsr |= R_V7M_SFSR_INVIS_MASK; armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_SECURE, false); v7m_exception_taken(cpu, excret); qemu_log_mask(CPU_LOG_INT, "...taking SecureFault on existing " "stackframe: failed exception return integrity " "signature check\n"); return; } env->regs[4] = ldl_phys(cs->as, frameptr + 0x8); env->regs[5] = ldl_phys(cs->as, frameptr + 0xc); env->regs[6] = ldl_phys(cs->as, frameptr + 0x10); env->regs[7] = ldl_phys(cs->as, frameptr + 0x14); env->regs[8] = ldl_phys(cs->as, frameptr + 0x18); env->regs[9] = ldl_phys(cs->as, frameptr + 0x1c); env->regs[10] = ldl_phys(cs->as, frameptr + 0x20); env->regs[11] = ldl_phys(cs->as, frameptr + 0x24); frameptr += 0x28; } /* Pop registers. TODO: make these accesses use the correct * attributes and address space (S/NS, priv/unpriv) and handle * memory transaction failures. */ env->regs[0] = ldl_phys(cs->as, frameptr); env->regs[1] = ldl_phys(cs->as, frameptr + 0x4); env->regs[2] = ldl_phys(cs->as, frameptr + 0x8); env->regs[3] = ldl_phys(cs->as, frameptr + 0xc); env->regs[12] = ldl_phys(cs->as, frameptr + 0x10); env->regs[14] = ldl_phys(cs->as, frameptr + 0x14); env->regs[15] = ldl_phys(cs->as, frameptr + 0x18); /* Returning from an exception with a PC with bit 0 set is defined * behaviour on v8M (bit 0 is ignored), but for v7M it was specified * to be UNPREDICTABLE. In practice actual v7M hardware seems to ignore * the lsbit, and there are several RTOSes out there which incorrectly * assume the r15 in the stack frame should be a Thumb-style "lsbit * indicates ARM/Thumb" value, so ignore the bit on v7M as well, but * complain about the badly behaved guest. */ if (env->regs[15] & 1) { env->regs[15] &= ~1U; if (!arm_feature(env, ARM_FEATURE_V8)) { qemu_log_mask(LOG_GUEST_ERROR, "M profile return from interrupt with misaligned " "PC is UNPREDICTABLE on v7M\n"); } } xpsr = ldl_phys(cs->as, frameptr + 0x1c); if (arm_feature(env, ARM_FEATURE_V8)) { /* For v8M we have to check whether the xPSR exception field * matches the EXCRET value for return to handler/thread * before we commit to changing the SP and xPSR. */ bool will_be_handler = (xpsr & XPSR_EXCP) != 0; if (return_to_handler != will_be_handler) { /* Take an INVPC UsageFault on the current stack. * By this point we will have switched to the security state * for the background state, so this UsageFault will target * that state. */ armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, env->v7m.secure); env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; v7m_exception_taken(cpu, excret); qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on existing " "stackframe: failed exception return integrity " "check\n"); return; } } /* Commit to consuming the stack frame */ frameptr += 0x20; /* Undo stack alignment (the SPREALIGN bit indicates that the original * pre-exception SP was not 8-aligned and we added a padding word to * align it, so we undo this by ORing in the bit that increases it * from the current 8-aligned value to the 8-unaligned value. (Adding 4 * would work too but a logical OR is how the pseudocode specifies it.) */ if (xpsr & XPSR_SPREALIGN) { frameptr |= 4; } *frame_sp_p = frameptr; } /* This xpsr_write() will invalidate frame_sp_p as it may switch stack */ xpsr_write(env, xpsr, ~XPSR_SPREALIGN); /* The restored xPSR exception field will be zero if we're * resuming in Thread mode. If that doesn't match what the * exception return excret specified then this is a UsageFault. * v7M requires we make this check here; v8M did it earlier. */ if (return_to_handler != arm_v7m_is_handler_mode(env)) { /* Take an INVPC UsageFault by pushing the stack again; * we know we're v7M so this is never a Secure UsageFault. */ assert(!arm_feature(env, ARM_FEATURE_V8)); armv7m_nvic_set_pending(env->nvic, ARMV7M_EXCP_USAGE, false); env->v7m.cfsr[env->v7m.secure] |= R_V7M_CFSR_INVPC_MASK; v7m_push_stack(cpu); v7m_exception_taken(cpu, excret); qemu_log_mask(CPU_LOG_INT, "...taking UsageFault on new stackframe: " "failed exception return integrity check\n"); return; } /* Otherwise, we have a successful exception exit. */ arm_clear_exclusive(env); qemu_log_mask(CPU_LOG_INT, "...successful exception return\n"); }


static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame) { int (*filter_frame)(AVFilterLink *, AVFrame *); AVFilterContext *dstctx = link->dst; AVFilterPad *dst = link->dstpad; AVFrame *out; int ret; AVFilterCommand *cmd= link->dst->command_queue; int64_t pts; if (link->closed) { av_frame_free(&frame); return AVERROR_EOF; } if (!(filter_frame = dst->filter_frame)) filter_frame = default_filter_frame; /* copy the frame if needed */ if (dst->needs_writable && !av_frame_is_writable(frame)) { av_log(link->dst, AV_LOG_DEBUG, "Copying data in avfilter.\n"); /* Maybe use ff_copy_buffer_ref instead? */ switch (link->type) { case AVMEDIA_TYPE_VIDEO: out = ff_get_video_buffer(link, link->w, link->h); break; case AVMEDIA_TYPE_AUDIO: out = ff_get_audio_buffer(link, frame->nb_samples); break; default: ret = AVERROR(EINVAL); goto fail; } if (!out) { ret = AVERROR(ENOMEM); goto fail; } ret = av_frame_copy_props(out, frame); if (ret < 0) goto fail; switch (link->type) { case AVMEDIA_TYPE_VIDEO: av_image_copy(out->data, out->linesize, (const uint8_t **)frame->data, frame->linesize, frame->format, frame->width, frame->height); break; case AVMEDIA_TYPE_AUDIO: av_samples_copy(out->extended_data, frame->extended_data, 0, 0, frame->nb_samples, av_get_channel_layout_nb_channels(frame->channel_layout), frame->format); break; default: ret = AVERROR(EINVAL); goto fail; } av_frame_free(&frame); } else out = frame; while(cmd && cmd->time <= out->pts * av_q2d(link->time_base)){ av_log(link->dst, AV_LOG_DEBUG, "Processing command time:%f command:%s arg:%s\n", cmd->time, cmd->command, cmd->arg); avfilter_process_command(link->dst, cmd->command, cmd->arg, 0, 0, cmd->flags); ff_command_queue_pop(link->dst); cmd= link->dst->command_queue; } pts = out->pts; if (dstctx->enable_str) { int64_t pos = av_frame_get_pkt_pos(out); dstctx->var_values[VAR_N] = link->frame_count; dstctx->var_values[VAR_T] = pts == AV_NOPTS_VALUE ? NAN : pts * av_q2d(link->time_base); dstctx->var_values[VAR_POS] = pos == -1 ? NAN : pos; dstctx->is_disabled = fabs(av_expr_eval(dstctx->enable, dstctx->var_values, NULL)) < 0.5; if (dstctx->is_disabled && (dstctx->filter->flags & AVFILTER_FLAG_SUPPORT_TIMELINE_GENERIC)) filter_frame = default_filter_frame; } ret = filter_frame(link, out); link->frame_count++; link->frame_requested = 0; ff_update_link_current_pts(link, pts); return ret; fail: av_frame_free(&out); av_frame_free(&frame); return ret; }


static inline void FUNC(idctRowCondDC)(int16_t *row, int extra_shift) { int a0, a1, a2, a3, b0, b1, b2, b3; #if HAVE_FAST_64BIT #define ROW0_MASK (0xffffLL << 48 * HAVE_BIGENDIAN) if (((((uint64_t *)row)[0] & ~ROW0_MASK) | ((uint64_t *)row)[1]) == 0) { uint64_t temp; if (DC_SHIFT - extra_shift > 0) { temp = (row[0] << (DC_SHIFT - extra_shift)) & 0xffff; } else { temp = (row[0] >> (extra_shift - DC_SHIFT)) & 0xffff; } temp += temp << 16; temp += temp << 32; ((uint64_t *)row)[0] = temp; ((uint64_t *)row)[1] = temp; return; } #else if (!(((uint32_t*)row)[1] | ((uint32_t*)row)[2] | ((uint32_t*)row)[3] | row[1])) { uint32_t temp; if (DC_SHIFT - extra_shift > 0) { temp = (row[0] << (DC_SHIFT - extra_shift)) & 0xffff; } else { temp = (row[0] >> (extra_shift - DC_SHIFT)) & 0xffff; } temp += temp << 16; ((uint32_t*)row)[0]=((uint32_t*)row)[1] = ((uint32_t*)row)[2]=((uint32_t*)row)[3] = temp; return; } #endif a0 = (W4 * row[0]) + (1 << (ROW_SHIFT - 1)); a1 = a0; a2 = a0; a3 = a0; a0 += W2 * row[2]; a1 += W6 * row[2]; a2 -= W6 * row[2]; a3 -= W2 * row[2]; b0 = MUL(W1, row[1]); MAC(b0, W3, row[3]); b1 = MUL(W3, row[1]); MAC(b1, -W7, row[3]); b2 = MUL(W5, row[1]); MAC(b2, -W1, row[3]); b3 = MUL(W7, row[1]); MAC(b3, -W5, row[3]); if (AV_RN64A(row + 4)) { a0 += W4*row[4] + W6*row[6]; a1 += - W4*row[4] - W2*row[6]; a2 += - W4*row[4] + W2*row[6]; a3 += W4*row[4] - W6*row[6]; MAC(b0, W5, row[5]); MAC(b0, W7, row[7]); MAC(b1, -W1, row[5]); MAC(b1, -W5, row[7]); MAC(b2, W7, row[5]); MAC(b2, W3, row[7]); MAC(b3, W3, row[5]); MAC(b3, -W1, row[7]); } row[0] = (a0 + b0) >> (ROW_SHIFT + extra_shift); row[7] = (a0 - b0) >> (ROW_SHIFT + extra_shift); row[1] = (a1 + b1) >> (ROW_SHIFT + extra_shift); row[6] = (a1 - b1) >> (ROW_SHIFT + extra_shift); row[2] = (a2 + b2) >> (ROW_SHIFT + extra_shift); row[5] = (a2 - b2) >> (ROW_SHIFT + extra_shift); row[3] = (a3 + b3) >> (ROW_SHIFT + extra_shift); row[4] = (a3 - b3) >> (ROW_SHIFT + extra_shift); }


static int io_write_data_type(void *opaque, uint8_t *buf, int size, enum AVIODataMarkerType type, int64_t time) { char timebuf[30], content[5] = { 0 }; const char *str; switch (type) { case AVIO_DATA_MARKER_HEADER: str = "header"; break; case AVIO_DATA_MARKER_SYNC_POINT: str = "sync"; break; case AVIO_DATA_MARKER_BOUNDARY_POINT: str = "boundary"; break; case AVIO_DATA_MARKER_UNKNOWN: str = "unknown"; break; case AVIO_DATA_MARKER_TRAILER: str = "trailer"; break; } if (time == AV_NOPTS_VALUE) snprintf(timebuf, sizeof(timebuf), "nopts"); else snprintf(timebuf, sizeof(timebuf), "%"PRId64, time); // There can be multiple header/trailer callbacks, only log the box type // for header at out_size == 0 if (type != AVIO_DATA_MARKER_UNKNOWN && type != AVIO_DATA_MARKER_TRAILER && (type != AVIO_DATA_MARKER_HEADER || out_size == 0) && size >= 8) memcpy(content, &buf[4], 4); else snprintf(content, sizeof(content), "-"); printf("write_data len %d, time %s, type %s atom %s\n", size, timebuf, str, content); return io_write(opaque, buf, size); }


static void release_buffer(AVCodecContext *avctx, AVFrame *pic) { int i; CVPixelBufferRef cv_buffer = (CVPixelBufferRef)pic->data[3]; CVPixelBufferUnlockBaseAddress(cv_buffer, 0); CVPixelBufferRelease(cv_buffer); for (i = 0; i < 4; i++) pic->data[i] = NULL; }


AVOption *av_set_string(void *obj, const char *name, const char *val){ AVOption *o= find_opt(obj, name); if(!o || !val || o->offset<=0) return NULL; if(o->type != FF_OPT_TYPE_STRING){ double d=0, tmp_d; for(;;){ int i; char buf[256], *tail; for(i=0; i<sizeof(buf)-1 && val[i] && val[i]!='+'; i++) buf[i]= val[i]; buf[i]=0; val+= i; tmp_d= av_parse_num(buf, &tail); if(tail > buf) d+= tmp_d; else{ AVOption *o_named= find_opt(obj, buf); if(o_named && o_named->type == FF_OPT_TYPE_CONST) d+= o_named->default_val; else if(!strcmp(buf, "default")) d+= o->default_val; else if(!strcmp(buf, "max" )) d+= o->max; else if(!strcmp(buf, "min" )) d+= o->min; else return NULL; } if(*val == '+') val++; if(!*val) return av_set_number(obj, name, d, 1, 1); } return NULL; } memcpy(((uint8_t*)obj) + o->offset, val, sizeof(val)); return o; }


static void qed_aio_write_alloc(QEDAIOCB *acb, size_t len) { BDRVQEDState *s = acb_to_s(acb); /* Freeze this request if another allocating write is in progress */ if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) { QSIMPLEQ_INSERT_TAIL(&s->allocating_write_reqs, acb, next); } if (acb != QSIMPLEQ_FIRST(&s->allocating_write_reqs)) { return; /* wait for existing request to finish */ } acb->cur_nclusters = qed_bytes_to_clusters(s, qed_offset_into_cluster(s, acb->cur_pos) + len); acb->cur_cluster = qed_alloc_clusters(s, acb->cur_nclusters); qemu_iovec_copy(&acb->cur_qiov, acb->qiov, acb->qiov_offset, len); if (qed_should_set_need_check(s)) { s->header.features |= QED_F_NEED_CHECK; qed_write_header(s, qed_aio_write_prefill, acb); } else { qed_aio_write_prefill(acb, 0); } }


static int parse_numa(void *opaque, QemuOpts *opts, Error **errp) { NumaOptions *object = NULL; Error *err = NULL; { Visitor *v = opts_visitor_new(opts); visit_type_NumaOptions(v, NULL, &object, &err); visit_free(v); } if (err) { goto error; } switch (object->type) { case NUMA_OPTIONS_KIND_NODE: numa_node_parse(object->u.node.data, opts, &err); if (err) { goto error; } nb_numa_nodes++; break; default: abort(); } return 0; error: error_report_err(err); qapi_free_NumaOptions(object); return -1; }


static uint8_t send_read_command(void) { uint8_t drive = 0; uint8_t head = 0; uint8_t cyl = 0; uint8_t sect_addr = 1; uint8_t sect_size = 2; uint8_t eot = 1; uint8_t gap = 0x1b; uint8_t gpl = 0xff; uint8_t msr = 0; uint8_t st0; uint8_t ret = 0; floppy_send(CMD_READ); floppy_send(head << 2 | drive); g_assert(!get_irq(FLOPPY_IRQ)); floppy_send(cyl); floppy_send(head); floppy_send(sect_addr); floppy_send(sect_size); floppy_send(eot); floppy_send(gap); floppy_send(gpl); uint8_t i = 0; uint8_t n = 2; for (; i < n; i++) { msr = inb(FLOPPY_BASE + reg_msr); if (msr == 0xd0) { break; } sleep(1); } if (i >= n) { return 1; } st0 = floppy_recv(); if (st0 != 0x40) { ret = 1; } floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); floppy_recv(); return ret; }


static void trigger_ascii_console_data(void *opaque, int n, int level) { sclp_service_interrupt(0); }


static uint64_t bonito_readl(void *opaque, hwaddr addr, unsigned size) { PCIBonitoState *s = opaque; uint32_t saddr; saddr = (addr - BONITO_REGBASE) >> 2; DPRINTF("bonito_readl "TARGET_FMT_plx"\n", addr); switch (saddr) { case BONITO_INTISR: return s->regs[saddr]; default: return s->regs[saddr]; } }


static int virtio_net_can_receive(void *opaque) { VirtIONet *n = opaque; return do_virtio_net_can_receive(n, VIRTIO_NET_MAX_BUFSIZE); }


static void bt_hci_inquiry_result(struct bt_hci_s *hci, struct bt_device_s *slave) { if (!slave->inquiry_scan || !hci->lm.responses_left) return; hci->lm.responses_left --; hci->lm.responses ++; switch (hci->lm.inquiry_mode) { case 0x00: bt_hci_inquiry_result_standard(hci, slave); return; case 0x01: bt_hci_inquiry_result_with_rssi(hci, slave); return; default: fprintf(stderr, "%s: bad inquiry mode %02x\n", __FUNCTION__, hci->lm.inquiry_mode); exit(-1); } }


static uint32_t hpet_ram_readw(void *opaque, target_phys_addr_t addr) { printf("qemu: hpet_read w at %" PRIx64 "\n", addr); return 0; }


gen_intermediate_code_internal(MicroBlazeCPU *cpu, TranslationBlock *tb, bool search_pc) { CPUState *cs = CPU(cpu); CPUMBState *env = &cpu->env; uint32_t pc_start; int j, lj; struct DisasContext ctx; struct DisasContext *dc = &ctx; uint32_t next_page_start, org_flags; target_ulong npc; int num_insns; int max_insns; pc_start = tb->pc; dc->cpu = cpu; dc->tb = tb; org_flags = dc->synced_flags = dc->tb_flags = tb->flags; dc->is_jmp = DISAS_NEXT; dc->jmp = 0; dc->delayed_branch = !!(dc->tb_flags & D_FLAG); if (dc->delayed_branch) { dc->jmp = JMP_INDIRECT; } dc->pc = pc_start; dc->singlestep_enabled = cs->singlestep_enabled; dc->cpustate_changed = 0; dc->abort_at_next_insn = 0; dc->nr_nops = 0; if (pc_start & 3) { cpu_abort(cs, "Microblaze: unaligned PC=%x\n", pc_start); } if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { #if !SIM_COMPAT qemu_log("--------------\n"); log_cpu_state(CPU(cpu), 0); #endif } next_page_start = (pc_start & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; lj = -1; num_insns = 0; max_insns = tb->cflags & CF_COUNT_MASK; if (max_insns == 0) max_insns = CF_COUNT_MASK; gen_tb_start(tb); do { #if SIM_COMPAT if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { tcg_gen_movi_tl(cpu_SR[SR_PC], dc->pc); gen_helper_debug(); } #endif check_breakpoint(env, dc); if (search_pc) { j = tcg_op_buf_count(); if (lj < j) { lj++; while (lj < j) tcg_ctx.gen_opc_instr_start[lj++] = 0; } tcg_ctx.gen_opc_pc[lj] = dc->pc; tcg_ctx.gen_opc_instr_start[lj] = 1; tcg_ctx.gen_opc_icount[lj] = num_insns; } /* Pretty disas. */ LOG_DIS("%8.8x:\t", dc->pc); if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO)) gen_io_start(); dc->clear_imm = 1; decode(dc, cpu_ldl_code(env, dc->pc)); if (dc->clear_imm) dc->tb_flags &= ~IMM_FLAG; dc->pc += 4; num_insns++; if (dc->delayed_branch) { dc->delayed_branch--; if (!dc->delayed_branch) { if (dc->tb_flags & DRTI_FLAG) do_rti(dc); if (dc->tb_flags & DRTB_FLAG) do_rtb(dc); if (dc->tb_flags & DRTE_FLAG) do_rte(dc); /* Clear the delay slot flag. */ dc->tb_flags &= ~D_FLAG; /* If it is a direct jump, try direct chaining. */ if (dc->jmp == JMP_INDIRECT) { eval_cond_jmp(dc, env_btarget, tcg_const_tl(dc->pc)); dc->is_jmp = DISAS_JUMP; } else if (dc->jmp == JMP_DIRECT) { t_sync_flags(dc); gen_goto_tb(dc, 0, dc->jmp_pc); dc->is_jmp = DISAS_TB_JUMP; } else if (dc->jmp == JMP_DIRECT_CC) { int l1; t_sync_flags(dc); l1 = gen_new_label(); /* Conditional jmp. */ tcg_gen_brcondi_tl(TCG_COND_NE, env_btaken, 0, l1); gen_goto_tb(dc, 1, dc->pc); gen_set_label(l1); gen_goto_tb(dc, 0, dc->jmp_pc); dc->is_jmp = DISAS_TB_JUMP; } break; } } if (cs->singlestep_enabled) { break; } } while (!dc->is_jmp && !dc->cpustate_changed && !tcg_op_buf_full() && !singlestep && (dc->pc < next_page_start) && num_insns < max_insns); npc = dc->pc; if (dc->jmp == JMP_DIRECT || dc->jmp == JMP_DIRECT_CC) { if (dc->tb_flags & D_FLAG) { dc->is_jmp = DISAS_UPDATE; tcg_gen_movi_tl(cpu_SR[SR_PC], npc); sync_jmpstate(dc); } else npc = dc->jmp_pc; } if (tb->cflags & CF_LAST_IO) gen_io_end(); /* Force an update if the per-tb cpu state has changed. */ if (dc->is_jmp == DISAS_NEXT && (dc->cpustate_changed || org_flags != dc->tb_flags)) { dc->is_jmp = DISAS_UPDATE; tcg_gen_movi_tl(cpu_SR[SR_PC], npc); } t_sync_flags(dc); if (unlikely(cs->singlestep_enabled)) { TCGv_i32 tmp = tcg_const_i32(EXCP_DEBUG); if (dc->is_jmp != DISAS_JUMP) { tcg_gen_movi_tl(cpu_SR[SR_PC], npc); } gen_helper_raise_exception(cpu_env, tmp); tcg_temp_free_i32(tmp); } else { switch(dc->is_jmp) { case DISAS_NEXT: gen_goto_tb(dc, 1, npc); break; default: case DISAS_JUMP: case DISAS_UPDATE: /* indicate that the hash table must be used to find the next TB */ tcg_gen_exit_tb(0); break; case DISAS_TB_JUMP: /* nothing more to generate */ break; } } gen_tb_end(tb, num_insns); if (search_pc) { j = tcg_op_buf_count(); lj++; while (lj <= j) tcg_ctx.gen_opc_instr_start[lj++] = 0; } else { tb->size = dc->pc - pc_start; tb->icount = num_insns; } #ifdef DEBUG_DISAS #if !SIM_COMPAT if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) { qemu_log("\n"); #if DISAS_GNU log_target_disas(env, pc_start, dc->pc - pc_start, 0); #endif qemu_log("\nisize=%d osize=%d\n", dc->pc - pc_start, tcg_op_buf_count()); } #endif #endif assert(!dc->abort_at_next_insn); }


static void test_bh_delete_from_cb_many(void) { BHTestData data1 = { .n = 0, .max = 1 }; BHTestData data2 = { .n = 0, .max = 3 }; BHTestData data3 = { .n = 0, .max = 2 }; BHTestData data4 = { .n = 0, .max = 4 }; data1.bh = aio_bh_new(ctx, bh_delete_cb, &data1); data2.bh = aio_bh_new(ctx, bh_delete_cb, &data2); data3.bh = aio_bh_new(ctx, bh_delete_cb, &data3); data4.bh = aio_bh_new(ctx, bh_delete_cb, &data4); qemu_bh_schedule(data1.bh); qemu_bh_schedule(data2.bh); qemu_bh_schedule(data3.bh); qemu_bh_schedule(data4.bh); g_assert_cmpint(data1.n, ==, 0); g_assert_cmpint(data2.n, ==, 0); g_assert_cmpint(data3.n, ==, 0); g_assert_cmpint(data4.n, ==, 0); g_assert(aio_poll(ctx, false)); g_assert_cmpint(data1.n, ==, 1); g_assert_cmpint(data2.n, ==, 1); g_assert_cmpint(data3.n, ==, 1); g_assert_cmpint(data4.n, ==, 1); g_assert(data1.bh == NULL); wait_for_aio(); g_assert_cmpint(data1.n, ==, data1.max); g_assert_cmpint(data2.n, ==, data2.max); g_assert_cmpint(data3.n, ==, data3.max); g_assert_cmpint(data4.n, ==, data4.max); g_assert(data1.bh == NULL); g_assert(data2.bh == NULL); g_assert(data3.bh == NULL); g_assert(data4.bh == NULL); }


static int raw_has_zero_init(BlockDriverState *bs) { return bdrv_has_zero_init(bs->file->bs); }


void bios_linker_loader_add_pointer(GArray *linker, const char *dest_file, const char *src_file, GArray *table, void *pointer, uint8_t pointer_size) { BiosLinkerLoaderEntry entry; memset(&entry, 0, sizeof entry); strncpy(entry.pointer.dest_file, dest_file, sizeof entry.pointer.dest_file - 1); strncpy(entry.pointer.src_file, src_file, sizeof entry.pointer.src_file - 1); entry.command = cpu_to_le32(BIOS_LINKER_LOADER_COMMAND_ADD_POINTER); entry.pointer.offset = cpu_to_le32((gchar *)pointer - table->data); entry.pointer.size = pointer_size; assert(pointer_size == 1 || pointer_size == 2 || pointer_size == 4 || pointer_size == 8); g_array_append_val(linker, entry); }


static void vga_draw_graphic(VGACommonState *s, int full_update) { int y1, y, update, linesize, y_start, double_scan, mask, depth; int width, height, shift_control, line_offset, bwidth, bits; ram_addr_t page0, page1, page_min, page_max; int disp_width, multi_scan, multi_run; uint8_t *d; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line; full_update |= update_basic_params(s); if (!full_update) vga_sync_dirty_bitmap(s); s->get_resolution(s, &width, &height); disp_width = width; shift_control = (s->gr[VGA_GFX_MODE] >> 5) & 3; double_scan = (s->cr[VGA_CRTC_MAX_SCAN] >> 7); if (shift_control != 1) { multi_scan = (((s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1) << double_scan) - 1; } else { /* in CGA modes, multi_scan is ignored */ /* XXX: is it correct ? */ multi_scan = double_scan; } multi_run = multi_scan; if (shift_control != s->shift_control || double_scan != s->double_scan) { full_update = 1; s->shift_control = shift_control; s->double_scan = double_scan; } if (shift_control == 0) { if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { disp_width <<= 1; } } else if (shift_control == 1) { if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { disp_width <<= 1; } } depth = s->get_bpp(s); if (s->line_offset != s->last_line_offset || disp_width != s->last_width || height != s->last_height || s->last_depth != depth) { #if defined(HOST_WORDS_BIGENDIAN) == defined(TARGET_WORDS_BIGENDIAN) if (depth == 16 || depth == 32) { #else if (depth == 32) { #endif qemu_free_displaysurface(s->ds); s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4)); #if defined(HOST_WORDS_BIGENDIAN) != defined(TARGET_WORDS_BIGENDIAN) s->ds->surface->pf = qemu_different_endianness_pixelformat(depth); #endif dpy_gfx_resize(s->ds); } else { qemu_console_resize(s->ds, disp_width, height); } s->last_scr_width = disp_width; s->last_scr_height = height; s->last_width = disp_width; s->last_height = height; s->last_line_offset = s->line_offset; s->last_depth = depth; full_update = 1; } else if (is_buffer_shared(s->ds->surface) && (full_update || ds_get_data(s->ds) != s->vram_ptr + (s->start_addr * 4))) { qemu_free_displaysurface(s->ds); s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4)); dpy_gfx_setdata(s->ds); } s->rgb_to_pixel = rgb_to_pixel_dup_table[get_depth_index(s->ds)]; if (shift_control == 0) { full_update |= update_palette16(s); if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { v = VGA_DRAW_LINE4D2; } else { v = VGA_DRAW_LINE4; } bits = 4; } else if (shift_control == 1) { full_update |= update_palette16(s); if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { v = VGA_DRAW_LINE2D2; } else { v = VGA_DRAW_LINE2; } bits = 4; } else { switch(s->get_bpp(s)) { default: case 0: full_update |= update_palette256(s); v = VGA_DRAW_LINE8D2; bits = 4; break; case 8: full_update |= update_palette256(s); v = VGA_DRAW_LINE8; bits = 8; break; case 15: v = VGA_DRAW_LINE15; bits = 16; break; case 16: v = VGA_DRAW_LINE16; bits = 16; break; case 24: v = VGA_DRAW_LINE24; bits = 24; break; case 32: v = VGA_DRAW_LINE32; bits = 32; break; } } vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)]; if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate) s->cursor_invalidate(s); line_offset = s->line_offset; #if 0 printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]); #endif addr1 = (s->start_addr * 4); bwidth = (width * bits + 7) / 8; y_start = -1; page_min = -1; page_max = 0; d = ds_get_data(s->ds); linesize = ds_get_linesize(s->ds); y1 = 0; for(y = 0; y < height; y++) { addr = addr1; if (!(s->cr[VGA_CRTC_MODE] & 1)) { int shift; /* CGA compatibility handling */ shift = 14 + ((s->cr[VGA_CRTC_MODE] >> 6) & 1); addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift); } if (!(s->cr[VGA_CRTC_MODE] & 2)) { addr = (addr & ~0x8000) | ((y1 & 2) << 14); } update = full_update; page0 = addr; page1 = addr + bwidth - 1; update |= memory_region_get_dirty(&s->vram, page0, page1 - page0, DIRTY_MEMORY_VGA); /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; if (update) { if (y_start < 0) y_start = y; if (page0 < page_min) page_min = page0; if (page1 > page_max) page_max = page1; if (!(is_buffer_shared(s->ds->surface))) { vga_draw_line(s, d, s->vram_ptr + addr, width); if (s->cursor_draw_line) s->cursor_draw_line(s, d, y); } } else { if (y_start >= 0) { /* flush to display */ dpy_gfx_update(s->ds, 0, y_start, disp_width, y - y_start); y_start = -1; } } if (!multi_run) { mask = (s->cr[VGA_CRTC_MODE] & 3) ^ 3; if ((y1 & mask) == mask) addr1 += line_offset; y1++; multi_run = multi_scan; } else { multi_run--; } /* line compare acts on the displayed lines */ if (y == s->line_compare) addr1 = 0; d += linesize; } if (y_start >= 0) { /* flush to display */ dpy_gfx_update(s->ds, 0, y_start, disp_width, y - y_start); } /* reset modified pages */ if (page_max >= page_min) { memory_region_reset_dirty(&s->vram, page_min, page_max - page_min, DIRTY_MEMORY_VGA); } memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); }


static int ffm_write_header(AVFormatContext *s) { FFMContext *ffm = s->priv_data; AVStream *st; ByteIOContext *pb = s->pb; AVCodecContext *codec; int bit_rate, i; ffm->packet_size = FFM_PACKET_SIZE; /* header */ put_le32(pb, MKTAG('F', 'F', 'M', '1')); put_be32(pb, ffm->packet_size); /* XXX: store write position in other file ? */ put_be64(pb, ffm->packet_size); /* current write position */ put_be32(pb, s->nb_streams); bit_rate = 0; for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; bit_rate += st->codec->bit_rate; } put_be32(pb, bit_rate); /* list of streams */ for(i=0;i<s->nb_streams;i++) { st = s->streams[i]; av_set_pts_info(st, 64, 1, 1000000); codec = st->codec; /* generic info */ put_be32(pb, codec->codec_id); put_byte(pb, codec->codec_type); put_be32(pb, codec->bit_rate); put_be32(pb, st->quality); put_be32(pb, codec->flags); put_be32(pb, codec->flags2); put_be32(pb, codec->debug); /* specific info */ switch(codec->codec_type) { case CODEC_TYPE_VIDEO: put_be32(pb, codec->time_base.num); put_be32(pb, codec->time_base.den); put_be16(pb, codec->width); put_be16(pb, codec->height); put_be16(pb, codec->gop_size); put_be32(pb, codec->pix_fmt); put_byte(pb, codec->qmin); put_byte(pb, codec->qmax); put_byte(pb, codec->max_qdiff); put_be16(pb, (int) (codec->qcompress * 10000.0)); put_be16(pb, (int) (codec->qblur * 10000.0)); put_be32(pb, codec->bit_rate_tolerance); put_strz(pb, codec->rc_eq); put_be32(pb, codec->rc_max_rate); put_be32(pb, codec->rc_min_rate); put_be32(pb, codec->rc_buffer_size); put_be64(pb, av_dbl2int(codec->i_quant_factor)); put_be64(pb, av_dbl2int(codec->b_quant_factor)); put_be64(pb, av_dbl2int(codec->i_quant_offset)); put_be64(pb, av_dbl2int(codec->b_quant_offset)); put_be32(pb, codec->dct_algo); put_be32(pb, codec->strict_std_compliance); put_be32(pb, codec->max_b_frames); put_be32(pb, codec->luma_elim_threshold); put_be32(pb, codec->chroma_elim_threshold); put_be32(pb, codec->mpeg_quant); put_be32(pb, codec->intra_dc_precision); put_be32(pb, codec->me_method); put_be32(pb, codec->mb_decision); put_be32(pb, codec->nsse_weight); put_be32(pb, codec->frame_skip_cmp); put_be64(pb, av_dbl2int(codec->rc_buffer_aggressivity)); put_be32(pb, codec->codec_tag); break; case CODEC_TYPE_AUDIO: put_be32(pb, codec->sample_rate); put_le16(pb, codec->channels); put_le16(pb, codec->frame_size); break; default: return -1; } } /* hack to have real time */ if (ffm_nopts) ffm->start_time = 0; else ffm->start_time = av_gettime(); /* flush until end of block reached */ while ((url_ftell(pb) % ffm->packet_size) != 0) put_byte(pb, 0); put_flush_packet(pb); /* init packet mux */ ffm->packet_ptr = ffm->packet; ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; assert(ffm->packet_end >= ffm->packet); ffm->frame_offset = 0; ffm->pts = 0; ffm->first_packet = 1; return 0; }