static void tricore_testboard_init(MachineState *machine, int board_id) { TriCoreCPU *cpu; CPUTriCoreState *env; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ext_cram = g_new(MemoryRegion, 1); MemoryRegion *ext_dram = g_new(MemoryRegion, 1); MemoryRegion *int_cram = g_new(MemoryRegion, 1); MemoryRegion *int_dram = g_new(MemoryRegion, 1); MemoryRegion *pcp_data = g_new(MemoryRegion, 1); MemoryRegion *pcp_text = g_new(MemoryRegion, 1); if (!machine->cpu_model) { machine->cpu_model = "tc1796"; } cpu = cpu_tricore_init(machine->cpu_model); if (!cpu) { error_report("Unable to find CPU definition"); exit(1); } env = &cpu->env; memory_region_init_ram(ext_cram, NULL, "powerlink_ext_c.ram", 2*1024*1024, &error_abort); vmstate_register_ram_global(ext_cram); memory_region_init_ram(ext_dram, NULL, "powerlink_ext_d.ram", 4*1024*1024, &error_abort); vmstate_register_ram_global(ext_dram); memory_region_init_ram(int_cram, NULL, "powerlink_int_c.ram", 48*1024, &error_abort); vmstate_register_ram_global(int_cram); memory_region_init_ram(int_dram, NULL, "powerlink_int_d.ram", 48*1024, &error_abort); vmstate_register_ram_global(int_dram); memory_region_init_ram(pcp_data, NULL, "powerlink_pcp_data.ram", 16*1024, &error_abort); vmstate_register_ram_global(pcp_data); memory_region_init_ram(pcp_text, NULL, "powerlink_pcp_text.ram", 32*1024, &error_abort); vmstate_register_ram_global(pcp_text); memory_region_add_subregion(sysmem, 0x80000000, ext_cram); memory_region_add_subregion(sysmem, 0xa1000000, ext_dram); memory_region_add_subregion(sysmem, 0xd4000000, int_cram); memory_region_add_subregion(sysmem, 0xd0000000, int_dram); memory_region_add_subregion(sysmem, 0xf0050000, pcp_data); memory_region_add_subregion(sysmem, 0xf0060000, pcp_text); tricoretb_binfo.ram_size = machine->ram_size; tricoretb_binfo.kernel_filename = machine->kernel_filename; if (machine->kernel_filename) { tricore_load_kernel(env); } }


static void ahci_write_fis_sdb(AHCIState *s, int port, uint32_t finished) { AHCIPortRegs *pr = &s->dev[port].port_regs; IDEState *ide_state; uint8_t *sdb_fis; if (!s->dev[port].res_fis || !(pr->cmd & PORT_CMD_FIS_RX)) { return; } sdb_fis = &s->dev[port].res_fis[RES_FIS_SDBFIS]; ide_state = &s->dev[port].port.ifs[0]; /* clear memory */ *(uint32_t*)sdb_fis = 0; /* write values */ sdb_fis[0] = ide_state->error; sdb_fis[2] = ide_state->status & 0x77; s->dev[port].finished |= finished; *(uint32_t*)(sdb_fis + 4) = cpu_to_le32(s->dev[port].finished); ahci_trigger_irq(s, &s->dev[port], PORT_IRQ_SDB_FIS); }


int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name, void *value, size_t size, int flags) { XattrOperations *xops = get_xattr_operations(ctx->xops, name); if (xops) { return xops->setxattr(ctx, path, name, value, size, flags); } errno = -EOPNOTSUPP; return -1; }


void kvm_irqchip_add_irq_route(KVMState *s, int irq, int irqchip, int pin) { struct kvm_irq_routing_entry e; assert(pin < s->gsi_count); e.gsi = irq; e.type = KVM_IRQ_ROUTING_IRQCHIP; e.flags = 0; e.u.irqchip.irqchip = irqchip; e.u.irqchip.pin = pin; kvm_add_routing_entry(s, &e); }


static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2) { TCGv_i32 t0; int l1, l2; l1 = gen_new_label(); l2 = gen_new_label(); t0 = tcg_temp_local_new_i32(); /* No error here: 6 bits are used */ tcg_gen_andi_i32(t0, arg2, 0x3F); tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1); tcg_gen_shr_i32(ret, arg1, t0); tcg_gen_br(l2); gen_set_label(l1); tcg_gen_movi_i32(ret, 0); gen_set_label(l2); tcg_temp_free_i32(t0); }


static int hqx_decode_frame(AVCodecContext *avctx, void *data, int *got_picture_ptr, AVPacket *avpkt) { HQXContext *ctx = avctx->priv_data; uint8_t *src = avpkt->data; uint32_t info_tag; int data_start; int i, ret; if (avpkt->size < 4 + 4) { av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); return AVERROR_INVALIDDATA; } info_tag = AV_RL32(src); if (info_tag == MKTAG('I', 'N', 'F', 'O')) { int info_offset = AV_RL32(src + 4); if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) { av_log(avctx, AV_LOG_ERROR, "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", info_offset); return AVERROR_INVALIDDATA; } ff_canopus_parse_info_tag(avctx, src + 8, info_offset); info_offset += 8; src += info_offset; } data_start = src - avpkt->data; ctx->data_size = avpkt->size - data_start; ctx->src = src; ctx->pic = data; if (ctx->data_size < HQX_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "Frame too small.\n"); return AVERROR_INVALIDDATA; } if (src[0] != 'H' || src[1] != 'Q') { av_log(avctx, AV_LOG_ERROR, "Not an HQX frame.\n"); return AVERROR_INVALIDDATA; } ctx->interlaced = !(src[2] & 0x80); ctx->format = src[2] & 7; ctx->dcb = (src[3] & 3) + 8; ctx->width = AV_RB16(src + 4); ctx->height = AV_RB16(src + 6); for (i = 0; i < 17; i++) ctx->slice_off[i] = AV_RB24(src + 8 + i * 3); if (ctx->dcb == 8) { av_log(avctx, AV_LOG_ERROR, "Invalid DC precision %d.\n", ctx->dcb); return AVERROR_INVALIDDATA; } ret = av_image_check_size(ctx->width, ctx->height, 0, avctx); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Invalid stored dimenstions %dx%d.\n", ctx->width, ctx->height); return AVERROR_INVALIDDATA; } avctx->coded_width = FFALIGN(ctx->width, 16); avctx->coded_height = FFALIGN(ctx->height, 16); avctx->width = ctx->width; avctx->height = ctx->height; avctx->bits_per_raw_sample = 10; switch (ctx->format) { case HQX_422: avctx->pix_fmt = AV_PIX_FMT_YUV422P16; ctx->decode_func = hqx_decode_422; break; case HQX_444: avctx->pix_fmt = AV_PIX_FMT_YUV444P16; ctx->decode_func = hqx_decode_444; break; case HQX_422A: avctx->pix_fmt = AV_PIX_FMT_YUVA422P16; ctx->decode_func = hqx_decode_422a; break; case HQX_444A: avctx->pix_fmt = AV_PIX_FMT_YUVA444P16; ctx->decode_func = hqx_decode_444a; break; default: av_log(avctx, AV_LOG_ERROR, "Invalid format: %d.\n", ctx->format); return AVERROR_INVALIDDATA; } ret = ff_get_buffer(avctx, ctx->pic, 0); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return ret; } avctx->execute2(avctx, decode_slice_thread, NULL, NULL, 16); ctx->pic->key_frame = 1; ctx->pic->pict_type = AV_PICTURE_TYPE_I; *got_picture_ptr = 1; return avpkt->size; }


START_TEST(qlist_append_test) { QInt *qi; QList *qlist; QListEntry *entry; qi = qint_from_int(42); qlist = qlist_new(); qlist_append(qlist, qi); entry = QTAILQ_FIRST(&qlist->head); fail_unless(entry != NULL); fail_unless(entry->value == QOBJECT(qi)); // destroy doesn't exist yet QDECREF(qi); g_free(entry); g_free(qlist); }


static int parse_chr(DeviceState *dev, Property *prop, const char *str) { CharDriverState **ptr = qdev_get_prop_ptr(dev, prop); *ptr = qemu_chr_find(str); if (*ptr == NULL) return -ENOENT; return 0; }


static unsigned virtio_pci_get_features(void *opaque) { unsigned ret = 0; ret |= (1 << VIRTIO_F_NOTIFY_ON_EMPTY); ret |= (1 << VIRTIO_RING_F_INDIRECT_DESC); ret |= (1 << VIRTIO_F_BAD_FEATURE); return ret; }


target_ulong HELPER(mfspr)(CPUOpenRISCState *env, target_ulong rd, target_ulong ra, uint32_t offset) { #ifndef CONFIG_USER_ONLY int spr = (ra | offset); int idx; OpenRISCCPU *cpu = openrisc_env_get_cpu(env); switch (spr) { case TO_SPR(0, 0): /* VR */ return env->vr & SPR_VR; case TO_SPR(0, 1): /* UPR */ return env->upr; /* TT, DM, IM, UP present */ case TO_SPR(0, 2): /* CPUCFGR */ return env->cpucfgr; case TO_SPR(0, 3): /* DMMUCFGR */ return env->dmmucfgr; /* 1Way, 64 entries */ case TO_SPR(0, 4): /* IMMUCFGR */ return env->immucfgr; case TO_SPR(0, 16): /* NPC */ return env->npc; case TO_SPR(0, 17): /* SR */ return env->sr; case TO_SPR(0, 18): /* PPC */ return env->ppc; case TO_SPR(0, 32): /* EPCR */ return env->epcr; case TO_SPR(0, 48): /* EEAR */ return env->eear; case TO_SPR(0, 64): /* ESR */ return env->esr; case TO_SPR(1, 512) ... TO_SPR(1, 639): /* DTLBW0MR 0-127 */ idx = spr - TO_SPR(1, 512); return env->tlb->dtlb[0][idx].mr; case TO_SPR(1, 640) ... TO_SPR(1, 767): /* DTLBW0TR 0-127 */ idx = spr - TO_SPR(1, 640); return env->tlb->dtlb[0][idx].tr; case TO_SPR(1, 768) ... TO_SPR(1, 895): /* DTLBW1MR 0-127 */ case TO_SPR(1, 896) ... TO_SPR(1, 1023): /* DTLBW1TR 0-127 */ case TO_SPR(1, 1024) ... TO_SPR(1, 1151): /* DTLBW2MR 0-127 */ case TO_SPR(1, 1152) ... TO_SPR(1, 1279): /* DTLBW2TR 0-127 */ case TO_SPR(1, 1280) ... TO_SPR(1, 1407): /* DTLBW3MR 0-127 */ case TO_SPR(1, 1408) ... TO_SPR(1, 1535): /* DTLBW3TR 0-127 */ break; case TO_SPR(2, 512) ... TO_SPR(2, 639): /* ITLBW0MR 0-127 */ idx = spr - TO_SPR(2, 512); return env->tlb->itlb[0][idx].mr; case TO_SPR(2, 640) ... TO_SPR(2, 767): /* ITLBW0TR 0-127 */ idx = spr - TO_SPR(2, 640); return env->tlb->itlb[0][idx].tr; case TO_SPR(2, 768) ... TO_SPR(2, 895): /* ITLBW1MR 0-127 */ case TO_SPR(2, 896) ... TO_SPR(2, 1023): /* ITLBW1TR 0-127 */ case TO_SPR(2, 1024) ... TO_SPR(2, 1151): /* ITLBW2MR 0-127 */ case TO_SPR(2, 1152) ... TO_SPR(2, 1279): /* ITLBW2TR 0-127 */ case TO_SPR(2, 1280) ... TO_SPR(2, 1407): /* ITLBW3MR 0-127 */ case TO_SPR(2, 1408) ... TO_SPR(2, 1535): /* ITLBW3TR 0-127 */ break; case TO_SPR(9, 0): /* PICMR */ return env->picmr; case TO_SPR(9, 2): /* PICSR */ return env->picsr; case TO_SPR(10, 0): /* TTMR */ return env->ttmr; case TO_SPR(10, 1): /* TTCR */ cpu_openrisc_count_update(cpu); return env->ttcr; default: break; } #endif /*If we later need to add tracepoints (or debug printfs) for the return value, it may be useful to structure the code like this: target_ulong ret = 0; switch() { case x: ret = y; break; case z: ret = 42; break; ... } later something like trace_spr_read(ret); return ret;*/ /* for rd is passed in, if rd unchanged, just keep it back. */ return rd; }


ssize_t virtio_pdu_vunmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, va_list ap) { V9fsState *s = pdu->s; V9fsVirtioState *v = container_of(s, V9fsVirtioState, state); VirtQueueElement *elem = &v->elems[pdu->idx]; return v9fs_iov_vunmarshal(elem->out_sg, elem->out_num, offset, 1, fmt, ap); }


void do_td (int flags) { if (!likely(!(((int64_t)T0 < (int64_t)T1 && (flags & 0x10)) || ((int64_t)T0 > (int64_t)T1 && (flags & 0x08)) || ((int64_t)T0 == (int64_t)T1 && (flags & 0x04)) || ((uint64_t)T0 < (uint64_t)T1 && (flags & 0x02)) || ((uint64_t)T0 > (uint64_t)T1 && (flags & 0x01))))) do_raise_exception_err(EXCP_PROGRAM, EXCP_TRAP); }


static ssize_t block_crypto_read_func(QCryptoBlock *block, void *opaque, size_t offset, uint8_t *buf, size_t buflen, Error **errp) { BlockDriverState *bs = opaque; ssize_t ret; ret = bdrv_pread(bs->file, offset, buf, buflen); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read encryption header"); return ret; } return ret; }


vnc_display_setup_auth(VncDisplay *vd, bool password, bool sasl, bool websocket, Error **errp) { /* * We have a choice of 3 authentication options * * 1. none * 2. vnc * 3. sasl * * The channel can be run in 2 modes * * 1. clear * 2. tls * * And TLS can use 2 types of credentials * * 1. anon * 2. x509 * * We thus have 9 possible logical combinations * * 1. clear + none * 2. clear + vnc * 3. clear + sasl * 4. tls + anon + none * 5. tls + anon + vnc * 6. tls + anon + sasl * 7. tls + x509 + none * 8. tls + x509 + vnc * 9. tls + x509 + sasl * * These need to be mapped into the VNC auth schemes * in an appropriate manner. In regular VNC, all the * TLS options get mapped into VNC_AUTH_VENCRYPT * sub-auth types. * * In websockets, the https:// protocol already provides * TLS support, so there is no need to make use of the * VeNCrypt extension. Furthermore, websockets browser * clients could not use VeNCrypt even if they wanted to, * as they cannot control when the TLS handshake takes * place. Thus there is no option but to rely on https://, * meaning combinations 4->6 and 7->9 will be mapped to * VNC auth schemes in the same way as combos 1->3. * * Regardless of fact that we have a different mapping to * VNC auth mechs for plain VNC vs websockets VNC, the end * result has the same security characteristics. */ if (password) { if (vd->tlscreds) { vd->auth = VNC_AUTH_VENCRYPT; if (object_dynamic_cast(OBJECT(vd->tlscreds), TYPE_QCRYPTO_TLS_CREDS_X509)) { VNC_DEBUG("Initializing VNC server with x509 password auth\n"); vd->subauth = VNC_AUTH_VENCRYPT_X509VNC; } else if (object_dynamic_cast(OBJECT(vd->tlscreds), TYPE_QCRYPTO_TLS_CREDS_ANON)) { VNC_DEBUG("Initializing VNC server with TLS password auth\n"); vd->subauth = VNC_AUTH_VENCRYPT_TLSVNC; } else { error_setg(errp, "Unsupported TLS cred type %s", object_get_typename(OBJECT(vd->tlscreds))); return -1; } } else { VNC_DEBUG("Initializing VNC server with password auth\n"); vd->auth = VNC_AUTH_VNC; vd->subauth = VNC_AUTH_INVALID; } if (websocket) { vd->ws_auth = VNC_AUTH_VNC; } else { vd->ws_auth = VNC_AUTH_INVALID; } } else if (sasl) { if (vd->tlscreds) { vd->auth = VNC_AUTH_VENCRYPT; if (object_dynamic_cast(OBJECT(vd->tlscreds), TYPE_QCRYPTO_TLS_CREDS_X509)) { VNC_DEBUG("Initializing VNC server with x509 SASL auth\n"); vd->subauth = VNC_AUTH_VENCRYPT_X509SASL; } else if (object_dynamic_cast(OBJECT(vd->tlscreds), TYPE_QCRYPTO_TLS_CREDS_ANON)) { VNC_DEBUG("Initializing VNC server with TLS SASL auth\n"); vd->subauth = VNC_AUTH_VENCRYPT_TLSSASL; } else { error_setg(errp, "Unsupported TLS cred type %s", object_get_typename(OBJECT(vd->tlscreds))); return -1; } } else { VNC_DEBUG("Initializing VNC server with SASL auth\n"); vd->auth = VNC_AUTH_SASL; vd->subauth = VNC_AUTH_INVALID; } if (websocket) { vd->ws_auth = VNC_AUTH_SASL; } else { vd->ws_auth = VNC_AUTH_INVALID; } } else { if (vd->tlscreds) { vd->auth = VNC_AUTH_VENCRYPT; if (object_dynamic_cast(OBJECT(vd->tlscreds), TYPE_QCRYPTO_TLS_CREDS_X509)) { VNC_DEBUG("Initializing VNC server with x509 no auth\n"); vd->subauth = VNC_AUTH_VENCRYPT_X509NONE; } else if (object_dynamic_cast(OBJECT(vd->tlscreds), TYPE_QCRYPTO_TLS_CREDS_ANON)) { VNC_DEBUG("Initializing VNC server with TLS no auth\n"); vd->subauth = VNC_AUTH_VENCRYPT_TLSNONE; } else { error_setg(errp, "Unsupported TLS cred type %s", object_get_typename(OBJECT(vd->tlscreds))); return -1; } } else { VNC_DEBUG("Initializing VNC server with no auth\n"); vd->auth = VNC_AUTH_NONE; vd->subauth = VNC_AUTH_INVALID; } if (websocket) { vd->ws_auth = VNC_AUTH_NONE; } else { vd->ws_auth = VNC_AUTH_INVALID; } } return 0; }


static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, off_t offset) { phdr->p_type = PT_NOTE; phdr->p_offset = offset; phdr->p_vaddr = 0; phdr->p_paddr = 0; phdr->p_filesz = sz; phdr->p_memsz = 0; phdr->p_flags = 0; phdr->p_align = 0; #ifdef BSWAP_NEEDED bswap_phdr(phdr); #endif }


static av_cold int vaapi_encode_mjpeg_init_internal(AVCodecContext *avctx) { static const VAConfigAttrib default_config_attributes[] = { { .type = VAConfigAttribRTFormat, .value = VA_RT_FORMAT_YUV420 }, { .type = VAConfigAttribEncPackedHeaders, .value = VA_ENC_PACKED_HEADER_SEQUENCE }, }; VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodeMJPEGContext *priv = ctx->priv_data; int i; ctx->va_profile = VAProfileJPEGBaseline; ctx->va_entrypoint = VAEntrypointEncPicture; ctx->input_width = avctx->width; ctx->input_height = avctx->height; ctx->aligned_width = FFALIGN(ctx->input_width, 8); ctx->aligned_height = FFALIGN(ctx->input_height, 8); for (i = 0; i < FF_ARRAY_ELEMS(default_config_attributes); i++) { ctx->config_attributes[ctx->nb_config_attributes++] = default_config_attributes[i]; } priv->quality = avctx->global_quality; if (priv->quality < 1 || priv->quality > 100) { av_log(avctx, AV_LOG_ERROR, "Invalid quality value %d " "(must be 1-100).\n", priv->quality); return AVERROR(EINVAL); } vaapi_encode_mjpeg_init_tables(avctx); return 0; }


static gboolean tcp_chr_chan_close(GIOChannel *channel, GIOCondition cond, void *opaque) { CharDriverState *chr = opaque; if (cond != G_IO_HUP) { return FALSE; } /* connection closed */ tcp_chr_disconnect(chr); if (chr->fd_hup_tag) { g_source_remove(chr->fd_hup_tag); chr->fd_hup_tag = 0; } return TRUE; }


static void rtas_ibm_configure_pe(PowerPCCPU *cpu, sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { sPAPRPHBState *sphb; sPAPRPHBClass *spc; uint64_t buid; int ret; if ((nargs != 3) || (nret != 1)) { goto param_error_exit; } buid = ((uint64_t)rtas_ld(args, 1) << 32) | rtas_ld(args, 2); sphb = find_phb(spapr, buid); if (!sphb) { goto param_error_exit; } spc = SPAPR_PCI_HOST_BRIDGE_GET_CLASS(sphb); if (!spc->eeh_configure) { goto param_error_exit; } ret = spc->eeh_configure(sphb); rtas_st(rets, 0, ret); return; param_error_exit: rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); }


static void sigp_cpu_start(void *arg) { CPUState *cs = arg; S390CPU *cpu = S390_CPU(cs); s390_cpu_set_state(CPU_STATE_OPERATING, cpu); DPRINTF("DONE: KVM cpu start: %p\n", &cpu->env); }


static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) { int k, l; int subsubframe = s->current_subsubframe; const float *quant_step_table; /* FIXME */ float (*subband_samples)[DCA_SUBBANDS][8] = s->subband_samples[block_index]; LOCAL_ALIGNED_16(int32_t, block, [8 * DCA_SUBBANDS]); /* * Audio data */ /* Select quantization step size table */ if (s->bit_rate_index == 0x1f) quant_step_table = lossless_quant_d; else quant_step_table = lossy_quant_d; for (k = base_channel; k < s->prim_channels; k++) { float rscale[DCA_SUBBANDS]; if (get_bits_left(&s->gb) < 0) return AVERROR_INVALIDDATA; for (l = 0; l < s->vq_start_subband[k]; l++) { int m; /* Select the mid-tread linear quantizer */ int abits = s->bitalloc[k][l]; float quant_step_size = quant_step_table[abits]; /* * Determine quantization index code book and its type */ /* Select quantization index code book */ int sel = s->quant_index_huffman[k][abits]; /* * Extract bits from the bit stream */ if (!abits) { rscale[l] = 0; memset(block + 8 * l, 0, 8 * sizeof(block[0])); } else { /* Deal with transients */ int sfi = s->transition_mode[k][l] && subsubframe >= s->transition_mode[k][l]; rscale[l] = quant_step_size * s->scale_factor[k][l][sfi] * s->scalefactor_adj[k][sel]; if (abits >= 11 || !dca_smpl_bitalloc[abits].vlc[sel].table) { if (abits <= 7) { /* Block code */ int block_code1, block_code2, size, levels, err; size = abits_sizes[abits - 1]; levels = abits_levels[abits - 1]; block_code1 = get_bits(&s->gb, size); block_code2 = get_bits(&s->gb, size); err = decode_blockcodes(block_code1, block_code2, levels, block + 8 * l); if (err) { av_log(s->avctx, AV_LOG_ERROR, "ERROR: block code look-up failed\n"); return AVERROR_INVALIDDATA; } } else { /* no coding */ for (m = 0; m < 8; m++) block[8 * l + m] = get_sbits(&s->gb, abits - 3); } } else { /* Huffman coded */ for (m = 0; m < 8; m++) block[8 * l + m] = get_bitalloc(&s->gb, &dca_smpl_bitalloc[abits], sel); } } } s->fmt_conv.int32_to_float_fmul_array8(&s->fmt_conv, subband_samples[k][0], block, rscale, 8 * s->vq_start_subband[k]); for (l = 0; l < s->vq_start_subband[k]; l++) { int m; /* * Inverse ADPCM if in prediction mode */ if (s->prediction_mode[k][l]) { int n; if (s->predictor_history) subband_samples[k][l][0] += (adpcm_vb[s->prediction_vq[k][l]][0] * s->subband_samples_hist[k][l][3] + adpcm_vb[s->prediction_vq[k][l]][1] * s->subband_samples_hist[k][l][2] + adpcm_vb[s->prediction_vq[k][l]][2] * s->subband_samples_hist[k][l][1] + adpcm_vb[s->prediction_vq[k][l]][3] * s->subband_samples_hist[k][l][0]) * (1.0f / 8192); for (m = 1; m < 8; m++) { float sum = adpcm_vb[s->prediction_vq[k][l]][0] * subband_samples[k][l][m - 1]; for (n = 2; n <= 4; n++) if (m >= n) sum += adpcm_vb[s->prediction_vq[k][l]][n - 1] * subband_samples[k][l][m - n]; else if (s->predictor_history) sum += adpcm_vb[s->prediction_vq[k][l]][n - 1] * s->subband_samples_hist[k][l][m - n + 4]; subband_samples[k][l][m] += sum * 1.0f / 8192; } } } /* * Decode VQ encoded high frequencies */ for (l = s->vq_start_subband[k]; l < s->subband_activity[k]; l++) { /* 1 vector -> 32 samples but we only need the 8 samples * for this subsubframe. */ int hfvq = s->high_freq_vq[k][l]; if (!s->debug_flag & 0x01) { av_log(s->avctx, AV_LOG_DEBUG, "Stream with high frequencies VQ coding\n"); s->debug_flag |= 0x01; } int8x8_fmul_int32(&s->dcadsp, subband_samples[k][l], &high_freq_vq[hfvq][subsubframe * 8], s->scale_factor[k][l][0]); } } /* Check for DSYNC after subsubframe */ if (s->aspf || subsubframe == s->subsubframes[s->current_subframe] - 1) { if (0xFFFF == get_bits(&s->gb, 16)) { /* 0xFFFF */ #ifdef TRACE av_log(s->avctx, AV_LOG_DEBUG, "Got subframe DSYNC\n"); #endif } else { av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n"); return AVERROR_INVALIDDATA; } } /* Backup predictor history for adpcm */ for (k = base_channel; k < s->prim_channels; k++) for (l = 0; l < s->vq_start_subband[k]; l++) AV_COPY128(s->subband_samples_hist[k][l], &subband_samples[k][l][4]); return 0; }


int ff_mpeg_update_thread_context(AVCodecContext *dst, const AVCodecContext *src) { int i; MpegEncContext *s = dst->priv_data, *s1 = src->priv_data; if (dst == src) return 0; // FIXME can parameters change on I-frames? // in that case dst may need a reinit if (!s->context_initialized) { memcpy(s, s1, sizeof(MpegEncContext)); s->avctx = dst; s->bitstream_buffer = NULL; s->bitstream_buffer_size = s->allocated_bitstream_buffer_size = 0; if (s1->context_initialized){ s->picture_range_start += MAX_PICTURE_COUNT; s->picture_range_end += MAX_PICTURE_COUNT; ff_MPV_common_init(s); } } if (s->height != s1->height || s->width != s1->width || s->context_reinit) { int err; s->context_reinit = 0; s->height = s1->height; s->width = s1->width; if ((err = ff_MPV_common_frame_size_change(s)) < 0) return err; } s->avctx->coded_height = s1->avctx->coded_height; s->avctx->coded_width = s1->avctx->coded_width; s->avctx->width = s1->avctx->width; s->avctx->height = s1->avctx->height; s->coded_picture_number = s1->coded_picture_number; s->picture_number = s1->picture_number; s->input_picture_number = s1->input_picture_number; memcpy(s->picture, s1->picture, s1->picture_count * sizeof(Picture)); memcpy(&s->last_picture, &s1->last_picture, (char *) &s1->last_picture_ptr - (char *) &s1->last_picture); // reset s->picture[].f.extended_data to s->picture[].f.data for (i = 0; i < s->picture_count; i++) s->picture[i].f.extended_data = s->picture[i].f.data; s->last_picture_ptr = REBASE_PICTURE(s1->last_picture_ptr, s, s1); s->current_picture_ptr = REBASE_PICTURE(s1->current_picture_ptr, s, s1); s->next_picture_ptr = REBASE_PICTURE(s1->next_picture_ptr, s, s1); // Error/bug resilience s->next_p_frame_damaged = s1->next_p_frame_damaged; s->workaround_bugs = s1->workaround_bugs; s->padding_bug_score = s1->padding_bug_score; // MPEG4 timing info memcpy(&s->time_increment_bits, &s1->time_increment_bits, (char *) &s1->shape - (char *) &s1->time_increment_bits); // B-frame info s->max_b_frames = s1->max_b_frames; s->low_delay = s1->low_delay; s->dropable = s1->dropable; // DivX handling (doesn't work) s->divx_packed = s1->divx_packed; if (s1->bitstream_buffer) { if (s1->bitstream_buffer_size + FF_INPUT_BUFFER_PADDING_SIZE > s->allocated_bitstream_buffer_size) av_fast_malloc(&s->bitstream_buffer, &s->allocated_bitstream_buffer_size, s1->allocated_bitstream_buffer_size); s->bitstream_buffer_size = s1->bitstream_buffer_size; memcpy(s->bitstream_buffer, s1->bitstream_buffer, s1->bitstream_buffer_size); memset(s->bitstream_buffer + s->bitstream_buffer_size, 0, FF_INPUT_BUFFER_PADDING_SIZE); } // MPEG2/interlacing info memcpy(&s->progressive_sequence, &s1->progressive_sequence, (char *) &s1->rtp_mode - (char *) &s1->progressive_sequence); if (!s1->first_field) { s->last_pict_type = s1->pict_type; if (s1->current_picture_ptr) s->last_lambda_for[s1->pict_type] = s1->current_picture_ptr->f.quality; if (s1->pict_type != AV_PICTURE_TYPE_B) { s->last_non_b_pict_type = s1->pict_type; } } return 0; }


static int h261_probe(AVProbeData *p) { int code; const uint8_t *d; if (p->buf_size < 6) return 0; d = p->buf; code = (d[0] << 12) | (d[1] << 4) | (d[2] >> 4); if (code == 0x10) { return 50; } return 0; }


static void netfilter_finalize(Object *obj) { NetFilterState *nf = NETFILTER(obj); NetFilterClass *nfc = NETFILTER_GET_CLASS(obj); if (nfc->cleanup) { nfc->cleanup(nf); } if (nf->netdev && !QTAILQ_EMPTY(&nf->netdev->filters) && nf->next.tqe_prev) { QTAILQ_REMOVE(&nf->netdev->filters, nf, next); } g_free(nf->netdev_id); }


static void ne2000_cleanup(NetClientState *nc) { NE2000State *s = qemu_get_nic_opaque(nc); s->nic = NULL; }


static void sys_write(void *opaque, hwaddr addr, uint64_t value, unsigned size) { LM32SysState *s = opaque; char *testname; trace_lm32_sys_memory_write(addr, value); addr >>= 2; switch (addr) { case R_CTRL: qemu_system_shutdown_request(); break; case R_PASSFAIL: s->regs[addr] = value; testname = (char *)s->testname; qemu_log("TC %-16s %s\n", testname, (value) ? "FAILED" : "OK"); break; case R_TESTNAME: s->regs[addr] = value; copy_testname(s); break; default: error_report("lm32_sys: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } }


static DeviceState *qbus_find_dev(BusState *bus, char *elem) { DeviceState *dev; /* * try to match in order: * (1) instance id, if present * (2) driver name * (3) driver alias, if present */ LIST_FOREACH(dev, &bus->children, sibling) { if (dev->id && strcmp(dev->id, elem) == 0) { return dev; } } LIST_FOREACH(dev, &bus->children, sibling) { if (strcmp(dev->info->name, elem) == 0) { return dev; } } LIST_FOREACH(dev, &bus->children, sibling) { if (dev->info->alias && strcmp(dev->info->alias, elem) == 0) { return dev; } } return NULL; }


void scsi_req_cancel_async(SCSIRequest *req, Notifier *notifier) { trace_scsi_req_cancel(req->dev->id, req->lun, req->tag); if (notifier) { notifier_list_add(&req->cancel_notifiers, notifier); } if (req->io_canceled) { return; } scsi_req_ref(req); scsi_req_dequeue(req); req->io_canceled = true; if (req->aiocb) { bdrv_aio_cancel_async(req->aiocb); } }


static inline void temp_save(TCGContext *s, TCGTemp *ts, TCGRegSet allocated_regs) { #ifdef USE_LIVENESS_ANALYSIS /* ??? Liveness does not yet incorporate indirect bases. */ if (!ts->indirect_base) { /* The liveness analysis already ensures that globals are back in memory. Keep an assert for safety. */ tcg_debug_assert(ts->val_type == TEMP_VAL_MEM || ts->fixed_reg); return; } #endif temp_sync(s, ts, allocated_regs); temp_dead(s, ts); }


static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; if (c->fc->nb_streams < 1) return 0; st = c->fc->streams[c->fc->nb_streams-1]; ff_get_wav_header(pb, st->codec, atom.size); return 0; }


static void register_multipage(AddressSpaceDispatch *d, MemoryRegionSection *section) { target_phys_addr_t start_addr = section->offset_within_address_space; ram_addr_t size = section->size; target_phys_addr_t addr; uint16_t section_index = phys_section_add(section); assert(size); addr = start_addr; phys_page_set(d, addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS, section_index); }


static int IRQ_get_next(OpenPICState *opp, IRQQueue *q) { if (q->next == -1) { /* XXX: optimize */ IRQ_check(opp, q); } return q->next; }


static int enable_write_target(BDRVVVFATState *s) { BlockDriver *bdrv_qcow; QEMUOptionParameter *options; Error *local_err = NULL; int ret; int size = sector2cluster(s, s->sector_count); s->used_clusters = calloc(size, 1); array_init(&(s->commits), sizeof(commit_t)); s->qcow_filename = g_malloc(1024); ret = get_tmp_filename(s->qcow_filename, 1024); if (ret < 0) { goto err; } bdrv_qcow = bdrv_find_format("qcow"); options = parse_option_parameters("", bdrv_qcow->create_options, NULL); set_option_parameter_int(options, BLOCK_OPT_SIZE, s->sector_count * 512); set_option_parameter(options, BLOCK_OPT_BACKING_FILE, "fat:"); ret = bdrv_create(bdrv_qcow, s->qcow_filename, options, &local_err); if (ret < 0) { qerror_report_err(local_err); error_free(local_err); goto err; } s->qcow = NULL; ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, bdrv_qcow, &local_err); if (ret < 0) { qerror_report_err(local_err); error_free(local_err); goto err; } #ifndef _WIN32 unlink(s->qcow_filename); #endif s->bs->backing_hd = bdrv_new(""); s->bs->backing_hd->drv = &vvfat_write_target; s->bs->backing_hd->opaque = g_malloc(sizeof(void*)); *(void**)s->bs->backing_hd->opaque = s; return 0; err: g_free(s->qcow_filename); s->qcow_filename = NULL; return ret; }


static void dump_json_image_info_list(ImageInfoList *list) { QString *str; QmpOutputVisitor *ov = qmp_output_visitor_new(); QObject *obj; visit_type_ImageInfoList(qmp_output_get_visitor(ov), NULL, &list, &error_abort); obj = qmp_output_get_qobject(ov); str = qobject_to_json_pretty(obj); assert(str != NULL); printf("%s\n", qstring_get_str(str)); qobject_decref(obj); qmp_output_visitor_cleanup(ov); QDECREF(str); }


static int get_segment32(CPUPPCState *env, struct mmu_ctx_hash32 *ctx, target_ulong eaddr, int rw, int type) { hwaddr hash; target_ulong vsid; int ds, pr, target_page_bits; int ret, ret2; target_ulong sr, pgidx; pr = msr_pr; ctx->eaddr = eaddr; sr = env->sr[eaddr >> 28]; ctx->key = (((sr & SR32_KP) && (pr != 0)) || ((sr & SR32_KS) && (pr == 0))) ? 1 : 0; ds = !!(sr & SR32_T); ctx->nx = !!(sr & SR32_NX); vsid = sr & SR32_VSID; target_page_bits = TARGET_PAGE_BITS; LOG_MMU("Check segment v=" TARGET_FMT_lx " %d " TARGET_FMT_lx " nip=" TARGET_FMT_lx " lr=" TARGET_FMT_lx " ir=%d dr=%d pr=%d %d t=%d\n", eaddr, (int)(eaddr >> 28), sr, env->nip, env->lr, (int)msr_ir, (int)msr_dr, pr != 0 ? 1 : 0, rw, type); pgidx = (eaddr & ~SEGMENT_MASK_256M) >> target_page_bits; hash = vsid ^ pgidx; ctx->ptem = (vsid << 7) | (pgidx >> 10); LOG_MMU("pte segment: key=%d ds %d nx %d vsid " TARGET_FMT_lx "\n", ctx->key, ds, ctx->nx, vsid); ret = -1; if (!ds) { /* Check if instruction fetch is allowed, if needed */ if (type != ACCESS_CODE || ctx->nx == 0) { /* Page address translation */ LOG_MMU("htab_base " TARGET_FMT_plx " htab_mask " TARGET_FMT_plx " hash " TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, hash); ctx->hash[0] = hash; ctx->hash[1] = ~hash; /* Initialize real address with an invalid value */ ctx->raddr = (hwaddr)-1ULL; LOG_MMU("0 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " ptem=" TARGET_FMT_lx " hash=" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ctx->ptem, ctx->hash[0]); /* Primary table lookup */ ret = find_pte32(env, ctx, 0, rw, type, target_page_bits); if (ret < 0) { /* Secondary table lookup */ LOG_MMU("1 htab=" TARGET_FMT_plx "/" TARGET_FMT_plx " vsid=" TARGET_FMT_lx " api=" TARGET_FMT_lx " hash=" TARGET_FMT_plx "\n", env->htab_base, env->htab_mask, vsid, ctx->ptem, ctx->hash[1]); ret2 = find_pte32(env, ctx, 1, rw, type, target_page_bits); if (ret2 != -1) { ret = ret2; } } #if defined(DUMP_PAGE_TABLES) if (qemu_log_enabled()) { hwaddr curaddr; uint32_t a0, a1, a2, a3; qemu_log("Page table: " TARGET_FMT_plx " len " TARGET_FMT_plx "\n", sdr, mask + 0x80); for (curaddr = sdr; curaddr < (sdr + mask + 0x80); curaddr += 16) { a0 = ldl_phys(curaddr); a1 = ldl_phys(curaddr + 4); a2 = ldl_phys(curaddr + 8); a3 = ldl_phys(curaddr + 12); if (a0 != 0 || a1 != 0 || a2 != 0 || a3 != 0) { qemu_log(TARGET_FMT_plx ": %08x %08x %08x %08x\n", curaddr, a0, a1, a2, a3); } } } #endif } else { LOG_MMU("No access allowed\n"); ret = -3; } } else { target_ulong sr; LOG_MMU("direct store...\n"); /* Direct-store segment : absolutely *BUGGY* for now */ /* Direct-store implies a 32-bit MMU. * Check the Segment Register's bus unit ID (BUID). */ sr = env->sr[eaddr >> 28]; if ((sr & 0x1FF00000) >> 20 == 0x07f) { /* Memory-forced I/O controller interface access */ /* If T=1 and BUID=x'07F', the 601 performs a memory access * to SR[28-31] LA[4-31], bypassing all protection mechanisms. */ ctx->raddr = ((sr & 0xF) << 28) | (eaddr & 0x0FFFFFFF); ctx->prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; return 0; } switch (type) { case ACCESS_INT: /* Integer load/store : only access allowed */ break; case ACCESS_CODE: /* No code fetch is allowed in direct-store areas */ return -4; case ACCESS_FLOAT: /* Floating point load/store */ return -4; case ACCESS_RES: /* lwarx, ldarx or srwcx. */ return -4; case ACCESS_CACHE: /* dcba, dcbt, dcbtst, dcbf, dcbi, dcbst, dcbz, or icbi */ /* Should make the instruction do no-op. * As it already do no-op, it's quite easy :-) */ ctx->raddr = eaddr; return 0; case ACCESS_EXT: /* eciwx or ecowx */ return -4; default: qemu_log("ERROR: instruction should not need " "address translation\n"); return -4; } if ((rw == 1 || ctx->key != 1) && (rw == 0 || ctx->key != 0)) { ctx->raddr = eaddr; ret = 2; } else { ret = -2; } } return ret; }


static int dmg_read_mish_block(BDRVDMGState *s, DmgHeaderState *ds, uint8_t *buffer, uint32_t count) { uint32_t type, i; int ret; size_t new_size; uint32_t chunk_count; int64_t offset = 0; uint64_t data_offset; uint64_t in_offset = ds->data_fork_offset; uint64_t out_offset; type = buff_read_uint32(buffer, offset); /* skip data that is not a valid MISH block (invalid magic or too small) */ if (type != 0x6d697368 || count < 244) { /* assume success for now */ return 0; } /* chunk offsets are relative to this sector number */ out_offset = buff_read_uint64(buffer, offset + 8); /* location in data fork for (compressed) blob (in bytes) */ data_offset = buff_read_uint64(buffer, offset + 0x18); in_offset += data_offset; /* move to begin of chunk entries */ offset += 204; chunk_count = (count - 204) / 40; new_size = sizeof(uint64_t) * (s->n_chunks + chunk_count); s->types = g_realloc(s->types, new_size / 2); s->offsets = g_realloc(s->offsets, new_size); s->lengths = g_realloc(s->lengths, new_size); s->sectors = g_realloc(s->sectors, new_size); s->sectorcounts = g_realloc(s->sectorcounts, new_size); for (i = s->n_chunks; i < s->n_chunks + chunk_count; i++) { s->types[i] = buff_read_uint32(buffer, offset); offset += 4; if (s->types[i] != 0x80000005 && s->types[i] != 1 && s->types[i] != 2) { chunk_count--; i--; offset += 36; continue; } offset += 4; s->sectors[i] = buff_read_uint64(buffer, offset); s->sectors[i] += out_offset; offset += 8; s->sectorcounts[i] = buff_read_uint64(buffer, offset); offset += 8; if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) { error_report("sector count %" PRIu64 " for chunk %" PRIu32 " is larger than max (%u)", s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX); ret = -EINVAL; goto fail; } s->offsets[i] = buff_read_uint64(buffer, offset); s->offsets[i] += in_offset; offset += 8; s->lengths[i] = buff_read_uint64(buffer, offset); offset += 8; if (s->lengths[i] > DMG_LENGTHS_MAX) { error_report("length %" PRIu64 " for chunk %" PRIu32 " is larger than max (%u)", s->lengths[i], i, DMG_LENGTHS_MAX); ret = -EINVAL; goto fail; } update_max_chunk_size(s, i, &ds->max_compressed_size, &ds->max_sectors_per_chunk); } s->n_chunks += chunk_count; return 0; fail: return ret; }


static always_inline void gen_qemu_ldf (TCGv t0, TCGv t1, int flags) { TCGv tmp = tcg_temp_new(TCG_TYPE_I32); tcg_gen_qemu_ld32u(tmp, t1, flags); tcg_gen_helper_1_1(helper_memory_to_f, t0, tmp); tcg_temp_free(tmp); }


static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp) { char buffer[PATH_MAX]; char *path = fs_path->data; if (fs_ctx->fs_sm == SM_MAPPED) { return local_set_xattr(rpath(fs_ctx, path, buffer), credp); } else if ((fs_ctx->fs_sm == SM_PASSTHROUGH) || (fs_ctx->fs_sm == SM_NONE)) { return chmod(rpath(fs_ctx, path, buffer), credp->fc_mode); } return -1; }


static inline PageDesc *page_find(target_ulong index) { PageDesc *p; p = l1_map[index >> L2_BITS]; if (!p) return 0; return p + (index & (L2_SIZE - 1)); }


static int pcm_bluray_parse_header(AVCodecContext *avctx, const uint8_t *header) { static const uint8_t bits_per_samples[4] = { 0, 16, 20, 24 }; static const uint32_t channel_layouts[16] = { 0, AV_CH_LAYOUT_MONO, 0, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, AV_CH_LAYOUT_2_1, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_2_2, AV_CH_LAYOUT_5POINT0, AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_7POINT0, AV_CH_LAYOUT_7POINT1, 0, 0, 0, 0 }; static const uint8_t channels[16] = { 0, 1, 0, 2, 3, 3, 4, 4, 5, 6, 7, 8, 0, 0, 0, 0 }; uint8_t channel_layout = header[2] >> 4; if (avctx->debug & FF_DEBUG_PICT_INFO) av_dlog(avctx, "pcm_bluray_parse_header: header = %02x%02x%02x%02x\n", header[0], header[1], header[2], header[3]); /* get the sample depth and derive the sample format from it */ avctx->bits_per_coded_sample = bits_per_samples[header[3] >> 6]; if (!avctx->bits_per_coded_sample) { av_log(avctx, AV_LOG_ERROR, "unsupported sample depth (0)\n"); return -1; } avctx->sample_fmt = avctx->bits_per_coded_sample == 16 ? AV_SAMPLE_FMT_S16 : AV_SAMPLE_FMT_S32; if (avctx->sample_fmt == AV_SAMPLE_FMT_S32) avctx->bits_per_raw_sample = avctx->bits_per_coded_sample; /* get the sample rate. Not all values are known or exist. */ switch (header[2] & 0x0f) { case 1: avctx->sample_rate = 48000; break; case 4: avctx->sample_rate = 96000; break; case 5: avctx->sample_rate = 192000; break; default: avctx->sample_rate = 0; av_log(avctx, AV_LOG_ERROR, "unsupported sample rate (%d)\n", header[2] & 0x0f); return -1; } /* * get the channel number (and mapping). Not all values are known or exist. * It must be noted that the number of channels in the MPEG stream can * differ from the actual meaningful number, e.g. mono audio still has two * channels, one being empty. */ avctx->channel_layout = channel_layouts[channel_layout]; avctx->channels = channels[channel_layout]; if (!avctx->channels) { av_log(avctx, AV_LOG_ERROR, "unsupported channel configuration (%d)\n", channel_layout); return -1; } avctx->bit_rate = avctx->channels * avctx->sample_rate * avctx->bits_per_coded_sample; if (avctx->debug & FF_DEBUG_PICT_INFO) av_dlog(avctx, "pcm_bluray_parse_header: %d channels, %d bits per sample, %d kHz, %d kbit\n", avctx->channels, avctx->bits_per_coded_sample, avctx->sample_rate, avctx->bit_rate); return 0; }


static int protocol_client_auth_sasl_mechname_len(VncState *vs, uint8_t *data, size_t len) { uint32_t mechlen = read_u32(data, 0); VNC_DEBUG("Got client mechname len %d\n", mechlen); if (mechlen > 100) { VNC_DEBUG("Too long SASL mechname data %d\n", mechlen); vnc_client_error(vs); return -1; } if (mechlen < 1) { VNC_DEBUG("Too short SASL mechname %d\n", mechlen); vnc_client_error(vs); return -1; } vnc_read_when(vs, protocol_client_auth_sasl_mechname,mechlen); return 0; }


static inline int ultrasparc_tag_match(SparcTLBEntry *tlb, uint64_t address, uint64_t context, target_phys_addr_t *physical, int is_nucleus) { uint64_t mask; switch ((tlb->tte >> 61) & 3) { default: case 0x0: // 8k mask = 0xffffffffffffe000ULL; break; case 0x1: // 64k mask = 0xffffffffffff0000ULL; break; case 0x2: // 512k mask = 0xfffffffffff80000ULL; break; case 0x3: // 4M mask = 0xffffffffffc00000ULL; break; } // valid, context match, virtual address match? if (TTE_IS_VALID(tlb->tte) && ((is_nucleus && compare_masked(0, tlb->tag, 0x1fff)) || TTE_IS_GLOBAL(tlb->tte) || compare_masked(context, tlb->tag, 0x1fff)) && compare_masked(address, tlb->tag, mask)) { // decode physical address *physical = ((tlb->tte & mask) | (address & ~mask)) & 0x1ffffffe000ULL; return 1; } return 0; }


int ff_dxva2_commit_buffer(AVCodecContext *avctx, AVDXVAContext *ctx, DECODER_BUFFER_DESC *dsc, unsigned type, const void *data, unsigned size, unsigned mb_count) { void *dxva_data; unsigned dxva_size; int result; HRESULT hr; #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) hr = ID3D11VideoContext_GetDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type, &dxva_size, &dxva_data); #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) hr = IDirectXVideoDecoder_GetBuffer(DXVA2_CONTEXT(ctx)->decoder, type, &dxva_data, &dxva_size); #endif if (FAILED(hr)) { av_log(avctx, AV_LOG_ERROR, "Failed to get a buffer for %u: 0x%lx\n", type, hr); return -1; } if (size <= dxva_size) { memcpy(dxva_data, data, size); #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) { D3D11_VIDEO_DECODER_BUFFER_DESC *dsc11 = dsc; memset(dsc11, 0, sizeof(*dsc11)); dsc11->BufferType = type; dsc11->DataSize = size; dsc11->NumMBsInBuffer = mb_count; } #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) { DXVA2_DecodeBufferDesc *dsc2 = dsc; memset(dsc2, 0, sizeof(*dsc2)); dsc2->CompressedBufferType = type; dsc2->DataSize = size; dsc2->NumMBsInBuffer = mb_count; } #endif result = 0; } else { av_log(avctx, AV_LOG_ERROR, "Buffer for type %u was too small\n", type); result = -1; } #if CONFIG_D3D11VA if (avctx->pix_fmt == AV_PIX_FMT_D3D11VA_VLD) hr = ID3D11VideoContext_ReleaseDecoderBuffer(D3D11VA_CONTEXT(ctx)->video_context, D3D11VA_CONTEXT(ctx)->decoder, type); #endif #if CONFIG_DXVA2 if (avctx->pix_fmt == AV_PIX_FMT_DXVA2_VLD) hr = IDirectXVideoDecoder_ReleaseBuffer(DXVA2_CONTEXT(ctx)->decoder, type); #endif if (FAILED(hr)) { av_log(avctx, AV_LOG_ERROR, "Failed to release buffer type %u: 0x%lx\n", type, hr); result = -1; } return result; }


static void new_video_stream(AVFormatContext *oc, int file_idx) { AVStream *st; AVOutputStream *ost; AVCodecContext *video_enc; enum CodecID codec_id; AVCodec *codec= NULL; st = av_new_stream(oc, oc->nb_streams < nb_streamid_map ? streamid_map[oc->nb_streams] : 0); if (!st) { fprintf(stderr, "Could not alloc stream\n"); ffmpeg_exit(1); } ost = new_output_stream(oc, file_idx); output_codecs = grow_array(output_codecs, sizeof(*output_codecs), &nb_output_codecs, nb_output_codecs + 1); if(!video_stream_copy){ if (video_codec_name) { codec_id = find_codec_or_die(video_codec_name, AVMEDIA_TYPE_VIDEO, 1, avcodec_opts[AVMEDIA_TYPE_VIDEO]->strict_std_compliance); codec = avcodec_find_encoder_by_name(video_codec_name); output_codecs[nb_output_codecs-1] = codec; } else { codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, AVMEDIA_TYPE_VIDEO); codec = avcodec_find_encoder(codec_id); } } avcodec_get_context_defaults3(st->codec, codec); ost->bitstream_filters = video_bitstream_filters; video_bitstream_filters= NULL; avcodec_thread_init(st->codec, thread_count); video_enc = st->codec; if(video_codec_tag) video_enc->codec_tag= video_codec_tag; if( (video_global_header&1) || (video_global_header==0 && (oc->oformat->flags & AVFMT_GLOBALHEADER))){ video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER; avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags|= CODEC_FLAG_GLOBAL_HEADER; } if(video_global_header&2){ video_enc->flags2 |= CODEC_FLAG2_LOCAL_HEADER; avcodec_opts[AVMEDIA_TYPE_VIDEO]->flags2|= CODEC_FLAG2_LOCAL_HEADER; } if (video_stream_copy) { st->stream_copy = 1; video_enc->codec_type = AVMEDIA_TYPE_VIDEO; video_enc->sample_aspect_ratio = st->sample_aspect_ratio = av_d2q(frame_aspect_ratio*frame_height/frame_width, 255); } else { const char *p; int i; AVRational fps= frame_rate.num ? frame_rate : (AVRational){25,1}; video_enc->codec_id = codec_id; set_context_opts(video_enc, avcodec_opts[AVMEDIA_TYPE_VIDEO], AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM, codec); if (codec && codec->supported_framerates && !force_fps) fps = codec->supported_framerates[av_find_nearest_q_idx(fps, codec->supported_framerates)]; video_enc->time_base.den = fps.num; video_enc->time_base.num = fps.den; video_enc->width = frame_width; video_enc->height = frame_height; video_enc->sample_aspect_ratio = av_d2q(frame_aspect_ratio*video_enc->height/video_enc->width, 255); video_enc->pix_fmt = frame_pix_fmt; st->sample_aspect_ratio = video_enc->sample_aspect_ratio; choose_pixel_fmt(st, codec); if (intra_only) video_enc->gop_size = 0; if (video_qscale || same_quality) { video_enc->flags |= CODEC_FLAG_QSCALE; video_enc->global_quality= st->quality = FF_QP2LAMBDA * video_qscale; } if(intra_matrix) video_enc->intra_matrix = intra_matrix; if(inter_matrix) video_enc->inter_matrix = inter_matrix; p= video_rc_override_string; for(i=0; p; i++){ int start, end, q; int e=sscanf(p, "%d,%d,%d", &start, &end, &q); if(e!=3){ fprintf(stderr, "error parsing rc_override\n"); ffmpeg_exit(1); } video_enc->rc_override= av_realloc(video_enc->rc_override, sizeof(RcOverride)*(i+1)); video_enc->rc_override[i].start_frame= start; video_enc->rc_override[i].end_frame = end; if(q>0){ video_enc->rc_override[i].qscale= q; video_enc->rc_override[i].quality_factor= 1.0; } else{ video_enc->rc_override[i].qscale= 0; video_enc->rc_override[i].quality_factor= -q/100.0; } p= strchr(p, '/'); if(p) p++; } video_enc->rc_override_count=i; if (!video_enc->rc_initial_buffer_occupancy) video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size*3/4; video_enc->me_threshold= me_threshold; video_enc->intra_dc_precision= intra_dc_precision - 8; if (do_psnr) video_enc->flags|= CODEC_FLAG_PSNR; /* two pass mode */ if (do_pass) { if (do_pass == 1) { video_enc->flags |= CODEC_FLAG_PASS1; } else { video_enc->flags |= CODEC_FLAG_PASS2; } } if (forced_key_frames) parse_forced_key_frames(forced_key_frames, ost, video_enc); } if (video_language) { av_metadata_set2(&st->metadata, "language", video_language, 0); av_freep(&video_language); } /* reset some key parameters */ video_disable = 0; av_freep(&video_codec_name); av_freep(&forced_key_frames); video_stream_copy = 0; frame_pix_fmt = PIX_FMT_NONE; }


static ExitStatus trans_fop_wew_0e(DisasContext *ctx, uint32_t insn, const DisasInsn *di) { unsigned rt = assemble_rt64(insn); unsigned ra = assemble_ra64(insn); return do_fop_wew(ctx, rt, ra, di->f_wew); }


static int alac_decode_frame(AVCodecContext *avctx, void *outbuffer, int *outputsize, uint8_t *inbuffer, int input_buffer_size) { ALACContext *alac = avctx->priv_data; int channels; int32_t outputsamples; /* short-circuit null buffers */ if (!inbuffer || !input_buffer_size) return input_buffer_size; /* initialize from the extradata */ if (!alac->context_initialized) { if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) { av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n", ALAC_EXTRADATA_SIZE); return input_buffer_size; } alac_set_info(alac); alac->context_initialized = 1; } outputsamples = alac->setinfo_max_samples_per_frame; init_get_bits(&alac->gb, inbuffer, input_buffer_size * 8); channels = get_bits(&alac->gb, 3); *outputsize = outputsamples * alac->bytespersample; switch(channels) { case 0: { /* 1 channel */ int hassize; int isnotcompressed; int readsamplesize; int wasted_bytes; int ricemodifier; /* 2^result = something to do with output waiting. * perhaps matters if we read > 1 frame in a pass? */ get_bits(&alac->gb, 4); get_bits(&alac->gb, 12); /* unknown, skip 12 bits */ hassize = get_bits(&alac->gb, 1); /* the output sample size is stored soon */ wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ isnotcompressed = get_bits(&alac->gb, 1); /* whether the frame is compressed */ if (hassize) { /* now read the number of samples, * as a 32bit integer */ outputsamples = get_bits(&alac->gb, 32); *outputsize = outputsamples * alac->bytespersample; } readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8); if (!isnotcompressed) { /* so it is compressed */ int16_t predictor_coef_table[32]; int predictor_coef_num; int prediction_type; int prediction_quantitization; int i; /* FIXME: skip 16 bits, not sure what they are. seem to be used in * two channel case */ get_bits(&alac->gb, 8); get_bits(&alac->gb, 8); prediction_type = get_bits(&alac->gb, 4); prediction_quantitization = get_bits(&alac->gb, 4); ricemodifier = get_bits(&alac->gb, 3); predictor_coef_num = get_bits(&alac->gb, 5); /* read the predictor table */ for (i = 0; i < predictor_coef_num; i++) { predictor_coef_table[i] = (int16_t)get_bits(&alac->gb, 16); } if (wasted_bytes) { /* these bytes seem to have something to do with * > 2 channel files. */ av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); } bastardized_rice_decompress(alac, alac->predicterror_buffer_a, outputsamples, readsamplesize, alac->setinfo_rice_initialhistory, alac->setinfo_rice_kmodifier, ricemodifier * alac->setinfo_rice_historymult / 4, (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type == 0) { /* adaptive fir */ predictor_decompress_fir_adapt(alac->predicterror_buffer_a, alac->outputsamples_buffer_a, outputsamples, readsamplesize, predictor_coef_table, predictor_coef_num, prediction_quantitization); } else { av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type); /* i think the only other prediction type (or perhaps this is just a * boolean?) runs adaptive fir twice.. like: * predictor_decompress_fir_adapt(predictor_error, tempout, ...) * predictor_decompress_fir_adapt(predictor_error, outputsamples ...) * little strange.. */ } } else { /* not compressed, easy case */ if (readsamplesize <= 16) { int i; for (i = 0; i < outputsamples; i++) { int32_t audiobits = get_bits(&alac->gb, readsamplesize); audiobits = SIGN_EXTENDED32(audiobits, readsamplesize); alac->outputsamples_buffer_a[i] = audiobits; } } else { int i; for (i = 0; i < outputsamples; i++) { int32_t audiobits; audiobits = get_bits(&alac->gb, 16); /* special case of sign extension.. * as we'll be ORing the low 16bits into this */ audiobits = audiobits << 16; audiobits = audiobits >> (32 - readsamplesize); audiobits |= get_bits(&alac->gb, readsamplesize - 16); alac->outputsamples_buffer_a[i] = audiobits; } } /* wasted_bytes = 0; // unused */ } switch(alac->setinfo_sample_size) { case 16: { int i; for (i = 0; i < outputsamples; i++) { int16_t sample = alac->outputsamples_buffer_a[i]; ((int16_t*)outbuffer)[i * alac->numchannels] = sample; } break; } case 20: case 24: case 32: av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); break; default: break; } break; } case 1: { /* 2 channels */ int hassize; int isnotcompressed; int readsamplesize; int wasted_bytes; uint8_t interlacing_shift; uint8_t interlacing_leftweight; /* 2^result = something to do with output waiting. * perhaps matters if we read > 1 frame in a pass? */ get_bits(&alac->gb, 4); get_bits(&alac->gb, 12); /* unknown, skip 12 bits */ hassize = get_bits(&alac->gb, 1); /* the output sample size is stored soon */ wasted_bytes = get_bits(&alac->gb, 2); /* unknown ? */ isnotcompressed = get_bits(&alac->gb, 1); /* whether the frame is compressed */ if (hassize) { /* now read the number of samples, * as a 32bit integer */ outputsamples = get_bits(&alac->gb, 32); *outputsize = outputsamples * alac->bytespersample; } readsamplesize = alac->setinfo_sample_size - (wasted_bytes * 8) + 1; if (!isnotcompressed) { /* compressed */ int16_t predictor_coef_table_a[32]; int predictor_coef_num_a; int prediction_type_a; int prediction_quantitization_a; int ricemodifier_a; int16_t predictor_coef_table_b[32]; int predictor_coef_num_b; int prediction_type_b; int prediction_quantitization_b; int ricemodifier_b; int i; interlacing_shift = get_bits(&alac->gb, 8); interlacing_leftweight = get_bits(&alac->gb, 8); /******** channel 1 ***********/ prediction_type_a = get_bits(&alac->gb, 4); prediction_quantitization_a = get_bits(&alac->gb, 4); ricemodifier_a = get_bits(&alac->gb, 3); predictor_coef_num_a = get_bits(&alac->gb, 5); /* read the predictor table */ for (i = 0; i < predictor_coef_num_a; i++) { predictor_coef_table_a[i] = (int16_t)get_bits(&alac->gb, 16); } /******** channel 2 *********/ prediction_type_b = get_bits(&alac->gb, 4); prediction_quantitization_b = get_bits(&alac->gb, 4); ricemodifier_b = get_bits(&alac->gb, 3); predictor_coef_num_b = get_bits(&alac->gb, 5); /* read the predictor table */ for (i = 0; i < predictor_coef_num_b; i++) { predictor_coef_table_b[i] = (int16_t)get_bits(&alac->gb, 16); } /*********************/ if (wasted_bytes) { /* see mono case */ av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented, unhandling of wasted_bytes\n"); } /* channel 1 */ bastardized_rice_decompress(alac, alac->predicterror_buffer_a, outputsamples, readsamplesize, alac->setinfo_rice_initialhistory, alac->setinfo_rice_kmodifier, ricemodifier_a * alac->setinfo_rice_historymult / 4, (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type_a == 0) { /* adaptive fir */ predictor_decompress_fir_adapt(alac->predicterror_buffer_a, alac->outputsamples_buffer_a, outputsamples, readsamplesize, predictor_coef_table_a, predictor_coef_num_a, prediction_quantitization_a); } else { /* see mono case */ av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type_a); } /* channel 2 */ bastardized_rice_decompress(alac, alac->predicterror_buffer_b, outputsamples, readsamplesize, alac->setinfo_rice_initialhistory, alac->setinfo_rice_kmodifier, ricemodifier_b * alac->setinfo_rice_historymult / 4, (1 << alac->setinfo_rice_kmodifier) - 1); if (prediction_type_b == 0) { /* adaptive fir */ predictor_decompress_fir_adapt(alac->predicterror_buffer_b, alac->outputsamples_buffer_b, outputsamples, readsamplesize, predictor_coef_table_b, predictor_coef_num_b, prediction_quantitization_b); } else { av_log(avctx, AV_LOG_ERROR, "FIXME: unhandled prediction type: %i\n", prediction_type_b); } } else { /* not compressed, easy case */ if (alac->setinfo_sample_size <= 16) { int i; for (i = 0; i < outputsamples; i++) { int32_t audiobits_a, audiobits_b; audiobits_a = get_bits(&alac->gb, alac->setinfo_sample_size); audiobits_b = get_bits(&alac->gb, alac->setinfo_sample_size); audiobits_a = SIGN_EXTENDED32(audiobits_a, alac->setinfo_sample_size); audiobits_b = SIGN_EXTENDED32(audiobits_b, alac->setinfo_sample_size); alac->outputsamples_buffer_a[i] = audiobits_a; alac->outputsamples_buffer_b[i] = audiobits_b; } } else { int i; for (i = 0; i < outputsamples; i++) { int32_t audiobits_a, audiobits_b; audiobits_a = get_bits(&alac->gb, 16); audiobits_a = audiobits_a << 16; audiobits_a = audiobits_a >> (32 - alac->setinfo_sample_size); audiobits_a |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); audiobits_b = get_bits(&alac->gb, 16); audiobits_b = audiobits_b << 16; audiobits_b = audiobits_b >> (32 - alac->setinfo_sample_size); audiobits_b |= get_bits(&alac->gb, alac->setinfo_sample_size - 16); alac->outputsamples_buffer_a[i] = audiobits_a; alac->outputsamples_buffer_b[i] = audiobits_b; } } /* wasted_bytes = 0; */ interlacing_shift = 0; interlacing_leftweight = 0; } switch(alac->setinfo_sample_size) { case 16: { deinterlace_16(alac->outputsamples_buffer_a, alac->outputsamples_buffer_b, (int16_t*)outbuffer, alac->numchannels, outputsamples, interlacing_shift, interlacing_leftweight); break; } case 20: case 24: case 32: av_log(avctx, AV_LOG_ERROR, "FIXME: unimplemented sample size %i\n", alac->setinfo_sample_size); break; default: break; } break; } } return input_buffer_size; }


static int disas_thumb2_insn(CPUState *env, DisasContext *s, uint16_t insn_hw1) { uint32_t insn, imm, shift, offset; uint32_t rd, rn, rm, rs; TCGv tmp; TCGv tmp2; TCGv tmp3; TCGv addr; TCGv_i64 tmp64; int op; int shiftop; int conds; int logic_cc; if (!(arm_feature(env, ARM_FEATURE_THUMB2) || arm_feature (env, ARM_FEATURE_M))) { /* Thumb-1 cores may need to treat bl and blx as a pair of 16-bit instructions to get correct prefetch abort behavior. */ insn = insn_hw1; if ((insn & (1 << 12)) == 0) { /* Second half of blx. */ offset = ((insn & 0x7ff) << 1); tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tcg_gen_andi_i32(tmp, tmp, 0xfffffffc); tmp2 = new_tmp(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); return 0; } if (insn & (1 << 11)) { /* Second half of bl. */ offset = ((insn & 0x7ff) << 1) | 1; tmp = load_reg(s, 14); tcg_gen_addi_i32(tmp, tmp, offset); tmp2 = new_tmp(); tcg_gen_movi_i32(tmp2, s->pc | 1); store_reg(s, 14, tmp2); gen_bx(s, tmp); return 0; } if ((s->pc & ~TARGET_PAGE_MASK) == 0) { /* Instruction spans a page boundary. Implement it as two 16-bit instructions in case the second half causes an prefetch abort. */ offset = ((int32_t)insn << 21) >> 9; tcg_gen_movi_i32(cpu_R[14], s->pc + 2 + offset); return 0; } /* Fall through to 32-bit decode. */ } insn = lduw_code(s->pc); s->pc += 2; insn |= (uint32_t)insn_hw1 << 16; if ((insn & 0xf800e800) != 0xf000e800) { ARCH(6T2); } rn = (insn >> 16) & 0xf; rs = (insn >> 12) & 0xf; rd = (insn >> 8) & 0xf; rm = insn & 0xf; switch ((insn >> 25) & 0xf) { case 0: case 1: case 2: case 3: /* 16-bit instructions. Should never happen. */ abort(); case 4: if (insn & (1 << 22)) { /* Other load/store, table branch. */ if (insn & 0x01200000) { /* Load/store doubleword. */ if (rn == 15) { addr = new_tmp(); tcg_gen_movi_i32(addr, s->pc & ~3); } else { addr = load_reg(s, rn); } offset = (insn & 0xff) * 4; if ((insn & (1 << 23)) == 0) offset = -offset; if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, offset); offset = 0; } if (insn & (1 << 20)) { /* ldrd */ tmp = gen_ld32(addr, IS_USER(s)); store_reg(s, rs, tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = gen_ld32(addr, IS_USER(s)); store_reg(s, rd, tmp); } else { /* strd */ tmp = load_reg(s, rs); gen_st32(tmp, addr, IS_USER(s)); tcg_gen_addi_i32(addr, addr, 4); tmp = load_reg(s, rd); gen_st32(tmp, addr, IS_USER(s)); } if (insn & (1 << 21)) { /* Base writeback. */ if (rn == 15) goto illegal_op; tcg_gen_addi_i32(addr, addr, offset - 4); store_reg(s, rn, addr); } else { dead_tmp(addr); } } else if ((insn & (1 << 23)) == 0) { /* Load/store exclusive word. */ addr = tcg_temp_local_new(); load_reg_var(s, addr, rn); tcg_gen_addi_i32(addr, addr, (insn & 0xff) << 2); if (insn & (1 << 20)) { gen_load_exclusive(s, rs, 15, addr, 2); } else { gen_store_exclusive(s, rd, rs, 15, addr, 2); } tcg_temp_free(addr); } else if ((insn & (1 << 6)) == 0) { /* Table Branch. */ if (rn == 15) { addr = new_tmp(); tcg_gen_movi_i32(addr, s->pc); } else { addr = load_reg(s, rn); } tmp = load_reg(s, rm); tcg_gen_add_i32(addr, addr, tmp); if (insn & (1 << 4)) { /* tbh */ tcg_gen_add_i32(addr, addr, tmp); dead_tmp(tmp); tmp = gen_ld16u(addr, IS_USER(s)); } else { /* tbb */ dead_tmp(tmp); tmp = gen_ld8u(addr, IS_USER(s)); } dead_tmp(addr); tcg_gen_shli_i32(tmp, tmp, 1); tcg_gen_addi_i32(tmp, tmp, s->pc); store_reg(s, 15, tmp); } else { /* Load/store exclusive byte/halfword/doubleword. */ ARCH(7); op = (insn >> 4) & 0x3; if (op == 2) { goto illegal_op; } addr = tcg_temp_local_new(); load_reg_var(s, addr, rn); if (insn & (1 << 20)) { gen_load_exclusive(s, rs, rd, addr, op); } else { gen_store_exclusive(s, rm, rs, rd, addr, op); } tcg_temp_free(addr); } } else { /* Load/store multiple, RFE, SRS. */ if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { /* Not available in user mode. */ if (IS_USER(s)) goto illegal_op; if (insn & (1 << 20)) { /* rfe */ addr = load_reg(s, rn); if ((insn & (1 << 24)) == 0) tcg_gen_addi_i32(addr, addr, -8); /* 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. */ if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, 4); } else { tcg_gen_addi_i32(addr, addr, -4); } store_reg(s, rn, addr); } else { dead_tmp(addr); } gen_rfe(s, tmp, tmp2); } else { /* srs */ op = (insn & 0x1f); if (op == (env->uncached_cpsr & CPSR_M)) { addr = load_reg(s, 13); } else { addr = new_tmp(); tmp = tcg_const_i32(op); gen_helper_get_r13_banked(addr, cpu_env, tmp); tcg_temp_free_i32(tmp); } if ((insn & (1 << 24)) == 0) { tcg_gen_addi_i32(addr, addr, -8); } tmp = load_reg(s, 14); gen_st32(tmp, addr, 0); tcg_gen_addi_i32(addr, addr, 4); tmp = new_tmp(); gen_helper_cpsr_read(tmp); gen_st32(tmp, addr, 0); if (insn & (1 << 21)) { if ((insn & (1 << 24)) == 0) { tcg_gen_addi_i32(addr, addr, -4); } else { tcg_gen_addi_i32(addr, addr, 4); } if (op == (env->uncached_cpsr & CPSR_M)) { store_reg(s, 13, addr); } else { tmp = tcg_const_i32(op); gen_helper_set_r13_banked(cpu_env, tmp, addr); tcg_temp_free_i32(tmp); } } else { dead_tmp(addr); } } } else { int i; /* Load/store multiple. */ addr = load_reg(s, rn); offset = 0; for (i = 0; i < 16; i++) { if (insn & (1 << i)) offset += 4; } if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, -offset); } for (i = 0; i < 16; i++) { if ((insn & (1 << i)) == 0) continue; if (insn & (1 << 20)) { /* Load. */ tmp = gen_ld32(addr, IS_USER(s)); if (i == 15) { gen_bx(s, tmp); } else { store_reg(s, i, tmp); } } else { /* Store. */ tmp = load_reg(s, i); gen_st32(tmp, addr, IS_USER(s)); } tcg_gen_addi_i32(addr, addr, 4); } if (insn & (1 << 21)) { /* Base register writeback. */ if (insn & (1 << 24)) { tcg_gen_addi_i32(addr, addr, -offset); } /* Fault if writeback register is in register list. */ if (insn & (1 << rn)) goto illegal_op; store_reg(s, rn, addr); } else { dead_tmp(addr); } } } break; case 5: op = (insn >> 21) & 0xf; if (op == 6) { /* Halfword pack. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); shift = ((insn >> 10) & 0x1c) | ((insn >> 6) & 0x3); if (insn & (1 << 5)) { /* 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); dead_tmp(tmp2); store_reg(s, rd, tmp); } else { /* Data processing register constant shift. */ if (rn == 15) { tmp = new_tmp(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } tmp2 = load_reg(s, rm); shiftop = (insn >> 4) & 3; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); conds = (insn & (1 << 20)) != 0; logic_cc = (conds && thumb2_logic_op(op)); gen_arm_shift_im(tmp2, shiftop, shift, logic_cc); if (gen_thumb2_data_op(s, op, conds, 0, tmp, tmp2)) goto illegal_op; dead_tmp(tmp2); if (rd != 15) { store_reg(s, rd, tmp); } else { dead_tmp(tmp); } } break; case 13: /* Misc data processing. */ op = ((insn >> 22) & 6) | ((insn >> 7) & 1); if (op < 4 && (insn & 0xf000) != 0xf000) goto illegal_op; switch (op) { case 0: /* Register controlled shift. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if ((insn & 0x70) != 0) goto illegal_op; op = (insn >> 21) & 3; logic_cc = (insn & (1 << 20)) != 0; gen_arm_shift_reg(tmp, op, tmp2, logic_cc); if (logic_cc) gen_logic_CC(tmp); store_reg_bx(env, s, rd, tmp); break; case 1: /* Sign/zero extend. */ tmp = load_reg(s, rm); shift = (insn >> 4) & 3; /* ??? In many cases it's not neccessary to do a rotate, a shift is sufficient. */ if (shift != 0) tcg_gen_rotri_i32(tmp, tmp, shift * 8); op = (insn >> 20) & 7; switch (op) { case 0: gen_sxth(tmp); break; case 1: gen_uxth(tmp); break; case 2: gen_sxtb16(tmp); break; case 3: gen_uxtb16(tmp); break; case 4: gen_sxtb(tmp); break; case 5: gen_uxtb(tmp); break; default: goto illegal_op; } if (rn != 15) { tmp2 = load_reg(s, rn); if ((op >> 1) == 1) { gen_add16(tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); dead_tmp(tmp2); } } store_reg(s, rd, tmp); break; case 2: /* SIMD add/subtract. */ op = (insn >> 20) & 7; shift = (insn >> 4) & 7; if ((op & 3) == 3 || (shift & 3) == 3) goto illegal_op; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); gen_thumb2_parallel_addsub(op, shift, tmp, tmp2); dead_tmp(tmp2); store_reg(s, rd, tmp); break; case 3: /* Other data processing. */ op = ((insn >> 17) & 0x38) | ((insn >> 4) & 7); if (op < 4) { /* Saturating add/subtract. */ tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if (op & 1) gen_helper_double_saturate(tmp, tmp); if (op & 2) gen_helper_sub_saturate(tmp, tmp2, tmp); else gen_helper_add_saturate(tmp, tmp, tmp2); dead_tmp(tmp2); } else { tmp = load_reg(s, rn); switch (op) { case 0x0a: /* rbit */ gen_helper_rbit(tmp, tmp); break; case 0x08: /* rev */ tcg_gen_bswap32_i32(tmp, tmp); break; case 0x09: /* rev16 */ gen_rev16(tmp); break; case 0x0b: /* revsh */ gen_revsh(tmp); break; case 0x10: /* sel */ tmp2 = load_reg(s, rm); tmp3 = new_tmp(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); dead_tmp(tmp3); dead_tmp(tmp2); break; case 0x18: /* clz */ gen_helper_clz(tmp, tmp); break; default: goto illegal_op; } } store_reg(s, rd, tmp); break; case 4: case 5: /* 32-bit multiply. Sum of absolute differences. */ op = (insn >> 4) & 0xf; tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); switch ((insn >> 20) & 7) { case 0: /* 32 x 32 -> 32 */ tcg_gen_mul_i32(tmp, tmp, tmp2); dead_tmp(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); if (op) tcg_gen_sub_i32(tmp, tmp2, tmp); else tcg_gen_add_i32(tmp, tmp, tmp2); dead_tmp(tmp2); } break; case 1: /* 16 x 16 -> 32 */ gen_mulxy(tmp, tmp2, op & 2, op & 1); dead_tmp(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, tmp, tmp2); dead_tmp(tmp2); } break; case 2: /* Dual multiply add. */ case 4: /* Dual multiply subtract. */ if (op) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); /* This addition cannot overflow. */ if (insn & (1 << 22)) { tcg_gen_sub_i32(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } dead_tmp(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, tmp, tmp2); dead_tmp(tmp2); } break; case 3: /* 32 * 16 -> 32msb */ if (op) 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 = new_tmp(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, tmp, tmp2); dead_tmp(tmp2); } break; case 5: case 6: /* 32 * 32 -> 32msb (SMMUL, SMMLA, SMMLS) */ tmp64 = gen_muls_i64_i32(tmp, tmp2); if (rs != 15) { tmp = load_reg(s, rs); if (insn & (1 << 20)) { tmp64 = gen_addq_msw(tmp64, tmp); } else { tmp64 = gen_subq_msw(tmp64, tmp); } } if (insn & (1 << 4)) { tcg_gen_addi_i64(tmp64, tmp64, 0x80000000u); } tcg_gen_shri_i64(tmp64, tmp64, 32); tmp = new_tmp(); tcg_gen_trunc_i64_i32(tmp, tmp64); tcg_temp_free_i64(tmp64); break; case 7: /* Unsigned sum of absolute differences. */ gen_helper_usad8(tmp, tmp, tmp2); dead_tmp(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); tcg_gen_add_i32(tmp, tmp, tmp2); dead_tmp(tmp2); } break; } store_reg(s, rd, tmp); break; case 6: case 7: /* 64-bit multiply, Divide. */ op = ((insn >> 4) & 0xf) | ((insn >> 16) & 0x70); tmp = load_reg(s, rn); tmp2 = load_reg(s, rm); if ((op & 0x50) == 0x10) { /* sdiv, udiv */ if (!arm_feature(env, ARM_FEATURE_DIV)) goto illegal_op; if (op & 0x20) gen_helper_udiv(tmp, tmp, tmp2); else gen_helper_sdiv(tmp, tmp, tmp2); dead_tmp(tmp2); store_reg(s, rd, tmp); } else if ((op & 0xe) == 0xc) { /* Dual multiply accumulate long. */ if (op & 1) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (op & 0x10) { tcg_gen_sub_i32(tmp, tmp, tmp2); } else { tcg_gen_add_i32(tmp, tmp, tmp2); } dead_tmp(tmp2); /* BUGFIX */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); dead_tmp(tmp); gen_addq(s, tmp64, rs, rd); gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); } else { if (op & 0x20) { /* Unsigned 64-bit multiply */ tmp64 = gen_mulu_i64_i32(tmp, tmp2); } else { if (op & 8) { /* smlalxy */ gen_mulxy(tmp, tmp2, op & 2, op & 1); dead_tmp(tmp2); tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); dead_tmp(tmp); } else { /* Signed 64-bit multiply */ tmp64 = gen_muls_i64_i32(tmp, tmp2); } } if (op & 4) { /* umaal */ gen_addq_lo(s, tmp64, rs); gen_addq_lo(s, tmp64, rd); } else if (op & 0x40) { /* 64-bit accumulate. */ gen_addq(s, tmp64, rs, rd); } gen_storeq_reg(s, rs, rd, tmp64); tcg_temp_free_i64(tmp64); } break; } break; case 6: case 7: case 14: case 15: /* Coprocessor. */ if (((insn >> 24) & 3) == 3) { /* Translate into the equivalent ARM encoding. */ insn = (insn & 0xe2ffffff) | ((insn & (1 << 28)) >> 4); if (disas_neon_data_insn(env, s, insn)) goto illegal_op; } else { if (insn & (1 << 28)) goto illegal_op; if (disas_coproc_insn (env, s, insn)) goto illegal_op; } break; case 8: case 9: case 10: case 11: if (insn & (1 << 15)) { /* Branches, misc control. */ if (insn & 0x5000) { /* Unconditional branch. */ /* signextend(hw1[10:0]) -> offset[:12]. */ offset = ((int32_t)insn << 5) >> 9 & ~(int32_t)0xfff; /* hw1[10:0] -> offset[11:1]. */ offset |= (insn & 0x7ff) << 1; /* (~hw2[13, 11] ^ offset[24]) -> offset[23,22] offset[24:22] already have the same value because of the sign extension above. */ offset ^= ((~insn) & (1 << 13)) << 10; offset ^= ((~insn) & (1 << 11)) << 11; if (insn & (1 << 14)) { /* Branch and link. */ tcg_gen_movi_i32(cpu_R[14], s->pc | 1); } offset += s->pc; if (insn & (1 << 12)) { /* b/bl */ gen_jmp(s, offset); } else { /* blx */ offset &= ~(uint32_t)2; gen_bx_im(s, offset); } } else if (((insn >> 23) & 7) == 7) { /* Misc control */ if (insn & (1 << 13)) goto illegal_op; if (insn & (1 << 26)) { /* Secure monitor call (v6Z) */ goto illegal_op; /* not implemented. */ } else { op = (insn >> 20) & 7; switch (op) { case 0: /* msr cpsr. */ if (IS_M(env)) { tmp = load_reg(s, rn); addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_msr(cpu_env, addr, tmp); tcg_temp_free_i32(addr); dead_tmp(tmp); gen_lookup_tb(s); break; } /* fall through */ case 1: /* msr spsr. */ if (IS_M(env)) goto illegal_op; tmp = load_reg(s, rn); if (gen_set_psr(s, msr_mask(env, s, (insn >> 8) & 0xf, op == 1), op == 1, tmp)) goto illegal_op; break; case 2: /* cps, nop-hint. */ if (((insn >> 8) & 7) == 0) { gen_nop_hint(s, insn & 0xff); } /* Implemented as NOP in user mode. */ if (IS_USER(s)) break; offset = 0; imm = 0; if (insn & (1 << 10)) { if (insn & (1 << 7)) offset |= CPSR_A; if (insn & (1 << 6)) offset |= CPSR_I; if (insn & (1 << 5)) offset |= CPSR_F; if (insn & (1 << 9)) imm = CPSR_A | CPSR_I | CPSR_F; } if (insn & (1 << 8)) { offset |= 0x1f; imm |= (insn & 0x1f); } if (offset) { gen_set_psr_im(s, offset, 0, imm); } break; case 3: /* Special control operations. */ ARCH(7); op = (insn >> 4) & 0xf; switch (op) { case 2: /* clrex */ gen_clrex(s); break; case 4: /* dsb */ case 5: /* dmb */ case 6: /* isb */ /* These execute as NOPs. */ break; default: goto illegal_op; } break; case 4: /* bxj */ /* Trivial implementation equivalent to bx. */ tmp = load_reg(s, rn); gen_bx(s, tmp); break; case 5: /* Exception return. */ if (IS_USER(s)) { goto illegal_op; } if (rn != 14 || rd != 15) { goto illegal_op; } tmp = load_reg(s, rn); tcg_gen_subi_i32(tmp, tmp, insn & 0xff); gen_exception_return(s, tmp); break; case 6: /* mrs cpsr. */ tmp = new_tmp(); if (IS_M(env)) { addr = tcg_const_i32(insn & 0xff); gen_helper_v7m_mrs(tmp, cpu_env, addr); tcg_temp_free_i32(addr); } else { gen_helper_cpsr_read(tmp); } store_reg(s, rd, tmp); break; case 7: /* mrs spsr. */ /* Not accessible in user mode. */ if (IS_USER(s) || IS_M(env)) goto illegal_op; tmp = load_cpu_field(spsr); store_reg(s, rd, tmp); break; } } } else { /* Conditional branch. */ op = (insn >> 22) & 0xf; /* Generate a conditional jump to next instruction. */ s->condlabel = gen_new_label(); gen_test_cc(op ^ 1, s->condlabel); s->condjmp = 1; /* offset[11:1] = insn[10:0] */ offset = (insn & 0x7ff) << 1; /* offset[17:12] = insn[21:16]. */ offset |= (insn & 0x003f0000) >> 4; /* offset[31:20] = insn[26]. */ offset |= ((int32_t)((insn << 5) & 0x80000000)) >> 11; /* offset[18] = insn[13]. */ offset |= (insn & (1 << 13)) << 5; /* offset[19] = insn[11]. */ offset |= (insn & (1 << 11)) << 8; /* jump to the offset */ gen_jmp(s, s->pc + offset); } } else { /* Data processing immediate. */ if (insn & (1 << 25)) { if (insn & (1 << 24)) { if (insn & (1 << 20)) goto illegal_op; /* Bitfield/Saturate. */ op = (insn >> 21) & 7; imm = insn & 0x1f; shift = ((insn >> 6) & 3) | ((insn >> 10) & 0x1c); if (rn == 15) { tmp = new_tmp(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } switch (op) { case 2: /* Signed bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; if (imm < 32) gen_sbfx(tmp, shift, imm); break; case 6: /* Unsigned bitfield extract. */ imm++; if (shift + imm > 32) goto illegal_op; if (imm < 32) gen_ubfx(tmp, shift, (1u << imm) - 1); break; case 3: /* Bitfield insert/clear. */ if (imm < shift) goto illegal_op; imm = imm + 1 - shift; if (imm != 32) { tmp2 = load_reg(s, rd); gen_bfi(tmp, tmp2, tmp, shift, (1u << imm) - 1); dead_tmp(tmp2); } break; case 7: goto illegal_op; default: /* Saturate. */ if (shift) { if (op & 1) tcg_gen_sari_i32(tmp, tmp, shift); else tcg_gen_shli_i32(tmp, tmp, shift); } tmp2 = tcg_const_i32(imm); if (op & 4) { /* Unsigned. */ if ((op & 1) && shift == 0) gen_helper_usat16(tmp, tmp, tmp2); else gen_helper_usat(tmp, tmp, tmp2); } else { /* Signed. */ if ((op & 1) && shift == 0) gen_helper_ssat16(tmp, tmp, tmp2); else gen_helper_ssat(tmp, tmp, tmp2); } tcg_temp_free_i32(tmp2); break; } store_reg(s, rd, tmp); } else { imm = ((insn & 0x04000000) >> 15) | ((insn & 0x7000) >> 4) | (insn & 0xff); if (insn & (1 << 22)) { /* 16-bit immediate. */ imm |= (insn >> 4) & 0xf000; if (insn & (1 << 23)) { /* movt */ tmp = load_reg(s, rd); tcg_gen_ext16u_i32(tmp, tmp); tcg_gen_ori_i32(tmp, tmp, imm << 16); } else { /* movw */ tmp = new_tmp(); tcg_gen_movi_i32(tmp, imm); } } else { /* Add/sub 12-bit immediate. */ if (rn == 15) { offset = s->pc & ~(uint32_t)3; if (insn & (1 << 23)) offset -= imm; else offset += imm; tmp = new_tmp(); tcg_gen_movi_i32(tmp, offset); } else { tmp = load_reg(s, rn); if (insn & (1 << 23)) tcg_gen_subi_i32(tmp, tmp, imm); else tcg_gen_addi_i32(tmp, tmp, imm); } } store_reg(s, rd, tmp); } } else { int shifter_out = 0; /* modified 12-bit immediate. */ shift = ((insn & 0x04000000) >> 23) | ((insn & 0x7000) >> 12); imm = (insn & 0xff); switch (shift) { case 0: /* XY */ /* Nothing to do. */ break; case 1: /* 00XY00XY */ imm |= imm << 16; break; case 2: /* XY00XY00 */ imm |= imm << 16; imm <<= 8; break; case 3: /* XYXYXYXY */ imm |= imm << 16; imm |= imm << 8; break; default: /* Rotated constant. */ shift = (shift << 1) | (imm >> 7); imm |= 0x80; imm = imm << (32 - shift); shifter_out = 1; break; } tmp2 = new_tmp(); tcg_gen_movi_i32(tmp2, imm); rn = (insn >> 16) & 0xf; if (rn == 15) { tmp = new_tmp(); tcg_gen_movi_i32(tmp, 0); } else { tmp = load_reg(s, rn); } op = (insn >> 21) & 0xf; if (gen_thumb2_data_op(s, op, (insn & (1 << 20)) != 0, shifter_out, tmp, tmp2)) goto illegal_op; dead_tmp(tmp2); rd = (insn >> 8) & 0xf; if (rd != 15) { store_reg(s, rd, tmp); } else { dead_tmp(tmp); } } } break; case 12: /* Load/store single data item. */ { int postinc = 0; int writeback = 0; int user; if ((insn & 0x01100000) == 0x01000000) { if (disas_neon_ls_insn(env, s, insn)) goto illegal_op; break; } user = IS_USER(s); if (rn == 15) { addr = new_tmp(); /* PC relative. */ /* s->pc has already been incremented by 4. */ imm = s->pc & 0xfffffffc; if (insn & (1 << 23)) imm += insn & 0xfff; else imm -= insn & 0xfff; tcg_gen_movi_i32(addr, imm); } else { addr = load_reg(s, rn); if (insn & (1 << 23)) { /* Positive offset. */ imm = insn & 0xfff; tcg_gen_addi_i32(addr, addr, imm); } else { op = (insn >> 8) & 7; imm = insn & 0xff; switch (op) { case 0: case 8: /* Shifted Register. */ shift = (insn >> 4) & 0xf; if (shift > 3) goto illegal_op; tmp = load_reg(s, rm); if (shift) tcg_gen_shli_i32(tmp, tmp, shift); tcg_gen_add_i32(addr, addr, tmp); dead_tmp(tmp); break; case 4: /* Negative offset. */ tcg_gen_addi_i32(addr, addr, -imm); break; case 6: /* User privilege. */ tcg_gen_addi_i32(addr, addr, imm); user = 1; break; case 1: /* Post-decrement. */ imm = -imm; /* Fall through. */ case 3: /* Post-increment. */ postinc = 1; writeback = 1; break; case 5: /* Pre-decrement. */ imm = -imm; /* Fall through. */ case 7: /* Pre-increment. */ tcg_gen_addi_i32(addr, addr, imm); writeback = 1; break; default: goto illegal_op; } } } op = ((insn >> 21) & 3) | ((insn >> 22) & 4); if (insn & (1 << 20)) { /* Load. */ if (rs == 15 && op != 2) { if (op & 2) goto illegal_op; /* Memory hint. Implemented as NOP. */ } else { switch (op) { case 0: tmp = gen_ld8u(addr, user); break; case 4: tmp = gen_ld8s(addr, user); break; case 1: tmp = gen_ld16u(addr, user); break; case 5: tmp = gen_ld16s(addr, user); break; case 2: tmp = gen_ld32(addr, user); break; default: goto illegal_op; } if (rs == 15) { gen_bx(s, tmp); } else { store_reg(s, rs, tmp); } } } else { /* Store. */ if (rs == 15) goto illegal_op; tmp = load_reg(s, rs); switch (op) { case 0: gen_st8(tmp, addr, user); break; case 1: gen_st16(tmp, addr, user); break; case 2: gen_st32(tmp, addr, user); break; default: goto illegal_op; } } if (postinc) tcg_gen_addi_i32(addr, addr, imm); if (writeback) { store_reg(s, rn, addr); } else { dead_tmp(addr); } } break; default: goto illegal_op; } return 0; illegal_op: return 1; }


size_t iov_to_buf(const struct iovec *iov, const unsigned int iov_cnt, size_t iov_off, void *buf, size_t size) { uint8_t *ptr; size_t iovec_off, buf_off; unsigned int i; ptr = buf; iovec_off = 0; buf_off = 0; for (i = 0; i < iov_cnt && size; i++) { if (iov_off < (iovec_off + iov[i].iov_len)) { size_t len = MIN((iovec_off + iov[i].iov_len) - iov_off , size); memcpy(ptr + buf_off, iov[i].iov_base + (iov_off - iovec_off), len); buf_off += len; iov_off += len; size -= len; } iovec_off += iov[i].iov_len; } return buf_off; }


void hmp_savevm(Monitor *mon, const QDict *qdict) { BlockDriverState *bs, *bs1; QEMUSnapshotInfo sn1, *sn = &sn1, old_sn1, *old_sn = &old_sn1; int ret; QEMUFile *f; int saved_vm_running; uint64_t vm_state_size; qemu_timeval tv; struct tm tm; const char *name = qdict_get_try_str(qdict, "name"); Error *local_err = NULL; AioContext *aio_context; if (!bdrv_all_can_snapshot(&bs)) { monitor_printf(mon, "Device '%s' is writable but does not " "support snapshots.\n", bdrv_get_device_name(bs)); return; } /* Delete old snapshots of the same name */ if (name && bdrv_all_delete_snapshot(name, &bs1, &local_err) < 0) { error_reportf_err(local_err, "Error while deleting snapshot on device '%s': ", bdrv_get_device_name(bs1)); return; } bs = bdrv_all_find_vmstate_bs(); if (bs == NULL) { monitor_printf(mon, "No block device can accept snapshots\n"); return; } aio_context = bdrv_get_aio_context(bs); saved_vm_running = runstate_is_running(); ret = global_state_store(); if (ret) { monitor_printf(mon, "Error saving global state\n"); return; } vm_stop(RUN_STATE_SAVE_VM); aio_context_acquire(aio_context); memset(sn, 0, sizeof(*sn)); /* fill auxiliary fields */ qemu_gettimeofday(&tv); sn->date_sec = tv.tv_sec; sn->date_nsec = tv.tv_usec * 1000; sn->vm_clock_nsec = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); if (name) { ret = bdrv_snapshot_find(bs, old_sn, name); if (ret >= 0) { pstrcpy(sn->name, sizeof(sn->name), old_sn->name); pstrcpy(sn->id_str, sizeof(sn->id_str), old_sn->id_str); } else { pstrcpy(sn->name, sizeof(sn->name), name); } } else { /* cast below needed for OpenBSD where tv_sec is still 'long' */ localtime_r((const time_t *)&tv.tv_sec, &tm); strftime(sn->name, sizeof(sn->name), "vm-%Y%m%d%H%M%S", &tm); } /* save the VM state */ f = qemu_fopen_bdrv(bs, 1); if (!f) { monitor_printf(mon, "Could not open VM state file\n"); goto the_end; } ret = qemu_savevm_state(f, &local_err); vm_state_size = qemu_ftell(f); qemu_fclose(f); if (ret < 0) { error_report_err(local_err); goto the_end; } ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, &bs); if (ret < 0) { monitor_printf(mon, "Error while creating snapshot on '%s'\n", bdrv_get_device_name(bs)); } the_end: aio_context_release(aio_context); if (saved_vm_running) { vm_start(); } }


static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags) { BDRVQcow2State *s = bs->opaque; int offset_in_cluster; int ret; unsigned int cur_bytes; /* number of sectors in current iteration */ uint64_t cluster_offset; QEMUIOVector hd_qiov; uint64_t bytes_done = 0; uint8_t *cluster_data = NULL; QCowL2Meta *l2meta = NULL; trace_qcow2_writev_start_req(qemu_coroutine_self(), offset, bytes); qemu_iovec_init(&hd_qiov, qiov->niov); s->cluster_cache_offset = -1; /* disable compressed cache */ qemu_co_mutex_lock(&s->lock); while (bytes != 0) { l2meta = NULL; trace_qcow2_writev_start_part(qemu_coroutine_self()); offset_in_cluster = offset_into_cluster(s, offset); cur_bytes = MIN(bytes, INT_MAX); if (bs->encrypted) { cur_bytes = MIN(cur_bytes, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size - offset_in_cluster); } ret = qcow2_alloc_cluster_offset(bs, offset, &cur_bytes, &cluster_offset, &l2meta); if (ret < 0) { goto fail; } assert((cluster_offset & 511) == 0); qemu_iovec_reset(&hd_qiov); qemu_iovec_concat(&hd_qiov, qiov, bytes_done, cur_bytes); if (bs->encrypted) { Error *err = NULL; assert(s->cipher); if (!cluster_data) { cluster_data = qemu_try_blockalign(bs->file->bs, QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); if (cluster_data == NULL) { ret = -ENOMEM; goto fail; } } assert(hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); qemu_iovec_to_buf(&hd_qiov, 0, cluster_data, hd_qiov.size); if (qcow2_encrypt_sectors(s, offset >> BDRV_SECTOR_BITS, cluster_data, cur_bytes >>BDRV_SECTOR_BITS, true, &err) < 0) { error_free(err); ret = -EIO; goto fail; } qemu_iovec_reset(&hd_qiov); qemu_iovec_add(&hd_qiov, cluster_data, cur_bytes); } ret = qcow2_pre_write_overlap_check(bs, 0, cluster_offset + offset_in_cluster, cur_bytes); if (ret < 0) { goto fail; } /* If we need to do COW, check if it's possible to merge the * writing of the guest data together with that of the COW regions. * If it's not possible (or not necessary) then write the * guest data now. */ if (!merge_cow(offset, cur_bytes, &hd_qiov, l2meta)) { qemu_co_mutex_unlock(&s->lock); BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); trace_qcow2_writev_data(qemu_coroutine_self(), cluster_offset + offset_in_cluster); ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster, cur_bytes, &hd_qiov, 0); qemu_co_mutex_lock(&s->lock); if (ret < 0) { goto fail; } } while (l2meta != NULL) { QCowL2Meta *next; ret = qcow2_alloc_cluster_link_l2(bs, l2meta); if (ret < 0) { goto fail; } /* Take the request off the list of running requests */ if (l2meta->nb_clusters != 0) { QLIST_REMOVE(l2meta, next_in_flight); } qemu_co_queue_restart_all(&l2meta->dependent_requests); next = l2meta->next; g_free(l2meta); l2meta = next; } bytes -= cur_bytes; offset += cur_bytes; bytes_done += cur_bytes; trace_qcow2_writev_done_part(qemu_coroutine_self(), cur_bytes); } ret = 0; fail: qemu_co_mutex_unlock(&s->lock); while (l2meta != NULL) { QCowL2Meta *next; if (l2meta->nb_clusters != 0) { QLIST_REMOVE(l2meta, next_in_flight); } qemu_co_queue_restart_all(&l2meta->dependent_requests); next = l2meta->next; g_free(l2meta); l2meta = next; } qemu_iovec_destroy(&hd_qiov); qemu_vfree(cluster_data); trace_qcow2_writev_done_req(qemu_coroutine_self(), ret); return ret; }


static int open_self_maps(void *cpu_env, int fd) { #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) CPUState *cpu = ENV_GET_CPU((CPUArchState *)cpu_env); TaskState *ts = cpu->opaque; #endif FILE *fp; char *line = NULL; size_t len = 0; ssize_t read; fp = fopen("/proc/self/maps", "r"); if (fp == NULL) { return -EACCES; } while ((read = getline(&line, &len, fp)) != -1) { int fields, dev_maj, dev_min, inode; uint64_t min, max, offset; char flag_r, flag_w, flag_x, flag_p; char path[512] = ""; fields = sscanf(line, "%"PRIx64"-%"PRIx64" %c%c%c%c %"PRIx64" %x:%x %d" " %512s", &min, &max, &flag_r, &flag_w, &flag_x, &flag_p, &offset, &dev_maj, &dev_min, &inode, path); if ((fields < 10) || (fields > 11)) { continue; } if (!strncmp(path, "[stack]", 7)) { continue; } if (h2g_valid(min) && h2g_valid(max)) { dprintf(fd, TARGET_ABI_FMT_lx "-" TARGET_ABI_FMT_lx " %c%c%c%c %08" PRIx64 " %02x:%02x %d %s%s\n", h2g(min), h2g(max), flag_r, flag_w, flag_x, flag_p, offset, dev_maj, dev_min, inode, path[0] ? " " : "", path); } } free(line); fclose(fp); #if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) dprintf(fd, "%08llx-%08llx rw-p %08llx 00:00 0 [stack]\n", (unsigned long long)ts->info->stack_limit, (unsigned long long)(ts->info->start_stack + (TARGET_PAGE_SIZE - 1)) & TARGET_PAGE_MASK, (unsigned long long)0); #endif return 0; }


static void qxl_log_cmd_draw(PCIQXLDevice *qxl, QXLDrawable *draw, int group_id) { fprintf(stderr, ": surface_id %d type %s effect %s", draw->surface_id, qxl_name(qxl_draw_type, draw->type), qxl_name(qxl_draw_effect, draw->effect)); switch (draw->type) { case QXL_DRAW_COPY: qxl_log_cmd_draw_copy(qxl, &draw->u.copy, group_id); break; } }


int bdrv_enable_write_cache(BlockDriverState *bs) { return bs->enable_write_cache; }


static int add_doubles_metadata(int count, const char *name, const char *sep, TiffContext *s) { char *ap; int i; double *dp; if (bytestream2_get_bytes_left(&s->gb) < count * sizeof(int64_t)) return -1; dp = av_malloc(count * sizeof(double)); if (!dp) return AVERROR(ENOMEM); for (i = 0; i < count; i++) dp[i] = tget_double(&s->gb, s->le); ap = doubles2str(dp, count, sep); av_freep(&dp); if (!ap) return AVERROR(ENOMEM); av_dict_set(&s->picture.metadata, name, ap, AV_DICT_DONT_STRDUP_VAL); return 0; }


static void device_set_realized(Object *obj, bool value, Error **errp) { DeviceState *dev = DEVICE(obj); DeviceClass *dc = DEVICE_GET_CLASS(dev); HotplugHandler *hotplug_ctrl; BusState *bus; Error *local_err = NULL; bool unattached_parent = false; static int unattached_count; if (dev->hotplugged && !dc->hotpluggable) { error_setg(errp, QERR_DEVICE_NO_HOTPLUG, object_get_typename(obj)); return; } if (value && !dev->realized) { if (!obj->parent) { gchar *name = g_strdup_printf("device[%d]", unattached_count++); object_property_add_child(container_get(qdev_get_machine(), "/unattached"), name, obj, &error_abort); unattached_parent = true; g_free(name); } hotplug_ctrl = qdev_get_hotplug_handler(dev); if (hotplug_ctrl) { hotplug_handler_pre_plug(hotplug_ctrl, dev, &local_err); if (local_err != NULL) { goto fail; } } if (dc->realize) { dc->realize(dev, &local_err); } if (local_err != NULL) { goto fail; } DEVICE_LISTENER_CALL(realize, Forward, dev); if (hotplug_ctrl) { hotplug_handler_plug(hotplug_ctrl, dev, &local_err); } if (local_err != NULL) { goto post_realize_fail; } if (qdev_get_vmsd(dev)) { vmstate_register_with_alias_id(dev, -1, qdev_get_vmsd(dev), dev, dev->instance_id_alias, dev->alias_required_for_version, NULL); } QLIST_FOREACH(bus, &dev->child_bus, sibling) { object_property_set_bool(OBJECT(bus), true, "realized", &local_err); if (local_err != NULL) { goto child_realize_fail; } } if (dev->hotplugged) { device_reset(dev); } dev->pending_deleted_event = false; } else if (!value && dev->realized) { Error **local_errp = NULL; QLIST_FOREACH(bus, &dev->child_bus, sibling) { local_errp = local_err ? NULL : &local_err; object_property_set_bool(OBJECT(bus), false, "realized", local_errp); } if (qdev_get_vmsd(dev)) { vmstate_unregister(dev, qdev_get_vmsd(dev), dev); } if (dc->unrealize) { local_errp = local_err ? NULL : &local_err; dc->unrealize(dev, local_errp); } dev->pending_deleted_event = true; DEVICE_LISTENER_CALL(unrealize, Reverse, dev); } if (local_err != NULL) { goto fail; } dev->realized = value; return; child_realize_fail: QLIST_FOREACH(bus, &dev->child_bus, sibling) { object_property_set_bool(OBJECT(bus), false, "realized", NULL); } if (qdev_get_vmsd(dev)) { vmstate_unregister(dev, qdev_get_vmsd(dev), dev); } post_realize_fail: if (dc->unrealize) { dc->unrealize(dev, NULL); } fail: error_propagate(errp, local_err); if (unattached_parent) { object_unparent(OBJECT(dev)); unattached_count--; } }


static void serial_update_irq(SerialState *s) { uint8_t tmp_iir = UART_IIR_NO_INT; if ((s->ier & UART_IER_RLSI) && (s->lsr & UART_LSR_INT_ANY)) { tmp_iir = UART_IIR_RLSI; } else if ((s->ier & UART_IER_RDI) && s->timeout_ipending) { /* Note that(s->ier & UART_IER_RDI) can mask this interrupt, * this is not in the specification but is observed on existing * hardware. */ tmp_iir = UART_IIR_CTI; } else if ((s->ier & UART_IER_RDI) && (s->lsr & UART_LSR_DR)) { if (!(s->fcr & UART_FCR_FE)) { tmp_iir = UART_IIR_RDI; } else if (s->recv_fifo.count >= s->recv_fifo.itl) { tmp_iir = UART_IIR_RDI; } } else if ((s->ier & UART_IER_THRI) && s->thr_ipending) { tmp_iir = UART_IIR_THRI; } else if ((s->ier & UART_IER_MSI) && (s->msr & UART_MSR_ANY_DELTA)) { tmp_iir = UART_IIR_MSI; } s->iir = tmp_iir | (s->iir & 0xF0); if (tmp_iir != UART_IIR_NO_INT) { qemu_irq_raise(s->irq); } else { qemu_irq_lower(s->irq); } }


static void spapr_add_lmbs(DeviceState *dev, uint64_t addr_start, uint64_t size, uint32_t node, bool dedicated_hp_event_source, Error **errp) { sPAPRDRConnector *drc; uint32_t nr_lmbs = size/SPAPR_MEMORY_BLOCK_SIZE; int i, fdt_offset, fdt_size; void *fdt; uint64_t addr = addr_start; for (i = 0; i < nr_lmbs; i++) { drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, addr / SPAPR_MEMORY_BLOCK_SIZE); g_assert(drc); fdt = create_device_tree(&fdt_size); fdt_offset = spapr_populate_memory_node(fdt, node, addr, SPAPR_MEMORY_BLOCK_SIZE); spapr_drc_attach(drc, dev, fdt, fdt_offset, !dev->hotplugged, errp); addr += SPAPR_MEMORY_BLOCK_SIZE; if (!dev->hotplugged) { sPAPRDRConnectorClass *drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); /* guests expect coldplugged LMBs to be pre-allocated */ drck->set_allocation_state(drc, SPAPR_DR_ALLOCATION_STATE_USABLE); drck->set_isolation_state(drc, SPAPR_DR_ISOLATION_STATE_UNISOLATED); } } /* send hotplug notification to the * guest only in case of hotplugged memory */ if (dev->hotplugged) { if (dedicated_hp_event_source) { drc = spapr_drc_by_id(TYPE_SPAPR_DRC_LMB, addr_start / SPAPR_MEMORY_BLOCK_SIZE); spapr_hotplug_req_add_by_count_indexed(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs, spapr_drc_index(drc)); } else { spapr_hotplug_req_add_by_count(SPAPR_DR_CONNECTOR_TYPE_LMB, nr_lmbs); } } }


static int vdi_open(BlockDriverState *bs, int flags) { BDRVVdiState *s = bs->opaque; VdiHeader header; size_t bmap_size; int ret; logout("\n"); ret = bdrv_read(bs->file, 0, (uint8_t *)&header, 1); if (ret < 0) { goto fail; } vdi_header_to_cpu(&header); #if defined(CONFIG_VDI_DEBUG) vdi_header_print(&header); #endif if (header.disk_size % SECTOR_SIZE != 0) { /* 'VBoxManage convertfromraw' can create images with odd disk sizes. We accept them but round the disk size to the next multiple of SECTOR_SIZE. */ logout("odd disk size %" PRIu64 " B, round up\n", header.disk_size); header.disk_size += SECTOR_SIZE - 1; header.disk_size &= ~(SECTOR_SIZE - 1); } if (header.version != VDI_VERSION_1_1) { logout("unsupported version %u.%u\n", header.version >> 16, header.version & 0xffff); ret = -ENOTSUP; goto fail; } else if (header.offset_bmap % SECTOR_SIZE != 0) { /* We only support block maps which start on a sector boundary. */ logout("unsupported block map offset 0x%x B\n", header.offset_bmap); ret = -ENOTSUP; goto fail; } else if (header.offset_data % SECTOR_SIZE != 0) { /* We only support data blocks which start on a sector boundary. */ logout("unsupported data offset 0x%x B\n", header.offset_data); ret = -ENOTSUP; goto fail; } else if (header.sector_size != SECTOR_SIZE) { logout("unsupported sector size %u B\n", header.sector_size); ret = -ENOTSUP; goto fail; } else if (header.block_size != 1 * MiB) { logout("unsupported block size %u B\n", header.block_size); ret = -ENOTSUP; goto fail; } else if (header.disk_size > (uint64_t)header.blocks_in_image * header.block_size) { logout("unsupported disk size %" PRIu64 " B\n", header.disk_size); ret = -ENOTSUP; goto fail; } else if (!uuid_is_null(header.uuid_link)) { logout("link uuid != 0, unsupported\n"); ret = -ENOTSUP; goto fail; } else if (!uuid_is_null(header.uuid_parent)) { logout("parent uuid != 0, unsupported\n"); ret = -ENOTSUP; goto fail; } bs->total_sectors = header.disk_size / SECTOR_SIZE; s->block_size = header.block_size; s->block_sectors = header.block_size / SECTOR_SIZE; s->bmap_sector = header.offset_bmap / SECTOR_SIZE; s->header = header; bmap_size = header.blocks_in_image * sizeof(uint32_t); bmap_size = (bmap_size + SECTOR_SIZE - 1) / SECTOR_SIZE; if (bmap_size > 0) { s->bmap = g_malloc(bmap_size * SECTOR_SIZE); } ret = bdrv_read(bs->file, s->bmap_sector, (uint8_t *)s->bmap, bmap_size); if (ret < 0) { goto fail_free_bmap; } /* Disable migration when vdi images are used */ error_set(&s->migration_blocker, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED, "vdi", bs->device_name, "live migration"); migrate_add_blocker(s->migration_blocker); return 0; fail_free_bmap: g_free(s->bmap); fail: return ret; }


qemu_irq isa_reserve_irq(int isairq) { if (isairq < 0 || isairq > 15) { hw_error("isa irq %d invalid", isairq); } if (isabus->assigned & (1 << isairq)) { hw_error("isa irq %d already assigned", isairq); } isabus->assigned |= (1 << isairq); return isabus->irqs[isairq]; }


S390CPU *cpu_s390x_create(const char *cpu_model, Error **errp) { static bool features_parsed; char *name, *features; const char *typename; ObjectClass *oc; CPUClass *cc; name = g_strdup(cpu_model); features = strchr(name, ','); if (features) { features[0] = 0; features++; } oc = cpu_class_by_name(TYPE_S390_CPU, name); if (!oc) { error_setg(errp, "Unknown CPU definition \'%s\'", name); g_free(name); return NULL; } typename = object_class_get_name(oc); if (!features_parsed) { features_parsed = true; cc = CPU_CLASS(oc); cc->parse_features(typename, features, errp); } g_free(name); if (*errp) { return NULL; } return S390_CPU(CPU(object_new(typename))); }


static inline void pit_load_count(PITChannelState *s, int val) { if (val == 0) val = 0x10000; s->count_load_time = cpu_get_ticks(); s->count_last_edge_check_time = s->count_load_time; s->count = val; if (s == &pit_channels[0] && val <= pit_min_timer_count) { fprintf(stderr, "\nWARNING: qemu: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.5.xx Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.\n\n", PIT_FREQ / pit_min_timer_count); } }


static int usbredir_handle_bulk_data(USBRedirDevice *dev, USBPacket *p, uint8_t ep) { AsyncURB *aurb = async_alloc(dev, p); struct usb_redir_bulk_packet_header bulk_packet; DPRINTF("bulk-out ep %02X len %zd id %u\n", ep, p->iov.size, aurb->packet_id); bulk_packet.endpoint = ep; bulk_packet.length = p->iov.size; bulk_packet.stream_id = 0; aurb->bulk_packet = bulk_packet; if (ep & USB_DIR_IN) { usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id, &bulk_packet, NULL, 0); } else { uint8_t buf[p->iov.size]; usb_packet_copy(p, buf, p->iov.size); usbredir_log_data(dev, "bulk data out:", buf, p->iov.size); usbredirparser_send_bulk_packet(dev->parser, aurb->packet_id, &bulk_packet, buf, p->iov.size); } usbredirparser_do_write(dev->parser); return USB_RET_ASYNC; }


static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; AVFrame * const newpic = &c93->pictures[c93->currentpic]; AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; AVFrame *picture = data; uint8_t *out; int stride, i, x, y, bt = 0; c93->currentpic ^= 1; newpic->reference = 1; newpic->buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE | FF_BUFFER_HINTS_READABLE; if (avctx->reget_buffer(avctx, newpic)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; } stride = newpic->linesize[0]; if (buf[0] & C93_FIRST_FRAME) { newpic->pict_type = AV_PICTURE_TYPE_I; newpic->key_frame = 1; } else { newpic->pict_type = AV_PICTURE_TYPE_P; newpic->key_frame = 0; } if (*buf++ & C93_HAS_PALETTE) { uint32_t *palette = (uint32_t *) newpic->data[1]; const uint8_t *palbuf = buf + buf_size - 768 - 1; for (i = 0; i < 256; i++) { palette[i] = bytestream_get_be24(&palbuf); } } else { if (oldpic->data[1]) memcpy(newpic->data[1], oldpic->data[1], 256 * 4); } for (y = 0; y < HEIGHT; y += 8) { out = newpic->data[0] + y * stride; for (x = 0; x < WIDTH; x += 8) { uint8_t *copy_from = oldpic->data[0]; unsigned int offset, j; uint8_t cols[4], grps[4]; C93BlockType block_type; if (!bt) bt = *buf++; block_type= bt & 0x0F; switch (block_type) { case C93_8X8_FROM_PREV: offset = bytestream_get_le16(&buf); if (copy_block(avctx, out, copy_from, offset, 8, stride)) return -1; break; case C93_4X4_FROM_CURR: copy_from = newpic->data[0]; case C93_4X4_FROM_PREV: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { offset = bytestream_get_le16(&buf); if (copy_block(avctx, &out[j*stride+i], copy_from, offset, 4, stride)) return -1; } } break; case C93_8X8_2COLOR: bytestream_get_buffer(&buf, cols, 2); for (i = 0; i < 8; i++) { draw_n_color(out + i*stride, stride, 8, 1, 1, cols, NULL, *buf++); } break; case C93_4X4_2COLOR: case C93_4X4_4COLOR: case C93_4X4_4COLOR_GRP: for (j = 0; j < 8; j += 4) { for (i = 0; i < 8; i += 4) { if (block_type == C93_4X4_2COLOR) { bytestream_get_buffer(&buf, cols, 2); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, NULL, bytestream_get_le16(&buf)); } else if (block_type == C93_4X4_4COLOR) { bytestream_get_buffer(&buf, cols, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 2, cols, NULL, bytestream_get_le32(&buf)); } else { bytestream_get_buffer(&buf, grps, 4); draw_n_color(out + i + j*stride, stride, 4, 4, 1, cols, grps, bytestream_get_le16(&buf)); } } } break; case C93_NOOP: break; case C93_8X8_INTRA: for (j = 0; j < 8; j++) bytestream_get_buffer(&buf, out + j*stride, 8); break; default: av_log(avctx, AV_LOG_ERROR, "unexpected type %x at %dx%d\n", block_type, x, y); return -1; } bt >>= 4; out += 8; } } *picture = *newpic; *data_size = sizeof(AVFrame); return buf_size; }


static int filter_frame(AVFilterLink *inlink, AVFilterBufferRef *in) { HQDN3DContext *hqdn3d = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; AVFilterBufferRef *out; int direct, c; if (in->perms & AV_PERM_WRITE) { direct = 1; out = in; } else { out = ff_get_video_buffer(outlink, AV_PERM_WRITE, outlink->w, outlink->h); if (!out) { avfilter_unref_bufferp(&in); return AVERROR(ENOMEM); } avfilter_copy_buffer_ref_props(out, in); out->video->w = outlink->w; out->video->h = outlink->h; } for (c = 0; c < 3; c++) { denoise(hqdn3d, in->data[c], out->data[c], hqdn3d->line, &hqdn3d->frame_prev[c], in->video->w >> (!!c * hqdn3d->hsub), in->video->h >> (!!c * hqdn3d->vsub), in->linesize[c], out->linesize[c], hqdn3d->coefs[c?2:0], hqdn3d->coefs[c?3:1]); } if (!direct) avfilter_unref_bufferp(&in); return ff_filter_frame(outlink, out); }


void *qemu_blockalign(BlockDriverState *bs, size_t size) { return qemu_memalign((bs && bs->buffer_alignment) ? bs->buffer_alignment : 512, size); }


static int ehci_fill_queue(EHCIPacket *p) { USBEndpoint *ep = p->packet.ep; EHCIQueue *q = p->queue; EHCIqtd qtd = p->qtd; uint32_t qtdaddr; for (;;) { if (NLPTR_TBIT(qtd.next) != 0) { qtdaddr = qtd.next; /* * Detect circular td lists, Windows creates these, counting on the * active bit going low after execution to make the queue stop. */ QTAILQ_FOREACH(p, &q->packets, next) { if (p->qtdaddr == qtdaddr) { goto leave; if (get_dwords(q->ehci, NLPTR_GET(qtdaddr), (uint32_t *) &qtd, sizeof(EHCIqtd) >> 2) < 0) { return -1; ehci_trace_qtd(q, NLPTR_GET(qtdaddr), &qtd); if (!(qtd.token & QTD_TOKEN_ACTIVE)) { p = ehci_alloc_packet(q); p->qtdaddr = qtdaddr; p->qtd = qtd; if (ehci_execute(p, "queue") == -1) { return -1; assert(p->packet.status == USB_RET_ASYNC); p->async = EHCI_ASYNC_INFLIGHT; leave: usb_device_flush_ep_queue(ep->dev, ep); return 1;


void bdrv_close(BlockDriverState *bs) { if (bs->drv) { if (bs->backing_hd) bdrv_delete(bs->backing_hd); bs->drv->bdrv_close(bs); qemu_free(bs->opaque); #ifdef _WIN32 if (bs->is_temporary) { unlink(bs->filename); } #endif bs->opaque = NULL; bs->drv = NULL; /* call the change callback */ bs->total_sectors = 0; bs->media_changed = 1; if (bs->change_cb) bs->change_cb(bs->change_opaque); } }