static int unpack_superblocks(Vp3DecodeContext *s, GetBitContext *gb) { int superblock_starts[3] = { 0, s->u_superblock_start, s->v_superblock_start }; int bit = 0; int current_superblock = 0; int current_run = 0; int num_partial_superblocks = 0; int i, j; int current_fragment; int plane; if (s->keyframe) { memset(s->superblock_coding, SB_FULLY_CODED, s->superblock_count); } else { /* unpack the list of partially-coded superblocks */ bit = get_bits1(gb) ^ 1; current_run = 0; while (current_superblock < s->superblock_count && get_bits_left(gb) > 0) { if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN) bit = get_bits1(gb); else bit ^= 1; current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1; if (current_run == 34) current_run += get_bits(gb, 12); if (current_superblock + current_run > s->superblock_count) { av_log(s->avctx, AV_LOG_ERROR, "Invalid partially coded superblock run length\n"); return -1; } memset(s->superblock_coding + current_superblock, bit, current_run); current_superblock += current_run; if (bit) num_partial_superblocks += current_run; } /* unpack the list of fully coded superblocks if any of the blocks were * not marked as partially coded in the previous step */ if (num_partial_superblocks < s->superblock_count) { int superblocks_decoded = 0; current_superblock = 0; bit = get_bits1(gb) ^ 1; current_run = 0; while (superblocks_decoded < s->superblock_count - num_partial_superblocks && get_bits_left(gb) > 0) { if (s->theora && current_run == MAXIMUM_LONG_BIT_RUN) bit = get_bits1(gb); else bit ^= 1; current_run = get_vlc2(gb, s->superblock_run_length_vlc.table, 6, 2) + 1; if (current_run == 34) current_run += get_bits(gb, 12); for (j = 0; j < current_run; current_superblock++) { if (current_superblock >= s->superblock_count) { av_log(s->avctx, AV_LOG_ERROR, "Invalid fully coded superblock run length\n"); return -1; } /* skip any superblocks already marked as partially coded */ if (s->superblock_coding[current_superblock] == SB_NOT_CODED) { s->superblock_coding[current_superblock] = 2 * bit; j++; } } superblocks_decoded += current_run; } } /* if there were partial blocks, initialize bitstream for * unpacking fragment codings */ if (num_partial_superblocks) { current_run = 0; bit = get_bits1(gb); /* toggle the bit because as soon as the first run length is * fetched the bit will be toggled again */ bit ^= 1; } } /* figure out which fragments are coded; iterate through each * superblock (all planes) */ s->total_num_coded_frags = 0; memset(s->macroblock_coding, MODE_COPY, s->macroblock_count); for (plane = 0; plane < 3; plane++) { int sb_start = superblock_starts[plane]; int sb_end = sb_start + (plane ? s->c_superblock_count : s->y_superblock_count); int num_coded_frags = 0; for (i = sb_start; i < sb_end && get_bits_left(gb) > 0; i++) { /* iterate through all 16 fragments in a superblock */ for (j = 0; j < 16; j++) { /* if the fragment is in bounds, check its coding status */ current_fragment = s->superblock_fragments[i * 16 + j]; if (current_fragment != -1) { int coded = s->superblock_coding[i]; if (s->superblock_coding[i] == SB_PARTIALLY_CODED) { /* fragment may or may not be coded; this is the case * that cares about the fragment coding runs */ if (current_run-- == 0) { bit ^= 1; current_run = get_vlc2(gb, s->fragment_run_length_vlc.table, 5, 2); } coded = bit; } if (coded) { /* default mode; actual mode will be decoded in * the next phase */ s->all_fragments[current_fragment].coding_method = MODE_INTER_NO_MV; s->coded_fragment_list[plane][num_coded_frags++] = current_fragment; } else { /* not coded; copy this fragment from the prior frame */ s->all_fragments[current_fragment].coding_method = MODE_COPY; } } } } s->total_num_coded_frags += num_coded_frags; for (i = 0; i < 64; i++) s->num_coded_frags[plane][i] = num_coded_frags; if (plane < 2) s->coded_fragment_list[plane + 1] = s->coded_fragment_list[plane] + num_coded_frags; } return 0; }


static void isapc_machine_options(MachineClass *m) { pc_common_machine_options(m); m->desc = "ISA-only PC"; m->max_cpus = 1; }


static int init_video_param(AVCodecContext *avctx, QSVEncContext *q) { float quant; int ret; ret = ff_qsv_codec_id_to_mfx(avctx->codec_id); if (ret < 0) return AVERROR_BUG; q->param.mfx.CodecId = ret; q->width_align = avctx->codec_id == AV_CODEC_ID_HEVC ? 32 : 16; if (avctx->level > 0) q->param.mfx.CodecLevel = avctx->level; q->param.mfx.CodecProfile = q->profile; q->param.mfx.TargetUsage = q->preset; q->param.mfx.GopPicSize = FFMAX(0, avctx->gop_size); q->param.mfx.GopRefDist = FFMAX(-1, avctx->max_b_frames) + 1; q->param.mfx.GopOptFlag = avctx->flags & AV_CODEC_FLAG_CLOSED_GOP ? MFX_GOP_CLOSED : 0; q->param.mfx.IdrInterval = q->idr_interval; q->param.mfx.NumSlice = avctx->slices; q->param.mfx.NumRefFrame = FFMAX(0, avctx->refs); q->param.mfx.EncodedOrder = 0; q->param.mfx.BufferSizeInKB = 0; q->param.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12; q->param.mfx.FrameInfo.Width = FFALIGN(avctx->width, q->width_align); q->param.mfx.FrameInfo.Height = FFALIGN(avctx->height, 32); q->param.mfx.FrameInfo.CropX = 0; q->param.mfx.FrameInfo.CropY = 0; q->param.mfx.FrameInfo.CropW = avctx->width; q->param.mfx.FrameInfo.CropH = avctx->height; q->param.mfx.FrameInfo.AspectRatioW = avctx->sample_aspect_ratio.num; q->param.mfx.FrameInfo.AspectRatioH = avctx->sample_aspect_ratio.den; q->param.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE; q->param.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420; q->param.mfx.FrameInfo.BitDepthLuma = 8; q->param.mfx.FrameInfo.BitDepthChroma = 8; if (avctx->framerate.den > 0 && avctx->framerate.num > 0) { q->param.mfx.FrameInfo.FrameRateExtN = avctx->framerate.num; q->param.mfx.FrameInfo.FrameRateExtD = avctx->framerate.den; } else { q->param.mfx.FrameInfo.FrameRateExtN = avctx->time_base.den; q->param.mfx.FrameInfo.FrameRateExtD = avctx->time_base.num; } ret = select_rc_mode(avctx, q); if (ret < 0) return ret; switch (q->param.mfx.RateControlMethod) { case MFX_RATECONTROL_CBR: case MFX_RATECONTROL_VBR: #if QSV_HAVE_VCM case MFX_RATECONTROL_VCM: #endif q->param.mfx.InitialDelayInKB = avctx->rc_initial_buffer_occupancy / 1000; q->param.mfx.TargetKbps = avctx->bit_rate / 1000; q->param.mfx.MaxKbps = avctx->rc_max_rate / 1000; break; case MFX_RATECONTROL_CQP: quant = avctx->global_quality / FF_QP2LAMBDA; q->param.mfx.QPI = av_clip(quant * fabs(avctx->i_quant_factor) + avctx->i_quant_offset, 0, 51); q->param.mfx.QPP = av_clip(quant, 0, 51); q->param.mfx.QPB = av_clip(quant * fabs(avctx->b_quant_factor) + avctx->b_quant_offset, 0, 51); break; case MFX_RATECONTROL_AVBR: q->param.mfx.TargetKbps = avctx->bit_rate / 1000; q->param.mfx.Convergence = q->avbr_convergence; q->param.mfx.Accuracy = q->avbr_accuracy; break; #if QSV_HAVE_LA case MFX_RATECONTROL_LA: q->param.mfx.TargetKbps = avctx->bit_rate / 1000; q->extco2.LookAheadDepth = q->la_depth; break; #if QSV_HAVE_ICQ case MFX_RATECONTROL_LA_ICQ: q->extco2.LookAheadDepth = q->la_depth; case MFX_RATECONTROL_ICQ: q->param.mfx.ICQQuality = avctx->global_quality; break; #endif #endif } // the HEVC encoder plugin currently fails if coding options // are provided if (avctx->codec_id != AV_CODEC_ID_HEVC) { q->extco.Header.BufferId = MFX_EXTBUFF_CODING_OPTION; q->extco.Header.BufferSz = sizeof(q->extco); q->extco.CAVLC = avctx->coder_type == FF_CODER_TYPE_VLC ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_UNKNOWN; if (q->rdo >= 0) q->extco.RateDistortionOpt = q->rdo > 0 ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (avctx->codec_id == AV_CODEC_ID_H264) { if (avctx->strict_std_compliance != FF_COMPLIANCE_NORMAL) q->extco.NalHrdConformance = avctx->strict_std_compliance > FF_COMPLIANCE_NORMAL ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->single_sei_nal_unit >= 0) q->extco.SingleSeiNalUnit = q->single_sei_nal_unit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->recovery_point_sei >= 0) q->extco.RecoveryPointSEI = q->recovery_point_sei ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; q->extco.MaxDecFrameBuffering = q->max_dec_frame_buffering; } q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco; #if QSV_HAVE_CO2 if (avctx->codec_id == AV_CODEC_ID_H264) { q->extco2.Header.BufferId = MFX_EXTBUFF_CODING_OPTION2; q->extco2.Header.BufferSz = sizeof(q->extco2); if (q->int_ref_type >= 0) q->extco2.IntRefType = q->int_ref_type; if (q->int_ref_cycle_size >= 0) q->extco2.IntRefCycleSize = q->int_ref_cycle_size; if (q->int_ref_qp_delta != INT16_MIN) q->extco2.IntRefQPDelta = q->int_ref_qp_delta; if (q->bitrate_limit >= 0) q->extco2.BitrateLimit = q->bitrate_limit ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->mbbrc >= 0) q->extco2.MBBRC = q->mbbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->extbrc >= 0) q->extco2.ExtBRC = q->extbrc ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->max_frame_size >= 0) q->extco2.MaxFrameSize = q->max_frame_size; #if QSV_HAVE_MAX_SLICE_SIZE if (q->max_slice_size >= 0) q->extco2.MaxSliceSize = q->max_slice_size; #endif #if QSV_HAVE_TRELLIS q->extco2.Trellis = q->trellis; #endif #if QSV_HAVE_BREF_TYPE if (avctx->b_frame_strategy >= 0) q->extco2.BRefType = avctx->b_frame_strategy ? MFX_B_REF_PYRAMID : MFX_B_REF_OFF; if (q->adaptive_i >= 0) q->extco2.AdaptiveI = q->adaptive_i ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; if (q->adaptive_b >= 0) q->extco2.AdaptiveB = q->adaptive_b ? MFX_CODINGOPTION_ON : MFX_CODINGOPTION_OFF; #endif q->extparam_internal[q->nb_extparam_internal++] = (mfxExtBuffer *)&q->extco2; } #endif } if (!rc_supported(q)) { av_log(avctx, AV_LOG_ERROR, "Selected ratecontrol mode is not supported by the QSV " "runtime. Choose a different mode.\n"); return AVERROR(ENOSYS); } return 0; }


static void lag_pred_line(LagarithContext *l, uint8_t *buf, int width, int stride, int line) { int L, TL; /* Left pixel is actually prev_row[width] */ L = buf[width - stride - 1]; if (!line) { /* Left prediction only for first line */ L = l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]); return; } else if (line == 1) { /* Second line, left predict first pixel, the rest of the line is median predicted * NOTE: In the case of RGB this pixel is top predicted */ TL = l->avctx->pix_fmt == PIX_FMT_YUV420P ? buf[-stride] : L; } else { /* Top left is 2 rows back, last pixel */ TL = buf[width - (2 * stride) - 1]; } add_lag_median_prediction(buf, buf - stride, buf, width, &L, &TL); }


static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb, uint64_t oid, unsigned int data_len, uint64_t offset, uint8_t flags, uint64_t base_oid, unsigned int iov_offset) { AIOReq *aio_req; aio_req = g_malloc(sizeof(*aio_req)); aio_req->aiocb = acb; aio_req->iov_offset = iov_offset; aio_req->oid = oid; aio_req->base_oid = base_oid; aio_req->offset = offset; aio_req->data_len = data_len; aio_req->flags = flags; aio_req->id = s->aioreq_seq_num++; acb->nr_pending++; return aio_req; }


static void ff_acelp_interpolatef_mips(float *out, const float *in, const float *filter_coeffs, int precision, int frac_pos, int filter_length, int length) { int n, i; int prec = precision * 4; int fc_offset = precision - frac_pos; float in_val_p, in_val_m, fc_val_p, fc_val_m; for (n = 0; n < length; n++) { /** * four pointers are defined in order to minimize number of * computations done in inner loop */ const float *p_in_p = &in[n]; const float *p_in_m = &in[n-1]; const float *p_filter_coeffs_p = &filter_coeffs[frac_pos]; const float *p_filter_coeffs_m = filter_coeffs + fc_offset; float v = 0; for (i = 0; i < filter_length;i++) { __asm__ volatile ( "lwc1 %[in_val_p], 0(%[p_in_p]) \n\t" "lwc1 %[fc_val_p], 0(%[p_filter_coeffs_p]) \n\t" "lwc1 %[in_val_m], 0(%[p_in_m]) \n\t" "lwc1 %[fc_val_m], 0(%[p_filter_coeffs_m]) \n\t" "addiu %[p_in_p], %[p_in_p], 4 \n\t" "madd.s %[v],%[v], %[in_val_p],%[fc_val_p] \n\t" "addiu %[p_in_m], %[p_in_m], -4 \n\t" "addu %[p_filter_coeffs_p], %[p_filter_coeffs_p], %[prec] \n\t" "addu %[p_filter_coeffs_m], %[p_filter_coeffs_m], %[prec] \n\t" "madd.s %[v],%[v],%[in_val_m], %[fc_val_m] \n\t" : [v] "=&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m), [p_filter_coeffs_p] "+r" (p_filter_coeffs_p), [in_val_p] "=&f" (in_val_p), [in_val_m] "=&f" (in_val_m), [fc_val_p] "=&f" (fc_val_p), [fc_val_m] "=&f" (fc_val_m), [p_filter_coeffs_m] "+r" (p_filter_coeffs_m) : [prec] "r" (prec) : "memory" ); } out[n] = v; } }


static int mpegts_push_data(MpegTSFilter *filter, const uint8_t *buf, int buf_size, int is_start, int64_t pos) { PESContext *pes = filter->u.pes_filter.opaque; MpegTSContext *ts = pes->ts; const uint8_t *p; int len, code; if(!ts->pkt) return 0; if (is_start) { if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { new_pes_packet(pes, ts->pkt); ts->stop_parse = 1; } pes->state = MPEGTS_HEADER; pes->data_index = 0; pes->ts_packet_pos = pos; } p = buf; while (buf_size > 0) { switch(pes->state) { case MPEGTS_HEADER: len = PES_START_SIZE - pes->data_index; if (len > buf_size) len = buf_size; memcpy(pes->header + pes->data_index, p, len); pes->data_index += len; p += len; buf_size -= len; if (pes->data_index == PES_START_SIZE) { /* we got all the PES or section header. We can now decide */ if (pes->header[0] == 0x00 && pes->header[1] == 0x00 && pes->header[2] == 0x01) { /* it must be an mpeg2 PES stream */ code = pes->header[3] | 0x100; av_dlog(pes->stream, "pid=%x pes_code=%#x\n", pes->pid, code); if ((pes->st && pes->st->discard == AVDISCARD_ALL) || code == 0x1be) /* padding_stream */ goto skip; /* stream not present in PMT */ if (!pes->st) { pes->st = av_new_stream(ts->stream, pes->pid); if (!pes->st) return AVERROR(ENOMEM); mpegts_set_stream_info(pes->st, pes, 0, 0); } pes->total_size = AV_RB16(pes->header + 4); /* NOTE: a zero total size means the PES size is unbounded */ if (!pes->total_size) pes->total_size = MAX_PES_PAYLOAD; /* allocate pes buffer */ pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); if (!pes->buffer) return AVERROR(ENOMEM); if (code != 0x1bc && code != 0x1bf && /* program_stream_map, private_stream_2 */ code != 0x1f0 && code != 0x1f1 && /* ECM, EMM */ code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */ code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */ pes->state = MPEGTS_PESHEADER; if (pes->st->codec->codec_id == CODEC_ID_NONE) { av_dlog(pes->stream, "pid=%x stream_type=%x probing\n", pes->pid, pes->stream_type); pes->st->codec->codec_id = CODEC_ID_PROBE; } } else { pes->state = MPEGTS_PAYLOAD; pes->data_index = 0; } } else { /* otherwise, it should be a table */ /* skip packet */ skip: pes->state = MPEGTS_SKIP; continue; } } break; /**********************************************/ /* PES packing parsing */ case MPEGTS_PESHEADER: len = PES_HEADER_SIZE - pes->data_index; if (len < 0) return -1; if (len > buf_size) len = buf_size; memcpy(pes->header + pes->data_index, p, len); pes->data_index += len; p += len; buf_size -= len; if (pes->data_index == PES_HEADER_SIZE) { pes->pes_header_size = pes->header[8] + 9; pes->state = MPEGTS_PESHEADER_FILL; } break; case MPEGTS_PESHEADER_FILL: len = pes->pes_header_size - pes->data_index; if (len < 0) return -1; if (len > buf_size) len = buf_size; memcpy(pes->header + pes->data_index, p, len); pes->data_index += len; p += len; buf_size -= len; if (pes->data_index == pes->pes_header_size) { const uint8_t *r; unsigned int flags, pes_ext, skip; flags = pes->header[7]; r = pes->header + 9; pes->pts = AV_NOPTS_VALUE; pes->dts = AV_NOPTS_VALUE; if ((flags & 0xc0) == 0x80) { pes->dts = pes->pts = ff_parse_pes_pts(r); r += 5; } else if ((flags & 0xc0) == 0xc0) { pes->pts = ff_parse_pes_pts(r); r += 5; pes->dts = ff_parse_pes_pts(r); r += 5; } pes->extended_stream_id = -1; if (flags & 0x01) { /* PES extension */ pes_ext = *r++; /* Skip PES private data, program packet sequence counter and P-STD buffer */ skip = (pes_ext >> 4) & 0xb; skip += skip & 0x9; r += skip; if ((pes_ext & 0x41) == 0x01 && (r + 2) <= (pes->header + pes->pes_header_size)) { /* PES extension 2 */ if ((r[0] & 0x7f) > 0 && (r[1] & 0x80) == 0) pes->extended_stream_id = r[1]; } } /* we got the full header. We parse it and get the payload */ pes->state = MPEGTS_PAYLOAD; pes->data_index = 0; } break; case MPEGTS_PAYLOAD: if (buf_size > 0 && pes->buffer) { if (pes->data_index > 0 && pes->data_index+buf_size > pes->total_size) { new_pes_packet(pes, ts->pkt); pes->total_size = MAX_PES_PAYLOAD; pes->buffer = av_malloc(pes->total_size+FF_INPUT_BUFFER_PADDING_SIZE); if (!pes->buffer) return AVERROR(ENOMEM); ts->stop_parse = 1; } else if (pes->data_index == 0 && buf_size > pes->total_size) { // pes packet size is < ts size packet and pes data is padded with 0xff // not sure if this is legal in ts but see issue #2392 buf_size = pes->total_size; pes->flags |= AV_PKT_FLAG_CORRUPT; } memcpy(pes->buffer+pes->data_index, p, buf_size); pes->data_index += buf_size; } buf_size = 0; /* emit complete packets with known packet size * decreases demuxer delay for infrequent packets like subtitles from * a couple of seconds to milliseconds for properly muxed files. * total_size is the number of bytes following pes_packet_length * in the pes header, i.e. not counting the first 6 bytes */ if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD && pes->pes_header_size + pes->data_index == pes->total_size + 6) { ts->stop_parse = 1; new_pes_packet(pes, ts->pkt); } break; case MPEGTS_SKIP: buf_size = 0; break; } } return 0; }


static void mov_build_index(MOVContext *mov, AVStream *st) { MOVStreamContext *sc = st->priv_data; int64_t current_offset; int64_t current_dts = 0; unsigned int stts_index = 0; unsigned int stsc_index = 0; unsigned int stss_index = 0; unsigned int stps_index = 0; unsigned int i, j; uint64_t stream_size = 0; /* adjust first dts according to edit list */ if (sc->time_offset && mov->time_scale > 0) { if (sc->time_offset < 0) sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale); current_dts = -sc->time_offset; if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration && sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) { /* more than 16 frames delay, dts are likely wrong this happens with files created by iMovie */ sc->wrong_dts = 1; st->internal->avctx->has_b_frames = 1; } } /* only use old uncompressed audio chunk demuxing when stts specifies it */ if (!(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { unsigned int current_sample = 0; unsigned int stts_sample = 0; unsigned int sample_size; unsigned int distance = 0; unsigned int rap_group_index = 0; unsigned int rap_group_sample = 0; int rap_group_present = sc->rap_group_count && sc->rap_group; int key_off = (sc->keyframes && sc->keyframes[0] > 0) || (sc->stps_data && sc->stps_data[0] > 0); current_dts -= sc->dts_shift; if (!sc->sample_count) return; if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; if (av_reallocp_array(&st->index_entries, st->nb_index_entries + sc->sample_count, sizeof(*st->index_entries)) < 0) { st->nb_index_entries = 0; return; } st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); for (i = 0; i < sc->chunk_count; i++) { current_offset = sc->chunk_offsets[i]; while (mov_stsc_index_valid(stsc_index, sc->stsc_count) && i + 1 == sc->stsc_data[stsc_index + 1].first) stsc_index++; for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { int keyframe = 0; if (current_sample >= sc->sample_count) { av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); return; } if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) { keyframe = 1; if (stss_index + 1 < sc->keyframe_count) stss_index++; } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) { keyframe = 1; if (stps_index + 1 < sc->stps_count) stps_index++; } if (rap_group_present && rap_group_index < sc->rap_group_count) { if (sc->rap_group[rap_group_index].index > 0) keyframe = 1; if (++rap_group_sample == sc->rap_group[rap_group_index].count) { rap_group_sample = 0; rap_group_index++; } } if (keyframe) distance = 0; sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample]; if (sc->pseudo_stream_id == -1 || sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; e->pos = current_offset; e->timestamp = current_dts; e->size = sample_size; e->min_distance = distance; e->flags = keyframe ? AVINDEX_KEYFRAME : 0; av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " "size %d, distance %d, keyframe %d\n", st->index, current_sample, current_offset, current_dts, sample_size, distance, keyframe); } current_offset += sample_size; stream_size += sample_size; current_dts += sc->stts_data[stts_index].duration; distance++; stts_sample++; current_sample++; if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) { stts_sample = 0; stts_index++; } } } if (st->duration > 0) st->codecpar->bit_rate = stream_size*8*sc->time_scale/st->duration; } else { unsigned chunk_samples, total = 0; // compute total chunk count for (i = 0; i < sc->stsc_count; i++) { unsigned count, chunk_count; chunk_samples = sc->stsc_data[i].count; if (i != sc->stsc_count - 1 && sc->samples_per_frame && chunk_samples % sc->samples_per_frame) { av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); return; } if (sc->samples_per_frame >= 160) { // gsm count = chunk_samples / sc->samples_per_frame; } else if (sc->samples_per_frame > 1) { unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame; count = (chunk_samples+samples-1) / samples; } else { count = (chunk_samples+1023) / 1024; } if (mov_stsc_index_valid(i, sc->stsc_count)) chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first; else chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1); total += chunk_count * count; } av_log(mov->fc, AV_LOG_TRACE, "chunk count %d\n", total); if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; if (av_reallocp_array(&st->index_entries, st->nb_index_entries + total, sizeof(*st->index_entries)) < 0) { st->nb_index_entries = 0; return; } st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries); // populate index for (i = 0; i < sc->chunk_count; i++) { current_offset = sc->chunk_offsets[i]; if (mov_stsc_index_valid(stsc_index, sc->stsc_count) && i + 1 == sc->stsc_data[stsc_index + 1].first) stsc_index++; chunk_samples = sc->stsc_data[stsc_index].count; while (chunk_samples > 0) { AVIndexEntry *e; unsigned size, samples; if (sc->samples_per_frame > 1 && !sc->bytes_per_frame) { avpriv_request_sample(mov->fc, "Zero bytes per frame, but %d samples per frame", sc->samples_per_frame); return; } if (sc->samples_per_frame >= 160) { // gsm samples = sc->samples_per_frame; size = sc->bytes_per_frame; } else { if (sc->samples_per_frame > 1) { samples = FFMIN((1024 / sc->samples_per_frame)* sc->samples_per_frame, chunk_samples); size = (samples / sc->samples_per_frame) * sc->bytes_per_frame; } else { samples = FFMIN(1024, chunk_samples); size = samples * sc->sample_size; } } if (st->nb_index_entries >= total) { av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total); return; } e = &st->index_entries[st->nb_index_entries++]; e->pos = current_offset; e->timestamp = current_dts; e->size = size; e->min_distance = 0; e->flags = AVINDEX_KEYFRAME; av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " "size %d, duration %d\n", st->index, i, current_offset, current_dts, size, samples); current_offset += size; current_dts += samples; chunk_samples -= samples; } } } }


static int32_t scsi_target_send_command(SCSIRequest *req, uint8_t *buf) { SCSITargetReq *r = DO_UPCAST(SCSITargetReq, req, req); switch (buf[0]) { case REPORT_LUNS: if (!scsi_target_emulate_report_luns(r)) { goto illegal_request; } break; case INQUIRY: if (!scsi_target_emulate_inquiry(r)) { goto illegal_request; } break; case REQUEST_SENSE: scsi_target_alloc_buf(&r->req, scsi_sense_len(req)); r->len = scsi_device_get_sense(r->req.dev, r->buf, MIN(req->cmd.xfer, r->buf_len), (req->cmd.buf[1] & 1) == 0); if (r->req.dev->sense_is_ua) { scsi_device_unit_attention_reported(req->dev); r->req.dev->sense_len = 0; r->req.dev->sense_is_ua = false; } break; case TEST_UNIT_READY: break; default: scsi_req_build_sense(req, SENSE_CODE(LUN_NOT_SUPPORTED)); scsi_req_complete(req, CHECK_CONDITION); return 0; illegal_request: scsi_req_build_sense(req, SENSE_CODE(INVALID_FIELD)); scsi_req_complete(req, CHECK_CONDITION); return 0; } if (!r->len) { scsi_req_complete(req, GOOD); } return r->len; }


static inline int onenand_load_spare(OneNANDState *s, int sec, int secn, void *dest) { uint8_t buf[512]; if (s->bdrv_cur) { if (bdrv_read(s->bdrv_cur, s->secs_cur + (sec >> 5), buf, 1) < 0) return 1; memcpy(dest, buf + ((sec & 31) << 4), secn << 4); } else if (sec + secn > s->secs_cur) return 1; else memcpy(dest, s->current + (s->secs_cur << 9) + (sec << 4), secn << 4); return 0; }


static inline void gen_op_fcmps(int fccno, TCGv_i32 r_rs1, TCGv_i32 r_rs2) { switch (fccno) { case 0: gen_helper_fcmps(cpu_env, r_rs1, r_rs2); break; case 1: gen_helper_fcmps_fcc1(cpu_env, r_rs1, r_rs2); break; case 2: gen_helper_fcmps_fcc2(cpu_env, r_rs1, r_rs2); break; case 3: gen_helper_fcmps_fcc3(cpu_env, r_rs1, r_rs2); break; } }


static void tpm_tis_receive_cb(TPMState *s, uint8_t locty) { TPMTISEmuState *tis = &s->s.tis; assert(s->locty_number == locty); qemu_bh_schedule(tis->bh); }


void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len, int is_write, target_phys_addr_t access_len) { if (buffer != bounce.buffer) { if (is_write) { ram_addr_t addr1 = qemu_ram_addr_from_host(buffer); while (access_len) { unsigned l; l = TARGET_PAGE_SIZE; if (l > access_len) l = access_len; if (!cpu_physical_memory_is_dirty(addr1)) { /* invalidate code */ tb_invalidate_phys_page_range(addr1, addr1 + l, 0); /* set dirty bit */ phys_ram_dirty[addr1 >> TARGET_PAGE_BITS] |= (0xff & ~CODE_DIRTY_FLAG); } addr1 += l; access_len -= l; } } return; } if (is_write) { cpu_physical_memory_write(bounce.addr, bounce.buffer, access_len); } qemu_vfree(bounce.buffer); bounce.buffer = NULL; cpu_notify_map_clients(); }


void qdev_prop_set_defaults(DeviceState *dev, Property *props) { if (!props) return; while (props->name) { if (props->defval) { qdev_prop_cpy(dev, props, props->defval); } props++; } }


static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1) { int l1 = gen_new_label(); int l2 = gen_new_label(); tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1); tcg_gen_neg_i32(ret, arg1); tcg_gen_br(l2); gen_set_label(l1); tcg_gen_mov_i32(ret, arg1); gen_set_label(l2); }


static void video_audio_display(VideoState *s) { int i, i_start, x, y1, y, ys, delay, n, nb_display_channels; int ch, channels, h, h2, bgcolor, fgcolor; int16_t time_diff; int rdft_bits, nb_freq; for (rdft_bits = 1; (1 << rdft_bits) < 2 * s->height; rdft_bits++) ; nb_freq = 1 << (rdft_bits - 1); /* compute display index : center on currently output samples */ channels = s->audio_st->codec->channels; nb_display_channels = channels; if (!s->paused) { int data_used = s->show_audio == 1 ? s->width : (2 * nb_freq); n = 2 * channels; delay = audio_write_get_buf_size(s); delay /= n; /* to be more precise, we take into account the time spent since the last buffer computation */ if (audio_callback_time) { time_diff = av_gettime() - audio_callback_time; delay -= (time_diff * s->audio_st->codec->sample_rate) / 1000000; } delay += 2 * data_used; if (delay < data_used) delay = data_used; i_start= x = compute_mod(s->sample_array_index - delay * channels, SAMPLE_ARRAY_SIZE); if (s->show_audio == 1) { h = INT_MIN; for (i = 0; i < 1000; i += channels) { int idx = (SAMPLE_ARRAY_SIZE + x - i) % SAMPLE_ARRAY_SIZE; int a = s->sample_array[idx]; int b = s->sample_array[(idx + 4 * channels) % SAMPLE_ARRAY_SIZE]; int c = s->sample_array[(idx + 5 * channels) % SAMPLE_ARRAY_SIZE]; int d = s->sample_array[(idx + 9 * channels) % SAMPLE_ARRAY_SIZE]; int score = a - d; if (h < score && (b ^ c) < 0) { h = score; i_start = idx; } } } s->last_i_start = i_start; } else { i_start = s->last_i_start; } bgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00); if (s->show_audio == 1) { fill_rectangle(screen, s->xleft, s->ytop, s->width, s->height, bgcolor); fgcolor = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff); /* total height for one channel */ h = s->height / nb_display_channels; /* graph height / 2 */ h2 = (h * 9) / 20; for (ch = 0; ch < nb_display_channels; ch++) { i = i_start + ch; y1 = s->ytop + ch * h + (h / 2); /* position of center line */ for (x = 0; x < s->width; x++) { y = (s->sample_array[i] * h2) >> 15; if (y < 0) { y = -y; ys = y1 - y; } else { ys = y1; } fill_rectangle(screen, s->xleft + x, ys, 1, y, fgcolor); i += channels; if (i >= SAMPLE_ARRAY_SIZE) i -= SAMPLE_ARRAY_SIZE; } } fgcolor = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff); for (ch = 1; ch < nb_display_channels; ch++) { y = s->ytop + ch * h; fill_rectangle(screen, s->xleft, y, s->width, 1, fgcolor); } SDL_UpdateRect(screen, s->xleft, s->ytop, s->width, s->height); } else { nb_display_channels= FFMIN(nb_display_channels, 2); if (rdft_bits != s->rdft_bits) { av_rdft_end(s->rdft); av_free(s->rdft_data); s->rdft = av_rdft_init(rdft_bits, DFT_R2C); s->rdft_bits = rdft_bits; s->rdft_data = av_malloc(4 * nb_freq * sizeof(*s->rdft_data)); } { FFTSample *data[2]; for (ch = 0; ch < nb_display_channels; ch++) { data[ch] = s->rdft_data + 2 * nb_freq * ch; i = i_start + ch; for (x = 0; x < 2 * nb_freq; x++) { double w = (x-nb_freq) * (1.0 / nb_freq); data[ch][x] = s->sample_array[i] * (1.0 - w * w); i += channels; if (i >= SAMPLE_ARRAY_SIZE) i -= SAMPLE_ARRAY_SIZE; } av_rdft_calc(s->rdft, data[ch]); } // least efficient way to do this, we should of course directly access it but its more than fast enough for (y = 0; y < s->height; y++) { double w = 1 / sqrt(nb_freq); int a = sqrt(w * sqrt(data[0][2 * y + 0] * data[0][2 * y + 0] + data[0][2 * y + 1] * data[0][2 * y + 1])); int b = (nb_display_channels == 2 ) ? sqrt(w * sqrt(data[1][2 * y + 0] * data[1][2 * y + 0] + data[1][2 * y + 1] * data[1][2 * y + 1])) : a; a = FFMIN(a, 255); b = FFMIN(b, 255); fgcolor = SDL_MapRGB(screen->format, a, b, (a + b) / 2); fill_rectangle(screen, s->xpos, s->height-y, 1, 1, fgcolor); } } SDL_UpdateRect(screen, s->xpos, s->ytop, 1, s->height); s->xpos++; if (s->xpos >= s->width) s->xpos= s->xleft; } }


static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs) { int ret; GlusterAIOCB acb; BDRVGlusterState *s = bs->opaque; acb.size = 0; acb.ret = 0; acb.coroutine = qemu_coroutine_self(); acb.aio_context = bdrv_get_aio_context(bs); ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb); if (ret < 0) { return -errno; } qemu_coroutine_yield(); return acb.ret; }


static DriveInfo *blockdev_init(QemuOpts *all_opts, BlockInterfaceType block_default_type) { const char *buf; const char *file = NULL; const char *serial; const char *mediastr = ""; BlockInterfaceType type; enum { MEDIA_DISK, MEDIA_CDROM } media; int bus_id, unit_id; int cyls, heads, secs, translation; int max_devs; int index; int ro = 0; int bdrv_flags = 0; int on_read_error, on_write_error; const char *devaddr; DriveInfo *dinfo; ThrottleConfig cfg; int snapshot = 0; bool copy_on_read; int ret; Error *error = NULL; QemuOpts *opts; QDict *bs_opts; const char *id; bool has_driver_specific_opts; BlockDriver *drv = NULL; translation = BIOS_ATA_TRANSLATION_AUTO; media = MEDIA_DISK; /* Check common options by copying from all_opts to opts, all other options * are stored in bs_opts. */ id = qemu_opts_id(all_opts); 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; } bs_opts = qdict_new(); qemu_opts_to_qdict(all_opts, bs_opts); 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 */ bus_id = qemu_opt_get_number(opts, "bus", 0); unit_id = qemu_opt_get_number(opts, "unit", -1); index = qemu_opt_get_number(opts, "index", -1); cyls = qemu_opt_get_number(opts, "cyls", 0); heads = qemu_opt_get_number(opts, "heads", 0); secs = qemu_opt_get_number(opts, "secs", 0); 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, "if")) != NULL) { for (type = 0; type < IF_COUNT && strcmp(buf, if_name[type]); type++) ; if (type == IF_COUNT) { error_report("unsupported bus type '%s'", buf); return NULL; } } else { type = block_default_type; } max_devs = if_max_devs[type]; if (cyls || heads || secs) { if (cyls < 1) { error_report("invalid physical cyls number"); return NULL; } if (heads < 1) { error_report("invalid physical heads number"); return NULL; } if (secs < 1) { error_report("invalid physical secs number"); return NULL; } } if ((buf = qemu_opt_get(opts, "trans")) != NULL) { if (!cyls) { error_report("'%s' trans must be used with cyls, heads and secs", buf); return NULL; } if (!strcmp(buf, "none")) translation = BIOS_ATA_TRANSLATION_NONE; else if (!strcmp(buf, "lba")) translation = BIOS_ATA_TRANSLATION_LBA; else if (!strcmp(buf, "auto")) translation = BIOS_ATA_TRANSLATION_AUTO; else { error_report("'%s' invalid translation type", buf); return NULL; } } if ((buf = qemu_opt_get(opts, "media")) != NULL) { if (!strcmp(buf, "disk")) { media = MEDIA_DISK; } else if (!strcmp(buf, "cdrom")) { if (cyls || secs || heads) { error_report("CHS can't be set with media=%s", buf); return NULL; } media = MEDIA_CDROM; } else { error_report("'%s' invalid media", buf); return NULL; } } 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_whitelisted_format(buf, ro); if (!drv) { if (!ro && bdrv_find_whitelisted_format(buf, !ro)) { error_report("'%s' can be only used as read-only device.", buf); } else { 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; } if (qemu_opt_get(opts, "boot") != NULL) { fprintf(stderr, "qemu-kvm: boot=on|off is deprecated and will be " "ignored. Future versions will reject this parameter. Please " "update your scripts.\n"); } 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; } } if ((devaddr = qemu_opt_get(opts, "addr")) != NULL) { if (type != IF_VIRTIO) { error_report("addr is not supported by this bus type"); return NULL; } } /* compute bus and unit according index */ if (index != -1) { if (bus_id != 0 || unit_id != -1) { error_report("index cannot be used with bus and unit"); return NULL; } bus_id = drive_index_to_bus_id(type, index); unit_id = drive_index_to_unit_id(type, index); } /* if user doesn't specify a unit_id, * try to find the first free */ if (unit_id == -1) { unit_id = 0; while (drive_get(type, bus_id, unit_id) != NULL) { unit_id++; if (max_devs && unit_id >= max_devs) { unit_id -= max_devs; bus_id++; } } } /* check unit id */ if (max_devs && unit_id >= max_devs) { error_report("unit %d too big (max is %d)", unit_id, max_devs - 1); return NULL; } /* * catch multiple definitions */ if (drive_get(type, bus_id, unit_id) != NULL) { error_report("drive with bus=%d, unit=%d (index=%d) exists", bus_id, unit_id, index); return NULL; } /* init */ dinfo = g_malloc0(sizeof(*dinfo)); if ((buf = qemu_opts_id(opts)) != NULL) { dinfo->id = g_strdup(buf); } else { /* no id supplied -> create one */ dinfo->id = g_malloc0(32); if (type == IF_IDE || type == IF_SCSI) mediastr = (media == MEDIA_CDROM) ? "-cd" : "-hd"; if (max_devs) snprintf(dinfo->id, 32, "%s%i%s%i", if_name[type], bus_id, mediastr, unit_id); else snprintf(dinfo->id, 32, "%s%s%i", if_name[type], mediastr, unit_id); } dinfo->bdrv = bdrv_new(dinfo->id); dinfo->bdrv->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0; dinfo->bdrv->read_only = ro; dinfo->devaddr = devaddr; dinfo->type = type; dinfo->bus = bus_id; dinfo->unit = unit_id; dinfo->cyls = cyls; dinfo->heads = heads; dinfo->secs = secs; dinfo->trans = translation; dinfo->opts = all_opts; 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: break; case IF_VIRTIO: { /* add virtio block device */ QemuOpts *devopts; devopts = qemu_opts_create_nofail(qemu_find_opts("device")); if (arch_type == QEMU_ARCH_S390X) { qemu_opt_set(devopts, "driver", "virtio-blk-s390"); } else { qemu_opt_set(devopts, "driver", "virtio-blk-pci"); } qemu_opt_set(devopts, "drive", dinfo->id); if (devaddr) qemu_opt_set(devopts, "addr", devaddr); 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; }


int ff_get_cpu_flags_arm(void) { int flags = CORE_CPU_FLAGS; uint32_t hwcap; if (get_hwcap(&hwcap) < 0) if (get_cpuinfo(&hwcap) < 0) return flags; #define check_cap(cap, flag) do { \ if (hwcap & HWCAP_ ## cap) \ flags |= AV_CPU_FLAG_ ## flag; \ } while (0) /* No flags explicitly indicate v6 or v6T2 so check others which imply support. */ check_cap(EDSP, ARMV5TE); check_cap(TLS, ARMV6); check_cap(THUMBEE, ARMV6T2); check_cap(VFP, VFP); check_cap(VFPv3, VFPV3); check_cap(NEON, NEON); /* The v6 checks above are not reliable so let higher flags trickle down. */ if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)) flags |= AV_CPU_FLAG_ARMV6T2; if (flags & AV_CPU_FLAG_ARMV6T2) flags |= AV_CPU_FLAG_ARMV6; return flags; }


static void avc_luma_vt_4w_msa(const uint8_t *src, int32_t src_stride, uint8_t *dst, int32_t dst_stride, int32_t height) { int32_t loop_cnt; int16_t filt_const0 = 0xfb01; int16_t filt_const1 = 0x1414; int16_t filt_const2 = 0x1fb; v16i8 src0, src1, src2, src3, src4, src5, src6, src7, src8; v16i8 src10_r, src32_r, src54_r, src76_r, src21_r, src43_r, src65_r; v16i8 src87_r, src2110, src4332, src6554, src8776; v16i8 filt0, filt1, filt2; v8i16 out10, out32; v16u8 out; filt0 = (v16i8) __msa_fill_h(filt_const0); filt1 = (v16i8) __msa_fill_h(filt_const1); filt2 = (v16i8) __msa_fill_h(filt_const2); LD_SB5(src, src_stride, src0, src1, src2, src3, src4); src += (5 * src_stride); ILVR_B4_SB(src1, src0, src2, src1, src3, src2, src4, src3, src10_r, src21_r, src32_r, src43_r); ILVR_D2_SB(src21_r, src10_r, src43_r, src32_r, src2110, src4332); XORI_B2_128_SB(src2110, src4332); for (loop_cnt = (height >> 2); loop_cnt--;) { LD_SB4(src, src_stride, src5, src6, src7, src8); src += (4 * src_stride); ILVR_B4_SB(src5, src4, src6, src5, src7, src6, src8, src7, src54_r, src65_r, src76_r, src87_r); ILVR_D2_SB(src65_r, src54_r, src87_r, src76_r, src6554, src8776); XORI_B2_128_SB(src6554, src8776); out10 = DPADD_SH3_SH(src2110, src4332, src6554, filt0, filt1, filt2); out32 = DPADD_SH3_SH(src4332, src6554, src8776, filt0, filt1, filt2); SRARI_H2_SH(out10, out32, 5); SAT_SH2_SH(out10, out32, 7); out = PCKEV_XORI128_UB(out10, out32); ST4x4_UB(out, out, 0, 1, 2, 3, dst, dst_stride); dst += (4 * dst_stride); src2110 = src6554; src4332 = src8776; src4 = src8; } }


static inline uint32_t reloc_26_val(tcg_insn_unit *pc, tcg_insn_unit *target) { assert((((uintptr_t)pc ^ (uintptr_t)target) & 0xf0000000) == 0); return ((uintptr_t)target >> 2) & 0x3ffffff; }


static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) { IRQSource *src; int retval, irq; DPRINTF("Lower OpenPIC INT output\n"); qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); irq = IRQ_get_next(opp, &dst->raised); DPRINTF("IACK: irq=%d\n", irq); if (irq == -1) { /* No more interrupt pending */ return opp->spve; } src = &opp->src[irq]; if (!(src->ivpr & IVPR_ACTIVITY_MASK) || !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) { /* - Spurious level-sensitive IRQ * - Priorities has been changed * and the pending IRQ isn't allowed anymore */ src->ivpr &= ~IVPR_ACTIVITY_MASK; retval = opp->spve; } else { /* IRQ enter servicing state */ IRQ_setbit(&dst->servicing, irq); retval = IVPR_VECTOR(opp, src->ivpr); } IRQ_resetbit(&dst->raised, irq); if (!src->level) { /* edge-sensitive IRQ */ src->ivpr &= ~IVPR_ACTIVITY_MASK; src->pending = 0; } if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + MAX_IPI))) { src->idr &= ~(1 << cpu); if (src->idr && !src->level) { /* trigger on CPUs that didn't know about it yet */ openpic_set_irq(opp, irq, 1); openpic_set_irq(opp, irq, 0); /* if all CPUs knew about it, set active bit again */ src->ivpr |= IVPR_ACTIVITY_MASK; } } return retval; }


static void realview_init(MachineState *machine, enum realview_board_type board_type) { ARMCPU *cpu = NULL; CPUARMState *env; ObjectClass *cpu_oc; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram_lo = g_new(MemoryRegion, 1); MemoryRegion *ram_hi = g_new(MemoryRegion, 1); MemoryRegion *ram_alias = g_new(MemoryRegion, 1); MemoryRegion *ram_hack = g_new(MemoryRegion, 1); DeviceState *dev, *sysctl, *gpio2, *pl041; SysBusDevice *busdev; qemu_irq pic[64]; qemu_irq mmc_irq[2]; PCIBus *pci_bus = NULL; NICInfo *nd; I2CBus *i2c; int n; int done_nic = 0; qemu_irq cpu_irq[4]; int is_mpcore = 0; int is_pb = 0; uint32_t proc_id = 0; uint32_t sys_id; ram_addr_t low_ram_size; ram_addr_t ram_size = machine->ram_size; hwaddr periphbase = 0; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; periphbase = 0x10100000; break; case BOARD_PB_A8: is_pb = 1; break; case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; periphbase = 0x1f000000; break; } cpu_oc = cpu_class_by_name(TYPE_ARM_CPU, machine->cpu_model); if (!cpu_oc) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } for (n = 0; n < smp_cpus; n++) { Object *cpuobj = object_new(object_class_get_name(cpu_oc)); Error *err = NULL; if (is_pb && is_mpcore) { object_property_set_int(cpuobj, periphbase, "reset-cbar", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); } cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpuobj), ARM_CPU_IRQ); } cpu = ARM_CPU(first_cpu); env = &cpu->env; if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { proc_id = 0x0c000000; } else { proc_id = 0x0e000000; } } else if (arm_feature(env, ARM_FEATURE_V6K)) { proc_id = 0x06000000; } else if (arm_feature(env, ARM_FEATURE_V6)) { proc_id = 0x04000000; } else { proc_id = 0x02000000; } if (is_pb && ram_size > 0x20000000) { /* Core tile RAM. */ low_ram_size = ram_size - 0x20000000; ram_size = 0x20000000; memory_region_init_ram(ram_lo, NULL, "realview.lowmem", low_ram_size, &error_abort); vmstate_register_ram_global(ram_lo); memory_region_add_subregion(sysmem, 0x20000000, ram_lo); } memory_region_init_ram(ram_hi, NULL, "realview.highmem", ram_size, &error_abort); vmstate_register_ram_global(ram_hi); low_ram_size = ram_size; if (low_ram_size > 0x10000000) low_ram_size = 0x10000000; /* SDRAM at address zero. */ memory_region_init_alias(ram_alias, NULL, "realview.alias", ram_hi, 0, low_ram_size); memory_region_add_subregion(sysmem, 0, ram_alias); if (is_pb) { /* And again at a high address. */ memory_region_add_subregion(sysmem, 0x70000000, ram_hi); } else { ram_size = low_ram_size; } sys_id = is_pb ? 0x01780500 : 0xc1400400; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_prop_set_uint32(sysctl, "proc_id", proc_id); qdev_init_nofail(sysctl); sysbus_mmio_map(SYS_BUS_DEVICE(sysctl), 0, 0x10000000); if (is_mpcore) { dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, periphbase); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } sysbus_create_varargs("l2x0", periphbase + 0x2000, NULL); /* Both A9 and 11MPCore put the GIC CPU i/f at base + 0x100 */ realview_binfo.gic_cpu_if_addr = periphbase + 0x100; } else { uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000; /* For now just create the nIRQ GIC, and ignore the others. */ dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]); } for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } pl041 = qdev_create(NULL, "pl041"); qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512); qdev_init_nofail(pl041); sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000); sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[19]); sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl011", 0x10009000, pic[12]); sysbus_create_simple("pl011", 0x1000a000, pic[13]); sysbus_create_simple("pl011", 0x1000b000, pic[14]); sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); sysbus_create_simple("pl061", 0x10013000, pic[6]); sysbus_create_simple("pl061", 0x10014000, pic[7]); gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]); sysbus_create_simple("pl111", 0x10020000, pic[23]); dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); /* Wire up MMC card detect and read-only signals. These have * to go to both the PL061 GPIO and the sysctl register. * Note that the PL181 orders these lines (readonly,inserted) * and the PL061 has them the other way about. Also the card * detect line is inverted. */ mmc_irq[0] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT), qdev_get_gpio_in(gpio2, 1)); mmc_irq[1] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN), qemu_irq_invert(qdev_get_gpio_in(gpio2, 0))); qdev_connect_gpio_out(dev, 0, mmc_irq[0]); qdev_connect_gpio_out(dev, 1, mmc_irq[1]); sysbus_create_simple("pl031", 0x10017000, pic[10]); if (!is_pb) { dev = qdev_create(NULL, "realview_pci"); busdev = SYS_BUS_DEVICE(dev); qdev_init_nofail(dev); sysbus_mmio_map(busdev, 0, 0x10019000); /* PCI controller registers */ sysbus_mmio_map(busdev, 1, 0x60000000); /* PCI self-config */ sysbus_mmio_map(busdev, 2, 0x61000000); /* PCI config */ sysbus_mmio_map(busdev, 3, 0x62000000); /* PCI I/O */ sysbus_mmio_map(busdev, 4, 0x63000000); /* PCI memory window 1 */ sysbus_mmio_map(busdev, 5, 0x64000000); /* PCI memory window 2 */ sysbus_mmio_map(busdev, 6, 0x68000000); /* PCI memory window 3 */ sysbus_connect_irq(busdev, 0, pic[48]); sysbus_connect_irq(busdev, 1, pic[49]); sysbus_connect_irq(busdev, 2, pic[50]); sysbus_connect_irq(busdev, 3, pic[51]); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); if (usb_enabled(false)) { pci_create_simple(pci_bus, -1, "pci-ohci"); } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { pci_create_simple(pci_bus, -1, "lsi53c895a"); n--; } } for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (!done_nic && (!nd->model || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) { if (is_pb) { lan9118_init(nd, 0x4e000000, pic[28]); } else { smc91c111_init(nd, 0x4e000000, pic[28]); } done_nic = 1; } else { if (pci_bus) { pci_nic_init_nofail(nd, pci_bus, "rtl8139", NULL); } } } dev = sysbus_create_simple("versatile_i2c", 0x10002000, NULL); i2c = (I2CBus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); /* Memory map for RealView Emulation Baseboard: */ /* 0x10000000 System registers. */ /* 0x10001000 System controller. */ /* 0x10002000 Two-Wire Serial Bus. */ /* 0x10003000 Reserved. */ /* 0x10004000 AACI. */ /* 0x10005000 MCI. */ /* 0x10006000 KMI0. */ /* 0x10007000 KMI1. */ /* 0x10008000 Character LCD. (EB) */ /* 0x10009000 UART0. */ /* 0x1000a000 UART1. */ /* 0x1000b000 UART2. */ /* 0x1000c000 UART3. */ /* 0x1000d000 SSPI. */ /* 0x1000e000 SCI. */ /* 0x1000f000 Reserved. */ /* 0x10010000 Watchdog. */ /* 0x10011000 Timer 0+1. */ /* 0x10012000 Timer 2+3. */ /* 0x10013000 GPIO 0. */ /* 0x10014000 GPIO 1. */ /* 0x10015000 GPIO 2. */ /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */ /* 0x10017000 RTC. */ /* 0x10018000 DMC. */ /* 0x10019000 PCI controller config. */ /* 0x10020000 CLCD. */ /* 0x10030000 DMA Controller. */ /* 0x10040000 GIC1. (EB) */ /* 0x10050000 GIC2. (EB) */ /* 0x10060000 GIC3. (EB) */ /* 0x10070000 GIC4. (EB) */ /* 0x10080000 SMC. */ /* 0x1e000000 GIC1. (PB) */ /* 0x1e001000 GIC2. (PB) */ /* 0x1e002000 GIC3. (PB) */ /* 0x1e003000 GIC4. (PB) */ /* 0x40000000 NOR flash. */ /* 0x44000000 DoC flash. */ /* 0x48000000 SRAM. */ /* 0x4c000000 Configuration flash. */ /* 0x4e000000 Ethernet. */ /* 0x4f000000 USB. */ /* 0x50000000 PISMO. */ /* 0x54000000 PISMO. */ /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ /* 0x60000000 PCI Self Config. */ /* 0x61000000 PCI Config. */ /* 0x62000000 PCI IO. */ /* 0x63000000 PCI mem 0. */ /* 0x64000000 PCI mem 1. */ /* 0x68000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ memory_region_init_ram(ram_hack, NULL, "realview.hack", 0x1000, &error_abort); vmstate_register_ram_global(ram_hack); memory_region_add_subregion(sysmem, SMP_BOOT_ADDR, ram_hack); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = machine->kernel_filename; realview_binfo.kernel_cmdline = machine->kernel_cmdline; realview_binfo.initrd_filename = machine->initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); arm_load_kernel(ARM_CPU(first_cpu), &realview_binfo); }


static void gen_tlbie(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else if (unlikely(ctx->pr || !ctx->hv)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } if (NARROW_MODE(ctx)) { TCGv t0 = tcg_temp_new(); tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]); gen_helper_tlbie(cpu_env, t0); tcg_temp_free(t0); } else { gen_helper_tlbie(cpu_env, cpu_gpr[rB(ctx->opcode)]); } #endif }


static int flashsv_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int buf_size = avpkt->size; FlashSVContext *s = avctx->priv_data; int h_blocks, v_blocks, h_part, v_part, i, j; GetBitContext gb; /* no supplementary picture */ if (buf_size == 0) return 0; if (buf_size < 4) return -1; init_get_bits(&gb, avpkt->data, buf_size * 8); /* start to parse the bitstream */ s->block_width = 16 * (get_bits(&gb, 4) + 1); s->image_width = get_bits(&gb, 12); s->block_height = 16 * (get_bits(&gb, 4) + 1); s->image_height = get_bits(&gb, 12); if (s->ver == 2) { skip_bits(&gb, 6); if (get_bits1(&gb)) { av_log_missing_feature(avctx, "iframe", 1); return AVERROR_PATCHWELCOME; } if (get_bits1(&gb)) { av_log_missing_feature(avctx, "Custom palette", 1); return AVERROR_PATCHWELCOME; } } /* calculate number of blocks and size of border (partial) blocks */ h_blocks = s->image_width / s->block_width; h_part = s->image_width % s->block_width; v_blocks = s->image_height / s->block_height; v_part = s->image_height % s->block_height; /* the block size could change between frames, make sure the buffer * is large enough, if not, get a larger one */ if (s->block_size < s->block_width * s->block_height) { int tmpblock_size = 3 * s->block_width * s->block_height; s->tmpblock = av_realloc(s->tmpblock, tmpblock_size); if (!s->tmpblock) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); return AVERROR(ENOMEM); } if (s->ver == 2) { s->deflate_block_size = calc_deflate_block_size(tmpblock_size); if (s->deflate_block_size <= 0) { av_log(avctx, AV_LOG_ERROR, "Can't determine deflate buffer size.\n"); return -1; } s->deflate_block = av_realloc(s->deflate_block, s->deflate_block_size); if (!s->deflate_block) { av_log(avctx, AV_LOG_ERROR, "Can't allocate deflate buffer.\n"); return AVERROR(ENOMEM); } } } s->block_size = s->block_width * s->block_height; /* initialize the image size once */ if (avctx->width == 0 && avctx->height == 0) { avcodec_set_dimensions(avctx, s->image_width, s->image_height); } /* check for changes of image width and image height */ if (avctx->width != s->image_width || avctx->height != s->image_height) { av_log(avctx, AV_LOG_ERROR, "Frame width or height differs from first frame!\n"); av_log(avctx, AV_LOG_ERROR, "fh = %d, fv %d vs ch = %d, cv = %d\n", avctx->height, avctx->width, s->image_height, s->image_width); return AVERROR_INVALIDDATA; } /* we care for keyframes only in Screen Video v2 */ s->is_keyframe = (avpkt->flags & AV_PKT_FLAG_KEY) && (s->ver == 2); if (s->is_keyframe) { s->keyframedata = av_realloc(s->keyframedata, avpkt->size); memcpy(s->keyframedata, avpkt->data, avpkt->size); } if(s->ver == 2) s->blocks = av_realloc(s->blocks, (v_blocks + !!v_part) * (h_blocks + !!h_part) * sizeof(s->blocks[0])); av_dlog(avctx, "image: %dx%d block: %dx%d num: %dx%d part: %dx%d\n", s->image_width, s->image_height, s->block_width, s->block_height, h_blocks, v_blocks, h_part, v_part); s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; if (avctx->reget_buffer(avctx, &s->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } /* loop over all block columns */ for (j = 0; j < v_blocks + (v_part ? 1 : 0); j++) { int y_pos = j * s->block_height; // vertical position in frame int cur_blk_height = (j < v_blocks) ? s->block_height : v_part; /* loop over all block rows */ for (i = 0; i < h_blocks + (h_part ? 1 : 0); i++) { int x_pos = i * s->block_width; // horizontal position in frame int cur_blk_width = (i < h_blocks) ? s->block_width : h_part; int has_diff = 0; /* get the size of the compressed zlib chunk */ int size = get_bits(&gb, 16); s->color_depth = 0; s->zlibprime_curr = 0; s->zlibprime_prev = 0; s->diff_start = 0; s->diff_height = cur_blk_height; if (8 * size > get_bits_left(&gb)) { avctx->release_buffer(avctx, &s->frame); s->frame.data[0] = NULL; return AVERROR_INVALIDDATA; } if (s->ver == 2 && size) { skip_bits(&gb, 3); s->color_depth = get_bits(&gb, 2); has_diff = get_bits1(&gb); s->zlibprime_curr = get_bits1(&gb); s->zlibprime_prev = get_bits1(&gb); if (s->color_depth != 0 && s->color_depth != 2) { av_log(avctx, AV_LOG_ERROR, "%dx%d invalid color depth %d\n", i, j, s->color_depth); return AVERROR_INVALIDDATA; } if (has_diff) { if (!s->keyframe) { av_log(avctx, AV_LOG_ERROR, "inter frame without keyframe\n"); return AVERROR_INVALIDDATA; } s->diff_start = get_bits(&gb, 8); s->diff_height = get_bits(&gb, 8); av_log(avctx, AV_LOG_DEBUG, "%dx%d diff start %d height %d\n", i, j, s->diff_start, s->diff_height); size -= 2; } if (s->zlibprime_prev) av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_prev\n", i, j); if (s->zlibprime_curr) { int col = get_bits(&gb, 8); int row = get_bits(&gb, 8); av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row); size -= 2; av_log_missing_feature(avctx, "zlibprime_curr", 1); return AVERROR_PATCHWELCOME; } if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) { av_log(avctx, AV_LOG_ERROR, "no data available for zlib " "priming\n"); return AVERROR_INVALIDDATA; } size--; // account for flags byte } if (has_diff) { int k; int off = (s->image_height - y_pos - 1) * s->frame.linesize[0]; for (k = 0; k < cur_blk_height; k++) memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3, s->keyframe + off - k*s->frame.linesize[0] + x_pos*3, cur_blk_width * 3); } /* skip unchanged blocks, which have size 0 */ if (size) { if (flashsv_decode_block(avctx, avpkt, &gb, size, cur_blk_width, cur_blk_height, x_pos, y_pos, i + j * (h_blocks + !!h_part))) av_log(avctx, AV_LOG_ERROR, "error in decompression of block %dx%d\n", i, j); } } } if (s->is_keyframe && s->ver == 2) { if (!s->keyframe) { s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height); if (!s->keyframe) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n"); return AVERROR(ENOMEM); } } memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height); } *got_frame = 1; *(AVFrame*)data = s->frame; if ((get_bits_count(&gb) / 8) != buf_size) av_log(avctx, AV_LOG_ERROR, "buffer not fully consumed (%d != %d)\n", buf_size, (get_bits_count(&gb) / 8)); /* report that the buffer was completely consumed */ return buf_size; }


static void decode_subband(DiracContext *s, GetBitContext *gb, int quant, int slice_x, int slice_y, int bits_end, SubBand *b1, SubBand *b2) { int left = b1->width * slice_x / s->num_x; int right = b1->width *(slice_x+1) / s->num_x; int top = b1->height * slice_y / s->num_y; int bottom = b1->height *(slice_y+1) / s->num_y; int qfactor, qoffset; uint8_t *buf1 = b1->ibuf + top * b1->stride; uint8_t *buf2 = b2 ? b2->ibuf + top * b2->stride: NULL; int x, y; if (quant > 115) { av_log(s->avctx, AV_LOG_ERROR, "Unsupported quant %d\n", quant); return; } qfactor = ff_dirac_qscale_tab[quant & 0x7f]; qoffset = ff_dirac_qoffset_intra_tab[quant & 0x7f] + 2; /* we have to constantly check for overread since the spec explicitly requires this, with the meaning that all remaining coeffs are set to 0 */ if (get_bits_count(gb) >= bits_end) return; if (s->pshift) { for (y = top; y < bottom; y++) { for (x = left; x < right; x++) { PARSE_VALUES(int32_t, x, gb, bits_end, buf1, buf2); } buf1 += b1->stride; if (buf2) buf2 += b2->stride; } } else { for (y = top; y < bottom; y++) { for (x = left; x < right; x++) { PARSE_VALUES(int16_t, x, gb, bits_end, buf1, buf2); } buf1 += b1->stride; if (buf2) buf2 += b2->stride; } } }


void qga_vss_fsfreeze(int *nr_volume, Error **errp, bool freeze) { const char *func_name = freeze ? "requester_freeze" : "requester_thaw"; QGAVSSRequesterFunc func; ErrorSet errset = { .error_setg_win32 = error_setg_win32, .errp = errp, }; g_assert(errp); /* requester.cpp requires it */ func = (QGAVSSRequesterFunc)GetProcAddress(provider_lib, func_name); if (!func) { error_setg_win32(errp, GetLastError(), "failed to load %s from %s", func_name, QGA_VSS_DLL); return; } func(nr_volume, &errset); }


static void do_change_block(const char *device, const char *filename) { BlockDriverState *bs; bs = bdrv_find(device); if (!bs) { term_printf("device not found\n"); return; } if (eject_device(bs, 0) < 0) return; bdrv_open(bs, filename, 0); qemu_key_check(bs, filename); }


static int decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int log2w, int log2h, int stride) { const int index = size2index[log2h][log2w]; const int h = 1 << log2h; int code = get_vlc2(&f->gb, block_type_vlc[1 - (f->version > 1)][index].table, BLOCK_TYPE_VLC_BITS, 1); uint16_t *start = (uint16_t *)f->last_picture->data[0]; uint16_t *end = start + stride * (f->avctx->height - h + 1) - (1 << log2w); int ret; if (code < 0 || code > 6 || log2w < 0) return AVERROR_INVALIDDATA; if (code == 0) { src += f->mv[bytestream2_get_byte(&f->g)]; if (start > src || src > end) { av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 1, 0); } else if (code == 1) { log2h--; if ((ret = decode_p_block(f, dst, src, log2w, log2h, stride)) < 0) return ret; if ((ret = decode_p_block(f, dst + (stride << log2h), src + (stride << log2h), log2w, log2h, stride)) < 0) return ret; } else if (code == 2) { log2w--; if ((ret = decode_p_block(f, dst , src, log2w, log2h, stride)) < 0) return ret; if ((ret = decode_p_block(f, dst + (1 << log2w), src + (1 << log2w), log2w, log2h, stride)) < 0) return ret; } else if (code == 3 && f->version < 2) { if (start > src || src > end) { av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 1, 0); } else if (code == 4) { src += f->mv[bytestream2_get_byte(&f->g)]; if (start > src || src > end) { av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 1, bytestream2_get_le16(&f->g2)); } else if (code == 5) { if (start > src || src > end) { av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); return AVERROR_INVALIDDATA; } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2)); } else if (code == 6) { if (log2w) { dst[0] = bytestream2_get_le16(&f->g2); dst[1] = bytestream2_get_le16(&f->g2); } else { dst[0] = bytestream2_get_le16(&f->g2); dst[stride] = bytestream2_get_le16(&f->g2); } } return 0; }


static NFSServer *nfs_config(QDict *options, Error **errp) { NFSServer *server = NULL; QDict *addr = NULL; QObject *crumpled_addr = NULL; Visitor *iv = NULL; Error *local_error = NULL; qdict_extract_subqdict(options, &addr, "server."); if (!qdict_size(addr)) { error_setg(errp, "NFS server address missing"); goto out; } crumpled_addr = qdict_crumple(addr, errp); if (!crumpled_addr) { goto out; } iv = qobject_input_visitor_new(crumpled_addr); visit_type_NFSServer(iv, NULL, &server, &local_error); if (local_error) { error_propagate(errp, local_error); goto out; } out: QDECREF(addr); qobject_decref(crumpled_addr); visit_free(iv); return server; }


static void gen_rfmci(DisasContext *ctx) { #if defined(CONFIG_USER_ONLY) gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); #else if (unlikely(ctx->pr)) { gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC); return; } /* Restore CPU state */ gen_helper_rfmci(cpu_env); gen_sync_exception(ctx); #endif }


static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void *dst, const int type) { int i, j, count = 0; int last, t; int A, S, T; int pos = s->pos; uint32_t crc = s->sc.crc; uint32_t crc_extra_bits = s->extra_sc.crc; int16_t *dst16 = dst; int32_t *dst32 = dst; float *dstfl = dst; const int channel_stride = s->avctx->channels; if(s->samples_left == s->samples) s->one = s->zero = s->zeroes = 0; do{ T = wv_get_value(s, gb, 0, &last); S = 0; if(last) break; for(i = 0; i < s->terms; i++){ t = s->decorr[i].value; if(t > 8){ if(t & 1) A = 2 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]; else A = (3 * s->decorr[i].samplesA[0] - s->decorr[i].samplesA[1]) >> 1; s->decorr[i].samplesA[1] = s->decorr[i].samplesA[0]; j = 0; }else{ A = s->decorr[i].samplesA[pos]; j = (pos + t) & 7; } if(type != AV_SAMPLE_FMT_S16) S = T + ((s->decorr[i].weightA * (int64_t)A + 512) >> 10); else S = T + ((s->decorr[i].weightA * A + 512) >> 10); if(A && T) s->decorr[i].weightA -= ((((T ^ A) >> 30) & 2) - 1) * s->decorr[i].delta; s->decorr[i].samplesA[j] = T = S; } pos = (pos + 1) & 7; crc = crc * 3 + S; if(type == AV_SAMPLE_FMT_FLT){ *dstfl = wv_get_value_float(s, &crc_extra_bits, S); dstfl += channel_stride; }else if(type == AV_SAMPLE_FMT_S32){ *dst32 = wv_get_value_integer(s, &crc_extra_bits, S); dst32 += channel_stride; }else{ *dst16 = wv_get_value_integer(s, &crc_extra_bits, S); dst16 += channel_stride; } count++; }while(!last && count < s->max_samples); s->samples_left -= count; if(!s->samples_left){ wv_reset_saved_context(s); if(crc != s->CRC){ av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); return -1; } if(s->got_extra_bits && crc_extra_bits != s->crc_extra_bits){ av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n"); return -1; } }else{ s->pos = pos; s->sc.crc = crc; s->sc.bits_used = get_bits_count(&s->gb); if(s->got_extra_bits){ s->extra_sc.crc = crc_extra_bits; s->extra_sc.bits_used = get_bits_count(&s->gb_extra_bits); } } return count; }


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


static uint64_t block_save_pending(QEMUFile *f, void *opaque, uint64_t max_size) { /* Estimate pending number of bytes to send */ uint64_t pending; qemu_mutex_lock_iothread(); blk_mig_lock(); pending = get_remaining_dirty() + block_mig_state.submitted * BLOCK_SIZE + block_mig_state.read_done * BLOCK_SIZE; /* Report at least one block pending during bulk phase */ if (pending == 0 && !block_mig_state.bulk_completed) { pending = BLOCK_SIZE; } blk_mig_unlock(); qemu_mutex_unlock_iothread(); DPRINTF("Enter save live pending %" PRIu64 "\n", pending); return pending; }


PPC_OP(cmpli) { if (T0 < PARAM(1)) { T0 = 0x08; } else if (T0 > PARAM(1)) { T0 = 0x04; } else { T0 = 0x02; } RETURN(); }


static void FUNC(hevc_loop_filter_luma)(uint8_t *_pix, ptrdiff_t _xstride, ptrdiff_t _ystride, int *_beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q) { int d, j; pixel *pix = (pixel *)_pix; ptrdiff_t xstride = _xstride / sizeof(pixel); ptrdiff_t ystride = _ystride / sizeof(pixel); for (j = 0; j < 2; j++) { const int dp0 = abs(P2 - 2 * P1 + P0); const int dq0 = abs(Q2 - 2 * Q1 + Q0); const int dp3 = abs(TP2 - 2 * TP1 + TP0); const int dq3 = abs(TQ2 - 2 * TQ1 + TQ0); const int d0 = dp0 + dq0; const int d3 = dp3 + dq3; const int beta = _beta[j] << (BIT_DEPTH - 8); const int tc = _tc[j] << (BIT_DEPTH - 8); const int no_p = _no_p[j]; const int no_q = _no_q[j]; if (d0 + d3 >= beta) { pix += 4 * ystride; continue; } else { const int beta_3 = beta >> 3; const int beta_2 = beta >> 2; const int tc25 = ((tc * 5 + 1) >> 1); if (abs(P3 - P0) + abs(Q3 - Q0) < beta_3 && abs(P0 - Q0) < tc25 && abs(TP3 - TP0) + abs(TQ3 - TQ0) < beta_3 && abs(TP0 - TQ0) < tc25 && (d0 << 1) < beta_2 && (d3 << 1) < beta_2) { // strong filtering const int tc2 = tc << 1; for (d = 0; d < 4; d++) { const int p3 = P3; const int p2 = P2; const int p1 = P1; const int p0 = P0; const int q0 = Q0; const int q1 = Q1; const int q2 = Q2; const int q3 = Q3; if (!no_p) { P0 = p0 + av_clip(((p2 + 2 * p1 + 2 * p0 + 2 * q0 + q1 + 4) >> 3) - p0, -tc2, tc2); P1 = p1 + av_clip(((p2 + p1 + p0 + q0 + 2) >> 2) - p1, -tc2, tc2); P2 = p2 + av_clip(((2 * p3 + 3 * p2 + p1 + p0 + q0 + 4) >> 3) - p2, -tc2, tc2); } if (!no_q) { Q0 = q0 + av_clip(((p1 + 2 * p0 + 2 * q0 + 2 * q1 + q2 + 4) >> 3) - q0, -tc2, tc2); Q1 = q1 + av_clip(((p0 + q0 + q1 + q2 + 2) >> 2) - q1, -tc2, tc2); Q2 = q2 + av_clip(((2 * q3 + 3 * q2 + q1 + q0 + p0 + 4) >> 3) - q2, -tc2, tc2); } pix += ystride; } } else { // normal filtering int nd_p = 1; int nd_q = 1; const int tc_2 = tc >> 1; if (dp0 + dp3 < ((beta + (beta >> 1)) >> 3)) nd_p = 2; if (dq0 + dq3 < ((beta + (beta >> 1)) >> 3)) nd_q = 2; for (d = 0; d < 4; d++) { const int p2 = P2; const int p1 = P1; const int p0 = P0; const int q0 = Q0; const int q1 = Q1; const int q2 = Q2; int delta0 = (9 * (q0 - p0) - 3 * (q1 - p1) + 8) >> 4; if (abs(delta0) < 10 * tc) { delta0 = av_clip(delta0, -tc, tc); if (!no_p) P0 = av_clip_pixel(p0 + delta0); if (!no_q) Q0 = av_clip_pixel(q0 - delta0); if (!no_p && nd_p > 1) { const int deltap1 = av_clip((((p2 + p0 + 1) >> 1) - p1 + delta0) >> 1, -tc_2, tc_2); P1 = av_clip_pixel(p1 + deltap1); } if (!no_q && nd_q > 1) { const int deltaq1 = av_clip((((q2 + q0 + 1) >> 1) - q1 - delta0) >> 1, -tc_2, tc_2); Q1 = av_clip_pixel(q1 + deltaq1); } } pix += ystride; } } } } }


bool qdict_get_try_bool(const QDict *qdict, const char *key, bool def_value) { QObject *obj; obj = qdict_get(qdict, key); if (!obj || qobject_type(obj) != QTYPE_QBOOL) return def_value; return qbool_get_bool(qobject_to_qbool(obj)); }


static void qemu_rdma_dump_id(const char *who, struct ibv_context *verbs) { struct ibv_port_attr port; if (ibv_query_port(verbs, 1, &port)) { fprintf(stderr, "FAILED TO QUERY PORT INFORMATION!\n"); return; } printf("%s RDMA Device opened: kernel name %s " "uverbs device name %s, " "infiniband_verbs class device path %s, " "infiniband class device path %s, " "transport: (%d) %s\n", who, verbs->device->name, verbs->device->dev_name, verbs->device->dev_path, verbs->device->ibdev_path, port.link_layer, (port.link_layer == IBV_LINK_LAYER_INFINIBAND) ? "Infiniband" : ((port.link_layer == IBV_LINK_LAYER_ETHERNET) ? "Ethernet" : "Unknown")); }


static inline void RENAME(rgb24to16)(const uint8_t *src, uint8_t *dst, long src_size) { const uint8_t *s = src; const uint8_t *end; #ifdef HAVE_MMX const uint8_t *mm_end; #endif uint16_t *d = (uint16_t *)dst; end = s + src_size; #ifdef HAVE_MMX __asm __volatile(PREFETCH" %0"::"m"(*src):"memory"); __asm __volatile( "movq %0, %%mm7\n\t" "movq %1, %%mm6\n\t" ::"m"(red_16mask),"m"(green_16mask)); mm_end = end - 11; while(s < mm_end) { __asm __volatile( PREFETCH" 32%1\n\t" "movd %1, %%mm0\n\t" "movd 3%1, %%mm3\n\t" "punpckldq 6%1, %%mm0\n\t" "punpckldq 9%1, %%mm3\n\t" "movq %%mm0, %%mm1\n\t" "movq %%mm0, %%mm2\n\t" "movq %%mm3, %%mm4\n\t" "movq %%mm3, %%mm5\n\t" "psrlq $3, %%mm0\n\t" "psrlq $3, %%mm3\n\t" "pand %2, %%mm0\n\t" "pand %2, %%mm3\n\t" "psrlq $5, %%mm1\n\t" "psrlq $5, %%mm4\n\t" "pand %%mm6, %%mm1\n\t" "pand %%mm6, %%mm4\n\t" "psrlq $8, %%mm2\n\t" "psrlq $8, %%mm5\n\t" "pand %%mm7, %%mm2\n\t" "pand %%mm7, %%mm5\n\t" "por %%mm1, %%mm0\n\t" "por %%mm4, %%mm3\n\t" "por %%mm2, %%mm0\n\t" "por %%mm5, %%mm3\n\t" "psllq $16, %%mm3\n\t" "por %%mm3, %%mm0\n\t" MOVNTQ" %%mm0, %0\n\t" :"=m"(*d):"m"(*s),"m"(blue_16mask):"memory"); d += 4; s += 12; } __asm __volatile(SFENCE:::"memory"); __asm __volatile(EMMS:::"memory"); #endif while(s < end) { const int b= *s++; const int g= *s++; const int r= *s++; *d++ = (b>>3) | ((g&0xFC)<<3) | ((r&0xF8)<<8); } }


static int mp3_read_probe(AVProbeData *p) { int max_frames, first_frames = 0; int fsize, frames, sample_rate; uint32_t header; uint8_t *buf, *buf2, *end; AVCodecContext avctx; if(id3v2_match(p->buf)) return AVPROBE_SCORE_MAX/2+1; // this must be less than mpeg-ps because some retards put id3v2 tags before mpeg-ps files max_frames = 0; buf = p->buf; end = buf + p->buf_size - sizeof(uint32_t); for(; buf < end; buf= buf2+1) { buf2 = buf; for(frames = 0; buf2 < end; frames++) { header = AV_RB32(buf2); fsize = ff_mpa_decode_header(&avctx, header, &sample_rate); if(fsize < 0) break; buf2 += fsize; } max_frames = FFMAX(max_frames, frames); if(buf == p->buf) first_frames= frames; } if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; else if(max_frames>500)return AVPROBE_SCORE_MAX/2; else if(max_frames>=3) return AVPROBE_SCORE_MAX/4; else if(max_frames>=1) return 1; else return 0; }


static int ljpeg_encode_yuv(AVCodecContext *avctx, PutBitContext *pb, const AVFrame *frame) { const int predictor = avctx->prediction_method + 1; LJpegEncContext *s = avctx->priv_data; const int mb_width = (avctx->width + s->hsample[0] - 1) / s->hsample[0]; const int mb_height = (avctx->height + s->vsample[0] - 1) / s->vsample[0]; int mb_x, mb_y; for (mb_y = 0; mb_y < mb_height; mb_y++) { if (pb->buf_end - pb->buf - (put_bits_count(pb) >> 3) < mb_width * 4 * 3 * s->hsample[0] * s->vsample[0]) { av_log(avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } for (mb_x = 0; mb_x < mb_width; mb_x++) ljpeg_encode_yuv_mb(s, pb, frame, predictor, mb_x, mb_y); } return 0; }


static CharDriverState *qmp_chardev_open_serial(ChardevHostdev *serial, Error **errp) { #ifdef HAVE_CHARDEV_TTY int fd; fd = qmp_chardev_open_file_source(serial->device, O_RDWR, errp); if (error_is_set(errp)) { return NULL; } qemu_set_nonblock(fd); return qemu_chr_open_tty_fd(fd); #else error_setg(errp, "character device backend type 'serial' not supported"); return NULL; #endif }


static void gen_mul(DisasContext *dc, TCGv dest, TCGv srca, TCGv srcb) { TCGv sr_ov = tcg_temp_new(); TCGv t0 = tcg_temp_new(); tcg_gen_muls2_tl(dest, sr_ov, srca, srcb); tcg_gen_sari_tl(t0, dest, TARGET_LONG_BITS - 1); tcg_gen_setcond_tl(TCG_COND_NE, sr_ov, sr_ov, t0); tcg_temp_free(t0); tcg_gen_deposit_tl(cpu_sr, cpu_sr, sr_ov, ctz32(SR_OV), 1); gen_ove_ov(dc, sr_ov); tcg_temp_free(sr_ov); }


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


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


void ide_flush_cache(IDEState *s) { if (s->bs == NULL) { ide_flush_cb(s, 0); return; } bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH); bdrv_aio_flush(s->bs, ide_flush_cb, s); }


static void spapr_phb_hot_unplug_child(HotplugHandler *plug_handler, DeviceState *plugged_dev, Error **errp) { sPAPRPHBState *phb = SPAPR_PCI_HOST_BRIDGE(DEVICE(plug_handler)); PCIDevice *pdev = PCI_DEVICE(plugged_dev); sPAPRDRConnectorClass *drck; sPAPRDRConnector *drc = spapr_phb_get_pci_drc(phb, pdev); Error *local_err = NULL; if (!phb->dr_enabled) { error_setg(errp, QERR_BUS_NO_HOTPLUG, object_get_typename(OBJECT(phb))); return; } g_assert(drc); drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); if (!drck->release_pending(drc)) { spapr_phb_remove_pci_device(drc, phb, pdev, &local_err); if (local_err) { error_propagate(errp, local_err); return; } spapr_hotplug_req_remove_by_index(drc); } }


int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix) { if (bs->drv->bdrv_check == NULL) { return -ENOTSUP; memset(res, 0, sizeof(*res)); return bs->drv->bdrv_check(bs, res, fix);


static void map_linear_vram(CirrusVGAState *s) { if (!s->map_addr && s->lfb_addr && s->lfb_end) { s->map_addr = s->lfb_addr; s->map_end = s->lfb_end; cpu_register_physical_memory(s->map_addr, s->map_end - s->map_addr, s->vram_offset); } if (!s->map_addr) return; s->lfb_vram_mapped = 0; if (!(s->cirrus_srcptr != s->cirrus_srcptr_end) && !((s->sr[0x07] & 0x01) == 0) && !((s->gr[0x0B] & 0x14) == 0x14) && !(s->gr[0x0B] & 0x02)) { (s->vram_offset + s->cirrus_bank_base[0]) | IO_MEM_RAM); (s->vram_offset + s->cirrus_bank_base[1]) | IO_MEM_RAM); s->lfb_vram_mapped = 1; } else { cpu_register_physical_memory(isa_mem_base + 0xa0000, 0x20000, s->vga_io_memory); } vga_dirty_log_start((VGAState *)s); }


static int alloc_tables(H264Context *h){ MpegEncContext * const s = &h->s; const int big_mb_num= s->mb_stride * (s->mb_height+1); int x,y; CHECKED_ALLOCZ(h->intra4x4_pred_mode, big_mb_num * 8 * sizeof(uint8_t)) CHECKED_ALLOCZ(h->non_zero_count , big_mb_num * 16 * sizeof(uint8_t)) CHECKED_ALLOCZ(h->slice_table_base , (big_mb_num+s->mb_stride) * sizeof(uint8_t)) CHECKED_ALLOCZ(h->cbp_table, big_mb_num * sizeof(uint16_t)) if( h->pps.cabac ) { CHECKED_ALLOCZ(h->chroma_pred_mode_table, big_mb_num * sizeof(uint8_t)) CHECKED_ALLOCZ(h->mvd_table[0], 32*big_mb_num * sizeof(uint16_t)); CHECKED_ALLOCZ(h->mvd_table[1], 32*big_mb_num * sizeof(uint16_t)); CHECKED_ALLOCZ(h->direct_table, 32*big_mb_num * sizeof(uint8_t)); } memset(h->slice_table_base, -1, (big_mb_num+s->mb_stride) * sizeof(uint8_t)); h->slice_table= h->slice_table_base + s->mb_stride*2 + 1; CHECKED_ALLOCZ(h->mb2b_xy , big_mb_num * sizeof(uint32_t)); CHECKED_ALLOCZ(h->mb2b8_xy , big_mb_num * sizeof(uint32_t)); for(y=0; y<s->mb_height; y++){ for(x=0; x<s->mb_width; x++){ const int mb_xy= x + y*s->mb_stride; const int b_xy = 4*x + 4*y*h->b_stride; const int b8_xy= 2*x + 2*y*h->b8_stride; h->mb2b_xy [mb_xy]= b_xy; h->mb2b8_xy[mb_xy]= b8_xy; } } s->obmc_scratchpad = NULL; if(!h->dequant4_coeff[0]) init_dequant_tables(h); return 0; fail: free_tables(h); return -1; }


static void RENAME(swScale)(SwsContext *c, uint8_t* srcParam[], int srcStrideParam[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStrideParam[]){ /* load a few things into local vars to make the code more readable? and faster */ const int srcW= c->srcW; const int dstW= c->dstW; const int dstH= c->dstH; const int chrDstW= c->chrDstW; const int lumXInc= c->lumXInc; const int chrXInc= c->chrXInc; const int dstFormat= c->dstFormat; const int flags= c->flags; const int canMMX2BeUsed= c->canMMX2BeUsed; int16_t *vLumFilterPos= c->vLumFilterPos; int16_t *vChrFilterPos= c->vChrFilterPos; int16_t *hLumFilterPos= c->hLumFilterPos; int16_t *hChrFilterPos= c->hChrFilterPos; int16_t *vLumFilter= c->vLumFilter; int16_t *vChrFilter= c->vChrFilter; int16_t *hLumFilter= c->hLumFilter; int16_t *hChrFilter= c->hChrFilter; int16_t *lumMmxFilter= c->lumMmxFilter; int16_t *chrMmxFilter= c->chrMmxFilter; const int vLumFilterSize= c->vLumFilterSize; const int vChrFilterSize= c->vChrFilterSize; const int hLumFilterSize= c->hLumFilterSize; const int hChrFilterSize= c->hChrFilterSize; int16_t **lumPixBuf= c->lumPixBuf; int16_t **chrPixBuf= c->chrPixBuf; const int vLumBufSize= c->vLumBufSize; const int vChrBufSize= c->vChrBufSize; uint8_t *funnyYCode= c->funnyYCode; uint8_t *funnyUVCode= c->funnyUVCode; uint8_t *formatConvBuffer= c->formatConvBuffer; /* vars whch will change and which we need to storw back in the context */ int dstY= c->dstY; int lumBufIndex= c->lumBufIndex; int chrBufIndex= c->chrBufIndex; int lastInLumBuf= c->lastInLumBuf; int lastInChrBuf= c->lastInChrBuf; int srcStride[3]; int dstStride[3]; uint8_t *src[3]; uint8_t *dst[3]; if(c->srcFormat == IMGFMT_I420){ src[0]= srcParam[0]; src[1]= srcParam[2]; src[2]= srcParam[1]; srcStride[0]= srcStrideParam[0]; srcStride[1]= srcStrideParam[2]; srcStride[2]= srcStrideParam[1]; } else if(c->srcFormat==IMGFMT_YV12){ src[0]= srcParam[0]; src[1]= srcParam[1]; src[2]= srcParam[2]; srcStride[0]= srcStrideParam[0]; srcStride[1]= srcStrideParam[1]; srcStride[2]= srcStrideParam[2]; } else if(isPacked(c->srcFormat)){ src[0]= src[1]= src[2]= srcParam[0]; srcStride[0]= srcStrideParam[0]; srcStride[1]= srcStride[2]= srcStrideParam[0]<<1; } else if(isGray(c->srcFormat)){ src[0]= srcParam[0]; src[1]= src[2]= NULL; srcStride[0]= srcStrideParam[0]; srcStride[1]= srcStride[2]= 0; } if(dstFormat == IMGFMT_I420){ dst[0]= dstParam[0]; dst[1]= dstParam[2]; dst[2]= dstParam[1]; dstStride[0]= dstStrideParam[0]; dstStride[1]= dstStrideParam[2]; dstStride[2]= dstStrideParam[1]; }else{ dst[0]= dstParam[0]; dst[1]= dstParam[1]; dst[2]= dstParam[2]; dstStride[0]= dstStrideParam[0]; dstStride[1]= dstStrideParam[1]; dstStride[2]= dstStrideParam[2]; } //printf("sws Strides:%d %d %d -> %d %d %d\n", srcStride[0],srcStride[1],srcStride[2], //dstStride[0],dstStride[1],dstStride[2]); if(dstStride[0]%8 !=0 || dstStride[1]%8 !=0 || dstStride[2]%8 !=0) { static int firstTime=1; //FIXME move this into the context perhaps if(flags & SWS_PRINT_INFO && firstTime) { fprintf(stderr, "SwScaler: Warning: dstStride is not aligned!\n" "SwScaler: ->cannot do aligned memory acesses anymore\n"); firstTime=0; } } /* Note the user might start scaling the picture in the middle so this will not get executed this is not really intended but works currently, so ppl might do it */ if(srcSliceY ==0){ lumBufIndex=0; chrBufIndex=0; dstY=0; lastInLumBuf= -1; lastInChrBuf= -1; } for(;dstY < dstH; dstY++){ unsigned char *dest =dst[0]+dstStride[0]*dstY; unsigned char *uDest=dst[1]+dstStride[1]*(dstY>>1); unsigned char *vDest=dst[2]+dstStride[2]*(dstY>>1); const int chrDstY= isHalfChrV(dstFormat) ? (dstY>>1) : dstY; const int firstLumSrcY= vLumFilterPos[dstY]; //First line needed as input const int firstChrSrcY= vChrFilterPos[chrDstY]; //First line needed as input const int lastLumSrcY= firstLumSrcY + vLumFilterSize -1; // Last line needed as input const int lastChrSrcY= firstChrSrcY + vChrFilterSize -1; // Last line needed as input //handle holes (FAST_BILINEAR & weird filters) if(firstLumSrcY > lastInLumBuf) lastInLumBuf= firstLumSrcY-1; if(firstChrSrcY > lastInChrBuf) lastInChrBuf= firstChrSrcY-1; //printf("%d %d %d\n", firstChrSrcY, lastInChrBuf, vChrBufSize); ASSERT(firstLumSrcY >= lastInLumBuf - vLumBufSize + 1) ASSERT(firstChrSrcY >= lastInChrBuf - vChrBufSize + 1) // Do we have enough lines in this slice to output the dstY line if(lastLumSrcY < srcSliceY + srcSliceH && lastChrSrcY < ((srcSliceY + srcSliceH + 1)>>1)) { //Do horizontal scaling while(lastInLumBuf < lastLumSrcY) { uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; lumBufIndex++; // printf("%d %d %d %d\n", lumBufIndex, vLumBufSize, lastInLumBuf, lastLumSrcY); ASSERT(lumBufIndex < 2*vLumBufSize) ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH) ASSERT(lastInLumBuf + 1 - srcSliceY >= 0) // printf("%d %d\n", lumBufIndex, vLumBufSize); RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc, flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize, funnyYCode, c->srcFormat, formatConvBuffer); lastInLumBuf++; } while(lastInChrBuf < lastChrSrcY) { uint8_t *src1= src[1]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[1]; uint8_t *src2= src[2]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[2]; chrBufIndex++; ASSERT(chrBufIndex < 2*vChrBufSize) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) < ((srcSliceH+1)>>1)) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) >= 0) //FIXME replace parameters through context struct (some at least) RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc, flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize, funnyUVCode, c->srcFormat, formatConvBuffer); lastInChrBuf++; } //wrap buf index around to stay inside the ring buffer if(lumBufIndex >= vLumBufSize ) lumBufIndex-= vLumBufSize; if(chrBufIndex >= vChrBufSize ) chrBufIndex-= vChrBufSize; } else // not enough lines left in this slice -> load the rest in the buffer { /* printf("%d %d Last:%d %d LastInBuf:%d %d Index:%d %d Y:%d FSize: %d %d BSize: %d %d\n", firstChrSrcY,firstLumSrcY,lastChrSrcY,lastLumSrcY, lastInChrBuf,lastInLumBuf,chrBufIndex,lumBufIndex,dstY,vChrFilterSize,vLumFilterSize, vChrBufSize, vLumBufSize); */ //Do horizontal scaling while(lastInLumBuf+1 < srcSliceY + srcSliceH) { uint8_t *s= src[0]+(lastInLumBuf + 1 - srcSliceY)*srcStride[0]; lumBufIndex++; ASSERT(lumBufIndex < 2*vLumBufSize) ASSERT(lastInLumBuf + 1 - srcSliceY < srcSliceH) ASSERT(lastInLumBuf + 1 - srcSliceY >= 0) RENAME(hyscale)(lumPixBuf[ lumBufIndex ], dstW, s, srcW, lumXInc, flags, canMMX2BeUsed, hLumFilter, hLumFilterPos, hLumFilterSize, funnyYCode, c->srcFormat, formatConvBuffer); lastInLumBuf++; } while(lastInChrBuf+1 < ((srcSliceY + srcSliceH)>>1)) { uint8_t *src1= src[1]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[1]; uint8_t *src2= src[2]+(lastInChrBuf + 1 - (srcSliceY>>1))*srcStride[2]; chrBufIndex++; ASSERT(chrBufIndex < 2*vChrBufSize) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) < ((srcSliceH+1)>>1)) ASSERT(lastInChrBuf + 1 - (srcSliceY>>1) >= 0) RENAME(hcscale)(chrPixBuf[ chrBufIndex ], chrDstW, src1, src2, (srcW+1)>>1, chrXInc, flags, canMMX2BeUsed, hChrFilter, hChrFilterPos, hChrFilterSize, funnyUVCode, c->srcFormat, formatConvBuffer); lastInChrBuf++; } //wrap buf index around to stay inside the ring buffer if(lumBufIndex >= vLumBufSize ) lumBufIndex-= vLumBufSize; if(chrBufIndex >= vChrBufSize ) chrBufIndex-= vChrBufSize; break; //we cant output a dstY line so lets try with the next slice } #ifdef HAVE_MMX b5Dither= dither8[dstY&1]; g6Dither= dither4[dstY&1]; g5Dither= dither8[dstY&1]; r5Dither= dither8[(dstY+1)&1]; #endif if(dstY < dstH-2) { if(isPlanarYUV(dstFormat)) //YV12 like { if(dstY&1) uDest=vDest= NULL; //FIXME split functions in lumi / chromi if(vLumFilterSize == 1 && vChrFilterSize == 1) // Unscaled YV12 { int16_t *lumBuf = lumPixBuf[0]; int16_t *chrBuf= chrPixBuf[0]; RENAME(yuv2yuv1)(lumBuf, chrBuf, dest, uDest, vDest, dstW); } else //General YV12 { int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; RENAME(yuv2yuvX)( vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, vChrFilter+(dstY>>1)*vChrFilterSize, chrSrcPtr, vChrFilterSize, dest, uDest, vDest, dstW, lumMmxFilter+dstY*vLumFilterSize*4, chrMmxFilter+(dstY>>1)*vChrFilterSize*4); } } else { int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); if(vLumFilterSize == 1 && vChrFilterSize == 2) //Unscaled RGB { int chrAlpha= vChrFilter[2*dstY+1]; RENAME(yuv2rgb1)(*lumSrcPtr, *chrSrcPtr, *(chrSrcPtr+1), dest, dstW, chrAlpha, dstFormat, flags); } else if(vLumFilterSize == 2 && vChrFilterSize == 2) //BiLinear Upscale RGB { int lumAlpha= vLumFilter[2*dstY+1]; int chrAlpha= vChrFilter[2*dstY+1]; RENAME(yuv2rgb2)(*lumSrcPtr, *(lumSrcPtr+1), *chrSrcPtr, *(chrSrcPtr+1), dest, dstW, lumAlpha, chrAlpha, dstFormat, flags); } else //General RGB { RENAME(yuv2rgbX)( vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, dest, dstW, dstFormat, lumMmxFilter+dstY*vLumFilterSize*4, chrMmxFilter+dstY*vChrFilterSize*4); } } } else // hmm looks like we cant use MMX here without overwriting this arrays tail { int16_t **lumSrcPtr= lumPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize; int16_t **chrSrcPtr= chrPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; if(isPlanarYUV(dstFormat)) //YV12 { if(dstY&1) uDest=vDest= NULL; //FIXME split functions in lumi / chromi yuv2yuvXinC( vLumFilter+dstY*vLumFilterSize , lumSrcPtr, vLumFilterSize, vChrFilter+(dstY>>1)*vChrFilterSize, chrSrcPtr, vChrFilterSize, dest, uDest, vDest, dstW); } else { ASSERT(lumSrcPtr + vLumFilterSize - 1 < lumPixBuf + vLumBufSize*2); ASSERT(chrSrcPtr + vChrFilterSize - 1 < chrPixBuf + vChrBufSize*2); yuv2rgbXinC( vLumFilter+dstY*vLumFilterSize, lumSrcPtr, vLumFilterSize, vChrFilter+dstY*vChrFilterSize, chrSrcPtr, vChrFilterSize, dest, dstW, dstFormat); } } } #ifdef HAVE_MMX __asm __volatile(SFENCE:::"memory"); __asm __volatile(EMMS:::"memory"); #endif /* store changed local vars back in the context */ c->dstY= dstY; c->lumBufIndex= lumBufIndex; c->chrBufIndex= chrBufIndex; c->lastInLumBuf= lastInLumBuf; c->lastInChrBuf= lastInChrBuf; }


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


static void escc_mem_write(void *opaque, hwaddr addr, uint64_t val, unsigned size) { ESCCState *serial = opaque; ChannelState *s; uint32_t saddr; int newreg, channel; val &= 0xff; saddr = (addr >> serial->it_shift) & 1; channel = (addr >> (serial->it_shift + 1)) & 1; s = &serial->chn[channel]; switch (saddr) { case SERIAL_CTRL: trace_escc_mem_writeb_ctrl(CHN_C(s), s->reg, val & 0xff); newreg = 0; switch (s->reg) { case W_CMD: newreg = val & CMD_PTR_MASK; val &= CMD_CMD_MASK; switch (val) { case CMD_HI: newreg |= CMD_HI; break; case CMD_CLR_TXINT: clr_txint(s); break; case CMD_CLR_IUS: if (s->rxint_under_svc) { s->rxint_under_svc = 0; if (s->txint) { set_txint(s); } } else if (s->txint_under_svc) { s->txint_under_svc = 0; } escc_update_irq(s); break; default: break; } break; case W_INTR ... W_RXCTRL: case W_SYNC1 ... W_TXBUF: case W_MISC1 ... W_CLOCK: case W_MISC2 ... W_EXTINT: s->wregs[s->reg] = val; break; case W_TXCTRL1: case W_TXCTRL2: s->wregs[s->reg] = val; escc_update_parameters(s); break; case W_BRGLO: case W_BRGHI: s->wregs[s->reg] = val; s->rregs[s->reg] = val; escc_update_parameters(s); break; case W_MINTR: switch (val & MINTR_RST_MASK) { case 0: default: break; case MINTR_RST_B: escc_reset_chn(&serial->chn[0]); return; case MINTR_RST_A: escc_reset_chn(&serial->chn[1]); return; case MINTR_RST_ALL: escc_reset(DEVICE(serial)); return; } break; default: break; } if (s->reg == 0) s->reg = newreg; else s->reg = 0; break; case SERIAL_DATA: trace_escc_mem_writeb_data(CHN_C(s), val); s->tx = val; if (s->wregs[W_TXCTRL2] & TXCTRL2_TXEN) { // tx enabled if (s->chr) qemu_chr_fe_write(s->chr, &s->tx, 1); else if (s->type == kbd && !s->disabled) { handle_kbd_command(s, val); } } s->rregs[R_STATUS] |= STATUS_TXEMPTY; // Tx buffer empty s->rregs[R_SPEC] |= SPEC_ALLSENT; // All sent set_txint(s); break; default: break; } }


static int vmdaudio_decode_init(AVCodecContext *avctx) { VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data; int i; s->channels = avctx->channels; s->bits = avctx->bits_per_sample; s->block_align = avctx->block_align; printf (" %d channels, %d bits/sample, block align = %d\n", s->channels, s->bits, s->block_align); /* set up the steps8 and steps16 tables */ for (i = 0; i < 8; i++) { if (i < 4) s->steps8[i] = i; else s->steps8[i] = s->steps8[i - 1] + i - 1; if (i == 0) s->steps16[i] = 0; else if (i == 1) s->steps16[i] = 4; else if (i == 2) s->steps16[i] = 16; else s->steps16[i] = 1 << (i + 4); } /* set up the step128 table */ s->steps128[0] = 0; s->steps128[1] = 8; for (i = 0x02; i <= 0x20; i++) s->steps128[i] = (i - 1) << 4; for (i = 0x21; i <= 0x60; i++) s->steps128[i] = (i + 0x1F) << 3; for (i = 0x61; i <= 0x70; i++) s->steps128[i] = (i - 0x51) << 6; for (i = 0x71; i <= 0x78; i++) s->steps128[i] = (i - 0x69) << 8; for (i = 0x79; i <= 0x7D; i++) s->steps128[i] = (i - 0x75) << 10; s->steps128[0x7E] = 0x3000; s->steps128[0x7F] = 0x4000; /* set up the negative half of each table */ for (i = 0; i < 8; i++) { s->steps8[i + 8] = -s->steps8[i]; s->steps16[i + 8] = -s->steps16[i]; } for (i = 0; i < 128; i++) s->steps128[i + 128] = -s->steps128[i]; return 0; }


static int adb_kbd_request(ADBDevice *d, uint8_t *obuf, const uint8_t *buf, int len) { KBDState *s = ADB_KEYBOARD(d); int cmd, reg, olen; if ((buf[0] & 0x0f) == ADB_FLUSH) { /* flush keyboard fifo */ s->wptr = s->rptr = s->count = 0; return 0; } cmd = buf[0] & 0xc; reg = buf[0] & 0x3; olen = 0; switch(cmd) { case ADB_WRITEREG: switch(reg) { case 2: /* LED status */ break; case 3: switch(buf[2]) { case ADB_CMD_SELF_TEST: break; case ADB_CMD_CHANGE_ID: case ADB_CMD_CHANGE_ID_AND_ACT: case ADB_CMD_CHANGE_ID_AND_ENABLE: d->devaddr = buf[1] & 0xf; break; default: d->devaddr = buf[1] & 0xf; /* we support handlers: * 1: Apple Standard Keyboard * 2: Apple Extended Keyboard (LShift = RShift) * 3: Apple Extended Keyboard (LShift != RShift) */ if (buf[2] == 1 || buf[2] == 2 || buf[2] == 3) { d->handler = buf[2]; } break; } } break; case ADB_READREG: switch(reg) { case 0: olen = adb_kbd_poll(d, obuf); break; case 1: break; case 2: obuf[0] = 0x00; /* XXX: check this */ obuf[1] = 0x07; /* led status */ olen = 2; break; case 3: obuf[0] = d->handler; obuf[1] = d->devaddr; olen = 2; break; } break; } return olen; }