static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pic, int *got_packet) { ProresContext *ctx = avctx->priv_data; uint8_t *orig_buf, *buf, *slice_hdr, *slice_sizes, *tmp; uint8_t *picture_size_pos; PutBitContext pb; int x, y, i, mb, q = 0; int sizes[4] = { 0 }; int slice_hdr_size = 2 + 2 * (ctx->num_planes - 1); int frame_size, picture_size, slice_size; int pkt_size, ret; uint8_t frame_flags; *avctx->coded_frame = *pic; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; pkt_size = ctx->frame_size_upper_bound; if ((ret = ff_alloc_packet(pkt, pkt_size + FF_MIN_BUFFER_SIZE)) < 0) { av_log(avctx, AV_LOG_ERROR, "Error getting output packet.\n"); return ret; } orig_buf = pkt->data; // frame atom orig_buf += 4; // frame size bytestream_put_be32 (&orig_buf, FRAME_ID); // frame container ID buf = orig_buf; // frame header tmp = buf; buf += 2; // frame header size will be stored here bytestream_put_be16 (&buf, 0); // version 1 bytestream_put_buffer(&buf, ctx->vendor, 4); bytestream_put_be16 (&buf, avctx->width); bytestream_put_be16 (&buf, avctx->height); frame_flags = ctx->chroma_factor << 6; if (avctx->flags & CODEC_FLAG_INTERLACED_DCT) frame_flags |= pic->top_field_first ? 0x04 : 0x08; bytestream_put_byte (&buf, frame_flags); bytestream_put_byte (&buf, 0); // reserved bytestream_put_byte (&buf, avctx->color_primaries); bytestream_put_byte (&buf, avctx->color_trc); bytestream_put_byte (&buf, avctx->colorspace); bytestream_put_byte (&buf, 0x40 | (ctx->alpha_bits >> 3)); bytestream_put_byte (&buf, 0); // reserved if (ctx->quant_sel != QUANT_MAT_DEFAULT) { bytestream_put_byte (&buf, 0x03); // matrix flags - both matrices are present // luma quantisation matrix for (i = 0; i < 64; i++) bytestream_put_byte(&buf, ctx->quant_mat[i]); // chroma quantisation matrix for (i = 0; i < 64; i++) bytestream_put_byte(&buf, ctx->quant_mat[i]); } else { bytestream_put_byte (&buf, 0x00); // matrix flags - default matrices are used } bytestream_put_be16 (&tmp, buf - orig_buf); // write back frame header size for (ctx->cur_picture_idx = 0; ctx->cur_picture_idx < ctx->pictures_per_frame; ctx->cur_picture_idx++) { // picture header picture_size_pos = buf + 1; bytestream_put_byte (&buf, 0x40); // picture header size (in bits) buf += 4; // picture data size will be stored here bytestream_put_be16 (&buf, ctx->slices_per_picture); bytestream_put_byte (&buf, av_log2(ctx->mbs_per_slice) << 4); // slice width and height in MBs // seek table - will be filled during slice encoding slice_sizes = buf; buf += ctx->slices_per_picture * 2; // slices if (!ctx->force_quant) { ret = avctx->execute2(avctx, find_quant_thread, NULL, NULL, ctx->mb_height); if (ret) return ret; } for (y = 0; y < ctx->mb_height; y++) { int mbs_per_slice = ctx->mbs_per_slice; for (x = mb = 0; x < ctx->mb_width; x += mbs_per_slice, mb++) { q = ctx->force_quant ? ctx->force_quant : ctx->slice_q[mb + y * ctx->slices_width]; while (ctx->mb_width - x < mbs_per_slice) mbs_per_slice >>= 1; bytestream_put_byte(&buf, slice_hdr_size << 3); slice_hdr = buf; buf += slice_hdr_size - 1; init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8); ret = encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice); if (ret < 0) return ret; bytestream_put_byte(&slice_hdr, q); slice_size = slice_hdr_size + sizes[ctx->num_planes - 1]; for (i = 0; i < ctx->num_planes - 1; i++) { bytestream_put_be16(&slice_hdr, sizes[i]); slice_size += sizes[i]; } bytestream_put_be16(&slice_sizes, slice_size); buf += slice_size - slice_hdr_size; } } if (ctx->pictures_per_frame == 1) picture_size = buf - picture_size_pos - 6; else picture_size = buf - picture_size_pos + 1; bytestream_put_be32(&picture_size_pos, picture_size); } orig_buf -= 8; frame_size = buf - orig_buf; bytestream_put_be32(&orig_buf, frame_size); pkt->size = frame_size; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; }


void ff_lag_rac_init(lag_rac *l, GetBitContext *gb, int length) { int i, j; /* According to reference decoder "1st byte is garbage", * however, it gets skipped by the call to align_get_bits() */ align_get_bits(gb); l->bytestream_start = l->bytestream = gb->buffer + get_bits_count(gb) / 8; l->bytestream_end = l->bytestream_start + length; l->range = 0x80; l->low = *l->bytestream >> 1; l->hash_shift = FFMAX(l->scale - 8, 0); for (i = j = 0; i < 256; i++) { unsigned r = i << l->hash_shift; while (l->prob[j + 1] <= r) j++; l->range_hash[i] = j; } /* Add conversion factor to hash_shift so we don't have to in lag_get_rac. */ l->hash_shift += 23; }


void vmstate_unregister(DeviceState *dev, const VMStateDescription *vmsd, void *opaque) { SaveStateEntry *se, *new_se; QTAILQ_FOREACH_SAFE(se, &savevm_handlers, entry, new_se) { if (se->vmsd == vmsd && se->opaque == opaque) { QTAILQ_REMOVE(&savevm_handlers, se, entry); qemu_free(se);


void iothread_stop_all(void) { Object *container = object_get_objects_root(); BlockDriverState *bs; BdrvNextIterator it; for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) { AioContext *ctx = bdrv_get_aio_context(bs); if (ctx == qemu_get_aio_context()) { continue; } aio_context_acquire(ctx); bdrv_set_aio_context(bs, qemu_get_aio_context()); aio_context_release(ctx); } object_child_foreach(container, iothread_stop, NULL); }


int apic_get_interrupt(DeviceState *d) { APICState *s = DO_UPCAST(APICState, busdev.qdev, d); int intno; /* if the APIC is installed or enabled, we let the 8259 handle the IRQs */ if (!s) return -1; if (!(s->spurious_vec & APIC_SV_ENABLE)) return -1; /* XXX: spurious IRQ handling */ intno = get_highest_priority_int(s->irr); if (intno < 0) return -1; if (s->tpr && intno <= s->tpr) return s->spurious_vec & 0xff; reset_bit(s->irr, intno); set_bit(s->isr, intno); apic_update_irq(s); return intno; }


static inline void decode_residual_inter(AVSContext *h) { int block; /* get coded block pattern */ h->cbp = cbp_tab[get_ue_golomb(&h->s.gb)][1]; /* get quantizer */ if(h->cbp && !h->qp_fixed) h->qp += get_se_golomb(&h->s.gb); for(block=0;block<4;block++) if(h->cbp & (1<<block)) decode_residual_block(h,&h->s.gb,inter_2dvlc,0,h->qp, h->cy + h->luma_scan[block], h->l_stride); decode_residual_chroma(h); }


static void pfpu_write(void *opaque, target_phys_addr_t addr, uint64_t value, unsigned size) { MilkymistPFPUState *s = opaque; trace_milkymist_pfpu_memory_write(addr, value); addr >>= 2; switch (addr) { case R_CTL: if (value & CTL_START_BUSY) { pfpu_start(s); } break; case R_MESHBASE: case R_HMESHLAST: case R_VMESHLAST: case R_CODEPAGE: case R_VERTICES: case R_COLLISIONS: case R_STRAYWRITES: case R_LASTDMA: case R_PC: case R_DREGBASE: case R_CODEBASE: s->regs[addr] = value; break; case GPR_BEGIN ... GPR_END: s->gp_regs[addr - GPR_BEGIN] = value; break; case MICROCODE_BEGIN ... MICROCODE_END: s->microcode[get_microcode_address(s, addr)] = value; break; default: error_report("milkymist_pfpu: write access to unknown register 0x" TARGET_FMT_plx, addr << 2); break; } }


uint32_t vfio_pci_read_config(PCIDevice *pdev, uint32_t addr, int len) { VFIOPCIDevice *vdev = DO_UPCAST(VFIOPCIDevice, pdev, pdev); uint32_t emu_bits = 0, emu_val = 0, phys_val = 0, val; memcpy(&emu_bits, vdev->emulated_config_bits + addr, len); emu_bits = le32_to_cpu(emu_bits); if (emu_bits) { emu_val = pci_default_read_config(pdev, addr, len); } if (~emu_bits & (0xffffffffU >> (32 - len * 8))) { ssize_t ret; ret = pread(vdev->vbasedev.fd, &phys_val, len, vdev->config_offset + addr); if (ret != len) { error_report("%s(%04x:%02x:%02x.%x, 0x%x, 0x%x) failed: %m", __func__, vdev->host.domain, vdev->host.bus, vdev->host.slot, vdev->host.function, addr, len); return -errno; } phys_val = le32_to_cpu(phys_val); } val = (emu_val & emu_bits) | (phys_val & ~emu_bits); trace_vfio_pci_read_config(vdev->vbasedev.name, addr, len, val); return val; }


static void pci_device_reset(PCIDevice *dev) { int r; dev->irq_state = 0; pci_update_irq_status(dev); /* Clear all writeable bits */ pci_word_test_and_clear_mask(dev->config + PCI_COMMAND, pci_get_word(dev->wmask + PCI_COMMAND)); dev->config[PCI_CACHE_LINE_SIZE] = 0x0; dev->config[PCI_INTERRUPT_LINE] = 0x0; for (r = 0; r < PCI_NUM_REGIONS; ++r) { PCIIORegion *region = &dev->io_regions[r]; if (!region->size) { continue; } if (!(region->type & PCI_BASE_ADDRESS_SPACE_IO) && region->type & PCI_BASE_ADDRESS_MEM_TYPE_64) { pci_set_quad(dev->config + pci_bar(dev, r), region->type); } else { pci_set_long(dev->config + pci_bar(dev, r), region->type); } } pci_update_mappings(dev); }


static void xen_set_memory(struct MemoryListener *listener, MemoryRegionSection *section, bool add) { XenIOState *state = container_of(listener, XenIOState, memory_listener); hwaddr start_addr = section->offset_within_address_space; ram_addr_t size = int128_get64(section->size); bool log_dirty = memory_region_is_logging(section->mr); hvmmem_type_t mem_type; if (section->mr == &ram_memory) { return; } else { if (add) { xen_map_memory_section(xen_xc, xen_domid, state->ioservid, section); } else { xen_unmap_memory_section(xen_xc, xen_domid, state->ioservid, section); } } if (!memory_region_is_ram(section->mr)) { return; } if (log_dirty != add) { return; } trace_xen_client_set_memory(start_addr, size, log_dirty); start_addr &= TARGET_PAGE_MASK; size = TARGET_PAGE_ALIGN(size); if (add) { if (!memory_region_is_rom(section->mr)) { xen_add_to_physmap(state, start_addr, size, section->mr, section->offset_within_region); } else { mem_type = HVMMEM_ram_ro; if (xc_hvm_set_mem_type(xen_xc, xen_domid, mem_type, start_addr >> TARGET_PAGE_BITS, size >> TARGET_PAGE_BITS)) { DPRINTF("xc_hvm_set_mem_type error, addr: "TARGET_FMT_plx"\n", start_addr); } } } else { if (xen_remove_from_physmap(state, start_addr, size) < 0) { DPRINTF("physmapping does not exist at "TARGET_FMT_plx"\n", start_addr); } } }


static void hmp_mouse_move(Monitor *mon, const QDict *qdict) { int dx, dy, dz, button; const char *dx_str = qdict_get_str(qdict, "dx_str"); const char *dy_str = qdict_get_str(qdict, "dy_str"); const char *dz_str = qdict_get_try_str(qdict, "dz_str"); dx = strtol(dx_str, NULL, 0); dy = strtol(dy_str, NULL, 0); qemu_input_queue_rel(NULL, INPUT_AXIS_X, dx); qemu_input_queue_rel(NULL, INPUT_AXIS_Y, dy); if (dz_str) { dz = strtol(dz_str, NULL, 0); if (dz != 0) { button = (dz > 0) ? INPUT_BUTTON_WHEEL_UP : INPUT_BUTTON_WHEEL_DOWN; qemu_input_queue_btn(NULL, button, true); qemu_input_event_sync(); qemu_input_queue_btn(NULL, button, false); } } qemu_input_event_sync(); }


static void realview_init(ram_addr_t ram_size, const char *boot_device, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model, enum realview_board_type board_type) { CPUState *env = NULL; ram_addr_t ram_offset; DeviceState *dev, *sysctl, *gpio2; SysBusDevice *busdev; qemu_irq *irqp; qemu_irq pic[64]; qemu_irq mmc_irq[2]; PCIBus *pci_bus; NICInfo *nd; i2c_bus *i2c; int n; int done_nic = 0; qemu_irq cpu_irq[4]; int is_mpcore = 0; int is_pb = 0; uint32_t proc_id = 0; uint32_t sys_id; ram_addr_t low_ram_size; switch (board_type) { case BOARD_EB: break; case BOARD_EB_MPCORE: is_mpcore = 1; break; case BOARD_PB_A8: is_pb = 1; break; case BOARD_PBX_A9: is_mpcore = 1; is_pb = 1; break; } for (n = 0; n < smp_cpus; n++) { env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } irqp = arm_pic_init_cpu(env); cpu_irq[n] = irqp[ARM_PIC_CPU_IRQ]; } if (arm_feature(env, ARM_FEATURE_V7)) { if (is_mpcore) { proc_id = 0x0c000000; } else { proc_id = 0x0e000000; } } else if (arm_feature(env, ARM_FEATURE_V6K)) { proc_id = 0x06000000; } else if (arm_feature(env, ARM_FEATURE_V6)) { proc_id = 0x04000000; } else { proc_id = 0x02000000; } if (is_pb && ram_size > 0x20000000) { /* Core tile RAM. */ low_ram_size = ram_size - 0x20000000; ram_size = 0x20000000; ram_offset = qemu_ram_alloc(NULL, "realview.lowmem", low_ram_size); cpu_register_physical_memory(0x20000000, low_ram_size, ram_offset | IO_MEM_RAM); } ram_offset = qemu_ram_alloc(NULL, "realview.highmem", ram_size); low_ram_size = ram_size; if (low_ram_size > 0x10000000) low_ram_size = 0x10000000; /* SDRAM at address zero. */ cpu_register_physical_memory(0, low_ram_size, ram_offset | IO_MEM_RAM); if (is_pb) { /* And again at a high address. */ cpu_register_physical_memory(0x70000000, ram_size, ram_offset | IO_MEM_RAM); } else { ram_size = low_ram_size; } sys_id = is_pb ? 0x01780500 : 0xc1400400; sysctl = qdev_create(NULL, "realview_sysctl"); qdev_prop_set_uint32(sysctl, "sys_id", sys_id); qdev_init_nofail(sysctl); qdev_prop_set_uint32(sysctl, "proc_id", proc_id); sysbus_mmio_map(sysbus_from_qdev(sysctl), 0, 0x10000000); if (is_mpcore) { dev = qdev_create(NULL, is_pb ? "a9mpcore_priv": "realview_mpcore"); qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_init_nofail(dev); busdev = sysbus_from_qdev(dev); if (is_pb) { realview_binfo.smp_priv_base = 0x1f000000; } else { realview_binfo.smp_priv_base = 0x10100000; } sysbus_mmio_map(busdev, 0, realview_binfo.smp_priv_base); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); } } else { uint32_t gic_addr = is_pb ? 0x1e000000 : 0x10040000; /* For now just create the nIRQ GIC, and ignore the others. */ dev = sysbus_create_simple("realview_gic", gic_addr, cpu_irq[0]); } for (n = 0; n < 64; n++) { pic[n] = qdev_get_gpio_in(dev, n); } sysbus_create_simple("pl050_keyboard", 0x10006000, pic[20]); sysbus_create_simple("pl050_mouse", 0x10007000, pic[21]); sysbus_create_simple("pl011", 0x10009000, pic[12]); sysbus_create_simple("pl011", 0x1000a000, pic[13]); sysbus_create_simple("pl011", 0x1000b000, pic[14]); sysbus_create_simple("pl011", 0x1000c000, pic[15]); /* DMA controller is optional, apparently. */ sysbus_create_simple("pl081", 0x10030000, pic[24]); sysbus_create_simple("sp804", 0x10011000, pic[4]); sysbus_create_simple("sp804", 0x10012000, pic[5]); sysbus_create_simple("pl061", 0x10013000, pic[6]); sysbus_create_simple("pl061", 0x10014000, pic[7]); gpio2 = sysbus_create_simple("pl061", 0x10015000, pic[8]); sysbus_create_simple("pl111", 0x10020000, pic[23]); dev = sysbus_create_varargs("pl181", 0x10005000, pic[17], pic[18], NULL); /* Wire up MMC card detect and read-only signals. These have * to go to both the PL061 GPIO and the sysctl register. * Note that the PL181 orders these lines (readonly,inserted) * and the PL061 has them the other way about. Also the card * detect line is inverted. */ mmc_irq[0] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_WPROT), qdev_get_gpio_in(gpio2, 1)); mmc_irq[1] = qemu_irq_split( qdev_get_gpio_in(sysctl, ARM_SYSCTL_GPIO_MMC_CARDIN), qemu_irq_invert(qdev_get_gpio_in(gpio2, 0))); qdev_connect_gpio_out(dev, 0, mmc_irq[0]); qdev_connect_gpio_out(dev, 1, mmc_irq[1]); sysbus_create_simple("pl031", 0x10017000, pic[10]); if (!is_pb) { dev = sysbus_create_varargs("realview_pci", 0x60000000, pic[48], pic[49], pic[50], pic[51], NULL); pci_bus = (PCIBus *)qdev_get_child_bus(dev, "pci"); if (usb_enabled) { usb_ohci_init_pci(pci_bus, -1); } n = drive_get_max_bus(IF_SCSI); while (n >= 0) { pci_create_simple(pci_bus, -1, "lsi53c895a"); n--; } } for(n = 0; n < nb_nics; n++) { nd = &nd_table[n]; if (!done_nic && (!nd->model || strcmp(nd->model, is_pb ? "lan9118" : "smc91c111") == 0)) { if (is_pb) { lan9118_init(nd, 0x4e000000, pic[28]); } else { smc91c111_init(nd, 0x4e000000, pic[28]); } done_nic = 1; } else { pci_nic_init_nofail(nd, "rtl8139", NULL); } } dev = sysbus_create_simple("realview_i2c", 0x10002000, NULL); i2c = (i2c_bus *)qdev_get_child_bus(dev, "i2c"); i2c_create_slave(i2c, "ds1338", 0x68); /* Memory map for RealView Emulation Baseboard: */ /* 0x10000000 System registers. */ /* 0x10001000 System controller. */ /* 0x10002000 Two-Wire Serial Bus. */ /* 0x10003000 Reserved. */ /* 0x10004000 AACI. */ /* 0x10005000 MCI. */ /* 0x10006000 KMI0. */ /* 0x10007000 KMI1. */ /* 0x10008000 Character LCD. (EB) */ /* 0x10009000 UART0. */ /* 0x1000a000 UART1. */ /* 0x1000b000 UART2. */ /* 0x1000c000 UART3. */ /* 0x1000d000 SSPI. */ /* 0x1000e000 SCI. */ /* 0x1000f000 Reserved. */ /* 0x10010000 Watchdog. */ /* 0x10011000 Timer 0+1. */ /* 0x10012000 Timer 2+3. */ /* 0x10013000 GPIO 0. */ /* 0x10014000 GPIO 1. */ /* 0x10015000 GPIO 2. */ /* 0x10002000 Two-Wire Serial Bus - DVI. (PB) */ /* 0x10017000 RTC. */ /* 0x10018000 DMC. */ /* 0x10019000 PCI controller config. */ /* 0x10020000 CLCD. */ /* 0x10030000 DMA Controller. */ /* 0x10040000 GIC1. (EB) */ /* 0x10050000 GIC2. (EB) */ /* 0x10060000 GIC3. (EB) */ /* 0x10070000 GIC4. (EB) */ /* 0x10080000 SMC. */ /* 0x1e000000 GIC1. (PB) */ /* 0x1e001000 GIC2. (PB) */ /* 0x1e002000 GIC3. (PB) */ /* 0x1e003000 GIC4. (PB) */ /* 0x40000000 NOR flash. */ /* 0x44000000 DoC flash. */ /* 0x48000000 SRAM. */ /* 0x4c000000 Configuration flash. */ /* 0x4e000000 Ethernet. */ /* 0x4f000000 USB. */ /* 0x50000000 PISMO. */ /* 0x54000000 PISMO. */ /* 0x58000000 PISMO. */ /* 0x5c000000 PISMO. */ /* 0x60000000 PCI. */ /* 0x61000000 PCI Self Config. */ /* 0x62000000 PCI Config. */ /* 0x63000000 PCI IO. */ /* 0x64000000 PCI mem 0. */ /* 0x68000000 PCI mem 1. */ /* 0x6c000000 PCI mem 2. */ /* ??? Hack to map an additional page of ram for the secondary CPU startup code. I guess this works on real hardware because the BootROM happens to be in ROM/flash or in memory that isn't clobbered until after Linux boots the secondary CPUs. */ ram_offset = qemu_ram_alloc(NULL, "realview.hack", 0x1000); cpu_register_physical_memory(SMP_BOOT_ADDR, 0x1000, ram_offset | IO_MEM_RAM); realview_binfo.ram_size = ram_size; realview_binfo.kernel_filename = kernel_filename; realview_binfo.kernel_cmdline = kernel_cmdline; realview_binfo.initrd_filename = initrd_filename; realview_binfo.nb_cpus = smp_cpus; realview_binfo.board_id = realview_board_id[board_type]; realview_binfo.loader_start = (board_type == BOARD_PB_A8 ? 0x70000000 : 0); arm_load_kernel(first_cpu, &realview_binfo); }


static int intel_hda_post_load(void *opaque, int version) { IntelHDAState* d = opaque; int i; dprint(d, 1, "%s\n", __FUNCTION__); for (i = 0; i < ARRAY_SIZE(d->st); i++) { if (d->st[i].ctl & 0x02) { intel_hda_parse_bdl(d, &d->st[i]); } } intel_hda_update_irq(d); return 0; }


int cpu_x86_handle_mmu_fault(CPUX86State *env, target_ulong addr, int is_write1, int mmu_idx, int is_softmmu) { uint64_t ptep, pte; target_ulong pde_addr, pte_addr; int error_code, is_dirty, prot, page_size, ret, is_write, is_user; target_phys_addr_t paddr; uint32_t page_offset; target_ulong vaddr, virt_addr; is_user = mmu_idx == MMU_USER_IDX; #if defined(DEBUG_MMU) printf("MMU fault: addr=" TARGET_FMT_lx " w=%d u=%d eip=" TARGET_FMT_lx "\n", addr, is_write1, is_user, env->eip); #endif is_write = is_write1 & 1; if (!(env->cr[0] & CR0_PG_MASK)) { pte = addr; virt_addr = addr & TARGET_PAGE_MASK; prot = PAGE_READ | PAGE_WRITE | PAGE_EXEC; page_size = 4096; goto do_mapping; } if (env->cr[4] & CR4_PAE_MASK) { uint64_t pde, pdpe; target_ulong pdpe_addr; #ifdef TARGET_X86_64 if (env->hflags & HF_LMA_MASK) { uint64_t pml4e_addr, pml4e; int32_t sext; /* test virtual address sign extension */ sext = (int64_t)addr >> 47; if (sext != 0 && sext != -1) { env->error_code = 0; env->exception_index = EXCP0D_GPF; return 1; } pml4e_addr = ((env->cr[3] & ~0xfff) + (((addr >> 39) & 0x1ff) << 3)) & env->a20_mask; pml4e = ldq_phys(pml4e_addr); if (!(pml4e & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pml4e & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } if (!(pml4e & PG_ACCESSED_MASK)) { pml4e |= PG_ACCESSED_MASK; stl_phys_notdirty(pml4e_addr, pml4e); } ptep = pml4e ^ PG_NX_MASK; pdpe_addr = ((pml4e & PHYS_ADDR_MASK) + (((addr >> 30) & 0x1ff) << 3)) & env->a20_mask; pdpe = ldq_phys(pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pdpe & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } ptep &= pdpe ^ PG_NX_MASK; if (!(pdpe & PG_ACCESSED_MASK)) { pdpe |= PG_ACCESSED_MASK; stl_phys_notdirty(pdpe_addr, pdpe); } } else #endif { /* XXX: load them when cr3 is loaded ? */ pdpe_addr = ((env->cr[3] & ~0x1f) + ((addr >> 27) & 0x18)) & env->a20_mask; pdpe = ldq_phys(pdpe_addr); if (!(pdpe & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } ptep = PG_NX_MASK | PG_USER_MASK | PG_RW_MASK; } pde_addr = ((pdpe & PHYS_ADDR_MASK) + (((addr >> 21) & 0x1ff) << 3)) & env->a20_mask; pde = ldq_phys(pde_addr); if (!(pde & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pde & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } ptep &= pde ^ PG_NX_MASK; if (pde & PG_PSE_MASK) { /* 2 MB page */ page_size = 2048 * 1024; ptep ^= PG_NX_MASK; if ((ptep & PG_NX_MASK) && is_write1 == 2) goto do_fault_protect; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pde & PG_DIRTY_MASK); if (!(pde & PG_ACCESSED_MASK) || is_dirty) { pde |= PG_ACCESSED_MASK; if (is_dirty) pde |= PG_DIRTY_MASK; stl_phys_notdirty(pde_addr, pde); } /* align to page_size */ pte = pde & ((PHYS_ADDR_MASK & ~(page_size - 1)) | 0xfff); virt_addr = addr & ~(page_size - 1); } else { /* 4 KB page */ if (!(pde & PG_ACCESSED_MASK)) { pde |= PG_ACCESSED_MASK; stl_phys_notdirty(pde_addr, pde); } pte_addr = ((pde & PHYS_ADDR_MASK) + (((addr >> 12) & 0x1ff) << 3)) & env->a20_mask; pte = ldq_phys(pte_addr); if (!(pte & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } if (!(env->efer & MSR_EFER_NXE) && (pte & PG_NX_MASK)) { error_code = PG_ERROR_RSVD_MASK; goto do_fault; } /* combine pde and pte nx, user and rw protections */ ptep &= pte ^ PG_NX_MASK; ptep ^= PG_NX_MASK; if ((ptep & PG_NX_MASK) && is_write1 == 2) goto do_fault_protect; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { pte |= PG_ACCESSED_MASK; if (is_dirty) pte |= PG_DIRTY_MASK; stl_phys_notdirty(pte_addr, pte); } page_size = 4096; virt_addr = addr & ~0xfff; pte = pte & (PHYS_ADDR_MASK | 0xfff); } } else { uint32_t pde; /* page directory entry */ pde_addr = ((env->cr[3] & ~0xfff) + ((addr >> 20) & 0xffc)) & env->a20_mask; pde = ldl_phys(pde_addr); if (!(pde & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } /* if PSE bit is set, then we use a 4MB page */ if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) { page_size = 4096 * 1024; if (is_user) { if (!(pde & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(pde & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(pde & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pde & PG_DIRTY_MASK); if (!(pde & PG_ACCESSED_MASK) || is_dirty) { pde |= PG_ACCESSED_MASK; if (is_dirty) pde |= PG_DIRTY_MASK; stl_phys_notdirty(pde_addr, pde); } pte = pde & ~( (page_size - 1) & ~0xfff); /* align to page_size */ ptep = pte; virt_addr = addr & ~(page_size - 1); } else { if (!(pde & PG_ACCESSED_MASK)) { pde |= PG_ACCESSED_MASK; stl_phys_notdirty(pde_addr, pde); } /* page directory entry */ pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc)) & env->a20_mask; pte = ldl_phys(pte_addr); if (!(pte & PG_PRESENT_MASK)) { error_code = 0; goto do_fault; } /* combine pde and pte user and rw protections */ ptep = pte & pde; if (is_user) { if (!(ptep & PG_USER_MASK)) goto do_fault_protect; if (is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } else { if ((env->cr[0] & CR0_WP_MASK) && is_write && !(ptep & PG_RW_MASK)) goto do_fault_protect; } is_dirty = is_write && !(pte & PG_DIRTY_MASK); if (!(pte & PG_ACCESSED_MASK) || is_dirty) { pte |= PG_ACCESSED_MASK; if (is_dirty) pte |= PG_DIRTY_MASK; stl_phys_notdirty(pte_addr, pte); } page_size = 4096; virt_addr = addr & ~0xfff; } } /* the page can be put in the TLB */ prot = PAGE_READ; if (!(ptep & PG_NX_MASK)) prot |= PAGE_EXEC; if (pte & PG_DIRTY_MASK) { /* only set write access if already dirty... otherwise wait for dirty access */ if (is_user) { if (ptep & PG_RW_MASK) prot |= PAGE_WRITE; } else { if (!(env->cr[0] & CR0_WP_MASK) || (ptep & PG_RW_MASK)) prot |= PAGE_WRITE; } } do_mapping: pte = pte & env->a20_mask; /* Even if 4MB pages, we map only one 4KB page in the cache to avoid filling it too fast */ page_offset = (addr & TARGET_PAGE_MASK) & (page_size - 1); paddr = (pte & TARGET_PAGE_MASK) + page_offset; vaddr = virt_addr + page_offset; ret = tlb_set_page_exec(env, vaddr, paddr, prot, mmu_idx, is_softmmu); return ret; do_fault_protect: error_code = PG_ERROR_P_MASK; do_fault: error_code |= (is_write << PG_ERROR_W_BIT); if (is_user) error_code |= PG_ERROR_U_MASK; if (is_write1 == 2 && (env->efer & MSR_EFER_NXE) && (env->cr[4] & CR4_PAE_MASK)) error_code |= PG_ERROR_I_D_MASK; if (env->intercept_exceptions & (1 << EXCP0E_PAGE)) { /* cr2 is not modified in case of exceptions */ stq_phys(env->vm_vmcb + offsetof(struct vmcb, control.exit_info_2), addr); } else { env->cr[2] = addr; } env->error_code = error_code; env->exception_index = EXCP0E_PAGE; return 1; }


static CharDriverState *qemu_chr_open_ringbuf(const char *id, ChardevBackend *backend, ChardevReturn *ret, Error **errp) { ChardevRingbuf *opts = backend->u.ringbuf; CharDriverState *chr; RingBufCharDriver *d; chr = qemu_chr_alloc(); d = g_malloc(sizeof(*d)); d->size = opts->has_size ? opts->size : 65536; /* The size must be power of 2 */ if (d->size & (d->size - 1)) { error_setg(errp, "size of ringbuf chardev must be power of two"); goto fail; } d->prod = 0; d->cons = 0; d->cbuf = g_malloc0(d->size); chr->opaque = d; chr->chr_write = ringbuf_chr_write; chr->chr_close = ringbuf_chr_close; return chr; fail: g_free(d); g_free(chr); return NULL; }


int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate) { MPADecodeHeader s1, *s = &s1; if (ff_mpa_check_header(head) != 0) return -1; if (avpriv_mpegaudio_decode_header(s, head) != 0) { return -1; } switch(s->layer) { case 1: avctx->codec_id = AV_CODEC_ID_MP1; *frame_size = 384; break; case 2: avctx->codec_id = AV_CODEC_ID_MP2; *frame_size = 1152; break; default: case 3: if (avctx->codec_id != AV_CODEC_ID_MP3ADU) avctx->codec_id = AV_CODEC_ID_MP3; if (s->lsf) *frame_size = 576; else *frame_size = 1152; break; } *sample_rate = s->sample_rate; *channels = s->nb_channels; *bit_rate = s->bit_rate; return s->frame_size; }


static inline void gen_speundef (DisasContext *ctx) { RET_INVAL(ctx); }


int kqemu_init(CPUState *env) { struct kqemu_init kinit; int ret, version; #ifdef _WIN32 DWORD temp; #endif if (!kqemu_allowed) return -1; #ifdef _WIN32 kqemu_fd = CreateFile(KQEMU_DEVICE, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (kqemu_fd == KQEMU_INVALID_FD) { fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %lu\n", KQEMU_DEVICE, GetLastError()); return -1; } #else kqemu_fd = open(KQEMU_DEVICE, O_RDWR); if (kqemu_fd == KQEMU_INVALID_FD) { fprintf(stderr, "Could not open '%s' - QEMU acceleration layer not activated: %s\n", KQEMU_DEVICE, strerror(errno)); return -1; } #endif version = 0; #ifdef _WIN32 DeviceIoControl(kqemu_fd, KQEMU_GET_VERSION, NULL, 0, &version, sizeof(version), &temp, NULL); #else ioctl(kqemu_fd, KQEMU_GET_VERSION, &version); #endif if (version != KQEMU_VERSION) { fprintf(stderr, "Version mismatch between kqemu module and qemu (%08x %08x) - disabling kqemu use\n", version, KQEMU_VERSION); goto fail; } pages_to_flush = qemu_vmalloc(KQEMU_MAX_PAGES_TO_FLUSH * sizeof(uint64_t)); if (!pages_to_flush) goto fail; ram_pages_to_update = qemu_vmalloc(KQEMU_MAX_RAM_PAGES_TO_UPDATE * sizeof(uint64_t)); if (!ram_pages_to_update) goto fail; modified_ram_pages = qemu_vmalloc(KQEMU_MAX_MODIFIED_RAM_PAGES * sizeof(uint64_t)); if (!modified_ram_pages) goto fail; modified_ram_pages_table = qemu_mallocz(kqemu_phys_ram_size >> TARGET_PAGE_BITS); if (!modified_ram_pages_table) goto fail; memset(&kinit, 0, sizeof(kinit)); /* set the paddings to zero */ kinit.ram_base = kqemu_phys_ram_base; kinit.ram_size = kqemu_phys_ram_size; kinit.ram_dirty = phys_ram_dirty; kinit.pages_to_flush = pages_to_flush; kinit.ram_pages_to_update = ram_pages_to_update; kinit.modified_ram_pages = modified_ram_pages; #ifdef _WIN32 ret = DeviceIoControl(kqemu_fd, KQEMU_INIT, &kinit, sizeof(kinit), NULL, 0, &temp, NULL) == TRUE ? 0 : -1; #else ret = ioctl(kqemu_fd, KQEMU_INIT, &kinit); #endif if (ret < 0) { fprintf(stderr, "Error %d while initializing QEMU acceleration layer - disabling it for now\n", ret); fail: kqemu_closefd(kqemu_fd); kqemu_fd = KQEMU_INVALID_FD; return -1; } kqemu_update_cpuid(env); env->kqemu_enabled = kqemu_allowed; nb_pages_to_flush = 0; nb_ram_pages_to_update = 0; qpi_init(); return 0; }


POWERPC_FAMILY(POWER9)(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); dc->fw_name = "PowerPC,POWER9"; dc->desc = "POWER9"; dc->props = powerpc_servercpu_properties; pcc->pvr_match = ppc_pvr_match_power9; pcc->pcr_mask = PCR_COMPAT_2_05 | PCR_COMPAT_2_06 | PCR_COMPAT_2_07; pcc->pcr_supported = PCR_COMPAT_3_00 | PCR_COMPAT_2_07 | PCR_COMPAT_2_06 | PCR_COMPAT_2_05; pcc->init_proc = init_proc_POWER9; pcc->check_pow = check_pow_nocheck; pcc->insns_flags = PPC_INSNS_BASE | PPC_ISEL | PPC_STRING | PPC_MFTB | PPC_FLOAT | PPC_FLOAT_FSEL | PPC_FLOAT_FRES | PPC_FLOAT_FSQRT | PPC_FLOAT_FRSQRTE | PPC_FLOAT_FRSQRTES | PPC_FLOAT_STFIWX | PPC_FLOAT_EXT | PPC_CACHE | PPC_CACHE_ICBI | PPC_CACHE_DCBZ | PPC_MEM_SYNC | PPC_MEM_EIEIO | PPC_MEM_TLBIE | PPC_MEM_TLBSYNC | PPC_64B | PPC_64BX | PPC_ALTIVEC | PPC_SEGMENT_64B | PPC_SLBI | PPC_POPCNTB | PPC_POPCNTWD | PPC_CILDST; pcc->insns_flags2 = PPC2_VSX | PPC2_VSX207 | PPC2_DFP | PPC2_DBRX | PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 | PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206 | PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 | PPC2_ISA205 | PPC2_ISA207S | PPC2_FP_CVT_S64 | PPC2_TM | PPC2_PM_ISA206 | PPC2_ISA300; pcc->msr_mask = (1ull << MSR_SF) | (1ull << MSR_TM) | (1ull << MSR_VR) | (1ull << MSR_VSX) | (1ull << MSR_EE) | (1ull << MSR_PR) | (1ull << MSR_FP) | (1ull << MSR_ME) | (1ull << MSR_FE0) | (1ull << MSR_SE) | (1ull << MSR_DE) | (1ull << MSR_FE1) | (1ull << MSR_IR) | (1ull << MSR_DR) | (1ull << MSR_PMM) | (1ull << MSR_RI) | (1ull << MSR_LE); pcc->mmu_model = POWERPC_MMU_3_00; #if defined(CONFIG_SOFTMMU) pcc->handle_mmu_fault = ppc_hash64_handle_mmu_fault; /* segment page size remain the same */ pcc->sps = &POWER7_POWER8_sps; #endif pcc->excp_model = POWERPC_EXCP_POWER8; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | POWERPC_FLAG_VSX | POWERPC_FLAG_TM; pcc->l1_dcache_size = 0x8000; pcc->l1_icache_size = 0x8000; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_lpcr; }


int cpu_get_dump_info(ArchDumpInfo *info, const GuestPhysBlockList *guest_phys_blocks) { bool lma = false; GuestPhysBlock *block; #ifdef TARGET_X86_64 X86CPU *first_x86_cpu = X86_CPU(first_cpu); lma = !!(first_x86_cpu->env.hflags & HF_LMA_MASK); #endif if (lma) { info->d_machine = EM_X86_64; } else { info->d_machine = EM_386; } info->d_endian = ELFDATA2LSB; if (lma) { info->d_class = ELFCLASS64; } else { info->d_class = ELFCLASS32; QTAILQ_FOREACH(block, &guest_phys_blocks->head, next) { if (block->target_end > UINT_MAX) { /* The memory size is greater than 4G */ info->d_class = ELFCLASS64; break; } } } return 0; }


static void handler_audit(Monitor *mon, const mon_cmd_t *cmd, int ret) { if (ret && !monitor_has_error(mon)) { /* * If it returns failure, it must have passed on error. * * Action: Report an internal error to the client if in QMP. */ if (monitor_ctrl_mode(mon)) { qerror_report(QERR_UNDEFINED_ERROR); } MON_DEBUG("command '%s' returned failure but did not pass an error\n", cmd->name); } #ifdef CONFIG_DEBUG_MONITOR if (!ret && monitor_has_error(mon)) { /* * If it returns success, it must not have passed an error. * * Action: Report the passed error to the client. */ MON_DEBUG("command '%s' returned success but passed an error\n", cmd->name); } if (mon_print_count_get(mon) > 0 && strcmp(cmd->name, "info") != 0) { /* * Handlers should not call Monitor print functions. * * Action: Ignore them in QMP. * * (XXX: we don't check any 'info' or 'query' command here * because the user print function _is_ called by do_info(), hence * we will trigger this check. This problem will go away when we * make 'query' commands real and kill do_info()) */ MON_DEBUG("command '%s' called print functions %d time(s)\n", cmd->name, mon_print_count_get(mon)); } #endif }


char* qdev_get_fw_dev_path(DeviceState *dev) { char path[128]; int l; l = qdev_get_fw_dev_path_helper(dev, path, 128); path[l-1] = '\0'; return strdup(path); }


static ssize_t drop_sync(QIOChannel *ioc, size_t size) { ssize_t ret, dropped = size; char small[1024]; char *buffer; buffer = sizeof(small) < size ? small : g_malloc(MIN(65536, size)); while (size > 0) { ret = read_sync(ioc, buffer, MIN(65536, size)); if (ret < 0) { goto cleanup; } assert(ret <= size); size -= ret; } ret = dropped; cleanup: if (buffer != small) { g_free(buffer); } return ret; }


static BlockAIOCB *bdrv_aio_readv_em(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov, int nb_sectors, BlockCompletionFunc *cb, void *opaque) { return bdrv_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); }


static int seek_frame_generic(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { int index; int64_t ret; AVStream *st; AVIndexEntry *ie; st = s->streams[stream_index]; index = av_index_search_timestamp(st, timestamp, flags); if(index < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp) return -1; if(index < 0 || index==st->nb_index_entries-1){ AVPacket pkt; int nonkey=0; if(st->nb_index_entries){ assert(st->index_entries); ie= &st->index_entries[st->nb_index_entries-1]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); }else{ if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0) return ret; } for (;;) { int read_status; do{ read_status = av_read_frame(s, &pkt); } while (read_status == AVERROR(EAGAIN)); if (read_status < 0) break; av_free_packet(&pkt); if(stream_index == pkt.stream_index && pkt.dts > timestamp){ if(pkt.flags & AV_PKT_FLAG_KEY) break; if(nonkey++ > 1000){ av_log(s, AV_LOG_ERROR,"seek_frame_generic failed as this stream seems to contain no keyframes after the target timestamp, %d non keyframes found\n", nonkey); break; } } } index = av_index_search_timestamp(st, timestamp, flags); } if (index < 0) return -1; ff_read_frame_flush(s); AV_NOWARN_DEPRECATED( if (s->iformat->read_seek){ if(s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0) return 0; } ) ie = &st->index_entries[index]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); return 0; }


static void dvbsub_parse_page_segment(AVCodecContext *avctx, const uint8_t *buf, int buf_size) { DVBSubContext *ctx = avctx->priv_data; DVBSubRegionDisplay *display; DVBSubRegionDisplay *tmp_display_list, **tmp_ptr; const uint8_t *buf_end = buf + buf_size; int region_id; int page_state; if (buf_size < 1) return; ctx->time_out = *buf++; page_state = ((*buf++) >> 2) & 3; av_dlog(avctx, "Page time out %ds, state %d\n", ctx->time_out, page_state); if (page_state == 2) { delete_state(ctx); } tmp_display_list = ctx->display_list; ctx->display_list = NULL; ctx->display_list_size = 0; while (buf + 5 < buf_end) { region_id = *buf++; buf += 1; display = tmp_display_list; tmp_ptr = &tmp_display_list; while (display && display->region_id != region_id) { tmp_ptr = &display->next; display = display->next; } if (!display) display = av_mallocz(sizeof(DVBSubRegionDisplay)); display->region_id = region_id; display->x_pos = AV_RB16(buf); buf += 2; display->y_pos = AV_RB16(buf); buf += 2; *tmp_ptr = display->next; display->next = ctx->display_list; ctx->display_list = display; ctx->display_list_size++; av_dlog(avctx, "Region %d, (%d,%d)\n", region_id, display->x_pos, display->y_pos); } while (tmp_display_list) { display = tmp_display_list; tmp_display_list = display->next; av_free(display); } }


static void test_qemu_strtoul_negative(void) { const char *str = " \t -321"; 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, ==, -321ul); g_assert(endptr == str + strlen(str)); }


static int is_cpuid_supported(void) { return 1; }


void vnc_display_init(const char *id) { VncDisplay *vs; if (vnc_display_find(id) != NULL) { return; } vs = g_malloc0(sizeof(*vs)); vs->id = strdup(id); QTAILQ_INSERT_TAIL(&vnc_displays, vs, next); vs->lsock = -1; #ifdef CONFIG_VNC_WS vs->lwebsock = -1; #endif QTAILQ_INIT(&vs->clients); vs->expires = TIME_MAX; if (keyboard_layout) { trace_vnc_key_map_init(keyboard_layout); vs->kbd_layout = init_keyboard_layout(name2keysym, keyboard_layout); } else { vs->kbd_layout = init_keyboard_layout(name2keysym, "en-us"); } if (!vs->kbd_layout) exit(1); qemu_mutex_init(&vs->mutex); vnc_start_worker_thread(); vs->dcl.ops = &dcl_ops; register_displaychangelistener(&vs->dcl); }


static int get_key(const char **ropts, const char *delim, char *key, unsigned key_size) { unsigned key_pos = 0; const char *opts = *ropts; opts += strspn(opts, WHITESPACES); while (is_key_char(*opts)) { key[key_pos++] = *opts; if (key_pos == key_size) key_pos--; (opts)++; } opts += strspn(opts, WHITESPACES); if (!*opts || !strchr(delim, *opts)) return AVERROR(EINVAL); opts++; key[key_pos++] = 0; if (key_pos == key_size) key[key_pos - 4] = key[key_pos - 3] = key[key_pos - 2] = '.'; *ropts = opts; return 0; }


static void expand_timestamps(void *log, struct sbg_script *s) { int i, nb_rel = 0; int64_t now, cur_ts, delta = 0; for (i = 0; i < s->nb_tseq; i++) nb_rel += s->tseq[i].ts.type == 'N'; if (nb_rel == s->nb_tseq) { /* All ts are relative to NOW: consider NOW = 0 */ now = 0; if (s->start_ts != AV_NOPTS_VALUE) av_log(log, AV_LOG_WARNING, "Start time ignored in a purely relative script.\n"); } else if (nb_rel == 0 && s->start_ts != AV_NOPTS_VALUE || s->opt_start_at_first) { /* All ts are absolute and start time is specified */ if (s->start_ts == AV_NOPTS_VALUE) s->start_ts = s->tseq[0].ts.t; now = s->start_ts; } else { /* Mixed relative/absolute ts: expand */ time_t now0; struct tm *tm, tmpbuf; av_log(log, AV_LOG_WARNING, "Scripts with mixed absolute and relative timestamps can give " "unexpected results (pause, seeking, time zone change).\n"); #undef time time(&now0); tm = localtime_r(&now0, &tmpbuf); now = tm ? tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec : now0 % DAY; av_log(log, AV_LOG_INFO, "Using %02d:%02d:%02d as NOW.\n", (int)(now / 3600), (int)(now / 60) % 60, (int)now % 60); now *= AV_TIME_BASE; for (i = 0; i < s->nb_tseq; i++) { if (s->tseq[i].ts.type == 'N') { s->tseq[i].ts.t += now; s->tseq[i].ts.type = 'T'; /* not necessary */ } } } if (s->start_ts == AV_NOPTS_VALUE) s->start_ts = s->opt_start_at_first ? s->tseq[0].ts.t : now; s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration : AV_NOPTS_VALUE; /* may be overridden later by -E option */ cur_ts = now; for (i = 0; i < s->nb_tseq; i++) { if (s->tseq[i].ts.t + delta < cur_ts) delta += DAY_TS; cur_ts = s->tseq[i].ts.t += delta; } }


static void generate_len_table(uint8_t *dst, uint64_t *stats, int size){ heap_elem_t h[size]; int up[2*size]; int len[2*size]; int offset, i, next; for(offset=1; ; offset<<=1){ for(i=0; i<size; i++){ h[i].name = i; h[i].val = (stats[i] << 8) + offset; } for(i=size/2-1; i>=0; i--) heap_sift(h, i, size); for(next=size; next<size*2-1; next++){ // merge the two smallest entries, and put it back in the heap uint64_t min1v = h[0].val; up[h[0].name] = next; h[0].val = INT64_MAX; heap_sift(h, 0, size); up[h[0].name] = next; h[0].name = next; h[0].val += min1v; heap_sift(h, 0, size); } len[2*size-2] = 0; for(i=2*size-3; i>=size; i--) len[i] = len[up[i]] + 1; for(i=0; i<size; i++) { dst[i] = len[up[i]] + 1; if(dst[i] > 32) break; } if(i==size) break; } }


static int scale_vaapi_filter_frame(AVFilterLink *inlink, AVFrame *input_frame) { AVFilterContext *avctx = inlink->dst; AVFilterLink *outlink = avctx->outputs[0]; ScaleVAAPIContext *ctx = avctx->priv; AVFrame *output_frame = NULL; VASurfaceID input_surface, output_surface; VAProcPipelineParameterBuffer params; VABufferID params_id; VAStatus vas; int err; av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(input_frame->format), input_frame->width, input_frame->height, input_frame->pts); if (ctx->va_context == VA_INVALID_ID) return AVERROR(EINVAL); input_surface = (VASurfaceID)(uintptr_t)input_frame->data[3]; av_log(ctx, AV_LOG_DEBUG, "Using surface %#x for scale input.\n", input_surface); output_frame = av_frame_alloc(); if (!output_frame) { av_log(ctx, AV_LOG_ERROR, "Failed to allocate output frame."); err = AVERROR(ENOMEM); goto fail; } err = av_hwframe_get_buffer(ctx->output_frames_ref, output_frame, 0); if (err < 0) { av_log(ctx, AV_LOG_ERROR, "Failed to get surface for " "output: %d\n.", err); } output_surface = (VASurfaceID)(uintptr_t)output_frame->data[3]; av_log(ctx, AV_LOG_DEBUG, "Using surface %#x for scale output.\n", output_surface); memset(&params, 0, sizeof(params)); params.surface = input_surface; params.surface_region = 0; params.surface_color_standard = vaapi_proc_colour_standard(input_frame->colorspace); params.output_region = 0; params.output_background_color = 0xff000000; params.output_color_standard = params.surface_color_standard; params.pipeline_flags = 0; params.filter_flags = VA_FILTER_SCALING_HQ; vas = vaBeginPicture(ctx->hwctx->display, ctx->va_context, output_surface); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to attach new picture: " "%d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(EIO); goto fail; } vas = vaCreateBuffer(ctx->hwctx->display, ctx->va_context, VAProcPipelineParameterBufferType, sizeof(params), 1, &params, &params_id); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to create parameter buffer: " "%d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(EIO); goto fail_after_begin; } av_log(ctx, AV_LOG_DEBUG, "Pipeline parameter buffer is %#x.\n", params_id); vas = vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_id, 1); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to render parameter buffer: " "%d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(EIO); goto fail_after_begin; } vas = vaEndPicture(ctx->hwctx->display, ctx->va_context); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to start picture processing: " "%d (%s).\n", vas, vaErrorStr(vas)); err = AVERROR(EIO); goto fail_after_render; } if (ctx->hwctx->driver_quirks & AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS) { vas = vaDestroyBuffer(ctx->hwctx->display, params_id); if (vas != VA_STATUS_SUCCESS) { av_log(ctx, AV_LOG_ERROR, "Failed to free parameter buffer: " "%d (%s).\n", vas, vaErrorStr(vas)); // And ignore. } } av_frame_copy_props(output_frame, input_frame); av_frame_free(&input_frame); av_log(ctx, AV_LOG_DEBUG, "Filter output: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(output_frame->format), output_frame->width, output_frame->height, output_frame->pts); return ff_filter_frame(outlink, output_frame); // We want to make sure that if vaBeginPicture has been called, we also // call vaRenderPicture and vaEndPicture. These calls may well fail or // do something else nasty, but once we're in this failure case there // isn't much else we can do. fail_after_begin: vaRenderPicture(ctx->hwctx->display, ctx->va_context, &params_id, 1); fail_after_render: vaEndPicture(ctx->hwctx->display, ctx->va_context); fail: av_frame_free(&input_frame); av_frame_free(&output_frame); return err; }


static int get_packet(URLContext *s, int for_header) { RTMPContext *rt = s->priv_data; int ret; uint8_t *p; const uint8_t *next; uint32_t data_size; uint32_t ts, cts, pts=0; if (rt->state == STATE_STOPPED) return AVERROR_EOF; for (;;) { RTMPPacket rpkt = { 0 }; if ((ret = ff_rtmp_packet_read(rt->stream, &rpkt, rt->chunk_size, rt->prev_pkt[0])) <= 0) { if (ret == 0) { return AVERROR(EAGAIN); } else { return AVERROR(EIO); } } rt->bytes_read += ret; if (rt->bytes_read > rt->last_bytes_read + rt->client_report_size) { av_log(s, AV_LOG_DEBUG, "Sending bytes read report\n"); gen_bytes_read(s, rt, rpkt.timestamp + 1); rt->last_bytes_read = rt->bytes_read; } ret = rtmp_parse_result(s, rt, &rpkt); if (ret < 0) {//serious error in current packet ff_rtmp_packet_destroy(&rpkt); return -1; } if (rt->state == STATE_STOPPED) { ff_rtmp_packet_destroy(&rpkt); return AVERROR_EOF; } if (for_header && (rt->state == STATE_PLAYING || rt->state == STATE_PUBLISHING)) { ff_rtmp_packet_destroy(&rpkt); return 0; } if (!rpkt.data_size || !rt->is_input) { ff_rtmp_packet_destroy(&rpkt); continue; } if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO || (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) { ts = rpkt.timestamp; // generate packet header and put data into buffer for FLV demuxer rt->flv_off = 0; rt->flv_size = rpkt.data_size + 15; rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size); bytestream_put_byte(&p, rpkt.type); bytestream_put_be24(&p, rpkt.data_size); bytestream_put_be24(&p, ts); bytestream_put_byte(&p, ts >> 24); bytestream_put_be24(&p, 0); bytestream_put_buffer(&p, rpkt.data, rpkt.data_size); bytestream_put_be32(&p, 0); ff_rtmp_packet_destroy(&rpkt); return 0; } else if (rpkt.type == RTMP_PT_METADATA) { // we got raw FLV data, make it available for FLV demuxer rt->flv_off = 0; rt->flv_size = rpkt.data_size; rt->flv_data = av_realloc(rt->flv_data, rt->flv_size); /* rewrite timestamps */ next = rpkt.data; ts = rpkt.timestamp; while (next - rpkt.data < rpkt.data_size - 11) { next++; data_size = bytestream_get_be24(&next); p=next; cts = bytestream_get_be24(&next); cts |= bytestream_get_byte(&next) << 24; if (pts==0) pts=cts; ts += cts - pts; pts = cts; bytestream_put_be24(&p, ts); bytestream_put_byte(&p, ts >> 24); next += data_size + 3 + 4; } memcpy(rt->flv_data, rpkt.data, rpkt.data_size); ff_rtmp_packet_destroy(&rpkt); return 0; } ff_rtmp_packet_destroy(&rpkt); } }


static void save_display_set(DVBSubContext *ctx) { DVBSubRegion *region; DVBSubRegionDisplay *display; DVBSubCLUT *clut; uint32_t *clut_table; int x_pos, y_pos, width, height; int x, y, y_off, x_off; uint32_t *pbuf; char filename[32]; static int fileno_index = 0; x_pos = -1; y_pos = -1; width = 0; height = 0; for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); if (x_pos == -1) { x_pos = display->x_pos; y_pos = display->y_pos; width = region->width; height = region->height; } else { if (display->x_pos < x_pos) { width += (x_pos - display->x_pos); x_pos = display->x_pos; } if (display->y_pos < y_pos) { height += (y_pos - display->y_pos); y_pos = display->y_pos; } if (display->x_pos + region->width > x_pos + width) { width = display->x_pos + region->width - x_pos; } if (display->y_pos + region->height > y_pos + height) { height = display->y_pos + region->height - y_pos; } } } if (x_pos >= 0) { pbuf = av_malloc(width * height * 4); for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); x_off = display->x_pos - x_pos; y_off = display->y_pos - y_pos; clut = get_clut(ctx, region->clut); if (!clut) clut = &default_clut; switch (region->depth) { case 2: clut_table = clut->clut4; break; case 8: clut_table = clut->clut256; break; case 4: default: clut_table = clut->clut16; break; } for (y = 0; y < region->height; y++) { for (x = 0; x < region->width; x++) { pbuf[((y + y_off) * width) + x_off + x] = clut_table[region->pbuf[y * region->width + x]]; } } } snprintf(filename, sizeof(filename), "dvbs.%d", fileno_index); png_save2(filename, pbuf, width, height); av_freep(&pbuf); } fileno_index++; }


int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen, void *log_ctx) { char *tail, color_string2[128]; const ColorEntry *entry; int len, hex_offset = 0; if (color_string[0] == '#') { hex_offset = 1; } else if (!strncmp(color_string, "0x", 2)) hex_offset = 2; if (slen < 0) slen = strlen(color_string); av_strlcpy(color_string2, color_string + hex_offset, FFMIN(slen-hex_offset+1, sizeof(color_string2))); if ((tail = strchr(color_string2, ALPHA_SEP))) *tail++ = 0; len = strlen(color_string2); rgba_color[3] = 255; if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) { int rgba = av_get_random_seed(); rgba_color[0] = rgba >> 24; rgba_color[1] = rgba >> 16; rgba_color[2] = rgba >> 8; rgba_color[3] = rgba; } else if (hex_offset || strspn(color_string2, "0123456789ABCDEFabcdef") == len) { char *tail; unsigned int rgba = strtoul(color_string2, &tail, 16); if (*tail || (len != 6 && len != 8)) { av_log(log_ctx, AV_LOG_ERROR, "Invalid 0xRRGGBB[AA] color string: '%s'\n", color_string2); return AVERROR(EINVAL); } if (len == 8) { rgba_color[3] = rgba; rgba >>= 8; } rgba_color[0] = rgba >> 16; rgba_color[1] = rgba >> 8; rgba_color[2] = rgba; } else { entry = bsearch(color_string2, color_table, FF_ARRAY_ELEMS(color_table), sizeof(ColorEntry), color_table_compare); if (!entry) { av_log(log_ctx, AV_LOG_ERROR, "Cannot find color '%s'\n", color_string2); return AVERROR(EINVAL); } memcpy(rgba_color, entry->rgb_color, 3); } if (tail) { unsigned long int alpha; const char *alpha_string = tail; if (!strncmp(alpha_string, "0x", 2)) { alpha = strtoul(alpha_string, &tail, 16); } else { alpha = 255 * strtod(alpha_string, &tail); } if (tail == alpha_string || *tail || alpha > 255) { av_log(log_ctx, AV_LOG_ERROR, "Invalid alpha value specifier '%s' in '%s'\n", alpha_string, color_string); return AVERROR(EINVAL); } rgba_color[3] = alpha; } return 0; }


int i2c_start_transfer(I2CBus *bus, uint8_t address, int recv) { BusChild *kid; I2CSlaveClass *sc; I2CNode *node; if (address == 0x00) { /* * This is a broadcast, the current_devs will be all the devices of the * bus. */ bus->broadcast = true; } QTAILQ_FOREACH(kid, &bus->qbus.children, sibling) { DeviceState *qdev = kid->child; I2CSlave *candidate = I2C_SLAVE(qdev); if ((candidate->address == address) || (bus->broadcast)) { node = g_malloc(sizeof(struct I2CNode)); node->elt = candidate; QLIST_INSERT_HEAD(&bus->current_devs, node, next); if (!bus->broadcast) { break; } } } if (QLIST_EMPTY(&bus->current_devs)) { return 1; } QLIST_FOREACH(node, &bus->current_devs, next) { sc = I2C_SLAVE_GET_CLASS(node->elt); /* If the bus is already busy, assume this is a repeated start condition. */ if (sc->event) { sc->event(node->elt, recv ? I2C_START_RECV : I2C_START_SEND); } } return 0; }


void ff_MPV_encode_init_x86(MpegEncContext *s) { int mm_flags = av_get_cpu_flags(); const int dct_algo = s->avctx->dct_algo; if (dct_algo == FF_DCT_AUTO || dct_algo == FF_DCT_MMX) { #if HAVE_MMX_INLINE if (mm_flags & AV_CPU_FLAG_MMX && HAVE_MMX) s->dct_quantize = dct_quantize_MMX; #endif #if HAVE_MMXEXT_INLINE if (mm_flags & AV_CPU_FLAG_MMXEXT && HAVE_MMXEXT) s->dct_quantize = dct_quantize_MMX2; #endif #if HAVE_SSE2_INLINE if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE2) s->dct_quantize = dct_quantize_SSE2; #endif #if HAVE_SSSE3_INLINE if (mm_flags & AV_CPU_FLAG_SSSE3) s->dct_quantize = dct_quantize_SSSE3; #endif } }


static void smbios_build_type_1_fields(void) { smbios_maybe_add_str(1, offsetof(struct smbios_type_1, manufacturer_str), type1.manufacturer); smbios_maybe_add_str(1, offsetof(struct smbios_type_1, product_name_str), type1.product); smbios_maybe_add_str(1, offsetof(struct smbios_type_1, version_str), type1.version); smbios_maybe_add_str(1, offsetof(struct smbios_type_1, serial_number_str), type1.serial); smbios_maybe_add_str(1, offsetof(struct smbios_type_1, sku_number_str), type1.sku); smbios_maybe_add_str(1, offsetof(struct smbios_type_1, family_str), type1.family); if (qemu_uuid_set) { /* We don't encode the UUID in the "wire format" here because this * function is for legacy mode and needs to keep the guest ABI, and * because we don't know what's the SMBIOS version advertised by the * BIOS. */ smbios_add_field(1, offsetof(struct smbios_type_1, uuid), qemu_uuid, 16); } }


static inline int mirror_clip_sectors(MirrorBlockJob *s, int64_t sector_num, int nb_sectors) { return MIN(nb_sectors, s->bdev_length / BDRV_SECTOR_SIZE - sector_num); }


static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) { uint32_t tag; uint32_t bufsize; uint32_t tot_len; size_t resplen; uint32_t tmp; value &= ~0xf; s->addr = value; tot_len = ldl_phys(&s->dma_as, value); /* @(addr + 4) : Buffer response code */ value = s->addr + 8; while (value + 8 <= s->addr + tot_len) { tag = ldl_phys(&s->dma_as, value); bufsize = ldl_phys(&s->dma_as, value + 4); /* @(value + 8) : Request/response indicator */ resplen = 0; switch (tag) { case 0x00000000: /* End tag */ break; case 0x00000001: /* Get firmware revision */ stl_phys(&s->dma_as, value + 12, 346337); resplen = 4; break; case 0x00010001: /* Get board model */ qemu_log_mask(LOG_UNIMP, "bcm2835_property: %x get board model NYI\n", tag); resplen = 4; break; case 0x00010002: /* Get board revision */ qemu_log_mask(LOG_UNIMP, "bcm2835_property: %x get board revision NYI\n", tag); resplen = 4; break; case 0x00010003: /* Get board MAC address */ resplen = sizeof(s->macaddr.a); dma_memory_write(&s->dma_as, value + 12, s->macaddr.a, resplen); break; case 0x00010004: /* Get board serial */ qemu_log_mask(LOG_UNIMP, "bcm2835_property: %x get board serial NYI\n", tag); resplen = 8; break; case 0x00010005: /* Get ARM memory */ /* base */ stl_phys(&s->dma_as, value + 12, 0); /* size */ stl_phys(&s->dma_as, value + 16, s->ram_size); resplen = 8; break; case 0x00028001: /* Set power state */ /* Assume that whatever device they asked for exists, * and we'll just claim we set it to the desired state */ tmp = ldl_phys(&s->dma_as, value + 16); stl_phys(&s->dma_as, value + 16, (tmp & 1)); resplen = 8; break; /* Clocks */ case 0x00030001: /* Get clock state */ stl_phys(&s->dma_as, value + 16, 0x1); resplen = 8; break; case 0x00038001: /* Set clock state */ qemu_log_mask(LOG_UNIMP, "bcm2835_property: %x set clock state NYI\n", tag); resplen = 8; break; case 0x00030002: /* Get clock rate */ case 0x00030004: /* Get max clock rate */ case 0x00030007: /* Get min clock rate */ switch (ldl_phys(&s->dma_as, value + 12)) { case 1: /* EMMC */ stl_phys(&s->dma_as, value + 16, 50000000); break; case 2: /* UART */ stl_phys(&s->dma_as, value + 16, 3000000); break; default: stl_phys(&s->dma_as, value + 16, 700000000); break; } resplen = 8; break; case 0x00038002: /* Set clock rate */ case 0x00038004: /* Set max clock rate */ case 0x00038007: /* Set min clock rate */ qemu_log_mask(LOG_UNIMP, "bcm2835_property: %x set clock rates NYI\n", tag); resplen = 8; break; /* Temperature */ case 0x00030006: /* Get temperature */ stl_phys(&s->dma_as, value + 16, 25000); resplen = 8; break; case 0x0003000A: /* Get max temperature */ stl_phys(&s->dma_as, value + 16, 99000); resplen = 8; break; case 0x00060001: /* Get DMA channels */ /* channels 2-5 */ stl_phys(&s->dma_as, value + 12, 0x003C); resplen = 4; break; case 0x00050001: /* Get command line */ resplen = 0; break; default: qemu_log_mask(LOG_GUEST_ERROR, "bcm2835_property: unhandled tag %08x\n", tag); break; } if (tag == 0) { break; } stl_phys(&s->dma_as, value + 8, (1 << 31) | resplen); value += bufsize + 12; } /* Buffer response code */ stl_phys(&s->dma_as, s->addr + 4, (1 << 31)); }


ObjectClass *object_class_dynamic_cast(ObjectClass *class, const char *typename) { TypeImpl *target_type = type_get_by_name(typename); TypeImpl *type = class->type; ObjectClass *ret = NULL; if (type->num_interfaces && type_is_ancestor(target_type, type_interface)) { int found = 0; GSList *i; for (i = class->interfaces; i; i = i->next) { ObjectClass *target_class = i->data; if (type_is_ancestor(target_class->type, target_type)) { ret = target_class; found++; } } /* The match was ambiguous, don't allow a cast */ if (found > 1) { ret = NULL; } } else if (type_is_ancestor(type, target_type)) { ret = class; } return ret; }


static void sdhci_send_command(SDHCIState *s) { SDRequest request; uint8_t response[16]; int rlen; s->errintsts = 0; s->acmd12errsts = 0; request.cmd = s->cmdreg >> 8; request.arg = s->argument; DPRINT_L1("sending CMD%u ARG[0x%08x]\n", request.cmd, request.arg); rlen = sd_do_command(s->card, &request, response); if (s->cmdreg & SDHC_CMD_RESPONSE) { if (rlen == 4) { s->rspreg[0] = (response[0] << 24) | (response[1] << 16) | (response[2] << 8) | response[3]; s->rspreg[1] = s->rspreg[2] = s->rspreg[3] = 0; DPRINT_L1("Response: RSPREG[31..0]=0x%08x\n", s->rspreg[0]); } else if (rlen == 16) { s->rspreg[0] = (response[11] << 24) | (response[12] << 16) | (response[13] << 8) | response[14]; s->rspreg[1] = (response[7] << 24) | (response[8] << 16) | (response[9] << 8) | response[10]; s->rspreg[2] = (response[3] << 24) | (response[4] << 16) | (response[5] << 8) | response[6]; s->rspreg[3] = (response[0] << 16) | (response[1] << 8) | response[2]; DPRINT_L1("Response received:\n RSPREG[127..96]=0x%08x, RSPREG[95.." "64]=0x%08x,\n RSPREG[63..32]=0x%08x, RSPREG[31..0]=0x%08x\n", s->rspreg[3], s->rspreg[2], s->rspreg[1], s->rspreg[0]); } else { ERRPRINT("Timeout waiting for command response\n"); if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) { s->errintsts |= SDHC_EIS_CMDTIMEOUT; s->norintsts |= SDHC_NIS_ERR; } } if ((s->norintstsen & SDHC_NISEN_TRSCMP) && (s->cmdreg & SDHC_CMD_RESPONSE) == SDHC_CMD_RSP_WITH_BUSY) { s->norintsts |= SDHC_NIS_TRSCMP; } } else if (rlen != 0 && (s->errintstsen & SDHC_EISEN_CMDIDX)) { s->errintsts |= SDHC_EIS_CMDIDX; s->norintsts |= SDHC_NIS_ERR; } if (s->norintstsen & SDHC_NISEN_CMDCMP) { s->norintsts |= SDHC_NIS_CMDCMP; } sdhci_update_irq(s); if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) { s->data_count = 0; sdhci_do_data_transfer(s); } }


static void ss5_init(int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, const char *initrd_filename, const char *cpu_model) { if (cpu_model == NULL) cpu_model = "Fujitsu MB86904"; sun4m_common_init(ram_size, boot_device, ds, kernel_filename, kernel_cmdline, initrd_filename, cpu_model, 0); }


const char *qemu_opt_get(QemuOpts *opts, const char *name) { QemuOpt *opt = qemu_opt_find(opts, name); if (!opt) { const QemuOptDesc *desc = find_desc_by_name(opts->list->desc, name); if (desc && desc->def_value_str) { return desc->def_value_str; } } return opt ? opt->str : NULL; }


void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) { QEMUTimer **pt, *t; qemu_del_timer(ts); /* add the timer in the sorted list */ /* NOTE: this code must be signal safe because qemu_timer_expired() can be called from a signal. */ pt = &active_timers[ts->clock->type]; for(;;) { t = *pt; if (!t) break; if (t->expire_time > expire_time) break; pt = &t->next; } ts->expire_time = expire_time; ts->next = *pt; *pt = ts; /* Rearm if necessary */ if (pt == &active_timers[ts->clock->type]) { if ((alarm_timer->flags & ALARM_FLAG_EXPIRED) == 0) { qemu_rearm_alarm_timer(alarm_timer); } /* Interrupt execution to force deadline recalculation. */ if (use_icount) qemu_notify_event(); } }


static void qemu_system_suspend(void) { pause_all_vcpus(); notifier_list_notify(&suspend_notifiers, NULL); runstate_set(RUN_STATE_SUSPENDED); monitor_protocol_event(QEVENT_SUSPEND, NULL); is_suspended = true; }


static void RENAME(yuv2rgb565_1)(SwsContext *c, const uint16_t *buf0, const uint16_t *ubuf0, const uint16_t *ubuf1, const uint16_t *vbuf0, const uint16_t *vbuf1, const uint16_t *abuf0, uint8_t *dest, int dstW, int uvalpha, enum PixelFormat dstFormat, int flags, int y) { const uint16_t *buf1= buf0; //FIXME needed for RGB1/BGR1 if (uvalpha < 2048) { // note this is not correct (shifts chrominance by 0.5 pixels) but it is a bit faster __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */ #ifdef DITHER1XBPP "paddusb "BLUE_DITHER"(%5), %%mm2 \n\t" "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif WRITERGB16(%%REGb, 8280(%5), %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), "a" (&c->redDither) ); } else { __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" /* mm2=B, %%mm4=G, %%mm5=R, %%mm7=0 */ #ifdef DITHER1XBPP "paddusb "BLUE_DITHER"(%5), %%mm2 \n\t" "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif WRITERGB16(%%REGb, 8280(%5), %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), "a" (&c->redDither) ); } }


static void numa_node_parse_cpus(int nodenr, const char *cpus) { char *endptr; unsigned long long value, endvalue; value = strtoull(cpus, &endptr, 10); if (*endptr == '-') { endvalue = strtoull(endptr+1, &endptr, 10); } else { endvalue = value; } if (!(endvalue < MAX_CPUMASK_BITS)) { endvalue = MAX_CPUMASK_BITS - 1; fprintf(stderr, "A max of %d CPUs are supported in a guest\n", MAX_CPUMASK_BITS); } bitmap_set(node_cpumask[nodenr], value, endvalue-value+1); }


static void icount_dummy_timer(void *opaque) { (void)opaque; }


static int gdb_set_float_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { env->fpr[n] = ldfq_p(mem_buf); return 8; } if (n == 32) { /* FPSCR not implemented */ return 4; } return 0; }


static inline void decode(DisasContext *dc) { uint32_t ir; int i; if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP))) { tcg_gen_debug_insn_start(dc->pc); } dc->ir = ir = ldl_code(dc->pc); LOG_DIS("%8.8x\t", dc->ir); /* try guessing 'empty' instruction memory, although it may be a valid * instruction sequence (eg. srui r0, r0, 0) */ if (dc->ir) { dc->nr_nops = 0; } else { LOG_DIS("nr_nops=%d\t", dc->nr_nops); dc->nr_nops++; if (dc->nr_nops > 4) { cpu_abort(dc->env, "fetching nop sequence\n"); } } dc->opcode = EXTRACT_FIELD(ir, 26, 31); dc->imm5 = EXTRACT_FIELD(ir, 0, 4); dc->imm16 = EXTRACT_FIELD(ir, 0, 15); dc->imm26 = EXTRACT_FIELD(ir, 0, 25); dc->csr = EXTRACT_FIELD(ir, 21, 25); dc->r0 = EXTRACT_FIELD(ir, 21, 25); dc->r1 = EXTRACT_FIELD(ir, 16, 20); dc->r2 = EXTRACT_FIELD(ir, 11, 15); /* bit 31 seems to indicate insn type. */ if (ir & (1 << 31)) { dc->format = OP_FMT_RR; } else { dc->format = OP_FMT_RI; } /* Large switch for all insns. */ for (i = 0; i < ARRAY_SIZE(decinfo); i++) { if ((dc->opcode & decinfo[i].mask) == decinfo[i].bits) { decinfo[i].dec(dc); return; } } cpu_abort(dc->env, "unknown opcode 0x%02x\n", dc->opcode); }


void memory_region_init_iommu(MemoryRegion *mr, Object *owner, const MemoryRegionIOMMUOps *ops, const char *name, uint64_t size) { memory_region_init(mr, owner, name, size); mr->iommu_ops = ops, mr->terminates = true; /* then re-forwards */ notifier_list_init(&mr->iommu_notify); }


void helper_movl_drN_T0(CPUX86State *env, int reg, target_ulong t0) { #ifndef CONFIG_USER_ONLY if (reg < 4) { if (hw_breakpoint_enabled(env->dr[7], reg) && hw_breakpoint_type(env->dr[7], reg) != DR7_TYPE_IO_RW) { hw_breakpoint_remove(env, reg); env->dr[reg] = t0; hw_breakpoint_insert(env, reg); } else { env->dr[reg] = t0; } } else if (reg == 7) { cpu_x86_update_dr7(env, t0); } else { env->dr[reg] = t0; } #endif }


QDict *qdict_new(void) { QDict *qdict; qdict = g_malloc0(sizeof(*qdict)); QOBJECT_INIT(qdict, &qdict_type); return qdict; }


int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *cluster_offset) { BDRVQcow2State *s = bs->opaque; unsigned int l2_index; uint64_t l1_index, l2_offset, *l2_table; int l1_bits, c; unsigned int offset_in_cluster; uint64_t bytes_available, bytes_needed, nb_clusters; int ret; offset_in_cluster = offset_into_cluster(s, offset); bytes_needed = (uint64_t) *bytes + offset_in_cluster; l1_bits = s->l2_bits + s->cluster_bits; /* compute how many bytes there are between the start of the cluster * containing offset and the end of the l1 entry */ bytes_available = (1ULL << l1_bits) - (offset & ((1ULL << l1_bits) - 1)) + offset_in_cluster; if (bytes_needed > bytes_available) { bytes_needed = bytes_available; } *cluster_offset = 0; /* seek to the l2 offset in the l1 table */ l1_index = offset >> l1_bits; if (l1_index >= s->l1_size) { ret = QCOW2_CLUSTER_UNALLOCATED; goto out; } l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK; if (!l2_offset) { ret = QCOW2_CLUSTER_UNALLOCATED; goto out; } if (offset_into_cluster(s, l2_offset)) { qcow2_signal_corruption(bs, true, -1, -1, "L2 table offset %#" PRIx64 " unaligned (L1 index: %#" PRIx64 ")", l2_offset, l1_index); return -EIO; } /* load the l2 table in memory */ ret = l2_load(bs, l2_offset, &l2_table); if (ret < 0) { return ret; } /* find the cluster offset for the given disk offset */ l2_index = (offset >> s->cluster_bits) & (s->l2_size - 1); *cluster_offset = be64_to_cpu(l2_table[l2_index]); nb_clusters = size_to_clusters(s, bytes_needed); /* bytes_needed <= *bytes + offset_in_cluster, both of which are unsigned * integers; the minimum cluster size is 512, so this assertion is always * true */ assert(nb_clusters <= INT_MAX); ret = qcow2_get_cluster_type(*cluster_offset); switch (ret) { case QCOW2_CLUSTER_COMPRESSED: /* Compressed clusters can only be processed one by one */ c = 1; *cluster_offset &= L2E_COMPRESSED_OFFSET_SIZE_MASK; break; case QCOW2_CLUSTER_ZERO: if (s->qcow_version < 3) { qcow2_signal_corruption(bs, true, -1, -1, "Zero cluster entry found" " in pre-v3 image (L2 offset: %#" PRIx64 ", L2 index: %#x)", l2_offset, l2_index); ret = -EIO; goto fail; } c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index], QCOW2_CLUSTER_ZERO); *cluster_offset = 0; break; case QCOW2_CLUSTER_UNALLOCATED: /* how many empty clusters ? */ c = count_contiguous_clusters_by_type(nb_clusters, &l2_table[l2_index], QCOW2_CLUSTER_UNALLOCATED); *cluster_offset = 0; break; case QCOW2_CLUSTER_NORMAL: /* how many allocated clusters ? */ c = count_contiguous_clusters(nb_clusters, s->cluster_size, &l2_table[l2_index], QCOW_OFLAG_ZERO); *cluster_offset &= L2E_OFFSET_MASK; if (offset_into_cluster(s, *cluster_offset)) { qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset %#" PRIx64 " unaligned (L2 offset: %#" PRIx64 ", L2 index: %#x)", *cluster_offset, l2_offset, l2_index); ret = -EIO; goto fail; } break; default: abort(); } qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); bytes_available = (int64_t)c * s->cluster_size; out: if (bytes_available > bytes_needed) { bytes_available = bytes_needed; } /* bytes_available <= bytes_needed <= *bytes + offset_in_cluster; * subtracting offset_in_cluster will therefore definitely yield something * not exceeding UINT_MAX */ assert(bytes_available - offset_in_cluster <= UINT_MAX); *bytes = bytes_available - offset_in_cluster; return ret; fail: qcow2_cache_put(bs, s->l2_table_cache, (void **)&l2_table); return ret; }


mips_mipssim_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) { char buf[1024]; unsigned long bios_offset; CPUState *env; int bios_size; /* Init CPUs. */ if (cpu_model == NULL) { #ifdef TARGET_MIPS64 cpu_model = "5Kf"; #else cpu_model = "24Kf"; #endif } env = cpu_init(cpu_model); if (!env) { fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } qemu_register_reset(main_cpu_reset, env); /* Allocate RAM. */ cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); /* Load a BIOS / boot exception handler image. */ bios_offset = ram_size + vga_ram_size; if (bios_name == NULL) bios_name = BIOS_FILENAME; snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name); bios_size = load_image(buf, phys_ram_base + bios_offset); if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) { /* Bail out if we have neither a kernel image nor boot vector code. */ fprintf(stderr, "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n", buf); exit(1); } else { /* Map the BIOS / boot exception handler. */ cpu_register_physical_memory(0x1fc00000LL, bios_size, bios_offset | IO_MEM_ROM); /* We have a boot vector start address. */ env->active_tc.PC = (target_long)(int32_t)0xbfc00000; } if (kernel_filename) { loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; load_kernel(env); } /* Init CPU internal devices. */ cpu_mips_irq_init_cpu(env); cpu_mips_clock_init(env); /* Register 64 KB of ISA IO space at 0x1fd00000. */ isa_mmio_init(0x1fd00000, 0x00010000); /* A single 16450 sits at offset 0x3f8. It is attached to MIPS CPU INT2, which is interrupt 4. */ if (serial_hds[0]) serial_init(0x3f8, env->irq[4], 115200, serial_hds[0]); if (nd_table[0].vlan) { if (nd_table[0].model == NULL || strcmp(nd_table[0].model, "mipsnet") == 0) { /* MIPSnet uses the MIPS CPU INT0, which is interrupt 2. */ mipsnet_init(0x4200, env->irq[2], &nd_table[0]); } else if (strcmp(nd_table[0].model, "?") == 0) { fprintf(stderr, "qemu: Supported NICs: mipsnet\n"); exit (1); } else { fprintf(stderr, "qemu: Unsupported NIC: %s\n", nd_table[0].model); exit (1); } } }


static inline void RENAME(LEToUV)(uint8_t *dstU, uint8_t *dstV, const uint8_t *src1, const uint8_t *src2, long width, uint32_t *unused) { #if COMPILE_TEMPLATE_MMX __asm__ volatile( "mov %0, %%"REG_a" \n\t" "1: \n\t" "movq (%1, %%"REG_a",2), %%mm0 \n\t" "movq 8(%1, %%"REG_a",2), %%mm1 \n\t" "movq (%2, %%"REG_a",2), %%mm2 \n\t" "movq 8(%2, %%"REG_a",2), %%mm3 \n\t" "psrlw $8, %%mm0 \n\t" "psrlw $8, %%mm1 \n\t" "psrlw $8, %%mm2 \n\t" "psrlw $8, %%mm3 \n\t" "packuswb %%mm1, %%mm0 \n\t" "packuswb %%mm3, %%mm2 \n\t" "movq %%mm0, (%3, %%"REG_a") \n\t" "movq %%mm2, (%4, %%"REG_a") \n\t" "add $8, %%"REG_a" \n\t" " js 1b \n\t" : : "g" ((x86_reg)-width), "r" (src1+width*2), "r" (src2+width*2), "r" (dstU+width), "r" (dstV+width) : "%"REG_a ); #else int i; // FIXME I don't think this code is right for YUV444/422, since then h is not subsampled so // we need to skip each second pixel. Same for BEToUV. for (i=0; i<width; i++) { dstU[i]= src1[2*i + 1]; dstV[i]= src2[2*i + 1]; } #endif }


static target_phys_addr_t intel_hda_addr(uint32_t lbase, uint32_t ubase) { target_phys_addr_t addr; addr = ((uint64_t)ubase << 32) | lbase; return addr; }


static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, Error **errp) { Error *local_err = NULL; BlockMeasureInfo *info; uint64_t required = 0; /* bytes that contribute to required size */ uint64_t virtual_size; /* disk size as seen by guest */ uint64_t refcount_bits; uint64_t l2_tables; size_t cluster_size; int version; char *optstr; PreallocMode prealloc; bool has_backing_file; /* Parse image creation options */ cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err); if (local_err) { goto err; } version = qcow2_opt_get_version_del(opts, &local_err); if (local_err) { goto err; } refcount_bits = qcow2_opt_get_refcount_bits_del(opts, version, &local_err); if (local_err) { goto err; } optstr = qemu_opt_get_del(opts, BLOCK_OPT_PREALLOC); prealloc = qapi_enum_parse(&PreallocMode_lookup, optstr, PREALLOC_MODE_OFF, &local_err); g_free(optstr); if (local_err) { goto err; } optstr = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE); has_backing_file = !!optstr; g_free(optstr); virtual_size = align_offset(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), cluster_size); /* Check that virtual disk size is valid */ l2_tables = DIV_ROUND_UP(virtual_size / cluster_size, cluster_size / sizeof(uint64_t)); if (l2_tables * sizeof(uint64_t) > QCOW_MAX_L1_SIZE) { error_setg(&local_err, "The image size is too large " "(try using a larger cluster size)"); goto err; } /* Account for input image */ if (in_bs) { int64_t ssize = bdrv_getlength(in_bs); if (ssize < 0) { error_setg_errno(&local_err, -ssize, "Unable to get image virtual_size"); goto err; } virtual_size = align_offset(ssize, cluster_size); if (has_backing_file) { /* We don't how much of the backing chain is shared by the input * image and the new image file. In the worst case the new image's * backing file has nothing in common with the input image. Be * conservative and assume all clusters need to be written. */ required = virtual_size; } else { int64_t offset; int pnum = 0; for (offset = 0; offset < ssize; offset += pnum * BDRV_SECTOR_SIZE) { int nb_sectors = MIN(ssize - offset, BDRV_REQUEST_MAX_BYTES) / BDRV_SECTOR_SIZE; BlockDriverState *file; int64_t ret; ret = bdrv_get_block_status_above(in_bs, NULL, offset >> BDRV_SECTOR_BITS, nb_sectors, &pnum, &file); if (ret < 0) { error_setg_errno(&local_err, -ret, "Unable to get block status"); goto err; } if (ret & BDRV_BLOCK_ZERO) { /* Skip zero regions (safe with no backing file) */ } else if ((ret & (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) == (BDRV_BLOCK_DATA | BDRV_BLOCK_ALLOCATED)) { /* Extend pnum to end of cluster for next iteration */ pnum = (ROUND_UP(offset + pnum * BDRV_SECTOR_SIZE, cluster_size) - offset) >> BDRV_SECTOR_BITS; /* Count clusters we've seen */ required += offset % cluster_size + pnum * BDRV_SECTOR_SIZE; } } } } /* Take into account preallocation. Nothing special is needed for * PREALLOC_MODE_METADATA since metadata is always counted. */ if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) { required = virtual_size; } info = g_new(BlockMeasureInfo, 1); info->fully_allocated = qcow2_calc_prealloc_size(virtual_size, cluster_size, ctz32(refcount_bits)); /* Remove data clusters that are not required. This overestimates the * required size because metadata needed for the fully allocated file is * still counted. */ info->required = info->fully_allocated - virtual_size + required; return info; err: error_propagate(errp, local_err); return NULL; }


static void raw_aio_cancel(BlockDriverAIOCB *blockacb) { int ret; RawAIOCB *acb = (RawAIOCB *)blockacb; RawAIOCB **pacb; ret = aio_cancel(acb->aiocb.aio_fildes, &acb->aiocb); if (ret == AIO_NOTCANCELED) { /* fail safe: if the aio could not be canceled, we wait for it */ while (aio_error(&acb->aiocb) == EINPROGRESS); } /* remove the callback from the queue */ pacb = &posix_aio_state->first_aio; for(;;) { if (*pacb == NULL) { break; } else if (*pacb == acb) { *pacb = acb->next; raw_fd_pool_put(acb); qemu_aio_release(acb); break; } pacb = &acb->next; } }


void check_file_fixed_eof_mmaps(void) { char *addr; char *cp; unsigned int *p1; uintptr_t p; int i; /* Find a suitable address to start with. */ addr = mmap(NULL, pagesize * 44, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); fprintf (stderr, "%s addr=%p", __func__, (void *)addr); fail_unless (addr != MAP_FAILED); for (i = 0; i < 0x10; i++) { /* Create submaps within our unfixed map. */ p1 = mmap(addr, pagesize, PROT_READ, MAP_PRIVATE | MAP_FIXED, test_fd, (test_fsize - sizeof *p1) & ~pagemask); fail_unless (p1 != MAP_FAILED); /* Make sure we get pages aligned with the pagesize. The target expects this. */ p = (uintptr_t) p1; fail_unless ((p & pagemask) == 0); /* Verify that the file maps was made correctly. */ fail_unless (p1[(test_fsize & pagemask) / sizeof *p1 - 1] == ((test_fsize - sizeof *p1) / sizeof *p1)); /* Verify that the end of page is accessable and zeroed. */ cp = (void *)p1; fail_unless (cp[pagesize - 4] == 0); munmap (p1, pagesize); addr += pagesize; } fprintf (stderr, " passed\n"); }


static void nbd_attach_aio_context(BlockDriverState *bs, AioContext *new_context) { BDRVNBDState *s = bs->opaque; nbd_client_session_attach_aio_context(&s->client, new_context); }


void bmdma_cmd_writeb(void *opaque, uint32_t addr, uint32_t val) { BMDMAState *bm = opaque; #ifdef DEBUG_IDE printf("%s: 0x%08x\n", __func__, val); #endif /* Ignore writes to SSBM if it keeps the old value */ if ((val & BM_CMD_START) != (bm->cmd & BM_CMD_START)) { if (!(val & BM_CMD_START)) { /* * We can't cancel Scatter Gather DMA in the middle of the * operation or a partial (not full) DMA transfer would reach * the storage so we wait for completion instead (we beahve * like if the DMA was completed by the time the guest trying * to cancel dma with bmdma_cmd_writeb with BM_CMD_START not * set). * * In the future we'll be able to safely cancel the I/O if the * whole DMA operation will be submitted to disk with a single * aio operation with preadv/pwritev. */ if (bm->bus->dma->aiocb) { qemu_aio_flush(); #ifdef DEBUG_IDE if (bm->bus->dma->aiocb) printf("ide_dma_cancel: aiocb still pending\n"); if (bm->status & BM_STATUS_DMAING) printf("ide_dma_cancel: BM_STATUS_DMAING still pending\n"); #endif } } else { bm->cur_addr = bm->addr; if (!(bm->status & BM_STATUS_DMAING)) { bm->status |= BM_STATUS_DMAING; /* start dma transfer if possible */ if (bm->dma_cb) bm->dma_cb(bmdma_active_if(bm), 0); } } } bm->cmd = val & 0x09; }


uint32_t qemu_devtree_get_phandle(void *fdt, const char *path) { uint32_t r; r = fdt_get_phandle(fdt, findnode_nofail(fdt, path)); if (r <= 0) { fprintf(stderr, "%s: Couldn't get phandle for %s: %s\n", __func__, path, fdt_strerror(r)); exit(1); } return r; }


static char *SocketAddress_to_str(const char *prefix, SocketAddressLegacy *addr, bool is_listen, bool is_telnet) { switch (addr->type) { case SOCKET_ADDRESS_LEGACY_KIND_INET: return g_strdup_printf("%s%s:%s:%s%s", prefix, is_telnet ? "telnet" : "tcp", addr->u.inet.data->host, addr->u.inet.data->port, is_listen ? ",server" : ""); break; case SOCKET_ADDRESS_LEGACY_KIND_UNIX: return g_strdup_printf("%sunix:%s%s", prefix, addr->u.q_unix.data->path, is_listen ? ",server" : ""); break; case SOCKET_ADDRESS_LEGACY_KIND_FD: return g_strdup_printf("%sfd:%s%s", prefix, addr->u.fd.data->str, is_listen ? ",server" : ""); break; case SOCKET_ADDRESS_LEGACY_KIND_VSOCK: return g_strdup_printf("%svsock:%s:%s", prefix, addr->u.vsock.data->cid, addr->u.vsock.data->port); default: abort(); } }


void handle_vm86_fault(CPUX86State *env) { TaskState *ts = env->opaque; uint8_t *csp, *pc, *ssp; unsigned int ip, sp, newflags, newip, newcs, opcode, intno; int data32, pref_done; csp = (uint8_t *)(env->segs[R_CS] << 4); ip = env->eip & 0xffff; pc = csp + ip; ssp = (uint8_t *)(env->segs[R_SS] << 4); sp = env->regs[R_ESP] & 0xffff; #if defined(DEBUG_VM86) fprintf(logfile, "VM86 exception %04x:%08x %02x %02x\n", env->segs[R_CS], env->eip, pc[0], pc[1]); #endif data32 = 0; pref_done = 0; do { opcode = csp[ip]; ADD16(ip, 1); switch (opcode) { case 0x66: /* 32-bit data */ data32=1; break; case 0x67: /* 32-bit address */ break; case 0x2e: /* CS */ break; case 0x3e: /* DS */ break; case 0x26: /* ES */ break; case 0x36: /* SS */ break; case 0x65: /* GS */ break; case 0x64: /* FS */ break; case 0xf2: /* repnz */ break; case 0xf3: /* rep */ break; default: pref_done = 1; } } while (!pref_done); /* VM86 mode */ switch(opcode) { case 0x9c: /* pushf */ ADD16(env->eip, 2); if (data32) { vm_putl(ssp, sp - 4, get_vflags(env)); ADD16(env->regs[R_ESP], -4); } else { vm_putw(ssp, sp - 2, get_vflags(env)); ADD16(env->regs[R_ESP], -2); } env->eip = ip; VM86_FAULT_RETURN; case 0x9d: /* popf */ if (data32) { newflags = vm_getl(ssp, sp); ADD16(env->regs[R_ESP], 4); } else { newflags = vm_getw(ssp, sp); ADD16(env->regs[R_ESP], 2); } env->eip = ip; CHECK_IF_IN_TRAP(); if (data32) { if (set_vflags_long(newflags, env)) return; } else { if (set_vflags_short(newflags, env)) return; } VM86_FAULT_RETURN; case 0xcd: /* int */ intno = csp[ip]; ADD16(ip, 1); env->eip = ip; if (ts->vm86plus.vm86plus.flags & TARGET_vm86dbg_active) { if ( (ts->vm86plus.vm86plus.vm86dbg_intxxtab[intno >> 3] >> (intno &7)) & 1) { return_to_32bit(env, TARGET_VM86_INTx + (intno << 8)); return; } } do_int(env, intno); break; case 0xcf: /* iret */ if (data32) { newip = vm_getl(ssp, sp) & 0xffff; newcs = vm_getl(ssp, sp + 4) & 0xffff; newflags = vm_getl(ssp, sp + 8); ADD16(env->regs[R_ESP], 12); } else { newip = vm_getw(ssp, sp); newcs = vm_getw(ssp, sp + 2); newflags = vm_getw(ssp, sp + 4); ADD16(env->regs[R_ESP], 6); } env->eip = newip; cpu_x86_load_seg(env, R_CS, newcs); CHECK_IF_IN_TRAP(); if (data32) { if (set_vflags_long(newflags, env)) return; } else { if (set_vflags_short(newflags, env)) return; } VM86_FAULT_RETURN; case 0xfa: /* cli */ env->eip = ip; clear_IF(env); VM86_FAULT_RETURN; case 0xfb: /* sti */ env->eip = ip; if (set_IF(env)) return; VM86_FAULT_RETURN; default: /* real VM86 GPF exception */ return_to_32bit(env, TARGET_VM86_UNKNOWN); break; } }


static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset, uint32_t value, MemTxAttrs attrs) { switch (offset) { case 0x00: /* Control */ gic_set_cpu_control(s, cpu, value, attrs); break; case 0x04: /* Priority mask */ s->priority_mask[cpu] = (value & 0xff); break; case 0x08: /* Binary Point */ if (s->security_extn && !attrs.secure) { s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR); } else { s->bpr[cpu] = MAX(value & 0x7, GIC_MIN_BPR); } break; case 0x10: /* End Of Interrupt */ gic_complete_irq(s, cpu, value & 0x3ff); return MEMTX_OK; case 0x1c: /* Aliased Binary Point */ if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) { /* unimplemented, or NS access: RAZ/WI */ return MEMTX_OK; } else { s->abpr[cpu] = MAX(value & 0x7, GIC_MIN_ABPR); } break; case 0xd0: case 0xd4: case 0xd8: case 0xdc: qemu_log_mask(LOG_UNIMP, "Writing APR not implemented\n"); break; default: qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_write: Bad offset %x\n", (int)offset); return MEMTX_ERROR; } gic_update(s); return MEMTX_OK; }


static int op_to_movi(int op) { switch (op_bits(op)) { case 32: return INDEX_op_movi_i32; #if TCG_TARGET_REG_BITS == 64 case 64: return INDEX_op_movi_i64; #endif default: fprintf(stderr, "op_to_movi: unexpected return value of " "function op_bits.\n"); tcg_abort(); } }


static void dbdma_end(DBDMA_io *io) { DBDMA_channel *ch = io->channel; dbdma_cmd *current = &ch->current; if (conditional_wait(ch)) goto wait; current->xfer_status = cpu_to_le16(be32_to_cpu(ch->regs[DBDMA_STATUS])); current->res_count = cpu_to_le16(be32_to_cpu(io->len)); dbdma_cmdptr_save(ch); if (io->is_last) ch->regs[DBDMA_STATUS] &= cpu_to_be32(~FLUSH); conditional_interrupt(ch); conditional_branch(ch); wait: ch->processing = 0; if ((ch->regs[DBDMA_STATUS] & cpu_to_be32(RUN)) && (ch->regs[DBDMA_STATUS] & cpu_to_be32(ACTIVE))) channel_run(ch); }


static void nfs_process_read(void *arg) { NFSClient *client = arg; aio_context_acquire(client->aio_context); nfs_service(client->context, POLLIN); nfs_set_events(client); aio_context_release(client->aio_context); }


int qemu_init_main_loop(void) { int ret; qemu_init_sigbus(); ret = qemu_signal_init(); if (ret) { return ret; } /* Note eventfd must be drained before signalfd handlers run */ ret = qemu_event_init(); if (ret) { return ret; } qemu_cond_init(&qemu_cpu_cond); qemu_cond_init(&qemu_system_cond); qemu_cond_init(&qemu_pause_cond); qemu_cond_init(&qemu_work_cond); qemu_cond_init(&qemu_io_proceeded_cond); qemu_mutex_init(&qemu_global_mutex); qemu_mutex_lock(&qemu_global_mutex); qemu_thread_get_self(&io_thread); return 0; }


static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) { /* should be the case, see cirrus_bitblt_start */ assert(s->cirrus_blt_width > 0); assert(s->cirrus_blt_height > 0); if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) { return true; } if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { return true; } if (dst_only) { return false; } if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { return true; } return false; }


static void virtio_pci_register_devices(void) { type_register_static(&virtio_blk_info); type_register_static_alias(&virtio_blk_info, "virtio-blk"); type_register_static(&virtio_net_info); type_register_static_alias(&virtio_net_info, "virtio-net"); type_register_static(&virtio_serial_info); type_register_static_alias(&virtio_serial_info, "virtio-serial"); type_register_static(&virtio_balloon_info); type_register_static_alias(&virtio_balloon_info, "virtio-balloon"); }


static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) { NVICState *s = (NVICState *)opaque; uint32_t offset = addr; unsigned i, startvec, end; uint32_t val; if (attrs.user && !nvic_user_access_ok(s, addr)) { /* Generate BusFault for unprivileged accesses */ return MEMTX_ERROR; } switch (offset) { /* reads of set and clear both return the status */ case 0x100 ... 0x13f: /* NVIC Set enable */ offset += 0x80; /* fall through */ case 0x180 ... 0x1bf: /* NVIC Clear enable */ val = 0; startvec = offset - 0x180 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { if (s->vectors[startvec + i].enabled) { val |= (1 << i); } } break; case 0x200 ... 0x23f: /* NVIC Set pend */ offset += 0x80; /* fall through */ case 0x280 ... 0x2bf: /* NVIC Clear pend */ val = 0; startvec = offset - 0x280 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { if (s->vectors[startvec + i].pending) { val |= (1 << i); } } break; case 0x300 ... 0x33f: /* NVIC Active */ val = 0; startvec = offset - 0x300 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0, end = size * 8; i < end && startvec + i < s->num_irq; i++) { if (s->vectors[startvec + i].active) { val |= (1 << i); } } break; case 0x400 ... 0x5ef: /* NVIC Priority */ val = 0; startvec = offset - 0x400 + NVIC_FIRST_IRQ; /* vector # */ for (i = 0; i < size && startvec + i < s->num_irq; i++) { val |= s->vectors[startvec + i].prio << (8 * i); } break; case 0xd18 ... 0xd23: /* System Handler Priority. */ val = 0; for (i = 0; i < size; i++) { val |= s->vectors[(offset - 0xd14) + i].prio << (i * 8); } break; case 0xfe0 ... 0xfff: /* ID. */ if (offset & 3) { val = 0; } else { val = nvic_id[(offset - 0xfe0) >> 2]; } break; default: if (size == 4) { val = nvic_readl(s, offset); } else { qemu_log_mask(LOG_GUEST_ERROR, "NVIC: Bad read of size %d at offset 0x%x\n", size, offset); val = 0; } } trace_nvic_sysreg_read(addr, val, size); *data = val; return MEMTX_OK; }


coroutine_fn iscsi_co_pdiscard(BlockDriverState *bs, int64_t offset, int count) { IscsiLun *iscsilun = bs->opaque; struct IscsiTask iTask; struct unmap_list list; if (!is_byte_request_lun_aligned(offset, count, iscsilun)) { return -ENOTSUP; } if (!iscsilun->lbp.lbpu) { /* UNMAP is not supported by the target */ return 0; } list.lba = offset / iscsilun->block_size; list.num = count / iscsilun->block_size; iscsi_co_init_iscsitask(iscsilun, &iTask); retry: if (iscsi_unmap_task(iscsilun->iscsi, iscsilun->lun, 0, 0, &list, 1, iscsi_co_generic_cb, &iTask) == NULL) { return -ENOMEM; } while (!iTask.complete) { iscsi_set_events(iscsilun); qemu_coroutine_yield(); } if (iTask.task != NULL) { scsi_free_scsi_task(iTask.task); iTask.task = NULL; } if (iTask.do_retry) { iTask.complete = 0; goto retry; } if (iTask.status == SCSI_STATUS_CHECK_CONDITION) { /* the target might fail with a check condition if it is not happy with the alignment of the UNMAP request we silently fail in this case */ return 0; } if (iTask.status != SCSI_STATUS_GOOD) { return iTask.err_code; } iscsi_allocmap_set_invalid(iscsilun, offset >> BDRV_SECTOR_BITS, count >> BDRV_SECTOR_BITS); return 0; }


static ssize_t qio_channel_command_writev(QIOChannel *ioc, const struct iovec *iov, size_t niov, int *fds, size_t nfds, Error **errp) { QIOChannelCommand *cioc = QIO_CHANNEL_COMMAND(ioc); ssize_t ret; retry: ret = writev(cioc->writefd, iov, niov); if (ret <= 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return QIO_CHANNEL_ERR_BLOCK; } if (errno == EINTR) { goto retry; } error_setg_errno(errp, errno, "%s", "Unable to write to command"); return -1; } return ret; }


static void v9fs_synth_fill_statbuf(V9fsSynthNode *node, struct stat *stbuf) { stbuf->st_dev = 0; stbuf->st_ino = node->attr->inode; stbuf->st_mode = node->attr->mode; stbuf->st_nlink = node->attr->nlink; stbuf->st_uid = 0; stbuf->st_gid = 0; stbuf->st_rdev = 0; stbuf->st_size = 0; stbuf->st_blksize = 0; stbuf->st_blocks = 0; stbuf->st_atime = 0; stbuf->st_mtime = 0; stbuf->st_ctime = 0; }


void cpu_exec_init(CPUState *env) { CPUState **penv; int cpu_index; #if defined(CONFIG_USER_ONLY) cpu_list_lock(); #endif env->next_cpu = NULL; penv = &first_cpu; cpu_index = 0; while (*penv != NULL) { penv = &(*penv)->next_cpu; cpu_index++; } env->cpu_index = cpu_index; env->numa_node = 0; TAILQ_INIT(&env->breakpoints); TAILQ_INIT(&env->watchpoints); *penv = env; #if defined(CONFIG_USER_ONLY) cpu_list_unlock(); #endif #if defined(CPU_SAVE_VERSION) && !defined(CONFIG_USER_ONLY) vmstate_register(cpu_index, &vmstate_cpu_common, env); register_savevm("cpu", cpu_index, CPU_SAVE_VERSION, cpu_save, cpu_load, env); #endif }


static void sdhci_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); SDHCIClass *k = SDHCI_CLASS(klass); dc->vmsd = &sdhci_vmstate; dc->props = sdhci_properties; dc->reset = sdhci_generic_reset; dc->realize = sdhci_realize; k->reset = sdhci_reset; k->mem_read = sdhci_read; k->mem_write = sdhci_write; k->send_command = sdhci_send_command; k->can_issue_command = sdhci_can_issue_command; k->data_transfer = sdhci_data_transfer; k->end_data_transfer = sdhci_end_transfer; k->do_sdma_single = sdhci_sdma_transfer_single_block; k->do_sdma_multi = sdhci_sdma_transfer_multi_blocks; k->do_adma = sdhci_do_adma; k->read_block_from_card = sdhci_read_block_from_card; k->write_block_to_card = sdhci_write_block_to_card; k->bdata_read = sdhci_read_dataport; k->bdata_write = sdhci_write_dataport; }


static void ppc_heathrow_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; const char *boot_device = machine->boot_order; MemoryRegion *sysmem = get_system_memory(); PowerPCCPU *cpu = NULL; CPUPPCState *env = NULL; char *filename; qemu_irq *pic, **heathrow_irqs; int linux_boot, i; MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios = g_new(MemoryRegion, 1); MemoryRegion *isa = g_new(MemoryRegion, 1); uint32_t kernel_base, initrd_base, cmdline_base = 0; int32_t kernel_size, initrd_size; PCIBus *pci_bus; PCIDevice *macio; MACIOIDEState *macio_ide; DeviceState *dev; BusState *adb_bus; int bios_size; MemoryRegion *pic_mem; MemoryRegion *escc_mem, *escc_bar = g_new(MemoryRegion, 1); uint16_t ppc_boot_device; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; void *fw_cfg; linux_boot = (kernel_filename != NULL); /* init CPUs */ if (cpu_model == NULL) cpu_model = "G3"; for (i = 0; i < smp_cpus; i++) { cpu = cpu_ppc_init(cpu_model); if (cpu == NULL) { fprintf(stderr, "Unable to find PowerPC CPU definition\n"); exit(1); } env = &cpu->env; /* Set time-base frequency to 16.6 Mhz */ cpu_ppc_tb_init(env, TBFREQ); qemu_register_reset(ppc_heathrow_reset, cpu); } /* 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); } memory_region_allocate_system_memory(ram, NULL, "ppc_heathrow.ram", ram_size); memory_region_add_subregion(sysmem, 0, ram); /* allocate and load BIOS */ memory_region_init_ram(bios, NULL, "ppc_heathrow.bios", BIOS_SIZE); vmstate_register_ram_global(bios); if (bios_name == NULL) bios_name = PROM_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); memory_region_set_readonly(bios, true); memory_region_add_subregion(sysmem, PROM_ADDR, bios); /* 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 */ memory_region_init_alias(isa, NULL, "isa_mmio", get_system_io(), 0, 0x00200000); memory_region_add_subregion(sysmem, 0xfe000000, isa); /* 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(0, pic[0x0f], pic[0x10], serial_hds[0], serial_hds[1], ESCC_CLOCK, 4); memory_region_init_alias(escc_bar, NULL, "escc-bar", escc_mem, 0, memory_region_size(escc_mem)); for(i = 0; i < nb_nics; i++) pci_nic_init_nofail(&nd_table[i], pci_bus, "ne2k_pci", NULL); ide_drive_get(hd, MAX_IDE_BUS); macio = pci_create(pci_bus, -1, TYPE_OLDWORLD_MACIO); dev = DEVICE(macio); qdev_connect_gpio_out(dev, 0, pic[0x12]); /* CUDA */ qdev_connect_gpio_out(dev, 1, pic[0x0D]); /* IDE-0 */ qdev_connect_gpio_out(dev, 2, pic[0x02]); /* IDE-0 DMA */ qdev_connect_gpio_out(dev, 3, pic[0x0E]); /* IDE-1 */ qdev_connect_gpio_out(dev, 4, pic[0x03]); /* IDE-1 DMA */ macio_init(macio, pic_mem, escc_bar); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[0]")); macio_ide_init_drives(macio_ide, hd); macio_ide = MACIO_IDE(object_resolve_path_component(OBJECT(macio), "ide[1]")); macio_ide_init_drives(macio_ide, &hd[MAX_IDE_DEVS]); dev = DEVICE(object_resolve_path_component(OBJECT(macio), "cuda")); adb_bus = qdev_get_child_bus(dev, "adb.0"); dev = qdev_create(adb_bus, TYPE_ADB_KEYBOARD); qdev_init_nofail(dev); dev = qdev_create(adb_bus, TYPE_ADB_MOUSE); qdev_init_nofail(dev); if (usb_enabled(false)) { pci_create_simple(pci_bus, -1, "pci-ohci"); } 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_i16(fw_cfg, FW_CFG_MAX_CPUS, (uint16_t)max_cpus); 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, TBFREQ); } /* Mac OS X requires a "known good" clock-frequency value; pass it one. */ fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_CLOCKFREQ, CLOCKFREQ); fw_cfg_add_i32(fw_cfg, FW_CFG_PPC_BUSFREQ, BUSFREQ); qemu_register_boot_set(fw_cfg_boot_set, fw_cfg); }