static void machine_numa_finish_init(MachineState *machine) { int i; bool default_mapping; GString *s = g_string_new(NULL); MachineClass *mc = MACHINE_GET_CLASS(machine); const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(machine); assert(nb_numa_nodes); for (i = 0; i < possible_cpus->len; i++) { if (possible_cpus->cpus[i].props.has_node_id) { break; } } default_mapping = (i == possible_cpus->len); for (i = 0; i < possible_cpus->len; i++) { const CPUArchId *cpu_slot = &possible_cpus->cpus[i]; if (!cpu_slot->props.has_node_id) { /* fetch default mapping from board and enable it */ CpuInstanceProperties props = cpu_slot->props; props.node_id = mc->get_default_cpu_node_id(machine, i); if (!default_mapping) { /* record slots with not set mapping, * TODO: make it hard error in future */ char *cpu_str = cpu_slot_to_string(cpu_slot); g_string_append_printf(s, "%sCPU %d [%s]", s->len ? ", " : "", i, cpu_str); g_free(cpu_str); /* non mapped cpus used to fallback to node 0 */ props.node_id = 0; } props.has_node_id = true; machine_set_cpu_numa_node(machine, &props, &error_fatal); } } if (s->len && !qtest_enabled()) { warn_report("CPU(s) not present in any NUMA nodes: %s", s->str); warn_report("All CPU(s) up to maxcpus should be described " "in NUMA config, ability to start up with partial NUMA " "mappings is obsoleted and will be removed in future"); } g_string_free(s, true); }
static void vexpress_modify_dtb(const struct arm_boot_info *info, void *fdt) { uint32_t acells, scells, intc; const VEDBoardInfo *daughterboard = (const VEDBoardInfo *)info; acells = qemu_fdt_getprop_cell(fdt, "/", "#address-cells", 0, 0, &error_fatal); scells = qemu_fdt_getprop_cell(fdt, "/", "#size-cells", 0, 0, &error_fatal); intc = find_int_controller(fdt); if (!intc) { /* Not fatal, we just won't provide virtio. This will * happen with older device tree blobs. */ warn_report("couldn't find interrupt controller in " "dtb; will not include virtio-mmio devices in the dtb"); } else { int i; const hwaddr *map = daughterboard->motherboard_map; /* We iterate backwards here because adding nodes * to the dtb puts them in last-first. */ for (i = NUM_VIRTIO_TRANSPORTS - 1; i >= 0; i--) { add_virtio_mmio_node(fdt, acells, scells, map[VE_VIRTIO] + 0x200 * i, 0x200, intc, 40 + i); } } }
static void check_consistency(const S390CPUModel *model) { static int dep[][2] = { { S390_FEAT_IPTE_RANGE, S390_FEAT_DAT_ENH }, { S390_FEAT_IDTE_SEGMENT, S390_FEAT_DAT_ENH }, { S390_FEAT_IDTE_REGION, S390_FEAT_DAT_ENH }, { S390_FEAT_IDTE_REGION, S390_FEAT_IDTE_SEGMENT }, { S390_FEAT_LOCAL_TLB_CLEARING, S390_FEAT_DAT_ENH}, { S390_FEAT_LONG_DISPLACEMENT_FAST, S390_FEAT_LONG_DISPLACEMENT }, { S390_FEAT_DFP_FAST, S390_FEAT_DFP }, { S390_FEAT_TRANSACTIONAL_EXE, S390_FEAT_STFLE_49 }, { S390_FEAT_EDAT_2, S390_FEAT_EDAT}, { S390_FEAT_MSA_EXT_5, S390_FEAT_KIMD_SHA_512 }, { S390_FEAT_MSA_EXT_5, S390_FEAT_KLMD_SHA_512 }, { S390_FEAT_MSA_EXT_4, S390_FEAT_MSA_EXT_3 }, { S390_FEAT_SIE_CMMA, S390_FEAT_CMM }, { S390_FEAT_SIE_CMMA, S390_FEAT_SIE_GSLS }, { S390_FEAT_SIE_PFMFI, S390_FEAT_EDAT }, { S390_FEAT_MSA_EXT_8, S390_FEAT_MSA_EXT_3 }, { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, { S390_FEAT_VECTOR_PACKED_DECIMAL, S390_FEAT_VECTOR }, { S390_FEAT_VECTOR_ENH, S390_FEAT_VECTOR }, { S390_FEAT_INSTRUCTION_EXEC_PROT, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, { S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2, S390_FEAT_ESOP }, { S390_FEAT_CMM_NT, S390_FEAT_CMM }, { S390_FEAT_GUARDED_STORAGE, S390_FEAT_SIDE_EFFECT_ACCESS_ESOP2 }, { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_STORE_CLOCK_FAST }, { S390_FEAT_MULTIPLE_EPOCH, S390_FEAT_TOD_CLOCK_STEERING }, { S390_FEAT_SEMAPHORE_ASSIST, S390_FEAT_STFLE_49 }, { S390_FEAT_KIMD_SHA3_224, S390_FEAT_MSA }, { S390_FEAT_KIMD_SHA3_256, S390_FEAT_MSA }, { S390_FEAT_KIMD_SHA3_384, S390_FEAT_MSA }, { S390_FEAT_KIMD_SHA3_512, S390_FEAT_MSA }, { S390_FEAT_KIMD_SHAKE_128, S390_FEAT_MSA }, { S390_FEAT_KIMD_SHAKE_256, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHA3_224, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHA3_256, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHA3_384, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHA3_512, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHAKE_128, S390_FEAT_MSA }, { S390_FEAT_KLMD_SHAKE_256, S390_FEAT_MSA }, { S390_FEAT_PRNO_TRNG_QRTCR, S390_FEAT_MSA_EXT_5 }, { S390_FEAT_PRNO_TRNG, S390_FEAT_MSA_EXT_5 }, { S390_FEAT_SIE_KSS, S390_FEAT_SIE_F2 }, }; int i; for (i = 0; i < ARRAY_SIZE(dep); i++) { if (test_bit(dep[i][0], model->features) && !test_bit(dep[i][1], model->features)) { warn_report("\'%s\' requires \'%s\'.", s390_feat_def(dep[i][0])->name, s390_feat_def(dep[i][1])->name); } } }
static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq) { VirtIOBalloon *s = VIRTIO_BALLOON(vdev); VirtQueueElement *elem; VirtIOBalloonStat stat; size_t offset = 0; qemu_timeval tv; elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); if (!elem) { goto out; } if (s->stats_vq_elem != NULL) { /* This should never happen if the driver follows the spec. */ virtqueue_push(vq, s->stats_vq_elem, 0); virtio_notify(vdev, vq); g_free(s->stats_vq_elem); } s->stats_vq_elem = elem; /* Initialize the stats to get rid of any stale values. This is only * needed to handle the case where a guest supports fewer stats than it * used to (ie. it has booted into an old kernel). */ reset_stats(s); while (iov_to_buf(elem->out_sg, elem->out_num, offset, &stat, sizeof(stat)) == sizeof(stat)) { uint16_t tag = virtio_tswap16(vdev, stat.tag); uint64_t val = virtio_tswap64(vdev, stat.val); offset += sizeof(stat); if (tag < VIRTIO_BALLOON_S_NR) s->stats[tag] = val; } s->stats_vq_offset = offset; if (qemu_gettimeofday(&tv) < 0) { warn_report("%s: failed to get time of day", __func__); goto out; } s->stats_last_update = tv.tv_sec; out: if (balloon_stats_enabled(s)) { balloon_stats_change_timer(s, s->stats_poll_interval); } }
int keysym2scancode(kbd_layout_t *k, int keysym, bool shift, bool altgr, bool ctrl) { static const uint32_t mask = SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL; uint32_t mods, i; struct keysym2code *keysym2code; #ifdef XK_ISO_Left_Tab if (keysym == XK_ISO_Left_Tab) { keysym = XK_Tab; } #endif keysym2code = g_hash_table_lookup(k->hash, GINT_TO_POINTER(keysym)); if (!keysym2code) { trace_keymap_unmapped(keysym); warn_report("no scancode found for keysym %d", keysym); return 0; } if (keysym2code->count == 1) { return keysym2code->keycodes[0]; } /* * We have multiple keysym -> keycode mappings. * * Check whenever we find one mapping where the modifier state of * the mapping matches the current user interface modifier state. * If so, prefer that one. */ mods = 0; if (shift) { mods |= SCANCODE_SHIFT; } if (altgr) { mods |= SCANCODE_ALTGR; } if (ctrl) { mods |= SCANCODE_CTRL; } for (i = 0; i < keysym2code->count; i++) { if ((keysym2code->keycodes[i] & mask) == mods) { return keysym2code->keycodes[i]; } } return keysym2code->keycodes[0]; }
static void balloon_deflate_page(VirtIOBalloon *balloon, MemoryRegion *mr, hwaddr offset) { void *addr = memory_region_get_ram_ptr(mr) + offset; RAMBlock *rb; size_t rb_page_size; ram_addr_t ram_offset, host_page_base; void *host_addr; int ret; /* XXX is there a better way to get to the RAMBlock than via a * host address? */ rb = qemu_ram_block_from_host(addr, false, &ram_offset); rb_page_size = qemu_ram_pagesize(rb); host_page_base = ram_offset & ~(rb_page_size - 1); if (balloon->pbp && rb == balloon->pbp->rb && host_page_base == balloon->pbp->base) { int subpages = rb_page_size / BALLOON_PAGE_SIZE; /* * This means the guest has asked to discard some of the 4kiB * subpages of a host page, but then changed its mind and * asked to keep them after all. It's exceedingly unlikely * for a guest to do this in practice, but handle it anyway, * since getting it wrong could mean discarding memory the * guest is still using. */ bitmap_clear(balloon->pbp->bitmap, (ram_offset - balloon->pbp->base) / BALLOON_PAGE_SIZE, subpages); if (bitmap_empty(balloon->pbp->bitmap, subpages)) { g_free(balloon->pbp); balloon->pbp = NULL; } } host_addr = (void *)((uintptr_t)addr & ~(rb_page_size - 1)); /* When a page is deflated, we hint the whole host page it lives * on, since we can't do anything smaller */ ret = qemu_madvise(host_addr, rb_page_size, QEMU_MADV_WILLNEED); if (ret != 0) { warn_report("Couldn't MADV_WILLNEED on balloon deflate: %s", strerror(errno)); /* Otherwise ignore, failing to page hint shouldn't be fatal */ } }
/* * helper to parse debug environment variables */ int parse_debug_env(const char *name, int max, int initial) { char *debug_env = getenv(name); char *inv = NULL; long debug; if (!debug_env) { return initial; } errno = 0; debug = strtol(debug_env, &inv, 10); if (inv == debug_env) { return initial; } if (debug < 0 || debug > max || errno != 0) { warn_report("%s not in [0, %d]", name, max); return initial; } return debug; }
static int ast2500_rambits(AspeedSDMCState *s) { switch (s->ram_size >> 20) { case 128: return ASPEED_SDMC_AST2500_128MB; case 256: return ASPEED_SDMC_AST2500_256MB; case 512: return ASPEED_SDMC_AST2500_512MB; case 1024: return ASPEED_SDMC_AST2500_1024MB; default: break; } /* use a common default */ warn_report("Invalid RAM size 0x%" PRIx64 ". Using default 512M", s->ram_size); s->ram_size = 512 << 20; return ASPEED_SDMC_AST2500_512MB; }
static void add_keysym(char *line, int keysym, int keycode, kbd_layout_t *k) { struct keysym2code *keysym2code; keysym2code = g_hash_table_lookup(k->hash, GINT_TO_POINTER(keysym)); if (keysym2code) { if (keysym2code->count < ARRAY_SIZE(keysym2code->keycodes)) { keysym2code->keycodes[keysym2code->count++] = keycode; } else { warn_report("more than %zd keycodes for keysym %d", ARRAY_SIZE(keysym2code->keycodes), keysym); } return; } keysym2code = g_new0(struct keysym2code, 1); keysym2code->keycodes[0] = keycode; keysym2code->count = 1; g_hash_table_replace(k->hash, GINT_TO_POINTER(keysym), keysym2code); trace_keymap_add(keysym, keycode, line); }
/* Check whether this OS version supports VSS providers */ static bool vss_check_os_version(void) { OSVERSIONINFO OSver; OSver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionEx(&OSver); if ((OSver.dwMajorVersion == 5 && OSver.dwMinorVersion >= 2) || OSver.dwMajorVersion > 5) { BOOL wow64 = false; #ifndef _WIN64 /* Provider doesn't work under WOW64 (32bit agent on 64bit OS) */ if (!IsWow64Process(GetCurrentProcess(), &wow64)) { fprintf(stderr, "failed to IsWow64Process (Error: %lx\n)\n", GetLastError()); return false; } if (wow64) { warn_report("Running under WOW64"); } #endif return !wow64; } return false; }
/* ram_size must be set to match the upper bound of memory in the * device tree (linux/arch/arm/boot/dts/highbank.dts), which is * normally 0xff900000 or -m 4089. When running this board on a * 32-bit host, set the reg value of memory to 0xf7ff00000 in the * device tree and pass -m 2047 to QEMU. */ static void calxeda_init(MachineState *machine, enum cxmachines machine_id) { ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; DeviceState *dev = NULL; SysBusDevice *busdev; qemu_irq pic[128]; int n; qemu_irq cpu_irq[4]; qemu_irq cpu_fiq[4]; MemoryRegion *sysram; MemoryRegion *dram; MemoryRegion *sysmem; char *sysboot_filename; switch (machine_id) { case CALXEDA_HIGHBANK: machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a9"); break; case CALXEDA_MIDWAY: machine->cpu_type = ARM_CPU_TYPE_NAME("cortex-a15"); break; default: assert(0); } for (n = 0; n < smp_cpus; n++) { Object *cpuobj; ARMCPU *cpu; cpuobj = object_new(machine->cpu_type); cpu = ARM_CPU(cpuobj); object_property_set_int(cpuobj, QEMU_PSCI_CONDUIT_SMC, "psci-conduit", &error_abort); if (n) { /* Secondary CPUs start in PSCI powered-down state */ object_property_set_bool(cpuobj, true, "start-powered-off", &error_abort); } if (object_property_find(cpuobj, "reset-cbar", NULL)) { object_property_set_int(cpuobj, MPCORE_PERIPHBASE, "reset-cbar", &error_abort); } object_property_set_bool(cpuobj, true, "realized", &error_fatal); cpu_irq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_IRQ); cpu_fiq[n] = qdev_get_gpio_in(DEVICE(cpu), ARM_CPU_FIQ); } sysmem = get_system_memory(); dram = g_new(MemoryRegion, 1); memory_region_allocate_system_memory(dram, NULL, "highbank.dram", ram_size); /* SDRAM at address zero. */ memory_region_add_subregion(sysmem, 0, dram); sysram = g_new(MemoryRegion, 1); memory_region_init_ram_nomigrate(sysram, NULL, "highbank.sysram", 0x8000, &error_fatal); memory_region_add_subregion(sysmem, 0xfff88000, sysram); if (bios_name != NULL) { sysboot_filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (sysboot_filename != NULL) { if (load_image_targphys(sysboot_filename, 0xfff88000, 0x8000) < 0) { error_report("Unable to load %s", bios_name); exit(1); } g_free(sysboot_filename); } else { error_report("Unable to find %s", bios_name); exit(1); } } switch (machine_id) { case CALXEDA_HIGHBANK: dev = qdev_create(NULL, "l2x0"); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xfff12000); dev = qdev_create(NULL, TYPE_A9MPCORE_PRIV); break; case CALXEDA_MIDWAY: dev = qdev_create(NULL, TYPE_A15MPCORE_PRIV); break; } qdev_prop_set_uint32(dev, "num-cpu", smp_cpus); qdev_prop_set_uint32(dev, "num-irq", NIRQ_GIC); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, MPCORE_PERIPHBASE); for (n = 0; n < smp_cpus; n++) { sysbus_connect_irq(busdev, n, cpu_irq[n]); sysbus_connect_irq(busdev, n + smp_cpus, cpu_fiq[n]); } for (n = 0; n < 128; n++) { pic[n] = qdev_get_gpio_in(dev, n); } dev = qdev_create(NULL, "sp804"); qdev_prop_set_uint32(dev, "freq0", 150000000); qdev_prop_set_uint32(dev, "freq1", 150000000); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xfff34000); sysbus_connect_irq(busdev, 0, pic[18]); pl011_create(0xfff36000, pic[20], serial_hds[0]); dev = qdev_create(NULL, TYPE_HIGHBANK_REGISTERS); qdev_init_nofail(dev); busdev = SYS_BUS_DEVICE(dev); sysbus_mmio_map(busdev, 0, 0xfff3c000); sysbus_create_simple("pl061", 0xfff30000, pic[14]); sysbus_create_simple("pl061", 0xfff31000, pic[15]); sysbus_create_simple("pl061", 0xfff32000, pic[16]); sysbus_create_simple("pl061", 0xfff33000, pic[17]); sysbus_create_simple("pl031", 0xfff35000, pic[19]); sysbus_create_simple("pl022", 0xfff39000, pic[23]); sysbus_create_simple(TYPE_SYSBUS_AHCI, 0xffe08000, pic[83]); if (nd_table[0].used) { qemu_check_nic_model(&nd_table[0], "xgmac"); dev = qdev_create(NULL, "xgmac"); qdev_set_nic_properties(dev, &nd_table[0]); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff50000); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[77]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[78]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[79]); qemu_check_nic_model(&nd_table[1], "xgmac"); dev = qdev_create(NULL, "xgmac"); qdev_set_nic_properties(dev, &nd_table[1]); qdev_init_nofail(dev); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0xfff51000); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[80]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 1, pic[81]); sysbus_connect_irq(SYS_BUS_DEVICE(dev), 2, pic[82]); } /* TODO create and connect IDE devices for ide_drive_get() */ highbank_binfo.ram_size = ram_size; highbank_binfo.kernel_filename = kernel_filename; highbank_binfo.kernel_cmdline = kernel_cmdline; highbank_binfo.initrd_filename = initrd_filename; /* highbank requires a dtb in order to boot, and the dtb will override * the board ID. The following value is ignored, so set it to -1 to be * clear that the value is meaningless. */ highbank_binfo.board_id = -1; highbank_binfo.nb_cpus = smp_cpus; highbank_binfo.loader_start = 0; highbank_binfo.write_secondary_boot = hb_write_secondary; highbank_binfo.secondary_cpu_reset_hook = hb_reset_secondary; if (!kvm_enabled()) { highbank_binfo.board_setup_addr = BOARD_SETUP_ADDR; highbank_binfo.write_board_setup = hb_write_board_setup; highbank_binfo.secure_board_setup = true; } else { warn_report("cannot load built-in Monitor support " "if KVM is enabled. Some guests (such as Linux) " "may not boot."); } arm_load_kernel(ARM_CPU(first_cpu), &highbank_binfo); }
/* * The PowerNV cores (and threads) need to use real HW ids and not an * incremental index like it has been done on other platforms. This HW * id is stored in the CPU PIR, it is used to create cpu nodes in the * device tree, used in XSCOM to address cores and in interrupt * servers. */ static void powernv_create_core_node(PnvChip *chip, PnvCore *pc, void *fdt) { CPUState *cs = CPU(DEVICE(pc->threads)); DeviceClass *dc = DEVICE_GET_CLASS(cs); PowerPCCPU *cpu = POWERPC_CPU(cs); int smt_threads = CPU_CORE(pc)->nr_threads; CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); uint32_t servers_prop[smt_threads]; int i; uint32_t segs[] = {cpu_to_be32(28), cpu_to_be32(40), 0xffffffff, 0xffffffff}; uint32_t tbfreq = PNV_TIMEBASE_FREQ; uint32_t cpufreq = 1000000000; uint32_t page_sizes_prop[64]; size_t page_sizes_prop_size; const uint8_t pa_features[] = { 24, 0, 0xf6, 0x3f, 0xc7, 0xc0, 0x80, 0xf0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00 }; int offset; char *nodename; int cpus_offset = get_cpus_node(fdt); nodename = g_strdup_printf("%s@%x", dc->fw_name, pc->pir); offset = fdt_add_subnode(fdt, cpus_offset, nodename); _FDT(offset); g_free(nodename); _FDT((fdt_setprop_cell(fdt, offset, "ibm,chip-id", chip->chip_id))); _FDT((fdt_setprop_cell(fdt, offset, "reg", pc->pir))); _FDT((fdt_setprop_cell(fdt, offset, "ibm,pir", pc->pir))); _FDT((fdt_setprop_string(fdt, offset, "device_type", "cpu"))); _FDT((fdt_setprop_cell(fdt, offset, "cpu-version", env->spr[SPR_PVR]))); _FDT((fdt_setprop_cell(fdt, offset, "d-cache-block-size", env->dcache_line_size))); _FDT((fdt_setprop_cell(fdt, offset, "d-cache-line-size", env->dcache_line_size))); _FDT((fdt_setprop_cell(fdt, offset, "i-cache-block-size", env->icache_line_size))); _FDT((fdt_setprop_cell(fdt, offset, "i-cache-line-size", env->icache_line_size))); if (pcc->l1_dcache_size) { _FDT((fdt_setprop_cell(fdt, offset, "d-cache-size", pcc->l1_dcache_size))); } else { warn_report("Unknown L1 dcache size for cpu"); } if (pcc->l1_icache_size) { _FDT((fdt_setprop_cell(fdt, offset, "i-cache-size", pcc->l1_icache_size))); } else { warn_report("Unknown L1 icache size for cpu"); } _FDT((fdt_setprop_cell(fdt, offset, "timebase-frequency", tbfreq))); _FDT((fdt_setprop_cell(fdt, offset, "clock-frequency", cpufreq))); _FDT((fdt_setprop_cell(fdt, offset, "ibm,slb-size", env->slb_nr))); _FDT((fdt_setprop_string(fdt, offset, "status", "okay"))); _FDT((fdt_setprop(fdt, offset, "64-bit", NULL, 0))); if (env->spr_cb[SPR_PURR].oea_read) { _FDT((fdt_setprop(fdt, offset, "ibm,purr", NULL, 0))); } if (env->mmu_model & POWERPC_MMU_1TSEG) { _FDT((fdt_setprop(fdt, offset, "ibm,processor-segment-sizes", segs, sizeof(segs)))); } /* Advertise VMX/VSX (vector extensions) if available * 0 / no property == no vector extensions * 1 == VMX / Altivec available * 2 == VSX available */ if (env->insns_flags & PPC_ALTIVEC) { uint32_t vmx = (env->insns_flags2 & PPC2_VSX) ? 2 : 1; _FDT((fdt_setprop_cell(fdt, offset, "ibm,vmx", vmx))); } /* Advertise DFP (Decimal Floating Point) if available * 0 / no property == no DFP * 1 == DFP available */ if (env->insns_flags2 & PPC2_DFP) { _FDT((fdt_setprop_cell(fdt, offset, "ibm,dfp", 1))); } page_sizes_prop_size = ppc_create_page_sizes_prop(env, page_sizes_prop, sizeof(page_sizes_prop)); if (page_sizes_prop_size) { _FDT((fdt_setprop(fdt, offset, "ibm,segment-page-sizes", page_sizes_prop, page_sizes_prop_size))); } _FDT((fdt_setprop(fdt, offset, "ibm,pa-features", pa_features, sizeof(pa_features)))); /* Build interrupt servers properties */ for (i = 0; i < smt_threads; i++) { servers_prop[i] = cpu_to_be32(pc->pir + i); } _FDT((fdt_setprop(fdt, offset, "ibm,ppc-interrupt-server#s", servers_prop, sizeof(servers_prop)))); }
static void net_init_tap_one(const NetdevTapOptions *tap, NetClientState *peer, const char *model, const char *name, const char *ifname, const char *script, const char *downscript, const char *vhostfdname, int vnet_hdr, int fd, Error **errp) { Error *err = NULL; TAPState *s = net_tap_fd_init(peer, model, name, fd, vnet_hdr); int vhostfd; tap_set_sndbuf(s->fd, tap, &err); if (err) { error_propagate(errp, err); return; } if (tap->has_fd || tap->has_fds) { snprintf(s->nc.info_str, sizeof(s->nc.info_str), "fd=%d", fd); } else if (tap->has_helper) { snprintf(s->nc.info_str, sizeof(s->nc.info_str), "helper=%s", tap->helper); } else { snprintf(s->nc.info_str, sizeof(s->nc.info_str), "ifname=%s,script=%s,downscript=%s", ifname, script, downscript); if (strcmp(downscript, "no") != 0) { snprintf(s->down_script, sizeof(s->down_script), "%s", downscript); snprintf(s->down_script_arg, sizeof(s->down_script_arg), "%s", ifname); } } if (tap->has_vhost ? tap->vhost : vhostfdname || (tap->has_vhostforce && tap->vhostforce)) { VhostNetOptions options; options.backend_type = VHOST_BACKEND_TYPE_KERNEL; options.net_backend = &s->nc; if (tap->has_poll_us) { options.busyloop_timeout = tap->poll_us; } else { options.busyloop_timeout = 0; } if (vhostfdname) { vhostfd = monitor_fd_param(cur_mon, vhostfdname, &err); if (vhostfd == -1) { if (tap->has_vhostforce && tap->vhostforce) { error_propagate(errp, err); } else { warn_report_err(err); } return; } qemu_set_nonblock(vhostfd); } else { vhostfd = open("/dev/vhost-net", O_RDWR); if (vhostfd < 0) { if (tap->has_vhostforce && tap->vhostforce) { error_setg_errno(errp, errno, "tap: open vhost char device failed"); } else { warn_report("tap: open vhost char device failed: %s", strerror(errno)); } return; } fcntl(vhostfd, F_SETFL, O_NONBLOCK); } options.opaque = (void *)(uintptr_t)vhostfd; s->vhost_net = vhost_net_init(&options); if (!s->vhost_net) { if (tap->has_vhostforce && tap->vhostforce) { error_setg(errp, VHOST_NET_INIT_FAILED); } else { warn_report(VHOST_NET_INIT_FAILED); } return; } } else if (vhostfdname) { error_setg(errp, "vhostfd(s)= is not valid without vhost"); } }
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRBDState *s = bs->opaque; const char *pool, *snap, *conf, *user, *image_name, *keypairs; const char *secretid, *filename; QemuOpts *opts; Error *local_err = NULL; char *mon_host = NULL; int r; /* If we are given a filename, parse the filename, with precedence given to * filename encoded options */ filename = qdict_get_try_str(options, "filename"); if (filename) { warn_report("'filename' option specified. " "This is an unsupported option, and may be deprecated " "in the future"); qemu_rbd_parse_filename(filename, options, &local_err); if (local_err) { r = -EINVAL; error_propagate(errp, local_err); goto exit; } } opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { error_propagate(errp, local_err); r = -EINVAL; goto failed_opts; } mon_host = qemu_rbd_mon_host(options, &local_err); if (local_err) { error_propagate(errp, local_err); r = -EINVAL; goto failed_opts; } secretid = qemu_opt_get(opts, "password-secret"); pool = qemu_opt_get(opts, "pool"); conf = qemu_opt_get(opts, "conf"); snap = qemu_opt_get(opts, "snapshot"); user = qemu_opt_get(opts, "user"); image_name = qemu_opt_get(opts, "image"); keypairs = qemu_opt_get(opts, "=keyvalue-pairs"); if (!pool || !image_name) { error_setg(errp, "Parameters 'pool' and 'image' are required"); r = -EINVAL; goto failed_opts; } r = rados_create(&s->cluster, user); if (r < 0) { error_setg_errno(errp, -r, "error initializing"); goto failed_opts; } s->snap = g_strdup(snap); s->image_name = g_strdup(image_name); /* try default location when conf=NULL, but ignore failure */ r = rados_conf_read_file(s->cluster, conf); if (conf && r < 0) { error_setg_errno(errp, -r, "error reading conf file %s", conf); goto failed_shutdown; } r = qemu_rbd_set_keypairs(s->cluster, keypairs, errp); if (r < 0) { goto failed_shutdown; } if (mon_host) { r = rados_conf_set(s->cluster, "mon_host", mon_host); if (r < 0) { goto failed_shutdown; } } if (qemu_rbd_set_auth(s->cluster, secretid, errp) < 0) { r = -EIO; goto failed_shutdown; } /* * Fallback to more conservative semantics if setting cache * options fails. Ignore errors from setting rbd_cache because the * only possible error is that the option does not exist, and * librbd defaults to no caching. If write through caching cannot * be set up, fall back to no caching. */ if (flags & BDRV_O_NOCACHE) { rados_conf_set(s->cluster, "rbd_cache", "false"); } else { rados_conf_set(s->cluster, "rbd_cache", "true"); } r = rados_connect(s->cluster); if (r < 0) { error_setg_errno(errp, -r, "error connecting"); goto failed_shutdown; } r = rados_ioctx_create(s->cluster, pool, &s->io_ctx); if (r < 0) { error_setg_errno(errp, -r, "error opening pool %s", pool); goto failed_shutdown; } /* rbd_open is always r/w */ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap); if (r < 0) { error_setg_errno(errp, -r, "error reading header from %s", s->image_name); goto failed_open; } /* If we are using an rbd snapshot, we must be r/o, otherwise * leave as-is */ if (s->snap != NULL) { if (!bdrv_is_read_only(bs)) { error_report("Opening rbd snapshots without an explicit " "read-only=on option is deprecated. Future versions " "will refuse to open the image instead of " "automatically marking the image read-only."); r = bdrv_set_read_only(bs, true, &local_err); if (r < 0) { error_propagate(errp, local_err); goto failed_open; } } } qemu_opts_del(opts); return 0; failed_open: rados_ioctx_destroy(s->io_ctx); failed_shutdown: rados_shutdown(s->cluster); g_free(s->snap); g_free(s->image_name); failed_opts: qemu_opts_del(opts); g_free(mon_host); exit: return r; }
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRBDState *s = bs->opaque; BlockdevOptionsRbd *opts = NULL; const QDictEntry *e; Error *local_err = NULL; char *keypairs, *secretid; int r; keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs")); if (keypairs) { qdict_del(options, "=keyvalue-pairs"); } secretid = g_strdup(qdict_get_try_str(options, "password-secret")); if (secretid) { qdict_del(options, "password-secret"); } r = qemu_rbd_convert_options(options, &opts, &local_err); if (local_err) { /* If keypairs are present, that means some options are present in * the modern option format. Don't attempt to parse legacy option * formats, as we won't support mixed usage. */ if (keypairs) { error_propagate(errp, local_err); goto out; } /* If the initial attempt to convert and process the options failed, * we may be attempting to open an image file that has the rbd options * specified in the older format consisting of all key/value pairs * encoded in the filename. Go ahead and attempt to parse the * filename, and see if we can pull out the required options. */ r = qemu_rbd_attempt_legacy_options(options, &opts, &keypairs); if (r < 0) { /* Propagate the original error, not the legacy parsing fallback * error, as the latter was just a best-effort attempt. */ error_propagate(errp, local_err); goto out; } /* Take care whenever deciding to actually deprecate; once this ability * is removed, we will not be able to open any images with legacy-styled * backing image strings. */ warn_report("RBD options encoded in the filename as keyvalue pairs " "is deprecated"); } /* Remove the processed options from the QDict (the visitor processes * _all_ options in the QDict) */ while ((e = qdict_first(options))) { qdict_del(options, e->key); } r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts, !(flags & BDRV_O_NOCACHE), keypairs, secretid, errp); if (r < 0) { goto out; } s->snap = g_strdup(opts->snapshot); s->image_name = g_strdup(opts->image); /* rbd_open is always r/w */ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap); if (r < 0) { error_setg_errno(errp, -r, "error reading header from %s", s->image_name); goto failed_open; } /* If we are using an rbd snapshot, we must be r/o, otherwise * leave as-is */ if (s->snap != NULL) { r = bdrv_apply_auto_read_only(bs, "rbd snapshots are read-only", errp); if (r < 0) { rbd_close(s->image); goto failed_open; } } r = 0; goto out; failed_open: rados_ioctx_destroy(s->io_ctx); g_free(s->snap); g_free(s->image_name); rados_shutdown(s->cluster); out: qapi_free_BlockdevOptionsRbd(opts); g_free(keypairs); g_free(secretid); return r; }
static void imx25_pdk_init(MachineState *machine) { IMX25PDK *s = g_new0(IMX25PDK, 1); unsigned int ram_size; unsigned int alias_offset; int i; object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), TYPE_FSL_IMX25, &error_abort, NULL); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal); /* We need to initialize our memory */ if (machine->ram_size > (FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE)) { warn_report("RAM size " RAM_ADDR_FMT " above max supported, " "reduced to %x", machine->ram_size, FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE); machine->ram_size = FSL_IMX25_SDRAM0_SIZE + FSL_IMX25_SDRAM1_SIZE; } memory_region_allocate_system_memory(&s->ram, NULL, "imx25.ram", machine->ram_size); memory_region_add_subregion(get_system_memory(), FSL_IMX25_SDRAM0_ADDR, &s->ram); /* initialize the alias memory if any */ for (i = 0, ram_size = machine->ram_size, alias_offset = 0; (i < 2) && ram_size; i++) { unsigned int size; static const struct { hwaddr addr; unsigned int size; } ram[2] = { { FSL_IMX25_SDRAM0_ADDR, FSL_IMX25_SDRAM0_SIZE }, { FSL_IMX25_SDRAM1_ADDR, FSL_IMX25_SDRAM1_SIZE }, }; size = MIN(ram_size, ram[i].size); ram_size -= size; if (size < ram[i].size) { memory_region_init_alias(&s->ram_alias, NULL, "ram.alias", &s->ram, alias_offset, ram[i].size - size); memory_region_add_subregion(get_system_memory(), ram[i].addr + size, &s->ram_alias); } alias_offset += ram[i].size; } imx25_pdk_binfo.ram_size = machine->ram_size; imx25_pdk_binfo.kernel_filename = machine->kernel_filename; imx25_pdk_binfo.kernel_cmdline = machine->kernel_cmdline; imx25_pdk_binfo.initrd_filename = machine->initrd_filename; imx25_pdk_binfo.loader_start = FSL_IMX25_SDRAM0_ADDR; imx25_pdk_binfo.board_id = 1771, imx25_pdk_binfo.nb_cpus = 1; /* * We test explicitly for qtest here as it is not done (yet?) in * arm_load_kernel(). Without this the "make check" command would * fail. */ if (!qtest_enabled()) { arm_load_kernel(&s->soc.cpu, &imx25_pdk_binfo); } else { /* * This I2C device doesn't exist on the real board. * We add it here (only on qtest usage) to be able to do a bit * of simple qtest. See "make check" for details. */ i2c_create_slave((I2CBus *)qdev_get_child_bus(DEVICE(&s->soc.i2c[0]), "i2c-bus.0"), "ds1338", 0x68); } }
/* Install a copy of the ACPI table specified in @blob. * * If @has_header is set, @blob starts with the System Description Table Header * structure. Otherwise, "dfl_hdr" is prepended. In any case, each header field * is optionally overwritten from @hdrs. * * It is valid to call this function with * (@blob == NULL && bloblen == 0 && !has_header). * * @hdrs->file and @hdrs->data are ignored. * * SIZE_MAX is considered "infinity" in this function. * * The number of tables that can be installed is not limited, but the 16-bit * counter at the beginning of "acpi_tables" wraps around after UINT16_MAX. */ static void acpi_table_install(const char unsigned *blob, size_t bloblen, bool has_header, const struct AcpiTableOptions *hdrs, Error **errp) { size_t body_start; const char unsigned *hdr_src; size_t body_size, acpi_payload_size; struct acpi_table_header *ext_hdr; unsigned changed_fields; /* Calculate where the ACPI table body starts within the blob, plus where * to copy the ACPI table header from. */ if (has_header) { /* _length | ACPI header in blob | blob body * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^ * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size * == body_start * * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * acpi_payload_size == bloblen */ body_start = sizeof dfl_hdr; if (bloblen < body_start) { error_setg(errp, "ACPI table claiming to have header is too " "short, available: %zu, expected: %zu", bloblen, body_start); return; } hdr_src = blob; } else { /* _length | ACPI header in template | blob body * ^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^ * ACPI_TABLE_PFX_SIZE sizeof dfl_hdr body_size * == bloblen * * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * acpi_payload_size */ body_start = 0; hdr_src = dfl_hdr; } body_size = bloblen - body_start; acpi_payload_size = sizeof dfl_hdr + body_size; if (acpi_payload_size > UINT16_MAX) { error_setg(errp, "ACPI table too big, requested: %zu, max: %u", acpi_payload_size, (unsigned)UINT16_MAX); return; } /* We won't fail from here on. Initialize / extend the globals. */ if (acpi_tables == NULL) { acpi_tables_len = sizeof(uint16_t); acpi_tables = g_malloc0(acpi_tables_len); } acpi_tables = g_realloc(acpi_tables, acpi_tables_len + ACPI_TABLE_PFX_SIZE + sizeof dfl_hdr + body_size); ext_hdr = (struct acpi_table_header *)(acpi_tables + acpi_tables_len); acpi_tables_len += ACPI_TABLE_PFX_SIZE; memcpy(acpi_tables + acpi_tables_len, hdr_src, sizeof dfl_hdr); acpi_tables_len += sizeof dfl_hdr; if (blob != NULL) { memcpy(acpi_tables + acpi_tables_len, blob + body_start, body_size); acpi_tables_len += body_size; } /* increase number of tables */ stw_le_p(acpi_tables, lduw_le_p(acpi_tables) + 1u); /* Update the header fields. The strings need not be NUL-terminated. */ changed_fields = 0; ext_hdr->_length = cpu_to_le16(acpi_payload_size); if (hdrs->has_sig) { strncpy(ext_hdr->sig, hdrs->sig, sizeof ext_hdr->sig); ++changed_fields; } if (has_header && le32_to_cpu(ext_hdr->length) != acpi_payload_size) { warn_report("ACPI table has wrong length, header says " "%" PRIu32 ", actual size %zu bytes", le32_to_cpu(ext_hdr->length), acpi_payload_size); } ext_hdr->length = cpu_to_le32(acpi_payload_size); if (hdrs->has_rev) { ext_hdr->revision = hdrs->rev; ++changed_fields; } ext_hdr->checksum = 0; if (hdrs->has_oem_id) { strncpy(ext_hdr->oem_id, hdrs->oem_id, sizeof ext_hdr->oem_id); ++changed_fields; } if (hdrs->has_oem_table_id) { strncpy(ext_hdr->oem_table_id, hdrs->oem_table_id, sizeof ext_hdr->oem_table_id); ++changed_fields; } if (hdrs->has_oem_rev) { ext_hdr->oem_revision = cpu_to_le32(hdrs->oem_rev); ++changed_fields; } if (hdrs->has_asl_compiler_id) { strncpy(ext_hdr->asl_compiler_id, hdrs->asl_compiler_id, sizeof ext_hdr->asl_compiler_id); ++changed_fields; } if (hdrs->has_asl_compiler_rev) { ext_hdr->asl_compiler_revision = cpu_to_le32(hdrs->asl_compiler_rev); ++changed_fields; } if (!has_header && changed_fields == 0) { warn_report("ACPI table: no headers are specified"); } /* recalculate checksum */ ext_hdr->checksum = acpi_checksum((const char unsigned *)ext_hdr + ACPI_TABLE_PFX_SIZE, acpi_payload_size); }
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRBDState *s = bs->opaque; BlockdevOptionsRbd *opts = NULL; Visitor *v; QObject *crumpled = NULL; const QDictEntry *e; Error *local_err = NULL; const char *filename; char *keypairs, *secretid; int r; /* If we are given a filename, parse the filename, with precedence given to * filename encoded options */ filename = qdict_get_try_str(options, "filename"); if (filename) { warn_report("'filename' option specified. " "This is an unsupported option, and may be deprecated " "in the future"); qemu_rbd_parse_filename(filename, options, &local_err); qdict_del(options, "filename"); if (local_err) { error_propagate(errp, local_err); return -EINVAL; } } keypairs = g_strdup(qdict_get_try_str(options, "=keyvalue-pairs")); if (keypairs) { qdict_del(options, "=keyvalue-pairs"); } secretid = g_strdup(qdict_get_try_str(options, "password-secret")); if (secretid) { qdict_del(options, "password-secret"); } /* Convert the remaining options into a QAPI object */ crumpled = qdict_crumple(options, errp); if (crumpled == NULL) { r = -EINVAL; goto out; } v = qobject_input_visitor_new_keyval(crumpled); visit_type_BlockdevOptionsRbd(v, NULL, &opts, &local_err); visit_free(v); qobject_unref(crumpled); if (local_err) { error_propagate(errp, local_err); r = -EINVAL; goto out; } /* Remove the processed options from the QDict (the visitor processes * _all_ options in the QDict) */ while ((e = qdict_first(options))) { qdict_del(options, e->key); } r = qemu_rbd_connect(&s->cluster, &s->io_ctx, opts, !(flags & BDRV_O_NOCACHE), keypairs, secretid, errp); if (r < 0) { goto out; } s->snap = g_strdup(opts->snapshot); s->image_name = g_strdup(opts->image); /* rbd_open is always r/w */ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap); if (r < 0) { error_setg_errno(errp, -r, "error reading header from %s", s->image_name); goto failed_open; } /* If we are using an rbd snapshot, we must be r/o, otherwise * leave as-is */ if (s->snap != NULL) { if (!bdrv_is_read_only(bs)) { error_report("Opening rbd snapshots without an explicit " "read-only=on option is deprecated. Future versions " "will refuse to open the image instead of " "automatically marking the image read-only."); r = bdrv_set_read_only(bs, true, &local_err); if (r < 0) { error_propagate(errp, local_err); goto failed_open; } } } r = 0; goto out; failed_open: rados_ioctx_destroy(s->io_ctx); g_free(s->snap); g_free(s->image_name); rados_shutdown(s->cluster); out: qapi_free_BlockdevOptionsRbd(opts); g_free(keypairs); g_free(secretid); return r; }
static void mips_r4k_init(MachineState *machine) { ram_addr_t ram_size = machine->ram_size; const char *kernel_filename = machine->kernel_filename; const char *kernel_cmdline = machine->kernel_cmdline; const char *initrd_filename = machine->initrd_filename; char *filename; MemoryRegion *address_space_mem = get_system_memory(); MemoryRegion *ram = g_new(MemoryRegion, 1); MemoryRegion *bios; MemoryRegion *iomem = g_new(MemoryRegion, 1); MemoryRegion *isa_io = g_new(MemoryRegion, 1); MemoryRegion *isa_mem = g_new(MemoryRegion, 1); int bios_size; MIPSCPU *cpu; CPUMIPSState *env; ResetData *reset_info; int i; qemu_irq *i8259; ISABus *isa_bus; DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; DriveInfo *dinfo; int be; /* init CPUs */ cpu = MIPS_CPU(cpu_create(machine->cpu_type)); env = &cpu->env; reset_info = g_malloc0(sizeof(ResetData)); reset_info->cpu = cpu; reset_info->vector = env->active_tc.PC; qemu_register_reset(main_cpu_reset, reset_info); /* allocate RAM */ if (ram_size > (256 << 20)) { error_report("Too much memory for this machine: %dMB, maximum 256MB", ((unsigned int)ram_size / (1 << 20))); exit(1); } memory_region_allocate_system_memory(ram, NULL, "mips_r4k.ram", ram_size); memory_region_add_subregion(address_space_mem, 0, ram); memory_region_init_io(iomem, NULL, &mips_qemu_ops, NULL, "mips-qemu", 0x10000); memory_region_add_subregion(address_space_mem, 0x1fbf0000, iomem); /* Try to load a BIOS image. If this fails, we continue regardless, but initialize the hardware ourselves. When a kernel gets preloaded we also initialize the hardware, since the BIOS wasn't run. */ if (bios_name == NULL) bios_name = BIOS_FILENAME; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name); if (filename) { bios_size = get_image_size(filename); } else { bios_size = -1; } #ifdef TARGET_WORDS_BIGENDIAN be = 1; #else be = 0; #endif if ((bios_size > 0) && (bios_size <= BIOS_SIZE)) { bios = g_new(MemoryRegion, 1); memory_region_init_ram(bios, NULL, "mips_r4k.bios", BIOS_SIZE, &error_fatal); memory_region_set_readonly(bios, true); memory_region_add_subregion(get_system_memory(), 0x1fc00000, bios); load_image_targphys(filename, 0x1fc00000, BIOS_SIZE); } else if ((dinfo = drive_get(IF_PFLASH, 0, 0)) != NULL) { uint32_t mips_rom = 0x00400000; if (!pflash_cfi01_register(0x1fc00000, NULL, "mips_r4k.bios", mips_rom, blk_by_legacy_dinfo(dinfo), sector_len, mips_rom / sector_len, 4, 0, 0, 0, 0, be)) { fprintf(stderr, "qemu: Error registering flash memory.\n"); } } else if (!qtest_enabled()) { /* not fatal */ warn_report("could not load MIPS bios '%s'", bios_name); } g_free(filename); if (kernel_filename) { loaderparams.ram_size = ram_size; loaderparams.kernel_filename = kernel_filename; loaderparams.kernel_cmdline = kernel_cmdline; loaderparams.initrd_filename = initrd_filename; reset_info->vector = load_kernel(); } /* Init CPU internal devices */ cpu_mips_irq_init_cpu(cpu); cpu_mips_clock_init(cpu); /* ISA bus: IO space at 0x14000000, mem space at 0x10000000 */ memory_region_init_alias(isa_io, NULL, "isa-io", get_system_io(), 0, 0x00010000); memory_region_init(isa_mem, NULL, "isa-mem", 0x01000000); memory_region_add_subregion(get_system_memory(), 0x14000000, isa_io); memory_region_add_subregion(get_system_memory(), 0x10000000, isa_mem); isa_bus = isa_bus_new(NULL, isa_mem, get_system_io(), &error_abort); /* The PIC is attached to the MIPS CPU INT0 pin */ i8259 = i8259_init(isa_bus, env->irq[2]); isa_bus_irqs(isa_bus, i8259); mc146818_rtc_init(isa_bus, 2000, NULL); pit = i8254_pit_init(isa_bus, 0x40, 0, NULL); serial_hds_isa_init(isa_bus, 0, MAX_SERIAL_PORTS); isa_vga_init(isa_bus); if (nd_table[0].used) isa_ne2000_init(isa_bus, 0x300, 9, &nd_table[0]); ide_drive_get(hd, ARRAY_SIZE(hd)); for(i = 0; i < MAX_IDE_BUS; i++) isa_ide_init(isa_bus, ide_iobase[i], ide_iobase2[i], ide_irq[i], hd[MAX_IDE_DEVS * i], hd[MAX_IDE_DEVS * i + 1]); isa_create_simple(isa_bus, TYPE_I8042); }
int keysym2scancode(kbd_layout_t *k, int keysym, QKbdState *kbd, bool down) { static const uint32_t mask = SCANCODE_SHIFT | SCANCODE_ALTGR | SCANCODE_CTRL; uint32_t mods, i; struct keysym2code *keysym2code; #ifdef XK_ISO_Left_Tab if (keysym == XK_ISO_Left_Tab) { keysym = XK_Tab; } #endif keysym2code = g_hash_table_lookup(k->hash, GINT_TO_POINTER(keysym)); if (!keysym2code) { trace_keymap_unmapped(keysym); warn_report("no scancode found for keysym %d", keysym); return 0; } if (keysym2code->count == 1) { return keysym2code->keycodes[0]; } /* We have multiple keysym -> keycode mappings. */ if (down) { /* * On keydown: Check whenever we find one mapping where the * modifier state of the mapping matches the current user * interface modifier state. If so, prefer that one. */ mods = 0; if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_SHIFT)) { mods |= SCANCODE_SHIFT; } if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_ALTGR)) { mods |= SCANCODE_ALTGR; } if (kbd && qkbd_state_modifier_get(kbd, QKBD_MOD_CTRL)) { mods |= SCANCODE_CTRL; } for (i = 0; i < keysym2code->count; i++) { if ((keysym2code->keycodes[i] & mask) == mods) { return keysym2code->keycodes[i]; } } } else { /* * On keyup: Try find a key which is actually down. */ for (i = 0; i < keysym2code->count; i++) { QKeyCode qcode = qemu_input_key_number_to_qcode (keysym2code->keycodes[i]); if (kbd && qkbd_state_key_get(kbd, qcode)) { return keysym2code->keycodes[i]; } } } return keysym2code->keycodes[0]; }