sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) { SDHCIState *s = (SDHCIState *)opaque; unsigned shift = 8 * (offset & 0x3); uint32_t mask = ~(((1ULL << (size * 8)) - 1) << shift); uint32_t value = val; value <<= shift; switch (offset & ~0x3) { case SDHC_SYSAD: s->sdmasysad = (s->sdmasysad & mask) | value; MASKED_WRITE(s->sdmasysad, mask, value); /* Writing to last byte of sdmasysad might trigger transfer */ if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt && s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) { sdhci_sdma_transfer_multi_blocks(s); break; case SDHC_BLKSIZE: if (!TRANSFERRING_DATA(s->prnsts)) { MASKED_WRITE(s->blksize, mask, value); MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16); break; case SDHC_ARGUMENT: MASKED_WRITE(s->argument, mask, value); break; case SDHC_TRNMOD: /* DMA can be enabled only if it is supported as indicated by * capabilities register */ if (!(s->capareg & SDHC_CAN_DO_DMA)) { value &= ~SDHC_TRNS_DMA; MASKED_WRITE(s->trnmod, mask, value); MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16); /* Writing to the upper byte of CMDREG triggers SD command generation */ if ((mask & 0xFF000000) || !sdhci_can_issue_command(s)) { break; sdhci_send_command(s); break; case SDHC_BDATA: if (sdhci_buff_access_is_sequential(s, offset - SDHC_BDATA)) { sdhci_write_dataport(s, value >> shift, size); break; case SDHC_HOSTCTL: if (!(mask & 0xFF0000)) { sdhci_blkgap_write(s, value >> 16); MASKED_WRITE(s->hostctl, mask, value); MASKED_WRITE(s->pwrcon, mask >> 8, value >> 8); MASKED_WRITE(s->wakcon, mask >> 24, value >> 24); if (!(s->prnsts & SDHC_CARD_PRESENT) || ((s->pwrcon >> 1) & 0x7) < 5 || !(s->capareg & (1 << (31 - ((s->pwrcon >> 1) & 0x7))))) { s->pwrcon &= ~SDHC_POWER_ON; break; case SDHC_CLKCON: if (!(mask & 0xFF000000)) { sdhci_reset_write(s, value >> 24); MASKED_WRITE(s->clkcon, mask, value); MASKED_WRITE(s->timeoutcon, mask >> 16, value >> 16); if (s->clkcon & SDHC_CLOCK_INT_EN) { s->clkcon |= SDHC_CLOCK_INT_STABLE; } else { s->clkcon &= ~SDHC_CLOCK_INT_STABLE; break; case SDHC_NORINTSTS: if (s->norintstsen & SDHC_NISEN_CARDINT) { value &= ~SDHC_NIS_CARDINT; s->norintsts &= mask | ~value; s->errintsts &= (mask >> 16) | ~(value >> 16); if (s->errintsts) { s->norintsts |= SDHC_NIS_ERR; } else { s->norintsts &= ~SDHC_NIS_ERR; sdhci_update_irq(s); break; case SDHC_NORINTSTSEN: MASKED_WRITE(s->norintstsen, mask, value); MASKED_WRITE(s->errintstsen, mask >> 16, value >> 16); s->norintsts &= s->norintstsen; s->errintsts &= s->errintstsen; if (s->errintsts) { s->norintsts |= SDHC_NIS_ERR; } else { s->norintsts &= ~SDHC_NIS_ERR; sdhci_update_irq(s); break; case SDHC_NORINTSIGEN: MASKED_WRITE(s->norintsigen, mask, value); MASKED_WRITE(s->errintsigen, mask >> 16, value >> 16); sdhci_update_irq(s); break; case SDHC_ADMAERR: MASKED_WRITE(s->admaerr, mask, value); break; case SDHC_ADMASYSADDR: s->admasysaddr = (s->admasysaddr & (0xFFFFFFFF00000000ULL | (uint64_t)mask)) | (uint64_t)value; break; case SDHC_ADMASYSADDR + 4: s->admasysaddr = (s->admasysaddr & (0x00000000FFFFFFFFULL | ((uint64_t)mask << 32))) | ((uint64_t)value << 32); break; case SDHC_FEAER: s->acmd12errsts |= value; s->errintsts |= (value >> 16) & s->errintstsen; if (s->acmd12errsts) { s->errintsts |= SDHC_EIS_CMD12ERR; if (s->errintsts) { s->norintsts |= SDHC_NIS_ERR; sdhci_update_irq(s); break; default: ERRPRINT("bad %ub write offset: addr[0x%04x] <- %u(0x%x)\n", size, (int)offset, value >> shift, value >> shift); break; DPRINT_L2("write %ub: addr[0x%04x] <- %u(0x%x)\n", size, (int)offset, value >> shift, value >> shift);


static void filter_samples(AVFilterLink *inlink, AVFilterBufferRef *buf) { AVFilterContext *ctx = inlink->dst; ASyncContext *s = ctx->priv; AVFilterLink *outlink = ctx->outputs[0]; int nb_channels = av_get_channel_layout_nb_channels(buf->audio->channel_layout); int64_t pts = (buf->pts == AV_NOPTS_VALUE) ? buf->pts : av_rescale_q(buf->pts, inlink->time_base, outlink->time_base); int out_size; int64_t delta; /* buffer data until we get the first timestamp */ if (s->pts == AV_NOPTS_VALUE) { if (pts != AV_NOPTS_VALUE) { s->pts = pts - get_delay(s); } write_to_fifo(s, buf); return; } /* now wait for the next timestamp */ if (pts == AV_NOPTS_VALUE) { write_to_fifo(s, buf); return; } /* when we have two timestamps, compute how many samples would we have * to add/remove to get proper sync between data and timestamps */ delta = pts - s->pts - get_delay(s); out_size = avresample_available(s->avr); if (labs(delta) > s->min_delta) { av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta); out_size += delta; } else if (s->resample) { int comp = av_clip(delta, -s->max_comp, s->max_comp); av_log(ctx, AV_LOG_VERBOSE, "Compensating %d samples per second.\n", comp); avresample_set_compensation(s->avr, delta, inlink->sample_rate); } if (out_size > 0) { AVFilterBufferRef *buf_out = ff_get_audio_buffer(outlink, AV_PERM_WRITE, out_size); if (!buf_out) return; avresample_read(s->avr, (void**)buf_out->extended_data, out_size); buf_out->pts = s->pts; if (delta > 0) { av_samples_set_silence(buf_out->extended_data, out_size - delta, delta, nb_channels, buf->format); } ff_filter_samples(outlink, buf_out); } else { av_log(ctx, AV_LOG_WARNING, "Non-monotonous timestamps, dropping " "whole buffer.\n"); } /* drain any remaining buffered data */ avresample_read(s->avr, NULL, avresample_available(s->avr)); s->pts = pts - avresample_get_delay(s->avr); avresample_convert(s->avr, NULL, 0, 0, (void**)buf->extended_data, buf->linesize[0], buf->audio->nb_samples); avfilter_unref_buffer(buf); }


static void bmdma_irq(void *opaque, int n, int level) { BMDMAState *bm = opaque; if (!level) { /* pass through lower */ qemu_set_irq(bm->irq, level); return; } if (bm) { bm->status |= BM_STATUS_INT; } /* trigger the real irq */ qemu_set_irq(bm->irq, level); }


iscsi_aio_cancel(BlockDriverAIOCB *blockacb) { IscsiAIOCB *acb = (IscsiAIOCB *)blockacb; IscsiLun *iscsilun = acb->iscsilun; acb->common.cb(acb->common.opaque, -ECANCELED); acb->canceled = 1; /* send a task mgmt call to the target to cancel the task on the target */ iscsi_task_mgmt_abort_task_async(iscsilun->iscsi, acb->task, iscsi_abort_task_cb, NULL); /* then also cancel the task locally in libiscsi */ iscsi_scsi_task_cancel(iscsilun->iscsi, acb->task); }


static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) { RMDemuxContext *rm = s->priv_data; AVStream *st; int i, len, res, seq = 1; int64_t timestamp, pos; int flags; for (;;) { if (rm->audio_pkt_cnt) { // If there are queued audio packet return them first st = s->streams[rm->audio_stream_num]; res = ff_rm_retrieve_cache(s, s->pb, st, st->priv_data, pkt); if(res < 0) return res; flags = 0; } else { if (rm->old_format) { RMStream *ast; st = s->streams[0]; ast = st->priv_data; timestamp = AV_NOPTS_VALUE; len = !ast->audio_framesize ? RAW_PACKET_SIZE : ast->coded_framesize * ast->sub_packet_h / 2; flags = (seq++ == 1) ? 2 : 0; pos = avio_tell(s->pb); } else { len=sync(s, &timestamp, &flags, &i, &pos); if (len > 0) st = s->streams[i]; } if(len<0 || url_feof(s->pb)) return AVERROR(EIO); res = ff_rm_parse_packet (s, s->pb, st, st->priv_data, len, pkt, &seq, flags, timestamp); if((flags&2) && (seq&0x7F) == 1) av_add_index_entry(st, pos, timestamp, 0, 0, AVINDEX_KEYFRAME); if (res) continue; } if( (st->discard >= AVDISCARD_NONKEY && !(flags&2)) || st->discard >= AVDISCARD_ALL){ av_free_packet(pkt); } else break; } return 0; }


static void do_pci_unregister_device(PCIDevice *pci_dev) { pci_dev->bus->devices[pci_dev->devfn] = NULL; pci_config_free(pci_dev); memory_region_del_subregion(&pci_dev->bus_master_container_region, &pci_dev->bus_master_enable_region); address_space_destroy(&pci_dev->bus_master_as); }


static void vhost_user_cleanup(NetClientState *nc) { VhostUserState *s = DO_UPCAST(VhostUserState, nc, nc); vhost_user_stop(s); qemu_purge_queued_packets(nc); }


static void virtio_net_tx_timer(void *opaque) { VirtIONetQueue *q = opaque; VirtIONet *n = q->n; VirtIODevice *vdev = VIRTIO_DEVICE(n); assert(vdev->vm_running); q->tx_waiting = 0; /* Just in case the driver is not ready on more */ if (!(vdev->status & VIRTIO_CONFIG_S_DRIVER_OK)) { return; } virtio_queue_set_notification(q->tx_vq, 1); virtio_net_flush_tx(q); }


static uint64_t omap_pwl_read(void *opaque, target_phys_addr_t addr, unsigned size) { struct omap_pwl_s *s = (struct omap_pwl_s *) opaque; int offset = addr & OMAP_MPUI_REG_MASK; if (size != 1) { return omap_badwidth_read8(opaque, addr); } switch (offset) { case 0x00: /* PWL_LEVEL */ return s->level; case 0x04: /* PWL_CTRL */ return s->enable; } OMAP_BAD_REG(addr); return 0; }


int ff_parse_packing_format(int *ret, const char *arg, void *log_ctx) { char *tail; int planar = strtol(arg, &tail, 10); if (*tail) { planar = (strcmp(arg, "packed") != 0); } else if (planar != 0 && planar != 1) { av_log(log_ctx, AV_LOG_ERROR, "Invalid packing format '%s'\n", arg); return AVERROR(EINVAL); } *ret = planar; return 0; }


static int kvm_get_debugregs(CPUState *env) { #ifdef KVM_CAP_DEBUGREGS struct kvm_debugregs dbgregs; int i, ret; if (!kvm_has_debugregs()) { return 0; } ret = kvm_vcpu_ioctl(env, KVM_GET_DEBUGREGS, &dbgregs); if (ret < 0) { return ret; } for (i = 0; i < 4; i++) { env->dr[i] = dbgregs.db[i]; } env->dr[4] = env->dr[6] = dbgregs.dr6; env->dr[5] = env->dr[7] = dbgregs.dr7; #endif return 0; }


static void scsi_hd_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); blkconf_blocksizes(&s->qdev.conf); s->qdev.blocksize = s->qdev.conf.logical_block_size; s->qdev.type = TYPE_DISK; if (!s->product) { s->product = g_strdup("QEMU HARDDISK"); } scsi_realize(&s->qdev, errp); }


static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t size) { VirtIONet *n = qemu_get_nic_opaque(nc); VirtIONetQueue *q = virtio_net_get_subqueue(nc); VirtIODevice *vdev = VIRTIO_DEVICE(n); struct iovec mhdr_sg[VIRTQUEUE_MAX_SIZE]; struct virtio_net_hdr_mrg_rxbuf mhdr; unsigned mhdr_cnt = 0; size_t offset, i, guest_offset; if (!virtio_net_can_receive(nc)) { return -1; } /* hdr_len refers to the header we supply to the guest */ if (!virtio_net_has_buffers(q, size + n->guest_hdr_len - n->host_hdr_len)) { return 0; } if (!receive_filter(n, buf, size)) return size; offset = i = 0; while (offset < size) { VirtQueueElement elem; int len, total; const struct iovec *sg = elem.in_sg; total = 0; if (virtqueue_pop(q->rx_vq, &elem) == 0) { if (i == 0) return -1; error_report("virtio-net unexpected empty queue: " "i %zd mergeable %d offset %zd, size %zd, " "guest hdr len %zd, host hdr len %zd " "guest features 0x%" PRIx64, i, n->mergeable_rx_bufs, offset, size, n->guest_hdr_len, n->host_hdr_len, vdev->guest_features); exit(1); } if (elem.in_num < 1) { error_report("virtio-net receive queue contains no in buffers"); exit(1); } if (i == 0) { assert(offset == 0); if (n->mergeable_rx_bufs) { mhdr_cnt = iov_copy(mhdr_sg, ARRAY_SIZE(mhdr_sg), sg, elem.in_num, offsetof(typeof(mhdr), num_buffers), sizeof(mhdr.num_buffers)); } receive_header(n, sg, elem.in_num, buf, size); offset = n->host_hdr_len; total += n->guest_hdr_len; guest_offset = n->guest_hdr_len; } else { guest_offset = 0; } /* copy in packet. ugh */ len = iov_from_buf(sg, elem.in_num, guest_offset, buf + offset, size - offset); total += len; offset += len; /* If buffers can't be merged, at this point we * must have consumed the complete packet. * Otherwise, drop it. */ if (!n->mergeable_rx_bufs && offset < size) { virtqueue_discard(q->rx_vq, &elem, total); return size; } /* signal other side */ virtqueue_fill(q->rx_vq, &elem, total, i++); } if (mhdr_cnt) { virtio_stw_p(vdev, &mhdr.num_buffers, i); iov_from_buf(mhdr_sg, mhdr_cnt, 0, &mhdr.num_buffers, sizeof mhdr.num_buffers); } virtqueue_flush(q->rx_vq, i); virtio_notify(vdev, q->rx_vq); return size; }


int usb_claim_port(USBDevice *dev) { USBBus *bus = usb_bus_from_device(dev); USBPort *port; assert(dev->port == NULL); if (dev->port_path) { QTAILQ_FOREACH(port, &bus->free, next) { if (strcmp(port->path, dev->port_path) == 0) { break; } } if (port == NULL) { error_report("Error: usb port %s (bus %s) not found (in use?)", dev->port_path, bus->qbus.name); return -1; } } else { if (bus->nfree == 1 && strcmp(object_get_typename(OBJECT(dev)), "usb-hub") != 0) { /* Create a new hub and chain it on */ usb_create_simple(bus, "usb-hub"); } if (bus->nfree == 0) { error_report("Error: tried to attach usb device %s to a bus " "with no free ports", dev->product_desc); return -1; } port = QTAILQ_FIRST(&bus->free); } trace_usb_port_claim(bus->busnr, port->path); QTAILQ_REMOVE(&bus->free, port, next); bus->nfree--; dev->port = port; port->dev = dev; QTAILQ_INSERT_TAIL(&bus->used, port, next); bus->nused++; return 0; }


lqspi_read(void *opaque, hwaddr addr, unsigned int size) { int i; XilinxQSPIPS *q = opaque; XilinxSPIPS *s = opaque; uint32_t ret; if (addr >= q->lqspi_cached_addr && addr <= q->lqspi_cached_addr + LQSPI_CACHE_SIZE - 4) { ret = q->lqspi_buf[(addr - q->lqspi_cached_addr) >> 2]; DB_PRINT("addr: %08x, data: %08x\n", (unsigned)addr, (unsigned)ret); return ret; } else { int flash_addr = (addr / num_effective_busses(s)); int slave = flash_addr >> LQSPI_ADDRESS_BITS; int cache_entry = 0; DB_PRINT("config reg status: %08x\n", s->regs[R_LQSPI_CFG]); fifo8_reset(&s->tx_fifo); fifo8_reset(&s->rx_fifo); s->regs[R_CONFIG] &= ~CS; s->regs[R_CONFIG] |= ((~(1 << slave) << CS_SHIFT) & CS) | MANUAL_CS; xilinx_spips_update_cs_lines(s); /* instruction */ DB_PRINT("pushing read instruction: %02x\n", (uint8_t)(s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE)); fifo8_push(&s->tx_fifo, s->regs[R_LQSPI_CFG] & LQSPI_CFG_INST_CODE); /* read address */ DB_PRINT("pushing read address %06x\n", flash_addr); fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 16)); fifo8_push(&s->tx_fifo, (uint8_t)(flash_addr >> 8)); fifo8_push(&s->tx_fifo, (uint8_t)flash_addr); /* mode bits */ if (s->regs[R_LQSPI_CFG] & LQSPI_CFG_MODE_EN) { fifo8_push(&s->tx_fifo, extract32(s->regs[R_LQSPI_CFG], LQSPI_CFG_MODE_SHIFT, LQSPI_CFG_MODE_WIDTH)); } /* dummy bytes */ for (i = 0; i < (extract32(s->regs[R_LQSPI_CFG], LQSPI_CFG_DUMMY_SHIFT, LQSPI_CFG_DUMMY_WIDTH)); ++i) { DB_PRINT("pushing dummy byte\n"); fifo8_push(&s->tx_fifo, 0); } xilinx_spips_update_cs_lines(s); xilinx_spips_flush_txfifo(s); fifo8_reset(&s->rx_fifo); DB_PRINT("starting QSPI data read\n"); for (i = 0; i < LQSPI_CACHE_SIZE / 4; ++i) { tx_data_bytes(s, 0, 4); xilinx_spips_flush_txfifo(s); rx_data_bytes(s, &q->lqspi_buf[cache_entry], 4); cache_entry++; } xilinx_spips_update_cs_lines(s); s->regs[R_CONFIG] |= CS; xilinx_spips_update_cs_lines(s); q->lqspi_cached_addr = addr; return lqspi_read(opaque, addr, size); } }


static int send_jpeg_rect(VncState *vs, int x, int y, int w, int h, int quality) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; struct jpeg_destination_mgr manager; JSAMPROW row[1]; uint8_t *buf; int dy; if (ds_get_bytes_per_pixel(vs->ds) == 1) return send_full_color_rect(vs, w, h); buf = qemu_malloc(w * 3); row[0] = buf; buffer_reserve(&vs->tight_jpeg, 2048); cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); cinfo.client_data = vs; cinfo.image_width = w; cinfo.image_height = h; cinfo.input_components = 3; cinfo.in_color_space = JCS_RGB; jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, true); manager.init_destination = jpeg_init_destination; manager.empty_output_buffer = jpeg_empty_output_buffer; manager.term_destination = jpeg_term_destination; cinfo.dest = &manager; jpeg_start_compress(&cinfo, true); for (dy = 0; dy < h; dy++) { jpeg_prepare_row(vs, buf, x, y + dy, w); jpeg_write_scanlines(&cinfo, row, 1); } jpeg_finish_compress(&cinfo); jpeg_destroy_compress(&cinfo); vnc_write_u8(vs, VNC_TIGHT_JPEG << 4); tight_send_compact_size(vs, vs->tight_jpeg.offset); vnc_write(vs, vs->tight_jpeg.buffer, vs->tight_jpeg.offset); buffer_reset(&vs->tight_jpeg); return 1; }


static int alsa_init_out (HWVoiceOut *hw, audsettings_t *as) { ALSAVoiceOut *alsa = (ALSAVoiceOut *) hw; struct alsa_params_req req; struct alsa_params_obt obt; snd_pcm_t *handle; audsettings_t obt_as; req.fmt = aud_to_alsafmt (as->fmt); req.freq = as->freq; req.nchannels = as->nchannels; req.period_size = conf.period_size_out; req.buffer_size = conf.buffer_size_out; req.size_in_usec = conf.size_in_usec_out; req.override_mask = !!conf.period_size_out_overridden | (!!conf.buffer_size_out_overridden << 1); if (alsa_open (0, &req, &obt, &handle)) { return -1; } obt_as.freq = obt.freq; obt_as.nchannels = obt.nchannels; obt_as.fmt = obt.fmt; obt_as.endianness = obt.endianness; audio_pcm_init_info (&hw->info, &obt_as); hw->samples = obt.samples; alsa->pcm_buf = audio_calloc (AUDIO_FUNC, obt.samples, 1 << hw->info.shift); if (!alsa->pcm_buf) { dolog ("Could not allocate DAC buffer (%d samples, each %d bytes)\n", hw->samples, 1 << hw->info.shift); alsa_anal_close (&handle); return -1; } alsa->handle = handle; return 0; }


static int query_format(struct vf_instance *vf, unsigned int fmt) { /* FIXME - figure out which other formats work */ switch (fmt) { case IMGFMT_YV12: case IMGFMT_IYUV: case IMGFMT_I420: return ff_vf_next_query_format(vf, fmt); } return 0; }


static void vfio_probe_ati_bar4_quirk(VFIOPCIDevice *vdev, int nr) { VFIOQuirk *quirk; VFIOConfigWindowQuirk *window; /* This windows doesn't seem to be used except by legacy VGA code */ if (!vfio_pci_is(vdev, PCI_VENDOR_ID_ATI, PCI_ANY_ID) || !vdev->has_vga || nr != 4) { return; } quirk = g_malloc0(sizeof(*quirk)); quirk->mem = g_new0(MemoryRegion, 2); quirk->nr_mem = 2; window = quirk->data = g_malloc0(sizeof(*window) + sizeof(VFIOConfigWindowMatch)); window->vdev = vdev; window->address_offset = 0; window->data_offset = 4; window->nr_matches = 1; window->matches[0].match = 0x4000; window->matches[0].mask = PCIE_CONFIG_SPACE_SIZE - 1; window->bar = nr; window->addr_mem = &quirk->mem[0]; window->data_mem = &quirk->mem[1]; memory_region_init_io(window->addr_mem, OBJECT(vdev), &vfio_generic_window_address_quirk, window, "vfio-ati-bar4-window-address-quirk", 4); memory_region_add_subregion_overlap(&vdev->bars[nr].region.mem, window->address_offset, window->addr_mem, 1); memory_region_init_io(window->data_mem, OBJECT(vdev), &vfio_generic_window_data_quirk, window, "vfio-ati-bar4-window-data-quirk", 4); memory_region_add_subregion_overlap(&vdev->bars[nr].region.mem, window->data_offset, window->data_mem, 1); QLIST_INSERT_HEAD(&vdev->bars[nr].quirks, quirk, next); trace_vfio_quirk_ati_bar4_probe(vdev->vbasedev.name); }


int coroutine_fn bdrv_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) { trace_bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags); if (!(bs->open_flags & BDRV_O_UNMAP)) { flags &= ~BDRV_REQ_MAY_UNMAP; } return bdrv_co_do_writev(bs, sector_num, nb_sectors, NULL, BDRV_REQ_ZERO_WRITE | flags); }


void axisdev88_init (ram_addr_t ram_size, int vga_ram_size, const char *boot_device, DisplayState *ds, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env; struct etraxfs_pic *pic; void *etraxfs_dmac; struct etraxfs_dma_client *eth[2] = {NULL, NULL}; int kernel_size; int i; int nand_regs; int gpio_regs; ram_addr_t phys_ram; ram_addr_t phys_intmem; /* init CPUs */ if (cpu_model == NULL) { cpu_model = "crisv32"; } env = cpu_init(cpu_model); qemu_register_reset(main_cpu_reset, env); /* allocate RAM */ phys_ram = qemu_ram_alloc(ram_size); cpu_register_physical_memory(0x40000000, ram_size, phys_ram | IO_MEM_RAM); /* The ETRAX-FS has 128Kb on chip ram, the docs refer to it as the internal memory. */ phys_intmem = qemu_ram_alloc(INTMEM_SIZE); cpu_register_physical_memory(0x38000000, INTMEM_SIZE, phys_intmem | IO_MEM_RAM); /* Attach a NAND flash to CS1. */ nand_state.nand = nand_init(NAND_MFR_STMICRO, 0x39); nand_regs = cpu_register_io_memory(0, nand_read, nand_write, &nand_state); cpu_register_physical_memory(0x10000000, 0x05000000, nand_regs); gpio_state.nand = &nand_state; gpio_regs = cpu_register_io_memory(0, gpio_read, gpio_write, &gpio_state); cpu_register_physical_memory(0x3001a000, 0x5c, gpio_regs); pic = etraxfs_pic_init(env, 0x3001c000); etraxfs_dmac = etraxfs_dmac_init(env, 0x30000000, 10); for (i = 0; i < 10; i++) { /* On ETRAX, odd numbered channels are inputs. */ etraxfs_dmac_connect(etraxfs_dmac, i, pic->irq + 7 + i, i & 1); } /* Add the two ethernet blocks. */ eth[0] = etraxfs_eth_init(&nd_table[0], env, pic->irq + 25, 0x30034000); if (nb_nics > 1) eth[1] = etraxfs_eth_init(&nd_table[1], env, pic->irq + 26, 0x30036000); /* The DMA Connector block is missing, hardwire things for now. */ etraxfs_dmac_connect_client(etraxfs_dmac, 0, eth[0]); etraxfs_dmac_connect_client(etraxfs_dmac, 1, eth[0] + 1); if (eth[1]) { etraxfs_dmac_connect_client(etraxfs_dmac, 6, eth[1]); etraxfs_dmac_connect_client(etraxfs_dmac, 7, eth[1] + 1); } /* 2 timers. */ etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3001e000); etraxfs_timer_init(env, pic->irq + 0x1b, pic->nmi + 1, 0x3005e000); for (i = 0; i < 4; i++) { if (serial_hds[i]) { etraxfs_ser_init(env, pic->irq + 0x14 + i, serial_hds[i], 0x30026000 + i * 0x2000); } } if (kernel_filename) { uint64_t entry, high; int kcmdline_len; /* Boots a kernel elf binary, os/linux-2.6/vmlinux from the axis devboard SDK. */ kernel_size = load_elf(kernel_filename, -0x80000000LL, &entry, NULL, &high); bootstrap_pc = entry; if (kernel_size < 0) { /* Takes a kimage from the axis devboard SDK. */ kernel_size = load_image(kernel_filename, phys_ram_base + 0x4000); bootstrap_pc = 0x40004000; env->regs[9] = 0x40004000 + kernel_size; } env->regs[8] = 0x56902387; /* RAM init magic. */ if (kernel_cmdline && (kcmdline_len = strlen(kernel_cmdline))) { if (kcmdline_len > 256) { fprintf(stderr, "Too long CRIS kernel cmdline (max 256)\n"); exit(1); } pstrcpy_targphys(high, 256, kernel_cmdline); /* Let the kernel know we are modifying the cmdline. */ env->regs[10] = 0x87109563; env->regs[11] = high; } } env->pc = bootstrap_pc; printf ("pc =%x\n", env->pc); printf ("ram size =%ld\n", ram_size); }


uint32_t HELPER(neon_abd_f32)(uint32_t a, uint32_t b) { float32 f0 = make_float32(a); float32 f1 = make_float32(b); return float32_val((float32_compare_quiet(f0, f1, NFS) == 1) ? float32_sub(f0, f1, NFS) : float32_sub(f1, f0, NFS)); }


static void xen_init_pv(MachineState *machine) { DriveInfo *dinfo; int i; /* Initialize backend core & drivers */ if (xen_be_init() != 0) { fprintf(stderr, "%s: xen backend core setup failed\n", __FUNCTION__); exit(1); } switch (xen_mode) { case XEN_ATTACH: /* nothing to do, xend handles everything */ break; #ifdef CONFIG_XEN_PV_DOMAIN_BUILD case XEN_CREATE: { const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; if (xen_domain_build_pv(kernel_filename, initrd_filename, kernel_cmdline) < 0) { fprintf(stderr, "xen pv domain creation failed\n"); exit(1); } break; } #endif case XEN_EMULATE: fprintf(stderr, "xen emulation not implemented (yet)\n"); exit(1); break; default: fprintf(stderr, "unhandled xen_mode %d\n", xen_mode); exit(1); break; } xen_be_register_common(); xen_be_register("vfb", &xen_framebuffer_ops); xen_be_register("qnic", &xen_netdev_ops); /* configure framebuffer */ if (xenfb_enabled) { xen_config_dev_vfb(0, "vnc"); xen_config_dev_vkbd(0); } /* configure disks */ for (i = 0; i < 16; i++) { dinfo = drive_get(IF_XEN, 0, i); if (!dinfo) continue; xen_config_dev_blk(dinfo); } /* configure nics */ for (i = 0; i < nb_nics; i++) { if (!nd_table[i].model || 0 != strcmp(nd_table[i].model, "xen")) continue; xen_config_dev_nic(nd_table + i); } /* config cleanup hook */ atexit(xen_config_cleanup); /* setup framebuffer */ xen_init_display(xen_domid); }


static void iohandler_init(void) { if (!iohandler_ctx) { iohandler_ctx = aio_context_new(&error_abort); } }


static void tcg_out_tb_finalize(TCGContext *s) { static const void * const helpers[8] = { helper_ret_stb_mmu, helper_le_stw_mmu, helper_le_stl_mmu, helper_le_stq_mmu, helper_ret_ldub_mmu, helper_le_lduw_mmu, helper_le_ldul_mmu, helper_le_ldq_mmu, }; tcg_insn_unit *thunks[8] = { }; TCGLabelQemuLdst *l; for (l = s->be->labels; l != NULL; l = l->next) { long x = l->is_ld * 4 + l->size; tcg_insn_unit *dest = thunks[x]; /* The out-of-line thunks are all the same; load the return address from B0, load the GP, and branch to the code. Note that we are always post-call, so the register window has rolled, so we're using incoming parameter register numbers, not outgoing. */ if (dest == NULL) { uintptr_t *desc = (uintptr_t *)helpers[x]; uintptr_t func = desc[0], gp = desc[1], disp; thunks[x] = dest = s->code_ptr; tcg_out_bundle(s, mlx, INSN_NOP_M, tcg_opc_l2 (gp), tcg_opc_x2 (TCG_REG_P0, OPC_MOVL_X2, TCG_REG_R1, gp)); tcg_out_bundle(s, mii, INSN_NOP_M, INSN_NOP_I, tcg_opc_i22(TCG_REG_P0, OPC_MOV_I22, l->is_ld ? TCG_REG_R35 : TCG_REG_R36, TCG_REG_B0)); disp = (tcg_insn_unit *)func - s->code_ptr; tcg_out_bundle(s, mLX, INSN_NOP_M, tcg_opc_l3 (disp), tcg_opc_x3 (TCG_REG_P0, OPC_BRL_SPTK_MANY_X3, disp)); } reloc_pcrel21b_slot2(l->label_ptr, dest); } }


void bdrv_set_dirty_iter(HBitmapIter *hbi, int64_t offset) { assert(hbi->hb); hbitmap_iter_init(hbi, hbi->hb, offset); }


static uint32_t qpi_mem_readw(void *opaque, target_phys_addr_t addr) { return 0; }


static av_always_inline void hl_decode_mb_idct_luma(const H264Context *h, H264SliceContext *sl, int mb_type, int simple, int transform_bypass, int pixel_shift, const int *block_offset, int linesize, uint8_t *dest_y, int p) { void (*idct_add)(uint8_t *dst, int16_t *block, int stride); int i; block_offset += 16 * p; if (!IS_INTRA4x4(mb_type)) { if (IS_INTRA16x16(mb_type)) { if (transform_bypass) { if (h->sps.profile_idc == 244 && (sl->intra16x16_pred_mode == VERT_PRED8x8 || sl->intra16x16_pred_mode == HOR_PRED8x8)) { h->hpc.pred16x16_add[sl->intra16x16_pred_mode](dest_y, block_offset, sl->mb + (p * 256 << pixel_shift), linesize); } else { for (i = 0; i < 16; i++) if (sl->non_zero_count_cache[scan8[i + p * 16]] || dctcoef_get(sl->mb, pixel_shift, i * 16 + p * 256)) h->h264dsp.h264_add_pixels4_clear(dest_y + block_offset[i], sl->mb + (i * 16 + p * 256 << pixel_shift), linesize); } } else { h->h264dsp.h264_idct_add16intra(dest_y, block_offset, sl->mb + (p * 256 << pixel_shift), linesize, sl->non_zero_count_cache + p * 5 * 8); } } else if (sl->cbp & 15) { if (transform_bypass) { const int di = IS_8x8DCT(mb_type) ? 4 : 1; idct_add = IS_8x8DCT(mb_type) ? h->h264dsp.h264_add_pixels8_clear : h->h264dsp.h264_add_pixels4_clear; for (i = 0; i < 16; i += di) if (sl->non_zero_count_cache[scan8[i + p * 16]]) idct_add(dest_y + block_offset[i], sl->mb + (i * 16 + p * 256 << pixel_shift), linesize); } else { if (IS_8x8DCT(mb_type)) h->h264dsp.h264_idct8_add4(dest_y, block_offset, sl->mb + (p * 256 << pixel_shift), linesize, sl->non_zero_count_cache + p * 5 * 8); else h->h264dsp.h264_idct_add16(dest_y, block_offset, sl->mb + (p * 256 << pixel_shift), linesize, sl->non_zero_count_cache + p * 5 * 8); } } } }


static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn) { TCGv_i32 r_asi, r_size, r_sign; TCGv_i64 s64, d64 = tcg_temp_new_i64(); r_asi = gen_get_asi(dc, insn); r_size = tcg_const_i32(1); r_sign = tcg_const_i32(0); gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_size, r_sign); tcg_temp_free_i32(r_sign); s64 = tcg_const_i64(0xff); gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_size); tcg_temp_free_i64(s64); tcg_temp_free_i32(r_size); tcg_temp_free_i32(r_asi); tcg_gen_trunc_i64_tl(dst, d64); tcg_temp_free_i64(d64); }


float32 HELPER(ucf64_df2si)(float64 x, CPUUniCore32State *env) { return ucf64_itos(float64_to_int32(x, &env->ucf64.fp_status)); }


static int local_link(FsContext *ctx, V9fsPath *oldpath, V9fsPath *dirpath, const char *name) { int ret; V9fsString newpath; char buffer[PATH_MAX], buffer1[PATH_MAX]; v9fs_string_init(&newpath); v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name); ret = link(rpath(ctx, oldpath->data, buffer), rpath(ctx, newpath.data, buffer1)); /* now link the virtfs_metadata files */ if (!ret && (ctx->export_flags & V9FS_SM_MAPPED_FILE)) { /* Link the .virtfs_metadata files. Create the metada directory */ ret = local_create_mapped_attr_dir(ctx, newpath.data); if (ret < 0) { goto err_out; } ret = link(local_mapped_attr_path(ctx, oldpath->data, buffer), local_mapped_attr_path(ctx, newpath.data, buffer1)); if (ret < 0 && errno != ENOENT) { goto err_out; } } err_out: v9fs_string_free(&newpath); return ret; }


void ff_avg_h264_qpel4_mc02_msa(uint8_t *dst, const uint8_t *src, ptrdiff_t stride) { avc_luma_vt_and_aver_dst_4x4_msa(src - (stride * 2), stride, dst, stride); }


static void commit_complete(BlockJob *job, void *opaque) { CommitBlockJob *s = container_of(job, CommitBlockJob, common); CommitCompleteData *data = opaque; BlockDriverState *active = s->active; BlockDriverState *top = blk_bs(s->top); BlockDriverState *base = blk_bs(s->base); BlockDriverState *overlay_bs = bdrv_find_overlay(active, top); int ret = data->ret; if (!block_job_is_cancelled(&s->common) && ret == 0) { /* success */ ret = bdrv_drop_intermediate(active, top, base, s->backing_file_str); } /* restore base open flags here if appropriate (e.g., change the base back * to r/o). These reopens do not need to be atomic, since we won't abort * even on failure here */ if (s->base_flags != bdrv_get_flags(base)) { bdrv_reopen(base, s->base_flags, NULL); } if (overlay_bs && s->orig_overlay_flags != bdrv_get_flags(overlay_bs)) { bdrv_reopen(overlay_bs, s->orig_overlay_flags, NULL); } g_free(s->backing_file_str); blk_unref(s->top); blk_unref(s->base); block_job_completed(&s->common, ret); g_free(data); }


static int ide_drive_post_load(void *opaque, int version_id) { IDEState *s = opaque; if (s->identify_set) { blk_set_enable_write_cache(s->blk, !!(s->identify_data[85] & (1 << 5))); } return 0; }


void do_migrate_set_downtime(Monitor *mon, const QDict *qdict) { char *ptr; double d; const char *value = qdict_get_str(qdict, "value"); d = strtod(value, &ptr); if (!strcmp(ptr,"ms")) { d *= 1000000; } else if (!strcmp(ptr,"us")) { d *= 1000; } else if (!strcmp(ptr,"ns")) { } else { /* all else considered to be seconds */ d *= 1000000000; } max_downtime = (uint64_t)d; }


int kvm_set_ioeventfd_pio_word(int fd, uint16_t addr, uint16_t val, bool assign) { struct kvm_ioeventfd kick = { .datamatch = val, .addr = addr, .len = 2, .flags = KVM_IOEVENTFD_FLAG_DATAMATCH | KVM_IOEVENTFD_FLAG_PIO, .fd = fd, }; int r; if (!kvm_enabled()) return -ENOSYS; if (!assign) kick.flags |= KVM_IOEVENTFD_FLAG_DEASSIGN; r = kvm_vm_ioctl(kvm_state, KVM_IOEVENTFD, &kick); if (r < 0) return r; return 0; }


static inline void gen_goto_tb(DisasContext *s, int n, target_ulong dest) { if (use_goto_tb(s, dest)) { tcg_gen_goto_tb(n); gen_set_pc_im(s, dest); tcg_gen_exit_tb((uintptr_t)s->tb + n); } else { TCGv addr = tcg_temp_new(); gen_set_pc_im(s, dest); tcg_gen_extu_i32_tl(addr, cpu_R[15]); tcg_gen_lookup_and_goto_ptr(addr); tcg_temp_free(addr); } }


static int img_convert(int argc, char **argv) { int c, n, n1, bs_n, bs_i, compress, cluster_sectors, skip_create; int64_t ret = 0; int progress = 0, flags; const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename; BlockDriver *drv, *proto_drv; BlockDriverState **bs = NULL, *out_bs = NULL; int64_t total_sectors, nb_sectors, sector_num, bs_offset; int64_t *bs_sectors = NULL; uint8_t * buf = NULL; size_t bufsectors = IO_BUF_SIZE / BDRV_SECTOR_SIZE; const uint8_t *buf1; BlockDriverInfo bdi; QemuOpts *opts = NULL; QemuOptsList *create_opts = NULL; const char *out_baseimg_param; char *options = NULL; const char *snapshot_name = NULL; int min_sparse = 8; /* Need at least 4k of zeros for sparse detection */ bool quiet = false; Error *local_err = NULL; QemuOpts *sn_opts = NULL; fmt = NULL; out_fmt = "raw"; cache = "unsafe"; out_baseimg = NULL; compress = 0; skip_create = 0; for(;;) { c = getopt(argc, argv, "f:O:B:s:hce6o:pS:t:qnl:"); if (c == -1) { break; } switch(c) { case '?': case 'h': help(); break; case 'f': fmt = optarg; break; case 'O': out_fmt = optarg; break; case 'B': out_baseimg = optarg; break; case 'c': compress = 1; break; case 'e': error_report("option -e is deprecated, please use \'-o " "encryption\' instead!"); ret = -1; goto fail_getopt; case '6': error_report("option -6 is deprecated, please use \'-o " "compat6\' instead!"); ret = -1; goto fail_getopt; case 'o': if (!is_valid_option_list(optarg)) { error_report("Invalid option list: %s", optarg); ret = -1; goto fail_getopt; } if (!options) { options = g_strdup(optarg); } else { char *old_options = options; options = g_strdup_printf("%s,%s", options, optarg); g_free(old_options); } break; case 's': snapshot_name = optarg; break; case 'l': if (strstart(optarg, SNAPSHOT_OPT_BASE, NULL)) { sn_opts = qemu_opts_parse(&internal_snapshot_opts, optarg, 0); if (!sn_opts) { error_report("Failed in parsing snapshot param '%s'", optarg); ret = -1; goto fail_getopt; } } else { snapshot_name = optarg; } break; case 'S': { int64_t sval; char *end; sval = strtosz_suffix(optarg, &end, STRTOSZ_DEFSUFFIX_B); if (sval < 0 || *end) { error_report("Invalid minimum zero buffer size for sparse output specified"); ret = -1; goto fail_getopt; } min_sparse = sval / BDRV_SECTOR_SIZE; break; } case 'p': progress = 1; break; case 't': cache = optarg; break; case 'q': quiet = true; break; case 'n': skip_create = 1; break; } } /* Initialize before goto out */ if (quiet) { progress = 0; } qemu_progress_init(progress, 1.0); bs_n = argc - optind - 1; out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; if (options && has_help_option(options)) { ret = print_block_option_help(out_filename, out_fmt); goto out; } if (bs_n < 1) { error_exit("Must specify image file name"); } if (bs_n > 1 && out_baseimg) { error_report("-B makes no sense when concatenating multiple input " "images"); ret = -1; goto out; } qemu_progress_print(0, 100); bs = g_new0(BlockDriverState *, bs_n); bs_sectors = g_new(int64_t, bs_n); total_sectors = 0; for (bs_i = 0; bs_i < bs_n; bs_i++) { char *id = bs_n > 1 ? g_strdup_printf("source %d", bs_i) : g_strdup("source"); bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, BDRV_O_FLAGS, true, quiet); g_free(id); if (!bs[bs_i]) { error_report("Could not open '%s'", argv[optind + bs_i]); ret = -1; goto out; } bs_sectors[bs_i] = bdrv_nb_sectors(bs[bs_i]); if (bs_sectors[bs_i] < 0) { error_report("Could not get size of %s: %s", argv[optind + bs_i], strerror(-bs_sectors[bs_i])); ret = -1; goto out; } total_sectors += bs_sectors[bs_i]; } if (sn_opts) { ret = bdrv_snapshot_load_tmp(bs[0], qemu_opt_get(sn_opts, SNAPSHOT_OPT_ID), qemu_opt_get(sn_opts, SNAPSHOT_OPT_NAME), &local_err); } else if (snapshot_name != NULL) { if (bs_n > 1) { error_report("No support for concatenating multiple snapshot"); ret = -1; goto out; } bdrv_snapshot_load_tmp_by_id_or_name(bs[0], snapshot_name, &local_err); } if (local_err) { error_report("Failed to load snapshot: %s", error_get_pretty(local_err)); error_free(local_err); ret = -1; goto out; } /* Find driver and parse its options */ drv = bdrv_find_format(out_fmt); if (!drv) { error_report("Unknown file format '%s'", out_fmt); ret = -1; goto out; } proto_drv = bdrv_find_protocol(out_filename, true); if (!proto_drv) { error_report("Unknown protocol '%s'", out_filename); ret = -1; goto out; } create_opts = qemu_opts_append(create_opts, drv->create_opts); create_opts = qemu_opts_append(create_opts, proto_drv->create_opts); opts = qemu_opts_create(create_opts, NULL, 0, &error_abort); if (options && qemu_opts_do_parse(opts, options, NULL)) { error_report("Invalid options for file format '%s'", out_fmt); ret = -1; goto out; } qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_sectors * 512); ret = add_old_style_options(out_fmt, opts, out_baseimg, NULL); if (ret < 0) { goto out; } /* Get backing file name if -o backing_file was used */ out_baseimg_param = qemu_opt_get(opts, BLOCK_OPT_BACKING_FILE); if (out_baseimg_param) { out_baseimg = out_baseimg_param; } /* Check if compression is supported */ if (compress) { bool encryption = qemu_opt_get_bool(opts, BLOCK_OPT_ENCRYPT, false); const char *preallocation = qemu_opt_get(opts, BLOCK_OPT_PREALLOC); if (!drv->bdrv_write_compressed) { error_report("Compression not supported for this file format"); ret = -1; goto out; } if (encryption) { error_report("Compression and encryption not supported at " "the same time"); ret = -1; goto out; } if (preallocation && strcmp(preallocation, "off")) { error_report("Compression and preallocation not supported at " "the same time"); ret = -1; goto out; } } if (!skip_create) { /* Create the new image */ ret = bdrv_create(drv, out_filename, opts, &local_err); if (ret < 0) { error_report("%s: error while converting %s: %s", out_filename, out_fmt, error_get_pretty(local_err)); error_free(local_err); goto out; } } flags = min_sparse ? (BDRV_O_RDWR | BDRV_O_UNMAP) : BDRV_O_RDWR; ret = bdrv_parse_cache_flags(cache, &flags); if (ret < 0) { error_report("Invalid cache option: %s", cache); goto out; } out_bs = bdrv_new_open("target", out_filename, out_fmt, flags, true, quiet); if (!out_bs) { ret = -1; goto out; } bs_i = 0; bs_offset = 0; /* increase bufsectors from the default 4096 (2M) if opt_transfer_length * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB) * as maximum. */ bufsectors = MIN(32768, MAX(bufsectors, MAX(out_bs->bl.opt_transfer_length, out_bs->bl.discard_alignment)) ); buf = qemu_blockalign(out_bs, bufsectors * BDRV_SECTOR_SIZE); if (skip_create) { int64_t output_sectors = bdrv_nb_sectors(out_bs); if (output_sectors < 0) { error_report("unable to get output image length: %s\n", strerror(-output_sectors)); ret = -1; goto out; } else if (output_sectors < total_sectors) { error_report("output file is smaller than input file"); ret = -1; goto out; } } cluster_sectors = 0; ret = bdrv_get_info(out_bs, &bdi); if (ret < 0) { if (compress) { error_report("could not get block driver info"); goto out; } } else { compress = compress || bdi.needs_compressed_writes; cluster_sectors = bdi.cluster_size / BDRV_SECTOR_SIZE; } if (compress) { if (cluster_sectors <= 0 || cluster_sectors > bufsectors) { error_report("invalid cluster size"); ret = -1; goto out; } sector_num = 0; nb_sectors = total_sectors; for(;;) { int64_t bs_num; int remainder; uint8_t *buf2; nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) break; if (nb_sectors >= cluster_sectors) n = cluster_sectors; else n = nb_sectors; bs_num = sector_num - bs_offset; assert (bs_num >= 0); remainder = n; buf2 = buf; while (remainder > 0) { int nlow; while (bs_num == bs_sectors[bs_i]) { bs_offset += bs_sectors[bs_i]; bs_i++; assert (bs_i < bs_n); bs_num = 0; /* printf("changing part: sector_num=%" PRId64 ", " "bs_i=%d, bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n", sector_num, bs_i, bs_offset, bs_sectors[bs_i]); */ } assert (bs_num < bs_sectors[bs_i]); nlow = remainder > bs_sectors[bs_i] - bs_num ? bs_sectors[bs_i] - bs_num : remainder; ret = bdrv_read(bs[bs_i], bs_num, buf2, nlow); if (ret < 0) { error_report("error while reading sector %" PRId64 ": %s", bs_num, strerror(-ret)); goto out; } buf2 += nlow * 512; bs_num += nlow; remainder -= nlow; } assert (remainder == 0); if (!buffer_is_zero(buf, n * BDRV_SECTOR_SIZE)) { ret = bdrv_write_compressed(out_bs, sector_num, buf, n); if (ret != 0) { error_report("error while compressing sector %" PRId64 ": %s", sector_num, strerror(-ret)); goto out; } } sector_num += n; qemu_progress_print(100.0 * sector_num / total_sectors, 0); } /* signal EOF to align */ bdrv_write_compressed(out_bs, 0, NULL, 0); } else { int64_t sectors_to_read, sectors_read, sector_num_next_status; bool count_allocated_sectors; int has_zero_init = min_sparse ? bdrv_has_zero_init(out_bs) : 0; if (!has_zero_init && bdrv_can_write_zeroes_with_unmap(out_bs)) { ret = bdrv_make_zero(out_bs, BDRV_REQ_MAY_UNMAP); if (ret < 0) { goto out; } has_zero_init = 1; } sectors_to_read = total_sectors; count_allocated_sectors = progress && (out_baseimg || has_zero_init); restart: sector_num = 0; // total number of sectors converted so far sectors_read = 0; sector_num_next_status = 0; for(;;) { nb_sectors = total_sectors - sector_num; if (nb_sectors <= 0) { if (count_allocated_sectors) { sectors_to_read = sectors_read; count_allocated_sectors = false; goto restart; } ret = 0; break; } while (sector_num - bs_offset >= bs_sectors[bs_i]) { bs_offset += bs_sectors[bs_i]; bs_i ++; assert (bs_i < bs_n); /* printf("changing part: sector_num=%" PRId64 ", bs_i=%d, " "bs_offset=%" PRId64 ", bs_sectors=%" PRId64 "\n", sector_num, bs_i, bs_offset, bs_sectors[bs_i]); */ } if ((out_baseimg || has_zero_init) && sector_num >= sector_num_next_status) { n = nb_sectors > INT_MAX ? INT_MAX : nb_sectors; ret = bdrv_get_block_status(bs[bs_i], sector_num - bs_offset, n, &n1); if (ret < 0) { error_report("error while reading block status of sector %" PRId64 ": %s", sector_num - bs_offset, strerror(-ret)); goto out; } /* If the output image is zero initialized, we are not working * on a shared base and the input is zero we can skip the next * n1 sectors */ if (has_zero_init && !out_baseimg && (ret & BDRV_BLOCK_ZERO)) { sector_num += n1; continue; } /* If the output image is being created as a copy on write * image, assume that sectors which are unallocated in the * input image are present in both the output's and input's * base images (no need to copy them). */ if (out_baseimg) { if (!(ret & BDRV_BLOCK_DATA)) { sector_num += n1; continue; } /* The next 'n1' sectors are allocated in the input image. * Copy only those as they may be followed by unallocated * sectors. */ nb_sectors = n1; } /* avoid redundant callouts to get_block_status */ sector_num_next_status = sector_num + n1; } n = MIN(nb_sectors, bufsectors); /* round down request length to an aligned sector, but * do not bother doing this on short requests. They happen * when we found an all-zero area, and the next sector to * write will not be sector_num + n. */ if (cluster_sectors > 0 && n >= cluster_sectors) { int64_t next_aligned_sector = (sector_num + n); next_aligned_sector -= next_aligned_sector % cluster_sectors; if (sector_num + n > next_aligned_sector) { n = next_aligned_sector - sector_num; } } n = MIN(n, bs_sectors[bs_i] - (sector_num - bs_offset)); sectors_read += n; if (count_allocated_sectors) { sector_num += n; continue; } n1 = n; ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n); if (ret < 0) { error_report("error while reading sector %" PRId64 ": %s", sector_num - bs_offset, strerror(-ret)); goto out; } /* NOTE: at the same time we convert, we do not write zero sectors to have a chance to compress the image. Ideally, we should add a specific call to have the info to go faster */ buf1 = buf; while (n > 0) { if (!has_zero_init || is_allocated_sectors_min(buf1, n, &n1, min_sparse)) { ret = bdrv_write(out_bs, sector_num, buf1, n1); if (ret < 0) { error_report("error while writing sector %" PRId64 ": %s", sector_num, strerror(-ret)); goto out; } } sector_num += n1; n -= n1; buf1 += n1 * 512; } qemu_progress_print(100.0 * sectors_read / sectors_to_read, 0); } } out: if (!ret) { qemu_progress_print(100, 0); } qemu_progress_end(); qemu_opts_del(opts); qemu_opts_free(create_opts); qemu_vfree(buf); if (sn_opts) { qemu_opts_del(sn_opts); } if (out_bs) { bdrv_unref(out_bs); } if (bs) { for (bs_i = 0; bs_i < bs_n; bs_i++) { if (bs[bs_i]) { bdrv_unref(bs[bs_i]); } } g_free(bs); } g_free(bs_sectors); fail_getopt: g_free(options); if (ret) { return 1; } return 0; }


static void musb_packet(MUSBState *s, MUSBEndPoint *ep, int epnum, int pid, int len, USBCallback cb, int dir) { USBDevice *dev; int ret; int idx = epnum && dir; int ttype; /* ep->type[0,1] contains: * in bits 7:6 the speed (0 - invalid, 1 - high, 2 - full, 3 - slow) * in bits 5:4 the transfer type (BULK / INT) * in bits 3:0 the EP num */ ttype = epnum ? (ep->type[idx] >> 4) & 3 : 0; ep->timeout[dir] = musb_timeout(ttype, ep->type[idx] >> 6, ep->interval[idx]); ep->interrupt[dir] = ttype == USB_ENDPOINT_XFER_INT; ep->delayed_cb[dir] = cb; /* A wild guess on the FADDR semantics... */ usb_packet_setup(&ep->packey[dir].p, pid, ep->faddr[idx], ep->type[idx] & 0xf); usb_packet_addbuf(&ep->packey[dir].p, ep->buf[idx], len); ep->packey[dir].ep = ep; ep->packey[dir].dir = dir; dev = usb_find_device(&s->port, ep->packey[dir].p.devaddr); ret = usb_handle_packet(dev, &ep->packey[dir].p); if (ret == USB_RET_ASYNC) { ep->status[dir] = len; return; } ep->status[dir] = ret; musb_schedule_cb(&s->port, &ep->packey[dir].p); }


static bool net_tx_pkt_parse_headers(struct NetTxPkt *pkt) { struct iovec *l2_hdr, *l3_hdr; size_t bytes_read; size_t full_ip6hdr_len; uint16_t l3_proto; assert(pkt); l2_hdr = &pkt->vec[NET_TX_PKT_L2HDR_FRAG]; l3_hdr = &pkt->vec[NET_TX_PKT_L3HDR_FRAG]; bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base, ETH_MAX_L2_HDR_LEN); if (bytes_read < sizeof(struct eth_header)) { l2_hdr->iov_len = 0; return false; } l2_hdr->iov_len = sizeof(struct eth_header); switch (be16_to_cpu(PKT_GET_ETH_HDR(l2_hdr->iov_base)->h_proto)) { case ETH_P_VLAN: l2_hdr->iov_len += sizeof(struct vlan_header); break; case ETH_P_DVLAN: l2_hdr->iov_len += 2 * sizeof(struct vlan_header); break; } if (bytes_read < l2_hdr->iov_len) { l2_hdr->iov_len = 0; return false; } l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len); switch (l3_proto) { case ETH_P_IP: l3_hdr->iov_base = g_malloc(ETH_MAX_IP4_HDR_LEN); bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, l2_hdr->iov_len, l3_hdr->iov_base, sizeof(struct ip_header)); if (bytes_read < sizeof(struct ip_header)) { l3_hdr->iov_len = 0; return false; } l3_hdr->iov_len = IP_HDR_GET_LEN(l3_hdr->iov_base); pkt->l4proto = ((struct ip_header *) l3_hdr->iov_base)->ip_p; /* copy optional IPv4 header data */ bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, l2_hdr->iov_len + sizeof(struct ip_header), l3_hdr->iov_base + sizeof(struct ip_header), l3_hdr->iov_len - sizeof(struct ip_header)); if (bytes_read < l3_hdr->iov_len - sizeof(struct ip_header)) { l3_hdr->iov_len = 0; return false; } break; case ETH_P_IPV6: if (!eth_parse_ipv6_hdr(pkt->raw, pkt->raw_frags, l2_hdr->iov_len, &pkt->l4proto, &full_ip6hdr_len)) { l3_hdr->iov_len = 0; return false; } l3_hdr->iov_base = g_malloc(full_ip6hdr_len); bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, l2_hdr->iov_len, l3_hdr->iov_base, full_ip6hdr_len); if (bytes_read < full_ip6hdr_len) { l3_hdr->iov_len = 0; return false; } else { l3_hdr->iov_len = full_ip6hdr_len; } break; default: l3_hdr->iov_len = 0; break; } net_tx_pkt_calculate_hdr_len(pkt); pkt->packet_type = get_eth_packet_type(l2_hdr->iov_base); return true; }


static uint32_t bonito_sbridge_pciaddr(void *opaque, target_phys_addr_t addr) { PCIBonitoState *s = opaque; PCIHostState *phb = PCI_HOST_BRIDGE(s->pcihost); uint32_t cfgaddr; uint32_t idsel; uint32_t devno; uint32_t funno; uint32_t regno; uint32_t pciaddr; /* support type0 pci config */ if ((s->regs[BONITO_PCIMAP_CFG] & 0x10000) != 0x0) { return 0xffffffff; } cfgaddr = addr & 0xffff; cfgaddr |= (s->regs[BONITO_PCIMAP_CFG] & 0xffff) << 16; idsel = (cfgaddr & BONITO_PCICONF_IDSEL_MASK) >> BONITO_PCICONF_IDSEL_OFFSET; devno = ffs(idsel) - 1; funno = (cfgaddr & BONITO_PCICONF_FUN_MASK) >> BONITO_PCICONF_FUN_OFFSET; regno = (cfgaddr & BONITO_PCICONF_REG_MASK) >> BONITO_PCICONF_REG_OFFSET; if (idsel == 0) { fprintf(stderr, "error in bonito pci config address " TARGET_FMT_plx ",pcimap_cfg=%x\n", addr, s->regs[BONITO_PCIMAP_CFG]); exit(1); } pciaddr = PCI_ADDR(pci_bus_num(phb->bus), devno, funno, regno); DPRINTF("cfgaddr %x pciaddr %x busno %x devno %d funno %d regno %d\n", cfgaddr, pciaddr, pci_bus_num(phb->bus), devno, funno, regno); return pciaddr; }


static void ide_init1(IDEBus *bus, int unit) { static int drive_serial = 1; IDEState *s = &bus->ifs[unit]; s->bus = bus; s->unit = unit; s->drive_serial = drive_serial++; /* we need at least 2k alignment for accessing CDROMs using O_DIRECT */ s->io_buffer_total_len = IDE_DMA_BUF_SECTORS*512 + 4; s->io_buffer = qemu_memalign(2048, s->io_buffer_total_len); memset(s->io_buffer, 0, s->io_buffer_total_len); s->smart_selftest_data = qemu_blockalign(s->bs, 512); memset(s->smart_selftest_data, 0, 512); s->sector_write_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ide_sector_write_timer_cb, s); }


int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t min_size, bool exact_size) { BDRVQcowState *s = bs->opaque; int new_l1_size2, ret, i; uint64_t *new_l1_table; int64_t new_l1_table_offset, new_l1_size; uint8_t data[12]; if (min_size <= s->l1_size) return 0; if (exact_size) { new_l1_size = min_size; } else { /* Bump size up to reduce the number of times we have to grow */ new_l1_size = s->l1_size; if (new_l1_size == 0) { new_l1_size = 1; } while (min_size > new_l1_size) { new_l1_size = (new_l1_size * 3 + 1) / 2; } } if (new_l1_size > INT_MAX) { return -EFBIG; } #ifdef DEBUG_ALLOC2 fprintf(stderr, "grow l1_table from %d to %" PRId64 "\n", s->l1_size, new_l1_size); #endif new_l1_size2 = sizeof(uint64_t) * new_l1_size; new_l1_table = g_malloc0(align_offset(new_l1_size2, 512)); memcpy(new_l1_table, s->l1_table, s->l1_size * sizeof(uint64_t)); /* write new table (align to cluster) */ BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ALLOC_TABLE); new_l1_table_offset = qcow2_alloc_clusters(bs, new_l1_size2); if (new_l1_table_offset < 0) { g_free(new_l1_table); return new_l1_table_offset; } ret = qcow2_cache_flush(bs, s->refcount_block_cache); if (ret < 0) { goto fail; } /* the L1 position has not yet been updated, so these clusters must * indeed be completely free */ ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, new_l1_table_offset, new_l1_size2); if (ret < 0) { goto fail; } BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_WRITE_TABLE); for(i = 0; i < s->l1_size; i++) new_l1_table[i] = cpu_to_be64(new_l1_table[i]); ret = bdrv_pwrite_sync(bs->file, new_l1_table_offset, new_l1_table, new_l1_size2); if (ret < 0) goto fail; for(i = 0; i < s->l1_size; i++) new_l1_table[i] = be64_to_cpu(new_l1_table[i]); /* set new table */ BLKDBG_EVENT(bs->file, BLKDBG_L1_GROW_ACTIVATE_TABLE); cpu_to_be32w((uint32_t*)data, new_l1_size); cpu_to_be64wu((uint64_t*)(data + 4), new_l1_table_offset); ret = bdrv_pwrite_sync(bs->file, offsetof(QCowHeader, l1_size), data,sizeof(data)); if (ret < 0) { goto fail; } g_free(s->l1_table); qcow2_free_clusters(bs, s->l1_table_offset, s->l1_size * sizeof(uint64_t), QCOW2_DISCARD_OTHER); s->l1_table_offset = new_l1_table_offset; s->l1_table = new_l1_table; s->l1_size = new_l1_size; return 0; fail: g_free(new_l1_table); qcow2_free_clusters(bs, new_l1_table_offset, new_l1_size2, QCOW2_DISCARD_OTHER); return ret; }


static uint64_t bw_io_read(void *opaque, target_phys_addr_t addr, unsigned size) { switch (size) { case 1: return cpu_inb(addr); case 2: return cpu_inw(addr); case 4: return cpu_inl(addr); } abort(); }


static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci) { int i; static int inited; if (!inited) { inited = 1; for(i = 0;i < 256; i++) rop_to_index[i] = CIRRUS_ROP_NOP_INDEX; /* nop rop */ rop_to_index[CIRRUS_ROP_0] = 0; rop_to_index[CIRRUS_ROP_SRC_AND_DST] = 1; rop_to_index[CIRRUS_ROP_NOP] = 2; rop_to_index[CIRRUS_ROP_SRC_AND_NOTDST] = 3; rop_to_index[CIRRUS_ROP_NOTDST] = 4; rop_to_index[CIRRUS_ROP_SRC] = 5; rop_to_index[CIRRUS_ROP_1] = 6; rop_to_index[CIRRUS_ROP_NOTSRC_AND_DST] = 7; rop_to_index[CIRRUS_ROP_SRC_XOR_DST] = 8; rop_to_index[CIRRUS_ROP_SRC_OR_DST] = 9; rop_to_index[CIRRUS_ROP_NOTSRC_OR_NOTDST] = 10; rop_to_index[CIRRUS_ROP_SRC_NOTXOR_DST] = 11; rop_to_index[CIRRUS_ROP_SRC_OR_NOTDST] = 12; rop_to_index[CIRRUS_ROP_NOTSRC] = 13; rop_to_index[CIRRUS_ROP_NOTSRC_OR_DST] = 14; rop_to_index[CIRRUS_ROP_NOTSRC_AND_NOTDST] = 15; s->device_id = device_id; if (is_pci) s->bustype = CIRRUS_BUSTYPE_PCI; else s->bustype = CIRRUS_BUSTYPE_ISA; } register_ioport_write(0x3c0, 16, 1, vga_ioport_write, s); register_ioport_write(0x3b4, 2, 1, vga_ioport_write, s); register_ioport_write(0x3d4, 2, 1, vga_ioport_write, s); register_ioport_write(0x3ba, 1, 1, vga_ioport_write, s); register_ioport_write(0x3da, 1, 1, vga_ioport_write, s); register_ioport_read(0x3c0, 16, 1, vga_ioport_read, s); register_ioport_read(0x3b4, 2, 1, vga_ioport_read, s); register_ioport_read(0x3d4, 2, 1, vga_ioport_read, s); register_ioport_read(0x3ba, 1, 1, vga_ioport_read, s); register_ioport_read(0x3da, 1, 1, vga_ioport_read, s); s->vga_io_memory = cpu_register_io_memory(0, cirrus_vga_mem_read, cirrus_vga_mem_write, s); cpu_register_physical_memory(isa_mem_base + 0x000a0000, 0x20000, s->vga_io_memory); qemu_register_coalesced_mmio(isa_mem_base + 0x000a0000, 0x20000); /* I/O handler for LFB */ s->cirrus_linear_io_addr = cpu_register_io_memory(0, cirrus_linear_read, cirrus_linear_write, s); s->cirrus_linear_write = cpu_get_io_memory_write(s->cirrus_linear_io_addr); /* I/O handler for LFB */ s->cirrus_linear_bitblt_io_addr = cpu_register_io_memory(0, cirrus_linear_bitblt_read, cirrus_linear_bitblt_write, s); /* I/O handler for memory-mapped I/O */ s->cirrus_mmio_io_addr = cpu_register_io_memory(0, cirrus_mmio_read, cirrus_mmio_write, s); s->real_vram_size = (s->device_id == CIRRUS_ID_CLGD5446) ? 4096 * 1024 : 2048 * 1024; /* XXX: s->vram_size must be a power of two */ s->cirrus_addr_mask = s->real_vram_size - 1; s->linear_mmio_mask = s->real_vram_size - 256; s->get_bpp = cirrus_get_bpp; s->get_offsets = cirrus_get_offsets; s->get_resolution = cirrus_get_resolution; s->cursor_invalidate = cirrus_cursor_invalidate; s->cursor_draw_line = cirrus_cursor_draw_line; qemu_register_reset(cirrus_reset, s); cirrus_reset(s); register_savevm("cirrus_vga", 0, 2, cirrus_vga_save, cirrus_vga_load, s); }


static void translate_priority(GICState *s, int irq, int cpu, uint32_t *field, bool to_kernel) { if (to_kernel) { *field = GIC_GET_PRIORITY(irq, cpu) & 0xff; } else { gic_set_priority(s, cpu, irq, *field & 0xff); } }


static void FUNC(transquant_bypass32x32)(uint8_t *_dst, int16_t *coeffs, ptrdiff_t stride) { int x, y; pixel *dst = (pixel *)_dst; stride /= sizeof(pixel); for (y = 0; y < 32; y++) { for (x = 0; x < 32; x++) { dst[x] += *coeffs; coeffs++; } dst += stride; } }


static void ppc_heathrow_init (ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { CPUState *env = NULL; char *filename; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; ram_addr_t ram_offset, bios_offset; uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; MacIONVRAMState *nvr; int bios_size; MemoryRegion *pic_mem, *dbdma_mem, *cuda_mem; MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1), *ide_mem[2]; uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; void *dbdma; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) cpu_model = "G3"; for (i = 0; i < smp_cpus; i++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } /* Set time-base frequency to 16.6 Mhz */ cpu_ppc_tb_init(env, 16600000UL); qemu_register_reset((QEMUResetHandler*)&cpu_reset, env); } /* allocate RAM */ if (ram_size > (2047 << 20)) { fprintf(stderr, "qemu: Too much memory for this machine: %d MB, maximum 2047 MB\n", ((unsigned int)ram_size / (1 << 20))); exit(1); } ram_offset = qemu_ram_alloc(NULL, "ppc_heathrow.ram", ram_size); cpu_register_physical_memory(0, ram_size, ram_offset); /* allocate and load BIOS */ bios_offset = qemu_ram_alloc(NULL, "ppc_heathrow.bios", BIOS_SIZE); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); cpu_register_physical_memory(PROM_ADDR, BIOS_SIZE, bios_offset | IO_MEM_ROM); /* Load OpenBIOS (ELF) */ if (filename) { bios_size = load_elf(filename, 0, NULL, NULL, NULL, NULL, 1, ELF_MACHINE, 0); g_free(filename); } else { bios_size = -1; } if (bios_size < 0 || bios_size > BIOS_SIZE) { hw_error("qemu: could not load PowerPC bios '%s'\n", bios_name); exit(1); } if (linux_boot) { uint64_t lowaddr = 0; int bswap_needed; #ifdef BSWAP_NEEDED bswap_needed = 1; #else bswap_needed = 0; #endif kernel_base = KERNEL_LOAD_ADDR; kernel_size = load_elf(kernel_filename, translate_kernel_address, NULL, NULL, &lowaddr, NULL, 1, ELF_MACHINE, 0); if (kernel_size < 0) kernel_size = load_aout(kernel_filename, kernel_base, ram_size - kernel_base, bswap_needed, TARGET_PAGE_SIZE); if (kernel_size < 0) kernel_size = load_image_targphys(kernel_filename, kernel_base, ram_size - kernel_base); if (kernel_size < 0) { hw_error("qemu: could not load kernel '%s'\n", kernel_filename); exit(1); } /* load initrd */ if (initrd_filename) { initrd_base = round_page(kernel_base + kernel_size + KERNEL_GAP); initrd_size = load_image_targphys(initrd_filename, initrd_base, ram_size - initrd_base); if (initrd_size < 0) { hw_error("qemu: could not load initial ram disk '%s'\n", initrd_filename); exit(1); } cmdline_base = round_page(initrd_base + initrd_size); } else { initrd_base = 0; initrd_size = 0; cmdline_base = round_page(kernel_base + kernel_size + KERNEL_GAP); } ppc_boot_device = 'm'; } else { kernel_base = 0; kernel_size = 0; initrd_base = 0; initrd_size = 0; ppc_boot_device = '\0'; for (i = 0; boot_device[i] != '\0'; i++) { /* TOFIX: for now, the second IDE channel is not properly * used by OHW. The Mac floppy disk are not emulated. * For now, OHW cannot boot from the network. */ #if 0 if (boot_device[i] >= 'a' && boot_device[i] <= 'f') { ppc_boot_device = boot_device[i]; break; } #else if (boot_device[i] >= 'c' && boot_device[i] <= 'd') { ppc_boot_device = boot_device[i]; break; } #endif } if (ppc_boot_device == '\0') { fprintf(stderr, "No valid boot device for G3 Beige machine\n"); exit(1); } } /* Register 2 MB of ISA IO space */ isa_mmio_init(0xfe000000, 0x00200000); /* XXX: we register only 1 output pin for heathrow PIC */ heathrow_irqs = g_malloc0(smp_cpus * sizeof(qemu_irq *)); heathrow_irqs[0] = g_malloc0(smp_cpus * sizeof(qemu_irq) * 1); /* Connect the heathrow PIC outputs to the 6xx bus */ for (i = 0; i < smp_cpus; i++) { switch (PPC_INPUT(env)) { case PPC_FLAGS_INPUT_6xx: heathrow_irqs[i] = heathrow_irqs[0] + (i * 1); heathrow_irqs[i][0] = ((qemu_irq *)env->irq_inputs)[PPC6xx_INPUT_INT]; break; default: hw_error("Bus model not supported on OldWorld Mac machine\n"); } } /* init basic PC hardware */ if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) { hw_error("Only 6xx bus is supported on heathrow machine\n"); } pic = heathrow_pic_init(&pic_mem, 1, heathrow_irqs); pci_bus = pci_grackle_init(0xfec00000, pic, get_system_memory(), get_system_io()); pci_vga_init(pci_bus); escc_mem = escc_init(0x80013000, pic[0x0f], pic[0x10], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); memory_region_init_alias(escc_bar, "escc-bar", escc_mem, 0, memory_region_size(escc_mem)); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); /* First IDE channel is a MAC IDE on the MacIO bus */ dbdma = DBDMA_init(&dbdma_mem); ide_mem[0] = NULL; ide_mem[1] = pmac_ide_init(hd, pic[0x0D], dbdma, 0x16, pic[0x02]); /* Second IDE channel is a CMD646 on the PCI bus */ hd[0] = hd[MAX_IDE_DEVS]; hd[1] = hd[MAX_IDE_DEVS + 1]; hd[3] = hd[2] = NULL; pci_cmd646_ide_init(pci_bus, hd, 0); /* cuda also initialize ADB */ cuda_init(&cuda_mem, pic[0x12]); adb_kbd_init(&adb_bus); adb_mouse_init(&adb_bus); nvr = macio_nvram_init(0x2000, 4); pmac_format_nvram_partition(nvr, 0x2000); macio_init(pci_bus, PCI_DEVICE_ID_APPLE_343S1201, 1, pic_mem, dbdma_mem, cuda_mem, nvr, 2, ide_mem, escc_bar); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); } if (graphic_depth != 15 && graphic_depth != 32 && graphic_depth != 8) graphic_depth = 15; /* No PCI init: the BIOS will do it */ fw_cfg = fw_cfg_init(0, 0, CFG_ADDR, CFG_ADDR + 2); fw_cfg_add_i32(fw_cfg, FW_CFG_ID, 1); fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)ram_size); fw_cfg_add_i16(fw_cfg, FW_CFG_MACHINE_ID, ARCH_HEATHROW); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_ADDR, kernel_base); fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_SIZE, kernel_size); if (kernel_cmdline) { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, cmdline_base); pstrcpy_targphys("cmdline", cmdline_base, TARGET_PAGE_SIZE, kernel_cmdline); } else { fw_cfg_add_i32(fw_cfg, FW_CFG_KERNEL_CMDLINE, 0); } fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_ADDR, initrd_base); fw_cfg_add_i32(fw_cfg, FW_CFG_INITRD_SIZE, initrd_size); fw_cfg_add_i16(fw_cfg, FW_CFG_BOOT_DEVICE, ppc_boot_device); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_WIDTH, graphic_width); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_HEIGHT, graphic_height); fw_cfg_add_i16(fw_cfg, FW_CFG_PPC_DEPTH, graphic_depth); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_IS_KVM, kvm_enabled()); if (kvm_enabled()) { #ifdef CONFIG_KVM uint8_t *hypercall; fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, kvmppc_get_tbfreq()); hypercall = g_malloc(16); kvmppc_get_hypercall(env, hypercall, 16); fw_cfg_add_bytes(fw_cfg, FW_CFG_PPC_KVM_HC, hypercall, 16); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_KVM_PID, getpid()); #endif } else { fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_TBFREQ, get_ticks_per_sec()); } qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }


static void *qesd_thread_out (void *arg) { ESDVoiceOut *esd = arg; HWVoiceOut *hw = &esd->hw; int threshold; threshold = conf.divisor ? hw->samples / conf.divisor : 0; if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) { return NULL; } for (;;) { int decr, to_mix, rpos; for (;;) { if (esd->done) { goto exit; } if (esd->live > threshold) { break; } if (audio_pt_wait (&esd->pt, AUDIO_FUNC)) { goto exit; } } decr = to_mix = esd->live; rpos = hw->rpos; if (audio_pt_unlock (&esd->pt, AUDIO_FUNC)) { return NULL; } while (to_mix) { ssize_t written; int chunk = audio_MIN (to_mix, hw->samples - rpos); st_sample_t *src = hw->mix_buf + rpos; hw->clip (esd->pcm_buf, src, chunk); again: written = write (esd->fd, esd->pcm_buf, chunk << hw->info.shift); if (written == -1) { if (errno == EINTR || errno == EAGAIN) { goto again; } qesd_logerr (errno, "write failed\n"); return NULL; } if (written != chunk << hw->info.shift) { int wsamples = written >> hw->info.shift; int wbytes = wsamples << hw->info.shift; if (wbytes != written) { dolog ("warning: Misaligned write %d (requested %d), " "alignment %d\n", wbytes, written, hw->info.align + 1); } to_mix -= wsamples; rpos = (rpos + wsamples) % hw->samples; break; } rpos = (rpos + chunk) % hw->samples; to_mix -= chunk; } if (audio_pt_lock (&esd->pt, AUDIO_FUNC)) { return NULL; } esd->rpos = rpos; esd->live -= decr; esd->decr += decr; } exit: audio_pt_unlock (&esd->pt, AUDIO_FUNC); return NULL; }


static void v9fs_mkdir(void *opaque) { V9fsPDU *pdu = opaque; size_t offset = 7; int32_t fid; struct stat stbuf; V9fsQID qid; V9fsString name; V9fsFidState *fidp; gid_t gid; int mode; int err = 0; pdu_unmarshal(pdu, offset, "dsdd", &fid, &name, &mode, &gid); trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid); fidp = get_fid(pdu, fid); if (fidp == NULL) { err = -ENOENT; goto out_nofid; } err = v9fs_co_mkdir(pdu, fidp, &name, mode, fidp->uid, gid, &stbuf); if (err < 0) { goto out; } stat_to_qid(&stbuf, &qid); offset += pdu_marshal(pdu, offset, "Q", &qid); err = offset; trace_v9fs_mkdir_return(pdu->tag, pdu->id, qid.type, qid.version, qid.path, err); out: put_fid(pdu, fidp); out_nofid: complete_pdu(pdu->s, pdu, err); v9fs_string_free(&name); }


static void peer_test_vnet_hdr(VirtIONet *n) { NetClientState *nc = qemu_get_queue(n->nic); if (!nc->peer) { return; } n->has_vnet_hdr = qemu_peer_has_vnet_hdr(nc); }


static void tpm_tis_receive_bh(void *opaque) { TPMState *s = opaque; TPMTISEmuState *tis = &s->s.tis; uint8_t locty = s->locty_number; tis->loc[locty].sts = TPM_TIS_STS_VALID | TPM_TIS_STS_DATA_AVAILABLE; tis->loc[locty].state = TPM_TIS_STATE_COMPLETION; tis->loc[locty].r_offset = 0; tis->loc[locty].w_offset = 0; if (TPM_TIS_IS_VALID_LOCTY(tis->next_locty)) { tpm_tis_abort(s, locty); } #ifndef RAISE_STS_IRQ tpm_tis_raise_irq(s, locty, TPM_TIS_INT_DATA_AVAILABLE); #else tpm_tis_raise_irq(s, locty, TPM_TIS_INT_DATA_AVAILABLE | TPM_TIS_INT_STS_VALID); #endif }


static int omap_validate_imif_addr(struct omap_mpu_state_s *s, target_phys_addr_t addr) { return range_covers_byte(OMAP_IMIF_BASE, s->sram_size, addr); }


static void rtas_set_indicator(PowerPCCPU *cpu, sPAPRMachineState *spapr, uint32_t token, uint32_t nargs, target_ulong args, uint32_t nret, target_ulong rets) { uint32_t sensor_type; uint32_t sensor_index; uint32_t sensor_state; uint32_t ret = RTAS_OUT_SUCCESS; sPAPRDRConnector *drc; sPAPRDRConnectorClass *drck; if (nargs != 3 || nret != 1) { ret = RTAS_OUT_PARAM_ERROR; goto out; } sensor_type = rtas_ld(args, 0); sensor_index = rtas_ld(args, 1); sensor_state = rtas_ld(args, 2); if (!sensor_type_is_dr(sensor_type)) { goto out_unimplemented; } /* if this is a DR sensor we can assume sensor_index == drc_index */ drc = spapr_drc_by_index(sensor_index); if (!drc) { trace_spapr_rtas_set_indicator_invalid(sensor_index); ret = RTAS_OUT_PARAM_ERROR; goto out; } drck = SPAPR_DR_CONNECTOR_GET_CLASS(drc); switch (sensor_type) { case RTAS_SENSOR_TYPE_ISOLATION_STATE: ret = drck->set_isolation_state(drc, sensor_state); break; case RTAS_SENSOR_TYPE_DR: ret = drck->set_indicator_state(drc, sensor_state); break; case RTAS_SENSOR_TYPE_ALLOCATION_STATE: ret = drck->set_allocation_state(drc, sensor_state); break; default: goto out_unimplemented; } out: rtas_st(rets, 0, ret); return; out_unimplemented: /* currently only DR-related sensors are implemented */ trace_spapr_rtas_set_indicator_not_supported(sensor_index, sensor_type); rtas_st(rets, 0, RTAS_OUT_NOT_SUPPORTED); }


static int g2m_decode_frame(AVCodecContext *avctx, void *data, int *got_picture_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; G2MContext *c = avctx->priv_data; AVFrame *pic = data; GetByteContext bc, tbc; int magic; int got_header = 0; uint32_t chunk_size, cur_size; int chunk_type; int i; int ret; if (buf_size < 12) { av_log(avctx, AV_LOG_ERROR, "Frame should have at least 12 bytes, got %d instead\n", buf_size); return AVERROR_INVALIDDATA; } bytestream2_init(&bc, buf, buf_size); magic = bytestream2_get_be32(&bc); if ((magic & ~0xF) != MKBETAG('G', '2', 'M', '0') || (magic & 0xF) < 2 || (magic & 0xF) > 4) { av_log(avctx, AV_LOG_ERROR, "Wrong magic %08X\n", magic); return AVERROR_INVALIDDATA; } if ((magic & 0xF) != 4) { av_log(avctx, AV_LOG_ERROR, "G2M2 and G2M3 are not yet supported\n"); return AVERROR(ENOSYS); } while (bytestream2_get_bytes_left(&bc) > 5) { chunk_size = bytestream2_get_le32(&bc) - 1; chunk_type = bytestream2_get_byte(&bc); if (chunk_size > bytestream2_get_bytes_left(&bc)) { av_log(avctx, AV_LOG_ERROR, "Invalid chunk size %d type %02X\n", chunk_size, chunk_type); break; } switch (chunk_type) { case FRAME_INFO: c->got_header = 0; if (chunk_size < 21) { av_log(avctx, AV_LOG_ERROR, "Invalid frame info size %d\n", chunk_size); break; } c->width = bytestream2_get_be32(&bc); c->height = bytestream2_get_be32(&bc); if (c->width < 16 || c->width > avctx->width || c->height < 16 || c->height > avctx->height) { av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d\n", c->width, c->height); c->width = c->height = 0; bytestream2_skip(&bc, bytestream2_get_bytes_left(&bc)); } if (c->width != avctx->width || c->height != avctx->height) avcodec_set_dimensions(avctx, c->width, c->height); c->compression = bytestream2_get_be32(&bc); if (c->compression != 2 && c->compression != 3) { av_log(avctx, AV_LOG_ERROR, "Unknown compression method %d\n", c->compression); return AVERROR_PATCHWELCOME; } c->tile_width = bytestream2_get_be32(&bc); c->tile_height = bytestream2_get_be32(&bc); if (!c->tile_width || !c->tile_height) { av_log(avctx, AV_LOG_ERROR, "Invalid tile dimensions %dx%d\n", c->tile_width, c->tile_height); return AVERROR_INVALIDDATA; } c->tiles_x = (c->width + c->tile_width - 1) / c->tile_width; c->tiles_y = (c->height + c->tile_height - 1) / c->tile_height; c->bpp = bytestream2_get_byte(&bc); chunk_size -= 21; bytestream2_skip(&bc, chunk_size); if (g2m_init_buffers(c)) return AVERROR(ENOMEM); got_header = 1; break; case TILE_DATA: if (!c->tiles_x || !c->tiles_y) { av_log(avctx, AV_LOG_WARNING, "No frame header - skipping tile\n"); bytestream2_skip(&bc, bytestream2_get_bytes_left(&bc)); break; } if (chunk_size < 2) { av_log(avctx, AV_LOG_ERROR, "Invalid tile data size %d\n", chunk_size); break; } c->tile_x = bytestream2_get_byte(&bc); c->tile_y = bytestream2_get_byte(&bc); if (c->tile_x >= c->tiles_x || c->tile_y >= c->tiles_y) { av_log(avctx, AV_LOG_ERROR, "Invalid tile pos %d,%d (in %dx%d grid)\n", c->tile_x, c->tile_y, c->tiles_x, c->tiles_y); break; } chunk_size -= 2; ret = 0; switch (c->compression) { case COMPR_EPIC_J_B: av_log(avctx, AV_LOG_ERROR, "ePIC j-b compression is not implemented yet\n"); return AVERROR(ENOSYS); case COMPR_KEMPF_J_B: ret = kempf_decode_tile(c, c->tile_x, c->tile_y, buf + bytestream2_tell(&bc), chunk_size); break; } if (ret && c->framebuf) av_log(avctx, AV_LOG_ERROR, "Error decoding tile %d,%d\n", c->tile_x, c->tile_y); bytestream2_skip(&bc, chunk_size); break; case CURSOR_POS: if (chunk_size < 5) { av_log(avctx, AV_LOG_ERROR, "Invalid cursor pos size %d\n", chunk_size); break; } c->cursor_x = bytestream2_get_be16(&bc); c->cursor_y = bytestream2_get_be16(&bc); bytestream2_skip(&bc, chunk_size - 4); break; case CURSOR_SHAPE: if (chunk_size < 8) { av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d\n", chunk_size); break; } bytestream2_init(&tbc, buf + bytestream2_tell(&bc), chunk_size - 4); cur_size = bytestream2_get_be32(&tbc); c->cursor_w = bytestream2_get_byte(&tbc); c->cursor_h = bytestream2_get_byte(&tbc); c->cursor_hot_x = bytestream2_get_byte(&tbc); c->cursor_hot_y = bytestream2_get_byte(&tbc); c->cursor_fmt = bytestream2_get_byte(&tbc); if (cur_size >= chunk_size || c->cursor_w * c->cursor_h / 4 > cur_size) { av_log(avctx, AV_LOG_ERROR, "Invalid cursor data size %d\n", chunk_size); break; } g2m_load_cursor(c, &tbc); bytestream2_skip(&bc, chunk_size); break; case CHUNK_CC: case CHUNK_CD: bytestream2_skip(&bc, chunk_size); break; default: av_log(avctx, AV_LOG_WARNING, "Skipping chunk type %02X\n", chunk_type); bytestream2_skip(&bc, chunk_size); } } if (got_header) c->got_header = 1; if (c->width && c->height && c->framebuf) { if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } pic->key_frame = got_header; pic->pict_type = got_header ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; for (i = 0; i < avctx->height; i++) memcpy(pic->data[0] + i * pic->linesize[0], c->framebuf + i * c->framebuf_stride, c->width * 3); g2m_paint_cursor(c, pic->data[0], pic->linesize[0]); *got_picture_ptr = 1; } return buf_size; }


static inline void chroma_4mv_motion_lowres(MpegEncContext *s, uint8_t *dest_cb, uint8_t *dest_cr, uint8_t **ref_picture, h264_chroma_mc_func * pix_op, int mx, int my) { const int lowres = s->avctx->lowres; const int op_index = FFMIN(lowres, 2); const int block_s = 8 >> lowres; const int s_mask = (2 << lowres) - 1; const int h_edge_pos = s->h_edge_pos >> lowres + 1; const int v_edge_pos = s->v_edge_pos >> lowres + 1; int emu = 0, src_x, src_y, offset, sx, sy; uint8_t *ptr; if (s->quarter_sample) { mx /= 2; my /= 2; } /* In case of 8X8, we construct a single chroma motion vector with a special rounding */ mx = ff_h263_round_chroma(mx); my = ff_h263_round_chroma(my); sx = mx & s_mask; sy = my & s_mask; src_x = s->mb_x * block_s + (mx >> lowres + 1); src_y = s->mb_y * block_s + (my >> lowres + 1); offset = src_y * s->uvlinesize + src_x; ptr = ref_picture[1] + offset; if (s->flags & CODEC_FLAG_EMU_EDGE) { if ((unsigned) src_x > FFMAX(h_edge_pos - (!!sx) - block_s, 0) || (unsigned) src_y > FFMAX(v_edge_pos - (!!sy) - block_s, 0)) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos); ptr = s->edge_emu_buffer; emu = 1; } } sx = (sx << 2) >> lowres; sy = (sy << 2) >> lowres; pix_op[op_index](dest_cb, ptr, s->uvlinesize, block_s, sx, sy); ptr = ref_picture[2] + offset; if (emu) { s->vdsp.emulated_edge_mc(s->edge_emu_buffer, ptr, s->uvlinesize, 9, 9, src_x, src_y, h_edge_pos, v_edge_pos); ptr = s->edge_emu_buffer; } pix_op[op_index](dest_cr, ptr, s->uvlinesize, block_s, sx, sy); }


static inline int vmsvga_fifo_length(struct vmsvga_state_s *s) { int num; if (!s->config || !s->enable) { return 0; } /* Check range and alignment. */ if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) { return 0; } if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) { return 0; } if (CMD(max) > SVGA_FIFO_SIZE || CMD(min) >= SVGA_FIFO_SIZE || CMD(stop) >= SVGA_FIFO_SIZE || CMD(next_cmd) >= SVGA_FIFO_SIZE) { return 0; } if (CMD(max) < CMD(min) + 10 * 1024) { return 0; } num = CMD(next_cmd) - CMD(stop); if (num < 0) { num += CMD(max) - CMD(min); } return num >> 2; }