@@ -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 = {
@@ -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);