static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) { RTPMuxContext *s = s1->priv_data; AVStream *st = s1->streams[0]; int rtcp_bytes; int size= pkt->size; av_dlog(s1, "%d: write len=%d\n", pkt->stream_index, size); rtcp_bytes = ((s->octet_count - s->last_octet_count) * RTCP_TX_RATIO_NUM) / RTCP_TX_RATIO_DEN; if ((s->first_packet || ((rtcp_bytes >= RTCP_SR_SIZE) && (ff_ntp_time() - s->last_rtcp_ntp_time > 5000000))) && !(s->flags & FF_RTP_FLAG_SKIP_RTCP)) { rtcp_send_sr(s1, ff_ntp_time(), 0); s->last_octet_count = s->octet_count; s->first_packet = 0; } s->cur_timestamp = s->base_timestamp + pkt->pts; switch(st->codec->codec_id) { case AV_CODEC_ID_PCM_MULAW: case AV_CODEC_ID_PCM_ALAW: case AV_CODEC_ID_PCM_U8: case AV_CODEC_ID_PCM_S8: return rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels); case AV_CODEC_ID_PCM_U16BE: case AV_CODEC_ID_PCM_U16LE: case AV_CODEC_ID_PCM_S16BE: case AV_CODEC_ID_PCM_S16LE: return rtp_send_samples(s1, pkt->data, size, 16 * st->codec->channels); case AV_CODEC_ID_ADPCM_G722: /* The actual sample size is half a byte per sample, but since the * stream clock rate is 8000 Hz while the sample rate is 16000 Hz, * the correct parameter for send_samples_bits is 8 bits per stream * clock. */ return rtp_send_samples(s1, pkt->data, size, 8 * st->codec->channels); case AV_CODEC_ID_ADPCM_G726: return rtp_send_samples(s1, pkt->data, size, st->codec->bits_per_coded_sample * st->codec->channels); case AV_CODEC_ID_MP2: case AV_CODEC_ID_MP3: rtp_send_mpegaudio(s1, pkt->data, size); break; case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: ff_rtp_send_mpegvideo(s1, pkt->data, size); break; case AV_CODEC_ID_AAC: if (s->flags & FF_RTP_FLAG_MP4A_LATM) ff_rtp_send_latm(s1, pkt->data, size); else ff_rtp_send_aac(s1, pkt->data, size); break; case AV_CODEC_ID_AMR_NB: case AV_CODEC_ID_AMR_WB: ff_rtp_send_amr(s1, pkt->data, size); break; case AV_CODEC_ID_MPEG2TS: rtp_send_mpegts_raw(s1, pkt->data, size); break; case AV_CODEC_ID_H264: ff_rtp_send_h264(s1, pkt->data, size); break; case AV_CODEC_ID_H261: ff_rtp_send_h261(s1, pkt->data, size); break; case AV_CODEC_ID_H263: if (s->flags & FF_RTP_FLAG_RFC2190) { int mb_info_size = 0; const uint8_t *mb_info = av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, &mb_info_size); ff_rtp_send_h263_rfc2190(s1, pkt->data, size, mb_info, mb_info_size); break; } /* Fallthrough */ case AV_CODEC_ID_H263P: ff_rtp_send_h263(s1, pkt->data, size); break; case AV_CODEC_ID_HEVC: ff_rtp_send_hevc(s1, pkt->data, size); break; case AV_CODEC_ID_VORBIS: case AV_CODEC_ID_THEORA: ff_rtp_send_xiph(s1, pkt->data, size); break; case AV_CODEC_ID_VP8: ff_rtp_send_vp8(s1, pkt->data, size); break; case AV_CODEC_ID_ILBC: rtp_send_ilbc(s1, pkt->data, size); break; case AV_CODEC_ID_MJPEG: ff_rtp_send_jpeg(s1, pkt->data, size); break; case AV_CODEC_ID_OPUS: if (size > s->max_payload_size) { av_log(s1, AV_LOG_ERROR, "Packet size %d too large for max RTP payload size %d\n", size, s->max_payload_size); return AVERROR(EINVAL); } /* Intentional fallthrough */ default: /* better than nothing : send the codec raw data */ rtp_send_raw(s1, pkt->data, size); break; } return 0; }


static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) { int sx, sy; int dx, dy; int width, height; int depth; int notify = 0; depth = s->get_bpp((VGAState *)s) / 8; s->get_resolution((VGAState *)s, &width, &height); /* extra x, y */ sx = (src % (width * depth)) / depth; sy = (src / (width * depth)); dx = (dst % (width *depth)) / depth; dy = (dst / (width * depth)); /* normalize width */ w /= depth; /* if we're doing a backward copy, we have to adjust our x/y to be the upper left corner (instead of the lower right corner) */ if (s->cirrus_blt_dstpitch < 0) { sx -= (s->cirrus_blt_width / depth) - 1; dx -= (s->cirrus_blt_width / depth) - 1; sy -= s->cirrus_blt_height - 1; dy -= s->cirrus_blt_height - 1; } /* are we in the visible portion of memory? */ if (sx >= 0 && sy >= 0 && dx >= 0 && dy >= 0 && (sx + w) <= width && (sy + h) <= height && (dx + w) <= width && (dy + h) <= height) { notify = 1; } /* make to sure only copy if it's a plain copy ROP */ if (*s->cirrus_rop != cirrus_bitblt_rop_fwd_src && *s->cirrus_rop != cirrus_bitblt_rop_bkwd_src) notify = 0; /* we have to flush all pending changes so that the copy is generated at the appropriate moment in time */ if (notify) vga_hw_update(); (*s->cirrus_rop) (s, s->vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), s->vram_ptr + (s->cirrus_blt_srcaddr & s->cirrus_addr_mask), s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, s->cirrus_blt_width, s->cirrus_blt_height); if (notify) qemu_console_copy(s->ds, sx, sy, dx, dy, s->cirrus_blt_width / depth, s->cirrus_blt_height); /* we don't have to notify the display that this portion has changed since qemu_console_copy implies this */ if (!notify) cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, s->cirrus_blt_dstpitch, s->cirrus_blt_width, s->cirrus_blt_height); }


void vnc_write(VncState *vs, const void *data, size_t len) { buffer_reserve(&vs->output, len); if (buffer_empty(&vs->output)) { qemu_set_fd_handler2(vs->csock, NULL, vnc_client_read, vnc_client_write, vs); } buffer_append(&vs->output, data, len); }


static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr, const char* strmmu, CPUState *env1) { unsigned int i; target_ulong mask; for (i = 0; i < 64; i++) { if (TTE_IS_VALID(tlb[i].tte)) { mask = 0xffffffffffffe000ULL; mask <<= 3 * ((tlb[i].tte >> 61) & 3); if ((demap_addr & mask) == (tlb[i].tag & mask)) { replace_tlb_entry(&tlb[i], 0, 0, env1); #ifdef DEBUG_MMU DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i); dump_mmu(env1); #endif } //return; } } }


static void vda_decoder_callback(void *vda_hw_ctx, CFDictionaryRef user_info, OSStatus status, uint32_t infoFlags, CVImageBufferRef image_buffer) { struct vda_context *vda_ctx = vda_hw_ctx; if (!image_buffer) return; if (vda_ctx->cv_pix_fmt_type != CVPixelBufferGetPixelFormatType(image_buffer)) return; vda_ctx->cv_buffer = CVPixelBufferRetain(image_buffer); }


static int wc3_read_close(AVFormatContext *s) { Wc3DemuxContext *wc3 = s->priv_data; av_free(wc3->palettes); return 0; }


static int64_t cpu_get_clock_locked(void) { int64_t ti; if (!timers_state.cpu_ticks_enabled) { ti = timers_state.cpu_clock_offset; } else { ti = get_clock(); ti += timers_state.cpu_clock_offset; } return ti; }


int main(void){ int i,k; AVTreeNode *root= NULL, *node=NULL; for(i=0; i<10000; i++){ int j= (random()%86294); if(check(root) > 999){ av_log(NULL, AV_LOG_ERROR, "FATAL error %d\n", i); print(root, 0); return -1; } av_log(NULL, AV_LOG_ERROR, "inserting %4d\n", j); if(!node) node= av_mallocz(av_tree_node_size); av_tree_insert(&root, (void*)(j+1), cmp, &node); j= (random()%86294); k= av_tree_find(root, (void*)(j+1), cmp, NULL); if(k){ AVTreeNode *node2=NULL; av_log(NULL, AV_LOG_ERROR, "removing %4d\n", j); av_tree_insert(&root, (void*)(j+1), cmp, &node2); k= av_tree_find(root, (void*)(j+1), cmp, NULL); if(k) av_log(NULL, AV_LOG_ERROR, "removial failure %d\n", i); } } return 0; }


static void qpeg_decode_inter(uint8_t *src, uint8_t *dst, int size, int stride, int width, int height, int delta, uint8_t *ctable, uint8_t *refdata) { int i, j; int code; int filled = 0; uint8_t *blkdata; /* copy prev frame */ for(i = 0; i < height; i++) memcpy(refdata + (i * width), dst + (i * stride), width); blkdata = src - 0x86; height--; dst = dst + height * stride; while(size > 0) { code = *src++; size--; if(delta) { /* motion compensation */ while((code & 0xF0) == 0xF0) { if(delta == 1) { int me_idx; int me_w, me_h, me_x, me_y; uint8_t *me_plane; int corr, val; /* get block size by index */ me_idx = code & 0xF; me_w = qpeg_table_w[me_idx]; me_h = qpeg_table_h[me_idx]; /* extract motion vector */ corr = *src++; size--; val = corr >> 4; if(val > 7) val -= 16; me_x = val; val = corr & 0xF; if(val > 7) val -= 16; me_y = val; /* do motion compensation */ me_plane = refdata + (filled + me_x) + (height - me_y) * width; for(j = 0; j < me_h; j++) { for(i = 0; i < me_w; i++) dst[filled + i - (j * stride)] = me_plane[i - (j * width)]; } } code = *src++; size--; } } if(code == 0xE0) /* end-of-picture code */ break; if(code > 0xE0) { /* run code: 0xE1..0xFF */ int p; code &= 0x1F; p = *src++; size--; for(i = 0; i <= code; i++) { dst[filled++] = p; if(filled >= width) { filled = 0; dst -= stride; height--; } } } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ code &= 0x1F; for(i = 0; i <= code; i++) { dst[filled++] = *src++; if(filled >= width) { filled = 0; dst -= stride; height--; } } size -= code + 1; } else if(code >= 0x80) { /* skip code: 0x80..0xBF */ int skip; code &= 0x3F; /* codes 0x80 and 0x81 are actually escape codes, skip value minus constant is in the next byte */ if(!code) skip = (*src++) + 64; else if(code == 1) skip = (*src++) + 320; else skip = code; filled += skip; while( filled >= width) { filled -= width; dst -= stride; height--; } } else { /* zero code treated as one-pixel skip */ if(code) dst[filled++] = ctable[code & 0x7F]; else filled++; if(filled >= width) { filled = 0; dst -= stride; height--; } } } }


static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model) { unsigned int i; const sparc_def_t *def = NULL; char *s = strdup(cpu_model); char *featurestr, *name = strtok(s, ","); uint32_t plus_features = 0; uint32_t minus_features = 0; uint64_t iu_version; uint32_t fpu_version, mmu_version, nwindows; for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) { if (strcasecmp(name, sparc_defs[i].name) == 0) { def = &sparc_defs[i]; } } if (!def) { goto error; } memcpy(cpu_def, def, sizeof(*def)); featurestr = strtok(NULL, ","); while (featurestr) { char *val; if (featurestr[0] == '+') { add_flagname_to_bitmaps(featurestr + 1, &plus_features); } else if (featurestr[0] == '-') { add_flagname_to_bitmaps(featurestr + 1, &minus_features); } else if ((val = strchr(featurestr, '='))) { *val = 0; val++; if (!strcmp(featurestr, "iu_version")) { char *err; iu_version = strtoll(val, &err, 0); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } cpu_def->iu_version = iu_version; #ifdef DEBUG_FEATURES fprintf(stderr, "iu_version %" PRIx64 "\n", iu_version); #endif } else if (!strcmp(featurestr, "fpu_version")) { char *err; fpu_version = strtol(val, &err, 0); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } cpu_def->fpu_version = fpu_version; #ifdef DEBUG_FEATURES fprintf(stderr, "fpu_version %x\n", fpu_version); #endif } else if (!strcmp(featurestr, "mmu_version")) { char *err; mmu_version = strtol(val, &err, 0); if (!*val || *err) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } cpu_def->mmu_version = mmu_version; #ifdef DEBUG_FEATURES fprintf(stderr, "mmu_version %x\n", mmu_version); #endif } else if (!strcmp(featurestr, "nwindows")) { char *err; nwindows = strtol(val, &err, 0); if (!*val || *err || nwindows > MAX_NWINDOWS || nwindows < MIN_NWINDOWS) { fprintf(stderr, "bad numerical value %s\n", val); goto error; } cpu_def->nwindows = nwindows; #ifdef DEBUG_FEATURES fprintf(stderr, "nwindows %d\n", nwindows); #endif } else { fprintf(stderr, "unrecognized feature %s\n", featurestr); goto error; } } else { fprintf(stderr, "feature string `%s' not in format " "(+feature|-feature|feature=xyz)\n", featurestr); goto error; } featurestr = strtok(NULL, ","); } cpu_def->features |= plus_features; cpu_def->features &= ~minus_features; #ifdef DEBUG_FEATURES print_features(stderr, fprintf, cpu_def->features, NULL); #endif free(s); return 0; error: free(s); return -1; }


void spapr_drc_reset(sPAPRDRConnector *drc) { trace_spapr_drc_reset(spapr_drc_index(drc)); g_free(drc->ccs); drc->ccs = NULL; /* immediately upon reset we can safely assume DRCs whose devices * are pending removal can be safely removed. */ if (drc->awaiting_release) { spapr_drc_release(drc); } drc->awaiting_allocation = false; if (drc->dev) { /* A device present at reset is coldplugged */ drc->isolation_state = SPAPR_DR_ISOLATION_STATE_UNISOLATED; if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) { drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_USABLE; } drc->dr_indicator = SPAPR_DR_INDICATOR_ACTIVE; } else { /* Otherwise device is absent, but might be hotplugged */ drc->isolation_state = SPAPR_DR_ISOLATION_STATE_ISOLATED; if (spapr_drc_type(drc) != SPAPR_DR_CONNECTOR_TYPE_PCI) { drc->allocation_state = SPAPR_DR_ALLOCATION_STATE_UNUSABLE; } drc->dr_indicator = SPAPR_DR_INDICATOR_INACTIVE; } }


static void clipper_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *cpu_model = machine->cpu_model; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; AlphaCPU *cpus[4]; PCIBus *pci_bus; ISABus *isa_bus; qemu_irq rtc_irq; long size, i; const char *palcode_filename; uint64_t palcode_entry, palcode_low, palcode_high; uint64_t kernel_entry, kernel_low, kernel_high; /* Create up to 4 cpus. */ memset(cpus, 0, sizeof(cpus)); for (i = 0; i < smp_cpus; ++i) { cpus[i] = cpu_alpha_init(cpu_model ? cpu_model : "ev67"); } cpus[0]->env.trap_arg0 = ram_size; cpus[0]->env.trap_arg1 = 0; cpus[0]->env.trap_arg2 = smp_cpus; /* Init the chipset. */ pci_bus = typhoon_init(ram_size, &isa_bus, &rtc_irq, cpus, clipper_pci_map_irq); /* Since we have an SRM-compatible PALcode, use the SRM epoch. */ rtc_init(isa_bus, 1900, rtc_irq); pit_init(isa_bus, 0x40, 0, NULL); isa_create_simple(isa_bus, "i8042"); /* VGA setup. Don't bother loading the bios. */ pci_vga_init(pci_bus); /* Serial code setup. */ serial_hds_isa_init(isa_bus, MAX_SERIAL_PORTS); /* Network setup. e1000 is good enough, failing Tulip support. */ for (i = 0; i < nb_nics; i++) { pci_nic_init_nofail(&nd_table[i], pci_bus, "e1000", NULL); } /* IDE disk setup. */ { DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; ide_drive_get(hd, ARRAY_SIZE(hd)); pci_cmd646_ide_init(pci_bus, hd, 0); } /* Load PALcode. Given that this is not "real" cpu palcode, but one explicitly written for the emulation, we might as well load it directly from and ELF image. */ palcode_filename = (bios_name ? bios_name : "palcode-clipper"); palcode_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, palcode_filename); if (palcode_filename == NULL) { hw_error("no palcode provided\n"); exit(1); } size = load_elf(palcode_filename, cpu_alpha_superpage_to_phys, NULL, &palcode_entry, &palcode_low, &palcode_high, 0, EM_ALPHA, 0); if (size < 0) { hw_error("could not load palcode '%s'\n", palcode_filename); exit(1); } /* Start all cpus at the PALcode RESET entry point. */ for (i = 0; i < smp_cpus; ++i) { cpus[i]->env.pal_mode = 1; cpus[i]->env.pc = palcode_entry; cpus[i]->env.palbr = palcode_entry; } /* Load a kernel. */ if (kernel_filename) { uint64_t param_offset; size = load_elf(kernel_filename, cpu_alpha_superpage_to_phys, NULL, &kernel_entry, &kernel_low, &kernel_high, 0, EM_ALPHA, 0); if (size < 0) { hw_error("could not load kernel '%s'\n", kernel_filename); exit(1); } cpus[0]->env.trap_arg1 = kernel_entry; param_offset = kernel_low - 0x6000; if (kernel_cmdline) { pstrcpy_targphys("cmdline", param_offset, 0x100, kernel_cmdline); } if (initrd_filename) { long initrd_base, initrd_size; initrd_size = get_image_size(initrd_filename); if (initrd_size < 0) { hw_error("could not load initial ram disk '%s'\n", initrd_filename); exit(1); } /* Put the initrd image as high in memory as possible. */ initrd_base = (ram_size - initrd_size) & TARGET_PAGE_MASK; load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); address_space_stq(&address_space_memory, param_offset + 0x100, initrd_base + 0xfffffc0000000000ULL, MEMTXATTRS_UNSPECIFIED, NULL); address_space_stq(&address_space_memory, param_offset + 0x108, initrd_size, MEMTXATTRS_UNSPECIFIED, NULL); } } }


ogm_dshow_header(AVFormatContext *s, int idx) { struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + idx; AVStream *st = s->streams[idx]; uint8_t *p = os->buf + os->pstart; uint32_t t; if(!(*p & 1)) return 0; if(*p != 1) return 1; t = AV_RL32(p + 96); if(t == 0x05589f80){ st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(p + 68)); avpriv_set_pts_info(st, 64, AV_RL64(p + 164), 10000000); st->codec->width = AV_RL32(p + 176); st->codec->height = AV_RL32(p + 180); } else if(t == 0x05589f81){ st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, AV_RL16(p + 124)); st->codec->channels = AV_RL16(p + 126); st->codec->sample_rate = AV_RL32(p + 128); st->codec->bit_rate = AV_RL32(p + 132) * 8; } return 1; }


void qemu_bh_schedule(QEMUBH *bh) { AioContext *ctx; if (bh->scheduled) return; ctx = bh->ctx; bh->idle = 0; /* Make sure that: * 1. idle & any writes needed by the callback are done before the * locations are read in the aio_bh_poll. * 2. ctx is loaded before scheduled is set and the callback has a chance * to execute. */ smp_mb(); bh->scheduled = 1; aio_notify(ctx); }


static void emulate_spapr_hypercall(CPUPPCState *env) { env->gpr[3] = spapr_hypercall(env, env->gpr[3], &env->gpr[4]); }


static struct pathelem *add_dir_maybe(struct pathelem *path) { DIR *dir; if ((dir = opendir(path->pathname)) != NULL) { struct dirent *dirent; while ((dirent = readdir(dir)) != NULL) { if (!streq(dirent->d_name,".") && !streq(dirent->d_name,"..")){ path = add_entry(path, dirent->d_name); } } closedir(dir); } return path; }


static void test_qemu_strtoul_whitespace(void) { const char *str = " \t "; char f = 'X'; const char *endptr = &f; unsigned long res = 999; int err; err = qemu_strtoul(str, &endptr, 0, &res); g_assert_cmpint(err, ==, 0); g_assert_cmpint(res, ==, 0); g_assert(endptr == str); }


static int vmd_read_packet(AVFormatContext *s, AVPacket *pkt) { VmdDemuxContext *vmd = (VmdDemuxContext *)s->priv_data; ByteIOContext *pb = &s->pb; int ret = 0; vmd_frame_t *frame; if (vmd->current_frame >= vmd->frame_count) return -EIO; frame = &vmd->frame_table[vmd->current_frame]; /* position the stream (will probably be there already) */ url_fseek(pb, frame->frame_offset, SEEK_SET); if (av_new_packet(pkt, frame->frame_size + BYTES_PER_FRAME_RECORD)) return AVERROR_NOMEM; memcpy(pkt->data, frame->frame_record, BYTES_PER_FRAME_RECORD); ret = get_buffer(pb, pkt->data + BYTES_PER_FRAME_RECORD, frame->frame_size); if (ret != frame->frame_size) ret = -EIO; pkt->stream_index = frame->stream_index; pkt->pts = frame->pts; vmd->current_frame++; return ret; }


int qemu_add_balloon_handler(QEMUBalloonEvent *event_func, QEMUBalloonStatus *stat_func, void *opaque) { if (balloon_event_fn || balloon_stat_fn || balloon_opaque) { /* We're already registered one balloon handler. How many can * a guest really have? */ error_report("Another balloon device already registered"); return -1; } balloon_event_fn = event_func; balloon_stat_fn = stat_func; balloon_opaque = opaque; return 0; }


static int parse_object_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { PGSSubContext *ctx = avctx->priv_data; PGSSubObject *object; uint8_t sequence_desc; unsigned int rle_bitmap_len, width, height; int id; if (buf_size <= 4) buf_size -= 4; id = bytestream_get_be16(&buf); object = find_object(id, &ctx->objects); if (!object) { if (ctx->objects.count >= MAX_EPOCH_OBJECTS) { av_log(avctx, AV_LOG_ERROR, "Too many objects in epoch\n"); object = &ctx->objects.object[ctx->objects.count++]; object->id = id; /* skip object version number */ buf += 1; /* Read the Sequence Description to determine if start of RLE data or appended to previous RLE */ sequence_desc = bytestream_get_byte(&buf); if (!(sequence_desc & 0x80)) { /* Additional RLE data */ if (buf_size > object->rle_remaining_len) memcpy(object->rle + object->rle_data_len, buf, buf_size); object->rle_data_len += buf_size; object->rle_remaining_len -= buf_size; return 0; if (buf_size <= 7) buf_size -= 7; /* Decode rle bitmap length, stored size includes width/height data */ rle_bitmap_len = bytestream_get_be24(&buf) - 2*2; /* Get bitmap dimensions from data */ width = bytestream_get_be16(&buf); height = bytestream_get_be16(&buf); /* Make sure the bitmap is not too large */ if (avctx->width < width || avctx->height < height) { av_log(avctx, AV_LOG_ERROR, "Bitmap dimensions larger than video.\n"); object->w = width; object->h = height; av_fast_malloc(&object->rle, &object->rle_buffer_size, rle_bitmap_len); if (!object->rle) return AVERROR(ENOMEM); memcpy(object->rle, buf, buf_size); object->rle_data_len = buf_size; object->rle_remaining_len = rle_bitmap_len - buf_size; return 0;


static void pci_error_message(Monitor *mon) { monitor_printf(mon, "PCI devices not supported\n"); }


static void usbredir_interface_info(void *priv, struct usb_redir_interface_info_header *interface_info) { USBRedirDevice *dev = priv; dev->interface_info = *interface_info; /* * If we receive interface info after the device has already been * connected (ie on a set_config), re-check the filter. */ if (qemu_timer_pending(dev->attach_timer) || dev->dev.attached) { if (usbredir_check_filter(dev)) { ERROR("Device no longer matches filter after interface info " "change, disconnecting!\n"); } } }


static void update_irq(struct HPETTimer *timer) { qemu_irq irq; int route; if (timer->tn <= 1 && hpet_in_legacy_mode()) { /* if LegacyReplacementRoute bit is set, HPET specification requires * timer0 be routed to IRQ0 in NON-APIC or IRQ2 in the I/O APIC, * timer1 be routed to IRQ8 in NON-APIC or IRQ8 in the I/O APIC. */ if (timer->tn == 0) { irq=timer->state->irqs[0]; } else irq=timer->state->irqs[8]; } else { route=timer_int_route(timer); irq=timer->state->irqs[route]; } if (timer_enabled(timer) && hpet_enabled()) { qemu_irq_pulse(irq); } }


void virtio_reset(void *opaque) { VirtIODevice *vdev = opaque; VirtioDeviceClass *k = VIRTIO_DEVICE_GET_CLASS(vdev); int i; virtio_set_status(vdev, 0); if (current_cpu) { /* Guest initiated reset */ vdev->device_endian = virtio_current_cpu_endian(); } else { /* System reset */ vdev->device_endian = virtio_default_endian(); } if (k->reset) { k->reset(vdev); } vdev->guest_features = 0; vdev->queue_sel = 0; vdev->status = 0; vdev->isr = 0; vdev->config_vector = VIRTIO_NO_VECTOR; virtio_notify_vector(vdev, vdev->config_vector); for(i = 0; i < VIRTIO_QUEUE_MAX; i++) { vdev->vq[i].vring.desc = 0; vdev->vq[i].vring.avail = 0; vdev->vq[i].vring.used = 0; vdev->vq[i].last_avail_idx = 0; vdev->vq[i].shadow_avail_idx = 0; vdev->vq[i].used_idx = 0; virtio_queue_set_vector(vdev, i, VIRTIO_NO_VECTOR); vdev->vq[i].signalled_used = 0; vdev->vq[i].signalled_used_valid = false; vdev->vq[i].notification = true; vdev->vq[i].vring.num = vdev->vq[i].vring.num_default; vdev->vq[i].inuse = 0; } }


int ffurl_get_short_seek(URLContext *h) { if (!h->prot->url_get_short_seek) return AVERROR(ENOSYS); return h->prot->url_get_short_seek(h); }


static uint64_t vmxnet3_get_command_status(VMXNET3State *s) { uint64_t ret; switch (s->last_command) { case VMXNET3_CMD_ACTIVATE_DEV: ret = (s->device_active) ? 0 : -1; VMW_CFPRN("Device active: %" PRIx64, ret); break; case VMXNET3_CMD_RESET_DEV: case VMXNET3_CMD_QUIESCE_DEV: case VMXNET3_CMD_GET_QUEUE_STATUS: ret = 0; break; case VMXNET3_CMD_GET_LINK: ret = s->link_status_and_speed; VMW_CFPRN("Link and speed: %" PRIx64, ret); break; case VMXNET3_CMD_GET_PERM_MAC_LO: ret = vmxnet3_get_mac_low(&s->perm_mac); break; case VMXNET3_CMD_GET_PERM_MAC_HI: ret = vmxnet3_get_mac_high(&s->perm_mac); break; case VMXNET3_CMD_GET_CONF_INTR: ret = vmxnet3_get_interrupt_config(s); break; case VMXNET3_CMD_GET_ADAPTIVE_RING_INFO: ret = VMXNET3_DISABLE_ADAPTIVE_RING; break; default: VMW_WRPRN("Received request for unknown command: %x", s->last_command); ret = -1; break; } return ret; }


static int mxpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MXpegDecodeContext *s = avctx->priv_data; MJpegDecodeContext *jpg = &s->jpg; const uint8_t *buf_end, *buf_ptr; const uint8_t *unescaped_buf_ptr; int unescaped_buf_size; int start_code; int ret; buf_ptr = buf; buf_end = buf + buf_size; jpg->got_picture = 0; s->got_mxm_bitmask = 0; while (buf_ptr < buf_end) { start_code = ff_mjpeg_find_marker(jpg, &buf_ptr, buf_end, &unescaped_buf_ptr, &unescaped_buf_size); if (start_code < 0) goto the_end; { init_get_bits(&jpg->gb, unescaped_buf_ptr, unescaped_buf_size*8); if (start_code >= APP0 && start_code <= APP15) { mxpeg_decode_app(s, unescaped_buf_ptr, unescaped_buf_size); } switch (start_code) { case SOI: if (jpg->got_picture) //emulating EOI goto the_end; break; case EOI: goto the_end; case DQT: ret = ff_mjpeg_decode_dqt(jpg); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "quantization table decode error\n"); return ret; } break; case DHT: ret = ff_mjpeg_decode_dht(jpg); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "huffman table decode error\n"); return ret; } break; case COM: ret = mxpeg_decode_com(s, unescaped_buf_ptr, unescaped_buf_size); if (ret < 0) return ret; break; case SOF0: s->got_sof_data = 0; ret = ff_mjpeg_decode_sof(jpg); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "SOF data decode error\n"); return ret; } if (jpg->interlaced) { av_log(avctx, AV_LOG_ERROR, "Interlaced mode not supported in MxPEG\n"); return AVERROR(EINVAL); } s->got_sof_data = 1; break; case SOS: if (!s->got_sof_data) { av_log(avctx, AV_LOG_WARNING, "Can not process SOS without SOF data, skipping\n"); break; } if (!jpg->got_picture) { if (jpg->first_picture) { av_log(avctx, AV_LOG_WARNING, "First picture has no SOF, skipping\n"); break; } if (!s->got_mxm_bitmask){ av_log(avctx, AV_LOG_WARNING, "Non-key frame has no MXM, skipping\n"); break; } /* use stored SOF data to allocate current picture */ av_frame_unref(jpg->picture_ptr); if ((ret = ff_get_buffer(avctx, jpg->picture_ptr, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_P; jpg->picture_ptr->key_frame = 0; jpg->got_picture = 1; } else { jpg->picture_ptr->pict_type = AV_PICTURE_TYPE_I; jpg->picture_ptr->key_frame = 1; } if (s->got_mxm_bitmask) { AVFrame *reference_ptr = s->picture[s->picture_index ^ 1]; if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0) break; /* allocate dummy reference picture if needed */ if (!reference_ptr->data[0] && (ret = ff_get_buffer(avctx, reference_ptr, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } else { ret = ff_mjpeg_decode_sos(jpg, NULL, NULL); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } break; } buf_ptr += (get_bits_count(&jpg->gb)+7) >> 3; } } the_end: if (jpg->got_picture) { int ret = av_frame_ref(data, jpg->picture_ptr); if (ret < 0) return ret; *got_frame = 1; s->picture_index ^= 1; jpg->picture_ptr = s->picture[s->picture_index]; if (!s->has_complete_frame) { if (!s->got_mxm_bitmask) s->has_complete_frame = 1; else *got_frame = 0; } } return buf_ptr - buf; }


int main(int argc, char* argv[]) { FILE *f[2]; uint8_t *buf[2], *plane[2][3]; int *temp; uint64_t ssd[3] = {0,0,0}; double ssim[3] = {0,0,0}; int frame_size, w, h; int frames, seek; int i; if( argc<4 || 2 != sscanf(argv[3], "%dx%d", &w, &h) ) { printf("tiny_ssim <file1.yuv> <file2.yuv> <width>x<height> [<seek>]\n"); return -1; } f[0] = fopen(argv[1], "rb"); f[1] = fopen(argv[2], "rb"); sscanf(argv[3], "%dx%d", &w, &h); frame_size = w*h*3/2; for( i=0; i<2; i++ ) { buf[i] = malloc(frame_size); plane[i][0] = buf[i]; plane[i][1] = plane[i][0] + w*h; plane[i][2] = plane[i][1] + w*h/4; } temp = malloc((2*w+12)*sizeof(*temp)); seek = argc<5 ? 0 : atoi(argv[4]); fseek(f[seek<0], seek < 0 ? -seek : seek, SEEK_SET); for( frames=0;; frames++ ) { uint64_t ssd_one[3]; double ssim_one[3]; if( fread(buf[0], frame_size, 1, f[0]) != 1) break; if( fread(buf[1], frame_size, 1, f[1]) != 1) break; for( i=0; i<3; i++ ) { ssd_one[i] = ssd_plane ( plane[0][i], plane[1][i], w*h>>2*!!i ); ssim_one[i] = ssim_plane( plane[0][i], w>>!!i, plane[1][i], w>>!!i, w>>!!i, h>>!!i, temp, NULL ); ssd[i] += ssd_one[i]; ssim[i] += ssim_one[i]; } printf("Frame %d | ", frames); print_results(ssd_one, ssim_one, 1, w, h); printf(" \r"); fflush(stdout); } if( !frames ) return 0; printf("Total %d frames | ", frames); print_results(ssd, ssim, frames, w, h); printf("\n"); return 0; }


static void load_linux(void *fw_cfg, const char *kernel_filename, const char *initrd_filename, const char *kernel_cmdline, target_phys_addr_t max_ram_size) { uint16_t protocol; int setup_size, kernel_size, initrd_size = 0, cmdline_size; uint32_t initrd_max; uint8_t header[8192], *setup, *kernel, *initrd_data; target_phys_addr_t real_addr, prot_addr, cmdline_addr, initrd_addr = 0; FILE *f; char *vmode; /* Align to 16 bytes as a paranoia measure */ cmdline_size = (strlen(kernel_cmdline)+16) & ~15; /* load the kernel header */ f = fopen(kernel_filename, "rb"); if (!f || !(kernel_size = get_file_size(f)) || fread(header, 1, MIN(ARRAY_SIZE(header), kernel_size), f) != MIN(ARRAY_SIZE(header), kernel_size)) { fprintf(stderr, "qemu: could not load kernel '%s': %s\n", kernel_filename, strerror(errno)); /* kernel protocol version */ #if 0 fprintf(stderr, "header magic: %#x\n", ldl_p(header+0x202)); #endif if (ldl_p(header+0x202) == 0x53726448) protocol = lduw_p(header+0x206); else { /* This looks like a multiboot kernel. If it is, let's stop treating it like a Linux kernel. */ if (load_multiboot(fw_cfg, f, kernel_filename, initrd_filename, kernel_cmdline, kernel_size, header)) return; protocol = 0; if (protocol < 0x200 || !(header[0x211] & 0x01)) { /* Low kernel */ real_addr = 0x90000; cmdline_addr = 0x9a000 - cmdline_size; prot_addr = 0x10000; } else if (protocol < 0x202) { /* High but ancient kernel */ real_addr = 0x90000; cmdline_addr = 0x9a000 - cmdline_size; prot_addr = 0x100000; } else { /* High and recent kernel */ real_addr = 0x10000; cmdline_addr = 0x20000; prot_addr = 0x100000; #if 0 fprintf(stderr, "qemu: real_addr = 0x" TARGET_FMT_plx "\n" "qemu: cmdline_addr = 0x" TARGET_FMT_plx "\n" "qemu: prot_addr = 0x" TARGET_FMT_plx "\n", real_addr, cmdline_addr, prot_addr); #endif /* highest address for loading the initrd */ if (protocol >= 0x203) initrd_max = ldl_p(header+0x22c); else initrd_max = 0x37ffffff; if (initrd_max >= max_ram_size-ACPI_DATA_SIZE) initrd_max = max_ram_size-ACPI_DATA_SIZE-1; fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_ADDR, cmdline_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(kernel_cmdline)+1); fw_cfg_add_bytes(fw_cfg, FW_CFG_CMDLINE_DATA, (uint8_t*)strdup(kernel_cmdline), strlen(kernel_cmdline)+1); if (protocol >= 0x202) { stl_p(header+0x228, cmdline_addr); } else { stw_p(header+0x20, 0xA33F); stw_p(header+0x22, cmdline_addr-real_addr); /* handle vga= parameter */ vmode = strstr(kernel_cmdline, "vga="); if (vmode) { unsigned int video_mode; /* skip "vga=" */ vmode += 4; if (!strncmp(vmode, "normal", 6)) { video_mode = 0xffff; } else if (!strncmp(vmode, "ext", 3)) { video_mode = 0xfffe; } else if (!strncmp(vmode, "ask", 3)) { video_mode = 0xfffd; } else { video_mode = strtol(vmode, NULL, 0); stw_p(header+0x1fa, video_mode); /* loader type */ /* High nybble = B reserved for Qemu; low nybble is revision number. If this code is substantially changed, you may want to consider incrementing the revision. */ if (protocol >= 0x200) header[0x210] = 0xB0; /* heap */ if (protocol >= 0x201) { header[0x211] |= 0x80; /* CAN_USE_HEAP */ stw_p(header+0x224, cmdline_addr-real_addr-0x200); /* load initrd */ if (initrd_filename) { if (protocol < 0x200) { fprintf(stderr, "qemu: linux kernel too old to load a ram disk\n"); initrd_size = get_image_size(initrd_filename); initrd_addr = (initrd_max-initrd_size) & ~4095; initrd_data = qemu_malloc(initrd_size); load_image(initrd_filename, initrd_data); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_INITRD_DATA, initrd_data, initrd_size); stl_p(header+0x218, initrd_addr); stl_p(header+0x21c, initrd_size); /* load kernel and setup */ setup_size = header[0x1f1]; if (setup_size == 0) setup_size = 4; setup_size = (setup_size+1)*512; kernel_size -= setup_size; setup = qemu_malloc(setup_size); kernel = qemu_malloc(kernel_size); fseek(f, 0, SEEK_SET); if (fread(setup, 1, setup_size, f) != setup_size) { fprintf(stderr, "fread() failed\n"); if (fread(kernel, 1, kernel_size, f) != kernel_size) { fprintf(stderr, "fread() failed\n"); fclose(f); memcpy(setup, header, MIN(sizeof(header), setup_size)); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, prot_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_KERNEL_DATA, kernel, kernel_size); fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_ADDR, real_addr); fw_cfg_add_i32(fw_cfg, FW_CFG_SETUP_SIZE, setup_size); fw_cfg_add_bytes(fw_cfg, FW_CFG_SETUP_DATA, setup, setup_size); option_rom[nb_option_roms] = "linuxboot.bin"; nb_option_roms++;


target_ulong spapr_hypercall(CPUPPCState *env, target_ulong opcode, target_ulong *args) { if (msr_pr) { hcall_dprintf("Hypercall made with MSR[PR]=1\n"); return H_PRIVILEGE; } if ((opcode <= MAX_HCALL_OPCODE) && ((opcode & 0x3) == 0)) { spapr_hcall_fn fn = papr_hypercall_table[opcode / 4]; if (fn) { return fn(env, spapr, opcode, args); } } else if ((opcode >= KVMPPC_HCALL_BASE) && (opcode <= KVMPPC_HCALL_MAX)) { spapr_hcall_fn fn = kvmppc_hypercall_table[opcode - KVMPPC_HCALL_BASE]; if (fn) { return fn(env, spapr, opcode, args); } } hcall_dprintf("Unimplemented hcall 0x" TARGET_FMT_lx "\n", opcode); return H_FUNCTION; }


void av_thread_message_queue_set_err_send(AVThreadMessageQueue *mq, int err) { #if HAVE_THREADS pthread_mutex_lock(&mq->lock); mq->err_send = err; pthread_cond_broadcast(&mq->cond); pthread_mutex_unlock(&mq->lock); #endif /* HAVE_THREADS */ }


static int piix4_pm_initfn(PCIDevice *dev) { PIIX4PMState *s = DO_UPCAST(PIIX4PMState, dev, dev); uint8_t *pci_conf; pci_conf = s->dev.config; pci_conf[0x06] = 0x80; pci_conf[0x07] = 0x02; pci_conf[0x09] = 0x00; pci_conf[0x3d] = 0x01; // interrupt pin 1 /* APM */ apm_init(dev, &s->apm, apm_ctrl_changed, s); if (s->kvm_enabled) { /* Mark SMM as already inited to prevent SMM from running. KVM does not * support SMM mode. */ pci_conf[0x5B] = 0x02; } /* XXX: which specification is used ? The i82731AB has different mappings */ pci_conf[0x90] = s->smb_io_base | 1; pci_conf[0x91] = s->smb_io_base >> 8; pci_conf[0xd2] = 0x09; pm_smbus_init(&s->dev.qdev, &s->smb); memory_region_set_enabled(&s->smb.io, pci_conf[0xd2] & 1); memory_region_add_subregion(pci_address_space_io(dev), s->smb_io_base, &s->smb.io); memory_region_init(&s->io, "piix4-pm", 64); memory_region_set_enabled(&s->io, false); memory_region_add_subregion(pci_address_space_io(dev), 0, &s->io); acpi_pm_tmr_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_evt_init(&s->ar, pm_tmr_timer, &s->io); acpi_pm1_cnt_init(&s->ar, &s->io); acpi_gpe_init(&s->ar, GPE_LEN); s->powerdown_notifier.notify = piix4_pm_powerdown_req; qemu_register_powerdown_notifier(&s->powerdown_notifier); s->machine_ready.notify = piix4_pm_machine_ready; qemu_add_machine_init_done_notifier(&s->machine_ready); qemu_register_reset(piix4_reset, s); piix4_acpi_system_hot_add_init(pci_address_space_io(dev), dev->bus, s); return 0; }


static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) { AVIndexEntry *sample = NULL; int64_t best_dts = INT64_MAX; int i; for (i = 0; i < s->nb_streams; i++) { AVStream *avst = s->streams[i]; MOVStreamContext *msc = avst->priv_data; if (msc->pb && msc->current_sample < avst->nb_index_entries) { AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; int64_t dts; if (msc->ctts_data) dts = av_rescale(current_sample->timestamp - msc->dts_shift - msc->ctts_data[msc->ctts_index].duration, AV_TIME_BASE, msc->time_scale); else dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); av_dlog(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) || (s->pb->seekable && ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { sample = current_sample; best_dts = dts; *st = avst; } } } return sample; }


static int kvm_put_msrs(X86CPU *cpu, int level) { CPUX86State *env = &cpu->env; int i; int ret; kvm_msr_buf_reset(cpu); kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_CS, env->sysenter_cs); kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_ESP, env->sysenter_esp); kvm_msr_entry_add(cpu, MSR_IA32_SYSENTER_EIP, env->sysenter_eip); kvm_msr_entry_add(cpu, MSR_PAT, env->pat); if (has_msr_star) { kvm_msr_entry_add(cpu, MSR_STAR, env->star); } if (has_msr_hsave_pa) { kvm_msr_entry_add(cpu, MSR_VM_HSAVE_PA, env->vm_hsave); } if (has_msr_tsc_aux) { kvm_msr_entry_add(cpu, MSR_TSC_AUX, env->tsc_aux); } if (has_msr_tsc_adjust) { kvm_msr_entry_add(cpu, MSR_TSC_ADJUST, env->tsc_adjust); } if (has_msr_misc_enable) { kvm_msr_entry_add(cpu, MSR_IA32_MISC_ENABLE, env->msr_ia32_misc_enable); } if (has_msr_smbase) { kvm_msr_entry_add(cpu, MSR_IA32_SMBASE, env->smbase); } if (has_msr_bndcfgs) { kvm_msr_entry_add(cpu, MSR_IA32_BNDCFGS, env->msr_bndcfgs); } if (has_msr_xss) { kvm_msr_entry_add(cpu, MSR_IA32_XSS, env->xss); } #ifdef TARGET_X86_64 if (lm_capable_kernel) { kvm_msr_entry_add(cpu, MSR_CSTAR, env->cstar); kvm_msr_entry_add(cpu, MSR_KERNELGSBASE, env->kernelgsbase); kvm_msr_entry_add(cpu, MSR_FMASK, env->fmask); kvm_msr_entry_add(cpu, MSR_LSTAR, env->lstar); } #endif /* * The following MSRs have side effects on the guest or are too heavy * for normal writeback. Limit them to reset or full state updates. */ if (level >= KVM_PUT_RESET_STATE) { kvm_msr_entry_add(cpu, MSR_IA32_TSC, env->tsc); kvm_msr_entry_add(cpu, MSR_KVM_SYSTEM_TIME, env->system_time_msr); kvm_msr_entry_add(cpu, MSR_KVM_WALL_CLOCK, env->wall_clock_msr); if (has_msr_async_pf_en) { kvm_msr_entry_add(cpu, MSR_KVM_ASYNC_PF_EN, env->async_pf_en_msr); } if (has_msr_pv_eoi_en) { kvm_msr_entry_add(cpu, MSR_KVM_PV_EOI_EN, env->pv_eoi_en_msr); } if (has_msr_kvm_steal_time) { kvm_msr_entry_add(cpu, MSR_KVM_STEAL_TIME, env->steal_time_msr); } if (has_msr_architectural_pmu) { /* Stop the counter. */ kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, 0); kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, 0); /* Set the counter values. */ for (i = 0; i < MAX_FIXED_COUNTERS; i++) { kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR0 + i, env->msr_fixed_counters[i]); } for (i = 0; i < num_architectural_pmu_counters; i++) { kvm_msr_entry_add(cpu, MSR_P6_PERFCTR0 + i, env->msr_gp_counters[i]); kvm_msr_entry_add(cpu, MSR_P6_EVNTSEL0 + i, env->msr_gp_evtsel[i]); } kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_STATUS, env->msr_global_status); kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_OVF_CTRL, env->msr_global_ovf_ctrl); /* Now start the PMU. */ kvm_msr_entry_add(cpu, MSR_CORE_PERF_FIXED_CTR_CTRL, env->msr_fixed_ctr_ctrl); kvm_msr_entry_add(cpu, MSR_CORE_PERF_GLOBAL_CTRL, env->msr_global_ctrl); } if (has_msr_hv_hypercall) { kvm_msr_entry_add(cpu, HV_X64_MSR_GUEST_OS_ID, env->msr_hv_guest_os_id); kvm_msr_entry_add(cpu, HV_X64_MSR_HYPERCALL, env->msr_hv_hypercall); } if (has_msr_hv_vapic) { kvm_msr_entry_add(cpu, HV_X64_MSR_APIC_ASSIST_PAGE, env->msr_hv_vapic); } if (has_msr_hv_tsc) { kvm_msr_entry_add(cpu, HV_X64_MSR_REFERENCE_TSC, env->msr_hv_tsc); } if (has_msr_hv_crash) { int j; for (j = 0; j < HV_X64_MSR_CRASH_PARAMS; j++) kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_P0 + j, env->msr_hv_crash_params[j]); kvm_msr_entry_add(cpu, HV_X64_MSR_CRASH_CTL, HV_X64_MSR_CRASH_CTL_NOTIFY); } if (has_msr_hv_runtime) { kvm_msr_entry_add(cpu, HV_X64_MSR_VP_RUNTIME, env->msr_hv_runtime); } if (cpu->hyperv_synic) { int j; kvm_msr_entry_add(cpu, HV_X64_MSR_SCONTROL, env->msr_hv_synic_control); kvm_msr_entry_add(cpu, HV_X64_MSR_SVERSION, env->msr_hv_synic_version); kvm_msr_entry_add(cpu, HV_X64_MSR_SIEFP, env->msr_hv_synic_evt_page); kvm_msr_entry_add(cpu, HV_X64_MSR_SIMP, env->msr_hv_synic_msg_page); for (j = 0; j < ARRAY_SIZE(env->msr_hv_synic_sint); j++) { kvm_msr_entry_add(cpu, HV_X64_MSR_SINT0 + j, env->msr_hv_synic_sint[j]); } } if (has_msr_hv_stimer) { int j; for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_config); j++) { kvm_msr_entry_add(cpu, HV_X64_MSR_STIMER0_CONFIG + j * 2, env->msr_hv_stimer_config[j]); } for (j = 0; j < ARRAY_SIZE(env->msr_hv_stimer_count); j++) { kvm_msr_entry_add(cpu, HV_X64_MSR_STIMER0_COUNT + j * 2, env->msr_hv_stimer_count[j]); } } if (has_msr_mtrr) { kvm_msr_entry_add(cpu, MSR_MTRRdefType, env->mtrr_deftype); kvm_msr_entry_add(cpu, MSR_MTRRfix64K_00000, env->mtrr_fixed[0]); kvm_msr_entry_add(cpu, MSR_MTRRfix16K_80000, env->mtrr_fixed[1]); kvm_msr_entry_add(cpu, MSR_MTRRfix16K_A0000, env->mtrr_fixed[2]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C0000, env->mtrr_fixed[3]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_C8000, env->mtrr_fixed[4]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D0000, env->mtrr_fixed[5]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_D8000, env->mtrr_fixed[6]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E0000, env->mtrr_fixed[7]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_E8000, env->mtrr_fixed[8]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F0000, env->mtrr_fixed[9]); kvm_msr_entry_add(cpu, MSR_MTRRfix4K_F8000, env->mtrr_fixed[10]); for (i = 0; i < MSR_MTRRcap_VCNT; i++) { kvm_msr_entry_add(cpu, MSR_MTRRphysBase(i), env->mtrr_var[i].base); kvm_msr_entry_add(cpu, MSR_MTRRphysMask(i), env->mtrr_var[i].mask); } } /* Note: MSR_IA32_FEATURE_CONTROL is written separately, see * kvm_put_msr_feature_control. */ } if (env->mcg_cap) { int i; kvm_msr_entry_add(cpu, MSR_MCG_STATUS, env->mcg_status); kvm_msr_entry_add(cpu, MSR_MCG_CTL, env->mcg_ctl); if (has_msr_mcg_ext_ctl) { kvm_msr_entry_add(cpu, MSR_MCG_EXT_CTL, env->mcg_ext_ctl); } for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++) { kvm_msr_entry_add(cpu, MSR_MC0_CTL + i, env->mce_banks[i]); } } ret = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_MSRS, cpu->kvm_msr_buf); if (ret < 0) { return ret; } assert(ret == cpu->kvm_msr_buf->nmsrs); return 0; }


static void mv88w8618_pic_write(void *opaque, target_phys_addr_t offset, uint64_t value, unsigned size) { mv88w8618_pic_state *s = opaque; switch (offset) { case MP_PIC_ENABLE_SET: s->enabled |= value; break; case MP_PIC_ENABLE_CLR: s->enabled &= ~value; s->level &= ~value; break; } mv88w8618_pic_update(s); }


static int ram_load(QEMUFile *f, void *opaque, int version_id) { ram_addr_t addr; int flags; if (version_id != 3) return -EINVAL; do { addr = qemu_get_be64(f); flags = addr & ~TARGET_PAGE_MASK; addr &= TARGET_PAGE_MASK; if (flags & RAM_SAVE_FLAG_MEM_SIZE) { if (addr != last_ram_offset) return -EINVAL; } if (flags & RAM_SAVE_FLAG_COMPRESS) { uint8_t ch = qemu_get_byte(f); memset(qemu_get_ram_ptr(addr), ch, TARGET_PAGE_SIZE); #ifndef _WIN32 if (ch == 0 && (!kvm_enabled() || kvm_has_sync_mmu())) { madvise(qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE, MADV_DONTNEED); } #endif } else if (flags & RAM_SAVE_FLAG_PAGE) { qemu_get_buffer(f, qemu_get_ram_ptr(addr), TARGET_PAGE_SIZE); } if (qemu_file_has_error(f)) { return -EIO; } } while (!(flags & RAM_SAVE_FLAG_EOS)); return 0; }


int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb, int search_pc) { DisasContext ctx, *ctxp = &ctx; opc_handler_t **table, *handler; uint32_t pc_start; uint16_t *gen_opc_end; int j, lj = -1; pc_start = tb->pc; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; ctx.nip = pc_start; ctx.tb = tb; ctx.exception = EXCP_NONE; #if defined(CONFIG_USER_ONLY) ctx.mem_idx = 0; #else ctx.supervisor = 1 - msr_pr; ctx.mem_idx = (1 - msr_pr); #endif #if defined (DO_SINGLE_STEP) /* Single step trace mode */ msr_se = 1; #endif env->access_type = ACCESS_CODE; /* Set env in case of segfault during code fetch */ while (ctx.exception == EXCP_NONE && gen_opc_ptr < gen_opc_end) { if (search_pc) { if (loglevel > 0) fprintf(logfile, "Search PC...\n"); j = gen_opc_ptr - gen_opc_buf; if (lj < j) { lj++; while (lj < j) gen_opc_instr_start[lj++] = 0; gen_opc_pc[lj] = ctx.nip; gen_opc_instr_start[lj] = 1; } } #if defined PPC_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "----------------\n"); fprintf(logfile, "nip=%08x super=%d ir=%d\n", ctx.nip, 1 - msr_pr, msr_ir); } #endif ctx.opcode = ldl_code((void *)ctx.nip); #if defined PPC_DEBUG_DISAS if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "translate opcode %08x (%02x %02x %02x)\n", ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode)); } #endif ctx.nip += 4; table = ppc_opcodes; handler = table[opc1(ctx.opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); handler = table[opc2(ctx.opcode)]; if (is_indirect_opcode(handler)) { table = ind_table(handler); handler = table[opc3(ctx.opcode)]; } } /* Is opcode *REALLY* valid ? */ if (handler->handler == &gen_invalid) { if (loglevel > 0) { fprintf(logfile, "invalid/unsupported opcode: " "%02x - %02x - %02x (%08x) 0x%08x %d\n", opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir); } else { printf("invalid/unsupported opcode: " "%02x - %02x - %02x (%08x) 0x%08x %d\n", opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4, msr_ir); } } else { if ((ctx.opcode & handler->inval) != 0) { if (loglevel > 0) { fprintf(logfile, "invalid bits: %08x for opcode: " "%02x -%02x - %02x (0x%08x) (0x%08x)\n", ctx.opcode & handler->inval, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); } else { printf("invalid bits: %08x for opcode: " "%02x -%02x - %02x (0x%08x) (0x%08x)\n", ctx.opcode & handler->inval, opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode), ctx.opcode, ctx.nip - 4); } RET_INVAL(ctxp); break; } } (*(handler->handler))(&ctx); /* Check trace mode exceptions */ if ((msr_be && ctx.exception == EXCP_BRANCH) || /* Check in single step trace mode * we need to stop except if: * - rfi, trap or syscall * - first instruction of an exception handler */ (msr_se && (ctx.nip < 0x100 || ctx.nip > 0xF00 || (ctx.nip & 0xFC) != 0x04) && ctx.exception != EXCP_SYSCALL && ctx.exception != EXCP_RFI && ctx.exception != EXCP_TRAP)) { RET_EXCP(ctxp, EXCP_TRACE, 0); } /* if we reach a page boundary, stop generation */ if ((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) { RET_EXCP(ctxp, EXCP_BRANCH, 0); } } if (ctx.exception == EXCP_NONE) { gen_op_b((unsigned long)ctx.tb, ctx.nip); } else if (ctx.exception != EXCP_BRANCH) { gen_op_set_T0(0); } #if 1 /* TO BE FIXED: T0 hasn't got a proper value, which makes tb_add_jump * do bad business and then qemu crashes ! */ gen_op_set_T0(0); #endif /* Generate the return instruction */ gen_op_exit_tb(); *gen_opc_ptr = INDEX_op_end; if (search_pc) { j = gen_opc_ptr - gen_opc_buf; lj++; while (lj <= j) gen_opc_instr_start[lj++] = 0; tb->size = 0; #if 0 if (loglevel > 0) { page_dump(logfile); } #endif } else { tb->size = ctx.nip - pc_start; } #ifdef DEBUG_DISAS if (loglevel & CPU_LOG_TB_CPU) { fprintf(logfile, "---------------- excp: %04x\n", ctx.exception); cpu_ppc_dump_state(env, logfile, 0); } if (loglevel & CPU_LOG_TB_IN_ASM) { fprintf(logfile, "IN: %s\n", lookup_symbol((void *)pc_start)); disas(logfile, (void *)pc_start, ctx.nip - pc_start, 0, 0); fprintf(logfile, "\n"); } if (loglevel & CPU_LOG_TB_OP) { fprintf(logfile, "OP:\n"); dump_ops(gen_opc_buf, gen_opparam_buf); fprintf(logfile, "\n"); } #endif env->access_type = ACCESS_INT; return 0; }


static void bdrv_cow_init(void) { bdrv_register(&bdrv_cow); }


void vnc_zlib_clear(VncState *vs) { if (vs->zlib_stream.opaque) { deflateEnd(&vs->zlib_stream); } buffer_free(&vs->zlib); }


void bt_device_done(struct bt_device_s *dev) { struct bt_device_s **p = &dev->net->slave; while (*p && *p != dev) p = &(*p)->next; if (*p != dev) { fprintf(stderr, "%s: bad bt device \"%s\"\n", __FUNCTION__, dev->lmp_name ?: "(null)"); exit(-1); } *p = dev->next; }


static void s390_init(MachineState *machine) { ram_addr_t my_ram_size = machine->ram_size; MemoryRegion *sysmem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); int increment_size = 20; void *virtio_region; hwaddr virtio_region_len; hwaddr virtio_region_start; if (machine->ram_slots) { error_report("Memory hotplug not supported by the selected machine."); exit(EXIT_FAILURE); } /* * The storage increment size is a multiple of 1M and is a power of 2. * The number of storage increments must be MAX_STORAGE_INCREMENTS or * fewer. */ while ((my_ram_size >> increment_size) > MAX_STORAGE_INCREMENTS) { increment_size++; } my_ram_size = my_ram_size >> increment_size << increment_size; /* let's propagate the changed ram size into the global variable. */ ram_size = my_ram_size; /* get a BUS */ s390_bus = s390_virtio_bus_init(&my_ram_size); s390_sclp_init(); s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, machine->initrd_filename, ZIPL_FILENAME, false); s390_flic_init(); /* register hypercalls */ s390_virtio_register_hcalls(); /* allocate RAM */ memory_region_init_ram(ram, NULL, "s390.ram", my_ram_size, &error_abort); vmstate_register_ram_global(ram); memory_region_add_subregion(sysmem, 0, ram); /* clear virtio region */ virtio_region_len = my_ram_size - ram_size; virtio_region_start = ram_size; virtio_region = cpu_physical_memory_map(virtio_region_start, &virtio_region_len, true); memset(virtio_region, 0, virtio_region_len); cpu_physical_memory_unmap(virtio_region, virtio_region_len, 1, virtio_region_len); /* Initialize storage key device */ s390_skeys_init(); /* init CPUs */ s390_init_cpus(machine->cpu_model); /* Create VirtIO network adapters */ s390_create_virtio_net((BusState *)s390_bus, "virtio-net-s390"); /* Register savevm handler for guest TOD clock */ register_savevm(NULL, "todclock", 0, 1, gtod_save, gtod_load, NULL); }


static bool scsi_block_is_passthrough(SCSIDiskState *s, uint8_t *buf) { switch (buf[0]) { case READ_6: case READ_10: case READ_12: case READ_16: case VERIFY_10: case VERIFY_12: case VERIFY_16: case WRITE_6: case WRITE_10: case WRITE_12: case WRITE_16: case WRITE_VERIFY_10: case WRITE_VERIFY_12: case WRITE_VERIFY_16: /* If we are not using O_DIRECT, we might read stale data from the * host cache if writes were made using other commands than these * ones (such as WRITE SAME or EXTENDED COPY, etc.). So, without * O_DIRECT everything must go through SG_IO. */ if (!(bdrv_get_flags(s->qdev.conf.bs) & BDRV_O_NOCACHE)) { break; } /* MMC writing cannot be done via pread/pwrite, because it sometimes * involves writing beyond the maximum LBA or to negative LBA (lead-in). * And once you do these writes, reading from the block device is * unreliable, too. It is even possible that reads deliver random data * from the host page cache (this is probably a Linux bug). * * We might use scsi_disk_dma_reqops as long as no writing commands are * seen, but performance usually isn't paramount on optical media. So, * just make scsi-block operate the same as scsi-generic for them. */ if (s->qdev.type != TYPE_ROM) { return false; } break; default: break; } return true; }


int ff_lpc_calc_coefs(LPCContext *s, const int32_t *samples, int blocksize, int min_order, int max_order, int precision, int32_t coefs[][MAX_LPC_ORDER], int *shift, enum FFLPCType lpc_type, int lpc_passes, int omethod, int max_shift, int zero_shift) { double autoc[MAX_LPC_ORDER+1]; double ref[MAX_LPC_ORDER]; double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; int i, j, pass; int opt_order; av_assert2(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && lpc_type > FF_LPC_TYPE_FIXED); /* reinit LPC context if parameters have changed */ if (blocksize != s->blocksize || max_order != s->max_order || lpc_type != s->lpc_type) { ff_lpc_end(s); ff_lpc_init(s, blocksize, max_order, lpc_type); } if (lpc_type == FF_LPC_TYPE_LEVINSON) { s->lpc_apply_welch_window(samples, blocksize, s->windowed_samples); s->lpc_compute_autocorr(s->windowed_samples, blocksize, max_order, autoc); compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1); for(i=0; i<max_order; i++) ref[i] = fabs(lpc[i][i]); } else if (lpc_type == FF_LPC_TYPE_CHOLESKY) { LLSModel m[2]; double var[MAX_LPC_ORDER+1], av_uninit(weight); if(lpc_passes <= 0) lpc_passes = 2; for(pass=0; pass<lpc_passes; pass++){ av_init_lls(&m[pass&1], max_order); weight=0; for(i=max_order; i<blocksize; i++){ for(j=0; j<=max_order; j++) var[j]= samples[i-j]; if(pass){ double eval, inv, rinv; eval= av_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1); eval= (512>>pass) + fabs(eval - var[0]); inv = 1/eval; rinv = sqrt(inv); for(j=0; j<=max_order; j++) var[j] *= rinv; weight += inv; }else weight++; av_update_lls(&m[pass&1], var, 1.0); } av_solve_lls(&m[pass&1], 0.001, 0); } for(i=0; i<max_order; i++){ for(j=0; j<max_order; j++) lpc[i][j]=-m[(pass-1)&1].coeff[i][j]; ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000; } for(i=max_order-1; i>0; i--) ref[i] = ref[i-1] - ref[i]; } opt_order = max_order; if(omethod == ORDER_METHOD_EST) { opt_order = estimate_best_order(ref, min_order, max_order); i = opt_order-1; quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); } else { for(i=min_order-1; i<max_order; i++) { quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); } } return opt_order; }


static uint64_t pci_config_get_memory_base(PCIDevice *d, uint32_t base) { return ((uint64_t)pci_get_word(d->config + base) & PCI_MEMORY_RANGE_MASK) << 16; }


void pci_default_write_config(PCIDevice *d, uint32_t address, uint32_t val, int len) { int can_write, i; uint32_t end, addr; if (len == 4 && ((address >= 0x10 && address < 0x10 + 4 * 6) || (address >= 0x30 && address < 0x34))) { PCIIORegion *r; int reg; if ( address >= 0x30 ) { reg = PCI_ROM_SLOT; }else{ reg = (address - 0x10) >> 2; } r = &d->io_regions[reg]; if (r->size == 0) goto default_config; /* compute the stored value */ if (reg == PCI_ROM_SLOT) { /* keep ROM enable bit */ val &= (~(r->size - 1)) | 1; } else { val &= ~(r->size - 1); val |= r->type; } *(uint32_t *)(d->config + address) = cpu_to_le32(val); pci_update_mappings(d); return; } default_config: /* not efficient, but simple */ addr = address; for(i = 0; i < len; i++) { /* default read/write accesses */ switch(d->config[0x0e]) { case 0x00: case 0x80: switch(addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0e: case 0x10 ... 0x27: /* base */ case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */ case 0x30 ... 0x33: /* rom */ case 0x3d: can_write = 0; break; default: can_write = 1; break; } break; default: case 0x01: switch(addr) { case 0x00: case 0x01: case 0x02: case 0x03: case 0x06: case 0x07: case 0x08: case 0x09: case 0x0a: case 0x0b: case 0x0e: case 0x2c ... 0x2f: /* read-only subsystem ID & vendor ID */ case 0x38 ... 0x3b: /* rom */ case 0x3d: can_write = 0; break; default: can_write = 1; break; } break; } if (can_write) { /* Mask out writes to reserved bits in registers */ switch (addr) { case 0x05: val &= ~PCI_COMMAND_RESERVED_MASK_HI; break; case 0x06: val &= ~PCI_STATUS_RESERVED_MASK_LO; break; case 0x07: val &= ~PCI_STATUS_RESERVED_MASK_HI; break; } d->config[addr] = val; } if (++addr > 0xff) break; val >>= 8; } end = address + len; if (end > PCI_COMMAND && address < (PCI_COMMAND + 2)) { /* if the command register is modified, we must modify the mappings */ pci_update_mappings(d); } }


static int ehci_state_writeback(EHCIQueue *q, int async) { int again = 0; /* Write back the QTD from the QH area */ ehci_trace_qtd(q, NLPTR_GET(q->qtdaddr), (EHCIqtd*) &q->qh.next_qtd); put_dwords(NLPTR_GET(q->qtdaddr),(uint32_t *) &q->qh.next_qtd, sizeof(EHCIqtd) >> 2); /* * EHCI specs say go horizontal here. * * We can also advance the queue here for performance reasons. We * need to take care to only take that shortcut in case we've * processed the qtd just written back without errors, i.e. halt * bit is clear. */ if (q->qh.token & QTD_TOKEN_HALT) { ehci_set_state(q->ehci, async, EST_HORIZONTALQH); again = 1; } else { ehci_set_state(q->ehci, async, EST_ADVANCEQUEUE); again = 1; } return again; }


static uint64_t omap_dpll_read(void *opaque, target_phys_addr_t addr, unsigned size) { struct dpll_ctl_s *s = (struct dpll_ctl_s *) opaque; if (size != 2) { return omap_badwidth_read16(opaque, addr); } if (addr == 0x00) /* CTL_REG */ return s->mode; OMAP_BAD_REG(addr); return 0; }


static QEMUCursor *qxl_cursor(PCIQXLDevice *qxl, QXLCursor *cursor) { QEMUCursor *c; uint8_t *image, *mask; size_t size; c = cursor_alloc(cursor->header.width, cursor->header.height); c->hot_x = cursor->header.hot_spot_x; c->hot_y = cursor->header.hot_spot_y; switch (cursor->header.type) { case SPICE_CURSOR_TYPE_ALPHA: size = sizeof(uint32_t) * cursor->header.width * cursor->header.height; memcpy(c->data, cursor->chunk.data, size); if (qxl->debug > 2) { cursor_print_ascii_art(c, "qxl/alpha"); } break; case SPICE_CURSOR_TYPE_MONO: mask = cursor->chunk.data; image = mask + cursor_get_mono_bpl(c) * c->width; cursor_set_mono(c, 0xffffff, 0x000000, image, 1, mask); if (qxl->debug > 2) { cursor_print_ascii_art(c, "qxl/mono"); } break; default: fprintf(stderr, "%s: not implemented: type %d\n", __FUNCTION__, cursor->header.type); goto fail; } return c; fail: cursor_put(c); return NULL; }


static inline int silk_is_lpc_stable(const int16_t lpc[16], int order) { int k, j, DC_resp = 0; int32_t lpc32[2][16]; // Q24 int totalinvgain = 1 << 30; // 1.0 in Q30 int32_t *row = lpc32[0], *prevrow; /* initialize the first row for the Levinson recursion */ for (k = 0; k < order; k++) { DC_resp += lpc[k]; row[k] = lpc[k] * 4096; } if (DC_resp >= 4096) return 0; /* check if prediction gain pushes any coefficients too far */ for (k = order - 1; 1; k--) { int rc; // Q31; reflection coefficient int gaindiv; // Q30; inverse of the gain (the divisor) int gain; // gain for this reflection coefficient int fbits; // fractional bits used for the gain int error; // Q29; estimate of the error of our partial estimate of 1/gaindiv if (FFABS(row[k]) > 16773022) return 0; rc = -(row[k] * 128); gaindiv = (1 << 30) - MULH(rc, rc); totalinvgain = MULH(totalinvgain, gaindiv) << 2; if (k == 0) return (totalinvgain >= 107374); /* approximate 1.0/gaindiv */ fbits = opus_ilog(gaindiv); gain = ((1 << 29) - 1) / (gaindiv >> (fbits + 1 - 16)); // Q<fbits-16> error = (1 << 29) - MULL(gaindiv << (15 + 16 - fbits), gain, 16); gain = ((gain << 16) + (error * gain >> 13)); /* switch to the next row of the LPC coefficients */ prevrow = row; row = lpc32[k & 1]; for (j = 0; j < k; j++) { int x = prevrow[j] - ROUND_MULL(prevrow[k - j - 1], rc, 31); row[j] = ROUND_MULL(x, gain, fbits); } } }


static inline int mov_get_stsc_samples(MOVStreamContext *sc, int index) { int chunk_count; if (mov_stsc_index_valid(index, sc->stsc_count)) chunk_count = sc->stsc_data[index + 1].first - sc->stsc_data[index].first; else chunk_count = sc->chunk_count - (sc->stsc_data[index].first - 1); return sc->stsc_data[index].count * chunk_count; }


static void test_machine(const void *data) { const testdef_t *test = data; char *args; char tmpname[] = "/tmp/qtest-boot-serial-XXXXXX"; int fd; fd = mkstemp(tmpname); g_assert(fd != -1); args = g_strdup_printf("-M %s,accel=tcg -chardev file,id=serial0,path=%s" " -serial chardev:serial0 %s", test->machine, tmpname, test->extra); qtest_start(args); unlink(tmpname); check_guest_output(test, fd); qtest_quit(global_qtest); g_free(args); close(fd); }


static int write_number(void *obj, const AVOption *o, void *dst, double num, int den, int64_t intnum) { if (o->max*den < num*intnum || o->min*den > num*intnum) { av_log(obj, AV_LOG_ERROR, "Value %f for parameter '%s' out of range\n", num*intnum/den, o->name); return AVERROR(ERANGE); } switch (o->type) { case AV_OPT_TYPE_FLAGS: case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_INT64: *(int64_t *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_FLOAT: *(float *)dst= num*intnum/den; break; case AV_OPT_TYPE_DOUBLE:*(double *)dst= num*intnum/den; break; case AV_OPT_TYPE_RATIONAL: if ((int)num == num) *(AVRational*)dst= (AVRational){num*intnum, den}; else *(AVRational*)dst= av_d2q(num*intnum/den, 1<<24); break; default: return AVERROR(EINVAL); } return 0; }


static void rtas_stop_self(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); cs->halted = 1; qemu_cpu_kick(cs); /* * While stopping a CPU, the guest calls H_CPPR which * effectively disables interrupts on XICS level. * However decrementer interrupts in TCG can still * wake the CPU up so here we disable interrupts in MSR * as well. * As rtas_start_cpu() resets the whole MSR anyway, there is * no need to bother with specific bits, we just clear it. */ env->msr = 0; }


static void count_colors(AVCodecContext *avctx, unsigned hits[33], const AVSubtitleRect *r) { DVDSubtitleContext *dvdc = avctx->priv_data; unsigned count[256] = { 0 }; uint32_t *palette = (uint32_t *)r->pict.data[1]; uint32_t color; int x, y, i, j, match, d, best_d, av_uninit(best_j); uint8_t *p = r->pict.data[0]; for (y = 0; y < r->h; y++) { for (x = 0; x < r->w; x++) count[*(p++)]++; p += r->pict.linesize[0] - r->w; } for (i = 0; i < 256; i++) { if (!count[i]) /* avoid useless search */ continue; color = palette[i]; /* 0: transparent, 1-16: semi-transparent, 17-33 opaque */ match = color < 0x33000000 ? 0 : color < 0xCC000000 ? 1 : 17; if (match) { best_d = INT_MAX; for (j = 0; j < 16; j++) { d = color_distance(color & 0xFFFFFF, dvdc->global_palette[j]); if (d < best_d) { best_d = d; best_j = j; } } match += best_j; } hits[match] += count[i]; } }


Coroutine *qemu_coroutine_new(void) { const size_t stack_size = 1 << 20; CoroutineUContext *co; CoroutineThreadState *coTS; struct sigaction sa; struct sigaction osa; stack_t ss; stack_t oss; sigset_t sigs; sigset_t osigs; jmp_buf old_env; /* The way to manipulate stack is with the sigaltstack function. We * prepare a stack, with it delivering a signal to ourselves and then * put sigsetjmp/siglongjmp where needed. * This has been done keeping coroutine-ucontext as a model and with the * pth ideas (GNU Portable Threads). See coroutine-ucontext for the basics * of the coroutines and see pth_mctx.c (from the pth project) for the * sigaltstack way of manipulating stacks. */ co = g_malloc0(sizeof(*co)); co->stack = g_malloc(stack_size); co->base.entry_arg = &old_env; /* stash away our jmp_buf */ coTS = coroutine_get_thread_state(); coTS->tr_handler = co; /* * Preserve the SIGUSR2 signal state, block SIGUSR2, * and establish our signal handler. The signal will * later transfer control onto the signal stack. */ sigemptyset(&sigs); sigaddset(&sigs, SIGUSR2); pthread_sigmask(SIG_BLOCK, &sigs, &osigs); sa.sa_handler = coroutine_trampoline; sigfillset(&sa.sa_mask); sa.sa_flags = SA_ONSTACK; if (sigaction(SIGUSR2, &sa, &osa) != 0) { abort(); } /* * Set the new stack. */ ss.ss_sp = co->stack; ss.ss_size = stack_size; ss.ss_flags = 0; if (sigaltstack(&ss, &oss) < 0) { abort(); } /* * Now transfer control onto the signal stack and set it up. * It will return immediately via "return" after the sigsetjmp() * was performed. Be careful here with race conditions. The * signal can be delivered the first time sigsuspend() is * called. */ coTS->tr_called = 0; pthread_kill(pthread_self(), SIGUSR2); sigfillset(&sigs); sigdelset(&sigs, SIGUSR2); while (!coTS->tr_called) { sigsuspend(&sigs); } /* * Inform the system that we are back off the signal stack by * removing the alternative signal stack. Be careful here: It * first has to be disabled, before it can be removed. */ sigaltstack(NULL, &ss); ss.ss_flags = SS_DISABLE; if (sigaltstack(&ss, NULL) < 0) { abort(); } sigaltstack(NULL, &ss); if (!(oss.ss_flags & SS_DISABLE)) { sigaltstack(&oss, NULL); } /* * Restore the old SIGUSR2 signal handler and mask */ sigaction(SIGUSR2, &osa, NULL); pthread_sigmask(SIG_SETMASK, &osigs, NULL); /* * Now enter the trampoline again, but this time not as a signal * handler. Instead we jump into it directly. The functionally * redundant ping-pong pointer arithmetic is necessary to avoid * type-conversion warnings related to the `volatile' qualifier and * the fact that `jmp_buf' usually is an array type. */ if (!sigsetjmp(old_env, 0)) { siglongjmp(coTS->tr_reenter, 1); } /* * Ok, we returned again, so now we're finished */ return &co->base; }


static MemTxResult memory_region_read_with_attrs_accessor(MemoryRegion *mr, hwaddr addr, uint64_t *value, unsigned size, unsigned shift, uint64_t mask, MemTxAttrs attrs) { uint64_t tmp = 0; MemTxResult r; r = mr->ops->read_with_attrs(mr->opaque, addr, &tmp, size, attrs); if (mr->subpage) { trace_memory_region_subpage_read(get_cpu_index(), mr, addr, tmp, size); } else if (TRACE_MEMORY_REGION_OPS_READ_ENABLED) { hwaddr abs_addr = memory_region_to_absolute_addr(mr, addr); trace_memory_region_ops_read(get_cpu_index(), mr, abs_addr, tmp, size); } *value |= (tmp & mask) << shift; return r; }


void kvm_arch_remove_all_hw_breakpoints(void) { }


static inline void RENAME(rgb24ToUV)(uint8_t *dstU, uint8_t *dstV, uint8_t *src1, uint8_t *src2, int width) { int i; assert(src1==src2); for(i=0; i<width; i++) { int r= src1[6*i + 0] + src1[6*i + 3]; int g= src1[6*i + 1] + src1[6*i + 4]; int b= src1[6*i + 2] + src1[6*i + 5]; dstU[i]= ((RU*r + GU*g + BU*b)>>(RGB2YUV_SHIFT+1)) + 128; dstV[i]= ((RV*r + GV*g + BV*b)>>(RGB2YUV_SHIFT+1)) + 128; } }


void ff_filter_samples(AVFilterLink *link, AVFilterBufferRef *samplesref) { void (*filter_samples)(AVFilterLink *, AVFilterBufferRef *); AVFilterPad *dst = link->dstpad; FF_DPRINTF_START(NULL, filter_samples); ff_dlog_link(NULL, link, 1); if (!(filter_samples = dst->filter_samples)) filter_samples = ff_default_filter_samples; /* prepare to copy the samples if the buffer has insufficient permissions */ if ((dst->min_perms & samplesref->perms) != dst->min_perms || dst->rej_perms & samplesref->perms) { int i, planar = av_sample_fmt_is_planar(samplesref->format); int planes = !planar ? 1: av_get_channel_layout_nb_channels(samplesref->audio->channel_layout); av_log(link->dst, AV_LOG_DEBUG, "Copying audio data in avfilter (have perms %x, need %x, reject %x)\n", samplesref->perms, link->dstpad->min_perms, link->dstpad->rej_perms); link->cur_buf = ff_default_get_audio_buffer(link, dst->min_perms, samplesref->audio->nb_samples); link->cur_buf->pts = samplesref->pts; link->cur_buf->audio->sample_rate = samplesref->audio->sample_rate; /* Copy actual data into new samples buffer */ for (i = 0; i < planes; i++) memcpy(link->cur_buf->extended_data[i], samplesref->extended_data[i], samplesref->linesize[0]); avfilter_unref_buffer(samplesref); } else link->cur_buf = samplesref; filter_samples(link, link->cur_buf); }


int nbd_send_request(int csock, struct nbd_request *request) { uint8_t buf[4 + 4 + 8 + 8 + 4]; cpu_to_be32w((uint32_t*)buf, NBD_REQUEST_MAGIC); cpu_to_be32w((uint32_t*)(buf + 4), request->type); cpu_to_be64w((uint64_t*)(buf + 8), request->handle); cpu_to_be64w((uint64_t*)(buf + 16), request->from); cpu_to_be32w((uint32_t*)(buf + 24), request->len); TRACE("Sending request to client: " "{ .from = %" PRIu64", .len = %u, .handle = %" PRIu64", .type=%i}", request->from, request->len, request->handle, request->type); if (write_sync(csock, buf, sizeof(buf)) != sizeof(buf)) { LOG("writing to socket failed"); errno = EINVAL; return -1; } return 0; }


static int movie_push_frame(AVFilterContext *ctx, unsigned out_id) { MovieContext *movie = ctx->priv; AVPacket *pkt = &movie->pkt; enum AVMediaType frame_type; MovieStream *st; int ret, got_frame = 0, pkt_out_id; AVFilterLink *outlink; if (!pkt->size) { if (movie->eof) { if (movie->st[out_id].done) { if (movie->loop_count != 1) { ret = rewind_file(ctx); if (ret < 0) return ret; movie->loop_count -= movie->loop_count > 1; av_log(ctx, AV_LOG_VERBOSE, "Stream finished, looping.\n"); return 0; /* retry */ } return AVERROR_EOF; } pkt->stream_index = movie->st[out_id].st->index; /* packet is already ready for flushing */ } else { ret = av_read_frame(movie->format_ctx, &movie->pkt0); if (ret < 0) { av_init_packet(&movie->pkt0); /* ready for flushing */ *pkt = movie->pkt0; if (ret == AVERROR_EOF) { movie->eof = 1; return 0; /* start flushing */ } return ret; } *pkt = movie->pkt0; } } pkt_out_id = pkt->stream_index > movie->max_stream_index ? -1 : movie->out_index[pkt->stream_index]; if (pkt_out_id < 0) { av_free_packet(&movie->pkt0); pkt->size = 0; /* ready for next run */ pkt->data = NULL; return 0; } st = &movie->st[pkt_out_id]; outlink = ctx->outputs[pkt_out_id]; movie->frame = av_frame_alloc(); if (!movie->frame) return AVERROR(ENOMEM); frame_type = st->st->codec->codec_type; switch (frame_type) { case AVMEDIA_TYPE_VIDEO: ret = avcodec_decode_video2(st->st->codec, movie->frame, &got_frame, pkt); break; case AVMEDIA_TYPE_AUDIO: ret = avcodec_decode_audio4(st->st->codec, movie->frame, &got_frame, pkt); break; default: ret = AVERROR(ENOSYS); break; } if (ret < 0) { av_log(ctx, AV_LOG_WARNING, "Decode error: %s\n", av_err2str(ret)); av_frame_free(&movie->frame); av_free_packet(&movie->pkt0); movie->pkt.size = 0; movie->pkt.data = NULL; return 0; } if (!ret || st->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) ret = pkt->size; pkt->data += ret; pkt->size -= ret; if (pkt->size <= 0) { av_free_packet(&movie->pkt0); pkt->size = 0; /* ready for next run */ pkt->data = NULL; } if (!got_frame) { if (!ret) st->done = 1; av_frame_free(&movie->frame); return 0; } movie->frame->pts = av_frame_get_best_effort_timestamp(movie->frame); av_dlog(ctx, "movie_push_frame(): file:'%s' %s\n", movie->file_name, describe_frame_to_str((char[1024]){0}, 1024, movie->frame, frame_type, outlink)); if (st->st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { if (movie->frame->format != outlink->format) { av_log(ctx, AV_LOG_ERROR, "Format changed %s -> %s, discarding frame\n", av_get_pix_fmt_name(outlink->format), av_get_pix_fmt_name(movie->frame->format) ); av_frame_free(&movie->frame); return 0; } } ret = ff_filter_frame(outlink, movie->frame); movie->frame = NULL; if (ret < 0) return ret; return pkt_out_id == out_id; }


void blk_remove_bs(BlockBackend *blk) { BlockDriverState *bs; ThrottleTimers *tt; notifier_list_notify(&blk->remove_bs_notifiers, blk); if (blk->public.throttle_group_member.throttle_state) { tt = &blk->public.throttle_group_member.throttle_timers; bs = blk_bs(blk); bdrv_drained_begin(bs); throttle_timers_detach_aio_context(tt); bdrv_drained_end(bs); } blk_update_root_state(blk); bdrv_root_unref_child(blk->root); blk->root = NULL; }


static void vmsvga_init(DeviceState *dev, struct vmsvga_state_s *s, MemoryRegion *address_space, MemoryRegion *io) { s->scratch_size = SVGA_SCRATCH_SIZE; s->scratch = g_malloc(s->scratch_size * 4); s->vga.con = graphic_console_init(dev, 0, &vmsvga_ops, s); s->fifo_size = SVGA_FIFO_SIZE; memory_region_init_ram(&s->fifo_ram, NULL, "vmsvga.fifo", s->fifo_size, &error_abort); vmstate_register_ram_global(&s->fifo_ram); s->fifo_ptr = memory_region_get_ram_ptr(&s->fifo_ram); vga_common_init(&s->vga, OBJECT(dev), true); vga_init(&s->vga, OBJECT(dev), address_space, io, true); vmstate_register(NULL, 0, &vmstate_vga_common, &s->vga); s->new_depth = 32; }


static void x86_cpu_common_class_init(ObjectClass *oc, void *data) { X86CPUClass *xcc = X86_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); DeviceClass *dc = DEVICE_CLASS(oc); xcc->parent_realize = dc->realize; dc->realize = x86_cpu_realizefn; dc->props = x86_cpu_properties; xcc->parent_reset = cc->reset; cc->reset = x86_cpu_reset; cc->reset_dump_flags = CPU_DUMP_FPU | CPU_DUMP_CCOP; cc->class_by_name = x86_cpu_class_by_name; cc->parse_features = x86_cpu_parse_featurestr; cc->has_work = x86_cpu_has_work; cc->do_interrupt = x86_cpu_do_interrupt; cc->cpu_exec_interrupt = x86_cpu_exec_interrupt; cc->dump_state = x86_cpu_dump_state; cc->set_pc = x86_cpu_set_pc; cc->synchronize_from_tb = x86_cpu_synchronize_from_tb; cc->gdb_read_register = x86_cpu_gdb_read_register; cc->gdb_write_register = x86_cpu_gdb_write_register; cc->get_arch_id = x86_cpu_get_arch_id; cc->get_paging_enabled = x86_cpu_get_paging_enabled; #ifdef CONFIG_USER_ONLY cc->handle_mmu_fault = x86_cpu_handle_mmu_fault; #else cc->get_memory_mapping = x86_cpu_get_memory_mapping; cc->get_phys_page_debug = x86_cpu_get_phys_page_debug; cc->write_elf64_note = x86_cpu_write_elf64_note; cc->write_elf64_qemunote = x86_cpu_write_elf64_qemunote; cc->write_elf32_note = x86_cpu_write_elf32_note; cc->write_elf32_qemunote = x86_cpu_write_elf32_qemunote; cc->vmsd = &vmstate_x86_cpu; #endif cc->gdb_num_core_regs = CPU_NB_REGS * 2 + 25; #ifndef CONFIG_USER_ONLY cc->debug_excp_handler = breakpoint_handler; #endif cc->cpu_exec_enter = x86_cpu_exec_enter; cc->cpu_exec_exit = x86_cpu_exec_exit; }


static int ds1225y_set_to_mode(ds1225y_t *NVRAM, nvram_open_mode mode, const char *filemode) { if (NVRAM->open_mode != mode) { if (NVRAM->file) qemu_fclose(NVRAM->file); NVRAM->file = qemu_fopen(NVRAM->filename, filemode); NVRAM->open_mode = mode; } return (NVRAM->file != NULL); }


static int usb_wacom_handle_data(USBDevice *dev, USBPacket *p) { USBWacomState *s = (USBWacomState *) dev; int ret = 0; switch (p->pid) { case USB_TOKEN_IN: if (p->devep == 1) { if (!(s->changed || s->idle)) return USB_RET_NAK; s->changed = 0; if (s->mode == WACOM_MODE_HID) ret = usb_mouse_poll(s, p->data, p->len); else if (s->mode == WACOM_MODE_WACOM) ret = usb_wacom_poll(s, p->data, p->len); break; } /* Fall through. */ case USB_TOKEN_OUT: default: ret = USB_RET_STALL; break; } return ret; }


static float quantize_band_cost(struct AACEncContext *s, const float *in, const float *scaled, int size, int scale_idx, int cb, const float lambda, const float uplim, int *bits) { const float IQ = ff_aac_pow2sf_tab[200 + scale_idx - SCALE_ONE_POS + SCALE_DIV_512]; const float Q = ff_aac_pow2sf_tab[200 - scale_idx + SCALE_ONE_POS - SCALE_DIV_512]; const float CLIPPED_ESCAPE = 165140.0f*IQ; int i, j, k; float cost = 0; const int dim = cb < FIRST_PAIR_BT ? 4 : 2; int resbits = 0; #ifndef USE_REALLY_FULL_SEARCH const float Q34 = sqrtf(Q * sqrtf(Q)); const int range = aac_cb_range[cb]; const int maxval = aac_cb_maxval[cb]; int offs[4]; #endif /* USE_REALLY_FULL_SEARCH */ if (!cb) { for (i = 0; i < size; i++) cost += in[i]*in[i]; if (bits) *bits = 0; return cost * lambda; } #ifndef USE_REALLY_FULL_SEARCH offs[0] = 1; for (i = 1; i < dim; i++) offs[i] = offs[i-1]*range; quantize_bands(s->qcoefs, in, scaled, size, Q34, !IS_CODEBOOK_UNSIGNED(cb), maxval); #endif /* USE_REALLY_FULL_SEARCH */ for (i = 0; i < size; i += dim) { float mincost; int minidx = 0; int minbits = 0; const float *vec; #ifndef USE_REALLY_FULL_SEARCH int (*quants)[2] = &s->qcoefs[i]; mincost = 0.0f; for (j = 0; j < dim; j++) mincost += in[i+j]*in[i+j]; minidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40; minbits = ff_aac_spectral_bits[cb-1][minidx]; mincost = mincost * lambda + minbits; for (j = 0; j < (1<<dim); j++) { float rd = 0.0f; int curbits; int curidx = IS_CODEBOOK_UNSIGNED(cb) ? 0 : 40; int same = 0; for (k = 0; k < dim; k++) { if ((j & (1 << k)) && quants[k][0] == quants[k][1]) { same = 1; break; } } if (same) continue; for (k = 0; k < dim; k++) curidx += quants[k][!!(j & (1 << k))] * offs[dim - 1 - k]; curbits = ff_aac_spectral_bits[cb-1][curidx]; vec = &ff_aac_codebook_vectors[cb-1][curidx*dim]; #else mincost = INFINITY; vec = ff_aac_codebook_vectors[cb-1]; for (j = 0; j < ff_aac_spectral_sizes[cb-1]; j++, vec += dim) { float rd = 0.0f; int curbits = ff_aac_spectral_bits[cb-1][j]; #endif /* USE_REALLY_FULL_SEARCH */ if (IS_CODEBOOK_UNSIGNED(cb)) { for (k = 0; k < dim; k++) { float t = fabsf(in[i+k]); float di; if (vec[k] == 64.0f) { //FIXME: slow //do not code with escape sequence small values if (t < 39.0f*IQ) { rd = INFINITY; break; } if (t >= CLIPPED_ESCAPE) { di = t - CLIPPED_ESCAPE; curbits += 21; } else { int c = av_clip(quant(t, Q), 0, 8191); di = t - c*cbrtf(c)*IQ; curbits += av_log2(c)*2 - 4 + 1; } } else { di = t - vec[k]*IQ; } if (vec[k] != 0.0f) curbits++; rd += di*di; } } else { for (k = 0; k < dim; k++) { float di = in[i+k] - vec[k]*IQ; rd += di*di; } } rd = rd * lambda + curbits; if (rd < mincost) { mincost = rd; minidx = j; minbits = curbits; } } cost += mincost; resbits += minbits; if (cost >= uplim) return uplim; } if (bits) *bits = resbits; return cost; }


static void sysbus_esp_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); dc->realize = sysbus_esp_realize; dc->reset = sysbus_esp_hard_reset; dc->vmsd = &vmstate_sysbus_esp_scsi; set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); }


static int vfio_initfn(PCIDevice *pdev) { VFIODevice *pvdev, *vdev = DO_UPCAST(VFIODevice, pdev, pdev); VFIOGroup *group; char path[PATH_MAX], iommu_group_path[PATH_MAX], *group_name; ssize_t len; struct stat st; int groupid; int ret; /* Check that the host device exists */ snprintf(path, sizeof(path), "/sys/bus/pci/devices/%04x:%02x:%02x.%01x/", vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function); if (stat(path, &st) < 0) { error_report("vfio: error: no such host device: %s", path); return -errno; } strncat(path, "iommu_group", sizeof(path) - strlen(path) - 1); len = readlink(path, iommu_group_path, PATH_MAX); if (len <= 0) { error_report("vfio: error no iommu_group for device"); return -errno; } iommu_group_path[len] = 0; group_name = basename(iommu_group_path); if (sscanf(group_name, "%d", &groupid) != 1) { error_report("vfio: error reading %s: %m", path); return -errno; } DPRINTF("%s(%04x:%02x:%02x.%x) group %d\n", __func__, vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function, groupid); group = vfio_get_group(groupid); if (!group) { error_report("vfio: failed to get group %d", groupid); return -ENOENT; } snprintf(path, sizeof(path), "%04x:%02x:%02x.%01x", vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function); QLIST_FOREACH(pvdev, &group->device_list, next) { if (pvdev->host.domain == vdev->host.domain && pvdev->host.bus == vdev->host.bus && pvdev->host.slot == vdev->host.slot && pvdev->host.function == vdev->host.function) { error_report("vfio: error: device %s is already attached", path); vfio_put_group(group); return -EBUSY; } } ret = vfio_get_device(group, path, vdev); if (ret) { error_report("vfio: failed to get device %s", path); vfio_put_group(group); return ret; } /* Get a copy of config space */ ret = pread(vdev->fd, vdev->pdev.config, MIN(pci_config_size(&vdev->pdev), vdev->config_size), vdev->config_offset); if (ret < (int)MIN(pci_config_size(&vdev->pdev), vdev->config_size)) { ret = ret < 0 ? -errno : -EFAULT; error_report("vfio: Failed to read device config space"); goto out_put; } /* vfio emulates a lot for us, but some bits need extra love */ vdev->emulated_config_bits = g_malloc0(vdev->config_size); /* QEMU can choose to expose the ROM or not */ memset(vdev->emulated_config_bits + PCI_ROM_ADDRESS, 0xff, 4); /* QEMU can change multi-function devices to single function, or reverse */ vdev->emulated_config_bits[PCI_HEADER_TYPE] = PCI_HEADER_TYPE_MULTI_FUNCTION; /* Restore or clear multifunction, this is always controlled by QEMU */ if (vdev->pdev.cap_present & QEMU_PCI_CAP_MULTIFUNCTION) { vdev->pdev.config[PCI_HEADER_TYPE] |= PCI_HEADER_TYPE_MULTI_FUNCTION; } else { vdev->pdev.config[PCI_HEADER_TYPE] &= ~PCI_HEADER_TYPE_MULTI_FUNCTION; } /* * Clear host resource mapping info. If we choose not to register a * BAR, such as might be the case with the option ROM, we can get * confusing, unwritable, residual addresses from the host here. */ memset(&vdev->pdev.config[PCI_BASE_ADDRESS_0], 0, 24); memset(&vdev->pdev.config[PCI_ROM_ADDRESS], 0, 4); vfio_pci_size_rom(vdev); ret = vfio_early_setup_msix(vdev); if (ret) { goto out_put; } vfio_map_bars(vdev); ret = vfio_add_capabilities(vdev); if (ret) { goto out_teardown; } /* QEMU emulates all of MSI & MSIX */ if (pdev->cap_present & QEMU_PCI_CAP_MSIX) { memset(vdev->emulated_config_bits + pdev->msix_cap, 0xff, MSIX_CAP_LENGTH); } if (pdev->cap_present & QEMU_PCI_CAP_MSI) { memset(vdev->emulated_config_bits + pdev->msi_cap, 0xff, vdev->msi_cap_size); } if (vfio_pci_read_config(&vdev->pdev, PCI_INTERRUPT_PIN, 1)) { vdev->intx.mmap_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, vfio_intx_mmap_enable, vdev); pci_device_set_intx_routing_notifier(&vdev->pdev, vfio_update_irq); ret = vfio_enable_intx(vdev); if (ret) { goto out_teardown; } } add_boot_device_path(vdev->bootindex, &pdev->qdev, NULL); vfio_register_err_notifier(vdev); return 0; out_teardown: pci_device_set_intx_routing_notifier(&vdev->pdev, NULL); vfio_teardown_msi(vdev); vfio_unmap_bars(vdev); out_put: g_free(vdev->emulated_config_bits); vfio_put_device(vdev); vfio_put_group(group); return ret; }