diff mbox

[v5,09/14] memory controller: initialize dram controller.

Message ID 2c8895d39b5503d2665ce648efe1912c1350f845.1372234719.git.hutao@cn.fujitsu.com
State New
Headers show

Commit Message

Hu Tao June 26, 2013, 9:13 a.m. UTC
Signed-off-by: Vasilis Liaskovitis <vasilis.liaskovitis@profitbricks.com>
Signed-off-by: Hu Tao <hutao@cn.fujitsu.com>
---
 hw/i386/pc.c         | 27 +++++++++++++++++++++++++++
 include/hw/i386/pc.h |  5 +++++
 2 files changed, 32 insertions(+)
diff mbox

Patch

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);