diff --git a/src/sim/mem_pool.cc b/src/sim/mem_pool.cc index a7dc7c4631..21efb5c7c0 100644 --- a/src/sim/mem_pool.cc +++ b/src/sim/mem_pool.cc @@ -33,7 +33,11 @@ #include "sim/mem_pool.hh" +#include + +#include "base/addr_range.hh" #include "base/logging.hh" +#include "sim/system.hh" namespace gem5 { @@ -142,4 +146,70 @@ MemPool::unserialize(CheckpointIn &cp) paramIn(cp, "total_pages", _totalPages); } +void +MemPools::populate(const System &sys) +{ + AddrRangeList memories = sys.getPhysMem().getConfAddrRanges(); + const auto &m5op_range = sys.m5opRange(); + + assert(!memories.empty()); + for (const auto &mem : memories) { + assert(!mem.interleaved()); + if (m5op_range.valid()) { + // Make sure the m5op range is not included. + for (const auto &range: mem.exclude({m5op_range})) + pools.emplace_back(pageShift, range.start(), range.end()); + } else { + pools.emplace_back(pageShift, mem.start(), mem.end()); + } + } + + /* + * Set freePage to what it was before Gabe Black's page table changes + * so allocations don't trample the page table entries. + */ + pools[0].setFreePage(pools[0].freePage() + 70); +} + +Addr +MemPools::allocPhysPages(int npages, int pool_id) +{ + return pools[pool_id].allocate(npages); +} + +Addr +MemPools::memSize(int pool_id) const +{ + return pools[pool_id].totalBytes(); +} + +Addr +MemPools::freeMemSize(int pool_id) const +{ + return pools[pool_id].freeBytes(); +} + +void +MemPools::serialize(CheckpointOut &cp) const +{ + int num_pools = pools.size(); + SERIALIZE_SCALAR(num_pools); + + for (int i = 0; i < num_pools; i++) + pools[i].serializeSection(cp, csprintf("pool%d", i)); +} + +void +MemPools::unserialize(CheckpointIn &cp) +{ + int num_pools = 0; + UNSERIALIZE_SCALAR(num_pools); + + for (int i = 0; i < num_pools; i++) { + MemPool pool; + pool.unserializeSection(cp, csprintf("pool%d", i)); + pools.push_back(pool); + } +} + } // namespace gem5 diff --git a/src/sim/mem_pool.hh b/src/sim/mem_pool.hh index 0b681cd051..613d763923 100644 --- a/src/sim/mem_pool.hh +++ b/src/sim/mem_pool.hh @@ -34,6 +34,8 @@ #ifndef __MEM_POOL_HH__ #define __MEM_POOL_HH__ +#include + #include "base/types.hh" #include "sim/serialize.hh" @@ -57,9 +59,11 @@ class MemPool : public Serializable /** The size of the pool, in number of pages. */ Counter _totalPages = 0; - public: MemPool() {} + friend class MemPools; + + public: MemPool(Addr page_shift, Addr ptr, Addr limit); Counter startPage() const; @@ -82,6 +86,32 @@ class MemPool : public Serializable void unserialize(CheckpointIn &cp) override; }; +class MemPools : public Serializable +{ + private: + Addr pageShift; + + std::vector pools; + + public: + MemPools(Addr page_shift) : pageShift(page_shift) {} + + void populate(const System &sys); + + /// Allocate npages contiguous unused physical pages. + /// @return Starting address of first page + Addr allocPhysPages(int npages, int pool_id=0); + + /** Amount of physical memory that exists in a pool. */ + Addr memSize(int pool_id=0) const; + + /** Amount of physical memory that is still free in a pool. */ + Addr freeMemSize(int pool_id=0) const; + + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; +}; + } // namespace gem5 #endif // __MEM_POOL_HH__ diff --git a/src/sim/system.cc b/src/sim/system.cc index 5196c7183a..8777fc4c31 100644 --- a/src/sim/system.cc +++ b/src/sim/system.cc @@ -199,6 +199,7 @@ int System::numSystemsRunning = 0; System::System(const Params &p) : SimObject(p), _systemPort("system_port", this), multiThread(p.multi_thread), + memPools(getPageShift()), init_param(p.init_param), physProxy(_systemPort, p.cache_line_size), workload(p.workload), @@ -221,6 +222,9 @@ System::System(const Params &p) if (workload) workload->setSystem(this); + if (!FullSystem) + memPools.populate(*this); + // add self to global system list systemList.push_back(this); @@ -230,28 +234,6 @@ System::System(const Params &p) } #endif - if (!FullSystem) { - AddrRangeList memories = physmem.getConfAddrRanges(); - assert(!memories.empty()); - for (const auto &mem : memories) { - assert(!mem.interleaved()); - if (_m5opRange.valid()) { - // Make sure the m5op range is not included. - for (const auto &range: mem.exclude({_m5opRange})) - memPools.emplace_back(getPageShift(), - range.start(), range.end()); - } else { - memPools.emplace_back(getPageShift(), mem.start(), mem.end()); - } - } - - /* - * Set freePage to what it was before Gabe Black's page table changes - * so allocations don't trample the page table entries. - */ - memPools[0].setFreePage(memPools[0].freePage() + 70); - } - // check if the cache line size is a value known to work if (_cacheLineSize != 16 && _cacheLineSize != 32 && _cacheLineSize != 64 && _cacheLineSize != 128) { @@ -361,24 +343,24 @@ System::validKvmEnvironment() const } Addr -System::allocPhysPages(int npages, int poolID) +System::allocPhysPages(int npages, int pool_id) { assert(!FullSystem); - return memPools[poolID].allocate(npages); + return memPools.allocPhysPages(npages, pool_id); } Addr -System::memSize(int poolID) const +System::memSize(int pool_id) const { assert(!FullSystem); - return memPools[poolID].totalBytes(); + return memPools.memSize(pool_id); } Addr -System::freeMemSize(int poolID) const +System::freeMemSize(int pool_id) const { assert(!FullSystem); - return memPools[poolID].freeBytes(); + return memPools.freeMemSize(pool_id); } bool @@ -432,11 +414,7 @@ System::serialize(CheckpointOut &cp) const paramOut(cp, csprintf("quiesceEndTick_%d", id), when); } - int num_mem_pools = memPools.size(); - SERIALIZE_SCALAR(num_mem_pools); - - for (int i = 0; i < num_mem_pools; i++) - memPools[i].serializeSection(cp, csprintf("memPool%d", i)); + memPools.serializeSection(cp, "memPools"); // also serialize the memories in the system physmem.serializeSection(cp, "physmem"); @@ -458,14 +436,7 @@ System::unserialize(CheckpointIn &cp) # endif } - int num_mem_pools = 0; - UNSERIALIZE_SCALAR(num_mem_pools); - - for (int i = 0; i < num_mem_pools; i++) { - MemPool pool; - pool.unserializeSection(cp, csprintf("memPool%d", i)); - memPools.push_back(pool); - } + memPools.unserializeSection(cp, "memPools"); // also unserialize the memories in the system physmem.unserializeSection(cp, "physmem"); diff --git a/src/sim/system.hh b/src/sim/system.hh index 14d4d24efa..a5b7dd9a59 100644 --- a/src/sim/system.hh +++ b/src/sim/system.hh @@ -323,7 +323,7 @@ class System : public SimObject, public PCEventScope bool remove(PCEvent *event) override; /** Memory allocation objects for all physical memories in the system. */ - std::vector memPools; + MemPools memPools; uint64_t init_param; @@ -346,6 +346,7 @@ class System : public SimObject, public PCEventScope /** Get a pointer to access the physical memory of the system */ memory::PhysicalMemory& getPhysMem() { return physmem; } + const memory::PhysicalMemory& getPhysMem() const { return physmem; } /** Amount of physical memory that is still free */ Addr freeMemSize(int poolID = 0) const;