Mem: Finish half-baked support for mmaping file in physmem.
authorAli Saidi <Ali.Saidi@ARM.com>
Mon, 8 Nov 2010 19:58:24 +0000 (13:58 -0600)
committerAli Saidi <Ali.Saidi@ARM.com>
Mon, 8 Nov 2010 19:58:24 +0000 (13:58 -0600)
Physmem has a parameter to be able to mem map a file, however
it isn't actually used. This changeset utilizes the parameter
so a file can be mmapped.

configs/common/FSConfig.py
src/mem/physical.cc
src/mem/physical.hh

index 6509490d7d1d3f2cb4d42bc359b4a098d0e75faf..fe57b5cab3457589f29d37f28d7dc808b1e40fd0 100644 (file)
@@ -200,9 +200,12 @@ def makeLinuxArmSystem(mem_mode, mdesc = None, bare_metal=False,
     self.membus.badaddr_responder.warn_access = "warn"
     self.bridge = Bridge(delay='50ns', nack_delay='4ns')
     self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()), zero = True)
+    self.diskmem = PhysicalMemory(range = AddrRange(Addr('128MB'), size = '128MB'),
+                                  file = disk('ael-arm.ext2'))
     self.bridge.side_a = self.iobus.port
     self.bridge.side_b = self.membus.port
     self.physmem.port = self.membus.port
+    self.diskmem.port = self.membus.port
 
     self.mem_mode = mem_mode
 
@@ -224,7 +227,10 @@ def makeLinuxArmSystem(mem_mode, mdesc = None, bare_metal=False,
 
     self.intrctrl = IntrControl()
     self.terminal = Terminal()
-    self.boot_osflags = 'earlyprintk mem=128MB console=ttyAMA0 lpj=19988480 norandmaps'
+    self.kernel = binary('vmlinux.arm')
+    self.boot_osflags = 'earlyprintk mem=128MB console=ttyAMA0 lpj=19988480' + \
+                        ' norandmaps slram=slram0,0x8000000,+0x8000000' +      \
+                        ' mtdparts=slram0:- rw loglevel=8 root=/dev/mtdblock0'
 
     return self
 
index 081fbb4cb2f3a7e8d0301a77ad767106e9831bd5..889794db61569c05cb00decabf09cef9370cd882 100644 (file)
@@ -31,6 +31,7 @@
 
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/user.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -41,6 +42,7 @@
 #include <string>
 
 #include "arch/registers.hh"
+#include "base/intmath.hh"
 #include "base/misc.hh"
 #include "base/random.hh"
 #include "base/types.hh"
@@ -56,26 +58,39 @@ using namespace TheISA;
 PhysicalMemory::PhysicalMemory(const Params *p)
     : MemObject(p), pmemAddr(NULL), pagePtr(0),
       lat(p->latency), lat_var(p->latency_var),
-      cachedSize(params()->range.size()), cachedStart(params()->range.start)
+      _size(params()->range.size()), _start(params()->range.start)
 {
-    if (params()->range.size() % TheISA::PageBytes != 0)
+    if (size() % TheISA::PageBytes != 0)
         panic("Memory Size not divisible by page size\n");
 
     if (params()->null)
         return;
 
-    int map_flags = MAP_ANON | MAP_PRIVATE;
-    pmemAddr = (uint8_t *)mmap(NULL, params()->range.size(),
-                               PROT_READ | PROT_WRITE, map_flags, -1, 0);
+
+    if (params()->file == "") {
+        int map_flags = MAP_ANON | MAP_PRIVATE;
+        pmemAddr = (uint8_t *)mmap(NULL, size(),
+                                   PROT_READ | PROT_WRITE, map_flags, -1, 0);
+    } else {
+        int map_flags = MAP_PRIVATE;
+        int fd = open(params()->file.c_str(), O_RDONLY);
+        _size = lseek(fd, 0, SEEK_END);
+        lseek(fd, 0, SEEK_SET);
+        pmemAddr = (uint8_t *)mmap(NULL, roundUp(size(), PAGE_SIZE),
+                                   PROT_READ | PROT_WRITE, map_flags, fd, 0);
+    }
 
     if (pmemAddr == (void *)MAP_FAILED) {
         perror("mmap");
-        fatal("Could not mmap!\n");
+        if (params()->file == "")
+            fatal("Could not mmap!\n");
+        else
+            fatal("Could not find file: %s\n", params()->file);
     }
 
     //If requested, initialize all the memory to 0
     if (p->zero)
-        memset(pmemAddr, 0, p->range.size());
+        memset(pmemAddr, 0, size());
 }
 
 void
@@ -94,8 +109,7 @@ PhysicalMemory::init()
 PhysicalMemory::~PhysicalMemory()
 {
     if (pmemAddr)
-        munmap((char*)pmemAddr, params()->range.size());
-    //Remove memPorts?
+        munmap((char*)pmemAddr, size());
 }
 
 Addr
@@ -408,7 +422,7 @@ PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop)
 {
     snoop = false;
     resp.clear();
-    resp.push_back(RangeSize(start(), params()->range.size()));
+    resp.push_back(RangeSize(start(), size()));
 }
 
 unsigned
@@ -463,6 +477,7 @@ PhysicalMemory::serialize(ostream &os)
     string filename = name() + ".physmem";
 
     SERIALIZE_SCALAR(filename);
+    SERIALIZE_SCALAR(_size);
 
     // write memory file
     string thefile = Checkpoint::dir() + "/" + filename.c_str();
@@ -477,8 +492,7 @@ PhysicalMemory::serialize(ostream &os)
         fatal("Insufficient memory to allocate compression state for %s\n",
                 filename);
 
-    if (gzwrite(compressedMem, pmemAddr, params()->range.size()) !=
-        (int)params()->range.size()) {
+    if (gzwrite(compressedMem, pmemAddr, size()) != (int)size()) {
         fatal("Write failed on physical memory checkpoint file '%s'\n",
               filename);
     }
@@ -522,9 +536,13 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
     // unmap file that was mmaped in the constructor
     // This is done here to make sure that gzip and open don't muck with our
     // nice large space of memory before we reallocate it
-    munmap((char*)pmemAddr, params()->range.size());
+    munmap((char*)pmemAddr, size());
+
+    UNSERIALIZE_SCALAR(_size);
+    if (size() > params()->range.size())
+        fatal("Memory size has changed!\n");
 
-    pmemAddr = (uint8_t *)mmap(NULL, params()->range.size(),
+    pmemAddr = (uint8_t *)mmap(NULL, size(),
         PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
 
     if (pmemAddr == (void *)MAP_FAILED) {
@@ -538,7 +556,7 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
         fatal("Unable to malloc memory to read file %s\n", filename);
 
     /* Only copy bytes that are non-zero, so we don't give the VM system hell */
-    while (curSize < params()->range.size()) {
+    while (curSize < size()) {
         bytesRead = gzread(compressedMem, tempPage, chunkSize);
         if (bytesRead == 0)
             break;
index dae6b42af5d44fcf6f69ad6e60e9c1a1e8518b9f..290e2bbae825e8145b1b2ab806d3216ae29cefa3 100644 (file)
@@ -149,12 +149,12 @@ class PhysicalMemory : public MemObject
     std::vector<MemoryPort*> ports;
     typedef std::vector<MemoryPort*>::iterator PortIterator;
 
-    uint64_t cachedSize;
-    uint64_t cachedStart;
+    uint64_t _size;
+    uint64_t _start;
   public:
     Addr new_page();
-    uint64_t size() { return cachedSize; }
-    uint64_t start() { return cachedStart; }
+    uint64_t size() { return _size; }
+    uint64_t start() { return _start; }
 
   public:
     typedef PhysicalMemoryParams Params;