/* * Loop through all dynamically created sysbus devices and call * func() for each instance. */ void foreach_dynamic_sysbus_device(FindSysbusDeviceFunc *func, void *opaque) { Object *container; SysBusFind find = { .func = func, .opaque = opaque, }; /* Loop through all sysbus devices that were spawened outside the machine */ container = container_get(qdev_get_machine(), "/peripheral"); find_sysbus_device(container, &find); container = container_get(qdev_get_machine(), "/peripheral-anon"); find_sysbus_device(container, &find); }
ram_addr_t get_current_ram_size(void) { MemoryDeviceInfoList *info_list = NULL; MemoryDeviceInfoList **prev = &info_list; MemoryDeviceInfoList *info; ram_addr_t size = ram_size; qmp_pc_dimm_device_list(qdev_get_machine(), &prev); for (info = info_list; info; info = info->next) { MemoryDeviceInfo *value = info->value; if (value) { switch (value->kind) { case MEMORY_DEVICE_INFO_KIND_DIMM: size += value->dimm->size; break; default: break; } } } qapi_free_MemoryDeviceInfoList(info_list); return size; }
int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp) { unsigned long *bitmap = bitmap_new(max_slots); int slot = 0; object_child_foreach(qdev_get_machine(), pc_dimm_slot2bitmap, bitmap); /* check if requested slot is not occupied */ if (hint) { if (*hint >= max_slots) { error_setg(errp, "invalid slot# %d, should be less than %d", *hint, max_slots); } else if (!test_bit(*hint, bitmap)) { slot = *hint; } else { error_setg(errp, "slot %d is busy", *hint); } goto out; } /* search for free slot */ slot = find_first_zero_bit(bitmap, max_slots); if (slot == max_slots) { error_setg(errp, "no free slots available"); } out: g_free(bitmap); return slot; }
/* * inquire NVDIMM devices and link them into the list which is * returned to the caller. * * Note: it is the caller's responsibility to free the list to avoid * memory leak. */ static GSList *nvdimm_get_device_list(void) { GSList *list = NULL; object_child_foreach(qdev_get_machine(), nvdimm_device_list, &list); return list; }
VirtualCssBus *virtual_css_bus_init(void) { VirtualCssBus *cbus; BusState *bus; DeviceState *dev; /* Create bridge device */ dev = qdev_create(NULL, TYPE_VIRTUAL_CSS_BRIDGE); object_property_add_child(qdev_get_machine(), TYPE_VIRTUAL_CSS_BRIDGE, OBJECT(dev), NULL); qdev_init_nofail(dev); /* Create bus on bridge device */ bus = qbus_create(TYPE_VIRTUAL_CSS_BUS, dev, "virtual-css"); cbus = VIRTUAL_CSS_BUS(bus); cbus->squash_mcss = s390_get_squash_mcss(); /* Enable hotplugging */ qbus_set_hotplug_handler(bus, dev, &error_abort); css_register_io_adapters(CSS_IO_ADAPTER_VIRTIO, true, false, 0, &error_abort); return cbus; }
static void spapr_cpu_reset(void *opaque) { PowerPCCPU *cpu = opaque; CPUState *cs = CPU(cpu); CPUPPCState *env = &cpu->env; PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu); SpaprCpuState *spapr_cpu = spapr_cpu_state(cpu); target_ulong lpcr; cpu_reset(cs); /* All CPUs start halted. CPU0 is unhalted from the machine level * reset code and the rest are explicitly started up by the guest * using an RTAS call */ cs->halted = 1; /* Set compatibility mode to match the boot CPU, which was either set * by the machine reset code or by CAS. This should never fail. */ ppc_set_compat(cpu, POWERPC_CPU(first_cpu)->compat_pvr, &error_abort); env->spr[SPR_HIOR] = 0; lpcr = env->spr[SPR_LPCR]; /* Set emulated LPCR to not send interrupts to hypervisor. Note that * under KVM, the actual HW LPCR will be set differently by KVM itself, * the settings below ensure proper operations with TCG in absence of * a real hypervisor. * * Clearing VPM0 will also cause us to use RMOR in mmu-hash64.c for * real mode accesses, which thankfully defaults to 0 and isn't * accessible in guest mode. * * Disable Power-saving mode Exit Cause exceptions for the CPU, so * we don't get spurious wakups before an RTAS start-cpu call. */ lpcr &= ~(LPCR_VPM0 | LPCR_VPM1 | LPCR_ISL | LPCR_KBV | pcc->lpcr_pm); lpcr |= LPCR_LPES0 | LPCR_LPES1; /* Set RMLS to the max (ie, 16G) */ lpcr &= ~LPCR_RMLS; lpcr |= 1ull << LPCR_RMLS_SHIFT; ppc_store_lpcr(cpu, lpcr); /* Set a full AMOR so guest can use the AMR as it sees fit */ env->spr[SPR_AMOR] = 0xffffffffffffffffull; spapr_cpu->vpa_addr = 0; spapr_cpu->slb_shadow_addr = 0; spapr_cpu->slb_shadow_size = 0; spapr_cpu->dtl_addr = 0; spapr_cpu->dtl_size = 0; spapr_caps_cpu_apply(SPAPR_MACHINE(qdev_get_machine()), cpu); kvm_check_mmu(cpu, &error_fatal); }
static void mch_realize(PCIDevice *d, Error **errp) { int i; MCHPCIState *mch = MCH_PCI_DEVICE(d); /* setup pci memory mapping */ pc_pci_as_mapping_init(OBJECT(mch), mch->system_memory, mch->pci_address_space); /* if *disabled* show SMRAM to all CPUs */ memory_region_init_alias(&mch->smram_region, OBJECT(mch), "smram-region", mch->pci_address_space, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xa0000, &mch->smram_region, 1); memory_region_set_enabled(&mch->smram_region, true); memory_region_init_alias(&mch->open_high_smram, OBJECT(mch), "smram-open-high", mch->ram_memory, 0xa0000, 0x20000); memory_region_add_subregion_overlap(mch->system_memory, 0xfeda0000, &mch->open_high_smram, 1); memory_region_set_enabled(&mch->open_high_smram, false); /* smram, as seen by SMM CPUs */ memory_region_init(&mch->smram, OBJECT(mch), "smram", 1ull << 32); memory_region_set_enabled(&mch->smram, true); memory_region_init_alias(&mch->low_smram, OBJECT(mch), "smram-low", mch->ram_memory, 0xa0000, 0x20000); memory_region_set_enabled(&mch->low_smram, true); memory_region_add_subregion(&mch->smram, 0xa0000, &mch->low_smram); memory_region_init_alias(&mch->high_smram, OBJECT(mch), "smram-high", mch->ram_memory, 0xa0000, 0x20000); memory_region_set_enabled(&mch->high_smram, true); memory_region_add_subregion(&mch->smram, 0xfeda0000, &mch->high_smram); memory_region_init_io(&mch->tseg_blackhole, OBJECT(mch), &tseg_blackhole_ops, NULL, "tseg-blackhole", 0); memory_region_set_enabled(&mch->tseg_blackhole, false); memory_region_add_subregion_overlap(mch->system_memory, mch->below_4g_mem_size, &mch->tseg_blackhole, 1); memory_region_init_alias(&mch->tseg_window, OBJECT(mch), "tseg-window", mch->ram_memory, mch->below_4g_mem_size, 0); memory_region_set_enabled(&mch->tseg_window, false); memory_region_add_subregion(&mch->smram, mch->below_4g_mem_size, &mch->tseg_window); object_property_add_const_link(qdev_get_machine(), "smram", OBJECT(&mch->smram), &error_abort); init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[0], PAM_BIOS_BASE, PAM_BIOS_SIZE); for (i = 0; i < 12; ++i) { init_pam(DEVICE(mch), mch->ram_memory, mch->system_memory, mch->pci_address_space, &mch->pam_regions[i+1], PAM_EXPAN_BASE + i * PAM_EXPAN_SIZE, PAM_EXPAN_SIZE); } }
static void qemu_s390_skeys_init(Object *obj) { QEMUS390SKeysState *skeys = QEMU_S390_SKEYS(obj); MachineState *machine = MACHINE(qdev_get_machine()); skeys->key_count = machine->maxram_size / TARGET_PAGE_SIZE; skeys->keydata = g_malloc0(skeys->key_count); }
static void s390_hot_add_cpu(const int64_t id, Error **errp) { MachineState *machine = MACHINE(qdev_get_machine()); Error *err = NULL; s390x_new_cpu(machine->cpu_model, id, &err); error_propagate(errp, err); }
uint64_t pc_dimm_get_free_addr(uint64_t address_space_start, uint64_t address_space_size, uint64_t *hint, uint64_t size, Error **errp) { GSList *list = NULL, *item; uint64_t new_addr, ret = 0; uint64_t address_space_end = address_space_start + address_space_size; if (!address_space_size) { error_setg(errp, "memory hotplug is not enabled, " "please add maxmem option"); goto out; } assert(address_space_end > address_space_start); object_child_foreach(qdev_get_machine(), pc_dimm_built_list, &list); if (hint) { new_addr = *hint; } else { new_addr = address_space_start; } /* find address range that will fit new DIMM */ for (item = list; item; item = g_slist_next(item)) { PCDIMMDevice *dimm = item->data; uint64_t dimm_size = object_property_get_int(OBJECT(dimm), PC_DIMM_SIZE_PROP, errp); if (errp && *errp) { goto out; } if (ranges_overlap(dimm->addr, dimm_size, new_addr, size)) { if (hint) { DeviceState *d = DEVICE(dimm); error_setg(errp, "address range conflicts with '%s'", d->id); goto out; } new_addr = dimm->addr + dimm_size; } } ret = new_addr; if (new_addr < address_space_start) { error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64 "] at 0x%" PRIx64, new_addr, size, address_space_start); } else if ((new_addr + size) > address_space_end) { error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64 "] beyond 0x%" PRIx64, new_addr, size, address_space_end); } out: g_slist_free(list); return ret; }
static void machine_init_notify(Notifier *notifier, void *data) { MachineState *machine = MACHINE(qdev_get_machine()); /* * Loop through all dynamically created sysbus devices and check if they are * all allowed. If a device is not allowed, error out. */ foreach_dynamic_sysbus_device(validate_sysbus_device, machine); }
uint64_t pc_existing_dimms_capacity(Error **errp) { pc_dimms_capacity cap; cap.size = 0; cap.errp = errp; pc_existing_dimms_capacity_internal(qdev_get_machine(), &cap); return cap.size; }
DeviceState *s390_flic_kvm_create(void) { DeviceState *dev = NULL; if (kvm_enabled()) { dev = qdev_create(NULL, TYPE_KVM_S390_FLIC); object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC, OBJECT(dev), NULL); } return dev; }
static void main_system_bus_create(void) { /* assign main_system_bus before qbus_create_inplace() * in order to make "if (bus != sysbus_get_default())" work */ main_system_bus = g_malloc0(system_bus_info.instance_size); qbus_create_inplace(main_system_bus, system_bus_info.instance_size, TYPE_SYSTEM_BUS, NULL, "main-system-bus"); OBJECT(main_system_bus)->free = g_free; object_property_add_child(container_get(qdev_get_machine(), "/unattached"), "sysbus", OBJECT(main_system_bus), NULL); }
bool ri_allowed(void) { if (kvm_enabled()) { MachineClass *mc = MACHINE_GET_CLASS(qdev_get_machine()); if (object_class_dynamic_cast(OBJECT_CLASS(mc), TYPE_S390_CCW_MACHINE)) { S390CcwMachineClass *s390mc = S390_MACHINE_CLASS(mc); return s390mc->ri_allowed; } } return 0; }
uint8_t *load_eeprom(void) { char *filename; int fd; int rc; int eeprom_file_size; const int eeprom_size = 256; uint8_t *eeprom_data = g_malloc(eeprom_size); const char *eeprom_file = object_property_get_str(qdev_get_machine(), "eeprom", NULL); if ((eeprom_file != NULL) && *eeprom_file) { filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, eeprom_file); assert(filename); eeprom_file_size = get_image_size(filename); if (eeprom_size != eeprom_file_size) { fprintf(stderr, "qemu: EEPROM file size != %d bytes. (Is %d bytes)\n", eeprom_size, eeprom_file_size); g_free(filename); exit(1); return NULL; } fd = open(filename, O_RDONLY | O_BINARY); if (fd < 0) { fprintf(stderr, "qemu: EEPROM file '%s' could not be opened.\n", filename); g_free(filename); exit(1); return NULL; } rc = read(fd, eeprom_data, eeprom_size); if (rc != eeprom_size) { fprintf(stderr, "qemu: Could not read the full EEPROM file.\n"); close(fd); g_free(filename); exit(1); return NULL; } close(fd); g_free(filename); } else { memcpy(eeprom_data, default_eeprom, eeprom_size); } return eeprom_data; }
S390CPU *s390_cpu_addr2state(uint16_t cpu_addr) { static MachineState *ms; if (!ms) { ms = MACHINE(qdev_get_machine()); g_assert(ms->possible_cpus); } /* CPU address corresponds to the core_id and the index */ if (cpu_addr >= ms->possible_cpus->len) { return NULL; } return S390_CPU(ms->possible_cpus->cpus[cpu_addr].cpu); }
void s390_stattrib_init(void) { Object *obj; obj = kvm_s390_stattrib_create(); if (!obj) { obj = object_new(TYPE_QEMU_S390_STATTRIB); } object_property_add_child(qdev_get_machine(), TYPE_S390_STATTRIB, obj, NULL); object_unref(obj); qdev_init_nofail(DEVICE(obj)); }
void s390_skeys_init(void) { Object *obj; if (kvm_enabled()) { obj = object_new(TYPE_KVM_S390_SKEYS); } else { obj = object_new(TYPE_QEMU_S390_SKEYS); } object_property_add_child(qdev_get_machine(), TYPE_S390_SKEYS, obj, NULL); object_unref(obj); qdev_init_nofail(DEVICE(obj)); }
void acpi_memory_hotplug_init(MemoryRegion *as, Object *owner, MemHotplugState *state) { MachineState *machine = MACHINE(qdev_get_machine()); state->dev_count = machine->ram_slots; if (!state->dev_count) { return; } state->devs = g_malloc0(sizeof(*state->devs) * state->dev_count); memory_region_init_io(&state->io, owner, &acpi_memory_hotplug_ops, state, "acpi-mem-hotplug", ACPI_MEMORY_HOTPLUG_IO_LEN); memory_region_add_subregion(as, ACPI_MEMORY_HOTPLUG_BASE, &state->io); }
/* If we don't use the built-in LPC interrupt deserializer, we need * to provide a set of qirqs for the ISA bus or things will go bad. * * Most machines using pre-Naples chips (without said deserializer) * have a CPLD that will collect the SerIRQ and shoot them as a * single level interrupt to the P8 chip. So let's setup a hook * for doing just that. */ static void pnv_lpc_isa_irq_handler_cpld(void *opaque, int n, int level) { PnvMachineState *pnv = PNV_MACHINE(qdev_get_machine()); uint32_t old_state = pnv->cpld_irqstate; PnvLpcController *lpc = PNV_LPC(opaque); if (level) { pnv->cpld_irqstate |= 1u << n; } else { pnv->cpld_irqstate &= ~(1u << n); } if (pnv->cpld_irqstate != old_state) { pnv_psi_irq_set(lpc->psi, PSIHB_IRQ_EXTERNAL, pnv->cpld_irqstate != 0); } }
void s390_flic_init(void) { DeviceState *dev; int r; dev = s390_flic_kvm_create(); if (!dev) { dev = qdev_create(NULL, TYPE_QEMU_S390_FLIC); object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC, OBJECT(dev), NULL); } r = qdev_init(dev); if (r) { error_report("flic: couldn't create qdev"); } }
static void machine_init_notify(Notifier *notifier, void *data) { Object *machine = qdev_get_machine(); ObjectClass *oc = object_get_class(machine); MachineClass *mc = MACHINE_CLASS(oc); if (mc->has_dynamic_sysbus) { /* Our machine can handle dynamic sysbus devices, we're all good */ return; } /* * Loop through all dynamically created devices and check whether there * are sysbus devices among them. If there are, error out. */ foreach_dynamic_sysbus_device(error_on_sysbus_device, NULL); }
static ram_addr_t get_current_ram_size(void) { GSList *list = NULL, *item; ram_addr_t size = ram_size; build_dimm_list(qdev_get_machine(), &list); for (item = list; item; item = g_slist_next(item)) { Object *obj = OBJECT(item->data); if (!strcmp(object_get_typename(obj), TYPE_PC_DIMM)) { size += object_property_get_int(obj, PC_DIMM_SIZE_PROP, &error_abort); } } g_slist_free(list); return size; }
uint64_t qtest_rtas_call(char *cmd, uint32_t nargs, uint64_t args, uint32_t nret, uint64_t rets) { int token; for (token = 0; token < RTAS_TOKEN_MAX - RTAS_TOKEN_BASE; token++) { if (strcmp(cmd, rtas_table[token].name) == 0) { sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine()); PowerPCCPU *cpu = POWERPC_CPU(first_cpu); rtas_table[token].fn(cpu, spapr, token + RTAS_TOKEN_BASE, nargs, args, nret, rets); return H_SUCCESS; } } return H_PARAMETER; }
static void spapr_cpu_core_realize(DeviceState *dev, Error **errp) { /* We don't use SPAPR_MACHINE() in order to exit gracefully if the user * tries to add a sPAPR CPU core to a non-pseries machine. */ SpaprMachineState *spapr = (SpaprMachineState *) object_dynamic_cast(qdev_get_machine(), TYPE_SPAPR_MACHINE); SpaprCpuCore *sc = SPAPR_CPU_CORE(OBJECT(dev)); CPUCore *cc = CPU_CORE(OBJECT(dev)); Error *local_err = NULL; int i, j; if (!spapr) { error_setg(errp, TYPE_SPAPR_CPU_CORE " needs a pseries machine"); return; } sc->threads = g_new(PowerPCCPU *, cc->nr_threads); for (i = 0; i < cc->nr_threads; i++) { sc->threads[i] = spapr_create_vcpu(sc, i, &local_err); if (local_err) { goto err; } } for (j = 0; j < cc->nr_threads; j++) { spapr_realize_vcpu(sc->threads[j], spapr, sc, &local_err); if (local_err) { goto err_unrealize; } } return; err_unrealize: while (--j >= 0) { spapr_unrealize_vcpu(sc->threads[j], sc); } err: while (--i >= 0) { spapr_delete_vcpu(sc->threads[i], sc); } g_free(sc->threads); error_propagate(errp, local_err); }
static void q35_host_realize(DeviceState *dev, Error **errp) { PCIHostState *pci = PCI_HOST_BRIDGE(dev); Q35PCIHost *s = Q35_HOST_DEVICE(dev); SysBusDevice *sbd = SYS_BUS_DEVICE(dev); sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, &pci->conf_mem); sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_ADDR, 4); sysbus_add_io(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, &pci->data_mem); sysbus_init_ioports(sbd, MCH_HOST_BRIDGE_CONFIG_DATA, 4); pci->bus = pci_bus_new(DEVICE(s), "pcie.0", s->mch.pci_address_space, s->mch.address_space_io, 0, TYPE_PCIE_BUS); PC_MACHINE(qdev_get_machine())->bus = pci->bus; qdev_set_parent_bus(DEVICE(&s->mch), BUS(pci->bus)); qdev_init_nofail(DEVICE(&s->mch)); }
static void ccw_init(MachineState *machine) { int ret; VirtualCssBus *css_bus; DeviceState *dev; s390_sclp_init(); s390_memory_init(machine->ram_size); /* get a BUS */ css_bus = virtual_css_bus_init(); s390_init_ipl_dev(machine->kernel_filename, machine->kernel_cmdline, machine->initrd_filename, "s390-ccw.img", true); s390_flic_init(); dev = qdev_create(NULL, TYPE_S390_PCI_HOST_BRIDGE); object_property_add_child(qdev_get_machine(), TYPE_S390_PCI_HOST_BRIDGE, OBJECT(dev), NULL); qdev_init_nofail(dev); /* register hypercalls */ virtio_ccw_register_hcalls(); /* init CPUs */ s390_init_cpus(machine->cpu_model); if (kvm_enabled()) { kvm_s390_enable_css_support(s390_cpu_addr2state(0)); } /* * Create virtual css and set it as default so that non mcss-e * enabled guests only see virtio devices. */ ret = css_create_css_image(VIRTUAL_CSSID, true); assert(ret == 0); /* Create VirtIO network adapters */ s390_create_virtio_net(BUS(css_bus), "virtio-net-ccw"); /* Register savevm handler for guest TOD clock */ register_savevm(NULL, "todclock", 0, 1, gtod_save, gtod_load, kvm_state); }
int s390_ipl_set_loadparm(uint8_t *loadparm) { MachineState *machine = MACHINE(qdev_get_machine()); char *lp = object_property_get_str(OBJECT(machine), "loadparm", NULL); if (lp) { int i; /* lp is an uppercase string without leading/embedded spaces */ for (i = 0; i < 8 && lp[i]; i++) { loadparm[i] = ascii2ebcdic[(uint8_t) lp[i]]; } g_free(lp); return 0; } return -1; }
void cpu_hotplug_hw_init(MemoryRegion *as, Object *owner, CPUHotplugState *state, hwaddr base_addr) { MachineState *machine = MACHINE(qdev_get_machine()); MachineClass *mc = MACHINE_GET_CLASS(machine); const CPUArchIdList *id_list; int i; assert(mc->possible_cpu_arch_ids); id_list = mc->possible_cpu_arch_ids(machine); state->dev_count = id_list->len; state->devs = g_new0(typeof(*state->devs), state->dev_count); for (i = 0; i < id_list->len; i++) { state->devs[i].cpu = CPU(id_list->cpus[i].cpu); state->devs[i].arch_id = id_list->cpus[i].arch_id; } memory_region_init_io(&state->ctrl_reg, owner, &cpu_hotplug_ops, state, "acpi-mem-hotplug", ACPI_CPU_HOTPLUG_REG_LEN); memory_region_add_subregion(as, base_addr, &state->ctrl_reg); }