static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale) { int i, j, level, last_non_zero, q; const int *qmat; int minLevel, maxLevel; if(s->avctx!=NULL && s->avctx->codec->id==CODEC_ID_MPEG4){ /* mpeg4 */ minLevel= -2048; maxLevel= 2047; }else if(s->out_format==FMT_MPEG1){ /* mpeg1 */ minLevel= -255; maxLevel= 255; }else if(s->out_format==FMT_MJPEG){ /* (m)jpeg */ minLevel= -1023; maxLevel= 1023; }else{ /* h263 / msmpeg4 */ minLevel= -128; maxLevel= 127; } av_fdct (block); /* we need this permutation so that we correct the IDCT permutation. will be moved into DCT code */ block_permute(block); if (s->mb_intra) { if (n < 4) q = s->y_dc_scale; else q = s->c_dc_scale; q = q << 3; /* note: block[0] is assumed to be positive */ block[0] = (block[0] + (q >> 1)) / q; i = 1; last_non_zero = 0; if (s->out_format == FMT_H263) { qmat = s->q_non_intra_matrix; } else { qmat = s->q_intra_matrix; } } else { i = 0; last_non_zero = -1; qmat = s->q_non_intra_matrix; } for(;i<64;i++) { j = zigzag_direct[i]; level = block[j]; level = level * qmat[j]; #ifdef PARANOID { static int count = 0; int level1, level2, qmat1; double val; if (qmat == s->q_non_intra_matrix) { qmat1 = default_non_intra_matrix[j] * s->qscale; } else { qmat1 = default_intra_matrix[j] * s->qscale; } if (av_fdct != jpeg_fdct_ifast) val = ((double)block[j] * 8.0) / (double)qmat1; else val = ((double)block[j] * 8.0 * 2048.0) / ((double)qmat1 * aanscales[j]); level1 = (int)val; level2 = level / (1 << (QMAT_SHIFT - 3)); if (level1 != level2) { fprintf(stderr, "%d: quant error qlevel=%d wanted=%d level=%d qmat1=%d qmat=%d wantedf=%0.6f\n", count, level2, level1, block[j], qmat1, qmat[j], val); count++; } } #endif /* XXX: slight error for the low range. Test should be equivalent to (level <= -(1 << (QMAT_SHIFT - 3)) || level >= (1 << (QMAT_SHIFT - 3))) */ if (((level << (31 - (QMAT_SHIFT - 3))) >> (31 - (QMAT_SHIFT - 3))) != level) { level = level / (1 << (QMAT_SHIFT - 3)); /* XXX: currently, this code is not optimal. the range should be: mpeg1: -255..255 mpeg2: -2048..2047 h263: -128..127 mpeg4: -2048..2047 */ if (level > maxLevel) level = maxLevel; else if (level < minLevel) level = minLevel; block[j] = level; last_non_zero = i; } else { block[j] = 0; } } return last_non_zero; }


static void drive_backup_abort(BlkActionState *common) { DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common); BlockDriverState *bs = state->bs; /* Only cancel if it's the job we started */ if (bs && bs->job && bs->job == state->job) { block_job_cancel_sync(bs->job); } }


static void ivshmem_check_version(void *opaque, const uint8_t * buf, int size) { IVShmemState *s = opaque; int tmp; int64_t version; if (!fifo_update_and_get_i64(s, buf, size, &version)) { return; } tmp = qemu_chr_fe_get_msgfd(s->server_chr); if (tmp != -1 || version != IVSHMEM_PROTOCOL_VERSION) { fprintf(stderr, "incompatible version, you are connecting to a ivshmem-" "server using a different protocol please check your setup\n"); qemu_chr_add_handlers(s->server_chr, NULL, NULL, NULL, s); return; } IVSHMEM_DPRINTF("version check ok, switch to real chardev handler\n"); qemu_chr_add_handlers(s->server_chr, ivshmem_can_receive, ivshmem_read, NULL, s); }


static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) { AVIOContext *pb = s->pb; char abss[24]; int hour, min, sec, i, ret, config; int dsd_layout[6]; ID3v2ExtraMeta *id3v2_extra_meta; while (avio_tell(pb) + 12 <= eof) { uint32_t tag = avio_rl32(pb); uint64_t size = avio_rb64(pb); uint64_t orig_pos = avio_tell(pb); switch(tag) { case MKTAG('A','B','S','S'): if (size < 8) return AVERROR_INVALIDDATA; hour = avio_rb16(pb); min = avio_r8(pb); sec = avio_r8(pb); snprintf(abss, sizeof(abss), "%02dh:%02dm:%02ds:%d", hour, min, sec, avio_rb32(pb)); av_dict_set(&st->metadata, "absolute_start_time", abss, 0); break; case MKTAG('C','H','N','L'): if (size < 2) return AVERROR_INVALIDDATA; st->codecpar->channels = avio_rb16(pb); if (size < 2 + st->codecpar->channels * 4) return AVERROR_INVALIDDATA; st->codecpar->channel_layout = 0; if (st->codecpar->channels > FF_ARRAY_ELEMS(dsd_layout)) { avpriv_request_sample(s, "channel layout"); break; } for (i = 0; i < st->codecpar->channels; i++) dsd_layout[i] = avio_rl32(pb); for (i = 0; i < FF_ARRAY_ELEMS(dsd_channel_layout); i++) { const DSDLayoutDesc * d = &dsd_channel_layout[i]; if (av_get_channel_layout_nb_channels(d->layout) == st->codecpar->channels && !memcmp(d->dsd_layout, dsd_layout, st->codecpar->channels * sizeof(uint32_t))) { st->codecpar->channel_layout = d->layout; break; } } break; case MKTAG('C','M','P','R'): if (size < 4) return AVERROR_INVALIDDATA; tag = avio_rl32(pb); st->codecpar->codec_id = ff_codec_get_id(dsd_codec_tags, tag); if (!st->codecpar->codec_id) { av_log(s, AV_LOG_ERROR, "'%c%c%c%c' compression is not supported\n", tag&0xFF, (tag>>8)&0xFF, (tag>>16)&0xFF, (tag>>24)&0xFF); return AVERROR_PATCHWELCOME; } break; case MKTAG('F','S',' ',' '): if (size < 4) return AVERROR_INVALIDDATA; st->codecpar->sample_rate = avio_rb32(pb) / 8; break; case MKTAG('I','D','3',' '): id3v2_extra_meta = NULL; ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); if (id3v2_extra_meta) { if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { ff_id3v2_free_extra_meta(&id3v2_extra_meta); return ret; } ff_id3v2_free_extra_meta(&id3v2_extra_meta); } if (size < avio_tell(pb) - orig_pos) { av_log(s, AV_LOG_ERROR, "id3 exceeds chunk size\n"); return AVERROR_INVALIDDATA; } break; case MKTAG('L','S','C','O'): if (size < 2) return AVERROR_INVALIDDATA; config = avio_rb16(pb); if (config != 0xFFFF) { if (config < FF_ARRAY_ELEMS(dsd_loudspeaker_config)) st->codecpar->channel_layout = dsd_loudspeaker_config[config]; if (!st->codecpar->channel_layout) avpriv_request_sample(s, "loudspeaker configuration %d", config); } break; } avio_skip(pb, size - (avio_tell(pb) - orig_pos) + (size & 1)); } return 0; }


static int tcp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, uint8_t *buf, int buf_size) { RTSPState *rt = s->priv_data; int id, len, i, ret; RTSPStream *rtsp_st; #ifdef DEBUG_RTP_TCP dprintf(s, "tcp_read_packet:\n"); #endif redo: for(;;) { RTSPMessageHeader reply; ret = rtsp_read_reply(s, &reply, NULL, 1); if (ret == -1) return -1; if (ret == 1) /* received '$' */ break; /* XXX: parse message */ if (rt->state != RTSP_STATE_PLAYING) return 0; } ret = url_read_complete(rt->rtsp_hd, buf, 3); if (ret != 3) return -1; id = buf[0]; len = AV_RB16(buf + 1); #ifdef DEBUG_RTP_TCP dprintf(s, "id=%d len=%d\n", id, len); #endif if (len > buf_size || len < 12) goto redo; /* get the data */ ret = url_read_complete(rt->rtsp_hd, buf, len); if (ret != len) return -1; if (rt->transport == RTSP_TRANSPORT_RDT && ff_rdt_parse_header(buf, len, &id, NULL, NULL, NULL, NULL) < 0) return -1; /* find the matching stream */ for(i = 0; i < rt->nb_rtsp_streams; i++) { rtsp_st = rt->rtsp_streams[i]; if (id >= rtsp_st->interleaved_min && id <= rtsp_st->interleaved_max) goto found; } goto redo; found: *prtsp_st = rtsp_st; return len; }


static int read_ts(const char *s, int64_t *start, int *duration) { int64_t end; int hh1, mm1, ss1, ms1; int hh2, mm2, ss2, ms2; if (sscanf(s, "%u:%u:%u.%u,%u:%u:%u.%u", &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) { end = (hh2*3600 + mm2*60 + ss2) * 100 + ms2; *start = (hh1*3600 + mm1*60 + ss1) * 100 + ms1; *duration = end - *start; return 0; } return -1; }


static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap) { RMContext *rm = s->priv_data; AVStream *st; rm->old_format = 1; st = av_new_stream(s, 0); if (!st) goto fail; rm_read_audio_stream_info(s, st, 1); return 0; fail: return -1; }


static void alloc_aio_bitmap(BlkMigDevState *bmds) { BlockDriverState *bs = bmds->bs; int64_t bitmap_size; bitmap_size = bdrv_nb_sectors(bs) + BDRV_SECTORS_PER_DIRTY_CHUNK * 8 - 1; bitmap_size /= BDRV_SECTORS_PER_DIRTY_CHUNK * 8; bmds->aio_bitmap = g_malloc0(bitmap_size); }


static uint8_t *xen_map_cache_unlocked(hwaddr phys_addr, hwaddr size, uint8_t lock, bool dma) { MapCacheEntry *entry, *pentry = NULL; hwaddr address_index; hwaddr address_offset; hwaddr cache_size = size; hwaddr test_bit_size; bool translated G_GNUC_UNUSED = false; bool dummy = false; tryagain: address_index = phys_addr >> MCACHE_BUCKET_SHIFT; address_offset = phys_addr & (MCACHE_BUCKET_SIZE - 1); trace_xen_map_cache(phys_addr); /* test_bit_size is always a multiple of XC_PAGE_SIZE */ if (size) { test_bit_size = size + (phys_addr & (XC_PAGE_SIZE - 1)); if (test_bit_size % XC_PAGE_SIZE) { test_bit_size += XC_PAGE_SIZE - (test_bit_size % XC_PAGE_SIZE); } } else { test_bit_size = XC_PAGE_SIZE; } if (mapcache->last_entry != NULL && mapcache->last_entry->paddr_index == address_index && !lock && !size && test_bits(address_offset >> XC_PAGE_SHIFT, test_bit_size >> XC_PAGE_SHIFT, mapcache->last_entry->valid_mapping)) { trace_xen_map_cache_return(mapcache->last_entry->vaddr_base + address_offset); return mapcache->last_entry->vaddr_base + address_offset; } /* size is always a multiple of MCACHE_BUCKET_SIZE */ if (size) { cache_size = size + address_offset; if (cache_size % MCACHE_BUCKET_SIZE) { cache_size += MCACHE_BUCKET_SIZE - (cache_size % MCACHE_BUCKET_SIZE); } } else { cache_size = MCACHE_BUCKET_SIZE; } entry = &mapcache->entry[address_index % mapcache->nr_buckets]; while (entry && entry->lock && entry->vaddr_base && (entry->paddr_index != address_index || entry->size != cache_size || !test_bits(address_offset >> XC_PAGE_SHIFT, test_bit_size >> XC_PAGE_SHIFT, entry->valid_mapping))) { pentry = entry; entry = entry->next; } if (!entry) { entry = g_malloc0(sizeof (MapCacheEntry)); pentry->next = entry; xen_remap_bucket(entry, NULL, cache_size, address_index, dummy); } else if (!entry->lock) { if (!entry->vaddr_base || entry->paddr_index != address_index || entry->size != cache_size || !test_bits(address_offset >> XC_PAGE_SHIFT, test_bit_size >> XC_PAGE_SHIFT, entry->valid_mapping)) { xen_remap_bucket(entry, NULL, cache_size, address_index, dummy); } } if(!test_bits(address_offset >> XC_PAGE_SHIFT, test_bit_size >> XC_PAGE_SHIFT, entry->valid_mapping)) { mapcache->last_entry = NULL; #ifdef XEN_COMPAT_PHYSMAP if (!translated && mapcache->phys_offset_to_gaddr) { phys_addr = mapcache->phys_offset_to_gaddr(phys_addr, size, mapcache->opaque); translated = true; goto tryagain; } #endif if (!dummy && runstate_check(RUN_STATE_INMIGRATE)) { dummy = true; goto tryagain; } trace_xen_map_cache_return(NULL); return NULL; } mapcache->last_entry = entry; if (lock) { MapCacheRev *reventry = g_malloc0(sizeof(MapCacheRev)); entry->lock++; reventry->dma = dma; reventry->vaddr_req = mapcache->last_entry->vaddr_base + address_offset; reventry->paddr_index = mapcache->last_entry->paddr_index; reventry->size = entry->size; QTAILQ_INSERT_HEAD(&mapcache->locked_entries, reventry, next); } trace_xen_map_cache_return(mapcache->last_entry->vaddr_base + address_offset); return mapcache->last_entry->vaddr_base + address_offset; }


static void disas_arm_insn(CPUARMState * env, DisasContext *s) { unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; TCGv tmp; TCGv tmp2; TCGv tmp3; TCGv addr; TCGv_i64 tmp64; insn = arm_ldl_code(env, s->pc, s->bswap_code); s->pc += 4; /* M variants do not implement ARM mode. */ if (IS_M(env)) goto illegal_op; cond = insn >> 28; if (cond == 0xf){ /* In ARMv3 and v4 the NV condition is UNPREDICTABLE; we * choose to UNDEF. In ARMv5 and above the space is used * for miscellaneous unconditional instructions. */ ARCH(5); /* Unconditional instructions. */ if (((insn >> 25) & 7) == 1) { /* NEON Data processing. */ if (!arm_feature(env, ARM_FEATURE_NEON)) goto illegal_op; if (disas_neon_data_insn(env, s, insn)) goto illegal_op; } if ((insn & 0x0f100000) == 0x04000000) { /* NEON load/store. */ if (!arm_feature(env, ARM_FEATURE_NEON)) goto illegal_op; if (disas_neon_ls_insn(env, s, insn)) goto illegal_op; } if (((insn & 0x0f30f000) == 0x0510f000) || ((insn & 0x0f30f010) == 0x0710f000)) { if ((insn & (1 << 22)) == 0) { /* PLDW; v7MP */ if (!arm_feature(env, ARM_FEATURE_V7MP)) { goto illegal_op; } } /* Otherwise PLD; v5TE+ */ ARCH(5TE); } if (((insn & 0x0f70f000) == 0x0450f000) || ((insn & 0x0f70f010) == 0x0650f000)) { ARCH(7); return; /* PLI; V7 */ } if (((insn & 0x0f700000) == 0x04100000) || ((insn & 0x0f700010) == 0x06100000)) { if (!arm_feature(env, ARM_FEATURE_V7MP)) { goto illegal_op; } return; /* v7MP: Unallocated memory hint: must NOP */ } if ((insn & 0x0ffffdff) == 0x01010000) { ARCH(6); /* setend */ if (((insn >> 9) & 1) != s->bswap_code) { /* Dynamic endianness switching not implemented. */ goto illegal_op; } } else if ((insn & 0x0fffff00) == 0x057ff000) { switch ((insn >> 4) & 0xf) { case 1: /* clrex */ ARCH(6K); gen_clrex(s); case 4: /* dsb */ case 5: /* dmb */ case 6: /* isb */ ARCH(7); /* We don't emulate caches so these are a no-op. */ default: goto illegal_op; } } else if ((insn & 0x0e5fffe0) == 0x084d0500) { /* srs */ if (IS_USER(s)) { goto illegal_op; } ARCH(6); gen_srs(s, (insn & 0x1f), (insn >> 23) & 3, insn & (1 << 21)); } else if ((insn & 0x0e50ffe0) == 0x08100a00) { /* rfe */ int32_t offset; if (IS_USER(s)) goto illegal_op; ARCH(6); rn = (insn >> 16) & 0xf; addr = load_reg(s, rn); i = (insn >> 23) & 3; switch (i) { case 0: offset = -4; break; /* DA */ case 1: offset = 0; break; /* IA */ case 2: offset = -8; break; /* DB */ case 3: offset = 4; break; /* IB */ default: abort(); } if (offset) tcg_gen_addi_i32(addr, addr, offset); /* Load PC into tmp and CPSR into tmp2. */ tmp = gen_ld32(addr, 0); tcg_gen_addi_i32(addr, addr, 4); tmp2 = gen_ld32(addr, 0); if (insn & (1 << 21)) { /* Base writeback. */ switch (i) { case 0: offset = -8; break; case 1: offset = 4; break; case 2: offset = -4; break; case 3: offset = 0; break; default: abort(); } if (offset) tcg_gen_addi_i32(addr, addr, offset); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); } else if ((insn & 0x0e000000) == 0x0a000000) { /* branch link and change to thumb (blx <offset>) */ int32_t offset; val = (uint32_t)s->pc; tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_reg(s, 14, tmp); /* Sign-extend the 24-bit offset */ offset = (((int32_t)insn) << 8) >> 8; /* offset * 4 + bit24 * 2 + (thumb bit) */ val += (offset << 2) | ((insn >> 23) & 2) | 1; /* pipeline offset */ val += 4; /* protected by ARCH(5); above, near the start of uncond block */ gen_bx_im(s, val); } else if ((insn & 0x0e000f00) == 0x0c000100) { if (arm_feature(env, ARM_FEATURE_IWMMXT)) { /* iWMMXt register transfer. */ if (env->cp15.c15_cpar & (1 << 1)) if (!disas_iwmmxt_insn(env, s, insn)) } } else if ((insn & 0x0fe00000) == 0x0c400000) { /* Coprocessor double register transfer. */ ARCH(5TE); } else if ((insn & 0x0f000010) == 0x0e000010) { /* Additional coprocessor register transfer. */ } else if ((insn & 0x0ff10020) == 0x01000000) { uint32_t mask; uint32_t val; /* cps (privileged) */ if (IS_USER(s)) mask = val = 0; if (insn & (1 << 19)) { if (insn & (1 << 8)) mask |= CPSR_A; if (insn & (1 << 7)) mask |= CPSR_I; if (insn & (1 << 6)) mask |= CPSR_F; if (insn & (1 << 18)) val |= mask; } if (insn & (1 << 17)) { mask |= CPSR_M; val |= (insn & 0x1f); } if (mask) { gen_set_psr_im(s, mask, 0, val); } } goto illegal_op; } if (cond != 0xe) { /* if not always execute, we generate a conditional jump to next instruction */ s->condlabel = gen_new_label(); gen_test_cc(cond ^ 1, s->condlabel); s->condjmp = 1; } if ((insn & 0x0f900000) == 0x03000000) { if ((insn & (1 << 21)) == 0) { ARCH(6T2); rd = (insn >> 12) & 0xf; val = ((insn >> 4) & 0xf000) | (insn & 0xfff); if ((insn & (1 << 22)) == 0) { /* MOVW */ tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); } else { /* MOVT */ tmp = load_reg(s, rd); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_ori_i32(tmp, tmp, val << 16); } store_reg(s, rd, tmp); } else { if (((insn >> 12) & 0xf) != 0xf) goto illegal_op; if (((insn >> 16) & 0xf) == 0) { gen_nop_hint(s, insn & 0xff); } else { /* CPSR = immediate */ val = insn & 0xff; shift = ((insn >> 8) & 0xf) * 2; if (shift) val = (val >> shift) | (val << (32 - shift)); i = ((insn & (1 << 22)) != 0); if (gen_set_psr_im(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, val)) goto illegal_op; } } } else if ((insn & 0x0f900000) == 0x01000000 && (insn & 0x00000090) != 0x00000090) { /* miscellaneous instructions */ op1 = (insn >> 21) & 3; sh = (insn >> 4) & 0xf; rm = insn & 0xf; switch (sh) { case 0x0: /* move program status register */ if (op1 & 1) { /* PSR = reg */ tmp = load_reg(s, rm); i = ((op1 & 2) != 0); if (gen_set_psr(s, msr_mask(env, s, (insn >> 16) & 0xf, i), i, tmp)) goto illegal_op; } else { /* reg = PSR */ rd = (insn >> 12) & 0xf; if (op1 & 2) { if (IS_USER(s)) goto illegal_op; tmp = load_cpu_field(spsr); } else { tmp = tcg_temp_new_i32(); gen_helper_cpsr_read(tmp, cpu_env); } store_reg(s, rd, tmp); } break; case 0x1: if (op1 == 1) { /* branch/exchange thumb (bx). */ ARCH(4T); tmp = load_reg(s, rm); gen_bx(s, tmp); } else if (op1 == 3) { /* clz */ ARCH(5); rd = (insn >> 12) & 0xf; tmp = load_reg(s, rm); gen_helper_clz(tmp, tmp); store_reg(s, rd, tmp); } else { goto illegal_op; } break; case 0x2: if (op1 == 1) { ARCH(5J); /* bxj */ /* Trivial implementation equivalent to bx. */ tmp = load_reg(s, rm); gen_bx(s, tmp); } else { goto illegal_op; } break; case 0x3: if (op1 != 1) goto illegal_op; ARCH(5); /* branch link/exchange thumb (blx) */ tmp = load_reg(s, rm); tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, s->pc); store_reg(s, 14, tmp2); gen_bx(s, tmp); break; case 0x5: /* saturating add/subtract */ ARCH(5TE); rd = (insn >> 12) & 0xf; rn = (insn >> 16) & 0xf; tmp = load_reg(s, rm); tmp2 = load_reg(s, rn); if (op1 & 2) gen_helper_double_saturate(tmp2, cpu_env, tmp2); if (op1 & 1) gen_helper_sub_saturate(tmp, cpu_env, tmp, tmp2); else gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 7: /* SMC instruction (op1 == 3) and undefined instructions (op1 == 0 || op1 == 2) will trap */ if (op1 != 1) { goto illegal_op; } /* bkpt */ ARCH(5); gen_exception_insn(s, 4, EXCP_BKPT); break; case 0x8: /* signed multiply */ case 0xa: case 0xc: case 0xe: ARCH(5TE); rs = (insn >> 8) & 0xf; rn = (insn >> 12) & 0xf; rd = (insn >> 16) & 0xf; if (op1 == 1) { /* (32 * 16) >> 16 */ tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); if (sh & 4) tcg_gen_sari_i32(tmp2, tmp2, 16); else gen_sxth(tmp2); tmp64 = gen_muls_i64_i32(tmp, tmp2); tcg_gen_shri_i64(tmp64, tmp64, 16); tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if ((sh & 2) == 0) { tmp2 = load_reg(s, rn); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); } else { /* 16 * 16 */ tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); gen_mulxy(tmp, tmp2, sh & 2, sh & 4); tcg_temp_free_i32(tmp2); if (op1 == 2) { tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rn, rd); gen_storeq_reg(s, rn, rd, tmp64); tcg_temp_free_i64(tmp64); } else { if (op1 == 0) { tmp2 = load_reg(s, rn); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); } } break; default: goto illegal_op; } } else if (((insn & 0x0e000000) == 0 && (insn & 0x00000090) != 0x90) || ((insn & 0x0e000000) == (1 << 25))) { int set_cc, logic_cc, shiftop; op1 = (insn >> 21) & 0xf; set_cc = (insn >> 20) & 1; logic_cc = table_logic_cc[op1] & set_cc; /* data processing instruction */ if (insn & (1 << 25)) { /* immediate operand */ val = insn & 0xff; shift = ((insn >> 8) & 0xf) * 2; if (shift) { val = (val >> shift) | (val << (32 - shift)); } tmp2 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, val); if (logic_cc && shift) { gen_set_CF_bit31(tmp2); } } else { /* register */ rm = (insn) & 0xf; tmp2 = load_reg(s, rm); shiftop = (insn >> 5) & 3; if (!(insn & (1 << 4))) { shift = (insn >> 7) & 0x1f; gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); } else { rs = (insn >> 8) & 0xf; tmp = load_reg(s, rs); gen_arm_shift_reg(tmp2, shiftop, tmp, logic_cc); } } if (op1 != 0x0f && op1 != 0x0d) { rn = (insn >> 16) & 0xf; tmp = load_reg(s, rn); } else { TCGV_UNUSED(tmp); } rd = (insn >> 12) & 0xf; switch(op1) { case 0x00: tcg_gen_and_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x01: tcg_gen_xor_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x02: if (set_cc && rd == 15) { /* SUBS r15, ... is used for exception return. */ if (IS_USER(s)) { goto illegal_op; } gen_sub_CC(tmp, tmp, tmp2); gen_exception_return(s, tmp); } else { if (set_cc) { gen_sub_CC(tmp, tmp, tmp2); } else { tcg_gen_sub_i32(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); } break; case 0x03: if (set_cc) { gen_sub_CC(tmp, tmp2, tmp); } else { tcg_gen_sub_i32(tmp, tmp2, tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x04: if (set_cc) { gen_add_CC(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); break; case 0x05: if (set_cc) { gen_adc_CC(tmp, tmp, tmp2); } else { gen_add_carry(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); break; case 0x06: if (set_cc) { gen_sbc_CC(tmp, tmp, tmp2); } else { gen_sub_carry(tmp, tmp, tmp2); } store_reg_bx(env, s, rd, tmp); break; case 0x07: if (set_cc) { gen_sbc_CC(tmp, tmp2, tmp); } else { gen_sub_carry(tmp, tmp2, tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x08: if (set_cc) { tcg_gen_and_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); } tcg_temp_free_i32(tmp); break; case 0x09: if (set_cc) { tcg_gen_xor_i32(tmp, tmp, tmp2); gen_logic_CC(tmp); } tcg_temp_free_i32(tmp); break; case 0x0a: if (set_cc) { gen_sub_CC(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp); break; case 0x0b: if (set_cc) { gen_add_CC(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp); break; case 0x0c: tcg_gen_or_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; case 0x0d: if (logic_cc && rd == 15) { /* MOVS r15, ... is used for exception return. */ if (IS_USER(s)) { goto illegal_op; } gen_exception_return(s, tmp2); } else { if (logic_cc) { gen_logic_CC(tmp2); } store_reg_bx(env, s, rd, tmp2); } break; case 0x0e: tcg_gen_andc_i32(tmp, tmp, tmp2); if (logic_cc) { gen_logic_CC(tmp); } store_reg_bx(env, s, rd, tmp); break; default: case 0x0f: tcg_gen_not_i32(tmp2, tmp2); if (logic_cc) { gen_logic_CC(tmp2); } store_reg_bx(env, s, rd, tmp2); break; } if (op1 != 0x0f && op1 != 0x0d) { tcg_temp_free_i32(tmp2); } } else { /* other instructions */ op1 = (insn >> 24) & 0xf; switch(op1) { case 0x0: case 0x1: /* multiplies, extra load/stores */ sh = (insn >> 5) & 3; if (sh == 0) { if (op1 == 0x0) { rd = (insn >> 16) & 0xf; rn = (insn >> 12) & 0xf; rs = (insn >> 8) & 0xf; rm = (insn) & 0xf; op1 = (insn >> 20) & 0xf; switch (op1) { case 0: case 1: case 2: case 3: case 6: /* 32 bit mul */ tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); tcg_gen_mul_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* Subtract (mls) */ ARCH(6T2); tmp2 = load_reg(s, rn); tcg_gen_sub_i32(tmp, tmp2, tmp); tcg_temp_free_i32(tmp2); } else if (insn & (1 << 21)) { /* Add */ tmp2 = load_reg(s, rn); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } if (insn & (1 << 20)) gen_logic_CC(tmp); store_reg(s, rd, tmp); break; case 4: /* 64 bit mul double accumulate (UMAAL) */ ARCH(6); tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); tmp64 = gen_mulu_i64_i32(tmp, tmp2); gen_addq_lo(s, tmp64, rn); gen_addq_lo(s, tmp64, rd); gen_storeq_reg(s, rn, rd, tmp64); tcg_temp_free_i64(tmp64); break; case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15: /* 64 bit mul: UMULL, UMLAL, SMULL, SMLAL. */ tmp = load_reg(s, rs); tmp2 = load_reg(s, rm); if (insn & (1 << 22)) { tcg_gen_muls2_i32(tmp, tmp2, tmp, tmp2); } else { tcg_gen_mulu2_i32(tmp, tmp2, tmp, tmp2); } if (insn & (1 << 21)) { /* mult accumulate */ TCGv al = load_reg(s, rn); TCGv ah = load_reg(s, rd); tcg_gen_add2_i32(tmp, tmp2, tmp, tmp2, al, ah); tcg_temp_free(al); tcg_temp_free(ah); } if (insn & (1 << 20)) { gen_logicq_cc(tmp, tmp2); } store_reg(s, rn, tmp); store_reg(s, rd, tmp2); break; default: goto illegal_op; } } else { rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; if (insn & (1 << 23)) { /* load/store exclusive */ op1 = (insn >> 21) & 0x3; if (op1) ARCH(6K); else ARCH(6); addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); if (insn & (1 << 20)) { switch (op1) { case 0: /* ldrex */ gen_load_exclusive(s, rd, 15, addr, 2); break; case 1: /* ldrexd */ gen_load_exclusive(s, rd, rd + 1, addr, 3); break; case 2: /* ldrexb */ gen_load_exclusive(s, rd, 15, addr, 0); break; case 3: /* ldrexh */ gen_load_exclusive(s, rd, 15, addr, 1); break; default: abort(); } } else { rm = insn & 0xf; switch (op1) { case 0: /* strex */ gen_store_exclusive(s, rd, rm, 15, addr, 2); break; case 1: /* strexd */ gen_store_exclusive(s, rd, rm, rm + 1, addr, 3); break; case 2: /* strexb */ gen_store_exclusive(s, rd, rm, 15, addr, 0); break; case 3: /* strexh */ gen_store_exclusive(s, rd, rm, 15, addr, 1); break; default: abort(); } } tcg_temp_free(addr); } else { /* SWP instruction */ rm = (insn) & 0xf; /* ??? This is not really atomic. However we know we never have multiple CPUs running in parallel, so it is good enough. */ addr = load_reg(s, rn); tmp = load_reg(s, rm); if (insn & (1 << 22)) { tmp2 = gen_ld8u(addr, IS_USER(s)); gen_st8(tmp, addr, IS_USER(s)); } else { tmp2 = gen_ld32(addr, IS_USER(s)); gen_st32(tmp, addr, IS_USER(s)); } tcg_temp_free_i32(addr); store_reg(s, rd, tmp2); } } } else { int address_offset; int load; /* Misc load/store */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; addr = load_reg(s, rn); if (insn & (1 << 24)) gen_add_datah_offset(s, insn, 0, addr); address_offset = 0; if (insn & (1 << 20)) { /* load */ switch(sh) { case 1: tmp = gen_ld16u(addr, IS_USER(s)); break; case 2: tmp = gen_ld8s(addr, IS_USER(s)); break; default: case 3: tmp = gen_ld16s(addr, IS_USER(s)); break; } load = 1; } else if (sh & 2) { ARCH(5TE); /* doubleword */ if (sh & 1) { /* store */ tmp = load_reg(s, rd); gen_st32(tmp, addr, IS_USER(s)); tcg_gen_addi_i32(addr, addr, 4); tmp = load_reg(s, rd + 1); gen_st32(tmp, addr, IS_USER(s)); load = 0; } else { /* load */ tmp = gen_ld32(addr, IS_USER(s)); store_reg(s, rd, tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = gen_ld32(addr, IS_USER(s)); rd++; load = 1; } address_offset = -4; } else { /* store */ tmp = load_reg(s, rd); gen_st16(tmp, addr, IS_USER(s)); load = 0; } /* Perform base writeback before the loaded value to ensure correct behavior with overlapping index registers. ldrd with base writeback is is undefined if the destination and index registers overlap. */ if (!(insn & (1 << 24))) { gen_add_datah_offset(s, insn, address_offset, addr); store_reg(s, rn, addr); } else if (insn & (1 << 21)) { if (address_offset) tcg_gen_addi_i32(addr, addr, address_offset); store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } if (load) { /* Complete the load. */ store_reg(s, rd, tmp); } } break; case 0x4: case 0x5: goto do_ldst; case 0x6: case 0x7: if (insn & (1 << 4)) { ARCH(6); /* Armv6 Media instructions. */ rm = insn & 0xf; rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; rs = (insn >> 8) & 0xf; switch ((insn >> 23) & 3) { case 0: /* Parallel add/subtract. */ op1 = (insn >> 20) & 7; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); sh = (insn >> 5) & 7; if ((op1 & 3) == 0 || sh == 5 || sh == 6) goto illegal_op; gen_arm_parallel_addsub(op1, sh, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); break; case 1: if ((insn & 0x00700020) == 0) { /* Halfword pack. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); shift = (insn >> 7) & 0x1f; if (insn & (1 << 6)) { /* pkhtb */ if (shift == 0) shift = 31; tcg_gen_sari_i32(tmp2, tmp2, shift); tcg_gen_andi_i32(tmp, tmp, 0xffff0000); tcg_gen_ext16u_i32(tmp2, tmp2); } else { /* pkhbt */ if (shift) tcg_gen_shli_i32(tmp2, tmp2, shift); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_andi_i32(tmp2, tmp2, 0xffff0000); } tcg_gen_or_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00200020) == 0x00200000) { /* [us]sat */ tmp = load_reg(s, rm); shift = (insn >> 7) & 0x1f; if (insn & (1 << 6)) { if (shift == 0) shift = 31; tcg_gen_sari_i32(tmp, tmp, shift); } else { tcg_gen_shli_i32(tmp, tmp, shift); } sh = (insn >> 16) & 0x1f; tmp2 = tcg_const_i32(sh); if (insn & (1 << 22)) gen_helper_usat(tmp, cpu_env, tmp, tmp2); else gen_helper_ssat(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00300fe0) == 0x00200f20) { /* [us]sat16 */ tmp = load_reg(s, rm); sh = (insn >> 16) & 0x1f; tmp2 = tcg_const_i32(sh); if (insn & (1 << 22)) gen_helper_usat16(tmp, cpu_env, tmp, tmp2); else gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x00700fe0) == 0x00000fa0) { /* Select bytes. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); tmp3 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); tcg_temp_free_i32(tmp3); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else if ((insn & 0x000003e0) == 0x00000060) { tmp = load_reg(s, rm); shift = (insn >> 10) & 3; /* ??? In many cases it's not necessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); op1 = (insn >> 20) & 7; switch (op1) { case 0: gen_sxtb16(tmp); break; case 2: gen_sxtb(tmp); break; case 3: gen_sxth(tmp); break; case 4: gen_uxtb16(tmp); break; case 6: gen_uxtb(tmp); break; case 7: gen_uxth(tmp); break; default: goto illegal_op; } if (rn != 15) { tmp2 = load_reg(s, rn); if ((op1 & 3) == 0) { gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } } store_reg(s, rd, tmp); } else if ((insn & 0x003f0f60) == 0x003f0f20) { /* rev */ tmp = load_reg(s, rm); if (insn & (1 << 22)) { if (insn & (1 << 7)) { gen_revsh(tmp); } else { ARCH(6T2); gen_helper_rbit(tmp, tmp); } } else { if (insn & (1 << 7)) gen_rev16(tmp); else tcg_gen_bswap32_i32(tmp, tmp); } store_reg(s, rd, tmp); } else { goto illegal_op; } break; case 2: /* Multiplies (Type 3). */ switch ((insn >> 20) & 0x7) { case 5: if (((insn >> 6) ^ (insn >> 7)) & 1) { /* op2 not 00x or 11x : UNDEF */ goto illegal_op; } /* Signed multiply most significant [accumulate]. (SMMUL, SMMLA, SMMLS) */ tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); tmp64 = gen_muls_i64_i32(tmp, tmp2); if (rd != 15) { tmp = load_reg(s, rd); if (insn & (1 << 6)) { tmp64 = gen_subq_msw(tmp64, tmp); } else { tmp64 = gen_addq_msw(tmp64, tmp); } } if (insn & (1 << 5)) { tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); tmp = tcg_temp_new_i32(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); store_reg(s, rn, tmp); break; case 0: case 4: /* SMLAD, SMUAD, SMLSD, SMUSD, SMLALD, SMLSLD */ if (insn & (1 << 7)) { goto illegal_op; } tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); if (insn & (1 << 5)) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (insn & (1 << 6)) { /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { /* This addition cannot overflow 32 bits; * however it may overflow considered as a signed * operation, in which case we must set the Q flag. */ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); } tcg_temp_free_i32(tmp2); if (insn & (1 << 22)) { /* smlald, smlsld */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(tmp); gen_addq(s, tmp64, rd, rn); gen_storeq_reg(s, rd, rn, tmp64); tcg_temp_free_i64(tmp64); } else { /* smuad, smusd, smlad, smlsd */ if (rd != 15) { tmp2 = load_reg(s, rd); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rn, tmp); } break; case 1: case 3: /* SDIV, UDIV */ if (!arm_feature(env, ARM_FEATURE_ARM_DIV)) { goto illegal_op; } if (((insn >> 5) & 7) || (rd != 15)) { goto illegal_op; } tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); if (insn & (1 << 21)) { gen_helper_udiv(tmp, tmp, tmp2); } else { gen_helper_sdiv(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp2); store_reg(s, rn, tmp); break; default: goto illegal_op; } break; case 3: op1 = ((insn >> 17) & 0x38) | ((insn >> 5) & 7); switch (op1) { case 0: /* Unsigned sum of absolute differences. */ ARCH(6); tmp = load_reg(s, rm); tmp2 = load_reg(s, rs); gen_helper_usad8(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); if (rd != 15) { tmp2 = load_reg(s, rd); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(tmp2); } store_reg(s, rn, tmp); break; case 0x20: case 0x24: case 0x28: case 0x2c: /* Bitfield insert/clear. */ ARCH(6T2); shift = (insn >> 7) & 0x1f; i = (insn >> 16) & 0x1f; i = i + 1 - shift; if (rm == 15) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rm); } if (i != 32) { tmp2 = load_reg(s, rd); tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, i); tcg_temp_free_i32(tmp2); } store_reg(s, rd, tmp); break; case 0x12: case 0x16: case 0x1a: case 0x1e: /* sbfx */ case 0x32: case 0x36: case 0x3a: case 0x3e: /* ubfx */ ARCH(6T2); tmp = load_reg(s, rm); shift = (insn >> 7) & 0x1f; i = ((insn >> 16) & 0x1f) + 1; if (shift + i > 32) goto illegal_op; if (i < 32) { if (op1 & 0x20) { gen_ubfx(tmp, shift, (1u << i) - 1); } else { gen_sbfx(tmp, shift, i); } } store_reg(s, rd, tmp); break; default: goto illegal_op; } break; } break; } do_ldst: /* Check for undefined extension instructions * per the ARM Bible IE: * xxxx 0111 1111 xxxx xxxx xxxx 1111 xxxx */ sh = (0xf << 20) | (0xf << 4); if (op1 == 0x7 && ((insn & sh) == sh)) { goto illegal_op; } /* load/store byte/word */ rn = (insn >> 16) & 0xf; rd = (insn >> 12) & 0xf; tmp2 = load_reg(s, rn); i = (IS_USER(s) || (insn & 0x01200000) == 0x00200000); if (insn & (1 << 24)) gen_add_data_offset(s, insn, tmp2); if (insn & (1 << 20)) { /* load */ if (insn & (1 << 22)) { tmp = gen_ld8u(tmp2, i); } else { tmp = gen_ld32(tmp2, i); } } else { /* store */ tmp = load_reg(s, rd); if (insn & (1 << 22)) gen_st8(tmp, tmp2, i); else gen_st32(tmp, tmp2, i); } if (!(insn & (1 << 24))) { gen_add_data_offset(s, insn, tmp2); store_reg(s, rn, tmp2); } else if (insn & (1 << 21)) { store_reg(s, rn, tmp2); } else { tcg_temp_free_i32(tmp2); } if (insn & (1 << 20)) { /* Complete the load. */ store_reg_from_load(env, s, rd, tmp); } break; case 0x08: case 0x09: { int j, n, user, loaded_base; TCGv loaded_var; /* load/store multiple words */ /* XXX: store correct base if write back */ user = 0; if (insn & (1 << 22)) { if (IS_USER(s)) goto illegal_op; /* only usable in supervisor mode */ if ((insn & (1 << 15)) == 0) user = 1; } rn = (insn >> 16) & 0xf; addr = load_reg(s, rn); /* compute total size */ loaded_base = 0; TCGV_UNUSED(loaded_var); n = 0; for(i=0;i<16;i++) { if (insn & (1 << i)) n++; } /* XXX: test invalid n == 0 case ? */ if (insn & (1 << 23)) { if (insn & (1 << 24)) { /* pre increment */ tcg_gen_addi_i32(addr, addr, 4); } else { /* post increment */ } } else { if (insn & (1 << 24)) { /* pre decrement */ tcg_gen_addi_i32(addr, addr, -(n * 4)); } else { /* post decrement */ if (n != 1) tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); } } j = 0; for(i=0;i<16;i++) { if (insn & (1 << i)) { if (insn & (1 << 20)) { /* load */ tmp = gen_ld32(addr, IS_USER(s)); if (user) { tmp2 = tcg_const_i32(i); gen_helper_set_user_reg(cpu_env, tmp2, tmp); tcg_temp_free_i32(tmp2); tcg_temp_free_i32(tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; } else { store_reg_from_load(env, s, i, tmp); } } else { /* store */ if (i == 15) { /* special case: r15 = PC + 8 */ val = (long)s->pc + 4; tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); } else if (user) { tmp = tcg_temp_new_i32(); tmp2 = tcg_const_i32(i); gen_helper_get_user_reg(tmp, cpu_env, tmp2); tcg_temp_free_i32(tmp2); } else { tmp = load_reg(s, i); } gen_st32(tmp, addr, IS_USER(s)); } j++; /* no need to add after the last transfer */ if (j != n) tcg_gen_addi_i32(addr, addr, 4); } } if (insn & (1 << 21)) { /* write back */ if (insn & (1 << 23)) { if (insn & (1 << 24)) { /* pre increment */ } else { /* post increment */ tcg_gen_addi_i32(addr, addr, 4); } } else { if (insn & (1 << 24)) { /* pre decrement */ if (n != 1) tcg_gen_addi_i32(addr, addr, -((n - 1) * 4)); } else { /* post decrement */ tcg_gen_addi_i32(addr, addr, -(n * 4)); } } store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } if (loaded_base) { store_reg(s, rn, loaded_var); } if ((insn & (1 << 22)) && !user) { /* Restore CPSR from SPSR. */ tmp = load_cpu_field(spsr); gen_set_cpsr(tmp, 0xffffffff); tcg_temp_free_i32(tmp); s->is_jmp = DISAS_UPDATE; } } break; case 0xa: case 0xb: { int32_t offset; /* branch (and link) */ val = (int32_t)s->pc; if (insn & (1 << 24)) { tmp = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp, val); store_reg(s, 14, tmp); } offset = (((int32_t)insn << 8) >> 8); val += (offset << 2) + 4; gen_jmp(s, val); } break; case 0xc: case 0xd: case 0xe: /* Coprocessor. */ if (disas_coproc_insn(env, s, insn)) goto illegal_op; break; case 0xf: /* swi */ gen_set_pc_im(s->pc); s->is_jmp = DISAS_SWI; break; default: illegal_op: gen_exception_insn(s, 4, EXCP_UDEF); break; } } }


static const uint8_t *pcx_rle_decode(const uint8_t *src, uint8_t *dst, unsigned int bytes_per_scanline, int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { while (i<bytes_per_scanline) { run = 1; value = *src++; if (value >= 0xc0) { run = value & 0x3f; value = *src++; } while (i<bytes_per_scanline && run--) dst[i++] = value; } } else { memcpy(dst, src, bytes_per_scanline); src += bytes_per_scanline; } return src; }


static int coroutine_fn blkreplay_co_flush(BlockDriverState *bs) { uint64_t reqid = request_id++; int ret = bdrv_co_flush(bs->file->bs); block_request_create(reqid, bs, qemu_coroutine_self()); qemu_coroutine_yield(); return ret; }


USBDevice *usb_net_init(NICInfo *nd) { USBNetState *s; s = qemu_mallocz(sizeof(USBNetState)); s->dev.speed = USB_SPEED_FULL; s->dev.handle_packet = usb_generic_handle_packet; s->dev.handle_reset = usb_net_handle_reset; s->dev.handle_control = usb_net_handle_control; s->dev.handle_data = usb_net_handle_data; s->dev.handle_destroy = usb_net_handle_destroy; s->rndis = 1; s->rndis_state = RNDIS_UNINITIALIZED; s->medium = 0; /* NDIS_MEDIUM_802_3 */ s->speed = 1000000; /* 100MBps, in 100Bps units */ s->media_state = 0; /* NDIS_MEDIA_STATE_CONNECTED */; s->filter = 0; s->vendorid = 0x1234; memcpy(s->mac, nd->macaddr, 6); TAILQ_INIT(&s->rndis_resp); pstrcpy(s->dev.devname, sizeof(s->dev.devname), "QEMU USB Network Interface"); s->vc = qemu_new_vlan_client(nd->vlan, nd->model, nd->name, usbnet_receive, usbnet_can_receive, s); qemu_format_nic_info_str(s->vc, s->mac); snprintf(s->usbstring_mac, sizeof(s->usbstring_mac), "%02x%02x%02x%02x%02x%02x", 0x40, s->mac[1], s->mac[2], s->mac[3], s->mac[4], s->mac[5]); fprintf(stderr, "usbnet: initialized mac %02x:%02x:%02x:%02x:%02x:%02x\n", s->mac[0], s->mac[1], s->mac[2], s->mac[3], s->mac[4], s->mac[5]); return (USBDevice *) s; }


x11grab_read_header(AVFormatContext *s1) { struct x11_grab *x11grab = s1->priv_data; Display *dpy; AVStream *st = NULL; enum PixelFormat input_pixfmt; XImage *image; int x_off = 0; int y_off = 0; int screen; int use_shm; char *param, *offset; int ret = 0; AVRational framerate; param = av_strdup(s1->filename); if (!param) goto out; offset = strchr(param, '+'); if (offset) { sscanf(offset, "%d,%d", &x_off, &y_off); x11grab->draw_mouse = !strstr(offset, "nomouse"); *offset= 0; } if ((ret = av_parse_video_size(&x11grab->width, &x11grab->height, x11grab->video_size)) < 0) { av_log(s1, AV_LOG_ERROR, "Couldn't parse video size.\n"); goto out; } if ((ret = av_parse_video_rate(&framerate, x11grab->framerate)) < 0) { av_log(s1, AV_LOG_ERROR, "Could not parse framerate: %s.\n", x11grab->framerate); goto out; } av_log(s1, AV_LOG_INFO, "device: %s -> display: %s x: %d y: %d width: %d height: %d\n", s1->filename, param, x_off, y_off, x11grab->width, x11grab->height); dpy = XOpenDisplay(param); if(!dpy) { av_log(s1, AV_LOG_ERROR, "Could not open X display.\n"); ret = AVERROR(EIO); goto out; } st = avformat_new_stream(s1, NULL); if (!st) { ret = AVERROR(ENOMEM); goto out; } avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ screen = DefaultScreen(dpy); if (x11grab->follow_mouse) { int screen_w, screen_h; Window w; screen_w = DisplayWidth(dpy, screen); screen_h = DisplayHeight(dpy, screen); XQueryPointer(dpy, RootWindow(dpy, screen), &w, &w, &x_off, &y_off, &ret, &ret, &ret); x_off -= x11grab->width / 2; y_off -= x11grab->height / 2; x_off = FFMIN(FFMAX(x_off, 0), screen_w - x11grab->width); y_off = FFMIN(FFMAX(y_off, 0), screen_h - x11grab->height); av_log(s1, AV_LOG_INFO, "followmouse is enabled, resetting grabbing region to x: %d y: %d\n", x_off, y_off); } use_shm = XShmQueryExtension(dpy); av_log(s1, AV_LOG_INFO, "shared memory extension %s found\n", use_shm ? "" : "not"); if(use_shm) { int scr = XDefaultScreen(dpy); image = XShmCreateImage(dpy, DefaultVisual(dpy, scr), DefaultDepth(dpy, scr), ZPixmap, NULL, &x11grab->shminfo, x11grab->width, x11grab->height); x11grab->shminfo.shmid = shmget(IPC_PRIVATE, image->bytes_per_line * image->height, IPC_CREAT|0777); if (x11grab->shminfo.shmid == -1) { av_log(s1, AV_LOG_ERROR, "Fatal: Can't get shared memory!\n"); ret = AVERROR(ENOMEM); goto out; } x11grab->shminfo.shmaddr = image->data = shmat(x11grab->shminfo.shmid, 0, 0); x11grab->shminfo.readOnly = False; if (!XShmAttach(dpy, &x11grab->shminfo)) { av_log(s1, AV_LOG_ERROR, "Fatal: Failed to attach shared memory!\n"); /* needs some better error subroutine :) */ ret = AVERROR(EIO); goto out; } } else { image = XGetImage(dpy, RootWindow(dpy, screen), x_off,y_off, x11grab->width, x11grab->height, AllPlanes, ZPixmap); } switch (image->bits_per_pixel) { case 8: av_log (s1, AV_LOG_DEBUG, "8 bit palette\n"); input_pixfmt = PIX_FMT_PAL8; break; case 16: if ( image->red_mask == 0xf800 && image->green_mask == 0x07e0 && image->blue_mask == 0x001f ) { av_log (s1, AV_LOG_DEBUG, "16 bit RGB565\n"); input_pixfmt = PIX_FMT_RGB565; } else if (image->red_mask == 0x7c00 && image->green_mask == 0x03e0 && image->blue_mask == 0x001f ) { av_log(s1, AV_LOG_DEBUG, "16 bit RGB555\n"); input_pixfmt = PIX_FMT_RGB555; } else { av_log(s1, AV_LOG_ERROR, "RGB ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel); av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask); ret = AVERROR(EIO); goto out; } break; case 24: if ( image->red_mask == 0xff0000 && image->green_mask == 0x00ff00 && image->blue_mask == 0x0000ff ) { input_pixfmt = PIX_FMT_BGR24; } else if ( image->red_mask == 0x0000ff && image->green_mask == 0x00ff00 && image->blue_mask == 0xff0000 ) { input_pixfmt = PIX_FMT_RGB24; } else { av_log(s1, AV_LOG_ERROR,"rgb ordering at image depth %i not supported ... aborting\n", image->bits_per_pixel); av_log(s1, AV_LOG_ERROR, "color masks: r 0x%.6lx g 0x%.6lx b 0x%.6lx\n", image->red_mask, image->green_mask, image->blue_mask); ret = AVERROR(EIO); goto out; } break; case 32: input_pixfmt = PIX_FMT_RGB32; break; default: av_log(s1, AV_LOG_ERROR, "image depth %i not supported ... aborting\n", image->bits_per_pixel); ret = AVERROR(EINVAL); goto out; } x11grab->frame_size = x11grab->width * x11grab->height * image->bits_per_pixel/8; x11grab->dpy = dpy; x11grab->time_base = (AVRational){framerate.den, framerate.num}; x11grab->time_frame = av_gettime() / av_q2d(x11grab->time_base); x11grab->x_off = x_off; x11grab->y_off = y_off; x11grab->image = image; x11grab->use_shm = use_shm; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_RAWVIDEO; st->codec->width = x11grab->width; st->codec->height = x11grab->height; st->codec->pix_fmt = input_pixfmt; st->codec->time_base = x11grab->time_base; st->codec->bit_rate = x11grab->frame_size * 1/av_q2d(x11grab->time_base) * 8; out: return ret; }


static int mpc7_decode_frame(AVCodecContext * avctx, void *data, int *data_size, uint8_t * buf, int buf_size) { MPCContext *c = avctx->priv_data; GetBitContext gb; uint8_t *bits; int i, j, ch, t; int mb = -1; Band bands[BANDS]; int Q[2][MPC_FRAME_SIZE]; int off; float mul; int bits_used, bits_avail; memset(bands, 0, sizeof(bands)); if(buf_size <= 4){ av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size); } bits = av_malloc((buf_size - 1) & ~3); c->dsp.bswap_buf(bits, buf + 4, (buf_size - 4) >> 2); init_get_bits(&gb, bits, (buf_size - 4)* 8); skip_bits(&gb, buf[0]); /* read subband indexes */ for(i = 0; i <= c->bands; i++){ for(ch = 0; ch < 2; ch++){ if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; if(!i || (t == 4)) bands[i].res[ch] = get_bits(&gb, 4); else bands[i].res[ch] = bands[i-1].res[ch] + t; } if(bands[i].res[0] || bands[i].res[1]){ mb = i; if(c->MSS) bands[i].msf = get_bits1(&gb); } } /* get scale indexes coding method */ for(i = 0; i <= mb; i++) for(ch = 0; ch < 2; ch++) if(bands[i].res[ch]) bands[i].scfi[ch] = get_vlc2(&gb, scfi_vlc.table, MPC7_SCFI_BITS, 1); /* get scale indexes */ for(i = 0; i <= mb; i++){ for(ch = 0; ch < 2; ch++){ if(bands[i].res[ch]){ bands[i].scf_idx[ch][2] = c->oldDSCF[ch][i]; t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; bands[i].scf_idx[ch][0] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][2] + t); switch(bands[i].scfi[ch]){ case 0: t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; bands[i].scf_idx[ch][1] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][0] + t); t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; bands[i].scf_idx[ch][2] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][1] + t); break; case 1: t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; bands[i].scf_idx[ch][1] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][0] + t); bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1]; break; case 2: bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; t = get_vlc2(&gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; bands[i].scf_idx[ch][2] = (t == 8) ? get_bits(&gb, 6) : (bands[i].scf_idx[ch][1] + t); break; case 3: bands[i].scf_idx[ch][2] = bands[i].scf_idx[ch][1] = bands[i].scf_idx[ch][0]; break; } c->oldDSCF[ch][i] = bands[i].scf_idx[ch][2]; } } } /* get quantizers */ memset(Q, 0, sizeof(Q)); off = 0; for(i = 0; i < BANDS; i++, off += SAMPLES_PER_BAND) for(ch = 0; ch < 2; ch++) idx_to_quant(c, &gb, bands[i].res[ch], Q[ch] + off); /* dequantize */ memset(c->sb_samples, 0, sizeof(c->sb_samples)); off = 0; for(i = 0; i <= mb; i++, off += SAMPLES_PER_BAND){ for(ch = 0; ch < 2; ch++){ if(bands[i].res[ch]){ j = 0; mul = mpc_CC[bands[i].res[ch]] * mpc7_SCF[bands[i].scf_idx[ch][0]]; for(; j < 12; j++) c->sb_samples[ch][j][i] = mul * Q[ch][j + off]; mul = mpc_CC[bands[i].res[ch]] * mpc7_SCF[bands[i].scf_idx[ch][1]]; for(; j < 24; j++) c->sb_samples[ch][j][i] = mul * Q[ch][j + off]; mul = mpc_CC[bands[i].res[ch]] * mpc7_SCF[bands[i].scf_idx[ch][2]]; for(; j < 36; j++) c->sb_samples[ch][j][i] = mul * Q[ch][j + off]; } } if(bands[i].msf){ int t1, t2; for(j = 0; j < SAMPLES_PER_BAND; j++){ t1 = c->sb_samples[0][j][i]; t2 = c->sb_samples[1][j][i]; c->sb_samples[0][j][i] = t1 + t2; c->sb_samples[1][j][i] = t1 - t2; } } } mpc_synth(c, data); av_free(bits); bits_used = get_bits_count(&gb); bits_avail = (buf_size - 4) * 8; if(!buf[1] && ((bits_avail < bits_used) || (bits_used + 32 <= bits_avail))){ av_log(NULL,0, "Error decoding frame: used %i of %i bits\n", bits_used, bits_avail); return -1; } if(c->frames_to_skip){ c->frames_to_skip--; *data_size = 0; return buf_size; } *data_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4; return buf_size; }


void register_avcodec(AVCodec *codec) { AVCodec **p; p = &first_avcodec; while (*p != NULL) p = &(*p)->next; *p = codec; codec->next = NULL; }


static int uhci_broadcast_packet(UHCIState *s, USBPacket *p) { int i, ret; DPRINTF("uhci: packet enter. pid %s addr 0x%02x ep %d len %d\n", pid2str(p->pid), p->devaddr, p->devep, p->len); if (p->pid == USB_TOKEN_OUT || p->pid == USB_TOKEN_SETUP) dump_data(p->data, p->len); ret = USB_RET_NODEV; for (i = 0; i < NB_PORTS && ret == USB_RET_NODEV; i++) { UHCIPort *port = &s->ports[i]; USBDevice *dev = port->port.dev; if (dev && (port->ctrl & UHCI_PORT_EN)) ret = usb_handle_packet(dev, p); } DPRINTF("uhci: packet exit. ret %d len %d\n", ret, p->len); if (p->pid == USB_TOKEN_IN && ret > 0) dump_data(p->data, ret); return ret; }


static int vfio_early_setup_msix(VFIOPCIDevice *vdev) { uint8_t pos; uint16_t ctrl; uint32_t table, pba; int fd = vdev->vbasedev.fd; pos = pci_find_capability(&vdev->pdev, PCI_CAP_ID_MSIX); if (!pos) { return 0; } if (pread(fd, &ctrl, sizeof(ctrl), vdev->config_offset + pos + PCI_CAP_FLAGS) != sizeof(ctrl)) { return -errno; } if (pread(fd, &table, sizeof(table), vdev->config_offset + pos + PCI_MSIX_TABLE) != sizeof(table)) { return -errno; } if (pread(fd, &pba, sizeof(pba), vdev->config_offset + pos + PCI_MSIX_PBA) != sizeof(pba)) { return -errno; } ctrl = le16_to_cpu(ctrl); table = le32_to_cpu(table); pba = le32_to_cpu(pba); vdev->msix = g_malloc0(sizeof(*(vdev->msix))); vdev->msix->table_bar = table & PCI_MSIX_FLAGS_BIRMASK; vdev->msix->table_offset = table & ~PCI_MSIX_FLAGS_BIRMASK; vdev->msix->pba_bar = pba & PCI_MSIX_FLAGS_BIRMASK; vdev->msix->pba_offset = pba & ~PCI_MSIX_FLAGS_BIRMASK; vdev->msix->entries = (ctrl & PCI_MSIX_FLAGS_QSIZE) + 1; /* * Test the size of the pba_offset variable and catch if it extends outside * of the specified BAR. If it is the case, we need to apply a hardware * specific quirk if the device is known or we have a broken configuration. */ if (vdev->msix->pba_offset >= vdev->bars[vdev->msix->pba_bar].region.size) { PCIDevice *pdev = &vdev->pdev; uint16_t vendor = pci_get_word(pdev->config + PCI_VENDOR_ID); uint16_t device = pci_get_word(pdev->config + PCI_DEVICE_ID); /* * Chelsio T5 Virtual Function devices are encoded as 0x58xx for T5 * adapters. The T5 hardware returns an incorrect value of 0x8000 for * the VF PBA offset while the BAR itself is only 8k. The correct value * is 0x1000, so we hard code that here. */ if (vendor == PCI_VENDOR_ID_CHELSIO && (device & 0xff00) == 0x5800) { vdev->msix->pba_offset = 0x1000; } else { error_report("vfio: Hardware reports invalid configuration, " "MSIX PBA outside of specified BAR"); return -EINVAL; } } trace_vfio_early_setup_msix(vdev->vbasedev.name, pos, vdev->msix->table_bar, vdev->msix->table_offset, vdev->msix->entries); return 0; }


static int local_mkdir(FsContext *fs_ctx, const char *path, FsCred *credp) { int err = -1; int serrno = 0; /* Determine the security model */ if (fs_ctx->fs_sm == SM_MAPPED) { err = mkdir(rpath(fs_ctx, path), SM_LOCAL_DIR_MODE_BITS); if (err == -1) { return err; } credp->fc_mode = credp->fc_mode|S_IFDIR; err = local_set_xattr(rpath(fs_ctx, path), credp); if (err == -1) { serrno = errno; goto err_end; } } else if (fs_ctx->fs_sm == SM_PASSTHROUGH) { err = mkdir(rpath(fs_ctx, path), credp->fc_mode); if (err == -1) { return err; } err = local_post_create_passthrough(fs_ctx, path, credp); if (err == -1) { serrno = errno; goto err_end; } } return err; err_end: remove(rpath(fs_ctx, path)); errno = serrno; return err; }


static int pmp_header(AVFormatContext *s) { PMPContext *pmp = s->priv_data; AVIOContext *pb = s->pb; int tb_num, tb_den; uint32_t index_cnt; int audio_codec_id = AV_CODEC_ID_NONE; int srate, channels; int i; uint64_t pos; int64_t fsize = avio_size(pb); AVStream *vst = avformat_new_stream(s, NULL); if (!vst) return AVERROR(ENOMEM); vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; avio_skip(pb, 8); switch (avio_rl32(pb)) { case 0: vst->codec->codec_id = AV_CODEC_ID_MPEG4; break; case 1: vst->codec->codec_id = AV_CODEC_ID_H264; break; default: av_log(s, AV_LOG_ERROR, "Unsupported video format\n"); break; } index_cnt = avio_rl32(pb); vst->codec->width = avio_rl32(pb); vst->codec->height = avio_rl32(pb); tb_num = avio_rl32(pb); tb_den = avio_rl32(pb); avpriv_set_pts_info(vst, 32, tb_num, tb_den); vst->nb_frames = index_cnt; vst->duration = index_cnt; switch (avio_rl32(pb)) { case 0: audio_codec_id = AV_CODEC_ID_MP3; break; case 1: av_log(s, AV_LOG_ERROR, "AAC not yet correctly supported\n"); audio_codec_id = AV_CODEC_ID_AAC; break; default: av_log(s, AV_LOG_ERROR, "Unsupported audio format\n"); break; } pmp->num_streams = avio_rl16(pb) + 1; avio_skip(pb, 10); srate = avio_rl32(pb); channels = avio_rl32(pb) + 1; pos = avio_tell(pb) + 4*index_cnt; for (i = 0; i < index_cnt; i++) { uint32_t size = avio_rl32(pb); int flags = size & 1 ? AVINDEX_KEYFRAME : 0; if (url_feof(pb)) { av_log(s, AV_LOG_FATAL, "Encountered EOF while reading index.\n"); return AVERROR_INVALIDDATA; } size >>= 1; if (size < 9 + 4*pmp->num_streams) { av_log(s, AV_LOG_ERROR, "Packet too small\n"); return AVERROR_INVALIDDATA; } av_add_index_entry(vst, pos, i, size, 0, flags); pos += size; if (fsize > 0 && i == 0 && pos > fsize) { av_log(s, AV_LOG_ERROR, "File ends before first packet\n"); return AVERROR_INVALIDDATA; } } for (i = 1; i < pmp->num_streams; i++) { AVStream *ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = audio_codec_id; ast->codec->channels = channels; ast->codec->sample_rate = srate; avpriv_set_pts_info(ast, 32, 1, srate); } return 0; }


cpu_x86_dump_seg_cache(CPUX86State *env, FILE *f, fprintf_function cpu_fprintf, const char *name, struct SegmentCache *sc) { #ifdef TARGET_X86_64 if (env->hflags & HF_CS64_MASK) { cpu_fprintf(f, "%-3s=%04x %016" PRIx64 " %08x %08x", name, sc->selector, sc->base, sc->limit, sc->flags & 0x00ffff00); } else #endif { cpu_fprintf(f, "%-3s=%04x %08x %08x %08x", name, sc->selector, (uint32_t)sc->base, sc->limit, sc->flags & 0x00ffff00); } if (!(env->hflags & HF_PE_MASK) || !(sc->flags & DESC_P_MASK)) goto done; cpu_fprintf(f, " DPL=%d ", (sc->flags & DESC_DPL_MASK) >> DESC_DPL_SHIFT); if (sc->flags & DESC_S_MASK) { if (sc->flags & DESC_CS_MASK) { cpu_fprintf(f, (sc->flags & DESC_L_MASK) ? "CS64" : ((sc->flags & DESC_B_MASK) ? "CS32" : "CS16")); cpu_fprintf(f, " [%c%c", (sc->flags & DESC_C_MASK) ? 'C' : '-', (sc->flags & DESC_R_MASK) ? 'R' : '-'); } else { cpu_fprintf(f, (sc->flags & DESC_B_MASK) ? "DS " : "DS16"); cpu_fprintf(f, " [%c%c", (sc->flags & DESC_E_MASK) ? 'E' : '-', (sc->flags & DESC_W_MASK) ? 'W' : '-'); } cpu_fprintf(f, "%c]", (sc->flags & DESC_A_MASK) ? 'A' : '-'); } else { static const char *sys_type_name[2][16] = { { /* 32 bit mode */ "Reserved", "TSS16-avl", "LDT", "TSS16-busy", "CallGate16", "TaskGate", "IntGate16", "TrapGate16", "Reserved", "TSS32-avl", "Reserved", "TSS32-busy", "CallGate32", "Reserved", "IntGate32", "TrapGate32" }, { /* 64 bit mode */ "<hiword>", "Reserved", "LDT", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "TSS64-avl", "Reserved", "TSS64-busy", "CallGate64", "Reserved", "IntGate64", "TrapGate64" } }; cpu_fprintf(f, "%s", sys_type_name[(env->hflags & HF_LMA_MASK) ? 1 : 0] [(sc->flags & DESC_TYPE_MASK) >> DESC_TYPE_SHIFT]); } done: cpu_fprintf(f, "\n"); }


static int encode_frame(AVCodecContext *avctx, uint8_t *buf, int buf_size, void *data) { int tileno, ret; J2kEncoderContext *s = avctx->priv_data; // init: s->buf = s->buf_start = buf; s->buf_end = buf + buf_size; s->picture = data; s->lambda = s->picture->quality * LAMBDA_SCALE; copy_frame(s); reinit(s); if (s->buf_end - s->buf < 2) return -1; bytestream_put_be16(&s->buf, J2K_SOC); if (ret = put_siz(s)) return ret; if (ret = put_cod(s)) return ret; if (ret = put_qcd(s, 0)) return ret; for (tileno = 0; tileno < s->numXtiles * s->numYtiles; tileno++){ uint8_t *psotptr; if ((psotptr = put_sot(s, tileno)) < 0) return psotptr; if (s->buf_end - s->buf < 2) return -1; bytestream_put_be16(&s->buf, J2K_SOD); if (ret = encode_tile(s, s->tile + tileno, tileno)) return ret; bytestream_put_be32(&psotptr, s->buf - psotptr + 6); } if (s->buf_end - s->buf < 2) return -1; bytestream_put_be16(&s->buf, J2K_EOC); av_log(s->avctx, AV_LOG_DEBUG, "end\n"); return s->buf - s->buf_start; }


static void vqa_decode_chunk(VqaContext *s) { unsigned int chunk_type; unsigned int chunk_size; int byte_skip; unsigned int index = 0; int i; unsigned char r, g, b; int index_shift; int cbf0_chunk = -1; int cbfz_chunk = -1; int cbp0_chunk = -1; int cbpz_chunk = -1; int cpl0_chunk = -1; int cplz_chunk = -1; int vptz_chunk = -1; int x, y; int lines = 0; int pixel_ptr; int vector_index = 0; int lobyte = 0; int hibyte = 0; int lobytes = 0; int hibytes = s->decode_buffer_size / 2; /* first, traverse through the frame and find the subchunks */ while (index < s->size) { chunk_type = AV_RB32(&s->buf[index]); chunk_size = AV_RB32(&s->buf[index + 4]); switch (chunk_type) { case CBF0_TAG: cbf0_chunk = index; break; case CBFZ_TAG: cbfz_chunk = index; break; case CBP0_TAG: cbp0_chunk = index; break; case CBPZ_TAG: cbpz_chunk = index; break; case CPL0_TAG: cpl0_chunk = index; break; case CPLZ_TAG: cplz_chunk = index; break; case VPTZ_TAG: vptz_chunk = index; break; default: av_log(s->avctx, AV_LOG_ERROR, " VQA video: Found unknown chunk type: %c%c%c%c (%08X)\n", (chunk_type >> 24) & 0xFF, (chunk_type >> 16) & 0xFF, (chunk_type >> 8) & 0xFF, (chunk_type >> 0) & 0xFF, chunk_type); break; } byte_skip = chunk_size & 0x01; index += (CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip); } /* next, deal with the palette */ if ((cpl0_chunk != -1) && (cplz_chunk != -1)) { /* a chunk should not have both chunk types */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CPL0 and CPLZ chunks\n"); return; } /* decompress the palette chunk */ if (cplz_chunk != -1) { /* yet to be handled */ } /* convert the RGB palette into the machine's endian format */ if (cpl0_chunk != -1) { chunk_size = AV_RB32(&s->buf[cpl0_chunk + 4]); /* sanity check the palette size */ if (chunk_size / 3 > 256) { av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found a palette chunk with %d colors\n", chunk_size / 3); return; } cpl0_chunk += CHUNK_PREAMBLE_SIZE; for (i = 0; i < chunk_size / 3; i++) { /* scale by 4 to transform 6-bit palette -> 8-bit */ r = s->buf[cpl0_chunk++] * 4; g = s->buf[cpl0_chunk++] * 4; b = s->buf[cpl0_chunk++] * 4; s->palette[i] = (r << 16) | (g << 8) | (b); } } /* next, look for a full codebook */ if ((cbf0_chunk != -1) && (cbfz_chunk != -1)) { /* a chunk should not have both chunk types */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBF0 and CBFZ chunks\n"); return; } /* decompress the full codebook chunk */ if (cbfz_chunk != -1) { chunk_size = AV_RB32(&s->buf[cbfz_chunk + 4]); cbfz_chunk += CHUNK_PREAMBLE_SIZE; decode_format80(&s->buf[cbfz_chunk], chunk_size, s->codebook, s->codebook_size, 0); } /* copy a full codebook */ if (cbf0_chunk != -1) { chunk_size = AV_RB32(&s->buf[cbf0_chunk + 4]); /* sanity check the full codebook size */ if (chunk_size > MAX_CODEBOOK_SIZE) { av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: CBF0 chunk too large (0x%X bytes)\n", chunk_size); return; } cbf0_chunk += CHUNK_PREAMBLE_SIZE; memcpy(s->codebook, &s->buf[cbf0_chunk], chunk_size); } /* decode the frame */ if (vptz_chunk == -1) { /* something is wrong if there is no VPTZ chunk */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: no VPTZ chunk found\n"); return; } chunk_size = AV_RB32(&s->buf[vptz_chunk + 4]); vptz_chunk += CHUNK_PREAMBLE_SIZE; decode_format80(&s->buf[vptz_chunk], chunk_size, s->decode_buffer, s->decode_buffer_size, 1); /* render the final PAL8 frame */ if (s->vector_height == 4) index_shift = 4; else index_shift = 3; for (y = 0; y < s->frame.linesize[0] * s->height; y += s->frame.linesize[0] * s->vector_height) { for (x = y; x < y + s->width; x += 4, lobytes++, hibytes++) { pixel_ptr = x; /* get the vector index, the method for which varies according to * VQA file version */ switch (s->vqa_version) { case 1: lobyte = s->decode_buffer[lobytes * 2]; hibyte = s->decode_buffer[(lobytes * 2) + 1]; vector_index = ((hibyte << 8) | lobyte) >> 3; vector_index <<= index_shift; lines = s->vector_height; /* uniform color fill - a quick hack */ if (hibyte == 0xFF) { while (lines--) { s->frame.data[0][pixel_ptr + 0] = 255 - lobyte; s->frame.data[0][pixel_ptr + 1] = 255 - lobyte; s->frame.data[0][pixel_ptr + 2] = 255 - lobyte; s->frame.data[0][pixel_ptr + 3] = 255 - lobyte; pixel_ptr += s->frame.linesize[0]; } lines=0; } break; case 2: lobyte = s->decode_buffer[lobytes]; hibyte = s->decode_buffer[hibytes]; vector_index = (hibyte << 8) | lobyte; vector_index <<= index_shift; lines = s->vector_height; break; case 3: /* not implemented yet */ lines = 0; break; } while (lines--) { s->frame.data[0][pixel_ptr + 0] = s->codebook[vector_index++]; s->frame.data[0][pixel_ptr + 1] = s->codebook[vector_index++]; s->frame.data[0][pixel_ptr + 2] = s->codebook[vector_index++]; s->frame.data[0][pixel_ptr + 3] = s->codebook[vector_index++]; pixel_ptr += s->frame.linesize[0]; } } } /* handle partial codebook */ if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) { /* a chunk should not have both chunk types */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBP0 and CBPZ chunks\n"); return; } if (cbp0_chunk != -1) { chunk_size = AV_RB32(&s->buf[cbp0_chunk + 4]); cbp0_chunk += CHUNK_PREAMBLE_SIZE; /* accumulate partial codebook */ memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], &s->buf[cbp0_chunk], chunk_size); s->next_codebook_buffer_index += chunk_size; s->partial_countdown--; if (s->partial_countdown == 0) { /* time to replace codebook */ memcpy(s->codebook, s->next_codebook_buffer, s->next_codebook_buffer_index); /* reset accounting */ s->next_codebook_buffer_index = 0; s->partial_countdown = s->partial_count; } } if (cbpz_chunk != -1) { chunk_size = AV_RB32(&s->buf[cbpz_chunk + 4]); cbpz_chunk += CHUNK_PREAMBLE_SIZE; /* accumulate partial codebook */ memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], &s->buf[cbpz_chunk], chunk_size); s->next_codebook_buffer_index += chunk_size; s->partial_countdown--; if (s->partial_countdown == 0) { /* decompress codebook */ decode_format80(s->next_codebook_buffer, s->next_codebook_buffer_index, s->codebook, s->codebook_size, 0); /* reset accounting */ s->next_codebook_buffer_index = 0; s->partial_countdown = s->partial_count; } } }


int decode_luma_intra_block(VC9Context *v, int mquant) { GetBitContext *gb = &v->s.gb; int dcdiff; dcdiff = get_vlc2(gb, v->luma_dc_vlc->table, DC_VLC_BITS, 2); if (dcdiff) { if (dcdiff == 119 /* ESC index value */) { /* TODO: Optimize */ if (mquant == 1) dcdiff = get_bits(gb, 10); else if (mquant == 2) dcdiff = get_bits(gb, 9); else dcdiff = get_bits(gb, 8); } else { if (mquant == 1) dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3; else if (mquant == 2) dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1; } if (get_bits(gb, 1)) dcdiff = -dcdiff; } /* FIXME: 8.1.1.15, p(1)13, coeff scaling for Adv Profile */ return 0; }


static uint32_t nvic_readl(NVICState *s, uint32_t offset, MemTxAttrs attrs) { ARMCPU *cpu = s->cpu; uint32_t val; switch (offset) { case 4: /* Interrupt Control Type. */ return ((s->num_irq - NVIC_FIRST_IRQ) / 32) - 1; case 0x380 ... 0x3bf: /* NVIC_ITNS<n> */ { int startvec = 32 * (offset - 0x380) + NVIC_FIRST_IRQ; int i; if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } val = 0; for (i = 0; i < 32 && startvec + i < s->num_irq; i++) { if (s->itns[startvec + i]) { val |= (1 << i); } } return val; } case 0xd00: /* CPUID Base. */ return cpu->midr; case 0xd04: /* Interrupt Control State (ICSR) */ /* VECTACTIVE */ val = cpu->env.v7m.exception; /* VECTPENDING */ val |= (s->vectpending & 0xff) << 12; /* ISRPENDING - set if any external IRQ is pending */ if (nvic_isrpending(s)) { val |= (1 << 22); } /* RETTOBASE - set if only one handler is active */ if (nvic_rettobase(s)) { val |= (1 << 11); } if (attrs.secure) { /* PENDSTSET */ if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].pending) { val |= (1 << 26); } /* PENDSVSET */ if (s->sec_vectors[ARMV7M_EXCP_PENDSV].pending) { val |= (1 << 28); } } else { /* PENDSTSET */ if (s->vectors[ARMV7M_EXCP_SYSTICK].pending) { val |= (1 << 26); } /* PENDSVSET */ if (s->vectors[ARMV7M_EXCP_PENDSV].pending) { val |= (1 << 28); } } /* NMIPENDSET */ if ((cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK) && s->vectors[ARMV7M_EXCP_NMI].pending) { val |= (1 << 31); } /* ISRPREEMPT: RES0 when halting debug not implemented */ /* STTNS: RES0 for the Main Extension */ return val; case 0xd08: /* Vector Table Offset. */ return cpu->env.v7m.vecbase[attrs.secure]; case 0xd0c: /* Application Interrupt/Reset Control (AIRCR) */ val = 0xfa050000 | (s->prigroup[attrs.secure] << 8); if (attrs.secure) { /* s->aircr stores PRIS, BFHFNMINS, SYSRESETREQS */ val |= cpu->env.v7m.aircr; } else { if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* BFHFNMINS is R/O from NS; other bits are RAZ/WI. If * security isn't supported then BFHFNMINS is RAO (and * the bit in env.v7m.aircr is always set). */ val |= cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK; } } return val; case 0xd10: /* System Control. */ /* TODO: Implement SLEEPONEXIT. */ return 0; case 0xd14: /* Configuration Control. */ /* The BFHFNMIGN bit is the only non-banked bit; we * keep it in the non-secure copy of the register. */ val = cpu->env.v7m.ccr[attrs.secure]; val |= cpu->env.v7m.ccr[M_REG_NS] & R_V7M_CCR_BFHFNMIGN_MASK; return val; case 0xd24: /* System Handler Control and State (SHCSR) */ val = 0; if (attrs.secure) { if (s->sec_vectors[ARMV7M_EXCP_MEM].active) { val |= (1 << 0); } if (s->sec_vectors[ARMV7M_EXCP_HARD].active) { val |= (1 << 2); } if (s->sec_vectors[ARMV7M_EXCP_USAGE].active) { val |= (1 << 3); } if (s->sec_vectors[ARMV7M_EXCP_SVC].active) { val |= (1 << 7); } if (s->sec_vectors[ARMV7M_EXCP_PENDSV].active) { val |= (1 << 10); } if (s->sec_vectors[ARMV7M_EXCP_SYSTICK].active) { val |= (1 << 11); } if (s->sec_vectors[ARMV7M_EXCP_USAGE].pending) { val |= (1 << 12); } if (s->sec_vectors[ARMV7M_EXCP_MEM].pending) { val |= (1 << 13); } if (s->sec_vectors[ARMV7M_EXCP_SVC].pending) { val |= (1 << 15); } if (s->sec_vectors[ARMV7M_EXCP_MEM].enabled) { val |= (1 << 16); } if (s->sec_vectors[ARMV7M_EXCP_USAGE].enabled) { val |= (1 << 18); } if (s->sec_vectors[ARMV7M_EXCP_HARD].pending) { val |= (1 << 21); } /* SecureFault is not banked but is always RAZ/WI to NS */ if (s->vectors[ARMV7M_EXCP_SECURE].active) { val |= (1 << 4); } if (s->vectors[ARMV7M_EXCP_SECURE].enabled) { val |= (1 << 19); } if (s->vectors[ARMV7M_EXCP_SECURE].pending) { val |= (1 << 20); } } else { if (s->vectors[ARMV7M_EXCP_MEM].active) { val |= (1 << 0); } if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* HARDFAULTACT, HARDFAULTPENDED not present in v7M */ if (s->vectors[ARMV7M_EXCP_HARD].active) { val |= (1 << 2); } if (s->vectors[ARMV7M_EXCP_HARD].pending) { val |= (1 << 21); } } if (s->vectors[ARMV7M_EXCP_USAGE].active) { val |= (1 << 3); } if (s->vectors[ARMV7M_EXCP_SVC].active) { val |= (1 << 7); } if (s->vectors[ARMV7M_EXCP_PENDSV].active) { val |= (1 << 10); } if (s->vectors[ARMV7M_EXCP_SYSTICK].active) { val |= (1 << 11); } if (s->vectors[ARMV7M_EXCP_USAGE].pending) { val |= (1 << 12); } if (s->vectors[ARMV7M_EXCP_MEM].pending) { val |= (1 << 13); } if (s->vectors[ARMV7M_EXCP_SVC].pending) { val |= (1 << 15); } if (s->vectors[ARMV7M_EXCP_MEM].enabled) { val |= (1 << 16); } if (s->vectors[ARMV7M_EXCP_USAGE].enabled) { val |= (1 << 18); } } if (attrs.secure || (cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { if (s->vectors[ARMV7M_EXCP_BUS].active) { val |= (1 << 1); } if (s->vectors[ARMV7M_EXCP_BUS].pending) { val |= (1 << 14); } if (s->vectors[ARMV7M_EXCP_BUS].enabled) { val |= (1 << 17); } if (arm_feature(&cpu->env, ARM_FEATURE_V8) && s->vectors[ARMV7M_EXCP_NMI].active) { /* NMIACT is not present in v7M */ val |= (1 << 5); } } /* TODO: this is RAZ/WI from NS if DEMCR.SDME is set */ if (s->vectors[ARMV7M_EXCP_DEBUG].active) { val |= (1 << 8); } return val; case 0xd28: /* Configurable Fault Status. */ /* The BFSR bits [15:8] are shared between security states * and we store them in the NS copy */ val = cpu->env.v7m.cfsr[attrs.secure]; val |= cpu->env.v7m.cfsr[M_REG_NS] & R_V7M_CFSR_BFSR_MASK; return val; case 0xd2c: /* Hard Fault Status. */ return cpu->env.v7m.hfsr; case 0xd30: /* Debug Fault Status. */ return cpu->env.v7m.dfsr; case 0xd34: /* MMFAR MemManage Fault Address */ return cpu->env.v7m.mmfar[attrs.secure]; case 0xd38: /* Bus Fault Address. */ return cpu->env.v7m.bfar; case 0xd3c: /* Aux Fault Status. */ /* TODO: Implement fault status registers. */ qemu_log_mask(LOG_UNIMP, "Aux Fault status registers unimplemented\n"); return 0; case 0xd40: /* PFR0. */ return 0x00000030; case 0xd44: /* PRF1. */ return 0x00000200; case 0xd48: /* DFR0. */ return 0x00100000; case 0xd4c: /* AFR0. */ return 0x00000000; case 0xd50: /* MMFR0. */ return 0x00000030; case 0xd54: /* MMFR1. */ return 0x00000000; case 0xd58: /* MMFR2. */ return 0x00000000; case 0xd5c: /* MMFR3. */ return 0x00000000; case 0xd60: /* ISAR0. */ return 0x01141110; case 0xd64: /* ISAR1. */ return 0x02111000; case 0xd68: /* ISAR2. */ return 0x21112231; case 0xd6c: /* ISAR3. */ return 0x01111110; case 0xd70: /* ISAR4. */ return 0x01310102; /* TODO: Implement debug registers. */ case 0xd90: /* MPU_TYPE */ /* Unified MPU; if the MPU is not present this value is zero */ return cpu->pmsav7_dregion << 8; break; case 0xd94: /* MPU_CTRL */ return cpu->env.v7m.mpu_ctrl[attrs.secure]; case 0xd98: /* MPU_RNR */ return cpu->env.pmsav7.rnr[attrs.secure]; case 0xd9c: /* MPU_RBAR */ case 0xda4: /* MPU_RBAR_A1 */ case 0xdac: /* MPU_RBAR_A2 */ case 0xdb4: /* MPU_RBAR_A3 */ { int region = cpu->env.pmsav7.rnr[attrs.secure]; if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* PMSAv8M handling of the aliases is different from v7M: * aliases A1, A2, A3 override the low two bits of the region * number in MPU_RNR, and there is no 'region' field in the * RBAR register. */ int aliasno = (offset - 0xd9c) / 8; /* 0..3 */ if (aliasno) { region = deposit32(region, 0, 2, aliasno); } if (region >= cpu->pmsav7_dregion) { return 0; } return cpu->env.pmsav8.rbar[attrs.secure][region]; } if (region >= cpu->pmsav7_dregion) { return 0; } return (cpu->env.pmsav7.drbar[region] & 0x1f) | (region & 0xf); } case 0xda0: /* MPU_RASR (v7M), MPU_RLAR (v8M) */ case 0xda8: /* MPU_RASR_A1 (v7M), MPU_RLAR_A1 (v8M) */ case 0xdb0: /* MPU_RASR_A2 (v7M), MPU_RLAR_A2 (v8M) */ case 0xdb8: /* MPU_RASR_A3 (v7M), MPU_RLAR_A3 (v8M) */ { int region = cpu->env.pmsav7.rnr[attrs.secure]; if (arm_feature(&cpu->env, ARM_FEATURE_V8)) { /* PMSAv8M handling of the aliases is different from v7M: * aliases A1, A2, A3 override the low two bits of the region * number in MPU_RNR. */ int aliasno = (offset - 0xda0) / 8; /* 0..3 */ if (aliasno) { region = deposit32(region, 0, 2, aliasno); } if (region >= cpu->pmsav7_dregion) { return 0; } return cpu->env.pmsav8.rlar[attrs.secure][region]; } if (region >= cpu->pmsav7_dregion) { return 0; } return ((cpu->env.pmsav7.dracr[region] & 0xffff) << 16) | (cpu->env.pmsav7.drsr[region] & 0xffff); } case 0xdc0: /* MPU_MAIR0 */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } return cpu->env.pmsav8.mair0[attrs.secure]; case 0xdc4: /* MPU_MAIR1 */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } return cpu->env.pmsav8.mair1[attrs.secure]; case 0xdd0: /* SAU_CTRL */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } return cpu->env.sau.ctrl; case 0xdd4: /* SAU_TYPE */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } return cpu->sau_sregion; case 0xdd8: /* SAU_RNR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } return cpu->env.sau.rnr; case 0xddc: /* SAU_RBAR */ { int region = cpu->env.sau.rnr; if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } if (region >= cpu->sau_sregion) { return 0; } return cpu->env.sau.rbar[region]; } case 0xde0: /* SAU_RLAR */ { int region = cpu->env.sau.rnr; if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } if (region >= cpu->sau_sregion) { return 0; } return cpu->env.sau.rlar[region]; } case 0xde4: /* SFSR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } return cpu->env.v7m.sfsr; case 0xde8: /* SFAR */ if (!arm_feature(&cpu->env, ARM_FEATURE_V8)) { goto bad_offset; } if (!attrs.secure) { return 0; } return cpu->env.v7m.sfar; default: bad_offset: qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read offset 0x%x\n", offset); return 0; } }


static int init_opencl_env(GPUEnv *gpu_env, AVOpenCLExternalEnv *ext_opencl_env) { size_t device_length; cl_int status; cl_uint num_platforms, num_devices; cl_platform_id *platform_ids = NULL; cl_context_properties cps[3]; char platform_name[100]; int i, ret = 0; cl_device_type device_type[] = {CL_DEVICE_TYPE_GPU, CL_DEVICE_TYPE_CPU, CL_DEVICE_TYPE_DEFAULT}; if (ext_opencl_env) { if (gpu_env->is_user_created) return 0; gpu_env->platform_id = ext_opencl_env->platform_id; gpu_env->is_user_created = 1; gpu_env->command_queue = ext_opencl_env->command_queue; gpu_env->context = ext_opencl_env->context; gpu_env->device_ids = ext_opencl_env->device_ids; gpu_env->device_id = ext_opencl_env->device_id; gpu_env->device_type = ext_opencl_env->device_type; } else { if (!gpu_env->is_user_created) { status = clGetPlatformIDs(0, NULL, &num_platforms); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL platform ids: %s\n", opencl_errstr(status)); return AVERROR_EXTERNAL; } if (gpu_env->usr_spec_dev_info.platform_idx >= 0) { if (num_platforms < gpu_env->usr_spec_dev_info.platform_idx + 1) { av_log(&openclutils, AV_LOG_ERROR, "User set platform index not exist\n"); return AVERROR(EINVAL); } } if (num_platforms > 0) { platform_ids = av_mallocz(num_platforms * sizeof(cl_platform_id)); if (!platform_ids) { ret = AVERROR(ENOMEM); goto end; } status = clGetPlatformIDs(num_platforms, platform_ids, NULL); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL platform ids: %s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } i = 0; if (gpu_env->usr_spec_dev_info.platform_idx >= 0) { i = gpu_env->usr_spec_dev_info.platform_idx; } while (i < num_platforms) { status = clGetPlatformInfo(platform_ids[i], CL_PLATFORM_VENDOR, sizeof(platform_name), platform_name, NULL); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL platform info: %s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } gpu_env->platform_id = platform_ids[i]; status = clGetDeviceIDs(gpu_env->platform_id, CL_DEVICE_TYPE_GPU, 0, NULL, &num_devices); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL device number:%s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } if (num_devices == 0) { //find CPU device status = clGetDeviceIDs(gpu_env->platform_id, CL_DEVICE_TYPE_CPU, 0, NULL, &num_devices); } if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL device ids: %s\n", opencl_errstr(status)); ret = AVERROR(EINVAL); goto end; } if (num_devices) break; if (gpu_env->usr_spec_dev_info.platform_idx >= 0) { av_log(&openclutils, AV_LOG_ERROR, "Device number of user set platform is 0\n"); ret = AVERROR_EXTERNAL; goto end; } i++; } } if (!gpu_env->platform_id) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL platforms\n"); ret = AVERROR_EXTERNAL; goto end; } if (gpu_env->usr_spec_dev_info.dev_idx >= 0) { if (num_devices < gpu_env->usr_spec_dev_info.dev_idx + 1) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL device idx in the user set platform\n"); ret = AVERROR(EINVAL); goto end; } } /* * Use available platform. */ av_log(&openclutils, AV_LOG_VERBOSE, "Platform Name: %s\n", platform_name); cps[0] = CL_CONTEXT_PLATFORM; cps[1] = (cl_context_properties)gpu_env->platform_id; cps[2] = 0; /* Check for GPU. */ for (i = 0; i < sizeof(device_type); i++) { gpu_env->device_type = device_type[i]; gpu_env->context = clCreateContextFromType(cps, gpu_env->device_type, NULL, NULL, &status); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL context from device type: %s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } if (gpu_env->context) break; } if (!gpu_env->context) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL context from device type\n"); ret = AVERROR_EXTERNAL; goto end; } /* Detect OpenCL devices. */ /* First, get the size of device list data */ status = clGetContextInfo(gpu_env->context, CL_CONTEXT_DEVICES, 0, NULL, &device_length); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL device length: %s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } if (device_length == 0) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL device length\n"); ret = AVERROR_EXTERNAL; goto end; } /* Now allocate memory for device list based on the size we got earlier */ gpu_env->device_ids = av_mallocz(device_length); if (!gpu_env->device_ids) { ret = AVERROR(ENOMEM); goto end; } /* Now, get the device list data */ status = clGetContextInfo(gpu_env->context, CL_CONTEXT_DEVICES, device_length, gpu_env->device_ids, NULL); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not get OpenCL context info: %s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } /* Create OpenCL command queue. */ i = 0; if (gpu_env->usr_spec_dev_info.dev_idx >= 0) { i = gpu_env->usr_spec_dev_info.dev_idx; } gpu_env->command_queue = clCreateCommandQueue(gpu_env->context, gpu_env->device_ids[i], 0, &status); if (status != CL_SUCCESS) { av_log(&openclutils, AV_LOG_ERROR, "Could not create OpenCL command queue: %s\n", opencl_errstr(status)); ret = AVERROR_EXTERNAL; goto end; } } } end: av_free(platform_ids); return ret; }


static int vhost_user_call(struct vhost_dev *dev, unsigned long int request, void *arg) { VhostUserMsg msg; VhostUserRequest msg_request; struct vhost_vring_file *file = 0; int need_reply = 0; int fds[VHOST_MEMORY_MAX_NREGIONS]; int i, fd; size_t fd_num = 0; assert(dev->vhost_ops->backend_type == VHOST_BACKEND_TYPE_USER); msg_request = vhost_user_request_translate(request); msg.request = msg_request; msg.flags = VHOST_USER_VERSION; msg.size = 0; switch (request) { case VHOST_GET_FEATURES: need_reply = 1; break; case VHOST_SET_FEATURES: case VHOST_SET_LOG_BASE: msg.u64 = *((__u64 *) arg); msg.size = sizeof(m.u64); break; case VHOST_SET_OWNER: case VHOST_RESET_OWNER: break; case VHOST_SET_MEM_TABLE: for (i = 0; i < dev->mem->nregions; ++i) { struct vhost_memory_region *reg = dev->mem->regions + i; ram_addr_t ram_addr; qemu_ram_addr_from_host((void *)reg->userspace_addr, &ram_addr); fd = qemu_get_ram_fd(ram_addr); if (fd > 0) { msg.memory.regions[fd_num].userspace_addr = reg->userspace_addr; msg.memory.regions[fd_num].memory_size = reg->memory_size; msg.memory.regions[fd_num].guest_phys_addr = reg->guest_phys_addr; msg.memory.regions[fd_num].mmap_offset = reg->userspace_addr - (uintptr_t) qemu_get_ram_block_host_ptr(reg->guest_phys_addr); assert(fd_num < VHOST_MEMORY_MAX_NREGIONS); fds[fd_num++] = fd; } } msg.memory.nregions = fd_num; if (!fd_num) { error_report("Failed initializing vhost-user memory map\n" "consider using -object memory-backend-file share=on\n"); return -1; } msg.size = sizeof(m.memory.nregions); msg.size += sizeof(m.memory.padding); msg.size += fd_num * sizeof(VhostUserMemoryRegion); break; case VHOST_SET_LOG_FD: fds[fd_num++] = *((int *) arg); break; case VHOST_SET_VRING_NUM: case VHOST_SET_VRING_BASE: memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); msg.size = sizeof(m.state); break; case VHOST_GET_VRING_BASE: memcpy(&msg.state, arg, sizeof(struct vhost_vring_state)); msg.size = sizeof(m.state); need_reply = 1; break; case VHOST_SET_VRING_ADDR: memcpy(&msg.addr, arg, sizeof(struct vhost_vring_addr)); msg.size = sizeof(m.addr); break; case VHOST_SET_VRING_KICK: case VHOST_SET_VRING_CALL: case VHOST_SET_VRING_ERR: file = arg; msg.u64 = file->index & VHOST_USER_VRING_IDX_MASK; msg.size = sizeof(m.u64); if (ioeventfd_enabled() && file->fd > 0) { fds[fd_num++] = file->fd; } else { msg.u64 |= VHOST_USER_VRING_NOFD_MASK; } break; default: error_report("vhost-user trying to send unhandled ioctl\n"); return -1; break; } if (vhost_user_write(dev, &msg, fds, fd_num) < 0) { return 0; } if (need_reply) { if (vhost_user_read(dev, &msg) < 0) { return 0; } if (msg_request != msg.request) { error_report("Received unexpected msg type." " Expected %d received %d\n", msg_request, msg.request); return -1; } switch (msg_request) { case VHOST_USER_GET_FEATURES: if (msg.size != sizeof(m.u64)) { error_report("Received bad msg size.\n"); return -1; } *((__u64 *) arg) = msg.u64; break; case VHOST_USER_GET_VRING_BASE: if (msg.size != sizeof(m.state)) { error_report("Received bad msg size.\n"); return -1; } memcpy(arg, &msg.state, sizeof(struct vhost_vring_state)); break; default: error_report("Received unexpected msg type.\n"); return -1; break; } } return 0; }


static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp) { uint64_t magic; uint32_t opt; uint32_t type; uint32_t len; uint32_t namelen; *name = NULL; if (read_sync(ioc, &magic, sizeof(magic)) != sizeof(magic)) { error_setg(errp, "failed to read list option magic"); return -1; } magic = be64_to_cpu(magic); if (magic != NBD_REP_MAGIC) { error_setg(errp, "Unexpected option list magic"); return -1; } if (read_sync(ioc, &opt, sizeof(opt)) != sizeof(opt)) { error_setg(errp, "failed to read list option"); return -1; } opt = be32_to_cpu(opt); if (opt != NBD_OPT_LIST) { error_setg(errp, "Unexpected option type %x expected %x", opt, NBD_OPT_LIST); return -1; } if (read_sync(ioc, &type, sizeof(type)) != sizeof(type)) { error_setg(errp, "failed to read list option type"); return -1; } type = be32_to_cpu(type); if (type == NBD_REP_ERR_UNSUP) { return 0; } if (nbd_handle_reply_err(opt, type, errp) < 0) { return -1; } if (read_sync(ioc, &len, sizeof(len)) != sizeof(len)) { error_setg(errp, "failed to read option length"); return -1; } len = be32_to_cpu(len); if (type == NBD_REP_ACK) { if (len != 0) { error_setg(errp, "length too long for option end"); return -1; } } else if (type == NBD_REP_SERVER) { if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) { error_setg(errp, "failed to read option name length"); return -1; } namelen = be32_to_cpu(namelen); if (len != (namelen + sizeof(namelen))) { error_setg(errp, "incorrect option mame length"); return -1; } if (namelen > 255) { error_setg(errp, "export name length too long %d", namelen); return -1; } *name = g_new0(char, namelen + 1); if (read_sync(ioc, *name, namelen) != namelen) { error_setg(errp, "failed to read export name"); g_free(*name); *name = NULL; return -1; } (*name)[namelen] = '\0'; } else { error_setg(errp, "Unexpected reply type %x expected %x", type, NBD_REP_SERVER); return -1; } return 1; }


int64_t throttle_compute_wait(LeakyBucket *bkt) { double extra; /* the number of extra units blocking the io */ double bucket_size; /* I/O before throttling to bkt->avg */ double burst_bucket_size; /* Before throttling to bkt->max */ if (!bkt->avg) { return 0; } if (!bkt->max) { /* If bkt->max is 0 we still want to allow short bursts of I/O * from the guest, otherwise every other request will be throttled * and performance will suffer considerably. */ bucket_size = (double) bkt->avg / 10; burst_bucket_size = 0; } else { /* If we have a burst limit then we have to wait until all I/O * at burst rate has finished before throttling to bkt->avg */ bucket_size = bkt->max * bkt->burst_length; burst_bucket_size = (double) bkt->max / 10; } /* If the main bucket is full then we have to wait */ extra = bkt->level - bucket_size; if (extra > 0) { return throttle_do_compute_wait(bkt->avg, extra); } /* If the main bucket is not full yet we still have to check the * burst bucket in order to enforce the burst limit */ if (bkt->burst_length > 1) { extra = bkt->burst_level - burst_bucket_size; if (extra > 0) { return throttle_do_compute_wait(bkt->max, extra); } } return 0; }


static uint64_t pci_host_data_read(void *opaque, hwaddr addr, unsigned len) { PCIHostState *s = opaque; uint32_t val; if (!(s->config_reg & (1 << 31))) return 0xffffffff; val = pci_data_read(s->bus, s->config_reg | (addr & 3), len); PCI_DPRINTF("read addr " TARGET_FMT_plx " len %d val %x\n", addr, len, val); return val; }


static void test_tco_timeout(void) { TestData d; const uint16_t ticks = TCO_SECS_TO_TICKS(4); uint32_t val; int ret; d.args = NULL; d.noreboot = true; test_init(&d); stop_tco(&d); clear_tco_status(&d); reset_on_second_timeout(false); set_tco_timeout(&d, ticks); load_tco(&d); start_tco(&d); clock_step(ticks * TCO_TICK_NSEC); /* test first timeout */ val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); /* test clearing timeout bit */ val |= TCO_TIMEOUT; qpci_io_writew(d.dev, d.tco_io_base + TCO1_STS, val); val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 0); /* test second timeout */ clock_step(ticks * TCO_TICK_NSEC); val = qpci_io_readw(d.dev, d.tco_io_base + TCO1_STS); ret = val & TCO_TIMEOUT ? 1 : 0; g_assert(ret == 1); val = qpci_io_readw(d.dev, d.tco_io_base + TCO2_STS); ret = val & TCO_SECOND_TO_STS ? 1 : 0; g_assert(ret == 1); stop_tco(&d); qtest_end(); }


hwaddr memory_region_section_get_iotlb(CPUArchState *env, MemoryRegionSection *section, target_ulong vaddr, hwaddr paddr, hwaddr xlat, int prot, target_ulong *address) { hwaddr iotlb; CPUWatchpoint *wp; if (memory_region_is_ram(section->mr)) { /* Normal RAM. */ iotlb = (memory_region_get_ram_addr(section->mr) & TARGET_PAGE_MASK) + xlat; if (!section->readonly) { iotlb |= PHYS_SECTION_NOTDIRTY; } else { iotlb |= PHYS_SECTION_ROM; } } else { iotlb = section - address_space_memory.dispatch->sections; iotlb += xlat; } /* Make accesses to pages with watchpoints go via the watchpoint trap routines. */ QTAILQ_FOREACH(wp, &env->watchpoints, entry) { if (vaddr == (wp->vaddr & TARGET_PAGE_MASK)) { /* Avoid trapping reads of pages with a write breakpoint. */ if ((prot & PAGE_WRITE) || (wp->flags & BP_MEM_READ)) { iotlb = PHYS_SECTION_WATCH + paddr; *address |= TLB_MMIO; break; } } } return iotlb; }


static inline void gen_op_eval_fbule(TCGv dst, TCGv src, unsigned int fcc_offset) { gen_mov_reg_FCC0(dst, src, fcc_offset); tcg_gen_xori_tl(dst, dst, 0x1); gen_mov_reg_FCC1(cpu_tmp0, src, fcc_offset); tcg_gen_and_tl(dst, dst, cpu_tmp0); tcg_gen_xori_tl(dst, dst, 0x1); }


PXA2xxState *pxa255_init(MemoryRegion *address_space, unsigned int sdram_size) { PXA2xxState *s; int i; DriveInfo *dinfo; s = g_new0(PXA2xxState, 1); s->cpu = cpu_arm_init("pxa255"); if (s->cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } s->reset = qemu_allocate_irq(pxa2xx_reset, s, 0); /* SDRAM & Internal Memory Storage */ memory_region_init_ram(&s->sdram, NULL, "pxa255.sdram", sdram_size, &error_fatal); vmstate_register_ram_global(&s->sdram); memory_region_add_subregion(address_space, PXA2XX_SDRAM_BASE, &s->sdram); memory_region_init_ram(&s->internal, NULL, "pxa255.internal", PXA2XX_INTERNAL_SIZE, &error_fatal); vmstate_register_ram_global(&s->internal); memory_region_add_subregion(address_space, PXA2XX_INTERNAL_BASE, &s->internal); s->pic = pxa2xx_pic_init(0x40d00000, s->cpu); s->dma = pxa255_dma_init(0x40000000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_DMA)); sysbus_create_varargs("pxa25x-timer", 0x40a00000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 0), qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 1), qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 2), qdev_get_gpio_in(s->pic, PXA2XX_PIC_OST_0 + 3), NULL); s->gpio = pxa2xx_gpio_init(0x40e00000, s->cpu, s->pic, 85); dinfo = drive_get(IF_SD, 0, 0); if (!dinfo) { fprintf(stderr, "qemu: missing SecureDigital device\n"); exit(1); } s->mmc = pxa2xx_mmci_init(address_space, 0x41100000, blk_by_legacy_dinfo(dinfo), qdev_get_gpio_in(s->pic, PXA2XX_PIC_MMC), qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_MMCI), qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_MMCI)); for (i = 0; pxa255_serial[i].io_base; i++) { if (serial_hds[i]) { serial_mm_init(address_space, pxa255_serial[i].io_base, 2, qdev_get_gpio_in(s->pic, pxa255_serial[i].irqn), 14745600 / 16, serial_hds[i], DEVICE_NATIVE_ENDIAN); } else { break; } } if (serial_hds[i]) s->fir = pxa2xx_fir_init(address_space, 0x40800000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_ICP), qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_ICP), qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_ICP), serial_hds[i]); s->lcd = pxa2xx_lcdc_init(address_space, 0x44000000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_LCD)); s->cm_base = 0x41300000; s->cm_regs[CCCR >> 2] = 0x02000210; /* 416.0 MHz */ s->clkcfg = 0x00000009; /* Turbo mode active */ memory_region_init_io(&s->cm_iomem, NULL, &pxa2xx_cm_ops, s, "pxa2xx-cm", 0x1000); memory_region_add_subregion(address_space, s->cm_base, &s->cm_iomem); vmstate_register(NULL, 0, &vmstate_pxa2xx_cm, s); pxa2xx_setup_cp14(s); s->mm_base = 0x48000000; s->mm_regs[MDMRS >> 2] = 0x00020002; s->mm_regs[MDREFR >> 2] = 0x03ca4000; s->mm_regs[MECR >> 2] = 0x00000001; /* Two PC Card sockets */ memory_region_init_io(&s->mm_iomem, NULL, &pxa2xx_mm_ops, s, "pxa2xx-mm", 0x1000); memory_region_add_subregion(address_space, s->mm_base, &s->mm_iomem); vmstate_register(NULL, 0, &vmstate_pxa2xx_mm, s); s->pm_base = 0x40f00000; memory_region_init_io(&s->pm_iomem, NULL, &pxa2xx_pm_ops, s, "pxa2xx-pm", 0x100); memory_region_add_subregion(address_space, s->pm_base, &s->pm_iomem); vmstate_register(NULL, 0, &vmstate_pxa2xx_pm, s); for (i = 0; pxa255_ssp[i].io_base; i ++); s->ssp = g_new0(SSIBus *, i); for (i = 0; pxa255_ssp[i].io_base; i ++) { DeviceState *dev; dev = sysbus_create_simple(TYPE_PXA2XX_SSP, pxa255_ssp[i].io_base, qdev_get_gpio_in(s->pic, pxa255_ssp[i].irqn)); s->ssp[i] = (SSIBus *)qdev_get_child_bus(dev, "ssi"); } if (usb_enabled()) { sysbus_create_simple("sysbus-ohci", 0x4c000000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_USBH1)); } s->pcmcia[0] = pxa2xx_pcmcia_init(address_space, 0x20000000); s->pcmcia[1] = pxa2xx_pcmcia_init(address_space, 0x30000000); sysbus_create_simple(TYPE_PXA2XX_RTC, 0x40900000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_RTCALARM)); s->i2c[0] = pxa2xx_i2c_init(0x40301600, qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2C), 0xffff); s->i2c[1] = pxa2xx_i2c_init(0x40f00100, qdev_get_gpio_in(s->pic, PXA2XX_PIC_PWRI2C), 0xff); s->i2s = pxa2xx_i2s_init(address_space, 0x40400000, qdev_get_gpio_in(s->pic, PXA2XX_PIC_I2S), qdev_get_gpio_in(s->dma, PXA2XX_RX_RQ_I2S), qdev_get_gpio_in(s->dma, PXA2XX_TX_RQ_I2S)); /* GPIO1 resets the processor */ /* The handler can be overridden by board-specific code */ qdev_connect_gpio_out(s->gpio, 1, s->reset); return s; }


static int jpeg_parse_packet(AVFormatContext *ctx, PayloadContext *jpeg, AVStream *st, AVPacket *pkt, uint32_t *timestamp, const uint8_t *buf, int len, uint16_t seq, int flags) { uint8_t type, q, width, height; const uint8_t *qtables = NULL; uint16_t qtable_len; uint32_t off; int ret; if (len < 8) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; } /* Parse the main JPEG header. */ off = AV_RB24(buf + 1); /* fragment byte offset */ type = AV_RB8(buf + 4); /* id of jpeg decoder params */ q = AV_RB8(buf + 5); /* quantization factor (or table id) */ width = AV_RB8(buf + 6); /* frame width in 8 pixel blocks */ height = AV_RB8(buf + 7); /* frame height in 8 pixel blocks */ buf += 8; len -= 8; /* Parse the restart marker header. */ if (type > 63) { av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG restart marker header.\n"); return AVERROR_PATCHWELCOME; } if (type > 1) { av_log(ctx, AV_LOG_ERROR, "Unimplemented RTP/JPEG type %d\n", type); return AVERROR_PATCHWELCOME; } /* Parse the quantization table header. */ if (off == 0) { /* Start of JPEG data packet. */ uint8_t new_qtables[128]; uint8_t hdr[1024]; if (q > 127) { uint8_t precision; if (len < 4) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; } /* The first byte is reserved for future use. */ precision = AV_RB8(buf + 1); /* size of coefficients */ qtable_len = AV_RB16(buf + 2); /* length in bytes */ buf += 4; len -= 4; if (precision) av_log(ctx, AV_LOG_WARNING, "Only 8-bit precision is supported.\n"); if (qtable_len > 0) { if (len < qtable_len) { av_log(ctx, AV_LOG_ERROR, "Too short RTP/JPEG packet.\n"); return AVERROR_INVALIDDATA; } qtables = buf; buf += qtable_len; len -= qtable_len; if (q < 255) { if (jpeg->qtables_len[q - 128] && (jpeg->qtables_len[q - 128] != qtable_len || memcmp(qtables, &jpeg->qtables[q - 128][0], qtable_len))) { av_log(ctx, AV_LOG_WARNING, "Quantization tables for q=%d changed\n", q); } else if (!jpeg->qtables_len[q - 128] && qtable_len <= 128) { memcpy(&jpeg->qtables[q - 128][0], qtables, qtable_len); jpeg->qtables_len[q - 128] = qtable_len; } } } else { if (q == 255) { av_log(ctx, AV_LOG_ERROR, "Invalid RTP/JPEG packet. Quantization tables not found.\n"); return AVERROR_INVALIDDATA; } if (!jpeg->qtables_len[q - 128]) { av_log(ctx, AV_LOG_ERROR, "No quantization tables known for q=%d yet.\n", q); return AVERROR_INVALIDDATA; } qtables = &jpeg->qtables[q - 128][0]; qtable_len = jpeg->qtables_len[q - 128]; } } else { /* q <= 127 */ if (q == 0 || q > 99) { av_log(ctx, AV_LOG_ERROR, "Reserved q value %d\n", q); return AVERROR_INVALIDDATA; } create_default_qtables(new_qtables, q); qtables = new_qtables; qtable_len = sizeof(new_qtables); } /* Skip the current frame in case of the end packet * has been lost somewhere. */ ffio_free_dyn_buf(&jpeg->frame); if ((ret = avio_open_dyn_buf(&jpeg->frame)) < 0) return ret; jpeg->timestamp = *timestamp; /* Generate a frame and scan headers that can be prepended to the * RTP/JPEG data payload to produce a JPEG compressed image in * interchange format. */ jpeg->hdr_size = jpeg_create_header(hdr, sizeof(hdr), type, width, height, qtables, qtable_len / 64); /* Copy JPEG header to frame buffer. */ avio_write(jpeg->frame, hdr, jpeg->hdr_size); } if (!jpeg->frame) { av_log(ctx, AV_LOG_ERROR, "Received packet without a start chunk; dropping frame.\n"); return AVERROR(EAGAIN); } if (jpeg->timestamp != *timestamp) { /* Skip the current frame if timestamp is incorrect. * A start packet has been lost somewhere. */ ffio_free_dyn_buf(&jpeg->frame); av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match.\n"); return AVERROR_INVALIDDATA; } if (off != avio_tell(jpeg->frame) - jpeg->hdr_size) { av_log(ctx, AV_LOG_ERROR, "Missing packets; dropping frame.\n"); return AVERROR(EAGAIN); } /* Copy data to frame buffer. */ avio_write(jpeg->frame, buf, len); if (flags & RTP_FLAG_MARKER) { /* End of JPEG data packet. */ uint8_t buf[2] = { 0xff, EOI }; /* Put EOI marker. */ avio_write(jpeg->frame, buf, sizeof(buf)); /* Prepare the JPEG packet. */ if ((ret = ff_rtp_finalize_packet(pkt, &jpeg->frame, st->index)) < 0) { av_log(ctx, AV_LOG_ERROR, "Error occurred when getting frame buffer.\n"); return ret; } return 0; } return AVERROR(EAGAIN); }


int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr) { #if defined(KVM_CAP_MCE) struct kvm_x86_mce mce = { .bank = 9, }; void *vaddr; ram_addr_t ram_addr; target_phys_addr_t paddr; int r; if ((env->mcg_cap & MCG_SER_P) && addr && (code == BUS_MCEERR_AR || code == BUS_MCEERR_AO)) { if (code == BUS_MCEERR_AR) { /* Fake an Intel architectural Data Load SRAR UCR */ mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S | MCI_STATUS_AR | 0x134; mce.misc = (MCM_ADDR_PHYS << 6) | 0xc; mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV; } else { /* * If there is an MCE excpetion being processed, ignore * this SRAO MCE */ if (kvm_mce_in_progress(env)) { return 0; } /* Fake an Intel architectural Memory scrubbing UCR */ mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S | 0xc0; mce.misc = (MCM_ADDR_PHYS << 6) | 0xc; mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; } vaddr = (void *)addr; if (qemu_ram_addr_from_host(vaddr, &ram_addr) || !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, &paddr)) { fprintf(stderr, "Hardware memory error for memory used by " "QEMU itself instead of guest system!\n"); /* Hope we are lucky for AO MCE */ if (code == BUS_MCEERR_AO) { return 0; } else { hardware_memory_error(); } } mce.addr = paddr; r = kvm_set_mce(env, &mce); if (r < 0) { fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno)); abort(); } kvm_mce_broadcast_rest(env); } else #endif { if (code == BUS_MCEERR_AO) { return 0; } else if (code == BUS_MCEERR_AR) { hardware_memory_error(); } else { return 1; } } return 0; }


int kvm_has_pit_state2(void) { return 0; }


void mcf_fec_init(MemoryRegion *sysmem, NICInfo *nd, target_phys_addr_t base, qemu_irq *irq) { mcf_fec_state *s; qemu_check_nic_model(nd, "mcf_fec"); s = (mcf_fec_state *)g_malloc0(sizeof(mcf_fec_state)); s->sysmem = sysmem; s->irq = irq; memory_region_init_io(&s->iomem, &mcf_fec_ops, s, "fec", 0x400); memory_region_add_subregion(sysmem, base, &s->iomem); s->conf.macaddr = nd->macaddr; s->conf.peer = nd->netdev; s->nic = qemu_new_nic(&net_mcf_fec_info, &s->conf, nd->model, nd->name, s); qemu_format_nic_info_str(&s->nic->nc, s->conf.macaddr.a); }


static void dec10_reg_scc(DisasContext *dc) { int cond = dc->dst; LOG_DIS("s%s $r%u\n", cc_name(cond), dc->src); if (cond != CC_A) { int l1; gen_tst_cc (dc, cpu_R[dc->src], cond); l1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_R[dc->src], 0, l1); tcg_gen_movi_tl(cpu_R[dc->src], 1); gen_set_label(l1); } else { tcg_gen_movi_tl(cpu_R[dc->src], 1); } cris_cc_mask(dc, 0); }


void armv7m_nvic_acknowledge_irq(void *opaque) { NVICState *s = (NVICState *)opaque; CPUARMState *env = &s->cpu->env; const int pending = s->vectpending; const int running = nvic_exec_prio(s); int pendgroupprio; VecInfo *vec; assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); vec = &s->vectors[pending]; assert(vec->enabled); assert(vec->pending); pendgroupprio = vec->prio; if (pendgroupprio > 0) { pendgroupprio &= nvic_gprio_mask(s); } assert(pendgroupprio < running); trace_nvic_acknowledge_irq(pending, vec->prio); vec->active = 1; vec->pending = 0; env->v7m.exception = s->vectpending; nvic_irq_update(s); }


static CharDriverState *text_console_init(ChardevVC *vc) { CharDriverState *chr; QemuConsole *s; unsigned width = 0; unsigned height = 0; chr = g_malloc0(sizeof(CharDriverState)); if (vc->has_width) { width = vc->width; } else if (vc->has_cols) { width = vc->cols * FONT_WIDTH; } if (vc->has_height) { height = vc->height; } else if (vc->has_rows) { height = vc->rows * FONT_HEIGHT; } trace_console_txt_new(width, height); if (width == 0 || height == 0) { s = new_console(NULL, TEXT_CONSOLE, 0); } else { s = new_console(NULL, TEXT_CONSOLE_FIXED_SIZE, 0); s->surface = qemu_create_displaysurface(width, height); } if (!s) { g_free(chr); return NULL; } s->chr = chr; chr->opaque = s; chr->chr_set_echo = text_console_set_echo; /* console/chardev init sometimes completes elsewhere in a 2nd * stage, so defer OPENED events until they are fully initialized */ chr->explicit_be_open = true; if (display_state) { text_console_do_init(chr, display_state); } return chr; }


static char *spapr_vio_get_dev_name(DeviceState *qdev) { VIOsPAPRDevice *dev = VIO_SPAPR_DEVICE(qdev); VIOsPAPRDeviceClass *pc = VIO_SPAPR_DEVICE_GET_CLASS(dev); char *name; /* Device tree style name device@reg */ name = g_strdup_printf("%s@%x", pc->dt_name, dev->reg); return name; }