Machine queue, 2018-10-25

* sysbus init/realize cleanups
   (Cédric Le Goater, Philippe Mathieu-Daudé)
 * memory-device refactoring (David Hildenbrand)
 * -smp: deprecate incorrect CPUs topology (Igor Mammedov)
 * -numa parsing cleanups (Markus Armbruster)
 * Fix hostmem-file memory leak (Zhang Yi)
 * Typo fix (Li Qiang)
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCAAGBQJb0cXCAAoJECgHk2+YTcWm9zoP/ioCxlqmjBYTJ9mrH0Ws8Cu3
 oeC/GefLgVmc9CZbalt7JXa/eWsALHzwKJkEAmokayORFKewLmKWnlSd0YIjL5+e
 jdstSQetNtjHn8wwtL2tx8stA7PS678p5vjQcgx2MP0Ia+drsqBKSm2OPYqF0+Hm
 LmmfGCoV4ijzof7NQXL/IPlyxt/FdphiUKZjaWqbiG4mFmZwRUfREcFcgAyz16tr
 m5M3bUzVaGvxVTa0gxsxwnVUpcQmjuT/x5BlhrHJs38LfEbafCDV0HDHYZurJ7Wv
 vaQMLUSpHHl+qThihEOxDsWXISNxLmjniYSa3Aq9RXjas2JbL90QZa3z/AQ9UNXc
 j3+/nkvNbFL/TkCPalOC5KdsN+6auLqmOcvdmDZSMumezAL52c+ysO5jt4lNYH+h
 FaxDptVrVOSrcpVNsb1vgSZHxTLxDz0VkDG4/zZx+I0f8IZXmuRdHsdGjGdZDkjp
 G8PEPW9QBUUHxDagc4M7wrFFrUvRkD8Aa8Z0xNSiYsU1Hb7h1Ke3pD9oFrLwSNKR
 g++hAY3kHSoHKnw4fAcu7Np+xdohhUQd4FzllcfDZwFfIsN/8jAxGc3BCodqbyoL
 aPBS3sxYkC3kWAHLpOXnD3luBn/LR8bfWdkqU0lD0cP4+msZQIcFcfhpcxY7nGg7
 GPVm2iywNQncewpb7yiN
 =5LPN
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/ehabkost/tags/machine-next-pull-request' into staging

Machine queue, 2018-10-25

* sysbus init/realize cleanups
  (Cédric Le Goater, Philippe Mathieu-Daudé)
* memory-device refactoring (David Hildenbrand)
* -smp: deprecate incorrect CPUs topology (Igor Mammedov)
* -numa parsing cleanups (Markus Armbruster)
* Fix hostmem-file memory leak (Zhang Yi)
* Typo fix (Li Qiang)

# gpg: Signature made Thu 25 Oct 2018 14:31:46 BST
# gpg:                using RSA key 2807936F984DC5A6
# gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>"
# Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF  D1AA 2807 936F 984D C5A6

* remotes/ehabkost/tags/machine-next-pull-request: (43 commits)
  net: xgmac: convert SysBus init method to a realize method
  net: stellaris_enet: add a reset method
  net: stellaris_enet: convert SysBus init method to a realize method
  net: smc91c111: convert SysBus init method to a realize method
  net: opencores_eth: convert SysBus init method to a realize method
  net: mipsnet: convert SysBus init method to a realize method
  net: milkymist_minimac2: convert SysBus init method to a realize method
  net: lance: convert SysBus init method to a realize method
  net: lan9118: convert SysBus init method to a realize method
  net: etraxfs_eth: add a reset method
  net: etraxfs_eth: convert SysBus init method to a realize method
  memory-device: trace when pre_plugging/plugging/unplugging
  memory-device: complete factoring out unplug handling
  memory-device: complete factoring out plug handling
  memory-device: complete factoring out pre_plug handling
  memory-device: add device class function set_addr()
  memory-device: drop get_region_size()
  memory-device: factor out get_memory_region() from pc-dimm
  memory-device: add and use memory_device_get_region_size()
  memory-device: document MemoryDeviceClass
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2018-10-25 20:17:12 +01:00
commit 6e6ffc9ffa
38 changed files with 344 additions and 286 deletions

View File

@ -145,20 +145,26 @@ static void file_memory_backend_set_pmem(Object *o, bool value, Error **errp)
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
if (host_memory_backend_mr_inited(backend)) {
char *path = object_get_canonical_path_component(o);
error_setg(errp, "cannot change property 'pmem' of %s '%s'",
object_get_typename(o),
object_get_canonical_path_component(o));
path);
g_free(path);
return;
}
#ifndef CONFIG_LIBPMEM
if (value) {
Error *local_err = NULL;
char *path = object_get_canonical_path_component(o);
error_setg(&local_err,
"Lack of libpmem support while setting the 'pmem=on'"
" of %s '%s'. We can't ensure data persistence.",
object_get_typename(o),
object_get_canonical_path_component(o));
path);
g_free(path);
error_propagate(errp, local_err);
return;
}

View File

@ -51,7 +51,8 @@ CONFIG_PCI_Q35=y
CONFIG_APIC=y
CONFIG_IOAPIC=y
CONFIG_PVPANIC=y
CONFIG_MEM_HOTPLUG=y
CONFIG_MEM_DEVICE=y
CONFIG_DIMM=y
CONFIG_NVDIMM=y
CONFIG_ACPI_NVDIMM=y
CONFIG_PCIE_PORT=y

View File

@ -16,4 +16,5 @@ CONFIG_VIRTIO_VGA=y
CONFIG_XICS=$(CONFIG_PSERIES)
CONFIG_XICS_SPAPR=$(CONFIG_PSERIES)
CONFIG_XICS_KVM=$(call land,$(CONFIG_PSERIES),$(CONFIG_KVM))
CONFIG_MEM_HOTPLUG=y
CONFIG_MEM_DEVICE=y
CONFIG_DIMM=y

View File

@ -16,5 +16,4 @@ CONFIG_SIMBA=y
CONFIG_SUNHME=y
CONFIG_MC146818RTC=y
CONFIG_ISA_TESTDEV=y
CONFIG_EMPTY_SLOT=y
CONFIG_SUN4V_RTC=y

View File

@ -34,7 +34,7 @@ devices-dirs-$(CONFIG_SOFTMMU) += vfio/
devices-dirs-$(CONFIG_SOFTMMU) += virtio/
devices-dirs-$(CONFIG_SOFTMMU) += watchdog/
devices-dirs-$(CONFIG_SOFTMMU) += xen/
devices-dirs-$(CONFIG_MEM_HOTPLUG) += mem/
devices-dirs-$(CONFIG_MEM_DEVICE) += mem/
devices-dirs-$(CONFIG_SOFTMMU) += smbios/
devices-dirs-y += core/
common-obj-y += $(devices-dirs-y)

View File

@ -932,23 +932,10 @@ PCIBus *typhoon_init(ram_addr_t ram_size, ISABus **isa_bus,
return b;
}
static int typhoon_pcihost_init(SysBusDevice *dev)
{
return 0;
}
static void typhoon_pcihost_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = typhoon_pcihost_init;
}
static const TypeInfo typhoon_pcihost_info = {
.name = TYPE_TYPHOON_PCI_HOST_BRIDGE,
.parent = TYPE_PCI_HOST_BRIDGE,
.instance_size = sizeof(TyphoonState),
.class_init = typhoon_pcihost_class_init,
};
static void typhoon_iommu_memory_region_class_init(ObjectClass *klass,

View File

@ -636,7 +636,7 @@ static void machine_class_init(ObjectClass *oc, void *data)
machine_get_memory_encryption, machine_set_memory_encryption,
&error_abort);
object_class_property_set_description(oc, "memory-encryption",
"Set memory encyption object to use", &error_abort);
"Set memory encryption object to use", &error_abort);
}
static void machine_class_base_init(ObjectClass *oc, void *data)

View File

@ -488,17 +488,10 @@ PCIBus *dino_init(MemoryRegion *addr_space,
return b;
}
static int dino_pcihost_init(SysBusDevice *dev)
{
return 0;
}
static void dino_pcihost_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = dino_pcihost_init;
dc->vmsd = &vmstate_dino;
}

View File

@ -1704,7 +1704,7 @@ static void pc_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
pc_dimm_pre_plug(dev, MACHINE(hotplug_dev),
pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev),
pcmc->enforce_aligned_dimm ? NULL : &legacy_align, errp);
}
@ -1716,7 +1716,7 @@ static void pc_memory_plug(HotplugHandler *hotplug_dev,
PCMachineState *pcms = PC_MACHINE(hotplug_dev);
bool is_nvdimm = object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
pc_dimm_plug(dev, MACHINE(pcms), &local_err);
pc_dimm_plug(PC_DIMM(dev), MACHINE(pcms), &local_err);
if (local_err) {
goto out;
}
@ -1776,7 +1776,7 @@ static void pc_memory_unplug(HotplugHandler *hotplug_dev,
goto out;
}
pc_dimm_unplug(dev, MACHINE(pcms));
pc_dimm_unplug(PC_DIMM(dev), MACHINE(pcms));
object_unparent(OBJECT(dev));
out:

View File

@ -1,3 +1,3 @@
common-obj-$(CONFIG_MEM_HOTPLUG) += pc-dimm.o
common-obj-$(CONFIG_MEM_HOTPLUG) += memory-device.o
common-obj-$(CONFIG_DIMM) += pc-dimm.o
common-obj-$(CONFIG_MEM_DEVICE) += memory-device.o
common-obj-$(CONFIG_NVDIMM) += nvdimm.o

View File

@ -17,6 +17,7 @@
#include "qemu/range.h"
#include "hw/virtio/vhost.h"
#include "sysemu/kvm.h"
#include "trace.h"
static gint memory_device_addr_sort(gconstpointer a, gconstpointer b)
{
@ -57,10 +58,9 @@ static int memory_device_used_region_size(Object *obj, void *opaque)
if (object_dynamic_cast(obj, TYPE_MEMORY_DEVICE)) {
const DeviceState *dev = DEVICE(obj);
const MemoryDeviceState *md = MEMORY_DEVICE(obj);
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj);
if (dev->realized) {
*size += mdc->get_region_size(md);
*size += memory_device_get_region_size(md, &error_abort);
}
}
@ -87,16 +87,17 @@ static void memory_device_check_addable(MachineState *ms, uint64_t size,
memory_device_used_region_size(OBJECT(ms), &used_region_size);
if (used_region_size + size > ms->maxram_size - ms->ram_size) {
error_setg(errp, "not enough space, currently 0x%" PRIx64
" in use of total hot pluggable 0x" RAM_ADDR_FMT,
" in use of total space for memory devices 0x" RAM_ADDR_FMT,
used_region_size, ms->maxram_size - ms->ram_size);
return;
}
}
uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
uint64_t align, uint64_t size,
Error **errp)
static uint64_t memory_device_get_free_addr(MachineState *ms,
const uint64_t *hint,
uint64_t align, uint64_t size,
Error **errp)
{
uint64_t address_space_start, address_space_end;
GSList *list = NULL, *item;
@ -120,7 +121,7 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
/* address_space_start indicates the maximum alignment we expect */
if (QEMU_ALIGN_UP(address_space_start, align) != address_space_start) {
error_setg(errp, "the alignment (0%" PRIx64 ") is not supported",
error_setg(errp, "the alignment (0x%" PRIx64 ") is not supported",
align);
return 0;
}
@ -145,11 +146,12 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
if (hint) {
new_addr = *hint;
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);
error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64
"] before 0x%" PRIx64, new_addr, size,
address_space_start);
return 0;
} else if ((new_addr + size) > address_space_end) {
error_setg(errp, "can't add memory [0x%" PRIx64 ":0x%" PRIx64
error_setg(errp, "can't add memory device [0x%" PRIx64 ":0x%" PRIx64
"] beyond 0x%" PRIx64, new_addr, size,
address_space_end);
return 0;
@ -166,15 +168,13 @@ uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
uint64_t md_size, md_addr;
md_addr = mdc->get_addr(md);
md_size = mdc->get_region_size(md);
if (*errp) {
goto out;
}
md_size = memory_device_get_region_size(md, &error_abort);
if (ranges_overlap(md_addr, md_size, new_addr, size)) {
if (hint) {
const DeviceState *d = DEVICE(md);
error_setg(errp, "address range conflicts with '%s'", d->id);
error_setg(errp, "address range conflicts with memory device"
" id='%s'", d->id ? d->id : "(unnamed)");
goto out;
}
new_addr = QEMU_ALIGN_UP(md_addr + md_size, align);
@ -232,7 +232,7 @@ static int memory_device_plugged_size(Object *obj, void *opaque)
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(obj);
if (dev->realized) {
*size += mdc->get_plugged_size(md);
*size += mdc->get_plugged_size(md, &error_abort);
}
}
@ -249,22 +249,83 @@ uint64_t get_plugged_memory_size(void)
return size;
}
void memory_device_plug_region(MachineState *ms, MemoryRegion *mr,
uint64_t addr)
void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
const uint64_t *legacy_align, Error **errp)
{
/* we expect a previous call to memory_device_get_free_addr() */
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
Error *local_err = NULL;
uint64_t addr, align;
MemoryRegion *mr;
mr = mdc->get_memory_region(md, &local_err);
if (local_err) {
goto out;
}
align = legacy_align ? *legacy_align : memory_region_get_alignment(mr);
addr = mdc->get_addr(md);
addr = memory_device_get_free_addr(ms, !addr ? NULL : &addr, align,
memory_region_size(mr), &local_err);
if (local_err) {
goto out;
}
mdc->set_addr(md, addr, &local_err);
if (!local_err) {
trace_memory_device_pre_plug(DEVICE(md)->id ? DEVICE(md)->id : "",
addr);
}
out:
error_propagate(errp, local_err);
}
void memory_device_plug(MemoryDeviceState *md, MachineState *ms)
{
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
const uint64_t addr = mdc->get_addr(md);
MemoryRegion *mr;
/*
* We expect that a previous call to memory_device_pre_plug() succeeded, so
* it can't fail at this point.
*/
mr = mdc->get_memory_region(md, &error_abort);
g_assert(ms->device_memory);
memory_region_add_subregion(&ms->device_memory->mr,
addr - ms->device_memory->base, mr);
trace_memory_device_plug(DEVICE(md)->id ? DEVICE(md)->id : "", addr);
}
void memory_device_unplug_region(MachineState *ms, MemoryRegion *mr)
void memory_device_unplug(MemoryDeviceState *md, MachineState *ms)
{
/* we expect a previous call to memory_device_get_free_addr() */
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
MemoryRegion *mr;
/*
* We expect that a previous call to memory_device_pre_plug() succeeded, so
* it can't fail at this point.
*/
mr = mdc->get_memory_region(md, &error_abort);
g_assert(ms->device_memory);
memory_region_del_subregion(&ms->device_memory->mr, mr);
trace_memory_device_unplug(DEVICE(md)->id ? DEVICE(md)->id : "",
mdc->get_addr(md));
}
uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
Error **errp)
{
const MemoryDeviceClass *mdc = MEMORY_DEVICE_GET_CLASS(md);
MemoryRegion *mr;
/* dropping const here is fine as we don't touch the memory region */
mr = mdc->get_memory_region((MemoryDeviceState *)md, errp);
if (!mr) {
return 0;
}
return memory_region_size(mr);
}
static const TypeInfo memory_device_info = {

View File

@ -27,6 +27,7 @@
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "hw/mem/nvdimm.h"
#include "hw/mem/memory-device.h"
static void nvdimm_get_label_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
@ -118,9 +119,10 @@ static void nvdimm_prepare_memory_region(NVDIMMDevice *nvdimm, Error **errp)
nvdimm->nvdimm_mr->align = align;
}
static MemoryRegion *nvdimm_get_memory_region(PCDIMMDevice *dimm, Error **errp)
static MemoryRegion *nvdimm_md_get_memory_region(MemoryDeviceState *md,
Error **errp)
{
NVDIMMDevice *nvdimm = NVDIMM(dimm);
NVDIMMDevice *nvdimm = NVDIMM(md);
Error *local_err = NULL;
if (!nvdimm->nvdimm_mr) {
@ -190,11 +192,12 @@ static Property nvdimm_properties[] = {
static void nvdimm_class_init(ObjectClass *oc, void *data)
{
PCDIMMDeviceClass *ddc = PC_DIMM_CLASS(oc);
MemoryDeviceClass *mdc = MEMORY_DEVICE_CLASS(oc);
NVDIMMClass *nvc = NVDIMM_CLASS(oc);
DeviceClass *dc = DEVICE_CLASS(oc);
ddc->realize = nvdimm_realize;
ddc->get_memory_region = nvdimm_get_memory_region;
mdc->get_memory_region = nvdimm_md_get_memory_region;
dc->props = nvdimm_properties;
nvc->read_label_data = nvdimm_read_label_data;

View File

@ -29,72 +29,47 @@
static int pc_dimm_get_free_slot(const int *hint, int max_slots, Error **errp);
void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine,
void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
const uint64_t *legacy_align, Error **errp)
{
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
Error *local_err = NULL;
MemoryRegion *mr;
uint64_t addr, align;
int slot;
slot = object_property_get_int(OBJECT(dev), PC_DIMM_SLOT_PROP,
slot = object_property_get_int(OBJECT(dimm), PC_DIMM_SLOT_PROP,
&error_abort);
slot = pc_dimm_get_free_slot(slot == PC_DIMM_UNASSIGNED_SLOT ? NULL : &slot,
machine->ram_slots, &local_err);
if (local_err) {
goto out;
}
object_property_set_int(OBJECT(dev), slot, PC_DIMM_SLOT_PROP, &error_abort);
object_property_set_int(OBJECT(dimm), slot, PC_DIMM_SLOT_PROP,
&error_abort);
trace_mhp_pc_dimm_assigned_slot(slot);
mr = ddc->get_memory_region(dimm, &local_err);
if (local_err) {
goto out;
}
align = legacy_align ? *legacy_align : memory_region_get_alignment(mr);
addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
&error_abort);
addr = memory_device_get_free_addr(machine, !addr ? NULL : &addr, align,
memory_region_size(mr), &local_err);
if (local_err) {
goto out;
}
trace_mhp_pc_dimm_assigned_address(addr);
object_property_set_uint(OBJECT(dev), addr, PC_DIMM_ADDR_PROP,
&error_abort);
memory_device_pre_plug(MEMORY_DEVICE(dimm), machine, legacy_align,
&local_err);
out:
error_propagate(errp, local_err);
}
void pc_dimm_plug(DeviceState *dev, MachineState *machine, Error **errp)
void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp)
{
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
&error_abort);
MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
uint64_t addr;
addr = object_property_get_uint(OBJECT(dev), PC_DIMM_ADDR_PROP,
&error_abort);
memory_device_plug_region(machine, mr, addr);
vmstate_register_ram(vmstate_mr, dev);
memory_device_plug(MEMORY_DEVICE(dimm), machine);
vmstate_register_ram(vmstate_mr, DEVICE(dimm));
}
void pc_dimm_unplug(DeviceState *dev, MachineState *machine)
void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine)
{
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *vmstate_mr = ddc->get_vmstate_memory_region(dimm,
&error_abort);
MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
memory_device_unplug_region(machine, mr);
vmstate_unregister_ram(vmstate_mr, dev);
memory_device_unplug(MEMORY_DEVICE(dimm), machine);
vmstate_unregister_ram(vmstate_mr, DEVICE(dimm));
}
static int pc_dimm_slot2bitmap(Object *obj, void *opaque)
@ -163,16 +138,14 @@ static Property pc_dimm_properties[] = {
static void pc_dimm_get_size(Object *obj, Visitor *v, const char *name,
void *opaque, Error **errp)
{
Error *local_err = NULL;
uint64_t value;
MemoryRegion *mr;
PCDIMMDevice *dimm = PC_DIMM(obj);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(obj);
mr = ddc->get_memory_region(dimm, errp);
if (!mr) {
value = memory_device_get_region_size(MEMORY_DEVICE(obj), &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
value = memory_region_size(mr);
visit_type_uint64(v, name, &value, errp);
}
@ -236,19 +209,16 @@ static uint64_t pc_dimm_md_get_addr(const MemoryDeviceState *md)
return dimm->addr;
}
static uint64_t pc_dimm_md_get_region_size(const MemoryDeviceState *md)
static void pc_dimm_md_set_addr(MemoryDeviceState *md, uint64_t addr,
Error **errp)
{
/* dropping const here is fine as we don't touch the memory region */
PCDIMMDevice *dimm = PC_DIMM(md);
const PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(md);
MemoryRegion *mr;
object_property_set_uint(OBJECT(md), addr, PC_DIMM_ADDR_PROP, errp);
}
mr = ddc->get_memory_region(dimm, &error_abort);
if (!mr) {
return 0;
}
return memory_region_size(mr);
static MemoryRegion *pc_dimm_md_get_memory_region(MemoryDeviceState *md,
Error **errp)
{
return pc_dimm_get_memory_region(PC_DIMM(md), errp);
}
static void pc_dimm_md_fill_device_info(const MemoryDeviceState *md,
@ -292,13 +262,13 @@ static void pc_dimm_class_init(ObjectClass *oc, void *data)
dc->props = pc_dimm_properties;
dc->desc = "DIMM memory module";
ddc->get_memory_region = pc_dimm_get_memory_region;
ddc->get_vmstate_memory_region = pc_dimm_get_memory_region;
mdc->get_addr = pc_dimm_md_get_addr;
mdc->set_addr = pc_dimm_md_set_addr;
/* for a dimm plugged_size == region_size */
mdc->get_plugged_size = pc_dimm_md_get_region_size;
mdc->get_region_size = pc_dimm_md_get_region_size;
mdc->get_plugged_size = memory_device_get_region_size;
mdc->get_memory_region = pc_dimm_md_get_memory_region;
mdc->fill_device_info = pc_dimm_md_fill_device_info;
}

View File

@ -2,4 +2,7 @@
# hw/mem/pc-dimm.c
mhp_pc_dimm_assigned_slot(int slot) "%d"
mhp_pc_dimm_assigned_address(uint64_t addr) "0x%"PRIx64
# hw/mem/memory-device.c
memory_device_pre_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
memory_device_plug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64
memory_device_unplug(const char *id, uint64_t addr) "id=%s addr=0x%"PRIx64

View File

@ -992,9 +992,9 @@ static void gt64120_pci_set_irq(void *opaque, int irq_num, int level)
}
static void gt64120_reset(void *opaque)
static void gt64120_reset(DeviceState *dev)
{
GT64120State *s = opaque;
GT64120State *s = GT64120_PCI_HOST_BRIDGE(dev);
/* FIXME: Malta specific hw assumptions ahead */
@ -1184,16 +1184,6 @@ PCIBus *gt64120_register(qemu_irq *pic)
return phb->bus;
}
static int gt64120_init(SysBusDevice *dev)
{
GT64120State *s;
s = GT64120_PCI_HOST_BRIDGE(dev);
qemu_register_reset(gt64120_reset, s);
return 0;
}
static void gt64120_pci_realize(PCIDevice *d, Error **errp)
{
/* FIXME: Malta specific hw assumptions ahead */
@ -1241,9 +1231,9 @@ static const TypeInfo gt64120_pci_info = {
static void gt64120_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
sdc->init = gt64120_init;
set_bit(DEVICE_CATEGORY_BRIDGE, dc->categories);
dc->reset = gt64120_reset;
dc->vmsd = &vmstate_gt64120;
}

View File

@ -1422,23 +1422,10 @@ void mips_malta_init(MachineState *machine)
pci_vga_init(pci_bus);
}
static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
{
return 0;
}
static void mips_malta_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = mips_malta_sysbus_device_init;
}
static const TypeInfo mips_malta_device = {
.name = TYPE_MIPS_MALTA,
.parent = TYPE_SYS_BUS_DEVICE,
.instance_size = sizeof(MaltaState),
.class_init = mips_malta_class_init,
};
static void mips_malta_machine_init(MachineClass *mc)

View File

@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/sysbus.h"
#include "net/net.h"
#include "hw/cris/etraxfs.h"
@ -126,7 +127,7 @@ tdk_write(struct qemu_phy *phy, unsigned int req, unsigned int data)
}
static void
tdk_init(struct qemu_phy *phy)
tdk_reset(struct qemu_phy *phy)
{
phy->regs[0] = 0x3100;
/* PHY Id. */
@ -135,9 +136,6 @@ tdk_init(struct qemu_phy *phy)
/* Autonegotiation advertisement reg. */
phy->regs[4] = 0x01E1;
phy->link = 1;
phy->read = tdk_read;
phy->write = tdk_write;
}
struct qemu_mdio
@ -584,14 +582,35 @@ static NetClientInfo net_etraxfs_info = {
.link_status_changed = eth_set_link,
};
static int fs_eth_init(SysBusDevice *sbd)
static void etraxfs_eth_reset(DeviceState *dev)
{
DeviceState *dev = DEVICE(sbd);
ETRAXFSEthState *s = ETRAX_FS_ETH(dev);
memset(s->regs, 0, sizeof(s->regs));
memset(s->macaddr, 0, sizeof(s->macaddr));
s->duplex_mismatch = 0;
s->mdio_bus.mdc = 0;
s->mdio_bus.mdio = 0;
s->mdio_bus.state = 0;
s->mdio_bus.drive = 0;
s->mdio_bus.cnt = 0;
s->mdio_bus.addr = 0;
s->mdio_bus.opc = 0;
s->mdio_bus.req = 0;
s->mdio_bus.data = 0;
tdk_reset(&s->phy);
}
static void etraxfs_eth_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
ETRAXFSEthState *s = ETRAX_FS_ETH(dev);
if (!s->dma_out || !s->dma_in) {
error_report("Unconnected ETRAX-FS Ethernet MAC");
return -1;
error_setg(errp, "Unconnected ETRAX-FS Ethernet MAC");
return;
}
s->dma_out->client.push = eth_tx_push;
@ -608,10 +627,9 @@ static int fs_eth_init(SysBusDevice *sbd)
object_get_typename(OBJECT(s)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
tdk_init(&s->phy);
s->phy.read = tdk_read;
s->phy.write = tdk_write;
mdio_attach(&s->mdio_bus, &s->phy, s->phyaddr);
return 0;
}
static Property etraxfs_eth_properties[] = {
@ -625,9 +643,9 @@ static Property etraxfs_eth_properties[] = {
static void etraxfs_eth_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = fs_eth_init;
dc->realize = etraxfs_eth_realize;
dc->reset = etraxfs_eth_reset;
dc->props = etraxfs_eth_properties;
/* Reason: pointer properties "dma_out", "dma_in" */
dc->user_creatable = false;

View File

@ -1320,9 +1320,9 @@ static NetClientInfo net_lan9118_info = {
.link_status_changed = lan9118_set_link,
};
static int lan9118_init1(SysBusDevice *sbd)
static void lan9118_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
lan9118_state *s = LAN9118(dev);
QEMUBH *bh;
int i;
@ -1349,8 +1349,6 @@ static int lan9118_init1(SysBusDevice *sbd)
s->timer = ptimer_init(bh, PTIMER_POLICY_DEFAULT);
ptimer_set_freq(s->timer, 10000);
ptimer_set_limit(s->timer, 0xffff, 1);
return 0;
}
static Property lan9118_properties[] = {
@ -1362,12 +1360,11 @@ static Property lan9118_properties[] = {
static void lan9118_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = lan9118_init1;
dc->reset = lan9118_reset;
dc->props = lan9118_properties;
dc->vmsd = &vmstate_lan9118;
dc->realize = lan9118_realize;
}
static const TypeInfo lan9118_info = {

View File

@ -97,9 +97,9 @@ static const VMStateDescription vmstate_lance = {
}
};
static int lance_init(SysBusDevice *sbd)
static void lance_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
SysBusPCNetState *d = SYSBUS_PCNET(dev);
PCNetState *s = &d->state;
@ -115,7 +115,6 @@ static int lance_init(SysBusDevice *sbd)
s->phys_mem_read = ledma_memory_read;
s->phys_mem_write = ledma_memory_write;
pcnet_common_init(dev, s, &net_lance_info);
return 0;
}
static void lance_reset(DeviceState *dev)
@ -144,9 +143,8 @@ static Property lance_properties[] = {
static void lance_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = lance_init;
dc->realize = lance_realize;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->fw_name = "ethernet";
dc->reset = lance_reset;

View File

@ -452,9 +452,9 @@ static NetClientInfo net_milkymist_minimac2_info = {
.receive = minimac2_rx,
};
static int milkymist_minimac2_init(SysBusDevice *sbd)
static void milkymist_minimac2_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
MilkymistMinimac2State *s = MILKYMIST_MINIMAC2(dev);
size_t buffers_size = TARGET_PAGE_ALIGN(3 * MINIMAC2_BUFFER_SIZE);
@ -479,8 +479,6 @@ static int milkymist_minimac2_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_milkymist_minimac2_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
return 0;
}
static const VMStateDescription vmstate_milkymist_minimac2_mdio = {
@ -521,9 +519,8 @@ static Property milkymist_minimac2_properties[] = {
static void milkymist_minimac2_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = milkymist_minimac2_init;
dc->realize = milkymist_minimac2_realize;
dc->reset = milkymist_minimac2_reset;
dc->vmsd = &vmstate_milkymist_minimac2;
dc->props = milkymist_minimac2_properties;

View File

@ -236,9 +236,9 @@ static const MemoryRegionOps mipsnet_ioport_ops = {
.impl.max_access_size = 4,
};
static int mipsnet_sysbus_init(SysBusDevice *sbd)
static void mipsnet_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
MIPSnetState *s = MIPS_NET(dev);
memory_region_init_io(&s->io, OBJECT(dev), &mipsnet_ioport_ops, s,
@ -249,8 +249,6 @@ static int mipsnet_sysbus_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_mipsnet_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
return 0;
}
static void mipsnet_sysbus_reset(DeviceState *dev)
@ -267,9 +265,8 @@ static Property mipsnet_properties[] = {
static void mipsnet_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = mipsnet_sysbus_init;
dc->realize = mipsnet_realize;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "MIPS Simulator network device";
dc->reset = mipsnet_sysbus_reset;

View File

@ -715,9 +715,9 @@ static const MemoryRegionOps open_eth_desc_ops = {
.write = open_eth_desc_write,
};
static int sysbus_open_eth_init(SysBusDevice *sbd)
static void sysbus_open_eth_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
OpenEthState *s = OPEN_ETH(dev);
memory_region_init_io(&s->reg_io, OBJECT(dev), &open_eth_reg_ops, s,
@ -732,7 +732,6 @@ static int sysbus_open_eth_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_open_eth_info, &s->conf,
object_get_typename(OBJECT(s)), dev->id, s);
return 0;
}
static void qdev_open_eth_reset(DeviceState *dev)
@ -750,9 +749,8 @@ static Property open_eth_properties[] = {
static void open_eth_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = sysbus_open_eth_init;
dc->realize = sysbus_open_eth_realize;
set_bit(DEVICE_CATEGORY_NETWORK, dc->categories);
dc->desc = "Opencores 10/100 Mbit Ethernet";
dc->reset = qdev_open_eth_reset;

View File

@ -766,9 +766,9 @@ static NetClientInfo net_smc91c111_info = {
.receive = smc91c111_receive,
};
static int smc91c111_init1(SysBusDevice *sbd)
static void smc91c111_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
smc91c111_state *s = SMC91C111(dev);
memory_region_init_io(&s->mmio, OBJECT(s), &smc91c111_mem_ops, s,
@ -780,7 +780,6 @@ static int smc91c111_init1(SysBusDevice *sbd)
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
/* ??? Save/restore. */
return 0;
}
static Property smc91c111_properties[] = {
@ -791,9 +790,8 @@ static Property smc91c111_properties[] = {
static void smc91c111_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = smc91c111_init1;
dc->realize = smc91c111_realize;
dc->reset = smc91c111_reset;
dc->vmsd = &vmstate_smc91c111;
dc->props = smc91c111_properties;

View File

@ -457,8 +457,10 @@ static const MemoryRegionOps stellaris_enet_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
static void stellaris_enet_reset(stellaris_enet_state *s)
static void stellaris_enet_reset(DeviceState *dev)
{
stellaris_enet_state *s = STELLARIS_ENET(dev);
s->mdv = 0x80;
s->rctl = SE_RCTL_BADCRC;
s->im = SE_INT_PHY | SE_INT_MD | SE_INT_RXER | SE_INT_FOV | SE_INT_TXEMP
@ -473,9 +475,9 @@ static NetClientInfo net_stellaris_enet_info = {
.receive = stellaris_enet_receive,
};
static int stellaris_enet_init(SysBusDevice *sbd)
static void stellaris_enet_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
stellaris_enet_state *s = STELLARIS_ENET(dev);
memory_region_init_io(&s->mmio, OBJECT(s), &stellaris_enet_ops, s,
@ -487,9 +489,6 @@ static int stellaris_enet_init(SysBusDevice *sbd)
s->nic = qemu_new_nic(&net_stellaris_enet_info, &s->conf,
object_get_typename(OBJECT(dev)), dev->id, s);
qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a);
stellaris_enet_reset(s);
return 0;
}
static Property stellaris_enet_properties[] = {
@ -500,9 +499,9 @@ static Property stellaris_enet_properties[] = {
static void stellaris_enet_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = stellaris_enet_init;
dc->realize = stellaris_enet_realize;
dc->reset = stellaris_enet_reset;
dc->props = stellaris_enet_properties;
dc->vmsd = &vmstate_stellaris_enet;
}

View File

@ -374,9 +374,9 @@ static NetClientInfo net_xgmac_enet_info = {
.receive = eth_rx,
};
static int xgmac_enet_init(SysBusDevice *sbd)
static void xgmac_enet_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
XgmacState *s = XGMAC(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &enet_mem_ops, s,
@ -397,8 +397,6 @@ static int xgmac_enet_init(SysBusDevice *sbd)
(s->conf.macaddr.a[2] << 16) |
(s->conf.macaddr.a[1] << 8) |
s->conf.macaddr.a[0];
return 0;
}
static Property xgmac_properties[] = {
@ -408,10 +406,9 @@ static Property xgmac_properties[] = {
static void xgmac_enet_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *sbc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
sbc->init = xgmac_enet_init;
dc->realize = xgmac_enet_realize;
dc->vmsd = &vmstate_xgmac;
dc->props = xgmac_properties;
}

View File

@ -595,7 +595,7 @@ static const VMStateDescription vmstate_bonito = {
}
};
static int bonito_pcihost_initfn(SysBusDevice *dev)
static void bonito_pcihost_realize(DeviceState *dev, Error **errp)
{
PCIHostState *phb = PCI_HOST_BRIDGE(dev);
@ -603,8 +603,6 @@ static int bonito_pcihost_initfn(SysBusDevice *dev)
pci_bonito_set_irq, pci_bonito_map_irq,
dev, get_system_memory(), get_system_io(),
0x28, 32, TYPE_PCI_BUS);
return 0;
}
static void bonito_realize(PCIDevice *dev, Error **errp)
@ -684,7 +682,6 @@ PCIBus *bonito_init(qemu_irq *pic)
pcihost->pic = pic;
qdev_init_nofail(dev);
/* set the pcihost pointer before bonito_initfn is called */
d = pci_create(phb->bus, PCI_DEVFN(0, 0), TYPE_PCI_BONITO);
s = PCI_BONITO(d);
s->pcihost = pcihost;
@ -726,9 +723,9 @@ static const TypeInfo bonito_info = {
static void bonito_pcihost_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = bonito_pcihost_initfn;
dc->realize = bonito_pcihost_realize;
}
static const TypeInfo bonito_pcihost_info = {

View File

@ -3128,14 +3128,12 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
Error *local_err = NULL;
sPAPRMachineState *ms = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
uint64_t size, addr;
uint32_t node;
size = memory_region_size(mr);
size = memory_device_get_region_size(MEMORY_DEVICE(dev), &error_abort);
pc_dimm_plug(dev, MACHINE(ms), &local_err);
pc_dimm_plug(dimm, MACHINE(ms), &local_err);
if (local_err) {
goto out;
}
@ -3158,7 +3156,7 @@ static void spapr_memory_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
out_unplug:
pc_dimm_unplug(dev, MACHINE(ms));
pc_dimm_unplug(dimm, MACHINE(ms));
out:
error_propagate(errp, local_err);
}
@ -3169,9 +3167,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
const sPAPRMachineClass *smc = SPAPR_MACHINE_GET_CLASS(hotplug_dev);
sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
Error *local_err = NULL;
MemoryRegion *mr;
uint64_t size;
Object *memdev;
hwaddr pagesize;
@ -3181,11 +3177,11 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
mr = ddc->get_memory_region(dimm, errp);
if (!mr) {
size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &local_err);
if (local_err) {
error_propagate(errp, local_err);
return;
}
size = memory_region_size(mr);
if (size % SPAPR_MEMORY_BLOCK_SIZE) {
error_setg(errp, "Hotplugged memory size must be a multiple of "
@ -3202,7 +3198,7 @@ static void spapr_memory_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
return;
}
pc_dimm_pre_plug(dev, MACHINE(hotplug_dev), NULL, errp);
pc_dimm_pre_plug(dimm, MACHINE(hotplug_dev), NULL, errp);
}
struct sPAPRDIMMState {
@ -3257,9 +3253,8 @@ static sPAPRDIMMState *spapr_recover_pending_dimm_state(sPAPRMachineState *ms,
PCDIMMDevice *dimm)
{
sPAPRDRConnector *drc;
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
uint64_t size = memory_region_size(mr);
uint64_t size = memory_device_get_region_size(MEMORY_DEVICE(dimm),
&error_abort);
uint32_t nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
uint32_t avail_lmbs = 0;
uint64_t addr_start, addr;
@ -3314,7 +3309,7 @@ static void spapr_memory_unplug(HotplugHandler *hotplug_dev, DeviceState *dev)
sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
sPAPRDIMMState *ds = spapr_pending_dimm_unplugs_find(spapr, PC_DIMM(dev));
pc_dimm_unplug(dev, MACHINE(hotplug_dev));
pc_dimm_unplug(PC_DIMM(dev), MACHINE(hotplug_dev));
object_unparent(OBJECT(dev));
spapr_pending_dimm_unplugs_remove(spapr, ds);
}
@ -3325,14 +3320,12 @@ static void spapr_memory_unplug_request(HotplugHandler *hotplug_dev,
sPAPRMachineState *spapr = SPAPR_MACHINE(hotplug_dev);
Error *local_err = NULL;
PCDIMMDevice *dimm = PC_DIMM(dev);
PCDIMMDeviceClass *ddc = PC_DIMM_GET_CLASS(dimm);
MemoryRegion *mr = ddc->get_memory_region(dimm, &error_abort);
uint32_t nr_lmbs;
uint64_t size, addr_start, addr;
int i;
sPAPRDRConnector *drc;
size = memory_region_size(mr);
size = memory_device_get_region_size(MEMORY_DEVICE(dimm), &error_abort);
nr_lmbs = size / SPAPR_MEMORY_BLOCK_SIZE;
addr_start = object_property_get_uint(OBJECT(dimm), PC_DIMM_ADDR_PROP,

View File

@ -120,16 +120,15 @@ static void sh_pci_set_irq(void *opaque, int irq_num, int level)
qemu_set_irq(pic[irq_num], level);
}
static int sh_pci_device_init(SysBusDevice *dev)
static void sh_pci_device_realize(DeviceState *dev, Error **errp)
{
PCIHostState *phb;
SHPCIState *s;
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
SHPCIState *s = SH_PCI_HOST_BRIDGE(dev);
PCIHostState *phb = PCI_HOST_BRIDGE(s);
int i;
s = SH_PCI_HOST_BRIDGE(dev);
phb = PCI_HOST_BRIDGE(s);
for (i = 0; i < 4; i++) {
sysbus_init_irq(dev, &s->irq[i]);
sysbus_init_irq(sbd, &s->irq[i]);
}
phb->bus = pci_register_root_bus(DEVICE(dev), "pci",
sh_pci_set_irq, sh_pci_map_irq,
@ -143,13 +142,12 @@ static int sh_pci_device_init(SysBusDevice *dev)
&s->memconfig_p4, 0, 0x224);
memory_region_init_alias(&s->isa, OBJECT(s), "sh_pci.isa",
get_system_io(), 0, 0x40000);
sysbus_init_mmio(dev, &s->memconfig_p4);
sysbus_init_mmio(dev, &s->memconfig_a7);
sysbus_init_mmio(sbd, &s->memconfig_p4);
sysbus_init_mmio(sbd, &s->memconfig_a7);
s->iobr = 0xfe240000;
memory_region_add_subregion(get_system_memory(), s->iobr, &s->isa);
s->dev = pci_create_simple(phb->bus, PCI_DEVFN(0, 0), "sh_pci_host");
return 0;
}
static void sh_pci_host_realize(PCIDevice *d, Error **errp)
@ -187,9 +185,9 @@ static const TypeInfo sh_pci_host_info = {
static void sh_pci_device_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *sdc = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
sdc->init = sh_pci_device_init;
dc->realize = sh_pci_device_realize;
}
static const TypeInfo sh_pci_device_info = {

View File

@ -29,7 +29,7 @@
#include "hw/hw.h"
#include "hw/boards.h"
#include "hw/char/serial.h"
#include "hw/empty_slot.h"
#include "hw/misc/unimp.h"
#include "hw/loader.h"
#include "hw/sparc/sparc64.h"
#include "hw/timer/sun4v-rtc.h"
@ -161,7 +161,7 @@ static void niagara_init(MachineState *machine)
serial_mm_init(sysmem, NIAGARA_UART_BASE, 0, NULL, 115200,
serial_hd(0), DEVICE_BIG_ENDIAN);
}
empty_slot_init(NIAGARA_IOBBASE, NIAGARA_IOBSIZE);
create_unimplemented_device("sun4v-iob", NIAGARA_IOBBASE, NIAGARA_IOBSIZE);
sun4v_rtc_init(NIAGARA_RTC_BASE);
}

View File

@ -319,9 +319,9 @@ static const MemoryRegionOps spi_ops = {
}
};
static int xilinx_spi_init(SysBusDevice *sbd)
static void xilinx_spi_realize(DeviceState *dev, Error **errp)
{
DeviceState *dev = DEVICE(sbd);
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
XilinxSPI *s = XILINX_SPI(dev);
int i;
@ -344,8 +344,6 @@ static int xilinx_spi_init(SysBusDevice *sbd)
fifo8_create(&s->tx_fifo, FIFO_CAPACITY);
fifo8_create(&s->rx_fifo, FIFO_CAPACITY);
return 0;
}
static const VMStateDescription vmstate_xilinx_spi = {
@ -368,9 +366,8 @@ static Property xilinx_spi_properties[] = {
static void xilinx_spi_class_init(ObjectClass *klass, void *data)
{
DeviceClass *dc = DEVICE_CLASS(klass);
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
k->init = xilinx_spi_init;
dc->realize = xilinx_spi_realize;
dc->reset = xlx_spi_reset;
dc->props = xilinx_spi_properties;
dc->vmsd = &vmstate_xilinx_spi;

View File

@ -14,15 +14,8 @@
#include "hw/sysbus.h"
#include "qemu/timer.h"
#include "hw/timer/sun4v-rtc.h"
#include "trace.h"
//#define DEBUG_SUN4V_RTC
#ifdef DEBUG_SUN4V_RTC
#define DPRINTF(fmt, ...) \
do { printf("sun4v_rtc: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) do {} while (0)
#endif
#define TYPE_SUN4V_RTC "sun4v_rtc"
#define SUN4V_RTC(obj) OBJECT_CHECK(Sun4vRtc, (obj), TYPE_SUN4V_RTC)
@ -41,14 +34,14 @@ static uint64_t sun4v_rtc_read(void *opaque, hwaddr addr,
/* accessing the high 32 bits */
val >>= 32;
}
DPRINTF("read from " TARGET_FMT_plx " val %lx\n", addr, val);
trace_sun4v_rtc_read(addr, val);
return val;
}
static void sun4v_rtc_write(void *opaque, hwaddr addr,
uint64_t val, unsigned size)
{
DPRINTF("write 0x%x to " TARGET_FMT_plx "\n", (unsigned)val, addr);
trace_sun4v_rtc_read(addr, val);
}
static const MemoryRegionOps sun4v_rtc_ops = {
@ -70,21 +63,21 @@ void sun4v_rtc_init(hwaddr addr)
sysbus_mmio_map(s, 0, addr);
}
static int sun4v_rtc_init1(SysBusDevice *dev)
static void sun4v_rtc_realize(DeviceState *dev, Error **errp)
{
SysBusDevice *sbd = SYS_BUS_DEVICE(dev);
Sun4vRtc *s = SUN4V_RTC(dev);
memory_region_init_io(&s->iomem, OBJECT(s), &sun4v_rtc_ops, s,
"sun4v-rtc", 0x08ULL);
sysbus_init_mmio(dev, &s->iomem);
return 0;
sysbus_init_mmio(sbd, &s->iomem);
}
static void sun4v_rtc_class_init(ObjectClass *klass, void *data)
{
SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
DeviceClass *dc = DEVICE_CLASS(klass);
k->init = sun4v_rtc_init1;
dc->realize = sun4v_rtc_realize;
}
static const TypeInfo sun4v_rtc_info = {

View File

@ -56,7 +56,7 @@ systick_timer_tick(void) "systick reload"
systick_read(uint64_t addr, uint32_t value, unsigned size) "systick read addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
systick_write(uint64_t addr, uint32_t value, unsigned size) "systick write addr 0x%" PRIx64 " data 0x%" PRIx32 " size %u"
# hw/char/cmsdk_apb_timer.c
# hw/timer/cmsdk_apb_timer.c
cmsdk_apb_timer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer read: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_timer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB timer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_timer_reset(void) "CMSDK APB timer: reset"
@ -66,5 +66,9 @@ cmsdk_apb_dualtimer_read(uint64_t offset, uint64_t data, unsigned size) "CMSDK A
cmsdk_apb_dualtimer_write(uint64_t offset, uint64_t data, unsigned size) "CMSDK APB dualtimer write: offset 0x%" PRIx64 " data 0x%" PRIx64 " size %u"
cmsdk_apb_dualtimer_reset(void) "CMSDK APB dualtimer: reset"
# hw/timer/sun4v-rtc.c
sun4v_rtc_read(uint64_t addr, uint64_t value) "read: addr 0x%" PRIx64 " value 0x%" PRIx64
sun4v_rtc_write(uint64_t addr, uint64_t value) "write: addr 0x%" PRIx64 " value 0x%" PRIx64
# hw/timer/xlnx-zynqmp-rtc.c
xlnx_zynqmp_rtc_gettime(int year, int month, int day, int hour, int min, int sec) "Get time from host: %d-%d-%d %2d:%02d:%02d"

View File

@ -29,23 +29,81 @@ typedef struct MemoryDeviceState {
Object parent_obj;
} MemoryDeviceState;
/**
* MemoryDeviceClass:
*
* All memory devices need to implement TYPE_MEMORY_DEVICE as an interface.
*
* A memory device is a device that owns a memory region which is
* mapped into guest physical address space at a certain address. The
* address in guest physical memory can either be specified explicitly
* or get assigned automatically.
*
* Conceptually, memory devices only span one memory region. If multiple
* successive memory regions are used, a covering memory region has to
* be provided. Scattered memory regions are not supported for single
* devices.
*/
typedef struct MemoryDeviceClass {
/* private */
InterfaceClass parent_class;
/*
* Return the address of the memory device in guest physical memory.
*
* Called when (un)plugging a memory device or when iterating over
* all memory devices mapped into guest physical address space.
*
* If "0" is returned, no address has been specified by the user and
* no address has been assigned to this memory device yet.
*/
uint64_t (*get_addr)(const MemoryDeviceState *md);
uint64_t (*get_plugged_size)(const MemoryDeviceState *md);
uint64_t (*get_region_size)(const MemoryDeviceState *md);
/*
* Set the address of the memory device in guest physical memory.
*
* Called when plugging the memory device to configure the determined
* address in guest physical memory.
*/
void (*set_addr)(MemoryDeviceState *md, uint64_t addr, Error **errp);
/*
* Return the amount of memory provided by the memory device currently
* usable ("plugged") by the VM.
*
* Called when calculating the total amount of ram available to the
* VM (e.g. to report memory stats to the user).
*
* This is helpful for devices that dynamically manage the amount of
* memory accessible by the guest via the reserved memory region. For
* most devices, this corresponds to the size of the memory region.
*/
uint64_t (*get_plugged_size)(const MemoryDeviceState *md, Error **errp);
/*
* Return the memory region of the memory device.
*
* Called when (un)plugging the memory device, to (un)map the
* memory region in guest physical memory, but also to detect the
* required alignment during address assignment or when the size of the
* memory region is required.
*/
MemoryRegion *(*get_memory_region)(MemoryDeviceState *md, Error **errp);
/*
* Translate the memory device into #MemoryDeviceInfo.
*/
void (*fill_device_info)(const MemoryDeviceState *md,
MemoryDeviceInfo *info);
} MemoryDeviceClass;
MemoryDeviceInfoList *qmp_memory_device_list(void);
uint64_t get_plugged_memory_size(void);
uint64_t memory_device_get_free_addr(MachineState *ms, const uint64_t *hint,
uint64_t align, uint64_t size,
Error **errp);
void memory_device_plug_region(MachineState *ms, MemoryRegion *mr,
uint64_t addr);
void memory_device_unplug_region(MachineState *ms, MemoryRegion *mr);
void memory_device_pre_plug(MemoryDeviceState *md, MachineState *ms,
const uint64_t *legacy_align, Error **errp);
void memory_device_plug(MemoryDeviceState *md, MachineState *ms);
void memory_device_unplug(MemoryDeviceState *md, MachineState *ms);
uint64_t memory_device_get_region_size(const MemoryDeviceState *md,
Error **errp);
#endif

View File

@ -61,9 +61,6 @@ typedef struct PCDIMMDevice {
* PCDIMMDeviceClass:
* @realize: called after common dimm is realized so that the dimm based
* devices get the chance to do specified operations.
* @get_memory_region: returns #MemoryRegion associated with @dimm which
* is directly mapped into the physical address space of guest. Will not
* fail after the device was realized.
* @get_vmstate_memory_region: returns #MemoryRegion which indicates the
* memory of @dimm should be kept during live migration. Will not fail
* after the device was realized.
@ -74,13 +71,12 @@ typedef struct PCDIMMDeviceClass {
/* public */
void (*realize)(PCDIMMDevice *dimm, Error **errp);
MemoryRegion *(*get_memory_region)(PCDIMMDevice *dimm, Error **errp);
MemoryRegion *(*get_vmstate_memory_region)(PCDIMMDevice *dimm,
Error **errp);
} PCDIMMDeviceClass;
void pc_dimm_pre_plug(DeviceState *dev, MachineState *machine,
void pc_dimm_pre_plug(PCDIMMDevice *dimm, MachineState *machine,
const uint64_t *legacy_align, Error **errp);
void pc_dimm_plug(DeviceState *dev, MachineState *machine, Error **errp);
void pc_dimm_unplug(DeviceState *dev, MachineState *machine);
void pc_dimm_plug(PCDIMMDevice *dimm, MachineState *machine, Error **errp);
void pc_dimm_unplug(PCDIMMDevice *dimm, MachineState *machine);
#endif

View File

@ -2066,7 +2066,7 @@
#
# @plugged-memory: size of memory that can be hot-unplugged. This field
# is omitted if target doesn't support memory hotplug
# (i.e. CONFIG_MEM_HOTPLUG not defined on build time).
# (i.e. CONFIG_MEM_DEVICE not defined at build time).
#
# Since: 2.11.0
##

View File

@ -86,6 +86,18 @@ for these file types is 'host_cdrom' or 'host_device' as appropriate.
The @option{name} parameter of the @option{-net} option is a synonym
for the @option{id} parameter, which should now be used instead.
@subsection -smp (invalid topologies) (since 3.1)
CPU topology properties should describe whole machine topology including
possible CPUs.
However, historically it was possible to start QEMU with an incorrect topology
where @math{@var{n} <= @var{sockets} * @var{cores} * @var{threads} < @var{maxcpus}},
which could lead to an incorrect topology enumeration by the guest.
Support for invalid topologies will be removed, the user must ensure
topologies described with -smp include all possible cpus, i.e.
@math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}.
@section QEMU Machine Protocol (QMP) commands
@subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0)

View File

@ -32,12 +32,12 @@ static void test_plug_with_cpu_add(gconstpointer data)
unsigned int i;
args = g_strdup_printf("-machine %s -cpu %s "
"-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
"-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
s->machine, s->cpu_model,
s->sockets, s->cores, s->threads, s->maxcpus);
qtest_start(args);
for (i = s->sockets * s->cores * s->threads; i < s->maxcpus; i++) {
for (i = 1; i < s->maxcpus; i++) {
response = qmp("{ 'execute': 'cpu-add',"
" 'arguments': { 'id': %d } }", i);
g_assert(response);
@ -56,7 +56,7 @@ static void test_plug_without_cpu_add(gconstpointer data)
QDict *response;
args = g_strdup_printf("-machine %s -cpu %s "
"-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
"-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
s->machine, s->cpu_model,
s->sockets, s->cores, s->threads, s->maxcpus);
qtest_start(args);
@ -79,12 +79,12 @@ static void test_plug_with_device_add_x86(gconstpointer data)
unsigned int s, c, t;
args = g_strdup_printf("-machine %s -cpu %s "
"-smp sockets=%u,cores=%u,threads=%u,maxcpus=%u",
"-smp 1,sockets=%u,cores=%u,threads=%u,maxcpus=%u",
td->machine, td->cpu_model,
td->sockets, td->cores, td->threads, td->maxcpus);
qtest_start(args);
for (s = td->sockets; s < td->maxcpus / td->cores / td->threads; s++) {
for (s = 1; s < td->sockets; s++) {
for (c = 0; c < td->cores; c++) {
for (t = 0; t < td->threads; t++) {
char *id = g_strdup_printf("id-%i-%i-%i", s, c, t);
@ -113,7 +113,7 @@ static void test_plug_with_device_add_coreid(gconstpointer data)
td->sockets, td->cores, td->threads, td->maxcpus);
qtest_start(args);
for (c = td->cores; c < td->maxcpus / td->sockets / td->threads; c++) {
for (c = 1; c < td->cores; c++) {
char *id = g_strdup_printf("id-%i", c);
qtest_qmp_device_add(td->device_model, id, "{'core-id':%u}", c);
g_free(id);
@ -148,7 +148,7 @@ static void add_pc_test_case(const char *mname)
data->sockets = 1;
data->cores = 3;
data->threads = 2;
data->maxcpus = data->sockets * data->cores * data->threads * 2;
data->maxcpus = data->sockets * data->cores * data->threads;
if (g_str_has_suffix(mname, "-1.4") ||
(strcmp(mname, "pc-1.3") == 0) ||
(strcmp(mname, "pc-1.2") == 0) ||
@ -203,7 +203,7 @@ static void add_pseries_test_case(const char *mname)
data->sockets = 2;
data->cores = 3;
data->threads = 1;
data->maxcpus = data->sockets * data->cores * data->threads * 2;
data->maxcpus = data->sockets * data->cores * data->threads;
path = g_strdup_printf("cpu-plug/%s/device-add/%ux%ux%u&maxcpus=%u",
mname, data->sockets, data->cores,
@ -229,7 +229,7 @@ static void add_s390x_test_case(const char *mname)
data->sockets = 1;
data->cores = 3;
data->threads = 1;
data->maxcpus = data->sockets * data->cores * data->threads * 2;
data->maxcpus = data->sockets * data->cores * data->threads;
data2 = g_memdup(data, sizeof(PlugTestData));
data2->machine = g_strdup(data->machine);

12
vl.c
View File

@ -1230,11 +1230,14 @@ static void smp_parse(QemuOpts *opts)
/* compute missing values, prefer sockets over cores over threads */
if (cpus == 0 || sockets == 0) {
sockets = sockets > 0 ? sockets : 1;
cores = cores > 0 ? cores : 1;
threads = threads > 0 ? threads : 1;
if (cpus == 0) {
sockets = sockets > 0 ? sockets : 1;
cpus = cores * threads * sockets;
} else {
max_cpus = qemu_opt_get_number(opts, "maxcpus", cpus);
sockets = max_cpus / (cores * threads);
}
} else if (cores == 0) {
threads = threads > 0 ? threads : 1;
@ -1266,6 +1269,13 @@ static void smp_parse(QemuOpts *opts)
exit(1);
}
if (sockets * cores * threads != max_cpus) {
warn_report("Invalid CPU topology deprecated: "
"sockets (%u) * cores (%u) * threads (%u) "
"!= maxcpus (%u)",
sockets, cores, threads, max_cpus);
}
smp_cpus = cpus;
smp_cores = cores;
smp_threads = threads;