Go to the documentation of this file.
42 #include <sys/types.h>
54 #include "debug/AddrRanges.hh"
55 #include "debug/Checkpoint.hh"
64 #if defined(__APPLE__) || defined(__FreeBSD__)
66 #define MAP_NORESERVE 0
74 bool mmap_using_noreserve,
75 const std::string& shared_backstore) :
76 _name(_name), size(0), mmapUsingNoReserve(mmap_using_noreserve),
77 sharedBackstore(shared_backstore)
79 if (mmap_using_noreserve)
80 warn(
"Not reserving swap space. May cause SIGSEGV on actual usage\n");
84 for (
const auto&
m : _memories) {
86 if (
m->isInAddrMap()) {
87 memories.push_back(
m);
94 fatal_if(addrMap.insert(
m->getAddrRange(),
m) == addrMap.end(),
95 "Memory address range for %s is overlapping\n",
102 "Skipping memory %s that is not in global address map\n",
106 fatal_if(
m->getAddrRange().interleaved(),
107 "Memory %s that is not in the global address map cannot "
108 "be interleaved\n",
m->name());
114 createBackingStore(
m->getAddrRange(), unmapped_mems,
115 m->isConfReported(),
m->isInAddrMap(),
125 for (
const auto&
r : addrMap) {
128 if (!
r.second->isNull()) {
130 if (
r.first.interleaved()) {
134 if (!intlv_ranges.empty() &&
135 !intlv_ranges.back().mergesWith(
r.first)) {
139 for (
const auto&
c : curr_memories)
140 if (
f->isConfReported() !=
c->isConfReported() ||
141 f->isInAddrMap() !=
c->isInAddrMap() ||
142 f->isKvmMap() !=
c->isKvmMap())
143 fatal(
"Inconsistent flags in an interleaved "
146 createBackingStore(merged_range, curr_memories,
147 f->isConfReported(),
f->isInAddrMap(),
150 intlv_ranges.clear();
151 curr_memories.clear();
153 intlv_ranges.push_back(
r.first);
154 curr_memories.push_back(
r.second);
157 createBackingStore(
r.first, single_memory,
158 r.second->isConfReported(),
159 r.second->isInAddrMap(),
160 r.second->isKvmMap());
167 if (!intlv_ranges.empty()) {
171 for (
const auto&
c : curr_memories)
172 if (
f->isConfReported() !=
c->isConfReported() ||
173 f->isInAddrMap() !=
c->isInAddrMap() ||
174 f->isKvmMap() !=
c->isKvmMap())
175 fatal(
"Inconsistent flags in an interleaved "
178 createBackingStore(merged_range, curr_memories,
179 f->isConfReported(),
f->isInAddrMap(),
187 bool conf_table_reported,
188 bool in_addr_map,
bool kvm_map)
191 "Cannot create backing store for interleaved range %s\n",
195 DPRINTF(AddrRanges,
"Creating backing store for range %s with size %d\n",
203 map_flags = MAP_ANON | MAP_PRIVATE;
205 DPRINTF(AddrRanges,
"Sharing backing store as %s\n",
209 panic(
"Shared memory failed");
210 if (ftruncate(shm_fd, range.
size()))
211 panic(
"Setting size of shared memory failed");
212 map_flags = MAP_SHARED;
218 map_flags |= MAP_NORESERVE;
221 uint8_t* pmem = (uint8_t*) mmap(NULL, range.
size(),
222 PROT_READ | PROT_WRITE,
223 map_flags, shm_fd, 0);
225 if (pmem == (uint8_t*) MAP_FAILED) {
227 fatal(
"Could not mmap %d bytes for range %s!\n", range.
size(),
234 conf_table_reported, in_addr_map, kvm_map);
237 for (
const auto&
m : _memories) {
238 DPRINTF(AddrRanges,
"Mapping memory %s to backing store\n",
240 m->setBackingStore(pmem);
248 munmap((
char*)
s.pmem,
s.range.size());
265 if (
r.second->isConfReported()) {
267 if (
r.first.interleaved()) {
271 if (!intlv_ranges.empty() &&
272 !intlv_ranges.back().mergesWith(
r.first)) {
273 ranges.push_back(
AddrRange(intlv_ranges));
274 intlv_ranges.clear();
276 intlv_ranges.push_back(
r.first);
279 ranges.push_back(
r.first);
286 if (!intlv_ranges.empty()) {
287 ranges.push_back(
AddrRange(intlv_ranges));
299 m->second->access(pkt);
308 m->second->functionalAccess(pkt);
321 lal_addr.push_back(
l.addr);
322 lal_cid.push_back(
l.contextId);
333 unsigned int store_id = 0;
347 string filename =
name() +
".store" +
to_string(store_id) +
".pmem";
348 long range_size = range.
size();
350 DPRINTF(Checkpoint,
"Serializing physical memory %s with size %d\n",
351 filename, range_size);
359 gzFile compressed_mem = gzopen(filepath.c_str(),
"wb");
360 if (compressed_mem == NULL)
361 fatal(
"Can't open physical memory checkpoint file '%s'\n",
364 uint64_t pass_size = 0;
367 for (uint64_t written = 0; written < range.
size();
368 written += pass_size) {
369 pass_size = (uint64_t)INT_MAX < (range.
size() - written) ?
370 (uint64_t)INT_MAX : (range.
size() - written);
372 if (gzwrite(compressed_mem, pmem + written,
373 (
unsigned int) pass_size) != (
int) pass_size) {
374 fatal(
"Write failed on physical memory checkpoint file '%s'\n",
381 if (gzclose(compressed_mem))
382 fatal(
"Close failed on physical memory checkpoint file '%s'\n",
396 for (
size_t i = 0;
i < lal_addr.size(); ++
i) {
398 m->second->addLockedAddr(
LockedAddr(lal_addr[
i], lal_cid[
i]));
402 unsigned int nbr_of_stores;
405 for (
unsigned int i = 0;
i < nbr_of_stores; ++
i) {
415 const uint32_t chunk_size = 16384;
417 unsigned int store_id;
422 string filepath =
cp.getCptDir() +
"/" + filename;
425 gzFile compressed_mem = gzopen(filepath.c_str(),
"rb");
426 if (compressed_mem == NULL)
427 fatal(
"Can't open physical memory checkpoint file '%s'", filename);
436 DPRINTF(Checkpoint,
"Unserializing physical memory %s with size %d\n",
437 filename, range_size);
439 if (range_size != range.
size())
440 fatal(
"Memory range size has changed! Saw %lld, expected %lld\n",
441 range_size, range.
size());
443 uint64_t curr_size = 0;
444 long* temp_page =
new long[chunk_size];
447 while (curr_size < range.
size()) {
448 bytes_read = gzread(compressed_mem, temp_page, chunk_size);
452 assert(bytes_read %
sizeof(
long) == 0);
454 for (uint32_t
x = 0;
x < bytes_read /
sizeof(long);
x++) {
457 if (*(temp_page +
x) != 0) {
458 pmem_current = (
long*)(pmem + curr_size +
x *
sizeof(
long));
459 *pmem_current = *(temp_page +
x);
462 curr_size += bytes_read;
467 if (gzclose(compressed_mem))
468 fatal(
"Close failed on physical memory checkpoint file '%s'\n",
#define fatal(...)
This implements a cprintf based fatal() function.
AddrRange getAddrRange() const
Get address range to which this packet belongs.
#define UNSERIALIZE_SCALAR(scalar)
#define UNSERIALIZE_CONTAINER(member)
bool interleaved() const
Determine if the range is interleaved or not.
const_iterator end() const
Locked address class that represents a physical address and a context id.
const std::string to_string(sc_enc enc)
void unserializeStore(CheckpointIn &cp)
Unserialize a specific backing store, identified by a section.
const std::string sharedBackstore
std::unordered_map< int, std::stack< Addr > > locked_addrs
PhysicalMemory(const PhysicalMemory &)
An abstract memory represents a contiguous block of physical memory, with an associated address range...
const std::string name() const
Return the name for debugging and for creation of sections for checkpointing.
void createBackingStore(AddrRange range, const std::vector< AbstractMemory * > &_memories, bool conf_table_reported, bool in_addr_map, bool kvm_map)
Create the memory region providing the backing store for a given address range that corresponds to a ...
void serializeStore(CheckpointOut &cp, unsigned int store_id, AddrRange range, uint8_t *pmem) const
Serialize a specific store.
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
std::vector< BackingStoreEntry > backingStore
const bool mmapUsingNoReserve
void functionalAccess(PacketPtr pkt)
Perform an untimed memory read or write without changing anything but the memory itself.
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
#define SERIALIZE_SCALAR(scalar)
static std::string dir()
Get the current checkout directory name.
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
std::vector< AbstractMemory * > memories
bool isMemAddr(Addr addr) const
Check if a physical address is within a range of a memory that is part of the global address map.
std::string to_string() const
Get a string representation of the range.
Overload hash function for BasicBlockRange type.
AddrRangeMap< AbstractMemory *, 1 > addrMap
#define SERIALIZE_CONTAINER(member)
const_iterator contains(const AddrRange &r) const
Find entry that contains the given address range.
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
void serialize(CheckpointOut &cp) const override
Serialize all the memories in the system.
std::ostream CheckpointOut
void access(PacketPtr pkt)
Perform an untimed memory access and update all the state (e.g.
AddrRangeList getConfAddrRanges() const
Get the memory ranges for all memories that are to be reported to the configuration table.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Addr size() const
Get the size of the address range.
void unserialize(CheckpointIn &cp) override
Unserialize the memories in the system.
~PhysicalMemory()
Unmap all the backing store we have used.
std::string csprintf(const char *format, const Args &...args)
#define panic(...)
This implements a cprintf based panic() function.
Generated on Wed Sep 30 2020 14:02:13 for gem5 by doxygen 1.8.17