static void vga_draw_graphic(VGAState *s, int full_update) { int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask, depth; int width, height, shift_control, line_offset, page0, page1, bwidth, bits; int disp_width, multi_scan, multi_run; uint8_t *d; uint32_t v, addr1, addr; vga_draw_line_func *vga_draw_line; full_update |= update_basic_params(s); if (!full_update) vga_sync_dirty_bitmap(s); s->get_resolution(s, &width, &height); disp_width = width; shift_control = (s->gr[0x05] >> 5) & 3; double_scan = (s->cr[0x09] >> 7); if (shift_control != 1) { multi_scan = (((s->cr[0x09] & 0x1f) + 1) << double_scan) - 1; } else { /* in CGA modes, multi_scan is ignored */ /* XXX: is it correct ? */ multi_scan = double_scan; } multi_run = multi_scan; if (shift_control != s->shift_control || double_scan != s->double_scan) { full_update = 1; s->shift_control = shift_control; s->double_scan = double_scan; } if (shift_control == 0) { full_update |= update_palette16(s); if (s->sr[0x01] & 8) { v = VGA_DRAW_LINE4D2; disp_width <<= 1; } else { v = VGA_DRAW_LINE4; } bits = 4; } else if (shift_control == 1) { full_update |= update_palette16(s); if (s->sr[0x01] & 8) { v = VGA_DRAW_LINE2D2; disp_width <<= 1; } else { v = VGA_DRAW_LINE2; } bits = 4; } else { switch(s->get_bpp(s)) { default: case 0: full_update |= update_palette256(s); v = VGA_DRAW_LINE8D2; bits = 4; break; case 8: full_update |= update_palette256(s); v = VGA_DRAW_LINE8; bits = 8; break; case 15: v = VGA_DRAW_LINE15; bits = 16; break; case 16: v = VGA_DRAW_LINE16; bits = 16; break; case 24: v = VGA_DRAW_LINE24; bits = 24; break; case 32: v = VGA_DRAW_LINE32; bits = 32; break; } } vga_draw_line = vga_draw_line_table[v * NB_DEPTHS + get_depth_index(s->ds)]; depth = s->get_bpp(s); if (s->line_offset != s->last_line_offset || disp_width != s->last_width || height != s->last_height || s->last_depth != depth) { if (depth == 16 || depth == 32) { if (is_graphic_console()) { qemu_free_displaysurface(s->ds->surface); s->ds->surface = qemu_create_displaysurface_from(disp_width, height, depth, s->line_offset, s->vram_ptr + (s->start_addr * 4)); dpy_resize(s->ds); } else { qemu_console_resize(s->ds, disp_width, height); } } else { qemu_console_resize(s->ds, disp_width, height); } s->last_scr_width = disp_width; s->last_scr_height = height; s->last_width = disp_width; s->last_height = height; s->last_line_offset = s->line_offset; s->last_depth = depth; full_update = 1; } else if (is_graphic_console() && is_buffer_shared(s->ds->surface) && (full_update || s->ds->surface->data != s->vram_ptr + (s->start_addr * 4))) { s->ds->surface->data = s->vram_ptr + (s->start_addr * 4); dpy_setdata(s->ds); } s->rgb_to_pixel = rgb_to_pixel_dup_table[get_depth_index(s->ds)]; if (!is_buffer_shared(s->ds->surface) && s->cursor_invalidate) s->cursor_invalidate(s); line_offset = s->line_offset; #if 0 printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", width, height, v, line_offset, s->cr[9], s->cr[0x17], s->line_compare, s->sr[0x01]); #endif addr1 = (s->start_addr * 4); bwidth = (width * bits + 7) / 8; y_start = -1; page_min = 0x7fffffff; page_max = -1; d = ds_get_data(s->ds); linesize = ds_get_linesize(s->ds); y1 = 0; for(y = 0; y < height; y++) { addr = addr1; if (!(s->cr[0x17] & 1)) { int shift; /* CGA compatibility handling */ shift = 14 + ((s->cr[0x17] >> 6) & 1); addr = (addr & ~(1 << shift)) | ((y1 & 1) << shift); } if (!(s->cr[0x17] & 2)) { addr = (addr & ~0x8000) | ((y1 & 2) << 14); } page0 = s->vram_offset + (addr & TARGET_PAGE_MASK); page1 = s->vram_offset + ((addr + bwidth - 1) & TARGET_PAGE_MASK); update = full_update | cpu_physical_memory_get_dirty(page0, VGA_DIRTY_FLAG) | cpu_physical_memory_get_dirty(page1, VGA_DIRTY_FLAG); if ((page1 - page0) > TARGET_PAGE_SIZE) { /* if wide line, can use another page */ update |= cpu_physical_memory_get_dirty(page0 + TARGET_PAGE_SIZE, VGA_DIRTY_FLAG); } /* explicit invalidation for the hardware cursor */ update |= (s->invalidated_y_table[y >> 5] >> (y & 0x1f)) & 1; if (update) { if (y_start < 0) y_start = y; if (page0 < page_min) page_min = page0; if (page1 > page_max) page_max = page1; if (!(is_buffer_shared(s->ds->surface))) { vga_draw_line(s, d, s->vram_ptr + addr, width); if (s->cursor_draw_line) s->cursor_draw_line(s, d, y); } } else { if (y_start >= 0) { /* flush to display */ dpy_update(s->ds, 0, y_start, disp_width, y - y_start); y_start = -1; } } if (!multi_run) { mask = (s->cr[0x17] & 3) ^ 3; if ((y1 & mask) == mask) addr1 += line_offset; y1++; multi_run = multi_scan; } else { multi_run--; } /* line compare acts on the displayed lines */ if (y == s->line_compare) addr1 = 0; d += linesize; } if (y_start >= 0) { /* flush to display */ dpy_update(s->ds, 0, y_start, disp_width, y - y_start); } /* reset modified pages */ if (page_max != -1) { cpu_physical_memory_reset_dirty(page_min, page_max + TARGET_PAGE_SIZE, VGA_DIRTY_FLAG); } memset(s->invalidated_y_table, 0, ((height + 31) >> 5) * 4); }


static int qemu_signalfd_compat(const sigset_t *mask) { pthread_attr_t attr; pthread_t tid; struct sigfd_compat_info *info; int fds[2]; info = malloc(sizeof(*info)); if (info == NULL) { errno = ENOMEM; return -1; } if (pipe(fds) == -1) { free(info); return -1; } memcpy(&info->mask, mask, sizeof(*mask)); info->fd = fds[1]; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); pthread_create(&tid, &attr, sigwait_compat, info); pthread_attr_destroy(&attr); return fds[0]; }


static int protocol_client_auth_sasl_start_len(VncState *vs, uint8_t *data, size_t len) { uint32_t startlen = read_u32(data, 0); VNC_DEBUG("Got client start len %d\n", startlen); if (startlen > SASL_DATA_MAX_LEN) { VNC_DEBUG("Too much SASL data %d\n", startlen); vnc_client_error(vs); return -1; } if (startlen == 0) return protocol_client_auth_sasl_start(vs, NULL, 0); vnc_read_when(vs, protocol_client_auth_sasl_start, startlen); return 0; }


static inline void mv_pred_direct(AVSContext *h, cavs_vector *pmv_fw, cavs_vector *col_mv) { cavs_vector *pmv_bw = pmv_fw + MV_BWD_OFFS; int den = h->direct_den[col_mv->ref]; int m = FF_SIGNBIT(col_mv->x); pmv_fw->dist = h->dist[1]; pmv_bw->dist = h->dist[0]; pmv_fw->ref = 1; pmv_bw->ref = 0; /* scale the co-located motion vector according to its temporal span */ pmv_fw->x = (((den + (den * col_mv->x * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m; pmv_bw->x = m - (((den + (den * col_mv->x * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m); m = FF_SIGNBIT(col_mv->y); pmv_fw->y = (((den + (den * col_mv->y * pmv_fw->dist ^ m) - m - 1) >> 14) ^ m) - m; pmv_bw->y = m - (((den + (den * col_mv->y * pmv_bw->dist ^ m) - m - 1) >> 14) ^ m); }


static inline void h264_deblock_q1(register vector unsigned char p0, register vector unsigned char p1, register vector unsigned char p2, register vector unsigned char q0, register vector unsigned char tc0) { register vector unsigned char average = vec_avg(p0, q0); register vector unsigned char temp; register vector unsigned char uncliped; register vector unsigned char ones; register vector unsigned char max; register vector unsigned char min; temp = vec_xor(average, p2); average = vec_avg(average, p2); /*avg(p2, avg(p0, q0)) */ ones = vec_splat_u8(1); temp = vec_and(temp, ones); /*(p2^avg(p0, q0)) & 1 */ uncliped = vec_subs(average, temp); /*(p2+((p0+q0+1)>>1))>>1 */ max = vec_adds(p1, tc0); min = vec_subs(p1, tc0); p1 = vec_max(min, uncliped); p1 = vec_min(max, p1); }


static inline void gen_branch_a(DisasContext *dc, target_ulong pc1, target_ulong pc2, TCGv r_cond) { int l1; l1 = gen_new_label(); tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, 0, l1); gen_goto_tb(dc, 0, pc2, pc1); gen_set_label(l1); gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8); }


uint64_t qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, int n_start, int n_end, int *num, QCowL2Meta *m) { BDRVQcowState *s = bs->opaque; int l2_index, ret; uint64_t l2_offset, *l2_table, cluster_offset; int nb_clusters, i = 0; QCowL2Meta *old_alloc; ret = get_cluster_table(bs, offset, &l2_table, &l2_offset, &l2_index); if (ret == 0) return 0; nb_clusters = size_to_clusters(s, n_end << 9); nb_clusters = MIN(nb_clusters, s->l2_size - l2_index); cluster_offset = be64_to_cpu(l2_table[l2_index]); /* We keep all QCOW_OFLAG_COPIED clusters */ if (cluster_offset & QCOW_OFLAG_COPIED) { nb_clusters = count_contiguous_clusters(nb_clusters, s->cluster_size, &l2_table[l2_index], 0, 0); cluster_offset &= ~QCOW_OFLAG_COPIED; m->nb_clusters = 0; goto out; } /* for the moment, multiple compressed clusters are not managed */ if (cluster_offset & QCOW_OFLAG_COMPRESSED) nb_clusters = 1; /* how many available clusters ? */ while (i < nb_clusters) { i += count_contiguous_clusters(nb_clusters - i, s->cluster_size, &l2_table[l2_index], i, 0); if(be64_to_cpu(l2_table[l2_index + i])) break; i += count_contiguous_free_clusters(nb_clusters - i, &l2_table[l2_index + i]); cluster_offset = be64_to_cpu(l2_table[l2_index + i]); if ((cluster_offset & QCOW_OFLAG_COPIED) || (cluster_offset & QCOW_OFLAG_COMPRESSED)) break; } nb_clusters = i; /* * Check if there already is an AIO write request in flight which allocates * the same cluster. In this case we need to wait until the previous * request has completed and updated the L2 table accordingly. */ LIST_FOREACH(old_alloc, &s->cluster_allocs, next_in_flight) { uint64_t end_offset = offset + nb_clusters * s->cluster_size; uint64_t old_offset = old_alloc->offset; uint64_t old_end_offset = old_alloc->offset + old_alloc->nb_clusters * s->cluster_size; if (end_offset < old_offset || offset > old_end_offset) { /* No intersection */ } else { if (offset < old_offset) { /* Stop at the start of a running allocation */ nb_clusters = (old_offset - offset) >> s->cluster_bits; } else { nb_clusters = 0; } if (nb_clusters == 0) { /* Set dependency and wait for a callback */ m->depends_on = old_alloc; m->nb_clusters = 0; *num = 0; return 0; } } } if (!nb_clusters) { abort(); } LIST_INSERT_HEAD(&s->cluster_allocs, m, next_in_flight); /* allocate a new cluster */ cluster_offset = qcow2_alloc_clusters(bs, nb_clusters * s->cluster_size); /* save info needed for meta data update */ m->offset = offset; m->n_start = n_start; m->nb_clusters = nb_clusters; out: m->nb_available = MIN(nb_clusters << (s->cluster_bits - 9), n_end); *num = m->nb_available - n_start; return cluster_offset; }


static int tx_consume(Rocker *r, DescInfo *info) { PCIDevice *dev = PCI_DEVICE(r); char *buf = desc_get_buf(info, true); RockerTlv *tlv_frag; RockerTlv *tlvs[ROCKER_TLV_TX_MAX + 1]; struct iovec iov[ROCKER_TX_FRAGS_MAX] = { { 0, }, }; uint32_t pport; uint32_t port; uint16_t tx_offload = ROCKER_TX_OFFLOAD_NONE; uint16_t tx_l3_csum_off = 0; uint16_t tx_tso_mss = 0; uint16_t tx_tso_hdr_len = 0; int iovcnt = 0; int err = ROCKER_OK; int rem; int i; if (!buf) { return -ROCKER_ENXIO; } rocker_tlv_parse(tlvs, ROCKER_TLV_TX_MAX, buf, desc_tlv_size(info)); if (!tlvs[ROCKER_TLV_TX_FRAGS]) { return -ROCKER_EINVAL; } pport = rocker_get_pport_by_tx_ring(r, desc_get_ring(info)); if (!fp_port_from_pport(pport, &port)) { return -ROCKER_EINVAL; } if (tlvs[ROCKER_TLV_TX_OFFLOAD]) { tx_offload = rocker_tlv_get_u8(tlvs[ROCKER_TLV_TX_OFFLOAD]); } switch (tx_offload) { case ROCKER_TX_OFFLOAD_L3_CSUM: if (!tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) { return -ROCKER_EINVAL; } break; case ROCKER_TX_OFFLOAD_TSO: if (!tlvs[ROCKER_TLV_TX_TSO_MSS] || !tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) { return -ROCKER_EINVAL; } break; } if (tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]) { tx_l3_csum_off = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_L3_CSUM_OFF]); } if (tlvs[ROCKER_TLV_TX_TSO_MSS]) { tx_tso_mss = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_MSS]); } if (tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]) { tx_tso_hdr_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_TSO_HDR_LEN]); } rocker_tlv_for_each_nested(tlv_frag, tlvs[ROCKER_TLV_TX_FRAGS], rem) { hwaddr frag_addr; uint16_t frag_len; if (rocker_tlv_type(tlv_frag) != ROCKER_TLV_TX_FRAG) { err = -ROCKER_EINVAL; goto err_bad_attr; } rocker_tlv_parse_nested(tlvs, ROCKER_TLV_TX_FRAG_ATTR_MAX, tlv_frag); if (!tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR] || !tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]) { err = -ROCKER_EINVAL; goto err_bad_attr; } frag_addr = rocker_tlv_get_le64(tlvs[ROCKER_TLV_TX_FRAG_ATTR_ADDR]); frag_len = rocker_tlv_get_le16(tlvs[ROCKER_TLV_TX_FRAG_ATTR_LEN]); iov[iovcnt].iov_len = frag_len; iov[iovcnt].iov_base = g_malloc(frag_len); if (!iov[iovcnt].iov_base) { err = -ROCKER_ENOMEM; goto err_no_mem; } if (pci_dma_read(dev, frag_addr, iov[iovcnt].iov_base, iov[iovcnt].iov_len)) { err = -ROCKER_ENXIO; goto err_bad_io; } if (++iovcnt > ROCKER_TX_FRAGS_MAX) { goto err_too_many_frags; } } if (iovcnt) { /* XXX perform Tx offloads */ /* XXX silence compiler for now */ tx_l3_csum_off += tx_tso_mss = tx_tso_hdr_len = 0; } err = fp_port_eg(r->fp_port[port], iov, iovcnt); err_too_many_frags: err_bad_io: err_no_mem: err_bad_attr: for (i = 0; i < ROCKER_TX_FRAGS_MAX; i++) { if (iov[i].iov_base) { g_free(iov[i].iov_base); } } return err; }


AVFilterFormats *avfilter_all_colorspaces(void) { return avfilter_make_format_list(35, PIX_FMT_YUV444P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_YUV411P, PIX_FMT_YUV410P, PIX_FMT_YUYV422, PIX_FMT_UYVY422, PIX_FMT_UYYVYY411, PIX_FMT_YUVJ444P, PIX_FMT_YUVJ422P, PIX_FMT_YUVJ420P, PIX_FMT_YUV440P, PIX_FMT_YUVJ440P, PIX_FMT_RGB32, PIX_FMT_BGR32, PIX_FMT_RGB32_1, PIX_FMT_BGR32_1, PIX_FMT_RGB24, PIX_FMT_BGR24, PIX_FMT_RGB565, PIX_FMT_BGR565, PIX_FMT_RGB555, PIX_FMT_BGR555, PIX_FMT_RGB8, PIX_FMT_BGR8, PIX_FMT_RGB4_BYTE,PIX_FMT_BGR4_BYTE, PIX_FMT_GRAY16BE, PIX_FMT_GRAY16LE, PIX_FMT_GRAY8, PIX_FMT_PAL8, PIX_FMT_MONOWHITE,PIX_FMT_MONOBLACK PIX_FMT_NV12, PIX_FMT_NV21); }


MemoryRegion *escc_init(target_phys_addr_t base, qemu_irq irqA, qemu_irq irqB, CharDriverState *chrA, CharDriverState *chrB, int clock, int it_shift) { DeviceState *dev; SysBusDevice *s; SerialState *d; dev = qdev_create(NULL, "escc"); qdev_prop_set_uint32(dev, "disabled", 0); qdev_prop_set_uint32(dev, "frequency", clock); qdev_prop_set_uint32(dev, "it_shift", it_shift); qdev_prop_set_chr(dev, "chrB", chrB); qdev_prop_set_chr(dev, "chrA", chrA); qdev_prop_set_uint32(dev, "chnBtype", ser); qdev_prop_set_uint32(dev, "chnAtype", ser); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); sysbus_connect_irq(s, 0, irqB); sysbus_connect_irq(s, 1, irqA); if (base) { sysbus_mmio_map(s, 0, base); } d = FROM_SYSBUS(SerialState, s); return &d->mmio; }


static void free_geotags(TiffContext *const s) { int i; for (i = 0; i < s->geotag_count; i++) { if (s->geotags[i].val) av_freep(&s->geotags[i].val); } av_freep(&s->geotags); }


void ff_bink_idct_c(DCTELEM *block) { int i; DCTELEM temp[64]; for (i = 0; i < 8; i++) bink_idct_col(&temp[i], &block[i]); for (i = 0; i < 8; i++) { IDCT_ROW( (&block[8*i]), (&temp[8*i]) ); } }


PCIBus *pci_pmac_init(qemu_irq *pic) { DeviceState *dev; SysBusDevice *s; UNINState *d; /* Use values found on a real PowerMac */ /* Uninorth main bus */ dev = qdev_create(NULL, "Uni-north main"); qdev_init_nofail(dev); s = sysbus_from_qdev(dev); d = FROM_SYSBUS(UNINState, s); d->host_state.bus = pci_register_bus(&d->busdev.qdev, "pci", pci_unin_set_irq, pci_unin_map_irq, pic, 11 << 3, 4); pci_create_simple(d->host_state.bus, 11 << 3, "Uni-north main"); sysbus_mmio_map(s, 0, 0xf2800000); sysbus_mmio_map(s, 1, 0xf2c00000); /* DEC 21154 bridge */ #if 0 /* XXX: not activated as PPC BIOS doesn't handle multiple buses properly */ pci_create_simple(d->host_state.bus, 12 << 3, "DEC 21154"); #endif /* Uninorth AGP bus */ pci_create_simple(d->host_state.bus, 13 << 3, "Uni-north AGP"); /* Uninorth internal bus */ #if 0 /* XXX: not needed for now */ pci_create_simple(d->host_state.bus, 14 << 3, "Uni-north internal"); #endif return d->host_state.bus; }


static void json_message_process_token(JSONLexer *lexer, GString *input, JSONTokenType type, int x, int y) { JSONMessageParser *parser = container_of(lexer, JSONMessageParser, lexer); QDict *dict; switch (type) { case JSON_LCURLY: parser->brace_count++; break; case JSON_RCURLY: parser->brace_count--; break; case JSON_LSQUARE: parser->bracket_count++; break; case JSON_RSQUARE: parser->bracket_count--; break; default: break; } dict = qdict_new(); qdict_put(dict, "type", qint_from_int(type)); qdict_put(dict, "token", qstring_from_str(input->str)); qdict_put(dict, "x", qint_from_int(x)); qdict_put(dict, "y", qint_from_int(y)); parser->token_size += input->len; g_queue_push_tail(parser->tokens, dict); if (type == JSON_ERROR) { goto out_emit_bad; } else if (parser->brace_count < 0 || parser->bracket_count < 0 || (parser->brace_count == 0 && parser->bracket_count == 0)) { goto out_emit; } else if (parser->token_size > MAX_TOKEN_SIZE || parser->bracket_count + parser->brace_count > MAX_NESTING) { /* Security consideration, we limit total memory allocated per object * and the maximum recursion depth that a message can force. */ goto out_emit_bad; } return; out_emit_bad: /* * Clear out token list and tell the parser to emit an error * indication by passing it a NULL list */ json_message_free_tokens(parser); out_emit: /* send current list of tokens to parser and reset tokenizer */ parser->brace_count = 0; parser->bracket_count = 0; /* parser->emit takes ownership of parser->tokens. */ parser->emit(parser, parser->tokens); parser->tokens = g_queue_new(); parser->token_size = 0; }


static inline void ppc4xx_tlb_invalidate_virt(CPUPPCState *env, target_ulong eaddr, uint32_t pid) { #if !defined(FLUSH_ALL_TLBS) CPUState *cs = CPU(ppc_env_get_cpu(env)); ppcemb_tlb_t *tlb; hwaddr raddr; target_ulong page, end; int i; for (i = 0; i < env->nb_tlb; i++) { tlb = &env->tlb.tlbe[i]; if (ppcemb_tlb_check(env, tlb, &raddr, eaddr, pid, 0, i) == 0) { end = tlb->EPN + tlb->size; for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) { tlb_flush_page(cs, page); } tlb->prot &= ~PAGE_VALID; break; } } #else ppc4xx_tlb_invalidate_all(env); #endif }


void pci_bridge_initfn(PCIDevice *dev, const char *typename) { PCIBus *parent = dev->bus; PCIBridge *br = PCI_BRIDGE(dev); PCIBus *sec_bus = &br->sec_bus; pci_word_test_and_set_mask(dev->config + PCI_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); /* * TODO: We implement VGA Enable in the Bridge Control Register * therefore per the PCI to PCI bridge spec we must also implement * VGA Palette Snooping. When done, set this bit writable: * * pci_word_test_and_set_mask(dev->wmask + PCI_COMMAND, * PCI_COMMAND_VGA_PALETTE); */ pci_config_set_class(dev->config, PCI_CLASS_BRIDGE_PCI); dev->config[PCI_HEADER_TYPE] = (dev->config[PCI_HEADER_TYPE] & PCI_HEADER_TYPE_MULTI_FUNCTION) | PCI_HEADER_TYPE_BRIDGE; pci_set_word(dev->config + PCI_SEC_STATUS, PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK); /* * If we don't specify the name, the bus will be addressed as <id>.0, where * id is the device id. * Since PCI Bridge devices have a single bus each, we don't need the index: * let users address the bus using the device name. */ if (!br->bus_name && dev->qdev.id && *dev->qdev.id) { br->bus_name = dev->qdev.id; } qbus_create_inplace(sec_bus, sizeof(br->sec_bus), typename, DEVICE(dev), br->bus_name); sec_bus->parent_dev = dev; sec_bus->map_irq = br->map_irq ? br->map_irq : pci_swizzle_map_irq_fn; sec_bus->address_space_mem = &br->address_space_mem; memory_region_init(&br->address_space_mem, OBJECT(br), "pci_bridge_pci", UINT64_MAX); sec_bus->address_space_io = &br->address_space_io; memory_region_init(&br->address_space_io, OBJECT(br), "pci_bridge_io", 65536); br->windows = pci_bridge_region_init(br); QLIST_INIT(&sec_bus->child); QLIST_INSERT_HEAD(&parent->child, sec_bus, sibling); }


void qemu_pixman_linebuf_fill(pixman_image_t *linebuf, pixman_image_t *fb, int width, int y) { pixman_image_composite(PIXMAN_OP_SRC, fb, NULL, linebuf, 0, y, 0, 0, 0, 0, width, 1); }


static inline abi_long target_to_host_cmsg(struct msghdr *msgh, struct target_msghdr *target_msgh) { struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); abi_long msg_controllen; abi_ulong target_cmsg_addr; struct target_cmsghdr *target_cmsg; socklen_t space = 0; msg_controllen = tswapal(target_msgh->msg_controllen); if (msg_controllen < sizeof (struct target_cmsghdr)) goto the_end; target_cmsg_addr = tswapal(target_msgh->msg_control); target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); if (!target_cmsg) return -TARGET_EFAULT; while (cmsg && target_cmsg) { void *data = CMSG_DATA(cmsg); void *target_data = TARGET_CMSG_DATA(target_cmsg); int len = tswapal(target_cmsg->cmsg_len) - TARGET_CMSG_ALIGN(sizeof (struct target_cmsghdr)); space += CMSG_SPACE(len); if (space > msgh->msg_controllen) { space -= CMSG_SPACE(len); gemu_log("Host cmsg overflow\n"); break; } if (tswap32(target_cmsg->cmsg_level) == TARGET_SOL_SOCKET) { cmsg->cmsg_level = SOL_SOCKET; } else { cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level); } cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type); cmsg->cmsg_len = CMSG_LEN(len); if (cmsg->cmsg_level != SOL_SOCKET || cmsg->cmsg_type != SCM_RIGHTS) { gemu_log("Unsupported ancillary data: %d/%d\n", cmsg->cmsg_level, cmsg->cmsg_type); memcpy(data, target_data, len); } else { int *fd = (int *)data; int *target_fd = (int *)target_data; int i, numfds = len / sizeof(int); for (i = 0; i < numfds; i++) fd[i] = tswap32(target_fd[i]); } cmsg = CMSG_NXTHDR(msgh, cmsg); target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); } unlock_user(target_cmsg, target_cmsg_addr, 0); the_end: msgh->msg_controllen = space; return 0; }


static bool ga_open_pidfile(const char *pidfile) { int pidfd; char pidstr[32]; pidfd = open(pidfile, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR); if (pidfd == -1 || lockf(pidfd, F_TLOCK, 0)) { g_critical("Cannot lock pid file, %s", strerror(errno)); if (pidfd != -1) { close(pidfd); } return false; } if (ftruncate(pidfd, 0) || lseek(pidfd, 0, SEEK_SET)) { g_critical("Failed to truncate pid file"); goto fail; } sprintf(pidstr, "%d", getpid()); if (write(pidfd, pidstr, strlen(pidstr)) != strlen(pidstr)) { g_critical("Failed to write pid file"); goto fail; } return true; fail: unlink(pidfile); return false; }


static void handle_pending_signal(CPUArchState *cpu_env, int sig) { CPUState *cpu = ENV_GET_CPU(cpu_env); abi_ulong handler; sigset_t set, old_set; target_sigset_t target_old_set; struct target_sigaction *sa; struct sigqueue *q; TaskState *ts = cpu->opaque; struct emulated_sigtable *k = &ts->sigtab[sig - 1]; trace_user_handle_signal(cpu_env, sig); /* dequeue signal */ q = k->first; k->first = q->next; if (!k->first) k->pending = 0; sig = gdb_handlesig(cpu, sig); if (!sig) { sa = NULL; handler = TARGET_SIG_IGN; } else { sa = &sigact_table[sig - 1]; handler = sa->_sa_handler; } if (ts->sigsegv_blocked && sig == TARGET_SIGSEGV) { /* Guest has blocked SIGSEGV but we got one anyway. Assume this * is a forced SIGSEGV (ie one the kernel handles via force_sig_info * because it got a real MMU fault), and treat as if default handler. */ handler = TARGET_SIG_DFL; } if (handler == TARGET_SIG_DFL) { /* default handler : ignore some signal. The other are job control or fatal */ if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) { kill(getpid(),SIGSTOP); } else if (sig != TARGET_SIGCHLD && sig != TARGET_SIGURG && sig != TARGET_SIGWINCH && sig != TARGET_SIGCONT) { force_sig(sig); } } else if (handler == TARGET_SIG_IGN) { /* ignore sig */ } else if (handler == TARGET_SIG_ERR) { force_sig(sig); } else { /* compute the blocked signals during the handler execution */ target_to_host_sigset(&set, &sa->sa_mask); /* SA_NODEFER indicates that the current signal should not be blocked during the handler */ if (!(sa->sa_flags & TARGET_SA_NODEFER)) sigaddset(&set, target_to_host_signal(sig)); /* block signals in the handler using Linux */ do_sigprocmask(SIG_BLOCK, &set, &old_set); /* save the previous blocked signal state to restore it at the end of the signal execution (see do_sigreturn) */ host_to_target_sigset_internal(&target_old_set, &old_set); /* if the CPU is in VM86 mode, we restore the 32 bit values */ #if defined(TARGET_I386) && !defined(TARGET_X86_64) { CPUX86State *env = cpu_env; if (env->eflags & VM_MASK) save_v86_state(env); } #endif /* prepare the stack frame of the virtual CPU */ #if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) \ || defined(TARGET_OPENRISC) || defined(TARGET_TILEGX) /* These targets do not have traditional signals. */ setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env); #else if (sa->sa_flags & TARGET_SA_SIGINFO) setup_rt_frame(sig, sa, &q->info, &target_old_set, cpu_env); else setup_frame(sig, sa, &target_old_set, cpu_env); #endif if (sa->sa_flags & TARGET_SA_RESETHAND) { sa->_sa_handler = TARGET_SIG_DFL; } } if (q != &k->info) free_sigqueue(cpu_env, q); }


static void pcie_pci_bridge_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { pci_bridge_write_config(d, address, val, len); msi_write_config(d, address, val, len); shpc_cap_write_config(d, address, val, len); }


static ram_addr_t find_ram_offset(ram_addr_t size) { RAMBlock *block, *next_block; ram_addr_t offset = RAM_ADDR_MAX, mingap = RAM_ADDR_MAX; assert(size != 0); /* it would hand out same offset multiple times */ if (QTAILQ_EMPTY(&ram_list.blocks)) return 0; QTAILQ_FOREACH(block, &ram_list.blocks, next) { ram_addr_t end, next = RAM_ADDR_MAX; end = block->offset + block->length; QTAILQ_FOREACH(next_block, &ram_list.blocks, next) { if (next_block->offset >= end) { next = MIN(next, next_block->offset); } } if (next - end >= size && next - end < mingap) { offset = end; mingap = next - end; } } if (offset == RAM_ADDR_MAX) { fprintf(stderr, "Failed to find gap of requested size: %" PRIu64 "\n", (uint64_t)size); abort(); } return offset; }


CharDriverState *qemu_chr_alloc(void) { CharDriverState *chr = g_malloc0(sizeof(CharDriverState)); qemu_mutex_init(&chr->chr_write_lock); return chr; }


static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) { SCSIRequest *req = &r->req; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); uint64_t nb_sectors; int buflen = 0; int ret; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: if (!bdrv_is_inserted(s->bs)) goto not_ready; break; case REQUEST_SENSE: if (req->cmd.xfer < 4) goto illegal_request; buflen = scsi_device_get_sense(&s->qdev, outbuf, req->cmd.xfer, (req->cmd.buf[1] & 1) == 0); break; case INQUIRY: buflen = scsi_disk_emulate_inquiry(req, outbuf); if (buflen < 0) goto illegal_request; break; case MODE_SENSE: case MODE_SENSE_10: buflen = scsi_disk_emulate_mode_sense(req, outbuf); if (buflen < 0) goto illegal_request; break; case READ_TOC: buflen = scsi_disk_emulate_read_toc(req, outbuf); if (buflen < 0) goto illegal_request; break; case RESERVE: if (req->cmd.buf[1] & 1) goto illegal_request; break; case RESERVE_10: if (req->cmd.buf[1] & 3) goto illegal_request; break; case RELEASE: if (req->cmd.buf[1] & 1) goto illegal_request; break; case RELEASE_10: if (req->cmd.buf[1] & 3) goto illegal_request; break; case START_STOP: if (s->qdev.type == TYPE_ROM && (req->cmd.buf[4] & 2)) { /* load/eject medium */ bdrv_eject(s->bs, !(req->cmd.buf[4] & 1)); } break; case ALLOW_MEDIUM_REMOVAL: bdrv_set_locked(s->bs, req->cmd.buf[4] & 1); break; case READ_CAPACITY_10: /* The normal LEN field for this command is zero. */ memset(outbuf, 0, 8); bdrv_get_geometry(s->bs, &nb_sectors); if (!nb_sectors) goto not_ready; nb_sectors /= s->cluster_size; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ s->max_lba = nb_sectors; /* Clip to 2TB, instead of returning capacity modulo 2TB. */ if (nb_sectors > UINT32_MAX) nb_sectors = UINT32_MAX; outbuf[0] = (nb_sectors >> 24) & 0xff; outbuf[1] = (nb_sectors >> 16) & 0xff; outbuf[2] = (nb_sectors >> 8) & 0xff; outbuf[3] = nb_sectors & 0xff; outbuf[4] = 0; outbuf[5] = 0; outbuf[6] = s->cluster_size * 2; outbuf[7] = 0; buflen = 8; break; case SYNCHRONIZE_CACHE: ret = bdrv_flush(s->bs); if (ret < 0) { if (scsi_handle_rw_error(r, -ret, SCSI_REQ_STATUS_RETRY_FLUSH)) { return -1; } } break; case GET_CONFIGURATION: memset(outbuf, 0, 8); /* ??? This should probably return much more information. For now just return the basic header indicating the CD-ROM profile. */ outbuf[7] = 8; // CD-ROM buflen = 8; break; case SERVICE_ACTION_IN: /* Service Action In subcommands. */ if ((req->cmd.buf[1] & 31) == 0x10) { DPRINTF("SAI READ CAPACITY(16)\n"); memset(outbuf, 0, req->cmd.xfer); bdrv_get_geometry(s->bs, &nb_sectors); if (!nb_sectors) goto not_ready; nb_sectors /= s->cluster_size; /* Returned value is the address of the last sector. */ nb_sectors--; /* Remember the new size for read/write sanity checking. */ s->max_lba = nb_sectors; outbuf[0] = (nb_sectors >> 56) & 0xff; outbuf[1] = (nb_sectors >> 48) & 0xff; outbuf[2] = (nb_sectors >> 40) & 0xff; outbuf[3] = (nb_sectors >> 32) & 0xff; outbuf[4] = (nb_sectors >> 24) & 0xff; outbuf[5] = (nb_sectors >> 16) & 0xff; outbuf[6] = (nb_sectors >> 8) & 0xff; outbuf[7] = nb_sectors & 0xff; outbuf[8] = 0; outbuf[9] = 0; outbuf[10] = s->cluster_size * 2; outbuf[11] = 0; outbuf[12] = 0; outbuf[13] = get_physical_block_exp(&s->qdev.conf); /* set TPE bit if the format supports discard */ if (s->qdev.conf.discard_granularity) { outbuf[14] = 0x80; } /* Protection, exponent and lowest lba field left blank. */ buflen = req->cmd.xfer; break; } DPRINTF("Unsupported Service Action In\n"); goto illegal_request; case REPORT_LUNS: if (req->cmd.xfer < 16) goto illegal_request; memset(outbuf, 0, 16); outbuf[3] = 8; buflen = 16; break; case VERIFY_10: break; default: scsi_check_condition(r, SENSE_CODE(INVALID_OPCODE)); return -1; } return buflen; not_ready: if (!bdrv_is_inserted(s->bs)) { scsi_check_condition(r, SENSE_CODE(NO_MEDIUM)); } else { scsi_check_condition(r, SENSE_CODE(LUN_NOT_READY)); } return -1; illegal_request: scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); return -1; }


static void flush_queued_work(CPUState *cpu) { struct qemu_work_item *wi; if (cpu->queued_work_first == NULL) { return; } while ((wi = cpu->queued_work_first)) { cpu->queued_work_first = wi->next; wi->func(wi->data); wi->done = true; if (wi->free) { g_free(wi); } } cpu->queued_work_last = NULL; qemu_cond_broadcast(&qemu_work_cond); }


static int validate_guest_space(unsigned long guest_base, unsigned long guest_size) { unsigned long real_start, test_page_addr; /* We need to check that we can force a fault on access to the * commpage at 0xffff0fxx */ test_page_addr = guest_base + (0xffff0f00 & qemu_host_page_mask); /* If the commpage lies within the already allocated guest space, * then there is no way we can allocate it. */ if (test_page_addr >= guest_base && test_page_addr <= (guest_base + guest_size)) { return -1; } /* Note it needs to be writeable to let us initialise it */ real_start = (unsigned long) mmap((void *)test_page_addr, qemu_host_page_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); /* If we can't map it then try another address */ if (real_start == -1ul) { return 0; } if (real_start != test_page_addr) { /* OS didn't put the page where we asked - unmap and reject */ munmap((void *)real_start, qemu_host_page_size); return 0; } /* Leave the page mapped * Populate it (mmap should have left it all 0'd) */ /* Kernel helper versions */ __put_user(5, (uint32_t *)g2h(0xffff0ffcul)); /* Now it's populated make it RO */ if (mprotect((void *)test_page_addr, qemu_host_page_size, PROT_READ)) { perror("Protecting guest commpage"); exit(-1); } return 1; /* All good */ }


long do_sigreturn(CPUCRISState *env) { struct target_signal_frame *frame; abi_ulong frame_addr; target_sigset_t target_set; sigset_t set; int i; frame_addr = env->regs[R_SP]; /* Make sure the guest isn't playing games. */ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 1)) goto badframe; /* Restore blocked signals */ if (__get_user(target_set.sig[0], &frame->sc.oldmask)) goto badframe; for(i = 1; i < TARGET_NSIG_WORDS; i++) { if (__get_user(target_set.sig[i], &frame->extramask[i - 1])) goto badframe; } target_to_host_sigset_internal(&set, &target_set); do_sigprocmask(SIG_SETMASK, &set, NULL); restore_sigcontext(&frame->sc, env); unlock_user_struct(frame, frame_addr, 0); return env->regs[10]; badframe: unlock_user_struct(frame, frame_addr, 0); force_sig(TARGET_SIGSEGV); }


static void usbredir_interrupt_packet(void *priv, uint32_t id, struct usb_redir_interrupt_packet_header *interrupt_packet, uint8_t *data, int data_len) { USBRedirDevice *dev = priv; uint8_t ep = interrupt_packet->endpoint; DPRINTF("interrupt-in status %d ep %02X len %d id %u\n", interrupt_packet->status, ep, data_len, id); if (dev->endpoint[EP2I(ep)].type != USB_ENDPOINT_XFER_INT) { ERROR("received int packet for non interrupt endpoint %02X\n", ep); free(data); return; } if (ep & USB_DIR_IN) { if (dev->endpoint[EP2I(ep)].interrupt_started == 0) { DPRINTF("received int packet while not started ep %02X\n", ep); free(data); return; } /* bufp_alloc also adds the packet to the ep queue */ bufp_alloc(dev, data, data_len, interrupt_packet->status, ep); } else { int len = interrupt_packet->length; AsyncURB *aurb = async_find(dev, id); if (!aurb) { return; } if (aurb->interrupt_packet.endpoint != interrupt_packet->endpoint) { ERROR("return int packet mismatch, please report this!\n"); len = USB_RET_NAK; } if (aurb->packet) { aurb->packet->len = usbredir_handle_status(dev, interrupt_packet->status, len); usb_packet_complete(&dev->dev, aurb->packet); } async_free(dev, aurb); } }


void mpeg1_encode_mb(MpegEncContext *s, DCTELEM block[6][64], int motion_x, int motion_y) { int i, cbp; const int mb_x = s->mb_x; const int mb_y = s->mb_y; const int first_mb= mb_x == s->resync_mb_x && mb_y == s->resync_mb_y; /* compute cbp */ cbp = 0; for(i=0;i<6;i++) { if (s->block_last_index[i] >= 0) cbp |= 1 << (5 - i); } if (cbp == 0 && !first_mb && (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && ((s->pict_type == P_TYPE && s->mv_type == MV_TYPE_16X16 && (motion_x | motion_y) == 0) || (s->pict_type == B_TYPE && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { s->mb_skip_run++; s->qscale -= s->dquant; s->skip_count++; s->misc_bits++; s->last_bits++; if(s->pict_type == P_TYPE){ s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->last_mv[0][1][1]= s->last_mv[0][0][1]= 0; } } else { if(first_mb){ assert(s->mb_skip_run == 0); encode_mb_skip_run(s, s->mb_x); }else{ encode_mb_skip_run(s, s->mb_skip_run); } if (s->pict_type == I_TYPE) { if(s->dquant && cbp){ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_type : macroblock_quant = 1 */ put_bits(&s->pb, 5, s->qscale); }else{ put_mb_modes(s, 1, 1, 0, 0); /* macroblock_type : macroblock_quant = 0 */ s->qscale -= s->dquant; } s->misc_bits+= get_bits_diff(s); s->i_count++; } else if (s->mb_intra) { if(s->dquant && cbp){ put_mb_modes(s, 6, 0x01, 0, 0); put_bits(&s->pb, 5, s->qscale); }else{ put_mb_modes(s, 5, 0x03, 0, 0); s->qscale -= s->dquant; } s->misc_bits+= get_bits_diff(s); s->i_count++; memset(s->last_mv, 0, sizeof(s->last_mv)); } else if (s->pict_type == P_TYPE) { if(s->mv_type == MV_TYPE_16X16){ if (cbp != 0) { if ((motion_x|motion_y) == 0) { if(s->dquant){ put_mb_modes(s, 5, 1, 0, 0); /* macroblock_pattern & quant */ put_bits(&s->pb, 5, s->qscale); }else{ put_mb_modes(s, 2, 1, 0, 0); /* macroblock_pattern only */ } s->misc_bits+= get_bits_diff(s); } else { if(s->dquant){ put_mb_modes(s, 5, 2, 1, 0); /* motion + cbp */ put_bits(&s->pb, 5, s->qscale); }else{ put_mb_modes(s, 1, 1, 1, 0); /* motion + cbp */ } s->misc_bits+= get_bits_diff(s); mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added s->mv_bits+= get_bits_diff(s); } } else { put_bits(&s->pb, 3, 1); /* motion only */ if (!s->frame_pred_frame_dct) put_bits(&s->pb, 2, 2); /* motion_type: frame */ s->misc_bits+= get_bits_diff(s); mpeg1_encode_motion(s, motion_x - s->last_mv[0][0][0], s->f_code); // RAL: f_code parameter added mpeg1_encode_motion(s, motion_y - s->last_mv[0][0][1], s->f_code); // RAL: f_code parameter added s->qscale -= s->dquant; s->mv_bits+= get_bits_diff(s); } s->last_mv[0][1][0]= s->last_mv[0][0][0]= motion_x; s->last_mv[0][1][1]= s->last_mv[0][0][1]= motion_y; }else{ assert(!s->frame_pred_frame_dct && s->mv_type == MV_TYPE_FIELD); if (cbp) { if(s->dquant){ put_mb_modes(s, 5, 2, 1, 1); /* motion + cbp */ put_bits(&s->pb, 5, s->qscale); }else{ put_mb_modes(s, 1, 1, 1, 1); /* motion + cbp */ } } else { put_bits(&s->pb, 3, 1); /* motion only */ put_bits(&s->pb, 2, 1); /* motion_type: field */ s->qscale -= s->dquant; } s->misc_bits+= get_bits_diff(s); for(i=0; i<2; i++){ put_bits(&s->pb, 1, s->field_select[0][i]); mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); s->last_mv[0][i][0]= s->mv[0][i][0]; s->last_mv[0][i][1]= 2*s->mv[0][i][1]; } s->mv_bits+= get_bits_diff(s); } if(cbp) put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); s->f_count++; } else{ static const int mb_type_len[4]={0,3,4,2}; //bak,for,bi if(s->mv_type == MV_TYPE_16X16){ if (cbp){ // With coded bloc pattern if (s->dquant) { if(s->mv_dir == MV_DIR_FORWARD) put_mb_modes(s, 6, 3, 1, 0); else put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 0); put_bits(&s->pb, 5, s->qscale); } else { put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 0); } }else{ // No coded bloc pattern put_bits(&s->pb, mb_type_len[s->mv_dir], 2); if (!s->frame_pred_frame_dct) put_bits(&s->pb, 2, 2); /* motion_type: frame */ s->qscale -= s->dquant; } s->misc_bits += get_bits_diff(s); if (s->mv_dir&MV_DIR_FORWARD){ mpeg1_encode_motion(s, s->mv[0][0][0] - s->last_mv[0][0][0], s->f_code); mpeg1_encode_motion(s, s->mv[0][0][1] - s->last_mv[0][0][1], s->f_code); s->last_mv[0][0][0]=s->last_mv[0][1][0]= s->mv[0][0][0]; s->last_mv[0][0][1]=s->last_mv[0][1][1]= s->mv[0][0][1]; s->f_count++; } if (s->mv_dir&MV_DIR_BACKWARD){ mpeg1_encode_motion(s, s->mv[1][0][0] - s->last_mv[1][0][0], s->b_code); mpeg1_encode_motion(s, s->mv[1][0][1] - s->last_mv[1][0][1], s->b_code); s->last_mv[1][0][0]=s->last_mv[1][1][0]= s->mv[1][0][0]; s->last_mv[1][0][1]=s->last_mv[1][1][1]= s->mv[1][0][1]; s->b_count++; } }else{ assert(s->mv_type == MV_TYPE_FIELD); assert(!s->frame_pred_frame_dct); if (cbp){ // With coded bloc pattern if (s->dquant) { if(s->mv_dir == MV_DIR_FORWARD) put_mb_modes(s, 6, 3, 1, 1); else put_mb_modes(s, mb_type_len[s->mv_dir]+3, 2, 1, 1); put_bits(&s->pb, 5, s->qscale); } else { put_mb_modes(s, mb_type_len[s->mv_dir], 3, 1, 1); } }else{ // No coded bloc pattern put_bits(&s->pb, mb_type_len[s->mv_dir], 2); put_bits(&s->pb, 2, 1); /* motion_type: field */ s->qscale -= s->dquant; } s->misc_bits += get_bits_diff(s); if (s->mv_dir&MV_DIR_FORWARD){ for(i=0; i<2; i++){ put_bits(&s->pb, 1, s->field_select[0][i]); mpeg1_encode_motion(s, s->mv[0][i][0] - s->last_mv[0][i][0] , s->f_code); mpeg1_encode_motion(s, s->mv[0][i][1] - (s->last_mv[0][i][1]>>1), s->f_code); s->last_mv[0][i][0]= s->mv[0][i][0]; s->last_mv[0][i][1]= 2*s->mv[0][i][1]; } s->f_count++; } if (s->mv_dir&MV_DIR_BACKWARD){ for(i=0; i<2; i++){ put_bits(&s->pb, 1, s->field_select[1][i]); mpeg1_encode_motion(s, s->mv[1][i][0] - s->last_mv[1][i][0] , s->b_code); mpeg1_encode_motion(s, s->mv[1][i][1] - (s->last_mv[1][i][1]>>1), s->b_code); s->last_mv[1][i][0]= s->mv[1][i][0]; s->last_mv[1][i][1]= 2*s->mv[1][i][1]; } s->b_count++; } } s->mv_bits += get_bits_diff(s); if(cbp) put_bits(&s->pb, mbPatTable[cbp - 1][1], mbPatTable[cbp - 1][0]); } for(i=0;i<6;i++) { if (cbp & (1 << (5 - i))) { mpeg1_encode_block(s, block[i], i); } } s->mb_skip_run = 0; if(s->mb_intra) s->i_tex_bits+= get_bits_diff(s); else s->p_tex_bits+= get_bits_diff(s); } }


static void virtio_ccw_device_realize(VirtioCcwDevice *dev, Error **errp) { unsigned int cssid = 0; unsigned int ssid = 0; unsigned int schid; unsigned int devno; bool have_devno = false; bool found = false; SubchDev *sch; int num; DeviceState *parent = DEVICE(dev); Error *err = NULL; VirtIOCCWDeviceClass *k = VIRTIO_CCW_DEVICE_GET_CLASS(dev); VirtIODevice *vdev; sch = g_malloc0(sizeof(SubchDev)); sch->driver_data = dev; dev->sch = sch; dev->indicators = NULL; /* Initialize subchannel structure. */ sch->channel_prog = 0x0; sch->last_cmd_valid = false; sch->thinint_active = false; /* * Use a device number if provided. Otherwise, fall back to subchannel * number. */ if (dev->bus_id) { num = sscanf(dev->bus_id, "%x.%x.%04x", &cssid, &ssid, &devno); if (num == 3) { if ((cssid > MAX_CSSID) || (ssid > MAX_SSID)) { error_setg(errp, "Invalid cssid or ssid: cssid %x, ssid %x", cssid, ssid); goto out_err; } /* Enforce use of virtual cssid. */ if (cssid != VIRTUAL_CSSID) { error_setg(errp, "cssid %x not valid for virtio devices", cssid); goto out_err; } if (css_devno_used(cssid, ssid, devno)) { error_setg(errp, "Device %x.%x.%04x already exists", cssid, ssid, devno); goto out_err; } sch->cssid = cssid; sch->ssid = ssid; sch->devno = devno; have_devno = true; } else { error_setg(errp, "Malformed devno parameter '%s'", dev->bus_id); goto out_err; } } /* Find the next free id. */ if (have_devno) { for (schid = 0; schid <= MAX_SCHID; schid++) { if (!css_find_subch(1, cssid, ssid, schid)) { sch->schid = schid; css_subch_assign(cssid, ssid, schid, devno, sch); found = true; break; } } if (!found) { error_setg(errp, "No free subchannel found for %x.%x.%04x", cssid, ssid, devno); goto out_err; } trace_virtio_ccw_new_device(cssid, ssid, schid, devno, "user-configured"); } else { cssid = VIRTUAL_CSSID; for (ssid = 0; ssid <= MAX_SSID; ssid++) { for (schid = 0; schid <= MAX_SCHID; schid++) { if (!css_find_subch(1, cssid, ssid, schid)) { sch->cssid = cssid; sch->ssid = ssid; sch->schid = schid; devno = schid; /* * If the devno is already taken, look further in this * subchannel set. */ while (css_devno_used(cssid, ssid, devno)) { if (devno == MAX_SCHID) { devno = 0; } else if (devno == schid - 1) { error_setg(errp, "No free devno found"); goto out_err; } else { devno++; } } sch->devno = devno; css_subch_assign(cssid, ssid, schid, devno, sch); found = true; break; } } if (found) { break; } } if (!found) { error_setg(errp, "Virtual channel subsystem is full!"); goto out_err; } trace_virtio_ccw_new_device(cssid, ssid, schid, devno, "auto-configured"); } /* Build initial schib. */ css_sch_build_virtual_schib(sch, 0, VIRTIO_CCW_CHPID_TYPE); sch->ccw_cb = virtio_ccw_cb; /* Build senseid data. */ memset(&sch->id, 0, sizeof(SenseId)); sch->id.reserved = 0xff; sch->id.cu_type = VIRTIO_CCW_CU_TYPE; if (k->realize) { k->realize(dev, &err); } if (err) { error_propagate(errp, err); css_subch_assign(cssid, ssid, schid, devno, NULL); goto out_err; } /* device_id is only set after vdev has been realized */ vdev = virtio_ccw_get_vdev(sch); sch->id.cu_model = vdev->device_id; /* Only the first 32 feature bits are used. */ dev->host_features[0] = virtio_bus_get_vdev_features(&dev->bus, dev->host_features[0]); virtio_add_feature(&dev->host_features[0], VIRTIO_F_NOTIFY_ON_EMPTY); virtio_add_feature(&dev->host_features[0], VIRTIO_F_BAD_FEATURE); css_generate_sch_crws(sch->cssid, sch->ssid, sch->schid, parent->hotplugged, 1); return; out_err: dev->sch = NULL; g_free(sch); }


void op_cp1_registers(void) { if (!(env->CP0_Status & (1 << CP0St_FR)) && (PARAM1 & 1)) { CALL_FROM_TB1(do_raise_exception, EXCP_RI); } RETURN(); }


static inline void RENAME(rgb24tobgr24)(const uint8_t *src, uint8_t *dst, long src_size) { unsigned i; #ifdef HAVE_MMX long mmx_size= 23 - src_size; asm volatile ( "test %%"REG_a", %%"REG_a" \n\t" "jns 2f \n\t" "movq "MANGLE(mask24r)", %%mm5 \n\t" "movq "MANGLE(mask24g)", %%mm6 \n\t" "movq "MANGLE(mask24b)", %%mm7 \n\t" ASMALIGN(4) "1: \n\t" PREFETCH" 32(%1, %%"REG_a") \n\t" "movq (%1, %%"REG_a"), %%mm0 \n\t" // BGR BGR BG "movq (%1, %%"REG_a"), %%mm1 \n\t" // BGR BGR BG "movq 2(%1, %%"REG_a"), %%mm2 \n\t" // R BGR BGR B "psllq $16, %%mm0 \n\t" // 00 BGR BGR "pand %%mm5, %%mm0 \n\t" "pand %%mm6, %%mm1 \n\t" "pand %%mm7, %%mm2 \n\t" "por %%mm0, %%mm1 \n\t" "por %%mm2, %%mm1 \n\t" "movq 6(%1, %%"REG_a"), %%mm0 \n\t" // BGR BGR BG MOVNTQ" %%mm1, (%2, %%"REG_a")\n\t" // RGB RGB RG "movq 8(%1, %%"REG_a"), %%mm1 \n\t" // R BGR BGR B "movq 10(%1, %%"REG_a"), %%mm2 \n\t" // GR BGR BGR "pand %%mm7, %%mm0 \n\t" "pand %%mm5, %%mm1 \n\t" "pand %%mm6, %%mm2 \n\t" "por %%mm0, %%mm1 \n\t" "por %%mm2, %%mm1 \n\t" "movq 14(%1, %%"REG_a"), %%mm0 \n\t" // R BGR BGR B MOVNTQ" %%mm1, 8(%2, %%"REG_a")\n\t" // B RGB RGB R "movq 16(%1, %%"REG_a"), %%mm1 \n\t" // GR BGR BGR "movq 18(%1, %%"REG_a"), %%mm2 \n\t" // BGR BGR BG "pand %%mm6, %%mm0 \n\t" "pand %%mm7, %%mm1 \n\t" "pand %%mm5, %%mm2 \n\t" "por %%mm0, %%mm1 \n\t" "por %%mm2, %%mm1 \n\t" MOVNTQ" %%mm1, 16(%2, %%"REG_a")\n\t" "add $24, %%"REG_a" \n\t" " js 1b \n\t" "2: \n\t" : "+a" (mmx_size) : "r" (src-mmx_size), "r"(dst-mmx_size) ); __asm __volatile(SFENCE:::"memory"); __asm __volatile(EMMS:::"memory"); if(mmx_size==23) return; //finihsed, was multiple of 8 src+= src_size; dst+= src_size; src_size= 23-mmx_size; src-= src_size; dst-= src_size; #endif for(i=0; i<src_size; i+=3) { register uint8_t x; x = src[i + 2]; dst[i + 1] = src[i + 1]; dst[i + 2] = src[i + 0]; dst[i + 0] = x; } }


static int vda_h264_end_frame(AVCodecContext *avctx) { H264Context *h = avctx->priv_data; struct vda_context *vda_ctx = avctx->hwaccel_context; AVFrame *frame = &h->cur_pic_ptr->f; struct vda_buffer *context; AVBufferRef *buffer; int status; if (!vda_ctx->decoder || !vda_ctx->priv_bitstream) status = vda_sync_decode(vda_ctx); frame->data[3] = (void*)vda_ctx->cv_buffer; if (status) av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%d)\n", status);


static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; H264Context *h = avctx->priv_data; AVFrame *pict = data; int buf_index = 0; Picture *out; int i, out_idx; int ret; h->flags = avctx->flags; /* end of stream, output what is still in the buffers */ if (buf_size == 0) { out: h->cur_pic_ptr = NULL; h->first_field = 0; // FIXME factorize this with the output code below out = h->delayed_pic[0]; out_idx = 0; for (i = 1; h->delayed_pic[i] && !h->delayed_pic[i]->f.key_frame && !h->delayed_pic[i]->mmco_reset; i++) if (h->delayed_pic[i]->poc < out->poc) { out = h->delayed_pic[i]; out_idx = i; } for (i = out_idx; h->delayed_pic[i]; i++) h->delayed_pic[i] = h->delayed_pic[i + 1]; if (out) { out->reference &= ~DELAYED_PIC_REF; ret = output_frame(h, pict, &out->f); if (ret < 0) return ret; *got_frame = 1; } return buf_index; } if(h->is_avc && buf_size >= 9 && buf[0]==1 && buf[2]==0 && (buf[4]&0xFC)==0xFC && (buf[5]&0x1F) && buf[8]==0x67){ int cnt= buf[5]&0x1f; const uint8_t *p= buf+6; while(cnt--){ int nalsize= AV_RB16(p) + 2; if(nalsize > buf_size - (p-buf) || p[2]!=0x67) goto not_extra; p += nalsize; } cnt = *(p++); if(!cnt) goto not_extra; while(cnt--){ int nalsize= AV_RB16(p) + 2; if(nalsize > buf_size - (p-buf) || p[2]!=0x68) goto not_extra; p += nalsize; } return ff_h264_decode_extradata(h, buf, buf_size); } not_extra: buf_index = decode_nal_units(h, buf, buf_size, 0); if (buf_index < 0) return -1; if (!h->cur_pic_ptr && h->nal_unit_type == NAL_END_SEQUENCE) { av_assert0(buf_index <= buf_size); goto out; } if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) && !h->cur_pic_ptr) { if (avctx->skip_frame >= AVDISCARD_NONREF || buf_size >= 4 && !memcmp("Q264", buf, 4)) return buf_size; av_log(avctx, AV_LOG_ERROR, "no frame!\n"); return -1; } if (!(avctx->flags2 & CODEC_FLAG2_CHUNKS) || (h->mb_y >= h->mb_height && h->mb_height)) { if (avctx->flags2 & CODEC_FLAG2_CHUNKS) decode_postinit(h, 1); field_end(h, 0); /* Wait for second field. */ *got_frame = 0; if (h->next_output_pic && (h->next_output_pic->sync || h->sync>1)) { ret = output_frame(h, pict, &h->next_output_pic->f); if (ret < 0) return ret; *got_frame = 1; if (CONFIG_MPEGVIDEO) { ff_print_debug_info2(h->avctx, h->next_output_pic, pict, h->er.mbskip_table, &h->low_delay, h->mb_width, h->mb_height, h->mb_stride, 1); } } } assert(pict->data[0] || !*got_frame); return get_consumed_bytes(buf_index, buf_size); }


GIOStatus ga_channel_write_all(GAChannel *c, const char *buf, size_t size) { GIOStatus status = G_IO_STATUS_NORMAL; size_t count; while (size) { status = ga_channel_write(c, buf, size, &count); if (status == G_IO_STATUS_NORMAL) { size -= count; buf += count; } else if (status != G_IO_STATUS_AGAIN) { break; } } return status; }


static int channelmap_query_formats(AVFilterContext *ctx) { ChannelMapContext *s = ctx->priv; ff_set_common_formats(ctx, ff_planar_sample_fmts()); ff_set_common_samplerates(ctx, ff_all_samplerates()); ff_channel_layouts_ref(ff_all_channel_layouts(), &ctx->inputs[0]->out_channel_layouts); ff_channel_layouts_ref(s->channel_layouts, &ctx->outputs[0]->in_channel_layouts); return 0; }


static void flush_queued_work(CPUState *env) { struct qemu_work_item *wi; if (!env->queued_work_first) return; while ((wi = env->queued_work_first)) { env->queued_work_first = wi->next; wi->func(wi->data); wi->done = true; } env->queued_work_last = NULL; qemu_cond_broadcast(&qemu_work_cond); }


static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, bool create, enum AIOCBState aiocb_type) { int nr_copies = s->inode.nr_copies; SheepdogObjReq hdr; unsigned int wlen; int ret; uint64_t oid = aio_req->oid; unsigned int datalen = aio_req->data_len; uint64_t offset = aio_req->offset; uint8_t flags = aio_req->flags; uint64_t old_oid = aio_req->base_oid; if (!nr_copies) { error_report("bug"); } memset(&hdr, 0, sizeof(hdr)); if (aiocb_type == AIOCB_READ_UDATA) { wlen = 0; hdr.opcode = SD_OP_READ_OBJ; hdr.flags = flags; } else if (create) { wlen = datalen; hdr.opcode = SD_OP_CREATE_AND_WRITE_OBJ; hdr.flags = SD_FLAG_CMD_WRITE | flags; } else { wlen = datalen; hdr.opcode = SD_OP_WRITE_OBJ; hdr.flags = SD_FLAG_CMD_WRITE | flags; } if (s->cache_flags) { hdr.flags |= s->cache_flags; } hdr.oid = oid; hdr.cow_oid = old_oid; hdr.copies = s->inode.nr_copies; hdr.data_length = datalen; hdr.offset = offset; hdr.id = aio_req->id; qemu_co_mutex_lock(&s->lock); s->co_send = qemu_coroutine_self(); qemu_aio_set_fd_handler(s->fd, co_read_response, co_write_request, aio_flush_request, s); socket_set_cork(s->fd, 1); /* send a header */ ret = qemu_co_send(s->fd, &hdr, sizeof(hdr)); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); error_report("failed to send a req, %s", strerror(errno)); return -errno; } if (wlen) { ret = qemu_co_sendv(s->fd, iov, niov, aio_req->iov_offset, wlen); if (ret < 0) { qemu_co_mutex_unlock(&s->lock); error_report("failed to send a data, %s", strerror(errno)); return -errno; } } socket_set_cork(s->fd, 0); qemu_aio_set_fd_handler(s->fd, co_read_response, NULL, aio_flush_request, s); qemu_co_mutex_unlock(&s->lock); return 0; }


static int img_write_packet(AVFormatContext *s, int stream_index, UINT8 *buf, int size) { VideoData *img = s->priv_data; AVStream *st = s->streams[stream_index]; ByteIOContext pb1, *pb; AVPicture picture; int width, height, ret, size1; char filename[1024]; width = st->codec.width; height = st->codec.height; switch(st->codec.pix_fmt) { case PIX_FMT_YUV420P: size1 = (width * height * 3) / 2; if (size != size1) return -EIO; picture.data[0] = buf; picture.data[1] = picture.data[0] + width * height; picture.data[2] = picture.data[1] + (width * height) / 4; picture.linesize[0] = width; picture.linesize[1] = width >> 1; picture.linesize[2] = width >> 1; break; case PIX_FMT_RGB24: size1 = (width * height * 3); if (size != size1) return -EIO; picture.data[0] = buf; picture.linesize[0] = width * 3; break; default: return -EIO; } if (get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0) return -EIO; if (!img->is_pipe) { pb = &pb1; if (url_fopen(pb, filename, URL_WRONLY) < 0) return -EIO; } else { pb = &s->pb; } switch(img->img_fmt) { case IMGFMT_PGMYUV: ret = pgm_save(&picture, width, height, pb, 1); break; case IMGFMT_PGM: ret = pgm_save(&picture, width, height, pb, 0); break; case IMGFMT_YUV: ret = yuv_save(&picture, width, height, filename); break; case IMGFMT_PPM: ret = ppm_save(&picture, width, height, pb); break; } if (!img->is_pipe) { url_fclose(pb); } img->img_number++; return 0; }


int pci_drive_hot_add(Monitor *mon, const QDict *qdict, DriveInfo *dinfo) { /* On non-x86 we don't do PCI hotplug */ monitor_printf(mon, "Can't hot-add drive to type %d\n", dinfo->type); return -1; }


static inline int yv12toyuy2_unscaled_altivec(SwsContext *c, uint8_t* src[], int srcStride[], int srcSliceY, int srcSliceH, uint8_t* dstParam[], int dstStride_a[]) { uint8_t *dst=dstParam[0] + dstStride_a[0]*srcSliceY; // yv12toyuy2( src[0],src[1],src[2],dst,c->srcW,srcSliceH,srcStride[0],srcStride[1],dstStride[0] ); uint8_t *ysrc = src[0]; uint8_t *usrc = src[1]; uint8_t *vsrc = src[2]; const int width = c->srcW; const int height = srcSliceH; const int lumStride = srcStride[0]; const int chromStride = srcStride[1]; const int dstStride = dstStride_a[0]; const vector unsigned char yperm = vec_lvsl(0, ysrc); const int vertLumPerChroma = 2; register unsigned int y; if(width&15){ yv12toyuy2( ysrc, usrc, vsrc, dst,c->srcW,srcSliceH, lumStride, chromStride, dstStride); return srcSliceH; } /* this code assume: 1) dst is 16 bytes-aligned 2) dstStride is a multiple of 16 3) width is a multiple of 16 4) lum&chrom stride are multiple of 8 */ for(y=0; y<height; y++) { int i; for (i = 0; i < width - 31; i+= 32) { const unsigned int j = i >> 1; vector unsigned char v_yA = vec_ld(i, ysrc); vector unsigned char v_yB = vec_ld(i + 16, ysrc); vector unsigned char v_yC = vec_ld(i + 32, ysrc); vector unsigned char v_y1 = vec_perm(v_yA, v_yB, yperm); vector unsigned char v_y2 = vec_perm(v_yB, v_yC, yperm); vector unsigned char v_uA = vec_ld(j, usrc); vector unsigned char v_uB = vec_ld(j + 16, usrc); vector unsigned char v_u = vec_perm(v_uA, v_uB, vec_lvsl(j, usrc)); vector unsigned char v_vA = vec_ld(j, vsrc); vector unsigned char v_vB = vec_ld(j + 16, vsrc); vector unsigned char v_v = vec_perm(v_vA, v_vB, vec_lvsl(j, vsrc)); vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); vector unsigned char v_uv_b = vec_mergel(v_u, v_v); vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a); vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a); vector unsigned char v_yuy2_2 = vec_mergeh(v_y2, v_uv_b); vector unsigned char v_yuy2_3 = vec_mergel(v_y2, v_uv_b); vec_st(v_yuy2_0, (i << 1), dst); vec_st(v_yuy2_1, (i << 1) + 16, dst); vec_st(v_yuy2_2, (i << 1) + 32, dst); vec_st(v_yuy2_3, (i << 1) + 48, dst); } if (i < width) { const unsigned int j = i >> 1; vector unsigned char v_y1 = vec_ld(i, ysrc); vector unsigned char v_u = vec_ld(j, usrc); vector unsigned char v_v = vec_ld(j, vsrc); vector unsigned char v_uv_a = vec_mergeh(v_u, v_v); vector unsigned char v_yuy2_0 = vec_mergeh(v_y1, v_uv_a); vector unsigned char v_yuy2_1 = vec_mergel(v_y1, v_uv_a); vec_st(v_yuy2_0, (i << 1), dst); vec_st(v_yuy2_1, (i << 1) + 16, dst); } if((y&(vertLumPerChroma-1))==(vertLumPerChroma-1) ) { usrc += chromStride; vsrc += chromStride; } ysrc += lumStride; dst += dstStride; } return srcSliceH; }


void cpu_loop(CPUAlphaState *env) { CPUState *cs = CPU(alpha_env_get_cpu(env)); int trapnr; target_siginfo_t info; abi_long sysret; while (1) { cpu_exec_start(cs); trapnr = cpu_alpha_exec(cs); cpu_exec_end(cs); /* All of the traps imply a transition through PALcode, which implies an REI instruction has been executed. Which means that the intr_flag should be cleared. */ env->intr_flag = 0; switch (trapnr) { case EXCP_RESET: fprintf(stderr, "Reset requested. Exit\n"); exit(EXIT_FAILURE); break; case EXCP_MCHK: fprintf(stderr, "Machine check exception. Exit\n"); exit(EXIT_FAILURE); break; case EXCP_SMP_INTERRUPT: case EXCP_CLK_INTERRUPT: case EXCP_DEV_INTERRUPT: fprintf(stderr, "External interrupt. Exit\n"); exit(EXIT_FAILURE); break; case EXCP_MMFAULT: env->lock_addr = -1; info.si_signo = TARGET_SIGSEGV; info.si_errno = 0; info.si_code = (page_get_flags(env->trap_arg0) & PAGE_VALID ? TARGET_SEGV_ACCERR : TARGET_SEGV_MAPERR); info._sifields._sigfault._addr = env->trap_arg0; queue_signal(env, info.si_signo, &info); break; case EXCP_UNALIGN: env->lock_addr = -1; info.si_signo = TARGET_SIGBUS; info.si_errno = 0; info.si_code = TARGET_BUS_ADRALN; info._sifields._sigfault._addr = env->trap_arg0; queue_signal(env, info.si_signo, &info); break; case EXCP_OPCDEC: do_sigill: env->lock_addr = -1; info.si_signo = TARGET_SIGILL; info.si_errno = 0; info.si_code = TARGET_ILL_ILLOPC; info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, &info); break; case EXCP_ARITH: env->lock_addr = -1; info.si_signo = TARGET_SIGFPE; info.si_errno = 0; info.si_code = TARGET_FPE_FLTINV; info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, &info); break; case EXCP_FEN: /* No-op. Linux simply re-enables the FPU. */ break; case EXCP_CALL_PAL: env->lock_addr = -1; switch (env->error_code) { case 0x80: /* BPT */ info.si_signo = TARGET_SIGTRAP; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, &info); break; case 0x81: /* BUGCHK */ info.si_signo = TARGET_SIGTRAP; info.si_errno = 0; info.si_code = 0; info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, &info); break; case 0x83: /* CALLSYS */ trapnr = env->ir[IR_V0]; sysret = do_syscall(env, trapnr, env->ir[IR_A0], env->ir[IR_A1], env->ir[IR_A2], env->ir[IR_A3], env->ir[IR_A4], env->ir[IR_A5], 0, 0); if (trapnr == TARGET_NR_sigreturn || trapnr == TARGET_NR_rt_sigreturn) { break; } /* Syscall writes 0 to V0 to bypass error check, similar to how this is handled internal to Linux kernel. (Ab)use trapnr temporarily as boolean indicating error. */ trapnr = (env->ir[IR_V0] != 0 && sysret < 0); env->ir[IR_V0] = (trapnr ? -sysret : sysret); env->ir[IR_A3] = trapnr; break; case 0x86: /* IMB */ /* ??? We can probably elide the code using page_unprotect that is checking for self-modifying code. Instead we could simply call tb_flush here. Until we work out the changes required to turn off the extra write protection, this can be a no-op. */ break; case 0x9E: /* RDUNIQUE */ /* Handled in the translator for usermode. */ abort(); case 0x9F: /* WRUNIQUE */ /* Handled in the translator for usermode. */ abort(); case 0xAA: /* GENTRAP */ info.si_signo = TARGET_SIGFPE; switch (env->ir[IR_A0]) { case TARGET_GEN_INTOVF: info.si_code = TARGET_FPE_INTOVF; break; case TARGET_GEN_INTDIV: info.si_code = TARGET_FPE_INTDIV; break; case TARGET_GEN_FLTOVF: info.si_code = TARGET_FPE_FLTOVF; break; case TARGET_GEN_FLTUND: info.si_code = TARGET_FPE_FLTUND; break; case TARGET_GEN_FLTINV: info.si_code = TARGET_FPE_FLTINV; break; case TARGET_GEN_FLTINE: info.si_code = TARGET_FPE_FLTRES; break; case TARGET_GEN_ROPRAND: info.si_code = 0; break; default: info.si_signo = TARGET_SIGTRAP; info.si_code = 0; break; } info.si_errno = 0; info._sifields._sigfault._addr = env->pc; queue_signal(env, info.si_signo, &info); break; default: goto do_sigill; } break; case EXCP_DEBUG: info.si_signo = gdb_handlesig(cs, TARGET_SIGTRAP); if (info.si_signo) { env->lock_addr = -1; info.si_errno = 0; info.si_code = TARGET_TRAP_BRKPT; queue_signal(env, info.si_signo, &info); } break; case EXCP_STL_C: case EXCP_STQ_C: do_store_exclusive(env, env->error_code, trapnr - EXCP_STL_C); break; case EXCP_INTERRUPT: /* Just indicate that signals should be handled asap. */ break; default: printf ("Unhandled trap: 0x%x\n", trapnr); cpu_dump_state(cs, stderr, fprintf, 0); exit(EXIT_FAILURE); } process_pending_signals (env); } }


static S390PCIBusDevice *s390_pci_find_dev_by_target(const char *target) { int i; S390PCIBusDevice *pbdev; S390pciState *s = s390_get_phb(); if (!target) { return NULL; } for (i = 0; i < PCI_SLOT_MAX; i++) { pbdev = s->pbdev[i]; if (!pbdev) { continue; } if (!strcmp(pbdev->target, target)) { return pbdev; } } return NULL; }


static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) { uint16_t cmd; int i, sz, offset, code; unsigned char *dst_end = dst + dst_size; const unsigned char *src_end = src + src_size; while (src < src_end && dst < dst_end) { code = *src++; for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) { if (code & (1 << i)) { *dst++ = *src++; } else { cmd = AV_RL16(src); src += 2; offset = cmd >> 4; sz = (cmd & 0xF) + 2; /* don't use memcpy/memmove here as the decoding routine (ab)uses */ /* buffer overlappings to repeat bytes in the destination */ sz = FFMIN(sz, dst_end - dst); while (sz--) { *dst = *(dst - offset - 1); ++dst; } } } } }


ff_rdt_parse_open(AVFormatContext *ic, int first_stream_of_set_idx, void *priv_data, RTPDynamicProtocolHandler *handler) { RDTDemuxContext *s = av_mallocz(sizeof(RDTDemuxContext)); if (!s) return NULL; s->ic = ic; s->streams = &ic->streams[first_stream_of_set_idx]; do { s->n_streams++; } while (first_stream_of_set_idx + s->n_streams < ic->nb_streams && s->streams[s->n_streams]->priv_data == s->streams[0]->priv_data); s->prev_set_id = -1; s->prev_stream_id = -1; s->prev_timestamp = -1; s->parse_packet = handler->parse_packet; s->dynamic_protocol_context = priv_data; return s; }


static int qcow2_co_writev(BlockDriverState *bs, int64_t sector_num, int remaining_sectors, QEMUIOVector *qiov) { BDRVQcowState *s = bs->opaque; int index_in_cluster; int n_end; int ret; int cur_nr_sectors; /* number of sectors in current iteration */ QCowL2Meta l2meta; uint64_t cluster_offset; QEMUIOVector hd_qiov; uint64_t bytes_done = 0; uint8_t *cluster_data = NULL; l2meta.nb_clusters = 0; qemu_co_queue_init(&l2meta.dependent_requests); qemu_iovec_init(&hd_qiov, qiov->niov); s->cluster_cache_offset = -1; /* disable compressed cache */ qemu_co_mutex_lock(&s->lock); while (remaining_sectors != 0) { index_in_cluster = sector_num & (s->cluster_sectors - 1); n_end = index_in_cluster + remaining_sectors; if (s->crypt_method && n_end > QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors) { n_end = QCOW_MAX_CRYPT_CLUSTERS * s->cluster_sectors; } ret = qcow2_alloc_cluster_offset(bs, sector_num << 9, index_in_cluster, n_end, &cur_nr_sectors, &l2meta); if (ret < 0) { goto fail; } cluster_offset = l2meta.cluster_offset; assert((cluster_offset & 511) == 0); qemu_iovec_reset(&hd_qiov); qemu_iovec_copy(&hd_qiov, qiov, bytes_done, cur_nr_sectors * 512); if (s->crypt_method) { if (!cluster_data) { cluster_data = g_malloc0(QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); } assert(hd_qiov.size <= QCOW_MAX_CRYPT_CLUSTERS * s->cluster_size); qemu_iovec_to_buffer(&hd_qiov, cluster_data); qcow2_encrypt_sectors(s, sector_num, cluster_data, cluster_data, cur_nr_sectors, 1, &s->aes_encrypt_key); qemu_iovec_reset(&hd_qiov); qemu_iovec_add(&hd_qiov, cluster_data, cur_nr_sectors * 512); } BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); qemu_co_mutex_unlock(&s->lock); ret = bdrv_co_writev(bs->file, (cluster_offset >> 9) + index_in_cluster, cur_nr_sectors, &hd_qiov); qemu_co_mutex_lock(&s->lock); if (ret < 0) { goto fail; } ret = qcow2_alloc_cluster_link_l2(bs, &l2meta); run_dependent_requests(s, &l2meta); if (ret < 0) { goto fail; } remaining_sectors -= cur_nr_sectors; sector_num += cur_nr_sectors; bytes_done += cur_nr_sectors * 512; } ret = 0; fail: qemu_co_mutex_unlock(&s->lock); qemu_iovec_destroy(&hd_qiov); return ret; }


int vhost_dev_init(struct vhost_dev *hdev, void *opaque, VhostBackendType backend_type, bool force) { uint64_t features; int i, r; if (vhost_set_backend_type(hdev, backend_type) < 0) { close((uintptr_t)opaque); return -1; } if (hdev->vhost_ops->vhost_backend_init(hdev, opaque) < 0) { close((uintptr_t)opaque); return -errno; } r = hdev->vhost_ops->vhost_call(hdev, VHOST_SET_OWNER, NULL); if (r < 0) { goto fail; } r = hdev->vhost_ops->vhost_call(hdev, VHOST_GET_FEATURES, &features); if (r < 0) { goto fail; } for (i = 0; i < hdev->nvqs; ++i) { r = vhost_virtqueue_init(hdev, hdev->vqs + i, i); if (r < 0) { goto fail_vq; } } hdev->features = features; hdev->memory_listener = (MemoryListener) { .begin = vhost_begin, .commit = vhost_commit, .region_add = vhost_region_add, .region_del = vhost_region_del, .region_nop = vhost_region_nop, .log_start = vhost_log_start, .log_stop = vhost_log_stop, .log_sync = vhost_log_sync, .log_global_start = vhost_log_global_start, .log_global_stop = vhost_log_global_stop, .eventfd_add = vhost_eventfd_add, .eventfd_del = vhost_eventfd_del, .priority = 10 }; hdev->migration_blocker = NULL; if (!(hdev->features & (0x1ULL << VHOST_F_LOG_ALL))) { error_setg(&hdev->migration_blocker, "Migration disabled: vhost lacks VHOST_F_LOG_ALL feature."); migrate_add_blocker(hdev->migration_blocker); } hdev->mem = g_malloc0(offsetof(struct vhost_memory, regions)); hdev->n_mem_sections = 0; hdev->mem_sections = NULL; hdev->log = NULL; hdev->log_size = 0; hdev->log_enabled = false; hdev->started = false; hdev->memory_changed = false; memory_listener_register(&hdev->memory_listener, &address_space_memory); hdev->force = force; return 0; fail_vq: while (--i >= 0) { vhost_virtqueue_cleanup(hdev->vqs + i); } fail: r = -errno; hdev->vhost_ops->vhost_backend_cleanup(hdev); return r; }


int ff_set_systematic_pal2(uint32_t pal[256], enum AVPixelFormat pix_fmt) { int i; for (i = 0; i < 256; i++) { int r, g, b; switch (pix_fmt) { case AV_PIX_FMT_RGB8: r = (i>>5 )*36; g = ((i>>2)&7)*36; b = (i&3 )*85; break; case AV_PIX_FMT_BGR8: b = (i>>6 )*85; g = ((i>>3)&7)*36; r = (i&7 )*36; break; case AV_PIX_FMT_RGB4_BYTE: r = (i>>3 )*255; g = ((i>>1)&3)*85; b = (i&1 )*255; break; case AV_PIX_FMT_BGR4_BYTE: b = (i>>3 )*255; g = ((i>>1)&3)*85; r = (i&1 )*255; break; case AV_PIX_FMT_GRAY8: r = b = g = i; break; default: return AVERROR(EINVAL); } pal[i] = b + (g<<8) + (r<<16) + (0xFF<<24); } return 0; }


void qmp_transaction(TransactionActionList *dev_list, Error **errp) { TransactionActionList *dev_entry = dev_list; BlkTransactionState *state, *next; Error *local_err = NULL; QSIMPLEQ_HEAD(snap_bdrv_states, BlkTransactionState) snap_bdrv_states; QSIMPLEQ_INIT(&snap_bdrv_states); /* drain all i/o before any operations */ bdrv_drain_all(); /* We don't do anything in this loop that commits us to the operations */ while (NULL != dev_entry) { TransactionAction *dev_info = NULL; const BdrvActionOps *ops; dev_info = dev_entry->value; dev_entry = dev_entry->next; assert(dev_info->kind < ARRAY_SIZE(actions)); ops = &actions[dev_info->kind]; assert(ops->instance_size > 0); state = g_malloc0(ops->instance_size); state->ops = ops; state->action = dev_info; QSIMPLEQ_INSERT_TAIL(&snap_bdrv_states, state, entry); state->ops->prepare(state, &local_err); if (local_err) { error_propagate(errp, local_err); goto delete_and_fail; } } QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) { if (state->ops->commit) { state->ops->commit(state); } } /* success */ goto exit; delete_and_fail: /* failure, and it is all-or-none; roll back all operations */ QSIMPLEQ_FOREACH(state, &snap_bdrv_states, entry) { if (state->ops->abort) { state->ops->abort(state); } } exit: QSIMPLEQ_FOREACH_SAFE(state, &snap_bdrv_states, entry, next) { if (state->ops->clean) { state->ops->clean(state); } g_free(state); } }


static int intel_hda_init(PCIDevice *pci) { IntelHDAState *d = DO_UPCAST(IntelHDAState, pci, pci); uint8_t *conf = d->pci.config; d->name = d->pci.qdev.info->name; pci_config_set_vendor_id(conf, PCI_VENDOR_ID_INTEL); pci_config_set_device_id(conf, 0x2668); pci_config_set_revision(conf, 1); pci_config_set_class(conf, PCI_CLASS_MULTIMEDIA_HD_AUDIO); pci_config_set_interrupt_pin(conf, 1); /* HDCTL off 0x40 bit 0 selects signaling mode (1-HDA, 0 - Ac97) 18.1.19 */ conf[0x40] = 0x01; d->mmio_addr = cpu_register_io_memory(intel_hda_mmio_read, intel_hda_mmio_write, d, DEVICE_NATIVE_ENDIAN); pci_register_bar_simple(&d->pci, 0, 0x4000, 0, d->mmio_addr); if (d->msi) { msi_init(&d->pci, 0x50, 1, true, false); } hda_codec_bus_init(&d->pci.qdev, &d->codecs, intel_hda_response, intel_hda_xfer); return 0; }


static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockDriverCompletionFunc *cb, void *opaque) { RawAIOCB *acb; acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque); if (!acb) return NULL; if (qemu_paio_write(&acb->aiocb) < 0) { raw_aio_remove(acb); return NULL; } return &acb->common; }


static inline void pred_direct_motion(H264Context * const h, int *mb_type){ MpegEncContext * const s = &h->s; const int mb_xy = s->mb_x + s->mb_y*s->mb_stride; const int b8_xy = 2*s->mb_x + 2*s->mb_y*h->b8_stride; const int b4_xy = 4*s->mb_x + 4*s->mb_y*h->b_stride; const int mb_type_col = h->ref_list[1][0].mb_type[mb_xy]; const int16_t (*l1mv0)[2] = (const int16_t (*)[2]) &h->ref_list[1][0].motion_val[0][b4_xy]; const int8_t *l1ref0 = &h->ref_list[1][0].ref_index[0][b8_xy]; const int is_b8x8 = IS_8X8(*mb_type); int sub_mb_type; int i8, i4; if(IS_8X8(mb_type_col) && !h->sps.direct_8x8_inference_flag){ /* FIXME save sub mb types from previous frames (or derive from MVs) * so we know exactly what block size to use */ sub_mb_type = MB_TYPE_8x8|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_4x4 */ *mb_type = MB_TYPE_8x8; }else if(!is_b8x8 && (IS_16X16(mb_type_col) || IS_INTRA(mb_type_col))){ sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ *mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_16x16 */ }else{ sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ *mb_type = MB_TYPE_8x8; } if(!is_b8x8) *mb_type |= MB_TYPE_DIRECT2; tprintf("mb_type = %08x, sub_mb_type = %08x, is_b8x8 = %d, mb_type_col = %08x\n", *mb_type, sub_mb_type, is_b8x8, mb_type_col); if(h->direct_spatial_mv_pred){ int ref[2]; int mv[2][2]; int list; /* ref = min(neighbors) */ for(list=0; list<2; list++){ int refa = h->ref_cache[list][scan8[0] - 1]; int refb = h->ref_cache[list][scan8[0] - 8]; int refc = h->ref_cache[list][scan8[0] - 8 + 4]; if(refc == -2) refc = h->ref_cache[list][scan8[0] - 8 - 1]; ref[list] = refa; if(ref[list] < 0 || (refb < ref[list] && refb >= 0)) ref[list] = refb; if(ref[list] < 0 || (refc < ref[list] && refc >= 0)) ref[list] = refc; if(ref[list] < 0) ref[list] = -1; } if(ref[0] < 0 && ref[1] < 0){ ref[0] = ref[1] = 0; mv[0][0] = mv[0][1] = mv[1][0] = mv[1][1] = 0; }else{ for(list=0; list<2; list++){ if(ref[list] >= 0) pred_motion(h, 0, 4, list, ref[list], &mv[list][0], &mv[list][1]); else mv[list][0] = mv[list][1] = 0; } } if(ref[1] < 0){ *mb_type &= ~MB_TYPE_P0L1; sub_mb_type &= ~MB_TYPE_P0L1; }else if(ref[0] < 0){ *mb_type &= ~MB_TYPE_P0L0; sub_mb_type &= ~MB_TYPE_P0L0; } if(IS_16X16(*mb_type)){ fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref[0], 1); fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, ref[1], 1); if(!IS_INTRA(mb_type_col) && l1ref0[0] == 0 && ABS(l1mv0[0][0]) <= 1 && ABS(l1mv0[0][1]) <= 1){ if(ref[0] > 0) fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4); else fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); if(ref[1] > 0) fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv[1][0],mv[1][1]), 4); else fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); }else{ fill_rectangle(&h->mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv[0][0],mv[0][1]), 4); fill_rectangle(&h->mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv[1][0],mv[1][1]), 4); } }else{ for(i8=0; i8<4; i8++){ const int x8 = i8&1; const int y8 = i8>>1; if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) continue; h->sub_mb_type[i8] = sub_mb_type; fill_rectangle(&h->mv_cache[0][scan8[i8*4]], 2, 2, 8, pack16to32(mv[0][0],mv[0][1]), 4); fill_rectangle(&h->mv_cache[1][scan8[i8*4]], 2, 2, 8, pack16to32(mv[1][0],mv[1][1]), 4); fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref[0], 1); fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, ref[1], 1); /* col_zero_flag */ if(!IS_INTRA(mb_type_col) && l1ref0[x8 + y8*h->b8_stride] == 0){ for(i4=0; i4<4; i4++){ const int16_t *mv_col = l1mv0[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; if(ABS(mv_col[0]) <= 1 && ABS(mv_col[1]) <= 1){ if(ref[0] == 0) *(uint32_t*)h->mv_cache[0][scan8[i8*4+i4]] = 0; if(ref[1] == 0) *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = 0; } } } } } }else{ /* direct temporal mv pred */ /* FIXME assumes that L1ref0 used the same ref lists as current frame */ if(IS_16X16(*mb_type)){ fill_rectangle(&h->ref_cache[1][scan8[0]], 4, 4, 8, 0, 1); if(IS_INTRA(mb_type_col)){ fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, 0, 1); fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, 0, 4); fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, 0, 4); }else{ const int ref0 = l1ref0[0]; const int dist_scale_factor = h->dist_scale_factor[ref0]; const int16_t *mv_col = l1mv0[0]; int mv_l0[2]; mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8; mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8; fill_rectangle(&h->ref_cache[0][scan8[0]], 4, 4, 8, ref0, 1); fill_rectangle(&h-> mv_cache[0][scan8[0]], 4, 4, 8, pack16to32(mv_l0[0],mv_l0[1]), 4); fill_rectangle(&h-> mv_cache[1][scan8[0]], 4, 4, 8, pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]), 4); } }else{ for(i8=0; i8<4; i8++){ const int x8 = i8&1; const int y8 = i8>>1; int ref0, dist_scale_factor; if(is_b8x8 && !IS_DIRECT(h->sub_mb_type[i8])) continue; h->sub_mb_type[i8] = sub_mb_type; if(IS_INTRA(mb_type_col)){ fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, 0, 1); fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); fill_rectangle(&h-> mv_cache[0][scan8[i8*4]], 2, 2, 8, 0, 4); fill_rectangle(&h-> mv_cache[1][scan8[i8*4]], 2, 2, 8, 0, 4); continue; } ref0 = l1ref0[x8 + y8*h->b8_stride]; dist_scale_factor = h->dist_scale_factor[ref0]; fill_rectangle(&h->ref_cache[0][scan8[i8*4]], 2, 2, 8, ref0, 1); fill_rectangle(&h->ref_cache[1][scan8[i8*4]], 2, 2, 8, 0, 1); for(i4=0; i4<4; i4++){ const int16_t *mv_col = l1mv0[x8*2 + (i4&1) + (y8*2 + (i4>>1))*h->b_stride]; int16_t *mv_l0 = h->mv_cache[0][scan8[i8*4+i4]]; mv_l0[0] = (dist_scale_factor * mv_col[0] + 128) >> 8; mv_l0[1] = (dist_scale_factor * mv_col[1] + 128) >> 8; *(uint32_t*)h->mv_cache[1][scan8[i8*4+i4]] = pack16to32(mv_l0[0]-mv_col[0],mv_l0[1]-mv_col[1]); } } } } }


static inline uint32_t insn_get(CPUX86State *env, DisasContext *s, TCGMemOp ot) { uint32_t ret; switch (ot) { case MO_8: ret = cpu_ldub_code(env, s->pc); s->pc++; break; case MO_16: ret = cpu_lduw_code(env, s->pc); s->pc += 2; break; case MO_32: #ifdef TARGET_X86_64 case MO_64: #endif ret = cpu_ldl_code(env, s->pc); s->pc += 4; break; default: tcg_abort(); } return ret; }


static void bdrv_throttle_write_timer_cb(void *opaque) { BlockDriverState *bs = opaque; qemu_co_enter_next(&bs->throttled_reqs[1]); }


static int find_pte32(CPUPPCState *env, mmu_ctx_t *ctx, int h, int rw, int type, int target_page_bits) { hwaddr pteg_off; target_ulong pte0, pte1; int i, good = -1; int ret, r; ret = -1; /* No entry found */ pteg_off = get_pteg_offset(env, ctx->hash[h], HASH_PTE_SIZE_32); for (i = 0; i < 8; i++) { if (env->external_htab) { pte0 = ldl_p(env->external_htab + pteg_off + (i * 8)); pte1 = ldl_p(env->external_htab + pteg_off + (i * 8) + 4); } else { pte0 = ldl_phys(env->htab_base + pteg_off + (i * 8)); pte1 = ldl_phys(env->htab_base + pteg_off + (i * 8) + 4); } r = pte_check_hash32(ctx, pte0, pte1, h, rw, type); LOG_MMU("Load pte from %08" HWADDR_PRIx " => " TARGET_FMT_lx " " TARGET_FMT_lx " %d %d %d " TARGET_FMT_lx "\n", pteg_off + (i * 8), pte0, pte1, (int)(pte0 >> 31), h, (int)((pte0 >> 6) & 1), ctx->ptem); switch (r) { case -3: /* PTE inconsistency */ return -1; case -2: /* Access violation */ ret = -2; good = i; break; case -1: default: /* No PTE match */ break; case 0: /* access granted */ /* XXX: we should go on looping to check all PTEs consistency * but if we can speed-up the whole thing as the * result would be undefined if PTEs are not consistent. */ ret = 0; good = i; goto done; } } if (good != -1) { done: LOG_MMU("found PTE at addr %08" HWADDR_PRIx " prot=%01x ret=%d\n", ctx->raddr, ctx->prot, ret); /* Update page flags */ pte1 = ctx->raddr; if (pte_update_flags(ctx, &pte1, ret, rw) == 1) { if (env->external_htab) { stl_p(env->external_htab + pteg_off + (good * 8) + 4, pte1); } else { stl_phys_notdirty(env->htab_base + pteg_off + (good * 8) + 4, pte1); } } } /* We have a TLB that saves 4K pages, so let's * split a huge page to 4k chunks */ if (target_page_bits != TARGET_PAGE_BITS) { ctx->raddr |= (ctx->eaddr & ((1 << target_page_bits) - 1)) & TARGET_PAGE_MASK; } return ret; }


static int kvm_put_xcrs(CPUState *env) { #ifdef KVM_CAP_XCRS struct kvm_xcrs xcrs; if (!kvm_has_xcrs()) return 0; xcrs.nr_xcrs = 1; xcrs.flags = 0; xcrs.xcrs[0].xcr = 0; xcrs.xcrs[0].value = env->xcr0; return kvm_vcpu_ioctl(env, KVM_SET_XCRS, &xcrs); #else return 0; #endif }


static ExitStatus gen_bcond_internal(DisasContext *ctx, TCGCond cond, TCGv cmp, int32_t disp) { uint64_t dest = ctx->pc + (disp << 2); int lab_true = gen_new_label(); if (use_goto_tb(ctx, dest)) { tcg_gen_brcondi_i64(cond, cmp, 0, lab_true); tcg_gen_goto_tb(0); tcg_gen_movi_i64(cpu_pc, ctx->pc); tcg_gen_exit_tb((uintptr_t)ctx->tb); gen_set_label(lab_true); tcg_gen_goto_tb(1); tcg_gen_movi_i64(cpu_pc, dest); tcg_gen_exit_tb((uintptr_t)ctx->tb + 1); return EXIT_GOTO_TB; } else { TCGv_i64 z = tcg_const_i64(0); TCGv_i64 d = tcg_const_i64(dest); TCGv_i64 p = tcg_const_i64(ctx->pc); tcg_gen_movcond_i64(cond, cpu_pc, cmp, z, d, p); tcg_temp_free_i64(z); tcg_temp_free_i64(d); tcg_temp_free_i64(p); return EXIT_PC_UPDATED; } }


static uint32_t gt64120_read_config(PCIDevice *d, uint32_t address, int len) { uint32_t val = pci_default_read_config(d, address, len); #ifdef TARGET_WORDS_BIGENDIAN val = bswap32(val); #endif return val; }


static void rtas_get_time_of_day(PowerPCCPU *cpu, sPAPREnvironment *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { struct tm tm; if (nret != 8) { rtas_st(rets, 0, RTAS_OUT_PARAM_ERROR); return; } qemu_get_timedate(&tm, spapr->rtc_offset); rtas_st(rets, 0, RTAS_OUT_SUCCESS); rtas_st(rets, 1, tm.tm_year + 1900); rtas_st(rets, 2, tm.tm_mon + 1); rtas_st(rets, 3, tm.tm_mday); rtas_st(rets, 4, tm.tm_hour); rtas_st(rets, 5, tm.tm_min); rtas_st(rets, 6, tm.tm_sec); rtas_st(rets, 7, 0); /* we don't do nanoseconds */ }


void qmp_block_job_set_speed(const char *device, int64_t speed, Error **errp) { BlockJob *job = find_block_job(device); if (!job) { error_set(errp, QERR_BLOCK_JOB_NOT_ACTIVE, device); return; } block_job_set_speed(job, speed, errp); }


static int create_stream(AVFormatContext *s) { XCBGrabContext *c = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); xcb_get_geometry_cookie_t gc; xcb_get_geometry_reply_t *geo; int ret; if (!st) return AVERROR(ENOMEM); ret = av_parse_video_size(&c->width, &c->height, c->video_size); if (ret < 0) return ret; ret = av_parse_video_rate(&st->avg_frame_rate, c->framerate); if (ret < 0) return ret; avpriv_set_pts_info(st, 64, 1, 1000000); gc = xcb_get_geometry(c->conn, c->screen->root); geo = xcb_get_geometry_reply(c->conn, gc, NULL); c->width = FFMIN(geo->width, c->width); c->height = FFMIN(geo->height, c->height); c->time_base = (AVRational){ st->avg_frame_rate.den, st->avg_frame_rate.num }; c->time_frame = av_gettime(); st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; st->codec->width = c->width; st->codec->height = c->height; st->codec->time_base = c->time_base; ret = pixfmt_from_pixmap_format(s, geo->depth, &st->codec->pix_fmt); free(geo); return ret; }


static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) { unsigned cb; uint8_t *tmp_vlc_bits; uint32_t *tmp_vlc_codes; GetBitContext *gb = &vc->gb; uint16_t *codebook_multiplicands; int ret = 0; vc->codebook_count = get_bits(gb, 8) + 1; av_dlog(NULL, " Codebooks: %d \n", vc->codebook_count); vc->codebooks = av_mallocz(vc->codebook_count * sizeof(*vc->codebooks)); tmp_vlc_bits = av_mallocz(V_MAX_VLCS * sizeof(*tmp_vlc_bits)); tmp_vlc_codes = av_mallocz(V_MAX_VLCS * sizeof(*tmp_vlc_codes)); codebook_multiplicands = av_malloc(V_MAX_VLCS * sizeof(*codebook_multiplicands)); for (cb = 0; cb < vc->codebook_count; ++cb) { vorbis_codebook *codebook_setup = &vc->codebooks[cb]; unsigned ordered, t, entries, used_entries = 0; av_dlog(NULL, " %u. Codebook\n", cb); if (get_bits(gb, 24) != 0x564342) { av_log(vc->avctx, AV_LOG_ERROR, " %u. Codebook setup data corrupt.\n", cb); ret = AVERROR_INVALIDDATA; goto error; } codebook_setup->dimensions=get_bits(gb, 16); if (codebook_setup->dimensions > 16 || codebook_setup->dimensions == 0) { av_log(vc->avctx, AV_LOG_ERROR, " %u. Codebook's dimension is invalid (%d).\n", cb, codebook_setup->dimensions); ret = AVERROR_INVALIDDATA; goto error; } entries = get_bits(gb, 24); if (entries > V_MAX_VLCS) { av_log(vc->avctx, AV_LOG_ERROR, " %u. Codebook has too many entries (%u).\n", cb, entries); ret = AVERROR_INVALIDDATA; goto error; } ordered = get_bits1(gb); av_dlog(NULL, " codebook_dimensions %d, codebook_entries %u\n", codebook_setup->dimensions, entries); if (!ordered) { unsigned ce, flag; unsigned sparse = get_bits1(gb); av_dlog(NULL, " not ordered \n"); if (sparse) { av_dlog(NULL, " sparse \n"); used_entries = 0; for (ce = 0; ce < entries; ++ce) { flag = get_bits1(gb); if (flag) { tmp_vlc_bits[ce] = get_bits(gb, 5) + 1; ++used_entries; } else tmp_vlc_bits[ce] = 0; } } else { av_dlog(NULL, " not sparse \n"); used_entries = entries; for (ce = 0; ce < entries; ++ce) tmp_vlc_bits[ce] = get_bits(gb, 5) + 1; } } else { unsigned current_entry = 0; unsigned current_length = get_bits(gb, 5) + 1; av_dlog(NULL, " ordered, current length: %u\n", current_length); //FIXME used_entries = entries; for (; current_entry < used_entries && current_length <= 32; ++current_length) { unsigned i, number; av_dlog(NULL, " number bits: %u ", ilog(entries - current_entry)); number = get_bits(gb, ilog(entries - current_entry)); av_dlog(NULL, " number: %u\n", number); for (i = current_entry; i < number+current_entry; ++i) if (i < used_entries) tmp_vlc_bits[i] = current_length; current_entry+=number; } if (current_entry>used_entries) { av_log(vc->avctx, AV_LOG_ERROR, " More codelengths than codes in codebook. \n"); ret = AVERROR_INVALIDDATA; goto error; } } codebook_setup->lookup_type = get_bits(gb, 4); av_dlog(NULL, " lookup type: %d : %s \n", codebook_setup->lookup_type, codebook_setup->lookup_type ? "vq" : "no lookup"); // If the codebook is used for (inverse) VQ, calculate codevectors. if (codebook_setup->lookup_type == 1) { unsigned i, j, k; unsigned codebook_lookup_values = ff_vorbis_nth_root(entries, codebook_setup->dimensions); float codebook_minimum_value = vorbisfloat2float(get_bits_long(gb, 32)); float codebook_delta_value = vorbisfloat2float(get_bits_long(gb, 32)); unsigned codebook_value_bits = get_bits(gb, 4) + 1; unsigned codebook_sequence_p = get_bits1(gb); av_dlog(NULL, " We expect %d numbers for building the codevectors. \n", codebook_lookup_values); av_dlog(NULL, " delta %f minmum %f \n", codebook_delta_value, codebook_minimum_value); for (i = 0; i < codebook_lookup_values; ++i) { codebook_multiplicands[i] = get_bits(gb, codebook_value_bits); av_dlog(NULL, " multiplicands*delta+minmum : %e \n", (float)codebook_multiplicands[i] * codebook_delta_value + codebook_minimum_value); av_dlog(NULL, " multiplicand %u\n", codebook_multiplicands[i]); } // Weed out unused vlcs and build codevector vector codebook_setup->codevectors = used_entries ? av_mallocz(used_entries * codebook_setup->dimensions * sizeof(*codebook_setup->codevectors)) : NULL; for (j = 0, i = 0; i < entries; ++i) { unsigned dim = codebook_setup->dimensions; if (tmp_vlc_bits[i]) { float last = 0.0; unsigned lookup_offset = i; av_dlog(vc->avctx, "Lookup offset %u ,", i); for (k = 0; k < dim; ++k) { unsigned multiplicand_offset = lookup_offset % codebook_lookup_values; codebook_setup->codevectors[j * dim + k] = codebook_multiplicands[multiplicand_offset] * codebook_delta_value + codebook_minimum_value + last; if (codebook_sequence_p) last = codebook_setup->codevectors[j * dim + k]; lookup_offset/=codebook_lookup_values; } tmp_vlc_bits[j] = tmp_vlc_bits[i]; av_dlog(vc->avctx, "real lookup offset %u, vector: ", j); for (k = 0; k < dim; ++k) av_dlog(vc->avctx, " %f ", codebook_setup->codevectors[j * dim + k]); av_dlog(vc->avctx, "\n"); ++j; } } if (j != used_entries) { av_log(vc->avctx, AV_LOG_ERROR, "Bug in codevector vector building code. \n"); ret = AVERROR_INVALIDDATA; goto error; } entries = used_entries; } else if (codebook_setup->lookup_type >= 2) { av_log(vc->avctx, AV_LOG_ERROR, "Codebook lookup type not supported. \n"); ret = AVERROR_INVALIDDATA; goto error; } // Initialize VLC table if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) { av_log(vc->avctx, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n"); ret = AVERROR_INVALIDDATA; goto error; } codebook_setup->maxdepth = 0; for (t = 0; t < entries; ++t) if (tmp_vlc_bits[t] >= codebook_setup->maxdepth) codebook_setup->maxdepth = tmp_vlc_bits[t]; if (codebook_setup->maxdepth > 3 * V_NB_BITS) codebook_setup->nb_bits = V_NB_BITS2; else codebook_setup->nb_bits = V_NB_BITS; codebook_setup->maxdepth = (codebook_setup->maxdepth+codebook_setup->nb_bits - 1) / codebook_setup->nb_bits; if ((ret = init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE))) { av_log(vc->avctx, AV_LOG_ERROR, " Error generating vlc tables. \n"); goto error; } } av_free(tmp_vlc_bits); av_free(tmp_vlc_codes); av_free(codebook_multiplicands); return 0; // Error: error: av_free(tmp_vlc_bits); av_free(tmp_vlc_codes); av_free(codebook_multiplicands); return ret; }


static int htab_save_later_pass(QEMUFile *f, sPAPREnvironment *spapr, int64_t max_ns) { bool final = max_ns < 0; int htabslots = HTAB_SIZE(spapr) / HASH_PTE_SIZE_64; int examined = 0, sent = 0; int index = spapr->htab_save_index; int64_t starttime = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); assert(!spapr->htab_first_pass); do { int chunkstart, invalidstart; /* Consume non-dirty HPTEs */ while ((index < htabslots) && !HPTE_DIRTY(HPTE(spapr->htab, index))) { index++; examined++; } chunkstart = index; /* Consume valid dirty HPTEs */ while ((index < htabslots) && HPTE_DIRTY(HPTE(spapr->htab, index)) && HPTE_VALID(HPTE(spapr->htab, index))) { CLEAN_HPTE(HPTE(spapr->htab, index)); index++; examined++; } invalidstart = index; /* Consume invalid dirty HPTEs */ while ((index < htabslots) && HPTE_DIRTY(HPTE(spapr->htab, index)) && !HPTE_VALID(HPTE(spapr->htab, index))) { CLEAN_HPTE(HPTE(spapr->htab, index)); index++; examined++; } if (index > chunkstart) { int n_valid = invalidstart - chunkstart; int n_invalid = index - invalidstart; qemu_put_be32(f, chunkstart); qemu_put_be16(f, n_valid); qemu_put_be16(f, n_invalid); qemu_put_buffer(f, HPTE(spapr->htab, chunkstart), HASH_PTE_SIZE_64 * n_valid); sent += index - chunkstart; if (!final && (qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - starttime) > max_ns) { break; } } if (examined >= htabslots) { break; } if (index >= htabslots) { assert(index == htabslots); index = 0; } } while ((examined < htabslots) && (!qemu_file_rate_limit(f) || final)); if (index >= htabslots) { assert(index == htabslots); index = 0; } spapr->htab_save_index = index; return (examined >= htabslots) && (sent == 0) ? 1 : 0; }


static abi_long do_socket(int domain, int type, int protocol) { int target_type = type; int ret; ret = target_to_host_sock_type(&type); if (ret) { return ret; } if (domain == PF_NETLINK) return -TARGET_EAFNOSUPPORT; if (domain == AF_PACKET || (domain == AF_INET && type == SOCK_PACKET)) { protocol = tswap16(protocol); } ret = get_errno(socket(domain, type, protocol)); if (ret >= 0) { ret = sock_flags_fixup(ret, target_type); if (type == SOCK_PACKET) { /* Manage an obsolete case : * if socket type is SOCK_PACKET, bind by name */ fd_trans_register(ret, &target_packet_trans); } } return ret; }


int kvmppc_get_hypercall(CPUPPCState *env, uint8_t *buf, int buf_len) { PowerPCCPU *cpu = ppc_env_get_cpu(env); CPUState *cs = CPU(cpu); uint32_t *hc = (uint32_t*)buf; struct kvm_ppc_pvinfo pvinfo; if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) && !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, &pvinfo)) { memcpy(buf, pvinfo.hcall, buf_len); return 0; } /* * Fallback to always fail hypercalls: * * li r3, -1 * nop * nop * nop */ hc[0] = 0x3860ffff; hc[1] = 0x60000000; hc[2] = 0x60000000; hc[3] = 0x60000000; return 0; }


void process_incoming_migration(QEMUFile *f) { if (qemu_loadvm_state(f) < 0) { fprintf(stderr, "load of migration failed\n"); exit(0); } qemu_announce_self(); DPRINTF("successfully loaded vm state\n"); incoming_expected = false; if (autostart) { vm_start(); } else { runstate_set(RSTATE_PRE_LAUNCH); } }


static int rv40_decode_mb_info(RV34DecContext *r) { MpegEncContext *s = &r->s; GetBitContext *gb = &s->gb; int q, i; int prev_type = 0; int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int blocks[RV34_MB_TYPES] = {0}; int count = 0; if(!r->s.mb_skip_run) r->s.mb_skip_run = svq3_get_ue_golomb(gb) + 1; if(--r->s.mb_skip_run) return RV34_MB_SKIP; if(r->avail_cache[6-1]) blocks[r->mb_type[mb_pos - 1]]++; if(r->avail_cache[6-4]){ blocks[r->mb_type[mb_pos - s->mb_stride]]++; if(r->avail_cache[6-2]) blocks[r->mb_type[mb_pos - s->mb_stride + 1]]++; if(r->avail_cache[6-5]) blocks[r->mb_type[mb_pos - s->mb_stride - 1]]++; } for(i = 0; i < RV34_MB_TYPES; i++){ if(blocks[i] > count){ count = blocks[i]; prev_type = i; } } if(s->pict_type == AV_PICTURE_TYPE_P){ prev_type = block_num_to_ptype_vlc_num[prev_type]; q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); if(q < PBTYPE_ESCAPE) return q; q = get_vlc2(gb, ptype_vlc[prev_type].table, PTYPE_VLC_BITS, 1); av_log(s->avctx, AV_LOG_ERROR, "Dquant for P-frame\n"); }else{ prev_type = block_num_to_btype_vlc_num[prev_type]; q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); if(q < PBTYPE_ESCAPE) return q; q = get_vlc2(gb, btype_vlc[prev_type].table, BTYPE_VLC_BITS, 1); av_log(s->avctx, AV_LOG_ERROR, "Dquant for B-frame\n"); } return 0; }


static inline void RENAME(yvu9_to_yuy2)(const uint8_t *src1, const uint8_t *src2, const uint8_t *src3, uint8_t *dst, long width, long height, long srcStride1, long srcStride2, long srcStride3, long dstStride) { x86_reg x; long y,w,h; w=width/2; h=height; for (y=0;y<h;y++) { const uint8_t* yp=src1+srcStride1*y; const uint8_t* up=src2+srcStride2*(y>>2); const uint8_t* vp=src3+srcStride3*(y>>2); uint8_t* d=dst+dstStride*y; x=0; #if COMPILE_TEMPLATE_MMX for (;x<w-7;x+=8) { __asm__ volatile( PREFETCH" 32(%1, %0) \n\t" PREFETCH" 32(%2, %0) \n\t" PREFETCH" 32(%3, %0) \n\t" "movq (%1, %0, 4), %%mm0 \n\t" /* Y0Y1Y2Y3Y4Y5Y6Y7 */ "movq (%2, %0), %%mm1 \n\t" /* U0U1U2U3U4U5U6U7 */ "movq (%3, %0), %%mm2 \n\t" /* V0V1V2V3V4V5V6V7 */ "movq %%mm0, %%mm3 \n\t" /* Y0Y1Y2Y3Y4Y5Y6Y7 */ "movq %%mm1, %%mm4 \n\t" /* U0U1U2U3U4U5U6U7 */ "movq %%mm2, %%mm5 \n\t" /* V0V1V2V3V4V5V6V7 */ "punpcklbw %%mm1, %%mm1 \n\t" /* U0U0 U1U1 U2U2 U3U3 */ "punpcklbw %%mm2, %%mm2 \n\t" /* V0V0 V1V1 V2V2 V3V3 */ "punpckhbw %%mm4, %%mm4 \n\t" /* U4U4 U5U5 U6U6 U7U7 */ "punpckhbw %%mm5, %%mm5 \n\t" /* V4V4 V5V5 V6V6 V7V7 */ "movq %%mm1, %%mm6 \n\t" "punpcklbw %%mm2, %%mm1 \n\t" /* U0V0 U0V0 U1V1 U1V1*/ "punpcklbw %%mm1, %%mm0 \n\t" /* Y0U0 Y1V0 Y2U0 Y3V0*/ "punpckhbw %%mm1, %%mm3 \n\t" /* Y4U1 Y5V1 Y6U1 Y7V1*/ MOVNTQ" %%mm0, (%4, %0, 8) \n\t" MOVNTQ" %%mm3, 8(%4, %0, 8) \n\t" "punpckhbw %%mm2, %%mm6 \n\t" /* U2V2 U2V2 U3V3 U3V3*/ "movq 8(%1, %0, 4), %%mm0 \n\t" "movq %%mm0, %%mm3 \n\t" "punpcklbw %%mm6, %%mm0 \n\t" /* Y U2 Y V2 Y U2 Y V2*/ "punpckhbw %%mm6, %%mm3 \n\t" /* Y U3 Y V3 Y U3 Y V3*/ MOVNTQ" %%mm0, 16(%4, %0, 8) \n\t" MOVNTQ" %%mm3, 24(%4, %0, 8) \n\t" "movq %%mm4, %%mm6 \n\t" "movq 16(%1, %0, 4), %%mm0 \n\t" "movq %%mm0, %%mm3 \n\t" "punpcklbw %%mm5, %%mm4 \n\t" "punpcklbw %%mm4, %%mm0 \n\t" /* Y U4 Y V4 Y U4 Y V4*/ "punpckhbw %%mm4, %%mm3 \n\t" /* Y U5 Y V5 Y U5 Y V5*/ MOVNTQ" %%mm0, 32(%4, %0, 8) \n\t" MOVNTQ" %%mm3, 40(%4, %0, 8) \n\t" "punpckhbw %%mm5, %%mm6 \n\t" "movq 24(%1, %0, 4), %%mm0 \n\t" "movq %%mm0, %%mm3 \n\t" "punpcklbw %%mm6, %%mm0 \n\t" /* Y U6 Y V6 Y U6 Y V6*/ "punpckhbw %%mm6, %%mm3 \n\t" /* Y U7 Y V7 Y U7 Y V7*/ MOVNTQ" %%mm0, 48(%4, %0, 8) \n\t" MOVNTQ" %%mm3, 56(%4, %0, 8) \n\t" : "+r" (x) : "r"(yp), "r" (up), "r"(vp), "r"(d) :"memory"); } #endif for (; x<w; x++) { const long x2 = x<<2; d[8*x+0] = yp[x2]; d[8*x+1] = up[x]; d[8*x+2] = yp[x2+1]; d[8*x+3] = vp[x]; d[8*x+4] = yp[x2+2]; d[8*x+5] = up[x]; d[8*x+6] = yp[x2+3]; d[8*x+7] = vp[x]; } } #if COMPILE_TEMPLATE_MMX __asm__( EMMS" \n\t" SFENCE" \n\t" ::: "memory" ); #endif }


static int pcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; PCMDecode *s = avctx->priv_data; int sample_size, c, n, i; uint8_t *samples; const uint8_t *src, *src8, *src2[MAX_CHANNELS]; int32_t *dst_int32_t; samples = data; src = buf; if (avctx->sample_fmt!=avctx->codec->sample_fmts[0]) { av_log(avctx, AV_LOG_ERROR, "invalid sample_fmt\n"); return -1; } if(avctx->channels <= 0 || avctx->channels > MAX_CHANNELS){ av_log(avctx, AV_LOG_ERROR, "PCM channels out of bounds\n"); return -1; } sample_size = av_get_bits_per_sample(avctx->codec_id)/8; /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */ if (CODEC_ID_PCM_DVD == avctx->codec_id) /* 2 samples are interleaved per block in PCM_DVD */ sample_size = avctx->bits_per_coded_sample * 2 / 8; else if (avctx->codec_id == CODEC_ID_PCM_LXF) /* we process 40-bit blocks per channel for LXF */ sample_size = 5; if (sample_size == 0) { av_log(avctx, AV_LOG_ERROR, "Invalid sample_size\n"); return AVERROR(EINVAL); } n = avctx->channels * sample_size; if(n && buf_size % n){ if (buf_size < n) { av_log(avctx, AV_LOG_ERROR, "invalid PCM packet\n"); return -1; }else buf_size -= buf_size % n; } buf_size= FFMIN(buf_size, *data_size/2); n = buf_size/sample_size; switch(avctx->codec->id) { case CODEC_ID_PCM_U32LE: DECODE(32, le32, src, samples, n, 0, 0x80000000) break; case CODEC_ID_PCM_U32BE: DECODE(32, be32, src, samples, n, 0, 0x80000000) break; case CODEC_ID_PCM_S24LE: DECODE(32, le24, src, samples, n, 8, 0) break; case CODEC_ID_PCM_S24BE: DECODE(32, be24, src, samples, n, 8, 0) break; case CODEC_ID_PCM_U24LE: DECODE(32, le24, src, samples, n, 8, 0x800000) break; case CODEC_ID_PCM_U24BE: DECODE(32, be24, src, samples, n, 8, 0x800000) break; case CODEC_ID_PCM_S24DAUD: for(;n>0;n--) { uint32_t v = bytestream_get_be24(&src); v >>= 4; // sync flags are here AV_WN16A(samples, av_reverse[(v >> 8) & 0xff] + (av_reverse[v & 0xff] << 8)); samples += 2; } break; case CODEC_ID_PCM_S16LE_PLANAR: n /= avctx->channels; for(c=0;c<avctx->channels;c++) src2[c] = &src[c*n*2]; for(;n>0;n--) for(c=0;c<avctx->channels;c++) { AV_WN16A(samples, bytestream_get_le16(&src2[c])); samples += 2; } src = src2[avctx->channels-1]; break; case CODEC_ID_PCM_U16LE: DECODE(16, le16, src, samples, n, 0, 0x8000) break; case CODEC_ID_PCM_U16BE: DECODE(16, be16, src, samples, n, 0, 0x8000) break; case CODEC_ID_PCM_S8: for(;n>0;n--) { *samples++ = *src++ + 128; } break; #if HAVE_BIGENDIAN case CODEC_ID_PCM_F64LE: DECODE(64, le64, src, samples, n, 0, 0) break; case CODEC_ID_PCM_S32LE: case CODEC_ID_PCM_F32LE: DECODE(32, le32, src, samples, n, 0, 0) break; case CODEC_ID_PCM_S16LE: DECODE(16, le16, src, samples, n, 0, 0) break; case CODEC_ID_PCM_F64BE: case CODEC_ID_PCM_F32BE: case CODEC_ID_PCM_S32BE: case CODEC_ID_PCM_S16BE: #else case CODEC_ID_PCM_F64BE: DECODE(64, be64, src, samples, n, 0, 0) break; case CODEC_ID_PCM_F32BE: case CODEC_ID_PCM_S32BE: DECODE(32, be32, src, samples, n, 0, 0) break; case CODEC_ID_PCM_S16BE: DECODE(16, be16, src, samples, n, 0, 0) break; case CODEC_ID_PCM_F64LE: case CODEC_ID_PCM_F32LE: case CODEC_ID_PCM_S32LE: case CODEC_ID_PCM_S16LE: #endif /* HAVE_BIGENDIAN */ case CODEC_ID_PCM_U8: memcpy(samples, src, n*sample_size); src += n*sample_size; samples += n * sample_size; break; case CODEC_ID_PCM_ZORK: for(;n>0;n--) { int x= *src++; if(x&128) x-= 128; else x = -x; AV_WN16A(samples, x << 8); samples += 2; } break; case CODEC_ID_PCM_ALAW: case CODEC_ID_PCM_MULAW: for(;n>0;n--) { AV_WN16A(samples, s->table[*src++]); samples += 2; } break; case CODEC_ID_PCM_DVD: dst_int32_t = data; n /= avctx->channels; switch (avctx->bits_per_coded_sample) { case 20: while (n--) { c = avctx->channels; src8 = src + 4*c; while (c--) { *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8 &0xf0) << 8); *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++ &0x0f) << 12); } src = src8; } break; case 24: while (n--) { c = avctx->channels; src8 = src + 4*c; while (c--) { *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); *dst_int32_t++ = (bytestream_get_be16(&src) << 16) + ((*src8++) << 8); } src = src8; } break; default: av_log(avctx, AV_LOG_ERROR, "PCM DVD unsupported sample depth\n"); return -1; } samples = (uint8_t *) dst_int32_t; break; case CODEC_ID_PCM_LXF: dst_int32_t = data; n /= avctx->channels; //unpack and de-planerize for (i = 0; i < n; i++) { for (c = 0, src8 = src + i*5; c < avctx->channels; c++, src8 += n*5) { //extract low 20 bits and expand to 32 bits *dst_int32_t++ = (src8[2] << 28) | (src8[1] << 20) | (src8[0] << 12) | ((src8[2] & 0xF) << 8) | src8[1]; } for (c = 0, src8 = src + i*5; c < avctx->channels; c++, src8 += n*5) { //extract high 20 bits and expand to 32 bits *dst_int32_t++ = (src8[4] << 24) | (src8[3] << 16) | ((src8[2] & 0xF0) << 8) | (src8[4] << 4) | (src8[3] >> 4); } } src += n * avctx->channels * 5; samples = (uint8_t *) dst_int32_t; break; default: return -1; } *data_size = samples - (uint8_t *)data; return src - buf; }


static int parse_presentation_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int64_t pts) { PGSSubContext *ctx = avctx->priv_data; int x, y, ret; int w = bytestream_get_be16(&buf); int h = bytestream_get_be16(&buf); ctx->presentation.pts = pts; av_dlog(avctx, "Video Dimensions %dx%d\n", w, h); ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; /* Skip 1 bytes of unknown, frame rate? */ buf++; ctx->presentation.id_number = bytestream_get_be16(&buf); /* * Skip 3 bytes of unknown: * state * palette_update_flag (0x80), * palette_id_to_use, */ buf += 3; ctx->presentation.object_number = bytestream_get_byte(&buf); ctx->presentation.composition_flag = 0; if (!ctx->presentation.object_number) return 0; /* * Skip 3 bytes of unknown: * object_id_ref (2 bytes), * window_id_ref, */ buf += 3; ctx->presentation.composition_flag = bytestream_get_byte(&buf); x = bytestream_get_be16(&buf); y = bytestream_get_be16(&buf); /* TODO If cropping, cropping_x, cropping_y, cropping_width, cropping_height (all 2 bytes).*/ av_dlog(avctx, "Subtitle Placement x=%d, y=%d\n", x, y); if (x > avctx->width || y > avctx->height) { av_log(avctx, AV_LOG_ERROR, "Subtitle out of video bounds. x = %d, y = %d, video width = %d, video height = %d.\n", x, y, avctx->width, avctx->height); x = 0; y = 0; } /* Fill in dimensions */ ctx->presentation.x = x; ctx->presentation.y = y; return 0; }