Mem: Finish half-baked support for mmaping file in physmem.

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.
This commit is contained in:
Ali Saidi 2010-11-08 13:58:24 -06:00
parent ea1167dd9f
commit c779af4e12
3 changed files with 44 additions and 20 deletions

View file

@ -200,9 +200,12 @@ def makeLinuxArmSystem(mem_mode, mdesc = None, bare_metal=False,
self.membus.badaddr_responder.warn_access = "warn" self.membus.badaddr_responder.warn_access = "warn"
self.bridge = Bridge(delay='50ns', nack_delay='4ns') self.bridge = Bridge(delay='50ns', nack_delay='4ns')
self.physmem = PhysicalMemory(range = AddrRange(mdesc.mem()), zero = True) 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_a = self.iobus.port
self.bridge.side_b = self.membus.port self.bridge.side_b = self.membus.port
self.physmem.port = self.membus.port self.physmem.port = self.membus.port
self.diskmem.port = self.membus.port
self.mem_mode = mem_mode self.mem_mode = mem_mode
@ -224,7 +227,10 @@ def makeLinuxArmSystem(mem_mode, mdesc = None, bare_metal=False,
self.intrctrl = IntrControl() self.intrctrl = IntrControl()
self.terminal = Terminal() 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 return self

View file

@ -31,6 +31,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/user.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
@ -41,6 +42,7 @@
#include <string> #include <string>
#include "arch/registers.hh" #include "arch/registers.hh"
#include "base/intmath.hh"
#include "base/misc.hh" #include "base/misc.hh"
#include "base/random.hh" #include "base/random.hh"
#include "base/types.hh" #include "base/types.hh"
@ -56,26 +58,39 @@ using namespace TheISA;
PhysicalMemory::PhysicalMemory(const Params *p) PhysicalMemory::PhysicalMemory(const Params *p)
: MemObject(p), pmemAddr(NULL), pagePtr(0), : MemObject(p), pmemAddr(NULL), pagePtr(0),
lat(p->latency), lat_var(p->latency_var), 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"); panic("Memory Size not divisible by page size\n");
if (params()->null) if (params()->null)
return; return;
int map_flags = MAP_ANON | MAP_PRIVATE;
pmemAddr = (uint8_t *)mmap(NULL, params()->range.size(), if (params()->file == "") {
PROT_READ | PROT_WRITE, map_flags, -1, 0); 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) { if (pmemAddr == (void *)MAP_FAILED) {
perror("mmap"); 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 requested, initialize all the memory to 0
if (p->zero) if (p->zero)
memset(pmemAddr, 0, p->range.size()); memset(pmemAddr, 0, size());
} }
void void
@ -94,8 +109,7 @@ PhysicalMemory::init()
PhysicalMemory::~PhysicalMemory() PhysicalMemory::~PhysicalMemory()
{ {
if (pmemAddr) if (pmemAddr)
munmap((char*)pmemAddr, params()->range.size()); munmap((char*)pmemAddr, size());
//Remove memPorts?
} }
Addr Addr
@ -408,7 +422,7 @@ PhysicalMemory::getAddressRanges(AddrRangeList &resp, bool &snoop)
{ {
snoop = false; snoop = false;
resp.clear(); resp.clear();
resp.push_back(RangeSize(start(), params()->range.size())); resp.push_back(RangeSize(start(), size()));
} }
unsigned unsigned
@ -463,6 +477,7 @@ PhysicalMemory::serialize(ostream &os)
string filename = name() + ".physmem"; string filename = name() + ".physmem";
SERIALIZE_SCALAR(filename); SERIALIZE_SCALAR(filename);
SERIALIZE_SCALAR(_size);
// write memory file // write memory file
string thefile = Checkpoint::dir() + "/" + filename.c_str(); 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", fatal("Insufficient memory to allocate compression state for %s\n",
filename); filename);
if (gzwrite(compressedMem, pmemAddr, params()->range.size()) != if (gzwrite(compressedMem, pmemAddr, size()) != (int)size()) {
(int)params()->range.size()) {
fatal("Write failed on physical memory checkpoint file '%s'\n", fatal("Write failed on physical memory checkpoint file '%s'\n",
filename); filename);
} }
@ -522,9 +536,13 @@ PhysicalMemory::unserialize(Checkpoint *cp, const string &section)
// unmap file that was mmaped in the constructor // unmap file that was mmaped in the constructor
// This is done here to make sure that gzip and open don't muck with our // 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 // nice large space of memory before we reallocate it
munmap((char*)pmemAddr, params()->range.size()); munmap((char*)pmemAddr, size());
pmemAddr = (uint8_t *)mmap(NULL, params()->range.size(), UNSERIALIZE_SCALAR(_size);
if (size() > params()->range.size())
fatal("Memory size has changed!\n");
pmemAddr = (uint8_t *)mmap(NULL, size(),
PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (pmemAddr == (void *)MAP_FAILED) { 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); 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 */ /* 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); bytesRead = gzread(compressedMem, tempPage, chunkSize);
if (bytesRead == 0) if (bytesRead == 0)
break; break;

View file

@ -149,12 +149,12 @@ class PhysicalMemory : public MemObject
std::vector<MemoryPort*> ports; std::vector<MemoryPort*> ports;
typedef std::vector<MemoryPort*>::iterator PortIterator; typedef std::vector<MemoryPort*>::iterator PortIterator;
uint64_t cachedSize; uint64_t _size;
uint64_t cachedStart; uint64_t _start;
public: public:
Addr new_page(); Addr new_page();
uint64_t size() { return cachedSize; } uint64_t size() { return _size; }
uint64_t start() { return cachedStart; } uint64_t start() { return _start; }
public: public:
typedef PhysicalMemoryParams Params; typedef PhysicalMemoryParams Params;