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:
parent
ea1167dd9f
commit
c779af4e12
3 changed files with 44 additions and 20 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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 §ion)
|
||||||
// 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 §ion)
|
||||||
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue