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:
commit
6e6ffc9ffa
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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 = {
|
||||
|
@ -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,
|
||||
|
@ -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 = {
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 = {
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
##
|
||||
|
@ -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)
|
||||
|
@ -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
12
vl.c
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user