static uint64_t ehci_opreg_read(void *ptr, hwaddr addr, unsigned size) { EHCIState *s = ptr; uint32_t val; val = s->opreg[addr >> 2]; trace_usb_ehci_opreg_read(addr + s->opregbase, addr2str(addr), val); return val; }


static void qemu_fflush(QEMUFile *f) { int ret = 0; if (!f->ops->put_buffer) { return; } if (f->is_write && f->buf_index > 0) { ret = f->ops->put_buffer(f->opaque, f->buf, f->buf_offset, f->buf_index); if (ret >= 0) { f->buf_offset += f->buf_index; } f->buf_index = 0; } if (ret < 0) { qemu_file_set_error(f, ret); } }


static void omap_mpui_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; if (size != 4) { return omap_badwidth_write32(opaque, addr, value); } switch (addr) { case 0x00: /* CTRL */ s->mpui_ctrl = value & 0x007fffff; break; case 0x04: /* DEBUG_ADDR */ case 0x08: /* DEBUG_DATA */ case 0x0c: /* DEBUG_FLAG */ case 0x10: /* STATUS */ /* Not in OMAP310 */ case 0x14: /* DSP_STATUS */ OMAP_RO_REG(addr); case 0x18: /* DSP_BOOT_CONFIG */ case 0x1c: /* DSP_MPUI_CONFIG */ break; default: OMAP_BAD_REG(addr); } }


static void sdl_mouse_mode_change(Notifier *notify, void *data) { if (kbd_mouse_is_absolute()) { if (!absolute_enabled) { sdl_hide_cursor(); if (gui_grab) { sdl_grab_end(); } absolute_enabled = 1; } } else if (absolute_enabled) { sdl_show_cursor(); absolute_enabled = 0; } }


static int mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer) { int category_index[128]; int quant_index_table[102]; int category[128]; int ret; memset(&category, 0, sizeof(category)); memset(&category_index, 0, sizeof(category_index)); if ((ret = decode_envelope(q, p, quant_index_table)) < 0) return ret; q->num_vectors = get_bits(&q->gb, p->log2_numvector_size); categorize(q, p, quant_index_table, category, category_index); expand_category(q, category, category_index); decode_vectors(q, p, category, quant_index_table, mlt_buffer); return 0; }


static void omap_clkm_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { struct omap_mpu_state_s *s = (struct omap_mpu_state_s *) opaque; uint16_t diff; omap_clk clk; static const char *clkschemename[8] = { "fully synchronous", "fully asynchronous", "synchronous scalable", "mix mode 1", "mix mode 2", "bypass mode", "mix mode 3", "mix mode 4", }; if (size != 2) { return omap_badwidth_write16(opaque, addr, value); } switch (addr) { case 0x00: /* ARM_CKCTL */ diff = s->clkm.arm_ckctl ^ value; s->clkm.arm_ckctl = value & 0x7fff; omap_clkm_ckctl_update(s, diff, value); return; case 0x04: /* ARM_IDLECT1 */ diff = s->clkm.arm_idlect1 ^ value; s->clkm.arm_idlect1 = value & 0x0fff; omap_clkm_idlect1_update(s, diff, value); return; case 0x08: /* ARM_IDLECT2 */ diff = s->clkm.arm_idlect2 ^ value; s->clkm.arm_idlect2 = value & 0x07ff; omap_clkm_idlect2_update(s, diff, value); return; case 0x0c: /* ARM_EWUPCT */ s->clkm.arm_ewupct = value & 0x003f; return; case 0x10: /* ARM_RSTCT1 */ diff = s->clkm.arm_rstct1 ^ value; s->clkm.arm_rstct1 = value & 0x0007; if (value & 9) { qemu_system_reset_request(); s->clkm.cold_start = 0xa; } if (diff & ~value & 4) { /* DSP_RST */ omap_mpui_reset(s); omap_tipb_bridge_reset(s->private_tipb); omap_tipb_bridge_reset(s->public_tipb); } if (diff & 2) { /* DSP_EN */ clk = omap_findclk(s, "dsp_ck"); omap_clk_canidle(clk, (~value >> 1) & 1); } return; case 0x14: /* ARM_RSTCT2 */ s->clkm.arm_rstct2 = value & 0x0001; return; case 0x18: /* ARM_SYSST */ if ((s->clkm.clocking_scheme ^ (value >> 11)) & 7) { s->clkm.clocking_scheme = (value >> 11) & 7; printf("%s: clocking scheme set to %s\n", __FUNCTION__, clkschemename[s->clkm.clocking_scheme]); } s->clkm.cold_start &= value & 0x3f; return; case 0x1c: /* ARM_CKOUT1 */ diff = s->clkm.arm_ckout1 ^ value; s->clkm.arm_ckout1 = value & 0x003f; omap_clkm_ckout1_update(s, diff, value); return; case 0x20: /* ARM_CKOUT2 */ default: OMAP_BAD_REG(addr); } }


static int cuvid_test_dummy_decoder(AVCodecContext *avctx, const CUVIDPARSERPARAMS *cuparseinfo, int probed_width, int probed_height) { CuvidContext *ctx = avctx->priv_data; CUVIDDECODECREATEINFO cuinfo; CUvideodecoder cudec = 0; int ret = 0; memset(&cuinfo, 0, sizeof(cuinfo)); cuinfo.CodecType = cuparseinfo->CodecType; cuinfo.ChromaFormat = cudaVideoChromaFormat_420; cuinfo.OutputFormat = cudaVideoSurfaceFormat_NV12; cuinfo.ulWidth = probed_width; cuinfo.ulHeight = probed_height; cuinfo.ulTargetWidth = cuinfo.ulWidth; cuinfo.ulTargetHeight = cuinfo.ulHeight; cuinfo.target_rect.left = 0; cuinfo.target_rect.top = 0; cuinfo.target_rect.right = cuinfo.ulWidth; cuinfo.target_rect.bottom = cuinfo.ulHeight; cuinfo.ulNumDecodeSurfaces = ctx->nb_surfaces; cuinfo.ulNumOutputSurfaces = 1; cuinfo.ulCreationFlags = cudaVideoCreate_PreferCUVID; cuinfo.bitDepthMinus8 = 0; cuinfo.DeinterlaceMode = cudaVideoDeinterlaceMode_Weave; ret = CHECK_CU(ctx->cvdl->cuvidCreateDecoder(&cudec, &cuinfo)); if (ret < 0) return ret; ret = CHECK_CU(ctx->cvdl->cuvidDestroyDecoder(cudec)); if (ret < 0) return ret; return 0; }


static void vfio_intp_inject_pending_lockheld(VFIOINTp *intp) { trace_vfio_platform_intp_inject_pending_lockheld(intp->pin, event_notifier_get_fd(&intp->interrupt)); intp->state = VFIO_IRQ_ACTIVE; /* trigger the virtual IRQ */ qemu_set_irq(intp->qemuirq, 1); }


void qemu_spice_display_resize(SimpleSpiceDisplay *ssd) { dprint(1, "%s:\n", __FUNCTION__); pthread_mutex_lock(&ssd->lock); memset(&ssd->dirty, 0, sizeof(ssd->dirty)); qemu_pf_conv_put(ssd->conv); ssd->conv = NULL; pthread_mutex_unlock(&ssd->lock); qemu_spice_destroy_host_primary(ssd); qemu_spice_create_host_primary(ssd); pthread_mutex_lock(&ssd->lock); memset(&ssd->dirty, 0, sizeof(ssd->dirty)); ssd->notify++; pthread_mutex_unlock(&ssd->lock); }


void qemu_savevm_state_cancel(Monitor *mon, QEMUFile *f) { SaveStateEntry *se; QTAILQ_FOREACH(se, &savevm_handlers, entry) { if (se->save_live_state) { se->save_live_state(mon, f, -1, se->opaque); } } }


VLANState *qemu_find_vlan(int id, int allocate) { VLANState **pvlan, *vlan; for(vlan = first_vlan; vlan != NULL; vlan = vlan->next) { if (vlan->id == id) return vlan; } if (!allocate) { return NULL; } vlan = qemu_mallocz(sizeof(VLANState)); vlan->id = id; TAILQ_INIT(&vlan->send_queue); vlan->next = NULL; pvlan = &first_vlan; while (*pvlan != NULL) pvlan = &(*pvlan)->next; *pvlan = vlan; return vlan; }


static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, BlockDriverAmendStatusCB *status_cb) { BDRVQcowState *s = bs->opaque; int old_version = s->qcow_version, new_version = old_version; uint64_t new_size = 0; const char *backing_file = NULL, *backing_format = NULL; bool lazy_refcounts = s->use_lazy_refcounts; const char *compat = NULL; uint64_t cluster_size = s->cluster_size; bool encrypt; int ret; QemuOptDesc *desc = opts->list->desc; while (desc && desc->name) { if (!qemu_opt_find(opts, desc->name)) { /* only change explicitly defined options */ desc++; continue; } if (!strcmp(desc->name, BLOCK_OPT_COMPAT_LEVEL)) { compat = qemu_opt_get(opts, BLOCK_OPT_COMPAT_LEVEL); if (!compat) { /* preserve default */ } else if (!strcmp(compat, "0.10")) { new_version = 2; } else if (!strcmp(compat, "1.1")) { new_version = 3; } else { fprintf(stderr, "Unknown compatibility level %s.\n", compat); return -EINVAL; } } else if (!strcmp(desc->name, BLOCK_OPT_PREALLOC)) { fprintf(stderr, "Cannot change preallocation mode.\n"); return -ENOTSUP; } else if (!strcmp(desc->name, BLOCK_OPT_SIZE)) { new_size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0); } else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FILE)) { backing_file = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE); } else if (!strcmp(desc->name, BLOCK_OPT_BACKING_FMT)) { backing_format = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT); } else if (!strcmp(desc->name, BLOCK_OPT_ENCRYPT)) { encrypt = qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, s->crypt_method); if (encrypt != !!s->crypt_method) { fprintf(stderr, "Changing the encryption flag is not " "supported.\n"); return -ENOTSUP; } } else if (!strcmp(desc->name, BLOCK_OPT_CLUSTER_SIZE)) { cluster_size = qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, cluster_size); if (cluster_size != s->cluster_size) { fprintf(stderr, "Changing the cluster size is not " "supported.\n"); return -ENOTSUP; } } else if (!strcmp(desc->name, BLOCK_OPT_LAZY_REFCOUNTS)) { lazy_refcounts = qemu_opt_get_bool(opts, BLOCK_OPT_LAZY_REFCOUNTS, lazy_refcounts); } else if (!strcmp(desc->name, BLOCK_OPT_REFCOUNT_BITS)) { error_report("Cannot change refcount entry width"); return -ENOTSUP; } else { /* if this assertion fails, this probably means a new option was * added without having it covered here */ assert(false); } desc++; } if (new_version != old_version) { if (new_version > old_version) { /* Upgrade */ s->qcow_version = new_version; ret = qcow2_update_header(bs); if (ret < 0) { s->qcow_version = old_version; return ret; } } else { ret = qcow2_downgrade(bs, new_version, status_cb); if (ret < 0) { return ret; } } } if (backing_file || backing_format) { ret = qcow2_change_backing_file(bs, backing_file ?: bs->backing_file, backing_format ?: bs->backing_format); if (ret < 0) { return ret; } } if (s->use_lazy_refcounts != lazy_refcounts) { if (lazy_refcounts) { if (s->qcow_version < 3) { fprintf(stderr, "Lazy refcounts only supported with compatibility " "level 1.1 and above (use compat=1.1 or greater)\n"); return -EINVAL; } s->compatible_features |= QCOW2_COMPAT_LAZY_REFCOUNTS; ret = qcow2_update_header(bs); if (ret < 0) { s->compatible_features &= ~QCOW2_COMPAT_LAZY_REFCOUNTS; return ret; } s->use_lazy_refcounts = true; } else { /* make image clean first */ ret = qcow2_mark_clean(bs); if (ret < 0) { return ret; } /* now disallow lazy refcounts */ s->compatible_features &= ~QCOW2_COMPAT_LAZY_REFCOUNTS; ret = qcow2_update_header(bs); if (ret < 0) { s->compatible_features |= QCOW2_COMPAT_LAZY_REFCOUNTS; return ret; } s->use_lazy_refcounts = false; } } if (new_size) { ret = bdrv_truncate(bs, new_size); if (ret < 0) { return ret; } } return 0; }


void aio_set_event_notifier(AioContext *ctx, EventNotifier *e, bool is_external, EventNotifierHandler *io_notify, AioPollFn *io_poll) { AioHandler *node; qemu_lockcnt_lock(&ctx->list_lock); QLIST_FOREACH(node, &ctx->aio_handlers, node) { if (node->e == e && !node->deleted) { break; } } /* Are we deleting the fd handler? */ if (!io_notify) { if (node) { g_source_remove_poll(&ctx->source, &node->pfd); /* aio_poll is in progress, just mark the node as deleted */ if (qemu_lockcnt_count(&ctx->list_lock)) { node->deleted = 1; node->pfd.revents = 0; } else { /* Otherwise, delete it for real. We can't just mark it as * deleted because deleted nodes are only cleaned up after * releasing the list_lock. */ QLIST_REMOVE(node, node); g_free(node); } } } else { if (node == NULL) { /* Alloc and insert if it's not already there */ node = g_new0(AioHandler, 1); node->e = e; node->pfd.fd = (uintptr_t)event_notifier_get_handle(e); node->pfd.events = G_IO_IN; node->is_external = is_external; QLIST_INSERT_HEAD_RCU(&ctx->aio_handlers, node, node); g_source_add_poll(&ctx->source, &node->pfd); } /* Update handler with latest information */ node->io_notify = io_notify; } qemu_lockcnt_unlock(&ctx->list_lock); aio_notify(ctx); }


static int ehci_state_fetchqtd(EHCIQueue *q) { EHCIqtd qtd; EHCIPacket *p; int again = 0; get_dwords(q->ehci, NLPTR_GET(q->qtdaddr), (uint32_t *) &qtd, sizeof(EHCIqtd) >> 2); ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), &qtd); p = QTAILQ_FIRST(&q->packets); if (p != NULL) { if (p->qtdaddr != q->qtdaddr || (!NLPTR_TBIT(p->qtd.next) && (p->qtd.next != qtd.next)) || (!NLPTR_TBIT(p->qtd.altnext) && (p->qtd.altnext != qtd.altnext)) || p->qtd.bufptr[0] != qtd.bufptr[0]) { ehci_cancel_queue(q); ehci_trace_guest_bug(q->ehci, "guest updated active QH or qTD"); p = NULL; } else { p->qtd = qtd; ehci_qh_do_overlay(q); } } if (!(qtd.token & QTD_TOKEN_ACTIVE)) { if (p != NULL) { /* transfer canceled by guest (clear active) */ ehci_cancel_queue(q); p = NULL; } ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); again = 1; } else if (p != NULL) { switch (p->async) { case EHCI_ASYNC_NONE: case EHCI_ASYNC_INITIALIZED: /* Not yet executed (MULT), or previously nacked (int) packet */ ehci_set_state(q->ehci, q->async, EST_EXECUTE); break; case EHCI_ASYNC_INFLIGHT: /* Unfinished async handled packet, go horizontal */ ehci_set_state(q->ehci, q->async, EST_HORIZONTALQH); break; case EHCI_ASYNC_FINISHED: /* * We get here when advqueue moves to a packet which is already * finished, which can happen with packets queued up by fill_queue */ ehci_set_state(q->ehci, q->async, EST_EXECUTING); break; } again = 1; } else { p = ehci_alloc_packet(q); p->qtdaddr = q->qtdaddr; p->qtd = qtd; ehci_set_state(q->ehci, q->async, EST_EXECUTE); again = 1; } return again; }


int net_init_hubport(const NetClientOptions *opts, const char *name, NetClientState *peer) { const NetdevHubPortOptions *hubport; assert(opts->kind == NET_CLIENT_OPTIONS_KIND_HUBPORT); hubport = opts->hubport; if (peer) { return -EINVAL; } net_hub_add_port(hubport->hubid, name); return 0; }


int cpu_breakpoint_remove(CPUState *env, target_ulong pc, int flags) { #if defined(TARGET_HAS_ICE) CPUBreakpoint *bp; TAILQ_FOREACH(bp, &env->breakpoints, entry) { if (bp->pc == pc && bp->flags == flags) { cpu_breakpoint_remove_by_ref(env, bp); return 0; } } return -ENOENT; #else return -ENOSYS; #endif }


static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) { const int data_ptr = 2 + AV_RL16(&buf[0]); int d, r, y; d = data_ptr; r = 2; y = 0; while(r < data_ptr) { int i, j; int length = buf[r] & 0x7f; int x = buf[r+1] + ((buf[r] & 0x80) << 1); r += 2; if (length==0) { y += x; continue; } for(i=0; i<length; i++) { for(j=0; j<8; j++) { int replace = (buf[r+i] >> (7-j)) & 1; if (replace) { int color = buf[d]; s->frame.data[0][y*s->frame.linesize[0] + x] = color; if (half_horiz) s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; if (half_vert) { s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color; if (half_horiz) s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color; } d++; } x += half_horiz ? 2 : 1; } } r += length; y += half_vert ? 2 : 1; } }


static void pxa2xx_ssp_fifo_update(PXA2xxSSPState *s) { s->sssr &= ~(0xf << 12); /* Clear RFL */ s->sssr &= ~(0xf << 8); /* Clear TFL */ s->sssr &= ~SSSR_TNF; if (s->enable) { s->sssr |= ((s->rx_level - 1) & 0xf) << 12; if (s->rx_level >= SSCR1_RFT(s->sscr[1])) s->sssr |= SSSR_RFS; else s->sssr &= ~SSSR_RFS; if (0 <= SSCR1_TFT(s->sscr[1])) s->sssr |= SSSR_TFS; else s->sssr &= ~SSSR_TFS; if (s->rx_level) s->sssr |= SSSR_RNE; else s->sssr &= ~SSSR_RNE; s->sssr |= SSSR_TNF; } pxa2xx_ssp_int_update(s); }


static void grlib_apbuart_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { UART *uart = opaque; unsigned char c = 0; addr &= 0xff; /* Unit registers */ switch (addr) { case DATA_OFFSET: case DATA_OFFSET + 3: /* When only one byte write */ c = value & 0xFF; qemu_chr_fe_write(uart->chr, &c, 1); return; case STATUS_OFFSET: /* Read Only */ return; case CONTROL_OFFSET: uart->control = value; return; case SCALER_OFFSET: /* Not supported */ return; default: break; } trace_grlib_apbuart_writel_unknown(addr, value); }


int cpu_x86_handle_mmu_fault(CPUX86State *env, uint32_t addr, int is_write, int is_user, int is_softmmu) { uint8_t *pde_ptr, *pte_ptr; uint32_t pde, pte, virt_addr, ptep; int error_code, is_dirty, prot, page_size, ret; unsigned long paddr, vaddr, page_offset; #if defined(DEBUG_MMU) printf("MMU fault: addr=0x%08x w=%d u=%d eip=%08x\n", addr, is_write, is_user, env->eip); #endif if (env->user_mode_only) { /* user mode only emulation */ error_code = 0; goto do_fault; } if (!(env->cr[0] & CR0_PG_MASK)) { pte = addr; virt_addr = addr & TARGET_PAGE_MASK; prot = PROT_READ | PROT_WRITE; page_size = 4096; goto do_mapping; } /* page directory entry */ pde_ptr = phys_ram_base + (((env->cr[3] & ~0xfff) + ((addr >> 20) & ~3)) & a20_mask); pde = ldl_raw(pde_ptr); if (!(pde & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } /* if PSE bit is set, then we use a 4MB page */ if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { if (is_user) { if (!(pde & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(pde & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && (pde & PG_USER_MASK) && is_write && !(pde & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pde & PG_DIRTY_MASK); if (!(pde & PG_ACCESSED_MASK) || is_dirty) { pde |= PG_ACCESSED_MASK; if (is_dirty) pde |= PG_DIRTY_MASK; stl_raw(pde_ptr, pde); } pte = pde & ~0x003ff000; /* align to 4MB */ ptep = pte; page_size = 4096 * 1024; virt_addr = addr & ~0x003fffff; } else { if (!(pde & PG_ACCESSED_MASK)) { pde |= PG_ACCESSED_MASK; stl_raw(pde_ptr, pde); } /* page directory entry */ pte_ptr = phys_ram_base + (((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & a20_mask); pte = ldl_raw(pte_ptr); if (!(pte & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } /* combine pde and pte user and rw protections */ ptep = pte & pde; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && (ptep & PG_USER_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { pte |= PG_ACCESSED_MASK; if (is_dirty) pte |= PG_DIRTY_MASK; stl_raw(pte_ptr, pte); } page_size = 4096; virt_addr = addr & ~0xfff; } /* the page can be put in the TLB */ prot = PROT_READ; if (pte & PG_DIRTY_MASK) { /* only set write access if already dirty... otherwise wait for dirty access */ if (is_user) { if (ptep & PG_RW_MASK) prot |= PROT_WRITE; } else { if (!(env->cr[0] & CR0_WP_MASK) || !(ptep & PG_USER_MASK) || (ptep & PG_RW_MASK)) prot |= PROT_WRITE; } } do_mapping: pte = pte & a20_mask; /* Even if 4MB pages, we map only one 4KB page in the cache to avoid filling it too fast */ page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); paddr = (pte & TARGET_PAGE_MASK) + page_offset; vaddr = virt_addr + page_offset; ret = tlb_set_page(env, vaddr, paddr, prot, is_user, is_softmmu); return ret; do_fault_protect: error_code = PG_ERROR_P_MASK; do_fault: env->cr[2] = addr; env->error_code = (is_write << PG_ERROR_W_BIT) | error_code; if (is_user) env->error_code |= PG_ERROR_U_MASK; return 1; }


static void term_delete_char(void) { if (term_cmd_buf_index < term_cmd_buf_size) { memmove(term_cmd_buf + term_cmd_buf_index, term_cmd_buf + term_cmd_buf_index + 1, term_cmd_buf_size - term_cmd_buf_index - 1); term_cmd_buf_size--; } }


static void sch_handle_start_func(SubchDev *sch, ORB *orb) { PMCW *p = &sch->curr_status.pmcw; SCSW *s = &sch->curr_status.scsw; int path; int ret; bool suspend_allowed; /* Path management: In our simple css, we always choose the only path. */ path = 0x80; if (!(s->ctrl & SCSW_ACTL_SUSP)) { /* Start Function triggered via ssch, i.e. we have an ORB */ s->cstat = 0; s->dstat = 0; /* Look at the orb and try to execute the channel program. */ assert(orb != NULL); /* resume does not pass an orb */ p->intparm = orb->intparm; if (!(orb->lpm & path)) { /* Generate a deferred cc 3 condition. */ s->flags |= SCSW_FLAGS_MASK_CC; s->ctrl &= ~SCSW_CTRL_MASK_STCTL; s->ctrl |= (SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND); return; } sch->ccw_fmt_1 = !!(orb->ctrl0 & ORB_CTRL0_MASK_FMT); s->flags |= (sch->ccw_fmt_1) ? SCSW_FLAGS_MASK_FMT : 0; sch->ccw_no_data_cnt = 0; suspend_allowed = !!(orb->ctrl0 & ORB_CTRL0_MASK_SPND); } else { /* Start Function resumed via rsch, i.e. we don't have an * ORB */ s->ctrl &= ~(SCSW_ACTL_SUSP | SCSW_ACTL_RESUME_PEND); /* The channel program had been suspended before. */ suspend_allowed = true; } sch->last_cmd_valid = false; do { ret = css_interpret_ccw(sch, sch->channel_prog, suspend_allowed); switch (ret) { case -EAGAIN: /* ccw chain, continue processing */ break; case 0: /* success */ s->ctrl &= ~SCSW_ACTL_START_PEND; s->ctrl &= ~SCSW_CTRL_MASK_STCTL; s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | SCSW_STCTL_STATUS_PEND; s->dstat = SCSW_DSTAT_CHANNEL_END | SCSW_DSTAT_DEVICE_END; s->cpa = sch->channel_prog + 8; break; case -EIO: /* I/O errors, status depends on specific devices */ break; case -ENOSYS: /* unsupported command, generate unit check (command reject) */ s->ctrl &= ~SCSW_ACTL_START_PEND; s->dstat = SCSW_DSTAT_UNIT_CHECK; /* Set sense bit 0 in ecw0. */ sch->sense_data[0] = 0x80; s->ctrl &= ~SCSW_CTRL_MASK_STCTL; s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; s->cpa = sch->channel_prog + 8; break; case -EFAULT: /* memory problem, generate channel data check */ s->ctrl &= ~SCSW_ACTL_START_PEND; s->cstat = SCSW_CSTAT_DATA_CHECK; s->ctrl &= ~SCSW_CTRL_MASK_STCTL; s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; s->cpa = sch->channel_prog + 8; break; case -EBUSY: /* subchannel busy, generate deferred cc 1 */ s->flags &= ~SCSW_FLAGS_MASK_CC; s->flags |= (1 << 8); s->ctrl &= ~SCSW_CTRL_MASK_STCTL; s->ctrl |= SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; break; case -EINPROGRESS: /* channel program has been suspended */ s->ctrl &= ~SCSW_ACTL_START_PEND; s->ctrl |= SCSW_ACTL_SUSP; break; default: /* error, generate channel program check */ s->ctrl &= ~SCSW_ACTL_START_PEND; s->cstat = SCSW_CSTAT_PROG_CHECK; s->ctrl &= ~SCSW_CTRL_MASK_STCTL; s->ctrl |= SCSW_STCTL_PRIMARY | SCSW_STCTL_SECONDARY | SCSW_STCTL_ALERT | SCSW_STCTL_STATUS_PEND; s->cpa = sch->channel_prog + 8; break; } } while (ret == -EAGAIN); }


QEMUFile *qemu_fopen_ops_buffered(MigrationState *migration_state) { QEMUFileBuffered *s; s = g_malloc0(sizeof(*s)); s->migration_state = migration_state; s->xfer_limit = migration_state->bandwidth_limit / 10; s->file = qemu_fopen_ops(s, &buffered_file_ops); s->timer = qemu_new_timer_ms(rt_clock, buffered_rate_tick, s); qemu_mod_timer(s->timer, qemu_get_clock_ms(rt_clock) + 100); return s->file; }


static int walk_memory_regions_1(struct walk_memory_regions_data *data, abi_ulong base, int level, void **lp) { abi_ulong pa; int i, rc; if (*lp == NULL) { return walk_memory_regions_end(data, base, 0); } if (level == 0) { PageDesc *pd = *lp; for (i = 0; i < L2_SIZE; ++i) { int prot = pd[i].flags; pa = base | (i << TARGET_PAGE_BITS); if (prot != data->prot) { rc = walk_memory_regions_end(data, pa, prot); if (rc != 0) { return rc; } } } } else { void **pp = *lp; for (i = 0; i < L2_SIZE; ++i) { pa = base | ((abi_ulong)i << (TARGET_PAGE_BITS + L2_BITS * level)); rc = walk_memory_regions_1(data, pa, level - 1, pp + i); if (rc != 0) { return rc; } } } return 0; }


void helper_ldq_data(uint64_t t0, uint64_t t1) { ldq_data(t1, t0); }


static int v9fs_do_open2(V9fsState *s, V9fsCreateState *vs) { FsCred cred; int flags; cred_init(&cred); cred.fc_uid = vs->fidp->uid; cred.fc_mode = vs->perm & 0777; flags = omode_to_uflags(vs->mode) | O_CREAT; return s->ops->open2(&s->ctx, vs->fullname.data, flags, &cred); }


static inline void RENAME(vu9_to_vu12)(const uint8_t *src1, const uint8_t *src2, uint8_t *dst1, uint8_t *dst2, long width, long height, long srcStride1, long srcStride2, long dstStride1, long dstStride2) { x86_reg y; long x,w,h; w=width/2; h=height/2; #if COMPILE_TEMPLATE_MMX __asm__ volatile( PREFETCH" %0 \n\t" PREFETCH" %1 \n\t" ::"m"(*(src1+srcStride1)),"m"(*(src2+srcStride2)):"memory"); #endif for (y=0;y<h;y++) { const uint8_t* s1=src1+srcStride1*(y>>1); uint8_t* d=dst1+dstStride1*y; x=0; #if COMPILE_TEMPLATE_MMX for (;x<w-31;x+=32) { __asm__ volatile( PREFETCH" 32%1 \n\t" "movq %1, %%mm0 \n\t" "movq 8%1, %%mm2 \n\t" "movq 16%1, %%mm4 \n\t" "movq 24%1, %%mm6 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm2, %%mm3 \n\t" "movq %%mm4, %%mm5 \n\t" "movq %%mm6, %%mm7 \n\t" "punpcklbw %%mm0, %%mm0 \n\t" "punpckhbw %%mm1, %%mm1 \n\t" "punpcklbw %%mm2, %%mm2 \n\t" "punpckhbw %%mm3, %%mm3 \n\t" "punpcklbw %%mm4, %%mm4 \n\t" "punpckhbw %%mm5, %%mm5 \n\t" "punpcklbw %%mm6, %%mm6 \n\t" "punpckhbw %%mm7, %%mm7 \n\t" MOVNTQ" %%mm0, %0 \n\t" MOVNTQ" %%mm1, 8%0 \n\t" MOVNTQ" %%mm2, 16%0 \n\t" MOVNTQ" %%mm3, 24%0 \n\t" MOVNTQ" %%mm4, 32%0 \n\t" MOVNTQ" %%mm5, 40%0 \n\t" MOVNTQ" %%mm6, 48%0 \n\t" MOVNTQ" %%mm7, 56%0" :"=m"(d[2*x]) :"m"(s1[x]) :"memory"); } #endif for (;x<w;x++) d[2*x]=d[2*x+1]=s1[x]; } for (y=0;y<h;y++) { const uint8_t* s2=src2+srcStride2*(y>>1); uint8_t* d=dst2+dstStride2*y; x=0; #if COMPILE_TEMPLATE_MMX for (;x<w-31;x+=32) { __asm__ volatile( PREFETCH" 32%1 \n\t" "movq %1, %%mm0 \n\t" "movq 8%1, %%mm2 \n\t" "movq 16%1, %%mm4 \n\t" "movq 24%1, %%mm6 \n\t" "movq %%mm0, %%mm1 \n\t" "movq %%mm2, %%mm3 \n\t" "movq %%mm4, %%mm5 \n\t" "movq %%mm6, %%mm7 \n\t" "punpcklbw %%mm0, %%mm0 \n\t" "punpckhbw %%mm1, %%mm1 \n\t" "punpcklbw %%mm2, %%mm2 \n\t" "punpckhbw %%mm3, %%mm3 \n\t" "punpcklbw %%mm4, %%mm4 \n\t" "punpckhbw %%mm5, %%mm5 \n\t" "punpcklbw %%mm6, %%mm6 \n\t" "punpckhbw %%mm7, %%mm7 \n\t" MOVNTQ" %%mm0, %0 \n\t" MOVNTQ" %%mm1, 8%0 \n\t" MOVNTQ" %%mm2, 16%0 \n\t" MOVNTQ" %%mm3, 24%0 \n\t" MOVNTQ" %%mm4, 32%0 \n\t" MOVNTQ" %%mm5, 40%0 \n\t" MOVNTQ" %%mm6, 48%0 \n\t" MOVNTQ" %%mm7, 56%0" :"=m"(d[2*x]) :"m"(s2[x]) :"memory"); } #endif for (;x<w;x++) d[2*x]=d[2*x+1]=s2[x]; } #if COMPILE_TEMPLATE_MMX __asm__( EMMS" \n\t" SFENCE" \n\t" ::: "memory" ); #endif }


static TranslationBlock *tb_find_slow(target_ulong pc, target_ulong cs_base, uint64_t flags) { TranslationBlock *tb, **ptb1; unsigned int h; tb_page_addr_t phys_pc, phys_page1, phys_page2; target_ulong virt_page2; tb_invalidated_flag = 0; /* find translated block using physical mappings */ phys_pc = get_page_addr_code(env, pc); phys_page1 = phys_pc & TARGET_PAGE_MASK; phys_page2 = -1; h = tb_phys_hash_func(phys_pc); ptb1 = &tb_phys_hash[h]; for(;;) { tb = *ptb1; if (!tb) goto not_found; if (tb->pc == pc && tb->page_addr[0] == phys_page1 && tb->cs_base == cs_base && tb->flags == flags) { /* check next page if needed */ if (tb->page_addr[1] != -1) { virt_page2 = (pc & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE; phys_page2 = get_page_addr_code(env, virt_page2); if (tb->page_addr[1] == phys_page2) goto found; } else { goto found; } } ptb1 = &tb->phys_hash_next; } not_found: /* if no translated code available, then translate it now */ tb = tb_gen_code(env, pc, cs_base, flags, 0); found: /* Move the last found TB to the head of the list */ if (likely(*ptb1)) { *ptb1 = tb->phys_hash_next; tb->phys_hash_next = tb_phys_hash[h]; tb_phys_hash[h] = tb; } /* we add the TB in the virtual pc hash table */ env->tb_jmp_cache[tb_jmp_cache_hash_func(pc)] = tb; return tb; }


static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd) { uint32_t pa_hi, pa_lo; target_phys_addr_t iq_pa, initq_size; struct mfi_init_qinfo *initq; uint32_t flags; int ret = MFI_STAT_OK; pa_lo = le32_to_cpu(cmd->frame->init.qinfo_new_addr_lo); pa_hi = le32_to_cpu(cmd->frame->init.qinfo_new_addr_hi); iq_pa = (((uint64_t) pa_hi << 32) | pa_lo); trace_megasas_init_firmware((uint64_t)iq_pa); initq_size = sizeof(*initq); initq = cpu_physical_memory_map(iq_pa, &initq_size, 0); if (!initq || initq_size != sizeof(*initq)) { trace_megasas_initq_map_failed(cmd->index); s->event_count++; ret = MFI_STAT_MEMORY_NOT_AVAILABLE; goto out; } s->reply_queue_len = le32_to_cpu(initq->rq_entries) & 0xFFFF; if (s->reply_queue_len > s->fw_cmds) { trace_megasas_initq_mismatch(s->reply_queue_len, s->fw_cmds); s->event_count++; ret = MFI_STAT_INVALID_PARAMETER; goto out; } pa_lo = le32_to_cpu(initq->rq_addr_lo); pa_hi = le32_to_cpu(initq->rq_addr_hi); s->reply_queue_pa = ((uint64_t) pa_hi << 32) | pa_lo; pa_lo = le32_to_cpu(initq->ci_addr_lo); pa_hi = le32_to_cpu(initq->ci_addr_hi); s->consumer_pa = ((uint64_t) pa_hi << 32) | pa_lo; pa_lo = le32_to_cpu(initq->pi_addr_lo); pa_hi = le32_to_cpu(initq->pi_addr_hi); s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo; s->reply_queue_head = ldl_le_phys(s->producer_pa); s->reply_queue_tail = ldl_le_phys(s->consumer_pa); flags = le32_to_cpu(initq->flags); if (flags & MFI_QUEUE_FLAG_CONTEXT64) { s->flags |= MEGASAS_MASK_USE_QUEUE64; } trace_megasas_init_queue((unsigned long)s->reply_queue_pa, s->reply_queue_len, s->reply_queue_head, s->reply_queue_tail, flags); megasas_reset_frames(s); s->fw_state = MFI_FWSTATE_OPERATIONAL; out: if (initq) { cpu_physical_memory_unmap(initq, initq_size, 0, 0); } return ret; }


static void pmac_ide_writel (void *opaque, target_phys_addr_t addr, uint32_t val) { MACIOIDEState *d = opaque; addr = (addr & 0xFFF) >> 4; val = bswap32(val); if (addr == 0) { ide_data_writel(&d->bus, 0, val); } }


static void control_out(VirtIODevice *vdev, VirtQueue *vq) { VirtQueueElement elem; VirtIOSerial *vser; uint8_t *buf; size_t len; vser = VIRTIO_SERIAL(vdev); len = 0; buf = NULL; while (virtqueue_pop(vq, &elem)) { size_t cur_len; cur_len = iov_size(elem.out_sg, elem.out_num); /* * Allocate a new buf only if we didn't have one previously or * if the size of the buf differs */ if (cur_len > len) { g_free(buf); buf = g_malloc(cur_len); len = cur_len; } iov_to_buf(elem.out_sg, elem.out_num, 0, buf, cur_len); handle_control_message(vser, buf, cur_len); virtqueue_push(vq, &elem, 0); } g_free(buf); virtio_notify(vdev, vq); }


static int disas_thumb2_insn(CPUARMState *env, DisasContext *s, uint16_t insn_hw1) { uint32_t insn, imm, shift, offset; uint32_t rd, rn, rm, rs; TCGv_i32 tmp; TCGv_i32 tmp2; TCGv_i32 tmp3; TCGv_i32 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) { ARCH(5); /* 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 = tcg_temp_new_i32(); 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 = tcg_temp_new_i32(); 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 = arm_lduw_code(env, s->pc, s->bswap_code); 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 = tcg_temp_new_i32(); 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 = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); store_reg(s, rs, tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); store_reg(s, rd, tmp); } else { /* strd */ tmp = load_reg(s, rs); tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); tcg_temp_free_i32(tmp); tcg_gen_addi_i32(addr, addr, 4); tmp = load_reg(s, rd); tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); tcg_temp_free_i32(tmp); } 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 { tcg_temp_free_i32(addr); } } else if ((insn & (1 << 23)) == 0) { /* Load/store exclusive word. */ addr = tcg_temp_local_new_i32(); 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_i32(addr); } else if ((insn & (7 << 5)) == 0) { /* Table Branch. */ if (rn == 15) { addr = tcg_temp_new_i32(); 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); tcg_temp_free_i32(tmp); tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s)); } else { /* tbb */ tcg_temp_free_i32(tmp); tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s)); } tcg_temp_free_i32(addr); tcg_gen_shli_i32(tmp, tmp, 1); tcg_gen_addi_i32(tmp, tmp, s->pc); store_reg(s, 15, tmp); } else { int op2 = (insn >> 6) & 0x3; op = (insn >> 4) & 0x3; switch (op2) { case 0: goto illegal_op; case 1: /* Load/store exclusive byte/halfword/doubleword */ if (op == 2) { goto illegal_op; } ARCH(7); break; case 2: /* Load-acquire/store-release */ if (op == 3) { goto illegal_op; } /* Fall through */ case 3: /* Load-acquire/store-release exclusive */ ARCH(8); break; } addr = tcg_temp_local_new_i32(); load_reg_var(s, addr, rn); if (!(op2 & 1)) { if (insn & (1 << 20)) { tmp = tcg_temp_new_i32(); switch (op) { case 0: /* ldab */ tcg_gen_qemu_ld8u(tmp, addr, IS_USER(s)); break; case 1: /* ldah */ tcg_gen_qemu_ld16u(tmp, addr, IS_USER(s)); break; case 2: /* lda */ tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); break; default: abort(); } store_reg(s, rs, tmp); } else { tmp = load_reg(s, rs); switch (op) { case 0: /* stlb */ tcg_gen_qemu_st8(tmp, addr, IS_USER(s)); break; case 1: /* stlh */ tcg_gen_qemu_st16(tmp, addr, IS_USER(s)); break; case 2: /* stl */ tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); break; default: abort(); } tcg_temp_free_i32(tmp); } } else 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_i32(addr); } } else { /* Load/store multiple, RFE, SRS. */ if (((insn >> 23) & 1) == ((insn >> 24) & 1)) { /* RFE, SRS: not available in user mode or on M profile */ if (IS_USER(s) || IS_M(env)) { 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 = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, 0); tcg_gen_addi_i32(addr, addr, 4); tmp2 = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp2, 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 { tcg_temp_free_i32(addr); } gen_rfe(s, tmp, tmp2); } else { /* srs */ gen_srs(s, (insn & 0x1f), (insn & (1 << 24)) ? 1 : 2, insn & (1 << 21)); } } else { int i, loaded_base = 0; TCGv_i32 loaded_var; /* 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); } TCGV_UNUSED_I32(loaded_var); for (i = 0; i < 16; i++) { if ((insn & (1 << i)) == 0) continue; if (insn & (1 << 20)) { /* Load. */ tmp = tcg_temp_new_i32(); tcg_gen_qemu_ld32u(tmp, addr, IS_USER(s)); if (i == 15) { gen_bx(s, tmp); } else if (i == rn) { loaded_var = tmp; loaded_base = 1; } else { store_reg(s, i, tmp); } } else { /* Store. */ tmp = load_reg(s, i); tcg_gen_qemu_st32(tmp, addr, IS_USER(s)); tcg_temp_free_i32(tmp); } tcg_gen_addi_i32(addr, addr, 4); } if (loaded_base) { store_reg(s, rn, loaded_var); } 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 { tcg_temp_free_i32(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); tcg_temp_free_i32(tmp2); store_reg(s, rd, tmp); } else { /* Data processing register constant shift. */ if (rn == 15) { tmp = tcg_temp_new_i32(); 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; tcg_temp_free_i32(tmp2); if (rd != 15) { store_reg(s, rd, tmp); } else { tcg_temp_free_i32(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 necessary 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); tcg_temp_free_i32(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); tcg_temp_free_i32(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, cpu_env, tmp); if (op & 2) gen_helper_sub_saturate(tmp, cpu_env, tmp2, tmp); else gen_helper_add_saturate(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(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 = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp3, cpu_env, offsetof(CPUARMState, GE)); gen_helper_sel_flags(tmp, tmp3, tmp, tmp2); tcg_temp_free_i32(tmp3); tcg_temp_free_i32(tmp2); 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); tcg_temp_free_i32(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); tcg_temp_free_i32(tmp2); } break; case 1: /* 16 x 16 -> 32 */ gen_mulxy(tmp, tmp2, op & 2, op & 1); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(tmp2); } break; case 2: /* Dual multiply add. */ case 4: /* Dual multiply subtract. */ if (op) gen_swap_half(tmp2); gen_smul_dual(tmp, tmp2); if (insn & (1 << 22)) { /* This subtraction cannot overflow. */ tcg_gen_sub_i32(tmp, tmp, tmp2); } else { /* This addition cannot overflow 32 bits; * however it may overflow considered as a signed * operation, in which case we must set the Q flag. */ gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); } tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); gen_helper_add_setq(tmp, cpu_env, tmp, tmp2); tcg_temp_free_i32(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 = tcg_temp_new_i32(); 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, cpu_env, tmp, tmp2); tcg_temp_free_i32(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 = tcg_temp_new_i32(); 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); tcg_temp_free_i32(tmp2); if (rs != 15) { tmp2 = load_reg(s, rs); tcg_gen_add_i32(tmp, tmp, tmp2); tcg_temp_free_i32(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_THUMB_DIV)) { goto illegal_op; } if (op & 0x20) gen_helper_udiv(tmp, tmp, tmp2); else gen_helper_sdiv(tmp, tmp, tmp2); tcg_temp_free_i32(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); } tcg_temp_free_i32(tmp2); /* BUGFIX */ tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(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); tcg_temp_free_i32(tmp2); tmp64 = tcg_temp_new_i64(); tcg_gen_ext_i32_i64(tmp64, tmp); tcg_temp_free_i32(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) | (1 << 28); 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; /* thumb2 bx, no need to check */ 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); tcg_temp_free_i32(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 = tcg_temp_new_i32(); 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, cpu_env); } 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 = tcg_temp_new_i32(); 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); tcg_gen_deposit_i32(tmp, tmp2, tmp, shift, imm); tcg_temp_free_i32(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, cpu_env, tmp, tmp2); else gen_helper_usat(tmp, cpu_env, tmp, tmp2); } else { /* Signed. */ if ((op & 1) && shift == 0) gen_helper_ssat16(tmp, cpu_env, tmp, tmp2); else gen_helper_ssat(tmp, cpu_env, 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 = tcg_temp_new_i32(); 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 = tcg_temp_new_i32(); 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 = tcg_temp_new_i32(); tcg_gen_movi_i32(tmp2, imm); rn = (insn >> 16) & 0xf; if (rn == 15) { tmp = tcg_temp_new_i32(); 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; tcg_temp_free_i32(tmp2); rd = (insn >> 8) & 0xf; if (rd != 15) { store_reg(s, rd, tmp); } else { tcg_temp_free_i32(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; } op = ((insn >> 21) & 3) | ((insn >> 22) & 4); if (rs == 15) { if (!(insn & (1 << 20))) { goto illegal_op; } if (op != 2) { /* Byte or halfword load space with dest == r15 : memory hints. * Catch them early so we don't emit pointless addressing code. * This space is a mix of: * PLD/PLDW/PLI, which we implement as NOPs (note that unlike * the ARM encodings, PLDW space doesn't UNDEF for non-v7MP * cores) * unallocated hints, which must be treated as NOPs * UNPREDICTABLE space, which we NOP or UNDEF depending on * which is easiest for the decoding logic * Some space which must UNDEF */ int op1 = (insn >> 23) & 3; int op2 = (insn >> 6) & 0x3f; if (op & 2) { goto illegal_op; } if (rn == 15) { /* UNPREDICTABLE, unallocated hint or * PLD/PLDW/PLI (literal) */ return 0; } if (op1 & 1) { return 0; /* PLD/PLDW/PLI or unallocated hint */ } if ((op2 == 0) || ((op2 & 0x3c) == 0x30)) { return 0; /* PLD/PLDW/PLI or unallocated hint */ } /* UNDEF space, or an UNPREDICTABLE */ return 1; } } user = IS_USER(s); if (rn == 15) { addr = tcg_temp_new_i32(); /* 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 { imm = insn & 0xff; switch ((insn >> 8) & 0xf) { case 0x0: /* Shifted Register. */ shift = (insn >> 4) & 0xf; if (shift > 3) { tcg_temp_free_i32(addr); goto illegal_op; } tmp = load_reg(s, rm); if (shift) tcg_gen_shli_i32(tmp, tmp, shift); tcg_gen_add_i32(addr, addr, tmp); tcg_temp_free_i32(tmp); break; case 0xc: /* Negative offset. */ tcg_gen_addi_i32(addr, addr, -imm); break; case 0xe: /* User privilege. */ tcg_gen_addi_i32(addr, addr, imm); user = 1; break; case 0x9: /* Post-decrement. */ imm = -imm; /* Fall through. */ case 0xb: /* Post-increment. */ postinc = 1; writeback = 1; break; case 0xd: /* Pre-decrement. */ imm = -imm; /* Fall through. */ case 0xf: /* Pre-increment. */ tcg_gen_addi_i32(addr, addr, imm); writeback = 1; break; default: tcg_temp_free_i32(addr); goto illegal_op; } } } if (insn & (1 << 20)) { /* Load. */ tmp = tcg_temp_new_i32(); switch (op) { case 0: tcg_gen_qemu_ld8u(tmp, addr, user); break; case 4: tcg_gen_qemu_ld8s(tmp, addr, user); break; case 1: tcg_gen_qemu_ld16u(tmp, addr, user); break; case 5: tcg_gen_qemu_ld16s(tmp, addr, user); break; case 2: tcg_gen_qemu_ld32u(tmp, addr, user); break; default: tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); goto illegal_op; } if (rs == 15) { gen_bx(s, tmp); } else { store_reg(s, rs, tmp); } } else { /* Store. */ tmp = load_reg(s, rs); switch (op) { case 0: tcg_gen_qemu_st8(tmp, addr, user); break; case 1: tcg_gen_qemu_st16(tmp, addr, user); break; case 2: tcg_gen_qemu_st32(tmp, addr, user); break; default: tcg_temp_free_i32(tmp); tcg_temp_free_i32(addr); goto illegal_op; } tcg_temp_free_i32(tmp); } if (postinc) tcg_gen_addi_i32(addr, addr, imm); if (writeback) { store_reg(s, rn, addr); } else { tcg_temp_free_i32(addr); } } break; default: goto illegal_op; } return 0; illegal_op: return 1; }


static int hevc_decode_nal_units(const uint8_t *buf, int buf_size, HEVCParamSets *ps, int is_nalff, int nal_length_size, void *logctx) { int i; int ret = 0; H2645Packet pkt = { 0 }; ret = ff_h2645_packet_split(&pkt, buf, buf_size, logctx, is_nalff, nal_length_size, AV_CODEC_ID_HEVC, 1); if (ret < 0) { goto done; } for (i = 0; i < pkt.nb_nals; i++) { H2645NAL *nal = &pkt.nals[i]; /* ignore everything except parameter sets and VCL NALUs */ switch (nal->type) { case HEVC_NAL_VPS: ff_hevc_decode_nal_vps(&nal->gb, logctx, ps); break; case HEVC_NAL_SPS: ff_hevc_decode_nal_sps(&nal->gb, logctx, ps, 1); break; case HEVC_NAL_PPS: ff_hevc_decode_nal_pps(&nal->gb, logctx, ps); break; default: av_log(logctx, AV_LOG_VERBOSE, "Ignoring NAL type %d in extradata\n", nal->type); break; } } done: ff_h2645_packet_uninit(&pkt); return ret; }


static void test_qemu_strtoll_full_max(void) { const char *str = g_strdup_printf("%lld", LLONG_MAX); int64_t res; int err; err = qemu_strtoll(str, NULL, 0, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, LLONG_MAX); }


static int dump_init(DumpState *s, int fd, bool paging, bool has_filter, int64_t begin, int64_t length, Error **errp) { CPUState *cpu; int nr_cpus; Error *err = NULL; int ret; if (runstate_is_running()) { vm_stop(RUN_STATE_SAVE_VM); s->resume = true; } else { s->resume = false; } /* If we use KVM, we should synchronize the registers before we get dump * info or physmap info. */ cpu_synchronize_all_states(); nr_cpus = 0; CPU_FOREACH(cpu) { nr_cpus++; } s->errp = errp; s->fd = fd; s->has_filter = has_filter; s->begin = begin; s->length = length; guest_phys_blocks_init(&s->guest_phys_blocks); guest_phys_blocks_append(&s->guest_phys_blocks); s->start = get_start_block(s); if (s->start == -1) { error_set(errp, QERR_INVALID_PARAMETER, "begin"); goto cleanup; } /* get dump info: endian, class and architecture. * If the target architecture is not supported, cpu_get_dump_info() will * return -1. */ ret = cpu_get_dump_info(&s->dump_info, &s->guest_phys_blocks); if (ret < 0) { error_set(errp, QERR_UNSUPPORTED); goto cleanup; } s->note_size = cpu_get_note_size(s->dump_info.d_class, s->dump_info.d_machine, nr_cpus); if (s->note_size < 0) { error_set(errp, QERR_UNSUPPORTED); goto cleanup; } /* get memory mapping */ memory_mapping_list_init(&s->list); if (paging) { qemu_get_guest_memory_mapping(&s->list, &s->guest_phys_blocks, &err); if (err != NULL) { error_propagate(errp, err); goto cleanup; } } else { qemu_get_guest_simple_memory_mapping(&s->list, &s->guest_phys_blocks); } s->nr_cpus = nr_cpus; s->page_size = TARGET_PAGE_SIZE; s->page_shift = ffs(s->page_size) - 1; get_max_mapnr(s); uint64_t tmp; tmp = DIV_ROUND_UP(DIV_ROUND_UP(s->max_mapnr, CHAR_BIT), s->page_size); s->len_dump_bitmap = tmp * s->page_size; if (s->has_filter) { memory_mapping_filter(&s->list, s->begin, s->length); } /* * calculate phdr_num * * the type of ehdr->e_phnum is uint16_t, so we should avoid overflow */ s->phdr_num = 1; /* PT_NOTE */ if (s->list.num < UINT16_MAX - 2) { s->phdr_num += s->list.num; s->have_section = false; } else { s->have_section = true; s->phdr_num = PN_XNUM; s->sh_info = 1; /* PT_NOTE */ /* the type of shdr->sh_info is uint32_t, so we should avoid overflow */ if (s->list.num <= UINT32_MAX - 1) { s->sh_info += s->list.num; } else { s->sh_info = UINT32_MAX; } } if (s->dump_info.d_class == ELFCLASS64) { if (s->have_section) { s->memory_offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->sh_info + sizeof(Elf64_Shdr) + s->note_size; } else { s->memory_offset = sizeof(Elf64_Ehdr) + sizeof(Elf64_Phdr) * s->phdr_num + s->note_size; } } else { if (s->have_section) { s->memory_offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->sh_info + sizeof(Elf32_Shdr) + s->note_size; } else { s->memory_offset = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) * s->phdr_num + s->note_size; } } return 0; cleanup: guest_phys_blocks_free(&s->guest_phys_blocks); if (s->resume) { vm_start(); } return -1; }


static void crs_replace_with_free_ranges(GPtrArray *ranges, uint64_t start, uint64_t end) { GPtrArray *free_ranges = g_ptr_array_new_with_free_func(crs_range_free); uint64_t free_base = start; int i; g_ptr_array_sort(ranges, crs_range_compare); for (i = 0; i < ranges->len; i++) { CrsRangeEntry *used = g_ptr_array_index(ranges, i); if (free_base < used->base) { crs_range_insert(free_ranges, free_base, used->base - 1); } free_base = used->limit + 1; } if (free_base < end) { crs_range_insert(free_ranges, free_base, end); } g_ptr_array_set_size(ranges, 0); for (i = 0; i < free_ranges->len; i++) { g_ptr_array_add(ranges, g_ptr_array_index(free_ranges, i)); } g_ptr_array_free(free_ranges, false); }


static ssize_t qio_channel_websock_decode_payload(QIOChannelWebsock *ioc, Error **errp) { size_t i; size_t payload_len; uint32_t *payload32; if (!ioc->payload_remain) { error_setg(errp, "Decoding payload but no bytes of payload remain"); return -1; } /* If we aren't at the end of the payload, then drop * off the last bytes, so we're always multiple of 4 * for purpose of unmasking, except at end of payload */ if (ioc->encinput.offset < ioc->payload_remain) { payload_len = ioc->encinput.offset - (ioc->encinput.offset % 4); } else { payload_len = ioc->payload_remain; } if (payload_len == 0) { return QIO_CHANNEL_ERR_BLOCK; } ioc->payload_remain -= payload_len; /* unmask frame */ /* process 1 frame (32 bit op) */ payload32 = (uint32_t *)ioc->encinput.buffer; for (i = 0; i < payload_len / 4; i++) { payload32[i] ^= ioc->mask.u; } /* process the remaining bytes (if any) */ for (i *= 4; i < payload_len; i++) { ioc->encinput.buffer[i] ^= ioc->mask.c[i % 4]; } buffer_reserve(&ioc->rawinput, payload_len); buffer_append(&ioc->rawinput, ioc->encinput.buffer, payload_len); buffer_advance(&ioc->encinput, payload_len); return payload_len; }


static int load_sofa(AVFilterContext *ctx, char *filename, int *samplingrate) { struct SOFAlizerContext *s = ctx->priv; /* variables associated with content of SOFA file: */ int ncid, n_dims, n_vars, n_gatts, n_unlim_dim_id, status; char data_delay_dim_name[NC_MAX_NAME]; float *sp_a, *sp_e, *sp_r, *data_ir; char *sofa_conventions; char dim_name[NC_MAX_NAME]; /* names of netCDF dimensions */ size_t *dim_length; /* lengths of netCDF dimensions */ char *text; unsigned int sample_rate; int data_delay_dim_id[2]; int samplingrate_id; int data_delay_id; int n_samples; int m_dim_id = -1; int n_dim_id = -1; int data_ir_id; size_t att_len; int m_dim; int *data_delay; int sp_id; int i, ret; s->sofa.ncid = 0; status = nc_open(filename, NC_NOWRITE, &ncid); /* open SOFA file read-only */ if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Can't find SOFA-file '%s'\n", filename); return AVERROR(EINVAL); } /* get number of dimensions, vars, global attributes and Id of unlimited dimensions: */ nc_inq(ncid, &n_dims, &n_vars, &n_gatts, &n_unlim_dim_id); /* -- get number of measurements ("M") and length of one IR ("N") -- */ dim_length = av_malloc_array(n_dims, sizeof(*dim_length)); if (!dim_length) { nc_close(ncid); return AVERROR(ENOMEM); } for (i = 0; i < n_dims; i++) { /* go through all dimensions of file */ nc_inq_dim(ncid, i, (char *)&dim_name, &dim_length[i]); /* get dimensions */ if (!strncmp("M", (const char *)&dim_name, 1)) /* get ID of dimension "M" */ m_dim_id = i; if (!strncmp("N", (const char *)&dim_name, 1)) /* get ID of dimension "N" */ n_dim_id = i; } if ((m_dim_id == -1) || (n_dim_id == -1)) { /* dimension "M" or "N" couldn't be found */ av_log(ctx, AV_LOG_ERROR, "Can't find required dimensions in SOFA file.\n"); av_freep(&dim_length); nc_close(ncid); return AVERROR(EINVAL); } n_samples = dim_length[n_dim_id]; /* get length of one IR */ m_dim = dim_length[m_dim_id]; /* get number of measurements */ av_freep(&dim_length); /* -- check file type -- */ /* get length of attritube "Conventions" */ status = nc_inq_attlen(ncid, NC_GLOBAL, "Conventions", &att_len); if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Can't get length of attribute \"Conventions\".\n"); nc_close(ncid); return AVERROR_INVALIDDATA; } /* check whether file is SOFA file */ text = av_malloc(att_len + 1); if (!text) { nc_close(ncid); return AVERROR(ENOMEM); } nc_get_att_text(ncid, NC_GLOBAL, "Conventions", text); *(text + att_len) = 0; if (strncmp("SOFA", text, 4)) { av_log(ctx, AV_LOG_ERROR, "Not a SOFA file!\n"); av_freep(&text); nc_close(ncid); return AVERROR(EINVAL); } av_freep(&text); status = nc_inq_attlen(ncid, NC_GLOBAL, "License", &att_len); if (status == NC_NOERR) { text = av_malloc(att_len + 1); if (text) { nc_get_att_text(ncid, NC_GLOBAL, "License", text); *(text + att_len) = 0; av_log(ctx, AV_LOG_INFO, "SOFA file License: %s\n", text); av_freep(&text); } } status = nc_inq_attlen(ncid, NC_GLOBAL, "SourceDescription", &att_len); if (status == NC_NOERR) { text = av_malloc(att_len + 1); if (text) { nc_get_att_text(ncid, NC_GLOBAL, "SourceDescription", text); *(text + att_len) = 0; av_log(ctx, AV_LOG_INFO, "SOFA file SourceDescription: %s\n", text); av_freep(&text); } } status = nc_inq_attlen(ncid, NC_GLOBAL, "Comment", &att_len); if (status == NC_NOERR) { text = av_malloc(att_len + 1); if (text) { nc_get_att_text(ncid, NC_GLOBAL, "Comment", text); *(text + att_len) = 0; av_log(ctx, AV_LOG_INFO, "SOFA file Comment: %s\n", text); av_freep(&text); } } status = nc_inq_attlen(ncid, NC_GLOBAL, "SOFAConventions", &att_len); if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Can't get length of attribute \"SOFAConventions\".\n"); nc_close(ncid); return AVERROR_INVALIDDATA; } sofa_conventions = av_malloc(att_len + 1); if (!sofa_conventions) { nc_close(ncid); return AVERROR(ENOMEM); } nc_get_att_text(ncid, NC_GLOBAL, "SOFAConventions", sofa_conventions); *(sofa_conventions + att_len) = 0; if (strncmp("SimpleFreeFieldHRIR", sofa_conventions, att_len)) { av_log(ctx, AV_LOG_ERROR, "Not a SimpleFreeFieldHRIR file!\n"); av_freep(&sofa_conventions); nc_close(ncid); return AVERROR(EINVAL); } av_freep(&sofa_conventions); /* -- get sampling rate of HRTFs -- */ /* read ID, then value */ status = nc_inq_varid(ncid, "Data.SamplingRate", &samplingrate_id); status += nc_get_var_uint(ncid, samplingrate_id, &sample_rate); if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Couldn't read Data.SamplingRate.\n"); nc_close(ncid); return AVERROR(EINVAL); } *samplingrate = sample_rate; /* remember sampling rate */ /* -- allocate memory for one value for each measurement position: -- */ sp_a = s->sofa.sp_a = av_malloc_array(m_dim, sizeof(float)); sp_e = s->sofa.sp_e = av_malloc_array(m_dim, sizeof(float)); sp_r = s->sofa.sp_r = av_malloc_array(m_dim, sizeof(float)); /* delay and IR values required for each ear and measurement position: */ data_delay = s->sofa.data_delay = av_calloc(m_dim, 2 * sizeof(int)); data_ir = s->sofa.data_ir = av_malloc_array(m_dim * n_samples, sizeof(float) * 2); if (!data_delay || !sp_a || !sp_e || !sp_r || !data_ir) { /* if memory could not be allocated */ close_sofa(&s->sofa); return AVERROR(ENOMEM); } /* get impulse responses (HRTFs): */ /* get corresponding ID */ status = nc_inq_varid(ncid, "Data.IR", &data_ir_id); status += nc_get_var_float(ncid, data_ir_id, data_ir); /* read and store IRs */ if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Couldn't read Data.IR!\n"); ret = AVERROR(EINVAL); goto error; } /* get source positions of the HRTFs in the SOFA file: */ status = nc_inq_varid(ncid, "SourcePosition", &sp_id); /* get corresponding ID */ status += nc_get_vara_float(ncid, sp_id, (size_t[2]){ 0, 0 } , (size_t[2]){ m_dim, 1}, sp_a); /* read & store azimuth angles */ status += nc_get_vara_float(ncid, sp_id, (size_t[2]){ 0, 1 } , (size_t[2]){ m_dim, 1}, sp_e); /* read & store elevation angles */ status += nc_get_vara_float(ncid, sp_id, (size_t[2]){ 0, 2 } , (size_t[2]){ m_dim, 1}, sp_r); /* read & store radii */ if (status != NC_NOERR) { /* if any source position variable coudn't be read */ av_log(ctx, AV_LOG_ERROR, "Couldn't read SourcePosition.\n"); ret = AVERROR(EINVAL); goto error; } /* read Data.Delay, check for errors and fit it to data_delay */ status = nc_inq_varid(ncid, "Data.Delay", &data_delay_id); status += nc_inq_vardimid(ncid, data_delay_id, &data_delay_dim_id[0]); status += nc_inq_dimname(ncid, data_delay_dim_id[0], data_delay_dim_name); if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Couldn't read Data.Delay.\n"); ret = AVERROR(EINVAL); goto error; } /* Data.Delay dimension check */ /* dimension of Data.Delay is [I R]: */ if (!strncmp(data_delay_dim_name, "I", 2)) { /* check 2 characters to assure string is 0-terminated after "I" */ int delay[2]; /* delays get from SOFA file: */ av_log(ctx, AV_LOG_DEBUG, "Data.Delay has dimension [I R]\n"); status = nc_get_var_int(ncid, data_delay_id, &delay[0]); if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Couldn't read Data.Delay\n"); ret = AVERROR(EINVAL); goto error; } int *data_delay_r = data_delay + m_dim; for (i = 0; i < m_dim; i++) { /* extend given dimension [I R] to [M R] */ /* assign constant delay value for all measurements to data_delay fields */ data_delay[i] = delay[0]; data_delay_r[i] = delay[1]; } /* dimension of Data.Delay is [M R] */ } else if (!strncmp(data_delay_dim_name, "M", 2)) { av_log(ctx, AV_LOG_ERROR, "Data.Delay in dimension [M R]\n"); /* get delays from SOFA file: */ status = nc_get_var_int(ncid, data_delay_id, data_delay); if (status != NC_NOERR) { av_log(ctx, AV_LOG_ERROR, "Couldn't read Data.Delay\n"); ret = AVERROR(EINVAL); goto error; } } else { /* dimension of Data.Delay is neither [I R] nor [M R] */ av_log(ctx, AV_LOG_ERROR, "Data.Delay does not have the required dimensions [I R] or [M R].\n"); ret = AVERROR(EINVAL); goto error; } /* save information in SOFA struct: */ s->sofa.m_dim = m_dim; /* no. measurement positions */ s->sofa.n_samples = n_samples; /* length on one IR */ s->sofa.ncid = ncid; /* netCDF ID of SOFA file */ nc_close(ncid); /* close SOFA file */ return 0; error: close_sofa(&s->sofa); return ret; }


static void create_flash(const VirtBoardInfo *vbi) { /* Create two flash devices to fill the VIRT_FLASH space in the memmap. * Any file passed via -bios goes in the first of these. */ hwaddr flashsize = vbi->memmap[VIRT_FLASH].size / 2; hwaddr flashbase = vbi->memmap[VIRT_FLASH].base; char *nodename; if (bios_name) { char *fn; int image_size; if (drive_get(IF_PFLASH, 0, 0)) { error_report("The contents of the first flash device may be " "specified with -bios or with -drive if=pflash... " "but you cannot use both options at once"); exit(1); } fn = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (!fn) { error_report("Could not find ROM image '%s'", bios_name); exit(1); } image_size = load_image_targphys(fn, flashbase, flashsize); g_free(fn); if (image_size < 0) { error_report("Could not load ROM image '%s'", bios_name); exit(1); } g_free(fn); } create_one_flash("virt.flash0", flashbase, flashsize); create_one_flash("virt.flash1", flashbase + flashsize, flashsize); nodename = g_strdup_printf("/flash@%" PRIx64, flashbase); qemu_fdt_add_subnode(vbi->fdt, nodename); qemu_fdt_setprop_string(vbi->fdt, nodename, "compatible", "cfi-flash"); qemu_fdt_setprop_sized_cells(vbi->fdt, nodename, "reg", 2, flashbase, 2, flashsize, 2, flashbase + flashsize, 2, flashsize); qemu_fdt_setprop_cell(vbi->fdt, nodename, "bank-width", 4); g_free(nodename); }


void mips_malta_init(QEMUMachineInitArgs *args) { ram_addr_t ram_size = args->ram_size; const char *cpu_model = args->cpu_model; const char *kernel_filename = args->kernel_filename; const char *kernel_cmdline = args->kernel_cmdline; const char *initrd_filename = args->initrd_filename; char *filename; pflash_t *fl; MemoryRegion *system_memory = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1); target_long bios_size = FLASH_SIZE; const size_t smbus_eeprom_size = 8 * 256; uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size); int64_t kernel_entry; PCIBus *pci_bus; ISABus *isa_bus; MIPSCPU *cpu; CPUMIPSState *env; qemu_irq *isa_irq; qemu_irq *cpu_exit_irq; int piix4_devfn; i2c_bus *smbus; int i; DriveInfo *dinfo; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *fd[MAX_FD]; int fl_idx = 0; int fl_sectors = bios_size >> 16; int be; DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA); MaltaState *s = MIPS_MALTA(dev); qdev_init_nofail(dev); /* Make sure the first 3 serial ports are associated with a device. */ for(i = 0; i < 3; i++) { if (!serial_hds[i]) { char label[32]; snprintf(label, sizeof(label), "serial%d", i); serial_hds[i] = qemu_chr_new(label, "null", NULL); } } /* init CPUs */ if (cpu_model == NULL) { #ifdef TARGET_MIPS64 cpu_model = "20Kc"; #else cpu_model = "24Kf"; #endif } for (i = 0; i < smp_cpus; i++) { cpu = cpu_mips_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } env = &cpu->env; /* Init internal devices */ cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); qemu_register_reset(main_cpu_reset, cpu); } cpu = MIPS_CPU(first_cpu); env = &cpu->env; /* allocate RAM */ if (ram_size > (256 << 20)) { fprintf(stderr, "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n", ((unsigned int)ram_size / (1 << 20))); exit(1); } memory_region_init_ram(ram, NULL, "mips_malta.ram", ram_size); vmstate_register_ram_global(ram); memory_region_add_subregion(system_memory, 0, ram); /* generate SPD EEPROM data */ generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size); generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]); #ifdef TARGET_WORDS_BIGENDIAN be = 1; #else be = 0; #endif /* FPGA */ /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */ malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]); /* Load firmware in flash / BIOS. */ dinfo = drive_get(IF_PFLASH, 0, fl_idx); #ifdef DEBUG_BOARD_INIT if (dinfo) { printf("Register parallel flash %d size " TARGET_FMT_lx " at " "addr %08llx '%s' %x\n", fl_idx, bios_size, FLASH_ADDRESS, bdrv_get_device_name(dinfo->bdrv), fl_sectors); } #endif fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios", BIOS_SIZE, dinfo ? dinfo->bdrv : NULL, 65536, fl_sectors, 4, 0x0000, 0x0000, 0x0000, 0x0000, be); bios = pflash_cfi01_get_memory(fl); fl_idx++; if (kernel_filename) { /* Write a small bootloader to the flash location. */ loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; kernel_entry = load_kernel(); write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry); } else { /* Load firmware from flash. */ if (!dinfo) { /* Load a BIOS image. */ if (bios_name == NULL) { bios_name = BIOS_FILENAME; } filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = load_image_targphys(filename, FLASH_ADDRESS, BIOS_SIZE); g_free(filename); } else { bios_size = -1; } if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename && !qtest_enabled()) { error_report("Could not load MIPS bios '%s', and no " "-kernel argument was specified", bios_name); exit(1); } } /* In little endian mode the 32bit words in the bios are swapped, a neat trick which allows bi-endian firmware. */ #ifndef TARGET_WORDS_BIGENDIAN { uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS); if (!addr) { addr = memory_region_get_ram_ptr(bios); } end = (void *)addr + MIN(bios_size, 0x3e0000); while (addr < end) { bswap32s(addr); addr++; } } #endif } /* * Map the BIOS at a 2nd physical location, as on the real board. * Copy it so that we can patch in the MIPS revision, which cannot be * handled by an overlapping region as the resulting ROM code subpage * regions are not executable. */ memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE); if (!rom_copy(memory_region_get_ram_ptr(bios_copy), FLASH_ADDRESS, BIOS_SIZE)) { memcpy(memory_region_get_ram_ptr(bios_copy), memory_region_get_ram_ptr(bios), BIOS_SIZE); } memory_region_set_readonly(bios_copy, true); memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy); /* Board ID = 0x420 (Malta Board with CoreLV) */ stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420); /* Init internal devices */ cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); /* * We have a circular dependency problem: pci_bus depends on isa_irq, * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends * on piix4, and piix4 depends on pci_bus. To stop the cycle we have * qemu_irq_proxy() adds an extra bit of indirection, allowing us * to resolve the isa_irq -> i8259 dependency after i8259 is initialized. */ isa_irq = qemu_irq_proxy(&s->i8259, 16); /* Northbridge */ pci_bus = gt64120_register(isa_irq); /* Southbridge */ ide_drive_get(hd, MAX_IDE_BUS); piix4_devfn = piix4_init(pci_bus, &isa_bus, 80); /* Interrupt controller */ /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */ s->i8259 = i8259_init(isa_bus, env->irq[2]); isa_bus_irqs(isa_bus, s->i8259); pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1); pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci"); smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(NULL, 9), NULL, 0, NULL); smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size); g_free(smbus_eeprom_buf); pit = pit_init(isa_bus, 0x40, 0, NULL); cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1); DMA_init(0, cpu_exit_irq); /* Super I/O */ isa_create_simple(isa_bus, "i8042"); rtc_init(isa_bus, 2000, NULL); serial_isa_init(isa_bus, 0, serial_hds[0]); serial_isa_init(isa_bus, 1, serial_hds[1]); if (parallel_hds[0]) parallel_init(isa_bus, 0, parallel_hds[0]); for(i = 0; i < MAX_FD; i++) { fd[i] = drive_get(IF_FLOPPY, 0, i); } fdctrl_init_isa(isa_bus, fd); /* Network card */ network_init(pci_bus); /* Optional PCI video card */ pci_vga_init(pci_bus); }


static qemu_irq *ppce500_init_mpic(PPCE500Params *params, MemoryRegion *ccsr, qemu_irq **irqs) { QemuOptsList *list; qemu_irq *mpic; DeviceState *dev = NULL; SysBusDevice *s; int i; mpic = g_new(qemu_irq, 256); if (kvm_enabled()) { bool irqchip_allowed = true, irqchip_required = false; list = qemu_find_opts("machine"); if (!QTAILQ_EMPTY(&list->head)) { irqchip_allowed = qemu_opt_get_bool(QTAILQ_FIRST(&list->head), "kernel_irqchip", true); irqchip_required = qemu_opt_get_bool(QTAILQ_FIRST(&list->head), "kernel_irqchip", false); } if (irqchip_allowed) { dev = ppce500_init_mpic_kvm(params, irqs); } if (irqchip_required && !dev) { fprintf(stderr, "%s: irqchip requested but unavailable\n", __func__); abort(); } } if (!dev) { dev = ppce500_init_mpic_qemu(params, irqs); } for (i = 0; i < 256; i++) { mpic[i] = qdev_get_gpio_in(dev, i); } s = SYS_BUS_DEVICE(dev); memory_region_add_subregion(ccsr, MPC8544_MPIC_REGS_OFFSET, s->mmio[0].memory); return mpic; }


static char *spapr_get_fw_dev_path(FWPathProvider *p, BusState *bus, DeviceState *dev) { #define CAST(type, obj, name) \ ((type *)object_dynamic_cast(OBJECT(obj), (name))) SCSIDevice *d = CAST(SCSIDevice, dev, TYPE_SCSI_DEVICE); sPAPRPHBState *phb = CAST(sPAPRPHBState, dev, TYPE_SPAPR_PCI_HOST_BRIDGE); VHostSCSICommon *vsc = CAST(VHostSCSICommon, dev, TYPE_VHOST_SCSI_COMMON); if (d) { void *spapr = CAST(void, bus->parent, "spapr-vscsi"); VirtIOSCSI *virtio = CAST(VirtIOSCSI, bus->parent, TYPE_VIRTIO_SCSI); USBDevice *usb = CAST(USBDevice, bus->parent, TYPE_USB_DEVICE); if (spapr) { /* * Replace "channel@0/disk@0,0" with "disk@8000000000000000": * We use SRP luns of the form 8000 | (bus << 8) | (id << 5) | lun * in the top 16 bits of the 64-bit LUN */ unsigned id = 0x8000 | (d->id << 8) | d->lun; return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev), (uint64_t)id << 48); } else if (virtio) { /* * We use SRP luns of the form 01000000 | (target << 8) | lun * in the top 32 bits of the 64-bit LUN * Note: the quote above is from SLOF and it is wrong, * the actual binding is: * swap 0100 or 10 << or 20 << ( target lun-id -- srplun ) */ unsigned id = 0x1000000 | (d->id << 16) | d->lun; return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev), (uint64_t)id << 32); } else if (usb) { /* * We use SRP luns of the form 01000000 | (usb-port << 16) | lun * in the top 32 bits of the 64-bit LUN */ unsigned usb_port = atoi(usb->port->path); unsigned id = 0x1000000 | (usb_port << 16) | d->lun; return g_strdup_printf("%s@%"PRIX64, qdev_fw_name(dev), (uint64_t)id << 32); /* * SLOF probes the USB devices, and if it recognizes that the device is a * storage device, it changes its name to "storage" instead of "usb-host", * and additionally adds a child node for the SCSI LUN, so the correct * boot path in SLOF is something like .../storage@1/disk@xxx" instead. */ if (strcmp("usb-host", qdev_fw_name(dev)) == 0) { USBDevice *usbdev = CAST(USBDevice, dev, TYPE_USB_DEVICE); if (usb_host_dev_is_scsi_storage(usbdev)) { return g_strdup_printf("storage@%s/disk", usbdev->port->path); if (phb) { /* Replace "pci" with "pci@800000020000000" */ return g_strdup_printf("pci@%"PRIX64, phb->buid); if (vsc) { /* Same logic as virtio above */ unsigned id = 0x1000000 | (vsc->target << 16) | vsc->lun; return g_strdup_printf("disk@%"PRIX64, (uint64_t)id << 32); if (g_str_equal("pci-bridge", qdev_fw_name(dev))) { /* SLOF uses "pci" instead of "pci-bridge" for PCI bridges */ PCIDevice *pcidev = CAST(PCIDevice, dev, TYPE_PCI_DEVICE); return g_strdup_printf("pci@%x", PCI_SLOT(pcidev->devfn)); return NULL;


static int qemu_rdma_alloc_qp(RDMAContext *rdma) { struct ibv_qp_init_attr attr = { 0 }; int ret; attr.cap.max_send_wr = RDMA_SIGNALED_SEND_MAX; attr.cap.max_recv_wr = 3; attr.cap.max_send_sge = 1; attr.cap.max_recv_sge = 1; attr.send_cq = rdma->cq; attr.recv_cq = rdma->cq; attr.qp_type = IBV_QPT_RC; ret = rdma_create_qp(rdma->cm_id, rdma->pd, &attr); if (ret) { return -1; } rdma->qp = rdma->cm_id->qp; return 0; }


static void qio_channel_websock_handshake_process(QIOChannelWebsock *ioc, char *buffer, Error **errp) { QIOChannelWebsockHTTPHeader hdrs[32]; size_t nhdrs = G_N_ELEMENTS(hdrs); const char *protocols = NULL, *version = NULL, *key = NULL, *host = NULL, *connection = NULL, *upgrade = NULL; nhdrs = qio_channel_websock_extract_headers(ioc, buffer, hdrs, nhdrs, errp); if (!nhdrs) { return; } protocols = qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_PROTOCOL); if (!protocols) { error_setg(errp, "Missing websocket protocol header data"); goto bad_request; } version = qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_VERSION); if (!version) { error_setg(errp, "Missing websocket version header data"); goto bad_request; } key = qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_KEY); if (!key) { error_setg(errp, "Missing websocket key header data"); goto bad_request; } host = qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_HOST); if (!host) { error_setg(errp, "Missing websocket host header data"); goto bad_request; } connection = qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_CONNECTION); if (!connection) { error_setg(errp, "Missing websocket connection header data"); goto bad_request; } upgrade = qio_channel_websock_find_header( hdrs, nhdrs, QIO_CHANNEL_WEBSOCK_HEADER_UPGRADE); if (!upgrade) { error_setg(errp, "Missing websocket upgrade header data"); goto bad_request; } if (!g_strrstr(protocols, QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY)) { error_setg(errp, "No '%s' protocol is supported by client '%s'", QIO_CHANNEL_WEBSOCK_PROTOCOL_BINARY, protocols); goto bad_request; } if (!g_str_equal(version, QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION)) { error_setg(errp, "Version '%s' is not supported by client '%s'", QIO_CHANNEL_WEBSOCK_SUPPORTED_VERSION, version); goto bad_request; } if (strlen(key) != QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN) { error_setg(errp, "Key length '%zu' was not as expected '%d'", strlen(key), QIO_CHANNEL_WEBSOCK_CLIENT_KEY_LEN); goto bad_request; } if (strcasecmp(connection, QIO_CHANNEL_WEBSOCK_CONNECTION_UPGRADE) != 0) { error_setg(errp, "No connection upgrade requested '%s'", connection); goto bad_request; } if (strcasecmp(upgrade, QIO_CHANNEL_WEBSOCK_UPGRADE_WEBSOCKET) != 0) { error_setg(errp, "Incorrect upgrade method '%s'", upgrade); goto bad_request; } qio_channel_websock_handshake_send_res_ok(ioc, key, errp); return; bad_request: qio_channel_websock_handshake_send_res_err( ioc, QIO_CHANNEL_WEBSOCK_HANDSHAKE_RES_BAD_REQUEST); }


static int rv40_h_loop_filter_strength(uint8_t *src, int stride, int beta, int beta2, int edge, int *p1, int *q1) { return rv40_loop_filter_strength(src, stride, 1, beta, beta2, edge, p1, q1); }


static int decode_pic(AVSContext *h) { MpegEncContext *s = &h->s; int skip_count; enum cavs_mb mb_type; if (!s->context_initialized) { s->avctx->idct_algo = FF_IDCT_CAVS; if (MPV_common_init(s) < 0) return -1; ff_init_scantable(s->dsp.idct_permutation,&h->scantable,ff_zigzag_direct); } skip_bits(&s->gb,16);//bbv_dwlay if(h->stc == PIC_PB_START_CODE) { h->pic_type = get_bits(&s->gb,2) + FF_I_TYPE; if(h->pic_type > FF_B_TYPE) { av_log(s->avctx, AV_LOG_ERROR, "illegal picture type\n"); return -1; } /* make sure we have the reference frames we need */ if(!h->DPB[0].data[0] || (!h->DPB[1].data[0] && h->pic_type == FF_B_TYPE)) return -1; } else { h->pic_type = FF_I_TYPE; if(get_bits1(&s->gb)) skip_bits(&s->gb,24);//time_code } /* release last B frame */ if(h->picture.data[0]) s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture); s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture); ff_cavs_init_pic(h); h->picture.poc = get_bits(&s->gb,8)*2; /* get temporal distances and MV scaling factors */ if(h->pic_type != FF_B_TYPE) { h->dist[0] = (h->picture.poc - h->DPB[0].poc + 512) % 512; } else { h->dist[0] = (h->DPB[0].poc - h->picture.poc + 512) % 512; } h->dist[1] = (h->picture.poc - h->DPB[1].poc + 512) % 512; h->scale_den[0] = h->dist[0] ? 512/h->dist[0] : 0; h->scale_den[1] = h->dist[1] ? 512/h->dist[1] : 0; if(h->pic_type == FF_B_TYPE) { h->sym_factor = h->dist[0]*h->scale_den[1]; } else { h->direct_den[0] = h->dist[0] ? 16384/h->dist[0] : 0; h->direct_den[1] = h->dist[1] ? 16384/h->dist[1] : 0; } if(s->low_delay) get_ue_golomb(&s->gb); //bbv_check_times h->progressive = get_bits1(&s->gb); h->pic_structure = 1; if(!h->progressive) h->pic_structure = get_bits1(&s->gb); if(!h->pic_structure && h->stc == PIC_PB_START_CODE) skip_bits1(&s->gb); //advanced_pred_mode_disable skip_bits1(&s->gb); //top_field_first skip_bits1(&s->gb); //repeat_first_field h->qp_fixed = get_bits1(&s->gb); h->qp = get_bits(&s->gb,6); if(h->pic_type == FF_I_TYPE) { if(!h->progressive && !h->pic_structure) skip_bits1(&s->gb);//what is this? skip_bits(&s->gb,4); //reserved bits } else { if(!(h->pic_type == FF_B_TYPE && h->pic_structure == 1)) h->ref_flag = get_bits1(&s->gb); skip_bits(&s->gb,4); //reserved bits h->skip_mode_flag = get_bits1(&s->gb); } h->loop_filter_disable = get_bits1(&s->gb); if(!h->loop_filter_disable && get_bits1(&s->gb)) { h->alpha_offset = get_se_golomb(&s->gb); h->beta_offset = get_se_golomb(&s->gb); } else { h->alpha_offset = h->beta_offset = 0; } if(h->pic_type == FF_I_TYPE) { do { check_for_slice(h); decode_mb_i(h, 0); } while(ff_cavs_next_mb(h)); } else if(h->pic_type == FF_P_TYPE) { do { check_for_slice(h); if(h->skip_mode_flag) { skip_count = get_ue_golomb(&s->gb); while(skip_count--) { decode_mb_p(h,P_SKIP); if(!ff_cavs_next_mb(h)) goto done; } check_for_slice(h); mb_type = get_ue_golomb(&s->gb) + P_16X16; } else mb_type = get_ue_golomb(&s->gb) + P_SKIP; if(mb_type > P_8X8) { decode_mb_i(h, mb_type - P_8X8 - 1); } else decode_mb_p(h,mb_type); } while(ff_cavs_next_mb(h)); } else { /* FF_B_TYPE */ do { check_for_slice(h); if(h->skip_mode_flag) { skip_count = get_ue_golomb(&s->gb); while(skip_count--) { decode_mb_b(h,B_SKIP); if(!ff_cavs_next_mb(h)) goto done; } check_for_slice(h); mb_type = get_ue_golomb(&s->gb) + B_DIRECT; } else mb_type = get_ue_golomb(&s->gb) + B_SKIP; if(mb_type > B_8X8) { decode_mb_i(h, mb_type - B_8X8 - 1); } else decode_mb_b(h,mb_type); } while(ff_cavs_next_mb(h)); } done: if(h->pic_type != FF_B_TYPE) { if(h->DPB[1].data[0]) s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]); h->DPB[1] = h->DPB[0]; h->DPB[0] = h->picture; memset(&h->picture,0,sizeof(Picture)); } return 0; }


static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) { GXFContext *gxf = s->priv_data; AVPacket new_pkt; int i; for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) { GXFStreamContext *sc = &gxf->streams[i]; if (pkt && pkt->stream_index == i) { av_fifo_write(&sc->audio_buffer, pkt->data, pkt->size); pkt = NULL; } if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) { if (!pkt && gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) { pkt = &new_pkt; break; /* add pkt right now into list */ } } } } return av_interleave_packet_per_dts(s, out, pkt, flush); }


int ff_nvdec_decode_init(AVCodecContext *avctx) { NVDECContext *ctx = avctx->internal->hwaccel_priv_data; NVDECFramePool *pool; AVHWFramesContext *frames_ctx; const AVPixFmtDescriptor *sw_desc; CUVIDDECODECREATEINFO params = { 0 }; int cuvid_codec_type, cuvid_chroma_format; int ret = 0; sw_desc = av_pix_fmt_desc_get(avctx->sw_pix_fmt); if (!sw_desc) return AVERROR_BUG; cuvid_codec_type = map_avcodec_id(avctx->codec_id); if (cuvid_codec_type < 0) { av_log(avctx, AV_LOG_ERROR, "Unsupported codec ID\n"); return AVERROR_BUG; } cuvid_chroma_format = map_chroma_format(avctx->sw_pix_fmt); if (cuvid_chroma_format < 0) { av_log(avctx, AV_LOG_ERROR, "Unsupported chroma format\n"); return AVERROR(ENOSYS); } if (!avctx->hw_frames_ctx) { ret = ff_decode_get_hw_frames_ctx(avctx, AV_HWDEVICE_TYPE_CUDA); if (ret < 0) return ret; } frames_ctx = (AVHWFramesContext*)avctx->hw_frames_ctx->data; params.ulWidth = avctx->coded_width; params.ulHeight = avctx->coded_height; params.ulTargetWidth = avctx->coded_width; params.ulTargetHeight = avctx->coded_height; params.bitDepthMinus8 = sw_desc->comp[0].depth - 8; params.OutputFormat = params.bitDepthMinus8 ? cudaVideoSurfaceFormat_P016 : cudaVideoSurfaceFormat_NV12; params.CodecType = cuvid_codec_type; params.ChromaFormat = cuvid_chroma_format; params.ulNumDecodeSurfaces = frames_ctx->initial_pool_size; params.ulNumOutputSurfaces = 1; ret = nvdec_decoder_create(&ctx->decoder_ref, frames_ctx->device_ref, &params, avctx); if (ret < 0) return ret; pool = av_mallocz(sizeof(*pool)); if (!pool) { ret = AVERROR(ENOMEM); goto fail; } pool->dpb_size = frames_ctx->initial_pool_size; ctx->decoder_pool = av_buffer_pool_init2(sizeof(int), pool, nvdec_decoder_frame_alloc, av_free); if (!ctx->decoder_pool) { ret = AVERROR(ENOMEM); goto fail; } return 0; fail: ff_nvdec_decode_uninit(avctx); return ret; }


static void versatile_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, int board_id) { CPUState *env; ram_addr_t ram_offset; qemu_irq *cpu_pic; qemu_irq pic[32]; qemu_irq sic[32]; DeviceState *dev; PCIBus *pci_bus; NICInfo *nd; int n; int done_smc = 0; if (!cpu_model) cpu_model = "arm926"; env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } ram_offset = qemu_ram_alloc(NULL, "versatile.ram", ram_size); /* ??? RAM should repeat to fill physical memory space. */ /* SDRAM at address zero. */ cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM); arm_sysctl_init(0x10000000, 0x41007004, 0x02000000); cpu_pic = arm_pic_init_cpu(env); dev = sysbus_create_varargs("pl190", 0x10140000, cpu_pic[0], cpu_pic[1], NULL); for (n = 0; n < 32; n++) { pic[n] = qdev_get_gpio_in(dev, n); } dev = sysbus_create_simple("versatilepb_sic", 0x10003000, NULL); for (n = 0; n < 32; n++) { sysbus_connect_irq(sysbus_from_qdev(dev), n, pic[n]); sic[n] = qdev_get_gpio_in(dev, n); } sysbus_create_simple("pl050_keyboard", 0x10006000, sic[3]); sysbus_create_simple("pl050_mouse", 0x10007000, sic[4]); dev = sysbus_create_varargs("versatile_pci", 0x40000000, sic[27], sic[28], sic[29], sic[30], NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); /* The Versatile PCI bridge does not provide access to PCI IO space, so many of the qemu PCI devices are not useable. */ for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) { smc91c111_init(nd, 0x10010000, sic[25]); done_smc = 1; } else { pci_nic_init_nofail(nd, "rtl8139", NULL); } } if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { pci_create_simple(pci_bus, -1, "lsi53c895a"); n--; } sysbus_create_simple("pl011", 0x101f1000, pic[12]); sysbus_create_simple("pl011", 0x101f2000, pic[13]); sysbus_create_simple("pl011", 0x101f3000, pic[14]); sysbus_create_simple("pl011", 0x10009000, sic[6]); sysbus_create_simple("pl080", 0x10130000, pic[17]); sysbus_create_simple("sp804", 0x101e2000, pic[4]); sysbus_create_simple("sp804", 0x101e3000, pic[5]); /* The versatile/PB actually has a modified Color LCD controller that includes hardware cursor support from the PL111. */ sysbus_create_simple("pl110_versatile", 0x10120000, pic[16]); sysbus_create_varargs("pl181", 0x10005000, sic[22], sic[1], NULL); sysbus_create_varargs("pl181", 0x1000b000, sic[23], sic[2], NULL); /* Add PL031 Real Time Clock. */ sysbus_create_simple("pl031", 0x101e8000, pic[10]); /* Memory map for Versatile/PB: */ /* 0x10000000 System registers. */ /* 0x10001000 PCI controller config registers. */ /* 0x10002000 Serial bus interface. */ /* 0x10003000 Secondary interrupt controller. */ /* 0x10004000 AACI (audio). */ /* 0x10005000 MMCI0. */ /* 0x10006000 KMI0 (keyboard). */ /* 0x10007000 KMI1 (mouse). */ /* 0x10008000 Character LCD Interface. */ /* 0x10009000 UART3. */ /* 0x1000a000 Smart card 1. */ /* 0x1000b000 MMCI1. */ /* 0x10010000 Ethernet. */ /* 0x10020000 USB. */ /* 0x10100000 SSMC. */ /* 0x10110000 MPMC. */ /* 0x10120000 CLCD Controller. */ /* 0x10130000 DMA Controller. */ /* 0x10140000 Vectored interrupt controller. */ /* 0x101d0000 AHB Monitor Interface. */ /* 0x101e0000 System Controller. */ /* 0x101e1000 Watchdog Interface. */ /* 0x101e2000 Timer 0/1. */ /* 0x101e3000 Timer 2/3. */ /* 0x101e4000 GPIO port 0. */ /* 0x101e5000 GPIO port 1. */ /* 0x101e6000 GPIO port 2. */ /* 0x101e7000 GPIO port 3. */ /* 0x101e8000 RTC. */ /* 0x101f0000 Smart card 0. */ /* 0x101f1000 UART0. */ /* 0x101f2000 UART1. */ /* 0x101f3000 UART2. */ /* 0x101f4000 SSPI. */ versatile_binfo.ram_size = ram_size; versatile_binfo.kernel_filename = kernel_filename; versatile_binfo.kernel_cmdline = kernel_cmdline; versatile_binfo.initrd_filename = initrd_filename; versatile_binfo.board_id = board_id; arm_load_kernel(env, &versatile_binfo); }


static void kvm_mem_ioeventfd_add(MemoryListener *listener, MemoryRegionSection *section, bool match_data, uint64_t data, EventNotifier *e) { int fd = event_notifier_get_fd(e); int r; r = kvm_set_ioeventfd_mmio(fd, section->offset_within_address_space, data, true, int128_get64(section->size), match_data); if (r < 0) { abort(); } }


static void vfio_probe_rtl8168_bar2_window_quirk(VFIOPCIDevice *vdev, int nr) { PCIDevice *pdev = &vdev->pdev; VFIOQuirk *quirk; if (pci_get_word(pdev->config + PCI_VENDOR_ID) != PCI_VENDOR_ID_REALTEK || pci_get_word(pdev->config + PCI_DEVICE_ID) != 0x8168 || nr != 2) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->vdev = vdev; quirk->data.bar = nr; memory_region_init_io(&quirk->mem, OBJECT(vdev), &vfio_rtl8168_window_quirk, quirk, "vfio-rtl8168-window-quirk", 8); memory_region_add_subregion_overlap(&vdev->bars[nr].region.mem, 0x70, &quirk->mem, 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); trace_vfio_probe_rtl8168_bar2_window_quirk(vdev->vbasedev.name); }


tcp_listen(Slirp *slirp, u_int32_t haddr, u_int hport, u_int32_t laddr, u_int lport, int flags) { struct sockaddr_in addr; struct socket *so; int s, opt = 1; socklen_t addrlen = sizeof(addr); DEBUG_CALL("tcp_listen"); DEBUG_ARG("haddr = %x", haddr); DEBUG_ARG("hport = %d", hport); DEBUG_ARG("laddr = %x", laddr); DEBUG_ARG("lport = %d", lport); DEBUG_ARG("flags = %x", flags); so = socreate(slirp); if (!so) { return NULL; } /* Don't tcp_attach... we don't need so_snd nor so_rcv */ if ((so->so_tcpcb = tcp_newtcpcb(so)) == NULL) { free(so); return NULL; } insque(so, &slirp->tcb); /* * SS_FACCEPTONCE sockets must time out. */ if (flags & SS_FACCEPTONCE) so->so_tcpcb->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT*2; so->so_state &= SS_PERSISTENT_MASK; so->so_state |= (SS_FACCEPTCONN | flags); so->so_lport = lport; /* Kept in network format */ so->so_laddr.s_addr = laddr; /* Ditto */ addr.sin_family = AF_INET; addr.sin_addr.s_addr = haddr; addr.sin_port = hport; if (((s = socket(AF_INET,SOCK_STREAM,0)) < 0) || (setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&opt,sizeof(int)) < 0) || (bind(s,(struct sockaddr *)&addr, sizeof(addr)) < 0) || (listen(s,1) < 0)) { int tmperrno = errno; /* Don't clobber the real reason we failed */ close(s); sofree(so); /* Restore the real errno */ #ifdef _WIN32 WSASetLastError(tmperrno); #else errno = tmperrno; #endif return NULL; } setsockopt(s,SOL_SOCKET,SO_OOBINLINE,(char *)&opt,sizeof(int)); getsockname(s,(struct sockaddr *)&addr,&addrlen); so->so_fport = addr.sin_port; if (addr.sin_addr.s_addr == 0 || addr.sin_addr.s_addr == loopback_addr.s_addr) so->so_faddr = slirp->vhost_addr; else so->so_faddr = addr.sin_addr; so->s = s; return so; }


static void test_dummy_createcmdl(void) { QemuOpts *opts; DummyObject *dobj; Error *err = NULL; const char *params = TYPE_DUMMY \ ",id=dev0," \ "bv=yes,sv=Hiss hiss hiss,av=platypus"; qemu_add_opts(&qemu_object_opts); opts = qemu_opts_parse(&qemu_object_opts, params, true, &err); g_assert(err == NULL); g_assert(opts); dobj = DUMMY_OBJECT(user_creatable_add_opts(opts, &err)); g_assert(err == NULL); g_assert(dobj); g_assert_cmpstr(dobj->sv, ==, "Hiss hiss hiss"); g_assert(dobj->bv == true); g_assert(dobj->av == DUMMY_PLATYPUS); user_creatable_del("dev0", &err); g_assert(err == NULL); error_free(err); /* * cmdline-parsing via qemu_opts_parse() results in a QemuOpts entry * corresponding to the Object's ID to be added to the QemuOptsList * for objects. To avoid having this entry conflict with future * Objects using the same ID (which can happen in cases where * qemu_opts_parse() is used to parse the object params, such as * with hmp_object_add() at the time of this comment), we need to * check for this in user_creatable_del() and remove the QemuOpts if * it is present. * * The below check ensures this works as expected. */ g_assert_null(qemu_opts_find(&qemu_object_opts, "dev0")); }


static int thp_read_packet(AVFormatContext *s, AVPacket *pkt) { ThpDemuxContext *thp = s->priv_data; AVIOContext *pb = s->pb; unsigned int size; int ret; if (thp->audiosize == 0) { /* Terminate when last frame is reached. */ if (thp->frame >= thp->framecnt) return AVERROR_EOF; avio_seek(pb, thp->next_frame, SEEK_SET); /* Locate the next frame and read out its size. */ thp->next_frame += FFMAX(thp->next_framesz, 1); thp->next_framesz = avio_rb32(pb); avio_rb32(pb); /* Previous total size. */ size = avio_rb32(pb); /* Total size of this frame. */ /* Store the audiosize so the next time this function is called, the audio can be read. */ if (thp->has_audio) thp->audiosize = avio_rb32(pb); /* Audio size. */ else thp->frame++; ret = av_get_packet(pb, pkt, size); if (ret != size) { av_free_packet(pkt); return AVERROR(EIO); } pkt->stream_index = thp->video_stream_index; } else { ret = av_get_packet(pb, pkt, thp->audiosize); if (ret != thp->audiosize) { av_free_packet(pkt); return AVERROR(EIO); } pkt->stream_index = thp->audio_stream_index; if (thp->audiosize >= 8) pkt->duration = AV_RB32(&pkt->data[4]); thp->audiosize = 0; thp->frame++; } return 0; }


static int RENAME(resample_common)(ResampleContext *c, DELEM *dst, const DELEM *src, int n, int update_ctx) { int dst_index; int index= c->index; int frac= c->frac; int sample_index = index >> c->phase_shift; index &= c->phase_mask; for (dst_index = 0; dst_index < n; dst_index++) { FELEM *filter = ((FELEM *) c->filter_bank) + c->filter_alloc * index; FELEM2 val=0; int i; for (i = 0; i < c->filter_length; i++) { val += src[sample_index + i] * (FELEM2)filter[i]; } OUT(dst[dst_index], val); frac += c->dst_incr_mod; index += c->dst_incr_div; if (frac >= c->src_incr) { frac -= c->src_incr; index++; } sample_index += index >> c->phase_shift; index &= c->phase_mask; } if(update_ctx){ c->frac= frac; c->index= index; } return sample_index; }


static int send_status(int sockfd, struct iovec *iovec, int status) { ProxyHeader header; int retval, msg_size; if (status < 0) { header.type = T_ERROR; } else { header.type = T_SUCCESS; header.size = sizeof(status); /* * marshal the return status. We don't check error. * because we are sure we have enough space for the status */ msg_size = proxy_marshal(iovec, 0, "ddd", header.type, header.size, status); retval = socket_write(sockfd, iovec->iov_base, msg_size); if (retval < 0) { return retval; return 0;


int av_image_fill_pointers(uint8_t *data[4], enum PixelFormat pix_fmt, int height, uint8_t *ptr, const int linesizes[4]) { int i, total_size, size[4], has_plane[4]; const AVPixFmtDescriptor *desc = &av_pix_fmt_descriptors[pix_fmt]; memset(data , 0, sizeof(data[0])*4); memset(size , 0, sizeof(size)); memset(has_plane, 0, sizeof(has_plane)); if ((unsigned)pix_fmt >= PIX_FMT_NB || desc->flags & PIX_FMT_HWACCEL) return AVERROR(EINVAL); data[0] = ptr; if (linesizes[0] > (INT_MAX - 1024) / height) return AVERROR(EINVAL); size[0] = linesizes[0] * height; if (desc->flags & PIX_FMT_PAL) { size[0] = (size[0] + 3) & ~3; data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */ return size[0] + 256 * 4; } for (i = 0; i < 4; i++) has_plane[desc->comp[i].plane] = 1; total_size = size[0]; for (i = 1; i < 4 && has_plane[i]; i++) { int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0; data[i] = data[i-1] + size[i-1]; h = (height + (1 << s) - 1) >> s; if (linesizes[i] > INT_MAX / h) return AVERROR(EINVAL); size[i] = h * linesizes[i]; if (total_size > INT_MAX - size[i]) return AVERROR(EINVAL); total_size += size[i]; } return total_size; }