Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovi...@profitbricks.com> Signed-off-by: Hu Tao <hu...@cn.fujitsu.com> --- hw/i386/pc.c | 27 +++++++++++++++++++++++++++ include/hw/i386/pc.h | 5 +++++ 2 files changed, 32 insertions(+)
diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 55056b1..65838a6 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1283,6 +1283,27 @@ void mc_set_smm(int val, void *arg) memory_region_transaction_commit(); } +static hwaddr mc_dimm_offset(DeviceState *dev, uint64_t size) +{ + MemoryController *d = MEMORY_CONTROLLER(dev); + MemoryControllerClass *c = MEMORY_CONTROLLER_GET_CLASS(d); + hwaddr ret; + + if (d->below_4g_mem_size + size <= c->pci_hole_start) { + /* if dimm fits before pci hole, append it normally */ + ret = d->below_4g_mem_size; + d->below_4g_mem_size += size; + } else { + /* otherwise place it above 4GB */ + ret = d->above_4g_mem_size + c->pci_hole_end; + d->above_4g_mem_size += size; + } + + d->ram_size += size; + + return ret; +} + static int memory_controller_init(PCIDevice *dev) { MemoryController *m = MEMORY_CONTROLLER(dev); @@ -1353,6 +1374,11 @@ static int memory_controller_init(PCIDevice *dev) PAM_EXPAN_SIZE); } + m->dram_channel0 = dimm_bus_create(OBJECT(m), "membus.0", 8, + c->dimm_offset); + m->pv_dram_channel = dimm_bus_create(OBJECT(m), "membus.pv", 0, + c->dimm_offset); + ram_size = m->ram_size / 8 / 1024 / 1024; if (ram_size > 255) { ram_size = 255; @@ -1388,6 +1414,7 @@ static void memory_controller_class_init(ObjectClass *klass, void *data) dc->no_user = 1; mc->set_smm = mc_set_smm; mc->update = mc_update; + mc->dimm_offset = mc_dimm_offset; } static const TypeInfo memory_controller_type_info = { diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h index e2cbc1b..959b92b 100644 --- a/include/hw/i386/pc.h +++ b/include/hw/i386/pc.h @@ -10,6 +10,7 @@ #include "hw/i386/ioapic.h" #include "hw/pci/pci.h" #include "hw/pci-host/pam.h" +#include "hw/mem-hotplug/dimm.h" #define TYPE_MEMORY_CONTROLLER "memory controller" #define MEMORY_CONTROLLER(obj) OBJECT_CHECK(MemoryController, (obj), TYPE_DEVICE) @@ -29,6 +30,7 @@ typedef struct MemoryControllerClass { void (*set_smm)(int val, void *arg); void (*update)(MemoryController *m); + hwaddr (*dimm_offset)(DeviceState *d, uint64_t size); } MemoryControllerClass; typedef struct MemoryController { @@ -48,6 +50,9 @@ typedef struct MemoryController { MemoryRegion ram_above_4g; hwaddr below_4g_mem_size; hwaddr above_4g_mem_size; + + DimmBus *dram_channel0; + DimmBus *pv_dram_channel; } MemoryController; void mc_update_pam(MemoryController *d); -- 1.8.3.1