/*
+ * Copyright (c) 2010 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
* Copyright (c) 2001-2005 The Regents of The University of Michigan
* All rights reserved.
*
* Ali Saidi
*/
-#include <sys/types.h>
#include <sys/mman.h>
-#include <errno.h>
+#include <sys/types.h>
+#include <sys/user.h>
#include <fcntl.h>
#include <unistd.h>
#include <zlib.h>
+#include <cerrno>
+#include <cstdio>
#include <iostream>
#include <string>
#include "arch/isa_traits.hh"
+#include "arch/registers.hh"
+#include "base/intmath.hh"
#include "base/misc.hh"
#include "base/random.hh"
#include "base/types.hh"
-#include "config/full_system.hh"
+#include "config/the_isa.hh"
+#include "debug/LLSC.hh"
+#include "debug/MemoryAccess.hh"
#include "mem/packet_access.hh"
#include "mem/physical.hh"
#include "sim/eventq.hh"
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)
+ : MemObject(p), pmemAddr(NULL), lat(p->latency), lat_var(p->latency_var),
+ _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(), sysconf(_SC_PAGESIZE)),
+ 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
PhysicalMemory::~PhysicalMemory()
{
if (pmemAddr)
- munmap((char*)pmemAddr, params()->range.size());
- //Remove memPorts?
-}
-
-Addr
-PhysicalMemory::new_page()
-{
- Addr return_addr = pagePtr << LogVMPageSize;
- return_addr += start();
-
- ++pagePtr;
- return return_addr;
+ munmap((char*)pmemAddr, size());
}
-int
-PhysicalMemory::deviceBlockSize()
+unsigned
+PhysicalMemory::deviceBlockSize() const
{
//Can accept anysize request
return 0;
#define CASE(A, T) \
case sizeof(T): \
- DPRINTF(MemoryAccess, A " of size %i on address 0x%x data 0x%x\n", \
- pkt->getSize(), pkt->getAddr(), pkt->get<T>()); \
+ DPRINTF(MemoryAccess,"%s of size %i on address 0x%x data 0x%x\n", \
+ A, pkt->getSize(), pkt->getAddr(), pkt->get<T>()); \
break
CASE(A, uint16_t); \
CASE(A, uint8_t); \
default: \
- DPRINTF(MemoryAccess, A " of size %i on address 0x%x\n", \
- pkt->getSize(), pkt->getAddr()); \
+ DPRINTF(MemoryAccess, "%s of size %i on address 0x%x\n", \
+ A, pkt->getSize(), pkt->getAddr()); \
+ DDUMP(MemoryAccess, pkt->getPtr<uint8_t>(), pkt->getSize());\
} \
} while (0)
if (overwrite_mem)
std::memcpy(hostAddr, &overwrite_val, pkt->getSize());
+ assert(!pkt->req->isInstFetch());
TRACE_PACKET("Read/Write");
} else if (pkt->isRead()) {
assert(!pkt->isWrite());
}
if (pmemAddr)
memcpy(pkt->getPtr<uint8_t>(), hostAddr, pkt->getSize());
- TRACE_PACKET("Read");
+ TRACE_PACKET(pkt->req->isInstFetch() ? "IFetch" : "Read");
} else if (pkt->isWrite()) {
if (writeOK(pkt)) {
if (pmemAddr)
memcpy(hostAddr, pkt->getPtr<uint8_t>(), pkt->getSize());
+ assert(!pkt->req->isInstFetch());
TRACE_PACKET("Write");
}
} else if (pkt->isInvalidate()) {
panic("PhysicalMemory::getPort: unknown port %s requested", if_name);
}
- if (idx >= ports.size()) {
- ports.resize(idx+1);
+ if (idx >= (int)ports.size()) {
+ ports.resize(idx + 1);
}
if (ports[idx] != NULL) {
{
snoop = false;
resp.clear();
- resp.push_back(RangeSize(start(), params()->range.size()));
+ resp.push_back(RangeSize(start(), size()));
}
-int
-PhysicalMemory::MemoryPort::deviceBlockSize()
+unsigned
+PhysicalMemory::MemoryPort::deviceBlockSize() const
{
return memory->deviceBlockSize();
}
string filename = name() + ".physmem";
SERIALIZE_SCALAR(filename);
+ SERIALIZE_SCALAR(_size);
// write memory file
string thefile = Checkpoint::dir() + "/" + filename.c_str();
fatal("Insufficient memory to allocate compression state for %s\n",
filename);
- if (gzwrite(compressedMem, pmemAddr, params()->range.size()) !=
- params()->range.size()) {
+ if (gzwrite(compressedMem, pmemAddr, size()) != (int)size()) {
fatal("Write failed on physical memory checkpoint file '%s'\n",
filename);
}
if (gzclose(compressedMem))
fatal("Close failed on physical memory checkpoint file '%s'\n",
filename);
+
+ list<LockedAddr>::iterator i = lockedAddrList.begin();
+
+ vector<Addr> lal_addr;
+ vector<int> lal_cid;
+ while (i != lockedAddrList.end()) {
+ lal_addr.push_back(i->addr);
+ lal_cid.push_back(i->contextId);
+ i++;
+ }
+ arrayParamOut(os, "lal_addr", lal_addr);
+ arrayParamOut(os, "lal_cid", lal_cid);
}
void
long *pmem_current;
uint64_t curSize;
uint32_t bytesRead;
- const int chunkSize = 16384;
+ const uint32_t chunkSize = 16384;
string filename;
fatal("Insufficient memory to allocate compression state for %s\n",
filename);
- // unmap file that was mmaped in the constructor
+ // unmap file that was mmapped 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! size %lld, param size %lld\n",
+ size(), params()->range.size());
- 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) {
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 != chunkSize &&
- bytesRead != params()->range.size() - curSize)
- fatal("Read failed on physical memory checkpoint file '%s'"
- " got %d bytes, expected %d or %d bytes\n",
- filename, bytesRead, chunkSize,
- params()->range.size() - curSize);
+ if (bytesRead == 0)
+ break;
assert(bytesRead % sizeof(long) == 0);
- for (int x = 0; x < bytesRead/sizeof(long); x++)
+ for (uint32_t x = 0; x < bytesRead / sizeof(long); x++)
{
if (*(tempPage+x) != 0) {
pmem_current = (long*)(pmemAddr + curSize + x * sizeof(long));
fatal("Close failed on physical memory checkpoint file '%s'\n",
filename);
+ vector<Addr> lal_addr;
+ vector<int> lal_cid;
+ arrayParamIn(cp, section, "lal_addr", lal_addr);
+ arrayParamIn(cp, section, "lal_cid", lal_cid);
+ for(int i = 0; i < lal_addr.size(); i++)
+ lockedAddrList.push_front(LockedAddr(lal_addr[i], lal_cid[i]));
}
PhysicalMemory *