static void lan9118_writel(void *opaque, target_phys_addr_t offset, uint64_t val, unsigned size) { lan9118_state *s = (lan9118_state *)opaque; offset &= 0xff; //DPRINTF("Write reg 0x%02x = 0x%08x\n", (int)offset, val); if (offset >= 0x20 && offset < 0x40) { /* TX FIFO */ tx_fifo_push(s, val); return; } switch (offset) { case CSR_IRQ_CFG: /* TODO: Implement interrupt deassertion intervals. */ val &= (IRQ_EN | IRQ_POL | IRQ_TYPE); s->irq_cfg = (s->irq_cfg & IRQ_INT) | val; break; case CSR_INT_STS: s->int_sts &= ~val; break; case CSR_INT_EN: s->int_en = val & ~RESERVED_INT; s->int_sts |= val & SW_INT; break; case CSR_FIFO_INT: DPRINTF("FIFO INT levels %08x\n", val); s->fifo_int = val; break; case CSR_RX_CFG: if (val & 0x8000) { /* RX_DUMP */ s->rx_fifo_used = 0; s->rx_status_fifo_used = 0; s->rx_packet_size_tail = s->rx_packet_size_head; s->rx_packet_size[s->rx_packet_size_head] = 0; } s->rx_cfg = val & 0xcfff1ff0; break; case CSR_TX_CFG: if (val & 0x8000) { s->tx_status_fifo_used = 0; } if (val & 0x4000) { s->txp->state = TX_IDLE; s->txp->fifo_used = 0; s->txp->cmd_a = 0xffffffff; } s->tx_cfg = val & 6; break; case CSR_HW_CFG: if (val & 1) { /* SRST */ lan9118_reset(&s->busdev.qdev); } else { s->hw_cfg = (val & 0x003f300) | (s->hw_cfg & 0x4); } break; case CSR_RX_DP_CTRL: if (val & 0x80000000) { /* Skip forward to next packet. */ s->rxp_pad = 0; s->rxp_offset = 0; if (s->rxp_size == 0) { /* Pop a word to start the next packet. */ rx_fifo_pop(s); s->rxp_pad = 0; s->rxp_offset = 0; } s->rx_fifo_head += s->rxp_size; if (s->rx_fifo_head >= s->rx_fifo_size) { s->rx_fifo_head -= s->rx_fifo_size; } } break; case CSR_PMT_CTRL: if (val & 0x400) { phy_reset(s); } s->pmt_ctrl &= ~0x34e; s->pmt_ctrl |= (val & 0x34e); break; case CSR_GPIO_CFG: /* Probably just enabling LEDs. */ s->gpio_cfg = val & 0x7777071f; break; case CSR_GPT_CFG: if ((s->gpt_cfg ^ val) & GPT_TIMER_EN) { if (val & GPT_TIMER_EN) { ptimer_set_count(s->timer, val & 0xffff); ptimer_run(s->timer, 0); } else { ptimer_stop(s->timer); ptimer_set_count(s->timer, 0xffff); } } s->gpt_cfg = val & (GPT_TIMER_EN | 0xffff); break; case CSR_WORD_SWAP: /* Ignored because we're in 32-bit mode. */ s->word_swap = val; break; case CSR_MAC_CSR_CMD: s->mac_cmd = val & 0x4000000f; if (val & 0x80000000) { if (val & 0x40000000) { s->mac_data = do_mac_read(s, val & 0xf); DPRINTF("MAC read %d = 0x%08x\n", val & 0xf, s->mac_data); } else { DPRINTF("MAC write %d = 0x%08x\n", val & 0xf, s->mac_data); do_mac_write(s, val & 0xf, s->mac_data); } } break; case CSR_MAC_CSR_DATA: s->mac_data = val; break; case CSR_AFC_CFG: s->afc_cfg = val & 0x00ffffff; break; case CSR_E2P_CMD: lan9118_eeprom_cmd(s, (val >> 28) & 7, val & 0x7f); break; case CSR_E2P_DATA: s->e2p_data = val & 0xff; break; default: hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, (int)val); break; } lan9118_update(s); }


float64 HELPER(ucf64_muld)(float64 a, float64 b, CPUUniCore32State *env) { return float64_mul(a, b, &env->ucf64.fp_status); }


static int check_physical (CPUState *env, mmu_ctx_t *ctx, target_ulong eaddr, int rw) { int in_plb, ret; ctx->raddr = eaddr; ctx->prot = PAGE_READ; ret = 0; switch (env->mmu_model) { case POWERPC_MMU_32B: case POWERPC_MMU_SOFT_6xx: case POWERPC_MMU_SOFT_74xx: case POWERPC_MMU_SOFT_4xx: case POWERPC_MMU_REAL_4xx: case POWERPC_MMU_BOOKE: ctx->prot |= PAGE_WRITE; break; #if defined(TARGET_PPC64) case POWERPC_MMU_64B: /* Real address are 60 bits long */ ctx->raddr &= 0x0FFFFFFFFFFFFFFFULL; ctx->prot |= PAGE_WRITE; break; #endif case POWERPC_MMU_SOFT_4xx_Z: if (unlikely(msr_pe != 0)) { /* 403 family add some particular protections, * using PBL/PBU registers for accesses with no translation. */ in_plb = /* Check PLB validity */ (env->pb[0] < env->pb[1] && /* and address in plb area */ eaddr >= env->pb[0] && eaddr < env->pb[1]) || (env->pb[2] < env->pb[3] && eaddr >= env->pb[2] && eaddr < env->pb[3]) ? 1 : 0; if (in_plb ^ msr_px) { /* Access in protected area */ if (rw == 1) { /* Access is not allowed */ ret = -2; } } else { /* Read-write access is allowed */ ctx->prot |= PAGE_WRITE; } } break; case POWERPC_MMU_BOOKE_FSL: /* XXX: TODO */ cpu_abort(env, "BookE FSL MMU model not implemented\n"); break; default: cpu_abort(env, "Unknown or invalid MMU model\n"); return -1; } return ret; }


static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) { if (blit_is_unsafe(s)) return 0; cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, s->cirrus_blt_srcaddr - s->vga.start_addr, s->cirrus_blt_width, s->cirrus_blt_height); return 1; }


static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque); }


static void xen_main_loop_prepare(XenIOState *state) { int evtchn_fd = -1; if (state->xce_handle != XC_HANDLER_INITIAL_VALUE) { evtchn_fd = xc_evtchn_fd(state->xce_handle); } state->buffered_io_timer = timer_new_ms(QEMU_CLOCK_REALTIME, handle_buffered_io, state); if (evtchn_fd != -1) { CPUState *cpu_state; DPRINTF("%s: Init cpu_by_vcpu_id\n", __func__); CPU_FOREACH(cpu_state) { DPRINTF("%s: cpu_by_vcpu_id[%d]=%p\n", __func__, cpu_state->cpu_index, cpu_state); state->cpu_by_vcpu_id[cpu_state->cpu_index] = cpu_state; } qemu_set_fd_handler(evtchn_fd, cpu_handle_ioreq, NULL, state); } }


static void blk_mig_cleanup(void) { BlkMigDevState *bmds; BlkMigBlock *blk; bdrv_drain_all(); unset_dirty_tracking(); blk_mig_lock(); while ((bmds = QSIMPLEQ_FIRST(&block_mig_state.bmds_list)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&block_mig_state.bmds_list, entry); bdrv_set_in_use(bmds->bs, 0); bdrv_unref(bmds->bs); g_free(bmds->aio_bitmap); g_free(bmds); } while ((blk = QSIMPLEQ_FIRST(&block_mig_state.blk_list)) != NULL) { QSIMPLEQ_REMOVE_HEAD(&block_mig_state.blk_list, entry); g_free(blk->buf); g_free(blk); } blk_mig_unlock(); }


static int decode_rle(GetBitContext *gb, uint8_t *pal_dst, int pal_stride, uint8_t *rgb_dst, int rgb_stride, uint32_t *pal, int keyframe, int kf_slipt, int slice, int w, int h) { uint8_t bits[270] = { 0 }; uint32_t codes[270]; VLC vlc; int current_length = 0, read_codes = 0, next_code = 0, current_codes = 0; int remaining_codes, surplus_codes, i; const int alphabet_size = 270 - keyframe; int last_symbol = 0, repeat = 0, prev_avail = 0; if (!keyframe) { int x, y, clipw, cliph; x = get_bits(gb, 12); y = get_bits(gb, 12); clipw = get_bits(gb, 12) + 1; cliph = get_bits(gb, 12) + 1; if (x + clipw > w || y + cliph > h) return AVERROR_INVALIDDATA; pal_dst += pal_stride * y + x; rgb_dst += rgb_stride * y + x * 3; w = clipw; h = cliph; if (y) prev_avail = 1; } else { if (slice > 0) { pal_dst += pal_stride * kf_slipt; rgb_dst += rgb_stride * kf_slipt; prev_avail = 1; h -= kf_slipt; } else h = kf_slipt; } /* read explicit codes */ do { while (current_codes--) { int symbol = get_bits(gb, 8); if (symbol >= 204 - keyframe) symbol += 14 - keyframe; else if (symbol > 189) symbol = get_bits1(gb) + (symbol << 1) - 190; if (bits[symbol]) return AVERROR_INVALIDDATA; bits[symbol] = current_length; codes[symbol] = next_code++; read_codes++; } current_length++; next_code <<= 1; remaining_codes = (1 << current_length) - next_code; current_codes = get_bits(gb, av_ceil_log2(remaining_codes + 1)); if (current_length > 22 || current_codes > remaining_codes) return AVERROR_INVALIDDATA; } while (current_codes != remaining_codes); remaining_codes = alphabet_size - read_codes; /* determine the minimum length to fit the rest of the alphabet */ while ((surplus_codes = (2 << current_length) - (next_code << 1) - remaining_codes) < 0) { current_length++; next_code <<= 1; } /* add the rest of the symbols lexicographically */ for (i = 0; i < alphabet_size; i++) if (!bits[i]) { if (surplus_codes-- == 0) { current_length++; next_code <<= 1; } bits[i] = current_length; codes[i] = next_code++; } if (next_code != 1 << current_length) return AVERROR_INVALIDDATA; if (i = init_vlc(&vlc, 9, alphabet_size, bits, 1, 1, codes, 4, 4, 0)) return i; /* frame decode */ do { uint8_t *pp = pal_dst; uint8_t *rp = rgb_dst; do { if (repeat-- < 1) { int b = get_vlc2(gb, vlc.table, 9, 3); if (b < 256) last_symbol = b; else if (b < 268) { b -= 256; if (b == 11) b = get_bits(gb, 4) + 10; if (!b) repeat = 0; else repeat = get_bits(gb, b); repeat += (1 << b) - 1; if (last_symbol == -2) { int skip = FFMIN(repeat, pal_dst + w - pp); repeat -= skip; pp += skip; rp += skip * 3; } } else last_symbol = 267 - b; } if (last_symbol >= 0) { *pp = last_symbol; AV_WB24(rp, pal[last_symbol]); } else if (last_symbol == -1 && prev_avail) { *pp = *(pp - pal_stride); memcpy(rp, rp - rgb_stride, 3); } rp += 3; } while (++pp < pal_dst + w); pal_dst += pal_stride; rgb_dst += rgb_stride; prev_avail = 1; } while (--h); ff_free_vlc(&vlc); return 0; }


static void dacr_write(CPUARMState *env, const ARMCPRegInfo *ri, uint64_t value) { ARMCPU *cpu = arm_env_get_cpu(env); env->cp15.c3 = value; tlb_flush(CPU(cpu), 1); /* Flush TLB as domain not tracked in TLB */ }


void bdrv_io_unplugged_end(BlockDriverState *bs) { BdrvChild *child; assert(bs->io_plug_disabled); QLIST_FOREACH(child, &bs->children, next) { bdrv_io_unplugged_end(child->bs); } if (--bs->io_plug_disabled == 0 && bs->io_plugged > 0) { BlockDriver *drv = bs->drv; if (drv && drv->bdrv_io_plug) { drv->bdrv_io_plug(bs); } } }


static uint64_t omap_prcm_read(void *opaque, target_phys_addr_t addr, unsigned size) { struct omap_prcm_s *s = (struct omap_prcm_s *) opaque; uint32_t ret; if (size != 4) { return omap_badwidth_read32(opaque, addr); } switch (addr) { case 0x000: /* PRCM_REVISION */ return 0x10; case 0x010: /* PRCM_SYSCONFIG */ return s->sysconfig; case 0x018: /* PRCM_IRQSTATUS_MPU */ return s->irqst[0]; case 0x01c: /* PRCM_IRQENABLE_MPU */ return s->irqen[0]; case 0x050: /* PRCM_VOLTCTRL */ return s->voltctrl; case 0x054: /* PRCM_VOLTST */ return s->voltctrl & 3; case 0x060: /* PRCM_CLKSRC_CTRL */ return s->clksrc[0]; case 0x070: /* PRCM_CLKOUT_CTRL */ return s->clkout[0]; case 0x078: /* PRCM_CLKEMUL_CTRL */ return s->clkemul[0]; case 0x080: /* PRCM_CLKCFG_CTRL */ case 0x084: /* PRCM_CLKCFG_STATUS */ return 0; case 0x090: /* PRCM_VOLTSETUP */ return s->setuptime[0]; case 0x094: /* PRCM_CLKSSETUP */ return s->setuptime[1]; case 0x098: /* PRCM_POLCTRL */ return s->clkpol[0]; case 0x0b0: /* GENERAL_PURPOSE1 */ case 0x0b4: /* GENERAL_PURPOSE2 */ case 0x0b8: /* GENERAL_PURPOSE3 */ case 0x0bc: /* GENERAL_PURPOSE4 */ case 0x0c0: /* GENERAL_PURPOSE5 */ case 0x0c4: /* GENERAL_PURPOSE6 */ case 0x0c8: /* GENERAL_PURPOSE7 */ case 0x0cc: /* GENERAL_PURPOSE8 */ case 0x0d0: /* GENERAL_PURPOSE9 */ case 0x0d4: /* GENERAL_PURPOSE10 */ case 0x0d8: /* GENERAL_PURPOSE11 */ case 0x0dc: /* GENERAL_PURPOSE12 */ case 0x0e0: /* GENERAL_PURPOSE13 */ case 0x0e4: /* GENERAL_PURPOSE14 */ case 0x0e8: /* GENERAL_PURPOSE15 */ case 0x0ec: /* GENERAL_PURPOSE16 */ case 0x0f0: /* GENERAL_PURPOSE17 */ case 0x0f4: /* GENERAL_PURPOSE18 */ case 0x0f8: /* GENERAL_PURPOSE19 */ case 0x0fc: /* GENERAL_PURPOSE20 */ return s->scratch[(addr - 0xb0) >> 2]; case 0x140: /* CM_CLKSEL_MPU */ return s->clksel[0]; case 0x148: /* CM_CLKSTCTRL_MPU */ return s->clkctrl[0]; case 0x158: /* RM_RSTST_MPU */ return s->rst[0]; case 0x1c8: /* PM_WKDEP_MPU */ return s->wkup[0]; case 0x1d4: /* PM_EVGENCTRL_MPU */ return s->ev; case 0x1d8: /* PM_EVEGENONTIM_MPU */ return s->evtime[0]; case 0x1dc: /* PM_EVEGENOFFTIM_MPU */ return s->evtime[1]; case 0x1e0: /* PM_PWSTCTRL_MPU */ return s->power[0]; case 0x1e4: /* PM_PWSTST_MPU */ return 0; case 0x200: /* CM_FCLKEN1_CORE */ return s->clken[0]; case 0x204: /* CM_FCLKEN2_CORE */ return s->clken[1]; case 0x210: /* CM_ICLKEN1_CORE */ return s->clken[2]; case 0x214: /* CM_ICLKEN2_CORE */ return s->clken[3]; case 0x21c: /* CM_ICLKEN4_CORE */ return s->clken[4]; case 0x220: /* CM_IDLEST1_CORE */ /* TODO: check the actual iclk status */ return 0x7ffffff9; case 0x224: /* CM_IDLEST2_CORE */ /* TODO: check the actual iclk status */ return 0x00000007; case 0x22c: /* CM_IDLEST4_CORE */ /* TODO: check the actual iclk status */ return 0x0000001f; case 0x230: /* CM_AUTOIDLE1_CORE */ return s->clkidle[0]; case 0x234: /* CM_AUTOIDLE2_CORE */ return s->clkidle[1]; case 0x238: /* CM_AUTOIDLE3_CORE */ return s->clkidle[2]; case 0x23c: /* CM_AUTOIDLE4_CORE */ return s->clkidle[3]; case 0x240: /* CM_CLKSEL1_CORE */ return s->clksel[1]; case 0x244: /* CM_CLKSEL2_CORE */ return s->clksel[2]; case 0x248: /* CM_CLKSTCTRL_CORE */ return s->clkctrl[1]; case 0x2a0: /* PM_WKEN1_CORE */ return s->wken[0]; case 0x2a4: /* PM_WKEN2_CORE */ return s->wken[1]; case 0x2b0: /* PM_WKST1_CORE */ return s->wkst[0]; case 0x2b4: /* PM_WKST2_CORE */ return s->wkst[1]; case 0x2c8: /* PM_WKDEP_CORE */ return 0x1e; case 0x2e0: /* PM_PWSTCTRL_CORE */ return s->power[1]; case 0x2e4: /* PM_PWSTST_CORE */ return 0x000030 | (s->power[1] & 0xfc00); case 0x300: /* CM_FCLKEN_GFX */ return s->clken[5]; case 0x310: /* CM_ICLKEN_GFX */ return s->clken[6]; case 0x320: /* CM_IDLEST_GFX */ /* TODO: check the actual iclk status */ return 0x00000001; case 0x340: /* CM_CLKSEL_GFX */ return s->clksel[3]; case 0x348: /* CM_CLKSTCTRL_GFX */ return s->clkctrl[2]; case 0x350: /* RM_RSTCTRL_GFX */ return s->rstctrl[0]; case 0x358: /* RM_RSTST_GFX */ return s->rst[1]; case 0x3c8: /* PM_WKDEP_GFX */ return s->wkup[1]; case 0x3e0: /* PM_PWSTCTRL_GFX */ return s->power[2]; case 0x3e4: /* PM_PWSTST_GFX */ return s->power[2] & 3; case 0x400: /* CM_FCLKEN_WKUP */ return s->clken[7]; case 0x410: /* CM_ICLKEN_WKUP */ return s->clken[8]; case 0x420: /* CM_IDLEST_WKUP */ /* TODO: check the actual iclk status */ return 0x0000003f; case 0x430: /* CM_AUTOIDLE_WKUP */ return s->clkidle[4]; case 0x440: /* CM_CLKSEL_WKUP */ return s->clksel[4]; case 0x450: /* RM_RSTCTRL_WKUP */ return 0; case 0x454: /* RM_RSTTIME_WKUP */ return s->rsttime_wkup; case 0x458: /* RM_RSTST_WKUP */ return s->rst[2]; case 0x4a0: /* PM_WKEN_WKUP */ return s->wken[2]; case 0x4b0: /* PM_WKST_WKUP */ return s->wkst[2]; case 0x500: /* CM_CLKEN_PLL */ return s->clken[9]; case 0x520: /* CM_IDLEST_CKGEN */ ret = 0x0000070 | (s->apll_lock[0] << 9) | (s->apll_lock[1] << 8); if (!(s->clksel[6] & 3)) /* Core uses 32-kHz clock */ ret |= 3 << 0; else if (!s->dpll_lock) /* DPLL not locked, core uses ref_clk */ ret |= 1 << 0; else /* Core uses DPLL */ ret |= 2 << 0; return ret; case 0x530: /* CM_AUTOIDLE_PLL */ return s->clkidle[5]; case 0x540: /* CM_CLKSEL1_PLL */ return s->clksel[5]; case 0x544: /* CM_CLKSEL2_PLL */ return s->clksel[6]; case 0x800: /* CM_FCLKEN_DSP */ return s->clken[10]; case 0x810: /* CM_ICLKEN_DSP */ return s->clken[11]; case 0x820: /* CM_IDLEST_DSP */ /* TODO: check the actual iclk status */ return 0x00000103; case 0x830: /* CM_AUTOIDLE_DSP */ return s->clkidle[6]; case 0x840: /* CM_CLKSEL_DSP */ return s->clksel[7]; case 0x848: /* CM_CLKSTCTRL_DSP */ return s->clkctrl[3]; case 0x850: /* RM_RSTCTRL_DSP */ return 0; case 0x858: /* RM_RSTST_DSP */ return s->rst[3]; case 0x8c8: /* PM_WKDEP_DSP */ return s->wkup[2]; case 0x8e0: /* PM_PWSTCTRL_DSP */ return s->power[3]; case 0x8e4: /* PM_PWSTST_DSP */ return 0x008030 | (s->power[3] & 0x3003); case 0x8f0: /* PRCM_IRQSTATUS_DSP */ return s->irqst[1]; case 0x8f4: /* PRCM_IRQENABLE_DSP */ return s->irqen[1]; case 0x8f8: /* PRCM_IRQSTATUS_IVA */ return s->irqst[2]; case 0x8fc: /* PRCM_IRQENABLE_IVA */ return s->irqen[2]; } OMAP_BAD_REG(addr); return 0; }


float64 HELPER(ucf64_negd)(float64 a) { return float64_chs(a); }


static int tcp_chr_add_client(CharDriverState *chr, int fd) { TCPCharDriver *s = chr->opaque; if (s->fd != -1) return -1; qemu_set_nonblock(fd); if (s->do_nodelay) socket_set_nodelay(fd); s->fd = fd; s->chan = io_channel_from_socket(fd); g_source_remove(s->listen_tag); s->listen_tag = 0; tcp_chr_connect(chr); return 0; }


static uint64_t omap_tipb_bridge_read(void *opaque, target_phys_addr_t addr, unsigned size) { struct omap_tipb_bridge_s *s = (struct omap_tipb_bridge_s *) opaque; if (size < 2) { return omap_badwidth_read16(opaque, addr); } switch (addr) { case 0x00: /* TIPB_CNTL */ return s->control; case 0x04: /* TIPB_BUS_ALLOC */ return s->alloc; case 0x08: /* MPU_TIPB_CNTL */ return s->buffer; case 0x0c: /* ENHANCED_TIPB_CNTL */ return s->enh_control; case 0x10: /* ADDRESS_DBG */ case 0x14: /* DATA_DEBUG_LOW */ case 0x18: /* DATA_DEBUG_HIGH */ return 0xffff; case 0x1c: /* DEBUG_CNTR_SIG */ return 0x00f8; } OMAP_BAD_REG(addr); return 0; }


static void lan9118_writel(void *opaque, hwaddr offset, uint64_t val, unsigned size) { lan9118_state *s = (lan9118_state *)opaque; offset &= 0xff; //DPRINTF("Write reg 0x%02x = 0x%08x\n", (int)offset, val); if (offset >= 0x20 && offset < 0x40) { /* TX FIFO */ tx_fifo_push(s, val); return; } switch (offset) { case CSR_IRQ_CFG: /* TODO: Implement interrupt deassertion intervals. */ val &= (IRQ_EN | IRQ_POL | IRQ_TYPE); s->irq_cfg = (s->irq_cfg & IRQ_INT) | val; break; case CSR_INT_STS: s->int_sts &= ~val; break; case CSR_INT_EN: s->int_en = val & ~RESERVED_INT; s->int_sts |= val & SW_INT; break; case CSR_FIFO_INT: DPRINTF("FIFO INT levels %08x\n", val); s->fifo_int = val; break; case CSR_RX_CFG: if (val & 0x8000) { /* RX_DUMP */ s->rx_fifo_used = 0; s->rx_status_fifo_used = 0; s->rx_packet_size_tail = s->rx_packet_size_head; s->rx_packet_size[s->rx_packet_size_head] = 0; } s->rx_cfg = val & 0xcfff1ff0; break; case CSR_TX_CFG: if (val & 0x8000) { s->tx_status_fifo_used = 0; } if (val & 0x4000) { s->txp->state = TX_IDLE; s->txp->fifo_used = 0; s->txp->cmd_a = 0xffffffff; } s->tx_cfg = val & 6; break; case CSR_HW_CFG: if (val & 1) { /* SRST */ lan9118_reset(DEVICE(s)); } else { s->hw_cfg = (val & 0x003f300) | (s->hw_cfg & 0x4); } break; case CSR_RX_DP_CTRL: if (val & 0x80000000) { /* Skip forward to next packet. */ s->rxp_pad = 0; s->rxp_offset = 0; if (s->rxp_size == 0) { /* Pop a word to start the next packet. */ rx_fifo_pop(s); s->rxp_pad = 0; s->rxp_offset = 0; } s->rx_fifo_head += s->rxp_size; if (s->rx_fifo_head >= s->rx_fifo_size) { s->rx_fifo_head -= s->rx_fifo_size; } } break; case CSR_PMT_CTRL: if (val & 0x400) { phy_reset(s); } s->pmt_ctrl &= ~0x34e; s->pmt_ctrl |= (val & 0x34e); break; case CSR_GPIO_CFG: /* Probably just enabling LEDs. */ s->gpio_cfg = val & 0x7777071f; break; case CSR_GPT_CFG: if ((s->gpt_cfg ^ val) & GPT_TIMER_EN) { if (val & GPT_TIMER_EN) { ptimer_set_count(s->timer, val & 0xffff); ptimer_run(s->timer, 0); } else { ptimer_stop(s->timer); ptimer_set_count(s->timer, 0xffff); } } s->gpt_cfg = val & (GPT_TIMER_EN | 0xffff); break; case CSR_WORD_SWAP: /* Ignored because we're in 32-bit mode. */ s->word_swap = val; break; case CSR_MAC_CSR_CMD: s->mac_cmd = val & 0x4000000f; if (val & 0x80000000) { if (val & 0x40000000) { s->mac_data = do_mac_read(s, val & 0xf); DPRINTF("MAC read %d = 0x%08x\n", val & 0xf, s->mac_data); } else { DPRINTF("MAC write %d = 0x%08x\n", val & 0xf, s->mac_data); do_mac_write(s, val & 0xf, s->mac_data); } } break; case CSR_MAC_CSR_DATA: s->mac_data = val; break; case CSR_AFC_CFG: s->afc_cfg = val & 0x00ffffff; break; case CSR_E2P_CMD: lan9118_eeprom_cmd(s, (val >> 28) & 7, val & 0x7f); break; case CSR_E2P_DATA: s->e2p_data = val & 0xff; break; default: hw_error("lan9118_write: Bad reg 0x%x = %x\n", (int)offset, (int)val); break; } lan9118_update(s); }


int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp) { BlockDriver *drv; Error *local_err = NULL; int ret; drv = bdrv_find_protocol(filename, true, errp); if (drv == NULL) { return -ENOENT; } ret = bdrv_create(drv, filename, opts, &local_err); if (local_err) { error_propagate(errp, local_err); } return ret; }


static int tcg_match_add2i(TCGType type, tcg_target_long val) { if (facilities & FACILITY_EXT_IMM) { if (type == TCG_TYPE_I32) { return 1; } else if (val >= -0xffffffffll && val <= 0xffffffffll) { return 1; } } return 0; }


int coroutine_fn bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors, int *pnum) { return bdrv_get_block_status(bs, sector_num, nb_sectors, pnum); }


static void fw_cfg_init1(DeviceState *dev) { FWCfgState *s = FW_CFG(dev); MachineState *machine = MACHINE(qdev_get_machine()); assert(!object_resolve_path(FW_CFG_PATH, NULL)); object_property_add_child(OBJECT(machine), FW_CFG_NAME, OBJECT(s), NULL); qdev_init_nofail(dev); fw_cfg_add_bytes(s, FW_CFG_SIGNATURE, (char *)"QEMU", 4); fw_cfg_add_bytes(s, FW_CFG_UUID, &qemu_uuid, 16); fw_cfg_add_i16(s, FW_CFG_NOGRAPHIC, (uint16_t)!machine->enable_graphics); fw_cfg_add_i16(s, FW_CFG_NB_CPUS, (uint16_t)smp_cpus); fw_cfg_add_i16(s, FW_CFG_BOOT_MENU, (uint16_t)boot_menu); fw_cfg_bootsplash(s); fw_cfg_reboot(s); s->machine_ready.notify = fw_cfg_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); }


static av_cold int vsink_init(AVFilterContext *ctx, const char *args, void *opaque) { BufferSinkContext *buf = ctx->priv; av_unused AVBufferSinkParams *params; if (!opaque) { av_log(ctx, AV_LOG_ERROR, "No opaque field provided\n"); return AVERROR(EINVAL); } else { #if FF_API_OLD_VSINK_API buf->pixel_fmts = (const enum PixelFormat *)opaque; #else params = (AVBufferSinkParams *)opaque; buf->pixel_fmts = params->pixel_fmts; #endif } return common_init(ctx); }


int ff_adts_write_frame_header(ADTSContext *ctx, uint8_t *buf, int size, int pce_size) { PutBitContext pb; init_put_bits(&pb, buf, ADTS_HEADER_SIZE); /* adts_fixed_header */ put_bits(&pb, 12, 0xfff); /* syncword */ put_bits(&pb, 1, 0); /* ID */ put_bits(&pb, 2, 0); /* layer */ put_bits(&pb, 1, 1); /* protection_absent */ put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */ put_bits(&pb, 4, ctx->sample_rate_index); put_bits(&pb, 1, 0); /* private_bit */ put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */ put_bits(&pb, 1, 0); /* original_copy */ put_bits(&pb, 1, 0); /* home */ /* adts_variable_header */ put_bits(&pb, 1, 0); /* copyright_identification_bit */ put_bits(&pb, 1, 0); /* copyright_identification_start */ put_bits(&pb, 13, ADTS_HEADER_SIZE + size + pce_size); /* aac_frame_length */ put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */ put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */ flush_put_bits(&pb); return 0; }


static int fbdev_read_packet(AVFormatContext *avctx, AVPacket *pkt) { FBDevContext *fbdev = avctx->priv_data; int64_t curtime, delay; struct timespec ts; int i, ret; uint8_t *pin, *pout; if (fbdev->time_frame == AV_NOPTS_VALUE) fbdev->time_frame = av_gettime(); /* wait based on the frame rate */ while (1) { curtime = av_gettime(); delay = fbdev->time_frame - curtime; av_dlog(avctx, "time_frame:%"PRId64" curtime:%"PRId64" delay:%"PRId64"\n", fbdev->time_frame, curtime, delay); if (delay <= 0) { fbdev->time_frame += INT64_C(1000000) * av_q2d(fbdev->time_base); break; } if (avctx->flags & AVFMT_FLAG_NONBLOCK) return AVERROR(EAGAIN); ts.tv_sec = delay / 1000000; ts.tv_nsec = (delay % 1000000) * 1000; while (nanosleep(&ts, &ts) == EINTR); } if ((ret = av_new_packet(pkt, fbdev->frame_size)) < 0) return ret; /* refresh fbdev->varinfo, visible data position may change at each call */ if (ioctl(fbdev->fd, FBIOGET_VSCREENINFO, &fbdev->varinfo) < 0) av_log(avctx, AV_LOG_WARNING, "Error refreshing variable info: %s\n", strerror(errno)); pkt->pts = curtime; /* compute visible data offset */ pin = fbdev->data + fbdev->bytes_per_pixel * fbdev->varinfo.xoffset + fbdev->varinfo.yoffset * fbdev->fixinfo.line_length; pout = pkt->data; for (i = 0; i < fbdev->heigth; i++) { memcpy(pout, pin, fbdev->frame_linesize); pin += fbdev->fixinfo.line_length; pout += fbdev->frame_linesize; } return fbdev->frame_size; }


static int virtio_ccw_set_guest_notifier(VirtioCcwDevice *dev, int n, bool assign, bool with_irqfd) { VirtIODevice *vdev = virtio_bus_get_device(&dev->bus); VirtQueue *vq = virtio_get_queue(vdev, n); EventNotifier *notifier = virtio_queue_get_guest_notifier(vq); VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); if (assign) { int r = event_notifier_init(notifier, 0); if (r < 0) { return r; } virtio_queue_set_guest_notifier_fd_handler(vq, true, with_irqfd); if (with_irqfd) { r = virtio_ccw_add_irqfd(dev, n); if (r) { virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); return r; } } /* * We do not support individual masking for channel devices, so we * need to manually trigger any guest masking callbacks here. */ if (k->guest_notifier_mask) { k->guest_notifier_mask(vdev, n, false); } /* get lost events and re-inject */ if (k->guest_notifier_pending && k->guest_notifier_pending(vdev, n)) { event_notifier_set(notifier); } } else { if (k->guest_notifier_mask) { k->guest_notifier_mask(vdev, n, true); } if (with_irqfd) { virtio_ccw_remove_irqfd(dev, n); } virtio_queue_set_guest_notifier_fd_handler(vq, false, with_irqfd); event_notifier_cleanup(notifier); } return 0; }


qemu_acl *qemu_acl_init(const char *aclname) { qemu_acl *acl; acl = qemu_acl_find(aclname); if (acl) return acl; acl = qemu_malloc(sizeof(*acl)); acl->aclname = qemu_strdup(aclname); /* Deny by default, so there is no window of "open * access" between QEMU starting, and the user setting * up ACLs in the monitor */ acl->defaultDeny = 1; acl->nentries = 0; TAILQ_INIT(&acl->entries); acls = qemu_realloc(acls, sizeof(*acls) * (nacls +1)); acls[nacls] = acl; nacls++; return acl; }


static void notdirty_mem_writew(void *opaque, target_phys_addr_t ram_addr, uint32_t val) { int dirty_flags; dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; if (!(dirty_flags & CODE_DIRTY_FLAG)) { #if !defined(CONFIG_USER_ONLY) tb_invalidate_phys_page_fast(ram_addr, 2); dirty_flags = phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS]; #endif } stw_p(qemu_get_ram_ptr(ram_addr), val); #ifdef CONFIG_KQEMU if (cpu_single_env->kqemu_enabled && (dirty_flags & KQEMU_MODIFY_PAGE_MASK) != KQEMU_MODIFY_PAGE_MASK) kqemu_modify_page(cpu_single_env, ram_addr); #endif dirty_flags |= (0xff & ~CODE_DIRTY_FLAG); phys_ram_dirty[ram_addr >> TARGET_PAGE_BITS] = dirty_flags; /* we remove the notdirty callback only if the code has been flushed */ if (dirty_flags == 0xff) tlb_set_dirty(cpu_single_env, cpu_single_env->mem_io_vaddr); }


static void aio_signal_handler(int signum) { if (posix_aio_state) { char byte = 0; write(posix_aio_state->wfd, &byte, sizeof(byte)); } qemu_service_io(); }


inline qemu_irq omap_inth_get_pin(struct omap_intr_handler_s *s, int n) { return s->pins[n]; }


static void realview_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) { CPUState *env; ram_addr_t ram_offset; DeviceState *dev; qemu_irq *irqp; qemu_irq pic[64]; PCIBus *pci_bus; NICInfo *nd; int n; int done_smc = 0; qemu_irq cpu_irq[4]; int ncpu; if (!cpu_model) cpu_model = "arm926"; /* FIXME: obey smp_cpus. */ if (strcmp(cpu_model, "arm11mpcore") == 0) { ncpu = 4; } else { ncpu = 1; } for (n = 0; n < ncpu; n++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } irqp = arm_pic_init_cpu(env); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; if (n > 0) { qemu_register_reset(secondary_cpu_reset, env); } } ram_offset = qemu_ram_alloc(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, 0xc1400400); if (ncpu == 1) { /* ??? The documentation says GIC1 is nFIQ and either GIC2 or GIC3 is nIRQ (there are inconsistencies). However Linux 2.6.17 expects GIC1 to be nIRQ and ignores all the others, so do that for now. */ dev = sysbus_create_simple("realview_gic", 0x10040000, cpu_irq[0]); } else { dev = sysbus_create_varargs("realview_mpcore", -1, cpu_irq[0], cpu_irq[1], cpu_irq[2], cpu_irq[3], NULL); } for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl011", 0x10009000, pic[12]); sysbus_create_simple("pl011", 0x1000a000, pic[13]); sysbus_create_simple("pl011", 0x1000b000, pic[14]); sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); sysbus_create_simple("pl110_versatile", 0x10020000, pic[23]); sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); sysbus_create_simple("pl031", 0x10017000, pic[10]); dev = sysbus_create_varargs("realview_pci", 0x60000000, pic[48], pic[49], pic[50], pic[51], NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); 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--; } for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if ((!nd->model && !done_smc) || strcmp(nd->model, "smc91c111") == 0) { smc91c111_init(nd, 0x4e000000, pic[28]); done_smc = 1; } else { pci_nic_init_nofail(nd, "rtl8139", NULL); } } /* Memory map for RealView Emulation Baseboard: */ /* 0x10000000 System registers. */ /* 0x10001000 System controller. */ /* 0x10002000 Two-Wire Serial Bus. */ /* 0x10003000 Reserved. */ /* 0x10004000 AACI. */ /* 0x10005000 MCI. */ /* 0x10006000 KMI0. */ /* 0x10007000 KMI1. */ /* 0x10008000 Character LCD. */ /* 0x10009000 UART0. */ /* 0x1000a000 UART1. */ /* 0x1000b000 UART2. */ /* 0x1000c000 UART3. */ /* 0x1000d000 SSPI. */ /* 0x1000e000 SCI. */ /* 0x1000f000 Reserved. */ /* 0x10010000 Watchdog. */ /* 0x10011000 Timer 0+1. */ /* 0x10012000 Timer 2+3. */ /* 0x10013000 GPIO 0. */ /* 0x10014000 GPIO 1. */ /* 0x10015000 GPIO 2. */ /* 0x10016000 Reserved. */ /* 0x10017000 RTC. */ /* 0x10018000 DMC. */ /* 0x10019000 PCI controller config. */ /* 0x10020000 CLCD. */ /* 0x10030000 DMA Controller. */ /* 0x10040000 GIC1. */ /* 0x10050000 GIC2. */ /* 0x10060000 GIC3. */ /* 0x10070000 GIC4. */ /* 0x10080000 SMC. */ /* 0x40000000 NOR flash. */ /* 0x44000000 DoC flash. */ /* 0x48000000 SRAM. */ /* 0x4c000000 Configuration flash. */ /* 0x4e000000 Ethernet. */ /* 0x4f000000 USB. */ /* 0x50000000 PISMO. */ /* 0x54000000 PISMO. */ /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ /* 0x61000000 PCI Self Config. */ /* 0x62000000 PCI Config. */ /* 0x63000000 PCI IO. */ /* 0x64000000 PCI mem 0. */ /* 0x68000000 PCI mem 1. */ /* 0x6c000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ ram_offset = qemu_ram_alloc(0x1000); cpu_register_physical_memory(0x80000000, 0x1000, ram_offset | IO_MEM_RAM); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = kernel_filename; realview_binfo.kernel_cmdline = kernel_cmdline; realview_binfo.initrd_filename = initrd_filename; realview_binfo.nb_cpus = ncpu; arm_load_kernel(first_cpu, &realview_binfo); }


static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt, int rs, int16_t imm) { if (ctx->CP0_Config1 & (1 << CP0C1_FP)) { check_cp1_enabled(ctx); gen_flt_ldst(ctx, op, rt, rs, imm); } else { generate_exception_err(ctx, EXCP_CpU, 1); } }


static IOMMUTLBEntry s390_translate_iommu(MemoryRegion *mr, hwaddr addr, bool is_write) { uint64_t pte; uint32_t flags; S390PCIIOMMU *iommu = container_of(mr, S390PCIIOMMU, iommu_mr); IOMMUTLBEntry ret = { .target_as = &address_space_memory, .iova = 0, .translated_addr = 0, .addr_mask = ~(hwaddr)0, .perm = IOMMU_NONE, }; switch (iommu->pbdev->state) { case ZPCI_FS_ENABLED: case ZPCI_FS_BLOCKED: if (!iommu->enabled) { return ret; } break; default: return ret; } DPRINTF("iommu trans addr 0x%" PRIx64 "\n", addr); if (addr < iommu->pba || addr > iommu->pal) { return ret; } pte = s390_guest_io_table_walk(s390_pci_get_table_origin(iommu->g_iota), addr); if (!pte) { return ret; } flags = pte & ZPCI_PTE_FLAG_MASK; ret.iova = addr; ret.translated_addr = pte & ZPCI_PTE_ADDR_MASK; ret.addr_mask = 0xfff; if (flags & ZPCI_PTE_INVALID) { ret.perm = IOMMU_NONE; } else { ret.perm = IOMMU_RW; } return ret; }


static void spr_write_dbatl (void *opaque, int sprn) { DisasContext *ctx = opaque; gen_op_store_dbatl((sprn - SPR_DBAT0L) / 2); RET_STOP(ctx); }


static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr) { VGACommonState *s = opaque; uint32_t val; val = s->vbe_index; return val; }


static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height) { const uint8_t *frame_start = frame; const uint8_t *frame_end = frame + width * height; int mask = 0x10000, bitbuf = 0; int i, v, offset, count, segments; segments = bytestream2_get_le16(gb); while (segments--) { if (bytestream2_get_bytes_left(gb) < 2) return -1; if (mask == 0x10000) { bitbuf = bytestream2_get_le16u(gb); mask = 1; } if (frame_end - frame < 2) return -1; if (bitbuf & mask) { v = bytestream2_get_le16(gb); offset = (v & 0x1FFF) << 2; count = ((v >> 13) + 2) << 1; if (frame - frame_start < offset || frame_end - frame < count*2 + width) return -1; for (i = 0; i < count; i++) { frame[0] = frame[1] = frame[width] = frame[width + 1] = frame[-offset]; frame += 2; } } else if (bitbuf & (mask << 1)) { frame += bytestream2_get_le16(gb) * 2; } else { frame[0] = frame[1] = frame[width] = frame[width + 1] = bytestream2_get_byte(gb); frame += 2; frame[0] = frame[1] = frame[width] = frame[width + 1] = bytestream2_get_byte(gb); frame += 2; } mask <<= 2; } return 0; }


static void netmap_update_fd_handler(NetmapState *s) { qemu_set_fd_handler2(s->me.fd, s->read_poll ? netmap_can_send : NULL, s->read_poll ? netmap_send : NULL, s->write_poll ? netmap_writable : NULL, s); }


static sPAPRDREntitySense logical_entity_sense(sPAPRDRConnector *drc) { if (drc->dev && (drc->allocation_state != SPAPR_DR_ALLOCATION_STATE_UNUSABLE)) { return SPAPR_DR_ENTITY_SENSE_PRESENT; } else { return SPAPR_DR_ENTITY_SENSE_UNUSABLE; } }


void x86_cpudef_setup(void) { int i, j; static const char *model_with_versions[] = { "qemu32", "qemu64", "athlon" }; for (i = 0; i < ARRAY_SIZE(builtin_x86_defs); ++i) { X86CPUDefinition *def = &builtin_x86_defs[i]; /* Look for specific "cpudef" models that */ /* have the QEMU version in .model_id */ for (j = 0; j < ARRAY_SIZE(model_with_versions); j++) { if (strcmp(model_with_versions[j], def->name) == 0) { pstrcpy(def->model_id, sizeof(def->model_id), "QEMU Virtual CPU version "); pstrcat(def->model_id, sizeof(def->model_id), qemu_get_version()); break; } } } }


static int scsi_read_dvd_structure(SCSIDiskState *s, SCSIDiskReq *r, uint8_t *outbuf) { static const int rds_caps_size[5] = { [0] = 2048 + 4, [1] = 4 + 4, [3] = 188 + 4, [4] = 2048 + 4, }; uint8_t media = r->req.cmd.buf[1]; uint8_t layer = r->req.cmd.buf[6]; uint8_t format = r->req.cmd.buf[7]; int size = -1; if (s->qdev.type != TYPE_ROM) { return -1; } if (media != 0) { scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); return -1; } if (format != 0xff) { if (s->tray_open || !bdrv_is_inserted(s->qdev.conf.bs)) { scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); return -1; } if (media_is_cd(s)) { scsi_check_condition(r, SENSE_CODE(INCOMPATIBLE_FORMAT)); return -1; } if (format >= ARRAY_SIZE(rds_caps_size)) { return -1; } size = rds_caps_size[format]; memset(outbuf, 0, size); } switch (format) { case 0x00: { /* Physical format information */ uint64_t nb_sectors; if (layer != 0) { goto fail; } bdrv_get_geometry(s->qdev.conf.bs, &nb_sectors); outbuf[4] = 1; /* DVD-ROM, part version 1 */ outbuf[5] = 0xf; /* 120mm disc, minimum rate unspecified */ outbuf[6] = 1; /* one layer, read-only (per MMC-2 spec) */ outbuf[7] = 0; /* default densities */ stl_be_p(&outbuf[12], (nb_sectors >> 2) - 1); /* end sector */ stl_be_p(&outbuf[16], (nb_sectors >> 2) - 1); /* l0 end sector */ break; } case 0x01: /* DVD copyright information, all zeros */ break; case 0x03: /* BCA information - invalid field for no BCA info */ return -1; case 0x04: /* DVD disc manufacturing information, all zeros */ break; case 0xff: { /* List capabilities */ int i; size = 4; for (i = 0; i < ARRAY_SIZE(rds_caps_size); i++) { if (!rds_caps_size[i]) { continue; } outbuf[size] = i; outbuf[size + 1] = 0x40; /* Not writable, readable */ stw_be_p(&outbuf[size + 2], rds_caps_size[i]); size += 4; } break; } default: return -1; } /* Size of buffer, not including 2 byte size field */ stw_be_p(outbuf, size - 2); return size; fail: return -1; }


START_TEST(qdict_get_not_exists_test) { fail_unless(qdict_get(tests_dict, "foo") == NULL); }


int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags) { BlockDriverState *bs; int ret; bs = bdrv_new(""); if (!bs) return -ENOMEM; ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL); if (ret < 0) { bdrv_delete(bs); return ret; } bs->growable = 1; *pbs = bs; return 0; }


size_t slirp_socket_can_recv(Slirp *slirp, struct in_addr guest_addr, int guest_port) { struct iovec iov[2]; struct socket *so; so = slirp_find_ctl_socket(slirp, guest_addr, guest_port); if (!so || so->so_state & SS_NOFDREF) return 0; if (!CONN_CANFRCV(so) || so->so_snd.sb_cc >= (so->so_snd.sb_datalen/2)) return 0; return sopreprbuf(so, iov, NULL); }


static void openpic_save(QEMUFile* f, void *opaque) { OpenPICState *opp = (OpenPICState *)opaque; unsigned int i; qemu_put_be32s(f, &opp->glbc); qemu_put_be32s(f, &opp->veni); qemu_put_be32s(f, &opp->pint); qemu_put_be32s(f, &opp->spve); qemu_put_be32s(f, &opp->tifr); for (i = 0; i < opp->max_irq; i++) { qemu_put_be32s(f, &opp->src[i].ipvp); qemu_put_be32s(f, &opp->src[i].ide); qemu_put_sbe32s(f, &opp->src[i].last_cpu); qemu_put_sbe32s(f, &opp->src[i].pending); } qemu_put_be32s(f, &opp->nb_cpus); for (i = 0; i < opp->nb_cpus; i++) { qemu_put_be32s(f, &opp->dst[i].pctp); qemu_put_be32s(f, &opp->dst[i].pcsr); openpic_save_IRQ_queue(f, &opp->dst[i].raised); openpic_save_IRQ_queue(f, &opp->dst[i].servicing); } for (i = 0; i < MAX_TMR; i++) { qemu_put_be32s(f, &opp->timers[i].ticc); qemu_put_be32s(f, &opp->timers[i].tibc); } }


static int ac3_parse_sync_info(AC3DecodeContext *ctx) { ac3_sync_info *sync_info = &ctx->sync_info; GetBitContext *gb = &ctx->gb; sync_info->sync_word = get_bits(gb, 16); sync_info->crc1 = get_bits(gb, 16); sync_info->fscod = get_bits(gb, 2); if (sync_info->fscod == 0x03) return -1; sync_info->frmsizecod = get_bits(gb, 6); if (sync_info->frmsizecod >= 0x38) return -1; sync_info->sampling_rate = ac3_freqs[sync_info->fscod]; sync_info->bit_rate = ac3_bitratetab[sync_info->frmsizecod >> 1]; return 0; }


static int curl_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVCURLState *s = bs->opaque; CURLState *state = NULL; QemuOpts *opts; Error *local_err = NULL; const char *file; double d; static int inited = 0; if (flags & BDRV_O_RDWR) { error_setg(errp, "curl block device does not support writes"); return -EROFS; } opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { error_propagate(errp, local_err); goto out_noclean; } s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE); if ((s->readahead_size & 0x1ff) != 0) { error_setg(errp, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512", s->readahead_size); goto out_noclean; } file = qemu_opt_get(opts, "url"); if (file == NULL) { error_setg(errp, "curl block driver requires an 'url' option"); goto out_noclean; } if (!inited) { curl_global_init(CURL_GLOBAL_ALL); inited = 1; } DPRINTF("CURL: Opening %s\n", file); s->url = g_strdup(file); state = curl_init_state(s); if (!state) goto out_noclean; // Get file size s->accept_range = false; curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1); curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION, curl_header_cb); curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s); if (curl_easy_perform(state->curl)) goto out; curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d); if (d) s->len = (size_t)d; else if(!s->len) goto out; if ((!strncasecmp(s->url, "http://", strlen("http://")) || !strncasecmp(s->url, "https://", strlen("https://"))) && !s->accept_range) { pstrcpy(state->errmsg, CURL_ERROR_SIZE, "Server does not support 'range' (byte ranges)."); goto out; } DPRINTF("CURL: Size = %zd\n", s->len); curl_clean_state(state); curl_easy_cleanup(state->curl); state->curl = NULL; aio_timer_init(bdrv_get_aio_context(bs), &s->timer, QEMU_CLOCK_REALTIME, SCALE_NS, curl_multi_timeout_do, s); // Now we know the file exists and its size, so let's // initialize the multi interface! s->multi = curl_multi_init(); curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s); curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb); #ifdef NEED_CURL_TIMER_CALLBACK curl_multi_setopt(s->multi, CURLMOPT_TIMERDATA, s); curl_multi_setopt(s->multi, CURLMOPT_TIMERFUNCTION, curl_timer_cb); #endif qemu_opts_del(opts); return 0; out: error_setg(errp, "CURL: Error opening file: %s", state->errmsg); curl_easy_cleanup(state->curl); state->curl = NULL; out_noclean: g_free(s->url); qemu_opts_del(opts); return -EINVAL; }


static int raw_truncate(BlockDriverState *bs, int64_t offset) { BDRVRawState *s = bs->opaque; LONG low, high; low = offset; high = offset >> 32; if (!SetFilePointer(s->hfile, low, &high, FILE_BEGIN)) return -EIO; if (!SetEndOfFile(s->hfile)) return -EIO; return 0; }


static bool tb_invalidate_phys_page(tb_page_addr_t addr, uintptr_t pc) { TranslationBlock *tb; PageDesc *p; int n; #ifdef TARGET_HAS_PRECISE_SMC TranslationBlock *current_tb = NULL; CPUState *cpu = current_cpu; CPUArchState *env = NULL; int current_tb_modified = 0; target_ulong current_pc = 0; target_ulong current_cs_base = 0; uint32_t current_flags = 0; #endif assert_memory_lock(); addr &= TARGET_PAGE_MASK; p = page_find(addr >> TARGET_PAGE_BITS); if (!p) { return false; } tb_lock(); tb = p->first_tb; #ifdef TARGET_HAS_PRECISE_SMC if (tb && pc != 0) { current_tb = tb_find_pc(pc); } if (cpu != NULL) { env = cpu->env_ptr; } #endif while (tb != NULL) { n = (uintptr_t)tb & 3; tb = (TranslationBlock *)((uintptr_t)tb & ~3); #ifdef TARGET_HAS_PRECISE_SMC if (current_tb == tb && (current_tb->cflags & CF_COUNT_MASK) != 1) { /* If we are modifying the current TB, we must stop its execution. We could be more precise by checking that the modification is after the current PC, but it would require a specialized function to partially restore the CPU state */ current_tb_modified = 1; cpu_restore_state_from_tb(cpu, current_tb, pc); cpu_get_tb_cpu_state(env, &current_pc, &current_cs_base, &current_flags); } #endif /* TARGET_HAS_PRECISE_SMC */ tb_phys_invalidate(tb, addr); tb = tb->page_next[n]; } p->first_tb = NULL; #ifdef TARGET_HAS_PRECISE_SMC if (current_tb_modified) { /* we generate a block containing just the instruction modifying the memory. It will ensure that it cannot modify itself */ tb_gen_code(cpu, current_pc, current_cs_base, current_flags, 1 | curr_cflags()); /* tb_lock will be reset after cpu_loop_exit_noexc longjmps * back into the cpu_exec loop. */ return true; } #endif tb_unlock(); return false; }


static int64_t raw_getlength(BlockDriverState *bs) { int64_t len; BDRVRawState *s = bs->opaque; /* Update size. It should not change unless the file was externally * modified. */ len = bdrv_getlength(bs->file->bs); if (len < 0) { return len; } if (len < s->offset) { s->size = 0; } else { if (s->has_size) { /* Try to honour the size */ s->size = MIN(s->size, len - s->offset); } else { s->size = len - s->offset; } } return s->size; }


void omap_rfbi_attach(struct omap_dss_s *s, int cs, struct rfbi_chip_s *chip) { if (cs < 0 || cs > 1) hw_error("%s: wrong CS %i\n", __FUNCTION__, cs); s->rfbi.chip[cs] = chip; }


int kvm_arch_init(MachineState *ms, KVMState *s) { MachineClass *mc = MACHINE_GET_CLASS(ms); mc->default_cpu_type = S390_CPU_TYPE_NAME("host"); cap_sync_regs = kvm_check_extension(s, KVM_CAP_SYNC_REGS); cap_async_pf = kvm_check_extension(s, KVM_CAP_ASYNC_PF); cap_mem_op = kvm_check_extension(s, KVM_CAP_S390_MEM_OP); cap_s390_irq = kvm_check_extension(s, KVM_CAP_S390_INJECT_IRQ); if (!kvm_check_extension(s, KVM_CAP_S390_GMAP) || !kvm_check_extension(s, KVM_CAP_S390_COW)) { phys_mem_set_alloc(legacy_s390_alloc); } kvm_vm_enable_cap(s, KVM_CAP_S390_USER_SIGP, 0); kvm_vm_enable_cap(s, KVM_CAP_S390_VECTOR_REGISTERS, 0); kvm_vm_enable_cap(s, KVM_CAP_S390_USER_STSI, 0); if (ri_allowed()) { if (kvm_vm_enable_cap(s, KVM_CAP_S390_RI, 0) == 0) { cap_ri = 1; } } if (gs_allowed()) { if (kvm_vm_enable_cap(s, KVM_CAP_S390_GS, 0) == 0) { cap_gs = 1; } } /* * The migration interface for ais was introduced with kernel 4.13 * but the capability itself had been active since 4.12. As migration * support is considered necessary let's disable ais in the 2.10 * machine. */ /* kvm_vm_enable_cap(s, KVM_CAP_S390_AIS, 0); */ qemu_mutex_init(&qemu_sigp_mutex); return 0; }


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


int mmu_translate(CPUS390XState *env, target_ulong vaddr, int rw, uint64_t asc, target_ulong *raddr, int *flags, bool exc) { int r = -1; uint8_t *sk; *flags = PAGE_READ | PAGE_WRITE | PAGE_EXEC; vaddr &= TARGET_PAGE_MASK; if (!(env->psw.mask & PSW_MASK_DAT)) { *raddr = vaddr; r = 0; goto out; } switch (asc) { case PSW_ASC_PRIMARY: PTE_DPRINTF("%s: asc=primary\n", __func__); r = mmu_translate_asce(env, vaddr, asc, env->cregs[1], raddr, flags, rw, exc); break; case PSW_ASC_HOME: PTE_DPRINTF("%s: asc=home\n", __func__); r = mmu_translate_asce(env, vaddr, asc, env->cregs[13], raddr, flags, rw, exc); break; case PSW_ASC_SECONDARY: PTE_DPRINTF("%s: asc=secondary\n", __func__); /* * Instruction: Primary * Data: Secondary */ if (rw == MMU_INST_FETCH) { r = mmu_translate_asce(env, vaddr, PSW_ASC_PRIMARY, env->cregs[1], raddr, flags, rw, exc); *flags &= ~(PAGE_READ | PAGE_WRITE); } else { r = mmu_translate_asce(env, vaddr, PSW_ASC_SECONDARY, env->cregs[7], raddr, flags, rw, exc); *flags &= ~(PAGE_EXEC); } break; case PSW_ASC_ACCREG: default: hw_error("guest switched to unknown asc mode\n"); break; } out: /* Convert real address -> absolute address */ *raddr = mmu_real2abs(env, *raddr); if (*raddr <= ram_size) { sk = &env->storage_keys[*raddr / TARGET_PAGE_SIZE]; if (*flags & PAGE_READ) { *sk |= SK_R; } if (*flags & PAGE_WRITE) { *sk |= SK_C; } } return r; }


static void adb_mouse_initfn(Object *obj) { ADBDevice *d = ADB_DEVICE(obj); d->devaddr = ADB_DEVID_MOUSE; }


int ff_raw_read_header(AVFormatContext *s, AVFormatParameters *ap) { AVStream *st; enum CodecID id; st = avformat_new_stream(s, NULL); if (!st) return AVERROR(ENOMEM); id = s->iformat->value; if (id == CODEC_ID_RAWVIDEO) { st->codec->codec_type = AVMEDIA_TYPE_VIDEO; } else { st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = id; switch(st->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: { RawAudioDemuxerContext *s1 = s->priv_data; st->codec->channels = 1; if (id == CODEC_ID_ADPCM_G722) st->codec->sample_rate = 16000; if (s1 && s1->sample_rate) st->codec->sample_rate = s1->sample_rate; if (s1 && s1->channels) st->codec->channels = s1->channels; st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); assert(st->codec->bits_per_coded_sample > 0); st->codec->block_align = st->codec->bits_per_coded_sample*st->codec->channels/8; av_set_pts_info(st, 64, 1, st->codec->sample_rate); break; case AVMEDIA_TYPE_VIDEO: { FFRawVideoDemuxerContext *s1 = s->priv_data; int width = 0, height = 0, ret = 0; enum PixelFormat pix_fmt; AVRational framerate; if (s1->video_size && (ret = av_parse_video_size(&width, &height, s1->video_size)) < 0) { av_log(s, AV_LOG_ERROR, "Couldn't parse video size.\n"); goto fail; if ((pix_fmt = av_get_pix_fmt(s1->pixel_format)) == PIX_FMT_NONE) { av_log(s, AV_LOG_ERROR, "No such pixel format: %s.\n", s1->pixel_format); ret = AVERROR(EINVAL); goto fail; if ((ret = av_parse_video_rate(&framerate, s1->framerate)) < 0) { av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate); goto fail; av_set_pts_info(st, 64, framerate.den, framerate.num); st->codec->width = width; st->codec->height = height; st->codec->pix_fmt = pix_fmt; fail: return ret; default: return -1; return 0;


e1000_mmio_map(PCIDevice *pci_dev, int region_num, uint32_t addr, uint32_t size, int type) { E1000State *d = (E1000State *)pci_dev; DBGOUT(MMIO, "e1000_mmio_map addr=0x%08x 0x%08x\n", addr, size); cpu_register_physical_memory(addr, PNPMMIO_SIZE, d->mmio_index); }


static av_cold int decode_init(AVCodecContext *avctx) { WMAProDecodeCtx *s = avctx->priv_data; uint8_t *edata_ptr = avctx->extradata; unsigned int channel_mask; int i, bits; int log2_max_num_subframes; int num_possible_block_sizes; if (avctx->codec_id == AV_CODEC_ID_XMA1 || avctx->codec_id == AV_CODEC_ID_XMA2) avctx->block_align = 2048; if (!avctx->block_align) { av_log(avctx, AV_LOG_ERROR, "block_align is not set\n"); return AVERROR(EINVAL); } s->avctx = avctx; s->fdsp = avpriv_float_dsp_alloc(avctx->flags & AV_CODEC_FLAG_BITEXACT); if (!s->fdsp) return AVERROR(ENOMEM); init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; if (avctx->codec_id == AV_CODEC_ID_XMA2 && avctx->extradata_size >= 34) { s->decode_flags = 0x10d6; channel_mask = AV_RL32(edata_ptr+2); s->bits_per_sample = 16; /** dump the extradata */ for (i = 0; i < avctx->extradata_size; i++) ff_dlog(avctx, "[%x] ", avctx->extradata[i]); ff_dlog(avctx, "\n"); } else if (avctx->codec_id == AV_CODEC_ID_XMA1 && avctx->extradata_size >= 28) { s->decode_flags = 0x10d6; s->bits_per_sample = 16; channel_mask = 0; /** dump the extradata */ for (i = 0; i < avctx->extradata_size; i++) ff_dlog(avctx, "[%x] ", avctx->extradata[i]); ff_dlog(avctx, "\n"); } else if (avctx->extradata_size >= 18) { s->decode_flags = AV_RL16(edata_ptr+14); channel_mask = AV_RL32(edata_ptr+2); s->bits_per_sample = AV_RL16(edata_ptr); /** dump the extradata */ for (i = 0; i < avctx->extradata_size; i++) ff_dlog(avctx, "[%x] ", avctx->extradata[i]); ff_dlog(avctx, "\n"); } else { avpriv_request_sample(avctx, "Unknown extradata size"); return AVERROR_PATCHWELCOME; } if (avctx->codec_id != AV_CODEC_ID_WMAPRO && avctx->channels > 2) { avpriv_report_missing_feature(avctx, ">2 channels support"); return AVERROR_PATCHWELCOME; } /** generic init */ s->log2_frame_size = av_log2(avctx->block_align) + 4; if (s->log2_frame_size > 25) { avpriv_request_sample(avctx, "Large block align"); return AVERROR_PATCHWELCOME; } /** frame info */ if (avctx->codec_id != AV_CODEC_ID_WMAPRO) s->skip_frame = 0; else s->skip_frame = 1; /* skip first frame */ s->packet_loss = 1; s->len_prefix = (s->decode_flags & 0x40); /** get frame len */ if (avctx->codec_id == AV_CODEC_ID_WMAPRO) { bits = ff_wma_get_frame_len_bits(avctx->sample_rate, 3, s->decode_flags); if (bits > WMAPRO_BLOCK_MAX_BITS) { avpriv_request_sample(avctx, "14-bit block sizes"); return AVERROR_PATCHWELCOME; } s->samples_per_frame = 1 << bits; } else { s->samples_per_frame = 512; } /** subframe info */ log2_max_num_subframes = ((s->decode_flags & 0x38) >> 3); s->max_num_subframes = 1 << log2_max_num_subframes; if (s->max_num_subframes == 16 || s->max_num_subframes == 4) s->max_subframe_len_bit = 1; s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1; num_possible_block_sizes = log2_max_num_subframes + 1; s->min_samples_per_subframe = s->samples_per_frame / s->max_num_subframes; s->dynamic_range_compression = (s->decode_flags & 0x80); if (s->max_num_subframes > MAX_SUBFRAMES) { av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %"PRId8"\n", s->max_num_subframes); return AVERROR_INVALIDDATA; } if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) { av_log(avctx, AV_LOG_ERROR, "min_samples_per_subframe of %d too small\n", s->min_samples_per_subframe); return AVERROR_INVALIDDATA; } if (s->avctx->sample_rate <= 0) { av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); return AVERROR_INVALIDDATA; } if (avctx->channels < 0) { av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", avctx->channels); return AVERROR_INVALIDDATA; } else if (avctx->channels > WMAPRO_MAX_CHANNELS) { avpriv_request_sample(avctx, "More than %d channels", WMAPRO_MAX_CHANNELS); return AVERROR_PATCHWELCOME; } /** init previous block len */ for (i = 0; i < avctx->channels; i++) s->channel[i].prev_block_len = s->samples_per_frame; /** extract lfe channel position */ s->lfe_channel = -1; if (channel_mask & 8) { unsigned int mask; for (mask = 1; mask < 16; mask <<= 1) { if (channel_mask & mask) ++s->lfe_channel; } } INIT_VLC_STATIC(&sf_vlc, SCALEVLCBITS, HUFF_SCALE_SIZE, scale_huffbits, 1, 1, scale_huffcodes, 2, 2, 616); INIT_VLC_STATIC(&sf_rl_vlc, VLCBITS, HUFF_SCALE_RL_SIZE, scale_rl_huffbits, 1, 1, scale_rl_huffcodes, 4, 4, 1406); INIT_VLC_STATIC(&coef_vlc[0], VLCBITS, HUFF_COEF0_SIZE, coef0_huffbits, 1, 1, coef0_huffcodes, 4, 4, 2108); INIT_VLC_STATIC(&coef_vlc[1], VLCBITS, HUFF_COEF1_SIZE, coef1_huffbits, 1, 1, coef1_huffcodes, 4, 4, 3912); INIT_VLC_STATIC(&vec4_vlc, VLCBITS, HUFF_VEC4_SIZE, vec4_huffbits, 1, 1, vec4_huffcodes, 2, 2, 604); INIT_VLC_STATIC(&vec2_vlc, VLCBITS, HUFF_VEC2_SIZE, vec2_huffbits, 1, 1, vec2_huffcodes, 2, 2, 562); INIT_VLC_STATIC(&vec1_vlc, VLCBITS, HUFF_VEC1_SIZE, vec1_huffbits, 1, 1, vec1_huffcodes, 2, 2, 562); /** calculate number of scale factor bands and their offsets for every possible block size */ for (i = 0; i < num_possible_block_sizes; i++) { int subframe_len = s->samples_per_frame >> i; int x; int band = 1; int rate = get_rate(avctx); s->sfb_offsets[i][0] = 0; for (x = 0; x < MAX_BANDS-1 && s->sfb_offsets[i][band - 1] < subframe_len; x++) { int offset = (subframe_len * 2 * critical_freq[x]) / rate + 2; offset &= ~3; if (offset > s->sfb_offsets[i][band - 1]) s->sfb_offsets[i][band++] = offset; if (offset >= subframe_len) break; } s->sfb_offsets[i][band - 1] = subframe_len; s->num_sfb[i] = band - 1; if (s->num_sfb[i] <= 0) { av_log(avctx, AV_LOG_ERROR, "num_sfb invalid\n"); return AVERROR_INVALIDDATA; } } /** Scale factors can be shared between blocks of different size as every block has a different scale factor band layout. The matrix sf_offsets is needed to find the correct scale factor. */ for (i = 0; i < num_possible_block_sizes; i++) { int b; for (b = 0; b < s->num_sfb[i]; b++) { int x; int offset = ((s->sfb_offsets[i][b] + s->sfb_offsets[i][b + 1] - 1) << i) >> 1; for (x = 0; x < num_possible_block_sizes; x++) { int v = 0; while (s->sfb_offsets[x][v + 1] << x < offset) { v++; av_assert0(v < MAX_BANDS); } s->sf_offsets[i][x][b] = v; } } } /** init MDCT, FIXME: only init needed sizes */ for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) ff_mdct_init(&s->mdct_ctx[i], WMAPRO_BLOCK_MIN_BITS+1+i, 1, 1.0 / (1 << (WMAPRO_BLOCK_MIN_BITS + i - 1)) / (1 << (s->bits_per_sample - 1))); /** init MDCT windows: simple sine window */ for (i = 0; i < WMAPRO_BLOCK_SIZES; i++) { const int win_idx = WMAPRO_BLOCK_MAX_BITS - i; ff_init_ff_sine_windows(win_idx); s->windows[WMAPRO_BLOCK_SIZES - i - 1] = ff_sine_windows[win_idx]; } /** calculate subwoofer cutoff values */ for (i = 0; i < num_possible_block_sizes; i++) { int block_size = s->samples_per_frame >> i; int cutoff = (440*block_size + 3 * (s->avctx->sample_rate >> 1) - 1) / s->avctx->sample_rate; s->subwoofer_cutoffs[i] = av_clip(cutoff, 4, block_size); } /** calculate sine values for the decorrelation matrix */ for (i = 0; i < 33; i++) sin64[i] = sin(i*M_PI / 64.0); if (avctx->debug & FF_DEBUG_BITSTREAM) dump_context(s); avctx->channel_layout = channel_mask; return 0; }


static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, uint64_t *new_offset) { *new_offset = bdrv_getlength(bs->file->bs); /* per the spec, the address for a block is in units of 1MB */ *new_offset = ROUND_UP(*new_offset, 1024 * 1024); return bdrv_truncate(bs->file, *new_offset + s->block_size, PREALLOC_MODE_OFF, NULL); }


POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER7"; dc->desc = "POWER7"; pcc->pvr = CPU_POWERPC_POWER7_BASE; pcc->pvr_mask = CPU_POWERPC_POWER7_MASK; pcc->init_proc = init_proc_POWER7; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD; pcc->insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205 | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_VR) | (1ull << MSR_VSX) | (1ull << MSR_EE) | (1ull << MSR_PR) | (1ull << MSR_FP) | (1ull << MSR_ME) | (1ull << MSR_FE0) | (1ull << MSR_SE) | (1ull << MSR_DE) | (1ull << MSR_FE1) | (1ull << MSR_IR) | (1ull << MSR_DR) | (1ull << MSR_PMM) | (1ull << MSR_RI) | (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_2_06; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; #endif pcc->excp_model = POWERPC_EXCP_POWER7; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | POWERPC_FLAG_VSX; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; }


static int parse_metadata_ext(DBEContext *s) { if (s->mtd_ext_size) skip_input(s, s->key_present + s->mtd_ext_size + 1); return 0; }


static void test_validate_fail_union_flat(TestInputVisitorData *data, const void *unused) { UserDefFlatUnion *tmp = NULL; Error *err = NULL; Visitor *v; v = validate_test_init(data, "{ 'string': 'c', 'integer': 41, 'boolean': true }"); visit_type_UserDefFlatUnion(v, &tmp, NULL, &err); g_assert(err); qapi_free_UserDefFlatUnion(tmp); }


static int net_slirp_init(VLANState *vlan, const char *model, const char *name) { if (!slirp_inited) { slirp_inited = 1; slirp_init(slirp_restrict, slirp_ip); } slirp_vc = qemu_new_vlan_client(vlan, model, name, slirp_receive, NULL, NULL); slirp_vc->info_str[0] = '\0'; return 0; }


static int adb_mouse_poll(ADBDevice *d, uint8_t *obuf) { MouseState *s = ADB_MOUSE(d); int dx, dy; if (s->last_buttons_state == s->buttons_state && s->dx == 0 && s->dy == 0) return 0; dx = s->dx; if (dx < -63) dx = -63; else if (dx > 63) dx = 63; dy = s->dy; if (dy < -63) dy = -63; else if (dy > 63) dy = 63; s->dx -= dx; s->dy -= dy; s->last_buttons_state = s->buttons_state; dx &= 0x7f; dy &= 0x7f; if (!(s->buttons_state & MOUSE_EVENT_LBUTTON)) dy |= 0x80; if (!(s->buttons_state & MOUSE_EVENT_RBUTTON)) dx |= 0x80; obuf[0] = dy; obuf[1] = dx; return 2; }


hwaddr ppc_cpu_get_phys_page_debug(CPUState *cs, vaddr addr) { PowerPCCPU *cpu = POWERPC_CPU(cs); CPUPPCState *env = &cpu->env; mmu_ctx_t ctx; switch (env->mmu_model) { #if defined(TARGET_PPC64) case POWERPC_MMU_64B: case POWERPC_MMU_2_03: case POWERPC_MMU_2_06: case POWERPC_MMU_2_07: return ppc_hash64_get_phys_page_debug(env, addr); #endif case POWERPC_MMU_32B: case POWERPC_MMU_601: return ppc_hash32_get_phys_page_debug(env, addr); default: ; } if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_INT) != 0)) { /* Some MMUs have separate TLBs for code and data. If we only try an * ACCESS_INT, we may not be able to read instructions mapped by code * TLBs, so we also try a ACCESS_CODE. */ if (unlikely(get_physical_address(env, &ctx, addr, 0, ACCESS_CODE) != 0)) { return -1; } } return ctx.raddr & TARGET_PAGE_MASK; }


static int get_physical_address_data(CPUState *env, target_phys_addr_t *physical, int *prot, target_ulong address, int rw, int mmu_idx) { unsigned int i; uint64_t context; int is_user = (mmu_idx == MMU_USER_IDX || mmu_idx == MMU_USER_SECONDARY_IDX); if ((env->lsu & DMMU_E) == 0) { /* DMMU disabled */ *physical = ultrasparc_truncate_physical(address); *prot = PAGE_READ | PAGE_WRITE; return 0; } switch(mmu_idx) { case MMU_USER_IDX: case MMU_KERNEL_IDX: context = env->dmmu.mmu_primary_context & 0x1fff; break; case MMU_USER_SECONDARY_IDX: case MMU_KERNEL_SECONDARY_IDX: context = env->dmmu.mmu_secondary_context & 0x1fff; break; case MMU_NUCLEUS_IDX: context = 0; break; } for (i = 0; i < 64; i++) { // ctx match, vaddr match, valid? if (ultrasparc_tag_match(&env->dtlb[i], address, context, physical)) { // access ok? if (((env->dtlb[i].tte & 0x4) && is_user) || (!(env->dtlb[i].tte & 0x2) && (rw == 1))) { uint8_t fault_type = 0; if ((env->dtlb[i].tte & 0x4) && is_user) { fault_type |= 1; /* privilege violation */ } if (env->dmmu.sfsr & 1) /* Fault status register */ env->dmmu.sfsr = 2; /* overflow (not read before another fault) */ env->dmmu.sfsr |= (is_user << 3) | ((rw == 1) << 2) | 1; env->dmmu.sfsr |= (fault_type << 7); env->dmmu.sfar = address; /* Fault address register */ env->exception_index = TT_DFAULT; #ifdef DEBUG_MMU printf("DFAULT at 0x%" PRIx64 "\n", address); #endif return 1; } *prot = PAGE_READ; if (env->dtlb[i].tte & 0x2) *prot |= PAGE_WRITE; TTE_SET_USED(env->dtlb[i].tte); return 0; } } #ifdef DEBUG_MMU printf("DMISS at 0x%" PRIx64 "\n", address); #endif env->dmmu.tag_access = (address & ~0x1fffULL) | context; env->exception_index = TT_DMISS; return 1; }


static void virtio_pci_reset(DeviceState *qdev) { VirtIOPCIProxy *proxy = VIRTIO_PCI(qdev); VirtioBusState *bus = VIRTIO_BUS(&proxy->bus); int i; virtio_pci_stop_ioeventfd(proxy); virtio_bus_reset(bus); msix_unuse_all_vectors(&proxy->pci_dev); for (i = 0; i < VIRTIO_QUEUE_MAX; i++) { proxy->vqs[i].enabled = 0; } }


static int decode_residual(const H264Context *h, H264SliceContext *sl, GetBitContext *gb, int16_t *block, int n, const uint8_t *scantable, const uint32_t *qmul, int max_coeff) { static const int coeff_token_table_index[17]= {0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3}; int level[16]; int zeros_left, coeff_token, total_coeff, i, trailing_ones, run_before; //FIXME put trailing_onex into the context if(max_coeff <= 8){ if (max_coeff == 4) coeff_token = get_vlc2(gb, chroma_dc_coeff_token_vlc.table, CHROMA_DC_COEFF_TOKEN_VLC_BITS, 1); else coeff_token = get_vlc2(gb, chroma422_dc_coeff_token_vlc.table, CHROMA422_DC_COEFF_TOKEN_VLC_BITS, 1); total_coeff= coeff_token>>2; }else{ if(n >= LUMA_DC_BLOCK_INDEX){ total_coeff= pred_non_zero_count(h, sl, (n - LUMA_DC_BLOCK_INDEX)*16); coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2); total_coeff= coeff_token>>2; }else{ total_coeff= pred_non_zero_count(h, sl, n); coeff_token= get_vlc2(gb, coeff_token_vlc[ coeff_token_table_index[total_coeff] ].table, COEFF_TOKEN_VLC_BITS, 2); total_coeff= coeff_token>>2; } } sl->non_zero_count_cache[scan8[n]] = total_coeff; //FIXME set last_non_zero? if(total_coeff==0) return 0; if(total_coeff > (unsigned)max_coeff) { av_log(h->avctx, AV_LOG_ERROR, "corrupted macroblock %d %d (total_coeff=%d)\n", sl->mb_x, sl->mb_y, total_coeff); return -1; } trailing_ones= coeff_token&3; ff_tlog(h->avctx, "trailing:%d, total:%d\n", trailing_ones, total_coeff); assert(total_coeff<=16); i = show_bits(gb, 3); skip_bits(gb, trailing_ones); level[0] = 1-((i&4)>>1); level[1] = 1-((i&2) ); level[2] = 1-((i&1)<<1); if(trailing_ones<total_coeff) { int mask, prefix; int suffix_length = total_coeff > 10 & trailing_ones < 3; int bitsi= show_bits(gb, LEVEL_TAB_BITS); int level_code= cavlc_level_tab[suffix_length][bitsi][0]; skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]); if(level_code >= 100){ prefix= level_code - 100; if(prefix == LEVEL_TAB_BITS) prefix += get_level_prefix(gb); //first coefficient has suffix_length equal to 0 or 1 if(prefix<14){ //FIXME try to build a large unified VLC table for all this if(suffix_length) level_code= (prefix<<1) + get_bits1(gb); //part else level_code= prefix; //part }else if(prefix==14){ if(suffix_length) level_code= (prefix<<1) + get_bits1(gb); //part else level_code= prefix + get_bits(gb, 4); //part }else{ level_code= 30 + get_bits(gb, prefix-3); //part if(prefix>=16){ if(prefix > 25+3){ av_log(h->avctx, AV_LOG_ERROR, "Invalid level prefix\n"); return -1; } level_code += (1<<(prefix-3))-4096; } } if(trailing_ones < 3) level_code += 2; suffix_length = 2; mask= -(level_code&1); level[trailing_ones]= (((2+level_code)>>1) ^ mask) - mask; }else{ level_code += ((level_code>>31)|1) & -(trailing_ones < 3); suffix_length = 1 + (level_code + 3U > 6U); level[trailing_ones]= level_code; } //remaining coefficients have suffix_length > 0 for(i=trailing_ones+1;i<total_coeff;i++) { static const unsigned int suffix_limit[7] = {0,3,6,12,24,48,INT_MAX }; int bitsi= show_bits(gb, LEVEL_TAB_BITS); level_code= cavlc_level_tab[suffix_length][bitsi][0]; skip_bits(gb, cavlc_level_tab[suffix_length][bitsi][1]); if(level_code >= 100){ prefix= level_code - 100; if(prefix == LEVEL_TAB_BITS){ prefix += get_level_prefix(gb); } if(prefix<15){ level_code = (prefix<<suffix_length) + get_bits(gb, suffix_length); }else{ level_code = (15<<suffix_length) + get_bits(gb, prefix-3); if(prefix>=16) level_code += (1<<(prefix-3))-4096; } mask= -(level_code&1); level_code= (((2+level_code)>>1) ^ mask) - mask; } level[i]= level_code; suffix_length+= suffix_limit[suffix_length] + level_code > 2U*suffix_limit[suffix_length]; } } if(total_coeff == max_coeff) zeros_left=0; else{ if (max_coeff <= 8) { if (max_coeff == 4) zeros_left = get_vlc2(gb, chroma_dc_total_zeros_vlc[total_coeff - 1].table, CHROMA_DC_TOTAL_ZEROS_VLC_BITS, 1); else zeros_left = get_vlc2(gb, chroma422_dc_total_zeros_vlc[total_coeff - 1].table, CHROMA422_DC_TOTAL_ZEROS_VLC_BITS, 1); } else { zeros_left= get_vlc2(gb, total_zeros_vlc[total_coeff - 1].table, TOTAL_ZEROS_VLC_BITS, 1); } } #define STORE_BLOCK(type) \ scantable += zeros_left + total_coeff - 1; \ if(n >= LUMA_DC_BLOCK_INDEX){ \ ((type*)block)[*scantable] = level[0]; \ for(i=1;i<total_coeff && zeros_left > 0;i++) { \ if(zeros_left < 7) \ run_before= get_vlc2(gb, run_vlc[zeros_left - 1].table, RUN_VLC_BITS, 1); \ else \ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \ zeros_left -= run_before; \ scantable -= 1 + run_before; \ ((type*)block)[*scantable]= level[i]; \ } \ for(;i<total_coeff;i++) { \ scantable--; \ ((type*)block)[*scantable]= level[i]; \ } \ }else{ \ ((type*)block)[*scantable] = ((int)(level[0] * qmul[*scantable] + 32))>>6; \ for(i=1;i<total_coeff && zeros_left > 0;i++) { \ if(zeros_left < 7) \ run_before= get_vlc2(gb, run_vlc[zeros_left - 1].table, RUN_VLC_BITS, 1); \ else \ run_before= get_vlc2(gb, run7_vlc.table, RUN7_VLC_BITS, 2); \ zeros_left -= run_before; \ scantable -= 1 + run_before; \ ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \ } \ for(;i<total_coeff;i++) { \ scantable--; \ ((type*)block)[*scantable]= ((int)(level[i] * qmul[*scantable] + 32))>>6; \ } \ } if (zeros_left < 0) { av_log(h->avctx, AV_LOG_ERROR, "negative number of zero coeffs at %d %d\n", sl->mb_x, sl->mb_y); return AVERROR_INVALIDDATA; } if (h->pixel_shift) { STORE_BLOCK(int32_t) } else { STORE_BLOCK(int16_t) } return 0; }


DISAS_INSN(fsave) { /* TODO: Implement fsave. */ qemu_assert(0, "FSAVE not implemented"); }


static int tap_alloc(char *dev, size_t dev_size) { int tap_fd, if_fd, ppa = -1; static int ip_fd = 0; char *ptr; static int arp_fd = 0; int ip_muxid, arp_muxid; struct strioctl strioc_if, strioc_ppa; int link_type = I_PLINK; struct lifreq ifr; char actual_name[32] = ""; memset(&ifr, 0x0, sizeof(ifr)); if( *dev ){ ptr = dev; while( *ptr && !qemu_isdigit((int)*ptr) ) ptr++; ppa = atoi(ptr); } /* Check if IP device was opened */ if( ip_fd ) close(ip_fd); TFR(ip_fd = open("/dev/udp", O_RDWR, 0)); if (ip_fd < 0) { syslog(LOG_ERR, "Can't open /dev/ip (actually /dev/udp)"); return -1; } TFR(tap_fd = open("/dev/tap", O_RDWR, 0)); if (tap_fd < 0) { syslog(LOG_ERR, "Can't open /dev/tap"); return -1; } /* Assign a new PPA and get its unit number. */ strioc_ppa.ic_cmd = TUNNEWPPA; strioc_ppa.ic_timout = 0; strioc_ppa.ic_len = sizeof(ppa); strioc_ppa.ic_dp = (char *)&ppa; if ((ppa = ioctl (tap_fd, I_STR, &strioc_ppa)) < 0) syslog (LOG_ERR, "Can't assign new interface"); TFR(if_fd = open("/dev/tap", O_RDWR, 0)); if (if_fd < 0) { syslog(LOG_ERR, "Can't open /dev/tap (2)"); return -1; } if(ioctl(if_fd, I_PUSH, "ip") < 0){ syslog(LOG_ERR, "Can't push IP module"); return -1; } if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) < 0) syslog(LOG_ERR, "Can't get flags\n"); snprintf (actual_name, 32, "tap%d", ppa); pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name); ifr.lifr_ppa = ppa; /* Assign ppa according to the unit number returned by tun device */ if (ioctl (if_fd, SIOCSLIFNAME, &ifr) < 0) syslog (LOG_ERR, "Can't set PPA %d", ppa); if (ioctl(if_fd, SIOCGLIFFLAGS, &ifr) <0) syslog (LOG_ERR, "Can't get flags\n"); /* Push arp module to if_fd */ if (ioctl (if_fd, I_PUSH, "arp") < 0) syslog (LOG_ERR, "Can't push ARP module (2)"); /* Push arp module to ip_fd */ if (ioctl (ip_fd, I_POP, NULL) < 0) syslog (LOG_ERR, "I_POP failed\n"); if (ioctl (ip_fd, I_PUSH, "arp") < 0) syslog (LOG_ERR, "Can't push ARP module (3)\n"); /* Open arp_fd */ TFR(arp_fd = open ("/dev/tap", O_RDWR, 0)); if (arp_fd < 0) syslog (LOG_ERR, "Can't open %s\n", "/dev/tap"); /* Set ifname to arp */ strioc_if.ic_cmd = SIOCSLIFNAME; strioc_if.ic_timout = 0; strioc_if.ic_len = sizeof(ifr); strioc_if.ic_dp = (char *)𝔦 if (ioctl(arp_fd, I_STR, &strioc_if) < 0){ syslog (LOG_ERR, "Can't set ifname to arp\n"); } if((ip_muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0){ syslog(LOG_ERR, "Can't link TAP device to IP"); return -1; } if ((arp_muxid = ioctl (ip_fd, link_type, arp_fd)) < 0) syslog (LOG_ERR, "Can't link TAP device to ARP"); close (if_fd); memset(&ifr, 0x0, sizeof(ifr)); pstrcpy(ifr.lifr_name, sizeof(ifr.lifr_name), actual_name); ifr.lifr_ip_muxid = ip_muxid; ifr.lifr_arp_muxid = arp_muxid; if (ioctl (ip_fd, SIOCSLIFMUXID, &ifr) < 0) { ioctl (ip_fd, I_PUNLINK , arp_muxid); ioctl (ip_fd, I_PUNLINK, ip_muxid); syslog (LOG_ERR, "Can't set multiplexor id"); } snprintf(dev, dev_size, "tap%d", ppa); return tap_fd; }